diff --git a/JugDigi/src/components/CalorimeterHitDigi.cpp b/JugDigi/src/components/CalorimeterHitDigi.cpp index 96b6a8fc3e004811a2fdde9a9fc33050280ea763..15fdd999b07a6fea529cab3c25f83512c042d9c4 100644 --- a/JugDigi/src/components/CalorimeterHitDigi.cpp +++ b/JugDigi/src/components/CalorimeterHitDigi.cpp @@ -212,7 +212,6 @@ namespace Jug::Digi { } // signal sum - int nhits = 0; for (auto &[id, hits] : merge_map) { double edep = hits[0].getEnergy(); double time = hits[0].getContributions(0).getTime(); diff --git a/JugFast/src/components/ParticlesWithTruthPID.cpp b/JugFast/src/components/ParticlesWithTruthPID.cpp index c78cf0f79e8cf65aee27e0978fb3c4588c6f899e..3886509da8f39a6dd44ce28b3843c02a5e6a9b5a 100644 --- a/JugFast/src/components/ParticlesWithTruthPID.cpp +++ b/JugFast/src/components/ParticlesWithTruthPID.cpp @@ -21,12 +21,11 @@ namespace Jug::Fast { class ParticlesWithTruthPID : public GaudiAlgorithm { public: - DataHandle<edm4hep::MCParticleCollection> m_inputTruthCollection{"inputMCParticles", Gaudi::DataHandle::Reader, - this}; + DataHandle<edm4hep::MCParticleCollection> m_inputTruthCollection{"inputMCParticles", Gaudi::DataHandle::Reader, this}; DataHandle<eic::TrackParametersCollection> m_inputTrackCollection{"inputTrackParameters", Gaudi::DataHandle::Reader, this}; - DataHandle<eic::ReconstructedParticleCollection> m_outputParticleCollection{ - "ReconstructedParticles", Gaudi::DataHandle::Writer, this}; + DataHandle<eic::ReconstructedParticleCollection> m_outputParticleCollection{"ReconstructedParticles", + Gaudi::DataHandle::Writer, this}; // Matching momentum tolerance requires 10% by default; Gaudi::Property<double> m_pRelativeTolerance{this, "pRelativeTolerance", {0.1}}; @@ -35,8 +34,7 @@ public: // Matchin eta tolerance of 0.1 Gaudi::Property<double> m_etaTolerance{this, "etaTolerance", {0.2}}; - ParticlesWithTruthPID(const std::string& name, ISvcLocator* svcLoc) - : GaudiAlgorithm(name, svcLoc) { + ParticlesWithTruthPID(const std::string& name, ISvcLocator* svcLoc) : GaudiAlgorithm(name, svcLoc) { declareProperty("inputMCParticles", m_inputTruthCollection, "MCParticles"); declareProperty("inputTrackParameters", m_inputTrackCollection, "outputTrackParameters"); declareProperty("outputParticles", m_outputParticleCollection, "ReconstructedParticles"); @@ -56,28 +54,29 @@ public: const double sinPhiOver2Tolerance = sin(0.5 * m_phiTolerance); std::vector<bool> consumed(mc.size(), false); for (const auto& trk : tracks) { - const eic::VectorXYZ mom = eicd::sphericalToVector(1.0 / std::abs(trk.qOverP()), trk.theta(), trk.phi()); - const auto charge_rec = std::copysign(1., trk.qOverP()); + const auto mom = eicd::sphericalToVector(1.0 / std::abs(trk.qOverP()), trk.theta(), trk.phi()); + const auto charge_rec = trk.charge(); // utility variables for matching int best_match = -1; double best_delta = std::numeric_limits<double>::max(); for (size_t ip = 0; ip < mc.size(); ++ip) { const auto& mcpart = mc[ip]; - if (consumed[ip] || mcpart.getGeneratorStatus() > 1 || mcpart.getCharge() == 0 || mcpart.getCharge() * charge_rec < 0) { + if (consumed[ip] || mcpart.getGeneratorStatus() > 1 || mcpart.getCharge() == 0 || + mcpart.getCharge() * charge_rec < 0) { if (msgLevel(MSG::DEBUG)) { debug() << "ignoring non-primary/neutral/opposite charge particle" << endmsg; } continue; } - const auto& p = mcpart.getMomentum(); - const auto p_mag = std::hypot(p.x, p.y, p.z); - const auto p_phi = std::atan2(p.y, p.x); - const auto p_eta = std::atanh(p.z / p_mag); - const double dp_rel = std::abs((mom.mag() - p_mag) / p_mag); + const auto& p = mcpart.getMomentum(); + const auto p_mag = std::hypot(p.x, p.y, p.z); + const auto p_phi = std::atan2(p.y, p.x); + const auto p_eta = std::atanh(p.z / p_mag); + const double dp_rel = std::abs((eicd::magnitude(mom) - p_mag) / p_mag); // check the tolerance for sin(dphi/2) to avoid the hemisphere problem and allow // for phi rollovers - const double dsphi = std::abs(sin(0.5 * (mom.phi() - p_phi))); - const double deta = std::abs((mom.eta() - p_eta)); + const double dsphi = std::abs(sin(0.5 * (eicd::angleAzimuthal(mom) - p_phi))); + const double deta = std::abs((eicd::eta(mom) - p_eta)); if (dp_rel < m_pRelativeTolerance && deta < m_etaTolerance && dsphi < sinPhiOver2Tolerance) { const double delta = @@ -88,21 +87,21 @@ public: } } } + auto rec_part = part.create(); int32_t best_pid = 0; - eic::VectorXYZ vertex; - float time = 0; - float mass = 0; + auto vertex = rec_part.v(); + float time = 0; + float mass = 0; eic::Index mcID; if (best_match >= 0) { consumed[best_match] = true; const auto& mcpart = mc[best_match]; best_pid = mcpart.getPDG(); - vertex = {mcpart.getVertex().x, mcpart.getVertex().y, mcpart.getVertex().z}; + vertex = mcpart.getVertex(); time = mcpart.getTime(); mass = mcpart.getMass(); - //mcID = {mcpart.ID()}; + // mcID = {mcpart.ID()}; } - auto rec_part = part.create(); rec_part.p(mom); rec_part.v(vertex); rec_part.time(time); @@ -110,10 +109,7 @@ public: rec_part.status(static_cast<int16_t>(best_match >= 0 ? 0 : -1)); rec_part.charge(static_cast<int16_t>(charge_rec)); rec_part.weight(1.); - rec_part.theta(mom.theta()); - rec_part.phi(mom.phi()); - rec_part.momentum(mom.mag()); - rec_part.energy(std::hypot(mom.mag(), mass)); + rec_part.energy(std::hypot(eicd::magnitude(mom), mass)); rec_part.mass(mass); rec_part.mcID(mcID); @@ -121,20 +117,20 @@ public: if (best_match > 0) { const auto& mcpart = mc[best_match]; debug() << fmt::format("Matched track with MC particle {}\n", best_match) << endmsg; - debug() << fmt::format(" - Track: (mom: {}, theta: {}, phi: {}, charge: {})", mom.mag(), mom.theta(), - mom.phi(), charge_rec) + debug() << fmt::format(" - Track: (mom: {}, theta: {}, phi: {}, charge: {})", eicd::magnitude(mom), + eicd::anglePolar(mom), eicd::angleAzimuthal(mom), charge_rec) << endmsg; - const auto& p = mcpart.getMomentum(); - const auto p_mag = std::hypot(p.x, p.y, p.z); - const auto p_phi = std::atan2(p.y, p.x); - const auto p_theta = std::atan2(std::hypot(p.x, p.y), p.z); - debug() << fmt::format(" - MC particle: (mom: {}, theta: {}, phi: {}, charge: {}, type: {}", - p_mag, p_theta, p_phi, mcpart.getCharge(), mcpart.getPDG()) + const auto& p = mcpart.getMomentum(); + const auto p_mag = eicd::magnitude(p); + const auto p_phi = eicd::angleAzimuthal(p); + const auto p_theta = eicd::anglePolar(p); + debug() << fmt::format(" - MC particle: (mom: {}, theta: {}, phi: {}, charge: {}, type: {}", p_mag, p_theta, + p_phi, mcpart.getCharge(), mcpart.getPDG()) << endmsg; } else { debug() << fmt::format("Did not find a good match for track \n") << endmsg; - debug() << fmt::format(" - Track: (mom: {}, theta: {}, phi: {}, charge: {})", mom.mag(), mom.theta(), - mom.phi(), charge_rec) + debug() << fmt::format(" - Track: (mom: {}, theta: {}, phi: {}, charge: {})", eicd::magnitude(mom), + eicd::anglePolar(mom), eicd::angleAzimuthal(mom), charge_rec) << endmsg; } } diff --git a/JugFast/src/components/SmearedFarForwardParticles.cpp b/JugFast/src/components/SmearedFarForwardParticles.cpp index 542c1ccb6de73b101111b861cc2c07de9db81ef5..6e961030294729e01e322bd952868834731c65a3 100644 --- a/JugFast/src/components/SmearedFarForwardParticles.cpp +++ b/JugFast/src/components/SmearedFarForwardParticles.cpp @@ -13,7 +13,7 @@ // Event Model related classes #include "edm4hep/MCParticleCollection.h" #include "eicd/ReconstructedParticleCollection.h" -#include "eicd/VectorXYZ.h" +#include "eicd/vector_utils.h" namespace { enum DetectorTags { @@ -219,7 +219,7 @@ private: debug() << fmt::format( "Found ZDC particle: {}, Etrue: {}, Emeas: {}, ptrue: {}, pmeas: {}, theta_true: {}, theta_meas: {}", - part.getPDG(), E, rec_part.energy(), part_p_mag, rec_part.p().mag(), th, rec_part.p().theta()) + part.getPDG(), E, rec_part.energy(), part_p_mag, eicd::magnitude(rec_part.p()), th, eicd::anglePolar(rec_part.p())) << endmsg; } } @@ -264,7 +264,7 @@ private: debug() << fmt::format("Found B0 particle: {}, ptrue: {}, pmeas: {}, pttrue: {}, ptmeas: {}, theta_true: {}, " "theta_meas: {}", part.getPDG(), part_p_mag, rec_part.momentum(), part_p_pt, - std::hypot(rec_part.p().x, rec_part.p().y), part_p_theta, rec_part.p().theta()) + std::hypot(rec_part.p().x, rec_part.p().y), part_p_theta, eicd::anglePolar(rec_part.p())) << endmsg; } } @@ -303,7 +303,7 @@ private: debug() << fmt::format("Found RP particle: {}, ptrue: {}, pmeas: {}, pttrue: {}, ptmeas: {}, theta_true: {}, " "theta_meas: {}", part.getPDG(), part_p_mag, rec_part.momentum(), part_p_pt, - std::hypot(rec_part.p().x, rec_part.p().y), part_p_theta, rec_part.p().theta()) + std::hypot(rec_part.p().x, rec_part.p().y), part_p_theta, eicd::anglePolar(rec_part.p())) << endmsg; } } @@ -348,7 +348,7 @@ private: debug() << fmt::format("Found OMD particle: {}, ptrue: {}, pmeas: {}, pttrue: {}, ptmeas: {}, theta_true: {}, " "theta_meas: {}", part.getPDG(), part_p_mag, rec_part.momentum(), part_p_pt, - std::hypot(rec_part.p().x, rec_part.p().y), part_p_theta, rec_part.p().theta()) + std::hypot(rec_part.p().x, rec_part.p().y), part_p_theta, eicd::anglePolar(rec_part.p())) << endmsg; } } diff --git a/JugReco/src/components/CalorimeterHitsEtaPhiProjector.cpp b/JugReco/src/components/CalorimeterHitsEtaPhiProjector.cpp index 6fdf007b381ab978f79e1e391543e267e130681c..746d0fb0edf278c65e07b68abd6cdc3d4c553edb 100644 --- a/JugReco/src/components/CalorimeterHitsEtaPhiProjector.cpp +++ b/JugReco/src/components/CalorimeterHitsEtaPhiProjector.cpp @@ -98,8 +98,8 @@ namespace Jug::Reco { std::unordered_map<std::pair<int64_t, int64_t>, std::vector<eic::ConstCalorimeterHit>, pair_hash> merged_hits; for (const auto h : *m_inputHitCollection.get()) { - auto bins = std::make_pair(static_cast<int64_t>(pos2bin(h.position().eta(), gridSizes[0], 0.)), - static_cast<int64_t>(pos2bin(h.position().phi(), gridSizes[1], 0.))); + auto bins = std::make_pair(static_cast<int64_t>(pos2bin(eicd::eta(h.position()), gridSizes[0], 0.)), + static_cast<int64_t>(pos2bin(eicd::angleAzimuthal(h.position()), gridSizes[1], 0.))); merged_hits[bins].push_back(h); } @@ -109,11 +109,11 @@ namespace Jug::Reco { hit.cellID(ref.cellID()); // TODO, we can do timing cut to reject noises hit.time(ref.time()); - double r = ref.position().mag(); + double r = eicd::magnitude(ref.position()); double eta = bin2pos(bins.first, gridSizes[0], 0.); double phi = bin2pos(bins.second, gridSizes[1], 1.); hit.position(eicd::sphericalToVector(r, eicd::etaToAngle(eta), phi)); - hit.dimension({gridSizes[0], gridSizes[1], 0.}); + hit.dimension({static_cast<float>(gridSizes[0]), static_cast<float>(gridSizes[1]), 0.}); // merge energy hit.energy(0.); for (const auto &h : hits) { diff --git a/JugReco/src/components/CalorimeterIslandCluster.cpp b/JugReco/src/components/CalorimeterIslandCluster.cpp index 5da860f7b0d23f5b5b1467549f767302affab934..220bc6a2eaf982e69c3da70b0f4be6de0c58441f 100644 --- a/JugReco/src/components/CalorimeterIslandCluster.cpp +++ b/JugReco/src/components/CalorimeterIslandCluster.cpp @@ -33,8 +33,8 @@ #include "eicd/CalorimeterHitCollection.h" #include "eicd/ClusterCollection.h" #include "eicd/ProtoClusterCollection.h" -#include "eicd/VectorXY.h" -#include "eicd/VectorXYZ.h" +#include "eicd/Vector2f.h" +#include "eicd/Vector3f.h" #include "eicd/vector_utils.h" using namespace Gaudi::Units; @@ -45,35 +45,35 @@ using CaloHit = eic::ConstCalorimeterHit; using CaloHitCollection = eic::CalorimeterHitCollection; // helper functions to get distance between hits -static eic::VectorXY localDistXY(const CaloHit& h1, const CaloHit& h2) { +static eicd::Vector2f localDistXY(const CaloHit& h1, const CaloHit& h2) { const auto delta = h1.local() - h2.local(); return {delta.x, delta.y}; } -static eic::VectorXY localDistXZ(const CaloHit& h1, const CaloHit& h2) { +static eicd::Vector2f localDistXZ(const CaloHit& h1, const CaloHit& h2) { const auto delta = h1.local() - h2.local(); return {delta.x, delta.z}; } -static eic::VectorXY localDistYZ(const CaloHit& h1, const CaloHit& h2) { +static eicd::Vector2f localDistYZ(const CaloHit& h1, const CaloHit& h2) { const auto delta = h1.local() - h2.local(); return {delta.y, delta.z}; } -static eic::VectorXY dimScaledLocalDistXY(const CaloHit& h1, const CaloHit& h2) { +static eicd::Vector2f dimScaledLocalDistXY(const CaloHit& h1, const CaloHit& h2) { const auto delta = h1.local() - h2.local(); const auto dimsum = h1.dimension() + h2.dimension(); return {2 * delta.x / dimsum.x, 2 * delta.y / dimsum.y}; } -static eic::VectorXY globalDistRPhi(const CaloHit& h1, const CaloHit& h2) { +static eicd::Vector2f globalDistRPhi(const CaloHit& h1, const CaloHit& h2) { return {eicd::magnitude(h1.position()) - eicd::magnitude(h2.position()), eicd::angleAzimuthal(h1.position()) - eicd::angleAzimuthal(h2.position())}; } -static eic::VectorXY globalDistEtaPhi(const CaloHit& h1, +static eicd::Vector2f globalDistEtaPhi(const CaloHit& h1, const CaloHit& h2) { return {eicd::eta(h1.position()) - eicd::eta(h2.position()), eicd::angleAzimuthal(h1.position()) - eicd::angleAzimuthal(h2.position())}; } // name: {method, units} static std::map<std::string, - std::tuple<std::function<eic::VectorXY(const CaloHit&, const CaloHit&)>, std::vector<double>>> + std::tuple<std::function<eicd::Vector2f(const CaloHit&, const CaloHit&)>, std::vector<double>>> distMethods{ {"localDistXY", {localDistXY, {mm, mm}}}, {"localDistXZ", {localDistXZ, {mm, mm}}}, {"localDistYZ", {localDistYZ, {mm, mm}}}, {"dimScaledLocalDistXY", {dimScaledLocalDistXY, {1., 1.}}}, @@ -113,7 +113,7 @@ public: Gaudi::Property<std::vector<double>> u_globalDistEtaPhi{this, "globalDistEtaPhi", {}}; Gaudi::Property<std::vector<double>> u_dimScaledLocalDistXY{this, "dimScaledLocalDistXY", {1.8, 1.8}}; // neighbor checking function - std::function<eic::VectorXY(const CaloHit&, const CaloHit&)> hitsDist; + std::function<eicd::Vector2f(const CaloHit&, const CaloHit&)> hitsDist; // unitless counterparts of the input parameters double minClusterHitEdep, minClusterCenterEdep, sectorDist; @@ -231,7 +231,7 @@ private: // in the same sector if (h1.sector() == h2.sector()) { auto dist = hitsDist(h1, h2); - return (dist.x <= neighbourDist[0]) && (dist.y <= neighbourDist[1]); + return (dist.a <= neighbourDist[0]) && (dist.b <= neighbourDist[1]); // different sector, local coordinates do not work, using global coordinates } else { // sector may have rotation (barrel), so z is included @@ -354,7 +354,7 @@ private: for (const auto& chit : maxima) { double dist_ref = chit.dimension().x; double energy = chit.energy(); - double dist = hitsDist(chit, hit).mag(); + double dist = eicd::magnitude(hitsDist(chit, hit)); weights[j] = std::exp(-dist / dist_ref) * energy; j += 1; } diff --git a/JugReco/src/components/ClusterRecoCoG.cpp b/JugReco/src/components/ClusterRecoCoG.cpp index ec93e131095203a3d09761940f9cf95e81665129..f9652f3eee49e9bae063cde7480ae8969307c0d2 100644 --- a/JugReco/src/components/ClusterRecoCoG.cpp +++ b/JugReco/src/components/ClusterRecoCoG.cpp @@ -186,18 +186,18 @@ private: // center of gravity with logarithmic weighting float tw = 0.; - eic::VectorXYZ v; + auto v = cl.position(); for (unsigned i = 0; i < pcl.hits().size(); ++i) { const auto& hit = pcl.hits()[i]; const auto weight = pcl.weights()[i]; float w = weightFunc(hit.energy() * weight, totalE, m_logWeightBase.value(), 0); tw += w; - v = v.add(hit.position().scale(w)); + v = v + (hit.position() * w); } if (tw == 0.) { warning() << "zero total weights encountered, you may want to adjust your weighting parameter." << endmsg; } - cl.position(v.scale(1 / tw)); + cl.position(v / tw); cl.positionError({}); // @TODO: Covariance matrix // Optionally constrain the cluster to the hit eta values diff --git a/JugReco/src/components/EnergyPositionClusterMerger.cpp b/JugReco/src/components/EnergyPositionClusterMerger.cpp index 7b56962071824b58cb5a511958cd9b4b82fe4360..76063ceaa177944e92d57231b20c37b7f8db6a64 100644 --- a/JugReco/src/components/EnergyPositionClusterMerger.cpp +++ b/JugReco/src/components/EnergyPositionClusterMerger.cpp @@ -13,6 +13,7 @@ // Event Model related classes #include "eicd/ClusterCollection.h" +#include "eicd/vector_utils.h" using namespace Gaudi::Units; @@ -46,8 +47,7 @@ public: double m_phiTolerance; public: - EnergyPositionClusterMerger(const std::string& name, ISvcLocator* svcLoc) - : GaudiAlgorithm(name, svcLoc) { + EnergyPositionClusterMerger(const std::string& name, ISvcLocator* svcLoc) : GaudiAlgorithm(name, svcLoc) { declareProperty("energyClusters", m_energyClusters, "Cluster collection with good energy precision"); declareProperty("positionClusters", m_positionClusters, "Cluster collection with good position precision"); declareProperty("outputClusters", m_outputClusters, ""); @@ -64,7 +64,7 @@ public: const auto& e_clus = *(m_energyClusters.get()); const auto& pos_clus = *(m_positionClusters.get()); // output - auto& merged = *(m_outputClusters.createAndPut()); + auto& merged = *(m_outputClusters.createAndPut()); std::vector<bool> consumed(e_clus.size(), false); @@ -80,7 +80,7 @@ public: const auto& ec = e_clus[ie]; // 1. stop if not within tolerance // (make sure to handle rollover of phi properly) - double dphi = pc.position().phi() - ec.position().phi(); + double dphi = eicd::angleAzimuthal(pc.position()) - eicd::angleAzimuthal(ec.position()); if (std::abs(dphi) > M_PI) { dphi = std::abs(dphi) - M_PI; } @@ -116,14 +116,14 @@ public: consumed[best_match] = true; if (msgLevel(MSG::DEBUG)) { debug() << fmt::format("Matched position cluster {} with energy cluster {}\n", pc.id(), ec.id()) << endmsg; - debug() << fmt::format(" - Position cluster: (E: {}, phi: {}, z: {})", pc.energy(), pc.position().phi(), - pc.position().z) + debug() << fmt::format(" - Position cluster: (E: {}, phi: {}, z: {})", pc.energy(), + eicd::angleAzimuthal(pc.position()), pc.position().z) << endmsg; - debug() << fmt::format(" - Energy cluster: (E: {}, phi: {}, z: {})", ec.energy(), ec.position().phi(), - ec.position().z) + debug() << fmt::format(" - Energy cluster: (E: {}, phi: {}, z: {})", ec.energy(), + eicd::angleAzimuthal(ec.position()), ec.position().z) << endmsg; debug() << fmt::format(" ---> Merged cluster: (E: {}, phi: {}, z: {})", new_clus.energy(), - new_clus.position().phi(), new_clus.position().z) + eicd::angleAzimuthal(new_clus.position()), new_clus.position().z) << endmsg; } } diff --git a/JugReco/src/components/FarForwardParticles.cpp b/JugReco/src/components/FarForwardParticles.cpp index eb21a3985e083a44a5839732dc285abd0657ce54..8ebbd83cdcc4250513f40ea60c242b26ad7b2a6b 100644 --- a/JugReco/src/components/FarForwardParticles.cpp +++ b/JugReco/src/components/FarForwardParticles.cpp @@ -18,6 +18,7 @@ // Event Model related classes #include "eicd/ReconstructedParticleCollection.h" #include "eicd/TrackerHitCollection.h" +#include <eicd/vector_utils.h> namespace Jug::Reco { @@ -39,16 +40,14 @@ class FarForwardParticles : public GaudiAlgorithm { Gaudi::Property<std::string> m_readout{this, "readoutClass", ""}; Gaudi::Property<std::string> m_layerField{this, "layerField", ""}; Gaudi::Property<std::string> m_sectorField{this, "sectorField", ""}; - SmartIF<IGeoSvc> m_geoSvc; - dd4hep::BitFieldCoder* id_dec = nullptr; - size_t sector_idx, layer_idx; + SmartIF<IGeoSvc> m_geoSvc; + dd4hep::BitFieldCoder* id_dec = nullptr; + size_t sector_idx, layer_idx; - Gaudi::Property<std::string> m_localDetElement{this, "localDetElement", ""}; + Gaudi::Property<std::string> m_localDetElement{this, "localDetElement", ""}; Gaudi::Property<std::vector<std::string>> u_localDetFields{this, "localDetFields", {}}; - dd4hep::DetElement local; - size_t local_mask = ~0; - - + dd4hep::DetElement local; + size_t local_mask = ~0; const double aXRP[2][2] = {{2.102403743, 29.11067626}, {0.186640381, 0.192604619}}; const double aYRP[2][2] = {{0.0000159900, 3.94082098}, {0.0000079946, -0.1402995}}; @@ -57,28 +56,26 @@ class FarForwardParticles : public GaudiAlgorithm { double aYRPinv[2][2] = {0.0, 0.0}; public: - FarForwardParticles(const std::string& name, ISvcLocator* svcLoc) - : GaudiAlgorithm(name, svcLoc) { + FarForwardParticles(const std::string& name, ISvcLocator* svcLoc) : GaudiAlgorithm(name, svcLoc) { declareProperty("inputCollection", m_inputHitCollection, "FarForwardTrackerHits"); declareProperty("outputCollection", m_outputParticles, "ReconstructedParticles"); } // See Wouter's example to extract local coordinates CalorimeterHitReco.cpp - //includes DDRec/CellIDPositionConverter.here - //See tutorial + // includes DDRec/CellIDPositionConverter.here + // See tutorial // auto converter = m_GeoSvc .... - //https://eicweb.phy.anl.gov/EIC/juggler/-/blob/master/JugReco/src/components/CalorimeterHitReco.cpp - line 200 - //include the Eigen libraries, used in ACTS, for the linear algebra. + // https://eicweb.phy.anl.gov/EIC/juggler/-/blob/master/JugReco/src/components/CalorimeterHitReco.cpp - line 200 + // include the Eigen libraries, used in ACTS, for the linear algebra. StatusCode initialize() override { - if (GaudiAlgorithm::initialize().isFailure()){ + if (GaudiAlgorithm::initialize().isFailure()) { return StatusCode::FAILURE; } m_geoSvc = service(m_geoSvcName); if (!m_geoSvc) { error() << "Unable to locate Geometry Service. " - << "Make sure you have GeoSvc and SimSvc in the right order in the configuration." - << endmsg; + << "Make sure you have GeoSvc and SimSvc in the right order in the configuration." << endmsg; return StatusCode::FAILURE; } @@ -107,14 +104,12 @@ public: if (m_localDetElement.value().size()) { try { local = m_geoSvc->detector()->detector(m_localDetElement.value()); - info() << "Local coordinate system from DetElement " << m_localDetElement.value() - << endmsg; + info() << "Local coordinate system from DetElement " << m_localDetElement.value() << endmsg; } catch (...) { - error() << "Failed to locate local coordinate system from DetElement " - << m_localDetElement.value() << endmsg; + error() << "Failed to locate local coordinate system from DetElement " << m_localDetElement.value() << endmsg; return StatusCode::FAILURE; } - // or get from fields + // or get from fields } else { std::vector<std::pair<std::string, int>> fields; for (auto& f : u_localDetFields.value()) { @@ -125,11 +120,11 @@ public: if (fields.empty()) { local_mask = ~0; } - //info() << fmt::format("Local DetElement mask {:#064b} from fields [{}]", local_mask, + // info() << fmt::format("Local DetElement mask {:#064b} from fields [{}]", local_mask, // fmt::join(fields, ", ")) // << endmsg; } - + double det = aXRP[0][0] * aXRP[1][1] - aXRP[0][1] * aXRP[1][0]; if (det == 0) { @@ -175,32 +170,30 @@ public: for (const auto& h : *rawhits) { - auto cellID = h.cellID(); + auto cellID = h.cellID(); // The actual hit position in Global Coordinates - //auto pos0 = h.position(); - + // auto pos0 = h.position(); + auto gpos = converter->position(cellID); - // local positions - if (m_localDetElement.value().empty()) { - auto volman = m_geoSvc->detector()->volumeManager(); - local = volman.lookupDetElement(cellID); - } - auto pos0 = local.nominal().worldToLocal(dd4hep::Position(gpos.x(), gpos.y(), gpos.z())); //hit position in local coordinates + // local positions + if (m_localDetElement.value().empty()) { + auto volman = m_geoSvc->detector()->volumeManager(); + local = volman.lookupDetElement(cellID); + } + auto pos0 = local.nominal().worldToLocal( + dd4hep::Position(gpos.x(), gpos.y(), gpos.z())); // hit position in local coordinates - // auto mom0 = h.momentum; // auto pidCode = h.g4ID; auto eDep = h.edep(); - - if (eDep < 0.00001) { continue; } if (eventReset < 2) { - hitx.push_back(pos0.x());// - local_x_offset_station_2); - } // use station 2 for both offsets since it is used for the reference orbit + hitx.push_back(pos0.x()); // - local_x_offset_station_2); + } // use station 2 for both offsets since it is used for the reference orbit else { hitx.push_back(pos0.x()); // - local_x_offset_station_2); } @@ -226,7 +219,7 @@ public: if (base == 0) { warning() << "Detector separation = 0!" - << "Cannot calculate slope!" << endmsg; + << "Cannot calculate slope!" << endmsg; return StatusCode::SUCCESS; } @@ -254,49 +247,23 @@ public: double p = nomMomentum * (1 + 0.01 * Xip[0]); double norm = std::sqrt(1.0 + rsx * rsx + rsy * rsy); - double prec[3]; - prec[0] = p * rsx / norm; - prec[1] = p * rsy / norm; - prec[2] = p / norm; - - // double pT_reco = std::sqrt(prec[0]*prec[0] + prec[1]*prec[1]); - float p_reco = std::sqrt(prec[0] * prec[0] + prec[1] * prec[1] + prec[2] * prec[2]); + const float prec[3] = {static_cast<float>(p * rsx / norm), static_cast<float>(p * rsy / norm), + static_cast<float>(p / norm)}; //----- end RP reconstruction code ------ - eic::VectorXYZ recoMom(prec[0], prec[1], prec[2]); - eic::VectorXYZ primVtx(0, 0, 0); - eic::Weight wgt(1); - - // ReconstructedParticle (eic::Index ID, eic::VectorXYZ p, eic::VectorXYZ v, float time, std::int32_t pid, - // std::int16_t status, std::int16_t charge, eic::Weight weight, eic::Direction direction, float momentum, - // float energy, float mass) - - // eic::ReconstructedParticle rec_part{{part.ID(), algorithmID()}, - // mom3s, - //{part.vs().x, part.vs().y, part.vs().z}, - // static_cast<float>(part.time()), - // part.pdgID(), - // 0, - // static_cast<int16_t>(part.charge()), - // 1., - //{mom3s.theta(), mom3s.phi()}, - // static_cast<float>(moms), - // static_cast<float>(Es), - // static_cast<float>(part.mass())}; - eic::ReconstructedParticle rpTrack; - rpTrack.p(recoMom); - rpTrack.v(primVtx); + rpTrack.p({prec}); + rpTrack.v({0, 0, 0}); rpTrack.time(0); rpTrack.pid(2122); rpTrack.status(0); rpTrack.charge(1); rpTrack.weight(1.); - rpTrack.theta(recoMom.theta()); - rpTrack.phi(recoMom.phi()); - rpTrack.momentum(p_reco); - rpTrack.energy(std::hypot(p_reco, .938272)); + rpTrack.theta(eicd::anglePolar(rpTrack.p())); + rpTrack.phi(eicd::angleAzimuthal(rpTrack.p())); + rpTrack.momentum(eicd::magnitude(rpTrack.p())); + rpTrack.energy(std::hypot(rpTrack.momentum(), .938272)); rpTrack.mass(.938272); rc->push_back(rpTrack); diff --git a/JugReco/src/components/FarForwardParticlesOMD.cpp b/JugReco/src/components/FarForwardParticlesOMD.cpp index 6539799cdd53e796fee9f5c145453ccb9ed713a4..5da4f762e87e0831882a12018640b2c0452fc6cd 100644 --- a/JugReco/src/components/FarForwardParticlesOMD.cpp +++ b/JugReco/src/components/FarForwardParticlesOMD.cpp @@ -13,6 +13,7 @@ // Event Model related classes #include "eicd/ReconstructedParticleCollection.h" #include "eicd/TrackerHitCollection.h" +#include <eicd/vector_utils.h> namespace Jug::Reco { @@ -153,49 +154,23 @@ public: double p = nomMomentum * (1 + 0.01 * Xip[0]); double norm = std::sqrt(1.0 + rsx * rsx + rsy * rsy); - double prec[3]; - prec[0] = p * rsx / norm; - prec[1] = p * rsy / norm; - prec[2] = p / norm; - - // double pT_reco = std::sqrt(prec[0]*prec[0] + prec[1]*prec[1]); - float p_reco = std::sqrt(prec[0] * prec[0] + prec[1] * prec[1] + prec[2] * prec[2]); + const float prec[3] = {static_cast<float>(p * rsx / norm), static_cast<float>(p * rsy / norm), + static_cast<float>(p / norm)}; //----- end RP reconstruction code ------ - eic::VectorXYZ recoMom(prec[0], prec[1], prec[2]); - eic::VectorXYZ primVtx(0, 0, 0); - eic::Weight wgt(1); - - // ReconstructedParticle (eic::Index ID, eic::VectorXYZ p, eic::VectorXYZ v, float time, std::int32_t pid, - // std::int16_t status, std::int16_t charge, eic::Weight weight, eic::Direction direction, float momentum, float - // energy, float mass) - - // eic::ReconstructedParticle rec_part{{part.ID(), algorithmID()}, - // mom3s, - //{part.vs().x, part.vs().y, part.vs().z}, - // static_cast<float>(part.time()), - // part.pdgID(), - // 0, - // static_cast<int16_t>(part.charge()), - // 1., - //{mom3s.theta(), mom3s.phi()}, - // static_cast<float>(moms), - // static_cast<float>(Es), - // static_cast<float>(part.mass())}; - eic::ReconstructedParticle rpTrack; - rpTrack.p(recoMom); - rpTrack.v(primVtx); + rpTrack.p({prec}); + rpTrack.v({0, 0, 0}); rpTrack.time(0); rpTrack.pid(2122); rpTrack.status(0); rpTrack.charge(1); rpTrack.weight(1.); - rpTrack.theta(recoMom.theta()); - rpTrack.phi(recoMom.phi()); - rpTrack.momentum(p_reco); - rpTrack.energy(std::hypot(p_reco, .938272)); + rpTrack.theta(eicd::anglePolar(rpTrack.p())); + rpTrack.phi(eicd::angleAzimuthal(rpTrack.p())); + rpTrack.momentum(eicd::magnitude(rpTrack.p())); + rpTrack.energy(std::hypot(rpTrack.momentum(), .938272)); rpTrack.mass(.938272); rc->push_back(rpTrack); diff --git a/JugReco/src/components/ImagingClusterReco.cpp b/JugReco/src/components/ImagingClusterReco.cpp index 7075eddc6507c78dab07d4d5bd59b21a704e6212..baa683d7290dc97637ed514615cacb15aa38a5b8 100644 --- a/JugReco/src/components/ImagingClusterReco.cpp +++ b/JugReco/src/components/ImagingClusterReco.cpp @@ -134,7 +134,7 @@ private: const auto& hits = pcl.hits(); const auto& weights = pcl.weights(); // using map to have hits sorted by layer - std::map<int, std::vector<std::pair<eic::ConstCalorimeterHit, eic::Weight>>> layer_map; + std::map<int, std::vector<std::pair<eic::ConstCalorimeterHit, float>>> layer_map; for (unsigned i = 0; i < hits.size(); ++i) { const auto hit = hits[i]; auto lid = hit.layer(); @@ -153,7 +153,7 @@ private: return cl_layers; } - eic::Cluster reconstruct_layer(const std::vector<std::pair<eic::ConstCalorimeterHit, eic::Weight>>& hits) const { + eic::Cluster reconstruct_layer(const std::vector<std::pair<eic::ConstCalorimeterHit, float>>& hits) const { eic::Cluster layer; layer.type(ClusterType::kClusterSlice); // Calculate averages @@ -162,7 +162,7 @@ private: double time; double timeError; double sumOfWeights = 0; - eic::VectorXYZ pos; + auto pos = layer.position(); for (const auto& [hit, weight] : hits) { energy += hit.energy() * weight; energyError += std::pow(hit.energyError() * weight, 2); @@ -199,13 +199,13 @@ private: const auto& weights = pcl.weights(); cluster.type(ClusterType::kCluster3D); - double energy = 0.; - double energyError = 0.; - double time = 0.; - double timeError = 0.; - double meta = 0.; - double mphi = 0.; - double r = 9999 * cm; + double energy = 0.; + double energyError = 0.; + double time = 0.; + double timeError = 0.; + double meta = 0.; + double mphi = 0.; + double r = 9999 * cm; for (unsigned i = 0; i < hits.size(); ++i) { const auto& hit = hits[i]; const auto weight = weights[i]; @@ -230,8 +230,8 @@ private: // shower radius estimate (eta-phi plane) double radius = 0.; for (const auto& hit : hits) { - radius += - pow2(hit.position().eta() - cluster.position().eta()) + pow2(hit.position().phi() - cluster.position().phi()); + radius += pow2(eicd::eta(hit.position()) - eicd::eta(cluster.position())) + + pow2(eicd::angleAzimuthal(hit.position()) - eicd::angleAzimuthal(cluster.position())); } cluster.addshapeParameters(std::sqrt(radius / cluster.nhits())); // Skewedness not calculated TODO @@ -248,7 +248,7 @@ private: std::pair<double /* polar */, double /* azimuthal */> fit_track(const std::vector<eic::Cluster>& layers) const { int nrows = 0; - eic::VectorXYZ mean_pos{0, 0, 0}; + eicd::Vector3f mean_pos{0, 0, 0}; for (const auto& layer : layers) { if ((layer.nhits() > 0) && (layer.hits(0).layer() <= m_trackStopLayer)) { mean_pos = mean_pos + layer.position(); diff --git a/JugReco/src/components/ImagingTopoCluster.cpp b/JugReco/src/components/ImagingTopoCluster.cpp index 528df7c73e149bb52da8f9a185a22af589366e8f..0ae7dd3b32affeffc9bc8f8efabc521db0ccb650 100644 --- a/JugReco/src/components/ImagingTopoCluster.cpp +++ b/JugReco/src/components/ImagingTopoCluster.cpp @@ -27,208 +27,202 @@ #include "JugReco/ClusterTypes.h" // Event Model related classes -#include "eicd/ProtoClusterCollection.h" #include "eicd/CalorimeterHitCollection.h" +#include "eicd/ProtoClusterCollection.h" +#include "eicd/vector_utils.h" using namespace Gaudi::Units; namespace Jug::Reco { - /** Topological Cell Clustering Algorithm. - * - * Topological Cell Clustering Algorithm for Imaging Calorimetry - * 1. group all the adjacent pixels - * - * Author: Chao Peng (ANL), 06/02/2021 - * References: https://arxiv.org/pdf/1603.02934.pdf - * - * \ingroup reco - */ - class ImagingTopoCluster : public GaudiAlgorithm { - public: - // maximum difference in layer numbers that can be considered as neighbours - Gaudi::Property<int> m_neighbourLayersRange{this, "neighbourLayersRange", 1}; - // maximum distance of local (x, y) to be considered as neighbors at the same layer - Gaudi::Property<std::vector<double>> u_localDistXY{this, "localDistXY", {1.0 * mm, 1.0 * mm}}; - // maximum distance of global (eta, phi) to be considered as neighbors at different layers - Gaudi::Property<std::vector<double>> u_layerDistEtaPhi{this, "layerDistEtaPhi", {0.01, 0.01}}; - // maximum global distance to be considered as neighbors in different sectors - Gaudi::Property<double> m_sectorDist{this, "sectorDist", 1.0 * cm}; - - // minimum hit energy to participate clustering - Gaudi::Property<double> m_minClusterHitEdep{this, "minClusterHitEdep", 0.}; - // minimum cluster center energy (to be considered as a seed for cluster) - Gaudi::Property<double> m_minClusterCenterEdep{this, "minClusterCenterEdep", 0.}; - // minimum cluster energy (to save this cluster) - Gaudi::Property<double> m_minClusterEdep{this, "minClusterEdep", 0.5 * MeV}; - // minimum number of hits (to save this cluster) - Gaudi::Property<int> m_minClusterNhits{this, "minClusterNhits", 10}; - // input hits collection - DataHandle<eic::CalorimeterHitCollection> m_inputHitCollection{"inputHitCollection", - Gaudi::DataHandle::Reader, this}; - // output clustered hits - DataHandle<eic::ProtoClusterCollection> m_outputProtoClusterCollection{"outputProtoClusterCollection", - Gaudi::DataHandle::Writer, this}; - - // unitless counterparts of the input parameters - double localDistXY[2], layerDistEtaPhi[2], sectorDist; - double minClusterHitEdep, minClusterCenterEdep, minClusterEdep, minClusterNhits; - - ImagingTopoCluster(const std::string& name, ISvcLocator* svcLoc) - : GaudiAlgorithm(name, svcLoc) - { - declareProperty("inputHitCollection", m_inputHitCollection, ""); - declareProperty("outputProtoClusterCollection", m_outputProtoClusterCollection, ""); +/** Topological Cell Clustering Algorithm. + * + * Topological Cell Clustering Algorithm for Imaging Calorimetry + * 1. group all the adjacent pixels + * + * Author: Chao Peng (ANL), 06/02/2021 + * References: https://arxiv.org/pdf/1603.02934.pdf + * + * \ingroup reco + */ +class ImagingTopoCluster : public GaudiAlgorithm { +public: + // maximum difference in layer numbers that can be considered as neighbours + Gaudi::Property<int> m_neighbourLayersRange{this, "neighbourLayersRange", 1}; + // maximum distance of local (x, y) to be considered as neighbors at the same layer + Gaudi::Property<std::vector<double>> u_localDistXY{this, "localDistXY", {1.0 * mm, 1.0 * mm}}; + // maximum distance of global (eta, phi) to be considered as neighbors at different layers + Gaudi::Property<std::vector<double>> u_layerDistEtaPhi{this, "layerDistEtaPhi", {0.01, 0.01}}; + // maximum global distance to be considered as neighbors in different sectors + Gaudi::Property<double> m_sectorDist{this, "sectorDist", 1.0 * cm}; + + // minimum hit energy to participate clustering + Gaudi::Property<double> m_minClusterHitEdep{this, "minClusterHitEdep", 0.}; + // minimum cluster center energy (to be considered as a seed for cluster) + Gaudi::Property<double> m_minClusterCenterEdep{this, "minClusterCenterEdep", 0.}; + // minimum cluster energy (to save this cluster) + Gaudi::Property<double> m_minClusterEdep{this, "minClusterEdep", 0.5 * MeV}; + // minimum number of hits (to save this cluster) + Gaudi::Property<int> m_minClusterNhits{this, "minClusterNhits", 10}; + // input hits collection + DataHandle<eic::CalorimeterHitCollection> m_inputHitCollection{"inputHitCollection", Gaudi::DataHandle::Reader, this}; + // output clustered hits + DataHandle<eic::ProtoClusterCollection> m_outputProtoClusterCollection{"outputProtoClusterCollection", + Gaudi::DataHandle::Writer, this}; + + // unitless counterparts of the input parameters + double localDistXY[2], layerDistEtaPhi[2], sectorDist; + double minClusterHitEdep, minClusterCenterEdep, minClusterEdep, minClusterNhits; + + ImagingTopoCluster(const std::string& name, ISvcLocator* svcLoc) : GaudiAlgorithm(name, svcLoc) { + declareProperty("inputHitCollection", m_inputHitCollection, ""); + declareProperty("outputProtoClusterCollection", m_outputProtoClusterCollection, ""); + } + + StatusCode initialize() override { + if (GaudiAlgorithm::initialize().isFailure()) { + return StatusCode::FAILURE; } - StatusCode initialize() override - { - if (GaudiAlgorithm::initialize().isFailure()) { - return StatusCode::FAILURE; - } + // unitless conversion + // sanity checks + if (u_localDistXY.size() != 2) { + error() << "Expected 2 values (x_dist, y_dist) for localDistXY" << endmsg; + return StatusCode::FAILURE; + } + if (u_layerDistEtaPhi.size() != 2) { + error() << "Expected 2 values (eta_dist, phi_dist) for layerDistEtaPhi" << endmsg; + return StatusCode::FAILURE; + } - // unitless conversion - // sanity checks - if (u_localDistXY.size() != 2) { - error() << "Expected 2 values (x_dist, y_dist) for localDistXY" << endmsg; - return StatusCode::FAILURE; + // using juggler internal units (GeV, mm, ns, rad) + localDistXY[0] = u_localDistXY.value()[0] / mm; + localDistXY[1] = u_localDistXY.value()[1] / mm; + layerDistEtaPhi[0] = u_layerDistEtaPhi.value()[0]; + layerDistEtaPhi[1] = u_layerDistEtaPhi.value()[1] / rad; + sectorDist = m_sectorDist.value() / mm; + minClusterHitEdep = m_minClusterHitEdep.value() / GeV; + minClusterCenterEdep = m_minClusterCenterEdep.value() / GeV; + minClusterEdep = m_minClusterEdep.value() / GeV; + + // summarize the clustering parameters + info() << fmt::format("Local clustering (same sector and same layer): " + "Local [x, y] distance between hits <= [{:.4f} mm, {:.4f} mm].", + localDistXY[0], localDistXY[1]) + << endmsg; + info() << fmt::format("Neighbour layers clustering (same sector and layer id within +- {:d}: " + "Global [eta, phi] distance between hits <= [{:.4f}, {:.4f} rad].", + m_neighbourLayersRange.value(), layerDistEtaPhi[0], layerDistEtaPhi[1]) + << endmsg; + info() << fmt::format("Neighbour sectors clustering (different sector): " + "Global distance between hits <= {:.4f} mm.", + sectorDist) + << endmsg; + + return StatusCode::SUCCESS; + } + + StatusCode execute() override { + // input collections + const auto& hits = *m_inputHitCollection.get(); + // Create output collections + auto& proto = *m_outputProtoClusterCollection.createAndPut(); + + // group neighboring hits + std::vector<bool> visits(hits.size(), false); + std::vector<std::vector<std::pair<uint32_t, eic::ConstCalorimeterHit>>> groups; + for (size_t i = 0; i < hits.size(); ++i) { + if (msgLevel(MSG::DEBUG)) { + debug() << fmt::format("hit {:d}: local position = ({}, {}, {}), global position = ({}, {}, {})", i + 1, + hits[i].local().x, hits[i].local().y, hits[i].position().z, hits[i].position().x, + hits[i].position().y, hits[i].position().z) + << endmsg; } - if (u_layerDistEtaPhi.size() != 2) { - error() << "Expected 2 values (eta_dist, phi_dist) for layerDistEtaPhi" << endmsg; - return StatusCode::FAILURE; + // already in a group, or not energetic enough to form a cluster + if (visits[i] || hits[i].energy() < minClusterCenterEdep) { + continue; + } + groups.emplace_back(); + // create a new group, and group all the neighboring hits + dfs_group(groups.back(), i, hits, visits); + } + if (msgLevel(MSG::DEBUG)) { + debug() << "found " << groups.size() << " potential clusters (groups of hits)" << endmsg; + for (size_t i = 0; i < groups.size(); ++i) { + debug() << fmt::format("group {}: {} hits", i, groups[i].size()) << endmsg; } - - // using juggler internal units (GeV, mm, ns, rad) - localDistXY[0] = u_localDistXY.value()[0]/mm; - localDistXY[1] = u_localDistXY.value()[1]/mm; - layerDistEtaPhi[0] = u_layerDistEtaPhi.value()[0]; - layerDistEtaPhi[1] = u_layerDistEtaPhi.value()[1]/rad; - sectorDist = m_sectorDist.value()/mm; - minClusterHitEdep = m_minClusterHitEdep.value()/GeV; - minClusterCenterEdep = m_minClusterCenterEdep.value()/GeV; - minClusterEdep = m_minClusterEdep.value()/GeV; - - // summarize the clustering parameters - info() << fmt::format("Local clustering (same sector and same layer): " - "Local [x, y] distance between hits <= [{:.4f} mm, {:.4f} mm].", - localDistXY[0], localDistXY[1]) << endmsg; - info() << fmt::format("Neighbour layers clustering (same sector and layer id within +- {:d}: " - "Global [eta, phi] distance between hits <= [{:.4f}, {:.4f} rad].", - m_neighbourLayersRange.value(), layerDistEtaPhi[0], layerDistEtaPhi[1]) << endmsg; - info() << fmt::format("Neighbour sectors clustering (different sector): " - "Global distance between hits <= {:.4f} mm.", - sectorDist) << endmsg; - - return StatusCode::SUCCESS; } - StatusCode execute() override - { - // input collections - const auto& hits = *m_inputHitCollection.get(); - // Create output collections - auto& proto = *m_outputProtoClusterCollection.createAndPut(); - - // group neighboring hits - std::vector<bool> visits(hits.size(), false); - std::vector<std::vector<std::pair<uint32_t, eic::ConstCalorimeterHit>>> groups; - for (size_t i = 0; i < hits.size(); ++i) { - if (msgLevel(MSG::DEBUG)) { - debug() << fmt::format("hit {:d}: local position = ({}, {}, {}), global position = ({}, {}, {})", i + 1, - hits[i].local().x, hits[i].local().y, hits[i].position().z, hits[i].position().x, - hits[i].position().y, hits[i].position().z) - << endmsg; - } - // already in a group, or not energetic enough to form a cluster - if (visits[i] || hits[i].energy() < minClusterCenterEdep) { - continue; - } - groups.emplace_back(); - // create a new group, and group all the neighboring hits - dfs_group(groups.back(), i, hits, visits); + // form clusters + for (const auto& group : groups) { + if (static_cast<int>(group.size()) < m_minClusterNhits.value()) { + continue; } - if (msgLevel(MSG::DEBUG)) { - debug() << "found " << groups.size() << " potential clusters (groups of hits)" << endmsg; - for (size_t i = 0; i < groups.size(); ++i) { - debug() << fmt::format("group {}: {} hits", i, groups[i].size()) << endmsg; - } + double energy = 0.; + for (const auto& [idx, hit] : group) { + energy += hit.energy(); } - - // form clusters - for (const auto& group : groups) { - if (static_cast<int>(group.size()) < m_minClusterNhits.value()) { - continue; - } - double energy = 0.; - for (const auto& [idx, hit] : group) { - energy += hit.energy(); - } - if (energy < minClusterEdep) { - continue; - } - auto pcl = proto.create(); - for (const auto& [idx, hit] : group) { - pcl.addhits(hit); - } + if (energy < minClusterEdep) { + continue; + } + auto pcl = proto.create(); + for (const auto& [idx, hit] : group) { + pcl.addhits(hit); } - - return StatusCode::SUCCESS; } - private: - template <typename T> - static inline T pow2(const T& x) - { - return x * x; - } + return StatusCode::SUCCESS; + } - // helper function to group hits - bool is_neighbor(const eic::ConstCalorimeterHit& h1, const eic::ConstCalorimeterHit& h2) const - { - // different sectors, simple distance check - if (h1.sector() != h2.sector()) { - return std::sqrt(pow2(h1.position().x - h2.position().x) + pow2(h1.position().y - h2.position().y) + pow2(h1.position().z - h2.position().z)) <= - sectorDist; - } +private: + template <typename T> static inline T pow2(const T& x) { return x * x; } - // layer check - int ldiff = std::abs(h1.layer() - h2.layer()); - // same layer, check local positions - if (!ldiff) { - return (std::abs(h1.local().x - h2.local().x) <= localDistXY[0]) && - (std::abs(h1.local().y - h2.local().y) <= localDistXY[1]); - } else if (ldiff <= m_neighbourLayersRange) { - return (std::abs(h1.position().eta() - h2.position().eta()) <= layerDistEtaPhi[0]) && - (std::abs(h1.position().phi() - h2.position().phi()) <= layerDistEtaPhi[1]); - } + // helper function to group hits + bool is_neighbor(const eic::ConstCalorimeterHit& h1, const eic::ConstCalorimeterHit& h2) const { + // different sectors, simple distance check + if (h1.sector() != h2.sector()) { + return std::sqrt(pow2(h1.position().x - h2.position().x) + pow2(h1.position().y - h2.position().y) + + pow2(h1.position().z - h2.position().z)) <= sectorDist; + } - // not in adjacent layers - return false; + // layer check + int ldiff = std::abs(h1.layer() - h2.layer()); + // same layer, check local positions + if (!ldiff) { + return (std::abs(h1.local().x - h2.local().x) <= localDistXY[0]) && + (std::abs(h1.local().y - h2.local().y) <= localDistXY[1]); + } else if (ldiff <= m_neighbourLayersRange) { + return (std::abs(eicd::eta(h1.position()) - eicd::eta(h2.position())) <= layerDistEtaPhi[0]) && + (std::abs(eicd::angleAzimuthal(h1.position()) - eicd::angleAzimuthal(h2.position())) <= + layerDistEtaPhi[1]); } - // grouping function with Depth-First Search - void dfs_group(std::vector<std::pair<uint32_t, eic::ConstCalorimeterHit>>& group, int idx, - const eic::CalorimeterHitCollection& hits, std::vector<bool>& visits) const - { - // not a qualified hit to participate in clustering, stop here - if (hits[idx].energy() < minClusterHitEdep) { - visits[idx] = true; - return; - } + // not in adjacent layers + return false; + } - group.push_back({idx, hits[idx]}); + // grouping function with Depth-First Search + void dfs_group(std::vector<std::pair<uint32_t, eic::ConstCalorimeterHit>>& group, int idx, + const eic::CalorimeterHitCollection& hits, std::vector<bool>& visits) const { + // not a qualified hit to participate in clustering, stop here + if (hits[idx].energy() < minClusterHitEdep) { visits[idx] = true; - for (size_t i = 0; i < hits.size(); ++i) { - // visited, or not a neighbor - if (visits[i] || !is_neighbor(hits[idx], hits[i])) { - continue; - } - dfs_group(group, i, hits, visits); + return; + } + + group.push_back({idx, hits[idx]}); + visits[idx] = true; + for (size_t i = 0; i < hits.size(); ++i) { + // visited, or not a neighbor + if (visits[i] || !is_neighbor(hits[idx], hits[i])) { + continue; } + dfs_group(group, i, hits, visits); } - }; // namespace Jug::Reco + } +}; // namespace Jug::Reco - DECLARE_COMPONENT(ImagingTopoCluster) +DECLARE_COMPONENT(ImagingTopoCluster) } // namespace Jug::Reco diff --git a/JugReco/src/components/SimpleClustering.cpp b/JugReco/src/components/SimpleClustering.cpp index 671eac3bd79cb10d2626bbbc889224d732859e87..cd14b39cccabb534f76394e384984c0a214cf505 100644 --- a/JugReco/src/components/SimpleClustering.cpp +++ b/JugReco/src/components/SimpleClustering.cpp @@ -21,6 +21,7 @@ #include "eicd/ClusterCollection.h" #include "eicd/ProtoClusterCollection.h" #include "eicd/RawCalorimeterHitCollection.h" +#include "eicd/vector_utils.h" using namespace Gaudi::Units; @@ -122,7 +123,7 @@ namespace Jug::Reco { std::vector<std::pair<uint32_t, eic::ConstCalorimeterHit>> cluster_hits; for (const auto& [idx, h] : the_hits) { - if (h.position().subtract(ref_hit.position()).mag() < max_dist) { + if (eicd::magnitude(h.position() - ref_hit.position()) < max_dist) { cluster_hits.push_back({idx, h}); } else { remaining_hits.push_back({idx, h}); @@ -142,7 +143,7 @@ namespace Jug::Reco { auto pcl = proto.create(); for (const auto& [idx, h] : cluster_hits) { cl.energy(cl.energy() + h.energy()); - cl.position(cl.position().add(h.position().scale(h.energy()/total_energy))); + cl.position(cl.position() + (h.position() * h.energy() / total_energy)); pcl.addhits(h); } // Optionally store the MC truth associated with the first hit in this cluster diff --git a/JugTrack/src/components/GenFitTrackFitter.cpp b/JugTrack/src/components/GenFitTrackFitter.cpp index c31d2a91976c02839ffa10dba83ed3f3b2ac9a41..3169faa6928c127198967a760a2c3829f4cde9ce 100644 --- a/JugTrack/src/components/GenFitTrackFitter.cpp +++ b/JugTrack/src/components/GenFitTrackFitter.cpp @@ -20,6 +20,7 @@ #include "JugTrack/Track.hpp" #include "eicd/TrackerHitCollection.h" +#include "eicd/vector_utils.h" #include <functional> #include <random> @@ -129,7 +130,7 @@ namespace Jug::Reco { ROOT::Math::XYZVector tp(track_param.momentum()[0], track_param.momentum()[1], track_param.momentum()[2]); auto first_hit = (*hits)[proto_track[0]]; - auto first_hit_phi = first_hit.position().phi(); + auto first_hit_phi = eicd::angleAzimuthal(first_hit.position()); auto track_param_phi = tp.phi(); if (msgLevel(MSG::DEBUG)) { debug() << " first hit phi: " << first_hit_phi << endmsg; diff --git a/JugTrack/src/components/ParticlesFromTrackFit.cpp b/JugTrack/src/components/ParticlesFromTrackFit.cpp index 49803460ddaea7ff80a98a25e7c570acdc8c92e7..02fc59100ef927f238ff15dc8397ab0cb22177b6 100644 --- a/JugTrack/src/components/ParticlesFromTrackFit.cpp +++ b/JugTrack/src/components/ParticlesFromTrackFit.cpp @@ -116,14 +116,14 @@ namespace Jug::Reco { debug() << " chi2 = " << trajState.chi2Sum << endmsg; } - const eic::CovXYZ covMomentum { + const eicd::Cov3f covMomentum { static_cast<float>(covariance(Acts::eBoundTheta, Acts::eBoundTheta)), static_cast<float>(covariance(Acts::eBoundPhi, Acts::eBoundPhi)), static_cast<float>(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)), static_cast<float>(covariance(Acts::eBoundTheta, Acts::eBoundPhi)), static_cast<float>(covariance(Acts::eBoundTheta, Acts::eBoundQOverP)), static_cast<float>(covariance(Acts::eBoundPhi, Acts::eBoundQOverP))}; - const eic::CovXY covPos { + const eicd::Cov2f covPos { static_cast<float>(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0)), static_cast<float>(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1)), static_cast<float>(covariance(Acts::eBoundLoc0, Acts::eBoundLoc1))}; diff --git a/JugTrack/src/components/TrackParamImagingClusterInit.cpp b/JugTrack/src/components/TrackParamImagingClusterInit.cpp index f6eb347c997c720948ada935b497fc25bb0942e0..dd35c7689cc31b9aa87932c8f91aa1bb38b5c91f 100644 --- a/JugTrack/src/components/TrackParamImagingClusterInit.cpp +++ b/JugTrack/src/components/TrackParamImagingClusterInit.cpp @@ -15,8 +15,8 @@ #include "eicd/TrackerHitCollection.h" #include "eicd/ClusterCollection.h" +#include "eicd/vector_utils.h" -#include "Math/Vector3D.h" #include "Acts/Surfaces/PerigeeSurface.hpp" ///// (Reconstructed) track parameters e.g. close to the vertex. @@ -76,28 +76,19 @@ namespace Jug::Reco { using Acts::UnitConstants::mm; using Acts::UnitConstants::ns; - double p = c.energy()*GeV; + const double p = c.energy()*GeV; // FIXME hardcoded value if( p < 0.1*GeV) { continue; } - double len = c.position().mag(); - ROOT::Math::XYZVector momentum(c.position().x * p / len, c.position().y * p / len, c.position().z * p / len); - - // build some track cov matrix - //Acts::BoundSymMatrix cov = Acts::BoundSymMatrix::Zero(); - //cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = 1.0 * mm*1.0 * mm; - //cov(Acts::eBoundLoc1, Acts::eBoundLoc1) = 1.0 * mm*1.0 * mm; - //cov(Acts::eBoundPhi, Acts::eBoundPhi) = M_PI / 180.0; - //cov(Acts::eBoundTheta, Acts::eBoundTheta) = M_PI / 180.0; - //cov(Acts::eBoundQOverP, Acts::eBoundQOverP) = 1.0 / (p*p); - //cov(Acts::eBoundTime, Acts::eBoundTime) = Acts::UnitConstants::ns; + const double theta = eicd::anglePolar(c.position()); + const double phi = eicd::angleAzimuthal(c.position()); Acts::BoundVector params; params(Acts::eBoundLoc0) = 0.0 * mm ; params(Acts::eBoundLoc1) = 0.0 * mm ; - params(Acts::eBoundPhi) = momentum.Phi(); - params(Acts::eBoundTheta) = momentum.Theta(); + params(Acts::eBoundPhi) = phi; + params(Acts::eBoundTheta) = theta; params(Acts::eBoundQOverP) = 1/p; params(Acts::eBoundTime) = 0 * ns; @@ -111,24 +102,12 @@ namespace Jug::Reco { Acts::BoundVector params2; params2(Acts::eBoundLoc0) = 0.0 * mm ; params2(Acts::eBoundLoc1) = 0.0 * mm ; - params2(Acts::eBoundPhi) = momentum.Phi(); - params2(Acts::eBoundTheta) = momentum.Theta(); + params2(Acts::eBoundPhi) = phi; + params2(Acts::eBoundTheta) = theta; params2(Acts::eBoundQOverP) = -1/p; params2(Acts::eBoundTime) = 0 * ns; init_trk_params->push_back({pSurface, params2, -1}); - // acts v1.2.0: - //init_trk_params->emplace_back(Acts::Vector4(0 * mm, 0 * mm, 0 * mm, 0), - // Acts::Vector3(c.x() * p / len, c.y() * p / len, c.z() * p / len), p, -1, - // std::make_optional(cov)); - //debug() << init_trk_params->back() << endmsg; - //init_trk_params->emplace_back(Acts::Vector4(0 * mm, 0 * mm, 0 * mm, 0), - // Acts::Vector3(c.x() * p / len, c.y() * p / len, c.z() * p / len), p, 1, - // std::make_optional(cov)); - ////debug() << init_trk_params->back() << endmsg; - //init_trk_params->emplace_back(Acts::Vector4(0 * mm, 0 * mm, 0 * mm, 0), - // Acts::Vector3(c.x() * p / len, c.y() * p / len, c.z() * p / len), p, 0, - // std::make_optional(cov)); } return StatusCode::SUCCESS; }