From 2256b4372f4a78cfe65758347cfaecf3a0be8cff Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Tue, 24 Feb 2026 14:37:45 +0100 Subject: [PATCH 01/30] Git rebase --- docs/assets/geometry/ATLAS/.SCT.obj.icloud | Bin 157 -> 0 bytes docs/assets/geometry/ATLAS/.toroids.obj.icloud | Bin 161 -> 0 bytes .../src/assets/geometry/ATLAS/.SCT.obj.icloud | Bin 157 -> 0 bytes .../src/assets/geometry/ATLAS/.toroids.obj.icloud | Bin 161 -> 0 bytes 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/assets/geometry/ATLAS/.SCT.obj.icloud delete mode 100644 docs/assets/geometry/ATLAS/.toroids.obj.icloud delete mode 100644 packages/phoenix-ng/projects/phoenix-app/src/assets/geometry/ATLAS/.SCT.obj.icloud delete mode 100644 packages/phoenix-ng/projects/phoenix-app/src/assets/geometry/ATLAS/.toroids.obj.icloud diff --git a/docs/assets/geometry/ATLAS/.SCT.obj.icloud b/docs/assets/geometry/ATLAS/.SCT.obj.icloud deleted file mode 100644 index df24bd6371eaf782a2ad2c90ee229464235a8c37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 157 zcmYc)$jK}&F)+By$i&RT$`<1n92(@~mzbOComv?$AOPmNW#*&?XI4RkB;Z0psm1xF zMaiill?5QF@L=Zr3IG>zE1CcR diff --git a/packages/phoenix-ng/projects/phoenix-app/src/assets/geometry/ATLAS/.SCT.obj.icloud b/packages/phoenix-ng/projects/phoenix-app/src/assets/geometry/ATLAS/.SCT.obj.icloud deleted file mode 100644 index df24bd6371eaf782a2ad2c90ee229464235a8c37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 157 zcmYc)$jK}&F)+By$i&RT$`<1n92(@~mzbOComv?$AOPmNW#*&?XI4RkB;Z0psm1xF zMaiill?5QF@L=Zr3IG>zE1CcR From 903d7849ec145cab95a78b5f3b2a73317a26261c Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Tue, 24 Feb 2026 14:46:50 +0100 Subject: [PATCH 02/30] Reduce number of passes through EDM4hep JSON event data to only one --- .../src/loaders/edm4hep-json-loader.ts | 902 +++++++----------- 1 file changed, 366 insertions(+), 536 deletions(-) diff --git a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts index 1a4ccfde7..85014306c 100644 --- a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts +++ b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts @@ -35,13 +35,57 @@ export class Edm4hepJsonLoader extends PhoenixLoader { 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); + for (const collName in event) { + const collDict = event[collName]; + + if ( + collDict.constructor === Object && + 'collType' in collDict && + 'collection' in collDict + ) { + switch (collDict['collType']) { + case 'edm4hep::VertexCollection': + oneEventData.Vertices[collName] = this.getVertices(collDict); + break; + case 'edm4hep::TrackCollection': { + this.getTracks(event, collDict) + .filter(([, arr]) => arr.length > 0) + .forEach(([label, arr]) => { + oneEventData.Tracks[`${collName} | ${label}`] = arr; + }); + break; + } + case 'edm4hep::TrackerHitCollection': + case 'edm4hep::SimTrackerHitCollection': { + this.getHits(event, collDict) + .filter(([, arr]) => arr.length > 0) + .forEach(([label, arr]) => { + oneEventData.Hits[`${collName} | ${label}`] = arr; + }); + break; + } + case 'edm4hep::CalorimeterHitCollection': + case 'edm4hep::SimCalorimeterHitCollection': + oneEventData.CaloCells[collName] = this.getCells(collDict); + break; + case 'edm4hep::ClusterCollection': + oneEventData.CaloClusters[collName] = + this.getCaloClusters(collDict); + break; + case 'edm4hep::ReconstructedParticleCollection': + if (collName.includes('Jet') || collName.includes('jet')) { + oneEventData.Jets[collName] = this.getJets(collDict); + } else if ( + collName.includes('Missing') || + collName.includes('missing') + ) { + oneEventData.MissingEnergy[collName] = + this.getMissingEnergy(collDict); + } + break; + } + } + } this.eventData[eventName] = oneEventData; }); @@ -186,592 +230,378 @@ export class Edm4hepJsonLoader extends PhoenixLoader { } /** Return the vertices */ - private getVertices(event: any) { - const allVertices: { [key: string]: 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; - } + private getVertices(collDict: any): any[] { + 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); + }); - return allVertices; + return vertices; } /** Return tracks */ - private getTracks(event: any) { - const allTracks: { [key: string]: 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']]; + private getTracks(event: any, collDict: any) { + 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([ - trackerHit['position']['x'] * 0.1, - trackerHit['position']['y'] * 0.1, - trackerHit['position']['z'] * 0.1, + trackState['referencePoint']['x'] * 0.1, + trackState['referencePoint']['y'] * 0.1, + trackState['referencePoint']['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']; - } + let trackColor = '0000cd'; + if ('color' in rawTrack) { + trackColor = rawTrack['color']; + } - const track = { - pos: positions, - color: trackColor, - }; + 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); - } + 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); } - }); - - allTracks[collName + ' | Electrons'] = electrons; - allTracks[collName + ' | Photons'] = photons; - allTracks[collName + ' | Pions'] = pions; - allTracks[collName + ' | Protons'] = protons; - allTracks[collName + ' | Kaons'] = kaons; - allTracks[collName + ' | Other'] = other; - } + } else { + other.push(track); + } + }); - return allTracks; + return [ + ['Electrons', electrons], + ['Photons', photons], + ['Pions', pions], + ['Protons', protons], + ['Kaons', kaons], + ['Other', other], + ]; } /** Return tracker hits */ - private getHits(event: any) { - const allHits: { [key: string]: any[] } = {}; - - for (const collName in event) { - if (event[collName].constructor != Object) { - continue; - } - - const collDict = event[collName]; - // console.log(collDict); - - 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 hitsOverlay: any[] = []; - const hitsProdBySecondary: any[] = []; - const hitsElectron: any[] = []; - const hitsMuon: any[] = []; - const hitsPion: any[] = []; - const hitsKaon: any[] = []; - const hitsProton: any[] = []; - const hitColor = this.randomColor(); - const hitColorOverlay = this.randomColor(); - const hitColorProdBySecondary = this.randomColor(); - const hitColorElectron = this.randomColor(); - const hitColorMuon = this.randomColor(); - const hitColorPion = this.randomColor(); - const hitColorKaon = this.randomColor(); - const hitColorProton = 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); - } - - /* BITOverlay = 31 - * https://github.com/key4hep/EDM4hep/blob/fe5a54046a91a7e648d0b588960db7841aebc670/edm4hep.yaml#L349 + private getHits(event: any, collDict: any) { + const rawHits = collDict['collection']; + const hits: any[] = []; + const hitsOverlay: any[] = []; + const hitsProdBySecondary: any[] = []; + const hitsElectron: any[] = []; + const hitsMuon: any[] = []; + const hitsPion: any[] = []; + const hitsKaon: any[] = []; + const hitsProton: any[] = []; + const hitColor = this.randomColor(); + const hitColorOverlay = this.randomColor(); + const hitColorProdBySecondary = this.randomColor(); + const hitColorElectron = this.randomColor(); + const hitColorMuon = this.randomColor(); + const hitColorPion = this.randomColor(); + const hitColorKaon = this.randomColor(); + const hitColorProton = 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); + } + + /* BITOverlay = 31 + * https://github.com/key4hep/EDM4hep/blob/fe5a54046a91a7e648d0b588960db7841aebc670/edm4hep.yaml#L349 + */ + if ((rawHit['quality'] & (1 << 31)) !== 0) { + const hit = { + type: 'CircularPoint', + pos: position, + color: '#' + hitColorOverlay, + size: 2, + }; + hitsOverlay.push(hit); + /* BITProducedBySecondary = 30 + * https://github.com/key4hep/EDM4hep/blob/fe5a54046a91a7e648d0b588960db7841aebc670/edm4hep.yaml#L350 */ - if ((rawHit['quality'] & (1 << 31)) !== 0) { - const hit = { - type: 'CircularPoint', - pos: position, - color: '#' + hitColorOverlay, - size: 2, - }; - hitsOverlay.push(hit); - /* BITProducedBySecondary = 30 - * https://github.com/key4hep/EDM4hep/blob/fe5a54046a91a7e648d0b588960db7841aebc670/edm4hep.yaml#L350 - */ - } else if ((rawHit['quality'] & (1 << 30)) !== 0) { - const hit = { - type: 'CircularPoint', - pos: position, - color: '#' + hitColorProdBySecondary, - size: 2, - }; - hitsProdBySecondary.push(hit); - } else { - let other = true; - if (rawHit['particle'].length > 0) { - const pdg = this.getPDG( - event, - rawHit['particle'][0]['collectionID'], - rawHit['particle'][0]['index'], - ); - if (Math.abs(pdg) === 11) { - const hit = { - type: 'CircularPoint', - pos: position, - color: '#' + hitColorElectron, - size: 2, - }; - hitsElectron.push(hit); - other = false; - } else if (Math.abs(pdg) === 13) { - const hit = { - type: 'CircularPoint', - pos: position, - color: '#' + hitColorMuon, - size: 2, - }; - hitsMuon.push(hit); - other = false; - } else if (Math.abs(pdg) === 211) { - const hit = { - type: 'CircularPoint', - pos: position, - color: '#' + hitColorPion, - size: 2, - }; - hitsPion.push(hit); - other = false; - } else if (Math.abs(pdg) === 321) { - const hit = { - type: 'CircularPoint', - pos: position, - color: '#' + hitColorKaon, - size: 2, - }; - hitsKaon.push(hit); - other = false; - } else if (Math.abs(pdg) === 2212) { - const hit = { - type: 'CircularPoint', - pos: position, - color: '#' + hitColorProton, - size: 2, - }; - hitsProton.push(hit); - other = false; - } - } - if (other) { + } else if ((rawHit['quality'] & (1 << 30)) !== 0) { + const hit = { + type: 'CircularPoint', + pos: position, + color: '#' + hitColorProdBySecondary, + size: 2, + }; + hitsProdBySecondary.push(hit); + } else { + let other = true; + if (rawHit['particle']?.length > 0) { + const pdg = this.getPDG( + event, + rawHit['particle'][0]['collectionID'], + rawHit['particle'][0]['index'], + ); + if (Math.abs(pdg) === 11) { + const hit = { + type: 'CircularPoint', + pos: position, + color: '#' + hitColorElectron, + size: 2, + }; + hitsElectron.push(hit); + other = false; + } else if (Math.abs(pdg) === 13) { + const hit = { + type: 'CircularPoint', + pos: position, + color: '#' + hitColorMuon, + size: 2, + }; + hitsMuon.push(hit); + other = false; + } else if (Math.abs(pdg) === 211) { + const hit = { + type: 'CircularPoint', + pos: position, + color: '#' + hitColorPion, + size: 2, + }; + hitsPion.push(hit); + other = false; + } else if (Math.abs(pdg) === 321) { const hit = { type: 'CircularPoint', pos: position, - color: '#' + hitColor, + color: '#' + hitColorKaon, size: 2, }; - hits.push(hit); + hitsKaon.push(hit); + other = false; + } else if (Math.abs(pdg) === 2212) { + const hit = { + type: 'CircularPoint', + pos: position, + color: '#' + hitColorProton, + size: 2, + }; + hitsProton.push(hit); + other = false; } } - }); - - if (hits.length > 0) { - allHits[collName + ' | Other'] = hits; - } - if (hitsOverlay.length > 0) { - allHits[collName + ' | Overlay'] = hitsOverlay; - } - if (hitsProdBySecondary.length > 0) { - allHits[collName + ' | Secondary'] = hitsProdBySecondary; - } - if (hitsElectron.length > 0) { - allHits[collName + ' | Electron'] = hitsElectron; - } - if (hitsMuon.length > 0) { - allHits[collName + ' | Muon'] = hitsMuon; - } - if (hitsPion.length > 0) { - allHits[collName + ' | Pion'] = hitsPion; - } - if (hitsKaon.length > 0) { - allHits[collName + ' | Kaon'] = hitsKaon; - } - if (hitsProton.length > 0) { - allHits[collName + ' | Proton'] = hitsProton; + if (other) { + const hit = { + type: 'CircularPoint', + pos: position, + color: '#' + hitColor, + size: 2, + }; + hits.push(hit); + } } - } + }); - return allHits; + return [ + ['Other', hits], + ['Overlay', hitsOverlay], + ['Secondary', hitsProdBySecondary], + ['Electron', hitsElectron], + ['Muon', hitsMuon], + ['Pion', hitsPion], + ['Kaon', hitsKaon], + ['Proton', hitsProton], + ]; } /** Returns the cells */ - private getCells(event: any) { - const allCells: { [key: string]: any[] } = {}; + private getCells(collDict: any) { + const rawCells = collDict['collection']; + const cells: any[] = []; - for (const collName in event) { - if (event[collName].constructor != Object) { + // 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 collDict = event[collName]; + 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 (!('collType' in collDict)) { - continue; + if (dr < drmin) { + drmin = dr; } - - 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; } + 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); + }); - return allCells; + return cells; } /** Return Calo clusters */ - private getCaloClusters(event: any) { - const allClusters: { [key: string]: 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; - } + private getCaloClusters(collDict: any) { + 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); + }); - return allClusters; + return clusters; } /** Return jets */ - private getJets(event: any) { - const allJets: { [key: string]: any[] } = {}; + private getJets(collDict: any) { + const jets: any[] = []; + const rawJets = collDict['collection']; - for (const collName in event) { - if (event[collName].constructor != Object) { - continue; + rawJets.forEach((rawJet: any) => { + if (!('momentum' in rawJet)) { + return; } - - 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; + if (!('energy' in rawJet)) { + return; } + const px = rawJet['momentum']['x']; + const py = rawJet['momentum']['y']; + const pz = rawJet['momentum']['z']; - 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; - } + 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); - return allJets; + const jet = { + eta: eta, + phi: phi, + energy: 1000 * rawJet.energy, + }; + jets.push(jet); + }); + return jets; } /** Return missing energy */ - private getMissingEnergy(event: any) { - const allMETs: { [key: string]: any[] } = {}; + private getMissingEnergy(collDict: any) { + const METs: any[] = []; + const rawMETs = collDict['collection']; - for (const collName in event) { - if (event[collName].constructor != Object) { - continue; + rawMETs.forEach((rawMET: any) => { + if (!('momentum' in rawMET)) { + return; } - - const collDict = event[collName]; - - if (!('collType' in collDict)) { - continue; + if (!('energy' in rawMET)) { + return; } + const px = rawMET['momentum']['x']; + const py = rawMET['momentum']['y']; + const pz = rawMET['momentum']['z']; - if ( - !(collDict['collType'] === 'edm4hep::ReconstructedParticleCollection') - ) { - continue; - } + 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; - 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; + const MET = { + etx: etx * 10, + ety: ety * 10, + color: '#ff69b4', + }; + METs.push(MET); + }); + return METs; } /** Return a random colour */ From 91d5deb1580053bde1a93d5594ee43fc024034a7 Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Mon, 2 Mar 2026 15:05:50 +0100 Subject: [PATCH 03/30] Create type namespace for each schema --- .../src/lib/types/schemas/schema1.ts | 134 +++++++++++++ .../src/lib/types/schemas/schema2.ts | 161 ++++++++++++++++ .../src/lib/types/schemas/schema3.ts | 161 ++++++++++++++++ .../src/lib/types/schemas/schema4.ts | 161 ++++++++++++++++ .../src/lib/types/schemas/schema5.ts | 178 ++++++++++++++++++ .../src/lib/types/schemas/schema6.ts | 178 ++++++++++++++++++ .../src/lib/types/schemas/utils.ts | 36 ++++ 7 files changed, 1009 insertions(+) create mode 100644 packages/phoenix-event-display/src/lib/types/schemas/schema1.ts create mode 100644 packages/phoenix-event-display/src/lib/types/schemas/schema2.ts create mode 100644 packages/phoenix-event-display/src/lib/types/schemas/schema3.ts create mode 100644 packages/phoenix-event-display/src/lib/types/schemas/schema4.ts create mode 100644 packages/phoenix-event-display/src/lib/types/schemas/schema5.ts create mode 100644 packages/phoenix-event-display/src/lib/types/schemas/schema6.ts create mode 100644 packages/phoenix-event-display/src/lib/types/schemas/utils.ts diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema1.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema1.ts new file mode 100644 index 000000000..106dfdfd6 --- /dev/null +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema1.ts @@ -0,0 +1,134 @@ +import { Vector3f, Vector3d, ObjectID } from './utils'; + +export namespace Schema1 { + type TrackState = { + location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation + D0: number; // transverse impact parameter + phi: number; // azimuthal angle + omega: number; // is the signed curvature of the track in [1/mm]. + Z0: number; // longitudinal impact parameter + tanLambda: number; // lambda is the dip angle of the track in r-z + time: number; // time of the track at this trackstate + referencePoint: Vector3f; // Reference point of the track parameters, e.g. the origin at the IP, or the position of the first/last hits or the entry point into the calorimeter. [mm] + covMatrix: number[]; // lower triangular covariance matrix of the track parameters. the order of parameters is d0, phi, omega, z0, tan(lambda), time. the array is a row-major flattening of the matrix. + }; + + /** Vertex */ + type Vertex = { + primary: number; // boolean flag, if vertex is the primary vertex of the event + chi2: number; // chi-squared of the vertex fit + probability: number; // probability of the vertex fit + position: Vector3f; // [mm] position of the vertex. + covMatrix: number[]; // covariance matrix of the position (stored as lower triangle matrix, i.e. cov(xx),cov(y,x),cov(z,x),cov(y,y),... ) + algorithmType: number; // type code for the algorithm that has been used to create the vertex - check/set the collection parameters AlgorithmName and AlgorithmType. + parameters: number[]; // additional parameters related to this vertex - check/set the collection parameter "VertexParameterNames" for the parameters meaning. + associatedParticle: ObjectID; // reconstructed particle associated to this vertex. + }; + + /** Reconstructed track */ + type Track = { + type: number; // flagword that defines the type of track.Bits 16-31 are used internally + chi2: number; // Chi^2 of the track fit + ndf: number; // number of degrees of freedom of the track fit + dEdx: number; // dEdx of the track. + dEdxError: number; // error of dEdx. + radiusOfInnermostHit: number; // radius of the innermost hit that has been used in the track fit + subdetectorHitNumbers: number[]; // number of hits in particular subdetectors.Check/set collection variable TrackSubdetectorNames for decoding the indices + trackStates: TrackState[]; // track states + dxQuantities: { + error: number; + type: number; + value: number; + }[]; // different measurements of dx quantities + trackerHits: ObjectID[]; // hits that have been used to create this track + tracks: ObjectID[]; // tracks (segments) that have been combined to create this track + }; + + /** Tracker hit */ + type TrackerHit = { + cellID: number; // ID of the sensor that created this hit + type: number; // type of raw data hit, either one of edm4hep::RawTimeSeries, edm4hep::SIMTRACKERHIT - see collection parameters "TrackerHitTypeNames" and "TrackerHitTypeValues". + quality: number; // quality bit flag of the hit. + time: number; // time of the hit [ns]. + eDep: number; // energy deposited on the hit [GeV]. + eDepError: number; // error measured on EDep [GeV]. + position: Vector3d; // hit position in [mm]. + covMatrix: number[]; // covariance of the position (x,y,z), stored as lower triangle matrix. i.e. cov(x,x) , cov(y,x) , cov(y,y) , cov(z,x) , cov(z,y) , cov(z,z) + rawHits: ObjectID[]; // raw data hits. Check getType to get actual data type. + }; + + /** Simulated tracker hit */ + type SimTrackerHit = { + cellID: number; // ID of the sensor that created this hit + EDep: number; // energy deposited in the hit [GeV]. + time: number; // proper time of the hit in the lab frame in [ns]. + pathLength: number; // path length of the particle in the sensitive material that resulted in this hit. + quality: number; // quality bit flag. + position: Vector3d; // the hit position in [mm]. + momentum: Vector3f; // the 3-momentum of the particle at the hits position in [GeV] + MCParticle: ObjectID; // MCParticle that caused the hit. + }; + + /** Calorimeter hit */ + type CalorimeterHit = { + cellID: number; // detector specific (geometrical) cell id. + energy: number; // energy of the hit in [GeV]. + energyError: number; // error of the hit energy in [GeV]. + time: number; // time of the hit in [ns]. + position: Vector3f; // position of the hit in world coordinates in [mm]. + type: number; // type of hit. Mapping of integer types to names via collection parameters "CalorimeterHitTypeNames" and "CalorimeterHitTypeValues". + }; + + /** Simulated calorimeter hit */ + type SimCalorimeterHit = { + cellID: number; // ID of the sensor that created this hit + energy: number; // energy of the hit in [GeV]. + position: Vector3f; // position of the hit in world coordinates in [mm]. + contributions: ObjectID[]; // Monte Carlo step contribution - parallel to particle + }; + + /** Calorimeter Hit Cluster */ + type Cluster = { + type: number; // flagword that defines the type of cluster. Bits 16-31 are used internally. + energy: number; // energy of the cluster [GeV] + energyError: number; // error on the energy + position: Vector3f; // position of the cluster [mm] + positionError: number[]; // covariance matrix of the position (6 Parameters) + iTheta: number; // intrinsic direction of cluster at position Theta. Not to be confused with direction cluster is seen from IP. + phi: number; // intrinsic direction of cluster at position - Phi. Not to be confused with direction cluster is seen from IP. + directionError: Vector3f; // covariance matrix of the direction (3 Parameters) [mm^2] + shapeParameters: number[]; // shape parameters - check/set collection parameter ClusterShapeParameters for size and names of parameters. + subdetectorEnergies: number[]; // energy observed in a particular subdetector. Check/set collection parameter ClusterSubdetectorNames for decoding the indices of the array. + clusters: ObjectID[]; // clusters that have been combined to this cluster. + hits: ObjectID[]; // hits that have been combined to this cluster. + particleIDs: ObjectID[]; // particle IDs (sorted by their likelihood) + }; + + /** Reconstructed Particle */ + type ReconstructedParticle = { + type: number; // type of reconstructed particle. Check/set collection parameters ReconstructedParticleTypeNames and ReconstructedParticleTypeValues. + energy: number; // [GeV] energy of the reconstructed particle. Four momentum state is not kept consistent internally. + momentum: Vector3f; // [GeV] particle momentum. Four momentum state is not kept consistent internally. + referencePoint: Vector3f; // [mm] reference, i.e. where the particle has been measured + charge: number; // charge of the reconstructed particle. + mass: number; // [GeV] mass of the reconstructed particle, set independently from four vector. Four momentum state is not kept consistent internally. + goodnessOfPID: number; // overall goodness of the PID on a scale of [0;1] + covMatrix: number[]; // cvariance matrix of the reconstructed particle 4vector (10 parameters). Stored as lower triangle matrix of the four momentum (px,py,pz,E), i.e. cov(px,px), cov(py,## + startVertex: ObjectID; // start vertex associated to this particle + particleIDUsed: ObjectID; // particle Id used for the kinematics of this particle + clusters: ObjectID[]; // clusters that have been used for this particle. + tracks: ObjectID[]; // tracks that have been used for this particle. + particles: ObjectID[]; // reconstructed particles that have been combined to this particle. + particleIDs: ObjectID[]; // particle Ids (not sorted by their likelihood) + }; + + type TrackStateCollection = TrackState[]; + type VertexCollection = Vertex[]; + type TrackCollection = Track[]; + type TrackerHitCollection = TrackerHit[]; + type SimTrackerHitCollection = SimTrackerHit[]; + type CalorimeterHitCollection = CalorimeterHit[]; + type SimCalorimeterHitCollection = SimCalorimeterHit[]; + type ClusterCollection = Cluster[]; + type ReconstructedParticleCollection = ReconstructedParticle[]; +} diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema2.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema2.ts new file mode 100644 index 000000000..ab58c7de1 --- /dev/null +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema2.ts @@ -0,0 +1,161 @@ +import { + CovMatrix3f, + CovMatrix4f, + CovMatrix6f, + Vector2f, + Vector3f, + Vector3d, + ObjectID, +} from './utils'; + +export namespace Schema2 { + /** Parametrized description of a particle track */ + type TrackState = { + location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation + D0: number; // transverse impact parameter + phi: number; // azimuthal angle + omega: number; // [1/mm] is the signed curvature of the track + Z0: number; // longitudinal impact parameter + tanLambda: number; // lambda is the dip angle of the track in r-z + time: number; // [ns] time of the track at this trackstate + referencePoint: Vector3f; // [mm] Reference point of the track parameters, e.g. the origin at the IP, or the position of the first/last hits or the entry point into the calorimeter + covMatrix: CovMatrix6f; // covariance matrix of the track parameters. + }; + + /** Vertex */ + type Vertex = { + type: number; // Flagword that defines the type of the vertex, see reserved bits for more information + chi2: number; // chi-squared of the vertex fit + ndf: number; // number of degrees of freedom of the vertex fit + position: Vector3f; // [mm] position of the vertex + covMatrix: CovMatrix3f; // covariance matrix of the position + algorithmType: number; // type code for the algorithm that has been used to create the vertex + parameters: number[]; // additional parameters related to this vertex + particles: ObjectID[]; // particles that have been used to form this vertex, aka the decay particles emerging from this vertex + }; + + /** Reconstructed track */ + type Track = { + type: number; // flagword that defines the type of track + chi2: number; // Chi^2 of the track fit + ndf: number; // number of degrees of freedom of the track fit + Nholes: number; // number of holes on track + subdetectorHitNumbers: number[]; // number of hits in particular subdetectors + subdetectorHoleNumbers: number[]; // number of holes in particular subdetectors + trackStates: TrackState[]; // track states + trackerHits: ObjectID[]; // hits that have been used to create this track + tracks: ObjectID[]; // tracks (segments) that have been combined to create this track + }; + + /** Tracker hit interface class */ + // Types: TrackerHit3D, TrackerHitPlane + interface TrackerHit { + cellID: number; // ID of the sensor that created this hit + type: number; // type of the raw data hit + quality: number; // quality bit flag of the hit + time: number; // [ns] time of the hit + eDep: number; // [GeV] energy deposited on the hit + eDepError: number; // [GeV] error measured on eDep + position: Vector3d; // [mm] hit position + } + + /** Tracker hit */ + interface TrackerHit3D extends TrackerHit { + cellID: number; // ID of the sensor that created this hit + type: number; // type of raw data hit + quality: number; // quality bit flag of the hit + time: number; // [ns] time of the hit + eDep: number; // [GeV] energy deposited on the hit + eDepError: number; // [GeV] error measured on EDep + position: Vector3d; // [mm] hit position + covMatrix: CovMatrix3f; // covariance matrix of the position (x,y,z) + } + + /** Tracker hit plane */ + interface TrackerHitPlane extends TrackerHit { + cellID: number; // ID of the sensor that created this hit + type: number; // type of raw data hit + quality: number; // quality bit flag of the hit + time: number; // [ns] time of the hit + eDep: number; // [GeV] energy deposited on the hit + eDepError: number; // [GeV] error measured on EDep + u: Vector2f; // measurement direction vector, u lies in the x-y plane + v: Vector2f; // measurement direction vector, v is along z + du: number; // measurement error along the direction + dv: number; // measurement error along the direction + position: Vector3d; // [mm] hit position + covMatrix: CovMatrix3f; // covariance of the position (x,y,z) + } + + /** Simulated tracker hit */ + type SimTrackerHit = { + cellID: number; // ID of the sensor that created this hit + eDep: number; // [GeV] energy deposited in the hit + time: number; // [ns] proper time of the hit in the lab frame + pathLength: number; // path length of the particle in the sensitive material that resulted in this hit + quality: number; // quality bit flag + position: Vector3d; // [mm] the hit position + momentum: Vector3f; // [GeV] the 3-momentum of the particle at the hits position + particle: ObjectID; // MCParticle that caused the hit + }; + + /** Calorimeter hit */ + type CalorimeterHit = { + cellID: number; // detector specific (geometrical) cell id + energy: number; // [GeV] energy of the hit + energyError: number; // [GeV] error of the hit energy + time: number; // [ns] time of the hit + position: Vector3f; // [mm] position of the hit in world coordinates + type: number; // type of hit + }; + + /** Simulated calorimeter hit */ + type SimCalorimeterHit = { + cellID: number; // ID of the sensor that created this hit + energy: number; // [GeV] energy of the hit + position: Vector3f; // [mm] position of the hit in world coordinates + contributions: ObjectID[]; // Monte Carlo step contributions + }; + + /** Calorimeter Hit Cluster */ + type Cluster = { + type: number; // flagword that defines the type of cluster + energy: number; // [GeV] energy of the cluster + energyError: number; // [GeV] error on the energy + position: Vector3f; // [mm] position of the cluster + positionError: CovMatrix3f; // covariance matrix of the position + iTheta: number; // intrinsic direction of cluster at position Theta. Not to be confused with direction cluster is seen from IP + phi: number; // intrinsic direction of cluster at position - Phi. Not to be confused with direction cluster is seen from IP + directionError: Vector3f; // [mm**2] covariance matrix of the direction + shapeParameters: number[]; // shape parameters. This should be accompanied by a descriptive list of names in the shapeParameterNames collection level metadata, as a vector of strings with the same ordering + subdetectorEnergies: number[]; // energy observed in a particular subdetector + clusters: ObjectID[]; // clusters that have been combined to this cluster + hits: ObjectID[]; // hits that have been combined to this cluster + }; + + /** Reconstructed Particle */ + type ReconstructedParticle = { + PDG: number; // PDG of the reconstructed particle. + energy: number; // [GeV] energy of the reconstructed particle. Four momentum state is not kept consistent internally + momentum: Vector3f; // [GeV] particle momentum. Four momentum state is not kept consistent internally + referencePoint: Vector3f; // [mm] reference, i.e. where the particle has been measured + charge: number; // charge of the reconstructed particle + mass: number; // [GeV] mass of the reconstructed particle, set independently from four vector. Four momentum state is not kept consistent internally + goodnessOfPID: number; // overall goodness of the PID on a scale of [0;1] + covMatrix: CovMatrix4f; // covariance matrix of the reconstructed particle 4vector + decayVertex: ObjectID; // decay vertex for the particle (if it is a composite particle) + clusters: ObjectID[]; // clusters that have been used for this particle + tracks: ObjectID[]; // tracks that have been used for this particle + particles: ObjectID[]; // reconstructed particles that have been combined to this particle + }; + + type TrackStateCollection = TrackState[]; + type VertexCollection = Vertex[]; + type TrackCollection = Track[]; + type TrackerHitCollection = (TrackerHit3D | TrackerHitPlane)[]; + type SimTrackerHitCollection = SimTrackerHit[]; + type CalorimeterHitCollection = CalorimeterHit[]; + type SimCalorimeterHitCollection = SimCalorimeterHit[]; + type ClusterCollection = Cluster[]; + type ReconstructedParticleCollection = ReconstructedParticle[]; +} diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema3.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema3.ts new file mode 100644 index 000000000..7c81fdb77 --- /dev/null +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema3.ts @@ -0,0 +1,161 @@ +import { + CovMatrix3f, + CovMatrix4f, + CovMatrix6f, + Vector2f, + Vector3f, + Vector3d, + ObjectID, +} from './utils'; + +export namespace Schema3 { + /** Parametrized description of a particle track */ + type TrackState = { + location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation + D0: number; // transverse impact parameter + phi: number; // [rad] azimuthal angle of the track at this location (i.e. not phi0) + omega: number; // [1/mm] is the signed curvature of the track + Z0: number; // longitudinal impact parameter + tanLambda: number; // lambda is the dip angle of the track in r-z + time: number; // [ns] time of the track at this trackstate + referencePoint: Vector3f; // [mm] Reference point of the track parameters, e.g. the origin at the IP, or the position of the first/last hits or the entry point into the calorimeter + covMatrix: CovMatrix6f; // covariance matrix of the track parameters. + }; + + /** Vertex */ + type Vertex = { + type: number; // flagword that defines the type of the vertex, see reserved bits for more information + chi2: number; // chi-squared of the vertex fit + ndf: number; // number of degrees of freedom of the vertex fit + position: Vector3f; // [mm] position of the vertex + covMatrix: CovMatrix3f; // [mm^2] covariance matrix of the position + algorithmType: number; // type code for the algorithm that has been used to create the vertex + parameters: number[]; // additional parameters related to this vertex + particles: ObjectID[]; // particles that have been used to form this vertex, aka the decay particles emerging from this vertex + }; + + /** Reconstructed track */ + type Track = { + type: number; // flagword that defines the type of track + chi2: number; // chi-squared of the track fit + ndf: number; // number of degrees of freedom of the track fit + Nholes: number; // number of holes on track + subdetectorHitNumbers: number[]; // number of hits in particular subdetectors + subdetectorHoleNumbers: number[]; // number of holes in particular subdetectors + trackStates: TrackState[]; // track states + trackerHits: ObjectID[]; // hits that have been used to create this track + tracks: ObjectID[]; // tracks (segments) that have been combined to create this track + }; + + /** Tracker hit interface class */ + // Types: TrackerHit3D, TrackerHitPlane + interface TrackerHit { + cellID: number; // ID of the sensor that created this hit + type: number; // type of the raw data hit + quality: number; // quality bit flag of the hit + time: number; // [ns] time of the hit + eDep: number; // [GeV] energy deposited on the hit + eDepError: number; // [GeV] error measured on eDep + position: Vector3d; // [mm] hit position + } + + /** Tracker hit */ + interface TrackerHit3D extends TrackerHit { + cellID: number; // ID of the sensor that created this hit + type: number; // type of raw data hit + quality: number; // quality bit flag of the hit + time: number; // [ns] time of the hit + eDep: number; // [GeV] energy deposited on the hit + eDepError: number; // [GeV] error measured on eDep + position: Vector3d; // [mm] hit position + covMatrix: CovMatrix3f; // [mm^2] covariance matrix of the position (x,y,z) + } + + /** Tracker hit plane */ + interface TrackerHitPlane extends TrackerHit { + cellID: number; // ID of the sensor that created this hit + type: number; // type of raw data hit + quality: number; // quality bit flag of the hit + time: number; // [ns] time of the hit + eDep: number; // [GeV] energy deposited on the hit + eDepError: number; // [GeV] error measured on eDep + u: Vector2f; // measurement direction vector, u lies in the x-y plane + v: Vector2f; // measurement direction vector, v is along z + du: number; // measurement error along the direction + dv: number; // measurement error along the direction + position: Vector3d; // [mm] hit position + covMatrix: CovMatrix3f; // [mm^2] covariance of the position (x,y,z) + } + + /** Simulated tracker hit */ + type SimTrackerHit = { + cellID: number; // ID of the sensor that created this hit + eDep: number; // [GeV] energy deposited in the hit + time: number; // [ns] proper time of the hit in the lab frame + pathLength: number; // path length of the particle in the sensitive material that resulted in this hit + quality: number; // quality bit flag + position: Vector3d; // [mm] the hit position + momentum: Vector3f; // [GeV] the 3-momentum of the particle at the hits position + particle: ObjectID; // MCParticle that caused the hit + }; + + /** Calorimeter hit */ + type CalorimeterHit = { + cellID: number; // detector specific (geometrical) cell id + energy: number; // [GeV] energy of the hit + energyError: number; // [GeV] error of the hit energy + time: number; // [ns] time of the hit + position: Vector3f; // [mm] position of the hit in world coordinates + type: number; // type of hit + }; + + /** Simulated calorimeter hit */ + type SimCalorimeterHit = { + cellID: number; // ID of the sensor that created this hit + energy: number; // [GeV] energy of the hit + position: Vector3f; // [mm] position of the hit in world coordinates + contributions: ObjectID[]; // Monte Carlo step contributions + }; + + /** Calorimeter Hit Cluster */ + type Cluster = { + type: number; // flagword that defines the type of cluster + energy: number; // [GeV] energy of the cluster + energyError: number; // [GeV] error on the energy + position: Vector3f; // [mm] position of the cluster + positionError: CovMatrix3f; // [mm^2] covariance matrix of the position + iTheta: number; // [rad] Polar angle of the cluster's intrinsic direction (used e.g. for vertexing). Not to be confused with the cluster position seen from IP + phi: number; // [rad] Azimuthal angle of the cluster's intrinsic direction (used e.g. for vertexing). Not to be confused with the cluster position seen from IP + directionError: Vector3f; // [mm^2] covariance matrix of the direction + shapeParameters: number[]; // shape parameters. This should be accompanied by a descriptive list of names in the shapeParameterNames collection level metadata, as a vector of strings with the same ordering + subdetectorEnergies: number[]; // energy observed in a particular subdetector + clusters: ObjectID[]; // clusters that have been combined to this cluster + hits: ObjectID[]; // hits that have been combined to this cluster + }; + + /** Reconstructed Particle */ + type ReconstructedParticle = { + PDG: number; // PDG of the reconstructed particle. + energy: number; // [GeV] energy of the reconstructed particle. Four momentum state is not kept consistent internally + momentum: Vector3f; // [GeV] particle momentum. Four momentum state is not kept consistent internally + referencePoint: Vector3f; // [mm] reference, i.e. where the particle has been measured + charge: number; // [e] charge of the reconstructed particle + mass: number; // [GeV] mass of the reconstructed particle, set independently from four vector. Four momentum state is not kept consistent internally + goodnessOfPID: number; // overall goodness of the PID on a scale of [0;1] + covMatrix: CovMatrix4f; // [GeV^2] covariance matrix of the reconstructed particle 4vector + decayVertex: ObjectID; // decay vertex for the particle (if it is a composite particle) + clusters: ObjectID[]; // clusters that have been used for this particle + tracks: ObjectID[]; // tracks that have been used for this particle + particles: ObjectID[]; // reconstructed particles that have been combined to this particle + }; + + type TrackStateCollection = TrackState[]; + type VertexCollection = Vertex[]; + type TrackCollection = Track[]; + type TrackerHitCollection = (TrackerHit3D | TrackerHitPlane)[]; + type SimTrackerHitCollection = SimTrackerHit[]; + type CalorimeterHitCollection = CalorimeterHit[]; + type SimCalorimeterHitCollection = SimCalorimeterHit[]; + type ClusterCollection = Cluster[]; + type ReconstructedParticleCollection = ReconstructedParticle[]; +} diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema4.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema4.ts new file mode 100644 index 000000000..629a323a5 --- /dev/null +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema4.ts @@ -0,0 +1,161 @@ +import { + CovMatrix3f, + CovMatrix4f, + CovMatrix6f, + Vector2f, + Vector3f, + Vector3d, + ObjectID, +} from './utils'; + +export namespace Schema4 { + /** Parametrized description of a particle track */ + interface TrackState { + location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation + D0: number; // transverse impact parameter + phi: number; // [rad] azimuthal angle of the track at this location (i.e. not phi0) + omega: number; // [1/mm] is the signed curvature of the track + Z0: number; // longitudinal impact parameter + tanLambda: number; // lambda is the dip angle of the track in r-z + time: number; // [ns] time of the track at this trackstate + referencePoint: Vector3f; // [mm] Reference point of the track parameters, e.g. the origin at the IP, or the position of the first/last hits or the entry point into the calorimeter + covMatrix: CovMatrix6f; // covariance matrix of the track parameters. + } + + /** Vertex */ + interface Vertex { + type: number; // flagword that defines the type of the vertex, see reserved bits for more information + chi2: number; // chi-squared of the vertex fit + ndf: number; // number of degrees of freedom of the vertex fit + position: Vector3f; // [mm] position of the vertex + covMatrix: CovMatrix3f; // [mm^2] covariance matrix of the position + algorithmType: number; // type code for the algorithm that has been used to create the vertex + parameters: number[]; // additional parameters related to this vertex + particles: ObjectID[]; // particles that have been used to form this vertex, aka the decay particles emerging from this vertex + } + + /** Reconstructed track */ + interface Track { + type: number; // flagword that defines the type of track + chi2: number; // chi-squared of the track fit + ndf: number; // number of degrees of freedom of the track fit + Nholes: number; // number of holes on track + subdetectorHitNumbers: number[]; // number of hits in particular subdetectors + subdetectorHoleNumbers: number[]; // number of holes in particular subdetectors + trackStates: TrackState[]; // track states + trackerHits: ObjectID[]; // hits that have been used to create this track + tracks: ObjectID[]; // tracks (segments) that have been combined to create this track + } + + /** Tracker hit interface class */ + // Types: TrackerHit3D, TrackerHitPlane + interface TrackerHit { + cellID: number; // ID of the sensor that created this hit + type: number; // type of the raw data hit + quality: number; // quality bit flag of the hit + time: number; // [ns] time of the hit + eDep: number; // [GeV] energy deposited on the hit + eDepError: number; // [GeV] error measured on eDep + position: Vector3d; // [mm] hit position + } + + /** Tracker hit */ + interface TrackerHit3D extends TrackerHit { + cellID: number; // ID of the sensor that created this hit + type: number; // type of raw data hit + quality: number; // quality bit flag of the hit + time: number; // [ns] time of the hit + eDep: number; // [GeV] energy deposited on the hit + eDepError: number; // [GeV] error measured on eDep + position: Vector3d; // [mm] hit position + covMatrix: CovMatrix3f; // [mm^2] covariance matrix of the position (x,y,z) + } + + /** Tracker hit plane */ + interface TrackerHitPlane { + cellID: number; // ID of the sensor that created this hit + type: number; // type of raw data hit + quality: number; // quality bit flag of the hit + time: number; // [ns] time of the hit + eDep: number; // [GeV] energy deposited on the hit + eDepError: number; // [GeV] error measured on eDep + u: Vector2f; // measurement direction vector, u lies in the x-y plane + v: Vector2f; // measurement direction vector, v is along z + du: number; // measurement error along the direction + dv: number; // measurement error along the direction + position: Vector3d; // [mm] hit position + covMatrix: CovMatrix3f; // [mm^2] covariance of the position (x,y,z) + } + + /** Simulated tracker hit */ + interface SimTrackerHit { + cellID: number; // ID of the sensor that created this hit + eDep: number; // [GeV] energy deposited in the hit + time: number; // [ns] proper time of the hit in the lab frame + pathLength: number; // path length of the particle in the sensitive material that resulted in this hit + quality: number; // quality bit flag + position: Vector3d; // [mm] the hit position + momentum: Vector3f; // [GeV] the 3-momentum of the particle at the hits position + particle: ObjectID; // MCParticle that caused the hit + } + + /** Calorimeter hit */ + interface CalorimeterHit { + cellID: number; // detector specific (geometrical) cell id + energy: number; // [GeV] energy of the hit + energyError: number; // [GeV] error of the hit energy + time: number; // [ns] time of the hit + position: Vector3f; // [mm] position of the hit in world coordinates + type: number; // type of hit + } + + /** Simulated calorimeter hit */ + interface SimCalorimeterHit { + cellID: number; // ID of the sensor that created this hit + energy: number; // [GeV] energy of the hit + position: Vector3f; // [mm] position of the hit in world coordinates + contributions: ObjectID[]; // Monte Carlo step contributions + } + + /** Calorimeter Hit Cluster */ + interface Cluster { + type: number; // flagword that defines the type of cluster + energy: number; // [GeV] energy of the cluster + energyError: number; // [GeV] error on the energy + position: Vector3f; // [mm] position of the cluster + positionError: CovMatrix3f; // [mm^2] covariance matrix of the position + iTheta: number; // [rad] Polar angle of the cluster's intrinsic direction (used e.g. for vertexing). Not to be confused with the cluster position seen from IP + phi: number; // [rad] Azimuthal angle of the cluster's intrinsic direction (used e.g. for vertexing). Not to be confused with the cluster position seen from IP + directionError: Vector3f; // [mm^2] covariance matrix of the direction + shapeParameters: number[]; // shape parameters. The corresponding names of the shape parameters should be stored in the collection named by edm4hep::labels::ShapeParameterNames in the file-level metadata, as a vector of strings in the same order as the parameters. + subdetectorEnergies: number[]; // energy observed in a particular subdetector + clusters: ObjectID[]; // clusters that have been combined to this cluster + hits: ObjectID[]; // hits that have been combined to this cluster + } + + /** Reconstructed Particle */ + interface ReconstructedParticle { + PDG: number; // PDG of the reconstructed particle. + energy: number; // [GeV] energy of the reconstructed particle. Four momentum state is not kept consistent internally + momentum: Vector3f; // [GeV] particle momentum. Four momentum state is not kept consistent internally + referencePoint: Vector3f; // [mm] reference, i.e. where the particle has been measured + charge: number; // [e] charge of the reconstructed particle + mass: number; // [GeV] mass of the reconstructed particle, set independently from four vector. Four momentum state is not kept consistent internally + goodnessOfPID: number; // overall goodness of the PID on a scale of [0;1] + covMatrix: CovMatrix4f; // [GeV^2] covariance matrix of the reconstructed particle 4vector + decayVertex: ObjectID; // decay vertex for the particle (if it is a composite particle) + clusters: ObjectID[]; // clusters that have been used for this particle + tracks: ObjectID[]; // tracks that have been used for this particle + particles: ObjectID[]; // reconstructed particles that have been combined to this particle + } + + type TrackStateCollection = TrackState[]; + type VertexCollection = Vertex[]; + type TrackCollection = Track[]; + type TrackerHitCollection = (TrackerHit3D | TrackerHitPlane)[]; + type SimTrackerHitCollection = SimTrackerHit[]; + type CalorimeterHitCollection = CalorimeterHit[]; + type SimCalorimeterHitCollection = SimCalorimeterHit[]; + type ClusterCollection = Cluster[]; + type ReconstructedParticleCollection = ReconstructedParticle[]; +} diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema5.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema5.ts new file mode 100644 index 000000000..6e576c936 --- /dev/null +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema5.ts @@ -0,0 +1,178 @@ +import { + CovMatrix3f, + CovMatrix4f, + CovMatrix6f, + Vector2f, + Vector3f, + Vector3d, + ObjectID, +} from './utils'; + +export namespace Schema5 { + /** Parametrized description of a particle track */ + interface TrackState { + location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation + D0: number; // transverse impact parameter + phi: number; // [rad] azimuthal angle of the track at this location (i.e. not phi0) + omega: number; // [1/mm] is the signed curvature of the track + Z0: number; // longitudinal impact parameter + tanLambda: number; // lambda is the dip angle of the track in r-z + time: number; // [ns] time of the track at this trackstate + referencePoint: Vector3f; // [mm] Reference point of the track parameters, e.g. the origin at the IP, or the position of the first/last hits or the entry point into the calorimeter + covMatrix: CovMatrix6f; // covariance matrix of the track parameters. + } + + /** Vertex */ + interface Vertex { + type: number; // flagword that defines the type of the vertex, see reserved bits for more information + chi2: number; // chi-squared of the vertex fit + ndf: number; // number of degrees of freedom of the vertex fit + position: Vector3f; // [mm] position of the vertex + covMatrix: CovMatrix3f; // [mm^2] covariance matrix of the position + algorithmType: number; // type code for the algorithm that has been used to create the vertex + parameters: number[]; // additional parameters related to this vertex + particles: ObjectID[]; // particles that have been used to form this vertex, aka the decay particles emerging from this vertex + } + + /** Reconstructed track */ + interface Track { + type: number; // flagword that defines the type of track + chi2: number; // chi-squared of the track fit + ndf: number; // number of degrees of freedom of the track fit + Nholes: number; // number of holes on track + subdetectorHitNumbers: number[]; // number of hits in particular subdetectors + subdetectorHoleNumbers: number[]; // number of holes in particular subdetectors + trackStates: TrackState[]; // track states + trackerHits: ObjectID[]; // hits that have been used to create this track + tracks: ObjectID[]; // tracks (segments) that have been combined to create this track + } + + /** Tracker hit interface class */ + // Types: TrackerHit3D, TrackerHitPlane, SenseWireHit + interface TrackerHit { + cellID: number; // ID of the sensor that created this hit + type: number; // type of the raw data hit + quality: number; // quality bit flag of the hit + time: number; // [ns] time of the hit + eDep: number; // [GeV] energy deposited on the hit + eDepError: number; // [GeV] error measured on eDep + position: Vector3d; // [mm] hit position as recorded by the sensor. The exact interpretation will depend on the currently held type of the interface + } + + /** Tracker hit */ + interface TrackerHit3D extends TrackerHit { + cellID: number; // ID of the sensor that created this hit + type: number; // type of raw data hit + quality: number; // quality bit flag of the hit + time: number; // [ns] time of the hit + eDep: number; // [GeV] energy deposited on the hit + eDepError: number; // [GeV] error measured on eDep + position: Vector3d; // [mm] hit position + covMatrix: CovMatrix3f; // [mm^2] covariance matrix of the position (x,y,z) + } + + /** Tracker hit plane */ + interface TrackerHitPlane extends TrackerHit { + cellID: number; // ID of the sensor that created this hit + type: number; // type of raw data hit + quality: number; // quality bit flag of the hit + time: number; // [ns] time of the hit + eDep: number; // [GeV] energy deposited on the hit + eDepError: number; // [GeV] error measured on eDep + u: Vector2f; // [rad] direction of the first measurement given as (theta, phi) in spherical coordinates + v: Vector2f; // [rad] direction of the second measurement given as (theta, phi) in spherical coordinates + du: number; // [mm] measurement error along the direction + dv: number; // [mm] measurement error along the direction + position: Vector3d; // [mm] hit position + covMatrix: CovMatrix3f; // [mm^2] covariance of the position (x,y,z) + } + + /** Sense wire hit, knowing only the distance to the wire. The circle representing possible positions is parametrized with its center, radius and normal vector (given by the wire direction). */ + interface SenseWireHit extends TrackerHit { + cellID: number; // ID of the sensor that created this hit + type: number; // type of the raw data hit + quality: number; // quality bit flag of the hit + time: number; // [ns] time of the hit + eDep: number; // [GeV] energy deposited by the hit + eDepError: number; // [GeV] error on eDep + wireStereoAngle: number; // angle between the sense wire axis and the drift chamber axis (usually the z-axis) - use it together with wireAzimuthalAngle to get the wire direction + wireAzimuthalAngle: number; // azimuthal angle at the middle of the sense wire - use it together with wireStereoAngle to get the wire direction + position: Vector3d; // [mm] point on the sense wire which is closest to the hit (center of the circle) + positionAlongWireError: number; // [mm] error on the hit position along the wire direction + distanceToWire: number; // [mm] distance between the hit and the wire (radius of the circle) + distanceToWireError: number; // [mm] error on distanceToWire + nElectrons: number[]; // number of electrons for each cluster (number of clusters = vector size) + } + + /** Simulated tracker hit */ + interface SimTrackerHit { + cellID: number; // ID of the sensor that created this hit + eDep: number; // [GeV] energy deposited in the hit + time: number; // [ns] proper time of the hit in the lab frame + pathLength: number; // path length of the particle in the sensitive material that resulted in this hit + quality: number; // quality bit flag + position: Vector3d; // [mm] the hit position + momentum: Vector3f; // [GeV] the 3-momentum of the particle at the hits position + particle: ObjectID; // MCParticle that caused the hit + } + + /** Calorimeter hit */ + interface CalorimeterHit { + cellID: number; // detector specific (geometrical) cell id + energy: number; // [GeV] energy of the hit + energyError: number; // [GeV] error of the hit energy + time: number; // [ns] time of the hit + position: Vector3f; // [mm] position of the hit in world coordinates + type: number; // type of hit + } + + /** Simulated calorimeter hit */ + interface SimCalorimeterHit { + cellID: number; // ID of the sensor that created this hit + energy: number; // [GeV] energy of the hit + position: Vector3f; // [mm] position of the hit in world coordinates + contributions: ObjectID[]; // Monte Carlo step contributions + } + + /** Calorimeter Hit Cluster */ + interface Cluster { + type: number; // flagword that defines the type of cluster + energy: number; // [GeV] energy of the cluster + energyError: number; // [GeV] error on the energy + position: Vector3f; // [mm] position of the cluster + positionError: CovMatrix3f; // [mm^2] covariance matrix of the position + iTheta: number; // [rad] Polar angle of the cluster's intrinsic direction (used e.g. for vertexing). Not to be confused with the cluster position seen from IP + phi: number; // [rad] Azimuthal angle of the cluster's intrinsic direction (used e.g. for vertexing). Not to be confused with the cluster position seen from IP + directionError: Vector3f; // [mm^2] covariance matrix of the direction + shapeParameters: number[]; // shape parameters. The corresponding names of the shape parameters should be stored in the collection named by edm4hep::labels::ShapeParameterNames in the file-level metadata, as a vector of strings in the same order as the parameters. + subdetectorEnergies: number[]; // energy observed in a particular subdetector + clusters: ObjectID[]; // clusters that have been combined to this cluster + hits: ObjectID[]; // hits that have been combined to this cluster + } + + /** Reconstructed Particle */ + interface ReconstructedParticle { + PDG: number; // PDG of the reconstructed particle. + energy: number; // [GeV] energy of the reconstructed particle. Four momentum state is not kept consistent internally + momentum: Vector3f; // [GeV] particle momentum. Four momentum state is not kept consistent internally + referencePoint: Vector3f; // [mm] reference, i.e. where the particle has been measured + charge: number; // [e] charge of the reconstructed particle + mass: number; // [GeV] mass of the reconstructed particle, set independently from four vector. Four momentum state is not kept consistent internally + goodnessOfPID: number; // overall goodness of the PID on a scale of [0;1] + covMatrix: CovMatrix4f; // [GeV^2] covariance matrix of the reconstructed particle 4vector + decayVertex: ObjectID; // decay vertex for the particle (if it is a composite particle) + clusters: ObjectID[]; // clusters that have been used for this particle + tracks: ObjectID[]; // tracks that have been used for this particle + particles: ObjectID[]; // reconstructed particles that have been combined to this particle + } + + type TrackStateCollection = TrackState[]; + type VertexCollection = Vertex[]; + type TrackCollection = Track[]; + type TrackerHitCollection = (TrackerHit3D | TrackerHitPlane | SenseWireHit)[]; + type SimTrackerHitCollection = SimTrackerHit[]; + type CalorimeterHitCollection = CalorimeterHit[]; + type SimCalorimeterHitCollection = SimCalorimeterHit[]; + type ClusterCollection = Cluster[]; + type ReconstructedParticleCollection = ReconstructedParticle[]; +} diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema6.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema6.ts new file mode 100644 index 000000000..d8abe44a1 --- /dev/null +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema6.ts @@ -0,0 +1,178 @@ +import { + CovMatrix3f, + CovMatrix4f, + CovMatrix6f, + Vector2f, + Vector3f, + Vector3d, + ObjectID, +} from './utils'; + +export namespace Schema6 { + /** Parametrized description of a particle track */ + interface TrackState { + location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation + D0: number; // transverse impact parameter + phi: number; // [rad] azimuthal angle of the track at this location (i.e. not phi0) + omega: number; // [1/mm] is the signed curvature of the track + Z0: number; // longitudinal impact parameter + tanLambda: number; // lambda is the dip angle of the track in r-z + time: number; // [ns] time of the track at this trackstate + referencePoint: Vector3f; // [mm] Reference point of the track parameters, e.g. the origin at the IP, or the position of the first/last hits or the entry point into the calorimeter + covMatrix: CovMatrix6f; // covariance matrix of the track parameters. + } + + /** Vertex */ + interface Vertex { + type: number; // flagword that defines the type of the vertex, see reserved bits for more information + chi2: number; // chi-squared of the vertex fit + ndf: number; // number of degrees of freedom of the vertex fit + position: Vector3f; // [mm] position of the vertex + covMatrix: CovMatrix3f; // [mm^2] covariance matrix of the position + algorithmType: number; // type code for the algorithm that has been used to create the vertex + parameters: number[]; // additional parameters related to this vertex + particles: ObjectID[]; // particles that have been used to form this vertex, aka the decay particles emerging from this vertex + } + + /** Reconstructed track */ + interface Track { + type: number; // flagword that defines the type of track + chi2: number; // chi-squared of the track fit + ndf: number; // number of degrees of freedom of the track fit + Nholes: number; // number of holes on track + subdetectorHitNumbers: number[]; // number of hits in particular subdetectors + subdetectorHoleNumbers: number[]; // number of holes in particular subdetectors + trackStates: TrackState[]; // track states + trackerHits: ObjectID[]; // hits that have been used to create this track + tracks: ObjectID[]; // tracks (segments) that have been combined to create this track + } + + /** Tracker hit interface class */ + // Types: TrackerHit3D, TrackerHitPlane, SenseWireHit + interface TrackerHit { + cellID: number; // ID of the sensor that created this hit + type: number; // type of the raw data hit + quality: number; // quality bit flag of the hit + time: number; // [ns] time of the hit + eDep: number; // [GeV] energy deposited on the hit + eDepError: number; // [GeV] error measured on eDep + position: Vector3d; // [mm] hit position as recorded by the sensor. The exact interpretation will depend on the currently held type of the interface + } + + /** Tracker hit */ + interface TrackerHit3D extends TrackerHit { + cellID: number; // ID of the sensor that created this hit + type: number; // type of raw data hit + quality: number; // quality bit flag of the hit + time: number; // [ns] time of the hit + eDep: number; // [GeV] energy deposited on the hit + eDepError: number; // [GeV] error measured on eDep + position: Vector3d; // [mm] hit position + covMatrix: CovMatrix3f; // [mm^2] covariance matrix of the position (x,y,z) + } + + /** Tracker hit plane */ + interface TrackerHitPlane extends TrackerHit { + cellID: number; // ID of the sensor that created this hit + type: number; // type of raw data hit + quality: number; // quality bit flag of the hit + time: number; // [ns] time of the hit + eDep: number; // [GeV] energy deposited on the hit + eDepError: number; // [GeV] error measured on eDep + u: Vector2f; // [rad] direction of the first measurement given as (theta, phi) in spherical coordinates + v: Vector2f; // [rad] direction of the second measurement given as (theta, phi) in spherical coordinates + du: number; // [mm] measurement error along the direction + dv: number; // [mm] measurement error along the direction + position: Vector3d; // [mm] hit position + covMatrix: CovMatrix3f; // [mm^2] covariance of the position (x,y,z) + } + + /** Sense wire hit, knowing only the distance to the wire. The circle representing possible positions is parametrized with its center, radius and normal vector (given by the wire direction). */ + interface SenseWireHit extends TrackerHit { + cellID: number; // ID of the sensor that created this hit + type: number; // type of the raw data hit + quality: number; // quality bit flag of the hit + time: number; // [ns] time of the hit + eDep: number; // [GeV] energy deposited by the hit + eDepError: number; // [GeV] error on eDep + wireStereoAngle: number; // angle between the sense wire axis and the drift chamber axis (usually the z-axis) - use it together with wireAzimuthalAngle to get the wire direction + wireAzimuthalAngle: number; // azimuthal angle at the middle of the sense wire - use it together with wireStereoAngle to get the wire direction + position: Vector3d; // [mm] point on the sense wire which is closest to the hit (center of the circle) + positionAlongWireError: number; // [mm] error on the hit position along the wire direction + distanceToWire: number; // [mm] distance between the hit and the wire (radius of the circle) + distanceToWireError: number; // [mm] error on distanceToWire + nElectrons: number[]; // number of electrons for each cluster (number of clusters = vector size) + } + + /** Simulated tracker hit */ + interface SimTrackerHit { + cellID: number; // ID of the sensor that created this hit + eDep: number; // [GeV] energy deposited in the hit + time: number; // [ns] proper time of the hit in the lab frame + pathLength: number; // path length of the particle in the sensitive material that resulted in this hit + quality: number; // quality bit flag + position: Vector3d; // [mm] the hit position + momentum: Vector3f; // [GeV] the 3-momentum of the particle at the hits position + particle: ObjectID; // MCParticle that caused the hit + } + + /** Calorimeter hit */ + interface CalorimeterHit { + cellID: number; // detector specific (geometrical) cell id + energy: number; // [GeV] energy of the hit + energyError: number; // [GeV] error of the hit energy + time: number; // [ns] time of the hit + position: Vector3f; // [mm] position of the hit in world coordinates + type: number; // type of hit + } + + /** Simulated calorimeter hit */ + interface SimCalorimeterHit { + cellID: number; // ID of the sensor that created this hit + energy: number; // [GeV] energy of the hit + position: Vector3f; // [mm] position of the hit in world coordinates + contributions: ObjectID[]; // Monte Carlo step contributions + } + + /** Calorimeter Hit Cluster */ + interface Cluster { + type: number; // flagword that defines the type of cluster + energy: number; // [GeV] energy of the cluster + energyError: number; // [GeV] error on the energy + position: Vector3f; // [mm] position of the cluster + positionError: CovMatrix3f; // [mm^2] covariance matrix of the position + iTheta: number; // [rad] Polar angle of the cluster's intrinsic direction (used e.g. for vertexing). Not to be confused with the cluster position seen from IP + iPhi: number; // [rad] Azimuthal angle of the cluster's intrinsic direction (used e.g. for vertexing). Not to be confused with the cluster position seen from IP + directionError: Vector3f; // [mm^2] covariance matrix of the direction + shapeParameters: number[]; // shape parameters. The corresponding names of the shape parameters should be stored in the collection named by edm4hep::labels::ShapeParameterNames in the file-level metadata, as a vector of strings in the same order as the parameters. + subdetectorEnergies: number[]; // energy observed in a particular subdetector + clusters: ObjectID[]; // clusters that have been combined to this cluster + hits: ObjectID[]; // hits that have been combined to this cluster + } + + /** Reconstructed Particle */ + interface ReconstructedParticle { + PDG: number; // PDG of the reconstructed particle. + energy: number; // [GeV] energy of the reconstructed particle. Four momentum state is not kept consistent internally + momentum: Vector3f; // [GeV] particle momentum. Four momentum state is not kept consistent internally + referencePoint: Vector3f; // [mm] reference, i.e. where the particle has been measured + charge: number; // [e] charge of the reconstructed particle + mass: number; // [GeV] mass of the reconstructed particle, set independently from four vector. Four momentum state is not kept consistent internally + goodnessOfPID: number; // overall goodness of the PID on a scale of [0;1] + covMatrix: CovMatrix4f; // [GeV^2] covariance matrix of the reconstructed particle 4vector + decayVertex: ObjectID; // decay vertex for the particle (if it is a composite particle) + clusters: ObjectID[]; // clusters that have been used for this particle + tracks: ObjectID[]; // tracks that have been used for this particle + particles: ObjectID[]; // reconstructed particles that have been combined to this particle + } + + type TrackStateCollection = TrackState[]; + type VertexCollection = Vertex[]; + type TrackCollection = Track[]; + type TrackerHitCollection = (TrackerHit3D | TrackerHitPlane | SenseWireHit)[]; + type SimTrackerHitCollection = SimTrackerHit[]; + type CalorimeterHitCollection = CalorimeterHit[]; + type SimCalorimeterHitCollection = SimCalorimeterHit[]; + type ClusterCollection = Cluster[]; + type ReconstructedParticleCollection = ReconstructedParticle[]; +} diff --git a/packages/phoenix-event-display/src/lib/types/schemas/utils.ts b/packages/phoenix-event-display/src/lib/types/schemas/utils.ts new file mode 100644 index 000000000..31c68cd1b --- /dev/null +++ b/packages/phoenix-event-display/src/lib/types/schemas/utils.ts @@ -0,0 +1,36 @@ +/** A generic 3 dimensional covariance matrix with values stored in lower triangular form */ +export type CovMatrix3f = { + values: number[]; // the covariance matrix values +}; + +/** A generic 4 dimensional covariance matrix with values stored in lower triangular form */ +export type CovMatrix4f = { + values: number[]; // the covariance matrix values +}; + +/** A generic 6 dimensional covariance matrix with values stored in lower triangular form */ +export type CovMatrix6f = { + values: number[]; // the covariance matrix values +}; + +export type Vector2f = { + a: number; + b: number; +}; + +export type Vector3f = { + x: number; + y: number; + z: number; +}; + +export type Vector3d = { + x: number; + y: number; + z: number; +}; + +export type ObjectID = { + collectionID: number; + index: number; +}; From ea101d3f25c815cb2da5fe63cbbebd0ef78eddba Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Mon, 2 Mar 2026 15:30:23 +0100 Subject: [PATCH 04/30] Move schema types folder and fix bigint support --- .../lib/types/schemas/schema1.ts | 8 ++++---- .../lib/types/schemas/schema2.ts | 12 ++++++------ .../lib/types/schemas/schema3.ts | 12 ++++++------ .../lib/types/schemas/schema4.ts | 12 ++++++------ .../lib/types/schemas/schema5.ts | 14 +++++++------- .../lib/types/schemas/schema6.ts | 14 +++++++------- .../lib/types/schemas/utils.ts | 0 7 files changed, 36 insertions(+), 36 deletions(-) rename packages/{phoenix-event-display/src => phoenix-ng/projects/phoenix-ui-components}/lib/types/schemas/schema1.ts (96%) rename packages/{phoenix-event-display/src => phoenix-ng/projects/phoenix-ui-components}/lib/types/schemas/schema2.ts (95%) rename packages/{phoenix-event-display/src => phoenix-ng/projects/phoenix-ui-components}/lib/types/schemas/schema3.ts (95%) rename packages/{phoenix-event-display/src => phoenix-ng/projects/phoenix-ui-components}/lib/types/schemas/schema4.ts (95%) rename packages/{phoenix-event-display/src => phoenix-ng/projects/phoenix-ui-components}/lib/types/schemas/schema5.ts (95%) rename packages/{phoenix-event-display/src => phoenix-ng/projects/phoenix-ui-components}/lib/types/schemas/schema6.ts (95%) rename packages/{phoenix-event-display/src => phoenix-ng/projects/phoenix-ui-components}/lib/types/schemas/utils.ts (100%) diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema1.ts b/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema1.ts similarity index 96% rename from packages/phoenix-event-display/src/lib/types/schemas/schema1.ts rename to packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema1.ts index 106dfdfd6..1a52f2ec7 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema1.ts +++ b/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema1.ts @@ -46,7 +46,7 @@ export namespace Schema1 { /** Tracker hit */ type TrackerHit = { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit, either one of edm4hep::RawTimeSeries, edm4hep::SIMTRACKERHIT - see collection parameters "TrackerHitTypeNames" and "TrackerHitTypeValues". quality: number; // quality bit flag of the hit. time: number; // time of the hit [ns]. @@ -59,7 +59,7 @@ export namespace Schema1 { /** Simulated tracker hit */ type SimTrackerHit = { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit EDep: number; // energy deposited in the hit [GeV]. time: number; // proper time of the hit in the lab frame in [ns]. pathLength: number; // path length of the particle in the sensitive material that resulted in this hit. @@ -71,7 +71,7 @@ export namespace Schema1 { /** Calorimeter hit */ type CalorimeterHit = { - cellID: number; // detector specific (geometrical) cell id. + cellID: bigint; // detector specific (geometrical) cell id. energy: number; // energy of the hit in [GeV]. energyError: number; // error of the hit energy in [GeV]. time: number; // time of the hit in [ns]. @@ -81,7 +81,7 @@ export namespace Schema1 { /** Simulated calorimeter hit */ type SimCalorimeterHit = { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit energy: number; // energy of the hit in [GeV]. position: Vector3f; // position of the hit in world coordinates in [mm]. contributions: ObjectID[]; // Monte Carlo step contribution - parallel to particle diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema2.ts b/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema2.ts similarity index 95% rename from packages/phoenix-event-display/src/lib/types/schemas/schema2.ts rename to packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema2.ts index ab58c7de1..f30415b53 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema2.ts +++ b/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema2.ts @@ -50,7 +50,7 @@ export namespace Schema2 { /** Tracker hit interface class */ // Types: TrackerHit3D, TrackerHitPlane interface TrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit type: number; // type of the raw data hit quality: number; // quality bit flag of the hit time: number; // [ns] time of the hit @@ -61,7 +61,7 @@ export namespace Schema2 { /** Tracker hit */ interface TrackerHit3D extends TrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit time: number; // [ns] time of the hit @@ -73,7 +73,7 @@ export namespace Schema2 { /** Tracker hit plane */ interface TrackerHitPlane extends TrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit time: number; // [ns] time of the hit @@ -89,7 +89,7 @@ export namespace Schema2 { /** Simulated tracker hit */ type SimTrackerHit = { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit eDep: number; // [GeV] energy deposited in the hit time: number; // [ns] proper time of the hit in the lab frame pathLength: number; // path length of the particle in the sensitive material that resulted in this hit @@ -101,7 +101,7 @@ export namespace Schema2 { /** Calorimeter hit */ type CalorimeterHit = { - cellID: number; // detector specific (geometrical) cell id + cellID: bigint; // detector specific (geometrical) cell id energy: number; // [GeV] energy of the hit energyError: number; // [GeV] error of the hit energy time: number; // [ns] time of the hit @@ -111,7 +111,7 @@ export namespace Schema2 { /** Simulated calorimeter hit */ type SimCalorimeterHit = { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit energy: number; // [GeV] energy of the hit position: Vector3f; // [mm] position of the hit in world coordinates contributions: ObjectID[]; // Monte Carlo step contributions diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema3.ts b/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema3.ts similarity index 95% rename from packages/phoenix-event-display/src/lib/types/schemas/schema3.ts rename to packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema3.ts index 7c81fdb77..c11fb6207 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema3.ts +++ b/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema3.ts @@ -50,7 +50,7 @@ export namespace Schema3 { /** Tracker hit interface class */ // Types: TrackerHit3D, TrackerHitPlane interface TrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit type: number; // type of the raw data hit quality: number; // quality bit flag of the hit time: number; // [ns] time of the hit @@ -61,7 +61,7 @@ export namespace Schema3 { /** Tracker hit */ interface TrackerHit3D extends TrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit time: number; // [ns] time of the hit @@ -73,7 +73,7 @@ export namespace Schema3 { /** Tracker hit plane */ interface TrackerHitPlane extends TrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit time: number; // [ns] time of the hit @@ -89,7 +89,7 @@ export namespace Schema3 { /** Simulated tracker hit */ type SimTrackerHit = { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit eDep: number; // [GeV] energy deposited in the hit time: number; // [ns] proper time of the hit in the lab frame pathLength: number; // path length of the particle in the sensitive material that resulted in this hit @@ -101,7 +101,7 @@ export namespace Schema3 { /** Calorimeter hit */ type CalorimeterHit = { - cellID: number; // detector specific (geometrical) cell id + cellID: bigint; // detector specific (geometrical) cell id energy: number; // [GeV] energy of the hit energyError: number; // [GeV] error of the hit energy time: number; // [ns] time of the hit @@ -111,7 +111,7 @@ export namespace Schema3 { /** Simulated calorimeter hit */ type SimCalorimeterHit = { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit energy: number; // [GeV] energy of the hit position: Vector3f; // [mm] position of the hit in world coordinates contributions: ObjectID[]; // Monte Carlo step contributions diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema4.ts b/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema4.ts similarity index 95% rename from packages/phoenix-event-display/src/lib/types/schemas/schema4.ts rename to packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema4.ts index 629a323a5..dc2bcfc07 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema4.ts +++ b/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema4.ts @@ -50,7 +50,7 @@ export namespace Schema4 { /** Tracker hit interface class */ // Types: TrackerHit3D, TrackerHitPlane interface TrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit type: number; // type of the raw data hit quality: number; // quality bit flag of the hit time: number; // [ns] time of the hit @@ -61,7 +61,7 @@ export namespace Schema4 { /** Tracker hit */ interface TrackerHit3D extends TrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit time: number; // [ns] time of the hit @@ -73,7 +73,7 @@ export namespace Schema4 { /** Tracker hit plane */ interface TrackerHitPlane { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit time: number; // [ns] time of the hit @@ -89,7 +89,7 @@ export namespace Schema4 { /** Simulated tracker hit */ interface SimTrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit eDep: number; // [GeV] energy deposited in the hit time: number; // [ns] proper time of the hit in the lab frame pathLength: number; // path length of the particle in the sensitive material that resulted in this hit @@ -101,7 +101,7 @@ export namespace Schema4 { /** Calorimeter hit */ interface CalorimeterHit { - cellID: number; // detector specific (geometrical) cell id + cellID: bigint; // detector specific (geometrical) cell id energy: number; // [GeV] energy of the hit energyError: number; // [GeV] error of the hit energy time: number; // [ns] time of the hit @@ -111,7 +111,7 @@ export namespace Schema4 { /** Simulated calorimeter hit */ interface SimCalorimeterHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit energy: number; // [GeV] energy of the hit position: Vector3f; // [mm] position of the hit in world coordinates contributions: ObjectID[]; // Monte Carlo step contributions diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema5.ts b/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema5.ts similarity index 95% rename from packages/phoenix-event-display/src/lib/types/schemas/schema5.ts rename to packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema5.ts index 6e576c936..3300f9b2c 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema5.ts +++ b/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema5.ts @@ -50,7 +50,7 @@ export namespace Schema5 { /** Tracker hit interface class */ // Types: TrackerHit3D, TrackerHitPlane, SenseWireHit interface TrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit type: number; // type of the raw data hit quality: number; // quality bit flag of the hit time: number; // [ns] time of the hit @@ -61,7 +61,7 @@ export namespace Schema5 { /** Tracker hit */ interface TrackerHit3D extends TrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit time: number; // [ns] time of the hit @@ -73,7 +73,7 @@ export namespace Schema5 { /** Tracker hit plane */ interface TrackerHitPlane extends TrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit time: number; // [ns] time of the hit @@ -89,7 +89,7 @@ export namespace Schema5 { /** Sense wire hit, knowing only the distance to the wire. The circle representing possible positions is parametrized with its center, radius and normal vector (given by the wire direction). */ interface SenseWireHit extends TrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit type: number; // type of the raw data hit quality: number; // quality bit flag of the hit time: number; // [ns] time of the hit @@ -106,7 +106,7 @@ export namespace Schema5 { /** Simulated tracker hit */ interface SimTrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit eDep: number; // [GeV] energy deposited in the hit time: number; // [ns] proper time of the hit in the lab frame pathLength: number; // path length of the particle in the sensitive material that resulted in this hit @@ -118,7 +118,7 @@ export namespace Schema5 { /** Calorimeter hit */ interface CalorimeterHit { - cellID: number; // detector specific (geometrical) cell id + cellID: bigint; // detector specific (geometrical) cell id energy: number; // [GeV] energy of the hit energyError: number; // [GeV] error of the hit energy time: number; // [ns] time of the hit @@ -128,7 +128,7 @@ export namespace Schema5 { /** Simulated calorimeter hit */ interface SimCalorimeterHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit energy: number; // [GeV] energy of the hit position: Vector3f; // [mm] position of the hit in world coordinates contributions: ObjectID[]; // Monte Carlo step contributions diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema6.ts b/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema6.ts similarity index 95% rename from packages/phoenix-event-display/src/lib/types/schemas/schema6.ts rename to packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema6.ts index d8abe44a1..23ba1759b 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema6.ts +++ b/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema6.ts @@ -50,7 +50,7 @@ export namespace Schema6 { /** Tracker hit interface class */ // Types: TrackerHit3D, TrackerHitPlane, SenseWireHit interface TrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit type: number; // type of the raw data hit quality: number; // quality bit flag of the hit time: number; // [ns] time of the hit @@ -61,7 +61,7 @@ export namespace Schema6 { /** Tracker hit */ interface TrackerHit3D extends TrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit time: number; // [ns] time of the hit @@ -73,7 +73,7 @@ export namespace Schema6 { /** Tracker hit plane */ interface TrackerHitPlane extends TrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit time: number; // [ns] time of the hit @@ -89,7 +89,7 @@ export namespace Schema6 { /** Sense wire hit, knowing only the distance to the wire. The circle representing possible positions is parametrized with its center, radius and normal vector (given by the wire direction). */ interface SenseWireHit extends TrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit type: number; // type of the raw data hit quality: number; // quality bit flag of the hit time: number; // [ns] time of the hit @@ -106,7 +106,7 @@ export namespace Schema6 { /** Simulated tracker hit */ interface SimTrackerHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit eDep: number; // [GeV] energy deposited in the hit time: number; // [ns] proper time of the hit in the lab frame pathLength: number; // path length of the particle in the sensitive material that resulted in this hit @@ -118,7 +118,7 @@ export namespace Schema6 { /** Calorimeter hit */ interface CalorimeterHit { - cellID: number; // detector specific (geometrical) cell id + cellID: bigint; // detector specific (geometrical) cell id energy: number; // [GeV] energy of the hit energyError: number; // [GeV] error of the hit energy time: number; // [ns] time of the hit @@ -128,7 +128,7 @@ export namespace Schema6 { /** Simulated calorimeter hit */ interface SimCalorimeterHit { - cellID: number; // ID of the sensor that created this hit + cellID: bigint; // ID of the sensor that created this hit energy: number; // [GeV] energy of the hit position: Vector3f; // [mm] position of the hit in world coordinates contributions: ObjectID[]; // Monte Carlo step contributions diff --git a/packages/phoenix-event-display/src/lib/types/schemas/utils.ts b/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/utils.ts similarity index 100% rename from packages/phoenix-event-display/src/lib/types/schemas/utils.ts rename to packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/utils.ts From a7e04e2118aa110bb4d246f15e2a302777165bf7 Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Wed, 4 Mar 2026 12:03:55 +0100 Subject: [PATCH 05/30] Define types --- .../src}/lib/types/schemas/schema1.ts | 35 +++-- .../src}/lib/types/schemas/schema2.ts | 39 +++-- .../src}/lib/types/schemas/schema3.ts | 39 +++-- .../src}/lib/types/schemas/schema4.ts | 69 +++++---- .../src}/lib/types/schemas/schema5.ts | 69 +++++---- .../src}/lib/types/schemas/schema6.ts | 133 +++++++++++++----- 6 files changed, 251 insertions(+), 133 deletions(-) rename packages/{phoenix-ng/projects/phoenix-ui-components => phoenix-event-display/src}/lib/types/schemas/schema1.ts (88%) rename packages/{phoenix-ng/projects/phoenix-ui-components => phoenix-event-display/src}/lib/types/schemas/schema2.ts (85%) rename packages/{phoenix-ng/projects/phoenix-ui-components => phoenix-event-display/src}/lib/types/schemas/schema3.ts (85%) rename packages/{phoenix-ng/projects/phoenix-ui-components => phoenix-event-display/src}/lib/types/schemas/schema4.ts (82%) rename packages/{phoenix-ng/projects/phoenix-ui-components => phoenix-event-display/src}/lib/types/schemas/schema5.ts (84%) rename packages/{phoenix-ng/projects/phoenix-ui-components => phoenix-event-display/src}/lib/types/schemas/schema6.ts (78%) diff --git a/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema1.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema1.ts similarity index 88% rename from packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema1.ts rename to packages/phoenix-event-display/src/lib/types/schemas/schema1.ts index 1a52f2ec7..8234efd52 100644 --- a/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema1.ts +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema1.ts @@ -1,18 +1,6 @@ import { Vector3f, Vector3d, ObjectID } from './utils'; export namespace Schema1 { - type TrackState = { - location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation - D0: number; // transverse impact parameter - phi: number; // azimuthal angle - omega: number; // is the signed curvature of the track in [1/mm]. - Z0: number; // longitudinal impact parameter - tanLambda: number; // lambda is the dip angle of the track in r-z - time: number; // time of the track at this trackstate - referencePoint: Vector3f; // Reference point of the track parameters, e.g. the origin at the IP, or the position of the first/last hits or the entry point into the calorimeter. [mm] - covMatrix: number[]; // lower triangular covariance matrix of the track parameters. the order of parameters is d0, phi, omega, z0, tan(lambda), time. the array is a row-major flattening of the matrix. - }; - /** Vertex */ type Vertex = { primary: number; // boolean flag, if vertex is the primary vertex of the event @@ -25,6 +13,18 @@ export namespace Schema1 { associatedParticle: ObjectID; // reconstructed particle associated to this vertex. }; + type TrackState = { + location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation + D0: number; // transverse impact parameter + phi: number; // azimuthal angle + omega: number; // is the signed curvature of the track in [1/mm]. + Z0: number; // longitudinal impact parameter + tanLambda: number; // lambda is the dip angle of the track in r-z + time: number; // time of the track at this trackstate + referencePoint: Vector3f; // Reference point of the track parameters, e.g. the origin at the IP, or the position of the first/last hits or the entry point into the calorimeter. [mm] + covMatrix: number[]; // lower triangular covariance matrix of the track parameters. the order of parameters is d0, phi, omega, z0, tan(lambda), time. the array is a row-major flattening of the matrix. + }; + /** Reconstructed track */ type Track = { type: number; // flagword that defines the type of track.Bits 16-31 are used internally @@ -122,7 +122,6 @@ export namespace Schema1 { particleIDs: ObjectID[]; // particle Ids (not sorted by their likelihood) }; - type TrackStateCollection = TrackState[]; type VertexCollection = Vertex[]; type TrackCollection = Track[]; type TrackerHitCollection = TrackerHit[]; @@ -131,4 +130,14 @@ export namespace Schema1 { type SimCalorimeterHitCollection = SimCalorimeterHit[]; type ClusterCollection = Cluster[]; type ReconstructedParticleCollection = ReconstructedParticle[]; + + export type Item = + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; collection: VertexCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; collection: TrackCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHitCollection'; collection: TrackerHitCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimTrackerHitCollection'; collection: SimTrackerHitCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::CalorimeterHitCollection'; collection: CalorimeterHitCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimCalorimeterHitCollection'; collection: SimCalorimeterHitCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ClusterCollection'; collection: ClusterCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; collection: ReconstructedParticleCollection }; } diff --git a/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema2.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema2.ts similarity index 85% rename from packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema2.ts rename to packages/phoenix-event-display/src/lib/types/schemas/schema2.ts index f30415b53..487a59e6b 100644 --- a/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema2.ts +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema2.ts @@ -9,6 +9,18 @@ import { } from './utils'; export namespace Schema2 { + /** Vertex */ + type Vertex = { + type: number; // Flagword that defines the type of the vertex, see reserved bits for more information + chi2: number; // chi-squared of the vertex fit + ndf: number; // number of degrees of freedom of the vertex fit + position: Vector3f; // [mm] position of the vertex + covMatrix: CovMatrix3f; // covariance matrix of the position + algorithmType: number; // type code for the algorithm that has been used to create the vertex + parameters: number[]; // additional parameters related to this vertex + particles: ObjectID[]; // particles that have been used to form this vertex, aka the decay particles emerging from this vertex + }; + /** Parametrized description of a particle track */ type TrackState = { location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation @@ -22,18 +34,6 @@ export namespace Schema2 { covMatrix: CovMatrix6f; // covariance matrix of the track parameters. }; - /** Vertex */ - type Vertex = { - type: number; // Flagword that defines the type of the vertex, see reserved bits for more information - chi2: number; // chi-squared of the vertex fit - ndf: number; // number of degrees of freedom of the vertex fit - position: Vector3f; // [mm] position of the vertex - covMatrix: CovMatrix3f; // covariance matrix of the position - algorithmType: number; // type code for the algorithm that has been used to create the vertex - parameters: number[]; // additional parameters related to this vertex - particles: ObjectID[]; // particles that have been used to form this vertex, aka the decay particles emerging from this vertex - }; - /** Reconstructed track */ type Track = { type: number; // flagword that defines the type of track @@ -149,13 +149,24 @@ export namespace Schema2 { particles: ObjectID[]; // reconstructed particles that have been combined to this particle }; - type TrackStateCollection = TrackState[]; type VertexCollection = Vertex[]; type TrackCollection = Track[]; - type TrackerHitCollection = (TrackerHit3D | TrackerHitPlane)[]; + type TrackerHit3DCollection = TrackerHit3D[]; + type TrackerHitPlaneCollection = TrackerHitPlane[]; type SimTrackerHitCollection = SimTrackerHit[]; type CalorimeterHitCollection = CalorimeterHit[]; type SimCalorimeterHitCollection = SimCalorimeterHit[]; type ClusterCollection = Cluster[]; type ReconstructedParticleCollection = ReconstructedParticle[]; + + export type Item = + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; collection: VertexCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; collection: TrackCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHit3DCollection'; collection: TrackerHit3DCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHitPlaneCollection'; collection: TrackerHitPlaneCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimTrackerHitCollection'; collection: SimTrackerHitCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::CalorimeterHitCollection'; collection: CalorimeterHitCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimCalorimeterHitCollection'; collection: SimCalorimeterHitCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ClusterCollection'; collection: ClusterCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; collection: ReconstructedParticleCollection }; } diff --git a/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema3.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema3.ts similarity index 85% rename from packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema3.ts rename to packages/phoenix-event-display/src/lib/types/schemas/schema3.ts index c11fb6207..48375ccdf 100644 --- a/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema3.ts +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema3.ts @@ -9,6 +9,18 @@ import { } from './utils'; export namespace Schema3 { + /** Vertex */ + type Vertex = { + type: number; // flagword that defines the type of the vertex, see reserved bits for more information + chi2: number; // chi-squared of the vertex fit + ndf: number; // number of degrees of freedom of the vertex fit + position: Vector3f; // [mm] position of the vertex + covMatrix: CovMatrix3f; // [mm^2] covariance matrix of the position + algorithmType: number; // type code for the algorithm that has been used to create the vertex + parameters: number[]; // additional parameters related to this vertex + particles: ObjectID[]; // particles that have been used to form this vertex, aka the decay particles emerging from this vertex + }; + /** Parametrized description of a particle track */ type TrackState = { location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation @@ -22,18 +34,6 @@ export namespace Schema3 { covMatrix: CovMatrix6f; // covariance matrix of the track parameters. }; - /** Vertex */ - type Vertex = { - type: number; // flagword that defines the type of the vertex, see reserved bits for more information - chi2: number; // chi-squared of the vertex fit - ndf: number; // number of degrees of freedom of the vertex fit - position: Vector3f; // [mm] position of the vertex - covMatrix: CovMatrix3f; // [mm^2] covariance matrix of the position - algorithmType: number; // type code for the algorithm that has been used to create the vertex - parameters: number[]; // additional parameters related to this vertex - particles: ObjectID[]; // particles that have been used to form this vertex, aka the decay particles emerging from this vertex - }; - /** Reconstructed track */ type Track = { type: number; // flagword that defines the type of track @@ -149,13 +149,24 @@ export namespace Schema3 { particles: ObjectID[]; // reconstructed particles that have been combined to this particle }; - type TrackStateCollection = TrackState[]; type VertexCollection = Vertex[]; type TrackCollection = Track[]; - type TrackerHitCollection = (TrackerHit3D | TrackerHitPlane)[]; + type TrackerHit3DCollection = TrackerHit3D[]; + type TrackerHitPlaneCollection = TrackerHitPlane[]; type SimTrackerHitCollection = SimTrackerHit[]; type CalorimeterHitCollection = CalorimeterHit[]; type SimCalorimeterHitCollection = SimCalorimeterHit[]; type ClusterCollection = Cluster[]; type ReconstructedParticleCollection = ReconstructedParticle[]; + + export type Item = + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; collection: VertexCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; collection: TrackCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHit3DCollection'; collection: TrackerHit3DCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHitPlaneCollection'; collection: TrackerHitPlaneCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimTrackerHitCollection'; collection: SimTrackerHitCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::CalorimeterHitCollection'; collection: CalorimeterHitCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimCalorimeterHitCollection'; collection: SimCalorimeterHitCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ClusterCollection'; collection: ClusterCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; collection: ReconstructedParticleCollection }; } diff --git a/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema4.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema4.ts similarity index 82% rename from packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema4.ts rename to packages/phoenix-event-display/src/lib/types/schemas/schema4.ts index dc2bcfc07..c8cbaf0f8 100644 --- a/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema4.ts +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema4.ts @@ -9,8 +9,20 @@ import { } from './utils'; export namespace Schema4 { + /** Vertex */ + type Vertex = { + type: number; // flagword that defines the type of the vertex, see reserved bits for more information + chi2: number; // chi-squared of the vertex fit + ndf: number; // number of degrees of freedom of the vertex fit + position: Vector3f; // [mm] position of the vertex + covMatrix: CovMatrix3f; // [mm^2] covariance matrix of the position + algorithmType: number; // type code for the algorithm that has been used to create the vertex + parameters: number[]; // additional parameters related to this vertex + particles: ObjectID[]; // particles that have been used to form this vertex, aka the decay particles emerging from this vertex + }; + /** Parametrized description of a particle track */ - interface TrackState { + type TrackState = { location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation D0: number; // transverse impact parameter phi: number; // [rad] azimuthal angle of the track at this location (i.e. not phi0) @@ -20,22 +32,10 @@ export namespace Schema4 { time: number; // [ns] time of the track at this trackstate referencePoint: Vector3f; // [mm] Reference point of the track parameters, e.g. the origin at the IP, or the position of the first/last hits or the entry point into the calorimeter covMatrix: CovMatrix6f; // covariance matrix of the track parameters. - } - - /** Vertex */ - interface Vertex { - type: number; // flagword that defines the type of the vertex, see reserved bits for more information - chi2: number; // chi-squared of the vertex fit - ndf: number; // number of degrees of freedom of the vertex fit - position: Vector3f; // [mm] position of the vertex - covMatrix: CovMatrix3f; // [mm^2] covariance matrix of the position - algorithmType: number; // type code for the algorithm that has been used to create the vertex - parameters: number[]; // additional parameters related to this vertex - particles: ObjectID[]; // particles that have been used to form this vertex, aka the decay particles emerging from this vertex - } + }; /** Reconstructed track */ - interface Track { + type Track = { type: number; // flagword that defines the type of track chi2: number; // chi-squared of the track fit ndf: number; // number of degrees of freedom of the track fit @@ -45,7 +45,7 @@ export namespace Schema4 { trackStates: TrackState[]; // track states trackerHits: ObjectID[]; // hits that have been used to create this track tracks: ObjectID[]; // tracks (segments) that have been combined to create this track - } + }; /** Tracker hit interface class */ // Types: TrackerHit3D, TrackerHitPlane @@ -72,7 +72,7 @@ export namespace Schema4 { } /** Tracker hit plane */ - interface TrackerHitPlane { + interface TrackerHitPlane extends TrackerHit { cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit @@ -88,7 +88,7 @@ export namespace Schema4 { } /** Simulated tracker hit */ - interface SimTrackerHit { + type SimTrackerHit = { cellID: bigint; // ID of the sensor that created this hit eDep: number; // [GeV] energy deposited in the hit time: number; // [ns] proper time of the hit in the lab frame @@ -97,28 +97,28 @@ export namespace Schema4 { position: Vector3d; // [mm] the hit position momentum: Vector3f; // [GeV] the 3-momentum of the particle at the hits position particle: ObjectID; // MCParticle that caused the hit - } + }; /** Calorimeter hit */ - interface CalorimeterHit { + type CalorimeterHit = { cellID: bigint; // detector specific (geometrical) cell id energy: number; // [GeV] energy of the hit energyError: number; // [GeV] error of the hit energy time: number; // [ns] time of the hit position: Vector3f; // [mm] position of the hit in world coordinates type: number; // type of hit - } + }; /** Simulated calorimeter hit */ - interface SimCalorimeterHit { + type SimCalorimeterHit = { cellID: bigint; // ID of the sensor that created this hit energy: number; // [GeV] energy of the hit position: Vector3f; // [mm] position of the hit in world coordinates contributions: ObjectID[]; // Monte Carlo step contributions - } + }; /** Calorimeter Hit Cluster */ - interface Cluster { + type Cluster = { type: number; // flagword that defines the type of cluster energy: number; // [GeV] energy of the cluster energyError: number; // [GeV] error on the energy @@ -131,10 +131,10 @@ export namespace Schema4 { subdetectorEnergies: number[]; // energy observed in a particular subdetector clusters: ObjectID[]; // clusters that have been combined to this cluster hits: ObjectID[]; // hits that have been combined to this cluster - } + }; /** Reconstructed Particle */ - interface ReconstructedParticle { + type ReconstructedParticle = { PDG: number; // PDG of the reconstructed particle. energy: number; // [GeV] energy of the reconstructed particle. Four momentum state is not kept consistent internally momentum: Vector3f; // [GeV] particle momentum. Four momentum state is not kept consistent internally @@ -147,15 +147,26 @@ export namespace Schema4 { clusters: ObjectID[]; // clusters that have been used for this particle tracks: ObjectID[]; // tracks that have been used for this particle particles: ObjectID[]; // reconstructed particles that have been combined to this particle - } + }; - type TrackStateCollection = TrackState[]; type VertexCollection = Vertex[]; type TrackCollection = Track[]; - type TrackerHitCollection = (TrackerHit3D | TrackerHitPlane)[]; + type TrackerHit3DCollection = TrackerHit3D[]; + type TrackerHitPlaneCollection = TrackerHitPlane[]; type SimTrackerHitCollection = SimTrackerHit[]; type CalorimeterHitCollection = CalorimeterHit[]; type SimCalorimeterHitCollection = SimCalorimeterHit[]; type ClusterCollection = Cluster[]; type ReconstructedParticleCollection = ReconstructedParticle[]; + + export type Item = + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; collection: VertexCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; collection: TrackCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHit3DCollection'; collection: TrackerHit3DCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHitPlaneCollection'; collection: TrackerHitPlaneCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimTrackerHitCollection'; collection: SimTrackerHitCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::CalorimeterHitCollection'; collection: CalorimeterHitCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimCalorimeterHitCollection'; collection: SimCalorimeterHitCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ClusterCollection'; collection: ClusterCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; collection: ReconstructedParticleCollection }; } diff --git a/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema5.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema5.ts similarity index 84% rename from packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema5.ts rename to packages/phoenix-event-display/src/lib/types/schemas/schema5.ts index 3300f9b2c..46c0edb2c 100644 --- a/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema5.ts +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema5.ts @@ -9,8 +9,20 @@ import { } from './utils'; export namespace Schema5 { + /** Vertex */ + type Vertex = { + type: number; // flagword that defines the type of the vertex, see reserved bits for more information + chi2: number; // chi-squared of the vertex fit + ndf: number; // number of degrees of freedom of the vertex fit + position: Vector3f; // [mm] position of the vertex + covMatrix: CovMatrix3f; // [mm^2] covariance matrix of the position + algorithmType: number; // type code for the algorithm that has been used to create the vertex + parameters: number[]; // additional parameters related to this vertex + particles: ObjectID[]; // particles that have been used to form this vertex, aka the decay particles emerging from this vertex + }; + /** Parametrized description of a particle track */ - interface TrackState { + type TrackState = { location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation D0: number; // transverse impact parameter phi: number; // [rad] azimuthal angle of the track at this location (i.e. not phi0) @@ -20,22 +32,10 @@ export namespace Schema5 { time: number; // [ns] time of the track at this trackstate referencePoint: Vector3f; // [mm] Reference point of the track parameters, e.g. the origin at the IP, or the position of the first/last hits or the entry point into the calorimeter covMatrix: CovMatrix6f; // covariance matrix of the track parameters. - } - - /** Vertex */ - interface Vertex { - type: number; // flagword that defines the type of the vertex, see reserved bits for more information - chi2: number; // chi-squared of the vertex fit - ndf: number; // number of degrees of freedom of the vertex fit - position: Vector3f; // [mm] position of the vertex - covMatrix: CovMatrix3f; // [mm^2] covariance matrix of the position - algorithmType: number; // type code for the algorithm that has been used to create the vertex - parameters: number[]; // additional parameters related to this vertex - particles: ObjectID[]; // particles that have been used to form this vertex, aka the decay particles emerging from this vertex - } + }; /** Reconstructed track */ - interface Track { + type Track = { type: number; // flagword that defines the type of track chi2: number; // chi-squared of the track fit ndf: number; // number of degrees of freedom of the track fit @@ -45,7 +45,7 @@ export namespace Schema5 { trackStates: TrackState[]; // track states trackerHits: ObjectID[]; // hits that have been used to create this track tracks: ObjectID[]; // tracks (segments) that have been combined to create this track - } + }; /** Tracker hit interface class */ // Types: TrackerHit3D, TrackerHitPlane, SenseWireHit @@ -105,7 +105,7 @@ export namespace Schema5 { } /** Simulated tracker hit */ - interface SimTrackerHit { + type SimTrackerHit = { cellID: bigint; // ID of the sensor that created this hit eDep: number; // [GeV] energy deposited in the hit time: number; // [ns] proper time of the hit in the lab frame @@ -114,28 +114,28 @@ export namespace Schema5 { position: Vector3d; // [mm] the hit position momentum: Vector3f; // [GeV] the 3-momentum of the particle at the hits position particle: ObjectID; // MCParticle that caused the hit - } + }; /** Calorimeter hit */ - interface CalorimeterHit { + type CalorimeterHit = { cellID: bigint; // detector specific (geometrical) cell id energy: number; // [GeV] energy of the hit energyError: number; // [GeV] error of the hit energy time: number; // [ns] time of the hit position: Vector3f; // [mm] position of the hit in world coordinates type: number; // type of hit - } + }; /** Simulated calorimeter hit */ - interface SimCalorimeterHit { + type SimCalorimeterHit = { cellID: bigint; // ID of the sensor that created this hit energy: number; // [GeV] energy of the hit position: Vector3f; // [mm] position of the hit in world coordinates contributions: ObjectID[]; // Monte Carlo step contributions - } + }; /** Calorimeter Hit Cluster */ - interface Cluster { + type Cluster = { type: number; // flagword that defines the type of cluster energy: number; // [GeV] energy of the cluster energyError: number; // [GeV] error on the energy @@ -148,10 +148,10 @@ export namespace Schema5 { subdetectorEnergies: number[]; // energy observed in a particular subdetector clusters: ObjectID[]; // clusters that have been combined to this cluster hits: ObjectID[]; // hits that have been combined to this cluster - } + }; /** Reconstructed Particle */ - interface ReconstructedParticle { + type ReconstructedParticle = { PDG: number; // PDG of the reconstructed particle. energy: number; // [GeV] energy of the reconstructed particle. Four momentum state is not kept consistent internally momentum: Vector3f; // [GeV] particle momentum. Four momentum state is not kept consistent internally @@ -164,15 +164,28 @@ export namespace Schema5 { clusters: ObjectID[]; // clusters that have been used for this particle tracks: ObjectID[]; // tracks that have been used for this particle particles: ObjectID[]; // reconstructed particles that have been combined to this particle - } + }; - type TrackStateCollection = TrackState[]; type VertexCollection = Vertex[]; type TrackCollection = Track[]; - type TrackerHitCollection = (TrackerHit3D | TrackerHitPlane | SenseWireHit)[]; + type TrackerHit3DCollection = TrackerHit3D[]; + type TrackerHitPlaneCollection = TrackerHitPlane[]; + type SenseWireHitCollection = SenseWireHit[]; type SimTrackerHitCollection = SimTrackerHit[]; type CalorimeterHitCollection = CalorimeterHit[]; type SimCalorimeterHitCollection = SimCalorimeterHit[]; type ClusterCollection = Cluster[]; type ReconstructedParticleCollection = ReconstructedParticle[]; + + export type Item = + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; collection: VertexCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; collection: TrackCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHit3DCollection'; collection: TrackerHit3DCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHitPlaneCollection'; collection: TrackerHitPlaneCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SenseWireHitCollection'; collection: SenseWireHitCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimTrackerHitCollection'; collection: SimTrackerHitCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::CalorimeterHitCollection'; collection: CalorimeterHitCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimCalorimeterHitCollection'; collection: SimCalorimeterHitCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ClusterCollection'; collection: ClusterCollection } + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; collection: ReconstructedParticleCollection }; } diff --git a/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema6.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema6.ts similarity index 78% rename from packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema6.ts rename to packages/phoenix-event-display/src/lib/types/schemas/schema6.ts index 23ba1759b..2e7083169 100644 --- a/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/schema6.ts +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema6.ts @@ -9,8 +9,20 @@ import { } from './utils'; export namespace Schema6 { + /** Vertex */ + type Vertex = { + type: number; // flagword that defines the type of the vertex, see reserved bits for more information + chi2: number; // chi-squared of the vertex fit + ndf: number; // number of degrees of freedom of the vertex fit + position: Vector3f; // [mm] position of the vertex + covMatrix: CovMatrix3f; // [mm^2] covariance matrix of the position + algorithmType: number; // type code for the algorithm that has been used to create the vertex + parameters: number[]; // additional parameters related to this vertex + particles: ObjectID[]; // particles that have been used to form this vertex, aka the decay particles emerging from this vertex + }; + /** Parametrized description of a particle track */ - interface TrackState { + type TrackState = { location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation D0: number; // transverse impact parameter phi: number; // [rad] azimuthal angle of the track at this location (i.e. not phi0) @@ -20,22 +32,10 @@ export namespace Schema6 { time: number; // [ns] time of the track at this trackstate referencePoint: Vector3f; // [mm] Reference point of the track parameters, e.g. the origin at the IP, or the position of the first/last hits or the entry point into the calorimeter covMatrix: CovMatrix6f; // covariance matrix of the track parameters. - } - - /** Vertex */ - interface Vertex { - type: number; // flagword that defines the type of the vertex, see reserved bits for more information - chi2: number; // chi-squared of the vertex fit - ndf: number; // number of degrees of freedom of the vertex fit - position: Vector3f; // [mm] position of the vertex - covMatrix: CovMatrix3f; // [mm^2] covariance matrix of the position - algorithmType: number; // type code for the algorithm that has been used to create the vertex - parameters: number[]; // additional parameters related to this vertex - particles: ObjectID[]; // particles that have been used to form this vertex, aka the decay particles emerging from this vertex - } + }; /** Reconstructed track */ - interface Track { + type Track = { type: number; // flagword that defines the type of track chi2: number; // chi-squared of the track fit ndf: number; // number of degrees of freedom of the track fit @@ -45,7 +45,7 @@ export namespace Schema6 { trackStates: TrackState[]; // track states trackerHits: ObjectID[]; // hits that have been used to create this track tracks: ObjectID[]; // tracks (segments) that have been combined to create this track - } + }; /** Tracker hit interface class */ // Types: TrackerHit3D, TrackerHitPlane, SenseWireHit @@ -105,7 +105,7 @@ export namespace Schema6 { } /** Simulated tracker hit */ - interface SimTrackerHit { + type SimTrackerHit = { cellID: bigint; // ID of the sensor that created this hit eDep: number; // [GeV] energy deposited in the hit time: number; // [ns] proper time of the hit in the lab frame @@ -114,28 +114,28 @@ export namespace Schema6 { position: Vector3d; // [mm] the hit position momentum: Vector3f; // [GeV] the 3-momentum of the particle at the hits position particle: ObjectID; // MCParticle that caused the hit - } + }; /** Calorimeter hit */ - interface CalorimeterHit { + type CalorimeterHit = { cellID: bigint; // detector specific (geometrical) cell id energy: number; // [GeV] energy of the hit energyError: number; // [GeV] error of the hit energy time: number; // [ns] time of the hit position: Vector3f; // [mm] position of the hit in world coordinates type: number; // type of hit - } + }; /** Simulated calorimeter hit */ - interface SimCalorimeterHit { + type SimCalorimeterHit = { cellID: bigint; // ID of the sensor that created this hit energy: number; // [GeV] energy of the hit position: Vector3f; // [mm] position of the hit in world coordinates contributions: ObjectID[]; // Monte Carlo step contributions - } + }; /** Calorimeter Hit Cluster */ - interface Cluster { + type Cluster = { type: number; // flagword that defines the type of cluster energy: number; // [GeV] energy of the cluster energyError: number; // [GeV] error on the energy @@ -148,10 +148,10 @@ export namespace Schema6 { subdetectorEnergies: number[]; // energy observed in a particular subdetector clusters: ObjectID[]; // clusters that have been combined to this cluster hits: ObjectID[]; // hits that have been combined to this cluster - } + }; /** Reconstructed Particle */ - interface ReconstructedParticle { + type ReconstructedParticle = { PDG: number; // PDG of the reconstructed particle. energy: number; // [GeV] energy of the reconstructed particle. Four momentum state is not kept consistent internally momentum: Vector3f; // [GeV] particle momentum. Four momentum state is not kept consistent internally @@ -164,15 +164,78 @@ export namespace Schema6 { clusters: ObjectID[]; // clusters that have been used for this particle tracks: ObjectID[]; // tracks that have been used for this particle particles: ObjectID[]; // reconstructed particles that have been combined to this particle - } + }; + + export type VertexCollection = Vertex[]; + export type TrackCollection = Track[]; + export type TrackerHit3DCollection = TrackerHit3D[]; + export type TrackerHitPlaneCollection = TrackerHitPlane[]; + export type SenseWireHitCollection = SenseWireHit[]; + export type SimTrackerHitCollection = SimTrackerHit[]; + export type CalorimeterHitCollection = CalorimeterHit[]; + export type SimCalorimeterHitCollection = SimCalorimeterHit[]; + export type ClusterCollection = Cluster[]; + export type ReconstructedParticleCollection = ReconstructedParticle[]; - type TrackStateCollection = TrackState[]; - type VertexCollection = Vertex[]; - type TrackCollection = Track[]; - type TrackerHitCollection = (TrackerHit3D | TrackerHitPlane | SenseWireHit)[]; - type SimTrackerHitCollection = SimTrackerHit[]; - type CalorimeterHitCollection = CalorimeterHit[]; - type SimCalorimeterHitCollection = SimCalorimeterHit[]; - type ClusterCollection = Cluster[]; - type ReconstructedParticleCollection = ReconstructedParticle[]; + export type Item = + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::VertexCollection'; + collection: VertexCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::TrackCollection'; + collection: TrackCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::TrackerHit3DCollection'; + collection: TrackerHit3DCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::TrackerHitPlaneCollection'; + collection: TrackerHitPlaneCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::SenseWireHitCollection'; + collection: SenseWireHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::SimTrackerHitCollection'; + collection: SimTrackerHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::CalorimeterHitCollection'; + collection: CalorimeterHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::SimCalorimeterHitCollection'; + collection: SimCalorimeterHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::ClusterCollection'; + collection: ClusterCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::ReconstructedParticleCollection'; + collection: ReconstructedParticleCollection; + }; } From 66eeb81a9e6489afb5c432fa263237c69a03750d Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Wed, 4 Mar 2026 12:04:20 +0100 Subject: [PATCH 06/30] Define common types for all schemas --- .../src/lib/types/schemas/utils.ts | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 packages/phoenix-event-display/src/lib/types/schemas/utils.ts diff --git a/packages/phoenix-event-display/src/lib/types/schemas/utils.ts b/packages/phoenix-event-display/src/lib/types/schemas/utils.ts new file mode 100644 index 000000000..689ec4fd2 --- /dev/null +++ b/packages/phoenix-event-display/src/lib/types/schemas/utils.ts @@ -0,0 +1,53 @@ +import { Schema1 } from './schema1'; +import { Schema2 } from './schema2'; +import { Schema3 } from './schema3'; +import { Schema4 } from './schema4'; +import { Schema5 } from './schema5'; +import { Schema6 } from './schema6'; + +/** A generic 3 dimensional covariance matrix with values stored in lower triangular form */ +export type CovMatrix3f = { + values: number[]; // the covariance matrix values +}; + +/** A generic 4 dimensional covariance matrix with values stored in lower triangular form */ +export type CovMatrix4f = { + values: number[]; // the covariance matrix values +}; + +/** A generic 6 dimensional covariance matrix with values stored in lower triangular form */ +export type CovMatrix6f = { + values: number[]; // the covariance matrix values +}; + +export type Vector2f = { + a: number; + b: number; +}; + +export type Vector3f = { + x: number; + y: number; + z: number; +}; + +export type Vector3d = { + x: number; + y: number; + z: number; +}; + +export type ObjectID = { + collectionID: number; + index: number; +}; + +export type edm4hepEvent = { + [name: string]: + | Schema6.Item + | Schema5.Item + | Schema4.Item + | Schema3.Item + | Schema2.Item + | Schema1.Item; +}; From f232ed6ee8e2a2cad20e17712f8cbbb6adce8604 Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Wed, 4 Mar 2026 12:24:43 +0100 Subject: [PATCH 07/30] Add EventHeader to types --- .../src/lib/types/schemas/schema1.ts | 10 ++++++ .../src/lib/types/schemas/schema2.ts | 11 ++++++ .../src/lib/types/schemas/schema3.ts | 12 +++++++ .../src/lib/types/schemas/schema4.ts | 11 ++++++ .../src/lib/types/schemas/schema5.ts | 11 ++++++ .../src/lib/types/schemas/schema6.ts | 17 +++++++++ .../lib/types/schemas/utils.ts | 36 ------------------- 7 files changed, 72 insertions(+), 36 deletions(-) delete mode 100644 packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/utils.ts diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema1.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema1.ts index 8234efd52..0f865d00f 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema1.ts +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema1.ts @@ -122,6 +122,15 @@ export namespace Schema1 { particleIDs: ObjectID[]; // particle Ids (not sorted by their likelihood) }; + /** Event Header. Additional parameters are assumed to go into the metadata tree. */ + type EventHeader = { + eventNumber: number; // event number + runNumber: number; // run number + timeStamp: bigint; // time stamp + weight: number; // event weight + }; + + type EventHeaderCollection = EventHeader[]; type VertexCollection = Vertex[]; type TrackCollection = Track[]; type TrackerHitCollection = TrackerHit[]; @@ -132,6 +141,7 @@ export namespace Schema1 { type ReconstructedParticleCollection = ReconstructedParticle[]; export type Item = + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::EventHeaderCollection'; collection: EventHeaderCollection } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; collection: VertexCollection } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; collection: TrackCollection } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHitCollection'; collection: TrackerHitCollection } diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema2.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema2.ts index 487a59e6b..0311e1029 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema2.ts +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema2.ts @@ -149,6 +149,16 @@ export namespace Schema2 { particles: ObjectID[]; // reconstructed particles that have been combined to this particle }; + /** Event Header. Additional parameters are assumed to go into the metadata tree. */ + type EventHeader = { + eventNumber: number; // event number + runNumber: number; // run number + timeStamp: bigint; // time stamp + weight: number; // event weight + weights: number[]; // event weights in case there are multiple. **NOTE that weights[0] might not be the same as weight!** Event weight names should be stored using the edm4hep::EventWeights name in the file level metadata + }; + + type EventHeaderCollection = EventHeader[]; type VertexCollection = Vertex[]; type TrackCollection = Track[]; type TrackerHit3DCollection = TrackerHit3D[]; @@ -160,6 +170,7 @@ export namespace Schema2 { type ReconstructedParticleCollection = ReconstructedParticle[]; export type Item = + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::EventHeaderCollection'; collection: EventHeaderCollection } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; collection: VertexCollection } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; collection: TrackCollection } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHit3DCollection'; collection: TrackerHit3DCollection } diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema3.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema3.ts index 48375ccdf..a36df2f15 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema3.ts +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema3.ts @@ -149,6 +149,17 @@ export namespace Schema3 { particles: ObjectID[]; // reconstructed particles that have been combined to this particle }; + + /** Event Header. Additional parameters are assumed to go into the metadata tree. */ + type EventHeader = { + eventNumber: bigint; // event number + runNumber: number; // run number + timeStamp: bigint; // time stamp + weight: number; // event weight + weights: number[]; // event weights in case there are multiple. **NOTE that weights[0] might not be the same as weight!** Event weight names should be stored using the edm4hep::EventWeights name in the file level metadata + }; + + type EventHeaderCollection = EventHeader[]; type VertexCollection = Vertex[]; type TrackCollection = Track[]; type TrackerHit3DCollection = TrackerHit3D[]; @@ -160,6 +171,7 @@ export namespace Schema3 { type ReconstructedParticleCollection = ReconstructedParticle[]; export type Item = + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::EventHeaderCollection'; collection: EventHeaderCollection } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; collection: VertexCollection } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; collection: TrackCollection } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHit3DCollection'; collection: TrackerHit3DCollection } diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema4.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema4.ts index c8cbaf0f8..4fba9acdc 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema4.ts +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema4.ts @@ -149,6 +149,16 @@ export namespace Schema4 { particles: ObjectID[]; // reconstructed particles that have been combined to this particle }; + /** Event Header. Additional parameters are assumed to go into the metadata tree. */ + type EventHeader = { + eventNumber: bigint; // event number + runNumber: number; // run number + timeStamp: bigint; // time stamp + weight: number; // event weight + weights: number[]; // event weights in case there are multiple. **NOTE that weights[0] might not be the same as weight!** The corresponding names of the event weights should be stored in the collection named by edm4hep::labels::EventWeightsNames in the file-level metadata. + }; + + type EventHeaderCollection = EventHeader[]; type VertexCollection = Vertex[]; type TrackCollection = Track[]; type TrackerHit3DCollection = TrackerHit3D[]; @@ -160,6 +170,7 @@ export namespace Schema4 { type ReconstructedParticleCollection = ReconstructedParticle[]; export type Item = + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::EventHeaderCollection'; collection: EventHeaderCollection } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; collection: VertexCollection } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; collection: TrackCollection } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHit3DCollection'; collection: TrackerHit3DCollection } diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema5.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema5.ts index 46c0edb2c..ba93d72b5 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema5.ts +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema5.ts @@ -166,6 +166,16 @@ export namespace Schema5 { particles: ObjectID[]; // reconstructed particles that have been combined to this particle }; + /** Event Header. Additional parameters are assumed to go into the metadata tree. */ + type EventHeader = { + eventNumber: bigint; // event number + runNumber: number; // run number + timeStamp: bigint; // time stamp + weight: number; // event weight + weights: number[]; // event weights in case there are multiple. **NOTE that weights[0] might not be the same as weight!** The corresponding names of the event weights should be stored in the collection named by edm4hep::labels::EventWeightsNames in the file-level metadata. + }; + + type EventHeaderCollection = EventHeader[]; type VertexCollection = Vertex[]; type TrackCollection = Track[]; type TrackerHit3DCollection = TrackerHit3D[]; @@ -178,6 +188,7 @@ export namespace Schema5 { type ReconstructedParticleCollection = ReconstructedParticle[]; export type Item = + | { collID: number; collSchemaVersion: number; collType: 'edm4hep::EventHeaderCollection'; collection: EventHeaderCollection } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; collection: VertexCollection } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; collection: TrackCollection } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHit3DCollection'; collection: TrackerHit3DCollection } diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema6.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema6.ts index 2e7083169..c9d90fa47 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema6.ts +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema6.ts @@ -166,6 +166,17 @@ export namespace Schema6 { particles: ObjectID[]; // reconstructed particles that have been combined to this particle }; + + /** Event Header. Additional parameters are assumed to go into the metadata tree. */ + type EventHeader = { + eventNumber: bigint; // event number + runNumber: number; // run number + timeStamp: bigint; // time stamp + weight: number; // event weight + weights: number[]; // event weights in case there are multiple. **NOTE that weights[0] might not be the same as weight!** The corresponding names of the event weights should be stored in the collection named by edm4hep::labels::EventWeightsNames in the file-level metadata. + }; + + export type EventHeaderCollection = EventHeader[]; export type VertexCollection = Vertex[]; export type TrackCollection = Track[]; export type TrackerHit3DCollection = TrackerHit3D[]; @@ -178,6 +189,12 @@ export namespace Schema6 { export type ReconstructedParticleCollection = ReconstructedParticle[]; export type Item = + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::EventHeaderCollection'; + collection: EventHeaderCollection; + } | { collID: number; collSchemaVersion: number; diff --git a/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/utils.ts b/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/utils.ts deleted file mode 100644 index 31c68cd1b..000000000 --- a/packages/phoenix-ng/projects/phoenix-ui-components/lib/types/schemas/utils.ts +++ /dev/null @@ -1,36 +0,0 @@ -/** A generic 3 dimensional covariance matrix with values stored in lower triangular form */ -export type CovMatrix3f = { - values: number[]; // the covariance matrix values -}; - -/** A generic 4 dimensional covariance matrix with values stored in lower triangular form */ -export type CovMatrix4f = { - values: number[]; // the covariance matrix values -}; - -/** A generic 6 dimensional covariance matrix with values stored in lower triangular form */ -export type CovMatrix6f = { - values: number[]; // the covariance matrix values -}; - -export type Vector2f = { - a: number; - b: number; -}; - -export type Vector3f = { - x: number; - y: number; - z: number; -}; - -export type Vector3d = { - x: number; - y: number; - z: number; -}; - -export type ObjectID = { - collectionID: number; - index: number; -}; From 8d526e9a097fc76fabd24eb78ab6043f91499a8a Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Wed, 4 Mar 2026 12:58:38 +0100 Subject: [PATCH 08/30] Export collection types --- .../src/lib/types/schemas/schema1.ts | 81 +++++++++++---- .../src/lib/types/schemas/schema2.ts | 90 +++++++++++++---- .../src/lib/types/schemas/schema3.ts | 91 +++++++++++++---- .../src/lib/types/schemas/schema4.ts | 90 +++++++++++++---- .../src/lib/types/schemas/schema5.ts | 99 ++++++++++++++----- .../src/lib/types/schemas/schema6.ts | 3 +- 6 files changed, 351 insertions(+), 103 deletions(-) diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema1.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema1.ts index 0f865d00f..ed24e1404 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema1.ts +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema1.ts @@ -130,24 +130,69 @@ export namespace Schema1 { weight: number; // event weight }; - type EventHeaderCollection = EventHeader[]; - type VertexCollection = Vertex[]; - type TrackCollection = Track[]; - type TrackerHitCollection = TrackerHit[]; - type SimTrackerHitCollection = SimTrackerHit[]; - type CalorimeterHitCollection = CalorimeterHit[]; - type SimCalorimeterHitCollection = SimCalorimeterHit[]; - type ClusterCollection = Cluster[]; - type ReconstructedParticleCollection = ReconstructedParticle[]; + export type EventHeaderCollection = EventHeader[]; + export type VertexCollection = Vertex[]; + export type TrackCollection = Track[]; + export type TrackerHitCollection = TrackerHit[]; + export type SimTrackerHitCollection = SimTrackerHit[]; + export type CalorimeterHitCollection = CalorimeterHit[]; + export type SimCalorimeterHitCollection = SimCalorimeterHit[]; + export type ClusterCollection = Cluster[]; + export type ReconstructedParticleCollection = ReconstructedParticle[]; export type Item = - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::EventHeaderCollection'; collection: EventHeaderCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; collection: VertexCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; collection: TrackCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHitCollection'; collection: TrackerHitCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimTrackerHitCollection'; collection: SimTrackerHitCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::CalorimeterHitCollection'; collection: CalorimeterHitCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimCalorimeterHitCollection'; collection: SimCalorimeterHitCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ClusterCollection'; collection: ClusterCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; collection: ReconstructedParticleCollection }; + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::EventHeaderCollection'; + collection: EventHeaderCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::VertexCollection'; + collection: VertexCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::TrackCollection'; + collection: TrackCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::TrackerHitCollection'; + collection: TrackerHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::SimTrackerHitCollection'; + collection: SimTrackerHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::CalorimeterHitCollection'; + collection: CalorimeterHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::SimCalorimeterHitCollection'; + collection: SimCalorimeterHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::ClusterCollection'; + collection: ClusterCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::ReconstructedParticleCollection'; + collection: ReconstructedParticleCollection; + }; } diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema2.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema2.ts index 0311e1029..df0262158 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema2.ts +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema2.ts @@ -158,26 +158,76 @@ export namespace Schema2 { weights: number[]; // event weights in case there are multiple. **NOTE that weights[0] might not be the same as weight!** Event weight names should be stored using the edm4hep::EventWeights name in the file level metadata }; - type EventHeaderCollection = EventHeader[]; - type VertexCollection = Vertex[]; - type TrackCollection = Track[]; - type TrackerHit3DCollection = TrackerHit3D[]; - type TrackerHitPlaneCollection = TrackerHitPlane[]; - type SimTrackerHitCollection = SimTrackerHit[]; - type CalorimeterHitCollection = CalorimeterHit[]; - type SimCalorimeterHitCollection = SimCalorimeterHit[]; - type ClusterCollection = Cluster[]; - type ReconstructedParticleCollection = ReconstructedParticle[]; + export type EventHeaderCollection = EventHeader[]; + export type VertexCollection = Vertex[]; + export type TrackCollection = Track[]; + export type TrackerHit3DCollection = TrackerHit3D[]; + export type TrackerHitPlaneCollection = TrackerHitPlane[]; + export type SimTrackerHitCollection = SimTrackerHit[]; + export type CalorimeterHitCollection = CalorimeterHit[]; + export type SimCalorimeterHitCollection = SimCalorimeterHit[]; + export type ClusterCollection = Cluster[]; + export type ReconstructedParticleCollection = ReconstructedParticle[]; export type Item = - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::EventHeaderCollection'; collection: EventHeaderCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; collection: VertexCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; collection: TrackCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHit3DCollection'; collection: TrackerHit3DCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHitPlaneCollection'; collection: TrackerHitPlaneCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimTrackerHitCollection'; collection: SimTrackerHitCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::CalorimeterHitCollection'; collection: CalorimeterHitCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimCalorimeterHitCollection'; collection: SimCalorimeterHitCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ClusterCollection'; collection: ClusterCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; collection: ReconstructedParticleCollection }; + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::EventHeaderCollection'; + collection: EventHeaderCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::VertexCollection'; + collection: VertexCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::TrackCollection'; + collection: TrackCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::TrackerHit3DCollection'; + collection: TrackerHit3DCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::TrackerHitPlaneCollection'; + collection: TrackerHitPlaneCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::SimTrackerHitCollection'; + collection: SimTrackerHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::CalorimeterHitCollection'; + collection: CalorimeterHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::SimCalorimeterHitCollection'; + collection: SimCalorimeterHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::ClusterCollection'; + collection: ClusterCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::ReconstructedParticleCollection'; + collection: ReconstructedParticleCollection; + }; } diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema3.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema3.ts index a36df2f15..edf8bf265 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema3.ts +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema3.ts @@ -149,7 +149,6 @@ export namespace Schema3 { particles: ObjectID[]; // reconstructed particles that have been combined to this particle }; - /** Event Header. Additional parameters are assumed to go into the metadata tree. */ type EventHeader = { eventNumber: bigint; // event number @@ -159,26 +158,76 @@ export namespace Schema3 { weights: number[]; // event weights in case there are multiple. **NOTE that weights[0] might not be the same as weight!** Event weight names should be stored using the edm4hep::EventWeights name in the file level metadata }; - type EventHeaderCollection = EventHeader[]; - type VertexCollection = Vertex[]; - type TrackCollection = Track[]; - type TrackerHit3DCollection = TrackerHit3D[]; - type TrackerHitPlaneCollection = TrackerHitPlane[]; - type SimTrackerHitCollection = SimTrackerHit[]; - type CalorimeterHitCollection = CalorimeterHit[]; - type SimCalorimeterHitCollection = SimCalorimeterHit[]; - type ClusterCollection = Cluster[]; - type ReconstructedParticleCollection = ReconstructedParticle[]; + export type EventHeaderCollection = EventHeader[]; + export type VertexCollection = Vertex[]; + export type TrackCollection = Track[]; + export type TrackerHit3DCollection = TrackerHit3D[]; + export type TrackerHitPlaneCollection = TrackerHitPlane[]; + export type SimTrackerHitCollection = SimTrackerHit[]; + export type CalorimeterHitCollection = CalorimeterHit[]; + export type SimCalorimeterHitCollection = SimCalorimeterHit[]; + export type ClusterCollection = Cluster[]; + export type ReconstructedParticleCollection = ReconstructedParticle[]; export type Item = - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::EventHeaderCollection'; collection: EventHeaderCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; collection: VertexCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; collection: TrackCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHit3DCollection'; collection: TrackerHit3DCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHitPlaneCollection'; collection: TrackerHitPlaneCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimTrackerHitCollection'; collection: SimTrackerHitCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::CalorimeterHitCollection'; collection: CalorimeterHitCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimCalorimeterHitCollection'; collection: SimCalorimeterHitCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ClusterCollection'; collection: ClusterCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; collection: ReconstructedParticleCollection }; + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::EventHeaderCollection'; + collection: EventHeaderCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::VertexCollection'; + collection: VertexCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::TrackCollection'; + collection: TrackCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::TrackerHit3DCollection'; + collection: TrackerHit3DCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::TrackerHitPlaneCollection'; + collection: TrackerHitPlaneCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::SimTrackerHitCollection'; + collection: SimTrackerHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::CalorimeterHitCollection'; + collection: CalorimeterHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::SimCalorimeterHitCollection'; + collection: SimCalorimeterHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::ClusterCollection'; + collection: ClusterCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::ReconstructedParticleCollection'; + collection: ReconstructedParticleCollection; + }; } diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema4.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema4.ts index 4fba9acdc..0358569ef 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema4.ts +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema4.ts @@ -158,26 +158,76 @@ export namespace Schema4 { weights: number[]; // event weights in case there are multiple. **NOTE that weights[0] might not be the same as weight!** The corresponding names of the event weights should be stored in the collection named by edm4hep::labels::EventWeightsNames in the file-level metadata. }; - type EventHeaderCollection = EventHeader[]; - type VertexCollection = Vertex[]; - type TrackCollection = Track[]; - type TrackerHit3DCollection = TrackerHit3D[]; - type TrackerHitPlaneCollection = TrackerHitPlane[]; - type SimTrackerHitCollection = SimTrackerHit[]; - type CalorimeterHitCollection = CalorimeterHit[]; - type SimCalorimeterHitCollection = SimCalorimeterHit[]; - type ClusterCollection = Cluster[]; - type ReconstructedParticleCollection = ReconstructedParticle[]; + export type EventHeaderCollection = EventHeader[]; + export type VertexCollection = Vertex[]; + export type TrackCollection = Track[]; + export type TrackerHit3DCollection = TrackerHit3D[]; + export type TrackerHitPlaneCollection = TrackerHitPlane[]; + export type SimTrackerHitCollection = SimTrackerHit[]; + export type CalorimeterHitCollection = CalorimeterHit[]; + export type SimCalorimeterHitCollection = SimCalorimeterHit[]; + export type ClusterCollection = Cluster[]; + export type ReconstructedParticleCollection = ReconstructedParticle[]; export type Item = - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::EventHeaderCollection'; collection: EventHeaderCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; collection: VertexCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; collection: TrackCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHit3DCollection'; collection: TrackerHit3DCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHitPlaneCollection'; collection: TrackerHitPlaneCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimTrackerHitCollection'; collection: SimTrackerHitCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::CalorimeterHitCollection'; collection: CalorimeterHitCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimCalorimeterHitCollection'; collection: SimCalorimeterHitCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ClusterCollection'; collection: ClusterCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; collection: ReconstructedParticleCollection }; + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::EventHeaderCollection'; + collection: EventHeaderCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::VertexCollection'; + collection: VertexCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::TrackCollection'; + collection: TrackCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::TrackerHit3DCollection'; + collection: TrackerHit3DCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::TrackerHitPlaneCollection'; + collection: TrackerHitPlaneCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::SimTrackerHitCollection'; + collection: SimTrackerHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::CalorimeterHitCollection'; + collection: CalorimeterHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::SimCalorimeterHitCollection'; + collection: SimCalorimeterHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::ClusterCollection'; + collection: ClusterCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::ReconstructedParticleCollection'; + collection: ReconstructedParticleCollection; + }; } diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema5.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema5.ts index ba93d72b5..9f7342a35 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema5.ts +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema5.ts @@ -175,28 +175,83 @@ export namespace Schema5 { weights: number[]; // event weights in case there are multiple. **NOTE that weights[0] might not be the same as weight!** The corresponding names of the event weights should be stored in the collection named by edm4hep::labels::EventWeightsNames in the file-level metadata. }; - type EventHeaderCollection = EventHeader[]; - type VertexCollection = Vertex[]; - type TrackCollection = Track[]; - type TrackerHit3DCollection = TrackerHit3D[]; - type TrackerHitPlaneCollection = TrackerHitPlane[]; - type SenseWireHitCollection = SenseWireHit[]; - type SimTrackerHitCollection = SimTrackerHit[]; - type CalorimeterHitCollection = CalorimeterHit[]; - type SimCalorimeterHitCollection = SimCalorimeterHit[]; - type ClusterCollection = Cluster[]; - type ReconstructedParticleCollection = ReconstructedParticle[]; + export type EventHeaderCollection = EventHeader[]; + export type VertexCollection = Vertex[]; + export type TrackCollection = Track[]; + export type TrackerHit3DCollection = TrackerHit3D[]; + export type TrackerHitPlaneCollection = TrackerHitPlane[]; + export type SenseWireHitCollection = SenseWireHit[]; + export type SimTrackerHitCollection = SimTrackerHit[]; + export type CalorimeterHitCollection = CalorimeterHit[]; + export type SimCalorimeterHitCollection = SimCalorimeterHit[]; + export type ClusterCollection = Cluster[]; + export type ReconstructedParticleCollection = ReconstructedParticle[]; export type Item = - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::EventHeaderCollection'; collection: EventHeaderCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; collection: VertexCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; collection: TrackCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHit3DCollection'; collection: TrackerHit3DCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHitPlaneCollection'; collection: TrackerHitPlaneCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SenseWireHitCollection'; collection: SenseWireHitCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimTrackerHitCollection'; collection: SimTrackerHitCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::CalorimeterHitCollection'; collection: CalorimeterHitCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimCalorimeterHitCollection'; collection: SimCalorimeterHitCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ClusterCollection'; collection: ClusterCollection } - | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; collection: ReconstructedParticleCollection }; + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::EventHeaderCollection'; + collection: EventHeaderCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::VertexCollection'; + collection: VertexCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::TrackCollection'; + collection: TrackCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::TrackerHit3DCollection'; + collection: TrackerHit3DCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::TrackerHitPlaneCollection'; + collection: TrackerHitPlaneCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::SenseWireHitCollection'; + collection: SenseWireHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::SimTrackerHitCollection'; + collection: SimTrackerHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::CalorimeterHitCollection'; + collection: CalorimeterHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::SimCalorimeterHitCollection'; + collection: SimCalorimeterHitCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::ClusterCollection'; + collection: ClusterCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::ReconstructedParticleCollection'; + collection: ReconstructedParticleCollection; + }; } diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema6.ts b/packages/phoenix-event-display/src/lib/types/schemas/schema6.ts index c9d90fa47..c2926980d 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema6.ts +++ b/packages/phoenix-event-display/src/lib/types/schemas/schema6.ts @@ -166,9 +166,8 @@ export namespace Schema6 { particles: ObjectID[]; // reconstructed particles that have been combined to this particle }; - /** Event Header. Additional parameters are assumed to go into the metadata tree. */ - type EventHeader = { + export type EventHeader = { eventNumber: bigint; // event number runNumber: number; // run number timeStamp: bigint; // time stamp From 5065cdae0ccdb384791179c67ac7bf6f96936c87 Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Thu, 5 Mar 2026 10:26:37 +0100 Subject: [PATCH 09/30] Create types to group all schemas --- .../{schemas => edm4hep-schemas}/schema1.ts | 18 +- .../{schemas => edm4hep-schemas}/schema2.ts | 20 +- .../{schemas => edm4hep-schemas}/schema3.ts | 20 +- .../{schemas => edm4hep-schemas}/schema4.ts | 20 +- .../{schemas => edm4hep-schemas}/schema5.ts | 22 +-- .../{schemas => edm4hep-schemas}/schema6.ts | 20 +- .../{schemas => edm4hep-schemas}/utils.ts | 10 - .../src/lib/types/edm4hep.ts | 184 ++++++++++++++++++ .../src/lib/types/edmPhoenix.ts | 80 ++++++++ 9 files changed, 324 insertions(+), 70 deletions(-) rename packages/phoenix-event-display/src/lib/types/{schemas => edm4hep-schemas}/schema1.ts (97%) rename packages/phoenix-event-display/src/lib/types/{schemas => edm4hep-schemas}/schema2.ts (96%) rename packages/phoenix-event-display/src/lib/types/{schemas => edm4hep-schemas}/schema3.ts (96%) rename packages/phoenix-event-display/src/lib/types/{schemas => edm4hep-schemas}/schema4.ts (96%) rename packages/phoenix-event-display/src/lib/types/{schemas => edm4hep-schemas}/schema5.ts (96%) rename packages/phoenix-event-display/src/lib/types/{schemas => edm4hep-schemas}/schema6.ts (96%) rename packages/phoenix-event-display/src/lib/types/{schemas => edm4hep-schemas}/utils.ts (85%) create mode 100644 packages/phoenix-event-display/src/lib/types/edm4hep.ts create mode 100644 packages/phoenix-event-display/src/lib/types/edmPhoenix.ts diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema1.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts similarity index 97% rename from packages/phoenix-event-display/src/lib/types/schemas/schema1.ts rename to packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts index ed24e1404..54820b065 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema1.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts @@ -2,7 +2,7 @@ import { Vector3f, Vector3d, ObjectID } from './utils'; export namespace Schema1 { /** Vertex */ - type Vertex = { + export type Vertex = { primary: number; // boolean flag, if vertex is the primary vertex of the event chi2: number; // chi-squared of the vertex fit probability: number; // probability of the vertex fit @@ -26,7 +26,7 @@ export namespace Schema1 { }; /** Reconstructed track */ - type Track = { + export type Track = { type: number; // flagword that defines the type of track.Bits 16-31 are used internally chi2: number; // Chi^2 of the track fit ndf: number; // number of degrees of freedom of the track fit @@ -45,7 +45,7 @@ export namespace Schema1 { }; /** Tracker hit */ - type TrackerHit = { + export type TrackerHit = { cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit, either one of edm4hep::RawTimeSeries, edm4hep::SIMTRACKERHIT - see collection parameters "TrackerHitTypeNames" and "TrackerHitTypeValues". quality: number; // quality bit flag of the hit. @@ -58,7 +58,7 @@ export namespace Schema1 { }; /** Simulated tracker hit */ - type SimTrackerHit = { + export type SimTrackerHit = { cellID: bigint; // ID of the sensor that created this hit EDep: number; // energy deposited in the hit [GeV]. time: number; // proper time of the hit in the lab frame in [ns]. @@ -70,7 +70,7 @@ export namespace Schema1 { }; /** Calorimeter hit */ - type CalorimeterHit = { + export type CalorimeterHit = { cellID: bigint; // detector specific (geometrical) cell id. energy: number; // energy of the hit in [GeV]. energyError: number; // error of the hit energy in [GeV]. @@ -80,7 +80,7 @@ export namespace Schema1 { }; /** Simulated calorimeter hit */ - type SimCalorimeterHit = { + export type SimCalorimeterHit = { cellID: bigint; // ID of the sensor that created this hit energy: number; // energy of the hit in [GeV]. position: Vector3f; // position of the hit in world coordinates in [mm]. @@ -88,7 +88,7 @@ export namespace Schema1 { }; /** Calorimeter Hit Cluster */ - type Cluster = { + export type Cluster = { type: number; // flagword that defines the type of cluster. Bits 16-31 are used internally. energy: number; // energy of the cluster [GeV] energyError: number; // error on the energy @@ -105,7 +105,7 @@ export namespace Schema1 { }; /** Reconstructed Particle */ - type ReconstructedParticle = { + export type ReconstructedParticle = { type: number; // type of reconstructed particle. Check/set collection parameters ReconstructedParticleTypeNames and ReconstructedParticleTypeValues. energy: number; // [GeV] energy of the reconstructed particle. Four momentum state is not kept consistent internally. momentum: Vector3f; // [GeV] particle momentum. Four momentum state is not kept consistent internally. @@ -123,7 +123,7 @@ export namespace Schema1 { }; /** Event Header. Additional parameters are assumed to go into the metadata tree. */ - type EventHeader = { + export type EventHeader = { eventNumber: number; // event number runNumber: number; // run number timeStamp: bigint; // time stamp diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema2.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts similarity index 96% rename from packages/phoenix-event-display/src/lib/types/schemas/schema2.ts rename to packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts index df0262158..7308ca0cf 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema2.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts @@ -10,7 +10,7 @@ import { export namespace Schema2 { /** Vertex */ - type Vertex = { + export type Vertex = { type: number; // Flagword that defines the type of the vertex, see reserved bits for more information chi2: number; // chi-squared of the vertex fit ndf: number; // number of degrees of freedom of the vertex fit @@ -35,7 +35,7 @@ export namespace Schema2 { }; /** Reconstructed track */ - type Track = { + export type Track = { type: number; // flagword that defines the type of track chi2: number; // Chi^2 of the track fit ndf: number; // number of degrees of freedom of the track fit @@ -60,7 +60,7 @@ export namespace Schema2 { } /** Tracker hit */ - interface TrackerHit3D extends TrackerHit { + export interface TrackerHit3D extends TrackerHit { cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit @@ -72,7 +72,7 @@ export namespace Schema2 { } /** Tracker hit plane */ - interface TrackerHitPlane extends TrackerHit { + export interface TrackerHitPlane extends TrackerHit { cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit @@ -88,7 +88,7 @@ export namespace Schema2 { } /** Simulated tracker hit */ - type SimTrackerHit = { + export type SimTrackerHit = { cellID: bigint; // ID of the sensor that created this hit eDep: number; // [GeV] energy deposited in the hit time: number; // [ns] proper time of the hit in the lab frame @@ -100,7 +100,7 @@ export namespace Schema2 { }; /** Calorimeter hit */ - type CalorimeterHit = { + export type CalorimeterHit = { cellID: bigint; // detector specific (geometrical) cell id energy: number; // [GeV] energy of the hit energyError: number; // [GeV] error of the hit energy @@ -110,7 +110,7 @@ export namespace Schema2 { }; /** Simulated calorimeter hit */ - type SimCalorimeterHit = { + export type SimCalorimeterHit = { cellID: bigint; // ID of the sensor that created this hit energy: number; // [GeV] energy of the hit position: Vector3f; // [mm] position of the hit in world coordinates @@ -118,7 +118,7 @@ export namespace Schema2 { }; /** Calorimeter Hit Cluster */ - type Cluster = { + export type Cluster = { type: number; // flagword that defines the type of cluster energy: number; // [GeV] energy of the cluster energyError: number; // [GeV] error on the energy @@ -134,7 +134,7 @@ export namespace Schema2 { }; /** Reconstructed Particle */ - type ReconstructedParticle = { + export type ReconstructedParticle = { PDG: number; // PDG of the reconstructed particle. energy: number; // [GeV] energy of the reconstructed particle. Four momentum state is not kept consistent internally momentum: Vector3f; // [GeV] particle momentum. Four momentum state is not kept consistent internally @@ -150,7 +150,7 @@ export namespace Schema2 { }; /** Event Header. Additional parameters are assumed to go into the metadata tree. */ - type EventHeader = { + export type EventHeader = { eventNumber: number; // event number runNumber: number; // run number timeStamp: bigint; // time stamp diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema3.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts similarity index 96% rename from packages/phoenix-event-display/src/lib/types/schemas/schema3.ts rename to packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts index edf8bf265..14ab1f9c9 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema3.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts @@ -10,7 +10,7 @@ import { export namespace Schema3 { /** Vertex */ - type Vertex = { + export type Vertex = { type: number; // flagword that defines the type of the vertex, see reserved bits for more information chi2: number; // chi-squared of the vertex fit ndf: number; // number of degrees of freedom of the vertex fit @@ -35,7 +35,7 @@ export namespace Schema3 { }; /** Reconstructed track */ - type Track = { + export type Track = { type: number; // flagword that defines the type of track chi2: number; // chi-squared of the track fit ndf: number; // number of degrees of freedom of the track fit @@ -60,7 +60,7 @@ export namespace Schema3 { } /** Tracker hit */ - interface TrackerHit3D extends TrackerHit { + export interface TrackerHit3D extends TrackerHit { cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit @@ -72,7 +72,7 @@ export namespace Schema3 { } /** Tracker hit plane */ - interface TrackerHitPlane extends TrackerHit { + export interface TrackerHitPlane extends TrackerHit { cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit @@ -88,7 +88,7 @@ export namespace Schema3 { } /** Simulated tracker hit */ - type SimTrackerHit = { + export type SimTrackerHit = { cellID: bigint; // ID of the sensor that created this hit eDep: number; // [GeV] energy deposited in the hit time: number; // [ns] proper time of the hit in the lab frame @@ -100,7 +100,7 @@ export namespace Schema3 { }; /** Calorimeter hit */ - type CalorimeterHit = { + export type CalorimeterHit = { cellID: bigint; // detector specific (geometrical) cell id energy: number; // [GeV] energy of the hit energyError: number; // [GeV] error of the hit energy @@ -110,7 +110,7 @@ export namespace Schema3 { }; /** Simulated calorimeter hit */ - type SimCalorimeterHit = { + export type SimCalorimeterHit = { cellID: bigint; // ID of the sensor that created this hit energy: number; // [GeV] energy of the hit position: Vector3f; // [mm] position of the hit in world coordinates @@ -118,7 +118,7 @@ export namespace Schema3 { }; /** Calorimeter Hit Cluster */ - type Cluster = { + export type Cluster = { type: number; // flagword that defines the type of cluster energy: number; // [GeV] energy of the cluster energyError: number; // [GeV] error on the energy @@ -134,7 +134,7 @@ export namespace Schema3 { }; /** Reconstructed Particle */ - type ReconstructedParticle = { + export type ReconstructedParticle = { PDG: number; // PDG of the reconstructed particle. energy: number; // [GeV] energy of the reconstructed particle. Four momentum state is not kept consistent internally momentum: Vector3f; // [GeV] particle momentum. Four momentum state is not kept consistent internally @@ -150,7 +150,7 @@ export namespace Schema3 { }; /** Event Header. Additional parameters are assumed to go into the metadata tree. */ - type EventHeader = { + export type EventHeader = { eventNumber: bigint; // event number runNumber: number; // run number timeStamp: bigint; // time stamp diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema4.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts similarity index 96% rename from packages/phoenix-event-display/src/lib/types/schemas/schema4.ts rename to packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts index 0358569ef..07264c6aa 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema4.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts @@ -10,7 +10,7 @@ import { export namespace Schema4 { /** Vertex */ - type Vertex = { + export type Vertex = { type: number; // flagword that defines the type of the vertex, see reserved bits for more information chi2: number; // chi-squared of the vertex fit ndf: number; // number of degrees of freedom of the vertex fit @@ -35,7 +35,7 @@ export namespace Schema4 { }; /** Reconstructed track */ - type Track = { + export type Track = { type: number; // flagword that defines the type of track chi2: number; // chi-squared of the track fit ndf: number; // number of degrees of freedom of the track fit @@ -60,7 +60,7 @@ export namespace Schema4 { } /** Tracker hit */ - interface TrackerHit3D extends TrackerHit { + export interface TrackerHit3D extends TrackerHit { cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit @@ -72,7 +72,7 @@ export namespace Schema4 { } /** Tracker hit plane */ - interface TrackerHitPlane extends TrackerHit { + export interface TrackerHitPlane extends TrackerHit { cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit @@ -88,7 +88,7 @@ export namespace Schema4 { } /** Simulated tracker hit */ - type SimTrackerHit = { + export type SimTrackerHit = { cellID: bigint; // ID of the sensor that created this hit eDep: number; // [GeV] energy deposited in the hit time: number; // [ns] proper time of the hit in the lab frame @@ -100,7 +100,7 @@ export namespace Schema4 { }; /** Calorimeter hit */ - type CalorimeterHit = { + export type CalorimeterHit = { cellID: bigint; // detector specific (geometrical) cell id energy: number; // [GeV] energy of the hit energyError: number; // [GeV] error of the hit energy @@ -110,7 +110,7 @@ export namespace Schema4 { }; /** Simulated calorimeter hit */ - type SimCalorimeterHit = { + export type SimCalorimeterHit = { cellID: bigint; // ID of the sensor that created this hit energy: number; // [GeV] energy of the hit position: Vector3f; // [mm] position of the hit in world coordinates @@ -118,7 +118,7 @@ export namespace Schema4 { }; /** Calorimeter Hit Cluster */ - type Cluster = { + export type Cluster = { type: number; // flagword that defines the type of cluster energy: number; // [GeV] energy of the cluster energyError: number; // [GeV] error on the energy @@ -134,7 +134,7 @@ export namespace Schema4 { }; /** Reconstructed Particle */ - type ReconstructedParticle = { + export type ReconstructedParticle = { PDG: number; // PDG of the reconstructed particle. energy: number; // [GeV] energy of the reconstructed particle. Four momentum state is not kept consistent internally momentum: Vector3f; // [GeV] particle momentum. Four momentum state is not kept consistent internally @@ -150,7 +150,7 @@ export namespace Schema4 { }; /** Event Header. Additional parameters are assumed to go into the metadata tree. */ - type EventHeader = { + export type EventHeader = { eventNumber: bigint; // event number runNumber: number; // run number timeStamp: bigint; // time stamp diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema5.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts similarity index 96% rename from packages/phoenix-event-display/src/lib/types/schemas/schema5.ts rename to packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts index 9f7342a35..aa62f9bd5 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema5.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts @@ -10,7 +10,7 @@ import { export namespace Schema5 { /** Vertex */ - type Vertex = { + export type Vertex = { type: number; // flagword that defines the type of the vertex, see reserved bits for more information chi2: number; // chi-squared of the vertex fit ndf: number; // number of degrees of freedom of the vertex fit @@ -35,7 +35,7 @@ export namespace Schema5 { }; /** Reconstructed track */ - type Track = { + export type Track = { type: number; // flagword that defines the type of track chi2: number; // chi-squared of the track fit ndf: number; // number of degrees of freedom of the track fit @@ -60,7 +60,7 @@ export namespace Schema5 { } /** Tracker hit */ - interface TrackerHit3D extends TrackerHit { + export interface TrackerHit3D extends TrackerHit { cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit @@ -72,7 +72,7 @@ export namespace Schema5 { } /** Tracker hit plane */ - interface TrackerHitPlane extends TrackerHit { + export interface TrackerHitPlane extends TrackerHit { cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit @@ -88,7 +88,7 @@ export namespace Schema5 { } /** Sense wire hit, knowing only the distance to the wire. The circle representing possible positions is parametrized with its center, radius and normal vector (given by the wire direction). */ - interface SenseWireHit extends TrackerHit { + export interface SenseWireHit extends TrackerHit { cellID: bigint; // ID of the sensor that created this hit type: number; // type of the raw data hit quality: number; // quality bit flag of the hit @@ -105,7 +105,7 @@ export namespace Schema5 { } /** Simulated tracker hit */ - type SimTrackerHit = { + export type SimTrackerHit = { cellID: bigint; // ID of the sensor that created this hit eDep: number; // [GeV] energy deposited in the hit time: number; // [ns] proper time of the hit in the lab frame @@ -117,7 +117,7 @@ export namespace Schema5 { }; /** Calorimeter hit */ - type CalorimeterHit = { + export type CalorimeterHit = { cellID: bigint; // detector specific (geometrical) cell id energy: number; // [GeV] energy of the hit energyError: number; // [GeV] error of the hit energy @@ -127,7 +127,7 @@ export namespace Schema5 { }; /** Simulated calorimeter hit */ - type SimCalorimeterHit = { + export type SimCalorimeterHit = { cellID: bigint; // ID of the sensor that created this hit energy: number; // [GeV] energy of the hit position: Vector3f; // [mm] position of the hit in world coordinates @@ -135,7 +135,7 @@ export namespace Schema5 { }; /** Calorimeter Hit Cluster */ - type Cluster = { + export type Cluster = { type: number; // flagword that defines the type of cluster energy: number; // [GeV] energy of the cluster energyError: number; // [GeV] error on the energy @@ -151,7 +151,7 @@ export namespace Schema5 { }; /** Reconstructed Particle */ - type ReconstructedParticle = { + export type ReconstructedParticle = { PDG: number; // PDG of the reconstructed particle. energy: number; // [GeV] energy of the reconstructed particle. Four momentum state is not kept consistent internally momentum: Vector3f; // [GeV] particle momentum. Four momentum state is not kept consistent internally @@ -167,7 +167,7 @@ export namespace Schema5 { }; /** Event Header. Additional parameters are assumed to go into the metadata tree. */ - type EventHeader = { + export type EventHeader = { eventNumber: bigint; // event number runNumber: number; // run number timeStamp: bigint; // time stamp diff --git a/packages/phoenix-event-display/src/lib/types/schemas/schema6.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts similarity index 96% rename from packages/phoenix-event-display/src/lib/types/schemas/schema6.ts rename to packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts index c2926980d..b9aa5e6c7 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/schema6.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts @@ -10,7 +10,7 @@ import { export namespace Schema6 { /** Vertex */ - type Vertex = { + export type Vertex = { type: number; // flagword that defines the type of the vertex, see reserved bits for more information chi2: number; // chi-squared of the vertex fit ndf: number; // number of degrees of freedom of the vertex fit @@ -35,7 +35,7 @@ export namespace Schema6 { }; /** Reconstructed track */ - type Track = { + export type Track = { type: number; // flagword that defines the type of track chi2: number; // chi-squared of the track fit ndf: number; // number of degrees of freedom of the track fit @@ -60,7 +60,7 @@ export namespace Schema6 { } /** Tracker hit */ - interface TrackerHit3D extends TrackerHit { + export interface TrackerHit3D extends TrackerHit { cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit @@ -72,7 +72,7 @@ export namespace Schema6 { } /** Tracker hit plane */ - interface TrackerHitPlane extends TrackerHit { + export interface TrackerHitPlane extends TrackerHit { cellID: bigint; // ID of the sensor that created this hit type: number; // type of raw data hit quality: number; // quality bit flag of the hit @@ -88,7 +88,7 @@ export namespace Schema6 { } /** Sense wire hit, knowing only the distance to the wire. The circle representing possible positions is parametrized with its center, radius and normal vector (given by the wire direction). */ - interface SenseWireHit extends TrackerHit { + export interface SenseWireHit extends TrackerHit { cellID: bigint; // ID of the sensor that created this hit type: number; // type of the raw data hit quality: number; // quality bit flag of the hit @@ -105,7 +105,7 @@ export namespace Schema6 { } /** Simulated tracker hit */ - type SimTrackerHit = { + export type SimTrackerHit = { cellID: bigint; // ID of the sensor that created this hit eDep: number; // [GeV] energy deposited in the hit time: number; // [ns] proper time of the hit in the lab frame @@ -117,7 +117,7 @@ export namespace Schema6 { }; /** Calorimeter hit */ - type CalorimeterHit = { + export type CalorimeterHit = { cellID: bigint; // detector specific (geometrical) cell id energy: number; // [GeV] energy of the hit energyError: number; // [GeV] error of the hit energy @@ -127,7 +127,7 @@ export namespace Schema6 { }; /** Simulated calorimeter hit */ - type SimCalorimeterHit = { + export type SimCalorimeterHit = { cellID: bigint; // ID of the sensor that created this hit energy: number; // [GeV] energy of the hit position: Vector3f; // [mm] position of the hit in world coordinates @@ -135,7 +135,7 @@ export namespace Schema6 { }; /** Calorimeter Hit Cluster */ - type Cluster = { + export type Cluster = { type: number; // flagword that defines the type of cluster energy: number; // [GeV] energy of the cluster energyError: number; // [GeV] error on the energy @@ -151,7 +151,7 @@ export namespace Schema6 { }; /** Reconstructed Particle */ - type ReconstructedParticle = { + export type ReconstructedParticle = { PDG: number; // PDG of the reconstructed particle. energy: number; // [GeV] energy of the reconstructed particle. Four momentum state is not kept consistent internally momentum: Vector3f; // [GeV] particle momentum. Four momentum state is not kept consistent internally diff --git a/packages/phoenix-event-display/src/lib/types/schemas/utils.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/utils.ts similarity index 85% rename from packages/phoenix-event-display/src/lib/types/schemas/utils.ts rename to packages/phoenix-event-display/src/lib/types/edm4hep-schemas/utils.ts index 689ec4fd2..4b603f62d 100644 --- a/packages/phoenix-event-display/src/lib/types/schemas/utils.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/utils.ts @@ -41,13 +41,3 @@ export type ObjectID = { collectionID: number; index: number; }; - -export type edm4hepEvent = { - [name: string]: - | Schema6.Item - | Schema5.Item - | Schema4.Item - | Schema3.Item - | Schema2.Item - | Schema1.Item; -}; diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep.ts b/packages/phoenix-event-display/src/lib/types/edm4hep.ts new file mode 100644 index 000000000..ed1754c66 --- /dev/null +++ b/packages/phoenix-event-display/src/lib/types/edm4hep.ts @@ -0,0 +1,184 @@ +import { Schema1 } from './edm4hep-schemas/schema1'; +import { Schema2 } from './edm4hep-schemas/schema2'; +import { Schema3 } from './edm4hep-schemas/schema3'; +import { Schema4 } from './edm4hep-schemas/schema4'; +import { Schema5 } from './edm4hep-schemas/schema5'; +import { Schema6 } from './edm4hep-schemas/schema6'; + +export namespace edm4hep { + export type Vertex = + | Schema1.Vertex + | Schema2.Vertex + | Schema3.Vertex + | Schema4.Vertex + | Schema5.Vertex + | Schema6.Vertex; + + export type TrackerHit = Schema1.TrackerHit; + + export type TrackerHit3D = + | Schema2.TrackerHit3D + | Schema3.TrackerHit3D + | Schema4.TrackerHit3D + | Schema5.TrackerHit3D + | Schema6.TrackerHit3D; + + export type TrackerHitPlane = + | Schema2.TrackerHitPlane + | Schema3.TrackerHitPlane + | Schema4.TrackerHitPlane + | Schema5.TrackerHitPlane + | Schema6.TrackerHitPlane; + + export type SenseWireHit = Schema5.SenseWireHit | Schema6.SenseWireHit; + + export type SimTrackerHit = + | Schema1.SimTrackerHit + | Schema2.SimTrackerHit + | Schema3.SimTrackerHit + | Schema4.SimTrackerHit + | Schema5.SimTrackerHit + | Schema6.SimTrackerHit; + + export type CalorimeterHit = + | Schema1.CalorimeterHit + | Schema2.CalorimeterHit + | Schema3.CalorimeterHit + | Schema4.CalorimeterHit + | Schema5.CalorimeterHit + | Schema6.CalorimeterHit; + + export type SimCalorimeterHit = + | Schema1.SimCalorimeterHit + | Schema2.SimCalorimeterHit + | Schema3.SimCalorimeterHit + | Schema4.SimCalorimeterHit + | Schema5.SimCalorimeterHit + | Schema6.SimCalorimeterHit; + + export type Cluster = + | Schema1.Cluster + | Schema2.Cluster + | Schema3.Cluster + | Schema4.Cluster + | Schema5.Cluster + | Schema6.Cluster; + + export type ReconstructedParticle = + | Schema1.ReconstructedParticle + | Schema2.ReconstructedParticle + | Schema3.ReconstructedParticle + | Schema4.ReconstructedParticle + | Schema5.ReconstructedParticle + | Schema6.ReconstructedParticle; + + export type EventHeader = + | Schema1.EventHeader + | Schema2.EventHeader + | Schema3.EventHeader + | Schema4.EventHeader + | Schema5.EventHeader + | Schema6.EventHeader; + + export type EventHeaderCollection = + | Schema1.EventHeader[] + | Schema2.EventHeader[] + | Schema3.EventHeader[] + | Schema4.EventHeader[] + | Schema5.EventHeader[] + | Schema6.EventHeader[]; + + export type VertexCollection = + | Schema1.Vertex[] + | Schema2.Vertex[] + | Schema3.Vertex[] + | Schema4.Vertex[] + | Schema5.Vertex[] + | Schema6.Vertex[]; + + export type TrackCollection = + | Schema1.Track[] + | Schema2.Track[] + | Schema3.Track[] + | Schema4.Track[] + | Schema5.Track[] + | Schema6.Track[]; + + export type TrackerHitCollection = Schema1.TrackerHit[]; + + export type TrackerHit3DCollection = + | Schema2.TrackerHit3D[] + | Schema3.TrackerHit3D[] + | Schema4.TrackerHit3D[] + | Schema5.TrackerHit3D[] + | Schema6.TrackerHit3D[]; + + export type TrackerHitPlaneCollection = + | Schema2.TrackerHitPlane[] + | Schema3.TrackerHitPlane[] + | Schema4.TrackerHitPlane[] + | Schema5.TrackerHitPlane[] + | Schema6.TrackerHitPlane[]; + + export type SenseWireHitCollection = + | Schema5.SenseWireHit[] + | Schema6.SenseWireHit[]; + + export type SimTrackerHitCollection = + | Schema1.SimTrackerHit[] + | Schema2.SimTrackerHit[] + | Schema3.SimTrackerHit[] + | Schema4.SimTrackerHit[] + | Schema5.SimTrackerHit[] + | Schema6.SimTrackerHit[]; + + export type CalorimeterHitCollection = + | Schema1.CalorimeterHit[] + | Schema2.CalorimeterHit[] + | Schema3.CalorimeterHit[] + | Schema4.CalorimeterHit[] + | Schema5.CalorimeterHit[] + | Schema6.CalorimeterHit[]; + + export type SimCalorimeterHitCollection = + | Schema1.SimCalorimeterHit[] + | Schema2.SimCalorimeterHit[] + | Schema3.SimCalorimeterHit[] + | Schema4.SimCalorimeterHit[] + | Schema5.SimCalorimeterHit[] + | Schema6.SimCalorimeterHit[]; + + export type ClusterCollection = + | Schema1.Cluster[] + | Schema2.Cluster[] + | Schema3.Cluster[] + | Schema4.Cluster[] + | Schema5.Cluster[] + | Schema6.Cluster[]; + + export type ReconstructedParticleCollection = + | Schema1.ReconstructedParticle[] + | Schema2.ReconstructedParticle[] + | Schema3.ReconstructedParticle[] + | Schema4.ReconstructedParticle[] + | Schema5.ReconstructedParticle[] + | Schema6.ReconstructedParticle[]; + + export type Item = + | Schema1.Item[] + | Schema2.Item[] + | Schema3.Item[] + | Schema4.Item[] + | Schema5.Item[] + | Schema6.Item[]; + + export type Event = { + [name: string]: + | Schema6.Item + | Schema5.Item + | Schema4.Item + | Schema3.Item + | Schema2.Item + | Schema1.Item; + }; +} diff --git a/packages/phoenix-event-display/src/lib/types/edmPhoenix.ts b/packages/phoenix-event-display/src/lib/types/edmPhoenix.ts new file mode 100644 index 000000000..c40f30a69 --- /dev/null +++ b/packages/phoenix-event-display/src/lib/types/edmPhoenix.ts @@ -0,0 +1,80 @@ +import { Vector3d } from './edm4hep-schemas/utils'; + +export namespace edmPhoenix { + export type Vertex = { + color?: string; + x: number; + y: number; + z: number; + }; + + export type Track = { + pos: Vector3d; + color?: string; + d0?: number; + z0?: number; + phi?: number; + eta?: number; + qOverP?: number; + }; + + type Hit = { + type?: 'Point'; + pos: Vector3d; + color?: string; + }; + + type CaloCell = { + energy: number; + phi: number; + eta: number; + }; + + type CaloCluster = { + energy: number; + phi: number; + eta: number; + }; + + type Jet = { + eta: number; + phi: number; + theta?: number; + energy?: number; + et?: number; + coneR: number; + color?: string; + }; + + type MissingEnegy = { + etx: number; + ety: number; + color?: string; + }; + + export type Event = { + 'event number'?: number; + 'run number'?: number; + Vertices?: { + [name: string]: Vertex[]; + }; + Tracks?: { + [name: string]: Track[]; + }; + Hits?: { + [name: string]: Hit[]; + }; + CaloCells?: { + [name: string]: CaloCell[]; + }; + CaloClusters?: { + [name: string]: CaloCluster[]; + }; + Jets?: { + [name: string]: Jet[]; + }; + MissingEnergy?: { + [name: string]: MissingEnegy[]; + }; + }; +} From 9b52204f9f8d7e59c6804763217b801eb93ac35b Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Thu, 5 Mar 2026 10:56:30 +0100 Subject: [PATCH 10/30] Acount for link type between ReconstructedParticle and MCParticle accross all schemas --- .../src/lib/types/edm4hep-schemas/schema1.ts | 14 ++++++++++++++ .../src/lib/types/edm4hep-schemas/schema2.ts | 14 ++++++++++++++ .../src/lib/types/edm4hep-schemas/schema3.ts | 15 +++++++++++++++ .../src/lib/types/edm4hep-schemas/schema4.ts | 14 ++++++++++++++ .../src/lib/types/edm4hep-schemas/schema5.ts | 14 ++++++++++++++ .../src/lib/types/edm4hep-schemas/schema6.ts | 14 ++++++++++++++ .../src/lib/types/edm4hep.ts | 16 ++++++++++++++++ 7 files changed, 101 insertions(+) diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts index 54820b065..3ba9bb83d 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts @@ -130,6 +130,13 @@ export namespace Schema1 { weight: number; // event weight }; + /** Used to keep track of the correspondence between MC and reconstructed particles */ + export type MCRecoParticleAssociation = { + weight: number; // weight of this association + rec: ObjectID; // reference to the reconstructed particle + sim: ObjectID; // reference to the Monte-Carlo particle + }; + export type EventHeaderCollection = EventHeader[]; export type VertexCollection = Vertex[]; export type TrackCollection = Track[]; @@ -139,6 +146,7 @@ export namespace Schema1 { export type SimCalorimeterHitCollection = SimCalorimeterHit[]; export type ClusterCollection = Cluster[]; export type ReconstructedParticleCollection = ReconstructedParticle[]; + export type MCRecoParticleAssociationCollection = MCRecoParticleAssociation[]; export type Item = | { @@ -194,5 +202,11 @@ export namespace Schema1 { collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; collection: ReconstructedParticleCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::MCRecoParticleAssociation'; + collection: MCRecoParticleAssociationCollection; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts index 7308ca0cf..18ef59b9f 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts @@ -158,6 +158,13 @@ export namespace Schema2 { weights: number[]; // event weights in case there are multiple. **NOTE that weights[0] might not be the same as weight!** Event weight names should be stored using the edm4hep::EventWeights name in the file level metadata }; + /** Link between a ReconstructedParticle and the corresponding MCParticle */ + export type RecoMCParticleLink = { + weight: number; // weight of this link + from: ObjectID; // reference to the reconstructed particle + to: ObjectID; // reference to the Monte-Carlo particle + }; + export type EventHeaderCollection = EventHeader[]; export type VertexCollection = Vertex[]; export type TrackCollection = Track[]; @@ -168,6 +175,7 @@ export namespace Schema2 { export type SimCalorimeterHitCollection = SimCalorimeterHit[]; export type ClusterCollection = Cluster[]; export type ReconstructedParticleCollection = ReconstructedParticle[]; + export type RecoMCParticleLinkCollection = RecoMCParticleLink[]; export type Item = | { @@ -229,5 +237,11 @@ export namespace Schema2 { collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; collection: ReconstructedParticleCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::RecoMCParticleLink'; + collection: RecoMCParticleLinkCollection; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts index 14ab1f9c9..a86e31ec8 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts @@ -158,6 +158,14 @@ export namespace Schema3 { weights: number[]; // event weights in case there are multiple. **NOTE that weights[0] might not be the same as weight!** Event weight names should be stored using the edm4hep::EventWeights name in the file level metadata }; + + /** Link between a ReconstructedParticle and an MCParticle */ + export type RecoMCParticleLink = { + weight: number; // weight of this link + from: ObjectID; // reference to the reconstructed particle + to: ObjectID; // reference to the Monte-Carlo particle + }; + export type EventHeaderCollection = EventHeader[]; export type VertexCollection = Vertex[]; export type TrackCollection = Track[]; @@ -168,6 +176,7 @@ export namespace Schema3 { export type SimCalorimeterHitCollection = SimCalorimeterHit[]; export type ClusterCollection = Cluster[]; export type ReconstructedParticleCollection = ReconstructedParticle[]; + export type RecoMCParticleLinkCollection = RecoMCParticleLink[]; export type Item = | { @@ -229,5 +238,11 @@ export namespace Schema3 { collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; collection: ReconstructedParticleCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'podio::LinkCollection'; + collection: RecoMCParticleLinkCollection; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts index 07264c6aa..653cc2b5d 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts @@ -158,6 +158,13 @@ export namespace Schema4 { weights: number[]; // event weights in case there are multiple. **NOTE that weights[0] might not be the same as weight!** The corresponding names of the event weights should be stored in the collection named by edm4hep::labels::EventWeightsNames in the file-level metadata. }; + /** Link between a ReconstructedParticle and an MCParticle */ + export type RecoMCParticleLink = { + weight: number; // weight of this link + from: ObjectID; // reference to the reconstructed particle + to: ObjectID; // reference to the Monte-Carlo particle + }; + export type EventHeaderCollection = EventHeader[]; export type VertexCollection = Vertex[]; export type TrackCollection = Track[]; @@ -168,6 +175,7 @@ export namespace Schema4 { export type SimCalorimeterHitCollection = SimCalorimeterHit[]; export type ClusterCollection = Cluster[]; export type ReconstructedParticleCollection = ReconstructedParticle[]; + export type RecoMCParticleLinkCollection = RecoMCParticleLink[]; export type Item = | { @@ -229,5 +237,11 @@ export namespace Schema4 { collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; collection: ReconstructedParticleCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'podio::LinkCollection'; + collection: RecoMCParticleLinkCollection; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts index aa62f9bd5..59b1627bc 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts @@ -175,6 +175,13 @@ export namespace Schema5 { weights: number[]; // event weights in case there are multiple. **NOTE that weights[0] might not be the same as weight!** The corresponding names of the event weights should be stored in the collection named by edm4hep::labels::EventWeightsNames in the file-level metadata. }; + /** Link between a ReconstructedParticle and an MCParticle */ + export type RecoMCParticleLink = { + weight: number; // weight of this link + from: ObjectID; // reference to the reconstructed particle + to: ObjectID; // reference to the Monte-Carlo particle + }; + export type EventHeaderCollection = EventHeader[]; export type VertexCollection = Vertex[]; export type TrackCollection = Track[]; @@ -186,6 +193,7 @@ export namespace Schema5 { export type SimCalorimeterHitCollection = SimCalorimeterHit[]; export type ClusterCollection = Cluster[]; export type ReconstructedParticleCollection = ReconstructedParticle[]; + export type RecoMCParticleLinkCollection = RecoMCParticleLink[]; export type Item = | { @@ -253,5 +261,11 @@ export namespace Schema5 { collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; collection: ReconstructedParticleCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'podio::LinkCollection'; + collection: RecoMCParticleLinkCollection; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts index b9aa5e6c7..0ae20f757 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts @@ -175,6 +175,13 @@ export namespace Schema6 { weights: number[]; // event weights in case there are multiple. **NOTE that weights[0] might not be the same as weight!** The corresponding names of the event weights should be stored in the collection named by edm4hep::labels::EventWeightsNames in the file-level metadata. }; + /** Link between a ReconstructedParticle and an MCParticle */ + export type RecoMCParticleLink = { + weight: number; // weight of this link + from: ObjectID; // reference to the reconstructed particle + to: ObjectID; // reference to the Monte-Carlo particle + }; + export type EventHeaderCollection = EventHeader[]; export type VertexCollection = Vertex[]; export type TrackCollection = Track[]; @@ -186,6 +193,7 @@ export namespace Schema6 { export type SimCalorimeterHitCollection = SimCalorimeterHit[]; export type ClusterCollection = Cluster[]; export type ReconstructedParticleCollection = ReconstructedParticle[]; + export type RecoMCParticleLinkCollection = RecoMCParticleLink[]; export type Item = | { @@ -253,5 +261,11 @@ export namespace Schema6 { collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; collection: ReconstructedParticleCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'podio::LinkCollection'; + collection: RecoMCParticleLinkCollection; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep.ts b/packages/phoenix-event-display/src/lib/types/edm4hep.ts index ed1754c66..d3e01459d 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep.ts @@ -104,6 +104,14 @@ export namespace edm4hep { | Schema5.Track[] | Schema6.Track[]; + export type RecoMCParticleLink = + | Schema1.MCRecoParticleAssociation[] + | Schema2.RecoMCParticleLink[] + | Schema3.RecoMCParticleLink[] + | Schema4.RecoMCParticleLink[] + | Schema5.RecoMCParticleLink[] + | Schema6.RecoMCParticleLink[]; + export type TrackerHitCollection = Schema1.TrackerHit[]; export type TrackerHit3DCollection = @@ -164,6 +172,14 @@ export namespace edm4hep { | Schema5.ReconstructedParticle[] | Schema6.ReconstructedParticle[]; + export type RecoMCParticleLinkCollection = + | Schema1.MCRecoParticleAssociationCollection[] + | Schema2.RecoMCParticleLinkCollection[] + | Schema3.RecoMCParticleLinkCollection[] + | Schema4.RecoMCParticleLinkCollection[] + | Schema5.RecoMCParticleLinkCollection[] + | Schema6.RecoMCParticleLinkCollection[]; + export type Item = | Schema1.Item[] | Schema2.Item[] From 6155c941830f3f6517091aab567c50aef59bb7cc Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Thu, 5 Mar 2026 17:10:55 +0100 Subject: [PATCH 11/30] Fix types --- .../src/lib/types/edm4hep.ts | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep.ts b/packages/phoenix-event-display/src/lib/types/edm4hep.ts index d3e01459d..6e7b22f95 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep.ts @@ -180,21 +180,13 @@ export namespace edm4hep { | Schema5.RecoMCParticleLinkCollection[] | Schema6.RecoMCParticleLinkCollection[]; - export type Item = - | Schema1.Item[] - | Schema2.Item[] - | Schema3.Item[] - | Schema4.Item[] - | Schema5.Item[] - | Schema6.Item[]; - export type Event = { [name: string]: - | Schema6.Item - | Schema5.Item - | Schema4.Item - | Schema3.Item + | Schema1.Item | Schema2.Item - | Schema1.Item; + | Schema3.Item + | Schema4.Item + | Schema5.Item + | Schema6.Item; }; } From e2af01ce04db21dd4f764941d29e12f7b0a093ff Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Thu, 5 Mar 2026 18:01:30 +0100 Subject: [PATCH 12/30] Add MCParticle to all schema types --- .../src/lib/types/edm4hep-schemas/schema1.ts | 27 ++++++++++++++++++- .../src/lib/types/edm4hep-schemas/schema2.ts | 26 ++++++++++++++++++ .../src/lib/types/edm4hep-schemas/schema3.ts | 24 +++++++++++++++++ .../src/lib/types/edm4hep-schemas/schema4.ts | 24 +++++++++++++++++ .../src/lib/types/edm4hep-schemas/schema5.ts | 24 +++++++++++++++++ .../src/lib/types/edm4hep-schemas/schema6.ts | 24 +++++++++++++++++ .../src/lib/types/edm4hep-schemas/utils.ts | 5 ++++ .../src/lib/types/edm4hep.ts | 25 ++++++++++++++--- 8 files changed, 175 insertions(+), 4 deletions(-) diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts index 3ba9bb83d..e784ac7b7 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts @@ -1,4 +1,4 @@ -import { Vector3f, Vector3d, ObjectID } from './utils'; +import { Vector3f, Vector3d, Vector2i, ObjectID } from './utils'; export namespace Schema1 { /** Vertex */ @@ -137,6 +137,24 @@ export namespace Schema1 { sim: ObjectID; // reference to the Monte-Carlo particle }; + /** The Monte Carlo particle - based on the lcio::MCParticle. */ + export type MCParticle = { + PDG: number; // PDG code of the particle + generatorStatus: number; // status of the particle as defined by the generator + simulatorStatus: number; // status of the particle from the simulation program - use BIT constants below + charge: number; // particle charge + time: number; // creation time of the particle in [ns] wrt. the event, e.g. for preassigned decays or decays in flight from the simulator. + mass: number; // mass of the particle in [GeV] + vertex: Vector3d; // production vertex of the particle in [mm]. + endpoint: Vector3d; // endpoint of the particle in [mm] + momentum: Vector3f; // particle 3-momentum at the production vertex in [GeV] + momentumAtEndpoint: Vector3f; // particle 3-momentum at the endpoint in [GeV] + spin: Vector3f; // spin (helicity) vector of the particle. + colorFlow: Vector2i; // color flow as defined by the generator + parents: ObjectID[]; // The parents of this particle. + daughters: ObjectID[]; // The daughters this particle. + }; + export type EventHeaderCollection = EventHeader[]; export type VertexCollection = Vertex[]; export type TrackCollection = Track[]; @@ -147,6 +165,7 @@ export namespace Schema1 { export type ClusterCollection = Cluster[]; export type ReconstructedParticleCollection = ReconstructedParticle[]; export type MCRecoParticleAssociationCollection = MCRecoParticleAssociation[]; + export type MCParticleCollection = MCParticle[]; export type Item = | { @@ -208,5 +227,11 @@ export namespace Schema1 { collSchemaVersion: number; collType: 'edm4hep::MCRecoParticleAssociation'; collection: MCRecoParticleAssociationCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::MCParticleCollection'; + collection: MCParticleCollection; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts index 18ef59b9f..1b6c67041 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts @@ -3,6 +3,7 @@ import { CovMatrix4f, CovMatrix6f, Vector2f, + Vector2i, Vector3f, Vector3d, ObjectID, @@ -165,6 +166,24 @@ export namespace Schema2 { to: ObjectID; // reference to the Monte-Carlo particle }; + /** The Monte Carlo particle - based on the lcio::MCParticle. */ + export type MCParticle = { + PDG: number; // PDG code of the particle + generatorStatus: number; // status of the particle as defined by the generator + simulatorStatus: number; // status of the particle from the simulation program - use BIT constants below + charge: number; // particle charge + time: number; // [ns] creation time of the particle in wrt. the event, e.g. for preassigned decays or decays in flight from the simulator + mass: number; // [GeV] mass of the particle + vertex: Vector3d; // [mm] production vertex of the particle + endpoint: Vector3d; // [mm] endpoint of the particle + momentum: Vector3d; // [GeV] particle 3-momentum at the production vertex + momentumAtEndpoint: Vector3d; // [GeV] particle 3-momentum at the endpoint + spin: Vector3f; // spin (helicity) vector of the particle + colorFlow: Vector2i; // color flow as defined by the generator + parents: ObjectID[]; // The parents of this particle + daughters: ObjectID[]; // The daughters this particle + }; + export type EventHeaderCollection = EventHeader[]; export type VertexCollection = Vertex[]; export type TrackCollection = Track[]; @@ -176,6 +195,7 @@ export namespace Schema2 { export type ClusterCollection = Cluster[]; export type ReconstructedParticleCollection = ReconstructedParticle[]; export type RecoMCParticleLinkCollection = RecoMCParticleLink[]; + export type MCParticleCollection = MCParticle[]; export type Item = | { @@ -243,5 +263,11 @@ export namespace Schema2 { collSchemaVersion: number; collType: 'edm4hep::RecoMCParticleLink'; collection: RecoMCParticleLinkCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::MCParticleCollection'; + collection: MCParticleCollection; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts index a86e31ec8..cd230ad2d 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts @@ -166,6 +166,23 @@ export namespace Schema3 { to: ObjectID; // reference to the Monte-Carlo particle }; + /** The Monte Carlo particle - based on the lcio::MCParticle. */ + export type MCParticle = { + PDG: number; // PDG code of the particle + generatorStatus: number; // status of the particle as defined by the generator + simulatorStatus: number; // status of the particle from the simulation program - use BIT constants below + charge: number; // [e] particle charge + time: number; // [ns] creation time of the particle in wrt. the event, e.g. for preassigned decays or decays in flight from the simulator + mass: number; // [GeV] mass of the particle + vertex: Vector3d; // [mm] production vertex of the particle + endpoint: Vector3d; // [mm] endpoint of the particle + momentum: Vector3d; // [GeV] particle 3-momentum at the production vertex + momentumAtEndpoint: Vector3d; // [GeV] particle 3-momentum at the endpoint + spin: Vector3f; // spin (helicity) vector of the particle + parents: ObjectID[]; // The parents of this particle + daughters: ObjectID[]; // The daughters this particle + }; + export type EventHeaderCollection = EventHeader[]; export type VertexCollection = Vertex[]; export type TrackCollection = Track[]; @@ -177,6 +194,7 @@ export namespace Schema3 { export type ClusterCollection = Cluster[]; export type ReconstructedParticleCollection = ReconstructedParticle[]; export type RecoMCParticleLinkCollection = RecoMCParticleLink[]; + export type MCParticleCollection = MCParticle[]; export type Item = | { @@ -244,5 +262,11 @@ export namespace Schema3 { collSchemaVersion: number; collType: 'podio::LinkCollection'; collection: RecoMCParticleLinkCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::MCParticleCollection'; + collection: MCParticleCollection; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts index 653cc2b5d..b95f017b5 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts @@ -165,6 +165,23 @@ export namespace Schema4 { to: ObjectID; // reference to the Monte-Carlo particle }; + /** The Monte Carlo particle - based on the lcio::MCParticle. */ + export type MCParticle = { + PDG: number; // PDG code of the particle + generatorStatus: number; // status of the particle as defined by the generator + simulatorStatus: number; // status of the particle from the simulation program - use BIT constants below + charge: number; // [e] particle charge + time: number; // [ns] creation time of the particle in wrt. the event, e.g. for preassigned decays or decays in flight from the simulator + mass: number; // [GeV] mass of the particle + vertex: Vector3d; // [mm] production vertex of the particle + endpoint: Vector3d; // [mm] endpoint of the particle + momentum: Vector3d; // [GeV] particle 3-momentum at the production vertex + momentumAtEndpoint: Vector3d; // [GeV] particle 3-momentum at the endpoint + helicity: number; // particle helicity (9 if unset) + parents: ObjectID[]; // The parents of this particle + daughters: ObjectID[]; // The daughters this particle + }; + export type EventHeaderCollection = EventHeader[]; export type VertexCollection = Vertex[]; export type TrackCollection = Track[]; @@ -176,6 +193,7 @@ export namespace Schema4 { export type ClusterCollection = Cluster[]; export type ReconstructedParticleCollection = ReconstructedParticle[]; export type RecoMCParticleLinkCollection = RecoMCParticleLink[]; + export type MCParticleCollection = MCParticle[]; export type Item = | { @@ -243,5 +261,11 @@ export namespace Schema4 { collSchemaVersion: number; collType: 'podio::LinkCollection'; collection: RecoMCParticleLinkCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::MCParticleCollection'; + collection: MCParticleCollection; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts index 59b1627bc..a042ec961 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts @@ -182,6 +182,23 @@ export namespace Schema5 { to: ObjectID; // reference to the Monte-Carlo particle }; + /** The Monte Carlo particle - based on the lcio::MCParticle. */ + export type MCParticle = { + PDG: number; // PDG code of the particle + generatorStatus: number; // status of the particle as defined by the generator + simulatorStatus: number; // status of the particle from the simulation program - use BIT constants below + charge: number; // [e] particle charge + time: number; // [ns] creation time of the particle in wrt. the event, e.g. for preassigned decays or decays in flight from the simulator + mass: number; // [GeV] mass of the particle + vertex: Vector3d; // [mm] production vertex of the particle + endpoint: Vector3d; // [mm] endpoint of the particle + momentum: Vector3d; // [GeV] particle 3-momentum at the production vertex + momentumAtEndpoint: Vector3d; // [GeV] particle 3-momentum at the endpoint + helicity: number; // particle helicity (9 if unset) + parents: ObjectID[]; // The parents of this particle + daughters: ObjectID[]; // The daughters this particle + }; + export type EventHeaderCollection = EventHeader[]; export type VertexCollection = Vertex[]; export type TrackCollection = Track[]; @@ -194,6 +211,7 @@ export namespace Schema5 { export type ClusterCollection = Cluster[]; export type ReconstructedParticleCollection = ReconstructedParticle[]; export type RecoMCParticleLinkCollection = RecoMCParticleLink[]; + export type MCParticleCollection = MCParticle[]; export type Item = | { @@ -267,5 +285,11 @@ export namespace Schema5 { collSchemaVersion: number; collType: 'podio::LinkCollection'; collection: RecoMCParticleLinkCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::MCParticleCollection'; + collection: MCParticleCollection; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts index 0ae20f757..c8e42250b 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts @@ -182,6 +182,23 @@ export namespace Schema6 { to: ObjectID; // reference to the Monte-Carlo particle }; + /** The Monte Carlo particle - based on the lcio::MCParticle. */ + export type MCParticle = { + PDG: number; // PDG code of the particle + generatorStatus: number; // status of the particle as defined by the generator + simulatorStatus: number; // status of the particle from the simulation program - use BIT constants below + charge: number; // [e] particle charge + time: number; // [ns] creation time of the particle in wrt. the event, e.g. for preassigned decays or decays in flight from the simulator + mass: number; // [GeV] mass of the particle + vertex: Vector3d; // [mm] production vertex of the particle + endpoint: Vector3d; // [mm] endpoint of the particle + momentum: Vector3d; // [GeV] particle 3-momentum at the production vertex + momentumAtEndpoint: Vector3d; // [GeV] particle 3-momentum at the endpoint + helicity: number; // particle helicity (9 if unset) + parents: ObjectID[]; // The parents of this particle + daughters: ObjectID[]; // The daughters this particle + }; + export type EventHeaderCollection = EventHeader[]; export type VertexCollection = Vertex[]; export type TrackCollection = Track[]; @@ -194,6 +211,7 @@ export namespace Schema6 { export type ClusterCollection = Cluster[]; export type ReconstructedParticleCollection = ReconstructedParticle[]; export type RecoMCParticleLinkCollection = RecoMCParticleLink[]; + export type MCParticleCollection = MCParticle[]; export type Item = | { @@ -267,5 +285,11 @@ export namespace Schema6 { collSchemaVersion: number; collType: 'podio::LinkCollection'; collection: RecoMCParticleLinkCollection; + } + | { + collID: number; + collSchemaVersion: number; + collType: 'edm4hep::MCParticleCollection'; + collection: MCParticleCollection; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/utils.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/utils.ts index 4b603f62d..9869aa529 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/utils.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/utils.ts @@ -25,6 +25,11 @@ export type Vector2f = { b: number; }; +export type Vector2i = { + a: number; + b: number; +}; + export type Vector3f = { x: number; y: number; diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep.ts b/packages/phoenix-event-display/src/lib/types/edm4hep.ts index 6e7b22f95..3b1164911 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep.ts @@ -104,8 +104,9 @@ export namespace edm4hep { | Schema5.Track[] | Schema6.Track[]; + export type MCRecoParticleAssociation = Schema1.MCRecoParticleAssociation[]; + export type RecoMCParticleLink = - | Schema1.MCRecoParticleAssociation[] | Schema2.RecoMCParticleLink[] | Schema3.RecoMCParticleLink[] | Schema4.RecoMCParticleLink[] @@ -172,8 +173,26 @@ export namespace edm4hep { | Schema5.ReconstructedParticle[] | Schema6.ReconstructedParticle[]; - export type RecoMCParticleLinkCollection = - | Schema1.MCRecoParticleAssociationCollection[] + export type MCParticle = + | Schema1.MCParticle + | Schema2.MCParticle + | Schema3.MCParticle + | Schema4.MCParticle + | Schema5.MCParticle + | Schema6.MCParticle; + + export type MCParticleCollection = + | Schema1.MCParticle[] + | Schema2.MCParticle[] + | Schema3.MCParticle[] + | Schema4.MCParticle[] + | Schema5.MCParticle[] + | Schema6.MCParticle[]; + + export type AssociationCollection = + Schema1.MCRecoParticleAssociationCollection[]; + + export type LinkCollection = | Schema2.RecoMCParticleLinkCollection[] | Schema3.RecoMCParticleLinkCollection[] | Schema4.RecoMCParticleLinkCollection[] From 2de875bd9a000085088710e1a2993c26a97634cb Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Thu, 5 Mar 2026 18:22:23 +0100 Subject: [PATCH 13/30] Simplify types --- .../src/lib/types/edm4hep.ts | 184 +++++++++--------- 1 file changed, 97 insertions(+), 87 deletions(-) diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep.ts b/packages/phoenix-event-display/src/lib/types/edm4hep.ts index 3b1164911..5cf083681 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep.ts @@ -80,124 +80,134 @@ export namespace edm4hep { | Schema5.EventHeader | Schema6.EventHeader; + export type MCParticle = + | Schema1.MCParticle + | Schema2.MCParticle + | Schema3.MCParticle + | Schema4.MCParticle + | Schema5.MCParticle + | Schema6.MCParticle; + + export type Association = Schema1.MCRecoParticleAssociation; + + export type Link = + | Schema2.RecoMCParticleLink + | Schema3.RecoMCParticleLink + | Schema4.RecoMCParticleLink + | Schema5.RecoMCParticleLink + | Schema6.RecoMCParticleLink; + export type EventHeaderCollection = - | Schema1.EventHeader[] - | Schema2.EventHeader[] - | Schema3.EventHeader[] - | Schema4.EventHeader[] - | Schema5.EventHeader[] - | Schema6.EventHeader[]; + | Schema1.EventHeaderCollection + | Schema2.EventHeaderCollection + | Schema3.EventHeaderCollection + | Schema4.EventHeaderCollection + | Schema5.EventHeaderCollection + | Schema6.EventHeaderCollection; export type VertexCollection = - | Schema1.Vertex[] - | Schema2.Vertex[] - | Schema3.Vertex[] - | Schema4.Vertex[] - | Schema5.Vertex[] - | Schema6.Vertex[]; + | Schema1.VertexCollection + | Schema2.VertexCollection + | Schema3.VertexCollection + | Schema4.VertexCollection + | Schema5.VertexCollection + | Schema6.VertexCollection; export type TrackCollection = - | Schema1.Track[] - | Schema2.Track[] - | Schema3.Track[] - | Schema4.Track[] - | Schema5.Track[] - | Schema6.Track[]; + | Schema1.TrackCollection + | Schema2.TrackCollection + | Schema3.TrackCollection + | Schema4.TrackCollection + | Schema5.TrackCollection + | Schema6.TrackCollection; - export type MCRecoParticleAssociation = Schema1.MCRecoParticleAssociation[]; + export type MCRecoParticleAssociation = + Schema1.MCRecoParticleAssociationCollection; export type RecoMCParticleLink = - | Schema2.RecoMCParticleLink[] - | Schema3.RecoMCParticleLink[] - | Schema4.RecoMCParticleLink[] - | Schema5.RecoMCParticleLink[] - | Schema6.RecoMCParticleLink[]; + | Schema2.RecoMCParticleLinkCollection + | Schema3.RecoMCParticleLinkCollection + | Schema4.RecoMCParticleLinkCollection + | Schema5.RecoMCParticleLinkCollection + | Schema6.RecoMCParticleLinkCollection; - export type TrackerHitCollection = Schema1.TrackerHit[]; + export type TrackerHitCollection = Schema1.TrackerHitCollection; export type TrackerHit3DCollection = - | Schema2.TrackerHit3D[] - | Schema3.TrackerHit3D[] - | Schema4.TrackerHit3D[] - | Schema5.TrackerHit3D[] - | Schema6.TrackerHit3D[]; + | Schema2.TrackerHit3DCollection + | Schema3.TrackerHit3DCollection + | Schema4.TrackerHit3DCollection + | Schema5.TrackerHit3DCollection + | Schema6.TrackerHit3DCollection; export type TrackerHitPlaneCollection = - | Schema2.TrackerHitPlane[] - | Schema3.TrackerHitPlane[] - | Schema4.TrackerHitPlane[] - | Schema5.TrackerHitPlane[] - | Schema6.TrackerHitPlane[]; + | Schema2.TrackerHitPlaneCollection + | Schema3.TrackerHitPlaneCollection + | Schema4.TrackerHitPlaneCollection + | Schema5.TrackerHitPlaneCollection + | Schema6.TrackerHitPlaneCollection; export type SenseWireHitCollection = - | Schema5.SenseWireHit[] - | Schema6.SenseWireHit[]; + | Schema5.SenseWireHitCollection + | Schema6.SenseWireHitCollection; export type SimTrackerHitCollection = - | Schema1.SimTrackerHit[] - | Schema2.SimTrackerHit[] - | Schema3.SimTrackerHit[] - | Schema4.SimTrackerHit[] - | Schema5.SimTrackerHit[] - | Schema6.SimTrackerHit[]; + | Schema1.SimTrackerHitCollection + | Schema2.SimTrackerHitCollection + | Schema3.SimTrackerHitCollection + | Schema4.SimTrackerHitCollection + | Schema5.SimTrackerHitCollection + | Schema6.SimTrackerHitCollection; export type CalorimeterHitCollection = - | Schema1.CalorimeterHit[] - | Schema2.CalorimeterHit[] - | Schema3.CalorimeterHit[] - | Schema4.CalorimeterHit[] - | Schema5.CalorimeterHit[] - | Schema6.CalorimeterHit[]; + | Schema1.CalorimeterHitCollection + | Schema2.CalorimeterHitCollection + | Schema3.CalorimeterHitCollection + | Schema4.CalorimeterHitCollection + | Schema5.CalorimeterHitCollection + | Schema6.CalorimeterHitCollection; export type SimCalorimeterHitCollection = - | Schema1.SimCalorimeterHit[] - | Schema2.SimCalorimeterHit[] - | Schema3.SimCalorimeterHit[] - | Schema4.SimCalorimeterHit[] - | Schema5.SimCalorimeterHit[] - | Schema6.SimCalorimeterHit[]; + | Schema1.SimCalorimeterHitCollection + | Schema2.SimCalorimeterHitCollection + | Schema3.SimCalorimeterHitCollection + | Schema4.SimCalorimeterHitCollection + | Schema5.SimCalorimeterHitCollection + | Schema6.SimCalorimeterHitCollection; export type ClusterCollection = - | Schema1.Cluster[] - | Schema2.Cluster[] - | Schema3.Cluster[] - | Schema4.Cluster[] - | Schema5.Cluster[] - | Schema6.Cluster[]; + | Schema1.ClusterCollection + | Schema2.ClusterCollection + | Schema3.ClusterCollection + | Schema4.ClusterCollection + | Schema5.ClusterCollection + | Schema6.ClusterCollection; export type ReconstructedParticleCollection = - | Schema1.ReconstructedParticle[] - | Schema2.ReconstructedParticle[] - | Schema3.ReconstructedParticle[] - | Schema4.ReconstructedParticle[] - | Schema5.ReconstructedParticle[] - | Schema6.ReconstructedParticle[]; - - export type MCParticle = - | Schema1.MCParticle - | Schema2.MCParticle - | Schema3.MCParticle - | Schema4.MCParticle - | Schema5.MCParticle - | Schema6.MCParticle; + | Schema1.ReconstructedParticleCollection + | Schema2.ReconstructedParticleCollection + | Schema3.ReconstructedParticleCollection + | Schema4.ReconstructedParticleCollection + | Schema5.ReconstructedParticleCollection + | Schema6.ReconstructedParticleCollection; export type MCParticleCollection = - | Schema1.MCParticle[] - | Schema2.MCParticle[] - | Schema3.MCParticle[] - | Schema4.MCParticle[] - | Schema5.MCParticle[] - | Schema6.MCParticle[]; + | Schema1.MCParticleCollection + | Schema2.MCParticleCollection + | Schema3.MCParticleCollection + | Schema4.MCParticleCollection + | Schema5.MCParticleCollection + | Schema6.MCParticleCollection; export type AssociationCollection = - Schema1.MCRecoParticleAssociationCollection[]; + Schema1.MCRecoParticleAssociationCollection; export type LinkCollection = - | Schema2.RecoMCParticleLinkCollection[] - | Schema3.RecoMCParticleLinkCollection[] - | Schema4.RecoMCParticleLinkCollection[] - | Schema5.RecoMCParticleLinkCollection[] - | Schema6.RecoMCParticleLinkCollection[]; + | Schema2.RecoMCParticleLinkCollection + | Schema3.RecoMCParticleLinkCollection + | Schema4.RecoMCParticleLinkCollection + | Schema5.RecoMCParticleLinkCollection + | Schema6.RecoMCParticleLinkCollection; export type Event = { [name: string]: From 3a2bacccbbf9dd2f6b7c48fbac9bb431ef8fd9d1 Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Thu, 5 Mar 2026 18:31:48 +0100 Subject: [PATCH 14/30] Push changes --- .../src/loaders/edm4hep-json-loader2.ts | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 packages/phoenix-event-display/src/loaders/edm4hep-json-loader2.ts diff --git a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader2.ts b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader2.ts new file mode 100644 index 000000000..8806f9589 --- /dev/null +++ b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader2.ts @@ -0,0 +1,92 @@ +import { PhoenixLoader } from './phoenix-loader'; +import { edmPhoenix } from 'src/lib/types/edmPhoenix'; +import { edm4hep } from 'src/lib/types/edm4hep'; + +export class Edm4hepJsonLoader extends PhoenixLoader { + private rawEventData: any; + + constructor() { + super(); + this.eventData = {}; + } + + setRawEventData(rawEventData: any) { + this.rawEventData = rawEventData; + } + + processEventData(): boolean { + // Iterate over events + Object.entries(this.rawEventData).forEach( + ([eventName, rawEvent]: [string, edm4hep.Event]) => { + const newEvent: edmPhoenix.Event = {}; + + /* Define particle PID based on link + */ + this.assignPID(rawEvent); + }, + ); + } + + /** Assign default color to Tracks */ + private assignPID(event: any) { + let recoParticles = event.ReconstructedParticles + ?.collection as edm4hep.ReconstructedParticleCollection; + + let mcParticles = event.Particle + ?.collection as edm4hep.MCParticleCollection; + + // Link collection name and type vary by schema version: + // - Schema 1 — name: MCRecoAssociations — type: AssociationCollection + // - Schema 2 — name: MCRecoAssociations or RecoMCLink — type: LinkCollection + // - Schema 3 — name: RecoMCLink — type: LinkCollection + const links = (event.MCRecoAssociations ?? event.RecoMCLink)?.collection as + | edm4hep.AssociationCollection + | edm4hep.LinkCollection; + + let tracks: any[]; + if ('EFlowTrack' in event) { + tracks = event['EFlowTrack']['collection']; + } else { + return; + } + + if (!links) return; + links.forEach((mcRecoAssoc: edm4hep.Association | edm4hep.Link) => { + const recoIndex = + typeof mcRecoAssoc['rec'] !== 'undefined' + ? mcRecoAssoc['rec']['index'] + : mcRecoAssoc['from']['index']; + const mcIndex = + typeof mcRecoAssoc['sim'] !== 'undefined' + ? mcRecoAssoc['sim']['index'] + : mcRecoAssoc['to']['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; + }); + }); + } +} From 7e50e638a3eaa2ec2f776cb4653cc32a89b1b29b Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Fri, 6 Mar 2026 16:36:20 +0100 Subject: [PATCH 15/30] Update types --- .../src/lib/types/edm4hep-schemas/schema1.ts | 6 - .../src/lib/types/edm4hep-schemas/schema2.ts | 11 +- .../src/lib/types/edm4hep-schemas/schema3.ts | 7 - .../src/lib/types/edm4hep-schemas/schema4.ts | 6 - .../src/lib/types/edm4hep-schemas/schema5.ts | 6 - .../src/lib/types/edm4hep-schemas/schema6.ts | 6 - .../src/lib/types/edm4hep.ts | 197 ++++++------------ .../src/lib/types/edmPhoenix.ts | 4 +- 8 files changed, 66 insertions(+), 177 deletions(-) diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts index e784ac7b7..4d5e41891 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts @@ -227,11 +227,5 @@ export namespace Schema1 { collSchemaVersion: number; collType: 'edm4hep::MCRecoParticleAssociation'; collection: MCRecoParticleAssociationCollection; - } - | { - collID: number; - collSchemaVersion: number; - collType: 'edm4hep::MCParticleCollection'; - collection: MCParticleCollection; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts index 1b6c67041..0d059aa57 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts @@ -46,6 +46,11 @@ export namespace Schema2 { trackStates: TrackState[]; // track states trackerHits: ObjectID[]; // hits that have been used to create this track tracks: ObjectID[]; // tracks (segments) that have been combined to create this track + + // MUTATED PROPERTIES + color: string; + pid: string; + pdgid: number; }; /** Tracker hit interface class */ @@ -263,11 +268,5 @@ export namespace Schema2 { collSchemaVersion: number; collType: 'edm4hep::RecoMCParticleLink'; collection: RecoMCParticleLinkCollection; - } - | { - collID: number; - collSchemaVersion: number; - collType: 'edm4hep::MCParticleCollection'; - collection: MCParticleCollection; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts index cd230ad2d..68b9391f6 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts @@ -158,7 +158,6 @@ export namespace Schema3 { weights: number[]; // event weights in case there are multiple. **NOTE that weights[0] might not be the same as weight!** Event weight names should be stored using the edm4hep::EventWeights name in the file level metadata }; - /** Link between a ReconstructedParticle and an MCParticle */ export type RecoMCParticleLink = { weight: number; // weight of this link @@ -262,11 +261,5 @@ export namespace Schema3 { collSchemaVersion: number; collType: 'podio::LinkCollection'; collection: RecoMCParticleLinkCollection; - } - | { - collID: number; - collSchemaVersion: number; - collType: 'edm4hep::MCParticleCollection'; - collection: MCParticleCollection; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts index b95f017b5..e558ed49f 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts @@ -261,11 +261,5 @@ export namespace Schema4 { collSchemaVersion: number; collType: 'podio::LinkCollection'; collection: RecoMCParticleLinkCollection; - } - | { - collID: number; - collSchemaVersion: number; - collType: 'edm4hep::MCParticleCollection'; - collection: MCParticleCollection; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts index a042ec961..8e52671ea 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts @@ -285,11 +285,5 @@ export namespace Schema5 { collSchemaVersion: number; collType: 'podio::LinkCollection'; collection: RecoMCParticleLinkCollection; - } - | { - collID: number; - collSchemaVersion: number; - collType: 'edm4hep::MCParticleCollection'; - collection: MCParticleCollection; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts index c8e42250b..d78d22eb0 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts @@ -285,11 +285,5 @@ export namespace Schema6 { collSchemaVersion: number; collType: 'podio::LinkCollection'; collection: RecoMCParticleLinkCollection; - } - | { - collID: number; - collSchemaVersion: number; - collType: 'edm4hep::MCParticleCollection'; - collection: MCParticleCollection; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep.ts b/packages/phoenix-event-display/src/lib/types/edm4hep.ts index 5cf083681..6eeba8e53 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep.ts @@ -14,49 +14,56 @@ export namespace edm4hep { | Schema5.Vertex | Schema6.Vertex; - export type TrackerHit = Schema1.TrackerHit; + export type Track = ( + | Schema1.Track + | Schema2.Track + | Schema3.Track + | Schema4.Track + | Schema5.Track + | Schema6.Track + ) & { + // MUTATED PROPERTIES + color: string; + pid: string; + pdgid: number; + }; - export type TrackerHit3D = + export type Hit = + | Schema1.TrackerHit + | Schema1.SimTrackerHit | Schema2.TrackerHit3D - | Schema3.TrackerHit3D - | Schema4.TrackerHit3D - | Schema5.TrackerHit3D - | Schema6.TrackerHit3D; - - export type TrackerHitPlane = | Schema2.TrackerHitPlane - | Schema3.TrackerHitPlane - | Schema4.TrackerHitPlane - | Schema5.TrackerHitPlane - | Schema6.TrackerHitPlane; - - export type SenseWireHit = Schema5.SenseWireHit | Schema6.SenseWireHit; - - export type SimTrackerHit = - | Schema1.SimTrackerHit | Schema2.SimTrackerHit + | Schema3.TrackerHit3D + | Schema3.TrackerHitPlane | Schema3.SimTrackerHit + | Schema4.TrackerHit3D + | Schema4.TrackerHitPlane | Schema4.SimTrackerHit + | Schema5.TrackerHit3D + | Schema5.TrackerHitPlane + | Schema5.SenseWireHit | Schema5.SimTrackerHit + | Schema6.TrackerHit3D + | Schema6.TrackerHitPlane + | Schema6.SenseWireHit | Schema6.SimTrackerHit; - export type CalorimeterHit = + export type CaloCell = | Schema1.CalorimeterHit - | Schema2.CalorimeterHit - | Schema3.CalorimeterHit - | Schema4.CalorimeterHit - | Schema5.CalorimeterHit - | Schema6.CalorimeterHit; - - export type SimCalorimeterHit = | Schema1.SimCalorimeterHit + | Schema2.CalorimeterHit | Schema2.SimCalorimeterHit + | Schema3.CalorimeterHit | Schema3.SimCalorimeterHit + | Schema4.CalorimeterHit | Schema4.SimCalorimeterHit + | Schema5.CalorimeterHit | Schema5.SimCalorimeterHit + | Schema6.CalorimeterHit | Schema6.SimCalorimeterHit; - export type Cluster = + export type CaloCluster = | Schema1.Cluster | Schema2.Cluster | Schema3.Cluster @@ -97,117 +104,33 @@ export namespace edm4hep { | Schema5.RecoMCParticleLink | Schema6.RecoMCParticleLink; - export type EventHeaderCollection = - | Schema1.EventHeaderCollection - | Schema2.EventHeaderCollection - | Schema3.EventHeaderCollection - | Schema4.EventHeaderCollection - | Schema5.EventHeaderCollection - | Schema6.EventHeaderCollection; - - export type VertexCollection = - | Schema1.VertexCollection - | Schema2.VertexCollection - | Schema3.VertexCollection - | Schema4.VertexCollection - | Schema5.VertexCollection - | Schema6.VertexCollection; - - export type TrackCollection = - | Schema1.TrackCollection - | Schema2.TrackCollection - | Schema3.TrackCollection - | Schema4.TrackCollection - | Schema5.TrackCollection - | Schema6.TrackCollection; - - export type MCRecoParticleAssociation = - Schema1.MCRecoParticleAssociationCollection; - - export type RecoMCParticleLink = - | Schema2.RecoMCParticleLinkCollection - | Schema3.RecoMCParticleLinkCollection - | Schema4.RecoMCParticleLinkCollection - | Schema5.RecoMCParticleLinkCollection - | Schema6.RecoMCParticleLinkCollection; - - export type TrackerHitCollection = Schema1.TrackerHitCollection; - - export type TrackerHit3DCollection = - | Schema2.TrackerHit3DCollection - | Schema3.TrackerHit3DCollection - | Schema4.TrackerHit3DCollection - | Schema5.TrackerHit3DCollection - | Schema6.TrackerHit3DCollection; - - export type TrackerHitPlaneCollection = - | Schema2.TrackerHitPlaneCollection - | Schema3.TrackerHitPlaneCollection - | Schema4.TrackerHitPlaneCollection - | Schema5.TrackerHitPlaneCollection - | Schema6.TrackerHitPlaneCollection; - - export type SenseWireHitCollection = - | Schema5.SenseWireHitCollection - | Schema6.SenseWireHitCollection; - - export type SimTrackerHitCollection = - | Schema1.SimTrackerHitCollection - | Schema2.SimTrackerHitCollection - | Schema3.SimTrackerHitCollection - | Schema4.SimTrackerHitCollection - | Schema5.SimTrackerHitCollection - | Schema6.SimTrackerHitCollection; - - export type CalorimeterHitCollection = - | Schema1.CalorimeterHitCollection - | Schema2.CalorimeterHitCollection - | Schema3.CalorimeterHitCollection - | Schema4.CalorimeterHitCollection - | Schema5.CalorimeterHitCollection - | Schema6.CalorimeterHitCollection; - - export type SimCalorimeterHitCollection = - | Schema1.SimCalorimeterHitCollection - | Schema2.SimCalorimeterHitCollection - | Schema3.SimCalorimeterHitCollection - | Schema4.SimCalorimeterHitCollection - | Schema5.SimCalorimeterHitCollection - | Schema6.SimCalorimeterHitCollection; - - export type ClusterCollection = - | Schema1.ClusterCollection - | Schema2.ClusterCollection - | Schema3.ClusterCollection - | Schema4.ClusterCollection - | Schema5.ClusterCollection - | Schema6.ClusterCollection; - - export type ReconstructedParticleCollection = - | Schema1.ReconstructedParticleCollection - | Schema2.ReconstructedParticleCollection - | Schema3.ReconstructedParticleCollection - | Schema4.ReconstructedParticleCollection - | Schema5.ReconstructedParticleCollection - | Schema6.ReconstructedParticleCollection; - - export type MCParticleCollection = - | Schema1.MCParticleCollection - | Schema2.MCParticleCollection - | Schema3.MCParticleCollection - | Schema4.MCParticleCollection - | Schema5.MCParticleCollection - | Schema6.MCParticleCollection; - - export type AssociationCollection = - Schema1.MCRecoParticleAssociationCollection; - - export type LinkCollection = - | Schema2.RecoMCParticleLinkCollection - | Schema3.RecoMCParticleLinkCollection - | Schema4.RecoMCParticleLinkCollection - | Schema5.RecoMCParticleLinkCollection - | Schema6.RecoMCParticleLinkCollection; + export type EventHeaderCollection = EventHeader[]; + + export type VertexCollection = Vertex[]; + + export type TrackCollection = Track[]; + + export type AssociationCollection = Association[]; + + export type HitCollection = Hit[]; + + export type caloCellCollection = CaloCell[]; + + export type ClusterCollection = CaloCluster[]; + + export type ReconstructedParticleCollection = ReconstructedParticle[]; + + export type MCParticleCollection = MCParticle[]; + + export type LinkCollection = Link[]; + + export type Item = + | Schema1.Item + | Schema2.Item + | Schema3.Item + | Schema4.Item + | Schema5.Item + | Schema6.Item; export type Event = { [name: string]: diff --git a/packages/phoenix-event-display/src/lib/types/edmPhoenix.ts b/packages/phoenix-event-display/src/lib/types/edmPhoenix.ts index c40f30a69..04b8709f4 100644 --- a/packages/phoenix-event-display/src/lib/types/edmPhoenix.ts +++ b/packages/phoenix-event-display/src/lib/types/edmPhoenix.ts @@ -3,9 +3,7 @@ import { Vector3d } from './edm4hep-schemas/utils'; export namespace edmPhoenix { export type Vertex = { color?: string; - x: number; - y: number; - z: number; + pos: Vector3d; }; export type Track = { From 4e40638ce5524a875e2c2d19e75cde8bd96190c1 Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Fri, 6 Mar 2026 16:36:56 +0100 Subject: [PATCH 16/30] Update types --- .../src/lib/types/edm4hep-schemas/schema2.ts | 5 ----- .../src/lib/types/edm4hep-schemas/utils.ts | 7 ------- 2 files changed, 12 deletions(-) diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts index 0d059aa57..65bb7ab49 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts @@ -46,11 +46,6 @@ export namespace Schema2 { trackStates: TrackState[]; // track states trackerHits: ObjectID[]; // hits that have been used to create this track tracks: ObjectID[]; // tracks (segments) that have been combined to create this track - - // MUTATED PROPERTIES - color: string; - pid: string; - pdgid: number; }; /** Tracker hit interface class */ diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/utils.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/utils.ts index 9869aa529..850a0ced1 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/utils.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/utils.ts @@ -1,10 +1,3 @@ -import { Schema1 } from './schema1'; -import { Schema2 } from './schema2'; -import { Schema3 } from './schema3'; -import { Schema4 } from './schema4'; -import { Schema5 } from './schema5'; -import { Schema6 } from './schema6'; - /** A generic 3 dimensional covariance matrix with values stored in lower triangular form */ export type CovMatrix3f = { values: number[]; // the covariance matrix values From 7934359cc54583d8d8343b6ff43f8ffc815476d4 Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Fri, 6 Mar 2026 16:47:12 +0100 Subject: [PATCH 17/30] Continue development --- .../src/loaders/edm4hep-json-loader2.ts | 303 ++++++++++++++---- 1 file changed, 245 insertions(+), 58 deletions(-) diff --git a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader2.ts b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader2.ts index 8806f9589..00174f38f 100644 --- a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader2.ts +++ b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader2.ts @@ -1,6 +1,7 @@ import { PhoenixLoader } from './phoenix-loader'; import { edmPhoenix } from 'src/lib/types/edmPhoenix'; import { edm4hep } from 'src/lib/types/edm4hep'; +import { ObjectID } from 'src/lib/types/edm4hep-schemas/utils'; export class Edm4hepJsonLoader extends PhoenixLoader { private rawEventData: any; @@ -14,79 +15,265 @@ export class Edm4hepJsonLoader extends PhoenixLoader { this.rawEventData = rawEventData; } - processEventData(): boolean { + processEventData(): void { // Iterate over events Object.entries(this.rawEventData).forEach( ([eventName, rawEvent]: [string, edm4hep.Event]) => { - const newEvent: edmPhoenix.Event = {}; + const newEvent: edmPhoenix.Event = { + 'event number': 0, + 'run number': 0, + Vertices: {}, + Tracks: {}, + Hits: {}, + Jets: {}, + CaloClusters: {}, + }; - /* Define particle PID based on link - */ this.assignPID(rawEvent); + + // Iterate over event items + Object.entries(rawEvent).forEach( + ([collName, item]: [string, edm4hep.Item]) => { + switch (item.collType) { + case 'edm4hep::EventHeaderCollection': + newEvent['event number'] = Number( + item.collection[0].eventNumber ?? 0, + ); + newEvent['run number'] = Number( + item.collection[0].runNumber ?? 0, + ); + break; + case 'edm4hep::VertexCollection': + newEvent.Vertices[collName] = this.getVertices(item.collection); + break; + case 'edm4hep::TrackCollection': + this.getTracks(rawEvent, item.collection as edm4hep.TrackCollection) + .filter(([, arr]) => arr.length > 0) + .forEach(([label, arr]) => { + newEvent.Tracks[`${collName} | ${label}`] = arr; + }); + break; + case 'edm4hep::TrackerHitCollection': + case 'edm4hep::TrackerHit3DCollection': + case 'edm4hep::TrackerHitPlaneCollection': + case 'edm4hep::SenseWireHitCollection': + case 'edm4hep::SimTrackerHitCollection': + newEvent.Hits[collName] = this.getHits(item.collection); + break; + case 'edm4hep::CalorimeterHitCollection': + case 'edm4hep::SimCalorimeterHitCollection': + newEvent.Jets[collName] = this.getCaloCells(item.collection); + break; + case 'edm4hep::ClusterCollection': + newEvent.CaloClusters[collName] = this.getCaloClusters( + item.collection, + ); + break; + case 'edm4hep::ReconstructedParticleCollection': + newEvent.Jets[collName] = this.getJets(item.collection); + break; + } + }, + ); }, ); } - /** Assign default color to Tracks */ - private assignPID(event: any) { - let recoParticles = event.ReconstructedParticles + /* Define particle PID based on link */ + private assignPID(rawEvent: any) { + // Link collection name and type vary by schema: + // - Schema 1: MCRecoAssociations + // - Schema 2: MCRecoAssociations or RecoMCLink + // - Schema 3: RecoMCLink + let linkCollection = (rawEvent.MCRecoAssociations ?? rawEvent.RecoMCLink) + ?.collection as + | edm4hep.AssociationCollection // Schema 1 + | edm4hep.LinkCollection; // From Schema 2 Onwards + + if (!linkCollection) return; + + let reconstructedParticleCollection = rawEvent.ReconstructedParticles ?.collection as edm4hep.ReconstructedParticleCollection; - let mcParticles = event.Particle + if (!reconstructedParticleCollection) return; + + let mcParticleCollection = rawEvent.Particle ?.collection as edm4hep.MCParticleCollection; - // Link collection name and type vary by schema version: - // - Schema 1 — name: MCRecoAssociations — type: AssociationCollection - // - Schema 2 — name: MCRecoAssociations or RecoMCLink — type: LinkCollection - // - Schema 3 — name: RecoMCLink — type: LinkCollection - const links = (event.MCRecoAssociations ?? event.RecoMCLink)?.collection as - | edm4hep.AssociationCollection - | edm4hep.LinkCollection; - - let tracks: any[]; - if ('EFlowTrack' in event) { - tracks = event['EFlowTrack']['collection']; - } else { - return; - } - - if (!links) return; - links.forEach((mcRecoAssoc: edm4hep.Association | edm4hep.Link) => { - const recoIndex = - typeof mcRecoAssoc['rec'] !== 'undefined' - ? mcRecoAssoc['rec']['index'] - : mcRecoAssoc['from']['index']; - const mcIndex = - typeof mcRecoAssoc['sim'] !== 'undefined' - ? mcRecoAssoc['sim']['index'] - : mcRecoAssoc['to']['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'; + if (!mcParticleCollection) return; + + let trackCollection = rawEvent.EFlowTrack + ?.collection as edm4hep.TrackCollection; + + if (!trackCollection) return; + + linkCollection.forEach((link: edm4hep.Association | edm4hep.Link) => { + const recIndex = 'rec' in link ? link.rec.index : link.from.index; + const simIndex = 'sim' in link ? link.sim.index : link.to.index; + const pdgid = mcParticleCollection[simIndex].PDG; + const trackRefs = reconstructedParticleCollection[recIndex].tracks; + + let color: string, pid: string; + + switch (Math.abs(pdgid)) { + case 11: + color = '00ff00'; + pid = 'electron'; + break; + case 22: + color = 'ff0000'; + pid = 'photon'; + break; + case 111: + case 211: + color = 'a52a2a'; + pid = 'pion'; + break; + case 2212: + color = '778899'; + pid = 'proton'; + break; + case 321: + color = '5f9ea0'; + pid = 'kaon'; + break; + default: + color = '0000cd'; + pid = 'other'; + } + + trackRefs.forEach(({ index }) => { + const track = trackCollection[index]; + + track.color = color; + track.pid = pid; + track.pdgid = pdgid; + }); + }); + } + + /** Return a random colour */ + private randomColor() { + return Math.floor(Math.random() * 16777215) + .toString(16) + .padStart(6, '0') + .toUpperCase(); + } + + /** Return vertices */ + private getVertices( + vertexCollection: edm4hep.VertexCollection, + ): edmPhoenix.Vertex[] { + return vertexCollection.map((vertex: edm4hep.Vertex) => ({ + pos: { + x: vertex.position.x * 0.1, + y: vertex.position.y * 0.1, + z: vertex.position.z * 0.1, + }, + color: `#${this.randomColor()}`, + })); + } + + /** Get the required collection */ + private getCollByID(event: any, id: number) { + const coll = Object.values(event).find((c: any) => c?.collID === id) as any; + return coll?.collection; + } + + private getTracks( + rawEvent: any, + trackCollection: edm4hep.TrackCollection, + ): [string, edmPhoenix.Track[]][] { + const electrons: any[] = []; + const photons: any[] = []; + const pions: any[] = []; + const protons: any[] = []; + const kaons: any[] = []; + const other: any[] = []; + + trackCollection.forEach((track: edm4hep.Track) => { + let newTrack: edmPhoenix.Track = null; + + if ('trackerHits' in track) { + track.trackerHits.forEach((trackerHitRef: ObjectID) => { + const trackerHits: edm4hep.HitCollection = this.getCollByID( + rawEvent, + trackerHitRef.collectionID, + ); + + newTrack.pos.x = trackerHits[trackerHitRef.index].position.x * 0.1; + newTrack.pos.y = trackerHits[trackerHitRef.index].position.y * 0.1; + newTrack.pos.z = trackerHits[trackerHitRef.index].position.z * 0.1; + }); + } + + if (newTrack === null && 'trackStates' in track) { + track.trackStates.forEach((trackState: any) => { + if ('referencePoint' in trackState) { + newTrack.pos.x = trackState.referencePoint.x * 0.1; + newTrack.pos.y = trackState.referencePoint.y * 0.1; + newTrack.pos.z = trackState.referencePoint.z * 0.1; + } + }); + } + + // @todo if none of those two properties exist definition will be invalid + + newTrack.color = track.color ?? '0000cd'; + + if ('pid' in track) { + if (track.pid == 'electron') { + electrons.push(track); + } else if (track.pid == 'photon') { + photons.push(track); + } else if (track.pid == 'pion') { + pions.push(track); + } else if (track.pid == 'proton') { + protons.push(track); + } else if (track.pid == 'kaon') { + kaons.push(track); } else { - track['color'] = '0000cd'; - track['pid'] = 'other'; + other.push(track); } - track['pdgid'] = pdgid; - }); + } else { + other.push(track); + } }); + + return [ + ['Electrons', electrons], + ['Photons', photons], + ['Pions', pions], + ['Protons', protons], + ['Kaons', kaons], + ['Other', other], + ]; } + + private getHits( + hitCollection: + | edm4hep.TrackerHitCollection + | edm4hep.TrackerHit3DCollection + | edm4hep.TrackerHitPlaneCollection + | edm4hep.SenseWireHitCollection + | edm4hep.SimTrackerHitCollection, + ): edmPhoenix.Hit[] {} + + private getCaloCells( + caloCellCollection: + | edm4hep.CalorimeterHitCollection + | edm4hep.SimCalorimeterHitCollection, + ): edmPhoenix.CaloCell[] {} + + private getCaloClusters( + caloClusterCollection: edm4hep.ClusterCollection, + ): edmPhoenix.CaloCluster[] {} + + private getJets( + jetCollection: edm4hep.ReconstructedParticleCollection, + ): edmPhoenix.Jet[] {} + + private getMissingEnergy( + missingEnergyCollection: edm4hep.ReconstructedParticleCollection, + ): edmPhoenix.MissingEnergy[] {} } From bee1fb26eef674dc12945f71aef208cd4dcabcee Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Mon, 9 Mar 2026 16:04:23 +0100 Subject: [PATCH 18/30] Update types --- .../src/lib/types/edm4hep-schemas/schema1.ts | 2 +- .../src/lib/types/edm4hep-schemas/schema2.ts | 4 ++-- .../src/lib/types/edm4hep-schemas/schema3.ts | 4 ++-- .../src/lib/types/edm4hep-schemas/schema4.ts | 4 ++-- .../src/lib/types/edm4hep-schemas/schema5.ts | 4 ++-- .../src/lib/types/edm4hep-schemas/schema6.ts | 4 ++-- .../phoenix-event-display/src/lib/types/edm4hep.ts | 8 ++++++++ .../src/lib/types/edmPhoenix.ts | 14 +++++++------- 8 files changed, 26 insertions(+), 18 deletions(-) diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts index 4d5e41891..8a7c76ed4 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts @@ -13,7 +13,7 @@ export namespace Schema1 { associatedParticle: ObjectID; // reconstructed particle associated to this vertex. }; - type TrackState = { + export type TrackState = { location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation D0: number; // transverse impact parameter phi: number; // azimuthal angle diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts index 65bb7ab49..c6cff16c6 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts @@ -23,7 +23,7 @@ export namespace Schema2 { }; /** Parametrized description of a particle track */ - type TrackState = { + export type TrackState = { location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation D0: number; // transverse impact parameter phi: number; // azimuthal angle @@ -97,7 +97,7 @@ export namespace Schema2 { quality: number; // quality bit flag position: Vector3d; // [mm] the hit position momentum: Vector3f; // [GeV] the 3-momentum of the particle at the hits position - particle: ObjectID; // MCParticle that caused the hit + particle: ObjectID[]; // MCParticle that caused the hit }; /** Calorimeter hit */ diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts index 68b9391f6..a922dc2b0 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts @@ -22,7 +22,7 @@ export namespace Schema3 { }; /** Parametrized description of a particle track */ - type TrackState = { + export type TrackState = { location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation D0: number; // transverse impact parameter phi: number; // [rad] azimuthal angle of the track at this location (i.e. not phi0) @@ -96,7 +96,7 @@ export namespace Schema3 { quality: number; // quality bit flag position: Vector3d; // [mm] the hit position momentum: Vector3f; // [GeV] the 3-momentum of the particle at the hits position - particle: ObjectID; // MCParticle that caused the hit + particle: ObjectID[]; // MCParticle that caused the hit }; /** Calorimeter hit */ diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts index e558ed49f..3ba3bf89a 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts @@ -22,7 +22,7 @@ export namespace Schema4 { }; /** Parametrized description of a particle track */ - type TrackState = { + export type TrackState = { location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation D0: number; // transverse impact parameter phi: number; // [rad] azimuthal angle of the track at this location (i.e. not phi0) @@ -96,7 +96,7 @@ export namespace Schema4 { quality: number; // quality bit flag position: Vector3d; // [mm] the hit position momentum: Vector3f; // [GeV] the 3-momentum of the particle at the hits position - particle: ObjectID; // MCParticle that caused the hit + particle: ObjectID[]; // MCParticle that caused the hit }; /** Calorimeter hit */ diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts index 8e52671ea..5d9935d15 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts @@ -22,7 +22,7 @@ export namespace Schema5 { }; /** Parametrized description of a particle track */ - type TrackState = { + export type TrackState = { location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation D0: number; // transverse impact parameter phi: number; // [rad] azimuthal angle of the track at this location (i.e. not phi0) @@ -113,7 +113,7 @@ export namespace Schema5 { quality: number; // quality bit flag position: Vector3d; // [mm] the hit position momentum: Vector3f; // [GeV] the 3-momentum of the particle at the hits position - particle: ObjectID; // MCParticle that caused the hit + particle: ObjectID[]; // MCParticle that caused the hit }; /** Calorimeter hit */ diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts index d78d22eb0..4a7f2077f 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts @@ -22,7 +22,7 @@ export namespace Schema6 { }; /** Parametrized description of a particle track */ - type TrackState = { + export type TrackState = { location: number; // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation D0: number; // transverse impact parameter phi: number; // [rad] azimuthal angle of the track at this location (i.e. not phi0) @@ -113,7 +113,7 @@ export namespace Schema6 { quality: number; // quality bit flag position: Vector3d; // [mm] the hit position momentum: Vector3f; // [GeV] the 3-momentum of the particle at the hits position - particle: ObjectID; // MCParticle that caused the hit + particle: ObjectID[]; // MCParticle that caused the hit }; /** Calorimeter hit */ diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep.ts b/packages/phoenix-event-display/src/lib/types/edm4hep.ts index 6eeba8e53..01aad3736 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep.ts @@ -14,6 +14,14 @@ export namespace edm4hep { | Schema5.Vertex | Schema6.Vertex; + export type TrackState = + | Schema1.TrackState + | Schema2.TrackState + | Schema3.TrackState + | Schema4.TrackState + | Schema5.TrackState + | Schema6.TrackState; + export type Track = ( | Schema1.Track | Schema2.Track diff --git a/packages/phoenix-event-display/src/lib/types/edmPhoenix.ts b/packages/phoenix-event-display/src/lib/types/edmPhoenix.ts index 04b8709f4..7029045e3 100644 --- a/packages/phoenix-event-display/src/lib/types/edmPhoenix.ts +++ b/packages/phoenix-event-display/src/lib/types/edmPhoenix.ts @@ -16,35 +16,35 @@ export namespace edmPhoenix { qOverP?: number; }; - type Hit = { + export type Hit = { type?: 'Point'; pos: Vector3d; color?: string; }; - type CaloCell = { + export type CaloCell = { energy: number; phi: number; eta: number; }; - type CaloCluster = { + export type CaloCluster = { energy: number; phi: number; eta: number; }; - type Jet = { + export type Jet = { eta: number; phi: number; theta?: number; energy?: number; et?: number; - coneR: number; + coneR?: number; color?: string; }; - type MissingEnegy = { + export type MissingEnergy = { etx: number; ety: number; color?: string; @@ -72,7 +72,7 @@ export namespace edmPhoenix { [name: string]: Jet[]; }; MissingEnergy?: { - [name: string]: MissingEnegy[]; + [name: string]: MissingEnergy[]; }; }; } From dfbc150854cf22599228b2dbec57f25d94ee6f70 Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Mon, 9 Mar 2026 16:05:03 +0100 Subject: [PATCH 19/30] Continue loader work --- .../src/loaders/edm4hep-json-loader2.ts | 307 ++++++++++++++---- 1 file changed, 244 insertions(+), 63 deletions(-) diff --git a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader2.ts b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader2.ts index 00174f38f..d433da9a5 100644 --- a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader2.ts +++ b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader2.ts @@ -1,7 +1,7 @@ import { PhoenixLoader } from './phoenix-loader'; import { edmPhoenix } from 'src/lib/types/edmPhoenix'; import { edm4hep } from 'src/lib/types/edm4hep'; -import { ObjectID } from 'src/lib/types/edm4hep-schemas/utils'; +import { ObjectID, Vector3d } from 'src/lib/types/edm4hep-schemas/utils'; export class Edm4hepJsonLoader extends PhoenixLoader { private rawEventData: any; @@ -25,8 +25,9 @@ export class Edm4hepJsonLoader extends PhoenixLoader { Vertices: {}, Tracks: {}, Hits: {}, - Jets: {}, CaloClusters: {}, + CaloCells: {}, + Jets: {}, }; this.assignPID(rawEvent); @@ -47,7 +48,10 @@ export class Edm4hepJsonLoader extends PhoenixLoader { newEvent.Vertices[collName] = this.getVertices(item.collection); break; case 'edm4hep::TrackCollection': - this.getTracks(rawEvent, item.collection as edm4hep.TrackCollection) + this.getTracks( + rawEvent, + item.collection as edm4hep.TrackCollection, + ) .filter(([, arr]) => arr.length > 0) .forEach(([label, arr]) => { newEvent.Tracks[`${collName} | ${label}`] = arr; @@ -58,19 +62,32 @@ export class Edm4hepJsonLoader extends PhoenixLoader { case 'edm4hep::TrackerHitPlaneCollection': case 'edm4hep::SenseWireHitCollection': case 'edm4hep::SimTrackerHitCollection': - newEvent.Hits[collName] = this.getHits(item.collection); + this.getHits(rawEvent, item.collection) + .filter(([, arr]) => arr.length > 0) + .forEach(([label, arr]) => { + newEvent.Hits[`${collName} | ${label}`] = arr; + }); break; case 'edm4hep::CalorimeterHitCollection': case 'edm4hep::SimCalorimeterHitCollection': - newEvent.Jets[collName] = this.getCaloCells(item.collection); + newEvent.CaloCells[collName] = this.getCaloCells( + item.collection, + ); break; case 'edm4hep::ClusterCollection': + // @todo highlight optional members in edm4hep newEvent.CaloClusters[collName] = this.getCaloClusters( item.collection, ); break; case 'edm4hep::ReconstructedParticleCollection': - newEvent.Jets[collName] = this.getJets(item.collection); + if (collName === 'Jet') + newEvent.Jets[collName] = this.getJets(item.collection); + // @todo 'missing' is never present + else if (collName.toLowerCase().includes('missing')) + newEvent.MissingEnergy[collName] = this.getMissingEnergy( + item.collection, + ); break; } }, @@ -183,97 +200,261 @@ export class Edm4hepJsonLoader extends PhoenixLoader { private getTracks( rawEvent: any, trackCollection: edm4hep.TrackCollection, - ): [string, edmPhoenix.Track[]][] { - const electrons: any[] = []; - const photons: any[] = []; - const pions: any[] = []; - const protons: any[] = []; - const kaons: any[] = []; - const other: any[] = []; + ): { [name: string]: edmPhoenix.Hit[] } { + const categories: { [name: string]: edmPhoenix.Hit[] } = { + other: [], + electron: [], + photon: [], + pion: [], + proton: [], + kaon: [], + }; trackCollection.forEach((track: edm4hep.Track) => { - let newTrack: edmPhoenix.Track = null; + let newTrack: edmPhoenix.Track[] = []; if ('trackerHits' in track) { track.trackerHits.forEach((trackerHitRef: ObjectID) => { + // @todo always assumes getCollById will return a collection const trackerHits: edm4hep.HitCollection = this.getCollByID( rawEvent, trackerHitRef.collectionID, ); + // @todo change the structure + newTrack.pos.x = trackerHits[trackerHitRef.index].position.x * 0.1; newTrack.pos.y = trackerHits[trackerHitRef.index].position.y * 0.1; newTrack.pos.z = trackerHits[trackerHitRef.index].position.z * 0.1; + newTrack.color = track.color ?? '0000cd'; }); } if (newTrack === null && 'trackStates' in track) { - track.trackStates.forEach((trackState: any) => { - if ('referencePoint' in trackState) { - newTrack.pos.x = trackState.referencePoint.x * 0.1; - newTrack.pos.y = trackState.referencePoint.y * 0.1; - newTrack.pos.z = trackState.referencePoint.z * 0.1; - } + track.trackStates.forEach((trackState: edm4hep.TrackState) => { + // @todo 'trackState' might always be present + newTrack.pos.x = trackState.referencePoint.x * 0.1; + newTrack.pos.y = trackState.referencePoint.y * 0.1; + newTrack.pos.z = trackState.referencePoint.z * 0.1; + newTrack.color = track.color ?? '0000cd'; }); } // @todo if none of those two properties exist definition will be invalid - newTrack.color = track.color ?? '0000cd'; - - if ('pid' in track) { - if (track.pid == 'electron') { - electrons.push(track); - } else if (track.pid == 'photon') { - photons.push(track); - } else if (track.pid == 'pion') { - pions.push(track); - } else if (track.pid == 'proton') { - protons.push(track); - } else if (track.pid == 'kaon') { - kaons.push(track); + const category = track.pid ?? 'other'; + + categories[category].push(newTrack); + }); + + return categories; + } + + /** Find PDG of the particle associated with the hit */ + private getHits( + rawEvent: any, + hitCollection: edm4hep.Hit[], + ): { [name: string]: edmPhoenix.Hit[] } { + const categories: { [name: string]: edmPhoenix.Hit[] } = { + other: [], + overlay: [], + secondary: [], + electron: [], + muon: [], + pion: [], + kaon: [], + proton: [], + }; + + const colorOther = this.randomColor(); + const colorOverlay = this.randomColor(); + const colorSecondary = this.randomColor(); + const colorElectron = this.randomColor(); + const colorMuon = this.randomColor(); + const colorPion = this.randomColor(); + const colorKaon = this.randomColor(); + const colorProton = this.randomColor(); + + hitCollection.forEach((rawHit) => { + // @todo 'position' might always be present + const pos: Vector3d = { + x: rawHit.position.x * 0.1, + y: rawHit.position.y * 0.1, + z: rawHit.position.z * 0.1, + }; + + if ((rawHit.quality & (1 << 31)) !== 0) { + /* BITOverlay = 31 + * https://github.com/key4hep/EDM4hep/blob/fe5a54046a91a7e648d0b588960db7841aebc670/edm4hep.yaml#L349 + */ + categories.overlay.push({ + type: 'Point', + pos, + color: `#${colorOverlay}`, + }); + } else if ((rawHit.quality & (1 << 30)) !== 0) { + /* BITProducedBySecondary = 30 + * https://github.com/key4hep/EDM4hep/blob/fe5a54046a91a7e648d0b588960db7841aebc670/edm4hep.yaml#L350 + */ + categories.secondary.push({ + type: 'Point', + pos, + color: `#${colorSecondary}`, + }); + } else { + let ref: ObjectID | null = null; + + if ('particle' in rawHit && rawHit.particle.length > 0) { + // 'particle' exists in type SimTrackerHit from Schema2 onwards + ref = rawHit.particle[0]; + } else if ('MCParticle' in rawHit) { + // 'MCParticle' only exists in type SimTrackerHit within Schema1 + ref = rawHit.MCParticle; + } + + if (ref !== null) { + const collection = this.getCollByID(rawEvent, ref.collectionID); + const pdg = Math.abs(collection?.[ref.index]?.PDG ?? 0); + + switch (pdg) { + case 11: + categories.electron.push({ + type: 'Point', + pos, + color: `#${colorElectron}`, + }); + break; + case 13: + categories.muon.push({ + type: 'Point', + pos, + color: `#${colorMuon}`, + }); + break; + case 211: + categories.pion.push({ + type: 'Point', + pos, + color: `#${colorPion}`, + }); + break; + case 321: + categories.kaon.push({ + type: 'Point', + pos, + color: `#${colorKaon}`, + }); + break; + case 2212: + categories.proton.push({ + type: 'Point', + pos, + color: `#${colorProton}`, + }); + break; + default: + categories.other.push({ + type: 'Point', + pos, + color: `#${colorOther}`, + }); + break; + } } else { - other.push(track); + categories.other.push({ + type: 'Point', + pos, + color: `#${colorOther}`, + }); } - } else { - other.push(track); } }); - return [ - ['Electrons', electrons], - ['Photons', photons], - ['Pions', pions], - ['Protons', protons], - ['Kaons', kaons], - ['Other', other], - ]; + return categories; } - private getHits( - hitCollection: - | edm4hep.TrackerHitCollection - | edm4hep.TrackerHit3DCollection - | edm4hep.TrackerHitPlaneCollection - | edm4hep.SenseWireHitCollection - | edm4hep.SimTrackerHitCollection, - ): edmPhoenix.Hit[] {} - + /** Returns the cells */ private getCaloCells( - caloCellCollection: - | edm4hep.CalorimeterHitCollection - | edm4hep.SimCalorimeterHitCollection, - ): edmPhoenix.CaloCell[] {} + caloCellCollection: edm4hep.CaloCell[], + ): edmPhoenix.CaloCell[] { + const cells: edmPhoenix.CaloCell[] = []; + + caloCellCollection.forEach((rawCell) => { + const x = rawCell.position.x * 0.1; + const y = rawCell.position.y * 0.1; + const z = rawCell.position.z * 0.1; + const rho = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); + + cells.push({ + eta: Math.asinh(z / rho), + phi: Math.acos(x / rho) * Math.sign(y), + energy: rawCell.energy, + }); + }); + + return cells; + } private getCaloClusters( - caloClusterCollection: edm4hep.ClusterCollection, - ): edmPhoenix.CaloCluster[] {} + caloClusterCollection: edm4hep.CaloCluster[], + ): edmPhoenix.CaloCluster[] { + const clusters: edmPhoenix.CaloCluster[] = []; + + caloClusterCollection.forEach((rawCluster) => { + const x = rawCluster.position.x * 0.1; + const y = rawCluster.position.y * 0.1; + const z = rawCluster.position.z * 0.1; + const rho = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); + + clusters.push({ + eta: Math.asinh(z / rho), + phi: Math.acos(x / rho) * Math.sign(y), + energy: rawCluster.energy * 100, // @todo no apparent reason to multiply by 10 + }); + }); + + return clusters; + } private getJets( - jetCollection: edm4hep.ReconstructedParticleCollection, - ): edmPhoenix.Jet[] {} + jetCollection: edm4hep.ReconstructedParticle[], + ): edmPhoenix.Jet[] { + const jets: edmPhoenix.Jet[] = []; + + jetCollection.forEach((rawJet) => { + 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)); + + jets.push({ + eta: Math.asinh(pz / pt), + phi: Math.acos(px / pt) * Math.sign(py), + energy: rawJet.energy * 1000, // @todo this currently converts GeV -> MeV + }); + }); + + return jets; + } private getMissingEnergy( - missingEnergyCollection: edm4hep.ReconstructedParticleCollection, - ): edmPhoenix.MissingEnergy[] {} + missingEnergyCollection: edm4hep.ReconstructedParticle[], + ): edmPhoenix.MissingEnergy[] { + const missingEnergies: edmPhoenix.MissingEnergy[] = []; + + missingEnergyCollection.forEach((rawMissingEnergy: any) => { + const px = rawMissingEnergy.momentum.x; + const py = rawMissingEnergy.momentum.y; + const pz = rawMissingEnergy.momentum.z; + const p = Math.sqrt(Math.pow(px, 2) + Math.pow(py, 2) + Math.pow(pz, 2)); + + missingEnergies.push({ + etx: ((rawMissingEnergy.energy * px) / p) * 10, // @todo no apparent reason to multiply by 10 + ety: ((rawMissingEnergy.energy * py) / p) * 10, + color: '#ff69b4', + }); + }); + + return missingEnergies; + } } From e8b7bf2536f5fcf513a88f21a1cc8b52c7538ccb Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Tue, 10 Mar 2026 11:04:40 +0100 Subject: [PATCH 20/30] Simplify types --- .../src/lib/types/edm4hep-schemas/schema1.ts | 22 +++++----- .../src/lib/types/edm4hep-schemas/schema2.ts | 37 +++++----------- .../src/lib/types/edm4hep-schemas/schema3.ts | 37 +++++----------- .../src/lib/types/edm4hep-schemas/schema4.ts | 37 +++++----------- .../src/lib/types/edm4hep-schemas/schema5.ts | 26 +++++------ .../src/lib/types/edm4hep-schemas/schema6.ts | 40 ++++++----------- .../src/lib/types/edm4hep.ts | 44 +++++-------------- 7 files changed, 85 insertions(+), 158 deletions(-) diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts index 8a7c76ed4..8a7509d1b 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts @@ -167,65 +167,65 @@ export namespace Schema1 { export type MCRecoParticleAssociationCollection = MCRecoParticleAssociation[]; export type MCParticleCollection = MCParticle[]; - export type Item = + export type Coll = | { collID: number; collSchemaVersion: number; collType: 'edm4hep::EventHeaderCollection'; - collection: EventHeaderCollection; + collection: EventHeader[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; - collection: VertexCollection; + collection: Vertex[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; - collection: TrackCollection; + collection: Track[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHitCollection'; - collection: TrackerHitCollection; + collection: TrackerHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimTrackerHitCollection'; - collection: SimTrackerHitCollection; + collection: SimTrackerHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::CalorimeterHitCollection'; - collection: CalorimeterHitCollection; + collection: CalorimeterHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimCalorimeterHitCollection'; - collection: SimCalorimeterHitCollection; + collection: SimCalorimeterHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ClusterCollection'; - collection: ClusterCollection; + collection: Cluster[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; - collection: ReconstructedParticleCollection; + collection: ReconstructedParticle[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::MCRecoParticleAssociation'; - collection: MCRecoParticleAssociationCollection; + collection: MCRecoParticleAssociation[]; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts index c6cff16c6..1979361e3 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts @@ -184,84 +184,71 @@ export namespace Schema2 { daughters: ObjectID[]; // The daughters this particle }; - export type EventHeaderCollection = EventHeader[]; - export type VertexCollection = Vertex[]; - export type TrackCollection = Track[]; - export type TrackerHit3DCollection = TrackerHit3D[]; - export type TrackerHitPlaneCollection = TrackerHitPlane[]; - export type SimTrackerHitCollection = SimTrackerHit[]; - export type CalorimeterHitCollection = CalorimeterHit[]; - export type SimCalorimeterHitCollection = SimCalorimeterHit[]; - export type ClusterCollection = Cluster[]; - export type ReconstructedParticleCollection = ReconstructedParticle[]; - export type RecoMCParticleLinkCollection = RecoMCParticleLink[]; - export type MCParticleCollection = MCParticle[]; - - export type Item = + export type Coll = | { collID: number; collSchemaVersion: number; collType: 'edm4hep::EventHeaderCollection'; - collection: EventHeaderCollection; + collection: EventHeader[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; - collection: VertexCollection; + collection: Vertex[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; - collection: TrackCollection; + collection: Track[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHit3DCollection'; - collection: TrackerHit3DCollection; + collection: TrackerHit3D[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHitPlaneCollection'; - collection: TrackerHitPlaneCollection; + collection: TrackerHitPlane[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimTrackerHitCollection'; - collection: SimTrackerHitCollection; + collection: SimTrackerHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::CalorimeterHitCollection'; - collection: CalorimeterHitCollection; + collection: CalorimeterHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimCalorimeterHitCollection'; - collection: SimCalorimeterHitCollection; + collection: SimCalorimeterHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ClusterCollection'; - collection: ClusterCollection; + collection: Cluster[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; - collection: ReconstructedParticleCollection; + collection: ReconstructedParticle[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::RecoMCParticleLink'; - collection: RecoMCParticleLinkCollection; + collection: RecoMCParticleLink[]; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts index a922dc2b0..8a1714ed4 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts @@ -182,84 +182,71 @@ export namespace Schema3 { daughters: ObjectID[]; // The daughters this particle }; - export type EventHeaderCollection = EventHeader[]; - export type VertexCollection = Vertex[]; - export type TrackCollection = Track[]; - export type TrackerHit3DCollection = TrackerHit3D[]; - export type TrackerHitPlaneCollection = TrackerHitPlane[]; - export type SimTrackerHitCollection = SimTrackerHit[]; - export type CalorimeterHitCollection = CalorimeterHit[]; - export type SimCalorimeterHitCollection = SimCalorimeterHit[]; - export type ClusterCollection = Cluster[]; - export type ReconstructedParticleCollection = ReconstructedParticle[]; - export type RecoMCParticleLinkCollection = RecoMCParticleLink[]; - export type MCParticleCollection = MCParticle[]; - - export type Item = + export type Coll = | { collID: number; collSchemaVersion: number; collType: 'edm4hep::EventHeaderCollection'; - collection: EventHeaderCollection; + collection: EventHeader[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; - collection: VertexCollection; + collection: Vertex[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; - collection: TrackCollection; + collection: Track[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHit3DCollection'; - collection: TrackerHit3DCollection; + collection: TrackerHit3D[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHitPlaneCollection'; - collection: TrackerHitPlaneCollection; + collection: TrackerHitPlane[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimTrackerHitCollection'; - collection: SimTrackerHitCollection; + collection: SimTrackerHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::CalorimeterHitCollection'; - collection: CalorimeterHitCollection; + collection: CalorimeterHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimCalorimeterHitCollection'; - collection: SimCalorimeterHitCollection; + collection: SimCalorimeterHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ClusterCollection'; - collection: ClusterCollection; + collection: Cluster[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; - collection: ReconstructedParticleCollection; + collection: ReconstructedParticle[]; } | { collID: number; collSchemaVersion: number; collType: 'podio::LinkCollection'; - collection: RecoMCParticleLinkCollection; + collection: RecoMCParticleLink[]; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts index 3ba3bf89a..3996e7995 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts @@ -182,84 +182,71 @@ export namespace Schema4 { daughters: ObjectID[]; // The daughters this particle }; - export type EventHeaderCollection = EventHeader[]; - export type VertexCollection = Vertex[]; - export type TrackCollection = Track[]; - export type TrackerHit3DCollection = TrackerHit3D[]; - export type TrackerHitPlaneCollection = TrackerHitPlane[]; - export type SimTrackerHitCollection = SimTrackerHit[]; - export type CalorimeterHitCollection = CalorimeterHit[]; - export type SimCalorimeterHitCollection = SimCalorimeterHit[]; - export type ClusterCollection = Cluster[]; - export type ReconstructedParticleCollection = ReconstructedParticle[]; - export type RecoMCParticleLinkCollection = RecoMCParticleLink[]; - export type MCParticleCollection = MCParticle[]; - - export type Item = + export type Coll = | { collID: number; collSchemaVersion: number; collType: 'edm4hep::EventHeaderCollection'; - collection: EventHeaderCollection; + collection: EventHeader[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; - collection: VertexCollection; + collection: Vertex[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; - collection: TrackCollection; + collection: Track[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHit3DCollection'; - collection: TrackerHit3DCollection; + collection: TrackerHit3D[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHitPlaneCollection'; - collection: TrackerHitPlaneCollection; + collection: TrackerHitPlane[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimTrackerHitCollection'; - collection: SimTrackerHitCollection; + collection: SimTrackerHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::CalorimeterHitCollection'; - collection: CalorimeterHitCollection; + collection: CalorimeterHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimCalorimeterHitCollection'; - collection: SimCalorimeterHitCollection; + collection: SimCalorimeterHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ClusterCollection'; - collection: ClusterCollection; + collection: Cluster[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; - collection: ReconstructedParticleCollection; + collection: ReconstructedParticle[]; } | { collID: number; collSchemaVersion: number; collType: 'podio::LinkCollection'; - collection: RecoMCParticleLinkCollection; + collection: RecoMCParticleLink[]; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts index 5d9935d15..473472d8b 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts @@ -213,77 +213,77 @@ export namespace Schema5 { export type RecoMCParticleLinkCollection = RecoMCParticleLink[]; export type MCParticleCollection = MCParticle[]; - export type Item = + export type Coll = | { collID: number; collSchemaVersion: number; collType: 'edm4hep::EventHeaderCollection'; - collection: EventHeaderCollection; + collection: EventHeader[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; - collection: VertexCollection; + collection: Vertex[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; - collection: TrackCollection; + collection: Track[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHit3DCollection'; - collection: TrackerHit3DCollection; + collection: TrackerHit3D[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHitPlaneCollection'; - collection: TrackerHitPlaneCollection; + collection: TrackerHitPlane[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SenseWireHitCollection'; - collection: SenseWireHitCollection; + collection: SenseWireHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimTrackerHitCollection'; - collection: SimTrackerHitCollection; + collection: SimTrackerHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::CalorimeterHitCollection'; - collection: CalorimeterHitCollection; + collection: CalorimeterHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimCalorimeterHitCollection'; - collection: SimCalorimeterHitCollection; + collection: SimCalorimeterHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ClusterCollection'; - collection: ClusterCollection; + collection: Cluster[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; - collection: ReconstructedParticleCollection; + collection: ReconstructedParticle[]; } | { collID: number; collSchemaVersion: number; collType: 'podio::LinkCollection'; - collection: RecoMCParticleLinkCollection; + collection: RecoMCParticleLink[]; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts index 4a7f2077f..7d262a04f 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts @@ -199,91 +199,77 @@ export namespace Schema6 { daughters: ObjectID[]; // The daughters this particle }; - export type EventHeaderCollection = EventHeader[]; - export type VertexCollection = Vertex[]; - export type TrackCollection = Track[]; - export type TrackerHit3DCollection = TrackerHit3D[]; - export type TrackerHitPlaneCollection = TrackerHitPlane[]; - export type SenseWireHitCollection = SenseWireHit[]; - export type SimTrackerHitCollection = SimTrackerHit[]; - export type CalorimeterHitCollection = CalorimeterHit[]; - export type SimCalorimeterHitCollection = SimCalorimeterHit[]; - export type ClusterCollection = Cluster[]; - export type ReconstructedParticleCollection = ReconstructedParticle[]; - export type RecoMCParticleLinkCollection = RecoMCParticleLink[]; - export type MCParticleCollection = MCParticle[]; - - export type Item = + export type Coll = | { collID: number; collSchemaVersion: number; collType: 'edm4hep::EventHeaderCollection'; - collection: EventHeaderCollection; + collection: EventHeader[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::VertexCollection'; - collection: VertexCollection; + collection: Vertex[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackCollection'; - collection: TrackCollection; + collection: Track[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHit3DCollection'; - collection: TrackerHit3DCollection; + collection: TrackerHit3D[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::TrackerHitPlaneCollection'; - collection: TrackerHitPlaneCollection; + collection: TrackerHitPlane[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SenseWireHitCollection'; - collection: SenseWireHitCollection; + collection: SenseWireHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimTrackerHitCollection'; - collection: SimTrackerHitCollection; + collection: SimTrackerHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::CalorimeterHitCollection'; - collection: CalorimeterHitCollection; + collection: CalorimeterHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::SimCalorimeterHitCollection'; - collection: SimCalorimeterHitCollection; + collection: SimCalorimeterHit[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ClusterCollection'; - collection: ClusterCollection; + collection: Cluster[]; } | { collID: number; collSchemaVersion: number; collType: 'edm4hep::ReconstructedParticleCollection'; - collection: ReconstructedParticleCollection; + collection: ReconstructedParticle[]; } | { collID: number; collSchemaVersion: number; collType: 'podio::LinkCollection'; - collection: RecoMCParticleLinkCollection; + collection: RecoMCParticleLink[]; }; } diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep.ts b/packages/phoenix-event-display/src/lib/types/edm4hep.ts index 01aad3736..57a7a0324 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep.ts @@ -112,41 +112,21 @@ export namespace edm4hep { | Schema5.RecoMCParticleLink | Schema6.RecoMCParticleLink; - export type EventHeaderCollection = EventHeader[]; - - export type VertexCollection = Vertex[]; - - export type TrackCollection = Track[]; - - export type AssociationCollection = Association[]; - - export type HitCollection = Hit[]; - - export type caloCellCollection = CaloCell[]; - - export type ClusterCollection = CaloCluster[]; - - export type ReconstructedParticleCollection = ReconstructedParticle[]; - - export type MCParticleCollection = MCParticle[]; - - export type LinkCollection = Link[]; - export type Item = - | Schema1.Item - | Schema2.Item - | Schema3.Item - | Schema4.Item - | Schema5.Item - | Schema6.Item; + | Schema1.Coll + | Schema2.Coll + | Schema3.Coll + | Schema4.Coll + | Schema5.Coll + | Schema6.Coll; export type Event = { [name: string]: - | Schema1.Item - | Schema2.Item - | Schema3.Item - | Schema4.Item - | Schema5.Item - | Schema6.Item; + | Schema1.Coll + | Schema2.Coll + | Schema3.Coll + | Schema4.Coll + | Schema5.Coll + | Schema6.Coll; }; } From e946ec1e7b977c990f723743bfeb7f14c28a45f0 Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Tue, 10 Mar 2026 11:05:39 +0100 Subject: [PATCH 21/30] Delete aux file --- .../src/loaders/edm4hep-json-loader2.ts | 460 ------------------ 1 file changed, 460 deletions(-) delete mode 100644 packages/phoenix-event-display/src/loaders/edm4hep-json-loader2.ts diff --git a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader2.ts b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader2.ts deleted file mode 100644 index d433da9a5..000000000 --- a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader2.ts +++ /dev/null @@ -1,460 +0,0 @@ -import { PhoenixLoader } from './phoenix-loader'; -import { edmPhoenix } from 'src/lib/types/edmPhoenix'; -import { edm4hep } from 'src/lib/types/edm4hep'; -import { ObjectID, Vector3d } from 'src/lib/types/edm4hep-schemas/utils'; - -export class Edm4hepJsonLoader extends PhoenixLoader { - private rawEventData: any; - - constructor() { - super(); - this.eventData = {}; - } - - setRawEventData(rawEventData: any) { - this.rawEventData = rawEventData; - } - - processEventData(): void { - // Iterate over events - Object.entries(this.rawEventData).forEach( - ([eventName, rawEvent]: [string, edm4hep.Event]) => { - const newEvent: edmPhoenix.Event = { - 'event number': 0, - 'run number': 0, - Vertices: {}, - Tracks: {}, - Hits: {}, - CaloClusters: {}, - CaloCells: {}, - Jets: {}, - }; - - this.assignPID(rawEvent); - - // Iterate over event items - Object.entries(rawEvent).forEach( - ([collName, item]: [string, edm4hep.Item]) => { - switch (item.collType) { - case 'edm4hep::EventHeaderCollection': - newEvent['event number'] = Number( - item.collection[0].eventNumber ?? 0, - ); - newEvent['run number'] = Number( - item.collection[0].runNumber ?? 0, - ); - break; - case 'edm4hep::VertexCollection': - newEvent.Vertices[collName] = this.getVertices(item.collection); - break; - case 'edm4hep::TrackCollection': - this.getTracks( - rawEvent, - item.collection as edm4hep.TrackCollection, - ) - .filter(([, arr]) => arr.length > 0) - .forEach(([label, arr]) => { - newEvent.Tracks[`${collName} | ${label}`] = arr; - }); - break; - case 'edm4hep::TrackerHitCollection': - case 'edm4hep::TrackerHit3DCollection': - case 'edm4hep::TrackerHitPlaneCollection': - case 'edm4hep::SenseWireHitCollection': - case 'edm4hep::SimTrackerHitCollection': - this.getHits(rawEvent, item.collection) - .filter(([, arr]) => arr.length > 0) - .forEach(([label, arr]) => { - newEvent.Hits[`${collName} | ${label}`] = arr; - }); - break; - case 'edm4hep::CalorimeterHitCollection': - case 'edm4hep::SimCalorimeterHitCollection': - newEvent.CaloCells[collName] = this.getCaloCells( - item.collection, - ); - break; - case 'edm4hep::ClusterCollection': - // @todo highlight optional members in edm4hep - newEvent.CaloClusters[collName] = this.getCaloClusters( - item.collection, - ); - break; - case 'edm4hep::ReconstructedParticleCollection': - if (collName === 'Jet') - newEvent.Jets[collName] = this.getJets(item.collection); - // @todo 'missing' is never present - else if (collName.toLowerCase().includes('missing')) - newEvent.MissingEnergy[collName] = this.getMissingEnergy( - item.collection, - ); - break; - } - }, - ); - }, - ); - } - - /* Define particle PID based on link */ - private assignPID(rawEvent: any) { - // Link collection name and type vary by schema: - // - Schema 1: MCRecoAssociations - // - Schema 2: MCRecoAssociations or RecoMCLink - // - Schema 3: RecoMCLink - let linkCollection = (rawEvent.MCRecoAssociations ?? rawEvent.RecoMCLink) - ?.collection as - | edm4hep.AssociationCollection // Schema 1 - | edm4hep.LinkCollection; // From Schema 2 Onwards - - if (!linkCollection) return; - - let reconstructedParticleCollection = rawEvent.ReconstructedParticles - ?.collection as edm4hep.ReconstructedParticleCollection; - - if (!reconstructedParticleCollection) return; - - let mcParticleCollection = rawEvent.Particle - ?.collection as edm4hep.MCParticleCollection; - - if (!mcParticleCollection) return; - - let trackCollection = rawEvent.EFlowTrack - ?.collection as edm4hep.TrackCollection; - - if (!trackCollection) return; - - linkCollection.forEach((link: edm4hep.Association | edm4hep.Link) => { - const recIndex = 'rec' in link ? link.rec.index : link.from.index; - const simIndex = 'sim' in link ? link.sim.index : link.to.index; - const pdgid = mcParticleCollection[simIndex].PDG; - const trackRefs = reconstructedParticleCollection[recIndex].tracks; - - let color: string, pid: string; - - switch (Math.abs(pdgid)) { - case 11: - color = '00ff00'; - pid = 'electron'; - break; - case 22: - color = 'ff0000'; - pid = 'photon'; - break; - case 111: - case 211: - color = 'a52a2a'; - pid = 'pion'; - break; - case 2212: - color = '778899'; - pid = 'proton'; - break; - case 321: - color = '5f9ea0'; - pid = 'kaon'; - break; - default: - color = '0000cd'; - pid = 'other'; - } - - trackRefs.forEach(({ index }) => { - const track = trackCollection[index]; - - track.color = color; - track.pid = pid; - track.pdgid = pdgid; - }); - }); - } - - /** Return a random colour */ - private randomColor() { - return Math.floor(Math.random() * 16777215) - .toString(16) - .padStart(6, '0') - .toUpperCase(); - } - - /** Return vertices */ - private getVertices( - vertexCollection: edm4hep.VertexCollection, - ): edmPhoenix.Vertex[] { - return vertexCollection.map((vertex: edm4hep.Vertex) => ({ - pos: { - x: vertex.position.x * 0.1, - y: vertex.position.y * 0.1, - z: vertex.position.z * 0.1, - }, - color: `#${this.randomColor()}`, - })); - } - - /** Get the required collection */ - private getCollByID(event: any, id: number) { - const coll = Object.values(event).find((c: any) => c?.collID === id) as any; - return coll?.collection; - } - - private getTracks( - rawEvent: any, - trackCollection: edm4hep.TrackCollection, - ): { [name: string]: edmPhoenix.Hit[] } { - const categories: { [name: string]: edmPhoenix.Hit[] } = { - other: [], - electron: [], - photon: [], - pion: [], - proton: [], - kaon: [], - }; - - trackCollection.forEach((track: edm4hep.Track) => { - let newTrack: edmPhoenix.Track[] = []; - - if ('trackerHits' in track) { - track.trackerHits.forEach((trackerHitRef: ObjectID) => { - // @todo always assumes getCollById will return a collection - const trackerHits: edm4hep.HitCollection = this.getCollByID( - rawEvent, - trackerHitRef.collectionID, - ); - - // @todo change the structure - - newTrack.pos.x = trackerHits[trackerHitRef.index].position.x * 0.1; - newTrack.pos.y = trackerHits[trackerHitRef.index].position.y * 0.1; - newTrack.pos.z = trackerHits[trackerHitRef.index].position.z * 0.1; - newTrack.color = track.color ?? '0000cd'; - }); - } - - if (newTrack === null && 'trackStates' in track) { - track.trackStates.forEach((trackState: edm4hep.TrackState) => { - // @todo 'trackState' might always be present - newTrack.pos.x = trackState.referencePoint.x * 0.1; - newTrack.pos.y = trackState.referencePoint.y * 0.1; - newTrack.pos.z = trackState.referencePoint.z * 0.1; - newTrack.color = track.color ?? '0000cd'; - }); - } - - // @todo if none of those two properties exist definition will be invalid - - const category = track.pid ?? 'other'; - - categories[category].push(newTrack); - }); - - return categories; - } - - /** Find PDG of the particle associated with the hit */ - private getHits( - rawEvent: any, - hitCollection: edm4hep.Hit[], - ): { [name: string]: edmPhoenix.Hit[] } { - const categories: { [name: string]: edmPhoenix.Hit[] } = { - other: [], - overlay: [], - secondary: [], - electron: [], - muon: [], - pion: [], - kaon: [], - proton: [], - }; - - const colorOther = this.randomColor(); - const colorOverlay = this.randomColor(); - const colorSecondary = this.randomColor(); - const colorElectron = this.randomColor(); - const colorMuon = this.randomColor(); - const colorPion = this.randomColor(); - const colorKaon = this.randomColor(); - const colorProton = this.randomColor(); - - hitCollection.forEach((rawHit) => { - // @todo 'position' might always be present - const pos: Vector3d = { - x: rawHit.position.x * 0.1, - y: rawHit.position.y * 0.1, - z: rawHit.position.z * 0.1, - }; - - if ((rawHit.quality & (1 << 31)) !== 0) { - /* BITOverlay = 31 - * https://github.com/key4hep/EDM4hep/blob/fe5a54046a91a7e648d0b588960db7841aebc670/edm4hep.yaml#L349 - */ - categories.overlay.push({ - type: 'Point', - pos, - color: `#${colorOverlay}`, - }); - } else if ((rawHit.quality & (1 << 30)) !== 0) { - /* BITProducedBySecondary = 30 - * https://github.com/key4hep/EDM4hep/blob/fe5a54046a91a7e648d0b588960db7841aebc670/edm4hep.yaml#L350 - */ - categories.secondary.push({ - type: 'Point', - pos, - color: `#${colorSecondary}`, - }); - } else { - let ref: ObjectID | null = null; - - if ('particle' in rawHit && rawHit.particle.length > 0) { - // 'particle' exists in type SimTrackerHit from Schema2 onwards - ref = rawHit.particle[0]; - } else if ('MCParticle' in rawHit) { - // 'MCParticle' only exists in type SimTrackerHit within Schema1 - ref = rawHit.MCParticle; - } - - if (ref !== null) { - const collection = this.getCollByID(rawEvent, ref.collectionID); - const pdg = Math.abs(collection?.[ref.index]?.PDG ?? 0); - - switch (pdg) { - case 11: - categories.electron.push({ - type: 'Point', - pos, - color: `#${colorElectron}`, - }); - break; - case 13: - categories.muon.push({ - type: 'Point', - pos, - color: `#${colorMuon}`, - }); - break; - case 211: - categories.pion.push({ - type: 'Point', - pos, - color: `#${colorPion}`, - }); - break; - case 321: - categories.kaon.push({ - type: 'Point', - pos, - color: `#${colorKaon}`, - }); - break; - case 2212: - categories.proton.push({ - type: 'Point', - pos, - color: `#${colorProton}`, - }); - break; - default: - categories.other.push({ - type: 'Point', - pos, - color: `#${colorOther}`, - }); - break; - } - } else { - categories.other.push({ - type: 'Point', - pos, - color: `#${colorOther}`, - }); - } - } - }); - - return categories; - } - - /** Returns the cells */ - private getCaloCells( - caloCellCollection: edm4hep.CaloCell[], - ): edmPhoenix.CaloCell[] { - const cells: edmPhoenix.CaloCell[] = []; - - caloCellCollection.forEach((rawCell) => { - const x = rawCell.position.x * 0.1; - const y = rawCell.position.y * 0.1; - const z = rawCell.position.z * 0.1; - const rho = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); - - cells.push({ - eta: Math.asinh(z / rho), - phi: Math.acos(x / rho) * Math.sign(y), - energy: rawCell.energy, - }); - }); - - return cells; - } - - private getCaloClusters( - caloClusterCollection: edm4hep.CaloCluster[], - ): edmPhoenix.CaloCluster[] { - const clusters: edmPhoenix.CaloCluster[] = []; - - caloClusterCollection.forEach((rawCluster) => { - const x = rawCluster.position.x * 0.1; - const y = rawCluster.position.y * 0.1; - const z = rawCluster.position.z * 0.1; - const rho = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); - - clusters.push({ - eta: Math.asinh(z / rho), - phi: Math.acos(x / rho) * Math.sign(y), - energy: rawCluster.energy * 100, // @todo no apparent reason to multiply by 10 - }); - }); - - return clusters; - } - - private getJets( - jetCollection: edm4hep.ReconstructedParticle[], - ): edmPhoenix.Jet[] { - const jets: edmPhoenix.Jet[] = []; - - jetCollection.forEach((rawJet) => { - 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)); - - jets.push({ - eta: Math.asinh(pz / pt), - phi: Math.acos(px / pt) * Math.sign(py), - energy: rawJet.energy * 1000, // @todo this currently converts GeV -> MeV - }); - }); - - return jets; - } - - private getMissingEnergy( - missingEnergyCollection: edm4hep.ReconstructedParticle[], - ): edmPhoenix.MissingEnergy[] { - const missingEnergies: edmPhoenix.MissingEnergy[] = []; - - missingEnergyCollection.forEach((rawMissingEnergy: any) => { - const px = rawMissingEnergy.momentum.x; - const py = rawMissingEnergy.momentum.y; - const pz = rawMissingEnergy.momentum.z; - const p = Math.sqrt(Math.pow(px, 2) + Math.pow(py, 2) + Math.pow(pz, 2)); - - missingEnergies.push({ - etx: ((rawMissingEnergy.energy * px) / p) * 10, // @todo no apparent reason to multiply by 10 - ety: ((rawMissingEnergy.energy * py) / p) * 10, - color: '#ff69b4', - }); - }); - - return missingEnergies; - } -} From a4e994373d09881c35e4bfb1fc0c8d1ad194532a Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Tue, 10 Mar 2026 14:49:22 +0100 Subject: [PATCH 22/30] Locally disable TypeScript ESLint namespace rule --- .../src/lib/types/edm4hep-schemas/schema1.ts | 1 + .../src/lib/types/edm4hep-schemas/schema2.ts | 1 + .../src/lib/types/edm4hep-schemas/schema4.ts | 1 + .../src/lib/types/edm4hep-schemas/schema5.ts | 1 + .../src/lib/types/edm4hep-schemas/schema6.ts | 1 + packages/phoenix-event-display/src/lib/types/edm4hep.ts | 1 + .../overlay-view-window/overlay-view-window.component.ts | 1 - 7 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts index 8a7509d1b..21cd586a7 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema1.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-namespace */ import { Vector3f, Vector3d, Vector2i, ObjectID } from './utils'; export namespace Schema1 { diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts index 1979361e3..3cd457cbe 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema2.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-namespace */ import { CovMatrix3f, CovMatrix4f, diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts index 3996e7995..002aafc1e 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema4.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-namespace */ import { CovMatrix3f, CovMatrix4f, diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts index 473472d8b..7e39776b5 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema5.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-namespace */ import { CovMatrix3f, CovMatrix4f, diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts index 7d262a04f..dce8a808b 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema6.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-namespace */ import { CovMatrix3f, CovMatrix4f, diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep.ts b/packages/phoenix-event-display/src/lib/types/edm4hep.ts index 57a7a0324..6de093d19 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-namespace */ import { Schema1 } from './edm4hep-schemas/schema1'; import { Schema2 } from './edm4hep-schemas/schema2'; import { Schema3 } from './edm4hep-schemas/schema3'; diff --git a/packages/phoenix-ng/projects/phoenix-ui-components/lib/components/ui-menu/overlay-view/overlay-view-window/overlay-view-window.component.ts b/packages/phoenix-ng/projects/phoenix-ui-components/lib/components/ui-menu/overlay-view/overlay-view-window/overlay-view-window.component.ts index 4440e628b..7464c2e76 100644 --- a/packages/phoenix-ng/projects/phoenix-ui-components/lib/components/ui-menu/overlay-view/overlay-view-window/overlay-view-window.component.ts +++ b/packages/phoenix-ng/projects/phoenix-ui-components/lib/components/ui-menu/overlay-view/overlay-view-window/overlay-view-window.component.ts @@ -35,7 +35,6 @@ export class OverlayViewWindowComponent implements AfterViewInit { x: number = window.innerWidth / 2.5, y: number = window.innerHeight / 2.5, ): HTMLCanvasElement { - console.log('doneee'); const width = x; const height = y; canvas.width = width; From df6bd28094789bd166384954a6d7509866620b2b Mon Sep 17 00:00:00 2001 From: Pablo Apausa <74920898+apausa@users.noreply.github.com> Date: Tue, 10 Mar 2026 14:50:16 +0100 Subject: [PATCH 23/30] Refactor loader --- .../src/loaders/edm4hep-json-loader.ts | 911 +++++++----------- 1 file changed, 361 insertions(+), 550 deletions(-) diff --git a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts index 85014306c..85ec933ef 100644 --- a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts +++ b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts @@ -1,4 +1,7 @@ import { PhoenixLoader } from './phoenix-loader'; +import { edmPhoenix } from 'src/lib/types/edmPhoenix'; +import { edm4hep } from 'src/lib/types/edm4hep'; +import { ObjectID, Vector3d } from 'src/lib/types/edm4hep-schemas/utils'; /** * Edm4hepJsonLoader for loading EDM4hep json dumps @@ -20,76 +23,79 @@ export class Edm4hepJsonLoader extends PhoenixLoader { /** 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); - - for (const collName in event) { - const collDict = event[collName]; + console.log('This is a test'); + // Iterate over events + Object.entries(this.rawEventData).forEach( + ([eventName, rawEvent]: [string, edm4hep.Event]) => { + const newEvent: edmPhoenix.Event = { + 'event number': 0, + 'run number': 0, + Vertices: {}, + Tracks: {}, + Hits: {}, + CaloClusters: {}, + CaloCells: {}, + Jets: {}, + MissingEnergy: {}, + }; - if ( - collDict.constructor === Object && - 'collType' in collDict && - 'collection' in collDict - ) { - switch (collDict['collType']) { - case 'edm4hep::VertexCollection': - oneEventData.Vertices[collName] = this.getVertices(collDict); - break; - case 'edm4hep::TrackCollection': { - this.getTracks(event, collDict) - .filter(([, arr]) => arr.length > 0) - .forEach(([label, arr]) => { - oneEventData.Tracks[`${collName} | ${label}`] = arr; + this.assignPID(rawEvent); + + // Iterate over event collections + Object.entries(rawEvent).forEach( + ([collName, { collType, collection }]: [string, edm4hep.Item]) => { + switch (collType) { + case 'edm4hep::EventHeaderCollection': + newEvent['event number'] = Number( + collection[0].eventNumber ?? 0, + ); + newEvent['run number'] = Number(collection[0].runNumber ?? 0); + break; + case 'edm4hep::VertexCollection': + newEvent.Vertices[collName] = this.getVertices(collection); + break; + case 'edm4hep::TrackCollection': + this.getTracks(rawEvent, collection as edm4hep.Track[]).forEach( + ([label, arr]) => { + newEvent.Tracks[`${collName} | ${label}`] = arr; + }, + ); + break; + case 'edm4hep::TrackerHitCollection': + case 'edm4hep::TrackerHit3DCollection': + case 'edm4hep::TrackerHitPlaneCollection': + case 'edm4hep::SenseWireHitCollection': + case 'edm4hep::SimTrackerHitCollection': + this.getHits(rawEvent, collection).forEach(([label, arr]) => { + newEvent.Hits[`${collName} | ${label}`] = arr; }); - break; + break; + case 'edm4hep::CalorimeterHitCollection': //done + case 'edm4hep::SimCalorimeterHitCollection': + newEvent.CaloCells[collName] = this.getCaloCells(collection); + break; + case 'edm4hep::ClusterCollection': + // @todo highlight optional members in edm4hep + newEvent.CaloClusters[collName] = + this.getCaloClusters(collection); + break; + case 'edm4hep::ReconstructedParticleCollection': + if (collName === 'Jet') + newEvent.Jets[collName] = this.getJets(collection); + // @todo 'missing' is never present + else if (collName.toLowerCase().includes('missing')) + newEvent.MissingEnergy[collName] = + this.getMissingEnergy(collection); + break; } - case 'edm4hep::TrackerHitCollection': - case 'edm4hep::SimTrackerHitCollection': { - this.getHits(event, collDict) - .filter(([, arr]) => arr.length > 0) - .forEach(([label, arr]) => { - oneEventData.Hits[`${collName} | ${label}`] = arr; - }); - break; - } - case 'edm4hep::CalorimeterHitCollection': - case 'edm4hep::SimCalorimeterHitCollection': - oneEventData.CaloCells[collName] = this.getCells(collDict); - break; - case 'edm4hep::ClusterCollection': - oneEventData.CaloClusters[collName] = - this.getCaloClusters(collDict); - break; - case 'edm4hep::ReconstructedParticleCollection': - if (collName.includes('Jet') || collName.includes('jet')) { - oneEventData.Jets[collName] = this.getJets(collDict); - } else if ( - collName.includes('Missing') || - collName.includes('missing') - ) { - oneEventData.MissingEnergy[collName] = - this.getMissingEnergy(collDict); - } - break; - } - } - } + }, + ); - this.eventData[eventName] = oneEventData; - }); + this.eventData[eventName] = newEvent; + console.log(eventName, newEvent); + }, + ); return true; } @@ -103,505 +109,364 @@ export class Edm4hepJsonLoader extends PhoenixLoader { 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[0]) { - 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[0]) { - return eventHeader[0]['eventNumber']; - } - - return 0; - } - - /** Find PDG of the particle associated with the hit */ - private getPDG(event: any, collectionID: number, index: number) { - for (const collName in event) { - if (event[collName].constructor != Object) { - continue; - } - - const collDict = event[collName]; - - if (!('collID' in collDict)) { - continue; - } - - if (collDict['collID'] !== collectionID) { - continue; - } - - if (collDict['collection'].length <= index) { - continue; + /* Define particle PID based on link */ + private assignPID(rawEvent: any) { + // Link collection name and type vary by schema: + // - Schema 1: MCRecoAssociations + // - Schema 2: MCRecoAssociations or RecoMCLink + // - Schema 3: RecoMCLink + const linkCollection = (rawEvent.MCRecoAssociations ?? rawEvent.RecoMCLink) + ?.collection as + | edm4hep.Association[] // Schema 1 + | edm4hep.Link[]; // From Schema 2 Onwards + + if (!linkCollection) return; + + const reconstructedParticleCollection = rawEvent.ReconstructedParticles + ?.collection as edm4hep.ReconstructedParticle[]; + + if (!reconstructedParticleCollection) return; + + const mcParticleCollection = rawEvent.Particle + ?.collection as edm4hep.MCParticle[]; + + if (!mcParticleCollection) return; + + const trackCollection = rawEvent.EFlowTrack?.collection as edm4hep.Track[]; + + if (!trackCollection) return; + + linkCollection.forEach((link: edm4hep.Association | edm4hep.Link) => { + const recIndex = 'rec' in link ? link.rec.index : link.from.index; + const simIndex = 'sim' in link ? link.sim.index : link.to.index; + const pdgid = mcParticleCollection[simIndex].PDG; + const trackRefs = reconstructedParticleCollection[recIndex].tracks; + + let color: string, pid: string; + + switch (Math.abs(pdgid)) { + case 11: + color = '00ff00'; + pid = 'electron'; + break; + case 22: + color = 'ff0000'; + pid = 'photon'; + break; + case 111: + case 211: + color = 'a52a2a'; + pid = 'pion'; + break; + case 2212: + color = '778899'; + pid = 'proton'; + break; + case 321: + color = '5f9ea0'; + pid = 'kaon'; + break; + default: + color = '0000cd'; + pid = 'other'; } - return collDict['collection'][index]['PDG']; - } - - return 0; - } + trackRefs.forEach(({ index }) => { + const track = trackCollection[index]; - /** 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 = - typeof mcRecoAssoc['rec'] !== 'undefined' - ? mcRecoAssoc['rec']['index'] - : mcRecoAssoc['from']['index']; - const mcIndex = - typeof mcRecoAssoc['sim'] !== 'undefined' - ? mcRecoAssoc['sim']['index'] - : mcRecoAssoc['to']['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; + track.color = color; + track.pid = pid; + track.pdgid = pdgid; }); }); } - /** Return the vertices */ - private getVertices(collDict: any): any[] { - 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); - }); - - return vertices; + /** Return vertices */ + private getVertices(vertexCollection: edm4hep.Vertex[]): edmPhoenix.Vertex[] { + return vertexCollection.map((vertex: edm4hep.Vertex) => ({ + pos: { + x: vertex.position.x * 0.1, + y: vertex.position.y * 0.1, + z: vertex.position.z * 0.1, + }, + color: `#${this.randomColor()}`, + })); } /** Return tracks */ - private getTracks(event: any, collDict: any) { - 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[] = []; + private getTracks( + rawEvent: any, + trackCollection: edm4hep.Track[], + ): [string, edmPhoenix.Track[]][] { + const categories: { [name: string]: edmPhoenix.Track[][] } = { + other: [], + electron: [], + photon: [], + pion: [], + proton: [], + kaon: [], + }; + + trackCollection.forEach((rawTrack: edm4hep.Track) => { + const parsedHits: edmPhoenix.Track[] = []; + if ('trackerHits' in rawTrack) { - const trackerHitRefs = rawTrack['trackerHits']; - trackerHitRefs.forEach((trackerHitRef: any) => { - const trackerHits = this.getCollByID( - event, - trackerHitRef['collectionID'], + rawTrack.trackerHits.forEach((trackerHitRef: ObjectID) => { + // @todo always assumes getCollById will return a collection + const trackerHits: edm4hep.Hit[] = this.getCollByID( + rawEvent, + trackerHitRef.collectionID, ); - const trackerHit = trackerHits[trackerHitRef['index']]; - positions.push([ - trackerHit['position']['x'] * 0.1, - trackerHit['position']['y'] * 0.1, - trackerHit['position']['z'] * 0.1, - ]); + + parsedHits.push({ + pos: { + x: trackerHits[trackerHitRef.index].position.x * 0.1, + y: trackerHits[trackerHitRef.index].position.y * 0.1, + z: trackerHits[trackerHitRef.index].position.z * 0.1, + }, + color: rawTrack.color ?? '0000cd', + }); }); } - 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, - ]); - } + + if (parsedHits.length === 0 && 'trackStates' in rawTrack) { + rawTrack.trackStates.forEach((trackState: edm4hep.TrackState) => { + // @todo 'trackState' might always be present + parsedHits.push({ + pos: { + x: trackState.referencePoint.x * 0.1, + y: trackState.referencePoint.y * 0.1, + z: trackState.referencePoint.z * 0.1, + }, + color: rawTrack.color ?? '0000cd', + }); }); } - let trackColor = '0000cd'; - if ('color' in rawTrack) { - trackColor = rawTrack['color']; - } + // @todo if none of those two properties exist definition will be invalid - const track = { - pos: positions, - color: trackColor, - }; + const category = rawTrack.pid ?? 'other'; - 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); - } + categories[category].push(parsedHits); }); - return [ - ['Electrons', electrons], - ['Photons', photons], - ['Pions', pions], - ['Protons', protons], - ['Kaons', kaons], - ['Other', other], - ]; + return Object.entries(categories) + .map(([label, category]): [string, edmPhoenix.Track[]] => [ + label, + category.flat(), + ]) + .filter(([, arr]) => arr.length !== 0); } - /** Return tracker hits */ - private getHits(event: any, collDict: any) { - const rawHits = collDict['collection']; - const hits: any[] = []; - const hitsOverlay: any[] = []; - const hitsProdBySecondary: any[] = []; - const hitsElectron: any[] = []; - const hitsMuon: any[] = []; - const hitsPion: any[] = []; - const hitsKaon: any[] = []; - const hitsProton: any[] = []; - const hitColor = this.randomColor(); - const hitColorOverlay = this.randomColor(); - const hitColorProdBySecondary = this.randomColor(); - const hitColorElectron = this.randomColor(); - const hitColorMuon = this.randomColor(); - const hitColorPion = this.randomColor(); - const hitColorKaon = this.randomColor(); - const hitColorProton = 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); - } + /** Find PDG of the particle associated with the hit */ + private getHits( + rawEvent: any, + hitCollection: edm4hep.Hit[], + ): [string, edmPhoenix.Hit[]][] { + const categories: { [name: string]: edmPhoenix.Hit[] } = { + other: [], + overlay: [], + secondary: [], + electron: [], + muon: [], + pion: [], + kaon: [], + proton: [], + }; - /* BITOverlay = 31 - * https://github.com/key4hep/EDM4hep/blob/fe5a54046a91a7e648d0b588960db7841aebc670/edm4hep.yaml#L349 - */ - if ((rawHit['quality'] & (1 << 31)) !== 0) { - const hit = { - type: 'CircularPoint', - pos: position, - color: '#' + hitColorOverlay, - size: 2, - }; - hitsOverlay.push(hit); + const colorOther = this.randomColor(); + const colorOverlay = this.randomColor(); + const colorSecondary = this.randomColor(); + const colorElectron = this.randomColor(); + const colorMuon = this.randomColor(); + const colorPion = this.randomColor(); + const colorKaon = this.randomColor(); + const colorProton = this.randomColor(); + + hitCollection.forEach((rawHit) => { + // @todo 'position' might always be present + const pos: Vector3d = { + x: rawHit.position.x * 0.1, + y: rawHit.position.y * 0.1, + z: rawHit.position.z * 0.1, + }; + + if ((rawHit.quality & (1 << 31)) !== 0) { + /* BITOverlay = 31 + * https://github.com/key4hep/EDM4hep/blob/fe5a54046a91a7e648d0b588960db7841aebc670/edm4hep.yaml#L349 + */ + categories.overlay.push({ + type: 'Point', + pos, + color: `#${colorOverlay}`, + }); + } else if ((rawHit.quality & (1 << 30)) !== 0) { /* BITProducedBySecondary = 30 * https://github.com/key4hep/EDM4hep/blob/fe5a54046a91a7e648d0b588960db7841aebc670/edm4hep.yaml#L350 */ - } else if ((rawHit['quality'] & (1 << 30)) !== 0) { - const hit = { - type: 'CircularPoint', - pos: position, - color: '#' + hitColorProdBySecondary, - size: 2, - }; - hitsProdBySecondary.push(hit); + categories.secondary.push({ + type: 'Point', + pos, + color: `#${colorSecondary}`, + }); } else { - let other = true; - if (rawHit['particle']?.length > 0) { - const pdg = this.getPDG( - event, - rawHit['particle'][0]['collectionID'], - rawHit['particle'][0]['index'], - ); - if (Math.abs(pdg) === 11) { - const hit = { - type: 'CircularPoint', - pos: position, - color: '#' + hitColorElectron, - size: 2, - }; - hitsElectron.push(hit); - other = false; - } else if (Math.abs(pdg) === 13) { - const hit = { - type: 'CircularPoint', - pos: position, - color: '#' + hitColorMuon, - size: 2, - }; - hitsMuon.push(hit); - other = false; - } else if (Math.abs(pdg) === 211) { - const hit = { - type: 'CircularPoint', - pos: position, - color: '#' + hitColorPion, - size: 2, - }; - hitsPion.push(hit); - other = false; - } else if (Math.abs(pdg) === 321) { - const hit = { - type: 'CircularPoint', - pos: position, - color: '#' + hitColorKaon, - size: 2, - }; - hitsKaon.push(hit); - other = false; - } else if (Math.abs(pdg) === 2212) { - const hit = { - type: 'CircularPoint', - pos: position, - color: '#' + hitColorProton, - size: 2, - }; - hitsProton.push(hit); - other = false; - } + let ref: ObjectID | null = null; + + if ('particle' in rawHit && rawHit.particle.length > 0) { + // 'particle' exists in type SimTrackerHit from Schema2 onwards + ref = rawHit.particle[0]; + } else if ('MCParticle' in rawHit) { + // 'MCParticle' only exists in type SimTrackerHit within Schema1 + ref = rawHit.MCParticle; } - if (other) { - const hit = { - type: 'CircularPoint', - pos: position, - color: '#' + hitColor, - size: 2, - }; - hits.push(hit); + + if (ref !== null) { + const collection = this.getCollByID(rawEvent, ref.collectionID); + const pdg = Math.abs(collection?.[ref.index]?.PDG ?? 0); + + switch (pdg) { + case 11: + categories.electron.push({ + type: 'Point', + pos, + color: `#${colorElectron}`, + }); + break; + case 13: + categories.muon.push({ + type: 'Point', + pos, + color: `#${colorMuon}`, + }); + break; + case 211: + categories.pion.push({ + type: 'Point', + pos, + color: `#${colorPion}`, + }); + break; + case 321: + categories.kaon.push({ + type: 'Point', + pos, + color: `#${colorKaon}`, + }); + break; + case 2212: + categories.proton.push({ + type: 'Point', + pos, + color: `#${colorProton}`, + }); + break; + default: + categories.other.push({ + type: 'Point', + pos, + color: `#${colorOther}`, + }); + break; + } + } else { + categories.other.push({ + type: 'Point', + pos, + color: `#${colorOther}`, + }); } } }); - return [ - ['Other', hits], - ['Overlay', hitsOverlay], - ['Secondary', hitsProdBySecondary], - ['Electron', hitsElectron], - ['Muon', hitsMuon], - ['Pion', hitsPion], - ['Kaon', hitsKaon], - ['Proton', hitsProton], - ]; + return Object.entries(categories).filter(([, arr]) => arr.length !== 0); } /** Returns the cells */ - private getCells(collDict: any) { - 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); + private getCaloCells( + caloCellCollection: edm4hep.CaloCell[], + ): edmPhoenix.CaloCell[] { + const cells: edmPhoenix.CaloCell[] = []; - rawCells.forEach((rawCell: any) => { + caloCellCollection.forEach((rawCell) => { 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, + + cells.push({ + eta: Math.asinh(z / rho), + phi: Math.acos(x / rho) * Math.sign(y), 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); + }); }); return cells; } /** Return Calo clusters */ - private getCaloClusters(collDict: any) { - const rawClusters = collDict['collection']; - const clusters: any[] = []; + private getCaloClusters( + caloClusterCollection: edm4hep.CaloCluster[], + ): edmPhoenix.CaloCluster[] { + const clusters: edmPhoenix.CaloCluster[] = []; - rawClusters.forEach((rawCluster: any) => { + caloClusterCollection.forEach((rawCluster) => { 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); + + clusters.push({ + eta: Math.asinh(z / rho), + phi: Math.acos(x / rho) * Math.sign(y), + energy: rawCluster.energy * 100, // @todo no apparent reason to multiply by 10 + }); }); return clusters; } /** Return jets */ - private getJets(collDict: any) { - 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']; - + private getJets( + jetCollection: edm4hep.ReconstructedParticle[], + ): edmPhoenix.Jet[] { + const jets: edmPhoenix.Jet[] = []; + + jetCollection.forEach((rawJet) => { + const px: number = rawJet.momentum.x; + const py: number = rawJet.momentum.y; + const pz: number = 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); + jets.push({ + eta: Math.asinh(pz / pt), + phi: Math.acos(px / pt) * Math.sign(py), + energy: rawJet.energy * 1000, // @todo this currently converts GeV -> MeV + }); }); + return jets; } /** Return missing energy */ - private getMissingEnergy(collDict: any) { - const METs: any[] = []; - const rawMETs = collDict['collection']; - - 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']; - + private getMissingEnergy( + missingEnergyCollection: edm4hep.ReconstructedParticle[], + ): edmPhoenix.MissingEnergy[] { + const missingEnergies: edmPhoenix.MissingEnergy[] = []; + + missingEnergyCollection.forEach((rawMissingEnergy: any) => { + const px: number = rawMissingEnergy.momentum.x; + const py: number = rawMissingEnergy.momentum.y; + const pz: number = rawMissingEnergy.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, + missingEnergies.push({ + etx: ((rawMissingEnergy.energy * px) / p) * 10, // @todo no apparent reason to multiply by 10 + ety: ((rawMissingEnergy.energy * py) / p) * 10, color: '#ff69b4', - }; - METs.push(MET); + }); }); - return METs; + + return missingEnergies; } /** Return a random colour */ @@ -612,63 +477,9 @@ export class Edm4hepJsonLoader extends PhoenixLoader { .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: number) => { - 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']; - } - } + const coll = Object.values(event).find((c: any) => c?.collID === id) as any; + return coll?.collection; } } From 34f07b9dccce6453861c71d472c6a624c28e5f4c Mon Sep 17 00:00:00 2001 From: pablo <74920898+apausa@users.noreply.github.com> Date: Wed, 11 Mar 2026 12:06:21 +0100 Subject: [PATCH 24/30] Debug code --- .../src/lib/types/edm4hep-schemas/schema3.ts | 1 + .../src/lib/types/edmPhoenix.ts | 11 +- .../src/loaders/edm4hep-json-loader.ts | 142 +++++++++--------- 3 files changed, 81 insertions(+), 73 deletions(-) diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts index 8a1714ed4..7b6d05403 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep-schemas/schema3.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-namespace */ import { CovMatrix3f, CovMatrix4f, diff --git a/packages/phoenix-event-display/src/lib/types/edmPhoenix.ts b/packages/phoenix-event-display/src/lib/types/edmPhoenix.ts index 7029045e3..ab67dbf87 100644 --- a/packages/phoenix-event-display/src/lib/types/edmPhoenix.ts +++ b/packages/phoenix-event-display/src/lib/types/edmPhoenix.ts @@ -1,13 +1,14 @@ -import { Vector3d } from './edm4hep-schemas/utils'; - +/* eslint-disable @typescript-eslint/no-namespace */ export namespace edmPhoenix { + export type Position = [number, number, number]; + export type Vertex = { + pos: Position; color?: string; - pos: Vector3d; }; export type Track = { - pos: Vector3d; + pos: Position; color?: string; d0?: number; z0?: number; @@ -17,8 +18,8 @@ export namespace edmPhoenix { }; export type Hit = { + pos: Position; type?: 'Point'; - pos: Vector3d; color?: string; }; diff --git a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts index 85ec933ef..d40527ea7 100644 --- a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts +++ b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts @@ -70,18 +70,17 @@ export class Edm4hepJsonLoader extends PhoenixLoader { newEvent.Hits[`${collName} | ${label}`] = arr; }); break; - case 'edm4hep::CalorimeterHitCollection': //done + case 'edm4hep::CalorimeterHitCollection': case 'edm4hep::SimCalorimeterHitCollection': - newEvent.CaloCells[collName] = this.getCaloCells(collection); + newEvent.CaloCells[collName] = this.getCaloCells(collection); // done break; case 'edm4hep::ClusterCollection': - // @todo highlight optional members in edm4hep newEvent.CaloClusters[collName] = - this.getCaloClusters(collection); + this.getCaloClusters(collection); // done break; case 'edm4hep::ReconstructedParticleCollection': if (collName === 'Jet') - newEvent.Jets[collName] = this.getJets(collection); + newEvent.Jets[collName] = this.getJets(collection); // done // @todo 'missing' is never present else if (collName.toLowerCase().includes('missing')) newEvent.MissingEnergy[collName] = @@ -146,28 +145,28 @@ export class Edm4hepJsonLoader extends PhoenixLoader { switch (Math.abs(pdgid)) { case 11: - color = '00ff00'; + color = '#00ff00'; pid = 'electron'; break; case 22: - color = 'ff0000'; + color = '#ff0000'; pid = 'photon'; break; case 111: case 211: - color = 'a52a2a'; + color = '#a52a2a'; pid = 'pion'; break; case 2212: - color = '778899'; + color = '#778899'; pid = 'proton'; break; case 321: - color = '5f9ea0'; + color = '#5f9ea0'; pid = 'kaon'; break; default: - color = '0000cd'; + color = '#0000cd'; pid = 'other'; } @@ -184,12 +183,12 @@ export class Edm4hepJsonLoader extends PhoenixLoader { /** Return vertices */ private getVertices(vertexCollection: edm4hep.Vertex[]): edmPhoenix.Vertex[] { return vertexCollection.map((vertex: edm4hep.Vertex) => ({ - pos: { - x: vertex.position.x * 0.1, - y: vertex.position.y * 0.1, - z: vertex.position.z * 0.1, - }, - color: `#${this.randomColor()}`, + pos: [ + (vertex.position?.x ?? 0) * 0.1, + (vertex.position?.y ?? 0) * 0.1, + (vertex.position?.z ?? 0) * 0.1, + ], + color: this.randomColor(), })); } @@ -210,7 +209,7 @@ export class Edm4hepJsonLoader extends PhoenixLoader { trackCollection.forEach((rawTrack: edm4hep.Track) => { const parsedHits: edmPhoenix.Track[] = []; - if ('trackerHits' in rawTrack) { + if ('trackerHits' in rawTrack && rawTrack.trackerHits.length > 0) { rawTrack.trackerHits.forEach((trackerHitRef: ObjectID) => { // @todo always assumes getCollById will return a collection const trackerHits: edm4hep.Hit[] = this.getCollByID( @@ -219,26 +218,30 @@ export class Edm4hepJsonLoader extends PhoenixLoader { ); parsedHits.push({ - pos: { - x: trackerHits[trackerHitRef.index].position.x * 0.1, - y: trackerHits[trackerHitRef.index].position.y * 0.1, - z: trackerHits[trackerHitRef.index].position.z * 0.1, - }, - color: rawTrack.color ?? '0000cd', + pos: [ + (trackerHits[trackerHitRef.index].position?.x ?? 0) * 0.1, + (trackerHits[trackerHitRef.index].position?.y ?? 0) * 0.1, + (trackerHits[trackerHitRef.index].position?.z ?? 0) * 0.1, + ], + color: rawTrack.color ?? '#0000cd', }); }); } - if (parsedHits.length === 0 && 'trackStates' in rawTrack) { + if ( + parsedHits.length === 0 && + 'trackStates' in rawTrack && + rawTrack.trackStates.length > 0 + ) { rawTrack.trackStates.forEach((trackState: edm4hep.TrackState) => { // @todo 'trackState' might always be present parsedHits.push({ - pos: { - x: trackState.referencePoint.x * 0.1, - y: trackState.referencePoint.y * 0.1, - z: trackState.referencePoint.z * 0.1, - }, - color: rawTrack.color ?? '0000cd', + pos: [ + (trackState.referencePoint?.x ?? 0) * 0.1, + (trackState.referencePoint?.y ?? 0) * 0.1, + (trackState.referencePoint?.z ?? 0) * 0.1, + ], + color: rawTrack.color ?? '#0000cd', }); }); } @@ -258,7 +261,7 @@ export class Edm4hepJsonLoader extends PhoenixLoader { .filter(([, arr]) => arr.length !== 0); } - /** Find PDG of the particle associated with the hit */ + /** Return tracker hits */ private getHits( rawEvent: any, hitCollection: edm4hep.Hit[], @@ -284,21 +287,21 @@ export class Edm4hepJsonLoader extends PhoenixLoader { const colorProton = this.randomColor(); hitCollection.forEach((rawHit) => { - // @todo 'position' might always be present - const pos: Vector3d = { - x: rawHit.position.x * 0.1, - y: rawHit.position.y * 0.1, - z: rawHit.position.z * 0.1, - }; + const pos: edmPhoenix.Position = [ + (rawHit.position?.x ?? 0) * 0.1, + (rawHit.position?.y ?? 0) * 0.1, + (rawHit.position?.z ?? 0) * 0.1, + ]; if ((rawHit.quality & (1 << 31)) !== 0) { + //@todo quality is always 0 /* BITOverlay = 31 * https://github.com/key4hep/EDM4hep/blob/fe5a54046a91a7e648d0b588960db7841aebc670/edm4hep.yaml#L349 */ categories.overlay.push({ type: 'Point', pos, - color: `#${colorOverlay}`, + color: colorOverlay, }); } else if ((rawHit.quality & (1 << 30)) !== 0) { /* BITProducedBySecondary = 30 @@ -307,7 +310,7 @@ export class Edm4hepJsonLoader extends PhoenixLoader { categories.secondary.push({ type: 'Point', pos, - color: `#${colorSecondary}`, + color: colorSecondary, }); } else { let ref: ObjectID | null = null; @@ -323,56 +326,59 @@ export class Edm4hepJsonLoader extends PhoenixLoader { if (ref !== null) { const collection = this.getCollByID(rawEvent, ref.collectionID); const pdg = Math.abs(collection?.[ref.index]?.PDG ?? 0); + console.log('Hits found collection', collection, pdg); switch (pdg) { case 11: categories.electron.push({ type: 'Point', pos, - color: `#${colorElectron}`, + color: colorElectron, }); break; case 13: categories.muon.push({ type: 'Point', pos, - color: `#${colorMuon}`, + color: colorMuon, }); break; case 211: categories.pion.push({ type: 'Point', pos, - color: `#${colorPion}`, + color: colorPion, }); break; case 321: categories.kaon.push({ type: 'Point', pos, - color: `#${colorKaon}`, + color: colorKaon, }); break; case 2212: categories.proton.push({ type: 'Point', pos, - color: `#${colorProton}`, + color: colorProton, }); break; default: categories.other.push({ type: 'Point', pos, - color: `#${colorOther}`, + color: colorOther, }); break; } } else { + console.log('Hits no ref'); + categories.other.push({ type: 'Point', pos, - color: `#${colorOther}`, + color: colorOther, }); } } @@ -381,22 +387,22 @@ export class Edm4hepJsonLoader extends PhoenixLoader { return Object.entries(categories).filter(([, arr]) => arr.length !== 0); } - /** Returns the cells */ + /** Returns Calo cells */ private getCaloCells( caloCellCollection: edm4hep.CaloCell[], ): edmPhoenix.CaloCell[] { const cells: edmPhoenix.CaloCell[] = []; caloCellCollection.forEach((rawCell) => { - const x = rawCell.position.x * 0.1; - const y = rawCell.position.y * 0.1; - const z = rawCell.position.z * 0.1; + const x = (rawCell.position?.x ?? 0) * 0.1; + const y = (rawCell.position?.y ?? 0) * 0.1; + const z = (rawCell.position?.z ?? 0) * 0.1; const rho = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); cells.push({ - eta: Math.asinh(z / rho), - phi: Math.acos(x / rho) * Math.sign(y), - energy: rawCell.energy, + eta: rho === 0 ? 0 : Math.asinh(z / rho), // Check because '0 / 0 = NaN' + phi: Math.atan2(y, x), // Safer equivalent to 'Math.acos(x / rho) * Math.sign(y)' + energy: rawCell.energy ?? 0, }); }); @@ -410,15 +416,15 @@ export class Edm4hepJsonLoader extends PhoenixLoader { const clusters: edmPhoenix.CaloCluster[] = []; caloClusterCollection.forEach((rawCluster) => { - const x = rawCluster.position.x * 0.1; - const y = rawCluster.position.y * 0.1; - const z = rawCluster.position.z * 0.1; + const x = (rawCluster.position?.x ?? 0) * 0.1; + const y = (rawCluster.position?.y ?? 0) * 0.1; + const z = (rawCluster.position?.z ?? 0) * 0.1; const rho = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); clusters.push({ - eta: Math.asinh(z / rho), - phi: Math.acos(x / rho) * Math.sign(y), - energy: rawCluster.energy * 100, // @todo no apparent reason to multiply by 10 + eta: rho === 0 ? 0 : Math.asinh(z / rho), // Check because '0 / 0 = NaN' + phi: Math.atan2(y, x), // Safer equivalent to 'Math.acos(x / rho) * Math.sign(y)' + energy: rawCluster.energy ?? 0, }); }); @@ -432,15 +438,15 @@ export class Edm4hepJsonLoader extends PhoenixLoader { const jets: edmPhoenix.Jet[] = []; jetCollection.forEach((rawJet) => { - const px: number = rawJet.momentum.x; - const py: number = rawJet.momentum.y; - const pz: number = rawJet.momentum.z; + const px: number = rawJet.momentum?.x ?? 0; + const py: number = rawJet.momentum?.y ?? 0; + const pz: number = rawJet.momentum?.z ?? 0; const pt = Math.sqrt(Math.pow(px, 2) + Math.pow(py, 2)); jets.push({ - eta: Math.asinh(pz / pt), - phi: Math.acos(px / pt) * Math.sign(py), - energy: rawJet.energy * 1000, // @todo this currently converts GeV -> MeV + eta: pt === 0 ? 0 : Math.asinh(pz / pt), // Check because '0 / 0 = NaN' + phi: Math.atan2(py, px), // Safer equivalent to 'Math.acos(px / pt) * Math.sign(py)' + energy: rawJet.energy ?? 0, }); }); @@ -471,10 +477,10 @@ export class Edm4hepJsonLoader extends PhoenixLoader { /** Return a random colour */ private randomColor() { - return Math.floor(Math.random() * 16777215) + return `#${Math.floor(Math.random() * 16777215) .toString(16) .padStart(6, '0') - .toUpperCase(); + .toUpperCase()}`; } /** Get the required collection */ From fe4cde6a70c0234686df000e76e80820e1e685dd Mon Sep 17 00:00:00 2001 From: pablo <74920898+apausa@users.noreply.github.com> Date: Wed, 11 Mar 2026 15:14:55 +0100 Subject: [PATCH 25/30] Exclude TrackerHitPlane and SenseWireHit --- .../src/loaders/edm4hep-json-loader.ts | 63 +++++++++---------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts index d40527ea7..e48d77400 100644 --- a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts +++ b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts @@ -63,24 +63,25 @@ export class Edm4hepJsonLoader extends PhoenixLoader { break; case 'edm4hep::TrackerHitCollection': case 'edm4hep::TrackerHit3DCollection': - case 'edm4hep::TrackerHitPlaneCollection': - case 'edm4hep::SenseWireHitCollection': case 'edm4hep::SimTrackerHitCollection': + // case 'edm4hep::TrackerHitPlaneCollection': + // case 'edm4hep::SenseWireHitCollection': + this.getHits(rawEvent, collection).forEach(([label, arr]) => { newEvent.Hits[`${collName} | ${label}`] = arr; }); break; case 'edm4hep::CalorimeterHitCollection': case 'edm4hep::SimCalorimeterHitCollection': - newEvent.CaloCells[collName] = this.getCaloCells(collection); // done + newEvent.CaloCells[collName] = this.getCaloCells(collection); break; case 'edm4hep::ClusterCollection': newEvent.CaloClusters[collName] = - this.getCaloClusters(collection); // done + this.getCaloClusters(collection); break; case 'edm4hep::ReconstructedParticleCollection': if (collName === 'Jet') - newEvent.Jets[collName] = this.getJets(collection); // done + newEvent.Jets[collName] = this.getJets(collection); // @todo 'missing' is never present else if (collName.toLowerCase().includes('missing')) newEvent.MissingEnergy[collName] = @@ -184,9 +185,9 @@ export class Edm4hepJsonLoader extends PhoenixLoader { private getVertices(vertexCollection: edm4hep.Vertex[]): edmPhoenix.Vertex[] { return vertexCollection.map((vertex: edm4hep.Vertex) => ({ pos: [ - (vertex.position?.x ?? 0) * 0.1, - (vertex.position?.y ?? 0) * 0.1, - (vertex.position?.z ?? 0) * 0.1, + vertex.position?.x * 0.1, + vertex.position?.y * 0.1, + vertex.position?.z * 0.1, ], color: this.randomColor(), })); @@ -219,9 +220,9 @@ export class Edm4hepJsonLoader extends PhoenixLoader { parsedHits.push({ pos: [ - (trackerHits[trackerHitRef.index].position?.x ?? 0) * 0.1, - (trackerHits[trackerHitRef.index].position?.y ?? 0) * 0.1, - (trackerHits[trackerHitRef.index].position?.z ?? 0) * 0.1, + trackerHits[trackerHitRef.index].position?.x * 0.1, + trackerHits[trackerHitRef.index].position?.y * 0.1, + trackerHits[trackerHitRef.index].position?.z * 0.1, ], color: rawTrack.color ?? '#0000cd', }); @@ -237,9 +238,9 @@ export class Edm4hepJsonLoader extends PhoenixLoader { // @todo 'trackState' might always be present parsedHits.push({ pos: [ - (trackState.referencePoint?.x ?? 0) * 0.1, - (trackState.referencePoint?.y ?? 0) * 0.1, - (trackState.referencePoint?.z ?? 0) * 0.1, + trackState.referencePoint?.x * 0.1, + trackState.referencePoint?.y * 0.1, + trackState.referencePoint?.z * 0.1, ], color: rawTrack.color ?? '#0000cd', }); @@ -288,13 +289,12 @@ export class Edm4hepJsonLoader extends PhoenixLoader { hitCollection.forEach((rawHit) => { const pos: edmPhoenix.Position = [ - (rawHit.position?.x ?? 0) * 0.1, - (rawHit.position?.y ?? 0) * 0.1, - (rawHit.position?.z ?? 0) * 0.1, + rawHit.position?.x * 0.1, + rawHit.position?.y * 0.1, + rawHit.position?.z * 0.1, ]; if ((rawHit.quality & (1 << 31)) !== 0) { - //@todo quality is always 0 /* BITOverlay = 31 * https://github.com/key4hep/EDM4hep/blob/fe5a54046a91a7e648d0b588960db7841aebc670/edm4hep.yaml#L349 */ @@ -326,7 +326,6 @@ export class Edm4hepJsonLoader extends PhoenixLoader { if (ref !== null) { const collection = this.getCollByID(rawEvent, ref.collectionID); const pdg = Math.abs(collection?.[ref.index]?.PDG ?? 0); - console.log('Hits found collection', collection, pdg); switch (pdg) { case 11: @@ -373,8 +372,6 @@ export class Edm4hepJsonLoader extends PhoenixLoader { break; } } else { - console.log('Hits no ref'); - categories.other.push({ type: 'Point', pos, @@ -394,15 +391,15 @@ export class Edm4hepJsonLoader extends PhoenixLoader { const cells: edmPhoenix.CaloCell[] = []; caloCellCollection.forEach((rawCell) => { - const x = (rawCell.position?.x ?? 0) * 0.1; - const y = (rawCell.position?.y ?? 0) * 0.1; - const z = (rawCell.position?.z ?? 0) * 0.1; + const x = rawCell.position?.x * 0.1; + const y = rawCell.position?.y * 0.1; + const z = rawCell.position?.z * 0.1; const rho = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); cells.push({ eta: rho === 0 ? 0 : Math.asinh(z / rho), // Check because '0 / 0 = NaN' phi: Math.atan2(y, x), // Safer equivalent to 'Math.acos(x / rho) * Math.sign(y)' - energy: rawCell.energy ?? 0, + energy: rawCell.energy, }); }); @@ -416,15 +413,15 @@ export class Edm4hepJsonLoader extends PhoenixLoader { const clusters: edmPhoenix.CaloCluster[] = []; caloClusterCollection.forEach((rawCluster) => { - const x = (rawCluster.position?.x ?? 0) * 0.1; - const y = (rawCluster.position?.y ?? 0) * 0.1; - const z = (rawCluster.position?.z ?? 0) * 0.1; + const x = rawCluster.position.x * 0.1; + const y = rawCluster.position.y * 0.1; + const z = rawCluster.position.z * 0.1; const rho = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); clusters.push({ eta: rho === 0 ? 0 : Math.asinh(z / rho), // Check because '0 / 0 = NaN' phi: Math.atan2(y, x), // Safer equivalent to 'Math.acos(x / rho) * Math.sign(y)' - energy: rawCluster.energy ?? 0, + energy: rawCluster.energy, }); }); @@ -438,15 +435,15 @@ export class Edm4hepJsonLoader extends PhoenixLoader { const jets: edmPhoenix.Jet[] = []; jetCollection.forEach((rawJet) => { - const px: number = rawJet.momentum?.x ?? 0; - const py: number = rawJet.momentum?.y ?? 0; - const pz: number = rawJet.momentum?.z ?? 0; + const px: number = rawJet.momentum.x; + const py: number = rawJet.momentum.y; + const pz: number = rawJet.momentum.z; const pt = Math.sqrt(Math.pow(px, 2) + Math.pow(py, 2)); jets.push({ eta: pt === 0 ? 0 : Math.asinh(pz / pt), // Check because '0 / 0 = NaN' phi: Math.atan2(py, px), // Safer equivalent to 'Math.acos(px / pt) * Math.sign(py)' - energy: rawJet.energy ?? 0, + energy: rawJet.energy, }); }); From 427d59923d3e6330de86d7d749e3969ef1283d42 Mon Sep 17 00:00:00 2001 From: pablo <74920898+apausa@users.noreply.github.com> Date: Wed, 11 Mar 2026 15:17:24 +0100 Subject: [PATCH 26/30] Remove property nullity checks --- .../src/loaders/edm4hep-json-loader.ts | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts index e48d77400..2a4f761d7 100644 --- a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts +++ b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts @@ -82,7 +82,6 @@ export class Edm4hepJsonLoader extends PhoenixLoader { case 'edm4hep::ReconstructedParticleCollection': if (collName === 'Jet') newEvent.Jets[collName] = this.getJets(collection); - // @todo 'missing' is never present else if (collName.toLowerCase().includes('missing')) newEvent.MissingEnergy[collName] = this.getMissingEnergy(collection); @@ -185,9 +184,9 @@ export class Edm4hepJsonLoader extends PhoenixLoader { private getVertices(vertexCollection: edm4hep.Vertex[]): edmPhoenix.Vertex[] { return vertexCollection.map((vertex: edm4hep.Vertex) => ({ pos: [ - vertex.position?.x * 0.1, - vertex.position?.y * 0.1, - vertex.position?.z * 0.1, + vertex.position.x * 0.1, + vertex.position.y * 0.1, + vertex.position.z * 0.1, ], color: this.randomColor(), })); @@ -220,9 +219,9 @@ export class Edm4hepJsonLoader extends PhoenixLoader { parsedHits.push({ pos: [ - trackerHits[trackerHitRef.index].position?.x * 0.1, - trackerHits[trackerHitRef.index].position?.y * 0.1, - trackerHits[trackerHitRef.index].position?.z * 0.1, + trackerHits[trackerHitRef.index].position.x * 0.1, + trackerHits[trackerHitRef.index].position.y * 0.1, + trackerHits[trackerHitRef.index].position.z * 0.1, ], color: rawTrack.color ?? '#0000cd', }); @@ -238,9 +237,9 @@ export class Edm4hepJsonLoader extends PhoenixLoader { // @todo 'trackState' might always be present parsedHits.push({ pos: [ - trackState.referencePoint?.x * 0.1, - trackState.referencePoint?.y * 0.1, - trackState.referencePoint?.z * 0.1, + trackState.referencePoint.x * 0.1, + trackState.referencePoint.y * 0.1, + trackState.referencePoint.z * 0.1, ], color: rawTrack.color ?? '#0000cd', }); @@ -289,9 +288,9 @@ export class Edm4hepJsonLoader extends PhoenixLoader { hitCollection.forEach((rawHit) => { const pos: edmPhoenix.Position = [ - rawHit.position?.x * 0.1, - rawHit.position?.y * 0.1, - rawHit.position?.z * 0.1, + rawHit.position.x * 0.1, + rawHit.position.y * 0.1, + rawHit.position.z * 0.1, ]; if ((rawHit.quality & (1 << 31)) !== 0) { @@ -391,9 +390,9 @@ export class Edm4hepJsonLoader extends PhoenixLoader { const cells: edmPhoenix.CaloCell[] = []; caloCellCollection.forEach((rawCell) => { - const x = rawCell.position?.x * 0.1; - const y = rawCell.position?.y * 0.1; - const z = rawCell.position?.z * 0.1; + const x = rawCell.position.x * 0.1; + const y = rawCell.position.y * 0.1; + const z = rawCell.position.z * 0.1; const rho = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); cells.push({ From 2a49ec3e464611a9429ed1c66cd928a714060676 Mon Sep 17 00:00:00 2001 From: pablo <74920898+apausa@users.noreply.github.com> Date: Thu, 12 Mar 2026 15:37:35 +0100 Subject: [PATCH 27/30] Refactor edm4hep json loader [Read more] Shared colors between tracks and hits Assign new Phoenix properties --- .../src/lib/types/edm4hep.ts | 12 +- .../src/lib/types/edmPhoenix.ts | 79 ---- .../src/loaders/edm4hep-json-loader.ts | 412 ++++++++++-------- 3 files changed, 237 insertions(+), 266 deletions(-) delete mode 100644 packages/phoenix-event-display/src/lib/types/edmPhoenix.ts diff --git a/packages/phoenix-event-display/src/lib/types/edm4hep.ts b/packages/phoenix-event-display/src/lib/types/edm4hep.ts index 6de093d19..9b8126b4b 100644 --- a/packages/phoenix-event-display/src/lib/types/edm4hep.ts +++ b/packages/phoenix-event-display/src/lib/types/edm4hep.ts @@ -32,9 +32,7 @@ export namespace edm4hep { | Schema6.Track ) & { // MUTATED PROPERTIES - color: string; pid: string; - pdgid: number; }; export type Hit = @@ -130,4 +128,14 @@ export namespace edm4hep { | Schema5.Coll | Schema6.Coll; }; + + export enum ParticleType { + Electron = 'electron', + Muon = 'muon', + Photon = 'photon', + Pion = 'pion', + Proton = 'proton', + Kaon = 'kaon', + Other = 'other', + } } diff --git a/packages/phoenix-event-display/src/lib/types/edmPhoenix.ts b/packages/phoenix-event-display/src/lib/types/edmPhoenix.ts deleted file mode 100644 index ab67dbf87..000000000 --- a/packages/phoenix-event-display/src/lib/types/edmPhoenix.ts +++ /dev/null @@ -1,79 +0,0 @@ -/* eslint-disable @typescript-eslint/no-namespace */ -export namespace edmPhoenix { - export type Position = [number, number, number]; - - export type Vertex = { - pos: Position; - color?: string; - }; - - export type Track = { - pos: Position; - color?: string; - d0?: number; - z0?: number; - phi?: number; - eta?: number; - qOverP?: number; - }; - - export type Hit = { - pos: Position; - type?: 'Point'; - color?: string; - }; - - export type CaloCell = { - energy: number; - phi: number; - eta: number; - }; - - export type CaloCluster = { - energy: number; - phi: number; - eta: number; - }; - - export type Jet = { - eta: number; - phi: number; - theta?: number; - energy?: number; - et?: number; - coneR?: number; - color?: string; - }; - - export type MissingEnergy = { - etx: number; - ety: number; - color?: string; - }; - - export type Event = { - 'event number'?: number; - 'run number'?: number; - Vertices?: { - [name: string]: Vertex[]; - }; - Tracks?: { - [name: string]: Track[]; - }; - Hits?: { - [name: string]: Hit[]; - }; - CaloCells?: { - [name: string]: CaloCell[]; - }; - CaloClusters?: { - [name: string]: CaloCluster[]; - }; - Jets?: { - [name: string]: Jet[]; - }; - MissingEnergy?: { - [name: string]: MissingEnergy[]; - }; - }; -} diff --git a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts index 2a4f761d7..ef04b8413 100644 --- a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts +++ b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts @@ -1,5 +1,14 @@ import { PhoenixLoader } from './phoenix-loader'; -import { edmPhoenix } from 'src/lib/types/edmPhoenix'; +import { + PhoenixEventData, + VertexParams, + TrackParams, + HitParams, + CaloCellParams, + CaloClusterParams, + JetParams, + MissingEnergyParams, +} from 'src/lib/types/event-data'; import { edm4hep } from 'src/lib/types/edm4hep'; import { ObjectID, Vector3d } from 'src/lib/types/edm4hep-schemas/utils'; @@ -7,6 +16,28 @@ import { ObjectID, Vector3d } from 'src/lib/types/edm4hep-schemas/utils'; * Edm4hepJsonLoader for loading EDM4hep json dumps */ export class Edm4hepJsonLoader extends PhoenixLoader { + /** PDG ID to particle type name */ + private static readonly pidNames: Record = { + 11: edm4hep.ParticleType.Electron, + 13: edm4hep.ParticleType.Muon, + 22: edm4hep.ParticleType.Photon, + 111: edm4hep.ParticleType.Pion, + 211: edm4hep.ParticleType.Pion, + 2212: edm4hep.ParticleType.Proton, + 321: edm4hep.ParticleType.Kaon, + }; + + /** Colors per particle type, shared between tracks and hits */ + private static readonly pidColors: Record = { + [edm4hep.ParticleType.Electron]: '#00ff00', + [edm4hep.ParticleType.Muon]: '#ff00ff', + [edm4hep.ParticleType.Photon]: '#ff0000', + [edm4hep.ParticleType.Pion]: '#a52a2a', + [edm4hep.ParticleType.Proton]: '#778899', + [edm4hep.ParticleType.Kaon]: '#5f9ea0', + [edm4hep.ParticleType.Other]: '#0000cd', + }; + /** Event data loaded from EDM4hep JSON file */ private rawEventData: any; @@ -23,11 +54,10 @@ export class Edm4hepJsonLoader extends PhoenixLoader { /** Process raw EDM4hep JSON event data into the Phoenix format */ processEventData(): boolean { - console.log('This is a test'); // Iterate over events Object.entries(this.rawEventData).forEach( ([eventName, rawEvent]: [string, edm4hep.Event]) => { - const newEvent: edmPhoenix.Event = { + const newEvent: PhoenixEventData = { 'event number': 0, 'run number': 0, Vertices: {}, @@ -119,76 +149,48 @@ export class Edm4hepJsonLoader extends PhoenixLoader { | edm4hep.Association[] // Schema 1 | edm4hep.Link[]; // From Schema 2 Onwards - if (!linkCollection) return; - const reconstructedParticleCollection = rawEvent.ReconstructedParticles ?.collection as edm4hep.ReconstructedParticle[]; - if (!reconstructedParticleCollection) return; - const mcParticleCollection = rawEvent.Particle ?.collection as edm4hep.MCParticle[]; - if (!mcParticleCollection) return; + const eFlowTrackCollection = rawEvent.EFlowTrack + ?.collection as edm4hep.Track[]; - const trackCollection = rawEvent.EFlowTrack?.collection as edm4hep.Track[]; - - if (!trackCollection) return; + if ( + linkCollection && + reconstructedParticleCollection && + mcParticleCollection && + eFlowTrackCollection + ) + return; linkCollection.forEach((link: edm4hep.Association | edm4hep.Link) => { const recIndex = 'rec' in link ? link.rec.index : link.from.index; const simIndex = 'sim' in link ? link.sim.index : link.to.index; const pdgid = mcParticleCollection[simIndex].PDG; - const trackRefs = reconstructedParticleCollection[recIndex].tracks; - - let color: string, pid: string; - - switch (Math.abs(pdgid)) { - case 11: - color = '#00ff00'; - pid = 'electron'; - break; - case 22: - color = '#ff0000'; - pid = 'photon'; - break; - case 111: - case 211: - color = '#a52a2a'; - pid = 'pion'; - break; - case 2212: - color = '#778899'; - pid = 'proton'; - break; - case 321: - color = '#5f9ea0'; - pid = 'kaon'; - break; - default: - color = '#0000cd'; - pid = 'other'; - } - trackRefs.forEach(({ index }) => { - const track = trackCollection[index]; - - track.color = color; - track.pid = pid; - track.pdgid = pdgid; + reconstructedParticleCollection[recIndex].tracks.forEach(({ index }) => { + eFlowTrackCollection[index].pid = + Edm4hepJsonLoader.pidNames[pdgid] ?? edm4hep.ParticleType.Other; }); }); } /** Return vertices */ - private getVertices(vertexCollection: edm4hep.Vertex[]): edmPhoenix.Vertex[] { - return vertexCollection.map((vertex: edm4hep.Vertex) => ({ + private getVertices(vertexCollection: edm4hep.Vertex[]): VertexParams[] { + const color = this.randomColor(); + + return vertexCollection.map((rawVertex: edm4hep.Vertex) => ({ pos: [ - vertex.position.x * 0.1, - vertex.position.y * 0.1, - vertex.position.z * 0.1, + rawVertex.position.x * 0.1, + rawVertex.position.y * 0.1, + rawVertex.position.z * 0.1, ], - color: this.randomColor(), + size: 1, + vertexType: 'type' in rawVertex ? rawVertex.type : null, + color, })); } @@ -196,98 +198,82 @@ export class Edm4hepJsonLoader extends PhoenixLoader { private getTracks( rawEvent: any, trackCollection: edm4hep.Track[], - ): [string, edmPhoenix.Track[]][] { - const categories: { [name: string]: edmPhoenix.Track[][] } = { - other: [], - electron: [], - photon: [], - pion: [], - proton: [], - kaon: [], - }; + ): [string, TrackParams[]][] { + const categories = Object.fromEntries( + Object.keys(Edm4hepJsonLoader.pidColors).map((type) => [ + type, + [] as TrackParams[], + ]), + ) as Record; trackCollection.forEach((rawTrack: edm4hep.Track) => { - const parsedHits: edmPhoenix.Track[] = []; + const pos: number[][] = []; // An array of positions is needed to render the tracks as bars if ('trackerHits' in rawTrack && rawTrack.trackerHits.length > 0) { rawTrack.trackerHits.forEach((trackerHitRef: ObjectID) => { - // @todo always assumes getCollById will return a collection const trackerHits: edm4hep.Hit[] = this.getCollByID( rawEvent, trackerHitRef.collectionID, ); - parsedHits.push({ - pos: [ - trackerHits[trackerHitRef.index].position.x * 0.1, - trackerHits[trackerHitRef.index].position.y * 0.1, - trackerHits[trackerHitRef.index].position.z * 0.1, - ], - color: rawTrack.color ?? '#0000cd', - }); + pos.push([ + trackerHits[trackerHitRef.index].position.x * 0.1, + trackerHits[trackerHitRef.index].position.y * 0.1, + trackerHits[trackerHitRef.index].position.z * 0.1, + ]); }); - } - - if ( - parsedHits.length === 0 && - 'trackStates' in rawTrack && - rawTrack.trackStates.length > 0 - ) { + } else { rawTrack.trackStates.forEach((trackState: edm4hep.TrackState) => { - // @todo 'trackState' might always be present - parsedHits.push({ - pos: [ - trackState.referencePoint.x * 0.1, - trackState.referencePoint.y * 0.1, - trackState.referencePoint.z * 0.1, - ], - color: rawTrack.color ?? '#0000cd', - }); + pos.push([ + trackState.referencePoint.x * 0.1, + trackState.referencePoint.y * 0.1, + trackState.referencePoint.z * 0.1, + ]); }); } - // @todo if none of those two properties exist definition will be invalid - const category = rawTrack.pid ?? 'other'; - categories[category].push(parsedHits); + categories[category].push({ + pos, + // @todo dparams (helix parameters for Runge-Kutta extrapolation: qOverP requires the magnetic field) + // @todo phi (aimuthal angle) + // @todo eta (peudorapidity) + // @todo d0 (tansverse impact parameter) + // @todo z0 (lngitudinal impact parameter) + // @todo pt (transverse momentum requires the magnetic field) + chi2: rawTrack.chi2, // no use by phoenix-object.ts + dof: rawTrack.ndf, // no use by phoenix-object.ts + color: Edm4hepJsonLoader.pidColors[rawTrack.pid ?? 'other'], + linewidth: 2, + }); }); - return Object.entries(categories) - .map(([label, category]): [string, edmPhoenix.Track[]] => [ - label, - category.flat(), - ]) - .filter(([, arr]) => arr.length !== 0); + return Object.entries(categories).filter(([, arr]) => arr.length !== 0) as [ + string, + TrackParams[], + ][]; } /** Return tracker hits */ private getHits( rawEvent: any, hitCollection: edm4hep.Hit[], - ): [string, edmPhoenix.Hit[]][] { - const categories: { [name: string]: edmPhoenix.Hit[] } = { - other: [], - overlay: [], - secondary: [], - electron: [], - muon: [], - pion: [], - kaon: [], - proton: [], - }; + ): [string, HitParams[]][] { + const categories = Object.fromEntries([ + ...Object.keys(Edm4hepJsonLoader.pidColors).map((type) => [ + type, + [] as HitParams[], + ]), + ['overlay', [] as HitParams[]], + ['secondary', [] as HitParams[]], + ]) as Record; - const colorOther = this.randomColor(); const colorOverlay = this.randomColor(); const colorSecondary = this.randomColor(); - const colorElectron = this.randomColor(); - const colorMuon = this.randomColor(); - const colorPion = this.randomColor(); - const colorKaon = this.randomColor(); - const colorProton = this.randomColor(); hitCollection.forEach((rawHit) => { - const pos: edmPhoenix.Position = [ + const pos: [number, number, number] = [ rawHit.position.x * 0.1, rawHit.position.y * 0.1, rawHit.position.z * 0.1, @@ -298,7 +284,7 @@ export class Edm4hepJsonLoader extends PhoenixLoader { * https://github.com/key4hep/EDM4hep/blob/fe5a54046a91a7e648d0b588960db7841aebc670/edm4hep.yaml#L349 */ categories.overlay.push({ - type: 'Point', + type: 'CircularPoint', pos, color: colorOverlay, }); @@ -307,7 +293,7 @@ export class Edm4hepJsonLoader extends PhoenixLoader { * https://github.com/key4hep/EDM4hep/blob/fe5a54046a91a7e648d0b588960db7841aebc670/edm4hep.yaml#L350 */ categories.secondary.push({ - type: 'Point', + type: 'CircularPoint', pos, color: colorSecondary, }); @@ -322,61 +308,20 @@ export class Edm4hepJsonLoader extends PhoenixLoader { ref = rawHit.MCParticle; } - if (ref !== null) { - const collection = this.getCollByID(rawEvent, ref.collectionID); - const pdg = Math.abs(collection?.[ref.index]?.PDG ?? 0); - - switch (pdg) { - case 11: - categories.electron.push({ - type: 'Point', - pos, - color: colorElectron, - }); - break; - case 13: - categories.muon.push({ - type: 'Point', - pos, - color: colorMuon, - }); - break; - case 211: - categories.pion.push({ - type: 'Point', - pos, - color: colorPion, - }); - break; - case 321: - categories.kaon.push({ - type: 'Point', - pos, - color: colorKaon, - }); - break; - case 2212: - categories.proton.push({ - type: 'Point', - pos, - color: colorProton, - }); - break; - default: - categories.other.push({ - type: 'Point', - pos, - color: colorOther, - }); - break; - } - } else { - categories.other.push({ - type: 'Point', - pos, - color: colorOther, - }); - } + const pdg = + ref !== null + ? (this.getCollByID(rawEvent, ref.collectionID)?.[ref.index]?.PDG ?? + null) + : null; + + const particleType = + Edm4hepJsonLoader.pidNames[pdg] ?? edm4hep.ParticleType.Other; + + categories[particleType].push({ + type: 'CircularPoint', + pos, + color: Edm4hepJsonLoader.pidColors[particleType], + }); } }); @@ -386,8 +331,39 @@ export class Edm4hepJsonLoader extends PhoenixLoader { /** Returns Calo cells */ private getCaloCells( caloCellCollection: edm4hep.CaloCell[], - ): edmPhoenix.CaloCell[] { - const cells: edmPhoenix.CaloCell[] = []; + ): CaloCellParams[] { + const cells: Omit[] = []; + const hue = Math.floor(Math.random() * 358); + + // 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() * caloCellCollection.length); + const k = Math.floor(Math.random() * caloCellCollection.length); + if (j === k) { + continue; + } + + const dx2 = Math.pow( + caloCellCollection[j].position.x - caloCellCollection[k].position.x, + 2, + ); + const dy2 = Math.pow( + caloCellCollection[j].position.y - caloCellCollection[k].position.y, + 2, + ); + const dz2 = Math.pow( + caloCellCollection[j].position.z - caloCellCollection[k].position.z, + 2, + ); + const dr = Math.sqrt(dx2 + dy2 + dz2); + + if (dr < drmin) { + drmin = dr; + } + } + + const side = Math.floor(drmin) * 0.1 > 1 ? Math.floor(drmin) * 0.1 : 1; caloCellCollection.forEach((rawCell) => { const x = rawCell.position.x * 0.1; @@ -399,17 +375,24 @@ export class Edm4hepJsonLoader extends PhoenixLoader { eta: rho === 0 ? 0 : Math.asinh(z / rho), // Check because '0 / 0 = NaN' phi: Math.atan2(y, x), // Safer equivalent to 'Math.acos(x / rho) * Math.sign(y)' energy: rawCell.energy, + radius: Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2)), + z, + color: this.convHSLtoHEX(hue, rawCell.energy), + opacity: this.valToOpacity(rawCell.energy, 1e-3, 1), + side: side, + length: side, // expecting cells in multiple layers }); }); - return cells; + return cells as CaloCellParams[]; } /** Return Calo clusters */ private getCaloClusters( caloClusterCollection: edm4hep.CaloCluster[], - ): edmPhoenix.CaloCluster[] { - const clusters: edmPhoenix.CaloCluster[] = []; + ): CaloClusterParams[] { + const clusters: CaloClusterParams[] = []; + const hue = Math.floor(Math.random() * 361); caloClusterCollection.forEach((rawCluster) => { const x = rawCluster.position.x * 0.1; @@ -421,6 +404,13 @@ export class Edm4hepJsonLoader extends PhoenixLoader { eta: rho === 0 ? 0 : Math.asinh(z / rho), // Check because '0 / 0 = NaN' phi: Math.atan2(y, x), // Safer equivalent to 'Math.acos(x / rho) * Math.sign(y)' energy: rawCluster.energy, + radius: Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2)), + z, + color: this.convHSLtoHEX(hue, rawCluster.energy), + theta: rawCluster.iTheta, + opacity: this.valToOpacity(rawCluster.energy, 1e-3, 1), + // side (overrides side width of the cluster box) + // length (overrides length (depth) of the cluster box) }); }); @@ -428,21 +418,29 @@ export class Edm4hepJsonLoader extends PhoenixLoader { } /** Return jets */ - private getJets( - jetCollection: edm4hep.ReconstructedParticle[], - ): edmPhoenix.Jet[] { - const jets: edmPhoenix.Jet[] = []; + private getJets(jetCollection: edm4hep.ReconstructedParticle[]): JetParams[] { + const jets: JetParams[] = []; + const hue = Math.floor(Math.random() * 358); jetCollection.forEach((rawJet) => { const px: number = rawJet.momentum.x; const py: number = rawJet.momentum.y; const pz: number = rawJet.momentum.z; + const p = Math.sqrt(px * px + py * py + pz * pz); const pt = Math.sqrt(Math.pow(px, 2) + Math.pow(py, 2)); + const eta = pt === 0 ? 0 : Math.asinh(pz / pt); jets.push({ - eta: pt === 0 ? 0 : Math.asinh(pz / pt), // Check because '0 / 0 = NaN' + eta, phi: Math.atan2(py, px), // Safer equivalent to 'Math.acos(px / pt) * Math.sign(py)' + theta: 2 * Math.atan(Math.exp(-eta)), energy: rawJet.energy, + et: p === 0 ? 0 : (rawJet.energy * pt) / p, + // coneR (overrides the cone radius for visualization width) + origin_X: rawJet.referencePoint.x, + origin_Y: rawJet.referencePoint.y, + origin_Z: rawJet.referencePoint.z, + color: this.convHSLtoHEX(hue, rawJet.energy), }); }); @@ -452,8 +450,8 @@ export class Edm4hepJsonLoader extends PhoenixLoader { /** Return missing energy */ private getMissingEnergy( missingEnergyCollection: edm4hep.ReconstructedParticle[], - ): edmPhoenix.MissingEnergy[] { - const missingEnergies: edmPhoenix.MissingEnergy[] = []; + ): MissingEnergyParams[] { + const missingEnergies: MissingEnergyParams[] = []; missingEnergyCollection.forEach((rawMissingEnergy: any) => { const px: number = rawMissingEnergy.momentum.x; @@ -462,7 +460,7 @@ export class Edm4hepJsonLoader extends PhoenixLoader { const p = Math.sqrt(Math.pow(px, 2) + Math.pow(py, 2) + Math.pow(pz, 2)); missingEnergies.push({ - etx: ((rawMissingEnergy.energy * px) / p) * 10, // @todo no apparent reason to multiply by 10 + etx: ((rawMissingEnergy.energy * px) / p) * 10, ety: ((rawMissingEnergy.energy * py) / p) * 10, color: '#ff69b4', }); @@ -484,4 +482,48 @@ export class Edm4hepJsonLoader extends PhoenixLoader { const coll = Object.values(event).find((c: any) => c?.collID === id) as any; return coll?.collection; } + + /** 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; + } + + /** Helper conversion of HSL to hexadecimal */ + private convHSLtoHEX(h: number, energy: number): string { + const s = Math.floor(Math.random() * 101); + const l = this.valToLightness(energy, 1e-3, 1) / 100; + + const a = (s * Math.min(l, 1 - l)) / 100; + + const f = (n: number) => { + 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)}`; + } } From aef5ebb919c69d607df7384d69a4e4e1b35c813c Mon Sep 17 00:00:00 2001 From: pablo <74920898+apausa@users.noreply.github.com> Date: Fri, 13 Mar 2026 13:43:24 +0100 Subject: [PATCH 28/30] Fix color assignment --- .../src/loaders/edm4hep-json-loader.ts | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts index ef04b8413..5c70faa3d 100644 --- a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts +++ b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts @@ -27,15 +27,16 @@ export class Edm4hepJsonLoader extends PhoenixLoader { 321: edm4hep.ParticleType.Kaon, }; - /** Colors per particle type, shared between tracks and hits */ + /** Colors per particle type, shared between tracks and hits + * Tracks receive hex color without '#' */ private static readonly pidColors: Record = { - [edm4hep.ParticleType.Electron]: '#00ff00', - [edm4hep.ParticleType.Muon]: '#ff00ff', - [edm4hep.ParticleType.Photon]: '#ff0000', - [edm4hep.ParticleType.Pion]: '#a52a2a', - [edm4hep.ParticleType.Proton]: '#778899', - [edm4hep.ParticleType.Kaon]: '#5f9ea0', - [edm4hep.ParticleType.Other]: '#0000cd', + [edm4hep.ParticleType.Electron]: '00ff00', + [edm4hep.ParticleType.Muon]: 'ff00ff', + [edm4hep.ParticleType.Photon]: 'ff0000', + [edm4hep.ParticleType.Pion]: 'a52a2a', + [edm4hep.ParticleType.Proton]: '778899', + [edm4hep.ParticleType.Kaon]: '5f9ea0', + [edm4hep.ParticleType.Other]: '0000cd', }; /** Event data loaded from EDM4hep JSON file */ @@ -244,7 +245,7 @@ export class Edm4hepJsonLoader extends PhoenixLoader { // @todo pt (transverse momentum requires the magnetic field) chi2: rawTrack.chi2, // no use by phoenix-object.ts dof: rawTrack.ndf, // no use by phoenix-object.ts - color: Edm4hepJsonLoader.pidColors[rawTrack.pid ?? 'other'], + color: Edm4hepJsonLoader.pidColors[rawTrack.pid ?? 'other'], // tracks reeceive hex color without '#' linewidth: 2, }); }); @@ -286,7 +287,7 @@ export class Edm4hepJsonLoader extends PhoenixLoader { categories.overlay.push({ type: 'CircularPoint', pos, - color: colorOverlay, + color: `#${colorOverlay}`, }); } else if ((rawHit.quality & (1 << 30)) !== 0) { /* BITProducedBySecondary = 30 @@ -295,7 +296,7 @@ export class Edm4hepJsonLoader extends PhoenixLoader { categories.secondary.push({ type: 'CircularPoint', pos, - color: colorSecondary, + color: `#${colorSecondary}`, }); } else { let ref: ObjectID | null = null; @@ -320,7 +321,7 @@ export class Edm4hepJsonLoader extends PhoenixLoader { categories[particleType].push({ type: 'CircularPoint', pos, - color: Edm4hepJsonLoader.pidColors[particleType], + color: `#${Edm4hepJsonLoader.pidColors[particleType]}`, }); } }); From 11a055003ef1d7cbb13dad2857ae706becf62aa8 Mon Sep 17 00:00:00 2001 From: pablo <74920898+apausa@users.noreply.github.com> Date: Fri, 13 Mar 2026 13:57:00 +0100 Subject: [PATCH 29/30] Fix bug --- .../src/loaders/edm4hep-json-loader.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts index 5c70faa3d..d41c8cf88 100644 --- a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts +++ b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts @@ -150,6 +150,8 @@ export class Edm4hepJsonLoader extends PhoenixLoader { | edm4hep.Association[] // Schema 1 | edm4hep.Link[]; // From Schema 2 Onwards + console.log(linkCollection); + const reconstructedParticleCollection = rawEvent.ReconstructedParticles ?.collection as edm4hep.ReconstructedParticle[]; @@ -160,17 +162,17 @@ export class Edm4hepJsonLoader extends PhoenixLoader { ?.collection as edm4hep.Track[]; if ( - linkCollection && - reconstructedParticleCollection && - mcParticleCollection && - eFlowTrackCollection + !linkCollection || + !reconstructedParticleCollection || + !mcParticleCollection || + !eFlowTrackCollection ) return; linkCollection.forEach((link: edm4hep.Association | edm4hep.Link) => { const recIndex = 'rec' in link ? link.rec.index : link.from.index; const simIndex = 'sim' in link ? link.sim.index : link.to.index; - const pdgid = mcParticleCollection[simIndex].PDG; + const pdgid = Math.abs(mcParticleCollection[simIndex].PDG); reconstructedParticleCollection[recIndex].tracks.forEach(({ index }) => { eFlowTrackCollection[index].pid = From e341fd065ca91016491f0eeb9fe251e5db8adcc0 Mon Sep 17 00:00:00 2001 From: pablo <74920898+apausa@users.noreply.github.com> Date: Fri, 13 Mar 2026 17:49:24 +0100 Subject: [PATCH 30/30] Debug refactor --- .../src/loaders/edm4hep-json-loader.ts | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts index d41c8cf88..93efd3b1f 100644 --- a/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts +++ b/packages/phoenix-event-display/src/loaders/edm4hep-json-loader.ts @@ -10,7 +10,7 @@ import { MissingEnergyParams, } from 'src/lib/types/event-data'; import { edm4hep } from 'src/lib/types/edm4hep'; -import { ObjectID, Vector3d } from 'src/lib/types/edm4hep-schemas/utils'; +import { ObjectID } from 'src/lib/types/edm4hep-schemas/utils'; /** * Edm4hepJsonLoader for loading EDM4hep json dumps @@ -150,8 +150,6 @@ export class Edm4hepJsonLoader extends PhoenixLoader { | edm4hep.Association[] // Schema 1 | edm4hep.Link[]; // From Schema 2 Onwards - console.log(linkCollection); - const reconstructedParticleCollection = rawEvent.ReconstructedParticles ?.collection as edm4hep.ReconstructedParticle[]; @@ -212,6 +210,7 @@ export class Edm4hepJsonLoader extends PhoenixLoader { trackCollection.forEach((rawTrack: edm4hep.Track) => { const pos: number[][] = []; // An array of positions is needed to render the tracks as bars + // @todo trackerhits might always exist if ('trackerHits' in rawTrack && rawTrack.trackerHits.length > 0) { rawTrack.trackerHits.forEach((trackerHitRef: ObjectID) => { const trackerHits: edm4hep.Hit[] = this.getCollByID( @@ -247,7 +246,7 @@ export class Edm4hepJsonLoader extends PhoenixLoader { // @todo pt (transverse momentum requires the magnetic field) chi2: rawTrack.chi2, // no use by phoenix-object.ts dof: rawTrack.ndf, // no use by phoenix-object.ts - color: Edm4hepJsonLoader.pidColors[rawTrack.pid ?? 'other'], // tracks reeceive hex color without '#' + color: Edm4hepJsonLoader.pidColors[rawTrack.pid ?? 'other'], // tracks receive hex color without '#' linewidth: 2, }); }); @@ -290,6 +289,7 @@ export class Edm4hepJsonLoader extends PhoenixLoader { type: 'CircularPoint', pos, color: `#${colorOverlay}`, + size: 2, }); } else if ((rawHit.quality & (1 << 30)) !== 0) { /* BITProducedBySecondary = 30 @@ -299,6 +299,7 @@ export class Edm4hepJsonLoader extends PhoenixLoader { type: 'CircularPoint', pos, color: `#${colorSecondary}`, + size: 2, }); } else { let ref: ObjectID | null = null; @@ -311,20 +312,21 @@ export class Edm4hepJsonLoader extends PhoenixLoader { ref = rawHit.MCParticle; } - const pdg = - ref !== null - ? (this.getCollByID(rawEvent, ref.collectionID)?.[ref.index]?.PDG ?? - null) - : null; + if (ref !== null) { + const pdg = + this.getCollByID(rawEvent, ref.collectionID)?.[ref.index]?.PDG ?? + null; - const particleType = - Edm4hepJsonLoader.pidNames[pdg] ?? edm4hep.ParticleType.Other; + const particleType = + Edm4hepJsonLoader.pidNames[pdg] ?? edm4hep.ParticleType.Other; - categories[particleType].push({ - type: 'CircularPoint', - pos, - color: `#${Edm4hepJsonLoader.pidColors[particleType]}`, - }); + categories[particleType].push({ + type: 'CircularPoint', + pos, + color: `#${Edm4hepJsonLoader.pidColors[particleType]}`, + size: 2, + }); + } } }); @@ -406,13 +408,13 @@ export class Edm4hepJsonLoader extends PhoenixLoader { clusters.push({ eta: rho === 0 ? 0 : Math.asinh(z / rho), // Check because '0 / 0 = NaN' phi: Math.atan2(y, x), // Safer equivalent to 'Math.acos(x / rho) * Math.sign(y)' - energy: rawCluster.energy, + energy: rawCluster.energy * 100, // @todo more energy -> smaller porportion. by why 100 specifically? radius: Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2)), z, color: this.convHSLtoHEX(hue, rawCluster.energy), - theta: rawCluster.iTheta, + theta: Math.atan2(rho, z), opacity: this.valToOpacity(rawCluster.energy, 1e-3, 1), - // side (overrides side width of the cluster box) + side: 4, // (overrides side width of the cluster box) // length (overrides length (depth) of the cluster box) }); }); @@ -437,7 +439,7 @@ export class Edm4hepJsonLoader extends PhoenixLoader { eta, phi: Math.atan2(py, px), // Safer equivalent to 'Math.acos(px / pt) * Math.sign(py)' theta: 2 * Math.atan(Math.exp(-eta)), - energy: rawJet.energy, + energy: rawJet.energy * 1000, et: p === 0 ? 0 : (rawJet.energy * pt) / p, // coneR (overrides the cone radius for visualization width) origin_X: rawJet.referencePoint.x,