File indexing completed on 2025-07-02 08:55:47
0001
0002
0003
0004 #include <algorithm>
0005
0006
0007 #include "Gaudi/Algorithm.h"
0008 #include "GaudiKernel/ToolHandle.h"
0009 #include "GaudiKernel/RndmGenerators.h"
0010 #include "Gaudi/Property.h"
0011
0012 #include "DDRec/CellIDPositionConverter.h"
0013 #include "DDRec/SurfaceManager.h"
0014 #include "DDRec/Surface.h"
0015
0016 #include <k4FWCore/DataHandle.h>
0017 #include <k4Interface/IGeoSvc.h>
0018
0019 #include "Acts/EventData/MultiTrajectory.hpp"
0020 #include "Acts/EventData/MultiTrajectoryHelpers.hpp"
0021
0022
0023 #include "edm4eic/EDM4eicVersion.h"
0024 #include "edm4eic/TrackerHitCollection.h"
0025 #include "edm4eic/TrackParametersCollection.h"
0026 #include "edm4eic/TrajectoryCollection.h"
0027 #include "edm4eic/TrackSegmentCollection.h"
0028 #include "ActsExamples/EventData/IndexSourceLink.hpp"
0029 #include "ActsExamples/EventData/Track.hpp"
0030 #include "ActsExamples/EventData/Trajectories.hpp"
0031
0032 #include "Acts/Utilities/Helpers.hpp"
0033 #include "Acts/Geometry/GeometryIdentifier.hpp"
0034 #include "Acts/MagneticField/ConstantBField.hpp"
0035 #include "Acts/MagneticField/InterpolatedBFieldMap.hpp"
0036 #include "Acts/Propagator/EigenStepper.hpp"
0037 #include "Acts/Surfaces/PerigeeSurface.hpp"
0038
0039 #include "edm4hep/utils/vector_utils.h"
0040
0041 #include <cmath>
0042
0043 namespace Jug::Reco {
0044
0045
0046
0047
0048
0049 class TrackProjector : public Gaudi::Algorithm {
0050 private:
0051 mutable DataHandle<ActsExamples::TrajectoriesContainer> m_inputTrajectories{"inputTrajectories", Gaudi::DataHandle::Reader, this};
0052 mutable DataHandle<edm4eic::TrackSegmentCollection> m_outputTrackSegments{"outputTrackSegments", Gaudi::DataHandle::Writer, this};
0053
0054 Gaudi::Property<unsigned int> m_firstInVolumeID{this, "firstInVolumeID", 0};
0055 Gaudi::Property<std::string> m_firstInVolumeName{this, "firstInVolumeName", ""};
0056 Gaudi::Property<float> m_firstSmallerThanZ{this, "firstSmallerThanZ", 0};
0057 Gaudi::Property<float> m_firstGreaterThanZ{this, "firstGreaterThanZ", 0};
0058 Gaudi::Property<float> m_firstGreaterThanR{this, "firstGreaterThanR", -1};
0059
0060 Acts::GeometryContext m_geoContext;
0061
0062 public:
0063
0064 TrackProjector(const std::string& name, ISvcLocator* svcLoc)
0065 : Gaudi::Algorithm(name, svcLoc) {
0066 declareProperty("inputTrajectories", m_inputTrajectories,"");
0067 declareProperty("outputTrackSegments", m_outputTrackSegments, "");
0068 }
0069
0070 StatusCode initialize() override {
0071 if (Gaudi::Algorithm::initialize().isFailure())
0072 return StatusCode::FAILURE;
0073 return StatusCode::SUCCESS;
0074 }
0075
0076 StatusCode execute(const EventContext&) const override {
0077
0078 const auto* const trajectories = m_inputTrajectories.get();
0079
0080 auto* track_segments = m_outputTrackSegments.createAndPut();
0081
0082 if (msgLevel(MSG::DEBUG)) {
0083 debug() << std::size(*trajectories) << " trajectories " << endmsg;
0084 }
0085
0086
0087 for (const auto& traj : *trajectories) {
0088
0089
0090 const auto& mj = traj.multiTrajectory();
0091 const auto& trackTips = traj.tips();
0092 if (msgLevel(MSG::DEBUG)) {
0093 debug() << "# of elements in trackTips " <<trackTips.size() << endmsg;
0094 }
0095
0096
0097 if (trackTips.empty()) {
0098 if (msgLevel(MSG::DEBUG)) {
0099 debug() << "Empty multiTrajectory." << endmsg;
0100 }
0101 continue;
0102 }
0103 auto& trackTip = trackTips.front();
0104
0105
0106 auto trajState = Acts::MultiTrajectoryHelpers::trajectoryState(mj, trackTip);
0107 int m_nMeasurements = trajState.nMeasurements;
0108 int m_nStates = trajState.nStates;
0109 int m_nCalibrated = 0;
0110 if (msgLevel(MSG::DEBUG)) {
0111 debug() << "n measurement in trajectory " << m_nMeasurements << endmsg;
0112 debug() << "n state in trajectory " << m_nStates << endmsg;
0113 }
0114
0115 edm4eic::MutableTrackSegment track_segment;
0116
0117
0118 mj.visitBackwards(trackTip, [&](auto&& trackstate) {
0119
0120 auto geoID = trackstate.referenceSurface().geometryId();
0121 auto volume = geoID.volume();
0122 auto layer = geoID.layer();
0123 if (trackstate.hasCalibrated()) {
0124 m_nCalibrated++;
0125 }
0126
0127
0128 const auto& parameter = trackstate.predicted();
0129 const auto& covariance = trackstate.predictedCovariance();
0130
0131
0132 auto global = trackstate.referenceSurface().localToGlobal(
0133 m_geoContext,
0134 {parameter[Acts::eBoundLoc0], parameter[Acts::eBoundLoc1]},
0135 {0, 0, 0}
0136 );
0137
0138 const decltype(edm4eic::TrackPoint::position) position {
0139 static_cast<float>(global.x()),
0140 static_cast<float>(global.y()),
0141 static_cast<float>(global.z())
0142 };
0143
0144
0145 const decltype(edm4eic::TrackParametersData::loc) loc {
0146 static_cast<float>(parameter[Acts::eBoundLoc0]),
0147 static_cast<float>(parameter[Acts::eBoundLoc1])
0148 };
0149 const edm4eic::Cov2f locError {
0150 static_cast<float>(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0)),
0151 static_cast<float>(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1)),
0152 static_cast<float>(covariance(Acts::eBoundLoc0, Acts::eBoundLoc1))
0153 };
0154 const decltype(edm4eic::TrackPoint::positionError) positionError{0, 0, 0};
0155 const decltype(edm4eic::TrackPoint::momentum) momentum = edm4hep::utils::sphericalToVector(
0156 static_cast<float>(1.0 / std::abs(parameter[Acts::eBoundQOverP])),
0157 static_cast<float>(parameter[Acts::eBoundTheta]),
0158 static_cast<float>(parameter[Acts::eBoundPhi])
0159 );
0160 const decltype(edm4eic::TrackPoint::momentumError) momentumError {
0161 static_cast<float>(covariance(Acts::eBoundTheta, Acts::eBoundTheta)),
0162 static_cast<float>(covariance(Acts::eBoundPhi, Acts::eBoundPhi)),
0163 static_cast<float>(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)),
0164 static_cast<float>(covariance(Acts::eBoundTheta, Acts::eBoundPhi)),
0165 static_cast<float>(covariance(Acts::eBoundTheta, Acts::eBoundQOverP)),
0166 static_cast<float>(covariance(Acts::eBoundPhi, Acts::eBoundQOverP))
0167 };
0168 const float time{static_cast<float>(parameter(Acts::eBoundTime))};
0169 const float timeError{static_cast<float>(sqrt(covariance(Acts::eBoundTime, Acts::eBoundTime)))};
0170 const float theta(parameter[Acts::eBoundTheta]);
0171 const float phi(parameter[Acts::eBoundPhi]);
0172 const decltype(edm4eic::TrackPoint::directionError) directionError {
0173 static_cast<float>(covariance(Acts::eBoundTheta, Acts::eBoundTheta)),
0174 static_cast<float>(covariance(Acts::eBoundPhi, Acts::eBoundPhi)),
0175 static_cast<float>(covariance(Acts::eBoundTheta, Acts::eBoundPhi))
0176 };
0177 const float pathLength = static_cast<float>(trackstate.pathLength());
0178 const float pathLengthError = 0;
0179
0180 #if EDM4EIC_VERSION_MAJOR >= 3
0181 uint64_t surface = 0;
0182 uint32_t system = 0;
0183 #endif
0184
0185
0186 track_segment.addToPoints({
0187 #if EDM4EIC_VERSION_MAJOR >= 3
0188 surface,
0189 system,
0190 #endif
0191 position,
0192 positionError,
0193 momentum,
0194 momentumError,
0195 time,
0196 timeError,
0197 theta,
0198 phi,
0199 directionError,
0200 pathLength,
0201 pathLengthError
0202 });
0203
0204 if (msgLevel(MSG::DEBUG)) {
0205 debug() << "******************************" << endmsg;
0206 debug() << "predicted variables: \n" << trackstate.predicted() << endmsg;
0207 debug() << "geoID = " << geoID << endmsg;
0208 debug() << "volume = " << volume << ", layer = " << layer << endmsg;
0209 debug() << "pathlength = " << pathLength << endmsg;
0210 debug() << "hasCalibrated = " << trackstate.hasCalibrated() << endmsg;
0211 debug() << "******************************" << endmsg;
0212 }
0213 });
0214
0215 if (msgLevel(MSG::DEBUG)) {
0216 debug() << "n calibrated state in trajectory " << m_nCalibrated << endmsg;
0217 }
0218
0219
0220 track_segments->push_back(track_segment);
0221 }
0222
0223 return StatusCode::SUCCESS;
0224 }
0225
0226 };
0227
0228 DECLARE_COMPONENT(TrackProjector)
0229
0230 }