micro-manager / mmCoreAndDevices

Micro-Manager's device control layer, written in C++
39 stars 101 forks source link

SLM api needs clarification #34

Open nicost opened 3 years ago

nicost commented 3 years ago

MMCore has a couple of functions to work with SLM (spatial light modulator) devices. These are basically treated as a a display with a rectangular coordinate system that images can be written to.

The api contains a number of functions to change the output of these devices: setSLMImage() doc: Write an 8-bit monochrome image to the SLM. (also a 32bit RGB version) setSLMPixelsTo() doc: Set all SLM pixels to a single 8-bit intensity. (also a r, g, b version) setSLMExposure() doc: For SLM devices with build-in light source (such as projectors) this will set the exposure time, but not (yet) start the illumination displaySLMImage(): doc: Display the waiting image on the SLM.

The GenericSLM implementation (which I would consider the "reference" implementation) will display immediately, when the setSLMPixelsTo function is called, but not when calling the setSLMImage function. The commands in the SLM api are consistent with this behavior (SetImage: "Load the image into the SLM device adapter. ", SetPixelsTo: "Command the SLM to display one 8-bit intensity. "). I am quite sure that several SLM device adapter will display the image immediately after calling setSLMImage(), i.e. without the need to call displaySLMImage().

I guess that the idea behind the current design is that it can be time consuming to load the image into the device, hence separating out loading and displaying can be beneficial. However, this is currently not obvious from the documentation, and took me more than an hour to figure out.

Probably the easiest solution is to update the documentation in the core to warn the user that the image loaded with setSLMImage() is only guaranteed to be displayed after calling displaySLMImage.

marktsuchida commented 3 years ago

I remember this interface making me very uncomfortable when I last worked on GenericSLM. I probably made it behave reasonably given the constraints at the time (e.g. how Projector works), but I don't know if it can be relied upon as a representative implementation.

Also I'm not sure (would need to check) how exposure is used by these methods (when it is used -- GenericSLM ignores exposure).

Part of the problem is that it seems that potentially three actions are conflated with each other: loading an image to the SLM controller hardware, setting the mirror array to physically display the image, and pulsing (or turning on) the illumination. I don't think the set vs display was necessarily intended to separate the first and second of those steps.

If, for example, displaySLMImage was intended to flash the illumination, we still effectively have the guarantee that setSLMImage will physically set the mirror array to the given image -- because the mirror state will never be observed when the illumination is off on such devices.

A deeper problem with the current interface is that it would appear that the application (mostly Projector in our case) needs to know about "SLM" devices with and without their own illumination and arrange accordingly.

It's probably necessary to check every implementation we currently have (including the closed-source Mosaic3 one).

marktsuchida commented 11 months ago

Useful discussion and device knowledge in micro-manager/pymmcore#86 and (especially well summarized) micro-manager/pymmcore#88: