FairRoot/PandaRoot
PndTrkTrackFinder.cxx
Go to the documentation of this file.
1 //
3 // PndTrkTrackFinder
4 //
5 // Class for secondary track pattern recognition
6 //
7 // authors: Lia Lavezzi - University of Torino (2015)
8 //
10 
11 #include "PndTrkTrackFinder.h"
12 
13 // stt
14 #include "PndSttHit.h"
15 #include "PndSttTube.h"
16 #include "PndSttMapCreator.h"
17 // sds
18 #include "PndSdsHit.h"
19 // track(cand)
20 #include "PndTrackCand.h"
21 #include "PndTrackCandHit.h"
22 #include "PndTrack.h"
23 
24 #include "PndTrkConformalHit.h"
25 #include "PndTrkConformalHitList.h"
27 #include "PndTrkTools.h"
28 #include "PndTrkSkewHit.h"
29 #include "PndTrkFitter.h"
30 // fairroot
31 #include "FairRootManager.h"
32 #include "FairRunAna.h"
33 #include "FairRuntimeDb.h"
34 // ROOT
35 #include "TClonesArray.h"
36 #include "TVector3.h"
37 #include "TArc.h"
38 #include "TLine.h"
39 #include "TMarker.h"
40 #include "TSpectrum2.h"
41 #include "TSpectrum.h"
42 #include "TStopwatch.h"
43 #include "TH3D.h"
44 #include "TMinuit.h"
45 // tracking
46 #include "PndTrkClusterList.h"
47 #include "PndTrkTrackList.h"
48 #include "PndTrkClean.h"
49 #include "PndTrkNeighboringMap.h"
50 #include "PndTrkIndivisibleHit.h"
51 
52 #include <iostream>
53 
54 using namespace std;
55 
56 // this is the function used for the fit
57 // par: vector with the fit parameters
59 {
60  double value=(par[0] * x - y + par[1]) / TMath::Sqrt(par[0] * par[0] + 1);
61  return value;
62 }
63 
64 
65 void Chi2Calculation(Int_t &, Double_t *, Double_t &f, Double_t *par, Int_t ) //npar gin iflag//[R.K.03/2017] unused variable(s)
66 {
67 
68 
69  TMatrixT<Double_t> *objtofit = (TMatrixT<Double_t> *) gMinuit->GetObjectFit();
70 
71  Double_t chi2 = 0;
72  Int_t hitcounter = objtofit->GetNrows();
73 
74  for (Int_t ihit = 0; ihit < hitcounter; ihit++)
75  {
76  double r_reco = fit_distance(objtofit[0][ihit][0], objtofit[0][ihit][1], par);
77  double delta = (objtofit[0][ihit][2] - r_reco)/objtofit[0][ihit][3];
78 
79  cout << "reco iso " << r_reco << endl;
80  cout << "drift " << objtofit[0][ihit][2] << endl;
81  cout << "delta " << delta << endl;
82  chi2 += delta * delta;
83  }
84  f = chi2;
85  return;
86 }
87 
88 void Chi2Calculation2(Int_t &, Double_t *, Double_t &f, Double_t *par, Int_t ) //npar gin iflag//[R.K.03/2017] unused variable(s)
89 {
90 
91  TMatrixT<Double_t> *objtofit = (TMatrixT<Double_t> *) gMinuit->GetObjectFit();
92 
93  Double_t chi2 = 0;
94  Int_t hitcounter = objtofit->GetNrows();
95 
96  for (Int_t ihit = 0; ihit < hitcounter; ihit++)
97  {
98 
99  double delta = TMath::Sqrt((objtofit[0][ihit][0] - par[0])*(objtofit[0][ihit][0] - par[0])+(objtofit[0][ihit][1] - par[1])*(objtofit[0][ihit][1] - par[1])) - par[2]+ par[3] * objtofit[0][ihit][2];
100  if(objtofit[0][ihit][2] == 0) chi2 += (delta * delta * 12.);
101  else chi2 += (delta*delta)/(pow(objtofit[0][ihit][3],2));
102  }
103  f = chi2;
104  return;
105 }
106 
107 Bool_t PndTrkTrackFinder::MinuitFit(PndTrkCluster *cluster, double mstart, double qstart, double &fitm, double&fitq) {
108 
109  if(fDisplayOn) {
110  display->cd(1);
111  Refresh();
112  }
113 
114  TMinuit minimizer;
115  minimizer.SetPrintLevel(-1);
116 
117  // set the object to be fitted: ................
118  // TMatrixT<Double_t> [x][y][r][err_r]
119  TMatrixT<Double_t> fitvect;
120 
121  int nofhits = 0;
122  for(int ihit = 0; ihit < cluster->GetNofHits(); ihit++)
123  {
124  PndTrkHit *hit = cluster->GetHit(ihit);
125  if(hit == fRefHit) continue;
126  if(hit->IsSttSkew()) continue;
127  nofhits++;
128  }
129  fitvect.ResizeTo(nofhits, 4); // x y r errr
130 
131  int counter = 0;
132  for(int ihit = 0; ihit < cluster->GetNofHits(); ihit++)
133  {
134  PndTrkHit *hit = cluster->GetHit(ihit);
135  if(hit == fRefHit) continue;
136  if(hit->IsSttSkew()) continue;
137 
138  PndTrkConformalHit chit = conform->GetConformalHit(hit);
139  PndTrkConformalHit chitstt = conform->GetConformalSttHit(hit);
140  double sigma = 1e-5;
141  if(hit->IsSttParallel()) {
142  sigma = chitstt.GetIsochrone(); // 0.1; // CHECK
143 
144  fitvect[counter][0] = chitstt.GetPosition().X();
145  fitvect[counter][1] = chitstt.GetPosition().Y();
146  fitvect[counter][2] = chitstt.GetIsochrone();
147  fitvect[counter][3] = sigma;
148  }
149  else {
150  fitvect[counter][0] = chit.GetPosition().X();
151  fitvect[counter][1] = chit.GetPosition().Y();
152  fitvect[counter][2] = 0.;
153  fitvect[counter][3] = sigma;
154  }
155  counter++;
156 
157  if(fDisplayOn) {
158  display->cd(1);
159  TMarker *mrk = new TMarker(hit->GetPosition().X(), hit->GetPosition().Y(), 6);
160  mrk->SetMarkerColor(kRed);
161  mrk->Draw("SAME");
162 
163  display->cd(2);
164  TMarker *mrk2 = new TMarker(chit.GetPosition().X(), chit.GetPosition().Y(), 6);
165  mrk2->SetMarkerColor(kRed);
166  mrk2->Draw("SAME");
167 
168 
169  display->Update();
170  display->Modified();
171  }
172  }
173  if(nofhits != counter) fitvect.ResizeTo(counter, 4); // x y r errr
174  //.....................
175 
176  minimizer.SetFCN(Chi2Calculation);
177  // minimizer.SetErrorDef(1); // ???
178 
179  minimizer.DefineParameter(0, "m", mstart, 0.1, -3000., 3000.); // ???
180  minimizer.DefineParameter(1, "q", qstart, 0.1, -3000., 3000.); // ??? LIMITS ???
181 
182  minimizer.SetObjectFit(&fitvect);
183  minimizer.SetPrintLevel();
184 
185  minimizer.SetMaxIterations(500);
186  minimizer.Migrad();
187 
188  Double_t results[3], errors[3]; //chisquare, //[R.K. 01/2017] unused variable
189  minimizer.GetParameter(0, results[0], errors[0]);
190  minimizer.GetParameter(1, results[1], errors[1]);
191 
192  cout << "fitm: " << results[0] << endl;
193  cout << "fitq: " << results[1] << endl;
194 
195 
196  if(fitm == 0) return kFALSE;
197 
198  fitm = results[0];
199  fitq = results[1];
200 
201  // // cout << "previous " << xc << " " << yc << " " << R << endl;
202 // FromConformalToRealTrack(fitm, fitq, xc, yc, R);
203 // // cout << "now " << xc << " " << yc << " " << R << endl;
204 
205 // if(fDisplayOn) {
206 // display->cd(2);
207 // cout << "wanna see the line?" << endl;
208 // TLine *line = new TLine(-10.07, fitq + fitm * (-10.07), 10.07, fitq + fitm * (10.07));
209 // line->SetLineColor(2);
210 // line->Draw("SAME");
211 // char goOnChar;
212 // display->Update();
213 // display->Modified();
214 // cin >> goOnChar;
215 // }
216 
217  return kTRUE;
218 }
219 
220 Bool_t PndTrkTrackFinder::MinuitFit2(PndTrkCluster *cluster, double xstart, double ystart, double rstart, double &xc, double&yc, double &R, double &sign) {
221 
222  if(fDisplayOn) {
223  display->cd(1);
224  Refresh();
225  }
226 
227  TMinuit minimizer;
228  minimizer.SetPrintLevel(-1);
229 
230  // set the object to be fitted: ................
231  // TMatrixT<Double_t> [x][y][r][err_r]
232  TMatrixT<Double_t> fitvect;
233 
234  int nofhits = 0;
235  for(int ihit = 0; ihit < cluster->GetNofHits(); ihit++)
236  {
237  PndTrkHit *hit = cluster->GetHit(ihit);
238  if(hit == fRefHit) continue;
239  if(hit->IsSttSkew()) continue;
240  nofhits++;
241  }
242  fitvect.ResizeTo(nofhits, 4); // x y r errr
243 
244  int counter = 0;
245  for(int ihit = 0; ihit < cluster->GetNofHits(); ihit++)
246  {
247  PndTrkHit *hit = cluster->GetHit(ihit);
248  if(hit == fRefHit) continue;
249  if(hit->IsSttSkew()) continue;
250 
251  double sigma = 1e-5;
252  if(hit->IsSttParallel()) {
253  sigma = hit->GetIsochrone(); // 0.1; // CHECK
254 
255  fitvect[counter][0] = hit->GetPosition().X();
256  fitvect[counter][1] = hit->GetPosition().Y();
257  fitvect[counter][2] = hit->GetIsochrone();
258  fitvect[counter][3] = sigma;
259  }
260  else {
261  fitvect[counter][0] = hit->GetPosition().X();
262  fitvect[counter][1] = hit->GetPosition().Y();
263  fitvect[counter][2] = 0.;
264  fitvect[counter][3] = sigma;
265  }
266  counter++;
267 
268  if(fDisplayOn) {
269  display->cd(1);
270  TMarker *mrk = new TMarker(hit->GetPosition().X(), hit->GetPosition().Y(), 6);
271  mrk->SetMarkerColor(kRed);
272  mrk->Draw("SAME");
273 
274  display->Update();
275  display->Modified();
276  }
277  }
278  if(nofhits != counter) fitvect.ResizeTo(counter, 4); // x y r errr
279  //.....................
280 
281  minimizer.SetFCN(Chi2Calculation2);
282  // minimizer.SetErrorDef(1); // ???
283 
284  minimizer.DefineParameter(0, "x", xstart, 0.1, -3000., 3000.); // ???
285  minimizer.DefineParameter(1, "y", ystart, 0.1, -3000., 3000.); // ??? LIMITS ???
286  minimizer.DefineParameter(2, "R", rstart, 0.1, 0., 3000.); // ??? LIMITS ???
287  minimizer.DefineParameter(3, "sign", 0, 1, -1, 1); // ??? LIMITS ???
288 
289  minimizer.SetObjectFit(&fitvect);
290  minimizer.SetPrintLevel();
291 
292  minimizer.SetMaxIterations(500);
293  minimizer.Migrad();
294 
295  Double_t results[4], errors[4]; //chisquare, //[R.K. 01/2017] unused variable
296  minimizer.GetParameter(0, results[0], errors[0]);
297  minimizer.GetParameter(1, results[1], errors[1]);
298  minimizer.GetParameter(2, results[2], errors[2]);
299  minimizer.GetParameter(3, results[3], errors[3]);
300 
301  cout << "xc: " << results[0] << endl;
302  cout << "yc: " << results[1] << endl;
303  cout << "R: " << results[2] << endl;
304  cout << "sign: " << results[3] << endl;
305 
306 
307  // if( == 0) return kFALSE;
308 
309  xc = results[0];
310  yc = results[1];
311  R = results[2];
312  sign = results[3];
313 
314  // // cout << "previous " << xc << " " << yc << " " << R << endl;
315 // FromConformalToRealTrack(fitm, fitq, xc, yc, R);
316 // // cout << "now " << xc << " " << yc << " " << R << endl;
317 
318 // if(fDisplayOn) {
319 // display->cd(2);
320 // cout << "wanna see the line?" << endl;
321 // TLine *line = new TLine(-10.07, fitq + fitm * (-10.07), 10.07, fitq + fitm * (10.07));
322 // line->SetLineColor(2);
323 // line->Draw("SAME");
324 // char goOnChar;
325 // display->Update();
326 // display->Modified();
327 // cin >> goOnChar;
328 // }
329 
330  return kTRUE;
331 }
332 
333 // ----- Default constructor -------------------------------------------
334 PndTrkTrackFinder::PndTrkTrackFinder() : FairTask("secondary track finder", 0), fDisplayOn(kFALSE), fPersistence(kTRUE), fUseMVDPix(kTRUE), fUseMVDStr(kTRUE), fUseSTT(kTRUE), fUseSCIT(kTRUE), fUseGEM(kTRUE), fSecondary(kFALSE), fInitDone(kFALSE), fMvdPix_RealDistLimit(1000), fMvdStr_RealDistLimit(1000), fStt_RealDistLimit(1000), fMvdPix_ConfDistLimit(1000), fMvdStr_ConfDistLimit(1000), fStt_ConfDistLimit(1000), fUmin(-0.07), fUmax(0.07), fVmin(-0.07), fVmax(0.07), fRmin(-1.5), fRmax(1.5), fThetamin(0), fThetamax(180), fRefHit(NULL), fDelPrim(kFALSE), fNofPrimaries(0) {
335  sprintf(fSttBranch,"STTHit");
336  sprintf(fMvdPixelBranch,"MVDHitsPixel");
337  sprintf(fMvdStripBranch,"MVDHitsStrip");
338  sprintf(fSciTBranch,"SciTHit");
339  sprintf(fGemBranch,"GEMHit");
341 }
342 
343 PndTrkTrackFinder::PndTrkTrackFinder(int verbose) : FairTask("secondary track finder", verbose), fDisplayOn(kFALSE), fPersistence(kTRUE), fUseMVDPix(kTRUE), fUseMVDStr(kTRUE), fUseSTT(kTRUE), fUseSCIT(kTRUE), fUseGEM(kTRUE), fSecondary(kFALSE), fInitDone(kFALSE), fMvdPix_RealDistLimit(1000), fMvdStr_RealDistLimit(1000), fStt_RealDistLimit(1000), fMvdPix_ConfDistLimit(1000), fMvdStr_ConfDistLimit(1000), fStt_ConfDistLimit(1000), fUmin(-0.07), fUmax(0.07), fVmin(-0.07), fVmax(0.07), fRmin(-1.5), fRmax(1.5), fThetamin(0), fThetamax(180), fRefHit(NULL), fDelPrim(kFALSE), fNofPrimaries(0) {
344  sprintf(fSttBranch,"STTHit");
345  sprintf(fMvdPixelBranch,"MVDHitsPixel");
346  sprintf(fMvdStripBranch,"MVDHitsStrip");
347  sprintf(fSciTBranch,"SciTHit");
348  sprintf(fGemBranch,"GEMHit");
350 }
351 
352 // -------------------------------------------------------------------------
353 
354 // ----- Destructor ----------------------------------------------------
356 
357  delete fSttPointArray;
358  delete fSttHitArray;
359  delete fMvdPixelHitArray;
360  delete fMvdStripHitArray;
361  delete fSciTHitArray;
362  delete fGemHitArray;
363  delete fTrackArray;
364  delete fTrkTrackArray;
365  delete fTrackCandArray;
366  delete fTubeArray;
367 
368  delete fSttParameters;
369  delete fMapper;
370 
371  delete stthitlist;
372  delete mvdpixhitlist;
373  delete mvdstrhitlist;
374  delete scithitlist;
375  delete gemhitlist;
376 
377  delete legendre;
378 
379  delete conform;
380  delete fConformalHitList;
381  delete tools;
382 
383  delete fRefHit;
384 
385  // delete fFoundPeaks;
386 
387  delete fTimer;
388 
389  delete fFitter;
390  delete fHitMap;
391 
392  delete hxy;
393  delete hxz;
394  delete hzphi;
395  delete display;
396  delete huv;
397 
398 }
399 // -------------------------------------------------------------------------
400 
401 
402 
403 // ----- Public method Init --------------------------------------------
405 
406  fEventCounter = 0;
407 
408  fMvdPix_RealDistLimit = 0.5; // CHECK limits
409  fMvdStr_RealDistLimit = 0.5; // CHECK limits
410  fStt_RealDistLimit = 1.5 * 0.5; // CHECK limits
411  fMvdPix_ConfDistLimit = 0.003; // CHECK limits
412  fMvdStr_ConfDistLimit = 0.003; // CHECK limits
413  fStt_ConfDistLimit = 0.001; // CHECK limits
414  if(fSecondary) {
415  fMvdPix_RealDistLimit = 1.; // CHECK limits
416  fMvdStr_RealDistLimit = 1.; // CHECK limits
417  fMvdPix_ConfDistLimit = 0.007; // CHECK limits
418  fMvdStr_ConfDistLimit = 0.007; // CHECK limits
419  }
420 
421 
422  // Get RootManager
423  FairRootManager* ioman = FairRootManager::Instance();
424  if ( ! ioman ) {
425  cout << "-E- PndTrkTrackFinder::Init: "
426  << "RootManager not instantiated, return!" << endl;
427  return kFATAL;
428  }
429 
430  // -- HITS -------------------------------------------------
431  //
432  // STT
433  fSttHitArray = (TClonesArray*) ioman->GetObject(fSttBranch);
434  if ( ! fSttHitArray ) {
435  cout << "-W- PndTrkTrackFinder::Init: "
436  << "No STTHit array, return!" << endl;
437  return kERROR;
438  }
439  //
440  // MVD PIXEL
441  fMvdPixelHitArray = (TClonesArray*) ioman->GetObject(fMvdPixelBranch);
442  if ( !fMvdPixelHitArray){
443  std::cout << "-W- PndTrkTrackFinder::Init: " << "No MVD Pixel hitArray, return!" << std::endl;
444  return kERROR;
445  }
446  //
447  // MVD STRIP
448  fMvdStripHitArray = (TClonesArray*) ioman->GetObject(fMvdStripBranch);
449  if ( !fMvdStripHitArray){
450  std::cout << "-W- PndTrkTrackFinder::Init: " << "No MVD Strip hitArray, return!" << std::endl;
451  return kERROR;
452  }
453  //
454  // SciT
455  fSciTHitArray = (TClonesArray*) ioman->GetObject(fSciTBranch);
456  if ( !fSciTHitArray){
457  std::cout << "-W- PndTrkTrackFinder::Init: " << "No SciT hitArray, return!" << std::endl;
458  return kERROR;
459  }
460  //
461  // GEM
462  fGemHitArray = (TClonesArray*) ioman->GetObject(fGemBranch);
463  if ( !fGemHitArray){
464  std::cout << "-W- PndTrkTrackFinder::Init: " << "No GEM hitArray, return!" << std::endl;
465  return kERROR;
466  }
467 
468  if(fDelPrim == kTRUE) fPrimaryTrackArray = (TClonesArray*) ioman->GetObject("SttMvdGemTrack");
469 
470  fTrackArray = new TClonesArray("PndTrack");
471  fTrkTrackArray = new TClonesArray("PndTrkTrack");
472  fTrackCandArray = new TClonesArray("PndTrackCand");
473  ioman->Register("Track", "pr", fTrackArray, fPersistence); // CHECK
474  ioman->Register("TrkTrack", "pr", fTrkTrackArray, fPersistence); // CHECK
475  ioman->Register("TrackCand", "pr", fTrackCandArray, fPersistence); // CHECK
476 
477 
478  // ---------------------------------------- maps of STT tubes
481  // ---------------------------------------------------- end map
482 
483  if(fDisplayOn) {
484  display = new TCanvas("display", "display", 0, 0, 800, 800); // CHECK
485  display->Divide(2, 2);
486  }
487 
489 
491 
492  tools = new PndTrkTools();
495  fTimer = new TStopwatch();
496 
497  fCluster = new PndTrkCluster();
500  fSkewCluster = new PndTrkCluster();
502  fTrackList = new PndTrkTrackList();
504 
506 
507  // fLineHisto = new TH2F("fLineHisto", "hl", 720, -360, 360, 8000, -400, 400);
508  fLineHisto = new TH2F("fLineHisto", "hl", 360, -360, 360, 500, -400, 400);
509 
515 
516  hxy = NULL;
517  huv = NULL;
518  hzphi = NULL;
519 
521 
522  return kSUCCESS;
523 
524 }
525 
526 // -------------------------------------------------------------------------
527 
529  FairRuntimeDb* rtdb = FairRunAna::Instance()->GetRuntimeDb();
530  fSttParameters = (PndGeoSttPar*) rtdb->getContainer("PndGeoSttPar");
531 }
532 
533 // -------------------------------------------------------------------------
534 
535 
537 
538 // stthitlist = new PndTrkSttHitList(fTubeArray);
539 // mvdpixhitlist = new PndTrkSdsHitList(MVDPIXEL);
540 // mvdstrhitlist = new PndTrkSdsHitList(MVDSTRIP);
541 // scithitlist = new PndTrkSciTHitList();
542 // gemhitlist = new PndTrkGemHitList();
543 
544 // stthitlist->Clear();
545 // mvdpixhitlist->Clear();
546 // mvdstrhitlist->Clear();
547 // gemhitlist->Clear();
548 // scithitlist->Clear();
549 
550  std::map< int, std::vector< int > > det_to_hitids;
551  if(fDelPrim) {
552  fNofPrimaries = RecreateHitArrays(det_to_hitids);
553  cout << fNofPrimaries << " --->" << det_to_hitids.size() << endl;
554  }
555 
556  if(fUseSTT) {
557  stthitlist->AddTCA(FairRootManager::Instance()->GetBranchId(fSttBranch), fSttHitArray);
558  std::map< int, bool > primaries = PrimaryCheck(FairRootManager::Instance()->GetBranchId(fSttBranch), det_to_hitids);
559  for(size_t ihit = 0; ihit < primaries.size(); ihit++) {
560  if(primaries[ihit] == true) continue;
562  stthitlist->RemoveHit(hit);
563  }
565  }
566 
567  if(fUseMVDPix) {
568  mvdpixhitlist->AddTCA(FairRootManager::Instance()->GetBranchId(fMvdPixelBranch), fMvdPixelHitArray);
569  std::map< int, bool > primaries = PrimaryCheck(FairRootManager::Instance()->GetBranchId(fMvdPixelBranch), det_to_hitids);
570  for(size_t ihit = 0; ihit < primaries.size(); ihit++) {
571  if(primaries[ihit] == true) continue;
573  mvdpixhitlist->RemoveHit(hit);
574  }
576  }
577 
578  if(fUseMVDStr) {
579  mvdstrhitlist->AddTCA(FairRootManager::Instance()->GetBranchId(fMvdStripBranch), fMvdStripHitArray);
580  std::map< int, bool > primaries = PrimaryCheck(FairRootManager::Instance()->GetBranchId(fMvdStripBranch), det_to_hitids);
581  for(size_t ihit = 0; ihit < primaries.size(); ihit++) {
582  if(primaries[ihit] == true) continue;
584  mvdstrhitlist->RemoveHit(hit);
585  }
587  }
588 
589  if(fUseSCIT) {
590  scithitlist->AddTCA(FairRootManager::Instance()->GetBranchId(fSciTBranch), fSciTHitArray);
591 // std::map< int, bool > primaries = PrimaryCheck(FairRootManager::Instance()->GetBranchId(fSciTBranch), det_to_hitids);
592 // for(int ihit = 0; ihit < primaries.size(); ihit++) {
593 // if(primaries[ihit] == true) continue;
594 // PndTrkHit *hit = scithitlist->GetHitByID(ihit);
595 // scithitlist->RemoveHit(hit);
596 // }
598  }
599 
600  if(fUseGEM) {
601  // gemhitlist->AddTCA(FairRootManager::Instance()->GetBranchId(fGemBranch), fGemHitArray);
602  std::map< int, bool > hitidTousability = fCombiFinder->CombinatorialSuppression();
603  gemhitlist->AddNonCombiHits(FairRootManager::Instance()->GetBranchId(fGemBranch), fGemHitArray, hitidTousability);
604 
605  std::map< int, bool > primaries = PrimaryCheck(FairRootManager::Instance()->GetBranchId(fGemBranch), det_to_hitids);
606  for(size_t ihit = 0; ihit < primaries.size(); ihit++) {
607  if(primaries[ihit] == true) continue;
609  if(hit) gemhitlist->RemoveHit(hit);
610  }
612  }
613 
615  fFoundPeaks.clear();
616 
617  fInitDone = kTRUE;
618  // stthitlist->PrintSectors();
619 
620  // cout << "number of stt hits " << stthitlist->GetNofHits() << endl;
621  // cout << "number of mvdpix hits " << mvdpixhitlist->GetNofHits() << endl;
622  // cout << "number of mvdstr hits " << mvdstrhitlist->GetNofHits() << endl;
623  // cout << "number of scit hits " << scithitlist->GetNofHits() << endl;
624  // cout << "number of gem hits " << gemhitlist->GetNofHits() << endl;
625 
626 }
627 
628 
629 void PndTrkTrackFinder::Exec(Option_t*) {
630  // ############## I N I T I A L I Z A T I O N S ##############
631  fTrackArray->Delete();
632  fTrkTrackArray->Delete();
633  fTrackCandArray->Delete();
634  if(fVerbose > 0) cout << "PndTrkTrackFinder:: *********************** " << fEventCounter << " ***********************" << endl;
635  // fDisplayOn = kTRUE;
636  fEventCounter++;
637  // initialize -----~~~~~-----~~~~~-----~~~~~-----~~~~~-----~~~~~-----~~~~~-----~~~~
638  Initialize();
639  if(fVerbose > 1)
640  {
641  cout << "number of stt hits " << fSttHitArray->GetEntriesFast() << endl;
642  cout << "number of mvdpix hits " << fMvdPixelHitArray->GetEntriesFast() << endl;
643  cout << "number of mvdstr hits " << fMvdStripHitArray->GetEntriesFast() << endl;
644  cout << "number of scit hits " << fSciTHitArray->GetEntriesFast() << endl;
645  cout << "number of gem hits " << fGemHitArray->GetEntriesFast() << endl;
646  }
647 
648 
649  if(fSttHitArray->GetEntriesFast() > 200) { // CHECK
650  fEventCounter++;
651  // cout << "STT hits " << fSttHitArray->GetEntriesFast() << endl;
652  Reset();
653  return;
654  }
655 
656 
657  // initialize display -----~~~~~-----~~~~~-----~~~~~-----~~~~~-----~~~~~-----~~~~~-
658  if(fDisplayOn) {
659  Refresh();
660  char goOnChar;
661  display->Update();
662  display->Modified();
663  cout << " STARTING" << endl;
664  cin >> goOnChar;
665  display->Update();
666  display->Modified();
667  }
668 
669  // initialize hit map -----~~~~~-----~~~~~-----~~~~~-----~~~~~-----~~~~~-----~~~~~-
670  fHitMap->Clear();
671  FillHitMap();
672 
673  // ##########################################################
674 
675  // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
676  // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
677  // L OOO N N GGG
678  // L O O NN N G
679  // L O O N N N G GG
680  // L O O N NN G G
681  // LLLLL OOO N N GGG
682 
683  // fDisplayOn = kFALSE;
684  PndTrkHit *stthit = NULL;
685  TObjArray indiv;
686  // calculate the indivisible parallel hits and
687  // their center of mass
688  // std::vector< PndTrkIndivisibleHit > listofindhits;
689  double numx, numy, den;
690  for(int ihit = 0; ihit < stthitlist->GetNofHits(); ihit++) {
691  stthit = stthitlist->GetHit(ihit);
692  if(stthit->IsSttSkew()) continue;
693  numx = stthit->GetPosition().X() * stthit->GetIsochrone();
694  numy = stthit->GetPosition().Y() * stthit->GetIsochrone();
695  den = stthit->GetIsochrone();
696  indiv = fHitMap->GetIndivisiblesToHit(stthit);
697  // cout << "--------------------------- indiv to stthit " << ihit << " " << indiv.GetEntriesFast() << " " << stthit->GetTubeID() << endl;
698  // cout << stthit->GetPosition().X() << " " << stthit->GetPosition().Y() << endl;
699  int nind = indiv.GetEntriesFast();
700  if(nind == 0) continue;
701 
702  TArrayI indhitids(nind + 1);
703  indhitids[0] = stthit->GetHitID();
704  int counter = 1;
705  for(int jhit = 0; jhit < nind; jhit++) {
706  PndTrkHit *stthit2 = (PndTrkHit*) indiv.At(jhit);
707  if(stthit2->IsSttSkew()) continue;
708  numx += stthit2->GetPosition().X() * stthit2->GetIsochrone();
709  numy += stthit2->GetPosition().Y() * stthit2->GetIsochrone();
710  den += stthit2->GetIsochrone();
711  indhitids[counter] = stthit2->GetHitID();
712  // cout << counter << " " << stthit2->GetPosition().X() << " " << stthit2->GetPosition().Y() << " " << stthit2->GetIsochrone() << " tube " << stthit2->GetTubeID() << endl;
713  counter++;
714  }
715  numx/=den;
716  numy/=den;
717 
718  // create combined hit
719  TVector3 indpos(numx, numy, 0.);
720  // cout << fIndivisibleHitList->GetNofHits() << " num.den " << numx << " " << numy << " " << den << endl;
721  PndTrkIndivisibleHit indhit(indhitids, indpos);
722 
723  fIndivisibleHitList->AddHit(&indhit);
724  }
725 
726  // cout << "nof indivisibles " << fIndivisibleHitList->GetNofHits() << endl;
727  if(fDisplayOn) {
728  for(int ihit = 0; ihit < fIndivisibleHitList->GetNofHits(); ihit++) {
730  // cout << "indhit " << indhit->GetPosition().X() << " " << indhit->GetPosition().Y() << " " << indhit->GetSector() << endl;
731  indhit->Draw(kMagenta);
732  }
733  display->Update();
734  display->Modified();
735  char goOnChar;
736  cin >> goOnChar;
737  }
738 
739 
740 
741  // +++++++++++++++++++++++++++++
742 
743  std::map< int, std::vector< int > > maplay2hits;
744  PndTrkHit *hit = NULL;
745  for(int ihit = 0; ihit < stthitlist->GetNofHits(); ihit++) {
746  hit = stthitlist->GetHit(ihit);
747  PndSttTube *tube = (PndSttTube*) fTubeArray->At(hit->GetTubeID());
748  int layerID = tube->GetLayerID();
749  std::map< int, std::vector< int > >::iterator it = maplay2hits.begin();
750  it = maplay2hits.find(layerID);
751  if(it == maplay2hits.end()) {
752  std::vector< int > hits;
753  hits.push_back(ihit);
754  maplay2hits[layerID] = hits;
755  // maplay2hits.insert(std::pair<int, std::vector<int> >(layerID, hits));
756  std::vector< int > hits2 = maplay2hits[layerID];
757  }
758  else {
759  std::vector< int > hits = maplay2hits[layerID];
760  hits.push_back(ihit);
761  maplay2hits[layerID] = hits;
762  }
763  }
764 
765 
766  for(size_t ilay = 0; ilay < maplay2hits.size(); ilay++) {
767  std::vector< int > hits = maplay2hits[ilay];
768  // cout << "layer " << ilay << " has nof hits " << hits.size() << endl;
769  }
770 
771  std::vector< std::vector < int > > trackcandidates;
772  // first inner - last inner layers ------------------------------------------------------------
773  // couples
774  // CUTS:
775  // xy distance < 10 cm
776  // cosalpha < 0.94
777 
778  std::vector< int > hits0 = maplay2hits[0];
779  for(size_t ihit = 0; ihit < hits0.size(); ihit++) {
780  std::vector< int > hits7 = maplay2hits[7];
781  for(size_t jhit = 0; jhit < hits7.size(); jhit++) {
782  // cut on distance
783  PndTrkHit *hiti = stthitlist->GetHit(hits0[ihit]);
784  PndTrkHit *hitj = stthitlist->GetHit(hits7[jhit]);
785  double distance = hiti->GetXYDistance(hitj);
786  // cout << hits0[ihit] << " and " << hits7[jhit];
787  if(distance > 10) {
788  // cout << " too distant " << distance << endl;
789  continue;
790  }
791 
792  // cut on angle
793  TVector2 hitipos = hiti->GetPosition().XYvector();
794  TVector2 hitjpos = hitj->GetPosition().XYvector();
795  double cosalpha = hitipos * hitjpos / (hitipos.Mod() * hitjpos.Mod());
796  if(cosalpha < 0.94) {
797  // cout << " have bad cosine " << cosalpha << endl;
798  continue;
799  }
800 
801  std::vector< int > couple;
802  couple.push_back(hits0[ihit]);
803  couple.push_back(hits7[jhit]);
804  trackcandidates.push_back(couple);
805  }
806  }
807 
808 
809  // cout << "nof couples " << trackcandidates.size() << endl;
810 // for(int i = 0; i < trackcandidates.size(); i++) {
811 // std::vector< int > driplet = trackcandidates[i];
812 // PndTrkHit *hit0 = stthitlist->GetHit(driplet[0]);
813 // PndTrkHit *hit1 = stthitlist->GetHit(driplet[1]);
814 // TMarker *mrk0 = new TMarker(hit0->GetPosition().X(), hit0->GetPosition().Y(), 21);
815 // mrk0->Draw("SAME");
816 // TMarker *mrk1 = new TMarker(hit1->GetPosition().X(), hit1->GetPosition().Y(), 21);
817 // mrk1->Draw("SAME");
818 // char *goOnChar;
819 
820 // display->Update();
821 // display->Modified();
822 
823 // cin >> goOnChar;
824 // }
825 
826 
827  // cout << endl;
828  // triplets
829  std::vector< std::vector < int > > trackcandidates2;
830  for(size_t ipair = 0; ipair < trackcandidates.size(); ipair++) {
831  std::vector< int > couple = trackcandidates[ipair];
832 
833  std::vector< int > hits16 = maplay2hits[16];
834  for(size_t jhit = 0; jhit < hits16.size(); jhit++) {
835  PndTrkHit *hit0 = stthitlist->GetHit(couple[0]);
836  PndTrkHit *hit1 = stthitlist->GetHit(couple[1]);
837 
838  PndTrkHit *hit16 = stthitlist->GetHit(hits16[jhit]);
839  double distance = hit1->GetXYDistance(hit16);
840  // cout << couple[0] << ", " << couple[1] << " and " << hits16[jhit];
841  if(distance > 15) {
842  // cout << " too distant " << distance << endl;
843  continue;
844  }
845 
846  // cut on angle
847  TVector2 hit1_0pos = hit1->GetPosition().XYvector() - hit0->GetPosition().XYvector();
848  TVector2 hit1_16pos = hit16->GetPosition().XYvector() - hit1->GetPosition().XYvector();
849  double cosalpha = hit1_0pos * hit1_16pos/ (hit1_0pos.Mod() * hit1_16pos.Mod());
850  // cout << "cosalpha " << cosalpha << endl;
851  if(cosalpha < 0.900) {
852  // cout << " have bad cosine " << cosalpha << endl;
853  continue;
854  }
855 
856  // cout << " are fine! " << cosalpha << endl;
857 
858  std::vector< int > triplet;
859  triplet.push_back(couple[0]);
860  triplet.push_back(couple[1]);
861  triplet.push_back(hits16[jhit]);
862 
863  trackcandidates2.push_back(triplet);
864  }
865  }
866  // cout << "nof triplets " << trackcandidates2.size() << endl;
867 // for(int i = 0; i < trackcandidates2.size(); i++) {
868 // std::vector< int > driplet = trackcandidates2[i];
869 // PndTrkHit *hit0 = stthitlist->GetHit(driplet[0]);
870 // PndTrkHit *hit1 = stthitlist->GetHit(driplet[1]);
871 // PndTrkHit *hit2 = stthitlist->GetHit(driplet[2]);
872 
873 // TMarker *mrk0 = new TMarker(hit0->GetPosition().X(), hit0->GetPosition().Y(), 21);
874 // mrk0->Draw("SAME");
875 // TMarker *mrk1 = new TMarker(hit1->GetPosition().X(), hit1->GetPosition().Y(), 21);
876 // mrk1->Draw("SAME");
877 // TMarker *mrk2 = new TMarker(hit2->GetPosition().X(), hit2->GetPosition().Y(), 21);
878 // mrk2->Draw("SAME");
879 
880 // char goOnChar;
881 
882 // display->Update();
883 // display->Modified();
884 
885 // cin >> goOnChar;
886 // }
887 
888  // fourth hit
889  std::vector< std::vector< int > > trackcandidates3;
890  for(size_t iqua = 0; iqua < trackcandidates2.size(); iqua++) {
891  std::vector< int > triplet = trackcandidates2[iqua];
892 
893  //PndTrkHit *hit0 = stthitlist->GetHit(triplet[0]); //[R.K. 03/2017] unused variable
894  PndTrkHit *hit1 = stthitlist->GetHit(triplet[1]);
895  PndTrkHit *hit2 = stthitlist->GetHit(triplet[2]);
896  // cout << "TRIPLET: " << triplet[0] << ", " << triplet[1] << " and " << triplet[2] << endl;
897 
898  std::vector< int > hits20 = maplay2hits[20];
899  for(size_t jhit = 0; jhit < hits20.size(); jhit++) {
900  PndTrkHit *hit20 = stthitlist->GetHit(hits20[jhit]);
901  double distance = hit2->GetXYDistance(hit20);
902  // cout << triplet[0] << ", " << triplet[1] << ", " << triplet[2] << " and " << hits20[jhit];
903  if(distance > 15) {
904  // cout << " too distant " << distance << endl;
905  continue;
906  }
907 
908  // cut on angle
909  TVector2 hit2_1pos = hit2->GetPosition().XYvector() - hit1->GetPosition().XYvector();
910  TVector2 hit2_20pos = hit20->GetPosition().XYvector() - hit1->GetPosition().XYvector();
911  double cosalpha = hit2_1pos * hit2_20pos/ (hit2_1pos.Mod() * hit2_20pos.Mod());
912  if(cosalpha < 0.94) {
913  // cout << " have bad cosine " << cosalpha << endl;
914  continue;
915  }
916 
917  // cout << " are fine! " << cosalpha << endl;
918 
919  std::vector< int > quadriplet;
920  quadriplet.push_back(triplet[0]);
921  quadriplet.push_back(triplet[1]);
922  quadriplet.push_back(triplet[2]);
923  quadriplet.push_back(hits20[jhit]);
924 
925  trackcandidates3.push_back(quadriplet);
926  }
927  }
928  // cout << "nof quadriplets " << trackcandidates3.size() << endl;
929 // for(int i = 0; i < trackcandidates3.size(); i++) {
930 // std::vector< int > driplet = trackcandidates3[i];
931 // PndTrkHit *hit0 = stthitlist->GetHit(driplet[0]);
932 // PndTrkHit *hit1 = stthitlist->GetHit(driplet[1]);
933 // PndTrkHit *hit2 = stthitlist->GetHit(driplet[2]);
934 // PndTrkHit *hit3 = stthitlist->GetHit(driplet[3]);
935 
936 // TMarker *mrk0 = new TMarker(hit0->GetPosition().X(), hit0->GetPosition().Y(), 21);
937 // mrk0->Draw("SAME");
938 // TMarker *mrk1 = new TMarker(hit1->GetPosition().X(), hit1->GetPosition().Y(), 21);
939 // mrk1->Draw("SAME");
940 // TMarker *mrk2 = new TMarker(hit2->GetPosition().X(), hit2->GetPosition().Y(), 21);
941 // mrk2->Draw("SAME");
942 // TMarker *mrk3 = new TMarker(hit3->GetPosition().X(), hit3->GetPosition().Y(), 21);
943 // mrk3->Draw("SAME");
944 
945 // char goOnChar;
946 
947 // display->Update();
948 // display->Modified();
949 
950 // cin >> goOnChar;
951 // }
952 
953 
954 
955  // circle through three points
956  // find the tracks
957  std::vector < std::vector < double > > tracks; // x0, y0, R
958  std::vector< std::vector< int > > trackcandidates4;
959  for(size_t iqua = 0; iqua < trackcandidates3.size(); iqua++) {
960  std::vector< int > quadriplet = trackcandidates3[iqua];
961  PndTrkHit *hit0 = stthitlist->GetHit(quadriplet[0]);
962  PndTrkHit *hit1 = stthitlist->GetHit(quadriplet[1]);
963  PndTrkHit *hit2 = stthitlist->GetHit(quadriplet[2]);
964  PndTrkHit *hit3 = stthitlist->GetHit(quadriplet[3]);
965 
966  double x01, y01, rad1;
967  CircleBy3Points(hit0, hit1, hit2, x01, y01, rad1);
968  double x02, y02, rad2;
969  CircleBy3Points(hit0, hit1, hit3, x02, y02, rad2);
970  double x03, y03, rad3;
971  CircleBy3Points(hit3, hit1, hit2, x03, y03, rad3);
972 
973  double xm = 0, ym = 0, rm = 0;
974  int positive[2] = {0, 0}, negative[2] = {0, 0};
975  if(x01 > 0) positive[0]++;
976  else negative[0]++;
977  if(x02 > 0) positive[0]++;
978  else negative[0]++;
979  if(x03 > 0) positive[0]++;
980  else negative[0]++;
981 
982  if(y01 > 0) positive[1]++;
983  else negative[1]++;
984  if(y02 > 0) positive[1]++;
985  else negative[1]++;
986  if(y03 > 0) positive[1]++;
987  else negative[1]++;
988 
989  bool posit[2] = {false, false};
990  positive[0] > negative[0] ? posit[0] = true : posit[0] = false;
991  positive[1] > negative[1] ? posit[1] = true : posit[1] = false;
992 
993  int count = 0;
994  if(posit[0] == true && x01 > 0) {
995  if(posit[1] == true && y01 > 0) { xm += x01; ym += y01; rm += rad1; count++; }
996  else if(posit[1] == false && y01 < 0) { xm += x01; ym += y01; rm += rad1; count++; }
997  }
998  else if(posit[0] == false && x01 < 0) {
999  if(posit[1] == true && y01 > 0) { xm += x01; ym += y01; rm += rad1; count++; }
1000  else if(posit[1] == false && y01 < 0) { xm += x01; ym += y01; rm += rad1; count++; }
1001  }
1002 
1003  if(posit[0] == true && x02 > 0) {
1004  if(posit[1] == true && y02 > 0) { xm += x02; ym += y02; rm += rad2; count++; }
1005  else if(posit[1] == false && y02 < 0) { xm += x02; ym += y02; rm += rad2; count++; }
1006  }
1007  else if(posit[0] == false && x02 < 0) {
1008  if(posit[1] == true && y02 > 0) { xm += x02; ym += y02; rm += rad2; count++; }
1009  else if(posit[1] == false && y02 < 0) { xm += x02; ym += y02; rm += rad2; count++; }
1010  }
1011 
1012  if(posit[0] == true && x03 > 0) {
1013  if(posit[1] == true && y03 > 0) { xm += x03; ym += y03; rm += rad3; count++; }
1014  else if(posit[1] == false && y03 < 0) { xm += x03; ym += y03; rm += rad3; count++; }
1015  }
1016  else if(posit[0] == false && x03 < 0) {
1017  if(posit[1] == true && y03 > 0) { xm += x03; ym += y03; rm += rad3; count++; }
1018  else if(posit[1] == false && y03 < 0) { xm += x03; ym += y03; rm += rad3; count++; }
1019  }
1020 
1021  xm /= count;
1022  ym /= count;
1023  rm /= count;
1024 
1025  // cout << "pos.neg " << positive << " " << negative << endl;
1026 
1027  double distance0 = fabs(TMath::Sqrt((hit0->GetPosition().X() - xm) * (hit0->GetPosition().X() - xm) + (hit0->GetPosition().Y() - ym) * (hit0->GetPosition().Y() - ym)) - rm);
1028  double distance1 = fabs(TMath::Sqrt((hit1->GetPosition().X() - xm) * (hit1->GetPosition().X() - xm) + (hit1->GetPosition().Y() - ym) * (hit1->GetPosition().Y() - ym)) - rm);
1029  double distance2 = fabs(TMath::Sqrt((hit2->GetPosition().X() - xm) * (hit2->GetPosition().X() - xm) + (hit2->GetPosition().Y() - ym) * (hit2->GetPosition().Y() - ym)) - rm);
1030  double distance3 = fabs(TMath::Sqrt((hit3->GetPosition().X() - xm) * (hit3->GetPosition().X() - xm) + (hit3->GetPosition().Y() - ym) * (hit3->GetPosition().Y() - ym)) - rm);
1031 
1032  // cut on the distance to accept quadriplet hypo
1033  double maxlimit = 1.;
1034  if(fabs(distance0 - hit0->GetIsochrone()) > maxlimit || fabs(distance1 - hit1->GetIsochrone()) > maxlimit || fabs(distance2 - hit2->GetIsochrone()) > maxlimit || fabs(distance3 - hit3->GetIsochrone()) > maxlimit) continue;
1035 
1036 
1037  if(fDisplayOn) {
1038  char goOnChar;
1039  Refresh();
1040 
1041  cout << "circ1 " << x01 << " " << y01 << " " << rad1 << endl;
1042  cout << "circ2 " << x02 << " " << y02 << " " << rad2 << endl;
1043  cout << "circ3 " << x03 << " " << y03 << " " << rad3 << endl;
1044  cout << "circm " << xm << " " << ym << " " << rm << endl;
1045 
1046  TArc *arc01 = new TArc(x01, y01, rad1);
1047  arc01->SetFillStyle(0);
1048  arc01->SetLineColor(1);
1049  arc01->Draw("SAME");
1050  TArc *arc02 = new TArc(x02, y02, rad2);
1051  arc02->SetFillStyle(0);
1052  arc02->SetLineColor(2);
1053  arc02->Draw("SAME");
1054  TArc *arc03 = new TArc(x03, y03, rad3);
1055  arc03->SetFillStyle(0);
1056  arc03->SetLineColor(3);
1057  arc03->Draw("SAME");
1058 
1059  TMarker *mrk1 = new TMarker(hit0->GetPosition().X(), hit0->GetPosition().Y(), 20);
1060  mrk1->SetMarkerColor(kBlack);
1061  mrk1->Draw("SAME");
1062 
1063  TMarker *mrk2 = new TMarker(hit1->GetPosition().X(), hit1->GetPosition().Y(), 20);
1064  mrk2->SetMarkerColor(kRed);
1065  mrk2->Draw("SAME");
1066 
1067  TMarker *mrk3 = new TMarker(hit2->GetPosition().X(), hit2->GetPosition().Y(), 20);
1068  mrk3->SetMarkerColor(kGreen);
1069  mrk3->Draw("SAME");
1070 
1071  TMarker *mrk4 = new TMarker(hit3->GetPosition().X(), hit3->GetPosition().Y(), 20);
1072  mrk4->SetMarkerColor(kBlue);
1073  mrk4->Draw("SAME");
1074 
1075  TArc *arcm = new TArc(xm, ym, rm);
1076  arcm->SetFillStyle(0);
1077  arcm->SetLineStyle(2);
1078  arcm->SetLineColor(kMagenta);
1079  arcm->Draw("SAME");
1080  display->Update();
1081  display->Modified();
1082 
1083  cout << "hit0: " << distance0 << " " << fabs(distance0 - hit0->GetIsochrone()) << " " << fabs(distance0 - hit0->GetIsochrone())/hit0->GetIsochrone() << " " << distance0/hit0->GetIsochrone() << endl;
1084  cout << "hit1: " << distance1 << " " << fabs(distance1 - hit1->GetIsochrone()) << " " << fabs(distance1 - hit1->GetIsochrone())/ hit1->GetIsochrone() << " " << distance1/hit1->GetIsochrone() <<endl;
1085  cout << "hit2: " << distance2 << " " << fabs(distance2 - hit2->GetIsochrone()) << " " << fabs(distance2 - hit2->GetIsochrone())/ hit2->GetIsochrone() << " " << distance2/hit2->GetIsochrone() <<endl;
1086  cout << "hit3: " << distance3 << " " << fabs(distance3 - hit3->GetIsochrone()) << " " << fabs(distance3 - hit3->GetIsochrone())/ hit3->GetIsochrone() << " " << distance3/hit3->GetIsochrone() <<endl;
1087 
1088  cout << "next quadriplet?" << endl;
1089  cin >> goOnChar;
1090  }
1091 
1092 
1093  std::vector< double > track;
1094  track.push_back(xm);
1095  track.push_back(ym);
1096  track.push_back(rm);
1097 
1098  // suppress identical clones
1099  std::vector< std::vector < double > >::iterator itr = tracks.begin();
1100  itr = std::find(tracks.begin(), tracks.end(), track);
1101  if(itr == tracks.end()) {
1102  // cout << "miss" << endl;
1103 
1104  // request 10 < rm < 2500
1105  // . 10 because it touches layers 0 and 20 -->
1106  // minimum diameter = 20 * 1 cm = 20 cm --> rm > 10
1107  // . 2500 [cm] = 15 [GeV/c] / 0.006
1108  if(rm > 10 && rm < 2500) {
1109  tracks.push_back(track);
1110  trackcandidates4.push_back(quadriplet);
1111  }
1112  }
1113  // else cout << "already" << endl;
1114  }
1115 
1116 
1117  PndTrkClusterList clusterlist;
1118 
1119  // cout << "tracks " << tracks.size() << endl;
1120  for(size_t itrk = 0; itrk < tracks.size(); itrk++) {
1121  std::vector< double > track = tracks[itrk];
1122  double x = track[0];
1123  double y = track[1];
1124  double r = track[2];
1125  // cout << x << " " << y << " " << r << endl;
1140  // find sector
1141  std::vector < int > quadriplet = trackcandidates4[itrk];
1142  PndTrkHit *hit0 = stthitlist->GetHit(quadriplet[0]);
1143  PndSttTube *tube0 = (PndSttTube*) fTubeArray->At(hit0->GetTubeID());
1144  PndTrkHit *hit1 = stthitlist->GetHit(quadriplet[1]);
1145  PndSttTube *tube1 = (PndSttTube*) fTubeArray->At(hit1->GetTubeID());
1146  PndTrkHit *hit2 = stthitlist->GetHit(quadriplet[2]);
1147  PndSttTube *tube2 = (PndSttTube*) fTubeArray->At(hit2->GetTubeID());
1148  PndTrkHit *hit3 = stthitlist->GetHit(quadriplet[3]);
1149  PndSttTube *tube3 = (PndSttTube*) fTubeArray->At(hit3->GetTubeID());
1150 
1151  std::map< int, int > sectorids;
1152  int sec[4];
1153  sec[0] = tube0->GetSectorID();
1154  sec[1] = tube1->GetSectorID();
1155  sec[2] = tube2->GetSectorID();
1156  sec[3] = tube3->GetSectorID();
1157  for(int isec = 0; isec < 4; isec++) {
1158  if(sectorids.find(sec[isec]) == sectorids.end()) sectorids[sec[isec]] = 1;
1159  else sectorids[sec[isec]]++;
1160  // cout << "settori " << sec[0] << " " << sec[1] << " " << sec[2] << " " << sec[3] << endl;
1161 
1162  }
1163 
1164  int tmpsecentries = 0, tmpsec = -1;
1165  for(size_t isec = 0; isec < sectorids.size(); isec++) {
1166  if(tmpsecentries < sectorids[isec]) {
1167  tmpsecentries = sectorids[isec];
1168  tmpsec = isec;
1169  }
1170  }
1171  int sectorID = tmpsec;
1172  // cout << "SECTOR " << sectorID << " " << sectorids.size() << endl;
1173 
1174  // border?
1175  bool border = false;
1176  int othersecID = -1;
1177  for(size_t isec = 0; isec < sectorids.size(); isec++) {
1178  if(sectorids[isec] > 0 && (int)isec != sectorID) {
1179  border = true;
1180  othersecID = isec;
1181  }
1182  }
1183 
1184  // cout << "sector " << sectorID << " at border? " << border << " " << othersecID << endl;
1185 
1186  // === CREATE CLUSTER
1187  // in the same sector or
1188  // nearby if at the limit of two sectors <<<<<<<<<<<<------------------
1189  PndTrkCluster cluster;
1190 
1191  // first of all the 4 hits!
1192  cluster.AddHit(hit0);
1193  cluster.AddHit(hit1);
1194  cluster.AddHit(hit2);
1195  cluster.AddHit(hit3);
1196 
1197  // create cluster depending on fitting
1198  for(int ihit = 0; ihit < stthitlist->GetNofHits(); ihit++) {
1199  hit = stthitlist->GetHit(ihit);
1200  if(hit == hit0 || hit == hit1 || hit == hit2 || hit == hit3) continue;
1201  if(hit->IsSttParallel() == kFALSE) continue;
1202  PndSttTube *tube = (PndSttTube*) fTubeArray->At(hit->GetTubeID());
1203  if(border == false && tube->GetSectorID() != sectorID) continue;
1204  else if(border == true && (tube->GetSectorID() != sectorID && tube->GetSectorID() != othersecID)) continue;
1205 
1206  double distance_hit_center = (hit->GetPosition().XYvector() - TVector2(x, y)).Mod();
1207  double recoiso = fabs(distance_hit_center - r);
1208 
1209  if(recoiso < 1.) cluster.AddHit(hit);
1210 
1211  }
1212  if(fDisplayOn) {
1213  display->cd(1);
1214  cluster.Draw(kBlue);
1215  display->Update();
1216  display->Modified();
1217  char goOnChar;
1218  cout << "want to go on?" << endl;
1219  cin >> goOnChar;
1220  }
1221 
1222 
1223  // get indivisible hits
1224  // only in appropriate sectors
1225  PndTrkCluster indcluster;
1226  // cout << "indivisibles " << fIndivisibleHitList->GetNofHits() << endl;
1227  if(fDisplayOn) {
1228  Refresh();
1229  }
1230  for(int ihit = 0; ihit < fIndivisibleHitList->GetNofHits(); ihit++) {
1232  if(border == false && indhit->GetSector() != sectorID) continue;
1233  else if(border == true && (indhit->GetSector() != sectorID && indhit->GetSector() != othersecID)) continue;
1234 
1235  double distance_hit_center = (indhit->GetPosition().XYvector() - TVector2(x, y)).Mod();
1236  double recoiso = fabs(distance_hit_center - r);
1237  if(recoiso < 1.) {
1238  indcluster.AddHit(indhit);
1239 
1245  }
1246  }
1247  if(fDisplayOn) {
1248  display->Update();
1249  display->Modified();
1250  //char goOnChar; //[R.K. 01/2017] unused variable
1251 // cin >> goOnChar;
1252  }
1253 
1254  // conformal map on last indivisible hit
1255  double tmpdistance = -1;
1256  int tmphitID = -1;
1257  for(int ihit = 0; ihit < indcluster.GetNofHits(); ihit++) {
1258  PndTrkIndivisibleHit *indhit2 = (PndTrkIndivisibleHit*) indcluster.GetHit(ihit);
1259  TVector3 position = indhit2->GetPosition();
1260  if(position.Perp() > tmpdistance) {
1261  tmpdistance = position.Perp();
1262  tmphitID = ihit;
1263  }
1264  }
1265 
1266  if(tmphitID == -1) continue; // CHECK what if there is no indivisible hit??
1267  // cout << "nof indivisible hits " << indcluster.GetNofHits() << " " << tmphitID << endl;
1268  // set up conformal map
1269  fConformalHitList->Clear("C");
1270  Double_t delta = 0, trasl[2] = {0., 0.};
1271  PndTrkHit *refhit = indcluster.GetHit(tmphitID);
1272  ComputeTraAndRot(refhit, delta, trasl);
1273  // cout << refhit << " " << refhit->GetHitID() << " " << delta << " " << trasl[0] << " " << trasl[1] << endl;
1274  conform->SetOrigin(trasl[0], trasl[1], delta);
1276 
1277  // fill conformal hits
1278  Int_t nofconfhits = FillConformalHitList(&cluster);
1279 
1280  // compute conformal plane extremities ----------------------------
1281  fUmin = 1000, fVmin = 1000, fRmin = 1000;
1282  fUmax = -1000, fVmax = -1000, fRmax = -1000;
1283  double rc_of_min, rc_of_max;
1284 
1285  for(int jhit = 0; jhit < fConformalHitList->GetNofHits(); jhit++) {
1287  double u = chit->GetU();
1288  double v = chit->GetV();
1289  double rc = chit->GetIsochrone();
1290  if(rc < 0) rc = 0;
1291  // cout << "conf hit " << jhit << " u, v " << u << " " << v << " " << rc << endl;
1292  u - rc < fUmin ? fUmin = u - rc : fUmin;
1293  v - rc < fVmin ? fVmin = v - rc : fVmin;
1294  u + rc > fUmax ? fUmax = u + rc : fUmax;
1295  v + rc > fVmax ? fVmax = v + rc : fVmax;
1296 
1297  double theta1 = TMath::ATan2(v, u);
1298  double theta2 = theta1 + TMath::Pi();
1299 
1300  double r1 = u * TMath::Cos(theta1) + v * TMath::Sin(theta1);
1301  double r2 = u * TMath::Cos(theta2) + v * TMath::Sin(theta2);
1302 
1303  double rimin, rimax;
1304  r1 < r2 ? (rimin = r1, rimax = r2) : (rimin = r2, rimax = r1);
1305 
1306  rimin < fRmin ? (rc_of_min = rc, fRmin = rimin) : fRmin;
1307  rimax > fRmax ? (rc_of_max = rc, fRmax = rimax) : fRmax;
1308  }
1309 
1310  fRmin -= rc_of_min;
1311  fRmax += rc_of_max;
1312 
1313  // to square the conformal plane
1314  double du = fUmax - fUmin;
1315  double dv = fVmax - fVmin;
1316  double delt = fabs(dv - du)/2.;
1317  du < dv ? (fUmin -= delt, fUmax += delt) : (fVmin -= delt, fVmax += delt);
1318 
1319  if(fDisplayOn) {
1320  DrawGeometryConf(fUmin, fUmax, fVmin, fVmax);
1321  // ----------------------------------------------------------------------
1322  for(int ihit = 0; ihit < nofconfhits; ihit++) {
1324  chit->Draw(kBlack);
1325  }
1326  }
1327 
1328  // ====== REFIT CLUSTER LEGENDRE
1329  double fitm, fitq;
1330  // AnalyticalFit(&cluster, x, y, r, fitm, fitq);
1331  // LEGENDRE ----------------------------------------------------------
1332  legendre->SetUpLegendreHisto(180, 0, 180, 1000, -0.07, 0.07);
1333  // reset the legendre histo for a new legendre fit
1335 
1336  if(fDisplayOn) {
1337  RefreshConf();
1338  DrawGeometryConf(fUmin, fUmax, fVmin, fVmax);
1339  }
1340 
1341  // fill legendre histo with the cluster hits
1342  FillLegendreHisto(&cluster);
1343  std::vector< double > theta_max, r_max;
1344  std::vector < int > content_max;
1345  // get the peak
1346  legendre->ExtractLegendreMaxima(1, theta_max, r_max, content_max);
1347  // from theta/r to line parameters in CONFORMAL plane
1348  double fitm2, fitq2;
1349  legendre->ExtractLineParameters(theta_max[0], r_max[0], fitm2, fitq2);
1350  if(fDisplayOn) {
1351  display->cd(2);
1352  TLine *line = new TLine(-10.07, fitq2 + fitm2 * (-10.07), 10.07, fitq2 + fitm2 * (10.07));
1353  line->Draw("SAME");
1354 
1355  display->cd(3);
1357  display->Update();
1358  display->Modified();
1359  }
1360 
1361  // from line parameters to center/radius in REAL plane
1362  Double_t xc, yc, R;
1363  FromConformalToRealTrack(fitm2, fitq2, xc, yc, R);
1364  // cout << "previous " << x << " " << y << " " << r << endl;
1365  // cout << "\033[1;33m MAXPEAK " << content_max[0] << " XR, YC, R: " << xc << " " << yc << " " << R << "\033[0m" << endl;
1366  bool goodtrack = true;
1367  double distance = TMath::Sqrt((x - xc) * (x - xc) + (y - yc) * (y - yc));
1368  double r_minus_rc = fabs(r - R);
1369 
1370  // cout << "start hit " << ihit << " " << hit->GetHitID() << " " << endsecid << " " << endlayid << endl;
1371  // --------------------------------------------------------------
1372  if(fabs(distance - r_minus_rc) > 2.) { // CHECK limit
1373  double recoisosum = 0;
1374  for(int ihit = 0; ihit < cluster.GetNofHits(); ihit++) {
1375  hit = cluster.GetHit(ihit);
1376  double distance_hit_center = (hit->GetPosition().XYvector() - TVector2(xc, yc)).Mod();
1377  double recoiso = fabs(distance_hit_center - R);
1378  recoisosum += recoiso;
1379  }
1380 
1381  if(recoisosum > 10) goodtrack = false; // CHECK limit
1382  }
1383 
1384  // dont use track which did not
1385  // pass the cuts
1386  if(goodtrack == false) continue;
1387 
1388  if(fDisplayOn) {
1389  //char goOnChar; //[R.K. 01/2017] unused variable
1390  display->cd(1);
1391  TArc *arcm = new TArc(xc, yc, R);
1392  arcm->SetFillStyle(0);
1393  arcm->SetLineColor(kBlue);
1394  arcm->Draw("SAME");
1395  display->Update();
1396  display->Modified();
1397  // cin >> goOnChar;
1398  }
1399 
1400 
1401  // what about adding the mvd hits now? lets do it!
1402  // ... and put mvd pixel hits to conformal plane ---------------
1403  for(int ihit = 0; ihit < mvdpixhitlist->GetNofHits(); ihit++) {
1404  hit = mvdpixhitlist->GetHit(ihit);
1405 
1406  // cout << "border " << border << " " << hit->GetSector() << " " << sectorID << " " << othersecID << endl;
1407  // if(border == false && hit->GetSector() != sectorID) continue;
1408  // else if(border == true && (hit->GetSector() != sectorID && hit->GetSector() != othersecID)) continue;
1409 
1410  if(fabs(hit->GetSector() - sectorID) > 1) continue;
1411  double distance_hit_center = (hit->GetPosition().XYvector() - TVector2(xc, yc)).Mod();
1412  double recoiso = fabs(distance_hit_center - R);
1413  // cout << "recoiso pix " << recoiso << endl;
1414  if(recoiso < 1.) {
1415  cluster.AddHit(hit);
1416  if(fDisplayOn) {
1417  hit->Draw(kOrange);
1418  display->Update();
1419  display->Modified();
1420  }
1422  fConformalHitList->AddHit(&chit);
1423  }
1424  }
1425 
1426  // ... and put mvd strip hits to conformal plane ---------------
1427  for(int ihit = 0; ihit < mvdstrhitlist->GetNofHits(); ihit++) {
1428  hit = mvdstrhitlist->GetHit(ihit);
1429  // if(border == false && hit->GetSector() != sectorID) continue;
1430  // else if(border == true && (hit->GetSector() != sectorID && hit->GetSector() != othersecID)) continue;
1431  if(fabs(hit->GetSector() - sectorID) > 1) continue;
1432 
1433  double distance_hit_center = (hit->GetPosition().XYvector() - TVector2(xc, yc)).Mod();
1434  double recoiso = fabs(distance_hit_center - R);
1435  // cout << "mvdstr recoiso str " << recoiso << endl;
1436  if(recoiso < 1.) {
1437  cluster.AddHit(hit);
1438  if(fDisplayOn) {
1439  hit->Draw(kOrange);
1440  display->Update();
1441  display->Modified();
1442  }
1444  fConformalHitList->AddHit(&chit);
1445  }
1446  }
1447 
1448  // and now: gem time!
1449  for(int ihit = 0; ihit < gemhitlist->GetNofHits(); ihit++) {
1450  hit = gemhitlist->GetHit(ihit);
1451  // if(border == false && hit->GetSector() != sectorID) continue;
1452  // else if(border == true && (hit->GetSector() != sectorID && hit->GetSector() != othersecID)) continue;
1453  if(fabs(hit->GetSector() - sectorID) > 1) continue;
1454  double distance_hit_center = (hit->GetPosition().XYvector() - TVector2(xc, yc)).Mod();
1455  double recoiso = fabs(distance_hit_center - R);
1456  // if(hit->GetPosition().Perp() > CTOUTRADIUS) cout << "recoiso gem " << recoiso << endl;
1457  if(recoiso < 1.5 && hit->GetPosition().Perp() > CTOUTRADIUS) {
1458  cluster.AddHit(hit);
1459  if(fDisplayOn) {
1460  hit->Draw(kOrange);
1461  display->Update();
1462  display->Modified();
1463  }
1464  // PndTrkConformalHit *chit = conform->GetConformalHit(hit);
1465  // conformalhitlist->AddHit(chit);
1466  }
1467  }
1468 
1469 
1470 
1471  // and the scitil? did we forget about that? here it comes...
1472  // ... and put scit hits to conformal plane ------------------------------
1473  // the scitil are far away so give a loose request - 10 cm
1474  // choose however the closest one!
1475  // remember to check the distance from hit20
1476  int tmphit = -1;
1477  tmpdistance = 1000;
1478  for(int ihit = 0; ihit < scithitlist->GetNofHits(); ihit++) {
1479  hit = scithitlist->GetHit(ihit);
1480  if(hit->GetXYDistance(hit3) > 30) continue;
1481  // if(border == false && hit->GetSector() != sectorID) continue;
1482  // else if(border == true && (hit->GetSector() != sectorID && hit->GetSector() != othersecID)) continue;
1483  // if(hit->GetSector() != sectorID) continue;
1484  double distance_hit_center = (hit->GetPosition().XYvector() - TVector2(xc, yc)).Mod();
1485  double recoiso = fabs(distance_hit_center - R);
1486  // cout << "recoiso scitil " << recoiso << " " << hit->GetXYDistance(hit3) << endl;
1487  if(recoiso < 10.) {
1488  if(recoiso < tmpdistance) {
1489  tmphit = ihit;
1490  tmpdistance = recoiso;
1491  }
1492  }
1493  }
1494  // if there is at least one: yuppi!
1495  if(tmphit > -1) {
1496  hit = scithitlist->GetHit(tmphit);
1497  cluster.AddHit(hit);
1498  if(fDisplayOn) {
1499  hit->Draw(kOrange);
1500  cout << "herh" << endl;
1501  char goOnChar;
1502  cin >> goOnChar;
1503  display->Update();
1504  display->Modified();
1505  }
1506  // PndTrkConformalHit *chit = conform->GetConformalHit(hit);
1507  // fConformalHitList->AddHit(chit);
1508  }
1509 
1510 
1511  // // --------------------------
1512  // // if there is a scitil lets use it as seed hit
1513  // // for the conformal map
1514  // if(tmphit > -1) {
1515  // // refhit = scithitlist->GetHit(tmphit);
1516  // fConformalHitList->Reset();
1517  // ComputeTraAndRot(refhit, delta, trasl);
1518  // conform->SetOrigin(trasl[0], trasl[1], delta);
1519  // fConformalHitList->SetConformalTransform(conform);
1520  // // cout << "conformal hits " << fConformalHitList->GetNofHits() << endl;
1521 
1522  // // fill conformal hits
1523  // nofconfhits = FillConformalHitList(&cluster);
1524 
1525  // // compute conformal plane extremities ---------------------------- this must go to a fctn CHECK
1526  // fUmin = 1000, fVmin = 1000, fRmin = 1000;
1527  // fUmax = -1000, fVmax = -1000, fRmax = -1000;
1528  // rc_of_min, rc_of_max;
1529 
1530  // for(int jhit = 0; jhit < fConformalHitList->GetNofHits(); jhit++) {
1531  // PndTrkConformalHit *chit = fConformalHitList->GetHit(jhit);
1532  // double u = chit->GetU();
1533  // double v = chit->GetV();
1534  // double rc = chit->GetIsochrone();
1535  // if(rc < 0) rc = 0;
1536  // // cout << "conf hit " << jhit << " u, v " << u << " " << v << " " << rc << endl;
1537  // u - rc < fUmin ? fUmin = u - rc : fUmin;
1538  // v - rc < fVmin ? fVmin = v - rc : fVmin;
1539  // u + rc > fUmax ? fUmax = u + rc : fUmax;
1540  // v + rc > fVmax ? fVmax = v + rc : fVmax;
1541 
1542  // double theta1 = TMath::ATan2(v, u);
1543  // double theta2 = theta1 + TMath::Pi();
1544 
1545  // double r1 = u * TMath::Cos(theta1) + v * TMath::Sin(theta1);
1546  // double r2 = u * TMath::Cos(theta2) + v * TMath::Sin(theta2);
1547 
1548  // double rimin, rimax;
1549  // r1 < r2 ? (rimin = r1, rimax = r2) : (rimin = r2, rimax = r1);
1550 
1551  // rimin < fRmin ? (rc_of_min = rc, fRmin = rimin) : fRmin;
1552  // rimax > fRmax ? (rc_of_max = rc, fRmax = rimax) : fRmax;
1553  // }
1554 
1555  // fRmin -= rc_of_min;
1556  // fRmax += rc_of_max;
1557 
1558  // // to square the conformal plane
1559  // du = fUmax - fUmin;
1560  // dv = fVmax - fVmin;
1561  // delt = fabs(dv - du)/2.;
1562  // du < dv ? (fUmin -= delt, fUmax += delt) : (fVmin -= delt, fVmax += delt);
1563 
1564  // }
1565  // else { // otherwise lets refit in the same conf map
1566  fConformalHitList->Reset(); // CHECK maybe you can just add hits
1567  // fill conformal hits
1568  nofconfhits = FillConformalHitList(&cluster);
1569  // }
1570 
1571  if(fDisplayOn) {
1572  display->cd(2);
1573  DrawGeometryConf(fUmin, fUmax, fVmin, fVmax);
1574  // ----------------------------------------------------------------------
1575  for(int ihit = 0; ihit < nofconfhits; ihit++) {
1577  chit->Draw(kRed);
1578  display->Update();
1579  display->Modified();
1580  }
1581  }
1582 
1583 
1584  // ====== REFIT CLUSTER ANALYTICALLY
1585  double xc2, yc2, R2;
1586 
1587  // line or parabola or minuit
1588  if(1 == 1) {
1589  bool fitting = AnalyticalFit(&cluster, xc, yc, R, fitm, fitq);
1590  if(fitting == kFALSE) continue;
1591  FromConformalToRealTrack(fitm, fitq, xc2, yc2, R2);
1592  }
1593  else if(1 == 0) {
1594  double fita, fitb, fitc, epsilon;
1595  bool fitting = AnalyticalParabolaFit(&cluster, xc, yc, R, fita, fitb, fitc, epsilon);
1596  if(fitting == kFALSE) continue;
1597  FromConformalToRealTrackParabola(fita, fitb, fitc, xc2, yc2, R2, epsilon);
1598  }
1599  else {
1600  bool fitting = MinuitFit(&cluster, fitm2, fitq2, fitm, fitq);
1601  if(fitting == kFALSE) continue;
1602  FromConformalToRealTrack(fitm, fitq, xc2, yc2, R2);
1603  }
1604 
1605  if(fDisplayOn) {
1606  //char goOnChar; //[R.K. 01/2017] unused variable
1607  display->cd(1);
1608  TArc *arcm = new TArc(xc2, yc2, R2);
1609  arcm->SetFillStyle(0);
1610  arcm->SetLineColor(5);
1611  arcm->Draw("SAME");
1612  display->Update();
1613  display->Modified();
1614  }
1615  // cout << "xc2: " << xc2 << " " << yc2 << " " << R2 << endl;
1616 
1617  // check goodness
1618  distance = TMath::Sqrt((xc - xc2) * (xc - xc2) + (yc - yc2) * (yc - yc2));
1619  r_minus_rc = fabs(R - R2);
1620  // cout << "distance " << distance << " r - rc " << r_minus_rc << " " << fabs(distance - r_minus_rc) << endl;
1621 
1622  // no backup, just throw it away!
1623  if(fabs(distance - r_minus_rc) > 2.) continue;
1624 
1625  // put in a list the hits you considered and
1626  // decided do not belong to the track
1627  std::vector< std::pair< int, int > > dontuse;
1628 
1629  // ==================
1630  // MAKE the FINAL CLUSTER (at least in xy)
1631  // finalcluster = new PndTrkCluster();
1632  fFinalCluster->Clear("C");
1633  // STT
1634  for(int ihit = 0; ihit < stthitlist->GetNofHits(); ihit++) {
1635  hit = stthitlist->GetHit(ihit);
1636  if(hit->IsSttParallel() == kFALSE) continue;
1637  PndSttTube* tube = (PndSttTube*) fTubeArray->At(hit->GetTubeID());
1638  if(border == false && tube->GetSectorID() != sectorID) continue;
1639  else if(border == true && (tube->GetSectorID() != sectorID && tube->GetSectorID() != othersecID)) continue;
1640  double distance_hit_center = (tube->GetPosition().XYvector() - TVector2(xc2, yc2)).Mod();
1641  double recoiso = fabs(distance_hit_center - R2);
1642  if(recoiso < 1.) {
1643  fFinalCluster->AddHit(hit);
1644  }
1645  }
1646  // MVD PIX
1647  for(int ihit = 0; ihit < mvdpixhitlist->GetNofHits(); ihit++) {
1648  hit = mvdpixhitlist->GetHit(ihit);
1649  // if(border == false && hit->GetSector() != sectorID) continue;
1650  // else if(border == true && (hit->GetSector() != sectorID && hit->GetSector() != othersecID)) continue;
1651  if(fabs(hit->GetSector() - sectorID) > 1) continue;
1652 
1653  double distance_hit_center = (hit->GetPosition().XYvector() - TVector2(xc2, yc2)).Mod();
1654  double recoiso = fabs(distance_hit_center - R2);
1655  if(recoiso < 0.5) {
1656  // dont want two hits on the same sensor
1657  int samesensor = false;
1658  for(int khit = 0; khit < fFinalCluster->GetNofHits(); khit++) {
1659  PndTrkHit *hitk = fFinalCluster->GetHit(khit);
1660  if(!hitk->IsMvdPixel()) continue;
1661  if(hitk->GetSensorID() != hit->GetSensorID()) continue;
1662  samesensor = true;
1663  double distance_hitk_center = (hitk->GetPosition().XYvector() - TVector2(xc2, yc2)).Mod();
1664  double recoisok = fabs(distance_hitk_center - R2);
1665  if(recoiso < recoisok) {
1667  std::pair< int, int > dontpair(hitk->GetHitID(), hitk->GetDetectorID());
1668  dontuse.push_back(dontpair);
1669  fFinalCluster->AddHit(hit);
1670  }
1671  else {
1672  std::pair< int, int > dontpair(hit->GetHitID(), hit->GetDetectorID());
1673  dontuse.push_back(dontpair);
1674  }
1675  }
1676  // fFinalCluster->AddHit(hit);
1677  if(samesensor == false) fFinalCluster->AddHit(hit);
1678  }
1679  }
1680  // MVD STR
1681  for(int ihit = 0; ihit < mvdstrhitlist->GetNofHits(); ihit++) {
1682  hit = mvdstrhitlist->GetHit(ihit);
1683  // if(border == false && hit->GetSector() != sectorID) continue;
1684  // else if(border == true && (hit->GetSector() != sectorID && hit->GetSector() != othersecID)) continue;
1685  if(fabs(hit->GetSector() - sectorID) > 1) continue;
1686 
1687  double distance_hit_center = (hit->GetPosition().XYvector() - TVector2(xc2, yc2)).Mod();
1688  double recoiso = fabs(distance_hit_center - R2);
1689  if(recoiso < 1.) {
1690  // dont want two hits on the same sensor
1691  int samesensor = false;
1692  for(int khit = 0; khit < fFinalCluster->GetNofHits(); khit++) {
1693  PndTrkHit *hitk = fFinalCluster->GetHit(khit);
1694  if(!hitk->IsMvdStrip()) continue;
1695  if(hitk->GetSensorID() != hit->GetSensorID()) continue;
1696  samesensor = true;
1697  double distance_hitk_center = (hitk->GetPosition().XYvector() - TVector2(xc2, yc2)).Mod();
1698  double recoisok = fabs(distance_hitk_center - R2);
1699  if(recoiso < recoisok) {
1701  std::pair< int, int > dontpair(hitk->GetHitID(), hitk->GetDetectorID());
1702  dontuse.push_back(dontpair);
1703  fFinalCluster->AddHit(hit);
1704  }
1705  else {
1706  std::pair< int, int > dontpair(hit->GetHitID(), hit->GetDetectorID());
1707  dontuse.push_back(dontpair);
1708  }
1709  }
1710  // fFinalCluster->AddHit(hit);
1711  if(samesensor == false) fFinalCluster->AddHit(hit);
1712  }
1713  }
1714  // GEM
1715  for(int ihit = 0; ihit < gemhitlist->GetNofHits(); ihit++) {
1716  hit = gemhitlist->GetHit(ihit);
1717  // if(border == false && hit->GetSector() != sectorID) continue;
1718  // else if(border == true && (hit->GetSector() != sectorID && hit->GetSector() != othersecID)) continue;
1719  if(fabs(hit->GetSector() - sectorID) > 1) continue;
1720  double distance_hit_center = (hit->GetPosition().XYvector() - TVector2(xc2, yc2)).Mod();
1721  double recoiso = fabs(distance_hit_center - R2);
1722  // if(hit->GetPosition().Perp() > CTOUTRADIUS) cout << "gem recoiso " << recoiso << endl;
1723  if(recoiso < 1.5 && hit->GetPosition().Perp() > CTOUTRADIUS) {
1724  // cout << "add " << hit->GetDetectorID() << " " << hit->GetHitID() << endl;
1725  fFinalCluster->AddHit(hit);
1726  }
1727  }
1728  // SCITIL
1729  tmphit = -1;
1730  tmpdistance = 1000;
1731  for(int ihit = 0; ihit < scithitlist->GetNofHits(); ihit++) {
1732  hit = scithitlist->GetHit(ihit);
1733  if(hit->GetXYDistance(hit3) > 30) continue;
1734  double distance_hit_center = (hit->GetPosition().XYvector() - TVector2(xc2, yc2)).Mod();
1735  double recoiso = fabs(distance_hit_center - R2);
1736  if(recoiso < 1.) {
1737  if(recoiso < tmpdistance) {
1738  tmphit = ihit;
1739  tmpdistance = recoiso;
1740  }
1741  }
1742  }
1743  if(tmphit > -1) {
1744  hit = scithitlist->GetHit(tmphit);
1745  fFinalCluster->AddHit(hit);
1746  }
1747 
1748  if(fFinalCluster->GetNofHits() == 0) continue;
1749  // cout << "FINAL CLUSTER HAS " << fFinalCluster->GetNofHits() << endl;
1750  if(fDisplayOn) {
1751  Refresh();
1752  display->cd(1);
1754  display->Update();
1755  display->Modified();
1756  char goOnChar;
1757  cin >> goOnChar;
1758  }
1759 
1760 
1761  // sorting
1762  for(int ihit = 0; ihit < fFinalCluster->GetNofHits(); ihit++) {
1763  hit = fFinalCluster->GetHit(ihit);
1764  hit->SetSortVariable(hit->GetPosition().Perp());
1772  }
1773  fFinalCluster->Sort();
1774 
1775  PndTrkTrack finaltrack(fFinalCluster, xc2, yc2, R2);
1776  finaltrack.ComputeCharge();
1777 
1778  //
1779  // fDisplayOn = kTRUE;
1780  if(fDisplayOn) {
1781  Refresh();
1782  display->cd(1);
1783  fFinalCluster->Draw(kGreen);
1784  finaltrack.Draw(kGreen);
1785  display->Update();
1786  display->Modified();
1787  }
1788 
1789  // =========================== Z PART ==================================
1790  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1791  // SKEWED ASSOCIATION ********* CHECK *********
1792  // -------------------------------------------------------
1793  // cout << " %%%%%%%%%%%%%%%%%%%% ZFINDER %%%%%%%%%%%%%%%%%%%%%%%%%%" << endl;
1794 
1795  if(fDisplayOn) DrawZGeometry(-360, 360, -40, 200);
1796 
1797  // create cluster for z finding
1798 
1799  // lets start from the skewed --------------------------------
1800  // PndTrkCluster skewhitlist = CreateSkewHitList(finaltrack);
1801  PndTrkSkewHitList skewhitlist;
1802  //double phimin = 400, phimax = -1, zmin = 1000, zmax = -1; //[R.K. 01/2017] unused variable
1803  for(int ihit = 0; ihit < stthitlist->GetNofHits(); ihit++) {
1804  hit = stthitlist->GetHit(ihit);
1805  // cout << hit->IsSttSkew() << " " << hit->GetSector() << " " << TMath::RadToDeg() * hit->GetPosition().Phi() << " " << sectorID << " " << othersecID << endl;
1806  if(hit->IsSttSkew() == kFALSE) continue;
1807 
1808  if(border == false && hit->GetSector() != sectorID) continue;
1809  else if(border == true && (hit->GetSector() != sectorID && hit->GetSector() != othersecID)) continue;
1810 
1811  int tubeID = hit->GetTubeID();
1812  PndSttTube *tube = (PndSttTube*) fTubeArray->At(tubeID);
1813 
1814  TVector3 wireDirection = tube->GetWireDirection();
1815  Double_t halflength = tube->GetHalfLength();
1816 
1817  TVector3 first = tube->GetPosition() + wireDirection * halflength; // CHECK
1818  TVector3 second = tube->GetPosition() - wireDirection * halflength; // CHECK
1819 
1820  // double m1 = (first - second).Y()/(first - second).X();
1821  // double q1 = first.Y() - m1 * first.X();
1822 
1823  // 1. compute intersection between the track circle and the wire
1824  TVector2 intersection1, intersection2;
1825  Int_t nofintersections = tools->ComputeSegmentCircleIntersection(TVector2(first.X(), first.Y()), TVector2(second.X(), second.Y()), xc2, yc2, R2, intersection1, intersection2);
1826 
1827  if(nofintersections == 0) continue;
1828  if(nofintersections >= 2) {
1829  if(fVerbose) cout << "ERROR: MORE THAN 1 INTERSECTION!!" << endl;
1830  continue; // CHECK
1831  }
1832 
1833  // 2. find the tangent to the track in the intersection point
1834  // tangent approximation
1835  TVector2 tangent = tools->ComputeTangentInPoint(xc2, yc2, intersection1);
1836 
1837  // 3. rotate clockwise the tangent/point/(wire, not explicitely)
1838  // in order to have the wire parallel to the x axis;
1839  // then translate everything to have the wire ON the x axis
1840  double beta = wireDirection.Phi();
1841  if(beta < 0) beta += TMath::Pi();
1842  // ... rotate the tangent
1843  double rtx = TMath::Cos(beta) * tangent.X() + TMath::Sin(beta) * tangent.Y();
1844  double rty = TMath::Cos(beta) * tangent.Y() - TMath::Sin(beta) * tangent.X();
1845  TVector2 rottangent(rtx, rty);
1846  rottangent = rottangent.Unit();
1847  // ... rotate the point
1848  double rx = TMath::Cos(beta) * intersection1.X() + TMath::Sin(beta) * intersection1.Y();
1849  double ry = TMath::Cos(beta) * intersection1.Y() - TMath::Sin(beta) * intersection1.X();
1850 
1851  // translation
1852  Double_t deltay = ry;
1853  rty -= deltay;
1854  ry -= deltay;
1855 
1856  // rotm, rotp
1857  Double_t rotm = rottangent.Y()/rottangent.X();
1858  Double_t rotp = ry - rotm * rx;
1859 
1860  // ellipsis
1861  double a = hit->GetIsochrone() * TMath::Cos(SKEW_ANGLE); // CHECK skew angle hard coded
1862  double b = hit->GetIsochrone();
1863 
1864  // center of ellipsis
1865  Double_t x0a, x0b, y0;
1866  y0 = 0.;
1867  x0a = (-rotp + TMath::Sqrt(b * b + a * a * rotm * rotm)) / rotm;
1868  x0b = (-rotp - TMath::Sqrt(b * b + a * a * rotm * rotm)) / rotm;
1869 
1870  // intersection point
1871  double intxa = (x0a * b * b - rotm * rotp * a * a) / (b * b + rotm * rotm * a * a);
1872  double intya = rotm * intxa + rotp;
1873  double intxb = (x0b * b * b - rotm * rotp * a * a) / (b * b + rotm * rotm * a * a);
1874  double intyb = rotm * intxb + rotp;
1875 
1876  // 4. retraslate/rerotate all back to the original plane
1877  // retranslate
1878  y0 += deltay;
1879  intya += deltay;
1880  intyb += deltay;
1881 
1882  // rerotate
1883  double x0anew = TMath::Cos(beta) * x0a - TMath::Sin(beta) * y0;
1884  double y0anew = TMath::Cos(beta) * y0 + TMath::Sin(beta) * x0a;
1885  double x0bnew = TMath::Cos(beta) * x0b - TMath::Sin(beta) * y0;
1886  double y0bnew = TMath::Cos(beta) * y0 + TMath::Sin(beta) * x0b;
1887 
1888  double intxanew = TMath::Cos(beta) * intxa - TMath::Sin(beta) * intya;
1889  double intyanew = TMath::Cos(beta) * intya + TMath::Sin(beta) * intxa;
1890  double intxbnew = TMath::Cos(beta) * intxb - TMath::Sin(beta) * intyb;
1891  double intybnew = TMath::Cos(beta) * intyb + TMath::Sin(beta) * intxb;
1892 
1893  intxa = intxanew;
1894  intya = intyanew;
1895  intxb = intxbnew;
1896  intyb = intybnew;
1897 
1898  // now we have x0a, y0a, center of the 1st ellipse
1899  // and x0b, y0b, center of the 2nd ellipse
1900  x0a = x0anew;
1901  double y0a = y0anew;
1902  x0b = x0bnew;
1903  double y0b = y0bnew;
1904 
1905  if(fDisplayOn) {
1906  //char goOnChar; //[R.K. 01/2017] unused variable
1907  display->cd(1);
1908 
1909  TEllipse *ell1 = new TEllipse(x0a, y0a, a, b, 0, 360, -beta);
1910  ell1->SetFillStyle(0);
1911  ell1->SetLineColor(4);
1912  ell1->Draw("SAME");
1913  TEllipse *ell2 = new TEllipse(x0b, y0b, a, b, 0, 360, -beta);
1914  ell2->SetFillStyle(0);
1915  ell2->SetLineColor(6);
1916  ell2->Draw("SAME");
1917 
1918  TMarker *mrkinta = new TMarker(intxa, intya, 20);
1919  mrkinta->SetMarkerColor(4);
1920  mrkinta->Draw("SAME");
1921  TMarker *mrkintb = new TMarker(intxb, intyb, 20);
1922  mrkintb->SetMarkerColor(6);
1923  mrkintb->Draw("SAME");
1924  }
1925 
1926  // 5. calculate z coordinate for each intersection
1927 
1928  // calculate z0a, z0b of the center of the ellipse
1929  Double_t t = ((x0a + y0a) - (first.X() + first.Y())) / ((second.X() - first.X()) + (second.Y() - first.Y()));
1930  Double_t z0a = first.Z() + (second.Z() - first.Z()) * t;
1931  // cout << "0 : calculate t, z0a " << t << " " << z0a << endl;
1932 
1933  t = ((x0b + y0b) - (first.X() + first.Y())) / ((second.X() - first.X()) + (second.Y() - first.Y()));
1934  Double_t z0b = first.Z() + (second.Z() - first.Z()) * t;
1935 
1936  TVector3 center1(x0a, y0a, z0a);
1937  TVector3 center2(x0b, y0b, z0b);
1938 
1939  // calculate the z of the intersection ON the ellipse (CHECK this step calculations!)
1940  double dx = intxa - x0a;
1941  double dy = intya - y0a;
1942  TVector3 dxdy(dx, dy, 0.0);
1943 
1944  TVector3 tfirst = first + dxdy;
1945  TVector3 tsecond = second + dxdy;
1946 
1947  t = ((intxa + intya) - (tfirst.X() + tfirst.Y())) / ((tsecond.X() - tfirst.X()) + (tsecond.Y() - tfirst.Y()));
1948  double intza = tfirst.Z() + (tsecond.Z() - tfirst.Z()) * t;
1949  // if(fDisplayOn) {
1950 // char goOnChar;
1951 // display->cd(3);
1952 // TLine *linezx1 = new TLine(tfirst.X(), tfirst.Z(), tsecond.X(), tsecond.Z());
1953 // linezx1->SetLineStyle(1);
1954 // linezx1->Draw("SAME");
1955 // TMarker *mrkza1 = new TMarker(intxa, intza, 20);
1956 // mrkza1->SetMarkerColor(kBlue - 9);
1957 // mrkza1->Draw("SAME");
1958 // cin >> goOnChar;
1959 // display->Update();
1960 // display->Modified();
1961 // }
1962 
1963  tfirst = first - dxdy;
1964  tsecond = second - dxdy;
1965 
1966  t = ((intxb + intyb) - (tfirst.X() + tfirst.Y())) / ((tsecond.X() - tfirst.X()) + (tsecond.Y() - tfirst.Y()));
1967  double intzb = tfirst.Z() + (tsecond.Z() - tfirst.Z()) * t;
1968 
1969  TVector3 fin_intersection1(intxa, intya, intza);
1970  TVector3 fin_intersection2(intxb, intyb, intzb);
1971 
1972  // CHECK to be changed
1973  int trackID = 1;
1974  double phi1 = finaltrack.ComputePhi(fin_intersection1);
1975  double phi2 = finaltrack.ComputePhi(fin_intersection2);
1976 
1977 
1978  // skewhit = new PndTrkSkewHit(*hit, trackID, center1, fin_intersection1, phi1, center2, fin_intersection2, phi2, a, b, -1, beta);
1979  // // skewhit->Print();
1980  // skewhitlist.AddHit(skewhit);
1981 
1982  skewhitlist.AddHit(PndTrkSkewHit(*hit, trackID, center1, fin_intersection1, phi1, center2, fin_intersection2, phi2, a, b, -1, beta));
1983 
1984 
1985  // if(fDisplayOn) {
1986  // display->cd(4);
1987  // TLine *linezphi = new TLine(phi1, fin_intersection1.Z(), phi2, fin_intersection2.Z());
1988  // linezphi->SetLineStyle(1);
1989  // linezphi->Draw("SAME");
1990  // TMarker *mrkzphi1 = new TMarker(phi1, fin_intersection1.Z(), 20);
1991  // mrkzphi1->SetMarkerColor(kBlue - 9);
1992  // mrkzphi1->Draw("SAME");
1993  // TMarker *mrkzphi2 = new TMarker(phi2, fin_intersection2.Z(), 20);
1994  // mrkzphi2->SetMarkerColor(kMagenta - 7);
1995  // mrkzphi2->Draw("SAME");
1996  // display->Update();
1997  // display->Modified();
1998  // }
1999  // --------------------------
2000  }
2001 
2002  // add hits which have a z info
2003  // and belong to the cluster
2004  for(int ihit = 0; ihit < fFinalCluster->GetNofHits(); ihit++) {
2005  hit = fFinalCluster->GetHit(ihit);
2006  double phi = finaltrack.ComputePhi(hit->GetPosition());
2007  hit->SetPhi(phi);
2008  if(hit->IsStt() == kFALSE) skewhitlist.AddHit(PndTrkSkewHit(*hit));
2009 
2010  }
2011 
2012 
2013  // if(fDisplayOn) {
2014 
2015 // for(int ihit = 0; ihit < fFinalCluster->GetNofHits(); ihit++) {
2016 // PndTrkHit *hitstt1 = fFinalCluster->GetHit(ihit);
2017 // if(hitstt1->IsStt() == kFALSE) continue;
2018 // PndSttHit *stthit1 = (PndSttHit*) fSttHitArray->At(hitstt1->GetHitID());
2019 
2020 // indiv = fHitMap->GetIndivisiblesToHit(hitstt1);
2021 // for(int jhit = 0; jhit < indiv.GetEntriesFast(); jhit++) {
2022 // PndTrkHit *hitstt2 = (PndTrkHit*) indiv.At(jhit);
2023 // PndSttHit *stthit2 = (PndSttHit*) fSttHitArray->At(hitstt2->GetHitID());
2024 
2025 // TVector3 poca(0, 0, 0);
2026 // PndSttGeometryMap geomap;
2027 // Double_t distancepoca = fMapper->GetGeometryMap()->CalculateStrawPoca(stthit1, stthit2, poca);
2028 
2029 // TVector3 pos1, pos2;
2030 // stthit1->Position(pos1);
2031 // pos1.Print();
2032 // stthit2->Position(pos2);
2033 // pos2.Print();
2034 // poca.Print();
2035 
2036 // TMarker *mrk = new TMarker(poca.X(), poca.Y(), 20);
2037 // mrk->SetMarkerColor(kOrange);
2038 // mrk->Draw("SAME");
2039 // char goOnChar;
2040 // display->cd(1);
2041 // cin >> goOnChar;
2042 // display->Update();
2043 // display->Modified();
2044 
2045 // }
2046 // }
2047 
2048 // for(int ihit = 0; ihit < skewhitlist.GetNofHits(); ihit++) {
2049 // PndTrkHit *hitstt1 = skewhitlist.GetHit(ihit);
2050 // if(hitstt1->IsStt() == kFALSE) continue;
2051 // PndSttHit *stthit1 = (PndSttHit*) fSttHitArray->At(hitstt1->GetHitID());
2052 
2053 // indiv = fHitMap->GetIndivisiblesToHit(hitstt1);
2054 // for(int jhit = 0; jhit < indiv.GetEntriesFast(); jhit++) {
2055 // PndTrkHit *hitstt2 = (PndTrkHit*) indiv.At(jhit);
2056 // PndSttHit *stthit2 = (PndSttHit*) fSttHitArray->At(hitstt2->GetHitID());
2057 
2058 // TVector3 poca(0, 0, 0);
2059 // PndSttGeometryMap geomap;
2060 // Double_t distancepoca = fMapper->GetGeometryMap()->CalculateStrawPoca(stthit1, stthit2, poca);
2061 
2062 // TVector3 pos1, pos2;
2063 // stthit1->Position(pos1);
2064 // pos1.Print();
2065 // stthit2->Position(pos2);
2066 // pos2.Print();
2067 // poca.Print();
2068 
2069 // TMarker *mrk = new TMarker(poca.X(), poca.Y(), 20);
2070 // mrk->SetMarkerColor(kOrange);
2071 // mrk->Draw("SAME");
2072 // char goOnChar;
2073 // display->cd(1);
2074 // cin >> goOnChar;
2075 // display->Update();
2076 // display->Modified();
2077 
2078 // }
2079 // }
2080 
2081 
2082 
2083 // }
2084 
2085 
2086  // ----------------------------------------------
2087  int phisec[2] = {0, 0};
2088  for(int ihit = 0; ihit < skewhitlist.GetNofHits(); ihit++)
2089  {
2090  PndTrkHit *hitj = skewhitlist.GetHit(ihit);
2091  if(!hitj) continue;
2092 
2093  TVector3 fin_intersection21(-999, -999, -999), fin_intersection22(-999, -999, -999);
2094  double phi21 = -999, phi22 = -999;
2095 
2096  if(hitj->IsStt() == kTRUE) {
2097  PndTrkSkewHit *skewhit2 = (PndTrkSkewHit*) hitj;
2098 
2099  fin_intersection21 = skewhit2->GetIntersection1();
2100  fin_intersection22 = skewhit2->GetIntersection2();
2101  phi21 = skewhit2->GetPhi1();
2102  phi22 = skewhit2->GetPhi2();
2103 
2104  double phimean = 0.5 * (phi21 + phi22);
2105  if(phimean >= 0 && phimean < 180) phisec[0]++;
2106  else phisec[1]++;
2107 
2108  }
2109  else {
2110  fin_intersection21 = hitj->GetPosition();
2111  phi21 = hitj->GetPhi();
2112  if(phi21 >= 0 && phi21 < 180) phisec[0]++;
2113  else phisec[1]++;
2114  }
2115  }
2116 
2117  // cout << "PHI SECTOR " << phisec[0] << " " << phisec[1] << endl;
2118 
2119  // correction
2120  for(int ihit = 0; ihit < skewhitlist.GetNofHits(); ihit++)
2121  {
2122  PndTrkHit *hitj = skewhitlist.GetHit(ihit);
2123  if(!hitj) continue;
2124 
2125  TVector3 fin_intersection21(-999, -999, -999), fin_intersection22(-999, -999, -999);
2126  double phi21 = -999, phi22 = -999;
2127 
2128  if(hitj->IsStt() == kTRUE) {
2129  PndTrkSkewHit *skewhit2 = (PndTrkSkewHit*) hitj;
2130 
2131  fin_intersection21 = skewhit2->GetIntersection1();
2132  fin_intersection22 = skewhit2->GetIntersection2();
2133  phi21 = skewhit2->GetPhi1();
2134  phi22 = skewhit2->GetPhi2();
2135 
2136  double phimean = 0.5 * (phi21 + phi22);
2137  // if 1st sec
2138  if((phisec[0] > phisec[1]) && (phimean >= 180)) {
2139  phi21 -= 180.;
2140  phi22 -= 180.;
2141  skewhit2->SetPhi1(phi21);
2142  skewhit2->SetPhi2(phi22);
2143  }
2144  else if((phisec[0] < phisec[1]) && (phimean < 180)) { // 2nd sec
2145  phi21 += 180.;
2146  phi22 += 180.;
2147  skewhit2->SetPhi1(phi21);
2148  skewhit2->SetPhi2(phi22);
2149  }
2150  }
2151  else {
2152  fin_intersection21 = hitj->GetPosition();
2153  phi21 = hitj->GetPhi();
2154 
2155  // if 1st sec
2156  if((phisec[0] > phisec[1]) && (phi21 >= 180)) {
2157  phi21 -= 180.;
2158  hitj->SetPhi(phi21);
2159  }
2160  else if((phisec[0] < phisec[1]) && (phi21 < 180)) { // 2nd sec
2161  phi21 += 180.;
2162  hitj->SetPhi(phi21);
2163  }
2164  }
2165  }
2166 
2167  // ----------------------------------------------
2168 
2169  // ========================================================
2170  std::vector < int > first, second;
2171  double fitm3 = 0, fitq3 = 0;
2172  for(int ihit = 0; ihit < skewhitlist.GetNofHits(); ihit++) {
2173  hit = skewhitlist.GetHit(ihit);
2174  if(!hit) continue;
2175  if(hit->IsStt() == kFALSE) continue;
2176 
2177  PndTrkSkewHit *skewhit = (PndTrkSkewHit*) hit;
2178 
2179  TVector3 fin_intersection1 = skewhit->GetIntersection1();
2180  TVector3 fin_intersection2 = skewhit->GetIntersection2();
2181  double phi1 = skewhit->GetPhi1();
2182  double phi2 = skewhit->GetPhi2();
2183 
2184 
2185  if(fDisplayOn) {
2186  display->cd(4);
2187  TLine *linezphi = new TLine(phi1, fin_intersection1.Z(), phi2, fin_intersection2.Z());
2188  linezphi->SetLineStyle(1);
2189  linezphi->Draw("SAME");
2190  TMarker *mrkzphi1 = new TMarker(phi1, fin_intersection1.Z(), 20);
2191  mrkzphi1->SetMarkerColor(kBlue - 9);
2192  mrkzphi1->Draw("SAME");
2193  TMarker *mrkzphi2 = new TMarker(phi2, fin_intersection2.Z(), 20);
2194  mrkzphi2->SetMarkerColor(kMagenta - 7);
2195  mrkzphi2->Draw("SAME");
2196  display->Update();
2197  display->Modified();
2198  }
2199 
2200 
2201  // check neighborings @ layer 8 & 15
2202  //PndSttTube *tube = (PndSttTube*) fTubeArray->At(hit->GetTubeID()); //[R.K. 01/2017] unused variable
2203  // if(tube->GetLayerID() == 8) {
2204  // PndTrkHit *thit = stthitlist->GetHit(hit->GetHitID());
2205  // TObjArray neighs = fHitMap->GetNeighboringsToHit(thit);
2206  // // cout << thit->GetHitID() << " on layer " << tube->GetLayerID() << " " << neighs.GetEntriesFast() << endl;
2207  // for(int j = 0; j < neighs.GetEntriesFast(); j++) {
2208  // PndTrkHit *nhit = (PndTrkHit*) neighs.At(j);
2209  // PndSttTube *ntube = (PndSttTube*) fTubeArray->At(nhit->GetTubeID());
2210  // if(ntube->GetLayerID() == 7) {
2211  // // cout << "hit close to 7" << endl;
2212  // first.push_back(ihit);
2213  // }
2214  // }
2215  // }
2216  // if(tube->GetLayerID() == 15)
2217  // {
2218  // PndTrkHit *thit = stthitlist->GetHit(hit->GetHitID());
2219  // TObjArray neighs = fHitMap->GetNeighboringsToHit(thit);
2220  // // cout << hit->GetHitID() << " on layer " << tube->GetLayerID() << " " << neighs.GetEntriesFast() << endl;
2221  // for(int j = 0; j < neighs.GetEntriesFast(); j++) {
2222  // PndTrkHit *nhit = (PndTrkHit*) neighs.At(j);
2223  // PndSttTube *ntube = (PndSttTube*) fTubeArray->At(nhit->GetTubeID());
2224  // if(ntube->GetLayerID() == 16) {
2225  // // cout << "hit close to 16" << endl;
2226  // second.push_back(ihit);
2227  // }
2228  // }
2229  // }
2230  }
2231 
2232  // if(first.size() != 0 && second.size() != 0) {
2233 
2234  // double zdistance = 1000;
2235  // int tmpi = -1, tmpj = -1;
2236  // double tmpiz = -999, tmpjz = -999, tmpiphi = -999, tmpjphi = -999;
2237 
2238  // for(int ihit = 0; ihit < first.size(); ihit++) {
2239  // int hitiskeid = first[ihit];
2240  // PndTrkSkewHit *skewhiti = (PndTrkSkewHit*) skewhitlist.GetHit(hitiskeid);
2241  // TVector3 fin_intersectioni = 0.5 * (skewhiti->GetIntersection1() + skewhiti->GetIntersection2());
2242  // double phii = 0.5 * (skewhiti->GetPhi1() + skewhiti->GetPhi2()) ;
2243  // for(int jhit = 0; jhit < second.size(); jhit++) {
2244  // int hitjskeid = second[jhit];
2245  // PndTrkSkewHit *skewhitj = (PndTrkSkewHit*) skewhitlist.GetHit(hitjskeid);
2246  // TVector3 fin_intersectionj = 0.5 * (skewhitj->GetIntersection1() + skewhitj->GetIntersection2());
2247  // double phij = 0.5 * (skewhitj->GetPhi1() + skewhitj->GetPhi2()) ;
2248 
2249  // double tmpzdistance = fabs(fin_intersectioni.Z() - fin_intersectionj.Z());
2250  // if(tmpzdistance < zdistance) {
2251  // zdistance = tmpzdistance;
2252  // tmpi = hitiskeid;
2253  // tmpj = hitjskeid;
2254  // tmpiz = fin_intersectioni.Z();
2255  // tmpjz = fin_intersectionj.Z();
2256  // tmpiphi = phii;
2257  // tmpjphi = phij;
2258  // }
2259  // }
2260  // }
2261 
2262  // fitm3 = (tmpiz - tmpjz) / (tmpiphi - tmpjphi);
2263  // fitq3 = tmpiz - fitm3 * tmpiphi;
2264  // }
2265  // else {
2266 
2267 
2268  fLineHisto->Reset();
2269  for(int ihit = 0; ihit < skewhitlist.GetNofHits(); ihit++)
2270  {
2271  hit = skewhitlist.GetHit(ihit);
2272  if(!hit) continue;
2273 
2274  TVector3 fin_intersection11(-999, -999, -999), fin_intersection12(-999, -999, -999);
2275  double phi11 = -999, phi12 = -999;
2276 
2277  if(hit->IsStt() == kTRUE) {
2278  PndTrkSkewHit *skewhit1 = (PndTrkSkewHit*) hit;
2279 
2280  fin_intersection11 = skewhit1->GetIntersection1();
2281  fin_intersection12 = skewhit1->GetIntersection2();
2282  phi11 = skewhit1->GetPhi1();
2283  phi12 = skewhit1->GetPhi2();
2284  }
2285  else {
2286  fin_intersection11 = hit->GetPosition();
2287  phi11 = hit->GetPhi();
2288  }
2289 
2290  if(fDisplayOn) {
2291  display->cd(4);
2292  if(phi12 != -999) {
2293  TLine *linezphi = new TLine(phi11, fin_intersection11.Z(), phi12, fin_intersection12.Z());
2294  linezphi->SetLineStyle(1);
2295  linezphi->Draw("SAME");
2296  TMarker *mrkzphi1 = new TMarker(phi11, fin_intersection11.Z(), 20);
2297  mrkzphi1->SetMarkerColor(kBlue - 9);
2298  mrkzphi1->Draw("SAME");
2299  TMarker *mrkzphi2 = new TMarker(phi12, fin_intersection12.Z(), 20);
2300  mrkzphi2->SetMarkerColor(kMagenta - 7);
2301  mrkzphi2->Draw("SAME");
2302  }
2303  else {
2304  TMarker *mrkzphi1 = new TMarker(phi11, fin_intersection11.Z(), 20);
2305  mrkzphi1->SetMarkerColor(kGreen);
2306  mrkzphi1->Draw("SAME");
2307  }
2308  display->Update();
2309  display->Modified();
2310  }
2311 
2312  for(int jhit = ihit + 1; jhit < skewhitlist.GetNofHits(); jhit++)
2313  {
2314  PndTrkHit *hitj = skewhitlist.GetHit(jhit);
2315  if(!hitj) continue;
2316 
2317  TVector3 fin_intersection21(-999, -999, -999), fin_intersection22(-999, -999, -999);
2318  double phi21 = -999, phi22 = -999;
2319 
2320  if(hitj->IsStt() == kTRUE) {
2321  PndTrkSkewHit *skewhit2 = (PndTrkSkewHit*) hitj;
2322 
2323  fin_intersection21 = skewhit2->GetIntersection1();
2324  fin_intersection22 = skewhit2->GetIntersection2();
2325  phi21 = skewhit2->GetPhi1();
2326  phi22 = skewhit2->GetPhi2();
2327  }
2328  else {
2329  fin_intersection21 = hitj->GetPosition();
2330  phi21 = hitj->GetPhi();
2331  }
2332 
2333 
2334  // 1 1
2335  double cost = (fin_intersection21.Z() - fin_intersection11.Z()) / TMath::Sqrt((phi11 - phi21) * (phi11 - phi21) + (fin_intersection21.Z() - fin_intersection11.Z()) * (fin_intersection21.Z() - fin_intersection11.Z()));
2336  double theta = TMath::ACos(cost);
2337  double r1 = phi11 * cost + fin_intersection11.Z() * TMath::Sin(theta);
2338  double r2 = phi21 * cost + fin_intersection21.Z() * TMath::Sin(theta);
2339  if(fabs(r1 - r2) > 1.e-9) {
2340  theta = -TMath::ACos(cost);
2341  r1 = phi11 * cost + fin_intersection11.Z() * TMath::Sin(theta);
2342  }
2343  fLineHisto->Fill(theta * TMath::RadToDeg(), r1);
2344  //double fitm11 = -TMath::Cos(theta)/TMath::Sin(theta); //[R.K. 03/2017] unused variable
2345  //double fitq11 = r1/TMath::Sin(theta); //[R.K. 03/2017] unused variable
2346  //TLine *line11 = new TLine(0, fitq11, 360, 360 * fitm11 + fitq11); //[R.K. 03/2017] unused variable
2347  // line11->Draw("SAME");
2348  // cout << phi11 << " " << phi21 << endl;
2349 
2350  if(phi12 != -999) {
2351  // 2 1
2352  cost = (fin_intersection21.Z() - fin_intersection12.Z()) / TMath::Sqrt((phi12 - phi21) * (phi12 - phi21) + (fin_intersection21.Z() - fin_intersection12.Z()) * (fin_intersection21.Z() - fin_intersection12.Z()));
2353  theta = TMath::ACos(cost);
2354  r1 = phi12 * cost + fin_intersection12.Z() * TMath::Sin(theta);
2355  r2 = phi21 * cost + fin_intersection21.Z() * TMath::Sin(theta);
2356  if(fabs(r1 - r2) > 1.e-9) {
2357  theta = -TMath::ACos(cost);
2358  r1 = phi12 * cost + fin_intersection12.Z() * TMath::Sin(theta);
2359  }
2360  fLineHisto->Fill(theta * TMath::RadToDeg(), r1);
2361  //double fitm21 = -TMath::Cos(theta)/TMath::Sin(theta); //[R.K. 03/2017] unused variable
2362  //double fitq21 = r1/TMath::Sin(theta); //[R.K. 03/2017] unused variable
2363  //TLine *line21 = new TLine(0, fitq21, 360, 360 * fitm21 + fitq21); //[R.K. 03/2017] unused variable
2364  // line21->Draw("SAME");
2365  // cout << phi12 << " " << phi21 << endl;
2366  }
2367 
2368  if(phi22 != -999) {
2369  // 1 2
2370  cost = (fin_intersection11.Z() - fin_intersection22.Z()) / TMath::Sqrt((phi22 - phi11) * (phi22 - phi11) + (fin_intersection11.Z() - fin_intersection22.Z()) * (fin_intersection11.Z() - fin_intersection22.Z()));
2371  theta = TMath::ACos(cost);
2372  r1 = phi22 * cost + fin_intersection22.Z() * TMath::Sin(theta);
2373  r2 = phi11 * cost + fin_intersection11.Z() * TMath::Sin(theta);
2374  if(fabs(r1 - r2) > 1.e-9) {
2375  theta = -TMath::ACos(cost);
2376  r1 = phi22 * cost + fin_intersection22.Z() * TMath::Sin(theta);
2377  }
2378  fLineHisto->Fill(theta * TMath::RadToDeg(), r1);
2379  //double fitm12 = -TMath::Cos(theta)/TMath::Sin(theta); //[R.K. 03/2017] unused variable
2380  //double fitq12 = r1/TMath::Sin(theta); //[R.K. 03/2017] unused variable
2381  //TLine *line12 = new TLine(0, fitq12, 360, 360 * fitm12 + fitq12); //[R.K. 03/2017] unused variable
2382  // line12->Draw("SAME");
2383  // cout << phi11<< " " << phi22<< endl;
2384  }
2385 
2386  if(phi12 != -999 && phi22 != -999) {
2387  // 2 2
2388  cost = (fin_intersection12.Z() - fin_intersection22.Z()) / TMath::Sqrt((phi22 - phi12) * (phi22 - phi12) + (fin_intersection12.Z() - fin_intersection22.Z()) * (fin_intersection12.Z() - fin_intersection22.Z()));
2389  theta = TMath::ACos(cost);
2390  r1 = phi22 * cost + fin_intersection22.Z() * TMath::Sin(theta);
2391  r2 = phi12 * cost + fin_intersection12.Z() * TMath::Sin(theta);
2392  if(fabs(r1 - r2) > 1.e-9) {
2393  theta = -TMath::ACos(cost);
2394  r1 = phi22 * cost + fin_intersection22.Z() * TMath::Sin(theta);
2395  }
2396  fLineHisto->Fill(theta * TMath::RadToDeg(), r1);
2397  //double fitm22 = -TMath::Cos(theta)/TMath::Sin(theta); //[R.K. 03/2017] unused variable
2398  //double fitq22 = r1/TMath::Sin(theta); //[R.K. 03/2017] unused variable
2399  //TLine *line22 = new TLine(0, fitq22, 360, 360 * fitm22 + fitq22); //[R.K. 03/2017] unused variable
2400  // line22->Draw("SAME");
2401  // cout << phi12 << " " << phi22<< endl;
2402  }
2403  }
2404  }
2405 
2406  if(fDisplayOn) {
2407  display->cd(3);
2408  fLineHisto->Draw("colz");
2409  display->cd(4);
2410  display->Update();
2411  display->Modified();
2412  char goOnChar;
2413  cin >> goOnChar;
2414  }
2415 
2416  int bin = fLineHisto->GetMaximumBin();
2417  int binx, biny, binz;
2418  fLineHisto->GetBinXYZ(bin, binx, biny, binz);
2419  double tpeak = fLineHisto->GetXaxis()->GetBinCenter(binx);
2420  double rpeak = fLineHisto->GetYaxis()->GetBinCenter(biny);
2421  // cout << "tpeak " << tpeak << " rpeak " << rpeak << endl;
2422  fitm3 = -TMath::Cos(tpeak * TMath::DegToRad())/TMath::Sin(tpeak * TMath::DegToRad());
2423  fitq3 = rpeak/TMath::Sin(tpeak * TMath::DegToRad());
2424  // }
2425 
2426  // ==========================================
2427  fFitter->Reset();
2428  for(int ihit = 0; ihit < skewhitlist.GetNofHits(); ihit++)
2429  {
2430  hit = skewhitlist.GetHit(ihit);
2431  if(!hit) continue;
2432 
2433  TVector3 fin_intersection11(-999, -999, -999), fin_intersection12(-999, -999, -999);
2434  double phi11 = -999, phi12 = -999;
2435 
2436  double phi = -999, z = -999, sigma = -999;
2437 
2438  if(hit->IsStt() == kTRUE) {
2439  PndTrkSkewHit *skewhit1 = (PndTrkSkewHit*) hit;
2440 
2441  fin_intersection11 = skewhit1->GetIntersection1();
2442  fin_intersection12 = skewhit1->GetIntersection2();
2443  phi11 = skewhit1->GetPhi1();
2444  phi12 = skewhit1->GetPhi2();
2445 
2446  z = 0.5 * (fin_intersection11.Z() + fin_intersection12.Z());
2447  phi = 0.5 * (phi11 + phi12);
2448  sigma = (fin_intersection11.Z() - fin_intersection12.Z())/TMath::Sqrt(12.);
2449  }
2450  else {
2451  fin_intersection11 = hit->GetPosition();
2452  phi11 = hit->GetPhi();
2453 
2454  z = fin_intersection11.Z();
2455  phi = phi11;
2456  sigma = 0.1;
2457  }
2458 
2459  fFitter->SetPointToFit(phi, z, sigma); // CHECK the error?
2460  if(fDisplayOn) {
2461  display->cd(4);
2462  if(phi12 != -999) {
2463  TLine *linezphi = new TLine(phi11, fin_intersection11.Z(), phi12, fin_intersection12.Z());
2464  linezphi->SetLineStyle(1);
2465  linezphi->Draw("SAME");
2466  TMarker *mrkzphi1 = new TMarker(phi11, fin_intersection11.Z(), 20);
2467  mrkzphi1->SetMarkerColor(kBlue - 9);
2468  mrkzphi1->Draw("SAME");
2469  TMarker *mrkzphi2 = new TMarker(phi12, fin_intersection12.Z(), 20);
2470  mrkzphi2->SetMarkerColor(kMagenta - 7);
2471  mrkzphi2->Draw("SAME");
2472  }
2473  else {
2474  TMarker *mrkzphi1 = new TMarker(phi11, fin_intersection11.Z(), 20);
2475  mrkzphi1->SetMarkerColor(kGreen);
2476  mrkzphi1->Draw("SAME");
2477  }
2478 
2479  TMarker *mrkzphi = new TMarker(phi, z, 20);
2480  mrkzphi->SetMarkerColor(kOrange);
2481  mrkzphi->Draw("SAME");
2482 
2483  display->Update();
2484  display->Modified();
2485  }
2486  }
2487  double fitm3b, fitq3b;
2488  fFitter->StraightLineFit(fitm3b, fitq3b);
2489  // ==========================================
2490  // at low fitm3 the fit prevails over legendre CHECK
2491  // this is temporary since it might be different
2492  // for a different channel
2493  if(fabs(fitm3b) > 1e-10) {
2494  if(fabs(fitm3b) > 0.1) {
2495  fitm3 = fitm3b;
2496  fitq3 = fitq3b;
2497  }
2498  }
2499 
2500  if(fDisplayOn) {
2501  display->cd(4);
2502  TLine *line = new TLine(0, fitq3, 360, 360 * fitm3 + fitq3);
2503  line->SetLineColor(kOrange);
2504  line->Draw("SAME");
2505 
2506  display->Update();
2507  display->Modified();
2508  char goOnChar;
2509  cin >> goOnChar;
2510  }
2511 
2512  // choose the fin_intersection of the skew
2513  PndTrkSkewHitList skewhitlist2;
2514  for(int ihit = 0; ihit < skewhitlist.GetNofHits(); ihit++) {
2515  hit = (PndTrkHit*) skewhitlist.GetHit(ihit);
2516  if(!hit) continue;
2517  if(hit->IsSttSkew() == kFALSE) {
2518 
2519  // check if already discarded in the phi.z procedure
2520  std::pair< int, int > thispair(hit->GetHitID(), hit->GetDetectorID());
2521  std::vector < std::pair< int, int > >::iterator itr = dontuse.begin();
2522  itr = std::find(dontuse.begin(), dontuse.end(), thispair);
2523  if(itr != dontuse.end()) continue;
2524 
2525  double zdistance = fabs(hit->GetPosition().Z() - fitm3 * hit->GetPhi() - fitq3);
2526  if(zdistance < 5) skewhitlist2.AddHit(hit);
2527  else dontuse.push_back(thispair);
2528  }
2529  else {
2530  TVector3 fin_intersection1 = ((PndTrkSkewHit*) hit)->GetIntersection1();
2531  TVector3 fin_intersection2 = ((PndTrkSkewHit*) hit)->GetIntersection2();
2532  double phi1 = ((PndTrkSkewHit*) hit)->GetPhi1();
2533  double phi2 = ((PndTrkSkewHit*) hit)->GetPhi2();
2534 
2535  double dist1 = fabs(fitm3 * phi1 - fin_intersection1.Z() + fitq3) / TMath::Sqrt(fitm3 * fitm3 + 1); // CHECK ortho distance or not?
2536  double dist2 = fabs(fitm3 * phi2 - fin_intersection2.Z() + fitq3) / TMath::Sqrt(fitm3 * fitm3 + 1); // CHECK " "
2537 
2538  distance = 1000;
2539  dist1 < dist2 ? (distance = dist1, hit->SetPosition(fin_intersection1), hit->SetPhi(phi1)) : (distance = dist2, hit->SetPosition(fin_intersection2), hit->SetPhi(phi2));
2540 
2541  if(distance < 10) skewhitlist2.AddHit(hit);
2542  }
2543  }
2544 
2545  // further cleaning
2546  PndTrkSkewHitList skewhitlist3;
2547  double mvdmeandist = 0, sttmeandist = 0, gemmeandist = 0, scitmeandist = 0;
2548  int mvdcount = 0, sttcount = 0, gemcount = 0, scitcount = 0;
2549  for(int ihit = 0; ihit < skewhitlist2.GetNofHits(); ihit++) {
2550  hit = (PndTrkHit*) skewhitlist2.GetHit(ihit);
2551  if(!hit) continue;
2552  double zdistance = fabs(hit->GetPosition().Z() - fitm3 * hit->GetPhi() - fitq3);
2553  if(hit->IsMvd()) {
2554  mvdmeandist += zdistance;
2555  mvdcount++;
2556  }
2557  else if(hit->IsStt()) {
2558  sttmeandist += zdistance;
2559  sttcount++;
2560  }
2561  else if(hit->IsGem()) {
2562  gemmeandist += zdistance;
2563  gemcount++;
2564  }
2565  else if(hit->IsSciTil()) {
2566  scitmeandist += zdistance;
2567  scitcount++;
2568  }
2569  }
2570  if(mvdcount > 0) mvdmeandist /= mvdcount;
2571  if(sttcount > 0) sttmeandist /= sttcount;
2572  if(gemcount > 0) gemmeandist /= gemcount;
2573  if(scitcount > 0) scitmeandist /= scitcount;
2574 
2575 
2576  for(int ihit = 0; ihit < skewhitlist2.GetNofHits(); ihit++) {
2577  hit = (PndTrkHit*) skewhitlist2.GetHit(ihit);
2578  if(!hit) continue;
2579  double zdistance = fabs(hit->GetPosition().Z() - fitm3 * hit->GetPhi() - fitq3);
2580  if(hit->IsMvd()) {
2581  // cout << "mvd " << mvdmeandist << " " << zdistance << " " << mvdmeandist - zdistance << endl;
2582  if(fabs(mvdmeandist - zdistance) < 2) skewhitlist3.AddHit(hit);
2583  }
2584  else if(hit->IsStt()) {
2585  // cout << "stt " << sttmeandist << " " << zdistance << " " << sttmeandist - zdistance << endl;
2586  if(fabs(sttmeandist - zdistance) < 10) skewhitlist3.AddHit(hit);
2587  }
2588  else if(hit->IsGem()) {
2589  // cout << "gem " << gemmeandist << " " << zdistance << " " << gemmeandist - zdistance << endl;
2590  if(fabs(gemmeandist - zdistance) < 20) skewhitlist3.AddHit(hit); // CHECK
2591  }
2592  else if(hit->IsSciTil()) {
2593  // cout << "scit " << scitmeandist << " " << zdistance << " " << scitmeandist - zdistance << endl;
2594  if(fabs(scitmeandist - zdistance) < 20) skewhitlist3.AddHit(hit); // CHECK
2595  }
2596  }
2597 
2598  // forget this track!
2599  if(skewhitlist3.GetNofHits() == 0) continue;
2600 
2601  if(fDisplayOn) {
2602  display->cd(4);
2603 
2604 
2605  cout << "final z " << skewhitlist3.GetNofHits() << endl;
2606  for(int ihit = 0; ihit < skewhitlist3.GetNofHits(); ihit++) {
2607  hit = (PndTrkHit*) skewhitlist3.GetHit(ihit);
2608 
2609  cout << "hitid " << hit->GetHitID() << " " << hit->GetDetectorID() << endl;
2610  display->cd(4);
2611  TMarker *mrkzphi = new TMarker(hit->GetPhi(), hit->GetPosition().Z(), 20);
2612  mrkzphi->SetMarkerColor(kMagenta);
2613  mrkzphi->Draw("SAME");
2614  display->Update();
2615  display->Modified();
2616  }
2617 
2618  char goOnChar;
2619  cin >> goOnChar;
2620  }
2621 
2622  // -------- refit with a line
2623  fFitter->Reset();
2624 
2625  // see the hits
2626  for(int ihit = 0; ihit < skewhitlist3.GetNofHits(); ihit++) {
2627  hit = skewhitlist3.GetHit(ihit);
2628  if(!hit) continue;
2629  TVector3 position = hit->GetPosition();
2630  double phi = finaltrack.ComputePhi(position);
2631  fFitter->SetPointToFit(phi, position.Z(), 0.1); // CHECK the error?
2632  // cout << "final point " << phi << " " << position.Z() << endl;
2633  if(fDisplayOn) {
2634  display->cd(4);
2635  TMarker *mrkzphi = new TMarker(phi, position.Z(), 20);
2636  mrkzphi->SetMarkerColor(kBlue);
2637  if(hit->IsStt() == kTRUE) mrkzphi->SetMarkerColor(kYellow);
2638  mrkzphi->Draw("SAME");
2639  display->Update();
2640  display->Modified();
2641  }
2642  }
2643 
2644  double fitm4, fitq4;
2645  fFitter->StraightLineFit(fitm4, fitq4);
2646 
2647  if(fDisplayOn) {
2648  display->cd(4);
2649  TLine *line = new TLine(0, fitq4, 360, 360 * fitm4 + fitq4);
2650  line->SetLineColor(4);
2651  line->Draw("SAME");
2652  display->Update();
2653  display->Modified();
2654  char goOnChar;
2655  cin >> goOnChar;
2656  }
2657 
2658  // finalize the cluster
2659  for(int ihit = 0; ihit < skewhitlist2.GetNofHits(); ihit++) {
2660  hit = skewhitlist2.GetHit(ihit);
2661  if(fFinalCluster->DoesContain(hit) == kFALSE) fFinalCluster->AddHit((PndTrkHit*) hit);
2662  }
2663 
2664  // sorting
2665  for(int ihit = 0; ihit < fFinalCluster->GetNofHits(); ihit++) {
2666  hit = fFinalCluster->GetHit(ihit);
2667  hit->SetSortVariable(hit->GetPosition().Perp());
2668 
2669  }
2670  fFinalCluster->Sort();
2671  // sorting
2672  for(int ihit = 0; ihit < fFinalCluster->GetNofHits(); ihit++) {
2673  hit = fFinalCluster->GetHit(ihit);
2674  }
2675 
2676  // fDisplayOn = kFALSE;
2677 
2678  // compute charge
2679  finaltrack.ComputeCharge();
2680 
2681  // last two parameters in real plane
2682  double tanl = - finaltrack.GetCharge() * fitm4 * (180./TMath::Pi())/R2;
2683  double z0 = fitq4;
2684 
2685 
2686 
2687  // PndTrkTrack *finaltrack2 = new PndTrkTrack(finalcluster, xc2, yc2, R2);
2688  finaltrack.SetCluster(fFinalCluster);
2689  finaltrack.SetZ0(z0);
2690  finaltrack.SetTanL(tanl);
2691  finaltrack.SetCluster(fFinalCluster);
2692  finaltrack.SetCenter(xc2, yc2);
2693  finaltrack.SetRadius(R2);
2694 
2695 
2696 // cout << "TRACK to TRACKLIST " << fTrackList->GetNofTracks() << endl;
2697 // cout << "X, Y, R " << finaltrack.GetCenter().X() << " " << finaltrack.GetCenter().Y() << " " << finaltrack.GetRadius() << endl;
2698 // cout << "Z0, TANL " << finaltrack.GetZ0() << " " << finaltrack.GetTanL() << endl;
2699 // cout << "CHARGE " << finaltrack.GetCharge() << endl;
2700 
2701  // clusterlist.AddCluster(finalcluster);
2702  fTrackList->AddTrack(&finaltrack);
2703  }
2704 
2705  // fDisplayOn = kTRUE;
2706 
2707 // cout << "TRACKS IN TRACKLIST " << fTrackList->GetNofTracks() << endl;
2708  if(fDisplayOn) {
2709  //char goOnChar; //[R.K. 01/2017] unused variable
2710  display->cd(1);
2711  for(int jtrk = 0; jtrk < fTrackList->GetNofTracks(); jtrk++) {
2713 
2714  track->Draw(kRed);
2715  display->Update();
2716  display->Modified();
2717 
2718  // cout << "TRACK " << jtrk << endl;
2719 // cout << "X, Y, R " << track->GetCenter().X() << " " << track->GetCenter().Y() << " " << track->GetRadius() << endl;
2720 // cout << "Z0, TANL " << track->GetZ0() << " " << track->GetTanL() << endl;
2721 // cout << "CHARGE " << track->GetCharge() << endl;
2722 // cin >> goOnChar;
2723  }
2724  }
2725 
2726  // ====== MERGIN ==========================
2727  PndTrkTrackList *mergedtracklist = new PndTrkTrackList();
2728  // choose what to merge
2729  std::vector< int > merged;
2730  merged.resize(fTrackList->GetNofTracks());
2731  for(int itrk = 0; itrk < fTrackList->GetNofTracks(); itrk++) merged[itrk] = 0;
2732  std::map < int , std::vector < int > > mergingtracks;
2733 
2734  for(int itrk = 0; itrk < fTrackList->GetNofTracks(); itrk++) {
2735  if(merged[itrk] == 1) continue;
2736  PndTrkTrack *tracki = fTrackList->GetTrack(itrk);
2737  PndTrkCluster clusteri = tracki->GetCluster();
2738  std::vector< int > mtracks;
2739  for(int jtrk = itrk + 1; jtrk < fTrackList->GetNofTracks() ; jtrk++) {
2740  if(merged[jtrk] == 1) continue;
2741  PndTrkTrack *trackj = fTrackList->GetTrack(jtrk);
2742  PndTrkCluster clusterj = trackj->GetCluster();
2743  if(clusterj.SharedAt(&clusteri, 0.70) == kTRUE) {
2744  mtracks.push_back(jtrk);
2745  // cout << "track " << itrk << " needs merging with track " << jtrk << endl;
2746  merged[itrk] = 1; // CHECK save time!
2747  merged[jtrk] = 1;
2748  }
2749  }
2750  if(mtracks.size() == 0) mtracks.push_back(-1);
2751  mergingtracks.insert(std::pair<int , std::vector < int > >(itrk, mtracks));
2752  // cout << "pair of " << itrk << " and " << mtracks.size() << endl;
2753  }
2754 
2755  // cout << "merging " << mergingtracks.size() << endl;
2756  // do the actual merging
2757  std::map< int, std::vector < int > >::iterator it;
2758  for(int itrk = 0; itrk < fTrackList->GetNofTracks(); itrk++) {
2759  PndTrkTrack *tracki = fTrackList->GetTrack(itrk);
2760  PndTrkCluster clusteri = tracki->GetCluster();
2761  it = mergingtracks.find(itrk);
2762  if(it == mergingtracks.end()) continue;
2763 
2764  std::vector< int > mtracks = it->second;
2765  // if it has merged tracks
2766  if(mtracks[0] != -1) {
2767  // cout << it->first << "/" << mergingtracks.size() << endl; // " last fit " << clusteri.GetNofHits() << endl;
2768  // cout << "i " << clusteri.GetNofHits() << endl;
2769  for(size_t ktrk = 0; ktrk < mtracks.size(); ktrk++) {
2770  int jtrk = mtracks[ktrk];
2771  PndTrkTrack *trackj = fTrackList->GetTrack(jtrk);
2772  PndTrkCluster clusterj = trackj->GetCluster();
2773  clusteri.MergeTo(&clusterj);
2774  }
2775  }
2776 
2777  //--------------------------------------
2778  // to conformal
2779  fRefHit = clusteri.GetHit(clusteri.GetNofHits() - 1);
2781  double delta, trasl[2];
2782  ComputeTraAndRot(fRefHit, delta, trasl);
2783  conform->SetOrigin(trasl[0], trasl[1], delta);
2785  // cout << "conformal hits " << fConformalHitList->GetNofHits() << endl;
2786 
2787  // fill conformal hits
2788  int nofconfhits = FillConformalHitList(&clusteri);
2789 
2790  // compute conformal plane extremities ---------------------------- this must go to a fctn CHECK
2791  fUmin = 1000, fVmin = 1000, fRmin = 1000;
2792  fUmax = -1000, fVmax = -1000, fRmax = -1000;
2793  double rc_of_min, rc_of_max;
2794 
2795  for(int jhit = 0; jhit < fConformalHitList->GetNofHits(); jhit++) {
2797  double u = chit->GetU();
2798  double v = chit->GetV();
2799  double rc = chit->GetIsochrone();
2800  if(rc < 0) rc = 0;
2801  // cout << "conf hit " << jhit << " u, v " << u << " " << v << " " << rc << endl;
2802  u - rc < fUmin ? fUmin = u - rc : fUmin;
2803  v - rc < fVmin ? fVmin = v - rc : fVmin;
2804  u + rc > fUmax ? fUmax = u + rc : fUmax;
2805  v + rc > fVmax ? fVmax = v + rc : fVmax;
2806 
2807  double theta1 = TMath::ATan2(v, u);
2808  double theta2 = theta1 + TMath::Pi();
2809 
2810  double r1 = u * TMath::Cos(theta1) + v * TMath::Sin(theta1);
2811  double r2 = u * TMath::Cos(theta2) + v * TMath::Sin(theta2);
2812 
2813  double rimin, rimax;
2814  r1 < r2 ? (rimin = r1, rimax = r2) : (rimin = r2, rimax = r1);
2815 
2816  rimin < fRmin ? (rc_of_min = rc, fRmin = rimin) : fRmin;
2817  rimax > fRmax ? (rc_of_max = rc, fRmax = rimax) : fRmax;
2818  }
2819 
2820  fRmin -= rc_of_min;
2821  fRmax += rc_of_max;
2822 
2823  // to square the conformal plane
2824  double du = fUmax - fUmin;
2825  double dv = fVmax - fVmin;
2826  double delt = 0.5 * fabs(dv - du);
2827  du < dv ? (fUmin -= delt, fUmax += delt) : (fVmin -= delt, fVmax += delt);
2828 
2829  if(fDisplayOn) {
2830  DrawGeometryConf(fUmin, fUmax, fVmin, fVmax);
2831  // ----------------------------------------------------------------------
2832  for(int ihit = 0; ihit < nofconfhits; ihit++) {
2834  if(fDisplayOn) {
2835  chit->Draw(kRed);
2836  }
2837  }
2838  }
2839 
2840 
2841  // last fit
2842  double xc2 = tracki->GetCenter().X();
2843  double yc2 = tracki->GetCenter().Y();
2844  double R2 = tracki->GetRadius();
2845  double fitm, fitq;
2846 
2847  double xc3, yc3, R3;
2848  // line or parabola
2849  if(1 == 1) {
2850  bool fitting = AnalyticalFit(&clusteri, xc2, yc2, R2, fitm, fitq);
2851  if(fitting == kFALSE) continue;
2852  FromConformalToRealTrack(fitm, fitq, xc3, yc3, R3);
2853  if(fDisplayOn) {
2854  //char goOnChar; //[R.K. 01/2017] unused variable
2855  display->cd(2);
2856  TLine *line = new TLine(-10, -10 * fitm + fitq, 10, 10 * fitm + fitq);
2857  line->SetLineColor(kMagenta);
2858  line->Draw("SAME");
2859  }
2860  }
2861  else {
2862  double fita, fitb, fitc, epsilon;
2863  bool fitting = AnalyticalParabolaFit(&clusteri, xc2, yc2, R2, fita, fitb, fitc, epsilon);
2864  if(fitting == kFALSE) continue;
2865  FromConformalToRealTrackParabola(fita, fitb, fitc, xc3, yc3, R3, epsilon);
2866  }
2867 
2868  if(fDisplayOn) {
2869  char goOnChar;
2870  Refresh();
2871 
2872  display->cd(1);
2873  clusteri.LightUp();
2874  TArc *arcm = new TArc(xc3, yc3, R3);
2875  arcm->SetFillStyle(0);
2876  arcm->SetLineColor(kMagenta);
2877  arcm->Draw("SAME");
2878 
2879  display->Update();
2880  display->Modified();
2881  cin >> goOnChar;
2882  }
2883 
2884  tracki->SetCluster(&clusteri);
2885  tracki->SetCenter(xc3, yc3);
2886  tracki->SetRadius(R3);
2887 
2888  mergedtracklist->AddTrack(tracki);
2889  }
2890 
2891 
2892 // cout << "TRACKS IN MERGED TRACK LIST " << mergedtracklist->GetNofTracks() << endl;
2893  if(fDisplayOn) {
2894  //char goOnChar; //[R.K. 01/2017] unused variable
2895  display->cd(1);
2896  for(int jtrk = 0; jtrk < mergedtracklist->GetNofTracks(); jtrk++) {
2897  PndTrkTrack *track = mergedtracklist->GetTrack(jtrk);
2898 
2899  track->Draw(kBlue);
2900  display->Update();
2901  display->Modified();
2902 
2903  // cout << "MERGED TRACK " << jtrk << endl;
2904 // cout << "X, Y, R " << track->GetCenter().X() << " " << track->GetCenter().Y() << " " << track->GetRadius() << endl;
2905 // cout << "Z0, TANL " << track->GetZ0() << " " << track->GetTanL() << endl;
2906 // cout << "CHARGE " << track->GetCharge() << endl;
2907 // cin >> goOnChar;
2908  }
2909  }
2910 
2911  // =============================================
2912  // CLEANING
2913  // rms
2914  PndTrkTrackList *cleanedtracklist = new PndTrkTrackList();
2915  for(int itrk = 0; itrk < mergedtracklist->GetNofTracks(); itrk++) {
2916  PndTrkTrack *track = mergedtracklist->GetTrack(itrk);
2917  double xc3 = track->GetCenter().X();
2918  double yc3 = track->GetCenter().Y();
2919  double R3 = track->GetRadius();
2920 
2921  bool vote = true;
2922  // CHI2 ___________________
2923  double gap[5] = {0, 0, 0, 0, 0};
2924  int gapcounter[5] = {0, 0, 0, 0, 0};
2925  PndTrkCluster clusteri = track->GetCluster();
2926 
2927  // check if it is a long track
2928  hit = clusteri.GetHit(0);
2929  // cout << "FIRST LAY " << hit->GetDetectorID() << endl;
2930  if(hit->GetDetectorID() == FairRootManager::Instance()->GetBranchId(fSttBranch)) {
2931  PndSttTube *tube0 = (PndSttTube* ) fTubeArray->At(hit->GetTubeID());
2932  // cout << tube0->GetLayerID() << endl;
2933  if(tube0->GetLayerID() > 4) continue; // CHECK
2934  }
2935  hit = clusteri.GetHit(clusteri.GetNofHits() - 1);
2936  // cout << "LAST LAY " << hit->GetDetectorID() << endl;
2937  if(hit->GetDetectorID() == FairRootManager::Instance()->GetBranchId(fSttBranch)) {
2938  PndSttTube *tubeN = (PndSttTube* ) fTubeArray->At(hit->GetTubeID());
2939  // cout << tubeN->GetLayerID() << endl;
2940  if(tubeN->GetLayerID() < 16) continue; // CHECK
2941  }
2942 
2943  for(int ihit = 0; ihit < clusteri.GetNofHits(); ihit++) {
2944  hit = clusteri.GetHit(ihit);
2945  int detID = hit->GetDetectorID();
2946  TVector3 pos = hit->GetPosition();
2947 
2948  // mvd pix
2949  if(detID == FairRootManager::Instance()->GetBranchId(fMvdPixelBranch)) {
2950  gap[0] += fabs(TMath::Sqrt((pos.X() - xc3) * (pos.X() - xc3) + (pos.Y() - yc3) * (pos.Y() - yc3)) - R3);
2951  gapcounter[0]++;
2952  }
2953  // mvd str
2954  else if(detID == FairRootManager::Instance()->GetBranchId(fMvdStripBranch)) {
2955  gap[1] += fabs(TMath::Sqrt((pos.X() - xc3) * (pos.X() - xc3) + (pos.Y() - yc3) * (pos.Y() - yc3)) - R3);
2956  gapcounter[1]++;
2957  }
2958  // stt
2959  else if(detID == FairRootManager::Instance()->GetBranchId(fSttBranch)) {
2960  gap[2] += fabs(TMath::Sqrt((pos.X() - xc3) * (pos.X() - xc3) + (pos.Y() - yc3) * (pos.Y() - yc3)) - R3) - hit->GetIsochrone();
2961  gapcounter[2]++;
2962  }
2963  // scitil;
2964  else if(detID == FairRootManager::Instance()->GetBranchId(fSciTBranch)) {
2965  gap[3] += fabs(TMath::Sqrt((pos.X() - xc3) * (pos.X() - xc3) + (pos.Y() - yc3) * (pos.Y() - yc3)) - R3);
2966  gapcounter[3]++;
2967  }
2968  // gem
2969  else if(detID == FairRootManager::Instance()->GetBranchId(fGemBranch)) {
2970  gap[4] += fabs(TMath::Sqrt((pos.X() - xc3) * (pos.X() - xc3) + (pos.Y() - yc3) * (pos.Y() - yc3)) - R3);
2971  gapcounter[4]++;
2972  }
2973  }
2974 
2975  // give large cuts CHECK
2976  for(int igap = 0; igap < 5; igap++) {
2977  if(gapcounter[igap] > 0) {
2978  gap[igap]/= gapcounter[igap];
2979  gap[igap] = fabs(gap[igap]);
2980  }
2981  }
2982  if(gap[0] > 2) vote = false; // mvd pix
2983  if(gap[1] > 2) vote = false; // mvd str
2984  if(gap[2] > 10) vote = false; // stt
2985  if(gap[3] > 2) vote = false; // scit
2986  if(gap[4] > 2) vote = false; // gem
2987  // cout << "VOTE " << vote << " " << gap[0] << " " << gap[1] << " " << gap[2] << " " << gap[3] << " " << gap[4] << endl;
2988 
2989  if(vote == true) cleanedtracklist->AddTrack(track);
2990  }
2991  delete mergedtracklist;
2992 // cout << "TRACKS IN CLEANED TRACK LIST " << cleanedtracklist->GetNofTracks() << endl;
2993 
2994  // at last, add the INDIVISIBLES
2995  PndTrkTrackList *indivtracklist = new PndTrkTrackList();
2996  for(int itrk = 0; itrk < cleanedtracklist->GetNofTracks(); itrk++) {
2997  PndTrkTrack *tracki = cleanedtracklist->GetTrack(itrk);
2998  PndTrkCluster clusteri = tracki->GetCluster();
2999  if(fDisplayOn) {
3000  char goOnChar;
3001  display->cd(1);
3002  Refresh();
3003  clusteri.Draw(kRed);
3004  display->Update();
3005  display->Modified();
3006  cin >> goOnChar ;
3007  }
3008  for(int ihit = 0; ihit < clusteri.GetNofHits(); ihit++) {
3009  hit = clusteri.GetHit(ihit);
3010  if(hit->GetDetectorID() != FairRootManager::Instance()->GetBranchId(fSttBranch)) continue;
3011  TObjArray indiv2 = fHitMap->GetIndivisiblesToHit(hit);
3012 
3013  if(fDisplayOn) {
3014  hit->Draw(kBlue);
3015  display->Update();
3016  display->Modified();
3017  }
3018  for(int jhit = 0; jhit < indiv2.GetEntriesFast(); jhit++) {
3019  PndTrkHit *hit2 = (PndTrkHit*) indiv2.At(jhit);
3020  if(fDisplayOn) {
3021  hit2->Draw(kGreen);
3022  display->Update();
3023  display->Modified();
3024  }
3025  hit2->SetSortVariable(hit2->GetPosition().Perp());
3026  if(!clusteri.DoesContain(hit2)) {
3027 
3028  //double distance_hit_center = (hit2->GetPosition().XYvector() - TVector2(tracki->GetCenter().X(), tracki->GetCenter().Y())).Mod(); //[R.K. 01/2017] unused variable?
3029  //double recoiso = fabs(distance_hit_center - tracki->GetRadius()); //[R.K. 01/2017] unused variable
3030  // if(recoiso < 0.5)
3031  clusteri.AddHit(hit2);
3032  }
3033  }
3034  if(fDisplayOn) {
3035  //char goOnChar; //[R.K. 01/2017] unused variable
3036  // cin >> goOnChar ;
3037  }
3038  }
3039  clusteri.Sort();
3040  tracki->SetCluster(&clusteri);
3041  if(fDisplayOn) {
3042  char goOnChar;
3043  display->cd(1);
3044  Refresh();
3045  clusteri.Draw(kMagenta);
3046  tracki->Draw();
3047  display->Update();
3048  display->Modified();
3049  cin >> goOnChar ;
3050  }
3051  indivtracklist->AddTrack(tracki);
3052  }
3053  delete cleanedtracklist;
3054 
3055  for(int itrk = 0; itrk < indivtracklist->GetNofTracks(); itrk++) {
3056  PndTrkTrack *tracki = indivtracklist->GetTrack(itrk);
3057  fTrackList->AddTrack(tracki);
3058  }
3059  delete indivtracklist;
3060 
3061  if(fDisplayOn) {
3062  //char goOnChar; //[R.K. 01/2017] unused variable
3063  display->cd(1);
3064  Refresh();
3065  }
3066  //
3067  // fDisplayOn = kTRUE;
3068 
3069  //--------------------------------------
3070  // PndTrkTrack --> PndTrack
3071  for(int itrk = 0; itrk < fTrackList->GetNofTracks(); itrk++) {
3073  // cout << "- ----------------------------------- track red " << track->GetRadius() << endl;
3074 
3075  // CHECK CHECK CHECK CHECK CHECK CHECK CHECK CHECK CHECK CHECK CHECK CHECK CHECK CHECK
3076  // temporary hacking not to save the SciTil to PndTrackCand CHECK CHECK CHECK CHECK
3077  // CHECK CHECK CHECK CHECK CHECK CHECK CHECK CHECK CHECK CHECK CHECK CHECK CHECK CHECK
3078  PndTrkCluster tempcluster = track->GetCluster();
3079  PndTrkCluster tempcluster2;
3080  for(int ihit = 0; ihit < tempcluster.GetNofHits(); ihit++) {
3081  hit = tempcluster.GetHit(ihit);
3082  if(hit->IsSciTil() == kTRUE) continue;
3083  tempcluster2.AddHit(hit);
3084  }
3085  track->SetCluster(&tempcluster2);
3086  //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
3087 
3088  PndTrack theTrack = track->ConvertToPndTrack();
3089 
3090  TClonesArray& clref1 = *fTrackArray;
3091  Int_t size = clref1.GetEntriesFast();
3092  PndTrack *outputtrack = new(clref1[size]) PndTrack(theTrack.GetParamFirst(),theTrack.GetParamLast(), theTrack.GetTrackCand());
3093  outputtrack->SetFlag(111);
3094  if(fabs(outputtrack->GetParamFirst().GetMomentum().Z()) < 1e-10) outputtrack->SetFlag(-111);
3095 
3096  TClonesArray& clref2 = *fTrackCandArray;
3097  size = clref2.GetEntriesFast();
3098  PndTrackCand *outputtrackcand = new(clref2[size]) PndTrackCand(theTrack.GetTrackCand());
3099 
3100  TClonesArray& clref3 = *fTrkTrackArray;
3101  size = clref3.GetEntriesFast();
3102  new(clref3[size]) PndTrkTrack(*track); // PndTrkTrack *outputtrktrack = //[R.K.03/2017] unused variable
3103 
3104  // cout << "\033[1;31m RECO R " << outputtrktrack->GetRadius() << ", " << outputtrack->GetParamFirst().GetMomentum().Perp() / 0.006 << "\033[0m" << endl;
3105  // cout << "MOM FIRST: TOT, PT, PL " << outputtrack->GetParamFirst().GetMomentum().Mag() << " " << outputtrack->GetParamFirst().GetMomentum().Perp() << " " << outputtrack->GetParamFirst().GetMomentum().Z() << endl;
3106  // cout << "MOM LAST: TOT, PT, PL " << outputtrack->GetParamLast().GetMomentum().Mag() << " " << outputtrack->GetParamLast().GetMomentum().Perp() << " " << outputtrack->GetParamLast().GetMomentum().Z() << endl;
3107 
3108  if(fDisplayOn) {
3109  char goOnChar;
3110  Refresh();
3111  display->cd(1);
3112  track->Draw(kRed);
3113  track->GetCluster().LightUp();
3114  display->Update();
3115  display->Modified();
3116 
3117  cout << "TRACK " << itrk << endl;
3118  cout << "MOM FIRST: TOT, PT, PL " << outputtrack->GetParamFirst().GetMomentum().Mag() << " " << outputtrack->GetParamFirst().GetMomentum().Perp() << " " << outputtrack->GetParamFirst().GetMomentum().Z() << " nofhits " << outputtrackcand->GetNHits() << endl;
3119  cout << "X, Y, R " << track->GetCenter().X() << " " << track->GetCenter().Y() << " " << track->GetRadius() << endl;
3120  cout << "Z0, TANL " << track->GetZ0() << " " << track->GetTanL() << endl;
3121  cout << "CHARGE " << track->GetCharge() << endl;
3122  cin >> goOnChar;
3123  }
3124 
3125  }
3126 
3127  int noflongtracks = fTrackArray->GetEntriesFast();
3128 
3129  // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3130  // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3131  // FFFFF W W DDD
3132  // F W W D D
3133  // FFFF W W W D D
3134  // F W W W D D
3135  // F W W DDDD
3136  // fDisplayOn = kFALSE;
3137  // fDisplayOn = kTRUE;
3138  // set unusable the hits assigned to long tracks ....................................
3139  for(int itrk = fNofPrimaries; itrk < fTrackArray->GetEntriesFast(); itrk++) {
3140  PndTrack *trk = (PndTrack*) fTrackArray->At(itrk);
3141  PndTrackCand *cand = trk->GetTrackCandPtr();
3142  if(!cand)
3143  {
3144  cout << "ERROR track " << itrk << " has no candidate association" << endl;
3145  continue;
3146  }
3147  // cout << fNofPrimaries << " track " << trk << " cand " << cand << endl;
3148  for (size_t ihit = 0; ihit < cand->GetNHits(); ihit++) {
3149  PndTrackCandHit candhit = cand->GetSortedHit(ihit);
3150  Int_t hitId = candhit.GetHitId();
3151  Int_t detId = candhit.GetDetId();
3152 
3153  if(detId == FairRootManager::Instance()->GetBranchId(fMvdPixelBranch)) {
3154  hit = mvdpixhitlist->GetHitByID(hitId);
3155  }
3156  // mvd str
3157  else if(detId == FairRootManager::Instance()->GetBranchId(fMvdStripBranch)) {
3158  hit = mvdstrhitlist->GetHitByID(hitId);
3159  }
3160  // stt
3161  else if(detId == FairRootManager::Instance()->GetBranchId(fSttBranch)) {
3162  hit = stthitlist->GetHitByID(hitId);
3163  }
3164  // scitil;
3165  else if(detId == FairRootManager::Instance()->GetBranchId(fSciTBranch)) {
3166  hit = scithitlist->GetHitByID(hitId);
3167  }
3168  // gem
3169  else if(detId == FairRootManager::Instance()->GetBranchId(fGemBranch)) {
3170  hit = gemhitlist->GetHitByID(hitId);
3171  }
3172  hit->SetUsedFlag(true);
3173  }
3174 
3175  }
3176 
3177  if(fDisplayOn) {
3178  Refresh();
3179 
3180  for(int itrk = 0; itrk < fTrackArray->GetEntriesFast(); itrk++) {
3181  PndTrack *trk = (PndTrack*) fTrackArray->At(itrk);
3182  PndTrkTrack track(trk);
3183  track.Draw();
3184  }
3185 
3186 
3187  char goOnChar;
3188  display->Update();
3189  display->Modified();
3190  cin >> goOnChar;
3191  }
3192  // ........................................................................................
3193 
3194  // Lets start from the GEM stations
3195  PndTrkCluster gemcluster;
3196 
3197  // sort by layer id 1, 2, 3, 4, 5, 6
3198  int nofgemhits_on_layer[NOFLAYERS] = {0, 0, 0, 0, 0, 0}; // CHECK
3199  for(int ihit = 0; ihit < gemhitlist->GetNofHits(); ihit++) {
3200  hit = gemhitlist->GetHit(ihit);
3201  if(hit->IsUsed() == kTRUE) continue;
3202  int layerid = hit->GetSensorID();
3203  hit->SetSortVariable(layerid);
3204  gemcluster.AddHit(hit);
3205  nofgemhits_on_layer[layerid]++;
3206  }
3207  gemcluster.Sort();
3208 
3209  for(int ihit = 0; ihit < gemcluster.GetNofHits(); ihit++) {
3210  PndTrkHit *hiti = gemcluster.GetHit(ihit);
3211  hiti->SetUsedFlag(kFALSE);
3212  }
3213 
3214  PndTrkClusterList newclusterlist;
3215 
3216  // make tracklets out of the gem hits ..............................
3217  // cout << "GEM CLUSTER " << gemcluster.GetNofHits() << endl;
3218  for(int ihit = 0; ihit < gemcluster.GetNofHits(); ihit++) {
3219  PndTrkHit *hiti = gemcluster.GetHit(ihit);
3220  if(hiti->IsUsed() == kTRUE) continue;
3221  PndTrkCluster cluster;
3222  cluster.AddHit(hiti);
3223 
3224  if(fDisplayOn) {
3225  Refresh();
3226  hiti->Draw(kRed);
3227  //char goOnChar; //[R.K. 01/2017] unused variable
3228  display->Update();
3229  display->Modified();
3230  // cin >> goOnChar;
3231  }
3232 
3233  hiti->SetUsedFlag(kTRUE);
3234  //int layerid = hiti->GetSensorID(); //[R.K. 01/2017] unused variable
3235  PndTrkHit *tmphiti = hiti;
3236 
3237  bool goOn = true;
3238  PndTrkHit *tmphitj = hiti;
3239 
3240  while(goOn == true) {
3241 
3242  double tmpdistance = 1000;
3243  for(int jhit = 0; jhit < gemcluster.GetNofHits(); jhit++) {
3244  PndTrkHit *hitj = gemcluster.GetHit(jhit);
3245  if(hitj->IsUsed() == kTRUE) continue;
3246  int layerjd = hitj->GetSensorID();
3247 
3248  if(layerjd != tmphitj->GetSensorID() + 1) continue;
3249 
3250  double distance = hitj->GetXYDistance(tmphiti);
3251  if(distance < tmpdistance) {
3252  tmphitj = hitj;
3253  tmpdistance = distance;
3254  // cout << "distance " << distance << " " << tmpdistance << endl;
3255  }
3256  }
3257 
3258  if(tmpdistance < 20) {
3259  cluster.AddHit(tmphitj);
3260  tmphitj->SetUsedFlag(kTRUE);
3261  tmphiti = tmphitj;
3262 
3263  if(fDisplayOn) {
3264  Refresh();
3265  tmphitj->Draw(kBlue);
3266  //char goOnChar; //[R.K. 01/2017] unused variable
3267  display->Update();
3268  display->Modified();
3269  // cin >> goOnChar;
3270  }
3271  }
3272  else goOn = false;
3273  }
3274 
3275  // cout << "CLUSTER " << cluster.GetNofHits() << endl;
3276  if(cluster.GetNofHits() >= 3) {
3277 
3278 
3279  // --------------------------------------------------------------
3280  // FIT THE CLUSTER
3281  //
3282  if(fDisplayOn) {
3283  Refresh();
3284  cluster.LightUp();
3285  char goOnChar;
3286  display->Update();
3287  display->Modified();
3288  cin >> goOnChar;
3289  }
3290 
3318  // ---------------------------------
3319  fConformalHitList->Clear("C");
3320  Double_t delta = 0, trasl[2] = {0., 0.};
3321  PndTrkHit *refhit = NULL;
3322 
3323  int tmpsensid = 1000;
3324  for(int jhit = 0; jhit < cluster.GetNofHits(); jhit++) {
3325  PndTrkHit * hitj = cluster.GetHit(jhit);
3326  if(hitj->GetSensorID() < tmpsensid) {
3327  refhit = hitj;
3328  tmpsensid = hitj->GetSensorID();
3329  }
3330  }
3331  ComputeTraAndRot(refhit, delta, trasl);
3332 
3333  conform->SetOrigin(trasl[0], trasl[1], delta);
3335 
3336  // fill conformal hits
3337  Int_t nofconfhits = FillConformalHitList(&cluster);
3338 
3339  // compute conformal plane extremities ----------------------------
3340  fUmin = 1000, fVmin = 1000, fRmin = 1000;
3341  fUmax = -1000, fVmax = -1000, fRmax = -1000;
3342  double rc_of_min, rc_of_max;
3343  fFitter->Reset();
3344  for(int jhit = 0; jhit < fConformalHitList->GetNofHits(); jhit++) {
3346  double u = chit->GetU();
3347  double v = chit->GetV();
3348  double rc = chit->GetIsochrone();
3349  if(rc < 0) rc = 0;
3350 
3351  double sigma = 1000.;
3352  if(hit->IsGem()) sigma = 0.1 * hit->GetPosition().Z(); // CHECK
3353  if(TMath::IsNaN(chit->GetPosition().X())) continue; // prevents the nan of the ref hit
3354  fFitter->SetPointToFit(chit->GetPosition().X(), chit->GetPosition().Y(), sigma);
3355 
3356  // cout << "conf hit " << jhit << " u, v " << u << " " << v << " " << rc << endl;
3357  u - rc < fUmin ? fUmin = u - rc : fUmin;
3358  v - rc < fVmin ? fVmin = v - rc : fVmin;
3359  u + rc > fUmax ? fUmax = u + rc : fUmax;
3360  v + rc > fVmax ? fVmax = v + rc : fVmax;
3361 
3362  double theta1 = TMath::ATan2(v, u);
3363  double theta2 = theta1 + TMath::Pi();
3364 
3365  double r1 = u * TMath::Cos(theta1) + v * TMath::Sin(theta1);
3366  double r2 = u * TMath::Cos(theta2) + v * TMath::Sin(theta2);
3367 
3368  double rimin, rimax;
3369  r1 < r2 ? (rimin = r1, rimax = r2) : (rimin = r2, rimax = r1);
3370 
3371  rimin < fRmin ? (rc_of_min = rc, fRmin = rimin) : fRmin;
3372  rimax > fRmax ? (rc_of_max = rc, fRmax = rimax) : fRmax;
3373  }
3374 
3375  fRmin -= rc_of_min;
3376  fRmax += rc_of_max;
3377 
3378  // to square the conformal plane
3379  double du = fUmax - fUmin;
3380  double dv = fVmax - fVmin;
3381  double delt = fabs(dv - du)/2.;
3382  du < dv ? (fUmin -= delt, fUmax += delt) : (fVmin -= delt, fVmax += delt);
3383 
3384  if(fDisplayOn) {
3385  DrawGeometryConf(fUmin, fUmax, fVmin, fVmax);
3386  // ----------------------------------------------------------------------
3387  for(int khit = 0; khit < nofconfhits; khit++) {
3389  chit->Draw(kBlack);
3390  }
3391  }
3392 
3393  // ====== REFIT CLUSTER LEGENDRE
3394  double fitm, fitq;
3395  fFitter->StraightLineFit(fitm, fitq);
3396 
3397  if(fDisplayOn) {
3398  RefreshConf();
3399  DrawGeometryConf(fUmin, fUmax, fVmin, fVmax);
3400  }
3401 
3402  // from line parameters to center/radius in REAL plane
3403  Double_t xc, yc, R;
3404  FromConformalToRealTrack(fitm, fitq, xc, yc, R);
3405  // ----------------------------------
3406 
3407 
3408 
3409  if(fDisplayOn) {
3410  char goOnChar;
3411  display->cd(1);
3412  TArc *arcm = new TArc(xc, yc, R);
3413  arcm->SetFillStyle(0);
3414  arcm->SetLineColor(3);
3415  arcm->Draw("SAME");
3416  display->Update();
3417  display->Modified();
3418  cin >> goOnChar;
3419  }
3420 
3421  newclusterlist.AddCluster(&cluster);
3422 
3423  // put in a list the hits you considered and
3424  // decided do not belong to the track
3425  std::vector< std::pair< int, int > > dontuse;
3426 
3427 
3428  // GET SECTOR ID ---------------------------------------------
3429  std::map< int, int > sectorids;
3430  for(int jhit = 0; jhit < cluster.GetNofHits(); jhit++)
3431  {
3432  hit = cluster.GetHit(jhit);
3433  if(hit == fRefHit) continue;
3434  int secid = hit->GetSector();
3435 
3436  if(sectorids.find(secid) == sectorids.end()) sectorids[secid] = 1;
3437  else sectorids[secid]++;
3438  }
3439 
3440  int tmpsecentries = 0, tmpsec = -1;
3441  for(size_t isec = 0; isec < sectorids.size(); isec++) {
3442  if(tmpsecentries < sectorids[isec]) {
3443  tmpsecentries = sectorids[isec];
3444  tmpsec = isec;
3445  }
3446  }
3447  int sectorID = tmpsec;
3448  // cout << "SECTOR " << sectorID << " " << sectorids.size() << endl;
3449 
3450  // border?
3451  bool border = false;
3452  int othersecID = -1;
3453  for(size_t isec = 0; isec < sectorids.size(); isec++) {
3454  if(sectorids[isec] > 0 && (int)isec != sectorID) {
3455  border = true;
3456  othersecID = isec;
3457  }
3458  }
3459  // cout << "SECTOR " << sectorID << " " << sectorids.size() << " " << othersecID << " " << border << endl;
3460  // --------------------------------------------------------------
3461 
3462  // EVALUATE WHICH SECTORS are interesting
3463  // due to the curvature radius
3464 
3465  double xydistance = TMath::Sqrt(xc * xc + yc * yc);
3466 
3467  // cout << CTINRADIUS - R << endl;
3468  bool searchnearby = false;
3469  if(xydistance < CTINRADIUS - R) {
3470 // cout << "************* INTERNAL TO INNER *****************" << endl;
3471  continue;
3472  }
3473  else if(xydistance < CTINRADIUS + R && xydistance < CTOUTRADIUS - R) {
3474 // cout << "************* INTERSECTING INNER *****************" << endl;
3475  searchnearby = true;
3476  }
3477  else if(xydistance < CTINRADIUS + R) {
3478 // cout << "************* INTERSECTING BOTH *****************" << endl;
3479  }
3480  else if(xydistance < CTOUTRADIUS - R) {
3481 // cout << "************* INTERNAL *****************" << endl;
3482  searchnearby = true;
3483  }
3484  else if(xydistance < CTOUTRADIUS + R) {
3485 // cout << "************* INTERSECTING EXTERNAL *****************" << endl;
3486  searchnearby = true;
3487  }
3488  else {
3489 // cout << "************* EXTERNAL TO OUTER *****************" << endl;
3490  continue;
3491  }
3492 
3493  // does it cross the target pipe?
3494  bool crossL = false;
3495  double y1left = 0, y2left = 0;
3496  double delta1 = R * R - (0.5 * PIPEDIAMETER - xc) * (0.5 * PIPEDIAMETER - xc);
3497  // cout << "delta1 " << delta1 << endl;
3498  if(delta1 == 0) {
3499  y1left = yc;
3500  crossL = true;
3501  }
3502  else if(delta1 > 0) {
3503  y1left = yc + TMath::Sqrt(delta1);
3504  y2left = yc - TMath::Sqrt(delta1);
3505  crossL = true;
3506  }
3507 
3508  bool crossR = false;
3509  double y1right = 0, y2right = 0;
3510  double delta2 = R * R - (-0.5 * PIPEDIAMETER - xc) * (-0.5 * PIPEDIAMETER - xc);
3511  if(delta2 == 0) {
3512  y1right = yc;
3513  crossR = true;
3514  }
3515  else if(delta2 > 0) {
3516  y1right = yc + TMath::Sqrt(delta2);
3517  y2right = yc - TMath::Sqrt(delta2);
3518  crossR = true;
3519  }
3520  // cout << "CROSS? " << crossL << " " << crossR << endl;
3521  bool crossingpipe = false;
3522  if(crossL && crossR) {
3523  double ycross = 0.5 * (y1left + y1right);
3524  if(fabs(ycross) < CTOUTRADIUS && fabs(ycross) > CTINRADIUS) crossingpipe = true;
3525  ycross = 0.5 * (y2left + y2right);
3526  if(fabs(ycross) < CTOUTRADIUS && fabs(ycross) > CTINRADIUS) crossingpipe = true;
3527 
3528  // cout << ycross << " " << y1left << " " << y1right << " " << y2left << " " << y2right << endl;
3529  }
3530 
3531 
3532  if(crossingpipe) {
3533  // cout << "************* CROSSING PIPE *****************" << endl;
3534  crossingpipe = true;
3535  }
3536 
3537  // -----------------------------------------
3538  // === CREATE CLUSTER - taken from PndTrkFinder ---> will be put in a fctn
3539  // in the same sector or
3540  // nearby if at the limit of two sectors <<<<<<<<<<<<------------------
3541  PndTrkCluster cluster2(cluster);
3542 
3543  // create cluster depending on fitting
3544  for(int jhit = 0; jhit < stthitlist->GetNofHits(); jhit++) {
3545  hit = stthitlist->GetHit(jhit);
3546  if(hit->IsUsed() == kTRUE) continue;
3547  if(hit->IsSttParallel() == kFALSE) continue;
3548 
3549  if(crossingpipe == true) {
3550  if(((hit->GetSector() == 0 && sectorID == 5) && !(hit->GetSector() == 2 && sectorID == 3) && !(hit->GetSector() == 5 && sectorID == 0) && !(hit->GetSector() == 3 && sectorID == 2)) && searchnearby == false) continue;
3551  }
3552  else if(searchnearby == true) { // search in this sector and +/- 1
3553  if(fabs(hit->GetSector() - sectorID) > 1 && !(hit->GetSector() == 5 && sectorID == 0) && !(hit->GetSector() == 0 && sectorID == 5)) continue;
3554  }
3555  else { // search only in this sector and possible othersector
3556  if(border == false && hit->GetSector() != sectorID) continue;
3557  else if(border == true && (hit->GetSector() != sectorID && hit->GetSector() != othersecID)) continue;
3558  }
3559  //double distance = hit->GetXYDistance(TVector3(xc, yc, 0.)); //[R.K. 01/2017] unused variable
3560 
3561  double distance_hit_center = (hit->GetPosition().XYvector() - TVector2(xc, yc)).Mod();
3562  double recoiso = fabs(distance_hit_center - R);
3563 
3564  if(recoiso < 3.) cluster2.AddHit(hit);
3565 
3566  }
3567 
3568 
3569  // GET SECTOR ID ---------------------------------------------
3570  sectorids.clear();
3571  for(int jhit = 0; jhit < cluster2.GetNofHits(); jhit++)
3572  {
3573  hit = cluster2.GetHit(jhit);
3574  if(hit == fRefHit) continue;
3575  int secid = hit->GetSector();
3576 
3577  if(sectorids.find(secid) == sectorids.end()) sectorids[secid] = 1;
3578  else sectorids[secid]++;
3579  }
3580 
3581  tmpsecentries = 0, tmpsec = -1;
3582  for(size_t isec = 0; isec < sectorids.size(); isec++) {
3583  if(tmpsecentries < sectorids[isec]) {
3584  tmpsecentries = sectorids[isec];
3585  tmpsec = isec;
3586  }
3587  }
3588  sectorID = tmpsec;
3589  // cout << "SECTOR " << sectorID << " " << sectorids.size() << endl;
3590 
3591  // border?
3592  border = false;
3593  othersecID = -1;
3594  for(size_t isec = 0; isec < sectorids.size(); isec++) {
3595  if(sectorids[isec] > 0 && (int)isec != sectorID) {
3596  border = true;
3597  othersecID = isec;
3598  }
3599  }
3600  // cout << "SECTOR " << sectorID << " " << sectorids.size() << " " << othersecID << " " << border << endl;
3601  // --------------------------------------------------------------
3602 
3603  // what about adding the mvd hits now? lets do it!
3604  // ... and put mvd pixel hits to conformal plane ---------------
3605  for(int jhit = 0; jhit < mvdpixhitlist->GetNofHits(); jhit++) {
3606  hit = mvdpixhitlist->GetHit(jhit);
3607  if(hit->IsUsed() == kTRUE) continue;
3608  if(searchnearby == true) { // search in this sector and +/- 1
3609  if(fabs(hit->GetSector() - sectorID) > 1 && !(hit->GetSector() == 5 && sectorID == 0) && !(hit->GetSector() == 0 && sectorID == 5)) continue;
3610  }
3611  else { // search only in this sector and possible othersector
3612  if(border == false && hit->GetSector() != sectorID) continue;
3613  else if(border == true && (hit->GetSector() != sectorID && hit->GetSector() != othersecID)) continue;
3614  }
3615  // if(hit->GetSector() != sectorID) continue;
3616  double distance_hit_center = (hit->GetPosition().XYvector() - TVector2(xc, yc)).Mod();
3617 
3618  double recoiso = fabs(distance_hit_center - R);
3619  // cout << "recoiso pix " << recoiso << endl;
3620  if(recoiso < 3.) {
3621 
3622  // dont want two hits on the same sensor
3623  int samesensor = false;
3624  for(int khit = 0; khit < cluster2.GetNofHits(); khit++) {
3625  PndTrkHit *hitk = cluster2.GetHit(khit);
3626  if(!hitk->IsMvdPixel()) continue;
3627  if(hitk->GetSensorID() != hit->GetSensorID()) continue;
3628  samesensor = true;
3629  double distance_hitk_center = (hitk->GetPosition().XYvector() - TVector2(xc, yc)).Mod();
3630  double recoisok = fabs(distance_hitk_center - R);
3631  if(recoiso < recoisok) {
3632  cluster2.DeleteHitAndCompress(hitk);
3633  std::pair< int, int > dontpair(hitk->GetHitID(), hitk->GetDetectorID());
3634  dontuse.push_back(dontpair);
3635  cluster2.AddHit(hit);
3636  }
3637  else {
3638  std::pair< int, int > dontpair(hit->GetHitID(), hit->GetDetectorID());
3639  dontuse.push_back(dontpair);
3640  }
3641  }
3642 
3643  if(samesensor == false) cluster2.AddHit(hit);
3644 
3645  if(fDisplayOn) {
3646  hit->Draw(kOrange);
3647  display->Update();
3648  display->Modified();
3649  }
3650  // PndTrkConformalHit *chit = conform->GetConformalHit(hit);
3651  // conformalhitlist->AddHit(chit);
3652  }
3653  }
3654 
3655  // ... and put mvd strip hits to conformal plane ---------------
3656  for(int jhit = 0; jhit < mvdstrhitlist->GetNofHits(); jhit++) {
3657  hit = mvdstrhitlist->GetHit(jhit);
3658  if(hit->IsUsed() == kTRUE) continue;
3659  if(searchnearby == true) { // search in this sector and +/- 1
3660  if(fabs(hit->GetSector() - sectorID) > 1 && !(hit->GetSector() == 5 && sectorID == 0) && !(hit->GetSector() == 0 && sectorID == 5)) continue;
3661  }
3662  else { // search only in this sector and possible othersector
3663  if(border == false && hit->GetSector() != sectorID) continue;
3664  else if(border == true && (hit->GetSector() != sectorID && hit->GetSector() != othersecID)) continue;
3665  }
3666  // if(hit->GetSector() != sectorID) continue;
3667  double distance_hit_center = (hit->GetPosition().XYvector() - TVector2(xc, yc)).Mod();
3668  double recoiso = fabs(distance_hit_center - R);
3669  // cout << "recoiso str " << recoiso << endl;
3670  if(recoiso < 3.) {
3671 
3672  // dont want two hits on the same sensor
3673  int samesensor = false;
3674  for(int khit = 0; khit < cluster2.GetNofHits(); khit++) {
3675  PndTrkHit *hitk = cluster2.GetHit(khit);
3676  if(!hitk->IsMvdStrip()) continue;
3677  if(hitk->GetSensorID() != hit->GetSensorID()) continue;
3678  samesensor = true;
3679  double distance_hitk_center = (hitk->GetPosition().XYvector() - TVector2(xc, yc)).Mod();
3680  double recoisok = fabs(distance_hitk_center - R);
3681  if(recoiso < recoisok) {
3682  cluster2.DeleteHitAndCompress(hitk);
3683  std::pair< int, int > dontpair(hitk->GetHitID(), hitk->GetDetectorID());
3684  dontuse.push_back(dontpair);
3685  cluster2.AddHit(hit);
3686  }
3687  else {
3688  std::pair< int, int > dontpair(hit->GetHitID(), hit->GetDetectorID());
3689  dontuse.push_back(dontpair);
3690  }
3691  }
3692 
3693  if(samesensor == false) cluster2.AddHit(hit);
3694 
3695  if(fDisplayOn) {
3696  hit->Draw(kOrange);
3697  display->Update();
3698  display->Modified();
3699  }
3701  fConformalHitList->AddHit(&chit);
3702  }
3703  }
3704 
3705 
3706  if(fDisplayOn) {
3707  display->cd(1);
3708  cluster2.Draw(kRed);
3709  display->Update();
3710  display->Modified();
3711  //char goOnChar; //[R.K. 01/2017] unused variable
3712  cout << "want to go on?" << endl;
3713  // cin >> goOnChar;
3714  }
3715 
3716 
3717  // -------- sorting
3718  // more complex sorting
3719  // sort in z ....
3720  for(int jhit = 0; jhit < cluster2.GetNofHits(); jhit++) {
3721  hit = cluster2.GetHit(jhit);
3722  hit->SetSortVariable(hit->GetPosition().Z());
3723  }
3724  cluster2.Sort();
3725  // ... then sort in phi from the 1st hit
3726  PndTrkTrack track2(&cluster2, xc, yc, R);
3727  // cout << "xc, yc, R " << xc << " " << yc << " " << R << endl;
3728  for(int jhit = 0; jhit < cluster2.GetNofHits(); jhit++) {
3729  hit = cluster2.GetHit(jhit);
3730  double phi = track2.ComputePhiFrom(hit->GetPosition(), cluster2.GetHit(0)->GetPosition());
3731  // double phi = track2.ComputePhi(hit->GetPosition());
3732  hit->SetPhi(phi);
3733  hit->SetSortVariable(phi);
3734  }
3735  cluster2.Sort();
3736 
3737  // // if the track is positive --> add 360 (otherwise is 0 followed by 350, 350...)
3738  // track2.ComputeCharge();
3739  // double charge = track2.GetCharge();
3740  // // cout << "charge " << charge << endl;
3741  // if(charge > 0) cluster2.GetHit(0)->SetPhi(360.) ; // CHECK
3742 
3743  // // further check, but maybe nomore necessary CHECK
3744  // if(cluster2.GetHit(0)->IsGem() && (cluster2.GetHit(cluster2.GetNofHits() - 1)->IsMvdPixel() || cluster2.GetHit(cluster2.GetNofHits() - 1)->IsMvdStrip())) {
3745  // PndTrkCluster cluster2b;
3746  // cluster2b.AddHit(cluster2.GetHit(0));
3747  // cluster2.ReverseSort();
3748  // for(int jhit = 1; jhit < cluster2.GetNofHits(); jhit++) {
3749  // cluster2b.AddHit(cluster2.GetHit(jhit));
3750  // }
3751  // cluster2 = cluster2b;
3752  // }
3753  // ..........................................
3754 
3755 
3756  for(int jhit = 0; jhit < cluster2.GetNofHits(); jhit++) {
3757  hit = cluster2.GetHit(jhit);
3758  // cout << "hit " << hit->GetHitID() << " " << hit->GetDetectorID() << " " << hit->GetPhi() << " " << hit->GetSortVariable() << endl;
3759  }
3760 
3761  // first hypothesis of z slope
3762  if(fDisplayOn) DrawZGeometry(-360, 360, -40, 200);
3763 
3764  fLineHisto->Reset();
3765 
3766  for(int jhit = 0; jhit < cluster2.GetNofHits(); jhit++) {
3767  hit = cluster2.GetHit(jhit);
3768  if(hit->IsStt()) continue;
3769  TVector3 position = hit->GetPosition();
3770  double phi = hit->GetPhi();
3771  if(fDisplayOn) {
3772  //char goOnChar; //[R.K. 01/2017] unused variable
3773  display->cd(4);
3774  TMarker *mrkz = NULL;
3775  if(hit->IsMvdPixel()) mrkz = new TMarker(phi, position.Z(), 21);
3776  else if(hit->IsMvdStrip()) mrkz = new TMarker(phi, position.Z(), 25);
3777  else if(hit->IsStt()) mrkz = new TMarker(phi, position.Z(), 6);
3778  else if(hit->IsGem()) mrkz = new TMarker(phi, position.Z(), 24);
3779  else if(hit->IsSciTil()) mrkz = new TMarker(phi, position.Z(), 26);
3780 
3781  mrkz->SetMarkerColor(kBlue);
3782  mrkz->Draw("SAME");
3783  display->Update();
3784  display->Modified();
3785  // cin >> goOnChar;
3786  }
3787  for(int khit = jhit + 1; khit < cluster2.GetNofHits(); khit++) {
3788  PndTrkHit* hitk = cluster2.GetHit(khit);
3789  if(hitk->IsStt()) continue;
3790  TVector3 positionk = hitk->GetPosition();
3791  double phik = hitk->GetPhi();
3792 
3793  double denom = (phi - phik) * (phi - phik) + (positionk.Z() - position.Z()) * (positionk.Z() - position.Z());
3794  if(denom == 0) continue;
3795  double cost = (positionk.Z() - position.Z()) / TMath::Sqrt(denom);
3796  double theta = TMath::ACos(cost);
3797  double r1 = phi * cost + position.Z() * TMath::Sin(theta);
3798  double r2 = phik * cost + positionk.Z() * TMath::Sin(theta);
3799  double r = r1;
3800  if(fabs(r1 - r2) > 1.e-9) {
3801  theta = -TMath::ACos(cost);
3802  r = phi * cost + position.Z() * TMath::Sin(theta);
3803  }
3804  fLineHisto->Fill(theta * TMath::RadToDeg(), r);
3805  // cout << theta * TMath::RadToDeg() << " " << r << endl;
3806  }
3807  }
3808  int bin = fLineHisto->GetMaximumBin();
3809  int binx, biny, binz;
3810  fLineHisto->GetBinXYZ(bin, binx, biny, binz);
3811  double tpeak = fLineHisto->GetXaxis()->GetBinCenter(binx);
3812  double rpeak = fLineHisto->GetYaxis()->GetBinCenter(biny);
3813  // cout << "tpeak " << tpeak << " rpeak " << rpeak << endl;
3814 
3815  // .........................................
3816  fFitter->Reset();
3817  for(int jhit = 0; jhit < cluster2.GetNofHits(); jhit++) {
3818  hit = cluster2.GetHit(jhit);
3819  if(!hit->IsGem()) continue;
3820  TVector3 position = hit->GetPosition();
3821  double phi = hit->GetPhi();
3822 
3823  if(fDisplayOn) {
3824  //char goOnChar; //[R.K. 01/2017] unused variable
3825  display->cd(4);
3826  TMarker *mrkz = NULL;
3827  if(hit->IsMvdPixel()) mrkz = new TMarker(phi, position.Z(), 21);
3828  else if(hit->IsMvdStrip()) mrkz = new TMarker(phi, position.Z(), 25);
3829  else if(hit->IsStt()) mrkz = new TMarker(phi, position.Z(), 6);
3830  else if(hit->IsGem()) mrkz = new TMarker(phi, position.Z(), 24);
3831  else if(hit->IsSciTil()) mrkz = new TMarker(phi, position.Z(), 26);
3832 
3833  mrkz->SetMarkerColor(kBlue);
3834  mrkz->Draw("SAME");
3835  display->Update();
3836  display->Modified();
3837  // cin >> goOnChar;
3838  }
3839 
3840  double sigma = 1e-5 * position.Z();
3841  fFitter->SetPointToFit(phi, position.Z(), sigma);
3842 
3843  }
3844 
3845  double fitm4, fitq4;
3846  fFitter->StraightLineFit(fitm4, fitq4);
3847 
3848 
3849  // .........................................
3850 
3851  double fitm44 = -TMath::Cos(tpeak * TMath::DegToRad())/TMath::Sin(tpeak * TMath::DegToRad());
3852  double fitq44 = rpeak/TMath::Sin(tpeak * TMath::DegToRad());
3853 
3854  if(fDisplayOn) {
3855  display->cd(3);
3856  fLineHisto->Draw("colz");
3857  display->cd(4);
3858  TLine *line = new TLine(-360, -360 * fitm4 + fitq4, 360, 360 * fitm4 + fitq4);
3859  line->SetLineColor(3);
3860  line->Draw("SAME");
3861 
3862  TLine *line4 = new TLine(-360, -360 * fitm44 + fitq44, 360, 360 * fitm44 + fitq44);
3863  line4->SetLineColor(4);
3864  line4->Draw("SAME");
3865 
3866  display->Update();
3867  display->Modified();
3868  //char goOnChar; //[R.K. 01/2017] unused variable
3869  // cin >> goOnChar;
3870  }
3871 
3872 // continue;
3873 
3874  // retrieve the hits shifted by 360 deg
3875  for(int jhit = 0; jhit < cluster2.GetNofHits(); jhit++) {
3876  hit = cluster2.GetHit(jhit);
3877  if(hit->IsStt()) continue;
3878  TVector3 position = hit->GetPosition();
3879  double phi = hit->GetPhi();
3880  double distance = fabs(position.Z() - fitm4 * phi - fitq4);
3881 
3882  // retrieve the hits shifted by 360
3883  if(distance > 100) {
3884  // try with 360 deg shift
3885  double comp_phi = (position.Z() - fitq4)/fitm4;
3886  if(fabs(comp_phi - phi) < 361 && fabs(comp_phi - phi) > 359){
3887  if(comp_phi > phi) phi += 360.;
3888  else phi -= 360.;
3889  hit->SetPhi(phi);
3890  distance = fabs(position.Z() - fitm4 * phi - fitq4);
3891  // cout << "PHI possible! " << fabs(comp_phi - phi) << endl;
3892  }
3893  }
3894  }
3895 
3896 
3897  // associate only the right hits in z for gem & mvd
3898  PndTrkCluster cluster3;
3899  for(int jhit = 0; jhit < cluster2.GetNofHits(); jhit++) {
3900  hit = cluster2.GetHit(jhit);
3901  // cout << " hit in cluster2: " << jhit << " " << hit->GetDetectorID() << endl;
3902  if(hit->IsStt()) {
3903  cluster3.AddHit(hit);
3904  // cout << " add hit " << jhit << endl;
3905  }
3906  else {
3907  TVector3 position = hit->GetPosition();
3908  double phi = hit->GetPhi();
3909 
3910  double distance = fabs(position.Z() - fitm4 * phi - fitq4);
3911  // cout << " z part " << phi << " " << position.Z() << " " << distance << endl;
3912 
3913  if(distance > 3 && hit->IsMvd() == kTRUE) {
3914  int hitId = hit->GetHitID();
3915  PndTrkHit *thishit = NULL;
3916  if(hit->IsMvdPixel()) thishit = mvdpixhitlist->GetHitByID(hitId);
3917  else if(hit->IsMvdStrip()) thishit = mvdstrhitlist->GetHitByID(hitId);
3918 
3919  std::pair< int, int > dontpair(hitId, hit->GetDetectorID());
3920  dontuse.push_back(dontpair);
3921 
3922  thishit->SetUsedFlag(kFALSE);
3923  // cout << "distance " << distance << " of hit " << hit->GetHitID() << " " << hit->GetDetectorID() << " " << hit->IsMvdPixel() << endl;
3924  continue;
3925  }
3926  else if(distance > 20 && hit->IsGem() == kTRUE) {
3927  int hitId = hit->GetHitID();
3928  PndTrkHit *thishit = gemhitlist->GetHitByID(hitId);
3929  thishit->SetUsedFlag(kFALSE);
3930 
3931  std::pair< int, int > dontpair(hitId, hit->GetDetectorID());
3932  dontuse.push_back(dontpair);
3933 
3934  // cout << "distance " << distance << " of hit " << hit->GetDetectorID() << endl;
3935  continue;
3936  }
3937 
3938 
3939  if(fDisplayOn) {
3940  //char goOnChar; //[R.K. 01/2017] unused variable
3941  display->cd(4);
3942  TMarker *mrkz = new TMarker(phi, position.Z(), 20);
3943  mrkz->SetMarkerColor(kOrange);
3944  mrkz->Draw("SAME");
3945  display->Update();
3946  display->Modified();
3947  }
3948  // cout << " add hit " << jhit << endl;
3949  cluster3.AddHit(hit);
3950  }
3951  }
3952 
3953  bool stat[3] = {false, false, false};
3954  for(int jhit = 0; jhit < cluster3.GetNofHits(); jhit++) {
3955  hit = cluster3.GetHit(jhit);
3956  if(hit->IsGem() == kFALSE) continue;
3957  switch(hit->GetSensorID()) {
3958  case 0:
3959  case 1:
3960  stat[0] = true;
3961  break;
3962  case 2:
3963  case 3:
3964  stat[1] = true;
3965  break;
3966  case 4:
3967  case 5:
3968  stat[2] = true;
3969  break;
3970  }
3971  }
3972 // if(stat[0] == false || stat[1] == false || stat[2] == false) continue;
3973  if(stat[0] == false && stat[1] == false && stat[2] == false) continue;
3974 
3975  cluster3.Sort();
3976  if(cluster3.GetNofHits() == 0) continue;
3977 
3978  // -------- fit with a line
3979  fFitter->Reset();
3980  for(int jhit = 0; jhit < cluster3.GetNofHits(); jhit++) {
3981  hit = cluster3.GetHit(jhit);
3982  if(hit->IsStt()) continue;
3983  TVector3 position = hit->GetPosition();
3984  double phi = hit->GetPhi();
3985  // cout << " z part " << phi << " " << position.Z() << endl;
3986  if(fDisplayOn) {
3987  //char goOnChar; //[R.K. 01/2017] unused variable
3988  display->cd(4);
3989  TMarker *mrkz = NULL;
3990  if(hit->IsMvdPixel()) mrkz = new TMarker(phi, position.Z(), 21);
3991  else if(hit->IsMvdStrip()) mrkz = new TMarker(phi, position.Z(), 25);
3992  else if(hit->IsStt()) mrkz = new TMarker(phi, position.Z(), 6);
3993  else if(hit->IsGem()) mrkz = new TMarker(phi, position.Z(), 24);
3994 
3995  mrkz->SetMarkerColor(kBlue);
3996  mrkz->Draw("SAME");
3997  display->Update();
3998  display->Modified();
3999  // cin >> goOnChar;
4000  }
4001 
4002  fFitter->SetPointToFit(phi, position.Z(), 0.1); // CHECK the error?
4003  }
4004 
4005  double fitm5, fitq5;
4006  fFitter->StraightLineFit(fitm5, fitq5);
4007 
4008  if(fDisplayOn) {
4009  display->cd(4);
4010  TLine *line = new TLine(-360, -360 * fitm5 + fitq5, 360, 360 * fitm5 + fitq5);
4011  line->SetLineColor(4);
4012  line->Draw("SAME");
4013  display->Update();
4014  display->Modified();
4015  //char goOnChar; //[R.K. 01/2017] unused variable
4016  // cin >> goOnChar;
4017  }
4018 
4019  fitm4 = fitm5;
4020  fitq4 = fitq5;
4021  // REFIT ANALYTICALLY ....again taken from-..
4022  // --------------------------
4023  // if there is a scitil lets use it as seed hit
4024  // for the conformal map
4025  fConformalHitList->Clear("C");
4026  refhit = cluster3.GetHit(0); // cluster3.GetNofHits() - 1);
4027  trasl[0] = 0;
4028  trasl[1] = 0;
4029  delta = 0;
4030 
4031 // cout << cluster3.GetNofHits() << " refhit ---> " << refhit << endl;
4032 
4033  ComputeTraAndRot(refhit, delta, trasl);
4034  conform->SetOrigin(trasl[0], trasl[1], delta);
4036 
4037  nofconfhits = FillConformalHitList(&cluster3);
4038 
4039  // cout << "nofhits1: " << nofconfhits << endl;
4040 
4041  // compute conformal plane extremities ---------------------------- this must go to a fctn CHECK
4042  fUmin = 1000, fVmin = 1000, fRmin = 1000;
4043  fUmax = -1000, fVmax = -1000, fRmax = -1000;
4044 
4045  for(int jhit = 0; jhit < fConformalHitList->GetNofHits(); jhit++) {
4047  double u = chit->GetU();
4048  double v = chit->GetV();
4049  double rc = chit->GetIsochrone();
4050  if(TMath::IsNaN(u)) continue; // prevents the nan of the ref hit
4051  if(rc < 0) rc = 0;
4052  // cout << "conf hit " << jhit << " u, v " << u << " " << v << " " << rc << endl;
4053  u - rc < fUmin ? fUmin = u - rc : fUmin;
4054  v - rc < fVmin ? fVmin = v - rc : fVmin;
4055  u + rc > fUmax ? fUmax = u + rc : fUmax;
4056  v + rc > fVmax ? fVmax = v + rc : fVmax;
4057 
4058  double theta1 = TMath::ATan2(v, u);
4059  double theta2 = theta1 + TMath::Pi();
4060 
4061  double r1 = u * TMath::Cos(theta1) + v * TMath::Sin(theta1);
4062  double r2 = u * TMath::Cos(theta2) + v * TMath::Sin(theta2);
4063 
4064  double rimin, rimax;
4065  r1 < r2 ? (rimin = r1, rimax = r2) : (rimin = r2, rimax = r1);
4066 
4067  rimin < fRmin ? (rc_of_min = rc, fRmin = rimin) : fRmin;
4068  rimax > fRmax ? (rc_of_max = rc, fRmax = rimax) : fRmax;
4069  }
4070 
4071  fRmin -= rc_of_min;
4072  fRmax += rc_of_max;
4073 
4074  // to square the conformal plane
4075  du = fUmax - fUmin;
4076  dv = fVmax - fVmin;
4077  delt = fabs(dv - du)/2.;
4078  du < dv ? (fUmin -= delt, fUmax += delt) : (fVmin -= delt, fVmax += delt);
4079  // cout << "min/max " << fUmin << " " << fUmax << " " << fVmin << " " << fVmax << endl;
4080  if(fDisplayOn) {
4081  DrawGeometryConf(fUmin, fUmax, fVmin, fVmax);
4082  // ----------------------------------------------------------------------
4083  for(int jhit = 0; jhit < nofconfhits; jhit++) {
4085  chit->Draw(kRed);
4086  }
4087  }
4088 
4089  // ====== REFIT CLUSTER ANALYTICALLY
4090  double fitm3, fitq3;
4091  bool fitting = AnalyticalFit(&cluster3, xc, yc, R, fitm3, fitq3);
4092  if(fitting == kFALSE) continue;
4093  double xc3, yc3, R3;
4094  FromConformalToRealTrack(fitm3, fitq3, xc3, yc3, R3);
4095 
4096  if(fDisplayOn) {
4097  //char goOnChar; //[R.K. 01/2017] unused variable
4098  display->cd(1);
4099  TArc *arcm = new TArc(xc3, yc3, R3);
4100  arcm->SetFillStyle(0);
4101  arcm->SetLineColor(4);
4102  arcm->Draw("SAME");
4103  display->Update();
4104  display->Modified();
4105  // cin >> goOnChar;
4106  }
4107 
4108 
4109  // ==================
4110  // MAKE the FINAL CLUSTER (at least in xy)
4111  fFinalCluster->Clear("C");
4112  // cout << "cluster3 " << cluster3.GetNofHits() << " fFinalCluster " << fFinalCluster->GetNofHits() << endl;
4113  // GEM
4114  for(int jhit = 0; jhit < gemhitlist->GetNofHits(); jhit++) {
4115  hit = gemhitlist->GetHit(jhit);
4116 
4117  // check if already discarded in the phi.z procedure
4118  std::pair< int, int > thispair(hit->GetHitID(), hit->GetDetectorID());
4119  std::vector < std::pair< int, int > >::iterator itr = dontuse.begin();
4120  itr = std::find(dontuse.begin(), dontuse.end(), thispair);
4121  if(itr != dontuse.end()) continue;
4122 
4123  if(border == false && hit->GetSector() != sectorID) continue;
4124  else if(border == true && (hit->GetSector() != sectorID && hit->GetSector() != othersecID)) continue;
4125  double distance_hit_center = (hit->GetPosition().XYvector() - TVector2(xc3, yc3)).Mod();
4126  double recoiso = fabs(distance_hit_center - R3);
4127  if(recoiso < 0.5) {
4128  hit->SetSortVariable(hit->GetPosition().Z());
4129 
4130  // dont want two hits on the same sensor
4131  int samesensor = false;
4132  for(int khit = 0; khit < fFinalCluster->GetNofHits(); khit++) {
4133  PndTrkHit *hitk = fFinalCluster->GetHit(khit);
4134  if(!hitk->IsGem()) continue;
4135  if(hitk->GetSensorID() != hit->GetSensorID()) continue;
4136  samesensor = true;
4137  double distance_hitk_center = (hitk->GetPosition().XYvector() - TVector2(xc3, yc3)).Mod();
4138  double recoisok = fabs(distance_hitk_center - R3);
4139  if(recoiso < recoisok) {
4141  std::pair< int, int > dontpair(hitk->GetHitID(), hitk->GetDetectorID());
4142  dontuse.push_back(dontpair);
4143  fFinalCluster->AddHit(hit);
4144  }
4145  else {
4146  std::pair< int, int > dontpair(hit->GetHitID(), hit->GetDetectorID());
4147  dontuse.push_back(dontpair);
4148  }
4149  }
4150 
4151  if(samesensor == false) fFinalCluster->AddHit(hit);
4152 
4153 // fFinalCluster->AddHit(hit);
4154  }
4155  }
4157 
4158  for(int jhit = 0; jhit < fFinalCluster->GetNofHits(); jhit++) {
4159  hit = fFinalCluster->GetHit(jhit);
4160 
4161  //PndGemHit *gemhit = (PndGemHit*) fGemHitArray->At(hit->GetHitID()); //[R.K. 01/2017] unused variable?
4162  //int refindex = gemhit->GetRefIndex(); //[R.K. 01/2017] unused variable
4163 
4164 // cout << "THIS it is " << hit->GetHitID() << " " << hit->GetDetectorID() << " " << hit->GetSensorID() << " " << refindex << endl;
4165  }
4166 
4167 
4168  // check if last station has only one hit ~~~~~~~~~~~~~~~~~~~~~
4169  // define last and almost last stations
4170  int laststat = -1, almostlaststat = -1;
4171  for(int jhit = 0; jhit < fFinalCluster->GetNofHits(); jhit++) {
4172  hit = fFinalCluster->GetHit(jhit);
4173  if(laststat == -1) laststat = hit->GetSensorID();
4174  if(laststat != -1 && almostlaststat == -1 && hit->GetSensorID() != laststat) almostlaststat = hit->GetSensorID();
4175  }
4176  // count
4177  int hitsonlaststat = 0;
4178  for(int jhit = 0; jhit < fFinalCluster->GetNofHits(); jhit++) {
4179  hit = fFinalCluster->GetHit(jhit);
4180 // cout << "hit " << hit->GetHitID() << " " << hit->GetDetectorID() << " " << hit->GetSensorID() << endl;
4181  if(hit->GetSensorID() != laststat) continue;
4182  hitsonlaststat++;
4183  }
4184 
4185 
4186  // cout << "ON LAST STATION " << laststat << " - " << hitsonlaststat << endl;
4187  if(laststat == -1 || almostlaststat == -1) continue;
4188  TVector3 fromhere = fFinalCluster->GetHit(0)->GetPosition(); // CHECK HERE
4189  // fromhere.Print();
4190  if(hitsonlaststat > 1) {
4191  double dist45 = 1000;
4192  for(int jhit = 0; jhit < fFinalCluster->GetNofHits(); jhit++) {
4193  hit = fFinalCluster->GetHit(jhit);
4194  if(hit->GetSensorID() != laststat) continue;
4195  else if(hit->GetSensorID() < laststat) break;
4196  for(int khit = jhit + 1; khit < fFinalCluster->GetNofHits(); khit++) {
4197  PndTrkHit *hitk = fFinalCluster->GetHit(khit);
4198  if(hitk->GetSensorID() != almostlaststat) continue;
4199  else if(hit->GetSensorID() < almostlaststat) break;
4200  double tmpdist = hit->GetXYDistance(hitk);
4201  if(tmpdist < dist45) fromhere = hit->GetPosition();
4202  }
4203  }
4204  }
4205  // fromhere.Print();
4206 
4207  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4208 
4209 // TVector3 fromhere = fFinalCluster->GetHit(0)->GetPosition(); // CHECK HERE
4210  // cout << "fFinalCluster, gem " << fFinalCluster->GetNofHits() << endl;
4211 
4212  // STT
4213  for(int jhit = 0; jhit < stthitlist->GetNofHits(); jhit++) {
4214  hit = stthitlist->GetHit(jhit);
4215  if(hit->IsSttParallel() == kFALSE) continue;
4216  PndSttTube* tube = (PndSttTube*) fTubeArray->At(hit->GetTubeID());
4217  if(border == false && tube->GetSectorID() != sectorID) continue;
4218  else if(border == true && (tube->GetSectorID() != sectorID && tube->GetSectorID() != othersecID)) continue;
4219  double distance_hit_center = (tube->GetPosition().XYvector() - TVector2(xc3, yc3)).Mod();
4220  double recoiso = fabs(distance_hit_center - R3);
4221  if(recoiso < 0.5) {
4222  fFinalCluster->AddHit(hit);
4223  }
4224  }
4225  // cout << "fFinalCluster, gem + stt " << fFinalCluster->GetNofHits() << endl;
4226 
4227 
4228  // MVD PIX
4229  for(int jhit = 0; jhit < mvdpixhitlist->GetNofHits(); jhit++) {
4230  hit = mvdpixhitlist->GetHit(jhit);
4231 
4232  // check if already discarded in the phi.z procedure
4233  std::pair< int, int > thispair(hit->GetHitID(), hit->GetDetectorID());
4234  std::vector < std::pair< int, int > >::iterator itr = dontuse.begin();
4235  itr = std::find(dontuse.begin(), dontuse.end(), thispair);
4236  if(itr != dontuse.end()) continue;
4237 
4238  if(border == false && hit->GetSector() != sectorID) continue;
4239  else if(border == true && (hit->GetSector() != sectorID && hit->GetSector() != othersecID)) continue;
4240  double distance_hit_center = (hit->GetPosition().XYvector() - TVector2(xc3, yc3)).Mod();
4241  double recoiso = fabs(distance_hit_center - R3);
4242  if(recoiso < 0.5) {
4243 
4244 
4245  // dont want two hits on the same sensor
4246  int samesensor = false;
4247  for(int khit = 0; khit < fFinalCluster->GetNofHits(); khit++) {
4248  PndTrkHit *hitk = fFinalCluster->GetHit(khit);
4249  if(!hitk->IsMvdPixel()) continue;
4250  if(hitk->GetSensorID() != hit->GetSensorID()) continue;
4251  samesensor = true;
4252  double distance_hitk_center = (hitk->GetPosition().XYvector() - TVector2(xc3, yc3)).Mod();
4253  double recoisok = fabs(distance_hitk_center - R3);
4254  if(recoiso < recoisok) {
4256  std::pair< int, int > dontpair(hitk->GetHitID(), hitk->GetDetectorID());
4257  dontuse.push_back(dontpair);
4258  fFinalCluster->AddHit(hit);
4259  }
4260  else {
4261  std::pair< int, int > dontpair(hit->GetHitID(), hit->GetDetectorID());
4262  dontuse.push_back(dontpair);
4263  }
4264  }
4265 
4266  if(samesensor == false) fFinalCluster->AddHit(hit);
4267  // fFinalCluster->AddHit(hit);
4268 
4269  }
4270  }
4271  // cout << "fFinalCluster, gem + stt + pix " << fFinalCluster->GetNofHits() << endl;
4272 
4273 
4274  // MVD STR
4275  for(int jhit = 0; jhit < mvdstrhitlist->GetNofHits(); jhit++) {
4276  hit = mvdstrhitlist->GetHit(jhit);
4277 
4278  // check if already discarded in the phi.z procedure
4279  std::pair< int, int > thispair(hit->GetHitID(), hit->GetDetectorID());
4280  std::vector < std::pair< int, int > >::iterator itr = dontuse.begin();
4281  itr = std::find(dontuse.begin(), dontuse.end(), thispair);
4282  if(itr != dontuse.end()) continue;
4283 
4284  if(border == false && hit->GetSector() != sectorID) continue;
4285  else if(border == true && (hit->GetSector() != sectorID && hit->GetSector() != othersecID)) continue;
4286  double distance_hit_center = (hit->GetPosition().XYvector() - TVector2(xc3, yc3)).Mod();
4287  double recoiso = fabs(distance_hit_center - R3);
4288  if(recoiso < 0.5) {
4289 
4290  fFinalCluster->AddHit(hit);
4291 
4292  }
4293  }
4294  // cout << "fFinalCluster, gem + stt + str " << fFinalCluster->GetNofHits() << endl;
4295 
4296  // SCITIL
4297  int tmphit = -1;
4298  double tmpdistance = 1000;
4299  for(int jhit = 0; jhit < scithitlist->GetNofHits(); jhit++) {
4300  hit = scithitlist->GetHit(jhit);
4301  double distance_hit_center = (hit->GetPosition().XYvector() - TVector2(xc3, yc3)).Mod();
4302  double recoiso = fabs(distance_hit_center - R3);
4303  if(recoiso < 0.5) {
4304  if(recoiso < tmpdistance) {
4305  tmphit = jhit;
4306  tmpdistance = recoiso;
4307  }
4308  }
4309  }
4310  if(tmphit > -1) {
4311  hit = scithitlist->GetHit(tmphit);
4312  fFinalCluster->AddHit(hit);
4313  }
4314  // cout << "fFinalCluster, gem + stt + pix + str + scit " << fFinalCluster->GetNofHits() << endl;
4315 
4316  if(fFinalCluster->GetNofHits() == 0) {
4317  continue;
4318  }
4319 
4320 
4321  // sorting from last gem
4322 
4323  PndTrkTrack track3(fFinalCluster, xc3, yc3, R3);
4324  for(int jhit = 0; jhit < fFinalCluster->GetNofHits(); jhit++) {
4325  hit = fFinalCluster->GetHit(jhit);
4326 
4327  double phi = track3.ComputePhiFrom(hit->GetPosition(), fromhere);
4328  if(phi == 360) phi = 0;
4329  hit->SetPhi(phi);
4330  hit->SetSortVariable(phi);
4331 
4332  }
4333  fFinalCluster->Sort();
4334  for(int jhit = 0; jhit < fFinalCluster->GetNofHits(); jhit++) {
4335  hit = fFinalCluster->GetHit(jhit);
4336  // cout << "-> " << hit->GetHitID() << " " << hit->GetDetectorID() << " " << hit->GetPhi() << " " << hit->GetSortVariable() << " " << hit->IsSortable() << endl;
4337  }
4338 
4339  // check the 0/360 discontinuity ..................
4340  //PndTrkHit *hit1 = fFinalCluster->GetHit(0); //[R.K. 03/2017] unused variable
4341  //PndTrkHit *hit2 = fFinalCluster->GetHit(1); //[R.K. 03/2017] unused variable
4342  if(fDisplayOn) {
4343  for(int jhit = 0; jhit < fFinalCluster->GetNofHits(); jhit++) {
4344  hit = fFinalCluster->GetHit(jhit);
4345  // cout << "-> " << hit->GetHitID() << " " << hit->GetDetectorID() << " " << hit->GetPhi() << " " << hit->GetSortVariable() << endl;
4346  TMarker *mrk = new TMarker(hit->GetPosition().X(), hit->GetPosition().Y(), 20);
4347  mrk->SetMarkerColor(kMagenta);
4348  mrk->Draw("SAME");
4349  char goOnChar;
4350  cin >> goOnChar;
4351  display->Update();
4352  display->Modified();
4353  }
4354  }
4355 
4356  int counter = 0;
4357  double meanphi = 0;
4358  for(int jhit = 0; jhit < fFinalCluster->GetNofHits(); jhit++) {
4359  hit = fFinalCluster->GetHit(jhit);
4360  if(!hit->IsGem()) continue;
4361  double phi = hit->GetPhi();
4362  if(phi != 0) {
4363  meanphi += phi;
4364  counter++;
4365  }
4366  }
4367 
4368  if(meanphi > 300) {
4369  for(int jhit = 0; jhit < fFinalCluster->GetNofHits(); jhit++) {
4370  hit = fFinalCluster->GetHit(jhit);
4371  if(!hit->IsGem()) continue;
4372  double phi = hit->GetPhi();
4373  if(phi < 10) phi += 360;
4374  hit->SetPhi(phi);
4375  hit->SetSortVariable(phi);
4376  }
4377  fFinalCluster->Sort();
4378  }
4379  else fFinalCluster->ReverseSort();
4380 
4381  if(fDisplayOn) {
4382  for(int jhit = 0; jhit < fFinalCluster->GetNofHits(); jhit++) {
4383  hit = fFinalCluster->GetHit(jhit);
4384  cout << "*** " << hit->GetHitID() << " " << hit->GetDetectorID() << " " << hit->GetPhi() << " " << hit->GetSortVariable() << endl;
4385  TMarker *mrk = new TMarker(hit->GetPosition().X(), hit->GetPosition().Y(), 20);
4386  mrk->SetMarkerColor(kGreen);
4387  mrk->Draw("SAME");
4388  char goOnChar;
4389  cin >> goOnChar;
4390  display->Update();
4391  display->Modified();
4392  }
4393  }
4394  // ....................................................
4395 
4396  // cout << "FINAL CLUSTER HAS " << fFinalCluster->GetNofHits() << endl;
4397  for(int jhit = 0; jhit < fFinalCluster->GetNofHits(); jhit++) {
4398  hit = fFinalCluster->GetHit(jhit);
4399  // cout << "final " << hit->GetHitID() << " " << hit->GetDetectorID() << " " << hit->GetPhi() << " " << hit->GetSortVariable() << " " << hit->IsSortable() << endl;
4400  }
4401  if(fDisplayOn) {
4402  Refresh();
4404  for(int jhit = 0; jhit < fFinalCluster->GetNofHits(); jhit++) {
4405  hit = fFinalCluster->GetHit(jhit);
4406  TMarker *mrk = new TMarker(hit->GetPosition().X(), hit->GetPosition().Y(), 20);
4407  mrk->SetMarkerColor(kOrange);
4408  mrk->Draw("SAME");
4409  char goOnChar;
4410  cin >> goOnChar;
4411  display->Update();
4412  display->Modified();
4413  }
4414  char goOnChar;
4415  cin >> goOnChar;
4416  }
4417 
4418  // ====== REFIT CLUSTER ANALYTICALLY
4419  // REFIT ANALYTICALLY ....again taken from-..
4420  // --------------------------
4421  // if there is a scitil lets use it as seed hit
4422  // for the conformal map
4423  fConformalHitList->Clear("C");
4424  refhit = fFinalCluster->GetHit(0); // cluster3.GetNofHits() - 1);
4425  // cout << "refhit ---> " << refhit << endl;
4426  ComputeTraAndRot(refhit, delta, trasl);
4427  conform->SetOrigin(trasl[0], trasl[1], delta);
4429 
4430  nofconfhits = FillConformalHitList(fFinalCluster);
4431 
4432  // compute conformal plane extremities ---------------------------- this must go to a fctn CHECK
4433  fUmin = 1000, fVmin = 1000, fRmin = 1000;
4434  fUmax = -1000, fVmax = -1000, fRmax = -1000;
4435 
4436  for(int jhit = 0; jhit < fConformalHitList->GetNofHits(); jhit++) {
4438  double u = chit->GetU();
4439  double v = chit->GetV();
4440  double rc = chit->GetIsochrone();
4441  if(TMath::IsNaN(u)) continue; // prevents the nan of the ref hit
4442  if(rc < 0) rc = 0;
4443  // cout << "conf hit " << jhit << " u, v " << u << " " << v << " " << rc << endl;
4444  u - rc < fUmin ? fUmin = u - rc : fUmin;
4445  v - rc < fVmin ? fVmin = v - rc : fVmin;
4446  u + rc > fUmax ? fUmax = u + rc : fUmax;
4447  v + rc > fVmax ? fVmax = v + rc : fVmax;
4448 
4449  double theta1 = TMath::ATan2(v, u);
4450  double theta2 = theta1 + TMath::Pi();
4451 
4452  double r1 = u * TMath::Cos(theta1) + v * TMath::Sin(theta1);
4453  double r2 = u * TMath::Cos(theta2) + v * TMath::Sin(theta2);
4454 
4455  double rimin, rimax;
4456  r1 < r2 ? (rimin = r1, rimax = r2) : (rimin = r2, rimax = r1);
4457 
4458  rimin < fRmin ? (rc_of_min = rc, fRmin = rimin) : fRmin;
4459  rimax > fRmax ? (rc_of_max = rc, fRmax = rimax) : fRmax;
4460  }
4461 
4462  fRmin -= rc_of_min;
4463  fRmax += rc_of_max;
4464 
4465  // to square the conformal plane
4466  du = fUmax - fUmin;
4467  dv = fVmax - fVmin;
4468  delt = fabs(dv - du)/2.;
4469  du < dv ? (fUmin -= delt, fUmax += delt) : (fVmin -= delt, fVmax += delt);
4470  // cout << "min/max " << fUmin << " " << fUmax << " " << fVmin << " " << fVmax << endl;
4471  if(fDisplayOn) {
4472  DrawGeometryConf(fUmin, fUmax, fVmin, fVmax);
4473  // ----------------------------------------------------------------------
4474  for(int jhit = 0; jhit < nofconfhits; jhit++) {
4476  chit->Draw(kBlue);
4477  }
4478  }
4479 
4480 
4481  // cout << "MINUIT FIT FWD" << endl;
4482  double fitm6, fitq6;
4483  fitting = AnalyticalFit(fFinalCluster, xc3, yc3, R3, fitm6, fitq6);
4484  if(fitting == kFALSE) continue;
4485 
4486  double xc6, yc6, R6;
4487  FromConformalToRealTrack(fitm6, fitq6, xc6, yc6, R6);
4488 
4489  // CHECK 15/0.006 cm
4490  if(R6 > 2500) continue;
4491  PndTrkTrack finaltrack(fFinalCluster, xc6, yc6, R6);
4492  finaltrack.ComputeCharge();
4493 
4494  if(fDisplayOn) {
4495  char goOnChar;
4496 
4497  display->cd(2);
4498  TLine *line = new TLine(-10, -10 * fitm6 + fitq6, 10, 10 * fitm6 + fitq6);
4499  line->SetLineColor(kMagenta);
4500  line->Draw("SAME");
4501 
4502  display->cd(1);
4503  TArc *arcm = new TArc(xc6, yc6, R6);
4504  arcm->SetFillStyle(0);
4505  arcm->SetLineColor(kMagenta);
4506  arcm->Draw("SAME");
4507 
4508  display->Update();
4509  display->Modified();
4510  cin >> goOnChar;
4511  }
4512 
4513  if(fDisplayOn) {
4514  char goOnChar;
4515  display->Update();
4516  display->Modified();
4517  cin >> goOnChar;
4518  }
4519 
4520  // ============================ Z PART FOR FWD
4521  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4522  // SKEWED ASSOCIATION ********* CHECK *********
4523  // -------------------------------------------------------
4524  // cout << " %%%%%%%%%%%%%%%%%%%% ZFINDER %%%%%%%%%%%%%%%%%%%%%%%%%%" << endl;
4525 
4526  if(fDisplayOn) DrawZGeometry(-360, 360, -40, 200);
4527 
4528  // create cluster for z finding
4529 
4530  // lets start from the skewed --------------------------------
4531  // PndTrkCluster skewhitlist = CreateSkewHitList(finaltrack);
4532  PndTrkSkewHitList skewhitlist;
4533  //double phimin = 400, phimax = -1, zmin = 1000, zmax = -1; //[R.K. 01/2017] unused variable
4534  for(int jhit = 0; jhit < stthitlist->GetNofHits(); jhit++) {
4535  hit = stthitlist->GetHit(jhit);
4536  // cout << hit->IsSttSkew() << " " << hit->GetSector() << " " << TMath::RadToDeg() * hit->GetPosition().Phi() << " " << sectorID << " " << othersecID << endl;
4537  if(hit->IsSttSkew() == kFALSE) continue;
4538 
4539  if(border == false && hit->GetSector() != sectorID) continue;
4540  else if(border == true && (hit->GetSector() != sectorID && hit->GetSector() != othersecID)) continue;
4541 
4542  int tubeID = hit->GetTubeID();
4543  PndSttTube *tube = (PndSttTube*) fTubeArray->At(tubeID);
4544 
4545  TVector3 wireDirection = tube->GetWireDirection();
4546  Double_t halflength = tube->GetHalfLength();
4547 
4548  TVector3 first = tube->GetPosition() + wireDirection * halflength; // CHECK
4549  TVector3 second = tube->GetPosition() - wireDirection * halflength; // CHECK
4550 
4551  // double m1 = (first - second).Y()/(first - second).X();
4552  // double q1 = first.Y() - m1 * first.X();
4553 
4554  // 1. compute intersection between the track circle and the wire
4555  TVector2 intersection1, intersection2;
4556  Int_t nofintersections = tools->ComputeSegmentCircleIntersection(TVector2(first.X(), first.Y()), TVector2(second.X(), second.Y()), xc6, yc6, R6, intersection1, intersection2);
4557 
4558  if(nofintersections == 0) continue;
4559  if(nofintersections >= 2) {
4560  cout << "ERROR: MORE THAN 1 INTERSECTION!!" << endl;
4561  continue; // CHECK
4562  }
4563 
4564  // 2. find the tangent to the track in the intersection point
4565  // tangent approximation
4566  TVector2 tangent = tools->ComputeTangentInPoint(xc6, yc6, intersection1);
4567 
4568  // 3. rotate clockwise the tangent/point/(wire, not explicitely)
4569  // in order to have the wire parallel to the x axis;
4570  // then translate everything to have the wire ON the x axis
4571  double beta = wireDirection.Phi();
4572  if(beta < 0) beta += TMath::Pi();
4573  // ... rotate the tangent
4574  double rtx = TMath::Cos(beta) * tangent.X() + TMath::Sin(beta) * tangent.Y();
4575  double rty = TMath::Cos(beta) * tangent.Y() - TMath::Sin(beta) * tangent.X();
4576  TVector2 rottangent(rtx, rty);
4577  rottangent = rottangent.Unit();
4578  // ... rotate the point
4579  double rx = TMath::Cos(beta) * intersection1.X() + TMath::Sin(beta) * intersection1.Y();
4580  double ry = TMath::Cos(beta) * intersection1.Y() - TMath::Sin(beta) * intersection1.X();
4581 
4582  // translation
4583  Double_t deltay = ry;
4584  rty -= deltay;
4585  ry -= deltay;
4586 
4587  // rotm, rotp
4588  Double_t rotm = rottangent.Y()/rottangent.X();
4589  Double_t rotp = ry - rotm * rx;
4590 
4591  // ellipsis
4592  double a = hit->GetIsochrone() * TMath::Cos(SKEW_ANGLE); // CHECK skew angle hard coded
4593  double b = hit->GetIsochrone();
4594 
4595  // center of ellipsis
4596  Double_t x0a, x0b, y0;
4597  y0 = 0.;
4598  x0a = (-rotp + TMath::Sqrt(b * b + a * a * rotm * rotm)) / rotm;
4599  x0b = (-rotp - TMath::Sqrt(b * b + a * a * rotm * rotm)) / rotm;
4600 
4601  // intersection point
4602  double intxa = (x0a * b * b - rotm * rotp * a * a) / (b * b + rotm * rotm * a * a);
4603  double intya = rotm * intxa + rotp;
4604  double intxb = (x0b * b * b - rotm * rotp * a * a) / (b * b + rotm * rotm * a * a);
4605  double intyb = rotm * intxb + rotp;
4606 
4607  // 4. retraslate/rerotate all back to the original plane
4608  // retranslate
4609  y0 += deltay;
4610  intya += deltay;
4611  intyb += deltay;
4612 
4613  // rerotate
4614  double x0anew = TMath::Cos(beta) * x0a - TMath::Sin(beta) * y0;
4615  double y0anew = TMath::Cos(beta) * y0 + TMath::Sin(beta) * x0a;
4616  double x0bnew = TMath::Cos(beta) * x0b - TMath::Sin(beta) * y0;
4617  double y0bnew = TMath::Cos(beta) * y0 + TMath::Sin(beta) * x0b;
4618 
4619  double intxanew = TMath::Cos(beta) * intxa - TMath::Sin(beta) * intya;
4620  double intyanew = TMath::Cos(beta) * intya + TMath::Sin(beta) * intxa;
4621  double intxbnew = TMath::Cos(beta) * intxb - TMath::Sin(beta) * intyb;
4622  double intybnew = TMath::Cos(beta) * intyb + TMath::Sin(beta) * intxb;
4623 
4624  intxa = intxanew;
4625  intya = intyanew;
4626  intxb = intxbnew;
4627  intyb = intybnew;
4628 
4629  // now we have x0a, y0a, center of the 1st ellipse
4630  // and x0b, y0b, center of the 2nd ellipse
4631  x0a = x0anew;
4632  double y0a = y0anew;
4633  x0b = x0bnew;
4634  double y0b = y0bnew;
4635 
4636  if(fDisplayOn) {
4637  //char goOnChar; //[R.K. 01/2017] unused variable
4638  display->cd(1);
4639 
4640  TEllipse *ell1 = new TEllipse(x0a, y0a, a, b, 0, 360, -beta);
4641  ell1->SetFillStyle(0);
4642  ell1->SetLineColor(4);
4643  ell1->Draw("SAME");
4644  TEllipse *ell2 = new TEllipse(x0b, y0b, a, b, 0, 360, -beta);
4645  ell2->SetFillStyle(0);
4646  ell2->SetLineColor(6);
4647  ell2->Draw("SAME");
4648 
4649  TMarker *mrkinta = new TMarker(intxa, intya, 20);
4650  mrkinta->SetMarkerColor(4);
4651  mrkinta->Draw("SAME");
4652  TMarker *mrkintb = new TMarker(intxb, intyb, 20);
4653  mrkintb->SetMarkerColor(6);
4654  mrkintb->Draw("SAME");
4655  display->Update();
4656  display->Modified();
4657  // cin >> goOnChar;
4658 
4659  }
4660 
4661  // 5. calculate z coordinate for each intersection
4662 
4663  // calculate z0a, z0b of the center of the ellipse
4664  Double_t t = ((x0a + y0a) - (first.X() + first.Y())) / ((second.X() - first.X()) + (second.Y() - first.Y()));
4665  Double_t z0a = first.Z() + (second.Z() - first.Z()) * t;
4666  // cout << "0 : calculate t, z0a " << t << " " << z0a << endl;
4667 
4668  t = ((x0b + y0b) - (first.X() + first.Y())) / ((second.X() - first.X()) + (second.Y() - first.Y()));
4669  Double_t z0b = first.Z() + (second.Z() - first.Z()) * t;
4670 
4671  TVector3 center1(x0a, y0a, z0a);
4672  TVector3 center2(x0b, y0b, z0b);
4673 
4674  // calculate the z of the intersection ON the ellipse (CHECK this step calculations!)
4675  double dx = intxa - x0a;
4676  double dy = intya - y0a;
4677  TVector3 dxdy(dx, dy, 0.0);
4678 
4679  TVector3 tfirst = first + dxdy;
4680  TVector3 tsecond = second + dxdy;
4681 
4682  t = ((intxa + intya) - (tfirst.X() + tfirst.Y())) / ((tsecond.X() - tfirst.X()) + (tsecond.Y() - tfirst.Y()));
4683  double intza = tfirst.Z() + (tsecond.Z() - tfirst.Z()) * t;
4684  if(fDisplayOn) {
4685  //char goOnChar; //[R.K. 01/2017] unused variable
4686  display->cd(3);
4687  TLine *linezx1 = new TLine(tfirst.X(), tfirst.Z(), tsecond.X(), tsecond.Z());
4688  linezx1->SetLineStyle(1);
4689  linezx1->Draw("SAME");
4690  TMarker *mrkza1 = new TMarker(intxa, intza, 20);
4691  mrkza1->SetMarkerColor(kBlue - 9);
4692  mrkza1->Draw("SAME");
4693  // cin >> goOnChar;
4694  }
4695 
4696  tfirst = first - dxdy;
4697  tsecond = second - dxdy;
4698 
4699  t = ((intxb + intyb) - (tfirst.X() + tfirst.Y())) / ((tsecond.X() - tfirst.X()) + (tsecond.Y() - tfirst.Y()));
4700  double intzb = tfirst.Z() + (tsecond.Z() - tfirst.Z()) * t;
4701 
4702  TVector3 fin_intersection1(intxa, intya, intza);
4703  TVector3 fin_intersection2(intxb, intyb, intzb);
4704 
4705  // CHECK to be changed
4706  int trackID = 1;
4707  double phi1 = finaltrack.ComputePhiFrom(fin_intersection1, fromhere);
4708  double phi2 = finaltrack.ComputePhiFrom(fin_intersection2, fromhere);
4709  hit->SetPhi((phi1 + phi2) * 0.5);
4710  hit->SetSortVariable((phi1 + phi2) * 0.5);
4711  skewhitlist.AddHit(PndTrkSkewHit(*hit, trackID, center1, fin_intersection1, phi1, center2, fin_intersection2, phi2, a, b, -1, beta));
4712  }
4713 
4714 
4715  // add hits which have a z info
4716  // and belong to the cluster
4717  for(int jhit = 0; jhit < fFinalCluster->GetNofHits(); jhit++) {
4718  hit = fFinalCluster->GetHit(jhit);
4719  //double phi = hit->GetPhi(); // finaltrack.ComputePhiFrom(hit->GetPosition(), fromhere); //[R.K. 01/2017] unused variable
4720  if(hit->IsStt() == kFALSE) {
4721  // hit->SetPhi(phi);
4722  // hit->SetSortVariable(phi);
4723  skewhitlist.AddHit(PndTrkSkewHit(*hit));
4724  }
4725  }
4726 
4727 
4728 
4729  // cout << "dopo sorting" << endl;
4730  for(int jhit = 0; jhit < fFinalCluster->GetNofHits(); jhit++) {
4731  hit = fFinalCluster->GetHit(jhit);
4732  if(fDisplayOn) {
4733  display->cd(1);
4734  TMarker *mrk = new TMarker(hit->GetPosition().X(), hit->GetPosition().Y(), 20);
4735  mrk->SetMarkerColor(kBlue);
4736  mrk->Draw("SAME");
4737  display->Update();
4738  display->Modified();
4739  char goOnChar;
4740  cin >> goOnChar;
4741  }
4742  }
4743 
4744  // cout << "fitm5 " << fitm5 << " fitq5 " << fitq5 << endl;;
4745  double fitm7 = fitm5;
4746  double fitq7 = 0.;
4747  for(int jhit = 0; jhit < skewhitlist.GetNofHits(); jhit++) {
4748  hit = skewhitlist.GetHit(jhit);
4749  if(!hit) continue;
4750  if(hit->IsStt() == kFALSE) {
4751  fitq7 = hit->GetPosition().Z() - fitm7 * hit->GetPhi();
4752  // cout << "non stt " << hit->GetPhi() << " " << hit->GetPosition().Z() << endl;
4753  }
4754  }
4755 
4756  if(fDisplayOn) {
4757  char goOnChar;
4758  display->cd(4);
4759  for(int jhit = 0; jhit < skewhitlist.GetNofHits(); jhit++) {
4760  hit = skewhitlist.GetHit(jhit);
4761  if(!hit) continue;
4762  // cout << "hit.det.phi " << hit->GetHitID() << " " << hit->GetDetectorID() << " " << hit->GetPhi() << endl;
4763  if(hit->IsStt() == kTRUE) {
4764  PndTrkSkewHit *skewhit = (PndTrkSkewHit*) hit;
4765 
4766  TVector3 fin_intersection1 = skewhit->GetIntersection1();
4767  TVector3 fin_intersection2 = skewhit->GetIntersection2();
4768  double phi1 = skewhit->GetPhi1();
4769  double phi2 = skewhit->GetPhi2();
4770 
4771  display->cd(4);
4772  TLine *linezphi = new TLine(phi1, fin_intersection1.Z(), phi2, fin_intersection2.Z());
4773  linezphi->SetLineStyle(1);
4774  linezphi->Draw("SAME");
4775  TMarker *mrkzphi1 = new TMarker(phi1, fin_intersection1.Z(), 20);
4776  mrkzphi1->SetMarkerColor(kBlue - 9);
4777  mrkzphi1->Draw("SAME");
4778  TMarker *mrkzphi2 = new TMarker(phi2, fin_intersection2.Z(), 20);
4779  mrkzphi2->SetMarkerColor(kMagenta - 7);
4780  mrkzphi2->Draw("SAME");
4781  display->Update();
4782  display->Modified();
4783  }
4784  else {
4785  cout << "2non stt " << hit->GetPhi() << " " << hit->GetPosition().Z() << endl;
4786  TMarker *mrkzphi = new TMarker(hit->GetPhi(), hit->GetPosition().Z(), 20);
4787  mrkzphi->SetMarkerColor(kOrange);
4788  mrkzphi->Draw("SAME");
4789  display->Update();
4790  display->Modified();
4791  }
4792  }
4793  cin >> goOnChar;
4794  }
4795 
4796 
4797  if(fDisplayOn) {
4798  display->cd(4);
4799  TLine *line = new TLine(-360, -360 * fitm7 + fitq7, 360, 360 * fitm7 + fitq7);
4800  line->SetLineColor(2);
4801  line->Draw("SAME");
4802 
4803  display->Update();
4804  display->Modified();
4805  char goOnChar;
4806  cin >> goOnChar;
4807  }
4808 
4809  // choose the fin_intersection of the skew
4810  PndTrkSkewHitList skewhitlist2;
4811  for(int jhit = 0; jhit < skewhitlist.GetNofHits(); jhit++) {
4812  hit = (PndTrkHit*) skewhitlist.GetHit(jhit);
4813  if(!hit) continue;
4814  if(hit->IsSttSkew() == kFALSE) {
4815  skewhitlist2.AddHit(hit);
4816  continue;
4817  }
4818  else {
4819  TVector3 fin_intersection1 = ((PndTrkSkewHit*) hit)->GetIntersection1();
4820  TVector3 fin_intersection2 = ((PndTrkSkewHit*) hit)->GetIntersection2();
4821  double phi1 = ((PndTrkSkewHit*) hit)->GetPhi1();
4822  double phi2 = ((PndTrkSkewHit*) hit)->GetPhi2();
4823 
4824  double dist1 = fabs(fitm7 * phi1 - fin_intersection1.Z() + fitq7) / TMath::Sqrt(fitm7 * fitm7 + 1); // CHECK ortho distance or not?
4825  double dist2 = fabs(fitm7 * phi2 - fin_intersection2.Z() + fitq7) / TMath::Sqrt(fitm7 * fitm7 + 1); // CHECK " "
4826 
4827  double distance = 1000;
4828  dist1 < dist2 ? (distance = dist1, hit->SetPosition(fin_intersection1), hit->SetPhi(phi1)) : (distance = dist2, hit->SetPosition(fin_intersection2), hit->SetPhi(phi2));
4829 
4830  if(distance < 10) skewhitlist2.AddHit(hit);
4831  }
4832  }
4833  fLineHisto->Reset();
4834  // see the hits
4835  TVector3 position, positionk;
4836  double phi, phik;
4837  for(int jhit = 0; jhit < skewhitlist2.GetNofHits(); jhit++) {
4838  hit = skewhitlist2.GetHit(jhit);
4839  if(!hit) continue;
4840 
4841  int solutions = 0;
4842  if(hit->IsStt()) solutions = 2;
4843  else solutions = 1;
4844 
4845  for(int khit = jhit + 1; khit < skewhitlist2.GetNofHits(); khit++) {
4846  PndTrkHit* hitk = skewhitlist2.GetHit(khit);
4847  if(!hitk) continue;
4848 
4849  int ksolutions = 0;
4850  if(hitk->IsStt()) ksolutions = 2;
4851  else ksolutions = 1;
4852 
4853  for(int jsol = 0; jsol < solutions; jsol++)
4854  {
4855  if(solutions == 1) {
4856  position = hit->GetPosition();
4857  phi = hit->GetPhi();
4858  }
4859  else if(jsol == 0) {
4860  position = ((PndTrkSkewHit*) hit)->GetIntersection1();
4861  phi = ((PndTrkSkewHit*) hit)->GetPhi1();
4862  }
4863  else {
4864  position = ((PndTrkSkewHit*) hit)->GetIntersection2();
4865  phi = ((PndTrkSkewHit*) hit)->GetPhi2();
4866  }
4867 
4868  for(int ksol = 0; ksol < ksolutions; ksol++)
4869  {
4870  if(ksolutions == 1) {
4871  positionk = hitk->GetPosition();
4872  phik = hitk->GetPhi();
4873  }
4874  else if(ksol == 0) {
4875  positionk = ((PndTrkSkewHit*) hitk)->GetIntersection1();
4876  phik = ((PndTrkSkewHit*) hitk)->GetPhi1();
4877  }
4878  else {
4879  positionk = ((PndTrkSkewHit*) hitk)->GetIntersection2();
4880  phik = ((PndTrkSkewHit*) hitk)->GetPhi2();
4881  }
4882 
4883  double cost = (positionk.Z() - position.Z()) / TMath::Sqrt((phi - phik) * (phi - phik) + (positionk.Z() - position.Z()) * (positionk.Z() - position.Z()));
4884  double theta = TMath::ACos(cost);
4885  double r1 = phi * cost + position.Z() * TMath::Sin(theta);
4886  double r2 = phik * cost + positionk.Z() * TMath::Sin(theta);
4887  double r = r1;
4888  if(fabs(r1 - r2) > 1.e-9) {
4889  theta = -TMath::ACos(cost);
4890  r = phi * cost + position.Z() * TMath::Sin(theta);
4891  }
4892  fLineHisto->Fill(theta * TMath::RadToDeg(), r);
4893  }
4894  }
4895  }
4896  }
4897 
4898  bin = fLineHisto->GetMaximumBin();
4899  fLineHisto->GetBinXYZ(bin, binx, biny, binz);
4900  tpeak = fLineHisto->GetXaxis()->GetBinCenter(binx);
4901  rpeak = fLineHisto->GetYaxis()->GetBinCenter(biny);
4902  // cout << "tpeak " << tpeak << " rpeak " << rpeak << endl;
4903  double fitm8 = -TMath::Cos(tpeak * TMath::DegToRad())/TMath::Sin(tpeak * TMath::DegToRad());
4904  double fitq8 = rpeak/TMath::Sin(tpeak * TMath::DegToRad());
4905 
4906  if(fDisplayOn) {
4907  display->cd(3);
4908  fLineHisto->Draw("colz");
4909  display->cd(4);
4910  TLine *line = new TLine(-360, -360 * fitm8 + fitq8, 360, 360 * fitm8 + fitq8);
4911  line->SetLineColor(3);
4912  line->Draw("SAME");
4913  display->Update();
4914  display->Modified();
4915  char goOnChar;
4916  cin >> goOnChar;
4917  }
4918 
4919  // finalize the cluster
4920  for(int jhit = 0; jhit < skewhitlist2.GetNofHits(); jhit++) {
4921  hit = skewhitlist2.GetHit(jhit);
4922  if(fFinalCluster->DoesContain(hit) == kFALSE) fFinalCluster->AddHit((PndTrkHit*) hit);
4923  }
4924  fFinalCluster->Sort();
4925  if(fFinalCluster->GetHit(0)->IsGem()) {
4927  }
4928 
4929  // cout << endl;
4930  for(int jhit = 0; jhit < fFinalCluster->GetNofHits(); jhit++) {
4931  hit = fFinalCluster->GetHit(jhit);
4932  // cout << "final hit " << hit->GetHitID() << " " << hit->GetDetectorID() << " " << hit->GetSortVariable() << endl;
4933  }
4934 
4935 
4936  // ................ final track ......................
4937  PndTrkTrack finalfwdtrack(fFinalCluster, xc6, yc6, R6);
4938  // compute charge
4939  finalfwdtrack.ComputeCharge();
4940 
4941  // last two parameters in real plane
4942  double tanl = - finalfwdtrack.GetCharge() * fitm8 * (180./TMath::Pi())/R6;
4943  double z0 = fitq8;
4944  finalfwdtrack.SetZ0(z0);
4945  finalfwdtrack.SetTanL(tanl);
4946  fTrackList->AddTrack(&finalfwdtrack);
4947  //for(int jtrk = 0; jtrk < fTrack //[R.K. 01/2017] unused variableList->GetNofTracks(); jtrk++) {
4948  //PndTrkTrack *tmptrack = fTrackList->GetTrack(jtrk); //[R.K. 01/2017] unused variable
4949  //} //[R.K. 01/2017] unused variable
4950  }
4951  }
4952 
4953  // fDisplayOn = kTRUE;
4954  if(fDisplayOn) {
4955  //char goOnChar; //[R.K. 01/2017] unused variable
4956  display->cd(1);
4957  Refresh();
4958  }
4959  // PndTrkTrack --> PndTrack
4960  for(int itrk = noflongtracks; itrk < fTrackList->GetNofTracks(); itrk++) {
4962  // cout << "- ----------------------------------- track green " << track->GetRadius() << endl;
4963 
4964  PndTrack theTrack = track->ConvertToPndTrack();
4965 
4966  TClonesArray& clref1 = *fTrackArray;
4967  Int_t size = clref1.GetEntriesFast();
4968  PndTrack *outputtrack = new(clref1[size]) PndTrack(theTrack.GetParamFirst(),theTrack.GetParamLast(), theTrack.GetTrackCand());
4969  outputtrack->SetFlag(222);
4970  TClonesArray& clref2 = *fTrackCandArray;
4971  size = clref2.GetEntriesFast();
4972  PndTrackCand *outputtrackcand = new(clref2[size]) PndTrackCand(theTrack.GetTrackCand());
4973 
4974  TClonesArray& clref3 = *fTrkTrackArray;
4975  size = clref3.GetEntriesFast();
4976  new(clref3[size]) PndTrkTrack(*track); //PndTrkTrack*outputtrktrack = //[R.K.03/2017] unused variable
4977 
4978  // cout << "\033[1;31m RECO R " << outputtrktrack->GetRadius() << ", " << outputtrack->GetParamFirst().GetMomentum().Perp() / 0.006 << "\033[0m" << endl;
4979 
4980 
4981  // cout << "MOM FIRST: TOT, PT, PL " << outputtrack->GetParamFirst().GetMomentum().Mag() << " " << outputtrack->GetParamFirst().GetMomentum().Perp() << " " << outputtrack->GetParamFirst().GetMomentum().Z() << endl;
4982  // cout << "MOM LAST: TOT, PT, PL " << outputtrack->GetParamLast().GetMomentum().Mag() << " " << outputtrack->GetParamLast().GetMomentum().Perp() << " " << outputtrack->GetParamLast().GetMomentum().Z() << endl;
4983 
4984  if(fDisplayOn) {
4985  char goOnChar;
4986  display->cd(1);
4987  track->Draw(kGreen);
4988  track->GetCluster().LightUp();
4989 
4990  cout << "TRACK " << itrk << endl;
4991  cout << "MOM FIRST: TOT, PT, PL " << outputtrack->GetParamFirst().GetMomentum().Mag() << " " << outputtrack->GetParamFirst().GetMomentum().Perp() << " " << outputtrack->GetParamFirst().GetMomentum().Z() << " nofhits " << outputtrackcand->GetNHits() << endl;
4992  cout << "X, Y, R " << track->GetCenter().X() << " " << track->GetCenter().Y() << " " << track->GetRadius() << endl;
4993  // cout << "Z0, TANL " << track->GetZ0() << " " << track->GetTanL() << endl;
4994  track->ComputeCharge();
4995 
4996  cout << "CHARGE " << track->GetCharge() << endl;
4997  display->Update();
4998  display->Modified();
4999  cin >> goOnChar;
5000  }
5001 
5002  }
5003 
5004  if(fDisplayOn) {
5005  char goOnChar;
5006  cin >> goOnChar;
5007  display->Update();
5008  display->Modified();
5009  }
5010 
5011 
5012  // cout << "HOW MANY TRACKS? " << fTrackArray->GetEntriesFast() << endl;
5013  // for(int itrk = 0; itrk < fTrackArray->GetEntriesFast(); itrk++) {
5014  // PndTrack *trk = (PndTrack*) fTrackArray->At(itrk);
5015  // cout << "TRACK " << itrk << " HAS FLAG " << trk->GetFlag() << endl;
5016  // }
5017 
5018 
5019 
5020  Reset();
5021  fFinalCluster->Clear("C");
5022  fTrackList->Clear("C");
5023  fConformalHitList->Clear("C");
5024 // delete indivtracklist;
5025 
5026 }
5027 
5028 
5029 
5031 {
5032 
5033  if(fDisplayOn) {
5034  char goOnChar;
5035  display->Update();
5036  display->Modified();
5037  cout << "Finish? ";
5038  cin >> goOnChar;
5039  cout << "FINISH" << endl;
5040  }
5041 
5042  if(fInitDone) {
5043  stthitlist->Clear();
5044  mvdpixhitlist->Clear();
5045  mvdstrhitlist->Clear();
5046  gemhitlist->Clear();
5047  scithitlist->Clear();
5048 
5049  // if(stthitlist) delete stthitlist;
5050  // if(mvdpixhitlist) delete mvdpixhitlist;
5051  // if(mvdstrhitlist) delete mvdstrhitlist;
5052  // if(scithitlist) delete scithitlist;
5053  // if(gemhitlist) delete gemhitlist;
5054 
5055  if(fTimer) {
5056  fTimer->Stop();
5057  fTime += fTimer->RealTime();
5058 
5059  if(fVerbose > 0) cerr << fEventCounter << " Real time " << fTime << " s" << endl;
5060  }
5061  }
5062 
5064  fInitDone = kFALSE;
5065 }
5066 
5067 
5068 // void PndTrkTrackFinder::Apollonius(PndTrkCluster *cluster, double *X, double *Y, double *R)
5069 void PndTrkTrackFinder::Apollonius(PndTrkCluster *cluster, std::vector< double > &X, std::vector< double > &Y, std::vector< double > &R)
5070 {
5071 
5072  if(fDisplayOn) {
5073  TH2F *h2 = new TH2F("h2", "", 100, -70, 70, 100, -70, 70);
5074  display->cd(2);
5075  h2->Draw();
5076 
5077  display->Update();
5078  display->Modified();
5079  }
5080 
5081  int ncircles = cluster->GetNofHits();
5082  double circle[ncircles][3];
5083 
5084  for(int i = 0; i < ncircles; i++)
5085  {
5086  PndTrkHit *hit = cluster->GetHit(i);
5087  double xc = hit->GetPosition().X();
5088  double yc = hit->GetPosition().Y();
5089  double rc = hit->GetIsochrone();
5090 
5091  circle[i][0] = xc;
5092  circle[i][1] = yc;
5093  circle[i][2] = rc;
5094  // cout << xc << " " << yc << " " << rc << endl;
5095 
5096  if(fDisplayOn) {
5097  //char goOnChar; //[R.K. 01/2017] unused variable
5098  display->cd(2);
5099  TArc *arc = new TArc(xc, yc, rc);
5100  arc->SetFillStyle(0);
5101  arc->Draw("SAME");
5102  display->Update();
5103  display->Modified();
5104  }
5105  }
5106 
5107  int counter = 0;
5108  for(int a = 0; a < ncircles; a++) {
5109  for(int b = a + 1; b < ncircles; b++) {
5110  for(int c = b + 1; c < ncircles; c++) {
5111  for(int csign1 = -1; csign1 <= 1; csign1 += 2) {
5112  for(int csign2 = -1; csign2 <= 1; csign2 += 2) {
5113  double avar = 2 * (circle[a][0] - circle[b][0]);
5114  double bvar = 2 * (circle[a][1] - circle[b][1]);
5115  double cvar = 2 * (csign1 * circle[a][2] + csign2 * circle[b][2]);
5116  double dvar = (circle[a][0] * circle[a][0] + circle[a][1] * circle[a][1] - circle[a][2] * circle[a][2]) - (circle[b][0] * circle[b][0] + circle[b][1] * circle[b][1] - circle[b][2] * circle[b][2]);
5117 
5118  for(int csignp = -1; csignp <= 1; csignp += 2) {
5119  double avarp = 2 * (circle[a][0] - circle[c][0]);
5120  double bvarp = 2 * (circle[a][1] - circle[c][1]);
5121  double cvarp = 2 * (csign1 * circle[a][2] + csignp * circle[c][2]);
5122  double dvarp = (circle[a][0] * circle[a][0] + circle[a][1] * circle[a][1] - circle[a][2] * circle[a][2]) - (circle[c][0] * circle[c][0] + circle[c][1] * circle[c][1] - circle[c][2] * circle[c][2]);
5123 
5124  // ======================================
5125  double thisq = (dvar * bvarp - dvarp * bvar) / (avar * bvarp - avarp * bvar);
5126  double thism = (bvar * cvarp - bvarp * cvar) / (avar * bvarp - avarp * bvar);
5127 
5128  double thisp = (avar * dvarp - avarp * dvar) / (avar * bvarp - avarp * bvar);
5129  double thiss = (cvar * avarp - cvarp * avar) / (avar * bvarp - avarp * bvar);
5130  // cout << thism << " " << thisq << " " << thiss << " " << thisp << endl;
5131  // ======================================
5132  // thisa x**2 + 2 * thisb x + thisc = 0
5133 
5134  double thisa = thism * thism + thiss * thiss - 1;
5135  double thisb = thism * (thisq - circle[a][0]) + thiss * (thisp - circle[a][1]) - csign1 * circle[a][2];
5136  double thisc = (thisq - circle[a][0]) * (thisq - circle[a][0]) + (thisp - circle[a][1]) * (thisp - circle[a][1]) - circle[a][2] * circle[a][2];
5137 
5138  if((thisb * thisb - thisa * thisc) < 0) continue;
5139  double r = (- thisb + TMath::Sqrt(thisb * thisb - thisa * thisc))/ thisa;
5140  // cout << "r1 " << r << endl;
5141  if(r < 0) {
5142  r = (- thisb - TMath::Sqrt(thisb * thisb - thisa * thisc))/ thisa;
5143  // cout << "r2 " << r << endl;
5144  }
5145 
5146  if(r < 0) continue; // CHECK
5147 
5148  // R[counter] = r;
5149  // X[counter] = thism * R[counter] + thisq;
5150  // Y[counter] = thiss * R[counter] + thisp;
5151 
5152  R.push_back(r);
5153  X.push_back(thism * R[counter] + thisq);
5154  Y.push_back(thiss * R[counter] + thisp);
5155  cout << R[counter] << " " << X[counter] << " " << Y[counter] << endl;
5156  // if(fDisplayOn) {
5157  // char goOnChar;
5158  // display->cd(2);
5159  // TArc *arc0 = new TArc(X[counter], Y[counter], R[counter]);
5160  // arc0->SetFillStyle(0);
5161  // arc0->SetLineColor(2);
5162  // arc0->Draw("SAME");
5163  // display->Update();
5164  // display->Modified();
5165  // // cin >> goOnChar;
5166  // }
5167 
5168 
5169  // cout << "ctr/dist/R " << counter << " " << TMath::Sqrt((circle[a][0] - X[counter]) * (circle[a][0] - X[counter]) + (circle[a][1] - Y[counter]) * (circle[a][1] - Y[counter])) - R[counter] << " " << R[counter] << endl;
5170  counter++;
5171  // cout << endl;
5172  }
5173  }
5174  }
5175  }
5176  }
5177  }
5178 }
5179 
5180 void PndTrkTrackFinder::CircleBy3Points(PndTrkHit* hit1, PndTrkHit * hit2, PndTrkHit * hit3, double &X, double &Y, double &R)
5181 {
5182 
5183  int ncircles = 3;
5184  double circle[ncircles][3];
5185 
5186  // cout << "circle 1 by 3 points " << hit1->GetPosition().X() << " " << hit1->GetPosition().Y() << endl;
5187  // cout << "circle 2 by 3 points " << hit2->GetPosition().X() << " " << hit2->GetPosition().Y() << endl;
5188  // cout << "circle 3 by 3 points " << hit3->GetPosition().X() << " " << hit3->GetPosition().Y() << endl;
5189 
5190 
5191  circle[0][0] = hit1->GetPosition().X();
5192  circle[0][1] = hit1->GetPosition().Y();
5193  circle[0][2] = hit1->GetIsochrone();
5194 
5195  circle[1][0] = hit2->GetPosition().X();
5196  circle[1][1] = hit2->GetPosition().Y();
5197  circle[1][2] = hit2->GetIsochrone();
5198 
5199  circle[2][0] = hit3->GetPosition().X();
5200  circle[2][1] = hit3->GetPosition().Y();
5201  circle[2][2] = hit3->GetIsochrone();
5202 
5203 
5204  // in case of alignement ad an error CHECK
5205  if((circle[1][1] - circle[0][1])/(circle[1][0] - circle[0][0]) - (circle[2][1] - circle[0][1])/(circle[2][0] - circle[0][0]) < 0.0001){
5206  circle[0][0] += 0.01;
5207  circle[0][1] += 0.01;
5208  }
5209 
5210  for(int a = 0; a < ncircles; a++) {
5211  for(int b = a + 1; b < ncircles; b++) {
5212  for(int c = b + 1; c < ncircles; c++) {
5213  Y = 0.5 * ((circle[a][0] - circle[b][0]) * (circle[a][0] * circle[a][0] - circle[c][0] * circle[c][0] + circle[a][1] * circle[a][1] - circle[c][1] * circle[c][1]) - (circle[a][0] - circle[c][0]) * (circle[a][0] * circle[a][0] - circle[b][0] * circle[b][0] + circle[a][1] * circle[a][1] - circle[b][1] * circle[b][1])) / ((circle[a][1] - circle[c][1]) * (circle[a][0] - circle[b][0]) - (circle[a][1] - circle[b][1]) * (circle[a][0] - circle[c][0]));
5214 
5215  if(circle[a][0] != circle[b][0]) {
5216  X = 0.5 * (circle[a][0] * circle[a][0] - circle[b][0] * circle[b][0] + circle[a][1] * circle[a][1] - circle[b][1] * circle[b][1] ) / (circle[a][0] - circle[b][0]) - Y * (circle[a][1] - circle[b][1])/(circle[a][0] - circle[b][0]);
5217  }
5218  else if(circle[a][0] != circle[c][0]) {
5219  X = 0.5 * (circle[a][0] * circle[a][0] - circle[c][0] * circle[c][0] + circle[a][1] * circle[a][1] - circle[c][1] * circle[c][1] ) / (circle[a][0] - circle[c][0]) - Y * (circle[a][1] - circle[c][1])/(circle[a][0] - circle[c][0]);
5220  }
5221 
5222  R = TMath::Sqrt((circle[a][0] - X) * (circle[a][0] - X) + (circle[a][1] - Y) * (circle[a][1] - Y));
5223  }
5224  }
5225  }
5226 }
5227 
5228 void PndTrkTrackFinder::Apollonius(PndTrkHit* hit1, PndTrkHit * hit2, PndTrkHit * hit3, std::vector< double > &X, std::vector< double > &Y, std::vector< double > &R)
5229 {
5230 
5231  int ncircles = 3;
5232  double circle[ncircles][3];
5233 
5234  circle[0][0] = hit1->GetPosition().X();
5235  circle[0][1] = hit1->GetPosition().Y();
5236  circle[0][2] = hit1->GetIsochrone();
5237 
5238  circle[1][0] = hit2->GetPosition().X();
5239  circle[1][1] = hit2->GetPosition().Y();
5240  circle[1][2] = hit2->GetIsochrone();
5241 
5242  circle[2][0] = hit3->GetPosition().X();
5243  circle[2][1] = hit3->GetPosition().Y();
5244  circle[2][2] = hit3->GetIsochrone();
5245 
5246  int counter = 0;
5247  for(int a = 0; a < ncircles; a++) {
5248  for(int b = a + 1; b < ncircles; b++) {
5249  for(int c = b + 1; c < ncircles; c++) {
5250  for(int csign1 = -1; csign1 <= 1; csign1 += 2) {
5251  for(int csign2 = -1; csign2 <= 1; csign2 += 2) {
5252  double avar = 2 * (circle[a][0] - circle[b][0]);
5253  double bvar = 2 * (circle[a][1] - circle[b][1]);
5254  double cvar = 2 * (csign1 * circle[a][2] + csign2 * circle[b][2]);
5255  double dvar = (circle[a][0] * circle[a][0] + circle[a][1] * circle[a][1] - circle[a][2] * circle[a][2]) - (circle[b][0] * circle[b][0] + circle[b][1] * circle[b][1] - circle[b][2] * circle[b][2]);
5256 
5257  for(int csignp = -1; csignp <= 1; csignp += 2) {
5258  double avarp = 2 * (circle[a][0] - circle[c][0]);
5259  double bvarp = 2 * (circle[a][1] - circle[c][1]);
5260  double cvarp = 2 * (csign1 * circle[a][2] + csignp * circle[c][2]);
5261  double dvarp = (circle[a][0] * circle[a][0] + circle[a][1] * circle[a][1] - circle[a][2] * circle[a][2]) - (circle[c][0] * circle[c][0] + circle[c][1] * circle[c][1] - circle[c][2] * circle[c][2]);
5262 
5263  // ======================================
5264  double thisq = (dvar * bvarp - dvarp * bvar) / (avar * bvarp - avarp * bvar);
5265  double thism = (bvar * cvarp - bvarp * cvar) / (avar * bvarp - avarp * bvar);
5266 
5267  double thisp = (avar * dvarp - avarp * dvar) / (avar * bvarp - avarp * bvar);
5268  double thiss = (cvar * avarp - cvarp * avar) / (avar * bvarp - avarp * bvar);
5269  // cout << thism << " " << thisq << " " << thiss << " " << thisp << endl;
5270  // ======================================
5271  // thisa x**2 + 2 * thisb x + thisc = 0
5272 
5273  double thisa = thism * thism + thiss * thiss - 1;
5274  double thisb = thism * (thisq - circle[a][0]) + thiss * (thisp - circle[a][1]) - csign1 * circle[a][2];
5275  double thisc = (thisq - circle[a][0]) * (thisq - circle[a][0]) + (thisp - circle[a][1]) * (thisp - circle[a][1]) - circle[a][2] * circle[a][2];
5276 
5277  if((thisb * thisb - thisa * thisc) < 0) continue;
5278  double r = (- thisb + TMath::Sqrt(thisb * thisb - thisa * thisc))/ thisa;
5279  // cout << "r1 " << r << endl;
5280  if(r < 0) {
5281  r = (- thisb - TMath::Sqrt(thisb * thisb - thisa * thisc))/ thisa;
5282  // cout << "r2 " << r << endl;
5283  }
5284 
5285  if(r < 0) continue; // CHECK
5286 
5287  // R[counter] = r;
5288  // X[counter] = thism * R[counter] + thisq;
5289  // Y[counter] = thiss * R[counter] + thisp;
5290 
5291  R.push_back(r);
5292  X.push_back(thism * R[counter] + thisq);
5293  Y.push_back(thiss * R[counter] + thisp);
5294  cout << R[counter] << " " << X[counter] << " " << Y[counter] << endl;
5295  // if(fDisplayOn) {
5296  // char goOnChar;
5297  // display->cd(2);
5298  // TArc *arc0 = new TArc(X[counter], Y[counter], R[counter]);
5299  // arc0->SetFillStyle(0);
5300  // arc0->SetLineColor(2);
5301  // arc0->Draw("SAME");
5302  // display->Update();
5303  // display->Modified();
5304  // // cin >> goOnChar;
5305  // }
5306 
5307 
5308  // cout << "ctr/dist/R " << counter << " " << TMath::Sqrt((circle[a][0] - X[counter]) * (circle[a][0] - X[counter]) + (circle[a][1] - Y[counter]) * (circle[a][1] - Y[counter])) - R[counter] << " " << R[counter] << endl;
5309  counter++;
5310  // cout << endl;
5311  }
5312  }
5313  }
5314  }
5315  }
5316  }
5317 }
5318 
5319 
5320 
5321 // ============================================================================================
5322 // DISPLAY ***********************************************************************************
5323 // ============================================================================================
5324 
5326  // CHECK
5327  //char goOnChar; //[R.K. 01/2017] unused variable
5328  // cout << "Refresh?" << endl;
5329  // cin >> goOnChar;
5330  // cout << "REFRESHING" << endl;
5331  DrawGeometry();
5332  if(fVerbose) cout << "Refresh stt" << endl;
5334  if(fVerbose) cout << "Refresh pixel" << endl;
5336  if(fVerbose) cout << "Refresh strip" << endl;
5338  if(fVerbose) cout << "Refresh scit" << endl;
5340  if(fVerbose) cout << "Refresh gem" << endl;
5342  if(fVerbose) cout << "Refresh stop" << endl;
5343 
5344 }
5345 
5347  display->cd(3);
5348  legendre->Draw();
5349  display->Update();
5350  display->Modified();
5351 }
5352 
5353 void PndTrkTrackFinder::RefreshConf() { // CHECK delete
5354  // CHECK
5355  //char goOnChar;
5356  // cout << "RefreshConf?" << endl;
5357  // cin >> goOnChar;
5358  // cout << "REFRESHING CONF" << endl;
5359 }
5360 
5362  display->cd(1);
5363  hitlist->Draw();
5364  display->Update();
5365  display->Modified();
5366 }
5367 
5369 
5370  if(hxy == NULL) hxy = new TH2F("hxy", "xy plane", 110, -55, 55, 110, -55, 55);
5371  else hxy->Reset();
5372  display->cd(1);
5373  hxy->SetStats(kFALSE);
5374  hxy->Draw();
5375 
5376  // draw all the tubes
5377  for(int itube = 1; itube < fTubeArray->GetEntriesFast(); itube++) {
5378  PndSttTube *tube = (PndSttTube*) fTubeArray->At(itube);
5379  if(tube->IsParallel()) {
5380  TArc * arc = new TArc(tube->GetPosition().X(), tube->GetPosition().Y(), 0.5);
5381  arc->SetFillStyle(0);
5382  arc->SetLineColor(kCyan - 10);
5383  // if(tube->GetLayerID() == 0 || tube->GetLayerID() == 7 || tube->GetLayerID() == 16 || tube->GetLayerID() == 20) arc->SetFillColor(kRed);
5384  // else arc->SetFillStyle(0);
5385 
5386  arc->Draw("SAME");
5387  }
5388  else {
5389  TMarker *mrk = new TMarker(tube->GetPosition().X(), tube->GetPosition().Y(), 6);
5390 
5391  mrk->SetMarkerColor(kCyan - 10);
5392  mrk->Draw("SAME");
5393  }
5394  }
5395  // ............................
5396 
5397  display->Update();
5398  display->Modified();
5399 
5400 }
5401 
5402 void PndTrkTrackFinder::DrawGeometryConf(double x1, double x2, double y1, double y2) {
5403  // CHECK
5404  //char goOnChar; //[R.K. 01/2017] unused variable
5405  // cout << "DRAWING GEOMETRY CONF" << endl;
5406  // cin >> goOnChar;
5407 
5408  // CHECK previous calculations, now not used;
5409  if(huv == NULL) huv = new TH2F("huv", "uv plane", 100, x1, x2, 100, y1, y2);
5410  else {
5411  huv->Reset();
5412  huv->GetXaxis()->SetLimits(x1, x2);
5413  huv->GetYaxis()->SetLimits(y1, y2);
5414  }
5415  display->cd(2);
5416  huv->Draw();
5417  display->Update();
5418  display->Modified();
5419 
5420 }
5421 
5422 // draw lists ---------
5424  char goOnChar;
5425  // cout << "DrawLists" << endl;
5426  // cin >> goOnChar;
5427  // Refresh();
5428 
5429 
5430  //for(int i = 0; i < fHitMap->GetStandalone().GetEntriesFast(); i++) { //[R.K. 03/2017] unused variable
5431  //PndTrkHit *hitA = (PndTrkHit*) fHitMap->GetStandalone().At(i); //[R.K. 03/2017] unused variable
5433  //} //[R.K. 03/2017] unused variable
5434  //for(int i = 0; i < fHitMap->GetSeeds().GetEntriesFast(); i++) { //[R.K. 03/2017] unused variable
5435  //PndTrkHit *hitA = (PndTrkHit*) fHitMap->GetSeeds().At(i); //[R.K. 03/2017] unused variable
5437  //} //[R.K. 03/2017] unused variable
5438  //for(int i = 0; i < fHitMap->GetCandseeds().GetEntriesFast(); i++) { //[R.K. 03/2017] unused variable
5439  //PndTrkHit *hitA = (PndTrkHit*) fHitMap->GetCandseeds().At(i); //[R.K. 03/2017] unused variable
5441  //} //[R.K. 03/2017] unused variable
5442  for(int i = 0; i < fHitMap->GetIndivisibles().GetEntriesFast(); i++) {
5443  PndTrkHit *hitA = (PndTrkHit*) fHitMap->GetIndivisibles().At(i);
5444  // hitA->DrawTube(kOrange);
5445  TObjArray neighs = fHitMap->GetNeighboringsToHit(hitA);
5446  for(int j = 0; j < neighs.GetEntriesFast(); j++) {
5447  PndTrkHit *hitB = (PndTrkHit*) neighs.At(j);
5448  TObjArray neighs2 = fHitMap->GetNeighboringsToHit(hitA);
5449  if(neighs2.GetEntriesFast() > 2) {
5450  int counter = 0;
5451  PndSttTube *tubeB = (PndSttTube* ) fTubeArray->At(hitB->GetTubeID());
5452  for(int k = 0; k < neighs2.GetEntriesFast(); k++) {
5453  PndTrkHit *hitC = (PndTrkHit*) neighs2.At(k);
5454  PndSttTube *tubeC = (PndSttTube* ) fTubeArray->At(hitC->GetTubeID());
5455  cout << "tubes " << tubeB << " "<< tubeC << endl;
5456  if(tubeB->GetLayerID() == tubeC->GetLayerID()) continue;
5457  counter++;
5458  }
5459  if(counter > 2) continue;
5460  }
5461  // hitB->DrawTube(kYellow);
5462  }
5463  // display->Update();
5464  // display->Modified();
5465  // cin >> goOnChar;
5466 
5467  }
5468 
5469  // for(int i = 0; i < limits.GetEntriesFast(); i++) {
5470  // PndTrkHit *hitA = (PndTrkHit*) limits.At(i);
5471  // hitA->DrawTube(kYellow);
5472  // }
5473 
5474  display->Update();
5475  display->Modified();
5476  cin >> goOnChar;
5477 }
5478 
5479 
5480 // draw neighborings ---------
5482  char goOnChar;
5483 
5484  for(int ihit = 0; ihit < stthitlist->GetNofHits(); ihit++) {
5485  cout << "new neigh hit?" << endl;
5486  cin >> goOnChar;
5487  PndTrkHit *hit = stthitlist->GetHit(ihit);
5488  DrawNeighboringsToHit(hit);
5489  cin >> goOnChar;
5490  }
5491 
5492 }
5493 
5495 
5496 
5497  Refresh();
5498  hit->DrawTube(kYellow);
5499  //PndSttTube *tube = (PndSttTube*) fTubeArray->At(hit->GetTubeID()); //[R.K. 01/2017] unused variable
5500  TObjArray neighs = fHitMap->GetNeighboringsToHit(hit);
5501 
5502 
5503  // cout << "HIT " << hit->GetHitID() << "(" << hit->GetTubeID() << "/" << tube->GetLayerID() << ")" << " has " << neighs.GetEntriesFast() << " neighborings: ";
5504  for(int i = 0; i < neighs.GetEntriesFast(); i++) {
5505  PndTrkHit *hitA = (PndTrkHit*) neighs.At(i);
5506  hitA->DrawTube(kCyan);
5507  PndSttTube *tubeA = (PndSttTube*) fTubeArray->At(hitA->GetTubeID());
5508  cout << " " << hitA->GetHitID() << "(" << hitA->GetTubeID() << "/" << tubeA->GetLayerID() << ")";
5509  }
5510  cout << endl;
5511  display->Update();
5512  display->Modified();
5513 
5514 }
5515 
5516 void PndTrkTrackFinder::DrawConfHit(double u, double v, double r, int marker) {
5517  display->cd(2);
5518  if(r >= 0) {
5519  TArc *arc = new TArc(u, v, r);
5520  arc->SetFillStyle(0);
5521  arc->Draw("SAME");
5522  }
5523  else {
5524  TMarker *mrk = new TMarker(u, v, marker);
5525  mrk->Draw("SAME");
5526  }
5527  // display->Update();
5528  // display->Modified();
5529 }
5530 
5532 
5533  // set the conformal transformation, where the
5534  // translation and rotation must be already set
5536 
5537  // loop over the cluster hits
5538  // and port them to conf plane
5539  for(int jhit = 0; jhit < cluster->GetNofHits(); jhit++) {
5540  PndTrkHit *hit = cluster->GetHit(jhit);
5541  if(hit == fRefHit) continue;
5542  PndTrkConformalHit chit;
5543  // cout << "HIT " << hit->GetHitID() << " " << hit->IsSttParallel() << " " << hit->IsSttSkew() << endl;
5544  if(hit->IsSttParallel() == kTRUE) chit = conform->GetConformalSttHit(hit);
5545  else chit = conform->GetConformalHit(hit); // CHECK
5546  fConformalHitList->AddHit(&chit);
5547  // cout << hit->GetPosition().X() << " " << hit->GetPosition().Y() << " " << hit->GetIsochrone() << " " << hit->IsSttParallel() << " " << " to CONFORMAL " << chit->GetU() << " " << chit->GetV() << " " << chit->GetIsochrone() << endl;
5548 
5549  }
5550  return fConformalHitList->GetNofHits();
5551 }
5552 
5553 // ----------------------- FOR SECONDARIES
5555  int ntot = 0;
5556  if(isec == -1) ntot = stthitlist->GetNofHits();
5557  else ntot = stthitlist->GetNofHitsInSector(isec);
5558 
5559  if(ntot == 0) return NULL;
5560 
5561 
5562  int tmphitid = -1;
5563  Double_t tmpiso = 1.;
5564  PndTrkHit *refhit = NULL;
5565  for(int jhit = 0; jhit < ntot; jhit++) {
5566  PndTrkHit *hit = NULL;
5567  if(isec == -1) hit = stthitlist->GetHit(jhit);
5568  else hit = stthitlist->GetHitFromSector(jhit, isec);
5569 
5570  if(hit->IsUsed()) {
5571  if(fVerbose > 1) cout << "STT hit " << jhit << "already used " << endl;
5572  continue; }
5573  if(hit->IsSttSkew()) continue;
5574  if(hit->GetIsochrone() < tmpiso) {
5575  tmphitid = jhit;
5576  tmpiso = hit->GetIsochrone();
5577  refhit = hit;
5578  }
5579  }
5580  if(tmphitid == -1) return NULL;
5581 
5582  // PndTrkHit *refhit = &thishitlist[tmphitid];
5583  if(fVerbose > 1) cout << "STT REFERENCE HIT " << tmphitid << " " << refhit->GetIsochrone() << endl;
5584  return refhit;
5585 
5586 }
5587 
5589 {
5590  if(mvdpixhitlist->GetNofHits() == 0) return NULL;
5591  // loop on mvd pix hits
5592  int tmphitid = -1;
5593  PndTrkHit *refhit = NULL;
5594  for(int jhit = 0; jhit < mvdpixhitlist->GetNofHits(); jhit++) {
5595  PndTrkHit *hit = mvdpixhitlist->GetHit(jhit);
5596  if(hit->IsUsed()) {
5597  if(fVerbose > 1) cout << "already used V" << endl;
5598  continue;
5599  }
5600  tmphitid = jhit;
5601  break;
5602  }
5603  if(tmphitid == -1) return NULL;
5604  refhit = mvdpixhitlist->GetHit(tmphitid);
5605  if(fVerbose > 1) cout << "MVD PIXEL REFERENCE HIT " << refhit->GetHitID() << endl;
5606  return refhit;
5607 }
5608 
5610 {
5611  if(mvdstrhitlist->GetNofHits() == 0) return NULL;
5612  // loop on mvd str hits
5613  int tmphitid = -1;
5614  PndTrkHit *refhit = NULL;
5615  for(int jhit = 0; jhit < mvdstrhitlist->GetNofHits(); jhit++) {
5616  PndTrkHit *hit = mvdstrhitlist->GetHit(jhit);
5617  if(hit->IsUsed()) {
5618  if(fVerbose > 1) cout << "already used V" << endl;
5619  continue;
5620  }
5621  tmphitid = jhit;
5622  break;
5623  }
5624  if(tmphitid == -1) return NULL;
5625  refhit = mvdstrhitlist->GetHit(tmphitid);
5626  if(fVerbose > 1) cout << "MVD STRIP REFERENCE HIT " << refhit->GetHitID() << endl;
5627  return refhit;
5628 }
5629 
5631 {
5632  PndTrkHit *refhit = NULL;
5633  refhit = FindMvdStripReferenceHit();
5634  // refhit = FindMvdPixelReferenceHit();
5635  if(refhit != NULL) return refhit;
5636  // refhit = FindMvdStripReferenceHit();
5638  return refhit;
5639 }
5640 
5642 {
5643  PndTrkHit *refhit = NULL;
5644  // refhit = FindMvdReferenceHit();
5645  refhit = FindSttReferenceHit();
5646  if(refhit != NULL) return refhit;
5647  // refhit = FindSttReferenceHit();
5649 
5650  return refhit;
5651 }
5652 
5654  int ntot = cluster->GetNofHits();
5655  // cout << "FIND REFERENCE HIT " << ntot << endl;
5656 
5657  if(ntot == 0) return NULL;
5658 
5659 
5660  int tmphitid = -1;
5661  Double_t tmpiso = 1.;
5662  PndTrkHit *refhit = NULL;
5663  for(int jhit = 0; jhit < ntot; jhit++) {
5664  PndTrkHit *hit = cluster->GetHit(jhit);
5665 
5666  // if(hit->IsUsed()) {
5667  // if(fVerbose > 1) cout << "STT hit " << jhit << "already used " << endl;
5668  // continue; }
5669 
5670  if(hit->IsStt()) {
5671  if(hit->IsSttParallel()) {
5672  if(hit->GetIsochrone() < tmpiso) {
5673  tmphitid = jhit;
5674  tmpiso = hit->GetIsochrone();
5675  refhit = hit;
5676  }
5677  }
5678  }
5679  else {
5680  tmphitid = jhit;
5681  break;
5682  }
5683  }
5684 
5685  if(tmphitid == -1) return NULL;
5686  refhit = cluster->GetHit(tmphitid);
5687  if(fVerbose > 1) cout << "REFERENCE HIT " << refhit->GetHitID() << " " << refhit->GetDetectorID() << endl;
5688  return refhit;
5689 
5690 
5691 }
5692 
5693 
5695 
5696  trasl[0] = hit->GetPosition().X();
5697  trasl[1] = hit->GetPosition().Y();
5698 
5699  delta = 0.; // TMath::ATan2(hit->GetPosition().Y() - 0., hit->GetPosition().X() - 0.); // CHECK
5700 
5701 }
5702 
5703 void PndTrkTrackFinder::ComputePlaneExtremities(PndTrkCluster *) { // cluster //[R.K.03/2017] unused variable(s)
5704  fUmin = 1000, fVmin = 1000, fRmin = 1000;
5705  fUmax = -1000, fVmax = -1000, fRmax = -1000;
5706  double rc_of_min, rc_of_max;
5707 
5708 
5709  for(int ihit = 0; ihit < fConformalHitList->GetNofHits(); ihit++) {
5711  double u = chit->GetU();
5712  double v = chit->GetV();
5713  double rc = chit->GetIsochrone();
5714  u - rc < fUmin ? fUmin = u - rc : fUmin;
5715  v - rc < fVmin ? fVmin = v - rc : fVmin;
5716  u + rc > fUmax ? fUmax = u + rc : fUmax;
5717  v + rc > fVmax ? fVmax = v + rc : fVmax;
5718 
5719  double theta1 = TMath::ATan2(v, u);
5720  double theta2 = theta1 + TMath::Pi();
5721 
5722  double r1 = u * TMath::Cos(theta1) + v * TMath::Sin(theta1);
5723  double r2 = u * TMath::Cos(theta2) + v * TMath::Sin(theta2);
5724 
5725  double rimin, rimax;
5726  r1 < r2 ? (rimin = r1, rimax = r2) : (rimin = r2, rimax = r1);
5727 
5728  rimin < fRmin ? (rc_of_min = rc, fRmin = rimin) : fRmin;
5729  rimax > fRmax ? (rc_of_max = rc, fRmax = rimax) : fRmax;
5730  }
5731 
5732  fRmin -= rc_of_min;
5733  fRmax += rc_of_max;
5734 
5735  // to square the conformal plane
5736  double du = fUmax - fUmin;
5737  double dv = fVmax - fVmin;
5738  double delta = fabs(dv - du)/2.;
5739  du < dv ? (fUmin -= delta, fUmax += delta) : (fVmin -= delta, fVmax += delta);
5740 
5741  cout << "u_min " << fUmin << " u_max " << fUmax << endl;
5742  cout << "v_min " << fVmin << " v_max " << fVmax << endl;
5743  cout << "r_min " << fRmin << " r_max " << fRmax << endl;
5744  cout << "theta_min 0 theta_max 180" << endl;
5745 
5746 
5747 }
5748 
5750 {
5751  // ---------------------------------------------------------------
5752  // cout << "FILL LEGENDRE HISTO " << cluster->GetNofHits() << endl;
5753 
5754  for(int ihit = 0; ihit < fConformalHitList->GetNofHits(); ihit++) {
5756  PndTrkHit *hit = chit->GetHit();
5757  if(cluster->DoesContain(hit) == kFALSE) continue;
5758  legendre->FillLegendreHisto(chit->GetU(), chit->GetV(), chit->GetIsochrone());
5759  if(fDisplayOn) {
5760  DrawConfHit(chit->GetU(), chit->GetV(), chit->GetIsochrone());
5761  // cout << "conformal2: " << chit->GetU() << " " << chit->GetV() << " " << chit->GetIsochrone() << endl;
5762  }
5763  }
5764 }
5765 
5767 
5768  // cout << "RESETTING LEGENDRE HISTO" << endl;
5770 
5771  if(fDisplayOn) {
5772  RefreshConf();
5774  }
5775  // cout << "%%%%%%%%%%%%%%%%%%%% XY FINDE %%%%%%%%%%%%%%%%%%%%%%%%%%" << endl;
5776  FillLegendreHisto(cluster);
5777 }
5778 
5779 Int_t PndTrkTrackFinder::ApplyLegendre(PndTrkCluster *cluster, double &theta_max, double &r_max) {
5780  RePrepareLegendre(cluster);
5781  return ExtractLegendre(1, theta_max, r_max);
5782 }
5783 
5784 
5785 
5786 Int_t PndTrkTrackFinder::ExtractLegendre(Int_t mode, double &theta_max, double &r_max) {
5787  if(fDisplayOn) {
5788  //char goOnChar; //[R.K. 01/2017] unused variable
5789  // cin >> goOnChar;
5791  // cout << "LEGENDRE (nof conf hits = " << conformalhitlist->GetNofHits() << ")" << endl;
5792  display->cd();
5793  // cin >> goOnChar;
5794  display->Update();
5795  display->Modified();
5796  }
5797 
5798  // FIND MAXIMUM IN LEGENDRE HISTO
5799 
5800  // legendre->ApplyThresholdLegendreHisto(0.3);
5801  int maxpeak = legendre->ExtractLegendreMaximum(theta_max, r_max);
5802 
5803  bool alreadythere = false;
5804  // if(mode == 0)
5805  {
5806 
5807  if(maxpeak <= 3) {
5808  if(fVerbose > 1) cout << "\033[1;31m MAXPEAK " << maxpeak << ", BREAK NOW! \033[0m" << endl;
5809  return maxpeak;
5810  }
5811 
5812  for(size_t ialready = 0; ialready < fFoundPeaks.size(); ialready++) {
5813  std::pair<double, double> foundthetar = fFoundPeaks.at(ialready);
5814  double foundtheta = foundthetar.first;
5815  double foundr = foundthetar.second;
5816  // IF THIS PEAK WAS ALREADY FOUND, DELETE THE PEAK AND GO ON (TO AVOID INFINITE LOOPS)
5817  if(theta_max == foundtheta && r_max == foundr) {
5818  legendre->DeleteZoneAroundXYLegendre(theta_max, r_max);
5819  maxpeak = legendre->ExtractLegendreMaximum(theta_max, r_max);
5820  alreadythere = true;
5821  if(fVerbose > 0) cout << "OH NO! THIS PEAK IS ALREADY THERE" << endl;
5822  return -1;
5823  }
5824  }
5825 
5826  if(alreadythere == false) {
5827  std::pair<double, double> tr(theta_max, r_max);
5828  fFoundPeaks.push_back(tr);
5829  }
5830  }
5831  // ZOOM LEGENDRE HISTO
5832  legendre->SetUpZoomHisto(theta_max, r_max, 3, 0.005);
5833  // cout << "THETA/R " << theta_max << " " << r_max << " maxpeak " << maxpeak << endl;
5834 
5835  for(int ihit = 0; ihit < fConformalHitList->GetNofHits(); ihit++) {
5837  legendre->FillZoomHisto(chit->GetU(), chit->GetV(), chit->GetIsochrone());
5838  }
5839 
5840  if(mode == 0 && alreadythere == true) {
5841  cout << "THIS PEAK IS ALREADY THERE" << endl;
5842  legendre->DeleteZoneAroundXYZoom(theta_max, r_max);
5843  }
5844 
5845  legendre->ExtractZoomMaximum(theta_max, r_max); //int maxpeakzoom = //FIXME [R.K. 01/2017] unused variable
5846  // cout << "THETA/R ZOOM " << theta_max << " " << r_max << " maxpeakzoom " << maxpeakzoom << endl;
5847 
5848  if(fDisplayOn) {
5849  //char goOnChar; //[R.K. 01/2017] unused variable
5850  display->cd(3);
5851  TMarker *mrk = new TMarker(theta_max, r_max, 29);
5852  mrk->Draw("SAME");
5853  display->cd(4);
5854  legendre->DrawZoom();
5855  mrk->Draw("SAME");
5856  display->Update();
5857  display->Modified();
5858  // cin >> goOnChar;
5859  }
5860 
5861  return maxpeak;
5862 }
5863 
5864 void PndTrkTrackFinder::FromConformalToRealTrack(double fitm, double fitp, double &x0, double &y0, double &R) {
5865  // CHECK if this needs to be kept --> change xc0 to xc etc
5866  // center and radius
5867 
5868  // cout << "conformal fit " << fitm << " " << fitp << endl;
5869 
5870  Double_t xcrot0, ycrot0;
5871  ycrot0 = 1 / (2 * fitp);
5872  xcrot0 = - fitm * ycrot0;
5873  R = sqrt(xcrot0 * xcrot0 + ycrot0 * ycrot0);
5874  // re-rotation and re-traslation of xc and yc
5875  // rotation
5878  // traslation
5881 }
5882 
5883 void PndTrkTrackFinder::FromConformalToRealTrackParabola(double fita, double fitb, double fitc, double &x0, double &y0, double &R, double &epsilon) {
5884  // CHECK if this needs to be kept --> change xc0 to xc etc
5885  // center and radius
5886 
5887  // cout << "conformal fit " << fita << " " << fitb << " " << fitc << endl;
5888 
5889  Double_t xcrot0, ycrot0;
5890 
5891  // center and radius
5892  ycrot0 = 1/(2 * fita);
5893  xcrot0 = -fitb/(2 * fita);
5894  epsilon = -fitc * pow((1+(fitb*fitb)), -3/2);
5895  R = epsilon + sqrt((xcrot0 * xcrot0)+(ycrot0 *ycrot0));
5896 
5897  // re-rotation and re-traslation of xc and yc
5898  // rotation
5901  // traslation
5904 
5905 }
5906 
5907 void PndTrkTrackFinder::FromRealToConformalTrack(double x0, double y0, double , double &fitm, double &fitp) { // R //[R.K.03/2017] unused variable(s)
5908  // CHECK if this needs to be kept --> change xc0 to xc etc
5909  Double_t xcrot0, ycrot0;
5910 
5911  // traslation
5914 
5920  // rotation
5923 
5924  // yr = 1/ (2 p) --> p = 1 / (2 yr)
5925  // xr = - m / (2 p) --> m = - 2 p xr
5926  fitp = 1 / (2 * ycrot0);
5927  fitm = - 2 * fitp * xcrot0;
5928 }
5929 
5931  TObjArray limits;
5932  TObjArray sector[6];
5933  TObjArray *neighborings = NULL;
5934 
5935 
5936  // PndTrkHit *hit, hit2;
5937  // Loop over all hits and look for:
5938  // 1 - tubes limiting sectors std::vector< int > limithit
5939  // 2 - tubes with no neighborings (will not use them) std::vector< int > standalone
5940  // 3 - tubes with only 1 neighboring (will serve as seed) std::vector< int > seeds
5941  // 4 - tubes with only 2 neighborings, one of which is on std::vector< int > candseeds
5942  // the same layer and has neighboring (will be candidate
5943  // to serve as seed, if needed)
5944  // 5 - Fill the sector std::vector according to sectors std::vector< int > sector*
5945 
5946  fHitMap->SetOwnerValue(kTRUE); // CHECK
5947  for(int ihit = 0; ihit < stthitlist->GetNofHits(); ihit++) {
5948 
5949  PndTrkHit *hit = stthitlist->GetHit(ihit);
5950  int tubeID = hit->GetTubeID();
5951  PndSttTube *tube = (PndSttTube*) fTubeArray->At(tubeID);
5952  if(tube->IsSectorLimit() == kTRUE) limits.Add(hit);
5953 
5954  neighborings = new TObjArray();
5955 
5956  for(int jhit = 0; jhit < stthitlist->GetNofHits(); jhit++) {
5957  if(ihit == jhit) continue;
5958 
5959  PndTrkHit *hit2 = stthitlist->GetHit(jhit);
5960  int tubeID2 = hit2->GetTubeID();
5961 
5962  if(tube->IsNeighboring(tubeID2) == kTRUE) neighborings->Add(hit2);
5963 
5964  }
5965 
5966  // cout << "HIT: " << hit->GetHitID() << "(tube: " << hit->GetTubeID() << ") has " << neighborings->GetEntriesFast() << " hits" << endl;
5967  // if(fDisplayOn) {
5968  // Refresh();
5969  // }
5970 
5971 
5972  fHitMap->AddNeighboringsToHit(hit, neighborings);
5973  TObjArray indiv = fHitMap->GetIndivisiblesToHit(hit);
5974  // cout << "hit " << hit->GetHitID() << "(tube: " << hit->GetTubeID() << ") has " << indiv.GetEntriesFast() << endl;
5975 
5976  // if(fDisplayOn) {
5977  // char goOnChar;
5978  // display->Update();
5979  // display->Modified();
5980  // cout << " go on?" << endl;
5981  // cin >> goOnChar;
5982  // }
5983  }
5984  // neighborings = NULL;
5985  // delete neighborings;
5986 
5987  if(fDisplayOn) {
5988  if(1 == 1) DrawLists();
5989  if(1 == 2) DrawNeighborings();
5990  // ================================================
5991  Refresh();
5992  char goOnChar;
5993  for(int ihit = 0; ihit < stthitlist->GetNofHits(); ihit++) {
5994  PndTrkHit *stthit = stthitlist->GetHit(ihit);
5995  TObjArray indiv = fHitMap->GetIndivisiblesToHit(stthit);
5996  for(int jhit = 0; jhit < indiv.GetEntriesFast(); jhit++) {
5997  //PndTrkHit *stthit2 = (PndTrkHit*) indiv.At(jhit); //[R.K. 01/2017] unused variable
5998  // stthit2->Draw(kOrange);
5999  // stthit->Draw(kOrange);
6000  }
6001  }
6002 
6003  display->Update();
6004  display->Modified();
6005  cout << " FILLHITMAP STARTING" << endl;
6006  cin >> goOnChar;
6007  display->Update();
6008  display->Modified();
6009  // ================================================
6010  }
6011  // cout << "PRINT INDIVISIBILE MAP" << endl;
6012  // fHitMap->PrintIndivisibleMap();
6013 
6014 }
6015 
6016 
6018  PndTrkClusterList clusterlist;
6019 
6020  cout << "CLUSTERIZATION <---------------" << endl;
6021 
6022  // get seeds *********************************************8
6023  TObjArray seeds = fHitMap->GetSeeds();
6024  TObjArray neighborings;
6025  int clusterizedhits = 0;
6026  // ----------------- loop over seeds
6027  for(int iseed = 0; iseed < seeds.GetEntriesFast(); iseed++) {
6028  PndTrkCluster *cluster = new PndTrkCluster();
6029  PndTrkHit *seedhit = (PndTrkHit*) seeds.At(iseed);
6030 
6031  // is it already used
6032  if(seedhit->IsUsed() == kTRUE) continue;
6033 
6034  int seedtubeID = seedhit->GetTubeID();
6035  //PndSttTube *seedtube = (PndSttTube*) fTubeArray->At(seedtubeID); //[R.K. 01/2017] unused variable?
6036  //int seedlayerID = seedtube->GetLayerID(); //[R.K. 01/2017] unused variable
6037 
6038  // add hit to cluster
6039  cluster->AddHit(seedhit);
6040 
6041  if(fDisplayOn) {
6042  display->cd(1);
6043  char goOnChar;
6044  cin >> goOnChar;
6045  cout << "SEED " << seedtubeID << endl;
6046  seedhit->Draw(kRed);
6047  display->Update();
6048  display->Modified();
6049  }
6050 
6051  // // add cluster to clusterlist
6052  // clusterlist.AddCluster(cluster);
6053 
6054  int nlastadded = 1, addedcounter = 0;
6055  // cout << "nlastadded to " << seedhit->GetHitID() << "(" << seedtubeID << ")" << " " << nlastadded << endl;
6056  // if(nlastadded == 0) continue;
6057  while(nlastadded > 0) {
6058  // loop on the last nlastadded hits to this cluster
6059  // example: add to a 5 hits cluster: 0 1 2 3 4
6060  // the hits no. 5, 6, 7
6061  // --> nlastadded = 3 & nof hits in cluster = 5 + 3 = 8
6062  // 7 6 5 = 8 - 3
6063  // here loop from hit 8 - 1 = 7 to hit 8 - 3 = 5
6064 
6065  addedcounter = 0;
6066 
6067  // cout << "@@@@@@@@@@@@@@@@@ loop on the last " << nlastadded << " hits of cluster" << endl;
6068  // for(int ihit = 0; ihit < cluster->GetNofHits(); ihit++) {
6069  // PndTrkHit *hit = cluster->GetHit(ihit);
6070  // cout << " " << hit->GetHitID() ;
6071  // }
6072  // cout << endl;
6073 
6074 
6075  int nclusterhits = cluster->GetNofHits();
6076  for(int iadded = nclusterhits - 1; iadded >= (nclusterhits - nlastadded); iadded--) {
6077  PndTrkHit *addedhit = cluster->GetHit(iadded);
6078  neighborings = fHitMap->GetNeighboringsToHit(addedhit);
6079  if(neighborings.GetEntriesFast() == 0) continue;
6080  // cout << "hit " << addedhit->GetHitID() << "(" << addedhit->GetTubeID() << ")" << " has " << neighborings->GetEntriesFast() << " neighborigns: " << endl;
6081 
6082  // loop over the neighborings and add them all
6083  for(int ineigh = 0; ineigh < neighborings.GetEntriesFast(); ineigh++)
6084  {
6085  PndTrkHit *neighhit = (PndTrkHit*) neighborings.At(ineigh);
6086  // cout << " " << neighhit->GetHitID() << "(" << neighhit->GetTubeID() << ")";
6087  if(cluster->DoesContain(neighhit) == kTRUE) {
6088  // cout << "UN-ADDED, in cluster already" << endl;
6089  continue;
6090  }
6091  cluster->AddHit(neighhit);
6092  addedcounter++;
6093  // cout << " - ADDED; ";
6094 
6095  if(fDisplayOn) {
6096  display->cd(1);
6097  char goOnChar;
6098  cin >> goOnChar;
6099  neighhit->Draw(kGreen);
6100  cout << "nof hits " << cluster->GetNofHits() << endl;
6101  // cluster->LightUp();
6102  display->Update();
6103  display->Modified();
6104  cin >> goOnChar;
6105  }
6106 
6107  }
6108 
6109 
6110  }
6111  // cout << endl;
6112  nlastadded = addedcounter;
6113  }
6114  // cout << "NEXT seed " << endl;
6115  // add cluster to clusterlist
6116  if(cluster->GetNofHits() > 3) {
6117  clusterlist.AddCluster(cluster); // CHECK
6118  clusterizedhits += cluster->GetNofHits();
6119  }
6120 
6121  }
6122 
6123  // -----------------------------------------
6124  cout << "NOF TOTAL HITS " << stthitlist->GetNofHits() << " NOF CLUSTERIZED HITS " << clusterizedhits << endl;
6125  if(stthitlist->GetNofHits() - clusterizedhits > 6) {
6126  // get candseeds *********************************************8
6127  TObjArray candseeds = fHitMap->GetCandseeds();
6128  // ----------------- loop over cand seeds
6129 
6130  cout << "we have " << candseeds.GetEntriesFast() << " canduidate seeds" << endl;
6131  for(int jseed = 0; jseed < candseeds.GetEntriesFast(); jseed++) {
6132  PndTrkCluster *cluster = new PndTrkCluster();
6133  PndTrkHit *cseedhit = (PndTrkHit*) candseeds.At(jseed);
6134 
6135  // is it already used
6136 
6137  if(fDisplayOn) {
6138  display->cd(1);
6139  char goOnChar;
6140  cin >> goOnChar;
6141  cout << "CSEED " << endl;
6142  cseedhit->Draw(kBlue);
6143  display->Update();
6144  display->Modified();
6145  }
6146 
6147 
6148  if(cseedhit->IsUsed() == kTRUE) { cout << "already" << endl ; continue; }
6149 
6150  int cseedtubeID = cseedhit->GetTubeID();
6151  //PndSttTube *cseedtube = (PndSttTube*) fTubeArray->At(cseedtubeID); //[R.K. 01/2017] unused variable?
6152  //int cseedlayerID = cseedtube->GetLayerID(); //[R.K. 01/2017] unused variable
6153 
6154  // add hit to cluster
6155  cluster->AddHit(cseedhit);
6156 
6157  if(fDisplayOn) {
6158  display->cd(1);
6159  char goOnChar;
6160  cin >> goOnChar;
6161  cout << "SEED " << cseedtubeID << endl;
6162  cseedhit->Draw(kRed);
6163  display->Update();
6164  display->Modified();
6165  }
6166 
6167  // // add cluster to clusterlist
6168  // clusterlist.AddCluster(cluster);
6169 
6170  int nlastadded = 1, addedcounter = 0;
6171  // cout << "nlastadded to " << seedhit->GetHitID() << "(" << seedtubeID << ")" << " " << nlastadded << endl;
6172  // if(nlastadded == 0) continue;
6173  while(nlastadded > 0) {
6174  // loop on the last nlastadded hits to this cluster
6175  // example: add to a 5 hits cluster: 0 1 2 3 4
6176  // the hits no. 5, 6, 7
6177  // --> nlastadded = 3 & nof hits in cluster = 5 + 3 = 8
6178  // 7 6 5 = 8 - 3
6179  // here loop from hit 8 - 1 = 7 to hit 8 - 3 = 5
6180 
6181  addedcounter = 0;
6182 
6183  // cout << "@@@@@@@@@@@@@@@@@ loop on the last " << nlastadded << " hits of cluster" << endl;
6184  // for(int ihit = 0; ihit < cluster->GetNofHits(); ihit++) {
6185  // PndTrkHit *hit = cluster->GetHit(ihit);
6186  // cout << " " << hit->GetHitID() ;
6187  // }
6188  // cout << endl;
6189 
6190 
6191  int nclusterhits = cluster->GetNofHits();
6192  for(int iadded = nclusterhits - 1; iadded >= (nclusterhits - nlastadded); iadded--) {
6193  PndTrkHit *addedhit = cluster->GetHit(iadded);
6194  neighborings = fHitMap->GetNeighboringsToHit(addedhit);
6195  if(neighborings.GetEntriesFast() == 0) continue;
6196  // cout << "hit " << addedhit->GetHitID() << "(" << addedhit->GetTubeID() << ")" << " has " << neighborings->GetEntriesFast() << " neighborigns: " << endl;
6197 
6198  // loop over the neighborings and add them all
6199  for(int ineigh = 0; ineigh < neighborings.GetEntriesFast(); ineigh++)
6200  {
6201  PndTrkHit *neighhit = (PndTrkHit*) neighborings.At(ineigh);
6202  // cout << " " << neighhit->GetHitID() << "(" << neighhit->GetTubeID() << ")";
6203  if(cluster->DoesContain(neighhit) == kTRUE) {
6204  // cout << "UN-ADDED, in cluster already" << endl;
6205  continue;
6206  }
6207  cluster->AddHit(neighhit);
6208  addedcounter++;
6209  // cout << " - ADDED; ";
6210 
6211  if(fDisplayOn) {
6212  display->cd(1);
6213  char goOnChar;
6214  cin >> goOnChar;
6215  neighhit->Draw(kGreen);
6216  cout << "nof hits " << cluster->GetNofHits() << endl;
6217  // cluster->LightUp();
6218  display->Update();
6219  display->Modified();
6220  cin >> goOnChar;
6221  }
6222 
6223  }
6224 
6225 
6226  }
6227  // cout << endl;
6228  nlastadded = addedcounter;
6229  }
6230 
6231  if(cluster->GetNofHits() > 3) {
6232  clusterlist.AddCluster(cluster); // CHECK
6233  }
6234 
6235  }
6236  }
6237  // -----------------------------------------
6238  return clusterlist;
6239 }
6240 
6241 // PndTrkClusterList PndTrkTrackFinder::CreateFullClusterization2() {
6242 // /**
6243 // PndTrkClusterList clusterlist;
6244 
6245 // // get seeds *********************************************8
6246 // TObjArray seeds = fHitMap->GetSeeds();
6247 // neighborings = NULL;
6248 // **/
6249 // }
6250 
6252  // check how many neighboring tubes each skew
6253  // tube on a layer has on that same layer
6254  // the total number of tubes on a layer minus the number
6255  // of neighboring couples gives the number of tracks:
6256  // example 1 with 3 tracks:
6257  // OOO OO OOO are tube no.: 0 1 2 3 4 5 6 7
6258  // nof tubes on the layer = 8
6259  // calculation of neighborings:
6260  // 0 <--> 1
6261  // 1 <--> 2
6262  // 3 <--> 4
6263  // 5 <--> 6
6264  // 6 <--> 7
6265  // so, nof neigboging couples = 5
6266  // Then: noftubes (8) - nofcouples (5) = 3 tracks !!OK!!
6267 
6268  int nofhitsinlay[30]; // CHECK initialize this
6269  for(int ilay = 0; ilay < 30; ilay++) nofhitsinlay[ilay] = 0;
6270  PndTrkCluster cluster;
6271  for(int ihit = 0; ihit < stthitlist->GetNofHits(); ihit++) {
6272  PndTrkHit *hit = stthitlist->GetHit(ihit);
6273  PndSttTube *tube = (PndSttTube*) fTubeArray->At(hit->GetTubeID());
6274  hit->SetSortVariable(tube->GetLayerID());
6275  nofhitsinlay[tube->GetLayerID()]++;
6276  cluster.AddHit(hit);
6277  // cout << "hit " << ihit << " " << tube->GetLayerID() << " " << nofhitsinlay[tube->GetLayerID()] << endl;
6278  }
6279  cluster.Sort();
6280 
6281  //for(int ihit = 0; ihit < cluster.GetNofHits(); ihit++) { //[R.K. 01/2017] unused variable?
6282  //PndTrkHit *hit = cluster.GetHit(ihit); //[R.K. 01/2017] unused variable?
6283  //PndSttTube *tube = (PndSttTube*) fTubeArray->At(hit->GetTubeID()); //[R.K. 01/2017] unused variable
6284  // cout << "SORTED " << ihit << " " << hit->GetHitID() << " " << tube->GetLayerID() << endl;
6285  //} //[R.K. 01/2017] unused variable?
6286 
6287  int maxnoftracks = 1;
6288  int tmplayid = -1;
6289  int counter = 0, counter1 = 0;;
6290  int isneigh = 0;
6291  // loop over cluster hits
6292  for(int ihit = 0; ihit < cluster.GetNofHits(); ihit++) {
6293  PndTrkHit *hit = cluster.GetHit(ihit);
6294  counter++;
6295 
6296  PndSttTube *tube = (PndSttTube*) fTubeArray->At(hit->GetTubeID());
6297 
6298  int layid = tube->GetLayerID();
6299  if(nofhitsinlay[layid] <= 1) continue;
6300 
6301  // new layer?
6302  if(layid != tmplayid) {
6308  isneigh = 0;
6309  tmplayid = layid;
6310  counter1 = 0;
6311  // continue; // break;
6312  }
6313  // cout << "hit " << ihit << " on layid " << layid << "/ " << nofhitsinlay[layid] << endl;
6314 
6315  // count processed hits
6316  // in this same layer
6317  counter1++;
6318 
6319  // if it is the last hit ==> all its
6320  // neighborings have already been taken
6321  // into account
6322  if(counter1 == nofhitsinlay[layid]) continue;
6323 
6324  for(int jhit = counter; jhit < counter + nofhitsinlay[layid] - counter1; jhit++) {
6325  PndTrkHit *hit2 = cluster.GetHit(jhit);
6326  int tubeid2 = hit2->GetTubeID();
6327  PndSttTube *tube2 = (PndSttTube*) fTubeArray->At(tubeid2);
6328 
6329 
6330 
6331  if(tube->GetLayerID() != tube2->GetLayerID()) cout << "ERROR" << tube->GetLayerID() << " " << tube2->GetLayerID() << endl;
6332  // cout << "compare " << ihit << "(" << hit->GetHitID() << "- " << hit->GetTubeID() << ") with " << jhit << " (" << hit2->GetHitID() << "- " << tubeid2 << ") from " << counter << " to " << counter + nofhitsinlay[layid] - 1 << endl;
6333  if(tube->IsNeighboring(tubeid2) == kTRUE) {
6334  isneigh++;
6335  // cout << "isneigh " << isneigh << endl;
6336  // // break;
6337  }
6338  }
6339 
6340  // if all the hits in the layer have been processed
6341  if(counter1 == nofhitsinlay[layid] - 1) {
6342  int noftracks = nofhitsinlay[layid] - isneigh;
6343  cout << "CLUSTER CONTAINS @ LAYER " << layid << " ACTUALLY " << nofhitsinlay[layid] << " - " << isneigh << " = " << noftracks << " TRACKS" << endl;
6344  if(noftracks > maxnoftracks) maxnoftracks = noftracks;
6345  }
6346 
6347  }
6348 
6349 
6350  cout << "THIS CLUSTER HAS A TOTAL OF " << maxnoftracks << " TRACKS" << endl;
6351  return maxnoftracks;
6352 }
6353 
6354 
6355 
6356 
6357 
6359  return CountTracksInCluster(cluster, 0);
6360 }
6361 
6362 
6364  return CountTracksInCluster(cluster, 1);
6365 }
6366 
6368  // where means:
6369  // 0 all: parallel & skewed sectors
6370  // 1: only skewed
6371 
6372  // check how many neighboring tubes each skew
6373  // tube on a layer has on that same layer
6374  // the total number of tubes on a layer minus the number
6375  // of neighboring couples gives the number of tracks:
6376  // example 1 with 3 tracks:
6377  // OOO OO OOO are tube no.: 0 1 2 3 4 5 6 7
6378  // nof tubes on the layer = 8
6379  // calculation of neighborings:
6380  // 0 <--> 1
6381  // 1 <--> 2
6382  // 3 <--> 4
6383  // 5 <--> 6
6384  // 6 <--> 7
6385  // so, nof neigboging couples = 5
6386  // Then: noftubes (8) - nofcouples (5) = 3 tracks !!OK!!
6387  cout << "COUNT TRACKS IN SKEW SECTOR" << endl;
6388  int nofhitsinlay[30]; // CHECK initialize this
6389  for(int ilay = 0; ilay < 30; ilay++) nofhitsinlay[ilay] = 0;
6390 
6391  for(int ihit = 0; ihit < cluster->GetNofHits(); ihit++) {
6392  PndTrkHit *hit = cluster->GetHit(ihit);
6393  PndSttTube *tube = (PndSttTube*) fTubeArray->At(hit->GetTubeID());
6394  hit->SetSortVariable(tube->GetLayerID());
6395  nofhitsinlay[tube->GetLayerID()]++;
6396  // cout << "hit " << ihit << " " << tube->GetLayerID() << " " << nofhitsinlay[tube->GetLayerID()] << endl;
6397 
6398  }
6399  cluster->Sort();
6400 
6401  //for(int ihit = 0; ihit < cluster->GetNofHits(); ihit++) { //[R.K. 01/2017] unused variable?
6402  //PndTrkHit *hit = cluster->GetHit(ihit); //[R.K. 01/2017] unused variable?
6403  //PndSttTube *tube = (PndSttTube*) fTubeArray->At(hit->GetTubeID()); //[R.K. 01/2017] unused variable
6404  // cout << "SORTED " << ihit << " " << hit->GetHitID() << " " << tube->GetLayerID() << endl;
6405  //} //[R.K. 01/2017] unused variable?
6406 
6407  int maxnoftracks = 1;
6408  int tmplayid = -1;
6409  int counter = 0, counter1 = 0;;
6410  int isneigh = 0;
6411  // loop over cluster hits
6412  for(int ihit = 0; ihit < cluster->GetNofHits(); ihit++) {
6413  PndTrkHit *hit = cluster->GetHit(ihit);
6414  counter++;
6415 
6416  // which sector?
6417  if(where == 1 && hit->IsSttParallel() == kTRUE) continue;
6418  PndSttTube *tube = (PndSttTube*) fTubeArray->At(hit->GetTubeID());
6419 
6420  int layid = tube->GetLayerID();
6421  if(nofhitsinlay[layid] <= 1) continue;
6422 
6423  // new layer?
6424  if(layid != tmplayid) {
6430  isneigh = 0;
6431  tmplayid = layid;
6432  counter1 = 0;
6433  // continue; // break;
6434  }
6435  // cout << "hit " << ihit << " on layid " << layid << "/ " << nofhitsinlay[layid] << endl;
6436 
6437  // count processed hits
6438  // in this same layer
6439  counter1++;
6440 
6441  // if it is the last hit ==> all its
6442  // neighborings have already been taken
6443  // into account
6444  if(counter1 == nofhitsinlay[layid]) continue;
6445 
6446  for(int jhit = counter; jhit < counter + nofhitsinlay[layid] - counter1; jhit++) {
6447  PndTrkHit *hit2 = cluster->GetHit(jhit);
6448  int tubeid2 = hit2->GetTubeID();
6449  PndSttTube *tube2 = (PndSttTube*) fTubeArray->At(tubeid2);
6450 
6451 
6452 
6453  if(tube->GetLayerID() != tube2->GetLayerID()) cout << "ERROR" << tube->GetLayerID() << " " << tube2->GetLayerID() << endl;
6454  // cout << "compare " << ihit << "(" << hit->GetHitID() << "- " << hit->GetTubeID() << ") with " << jhit << " (" << hit2->GetHitID() << "- " << tubeid2 << ") from " << counter << " to " << counter + nofhitsinlay[layid] - 1 << endl;
6455  if(tube->IsNeighboring(tubeid2) == kTRUE) {
6456  isneigh++;
6457  // cout << "isneigh " << isneigh << endl;
6458  // // break;
6459  }
6460  }
6461 
6462  // if all the hits in the layer have been processed
6463  if(counter1 == nofhitsinlay[layid] - 1) {
6464  int noftracks = nofhitsinlay[layid] - isneigh;
6465  cout << "CLUSTER CONTAINS @ LAYER " << layid << " ACTUALLY " << nofhitsinlay[layid] << " - " << isneigh << " = " << noftracks << " TRACKS" << endl;
6466  if(noftracks > maxnoftracks) maxnoftracks = noftracks;
6467  }
6468 
6469  }
6470 
6471 
6472  cout << "THIS CLUSTER HAS A TOTAL OF " << maxnoftracks << " TRACKS" << endl;
6473  return maxnoftracks;
6474 }
6475 
6476 
6478  // ================ --> TO CONFORMAL PLANE
6479  fConformalHitList = new PndTrkConformalHitList(); // CHECK
6480  // translation and rotation
6481  Int_t nchits = 0;
6482  Double_t delta = 0, trasl[2] = {0., 0.};
6483  if(fSecondary) {
6484  // translation and rotation - CHECK
6485  // cout << " REFERENCE HIT " << cluster->GetNofHits() << endl;
6486  fRefHit = FindReferenceHit(cluster);
6487  if(fRefHit == NULL) {
6488  // cout << "REFHIT " << fRefHit << endl;
6489  // Reset();
6490  return 0;
6491  }
6492  ComputeTraAndRot(fRefHit, delta, trasl);
6493  }
6494  //
6495  cout << "DELTA " << delta << " TRASL " << trasl[0] << " " << trasl[1] << endl;
6496  conform->SetOrigin(trasl[0], trasl[1], delta);
6497  nchits = FillConformalHitList(cluster);
6498 
6499  return nchits;
6500 }
6501 
6503 
6504  // cout << "APPLY LEGENDRE =======================" << endl;
6505  // cout << "nof hits " << cluster->GetNofHits() << endl;
6506 
6507  // reset the legendre histo for a new legendre fit
6509 
6510  if(fDisplayOn) {
6511  RefreshConf();
6513  }
6514 
6515  // fill legendre histo with the cluster hits
6516  FillLegendreHisto(cluster);
6517  double theta_max, r_max;
6518  // get the peak
6519  int maxpeak = ExtractLegendre(1, theta_max, r_max); // CHECK mode??
6520 
6521  if(maxpeak < 4) return NULL; // CHECK
6522  // from theta/r to line parameters in CONFORMAL plane
6523  double fitm, fitq;
6525  if(fDisplayOn) {
6526  display->cd(2);
6527  TLine *line = new TLine(-10.07, fitq + fitm * (-10.07), 10.07, fitq + fitm * (10.07));
6528  line->Draw("SAME");
6529  }
6530 
6531  // from line parameters to center/radius in REAL plane
6532  Double_t xc, yc, R;
6533  FromConformalToRealTrack(fitm, fitq, xc, yc, R);
6534  // cout << "\033[1;33m MAXPEAK " << maxpeak << " XR, YC, R: " << xc << " " << yc << " " << R << "\033[0m" << endl;
6535  // cout << "start hit " << ihit << " " << hit->GetHitID() << " " << endsecid << " " << endlayid << endl;
6536 
6537  // create a track from the cluster
6538  PndTrkTrack *track = new PndTrkTrack(cluster, xc, yc, R);
6539 
6540  return track;
6541 }
6542 
6543 
6545 
6546  double R = track->GetRadius();
6547  double xc = track->GetCenter().X();
6548  double yc = track->GetCenter().Y();
6549  double fitm, fitp;
6550  FromRealToConformalTrack(xc, yc, R, fitm, fitp);
6551 
6552 
6553  PndTrkCluster cluster = track->GetCluster();
6554 
6555  // create cluster depending on fitting
6556  double rmin = R - R * 0.05; // CHECK 5%?
6557  double rmax = R + R * 0.05; // " "
6558 
6559 
6560  if(fDisplayOn) {
6561  display->cd(1);
6562  track->Draw(kBlue);
6563 
6564  TArc *arcmin = new TArc(xc, yc, rmin);
6565  TArc *arcmax = new TArc(xc, yc, rmax);
6566 
6567  arcmin->SetFillStyle(0);
6568  arcmax->SetFillStyle(0);
6569  arcmin->SetLineColor(kGreen);
6570  arcmax->SetLineColor(kBlue);
6571 
6572  // arcmin->Draw("SAME");
6573  // arcmax->Draw("SAME");
6574 
6575  display->Update();
6576  display->Modified();
6577  char goOnChar;
6578  cout << "want to go to new cluster?" << endl;
6579  cin >> goOnChar;
6580  }
6581 
6582  // create cluster depending on fitting
6583  PndTrkCluster *thiscluster = new PndTrkCluster();
6584  int startsecid = 1000, endsecid = -1, startlayid = 1000, endlayid = -1;
6585  double totaldistanceconf = 0;//, chi2 = 0; //[R.K. 01/2017] unused variable
6586  // clean existing cluster
6587  for(int ihit = 0; ihit < cluster.GetNofHits(); ihit++) {
6588  PndTrkHit *hit = cluster.GetHit(ihit);
6589  PndTrkConformalHit chit;
6590  if(hit->IsSttParallel()) chit = conform->GetConformalSttHit(hit);
6591  else chit = conform->GetConformalHit(hit); // CHECK if skew?
6592  double distanceconf = fabs((chit.GetV() - fitm * chit.GetU() - fitp)/ TMath::Sqrt(fitm * fitm + 1));
6593 
6594 
6595  double distance = hit->GetXYDistance(TVector3(xc, yc, 0.));
6596  // cout << "distance " << distance << " " << rmin << " " << rmax << " " << distanceconf << endl;
6597  if(distance <= rmax && distance >= rmin) {
6598  thiscluster->AddHit(hit);
6599  if(fDisplayOn) {
6600  display->cd(1);
6601  // hit->DrawTube(kGreen);
6602  display->Update();
6603  display->Modified();
6604  // char goOnChar;
6605  // cout << "want to go to next hitcluster2?" << endl;
6606  // cin >> goOnChar;
6607  }
6608 
6609  PndSttTube *tube = (PndSttTube*) fTubeArray->At(hit->GetTubeID());
6610 
6611  if(tube->GetLayerID() < startlayid) startlayid = tube->GetLayerID();
6612  if(tube->GetSectorID() < startsecid) startsecid = tube->GetSectorID();
6613  if(tube->GetLayerID() > endlayid) endlayid = tube->GetLayerID();
6614  if(tube->GetSectorID() > endsecid) endsecid = tube->GetSectorID();
6615 
6616  // cout << "hit " << ihit << " " << hit->GetHitID() << " " << endsecid << " " << endlayid << endl;
6617  totaldistanceconf += distanceconf;
6618 
6619  }
6620  }
6621 
6622  //double meandistanceconf = totaldistanceconf/thiscluster->GetNofHits(); //[R.K. 01/2017] unused variable
6623 
6624 // cout << "START SECTOR " << startsecid << " END SECTOR " << endsecid << endl;
6625 // cout << "START LAYER " << startlayid << " END LAYER " << endlayid << endl;
6626 
6627  if(fDisplayOn) {
6628  display->cd(1);
6629  thiscluster->Draw(kRed);
6630  display->Update();
6631  display->Modified();
6632  char goOnChar;
6633  cout << "want to go to next cluster1?" << endl;
6634  cin >> goOnChar;
6635  }
6636 
6637 
6638  if(startlayid != 0 || endlayid != 23) {
6639  for(int ihit = 0; ihit < stthitlist->GetNofHits(); ihit++) {
6640  PndTrkHit *hit = stthitlist->GetHit(ihit);
6641  if(cluster.DoesContain(hit)) continue;
6642  PndSttTube *tube = (PndSttTube*) fTubeArray->At(hit->GetTubeID());
6643 
6644  double distance = hit->GetXYDistance(TVector3(xc, yc, 0.));
6645  if(distance <= rmax && distance >= rmin) {
6646  // cout << endl;
6647  // cout << "other sector " << tube->GetSectorID() << " " << tube->GetLayerID();
6648 
6649  if(tube->GetSectorID() == 0 || tube->GetSectorID() == 5) {
6650  if(startsecid != 5 && endsecid != 5 && startsecid != 0 && endsecid != 0) continue;
6651  }
6652  else if(fabs(tube->GetSectorID() - startsecid) > 1 && fabs(tube->GetSectorID() - endsecid) > 1) continue;
6653 
6654  if(tube->GetLayerID() > startlayid && tube->GetLayerID() < endlayid) continue;
6655  PndTrkConformalHit chit;
6656  if(hit->IsSttParallel()) chit = conform->GetConformalSttHit(hit);
6657  else chit = conform->GetConformalHit(hit); // CHECK if skew?
6658  //double distanceconf = fabs((chit.GetV() - fitm * chit.GetU() - fitp)/ TMath::Sqrt(fitm * fitm + 1)); //[R.K. 01/2017] unused variable
6659 
6660  // cout << "->distance " << distance << " (" << meandistanceconf << ") " << rmin << " " << rmax << " " << distanceconf << endl;
6661 
6662 
6663 
6664  if(fDisplayOn) {
6665  display->cd(1);
6666  // hit->DrawTube(kBlue);
6667  display->Update();
6668  display->Modified();
6669  //char goOnChar; //[R.K. 01/2017] unused variable
6670  cout << "want to go to next?" << endl;
6671  // cin >> goOnChar;
6672  }
6673 
6674  // cout << "tubeid " << hit->GetTubeID() << " " << tube->GetLayerID() << endl;
6675  thiscluster->AddHit(hit);
6676  // cout << " ***";
6677 
6678 
6679  }
6680  }
6681  }
6682  cout << endl;
6683 
6684  if(fDisplayOn) {
6685  display->cd(1);
6686  thiscluster->Draw(kRed);
6687  display->Update();
6688  display->Modified();
6689  char goOnChar;
6690  cout << "want to go to next cluster2?" << endl;
6691  cin >> goOnChar;
6692  }
6693  // ---------------------------
6694 
6695  return thiscluster;
6696 }
6697 
6698 Bool_t PndTrkTrackFinder::AnalyticalFit(PndTrkCluster *cluster, double xc, double yc, double R, double &fitm, double&fitq) {
6699 
6700 
6701  // fit with analytical chi2 -----~~~~~-----~~~~~-----~~~~~-----~~~~~-----~~~~~--
6702  fFitter->Reset();
6703  if(fDisplayOn) {
6704  display->cd(1);
6705  Refresh();
6706  }
6707  for(int ihit = 0; ihit < cluster->GetNofHits(); ihit++)
6708  {
6709  PndTrkHit *hit = cluster->GetHit(ihit);
6710  if(hit == fRefHit) continue;
6711  if(hit->IsSttSkew()) continue;
6712  if(hit->IsSttParallel()) IntersectionFinder(hit, xc, yc, R);
6713 
6716  double sigma = 1e-5 * hit->GetPosition().Perp();
6717  if(hit->IsSttParallel()) sigma = chitstt.GetIsochrone() * hit->GetPosition().Perp(); // 0.1; // CHECK
6718  if(hit->IsGem()) sigma = 0.1 * hit->GetPosition().Perp(); // CHECK
6719  if(hit->IsSciTil()) sigma = 0.5 * hit->GetPosition().Perp(); // CHECK
6720  // // if(chit.GetPosition().Mod() > 2) continue; // CHECK THIS OUT!
6721 
6722  if(TMath::IsNaN(chit.GetPosition().X())) continue; // prevents the nan of the ref hit
6723  fFitter->SetPointToFit(chit.GetPosition().X(), chit.GetPosition().Y(), sigma);
6724  // cout << "set point to fit " << chit.GetHit()->GetHitID() << " " << chit.GetHit()->GetDetectorID() << " " << chit.GetPosition().X() << " " << chit.GetPosition().Y() << " " << sigma << endl;
6725  if(fDisplayOn) {
6726  display->cd(1);
6727  TMarker *mrk = new TMarker(hit->GetPosition().X(), hit->GetPosition().Y(), 6);
6728  mrk->SetMarkerColor(kRed);
6729  mrk->Draw("SAME");
6730 
6731  display->cd(2);
6732  TMarker *mrk2 = new TMarker(chit.GetPosition().X(), chit.GetPosition().Y(), 6);
6733  mrk2->SetMarkerColor(kRed);
6734  mrk2->Draw("SAME");
6735 
6736 
6737  display->Update();
6738  display->Modified();
6739  }
6740  }
6741 
6742 
6743  fFitter->StraightLineFit(fitm, fitq);
6744 
6745  // fitq == 0 means infinite radius
6746  // fitm == 0
6747 
6748  if(fitm == 0) return kFALSE;
6749 
6750  // cout << "previous " << xc << " " << yc << " " << R << endl;
6751  FromConformalToRealTrack(fitm, fitq, xc, yc, R);
6752  // cout << "now " << xc << " " << yc << " " << R << endl;
6753 
6754  if(fDisplayOn) {
6755  display->cd(2);
6756  cout << "wanna see the line?" << endl;
6757  TLine *line = new TLine(-10.07, fitq + fitm * (-10.07), 10.07, fitq + fitm * (10.07));
6758  line->SetLineColor(2);
6759  line->Draw("SAME");
6760  char goOnChar;
6761  display->Update();
6762  display->Modified();
6763  cin >> goOnChar;
6764  }
6765 
6766  return kTRUE;
6767 
6768 
6769 
6770 
6771 }
6772 
6773 
6774 void PndTrkTrackFinder::AnalyticalFit2(PndTrkCluster *cluster, double fitm, double fitp, double &fitm2, double&fitp2) {
6775 
6776 
6777  // fit with analytical chi2 -----~~~~~-----~~~~~-----~~~~~-----~~~~~-----~~~~~--
6778  fFitter->Reset();
6779  if(fDisplayOn) {
6780  display->cd(1);
6781  Refresh();
6782  }
6783  for(int ihit = 0; ihit < cluster->GetNofHits(); ihit++)
6784  {
6785  PndTrkHit *hit = cluster->GetHit(ihit);
6786  if(hit->IsSttSkew()) continue;
6787 
6789  IntersectionFinder(&chit, fitm, fitp);
6790 
6791  double sigma = chit.GetIsochrone();
6792  fFitter->SetPointToFit(chit.GetPosition().X(), chit.GetPosition().Y(), sigma);
6793  // cout << "set point to fit " << chit.GetPosition().X() << " " << chit.GetPosition().Y() << endl;
6794  if(fDisplayOn) {
6795  display->cd(1);
6796  TMarker *mrk = new TMarker(hit->GetPosition().X(), hit->GetPosition().Y(), 6);
6797  mrk->SetMarkerColor(kRed);
6798  mrk->Draw("SAME");
6799 
6800  display->cd(2);
6801  chit.Draw(1);
6802 
6803  display->cd(2);
6804  TMarker *mrk2 = new TMarker(chit.GetPosition().X(), chit.GetPosition().Y(), 6);
6805  mrk2->SetMarkerColor(kRed);
6806  mrk2->Draw("SAME");
6807 
6808 
6809  display->Update();
6810  display->Modified();
6811  }
6812  }
6813 
6814 
6815  fFitter->StraightLineFit(fitm2, fitp2);
6816 
6817  double xc, yc, R;
6818  FromConformalToRealTrack(fitm, fitp, xc, yc, R);
6819  cout << "previous " << xc << " " << yc << " " << R << endl;
6820  FromConformalToRealTrack(fitm2, fitp2, xc, yc, R);
6821  cout << "now " << xc << " " << yc << " " << R << endl;
6822 
6823  if(fDisplayOn) {
6824  display->cd(2);
6825  cout << "wanna see the line?" << endl;
6826  TLine *line = new TLine(-10.07, fitp2 + fitm2 * (-10.07), 10.07, fitp2 + fitm2 * (10.07));
6827  line->SetLineColor(2);
6828  line->Draw("SAME");
6829 
6830  display->cd(1);
6831  TArc *aline = new TArc(xc, yc, R);
6832  aline->SetFillStyle(0);
6833  aline->SetLineColor(2);
6834  aline->Draw("SAME");
6835 
6836 
6837  char goOnChar;
6838  display->Update();
6839  display->Modified();
6840  cin >> goOnChar;
6841  }
6842 
6843 
6844 
6845 
6846 }
6847 
6848 
6849 
6850 Bool_t PndTrkTrackFinder::AnalyticalParabolaFit(PndTrkCluster *cluster, double xc, double yc, double R, double &fita, double&fitb, Double_t &fitc, Double_t &epsilon) {
6851 
6852 
6853  // fit with analytical chi2 -----~~~~~-----~~~~~-----~~~~~-----~~~~~-----~~~~~--
6854  fFitter->Reset();
6855  if(fDisplayOn) {
6856  display->cd(1);
6857  Refresh();
6858  }
6859  for(int ihit = 0; ihit < cluster->GetNofHits(); ihit++)
6860  {
6861  PndTrkHit *hit = cluster->GetHit(ihit);
6862  if(hit == fRefHit) continue;
6863  if(hit->IsSttSkew()) continue;
6864  if(hit->IsSttParallel()) IntersectionFinder(hit, xc, yc, R);
6865 
6868  double sigma = 1e-5;
6869  if(hit->IsSttParallel()) sigma = chitstt.GetIsochrone(); // 0.1; // CHECK
6870  if(hit->IsGem()) sigma = 0.1; // CHECK
6871  if(hit->IsSciTil()) sigma = 0.5; // CHECK
6872  // // if(chit.GetPosition().Mod() > 2) continue; // CHECK THIS OUT!
6873 
6874  if(TMath::IsNaN(chit.GetPosition().X())) continue; // prevents the nan of the ref hit
6875  fFitter->SetPointToFit(chit.GetPosition().X(), chit.GetPosition().Y(), sigma);
6876  // cout << "set point to fit " << chit.GetHit()->GetHitID() << " " << chit.GetHit()->GetDetectorID() << " " << chit.GetPosition().X() << " " << chit.GetPosition().Y() << " " << sigma << endl;
6877  if(fDisplayOn) {
6878  display->cd(1);
6879  TMarker *mrk = new TMarker(hit->GetPosition().X(), hit->GetPosition().Y(), 6);
6880  mrk->SetMarkerColor(kRed);
6881  mrk->Draw("SAME");
6882 
6883  display->cd(2);
6884  TMarker *mrk2 = new TMarker(chit.GetPosition().X(), chit.GetPosition().Y(), 6);
6885  mrk2->SetMarkerColor(kRed);
6886  mrk2->Draw("SAME");
6887 
6888 
6889  display->Update();
6890  display->Modified();
6891  }
6892  }
6893 
6894 
6895  fFitter->ParabolaFit(fita, fitb, fitc);
6896 
6897  // CHECK this
6898  if(fita == 0) return kFALSE;
6899 
6900  FromConformalToRealTrackParabola(fita, fitb, fitc, xc, yc, R, epsilon);
6901  // cout << "now " << xc << " " << yc << " " << R << endl;
6902 
6903 // if(fDisplayOn) {
6904 // display->cd(2);
6905 // cout << "wanna see the line?" << endl;
6906 // TLine *line = new TLine(-10.07, fitq + fitm * (-10.07), 10.07, fitq + fitm * (10.07));
6907 // line->SetLineColor(2);
6908 // line->Draw("SAME");
6909 // char goOnChar;
6910 // display->Update();
6911 // display->Modified();
6912 // cin >> goOnChar;
6913 // }
6914 
6915  return kTRUE;
6916 }
6917 
6918 
6919 
6920 void PndTrkTrackFinder::IntersectionFinder(PndTrkConformalHit *chit, double fitm, double fitp) {
6921 
6922  double xi1 = chit->GetU() + fitm * chit->GetIsochrone()/ TMath::Sqrt(fitm * fitm + 1);
6923  double yi1 = chit->GetV() - chit->GetIsochrone() / TMath::Sqrt(fitm * fitm + 1);
6924 
6925  double xi2 = chit->GetU() - fitm * chit->GetIsochrone() / TMath::Sqrt(fitm * fitm + 1);
6926  double yi2 = chit->GetV() + chit->GetIsochrone()/ TMath::Sqrt(fitm * fitm + 1);
6927 
6928  double xi = 0, yi = 0;
6929 
6930  fabs(yi1 - (fitm * xi1 + fitp)) < fabs(yi2 - (fitm * xi2 + fitp)) ? (yi = yi1, xi = xi1) : (yi = yi2, xi = xi2);
6931 
6932  chit->SetPosition(xi, yi);
6933 
6934 }
6935 
6936 void PndTrkTrackFinder::IntersectionFinder(PndTrkHit *hit, double xc, double yc, double R) {
6937 
6938  TVector2 vec(xc, yc);
6939 
6940  // tubeID CHECK added
6941  Int_t tubeID = hit->GetTubeID();
6942  PndSttTube *tube = (PndSttTube*) fTubeArray->At(tubeID);
6943 
6944  // [xp, yp] point = coordinates xy of the centre of the firing tube
6945  TVector2 point(tube->GetPosition().X(), tube->GetPosition().Y());
6946  double radius = hit->GetIsochrone();
6947 
6948  // the coordinates of the point are taken from the intersection
6949  // between the circumference from the drift time and the R radius of
6950  // curvature. -------------------------------------------------------
6951  // 2. find the intersection between the little circle and the line // R
6952  // 2.a
6953  // find the line passing throught [xc, yc] (centre of curvature) and [xp, yp] (first wire)
6954  // y = mx + q
6955  Double_t m = (point.Y() - vec.Y())/(point.X() - vec.X());
6956  Double_t q = point.Y() - m*point.X();
6957 
6958  Double_t x1 = 0, y1 = 0,
6959  x2 = 0, y2 = 0,
6960  xb1 = 0, yb1 = 0,
6961  xb2 = 0, yb2 = 0;
6962 
6963  // CHECK the vertical track
6964  if(fabs(point.X() - vec.X()) < 1e-6) {
6965 
6966  // 2.b
6967  // intersection little circle and line --> [x1, y1]
6968  // + and - refer to the 2 possible intersections
6969  // +
6970  x1 = point.X();
6971  y1 = point.Y() + sqrt(radius * radius - (x1 - point.X()) * (x1 - point.X()));
6972  // -
6973  x2 = x1;
6974  y2 = point.Y() - sqrt(radius * radius - (x2 - point.X()) * (x2 - point.X()));
6975 
6976  // 2.c intersection between line and circle
6977  // +
6978  xb1 = vec.X();
6979  yb1 = vec.Y() + sqrt(R * R - (xb1 - vec.X()) * (xb1 - vec.X()));
6980  // -
6981  xb2 = xb1;
6982  yb2 = vec.Y() - sqrt(R * R - (xb2 - vec.X()) * (xb2 - vec.X()));
6983 
6984  } // END CHECK
6985  else {
6986 
6987  // 2.b
6988  // intersection little circle and line --> [x1, y1]
6989  // + and - refer to the 2 possible intersections
6990  // +
6991  x1 = (-(m*(q - point.Y()) - point.X()) + sqrt((m*(q - point.Y()) - point.X())*(m*(q - point.Y()) - point.X()) - (m*m + 1)*((q - point.Y())*(q - point.Y()) + point.X()*point.X() - radius*radius))) / (m*m + 1);
6992  y1 = m*x1 + q;
6993  // -
6994  x2 = (-(m*(q - point.Y()) - point.X()) - sqrt((m*(q - point.Y()) - point.X())*(m*(q - point.Y()) - point.X()) - (m*m + 1)*((q - point.Y())*(q - point.Y()) + point.X()*point.X() - radius*radius))) / (m*m + 1);
6995  y2 = m*x2 + q;
6996 
6997  // 2.c intersection between line and circle
6998  // +
6999  xb1 = (-(m*(q - vec.Y()) - vec.X()) + sqrt((m*(q - vec.Y()) - vec.X())*(m*(q - vec.Y()) - vec.X()) - (m*m + 1)*((q - vec.Y())*(q - vec.Y()) + vec.X()*vec.X() - R * R))) / (m*m + 1);
7000  yb1 = m*xb1 + q;
7001  // -
7002  xb2 = (-(m*(q - vec.Y()) - vec.X()) - sqrt((m*(q - vec.Y()) - vec.X())*(m*(q - vec.Y()) - vec.X()) - (m*m + 1)*((q - vec.Y())*(q - vec.Y()) + vec.X()*vec.X() - R * R))) / (m*m + 1);
7003  yb2 = m*xb2 + q;
7004  }
7005 
7006  // calculation of the distance between [xb, yb] and [xp, yp]
7007  Double_t distb1 = sqrt((yb1 - point.Y())*(yb1 - point.Y()) + (xb1 - point.X())*(xb1 - point.X()));
7008  Double_t distb2 = sqrt((yb2 - point.Y())*(yb2 - point.Y()) + (xb2 - point.X())*(xb2 - point.X()));
7009 
7010  // choice of [xb, yb]
7011  TVector2 xyb;
7012  if(distb1 > distb2) xyb.Set(xb2, yb2);
7013  else xyb.Set(xb1, yb1);
7014 
7015  // calculation of the distance between [x, y] and [xb. yb]
7016  Double_t dist1 = sqrt((xyb.Y() - y1)*(xyb.Y() - y1) + (xyb.X() - x1)*(xyb.X() - x1));
7017  Double_t dist2 = sqrt((xyb.Y() - y2)*(xyb.Y() - y2) + (xyb.X() - x2)*(xyb.X() - x2));
7018 
7019  // choice of [x, y]
7020  TVector2 *xy;
7021  if(dist1 > dist2) xy = new TVector2(x2, y2);
7022  else xy = new TVector2(x1, y1); // <========= THIS IS THE NEW POINT to be used for the fit
7023 
7024  hit->SetPosition(TVector3(xy->X(), xy->Y(), 0.0));
7025 
7026  delete xy;
7027 }
7028 
7029 
7030 // ================================== ZFINDER
7032 
7033  double xc = track->GetCenter().X();
7034  double yc = track->GetCenter().Y();
7035  double R = track->GetRadius();
7036  PndTrkCluster skewhitlist;
7037 
7038  //double phimin = 400, phimax = -1, zmin = 1000, zmax = -1; //[R.K. 01/2017] unused variable
7039  for(int ihit = 0; ihit < stthitlist->GetNofHits(); ihit++) {
7040  PndTrkHit *hit = stthitlist->GetHit(ihit);
7041  if(hit->IsSttSkew() == kFALSE) continue;
7042 
7043  int tubeID = hit->GetTubeID();
7044  PndSttTube *tube = (PndSttTube*) fTubeArray->At(tubeID);
7045 
7046  TVector3 wireDirection = tube->GetWireDirection();
7047  Double_t halflength = tube->GetHalfLength();
7048 
7049  TVector3 first = tube->GetPosition() + wireDirection * halflength; // CHECK
7050  TVector3 second = tube->GetPosition() - wireDirection * halflength; // CHECK
7051  // if(fDisplayOn) {
7052  // char goOnChar;
7053  // display->cd(1);
7054  // TLine *l = new TLine(first.X(), first.Y(), second.X(), second.Y());
7055  // l->SetLineColor(kBlue);
7056  // l->Draw("SAME");
7057  // display->Update();
7058  // display->Modified();
7059  // cin >> goOnChar;
7060  // }
7061  // double m1 = (first - second).Y()/(first - second).X();
7062  // double q1 = first.Y() - m1 * first.X();
7063 
7064  // 1. compute intersection between the track circle and the wire
7065  TVector2 intersection1, intersection2;
7066  Int_t nofintersections = tools->ComputeSegmentCircleIntersection(TVector2(first.X(), first.Y()), TVector2(second.X(), second.Y()), xc, yc, R, intersection1, intersection2);
7067 
7068  if(nofintersections == 0) continue;
7069  if(nofintersections >= 2) {
7070  cout << "ERROR: MORE THAN 1 INTERSECTION!!" << endl;
7071  continue; // CHECK
7072  }
7073 
7074  if(fDisplayOn) {
7075  //char goOnChar; //[R.K. 01/2017] unused variable
7076  display->cd(1);
7077  TLine *l = new TLine(first.X(), first.Y(), second.X(), second.Y());
7078  l->SetLineColor(kBlue);
7079  l->Draw("SAME");
7080 
7081  TMarker *mrk = new TMarker(intersection1.X(), intersection1.Y(), 20);
7082  mrk->SetMarkerColor(kBlue);
7083  mrk->Draw("SAME");
7084 
7085  display->Update();
7086  display->Modified();
7087 
7088 
7089  // cin >> goOnChar;
7090  }
7091 
7092 
7093  // 2. find the tangent to the track in the intersection point
7094  // tangent approximation
7095  TVector2 tangent = tools->ComputeTangentInPoint(xc, yc, intersection1);
7096 
7097  // 3. rotate clockwise the tangent/point/(wire, not explicitely)
7098  // in order to have the wire parallel to the x axis;
7099  // then translate everything to have the wire ON the x axis
7100  double beta = wireDirection.Phi();
7101  if(beta < 0) beta += TMath::Pi();
7102  // ... rotate the tangent
7103  double rtx = TMath::Cos(beta) * tangent.X() + TMath::Sin(beta) * tangent.Y();
7104  double rty = TMath::Cos(beta) * tangent.Y() - TMath::Sin(beta) * tangent.X();
7105  TVector2 rottangent(rtx, rty);
7106  rottangent = rottangent.Unit();
7107  // ... rotate the point
7108  double rx = TMath::Cos(beta) * intersection1.X() + TMath::Sin(beta) * intersection1.Y();
7109  double ry = TMath::Cos(beta) * intersection1.Y() - TMath::Sin(beta) * intersection1.X();
7110 
7111  // translation
7112  Double_t deltay = ry;
7113  rty -= deltay;
7114  ry -= deltay;
7115 
7116  // rotm, rotp
7117  Double_t rotm = rottangent.Y()/rottangent.X();
7118  Double_t rotp = ry - rotm * rx;
7119 
7120  // ellipsis
7121  double a = hit->GetIsochrone() * TMath::Cos(SKEW_ANGLE); // CHECK skew angle hard coded
7122  double b = hit->GetIsochrone();
7123 
7124  // center of ellipsis
7125  Double_t x0a, x0b, y0;
7126  y0 = 0.;
7127  x0a = (-rotp + TMath::Sqrt(b * b + a * a * rotm * rotm)) / rotm;
7128  x0b = (-rotp - TMath::Sqrt(b * b + a * a * rotm * rotm)) / rotm;
7129 
7130  // intersection point
7131  double intxa = (x0a * b * b - rotm * rotp * a * a) / (b * b + rotm * rotm * a * a);
7132  double intya = rotm * intxa + rotp;
7133  double intxb = (x0b * b * b - rotm * rotp * a * a) / (b * b + rotm * rotm * a * a);
7134  double intyb = rotm * intxb + rotp;
7135 
7136  // 4. retraslate/rerotate all back to the original plane
7137  // retranslate
7138  y0 += deltay;
7139  intya += deltay;
7140  intyb += deltay;
7141 
7142  // rerotate
7143  double x0anew = TMath::Cos(beta) * x0a - TMath::Sin(beta) * y0;
7144  double y0anew = TMath::Cos(beta) * y0 + TMath::Sin(beta) * x0a;
7145  double x0bnew = TMath::Cos(beta) * x0b - TMath::Sin(beta) * y0;
7146  double y0bnew = TMath::Cos(beta) * y0 + TMath::Sin(beta) * x0b;
7147 
7148  double intxanew = TMath::Cos(beta) * intxa - TMath::Sin(beta) * intya;
7149  double intyanew = TMath::Cos(beta) * intya + TMath::Sin(beta) * intxa;
7150  double intxbnew = TMath::Cos(beta) * intxb - TMath::Sin(beta) * intyb;
7151  double intybnew = TMath::Cos(beta) * intyb + TMath::Sin(beta) * intxb;
7152 
7153  intxa = intxanew;
7154  intya = intyanew;
7155  intxb = intxbnew;
7156  intyb = intybnew;
7157 
7158  // now we have x0a, y0a, center of the 1st ellipse
7159  // and x0b, y0b, center of the 2nd ellipse
7160  x0a = x0anew;
7161  double y0a = y0anew;
7162  x0b = x0bnew;
7163  double y0b = y0bnew;
7164 
7165  if(fDisplayOn) {
7166  //char goOnChar; //[R.K. 01/2017] unused variable
7167  display->cd(1);
7168 
7169  TEllipse *ell1 = new TEllipse(x0a, y0a, a, b, 0, 360, -beta);
7170  ell1->SetFillStyle(0);
7171  ell1->SetLineColor(4);
7172  ell1->Draw("SAME");
7173  TEllipse *ell2 = new TEllipse(x0b, y0b, a, b, 0, 360, -beta);
7174  ell2->SetFillStyle(0);
7175  ell2->SetLineColor(6);
7176  ell2->Draw("SAME");
7177 
7178  TMarker *mrkinta = new TMarker(intxa, intya, 20);
7179  mrkinta->SetMarkerColor(4);
7180  mrkinta->Draw("SAME");
7181  TMarker *mrkintb = new TMarker(intxb, intyb, 20);
7182  mrkintb->SetMarkerColor(6);
7183  mrkintb->Draw("SAME");
7184  // cin >> goOnChar;
7185  }
7186 
7187  // 5. calculate z coordinate for each intersection
7188 
7189  // calculate z0a, z0b of the center of the ellipse
7190  Double_t t = ((x0a + y0a) - (first.X() + first.Y())) / ((second.X() - first.X()) + (second.Y() - first.Y()));
7191  Double_t z0a = first.Z() + (second.Z() - first.Z()) * t;
7192  // cout << "0 : calculate t, z0a " << t << " " << z0a << endl;
7193 
7194  t = ((x0b + y0b) - (first.X() + first.Y())) / ((second.X() - first.X()) + (second.Y() - first.Y()));
7195  Double_t z0b = first.Z() + (second.Z() - first.Z()) * t;
7196 
7197  TVector3 center1(x0a, y0a, z0a);
7198  TVector3 center2(x0b, y0b, z0b);
7199  // if(fDisplayOn) {
7200  // char goOnChar;
7201  // display->cd(3);
7202  // // cout << "COMPUTE Z COORDINATE" << endl;
7203  // DrawZGeometry();
7204  // TLine *linezx = new TLine(first.X(), first.Z(), second.X(), second.Z());
7205  // linezx->Draw("SAME");
7206  // TMarker *mrkza = new TMarker(x0a, z0a, 20);
7207  // mrkza->SetMarkerColor(4);
7208  // mrkza->Draw("SAME");
7209  // TMarker *mrkzb = new TMarker(x0b, z0b, 20);
7210  // mrkzb->SetMarkerColor(6);
7211  // mrkzb->Draw("SAME");
7212  // // cin >> goOnChar;
7213  // }
7214 
7215  // calculate the z of the intersection ON the ellipse (CHECK this step calculations!)
7216  double dx = intxa - x0a;
7217  double dy = intya - y0a;
7218  TVector3 dxdy(dx, dy, 0.0);
7219 
7220  TVector3 tfirst = first + dxdy;
7221  TVector3 tsecond = second + dxdy;
7222 
7223  t = ((intxa + intya) - (tfirst.X() + tfirst.Y())) / ((tsecond.X() - tfirst.X()) + (tsecond.Y() - tfirst.Y()));
7224  double intza = tfirst.Z() + (tsecond.Z() - tfirst.Z()) * t;
7225  if(fDisplayOn) {
7226  //char goOnChar; //[R.K. 01/2017] unused variable
7227  display->cd(3);
7228  TLine *linezx1 = new TLine(tfirst.X(), tfirst.Z(), tsecond.X(), tsecond.Z());
7229  linezx1->SetLineStyle(1);
7230  linezx1->Draw("SAME");
7231  TMarker *mrkza1 = new TMarker(intxa, intza, 20);
7232  mrkza1->SetMarkerColor(kBlue - 9);
7233  mrkza1->Draw("SAME");
7234  // cin >> goOnChar;
7235  }
7236 
7237  tfirst = first - dxdy;
7238  tsecond = second - dxdy;
7239 
7240  t = ((intxb + intyb) - (tfirst.X() + tfirst.Y())) / ((tsecond.X() - tfirst.X()) + (tsecond.Y() - tfirst.Y()));
7241  double intzb = tfirst.Z() + (tsecond.Z() - tfirst.Z()) * t;
7242 
7243  TVector3 fin_intersection1(intxa, intya, intza);
7244  TVector3 fin_intersection2(intxb, intyb, intzb);
7245 
7246  // if(fDisplayOn) {
7247  // char goOnChar;
7248  // display->cd(3);
7249  // TLine *linezx2 = new TLine(tfirst.X(), tfirst.Z(), tsecond.X(), tsecond.Z());
7250  // linezx2->SetLineStyle(1);
7251  // linezx2->Draw("SAME");
7252  // TMarker *mrkzb1 = new TMarker(intxb, intzb, 20);
7253  // mrkzb1->SetMarkerColor(kMagenta - 7);
7254  // mrkzb1->Draw("SAME");
7255  // // cin >> goOnChar;
7256  // }
7257  // int1.SetXYZ(intxa, intya, intza);
7258  // int2.SetXYZ(intxb, intyb, intzb);
7259  // errz = fabs(intza - intzb)/2. ;
7260 
7261  // CHECK to be changed
7262  int trackID = 1;
7263  double phi1 = track->ComputePhi(fin_intersection1);
7264  double phi2 = track->ComputePhi(fin_intersection2);
7265 
7266  PndTrkSkewHit *skewhit = new PndTrkSkewHit(*hit, trackID, center1, fin_intersection1, phi1, center2, fin_intersection2, phi2, a, b, -1, beta);
7267  // skewhit->Print();
7268  skewhitlist.AddHit(skewhit);
7269 
7270 
7271  }
7272  // cout << "PHI: " << phimin << " " << phimax << endl;
7273  // cout << "Z : " << zmin << " " << zmax << endl;
7274 
7275 
7276  return skewhitlist;
7277 }
7278 
7280 
7281 
7282  // 6. FIRST CLEANING of the track skewed associations
7283  // find most probable z - CHECK what happens if a track is very fwd peaked?
7284  // TRY WITH DELTA z = COST
7285  // cout << "##################### FIND MOST PROBABLE Z" << endl;
7286  double phimin = 400, phimax = -1, zmin = 1000, zmax = -1;
7287 
7288  for(int ihit = 0; ihit < skewhitlist->GetNofHits(); ihit++) {
7289  PndTrkSkewHit *skewhit = (PndTrkSkewHit*) skewhitlist->GetHit(ihit);
7290  if(!skewhit) continue;
7291  TVector3 fin_intersection1 = skewhit->GetIntersection1();
7292  TVector3 fin_intersection2 = skewhit->GetIntersection2();
7293 
7294  double phi1 = skewhit->GetPhi1();
7295  double phi2 = skewhit->GetPhi2();
7296 
7297  if(phi1 < phimin) phimin = phi1;
7298  if(phi2 < phimin) phimin = phi2;
7299  if(fin_intersection1.Z() < zmin) zmin = fin_intersection1.Z();
7300  if(fin_intersection2.Z() < zmin) zmin = fin_intersection2.Z();
7301 
7302  if(phi1 > phimax) phimax = phi1;
7303  if(phi2 > phimax) phimax = phi2;
7304  if(fin_intersection1.Z() > zmax) zmax = fin_intersection1.Z();
7305  if(fin_intersection2.Z() > zmax) zmax = fin_intersection2.Z();
7306  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ CHECK
7307  }
7308  // cout << "PHI: " << phimin << " " << phimax << endl;
7309  // cout << "Z : " << zmin << " " << zmax << endl;
7310 
7311  // DISPLAY ----------------------------
7312  if(fDisplayOn) {
7313  //char goOnChar; //[R.K. 01/2017] unused variable
7314  display->cd(4);
7315  phimin -= 30;
7316  phimax += 30;
7317  zmin -= 13;
7318  zmax += 13;
7319  DrawZGeometry(phimin, phimax, zmin, zmax);
7320  hzphi->SetXTitle("#phi");
7321  hzphi->SetYTitle("#z");
7322  hzphi->Draw();
7323  display->Update();
7324  display->Modified();
7325 
7326 
7327  for(int ihit = 0; ihit < skewhitlist->GetNofHits(); ihit++) {
7328  PndTrkSkewHit *skewhit = (PndTrkSkewHit*) skewhitlist->GetHit(ihit);
7329  if(!skewhit) continue;
7330 
7331  TVector3 fin_intersection1 = skewhit->GetIntersection1();
7332  TVector3 fin_intersection2 = skewhit->GetIntersection2();
7333 
7334  double phi1 = skewhit->GetPhi1();
7335  double phi2 = skewhit->GetPhi2();
7336 
7337  TLine *linezphi = new TLine(phi1, fin_intersection1.Z(), phi2, fin_intersection2.Z());
7338  // TLine *linezphi = new TLine(fin_intersection1.Z(), phi1, fin_intersection2.Z(), phi2);
7339  linezphi->SetLineStyle(1);
7340  linezphi->Draw("SAME");
7341 
7342  TMarker *mrkzphi1 = new TMarker(phi1, fin_intersection1.Z(), 20);
7343  // TMarker *mrkzphi1 = new TMarker(fin_intersection1.Z(), phi1, 20);
7344 
7345  mrkzphi1->SetMarkerColor(kBlue - 9);
7346  mrkzphi1->Draw("SAME");
7347 
7348  TMarker *mrkzphi2 = new TMarker(phi2, fin_intersection2.Z(), 20);
7349  // TMarker *mrkzphi2 = new TMarker(fin_intersection2.Z(), phi2, 20);
7350  mrkzphi2->SetMarkerColor(kMagenta - 7);
7351  mrkzphi2->Draw("SAME");
7352  }
7353  display->Update();
7354  display->Modified();
7355  // cin >> goOnChar;
7356  }
7357  // DISPLAY ----------------------------
7358 
7359  TH1F hz("hz", "z", (zmax - zmin)/10., zmin, zmax); // CHECK
7360  for(int ihit = 0; ihit < skewhitlist->GetNofHits(); ihit++) {
7361  PndTrkSkewHit *skewhit = (PndTrkSkewHit*) skewhitlist->GetHit(ihit);
7362  if(!skewhit) continue;
7363  TVector3 fin_intersection1 = skewhit->GetIntersection1();
7364  TVector3 fin_intersection2 = skewhit->GetIntersection2();
7365  hz.Fill(fin_intersection1.Z());
7366  hz.Fill(fin_intersection2.Z());
7367  }
7368  int maxbinz = hz.GetMaximumBin();
7369  double mostprobZ = hz.GetBinCenter(maxbinz);
7370  // cout << mostprobZ << endl;
7371 
7372  // delete hits too far away ..........
7373  // cout << "##################### DELETE HITS" << endl;
7374  PndTrkCluster tmpskewhitlist;
7375  for(int ihit = 0; ihit < skewhitlist->GetNofHits(); ihit++) {
7376  PndTrkSkewHit *skewhit = (PndTrkSkewHit*) skewhitlist->GetHit(ihit);
7377  if(!skewhit) continue;
7378  TVector3 fin_intersection1 = skewhit->GetIntersection1();
7379  TVector3 fin_intersection2 = skewhit->GetIntersection2();
7380  double phi1 = skewhit->GetPhi1();
7381  double phi2 = skewhit->GetPhi2();
7382 
7383  if(fabs(fin_intersection1.Z() - mostprobZ) > 30. && fabs(fin_intersection2.Z() - mostprobZ) > 30.) {
7384  // cout << "THROW AWAY " << ihit << " " << fabs(fin_intersection1.Z() - mostprobZ) << " " << fabs(fin_intersection2.Z() - mostprobZ) << endl;
7385  continue;
7386  }
7387  skewhit->SetSortVariable((phi1 + phi2)/2.);
7388  tmpskewhitlist.AddHit(skewhit);
7389  }
7390  tmpskewhitlist.Sort();
7391  return tmpskewhitlist;
7392 }
7393 
7394 
7395 void PndTrkTrackFinder::DrawZGeometry(double phimin, double phimax, double zmin, double zmax)
7396 {
7397  if(hzphi == NULL) hzphi = new TH2F("hzphi", "z - phi plane", phimax - phimin, phimin, phimax, zmax - zmin, zmin, zmax);
7398  else {
7399  hzphi->Reset();
7400  hzphi->GetXaxis()->SetLimits(phimin, phimax);
7401  hzphi->GetYaxis()->SetLimits(zmin, zmax);
7402  }
7403  display->cd(4);
7404  hzphi->Draw();
7405 
7406  display->Update();
7407  display->Modified();
7408 
7409 }
7410 
7411 
7412 Int_t PndTrkTrackFinder::RecreateHitArrays( std::map< int, std::vector< int > > &det_to_hitids) {
7413 
7414  int counter = 0;
7415  // std::map< int, std::vector< int > > det_to_hitids;
7416  for(int itrk = 0; itrk < fPrimaryTrackArray->GetEntriesFast(); itrk++) {
7417  PndTrack *pritrack = (PndTrack*) fPrimaryTrackArray->At(itrk);
7418 
7419 // if(pritrack->GetParamFirst().GetPosition().Perp() > 5) continue;
7420 // if(pritrack->GetParamFirst().GetPosition().Z() > 5) continue;
7421 // // if(pritrack->GetParamFirst().GetMomentum().Theta() * TMath::RadToDeg() < 10) continue;
7422 
7423 
7424  PndTrackCand *pricand = pritrack->GetTrackCandPtr();
7425  for (size_t ihit = 0; ihit < pricand->GetNHits(); ihit++) {
7426  PndTrackCandHit candhit = pricand->GetSortedHit(ihit);
7427  Int_t hitId = candhit.GetHitId();
7428  Int_t detId = candhit.GetDetId();
7429 
7430  std::vector< int > hitids = det_to_hitids[detId];
7431  if(std::find(hitids.begin(), hitids.end(), hitId) == hitids.end()) hitids.push_back(hitId);
7432  det_to_hitids[detId] = hitids;
7433  }
7434 
7435 
7436  // copy the track
7437  TClonesArray& clref1 = *fTrackArray;
7438  Int_t size = clref1.GetEntriesFast();
7439  PndTrack *outputtrack = new(clref1[size]) PndTrack(pritrack->GetParamFirst(), pritrack->GetParamLast(), pritrack->GetTrackCand());
7440  outputtrack->SetFlag(333);
7441 
7442  TClonesArray& clref2 = *fTrackCandArray;
7443  size = clref2.GetEntriesFast();
7444  new(clref2[size]) PndTrackCand(pritrack->GetTrackCand()); //PndTrackCand *outputtrackcand = //[R.K.03/2017] unused variable
7445  counter++;
7446  }
7447 
7461  return counter;
7462 }
7463 
7464 
7465 std::map< int, bool > PndTrkTrackFinder::PrimaryCheck(Int_t detid, std::map< int, std::vector< int > > &det_to_hitids )
7466 {
7467  std::map< int, bool > hitidTousability;
7468  std::vector< int > hits = det_to_hitids[detid];
7469 
7470  TClonesArray *array = NULL;
7471  if(detid == FairRootManager::Instance()->GetBranchId(fSttBranch)) array = fSttHitArray;
7472  else if(detid == FairRootManager::Instance()->GetBranchId(fMvdPixelBranch)) array = fMvdPixelHitArray;
7473  else if(detid == FairRootManager::Instance()->GetBranchId(fMvdStripBranch)) array = fMvdStripHitArray;
7474  else if(detid == FairRootManager::Instance()->GetBranchId(fGemBranch)) array = fGemHitArray;
7475 
7476  for(int ihit = 0; ihit < array->GetEntriesFast(); ihit++) {
7477  hitidTousability[ihit] = true;
7478  if(find(hits.begin(), hits.end(), ihit) != hits.end()) hitidTousability[ihit] = false;
7479  }
7480  return hitidTousability;
7481 }
7482 
7483 
Double_t tanl
Definition: checkhelixhit.C:63
void AddNeighboringsToHit(PndTrkHit *hit, TObjArray *hits)
TVector3 pos
Double_t z0
Definition: checkhelixhit.C:62
Double_t x0
Definition: checkhelixhit.C:70
PndTrkCluster CleanUpSkewHitList(PndTrkCluster *skewhitlist)
int fVerbose
Definition: poormantracks.C:24
PndTrkClusterList CreateFullClusterization()
Bool_t SharedAt(PndTrkCluster *cluster2, double limit)
PndTrkCluster * fIndivCluster
PndTrkConformalTransform * conform
double dy
TClonesArray * fMvdStripHitArray
void SetUpZoomHisto(double theta, double r, double deltatheta, double deltar)
Double_t GetRadius()
Definition: PndTrkTrack.h:43
void AddTCA(Int_t detID, TClonesArray *array)
PndTrkSttHitList * stthitlist
PndTrkHit * GetHitByID(int id)
double r
Definition: RiemannTest.C:14
Int_t i
Definition: run_full.C:25
__m128 m
Definition: P4_F32vec4.h:28
TTree * b
PndTrack ConvertToPndTrack()
TClonesArray * fTubeArray
Double_t GetHalfLength()
Definition: PndSttTube.cxx:99
TClonesArray * fPrimaryTrackArray
PndTrkHit * FindReferenceHit()
Double_t GetPhi1()
Definition: PndTrkSkewHit.h:37
void Draw(Color_t color=kBlack)
Double_t GetPhi()
Definition: PndTrkHit.h:67
PndTransMap * map
Definition: sim_emc_apd.C:99
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:29
int MergeTo(PndTrkCluster *cluster2)
PndTrkSttHitList * Instanciate()
Bool_t IsSciTil()
Definition: PndTrkHit.h:83
void DeleteHitAndCompress(PndTrkHit *hit)
static T Sqrt(const T &x)
Definition: PndCAMath.h:37
void AnalyticalFit2(PndTrkCluster *cluster, double fitm, double fitp, double &fitm2, double &fip2)
#define verbose
PndTrackCandHit GetSortedHit(UInt_t i)
Definition: PndTrackCand.h:54
void DrawNeighboringsToHit(PndTrkHit *hit)
PndTrkCluster GetCluster()
Definition: PndTrkTrack.h:48
void Chi2Calculation(Int_t &, Double_t *, Double_t &f, Double_t *par, Int_t)
Double_t fMvdPix_RealDistLimit
static T Sin(const T &x)
Definition: PndCAMath.h:42
PndTrkCluster * fIndivisibleHitList
Bool_t AnalyticalParabolaFit(PndTrkCluster *cluster, double xc, double yc, double R, double &fita, double &fitb, Double_t &fitc, Double_t &epsilon)
void SetTanL(double tanl)
Definition: PndTrkTrack.h:39
PndTrkHit * FindMvdReferenceHit()
TClonesArray * fMvdPixelHitArray
Double_t par[3]
PndTrkTrackList * fTrackList
TObjArray GetNeighboringsToHit(PndTrkHit *hit)
PndTrkGemHitList * gemhitlist
Double_t sigma[nsteps]
Definition: dedx_bands.C:65
void FillLegendreHisto(double x, double y, double radius)
PndTrkConformalHitList * fConformalHitList
#define NOFLAYERS
void SetPhi(Double_t phi)
Definition: PndTrkHit.h:48
Double_t GetZ0()
Definition: PndTrkTrack.h:46
int GetNofHitsInSector(int isec)
double r1
void SetSortVariable(Double_t sortvar)
Definition: PndTrkHit.h:44
PndTrkCluster * fFinalCluster
void AddNonCombiHits(Int_t detID, TClonesArray *array, std::map< int, bool > hitTousable)
void AddHit(PndTrkHit *hit)
void DrawConfHit(double x, double y, double r, int marker=2)
Bool_t IsMvdPixel()
Definition: PndTrkHit.h:75
double Y
Definition: anaLmdDigi.C:68
PndTrkHit * GetHitFromSector(int ihit, int isec)
Int_t ApplyLegendre(PndTrkCluster *cluster, double &theta_max, double &r_max)
static T Cos(const T &x)
Definition: PndCAMath.h:43
PndTrkCluster * fCluster
void SetCluster(PndTrkCluster *cluster)
Definition: PndTrkTrack.h:41
__m128 v
Definition: P4_F32vec4.h:4
PndTrkCluster * CreateClusterAroundTrack(PndTrkTrack *track)
PndTrkHit * GetHit(int index)
void DeleteZoneAroundXYLegendre(double x, double y)
PndTrkSkewHit * GetHit(int index)
TVector3 GetIntersection2()
Definition: PndTrkSkewHit.h:35
TVector2 GetCenter()
Definition: PndTrkTrack.h:44
PndTrkHit * GetHit(int index)
Bool_t IsMvdStrip()
Definition: PndTrkHit.h:76
void SetOwnerValue(Bool_t enable=kTRUE)
void AddCluster(PndTrkCluster *cluster)
int ExtractLegendreMaximum(double &theta_max, double &r_max)
Int_t GetHitID()
Definition: PndTrkHit.h:56
Double_t ComputePhi(TVector3 hit)
Bool_t IsSttParallel()
Definition: PndTrkHit.h:70
Bool_t IsMvd()
Definition: PndTrkHit.h:77
int GetLayerID()
Definition: PndSttTube.cxx:128
int isec
Definition: f_Init.h:19
Int_t GetSensorID()
Definition: PndTrkHit.h:60
void RemoveHit(PndTrkHit *hit)
Definition: PndTrkHitList.h:45
PndTrkSdsHitList * mvdpixhitlist
void ComputeCharge()
virtual InitStatus Init()
Bool_t MinuitFit(PndTrkCluster *cluster, double mstart, double qstart, double &fitm, double &fitq)
Int_t mode
Definition: autocutx.C:47
Bool_t MinuitFit2(PndTrkCluster *cluster, double xstart, double ystart, double rstart, double &xc, double &yc, double &R, double &sign)
Int_t GetCharge()
Definition: PndTrkTrack.h:57
std::map< int, bool > CombinatorialSuppression()
PndTrkCluster CreateSkewHitList(PndTrkTrack *track)
TClonesArray * fTrackCandArray
void AddHit(PndTrkConformalHit *chit)
PndTrkGemHitList * Instanciate()
PndTrkSciTHitList * Instanciate()
void SetCenter(double x, double y)
Definition: PndTrkTrack.h:37
Int_t a
Definition: anaLmdDigi.C:126
Int_t RecreateHitArrays(std::map< int, std::vector< int > > &det_to_hitids)
void FromConformalToRealTrack(double fitm, double fitp, double &x0, double &y0, double &R)
void FillLegendreHisto(PndTrkCluster *cluster)
Int_t CountTracksInCluster(PndTrkCluster *cluster)
Double_t fit_distance(float x, float y, Double_t *par)
Bool_t IsNeighboring(int tubeID)
Definition: PndSttTube.cxx:145
Int_t GetDetectorID()
Definition: PndTrkHit.h:57
#define MVDSTRIP
int counter
Definition: ZeeAnalysis.C:59
PndTrkTrack * GetTrack(Int_t index)
void Draw(Color_t color)
void DrawZGeometry(double phimin=0, double phimax=360, double zmin=-43, double zmax=113)
PndTrkSciTHitList * scithitlist
PndGeoSttPar * fSttParameters
void Clear(Option_t *="")
void AddTrack(PndTrkTrack *track)
Double_t GetPhi2()
Definition: PndTrkSkewHit.h:38
PndTrackCand GetTrackCand()
Definition: PndTrack.h:47
void SetUsedFlag(Bool_t used)
Definition: PndTrkHit.h:50
Double_t
PndTrkHit * FindMvdPixelReferenceHit()
PndTrkConformalHit * GetHit(int index)
void SetRadius(double radius)
Definition: PndTrkTrack.h:36
PndTrkConformalHit GetConformalHit(PndTrkHit *hit)
PndTrkSdsHitList * InstanciateStrip()
int ExtractZoomMaximum(double &theta_max, double &r_max)
virtual void Exec(Option_t *opt)
Double_t y0
Definition: checkhelixhit.C:71
TClonesArray * fTrackArray
void FromRealToConformalTrack(double x0, double y0, double R, double &fitm, double &fitp)
static T ATan2(const T &y, const T &x)
void Draw(Color_t color=kBlack)
void Apollonius(PndTrkCluster *cluster, std::vector< double > &X, std::vector< double > &Y, std::vector< double > &R)
TVector3 GetPosition()
Definition: PndTrkHit.h:62
PndMCTrack * track
Definition: anaLmdCluster.C:89
TVector3 GetPosition()
Definition: PndSttTube.cxx:87
void ComputeTraAndRot(PndTrkHit *hit, Double_t &delta, Double_t trasl[2])
Bool_t ParabolaFit(Double_t &fita, Double_t &fitb, Double_t &fitc)
void SetPhi2(Double_t phi2)
Definition: PndTrkSkewHit.h:41
void SetPosition(TVector3 pos)
Definition: PndTrkHit.h:47
void DrawGeometryConf(double x1, double x2, double y1, double y2)
PndTrkLegendreTransform * legendre
FairTrackParP GetParamLast()
Definition: PndTrack.h:50
TVector2 ComputeTangentInPoint(double xc, double yc, TVector2 point)
FairRuntimeDb * rtdb
Definition: hit_dirc.C:66
TFile * f
Definition: bump_analys.C:12
void FillZoomHisto(double x, double y, double radius)
void CircleBy3Points(PndTrkHit *hit1, PndTrkHit *hit2, PndTrkHit *hit3, double &X, double &Y, double &R)
TClonesArray * fGemHitArray
TClonesArray * FillTubeArray()
void Chi2Calculation2(Int_t &, Double_t *, Double_t &f, Double_t *par, Int_t)
PndTrkNeighboringMap * fHitMap
void ExtractLineParameters(double theta, double r, double &slope, double &intercept)
Double_t z
#define CTINRADIUS
Bool_t IsGem()
Definition: PndTrkHit.h:80
std::map< int, bool > PrimaryCheck(Int_t detid, std::map< int, std::vector< int > > &det_to_hitids)
void ComputePlaneExtremities(PndTrkCluster *cluster)
void SetOrigin(double x, double y, double delta)
void Draw(Color_t color=kBlack)
PndTrkCluster * fSkewCluster
friend F32vec4 fabs(const F32vec4 &a)
Definition: P4_F32vec4.h:47
PndTrkHit * FindSttReferenceHit(int isec=-1)
void AddHit(PndTrkSkewHit *shit)
PndTrkFitter * fFitter
void DrawTube(Color_t color)
Definition: PndTrkHit.cxx:178
void ExtractLegendreSingleLineParameters(double &slope, double &intercept)
#define CTOUTRADIUS
static PndGeoHandling * Instance()
void DrawHits(PndTrkHitList *hitlist)
void RePrepareLegendre(PndTrkCluster *cluster)
Bool_t IsUsed()
Definition: PndTrkHit.h:58
Double_t vote[201][1001]
double dx
GFTrack * trk
Definition: checkgenfit.C:13
double X
Definition: anaLmdDigi.C:68
Int_t ExtractLegendre(Int_t mode, double &theta_max, double &r_max)
void DeleteZoneAroundXYZoom(double x, double y)
Int_t ClusterToConformal(PndTrkCluster *cluster)
PndTrkCluster * fFinalSkewCluster
void SetPosition(double x, double y)
TClonesArray * fSciTHitArray
PndTrkSdsHitList * mvdstrhitlist
Double_t x
PndTrkTrack * LegendreFit(PndTrkCluster *cluster)
Int_t ComputeSegmentCircleIntersection(TVector2 ex1, TVector2 ex2, double xc, double yc, double R, TVector2 &intersection1, TVector2 &intersection2)
Definition: PndTrkTools.cxx:77
void Draw(Color_t color)
Definition: PndTrkHit.cxx:109
Int_t GetNofHits()
Definition: PndTrkHitList.h:43
Bool_t DoesContain(PndTrkHit *hit)
TObjArray GetIndivisiblesToHit(PndTrkHit *hit)
TVector3 GetIntersection1()
Definition: PndTrkSkewHit.h:34
std::vector< std::pair< double, double > > fFoundPeaks
Double_t GetXYDistance(PndTrkHit *fromhit)
Definition: PndTrkHit.cxx:94
PndTrkConformalTransform * GetConformalTransform()
void SetFlag(Int_t i)
Definition: PndTrack.h:38
Double_t fMvdPix_ConfDistLimit
#define PIPEDIAMETER
TClonesArray * fSttPointArray
Bool_t StraightLineFit(Double_t &fitm, Double_t &fitp)
void SetZ0(double z0)
Definition: PndTrkTrack.h:40
Bool_t IsStt()
Definition: PndTrkHit.h:72
UInt_t GetNHits() const
Definition: PndTrackCand.h:59
PndTrkConformalHit GetConformalSttHit(PndTrkHit *hit)
void IntersectionFinder(PndTrkHit *hit, double xc, double yc, double R)
void FromConformalToRealTrackParabola(double fita, double fitb, double fitc, double &x0, double &y0, double &R, double &epsilon)
ClassImp(PndAnaContFact)
PndSttMapCreator * fMapper
Double_t GetSortVariable()
Definition: PndTrkHit.h:66
TTree * t
Definition: bump_analys.C:13
int count
void Clear(Option_t *opt="")
int sign(T val)
Definition: PndCADef.h:48
void SetConformalTransform(PndTrkConformalTransform *conformal)
PndSdsMCPoint * hit
Definition: anasim.C:70
int IsSectorLimit()
Definition: PndSttTube.h:64
CbmHit * hits[nHits]
Definition: RiemannTest.C:19
Double_t y
TClonesArray * fSttHitArray
Int_t FillConformalHitList(PndTrkCluster *cluster)
Double_t GetIsochrone()
Definition: PndTrkHit.h:63
PndTrackCand * GetTrackCandPtr()
Definition: PndTrack.h:48
#define MVDPIXEL
Int_t GetHitId() const
bool IsParallel()
Definition: PndSttTube.h:66
Int_t GetNofHits()
Definition: PndTrkCluster.h:52
Double_t fMvdStr_RealDistLimit
TClonesArray * fTrkTrackArray
PndTrkGemCombinatorial * fCombiFinder
cout<<"the mcX, mcY, mcZ are "<< mcX<<","<< mcY<<","<< mcZ<< endl;vecmc.SetXYZ(mcX, mcY, mcZ);vecrc=hit-> GetPosition()
void SetPhi1(Double_t phi1)
Definition: PndTrkSkewHit.h:40
Double_t Pi
Double_t fMvdStr_ConfDistLimit
int GetSectorID()
Definition: PndSttTube.cxx:124
#define SKEW_ANGLE
int GetSector()
Definition: PndTrkHit.h:95
Int_t GetTubeID()
Definition: PndTrkHit.h:61
PndTrkHit * FindMvdStripReferenceHit()
Bool_t AnalyticalFit(PndTrkCluster *cluster, double xc, double yc, double R, double &fitm, double &fitq)
void Clear(Option_t *opt="")
Double_t R
Definition: checkhelixhit.C:61
Double_t GetTanL()
Definition: PndTrkTrack.h:45
dble_vec_t vec[12]
Definition: ranlxd.cxx:380
Int_t CountTracksInSkewSector(PndTrkCluster *cluster)
Int_t GetDetId() const
static int counter1
Definition: createSTT.C:27
TVector3 GetWireDirection()
Definition: PndSttTube.cxx:107
void Draw(Color_t color)
Bool_t IsSttSkew()
Definition: PndTrkHit.h:71
FairTrackParP GetParamFirst()
Definition: PndTrack.h:49
double r2
void ExtractLegendreMaxima(int nmaxima, std::vector< double > &theta_max, std::vector< double > &r_max, std::vector< int > &content_max)
void SetPointToFit(double x, double y, double sigma)
Double_t ComputePhiFrom(TVector3 hit, TVector3 from)
PndSdsMCPoint * point
Definition: anaLmdCluster.C:72
PndTrkSdsHitList * InstanciatePixel()