ROI Integration (Online Analysis)¶
ScanImage® allows to select several regions of interest (ROIs) for live analysis. The pixel intensities within these ROIs is averaged. The resulting time trace is plotted over time in the ROI Integration Display and can be used to drive a digital or analog output.
ROI Integration Experiment Setup
Integration ROIs¶
An Integration ROI is a 3D object, that defines the geometry of an image feature. See Scanfields, ROIs, ROI Groups to learn more about the ROI concept. The ROI is defined by 2D-cross sections at different z-positions. For each of these slices, a mask can be defined that weighs the underlying pixel values.
Calculation of Intensity¶
If no mask is assigned to an integration ROI, the sum of all pixels of the ROI is calculated and is divided by the number of all pixels in the ROI. If the ROI stretches over more than one slice, the sum of all pixels of all slices in the ROI is calculated. The final output is generated when the last slice of the integration ROI is acquired.
If a mask is assigned to an integration ROI, each pixel is multiplied by the associate weight of the mask. Next, the sum of all weighted pixels is calculated. This sum is then divided by the sum of all elements in the mask.
Attention
The ROI integration is done in the Matlab thread. If processing a single frame does not finish before the next frame arrives, Matlab can drop the incoming frame to stay in sync with the acquisition (the frame data is still logged to disk in this case). If this happens, the ROI Integration does not process the dropped frame.
Output File Format¶
If ROI Integration is enabled in the Integration Control Window, saving is enabled in the Main Controls Window <Main Controls>, and a Grab or Loop is performed, ScanImage® saves the integration value for all integration values into a CSV file, which is located in the same directory as the Tiff file containing the video stream.
Programmatic ROI access¶
The integration ROIs can be created, modified and deleted using the ScanImage® API. See ROI API to learn more.
hSI.hIntegrationRoiManager.roiGroup.rois(1).scanfields(1).centerXY = [1,1]; % define the center of the scanfield in scan angle coordinates
hSI.hIntegrationRoiManager.roiGroup.rois(1).scanfields(1).sizeXY = [1,1]; % define the size of the scanfield in scan angle coordinates
hSI.hIntegrationRoiManager.roiGroup.rois(1).scanfields(1).mask = rand(10,10); % define a (random) weighted mask for an integration scanfield
ROI PostProcessing¶
The IntegrationRoiManager weighs pixel values according to a mask and sums the weighted values to form the integration value. This integration value is displayed without further analysis. However, it might be desired to perform additional computation on the integration values (e.g. to calculate dF/F). This can be done by defining a post processing function.
The IntegrationRoiManager has a property ‘postProcessFcn’. This property defines a function handle points to a function, which, by default, passes the integrationValues through without any processing. By changing this function handle, a different functionality can be achieved.
hSI.hIntegrationRoiManager.postProcessFcn = @myPostProcessingFunction; % overwrite the default value of 'postProcessFcn'
To get started with your own postProcessingFcn, inspect the default post processing function
Default function¶
1integrationValues = integrationPostProcessingFcn(rois,integrationDone,arrayIndices,integrationValueHistory,integrationTimestampHistory,integrationFrameNumberHistory)
2 % This function is used to post process integration values
3 % standard behavior: pass the integration values through without changing the calculated values
4 integrationValues = integrationValueHistory(arrayIndices);
5end
This function can be changed to use the integration history for generating values:
Example: Average last three values¶
integrationValues = integrationPostProcessingFcn(rois,integrationDone,arrayIndices,integrationValueHistory,integrationTimestampHistory,integrationFrameNumberHistory)
historyLength = size(integrationValueHistory,1);
numRois = size(integrationValueHistory,2);
[is,js] = ind2sub(size(integrationValueHistory),arrayIndices); % get the line and row indices of the current integration values
is = [is-2;is-1;is]; % % get row indices for last three values
is(is<1) = historyLength - is(is<1); % integrationValueHistory is a rolling buffer. roll over rowindex over if i < 1
js = [js;js;js];
idx = sub2ind(is,js); % get 3xn index matrix
vals = integrationValueHistory(idx); % get last 3 values for each integration roi
integrationValues = mean(vals,1); % average last 3 values, return post processed value
end
Warning
The post processing function will be called several times during a volume. Makes sure to optimize the function for performance, so that the the processing pipeline is not slowed down.
Note
only values that are flagged by ‘integrationDone’ actually were updated when the post processing function was called. To optimize for performance, only these values need to be post processed
Performance optimization¶
1integrationValues = integrationPostProcessingFcn(rois,integrationDone,arrayIndices,integrationValueHistory,integrationTimestampHistory,integrationFrameNumberHistory)
2 historyLength = size(integrationValueHistory,1);
3 numRois = size(integrationValueHistory,2);
4
5
6 arrayIndices_ = arrayIndices(integrationDone); % get arrayIndices for values that changed
7 [is,js] = ind2sub(size(integrationValueHistory),arrayIndices_); % get the line and row indices of the new values
8
9 is = [is-2;is-1;is]; % % get row indices for last three values
10 is(is<1) = historyLength - is(is<1); % integrationValueHistory is a rolling buffer. roll over rowindex over if i < 1
11 js = [js;js;js];
12
13 idx = sub2ind(is,js); % get 3xn index matrix
14 vals = integrationValueHistory(idx); % get last 3 values for each integration roi
15
16 integrationValues = nan(1,numRois);
17 integrationValues(integrationDone) = mean(vals,1); % only update relevant values
18end
Application example¶
Application idea: overwrite the integrationValue of the last roi to show a peak every 30th frame
1integrationValues = integrationPostProcessingFcn(rois,integrationDone,arrayIndices,integrationValueHistory,integrationTimestampHistory,integrationFrameNumberHistory)
2 integrationValues = integrationValueHistory(arrayIndices);
3 % overwrite value for last integration roi
4 frameNumber = integrationFrameNumber(arrayIndices(end));
5 tfmultiple30 = mod(frameNumber,30)==0;
6 if tfmultiple30
7 integrationValues(end) = Inf;
8 else
9 integrationValues(end) = 0;
10 end
11end
Motion Correction¶
If the sample moves during an active acquisition, the pre-defined Integration ROIs might not process the correct portion of the image. To ensure the Integration ROIs track the sample, enable ScanImage’s Motion Correction feature.
Output Channels¶
The output generated by the ROI Integration module can be used to drive analog and digital outputs or to call user defined functions. See ROI Integration Output Channels for more information.