LDMX Software
Public Member Functions | Private Member Functions | Private Attributes | List of all members
tracking::reco::CKFProcessor Class Referencefinal

Public Member Functions

 CKFProcessor (const std::string &name, framework::Process &process)
 Constructor.
 
 ~CKFProcessor ()
 Destructor.
 
void onProcessStart () override
 Callback for the EventProcessor to take any necessary action when the processing of events starts, such as creating histograms.
 
void onNewRun (const ldmx::RunHeader &rh) override
 onNewRun is the first function called for each processor after the conditions are fully configured and accessible.
 
void onProcessEnd () override
 Callback for the EventProcessor to take any necessary action when the processing of events finishes, such as calculating job-summary quantities.
 
void configure (framework::config::Parameters &parameters) override
 Configure the processor using the given user specified parameters.
 
void produce (framework::Event &event) override
 Run the processor.
 
- Public Member Functions inherited from tracking::reco::TrackingGeometryUser
 TrackingGeometryUser (const std::string &name, framework::Process &p)
 
- Public Member Functions inherited from framework::Producer
 Producer (const std::string &name, Process &process)
 Class constructor.
 
virtual void beforeNewRun (ldmx::RunHeader &header)
 Handle allowing producers to modify run headers before the run begins.
 
- Public Member Functions inherited from framework::EventProcessor
 EventProcessor (const std::string &name, Process &process)
 Class constructor.
 
virtual ~EventProcessor ()
 Class destructor.
 
virtual void onFileOpen (EventFile &eventFile)
 Callback for the EventProcessor to take any necessary action when a new event input ROOT file is opened.
 
virtual void onFileClose (EventFile &eventFile)
 Callback for the EventProcessor to take any necessary action when a event input ROOT file is closed.
 
template<class T >
const T & getCondition (const std::string &condition_name)
 Access a conditions object for the current event.
 
TDirectory * getHistoDirectory ()
 Access/create a directory in the histogram file for this event processor to create histograms and analysis tuples.
 
void setStorageHint (framework::StorageControl::Hint hint)
 Mark the current event as having the given storage control hint from this module.
 
void setStorageHint (framework::StorageControl::Hint hint, const std::string &purposeString)
 Mark the current event as having the given storage control hint from this module and the given purpose string.
 
int getLogFrequency () const
 Get the current logging frequency from the process.
 
int getRunNumber () const
 Get the run number from the process.
 
std::string getName () const
 Get the processor name.
 
void createHistograms (const std::vector< framework::config::Parameters > &histos)
 Internal function which is used to create histograms passed from the python configuration @parma histos vector of Parameters that configure histograms to create.
 

Private Member Functions

auto makeGeoIdSourceLinkMap (const geo::TrackersTrackingGeometry &tg, const std::vector< ldmx::Measurement > &ldmxsps) -> std::unordered_multimap< Acts::GeometryIdentifier, ActsExamples::IndexSourceLink >
 

Private Attributes

bool dumpobj_ {false}
 
int pionstates_ {10}
 
int nevents_ {0}
 
double processing_time_ {0.}
 
std::map< std::string, double > profiling_map_
 
bool debug_acts_ {false}
 
std::shared_ptr< Acts::PlaneSurface > target_surface
 
Acts::RotationMatrix3 surf_rotation
 
double bfield_ {0}
 
bool const_b_field_ {true}
 
bool remove_stereo_ {false}
 
bool use1Dmeasurements_ {true}
 
int min_hits_ {7}
 
double propagator_step_size_ {200.}
 
int propagator_maxSteps_ {1000}
 
bool use_extrapolate_location_ {true}
 
std::vector< double > extrapolate_location_ {0., 0., 0.}
 
bool use_seed_perigee_ {false}
 
std::string measurement_collection_ {"TaggerMeasurements"}
 
double outlier_pval_ {3.84}
 
std::string out_trk_collection_ {"Tracks"}
 
std::string seed_coll_name_ {"seedTracks"}
 
std::string field_map_ {""}
 
std::unique_ptr< const CkfPropagator > propagator_
 
std::unique_ptr< const Acts::CombinatorialKalmanFilter< CkfPropagator, TrackContainer > > ckf_
 
std::shared_ptr< tracking::reco::TrackExtrapolatorTool< CkfPropagator > > trk_extrap_
 
int nseeds_ {0}
 n seeds and n tracks
 
int ntracks_ {0}
 
int eventnr_ {0}
 
std::vector< double > map_offset_
 
bool taggerTracking_ {true}
 

Additional Inherited Members

- Static Public Member Functions inherited from framework::EventProcessor
static void declare (const std::string &classname, int classtype, EventProcessorMaker *)
 Internal function which is part of the PluginFactory machinery.
 
- Static Public Attributes inherited from framework::Producer
static const int CLASSTYPE {1}
 Constant used to track EventProcessor types by the PluginFactory.
 
- Protected Member Functions inherited from tracking::reco::TrackingGeometryUser
const Acts::GeometryContext & geometry_context ()
 
const Acts::MagneticFieldContext & magnetic_field_context ()
 
const Acts::CalibrationContext & calibration_context ()
 
const geo::TrackersTrackingGeometrygeometry ()
 
- Protected Member Functions inherited from framework::EventProcessor
void abortEvent ()
 Abort the event immediately.
 
- Protected Attributes inherited from framework::EventProcessor
HistogramHelper histograms_
 Interface class for making and filling histograms.
 
NtupleManagerntuple_ {NtupleManager::getInstance()}
 Manager for any ntuples.
 
logging::logger theLog_
 The logger for this EventProcessor.
 

Detailed Description

Definition at line 93 of file CKFProcessor.h.

Constructor & Destructor Documentation

◆ CKFProcessor()

tracking::reco::CKFProcessor::CKFProcessor ( const std::string &  name,
framework::Process process 
)

Constructor.

Parameters
nameThe name of the instance of this object.
processThe process running this producer.

Definition at line 19 of file CKFProcessor.cxx.

20 : TrackingGeometryUser(name, process) {}

◆ ~CKFProcessor()

tracking::reco::CKFProcessor::~CKFProcessor ( )

Destructor.

Definition at line 22 of file CKFProcessor.cxx.

22{}

Member Function Documentation

◆ configure()

void tracking::reco::CKFProcessor::configure ( framework::config::Parameters parameters)
overridevirtual

Configure the processor using the given user specified parameters.

Parameters
parametersSet of parameters used to configure this processor.

Reimplemented from framework::EventProcessor.

Definition at line 660 of file CKFProcessor.cxx.

660 {
661 dumpobj_ = parameters.getParameter<bool>("dumpobj", 0);
662 pionstates_ = parameters.getParameter<int>("pionstates", 0);
663
664 bfield_ = parameters.getParameter<double>("bfield", -1.5);
665 const_b_field_ = parameters.getParameter<bool>("const_b_field", false);
666 field_map_ = parameters.getParameter<std::string>("field_map");
667 propagator_step_size_ =
668 parameters.getParameter<double>("propagator_step_size", 200.);
669 propagator_maxSteps_ =
670 parameters.getParameter<int>("propagator_maxSteps", 10000);
671 measurement_collection_ = parameters.getParameter<std::string>(
672 "measurement_collection", "TaggerMeasurements");
673 outlier_pval_ = parameters.getParameter<double>("outlier_pval_", 3.84);
674
675 debug_acts_ = parameters.getParameter<bool>("debug_acts", false);
676
677 remove_stereo_ = parameters.getParameter<bool>("remove_stereo", false);
678 use1Dmeasurements_ = parameters.getParameter<bool>("use1Dmeasurements", true);
679 min_hits_ = parameters.getParameter<int>("min_hits", 7);
680
681 // Ckf specific options
682 use_extrapolate_location_ =
683 parameters.getParameter<bool>("use_extrapolate_location", true);
684 extrapolate_location_ = parameters.getParameter<std::vector<double>>(
685 "extrapolate_location", {0., 0., 0.});
686 use_seed_perigee_ = parameters.getParameter<bool>("use_seed_perigee", false);
687
688 ldmx_log(debug) << " use_extrapolate_location ? "
689 << use_extrapolate_location_;
690 ldmx_log(debug) << " use_seed_perigee ? " << use_seed_perigee_;
691
692 // seeds from the event
693 seed_coll_name_ =
694 parameters.getParameter<std::string>("seed_coll_name", "seedTracks");
695
696 // output track collection
697 out_trk_collection_ =
698 parameters.getParameter<std::string>("out_trk_collection", "Tracks");
699
700 // keep track on which system tracking is running
701 taggerTracking_ = parameters.getParameter<bool>("taggerTracking", true);
702
703 // BField Systematics
704 map_offset_ =
705 parameters.getParameter<std::vector<double>>("map_offset_", {0., 0., 0.});
706}
T getParameter(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:89

References framework::config::Parameters::getParameter().

◆ makeGeoIdSourceLinkMap()

auto tracking::reco::CKFProcessor::makeGeoIdSourceLinkMap ( const geo::TrackersTrackingGeometry tg,
const std::vector< ldmx::Measurement > &  ldmxsps 
) -> std::unordered_multimap<Acts::GeometryIdentifier, ActsExamples::IndexSourceLink>
private

Definition at line 708 of file CKFProcessor.cxx.

712 {
713 std::unordered_multimap<Acts::GeometryIdentifier,
715 geoId_sl_map;
716
717 ldmx_log(debug) << "makeGeoIdSourceLinkMap::Available measurements = "
718 << measurements.size();
719
720 // Check the hits associated to the surfaces
721 for (unsigned int i_meas = 0; i_meas < measurements.size(); i_meas++) {
722 ldmx::Measurement meas = measurements.at(i_meas);
723 unsigned int layerid = meas.getLayerID();
724
725 const Acts::Surface* hit_surface = tg.getSurface(layerid);
726
727 if (hit_surface) {
728 // Transform the ldmx space point from global to local and store the
729 // information
730
731 ActsExamples::IndexSourceLink idx_sl(hit_surface->geometryId(), i_meas);
732 // mg aug 2024 ... these don't print statements
733 // don't compile using v36 in Acts...figure out later
734 /*
735 ldmx_log(debug)
736 << "Insert measurement on surface located at::"
737 << hit_surface->transform(geometry_context()).translation();
738 ldmx_log(debug) << "and geoId::" << hit_surface->geometryId()
739 << std::endl;
740
741 ldmx_log(debug) << "Surface info::"
742 << std::tie(*hit_surface, geometry_context());
743 */
744 geoId_sl_map.insert(std::make_pair(hit_surface->geometryId(), idx_sl));
745
746 } else
747 std::cout << getName() << "::HIT " << i_meas << " at layer"
748 << (measurements.at(i_meas)).getLayerID()
749 << " is not associated to any surface?!" << std::endl;
750 }
751
752 return geoId_sl_map;
753}
std::string getName() const
Get the processor name.
int getLayerID() const

◆ onNewRun()

void tracking::reco::CKFProcessor::onNewRun ( const ldmx::RunHeader rh)
overridevirtual

onNewRun is the first function called for each processor after the conditions are fully configured and accessible.

This is where you could create single-processors, multi-event calculation objects.

Reimplemented from framework::EventProcessor.

Definition at line 24 of file CKFProcessor.cxx.

24 {
25 profiling_map_["setup"] = 0.;
26 profiling_map_["hits"] = 0.;
27 profiling_map_["seeds"] = 0.;
28 profiling_map_["ckf_setup"] = 0.;
29 profiling_map_["ckf_run"] = 0.;
30 profiling_map_["result_loop"] = 0.;
31
32 // Generate a constant magnetic field
33 Acts::Vector3 b_field(0., 0., bfield_ * Acts::UnitConstants::T);
34
35 // Setup a constant magnetic field
36 const auto constBField = std::make_shared<Acts::ConstantBField>(b_field);
37
38 // Define the target surface - be careful:
39 // x - downstream
40 // y - left (when looking along x)
41 // z - up
42 // Passing identity here means that your target surface is oriented in the
43 // same way
44 surf_rotation = Acts::RotationMatrix3::Zero();
45 // u direction along +Y
46 surf_rotation(1, 0) = 1;
47 // v direction along +Z
48 surf_rotation(2, 1) = 1;
49 // w direction along +X
50 surf_rotation(0, 2) = 1;
51
52 Acts::Vector3 target_pos(0., 0., 0.);
53 Acts::Translation3 target_translation(target_pos);
54 Acts::Transform3 target_transform(target_translation * surf_rotation);
55
56 // Unbounded surface
57 target_surface =
58 Acts::Surface::makeShared<Acts::PlaneSurface>(target_transform);
59
60 // Custom transformation of the interpolated bfield map
61 bool debugTransform = false;
62 auto transformPos = [this, debugTransform](const Acts::Vector3& pos) {
63 Acts::Vector3 rot_pos;
64 rot_pos(0) = pos(1);
65 rot_pos(1) = pos(2);
66 rot_pos(2) = pos(0) + DIPOLE_OFFSET;
67
68 // Systematic effect
69 rot_pos(0) += this->map_offset_[0];
70 rot_pos(1) += this->map_offset_[1];
71 rot_pos(2) += this->map_offset_[2];
72
73 // Apply A rotation around the center of the magnet. (I guess offset first
74 // and then rotation)
75
76 if (debugTransform) {
77 std::cout << "PF::DEFAULT3 TRANSFORM" << std::endl;
78 std::cout << "PF::Check:: transforming Pos" << std::endl;
79 std::cout << pos << std::endl;
80 std::cout << "TO" << std::endl;
81 std::cout << rot_pos << std::endl;
82 }
83
84 return rot_pos;
85 };
86
87 Acts::RotationMatrix3 rotation = Acts::RotationMatrix3::Identity();
88 double scale = 1.;
89
90 auto transformBField = [rotation, scale, debugTransform](
91 const Acts::Vector3& field,
92 const Acts::Vector3& /*pos*/) {
93 // Rotate the field in tracking coordinates
94 Acts::Vector3 rot_field;
95 rot_field(0) = field(2);
96 rot_field(1) = field(0);
97 rot_field(2) = field(1);
98
99 // Scale the field
100 rot_field = scale * rot_field;
101
102 // Rotate the field
103 rot_field = rotation * rot_field;
104
105 // A distortion scaled by position.
106 if (debugTransform) {
107 std::cout << "PF::DEFAULT3 TRANSFORM" << std::endl;
108 std::cout << "PF::Check:: transforming" << std::endl;
109 std::cout << field << std::endl;
110 std::cout << "TO" << std::endl;
111 std::cout << rot_field << std::endl;
112 }
113
114 return rot_field;
115 };
116
117 // Setup a interpolated bfield map
118 const auto map = std::make_shared<InterpolatedMagneticField3>(
119 loadDefaultBField(field_map_,
120 // default_transformPos,
121 // default_transformBField));
122 transformPos, transformBField));
123
124 auto acts_loggingLevel = Acts::Logging::FATAL;
125 if (debug_acts_) acts_loggingLevel = Acts::Logging::VERBOSE;
126
127 // Setup the steppers
128 const auto stepper = Acts::EigenStepper<>{map};
129 const auto const_stepper = Acts::EigenStepper<>{constBField};
130 const auto multi_stepper = Acts::MultiEigenStepperLoop{map};
131
132 // Setup the navigator
133 Acts::Navigator::Config navCfg{geometry().getTG()};
134 navCfg.resolveMaterial = true;
135 navCfg.resolvePassive = true;
136 navCfg.resolveSensitive = true;
137 const Acts::Navigator navigator(navCfg);
138
139 // Setup the propagators
140 propagator_ =
141 const_b_field_
142 ? std::make_unique<CkfPropagator>(const_stepper, navigator)
143 : std::make_unique<CkfPropagator>(
144 stepper, navigator,
145 Acts::getDefaultLogger("ACTS_PROP", acts_loggingLevel));
146
147 // Setup the finder / fitters
148 ckf_ = std::make_unique<std::decay_t<decltype(*ckf_)>>(
149 *propagator_, Acts::getDefaultLogger("CKF", acts_loggingLevel));
150 trk_extrap_ = std::make_shared<std::decay_t<decltype(*trk_extrap_)>>(
151 *propagator_, geometry_context(), magnetic_field_context());
152}

◆ onProcessEnd()

void tracking::reco::CKFProcessor::onProcessEnd ( )
overridevirtual

Callback for the EventProcessor to take any necessary action when the processing of events finishes, such as calculating job-summary quantities.

Reimplemented from framework::EventProcessor.

Definition at line 634 of file CKFProcessor.cxx.

634 {
635 ldmx_log(info) << "found " << ntracks_ << " tracks / " << nseeds_
636 << " nseeds";
637 ldmx_log(info) << "AVG Time/Event: " << std::fixed << std::setprecision(1)
638 << processing_time_ / nevents_ << " ms";
639 ldmx_log(info) << "Breakdown::";
640 ldmx_log(info) << "setup Avg Time/Event = " << std::fixed
641 << std::setprecision(3) << profiling_map_["setup"] / nevents_
642 << " ms";
643 ldmx_log(info) << "hits Avg Time/Event = " << std::fixed
644 << std::setprecision(2) << profiling_map_["hits"] / nevents_
645 << " ms";
646 ldmx_log(info) << "seeds Avg Time/Event = " << std::fixed
647 << std::setprecision(3) << profiling_map_["seeds"] / nevents_
648 << " ms";
649 ldmx_log(info) << "cf_setup Avg Time/Event = " << std::fixed
650 << std::setprecision(3)
651 << profiling_map_["ckf_setup"] / nevents_ << " ms";
652 ldmx_log(info) << "ckf_run Avg Time/Event = " << std::fixed
653 << std::setprecision(3) << profiling_map_["ckf_run"] / nevents_
654 << " ms";
655 ldmx_log(info) << "result_loop Avg Time/Event = " << std::fixed
656 << std::setprecision(1)
657 << profiling_map_["result_loop"] / nevents_ << " ms";
658}
int nseeds_
n seeds and n tracks

References nseeds_.

◆ onProcessStart()

void tracking::reco::CKFProcessor::onProcessStart ( )
overridevirtual

Callback for the EventProcessor to take any necessary action when the processing of events starts, such as creating histograms.

Reimplemented from framework::EventProcessor.

Definition at line 626 of file CKFProcessor.cxx.

626 {
627 if (use1Dmeasurements_)
628 ldmx_log(info) << "use1Dmeasurements = " << std::boolalpha
629 << use1Dmeasurements_;
630 if (remove_stereo_)
631 ldmx_log(info) << "remove_stereo = " << std::boolalpha << remove_stereo_;
632}

◆ produce()

void tracking::reco::CKFProcessor::produce ( framework::Event event)
overridevirtual

Run the processor.

Parameters
eventThe event to process.

Implements framework::Producer.

Definition at line 154 of file CKFProcessor.cxx.

154 {
155 eventnr_++;
156 // get the tracking geometry from conditions
157 auto tg{geometry()};
158
159 // TODO use global variable instead and call clear;
160
161 std::vector<ldmx::Track> tracks;
162
163 auto start = std::chrono::high_resolution_clock::now();
164
165 nevents_++;
166 if (nevents_ % 1000 == 0) ldmx_log(info) << "events processed:" << nevents_;
167
168 auto loggingLevel = Acts::Logging::DEBUG;
169 ACTS_LOCAL_LOGGER(
170 Acts::getDefaultLogger("LDMX Tracking Geometry Maker", loggingLevel));
171
172 // Move this at the start of the producer
173 Acts::PropagatorOptions<Acts::StepperPlainOptions,
174 Acts::NavigatorPlainOptions, ActionList, AbortList>
175 propagator_options(geometry_context(), magnetic_field_context());
176
177 propagator_options.pathLimit = std::numeric_limits<double>::max();
178 // Activate loop protection at some pt value
179 propagator_options.loopProtection =
180 false; //(startParameters.transverseMomentum() < cfg.ptLoopers);
181
182 // Switch the material interaction on/off & eventually into logging mode
183 auto& mInteractor =
184 propagator_options.actionList.get<Acts::MaterialInteractor>();
185 mInteractor.multipleScattering = true;
186 mInteractor.energyLoss = true;
187 mInteractor.recordInteractions = false;
188
189 // The logger can be switched to sterile, e.g. for timing logging
190 auto& sLogger =
191 propagator_options.actionList.get<Acts::detail::SteppingLogger>();
192 sLogger.sterile = true;
193 // Set a maximum step size
194 propagator_options.stepping.maxStepSize =
195 propagator_step_size_ * Acts::UnitConstants::mm;
196 propagator_options.maxSteps = propagator_maxSteps_;
197
198 // #######################//
199 // Kalman Filter algorithm//
200 // #######################//
201
202 // Step 1 - Form the source links
203
204 // a) Loop over the sim Hits
205
206 auto setup = std::chrono::high_resolution_clock::now();
207 profiling_map_["setup"] +=
208 std::chrono::duration<double, std::milli>(setup - start).count();
209
210 const std::vector<ldmx::Measurement> measurements =
211 event.getCollection<ldmx::Measurement>(measurement_collection_);
212
213 // check if SimParticleMap is available for truth matching
214 std::shared_ptr<tracking::sim::TruthMatchingTool> truthMatchingTool = nullptr;
215 std::map<int, ldmx::SimParticle> particleMap;
216
217 if (event.exists("SimParticles")) {
218 ldmx_log(debug) << "Setting up track truth matching tool";
219 particleMap = event.getMap<int, ldmx::SimParticle>("SimParticles");
220 truthMatchingTool = std::make_shared<tracking::sim::TruthMatchingTool>(
221 particleMap, measurements);
222 }
223
224 // The mapping between the geometry identifier
225 // and the IndexsourceLink that points to the hit
226 const auto geoId_sl_map = makeGeoIdSourceLinkMap(tg, measurements);
227
228 auto hits = std::chrono::high_resolution_clock::now();
229 profiling_map_["hits"] +=
230 std::chrono::duration<double, std::milli>(hits - setup).count();
231
232 // ============ Setup the CKF ============
233
234 // Retrieve the seeds
235
236 ldmx_log(debug) << "Retrieve the seeds::" << seed_coll_name_;
237
238 const std::vector<ldmx::Track> seed_tracks =
239 event.getCollection<ldmx::Track>(seed_coll_name_);
240
241 ldmx_log(debug) << "Number of seeds::" << seed_tracks.size();
242
243 // Run the CKF on each seed and produce a track candidate
244 std::vector<Acts::BoundTrackParameters> startParameters;
245
246 // Tune the reconstruction for different PDG ID
247 std::vector<int> seedPDGID;
248
249 for (auto& seed : seed_tracks) {
250 // Transform the seed track to bound parameters
251 std::shared_ptr<Acts::PerigeeSurface> perigeeSurface =
252 Acts::Surface::makeShared<Acts::PerigeeSurface>(Acts::Vector3(
253 seed.getPerigeeX(), seed.getPerigeeY(), seed.getPerigeeZ()));
254
255 Acts::BoundVector paramVec;
256 paramVec << seed.getD0(), seed.getZ0(), seed.getPhi(), seed.getTheta(),
257 seed.getQoP(), seed.getT();
258
259 Acts::BoundSquareMatrix covMat =
260 tracking::sim::utils::unpackCov(seed.getPerigeeCov());
261
262 ldmx_log(debug) << "perigee" << std::endl
263 << seed.getPerigeeX() << " " << seed.getPerigeeY() << " "
264 << seed.getPerigeeZ() << std::endl
265 << "start Parameters" << std::endl
266 << paramVec;
267
268 ldmx_log(debug) << "cov matrix" << std::endl << covMat << std::endl;
269
270 // need to set particle hypothesis...set to electron for now...
271 auto partHypo{Acts::SinglyChargedParticleHypothesis::electron()};
272 startParameters.push_back(
273 Acts::BoundTrackParameters(perigeeSurface, paramVec, covMat, partHypo));
274
275 seedPDGID.push_back(seed.getPdgID());
276
277 nseeds_++;
278 } // loop on seeds
279
280 if (startParameters.size() < 1) {
281 std::vector<ldmx::Track> empty;
282 event.add(out_trk_collection_, empty);
283 return;
284 }
285
286 auto seeds = std::chrono::high_resolution_clock::now();
287 profiling_map_["seeds"] +=
288 std::chrono::duration<double, std::milli>(seeds - hits).count();
289
290 Acts::GainMatrixUpdater kfUpdater;
291
292 // configuration for the measurement selector. Empty geometry identifier means
293 // applicable to all the detector elements
294
295 Acts::MeasurementSelector::Config measurementSelectorCfg = {
296 // global default: no chi2 cut, only one measurement per surface
297 {Acts::GeometryIdentifier(), {{}, {outlier_pval_}, {1u}}},
298 };
299
300 Acts::MeasurementSelector measSel{measurementSelectorCfg};
301
302 tracking::sim::LdmxMeasurementCalibrator calibrator{measurements};
303
304 Acts::CombinatorialKalmanFilterExtensions<TrackContainer> ckf_extensions;
305
306 if (use1Dmeasurements_)
307 ckf_extensions.calibrator
309 Acts::VectorMultiTrajectory>>(&calibrator);
310
311 else
312 ckf_extensions.calibrator
314 Acts::VectorMultiTrajectory>>(&calibrator);
315
316 ckf_extensions.updater.connect<
317 &Acts::GainMatrixUpdater::operator()<Acts::VectorMultiTrajectory>>(
318 &kfUpdater);
319
320 ckf_extensions.measurementSelector
321 .connect<&Acts::MeasurementSelector::select<Acts::VectorMultiTrajectory>>(
322 &measSel);
323
324 ldmx_log(debug) << "SourceLinkAccessor..." << std::endl;
325
326 // Create source link accessor and connect delegate
327 struct SourceLinkAccIt {
328 using BaseIt = decltype(geoId_sl_map.begin());
329 BaseIt it;
330
331#pragma GCC diagnostic push
332#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
333
334 using difference_type = typename BaseIt::difference_type;
335 using iterator_category = typename BaseIt::iterator_category;
336 // using value_type = typename BaseIt::value_type::second_type;
337 using value_type = Acts::SourceLink;
338 using pointer = typename BaseIt::pointer;
339 using reference = value_type&;
340#pragma GCC diagnostic pop
341
342 SourceLinkAccIt& operator++() {
343 ++it;
344 return *this;
345 }
346 bool operator==(const SourceLinkAccIt& other) const {
347 return it == other.it;
348 }
349 bool operator!=(const SourceLinkAccIt& other) const {
350 return !(*this == other);
351 }
352 // const value_type& operator*() const { return it->second; }
353
354 // by value
355 value_type operator*() const { return value_type{it->second}; }
356 };
357
358 auto sourceLinkAccessor = [&](const Acts::Surface& surface)
359 -> std::pair<SourceLinkAccIt, SourceLinkAccIt> {
360 auto [begin, end] = geoId_sl_map.equal_range(surface.geometryId());
361 return {SourceLinkAccIt{begin}, SourceLinkAccIt{end}};
362 };
363
364 Acts::SourceLinkAccessorDelegate<SourceLinkAccIt> sourceLinkAccessorDelegate;
365 sourceLinkAccessorDelegate.connect<&decltype(sourceLinkAccessor)::operator(),
366 decltype(sourceLinkAccessor)>(
367 &sourceLinkAccessor);
368
369 ldmx_log(debug) << "Surfaces..." << std::endl;
370
371 std::shared_ptr<const Acts::PerigeeSurface> origin_surface =
372 Acts::Surface::makeShared<Acts::PerigeeSurface>(
373 Acts::Vector3(0., 0., 0.));
374
375 ldmx_log(debug) << "About to run CKF..." << std::endl;
376
377 // run the CKF for all initial track states
378 auto ckf_setup = std::chrono::high_resolution_clock::now();
379 profiling_map_["ckf_setup"] +=
380 std::chrono::duration<double, std::milli>(ckf_setup - seeds).count();
381
382 auto ckf_run = std::chrono::high_resolution_clock::now();
383 profiling_map_["ckf_run"] +=
384 std::chrono::duration<double, std::milli>(ckf_run - ckf_setup).count();
385
386 Acts::VectorTrackContainer vtc;
387 Acts::VectorMultiTrajectory mtj;
388 Acts::TrackContainer tc{vtc, mtj};
389
390 for (size_t trackId = 0u; trackId < startParameters.size(); ++trackId) {
391 // The seed has a track PdgID associated
392 if (seedPDGID.at(trackId) != 0) {
393 // int pdgID = seedPDGID.at(trackId);
394 }
395
396 // Define the CKF options here:
397 const Acts::CombinatorialKalmanFilterOptions<SourceLinkAccIt,
398 TrackContainer>
399 ckfOptions(TrackingGeometryUser::geometry_context(),
400 TrackingGeometryUser::magnetic_field_context(),
401 TrackingGeometryUser::calibration_context(),
402 sourceLinkAccessorDelegate, ckf_extensions,
403 propagator_options, true /* multiple scattering */,
404 false /* energy loss */);
405
406 ldmx_log(debug) << "Running CKF on seed params "
407 << startParameters.at(trackId).parameters().transpose()
408 << std::endl;
409 ldmx_log(debug) << "Checking options: multiple scattering = "
410 << ckfOptions.multipleScattering
411 << " energy loss = " << ckfOptions.energyLoss;
412 auto results =
413 ckf_->findTracks(startParameters.at(trackId), ckfOptions, tc);
414 ldmx_log(debug) << "findTracks returned ... checking if ok";
415 if (not results.ok()) {
416 ldmx_log(debug) << "CKF Fit failed" << std::endl;
417 continue;
418 }
419
420 // No track found
421 // if (tc.size() < trackId + 1) continue;
422
423 auto& tracksFromSeed = results.value();
424
425 ldmx_log(debug) << "number of entries in results " << tracksFromSeed.size();
426 for (auto& track : tracksFromSeed) {
427 // do the track smoothing...this is not done in the CKF code anymore
428 Acts::smoothTrack(geometry_context(), track); // from TrackHelpers
429 // make the empty ldmx::Track() and track state at target
430 ldmx::Track trk = ldmx::Track();
431 ldmx::Track::TrackState tsAtTarget;
432 ldmx_log(debug) << "Found track: nMeas " << track.nMeasurements();
433 ldmx_log(debug) << "Track states " << track.nTrackStates();
434 ldmx_log(debug) << "chi2 " << track.chi2();
435
436 for (const auto ts : track.trackStatesReversed()) {
437 // Check TrackStates Quality
438 ldmx_log(debug) << "Checking Track State at location "
439 << ts.referenceSurface()
440 .transform(geometry_context())
441 .translation()
442 .transpose()
443 << std::endl;
444
445 ldmx_log(debug) << "Smoothed? " << ts.hasSmoothed() << std::endl;
446 if (ts.hasSmoothed()) {
447 ldmx_log(debug) << "Parameters \n"
448 << ts.smoothed().transpose() << std::endl;
449 ldmx_log(debug) << "Covariance \n"
450 << ts.smoothedCovariance() << std::endl;
451 }
452
453 // Check if the track state is a measurement
454 auto typeFlags = ts.typeFlags();
455
456 if (typeFlags.test(Acts::TrackStateFlag::MeasurementFlag) &&
457 ts.hasUncalibratedSourceLink()) {
458 ldmx_log(debug) << " getting source link for this measurement";
459
461 ts.getUncalibratedSourceLink()
462 .template get<ActsExamples::IndexSourceLink>();
463
464 ldmx_log(debug) << " looking up this index in measurements list";
465 ldmx::Measurement ldmx_meas = measurements.at(sl.index());
466 ldmx_log(debug) << "SourceLink Index::" << sl.index();
467 ldmx_log(debug) << "Measurement:\n" << ldmx_meas << "\n";
468 ldmx_log(debug) << " adding measurement to ldmx::track";
469 trk.addMeasurementIndex(sl.index());
470 }
471 }
472 bool success = trk_extrap_->TrackStateAtSurface(
473 track, target_surface, tsAtTarget, ldmx::TrackStateType::AtTarget);
474 ldmx_log(debug) << "target extrapolation success??? " << success;
475 if (success) {
476 ldmx_log(debug) << "Successfully obtained TS at target";
477 ldmx_log(debug) << "Parameters At Target: \n"
478 << tsAtTarget.params[0] << " " << tsAtTarget.params[1]
479 << " " << tsAtTarget.params[2] << " "
480 << tsAtTarget.params[3] << " " << tsAtTarget.params[4];
481
482 trk.addTrackState(tsAtTarget);
483 } else {
484 ldmx_log(info)
485 << "Could not extrapolate to target? Printing track states: ";
486 ldmx_log(info) << " nhits = " << track.nMeasurements();
487 for (const auto ts : track.trackStatesReversed()) {
488 ldmx_log(info) << "Smoothed? " << ts.hasSmoothed() << std::endl;
489 if (ts.hasSmoothed()) {
490 ldmx_log(info) << "momentum for track state = "
491 << 1 / ts.smoothed()[Acts::eBoundQOverP];
492 ldmx_log(info) << "Parameters \n"
493 << ts.smoothed().transpose() << std::endl;
494 } else {
495 ldmx_log(info) << "Track state not smoothed?";
496 }
497 }
498 ldmx_log(info) << "...skipping this track...";
499 continue;
500 }
501
502 // get the BoundTrackParameters at the target
503 // ...use to fill in the Acts::TrackProxy object
504 // This isn't really necessary, since we can take
505 // most everything for making the ldmx::track
506 // from tsAtTarget...maybe useful for something?
507 // -->one thing this does is allow Acts to
508 // calculate the momentum 3-vector for you
509 Acts::BoundTrackParameters boundStateAtTarget =
510 tracking::sim::utils::btp(tsAtTarget, target_surface, 11);
511 track.setReferenceSurface(target_surface);
512 track.parameters() = boundStateAtTarget.parameters();
513
514 ldmx_log(debug) << typeid(track).name();
515 // These are the parameters at the target surface
516 const Acts::BoundVector& track_pars = track.parameters();
517 // const Acts::BoundMatrix& trk_cov = track.covariance();
518 const Acts::Surface& track_surface = track.referenceSurface();
519 ldmx_log(debug) << "Got the parameters, covariance, and perigee surface";
520
521 ldmx_log(debug) << track_pars[Acts::eBoundLoc0];
522 ldmx_log(debug) << track_pars[Acts::eBoundLoc1];
523 ldmx_log(debug) << track_pars[Acts::eBoundTheta];
524 ldmx_log(debug) << track_pars[Acts::eBoundPhi];
525 ldmx_log(debug)
526 << "Reference Surface" << std::endl
527 << " " << track_surface.transform(geometry_context()).translation()(0)
528 << " " << track_surface.transform(geometry_context()).translation()(1)
529 << " "
530 << track_surface.transform(geometry_context()).translation()(2);
531
532 trk.setPerigeeLocation(
533 0, 0, 0); // the target...it's not really perigee anymore.
534 trk.setPerigeeParameters(tsAtTarget.params);
535 trk.setPerigeeCov(tsAtTarget.cov);
536
537 ldmx_log(debug) << "setting chi2 and nHits: " << track.chi2() << " "
538 << track.nMeasurements();
539 trk.setChi2(track.chi2());
540 trk.setNhits(track.nMeasurements());
541 // trk.setNdf(track.nDoF());
542 // TODO Switch back to nDoF when Acts is fixed.
543 trk.setNdf(track.nMeasurements() - 5);
544 trk.setNsharedHits(track.nSharedHits());
545
546 ldmx_log(debug) << "setting track momentum: " << track.momentum();
547 trk.setMomentum(track.momentum()[0], track.momentum()[1],
548 track.momentum()[2]);
549
550 ldmx_log(debug) << "starting extrapolations";
551 // Extrapolations
552
553 const double ECAL_SCORING_PLANE = 240.5;
554 Acts::Vector3 pos(ECAL_SCORING_PLANE, 0., 0.);
555 Acts::Translation3 surf_translation(pos);
556 Acts::Transform3 surf_transform(surf_translation * surf_rotation);
557
558 // Unbounded surface
559 const std::shared_ptr<Acts::PlaneSurface> ecal_surface =
560 Acts::Surface::makeShared<Acts::PlaneSurface>(surf_transform);
561
562 // Beam Origin unbounded surface
563 const std::shared_ptr<Acts::Surface> beamOrigin_surface =
564 tracking::sim::utils::unboundSurface(-700);
565
566 if (taggerTracking_) {
567 ldmx_log(debug) << "Beam Origin Extrapolation";
568 ldmx::Track::TrackState tsAtBeamOrigin;
569 success = trk_extrap_->TrackStateAtSurface(
570 track, beamOrigin_surface, tsAtBeamOrigin,
571 ldmx::TrackStateType::AtBeamOrigin);
572
573 if (success) {
574 trk.addTrackState(tsAtBeamOrigin);
575 ldmx_log(debug) << "Successfully obtained TS at beam origin";
576 }
577 }
578
579 // Recoil Extrapolation to ECAL only
580 if (!taggerTracking_) {
581 ldmx_log(debug) << "Ecal Extrapolation";
583 success = trk_extrap_->TrackStateAtSurface(
584 track, ecal_surface, tsAtEcal, ldmx::TrackStateType::AtECAL);
585
586 if (success) {
587 trk.addTrackState(tsAtEcal);
588 ldmx_log(debug) << "Successfully obtained TS at Ecal";
589 ldmx_log(debug) << "Parameters At Ecal: \n"
590 << tsAtEcal.params[0] << " " << tsAtEcal.params[1]
591 << " " << tsAtEcal.params[2] << " "
592 << tsAtEcal.params[3] << " " << tsAtEcal.params[4];
593 }
594 }
595
596 // Truth matching
597 if (truthMatchingTool) {
598 auto truthInfo = truthMatchingTool->TruthMatch(trk);
599 trk.setTrackID(truthInfo.trackID);
600 trk.setPdgID(truthInfo.pdgID);
601 trk.setTruthProb(truthInfo.truthProb);
602 }
603
604 // At least min_hits_ hits and p > 50 MeV
605 if (trk.getNhits() > min_hits_ && abs(1. / trk.getQoP()) > 0.05) {
606 tracks.push_back(trk);
607 ntracks_++;
608 }
609 }
610 } // loop seed track parameters
611
612 auto result_loop = std::chrono::high_resolution_clock::now();
613 profiling_map_["result_loop"] +=
614 std::chrono::duration<double, std::milli>(result_loop - ckf_run).count();
615
616 // Add the tracks to the event
617 event.add(out_trk_collection_, tracks);
618
619 auto end = std::chrono::high_resolution_clock::now();
620 // long long microseconds =
621 // std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
622 auto diff = end - start;
623 processing_time_ += std::chrono::duration<double, std::milli>(diff).count();
624}
bool exists(const std::string &name, const std::string &passName="", bool unique=true) const
Check for the existence of an object or collection with the given name and pass name in the event.
Definition Event.cxx:92
Class representing a simulated particle.
Definition SimParticle.h:23
Implementation of a track object.
Definition Track.h:52
void setPerigeeParameters(const std::vector< double > &par)
d_0 z_0 phi_0 theta q/p t
Definition Track.h:144
void calibrate_1d(const Acts::GeometryContext &, const Acts::CalibrationContext &, const Acts::SourceLink &genericSourceLink, typename traj_t::TrackStateProxy trackState) const
Find the measurement corresponding to the source link.
void calibrate(const Acts::GeometryContext &, const Acts::CalibrationContext &, const Acts::SourceLink &genericSourceLink, typename traj_t::TrackStateProxy trackState) const
Find the measurement corresponding to the source link.

References tracking::sim::LdmxMeasurementCalibrator::calibrate(), tracking::sim::LdmxMeasurementCalibrator::calibrate_1d(), framework::Event::exists(), ActsExamples::IndexSourceLink::index(), nseeds_, and ldmx::Track::setPerigeeParameters().

Member Data Documentation

◆ bfield_

double tracking::reco::CKFProcessor::bfield_ {0}
private

Definition at line 163 of file CKFProcessor.h.

163{0};

◆ ckf_

std::unique_ptr< const Acts::CombinatorialKalmanFilter<CkfPropagator, TrackContainer> > tracking::reco::CKFProcessor::ckf_
private

Definition at line 210 of file CKFProcessor.h.

◆ const_b_field_

bool tracking::reco::CKFProcessor::const_b_field_ {true}
private

Definition at line 165 of file CKFProcessor.h.

165{true};

◆ debug_acts_

bool tracking::reco::CKFProcessor::debug_acts_ {false}
private

Definition at line 158 of file CKFProcessor.h.

158{false};

◆ dumpobj_

bool tracking::reco::CKFProcessor::dumpobj_ {false}
private

Definition at line 146 of file CKFProcessor.h.

146{false};

◆ eventnr_

int tracking::reco::CKFProcessor::eventnr_ {0}
private

Definition at line 219 of file CKFProcessor.h.

219{0};

◆ extrapolate_location_

std::vector<double> tracking::reco::CKFProcessor::extrapolate_location_ {0., 0., 0.}
private

Definition at line 182 of file CKFProcessor.h.

182{0., 0., 0.};

◆ field_map_

std::string tracking::reco::CKFProcessor::field_map_ {""}
private

Definition at line 202 of file CKFProcessor.h.

202{""};

◆ map_offset_

std::vector<double> tracking::reco::CKFProcessor::map_offset_
private
Initial value:
{
0.,
0.,
0.,
}

Definition at line 222 of file CKFProcessor.h.

222 {
223 0.,
224 0.,
225 0.,
226 };

◆ measurement_collection_

std::string tracking::reco::CKFProcessor::measurement_collection_ {"TaggerMeasurements"}
private

Definition at line 186 of file CKFProcessor.h.

186{"TaggerMeasurements"};

◆ min_hits_

int tracking::reco::CKFProcessor::min_hits_ {7}
private

Definition at line 174 of file CKFProcessor.h.

174{7};

◆ nevents_

int tracking::reco::CKFProcessor::nevents_ {0}
private

Definition at line 150 of file CKFProcessor.h.

150{0};

◆ nseeds_

int tracking::reco::CKFProcessor::nseeds_ {0}
private

n seeds and n tracks

Definition at line 217 of file CKFProcessor.h.

217{0};

Referenced by onProcessEnd(), and produce().

◆ ntracks_

int tracking::reco::CKFProcessor::ntracks_ {0}
private

Definition at line 218 of file CKFProcessor.h.

218{0};

◆ out_trk_collection_

std::string tracking::reco::CKFProcessor::out_trk_collection_ {"Tracks"}
private

Definition at line 196 of file CKFProcessor.h.

196{"Tracks"};

◆ outlier_pval_

double tracking::reco::CKFProcessor::outlier_pval_ {3.84}
private

Definition at line 193 of file CKFProcessor.h.

193{3.84};

◆ pionstates_

int tracking::reco::CKFProcessor::pionstates_ {10}
private

Definition at line 148 of file CKFProcessor.h.

148{10};

◆ processing_time_

double tracking::reco::CKFProcessor::processing_time_ {0.}
private

Definition at line 153 of file CKFProcessor.h.

153{0.};

◆ profiling_map_

std::map<std::string, double> tracking::reco::CKFProcessor::profiling_map_
private

Definition at line 156 of file CKFProcessor.h.

◆ propagator_

std::unique_ptr<const CkfPropagator> tracking::reco::CKFProcessor::propagator_
private

Definition at line 205 of file CKFProcessor.h.

◆ propagator_maxSteps_

int tracking::reco::CKFProcessor::propagator_maxSteps_ {1000}
private

Definition at line 178 of file CKFProcessor.h.

178{1000};

◆ propagator_step_size_

double tracking::reco::CKFProcessor::propagator_step_size_ {200.}
private

Definition at line 177 of file CKFProcessor.h.

177{200.};

◆ remove_stereo_

bool tracking::reco::CKFProcessor::remove_stereo_ {false}
private

Definition at line 168 of file CKFProcessor.h.

168{false};

◆ seed_coll_name_

std::string tracking::reco::CKFProcessor::seed_coll_name_ {"seedTracks"}
private

Definition at line 199 of file CKFProcessor.h.

199{"seedTracks"};

◆ surf_rotation

Acts::RotationMatrix3 tracking::reco::CKFProcessor::surf_rotation
private

Definition at line 161 of file CKFProcessor.h.

◆ taggerTracking_

bool tracking::reco::CKFProcessor::taggerTracking_ {true}
private

Definition at line 229 of file CKFProcessor.h.

229{true};

◆ target_surface

std::shared_ptr<Acts::PlaneSurface> tracking::reco::CKFProcessor::target_surface
private

Definition at line 160 of file CKFProcessor.h.

◆ trk_extrap_

std::shared_ptr<tracking::reco::TrackExtrapolatorTool<CkfPropagator> > tracking::reco::CKFProcessor::trk_extrap_
private

Definition at line 214 of file CKFProcessor.h.

◆ use1Dmeasurements_

bool tracking::reco::CKFProcessor::use1Dmeasurements_ {true}
private

Definition at line 171 of file CKFProcessor.h.

171{true};

◆ use_extrapolate_location_

bool tracking::reco::CKFProcessor::use_extrapolate_location_ {true}
private

Definition at line 181 of file CKFProcessor.h.

181{true};

◆ use_seed_perigee_

bool tracking::reco::CKFProcessor::use_seed_perigee_ {false}
private

Definition at line 183 of file CKFProcessor.h.

183{false};

The documentation for this class was generated from the following files: