Chicago LSM HTTP RESTful WebServices Interface
Chicago Laser Scanning Microscope (CLSM) provides a RESTful web interface so that the clients and develop their own higher level application.
Basic API interface
Below are the description and explanation of basic API for general operation.
(If you have the executable running on your computer, you can click the link to directly access some of the API call via browser.)
- http://localhost:38080/scclsm/get-identification (GET)
get-identification returns the following example json strings to indicate the basic instrument Information.{ "HostExecutable": { "FileVersion": "25.11.8.2036", "ProductName": "CLSM with RESTful Interface", "InternalName": "CLSM", "CompanyName": "SpecialtyCircuits LLC", "LegalCopyright": "(C) 2014-2025 SpecialtyCircuits LLC", "FileDescription": "CLSM - AppWebServer" }, "Controller": { "SN": "SN:210018BB6E2A", "Model": "Analog Discovery Pro 3450", "DriverVersion": "3.24.60" } } - http://localhost:38080/scclsm/get-image-param (GET)
get-image-param returns the default image parameters upon instrument core boot up. It is recommended that the higher level application pull this information first before proceeding with any image scan to preserve consistency between higher level application and lower level controller.
Resolution is self explanatory.{ "Resolution": { "X(pix)": 64, "Y(pix)": 32 }, "Origin": { "X(m)": 0, "Y(m)": 0 }, "Raster": { "Scale-X": 0.00001, "Scale-Y": 0.00001, "Shear(deg)": 0, "Rotation(deg)": 0 }, "DefCal": { "Scale-X": 10000, "Scale-Y": 10000, "Shear(deg)": 0, "Rotation(deg)": 0 }, "AdvParam": { "DwellTime(s)": 0.000001, "VideoSampleRate(Hz)": 100000000, "PixelOversampling": 4, "LineOversampling": 1, "FrameOversampling": 1, "WaveformType": 4, "ScannerOversampling": 1, "Retrace(pix)": 0 } }
Origin is give the raster image a translation shift from the center of the field-of-view. It is defined as a vector of the image center to the hardware field-of-view center.
Raster is used to shape how the image scanning area.
Size-X, Size-Y and Rotation are self-explanatory. Shear is defined as the angle between the secondary scan axis to the vertical axis.
DefCal is used to correct linear space distortion back to ideal orthogonal grid.
Size-X, Size-Y and Rotation are self-explanatory. Shear is defined as the angle between the secondary scan axis to the vertical axis. Note that the sign negates in all parameters related to an angle. Scale behave like as reciprocal of themselves as in Raster. More detailed explanation of Raster and DefCal can be found at [placeholder]
DwellTime is the time spend on each pixel in the final image (not as sampled acquired from digitizer.) DwellTime must be whole number times of the clock period. A warning will be generated if a fractional number of clock dwell time is set.
VideoSampleRate is the clock rate of the digitizer.
PixelOversampling, aka, pixel averaging, is used to acquire multiple samples per pixel. It does not change the pixel dwell time. DwellTime / Pixeloversampling must be a whole number times of clock period. Increasing PixelOversampling will not increase total time of the image.
LineOversampling, aka Line averaing, is to sample each line scan multiple time. Increasing LineOversamping will increase total time of the image.
FrameOversampling, aka image averaging, is to sample each image scan multiple time. Increasing LineOversamping will increase total time of the image.
Retrace is the addition dummy pixels added to the beginning of each scan path to account of finite turnaround time of the scanner mirror. Signal during Retrace will not be included in bitmap, greyscale and color image output, but will be included in raw output.
WaveformType is used to set how the scan path is constructed.
Due to the limitation that Enum is not a supported type in standard JSON string, all the enum had to converted to numeric representation. To parse the numeric option into meaningful strings, use the following table.
0: StairCaseRamp_FullDoF
1: Serpentine_FullDoF
2: Ramp (Disabled Legacy Mode)
3: StairCaseRamp
4: Serpentine
For more detail explanation of the difference between each type, refer to [placeholder].
All values in the JSON strings strictly follow SI units, unless otherwise stated. So a field of view of "1.0mm x 1.0mm" need to be expressed as "1E-3 m x 1E-3 m". - http://localhost:38080/scclsm/set-image-param (PUT)
set-image-param is used to set the image scanning condition. The API will take a JSON string in the same format as in get-image-param and store it in a cache. A subsequent API call of commit-image or snap must be called for any parameter change to become effective.
The rational behind this behavior is for the higher level application to create wrapper API calls for each individual parameters. When each individual parameter update being requested only cache is updated, not actual hardware configuration. This reduces overhead, latency, and wear of mechanical parts, when higher level application prefer to update parameters one by one. Commit changes only once after all parameters have been updated. - http://localhost:38080/scclsm/commit-image (POST)
commit-image will apply all the changes that previous requested by set-image-param to actual hardware. It must be called after image conditions changes and prior to get-image-time, get-image-greyscale-png, get-image-color-png. - http://localhost:38080/scclsm/get-image-time (GET)
get-image-time will return an estimated time of the image acquisition. This time is needed to set the timeout when snap is called.{ "Target Time(ms)": 100 }
Note that a reasonable additional amount of time, eg 100 ms, need to be added to the Target Time when setting up timeout in snap API call, to account for HTTP communication latency. - http://localhost:38080/scclsm/snap?timeout=1000 (GET)
{ "Timestamp(ISO8601)": "2025-11-10T16:48:36.004-08:00", "ImageParam": { "Resolution": { "X(pix)": 64, "Y(pix)": 32 }, "Origin": { "X(m)": 0, "Y(m)": 0 }, "Raster": { "Scale-X": 0.00001, "Scale-Y": 0.00001, "Shear(deg)": 0, "Rotation(deg)": 0 }, "DefCal": { "Scale-X": 10000, "Scale-Y": 10000, "Shear(deg)": 0, "Rotation(deg)": 0 }, "AdvParam": { "DwellTime(s)": 0.000001, "VideoSampleRate(Hz)": 100000000, "PixelOversampling": 4, "LineOversampling": 1, "FrameOversampling": 1, "WaveformType": 4, "ScannerOversampling": 1, "Retrace(pix)": 0 } } }
snap triggers a new image snap in the controller. It will return the meta data of the image when the acquisition is done. The meta data contains the timestamp in ISO1861 (RFC3339) format and the image parameter with same data structure as in the get-image-param return.
The timestamp reflects the time when the image trigger was sent to the hardware, so it at the beginning of each image.
snap API call implies commit-image if not called prior to snap.
The higher level software should call get-image-greyscale, get-image-raw, get-image-bitmap or get-image-color to get the images in PNG or raw binary format. - http://localhost:38080/scclsm/get-image-greyscale-png?channel=0 (GET)
get-image-greyscale returns an image in PNG format. A JSON string must be passed to the server to set which channel to export.
Option channel is to set which channel to export. Valid values of channel include 0,1,2,3. If not present, channel 0 will be returned.
For special builds that does not require NI-IMAQ, this function is disabled. - http://localhost:38080/scclsm/get-image-raw?channel=0 (GET)
get-image-raw returns an image in raw binary. Higher level application is responsible to reconstruct the binary raw data into an image.
Option channel is to set which channel to export. Valid values of channel include 0,1,2,3. If not present, channel 0 will be returned.
Details on the reconstruction refers to [placeholder]. - http://localhost:38080/scclsm/get-image-bitmap?channel=0 (GET)
get-image-bitmap returns an image in a binary U16 array. The data structure is simply a memory dump of the pixelmap 2D array. It starts with two I32 integers describing the size of the array, followed by the U16 2D array/pixelmap.
Option channel is to set which channel to export. Valid values of channel include 0,1,2,3. If not present, channel 0 will be returned.
For more detailed description of the data structure, refer to the Arrays session in NI's official documentation. - http://localhost:38080/scclsm/get-image-color-png (GET)
get-image-color returns an 8-bit color image, with transparency, in PNG format.
Option channelmap is used to assign mapping between color and input signal channel. If left empty, Red, Green, Blue, and Alpha are assigned to Channel 0, 1, 2, and 3 respectively. - http://localhost:38080/scclsm/save-as-default-settings (POST)
save-as-default-settings will commit the existing imaging condition into the underlying configuration data of the core image scanning controller. Once saved in the database, the image scanning core software will startup with the new configuration for all future operation. - http://localhost:38080/scclsm/get-input-filter (GET)
get-input-filter will return the committed parameters of the input filter.[ { "Input": 2, "Mode": 1, "Type": 0, "Tap/Order": 15, "hz1": 0.05, "hz2": 0, "epsilon": 0 }, { "Input": 2, "Mode": 1, "Type": 0, "Tap/Order": 15, "hz1": 0.05, "hz2": 0, "epsilon": 0 }, { "Input": 2, "Mode": 1, "Type": 0, "Tap/Order": 15, "hz1": 0.05, "hz2": 0, "epsilon": 0 }, { "Input": 2, "Mode": 1, "Type": 0, "Tap/Order": 15, "hz1": 0.05, "hz2": 0, "epsilon": 0 } ]
Input sets the source of single prior to hardware filtering
0: Raw
1: Decimate
2: Average
Mode sets the type of filter.
0: Window
1:FIR
2: IIR Butterworth
3: IIR Chebyshev
4: Pole
Type sets the type of filter in terms of low pass, high pass, etc
0: Low Pass
1: High Pass
2: Band Pass
3: Band Stop
Tap/Order set the parameter of the filter.
For FIR filter, it sets the number of tap, the maximum is 16
For IIR filter, it sets the order of the filer.
hz1/hz2 set the corner frequency of the filter.
For low pass and high pass, only hz1 is effective.
For band pass and band stop, hz1 and hz2 set the two corner frequency of the filter.
hz1 and hz2 is expressed as "corner frequency" / "sample rate". The valid effective value is 0.01-0.5. Since this is defined as irreverent to sampling rate, if can be kept the same for all imaging conditions, so long as the oversampling number is the same. - http://localhost:38080/scclsm/set-input-filter (PUT)
set-input-filter sets the parameters for the hardware input filter. The data structure is the same as in get-input-filter. - http://localhost:38080/scclsm/exit (POST)
exit will exiting the sequence to gracefully shutdown the controller. This API is the only way to gracefully shutdown the application, if --nogui command line argument is supplied upon startup. (For non-graceful shutdown, use Task Manager to kill the program.)
Advanced Low Level API interfaces
Advanced APIs are not meant for regular use, but provided in case the end user need to implement special functionalities. The format is subject to changes on each release. We will try out best to avoid name change, so if you query the JSON structure via path, your existing program should still work.
- http://localhost:38080/scclsm/get-scanner-setting (GET)
get-scanner-setting returns the committed parameters the imaging core relies on for acquiring image. It combines all subsystem's settings into one nested cluster structure.{ "Scanner": { "VideoPeriod(ms)": 250, "Latency": { "Deflection(s)": 0, "Video(s)": 0, "ShutterOpen(s)": 0, "ShutterClose(s)": 0 }, "VideoGain[]": [ { "Range": 1, "Offset(cts)": 0, "Scale(cts/V)": 1 }, { "Range": 1, "Offset(cts)": 0, "Scale(cts/V)": 1 }, { "Range": 1, "Offset(cts)": 0, "Scale(cts/V)": 1 }, { "Range": 1, "Offset(cts)": 0, "Scale(cts/V)": 1 } ], "FIR/IIR": [ { "Input": 2, "Mode": 1, "Type": 0, "Tap/Order": 15, "hz1": 0.05, "hz2": 0, "epsilon": 0 }, { "Input": 2, "Mode": 1, "Type": 0, "Tap/Order": 15, "hz1": 0.05, "hz2": 0, "epsilon": 0 }, { "Input": 2, "Mode": 1, "Type": 0, "Tap/Order": 15, "hz1": 0.05, "hz2": 0, "epsilon": 0 }, { "Input": 2, "Mode": 1, "Type": 0, "Tap/Order": 15, "hz1": 0.05, "hz2": 0, "epsilon": 0 } ], "ChannelOption[]": [0, 1, 2, 3] }, "ImageParam": { "Resolution": { "X(pix)": 64, "Y(pix)": 32 }, "Origin": { "X(m)": 0, "Y(m)": 0 }, "Raster": { "Scale-X": 0.00001, "Scale-Y": 0.00001, "Shear(deg)": 0, "Rotation(deg)": 0 }, "DefCal": { "Scale-X": 10000, "Scale-Y": 10000, "Shear(deg)": 0, "Rotation(deg)": 0 }, "AdvParam": { "DwellTime(s)": 0.000001, "VideoSampleRate(Hz)": 100000000, "PixelOversampling": 4, "LineOversampling": 1, "FrameOversampling": 1, "WaveformType": 4, "ScannerOversampling": 1, "Retrace(pix)": 0 } }, "AnalogIn": { "Timebase": { "SampleRate (Hz)": 4000000, "SampleLength(cts)": 8192, "AcquisitionMode": 0 }, "Vertical[]": [ { "Range(V)": 1, "Offset(V)": 0, "BW(Hz)": 20000000, "Impedance(ohm)": 1000000, "Coupling": 0, "Filter": 1 }, { "Range(V)": 1, "Offset(V)": 0, "BW(Hz)": 20000000, "Impedance(ohm)": 1000000, "Coupling": 0, "Filter": 1 }, { "Range(V)": 1, "Offset(V)": 0, "BW(Hz)": 20000000, "Impedance(ohm)": 1000000, "Coupling": 0, "Filter": 1 }, { "Range(V)": 1, "Offset(V)": 0, "BW(Hz)": 20000000, "Impedance(ohm)": 1000000, "Coupling": 0, "Filter": 1 } ], "Trigger": { "Type": 0, "Source": 8, "Slope": 0, "Delay(s)": 0, "Holdoff(s)": 0.002048, "Timeout(s)": 0 } }, "AnalogOut": { "Timebase": { "SampleRate (Hz)": 100000, "SampleLength(cts)": 16384 }, "Horizontal[]": [ { "Phase(deg)": 0, "Frequency(Hz)": 7812.5, "Symmetry(%)": 0, "Cycle#": 16, "TriggerDelay(s)": 0 }, { "Phase(deg)": 0, "Frequency(Hz)": 244.140625, "Symmetry(%)": 0, "Cycle#": 0.5, "TriggerDelay(s)": 0 } ], "Vertical[]": [ { "FUNC": 30, "Amplitude(V)": 0.1, "Offset(V)": 0, "Idle": 1 }, { "FUNC": 30, "Amplitude(V)": 0.1, "Offset(V)": 0, "Idle": 1 } ], "Trigger": { "Type": 0, "Source": 1, "Slope": 0 } }, "DigitalOut": { "Timebase": { "ClockFreq(Hz)": 100000000, "Cycle#": 0, "Duration(s)": 0.002048 }, "Horizontal[]": [ { "DividerInit": 0, "Divider": 25, "CounterInit": 0, "CounterHigh": 0, "CounterLow": 64, "BitLength": 256 } ], "Vertical[]": [ { "Enable": true, "IdleOutput": 1, "WaveformType": 1, "OutputType": 0, "Pin": 0 } ], "Trigger": { "Source": 1, "Slope": 0, "TriggerDelay(s)": 0 } } }
