linked-rolls 0.65.0 → 0.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,7 +5,7 @@ import { TrackCalibration } from "./TrackCalibration.js";
5
5
  import { AnyFeature, FeatureOrPatch, HorizontalSpan, Patch } from "./Feature.js";
6
6
  import { ActorAssignment, DateAssignment, ObjectAssumption, ReferenceAssumption } from "./Assumption.js";
7
7
  import { WithId, WithType } from "../shared/utils.js";
8
- import { Agent, Concept } from "./Agent.js";
8
+ import { Agent, Concept, Software } from "./Agent.js";
9
9
  import { FeatureSource } from "./FeatureSource.js";
10
10
  import { Measure, Millimeters, Percent, Quantity, Track } from "./Quantity.js";
11
11
  import { Perforator } from "./Perforator.js";
@@ -161,6 +161,28 @@ export interface Alignment {
161
161
  date: Date;
162
162
  };
163
163
  }
164
+ /**
165
+ * The width and length of a roll copy's paper, as they were measured on
166
+ * it or on its scan.
167
+ * @see crm:E54 Dimension
168
+ */
169
+ export interface RollDimensions {
170
+ /**
171
+ * The width of the roll.
172
+ * @see reo:width
173
+ */
174
+ width: Millimeters;
175
+ /**
176
+ * The total height (length) of the roll.
177
+ * @see reo:height
178
+ */
179
+ height: Millimeters;
180
+ /**
181
+ * The unit of measurement.
182
+ * @see crm:P91 has unit
183
+ */
184
+ unit: 'mm';
185
+ }
164
186
  /** The margins on the treble and bass sides of the roll, in the unit the scan was measured in. */
165
187
  export interface Margins<U extends 'px' | 'mm'> {
166
188
  treble: Quantity<U>;
@@ -209,11 +231,14 @@ export interface ProductionEvent {
209
231
  */
210
232
  system?: Concept;
211
233
  /**
212
- * The paper speed the copy was cut for. A copy cut from the same
213
- * master for another speed comes out longer or shorter than the
214
- * roll it is aligned with by the ratio of the speeds. The alignment
215
- * measures that ratio far more closely than a label states a speed,
216
- * so the speed is held against what the alignments give
234
+ * The paper speed the copy was cut for, as the speed at the
235
+ * beginning of the roll: a tempo marking states it so, and the
236
+ * take-up spool accelerates from there. A performance of a version
237
+ * the copy bears witness to starts at it (`paperSpeedOf`). A copy cut
238
+ * from the same master for another speed comes out longer or shorter
239
+ * than the roll it is aligned with by the ratio of the speeds. The
240
+ * alignment measures that ratio far more closely than a label states
241
+ * a speed, so the speed is held against what the alignments give
217
242
  * (`alignmentProblems`) rather than used to find it.
218
243
  * @see reo:paperSpeed
219
244
  */
@@ -307,11 +332,14 @@ export type Modification = Partial<{
307
332
  */
308
333
  export interface RollCopy extends WithType<'RollCopy'>, WithId {
309
334
  /**
310
- * Physical measurements of this roll copy, including
311
- * dimensions, hole separation, margins, the alignment onto the
312
- * edition's axis, and information about the measuring software. What the
313
- * perforations tell about the machine that cut them is stated
314
- * with the production.
335
+ * Physical measurements of this roll copy: its dimensions, hole
336
+ * separation and margins, the resolution of its scan, and how it
337
+ * lies on the edition's axis. What the perforations tell about the
338
+ * machine that cut them is stated with the production.
339
+ *
340
+ * A value the edition exports is an object assumption, so that it
341
+ * can say what took it: a measurement naming the program and its
342
+ * version, the scan or analysis it was taken on, and the day.
315
343
  * @see crm:P39i was measured by
316
344
  */
317
345
  measurements: Partial<{
@@ -319,23 +347,7 @@ export interface RollCopy extends WithType<'RollCopy'>, WithId {
319
347
  * The physical dimensions of the roll.
320
348
  * @see reo:dimensions
321
349
  */
322
- dimensions: {
323
- /**
324
- * The width of the roll.
325
- * @see reo:width
326
- */
327
- width: Millimeters;
328
- /**
329
- * The total height (length) of the roll.
330
- * @see reo:height
331
- */
332
- height: Millimeters;
333
- /**
334
- * The unit of measurement.
335
- * @see crm:P91 has unit
336
- */
337
- unit: 'mm';
338
- };
350
+ dimensions: ObjectAssumption<RollDimensions>;
339
351
  /**
340
352
  * The distance across the roll from the centre of one track to
341
353
  * the next, the track pitch or Teilung, in the unit the scan was
@@ -344,7 +356,7 @@ export interface RollCopy extends WithType<'RollCopy'>, WithId {
344
356
  * along the roll.
345
357
  * @see reo:holeSeparation
346
358
  */
347
- holeSeparation: Measure<'px'> | Measure<'mm'>;
359
+ holeSeparation: ObjectAssumption<Measure<'px'> | Measure<'mm'>>;
348
360
  /**
349
361
  * The margins on the treble and bass sides of the roll.
350
362
  * Not exported to RDF.
@@ -389,35 +401,13 @@ export interface RollCopy extends WithType<'RollCopy'>, WithId {
389
401
  * files do not state.
390
402
  * @see reo:scanResolution
391
403
  */
392
- scanResolution: Measure<'px/in'>;
404
+ scanResolution: ObjectAssumption<Measure<'px/in'>>;
393
405
  /**
394
406
  * Relates this copy's scan to the tracker bar: how the scanning
395
407
  * software's hole numbering was shifted onto the bar, and where
396
408
  * the track grid sits in the image. Not exported to RDF.
397
409
  */
398
410
  trackCalibration: TrackCalibration;
399
- /**
400
- * Information about the software used to take the measurements.
401
- * @see crmdig:L23 used software or firmware
402
- */
403
- measuredBy: {
404
- /**
405
- * The name of the measurement software.
406
- * @see rdfs:label
407
- */
408
- software: string;
409
- /**
410
- * The version of the measurement software.
411
- * @see owl:versionInfo
412
- */
413
- version: string;
414
- /**
415
- * The date on which the measurements were taken.
416
- * @format date
417
- * @see dcterms:date
418
- */
419
- date: Date;
420
- };
421
411
  }>;
422
412
  /**
423
413
  * The production event that created this roll copy.
@@ -496,6 +486,8 @@ export declare const statesNothing: (modification: Modification) => boolean;
496
486
  export declare const featuresByAct: (copy: Pick<RollCopy, 'production' | 'modifications'>) => FeatureOrPatch[][];
497
487
  /** Every feature the copy states at a place of its own, whichever act made it. */
498
488
  export declare const featuresOf: (copy: Pick<RollCopy, 'production' | 'modifications'>) => FeatureOrPatch[];
489
+ /** The programs the measurements of a copy name as having taken them, each once, as far as they name any. */
490
+ export declare const measuringSoftwareOf: (copy: Pick<RollCopy, 'measurements'>) => Software[];
499
491
  /** Whether the condition is the stretch or shrinkage of the paper, as measured on the copy. */
500
492
  export declare const isPaperStretch: (condition: RollConditionAssignment) => condition is ObjectAssumption<PaperStretch>;
501
493
  /** What the copy's paper was measured to have done, where anything was measured. */
@@ -35,6 +35,16 @@ export const statesNothing = (modification) => modification.type === 'Removal' ?
35
35
  export const featuresByAct = (copy) => [copy.production?.produced ?? [], ...copy.modifications.map(featuresMadeBy)];
36
36
  /** Every feature the copy states at a place of its own, whichever act made it. */
37
37
  export const featuresOf = (copy) => featuresByAct(copy).flat();
38
+ /** The measurements of a copy the edition exports, each of which can say what took it. */
39
+ const exportedMeasurementsOf = (copy) => [copy.measurements.dimensions, copy.measurements.holeSeparation, copy.measurements.scanResolution]
40
+ .filter(value => value !== undefined);
41
+ /** The programs the measurements of a copy name as having taken them, each once, as far as they name any. */
42
+ export const measuringSoftwareOf = (copy) => {
43
+ const named = exportedMeasurementsOf(copy)
44
+ .flatMap(value => value['@annotation']?.belief.reasons ?? [])
45
+ .flatMap(reason => reason.type === 'measurement' ? reason.software ?? [] : []);
46
+ return [...new Map(named.map(software => [`${software.name}\u0000${software.version ?? ''}`, software])).values()];
47
+ };
38
48
  /** Whether the condition is the stretch or shrinkage of the paper, as measured on the copy. */
39
49
  export const isPaperStretch = (condition) => condition.conditionType === 'paper-stretch';
40
50
  /** What the copy's paper was measured to have done, where anything was measured. */
@@ -33,6 +33,23 @@ export type Derivation = ReferenceAssumption & {
33
33
  };
34
34
  /** The tolerance the derivation was collated at, or the default where it states none. */
35
35
  export declare const collationToleranceOf: (derivation: Readonly<Derivation>) => CollationTolerance;
36
+ /**
37
+ * How long a version's paper runs for a length of the paper of the
38
+ * version it derives from: about 0.77 for a Licensee or green re-cut of
39
+ * a red roll, cut for a slower paper speed.
40
+ * @see crm:E54 Dimension
41
+ */
42
+ export interface LengthRatio {
43
+ /**
44
+ * @see crm:P90 has value
45
+ */
46
+ value: number;
47
+ /**
48
+ * The standard uncertainty of the value, one standard deviation.
49
+ * @see reo:uncertainty
50
+ */
51
+ uncertainty?: number;
52
+ }
36
53
  /**
37
54
  * How a version was made, where that is known and worth stating.
38
55
  *
@@ -63,6 +80,19 @@ export interface VersionCreation {
63
80
  * @see crm:P33 used specific technique
64
81
  */
65
82
  procedure?: Concept;
83
+ /**
84
+ * How long the act made the version's paper for a length of the
85
+ * paper of the version it derives from. A re-cut for a system whose
86
+ * paper runs slower comes out shorter by the ratio of the speeds,
87
+ * and the alignments of the copies measure that ratio more closely
88
+ * than any label states a speed (`lengthRatioOf`). It is stated
89
+ * where the edition holds to it, as a measurement naming the copies
90
+ * it used and the program that found it, so that it can serve as a
91
+ * premise. A speed follows from it only together with a premise
92
+ * about the speed of the other version.
93
+ * @see reo:lengthRatio
94
+ */
95
+ lengthRatio?: ObjectAssumption<LengthRatio>;
66
96
  }
67
97
  /**
68
98
  * A version is defined by the sum of edits applied to the version it is
@@ -1,5 +1,6 @@
1
1
  import { v4 } from "uuid";
2
2
  import { AtonParser } from "./AtonParser.js";
3
+ import { assignDate } from "../model/Assumption.js";
3
4
  import { systemOf } from "../systems/TrackerBar.js";
4
5
  import { welteT100 } from "../systems/welteT100/bar.js";
5
6
  import { inMillimeters, mean, mm, pixelsPerInch, px, subtract, track } from "../model/Quantity.js";
@@ -120,19 +121,24 @@ const tearsIn = (tears, dpi, depictionOf) => {
120
121
  .sort((a, b) => a.horizontal.from - b.horizontal.from);
121
122
  };
122
123
  /**
123
- * The software behind an analysis and when it was run, as the
124
- * analysis file states them.
124
+ * The software behind an analysis and the day it was run, as the
125
+ * analysis file states them: the measurement the dimensions and the
126
+ * hole separation it gives rest on.
125
127
  */
126
- const measuredByOf = (rollinfo) => {
128
+ const measurementOf = (rollinfo) => {
127
129
  const date = new Date(rollinfo.ANALYSIS_DATE);
128
130
  if (!rollinfo.HOLE_SOFTWARE || isNaN(date.getTime()))
129
131
  return undefined;
130
132
  return {
131
- software: rollinfo.HOLE_SOFTWARE,
132
- version: rollinfo.SOFTWARE_DATE ?? '',
133
- date
133
+ type: 'measurement',
134
+ software: [{ name: rollinfo.HOLE_SOFTWARE, ...(rollinfo.SOFTWARE_DATE && { version: rollinfo.SOFTWARE_DATE }) }],
135
+ date: assignDate(new Date(date.getFullYear(), date.getMonth(), date.getDate()))
134
136
  };
135
137
  };
138
+ /** The value held on the strength of the measurement, where the file names one, and plainly where it does not. */
139
+ const takenBy = (measurement) => (value) => measurement
140
+ ? { ...value, '@annotation': { id: v4(), belief: { type: 'belief', id: v4(), certainty: 'true', reasons: [measurement] } } }
141
+ : value;
136
142
  export function readFromStanfordAton(atonString, { trackShift, system = welteT100, scan } = {}) {
137
143
  const parser = new AtonParser();
138
144
  const json = parser.parse(atonString);
@@ -141,7 +147,7 @@ export function readFromStanfordAton(atonString, { trackShift, system = welteT10
141
147
  const stanford = druid ? stanfordScan(druid) : undefined;
142
148
  const separation = readPx(json.ROLLINFO.HOLE_SEPARATION);
143
149
  const dpi = parseFloat(json.ROLLINFO.LENGTH_DPI);
144
- const measuredBy = measuredByOf(json.ROLLINFO);
150
+ const measured = takenBy(measurementOf(json.ROLLINFO));
145
151
  const shift = trackShift ?? calibrationShiftIn(holes, system);
146
152
  const calibration = {
147
153
  unit: 'px',
@@ -196,15 +202,15 @@ export function readFromStanfordAton(atonString, { trackShift, system = welteT10
196
202
  modifications: [],
197
203
  ...((scan ?? stanford) && { scan: scan ?? stanford?.scan }),
198
204
  measurements: {
199
- dimensions: {
205
+ dimensions: measured({
200
206
  width: inMillimeters(readPx(json.ROLLINFO.ROLL_WIDTH), dpi),
201
207
  height: inMillimeters(readPx(json.ROLLINFO.IMAGE_LENGTH), dpi),
202
208
  unit: 'mm'
203
- },
204
- holeSeparation: {
209
+ }),
210
+ holeSeparation: measured({
205
211
  value: separation,
206
212
  unit: 'px'
207
- },
213
+ }),
208
214
  margins: {
209
215
  treble: readPx(json.ROLLINFO.HARD_MARGIN_TREBLE),
210
216
  bass: readPx(json.ROLLINFO.HARD_MARGIN_BASS),
@@ -213,8 +219,7 @@ export function readFromStanfordAton(atonString, { trackShift, system = welteT10
213
219
  ...(Number.isFinite(dpi) && {
214
220
  scanResolution: { value: pixelsPerInch(dpi), unit: 'px/in' }
215
221
  }),
216
- trackCalibration: calibration,
217
- ...(measuredBy && { measuredBy })
222
+ trackCalibration: calibration
218
223
  }
219
224
  };
220
225
  }