File

src/loaders/edm4hep-json-loader.ts

Description

Edm4hepJsonLoader for loading EDM4hep json dumps

Extends

PhoenixLoader

Index

Properties
Methods

Constructor

constructor()

Create Edm4hepJsonLoader

Properties

Private rawEventData
Type : any

Event data loaded from EDM4hep JSON file

Protected eventData
Type : any
Inherited from PhoenixLoader
Defined in PhoenixLoader:26

Event data processed by the loader.

Private graphicsLibrary
Type : ThreeManager
Inherited from PhoenixLoader
Defined in PhoenixLoader:22

ThreeService to perform three.js related functions.

Protected labelsObject
Type : literal type
Default value : {}
Inherited from PhoenixLoader
Defined in PhoenixLoader:32

Object containing event object labels.

Protected loadingManager
Type : LoadingManager
Inherited from PhoenixLoader
Defined in PhoenixLoader:28

Loading manager for loadable resources

Protected stateManager
Type : StateManager
Inherited from PhoenixLoader
Defined in PhoenixLoader:30

Loading manager for loadable resources

Private ui
Type : UIManager
Inherited from PhoenixLoader
Defined in PhoenixLoader:24

UIService to perform UI related functions.

Methods

Private colorTracks
colorTracks(event: any)

Assign default color to Tracks

Parameters :
Name Type Optional
event any No
Returns : void
Private convHSLtoHEX
convHSLtoHEX(h: number, s: number, l: number)

Helper conversion of HSL to hexadecimal

Parameters :
Name Type Optional
h number No
s number No
l number No
Returns : string
Private getCaloClusters
getCaloClusters(event: any)

Return Calo clusters

Parameters :
Name Type Optional
event any No
Returns : {}
Private getCells
getCells(event: any)

Returns the cells

Parameters :
Name Type Optional
event any No
Returns : {}
Private getCollByID
getCollByID(event: any, id: number)

Get the required collection

Parameters :
Name Type Optional
event any No
id number No
Returns : any
getEventData
getEventData()

Output event data in Phoenix compatible format

Returns : any
Private getEventNumber
getEventNumber(event: any)

Return event number (or 0, if not defined)

Parameters :
Name Type Optional
event any No
Returns : number
Private getHits
getHits(event: any)

Not implemented

Parameters :
Name Type Optional
event any No
Returns : {}
Private getJets
getJets(event: any)

Return jets

Parameters :
Name Type Optional
event any No
Returns : {}
Private getMissingEnergy
getMissingEnergy(event: any)

Return missing energy

Parameters :
Name Type Optional
event any No
Returns : {}
Private getNumEvents
getNumEvents()

Return number of events

Returns : number
Private getRunNumber
getRunNumber(event: any)

Return run number (or 0, if not defined)

Parameters :
Name Type Optional
event any No
Returns : number
Private getTracks
getTracks(event: any)

Return tracks

Parameters :
Name Type Optional
event any No
Returns : {}
Private getVertices
getVertices(event: any)

Return the vertices

Parameters :
Name Type Optional
event any No
Returns : {}
processEventData
processEventData()

Process raw EDM4hep JSON event data into the Phoenix format

Returns : boolean
Private randomColor
randomColor()

Return a random colour

Returns : any
setRawEventData
setRawEventData(rawEventData: any)

Put raw EDM4hep JSON event data into the loader

Parameters :
Name Type Optional
rawEventData any No
Returns : void
Private valToLightness
valToLightness(v: number, min: number, max: number)

Return a lightness value from the passed number and range

Parameters :
Name Type Optional
v number No
min number No
max number No
Returns : number
Private valToOpacity
valToOpacity(v: number, min: number, max: number)

Return a opacity value from the passed number and range

Parameters :
Name Type Optional
v number No
min number No
max number No
Returns : number
Private addCollection
addCollection(objectCollection: any, collectionName: string, getObject: (object: any) => void, typeName: string, objectGroup: Group, concatonateObjs: boolean)
Inherited from PhoenixLoader
Defined in PhoenixLoader:509

Adds to the event display all the objects inside a collection.

Parameters :
Name Type Optional Description
objectCollection any No

Contains the params for every object of the collection.

collectionName string No

Label to UNIQUELY identify the collection.

getObject function No

Handles reconstructing the objects of the collection.

typeName string No
objectGroup Group No

Group containing the collections of the same object type.

concatonateObjs boolean No

If true, don't process objects individually, but process as a group (e.g. for point hits).

Returns : void
Public addLabelToEventObject
addLabelToEventObject(label: string, collection: string, indexInCollection: number)
Inherited from PhoenixLoader
Defined in PhoenixLoader:726

Add label of event object to the labels object.

Parameters :
Name Type Optional Description
label string No

Label to be saved.

collection string No

Collection the event object is a part of.

indexInCollection number No

Event object's index in collection.

Returns : string

A unique label ID string.

Protected addObjectType
addObjectType(object: any, getObject: any, typeName: string, concatonateObjs: boolean, cuts?: Cut[], extendEventDataTypeUI?: (typeFolder?: GUI,typeFolderPM?: PhoenixMenuNode) => void)
Inherited from PhoenixLoader
Defined in PhoenixLoader:446

Adds to the event display all collections of a given object type.

Parameters :
Name Type Optional Default value Description
object any No

Contains all collections of a given type (Tracks, Jets, CaloClusters...).

getObject any No

Function that handles of reconstructing objects of the given type.

typeName string No

Label for naming the object type.

concatonateObjs boolean No false

If true, don't process objects individually, but process as a group (e.g. for point hits). Default is false.

cuts Cut[] Yes

Filters that can be applied to the objects.

extendEventDataTypeUI function Yes

A callback to add more options to event data type UI folder.

Returns : void
Public addScaleOptions
addScaleOptions(configKey: string, configLabel: string, scaleFunction: (value: number) => void)
Inherited from PhoenixLoader
Defined in PhoenixLoader:760

Get function to add options to scale event object type by.

Parameters :
Name Type Optional Description
configKey string No

Key of the scale configuration option (for dat.GUI menu).

configLabel string No

Label of the scale configuration option.

scaleFunction function No

Function to scale the objects by.

Function which adds scale options to Phoenix menu and dat.GUI menu.

Public buildEventData
buildEventData(eventData: any, graphicsLibrary: ThreeManager, ui: UIManager, infoLogger: InfoLogger)
Inherited from PhoenixLoader
Defined in PhoenixLoader:50

Takes an object that represents ONE event and takes care of adding the different objects to the graphics library and the UI controls.

Parameters :
Name Type Optional Description
eventData any No

Object representing the event.

graphicsLibrary ThreeManager No

Service containing functionality to draw the 3D objects.

ui UIManager No

Service for showing menus and controls to manipulate the geometries.

infoLogger InfoLogger No

Service for logging data to the information panel.

Returns : void
Public getCollection
getCollection(collectionName: string)
Inherited from PhoenixLoader
Defined in PhoenixLoader:126

Get the collection with the given collection name from the event data.

Parameters :
Name Type Optional Description
collectionName string No

Name of the collection to get.

Returns : any

An object containing the collection.

Public getCollections
getCollections()
Inherited from PhoenixLoader
Defined in PhoenixLoader:102

Get list of collections in the event data.

Returns : string[]

List of all collection names.

Protected getCompound
getCompound(params: any, name: string, objectIsTrack: boolean, objectIsCluster: boolean)
Inherited from PhoenixLoader
Defined in PhoenixLoader:574

Process the compound object (e.g. Muon, Electron, Photon) from the given parameters and get it as a group. FIXME. This is currently here and not in PhoenixObjects because we need to handle linked objects.

Parameters :
Name Type Optional Default value Description
params any No

Parameters of the Muon.

name string No ''
objectIsTrack boolean No false
objectIsCluster boolean No false
Returns : Object3D

Muon group containing Clusters and Tracks.

Protected getCompoundCluster
getCompoundCluster(params: any, name: string)
Inherited from PhoenixLoader
Defined in PhoenixLoader:564

Process the compound object of cluster type (e.g. Photon, ..) from the given parameters and get it as a group.

Parameters :
Name Type Optional Default value
params any No
name string No ''
Returns : Object3D
Protected getCompoundTrack
getCompoundTrack(params: any, name: string)
Inherited from PhoenixLoader
Defined in PhoenixLoader:558

Process the compound object of track type (e.g. Muon, Electron, ..) from the given parameters and get it as a group.

Parameters :
Name Type Optional Default value
params any No
name string No ''
Returns : Object3D
getEventMetadata
getEventMetadata()
Inherited from PhoenixLoader
Defined in PhoenixLoader:672

Get metadata associated to the event (experiment info, time, run, event...).

Returns : any[]

Metadata of the event.

Public getEventsList
getEventsList(eventsData: any)
Inherited from PhoenixLoader
Defined in PhoenixLoader:86

Get the list of event names from the event data.

Parameters :
Name Type Optional Description
eventsData any No

Object containing all event data.

Returns : string[]

List of event names.

Public getLabelsObject
getLabelsObject()
Inherited from PhoenixLoader
Defined in PhoenixLoader:749

Get the object containing labels.

Returns : literal type

The labels object.

Private getObjectTypeCollections
getObjectTypeCollections(object: any)
Inherited from PhoenixLoader
Defined in PhoenixLoader:544

Get collection names of a given object type.

Parameters :
Name Type Optional Description
object any No

Contains all collections of a given type (Tracks, Jets, CaloClusters etc.).

Returns : string[]

List of collection names of an object type (Tracks, Jets, CaloClusters etc.).

Protected loadObjectTypes
loadObjectTypes(eventData: any)
Inherited from PhoenixLoader
Defined in PhoenixLoader:147

Receives an object containing the data from an event and parses it to reconstruct the different collections of physics objects.

Parameters :
Name Type Optional Description
eventData any No

Representing ONE event (expressed in the Phoenix format).

Returns : void
import { PhoenixLoader } from './phoenix-loader';

/**
 * Edm4hepJsonLoader for loading EDM4hep json dumps
 */
export class Edm4hepJsonLoader extends PhoenixLoader {
  /**  Event data loaded from EDM4hep JSON file */
  private rawEventData: any;

  /** Create Edm4hepJsonLoader */
  constructor() {
    super();
    this.eventData = {};
  }

  /** Put raw EDM4hep JSON event data into the loader */
  setRawEventData(rawEventData: any) {
    this.rawEventData = rawEventData;
  }

  /** Process raw EDM4hep JSON event data into the Phoenix format */
  processEventData(): boolean {
    Object.entries(this.rawEventData).forEach(([eventName, event]) => {
      const oneEventData = {
        Vertices: {},
        Tracks: {},
        Hits: {},
        CaloCells: {},
        CaloClusters: {},
        Jets: {},
        MissingEnergy: {},
        'event number': this.getEventNumber(event),
        'run number': this.getRunNumber(event),
      };

      this.colorTracks(event);

      oneEventData.Vertices = this.getVertices(event);
      oneEventData.Tracks = this.getTracks(event);
      oneEventData.Hits = this.getHits(event);
      oneEventData.CaloCells = this.getCells(event);
      oneEventData.CaloClusters = this.getCaloClusters(event);
      oneEventData.Jets = this.getJets(event);
      oneEventData.MissingEnergy = this.getMissingEnergy(event);

      this.eventData[eventName] = oneEventData;
    });

    return true;
  }

  /** Output event data in Phoenix compatible format */
  getEventData(): any {
    return this.eventData;
  }

  /** Return number of events */
  private getNumEvents(): number {
    return Object.keys(this.rawEventData).length;
  }

  /** Return run number (or 0, if not defined) */
  private getRunNumber(event: any): number {
    if (!('EventHeader' in event)) {
      return 0;
    }

    const eventHeader = event['EventHeader']['collection'];

    if (!('runNumber' in eventHeader)) {
      return eventHeader[0]['runNumber'];
    }

    return 0;
  }

  /** Return event number (or 0, if not defined) */
  private getEventNumber(event: any): number {
    if (!('EventHeader' in event)) {
      return 0;
    }

    const eventHeader = event['EventHeader']['collection'];

    if (!('eventNumber' in eventHeader)) {
      return eventHeader[0]['eventNumber'];
    }

    return 0;
  }

  /** Assign default color to Tracks*/
  private colorTracks(event: any) {
    let recoParticles: any[];
    if ('ReconstructedParticles' in event) {
      recoParticles = event['ReconstructedParticles']['collection'];
    } else {
      return;
    }

    let mcParticles: any[];
    if ('Particle' in event) {
      mcParticles = event['Particle']['collection'];
    } else {
      return;
    }

    let mcRecoAssocs: any[];
    if ('MCRecoAssociations' in event) {
      mcRecoAssocs = event['MCRecoAssociations']['collection'];
    } else {
      return;
    }

    let tracks: any[];
    if ('EFlowTrack' in event) {
      tracks = event['EFlowTrack']['collection'];
    } else {
      return;
    }

    mcRecoAssocs.forEach((mcRecoAssoc: any) => {
      const recoIndex = mcRecoAssoc['rec']['index'];
      const mcIndex = mcRecoAssoc['sim']['index'];

      const pdgid = mcParticles[mcIndex]['PDG'];
      const trackRefs = recoParticles[recoIndex]['tracks'];

      trackRefs.forEach((trackRef: any) => {
        const track = tracks[trackRef['index']];
        if (Math.abs(pdgid) === 11) {
          track['color'] = '00ff00';
          track['pid'] = 'electron';
        } else if (Math.abs(pdgid) === 22) {
          track['color'] = 'ff0000';
          track['pid'] = 'photon';
        } else if (Math.abs(pdgid) === 211 || Math.abs(pdgid) === 111) {
          track['color'] = 'a52a2a';
          track['pid'] = 'pion';
        } else if (Math.abs(pdgid) === 2212) {
          track['color'] = '778899';
          track['pid'] = 'proton';
        } else if (Math.abs(pdgid) === 321) {
          track['color'] = '5f9ea0';
          track['pid'] = 'kaon';
        } else {
          track['color'] = '0000cd';
          track['pid'] = 'other';
        }
        track['pdgid'] = pdgid;
      });
    });
  }

  /** Return the vertices */
  private getVertices(event: any) {
    const allVertices: any[] = [];

    for (const collName in event) {
      if (event[collName].constructor != Object) {
        continue;
      }

      const collDict = event[collName];

      if (!('collType' in collDict)) {
        continue;
      }

      if (!('collection' in collDict)) {
        continue;
      }

      if (!(collDict['collType'] === 'edm4hep::VertexCollection')) {
        continue;
      }

      const vertices: any[] = [];
      const rawVertices = collDict['collection'];
      const vertexColor = this.randomColor();

      rawVertices.forEach((rawVertex: any) => {
        const position: any[] = [];
        if ('position' in rawVertex) {
          position.push(rawVertex['position']['x'] * 0.1);
          position.push(rawVertex['position']['y'] * 0.1);
          position.push(rawVertex['position']['z'] * 0.1);
        }

        const vertex = {
          pos: position,
          size: 0.2,
          color: '#' + vertexColor,
        };
        vertices.push(vertex);
      });

      allVertices[collName] = vertices;
    }

    return allVertices;
  }

  /** Return tracks */
  private getTracks(event: any) {
    const allTracks: any[] = [];

    for (const collName in event) {
      if (event[collName].constructor != Object) {
        continue;
      }

      const collDict = event[collName];

      if (!('collType' in collDict)) {
        continue;
      }

      if (!(collDict['collType'] === 'edm4hep::TrackCollection')) {
        continue;
      }

      if (!('collection' in collDict)) {
        continue;
      }

      const rawTracks = collDict['collection'];
      const electrons: any[] = [];
      const photons: any[] = [];
      const pions: any[] = [];
      const protons: any[] = [];
      const kaons: any[] = [];
      const other: any[] = [];

      rawTracks.forEach((rawTrack: any) => {
        const positions: any[] = [];
        if ('trackerHits' in rawTrack) {
          const trackerHitRefs = rawTrack['trackerHits'];
          trackerHitRefs.forEach((trackerHitRef: any) => {
            const trackerHits = this.getCollByID(
              event,
              trackerHitRef['collectionID'],
            );
            const trackerHit = trackerHits[trackerHitRef['index']];
            positions.push([
              trackerHit['position']['x'] * 0.1,
              trackerHit['position']['y'] * 0.1,
              trackerHit['position']['z'] * 0.1,
            ]);
          });
        }
        if ('trackStates' in rawTrack && positions.length === 0) {
          const trackStates = rawTrack['trackStates'];
          trackStates.forEach((trackState: any) => {
            if ('referencePoint' in trackState) {
              positions.push([
                trackState['referencePoint']['x'] * 0.1,
                trackState['referencePoint']['y'] * 0.1,
                trackState['referencePoint']['z'] * 0.1,
              ]);
            }
          });
        }

        let trackColor = '0000cd';
        if ('color' in rawTrack) {
          trackColor = rawTrack['color'];
        }

        const track = {
          pos: positions,
          color: trackColor,
        };

        if ('pid' in rawTrack) {
          if (rawTrack['pid'] == 'electron') {
            electrons.push(track);
          } else if (rawTrack['pid'] == 'photon') {
            photons.push(track);
          } else if (rawTrack['pid'] == 'pion') {
            pions.push(track);
          } else if (rawTrack['pid'] == 'proton') {
            protons.push(track);
          } else if (rawTrack['pid'] == 'kaon') {
            kaons.push(track);
          } else {
            other.push(track);
          }
        } else {
          other.push(track);
        }
      });

      allTracks[collName + ' | Electrons'] = electrons;
      allTracks[collName + ' | Photons'] = photons;
      allTracks[collName + ' | Pions'] = pions;
      allTracks[collName + ' | Protons'] = protons;
      allTracks[collName + ' | Kaons'] = kaons;
      allTracks[collName + ' | Other'] = other;
    }

    return allTracks;
  }

  /** Not implemented */
  private getHits(event: any) {
    const allHits: any[] = [];

    for (const collName in event) {
      if (event[collName].constructor != Object) {
        continue;
      }

      const collDict = event[collName];

      if (!('collType' in collDict)) {
        continue;
      }

      if (!collDict['collType'].includes('edm4hep::')) {
        continue;
      }

      if (!collDict['collType'].includes('TrackerHitCollection')) {
        continue;
      }

      if (!('collection' in collDict)) {
        continue;
      }

      const rawHits = collDict['collection'];
      const hits: any[] = [];
      const hitColor = this.randomColor();

      rawHits.forEach((rawHit: any) => {
        const position: any[] = [];
        if ('position' in rawHit) {
          position.push(rawHit['position']['x'] * 0.1);
          position.push(rawHit['position']['y'] * 0.1);
          position.push(rawHit['position']['z'] * 0.1);
        }

        const hit = {
          type: 'CircularPoint',
          pos: position,
          color: '#' + hitColor,
          size: 2,
        };
        hits.push(hit);
      });

      allHits[collName] = hits;
    }

    return allHits;
  }

  /** Returns the cells */
  private getCells(event: any) {
    const allCells: any[] = [];

    for (const collName in event) {
      if (event[collName].constructor != Object) {
        continue;
      }

      const collDict = event[collName];

      if (!('collType' in collDict)) {
        continue;
      }

      if (!collDict['collType'].includes('edm4hep::')) {
        continue;
      }

      if (!collDict['collType'].includes('CalorimeterHitCollection')) {
        continue;
      }

      if (!('collection' in collDict)) {
        continue;
      }

      const rawCells = collDict['collection'];
      const cells: any[] = [];

      // Find smallest distance between cell centers and use it as cell size
      let drmin = 1e9;
      for (let i = 0; i < 1e4; ++i) {
        const j = Math.floor(Math.random() * rawCells.length);
        const k = Math.floor(Math.random() * rawCells.length);
        if (j === k) {
          continue;
        }

        const dx2 = Math.pow(
          rawCells[j].position.x - rawCells[k].position.x,
          2,
        );
        const dy2 = Math.pow(
          rawCells[j].position.y - rawCells[k].position.y,
          2,
        );
        const dz2 = Math.pow(
          rawCells[j].position.z - rawCells[k].position.z,
          2,
        );
        const dr = Math.sqrt(dx2 + dy2 + dz2);

        if (dr < drmin) {
          drmin = dr;
        }
      }
      const cellSide =
        Math.floor(drmin) * 0.1 > 1 ? Math.floor(drmin) * 0.1 : 1;
      const cellsHue = Math.floor(Math.random() * 358);

      rawCells.forEach((rawCell: any) => {
        const x = rawCell.position.x * 0.1;
        const y = rawCell.position.y * 0.1;
        const z = rawCell.position.z * 0.1;

        const r = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2));
        const rho = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
        const eta = Math.asinh(z / rho);
        const phi = Math.acos(x / rho) * Math.sign(y);
        const cellLightness = this.valToLightness(rawCell.energy, 1e-3, 1);
        const cellOpacity = this.valToOpacity(rawCell.energy, 1e-3, 1);

        const cell = {
          eta: eta,
          phi: phi,
          energy: rawCell.energy,
          radius: r,
          side: cellSide,
          length: cellSide, // expecting cells in multiple layers
          color: '#' + this.convHSLtoHEX(cellsHue, 90, cellLightness),
          opacity: cellOpacity,
        };
        cells.push(cell);
      });

      allCells[collName] = cells;
    }

    return allCells;
  }

  /** Return Calo clusters */
  private getCaloClusters(event: any) {
    const allClusters: any[] = [];

    for (const collName in event) {
      if (event[collName].constructor != Object) {
        continue;
      }

      const collDict = event[collName];

      if (!('collType' in collDict)) {
        continue;
      }

      if (!(collDict['collType'] === 'edm4hep::ClusterCollection')) {
        continue;
      }

      if (!('collection' in collDict)) {
        continue;
      }

      const rawClusters = collDict['collection'];
      const clusters: any[] = [];

      rawClusters.forEach((rawCluster: any) => {
        const x = rawCluster.position.x * 0.1;
        const y = rawCluster.position.y * 0.1;
        const z = rawCluster.position.z * 0.1;

        const r = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2));
        const rho = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
        const eta = Math.asinh(z / rho);
        const phi = Math.acos(x / rho) * Math.sign(y);

        const cluster = {
          eta: eta,
          phi: phi,
          energy: rawCluster.energy * 100,
          radius: r,
          side: 4,
        };
        clusters.push(cluster);
      });

      allClusters[collName] = clusters;
    }

    return allClusters;
  }

  /** Return jets */
  private getJets(event: any) {
    const allJets: any[] = [];

    for (const collName in event) {
      if (event[collName].constructor != Object) {
        continue;
      }

      const collDict = event[collName];

      if (!('collType' in collDict)) {
        continue;
      }

      if (
        !(collDict['collType'] === 'edm4hep::ReconstructedParticleCollection')
      ) {
        continue;
      }

      if (!(collName.includes('Jet') || collName.includes('jet'))) {
        continue;
      }

      if (!('collection' in collDict)) {
        continue;
      }

      const jets: any[] = [];
      const rawJets = collDict['collection'];

      rawJets.forEach((rawJet: any) => {
        if (!('momentum' in rawJet)) {
          return;
        }
        if (!('energy' in rawJet)) {
          return;
        }
        const px = rawJet['momentum']['x'];
        const py = rawJet['momentum']['y'];
        const pz = rawJet['momentum']['z'];

        const pt = Math.sqrt(Math.pow(px, 2) + Math.pow(py, 2));
        const eta = Math.asinh(pz / pt);
        const phi = Math.acos(px / pt) * Math.sign(py);

        const jet = {
          eta: eta,
          phi: phi,
          energy: 1000 * rawJet.energy,
        };
        jets.push(jet);
      });
      allJets[collName] = jets;
    }

    return allJets;
  }

  /** Return missing energy */
  private getMissingEnergy(event: any) {
    const allMETs: any[] = [];

    for (const collName in event) {
      if (event[collName].constructor != Object) {
        continue;
      }

      const collDict = event[collName];

      if (!('collType' in collDict)) {
        continue;
      }

      if (
        !(collDict['collType'] === 'edm4hep::ReconstructedParticleCollection')
      ) {
        continue;
      }

      if (!(collName.includes('Missing') || collName.includes('missing'))) {
        continue;
      }

      if (!('collection' in collDict)) {
        continue;
      }

      const METs: any[] = [];
      const rawMETs = collDict['collection'];
      const METColor = '#ff69b4';

      rawMETs.forEach((rawMET: any) => {
        if (!('momentum' in rawMET)) {
          return;
        }
        if (!('energy' in rawMET)) {
          return;
        }
        const px = rawMET['momentum']['x'];
        const py = rawMET['momentum']['y'];
        const pz = rawMET['momentum']['z'];

        const p = Math.sqrt(
          Math.pow(px, 2) + Math.pow(py, 2) + Math.pow(pz, 2),
        );
        const etx = (rawMET['energy'] * px) / p;
        const ety = (rawMET['energy'] * py) / p;

        const MET = {
          etx: etx * 10,
          ety: ety * 10,
          color: '#ff69b4',
        };
        METs.push(MET);
      });
      allMETs[collName] = METs;
    }

    return allMETs;
  }

  /** Return a random colour */
  private randomColor() {
    return Math.floor(Math.random() * 16777215)
      .toString(16)
      .padStart(6, '0')
      .toUpperCase();
  }

  /** Helper conversion of HSL to hexadecimal */
  private convHSLtoHEX(h: number, s: number, l: number): string {
    l /= 100;
    const a = (s * Math.min(l, 1 - l)) / 100;
    const f = (n) => {
      const k = (n + h / 30) % 12;
      const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
      return Math.round(255 * color)
        .toString(16)
        .padStart(2, '0');
    };

    return `${f(0)}${f(8)}${f(4)}`;
  }

  /** Return a lightness value from the passed number and range */
  private valToLightness(v: number, min: number, max: number): number {
    let lightness = 80 - ((v - min) * 65) / (max - min);
    if (lightness < 20) {
      lightness = 20;
    }
    if (lightness > 85) {
      lightness = 85;
    }

    return lightness;
  }

  /** Return a opacity value from the passed number and range */
  private valToOpacity(v: number, min: number, max: number): number {
    let opacity = 0.2 + ((v - min) * 0.65) / (max - min);
    if (opacity < 0.2) {
      opacity = 0.2;
    }
    if (opacity > 0.8) {
      opacity = 0.8;
    }

    return opacity;
  }

  /** Get the required collection */
  private getCollByID(event: any, id: number) {
    for (const collName in event) {
      if (event[collName].constructor != Object) {
        continue;
      }

      const collDict = event[collName];

      if (!('collID' in collDict)) {
        continue;
      }

      if (collDict['collID'] === id) {
        return collDict['collection'];
      }
    }
  }
}

results matching ""

    No results matching ""