Skip to content

Configuration and Groups

Configuring a microscope with Micro-Manager entails storing and retrieving a number of device settings. In general, a single setting comprises a device name, a property name, and a value. A Configuration object (a preset, in the Micro-Manager app) represents a collection of individual settings; that is, it represents a number of device parameters all in a specific state, such as would be used to prepare the microscope to image a specific channel, like "DAPI", or "FITC".

A Configuration Group is, in turn, a collection of Configuration objects; for example, all of the Configuration objects that represent different "Channel" settings.

Conceptually, Configurations and Groups are organized like this:

ConfigGroupA:
    Configuration1:
        deviceA:
            propertyA: 'value_a'
            propertyB: 'value_b'
        deviceB:
            propertyC: 'value_c'
        ...
    Configuration2:
        deviceA:
            propertyA: 'value_d'
            propertyB: 'value_e'
        deviceB:
            propertyC: 'value_f'
        ...
    ...
ConfigGroupB:
    Configuration1:
        deviceC:
            propertyA: 'value_g'
        ...
    ...

Using groups and presets

Groups and presets are usually defined in your configuration (.cfg) file. The demo configuration has a few of them:

from pymmcore_plus import CMMCorePlus

core = CMMCorePlus()
core.loadSystemConfiguration()  # demo config

core.getAvailableConfigGroups()
# ('Camera', 'Channel', 'Channel-Multiband', 'LightPath', 'Objective', 'System')
core.getAvailableConfigs("Channel")
# ('Cy5', 'DAPI', 'FITC', 'Rhodamine')

core.setConfig("Channel", "FITC")  # (1)!
core.getCurrentConfig("Channel")  # 'FITC'
  1. This sets all of the properties in the FITC preset (and emits the configSet event).

To see what a preset actually does, use getConfigData. It returns a Configuration that can be indexed with (device, property) keys, and iterated over as (device, property, value) tuples:

cfg = core.getConfigData("Channel", "DAPI")
cfg["Dichroic", "Label"]  # '400DCLP'
list(cfg)
# [('Dichroic', 'Label', '400DCLP'), ('Emission', 'Label', 'Chroma-HQ620'),
#  ('Excitation', 'Label', 'Chroma-D360'), ('Core', 'Shutter', 'White Light Shutter')]

Defining presets

New presets are defined one setting at a time with defineConfig (the group is created if it doesn't exist yet), or all at once with a ConfigGroup object:

core.defineConfig("Channel", "Brightfield", "Dichroic", "Label", "400DCLP")

# or, equivalently, with a ConfigGroup:
channel = core.getConfigGroupObject("Channel")
channel["Brightfield"] = {
    ("Dichroic", "Label"): "400DCLP",
    ("Emission", "Label"): "Chroma-HQ700",
}
channel.setConfig("Brightfield")

These changes only live in memory. To keep them, save the whole system configuration to a new file (which you can load next time with loadSystemConfiguration):

core.saveSystemConfiguration("my_config.cfg")

Pixel size presets work much the same way, with their own methods (definePixelSizeConfig, getPixelSizeConfigData, etc...), except that you don't set them yourself. The core picks the one that matches the current state of the microscope. With the demo config, for example, core.setConfig("Objective", "20X") changes getCurrentPixelSizeConfig() to 'Res20x' and getPixelSizeUm() to 0.5.

pymmcore-plus objects

MMCore and pymmcore's configuration object implements a basic container interface, but with custom method names like addSetting, getSetting, and deleteSetting.

pymmcore-plus provides a Configuration subclass that supports mapping-style indexing, where the keys are 2-tuples of (deviceLabel, propertyLabel) and the values are the property values: cfg["Camera", "Exposure"], cfg["Camera", "Exposure"] = "10" and del cfg["Camera", "Exposure"] all work. (Note, however, that iterating over a Configuration object behaves like iterating over a list of 3-tuples (deviceLabel, propertyLabel, value), not a dict, and there are no keys() or items() methods. Use cfg.dict() if you want a nested dict.) All of the CMMCorePlus methods that return a configuration return this subclass, unless you pass native=True.

pymmcore-plus also offers a ConfigGroup object (returned by getConfigGroupObject), which is a MutableMapping where the keys are Configuration Preset names and the values are Configuration objects.

See Configuration and ConfigGroup for the full API. The related core methods are in the Config groups & presets section of the CMMCorePlus method summary.