Back to home page

EIC code displayed by LXR

 
 

    


Warning, /firebird/packages/firebird-core/src/model/event-piece.ts is written in an unsupported language. File is not indexed.

0001 /**
0002  * One reference from an entity into another piece: the declaring column,
0003  * the target piece name (from the piece `refs` declaration) and the target
0004  * entity index (entity id ≡ array index; -1 never appears here — refs that
0005  * hold -1 are "no reference" and are not reported).
0006  */
0007 export interface EntityRefLink {
0008   column: string;
0009   targetPiece: string;
0010   targetIndex: number;
0011 }
0012 
0013 /**
0014  * The EventPiece class is an abstract base class for all event components.
0015  * A "piece" is one named block of typed entity data inside an event —
0016  * a hits collection, a set of trajectories, a custom extension type.
0017  */
0018 export abstract class EventPiece {
0019 
0020   /**
0021    * The name of the piece, unique within its event. Shown in UI menus and
0022    * targeted by `refs` declarations of other pieces.
0023    */
0024   name: string;
0025 
0026   /**
0027    * The type of the piece, used to identify the piece class
0028    * and facilitate deserialization and factory lookup.
0029    */
0030   type: string;
0031 
0032   /**
0033    * An optional value indicating the origin of the piece,
0034    * such as the original EDM4EIC/EDM4HEP/C++ data type from which it was derived.
0035    */
0036   origin?: any;
0037 
0038   /**
0039    * The constructor is protected to prevent direct instantiation of the abstract class.
0040    * Only derived classes can call this constructor when they implement their own constructors.
0041    *
0042    * @param name - The name of the piece.
0043    * @param type - The type of the piece.
0044    * @param origin - Optional origin of the piece.
0045    */
0046   protected constructor(name: string, type: string, origin?: any) {
0047     this.name = name;
0048     this.type = type;
0049     this.origin = origin;
0050   }
0051 
0052   /**
0053    * Serializes the piece into a JSON-compatible object following the
0054    * Data Exchange format (a DEX v1 piece object).
0055    */
0056   abstract toDexObject(): any;
0057 
0058   // -------------------------------------------------------------------------
0059   // Entity introspection — powers model-oriented UI (the model tree panel)
0060   // without UI code knowing concrete piece classes. Entity id ≡ array index.
0061   // -------------------------------------------------------------------------
0062 
0063   /** Number of entities in this piece. Pieces with a `count` field report it. */
0064   get entityCount(): number {
0065     const count = (this as { count?: unknown }).count;
0066     return typeof count === 'number' ? count : 0;
0067   }
0068 
0069   /**
0070    * A short human-readable label for one entity. The default is the index;
0071    * pieces with meaningful columns (pdg, time, energy) override this.
0072    */
0073   entityLabel(entityIndex: number): string {
0074     return `#${entityIndex}`;
0075   }
0076 
0077   /**
0078    * The outgoing references of one entity, resolved from the piece's `refs`
0079    * declaration: which column points at which entity of which piece.
0080    * Values of -1 mean "no reference" and are not reported.
0081    */
0082   entityRefs(entityIndex: number): EntityRefLink[] {
0083     return [];
0084   }
0085 
0086   /** min and max time of the EventPiece
0087    * null means the piece doesn't need time and shows as is
0088    *
0089    * @returns [min, max] range of times or null if it is not available for the piece
0090    */
0091   abstract get timeRange(): [number, number] | null;
0092 }
0093 
0094 /**
0095  * The EventPieceFactory interface defines the structure for factory classes
0096  * that are responsible for creating instances of EventPiece subclasses.
0097  */
0098 export interface EventPieceFactory {
0099 
0100   /**
0101    * The type of the piece that this factory creates.
0102    * This should match the `type` property of the pieces it creates.
0103    */
0104   type: string;
0105 
0106   /**
0107    * Method to create an instance of an EventPiece subclass from a deserialized
0108    * DEX v1 piece object (typically parsed from JSON).
0109    *
0110    * @param obj - The deserialized piece object.
0111    * @returns An instance of an EventPiece subclass.
0112    */
0113   fromDexObject(obj: any): EventPiece;
0114 }
0115 
0116 /**
0117  * The pieceRegistry is a mapping from piece type strings to their corresponding factories.
0118  * It is used to look up the appropriate factory when deserializing pieces from JSON data.
0119  * This registry enables the system to support multiple piece types dynamically.
0120  */
0121 const pieceRegistry: { [type: string]: EventPieceFactory } = {};
0122 
0123 /**
0124  * Registers a new piece factory in the registry.
0125  * This allows the factory to be used during deserialization to create instances
0126  * of the piece it represents.
0127  *
0128  * @param factory - The factory to register.
0129  */
0130 export function registerEventPieceFactory(factory: EventPieceFactory): void {
0131   pieceRegistry[factory.type] = factory;
0132 }
0133 
0134 /**
0135  * Retrieves a piece factory from the registry based on the piece type.
0136  *
0137  * @param type - The type of the piece.
0138  * @returns The corresponding EventPieceFactory, or undefined if not found.
0139  */
0140 export function getEventPieceFactory(type: string): EventPieceFactory | undefined {
0141   return pieceRegistry[type];
0142 }
0143 
0144 /**
0145  * Resets the piece registry.
0146  * This function is intended for internal use during testing.
0147  *
0148  * @internal
0149  */
0150 export function _resetEventPieceRegistry(): void {
0151   for (const key in pieceRegistry) {
0152     delete pieceRegistry[key];
0153   }
0154 }
0155 
0156 // ---------------------------------------------------------------------------
0157 // Column reading helpers for piece factories.
0158 //
0159 // DEX v1 stores entity data as parallel arrays: a scalar column holds `count`
0160 // values, a fixed-width vector column (like an xyz position) holds
0161 // `stride * count` values flattened. Entity id IS the array index — malformed
0162 // files fail loudly here instead of producing silently shifted data (v1 files
0163 // are cheap to regenerate).
0164 // ---------------------------------------------------------------------------
0165 
0166 /** Reads the piece `count` field; throws with the piece name on bad data. */
0167 export function readPieceCount(obj: any): number {
0168   const count = obj?.['count'];
0169   if (typeof count !== 'number' || !Number.isInteger(count) || count < 0) {
0170     throw new Error(`DEX piece '${obj?.['name']}': "count" must be a non-negative integer, got ${count}`);
0171   }
0172   return count;
0173 }
0174 
0175 /**
0176  * Reads a required numeric column into a Float32Array (bulk copy, no
0177  * per-entity objects). `stride` is values per entity (1 = scalar, 3 = xyz).
0178  */
0179 export function readNumberColumn(obj: any, columnName: string, count: number, stride: number = 1): Float32Array {
0180   const column = readOptionalNumberColumn(obj, columnName, count, stride);
0181   if (column === null) {
0182     throw new Error(`DEX piece '${obj?.['name']}': required column "${columnName}" is missing`);
0183   }
0184   return column;
0185 }
0186 
0187 /** Same as readNumberColumn but returns null when the writer omitted the column. */
0188 export function readOptionalNumberColumn(obj: any, columnName: string, count: number, stride: number = 1): Float32Array | null {
0189   const column = obj?.['columns']?.[columnName];
0190   if (column === undefined || column === null) {
0191     return null;
0192   }
0193   if (!Array.isArray(column)) {
0194     throw new Error(`DEX piece '${obj?.['name']}': column "${columnName}" is not an array`);
0195   }
0196   if (column.length !== stride * count) {
0197     throw new Error(`DEX piece '${obj?.['name']}': column "${columnName}" has ${column.length} values, ` +
0198       `expected ${stride}*count=${stride * count} (entity id must equal array index)`);
0199   }
0200   return Float32Array.from(column);
0201 }