ScannerSet and Scanner Models

A scanimage.mroi.scannerset.ScannerSet is the layer between geometry and voltages. Give it a scanfield and it produces the scan path and, from that, the analog output samples that drive the mirrors, the FastZ actuator and the beams. It also answers the timing questions - how long a line takes, how long a transit between scanfields takes, how much flyback padding a frame needs.

Every Scan2D exposes the one it is currently configured for:

ss = hSI.hScan2D.scannerset;         % read-only, recomputed on configuration changes
ss = hSI.hScan2D.stimScannerset;     % the set used for photostimulation output

hSI.hWaveformManager is the component that drives this; you mostly read a scanner set rather than build one, but building one by hand is exactly how the offline analysis utilities reconstruct scan geometry from a logged file.


Scanner set classes

Class

Scanner combination

scannerset.GalvoGalvo

Two galvos. Linear scanning; spatial and temporal fill fractions are equal.

scannerset.ResonantGalvoGalvo

Resonant fast axis plus two galvos.

scannerset.SLM

Spatial light modulator based scanning.

scannerset.ResonantStageScanner

Resonant scanning combined with stage motion.

Note

Polygonal scanning does not have a scanner set of its own. A polygonal scanner is a dabs.resources.devices.SyncedScanner like a resonant scanner is, so RggScan accepts it as its hResonantScanner and builds a ResonantGalvoGalvo from it. The isPolygonalScanning flag on the imaging system records which kind of synced scanner is attached.

Each has a static default() constructor that builds a plausible set with no hardware attached - the entry point for offline work:

ss = scanimage.mroi.scannerset.GalvoGalvo.default;

Common members

scanimage.mroi.scannerset.ScannerSet is the abstract base.

Composition

Property

Description

name

Name of the set.

scanners

Cell array of the scanner models - see below. For a galvo-galvo set, scanners{1} is X and scanners{2} is Y.

beams

Fast beam models.

slowbeams

Slow beam models.

fastz

FastZ model.

slm

SLM models.

beamRouters, globalCurvatureCorrectors

Attached beam routers and curvature correctors.

angularRange

Abstract. The angular range of the set.

objectiveResolution

Microns per optical degree, carried in so that the set can convert.

tfSinusoidalX

Whether the X waveform is sinusoidal.

Coordinate systems

A scanner set holds direct references to the nodes it needs, so it can convert without reaching back into hSI: hCSReference, hCSFocus, hCSSampleRelative, hCSAxesPosition and hCSZAffineLut. See ScanImage Coordinate System Instances.

refToScannerTransform, scannerToRefTransform and transformParams are the legacy affine equivalents.

Field of view

Method

Description

pts = ss.fovCornerPoints(z_Ref)

Corner points of the field of view at a reference z.

pt = ss.fovCenterPoint(z_Ref)

Center point.

pts = ss.smallestFovCornerPoints()

The most restrictive field of view across the set’s scanners.

tf = ss.isPtInFOV(hPt_Ref)

Whether a point is reachable.

Capability queries and sample maths

Method

Description

ss.hasBeams(), hasSlowBeams(), hasFastZ(), hasSlm(), hasPowerBox()

What the set can do.

n = ss.nsamples(scanner,seconds)

Samples for a duration on a given scanner.

s = ss.nseconds(scanner,nsamples)

The inverse.

rg = ss.satisfyConstraintsRoiGroup(roigroup,scanfield)

Adjust a ROI group so it satisfies the set’s constraints.

[t,wDes,wCmd] = ss.zWvfm(roiGroup,zs,zsRelative,fb,wvType)

Desired and commanded z waveforms.


Path generation and timing

These are implemented per subclass, because the answers differ fundamentally between a resonant and a linear fast axis.

Method

Description

[path_FOV,seconds] = ss.scanPathFOV(scanfield,roi,actz,actzRelative,dzdt,zActuator,maxPtsPerSf)

The scan path for one scanfield, in field-of-view coordinates, and how long it takes.

ao_volts = ss.pathFovToAo(path_FOV)

Convert a path to analog output volts.

path_FOV = ss.pathAoToFov(ao_volts,zRef)

The inverse - useful for checking what a recorded waveform actually scanned.

path_FOV = ss.refFovToScannerFov(path_FOV)

Map a reference-space path into scanner space.

[seconds,...] = ss.scanTime(scanfield,limPts)

Time to scan a scanfield.

[lineScanPeriod,lineAcquisitionPeriod,ff] = ss.linePeriod(scanfield)

Line timing and the effective fill fraction.

[startTimes,endTimes] = ss.acqActiveTimes(scanfield)

When acquisition is active within the scan.

seconds = ss.transitTime(sf_from,sf_to)

Fly-to time between scanfields.

[path_FOV,dt] = ss.transitNaN(sf_from,sf_to)

The transit as a NaN-filled placeholder path.

path_FOV = ss.interpolateTransits(path_FOV,tuneZ,zWaveformType)

Fill the transits in.

path_FOV = ss.padFrameAO(path_FOV,frameTime,flybackTime,zWaveformType)

Pad a frame to its full period.

path_FOV = ss.zFlybackFrame(frameTime)

The z flyback frame.

v = ss.frameFlybackTime()

Flyback time per frame.

pos = ss.mirrorsActiveParkPosition()

Where the mirrors sit while parked but active.

n = ss.samplesPerTriggerForAO(outputData)

Samples per trigger for an output buffer.

cfg = ss.beamsTriggerCfg()

Beam trigger configuration.

Image formation

[success,imageData,stripePosition] = ss.formImage(scanfieldParams,sampleBuffer, ...
    fieldSamples,channelsActive,linePhaseSamples,disableAveraging,alreadyDeinterlaced);

formImage is the reverse direction: it turns a buffer of digitizer samples back into pixels, applying the resonant scan mask and line phase. It is what produces the imageData in a RoiData.

Waveform optimization

calibrateScanner, optimizeAO, testAO, retrieveOptimizedAO, ClearCachedWaveform, ClearCache, hasSensor and sensorCalibrated are the scanner-set-level entry points behind WaveformManager.


Subclass specifics

GalvoGalvo

Property

Description

fillFractionSpatial

For pure galvo-galvo scanning the spatial and temporal fill fractions are equal.

settleTimeFraction

Fraction of the line reserved for the mirror to settle.

pixelTime

Time per pixel.

bidirectional

Form a line on the return sweep.

stepY

Step the slow axis between lines rather than ramping it.

acqSampleRate

Digitizer sample rate.

ss = scanimage.mroi.scannerset.GalvoGalvo(name,galvox,galvoy,beams,slowBeams,fastZs, ...
     fillFractionSpatial,pixelTime,bidirectional,stepY,settleTimeFraction);

ResonantGalvoGalvo

Property

Description

fillFractionSpatial

Spatial fill fraction. The temporal fill fraction differs, because the resonant scanner’s velocity is not constant.

extendedRggFov

Use the extended field of view.

modifiedTimebaseSecsPerSec, useScannerTimebase

Run timing off the scanner’s own timebase rather than the DAQ clock.


Scanner models

scanimage.mroi.scanners holds the per-actuator models a scanner set is built from. These are thin models used for path computation - they wrap the dabs device in hDevice rather than replacing it.

Class

Members

scanners.Galvo

hDevice, sampleRateHz, flytoTimeSeconds, flybackTimeSeconds, actuatorLag_ms (samples are circularly shifted to compensate), useScannerTimebase.

scanners.Resonant

hDevice, fullAngleDegrees, scannerPeriod, bidirectionalScan, fillFractionSpatial, reverseLineRead.

scanners.FastZ / scanners.FastZAnalog

hDevice, enableFieldCurveCorr, fieldCurvature (a struct of zs, rxs, rys).

scanners.Beam / FastBeam / SlowBeam

hDevice, powerFraction, pzAdjust, Lz (length constant), pzFunction, pzLUT, pzReferenceZ, powerFracToVoltageFunc, includeFlybackLines. Methods: applySettingsFromRoi(hRoi), enforcePowerLimit(powers), powerDepthCorrectionFunc(powers,zs,...).

scanners.SLM

The SLM model. Owns hCoordinateSystem, hCSDiffractionEfficiency and hCSPixel - see ScanImage Coordinate System Instances.

scanners.StageScanner

Stage used as a scanning axis.

Most have a static default() too, which is what makes offline reconstruction possible.


Reconstructing geometry offline

Because a scanner set can be built without hardware, a logged acquisition can be replayed into scan geometry using only its header. This is the pattern the shipped scanimage.util.lineScan2Img example script uses:

[header,pmtData,scannerPosData,roiGroup] = ...
    scanimage.util.readLineScanDataFiles('file_00001');

ss  = scanimage.mroi.scannerset.GalvoGalvo.default;
Fsc = header.SI.hScan2D.sampleRateCtl;

ss.scanners{1}.sampleRateHz = Fsc;
ss.scanners{2}.sampleRateHz = Fsc;
ss.beams.sampleRateHz       = Fsc;
ss.fastz.sampleRateHz       = Fsc;

See also

Acquisition Metadata for the header fields these scripts read, and Custom Stimulus Functions for writing the parametric functions that a scanner set turns into stimulus paths.