Belle II Software  release-06-00-14
HoughFinder.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 //-----------------------------------------------------------------------------
10 // Description : A class to find tracks usning Hough algorithm
11 //-----------------------------------------------------------------------------
12 
13 #define TRG_SHORT_NAMES
14 #define TRGCDC_SHORT_NAMES
15 
16 #define ENV_PATH "BELLE2_LOCAL_DIR"
17 
18 #include <stdlib.h>
19 #include <map>
20 #include <iostream>
21 #include <fstream>
22 #include "cdc/geometry/CDCGeometryPar.h"
23 #include "trg/trg/Debug.h"
24 #include "trg/trg/Utilities.h"
25 #include "trg/trg/Time.h"
26 #include "trg/trg/Signal.h"
27 #include "trg/trg/Constants.h"
28 #include "trg/cdc/TRGCDC.h"
29 #include "trg/cdc/Layer.h"
30 #include "trg/cdc/Cell.h"
31 #include "trg/cdc/Wire.h"
32 #include "trg/cdc/WireHit.h"
33 #include "trg/cdc/HoughFinder.h"
34 #include "trg/cdc/Segment.h"
35 #include "trg/cdc/SegmentHit.h"
36 #include "trg/cdc/Circle.h"
37 #include "trg/cdc/TRGCDCTrack.h"
38 #include "trg/cdc/Link.h"
39 #include "trg/cdc/Relation.h"
40 #include "trg/cdc/Fitter3DUtility.h"
41 #include "trg/cdc/Fitter3D.h"
42 #include "trg/cdc/Helix.h"
43 #include "trg/cdc/JLUT.h"
44 #include "trg/cdc/JSignal.h"
45 #include "trg/cdc/JSignalData.h"
46 #include "trg/cdc/WireHitMC.h"
47 #include "trg/cdc/TrackMC.h"
48 #include "trg/cdc/FrontEnd.h"
49 #include "trg/cdc/Merger.h"
50 #include "trg/cdc/LUT.h"
51 #include "trg/cdc/EventTime.h"
52 
53 #ifdef TRGCDC_DISPLAY_HOUGH
54 #include "trg/cdc/DisplayRphi.h"
55 #include "trg/cdc/DisplayHough.h"
56 namespace Belle2_TRGCDC {
57  Belle2::TRGCDCDisplayHough* H0 = 0;
58  Belle2::TRGCDCDisplayHough* H1 = 0;
59 }
60 #endif
61 
62 using namespace std;
63 #ifdef TRGCDC_DISPLAY_HOUGH
64 using namespace Belle2_TRGCDC;
65 #endif
66 
67 namespace Belle2 {
73  string
74  TRGCDCHoughFinder::version(void) const
75  {
76  return string("TRGCDCHoughFinder 5.24");
77  }
78 
79  TRGCDCHoughFinder::TRGCDCHoughFinder(const string& name,
80  const TRGCDC& TRGCDC,
81  unsigned peakMin,
82  const string& mappingFilePlus,
83  const string& mappingFileMinus,
84  unsigned doit)
85  : _name(name),
86  _cdc(TRGCDC),
87  _circleH("CircleHough"),
88  _doit(doit),
89  _peakFinder("PeakFinder"),
90  _peakMin(peakMin)
91  {
92 
93  _commonData = 0;
94 
95  //...Read Hough plane parameters from file
96  const string fMap[2] = {mappingFilePlus, mappingFileMinus};
97  const string fName[2] = {string("circle hough plus"), string("circle hough minus")};
98 
99  for (unsigned f = 0; f < 2; f++) {
100  const string fn = fMap[f];
101  ifstream infile(fn.c_str(), ios::in);
102  if (infile.fail()) {
103  B2FATAL("Cannot open Hough mapping file " << fn);
104  return;
105  }
106 
107  //...Ignore lines not starting with a digit...
108  string ignores;
109  while (!isdigit(infile.peek())) {
110  getline(infile, ignores);
111  }
112 
113  //...Read Hough plane cell number and limits...
114  unsigned nX = 0;
115  unsigned nY = 0;
116  double Ymin = 0.;
117  double Ymax = 0.;
118 
119  infile >> nX >> nY >> Ymin >> Ymax;
120  infile.close();
121 
122  _plane[f] = new TCHPlaneMulti2(fName[f], _circleH,
123  nX, 0, 2 * M_PI,
124  nY, Ymin, Ymax,
125  5);
126  }
127 
128  //...Set charge...
129  _plane[0]->charge(1);
130  _plane[1]->charge(-1);
131 
132 #ifdef TRGCDC_DISPLAY_HOUGH
133  if (! H0)
134  H0 = new TCDisplayHough("Plus");
135  H0->link(* D);
136  H0->clear();
137  H0->show();
138  H0->move(630, 0);
139  if (! H1)
140  H1 = new TCDisplayHough("Minus");
141  H1->link(* D);
142  H1->clear();
143  H1->show();
144  H0->move(1260, 0);
145 #endif
146 
147  //...Old mapping (trasan methode)...
148  if (_doit == 0 || _doit == 1) {
149 
150  //...Create patterns...
151  unsigned axialSuperLayerId = 0;
152  for (unsigned i = 0; i < _cdc.nSegmentLayers(); i++) {
153  const Belle2::TRGCDCLayer* l = _cdc.segmentLayer(i);
154  const unsigned nWires = l->nCells();
155 
156  if (! nWires) continue;
157  if ((* l)[0]->stereo()) continue;
158 
159  _plane[0]->preparePatterns(axialSuperLayerId, nWires);
160  _plane[1]->preparePatterns(axialSuperLayerId, nWires);
161  for (unsigned j = 0; j < nWires; j++) {
162  const TCCell& w = * (* l)[j];
163  const float x = w.xyPosition().x();
164  const float y = w.xyPosition().y();
165 
166  _plane[0]->clear();
167  _plane[0]->vote(x, y, +1, axialSuperLayerId, 1);
168  _plane[0]->registerPattern(axialSuperLayerId, j);
169 
170  _plane[1]->clear();
171  _plane[1]->vote(x, y, -1, axialSuperLayerId, 1);
172  _plane[1]->registerPattern(axialSuperLayerId, j);
173  }
174  ++axialSuperLayerId;
175  }
176  }
177 
178  //...Kaiyu's methode...
179  else {
180  mappingByFile(mappingFilePlus, mappingFileMinus);
181  }
182  }
183 
185  {
186 #ifdef TRGCDC_DISPLAY_HOUGH
187  if (H0)
188  delete H0;
189  if (H1)
190  delete H1;
191  cout << "TRGCDCHoughFinder ... Hough displays deleted" << endl;
192 #endif
193  }
194 
195  int
196  TRGCDCHoughFinder::doFindingTrasan(vector<unsigned> peaks[],
197  vector<TCTrack*>& trackList2D) const
198  {
199 
200  const string sn = "Hough Finder Finding (trasan version)";
202 
203  //...Initialization...
204  _plane[0]->clear();
205  _plane[1]->clear();
206 
207  //...Voting...
208  unsigned nLayers = _cdc.nAxialSuperLayers();
209  for (unsigned i = 0; i < nLayers; i++) {
210  const vector<const TCSHit*> hits = _cdc.axialSegmentHits(i);
211  for (unsigned j = 0; j < hits.size(); j++) {
212  _plane[0]->vote(i, hits[j]->cell().localId());
213  _plane[1]->vote(i, hits[j]->cell().localId());
214  }
215  }
216  _plane[0]->merge();
217  _plane[1]->merge();
218 
219 #ifdef TRGCDC_DISPLAY_HOUGH
220  string stg = "2D : Hough : Results of Peak Finding";
221  string inf = " ";
222  H0->stage(stg);
223  H0->information(inf);
224  H0->clear();
225  H0->area().append(_plane[0]);
226  H0->show();
227  H1->stage(stg);
228  H1->information(inf);
229  H1->clear();
230  H1->area().append(_plane[1]);
231  H1->show();
232 #endif
233 
234  //...Look for peaks which have 5 hits...
235  _peakFinder.findPeaksTrasan(* _plane[0], _peakMin, false, peaks[0]);
236  _peakFinder.findPeaksTrasan(* _plane[1], _peakMin, false, peaks[1]);
237 
238  //...Peak loop to pick up segment hits...
239  // (no fit, using peak position only)
240  for (unsigned pm = 0; pm < 2; pm++) {
241  for (unsigned i = 0; i < peaks[pm].size(); i++) {
242  const unsigned peakId = peaks[pm][i];
243 
244  //...Make a track...
245  TCTrack* t = makeTrack(peakId, pm);
246  trackList2D.push_back(t);
247 
248 #ifdef TRGCDC_DISPLAY_HOUGH
249  vector<const TCTrack*> cc;
250  cc.push_back(t);
251  const string stgNow = "doFinding : track made";
252  const string infNow = " ";
253  D->clear();
254  D->stage(stgNow);
255  D->information(infNow);
256  D->area().append(cc, Gdk::Color("#FF0066009900"));
257  D->area().append(_cdc.hits());
258  D->area().append(_cdc.segmentHits());
259  D->show();
260  D->run();
261 #endif
262  }
263  }
264 
266  return 0;
267  }
268 
269  vector<TCLink*>
270  TRGCDCHoughFinder::selectBestHits(const vector<TCLink*>& links) const
271  {
272  vector<TCLink*> bests;
273  vector<TCLink*> layers[9];
274  TCLink::separate(links, 9, layers);
275 
276  if (TRGDebug::level()) {
277  for (unsigned i = 0; i < 9; i++) {
278  cout << TRGDebug::tab() << "layer " << i << endl;
279  TCLink::dump(layers[i], "", TRGDebug::tab(4));
280  }
281  }
282 
283  //...Select links to be removed...
284  for (unsigned i = 0; i < 9; i++) {
285  if (layers[i].size() == 0) continue;
286  if (layers[i].size() == 1) {
287  bests.push_back(layers[i][0]);
288  continue;
289  }
290 
291  TCLink* best = layers[i][0];
292  int timeMin = (layers[i][0]->cell()->signal())[0]->time();
293  for (unsigned j = 1; j < layers[i].size(); j++) {
294  const TRGTime& t = * (layers[i][j]->cell()->signal())[0];
295  if (t.time() < timeMin) {
296  timeMin = t.time();
297  best = layers[i][j];
298  }
299  }
300 
301  bests.push_back(best);
302  }
303  return bests;
304  }
305 
306  int
307  TRGCDCHoughFinder::doFittingTrasan(vector<unsigned> peaks[],
308  vector<TRGCDCTrack*>& trackList2DFitted) const
309  {
310 
311  const string sn = "Hough Finder Fitting (trasan version)";
313 
314  //...Peak loop...
315  unsigned nCircles = 0;
316  for (unsigned pm = 0; pm < 2; pm++) {
317  for (unsigned i = 0; i < peaks[pm].size(); i++) {
318  const unsigned peakId = peaks[pm][i];
319 
320  //...Get segment hits...
321  vector<TCLink*> links;
322  vector<const TCSegment*> segments;
323  const unsigned nLayers = _plane[pm]->nLayers();
324  for (unsigned j = 0; j < nLayers; j++) {
325  const vector<unsigned>& ptn =
326  _plane[pm]->patternId(j, peakId);
327  for (unsigned k = 0; k < ptn.size(); k++) {
328  const TCSegment& s = _cdc.axialSegment(j, ptn[k]);
329  segments.push_back(& s);
330  if (s.hit()) {
331  TCLink* l = new TCLink(0, s.hit());
332  links.push_back(l);
333  }
334  }
335  }
336 
337  //...Select best hits in each layer...
338  const vector<TCLink*> bests = selectBestHits(links);
339 
340  //...Make a circle...
341  TCCircle c(bests);
342  c.fit();
343  c.name("CircleFitted_" + TRGUtil::itostring(nCircles));
344  ++nCircles;
345 
346  if (TRGDebug::level()) {
347  cout << TRGDebug::tab() << "peak#" << nCircles << ":"
348  << "plane" << pm << ",serialId=" << peakId << endl;
349  cout << TRGDebug::tab() << "segments below" << endl;
350  cout << TRGDebug::tab(4);
351  for (unsigned j = 0; j < segments.size(); j++) {
352  cout << segments[j]->name();
353  if (j != (segments.size() - 1))
354  cout << ",";
355  }
356  cout << endl;
357  cout << TRGDebug::tab() << "best links below" << endl;
358  TCLink::dump(bests, "", TRGDebug::tab(1));
359  c.dump("detail", TRGDebug::tab() + "Circle> ");
360  }
361 
362  //...Make a track...
363  TCTrack& t = * new TCTrack(c);
364  t.name("Track_" + TRGUtil::itostring(i));
365  trackList2DFitted.push_back(& t);
366 
367  if (TRGDebug::level()) {
368  t.relation().dump("", TRGDebug::tab());
369  t.dump("detail", TRGDebug::tab(1));
370  }
371 
372 #ifdef TRGCDC_DISPLAY_HOUGH
373  vector<const TCCircle*> cc;
374  cc.push_back(& c);
375  const string stg = "doFitting : trasan method";
376  const string inf = " ";
377  D->clear();
378  D->stage(stg);
379  D->information(inf);
380  D->area().append(_cdc.hits());
381  D->area().append(_cdc.segmentHits());
382  D->area().append(cc, Gdk::Color("blue"));
383  D->show();
384  D->run();
385 #endif
386  }
387  }
388 
390 
391  return 0;
392  }
393 
394  void
396  {
397  if (_commonData) delete _commonData;
398  }
399 
400  double TRGCDCHoughFinder::calPhi(TRGCDCSegmentHit const* segmentHit, double eventTime)
401  {
403  unsigned localId = segmentHit->segment().center().localId();
404  unsigned layerId = segmentHit->segment().center().layerId();
405  int nWires = cdcp.nWiresInLayer(layerId) * 2;
406  double rr = cdcp.senseWireR(layerId);
407  double driftTime = segmentHit->segment().priorityTime();
408  int lr = segmentHit->segment().LUT()->getValue(segmentHit->segment().lutPattern());
409  return Fitter3DUtility::calPhi(localId, nWires, driftTime, eventTime, rr, lr);
410  }
411 
412  void TRGCDCHoughFinder::calCosPhi(std::map<std::string, Belle2::TRGCDCJSignal>& mSignalStorage,
413  std::map<std::string, Belle2::TRGCDCJLUT* >& mLutStorage)
414  {
415 
417  Belle2::TRGCDCJSignalData* commonData = mSignalStorage.begin()->second.getCommonData();
418  {
419  mSignalStorage["invPhiAxMin"] = Belle2::TRGCDCJSignal(M_PI, mSignalStorage["phi_4"].getToReal(), commonData);
420  mSignalStorage["invPhiAxMax"] = Belle2::TRGCDCJSignal(2 * M_PI, mSignalStorage["phi_4"].getToReal(), commonData);
421  }
422 
423  for (unsigned iSt = 0; iSt < 5; iSt++) {
424  string t_inputName = "phi_" + to_string(iSt);
425  string t_outputName = "cosPhi_" + to_string(iSt);
426 
427  if (!mLutStorage.count(t_outputName)) {
428  mLutStorage[t_outputName] = new Belle2::TRGCDCJLUT(t_outputName);
429  mLutStorage[t_outputName]->setFloatFunction(
430  [ = ](double aValue) -> double{return cos(aValue);},
431  mSignalStorage[t_inputName],
432  mSignalStorage["invPhiAxMin"], mSignalStorage["invPhiAxMax"], mSignalStorage[t_inputName].getToReal(),
433  12, 12);
434  };//if name
435 
436  mLutStorage[t_outputName]->operate(mSignalStorage[t_inputName], mSignalStorage[t_outputName]);
437  } // end for
438  }//calCosPhi
439 
440  void TRGCDCHoughFinder::calSinPhi(std::map<std::string, Belle2::TRGCDCJSignal>& mSignalStorage,
441  std::map<std::string, Belle2::TRGCDCJLUT* >& mLutStorage)
442  {
443  Belle2::TRGCDCJSignalData* commonData = mSignalStorage.begin()->second.getCommonData();
444  {
445  mSignalStorage["invPhiAxMin"] = Belle2::TRGCDCJSignal(-M_PI / 2, mSignalStorage["phi_4"].getToReal(), commonData);
446  mSignalStorage["invPhiAxMax"] = Belle2::TRGCDCJSignal(M_PI / 2, mSignalStorage["phi_4"].getToReal(), commonData);
447  }
448 
449  for (unsigned iSt = 0; iSt < 5; iSt++) {
450  string t_sininputName = "phi_" + to_string(iSt);
451  string t_sinoutputName = "sinPhi_" + to_string(iSt);
452 
453  if (!mLutStorage.count(t_sinoutputName)) {
454  mLutStorage[t_sinoutputName] = new Belle2::TRGCDCJLUT(t_sinoutputName);
455 
456  mLutStorage[t_sinoutputName]->setFloatFunction(
457  [ = ](double aValue) -> double{return sin(aValue);},
458  mSignalStorage[t_sininputName],
459  mSignalStorage["invPhiAxMin"], mSignalStorage["invPhiAxMax"], mSignalStorage[t_sininputName].getToReal(),
460  12, 12);
461  };//if name
462 
463  mLutStorage[t_sinoutputName]->operate(mSignalStorage[t_sininputName], mSignalStorage[t_sinoutputName]);
464  } // end for
465  }//calSinPhi
466 
467  void TRGCDCHoughFinder::rPhi(std::map<std::string, Belle2::TRGCDCJSignal>& mSignalStorage,
468  std::map<std::string, Belle2::TRGCDCJLUT* >& mLutStorage)
469  {
470  Belle2::TRGCDCJSignalData* commonData = mSignalStorage.begin()->second.getCommonData();
471  for (unsigned iSt = 0; iSt < 5; iSt++) {
472  mSignalStorage["cosPhiMul_" + to_string(iSt)] <= mSignalStorage["cosPhi_" + to_string(iSt)] * mSignalStorage["cosPhi_" + to_string(
473  iSt)];
474  }
475 
476  for (unsigned iSt = 0; iSt < 5; iSt++) {
477  mSignalStorage["sinPhiMul_" + to_string(iSt)] <= mSignalStorage["sinPhi_" + to_string(iSt)] * mSignalStorage["sinPhi_" + to_string(
478  iSt)];
479  }
480 
481  for (unsigned iSt = 0; iSt < 5; iSt++) {
482  mSignalStorage["cossinPhiMul_" + to_string(iSt)] <= mSignalStorage["cosPhi_" + to_string(iSt)] * mSignalStorage["sinPhi_" +
483  to_string(iSt)];
484  }
485 
486  for (unsigned iSt = 0; iSt < 5; iSt++) {
487  mSignalStorage["rcosPhiMul_" + to_string(iSt)] <= mSignalStorage["cosPhi_" + to_string(iSt)] * mSignalStorage["2Drr_" + to_string(
488  iSt)];
489  }
490 
491  for (unsigned iSt = 0; iSt < 5; iSt++) {
492  mSignalStorage["rsinPhiMul_" + to_string(iSt)] <= mSignalStorage["sinPhi_" + to_string(iSt)] * mSignalStorage["2Drr_" + to_string(
493  iSt)];
494  }
495  mSignalStorage["cossum_p1_0"] <= mSignalStorage["cosPhiMul_0"] + mSignalStorage["cosPhiMul_1"];
496  mSignalStorage["cossum_p1_1"] <= mSignalStorage["cosPhiMul_2"] + mSignalStorage["cosPhiMul_3"];
497  mSignalStorage["cossum_p1_2"] <= mSignalStorage["cosPhiMul_4"] ;
498  mSignalStorage["cossum_p2_0"] <= mSignalStorage["cossum_p1_0"] + mSignalStorage["cossum_p1_1"];
499  mSignalStorage["cossum_p2_1"] <= mSignalStorage["cossum_p1_2"] ;
500  mSignalStorage["cossum"] <= mSignalStorage["cossum_p2_0"] + mSignalStorage["cossum_p2_1"];
501  mSignalStorage["sinsum_p1_0"] <= mSignalStorage["sinPhiMul_0"] + mSignalStorage["sinPhiMul_1"];
502  mSignalStorage["sinsum_p1_1"] <= mSignalStorage["sinPhiMul_2"] + mSignalStorage["sinPhiMul_3"];
503  mSignalStorage["sinsum_p1_2"] <= mSignalStorage["sinPhiMul_4"] ;
504  mSignalStorage["sinsum_p2_0"] <= mSignalStorage["sinsum_p1_0"] + mSignalStorage["sinsum_p1_1"];
505  mSignalStorage["sinsum_p2_1"] <= mSignalStorage["sinsum_p1_2"] ;
506  mSignalStorage["sinsum"] <= mSignalStorage["sinsum_p2_0"] + mSignalStorage["sinsum_p2_1"];
507  mSignalStorage["cossinsum_p1_0"] <= mSignalStorage["cossinPhiMul_0"] + mSignalStorage["cossinPhiMul_1"];
508  mSignalStorage["cossinsum_p1_1"] <= mSignalStorage["cossinPhiMul_2"] + mSignalStorage["cossinPhiMul_3"];
509  mSignalStorage["cossinsum_p1_2"] <= mSignalStorage["cossinPhiMul_4"] ;
510  mSignalStorage["cossinsum_p2_0"] <= mSignalStorage["cossinsum_p1_0"] + mSignalStorage["cossinsum_p1_1"];
511  mSignalStorage["cossinsum_p2_1"] <= mSignalStorage["cossinsum_p1_2"] ;
512  mSignalStorage["cossinsum"] <= mSignalStorage["cossinsum_p2_0"] + mSignalStorage["cossinsum_p2_1"];
513  mSignalStorage["rcossum_p1_0"] <= mSignalStorage["rcosPhiMul_0"] + mSignalStorage["rcosPhiMul_1"];
514  mSignalStorage["rcossum_p1_1"] <= mSignalStorage["rcosPhiMul_2"] + mSignalStorage["rcosPhiMul_3"];
515  mSignalStorage["rcossum_p1_2"] <= mSignalStorage["rcosPhiMul_4"] ;
516  mSignalStorage["rcossum_p2_0"] <= mSignalStorage["rcossum_p1_0"] + mSignalStorage["rcossum_p1_1"];
517  mSignalStorage["rcossum_p2_1"] <= mSignalStorage["rcossum_p1_2"] ;
518  mSignalStorage["rcossum"] <= mSignalStorage["rcossum_p2_0"] + mSignalStorage["rcossum_p2_1"];
519  mSignalStorage["rsinsum_p1_0"] <= mSignalStorage["rsinPhiMul_0"] + mSignalStorage["rsinPhiMul_1"];
520  mSignalStorage["rsinsum_p1_1"] <= mSignalStorage["rsinPhiMul_2"] + mSignalStorage["rsinPhiMul_3"];
521  mSignalStorage["rsinsum_p1_2"] <= mSignalStorage["rsinPhiMul_4"] ;
522  mSignalStorage["rsinsum_p2_0"] <= mSignalStorage["rsinsum_p1_0"] + mSignalStorage["rsinsum_p1_1"];
523  mSignalStorage["rsinsum_p2_1"] <= mSignalStorage["rsinsum_p1_2"] ;
524  mSignalStorage["rsinsum"] <= mSignalStorage["rsinsum_p2_0"] + mSignalStorage["rsinsum_p2_1"];
525  mSignalStorage["hcx_p1_0"] <= mSignalStorage["rcossum"] * mSignalStorage["sinsum"];
526  mSignalStorage["hcx_p1_1"] <= mSignalStorage["rsinsum"] * mSignalStorage["cossinsum"];
527  mSignalStorage["hcx_p2"] <= mSignalStorage["hcx_p1_0"] - mSignalStorage["hcx_p1_1"];
528  mSignalStorage["hcy_p1_0"] <= mSignalStorage["rsinsum"] * mSignalStorage["cossum"];
529  mSignalStorage["hcy_p1_1"] <= mSignalStorage["rcossum"] * mSignalStorage["cossinsum"];
530  mSignalStorage["hcy_p2"] <= mSignalStorage["hcy_p1_0"] - mSignalStorage["hcy_p1_1"];
531  mSignalStorage["den_p1"] <= mSignalStorage["cossum"] * mSignalStorage["sinsum"];
532  mSignalStorage["den_p2"] <= mSignalStorage["cossinsum"] * mSignalStorage["cossinsum"];
533  mSignalStorage["den"] <= mSignalStorage["den_p1"] - mSignalStorage["den_p2"];
534  {
535  mSignalStorage["denMin"] = Belle2::TRGCDCJSignal(0.00315354, mSignalStorage["den"].getToReal(),
536  commonData);//den Min = 0.00630708*0.5
537  mSignalStorage["denMax"] = Belle2::TRGCDCJSignal(1.332705, mSignalStorage["den"].getToReal(), commonData);//den Max = 0.88847*1.5
538  }
539 
540  // Constrain den.
541  {
542  // Make ifElse data.
543  vector<pair<Belle2::TRGCDCJSignal, vector<pair<Belle2::TRGCDCJSignal*, Belle2::TRGCDCJSignal> > > > t_data;
544  // Compare
545  Belle2::TRGCDCJSignal t_compare = Belle2::TRGCDCJSignal::comp(mSignalStorage["den"], ">", mSignalStorage["denMax"]);
546  // Assignments
547  vector<pair<Belle2::TRGCDCJSignal*, Belle2::TRGCDCJSignal> > t_assigns = {
548  make_pair(&mSignalStorage["den_c"], mSignalStorage["denMax"])
549  };
550  // Push to data.
551  t_data.push_back(make_pair(t_compare, t_assigns));
552  // Compare
553  t_compare = Belle2::TRGCDCJSignal::comp(mSignalStorage["den"], ">", mSignalStorage["denMin"]);
554  // Assignments
555  t_assigns = {
556  make_pair(&mSignalStorage["den_c"], mSignalStorage["den"].limit(mSignalStorage["denMin"], mSignalStorage["denMax"]))
557  };
558  // Push to data.
559  t_data.push_back(make_pair(t_compare, t_assigns));
560  // Compare
561  t_compare = Belle2::TRGCDCJSignal();
562  // Assignments
563  t_assigns = {
564  make_pair(&mSignalStorage["den_c"], mSignalStorage["denMin"])
565  };
566  // Push to data.
567  t_data.push_back(make_pair(t_compare, t_assigns));
569  }
570 
571  {
572  unsigned long long t_int = mSignalStorage["den_c"].getMaxInt();
573  double t_toReal = mSignalStorage["den_c"].getToReal();
574  double t_actual = mSignalStorage["den_c"].getMaxActual();
575  mSignalStorage["iDenMin"] = Belle2::TRGCDCJSignal(t_int, t_toReal, t_int, t_int, t_actual, t_actual, t_actual, -1, commonData);
576  t_int = mSignalStorage["den_c"].getMinInt();
577  t_actual = mSignalStorage["den_c"].getMinActual();
578  mSignalStorage["iDenMax"] = Belle2::TRGCDCJSignal(t_int, t_toReal, t_int, t_int, t_actual, t_actual, t_actual, -1, commonData);
579  }
580 
581  if (!mLutStorage.count("iDen")) {
582  mLutStorage["iDen"] = new Belle2::TRGCDCJLUT("iDen");
583  mLutStorage["iDen"]->setFloatFunction(
584  [ = ](double aValue) -> double{return 0.5 / aValue;},
585  mSignalStorage["den_c"],
586  mSignalStorage["iDenMin"], mSignalStorage["iDenMax"], pow(1 / mSignalStorage["cossinsum"].getToReal(), 2),
587  12, 12);
588  }
589 
590  //Operate using LUT(iDen = 1/2/den)
591  mLutStorage["iDen"]->operate(mSignalStorage["den_c"], mSignalStorage["iDen"]);
592 
593  mSignalStorage["hcx"] <= mSignalStorage["hcx_p2"] * mSignalStorage["iDen"];
594  mSignalStorage["hcy"] <= mSignalStorage["hcy_p2"] * mSignalStorage["iDen"];
595 
596  mSignalStorage["hcx2"] <= mSignalStorage["hcx"] * mSignalStorage["hcx"];
597  mSignalStorage["hcy2"] <= mSignalStorage["hcy"] * mSignalStorage["hcy"];
598  mSignalStorage["sumhc"] <= mSignalStorage["hcx2"] + mSignalStorage["hcy2"];
599  {
600  mSignalStorage["sumhcMin"] = Belle2::TRGCDCJSignal(4489, mSignalStorage["sumhc"].getToReal(), commonData);
601  mSignalStorage["sumhcMax"] = Belle2::TRGCDCJSignal(2560000, mSignalStorage["sumhc"].getToReal(), commonData);
602  }
603 
604  // Constrain den.
605  {
606  // Make ifElse data.
607  vector<pair<Belle2::TRGCDCJSignal, vector<pair<Belle2::TRGCDCJSignal*, Belle2::TRGCDCJSignal> > > > t_data;
608  // Compare
609  Belle2::TRGCDCJSignal t_compare = Belle2::TRGCDCJSignal::comp(mSignalStorage["sumhc"], ">", mSignalStorage["sumhcMax"]);
610  // Assignments
611  vector<pair<Belle2::TRGCDCJSignal*, Belle2::TRGCDCJSignal> > t_assigns = {
612  make_pair(&mSignalStorage["sumhc_c"], mSignalStorage["sumhcMax"])
613  };
614  // Push to data.
615  t_data.push_back(make_pair(t_compare, t_assigns));
616  // Compare
617  t_compare = Belle2::TRGCDCJSignal::comp(mSignalStorage["sumhc"], ">", mSignalStorage["sumhcMin"]);
618  // Assignments
619  t_assigns = {
620  make_pair(&mSignalStorage["sumhc_c"], mSignalStorage["sumhc"].limit(mSignalStorage["sumhcMin"], mSignalStorage["sumhcMax"]))
621  };
622  // Push to data.
623  t_data.push_back(make_pair(t_compare, t_assigns));
624  // Compare
625  t_compare = Belle2::TRGCDCJSignal();
626  // Assignments
627  t_assigns = {
628  make_pair(&mSignalStorage["sumhc_c"], mSignalStorage["sumhcMin"])
629  };
630  // Push to data.
631  t_data.push_back(make_pair(t_compare, t_assigns));
633  }
634  {
635  unsigned long long t_int = mSignalStorage["sumhc_c"].getMaxInt();
636  double t_toReal = mSignalStorage["sumhc_c"].getToReal();
637  double t_actual = mSignalStorage["sumhc_c"].getMaxActual();
638  mSignalStorage["iRhoMax"] = Belle2::TRGCDCJSignal(t_int, t_toReal, t_int, t_int, t_actual, t_actual, t_actual, -1, commonData);
639  t_int = mSignalStorage["sumhc_c"].getMinInt();
640  t_actual = mSignalStorage["sumhc_c"].getMinActual();
641  mSignalStorage["iRhoMin"] = Belle2::TRGCDCJSignal(t_int, t_toReal, t_int, t_int, t_actual, t_actual, t_actual, -1, commonData);
642  }
643  // Generate sqrt LUT sqrt(hcx*hcx + hcy*hcy)
644  if (!mLutStorage.count("iRho")) {
645  mLutStorage["iRho"] = new Belle2::TRGCDCJLUT("iRho");
646  mLutStorage["iRho"]->setFloatFunction(
647  [ = ](double aValue) -> double{return abs(sqrt(aValue));},
648  mSignalStorage["sumhc_c"],
649  mSignalStorage["iRhoMin"], mSignalStorage["iRhoMax"], mSignalStorage["sumhc"].getToReal(),
650  24, 12);
651  }
652  // Operate using LUT(iRho = sqrt(sumhc))
653  mLutStorage["iRho"]->operate(mSignalStorage["sumhc_c"], mSignalStorage["iRho"]);
654  if (TRGDebug::level()) {
655  cout << "<<<iRho>>>" << endl;
656  mSignalStorage["iRho"].dump();
657  }
658  }//rphi
659 
660  void
661  TRGCDCHoughFinder::mappingByFile(const string& mappingFilePlus,
662  const string& mappingFileMinus)
663  {
664  const string sn = "mappingByFile";
666 
667  const string* fMap[2] = {& mappingFilePlus, & mappingFileMinus};
668 
669  for (unsigned f = 0; f < 2; f++) {
670 
671  const string& fn = * fMap[f];
672  ifstream infile(fn.c_str(), ios::in);
673  if (infile.fail()) {
674  cout << " !!! can not open file" << endl
675  << " " << fn << endl
676  << " Mapping aborted" << endl;
677  return;
678  }
679 
680  //...Map data storage...
681  vector<unsigned> x;
682  vector<unsigned> y;
683  vector<vector<unsigned>> tsf;
684 
685  //...Ignore lines not starting with a digit...
686  string ignores;
687  while (!isdigit(infile.peek())) {
688  getline(infile, ignores);
689  }
690  //...Skip the first line (read in constructor)...
691  getline(infile, ignores);
692 
693  //...Read map file...
694  string car;
695  while (getline(infile, car)) {
696  unsigned i = 0;
697  unsigned b;
698  istringstream in(car);
699  vector<unsigned> slts;
700  while (in >> b) {
701  ++i;
702  unsigned j = i % 2;
703  if (i == 1) // cell position x
704  x.push_back(b);
705  if (i == 2) // cell position y (stored with offset 1)
706  y.push_back(b - 1);
707  if (j != 0 && i != 1) // TSF SL
708  slts.push_back(b);
709  if (j != 1 && i != 2) // TSF local ID
710  slts.push_back(b);
711  }
712  tsf.push_back(slts);
713  }
714  infile.close();
715 
716  unsigned axialSuperLayerId = 0;
717  for (unsigned i = 0; i < _cdc.nSegmentLayers(); i++) {
718  const Belle2::TRGCDCLayer* l = _cdc.segmentLayer(i);
719  const unsigned nWires = l->nCells();
720 
721  if (! nWires) continue;
722  if ((* l)[0]->stereo()) continue;
723 
724  _plane[f]->preparePatterns(axialSuperLayerId, nWires);
725  for (unsigned j = 0; j < nWires; j++) {
726 
727  _plane[f]->clear();
728 
729  //...loop over all hp cells...
730  const unsigned n = x.size();
731  for (unsigned k = 0; k < n; k++) {
732  const int ix = x[k];
733  const int iy = y[k];
734  const unsigned sid = _plane[f]->serialId(ix, iy);
735  for (unsigned itsf = 0; itsf < tsf[k].size();) {
736  const unsigned sl = tsf[k][itsf];
737  const unsigned id = tsf[k][itsf + 1];
738  if ((i == sl) && (j == id)) {
739  _plane[f]->setEntry(sid, axialSuperLayerId, 1);
740  }
741  itsf += 2;
742  }
743  }
744 
745  _plane[f]->registerPattern(axialSuperLayerId, j);
746  }
747  ++axialSuperLayerId;
748  }
749  }
750 
752  }
753 
754  int
755  TRGCDCHoughFinder::FindAndFit(std::vector<TRGCDCTrack*>& trackList2D,
756  std::vector<TRGCDCTrack*>& trackList2DFitted)
757  {
758 
759  if (_doit == 0 || _doit == 1)
760  return doFindingAndFittingTrasan(trackList2D, trackList2DFitted);
761  else
762  return doFindingAndFitting(trackList2D, trackList2DFitted);
763  }
764 
765  int
766  TRGCDCHoughFinder::doFindingAndFittingTrasan(std::vector<TRGCDCTrack*>& trackList2D,
767  std::vector<TRGCDCTrack*>& trackList2DFitted)
768  {
769 
770  const string sn = "HoughFinder::doFindingAndFitting (trasan version)";
772 
773  vector<unsigned> peaks[2];
774  doFindingTrasan(peaks, trackList2D);
775  doFittingTrasan(peaks, trackList2DFitted);
776 
778 
779  return 0;
780  }
781 
782  int
783  TRGCDCHoughFinder::doFindingAndFitting(std::vector<TRGCDCTrack*>& trackList2D,
784  std::vector<TRGCDCTrack*>& trackList2DFitted)
785  {
786 
787  const string sn = "HoughFinder::doFindingAndFitting (kaiyu version)";
789 
790  vector<vector<unsigned>> peaks[2];
791  doFinding(peaks, trackList2D);
792  doFitting(trackList2D, trackList2DFitted);
793 
795 
796  return 0;
797  }
798 
799  int
800  TRGCDCHoughFinder::doFinding(std::vector<std::vector<unsigned>> peaks[],
801  std::vector<TRGCDCTrack*>& trackList2D)
802  {
803 
804  const string sn = "HoughFinder::doFinding";
806 
807  //...Initialization...
808  _plane[0]->clear();
809  _plane[1]->clear();
810 
811  //...Voting...
812  unsigned nLayers = _cdc.nAxialSuperLayers();
813  for (unsigned i = 0; i < nLayers; i++) {
814  const vector<const TCSHit*> hits = _cdc.axialSegmentHits(i);
815  for (unsigned j = 0; j < hits.size(); j++) {
816  _plane[0]->vote(i, hits[j]->cell().localId());
817  _plane[1]->vote(i, hits[j]->cell().localId());
818  }
819  }
820  _plane[0]->merge();
821  _plane[1]->merge();
822 
823  //...Look for peaks which have 5 hits...
824  _peakFinder.findPeaks(* _plane[0], _peakMin, peaks[0]);
825  _peakFinder.findPeaks(* _plane[1], _peakMin, peaks[1]);
826 
827  //...Peak loop to make tracks (no fit, using hough position only)...
828  for (unsigned pm = 0; pm < 2; pm++) {
829  for (unsigned i = 0; i < peaks[pm].size(); i++) {
830  const unsigned peakId = _plane[pm]->serialId(peaks[pm][i][0],
831  peaks[pm][i][1]);
832  TCTrack* t = makeTrack(peakId, pm);
833  trackList2D.push_back(t);
834 
835 #ifdef TRGCDC_DISPLAY_HOUGH
836  vector<const TCTrack*> cc;
837  cc.push_back(t);
838  const string stg = "doFinding : track made";
839  const string inf = " ";
840  D->clear();
841  D->stage(stg);
842  D->information(inf);
843  D->area().append(cc, Gdk::Color("#FF0066009900"));
844  D->area().append(_cdc.hits());
845  D->area().append(_cdc.segmentHits());
846  D->show();
847  D->run();
848 #endif
849  }
850  }
851 
853  return 0;
854  }
855 
856  int
857  TRGCDCHoughFinder::doFitting(std::vector<TRGCDCTrack*>& trackList2D,
858  std::vector<TRGCDCTrack*>& trackList2DFitted)
859  {
860 
861  const string sn = "Hough Finder Fitting";
863 
864  if (_commonData == 0) {
866  }
867 
868  //...Event time...
869  bool fEvtTime = true;
870  // cppcheck-suppress knownConditionTrueFalse
871  double eventTime = fEvtTime ? _cdc.getEventTime() : 0;
872 
873  // Loop over all tracks
874  for (unsigned int iTrack = 0; iTrack < trackList2D.size(); iTrack++) {
875  TCTrack& aTrack = * new TCTrack(* trackList2D[iTrack]);
876  trackList2DFitted.push_back(& aTrack);
877 
879  double phi02D, Trg_PI;
880  vector<double> nWires(9);
881  vector<double> rr(9);
882  vector<double> rr2D;
883  vector<double> wirePhi2DError(5);
884  wirePhi2DError[0] = 0.0085106;
885  wirePhi2DError[1] = 0.0039841;
886  wirePhi2DError[2] = 0.0025806;
887  wirePhi2DError[3] = 0.0019084;
888  wirePhi2DError[4] = 0.001514;
889  vector<double> driftPhi2DError(5);
890  driftPhi2DError[0] = 0.0085106;
891  driftPhi2DError[1] = 0.0039841;
892  driftPhi2DError[2] = 0.0025806;
893  driftPhi2DError[3] = 0.0019084;
894  driftPhi2DError[4] = 0.001514;
895  Trg_PI = 3.141592653589793;
896  // Check if all superlayers have one TS
897  bool trackFull = 1;
898  for (unsigned iSL = 0; iSL < _cdc.nSuperLayers(); iSL = iSL + 2) {
899  // Check if all superlayers have one TS
900  const vector<TCLink*>& links = aTrack.links(iSL);
901  const unsigned nSegments = links.size();
902 
903  if (TRGDebug::level())
904  cout << TRGDebug::tab() << "#segments in SL" << iSL << " : "
905  << nSegments << endl;
906 
907  // Find if there is a TS with a priority hit.
908  // Loop over all TS in same superlayer.
909  bool priorityHitTS = 0;
910  for (unsigned iTS = 0; iTS < nSegments; iTS++) {
911  const TCSegment* _segment = dynamic_cast<const TCSegment*>(& links[iTS]->hit()->cell());
912  if (_segment->center().hit() != 0) priorityHitTS = 1;
913  }
914  if (nSegments != 1) {
915  if (nSegments == 0) {
916  trackFull = 0;
917  if (TRGDebug::level())
918  cout << TRGDebug::tab()
919  << "=> Not enough TS." << endl;
920  } else {
921  if (TRGDebug::level())
922  cout << TRGDebug::tab()
923  << "=> multiple TS are assigned." << endl;
924  }
925  } else {
926  if (priorityHitTS == 0) {
927  trackFull = 0;
928  if (TRGDebug::level())
929  cout << TRGDebug::tab()
930  << "=> There are no priority hit TS" << endl;
931  }
932  }
933  } // End superlayer loop
934  if (trackFull == 0) {
935  TRGCDCHelix helix(ORIGIN, CLHEP::HepVector(5, 0), CLHEP::HepSymMatrix(5, 0));
936  CLHEP::HepVector helixParameters(5);
937  helixParameters = aTrack.helix().a();
938  aTrack.setFitted(0);
939  aTrack.setHelix(helix);
940  continue;
941  }
942 
943  for (unsigned iSL = 0; iSL < 9; iSL++) {
944  unsigned _layerId = _cdc.segment(iSL, 0).center().layerId();
945  rr[iSL] = cdcp.senseWireR(_layerId);
946  nWires[iSL] = cdcp.nWiresInLayer(_layerId) * 2;
947  }
948  rr2D = vector<double>({rr[0], rr[2], rr[4], rr[6], rr[8]});
949 
950  // Get wirePhi, Drift information
951  vector<double>wirePhi(9);
952  vector<double>driftLength(9);
953  vector<double>LR(9);
954  vector<double>lutLR(9);
955  vector<double>mcLR(9);
956  bool fmcLR = false, fLRLUT = true;
957  for (unsigned iSL = 0; iSL < 9; iSL = iSL + 2) {
958  const vector<TCLink*>& links = aTrack.links(iSL);
959  const TCSegment* _segment = dynamic_cast<const TCSegment*>(& links[0]->hit()->cell());
960  wirePhi[iSL] = _segment->localId() / nWires[iSL] * 4 * Trg_PI;
961  lutLR[iSL] = _segment->LUT()->getValue(_segment->lutPattern());
962  mcLR[iSL] = _segment->hit()->mcLR();
963  driftLength[iSL] = _segment->hit()->drift();
964  // cppcheck-suppress knownConditionTrueFalse
965  if (fmcLR) LR[iSL] = mcLR[iSL];
966  // cppcheck-suppress knownConditionTrueFalse
967  else if (fLRLUT) LR[iSL] = lutLR[iSL];
968  else LR[iSL] = 3;
969  }//End superlayer loop
970  // 2D fit values from IW 2D fitter
971  phi02D = aTrack.helix().phi0();
972  if (aTrack.charge() < 0) {
973  phi02D = phi02D - Trg_PI;
974  if (phi02D < 0) phi02D = phi02D + 2 * Trg_PI;
975  }
976  // Get 2D fit values from JB 2D fitter
977  // Set phi2DError for 2D fit
978  vector<double>phi2DError(5);
979  for (unsigned iAx = 0; iAx < 5; iAx++) {
980  if (LR[2 * iAx] != 2) phi2DError[iAx] = driftPhi2DError[iAx];
981  else phi2DError[iAx] = wirePhi2DError[iAx];
982  }
983  // Calculate phi2D using driftTime.
984  vector<double>phi2D(5);
985  for (unsigned iAx = 0; iAx < 5; iAx++) {
986  phi2D[iAx] = Fitter3DUtility::calPhi(wirePhi[iAx * 2],
987  driftLength[iAx * 2],
988  eventTime,
989  rr[iAx * 2],
990  LR[iAx * 2]);
991  if (TRGDebug::level()) {
992  cout << TRGDebug::tab() << "eventTime: " << eventTime << endl;
993  for (int i = 0 ; i < 5 ; i++) {
994  cout << TRGDebug::tab() << "phi2D: : " << phi2D[i] << endl;
995  cout << TRGDebug::tab() << "wirePhi: " << wirePhi[i * 2]
996  << endl;
997  cout << TRGDebug::tab() << "driftLength: " <<
998  driftLength[i * 2] << endl;
999  cout << TRGDebug::tab() << "LR: " << LR[i * 2] << endl;
1000  }
1001  }
1002  }
1003  // Fit2D
1004  double rho, phi0, pt, chi2;
1005  rho = 0;
1006  phi0 = 0;
1007  pt = 0;
1008  chi2 = 0;
1009  vector<double>phi2DInvError(5);
1010  for (unsigned iAx = 0; iAx < 5; iAx++) {
1011  phi2DInvError[iAx] = 1 / phi2DError[iAx];
1012  }
1013 
1014  Fitter3DUtility::rPhiFitter(&rr2D[0], &phi2D[0], &phi2DInvError[0], rho, phi0, chi2); // By JB
1015 
1016  pt = 0.3 * 1.5 * rho / 100;
1017 
1018  if (TRGDebug::level()) {
1019  cout << TRGDebug::tab() << "rho: " << rho << endl;
1020  cout << TRGDebug::tab() << "pt: " << pt << endl;
1021  }
1022 
1023  // update track parameters
1024  TRGCDCHelix helix(ORIGIN, CLHEP::HepVector(5, 0), CLHEP::HepSymMatrix(5, 0));
1025  CLHEP::HepVector a(5);
1026  a = aTrack.helix().a();
1027  a[1] = (aTrack.charge() < 0) ? fmod(phi0 + M_PI, 2 * M_PI) : phi0;
1028  a[2] = 1 / pt * aTrack.charge();
1029  helix.a(a);
1030  aTrack.setFitted(1);
1031  aTrack.setHelix(helix);
1032  aTrack.set2DFitChi2(chi2);
1033 
1034  // Change to Signals
1035  {
1037  double rhoMin = 67;
1038  double rhoMax = 1600;
1039  int phiBitSize = 12;
1040  int rhoBitSize = 12;
1041  vector<tuple<string, double, int, double, double, int> > t_values = {
1042  make_tuple("phi_0", phi2D[0], phiBitSize, -2 * M_PI, 2 * M_PI, 0),
1043  make_tuple("phi_1", phi2D[1], phiBitSize, -2 * M_PI, 2 * M_PI, 0),
1044  make_tuple("phi_2", phi2D[2], phiBitSize, -2 * M_PI, 2 * M_PI, 0),
1045  make_tuple("phi_3", phi2D[3], phiBitSize, -2 * M_PI, 2 * M_PI, 0),
1046  make_tuple("phi_4", phi2D[4], phiBitSize, -2 * M_PI, 2 * M_PI, 0),
1047  make_tuple("rho", rho, rhoBitSize, rhoMin, rhoMax, 0),
1048  make_tuple("2Drr_0", rr[0], 12, 18.8, 105.68, 0),
1049  make_tuple("2Drr_1", rr[2], 12, 18.8, 105.68, 0),
1050  make_tuple("2Drr_2", rr[4], 12, 18.8, 105.68, 0),
1051  make_tuple("2Drr_3", rr[6], 12, 18.8, 105.68, 0),
1052  make_tuple("2Drr_4", rr[8], 12, 18.8, 105.68, 0),
1053  };
1055  }
1059  // Name signals only once.
1060  bool updateSecondName = false;
1061  if ((*m_mSignalStorage.begin()).second.getName() == "") {
1062  for (auto it = m_mSignalStorage.begin(); it != m_mSignalStorage.end(); it++) {
1063  (*it).second.setName((*it).first);
1064  }
1065  updateSecondName = true;
1066  }
1067 
1068  if (updateSecondName) {
1069  // Print Vhdl
1070  if ((*m_mSignalStorage.begin()).second.getName() != "") {
1071  if (_commonData->getPrintedToFile() == 0) {
1072  if (_commonData->getPrintVhdl() == 0) {
1073  _commonData->setVhdlOutputFile("Fitter2D.vhd");
1075  } else {
1081  // Print LUTs.
1082  for (map<string, TRGCDCJLUT*>::iterator it = m_mLutStorage.begin(); it != m_mLutStorage.end(); ++it) {
1083  it->second->makeCOE(it->first + ".coe");
1084  }
1085  }
1086  }
1087  }
1088  }
1089 
1090 #ifdef TRGCDC_DISPLAY_HOUGH
1091  vector<const TCTrack*> cc;
1092  cc.push_back(& aTrack);
1093  const string stg = "doFitting : Kaiyu method";
1094  const string inf = " ";
1095  D->clear();
1096  D->stage(stg);
1097  D->information(inf);
1098  D->area().append(_cdc.hits());
1099  D->area().append(_cdc.segmentHits());
1100  D->area().append(cc, Gdk::Color("blue"));
1101  D->show();
1102  D->run();
1103 #endif
1104  }
1105 
1107 
1108  return 0;
1109  }
1110 
1111  TCTrack*
1112  TRGCDCHoughFinder::makeTrack(const unsigned peakId, const unsigned pm) const
1113  {
1114 
1115  //...Cal. pt and phi from the cell number...
1116  const TCHTransformationCircle& tc =
1117  (TCHTransformationCircle&) _plane[pm]->transformation();
1118  unsigned x, y;
1119  _plane[pm]->id(peakId, x, y);
1120  const TRGPoint2D hp = _plane[pm]->position(x, y);
1121  const TRGPoint2D cc = tc.circleCenter(hp);
1122  const double r = cc.y();
1123  const double phi = cc.x();
1124 
1125  //...Make a circle...
1126  TCCircle c(r, phi, pm ? -1. : 1., * _plane[pm]);
1127  c.name("circle_" + TRGUtil::itostring(int(peakId) * (pm ? -1 : 1)));
1128 
1129  if (TRGDebug::level()) {
1130  cout << TRGDebug::tab() << "plane" << pm << ",serialId=" << peakId
1131  << endl;
1132  c.dump("detail", TRGDebug::tab() + "Circle> ");
1133  }
1134 
1135  //...Get segment hits...
1136  vector<TCLink*> links;
1137  vector<const TCSegment*> segments;
1138  const unsigned nLayers = _plane[pm]->nLayers();
1139  for (unsigned j = 0; j < nLayers; j++) {
1140  const vector<unsigned>& ptn =
1141  _plane[pm]->patternId(j, peakId);
1142  for (unsigned k = 0; k < ptn.size(); k++) {
1143  const TCSegment& s = _cdc.axialSegment(j, ptn[k]);
1144  segments.push_back(& s);
1145  if (s.hit()) {
1146  TCLink* l = new TCLink(0, s.hit());
1147  links.push_back(l);
1148  }
1149  }
1150  }
1151  c.append(links);
1152 
1153  if (TRGDebug::level()) {
1154  cout << TRGDebug::tab() << "attched segments below" << endl;
1155  cout << TRGDebug::tab(4);
1156  for (unsigned j = 0; j < segments.size(); j++) {
1157  cout << segments[j]->name();
1158  if (j != (segments.size() - 1))
1159  cout << ",";
1160  }
1161  cout << endl;
1162  }
1163 
1164  //...Make a track...
1165  TCTrack* t = new TCTrack(c);
1166  t->name("track_" + TRGUtil::itostring(int(peakId) * (pm ? -1 : 1)));
1167 
1168  if (TRGDebug::level()) {
1169  t->relation().dump("", TRGDebug::tab());
1170  t->dump("detail");
1171  }
1172 
1173  return t;
1174  }
1175 
1177 } // namespace Belle2
The Class for CDC Geometry Parameters.
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
double senseWireR(int layerId) const
Returns radius of sense wire in each layer.
TRGCDCHelix parameter class.
Definition: Helix.h:34
TRGCDCJSignalData * _commonData
For VHDL code.
Definition: HoughFinder.h:184
TRGCDCHoughPlaneMulti2 * _plane[2]
Hough planes, for + and - charges.
Definition: HoughFinder.h:145
const TRGCDC & _cdc
CDCTRG.
Definition: HoughFinder.h:142
TRGCDCHoughTransformationCircle _circleH
Circle Hough transformtion.
Definition: HoughFinder.h:148
std::map< std::string, TRGCDCJLUT * > m_mLutStorage
Map to hold JLuts.
Definition: HoughFinder.h:181
const unsigned _doit
Doit version.
Definition: HoughFinder.h:151
std::map< std::string, TRGCDCJSignal > m_mSignalStorage
Map to hold JSignals.
Definition: HoughFinder.h:178
TRGCDCPeakFinder _peakFinder
Peak finder.
Definition: HoughFinder.h:154
const unsigned _peakMin
Min. peak height for the peak finder.
Definition: HoughFinder.h:157
const std::vector< unsigned > & patternId(unsigned cellId) const
returns pattern ID which activates specified cell.
A class to use LUTs for TRGCDC.
Definition: JLUT.h:35
A class to hold common data for JSignals.
Definition: JSignalData.h:33
A class to use Signals for TRGCDC 3D tracker.
Definition: JSignal.h:35
A class to represent a cell layer.
Definition: Layer.h:33
A class to represent a track segment hit in CDC.
Definition: SegmentHit.h:31
float priorityTime(void) const
return priority time in TSHit.
The instance of TRGCDC is a singleton.
Definition: TRGCDC.h:69
A class to represent a point in 2D.
Definition: Point2D.h:27
A class to represent a signal timing in the trigger system.
Definition: Time.h:25
static void rPhiFitter(double *rr, double *phi2, double *invphierror, double &rho, double &myphi0)
A circle fitter with invPhiError without fit chi2 output.
static double calPhi(double wirePhi, double driftLength, double rr, int lr)
Pre 3D fitter functions. rr is in cm scale. driftLength is in cm scale.
int doFindingTrasan(std::vector< unsigned > peaks[], std::vector< TRGCDCTrack * > &trackList2D) const
do track finding. (trasan version)
Definition: HoughFinder.cc:196
std::vector< const TRGCDCSegmentHit * > segmentHits(void) const
returns a list of TRGCDCSegmentHit.
Definition: TRGCDC.h:996
static void calCosPhi(std::map< std::string, Belle2::TRGCDCJSignal > &mSignalStorage, std::map< std::string, Belle2::TRGCDCJLUT * > &mLutStorage)
Calculate Cos Sin ?
Definition: HoughFinder.cc:412
void preparePatterns(unsigned layerId, unsigned nPatterns)
allocate memory for patterns.
static std::string tab(void)
returns tab spaces.
Definition: Debug.cc:47
std::vector< const TRGCDCSegmentHit * > axialSegmentHits(unsigned) const
returns a list of TRGCDCSegmentHit in a axial super layer N.
Definition: TRGCDC.h:1014
unsigned nSegmentLayers(void) const
returns # of track segment layers.
Definition: TRGCDC.h:1070
const TRGCDCWire & center(void) const
returns a center wire.
Definition: Segment.h:250
void printToFile()
Utilities Function to print VHDL code.
Definition: JSignalData.cc:106
static void valuesToMapSignals(std::vector< std::tuple< std::string, double, int, double, double, int > > const &inValues, Belle2::TRGCDCJSignalData *inCommonData, std::map< std::string, Belle2::TRGCDCJSignal > &outMap)
Values => [name, value, bitwidth, min, max, clock] Changes values to signals.
Definition: JSignal.cc:2206
static void calSinPhi(std::map< std::string, Belle2::TRGCDCJSignal > &mSignalStorage, std::map< std::string, Belle2::TRGCDCJLUT * > &mLutStorage)
Calculate Cos Sin ?
Definition: HoughFinder.cc:440
static double calPhi(TRGCDCSegmentHit const *segmentHit, double eventTime)
Utility functions.
Definition: HoughFinder.cc:400
TRGCDCTrack * makeTrack(const unsigned serialID, const unsigned pm) const
Make a track from serial ID in Hough plane.
int FindAndFit(std::vector< TRGCDCTrack * > &trackList2D, std::vector< TRGCDCTrack * > &trackList2DFitted)
do track finding and fitting (wrapper that can choose between different versions).
Definition: HoughFinder.cc:755
void mappingByFile(const std::string &mappingFilePlus, const std::string &mappingFileMinus)
creates mappings by a file.
Definition: HoughFinder.cc:661
float charge(void) const
returns charge for this plane.
bool getPrintVhdl() const
Gets the status of m_printVhdl.
Definition: JSignalData.cc:75
static void ifElse(std::vector< std::pair< TRGCDCJSignal, std::vector< std::pair< TRGCDCJSignal *, TRGCDCJSignal > > > > &data, int targetClock)
If else implementation with target clock.
Definition: JSignal.cc:800
unsigned layerId(void) const
returns layer id.
Definition: Cell.h:211
std::vector< TRGCDCLink * > selectBestHits(const std::vector< TRGCDCLink * > &links) const
selects the best(fastest) hits in each super layer.
Definition: HoughFinder.cc:270
void id(unsigned serialId, unsigned &x, unsigned &y) const
returns x and y for serialID.
virtual ~TRGCDCHoughFinder()
Destructor.
Definition: HoughFinder.cc:184
int getValue(unsigned) const
get LUT Values
Definition: LUT.cc:47
const TRGCDCLayer * segmentLayer(unsigned id) const
returns a pointer to a track segment layer.
Definition: TRGCDC.h:1061
bool getPrintedToFile() const
Gets the status of m_printedToFile.
Definition: JSignalData.cc:80
unsigned serialId(unsigned x, unsigned y) const
returns serial ID for position (x, y).
static void enterStage(const std::string &stageName)
Declare that you enter new stage.
Definition: Debug.cc:24
unsigned setEntry(unsigned serialId, unsigned layerId, unsigned n)
Sets entry.
void terminate()
termination.
Definition: HoughFinder.cc:395
int doFinding(std::vector< std::vector< unsigned >> peaks[], std::vector< TRGCDCTrack * > &trackList2D)
do track finding. (kaiyu version)
Definition: HoughFinder.cc:800
unsigned nAxialSuperLayers(void) const
return # of axial super layers.
Definition: TRGCDC.h:891
const CLHEP::HepVector & a(void) const
returns helix parameters.
Definition: Helix.h:313
int doFindingAndFitting(std::vector< TRGCDCTrack * > &trackList2D, std::vector< TRGCDCTrack * > &trackList2DFitted)
do track finding and fitting (Kaiyu version).
Definition: HoughFinder.cc:783
unsigned nSuperLayers(void) const
returns # of super layers.
Definition: TRGCDC.h:870
unsigned lutPattern(void) const
hit pattern containing bit for priority position
Definition: Segment.cc:559
const TRGCDCSegment & segment(unsigned id) const
returns a track segment.
Definition: TRGCDC.h:933
int doFindingAndFittingTrasan(std::vector< TRGCDCTrack * > &trackList2D, std::vector< TRGCDCTrack * > &trackList2DFitted)
do track finding and fitting (Trasan version).
Definition: HoughFinder.cc:766
void merge(void)
Merge layers into one.
void findPeaksTrasan(TRGCDCHoughPlaneMulti2 &hp, const unsigned threshold, const bool centerIsPeak, std::vector< unsigned > &peakSerialIds) const
do peak finding. This is a copy from "trasan".
Definition: PeakFinder.cc:360
const TRGCDCLUT * LUT(void) const
returns LUT
Definition: Segment.h:243
unsigned nLayers(void) const
returns # of Hough Boolean layers.
int getEventTime(void) const
returns bad hits(finding invalid hits).
Definition: TRGCDC.cc:2741
int doFittingTrasan(std::vector< unsigned > peaks[], std::vector< TRGCDCTrack * > &trackList2DFitted) const
do track fitting. (old trasan version)
Definition: HoughFinder.cc:307
void clear(void) override
Clears all entries and regions.
int doFitting(std::vector< TRGCDCTrack * > &trackList2D, std::vector< TRGCDCTrack * > &trackList2DFitted)
do track fitting. (kaiyu original)
Definition: HoughFinder.cc:857
const HepGeom::Point3D< double > ORIGIN
Origin 3D point.
const TRGCDCSegment & axialSegment(unsigned lyrId, unsigned id) const
returns a track segment in axial layers. (lyrId is axial #)
Definition: TRGCDC.h:940
static void rPhi(std::map< std::string, Belle2::TRGCDCJSignal > &mSignalStorage, std::map< std::string, Belle2::TRGCDCJLUT * > &mLutStorage)
Calculate r * phi ?
Definition: HoughFinder.cc:467
static int level(void)
returns the debug level.
Definition: Debug.cc:67
std::vector< const TRGCDCWireHit * > hits(void) const
returns a list of TRGCDCWireHit.
Definition: TRGCDC.cc:1703
static void leaveStage(const std::string &stageName)
Declare that you leave a stage.
Definition: Debug.cc:34
void findPeaks(const TRGCDCHoughPlaneMulti2 &hp, const unsigned threshold, std::vector< std::vector< unsigned >> &peaks) const
do peak finding. Kaiyu's version using p1p2Methode.
Definition: PeakFinder.cc:478
void registerPattern(unsigned layerId, unsigned id)
registers a pattern..
unsigned nCells(void) const
returns # of cells.
Definition: Layer.h:191
void entryVhdlCode()
Function to print entry VHDL code.
Definition: JSignalData.cc:195
const TRGCDCSegment & segment(void) const
returns a pointer to a track segment.
Definition: SegmentHit.cc:78
void signalsVhdlCode()
Function to print definition of signal VHDL code.
Definition: JSignalData.cc:178
TRGPoint2D position(unsigned x, unsigned y) const
returns position in Hough plain for a cell (x, y)..
void setVhdlOutputFile(const std::string &)
Sets the filename for VHDL output.
Definition: JSignalData.cc:45
void vote(float rx, float ry, int charge, unsigned layerId, int weight=1)
Voting.
void buffersVhdlCode()
Function to print buffer VHDL code.
Definition: JSignalData.cc:150
void setPrintVhdl(bool)
Sets if to print VHDL output.
Definition: JSignalData.cc:50
unsigned localId(void) const
returns local id in a layer.
Definition: Cell.h:204
static TRGCDCJSignal comp(TRGCDCJSignal const &lhs, const std::string &operate, TRGCDCJSignal const &rhs)
Compare two signals.
Definition: JSignal.cc:1169
Abstract base class for different kinds of events.