Back to home page

EIC code displayed by LXR

 
 

    


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 }