Degrees of freedom (DOFs)

Continuous degrees of freedom

A degree of freedom is a variable that affects our optimization objective. We can define a simple DOF as

from blop import DOF

dof = DOF(name="x1", description="my first DOF", search_domain=(lower, upper))

This will instantiate a bunch of stuff under the hood, so that our agent knows how to move things and where to search. Typically, this will correspond to a real, physical device available in Python. In that case, we can pass the DOF an ophyd device in place of a name

from blop import DOF

dof = DOF(device=my_ophyd_device, description="a real piece of hardware", search_domain=(lower, upper))

In this case, the agent will control the device as it sees fit, moving it between the search bounds.

Sometimes, a DOF may be something we can’t directly control (e.g. a changing synchrotron current or a changing sample temperature) but want our agent to be aware of. In this case, we can define a read-only DOF as

from blop import DOF

dof = DOF(device=a_read_only_ophyd_device, description="a thermometer or something", read_only=True, trust_domain=(lower, upper))

and the agent will use the received values to model its objective, but won’t try to move it. We can also pass a set of trust_domain, so that our agent will ignore experiments where the DOF value jumps outside of the interval.

Discrete degrees of freedom

In addition to degrees of freedom that vary continuously between a lower and upper bound, we can define discrete degrees of freedom. One kind is a binary degree of freedom, where the input can take one of two values, e.g.

discrete_dof = DOF(name="x1", description="A discrete DOF", type="discrete", search_domain={"in", "out"})

Another is an ordinal degree of freedom, which takes more than two discrete values but has some ordering, e.g.

ordinal_dof = DOF(name="x1", description="An ordinal DOF", type="ordinal", search_domain={"low", "medium", "high"})

The last is a categorical degree of freedom, which can take many different discrete values with no ordering, e.g.

categorical_dof = DOF(name="x1", description="A categorical DOF", type="categorical", search_domain={"banana", "mango", "papaya"})