LDMX Software
trigscint::TrigScintTrackProducer Class Reference

making tracks from trigger scintillator clusters More...

#include <TrigScintTrackProducer.h>

Classes

struct  LUTKey
 
struct  LUTKeyHash
 

Public Member Functions

 TrigScintTrackProducer (const std::string &name, framework::Process &process)
 
void configure (framework::config::Parameters &ps) override
 Callback for the EventProcessor to configure itself from the given set of parameters.
 
void produce (framework::Event &event) override
 Process the event and put new data products into it.
 
void onProcessStart () override
 Callback for the EventProcessor to take any necessary action when the processing of events starts, such as creating histograms.
 
void onProcessEnd () override
 Callback for the EventProcessor to take any necessary action when the processing of events finishes, such as calculating job-summary quantities.
 
- 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 onNewRun (const ldmx::RunHeader &run_header)
 Callback for the EventProcessor to take any necessary action when the run being processed changes.
 
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.
 
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

ldmx::TrigScintTrack makeTrack (std::vector< ldmx::TrigScintCluster > clusters)
 
void matchXYTracks (std::vector< ldmx::TrigScintTrack > &tracks)
 

Private Attributes

std::vector< ldmx::TrigScintTrack > tracks_
 
double max_delta_ {0.}
 
double max_delta_vert_ {0.}
 
double bar_length_y_ {30.}
 
int verbose_ {0}
 
std::string seeding_collection_
 
std::vector< std::string > input_collections_
 
std::string output_collection_
 
std::string pass_name_ {""}
 
bool skip_last_ {false}
 
bool lut_tracking_ {false}
 
int vert_bar_start_idx_ {52}
 
int n_bars_y_ {16}
 
int n_bars_x_ {8}
 
std::unordered_set< LUTKey, LUTKeyHash > lut_
 
float bar_width_y_ {3.}
 
float bar_gap_y_ {2.1}
 
float bar_width_x_ {3.}
 
float bar_gap_x_ {0.1}
 
float x_conv_factor_
 
float x_start_
 
float y_conv_factor_
 
float y_start_
 

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
 
NtupleManager & ntuple_ {NtupleManager::getInstance()}
 Manager for any ntuples.
 
logging::logger the_log_
 The logger for this EventProcessor.
 

Detailed Description

making tracks from trigger scintillator clusters

Definition at line 20 of file TrigScintTrackProducer.h.

Constructor & Destructor Documentation

◆ TrigScintTrackProducer()

trigscint::TrigScintTrackProducer::TrigScintTrackProducer ( const std::string & name,
framework::Process & process )
inline

Definition at line 22 of file TrigScintTrackProducer.h.

23 : Producer(name, process) {}
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 trigscint::TrigScintTrackProducer::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.

For an example, look at MyProcessor.

Parameters
parametersParameters for configuration.

Reimplemented from framework::EventProcessor.

Definition at line 10 of file TrigScintTrackProducer.cxx.

10 {
11 max_delta_ = ps.get<double>(
12 "delta_max"); // max distance to consider adding in a cluster to track
13 max_delta_vert_ = ps.get<double>(
14 "delta_vert_max"); // max distance between pad 1/2 and 3 along the x axis
15 // to consider make a track using the vertical bars
16 seeding_collection_ = ps.get<std::string>(
17 "seeding_collection"); // probably tagger pad, "TriggerPadTagClusters"
18 input_collections_ = ps.get<std::vector<std::string>>(
19 "further_input_collections"); // {"TriggerPadUpClusters" ,
20 // "TriggerPadDnClusters" }
21 output_collection_ = ps.get<std::string>("output_collection");
22 pass_name_ = ps.get<std::string>("input_pass_name");
23 verbose_ = ps.get<int>("verbosity");
24 vert_bar_start_idx_ = ps.get<int>("vertical_bar_start_index");
25 n_bars_y_ = ps.get<int>("number_horizontal_bars");
26 bar_width_y_ = ps.get<double>("horizontal_bar_width");
27 bar_gap_y_ = ps.get<double>("horizontal_bar_gap");
28 n_bars_x_ = ps.get<int>("number_vertical_bars");
29 bar_width_x_ = ps.get<double>("vertical_bar_width");
30 bar_gap_x_ = ps.get<double>("vertical_bar_gap");
31 skip_last_ = ps.get<bool>("allow_skip_last_collection");
32 bar_length_y_ = ps.get<double>(
33 "horizontal_bar_length"); // bar length of the horizontal bars
34 lut_tracking_ = ps.get<bool>("lut_tracking");
35 std::string lut_file =
36 ps.get<std::string>("lut_file"); // from PatternLUTMaker
37
38 // TO DO: allow any number of input collections
39
40 if (verbose_) {
41 ldmx_log(info) << "In TrigScintTrackProducer: configure done!" << std::endl;
42 ldmx_log(info) << "Got parameters: \nSeeding: " << seeding_collection_
43 << "\nTolerance: " << max_delta_
44 << "\nInput: " << input_collections_.at(0) << " and "
45 << input_collections_.at(1)
46 << "\nInput pass name: " << pass_name_
47 << "\nAllow tracks with no hit in last collection: "
48 << skip_last_
49 << "\nUsing LUT Tracking Method: " << lut_tracking_
50 << "\nIf using LUT Method, LUT from: " << lut_file
51 << "\nVertical bar start index: " << vert_bar_start_idx_
52 << "\nNumber of horizontal bars: " << n_bars_y_
53 << "\nHorizontal bar width: " << bar_width_y_
54 << "\nHorizontal bar gap: " << bar_gap_y_
55 << "\nNumber of vertical bars: " << n_bars_x_
56 << "\nVertical bar width: " << bar_width_x_
57 << "\nVertical bar gap: " << bar_gap_x_
58 << "\nOutput: " << output_collection_
59 << "\nVerbosity: " << verbose_;
60 }
61 // each bar only goes half this distance up (overlap/zig-zag)
62 y_conv_factor_ = (bar_width_y_ + bar_gap_y_) / 2.;
63 // half height of pad
64 y_start_ = -(n_bars_y_ * (bar_width_y_ + bar_gap_y_) - bar_gap_y_) / 2.;
65 // each bar goes entire distance sideways (no overlap)
66 x_conv_factor_ = bar_width_x_ + bar_gap_x_;
67 // half width of pad
68 x_start_ = -(n_bars_x_ * (bar_width_x_ + bar_gap_x_) - bar_gap_x_) / 2.;
69
70 if (lut_tracking_) {
71 std::ifstream file(lut_file);
72 if (!file.good()) {
73 EXCEPTION_RAISE("TrigScintTrackProducer",
74 "LUT file '" + lut_file +
75 "' not found! Make sure it's in the directory from "
76 "which just is executed!");
77 }
78
79 float a, b, c;
80
81 while (file >> a >> b >> c) {
82 float p1 = a;
83 float p2 = b;
84 float p3 = c;
85 lut_.insert({p1, p2, p3});
86 }
87
88 ldmx_log(info) << "Loaded LUT with size: " << lut_.size();
89 }
90
91 return;
92}

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

◆ makeTrack()

ldmx::TrigScintTrack trigscint::TrigScintTrackProducer::makeTrack ( std::vector< ldmx::TrigScintCluster > clusters)
private

Definition at line 558 of file TrigScintTrackProducer.cxx.

559 {
560 // for now let's keep a straight, unweighted centroid
561 // consider the possibility that at least one cluster has a centroid
562 // identically == 0. then we need to shift them by 1 if we want to do energy
563 // weighted track centroid later. but no need now
565 float centroid = 0;
566 float centroid_x = 0;
567 float centroid_y = 0;
568 float beam_efrac = 0;
569 float pe = 0;
570 for (uint i = 0; i < clusters.size(); i++) {
571 centroid += (clusters.at(i)).getCentroid();
572 centroid_x += (clusters.at(i)).getCentroidX();
573 centroid_y += (clusters.at(i)).getCentroidY();
574 tr.addConstituent(clusters.at(i));
575 beam_efrac += (clusters.at(i)).getBeamEfrac();
576 pe += (clusters.at(i)).getPE();
577 }
578 centroid /= clusters.size();
579 centroid_x /= clusters.size();
580 if (centroid >= vert_bar_start_idx_) {
581 if (verbose_) {
582 ldmx_log(debug)
583 << " -- In makeTrack made vertical bar track with centroid "
584 << centroid << " and y flag sum " << centroid_y;
585 // try commenting this to check if that helps with an out-of-bounds
586 // problem
587 // << " from clusters with y centroids";
588 // for (uint i = 0; i < clusters.size(); i++)
589 // ldmx_log(debug) << "\tpad " << i << ": centroidY "
590 // << (clusters.at(i)).getCentroidY();
591 }
592 // then the sum of centroid y is 0, 2, 4 or 6
593 // we have 4 divisions, so, the center of it should be divNb/8
594 // (or rather, that's where channel nBars/8 begins)
595 // and then a factor 2 for the zig-zag pattern
596 centroid_y = (centroid_y + 1) * 2 * n_bars_y_ / 8.;
597 // TODO: here we could instead just use quadrant indices 0-3 by dividing by
598 // 2 but that would mean that in the raw, x and y track centroidY would mean
599 // different things
600 if (verbose_) ldmx_log(debug) << " -- new centroidY = " << centroid_y;
601 } else
602 centroid_y /= clusters.size();
603
604 beam_efrac /= clusters.size();
605 pe /= clusters.size();
606
607 float residual = 0;
608 for (uint i = 0; i < clusters.size(); i++)
609 residual += ((clusters.at(i)).getCentroid() - centroid) *
610 ((clusters.at(i)).getCentroid() - centroid);
611 residual = sqrt(residual / clusters.size());
612
613 float residual_x = 0; // only for the vertical bars
614 if (centroid >= vert_bar_start_idx_) {
615 for (uint i = 0; i < clusters.size(); i++)
616 residual_x += ((clusters.at(i)).getCentroidX() - centroid_x) *
617 ((clusters.at(i)).getCentroidX() - centroid_x);
618 residual_x = sqrt(residual_x / clusters.size());
619 }
620
621 tr.setResidualX(residual_x);
622 tr.setCentroid(centroid);
623 tr.setCentroidX(centroid_x);
624 tr.setCentroidY(centroid_y);
625 tr.setResidual(residual);
626 tr.setBeamEfrac(beam_efrac);
627 tr.setPE(pe);
628
629 if (verbose_) {
630 ldmx_log(debug) << " -- In makeTrack made track with centroid "
631 << centroid << " and residual " << residual << " and pe "
632 << pe << " from clusters with centroids";
633 for (uint i = 0; i < clusters.size(); i++)
634 ldmx_log(debug) << "\tpad " << i << ": centroid "
635 << (clusters.at(i)).getCentroid();
636 }
637
638 return tr;
639}
Represents a track of trigger scintillator clusters.
void setCentroidX(float centroid)
Set the x centroid of the track.
void setResidual(float resid)
Set the detector ID residual of the track.
void setCentroidY(float centroid)
Set the y centroid of the track.
void setPE(float pe)
Set the average cluster pe of the track.
void addConstituent(TrigScintCluster cl)
Add a cluster to the list of track constituents.
void setCentroid(float centroid)
Set the detector ID centroid of the track.
void setBeamEfrac(float e)
Set beam energy fraction of hit.
void setResidualX(float resid)
Set the x residual of the track.

◆ matchXYTracks()

void trigscint::TrigScintTrackProducer::matchXYTracks ( std::vector< ldmx::TrigScintTrack > & tracks)
private

Definition at line 642 of file TrigScintTrackProducer.cxx.

643 {
644 // map quadrant nb to track (can be multiple per quadrant)
645 std::multimap<int, int>
646 y_idx_quad_map; // key = quad, val = track index in collection
647 std::multimap<int, int> x_idx_quad_map;
648
649 std::multimap<int, ldmx::TrigScintTrack> y_quad_map;
650 std::multimap<int, ldmx::TrigScintTrack> x_quad_map;
651 // map track in quadrant back to index in entire track collection
652 // used for updating collection track variables
653 std::map<ldmx::TrigScintTrack, int> y_track_map;
654 std::map<ldmx::TrigScintTrack, int> x_track_map;
655
656 uint trk_idx = -1;
657 for (auto trk : tracks) {
658 trk_idx++;
659 // 1. get the y bar tracks with centroidX = -1
660 if (trk.getCentroidX() == -1) {
661 if (verbose_)
662 ldmx_log(debug) << " -- In matchXYTracks found y track at "
663 << trk.getCentroidY() << "; mapping to quad "
664 << (int)trk.getCentroidY() / (n_bars_y_ / 2)
665 << " with trk index " << trk_idx;
666 // 2. order them... or map them to quadrants. note that there are 2 layers
667 // so 2*n_bars_y_/4 channels per quadrant
668 y_quad_map.insert(
669 std::make_pair((int)(trk.getCentroidY() / (n_bars_y_ / 2)), trk));
670 y_track_map[trk] = trk_idx;
671 y_idx_quad_map.insert(
672 std::make_pair((int)(trk.getCentroidY() / (n_bars_y_ / 2)), trk_idx));
673
674 } else { // 3. get the remaining tracks (from vertical bars) and map them
675 // (back) to (middle of) quadrants
676 x_quad_map.insert(
677 std::make_pair((int)(trk.getCentroidY() / (n_bars_y_ / 2)), trk));
678 x_track_map[trk] = trk_idx;
679 x_idx_quad_map.insert(
680 std::make_pair((int)(trk.getCentroidY() / (n_bars_y_ / 2)), trk_idx));
681 if (verbose_)
682 ldmx_log(debug) << " -- In matchXYTracks found x track at (x,y) = ("
683 << trk.getCentroidX() << ", " << trk.getCentroidY()
684 << "); mapping to quad "
685 << (int)trk.getCentroidY() / (n_bars_y_ / 2)
686 << " with trk index " << trk_idx;
687 }
688 }
689
690 // 4a
691 //
692 // 1) here use the geometry? if we can assume perfect alignment we can take
693 // width and nBars and take nBars/2 as origin
694 // --- now do the matching ---
695
696 // if there is no useful matching to be done: these are the pad width wide
697 // numbers
698 float x0 = 0;
699 // this should be half the pad... could also set
700 // it to full beam spot width
701 float sx0 = fabs(x_start_);
702 float sx0_vert = fabs(bar_length_y_ / 2); // When there are no hits
703 // along the vertical bars
704
705 // y_start_ is half the pad, so this should be half a quadrant
706 float sy0 = fabs(y_start_) / 4.;
707
708 // assume at least one y track. will have to figure out if there is ever a
709 // reason to use an isolated x track in its place.
710 for (auto yitr = y_quad_map.begin(); yitr != y_quad_map.end(); ++yitr) {
711 int n_yin_quad = y_quad_map.count((*yitr).first);
712 int n_xin_quad = x_quad_map.count((*yitr).first);
713 float y{-9999.}, sy{-9999.}, x{-9999.}, x1{-9999.}, x2{-9999.}, sx1{-9999.},
714 sx2{-9999.}, y1{-9999.}, y2{-9999.}, sy1{-9999.}, sy2{-9999.};
715 // quad midpoint:
716 float y0 = (((*yitr).first * 8) * y_conv_factor_) + y_start_ + sy0;
717 float sx = 1. / 2 *
718 x_conv_factor_; // rely on x precision being one single bar
719 // width; always used unless x is undeterminable
720
721 // check all x first
722 // do the easiest first:
723 if (n_xin_quad == 0) { // then there's no hope of setting a better x here
724 // just use the beam spot width... and center of pad
725 x = x0;
726 sx = sx0_vert;
727 if (verbose_)
728 ldmx_log(debug) << "\t\t\t no x info in quad " << (*yitr).first
729 << "; will set x to middle of pad, pad half-width as "
730 "precision: set (x, sx)=("
731 << x << ", " << sx << ")";
732 } // 0 x tracks in quadrant
733 else if (n_xin_quad ==
734 1) { // slightly harder: 1 x track -- might be easy if
735 // it's just one y track; if several, need to
736 // think about overlaps. but in overlap case, just
737 // revert to setting x0 and sx0, when we know
738 auto xitr = x_quad_map.find((*yitr).first);
739 x = ((*xitr).second).getCentroidX() * x_conv_factor_ + x_start_;
740
741 if (verbose_)
742 ldmx_log(debug) << "\t\t\t 1 x in quad " << (*yitr).first
743 << ", getting (x, sx)=(" << x << ", " << sx << ")";
744 } // 1 x track in quadrant
745 else if (n_xin_quad == 2) { // finally if we have two tracks, get x1 and x2
746 // and decide later how to use them
747 // don't think we want to experiment with discerning three overlapping
748 // tracks, so not >= 2
749 // continue; //debugging: skip for now -- didn't help
750 auto xitr1 = x_quad_map.lower_bound((*yitr).first);
751 auto xitr2 = x_quad_map.upper_bound((*yitr).first);
752 xitr2--; // upper_bound points to next element
753
754 if (xitr1 != xitr2) { // should be true already but...
755 x1 = ((*xitr1).second).getCentroidX() * x_conv_factor_ + x_start_;
756 x2 = ((*xitr2).second).getCentroidX() * x_conv_factor_ + x_start_;
757 sx1 = x_conv_factor_ / 2.; // 1 bar width
758 sx2 = sx1;
759 x = (x1 + x2) / 2.;
760 // rely on x precision being one single pad width
761 sx = fabs(x1 - x2) / 2;
762 if (verbose_)
763 ldmx_log(debug) << "\t\t -- 2 x in quad: setting y track x "
764 "coordinate to midpoint";
765 }
766 } // if 2 x tracks in quad
767
768 if (n_xin_quad >= 3) { // no implementaion made so far
769 x = x0;
770 sx = sx0;
771 if (verbose_)
772 ldmx_log(debug)
773 << "\t\t\t currently no x info assigned in ambiguous case of "
774 << n_xin_quad << "vertical bar track candidates in quad "
775 << (*yitr).first
776 << "; will set x to middle of pad, pad half-width as "
777 "precision: set (x, sx)=("
778 << x << ", " << sx << ")";
779 } // 3 x tracks in quadrant
780
781 // ok! over y:
782 // can skip 0 y case by construction
783 if (n_yin_quad == 1) { // we can already now tell what the y coordinate and
784 // its precision is
785 y = ((*yitr).second).getCentroidY() * y_conv_factor_ + y_start_;
786 sy = ((*yitr).second).getResidual() * y_conv_factor_;
787 // if all clusters lined up, assign
788 // precision of 1 bar width
789 if (sy == 0) sy = 1. / 2 * y_conv_factor_;
790
791 if (n_xin_quad <= 1) {
792 // 4. every quadrant which just has one of each --> done ;
793 // b) set the sx, sy of the x track now, using the residuals from the
794 // other b1) special case: no x tracks; then x, sx have been set above
795 if (n_xin_quad == 1) {
796 auto xidx = x_idx_quad_map.find((*yitr).first);
797 tracks.at((*xidx).second).setPosition(x, y);
798 tracks.at((*xidx).second).setSigmaXY(sx, sy);
799 }
800 if (verbose_)
801 ldmx_log(debug) << "\t\t\t in quad " << (*yitr).first
802 << ", set (x, y) = (" << x << ", " << y
803 << ") and (sx, sy) = " << sx << ", " << sy << ")";
804 auto yidx = y_idx_quad_map.find((*yitr).first);
805 tracks.at((*yidx).second).setPosition(x, y);
806 tracks.at((*yidx).second).setSigmaXY(sx, sy);
807 continue;
808 }
809 } // 1 y, 0 or 1 or 3+ x track in quadrant
810
811 if (verbose_)
812 ldmx_log(debug) << "\t\t in quad " << (*yitr).first
813 << ", not single x,y tracks: " << n_xin_quad
814 << " of x and " << n_yin_quad << " of y";
815
816 if (n_yin_quad == 2) { // let's start here and see if we can do >= 2 later
817 // here one could do sth to avoid checking the other y track again in the
818 // outermost loop over y
819 auto yitr1 = y_quad_map.lower_bound((*yitr).first);
820 auto yitr2 = y_quad_map.upper_bound((*yitr).first);
821 yitr2--; // back up once
822 y1 = ((*yitr1).second).getCentroidY() * y_conv_factor_ + y_start_;
823 y2 = ((*yitr2).second).getCentroidY() * y_conv_factor_ + y_start_;
824 sy1 = ((*yitr1).second).getResidual() * y_conv_factor_;
825 sy2 = ((*yitr2).second).getResidual() * y_conv_factor_;
826 if (sy1 == 0) sy1 = 1. / 2 * y_conv_factor_;
827 if (sy2 == 0) sy2 = 1. / 2 * y_conv_factor_;
828 y = (y1 + y2) / 2.;
829 sy = fabs(y1 - y2) / 2;
830 if (verbose_)
831 ldmx_log(debug)
832 << "\t\t -- 2 y in quad: setting x track y coordinate to midpoint";
833 } // 2y in quad
834
835 if ((n_xin_quad == 0 || n_xin_quad >= 3) &&
836 (n_yin_quad == 2)) { // not using the X tracks for now for >=3
837 if (n_xin_quad == 0) {
838 if (verbose_)
839 ldmx_log(debug) << "\t\t -- No x tracks but 2 y tracks in quad: "
840 "unusual behaviour";
841 }
842 auto yidx1 = y_idx_quad_map.lower_bound((*yitr).first);
843 auto yidx2 = y_idx_quad_map.upper_bound((*yitr).first);
844 yidx2--;
845 tracks.at((*yidx1).second).setPosition(x, y1);
846 tracks.at((*yidx1).second).setSigmaXY(sx, sy1);
847 tracks.at((*yidx2).second).setPosition(x, y2);
848 tracks.at((*yidx2).second).setSigmaXY(sx, sy2);
849 continue;
850 }
851
852 if (n_yin_quad == 1 &&
853 n_xin_quad == 2) { // don't think we want to experiment with discerning
854 // three overlapping tracks, so not >= 2
855
856 // first: set the y track coordinates to x = the mid of x tracks, y = y
857 // of y track
858 auto yidx = y_idx_quad_map.find((*yitr).first);
859 tracks.at((*yidx).second).setPosition(x, y);
860 tracks.at((*yidx).second).setSigmaXY(sx, sy);
861
862 int min_overlap_pe = 250;
863 if (((*yitr).second).getPE() < min_overlap_pe) {
864 // can't tell, really, that either of these belong to the y track. so.
865 // let them keep their own x coordinate but set y to quadrant midpoint,
866 // with uncertainty +/- half quadrant width (1/8 of pad height)
867 y = y0;
868 sy = sy0;
869 if (verbose_)
870 ldmx_log(debug) << "\t\t -- Can't tell which x track should be "
871 "matched to single y track. Setting both x track "
872 "coordinates to y quadrant value:";
873 } // if can't assume overlap
874 else if (verbose_)
875 ldmx_log(debug) << "\t\t -- Found large PE count ("
876 << ((*yitr).second).getPE() << " > " << min_overlap_pe
877 << "), suggesting overlap! Setting both x track "
878 "coordinates to y track value:";
879
880 // consider making two x tracks out if this one, and, anyway have to set
881 // their average as the y track x cocordinate
882 // EXPERIMENTAL : apply only to x tracks, which can be disregarded for
883 // electron counting
884 if (verbose_)
885 ldmx_log(debug) << "\t\t -- (x1, x2, y) = (" << x1 << ", " << x2
886 << ", " << y << ") and (sx1, sx2, sy) = " << sx1 << ", "
887 << sx2 << ", " << sy << ")";
888
889 // now set x track coordinates according to overlap check result
890 auto xidx1 = x_idx_quad_map.lower_bound((*yitr).first);
891 auto xidx2 = x_idx_quad_map.upper_bound((*yitr).first);
892 xidx2--; // upper_bound points to (last+1) element
893 tracks.at((*xidx1).second).setPosition(x1, y);
894 tracks.at((*xidx1).second).setSigmaXY(sx1, sy);
895 tracks.at((*xidx2).second).setPosition(x2, y);
896 tracks.at((*xidx2).second).setSigmaXY(sx2, sy);
897
898 } // 1 y, 2 x tracks in the quadrant
899 else if (n_yin_quad == 2 && n_xin_quad == 1) {
900 // 5b) if there are more y than x: could be an overlap
901
902 // first: set the x track coordinates to x = x of x track, y = the mid of
903 // y tracks
904 auto xidx = x_idx_quad_map.find((*yitr).first);
905 tracks.at((*xidx).second).setPosition(x, y);
906 tracks.at((*xidx).second).setSigmaXY(sx, sy);
907
908 auto xitr = x_quad_map.lower_bound((*yitr).first);
909 int min_overlap_pe = 300;
910 if (((*xitr).second).getPE() < min_overlap_pe) {
911 if (verbose_)
912 ldmx_log(debug)
913 << "\t\t just 1 x track with not-unusual PE in the quad -- can't "
914 "match; setting mid-point values for x ";
915 x = x0;
916 sx = sx0;
917 } // if can't assume overlap
918 else {
919 // consider making two x tracks out if this one, and, anyway have to set
920 // their average as the y track x cocordinate
921 // EXPERIMENTAL : apply only to x tracks, which can be disregarded for
922 // electron counting
923 if (verbose_)
924 ldmx_log(debug) << "\t\t -- Found large PE count ("
925 << ((*xitr).second).getPE() << " > " << min_overlap_pe
926 << ") in x track, suggesting overlap! Setting both y "
927 "track coordinates to x track value:";
928 } // if can assume overlap
929 if (verbose_)
930 ldmx_log(debug) << "\t\t -- (x, y1, y2) = (" << x << ", " << y1 << ", "
931 << y2 << ") and (sx, sy1, sy2) = " << sx << ", " << sy1
932 << ", " << sy2 << ")";
933
934 auto yidx1 = y_idx_quad_map.lower_bound((*yitr).first);
935 auto yidx2 = y_idx_quad_map.upper_bound((*yitr).first);
936 yidx2--; // upper_bound points to next element
937 tracks.at((*yidx1).second).setPosition(x, y1);
938 tracks.at((*yidx1).second).setSigmaXY(sx, sy1);
939 tracks.at((*yidx2).second).setPosition(x, y2);
940 tracks.at((*yidx2).second).setSigmaXY(sx, sy2);
941
942 } // 2 y and 1 x track in quad
943 else if (n_yin_quad == 2 && n_xin_quad == 2) {
944 // MIDPONTS ALL OVER!
945 auto xidx1 = x_idx_quad_map.lower_bound((*yitr).first);
946 auto xidx2 = x_idx_quad_map.upper_bound((*yitr).first);
947 xidx2--;
948 auto yidx1 = y_idx_quad_map.lower_bound((*yitr).first);
949 auto yidx2 = y_idx_quad_map.upper_bound((*yitr).first);
950 yidx2--;
951
952 if (y_idx_quad_map.find((*yitr).first) == y_idx_quad_map.end())
953 ldmx_log(error) << "The two y tracks in the same quadrant at "
954 << (*yitr).first
955 << " appear to not be found in the y track map! "
956 "investigate. Note that yidx1.first = "
957 << (*yidx1).first
958 << " and yidx2.first = " << (*yidx2).first;
959 else {
960 tracks.at((*xidx1).second).setPosition(x1, y);
961 tracks.at((*xidx1).second).setSigmaXY(sx1, sy);
962 tracks.at((*xidx2).second).setPosition(x2, y);
963 tracks.at((*xidx2).second).setSigmaXY(sx2, sy);
964
965 tracks.at((*yidx1).second).setPosition(x, y1);
966 tracks.at((*yidx1).second).setSigmaXY(sx, sy1);
967 tracks.at((*yidx2).second).setPosition(x, y2);
968 tracks.at((*yidx2).second).setSigmaXY(sx, sy2);
969
970 if (verbose_)
971 ldmx_log(debug) << "\t\t -- in a 2 x 2 situaiton; midpoint y: " << y
972 << " for both x tracks, midpoint x: " << x
973 << " for both y tracks";
974 }
975 } // if 2 y, 2 x tracks
976
977 if (n_xin_quad > 2) {
978 if (verbose_)
979 ldmx_log(debug) << "\t\t -*-*-*- more than 2 x tracks in the same quad "
980 "-- nothing done about the x,y coordinates in this "
981 "situation -- implement if needed!!";
982 }
983 if (n_yin_quad > 2) {
984 if (verbose_)
985 ldmx_log(debug) << "\t\t -*-*-*- more than 2 y tracks in the same quad "
986 "-- nothing done about the x,y coordinates in this "
987 "situation -- implement if needed!!";
988 }
989
990 } // over y tracks
991
992 y_quad_map.clear();
993 x_quad_map.clear();
994
995 // return tracks;
996}

◆ onProcessEnd()

void trigscint::TrigScintTrackProducer::onProcessEnd ( )
overridevirtual

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

Reimplemented from framework::EventProcessor.

Definition at line 1004 of file TrigScintTrackProducer.cxx.

1004 {
1005 ldmx_log(debug) << "Process ends!";
1006
1007 return;
1008}

◆ onProcessStart()

void trigscint::TrigScintTrackProducer::onProcessStart ( )
overridevirtual

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

Reimplemented from framework::EventProcessor.

Definition at line 998 of file TrigScintTrackProducer.cxx.

998 {
999 ldmx_log(debug) << "Process starts!";
1000
1001 return;
1002}

◆ produce()

void trigscint::TrigScintTrackProducer::produce ( framework::Event & event)
overridevirtual

Process the event and put new data products into it.

Parameters
eventThe Event to process.

Implements framework::Producer.

Definition at line 94 of file TrigScintTrackProducer.cxx.

94 {
95 // parameters.
96 // one pad cluster collection to use as seed
97 // a vector with the other two
98 // a maximum distance between seed centroid and other pad clusters
99 // allowed to belong to the same track
100 // an output collection name a verbosity controller
101
102 if (verbose_) {
103 ldmx_log(debug)
104 << "TrigScintTrackProducer: produce() starts! Event number: "
105 << event.getEventHeader().getEventNumber();
106 }
107 if (!event.exists(seeding_collection_, pass_name_)) {
108 ldmx_log(info) << "No collection called " << seeding_collection_
109 << "; skipping event";
110 // << "; still, not skipping event";
111 return;
112 }
113
114 if (!event.exists(seeding_collection_, pass_name_)) {
115 ldmx_log(info) << "No collection called " << seeding_collection_
116 << "; skipping event";
117 return;
118 }
119 const auto seeds{event.getCollection<ldmx::TrigScintCluster>(
120 seeding_collection_, pass_name_)};
121 uint num_seeds = seeds.size();
122
123 if (verbose_) {
124 ldmx_log(debug) << "Got track seeding cluster collection "
125 << seeding_collection_ << " with " << num_seeds
126 << " entries ";
127 }
128
129 if (!event.exists(input_collections_.at(0), pass_name_)) {
130 ldmx_log(info) << "No collection called " << input_collections_.at(0)
131 << "; skipping event";
132 // << "; still, not skipping event";
133
134 return;
135 }
136 const auto clusters_pad1{event.getCollection<ldmx::TrigScintCluster>(
137 input_collections_.at(0), pass_name_)};
138
139 if (!event.exists(input_collections_.at(1), pass_name_)) {
140 ldmx_log(info) << "No collection called "
141 << input_collections_.at(1)
142 // << "; still, not skipping event";
143 << "; skipping event";
144 std::vector<ldmx::TrigScintTrack> empty{};
145 event.add(output_collection_, empty);
146 event.add(output_collection_ + "Y", empty);
147 event.add(output_collection_ + "X", empty);
148 return;
149 }
150
151 const auto clusters_pad2{event.getCollection<ldmx::TrigScintCluster>(
152 input_collections_.at(1), pass_name_)};
153
154 if (verbose_) {
155 ldmx_log(debug) << "Got the other two pad collections:"
156 << input_collections_.at(0) << " with "
157 << clusters_pad1.size() << " entries, and "
158 << input_collections_.at(1) << " with "
159 << clusters_pad2.size() << " entries.";
160 }
161 std::vector<ldmx::TrigScintTrack> cleaned_tracks;
162 std::vector<ldmx::TrigScintTrack> cleaned_tracks_y;
163 std::vector<ldmx::TrigScintTrack> cleaned_tracks_x;
164
165 // loop over the clusters in the seeding pad collection, if there are clusters
166 // in all pads
167 // bool skipDn = false;
168 if (num_seeds && clusters_pad1.size()) {
169 // could check this explicitly here: and then just get out of all checks on
170 // the dn pad immediately
171 // if (! clusters_pad2.size())
172 // skipDn = true ;
173 for (const auto& seed : seeds) {
174 // for each seed, search through the other two pads to match all clusters
175 // with centroids within tolerance to tracks
176 float centroid = seed.getCentroid();
177
178 std::vector<ldmx::TrigScintTrack> track_candidates;
179
180 if (verbose_ > 1) {
181 ldmx_log(debug) << "Got seed with centroid " << centroid;
182 }
183
184 // reset for each seed
185 // bool madeTrack = false;
186
187 if (lut_tracking_) { // if using LUT method
188 for (const auto& cluster1 : clusters_pad1) {
189 for (const auto& cluster2 : clusters_pad2) {
190 float seed_bin = seed.getCentroid();
191 float pad1_bin = cluster1.getCentroid();
192 float pad2_bin = cluster2.getCentroid();
193
194 LUTKey key{seed_bin, pad1_bin,
195 pad2_bin}; // LUTKey defined in header file
196
197 if (lut_.find(key) != lut_.end()) {
198 std::vector<ldmx::TrigScintCluster> three_cluster_vec = {
199 seed, cluster1, cluster2};
200
201 ldmx::TrigScintTrack track = makeTrack(three_cluster_vec);
202 track_candidates.push_back(track);
203 }
204 }
205 }
206
207 }
208
209 else {
210 for (const auto& cluster1 : clusters_pad1) {
211 if (verbose_ > 1) {
212 ldmx_log(debug) << "\tGot pad1 cluster with centroid "
213 << cluster1.getCentroid();
214 }
215 if ((fabs(cluster1.getCentroid() - centroid) < max_delta_ &&
216 centroid < vert_bar_start_idx_) ||
217 (centroid >= vert_bar_start_idx_ &&
218 cluster1.getCentroid() >= vert_bar_start_idx_ &&
219 seed.getCentroidX() == cluster1.getCentroidX())) {
220 // use geometry y overlap scheme to see if this is really a match in
221 // x should be done in a map
222
223 if (centroid >= vert_bar_start_idx_ &&
224 seed.getCentroidY() < cluster1.getCentroidY()) {
225 // impossible combination
226 ldmx_log(warn) << "\tSkipping impossible x cluster combination "
227 "with y flags (tag up) ("
228 << seed.getCentroidY() << " "
229 << cluster1.getCentroidY() << ")";
230 continue;
231 }
232
233 // else: first (possible) match! loop through next pad too
234
235 if (verbose_ > 1) {
236 ldmx_log(debug) << "\t\tIt is close enough!. Check pad2";
237 }
238
239 // try making third pad clusters an optional part of track
240
241 std::vector<ldmx::TrigScintCluster> cluster_vec = {seed, cluster1};
242
243 bool has_match_dn = false;
244
245 for (const auto& cluster2 : clusters_pad2) {
246 if (verbose_ > 1) {
247 ldmx_log(debug) << "\tGot pad2 cluster with centroid "
248 << cluster2.getCentroid();
249 }
250
251 if ((fabs(cluster2.getCentroid() - centroid) < max_delta_ &&
252 centroid < vert_bar_start_idx_) ||
253 (centroid >= vert_bar_start_idx_ &&
254 cluster2.getCentroid() >= vert_bar_start_idx_ &&
255 fabs(seed.getCentroidX() - cluster2.getCentroidX()) <=
256 max_delta_vert_)) {
257 // use geometry y overlap scheme to see if this is really a
258 // match
259 // in x
260
261 if (centroid >= vert_bar_start_idx_ &&
262 (seed.getCentroidY() < cluster2.getCentroidY() ||
263 cluster1.getCentroidY() >
264 cluster2.getCentroidY())) { // impossible
265 ldmx_log(warn)
266 << "\tSkipping impossible x cluster combination with y "
267 "flags (tag up dn) ("
268 << seed.getCentroidY() << " " << cluster1.getCentroidY()
269 << " " << cluster2.getCentroidY() << ")";
270 continue;
271 }
272
273 // first match! loop through next pad too
274
275 if (verbose_ > 1) {
276 ldmx_log(debug) << "\t\tIt is close enough!. Make a track";
277 }
278
279 // only make this vector now! this ensures against hanging
280 // clusters with indices from earlier in the loop
281 std::vector<ldmx::TrigScintCluster> three_cluster_vec = {
282 seed, cluster1, cluster2};
283
284 /*
285 // here we could break if we didn't want to allow all possible
286 combinations madeTrack=true; break; //we're done with this
287 iteration once there's a track made
288 */
289 // make a track
290 ldmx::TrigScintTrack track = makeTrack(three_cluster_vec);
291 track_candidates.push_back(track);
292 has_match_dn = true;
293 } // if match in pad2
294 } // over clusters in pad2
295 // if there was no match to this in pad 2, make a track with just
296 // these two clusters
297 if (!has_match_dn && skip_last_) {
298 // we allow skipping last pad if needed
299 ldmx::TrigScintTrack track = makeTrack(cluster_vec);
300 track_candidates.push_back(track);
301 }
302
303 } // if possible (x,)y match in pad1
304 /*
305//same here
306if (madeTrack)
307break;
308*/
309
310 } // over clusters in pad1
311 }
312
313 // continue to next seed if 0 track candidates
314 if (track_candidates.size() == 0) continue;
315
316 int keep_idx = 0;
317 float min_residual = 1000; // some large number
318
319 // no need to choose between only one candidate track
320 if (track_candidates.size() > 1) {
321 // now for each seed, pick only the track with the smallest residual.
322
323 if (verbose_) {
324 ldmx_log(debug) << "Got " << track_candidates.size()
325 << " tracks to check.";
326 }
327
328 for (uint idx = 0; idx < track_candidates.size(); idx++) {
329 if ((track_candidates.at(idx)).getResidual() < min_residual) {
330 keep_idx = (int)idx;
331 min_residual =
332 (track_candidates.at(idx)).getResidual(); // update minimum
333
334 if (verbose_ > 1) {
335 ldmx_log(debug)
336 << "Track at index " << idx
337 << " has smallest residual so far: " << min_residual;
338 }
339
340 } // finding min residual
341 } // over track candidates
342 } // if more than 1 to choose from
343
344 // store the track at keepIdx, if there was one we made it this far and
345 // keepIdx is 0 or has been updated to the smallest residual track idx
346 // if (keepIdx >= 0) {
347 tracks_.push_back(track_candidates.at(keep_idx));
348 if (verbose_) {
349 ldmx_log(debug) << "Kept track at index " << keep_idx;
350 ldmx_log(trace) << track_candidates.at(keep_idx);
351 }
352 //}
353 } // over seeds
354
355 // done here if there were no tracks found
356 if (tracks_.size() == 0) {
357 if (verbose_) {
358 ldmx_log(debug) << "No tracks found!";
359 }
360 std::vector<ldmx::TrigScintTrack> empty{};
361 event.add(output_collection_, empty);
362 event.add(output_collection_ + "Y", empty);
363 event.add(output_collection_ + "X", empty);
364 return;
365 }
366 // now, if there are multiple seeds sharing the same downstream hits, this
367 // should also be remedied with a selection on min residual.
368
369 // The logic of this loop kind of assumes I can remove tracks immediately --
370 // that way I can do pairwise checks between more tracks within a single
371 // loop. But for now I haven't figured out how to erase elements in a fool
372 // proof way. So I iterate over a vector...
373
374 std::vector keep_indices(tracks_.size(), 1);
375 if (verbose_ > 1)
376 ldmx_log(debug) << "vector of indices to keep has size "
377 << keep_indices.size();
378
379 for (uint idx = tracks_.size() - 1; idx > 0; idx--) {
380 // since we start in one end, we only have to check matches in one
381 // direction
382 ldmx::TrigScintTrack track = tracks_.at(idx);
383 for (int idx_comp = idx - 1; idx_comp >= 0; idx_comp--) {
384 if (verbose_ > 1)
385 ldmx_log(debug) << "In track disambiguation loop, idx points at "
386 << idx << " and prev idx points at " << idx_comp;
387
388 ldmx::TrigScintTrack next_track = tracks_.at(idx_comp);
389
390 // no need to start pulling constituents from tracks that are
391 // ridiculously far apart
392 if (((fabs(track.getCentroid() - next_track.getCentroid()) <
393 3 * max_delta_) &&
394 (track.getCentroid() <
395 vert_bar_start_idx_)) // for the horizontal bars
396 || ((fabs(track.getCentroidX() - next_track.getCentroidX()) <
397 2 * max_delta_vert_) &&
398 (track.getCentroidY() == next_track.getCentroidY()) &&
399 (track.getCentroid() >= vert_bar_start_idx_))) {
400 // and for the vertical bars, check if they are in the same quad and
401 // close enough
402 std::vector<ldmx::TrigScintCluster> consts_1 =
403 track.getConstituents();
404 std::vector<ldmx::TrigScintCluster> consts_2 =
405 next_track.getConstituents();
406 if (verbose_ > 1)
407 ldmx_log(debug)
408 << "In track disambiguation loop, got the two tracks, "
409 "with nConstituents "
410 << consts_1.size() << " and " << consts_2.size()
411 << ", respectively. ";
412 // let's do "if either cluster is shared" right now... but could also
413 // have it settable to use a stricter cut: an AND
414 if (((consts_1[1].getCentroid() == consts_2[1].getCentroid() ||
415 ((consts_1.size() > 2) && (consts_2.size() > 2) &&
416 (consts_1[2].getCentroid() == consts_2[2].getCentroid()))) &&
417 (track.getCentroid() < vert_bar_start_idx_)) ||
418 // horizontal bars
419 ((track.getCentroid() >= vert_bar_start_idx_) &&
420 ((consts_1[1].getCentroidX() == consts_2[1].getCentroidX()) ||
421 (consts_1[2].getCentroidX() == consts_2[2].getCentroidX()) ||
422 (consts_1[0].getCentroidX() ==
423 consts_2[0].getCentroidX())))) { // and vertical bars
424
425 if (verbose_ > 1) {
426 ldmx_log(debug) << "Found overlap! Tracks at index " << idx
427 << " and " << idx_comp;
428 ldmx_log(trace) << tracks_.at(idx);
429 ldmx_log(trace) << tracks_.at(idx_comp);
430 }
431
432 if (((fabs((tracks_.at(idx)).getResidualX() -
433 (tracks_.at(idx_comp)).getResidualX())) <
434 0.01) // it should be equal
435 &&
436 (track.getCentroid() >=
437 vert_bar_start_idx_)) { // specific case for the vertical bars
438 continue; // currently we can't do more here
439 } else if (((tracks_.at(idx)).getResidual() <
440 (tracks_.at(idx_comp)).getResidual() &&
441 (track.getCentroid() < vert_bar_start_idx_)) ||
442 ((tracks_.at(idx)).getResidualX() <
443 (tracks_.at(idx_comp)).getResidualX() &&
444 (track.getCentroid() >= vert_bar_start_idx_))) {
445 // next track (lower index) is a worse choice, remove its flag for
446 // keeping
447 keep_indices.at(idx_comp) = 0;
448 } else // prefer next track over current. remove current track's
449 // keep
450 // flag
451 keep_indices.at(idx) = 0;
452 /*}
453 else {
454 tracks_.erase(itNext);
455 // removeIdx.push_back(idx+1);
456 // we might see the same index two times in the loop in this
457 case, if there are three seeds sharing the same clusters
458 downstream.
459 // then the third only gets removed if it's even worse than
460 the second.
461 // one could deal with this with an extra overlap check. not
462 sure we will be in this situation any time soon though.
463 }*/
464 } // over matching/overlapping tracks
465 } // over tracks close enough to share constituents
466 } // over constructed tracks at other indices, to match
467 } // over constructed tracks
468
469 for (uint idx = 0; idx < tracks_.size(); idx++) {
470 if (verbose_ > 1) {
471 ldmx_log(debug) << "keep flag for idx " << idx << " is "
472 << keep_indices.at(idx);
473 }
474 if (keep_indices.at(idx)) { // this hasn't been flagged for removal
475
476 cleaned_tracks.push_back(tracks_.at(idx));
477
478 if (verbose_) {
479 ldmx_log(debug) << "After cleaning, keeping track at index " << idx
480 << ": Centroid = " << (tracks_.at(idx)).getCentroid()
481 << "; CentroidX = "
482 << (tracks_.at(idx)).getCentroidX()
483 << "; CentroidY = "
484 << (tracks_.at(idx)).getCentroidY()
485 << "; track PE = " << (tracks_.at(idx)).getPE()
486 << tracks_.at(idx);
487 }
488 } // if index flagged for keeping
489 } // over all (uniquely seeded) tracks in the event
490
491 if (verbose_) {
492 for (uint idx = 0; idx < tracks_.size(); idx++) {
493 ldmx_log(debug) << "Keeping track at index " << idx << ":"
494 << tracks_.at(idx);
495 }
496 }
497
498 if (verbose_) {
499 ldmx_log(debug) << "Running track x,y matching ";
500 }
501
502 if (cleaned_tracks.size() > 0) {
503 matchXYTracks(cleaned_tracks);
504 std::vector<ldmx::TrigScintTrack> matched_tracks =
505 cleaned_tracks; // don't know why this copying needs to happen but it
506 // does
507 // std::vector<ldmx::TrigScintTrack> matchXYTracks( cleanedTracks
508 //); std::vector<ldmx::TrigScintTrack> matchedTracks =
509 // matchXYTracks( cleanedTracks );
510 for (auto trk : matched_tracks) {
511 /* for (uint idx = 0; idx < tracks_.size(); idx++) {
512 if (verbose_ > 1) {
513 ldmx_log(debug) << "keep flag for idx " << idx << " is "
514 << keepIndices.at(idx);
515 }
516 if (keepIndices.at(idx)) { // this hasn't
517 been flagged for removal
518 //check if channel nb is above that of horizontal bars
519 if (tracks_.at(idx).getCentroid() >= vert_bar_start_idx_)
520 */
521 if (trk.getCentroid() >= vert_bar_start_idx_)
522 cleaned_tracks_x.push_back(trk); // acks_.at(idx));
523 else
524 cleaned_tracks_y.push_back(trk); // acks_.at(idx));
525 // cleanedTracksY.push_back(trk);
526 if (verbose_ > 1) {
527 float centr = trk.getCentroid(); // tracks_.at(idx).getCentroid(); //
528 std::string coll_str = centr >= vert_bar_start_idx_ ? "X" : "Y";
529 coll_str = output_collection_ + coll_str;
530 ldmx_log(debug) << "saving track with centroid " << centr
531 << " to output track collection " << coll_str;
532 }
533 // }
534 }
535 }
536
537 } // if there are clusters in all pads
538 else if (verbose_) {
539 ldmx_log(info)
540 << "Not all pads had clusters; (maybe) skipping tracking attempt";
541 }
542
543 if (verbose_) {
544 ldmx_log(debug) << "Done with tracking step. ";
545 }
546
547 event.add(output_collection_, cleaned_tracks);
548 // event.add(output_collection_, matchedTracks);
549
550 event.add(output_collection_ + "Y", cleaned_tracks_y);
551 event.add(output_collection_ + "X", cleaned_tracks_x);
552
553 tracks_.resize(0);
554
555 return;
556}
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:107
Stores cluster information from the trigger scintillator pads.
float getCentroidX() const
Get the x centroid of the track.
float getCentroid() const
Get the detector ID centroid of the track.
std::vector< ldmx::TrigScintCluster > getConstituents() const
Get the cluster constituents of the track.
float getCentroidY() const
Get the y centroid of the track.

References framework::Event::exists(), ldmx::TrigScintTrack::getCentroid(), ldmx::TrigScintTrack::getCentroidX(), ldmx::TrigScintTrack::getCentroidY(), and ldmx::TrigScintTrack::getConstituents().

Member Data Documentation

◆ bar_gap_x_

float trigscint::TrigScintTrackProducer::bar_gap_x_ {0.1}
private

Definition at line 115 of file TrigScintTrackProducer.h.

115{0.1}; // mm

◆ bar_gap_y_

float trigscint::TrigScintTrackProducer::bar_gap_y_ {2.1}
private

Definition at line 113 of file TrigScintTrackProducer.h.

113{2.1}; // mm

◆ bar_length_y_

double trigscint::TrigScintTrackProducer::bar_length_y_ {30.}
private

Definition at line 49 of file TrigScintTrackProducer.h.

49{30.};

◆ bar_width_x_

float trigscint::TrigScintTrackProducer::bar_width_x_ {3.}
private

Definition at line 114 of file TrigScintTrackProducer.h.

114{3.}; // mm

◆ bar_width_y_

float trigscint::TrigScintTrackProducer::bar_width_y_ {3.}
private

Definition at line 112 of file TrigScintTrackProducer.h.

112{3.}; // mm

◆ input_collections_

std::vector<std::string> trigscint::TrigScintTrackProducer::input_collections_
private

Definition at line 58 of file TrigScintTrackProducer.h.

◆ lut_

std::unordered_set<LUTKey, LUTKeyHash> trigscint::TrigScintTrackProducer::lut_
private

Definition at line 110 of file TrigScintTrackProducer.h.

◆ lut_tracking_

bool trigscint::TrigScintTrackProducer::lut_tracking_ {false}
private

Definition at line 70 of file TrigScintTrackProducer.h.

70{false};

◆ max_delta_

double trigscint::TrigScintTrackProducer::max_delta_ {0.}
private

Definition at line 46 of file TrigScintTrackProducer.h.

46{0.};

◆ max_delta_vert_

double trigscint::TrigScintTrackProducer::max_delta_vert_ {0.}
private

Definition at line 48 of file TrigScintTrackProducer.h.

48{0.};

◆ n_bars_x_

int trigscint::TrigScintTrackProducer::n_bars_x_ {8}
private

Definition at line 79 of file TrigScintTrackProducer.h.

79{8};

◆ n_bars_y_

int trigscint::TrigScintTrackProducer::n_bars_y_ {16}
private

Definition at line 76 of file TrigScintTrackProducer.h.

76{16};

◆ output_collection_

std::string trigscint::TrigScintTrackProducer::output_collection_
private

Definition at line 61 of file TrigScintTrackProducer.h.

◆ pass_name_

std::string trigscint::TrigScintTrackProducer::pass_name_ {""}
private

Definition at line 64 of file TrigScintTrackProducer.h.

64{""};

◆ seeding_collection_

std::string trigscint::TrigScintTrackProducer::seeding_collection_
private

Definition at line 55 of file TrigScintTrackProducer.h.

◆ skip_last_

bool trigscint::TrigScintTrackProducer::skip_last_ {false}
private

Definition at line 67 of file TrigScintTrackProducer.h.

67{false};

◆ tracks_

std::vector<ldmx::TrigScintTrack> trigscint::TrigScintTrackProducer::tracks_
private

Definition at line 34 of file TrigScintTrackProducer.h.

◆ verbose_

int trigscint::TrigScintTrackProducer::verbose_ {0}
private

Definition at line 52 of file TrigScintTrackProducer.h.

52{0};

◆ vert_bar_start_idx_

int trigscint::TrigScintTrackProducer::vert_bar_start_idx_ {52}
private

Definition at line 73 of file TrigScintTrackProducer.h.

73{52};

◆ x_conv_factor_

float trigscint::TrigScintTrackProducer::x_conv_factor_
private

Definition at line 117 of file TrigScintTrackProducer.h.

◆ x_start_

float trigscint::TrigScintTrackProducer::x_start_
private

Definition at line 118 of file TrigScintTrackProducer.h.

◆ y_conv_factor_

float trigscint::TrigScintTrackProducer::y_conv_factor_
private

Definition at line 119 of file TrigScintTrackProducer.h.

◆ y_start_

float trigscint::TrigScintTrackProducer::y_start_
private

Definition at line 120 of file TrigScintTrackProducer.h.


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