Documentation Labwiew Scanning Software "Colibri"

C.Seebacher
last change 12. september 2006
Seebacher@biz.uni-muenchen.de
www.lmu.de/~chr
ToDo: split this document: into using, features and bugs and jobs.

Short instructions

Run the ScanMicroscope.vi. It is only a menu (like in ImageJ). This has the advantage to test all features seperately. I heard Max Spering has build a single GUI.
Menu Application
View a screenshot
Tools - Imaq-view-save: select the channels to view.
Run - Single: Start a scan or press <Strg>F1 (better use the Autohotkey tool)
optionally you can:
Edit - DefineScan: to change the scan
Edit - PMT gain: to change the high voltage, do not forget to put it to 0 at the end.
Tools - Maitai: Switch On/Off the laser, Change the wavelength, Open/Close the shutter.
Run - job-zstack: This is a predefined z-stack. Change it with Tools - ChangeJob or edit the job.ini file.
File - Save: save the Images as MultiTIFF file (all temp images are in the c:/temp directory), select 1 or more and press Save MultiTiff.

Workarounds

Features

Comes with complete source code.
Vector based scan description.
1 to 4 channels only limited by the AD-card.
support of the digital interface to the Smartmove boards (bidirectional scanning with all speeds).
4 Mhz sampling speed (AD-card and computer dependent) with variable binning n=1...65635 (slower than 15ms/pixel)
flexible scanspeeds from sub ms (40µs) to several s (1000x15ms=15s) per line.
Arbitrary scan tracks
Spot scan (at the monent not tested)
Line scan (at the monent not tested)
Flexible Job control
Units are meter at the sample.
Contionous running (no gap between scans)
Some support of PCO CCD cameras.

Tested scan speeds

With 60x Objective, f=35mm scan lens
50x16µm, 512x16x 1µs, 0.00983s/frame=101,7Hz (21% turnloss) contionous 200 images 1 chanal
10x10µm, 100x100pix 1µs, 0.02189s/frame =45,7Hz (120% turn loss) continous 200 images
200x200µm, 2000x2000pix, 1µs, 4,24s (6%loss)
200x200µm, 4000x4000pix, 1µs, 16,32s/frame (2%loss) contionous 5 images
4x4u, 16x16pixel, 0.00317s/frame=315Hz (25%loss) contious 40 images
16x16um, 64x64Pixel, 0,04475s/frame=22Hz (9%loss) contionous 400 images (empty memory)
30x30µm, 100x100pix, 10µs 0,10595s/frame, 6% loss, 1000 contionous
Tested: 4µx4µ, 80x80 pixel with 6µs/pixel, 40ms/frame 100 frames continous
Tested: 4µx4µ, 80x80 pixel with 12µs/pixel, 78.7ms/frame 500 frames continous

Jobs

all active Jobs are in the \JobControl\job.ini (filename stored in the variables) file 
supported command and their .data are:
the respective lines of the jobs.ini are copied to the variables and an event is executed on the job.position variable.
A job.#.command line is needed, a job.#.data line is often needed, a job.#.name line is optional but not yet used
An example:
[job-zstack] same name as in the menu defined by GUI.ini 
job.name="z-Stack 0.5µm"
job.position=0
job.position.driver=TJob.vi
job.1.command=newexperiment
job.2.command=piezorel
job.2.data=0
job.3.command=createnotifier
job.3.data=scan.number
job.4.command=loopstart
job.4.data="100 times"
job.5.command=scan
job.5.data="1"
job.6.command=waitfornotifier
job.6.data=20,false
job.7.command=piezorel
job.7.data=+5E-7
job.8.command=looprepeat
job.8.data="4 (# of loopstart)"
job.9.command=deletenotifier
job.10.command=newexperiment
job.11.command=end
It is also possible to write a totally different Job.vi that starts events etc...
To have the script 'program' in the data space is powerful but can be dangerous as you have full control on all data.
I am thinking about counting down the number to 0. Them you can stop the job easily. Now done with the special number="cancel".

Menu

the /GUI.ini file controlls all menu entries shortcuts and its assoziated GUI-Programs.
These programms will be loaded at startup.
Upon actiavation the frontpanel will be opend, it is tried to send the menu name to a String control named "Menu", and the vi is executed without wait.
Special names are: End, Cancel
[job-zstack]  Adds a new menu item
parent="Run" Adds the new item under the parent "Run" (must be declared before!, "" is top level)
vi-path="JobControl\StartJobGUI.vi" Starts this Application
shortcut="F2" Uses this Shortcut: <STRG> F2 but this works only with the focus on the menu bar. Use Autohotkey to solve this!
You can use the Autohotkey program to have real single key control!

Internal structure

Data-Flow
All changes by the User will change variables. This does automatically send a Notifier with the name of the Variable. A driver listening to the Notifier will get the change and is doing the Instrument input output. The result is sent back the same way via changing a vaiable.  All data is stored in the Varaibles.
Only the storage of the images is separated from the variables due to the lack of powerfull memory management, binary data and array functions.

Programming

variables

all data should be stoted in the variables\variables.vi.
Though it is text based it is designed for scalar numbers. But some variables are arrays or strings, so for simplicity i chose strings. The conversion time from a string to a number is some µs (only for a large arrays there could be a speed problem).
If you add a existing variable you will actually overwrite it so take care with your name definitions.
The "get all" function can point to a variable holding a space separated list of all variable tags to read. The output is tag="Value"<cr>tag="value"... (<cr> is the new line byte: \n); Data must not have a <cr> char.
My drivers expect a new value for a variable in a separate variable who has a name extended with .set
All other dots are (so far) not object oriented programming but used for structure. One could build a tree with  these  dots.
examples:
variable1="123"
variable1.set="124"

drivers (new with Notifier, new without extra Driver Notifier)

(first i tried to do it with user events but could not create them in a running program (dependent of the label of a front panel element!))
you can easily add you own instrument driver or exchange a existing one..
It does not need a special connector any more,
It does not need to run very fast any more,
It can do work when it is not called.!
See Prototype "DriverTemplate.vi", or the more difficult TiMicSDK.vi
Normal work flow: change the abc.set variable.
This sends a Notifier named abc.set with the data of the variable.
The driver is listening to its apropriate Notifier(s).
When the Notification arrives the driver is doing its job and at the end it changes the variable abc (without .set) to its new value. (whitch automatically creates another  Notification the a listening GUI).
Or you can call the driver direct (without Event via TimerLoop) by creating a Notifier with the name of the driver.vi and sending a notification with the .set data.
For an update request to the driver i send "update" as data instead of the value.
Some driver do understand a "cancel" to stop the the driver from their actual task.

GUI

GUIs should use an event loop (do not waste execution time by polling user input) and close the frontpanel after execution. Simple example: SetEventGUI.vi.
GUIs should watch te result of their changes by listening to the respective (without the .set) Notifier of the Variables they changed.

IMAQs

There was a timimg problem if the save and get functions are included within the IMAQ storage vi (blocked while saving).
There is still the idea of having a consecutive integer number for the images.
Now you can get the IMAQ from a function called ImaqStorage.vi. With "create IMAQ" you get a new IMAQ with "get IMAQ" you get an existing IMAQ defined with its number. Be careful if the "getIMAQ" returns the number "-1" you habe a valid IMAQ but not its data (deleted from Memory). Use the GetIMAQ.vi to obtain the IMAQ with its data reloaded from the disk.
To save the IMAQ send the IMAQ with its metadata (cluster) into a queue called "SaveQueue". There is SaveImaqFromQueue.vi running in the background taking care for the storage.
The number of a "active Image" is now stored in the Variables as imaq.active="12345". You can get the actualindex from ImaqStorage.vi if you want the number of the latest image.
Take care if you get the actual  IMAQ used for scanning (probably the last images). Its data is changing during while scaning. Do not change anything what could change the pointer to the image-data (border, imagesize etc). Read and copy etc. should be OK.
If the image is not older than the buffersize (currently 200 IMAQs, defined by DeleteImaqFromSavedQueue.vi) the getimaq.vi should be very fast (RAM).
After each call with "getIMAQ" (or use the GetIMAQ.vi) you should call a "decrease usage". Otherwise the internal delete function will never free this image from the RAM.

Actual IMAQ

You can listen to the notifier for the image1.imaq variable if you want to know when there is new data available. If you want to know when the image is ready listen to the scan.number variable. This variable is counting up each scan in a contionous run. In a single scan it is changing once to 1. (how does a job now if a sequence is ready?)
With the notifier comes the number if the IMAQ; with this number you get the image with the "GetIMAQ.vi".

Online analysis

nothing done so far, started with a histogram, add ROIs, use some IMAQ tools..

To do list (important on top)

Known Bugs (serious on top, sometimes not up to date; use svn/track system)

Fixed Bugs

Outlook

with programmable keys, the mouse, the mouse wheel or a external turnkeys one can tune any parameter (stage, amplifier, scanspeed?, focus, laserpower)
Use of the IMAQ image recognition/manipulation features.

Tuning

Take galvo-sensor-signal (pin2 signal and pin6 ground on the white Smartmove connector next to Power) connected into AnalogIn.
Try some delays with bidirectional scanning (there should not be any stripes in the image).
Save the delay in the mic.ini
Due to a delay of the signal in the Analog Detection (Ampifier?, PMT?) the real imaging needs a little bit extra delay.

Error Codes

-200284 (DAQmx Read) AI-Start trigger is missing: check contact and cables of Clock and Trigger!