Record an ENVI Cube in Intensities with References from a PushBroom While Generating a Preview

This example is identical to the PushBroom recording example, but it also generates a preview image at the same time while the recording is being performed. This may be useful when creating a user-facing application that wants to display a preview of the data that is currently being recorded, while not having to create a separate processing context for the preview data itself.

C++

The source code of the example can be found in the file example_pushbroom_create_envi_with_preview.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        instrumentParameters.flags |= fluxEngine::DeviceProcessingContext_CreationFlag_AdditionalPreview;
116        fluxEngine::ProcessingContext::HSIRecordingResult contextAndInfo = fluxEngine::ProcessingContext::createInstrumentHSIRecordingContext(camera, fluxEngine::ValueType::Intensity, instrumentParameters, {});
117
118        std::cout << "The recording will create a cube with the wavelengths: [";
119        for (std::size_t i = 0; i < contextAndInfo.wavelengths.size(); ++i) {
120            if (i > 0)
121                std::cout << ", ";
122            std::cout << contextAndInfo.wavelengths[i];
123        }
124        std::cout << "]\n";
125
126        // Create buffer container for recording 100 lines
127        fluxEngine::BufferContainer recordingBuffer = fluxEngine::createBufferContainer(contextAndInfo.context, 100);
128
129        /* NOTE:
130         * For real devices a this point the user should probably be
131         * asked to position the object to measure underneath the
132         * camera and start the motion of the motion control device
133         * they have.
134         *
135         * For the virtual device this is not required.
136         */
137
138        std::cout << "Starting acquisition:\n" << std::flush;
139        acqParams.referenceName = {};
140        camera->startAcquisition(acqParams);
141        std::cout << "Done.\n" << std::flush;
142
143        std::cout << "Recording buffers while generating preview:\n" << std::flush;
144        while (recordingBuffer.count() < 100) {
145            fluxEngine::BufferInfo buffer = camera->retrieveBuffer(std::chrono::milliseconds{100});
146            if (!buffer.ok)
147                continue;
148
149            contextAndInfo.context.setSourceData(buffer);
150            contextAndInfo.context.processNext();
151            recordingBuffer.addLastResult(contextAndInfo.context);
152
153            // Get preview
154            fluxEngine::TensorData data{contextAndInfo.context.outputSinkData(1)};
155            // Output the first 6 pixels of the preview for each line
156            if (data.dataType() == fluxEngine::DataType::Float64) {
157                for (int x = 0; x < 6; ++x) {
158                    if (x > 0)
159                        std::cout << ' ';
160                    std::cout << std::setw(20) << data.at<double>(0, x, 0) << std::setw(0);
161                }
162                std::cout << '\n' << std::flush;
163            } else if (data.dataType() == fluxEngine::DataType::Float32) {
164                for (int x = 0; x < 6; ++x) {
165                    if (x > 0)
166                        std::cout << ' ';
167                    std::cout << std::setw(20) << data.at<float>(0, x, 0) << std::setw(0);
168                }
169                std::cout << '\n' << std::flush;
170            }
171
172            camera->returnBuffer(buffer.id);
173        }
174        std::cout << "\n" << std::flush;
175
176        std::cout << "Stopping acquisition:\n" << std::flush;
177        camera->stopAcquisition();
178        std::cout << "Done.\n" << std::flush;
179
180        std::cout << "Creating measurement:\n" << std::flush;
181        fluxEngine::MeasurementHSICubeBufferInput recordingInput;
182        recordingInput.name = "Sample recording";
183        recordingInput.valueType = fluxEngine::ValueType::Intensity;
184        recordingInput.bufferContainers.push_back(&recordingBuffer);
185        recordingInput.wavelengths = contextAndInfo.wavelengths;
186        recordingInput.whiteReference = contextAndInfo.whiteReference;
187        recordingInput.darkReference = contextAndInfo.darkReference;
188        recordingInput.calibrationInfo = &contextAndInfo.calibrationInfo;
189        fluxEngine::MeasurementList cube = fluxEngine::createMeasurementHSICube(handle, recordingInput);
190        std::cout << "Done.\n" << std::flush;
191
192        std::cout << "Saving measurement to disk:\n" << std::flush;
193        fluxEngine::saveMeasurementList(handle, cube, "ENVI", g_recordingCubeFileName, true);
194        std::cout << "Done.\n" << std::flush;
195    } catch (std::exception& e) {
196        std::cerr << "Error: " << e.what() << std::endl;
197        return 1;
198    } catch (...) {
199        std::cerr << "Unknown error." << std::endl;
200        return 1;
201    }
202
203    return 0;
204}

This source file will compile to the executable ExamplePushBroomCreateENVIWithPreview.

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 ExamplePushBroomCreateENVIWithPreview\Program.cs.

  1using System;
  2
  3namespace ExamplePushBroomCreateENVIWithPreview
  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            instrumentParameters.CreationFlags |= LuxFlux.fluxEngineNET.ProcessingContext.DeviceContextCreationFlags.AdditionalPreview;
122
123            var contextAndInfo = LuxFlux.fluxEngineNET.ProcessingContext.CreateForInstrumentHSIRecording(camera, LuxFlux.fluxEngineNET.ValueType.Intensity, instrumentParameters);
124            Console.WriteLine($"The recording will create a cube with the wavelengths: [{string.Join(", ", contextAndInfo.Wavelengths)}]");
125
126            // Create buffer container for recording 100 lines
127            var recordingBuffer = LuxFlux.fluxEngineNET.Util.CreateBufferContainer(contextAndInfo.Context, 100);
128
129            /* NOTE:
130             * For real devices a this point the user should probably be
131             * asked to position the object to measure underneath the
132             * camera and start the motion of the motion control device
133             * they have.
134             *
135             * For the virtual device this is not required.
136             */
137
138            Console.WriteLine("Starting acquisition:");
139            acqParams.ReferenceName = null;
140            camera.StartAcquisition(acqParams);
141            Console.WriteLine("Done.");
142
143            Console.WriteLine("Recording buffers while generating preview:");
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
156                    var data = contextAndInfo.Context.OutputSinkData(1).AsTensorCopy();
157                    // Output the first 6 pixels of the preview for each line
158                    if (data.DataType == LuxFlux.fluxEngineNET.DataType.Float64)
159                    {
160                        for (int x = 0; x < 6; ++x)
161                        {
162                            if (x > 0)
163                                Console.Write(" ");
164                            Console.Write(string.Format("{0,20}", data.Value<double>(0, x, 0)));
165                        }
166                        Console.WriteLine("");
167                    }
168                    else if (data.DataType == LuxFlux.fluxEngineNET.DataType.Float32)
169                    {
170                        for (int x = 0; x < 6; ++x)
171                        {
172                            if (x > 0)
173                                Console.Write(" ");
174                            Console.Write(string.Format("{0,20}", data.Value<float>(0, x, 0)));
175                        }
176                        Console.WriteLine("");
177                    }
178
179                }
180                finally
181                {
182                    camera.ReturnBuffer(buffer);
183                }
184            }
185            Console.WriteLine("Done.");
186
187            Console.WriteLine("Stopping acquisition:");
188            camera.StopAcquisition();
189            Console.WriteLine("Done.");
190
191            Console.WriteLine("Creating measurement:");
192            var recordingInput = new LuxFlux.fluxEngineNET.MeasurementHSICubeBufferInput();
193            recordingInput.Name = "Sample recording";
194            recordingInput.ValueType = LuxFlux.fluxEngineNET.ValueType.Intensity;
195            recordingInput.BufferContainers = new LuxFlux.fluxEngineNET.BufferContainer[1];
196            recordingInput.BufferContainers[0] = recordingBuffer;
197            recordingInput.WhiteReference = contextAndInfo.WhiteReference;
198            recordingInput.DarkReference = contextAndInfo.DarkReference;
199            recordingInput.IlluminationReference = contextAndInfo.IlluminationReference;
200            recordingInput.CalibrationInfo = contextAndInfo.CalibrationInfo;
201            recordingInput.Wavelengths = contextAndInfo.Wavelengths;
202            var cube = LuxFlux.fluxEngineNET.MeasurementList.CreateForHSICube(handle, recordingInput);
203            Console.WriteLine("Done.");
204
205            Console.WriteLine("Saving measurement to disk:");
206            LuxFlux.fluxEngineNET.IO.SaveMeasurementList(handle, cube, "ENVI", ExampleHelpers.Paths.RecordingCubeFileName, true);
207            Console.WriteLine("Done.");
208
209            Console.WriteLine("Disconnecting from device...");
210            deviceGroup.Disconnect(TimeSpan.FromSeconds(5));
211            Console.WriteLine("Done.");
212            cube.Dispose();
213            handle.Dispose();
214        }
215    }
216}

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_with_preview.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
 88instrumentParameters.flags |= fluxEngine.DeviceProcessingContextCreationFlag.AdditionalPreview
 89
 90context = fluxEngine.ProcessingContext(None, fluxEngine.ProcessingContext.InstrumentHSIRecording,
 91                                       device=camera,
 92                                       valueType=fluxEngine.ValueType.Intensity,
 93                                       instrumentParameters=instrumentParameters)
 94recordingInfo = context.hsiRecordingResultInfo()
 95
 96print("The recording will create a cube with the wavelengths: [{}]".format(", ".join('{}'.format(l) for l in recordingInfo.wavelengths)))
 97
 98# Create buffer container for recording 100 lines
 99recordingBuffer = fluxEngine.createBufferContainerForRecordingContext(context, 100)
100
101# NOTE:
102# For real devices a this point the user should probably be
103# asked to position the object to measure underneath the
104# camera and start the motion of the motion control device
105# they have.
106#
107# For the virtual device this is not required.
108#
109
110print('Starting acquisition:')
111acqParams.referenceName = None
112camera.startAcquisition(acqParams)
113print('Done.')
114
115print('Recording buffers while generating preview:')
116while recordingBuffer.count() < 100:
117    buffer = camera.retrieveBuffer(100)
118    if not buffer:
119        continue
120
121    context.setSourceData(buffer)
122    context.processNext()
123    recordingBuffer.addLastResult(context)
124    data = context.outputSinkData(1)
125    print(data[0, :6, 0])
126    camera.returnBuffer(buffer)
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: 4.11.0~rc1
Attempting to connect to device...
  - DarkReferenceCube: /home/christian/LuxFlux/Code/fluxEnginePublic/examples/data/MiniCube_Dark.hdr
  - WhiteReferenceCube: /home/christian/LuxFlux/Code/fluxEnginePublic/examples/data/MiniCube_White.hdr
  - Cube: /home/christian/LuxFlux/Code/fluxEnginePublic/examples/data/MiniCube.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 while generating preview:
             7217.22              7160.26              7168.58              7146.76              7159.23              7192.86
             7348.53              7317.49              7322.11              7314.67              7316.54              7305.82
             7441.55              7431.62              7447.21               7439.7               7431.3              7396.99
[... more output here ...]
             7348.53              7317.49              7322.11              7314.67              7316.54              7305.82
             7441.55              7431.62              7447.21               7439.7               7431.3              7396.99
             7485.26              7476.21               7511.7              7488.82              7479.78              7450.21

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 reflectances, and no references will be saved for this reason.