Record an ENVI Cube in Intensities with References from a PushBroom

This example will connect to the virtual pushbroom camera (using MiniCube.hdr and its references), measure a white & dark reference, create a recording processing context and create an ENVI recording consisting of the first 100 lines returned from the device.

C++

The source code of the example can be found in the file example_pushbroom_create_envi.cpp:

  1#if defined(_WIN32) && defined(_MSC_VER)
  2#include <windows.h>
  3#endif
  4
  5#include <iostream>
  6#include <iomanip>
  7#include <string>
  8#include <fstream>
  9#include <streambuf>
 10#include <algorithm>
 11#include <utility>
 12
 13#include <cstddef>
 14
 15#include <fluxEngine/fluxEngine>
 16
 17#include "paths.h"
 18#include "helpers.h"
 19
 20int main()
 21{
 22    try {
 23        std::cout << "fluxEngine version: " << fluxEngine::versionString() << std::endl;
 24        fluxEngine::Handle handle(readFile(g_licenseFileName));
 25        handle.setDriverBaseDirectory(g_driverDirectory);
 26        handle.setDriverIsolationExecutable(g_driverIsolationExecutable);
 27        handle.createProcessingThreads(4);
 28
 29        // Load virtual camera
 30        fluxEngine::EnumerationResult enumeratedDevices = fluxEngine::enumerateDevices(handle, -1, std::chrono::seconds{1});
 31        fluxEngine::EnumeratedDevice* virtualCameraDevice = nullptr;
 32        for (auto const& device : enumeratedDevices.devices) {
 33            if (device->driver->name == "VirtualHyperCamera") {
 34                virtualCameraDevice = device.get();
 35                break;
 36            }
 37        }
 38
 39        if (!virtualCameraDevice)
 40            throw std::runtime_error("Could not find virtual camera driver");
 41
 42        fluxEngine::ConnectionSettings connectionSettings;
 43        connectionSettings.driverName = virtualCameraDevice->driver->name;
 44        connectionSettings.driverType = virtualCameraDevice->driver->type;
 45        connectionSettings.id = virtualCameraDevice->id;
 46        connectionSettings.timeout = std::chrono::seconds{60};
 47        connectionSettings.connectionParameters["Cube"] = encodeFileNameForConnectionParameter(g_cubeFileName);
 48        connectionSettings.connectionParameters["WhiteReferenceCube"] = encodeFileNameForConnectionParameter(g_whiteCubeFileName);
 49        connectionSettings.connectionParameters["DarkReferenceCube"] = encodeFileNameForConnectionParameter(g_darkCubeFileName);
 50
 51        std::cout << "Attempting to connect to device...\n" << std::flush;
 52        for (auto const& parameter : connectionSettings.connectionParameters)
 53            std::cout << "  - " << parameter.first << ": " << parameter.second << "\n" << std::flush;
 54        fluxEngine::DeviceGroup deviceGroup = fluxEngine::connectDeviceGroup(handle, connectionSettings);
 55        std::cout << "Connected.\n" << std::flush;
 56        fluxEngine::InstrumentDevice* camera = dynamic_cast<fluxEngine::InstrumentDevice*>(deviceGroup.primaryDevice());
 57        if (!camera) {
 58            deviceGroup.disconnect(std::chrono::seconds{5});
 59            throw std::runtime_error("The device is not an instrument device");
 60        }
 61
 62        camera->setupInternalBuffers(5);
 63
 64        /* NOTE:
 65         * For real devices a this point the user should probably be
 66         * asked to insert a white reference underneath the camera.
 67         *
 68         * For the virtual device this is not required.
 69         */
 70
 71        fluxEngine::InstrumentDevice::AcquisitionParameters acqParams;
 72        std::cout << "Measuring white reference:\n" << std::flush;
 73        fluxEngine::BufferContainer whiteReference = fluxEngine::createRingBufferContainer(camera, 10);
 74        acqParams.referenceName = "WhiteReference";
 75        camera->startAcquisition(acqParams);
 76        for (int i = 0; i < 10; ++i) {
 77            fluxEngine::BufferInfo buffer = camera->retrieveBuffer(std::chrono::seconds{1});
 78            if (buffer.ok) {
 79                whiteReference.add(buffer);
 80                camera->returnBuffer(buffer.id);
 81            }
 82        }
 83        camera->stopAcquisition();
 84        std::cout << "Done.\n" << std::flush;
 85
 86        /* NOTE:
 87         * For real devices a this point the user should probably be
 88         * asked to obscure the optics in front of the camera in order
 89         * for a proper dark reference to be measured.
 90         *
 91         * For the virtual device this is not required.
 92         *
 93         * Some cameras do have an internal shutter, where manual user
 94         * intervention is also not required here.
 95         */
 96
 97        std::cout << "Measuring dark reference:\n" << std::flush;
 98        fluxEngine::BufferContainer darkReference = fluxEngine::createBufferContainer(camera, 10);
 99        acqParams.referenceName = "DarkReference";
100        camera->startAcquisition(acqParams);
101        for (int i = 0; i < 10; ++i) {
102            fluxEngine::BufferInfo buffer = camera->retrieveBuffer(std::chrono::seconds{1});
103            if (buffer.ok) {
104                darkReference.add(buffer);
105                camera->returnBuffer(buffer.id);
106            }
107        }
108        camera->stopAcquisition();
109        std::cout << "Done.\n" << std::flush;
110
111        // Create recording context
112        fluxEngine::ProcessingContext::InstrumentParameters instrumentParameters;
113        instrumentParameters.whiteReference = &whiteReference;
114        instrumentParameters.darkReference = &darkReference;
115        fluxEngine::ProcessingContext::HSIRecordingResult contextAndInfo = fluxEngine::ProcessingContext::createInstrumentHSIRecordingContext(camera, fluxEngine::ValueType::Intensity, instrumentParameters, {});
116
117        std::cout << "The recording will create a cube with the wavelengths: [";
118        for (std::size_t i = 0; i < contextAndInfo.wavelengths.size(); ++i) {
119            if (i > 0)
120                std::cout << ", ";
121            std::cout << contextAndInfo.wavelengths[i];
122        }
123        std::cout << "]\n";
124
125        // Create buffer container for recording 100 lines
126        fluxEngine::BufferContainer recordingBuffer = fluxEngine::createBufferContainer(contextAndInfo.context, 100);
127
128        /* NOTE:
129         * For real devices a this point the user should probably be
130         * asked to position the object to measure underneath the
131         * camera and start the motion of the motion control device
132         * they have.
133         *
134         * For the virtual device this is not required.
135         */
136
137        std::cout << "Starting acquisition:\n" << std::flush;
138        acqParams.referenceName = {};
139        camera->startAcquisition(acqParams);
140        std::cout << "Done.\n" << std::flush;
141
142        std::cout << "Recording buffers" << std::flush;
143        while (recordingBuffer.count() < 100) {
144            fluxEngine::BufferInfo buffer = camera->retrieveBuffer(std::chrono::milliseconds{100});
145            if (!buffer.ok)
146                continue;
147
148            contextAndInfo.context.setSourceData(buffer);
149            contextAndInfo.context.processNext();
150            recordingBuffer.addLastResult(contextAndInfo.context);
151            std::cout << '.' << std::flush;
152
153            camera->returnBuffer(buffer.id);
154        }
155        std::cout << "\n" << std::flush;
156
157        std::cout << "Stopping acquisition:\n" << std::flush;
158        camera->stopAcquisition();
159        std::cout << "Done.\n" << std::flush;
160
161        std::cout << "Creating measurement:\n" << std::flush;
162        fluxEngine::MeasurementHSICubeBufferInput recordingInput;
163        recordingInput.name = "Sample recording";
164        recordingInput.valueType = fluxEngine::ValueType::Intensity;
165        recordingInput.bufferContainers.push_back(&recordingBuffer);
166        recordingInput.wavelengths = contextAndInfo.wavelengths;
167        recordingInput.whiteReference = contextAndInfo.whiteReference;
168        recordingInput.darkReference = contextAndInfo.darkReference;
169        recordingInput.calibrationInfo = &contextAndInfo.calibrationInfo;
170        fluxEngine::MeasurementList cube = fluxEngine::createMeasurementHSICube(handle, recordingInput);
171        std::cout << "Done.\n" << std::flush;
172
173        std::cout << "Saving measurement to disk:\n" << std::flush;
174        fluxEngine::saveMeasurementList(handle, cube, "ENVI", g_recordingCubeFileName, true);
175        std::cout << "Done.\n" << std::flush;
176    } catch (std::exception& e) {
177        std::cerr << "Error: " << e.what() << std::endl;
178        return 1;
179    } catch (...) {
180        std::cerr << "Unknown error." << std::endl;
181        return 1;
182    }
183
184    return 0;
185}

This source file will compile to the executable ExamplePushBroomCreateENVI.

The following classes and methods are among those used in this example:

.NET

The source code of the example can be found in the file ExamplePushBroomCreateENVI\Program.cs.

  1using System;
  2
  3namespace ExamplePushBroomCreateENVI
  4{
  5    class Program
  6    {
  7        static void Main(string[] args)
  8        {
  9            Console.WriteLine("fluxEngine version: " + LuxFlux.fluxEngineNET.Version.String);
 10            var handle = new LuxFlux.fluxEngineNET.Handle(ExampleHelpers.IO.ReadLicenseFile());
 11            handle.SetDriverBaseDirectory(ExampleHelpers.Paths.DriverDirectory);
 12            handle.CreateProcessingThreads(4);
 13
 14            // Load virtual camera
 15            var enumeratedDevices = LuxFlux.fluxEngineNET.DeviceEnumeration.EnumerateDevices(handle, null, TimeSpan.FromSeconds(1));
 16            LuxFlux.fluxEngineNET.EnumeratedDevice virtualCameraDevice = null;
 17            foreach (var device in enumeratedDevices.Devices)
 18            {
 19                if (device.Driver.Name == "VirtualHyperCamera")
 20                {
 21                    virtualCameraDevice = device;
 22                    break;
 23                }
 24            }
 25
 26            if (virtualCameraDevice == null)
 27                throw new Exception("Could not find virtual camera driver");
 28
 29            var connectionSettings = new LuxFlux.fluxEngineNET.ConnectionSettings();
 30            connectionSettings.DriverName = virtualCameraDevice.Driver.Name;
 31            connectionSettings.DriverType = virtualCameraDevice.Driver.Type;
 32            connectionSettings.Id = virtualCameraDevice.Id;
 33            connectionSettings.Timeout = TimeSpan.FromSeconds(60);
 34            connectionSettings.ConnectionParameters = new System.Collections.Generic.Dictionary<string, string>();
 35            connectionSettings.ConnectionParameters["Cube"] = ExampleHelpers.Paths.ExampleDataFileName("MiniCube.hdr");
 36            connectionSettings.ConnectionParameters["WhiteReferenceCube"] = ExampleHelpers.Paths.ExampleDataFileName("MiniCube_White.hdr");
 37            connectionSettings.ConnectionParameters["DarkReferenceCube"] = ExampleHelpers.Paths.ExampleDataFileName("MiniCube_Dark.hdr");
 38
 39            Console.WriteLine("Attempting to connect to device...");
 40            var deviceGroup = LuxFlux.fluxEngineNET.DeviceGroup.Connect(handle, connectionSettings);
 41            Console.WriteLine("Connected.");
 42            if (!(deviceGroup.PrimaryDevice is LuxFlux.fluxEngineNET.InstrumentDevice))
 43            {
 44                deviceGroup.Disconnect(TimeSpan.FromSeconds(5));
 45                throw new Exception("The device is not an instrument device.");
 46            }
 47            var camera = (LuxFlux.fluxEngineNET.InstrumentDevice)deviceGroup.PrimaryDevice;
 48
 49            camera.SetupInternalBuffers(5);
 50
 51
 52            /* NOTE:
 53             * For real devices a this point the user should probably be
 54             * asked to insert a white reference underneath the camera.
 55             *
 56             * For the virtual device this is not required.
 57             */
 58
 59            var acqParams = new LuxFlux.fluxEngineNET.InstrumentDevice.AcquisitionParameters();
 60            Console.WriteLine("Measuring white reference:");
 61            var whiteReference = LuxFlux.fluxEngineNET.Util.CreateRingBufferContainer(camera, 10);
 62            acqParams.ReferenceName = "WhiteReference";
 63            camera.StartAcquisition(acqParams);
 64            for (int i = 0; i < 10; ++i)
 65            {
 66                var buffer = camera.RetrieveBuffer(TimeSpan.FromSeconds(1));
 67                if (buffer != null)
 68                {
 69                    try
 70                    {
 71                        whiteReference.Add(buffer);
 72                    }
 73                    finally
 74                    {
 75                        camera.ReturnBuffer(buffer);
 76                    }
 77                }
 78            }
 79            camera.StopAcquisition();
 80            Console.WriteLine("Done.");
 81
 82            /* NOTE:
 83             * For real devices a this point the user should probably be
 84             * asked to obscure the optics in front of the camera in order
 85             * for a proper dark reference to be measured.
 86             *
 87             * For the virtual device this is not required.
 88             *
 89             * Some cameras do have an internal shutter, where manual user
 90             * intervention is also not required here.
 91             */
 92
 93            Console.WriteLine("Measuring dark reference:");
 94            var darkReference = LuxFlux.fluxEngineNET.Util.CreateRingBufferContainer(camera, 10);
 95            acqParams.ReferenceName = "DarkReference";
 96            camera.StartAcquisition(acqParams);
 97            for (int i = 0; i < 10; ++i)
 98            {
 99                var buffer = camera.RetrieveBuffer(TimeSpan.FromSeconds(1));
100                if (buffer != null)
101                {
102                    try
103                    {
104                        darkReference.Add(buffer);
105                    }
106                    finally
107                    {
108                        camera.ReturnBuffer(buffer);
109                    }
110                }
111            }
112            camera.StopAcquisition();
113            Console.WriteLine("Done.");
114
115            // Create recording context
116            var instrumentReferences = new LuxFlux.fluxEngineNET.ProcessingContext.BufferReferenceInput();
117            instrumentReferences.WhiteReference = whiteReference;
118            instrumentReferences.DarkReference = darkReference;
119            var instrumentParameters = new LuxFlux.fluxEngineNET.ProcessingContext.InstrumentParameters();
120            instrumentParameters.ReferenceInput = instrumentReferences;
121
122            var contextAndInfo = LuxFlux.fluxEngineNET.ProcessingContext.CreateForInstrumentHSIRecording(camera, LuxFlux.fluxEngineNET.ValueType.Intensity, instrumentParameters);
123            Console.WriteLine($"The recording will create a cube with the wavelengths: [{string.Join(", ", contextAndInfo.Wavelengths)}]");
124
125            // Create buffer container for recording 100 lines
126            var recordingBuffer = LuxFlux.fluxEngineNET.Util.CreateBufferContainer(contextAndInfo.Context, 100);
127
128            /* NOTE:
129             * For real devices a this point the user should probably be
130             * asked to position the object to measure underneath the
131             * camera and start the motion of the motion control device
132             * they have.
133             *
134             * For the virtual device this is not required.
135             */
136
137            Console.WriteLine("Starting acquisition:");
138            acqParams.ReferenceName = null;
139            camera.StartAcquisition(acqParams);
140            Console.WriteLine("Done.");
141
142            Console.Out.Write("Recording buffers");
143            Console.Out.Flush();
144            while (recordingBuffer.Count < 100)
145            {
146                var buffer = camera.RetrieveBuffer(TimeSpan.FromMilliseconds(100));
147                if (buffer == null)
148                    continue;
149
150                try
151                {
152                    contextAndInfo.Context.SetSourceData(buffer);
153                    contextAndInfo.Context.ProcessNext();
154                    recordingBuffer.AddLastResult(contextAndInfo.Context);
155                    Console.Out.Write(".");
156                    Console.Out.Flush();
157                }
158                finally
159                {
160                    camera.ReturnBuffer(buffer);
161                }
162            }
163            Console.WriteLine("");
164
165            Console.WriteLine("Stopping acquisition:");
166            camera.StopAcquisition();
167            Console.WriteLine("Done.");
168
169            Console.WriteLine("Creating measurement:");
170            var recordingInput = new LuxFlux.fluxEngineNET.MeasurementHSICubeBufferInput();
171            recordingInput.Name = "Sample recording";
172            recordingInput.ValueType = LuxFlux.fluxEngineNET.ValueType.Intensity;
173            recordingInput.BufferContainers = new LuxFlux.fluxEngineNET.BufferContainer[1];
174            recordingInput.BufferContainers[0] = recordingBuffer;
175            recordingInput.WhiteReference = contextAndInfo.WhiteReference;
176            recordingInput.DarkReference = contextAndInfo.DarkReference;
177            recordingInput.IlluminationReference = contextAndInfo.IlluminationReference;
178            recordingInput.CalibrationInfo = contextAndInfo.CalibrationInfo;
179            recordingInput.Wavelengths = contextAndInfo.Wavelengths;
180            var cube = LuxFlux.fluxEngineNET.MeasurementList.CreateForHSICube(handle, recordingInput);
181            Console.WriteLine("Done.");
182
183            Console.WriteLine("Saving measurement to disk:");
184            LuxFlux.fluxEngineNET.IO.SaveMeasurementList(handle, cube, "ENVI", ExampleHelpers.Paths.RecordingCubeFileName, true);
185            Console.WriteLine("Done.");
186
187            Console.WriteLine("Disconnecting from device...");
188            deviceGroup.Disconnect(TimeSpan.FromSeconds(5));
189            Console.WriteLine("Done.");
190            cube.Dispose();
191            handle.Dispose();
192        }
193    }
194}

The following classes and methods are among those used in this example:

Python

The source code of the example can be found in the file example_pushbroom_create_envi.py:

  1#!/usr/bin/env python3
  2
  3import fluxEngine
  4import os, sys
  5
  6import fluxEngine_example_paths as paths
  7data_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'data')
  8
  9print('fluxEngine version {}'.format(fluxEngine.versionString()))
 10with open(paths.licenseFileName, 'rb') as f:
 11    handle = fluxEngine.Handle(f.read())
 12handle.setDriverBaseDirectory(paths.driverDirectory)
 13handle.createProcessingThreads(4)
 14
 15enumeratedDevices = fluxEngine.enumerateDevices(handle, -1, 5000)
 16virtualCameraDevice = None
 17for device in enumeratedDevices.devices:
 18    if device.driver.name == 'VirtualHyperCamera':
 19        virtualCameraDevice = device
 20
 21if not virtualCameraDevice:
 22    raise Exception('Could not find virtual camera driver')
 23
 24connectionSettings = fluxEngine.ConnectionSettings(virtualCameraDevice.driver.name, virtualCameraDevice.driver.type, virtualCameraDevice.id)
 25connectionSettings.timeout = 60000
 26connectionSettings.connectionParameters['Cube'] = os.path.join(data_dir, 'MiniCube.hdr')
 27connectionSettings.connectionParameters['WhiteReferenceCube'] = os.path.join(data_dir, 'MiniCube_White.hdr')
 28connectionSettings.connectionParameters['DarkReferenceCube'] = os.path.join(data_dir, 'MiniCube_Dark.hdr')
 29
 30print("Attempting to connect to device...")
 31deviceGroup = fluxEngine.DeviceGroup(handle, connectionSettings)
 32print("Connected.")
 33
 34camera = deviceGroup.primaryDevice()
 35if not isinstance(camera, fluxEngine.InstrumentDevice):
 36    deviceGroup.disconnect(5000)
 37    raise Exception('The device is not an instrument device')
 38
 39camera.setupInternalBuffers(5)
 40
 41# NOTE:
 42# For real devices a this point the user should probably be
 43# asked to insert a white reference underneath the camera.
 44#
 45# For the virtual device this is not required.
 46
 47acqParams = fluxEngine.InstrumentDevice.AcquisitionParameters()
 48
 49print('Measuring white reference:')
 50whiteReference = fluxEngine.BufferContainer(camera, 10)
 51acqParams.referenceName = "WhiteReference"
 52camera.startAcquisition(acqParams)
 53for i in range(10):
 54    buffer = camera.retrieveBuffer(1000)
 55    if buffer:
 56        whiteReference.add(buffer)
 57        camera.returnBuffer(buffer)
 58camera.stopAcquisition()
 59print('Done.')
 60
 61# NOTE:
 62# For real devices a this point the user should probably be
 63# asked to obscure the optics in front of the camera in order
 64# for a proper dark reference to be measured.
 65#
 66# For the virtual device this is not required.
 67#
 68# Some cameras do have an internal shutter, where manual user
 69# intervention is also not required here.
 70#
 71
 72print('Measuring dark reference:')
 73darkReference = fluxEngine.BufferContainer(camera, 10)
 74acqParams.referenceName = "DarkReference"
 75camera.startAcquisition(acqParams)
 76for i in range(10):
 77    buffer = camera.retrieveBuffer(1000)
 78    if buffer:
 79        darkReference.add(buffer)
 80        camera.returnBuffer(buffer)
 81camera.stopAcquisition()
 82print('Done.')
 83
 84# Create recording contect
 85instrumentParameters = fluxEngine.InstrumentParameters()
 86instrumentParameters.whiteReference = whiteReference
 87instrumentParameters.darkReference = darkReference
 88
 89context = fluxEngine.ProcessingContext(None, fluxEngine.ProcessingContext.InstrumentHSIRecording,
 90                                       device=camera,
 91                                       valueType=fluxEngine.ValueType.Intensity,
 92                                       instrumentParameters=instrumentParameters)
 93recordingInfo = context.hsiRecordingResultInfo()
 94
 95print("The recording will create a cube with the wavelengths: [{}]".format(", ".join('{}'.format(l) for l in recordingInfo.wavelengths)))
 96
 97# Create buffer container for recording 100 lines
 98recordingBuffer = fluxEngine.createBufferContainerForRecordingContext(context, 100)
 99
100# NOTE:
101# For real devices a this point the user should probably be
102# asked to position the object to measure underneath the
103# camera and start the motion of the motion control device
104# they have.
105#
106# For the virtual device this is not required.
107#
108
109print('Starting acquisition:')
110acqParams.referenceName = None
111camera.startAcquisition(acqParams)
112print('Done.')
113
114print('Recording buffers:')
115while recordingBuffer.count() < 100:
116    buffer = camera.retrieveBuffer(100)
117    if not buffer:
118        continue
119
120    context.setSourceData(buffer)
121    context.processNext()
122    recordingBuffer.addLastResult(context)
123    sys.stdout.write('.')
124    sys.stdout.flush()
125    camera.returnBuffer(buffer)
126sys.stdout.write('\n')
127print('Done.')
128
129print('Stopping acquisition:')
130camera.stopAcquisition()
131print('Done.')
132
133print('Creating measurement:')
134recordingInput = fluxEngine.MeasurementHSICubeBufferInput()
135recordingInput.name = "Sample recording"
136recordingInput.valueType = fluxEngine.ValueType.Intensity
137recordingInput.bufferContainers.append(recordingBuffer)
138recordingInput.wavelengths = recordingInfo.wavelengths
139recordingInput.whiteReference = recordingInfo.whiteReference
140recordingInput.darkReference = recordingInfo.darkReference
141recordingInput.calibrationInfo = recordingInfo.calibrationInfo
142
143cube = fluxEngine.createMeasurementHSICube(handle, recordingInput)
144print('Done.')
145
146print('Saving measurement to disk:')
147fluxEngine.saveMeasurementList(handle, cube, "ENVI", paths.recordingCubeFileName, True)
148print('Done.')

The following classes and methods are among those used in this example:

Expected Output

The output should look like the following:

fluxEngine version: [...]
Attempting to connect to device...
- DarkReferenceCube: examples/data/MiniCube_Dark.hdr
- Cube: examples/data/MiniCube.hdr
- WhiteReferenceCube: examples/data/MiniCube_White.hdr
Connected.
Measuring white reference:
Done.
Measuring dark reference:
Done.
The recording will create a cube with the wavelengths: [945.03, 948.2, 951.37, 954.54, 957.7, 960.87, 964.04, 967.2, 970.37, 973.54, 976.7, 979.86, 983.03, 986.19, 989.36, 992.52, 995.68, 998.84, 1002, 1005.16, 1008.33, 1011.49, 1014.65, 1017.8, 1020.96, 1024.12, 1027.28, 1030.44, 1033.6, 1036.75, 1039.91, 1043.06, 1046.22, 1049.38, 1052.53, 1055.68, 1058.84, 1061.99, 1065.15, 1068.3, 1071.45, 1074.6, 1077.75, 1080.9, 1084.06, 1087.21, 1090.36, 1093.5, 1096.65, 1099.8, 1102.95, 1106.1, 1109.25, 1112.39, 1115.54, 1118.69, 1121.83, 1124.98, 1128.12, 1131.27, 1134.41, 1137.55, 1140.7, 1143.84, 1146.98, 1150.12, 1153.27, 1156.41, 1159.55, 1162.69, 1165.83, 1168.97, 1172.11, 1175.25, 1178.39, 1181.52, 1184.66, 1187.8, 1190.94, 1194.07, 1197.21, 1200.34, 1203.48, 1206.61, 1209.75, 1212.88, 1216.02, 1219.15, 1222.28, 1225.41, 1228.55, 1231.68, 1234.81, 1237.94, 1241.07, 1244.2, 1247.33, 1250.46, 1253.59, 1256.72, 1259.85, 1262.97, 1266.1, 1269.23, 1272.36, 1275.48, 1278.61, 1281.73, 1284.86, 1287.98, 1291.11, 1294.23, 1297.35, 1300.48, 1303.6, 1306.72, 1309.85, 1312.97, 1316.09, 1319.21, 1322.33, 1325.45, 1328.57, 1331.69, 1334.81, 1337.93, 1341.04, 1344.16, 1347.28, 1350.4, 1353.51, 1356.63, 1359.75, 1362.86, 1365.98, 1369.09, 1372.21, 1375.32, 1378.43, 1381.55, 1384.66, 1387.77, 1390.88, 1394, 1397.11, 1400.22, 1403.33, 1406.44, 1409.55, 1412.66, 1415.77, 1418.88, 1421.99, 1425.09, 1428.2, 1431.31, 1434.42, 1437.52, 1440.63, 1443.73, 1446.84, 1449.94, 1453.05, 1456.15, 1459.26, 1462.36, 1465.47, 1468.57, 1471.67, 1474.77, 1477.87, 1480.98, 1484.08, 1487.18, 1490.28, 1493.38, 1496.48, 1499.58, 1502.68, 1505.78, 1508.87, 1511.97, 1515.07, 1518.17, 1521.26, 1524.36, 1527.46, 1530.55, 1533.65, 1536.74, 1539.84, 1542.93, 1546.02, 1549.12, 1552.21, 1555.3, 1558.4, 1561.49, 1564.58, 1567.67, 1570.76, 1573.85, 1576.94, 1580.03, 1583.12, 1586.21, 1589.3, 1592.39, 1595.48, 1598.57, 1601.66, 1604.74, 1607.83, 1610.92, 1614, 1617.09, 1620.17, 1623.26, 1626.34, 1629.43, 1632.51, 1635.6, 1638.68, 1641.76, 1644.85, 1647.93, 1651.01, 1654.09, 1657.17, 1660.25, 1663.34, 1666.42, 1669.5, 1672.58, 1675.66, 1678.73, 1681.81, 1684.89, 1687.97, 1691.05, 1694.12, 1697.2, 1700.28, 1703.35, 1706.43, 1709.51, 1712.58, 1715.66, 1718.73, 1721.81, 1724.88, 1727.95, 1731.03, 1734.1, 1737.17, 1740.24]
Starting acquisition:
Done.
Recording buffers....................................................................................................
Stopping acquisition:
Done.
Creating measurement:
Done.
Saving measurement to disk:
Done.

This will then store an ENVI cube in the file name specified in g_recordingCubeFileName (C++) or recordingCubeFileName (Python). The cube will be saved in intensities, and a white and dark reference cube will also be written.