micro-manager / mmCoreAndDevices

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

add `objectiveConfigGroup` analgous to `channelConfigGroup` #166

Open ianhi opened 2 years ago

ianhi commented 2 years ago

Problem

The getChannelGroup is great. However, there is no equivalent for objectives. This is problematic because as far as I can tell the recommended approach to config groups is to have one named Objective: image

for channel groups we first check for if the channelGroup was defined in the config file and then fall back to guessing reasonable names: https://github.com/tlambert03/pymmcore-plus/blob/62416c797ec40a7c7614fc16061f1928ced8382d/pymmcore_plus/core/_mmcore_plus.py#L393-L413

However, for objectives we are just guessing based on the available devices in each config group: https://github.com/tlambert03/napari-micromanager/blob/0f61d199406c18e353086f0c4ea589f7c4d25e6f/micromanager_gui/main_window.py#L470-L490

Possible Solution

add analogous logic for channelGroup for objectiveGroup.

Or move towards not putting this information into a config group - because (i think??) this a group that's best left as modifying a single device - and instead follow the camera model of having a single current objective

cc @fdrgsp @tlambert03

marktsuchida commented 2 years ago

Cf. the pixel size config group, which might be close to what you are looking for?

tlambert03 commented 2 years ago

that's a good point. @ianhi, perhaps a best first way to guess the device label an Objective device would be:

for cfg in mmc.getAvailablePixelSizeConfigs():
   return mmc.getPixelSizeConfigData(cfg).getSetting(0).getDeviceLabel()

?

(though of course, if they haven't set pixel size configs it won't work)

ianhi commented 2 years ago

I have to confess I don't really understand how the pixel size config stuff works or what it does.

One worry i'd have about using it then is that I suspect like me many users don't know about it and thus don't set it. Towards that end I remember that when you make a config in MM there was an option to submit the config. Are those submitted configs publicly available? I'm really curious to analyze them in order to learn more about how prevalent things like this (or channelGroup are.

nicost commented 2 years ago

A pixel size configuration is a special configuration group that - in addition to the normal properties - has a pixel size (i.e. how many microns in real space is imaged on one pixel of the camera), and an affine transform (i.e., what affine transform maps real space on the camera). The latter is a recent, but very useful addition that in principle contains the pixel size information as well.

Most configuration files contain this information, not the least since most are derived from the demo config that is populated with this information. Creating pixel size conifgs is described in the configuration manual: https://micro-manager.org/Micro-Manager_Configuration_Guide#pixel-size-calibration. In addition, I hope that everyone using a microscope is looking for this information, hence I expect them to find the menu entry Devices > Pixel Size Configuration.

I am a bit surprised that you are so focused on the objective. Other things (notably the tube lens, but possibly others as well), will influence magnification, which is what you are really interested about.

The most interesting aspect here is the original design decision in Micro-Manager to treat all device as having properties with key value pairs. The system implied very little knowledge about what these things are or what they do, leaving most of this configuration up to the system configurator. It looks like you want to put more knowledge upfront, which may, or may not be a good decision. I kind of like the naive approach combined with educating the consumers of the software. In addition, we always left naming of properties to the devices themselves. It is interesting to now see a movement towards more defined and portable naming schemes. Having something like that would certainly make it easier for you to find objectives, and it is certainly worthwhile figuring out how to introduce some more controlled vocabulary in the 100s of MM device adapters.

B.t.w., @tlambert03 code is very error prone. Any pixel size config with tube lens listed first will not result in a list of objectives but of tube lenses.

tlambert03 commented 2 years ago

Thanks @nicost

I am a bit surprised that you are so focused on the objective. Other things (notably the tube lens, but possibly others as well), will influence magnification, which is what you are really interested about.

this is only partly true. You certainly need mag for properly handling acquired data, but you need to know more about the underlying devices when controlling the hardware (just knowing mag isn't going to be enough there).

It looks like you want to put more knowledge upfront, which may, or may not be a good decision.

i'd say at this point we're largely interested in the same things that the java based gui was. For instance, mm had to make at least some assumptions about the standard scope config to build the MDA window, which is undoubtedly useful no? It has things like getFocusDevice, getGalvoDevice, getCameraDevice, etc... so there too MM has baked in some of this upfront knowledge, yes? I'm 100% with you that this shouldn't be where it ends. I love the generic collection of devices and properties as the underlying scope model. But it's presumably for the same reasons those special methods were introduced that a getObjectiveDevice could conceivably useful, at least in some (many?) scenarios?

B.t.w., @tlambert03 code is very error prone. Any pixel size config with tube lens listed first will not result in a list of objectives but of tube lenses.

thanks! good point. We still haven't hit on anything that's not error prone. hence this issue :)

ianhi commented 2 years ago

All the below should be read with the caveat that I'm essentially a self taught user of microscopes/micromanager. Some bits here and there but never with a consistent mentor or concerted learning environment.

I am a bit surprised that you are so focused on the objective. Other things (notably the tube lens, but possibly others as well), will influence magnification, which is what you are really interested about.

Now this has me surprised :). Again probably due to my ignorance so excited to learn here. For me the objective has most often what I'm really interested as it's the only piece of magnification optics that I can control. So it seems like the natural thing to switch if I want to scan around in a broad view at low mag and then switch to higher mag objective for data collection. (this was also more important back when I was much worse at focusing on a sample- but thankfully I've gotten much better!)

I hope that everyone using a microscope is looking for this information, hence I expect them to find the menu entry Devices > Pixel Size Configuration.

I've never actually done the pixel calibration because it felt a bit intimidating and didn't seem super important as I was doing all the analysis in python. These are anecdotes, but I know at least one other person (postdoc) who also hasn't done this on his microscope which is controlled with micromanager.

nicost commented 2 years ago

Sorry, did not mean to sound so lecturing. Most microscope software (including Micro-Manager) will be configured by either a system integrator or "super user". That person will create the configuration files (including pixel size configurations), that are used by the "normal users" to do microscopy. This configuration role helps separate the logic of the Core (which has as little knowledge as possible) from the logic of the microscope user. Properties, and collections of properties (i.e. config groups) make it possible for the system configurator to create a workable user interface (the configuration groups and presets you see in the MM UI).

When you are asking for an objectiveConfigGroup, you are asking for the Core to have knowledge of something that the Core relegates to a human being, i.e. the system configurator. To the Core, objective switchers are just another state device, without any distinctive properties. Your examples of getFocusDevice, getGalvoDevice, getCameraDevice all refer to device types that the Core knows about, i.e. it knows what a Focus device is, and it lets you set one as the default one, but it really does not know anything about an Objective device. I completely agree that it would be useful to store structured information about objectives somewhere in the system, i.e. it is a glaring omission not to know the numerical aperture, chromatic correction, etc.. It would be useful to think a bit more about what that should look like, and especially where the information should live (in the Device Adapter, in the Core, in the config file?). However, before making that jump, if the goal is to create the same capabilities as in the Java GUI, why not use the same mechanism and leave knowledge about objectives to the system configurator?

tlambert03 commented 2 years ago

To the Core, objective switchers are just another state device, without any distinctive properties.

In a simple system yes. But as you point out, mag is more than just the lens. So if someone had an objective configuration that, for instance, changed the tube lens or optovar along with the state device... then we're back to needing a config group, right?

marktsuchida commented 2 years ago

(Since I'm not sure this was understood above) note that the Magnifier device type (used for optovars; we've also used it for LSM zoom/resolution) gets special treatment by MMCore when computing the pixel size. You do not include the Magnifier in the pixel size config group; it gets handled implicitly. (This is often confusing to users.)

One limitation is that there can only be one Magnifier active at a time.

tlambert03 commented 2 years ago

Thanks. i did miss that.

Anyway, I can definitely understand hesitation to bake in any assumptions in general. We run into this all the time in napari too where users are surprised to see that we have no internal model for a specific very common use case (such as labeling an axis as "belonging" to a specific dimension like time/channel/etc). Channels (sets of optical components) was an obvious thing to bake deeply into mmcore. All these other things (light path, lenses or other switchable optics, etc) have a vaguely similar argument, where there is a handful of things that need to change in concern. But since it's a bit hard to say exactly where the special casing ends, I'm very understanding/supportive of just leaving it out (and up to the user to assign semantics.)

This all came up because we were offering objective control in our GUI ... which is essentially what @nicost was saying by "It looks like you want to put more knowledge upfront". and indeed! it is one tiny bit more than the current model used in MDA.

I think I'm convinced enough that this probably shouldn't go into core. Maybe @ianhi or others have more thoughts, but it'd be fine with my if this got closed. thanks again!

nicost commented 2 years ago

Just as an historical note, we added the concept of channelConfigGroup to the Core only after about 10 years;) It became too much of a hack not to have it, but its addition was also a hack. I find myself often proposing creation of a Device Adapter to hold certain information, for instance, you could have a "Microscope Model" device adapter that has properties that you can query to find the objective, light path, etc.. You can then store the properties of that Microscope Model Device Adapter in the configuration file (job for the microscope configurator), and query them at runtime. Such design is completely driven by the current architecture of MM, but could work well.

tlambert03 commented 2 weeks ago

pinging this issue again since it came up at the recent hackathon. I think we should either close this as not planned, or try to condense the conversation above into possible action items.

Problem

It is hard to know which state device controls the objective turret.

(that's a slightly different wording than used in the original post)

Current Workarounds:

Possible Solutions

@marktsuchida and @nicost, curious what your current thoughts are on this. Maybe we can close or take action here