From 3cfbb4c9162354ca9274a7397a7b04f821b02ca8 Mon Sep 17 00:00:00 2001 From: Braulio Rivas Abad Date: Wed, 29 May 2024 18:12:34 -0500 Subject: [PATCH 01/35] create initial types of collections defined in gsoc --- js/types/Cluster.js | 17 +++++++++++++++++ js/types/ParticleID.js | 10 ++++++++++ js/types/RecoParticle.js | 17 +++++++++++++++++ js/types/Track.js | 15 +++++++++++++++ js/types/Vertex.js | 13 +++++++++++++ 5 files changed, 72 insertions(+) create mode 100644 js/types/Cluster.js create mode 100644 js/types/ParticleID.js create mode 100644 js/types/RecoParticle.js create mode 100644 js/types/Track.js create mode 100644 js/types/Vertex.js diff --git a/js/types/Cluster.js b/js/types/Cluster.js new file mode 100644 index 00000000..a1d842aa --- /dev/null +++ b/js/types/Cluster.js @@ -0,0 +1,17 @@ +export class Cluster { + constructor() { + // Physics properties + this.type = 0; + this.energy = 0; // GeV + this.energyError = 0; // GeV + this.position = []; // mm + this.positionError = []; + this.iTheta = 0; + this.phi = 0; + this.directionError; // mm^2 + this.shapeParameters = []; + this.subdetectorEnergies = []; + this.clusters = []; + this.hits = []; + } +} diff --git a/js/types/ParticleID.js b/js/types/ParticleID.js new file mode 100644 index 00000000..69f5e890 --- /dev/null +++ b/js/types/ParticleID.js @@ -0,0 +1,10 @@ +export class ParticleID { + constructor() { + // Physics properties + this.type = 0; + this.pdg = 0; + this.algorithmType = 0; + this.likelihood = 0; + this.parameters = []; + } +} diff --git a/js/types/RecoParticle.js b/js/types/RecoParticle.js new file mode 100644 index 00000000..4f68b320 --- /dev/null +++ b/js/types/RecoParticle.js @@ -0,0 +1,17 @@ +export class ReconstructedParticle { + constructor() { + // Physics properties + this.pdg = 0; + this.energy = 0; // GeV + this.momentum = 0; // GeV + this.referencePoint = 0; // mm + this.charge = 0; + this.mass = 0; // GeV + this.goodnessOfPID = 0; + this.covMatrix = []; + this.startVertex = []; + this.clusters = []; + this.tracks = []; + this.particles = []; + } +} diff --git a/js/types/Track.js b/js/types/Track.js new file mode 100644 index 00000000..5a910826 --- /dev/null +++ b/js/types/Track.js @@ -0,0 +1,15 @@ +export class Track { + constructor() { + // Physics properties + this.type = 0; + this.chi2 = 0; + this.ndf = 0; + this.dEdx = 0; + this.dEdxError = 0; + this.radiusOfInnermostHit = 0; + this.subdetectorHitNumbers = []; + this.dxQuantities = []; + this.trackerHits = []; + this.tracks = []; + } +} diff --git a/js/types/Vertex.js b/js/types/Vertex.js new file mode 100644 index 00000000..d954723c --- /dev/null +++ b/js/types/Vertex.js @@ -0,0 +1,13 @@ +export class Vertex { + constructor() { + // Physics properties + this.primary = 0; + this.chi2 = 0; + this.probability = 0; + this.position = 0; // mm + this.covMatrix = []; + this.algorithmType = 0; + this.parameters = 0; + this.associatedParticles = []; + } +} From 186024e23eef19fd182a158b06a535daf26c4081 Mon Sep 17 00:00:00 2001 From: Braulio Rivas Abad Date: Thu, 30 May 2024 20:38:12 -0500 Subject: [PATCH 02/35] loading function to check if types are correctly working --- js/types/Cluster.js | 17 ---- js/types/ParticleID.js | 10 --- js/types/RecoParticle.js | 17 ---- js/types/Track.js | 15 ---- js/types/Vertex.js | 13 --- js/types/load.js | 62 +++++++++++++ js/types/reconstruction.js | 175 +++++++++++++++++++++++++++++++++++++ 7 files changed, 237 insertions(+), 72 deletions(-) delete mode 100644 js/types/Cluster.js delete mode 100644 js/types/ParticleID.js delete mode 100644 js/types/RecoParticle.js delete mode 100644 js/types/Track.js delete mode 100644 js/types/Vertex.js create mode 100644 js/types/load.js create mode 100644 js/types/reconstruction.js diff --git a/js/types/Cluster.js b/js/types/Cluster.js deleted file mode 100644 index a1d842aa..00000000 --- a/js/types/Cluster.js +++ /dev/null @@ -1,17 +0,0 @@ -export class Cluster { - constructor() { - // Physics properties - this.type = 0; - this.energy = 0; // GeV - this.energyError = 0; // GeV - this.position = []; // mm - this.positionError = []; - this.iTheta = 0; - this.phi = 0; - this.directionError; // mm^2 - this.shapeParameters = []; - this.subdetectorEnergies = []; - this.clusters = []; - this.hits = []; - } -} diff --git a/js/types/ParticleID.js b/js/types/ParticleID.js deleted file mode 100644 index 69f5e890..00000000 --- a/js/types/ParticleID.js +++ /dev/null @@ -1,10 +0,0 @@ -export class ParticleID { - constructor() { - // Physics properties - this.type = 0; - this.pdg = 0; - this.algorithmType = 0; - this.likelihood = 0; - this.parameters = []; - } -} diff --git a/js/types/RecoParticle.js b/js/types/RecoParticle.js deleted file mode 100644 index 4f68b320..00000000 --- a/js/types/RecoParticle.js +++ /dev/null @@ -1,17 +0,0 @@ -export class ReconstructedParticle { - constructor() { - // Physics properties - this.pdg = 0; - this.energy = 0; // GeV - this.momentum = 0; // GeV - this.referencePoint = 0; // mm - this.charge = 0; - this.mass = 0; // GeV - this.goodnessOfPID = 0; - this.covMatrix = []; - this.startVertex = []; - this.clusters = []; - this.tracks = []; - this.particles = []; - } -} diff --git a/js/types/Track.js b/js/types/Track.js deleted file mode 100644 index 5a910826..00000000 --- a/js/types/Track.js +++ /dev/null @@ -1,15 +0,0 @@ -export class Track { - constructor() { - // Physics properties - this.type = 0; - this.chi2 = 0; - this.ndf = 0; - this.dEdx = 0; - this.dEdxError = 0; - this.radiusOfInnermostHit = 0; - this.subdetectorHitNumbers = []; - this.dxQuantities = []; - this.trackerHits = []; - this.tracks = []; - } -} diff --git a/js/types/Vertex.js b/js/types/Vertex.js deleted file mode 100644 index d954723c..00000000 --- a/js/types/Vertex.js +++ /dev/null @@ -1,13 +0,0 @@ -export class Vertex { - constructor() { - // Physics properties - this.primary = 0; - this.chi2 = 0; - this.probability = 0; - this.position = 0; // mm - this.covMatrix = []; - this.algorithmType = 0; - this.parameters = 0; - this.associatedParticles = []; - } -} diff --git a/js/types/load.js b/js/types/load.js new file mode 100644 index 00000000..7c88b530 --- /dev/null +++ b/js/types/load.js @@ -0,0 +1,62 @@ +import jsonData from "../../input/p8_ee_ZH_ecm240_edm4hep.edm4hep.json" assert { type: "json" }; // node 20 +import { + Cluster, + ParticleID, + ReconstructedParticle, + Vertex, + Track, +} from "./reconstruction.js"; + +const loaders = { + ReconstructedParticle: ReconstructedParticle.load, + ParticleID: ParticleID.load, + Vertex: Vertex.load, + Track: Track.load, + Cluster: Cluster.load, +}; + +const loadersConfig = [ + "ReconstructedParticle", + "ParticleID", + "Vertex", + "Track", + "Cluster", +]; + +function selectedParticles(loaders, particles) { + let newLoader = {}; + + for (const particle of particles) { + if (loaders.hasOwnProperty(particle)) { + newLoader[particle] = loaders[particle]; + } + } + + return newLoader; +} + +export function loadParticles(event, loadersConfig) { + const eventData = Object.values(jsonData["Event " + event]); + + const particles = []; + + const loader = selectedParticles(loaders, loadersConfig); + + for (const [type, loadFunction] of Object.entries(loader)) { + const particlesType = eventData.filter( + (element) => element.collType === `edm4hep::${type}Collection` + ); + + particlesType.forEach((collection) => { + const loadedParticles = loadFunction(collection.collection); + }); + } + try { + } catch (error) { + console.error(error); + } + + return particles; +} + +loadParticles(4, loadersConfig); diff --git a/js/types/reconstruction.js b/js/types/reconstruction.js new file mode 100644 index 00000000..f072440f --- /dev/null +++ b/js/types/reconstruction.js @@ -0,0 +1,175 @@ +export class Cluster { + constructor() { + // Physics properties + this.type = 0; + this.energy = 0; // GeV + this.energyError = 0; // GeV + this.position = []; // mm + this.positionError = []; + this.iTheta = 0; + this.phi = 0; + this.directionError = {}; // mm^2 + this.shapeParameters = []; + this.subdetectorEnergies = []; + this.clusters = []; + this.hits = []; + } + + static load(collection) { + const particles = []; + + for (const [index, particle] of collection.entries()) { + const cluster = new Cluster(); + cluster.index = index; + + cluster.type = particle.type; + cluster.energy = particle.energy; + cluster.energyError = particle.energyError; + cluster.position = particle.position; + cluster.positionError = particle.positionError; + cluster.iTheta = particle.iTheta; + cluster.phi = particle.phi; + cluster.directionError = particle.directionError; + cluster.shapeParameters = particle.shapeParameters; + cluster.subdetectorEnergies = particle.subdetectorEnergies; + cluster.clusters = particle.clusters; + cluster.hits = particle.hits; + + particles.push(cluster); + } + + return particles; + } +} + +export class ParticleID { + constructor() { + // Physics properties + this.type = 0; + this.pdg = 0; + this.algorithmType = 0; + this.likelihood = 0; + this.parameters = []; + this.particle = []; + } + + static load(collection) { + const particles = []; + + for (const [index, particle] of collection.entries()) { + const particleID = new ParticleID(); + particleID.index = index; + + particleID.type = particle.type; + particleID.pdg = particle.pdg; + particleID.algorithmType = particle.algorithmType; + particleID.likelihood = particle.likelihood; + particleID.parameters = particle.parameters; + + particles.push(particleID); + } + + return particles; + } +} + +export class ReconstructedParticle { + constructor() { + // Physics properties + this.pdg = 0; + this.energy = 0; // GeV + this.momentum = {}; // GeV + this.referencePoint = {}; // mm + this.charge = 0; + this.mass = 0; // GeV + this.goodnessOfPID = 0; + this.covMatrix = []; + this.startVertex = {}; + this.clusters = []; + this.tracks = []; + this.particles = []; + } + + static load(collection) { + const particles = []; + + for (const [index, particle] of collection.entries()) { + const reconstructedParticle = new ReconstructedParticle(); + reconstructedParticle.index = index; + + reconstructedParticle.energy = particle.energy; + reconstructedParticle.momentum = particle.momentum; + reconstructedParticle.referencePoint = particle.referencePoint; + reconstructedParticle.charge = particle.charge; + reconstructedParticle.mass = particle.mass; + reconstructedParticle.goodnessOfPID = particle.goodnessOfPID; + reconstructedParticle.covMatrix = particle.covMatrix; + reconstructedParticle.startVertex = particle.startVertex; + reconstructedParticle.clusters = particle.clusters; + reconstructedParticle.tracks = particle.tracks; + reconstructedParticle.particles = particle.particles; + + particles.push(reconstructedParticle); + } + + return particles; + } +} + +export class Vertex { + constructor() { + // Physics properties + this.primary = 0; + this.chi2 = 0; + this.probability = 0; + this.position = 0; // mm + this.covMatrix = []; + this.algorithmType = 0; + this.parameters = 0; + this.associatedParticles = []; + } + + static load() {} +} + +export class Track { + constructor() { + // Physics properties + this.type = 0; + this.chi2 = 0; + this.ndf = 0; + this.dEdx = 0; + this.dEdxError = 0; + this.radiusOfInnermostHit = 0; + this.subdetectorHitNumbers = []; + this.trackStates = []; + this.dxQuantities = []; + this.trackerHits = []; + this.tracks = []; + } + + static load(collection) { + const particles = []; + + for (const [index, particle] of collection.entries()) { + const track = new Track(); + track.index = index; + + track.type = particle.type; + track.chi2 = particle.chi2; + track.ndf = particle.ndf; + track.dEdx = particle.dEdx; + track.dEdxError = particle.dEdxError; + track.radiusOfInnermostHit = particle.radiusOfInnermostHit; + track.subdetectorHitNumbers = particle.subdetectorHitNumbers; + track.trackStates = particle.trackStates; + track.dxQuantities = particle.dxQuantities; + track.trackerHits = particle.trackerHits; + track.tracks = particle.tracks; + + particles.push(track); + } + + return particles; + } +} From fbfb0eaa80b4af4b04ef24fad8d3e60c3f49c93e Mon Sep 17 00:00:00 2001 From: Braulio Rivas Abad Date: Thu, 30 May 2024 21:58:12 -0500 Subject: [PATCH 03/35] test suite for loadParticles and buildLoader --- js/types/load.js | 33 ++++++++++++++------ test/load.test.js | 77 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 9 deletions(-) create mode 100644 test/load.test.js diff --git a/js/types/load.js b/js/types/load.js index 7c88b530..90abdda7 100644 --- a/js/types/load.js +++ b/js/types/load.js @@ -23,32 +23,47 @@ const loadersConfig = [ "Cluster", ]; -function selectedParticles(loaders, particles) { - let newLoader = {}; +export function buildLoader(config) { + let newLoader = { + types: {}, + getLoader: (name) => { + if (newLoader.types.hasOwnProperty(name)) { + return newLoader.types[name]; + } + return false; + }, + getAllLoaders: () => { + return newLoader.types; + }, + }; - for (const particle of particles) { + for (const particle of config) { if (loaders.hasOwnProperty(particle)) { - newLoader[particle] = loaders[particle]; + newLoader.types[particle] = loaders[particle]; } } return newLoader; } -export function loadParticles(event, loadersConfig) { +export function loadParticles(jsonData, event, loadersConfig) { const eventData = Object.values(jsonData["Event " + event]); - const particles = []; + const particles = {}; - const loader = selectedParticles(loaders, loadersConfig); + if (typeof loadersConfig === "string") loadersConfig = [loadersConfig]; + const loader = buildLoader(loadersConfig); - for (const [type, loadFunction] of Object.entries(loader)) { + Object.keys(loader.getAllLoaders()).forEach((key) => (particles[key] = [])); + + for (const [type, loadFunction] of Object.entries(loader.getAllLoaders())) { const particlesType = eventData.filter( (element) => element.collType === `edm4hep::${type}Collection` ); particlesType.forEach((collection) => { const loadedParticles = loadFunction(collection.collection); + particles[type] = loadedParticles; }); } try { @@ -59,4 +74,4 @@ export function loadParticles(event, loadersConfig) { return particles; } -loadParticles(4, loadersConfig); +loadParticles(jsonData, 4, loadersConfig); diff --git a/test/load.test.js b/test/load.test.js new file mode 100644 index 00000000..8dc5e19f --- /dev/null +++ b/test/load.test.js @@ -0,0 +1,77 @@ +import { buildLoader, loadParticles } from "../js/types/load"; + +const data = { + "Event 0": { + "AllMuon": { + "collID": 12, + "collType": "edm4hep::ReconstructedParticleCollection", + "collection": [], + }, + "EFlowPhoton": { + "collID": 7, + "collType": "edm4hep::ClusterCollection", + "collection": [ + { + "clusters": [], + "directionError": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + }, + "energy": 6.2020978927612305, + "energyError": 0.0, + "hits": [], + "iTheta": 0.0, + "particleIDs": [], + "phi": 0.0, + "position": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + }, + "positionError": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + "shapeParameters": [], + "subdetectorEnergies": [], + "type": 0, + }, + ], + }, + }, +}; + +describe("build loader", () => { + it("should create a loader with a set of types", () => { + const loadersConfig = ["ReconstructedParticle", "ParticleID"]; + const loader = buildLoader(loadersConfig); + const loaderFunctions = loadersConfig.map((type) => loader.getLoader(type)); + + expect(loaderFunctions.every((f) => typeof f === "function")).toBe(true); + }); + + it("should fail when requesting a loader that doesn't exist", () => { + const loadersConfig = ["ReconstructedParticle", "ParticleID"]; + const loader = buildLoader(loadersConfig); + + expect(loader.getLoader("Vertex")).toBe(false); + }); +}); + +describe("load different types of particles", () => { + it("should only load particles of one type", () => { + const loadersConfig = "ReconstructedParticle"; + + const particles = loadParticles(data, "0", loadersConfig); + + expect(particles.hasOwnProperty(loadersConfig)).toBe(true); + }); + + it("should load particles of multiple types", () => { + const loadersConfig = ["ReconstructedParticle", "Cluster"]; + + const particles = loadParticles(data, "0", loadersConfig); + + expect(loadersConfig.every((type) => particles.hasOwnProperty(type))).toBe( + true + ); + }); +}); From c7b270cd9ee21dc9fd41e1580fc0bc8624f1d559 Mon Sep 17 00:00:00 2001 From: Braulio Rivas Abad Date: Fri, 31 May 2024 08:46:39 -0500 Subject: [PATCH 04/35] change example data for RecoParticle test --- test/load.test.js | 71 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 5 deletions(-) diff --git a/test/load.test.js b/test/load.test.js index 8dc5e19f..d6183b19 100644 --- a/test/load.test.js +++ b/test/load.test.js @@ -2,11 +2,6 @@ import { buildLoader, loadParticles } from "../js/types/load"; const data = { "Event 0": { - "AllMuon": { - "collID": 12, - "collType": "edm4hep::ReconstructedParticleCollection", - "collection": [], - }, "EFlowPhoton": { "collID": 7, "collType": "edm4hep::ClusterCollection", @@ -36,6 +31,72 @@ const data = { }, ], }, + "Jet": { + "collID": 13, + "collType": "edm4hep::ReconstructedParticleCollection", + "collection": [ + { + "charge": 1.0, + "clusters": [], + "covMatrix": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + "energy": 12.062528610229492, + "goodnessOfPID": 0.0, + "mass": 2.315242290496826, + "momentum": { + "x": 11.738886833190918, + "y": 1.2114704847335815, + "z": 0.9354811906814575, + }, + "particleIDUsed": { + "collectionID": -2, + "index": -2, + }, + "particleIDs": [ + { + "collectionID": 4, + "index": 45, + }, + ], + "particles": [ + { + "collectionID": 14, + "index": 24, + }, + { + "collectionID": 14, + "index": 22, + }, + { + "collectionID": 14, + "index": 74, + }, + { + "collectionID": 14, + "index": 23, + }, + { + "collectionID": 14, + "index": 25, + }, + { + "collectionID": 14, + "index": 26, + }, + ], + "referencePoint": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + }, + "startVertex": { + "collectionID": -2, + "index": -2, + }, + "tracks": [], + "type": 0, + }, + ], + }, }, }; From 27d03eca6e1cb7f16d90fc90eab84f0559f9685c Mon Sep 17 00:00:00 2001 From: Braulio Rivas Abad Date: Fri, 31 May 2024 10:35:03 -0500 Subject: [PATCH 05/35] check if previews work --- index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 450c5126..b320acd8 100644 --- a/index.html +++ b/index.html @@ -17,9 +17,9 @@