LDMX Software
ecal::EcalTrackFinderProcessor Class Reference

Uses ACTS framework to fit tracks through ECAL hits with zero B-field. More...

#include <EcalTrackFinderProcessor.h>

Public Member Functions

 EcalTrackFinderProcessor (const std::string &name, framework::Process &process)
 Constructor.
 
virtual ~EcalTrackFinderProcessor ()=default
 Destructor.
 
void configure (framework::config::Parameters &parameters) override
 Configure the processor.
 
void onNewRun (const ldmx::RunHeader &) override
 Initialize ACTS tracking objects once the detector geometry is known.
 
void produce (framework::Event &event) override
 Process event to find ECAL tracks.
 
void onProcessEnd () override
 Print statistics.
 
- 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 onProcessStart ()
 Callback for the EventProcessor to take any necessary action when the processing of events starts, such as creating histograms.
 
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 Types

using EcalPropagator
 
using TrackContainer
 

Private Member Functions

std::vector< ldmx::MeasurementcreateMeasurements (const std::vector< ldmx::EcalHit > &hits, std::vector< double > &energies)
 Create ACTS measurement objects from ECAL hits.
 
void createEcalSurfaces ()
 Create unbounded plane surfaces at each ECAL layer.
 
std::vector< ldmx::TrackfindSeeds (const std::vector< ldmx::Measurement > &measurements)
 Find seed tracks via straight-line fitting.
 
std::tuple< Acts::Vector3, Acts::Vector3, double > fitStraightLine (const std::vector< Acts::Vector3 > &points)
 Fit straight line through 3D points Returns: (position, direction, RMS residual)
 
std::unordered_multimap< Acts::GeometryIdentifier, acts_examples::IndexSourceLinkmakeGeoIdSourceLinkMap (const std::vector< ldmx::Measurement > &measurements)
 Create geometry ID to source link map for CKF.
 

Private Attributes

std::unique_ptr< const EcalPropagator > propagator_
 
std::unique_ptr< const Acts::CombinatorialKalmanFilter< EcalPropagator, TrackContainer > > ckf_
 
std::map< int, std::shared_ptr< Acts::Surface > > layer_surfaces_
 
std::map< int, Acts::GeometryIdentifier > layer_geo_ids_
 
std::shared_ptr< Acts::Surface > reference_surface_
 
std::shared_ptr< const Acts::TrackingGeometry > tracking_geometry_
 
Acts::RotationMatrix3 surf_rotation_
 
std::string rec_coll_name_ {"EcalRecHits"}
 
std::string rec_pass_name_ {""}
 
std::string out_track_collection_ {"EcalTracks"}
 
int min_hits_ {3}
 
double max_chi2_ {10.0}
 
double cell_resolution_ {1.5}
 
bool debug_ {false}
 
double max_seed_rms_ {10.0}
 
double min_momentum_ {50.0}
 
double max_momentum_ {10000.0}
 
bool use_roc_energy_ {true}
 
std::string roc_file_name_
 
std::vector< std::vector< float > > roc_range_values_
 
const ldmx::EcalGeometrygeometry_ {nullptr}
 
int nevents_ {0}
 
int ntracks_ {0}
 
int nseeds_ {0}
 
double processing_time_ {0.0}
 

Additional Inherited Members

- 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

Uses ACTS framework to fit tracks through ECAL hits with zero B-field.

This processor:

  1. Converts ECAL RecHits to ldmx::Measurement objects
  2. Creates unbounded plane surfaces at each ECAL layer
  3. Finds straight-line seed tracks through hits
  4. Runs ACTS Combinatorial Kalman Filter with zero magnetic field
  5. Outputs fitted ldmx::Track objects

Definition at line 58 of file EcalTrackFinderProcessor.h.

Member Typedef Documentation

◆ EcalPropagator

using ecal::EcalTrackFinderProcessor::EcalPropagator
private
Initial value:
Acts::Propagator<Acts::EigenStepper<>, Acts::Navigator>

Definition at line 124 of file EcalTrackFinderProcessor.h.

◆ TrackContainer

using ecal::EcalTrackFinderProcessor::TrackContainer
private
Initial value:
Acts::TrackContainer<Acts::VectorTrackContainer,
Acts::VectorMultiTrajectory>

Definition at line 126 of file EcalTrackFinderProcessor.h.

Constructor & Destructor Documentation

◆ EcalTrackFinderProcessor()

ecal::EcalTrackFinderProcessor::EcalTrackFinderProcessor ( const std::string & name,
framework::Process & process )

Constructor.

Definition at line 45 of file EcalTrackFinderProcessor.cxx.

47 : Producer(name, process) {
48 // Setup surface rotation: u=+Y, v=+Z, w=+X (beam direction)
49 surf_rotation_ = Acts::RotationMatrix3::Zero();
50 surf_rotation_(1, 0) = 1; // u along Y
51 surf_rotation_(2, 1) = 1; // v along Z
52 surf_rotation_(0, 2) = 1; // w along X (beam/normal)
53}
Producer(const std::string &name, Process &process)
Class constructor.
virtual void process(Event &event) final
Processing an event for a Producer is calling produce.

Member Function Documentation

◆ configure()

void ecal::EcalTrackFinderProcessor::configure ( framework::config::Parameters & parameters)
overridevirtual

Configure the processor.

Reimplemented from framework::EventProcessor.

Definition at line 55 of file EcalTrackFinderProcessor.cxx.

56 {
57 rec_coll_name_ = parameters.get<std::string>("rec_coll_name");
58 rec_pass_name_ = parameters.get<std::string>("rec_pass_name");
59 out_track_collection_ = parameters.get<std::string>("out_track_collection");
60
61 min_hits_ = parameters.get<int>("min_hits");
62 max_chi2_ = parameters.get<double>("max_chi2");
63 cell_resolution_ = parameters.get<double>("cell_resolution");
64 debug_ = parameters.get<bool>("debug");
65
66 max_seed_rms_ = parameters.get<double>("max_seed_rms");
67 min_momentum_ = parameters.get<double>("min_momentum");
68 max_momentum_ = parameters.get<double>("max_momentum");
69
70 use_roc_energy_ = parameters.get<bool>("use_roc_energy");
71 if (use_roc_energy_) {
72 roc_file_name_ = parameters.get<std::string>("roc_file");
73 std::ifstream rocfile(roc_file_name_);
74 if (!rocfile.good()) {
75 EXCEPTION_RAISE("EcalTrackFinderProcessor",
76 "ROC file '" + roc_file_name_ + "' does not exist!");
77 }
78 std::string line, value;
79 // Skip header line
80 std::getline(rocfile, line);
81 while (std::getline(rocfile, line)) {
82 std::stringstream ss(line);
83 std::vector<float> values;
84 while (std::getline(ss, value, ',')) {
85 values.push_back(value.empty() ? -1.0f : std::stof(value));
86 }
87 roc_range_values_.push_back(values);
88 }
89 ldmx_log(info) << "Loaded ROC file with " << roc_range_values_.size()
90 << " bins";
91 }
92}
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:78

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

◆ createEcalSurfaces()

void ecal::EcalTrackFinderProcessor::createEcalSurfaces ( )
private

Create unbounded plane surfaces at each ECAL layer.

Definition at line 222 of file EcalTrackFinderProcessor.cxx.

222 {
223 int n_layers = geometry_->getNumLayers();
224
225 for (int layer = 0; layer < n_layers; ++layer) {
226 // Get z position of this layer
227 double z_pos = geometry_->getZPosition(layer);
228
229 // Create plane surface at this z position
230 // Position in ACTS frame (x=z_ldmx, y=x_ldmx, z=y_ldmx)
231 Acts::Vector3 acts_pos =
232 tracking::sim::utils::ldmx2Acts(Acts::Vector3(0.0, 0.0, z_pos));
233
234 Acts::Translation3 translation(acts_pos);
235 Acts::Transform3 transform(translation * surf_rotation_);
236
237 // Create bounded plane surface (500mm x 500mm, covers full ECAL)
238 auto bounds = std::make_shared<Acts::RectangleBounds>(500.0, 500.0);
239 auto surface =
240 Acts::Surface::makeShared<Acts::PlaneSurface>(transform, bounds);
241
242 // Assign a geometry ID (use layer as volume, 0 as layer in ACTS sense)
243 Acts::GeometryIdentifier geo_id;
244 geo_id.setVolume(layer);
245 geo_id.setLayer(0);
246 surface->assignGeometryId(geo_id);
247
248 layer_surfaces_[layer] = surface;
249 }
250
251 // Create reference surface at ECAL front face
252 double ecal_front_z = geometry_->getEcalFrontZ();
253 Acts::Vector3 ref_pos =
254 tracking::sim::utils::ldmx2Acts(Acts::Vector3(0.0, 0.0, ecal_front_z));
255 Acts::Translation3 ref_translation(ref_pos);
256 Acts::Transform3 ref_transform(ref_translation * surf_rotation_);
257 reference_surface_ =
258 Acts::Surface::makeShared<Acts::PlaneSurface>(ref_transform);
259}
double getEcalFrontZ() const
Get the z-coordinate of the Ecal face.
int getNumLayers() const
Get the number of layers in the Ecal Geometry.
double getZPosition(int layer) const
Get the z-coordinate given the layer id.

References ldmx::EcalGeometry::getEcalFrontZ(), ldmx::EcalGeometry::getNumLayers(), and ldmx::EcalGeometry::getZPosition().

Referenced by onNewRun().

◆ createMeasurements()

std::vector< ldmx::Measurement > ecal::EcalTrackFinderProcessor::createMeasurements ( const std::vector< ldmx::EcalHit > & hits,
std::vector< double > & energies )
private

Create ACTS measurement objects from ECAL hits.

Definition at line 261 of file EcalTrackFinderProcessor.cxx.

262 {
263 std::vector<ldmx::Measurement> measurements;
264 measurements.reserve(hits.size());
265 energies.clear();
266 energies.reserve(hits.size());
267
268 for (const auto& hit : hits) {
269 // Skip noise hits
270 if (hit.isNoise()) continue;
271
272 // Get EcalID
273 ldmx::EcalID ecal_id(hit.getID());
274 int layer = ecal_id.layer();
275
276 // Get position from geometry
277 auto [x, y, z] = geometry_->getPosition(ecal_id);
278
279 // Create measurement
281 meas.setGlobalPosition(x, y, z);
282 meas.setLayerID(layer);
283 meas.setTime(hit.getTime());
284
285 // Local coordinates: use x, y as local u, v in the layer plane
286 meas.setLocalPosition(x, y);
287
288 // Covariance: use cell resolution
289 double cov = cell_resolution_ * cell_resolution_;
290 meas.setLocalCovariance(cov, cov);
291
292 measurements.push_back(meas);
293 energies.push_back(hit.getEnergy());
294 }
295
296 return measurements;
297}
std::tuple< double, double, double > getPosition(EcalID id) const
Get a cell's position from its ID number.
Extension of DetectorID providing access to ECal layers and cell numbers in a hex grid.
Definition EcalID.h:20
void setLocalPosition(const float &meas_u, const float &meas_v)
Set the local position i.e.
Definition Measurement.h:60
void setLayerID(const int &layer_id)
Set the layer ID of the sensor where this measurement took place.
void setGlobalPosition(const float &meas_x, const float &meas_y, const float &meas_z)
Set the global position i.e.
Definition Measurement.h:41
void setLocalCovariance(const float &cov_uu, const float &cov_vv)
Set cov(U,U) and cov(V, V).
Definition Measurement.h:76
void setTime(const float &meas_t)
Set the measurement time in ns.
Definition Measurement.h:92

References ldmx::EcalGeometry::getPosition(), ldmx::EcalID::layer(), ldmx::Measurement::setGlobalPosition(), ldmx::Measurement::setLayerID(), ldmx::Measurement::setLocalCovariance(), ldmx::Measurement::setLocalPosition(), and ldmx::Measurement::setTime().

Referenced by produce().

◆ findSeeds()

std::vector< ldmx::Track > ecal::EcalTrackFinderProcessor::findSeeds ( const std::vector< ldmx::Measurement > & measurements)
private

Find seed tracks via straight-line fitting.

Definition at line 344 of file EcalTrackFinderProcessor.cxx.

345 {
346 std::vector<ldmx::Track> seeds;
347
348 if (measurements.size() < static_cast<size_t>(min_hits_)) {
349 ldmx_log(debug) << "Too few measurements for seed: " << measurements.size()
350 << " < " << min_hits_;
351 return seeds;
352 }
353
354 // Group measurements by layer
355 std::map<int, std::vector<const ldmx::Measurement*>> layer_map;
356 for (const auto& meas : measurements) {
357 layer_map[meas.getLayerID()].push_back(&meas);
358 }
359
360 ldmx_log(debug) << "Measurements span " << layer_map.size() << " layers";
361
362 // Simple strategy: use all hits for a single seed (can be extended later)
363 std::vector<Acts::Vector3> points;
364 std::vector<ldmx::Measurement> seed_measurements;
365
366 for (const auto& [layer, meas_vec] : layer_map) {
367 // For now, just take first hit in each layer
368 if (!meas_vec.empty()) {
369 const auto* meas = meas_vec[0];
370 auto gpos = meas->getGlobalPosition();
371
372 // Convert to ACTS frame
373 Acts::Vector3 pos_acts = tracking::sim::utils::ldmx2Acts(
374 Acts::Vector3(gpos[0], gpos[1], gpos[2]));
375 points.push_back(pos_acts);
376 seed_measurements.push_back(*meas);
377 }
378 }
379
380 if (points.size() < static_cast<size_t>(min_hits_)) {
381 ldmx_log(debug) << "Too few layers hit for seed: " << points.size() << " < "
382 << min_hits_;
383 return seeds;
384 }
385
386 // Fit straight line
387 auto [position, direction, rms] = fitStraightLine(points);
388
389 ldmx_log(debug) << "Seed line fit: rms=" << rms << " dir=(" << direction.x()
390 << "," << direction.y() << "," << direction.z() << ")";
391
392 if (rms > max_seed_rms_) {
393 ldmx_log(debug) << "Seed RMS too large: " << rms << " > " << max_seed_rms_
394 << " mm";
395 return seeds;
396 }
397
398 // Create seed track at reference surface (ECAL front)
399 // Intersect line with reference surface
402 .get();
403
404 // For a plane surface, normal is the third column of rotation (z-direction in
405 // local frame)
406 Acts::Vector3 ref_normal =
407 reference_surface_->transform(gctx).rotation().col(2);
408 Acts::Vector3 ref_center = reference_surface_->center(gctx);
409
410 double t =
411 (ref_center - position).dot(ref_normal) / direction.dot(ref_normal);
412 Acts::Vector3 seed_pos = position + t * direction;
413
414 // Estimate momentum (assume MIP ~200 MeV for now)
415 double p_estimate = 200.0; // MeV
416 Acts::Vector3 seed_mom = p_estimate * direction;
417
418 // Charge (assume positive)
419 Acts::ActsScalar q = Acts::UnitConstants::e;
420
421 // Convert to bound parameters at reference surface
422 Acts::FreeVector seed_free =
423 tracking::sim::utils::toFreeParameters(seed_pos, seed_mom, q);
424
425 auto bound_params_result = Acts::transformFreeToBoundParameters(
426 seed_free, *reference_surface_, gctx);
427
428 if (!bound_params_result.ok()) {
429 ldmx_log(warn) << "Failed to create bound parameters for seed";
430 return seeds;
431 }
432
433 Acts::BoundVector bound_params = bound_params_result.value();
434
435 // Create inflated covariance
436 Acts::BoundVector stddev;
437 stddev[Acts::eBoundLoc0] = 10.0 * Acts::UnitConstants::mm;
438 stddev[Acts::eBoundLoc1] = 10.0 * Acts::UnitConstants::mm;
439 stddev[Acts::eBoundPhi] = 0.1 * Acts::UnitConstants::rad;
440 stddev[Acts::eBoundTheta] = 0.1 * Acts::UnitConstants::rad;
441 stddev[Acts::eBoundQOverP] = 0.5 / p_estimate; // 50% uncertainty
442 stddev[Acts::eBoundTime] = 10.0 * Acts::UnitConstants::ns;
443
444 Acts::BoundSquareMatrix bound_cov = stddev.cwiseProduct(stddev).asDiagonal();
445
446 // Create ldmx::Track seed
447 ldmx::Track seed;
448
449 // Convert reference surface position to LDMX frame
450 Acts::Vector3 ref_ldmx = tracking::sim::utils::acts2Ldmx(ref_center);
451 seed.setPerigeeLocation(ref_ldmx[0], ref_ldmx[1], ref_ldmx[2]);
452
453 seed.setChi2(0.0);
454 seed.setNhits(seed_measurements.size());
455 seed.setNdf(0);
456 seed.setNsharedHits(0);
457 seed.setCharge(q > 0 ? 1 : -1);
458
459 // Convert to std::vector for storage
460 std::vector<double> v_seed_params(bound_params.data(),
461 bound_params.data() + bound_params.size());
462 std::vector<double> v_seed_cov;
463 tracking::sim::utils::flatCov(bound_cov, v_seed_cov);
464
465 seed.setPerigeeParameters(v_seed_params);
466 seed.setPerigeeCov(v_seed_cov);
467
468 seeds.push_back(seed);
469 return seeds;
470}
std::tuple< Acts::Vector3, Acts::Vector3, double > fitStraightLine(const std::vector< Acts::Vector3 > &points)
Fit straight line through 3D points Returns: (position, direction, RMS residual)
const T & getCondition(const std::string &condition_name)
Access a conditions object for the current event.
Implementation of a track object.
Definition Track.h:53
static const std::string NAME
Conditions object name.

References fitStraightLine(), framework::EventProcessor::getCondition(), and tracking::geo::GeometryContext::NAME.

Referenced by produce().

◆ fitStraightLine()

std::tuple< Acts::Vector3, Acts::Vector3, double > ecal::EcalTrackFinderProcessor::fitStraightLine ( const std::vector< Acts::Vector3 > & points)
private

Fit straight line through 3D points Returns: (position, direction, RMS residual)

Definition at line 300 of file EcalTrackFinderProcessor.cxx.

301 {
302 if (points.size() < 2) {
303 return {Acts::Vector3::Zero(), Acts::Vector3::Zero(), 1e6};
304 }
305
306 // Calculate centroid
307 Acts::Vector3 centroid = Acts::Vector3::Zero();
308 for (const auto& p : points) {
309 centroid += p;
310 }
311 centroid /= points.size();
312
313 // Build covariance matrix
314 Eigen::Matrix3d cov = Eigen::Matrix3d::Zero();
315 for (const auto& p : points) {
316 Acts::Vector3 dp = p - centroid;
317 cov += dp * dp.transpose();
318 }
319 cov /= points.size();
320
321 // Find principal direction (eigenvector with largest eigenvalue)
322 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> solver(cov);
323 Acts::Vector3 direction = solver.eigenvectors().col(2); // Largest eigenvalue
324 direction.normalize();
325
326 // Eigenvector has sign ambiguity — ensure it points forward along the beam.
327 // In ACTS coords, beam direction is +X (LDMX Z -> ACTS X).
328 if (direction.x() < 0) {
329 direction = -direction;
330 }
331
332 // Calculate RMS residual
333 double rms = 0.0;
334 for (const auto& p : points) {
335 Acts::Vector3 dp = p - centroid;
336 double residual = (dp - (dp.dot(direction)) * direction).norm();
337 rms += residual * residual;
338 }
339 rms = std::sqrt(rms / points.size());
340
341 return {centroid, direction, rms};
342}

Referenced by findSeeds().

◆ makeGeoIdSourceLinkMap()

std::unordered_multimap< Acts::GeometryIdentifier, acts_examples::IndexSourceLink > ecal::EcalTrackFinderProcessor::makeGeoIdSourceLinkMap ( const std::vector< ldmx::Measurement > & measurements)
private

Create geometry ID to source link map for CKF.

Definition at line 474 of file EcalTrackFinderProcessor.cxx.

475 {
476 std::unordered_multimap<Acts::GeometryIdentifier,
478 geo_id_sl_map;
479
480 for (size_t i = 0; i < measurements.size(); ++i) {
481 const auto& meas = measurements[i];
482 int layer = meas.getLayerID();
483
484 // Use the builder-assigned geometry ID for this layer (not the manually
485 // assigned one). This ensures the CKF Navigator's surface.geometryId()
486 // matches our source link map keys.
487 auto it = layer_geo_ids_.find(layer);
488 if (it == layer_geo_ids_.end()) {
489 ldmx_log(debug) << "No builder geometry ID for layer " << layer;
490 continue;
491 }
492
493 Acts::GeometryIdentifier geo_id = it->second;
494 acts_examples::IndexSourceLink idx_sl(geo_id, i);
495 geo_id_sl_map.insert(std::make_pair(geo_id, idx_sl));
496 }
497
498 ldmx_log(debug) << "Source link map has " << geo_id_sl_map.size()
499 << " entries from " << measurements.size() << " measurements";
500
501 return geo_id_sl_map;
502}

Referenced by produce().

◆ onNewRun()

void ecal::EcalTrackFinderProcessor::onNewRun ( const ldmx::RunHeader & )
overridevirtual

Initialize ACTS tracking objects once the detector geometry is known.

Reimplemented from framework::EventProcessor.

Definition at line 94 of file EcalTrackFinderProcessor.cxx.

94 {
95 // Geometry is available here: EcalGeometryProvider::onNewRun has already
96 // populated detector_geometry_ before processors receive onNewRun.
98 ldmx::EcalGeometry::CONDITIONS_OBJECT_NAME);
99
100 // Create ECAL layer surfaces
101 layer_surfaces_.clear();
103
104 // Setup zero magnetic field
105 Acts::Vector3 b_field(0., 0., 0.);
106 auto zero_b_field = std::make_shared<Acts::ConstantBField>(b_field);
107
108 // Build ACTS tracking geometry for the ECAL using CuboidVolumeBuilder
109 // Each ECAL layer becomes a sensitive layer in the tracking geometry
110
113 .get();
114
115 // Get ECAL extent in ACTS coordinates
116 double ecal_front_z = geometry_->getEcalFrontZ();
117 double ecal_back_z =
118 geometry_->getZPosition(geometry_->getNumLayers() - 1) + 50.0;
119 Acts::Vector3 front_acts =
120 tracking::sim::utils::ldmx2Acts(Acts::Vector3(0.0, 0.0, ecal_front_z));
121 Acts::Vector3 back_acts =
122 tracking::sim::utils::ldmx2Acts(Acts::Vector3(0.0, 0.0, ecal_back_z));
123
124 // Create layer configurations - one per ECAL layer
125 std::vector<Acts::CuboidVolumeBuilder::LayerConfig> layer_configs;
126 double clearance = 1.0; // mm envelope around each layer surface
127
128 for (auto& [layer, surface] : layer_surfaces_) {
129 Acts::CuboidVolumeBuilder::LayerConfig lcfg;
130 lcfg.surfaces = {surface};
131 lcfg.envelopeX = std::array<double, 2>{clearance, clearance};
132 lcfg.active = true;
133 layer_configs.push_back(lcfg);
134 }
135
136 // Volume config
137 Acts::Vector3 volume_center = 0.5 * (front_acts + back_acts);
138 double x_length = std::abs(back_acts.x() - front_acts.x()) + 20.0;
139
140 Acts::CuboidVolumeBuilder::VolumeConfig ecal_vol_cfg;
141 ecal_vol_cfg.position = volume_center;
142 ecal_vol_cfg.length = {x_length, 1000.0, 1000.0}; // generous transverse size
143 ecal_vol_cfg.name = "EcalVolume";
144 ecal_vol_cfg.layerCfg = layer_configs;
145 ecal_vol_cfg.volumeMaterial =
146 std::make_shared<Acts::HomogeneousVolumeMaterial>(Acts::Material());
147
148 // Build the tracking geometry
149 Acts::CuboidVolumeBuilder cvb;
150 Acts::CuboidVolumeBuilder::Config cvb_cfg;
151 cvb_cfg.position = volume_center;
152 cvb_cfg.length = {x_length + 20.0, 1020.0, 1020.0};
153 cvb_cfg.volumeCfg = {ecal_vol_cfg};
154 cvb.setConfig(cvb_cfg);
155
156 Acts::TrackingGeometryBuilder::Config tgb_cfg;
157 tgb_cfg.trackingVolumeBuilders.push_back(
158 [=](const auto& cxt, const auto& inner, const auto&) {
159 return cvb.trackingVolume(cxt, inner, nullptr);
160 });
161
162 Acts::TrackingGeometryBuilder tgb(tgb_cfg);
163 tracking_geometry_ = tgb.trackingGeometry(gctx);
164
165 // Extract the geometry IDs that the builder assigned to our surfaces.
166 // CuboidVolumeBuilder/TrackingGeometryBuilder reassign GeometryIdentifiers
167 // based on the volume/layer/sensitive hierarchy, overwriting our manual IDs.
168 // We must use these builder-assigned IDs when creating the source link map,
169 // because the CKF Navigator will see these IDs when it reaches a surface.
170 layer_geo_ids_.clear();
171 tracking_geometry_->visitSurfaces([&](const Acts::Surface* surface) {
172 if (!surface) return;
173 // Only care about sensitive surfaces (those with a sensitive ID)
174 if (surface->geometryId().sensitive() == 0) return;
175
176 // Match to ECAL layer by z position (LDMX frame)
177 Acts::Vector3 center_ldmx =
178 tracking::sim::utils::acts2Ldmx(surface->center(gctx));
179 double z_ldmx = center_ldmx[2];
180
181 for (int layer = 0; layer < geometry_->getNumLayers(); ++layer) {
182 double layer_z = geometry_->getZPosition(layer);
183 if (std::abs(z_ldmx - layer_z) < 0.1) { // 0.1 mm tolerance
184 layer_geo_ids_[layer] = surface->geometryId();
185 ldmx_log(debug) << "ECAL layer " << layer << " -> builder geo_id: vol="
186 << surface->geometryId().volume()
187 << " lay=" << surface->geometryId().layer()
188 << " sen=" << surface->geometryId().sensitive();
189 break;
190 }
191 }
192 });
193
194 ldmx_log(info) << "Mapped " << layer_geo_ids_.size()
195 << " ECAL layers to builder-assigned geometry IDs";
196
197 // Setup stepper with zero B-field
198 const auto stepper = Acts::EigenStepper<>{zero_b_field};
199
200 // Setup navigator with tracking geometry
201 Acts::Navigator::Config nav_cfg{tracking_geometry_};
202 nav_cfg.resolveSensitive = true;
203 nav_cfg.resolvePassive = false;
204 nav_cfg.resolveMaterial = false;
205 const Acts::Navigator navigator(nav_cfg);
206
207 // Create propagator
208 auto acts_logging_level =
209 debug_ ? Acts::Logging::VERBOSE : Acts::Logging::WARNING;
210 propagator_ = std::make_unique<EcalPropagator>(
211 stepper, navigator,
212 Acts::getDefaultLogger("ECAL_PROP", acts_logging_level));
213
214 // Create CKF
215 ckf_ = std::make_unique<std::decay_t<decltype(*ckf_)>>(
216 *propagator_, Acts::getDefaultLogger("ECAL_CKF", acts_logging_level));
217
218 ldmx_log(info) << "EcalTrackFinderProcessor initialized with "
219 << layer_surfaces_.size() << " ECAL layer surfaces";
220}
void createEcalSurfaces()
Create unbounded plane surfaces at each ECAL layer.

References createEcalSurfaces(), framework::EventProcessor::getCondition(), ldmx::EcalGeometry::getEcalFrontZ(), ldmx::EcalGeometry::getNumLayers(), ldmx::EcalGeometry::getZPosition(), and tracking::geo::GeometryContext::NAME.

◆ onProcessEnd()

void ecal::EcalTrackFinderProcessor::onProcessEnd ( )
overridevirtual

Print statistics.

Reimplemented from framework::EventProcessor.

Definition at line 870 of file EcalTrackFinderProcessor.cxx.

870 {
871 ldmx_log(info) << "EcalTrackFinderProcessor Statistics:";
872 ldmx_log(info) << " Events processed: " << nevents_;
873 ldmx_log(info) << " Total seeds: " << nseeds_;
874 ldmx_log(info) << " Total tracks: " << ntracks_;
875 ldmx_log(info) << " Avg tracks/event: "
876 << (nevents_ > 0 ? (double)ntracks_ / nevents_ : 0);
877 ldmx_log(info) << " Avg time/event: "
878 << (nevents_ > 0 ? processing_time_ / nevents_ : 0) << " ms";
879}

◆ produce()

void ecal::EcalTrackFinderProcessor::produce ( framework::Event & event)
overridevirtual

Process event to find ECAL tracks.

Implements framework::Producer.

Definition at line 504 of file EcalTrackFinderProcessor.cxx.

504 {
505 auto start = std::chrono::high_resolution_clock::now();
506 nevents_++;
507
508 std::vector<ldmx::Track> tracks;
509
510 // Get ECAL RecHits
511 if (!event.exists(rec_coll_name_, rec_pass_name_)) {
512 ldmx_log(debug) << "No ECAL RecHits collection found";
513 event.add(out_track_collection_, tracks);
514 return;
515 }
516
517 const std::vector<ldmx::EcalHit> ecal_hits =
518 event.getCollection<ldmx::EcalHit>(rec_coll_name_, rec_pass_name_);
519
520 ldmx_log(debug) << "Processing " << ecal_hits.size() << " ECAL hits";
521
522 // Convert hits to measurements (with parallel energy vector)
523 std::vector<double> measurement_energies;
524 auto measurements = createMeasurements(ecal_hits, measurement_energies);
525 ldmx_log(debug) << "Created " << measurements.size() << " measurements";
526
527 if (measurements.empty()) {
528 event.add(out_track_collection_, tracks);
529 return;
530 }
531
532 // Create source link map
533 auto geo_id_sl_map = makeGeoIdSourceLinkMap(measurements);
534 ldmx_log(debug) << "Source link map: " << geo_id_sl_map.size() << " entries";
535
536 // Find seed tracks
537 auto seed_tracks = findSeeds(measurements);
538 ldmx_log(info) << "Found " << seed_tracks.size() << " seed tracks";
539 nseeds_ += seed_tracks.size();
540
541 if (seed_tracks.empty()) {
542 event.add(out_track_collection_, tracks);
543 return;
544 }
545
546 // Get ACTS contexts
549 .get();
552 .get();
555 .get();
556
557 // Setup propagator options
558 Acts::PropagatorPlainOptions propagator_options(gctx, mctx);
559 propagator_options.pathLimit = std::numeric_limits<double>::max();
560 propagator_options.maxSteps = 1000;
561 propagator_options.stepping.maxStepSize = 100.0 * Acts::UnitConstants::mm;
562
563 // Setup CKF extensions
564 Acts::GainMatrixUpdater kf_updater;
565 Acts::MeasurementSelector::Config meas_sel_cfg = {
566 {Acts::GeometryIdentifier(), {{}, {max_chi2_}, {1u}}}};
567 Acts::MeasurementSelector meas_sel{meas_sel_cfg};
568
569 tracking::sim::LdmxMeasurementCalibrator calibrator{measurements};
570
571 Acts::CombinatorialKalmanFilterExtensions<TrackContainer> ckf_extensions;
572 ckf_extensions.calibrator
574 Acts::VectorMultiTrajectory>>(&calibrator);
575 ckf_extensions.updater.connect<
576 &Acts::GainMatrixUpdater::operator()<Acts::VectorMultiTrajectory>>(
577 &kf_updater);
578 ckf_extensions.measurementSelector
579 .connect<&Acts::MeasurementSelector::select<Acts::VectorMultiTrajectory>>(
580 &meas_sel);
581
582 // Setup source link accessor
583 struct SourceLinkAccIt {
584 using BaseIt = decltype(geo_id_sl_map.begin());
585 BaseIt it_;
586
587#pragma GCC diagnostic push
588#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
589
590 using difference_type = typename BaseIt::difference_type;
591 using iterator_category = std::input_iterator_tag;
592 using value_type = Acts::SourceLink;
593 using pointer = value_type*;
594 using reference = value_type&;
595#pragma GCC diagnostic pop
596
597 SourceLinkAccIt& operator++() {
598 ++it_;
599 return *this;
600 }
601 bool operator==(const SourceLinkAccIt& other) const {
602 return it_ == other.it_;
603 }
604 bool operator!=(const SourceLinkAccIt& other) const {
605 return !(*this == other);
606 }
607 value_type operator*() const { return value_type{it_->second}; }
608 };
609
610 auto source_link_accessor = [&](const Acts::Surface& surface)
611 -> std::pair<SourceLinkAccIt, SourceLinkAccIt> {
612 auto [begin, end] = geo_id_sl_map.equal_range(surface.geometryId());
613 return {SourceLinkAccIt{begin}, SourceLinkAccIt{end}};
614 };
615
616 Acts::SourceLinkAccessorDelegate<SourceLinkAccIt>
617 source_link_accessor_delegate;
618 source_link_accessor_delegate
619 .connect<&decltype(source_link_accessor)::operator(),
620 decltype(source_link_accessor)>(&source_link_accessor);
621
622 // Create track container
623 Acts::VectorTrackContainer vtc;
624 Acts::VectorMultiTrajectory mtj;
625 Acts::TrackContainer tc{vtc, mtj};
626
627 // Process each seed
628 for (size_t seed_idx = 0; seed_idx < seed_tracks.size(); ++seed_idx) {
629 const auto& seed = seed_tracks[seed_idx];
630
631 // Convert seed to BoundTrackParameters
632 // The seed was created with bound parameters on the reference PlaneSurface,
633 // so we must start the CKF from that same surface (NOT a PerigeeSurface,
634 // which interprets loc0/loc1 as d0/z0 instead of plane-local coordinates).
635 Acts::BoundVector param_vec;
636 param_vec << seed.getD0(), seed.getZ0(), seed.getPhi(), seed.getTheta(),
637 seed.getQoP(), seed.getT();
638
639 ldmx_log(debug) << "Seed " << seed_idx << ": loc0=" << param_vec[0]
640 << " loc1=" << param_vec[1] << " phi=" << param_vec[2]
641 << " theta=" << param_vec[3] << " qop=" << param_vec[4];
642
643 Acts::BoundSquareMatrix cov_mat =
644 tracking::sim::utils::unpackCov(seed.getPerigeeCov());
645
646 auto part_hypo{Acts::SinglyChargedParticleHypothesis::electron()};
647 Acts::BoundTrackParameters start_params(reference_surface_, param_vec,
648 cov_mat, part_hypo);
649
650 // Setup CKF options
651 const Acts::CombinatorialKalmanFilterOptions<SourceLinkAccIt,
652 TrackContainer>
653 ckf_options(gctx, mctx, cctx, source_link_accessor_delegate,
654 ckf_extensions, propagator_options);
655
656 // Run CKF
657 auto results = ckf_->findTracks(start_params, ckf_options, tc);
658
659 if (!results.ok()) {
660 ldmx_log(debug) << "CKF failed for seed " << seed_idx << ": "
661 << results.error().message();
662 continue;
663 }
664
665 auto& tracks_from_seed = results.value();
666 ldmx_log(debug) << "CKF returned " << tracks_from_seed.size()
667 << " tracks from seed " << seed_idx;
668 for (auto& track : tracks_from_seed) {
669 // Smooth the track
670 Acts::smoothTrack(gctx, track);
671
672 // Create output track
673 ldmx::Track trk;
674
675 // Get parameters from first smoothed state
676 // (setReferenceSurface doesn't actually transform params, need actual
677 // state)
678 Acts::BoundVector smoothed_params;
679 std::shared_ptr<const Acts::Surface> smoothed_surface;
680 bool found_smoothed = false;
681
682 for (const auto& ts : track.trackStatesReversed()) {
683 if (ts.hasSmoothed()) {
684 smoothed_params = ts.smoothed();
685 smoothed_surface = ts.referenceSurface().getSharedPtr();
686 found_smoothed = true;
687 break;
688 }
689 }
690
691 if (!found_smoothed) {
692 ldmx_log(warn) << "No smoothed track state found";
693 continue;
694 }
695
696 ldmx_log(debug) << "Smoothed params: loc0=" << smoothed_params[0]
697 << " loc1=" << smoothed_params[1]
698 << " phi=" << smoothed_params[2]
699 << " theta=" << smoothed_params[3]
700 << " qop=" << smoothed_params[4];
701
702 // Convert to free parameters (in ACTS global coords)
703 Acts::FreeVector free_params = Acts::transformBoundToFreeParameters(
704 *smoothed_surface, gctx, smoothed_params);
705
706 // Convert ACTS position and momentum to LDMX coordinates
707 Acts::Vector3 pos_acts(free_params[Acts::eFreePos0],
708 free_params[Acts::eFreePos1],
709 free_params[Acts::eFreePos2]);
710 Acts::Vector3 mom_acts(free_params[Acts::eFreeDir0],
711 free_params[Acts::eFreeDir1],
712 free_params[Acts::eFreeDir2]);
713
714 Acts::Vector3 pos_ldmx = tracking::sim::utils::acts2Ldmx(pos_acts);
715 Acts::Vector3 mom_ldmx = tracking::sim::utils::acts2Ldmx(mom_acts);
716
717 double x = pos_ldmx[0];
718 double y = pos_ldmx[1];
719 double z = pos_ldmx[2];
720 double px = mom_ldmx[0];
721 double py = mom_ldmx[1];
722 double pz = mom_ldmx[2];
723
724 ldmx_log(debug) << "LDMX momentum: px=" << px << " py=" << py
725 << " pz=" << pz;
726
727 // Compute theta and phi same way as SP electron (atan2(pt, pz))
728 double pt = std::sqrt(px * px + py * py);
729 double theta = std::atan2(pt, pz);
730 double phi = std::atan2(py, px);
731 if (phi < 0)
732 phi += 2.0 * M_PI; // Shift to [0, 2π] to avoid boundary artifacts
733 double qop = free_params[Acts::eFreeQOverP];
734
735 // Compute perigee parameters from smoothed track state position.
736 // PCA-based z0 is ill-defined for forward tracks (pz >> pt), so
737 // we just use the z of the smoothed state directly.
738 double d0 = -(x * std::sin(phi) - y * std::cos(phi));
739 double z0 = z;
740 double time = free_params[Acts::eFreeTime];
741
742 Acts::BoundVector perigee_params;
743 perigee_params << d0, z0, phi, theta, qop, time;
744
745 ldmx_log(debug) << "Perigee params: d0=" << d0 << " z0=" << z0
746 << " phi=" << phi << " theta=" << theta;
747
748 // Store perigee parameters
749 trk.setPerigeeParameters(
750 tracking::sim::utils::convertActsToLdmxPars(perigee_params));
751
752 // Covariance is always available for TrackProxy
753 std::vector<double> cov_vec;
754 tracking::sim::utils::flatCov(track.covariance(), cov_vec);
755 trk.setPerigeeCov(cov_vec);
756
757 Acts::Vector3 ref_loc_ldmx =
758 tracking::sim::utils::acts2Ldmx(reference_surface_->center(gctx));
759 trk.setPerigeeLocation(ref_loc_ldmx[0], ref_loc_ldmx[1], ref_loc_ldmx[2]);
760
761 trk.setChi2(track.chi2());
762 trk.setNhits(track.nMeasurements());
763 trk.setNdf(track.nMeasurements() - 5);
764 trk.setNsharedHits(0);
765 trk.setCharge(qop > 0 ? 1 : -1);
766
767 // Add measurement indices
768 for (const auto ts : track.trackStatesReversed()) {
769 if (ts.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag) &&
770 ts.hasUncalibratedSourceLink()) {
772 ts.getUncalibratedSourceLink()
773 .template get<acts_examples::IndexSourceLink>();
774 trk.addMeasurementIndex(sl.index());
775 }
776 }
777
778 // Compute track energy from RecHits
779 double track_energy = 0.0;
780
781 if (use_roc_energy_ && !roc_range_values_.empty()) {
782 // Use 68% containment cone: project track through each layer,
783 // sum energies of all RecHits within the ROC radius
784
785 // Track momentum magnitude and angle for ROC bin selection
786 double trk_p_mag = 1.0 / std::abs(smoothed_params[Acts::eBoundQOverP]);
787 double trk_theta_deg = theta * 180.0 / M_PI;
788
789 // Select ROC bin based on momentum and angle
790 std::vector<float> ele_radii(roc_range_values_[0].begin() + 4,
791 roc_range_values_[0].end());
792 for (const auto& row : roc_range_values_) {
793 float theta_min = row[0], theta_max = row[1];
794 float p_min = row[2], p_max = row[3];
795 bool inrange = true;
796 if (theta_min != -1.0f)
797 inrange = inrange && (trk_theta_deg >= theta_min);
798 if (theta_max != -1.0f)
799 inrange = inrange && (trk_theta_deg < theta_max);
800 if (p_min != -1.0f) inrange = inrange && (trk_p_mag >= p_min);
801 if (p_max != -1.0f) inrange = inrange && (trk_p_mag < p_max);
802 if (inrange) {
803 ele_radii.assign(row.begin() + 4, row.end());
804 }
805 }
806
807 // Project track through each ECAL layer (straight line in LDMX coords)
808 // Track at (x, y, z) with direction (px, py, pz) normalized
809 for (const auto& hit : ecal_hits) {
810 if (hit.isNoise()) continue;
811 ldmx::EcalID ecal_id(hit.getID());
812 int layer = ecal_id.layer();
813 if (layer < 0 || layer >= static_cast<int>(ele_radii.size()))
814 continue;
815
816 auto [hx, hy, hz] = geometry_->getPosition(ecal_id);
817
818 // Project track to this layer's z
819 double dz = hz - z;
820 double proj_x = x + (px / pz) * dz;
821 double proj_y = y + (py / pz) * dz;
822
823 // Distance from projected track to hit
824 double dx = hx - proj_x;
825 double dy = hy - proj_y;
826 double dist = std::sqrt(dx * dx + dy * dy);
827
828 if (dist < ele_radii[layer]) {
829 track_energy += hit.getEnergy();
830 }
831 }
832 } else {
833 // Fallback: sum on-track hit energies only
834 for (const auto ts : track.trackStatesReversed()) {
835 if (ts.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag) &&
836 ts.hasUncalibratedSourceLink()) {
838 ts.getUncalibratedSourceLink()
839 .template get<acts_examples::IndexSourceLink>();
840 track_energy += measurement_energies[sl.index()];
841 }
842 }
843 }
844
845 // Use energy as track momentum (E ≈ p for relativistic electrons)
846 double track_p = track_energy;
847 qop = (track_p > 0) ? -1.0 / track_p : 0.0;
848 perigee_params[Acts::eBoundQOverP] = qop;
849 trk.setPerigeeParameters(
850 tracking::sim::utils::convertActsToLdmxPars(perigee_params));
851
852 ldmx_log(debug) << "Track energy from RecHits: " << track_energy
853 << " MeV, q/p=" << qop;
854
855 tracks.push_back(trk);
856 ntracks_++;
857 }
858 }
859
860 ldmx_log(info) << "Found " << tracks.size() << " fitted tracks";
861
862 // Add to event
863 event.add(out_track_collection_, tracks);
864
865 auto end = std::chrono::high_resolution_clock::now();
866 auto diff = end - start;
867 processing_time_ += std::chrono::duration<double, std::milli>(diff).count();
868}
std::vector< ldmx::Measurement > createMeasurements(const std::vector< ldmx::EcalHit > &hits, std::vector< double > &energies)
Create ACTS measurement objects from ECAL hits.
std::unordered_multimap< Acts::GeometryIdentifier, acts_examples::IndexSourceLink > makeGeoIdSourceLinkMap(const std::vector< ldmx::Measurement > &measurements)
Create geometry ID to source link map for CKF.
std::vector< ldmx::Track > findSeeds(const std::vector< ldmx::Measurement > &measurements)
Find seed tracks via straight-line fitting.
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:105
Stores reconstructed hit information from the ECAL.
Definition EcalHit.h:19
static const std::string NAME
Conditions object name.
static const std::string NAME
Conditions object name.
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(), createMeasurements(), framework::Event::exists(), findSeeds(), framework::EventProcessor::getCondition(), ldmx::EcalGeometry::getPosition(), acts_examples::IndexSourceLink::index(), ldmx::EcalID::layer(), makeGeoIdSourceLinkMap(), tracking::geo::CalibrationContext::NAME, tracking::geo::GeometryContext::NAME, and tracking::geo::MagneticFieldContext::NAME.

Member Data Documentation

◆ cell_resolution_

double ecal::EcalTrackFinderProcessor::cell_resolution_ {1.5}
private

Definition at line 158 of file EcalTrackFinderProcessor.h.

158{1.5}; // ECAL cell resolution [mm]

◆ ckf_

std::unique_ptr< const Acts::CombinatorialKalmanFilter<EcalPropagator, TrackContainer> > ecal::EcalTrackFinderProcessor::ckf_
private

Definition at line 133 of file EcalTrackFinderProcessor.h.

◆ debug_

bool ecal::EcalTrackFinderProcessor::debug_ {false}
private

Definition at line 159 of file EcalTrackFinderProcessor.h.

159{false}; // ACTS debug logging

◆ geometry_

const ldmx::EcalGeometry* ecal::EcalTrackFinderProcessor::geometry_ {nullptr}
private

Definition at line 172 of file EcalTrackFinderProcessor.h.

172{nullptr};

◆ layer_geo_ids_

std::map<int, Acts::GeometryIdentifier> ecal::EcalTrackFinderProcessor::layer_geo_ids_
private

Definition at line 141 of file EcalTrackFinderProcessor.h.

◆ layer_surfaces_

std::map<int, std::shared_ptr<Acts::Surface> > ecal::EcalTrackFinderProcessor::layer_surfaces_
private

Definition at line 136 of file EcalTrackFinderProcessor.h.

◆ max_chi2_

double ecal::EcalTrackFinderProcessor::max_chi2_ {10.0}
private

Definition at line 157 of file EcalTrackFinderProcessor.h.

157{10.0}; // Outlier chi2 cut

◆ max_momentum_

double ecal::EcalTrackFinderProcessor::max_momentum_ {10000.0}
private

Definition at line 164 of file EcalTrackFinderProcessor.h.

164{10000.0}; // Max momentum estimate [MeV]

◆ max_seed_rms_

double ecal::EcalTrackFinderProcessor::max_seed_rms_ {10.0}
private

Definition at line 162 of file EcalTrackFinderProcessor.h.

162{10.0}; // Max RMS for seed fit [mm]

◆ min_hits_

int ecal::EcalTrackFinderProcessor::min_hits_ {3}
private

Definition at line 156 of file EcalTrackFinderProcessor.h.

156{3}; // Minimum hits per track

◆ min_momentum_

double ecal::EcalTrackFinderProcessor::min_momentum_ {50.0}
private

Definition at line 163 of file EcalTrackFinderProcessor.h.

163{50.0}; // Min momentum estimate [MeV]

◆ nevents_

int ecal::EcalTrackFinderProcessor::nevents_ {0}
private

Definition at line 175 of file EcalTrackFinderProcessor.h.

175{0};

◆ nseeds_

int ecal::EcalTrackFinderProcessor::nseeds_ {0}
private

Definition at line 177 of file EcalTrackFinderProcessor.h.

177{0};

◆ ntracks_

int ecal::EcalTrackFinderProcessor::ntracks_ {0}
private

Definition at line 176 of file EcalTrackFinderProcessor.h.

176{0};

◆ out_track_collection_

std::string ecal::EcalTrackFinderProcessor::out_track_collection_ {"EcalTracks"}
private

Definition at line 155 of file EcalTrackFinderProcessor.h.

155{"EcalTracks"};

◆ processing_time_

double ecal::EcalTrackFinderProcessor::processing_time_ {0.0}
private

Definition at line 178 of file EcalTrackFinderProcessor.h.

178{0.0};

◆ propagator_

std::unique_ptr<const EcalPropagator> ecal::EcalTrackFinderProcessor::propagator_
private

Definition at line 130 of file EcalTrackFinderProcessor.h.

◆ rec_coll_name_

std::string ecal::EcalTrackFinderProcessor::rec_coll_name_ {"EcalRecHits"}
private

Definition at line 153 of file EcalTrackFinderProcessor.h.

153{"EcalRecHits"};

◆ rec_pass_name_

std::string ecal::EcalTrackFinderProcessor::rec_pass_name_ {""}
private

Definition at line 154 of file EcalTrackFinderProcessor.h.

154{""};

◆ reference_surface_

std::shared_ptr<Acts::Surface> ecal::EcalTrackFinderProcessor::reference_surface_
private

Definition at line 144 of file EcalTrackFinderProcessor.h.

◆ roc_file_name_

std::string ecal::EcalTrackFinderProcessor::roc_file_name_
private

Definition at line 168 of file EcalTrackFinderProcessor.h.

◆ roc_range_values_

std::vector<std::vector<float> > ecal::EcalTrackFinderProcessor::roc_range_values_
private

Definition at line 169 of file EcalTrackFinderProcessor.h.

◆ surf_rotation_

Acts::RotationMatrix3 ecal::EcalTrackFinderProcessor::surf_rotation_
private

Definition at line 150 of file EcalTrackFinderProcessor.h.

◆ tracking_geometry_

std::shared_ptr<const Acts::TrackingGeometry> ecal::EcalTrackFinderProcessor::tracking_geometry_
private

Definition at line 147 of file EcalTrackFinderProcessor.h.

◆ use_roc_energy_

bool ecal::EcalTrackFinderProcessor::use_roc_energy_ {true}
private

Definition at line 167 of file EcalTrackFinderProcessor.h.

167{true}; // Use 68% containment cone for track energy

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