Skip to content

Replace a checkpoint

When better evidence arrives — a re-measurement of your sample — you replace the old checkpoint so the archive records that new evidence superseded the old.

sample.correct fixes one active record and keeps the checkpoint identity; replacement supersedes a checkpoint with new evidence and remains a core operation, as shown here.

This guide assumes: you have finished the tutorial path, in particular Fix a mistake, and you know the difference between a checkpoint and a record from two kinds of identity.

Suppose your first FTIR run of polymer-film-01 was measured at the wrong detector gain. The values are honest measurements, not typos, so a correction sends the wrong message: the old record was not mistaken, it has been superseded. You repeat the measurement at the right gain and replace the checkpoint with the new evidence.

import numpy as np
from mtrl import InstrumentRun, MaterialData, Mtrl
application = Mtrl(sample_id="polymer-film-01")
run = InstrumentRun(run_name="ftir-replicate-01")
checkpoint = MaterialData(
content=np.array([0.15, 0.21, 0.19]),
type="raw",
checkpoint_name="spectrum",
)
run.add_checkpoint(checkpoint)
application.add(run)
prior = application.get_active_record(checkpoint.checkpoint_id)
replacement = application.replace_checkpoint(
run.run_id,
application.active_ref(prior.checkpoint_id, run_id=run.run_id),
MaterialData(
content=np.array([0.16, 0.22, 0.20]),
type="raw",
checkpoint_name="spectrum",
),
)
print(f"new checkpoint: {replacement.checkpoint_id != prior.checkpoint_id}")
print(f"new record: {replacement.record_id != prior.record_id}")
print(
f"lineage names the prior record: "
f"{replacement.lineage.replacement_of.record_id == prior.record_id}"
)
print(f"prior record still readable: {application.get_record(prior.record_id) is not None}")
new checkpoint: True
new record: True
lineage names the prior record: True
prior record still readable: True

Every printed line ends in True: the replacement has fresh identities, its lineage names the exact record it supersedes, and the superseded record still reads back from history.

The call application.replace_checkpoint(run_id, target, replacement) commits new evidence in place of the old checkpoint. The target is a RecordRef (a pointer to one exact record) that must match the currently active record on both its checkpoint identifier and its record identifier, or MTRL refuses the change and commits nothing.

The replacement mints a brand-new checkpoint identifier and a brand-new record identifier. It reuses neither identity from the old checkpoint. Its lineage links back with a replacement_of reference to the exact record it supersedes, which is the link your third printed line checks. From now on the active view selects the replacement: the old checkpoint no longer appears in get_active_record or in exports of active data.

Nothing is deleted. The fourth printed line shows the old record still reads back through application.get_record(prior.record_id). The full history — the superseded measurement and the evidence that replaced it — stays in the archive.

Caution — The target must be the record that is active at the moment you call. If another correction landed first, your saved RecordRef is stale and MTRL raises InvalidRecordRevisionError. If another replacement landed first, the old CheckpointId has left the active view, and MTRL raises UnknownCheckpointError instead: only a correction preserves the checkpoint identity. Either way, read the active record again and rebuild the target.

Tip — Choose the verb that matches what happened in the lab. A correction says “the same measurement, fixed” and keeps the checkpoint identity. A replacement says “new evidence supersedes the old” and mints new identities. The page on corrections versus replacements walks through the choice.