Warning, /firebird/docs/dex.md is written in an unsupported language. File is not indexed.
0001 # Firebird Data Exchange format
0002
0003 Data exchange is both JSON and Javascript object compatible.
0004
0005 It starts with (in this order) `"type":"firebird-dex-json"`.
0006 Then goes `version` and `origin` - any custom origin info and a list of entries. They are described below.
0007
0008 Here `event` may correspond to `event` in HENP data, while has more technical definition:
0009 data container for a time labeled data for particular time interval to be displayed.
0010
0011 ```json
0012 {
0013 "type":"firebird-dex-json",
0014 "version": "0.04",
0015 "origin": {"any custom origin info": "here"},
0016 "events": [
0017 event0, event1, ...
0018 ]
0019 }
0020 ```
0021
0022 - **version** - is JSON schema version
0023 - **origin** - designed for any general custom info such as original file name,
0024 timestamp, simulation software version, etc.
0025 - **events** - list of entries/events. The format is below.
0026
0027 ## Event format
0028
0029
0030 ```
0031 +------------------------------------------------+
0032 | Event |
0033 | |
0034 | +--------------------+ |
0035 | | Group | |
0036 | | ~name type~ | |
0037 | +--------------------+ |
0038 | |
0039 | +-------------------+ |
0040 | | hits a | +----------+ |
0041 | +-------------------+ | hits b | |
0042 | +----------+ |
0043 | +----------------------------------+ |
0044 | | trajectories c | |
0045 | +----------------------------------+ |
0046 | |
0047 +------------------------------------------------+
0048
0049 0------------------------------------------------> time
0050
0051
0052 ```
0053
0054 Event is an object with `id` and `groups` properties.
0055 By design groups represent different hits, tracks, vertices, collections, etc.
0056 While can be any arbitary data, that will be further rendered by the frontend.
0057
0058 ```json
0059 {
0060 "id": "Event number or string - unique name",
0061 "groups": [
0062
0063 ...
0064
0065 ]
0066 }
0067 ```
0068
0069 Requrired fields are `id` and `groups`. `id` must be unique across events in FDEX file.
0070
0071
0072 ## Group format
0073
0074 - `name`: unique string id
0075 - `type`: string with type (depends on what group will be used in the frontend to render it)
0076 - `origin`: optional dictionary with origin data info such as type of origin,
0077 e.g. "edm4eic::TrackerHitData", EDM collection name and so on
0078
0079 - all other fields defined by "type"
0080
0081 So far example of exchange format looks like (only required fields are used here):
0082
0083 ```json
0084 {
0085 "version": "0.04",
0086 "events": [
0087 {
0088 "id": "event 0",
0089 "groups": [
0090 {
0091 "name": "BarrelVertexHits",
0092 "type": "BoxHit",
0093 "origin": {"type": "edm4eic::TrackerHitData", "name": "MPGDBarrelRecHits"},
0094 ...,
0095 },
0096 ...
0097 ]
0098 },
0099 ...
0100 ]
0101 }
0102 ```
0103
0104 ## BoxHit group
0105
0106 ```json
0107 {
0108 "pos": [1, 2, 3],
0109 "dim": [10, 10, 1],
0110 "t": [4, 1],
0111 "ed": [0.001, 0.0001]
0112 }
0113 ```
0114 Hit has
0115
0116 - "pos": position [mm] (x, y, z),
0117 - "dim": box dimensions [mm] (dx, dy, dz),
0118 - "t": time information [ns] (time, err_time),
0119 - "ed": energy deposit with error [GeV] (edep, err_edep)
0120
0121 Example
0122
0123 ```json
0124 "groups": [
0125 {
0126 "name": "MPGDBarrelRecHits",
0127 "type": "BoxHit",
0128 "origin": {"type": "edm4eic::TrackerHitData", "name": "MPGDBarrelRecHits"}
0129 "hits": [
0130 {
0131 "pos": [-567, -84.1, -908],
0132 "dim": [0.05, 0.04, 0.0],
0133 "t": [-10.6, 10.0],
0134 "ed": [2e-06, 0.0]
0135 },
0136 {
0137 "pos": [368, -424, 406],
0138 "dim": [0.05, 0.045, 0.0],
0139 "t": [33, 10],
0140 "ed": [9e-06, 0.0]
0141 },
0142 ...]
0143 }]
0144 ```
0145
0146 ## Trajectory group
0147
0148 Trajectories that are built based on lines connecting points.
0149
0150 ```json
0151 "groups": [
0152 {
0153 "name": "CentralTrackSegments",
0154 "type": "PointTrajectory",
0155 "origin": { "type": ["edm4eic::TrackPoint","edm4eic::TrackSegment"]}
0156 "paramColumns": [".."], // Param columns should correspond to what is written in line/track params
0157 "pointColumns": ["x", "y", "z", "t", "dx", "dy", "dz", "dt"]
0158
0159 "trajectories": [
0160 {
0161 points: [
0162 [x, y, z, t, dx, dy, dz, dt],
0163 [x, y, z, t, dx, dy, dz, dt],
0164 ... // all points go here
0165 ],
0166 params: [...] // values to parameter columns here
0167 },
0168 ... // other lines
0169 ]
0170 ...
0171 ]
0172 ```
0173
0174 ## HomoHisto2D group
0175
0176 Square 2D histogram where elements are of the same size and arranged over cols and plots.
0177 The value of each histogram bin can change in time
0178
0179 ** -
0180
0181
0182
0183
0184
0185 ## TypeScript Event Model
0186
0187
0188 The Firebird Data Exchange model provides a structured way to serialize and deserialize
0189 event data. The model is implemented in TypeScript and designed to be extensible by users,
0190 so they could add their own custom groups without modifying the core parsing logic.
0191
0192 The implementation TypeScript classes mirror the data exchange format
0193 and provide methods for serialization and deserialization.
0194
0195 - **DataExchange** class - Represents the entire data exchange object.
0196 - **Event** class - Represents an individual event.
0197 - **EventGroup** abstract class - A base class representing a generic group. Described below.
0198
0199 It Typescript Firebird Data Exchange often referenced as Dex (Data EXchange) or FDEX. E.g.
0200 `toDexObject`, `fromDexObject`. `DexObject` is a JS object, that if serialized to JSON
0201 would correspond a part of DataExchangeFormat. E.g. Dex BoxHit will have `pos`, `dim` etc.
0202
0203 What is JSON DEX and Typescript data model difference?
0204
0205 In general JSON format is very close to object definition in JS => TS.
0206 But despite that, Firebird JSON format is just a data exchange layer and when deserialized from
0207 JSON is not designed to be a 100% a convenient to work with JS data structure.
0208 More over, it lacks some methods and abstractions, that our domain data-model should have,
0209 such as links between event model and three.js rendering tree objects.
0210
0211 Summarizing:
0212
0213 - Firebird Data Exchange - is JSON schema shaping data exchange between backend and frontend
0214 - DexObject - JSON parsed to JS object
0215 - TypeScript event model - Frontend set of classes mimicking DexObject structure but designed
0216 to be convenient in terms of the frontend API
0217
0218
0219 ### EventGroups machinery
0220
0221 Different collection of objects such as hits, tracks, vertexes, etc.
0222 that firebird can work with are represented as various **group-s**.
0223 Each type derive from `EventGroup` and registered in a system.
0224 Then corresponding `Painter`-s classes know how to render/paint them, there are rules how
0225 to display them in tables, etc. Corresponding `Component`class can show GUI configuring configs, etc.
0226
0227 - **EventGroup** An abstract class representing a generic group.
0228 - Contains common properties:
0229 - `name`: Unique identifier.
0230 - `type`: group type (used for determining the appropriate factory).
0231 - `origin`: Optional string indicating the origin type.
0232 - Declares an abstract method `toDexObject()` that must be implemented by subclasses.
0233
0234 - **EventGroupFactory Interface**: Defines a factory for creating `EventGroup`
0235 instances from Dex objects - deserialized data.
0236 - **group Registry**: A mapping of group types to their corresponding factories.
0237 - Functions:
0238 - `registergroupFactory(factory: EventGroupFactory)`: Registers a new factory.
0239 - `getgroupFactory(type: string)`: Retrieves a factory based on the group type.
0240
0241
0242 ## Extending the Model
0243
0244 ### Adding a New group Type
0245
0246 To add a new group type, follow these steps:
0247
0248 1. **Create a New group Class**: Extend `EventGroup` and implement the `toDexObject()` method.
0249
0250 ```typescript
0251 export class Customgroup extends EventGroup {
0252 static type = 'CustomType';
0253 // Define additional properties
0254
0255 constructor(name: string, /* additional parameters */, origin?: string) {
0256 super(name, Customgroup.type, origin);
0257 // Initialize additional properties
0258 }
0259
0260 toDexObject(): any {
0261 return {
0262 name: this.name,
0263 type: this.type,
0264 origin: {type: this.origin},
0265 // Serialize additional properties
0266 };
0267 }
0268 }
0269 ```
0270
0271 2. **Create a Factory for the group**: Implement `EventGroupFactory` for your group.
0272
0273 ```typescript
0274 export class CustomgroupFactory implements EventGroupFactory {
0275 type: string = Customgroup.type;
0276
0277 fromDexObject(obj: any): EventGroup {
0278 const name = obj["name"];
0279 // Extract additional properties
0280 const origin = obj["origin"];
0281
0282 // Validate required fields
0283 if (!name /* || missing other required fields */) {
0284 throw new Error("Missing required fields in Customgroup");
0285 }
0286
0287 return new Customgroup(name, /* additional parameters */, origin);
0288 }
0289 }
0290 ```
0291
0292 3. **Register the Factory**: Use the `registerGroupFactory()` function to register your group factory.
0293
0294 ```typescript
0295 // Register the custom group factory
0296 registergroupFactory(new CustomgroupFactory());
0297 ```
0298
0299 4. **Update JSON Parsing Logic**: No need to modify existing parsing logic. The registry will dynamically resolve the new group type.
0300