Look underneath a result
In this lesson you will look inside the result handle you have already been using. By the
end you will be able to distinguish a convenient name from an exact version, and use one
registered operation through sample.core without moving your data elsewhere. Allow
about ten minutes; this is a chance to understand the model, not learn a longer setup.
The example uses the sample and raw handle from
Record your first measurement, still active after lesson 3,
so a session that has followed the tutorial this far is ready. You need only the base
package.
A name helps you find a result; a reference pins it down
Section titled “A name helps you find a result; a reference pins it down”Imagine writing “the FTIR spectrum” in your lab notebook. That is enough for a conversation until someone corrects the spectrum. Now there are two questions: which result are we talking about, and which version of it did we use? MTRL keeps those questions separate.
A checkpoint is the logical result, such as your measured spectrum. Its checkpoint_id
stays the same through a correction. A record is one immutable version of that
checkpoint, and its record_id names that version alone. The handle’s ref pairs those
identifiers into an exact record reference.
Name: ftir-replicate-01 a readable label, not a unique versionCheckpoint: C the result whose identity survives a correction├── Record: R1 the original values; an old handle still names these└── Record: R2 the corrected values; active selection finds these
Exact references: (C, R1) and (C, R2) name different versions of the same result.The letters stand in as placeholders, not identifiers you type into the example. The point is that a handle does not silently follow a correction. If an analysis used R1, its reference must continue to say R1, even after R2 becomes active. Otherwise the history would describe an analysis you never actually performed.
Names are useful for finding things, but they are not a first-or-latest shortcut.
select returns every exact match to your filters; one requires exactly one match and
raises LookupError if it finds none or several. A name may be reused, so identifiers
help you narrow a selection when the label alone is ambiguous.
The same lab folder, with a more detailed view
Section titled “The same lab folder, with a more detailed view”So far Sample has taken care of the structure around your measurements. Underneath it,
sample.core is the Mtrl application that owns the history. Think of the facade as
the convenient front of the same lab folder, not a second folder with another copy of
your work.
The core contains runs, which group measurement or analysis results, and the
checkpoints within them. InstrumentRun and MaterialData are the core construction
types. You do not need to construct them for routine recording, transforming, correcting
or aggregating: Sample already takes you to that same model. There is no separate
facade archive format to learn.
One reason to use the detailed view is a registry: the application’s set of approved,
named operations. The facade’s transform accepts your callable, not an operation name.
For a registered operation, use sample.core, then come back to facade selection.
Try one registered operation and come back
Section titled “Try one registered operation and come back”The example first checks that the handle’s reference matches the core’s active reference.
It then uses the registered resample_linear operation to put the spectrum on 51 points
instead of 101. Notice the explicit x_field and y_field: the operation needs to know
which field supplies coordinates and which supplies values. It does not guess from their
names.
Finally, sample.one finds the new checkpoint. You have changed the level of API detail,
not the application holding your results.
print(f"checkpoint: {raw.checkpoint_id}; record: {raw.record_id}")print(f"original handle still resolves: {raw.ref == sample.core.active_ref(raw.checkpoint_id, run_id=raw.run_id)}")
aligned_checkpoint = sample.core.transform( raw.run_id, raw.checkpoint_id, "resample_linear", parameters={ "x_field": "wavenumber", "y_field": "absorbance", "x_targets": np.linspace(2000.0, 3000.0, 51).tolist(), }, checkpoint_name="aligned",)aligned = sample.one(checkpoint_id=aligned_checkpoint.checkpoint_id)print(f"aligned: {aligned.name}, {len(aligned.to_numpy())} points")print(f"active records: {len(sample.records)}")checkpoint: 01a18304-dadc-74b8-b8cf-70ae86c8e344; record: 01a18304-dae2-7181-9fb2-17f65805fcecoriginal handle still resolves: Truealigned: aligned, 51 pointsactive records: 2The first line shows the two generated identifiers of the measurement and its corrected replacement. Yours will differ — identifiers mint on each commit — but the shape stays: two distinct versions side by side, the stale check passing for the original, and the aligned output holding all 51 target points across the two active records.
What just happened?
Section titled “What just happened?”The handle and the core agreed on the exact version of the measured spectrum. The core then committed the registered resampling result as a new checkpoint in one revision. Selecting that checkpoint returned a facade handle, ready to use like any other result. The core remained the sole owner of the records, lineage, revisions and archive behaviour.
Keep one more distinction in mind: sample.records, select and one show active
records, not the whole historical catalogue. For an older version, use
sample.core.get_record(record_id). An old handle may still be readable even when a new
mutation using it is refused; reading history and extending the current analysis are
different requests. The next lesson makes that difference visible.
Where next
Section titled “Where next”Find a result and fix a mistake puts those two identifiers to work: one result keeps its identity while its values get a new version. The registry guide covers approved operation sets.