File indexing completed on 2025-12-15 09:29:17
0001
0002
0003
0004 #include <DD4hep/Fields.h>
0005 #include <Evaluator/DD4hepUnits.h>
0006 #include <Math/GenVector/Cartesian3D.h>
0007 #include <Math/GenVector/DisplacementVector3D.h>
0008 #include <edm4eic/VertexCollection.h>
0009 #include <edm4eic/unit_system.h>
0010 #include <edm4hep/Vector3f.h>
0011 #include <edm4hep/Vector4f.h>
0012 #include <edm4hep/utils/vector_utils.h>
0013 #include <fmt/core.h>
0014 #include <cmath>
0015 #include <gsl/pointers>
0016 #include <utility>
0017 #include <vector>
0018
0019 #include "algorithms/reco/Helix.h"
0020 #include "algorithms/reco/SecondaryVerticesHelix.h"
0021 #include "algorithms/reco/SecondaryVerticesHelixConfig.h"
0022 #include "services/particle/ParticleSvc.h"
0023
0024 namespace eicrecon {
0025
0026
0027
0028
0029
0030 void SecondaryVerticesHelix::init() {}
0031
0032
0033
0034
0035
0036
0037
0038 void SecondaryVerticesHelix::process(const SecondaryVerticesHelix::Input& input,
0039 const SecondaryVerticesHelix::Output& output) const {
0040 const auto [rcvtx, rcparts] = input;
0041 auto [out_secondary_vertices] = output;
0042
0043 auto& particleSvc = algorithms::ParticleSvc::instance();
0044
0045 if ((*rcvtx).size() == 0) {
0046 info("No primary vertex in this event! Skip secondary vertex finder!");
0047 return;
0048 }
0049 const auto pVtxPos4f = (*rcvtx)[0].getPosition();
0050
0051 edm4hep::Vector3f pVtxPos(pVtxPos4f.x * edm4eic::unit::mm / edm4eic::unit::cm,
0052 pVtxPos4f.y * edm4eic::unit::mm / edm4eic::unit::cm,
0053 pVtxPos4f.z * edm4eic::unit::mm / edm4eic::unit::cm);
0054
0055 auto fieldObj = m_det->field();
0056 auto field = fieldObj.magneticField(
0057 {pVtxPos4f.x / edm4eic::unit::mm * dd4hep::mm, pVtxPos4f.y / edm4eic::unit::mm * dd4hep::mm,
0058 pVtxPos4f.z / edm4eic::unit::mm * dd4hep::mm});
0059 float b_field = field.z();
0060
0061 info("\tPrimary vertex = ({},{},{})cm \t b field = {} tesla", pVtxPos.x, pVtxPos.y, pVtxPos.z,
0062 b_field / dd4hep::tesla);
0063
0064 std::vector<Helix> hVec;
0065 hVec.clear();
0066 std::vector<unsigned int> indexVec;
0067 indexVec.clear();
0068 for (unsigned int i = 0; const auto& p : *rcparts) {
0069 if (p.getCharge() == 0)
0070 continue;
0071 Helix h(p, b_field);
0072 double dca = h.distance(pVtxPos) * edm4eic::unit::cm;
0073 if (dca < m_cfg.minDca)
0074 continue;
0075
0076 hVec.push_back(h);
0077 indexVec.push_back(i);
0078 ++i;
0079 }
0080
0081 if (hVec.size() != indexVec.size())
0082 return;
0083
0084 debug("\tVector size {}, {}", hVec.size(), indexVec.size());
0085
0086 for (unsigned int i1 = 0; i1 < hVec.size(); ++i1) {
0087 for (unsigned int i2 = i1 + 1; i2 < hVec.size(); ++i2) {
0088 const auto& p1 = (*rcparts)[indexVec[i1]];
0089 const auto& p2 = (*rcparts)[indexVec[i2]];
0090
0091 if (!(m_cfg.unlikesign && p1.getCharge() + p2.getCharge() == 0))
0092 continue;
0093
0094 const auto& h1 = hVec[i1];
0095 const auto& h2 = hVec[i2];
0096
0097
0098 double dca1 = h1.distance(pVtxPos) * edm4eic::unit::cm;
0099 double dca2 = h2.distance(pVtxPos) * edm4eic::unit::cm;
0100 if (dca1 < m_cfg.minDca || dca2 < m_cfg.minDca)
0101 continue;
0102
0103 std::pair<double, double> const ss = h1.pathLengths(h2);
0104 edm4hep::Vector3f h1AtDcaTo2 = h1.at(ss.first);
0105 edm4hep::Vector3f h2AtDcaTo1 = h2.at(ss.second);
0106
0107 double dca12 = edm4hep::utils::magnitude(h1AtDcaTo2 - h2AtDcaTo1) * edm4eic::unit::cm;
0108 if (std::isnan(dca12))
0109 continue;
0110 if (dca12 > m_cfg.maxDca12)
0111 continue;
0112 edm4hep::Vector3f pairPos = 0.5 * (h1AtDcaTo2 + h2AtDcaTo1);
0113
0114 edm4hep::Vector3f h1MomAtDca = h1.momentumAt(ss.first, b_field);
0115 edm4hep::Vector3f h2MomAtDca = h2.momentumAt(ss.second, b_field);
0116 edm4hep::Vector3f pairMom = h1MomAtDca + h2MomAtDca;
0117
0118 double e1 =
0119 std::hypot(edm4hep::utils::magnitude(h1MomAtDca), particleSvc.particle(p1.getPDG()).mass);
0120 double e2 =
0121 std::hypot(edm4hep::utils::magnitude(h2MomAtDca), particleSvc.particle(p2.getPDG()).mass);
0122 double pairE = e1 + e2;
0123 double angle = edm4hep::utils::angleBetween(pairMom, pairPos - pVtxPos);
0124 if (cos(angle) < m_cfg.minCostheta)
0125 continue;
0126
0127 double beta = edm4hep::utils::magnitude(pairMom) / pairE;
0128 double time = edm4hep::utils::magnitude(pairPos - pVtxPos) / (beta * dd4hep::c_light);
0129 edm4hep::Vector3f dL = pairPos - pVtxPos;
0130 edm4hep::Vector3f decayL(dL.x * edm4eic::unit::cm, dL.y * edm4eic::unit::cm,
0131 dL.z * edm4eic::unit::cm);
0132 double dca2pv = edm4hep::utils::magnitude(decayL) * sin(angle);
0133 if (dca2pv > m_cfg.maxDca)
0134 continue;
0135
0136 auto v0 = out_secondary_vertices->create();
0137 v0.setType(2);
0138 v0.setPosition({(float)(pairPos.x * edm4eic::unit::cm / edm4eic::unit::mm),
0139 (float)(pairPos.y * edm4eic::unit::cm / edm4eic::unit::mm),
0140 (float)(pairPos.z * edm4eic::unit::cm / edm4eic::unit::mm), (float)time});
0141 v0.addToAssociatedParticles(p1);
0142 v0.addToAssociatedParticles(p2);
0143
0144 info("One secondary vertex found at (x,y,z) = ({}, {}, {}) mm.",
0145 pairPos.x * edm4eic::unit::cm / edm4eic::unit::mm,
0146 pairPos.y * edm4eic::unit::cm / edm4eic::unit::mm,
0147 pairPos.x * edm4eic::unit::cm / edm4eic::unit::mm);
0148
0149 }
0150 }
0151
0152 }
0153
0154 }