LDMX Software
trigscint::TrigScintFirmwareTracker Class Reference

Public Member Functions

 TrigScintFirmwareTracker (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.
 
ldmx::TrigScintTrack makeTrack (Track outTrk)
 
- 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.
 
virtual void onProcessStart ()
 Callback for the EventProcessor to take any necessary action when the processing of events starts, such as creating histograms.
 
virtual void onProcessEnd ()
 Callback for the EventProcessor to take any necessary action when the processing of events finishes, such as calculating job-summary quantities.
 
template<class T >
const T & getCondition (const std::string &condition_name)
 Access a conditions object for the current event.
 
TDirectory * getHistoDirectory ()
 Access/create a directory in the histogram file for this event processor to create histograms and analysis tuples.
 
void setStorageHint (framework::StorageControl::Hint hint)
 Mark the current event as having the given storage control hint from this module_.
 
void setStorageHint (framework::StorageControl::Hint hint, const std::string &purposeString)
 Mark the current event as having the given storage control hint from this module and the given purpose string.
 
int getLogFrequency () const
 Get the current logging frequency from the process.
 
int getRunNumber () const
 Get the run number from the process.
 
std::string getName () const
 Get the processor name.
 
void createHistograms (const std::vector< framework::config::Parameters > &histos)
 Internal function which is used to create histograms passed from the python configuration @parma histos vector of Parameters that configure histograms to create.
 

Private Attributes

double min_thr_ {0.}
 add a hit at index idx to a cluster
 
int verbose_ {0}
 
double pad_time_ {0.}
 
double time_tolerance_ {0.}
 
std::string output_collection_
 
std::string digis1_collection_
 
std::string digis2_collection_
 
std::string digis3_collection_
 
std::vector< ldmx::TrigScintTracktracks_
 
std::string pass_name_ {""}
 
std::vector< unsigned int > v_added_indices_
 
std::vector< unsigned int > v_used_indices_
 
std::map< int, int > hit_channel_map_
 

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

Definition at line 27 of file TrigScintFirmwareTracker.h.

Constructor & Destructor Documentation

◆ TrigScintFirmwareTracker()

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

Definition at line 29 of file TrigScintFirmwareTracker.h.

30 : 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::TrigScintFirmwareTracker::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 className equal to the EventProcessor class name.

For an example, look at MyProcessor.

Parameters
parametersParameters for configuration.

Reimplemented from framework::EventProcessor.

Definition at line 13 of file TrigScintFirmwareTracker.cxx.

13 {
14 min_thr_ = ps.get<double>("clustering_threshold");
15 digis1_collection_ = ps.get<std::string>("digis1_collection");
16 digis2_collection_ = ps.get<std::string>("digis2_collection");
17 digis3_collection_ = ps.get<std::string>("digis3_collection");
18 pass_name_ = ps.get<std::string>("input_pass_name");
19 output_collection_ = ps.get<std::string>("output_collection");
20 verbose_ = ps.get<int>("verbosity");
21 time_tolerance_ = ps.get<double>("time_tolerance");
22 pad_time_ = ps.get<double>("pad_time");
23
24 if (verbose_) {
25 ldmx_log(info) << "In TrigScintFirmwareTracker: configure done!";
26 ldmx_log(info) << "\nClustering threshold: " << min_thr_
27 << "\nExpected pad hit time: " << pad_time_
28 << "\nMax hit time delay: " << time_tolerance_
29 << "\ndigis1 collection: " << digis1_collection_
30 << "\ndigis2 collection: " << digis2_collection_
31 << "\ndigis3 collection: " << digis3_collection_
32 << "\nInput pass name: " << pass_name_
33 << "\nOutput collection: " << output_collection_
34 << "\nVerbosity: " << verbose_;
35 }
36
37 return;
38}
double min_thr_
add a hit at index idx to a cluster

References framework::config::Parameters::get(), and min_thr_.

◆ makeTrack()

ldmx::TrigScintTrack trigscint::TrigScintFirmwareTracker::makeTrack ( Track outTrk)

Definition at line 302 of file TrigScintFirmwareTracker.cxx.

302 {
303 // This takes a firmware track object and reverts it into an ldmx track
304 // object, unfortunately only retaining that information of the track that is
305 // retained in the firmware track.
307 float pe{0.};
308 pe += static_cast<float>(outTrk.pad1_.seed_.amp_) +
309 static_cast<float>(outTrk.pad1_.sec_.amp_);
310 pe += static_cast<float>(outTrk.pad2_.seed_.amp_) +
311 static_cast<float>(outTrk.pad2_.sec_.amp_);
312 pe += static_cast<float>(outTrk.pad3_.seed_.amp_) +
313 static_cast<float>(outTrk.pad3_.sec_.amp_);
314 tr.setCentroid(calcTCent(outTrk));
315 calcResid(outTrk);
316 tr.setPE(pe);
317 return tr;
318}
Represents a track of trigger scintillator clusters.
void setPE(float pe)
Set the average cluster pe of the track.
void setCentroid(float centroid)
Set the detector ID centroid of the track.

◆ produce()

void trigscint::TrigScintFirmwareTracker::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 40 of file TrigScintFirmwareTracker.cxx.

40 {
41 // This processor takes in TS digis and outputs a track collection. It does so
42 // using clusterproducer_sw and trackproducerHw, which are validated pieces
43 // of HLS code (though clusterproducer_sw has had its instances of pragmas
44 // excluded. I will comment on how clusterproducer and trackproducer work more
45 // thouroughly in them respectively, but generally the clusterproducer makes
46 // only two hit clusters (as ready that was all that was made from the
47 // original sw) and does so by making a digi map and running along channels
48 // numerically and pairing if possible. The trackproducer takes a LOOKUP array
49 // as a LUT and does track pattern mathcing. This depends on alignment through
50 // the A vector below.
51
52 if (verbose_) {
53 ldmx_log(debug)
54 << "TrigScintFirmwareTracker: produce() starts! Event number: "
55 << event.getEventHeader().getEventNumber();
56 }
57
58 // A is the mis-alignment vector
59 ap_int<12> a[3] = {0, 0, 0};
60 ap_int<12> lookup[NCENT][COMBO][2];
61
62 // Initialize the LOOKUP table to zero
63 for (int i = 0; i < NCENT; ++i) {
64 for (int j = 0; j < COMBO; ++j) {
65 for (int k = 0; k < 2; ++k) {
66 lookup[i][j][k] = ap_int<12>(-1);
67 }
68 }
69 }
70
71 // This line fills in the LOOKUP table used for patter matching latter. The
72 // array takes in as its first argument the centroid of a first pad cluster,
73 // then the next two take on which track pattern (of ~9) we are matching to
74 // and the last if we are matching to a cluster with two hits
75 for (int i = 0; i < NCENT; i++) {
76 for (int j = 0; j < COMBO; j++) {
77 lookup[i][j][0] = (i - a[1] + a[0]);
78 lookup[i][j][1] = (i - a[2] + a[0]);
79 if (j / 3 == 0) {
80 lookup[i][j][0] -= 1;
81 } else if (j / 3 == 2) {
82 lookup[i][j][0] += 1;
83 }
84 if (j % 3 == 0) {
85 lookup[i][j][1] -= 1;
86 } else if (j % 3 == 2) {
87 lookup[i][j][1] += 1;
88 }
89 if (not((lookup[i][j][0] >= 0) and (lookup[i][j][1] >= 0) and
90 (lookup[i][j][0] < NCENT) and (lookup[i][j][1] < NCENT))) {
91 lookup[i][j][0] = -1;
92 lookup[i][j][1] = -1;
93 }
94 }
95 }
96 // Here we instantiate arrays necessary to do the rest of it.
97 Hit h_pad1[NHITS];
98 Hit h_pad2[NHITS];
99 Hit h_pad3[NHITS];
100
101 // Pad1 goes with NTRK bc of firmware bandwidth constraints
102 // It is also expected on Pad1 to have 1 cluster per track
103 Cluster pad1[NTRK];
104 Cluster pad2[NCLUS];
105 Cluster pad3[NCLUS];
106 Track out_trk[NTRK];
107
108 for (int j = 0; j < NHITS; j++) {
109 clearHit(h_pad1[j]);
110 clearHit(h_pad2[j]);
111 clearHit(h_pad3[j]);
112 }
113 for (int j = 0; j < NCLUS; j++) {
114 if (j < NTRK) {
115 clearClus(pad1[j]);
116 }
117 clearClus(pad2[j]);
118 clearClus(pad3[j]);
119 }
120 for (int j = 0; j < NTRK; j++) {
121 clearTrack(out_trk[j]);
122 }
123 // I am reading in the three digi collections
124 const auto &digis1{
125 event.getCollection<ldmx::TrigScintHit>(digis1_collection_, pass_name_)};
126 const auto &digis2{
127 event.getCollection<ldmx::TrigScintHit>(digis2_collection_, pass_name_)};
128 const auto &digis3{
129 event.getCollection<ldmx::TrigScintHit>(digis3_collection_, pass_name_)};
130
131 if (verbose_) {
132 ldmx_log(debug) << "Got digi collection " << digis1_collection_ << "_"
133 << pass_name_ << " with " << digis1.size() << " entries ";
134 }
135
136 // The next collection of things fill in the firmware hit objects from reading
137 // in the digi collections the necessary information. The firmware hit objects
138 // only keep bID,mID,Time, and PE count.
139 int occupied[NCHAN];
140 for (int i = 0; i < NCHAN; i++) {
141 occupied[i] = -1;
142 }
143 int count = 0;
144 for (const auto &digi : digis1) {
145 if ((digi.getPE() > min_thr_) and (digi.getBarID() <= NCHAN) and
146 (digi.getBarID() >= 0)) {
147 ap_int<12> b_id = (ap_int<12>)(digi.getBarID());
148 ap_int<12> amp = (ap_int<12>)(digi.getPE());
149 if (occupied[digi.getBarID()] >= 0) {
150 if (h_pad1[occupied[digi.getBarID()]].amp_ < digi.getPE()) {
151 h_pad1[occupied[digi.getBarID()]].b_id_ =
152 (ap_int<12>)(digi.getBarID());
153 h_pad1[occupied[digi.getBarID()]].m_id_ =
154 (ap_int<12>)(digi.getModuleID());
155 h_pad1[occupied[digi.getBarID()]].amp_ = (ap_int<12>)(digi.getPE());
156 h_pad1[occupied[digi.getBarID()]].time_ =
157 (ap_int<12>)(digi.getTime());
158 }
159 } else {
160 h_pad1[count].b_id_ = (ap_int<12>)(digi.getBarID());
161 h_pad1[count].m_id_ = (ap_int<12>)(digi.getModuleID());
162 h_pad1[count].amp_ = (ap_int<12>)(digi.getPE());
163 h_pad1[count].time_ = (ap_int<12>)(digi.getTime());
164 occupied[digi.getBarID()] = count;
165 count++;
166 }
167 }
168 }
169
170 for (int i = 0; i < NCHAN; i++) {
171 occupied[i] = -1;
172 }
173 count = 0;
174 for (const auto &digi : digis2) {
175 if ((digi.getPE() > min_thr_) and (digi.getBarID() <= NCHAN) and
176 (digi.getBarID() >= 0)) {
177 ap_int<12> b_id = (ap_int<12>)(digi.getBarID());
178 ap_int<12> amp = (ap_int<12>)(digi.getPE());
179 if (occupied[digi.getBarID()] >= 0) {
180 if (h_pad2[occupied[digi.getBarID()]].amp_ < digi.getPE()) {
181 h_pad2[occupied[digi.getBarID()]].b_id_ =
182 (ap_int<12>)(digi.getBarID());
183 h_pad2[occupied[digi.getBarID()]].m_id_ =
184 (ap_int<12>)(digi.getModuleID());
185 h_pad2[occupied[digi.getBarID()]].amp_ = (ap_int<12>)(digi.getPE());
186 h_pad2[occupied[digi.getBarID()]].time_ =
187 (ap_int<12>)(digi.getTime());
188 }
189 } else {
190 h_pad2[count].b_id_ = (ap_int<12>)(digi.getBarID());
191 h_pad2[count].m_id_ = (ap_int<12>)(digi.getModuleID());
192 h_pad2[count].amp_ = (ap_int<12>)(digi.getPE());
193 h_pad2[count].time_ = (ap_int<12>)(digi.getTime());
194 occupied[digi.getBarID()] = count;
195 count++;
196 }
197 }
198 }
199 for (int i = 0; i < NCHAN; i++) {
200 occupied[i] = -1;
201 }
202 count = 0;
203 for (const auto &digi : digis3) {
204 if ((digi.getPE() > min_thr_) and (digi.getBarID() <= NCHAN) and
205 (digi.getBarID() >= 0)) {
206 ap_int<12> b_id = (ap_int<12>)(digi.getBarID());
207 ap_int<12> amp = (ap_int<12>)(digi.getPE());
208 if (occupied[digi.getBarID()] >= 0) {
209 if (h_pad3[occupied[digi.getBarID()]].amp_ < digi.getPE()) {
210 h_pad3[occupied[digi.getBarID()]].b_id_ =
211 (ap_int<12>)(digi.getBarID());
212 h_pad3[occupied[digi.getBarID()]].m_id_ =
213 (ap_int<12>)(digi.getModuleID());
214 h_pad3[occupied[digi.getBarID()]].amp_ = (ap_int<12>)(digi.getPE());
215 h_pad3[occupied[digi.getBarID()]].time_ =
216 (ap_int<12>)(digi.getTime());
217 }
218 } else {
219 h_pad3[count].b_id_ = (ap_int<12>)(digi.getBarID());
220 h_pad3[count].m_id_ = (ap_int<12>)(digi.getModuleID());
221 h_pad3[count].amp_ = (ap_int<12>)(digi.getPE());
222 h_pad3[count].time_ = (ap_int<12>)(digi.getTime());
223 occupied[digi.getBarID()] = count;
224 count++;
225 }
226 }
227 }
228 // These next lines here calls clusterproducerSw(HPad1), which is just the
229 // validated firmware module. Since ap_* class is messy, I had to do some
230 // post-call cleanup before looping over the clusters and putting them into
231 // Point i which is feed into track producer
232 int counter_n = 0;
233 std::array<Cluster, NCLUS> point1 = clusterproducerSw(h_pad1);
234 int top_seed = 0;
235 for (int i = 0; i < NCLUS; i++) {
236 if ((point1[i].seed_.amp_ < 450) and (point1[i].seed_.amp_ > 30) and
237 (point1[i].seed_.b_id_ < (NCHAN + 1)) and
238 (point1[i].seed_.b_id_ >= 0) and (point1[i].sec_.amp_ < 450) and
239 (counter_n < NTRK)) {
240 if (point1[i].seed_.b_id_ >= top_seed) {
241 cpyHit(pad1[counter_n].seed_, point1[i].seed_);
242 cpyHit(pad1[counter_n].sec_, point1[i].sec_);
243 calcCent(pad1[counter_n]);
244 counter_n++;
245 top_seed = point1[i].seed_.b_id_;
246 }
247 }
248 }
249 std::array<Cluster, NCLUS> point2 = clusterproducerSw(h_pad2);
250 top_seed = 0;
251 for (int i = 0; i < NCLUS; i++) {
252 if ((point2[i].seed_.amp_ < 450) and (point2[i].seed_.amp_ > 30) and
253 (point2[i].seed_.b_id_ < (NCHAN + 1)) and
254 (point2[i].seed_.b_id_ >= 0) and (point2[i].sec_.amp_ < 450)) {
255 if (point2[i].seed_.b_id_ >= top_seed) {
256 cpyHit(pad2[i].seed_, point2[i].seed_);
257 cpyHit(pad2[i].sec_, point2[i].sec_);
258 calcCent(pad2[i]);
259 top_seed = point2[i].seed_.b_id_;
260 }
261 }
262 }
263 std::array<Cluster, NCLUS> point3 = clusterproducerSw(h_pad3);
264 top_seed = 0;
265 for (int i = 0; i < NCLUS; i++) {
266 if ((point3[i].seed_.amp_ < 450) and (point3[i].seed_.amp_ > 30) and
267 (point3[i].seed_.b_id_ < (NCHAN + 1)) and
268 (point3[i].seed_.b_id_ >= 0) and (point3[i].sec_.amp_ < 450)) {
269 if (point3[i].seed_.b_id_ >= top_seed) {
270 cpyHit(pad3[i].seed_, point3[i].seed_);
271 cpyHit(pad3[i].sec_, point3[i].sec_);
272 calcCent(pad3[i]);
273 top_seed = point3[i].seed_.b_id_;
274 }
275 }
276 }
277 // I have stagged the digis into firmware digi objects and paired them into
278 // firmware cluster objects, so at this point I can insert them and the LUT
279 // into the trackproducerHw to create the track collection I use makeTrack to
280 // revert the firmware track object back into a regular track object for
281 // analysis purposes
282 //
283 // NOTE: Pad1 has NTRK instead of NCLUS clusters for a reason: the firmware
284 // cannot facilitate NCLUS many tracks within its alloted bandwidth , we have
285 // to put a cut on them which is facilitated by a cut on the number of
286 // clusters in Pad1. Do not change this.
287 trackproducerHw(pad1, pad2, pad3, out_trk, lookup);
288 for (int i = 0; i < NTRK; i++) {
289 if (out_trk[i].pad1_.seed_.amp_ > 0. && out_trk[i].pad1_.sec_.amp_ >= 0. &&
290 out_trk[i].pad2_.seed_.amp_ > 0. && out_trk[i].pad2_.sec_.amp_ >= 0. &&
291 out_trk[i].pad3_.seed_.amp_ > 0. && out_trk[i].pad3_.sec_.amp_ >= 0.) {
292 ldmx::TrigScintTrack trk = makeTrack(out_trk[i]);
293 tracks_.push_back(trk);
294 }
295 }
296 event.add(output_collection_, tracks_);
297 tracks_.resize(0);
298
299 return;
300}
Definition objdef.h:49
Sign Arbitrary Precision Type.
Definition ap_int.h:28

References min_thr_.

Member Data Documentation

◆ digis1_collection_

std::string trigscint::TrigScintFirmwareTracker::digis1_collection_
private

Definition at line 59 of file TrigScintFirmwareTracker.h.

◆ digis2_collection_

std::string trigscint::TrigScintFirmwareTracker::digis2_collection_
private

Definition at line 60 of file TrigScintFirmwareTracker.h.

◆ digis3_collection_

std::string trigscint::TrigScintFirmwareTracker::digis3_collection_
private

Definition at line 61 of file TrigScintFirmwareTracker.h.

◆ hit_channel_map_

std::map<int, int> trigscint::TrigScintFirmwareTracker::hit_channel_map_
private

Definition at line 75 of file TrigScintFirmwareTracker.h.

◆ min_thr_

double trigscint::TrigScintFirmwareTracker::min_thr_ {0.}
private

add a hit at index idx to a cluster

Definition at line 44 of file TrigScintFirmwareTracker.h.

44{0.};

Referenced by configure(), and produce().

◆ output_collection_

std::string trigscint::TrigScintFirmwareTracker::output_collection_
private

Definition at line 56 of file TrigScintFirmwareTracker.h.

◆ pad_time_

double trigscint::TrigScintFirmwareTracker::pad_time_ {0.}
private

Definition at line 50 of file TrigScintFirmwareTracker.h.

50{0.};

◆ pass_name_

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

Definition at line 66 of file TrigScintFirmwareTracker.h.

66{""};

◆ time_tolerance_

double trigscint::TrigScintFirmwareTracker::time_tolerance_ {0.}
private

Definition at line 53 of file TrigScintFirmwareTracker.h.

53{0.};

◆ tracks_

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

Definition at line 63 of file TrigScintFirmwareTracker.h.

◆ v_added_indices_

std::vector<unsigned int> trigscint::TrigScintFirmwareTracker::v_added_indices_
private

Definition at line 69 of file TrigScintFirmwareTracker.h.

◆ v_used_indices_

std::vector<unsigned int> trigscint::TrigScintFirmwareTracker::v_used_indices_
private

Definition at line 72 of file TrigScintFirmwareTracker.h.

◆ verbose_

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

Definition at line 47 of file TrigScintFirmwareTracker.h.

47{0};

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