From eeeeef5179b1f730ce1ee1a3778999ce48c31b4c Mon Sep 17 00:00:00 2001 From: prayagyadav Date: Wed, 15 Jan 2025 10:12:33 +0100 Subject: [PATCH] EDM4HEPSchema and Newstyle FCCSchema --- src/coffea/nanoevents/__init__.py | 4 + src/coffea/nanoevents/assets/__init__.py | 9 + src/coffea/nanoevents/assets/edm4hep.yaml | 877 +++++++++++++++++ src/coffea/nanoevents/methods/edm4hep.py | 414 ++++++++ src/coffea/nanoevents/methods/fcc.py | 173 +++- src/coffea/nanoevents/schemas/__init__.py | 5 +- src/coffea/nanoevents/schemas/edm4hep.py | 1032 ++++++++++++++++++++ src/coffea/nanoevents/schemas/fcc.py | 60 +- src/coffea/nanoevents/transforms.py | 491 +++++++++- tests/samples/edm4hep.root | Bin 0 -> 116051 bytes tests/samples/p8_ee_WW_ecm240_edm4hep.root | Bin 0 -> 189503 bytes tests/test_nanoevents_edm4hep.py | 87 ++ tests/test_nanoevents_fcc_edm4hep1.py | 138 +++ tests/test_nanoevents_fcc_spring2021.py | 32 +- tests/test_nanoevents_fcc_winter2023.py | 32 +- 15 files changed, 3317 insertions(+), 37 deletions(-) create mode 100755 src/coffea/nanoevents/assets/__init__.py create mode 100755 src/coffea/nanoevents/assets/edm4hep.yaml create mode 100755 src/coffea/nanoevents/methods/edm4hep.py create mode 100755 src/coffea/nanoevents/schemas/edm4hep.py create mode 100644 tests/samples/edm4hep.root create mode 100644 tests/samples/p8_ee_WW_ecm240_edm4hep.root create mode 100755 tests/test_nanoevents_edm4hep.py create mode 100755 tests/test_nanoevents_fcc_edm4hep1.py diff --git a/src/coffea/nanoevents/__init__.py b/src/coffea/nanoevents/__init__.py index 8e66d8044..5bdef344d 100644 --- a/src/coffea/nanoevents/__init__.py +++ b/src/coffea/nanoevents/__init__.py @@ -7,7 +7,9 @@ FCC, BaseSchema, DelphesSchema, + EDM4HEPSchema, FCCSchema, + FCCSchema_edm4hep1, NanoAODSchema, PDUNESchema, PFNanoAODSchema, @@ -28,4 +30,6 @@ "ScoutingNanoAODSchema", "FCC", "FCCSchema", + "FCCSchema_edm4hep1", + "EDM4HEPSchema", ] diff --git a/src/coffea/nanoevents/assets/__init__.py b/src/coffea/nanoevents/assets/__init__.py new file mode 100755 index 000000000..2dfcd3caa --- /dev/null +++ b/src/coffea/nanoevents/assets/__init__.py @@ -0,0 +1,9 @@ +import os + +import yaml + +# path = os.path.abspath('src/coffea/nanoevents/assets/edm4hep.yaml') +root_dir = os.path.dirname(os.path.abspath(__file__)) +path = "/".join([root_dir, "edm4hep.yaml"]) +with open(path) as f: + edm4hep = yaml.safe_load(f) diff --git a/src/coffea/nanoevents/assets/edm4hep.yaml b/src/coffea/nanoevents/assets/edm4hep.yaml new file mode 100755 index 000000000..c53191b1f --- /dev/null +++ b/src/coffea/nanoevents/assets/edm4hep.yaml @@ -0,0 +1,877 @@ +--- +schema_version: 2 +options: + getSyntax: True + exposePODMembers: False + includeSubfolder: True + +components: + edm4hep::Vector4f: + Description: "Generic vector for storing classical 4D coordinates in memory. Four momentum helper functions are in edm4hep::utils" + Members: + - float x + - float y + - float z + - float t + ExtraCode: + includes: "#include " + declaration: " + constexpr Vector4f() : x(0),y(0),z(0),t(0) {}\n + constexpr Vector4f(float xx, float yy, float zz, float tt) : x(xx),y(yy),z(zz),t(tt) {}\n + constexpr Vector4f(const float* v) : x(v[0]),y(v[1]),z(v[2]),t(v[3]) {}\n + constexpr bool operator==(const Vector4f& v) const { return (x==v.x&&y==v.y&&z==v.z&&t==v.t) ; }\n + constexpr bool operator!=(const Vector4f& v) const { return !(*this == v) ; }\n + constexpr float operator[](unsigned i) const {\n + static_assert(\n + (offsetof(Vector4f,x)+sizeof(Vector4f::x) == offsetof(Vector4f,y)) &&\n + (offsetof(Vector4f,y)+sizeof(Vector4f::y) == offsetof(Vector4f,z)) &&\n + (offsetof(Vector4f,z)+sizeof(Vector4f::z) == offsetof(Vector4f,t)),\n + \"operator[] requires no padding\");\n + return *( &x + i ) ; }\n + " + + + edm4hep::Vector3f: + Members: + - float x + - float y + - float z + ExtraCode: + includes: "#include " + declaration: " + constexpr Vector3f() : x(0),y(0),z(0) {}\n + constexpr Vector3f(float xx, float yy, float zz) : x(xx),y(yy),z(zz) {}\n + constexpr Vector3f(const float* v) : x(v[0]),y(v[1]),z(v[2]) {}\n + constexpr bool operator==(const Vector3f& v) const { return (x==v.x&&y==v.y&&z==v.z) ; }\n + constexpr bool operator!=(const Vector3f& v) const { return !(*this == v) ; }\n + constexpr float operator[](unsigned i) const {\n + static_assert(\n + (offsetof(Vector3f,x)+sizeof(Vector3f::x) == offsetof(Vector3f,y)) &&\n + (offsetof(Vector3f,y)+sizeof(Vector3f::y) == offsetof(Vector3f,z)),\n + \"operator[] requires no padding\");\n + return *( &x + i ) ; }\n + " + + + edm4hep::Vector3d: + Members: + - double x + - double y + - double z + ExtraCode: + includes: " + #include \n + #include \n + " + declaration: " + constexpr Vector3d() : x(0),y(0),z(0) {}\n + constexpr Vector3d(double xx, double yy, double zz) : x(xx),y(yy),z(zz) {}\n + constexpr Vector3d(const double* v) : x(v[0]),y(v[1]),z(v[2]) {}\n + constexpr Vector3d(const float* v) : x(v[0]),y(v[1]),z(v[2]) {}\n + [[ deprecated(\"This constructor will be removed again it is mainly here for an easier transition\") ]]\n + constexpr Vector3d(const Vector3f& v) : x(v.x), y(v.y), z(v.z) {}\n + constexpr bool operator==(const Vector3d& v) const { return (x==v.x&&y==v.y&&z==v.z) ; }\n + constexpr bool operator!=(const Vector3d& v) const { return !(*this == v) ; }\n + constexpr double operator[](unsigned i) const {\n + static_assert(\n + (offsetof(Vector3d,x)+sizeof(Vector3d::x) == offsetof(Vector3d,y)) &&\n + (offsetof(Vector3d,y)+sizeof(Vector3d::y) == offsetof(Vector3d,z)),\n + \"operator[] requires no padding\");\n + return *( &x + i ) ; }\n + " + + + edm4hep::Vector2i: + Members: + - int32_t a + - int32_t b + ExtraCode: + includes: "#include " + declaration: " + constexpr Vector2i() : a(0),b(0) {}\n + constexpr Vector2i(int32_t aa, int32_t bb) : a(aa),b(bb) {}\n + constexpr Vector2i( const int32_t* v) : a(v[0]), b(v[1]) {}\n + constexpr bool operator==(const Vector2i& v) const { return (a==v.a&&b==v.b) ; }\n + constexpr bool operator!=(const Vector2i& v) const { return !(*this == v) ; }\n + constexpr int operator[](unsigned i) const {\n + static_assert(\n + offsetof(Vector2i,a)+sizeof(Vector2i::a) == offsetof(Vector2i,b),\n + \"operator[] requires no padding\");\n + return *( &a + i ) ; }\n + " + + + edm4hep::Vector2f: + Members: + - float a + - float b + ExtraCode: + includes: "#include " + declaration: " + constexpr Vector2f() : a(0),b(0) {}\n + constexpr Vector2f(float aa,float bb) : a(aa),b(bb) {}\n + constexpr Vector2f(const float* v) : a(v[0]), b(v[1]) {}\n + constexpr bool operator==(const Vector2f& v) const { return (a==v.a&&b==v.b) ; }\n + constexpr bool operator!=(const Vector2f& v) const { return !(*this == v) ; }\n + constexpr float operator[](unsigned i) const {\n + static_assert(\n + offsetof(Vector2f,a)+sizeof(Vector2f::a) == offsetof(Vector2f,b),\n + \"operator[] requires no padding\");\n + return *( &a + i ) ; }\n + " + + + edm4hep::CovMatrix2f: + Description: "A generic 2 dimensional covariance matrix with values stored in lower triangular form" + Members: + - std::array values // the covariance matrix values + ExtraCode: + includes: "#include " + declaration: " + constexpr CovMatrix2f() = default;\n + template\n + constexpr CovMatrix2f(Vs... v) : values{static_cast(v)...} { + static_assert(sizeof...(v) == 3, \"CovMatrix2f requires 3 values\"); + }\n + constexpr CovMatrix2f(const std::array& v) : values(v) {}\n + constexpr CovMatrix2f& operator=(std::array& v) { values = v; return *this; }\n + bool operator==(const CovMatrix2f& v) const { return v.values == values; }\n + bool operator!=(const CovMatrix2f& v) const { return v.values != values; }\n + " + declarationFile: "edm4hep/extra_code/CovMatrixCommon.ipp" + + + edm4hep::CovMatrix3f: + Description: "A generic 3 dimensional covariance matrix with values stored in lower triangular form" + Members: + - std::array values // the covariance matrix values + ExtraCode: + includes: "#include " + declaration: " + constexpr CovMatrix3f() = default;\n + constexpr CovMatrix3f(const std::array& v) : values(v) {}\n + template\n + constexpr CovMatrix3f(Vs... v) : values{static_cast(v)...} { + static_assert(sizeof...(v) == 6, \"CovMatrix3f requires 6 values\"); + }\n + constexpr CovMatrix3f& operator=(std::array& v) { values = v; return *this; }\n + bool operator==(const CovMatrix3f& v) const { return v.values == values; }\n + bool operator!=(const CovMatrix3f& v) const { return v.values != values; }\n + " + declarationFile: "edm4hep/extra_code/CovMatrixCommon.ipp" + + edm4hep::CovMatrix4f: + Description: "A generic 4 dimensional covariance matrix with values stored in lower triangular form" + Members: + - std::array values // the covariance matrix values + ExtraCode: + includes: "#include " + declaration: " + constexpr CovMatrix4f() = default;\n + template\n + constexpr CovMatrix4f(Vs... v) : values{static_cast(v)...} { + static_assert(sizeof...(v) == 10, \"CovMatrix4f requires 10 values\"); + }\n + constexpr CovMatrix4f(const std::array& v) : values(v) {}\n + constexpr CovMatrix4f& operator=(std::array& v) { values = v; return *this; }\n + bool operator==(const CovMatrix4f& v) const { return v.values == values; }\n + bool operator!=(const CovMatrix4f& v) const { return v.values != values; }\n + " + declarationFile: "edm4hep/extra_code/CovMatrixCommon.ipp" + + + edm4hep::CovMatrix6f: + Description: "A generic 6 dimensional covariance matrix with values stored in lower triangular form" + Members: + - std::array values // the covariance matrix values + ExtraCode: + includes: "#include " + declaration: " + constexpr CovMatrix6f() = default;\n + template\n + constexpr CovMatrix6f(Vs... v) : values{static_cast(v)...} { + static_assert(sizeof...(v) == 21, \"CovMatrix6f requires 21 values\"); + }\n + constexpr CovMatrix6f(const std::array& v) : values(v) {}\n + constexpr CovMatrix6f& operator=(std::array& v) { values = v; return *this; }\n + bool operator==(const CovMatrix6f& v) const { return v.values == values; }\n + bool operator!=(const CovMatrix6f& v) const { return v.values != values; }\n + " + declarationFile: "edm4hep/extra_code/CovMatrixCommon.ipp" + + + edm4hep::TrackState: + Description: "Parametrized description of a particle track" + Members: + - int32_t location // for use with At{Other|IP|FirstHit|LastHit|Calorimeter|Vertex}|LastLocation + - float D0 // transverse impact parameter + - float phi // azimuthal angle + - float omega [1/mm] // is the signed curvature of the track + - float Z0 // longitudinal impact parameter + - float tanLambda // lambda is the dip angle of the track in r-z + - float time [ns] // time of the track at this trackstate + - edm4hep::Vector3f referencePoint [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 + - edm4hep::CovMatrix6f covMatrix // covariance matrix of the track parameters. + ExtraCode: + includes: "#include " + declaration: " + static const int AtOther = 0 ; // any location other than the ones defined below\n + static const int AtIP = 1 ;\n + static const int AtFirstHit = 2 ;\n + static const int AtLastHit = 3 ;\n + static const int AtCalorimeter = 4 ;\n + static const int AtVertex = 5 ;\n + static const int LastLocation = AtVertex ;\n + + /// Get the covariance matrix value for the two passed parameters\n + constexpr float getCovMatrix(edm4hep::TrackParams parI, edm4hep::TrackParams parJ) const { return covMatrix.getValue(parI, parJ); }\n + /// Set the covariance matrix value for the two passed parameters\n + constexpr void setCovMatrix(float value, edm4hep::TrackParams parI, edm4hep::TrackParams parJ) { covMatrix.setValue(value, parI, parJ); } + " + + + edm4hep::Quantity: + Members: + - int16_t type // flag identifying how to interpret the quantity + - float value // value of the quantity + - float error // error on the value of the quantity + +datatypes: + + + edm4hep::EventHeader: + Description: "Event Header. Additional parameters are assumed to go into the metadata tree." + Author: "EDM4hep authors" + Members: + - int32_t eventNumber // event number + - int32_t runNumber // run number + - uint64_t timeStamp // time stamp + - double weight // event weight + VectorMembers: + - double weights // 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 + + + edm4hep::MCParticle: + Description: "The Monte Carlo particle - based on the lcio::MCParticle." + Author: "EDM4hep authors" + Members: + - int32_t PDG // PDG code of the particle + - int32_t generatorStatus // status of the particle as defined by the generator + - int32_t simulatorStatus // status of the particle from the simulation program - use BIT constants below + - float charge // particle charge + - float time [ns] // creation time of the particle in wrt. the event, e.g. for preassigned decays or decays in flight from the simulator + - double mass [GeV] // mass of the particle + - edm4hep::Vector3d vertex [mm] // production vertex of the particle + - edm4hep::Vector3d endpoint [mm] // endpoint of the particle + - edm4hep::Vector3d momentum [GeV] // particle 3-momentum at the production vertex + - edm4hep::Vector3d momentumAtEndpoint [GeV] // particle 3-momentum at the endpoint + - edm4hep::Vector3f spin // spin (helicity) vector of the particle + - edm4hep::Vector2i colorFlow // color flow as defined by the generator + OneToManyRelations: + - edm4hep::MCParticle parents // The parents of this particle + - edm4hep::MCParticle daughters // The daughters this particle + MutableExtraCode: + includes: "#include " + declaration: " + void setCreatedInSimulation(bool bitval) { setSimulatorStatus( utils::setBit( getSimulatorStatus() , BITCreatedInSimulation , bitval ) ) ; } \n + void setBackscatter(bool bitval) { setSimulatorStatus( utils::setBit( getSimulatorStatus() , BITBackscatter , bitval ) ) ; } \n + void setVertexIsNotEndpointOfParent(bool bitval) { setSimulatorStatus( utils::setBit( getSimulatorStatus() , BITVertexIsNotEndpointOfParent , bitval ) ) ; } \n + void setDecayedInTracker(bool bitval) { setSimulatorStatus( utils::setBit( getSimulatorStatus() , BITDecayedInTracker , bitval ) ) ; } \n + void setDecayedInCalorimeter(bool bitval) { setSimulatorStatus( utils::setBit( getSimulatorStatus() , BITDecayedInCalorimeter , bitval ) ) ; } \n + void setHasLeftDetector(bool bitval) { setSimulatorStatus( utils::setBit( getSimulatorStatus() , BITLeftDetector , bitval ) ) ; } \n + void setStopped(bool bitval) { setSimulatorStatus( utils::setBit( getSimulatorStatus() , BITStopped , bitval ) ) ; } \n + void setOverlay(bool bitval) { setSimulatorStatus( utils::setBit( getSimulatorStatus() , BITOverlay , bitval ) ) ; } \n + " + + ExtraCode: + includes: "#include \n" + declaration: " + // define the bit positions for the simulation flag\n + static const int BITCreatedInSimulation = 30;\n + static const int BITBackscatter = 29 ;\n + static const int BITVertexIsNotEndpointOfParent = 28 ; \n + static const int BITDecayedInTracker = 27 ; \n + static const int BITDecayedInCalorimeter = 26 ; \n + static const int BITLeftDetector = 25 ; \n + static const int BITStopped = 24 ; \n + static const int BITOverlay = 23 ; \n + /// return energy computed from momentum and mass \n + double getEnergy() const { return sqrt( getMomentum()[0]*getMomentum()[0]+getMomentum()[1]*getMomentum()[1]+\n + getMomentum()[2]*getMomentum()[2] + getMass()*getMass() ) ;} \n + + /// True if the particle has been created by the simulation program (rather than the generator). \n + bool isCreatedInSimulation() const { return utils::checkBit(getSimulatorStatus(), BITCreatedInSimulation); } \n + /// True if the particle is the result of a backscatter from a calorimeter shower. \n + bool isBackscatter() const { return utils::checkBit(getSimulatorStatus(), BITBackscatter); } \n + /// True if the particle's vertex is not the endpoint of the parent particle. \n + bool vertexIsNotEndpointOfParent() const { return utils::checkBit(getSimulatorStatus(), BITVertexIsNotEndpointOfParent); } \n + /// True if the particle has interacted in a tracking region. \n + bool isDecayedInTracker() const { return utils::checkBit(getSimulatorStatus(), BITDecayedInTracker); } \n + /// True if the particle has interacted in a calorimeter region. \n + bool isDecayedInCalorimeter() const { return utils::checkBit(getSimulatorStatus(), BITDecayedInCalorimeter); } \n + /// True if the particle has left the world volume undecayed. \n + bool hasLeftDetector() const { return utils::checkBit(getSimulatorStatus(), BITLeftDetector); }\n + /// True if the particle has been stopped by the simulation program. \n + bool isStopped() const { return utils::checkBit(getSimulatorStatus(), BITStopped); } \n + /// True if the particle has been overlaid by the simulation (or digitization) program.\n + bool isOverlay() const { return utils::checkBit(getSimulatorStatus(), BITOverlay); } \n + " + + + edm4hep::SimTrackerHit: + Description: "Simulated tracker hit" + Author: "EDM4hep authors" + Members: + - uint64_t cellID // ID of the sensor that created this hit + - float eDep [GeV] // energy deposited in the hit + - float time [ns] // proper time of the hit in the lab frame + - float pathLength // path length of the particle in the sensitive material that resulted in this hit + - int32_t quality // quality bit flag + - edm4hep::Vector3d position [mm] // the hit position + - edm4hep::Vector3f momentum [GeV] // the 3-momentum of the particle at the hits position + OneToOneRelations: + - edm4hep::MCParticle particle // MCParticle that caused the hit + MutableExtraCode: + includes: " + #include \n + #include \n + " + declaration: " + int32_t set_bit(int32_t val, int num, bool bitval){ return (val & ~(1<\n" + declaration: " + static const int BITOverlay = 31;\n + static const int BITProducedBySecondary = 30;\n + bool isOverlay() const { return getQuality() & (1 << BITOverlay) ; }\n + bool isProducedBySecondary() const { return getQuality() & (1 << BITProducedBySecondary) ; }\n + double x() const {return getPosition()[0];}\n + double y() const {return getPosition()[1];}\n + double z() const {return getPosition()[2];}\n + double rho() const {return sqrt(x()*x() + y()*y());}\n + [[deprecated(\"use getParticle instead\")]] + edm4hep::MCParticle getMCParticle() const { return getParticle(); }\n + " + + + edm4hep::CaloHitContribution: + Description: "Monte Carlo contribution to SimCalorimeterHit" + Author: "EDM4hep authors" + Members: + - int32_t PDG // PDG code of the shower particle that caused this contribution + - float energy [G] // energy of the this contribution + - float time [ns] // time of this contribution + - edm4hep::Vector3f stepPosition [mm] // position of this energy deposition (step) + OneToOneRelations: + - edm4hep::MCParticle particle // primary MCParticle that caused the shower responsible for this contribution to the hit + + + edm4hep::SimCalorimeterHit: + Description: "Simulated calorimeter hit" + Author: "EDM4hep authors" + Members: + - uint64_t cellID // ID of the sensor that created this hit + - float energy [GeV] // energy of the hit + - edm4hep::Vector3f position [mm] // position of the hit in world coordinates + OneToManyRelations: + - edm4hep::CaloHitContribution contributions // Monte Carlo step contributions + + + edm4hep::RawCalorimeterHit: + Description: "Raw calorimeter hit" + Author: "EDM4hep authors" + Members: + - uint64_t cellID // detector specific (geometrical) cell id + - int32_t amplitude // amplitude of the hit in ADC counts + - int32_t timeStamp // time stamp for the hit + + + edm4hep::CalorimeterHit: + Description: "Calorimeter hit" + Author: "EDM4hep authors" + Members: + - uint64_t cellID // detector specific (geometrical) cell id + - float energy [GeV] // energy of the hit + - float energyError [GeV] // error of the hit energy + - float time [ns] // time of the hit + - edm4hep::Vector3f position [mm] // position of the hit in world coordinates + - int32_t type // type of hit + + edm4hep::ParticleID: + Description: "ParticleID" + Author: "EDM4hep authors" + Members: + - int32_t type // userdefined type + - int32_t PDG // PDG code of this id - ( 999999 ) if unknown + - int32_t algorithmType // type of the algorithm/module that created this hypothesis + - float likelihood // likelihood of this hypothesis - in a user defined normalization + VectorMembers: + - float parameters // parameters associated with this hypothesis + OneToOneRelations: + - edm4hep::ReconstructedParticle particle // the particle from which this PID has been computed + + + edm4hep::Cluster: + Description: "Calorimeter Hit Cluster" + Author: "EDM4hep authors" + Members: + - int32_t type // flagword that defines the type of cluster + - float energy [GeV] // energy of the cluster + - float energyError [GeV] // error on the energy + - edm4hep::Vector3f position [mm] // position of the cluster + - edm4hep::CovMatrix3f positionError // covariance matrix of the position + - float iTheta // intrinsic direction of cluster at position Theta. Not to be confused with direction cluster is seen from IP + - float phi // intrinsic direction of cluster at position - Phi. Not to be confused with direction cluster is seen from IP + - edm4hep::Vector3f directionError [mm**2] // covariance matrix of the direction + VectorMembers: + - float shapeParameters // 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 + - float subdetectorEnergies // energy observed in a particular subdetector + OneToManyRelations: + - edm4hep::Cluster clusters // clusters that have been combined to this cluster + - edm4hep::CalorimeterHit hits // hits that have been combined to this cluster + ExtraCode: + includes: "#include " + declaration: " + /// Get the position error value for the two passed dimensions\n + float getPositionError(edm4hep::Cartesian dimI, edm4hep::Cartesian dimJ) const { return getPositionError().getValue(dimI, dimJ); }\n + " + MutableExtraCode: + includes: "#include " + declaration: " + /// Set the position error value for the two passed dimensions\n + void setPositionError(float value, edm4hep::Cartesian dimI, edm4hep::Cartesian dimJ) { return getPositionError().setValue(value, dimI, dimJ); }\n + " + + + edm4hep::TrackerHit3D: + Description: "Tracker hit" + Author: "EDM4hep authors" + Members: + - uint64_t cellID // ID of the sensor that created this hit + - int32_t type // type of raw data hit + - int32_t quality // quality bit flag of the hit + - float time [ns] // time of the hit + - float eDep [GeV] // energy deposited on the hit + - float eDepError [GeV] // error measured on EDep + - edm4hep::Vector3d position [mm] // hit position + - edm4hep::CovMatrix3f covMatrix // covariance matrix of the position (x,y,z) + ExtraCode: + includes: "#include " + declaration: " + /// Get the position covariance matrix value for the two passed dimensions\n + float getCovMatrix(edm4hep::Cartesian dimI, edm4hep::Cartesian dimJ) const { return getCovMatrix().getValue(dimI, dimJ); }\n + " + MutableExtraCode: + includes: "#include " + declaration: " + /// Set the position covariance matrix value for the two passed dimensions\n + void setCovMatrix(float value, edm4hep::Cartesian dimI, edm4hep::Cartesian dimJ) { getCovMatrix().setValue(value, dimI, dimJ); }\n + " + + + edm4hep::TrackerHitPlane: + Description: "Tracker hit plane" + Author: "EDM4hep authors" + Members: + - uint64_t cellID // ID of the sensor that created this hit + - int32_t type // type of raw data hit + - int32_t quality // quality bit flag of the hit + - float time [ns] // time of the hit + - float eDep [GeV] // energy deposited on the hit + - float eDepError [GeV] // error measured on EDep + - edm4hep::Vector2f u // measurement direction vector, u lies in the x-y plane + - edm4hep::Vector2f v // measurement direction vector, v is along z + - float du // measurement error along the direction + - float dv // measurement error along the direction + - edm4hep::Vector3d position [mm] // hit position + - edm4hep::CovMatrix3f covMatrix // covariance of the position (x,y,z) + ExtraCode: + includes: "#include " + declaration: " + /// Get the position covariance matrix value for the two passed dimensions\n + float getCovMatrix(edm4hep::Cartesian dimI, edm4hep::Cartesian dimJ) const { return getCovMatrix().getValue(dimI, dimJ); }\n + " + MutableExtraCode: + includes: "#include " + declaration: " + /// Set the position covariance matrix value for the two passed dimensions\n + void setCovMatrix(float value, edm4hep::Cartesian dimI, edm4hep::Cartesian dimJ) { getCovMatrix().setValue(value, dimI, dimJ); }\n + " + + + edm4hep::RawTimeSeries: + Description: "Raw data of a detector readout" + Author: "EDM4hep authors" + Members: + - uint64_t cellID // detector specific cell id + - int32_t quality // quality flag for the hit + - float time [ns] // time of the hit + - float charge [fC] // integrated charge of the hit + - float interval [ns] // interval of each sampling + VectorMembers: + - int32_t adcCounts // raw data (32-bit) word at i + + + + edm4hep::Track: + Description: "Reconstructed track" + Author: "EDM4hep authors" + Members: + - int32_t type // flagword that defines the type of track + - float chi2 // Chi^2 of the track fit + - int32_t ndf // number of degrees of freedom of the track fit + - int32_t Nholes // number of holes on track + VectorMembers: + - int32_t subdetectorHitNumbers // number of hits in particular subdetectors + - int32_t subdetectorHoleNumbers // number of holes in particular subdetectors + - edm4hep::TrackState trackStates // track states + OneToManyRelations: + - edm4hep::TrackerHit trackerHits // hits that have been used to create this track + - edm4hep::Track tracks // tracks (segments) that have been combined to create this track + + + edm4hep::Vertex: + Description: "Vertex" + Author: "EDM4hep authors" + Members: + - uint32_t type // Flagword that defines the type of the vertex, see reserved bits for more information + - float chi2 // chi-squared of the vertex fit + - int32_t ndf // number of degrees of freedom of the vertex fit + - edm4hep::Vector3f position // [mm] position of the vertex + - edm4hep::CovMatrix3f covMatrix // covariance matrix of the position + - int32_t algorithmType // type code for the algorithm that has been used to create the vertex + VectorMembers: + - float parameters // additional parameters related to this vertex + OneToManyRelations: + - edm4hep::ReconstructedParticle particles // particles that have been used to form this vertex, aka the decay particles emerging from this vertex + ExtraCode: + includes: "#include \n + #include \n" + declaration: " + /// Get the position covariance matrix value for the two passed dimensions\n + float getCovMatrix(edm4hep::Cartesian dimI, edm4hep::Cartesian dimJ) const { return getCovMatrix().getValue(dimI, dimJ); }\n + // Reserved bits for the type flagword\n + static constexpr int BITPrimaryVertex = 1;\n + static constexpr int BITSecondaryVertex = 2;\n + static constexpr int BITTertiaryVertex = 3;\n + + /// Check if this is a primary vertex\n + bool isPrimary() const { return utils::checkBit(getType(), BITPrimaryVertex); }\n + /// Check if this is a secondary vertex\n + bool isSecondary() const { return utils::checkBit(getType(), BITSecondaryVertex); }\n + /// Check if this is a tertiary vertex\n + bool isTertiary() const { return utils::checkBit(getType(), BITTertiaryVertex); }\n + " + MutableExtraCode: + declaration: " + /// Set the position covariance matrix value for the two passed dimensions\n + void setCovMatrix(float value, edm4hep::Cartesian dimI, edm4hep::Cartesian dimJ) { getCovMatrix().setValue(value, dimI, dimJ); }\n + + /// Set the primary vertex flag for this vertex\n + void setPrimary(bool value=true) { setType(utils::setBit(getType(), BITPrimaryVertex, value)); }\n + /// Set the secondary vertex flag for this vertex\n + void setSecondary(bool value=true) { setType(utils::setBit(getType(), BITSecondaryVertex, value)); }\n + /// Set the tertiary vertex flag for this vertex\n + void setTertiary(bool value=true) { setType(utils::setBit(getType(), BITTertiaryVertex, value)); }\n + " + + + edm4hep::ReconstructedParticle: + Description: "Reconstructed Particle" + Author: "EDM4hep authors" + Members: + - int32_t PDG // PDG of the reconstructed particle. + - float energy [GeV] // energy of the reconstructed particle. Four momentum state is not kept consistent internally + - edm4hep::Vector3f momentum [GeV] // particle momentum. Four momentum state is not kept consistent internally + - edm4hep::Vector3f referencePoint [mm] // reference, i.e. where the particle has been measured + - float charge // charge of the reconstructed particle + - float mass [GeV] // mass of the reconstructed particle, set independently from four vector. Four momentum state is not kept consistent internally + - float goodnessOfPID // overall goodness of the PID on a scale of [0;1] + - edm4hep::CovMatrix4f covMatrix // covariance matrix of the reconstructed particle 4vector + OneToOneRelations: + - edm4hep::Vertex decayVertex // decay vertex for the particle (if it is a composite particle) + OneToManyRelations: + - edm4hep::Cluster clusters // clusters that have been used for this particle + - edm4hep::Track tracks // tracks that have been used for this particle + - edm4hep::ReconstructedParticle particles // reconstructed particles that have been combined to this particle + ExtraCode: + includes: "#include " + declaration: " + bool isCompound() const { return particles_size() > 0 ;}\n + [[deprecated(\"use setPDG instead\")]]\n + int32_t getType() const { return getPDG(); }\n + /// Get the four momentum covariance matrix value for the two passed dimensions\n + float getCovMatrix(edm4hep::FourMomCoords dimI, edm4hep::FourMomCoords dimJ) const { return getCovMatrix().getValue(dimI, dimJ); }\n + " + MutableExtraCode: + includes: "#include " + declaration: " + //vertex where the particle decays. This method actually returns the start vertex from the first daughter particle found.\n + //TODO: edm4hep::Vertex getEndVertex() { return edm4hep::Vertex( (getParticles(0).isAvailable() ? getParticles(0).getStartVertex() : edm4hep::Vertex(0,0) ) ) ; }\n + [[deprecated(\"use setPDG instead\")]]\n + void setType(int32_t pdg) { setPDG(pdg); }\n + /// Set the four momentum covariance matrix value for the two passed dimensions\n + void setCovMatrix(float value, edm4hep::FourMomCoords dimI, edm4hep::FourMomCoords dimJ) { getCovMatrix().setValue(value, dimI, dimJ); }\n + " + + edm4hep::RecoMCParticleLink: + Description: "Link between a ReconstructedParticle and the corresponding MCParticle" + Author: "EDM4hep authors" + Members: + - float weight // weight of this link + OneToOneRelations: + - edm4hep::ReconstructedParticle from // reference to the reconstructed particle + - edm4hep::MCParticle to // reference to the Monte-Carlo particle + ExtraCode: + declaration: " + [[deprecated(\"use getFrom instead\")]] edm4hep::ReconstructedParticle getRec() const;\n + [[deprecated(\"use getTo instead\")]] edm4hep::MCParticle getSim() const;\n" + implementation: " + edm4hep::ReconstructedParticle {name}::getRec() const { return getFrom(); }\n + edm4hep::MCParticle {name}::getSim() const { return getTo(); }\n" + MutableExtraCode: + declaration: " + [[deprecated(\"use setFrom instead\")]]\n + void setRec(const edm4hep::ReconstructedParticle& rec);\n + [[deprecated(\"use setTo instead\")]]\n + void setSim(const edm4hep::MCParticle& sim);\n + " + implementation: " + void {name}::setSim(const edm4hep::MCParticle& sim) { setTo(sim); }\n + void {name}::setRec(const edm4hep::ReconstructedParticle& rec) { setFrom(rec); }\n + " + + edm4hep::CaloHitSimCaloHitLink: + Description: "Link between a CalorimeterHit and the corresponding SimCalorimeterHit" + Author: "EDM4hep authors" + Members: + - float weight // weight of this link + OneToOneRelations: + - edm4hep::CalorimeterHit from // reference to the reconstructed hit + - edm4hep::SimCalorimeterHit to // reference to the simulated hit + ExtraCode: + declaration: " + [[deprecated(\"use getFrom instead\")]] edm4hep::CalorimeterHit getRec() const;\n + [[deprecated(\"use getTo instead\")]] edm4hep::SimCalorimeterHit getSim() const;\n" + implementation: " + edm4hep::CalorimeterHit {name}::getRec() const { return getFrom(); }\n + edm4hep::SimCalorimeterHit {name}::getSim() const { return getTo(); }\n" + MutableExtraCode: + declaration: " + [[deprecated(\"use setFrom instead\")]]\n + void setRec(const edm4hep::CalorimeterHit& rec);\n + [[deprecated(\"use setTo instead\")]]\n + void setSim(const edm4hep::SimCalorimeterHit& sim);\n + " + implementation: " + void {name}::setSim(const edm4hep::SimCalorimeterHit& sim) { setTo(sim); }\n + void {name}::setRec(const edm4hep::CalorimeterHit& rec) { setFrom(rec); }\n + " + + + edm4hep::TrackerHitSimTrackerHitLink: + Description: "Link between a TrackerHit and the corresponding SimTrackerHit" + Author: "EDM4hep authors" + Members: + - float weight // weight of this link + OneToOneRelations: + - edm4hep::TrackerHit from // reference to the reconstructed hit + - edm4hep::SimTrackerHit to // reference to the simulated hit + ExtraCode: + declaration: " + [[deprecated(\"use getFrom instead\")]] edm4hep::TrackerHit getRec() const;\n + [[deprecated(\"use getTo instead\")]] edm4hep::SimTrackerHit getSim() const;\n" + implementation: " + edm4hep::TrackerHit {name}::getRec() const { return getFrom(); }\n + edm4hep::SimTrackerHit {name}::getSim() const { return getTo(); }\n" + MutableExtraCode: + declaration: " + [[deprecated(\"use setFrom instead\")]]\n + void setRec(const edm4hep::TrackerHit& rec);\n + [[deprecated(\"use setTo instead\")]]\n + void setSim(const edm4hep::SimTrackerHit& sim);\n + " + implementation: " + void {name}::setSim(const edm4hep::SimTrackerHit& sim) { setTo(sim); }\n + void {name}::setRec(const edm4hep::TrackerHit& rec) { setFrom(rec); }\n + " + + edm4hep::CaloHitMCParticleLink: + Description: "Link between a CalorimeterHit and the corresponding MCParticle" + Author: "EDM4hep authors" + Members: + - float weight // weight of this link + OneToOneRelations: + - edm4hep::CalorimeterHit from // reference to the reconstructed hit + - edm4hep::MCParticle to // reference to the Monte-Carlo particle + ExtraCode: + declaration: " + [[deprecated(\"use getFrom instead\")]] edm4hep::CalorimeterHit getRec() const;\n + [[deprecated(\"use getTo instead\")]] edm4hep::MCParticle getSim() const;\n" + implementation: " + edm4hep::CalorimeterHit {name}::getRec() const { return getFrom(); }\n + edm4hep::MCParticle {name}::getSim() const { return getTo(); }\n" + MutableExtraCode: + declaration: " + [[deprecated(\"use setFrom instead\")]]\n + void setRec(const edm4hep::CalorimeterHit& rec);\n + [[deprecated(\"use setTo instead\")]]\n + void setSim(const edm4hep::MCParticle& sim);\n + " + implementation: " + void {name}::setSim(const edm4hep::MCParticle& sim) { setTo(sim); }\n + void {name}::setRec(const edm4hep::CalorimeterHit& rec) { setFrom(rec); }\n + " + + edm4hep::ClusterMCParticleLink: + Description: "Link between a Cluster and the corresponding MCParticle" + Author: "EDM4hep authors" + Members: + - float weight // weight of this link + OneToOneRelations: + - edm4hep::Cluster from // reference to the cluster + - edm4hep::MCParticle to // reference to the Monte-Carlo particle + ExtraCode: + declaration: " + [[deprecated(\"use getFrom instead\")]] edm4hep::Cluster getRec() const;\n + [[deprecated(\"use getTo instead\")]] edm4hep::MCParticle getSim() const;\n" + implementation: " + edm4hep::Cluster {name}::getRec() const { return getFrom(); }\n + edm4hep::MCParticle {name}::getSim() const { return getTo(); }\n" + MutableExtraCode: + declaration: " + [[deprecated(\"use setFrom instead\")]]\n + void setRec(const edm4hep::Cluster& rec);\n + [[deprecated(\"use setTo instead\")]]\n + void setSim(const edm4hep::MCParticle& sim);\n + " + implementation: " + void {name}::setSim(const edm4hep::MCParticle& sim) { setTo(sim); }\n + void {name}::setRec(const edm4hep::Cluster& rec) { setFrom(rec); }\n + " + + edm4hep::TrackMCParticleLink: + Description: "Link between a Track and the corresponding MCParticle" + Author: "EDM4hep authors" + Members: + - float weight // weight of this link + OneToOneRelations: + - edm4hep::Track from // reference to the track + - edm4hep::MCParticle to // reference to the Monte-Carlo particle + ExtraCode: + declaration: " + [[deprecated(\"use getFrom instead\")]] edm4hep::Track getRec() const;\n + [[deprecated(\"use getTo instead\")]] edm4hep::MCParticle getSim() const;\n" + implementation: " + edm4hep::Track {name}::getRec() const { return getFrom(); }\n + edm4hep::MCParticle {name}::getSim() const { return getTo(); }\n" + MutableExtraCode: + declaration: " + [[deprecated(\"use setFrom instead\")]]\n + void setRec(const edm4hep::Track& rec);\n + [[deprecated(\"use setTo instead\")]]\n + void setSim(const edm4hep::MCParticle& sim);\n + " + implementation: " + void {name}::setSim(const edm4hep::MCParticle& sim) { setTo(sim); }\n + void {name}::setRec(const edm4hep::Track& rec) { setFrom(rec); }\n + " + + edm4hep::VertexRecoParticleLink: + Description: "Link between a Vertex and a ReconstructedParticle" + Author: "EDM4hep authors" + Members: + - float weight // weight of this link + OneToOneRelations: + - edm4hep::ReconstructedParticle to // reference to the reconstructed particle + - edm4hep::Vertex from // reference to the vertex + ExtraCode: + declaration: " + [[deprecated(\"use getTo instead\")]] edm4hep::ReconstructedParticle getRec() const;\n + [[deprecated(\"use getFrom instead\")]] edm4hep::Vertex getVertex() const;\n" + implementation: " + edm4hep::ReconstructedParticle {name}::getRec() const { return getTo(); }\n + edm4hep::Vertex {name}::getVertex() const { return getFrom(); }\n" + MutableExtraCode: + declaration: " + [[deprecated(\"use setFrom instead\")]]\n + void setVertex(const edm4hep::Vertex& rec);\n + [[deprecated(\"use setTo instead\")]]\n + void setRec(const edm4hep::ReconstructedParticle& sim);\n + " + implementation: " + void {name}::setVertex(const edm4hep::Vertex& vertex) { setFrom(vertex); }\n + void {name}::setRec(const edm4hep::ReconstructedParticle& rec) { setTo(rec); }\n + " + + + edm4hep::TimeSeries: + Description: "Calibrated Detector Data" + Author: "EDM4hep authors" + Members: + - uint64_t cellID // cell id + - float time [ns] // begin time + - float interval [ns] // interval of each sampling + VectorMembers: + - float amplitude // calibrated detector data + + + + edm4hep::RecDqdx: + Description: "dN/dx or dE/dx info of a Track" + Author: "EDM4hep authors" + Members: + - edm4hep::Quantity dQdx // the reconstructed dEdx or dNdx and its error + OneToOneRelations: + - edm4hep::Track track // the corresponding track + + + #===== Generator related data ===== + + + edm4hep::GeneratorEventParameters: + Description: "Generator event parameters" + Author: "EDM4hep authors" + Members: + - double eventScale // event scale + - double alphaQED // alpha_QED + - double alphaQCD // alpha_QCD + - int signalProcessId // id of signal process + - double sqrts [GeV] // sqrt(s) + VectorMembers: + - double crossSections [pb] // list of cross sections + - double crossSectionErrors [pb] // list of cross section errors + OneToManyRelations: + - edm4hep::MCParticle signalVertex // List of initial state MCParticle that are the source of the hard interaction + + + edm4hep::GeneratorPdfInfo: + Description: "Generator pdf information" + Author: "EDM4hep authors" + Members: + - std::array partonId // Parton PDG id + - std::array lhapdfId // LHAPDF PDF id (see https://lhapdf.hepforge.org/pdfsets.html) + - std::array x // Parton momentum fraction + - std::array xf // PDF value + - double scale [GeV] // Factorisation scale + +interfaces: + edm4hep::TrackerHit: + Description: "Tracker hit interface class" + Author: "Thomas Madlener, DESY" + Members: + - uint64_t cellID // ID of the sensor that created this hit + - int32_t type // type of the raw data hit + - int32_t quality // quality bit flag of the hit + - float time [ns] // time of the hit + - float eDep [GeV] // energy deposited on the hit + - float eDepError [GeV] // error measured on eDep + - edm4hep::Vector3d position [mm] // hit position + Types: + - edm4hep::TrackerHit3D + - edm4hep::TrackerHitPlane diff --git a/src/coffea/nanoevents/methods/edm4hep.py b/src/coffea/nanoevents/methods/edm4hep.py new file mode 100755 index 000000000..2a56c0c52 --- /dev/null +++ b/src/coffea/nanoevents/methods/edm4hep.py @@ -0,0 +1,414 @@ +import awkward +import numpy +from dask_awkward.lib.core import dask_method, dask_property + +from coffea.nanoevents.methods import base, vector +from coffea.nanoevents.methods.base import _ClassMethodFn + +behavior = {} +behavior.update(base.behavior) + + +class _EDM4HEPEvents(behavior["NanoEvents"]): + def __repr__(self): + return "EDM4HEP-Event" + + +behavior["NanoEvents"] = _EDM4HEPEvents + + +def _set_repr_name(classname): + def namefcn(self): + return classname + + behavior[classname].__repr__ = namefcn + + +@awkward.mixin_class(behavior) +class edm4hep_nanocollection(base.NanoCollection): + """Modified NanoCollection for EDM4HEP""" + + @dask_method + def _apply_nested_global_index(self, index): + # extract the shape of the index + counts1 = awkward.num(index, axis=1) + counts2 = awkward.flatten(awkward.num(index, axis=2), axis=1) + if index.ndim == 4: + counts3 = awkward.ravel(awkward.num(index, axis=3)) + + # Apply the flat index + out = self._apply_global_index(awkward.ravel(index)) + + # Rebuild the shape of the index + if index.ndim == 4: + out = awkward.unflatten(out, counts3, axis=0) + out = awkward.unflatten(out, counts2, axis=0) + out = awkward.unflatten(out, counts1, axis=0) + + return out + + @_apply_nested_global_index.dask + def _apply_nested_global_index(self, dask_array, index): + return dask_array.map_partitions( + _ClassMethodFn("_apply_nested_global_index"), + index, + label="apply_nested_global_index", + ) + + @dask_property + def List_Relations(self): + """List all the branches that are for OneToOneRelations or OneToManyRelations""" + idxs = {name for name in self.fields if "_idx_" in name} + return idxs + + @List_Relations.dask + def List_Relations(self, dask_array): + """List all the branches that are for OneToOneRelations or OneToManyRelations""" + idxs = {name for name in dask_array.fields if "_idx_" in name} + return idxs + + @dask_method + def Map_Relation(self, generic_name, target_name): + name_struct = generic_name + "_idx_" + target_name + "_index_Global" + idx_field_names = [name for name in self.fields if name_struct in name] + if len(idx_field_names) == 0: + raise FileNotFoundError( + f"*{name_struct} not found in the current collection" + ) + elif len(idx_field_names) > 1: + raise RuntimeError(f"More than one field available for *{name_struct}!") + + index = self[idx_field_names[0]] + if index.ndim == 2: + return self._events()[target_name]._apply_global_index(index) + elif index.ndim == 3 or index.ndim == 4: + return self._events()[target_name]._apply_nested_global_index(index) + else: + raise RuntimeError(f"Index is highly nested!\n{index}") + + @Map_Relation.dask + def Map_Relation(self, dask_array, generic_name, target_name): + name_struct = generic_name + "_idx_" + target_name + "_index_Global" + idx_field_names = [name for name in dask_array.fields if name_struct in name] + if len(idx_field_names) == 0: + raise FileNotFoundError( + f"*{name_struct} not found in the current collection" + ) + elif len(idx_field_names) > 1: + raise RuntimeError(f"More than one field available for *{name_struct}!") + + index = dask_array[idx_field_names[0]] + if index.ndim == 2: + return dask_array._events()[target_name]._apply_global_index(index) + elif index.ndim == 3 or index.ndim == 4: + return dask_array._events()[target_name]._apply_nested_global_index(index) + else: + raise RuntimeError(f"Index is highly nested!\n{index}") + + @dask_property + def List_Links(self): + """List all the branches that are Links""" + idxs = { + name + for name in self.fields + if (("Link_from" in name) or ("Link_to" in name)) + } + return idxs + + @List_Links.dask + def List_Links(self, dask_array): + """List all the branches that are Links""" + idxs = { + name + for name in dask_array.fields + if (("Link_from" in name) or ("Link_to" in name)) + } + return idxs + + @dask_method + def Map_Link(self, generic_name, target_name): + idx_field_name = "Link_" + generic_name + "_" + target_name + if idx_field_name not in self.fields: + raise FileNotFoundError( + f"{idx_field_name} not found in the current collection" + ) + return self._events()[target_name]._apply_global_index( + self[idx_field_name]["index_Global"] + ) + + @Map_Link.dask + def Map_Link(self, dask_array, generic_name, target_name): + idx_field_name = "Link_" + generic_name + "_" + target_name + if idx_field_name not in dask_array.fields: + raise FileNotFoundError( + f"{idx_field_name} not found in the current collection" + ) + return dask_array._events()[target_name]._apply_global_index( + dask_array[idx_field_name]["index_Global"] + ) + + +behavior.update( + awkward._util.copy_behaviors(base.NanoCollection, edm4hep_nanocollection, behavior) +) + + +@awkward.mixin_class(behavior) +class MomentumCandidate(vector.LorentzVector): + """A Lorentz vector with charge + + This mixin class requires the parent class to provide items `px`, `py`, `pz`, `E`, and `charge`. + """ + + @awkward.mixin_class_method(numpy.add, {"MomentumCandidate"}) + def add(self, other): + """Add two candidates together elementwise using `px`, `py`, `pz`, `E`, and `charge` components""" + return awkward.zip( + { + "px": self.px + other.px, + "py": self.py + other.py, + "pz": self.pz + other.pz, + "E": self.E + other.E, + "charge": self.charge + other.charge, + }, + with_name="MomentumCandidate", + behavior=self.behavior, + ) + + def sum(self, axis=-1): + """Sum an array of vectors elementwise using `px`, `py`, `pz`, `E`, and `charge` components""" + return awkward.zip( + { + "px": awkward.sum(self.px, axis=axis), + "py": awkward.sum(self.py, axis=axis), + "pz": awkward.sum(self.pz, axis=axis), + "E": awkward.sum(self.E, axis=axis), + "charge": awkward.sum(self.charge, axis=axis), + }, + with_name="MomentumCandidate", + behavior=self.behavior, + ) + + @property + def absolute_mass(self): + return numpy.sqrt(numpy.abs(self.mass2)) + + +behavior.update( + awkward._util.copy_behaviors(vector.LorentzVector, MomentumCandidate, behavior) +) +MomentumCandidateArray.ProjectionClass2D = vector.TwoVectorArray # noqa: F821 +MomentumCandidateArray.ProjectionClass3D = vector.ThreeVectorArray # noqa: F821 +MomentumCandidateArray.ProjectionClass4D = vector.LorentzVectorArray # noqa: F821 +MomentumCandidateArray.MomentumClass = MomentumCandidateArray # noqa: F821 + + +######################################################################################### +# Selected Components # +######################################################################################### +@awkward.mixin_class(behavior) +class TrackState(base.NanoCollection): + """EDM4HEP Component: TrackState""" + + +_set_repr_name("TrackState") +TrackState.ProjectionClass2D = vector.TwoVectorArray # noqa: F821 +TrackState.ProjectionClass3D = vector.ThreeVectorArray # noqa: F821 +TrackState.ProjectionClass4D = TrackState # noqa: F821 +TrackState.MomentumClass = vector.LorentzVectorArray # noqa: F821 + + +@awkward.mixin_class(behavior) +class Quantity(base.NanoCollection): + """EDM4HEP Component: Quantity""" + + +_set_repr_name("Quantity") + + +@awkward.mixin_class(behavior) +class covMatrix(base.NanoCollection): + """EDM4HEP Component: covMatrix""" + + +_set_repr_name("covMatrix") + + +######################################################################################### +# Datatypes # +######################################################################################### +@awkward.mixin_class(behavior) +class EventHeader(edm4hep_nanocollection): + """EDM4HEP Datatype: EventHeader""" + + +_set_repr_name("EventHeader") + + +@awkward.mixin_class(behavior) +class MCParticle(MomentumCandidate, edm4hep_nanocollection): + """EDM4HEP Datatype: MCParticle""" + + +_set_repr_name("MCParticle") +behavior.update(awkward._util.copy_behaviors(MomentumCandidate, MCParticle, behavior)) +MCParticleArray.ProjectionClass2D = vector.TwoVectorArray # noqa: F821 +MCParticleArray.ProjectionClass3D = vector.ThreeVectorArray # noqa: F821 +MCParticleArray.ProjectionClass4D = MCParticleArray # noqa: F821 +MCParticleArray.MomentumClass = vector.LorentzVectorArray # noqa: F821 + + +@awkward.mixin_class(behavior) +class SimTrackerHit(edm4hep_nanocollection): + """EDM4HEP Datatype: SimTrackerHit""" + + +_set_repr_name("SimTrackerHit") + + +@awkward.mixin_class(behavior) +class CaloHitContribution(edm4hep_nanocollection): + """EDM4HEP Datatype: CaloHitContribution""" + + +_set_repr_name("CaloHitContribution") + + +@awkward.mixin_class(behavior) +class SimCalorimeterHit(edm4hep_nanocollection): + """EDM4HEP Datatype: SimCalorimeterHit""" + + +_set_repr_name("SimCalorimeterHit") + + +@awkward.mixin_class(behavior) +class RawCalorimeterHit(edm4hep_nanocollection): + """EDM4HEP Datatype: RawCalorimeterHit""" + + +_set_repr_name("RawCalorimeterHit") + + +@awkward.mixin_class(behavior) +class CalorimeterHit(edm4hep_nanocollection): + """EDM4HEP Datatype: CalorimeterHit""" + + +_set_repr_name("CalorimeterHit") + + +@awkward.mixin_class(behavior) +class ParticleID(edm4hep_nanocollection): + """EDM4HEP Datatype: ParticleID""" + + +_set_repr_name("ParticleID") + + +@awkward.mixin_class(behavior) +class Cluster(edm4hep_nanocollection): + """EDM4HEP Datatype: Cluster""" + + +_set_repr_name("Cluster") + + +@awkward.mixin_class(behavior) +class TrackerHit3D(edm4hep_nanocollection): + """EDM4HEP Datatype: TrackerHit3D""" + + +_set_repr_name("TrackerHit3D") + + +@awkward.mixin_class(behavior) +class TrackerHitPlane(edm4hep_nanocollection): + """EDM4HEP Datatype: TrackerHitPlane""" + + +_set_repr_name("TrackerHitPlane") + + +@awkward.mixin_class(behavior) +class RawTimeSeries(edm4hep_nanocollection): + """EDM4HEP Datatype: RawTimeSeries""" + + +_set_repr_name("RawTimeSeries") + + +@awkward.mixin_class(behavior) +class Track(edm4hep_nanocollection): + """EDM4HEP Datatype: Track""" + + +_set_repr_name("Track") + + +@awkward.mixin_class(behavior) +class Vertex(edm4hep_nanocollection): + """EDM4HEP Datatype: Vertex""" + + +_set_repr_name("Vertex") + + +@awkward.mixin_class(behavior) +class ReconstructedParticle(MomentumCandidate, edm4hep_nanocollection): + """EDM4HEP Datatype: Reconstructed particle""" + + +_set_repr_name("ReconstructedParticle") +behavior.update( + awkward._util.copy_behaviors(MomentumCandidate, ReconstructedParticle, behavior) +) +ReconstructedParticleArray.ProjectionClass2D = vector.TwoVectorArray # noqa: F821 +ReconstructedParticleArray.ProjectionClass3D = vector.ThreeVectorArray # noqa: F821 +ReconstructedParticleArray.ProjectionClass4D = ReconstructedParticleArray # noqa: F821 +ReconstructedParticleArray.MomentumClass = vector.LorentzVectorArray # noqa: F821 + + +@awkward.mixin_class(behavior) +class TimeSeries(edm4hep_nanocollection): + """EDM4HEP Datatype: TimeSeries""" + + +_set_repr_name("TimeSeries") + + +@awkward.mixin_class(behavior) +class RecDqdx(edm4hep_nanocollection): + """EDM4HEP Datatype: RecDqdx""" + + +_set_repr_name("RecDqdx") + + +######################################################################################### +# Selected Links # +######################################################################################### +@awkward.mixin_class(behavior) +class RecoMCParticleLink(edm4hep_nanocollection): + """EDM4HEP Link: MCRecoParticleLink""" + + +_set_repr_name("RecoMCParticleLink") +RecoMCParticleLinkArray.ProjectionClass2D = vector.TwoVectorArray # noqa: F821 +RecoMCParticleLinkArray.ProjectionClass3D = vector.ThreeVectorArray # noqa: F821 +RecoMCParticleLinkArray.ProjectionClass4D = RecoMCParticleLinkArray # noqa: F821 +RecoMCParticleLinkArray.MomentumClass = vector.LorentzVectorArray # noqa: F821 + + +######################################################################################### +# Extras # +######################################################################################### +@awkward.mixin_class(behavior) +class ObjectID(base.NanoCollection): + """ + Generic Object ID storage, pointing to another collection. + Usually have the type + """ + + +_set_repr_name("ObjectID") diff --git a/src/coffea/nanoevents/methods/fcc.py b/src/coffea/nanoevents/methods/fcc.py index adc4dc49c..ffd2ba295 100644 --- a/src/coffea/nanoevents/methods/fcc.py +++ b/src/coffea/nanoevents/methods/fcc.py @@ -2,7 +2,7 @@ import numpy from dask_awkward.lib.core import dask_property -from coffea.nanoevents.methods import base, vector +from coffea.nanoevents.methods import base, edm4hep, vector behavior = {} behavior.update(base.behavior) @@ -356,3 +356,174 @@ class Track(base.NanoCollection): TrackArray.ProjectionClass3D = vector.ThreeVectorArray # noqa: F821 TrackArray.ProjectionClass4D = TrackArray # noqa: F821 TrackArray.MomentumClass = vector.LorentzVectorArray # noqa: F821 + + +########################################### +# Overloads for FCC_edm4hep1 +########################################### + +behavior_edm4hep1 = {} +behavior_edm4hep1.update(base.behavior) +behavior_edm4hep1.update(edm4hep.behavior) + + +def _set_repr_name_edm4hep1(classname): + def namefcn(self): + return classname + + behavior_edm4hep1[classname].__repr__ = namefcn + + +@awkward.mixin_class(behavior_edm4hep1) +class MCParticle(edm4hep.MCParticle): # noqa: F811 + """EDM4HEP Datatype: MCParticle; Modified for FCC""" + + # Get MC Daughters + @dask_property + def get_daughters(self): + return self.Map_Relation("daughters", "Particle") + + @get_daughters.dask + def get_daughters(self, dask_array): + return dask_array.Map_Relation("daughters", "Particle") + + # Get MC Parents + @dask_property + def get_parents(self): + return self.Map_Relation("parents", "Particle") + + @get_parents.dask + def get_parents(self, dask_array): + return dask_array.Map_Relation("parents", "Particle") + + +_set_repr_name_edm4hep1("MCParticle") +behavior_edm4hep1.update( + awkward._util.copy_behaviors(MomentumCandidate, MCParticle, behavior) +) +MCParticleArray.ProjectionClass2D = vector.TwoVectorArray # noqa: F821 +MCParticleArray.ProjectionClass3D = vector.ThreeVectorArray # noqa: F821 +MCParticleArray.ProjectionClass4D = MCParticleArray # noqa: F821 +MCParticleArray.MomentumClass = vector.LorentzVectorArray # noqa: F821 + + +@awkward.mixin_class(behavior_edm4hep1) +class ReconstructedParticle(edm4hep.ReconstructedParticle): # noqa: F811 + """EDM4HEP Datatype: Reconstructed particle; Modified for FCC""" + + # Get MC counterpart + @dask_property + def match_gen(self): + return self.Map_Link("to", "Particle") + + @match_gen.dask + def match_gen(self, dask_array): + return dask_array.Map_Link("to", "Particle") + + # Get cluster EFlowPhoton + @dask_property + def get_cluster_photons(self): + return self.Map_Relation("clusters", "EFlowPhoton") + + @get_cluster_photons.dask + def get_cluster_photons(self, dask_array): + return dask_array.Map_Relation("clusters", "EFlowPhoton") + + # Get ReconstructedParticle + @dask_property + def get_reconstructedparticles(self): + return self.Map_Relation("particles", "ReconstructedParticles") + + @get_reconstructedparticles.dask + def get_reconstructedparticles(self, dask_array): + return dask_array.Map_Relation("particles", "ReconstructedParticles") + + # Get Tracks + @dask_property + def get_tracks(self): + return self.Map_Relation("tracks", "EFlowTrack") + + @get_tracks.dask + def get_tracks(self, dask_array): + return dask_array.Map_Relation("tracks", "EFlowTrack") + + +_set_repr_name_edm4hep1("ReconstructedParticle") +behavior_edm4hep1.update( + awkward._util.copy_behaviors( + MomentumCandidate, ReconstructedParticle, behavior_edm4hep1 + ) +) +ReconstructedParticleArray.ProjectionClass2D = vector.TwoVectorArray # noqa: F821 +ReconstructedParticleArray.ProjectionClass3D = vector.ThreeVectorArray # noqa: F821 +ReconstructedParticleArray.ProjectionClass4D = ReconstructedParticleArray # noqa: F821 +ReconstructedParticleArray.MomentumClass = vector.LorentzVectorArray # noqa: F821 + + +@awkward.mixin_class(behavior_edm4hep1) +class ParticleID(edm4hep.ParticleID): # noqa: F811 + """EDM4HEP Datatype: ParticleID; Modified for FCC""" + + # Get ReconstructedParticle + @dask_property + def get_reconstructedparticles(self): + return self.Map_Relation("particle", "ReconstructedParticles") + + @get_reconstructedparticles.dask + def get_reconstructedparticles(self, dask_array): + return dask_array.Map_Relation("particle", "ReconstructedParticles") + + +_set_repr_name_edm4hep1("ParticleID") + + +@awkward.mixin_class(behavior_edm4hep1) +class Cluster(edm4hep.Cluster): # noqa: F811 + """EDM4HEP Datatype: Cluster; Modified for FCC""" + + # Get cluster EFlowPhoton + @dask_property + def get_cluster_photons(self): + return self.Map_Relation("clusters", "EFlowPhoton") + + @get_cluster_photons.dask + def get_cluster_photons(self, dask_array): + return dask_array.Map_Relation("clusters", "EFlowPhoton") + + # Get calorimeter hits + @dask_property + def get_hits(self): + return self.Map_Relation("hits", "CalorimeterHits") + + @get_hits.dask + def get_hits(self, dask_array): + return dask_array.Map_Relation("hits", "CalorimeterHits") + + +_set_repr_name_edm4hep1("Cluster") + + +@awkward.mixin_class(behavior_edm4hep1) +class Track(edm4hep.Track): # noqa: F811 + """EDM4HEP Datatype: Track; Modified for FCC""" + + # Get Tracks + @dask_property + def get_tracks(self): + return self.Map_Relation("tracks", "EFlowTrack") + + @get_tracks.dask + def get_tracks(self, dask_array): + return dask_array.Map_Relation("tracks", "EFlowTrack") + + # Get tracker hits + @dask_property + def get_trackerhits(self): + return self.Map_Relation("trackerHits", "TrackerHits") + + @get_trackerhits.dask + def get_trackerhits(self, dask_array): + return dask_array.Map_Relation("trackerHits", "TrackerHits") + + +_set_repr_name_edm4hep1("Track") diff --git a/src/coffea/nanoevents/schemas/__init__.py b/src/coffea/nanoevents/schemas/__init__.py index a598fbf26..4394b7240 100644 --- a/src/coffea/nanoevents/schemas/__init__.py +++ b/src/coffea/nanoevents/schemas/__init__.py @@ -1,6 +1,7 @@ from .base import BaseSchema from .delphes import DelphesSchema -from .fcc import FCC, FCCSchema +from .edm4hep import EDM4HEPSchema +from .fcc import FCC, FCCSchema, FCCSchema_edm4hep1 from .nanoaod import NanoAODSchema, PFNanoAODSchema, ScoutingNanoAODSchema from .pdune import PDUNESchema from .physlite import PHYSLITESchema @@ -17,4 +18,6 @@ "ScoutingNanoAODSchema", "FCC", "FCCSchema", + "FCCSchema_edm4hep1", + "EDM4HEPSchema", ] diff --git a/src/coffea/nanoevents/schemas/edm4hep.py b/src/coffea/nanoevents/schemas/edm4hep.py new file mode 100755 index 000000000..f80ace777 --- /dev/null +++ b/src/coffea/nanoevents/schemas/edm4hep.py @@ -0,0 +1,1032 @@ +import copy +import re +import warnings + +from coffea.nanoevents import transforms +from coffea.nanoevents.methods import vector +from coffea.nanoevents.schemas.base import BaseSchema, zip_forms +from coffea.nanoevents.util import concat + +# Load and Parse EDM4HEP.yaml + + +def parse_Members_and_Relations(Members_and_Relation_List, target_text=False): + parsed = {} + for i in Members_and_Relation_List: + # Separate the declaration and the comment + separated = i.split("//", 1) + declaration = separated[0].strip() + doc_str = "" + if len(separated) > 1: + doc_str = separated[1].strip() + + type_str = declaration.split()[0] + name_str = declaration.split()[1] + + if ("::" in declaration) and ("<" in declaration) and (">" in declaration): + type_str = declaration.split(">", 1)[0] + ">" + name_str = declaration.split(">", 1)[1] + + parsed[name_str.strip()] = {"type": type_str.strip(), "doc": doc_str.strip()} + if target_text: + parsed[name_str.strip()] = { + "type": type_str.strip(), + "target": type_str.strip().split("::")[1], + "doc": doc_str.strip(), + } + return parsed + + +from coffea.nanoevents.assets import edm4hep + +# with open("coffea/nanoevents/assets/edm4hep.yaml") as f: +# edm4hep = yaml.safe_load(f) + +parsed_edm4hep = copy.deepcopy(edm4hep) +for key in edm4hep.keys(): + if not isinstance(edm4hep[key], dict): + continue + for subkey in edm4hep[key].keys(): + if not isinstance(edm4hep[key][subkey], dict): + continue + for subsubkey in edm4hep[key][subkey].keys(): + if subsubkey in ["Members", "VectorMembers"]: + parsed_edm4hep[key][subkey][subsubkey] = parse_Members_and_Relations( + edm4hep[key][subkey][subsubkey] + ) + elif subsubkey in ["OneToOneRelations", "OneToManyRelations"]: + parsed_edm4hep[key][subkey][subsubkey] = parse_Members_and_Relations( + edm4hep[key][subkey][subsubkey], target_text=True + ) + + +# Add extra datatypes +parsed_edm4hep["datatypes"]["edm4hep::ObjectID"] = ( + { # Actually from podio, but, for parsing compatibility, keep as edm4hep + "Description": "The Monte Carlo particle - based on the lcio::MCParticle.", + "Author": "Prayag Yadav", + "Members": { + "index": {"type": "int64", "doc": "indices to the target collection"}, + "collectionID": { + "type": "int64", + "doc": "indices to the target collection", + }, + }, + } +) + +# Collection Regex # +# Any branch name with a forward slash '/' +# Example: 'ReconstructedParticles/ReconstructedParticles.energy' +_all_collections = re.compile(r".*[\/]+.*") + +# Any branch name with '[' and ']' +# Example: 'ReconstructedParticles/ReconstructedParticles.covMatrix[10]' +_square_braces = re.compile(r".*\[.*\]") + + +__dask_capable__ = True + + +def sort_dict(d): + """Sort a dictionary by key""" + return {k: d[k] for k in sorted(d)} + + +class EDM4HEPSchema(BaseSchema): + """ + Schema-builder for EDM4HEP root file structure. + """ + + __dask_capable__ = True + + # EDM4HEP components mixins + _components_mixins = { + "Vector4f": "LorentzVector", + "Vector3f": "ThreeVector", + "Vector3d": "ThreeVector", + "Vector2i": "TwoVector", + "Vector2f": "TwoVector", + "TrackState": "TrackState", + "Quantity": "Quantity", + "covMatrix2f": "covMatrix", + "covMatrix3f": "covMatrix", + "covMatrix4f": "covMatrix", + "covMatrix6f": "covMatrix", + } + + # EDM4HEP datatype mixins + _datatype_mixins = { # Example {'TrackCollection' : 'Track', 'MCParticleCollection':'MCParticleCollection', etc} + name.split("::")[1] + "Collection": name.split("::")[1] + for name in parsed_edm4hep["datatypes"].keys() + if name.split("::")[1] != "EventHeader" + } + _datatype_mixins["EventHeader"] = "EventHeader" + + _momentum_fields_e = { + "energy": "E", + "momentum.x": "px", + "momentum.y": "py", + "momentum.z": "pz", + } + _two_vec_replacement = {"a": "x", "b": "y"} + _replacement = {**_momentum_fields_e, **_two_vec_replacement} + + copy_links_to_target_datatype = False + + # Which collection to match if there are multiple matching collections for a given datatype + _datatype_priority = {} + + def __init__(self, base_form, *args, **kwargs): + super().__init__(base_form) + self._form["fields"], self._form["contents"] = self._build_collections( + self._form["fields"], self._form["contents"] + ) + + def _zip_components(self, collection_name, component_branches, branch_forms): + """ + Zip the members of a component collection + Eg. referencePoint (edm4hep::Vector3f) has the referencePoint.x, referencePoint.y and referencePoint.z branches + They are zipped together to return the referencePoint collection + """ + inverted_dict = {} + for name in component_branches.keys(): + var = component_branches[name]["branch_var"] + subvar = component_branches[name]["branch_subvar"] + type = component_branches[name]["type"] + doc = component_branches[name]["doc"] + if var + "@" + type not in inverted_dict.keys(): + inverted_dict[var + "@" + type] = [] + inverted_dict[var + "@" + type].append( + {"name": name, "branch_subvar": subvar, "doc": doc} + ) + + for var, branch_list in inverted_dict.items(): + assign_name = var.split("@")[0] + type_name = var.split("@")[1].split("::")[1] + mixin = self._components_mixins.get(type_name, None) + if assign_name == "momentum": + continue # Used to create 4 vector for the whole collection, later. + if var.split("@")[1] == "unknown": + continue + # component_name = var.split("@")[1].split("::")[1] + + to_zip_raw = { + item["branch_subvar"]: branch_forms.pop(item["name"]) + for item in branch_list + } + # replace keys if needed + to_zip = { + self._replacement.get(name, name): form + for name, form in to_zip_raw.items() + } + + replaced_branch = ( + collection_name + "/" + collection_name + "." + assign_name + ) + branch_forms[replaced_branch] = zip_forms( + sort_dict(to_zip), str(assign_name), str(mixin) + ) + + branch_forms[replaced_branch]["content"]["parameters"].update( + {"collection_name": assign_name, "__doc__": branch_list[0]["doc"]} + ) + return branch_forms + + def _lookup_branch(self, collection_name, branch_name, key=None): + """ + Returns 'type' or 'doc' of a branch component, given a collection_name, branch_name and key('type' or 'doc') + """ + datatype = self._datatype_mixins.get(collection_name, None) + if collection_name.startswith("_"): + col_name = collection_name[1:].split("_")[0] + subcol_name = collection_name[1:].split("_")[1] + datatype = self._datatype_mixins.get(col_name, None) + if datatype is None: + raise FileNotFoundError(f"No datatype found for {collection_name}!") + collection_edm4hep = parsed_edm4hep["datatypes"]["edm4hep::" + datatype] + Members = collection_edm4hep.get("Members", {}) + VectorMembers = collection_edm4hep.get("VectorMembers", {}) + OneToOneRelations = collection_edm4hep.get("OneToOneRelations", {}) + OneToManyRelations = collection_edm4hep.get("OneToOneRelations", {}) + composite_dict = { + **Members, + **VectorMembers, + **OneToOneRelations, + **OneToManyRelations, + } + if collection_name.startswith("_"): + matched_subcol = composite_dict.get( + subcol_name, {"type": "unknown", "doc": "unknown"} + ) + components_edm4hep = parsed_edm4hep["components"].get( + matched_subcol["type"], {"Members": {}} + )["Members"] + composite_dict = {**composite_dict, **components_edm4hep} + + if key is not None: + return composite_dict.get( + branch_name, {"type": "unknown", "doc": "unknown"} + )[key] + return composite_dict.get(branch_name, {"type": "unknown", "doc": "unknown"}) + + def _doc_strings(self, branch_forms, collections): + """ + Assign docstrings for all branches + Docstrings are taken from the comments in edm4hep.yaml + """ + + def assign_doc(branch, doc): + branch["content"]["parameters"]["__doc__"] = doc + return branch + + fieldnames = list(branch_forms.keys()) + for collection in collections: + for name in fieldnames: + slash_split = name.split("/") + if slash_split[0] == collection: + if ( + len(slash_split) > 1 + ): # Ensure that no placeholder branch is allowed + branch_name_split = slash_split[1].split(".") + var_name = branch_name_split[1] + if "[" in branch_name_split[1] and "]" in branch_name_split[1]: + var_name = branch_name_split[1].split("[")[0] + # Assign doc strings to all branches + doc = self._lookup_branch(collection, var_name, "doc") + branch_forms[name] = assign_doc(branch_forms[name], doc) + return branch_forms + + def _process_components(self, branch_forms, all_collections): + """ + Zip all the component types (except if the component is a VectorMember for a datatype) + """ + + def _process(branch_forms, collections): + fieldnames = branch_forms.keys() + for collection in collections: + component_branches = {} + for name in fieldnames: + slash_split = name.split("/") + if slash_split[0] == collection: + if ( + len(slash_split) > 1 + ): # Ensure that no placeholder branch is allowed + branch_name_split = slash_split[1].split(".") + if len(branch_name_split) > 2: + branch_var = branch_name_split[-2] + branch_subvar = branch_name_split[-1] + # skip momentum because it will be used + # later to create 4 vector with E or mass + if branch_var == "momentum": + continue + component = self._lookup_branch(collection, branch_var) + component_type = component["type"] + component_doc = component["doc"] + + component_branches[name] = { + "type": component_type, + "branch_var": branch_var, + "branch_subvar": branch_subvar, + "doc": component_doc, + } + branch_forms = self._zip_components( + collection, component_branches, branch_forms + ) + return branch_forms + + branch_forms = _process(branch_forms, all_collections) + branch_forms = _process( + branch_forms, all_collections + ) # Doing it twice to deal with nested components if at all present + + return branch_forms + + def _process_VectorMembers(self, branch_forms, all_collections): + fieldnames = list(branch_forms.keys()) + + for collection in all_collections: + if collection.startswith("_"): + continue + branch_var = { + name.split("/")[1].split(".")[1]: branch_forms[name] + for name in fieldnames + if (name.split("/")[0] == collection) and (len(name.split("/")) > 1) + } + datatype = self._datatype_mixins.get(collection, None) + if datatype is None: + continue + vec_members = parsed_edm4hep["datatypes"]["edm4hep::" + datatype].get( + "VectorMembers", None + ) + if vec_members is None: + continue + for member in vec_members.keys(): + target_contents = { + name.split("/")[1][1:].split("_")[1]: branch_forms.pop(name) + for name in fieldnames + if name.startswith(f"_{collection}_{member}") + and (len(name.split("/")) > 1) + } + begin_form = branch_var[member + "_begin"] + branch_forms.pop(f"{collection}/{collection}.{member}_begin") + end_form = branch_var[member + "_end"] + branch_forms.pop(f"{collection}/{collection}.{member}_end") + + vars = list(target_contents.keys()) + if len(vars) == 0: + if not vec_members[member]["type"].startswith("edm4hep::"): + # Example : _EventHeader_weights where 'weights' + # is the VectorMember of 'EventHeader' datatype + # ('weights' not to be confused with 'weight' ) + associated_target_form = branch_forms.get( + f"_{collection}_{member}", None + ) + if associated_target_form is None: + continue + branch_forms.pop(f"_{collection}_{member}") + target_form = transforms.begin_end_mapping_form( + begin_form, end_form, associated_target_form + ) + else: + raise RuntimeError(f"_{collection}_{member} not found!") + elif len(vars) == 1: + target_form = transforms.begin_end_mapping_form( + begin_form, end_form, target_contents[vars[0]] + ) + else: + # Example : _TrackCollection_trackStates.D0, _TrackCollection_trackStates.phi, etc. + # where 'trackStates' is the VectorMember of 'TrackStates' component in 'Track' datatype + vec_contents = { + name.split(".")[1]: transforms.begin_end_mapping_form( + begin_form, end_form, targetform + ) + for name, targetform in target_contents.items() + } + vec_contents = {} + for name, targetform in target_contents.items(): + if name.endswith("covMatrix"): + vec_contents[name.split(".")[1]] = ( + transforms.begin_end_mapping_nested_target_form( + begin_form, end_form, targetform + ) + ) + elif name.endswith("referencePoint"): + vec_contents[name.split(".")[1]] = ( + transforms.begin_end_mapping_with_xyzrecord_form( + begin_form, end_form, targetform + ) + ) + else: + vec_contents[name.split(".")[1]] = ( + transforms.begin_end_mapping_form( + begin_form, end_form, targetform + ) + ) + target_form = zip_forms(vec_contents, member) + + branch_forms[f"{collection}/{collection}.{member}"] = target_form + branch_forms[f"{collection}/{collection}.{member}"]["content"][ + "parameters" + ] = {"__doc__": vec_members[member]["doc"]} + + return branch_forms + + def _process_OneToOneRelations(self, branch_forms, all_collections): + fieldnames = list(branch_forms.keys()) + + for collection in all_collections: + if collection.startswith("_"): + continue + # branch_var = { + # name.split("/")[1].split(".")[1]: branch_forms[name] + # for name in fieldnames + # if (name.split("/")[0] == collection) and (len(name.split("/")) > 1) + # } + datatype = self._datatype_mixins.get(collection, None) + if datatype is None: + continue + OneToOneRelations = parsed_edm4hep["datatypes"]["edm4hep::" + datatype].get( + "OneToOneRelations", None + ) + if OneToOneRelations is None: + continue + for member in OneToOneRelations.keys(): + if member in ["from", "to"]: + continue # Skip Link Collections + target_contents = { + name.split("/")[1][1:].split("_")[-1]: branch_forms.pop(name) + for name in fieldnames + if name.startswith(f"_{collection}_{member}") + and (len(name.split("/")) > 1) + } + + vars = list(target_contents.keys()) + if not OneToOneRelations[member]["type"].startswith("edm4hep::"): + raise RuntimeError( + f"{member} does not point to a valid datatype({OneToOneRelations[member]['type']})!" + ) + if len(vars) == 0: + raise RuntimeError(f"_{collection}_{member} not found!") + else: + target_datatype = OneToOneRelations[member]["type"] + matched_collections = [ + collection_name + for collection_name, datatype in self._datatype_mixins.items() + if "edm4hep::" + datatype == target_datatype + ] + # Potential Bug: What if there are more than one collections with the same datatype + # Since We can't the collection ID from the events branch, truly matching collections + # seems impossible here + # For now, lets add the relation to all the matched collections + if len(matched_collections) == 0: + warnings.warn( + f"No matched collection for {target_datatype} found!\n skipping ..." + ) + continue + for matched_collection in matched_collections: + + # grab the offset from one of the branches of the target datatype + target_vars = parsed_edm4hep["datatypes"][target_datatype][ + "Members" + ] + first_var = list(target_vars.keys())[0] + offset_form = branch_forms[ + f"{matched_collection}/{matched_collection}.{first_var}" + ] + target_datatype_offset_form = { + "class": "NumpyArray", + "itemsize": 8, + "format": "i", + "primitive": "int64", + "form_key": concat( + offset_form["form_key"], + "!offsets", + ), + } + + OneToOneRelations_content = { + name.split(".")[1]: targetform + for name, targetform in target_contents.items() + } + OneToOneRelations_content.update( + { + "index_Global": transforms.local2global_form( + index=OneToOneRelations_content["index"], + target_offsets=target_datatype_offset_form, + ) + } + ) + # target_form = zip_forms(OneToOneRelations_content, member) + + # branch_forms[ + # f"{collection}/{collection}.{member}_idx_{matched_collection}" + # ] = target_form + # branch_forms[ + # f"{collection}/{collection}.{member}_idx_{matched_collection}" + # ]["content"]["parameters"] = {"__doc__": OneToOneRelations[member]["doc"]} + + for name, form in OneToOneRelations_content.items(): + branch_forms[ + f"{collection}/{collection}.{member}_idx_{matched_collection}_{name}" + ] = form + branch_forms[ + f"{collection}/{collection}.{member}_idx_{matched_collection}_{name}" + ]["content"]["parameters"] = { + "__doc__": OneToOneRelations[member]["doc"] + } + + return branch_forms + + def _process_OneToManyRelations(self, branch_forms, all_collections): + fieldnames = list(branch_forms.keys()) + + for collection in all_collections: + if collection.startswith("_"): + continue + # print("\ncollection : ", collection) + branch_var = { + name.split("/")[1].split(".")[1]: branch_forms[name] + for name in fieldnames + if (name.split("/")[0] == collection) and (len(name.split("/")) > 1) + } + datatype = self._datatype_mixins.get(collection, None) + if datatype is None: + continue + OneToManyRelations = parsed_edm4hep["datatypes"][ + "edm4hep::" + datatype + ].get("OneToManyRelations", None) + if OneToManyRelations is None: + continue + for member in OneToManyRelations.keys(): + if member in ["from", "to"]: + continue # Skip Link Collections + target_contents = { + name.split("/")[1][1:].split("_")[-1]: branch_forms.pop(name) + for name in fieldnames + if name.startswith(f"_{collection}_{member}") + and (len(name.split("/")) > 1) + } + + # print('\nmember : ', member) + # print('\ntarget_contents.keys() : \n', target_contents.keys()) + begin_form = branch_var[member + "_begin"] + end_form = branch_var[member + "_end"] + branch_forms.pop(f"{collection}/{collection}.{member}_begin") + branch_forms.pop(f"{collection}/{collection}.{member}_end") + + vars = list(target_contents.keys()) + if not OneToManyRelations[member]["type"].startswith("edm4hep::"): + raise RuntimeError( + f"{member} does not point to a valid datatype({OneToManyRelations[member]['type']})!" + ) + if len(vars) == 0: + raise RuntimeError(f"_{collection}_{member} not found!") + else: + target_datatype = OneToManyRelations[member]["type"] + # print('\ntarget_datatype : ', target_datatype) + matched_collections = [ + collection_name + for collection_name, datatype in self._datatype_mixins.items() + if "edm4hep::" + datatype == target_datatype + ] + # Potential problem: What if there are more than one collections with the same datatype + # Since We can't get the collection ID from the events branch, truly matching collections + # seems impossible here + # For now, lets add the relation to all the matched collections + if len(matched_collections) == 0: + # Might be the TrackerHit Interface + if target_datatype in list(parsed_edm4hep["interfaces"].keys()): + # What datatypes does it interface to? + interfaced_datatypes = parsed_edm4hep["interfaces"][ + target_datatype + ]["Types"] + matched_collections = [] + for i in interfaced_datatypes: + for ( + col_name, + datatype_name, + ) in self._datatype_mixins.items(): + if "edm4hep::" + datatype_name == i: + matched_collections.append(col_name) + # Or maybe not + else: + raise RuntimeError( + f"No matched collection for {target_datatype} found!" + ) + + for matched_collection in matched_collections: + + # print("\nmatched_collection : ", matched_collection) + # grab the offset from one of the branches of the target datatype + target_datatype = self._datatype_mixins.get( + matched_collection, None + ) + if target_datatype is None: + raise RuntimeError() + # print("\ntarget_datatype : ", target_datatype) + target_vars = parsed_edm4hep["datatypes"][ + "edm4hep::" + target_datatype + ]["Members"] + first_var = list(target_vars.keys())[0] + # print("\nfirst_var from target_vars: ", first_var) + offset_form = branch_forms[ + f"{matched_collection}/{matched_collection}.{first_var}" + ] + # print(collection) + # print(f'{matched_collection}/{matched_collection}.{first_var}') + target_datatype_offset_form = { + "class": "NumpyArray", + "itemsize": 8, + "format": "i", + "primitive": "int64", + "form_key": concat( + offset_form["form_key"], + "!offsets", + ), + } + first_var = list(branch_var.keys())[0] + # print("\nfirst_var from branch_var: ", first_var) + zip_offset_form = branch_var[first_var] + zip_datatype_offset_form = copy.deepcopy( + target_datatype_offset_form + ) + zip_datatype_offset_form["form_key"] = concat( + zip_offset_form["form_key"], "!offsets" + ) + + OneToManyRelations_content = { + name.split(".")[1]: transforms.begin_end_mapping_form( + begin_form, end_form, targetform + ) + for name, targetform in target_contents.items() + } + # print('\nOneToManyRelations_content :\n', OneToManyRelations_content) + # OneToManyRelations_content_global = { + # name.split(".")[1] + # + "_Global": transforms.global_begin_end_range_form( + # copy.deepcopy(begin_form), + # copy.deepcopy(end_form), + # copy.deepcopy(targetform), + # copy.deepcopy(target_datatype_offset_form), + # ) + # for name, targetform in target_contents.items() + # if name.split(".")[1] == "index" + # } + OneToManyRelations_content_global = { + name + + "_Global": transforms.nested_local2global_form( + form, + target_datatype_offset_form, + ) + for name, form in OneToManyRelations_content.items() + if name == "index" + } + # print('\nOneToManyRelations_content_global :\n', OneToManyRelations_content_global) + + to_zip = { + **OneToManyRelations_content, + **OneToManyRelations_content_global, + } + # target_form = zip_forms(to_zip, member, offsets=zip_datatype_offset_form) + + # branch_forms[ + # f"{collection}/{collection}.{member}_idx_{matched_collection}" + # ] = target_form + # branch_forms[ + # f"{collection}/{collection}.{member}_idx_{matched_collection}" + # ]["content"]["parameters"] = {"__doc__": OneToManyRelations[member]["doc"]} + + # branch_forms[ + # f"Special_Branch_{member}_idx_{matched_collection}/Special_Branch_{member}_idx_{matched_collection}.{member}_idx_{matched_collection}" + # ] = target_form + + for key, form in to_zip.items(): + branch_forms[ + f"{collection}/{collection}.{member}_idx_{matched_collection}_{key}" + ] = form + branch_forms[ + f"{collection}/{collection}.{member}_idx_{matched_collection}_{key}" + ]["content"]["parameters"] = { + "__doc__": OneToManyRelations[member]["doc"] + } + + return branch_forms + + def _process_Links(self, branch_forms, all_collections): + fieldnames = list(branch_forms.keys()) + + for collection in all_collections: + if collection.startswith("_"): + continue + # branch_var = { + # name.split("/")[1].split(".")[1]: branch_forms[name] + # for name in fieldnames + # if (name.split("/")[0] == collection) and (len(name.split("/")) > 1) + # } + datatype = self._datatype_mixins.get(collection, None) + if datatype is None: + continue + OneToOneRelations = parsed_edm4hep["datatypes"]["edm4hep::" + datatype].get( + "OneToOneRelations", None + ) + if OneToOneRelations is None: + continue + if not all( + link_name in OneToOneRelations.keys() for link_name in ["from", "to"] + ): + continue + set_matched_collections = set() + dict_branches_to_copy = {} + dict_docs_of_branches = {} + for member in OneToOneRelations.keys(): + if member in ["from", "to"]: + target_contents = { + name.split("/")[1][1:].split("_")[1]: branch_forms.pop(name) + for name in fieldnames + if name.startswith(f"_{collection}_{member}") + and (len(name.split("/")) > 1) + } + + vars = list(target_contents.keys()) + if not OneToOneRelations[member]["type"].startswith("edm4hep::"): + raise RuntimeError( + f"{member} does not point to a valid datatype({OneToOneRelations[member]['type']})!" + ) + if len(vars) == 0: + raise RuntimeError(f"_{collection}_{member} not found!") + else: + target_datatype = OneToOneRelations[member]["type"] + matched_collections = [ + collection_name + for collection_name, datatype in self._datatype_mixins.items() + if "edm4hep::" + datatype == target_datatype + ] + + if len(matched_collections) == 0: + # Might be the TrackerHit Interface + if target_datatype in list( + parsed_edm4hep["interfaces"].keys() + ): + # What datatypes does it interface to? + interfaced_datatypes = parsed_edm4hep["interfaces"][ + target_datatype + ]["Types"] + matched_collections = [] + for i in interfaced_datatypes: + for ( + col_name, + datatype_name, + ) in self._datatype_mixins.items(): + if "edm4hep::" + datatype_name == i: + matched_collections.append(col_name) + # Or maybe not + else: + raise RuntimeError( + f"No matched collection for {target_datatype} found!" + ) + + for matched_collection in matched_collections: + + # grab the offset from one of the branches of the target datatype + target_datatype = self._datatype_mixins.get( + matched_collection, None + ) + if target_datatype is None: + raise RuntimeError() + target_vars = parsed_edm4hep["datatypes"][ + "edm4hep::" + target_datatype + ]["Members"] + first_var = list(target_vars.keys())[0] + offset_form = branch_forms[ + f"{matched_collection}/{matched_collection}.{first_var}" + ] + + target_datatype_offset_form = { + "class": "NumpyArray", + "itemsize": 8, + "format": "i", + "primitive": "int64", + "form_key": concat( + offset_form["form_key"], + "!offsets", + ), + } + + OneToOneRelations_content = { + name.split(".")[1]: targetform + for name, targetform in target_contents.items() + } + OneToOneRelations_content.update( + { + "index_Global": transforms.local2global_form( + index=OneToOneRelations_content["index"], + target_offsets=target_datatype_offset_form, + ) + } + ) + + target_form = zip_forms(OneToOneRelations_content, member) + branch_forms[ + f"{collection}/{collection}.Link_{member}_{matched_collection}" + ] = target_form + branch_forms[ + f"{collection}/{collection}.Link_{member}_{matched_collection}" + ]["parameters"] = { + "__doc__": OneToOneRelations[member]["doc"] + } + # Also copy this to the matched_collections + # First collect all the branches that need to be copied + do_copy = False + if self.copy_links_to_target_datatype: + if len(self._datatype_priority.keys()) == 0: + raise RuntimeError( + "Cannot copy links if no priority is given!" + ) + if len(matched_collections) > 1: + # Choose which one to copy + priority = self._datatype_priority[target_datatype] + if matched_collection == priority: + do_copy = True + else: + do_copy = True + if do_copy: + if member == "from": + set_matched_collections.update({matched_collection}) + dict_branches_to_copy.update( + {f"Link_{member}_{matched_collection}": target_form} + ) + dict_docs_of_branches.update( + { + f"Link_{member}_{matched_collection}": OneToOneRelations[ + member + ][ + "doc" + ] + } + ) + + # Finally, copy the available branches to the set of matched_collections + if self.copy_links_to_target_datatype: + for matched_collection in set_matched_collections: + for name in dict_branches_to_copy.keys(): + branch_forms[ + f"{matched_collection}/{matched_collection}.{name}" + ] = dict_branches_to_copy[name] + branch_forms[ + f"{matched_collection}/{matched_collection}.{name}" + ]["content"]["parameters"] = { + "__doc__": dict_docs_of_branches[name] + } + + return branch_forms + + def _make_collections(self, output, branch_forms): + """ + Process branches to form a collection + Example: + "ReconstructedParticles/ReconstructedParticles.energy", + "ReconstructedParticles/ReconstructedParticles.charge", + "ReconstructedParticles/ReconstructedParticles.mass", + "ReconstructedParticles/ReconstructedParticles.referencePoint"(subcollection containing x,y,z), + ... + etc + are zipped together to form the "ReconstructedParticles" collection. + The momentum.[x,y,z] branches along with the energy branch (if available) are used to + provide the vector.LorentzVector behavior to the collection. + """ + field_names = list(branch_forms.keys()) + + # Extract the regular collection names + # Example collections: {'Jet', 'ReconstructedParticles', 'MCRecoAssociations', ...} + collections = { + collection_name.split("/")[0] + for collection_name in field_names + if _all_collections.match(collection_name) + } + + # Zip the collections + # Example: 'ReconstructedParticles' + for name in collections: + # Get the mixin class for the collection, if available, otherwise "NanoCollection" by default + mixin = self._datatype_mixins.get(name, "NanoCollection") + + # Content to be zipped together + # Example collection_content: {'type':, 'energy':, 'momentum.x': ...} + collection_content = { + k[(2 * len(name) + 2) :]: branch_forms.pop(k) + for k in field_names + if k.startswith(f"{name}/{name}.") + } + + # Change the name of momentum fields, to facilitate the vector.LorentzVector behavior + # 'energy' --> 'E' + # 'momentum.x' --> 'px' + # 'momentum.y' --> 'py' + # 'momentum.z' --> 'pz' + collection_content = { + (k.replace(k, self._replacement[k]) if k in self._replacement else k): v + for k, v in collection_content.items() + } + + first_var_form = collection_content[list(collection_content.keys())[0]] + # print(f"offset variable taken for {name} : ", list(collection_content.keys())[0]) + offset_form = { + "class": "NumpyArray", + "itemsize": 8, + "format": "i", + "primitive": "int64", + "form_key": concat( + first_var_form["form_key"], + "!offsets", + ), + } + + output[name] = zip_forms( + sort_dict(collection_content), + name, + record_name=mixin, + offsets=offset_form, + ) + # Update some metadata + if mixin != "NanoCollection": + output[name]["content"]["parameters"].update( + { + "collection_name": name, + "__doc__": parsed_edm4hep["datatypes"]["edm4hep::" + mixin].get( + "Description", mixin + ), + } + ) + + # Remove grouping branches which are generated from BaseSchema and contain no usable info + # Example: Along with the "Jet/Jet.type","Jet/Jet.energy",etc., BaseSchema may produce "Jet" grouping branch. + # It is an empty branch and needs to be removed + if name in field_names: + branch_forms.pop(name) + + return output, branch_forms + + def _unknown_collections(self, output, branch_forms, all_collections): + """ + Process all the unknown, empty or faulty branches that remain + after creating all the collections. + Should be called only after creating all the other relevant collections. + + Note: It is not a neat implementation and needs more testing. + """ + unlisted = copy.deepcopy(branch_forms) + for name, content in unlisted.items(): + if content["class"] == "ListOffsetArray": + if content["content"]["class"] == "RecordArray": + # Remove empty branches + if len(content["content"]["fields"]) == 0: + branch_forms.pop(name) + continue + elif content["content"]["class"] == "RecordArray": + # Remove empty branches + if len(content["contents"]) == 0: + continue + # If a branch is non-empty and is one of its kind (i.e. has no other associated branch) + # call it a singleton and assign it directly to the output + else: + # Singleton branch + output[name] = branch_forms.pop(name) + elif content["class"] == "RecordArray": + # Remove empty branches + if len(content["contents"]) == 0: + continue + else: + # If the branch is not empty, try to make a collection + # assuming good behavior of the branch + # Note: It's unlike that such a branch exists + + # Extract the collection name from the branch + record_name = name.split("/")[0] + + # Contents to be zipped + contents = { + k[2 * len(record_name) + 2 :]: branch_forms.pop(k) + for k in unlisted.keys() + if k.startswith(record_name + "/") + } + if len(list(contents.keys())) == 0: + continue + output[record_name] = zip_forms( + sort_dict(contents), + record_name, + self._datatype_mixins.get(record_name, "NanoCollection"), + ) + # If a branch is non-empty and is one of its kind (i.e. has no other associated branch) + # call it a singleton and assign it directly to the output + else: + output[name] = content + + return output, branch_forms + + def _build_collections(self, field_names, input_contents): + """ + Builds all the collections with the necessary behaviors defined in the mixins dictionary + """ + branch_forms = {k: v for k, v in zip(field_names, input_contents)} + + # All collection names + # Example: ReconstructedParticles or _ReconstructedParticle_clusters, etc + all_collections = { + collection_name.split("/")[0] + for collection_name in field_names + if _all_collections.match(collection_name) + } + + output = {} + branch_forms = self._doc_strings(branch_forms, all_collections) + + branch_forms = self._process_components(branch_forms, all_collections) + branch_forms = self._process_VectorMembers(branch_forms, all_collections) + branch_forms = self._process_OneToOneRelations(branch_forms, all_collections) + branch_forms = self._process_OneToManyRelations(branch_forms, all_collections) + branch_forms = self._process_Links(branch_forms, all_collections) + + output, branch_forms = self._make_collections(output, branch_forms) + + # Process all the other unknown/faulty/empty/singleton branches + output, branch_forms = self._unknown_collections( + output, branch_forms, all_collections + ) + + # sort the output by key + # output = sort_dict(branch_forms) + output = sort_dict(output) + + return output.keys(), output.values() + + @classmethod + def behavior(cls): + """Behaviors necessary to implement this schema""" + from coffea.nanoevents.methods import base, edm4hep + + behavior = {} + behavior.update(base.behavior) + behavior.update(vector.behavior) + behavior.update(edm4hep.behavior) + return behavior diff --git a/src/coffea/nanoevents/schemas/fcc.py b/src/coffea/nanoevents/schemas/fcc.py index aa8e922b4..31af6c113 100644 --- a/src/coffea/nanoevents/schemas/fcc.py +++ b/src/coffea/nanoevents/schemas/fcc.py @@ -4,6 +4,7 @@ from coffea.nanoevents import transforms from coffea.nanoevents.methods import vector from coffea.nanoevents.schemas.base import BaseSchema, zip_forms +from coffea.nanoevents.schemas.edm4hep import EDM4HEPSchema from coffea.nanoevents.util import concat # Collection Regex # @@ -594,17 +595,68 @@ def behavior(cls): return behavior +class FCCSchema_edm4hep1(EDM4HEPSchema): + """ + Schema-builder for Future Circular Collider pregenerated samples. + https://fcc-physics-events.web.cern.ch/ + + This schema supports FCC samples produced with edm4hep version >= 1. It inherits + from the EDM4HEPSchema and adds a few more functionality. + + For more info, check EDM4HEPSchema + """ + + _datatype_mixins = { + "CalorimeterHits": "CalorimeterHit", + "EFlowNeutralHadron": "Cluster", + "EFlowPhoton": "Cluster", + "EFlowTrack": "Track", + "EFlowTrack_dNdx": "RecDqdx", + "Electron_objIdx": "ObjectID", + "EventHeader": "EventHeader", + "Jet": "ReconstructedParticle", + "MCRecoAssociations": "RecoMCParticleLink", + "Muon_objIdx": "ObjectID", + "Particle": "MCParticle", + "ParticleIDs": "ParticleID", + "Photon_objIdx": "ObjectID", + "ReconstructedParticles": "ReconstructedParticle", + "TrackerHits": "TrackerHit3D", + } + + copy_links_to_target_datatype = True + + # Which collection to match if there are multiple matching collections for a given datatype + _datatype_priority = {"ReconstructedParticle": "ReconstructedParticles"} + + @classmethod + def behavior(cls): + """Behaviors necessary to implement this schema""" + from coffea.nanoevents.methods import base, fcc + + behavior = {} + behavior.update(base.behavior) + behavior.update(vector.behavior) + behavior.update(fcc.behavior_edm4hep1) + return behavior + + class FCC: """ Class to choose the required variant of FCCSchema Example: from coffea.nanoevents import FCC FCC.get_schema(version='latest') + latest --> FCCSchema_edm4hep1 + pre-edm4hep1 --> FCCSchema + edm4hep1 --> FCCSchema_edm4hep1 - Note: For now, only one variant is available, called the latest version, that points - to the fcc.FCCSchema class. This schema has been made keeping the Spring2021 pre-generated samples. + Note: FCCSchema --> This schema has been made keeping the Spring2021 pre-generated samples (pre-edm4hep1). Its also tested with Winter2023 samples with the uproot_options={"filter_name": lambda x : "PARAMETERS" not in x} parameter when loading the fileset. This removes the "PARAMETERS" branch that is unreadable in uproot afaik. More Schema variants could be added later. + + FCCSchema_edm4hep1 --> This schema supports FCC samples produced with edm4hep version >= 1. It inherits + from the EDM4HEPSchema and adds a few more functionality. """ def __init__(self, version="latest"): @@ -613,6 +665,10 @@ def __init__(self, version="latest"): @classmethod def get_schema(cls, version="latest"): if version == "latest": + return FCCSchema_edm4hep1 + elif version == "pre-edm4hep1": return FCCSchema + elif version == "edm4hep1": + return FCCSchema_edm4hep1 else: pass diff --git a/src/coffea/nanoevents/transforms.py b/src/coffea/nanoevents/transforms.py index 74f122dc5..64ba20548 100644 --- a/src/coffea/nanoevents/transforms.py +++ b/src/coffea/nanoevents/transforms.py @@ -219,13 +219,12 @@ def begin_and_end_to_counts(stack): @numba.njit -def _index_range_kernel(begin_end, target, builder): +def _index_range_kernel(begin_end, target, builder, type_real=False): for ev in range(len(begin_end)): builder.begin_list() for j in range(len(begin_end[ev])): builder.begin_list() for k in range(begin_end[ev][j][0], begin_end[ev][j][1]): - # builder.integer(k) builder.integer(target[ev][k]) builder.end_list() builder.end_list() @@ -282,20 +281,494 @@ def index_range(stack): begin_end = awkward.concatenate( (begin[:, :, numpy.newaxis], end[:, :, numpy.newaxis]), axis=2 ) - out = awkward.Array( _index_range_kernel(begin_end, target, awkward.ArrayBuilder()).snapshot() ) + out = index_range_global_index(out, begin, end) + stack.append(out) + +def index_range_global_index(array, begin, target): + """Helper function for index_range""" # Convert to global index - counts2 = awkward.flatten(awkward.num(out, axis=2), axis=1) + if awkward.sum(array) != 0: + return nested_local2global(array, begin.layout.offsets.data) + elif awkward.sum(array) == 0: + return awkward.flatten( + awkward.full_like( + awkward.values_astype(begin, "int64")[:, :, numpy.newaxis], "-1" + ), + axis=1, + ) + + +def nested_local2global(array, target_offsets_raw): + counts2 = awkward.flatten(awkward.num(array, axis=2), axis=1) + # flat_index = awkward.values_astype(awkward.flatten(awkward.local_index(array), axis=2),"int64") + flat_index = awkward.values_astype(awkward.flatten(array, axis=2), "int64") + + target_offsets = awkward.values_astype(target_offsets_raw, "int64") + + flat_index = flat_index.mask[flat_index >= 0] + target_offsets[:-1] + flat_index = flat_index.mask[flat_index < target_offsets[1:]] + out = ensure_array(awkward.flatten(awkward.fill_none(flat_index, -1), axis=None)) + if out.dtype != numpy.int64: + raise RuntimeError + + nested_global = awkward.unflatten(out, counts2, axis=0) + return nested_global + + +def nested_local2global_stack(stack): + target_offsets_raw = stack.pop() + array = stack.pop() + counts1 = awkward.num(array, axis=1) + counts2 = awkward.flatten(awkward.num(array, axis=2), axis=1) + + if awkward.sum(counts2) == 0: # Empty indices + # print('Empty Indices') + nested_global = array + else: + + # flat_index = awkward.values_astype(awkward.flatten(awkward.local_index(array), axis=2),"int64") + flat_index = awkward.values_astype(awkward.flatten(array, axis=2), "int64") + + target_offsets = awkward.values_astype(target_offsets_raw, "int64") + + flat_index = flat_index.mask[flat_index >= 0] + target_offsets[:-1] + flat_index = flat_index.mask[flat_index < target_offsets[1:]] + out = ensure_array( + awkward.flatten(awkward.fill_none(flat_index, -1), axis=None) + ) + + # if out.dtype != numpy.int64: + # raise RuntimeError + + nested_global_flat = awkward.unflatten(out, counts2, axis=0) + nested_global = awkward.unflatten(nested_global_flat, counts1, axis=0) + # print(nested_global) + stack.append(nested_global) + + +def nested_local2global_form(array_form, target_offsets_form): + if not array_form["class"].startswith("ListOffset"): + raise RuntimeError + if not target_offsets_form["class"].startswith("NumpyArray"): + raise RuntimeError + form = copy.deepcopy(array_form) + form["content"]["content"]["primitive"] = "int64" + form["content"]["content"]["form_key"] = concat( + array_form["form_key"], + target_offsets_form["form_key"], + "!nested_local2global_stack", + "!content", + "!content", + ) + return form + + +def get_index_ranges(begin, end): + begin_end = awkward.concatenate( + (begin[:, :, numpy.newaxis], end[:, :, numpy.newaxis]), axis=2 + ) + + @numba.njit + def get_index_ranges_kernel(begin_end, builder): + for ev in range(len(begin_end)): + builder.begin_list() + for j in range(len(begin_end[ev])): + builder.begin_list() + for k in range(begin_end[ev][j][0], begin_end[ev][j][1]): + builder.integer(k) + builder.end_list() + builder.end_list() + return builder + + ranges = get_index_ranges_kernel(begin_end, awkward.ArrayBuilder()).snapshot() + + offset1 = ranges.layout.offsets + offset2 = ranges.layout.content.offsets + return ranges, offset1, offset2 + + +def get_array_from_indices(indices, target): + @numba.jit + def get_array_from_indices_kernel(indices, target, builder): + for ev in range(len(indices)): + builder.begin_list() + for j in range(len(indices[ev])): + builder.begin_list() + for k in indices[ev][j]: + builder.real(target[ev][k]) + builder.end_list() + builder.end_list() + return builder + + @numba.jit + def get_array_from_indices_nested_target_kernel(indices, target, builder): + for ev in range(len(indices)): + builder.begin_list() + for j in range(len(indices[ev])): + builder.begin_list() + for k in indices[ev][j]: + builder.begin_list() + for num in target[ev][k]: + builder.real(num) + builder.end_list() + builder.end_list() + builder.end_list() + return builder + + if target.ndim == 2: + return get_array_from_indices_kernel( + indices, target, awkward.ArrayBuilder() + ).snapshot() + elif target.ndim == 3: + return get_array_from_indices_nested_target_kernel( + indices, target, awkward.ArrayBuilder() + ).snapshot() + else: + raise RuntimeError(f"Target array \n\t{target}\n is highly nested.") + + +def begin_end_mapping(stack): + target = stack.pop() + end = stack.pop() + begin = stack.pop() + indices, o1, o2 = get_index_ranges(begin, end) + + if awkward.sum(awkward.num(target, axis=1)) == 0: # Empty Target + out = indices[indices < 0] # return an empty array + else: + if awkward.sum(awkward.num(indices, axis=1)) == 0: # Empty Indices + out = indices[indices < 0] # return an empty array + else: # The usual case when both of the indices and target are non-empty + out = get_array_from_indices(awkward.fill_none(indices, -1), target) + # out = indices + + # out = awkward.flatten(out, axis=1) + # out = awkward.Array( + # awkward.contents.ListOffsetArray( + # out.layout.content.offsets, + # out.layout.content.content, + # ) + # ) + stack.append(out) + + +def begin_end_mapping_form(begin_form, end_form, target_form): + if not begin_form["class"].startswith("ListOffset"): + raise RuntimeError + if not end_form["class"].startswith("ListOffset"): + raise RuntimeError + if not target_form["class"].startswith("ListOffset"): + raise RuntimeError + form = { + "class": "ListOffsetArray", + "offsets": "i64", + "content": { + "class": "ListOffsetArray", + "offsets": "i64", + "content": { + "class": "NumpyArray", + "itemsize": 8, + "format": "i", + "primitive": "float64", + }, + }, + } + key = concat( + begin_form["form_key"], + end_form["form_key"], + target_form["form_key"], + "!begin_end_mapping", + ) + + form["form_key"] = key # Axis 1 offsets + form["content"]["form_key"] = concat(key, "!content") # Axis 2 offsets + form["content"]["content"]["form_key"] = concat( + key, "!content", "!content" + ) # Content + # form["form_key"] = key #Axis 1 offsets + # form["content"]["form_key"] = key #Axis 2 offsets + # form["content"]["content"]["form_key"] = concat(key, "!content") #Content + + return form + + +def begin_end_mapping_nested_target_form(begin_form, end_form, target_form): + if not begin_form["class"].startswith("ListOffset"): + raise RuntimeError + if not end_form["class"].startswith("ListOffset"): + raise RuntimeError + if not target_form["class"].startswith("ListOffset"): + raise RuntimeError + form = { + "class": "ListOffsetArray", + "offsets": "i64", + "content": { + "class": "ListOffsetArray", + "offsets": "i64", + "content": { + "class": "ListOffsetArray", + "offsets": "i64", + "content": { + "class": "NumpyArray", + "itemsize": 8, + "format": "i", + "primitive": "float64", + }, + }, + }, + } + key = concat( + begin_form["form_key"], + end_form["form_key"], + target_form["form_key"], + "!begin_end_mapping", + ) + + form["form_key"] = key # Axis 1 offsets + form["content"]["form_key"] = concat(key, "!content") # Axis 2 offsets + form["content"]["content"]["form_key"] = concat( + key, "!content", "!content" + ) # Axis 3 offsets + form["content"]["content"]["content"]["form_key"] = concat( + key, "!content", "!content", "!content" + ) # Content + return form + + +def get_array_from_indices_xyzrecord_target(indices, target): + @numba.jit + def get_array_from_indices_xyzrecord_target_kernel(indices, target, builder): + for ev in range(len(indices)): + builder.begin_list() + for j in range(len(indices[ev])): + builder.begin_list() + for k in indices[ev][j]: + builder.begin_record() + builder.field("x").real(target[ev][k]["x"]) + builder.field("y").real(target[ev][k]["y"]) + builder.field("z").real(target[ev][k]["z"]) + builder.end_record() + builder.end_list() + builder.end_list() + return builder + + return get_array_from_indices_xyzrecord_target_kernel( + indices, target, awkward.ArrayBuilder() + ).snapshot() + + +def begin_end_mapping_with_xyzrecord(stack): + target = stack.pop() + end = stack.pop() + begin = stack.pop() + indices, o1, o2 = get_index_ranges(begin, end) + + if len(target.fields) == 0: # Target is a ListOffset type + raise RuntimeError("Target is a ListOffset.") + else: # Target is a Record type + # target_fields = numpy.array([str(field) for field in target.fields]) + # print(target_fields) + if awkward.sum(awkward.num(target, axis=1)) == 0: # Empty Target + out = indices[indices < 0] # return an empty array + else: + if awkward.sum(awkward.num(indices, axis=1)) == 0: # Empty Indices + out = indices[indices < 0] # return an empty array + else: # The usual case when both of the indices and target are non-empty + out = get_array_from_indices_xyzrecord_target(indices, target) + stack.append(out) + + +def begin_end_mapping_with_xyzrecord_form(begin_form, end_form, target_form): + if not begin_form["class"].startswith("ListOffset"): + raise RuntimeError + if not end_form["class"].startswith("ListOffset"): + raise RuntimeError + if not target_form["class"].startswith("ListOffset"): + if not target_form["content"]["class"].startswith("RecordArray"): + raise RuntimeError + form = { + "class": "ListOffsetArray", + "offsets": "i64", + "content": { + "class": "ListOffsetArray", + "offsets": "i64", + # "content": { + # "class": "NumpyArray", + # "itemsize": 8, + # "format": "i", + # "primitive": 'float64', + # }, + "content": target_form["content"], + }, + } + key = concat( + begin_form["form_key"], + end_form["form_key"], + target_form["form_key"], + "!begin_end_mapping", + ) + + form["form_key"] = key # Axis 1 offsets + form["content"]["form_key"] = concat(key, "!content") # Axis 2 offsets + form["content"]["content"]["form_key"] = concat( + key, "!content", "!content" + ) # Content + + return form + + +@numba.njit +def _begin_end_range_kernel(begin_end, builder): + for ev in range(len(begin_end)): + builder.begin_list() + for j in range(len(begin_end[ev])): + builder.begin_list() + for k in range(begin_end[ev][j][0], begin_end[ev][j][1]): + # builder.integer(target_local_index[ev][k]) + builder.integer(k) + builder.end_list() + builder.end_list() + return builder + + +def begin_end_range_form(begin_form, end_form, target_form): + if not begin_form["class"].startswith("ListOffset"): + raise RuntimeError + if not end_form["class"].startswith("ListOffset"): + raise RuntimeError + if not target_form["class"].startswith("ListOffset"): + raise RuntimeError + form = { + "class": "ListOffsetArray", + "offsets": "i64", + "content": { + "class": "ListOffsetArray", + "offsets": "i64", + "content": target_form["content"], + "form_key": concat( + begin_form["form_key"], + end_form["form_key"], + target_form["form_key"], + "!begin_end_range", + ), + }, + # "form_key": concat( + # begin_form["form_key"], + # end_form["form_key"], + # target_form["form_key"], + # "!begin_end_range", + # ), + "form_key": begin_form["form_key"], # this is used to extract event offsets + } + form["content"]["content"]["form_key"] = concat( + begin_form["form_key"], + end_form["form_key"], + target_form["form_key"], + "!begin_end_range", + "!content", + ) + return form + + +def begin_end_range(stack): + """ + Takes in begin and end arrays and a target array. + This is the process: + Get ranges (double nesting) of begin to end + Corresponding to those index ranges, pick up elements from the target array(which are also indices) + """ + target = stack.pop() + end = stack.pop() + begin = stack.pop() + begin_end = awkward.concatenate( + (begin[:, :, numpy.newaxis], end[:, :, numpy.newaxis]), axis=2 + ) + + # Create the index ranges + indices = awkward.Array( + _begin_end_range_kernel(begin_end, awkward.ArrayBuilder()).snapshot() + ) + + # Map the index ranges onto target array + flat2_indices = awkward.flatten(indices, axis=2) + counts2 = awkward.flatten(awkward.num(indices, axis=2), axis=1) + flat2_out = target[flat2_indices] + out = awkward.unflatten(flat2_out, counts2, axis=1) + + # flatten across axis=1 + out = awkward.flatten(out, axis=1) + + stack.append(out) + + +def global_begin_end_range_form(begin_form, end_form, target_form, offsets_form): + if not begin_form["class"].startswith("ListOffset"): + raise RuntimeError + if not end_form["class"].startswith("ListOffset"): + raise RuntimeError + if not target_form["class"].startswith("ListOffset"): + raise RuntimeError + if not offsets_form["class"].startswith("NumpyArray"): + raise RuntimeError + key = concat( + begin_form["form_key"], + end_form["form_key"], + target_form["form_key"], + offsets_form["form_key"], + "!global_begin_end_range", + ) + content_level1 = copy.deepcopy(target_form["content"]) + content_level1["primitive"] = ( + "int64" # making sure the content dtype is int64 because mismatching dtypes cause a LOT of trouble + ) + form = { + "class": "ListOffsetArray", + "offsets": "i64", + "content": { + "class": "ListOffsetArray", + "offsets": "i64", + "content": content_level1, + "form_key": key, + }, + # "form_key": key, # this is used to extract event offsets + "form_key": begin_form["form_key"], + } + form["content"]["content"]["form_key"] = concat(key, "!content") + return form + + +def global_begin_end_range(stack): + """ + Takes in begin and end arrays and a target array. + This is the process: + Get ranges (double nesting) of begin to end + Corresponding to those index ranges, pick up elements from the target array(which are also indices) + """ + offsets = stack.pop() + target = stack.pop() + end = stack.pop() + begin = stack.pop() + begin_end = awkward.concatenate( + (begin[:, :, numpy.newaxis], end[:, :, numpy.newaxis]), axis=2 + ) + + # Create the index ranges + indices = awkward.Array( + _begin_end_range_kernel(begin_end, awkward.ArrayBuilder()).snapshot() + ) - out = awkward.flatten(out, axis=2) - stack2 = [out, begin.layout.offsets.data] - local2global(stack2) - out = stack2.pop() + # Map the index ranges onto target array + flat2_indices = awkward.flatten(indices, axis=2) + counts2 = awkward.flatten(awkward.num(indices, axis=2), axis=1) + flat2_out = target[flat2_indices] + out = awkward.unflatten(flat2_out, counts2, axis=1) - out = awkward.unflatten(out, counts2, axis=0) + # Convert to global indices + out = nested_local2global(out, offsets) stack.append(out) diff --git a/tests/samples/edm4hep.root b/tests/samples/edm4hep.root new file mode 100644 index 0000000000000000000000000000000000000000..b3d6f18c7810cbe478f03bc3b9012f00f79b9a9e GIT binary patch literal 116051 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 literal 0 HcmV?d00001 diff --git a/tests/samples/p8_ee_WW_ecm240_edm4hep.root b/tests/samples/p8_ee_WW_ecm240_edm4hep.root new file mode 100644 index 0000000000000000000000000000000000000000..536243d7e78bf78ed1f2cd00a93a5bd72e69ffbc GIT binary patch literal 189503 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 z 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%0A4ky^g2BA-I%5=?!= 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 VePjakJ`PQDWCub_e{{Tm=g7E+V literal 0 HcmV?d00001 diff --git a/tests/test_nanoevents_edm4hep.py b/tests/test_nanoevents_edm4hep.py new file mode 100755 index 000000000..3f236275b --- /dev/null +++ b/tests/test_nanoevents_edm4hep.py @@ -0,0 +1,87 @@ +import os + +import awkward +import pytest + +from coffea.nanoevents import EDM4HEPSchema, NanoEventsFactory + + +def _events(**kwargs): + # Original sample generated from key4hep workflow + path = os.path.abspath("tests/samples/edm4hep.root") + factory = NanoEventsFactory.from_root( + {path: "events"}, schemaclass=EDM4HEPSchema, **kwargs + ) + return factory.events() + + +@pytest.fixture(scope="module") +def eager_events(): + return _events(delayed=False) + + +@pytest.fixture(scope="module") +def delayed_events(): + return _events(delayed=True) + + +@pytest.mark.parametrize( + "field", + [ + "CaloHitContributionCollection", + "CaloHitMCParticleLinkCollection", + "CaloHitSimCaloHitLinkCollection", + "CalorimeterHitCollection", + "ClusterCollection", + "ClusterMCParticleLinkCollection", + "EventHeader", + "GPDoubleKeys", + "GPDoubleValues", + "GPFloatKeys", + "GPFloatValues", + "GPIntKeys", + "GPIntValues", + "GPStringKeys", + "GPStringValues", + "GeneratorEventParametersCollection", + "GeneratorPdfInfoCollection", + "MCParticleCollection", + "ParticleIDCollection", + "RawCalorimeterHitCollection", + "RawTimeSeriesCollection", + "RecDqdxCollection", + "RecoMCParticleLinkCollection", + "ReconstructedParticleCollection", + "SimCalorimeterHitCollection", + "SimTrackerHitCollection", + "TimeSeriesCollection", + "TrackCollection", + "TrackMCParticleLinkCollection", + "TrackerHit3DCollection", + "TrackerHitPlaneCollection", + "TrackerHitSimTrackerHitLinkCollection", + "VertexCollection", + "VertexRecoParticleLinkCollection", + ], +) +def test_field_is_present(eager_events, delayed_events, field): + eager_fields = eager_events.fields + delayed_fields = delayed_events.fields + assert field in eager_fields + assert field in delayed_fields + + +def test_MC_daughters(delayed_events): + d = delayed_events.MCParticleCollection.Map_Relation( + "daughters", "MCParticleCollection" + ).compute() + assert isinstance(d, awkward.highlevel.Array) + assert d.layout.branch_depth[1] == 3 + + +def test_MC_parents(delayed_events): + p = delayed_events.MCParticleCollection.Map_Relation( + "parents", "MCParticleCollection" + ).compute() + assert isinstance(p, awkward.highlevel.Array) + assert p.layout.branch_depth[1] == 3 diff --git a/tests/test_nanoevents_fcc_edm4hep1.py b/tests/test_nanoevents_fcc_edm4hep1.py new file mode 100755 index 000000000..f58729b06 --- /dev/null +++ b/tests/test_nanoevents_fcc_edm4hep1.py @@ -0,0 +1,138 @@ +import os + +import awkward +import pytest + +from coffea.nanoevents import FCC, NanoEventsFactory + + +def _events(**kwargs): + path = os.path.abspath("tests/samples/p8_ee_WW_ecm240_edm4hep.root") + factory = NanoEventsFactory.from_root( + {path: "events"}, schemaclass=FCC.get_schema(version="edm4hep1"), **kwargs + ) + return factory.events() + + +@pytest.fixture(scope="module") +def eager_events(): + return _events(delayed=False) + + +@pytest.fixture(scope="module") +def delayed_events(): + return _events(delayed=True) + + +@pytest.mark.parametrize( + "field", + [ + "CalorimeterHits", + "EFlowNeutralHadron", + "EFlowPhoton", + "EFlowTrack", + "EFlowTrack_L", + "EFlowTrack_dNdx", + "Electron_IsolationVar", + "Electron_objIdx", + "EventHeader", + "GPDoubleKeys", + "GPDoubleValues", + "GPFloatKeys", + "GPFloatValues", + "GPIntKeys", + "GPIntValues", + "GPStringKeys", + "GPStringValues", + "Jet", + "MCRecoAssociations", + "Muon_IsolationVar", + "Muon_objIdx", + "Particle", + "ParticleIDs", + "Photon_IsolationVar", + "Photon_objIdx", + "ReconstructedParticles", + "TrackerHits", + "magFieldBz", + ], +) +def test_field_is_present(eager_events, delayed_events, field): + eager_fields = eager_events.fields + delayed_fields = delayed_events.fields + assert field in eager_fields + assert field in delayed_fields + + +def test_MC_daughters(delayed_events): + d = delayed_events.Particle.Map_Relation("daughters", "Particle").compute() + assert isinstance(d, awkward.highlevel.Array) + assert d.layout.branch_depth[1] == 3 + + +def test_MC_parents(delayed_events): + p = delayed_events.Particle.Map_Relation("parents", "Particle").compute() + assert isinstance(p, awkward.highlevel.Array) + assert p.layout.branch_depth[1] == 3 + + +# Todo: Add Link tests +# + + +def test_KaonParent_to_PionDaughters_Loop(eager_events): + """Test to thoroughly check parents and daughters + - We look at the decay of Kaon $K_S^0 \\rightarrow pions $ + - Two decay modes: + $$ K_S^0 \\rightarrow \\pi^0 + \\pi^0 $$ + $$ K_S^0 \\rightarrow \\pi^+ + \\pi^- $$ + """ + PDG_IDs = {"K(S)0": 310, "pi+": 211, "pi-": -211, "pi0": 111} + mc = eager_events.Particle + + # Find Single K(S)0 + K_S0_cut = mc.PDG == PDG_IDs["K(S)0"] + K_S0 = mc[K_S0_cut] + single_K_S0_cut = awkward.num(K_S0, axis=1) == 1 + single_K_S0 = K_S0[single_K_S0_cut] + + # Daughter Test + # The Kaon K(S)0 must have only pions as the daughters + + # Find the daughters of Single K(S)0 + daughters_of_K_S0 = single_K_S0.Map_Relation("daughters", "Particle") + + # Some K_S0 can go undetected (I think) + # Ensure that at least one daughter is available per event + bool_non_empty_daughter_list = awkward.num(daughters_of_K_S0, axis=2) > 0 + daughters_of_K_S0 = daughters_of_K_S0[ + awkward.flatten(bool_non_empty_daughter_list, axis=1) + ] + + # Are these valid daughter particles (pi+ or pi- or pi0)? + flat_PDG = awkward.ravel(daughters_of_K_S0.PDG) + is_pi_0 = flat_PDG == PDG_IDs["pi0"] + is_pi_plus = flat_PDG == PDG_IDs["pi+"] + is_pi_minus = flat_PDG == PDG_IDs["pi-"] + names_valid = awkward.all(is_pi_0 | is_pi_plus | is_pi_minus) + assert names_valid + + # Do the daughters have valid charges (-1 or 0)? + nested_bool = awkward.prod(daughters_of_K_S0.charge, axis=2) <= 0 + charge_valid = awkward.all(awkward.ravel(nested_bool)) + assert charge_valid + + # Parent Test + # These pion daughters, just generated, must point back to the single parent K(S)0 + + p = daughters_of_K_S0.Map_Relation("parents", "Particle") + + # Do the daughters have a single parent? + nested_bool_daughter = awkward.num(p, axis=3) == 1 + daughters_have_single_parent = awkward.all(awkward.ravel(nested_bool_daughter)) + assert daughters_have_single_parent + + # Is that parent K(S)0 ? + nested_bool_parent = p.PDG == PDG_IDs["K(S)0"] + daughters_have_K_S0_parent = awkward.all(awkward.ravel(nested_bool_parent)) + assert daughters_have_K_S0_parent diff --git a/tests/test_nanoevents_fcc_spring2021.py b/tests/test_nanoevents_fcc_spring2021.py index f6ce197e3..6f08f7628 100644 --- a/tests/test_nanoevents_fcc_spring2021.py +++ b/tests/test_nanoevents_fcc_spring2021.py @@ -4,14 +4,13 @@ import pytest from coffea.nanoevents import FCC, NanoEventsFactory -from coffea.nanoevents.methods.vector import LorentzVectorRecord def _events(**kwargs): # Path to original sample : /eos/experiment/fcc/ee/generation/DelphesEvents/spring2021/IDEA/p8_ee_ZH_ecm240/events_082532938.root path = os.path.abspath("tests/samples/test_FCC_Spring2021.root") factory = NanoEventsFactory.from_root( - {path: "events"}, schemaclass=FCC.get_schema(version="latest"), **kwargs + {path: "events"}, schemaclass=FCC.get_schema(version="pre-edm4hep1"), **kwargs ) return factory.events() @@ -88,16 +87,18 @@ def test_field_is_present(eager_events, delayed_events, field): assert field in delayed_fields -def test_lorentz_behavior(delayed_events): - assert delayed_events.Particle.behavior["LorentzVector"] == LorentzVectorRecord - assert ( - delayed_events.ReconstructedParticles.behavior["LorentzVector"] - == LorentzVectorRecord - ) - assert isinstance(delayed_events.Particle.eta.compute(), awkward.highlevel.Array) - assert isinstance( - delayed_events.ReconstructedParticles.eta.compute(), awkward.highlevel.Array - ) +# Faulty Test: Returns Passed even with no events +# For now, commenting it out +# def test_lorentz_behavior(delayed_events): +# assert delayed_events.Particle.behavior["LorentzVector"] == LorentzVectorRecord +# assert ( +# delayed_events.ReconstructedParticles.behavior["LorentzVector"] +# == LorentzVectorRecord +# ) +# assert isinstance(delayed_events.Particle.eta.compute(), awkward.highlevel.Array) +# assert isinstance( +# delayed_events.ReconstructedParticles.eta.compute(), awkward.highlevel.Array +# ) def test_MC_daughters(delayed_events): @@ -140,6 +141,13 @@ def test_KaonParent_to_PionDaughters_Loop(eager_events): # Find the daughters of Single K(S)0 daughters_of_K_S0 = single_K_S0.get_daughters + # Some K_S0 can go undetected (I think) + # Ensure that at least one daughter is available per event + bool_non_empty_daughter_list = awkward.num(daughters_of_K_S0, axis=2) > 0 + daughters_of_K_S0 = daughters_of_K_S0[ + awkward.flatten(bool_non_empty_daughter_list, axis=1) + ] + # Are these valid daughter particles (pi+ or pi- or pi0)? flat_PDG = awkward.ravel(daughters_of_K_S0.PDG) is_pi_0 = flat_PDG == PDG_IDs["pi0"] diff --git a/tests/test_nanoevents_fcc_winter2023.py b/tests/test_nanoevents_fcc_winter2023.py index 58ab4c3df..239052503 100644 --- a/tests/test_nanoevents_fcc_winter2023.py +++ b/tests/test_nanoevents_fcc_winter2023.py @@ -4,14 +4,13 @@ import pytest from coffea.nanoevents import FCC, NanoEventsFactory -from coffea.nanoevents.methods.vector import LorentzVectorRecord def _events(**kwargs): # Path to original sample: /eos/experiment/fcc/ee/generation/DelphesEvents/winter2023/IDEA/wzp6_ee_mumuH_Hbb_ecm240/events_159112833.root path = os.path.abspath("tests/samples/test_FCC_Winter2023.root") factory = NanoEventsFactory.from_root( - {path: "events"}, schemaclass=FCC.get_schema(version="latest"), **kwargs + {path: "events"}, schemaclass=FCC.get_schema(version="pre-edm4hep1"), **kwargs ) return factory.events() @@ -93,16 +92,18 @@ def test_field_is_present(eager_events, delayed_events, field): assert field in delayed_fields -def test_lorentz_behavior(delayed_events): - assert delayed_events.Particle.behavior["LorentzVector"] == LorentzVectorRecord - assert ( - delayed_events.ReconstructedParticles.behavior["LorentzVector"] - == LorentzVectorRecord - ) - assert isinstance(delayed_events.Particle.eta.compute(), awkward.highlevel.Array) - assert isinstance( - delayed_events.ReconstructedParticles.eta.compute(), awkward.highlevel.Array - ) +# Faulty Test: Returns Passed even with no events +# For now, commenting it out +# def test_lorentz_behavior(delayed_events): +# assert delayed_events.Particle.behavior["LorentzVector"] == LorentzVectorRecord +# assert ( +# delayed_events.ReconstructedParticles.behavior["LorentzVector"] +# == LorentzVectorRecord +# ) +# assert isinstance(delayed_events.Particle.eta.compute(), awkward.highlevel.Array) +# assert isinstance( +# delayed_events.ReconstructedParticles.eta.compute(), awkward.highlevel.Array +# ) def test_MC_daughters(delayed_events): @@ -145,6 +146,13 @@ def test_KaonParent_to_PionDaughters_Loop(eager_events): # Find the daughters of Single K(S)0 daughters_of_K_S0 = single_K_S0.get_daughters + # Some K_S0 can go undetected (I think) + # Ensure that at least one daughter is available per event + bool_non_empty_daughter_list = awkward.num(daughters_of_K_S0, axis=2) > 0 + daughters_of_K_S0 = daughters_of_K_S0[ + awkward.flatten(bool_non_empty_daughter_list, axis=1) + ] + # Are these valid daughter particles (pi+ or pi- or pi0)? flat_PDG = awkward.ravel(daughters_of_K_S0.PDG) is_pi_0 = flat_PDG == PDG_IDs["pi0"]