Skip to content

Version 0.6.0. What's new?

Quickly:

  • You can access the filename inside parse_config_str function
  • Smarter config parsing. Now you can save the values used during acquisition.
  • cfg is now an attribute of aqm.data object.
  • Linting works with the local function definition.
  • Add json utils
  • class Path have more functionality

You can access the filename inside parse_config_str function

As easy as it sounds all these syntaxes are possible:

aqm.parse_config_str(['filename']) # -> "filename = ..."

aqm.parse_config_str(['file']) # -> "file = ..."

aqm.parse_config_str(['f']) # -> "f = ..."

cfg is now an attribute of aqm.data object.

With version 0.5.0 possibility to parse default configurations was added. The syntax is like this:

aqm.set_default_config_files(['config1.py', ...])
...
aqm.analysis_cell()
aqm.cfg.b # Wrong way to access the configuration value

But to make it more explicit that the configurations which have been parsed is the ones saved during acquisition, the best practice is to use aqm.data.cfg instead.

aqm.set_default_config_files(['config1.py', ...])
...
aqm.analysis_cell()
aqm.data.cfg.b # Right way

Keep in mind that in future updates the syntax aqm.cfg could be suspended.

Smarter config parsing. Now you can save the values used during acquisition.

More on parsing the configurations files. Some configuration files are like this:

def local_switch(param):
    if param == 'a':
        return 'param_a'
    return 'param_b'

str_1 = "a"
str_2 = local_switch(str_1)

And it's evident that str_2 is equal to "param_b". We still don't want to eval the config file during analysis just to find out what the values are. But you imported the config file during the acquisition, so why not save the values that were used? And this is exactly the logic of the following function.

Suppose you have the configuration file named config.py with the code given just above. Inside your main script you import config as some_cfg. Then, you should give this module to aqm:

aqm.set_config_file(["files/config.py"])
aqm.set_config_evaluation_module("files/config.py", some_cfg)

Remember that the name of the config files should be unique even if there are in different folders.

Then inside your analysis_cell you can parse str_2 parameter.

aqm.analysis_cell()

aqm.data.parse_config_str(['str_1', 'str_2'])
# -> 'str_1 = a; str_2 = param_a'

Linting works with the local function definition.

Now the linting works with the local function definition, but not completely ignores it. It will ignore all the local variables inside your function, but will lint the global ones.

Example:

aqm.analysis_cell()
def abc(a, b):
    c = a + b
    return c * x

This code will lint only x variable.

Add json utils

Problems with classical json that are solved:

  • When loading, int and float values are strings. So read function uses NumbersDecoder by default.
  • When dumping, object that can be converted to string or list are not converted. So write function converts objects to string and iterable to list.

Example:

from labmate import json as jsn
data = {'a': 1}
jsn.write(path, data)
from labmate import json as jsn
data = jsn.read(path)

Better Path class

Class Path is improvement of class Path from standard pathlib library. And now it's even better.

Features of Path class:

  • makedirs. Same as os.makedirs(dirname(path)).
  • make_extension. Checks is extension of the file is the one (or ones) expected. Otherwise add suffix to the end of the path.

Useful properties:

  • dirname
  • basename

Both return object of type Path.

Minor features

  • Fix bugs with AcquisitionLoop
  • Fix the bug at detecting an error in a last acquisition_cell run
  • Remove all from __future__ import annotations
  • Ignore bool type during config evaluation