TheDeanLab / navigate

navigate - open source light-sheet microscope controls
https://thedeanlab.github.io/navigate/
Other
31 stars 6 forks source link

Independent Control of Filter Wheels #489

Closed AdvancedImagingUTSW closed 4 months ago

AdvancedImagingUTSW commented 1 year ago

One of the final things we need for our spectral/multiplexing TIRF microscope is independent control of the filter wheels. My initial plan is to do this in a manner that is similar to the stages - e.g., multiple filter wheels can be specified in the configuration yaml file as a list. We then create one device connection, and pass it to multiple filter wheel objects. Each filter wheel would have its own set of filters, etc.

This would require some GUI changes. The GUI by default only has one set of filter wheel controls. If a microscope has more than one filter wheel, it should show more than one set of widgets for changing the filter wheel.

AdvancedImagingUTSW commented 4 months ago

Previously, I created some circular logic by handing the view the configuration.yaml file, which would then create the GUI elements accordingly.

It seems like we have to do add some logic to the filter wheel controller. If there is more than one filter wheel present, then we need to create an additional column in the GUI.

image

Would need to interpret how to act based upon the configuration.yaml file.

Single filter wheel:

    filter_wheel:
      hardware:
        name: filter_wheel
        type: SutterFilterWheel
        wheel_number: 2
      filter_wheel_delay: .030 # in seconds
      available_filters:
        Empty-Alignment: 0
        GFP - FF01-515/30-32: 1
        RFP - FF01-595/31-32: 2
        Far-Red - BLP01-647R/31-32: 3
        Blocked1: 4
        Blocked2: 5
        Blocked3: 6
        Blocked4: 7
        Blocked5: 8
        Blocked6: 9

Multiple filter wheels:

    filter_wheel:
      -
        hardware:
          name: filter_wheel1
          type: SutterFilterWheel
          wheel_number: 1
        filter_wheel_delay: .030 # in seconds
        available_filters:
          Empty-Alignment: 0
          GFP - FF01-515/30-32: 1
          RFP - FF01-595/31-32: 2
          Far-Red - BLP01-647R/31-32: 3
          Blocked1: 4
          Blocked2: 5
          Blocked3: 6
          Blocked4: 7
          Blocked5: 8
          Blocked6: 9
      -
        hardware:
          name: filter_wheel2
          type: SutterFilterWheel
          wheel_number: 2
        filter_wheel_delay: .030 # in seconds
        available_filters:
          Empty-Alignment: 0
          GFP - FF01-515/30-32: 1
          RFP - FF01-595/31-32: 2
          Far-Red - BLP01-647R/31-32: 3
          Blocked1: 4
          Blocked2: 5
          Blocked3: 6
          Blocked4: 7
          Blocked5: 8
          Blocked6: 9

Currently, I have the code set up so that it sends all filter wheels to the same filter wheel position by looping through them. For example, in filter_wheel_asi:

        # Send Filter Wheel/Wheels to Zeroth Position
        for i in range(self.number_of_filter_wheels):
            self.filter_wheel.select_filter_wheel(filter_wheel_number=i)

            #: int: Active filter wheel.
            self.active_filter_wheel = i
            self.filter_wheel.move_filter_wheel(filter_wheel_position=0)

            #: int: Filter wheel position.
            self.filter_wheel_position = 0

They act as shared devices. The Sutter Filter Wheel has one Lambda 10-3 controller, which we only have a single communication instance with. Same with ASI, which uses a Tiger Controller. Note, for ASI, it calls the Tiger Controller API.

Now we would like to handle which filter wheel is which, and then control each one independently.

AdvancedImagingUTSW commented 4 months ago

The use case is that we often have more than one camera, each of which has its own filter wheel. We ideally want to be able to have independent control over which filter position each camera is in.

For example, we may want: Camera0 -> Filter Wheel Position 2 Camera1 -> Filter Wheel Position 0

AdvancedImagingUTSW commented 4 months ago

This is ultimately also related to #637.

The microscope collects all of the light from the specimen, and you use what is called a dichroic to send some of the fluorescence towards one camera, and the rest of it towards another camera. This essentially acts like a filter wheel as well, but the filter is partially reflective, partially transmissive, and oriented at 45 degrees.

Probably too much information, but it is helpful to understand why we do this.

We put these dichroic in a dichroic turret, like this: http://www.asiimaging.com/docs/filter_and_turret_changer?s%5B%5D=filter&s%5B%5D=slider

It essentially also acts like a filter wheel, except it is a linear device, and not a rotary device in this case.

We would also want to be able to control this same device as if it were a filter wheel.

AdvancedImagingUTSW commented 4 months ago

So, if we had two filter wheels, and a dichroic, we would want three columns in our GUI.

In the configuration.yaml file, the list of filter wheels would have 3 devices. Currently, there is only one dichroic type that we support, which is the ASI. It has a very simple command sequence. We only need to know what the device identity is, which for the example below, is T. It is somewhat like axes mapping...

MOVE T=4
:A
WHERE T
:A 4
AdvancedImagingUTSW commented 4 months ago

In the configuration file, we would have to say that it needs to move "Stage" T as its axes.

AdvancedImagingUTSW commented 4 months ago

This issue has been resolved with #919. Still need to update the documentation.