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

Detailed Description

Definition at line 25 of file TrigScintFirmwareTracker.h.

Constructor & Destructor Documentation

◆ TrigScintFirmwareTracker()

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

Definition at line 27 of file TrigScintFirmwareTracker.h.

28 : 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 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 11 of file TrigScintFirmwareTracker.cxx.

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

300 {
301 // This takes a firmware track object and reverts it into an ldmx track
302 // object, unfortunately only retaining that information of the track that is
303 // retained in the firmware track.
305 float pe{0.};
306 pe += static_cast<float>(outTrk.pad1_.seed_.amp_) +
307 static_cast<float>(outTrk.pad1_.sec_.amp_);
308 pe += static_cast<float>(outTrk.pad2_.seed_.amp_) +
309 static_cast<float>(outTrk.pad2_.sec_.amp_);
310 pe += static_cast<float>(outTrk.pad3_.seed_.amp_) +
311 static_cast<float>(outTrk.pad3_.sec_.amp_);
312 tr.setCentroid(calcTCent(outTrk));
313 calcResid(outTrk);
314 tr.setPE(pe);
315 return tr;
316}
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 38 of file TrigScintFirmwareTracker.cxx.

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

◆ digis2_collection_

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

Definition at line 58 of file TrigScintFirmwareTracker.h.

◆ digis3_collection_

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

Definition at line 59 of file TrigScintFirmwareTracker.h.

◆ hit_channel_map_

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

Definition at line 73 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 42 of file TrigScintFirmwareTracker.h.

42{0.};

Referenced by configure(), and produce().

◆ output_collection_

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

Definition at line 54 of file TrigScintFirmwareTracker.h.

◆ pad_time_

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

Definition at line 48 of file TrigScintFirmwareTracker.h.

48{0.};

◆ pass_name_

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

Definition at line 64 of file TrigScintFirmwareTracker.h.

64{""};

◆ time_tolerance_

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

Definition at line 51 of file TrigScintFirmwareTracker.h.

51{0.};

◆ tracks_

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

Definition at line 61 of file TrigScintFirmwareTracker.h.

◆ v_added_indices_

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

Definition at line 67 of file TrigScintFirmwareTracker.h.

◆ v_used_indices_

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

Definition at line 70 of file TrigScintFirmwareTracker.h.

◆ verbose_

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

Definition at line 45 of file TrigScintFirmwareTracker.h.

45{0};

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