File indexing completed on 2025-01-18 09:13:15
0001
0002
0003
0004 #include <algorithm>
0005
0006
0007 #include "GaudiAlg/GaudiAlgorithm.h"
0008 #include "GaudiKernel/ToolHandle.h"
0009 #include "GaudiAlg/Transformer.h"
0010 #include "GaudiAlg/GaudiTool.h"
0011 #include "GaudiKernel/RndmGenerators.h"
0012 #include "Gaudi/Property.h"
0013
0014 #include "DDRec/CellIDPositionConverter.h"
0015 #include "DDRec/SurfaceManager.h"
0016 #include "DDRec/Surface.h"
0017
0018 #include "JugBase/DataHandle.h"
0019 #include "JugBase/IGeoSvc.h"
0020
0021 #include "Acts/EventData/MultiTrajectory.hpp"
0022 #include "Acts/EventData/MultiTrajectoryHelpers.hpp"
0023
0024
0025 #include "edm4eic/ReconstructedParticleCollection.h"
0026 #include "edm4eic/TrackerHitCollection.h"
0027 #include "edm4eic/TrackParametersCollection.h"
0028 #include "JugTrack/IndexSourceLink.hpp"
0029 #include "JugTrack/Track.hpp"
0030 #include "JugTrack/Trajectories.hpp"
0031
0032 #include "Acts/Utilities/Helpers.hpp"
0033
0034 #include "edm4hep/utils/vector_utils.h"
0035
0036 #include <cmath>
0037
0038 namespace Jug::Reco {
0039
0040
0041
0042
0043
0044 class ParticlesFromTrackFit : public GaudiAlgorithm {
0045 private:
0046 DataHandle<TrajectoriesContainer> m_inputTrajectories{"inputTrajectories", Gaudi::DataHandle::Reader, this};
0047 DataHandle<edm4eic::ReconstructedParticleCollection> m_outputParticles{"outputParticles", Gaudi::DataHandle::Writer, this};
0048 DataHandle<edm4eic::TrackParametersCollection> m_outputTrackParameters{"outputTrackParameters", Gaudi::DataHandle::Writer, this};
0049
0050 public:
0051
0052 ParticlesFromTrackFit(const std::string& name, ISvcLocator* svcLoc)
0053 : GaudiAlgorithm(name, svcLoc) {
0054 declareProperty("inputTrajectories", m_inputTrajectories,"");
0055 declareProperty("outputParticles", m_outputParticles, "");
0056 declareProperty("outputTrackParameters", m_outputTrackParameters, "Acts Track Parameters");
0057 }
0058
0059 StatusCode initialize() override {
0060 if (GaudiAlgorithm::initialize().isFailure()) {
0061 return StatusCode::FAILURE;
0062 }
0063 return StatusCode::SUCCESS;
0064 }
0065
0066 StatusCode execute() override {
0067
0068 const auto* const trajectories = m_inputTrajectories.get();
0069
0070 auto* rec_parts = m_outputParticles.createAndPut();
0071 auto* track_pars = m_outputTrackParameters.createAndPut();
0072
0073 if (msgLevel(MSG::DEBUG)) {
0074 debug() << std::size(*trajectories) << " trajectories " << endmsg;
0075 }
0076
0077
0078 for (const auto& traj : *trajectories) {
0079
0080
0081
0082 const auto& mj = traj.multiTrajectory();
0083 const auto& trackTips = traj.tips();
0084 if (trackTips.empty()) {
0085 if (msgLevel(MSG::DEBUG)) {
0086 debug() << "Empty multiTrajectory." << endmsg;
0087 }
0088 continue;
0089 }
0090
0091 const auto& trackTip = trackTips.front();
0092
0093
0094 auto trajState = Acts::MultiTrajectoryHelpers::trajectoryState(mj, trackTip);
0095
0096
0097
0098
0099
0100 if (traj.hasTrackParameters(trackTip)) {
0101 const auto& boundParam = traj.trackParameters(trackTip);
0102 const auto& parameter = boundParam.parameters();
0103 const auto& covariance = *boundParam.covariance();
0104 if (msgLevel(MSG::DEBUG)) {
0105 debug() << "loc 0 = " << parameter[Acts::eBoundLoc0] << endmsg;
0106 debug() << "loc 1 = " << parameter[Acts::eBoundLoc1] << endmsg;
0107 debug() << "phi = " << parameter[Acts::eBoundPhi] << endmsg;
0108 debug() << "theta = " << parameter[Acts::eBoundTheta] << endmsg;
0109 debug() << "q/p = " << parameter[Acts::eBoundQOverP] << endmsg;
0110 debug() << "p = " << 1.0 / parameter[Acts::eBoundQOverP] << endmsg;
0111
0112 debug() << "err phi = " << sqrt(covariance(Acts::eBoundPhi, Acts::eBoundPhi)) << endmsg;
0113 debug() << "err th = " << sqrt(covariance(Acts::eBoundTheta, Acts::eBoundTheta)) << endmsg;
0114 debug() << "err q/p = " << sqrt(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)) << endmsg;
0115
0116 debug() << " chi2 = " << trajState.chi2Sum << endmsg;
0117 }
0118
0119 const decltype(edm4eic::TrackParametersData::loc) loc {
0120 static_cast<float>(parameter[Acts::eBoundLoc0]),
0121 static_cast<float>(parameter[Acts::eBoundLoc1])
0122 };
0123 const decltype(edm4eic::TrackParametersData::momentumError) momentumError {
0124 static_cast<float>(covariance(Acts::eBoundTheta, Acts::eBoundTheta)),
0125 static_cast<float>(covariance(Acts::eBoundPhi, Acts::eBoundPhi)),
0126 static_cast<float>(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)),
0127 static_cast<float>(covariance(Acts::eBoundTheta, Acts::eBoundPhi)),
0128 static_cast<float>(covariance(Acts::eBoundTheta, Acts::eBoundQOverP)),
0129 static_cast<float>(covariance(Acts::eBoundPhi, Acts::eBoundQOverP))};
0130 const decltype(edm4eic::TrackParametersData::locError) locError {
0131 static_cast<float>(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0)),
0132 static_cast<float>(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1)),
0133 static_cast<float>(covariance(Acts::eBoundLoc0, Acts::eBoundLoc1))};
0134 const float timeError{sqrt(static_cast<float>(covariance(Acts::eBoundTime, Acts::eBoundTime)))};
0135
0136 edm4eic::TrackParameters pars{
0137 0,
0138 loc,
0139 locError,
0140 static_cast<float>(parameter[Acts::eBoundTheta]),
0141 static_cast<float>(parameter[Acts::eBoundPhi]),
0142 static_cast<float>(parameter[Acts::eBoundQOverP]),
0143 momentumError,
0144 static_cast<float>(parameter[Acts::eBoundTime]),
0145 timeError,
0146 static_cast<float>(boundParam.charge())};
0147 track_pars->push_back(pars);
0148 }
0149
0150 auto tsize = trackTips.size();
0151 if (msgLevel(MSG::DEBUG)) {
0152 debug() << "# fitted parameters : " << tsize << endmsg;
0153 }
0154 if (tsize == 0) {
0155 continue;
0156 }
0157
0158 mj.visitBackwards(tsize - 1, [&](auto&& trackstate) {
0159
0160
0161 auto params = trackstate.predicted();
0162
0163 double p0 = (1.0 / params[Acts::eBoundQOverP]) / Acts::UnitConstants::GeV;
0164 if (msgLevel(MSG::DEBUG)) {
0165 debug() << "track predicted p = " << p0 << " GeV" << endmsg;
0166 }
0167 if (std::abs(p0) > 500) {
0168 if (msgLevel(MSG::DEBUG)) {
0169 debug() << "skipping" << endmsg;
0170 }
0171 return;
0172 }
0173
0174 auto rec_part = rec_parts->create();
0175 rec_part.setMomentum(
0176 edm4hep::utils::sphericalToVector(
0177 1.0 / std::abs(params[Acts::eBoundQOverP]),
0178 params[Acts::eBoundTheta],
0179 params[Acts::eBoundPhi])
0180 );
0181 rec_part.setCharge(static_cast<int16_t>(std::copysign(1., params[Acts::eBoundQOverP])));
0182 });
0183 }
0184
0185 return StatusCode::SUCCESS;
0186 }
0187
0188 };
0189
0190 DECLARE_COMPONENT(ParticlesFromTrackFit)
0191
0192 }