Warning, /firebird/packages/firebird-core/src/model/box-hit.piece.ts is written in an unsupported language. File is not indexed.
0001 // box-hit.piece.ts
0002
0003 import {
0004 EventPiece,
0005 EventPieceFactory,
0006 readPieceCount,
0007 readNumberColumn,
0008 readOptionalNumberColumn,
0009 } from './event-piece';
0010
0011 /**
0012 * Box-shaped tracker hits stored in columns (DEX v1): parallel typed arrays,
0013 * hit id equals array index. There are no per-hit objects — painters read the
0014 * columns directly.
0015 *
0016 * DEX piece layout:
0017 *
0018 * {
0019 * "name": "BarrelHits", "type": "BoxHit", "version": "1.0",
0020 * "count": 2,
0021 * "columns": {
0022 * "pos": [x0,y0,z0, x1,y1,z1], // [mm] flat, 3 values per hit
0023 * "dim": [...], // [mm] box size, 3 values per hit
0024 * "time": [t0, t1], // [ns] optional
0025 * "timeError": [...], // [ns] optional
0026 * "edep": [...], // [GeV] optional
0027 * "edepError": [...] // [GeV] optional
0028 * }
0029 * }
0030 *
0031 * Optional columns are null when the writer omitted them (simulation output
0032 * has no error columns, for example).
0033 */
0034 export class BoxHitPiece extends EventPiece {
0035
0036 /** The static type identifier for the BoxHitPiece. */
0037 static type = 'BoxHit';
0038
0039 /** Number of hits. */
0040 count = 0;
0041
0042 /** Hit centers [mm]: flat x,y,z per hit, `3 * count` values. */
0043 pos: Float32Array = new Float32Array(0);
0044
0045 /** Box sizes [mm]: flat dx,dy,dz per hit, `3 * count` values. */
0046 dim: Float32Array = new Float32Array(0);
0047
0048 /** Hit times [ns], `count` values, or null when not written. */
0049 time: Float32Array | null = null;
0050
0051 /** Time errors [ns], `count` values, or null when not written. */
0052 timeError: Float32Array | null = null;
0053
0054 /** Energy deposits [GeV], `count` values, or null when not written. */
0055 edep: Float32Array | null = null;
0056
0057 /** Energy deposit errors [GeV], `count` values, or null when not written. */
0058 edepError: Float32Array | null = null;
0059
0060 constructor(name: string, origin?: any) {
0061 super(name, BoxHitPiece.type, origin);
0062 }
0063
0064 /** Label with the optional time and energy columns when the writer had them. */
0065 override entityLabel(hitIndex: number): string {
0066 let label = `#${hitIndex}`;
0067 if (this.time !== null) label += ` t=${this.time[hitIndex].toFixed(1)}`;
0068 if (this.edep !== null) label += ` edep=${this.edep[hitIndex].toExponential(1)}`;
0069 return label;
0070 }
0071
0072 /** Time range over the time column; null when the column is absent or empty. */
0073 override get timeRange(): [number, number] | null {
0074 if (this.time === null || this.count === 0) return null;
0075
0076 let minTime = this.time[0];
0077 let maxTime = this.time[0];
0078 for (let i = 1; i < this.count; i++) {
0079 const t = this.time[i];
0080 if (t < minTime) minTime = t;
0081 if (t > maxTime) maxTime = t;
0082 }
0083 return [minTime, maxTime];
0084 }
0085
0086 toDexObject(): any {
0087 const columns: any = {
0088 pos: Array.from(this.pos),
0089 dim: Array.from(this.dim),
0090 };
0091 if (this.time !== null) columns.time = Array.from(this.time);
0092 if (this.timeError !== null) columns.timeError = Array.from(this.timeError);
0093 if (this.edep !== null) columns.edep = Array.from(this.edep);
0094 if (this.edepError !== null) columns.edepError = Array.from(this.edepError);
0095
0096 const result: any = {
0097 name: this.name,
0098 type: this.type,
0099 version: '1.0',
0100 count: this.count,
0101 columns: columns,
0102 };
0103 if (this.origin !== undefined) result.origin = this.origin;
0104 return result;
0105 }
0106 }
0107
0108 /**
0109 * Factory for creating instances of BoxHitPiece from deserialized DEX data.
0110 * Column lengths are checked loudly — a malformed file throws instead of
0111 * rendering shifted hits.
0112 */
0113 export class BoxHitPieceFactory implements EventPieceFactory {
0114 /** The type of the piece that this factory creates. */
0115 type: string = BoxHitPiece.type;
0116
0117 fromDexObject(obj: any): BoxHitPiece {
0118 const result = new BoxHitPiece(obj['name'], obj['origin']);
0119 result.count = readPieceCount(obj);
0120 result.pos = readNumberColumn(obj, 'pos', result.count, 3);
0121 result.dim = readNumberColumn(obj, 'dim', result.count, 3);
0122 result.time = readOptionalNumberColumn(obj, 'time', result.count);
0123 result.timeError = readOptionalNumberColumn(obj, 'timeError', result.count);
0124 result.edep = readOptionalNumberColumn(obj, 'edep', result.count);
0125 result.edepError = readOptionalNumberColumn(obj, 'edepError', result.count);
0126 return result;
0127 }
0128 }