Open nicost opened 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).
Useful discussion and device knowledge in micro-manager/pymmcore#86 and (especially well summarized) micro-manager/pymmcore#88:
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.