SLM Photostim Calibration and Alignment

Phase LUT Calibration

SLMs take pixels from bitmaps and convert them to phase shifts. Ideally, each pixel’s phase shift would map linearly from 0 to 255. In reality, we must determine the actual relation.

../../_images/SLMPhaseLUTCalSetup.png

To calibrate the phase mask, a checkerboard phase mask pattern is applied to the SLM and every other checker square is swept through pixel value range [0, 255] while the others are held constant. At the same time, the intensity of the zero order spot is measured with a photodetector (read through an analog-input channel) as energy is diverted to higher order spots. The largest swing in measured zero order intensity while sweeping pixel values is used to map pixel values to phase.

The calibration is performed in the SLM LUT Calibration GUI (scanimage.gui.align.SlmLutCalibrationGui), launched from the Alignment Tab under CharacterizationsSLM LUT Calibration. No camera is required — the diffracted intensity is read back through a photodetector wired to an analog-input channel.

The GUI has a Pattern Controls panel over two plots:

  • SLM Phase Response — measured intensity versus the swept checker pixel value.

  • SLM LUT — the resulting pixel-value ↔ phase curve.

Workflow:

  1. Set the Pattern Controls parameters (table below) and pick the Measurement Channel (the analog-input resource the photodetector is wired to).

  2. If beam modulators are present, set their power fraction so the SLM is illuminated when prompted.

  3. Press Measure. ScanImage points the SLM to zero order, sweeps the checker pattern through the pixel-value range, and reads the diffracted intensity back through the selected channel. The response appears on the SLM Phase Response plot.

  4. Drag the two red markers along the response curve to bound the monotonic portion used for the fit (a red diamond marks the detected peak). The SLM LUT plot updates live: the raw fit is drawn in blue, and — if Polynomial Degree > 0 — the polynomial-smoothed LUT is overlaid in red.

  5. Press Save LUT to commit the wavelength and the fitted LUT to the SLM scanner.

../../_images/SLMPhaseLUTCal2.png ../../_images/SLMPhaseLUTCalibration.png

Wavelength (nm)

The wavelength of the stimulation laser

Number of measurement points

The total number of total phase masks from the checkerboard pattern mask to the zeroed phase mask

Reference Pixel value

The pixel value of the checker squares whose phase remains the same throughout (defaults to the maximum value the SLM accepts, e.g. 255 for an 8-bit device)

Checker Size Pixels

The side length of each of the checker squares

Measurement Channel

The analog-input channel the photodetector is read through to measure the brightness of the zero order spot

Polynomial Degree for LUT smoothing

A polynomial curve can be fitted to the SLM Pixel Value vs Phase plot. A value of zero gives no polynomial fitting.

SLM Flatness Correction

Wafer polishing of the SLM introduces a slight dome shape. To correct for this, a flatness correction file is provided by the manufacturer. The correction is wavelength dependent.

../../_images/SLMFlatnessCorrection.png

Spatial Alignment

All of the spatial alignment for the SLM happens through the SLM Spatial Alignment GUI (scanimage.gui.align.SlmSpatialAlignmentGui), which is launched from the Alignment Tab. The GUI bundles:

  • A Z Alignment panel that owns the LUT hSlmScan.hCSSlmNative.fromParentLutEntries. Each LUT entry maps a focal depth z_ScannerOffset (in µm, X axis) to an SLM vergence zto (in diopters, Y axis), along with a 2D affine for the lateral correction at that depth.

  • A Coarse Adjustment panel (SlmAffineAdjustmentPanel) that nudges the 2D affine of the LUT entry nearest the currently targeted Z (within 1 µm).

  • A tabbed XY-alignment area with three refinement workflows that write the 2D affine for the same entry:

    • Substage Camera — overlays a grid of SLM-aimed laser spots on a live camera image.

    • Burn Spots — burns a grid of holes into a fluorescent slide with the stim laser, then matches the imaging-scanner picture of those holes to the grid the SLM was commanded to.

    • Motion Detection — deflects a single SLM focal point laterally and reads the resulting offset, either by automated motion estimation or by manually overlaying the live (deflected) image onto a pinned reference. Useful when no camera is available and a hole-burning slide is undesirable.

Because the lateral correction is stored per Z entry, the workflow below deliberately defers any XY tweaks to the depth at which they are being viewed.

Step 1 — Align the linear scanner to the imaging scanner

If the SLM is relayed onto a linear scanner that is paired with a separate imaging scanner, the two scanners need to be brought into the same coordinate system before any SLM-specific alignment is meaningful.

The stimulation path and the imaging path do not in general share the same focal depth in the sample — at the SLM’s zero phase mask the two image planes can easily be tens of microns apart. Aligning the linear scanner to the imaging scanner therefore requires two passes: a Z calibration first, then a lateral one.

1a. Match the focal depths at z = 0

The Z mismatch is absorbed by the hCSScannerOffset LUT entry at zfrom = 0. Adjust this entry’s zto so the linear-scanner image plane coincides with the imaging-scanner image plane. Do not touch the 2D affine on this entry yet.

Sample: a thin layer of yellow highlighter on a glass slide. For a water-dipping objective, drop a coverslip on top of the highlighter before adding the water droplet, and don’t add so much water that it spills past the edge of the coverslip onto the highlighter underneath.

  1. Park the FastZ at target position 0 on the linear scanner’s FastZ device.

  2. Focus with the imaging scanner.

  3. Step the Z-stage until the histogram of the image data is at its maximum value — that’s the depth where the highlighter layer is in focus through the imaging path.

  4. Zero the sample relative coordinate system at this depth. Optionally pin the current imaging-scanner frame to the viewport background for reference.

  5. Switch imaging to the linear scanner paired with the SLM (SlmScan’s paired linear scanner).

  6. Scan with the linear scanner and, in the Z Alignment panel, adjust the zto for the hCSScannerOffset LUT entry at zfrom = 0 until the histogram is once again at its maximum mean pixel value across the frame — the two image planes now coincide. If there is slight non-uniformity in the highlighter layer or a small tilt of the sample, overlay the live image on the pinned reference at reduced opacity to compare them directly.

    Tip

    With the cursor inside the viewport, Ctrl + scroll adjusts the alpha of the live image, making it easy to fade between the live linear-scanner frame and the pinned imaging-scanner reference.

1b. Laterally align the linear scanner to the imaging scanner

Once the focal planes coincide, swap to a thin sample with structure that both paths can resolve (a thin pollen slide or fluorescent beads on a coverslip works well).

Open the Alignment Tab and bring up the Scanner-to-Reference alignment tool (scanimage.gui.viewport.tools.liveDisplay.ScannerToRefAlignmentTool). The tool freezes a copy of the reference scanner’s pinned image plus any visible ROI and scanfield overlays in scanner space, so dragging fixed points moves the live image relative to that frozen reference. Follow the standard Scanner-to-Scanner Alignment workflow to drag the linear-scanner image onto the reference image.

The right-click context menu on the tool also offers:

  • Clear transform at current z — remove the LUT entry of hCSZAffineLut at the current Z, falling back to whatever the LUT interpolation says.

  • Reset transform at current z — set the LUT entry at the current Z to the identity (or insert one if none exists within 1 µm).

When the Apply menu item is selected, the new transform is committed to hCSZAffineLut at the viewport’s current Z.

Step 2 — Coarse lateral alignment at z = 0

With the linear scanner now aligned to the imaging scanner, the SLM’s own lateral alignment can be tackled. Start at the calibrated z = 0 LUT entry (scanner offset = 0 µm). The intent is to take out the bulk of the mismatch first with the simple coarse-adjustment controls, then refine with the camera or hole-burning workflow.

2a. Coarse adjustment with the SlmAffineAdjustmentPanel

The Coarse Adjustment panel (SlmAffineAdjustmentPanel) writes directly to the 2D affine of the LUT entry of hCSSlmNative.fromParentLutEntries nearest the currently targeted Z (within 1 µm); if no entry is within tolerance, an identity entry is created at the target Z first and then nudged. The panel exposes four absolute fields and four nudge sliders:

  • Scale (%) — ratio of galvo°/SLM° × 100. The expected value comes from the SLM-to-galvo relay transverse magnification:

    scale ≈ 100 × f1 / f2
    

    where f1 is the focal length of the relay lens adjacent to the SLM and f2 the one adjacent to the galvos. For a 100 mm / 200 mm pair the panel should land near 50 %.

  • X Offset / Y Offset — translation in SLM-native coordinates. The - / + buttons step by the slider’s percentage of hSlm.nativeRangeXYZ (i.e. an XY shift expressed as a fraction of the SLM’s full deflection range).

  • Rotation (°) — rotation around the optical axis.

  • Invert X / Invert Y — flip the corresponding axis (handy when the relay or a downstream mirror has produced an unexpected handedness).

  • Reset Adjustments At This Z — restore the LUT entry’s affine to the identity (the Z mapping itself is preserved).

Type a value into one of the absolute edit fields and press Enter, or use the slider + -/+ buttons to nudge. Each click commits to fromParentLutEntries and saves the coordinate systems.

For this step, the easiest sample is a layer of yellow highlighter on a glass slide, viewed through the substage camera. Park the SLM at z = 0, project a single point or a small grid, and use Scale / Offset / Rotation / Invert to walk the projected spot(s) onto the centre of the camera field — close enough that the refinement step below will converge.

2b. Refine with the substage-camera, burn-spots, or motion-detection workflow

After the coarse pass, pick one of the three tabbed workflows in the SLM Spatial Alignment GUI to compute and apply the refinement affine.

Substage Camera tab (SlmCameraAlignmentPanel)

Sample: yellow highlighter on a glass slide.

  1. Press Start Camera to open the Camera Tab and begin live acquisition on the first configured substage camera.

  2. Set the Grid lines and % FOV fields (defaults 5 lines, 0.6 of the SLM native range).

  3. Press Project Grid to point the SLM at a grid of XY targets at the currently targeted z_ScannerOffset (taken from the Z Alignment panel).

  4. Press Start Alignment to overlay the ideal grid on the live image via SlmAlignByGrid. The default mode is bezier — drag the row and column curves (and the tangent handles at their endpoints) until the curve intersections coincide with the visible laser spots. Switch to drag swaps to per-point dragging if you prefer.

  5. Optionally press Detect Spots to auto-fit centroids (bright-polarity) to the projected spots.

  6. Press Generate Alignment to solve a 2D affine via pinv mapping the observed (dragged) ref-space positions back to the SLM-native targets. The new affine is left-composed with the existing LUT entry’s affine at this Z, or a new entry is created if none exists within the 1 µm tolerance.

Burn Spots tab (SlmBurnSpotsAlignmentPanel)

Sample: a fluorescent slide marked with permanent marker (Sharpie). The stim laser ablates the marker, leaving fluorescent bright spots in the imaging-scanner image.

  1. Press Start Focus — the GUI switches the imaging system to the SLM’s paired linear scanner, sets the scan mode appropriately, and begins a focus acquisition.

  2. Configure Grid lines, % FOV, Burn [um] (burn spot diameter), Power [%], Burn [s] (per-spot duration), and Pause [s].

  3. Press Burn Holes. The panel closes the detection-path shutters, powers off the PMTs, fires the configured grid as an on-demand photostim ROI group, and then restores the prior shutter / PMT / photostim state. The XY grid is sized relative to the default imaging scanfield, scaled by % FOV.

  4. Press Start Alignment, then drag the bezier curves (or individual markers, Switch to drag) so the curve intersections fall on the burn spots.

  5. Optionally press Detect Spots — same auto-fit as the camera workflow, but with dark polarity.

  6. Press Generate Alignment to commit the affine to the LUT entry at this Z. Burning requires a calibrated Z entry already in place, so this workflow is also usable as the refinement step at any other depth in step 4 below.

Motion Detection tab (SlmMotionDetectionPanel)

Sample: any thin sample with enough structure for the imaging scanner to resolve a single deflected SLM focal point (e.g. a pollen slide or beads). No camera is required. Rather than fitting a whole grid at once, this workflow records the lateral offset of one deflected point at a time and fits the affine from at least three such points.

The Alignment input dropdown selects how the offset is read:

  • Motion Estimation — ScanImage’s simple motion correction cross-correlates each live frame against a reference to measure the lateral offset automatically.

  • Manual Overlay — a fallback for when SLM defocus scales the live image (which breaks cross-correlation): the current frame is pinned as a reference and a live-image overlay tool is started, so you drag the live (deflected) image over the pinned reference and the overlay’s translation is taken as the offset.

  1. Press Start Focus to begin a focus acquisition on the SLM’s paired linear scanner.

  2. Press Start Alignment. This opens the Phase Mask Display so the SLM focal point can be deflected laterally. Motion Estimation enables motion correction; Manual Overlay pins the current frame and starts the image-overlay drag tool.

  3. Deflect the SLM focal point laterally with the Phase Mask Display. In Manual Overlay, drag the live image back onto the pinned reference. Then press Add Alignment Point to record the current SLM deflection and its lateral offset. A minimum of three points is needed for a full affine; Reset Points clears them.

  4. Press Finish Alignment to fit the full lateral affine and fill in the affine2D of the SLM’s existing hCSSlmNative.fromParentLutEntries entry at the current depth. View Alignment Matrix prints the current LUT entries for inspection.

Note

Like the burn-spots workflow, Finish fills in an existing Z entry’s affine — it never creates one — so the SLM Z depth must already be calibrated (step 3) before finishing a Motion Detection alignment.

Step 3 — Calibrate SLM Z at several depths

Once the lateral alignment at z = 0 is good, sweep the SLM through Z and record a vergence-vs-depth point at each of several focal offsets. This populates the hSlmScan.hCSSlmNative.fromParentLutEntries LUT with the zfrom / zto pairs that drive the SLM vergence used at runtime.

Sample: the same yellow highlighter on a glass slide.

The Z Alignment panel (SlmZAlignmentPanel) presents:

  • An axes with Z [µm] (scanner offset) on X and SLM vergence [diopter] on Y.

  • A blue marker for each calibrated entry; entries that also have a non-identity 2D affine are filled blue (hollow otherwise).

  • A red position marker showing the SLM’s currently commanded (Z, vergence) point.

  • Left / right arrows — scan the Z view (move the red marker in X) without writing to the LUT.

  • Up / down arrows — adjust the SLM vergence at the current Z and write/update a LUT entry there.

  • Goto Zero, Auto-fit, Reset LUT, and a Z [µm]: editable field with a ← Display Z button that syncs the field to the Viewport’s current focus-relative Z.

  • A Treadmill checkbox + dropdown. When enabled, every change in SLM z_ScannerOffset is paired with an equal-and-opposite move on the selected device (Z-stage, or one of the linear scanner’s FastZs) so the physical focal plane stays where it is while you hunt the SLM’s refocusing match. Jumps larger than 200 µm prompt for confirmation.

Workflow at each depth:

  1. Choose the Z-stage / FastZ depth you want to calibrate (turn Treadmill on if you’d rather keep the physical focal plane fixed and walk the stage in response to SLM steps).

  2. Use the up / down arrows to adjust the SLM vergence until the highlighter layer comes into focus in the imaging scanner.

    Tip

    Shift + scroll wheel over the axes zooms the Y axis (SLM vergence) centred on the red marker, letting you hunt vergence at arbitrary precision without overshooting the focus.

  3. The LUT entry at this Z auto-updates as you nudge.

  4. Repeat at several depths to span the working range. Right-clicking a point in the axes offers Goto, Delete, Reset XY alignment, Align XY at this Z, and Copy this XY alignment to other Zs.

Step 4 — Laterally align at each calibrated depth

The lateral correction can shift between Z entries because the SLM’s imaging through the optical train is not perfectly telecentric. Once Z is calibrated at several depths (step 3), revisit the lateral alignment at each of those entries.

For every calibrated Z:

  1. In the Z Alignment panel, right-click the entry’s blue marker and choose Goto to drive the SLM there, then Align XY at this Z. This hands off to whichever XY-alignment tab is currently selected:

    • Substage Camera — restarts the camera if needed, projects the grid at this Z, and brings up the alignment tool.

    • Burn Spots — sets the burn target Z to this entry (you still need to press Burn Holes and Start Alignment yourself, since burning is destructive).

    • Motion Detection — does not take a Z target; once the SLM is parked at this depth via Goto, just run the Motion Detection workflow (steps above) and Finish writes the affine into this entry.

  2. Run the chosen refinement workflow as in step 2b. The resulting affine is left-composed onto the existing entry at this Z.

Use the substage-camera workflow with highlighter-on-glass when a camera is available; use the burn-spots workflow with Sharpie-on-fluorescent-slide, or the motion-detection workflow with any structured thin sample, when only the imaging scanner is available. Calibrated entries with a non-identity 2D affine show as filled blue markers in the Z Alignment axes, so it’s easy to see at a glance which depths still need XY work.

Tip

If you’ve already produced a good affine at one Z and the optical train is roughly telecentric over the range of interest, right-click that entry and choose Copy this XY alignment to other Zs to bootstrap every other entry with the same affine. Then revisit each one only to the extent that residual error makes it worthwhile.