microscope icon indicating copy to clipboard operation
microscope copied to clipboard

duration pseudoglobal trigger type

Open carandraug opened this issue 5 years ago • 13 comments

On the cockpit side of things, there is a TRIGGER_DURATION_PSEUDOGLOBAL which is missing on microscope. On the cockpit side of things, it was added by @juliomateoslangerak in cockpit/87373a86 which documents:

    #   The TRIGGER_DURATION_PSEUDOGLOBAL is for using the rolling shutter and we
    #   only want to excite the sample in the time that all of the pixels are
    #   exposed.

This does not exist in microscope. It is present on @juliomateoslangerak master branch which also changes the andorsdk3 internal trigger mode "external exposure" from TRIGGER_DURATION to the new TRIGGER_DURATION_PSEUDOGLOBAL. Not sure which one is actually correct.

carandraug avatar Mar 22 '20 22:03 carandraug

Extracting the difference between Micron and @juliomateoslangerak master for this pseudoglobal type, the commit is this one.

carandraug avatar Mar 22 '20 22:03 carandraug

This is probably wrong and microscope camera should only implement TRIGGER_DURATION. It should be cockpit (experiment or the camera/light handler I guess) that generates the proper timing to achieve a pseudo global shuttering. It is anyway something very important. Cockpit should get if the camera is using rolling or global shutter.

juliomateoslangerak avatar Mar 23 '20 08:03 juliomateoslangerak

I'm not sure I understand why we need the psuedo global shutter option at all. Up until now cameras have been controlling their own exposure times ad then being triggered by a short (100 us typically) ttl pulse at the start of an exposure. I think the psuedo global mode is using light triggering to do the the global effect.

iandobbie avatar Mar 23 '20 09:03 iandobbie

Yes. What I call pseudo global shutter is that the light only triggers when all the pixels are exposed. That is camera_read_time after camera trigger. Then the real exposure time has to be longer than the exposure time requested by the user. Indeed there is no need to implement that as either external (camera controlled exp_time) or external_duration (executor controlled explique_time). But it has to be taken into account

juliomateoslangerak avatar Mar 23 '20 09:03 juliomateoslangerak

If I understood correctly, then the aim is to have global exposure mode even when using a rolling shutter. And that can be done by computing the part of a frame exposure where all pixels are being exposed and emit light during that time only. Is that correct? If so, when using rolling shutter, won't there be cases where there's no point in time where all pixels are being exposed?

carandraug avatar Mar 24 '20 16:03 carandraug

Yes. That's it. In principle, if exposure_time is shorter than the read_time, yes there is no point in time where all the pixels are being exposed. However, that should never happen cause the exposure time should be that of the light source, to which the read_time has to be added. The executor should trigger that camera read_time before the light source. This is currently working in my set-up when I use exposure mode 'external duration'. I'm not sure with internal trigger (sorry I cannot verify as we are pretty confined here).

This is managed in Experiment.py line 599. Probably I pushed this.

            elif mode == cockpit.handlers.camera.TRIGGER_DURATION_PSEUDOGLOBAL:
                # We added some security time to the readout time that
                # we have to remove now
                cameraExposureStartTime = (exposureStartTime
                                           - self.cameraToReadoutTime[camera]
                                           - decimal.Decimal(0.005))
                table.addAction(cameraExposureStartTime, camera, True)
                table.addAction(exposureEndTime, camera, False)

Probably this should be something like elif shuttering_mode == rolling: ... There are cases where you would like to not use pseudo global. Maybe that should be a configuration option for the camera.

juliomateoslangerak avatar Mar 24 '20 17:03 juliomateoslangerak

I see. This indeed does sound like something that a client such as cockpit should handle. So, just to be clear:

  1. we will not change the trigger modes in microscope (no adding TRIGGER_DURATION_PSEUDOGLOBAL mode and no change in andorsdk3)
  2. this issue becomes about figuring out whether camera is using rolling shutter or global exposure (in the case of andor sCMOS, that's the value of "ElectronicShutteringMode").
  3. a new issue open in cockpit to discuss how that will work because it seems that at the moment that won't work without patching the code.

Sounds right @juliomateoslangerak ?

carandraug avatar Mar 24 '20 17:03 carandraug

That sounds right to me.

juliomateoslangerak avatar Mar 25 '20 04:03 juliomateoslangerak

I believe all back-illuminated CMOS cameras lack a global shutter and should be treated as if they had a rolling one. As such, it is really important to associate a property with Camera devices that can tell users, e.g. Cockpit, what is the shutter type of the device. What Julio had implemented earlier was a step in the right direction.

Even better if more complex exposure modes can be configured on a per-camera basis. For example, expose only for the first row or expose from the start of the bottom row to the end of the top row (i.e. pseudo-global shutter mode).

dstoychev avatar Aug 14 '21 11:08 dstoychev

Indeed this is an issue for me cause I have rolling shutter Zyla's, and I do not get the right illumination without 'pseudo-global shuttering'. That is I believe the term comming from Andor's manual. So After I merged microscope's code before summer I revisited this issue and opened two issues where I suggest more appropriate changes: #209 Adding a electronic shuttering mode property and functions and corresponding Andor sdk3 implementations. I guess I should have followed this issue here. https://github.com/MicronOxford/cockpit/issues/651 Changing the code accordingly on cockpit. With those changes, the triggering seems to look good on the oscilloscope and the images. The snap is still not working though. I can look at that.

juliomateoslangerak avatar Aug 16 '21 08:08 juliomateoslangerak

The sCMOS shutter is very complex. Some of the sCMOS cameras do have global shuttering by reading exposure before and afterqards but you effectively double the read noise. A very bad idea. Much better is to know when your sensor is all active and flash you light source in this period with having no light when the sensor is only partially active. However this might make things slow as the rolling shutter period might allow longer exposure, even if some of the light is then thrown away.

iandobbie avatar Aug 16 '21 12:08 iandobbie

Yes, indeed I modified experiment.experiment.expose to do exactly that. Subtract the readout time from the camera trigger start so that all the pixels are active when the laser goes on. Both laser and camera triggers are off simultaneously. I do also add a fraction of time in order to be sure that the camera is ready when the acquisition is too quick (I had issues with that). I believe this time (the time the lights are not on) is not lost as it is considered as 'available' to do other things such as moving z and start reading another channel. I did a fair amount of testing that I would like to repeat and document properly. These are some scenarios that I'm thinking of:

  • Single channel single exposure with exp_time > readout_time
  • Single channel single exposure with exp_time < readout_time
  • Same thing in a time-lapse (no z movement).
  • Same thing in a time-lapse of z stacks.
  • Same test with multiple channels.
  • A more 'complex' experiment such as a SIM z-stack Any idea of what could go wrong and that would need testing? I can test this on the oscilloscope and with an homogeneity sample.

In the case @iandobbie is mentioning, I guess you would want to do something similar from the other side. That is, adding the readout time to the end of the exposure: you trigger on camera and laser at time=0 but you trigger off camera at time=exposure_time - readout_time and laser at time=exposure_time. Otherwise you get non-homogeneous exposure to light. I guess a question is if this is left as an option to the user / configuration.

juliomateoslangerak avatar Aug 16 '21 13:08 juliomateoslangerak

I suggest we close this issue and continue in #209. It is a duplicate.

juliomateoslangerak avatar Nov 21 '22 16:11 juliomateoslangerak