Object Model¶
The objects used to wrangle dfmuxes, mezzanines, SQUID controllers, wafers, bolometers, LC boards, and LC channels are all managed by a tool called an Object-Relational Mapper (ORM), and are internally managed in an SQL database. This provides a ton of flexibility and a very efficient means to access relationships between data in the system.
The downside of using an ORM is occasionally jargon-heavy error messages. If you are seeing these messages and want a short-cut deciphering them, feel free to contact Graeme Smecher <gsmecher@threespeedlogic.com>.
Table of Contents
Overview¶
We define four chains of structures:
- Readout hardware: IceCrate, Dfmux, MGMEZZ04, ReadoutModule, and ReadoutChannel;
- The “SQUID controller” chain: MGMEZZ04, SQUIDController, and SQUID;
- The “Wafer” chain: Wafer and Bolometer, and
- The LC chain: LCBoard and LCChannel.
The interconnections between these structures are shown in Objects in a Dfmux Hardware Map..
These objects and linkages are all physically motivated (i.e. they’re things you can poke, and the linkages between them generally match cables.) At the end of each of these chains is some object (a readout channel, a SQUID, a bolometer, and an LC channel) that we want to bundle together to define a single end-to-end chain of physical connections. We do this using a ChannelMapping.
Important
You do not need to construct these objects yourself! Instead, you are encouraged to use the YAML loader in pydfmux.core.session. For documentation, consult Hardware Map.
Readout Chain¶
The “Readout Chain” consists of the warm electronics living in the readout crates – IceBoards running dfmux firmware, and the complement of readout modules and channels living in the FPGA and controlled by software.
The readout chain consists of four objects:
Readout Chain Objects
These classes are all primarily focused with “firmware” tasks (controlling the resources within the FPGA, such as channel frequencies.) Each of these classes are described in the following sections.
Note that “firmware” functions (e.g. Dfmux.set_frequency()
) are not
shown in this documentation, since Sphinx cannot automatically extract them.
IceCrate objects¶
IceCrate objects represent a backplane (presumably in a crate) with IceBoards slotted into it.
Dfmux Objects¶
Dfmux objects represent an IceBoard running in a dfmux configuration (i.e. with dfmux hardware and software.) Under the hood, the Dfmux object inherits from an IceBoard object.
MGMEZZ04 Objects¶
A Dfmux object has up to 2 mezzanines, typically accessed via
dfmux.mezzanine[1]
or dfmux.mezzanine[2]
. For dfmux
experiments, these mezzanines are MGMEZZ04s represented by the
MGMEZZ04
class (which inherits from FMCMezzanine
).
SQUID Chain¶
The SQUID chain is a little odd, since it’s connected at both ends. On the
left side, an MGMEZZ04
mezzanine defines the control path (i.e. for
setting SQUID bias parameters.) On the right side, the data path specifies
which bolometers, LC channels, and readout channels a SQUID belongs with.
Objects in the SQUID Chain
Each of these classes are described in the following sections.
Wafer Chain¶
Objects in the Wafer Chain
Each of these classes are described in the following sections.
Pathstrings¶
Some Dfmux objects can be described by a unique pathstring that determines its
location in the readout chain. For example, the pathstring for
ReadoutChannel
42 located on module 2 of mezzanine 1 on the
IceBoard
with serial 0137 is: 0137/1/2/42. If the parent
IceBoard
is located in slot 5 of the IceCrate
with serial
003, then the pathstring is instead 003/5/1/2/42.
Each Dfmux object with a pathstring (and by extension, each query of Dfmux
objects with pathstrings) also has a pstring()
method for polling for
the pathstring. The result of each poll is cached in the hardware map as a
_pstring
column attribute.
Creating Experiment-Specific Extensions¶
The pydfmux package is intended to support multiple experiments. To do so, we allow the object model to be specialized through inheritance.
For example, the pydfmux.Dfmux
class (which controls
IceBoard hardware running Dfmux firmware) inherits from
an IceBoard
class, which is firmware-agnostic.
Inheritance is also a great way to specialize a given dfmux deployment. For
example, one experiment might wish to add a “date_checked” field to its
pydfmux.Bolometer
class as follows. We begin with some
imports:
>>> import pydfmux
>>> from sqlalchemy import Column, Date, Integer, ForeignKey
>>> from datetime import date
We’re now ready to define our new Bolometer implementation, which inherits
from pydfmux.Bolometer
. The three (unfortunate) lines
beginning with underscores (_) are SQLAlchemy boilerplate describing how to
handle inheritence in the database. The date_checked line does what we’re
interested in (namely, defining a new field that stores a date.)
>>> class SpecialBolometer(pydfmux.Bolometer):
... __tablename__ = 'special_bolometers'
... __mapper_args__ = {'polymorphic_identity': 'special_bolometer'}
... _pk = Column(Integer, ForeignKey('bolometers._pk'), primary_key=True)
...
... date_checked = Column(Date)
We can now use the new class in a hardware map:
>>> hwm = pydfmux.HardwareMap()
>>> bs = [pydfmux.Bolometer(name='Frank'),
... SpecialBolometer(name='Bernice', date_checked=date(2014,11,27)),
... SpecialBolometer(name='Andy', date_checked=date(2013,10,5))]
>>> hwm.add_all(bs)
>>> hwm.commit()
Our hardware map hwm
now contains one
pydfmux.Bolometer
and two instances of
SpecialBolometer
. Queries that search for all
pydfmux.Bolometer
will include the new class. Searches for
just the new class don’t return instances of the old one.
>>> # Search for all Bolometers
>>> print hwm.query(pydfmux.Bolometer).all()
[None.Bolometer(u'Frank'), None.SpecialBolometer(u'Bernice'), None.SpecialBolometer(u'Andy')]
>>> # Search for only SpecialBolometers; retrieve the date_checked column
>>> print hwm.query(SpecialBolometer).date_checked
[datetime.date(2014, 11, 27), datetime.date(2013, 10, 5)]
Note
To take advantage of this querying behaviour, algorithms should be written
using the “core” found in pydfmux.core.dfmux
. Hardware maps
should be constructed using specialized classes.