Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load particles according to edm4hep #36

Merged
merged 39 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
3cfbb4c
create initial types of collections defined in gsoc
brauliorivas May 29, 2024
186024e
loading function to check if types are correctly working
brauliorivas May 31, 2024
fbfb0ea
test suite for loadParticles and buildLoader
brauliorivas May 31, 2024
c7b270c
change example data for RecoParticle test
brauliorivas May 31, 2024
170de18
Merge branch 'main' into new-types
brauliorivas May 31, 2024
27d03ec
check if previews work
brauliorivas May 31, 2024
0a52737
small change
brauliorivas May 31, 2024
02392eb
another small change
brauliorivas May 31, 2024
13978a4
remove unnecessary exclamation mark
brauliorivas Jun 2, 2024
5f48b1d
eliminate try catch
brauliorivas Jun 3, 2024
00bb203
add version check + dynamic load of object
brauliorivas Jun 3, 2024
83a9bbd
update tests
brauliorivas Jun 3, 2024
3e64c41
types for RecoParticle relations including 1:1 and 1:many
brauliorivas Jun 4, 2024
f7a14c5
add links for types
brauliorivas Jun 5, 2024
904cd51
test for loading functions
brauliorivas Jun 6, 2024
ba9630c
test reconstruction
brauliorivas Jun 6, 2024
69f3fd6
remove a few things
brauliorivas Jun 7, 2024
a1afbfe
extract up-to-date types from edm4hep
brauliorivas Jun 9, 2024
1715a04
Merge branch 'new-types' into dynamic-types
brauliorivas Jun 9, 2024
cc58efa
load particles according to edm4hep.yaml definition
brauliorivas Jun 9, 2024
49d5e6e
improvements (advised) and create test a better test suite
brauliorivas Jun 10, 2024
0e30a99
add documentation to update-on-demand for dmx
brauliorivas Jun 11, 2024
1ff80b6
renaming from particle -> object
brauliorivas Jun 11, 2024
9ba9506
drop types for datatypes
brauliorivas Jun 11, 2024
57348db
correct file naming
brauliorivas Jun 11, 2024
c2b0742
typo in MODEl.md
brauliorivas Jun 12, 2024
c0c7387
Merge branch 'main' into dynamic-types
brauliorivas Jun 12, 2024
8e83913
Merge branch 'dynamic-types' of github.com:brauliorivas/dmx into dyna…
brauliorivas Jun 12, 2024
8e82181
[WIP] setup loading to later draw MCParticles
brauliorivas Jun 13, 2024
27ba065
fix typos in MODEL.md
brauliorivas Jun 13, 2024
e82ba4c
implement @tmadlener random color generator
brauliorivas Jun 13, 2024
9c0ee0a
minimal drawing for MCParticle
brauliorivas Jun 13, 2024
cd53b06
good working drawing
brauliorivas Jun 13, 2024
aeb04e2
dmx works with new loading functionality
brauliorivas Jun 13, 2024
fc45409
dmx completely using new loading function
brauliorivas Jun 14, 2024
bb0bc73
remove old files + fix filter function + fix lib
brauliorivas Jun 14, 2024
26597ee
new loading is done. [WIP] new test suite
brauliorivas Jun 14, 2024
0c1538b
add very basic tests for new loading logic
brauliorivas Jun 15, 2024
c37b2f3
check for correct object loading and links when reading a json file f…
brauliorivas Jun 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion js/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export function loadMCParticles(jsonData, eventNum, particlesHandler) {
}
}

function getName(pdg) {
export function getName(pdg) {
const particle = mappings[pdg];

if (particle !== undefined) {
Expand Down
55 changes: 55 additions & 0 deletions js/types/dynamic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Link, colors } from "./links.js";

export function loadMembers(object, data, membersToLoad) {
for (const member of membersToLoad) {
if (data[member.name] === undefined) continue; // load up to date data
tmadlener marked this conversation as resolved.
Show resolved Hide resolved
object.members[member.name] = data[member.name];
}
}

export function loadOneToOneRelations(
object,
data,
relationsToLoad = [],
oneToOne,
objects
) {
object.oneToOneRelations = {};
for (const relation of relationsToLoad) {
const name = relation.name;
const relationData = data[name];
if (relationData === undefined) continue;

const toObject = objects[relationData.index];
const link = new Link(object, toObject);
link.color = colors[name];

oneToOne[name].push(link);
object.oneToOneRelations[name] = link;
}
}

export function loadOneToManyRelations(
object,
data,
relationsToLoad = [],
oneToMany,
objects
) {
object.oneToManyRelations = {};
for (const relation of relationsToLoad) {
const name = relation.name;
const relationData = data[name];

if (relationData === undefined) continue;
object.oneToManyRelations[name] = [];

for (const relationElement of relationData) {
const toObject = objects[relationElement.index];
const link = new Link(object, toObject);
link.color = colors[name];
oneToMany[name].push(link);
object.oneToManyRelations[name].push(link);
}
}
}
9 changes: 9 additions & 0 deletions js/types/edmobject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export class EDMObject {
constructor(id) {
this.id = id;
this.members = {};
}

draw() {}
// more methods common to all particles
}
143 changes: 143 additions & 0 deletions js/types/links.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
export const colors = {
"daughters": "#00AA00",
"parents": "#AA0000",
// more if needed
};

const hexCharacters = [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
"A",
"B",
"C",
"D",
"E",
"F",
];

function getCharacter(index) {
return hexCharacters[index];
}

export function generateRandomColor() {
let hexColorRep = "#";

for (let index = 0; index < 6; index++) {
const randomPosition = Math.floor(Math.random() * hexCharacters.length);
hexColorRep += getCharacter(randomPosition);
}

return hexColorRep;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this could be done simpler without having to 6 times

  • generate a random number
  • append to a string

Depending on how tight the loop is that you will be calling this might become a bit too expensive. It is possible to achieve the same thing via:

"#'"+ (0xffffff * Math.random() << 0).toString(16).padStart(6, "0")

where we mainly leverage the fact that toString takes a base to convert to a string representation. The << 0 is mainly there to "cut off" the decimal places.


export class Link {
// we may create a specific class for each type if needed
constructor(from, to) {
this.from = from;
this.to = to;
this.color = "#A00";
this.xShift = 0;
}

draw(ctx, infoBoxes) {
const boxFrom = infoBoxes[this.from];
const boxTo = infoBoxes[this.to];

const fromX = boxFrom.x + boxFrom.width / 2;
const fromY = boxFrom.y + boxFrom.height;
const toX = boxTo.x + boxTo.width / 2;
const toY = boxTo.y;

if (toY > fromY) {
var cpFromY = (toY - fromY) / 2 + fromY;
var cpToY = cpFromY;
} else {
cpFromY = (fromY - toY) / 2 + fromY;
cpToY = toY - (fromY - toY) / 2;
}

if (toX > fromX) {
var cpFromX = (toX - fromX) / 4 + fromX;
var cpToX = (3 * (toX - fromX)) / 4 + fromX;
} else {
cpFromX = (3 * (fromX - toX)) / 4 + toX;
cpToX = (fromX - toX) / 4 + toX;
}

/*
drawCross(ctx, fromX, fromY, "blue");
drawCross(ctx, toX, toY, "green");
drawCross(ctx, cpFromX, cpFromY, "yellow");
drawLine(ctx, fromX, fromY, cpFromX, cpFromY, "yellow")
drawCross(ctx, cpToX, cpToY, "orange");
drawLine(ctx, toX, toY, cpToX, cpToY, "orange")
*/

ctx.save();
ctx.strokeStyle = this.color;
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(fromX + this.xShift, fromY);
ctx.bezierCurveTo(
cpFromX + this.xShift,
cpFromY,
cpToX + this.xShift,
cpToY,
toX + this.xShift,
toY
);
ctx.stroke();
ctx.restore();

/*
ctx.save();
ctx.font = "14px sans-serif";
ctx.fillStyle = this.color;
const idText = "ID: " + this.id;
ctx.fillText(idText,
cpToX, cpToY);
ctx.restore();
*/
}

isVisible(x, y, width, height, infoBoxes) {
const boxFrom = infoBoxes[this.from];
const boxTo = infoBoxes[this.to];

const fromX = boxFrom.x + boxFrom.width / 2;
const fromY = boxFrom.y + boxFrom.height;
const toX = boxTo.x + boxTo.width / 2;
const toY = boxTo.y;

const boxX = Math.min(fromX, toX);
const boxWidth = Math.abs(fromX - toX);
const boxY = Math.min(fromY, toY);
const boxHeight = Math.abs(fromY - toY);

/*
console.log("boxX: ", this.boxX);
console.log("boxY: ", this.boxY);
console.log("boxWidth: ", this.boxWidth);
console.log("boxHeight: ", this.boxHeight);
*/

return (
x + width > boxX &&
x < boxX + boxWidth &&
y + height > boxY &&
y < boxY + boxHeight
);
}
}

export function createLink(id, from, { collectionID, index }) {
return new Link(id, from, index, collectionID);
}
99 changes: 99 additions & 0 deletions js/types/load.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { objectTypes } from "./objects.js";
import { datatypes } from "../../output/datatypes.js";
import {
loadMembers,
loadOneToOneRelations,
loadOneToManyRelations,
} from "./dynamic.js";
import { generateRandomColor, colors } from "./links.js";
import json from "../../input/p8_ee_ZH_ecm240_edm4hep.edm4hep.json" assert { type: "json" };

export function loadObjectType(collection, datatype, type) {
const objects = [];
let oneToOne = {};
if (datatype.oneToOneRelations)
datatype.oneToOneRelations.forEach((relation) => {
oneToOne[relation.name] = [];
if (colors[relation.name] === undefined) {
colors[relation.name] = generateRandomColor();
}
});

let oneToMany = {};
if (datatype.oneToManyRelations)
datatype.oneToManyRelations.forEach((relation) => {
oneToMany[relation.name] = [];
if (colors[relation.name] === undefined) {
colors[relation.name] = generateRandomColor();
}
});

for (const [index, particle] of collection.entries()) {
const newObject = new type(index);

loadMembers(newObject, particle, datatype.members);

loadOneToOneRelations(
newObject,
particle,
datatype.oneToOneRelations,
oneToOne,
objects
);

loadOneToManyRelations(
newObject,
particle,
datatype.oneToManyRelations,
oneToMany,
objects
);

objects.push(newObject);
}

return [objects, oneToOne, oneToMany];
}

export function loadObjects(jsonData, event, objectsToLoad) {
const eventData = jsonData["Event " + event];

const objects = {};

for (const type of objectsToLoad) {
let collectionType = Object.values(eventData).filter(
(element) => element.collType === `${type}Collection`
);

collectionType = collectionType.map((coll) => coll.collection);
collectionType = collectionType.flat();

const [loadedCollection, oneToOne, oneToMany] = loadObjectType(
collectionType,
datatypes[type],
objectTypes[type]
);

objects[type] = {
collection: loadedCollection,
oneToMany: oneToMany,
oneToOne: oneToOne,
};
}

return objects;
}

const objectsToLoad = [
// subset of datatypes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am missing the edm4hep::MCParticle here (or I am missing something entirely?). It should be possible to load that through the same mechanism, right? That would also serve as a good "real world" test to see whether the scheme works to get to a useful representation in memory.

// should be changed dynamically by the user
// "edm4hep::Cluster",
// "edm4hep::ReconstructedParticle",
// "edm4hep::Vertex",
// "edm4hep::Track",
// "edm4hep::ParticleID",
"edm4hep::MCParticle",
];

const res = loadObjects(json, 0, objectsToLoad);
console.log(res);
Loading
Loading