File indexing completed on 2025-02-22 09:55:36
0001
0002
0003
0004 #include "Gaudi/Algorithm.h"
0005 #include "GaudiAlg/GaudiTool.h"
0006 #include "GaudiAlg/Producer.h"
0007 #include "GaudiAlg/Transformer.h"
0008 #include "GaudiKernel/RndmGenerators.h"
0009 #include "GaudiKernel/PhysicalConstants.h"
0010 #include <algorithm>
0011 #include <cmath>
0012
0013 #include "JugBase/IParticleSvc.h"
0014 #include "JugBase/DataHandle.h"
0015
0016 #include "JugBase/Utilities/Beam.h"
0017
0018 #include "Math/Vector4D.h"
0019 using ROOT::Math::PxPyPzEVector;
0020
0021
0022 #include "edm4hep/MCParticleCollection.h"
0023 #include "edm4eic/InclusiveKinematicsCollection.h"
0024
0025 #include "edm4hep/utils/vector_utils.h"
0026
0027 namespace Jug::Fast {
0028
0029 class InclusiveKinematicsTruth : public GaudiAlgorithm {
0030 private:
0031 DataHandle<edm4hep::MCParticleCollection> m_inputMCParticleCollection{
0032 "inputMCParticles",
0033 Gaudi::DataHandle::Reader,
0034 this};
0035 DataHandle<edm4eic::InclusiveKinematicsCollection> m_outputInclusiveKinematicsCollection{
0036 "outputInclusiveKinematics",
0037 Gaudi::DataHandle::Writer,
0038 this};
0039
0040 SmartIF<IParticleSvc> m_pidSvc;
0041 double m_proton{0};
0042 double m_neutron{0};
0043 double m_electron{0};
0044
0045 public:
0046 InclusiveKinematicsTruth(const std::string& name, ISvcLocator* svcLoc)
0047 : GaudiAlgorithm(name, svcLoc) {
0048 declareProperty("inputMCParticles", m_inputMCParticleCollection, "MCParticles");
0049 declareProperty("outputInclusiveKinematics", m_outputInclusiveKinematicsCollection, "InclusiveKinematicsTruth");
0050 }
0051
0052 StatusCode initialize() override {
0053 if (GaudiAlgorithm::initialize().isFailure()) {
0054 return StatusCode::FAILURE;
0055 }
0056
0057 m_pidSvc = service("ParticleSvc");
0058 if (!m_pidSvc) {
0059 error() << "Unable to locate Particle Service. "
0060 << "Make sure you have ParticleSvc in the configuration."
0061 << endmsg;
0062 return StatusCode::FAILURE;
0063 }
0064 m_proton = m_pidSvc->particle(2212).mass;
0065 m_neutron = m_pidSvc->particle(2112).mass;
0066 m_electron = m_pidSvc->particle(11).mass;
0067
0068 return StatusCode::SUCCESS;
0069 }
0070
0071 StatusCode execute() override {
0072
0073 const auto& mcparts = *(m_inputMCParticleCollection.get());
0074
0075 auto& out_kinematics = *(m_outputInclusiveKinematicsCollection.createAndPut());
0076
0077
0078
0079
0080
0081
0082
0083
0084 const auto ei_coll = Jug::Base::Beam::find_first_beam_electron(mcparts);
0085 if (ei_coll.size() == 0) {
0086 if (msgLevel(MSG::DEBUG)) {
0087 debug() << "No beam electron found" << endmsg;
0088 }
0089 return StatusCode::SUCCESS;
0090 }
0091 const auto ei_p = ei_coll[0].getMomentum();
0092 const auto ei_p_mag = edm4hep::utils::magnitude(ei_p);
0093 const auto ei_mass = m_electron;
0094 const PxPyPzEVector ei(ei_p.x, ei_p.y, ei_p.z, std::hypot(ei_p_mag, ei_mass));
0095
0096
0097 const auto pi_coll = Jug::Base::Beam::find_first_beam_hadron(mcparts);
0098 if (pi_coll.size() == 0) {
0099 if (msgLevel(MSG::DEBUG)) {
0100 debug() << "No beam hadron found" << endmsg;
0101 }
0102 return StatusCode::SUCCESS;
0103 }
0104 const auto pi_p = pi_coll[0].getMomentum();
0105 const auto pi_p_mag = edm4hep::utils::magnitude(pi_p);
0106 const auto pi_mass = pi_coll[0].getPDG() == 2212 ? m_proton : m_neutron;
0107 const PxPyPzEVector pi(pi_p.x, pi_p.y, pi_p.z, std::hypot(pi_p_mag, pi_mass));
0108
0109
0110
0111
0112
0113
0114 const auto ef_coll = Jug::Base::Beam::find_first_scattered_electron(mcparts);
0115 if (ef_coll.size() == 0) {
0116 if (msgLevel(MSG::DEBUG)) {
0117 debug() << "No truth scattered electron found" << endmsg;
0118 }
0119 return StatusCode::SUCCESS;
0120 }
0121 const auto ef_p = ef_coll[0].getMomentum();
0122 const auto ef_p_mag = edm4hep::utils::magnitude(ef_p);
0123 const auto ef_mass = m_electron;
0124 const PxPyPzEVector ef(ef_p.x, ef_p.y, ef_p.z, std::hypot(ef_p_mag, ef_mass));
0125
0126
0127 const auto q = ei - ef;
0128 const auto q_dot_pi = q.Dot(pi);
0129 const auto Q2 = -q.Dot(q);
0130 const auto y = q_dot_pi / ei.Dot(pi);
0131 const auto nu = q_dot_pi / pi_mass;
0132 const auto x = Q2 / (2.*q_dot_pi);
0133 const auto W = sqrt(pi_mass*pi_mass + 2.*q_dot_pi - Q2);
0134 const auto kin = out_kinematics.create(x, Q2, W, y, nu);
0135
0136
0137 if (msgLevel(MSG::DEBUG)) {
0138 debug() << "pi = " << pi << endmsg;
0139 debug() << "ei = " << ei << endmsg;
0140 debug() << "ef = " << ef << endmsg;
0141 debug() << "q = " << q << endmsg;
0142 debug() << "x,Q2,W,y,nu = "
0143 << kin.getX() << ","
0144 << kin.getQ2() << ","
0145 << kin.getW() << ","
0146 << kin.getY() << ","
0147 << kin.getNu()
0148 << endmsg;
0149 }
0150
0151 return StatusCode::SUCCESS;
0152 }
0153 };
0154
0155
0156 DECLARE_COMPONENT(InclusiveKinematicsTruth)
0157
0158 }