Open ianhi opened 2 years ago
Cf. the pixel size config group, which might be close to what you are looking for?
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)
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.
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.
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 :)
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.
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?
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?
(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.
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!
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.
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.
It is hard to know which state device controls the objective turret.
(that's a slightly different wording than used in the original post)
getAvailablePixelSizeConfigs()
, but as @nicost points out, that's error prone because those configs can contain many devices in addition to the actual state device controlling the objective.add the concept of a core objective device (core.setObjectiveDevice
), analogous to ShutterDevice
, CameraDevice
, FocusDevice
, XYStageDevice
.
The obvious objection to this is that it bakes in more assumptions about the standard microscope model, and makes it harder to evolve (for example, what about a light sheet that has multiple detection objective devices). However, a counter argument is that the current model is already well down that road, and that including an ObjectiveDevice
would have made just as much sense as all of the other core devices. In other words, this would be a patch consistent with the "old way" of doing things, which could removed in a new scope model v2. (can't find the issue at the moment but I know there's been plenty of discussions around this)
do nothing
as @nicost states in https://github.com/micro-manager/mmCoreAndDevices/issues/166#issuecomment-1056114471: "I'm bit surprised that you are so focused on the objective". Indeed, perhaps the whole motivation of wanting to know which device controls the objective is misguided? (I suspect there's something to this issue though, or we wouldn't be discussing it, but it's worth mentioning that the solution might be subtler and perhaps already exists)
@marktsuchida and @nicost, curious what your current thoughts are on this. Maybe we can close or take action here
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 namedObjective
: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