Model fit¶
How well each example in examples/ can be expressed in the model. Every
source value ends up in the example's dataset in export/, either in a model
field or, where it has none, in a Property record, so nothing is lost; this
page counts which. It measures the model and the mapping rules together: a
value the model has a field for still counts as not covered until a rule, or
the mapper's own matching, takes it there.
A value is counted in one of five categories:
| Category | Covered | The value |
|---|---|---|
| By rule | yes | is placed in a model field by a rule of mappings.json or combinations.json |
| Automatic | yes | is placed without a rule: its source path matches the end of one model path, as it is (Pixels.SizeX is Image.Pixels.SizeX); a source using the model's own names needs no rules |
| Does not fit | no | was taken to a model field, but its type, format or enumeration does not fit the field, or the field was taken |
| No such field | no | was taken into a model group that has no field of its name (Image.BeamScanSettings.scanHW) |
| No location | no | has no rule, and matches no model path |
Two columns check the output against the input before anything is counted, and are 100% for every example, or data is lost or made up:
- Kept: the share of the input's values the output holds, in a model field or as a Property.
- Traced: the share of the output's fields and Properties that name the input values they hold, or the ones they are derived from (a combined date, a unit the source implies).
Not every value is acquisition metadata. Covered, in scope leaves out the
values the model is not meant to hold: processing of the recorded image data
(TALOS's Velox operations, Leica's in-scan corrections and THUNDER), facts
about the file or its format (schema versions, GUIDs, TIFF and DICOM
bookkeeping), how the image is shown (display levels, LUTs, databars), the
acquisition software's own configuration (Leica's autofocus, trigger and
automatic-selection setup), and patient and administrative data. They are
listed, by kind, in scripts/out_of_scope.json, and they are still kept: only
the coverage leaves them out. A value the model does hold always counts, and a
test fails on a pattern that names no key of any example.
The table counts keys: source paths with their list indices removed, so
Laser[0].Name and Laser[1].Name are one key, and a long list of repeated
records does not swamp an example. A key whose values differ, one channel's
fitting and another's not, counts in the best of its values' categories.
Covered, values gives the same share of the example's values; the
counts after it are of keys.
| Example | Kept | Traced | Covered, keys | Covered, in scope | Covered, values | Keys | By rule | Automatic | Does not fit | No such field | No location | Out of scope |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Cikteq SEM4000x Automap | 100% | 100% | 63% | 68% | 63% (55 of 87) | 87 | 54 | 1 | 1 | 20 | 11 | 6 |
| Cikteq SEM4000x Normal | 100% | 100% | 63% | 68% | 63% (55 of 87) | 87 | 54 | 1 | 1 | 20 | 11 | 6 |
| Delmic FAST-EM | 100% | 100% | 31% | 44% | 27% (4 of 15) | 13 | 3 | 1 | 0 | 2 | 7 | 4 |
| dicom | 100% | 100% | 22% | 49% | 23% (24 of 105) | 94 | 19 | 2 | 0 | 0 | 73 | 51 |
| dicom_ct_axial | 100% | 100% | 17% | 31% | 15% (19 of 128) | 95 | 14 | 2 | 0 | 0 | 79 | 44 |
| dicom_ct_reformat | 100% | 100% | 20% | 42% | 16% (17 of 105) | 71 | 12 | 2 | 0 | 0 | 57 | 38 |
| EMSIS Xarosa | 100% | 100% | 41% | 57% | 38% (13 of 34) | 29 | 11 | 1 | 0 | 2 | 15 | 8 |
| lif_lmd7_metadata | 100% | 100% | 22% | 23% | 16% (14 of 88) | 65 | 14 | 0 | 0 | 1 | 50 | 3 |
| lif_metadata | 100% | 100% | 2% | 2% | 1% (47 of 4902) | 1629 | 29 | 0 | 0 | 0 | 1600 | 440 |
| lif_sp5_metadata | 100% | 100% | 3% | 10% | 1% (25 of 2870) | 747 | 25 | 0 | 0 | 0 | 722 | 499 |
| lif_tilescan_metadata | 100% | 100% | 6% | 9% | 0% (83 of 19738) | 638 | 41 | 0 | 0 | 0 | 597 | 162 |
| ome-tiff | 100% | 100% | 32% | 46% | 24% (42 of 173) | 112 | 32 | 4 | 5 | 4 | 67 | 33 |
| platy_tomography | 100% | 100% | 30% | 41% | 30% (7 of 23) | 23 | 7 | 0 | 0 | 0 | 16 | 6 |
| svs_metadata | 100% | 100% | 69% | 95% | 69% (18 of 26) | 26 | 18 | 0 | 0 | 0 | 8 | 7 |
| TFS Phenom Pharos | 100% | 100% | 50% | 56% | 50% (53 of 107) | 105 | 52 | 1 | 2 | 40 | 10 | 10 |
| TFS TALOSF | 100% | 100% | 17% | 47% | 5% (100 of 1956) | 593 | 98 | 2 | 0 | 480 | 13 | 379 |
| TFS TALOSF 2 | 100% | 100% | 15% | 60% | 4% (118 of 3014) | 798 | 116 | 2 | 0 | 673 | 7 | 602 |
| Zeiss Supra55 Fibics ATLAS | 100% | 100% | 69% | 76% | 69% (51 of 74) | 74 | 50 | 1 | 2 | 13 | 8 | 7 |
Fields filled¶
| Example | Fields filled | LiMi | Extension |
|---|---|---|---|
| Cikteq SEM4000x Automap | 64 | 18 | 46 |
| Cikteq SEM4000x Normal | 64 | 18 | 46 |
| Delmic FAST-EM | 4 | 2 | 2 |
| dicom | 31 | 27 | 4 |
| dicom_ct_axial | 26 | 22 | 4 |
| dicom_ct_reformat | 24 | 21 | 3 |
| EMSIS Xarosa | 15 | 14 | 1 |
| lif_lmd7_metadata | 15 | 14 | 1 |
| lif_metadata | 37 | 30 | 7 |
| lif_sp5_metadata | 27 | 22 | 5 |
| lif_tilescan_metadata | 57 | 46 | 11 |
| ome-tiff | 36 | 36 | 0 |
| platy_tomography | 14 | 12 | 2 |
| svs_metadata | 19 | 14 | 5 |
| TFS Phenom Pharos | 48 | 18 | 30 |
| TFS TALOSF | 85 | 25 | 60 |
| TFS TALOSF 2 | 95 | 22 | 73 |
| Zeiss Supra55 Fibics ATLAS | 54 | 11 | 43 |
Per example¶
Cikteq SEM4000x Automap: 63% of 87 keys covered
Placed automatically, without a rule (worth checking that each means what the field does):
SamplesPerPixel→Image.Pixels.Channel.SamplesPerPixel
No such field, by the model path the keys were headed for (a group without their field, or a plain field given a record):
Image.ElectronBeamSettings: 11Experimenter: 5MechanicalStage: 2Image.BeamScanSettings: 1Instrument: 1
No location, by source group:
FEI_HELIOS.TiltCorrect: 5FEI_HELIOS.Other: 1ImageWidth: 1ImageLength: 1BitsPerSample: 1PhotometricInterpretation: 1ResolutionUnit: 1
Out of scope, not acquisition metadata (scripts/out_of_scope.json):
display: 4file: 2
Cikteq SEM4000x Normal: 63% of 87 keys covered
Placed automatically, without a rule (worth checking that each means what the field does):
SamplesPerPixel→Image.Pixels.Channel.SamplesPerPixel
No such field, by the model path the keys were headed for (a group without their field, or a plain field given a record):
Image.ElectronBeamSettings: 11Experimenter: 5MechanicalStage: 2Image.BeamScanSettings: 1Instrument: 1
No location, by source group:
FEI_HELIOS.TiltCorrect: 5FEI_HELIOS.Other: 1ImageWidth: 1ImageLength: 1BitsPerSample: 1PhotometricInterpretation: 1ResolutionUnit: 1
Out of scope, not acquisition metadata (scripts/out_of_scope.json):
display: 4file: 2
Delmic FAST-EM: 31% of 13 keys covered
Placed automatically, without a rule (worth checking that each means what the field does):
SamplesPerPixel→Image.Pixels.Channel.SamplesPerPixel
No such field, by the model path the keys were headed for (a group without their field, or a plain field given a record):
XResolution: 1YResolution: 1
No location, by source group:
ImageWidth: 1ImageLength: 1BitsPerSample: 1PhotometricInterpretation: 1ResolutionUnit: 1DateTime: 1SampleFormat: 1
Out of scope, not acquisition metadata (scripts/out_of_scope.json):
file: 4
dicom: 22% of 94 keys covered
Placed automatically, without a rule (worth checking that each means what the field does):
AcquisitionDate→Image.AcquisitionDateSamplesPerPixel→Image.Pixels.Channel.SamplesPerPixel
No location, by source group:
SpecificCharacterSet: 1ImageType[]: 1InstanceCreationDate: 1InstanceCreationTime: 1SOPClassUID: 1StudyDate: 1SeriesDate: 1ContentDate: 1AcquisitionDateTime: 1StudyTime: 1- and 63 more
Out of scope, not acquisition metadata (scripts/out_of_scope.json):
file: 25patient and administrative: 24display: 2
dicom_ct_axial: 17% of 95 keys covered
Placed automatically, without a rule (worth checking that each means what the field does):
AcquisitionDate→Image.AcquisitionDateSamplesPerPixel→Image.Pixels.Channel.SamplesPerPixel
No location, by source group:
ContributingEquipmentSequence[].PurposeOfReferenceCodeSequence[]: 3ImageType[]: 1InstanceCreationDate: 1InstanceCreationTime: 1SOPClassUID: 1StudyDate: 1SeriesDate: 1ContentDate: 1StudyTime: 1SeriesTime: 1- and 67 more
Out of scope, not acquisition metadata (scripts/out_of_scope.json):
file: 24patient and administrative: 18display: 2
dicom_ct_reformat: 20% of 71 keys covered
Placed automatically, without a rule (worth checking that each means what the field does):
AcquisitionDate→Image.AcquisitionDateSamplesPerPixel→Image.Pixels.Channel.SamplesPerPixel
No location, by source group:
ContributingEquipmentSequence[].PurposeOfReferenceCodeSequence[]: 3ImageType[]: 1InstanceCreationDate: 1InstanceCreationTime: 1SOPClassUID: 1StudyDate: 1SeriesDate: 1ContentDate: 1StudyTime: 1SeriesTime: 1- and 45 more
Out of scope, not acquisition metadata (scripts/out_of_scope.json):
file: 20patient and administrative: 16display: 2
EMSIS Xarosa: 41% of 29 keys covered
Placed automatically, without a rule (worth checking that each means what the field does):
SamplesPerPixel→Image.Pixels.Channel.SamplesPerPixel
No such field, by the model path the keys were headed for (a group without their field, or a plain field given a record):
XResolution: 1YResolution: 1
No location, by source group:
ExifVersion: 1DateTimeDigitized: 1MeteringMode: 1FlashpixVersion: 1ColorSpace: 1ExposureMode: 1ImageWidth: 1ImageLength: 1BitsPerSample[]: 1PhotometricInterpretation: 1- and 5 more
Out of scope, not acquisition metadata (scripts/out_of_scope.json):
file: 8
lif_lmd7_metadata: 22% of 65 keys covered
No such field, by the model path the keys were headed for (a group without their field, or a plain field given a record):
Image: 1
No location, by source group:
HardwareSetting.Mic: 16ImageDescription.Channels: 9HardwareSetting.Laser: 8ImageDescription.Dimensions: 5CustomData.UserInfo: 3CustomData.ExperimentInfo: 2path: 1UniqueID: 1CustomData.Version: 1CustomData.Name: 1- and 3 more
Out of scope, not acquisition metadata (scripts/out_of_scope.json):
display: 2file: 1
lif_metadata: 2% of 1629 keys covered
No location, by source group:
HardwareSetting.Block_Widefocal: 1089HardwareSetting.CameraSettingDefinition: 351WidefocalExperimentSettings.SampleData: 71InScanProcessing.CameraLane0: 21ImageDescription.Channels: 9ViewerScaling.ChannelScalingInfo[]: 5ImageDescription.Dimensions: 5TileScanInfo.Tile: 4Coordinate.Coordinate[]: 2path: 1- and 42 more
Out of scope, not acquisition metadata (scripts/out_of_scope.json):
software state: 276file: 75display: 46processing: 43
lif_sp5_metadata: 3% of 747 keys covered
No location, by source group:
HardwareSettingList.ScannerSetting: 366HardwareSettingList.FilterSetting: 316ImageDescription.Channels: 9ViewerScaling.ChannelScalingInfo: 5ImageDescription.Dimensions: 5ChannelAttachment.Band: 2Coordinate.Coordinate[]: 2path: 1UniqueID: 1PreviewMarker.Name: 1- and 14 more
Out of scope, not acquisition metadata (scripts/out_of_scope.json):
file: 466display: 33
lif_tilescan_metadata: 6% of 638 keys covered
No location, by source group:
HardwareSetting.LDM_Block_Sequential: 315HardwareSetting.ConfocalSettingDefinition: 219ImageDescription.Channels: 9TileScanInfo.Tile[]: 5ViewerScaling.ChannelScalingInfo[]: 5ImageDescription.Dimensions: 5Coordinate.Coordinate[]: 2path: 1UniqueID: 1PreviewMarker.Name: 1- and 34 more
Out of scope, not acquisition metadata (scripts/out_of_scope.json):
software state: 81file: 53display: 17processing: 11
ome-tiff: 32% of 112 keys covered
Placed automatically, without a rule (worth checking that each means what the field does):
OME.Creator→CreatorOME.Instrument.ID→Instrument.IDOME.StructuredAnnotations.XMLAnnotation.ID→StructuredAnnotations.XMLAnnotation.IDOME.UUID→UUID
No such field, by the model path the keys were headed for (a group without their field, or a plain field given a record):
Image.Pixels: 3Image: 1
No location, by source group:
OME.StructuredAnnotations: 67
Out of scope, not acquisition metadata (scripts/out_of_scope.json):
file: 33
platy_tomography: 30% of 23 keys covered
No location, by source group:
SpimData.SequenceDescription: 9SpimData.ViewRegistrations: 4SpimData.BasePath: 2SpimData.version: 1
Out of scope, not acquisition metadata (scripts/out_of_scope.json):
file: 6
svs_metadata: 69% of 26 keys covered
No location, by source group:
Aperio Image Library v12.0: 1- ``: 1
28448x21839 [0,100 27888x21739] (240x240) J2K/KDU Q: 1Filename: 1User: 1DSR ID: 1DisplayColor: 1ICC Profile: 1
Out of scope, not acquisition metadata (scripts/out_of_scope.json):
file: 6display: 1
TFS Phenom Pharos: 50% of 105 keys covered
Placed automatically, without a rule (worth checking that each means what the field does):
SamplesPerPixel→Image.Pixels.Channel.SamplesPerPixel
No such field, by the model path the keys were headed for (a group without their field, or a plain field given a record):
Image.BeamScanSettings: 19GenericDetector: 16XResolution: 1YResolution: 1Instrument.Vacuum: 1Instrument: 1AcquisitionSoftware: 1
No location, by source group:
FEI_TITAN.FeiImage: 5ImageWidth: 1ImageLength: 1BitsPerSample: 1PhotometricInterpretation: 1ResolutionUnit: 1
Out of scope, not acquisition metadata (scripts/out_of_scope.json):
file: 6display: 4
TFS TALOSF: 17% of 593 keys covered
Placed automatically, without a rule (worth checking that each means what the field does):
Instrument.ComputerName→Instrument.ComputerNameInstrument.Manufacturer→Instrument.Manufacturer
No such field, by the model path the keys were headed for (a group without their field, or a plain field given a record):
OME.Operations: 333OME.CustomProperties: 59GenericDetector: 47Image.ElectronOpticsSettings: 13OME.Features: 10Image.BinaryResult: 6Image.BeamScanSettings: 5Image.ElectronOpticsSettings.Aperture: 4Instrument: 3
No location, by source group:
DetectorMetadata.CollectionAngleRange: 2Instrument.InstrumentClass: 1Acquisition.AcquisitionDatetime: 1Optics.StemFocus: 1EnergyFilter.EntranceApertureType: 1GasInjectionSystems: 1DetectorMetadata.DetectorName: 1DetectorMetadata.DetectorType: 1DetectorMetadata.Inserted: 1DetectorMetadata.Enabled: 1- and 2 more
Out of scope, not acquisition metadata (scripts/out_of_scope.json):
processing: 342file: 37
TFS TALOSF 2: 15% of 798 keys covered
Placed automatically, without a rule (worth checking that each means what the field does):
Instrument.ComputerName→Instrument.ComputerNameInstrument.Manufacturer→Instrument.Manufacturer
No such field, by the model path the keys were headed for (a group without their field, or a plain field given a record):
OME.Operations: 564OME.CustomProperties: 36GenericDetector: 29OME.Features: 14Image.ElectronOpticsSettings: 13Image.BeamScanSettings: 5Image.BinaryResult: 5Image.ElectronOpticsSettings.Aperture: 4Instrument: 3
No location, by source group:
Instrument.InstrumentClass: 1Acquisition.AcquisitionDatetime: 1Optics.StemFocus: 1EnergyFilter.EntranceApertureType: 1Sample: 1GasInjectionSystems: 1DetectorMetadata: 1
Out of scope, not acquisition metadata (scripts/out_of_scope.json):
processing: 577file: 25
Zeiss Supra55 Fibics ATLAS: 69% of 74 keys covered
Placed automatically, without a rule (worth checking that each means what the field does):
SamplesPerPixel→Image.Pixels.Channel.SamplesPerPixel
No such field, by the model path the keys were headed for (a group without their field, or a plain field given a record):
Image.BeamScanSettings: 5Image.Corrections: 4AcquisitionSoftware: 3Image: 1
No location, by source group:
FibicsXML.Fibics: 1ImageWidth: 1ImageLength: 1BitsPerSample: 1PhotometricInterpretation: 1Orientation: 1ResolutionUnit: 1SampleFormat: 1
Out of scope, not acquisition metadata (scripts/out_of_scope.json):
file: 7
Improving the fit¶
Each category not covered points to its own remedy:
- No location, the source groups listed per example: a value the model has a field for needs a rule taking it there; a common value the model has no place for needs a field, added to the extension where the model's structure has one for it. The rules come first.
- No such field, the model paths listed per example: the group is there, so the field is what is missing - a new field in the extension, or a rule sending the value to the field the group has under another name.
- Does not fit: the rule is right, the value's form is not, such as a unit the units schema does not list, or a date the field cannot parse.
An automatic match is taken on the path alone, so each is listed per
example to be checked: a source's Rows matches Plate.Rows, the rows of a
well plate, where a DICOM file means the image's height in pixels. A rule for
the source key overrides the match.
The fields filled are counted as LiMi's or the extension's, a field counting as extension as soon as its path runs through a class or slot LiMi does not have, as on the model browser.
Keeping this page in sync¶
The tables are computed when the site is built, by the MkDocs hook
scripts/docs_data.py (with scripts/model_fit.py), from the datasets in
export/; the tests keep those up to date with the examples, the rules and
the model. python scripts/model_fit.py prints the same tables.
The numbers come from one function, reused by the page, the script and the
tests: analyse(dataset, metadata) in scripts/model_fit.py returns the
statistics of one conversion as a dict (kept, traced, coverage by keys and by
values, the counts per category, the fields filled, and what explains the
rest). analyse_metadata(metadata) gives the same for a source dict that is
not exported yet, converting and exporting it in memory, and
analyse_examples() gives them for every example:
from model_fit import analyse_metadata
stats = analyse_metadata(metadata, 'my file')
stats['kept'], stats['traced'] # 1.0 and 1.0: nothing lost or made up
stats['coverage'] # {'keys': 0.57, 'values': 0.57}