Skip to content

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: 11
  • Experimenter: 5
  • MechanicalStage: 2
  • Image.BeamScanSettings: 1
  • Instrument: 1

No location, by source group:

  • FEI_HELIOS.TiltCorrect: 5
  • FEI_HELIOS.Other: 1
  • ImageWidth: 1
  • ImageLength: 1
  • BitsPerSample: 1
  • PhotometricInterpretation: 1
  • ResolutionUnit: 1

Out of scope, not acquisition metadata (scripts/out_of_scope.json):

  • display: 4
  • file: 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: 11
  • Experimenter: 5
  • MechanicalStage: 2
  • Image.BeamScanSettings: 1
  • Instrument: 1

No location, by source group:

  • FEI_HELIOS.TiltCorrect: 5
  • FEI_HELIOS.Other: 1
  • ImageWidth: 1
  • ImageLength: 1
  • BitsPerSample: 1
  • PhotometricInterpretation: 1
  • ResolutionUnit: 1

Out of scope, not acquisition metadata (scripts/out_of_scope.json):

  • display: 4
  • file: 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: 1
  • YResolution: 1

No location, by source group:

  • ImageWidth: 1
  • ImageLength: 1
  • BitsPerSample: 1
  • PhotometricInterpretation: 1
  • ResolutionUnit: 1
  • DateTime: 1
  • SampleFormat: 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.AcquisitionDate
  • SamplesPerPixel → Image.Pixels.Channel.SamplesPerPixel

No location, by source group:

  • SpecificCharacterSet: 1
  • ImageType[]: 1
  • InstanceCreationDate: 1
  • InstanceCreationTime: 1
  • SOPClassUID: 1
  • StudyDate: 1
  • SeriesDate: 1
  • ContentDate: 1
  • AcquisitionDateTime: 1
  • StudyTime: 1
  • and 63 more

Out of scope, not acquisition metadata (scripts/out_of_scope.json):

  • file: 25
  • patient and administrative: 24
  • display: 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.AcquisitionDate
  • SamplesPerPixel → Image.Pixels.Channel.SamplesPerPixel

No location, by source group:

  • ContributingEquipmentSequence[].PurposeOfReferenceCodeSequence[]: 3
  • ImageType[]: 1
  • InstanceCreationDate: 1
  • InstanceCreationTime: 1
  • SOPClassUID: 1
  • StudyDate: 1
  • SeriesDate: 1
  • ContentDate: 1
  • StudyTime: 1
  • SeriesTime: 1
  • and 67 more

Out of scope, not acquisition metadata (scripts/out_of_scope.json):

  • file: 24
  • patient and administrative: 18
  • display: 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.AcquisitionDate
  • SamplesPerPixel → Image.Pixels.Channel.SamplesPerPixel

No location, by source group:

  • ContributingEquipmentSequence[].PurposeOfReferenceCodeSequence[]: 3
  • ImageType[]: 1
  • InstanceCreationDate: 1
  • InstanceCreationTime: 1
  • SOPClassUID: 1
  • StudyDate: 1
  • SeriesDate: 1
  • ContentDate: 1
  • StudyTime: 1
  • SeriesTime: 1
  • and 45 more

Out of scope, not acquisition metadata (scripts/out_of_scope.json):

  • file: 20
  • patient and administrative: 16
  • display: 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: 1
  • YResolution: 1

No location, by source group:

  • ExifVersion: 1
  • DateTimeDigitized: 1
  • MeteringMode: 1
  • FlashpixVersion: 1
  • ColorSpace: 1
  • ExposureMode: 1
  • ImageWidth: 1
  • ImageLength: 1
  • BitsPerSample[]: 1
  • PhotometricInterpretation: 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: 16
  • ImageDescription.Channels: 9
  • HardwareSetting.Laser: 8
  • ImageDescription.Dimensions: 5
  • CustomData.UserInfo: 3
  • CustomData.ExperimentInfo: 2
  • path: 1
  • UniqueID: 1
  • CustomData.Version: 1
  • CustomData.Name: 1
  • and 3 more

Out of scope, not acquisition metadata (scripts/out_of_scope.json):

  • display: 2
  • file: 1
lif_metadata: 2% of 1629 keys covered

No location, by source group:

  • HardwareSetting.Block_Widefocal: 1089
  • HardwareSetting.CameraSettingDefinition: 351
  • WidefocalExperimentSettings.SampleData: 71
  • InScanProcessing.CameraLane0: 21
  • ImageDescription.Channels: 9
  • ViewerScaling.ChannelScalingInfo[]: 5
  • ImageDescription.Dimensions: 5
  • TileScanInfo.Tile: 4
  • Coordinate.Coordinate[]: 2
  • path: 1
  • and 42 more

Out of scope, not acquisition metadata (scripts/out_of_scope.json):

  • software state: 276
  • file: 75
  • display: 46
  • processing: 43
lif_sp5_metadata: 3% of 747 keys covered

No location, by source group:

  • HardwareSettingList.ScannerSetting: 366
  • HardwareSettingList.FilterSetting: 316
  • ImageDescription.Channels: 9
  • ViewerScaling.ChannelScalingInfo: 5
  • ImageDescription.Dimensions: 5
  • ChannelAttachment.Band: 2
  • Coordinate.Coordinate[]: 2
  • path: 1
  • UniqueID: 1
  • PreviewMarker.Name: 1
  • and 14 more

Out of scope, not acquisition metadata (scripts/out_of_scope.json):

  • file: 466
  • display: 33
lif_tilescan_metadata: 6% of 638 keys covered

No location, by source group:

  • HardwareSetting.LDM_Block_Sequential: 315
  • HardwareSetting.ConfocalSettingDefinition: 219
  • ImageDescription.Channels: 9
  • TileScanInfo.Tile[]: 5
  • ViewerScaling.ChannelScalingInfo[]: 5
  • ImageDescription.Dimensions: 5
  • Coordinate.Coordinate[]: 2
  • path: 1
  • UniqueID: 1
  • PreviewMarker.Name: 1
  • and 34 more

Out of scope, not acquisition metadata (scripts/out_of_scope.json):

  • software state: 81
  • file: 53
  • display: 17
  • processing: 11
ome-tiff: 32% of 112 keys covered

Placed automatically, without a rule (worth checking that each means what the field does):

  • OME.Creator → Creator
  • OME.Instrument.ID → Instrument.ID
  • OME.StructuredAnnotations.XMLAnnotation.ID → StructuredAnnotations.XMLAnnotation.ID
  • OME.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: 3
  • Image: 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: 9
  • SpimData.ViewRegistrations: 4
  • SpimData.BasePath: 2
  • SpimData.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: 1
  • Filename: 1
  • User: 1
  • DSR ID: 1
  • DisplayColor: 1
  • ICC Profile: 1

Out of scope, not acquisition metadata (scripts/out_of_scope.json):

  • file: 6
  • display: 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: 19
  • GenericDetector: 16
  • XResolution: 1
  • YResolution: 1
  • Instrument.Vacuum: 1
  • Instrument: 1
  • AcquisitionSoftware: 1

No location, by source group:

  • FEI_TITAN.FeiImage: 5
  • ImageWidth: 1
  • ImageLength: 1
  • BitsPerSample: 1
  • PhotometricInterpretation: 1
  • ResolutionUnit: 1

Out of scope, not acquisition metadata (scripts/out_of_scope.json):

  • file: 6
  • display: 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.ComputerName
  • Instrument.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: 333
  • OME.CustomProperties: 59
  • GenericDetector: 47
  • Image.ElectronOpticsSettings: 13
  • OME.Features: 10
  • Image.BinaryResult: 6
  • Image.BeamScanSettings: 5
  • Image.ElectronOpticsSettings.Aperture: 4
  • Instrument: 3

No location, by source group:

  • DetectorMetadata.CollectionAngleRange: 2
  • Instrument.InstrumentClass: 1
  • Acquisition.AcquisitionDatetime: 1
  • Optics.StemFocus: 1
  • EnergyFilter.EntranceApertureType: 1
  • GasInjectionSystems: 1
  • DetectorMetadata.DetectorName: 1
  • DetectorMetadata.DetectorType: 1
  • DetectorMetadata.Inserted: 1
  • DetectorMetadata.Enabled: 1
  • and 2 more

Out of scope, not acquisition metadata (scripts/out_of_scope.json):

  • processing: 342
  • file: 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.ComputerName
  • Instrument.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: 564
  • OME.CustomProperties: 36
  • GenericDetector: 29
  • OME.Features: 14
  • Image.ElectronOpticsSettings: 13
  • Image.BeamScanSettings: 5
  • Image.BinaryResult: 5
  • Image.ElectronOpticsSettings.Aperture: 4
  • Instrument: 3

No location, by source group:

  • Instrument.InstrumentClass: 1
  • Acquisition.AcquisitionDatetime: 1
  • Optics.StemFocus: 1
  • EnergyFilter.EntranceApertureType: 1
  • Sample: 1
  • GasInjectionSystems: 1
  • DetectorMetadata: 1

Out of scope, not acquisition metadata (scripts/out_of_scope.json):

  • processing: 577
  • file: 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: 5
  • Image.Corrections: 4
  • AcquisitionSoftware: 3
  • Image: 1

No location, by source group:

  • FibicsXML.Fibics: 1
  • ImageWidth: 1
  • ImageLength: 1
  • BitsPerSample: 1
  • PhotometricInterpretation: 1
  • Orientation: 1
  • ResolutionUnit: 1
  • SampleFormat: 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}