Class Reference for E1039 Core & Analysis Software
TriggerAnalyzer.cxx
Go to the documentation of this file.
1 #include <fstream>
2 #include <sstream>
3 #include <stdlib.h>
4 #include <algorithm>
5 
6 #include <TSQLServer.h>
7 #include <TSQLResult.h>
8 #include <TSQLRow.h>
9 
10 #include <phool/recoConsts.h>
11 
12 #include "TriggerAnalyzer.h"
13 
14 #define REQUIRE_TB
15 
17 {
18  uniqueID = uID;
19  children.clear();
20 }
21 
22 void SQTNode::add(SQTNode* child)
23 {
24  children.push_back(child);
25 }
26 
28 {
29  p_geomSvc = GeomSvc::instance();
30 
31  detectorIDs_trigger = p_geomSvc->getDetectorIDs("H1[TB]");
32  std::vector<int> H2X_trigger = p_geomSvc->getDetectorIDs("H2[TB]");
33  std::vector<int> H3X_trigger = p_geomSvc->getDetectorIDs("H3[TB]");
34  std::vector<int> H4X_trigger = p_geomSvc->getDetectorIDs("H4[TB]");
35 
36  detectorIDs_trigger.insert(detectorIDs_trigger.end(), H2X_trigger.begin(), H2X_trigger.end());
37  detectorIDs_trigger.insert(detectorIDs_trigger.end(), H3X_trigger.begin(), H3X_trigger.end());
38  detectorIDs_trigger.insert(detectorIDs_trigger.end(), H4X_trigger.begin(), H4X_trigger.end());
39 
40  root[0] = nullptr;
41  root[1] = nullptr;
42 }
43 
45 {
46  clear(1);
47  clear(-1);
48 }
49 
51 {
52  using namespace std;
53 
55 
56  int H1TID = p_geomSvc->getDetectorID("H1T");
57  int H2TID = p_geomSvc->getDetectorID("H2T");
58  int H3TID = p_geomSvc->getDetectorID("H3T");
59  int H4TID = p_geomSvc->getDetectorID("H4T");
60  int H1BID = p_geomSvc->getDetectorID("H1B");
61  int H2BID = p_geomSvc->getDetectorID("H2B");
62  int H3BID = p_geomSvc->getDetectorID("H3B");
63  int H4BID = p_geomSvc->getDetectorID("H4B");
64 
65  std::string roadsPT = rc->get_CharFlag("TRIGGER_REPO") + "/firmware/roads/L1/" + rc->get_CharFlag("TRIGGER_L1") + "/roads_plus_top.txt";
66  std::string roadsPB = rc->get_CharFlag("TRIGGER_REPO") + "/firmware/roads/L1/" + rc->get_CharFlag("TRIGGER_L1") + "/roads_plus_bottom.txt";
67  std::string roadsMT = rc->get_CharFlag("TRIGGER_REPO") + "/firmware/roads/L1/" + rc->get_CharFlag("TRIGGER_L1") + "/roads_minus_top.txt";
68  std::string roadsMB = rc->get_CharFlag("TRIGGER_REPO") + "/firmware/roads/L1/" + rc->get_CharFlag("TRIGGER_L1") + "/roads_minus_bottom.txt";
69 
70  std::string fileNames[4] = {roadsPT, roadsPB, roadsMT, roadsMB};
71  char buffer[300];
72  int pRoads = 0;
73  int mRoads = 0;
74  for(int i = 0; i < 4; ++i)
75  {
76  fstream fin(fileNames[i].c_str(), ios::in);
77 
78  while(fin.getline(buffer, 300))
79  {
80  istringstream stringBuf(buffer);
81 
82  int elementIDs[4];
83  int roadID;
84  int groupID;
85  int charge;
86  stringBuf >> roadID >> elementIDs[0] >> elementIDs[1] >> elementIDs[2] >> elementIDs[3] >> charge >> groupID;
87 
88  TriggerRoad road_new;
89  road_new.groupID = groupID;
90  if(i == 0 || i == 2)
91  {
92  road_new.addElement(H1TID, elementIDs[0]);
93  road_new.addElement(H2TID, elementIDs[1]);
94  road_new.addElement(H3TID, elementIDs[2]);
95  road_new.addElement(H4TID, elementIDs[3]);
96  }
97  else
98  {
99  road_new.addElement(H1BID, elementIDs[0]);
100  road_new.addElement(H2BID, elementIDs[1]);
101  road_new.addElement(H3BID, elementIDs[2]);
102  road_new.addElement(H4BID, elementIDs[3]);
103 
104  road_new.groupID = -road_new.groupID;
105  }
106 
107  if(i < 2)
108  {
109  road_new.roadID = pRoads++;
110  roads_enabled[0].insert(map<int, TriggerRoad>::value_type(road_new.getRoadID(), road_new));
111  }
112  else
113  {
114  road_new.roadID = mRoads++;
115  roads_enabled[1].insert(map<int, TriggerRoad>::value_type(road_new.getRoadID(), road_new));
116  }
117  }
118  }
119  makeRoadPairs();
120 
121  std::cout << "TriggerAnalyzer: " << roads_enabled[0].size() << " positive roads and " << roads_enabled[1].size() << " negative roads are activated." << std::endl;
122  return roads_enabled[0].size() > 0 && roads_enabled[1].size();
123 }
124 
125 bool TriggerAnalyzer::init(std::string fileName, double cut_td, double cut_gun)
126 {
127  TriggerRoad* road = new TriggerRoad();
128  road->clear();
129 
130  TFile dataFile(fileName.c_str(), "READ");
131  TTree* p_dataTree = (TTree*)dataFile.Get("single_p");
132  TTree* m_dataTree = (TTree*)dataFile.Get("single_m");
133 
134  p_dataTree->SetBranchAddress("road", &road);
135  m_dataTree->SetBranchAddress("road", &road);
136 
137  roads[0].clear();
138  for(int i = 0; i < p_dataTree->GetEntries(); i++)
139  {
140  p_dataTree->GetEntry(i);
141  if(road->isValid()) roads[0].insert(std::map<int, TriggerRoad>::value_type(road->getRoadID(), *road));
142  road->clear();
143  }
144 
145  roads[1].clear();
146  for(int i = 0; i < m_dataTree->GetEntries(); i++)
147  {
148  m_dataTree->GetEntry(i);
149  if(road->isValid()) roads[1].insert(std::map<int, TriggerRoad>::value_type(road->getRoadID(), *road));
150  road->clear();
151  }
152 
153  //filterRoads(cut_td, cut_gun);
154  makeRoadPairs();
155  return true;
156 }
157 
158 /*
159 void TriggerAnalyzer::filterRoads(double cut_td, double cut_gun)
160 {
161  //Filter road list
162  roads_enabled[0].clear();
163  roads_disabled[0].clear();
164  for(std::list<TriggerRoad>::iterator road = roads[0].begin(); road != roads[0].end(); ++road)
165  {
166  if(road->ratio() < cut_td || road->rndf > cut_gun)
167  {
168  road->disable();
169  roads_disabled[0].push_back(*road);
170  }
171  else
172  {
173  road->enable();
174  roads_enabled[0].push_back(*road);
175  }
176  }
177 
178  roads_enabled[1].clear();
179  roads_disabled[1].clear();
180  for(std::list<TriggerRoad>::iterator road = roads[1].begin(); road != roads[1].end(); ++road)
181  {
182  if(road->ratio() < cut_td || road->rndf > cut_gun)
183  {
184  road->disable();
185  roads_disabled[1].push_back(*road);
186  }
187  else
188  {
189  road->enable();
190  roads_enabled[1].push_back(*road);
191  }
192  }
193 
194  std::cout << "Loaded " << roads[0].size() << " positive roads and " << roads[1].size() << " negative roads" << std::endl;
195  std::cout << roads_enabled[0].size() << " positive roads and " << roads_enabled[1].size() << " negative roads are activated." << std::endl;
196 }
197 */
198 
200 {
201  //Form accepted trigger pair and rejected trigger pair
202  triggers.clear();
203  for(int i = 1; i <= 7; i++)
204  {
205  for(int j = 1; j <= 7; j++)
206  {
207  //if(abs(i-j) < 4 && i+j > 10)
208  {
209 #ifndef REQUIRE_TB
210  //Don't separate top/bottom
211  triggers.push_back(std::make_pair(i, j));
212 #else
213  //Separate top/bottom, i.e. one must come from top and the other should be from bottom
214  triggers.push_back(std::make_pair(-i, j));
215  triggers.push_back(std::make_pair(i, -j));
216 #endif
217  }
218  }
219  }
220 }
221 
223 {
224  bool pRoadFound = roads_enabled[0].find(p_road.getRoadID()) != roads_enabled[0].end();
225  bool mRoadFound = roads_enabled[1].find(m_road.getRoadID()) != roads_enabled[1].end();
226 
227  return pRoadFound && mRoadFound;
228 }
229 
230 bool TriggerAnalyzer::buildData(int nHits, int detectorIDs[], int elementIDs[])
231 {
232  p_geomSvc = GeomSvc::instance();
233  data.clear();
234 
235  //Form data matrix
236  std::set<int> vertex;
237  std::set<int> HX[4];
238 
239  vertex.insert(-1);
240  for(int i = 0; i < nHits; i++)
241  {
242  std::string detectorName = p_geomSvc->getDetectorName(detectorIDs[i]);
243  int uniqueID = detectorIDs[i]*100 + elementIDs[i];
244  if(detectorName.find("H1T") != std::string::npos || detectorName.find("H1B") != std::string::npos)
245  {
246  HX[0].insert(uniqueID);
247  }
248  else if(detectorName.find("H2T") != std::string::npos || detectorName.find("H2B") != std::string::npos)
249  {
250  HX[1].insert(uniqueID);
251  }
252  else if(detectorName.find("H3T") != std::string::npos || detectorName.find("H3B") != std::string::npos)
253  {
254  HX[2].insert(uniqueID);
255  }
256  else if(detectorName.find("H4T") != std::string::npos || detectorName.find("H4B") != std::string::npos)
257  {
258  HX[3].insert(uniqueID);
259  }
260  }
261 
262  for(int i = 0; i < 4; i++)
263  {
264  if(HX[i].empty()) return false;
265  }
266 
267  data.push_back(vertex);
268  data.push_back(HX[0]);
269  data.push_back(HX[1]);
270  data.push_back(HX[2]);
271  data.push_back(HX[3]);
272 
273  return true;
274 }
275 
276 bool TriggerAnalyzer::acceptEvent(SRawEvent* rawEvent, bool USE_TRIGGER_HIT, bool USE_HIT)
277 {
278  int nHits = 0;
279  int detectorIDs[10000];
280  int elementIDs[10000];
281 
282  if(USE_HIT)
283  {
284  for(std::vector<Hit>::iterator iter = rawEvent->getAllHits().begin(); iter != rawEvent->getAllHits().end(); ++iter)
285  {
286  if(iter->detectorID <= nChamberPlanes || iter->detectorID > nChamberPlanes+nHodoPlanes) continue;
287  if(!iter->isInTime()) continue;
288 
289  detectorIDs[nHits] = iter->detectorID;
290  elementIDs[nHits] = iter->elementID;
291 
292  ++nHits;
293  }
294  }
295 
296  if(USE_TRIGGER_HIT)
297  {
298  for(std::vector<Hit>::iterator iter = rawEvent->getTriggerHits().begin(); iter != rawEvent->getTriggerHits().end(); ++iter)
299  {
300  if(!iter->isInTime()) continue;
301 
302  detectorIDs[nHits] = iter->detectorID;
303  elementIDs[nHits] = iter->elementID;
304 
305  ++nHits;
306  }
307  }
308 
309  return acceptEvent(nHits, detectorIDs, elementIDs);
310 }
311 
312 bool TriggerAnalyzer::acceptEvent(int nHits, int detectorIDs[], int elementIDs[])
313 {
314  //initialize the container and counter
315  roads_found[0].clear();
316  roads_found[1].clear();
317  nRoads[0][0] = 0;
318  nRoads[0][1] = 0;
319  nRoads[1][0] = 0;
320  nRoads[1][1] = 0;
321 
322  //Build data structure
323  if(!buildData(nHits, detectorIDs, elementIDs)) return false;
324 
325  //search for patterns
326  for(int i = 0; i < 2; i++)
327  {
328  roads_temp.clear();
329  search(root[i], data, 0, i);
330  }
331 
332  //road selection criteria: remove invalid roads
333  std::set<int> groupIDs[2];
334  for(int i = 0; i < 2; i++)
335  {
336  for(std::list<TriggerRoad>::iterator iter = roads_found[i].begin(); iter != roads_found[i].end(); )
337  {
338  if(roads_enabled[i].find(iter->getRoadID()) == roads_enabled[i].end())
339  {
340  iter = roads_found[i].erase(iter);
341  continue;
342  }
343  else
344  {
345  *iter = roads_enabled[i][iter->getRoadID()];
346  iter->groupID > 0 ? ++nRoads[i][0] : ++nRoads[i][1];
347 
348 #ifndef REQUIRE_TB
349  //Don't separate top/bottom
350  groupIDs[i].insert(abs(iter->groupID));
351 #else
352  //Separate top/bottom
353  groupIDs[i].insert(iter->groupID);
354 #endif
355  ++iter;
356  }
357  }
358  }
359  if(groupIDs[0].empty() || groupIDs[1].empty()) return false;
360 
361  //Lv-2 selection based on group id selection
362  for(std::set<int>::iterator p_groupID = groupIDs[0].begin(); p_groupID != groupIDs[0].end(); ++p_groupID)
363  {
364  for(std::set<int>::iterator m_groupID = groupIDs[1].begin(); m_groupID != groupIDs[1].end(); ++m_groupID)
365  {
366  std::list<Trigger>::iterator trigger = std::find(triggers.begin(), triggers.end(), std::make_pair(*p_groupID, *m_groupID));
367  if(trigger != triggers.end()) return true;
368  }
369  }
370 
371  return false;
372 }
373 
374 void TriggerAnalyzer::search(SQTNode* root, DataMatrix& data, int level, int charge)
375 {
376  roads_temp.push_back(root->uniqueID);
377  if(root->children.empty())
378  {
379  //printRoadFound();
380  TriggerRoad road_found(roads_temp);
381  if(roads_enabled[charge].find(road_found.getRoadID()) != roads_enabled[charge].end()) roads_found[charge].push_back(road_found);
382  roads_temp.pop_back();
383 
384  return;
385  }
386 
387  for(std::list<SQTNode*>::iterator iter = root->children.begin(); iter != root->children.end(); ++iter)
388  {
389  if(data[level+1].find((*iter)->uniqueID) == data[level+1].end()) continue;
390  search(*iter, data, level+1, charge);
391  }
392  roads_temp.pop_back();
393 }
394 
396 {
397  if(root == nullptr) return;
398 
399  roads_temp.push_back(root->uniqueID);
400  if(root->children.empty())
401  {
402  printRoadFound();
403  roads_temp.pop_back();
404 
405  return;
406  }
407 
408  for(std::list<SQTNode*>::iterator iter = root->children.begin(); iter != root->children.end(); ++iter)
409  {
410  clearTree(*iter);
411  }
412  roads_temp.pop_back();
413 }
414 
416 {
417  if(root == nullptr) return;
418  if(root->children.empty())
419  {
420  delete root;
421  return;
422  }
423 
424  for(std::list<SQTNode*>::iterator iter = root->children.begin(); iter != root->children.end(); ++iter)
425  {
426  clearTree(*iter);
427  }
428  delete root;
429 }
430 
432 {
433  for(int i = 0; i < 2; i++)
434  {
435  root[i] = new SQTNode(-1);
436  for(std::map<int, TriggerRoad>::iterator iter = roads_enabled[i].begin(); iter != roads_enabled[i].end(); ++iter)
437  {
438  if(!iter->second.isEnabled()) continue;
439 
440  SQTNode* parentNode[5]; //note: index 4 is useless, just to keep the following code simpler
441  parentNode[0] = root[i];
442  for(int j = 0; j < 4; j++)
443  {
444  int uniqueID = iter->second.getDetectorID(j)*100 + iter->second.getElementID(j);
445  bool isNewNode = true;
446  for(std::list<SQTNode*>::iterator jter = parentNode[j]->children.begin(); jter != parentNode[j]->children.end(); ++jter)
447  {
448  if(uniqueID == (*jter)->uniqueID)
449  {
450  parentNode[j+1] = *jter;
451  isNewNode = false;
452 
453  break;
454  }
455  }
456 
457  if(isNewNode)
458  {
459  SQTNode* node_new = new SQTNode(uniqueID);
460  parentNode[j]->add(node_new);
461 
462  parentNode[j+1] = node_new;
463  }
464  }
465  }
466  }
467 }
468 
470 {
471  std::cout << "Found one road: " << std::endl;
472  for(std::list<int>::iterator iter = roads_temp.begin(); iter != roads_temp.end(); ++iter)
473  {
474  std::cout << *iter << " --> ";
475  }
476  std::cout << std::endl;
477 }
478 
480 {
481  for(unsigned int i = 0; i < data.size(); i++)
482  {
483  std::cout << i << ": ";
484  for(std::set<int>::iterator iter = data[i].begin(); iter != data[i].end(); ++iter)
485  {
486  std::cout << *iter << " ";
487  }
488  std::cout << std::endl;
489  }
490 }
491 
493 {
494  using namespace std;
495 
496  //Output single roads enabled
497  fstream fout_road[2][2];
498  fout_road[0][0].open("roads_plus_top.txt", ios::out);
499  fout_road[0][1].open("roads_plus_bottom.txt", ios::out);
500  fout_road[1][0].open("roads_minus_top.txt", ios::out);
501  fout_road[1][1].open("roads_minus_bottom.txt", ios::out);
502 
503  //roads_enabled[0].sort(TriggerRoad::byPt);
504  //roads_enabled[1].sort(TriggerRoad::byPt);
505  for(int i = 0; i < 2; i++)
506  {
507  for(std::map<int, TriggerRoad>::iterator iter = roads_enabled[i].begin(); iter != roads_enabled[i].end(); ++iter)
508  {
509  if(!iter->second.isEnabled()) continue;
510 
511  int tb = iter->second.getTB() > 0 ? 0 : 1;
512  fout_road[i][tb] << iter->second << endl;
513  }
514  }
515 
516  fout_road[0][0].close();
517  fout_road[0][1].close();
518  fout_road[1][0].close();
519  fout_road[1][1].close();
520 
521  //Output road combination
522  fstream fout_pair;
523  fout_pair.open("road_pairs.txt", ios::out);
524 
525  for(std::list<Trigger>::iterator iter = triggers.begin(); iter != triggers.end(); ++iter)
526  {
527  fout_pair << iter->first << " " << iter->second << endl;
528  }
529  fout_pair.close();
530 }
531 
532 void TriggerAnalyzer::trimEvent(SRawEvent* rawEvent, std::list<Hit>& hitlist, bool USE_TRIGGER_HIT, bool USE_HIT)
533 {
534  rawEvent->setTriggerEmu(acceptEvent(rawEvent, USE_TRIGGER_HIT, USE_HIT));
535 
536  int nRoads[4] = {getNRoadsPosTop(), getNRoadsPosBot(), getNRoadsNegTop(), getNRoadsNegBot()};
537  rawEvent->setNRoads(nRoads);
538 
539  for(int i = 0; i < 2; ++i)
540  {
541  for(std::list<TriggerRoad>::iterator iter = roads_found[i].begin(); iter != roads_found[i].end(); ++iter)
542  {
543  for(int j = 0; j < 4; ++j)
544  {
545  Hit h;
546  h.index = 10000 + hitlist.size(); // give it a huge offset;
547  h.detectorID = iter->detectorIDs[j];
548  h.elementID = iter->elementIDs[j];
549  h.tdcTime = 9999.;
550  h.driftDistance = 0.;
551  h.pos = p_geomSvc->getMeasurement(h.detectorID, h.elementID);
552  h.setInTime();
553  h.setTriggerMask();
554 
555  hitlist.push_back(h);
556  }
557  }
558  }
559 }
#define nChamberPlanes
Definition: GlobalConsts.h:6
#define nHodoPlanes
Definition: GlobalConsts.h:7
std::vector< std::set< int > > DataMatrix
static GeomSvc * instance()
singlton instance
Definition: GeomSvc.cxx:212
void getMeasurement(int detectorID, int elementID, double &measurement, double &dmeasurement)
Convert the detectorID and elementID to the actual hit position.
Definition: GeomSvc.cxx:651
std::string getDetectorName(const int &detectorID) const
Definition: GeomSvc.h:223
std::vector< int > getDetectorIDs(std::string pattern)
Definition: GeomSvc.cxx:594
Definition of hit structure.
Definition: SRawEvent.h:35
Int_t index
Definition: SRawEvent.h:77
Float_t pos
Definition: SRawEvent.h:82
Float_t tdcTime
Definition: SRawEvent.h:80
Short_t elementID
Definition: SRawEvent.h:79
Short_t detectorID
Definition: SRawEvent.h:78
void setTriggerMask(bool f=true)
Definition: SRawEvent.h:58
void setInTime(bool f=true)
Definition: SRawEvent.h:56
Float_t driftDistance
Definition: SRawEvent.h:81
virtual const std::string get_CharFlag(const std::string &flag) const
Definition: PHFlag.cc:13
std::list< SQTNode * > children
SQTNode(int uID)
void add(SQTNode *child)
std::vector< Hit > & getTriggerHits()
Definition: SRawEvent.h:142
void setTriggerEmu(bool flag)
Definition: SRawEvent.h:190
void setNRoads(Short_t nRoads[])
Definition: SRawEvent.h:191
std::vector< Hit > & getAllHits()
Definition: SRawEvent.h:141
void search(SQTNode *root, DataMatrix &data, int level, int charge)
bool buildData(int nHits, int detectorIDs[], int elementIDs[])
void printData(DataMatrix &data)
void printTree(SQTNode *root)
void clear(int charge)
void trimEvent(SRawEvent *rawEvent, std::list< Hit > &hitlist, bool USE_TRIGGER_HIT, bool USE_HIT)
void clearTree(SQTNode *root)
bool acceptEvent(TriggerRoad &p_road, TriggerRoad &m_road)
bool isValid()
void addElement(int detectorID, int elementID)
static recoConsts * instance()
Definition: recoConsts.cc:7