LDMX Software
tracking::reco::TruthSeedProcessor Class Reference

Create a track seed using truth information extracted from the corresponding SimParticle or SimTrackerHit. More...

#include <TruthSeedProcessor.h>

Public Member Functions

 TruthSeedProcessor (const std::string &name, framework::Process &process)
 Constructor.
 
virtual ~TruthSeedProcessor ()=default
 Destructor.
 
void configure (framework::config::Parameters &parameters) override
 Callback for the EventProcessor to configure itself from the given set of parameters.
 
void onProcessStart () override
 Callback for the EventProcessor to take any necessary action when the processing of events starts.
 
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 produce (framework::Event &event) override
 Main loop that creates the seed tracks for both the tagger and recoil tracker.
 
- 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 process (Event &event) final
 Processing an event for a Producer is calling produce.
 
- Public Member Functions inherited from framework::EventProcessor
 DECLARE_FACTORY (EventProcessor, EventProcessor *, const std::string &, Process &)
 declare that we have a factory for this class
 
 EventProcessor (const std::string &name, Process &process)
 Class constructor.
 
virtual ~EventProcessor ()=default
 Class destructor.
 
virtual void beforeNewRun (ldmx::RunHeader &run_header)
 Callback for Producers to add parameters to the run header before conditions are initialized.
 
virtual void onFileOpen (EventFile &event_file)
 Callback for the EventProcessor to take any necessary action when a new event input ROOT file is opened.
 
virtual void onFileClose (EventFile &event_file)
 Callback for the EventProcessor to take any necessary action when a event input ROOT file is closed.
 
virtual void onProcessEnd ()
 Callback for the EventProcessor to take any necessary action when the processing of events finishes, such as calculating job-summary quantities.
 
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

void makeHitCountMap (const std::vector< ldmx::SimTrackerHit > &sim_hits, std::map< int, std::vector< int > > &hit_count_map)
 Create a mapping from the selected scoring plane hit objects to the number of hits they associated particle creates in the tracker.
 
void createTruthTrack (const ldmx::SimParticle &particle, ldmx::Track &trk, const std::shared_ptr< Acts::Surface > &target_surface)
 Use the vertex position of the SimParticle to extract (x_, y_, z_, px, py, pz, q) and create a track seed.
 
void createTruthTrack (const ldmx::SimParticle &particle, const ldmx::SimTrackerHit &hit, ldmx::Track &trk, const std::shared_ptr< Acts::Surface > &target_surface)
 Use the scoring plane hit at the target to extract (x_, y_, z_, px, py, pz) and create a track seed.
 
void createTruthTrack (const std::vector< double > &pos_vec, const std::vector< double > &p_vec, int charge, ldmx::Track &trk, const std::shared_ptr< Acts::Surface > &target_surface)
 Create a seed track from the given position, momentum and charge.
 
bool scoringPlaneHitFilter (const ldmx::SimTrackerHit &hit, const std::vector< ldmx::SimTrackerHit > &ecal_sp_hits)
 Filter that checks if a scoring plane passes specified momentum cuts as well as if the associated SimParticle hits the ECal.
 
ldmx::Track seedFromTruth (const ldmx::Track &tt, bool seed_smearing)
 Create a track seed from a truth track applying a smearing to the truth parameters as well as an inflation to the covariance matrix.
 
ldmx::Track recoilFullSeed (const ldmx::SimParticle &particle, const int trackID, const ldmx::SimTrackerHit &hit, const ldmx::SimTrackerHit &ecal_hit, const std::map< int, std::vector< int > > &hit_count_map, const std::shared_ptr< Acts::Surface > &origin_surface, const std::shared_ptr< Acts::Surface > &target_surface, const std::shared_ptr< Acts::Surface > &ecal_surface)
 
ldmx::Track taggerFullSeed (const ldmx::SimParticle &beam_electron, const int trackID, const ldmx::SimTrackerHit &hit, const std::map< int, std::vector< int > > &hit_count_map, const std::shared_ptr< Acts::Surface > &origin_surface, const std::shared_ptr< Acts::Surface > &target_surface)
 This method retrieves the beam electron and forms a full seed The seed parameters are the truth parameters from the beam electron stored at the beam origin Additionally, the foolowing track states are stored ts_smeared : the truth smeared perigee state at the beam origin ts_truth_target : the truth on-surface state at the target Linear extrapolations are done from the origin of the particle to the reference surfaces This track also contains the list of hits belonging to the beam electron on the sensitive surfaces on the tagger tracker, for acceptance studies.
 

Private Attributes

std::vector< int > pdg_ids_ {11}
 pdg_ids of the particles we want to select for the seeds
 
std::string scoring_hits_coll_name_ {"TargetScoringPlaneHits"}
 Which scoring plane hits to use for the truth seeds generation.
 
std::string ecal_sp_coll_name_ {"EcalScoringPlaneHits"}
 
std::string sp_pass_name_ {""}
 
std::string tagger_sim_hits_coll_name_ {"TaggerSimHits"}
 Sim hits to check if the truth seed is findable.
 
std::string recoil_sim_hits_coll_name_ {"RecoilSimHits"}
 Sim hits to check if the truth seed is findable.
 
std::string input_pass_name_ {""}
 Pass name for the sim hit collections.
 
std::string sim_particles_coll_name_
 
std::string sim_particles_passname_
 
int n_min_hits_tagger_ {7}
 Minimum number of hits left in the recoil tracker to consider the seed as findable.
 
int n_min_hits_recoil_ {7}
 Minimum number of hits left in the recoil tracker to consider the seed as findable.
 
float z_min_ {-999}
 Min cut on the z_ of the scoring hit.
 
int track_id_ {-999}
 Only select a particular trackID.
 
double pz_cut_ {-9999}
 Ask for a minimum pz for the seeds.
 
double p_cut_ {0.}
 Ask for a minimum p for the seeds.
 
double p_cut_max_ {100000.}
 Ask for a maximum p for the seeds.
 
double p_cut_ecal_ {-1.}
 
bool recoil_sp_ {true}
 
bool target_sp_ {true}
 
bool skip_tagger_ {false}
 
bool skip_recoil_ {false}
 
int max_track_id_ {5}
 
std::unique_ptr< const TruthPropagator > propagator_
 
std::shared_ptr< tracking::reco::TrackExtrapolatorTool< TruthPropagator > > trk_extrap_
 
std::string field_map_ {""}
 Path to the magnetic field map.
 
std::default_random_engine generator_
 
std::shared_ptr< std::normal_distribution< float > > normal_
 
bool seed_smearing_ {false}
 
std::vector< double > d0smear_
 
std::vector< double > z0smear_
 
double phismear_
 
double thetasmear_
 
double relpsmear_
 
std::vector< double > rel_smearfactors_
 
std::vector< double > inflate_factors_
 
std::vector< double > beam_origin_ {-880.1, -44., 0.}
 
int particle_hypothesis_
 
std::string beam_electrons_collection_
 
std::string tagger_truth_collection_
 
std::string recoil_truth_collection_
 
std::string tagger_seeds_collection_
 
std::string recoil_seeds_collection_
 

Additional Inherited Members

- Protected Member Functions inherited from tracking::reco::TrackingGeometryUser
const Acts::GeometryContext & geometryContext ()
 
const Acts::MagneticFieldContext & magneticFieldContext ()
 
const Acts::CalibrationContext & calibrationContext ()
 
const geo::TrackersTrackingGeometrygeometry ()
 
void loadBField (const std::string &path, const std::vector< double > &map_offset={0., 0., 0.})
 Load the interpolated B-field map from path and cache it.
 
void loadBField (const std::vector< double > &map_offset={0., 0., 0.})
 Load B-field from the path recorded in the detector GDML.
 
std::shared_ptr< Acts::MagneticFieldProvider > bField () const
 Return the loaded B-field provider.
 
- Protected Member Functions inherited from framework::EventProcessor
void abortEvent ()
 Abort the event immediately.
 
- Protected Attributes inherited from framework::EventProcessor
HistogramPool histograms_
 helper object for making and filling histograms
 
NtupleManagerntuple_ {NtupleManager::getInstance()}
 Manager for any ntuples.
 
logging::logger the_log_
 The logger for this EventProcessor.
 

Detailed Description

Create a track seed using truth information extracted from the corresponding SimParticle or SimTrackerHit.

When creating seeds in the Tagger tracker, the SimParticle associated with the incident electron (trackID == 1) is used to create the seed from the parameters (x_, y_, z_, px, py, pz, q) at the vertex. For the Recoil tracker, since the electron is produced upstream, the SimParticle can't be used to get any parameters at the target. In this case, the target scoring plane hits are used to extract the parameters above.

Definition at line 43 of file TruthSeedProcessor.h.

Constructor & Destructor Documentation

◆ TruthSeedProcessor()

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

Constructor.

Parameters
nameName for this instance of the class.
processThe Process class associated with EventProcessor, provided by the framework.

Definition at line 7 of file TruthSeedProcessor.cxx.

9 : TrackingGeometryUser(name, process) {}
virtual void process(Event &event) final
Processing an event for a Producer is calling produce.

Member Function Documentation

◆ configure()

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

Callback for the EventProcessor to configure itself from the given set of parameters.

The parameters a processor has access to are the member variables of the python class in the sequence that has class_name equal to the EventProcessor class name.

Parameters
parametersParameters for configuration.

Reimplemented from framework::EventProcessor.

Definition at line 53 of file TruthSeedProcessor.cxx.

53 {
55 parameters.get<std::string>("scoring_hits_coll_name");
56 ecal_sp_coll_name_ = parameters.get<std::string>("ecal_sp_coll_name");
57 sp_pass_name_ = parameters.get<std::string>("sp_pass_name");
59 parameters.get<std::string>("recoil_sim_hits_coll_name");
61 parameters.get<std::string>("tagger_sim_hits_coll_name");
62 input_pass_name_ = parameters.get<std::string>("input_pass_name");
63 sim_particles_coll_name_ =
64 parameters.get<std::string>("sim_particles_coll_name");
65 sim_particles_passname_ =
66 parameters.get<std::string>("sim_particles_passname");
67
68 n_min_hits_tagger_ = parameters.get<int>("n_min_hits_tagger", 11);
69 n_min_hits_recoil_ = parameters.get<int>("n_min_hits_recoil", 7);
70 pdg_ids_ = parameters.get<std::vector<int>>("pdg_ids", {11});
71 z_min_ = parameters.get<double>("z_min", -9999); // mm
72 track_id_ = parameters.get<int>("track_id", -9999);
73 pz_cut_ = parameters.get<double>("pz_cut", -9999); // MeV
74 p_cut_ = parameters.get<double>("p_cut", 0.);
75 p_cut_max_ = parameters.get<double>("p_cut_max", 100000.); // MeV
76 p_cut_ecal_ = parameters.get<double>("p_cut_ecal", -1.); // MeV
77 recoil_sp_ = parameters.get<double>("recoil_sp", true);
78 target_sp_ = parameters.get<double>("tagger_sp", true);
79 seed_smearing_ = parameters.get<bool>("seedSmearing", false);
80 max_track_id_ = parameters.get<int>("max_track_id", 5);
81
82 ldmx_log(info) << "Seed Smearing is set to " << seed_smearing_;
83
84 d0smear_ = parameters.get<std::vector<double>>("d0smear", {0.01, 0.01, 0.01});
85 z0smear_ = parameters.get<std::vector<double>>("z0smear", {0.1, 0.1, 0.1});
86 phismear_ = parameters.get<double>("phismear", 0.001);
87 thetasmear_ = parameters.get<double>("thetasmear", 0.001);
88 relpsmear_ = parameters.get<double>("relpsmear", 0.1);
89
90 // Relative smear factor terms, only used if seed_smearing_ is true.
91 rel_smearfactors_ = parameters.get<std::vector<double>>(
92 "rel_smearfactors", {0.1, 0.1, 0.1, 0.1, 0.1, 0.1});
93 inflate_factors_ = parameters.get<std::vector<double>>(
94 "inflate_factors", {10., 10., 10., 10., 10., 10.});
95
96 // In tracking frame: where do these numbers come from?
97 // These numbers come from approximating the path of the beam up
98 // until it is about to enter the first detector volume (TriggerPad1).
99 // In detector coordinates, (x_,y_,z_) = (-21.7, -883) is
100 // where the beam arrives (if no smearing is applied) and we simply
101 // reorder these values so that they are in tracking coordinates.
102 beam_origin_ = parameters.get<std::vector<double>>("beamOrigin",
103 {-883.0, -21.745876, 0.0});
104
105 // Skip the tagger or recoil trackers if wanted
106 skip_tagger_ = parameters.get<bool>("skip_tagger", false);
107 skip_recoil_ = parameters.get<bool>("skip_recoil", false);
108 particle_hypothesis_ = parameters.get<int>("particle_hypothesis");
109
110 beam_electrons_collection_ =
111 parameters.get<std::string>("beam_electrons_collection");
112 tagger_truth_collection_ =
113 parameters.get<std::string>("tagger_truth_collection");
114 recoil_truth_collection_ =
115 parameters.get<std::string>("recoil_truth_collection");
116 tagger_seeds_collection_ =
117 parameters.get<std::string>("tagger_seeds_collection");
118 recoil_seeds_collection_ =
119 parameters.get<std::string>("recoil_seeds_collection");
120 // Get the field map for the propagator
121 field_map_ = parameters.get<std::string>("field_map");
122}
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:78
float z_min_
Min cut on the z_ of the scoring hit.
std::string input_pass_name_
Pass name for the sim hit collections.
std::string recoil_sim_hits_coll_name_
Sim hits to check if the truth seed is findable.
std::vector< int > pdg_ids_
pdg_ids of the particles we want to select for the seeds
int track_id_
Only select a particular trackID.
double pz_cut_
Ask for a minimum pz for the seeds.
double p_cut_
Ask for a minimum p for the seeds.
std::string field_map_
Path to the magnetic field map.
std::string scoring_hits_coll_name_
Which scoring plane hits to use for the truth seeds generation.
std::string tagger_sim_hits_coll_name_
Sim hits to check if the truth seed is findable.
double p_cut_max_
Ask for a maximum p for the seeds.
int n_min_hits_tagger_
Minimum number of hits left in the recoil tracker to consider the seed as findable.
int n_min_hits_recoil_
Minimum number of hits left in the recoil tracker to consider the seed as findable.

References field_map_, framework::config::Parameters::get(), input_pass_name_, n_min_hits_recoil_, n_min_hits_tagger_, p_cut_, p_cut_max_, pdg_ids_, pz_cut_, recoil_sim_hits_coll_name_, scoring_hits_coll_name_, tagger_sim_hits_coll_name_, track_id_, and z_min_.

◆ createTruthTrack() [1/3]

void tracking::reco::TruthSeedProcessor::createTruthTrack ( const ldmx::SimParticle & particle,
const ldmx::SimTrackerHit & hit,
ldmx::Track & trk,
const std::shared_ptr< Acts::Surface > & target_surface )
private

Use the scoring plane hit at the target to extract (x_, y_, z_, px, py, pz) and create a track seed.

In this case, the SimParticle is used to extract the charge of the particle.

Parameters
particleThe SimParticle to extract the charge from.
hitThe SimTrackerHit used to create the seed.

Definition at line 124 of file TruthSeedProcessor.cxx.

126 {
127 std::vector<double> pos{static_cast<double>(hit.getPosition()[0]),
128 static_cast<double>(hit.getPosition()[1]),
129 static_cast<double>(hit.getPosition()[2])};
130 createTruthTrack(pos, hit.getMomentum(), particle.getCharge(), trk,
131 target_surface);
132
133 trk.setTrackID(hit.getTrackID());
134 trk.setPdgID(hit.getPdgID());
135}
double getCharge() const
Get the charge of this particle.
int getPdgID() const
Get the Sim particle track ID of the hit.
std::vector< float > getPosition() const
Get the XYZ position of the hit [mm].
std::vector< double > getMomentum() const
Get the XYZ momentum of the particle at the position at which the hit took place [MeV].
int getTrackID() const
Get the Sim particle track ID of the hit.
void createTruthTrack(const ldmx::SimParticle &particle, ldmx::Track &trk, const std::shared_ptr< Acts::Surface > &target_surface)
Use the vertex position of the SimParticle to extract (x_, y_, z_, px, py, pz, q) and create a track ...

References createTruthTrack(), ldmx::SimParticle::getCharge(), ldmx::SimTrackerHit::getMomentum(), ldmx::SimTrackerHit::getPdgID(), ldmx::SimTrackerHit::getPosition(), and ldmx::SimTrackerHit::getTrackID().

◆ createTruthTrack() [2/3]

void tracking::reco::TruthSeedProcessor::createTruthTrack ( const ldmx::SimParticle & particle,
ldmx::Track & trk,
const std::shared_ptr< Acts::Surface > & target_surface )
private

Use the vertex position of the SimParticle to extract (x_, y_, z_, px, py, pz, q) and create a track seed.

Parameters
particleThe SimParticle to make a seed from.

Definition at line 137 of file TruthSeedProcessor.cxx.

139 {
140 createTruthTrack(particle.getVertex(), particle.getMomentum(),
141 particle.getCharge(), trk, target_surface);
142
143 trk.setPdgID(particle.getPdgID());
144}
std::vector< double > getVertex() const
Get a vector containing the vertex of this particle in mm.
int getPdgID() const
Get the PDG ID of this particle.
Definition SimParticle.h:86
std::vector< double > getMomentum() const
Get a vector containing the momentum of this particle [MeV].

References createTruthTrack(), ldmx::SimParticle::getCharge(), ldmx::SimParticle::getMomentum(), ldmx::SimParticle::getPdgID(), and ldmx::SimParticle::getVertex().

Referenced by createTruthTrack(), createTruthTrack(), and taggerFullSeed().

◆ createTruthTrack() [3/3]

void tracking::reco::TruthSeedProcessor::createTruthTrack ( const std::vector< double > & pos_vec,
const std::vector< double > & p_vec,
int charge,
ldmx::Track & trk,
const std::shared_ptr< Acts::Surface > & target_surface )
private

Create a seed track from the given position, momentum and charge.

Parameters
pos_The position at which the particle was created.
pThe momentum of the particle at the point of creation.
chargeThe charge of the particle.
target_surfacethe surface to where to express the truth track

Definition at line 146 of file TruthSeedProcessor.cxx.

149 {
150 // Get the position and momentum of the particle at the point of creation.
151 // This only works for the incident electron when creating a tagger tracker
152 // seed. For the recoil tracker, the scoring plane position will need to
153 // be used. For other particles created in the target or tracker planes,
154 // this version of the method can also be used.
155 // These are just Eigen vectors defined as
156 // Eigen::Matrix<double, kSize, 1>;
157 Acts::Vector3 pos{pos_vec[0], pos_vec[1], pos_vec[2]};
158 Acts::Vector3 mom{p_vec[0], p_vec[1], p_vec[2]};
159
160 // Rotate the position and momentum into the ACTS frame.
161 pos = tracking::sim::utils::ldmx2Acts(pos);
162 mom = tracking::sim::utils::ldmx2Acts(mom);
163
164 // Get the charge of the particle.
165 // TODO: Add function that uses the PDG ID to calculate this.
166 double q{charge * Acts::UnitConstants::e};
167
168 // The idea here is:
169 // 1 - Define a bound track state parameters at point P on track. Basically a
170 // curvilinear representation.
171 // 2 - Propagate to target surface to obtain the
172 // BoundTrackState there.
173
174 // Transform the position, momentum and charge to free parameters.
175 auto free_params{tracking::sim::utils::toFreeParameters(pos, mom, q)};
176
177 // Create a line surface at the perigee. The perigee position is extracted
178 // from a particle's vertex or the particle's position at a specific
179 // scoring plane.
180 auto gen_surface{Acts::Surface::makeShared<Acts::PerigeeSurface>(
181 Acts::Vector3(free_params[Acts::eFreePos0], free_params[Acts::eFreePos1],
182 free_params[Acts::eFreePos2]))};
183
184 // ldmx_log(trace)<<"PF:: gen_surface"<<free_params[Acts::eFreePos0]<<"
185 // " <<free_params[Acts::eFreePos1]<<" " <<free_params[Acts::eFreePos2];
186
187 // Transform the parameters to local positions on the perigee surface.
188 auto bound_params{Acts::transformFreeToBoundParameters(
189 free_params, *gen_surface, geometryContext())
190 .value()};
191 // Create a particle hypothesis
192 auto part{Acts::ParticleHypothesis(Acts::PdgParticle(particle_hypothesis_))};
193 Acts::BoundTrackParameters bound_trk_pars(gen_surface, bound_params,
194 std::nullopt, part);
195
196 auto prop_bound_state =
197 trk_extrap_->extrapolate(bound_trk_pars, target_surface);
198
199 if (!prop_bound_state) {
200 ldmx_log(warn) << "Propagation to target surface failed — "
201 << "track may have exited the B-field map.";
202 return;
203 }
204
205 // Create the seed track object.
206 Acts::Vector3 ref = target_surface->center(geometryContext());
207 Acts::Vector3 ref_ldmx = tracking::sim::utils::acts2Ldmx(ref);
208 trk.setPerigeeLocation(ref_ldmx(0), ref_ldmx(1), ref_ldmx(2));
209
210 auto prop_bound_vec = prop_bound_state->parameters();
211
212 trk.setPerigeeParameters(
213 tracking::sim::utils::convertActsToLdmxPars(prop_bound_vec));
214}

◆ makeHitCountMap()

void tracking::reco::TruthSeedProcessor::makeHitCountMap ( const std::vector< ldmx::SimTrackerHit > & sim_hits,
std::map< int, std::vector< int > > & hit_count_map )
private

Create a mapping from the selected scoring plane hit objects to the number of hits they associated particle creates in the tracker.

Parameters
sim_hitsvector
hit_count_mapfilled with the hits lefts by each track

Definition at line 467 of file TruthSeedProcessor.cxx.

469 {
470 for (int i_sim_hit = 0; i_sim_hit < sim_hits.size(); i_sim_hit++) {
471 auto& sim_hit = sim_hits.at(i_sim_hit);
472 // This track never left a hit before
473 if (!hit_count_map.count(sim_hit.getTrackID())) {
474 hit_count_map[sim_hit.getTrackID()].push_back(i_sim_hit);
475 }
476
477 // This track left a hit before.
478 // Check if it's on a different sensor than the others
479
480 else {
481 int sensor_id = tracking::sim::utils::getSensorID(sim_hit);
482 bool found_hit = false;
483
484 for (auto& i_rhit : hit_count_map[sim_hit.getTrackID()]) {
485 int tmp_sensor_id =
486 tracking::sim::utils::getSensorID(sim_hits.at(i_rhit));
487
488 if (sensor_id == tmp_sensor_id) {
489 found_hit = true;
490 break;
491 }
492 } // loop on the already recorded hits
493
494 if (!found_hit) {
495 hit_count_map[sim_hit.getTrackID()].push_back(i_sim_hit);
496 }
497 }
498 } // loop on sim hits
499}

Referenced by produce().

◆ onNewRun()

void tracking::reco::TruthSeedProcessor::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 11 of file TruthSeedProcessor.cxx.

11 {
12 normal_ = std::make_shared<std::normal_distribution<float>>(0., 1.);
13
14 // Custom transformation of the interpolated bfield map
15 auto transform_pos = [](const Acts::Vector3& pos_) {
16 Acts::Vector3 rot_pos;
17 rot_pos(0) = pos_(1);
18 rot_pos(1) = pos_(2);
19 rot_pos(2) = pos_(0) + DIPOLE_OFFSET;
20 return rot_pos;
21 };
22
23 auto transform_b_field = [](const Acts::Vector3& field,
24 const Acts::Vector3& /*pos_*/) {
25 Acts::Vector3 rot_field;
26 rot_field(0) = field(2);
27 rot_field(1) = field(0);
28 rot_field(2) = field(1);
29 return rot_field;
30 };
31
32 // Setup the interpolated bfield map
33 const auto map = std::make_shared<InterpolatedMagneticField3>(
34 loadDefaultBField(field_map_, transform_pos, transform_b_field));
35
36 // Setup the stepper and navigator
37 const auto stepper = Acts::EigenStepper<>{map};
38 Acts::Navigator::Config nav_cfg{geometry().getTG()};
39 nav_cfg.resolveMaterial = true;
40 nav_cfg.resolvePassive = true;
41 nav_cfg.resolveSensitive = true;
42 const Acts::Navigator navigator(nav_cfg);
43
44 propagator_ = std::make_unique<TruthPropagator>(
45 stepper, navigator,
46 Acts::getDefaultLogger("TruthPropagator", Acts::Logging::FATAL));
47 trk_extrap_ = std::make_shared<std::decay_t<decltype(*trk_extrap_)>>(
48 *propagator_, geometryContext(), magneticFieldContext());
49 trk_extrap_->setMaxStepSize(200); // mm
50 trk_extrap_->setPathLimit(3000); // mm
51}

References field_map_.

◆ onProcessStart()

void tracking::reco::TruthSeedProcessor::onProcessStart ( )
inlineoverridevirtual

Callback for the EventProcessor to take any necessary action when the processing of events starts.

For this class, the callback is used to retrieve the GeometryContext from ACTS.

Reimplemented from framework::EventProcessor.

Definition at line 74 of file TruthSeedProcessor.h.

74{};

◆ produce()

void tracking::reco::TruthSeedProcessor::produce ( framework::Event & event)
overridevirtual

Main loop that creates the seed tracks for both the tagger and recoil tracker.

Parameters
eventThe event containing the collections to process.

Implements framework::Producer.

Definition at line 555 of file TruthSeedProcessor.cxx.

555 {
556 // Retrieve the particleMap
557 auto particle_map{event.getMap<int, ldmx::SimParticle>(
558 sim_particles_coll_name_, sim_particles_passname_)};
559
560 // Retrieve the target scoring hits
561 // Information is extracted using the
562 // scoring plane hit left by the particle at the target.
563
564 const auto& scoring_hits = event.getCollection<ldmx::SimTrackerHit>(
565 scoring_hits_coll_name_, sp_pass_name_);
566
567 // Retrieve the sim hits in the tagger tracker
568 const auto& tagger_sim_hits = event.getCollection<ldmx::SimTrackerHit>(
570
571 // Retrieve the sim hits in the recoil tracker
572 const auto& recoil_sim_hits = event.getCollection<ldmx::SimTrackerHit>(
574
575 // If sim hit collections are empty throw a warning
576 if (tagger_sim_hits.size() == 0 && !skip_tagger_) {
577 ldmx_log(error) << "Tagger sim hits collection empty for event ";
578 }
579 if (recoil_sim_hits.size() == 0 && !skip_recoil_) {
580 ldmx_log(error) << "Recoil sim hits collection empty for event ";
581 }
582
583 // The map stores which track leaves which sim hits
584 std::map<int, std::vector<int>> hit_count_map_recoil;
585 makeHitCountMap(recoil_sim_hits, hit_count_map_recoil);
586
587 std::map<int, std::vector<int>> hit_count_map_tagger;
588 makeHitCountMap(tagger_sim_hits, hit_count_map_tagger);
589
590 // to keep track of how many sim particles leave hits on the scoring plane
591 std::vector<int> recoil_sh_idxs;
592 std::unordered_map<int, std::vector<int>> recoil_sh_count_map;
593
594 std::vector<int> tagger_sh_idxs;
595 std::unordered_map<int, std::vector<int>> tagger_sh_count_map;
596
597 // Target scoring hits for Tagger will have Z<0, Recoil scoring hits will
598 // have Z>0
599 for (unsigned int i_sh = 0; i_sh < scoring_hits.size(); i_sh++) {
600 const ldmx::SimTrackerHit& hit = scoring_hits.at(i_sh);
601 double zhit = hit.getPosition()[2];
602
603 Acts::Vector3 p_vec{hit.getMomentum()[0], hit.getMomentum()[1],
604 hit.getMomentum()[2]};
605 double tagger_p_max = 0.;
606
607 // Check if it is a tagger track going fwd that passes basic cuts
608 if (zhit < 0.) {
609 // Tagger selection cuts
610 // Negative scoring plane hit, with momentum > p_cut
611 if (p_vec(2) < 0. || p_vec.norm() < p_cut_) continue;
612
613 // Check that the hit was left by a charged particle
614 if (abs(particle_map[hit.getTrackID()].getCharge()) < 1e-8) continue;
615
616 if (p_vec.norm() > tagger_p_max) {
617 tagger_sh_count_map[hit.getTrackID()].push_back(i_sh);
618 }
619 } // Tagger loop
620
621 // Check the recoil hits
622 else {
623 // Recoil selection cuts
624 // Positive scoring plane hit, forward direction with momentum > p_cut
625 if (p_vec(2) < 0. || p_vec.norm() < p_cut_) continue;
626
627 // Check that the hit was left by a charged particle
628 if (abs(particle_map[hit.getTrackID()].getCharge()) < 1e-8) continue;
629
630 recoil_sh_count_map[hit.getTrackID()].push_back(i_sh);
631
632 } // Recoil
633 } // loop on Target scoring plane hits
634
635 for (std::pair<int, std::vector<int>> element : recoil_sh_count_map) {
636 std::sort(
637 element.second.begin(), element.second.end(),
638 [&](const int idx1, int idx2) -> bool {
639 const ldmx::SimTrackerHit& hit1 = scoring_hits.at(idx1);
640 const ldmx::SimTrackerHit& hit2 = scoring_hits.at(idx2);
641
642 Acts::Vector3 phit1{hit1.getMomentum()[0], hit1.getMomentum()[1],
643 hit1.getMomentum()[2]};
644 Acts::Vector3 phit2{hit2.getMomentum()[0], hit2.getMomentum()[1],
645 hit2.getMomentum()[2]};
646
647 return phit1.norm() > phit2.norm();
648 });
649 }
650
651 // Sort tagger hits.
652 for (auto& [_track_id, hit_indices] : tagger_sh_count_map) {
653 std::sort(
654 hit_indices.begin(), hit_indices.end(),
655 [&](const int idx1, int idx2) -> bool {
656 const ldmx::SimTrackerHit& hit1 = scoring_hits.at(idx1);
657 const ldmx::SimTrackerHit& hit2 = scoring_hits.at(idx2);
658
659 Acts::Vector3 phit1{hit1.getMomentum()[0], hit1.getMomentum()[1],
660 hit1.getMomentum()[2]};
661 Acts::Vector3 phit2{hit2.getMomentum()[0], hit2.getMomentum()[1],
662 hit2.getMomentum()[2]};
663
664 return phit1.norm() > phit2.norm();
665 });
666 }
667
668 // Building of the event truth information and the truth seeds
669 // TODO remove the truthtracks in the future as the truth seeds are enough
670
671 std::vector<ldmx::Track> tagger_truth_tracks;
672 std::vector<ldmx::Track> tagger_truth_seeds;
673 std::vector<ldmx::Track> recoil_truth_tracks;
674 std::vector<ldmx::Track> recoil_truth_seeds;
675 std::vector<ldmx::Track> beam_electrons;
676
677 // TODO:: The target should be taken from some conditions DB in the future.
678 // Define the perigee_surface at 0.0.0
679 auto target_surface{Acts::Surface::makeShared<Acts::PerigeeSurface>(
680 Acts::Vector3(0., 0., 0.))};
681
682 // Define the target_surface
683 auto target_unbound_surface = tracking::sim::utils::unboundSurface(0.);
684
685 // ecal
686 auto ecal_surface = tracking::sim::utils::unboundSurface(240.5);
687
688 auto beam_origin_surface{Acts::Surface::makeShared<Acts::PerigeeSurface>(
689 Acts::Vector3(beam_origin_[0], beam_origin_[1], beam_origin_[2]))};
690
691 if (!skip_tagger_) {
692 for (const auto& [track_id, hit_indices] : tagger_sh_count_map) {
693 const ldmx::SimTrackerHit& hit = scoring_hits.at(hit_indices.at(0));
694 const ldmx::SimParticle& phit = particle_map[hit.getTrackID()];
695
696 if (hit_count_map_tagger[hit.getTrackID()].size() > n_min_hits_tagger_) {
697 ldmx::Track truth_tagger_track;
698 createTruthTrack(phit, hit, truth_tagger_track, target_surface);
699 truth_tagger_track.setNhits(
700 hit_count_map_tagger[hit.getTrackID()].size());
701 // Add AtTarget state from the scoring plane hit (pos in mm, mom in MeV,
702 // both already in LDMX global frame)
703 ldmx::Track::TrackState ts_target;
704 ts_target.pos_ = {hit.getPosition()[0], hit.getPosition()[1],
705 hit.getPosition()[2]};
706 ts_target.mom_ = {hit.getMomentum()[0], hit.getMomentum()[1],
707 hit.getMomentum()[2]};
708 ts_target.ts_type_ = ldmx::AtTarget;
709 truth_tagger_track.addTrackState(ts_target);
710 tagger_truth_tracks.push_back(truth_tagger_track);
711
712 if (hit.getPdgID() == 11 && hit.getTrackID() < max_track_id_) {
713 ldmx::Track beam_e_truth_seed =
714 taggerFullSeed(particle_map[hit.getTrackID()], hit.getTrackID(),
715 hit, hit_count_map_tagger, beam_origin_surface,
716 target_unbound_surface);
717 beam_electrons.push_back(beam_e_truth_seed);
718 }
719 }
720 }
721 }
722
723 // Recover the EcalScoring hits
724 const auto& ecal_sp_hits = event.getCollection<ldmx::SimTrackerHit>(
725 ecal_sp_coll_name_, sp_pass_name_);
726 // Select ECAL hits
727 std::vector<ldmx::SimTrackerHit> sel_ecal_sp_hits;
728
729 for (auto sp_hit : ecal_sp_hits) {
730 if (sp_hit.getMomentum()[2] > 0 && ((sp_hit.getID() & 0xfff) == 31)) {
731 sel_ecal_sp_hits.push_back(sp_hit);
732 }
733 }
734
735 // Recoil target surface for truth and seed tracks is the target
736
737 for (std::pair<int, std::vector<int>> element : recoil_sh_count_map) {
738 // Only take the first entry of the vector: it should be the scoring plane
739 // hit with the highest momentum.
740 const ldmx::SimTrackerHit& hit = scoring_hits.at(element.second.at(0));
741 const ldmx::SimParticle& phit = particle_map[hit.getTrackID()];
742 ldmx::SimTrackerHit ecal_hit;
743
744 bool found_ecal_hit = false;
745 for (auto ecal_sp_hit : sel_ecal_sp_hits) {
746 if (ecal_sp_hit.getTrackID() == hit.getTrackID()) {
747 ecal_hit = ecal_sp_hit;
748 found_ecal_hit = true;
749 break;
750 }
751 }
752
753 // Findable particle selection
754 // ldmx_log(trace) << "!!! n_recoil_sim_hits found: " <<
755 // hit_count_map_recoil[hit.getTrackID()].size();
756 if (hit_count_map_recoil[hit.getTrackID()].size() > n_min_hits_recoil_ &&
757 found_ecal_hit && !skip_recoil_) {
758 ldmx::Track truth_recoil_track;
759 createTruthTrack(phit, hit, truth_recoil_track, target_surface);
760 truth_recoil_track.setTrackID(hit.getTrackID());
761
762 // AtTarget state from target scoring plane hit (pos mm, mom MeV, LDMX
763 // frame)
764 ldmx::Track::TrackState ts_target;
765 ts_target.pos_ = {hit.getPosition()[0], hit.getPosition()[1],
766 hit.getPosition()[2]};
767 ts_target.mom_ = {hit.getMomentum()[0], hit.getMomentum()[1],
768 hit.getMomentum()[2]};
769 ts_target.ts_type_ = ldmx::AtTarget;
770 truth_recoil_track.addTrackState(ts_target);
771
772 // Express truth ECAL state in the bound parametrization of ecal_surface
773 // (same surface definition used by CKFProcessor).
774 {
775 Acts::Vector3 ep{ecal_hit.getPosition()[0], ecal_hit.getPosition()[1],
776 ecal_hit.getPosition()[2]};
777 Acts::Vector3 em{ecal_hit.getMomentum()[0], ecal_hit.getMomentum()[1],
778 ecal_hit.getMomentum()[2]};
779 ep = tracking::sim::utils::ldmx2Acts(ep);
780 em = tracking::sim::utils::ldmx2Acts(em);
781 // Linearly extrapolate transverse coordinates to ACTS x = 240.5 mm
782 // (= LDMX z = 240.5 mm), correcting for the track slope over the small
783 // z-offset between the scoring plane and the ECAL surface.
784 if (std::abs(em[0]) > 0) {
785 double delta = 240.5 - ep[0];
786 ep[1] += delta * em[1] / em[0];
787 ep[2] += delta * em[2] / em[0];
788 ep[0] = 240.5;
789 }
790 double q_ecal = phit.getCharge() * Acts::UnitConstants::e;
791 auto ecal_free = tracking::sim::utils::toFreeParameters(ep, em, q_ecal);
792 auto ecal_bound = Acts::transformFreeToBoundParameters(
793 ecal_free, *ecal_surface, geometryContext());
794 if (ecal_bound.ok()) {
795 auto part{Acts::ParticleHypothesis(
796 Acts::PdgParticle(particle_hypothesis_))};
797 Acts::BoundTrackParameters ecal_pars(ecal_surface, ecal_bound.value(),
798 Acts::BoundMatrix::Identity(),
799 part);
800 truth_recoil_track.addTrackState(tracking::sim::utils::makeTrackState(
801 geometryContext(), ecal_pars, ldmx::AtECAL));
802 }
803 }
804
805 // Attach sim hit indices
806 int nhits = 0;
807 for (auto sim_hit_idx : hit_count_map_recoil.at(hit.getTrackID())) {
808 truth_recoil_track.addMeasurementIndex(sim_hit_idx);
809 nhits++;
810 }
811 truth_recoil_track.setNhits(nhits);
812
813 recoil_truth_tracks.push_back(truth_recoil_track);
814 }
815 }
816
817 /*
818 for (std::pair<int,std::vector<int>> element : recoil_sh_count_map) {
819
820 const ldmx::SimTrackerHit& hit = scoring_hits.at(element.second.at(0));
821 const ldmx::SimParticle& phit = particleMap[hit.getTrackID()];
822
823 if (hit_count_map_recoil[hit.getTrackID()].size() > n_min_hits_recoil_) {
824 ldmx::Track truth_recoil_track;
825 createTruthTrack(phit,hit,truth_recoil_track,targetSurface);
826 truth_recoil_track.setNhits(hit_count_map_recoil[hit.getTrackID()].size());
827 recoil_truth_tracks.push_back(truth_recoil_track);
828 }
829 }
830 */
831
832 // Form a truth seed from a truth track
833
834 for (auto& tt : tagger_truth_tracks) {
835 ldmx::Track seed = seedFromTruth(tt, seed_smearing_);
836
837 tagger_truth_seeds.push_back(seed);
838 }
839
840 ldmx_log(debug) << "Forming seeds from truth";
841 for (auto& tt : recoil_truth_tracks) {
842 ldmx_log(debug) << "Smearing truth track";
843
844 ldmx::Track seed = seedFromTruth(tt, seed_smearing_);
845
846 recoil_truth_seeds.push_back(seed);
847 }
848
849 // even if skip_tagger/recoil_ is true, still make the collections in the
850 // event
851 event.add(beam_electrons_collection_, beam_electrons);
852 event.add(tagger_truth_collection_, tagger_truth_tracks);
853 event.add(recoil_truth_collection_, recoil_truth_tracks);
854 event.add(tagger_seeds_collection_, tagger_truth_seeds);
855 event.add(recoil_seeds_collection_, recoil_truth_seeds);
856}
Class representing a simulated particle.
Definition SimParticle.h:24
Represents a simulated tracker hit in the simulation.
Implementation of a track object.
Definition Track.h:53
void makeHitCountMap(const std::vector< ldmx::SimTrackerHit > &sim_hits, std::map< int, std::vector< int > > &hit_count_map)
Create a mapping from the selected scoring plane hit objects to the number of hits they associated pa...
ldmx::Track taggerFullSeed(const ldmx::SimParticle &beam_electron, const int trackID, const ldmx::SimTrackerHit &hit, const std::map< int, std::vector< int > > &hit_count_map, const std::shared_ptr< Acts::Surface > &origin_surface, const std::shared_ptr< Acts::Surface > &target_surface)
This method retrieves the beam electron and forms a full seed The seed parameters are the truth param...
ldmx::Track seedFromTruth(const ldmx::Track &tt, bool seed_smearing)
Create a track seed from a truth track applying a smearing to the truth parameters as well as an infl...

References ldmx::SimTrackerHit::getMomentum(), ldmx::SimTrackerHit::getPosition(), ldmx::SimTrackerHit::getTrackID(), input_pass_name_, makeHitCountMap(), p_cut_, recoil_sim_hits_coll_name_, scoring_hits_coll_name_, and tagger_sim_hits_coll_name_.

◆ recoilFullSeed()

ldmx::Track tracking::reco::TruthSeedProcessor::recoilFullSeed ( const ldmx::SimParticle & particle,
const int trackID,
const ldmx::SimTrackerHit & hit,
const ldmx::SimTrackerHit & ecal_hit,
const std::map< int, std::vector< int > > & hit_count_map,
const std::shared_ptr< Acts::Surface > & origin_surface,
const std::shared_ptr< Acts::Surface > & target_surface,
const std::shared_ptr< Acts::Surface > & ecal_surface )
private

Definition at line 218 of file TruthSeedProcessor.cxx.

224 {
225 ldmx::Track truth_recoil_track;
226 createTruthTrack(particle, hit, truth_recoil_track, origin_surface);
227 truth_recoil_track.setTrackID(trackID);
228
229 // Seed at the target location
230 ldmx::Track smeared_truth_track = seedFromTruth(truth_recoil_track, false);
231
232 // Add truth track state at the target: use scoring plane hit (already LDMX
233 // frame)
234 ldmx::Track::TrackState ts_truth_target;
235 ts_truth_target.pos_ = {hit.getPosition()[0], hit.getPosition()[1],
236 hit.getPosition()[2]};
237 ts_truth_target.mom_ = {hit.getMomentum()[0], hit.getMomentum()[1],
238 hit.getMomentum()[2]};
239 ts_truth_target.ts_type_ = ldmx::AtTarget;
240 smeared_truth_track.addTrackState(ts_truth_target);
241
242 // Express truth ECAL state in the bound parametrization of ecal_surface
243 // (same surface definition used by CKFProcessor) rather than storing raw
244 // scoring plane hit coordinates.
245 {
246 Acts::Vector3 ep{ecal_hit.getPosition()[0], ecal_hit.getPosition()[1],
247 ecal_hit.getPosition()[2]};
248 Acts::Vector3 em{ecal_hit.getMomentum()[0], ecal_hit.getMomentum()[1],
249 ecal_hit.getMomentum()[2]};
250 ep = tracking::sim::utils::ldmx2Acts(ep);
251 em = tracking::sim::utils::ldmx2Acts(em);
252 // Linearly extrapolate transverse coordinates to ACTS x = 240.5 mm
253 // (= LDMX z = 240.5 mm), correcting for the track slope over the small
254 // z-offset between the scoring plane and the ECAL surface.
255 if (std::abs(em[0]) > 0) {
256 double delta = 240.5 - ep[0];
257 ep[1] += delta * em[1] / em[0];
258 ep[2] += delta * em[2] / em[0];
259 ep[0] = 240.5;
260 }
261 double q_ecal = particle.getCharge() * Acts::UnitConstants::e;
262 auto ecal_free = tracking::sim::utils::toFreeParameters(ep, em, q_ecal);
263 auto ecal_bound = Acts::transformFreeToBoundParameters(
264 ecal_free, *ecal_surface, geometryContext());
265 if (ecal_bound.ok()) {
266 auto part{
267 Acts::ParticleHypothesis(Acts::PdgParticle(particle_hypothesis_))};
268 Acts::BoundTrackParameters ecal_pars(ecal_surface, ecal_bound.value(),
269 Acts::BoundMatrix::Identity(), part);
270 smeared_truth_track.addTrackState(tracking::sim::utils::makeTrackState(
271 geometryContext(), ecal_pars, ldmx::AtECAL));
272 }
273 }
274
275 // Add the hits
276 int nhits = 0;
277
278 for (auto sim_hit_idx : hit_count_map.at(smeared_truth_track.getTrackID())) {
279 smeared_truth_track.addMeasurementIndex(sim_hit_idx);
280 nhits += 1;
281 }
282
283 smeared_truth_track.setNhits(nhits);
284
285 return smeared_truth_track;
286}

◆ scoringPlaneHitFilter()

bool tracking::reco::TruthSeedProcessor::scoringPlaneHitFilter ( const ldmx::SimTrackerHit & hit,
const std::vector< ldmx::SimTrackerHit > & ecal_sp_hits )
private

Filter that checks if a scoring plane passes specified momentum cuts as well as if the associated SimParticle hits the ECal.

Parameters
hitThe target scoring plane hit to check.
ecal_sp_hitsThe ECal scoring plane hit used to check if the associated particle hits the ECal.

Definition at line 501 of file TruthSeedProcessor.cxx.

503 {
504 // Clean some of the hits we don't want
505 if (hit.getPosition()[2] < z_min_) return false;
506
507 // Check if the track_id was requested
508 if (track_id_ > 0 && hit.getTrackID() != track_id_) return false;
509
510 // Check if we are requesting particular particles
511 if (std::find(pdg_ids_.begin(), pdg_ids_.end(), hit.getPdgID()) ==
512 pdg_ids_.end())
513 return false;
514
515 Acts::Vector3 p_vec{hit.getMomentum()[0], hit.getMomentum()[1],
516 hit.getMomentum()[2]};
517
518 // p cut
519 if (p_cut_ >= 0. && p_vec.norm() < p_cut_) return false;
520
521 // p cut Max
522 if (p_cut_ < 100000. && p_vec.norm() > p_cut_max_) return false;
523
524 // pz cut
525 if (pz_cut_ > -9999 && p_vec(2) < pz_cut_) return false;
526
527 // Check the ecal scoring plane
528 bool pass_ecal_scoring_plane = true;
529
530 if (p_cut_ecal_ > 0) { // only check if we care about it.
531
532 for (auto& e_sp_hit : ecal_sp_hits) {
533 if (e_sp_hit.getTrackID() == hit.getTrackID() &&
534 e_sp_hit.getPdgID() == hit.getPdgID()) {
535 Acts::Vector3 e_sp_p{e_sp_hit.getMomentum()[0],
536 e_sp_hit.getMomentum()[1],
537 e_sp_hit.getMomentum()[2]};
538
539 if (e_sp_p.norm() < p_cut_ecal_) pass_ecal_scoring_plane = false;
540
541 // Skip the rest of the scoring plane hits since we already found the
542 // track we care about
543 break;
544
545 } // check that the hit belongs to the inital particle from the target
546 // scoring plane hit
547 } // loop on Ecal scoring plane hits
548 } // pcutEcal
549
550 if (!pass_ecal_scoring_plane) return false;
551
552 return true;
553}

References ldmx::SimTrackerHit::getMomentum(), ldmx::SimTrackerHit::getPdgID(), ldmx::SimTrackerHit::getPosition(), ldmx::SimTrackerHit::getTrackID(), p_cut_, p_cut_max_, pdg_ids_, pz_cut_, track_id_, and z_min_.

◆ seedFromTruth()

ldmx::Track tracking::reco::TruthSeedProcessor::seedFromTruth ( const ldmx::Track & tt,
bool seed_smearing )
private

Create a track seed from a truth track applying a smearing to the truth parameters as well as an inflation to the covariance matrix.

Parameters
ttTruthTrack to be used to form a seed
Returns
seed The seed track

Definition at line 353 of file TruthSeedProcessor.cxx.

354 {
355 ldmx::Track seed = ldmx::Track();
356 seed.setPerigeeLocation(tt.getPerigeeLocation()[0],
357 tt.getPerigeeLocation()[1],
358 tt.getPerigeeLocation()[2]);
359 seed.setChi2(0.);
360 seed.setNhits(tt.getNhits());
361 seed.setNdf(0);
362 seed.setNsharedHits(0);
363 seed.setTrackID(tt.getTrackID());
364 seed.setPdgID(tt.getPdgID());
365 seed.setTruthProb(1.);
366
367 Acts::BoundVector bound_params;
368 Acts::BoundVector stddev;
369
370 if (seed_smearing) {
371 ldmx_log(debug) << "Smear track and inflate covariance";
372
373 /*
374 double sigma_d0 = rel_smearfactors_[Acts::eBoundLoc0] * tt.getD0();
375 double sigma_z0 = rel_smearfactors_[Acts::eBoundLoc1] * tt.getZ0();
376 double sigma_phi = rel_smearfactors_[Acts::eBoundPhi] * tt.getPhi();
377 double sigma_theta = rel_smearfactors_[Acts::eBoundTheta] *
378 tt.getTheta(); double sigma_p = rel_smearfactors_[Acts::eBoundQOverP]
379 * abs(1/tt.getQoP()); double sigma_t =
380 rel_smearfactors_[Acts::eBoundTime] * tt.getT();
381 */
382
383 double sigma_d0 = d0smear_[0];
384 double sigma_z0 = z0smear_[0];
385 double sigma_phi = phismear_;
386 double sigma_theta = thetasmear_;
387 double sigma_p = relpsmear_ * abs(1 / tt.getQoP());
388 double sigma_t = 1. * Acts::UnitConstants::ns;
389
390 double smear = (*normal_)(generator_);
391 double d0smear = tt.getD0() + smear * sigma_d0;
392
393 smear = (*normal_)(generator_);
394 double z0smear = tt.getZ0() + smear * sigma_z0;
395
396 smear = (*normal_)(generator_);
397 double phismear = tt.getPhi() + smear * sigma_phi;
398
399 smear = (*normal_)(generator_);
400 double thetasmear = tt.getTheta() + smear * sigma_theta;
401
402 double p = std::abs(1. / tt.getQoP());
403 smear = (*normal_)(generator_);
404 double psmear = p + smear * sigma_p;
405
406 double q = tt.getQoP() < 0 ? -1. : 1.;
407 double qo_psmear = q / psmear;
408
409 smear = (*normal_)(generator_);
410 double tsmear = tt.getT() + smear * sigma_t;
411
412 bound_params << d0smear, z0smear, phismear, thetasmear, qo_psmear, tsmear;
413
414 stddev[Acts::eBoundLoc0] =
415 inflate_factors_[Acts::eBoundLoc0] * sigma_d0 * Acts::UnitConstants::mm;
416 stddev[Acts::eBoundLoc1] =
417 inflate_factors_[Acts::eBoundLoc1] * sigma_z0 * Acts::UnitConstants::mm;
418 stddev[Acts::eBoundPhi] = inflate_factors_[Acts::eBoundPhi] * sigma_phi;
419 stddev[Acts::eBoundTheta] =
420 inflate_factors_[Acts::eBoundTheta] * sigma_theta;
421 stddev[Acts::eBoundQOverP] =
422 inflate_factors_[Acts::eBoundQOverP] * (1. / p) * (1. / p) * sigma_p;
423 stddev[Acts::eBoundTime] =
424 inflate_factors_[Acts::eBoundTime] * sigma_t * Acts::UnitConstants::ns;
425
426 ldmx_log(debug) << stddev;
427
428 std::vector<double> v_seed_params(
429 (bound_params).data(),
430 bound_params.data() + bound_params.rows() * bound_params.cols());
431
432 Acts::BoundMatrix bound_cov = stddev.cwiseProduct(stddev).asDiagonal();
433 std::vector<double> v_seed_cov;
434 tracking::sim::utils::flatCov(bound_cov, v_seed_cov);
435 seed.setPerigeeParameters(v_seed_params);
436 seed.setPerigeeCov(v_seed_cov);
437
438 } else {
439 // Do not smear the seed
440
441 bound_params << tt.getD0(), tt.getZ0(), tt.getPhi(), tt.getTheta(),
442 tt.getQoP(), tt.getT();
443
444 std::vector<double> v_seed_params(
445 (bound_params).data(),
446 bound_params.data() + bound_params.rows() * bound_params.cols());
447
448 double p = std::abs(1. / tt.getQoP());
449 double sigma_p = 0.75 * p * Acts::UnitConstants::GeV;
450 stddev[Acts::eBoundLoc0] = 2 * Acts::UnitConstants::mm;
451 stddev[Acts::eBoundLoc1] = 5 * Acts::UnitConstants::mm;
452 stddev[Acts::eBoundTime] = 1000 * Acts::UnitConstants::ns;
453 stddev[Acts::eBoundPhi] = 5 * Acts::UnitConstants::degree;
454 stddev[Acts::eBoundTheta] = 5 * Acts::UnitConstants::degree;
455 stddev[Acts::eBoundQOverP] = (1. / p) * (1. / p) * sigma_p;
456
457 Acts::BoundMatrix bound_cov = stddev.cwiseProduct(stddev).asDiagonal();
458 std::vector<double> v_seed_cov;
459 tracking::sim::utils::flatCov(bound_cov, v_seed_cov);
460 seed.setPerigeeParameters(v_seed_params);
461 seed.setPerigeeCov(v_seed_cov);
462 }
463
464 return seed;
465}

Referenced by taggerFullSeed().

◆ taggerFullSeed()

ldmx::Track tracking::reco::TruthSeedProcessor::taggerFullSeed ( const ldmx::SimParticle & beam_electron,
const int trackID,
const ldmx::SimTrackerHit & hit,
const std::map< int, std::vector< int > > & hit_count_map,
const std::shared_ptr< Acts::Surface > & origin_surface,
const std::shared_ptr< Acts::Surface > & target_surface )
private

This method retrieves the beam electron and forms a full seed The seed parameters are the truth parameters from the beam electron stored at the beam origin Additionally, the foolowing track states are stored ts_smeared : the truth smeared perigee state at the beam origin ts_truth_target : the truth on-surface state at the target Linear extrapolations are done from the origin of the particle to the reference surfaces This track also contains the list of hits belonging to the beam electron on the sensitive surfaces on the tagger tracker, for acceptance studies.

Parameters
beam_electron: the beam electron particle
hit: the scoring hit at the target from the beam electron particle survived
hit_count_map: the sim hit on track map
origin_surface: where to express the track origin parameters. Can be perigee, plane...
target_surface: the target surface for the truth target state

Definition at line 288 of file TruthSeedProcessor.cxx.

293 {
294 ldmx::Track truth_track;
295
296 createTruthTrack(beam_electron, truth_track, origin_surface);
297 truth_track.setTrackID(trackID);
298
299 // Smeared track at the beam origin
300 ldmx::Track smeared_truth_track = seedFromTruth(truth_track, true);
301
302 ldmx_log(debug) << "Truth parameters at beam origin";
303 for (auto par : truth_track.getPerigeeParameters())
304 ldmx_log(debug) << par << " ";
305 ldmx_log(debug);
306
307 // Add the truth track state at the target using the scoring plane hit
308 // (position and momentum are already in LDMX global frame)
309 ldmx::Track::TrackState ts_truth_target;
310 ts_truth_target.pos_ = {hit.getPosition()[0], hit.getPosition()[1],
311 hit.getPosition()[2]};
312 ts_truth_target.mom_ = {hit.getMomentum()[0], hit.getMomentum()[1],
313 hit.getMomentum()[2]};
314 ts_truth_target.ts_type_ = ldmx::AtTarget;
315 smeared_truth_track.addTrackState(ts_truth_target);
316
317 ldmx_log(debug) << "Truth position at target: " << hit.getPosition()[0] << " "
318 << hit.getPosition()[1] << " " << hit.getPosition()[2];
319
320 // Add the truth track state at the beam origin using particle vertex/momentum
321 // (SimParticle vertex and momentum are in LDMX global frame)
322 ldmx::Track::TrackState ts_truth_beam_origin;
323 ts_truth_beam_origin.pos_ = {beam_electron.getVertex()[0],
324 beam_electron.getVertex()[1],
325 beam_electron.getVertex()[2]};
326 ts_truth_beam_origin.mom_ = {beam_electron.getMomentum()[0],
327 beam_electron.getMomentum()[1],
328 beam_electron.getMomentum()[2]};
329 ts_truth_beam_origin.ts_type_ = ldmx::AtBeamOrigin;
330 smeared_truth_track.addTrackState(ts_truth_beam_origin);
331
332 ldmx_log(debug) << "Smeared parameters at origin";
333 for (auto par : smeared_truth_track.getPerigeeParameters())
334 ldmx_log(debug) << par << " ";
335
336 // assign the sim hit indices
337 // TODO this is not fully correct as the sim hits
338 // might be duplicated on sensors
339 // and should be merged if that is the case
340
341 int nhits = 0;
342
343 for (auto sim_hit_idx : hit_count_map.at(smeared_truth_track.getTrackID())) {
344 smeared_truth_track.addMeasurementIndex(sim_hit_idx);
345 nhits += 1;
346 }
347
348 smeared_truth_track.setNhits(nhits);
349
350 return smeared_truth_track;
351}

References createTruthTrack(), ldmx::SimParticle::getMomentum(), ldmx::SimTrackerHit::getMomentum(), ldmx::SimTrackerHit::getPosition(), ldmx::SimParticle::getVertex(), and seedFromTruth().

Member Data Documentation

◆ beam_electrons_collection_

std::string tracking::reco::TruthSeedProcessor::beam_electrons_collection_
private

Definition at line 286 of file TruthSeedProcessor.h.

◆ beam_origin_

std::vector<double> tracking::reco::TruthSeedProcessor::beam_origin_ {-880.1, -44., 0.}
private

Definition at line 283 of file TruthSeedProcessor.h.

283{-880.1, -44., 0.};

◆ d0smear_

std::vector<double> tracking::reco::TruthSeedProcessor::d0smear_
private

Definition at line 276 of file TruthSeedProcessor.h.

◆ ecal_sp_coll_name_

std::string tracking::reco::TruthSeedProcessor::ecal_sp_coll_name_ {"EcalScoringPlaneHits"}
private

Definition at line 197 of file TruthSeedProcessor.h.

197{"EcalScoringPlaneHits"};

◆ field_map_

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

Path to the magnetic field map.

Definition at line 267 of file TruthSeedProcessor.h.

267{""};

Referenced by configure(), and onNewRun().

◆ generator_

std::default_random_engine tracking::reco::TruthSeedProcessor::generator_
private

Definition at line 271 of file TruthSeedProcessor.h.

◆ inflate_factors_

std::vector<double> tracking::reco::TruthSeedProcessor::inflate_factors_
private

Definition at line 282 of file TruthSeedProcessor.h.

◆ input_pass_name_

std::string tracking::reco::TruthSeedProcessor::input_pass_name_ {""}
private

Pass name for the sim hit collections.

Definition at line 207 of file TruthSeedProcessor.h.

207{""};

Referenced by configure(), and produce().

◆ max_track_id_

int tracking::reco::TruthSeedProcessor::max_track_id_ {5}
private

Definition at line 258 of file TruthSeedProcessor.h.

258{5};

◆ n_min_hits_recoil_

int tracking::reco::TruthSeedProcessor::n_min_hits_recoil_ {7}
private

Minimum number of hits left in the recoil tracker to consider the seed as findable.

Definition at line 222 of file TruthSeedProcessor.h.

222{7};

Referenced by configure().

◆ n_min_hits_tagger_

int tracking::reco::TruthSeedProcessor::n_min_hits_tagger_ {7}
private

Minimum number of hits left in the recoil tracker to consider the seed as findable.

Definition at line 216 of file TruthSeedProcessor.h.

216{7};

Referenced by configure().

◆ normal_

std::shared_ptr<std::normal_distribution<float> > tracking::reco::TruthSeedProcessor::normal_
private

Definition at line 272 of file TruthSeedProcessor.h.

◆ p_cut_

double tracking::reco::TruthSeedProcessor::p_cut_ {0.}
private

Ask for a minimum p for the seeds.

Definition at line 237 of file TruthSeedProcessor.h.

237{0.};

Referenced by configure(), produce(), and scoringPlaneHitFilter().

◆ p_cut_ecal_

double tracking::reco::TruthSeedProcessor::p_cut_ecal_ {-1.}
private

Definition at line 243 of file TruthSeedProcessor.h.

243{-1.};

◆ p_cut_max_

double tracking::reco::TruthSeedProcessor::p_cut_max_ {100000.}
private

Ask for a maximum p for the seeds.

Definition at line 240 of file TruthSeedProcessor.h.

240{100000.};

Referenced by configure(), and scoringPlaneHitFilter().

◆ particle_hypothesis_

int tracking::reco::TruthSeedProcessor::particle_hypothesis_
private

Definition at line 284 of file TruthSeedProcessor.h.

◆ pdg_ids_

std::vector<int> tracking::reco::TruthSeedProcessor::pdg_ids_ {11}
private

pdg_ids of the particles we want to select for the seeds

Definition at line 193 of file TruthSeedProcessor.h.

193{11};

Referenced by configure(), and scoringPlaneHitFilter().

◆ phismear_

double tracking::reco::TruthSeedProcessor::phismear_
private

Definition at line 278 of file TruthSeedProcessor.h.

◆ propagator_

std::unique_ptr<const TruthPropagator> tracking::reco::TruthSeedProcessor::propagator_
private

Definition at line 260 of file TruthSeedProcessor.h.

◆ pz_cut_

double tracking::reco::TruthSeedProcessor::pz_cut_ {-9999}
private

Ask for a minimum pz for the seeds.

Definition at line 234 of file TruthSeedProcessor.h.

234{-9999};

Referenced by configure(), and scoringPlaneHitFilter().

◆ recoil_seeds_collection_

std::string tracking::reco::TruthSeedProcessor::recoil_seeds_collection_
private

Definition at line 290 of file TruthSeedProcessor.h.

◆ recoil_sim_hits_coll_name_

std::string tracking::reco::TruthSeedProcessor::recoil_sim_hits_coll_name_ {"RecoilSimHits"}
private

Sim hits to check if the truth seed is findable.

Definition at line 204 of file TruthSeedProcessor.h.

204{"RecoilSimHits"};

Referenced by configure(), and produce().

◆ recoil_sp_

bool tracking::reco::TruthSeedProcessor::recoil_sp_ {true}
private

Definition at line 246 of file TruthSeedProcessor.h.

246{true};

◆ recoil_truth_collection_

std::string tracking::reco::TruthSeedProcessor::recoil_truth_collection_
private

Definition at line 288 of file TruthSeedProcessor.h.

◆ rel_smearfactors_

std::vector<double> tracking::reco::TruthSeedProcessor::rel_smearfactors_
private

Definition at line 281 of file TruthSeedProcessor.h.

◆ relpsmear_

double tracking::reco::TruthSeedProcessor::relpsmear_
private

Definition at line 280 of file TruthSeedProcessor.h.

◆ scoring_hits_coll_name_

std::string tracking::reco::TruthSeedProcessor::scoring_hits_coll_name_ {"TargetScoringPlaneHits"}
private

Which scoring plane hits to use for the truth seeds generation.

Definition at line 196 of file TruthSeedProcessor.h.

196{"TargetScoringPlaneHits"};

Referenced by configure(), and produce().

◆ seed_smearing_

bool tracking::reco::TruthSeedProcessor::seed_smearing_ {false}
private

Definition at line 274 of file TruthSeedProcessor.h.

274{false};

◆ sim_particles_coll_name_

std::string tracking::reco::TruthSeedProcessor::sim_particles_coll_name_
private

Definition at line 209 of file TruthSeedProcessor.h.

◆ sim_particles_passname_

std::string tracking::reco::TruthSeedProcessor::sim_particles_passname_
private

Definition at line 210 of file TruthSeedProcessor.h.

◆ skip_recoil_

bool tracking::reco::TruthSeedProcessor::skip_recoil_ {false}
private

Definition at line 255 of file TruthSeedProcessor.h.

255{false};

◆ skip_tagger_

bool tracking::reco::TruthSeedProcessor::skip_tagger_ {false}
private

Definition at line 252 of file TruthSeedProcessor.h.

252{false};

◆ sp_pass_name_

std::string tracking::reco::TruthSeedProcessor::sp_pass_name_ {""}
private

Definition at line 198 of file TruthSeedProcessor.h.

198{""};

◆ tagger_seeds_collection_

std::string tracking::reco::TruthSeedProcessor::tagger_seeds_collection_
private

Definition at line 289 of file TruthSeedProcessor.h.

◆ tagger_sim_hits_coll_name_

std::string tracking::reco::TruthSeedProcessor::tagger_sim_hits_coll_name_ {"TaggerSimHits"}
private

Sim hits to check if the truth seed is findable.

Definition at line 201 of file TruthSeedProcessor.h.

201{"TaggerSimHits"};

Referenced by configure(), and produce().

◆ tagger_truth_collection_

std::string tracking::reco::TruthSeedProcessor::tagger_truth_collection_
private

Definition at line 287 of file TruthSeedProcessor.h.

◆ target_sp_

bool tracking::reco::TruthSeedProcessor::target_sp_ {true}
private

Definition at line 249 of file TruthSeedProcessor.h.

249{true};

◆ thetasmear_

double tracking::reco::TruthSeedProcessor::thetasmear_
private

Definition at line 279 of file TruthSeedProcessor.h.

◆ track_id_

int tracking::reco::TruthSeedProcessor::track_id_ {-999}
private

Only select a particular trackID.

Definition at line 231 of file TruthSeedProcessor.h.

231{-999};

Referenced by configure(), and scoringPlaneHitFilter().

◆ trk_extrap_

std::shared_ptr<tracking::reco::TrackExtrapolatorTool<TruthPropagator> > tracking::reco::TruthSeedProcessor::trk_extrap_
private

Definition at line 264 of file TruthSeedProcessor.h.

◆ z0smear_

std::vector<double> tracking::reco::TruthSeedProcessor::z0smear_
private

Definition at line 277 of file TruthSeedProcessor.h.

◆ z_min_

float tracking::reco::TruthSeedProcessor::z_min_ {-999}
private

Min cut on the z_ of the scoring hit.

It could be used to clean the scoring hits if desired.

Definition at line 228 of file TruthSeedProcessor.h.

228{-999};

Referenced by configure(), and scoringPlaneHitFilter().


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