Samples, runs, and checkpoints
Think of a lab binder. You keep one binder for each physical sample you characterise. Inside the binder, each tab collects everything from one measurement session. Behind each tab sit printed pages: one page for each table of data you chose to save. You can always add new tabs and new pages, and the binder is organised so that you can find any page again, even years later.
MTRL organises your data in exactly this shape, with three levels: the sample container, the instrument run, and the checkpoint.
One application per sample
Section titled “One application per sample”The application (the Mtrl object) is the binder. One application holds one physical
sample, named by its sample identifier, such as polymer-film-01. Everything you commit
to that application — every run, every table, every correction — belongs to that sample and
travels with it when you save the archive.
The application keeps its runs in a read-only mapping called data. You can look up any
run, but you cannot add, replace, or delete entries through the mapping itself. All changes
go through the application, so nothing enters the record without being validated and
committed. When you read the mapping back, runs appear in commit order: the order in which
you recorded them, which a save and reload preserves.
One run per measurement session
Section titled “One run per measurement session”An instrument run (the InstrumentRun object) is one tab in the binder. It groups the
metadata and the checkpoints from one measurement session. You give each run a run name,
such as ftir-replicate-01, and MTRL generates a separate run identifier for it. A
replicate measured the next day gets its own run, named ftir-replicate-02, even if you
measured the same sample in the same way.
Names and identifiers are different things, and confusing them trips many new users. A run
name is for people, and names are allowed to repeat: application.get_runs_by_name()
returns every run that shares one. The run identifier is generated, unique within an
application, and it is what identifier-based routes expect — application.get_run() and
application.transform() take run.run_id, not the name. If you try to add a second run
with an identifier that already exists, MTRL refuses rather than guess which run you meant.
One checkpoint per saved table
Section titled “One checkpoint per saved table”A checkpoint (the MaterialData object) is one printed page: one stable version of
measurement data. In the running story, each FTIR run saves one checkpoint with the display
name spectrum. A checkpoint carries:
- its content, the measured values themselves;
- a stage, one of
raw,cleaned,transformed, oraggregated, describing how far the data has progressed from the instrument; - a generated identifier that names this logical result;
- a display name, the human-readable label such as
spectrum; - an optional source file type, when the data came from an instrument file;
- its lineage: when it was created, which checkpoint it was derived from, and the transformation or aggregation that produced it.
Raw checkpoints start the story, so they have no parent. A cleaned or transformed checkpoint points back at the checkpoint it came from, and its lineage names the exact versions it was computed from.
Why identifiers matter more than names
Section titled “Why identifiers matter more than names”One run may hold several checkpoints of the same type or the same name. A run might, for
example, contain more than one table labelled spectrum. Display names are for people;
they are allowed to repeat. Identifiers are for MTRL, and they never repeat. Whenever you
ask for a checkpoint, it is the identifier — not the name or the stage — that selects one
exact answer.
This is worth remembering as your binder grows. Names tell you what a page is about. The identifier tells you which page it is.
Where next
Section titled “Where next”When you add a run or a checkpoint, MTRL commits it behind a boundary that freezes and protects the values. Read The commit boundary to see what happens at that moment, or revisit Your first record to see these three levels in working code.