er  dev
ERmuSiVertexFinder.cxx
1 #include "ERmuSiVertexFinder.h"
2 
3 #include <vector>
4 #include <iostream>
5 using namespace std;
6 
7 #include "TVector3.h"
8 #include "TMath.h"
9 #include "TMatrix.h"
10 #include "TF3.h"
11 #include "TError.h"
12 #include "Fit/BinData.h"
13 #include "Fit/Fitter.h"
14 #include "Math/WrappedMultiTF1.h"
15 
16 #include "FairRootManager.h"
17 #include "FairRunAna.h"
18 #include "FairRuntimeDb.h"
19 #include<iostream>
20 
21 #include "ERDetectorList.h"
22 #include "ERmuSiTrack.h"
23 #include "ERmuSiPoint.h"
24 
25 // ----------------------------------------------------------------------------
27  : FairTask("ER muSi vertex finding scheme")
28 {
29 }
30 // ----------------------------------------------------------------------------
31 
32 // ----------------------------------------------------------------------------
34  : FairTask("ER muSi vertex finding scheme ", verbose)
35 {
36 }
37 // ----------------------------------------------------------------------------
38 
39 // ----------------------------------------------------------------------------
41 {
42 }
43 // ----------------------------------------------------------------------------
44 
45 // ----------------------------------------------------------------------------
46 void ERmuSiVertexFinder::SetParContainers()
47 {
48  // Get run and runtime database
49  FairRunAna* run = FairRunAna::Instance();
50  if ( ! run ) Fatal("SetParContainers", "No analysis run");
51 
52  FairRuntimeDb* rtdb = run->GetRuntimeDb();
53  if ( ! rtdb ) Fatal("SetParContainers", "No runtime database");
54 }
55 // ----------------------------------------------------------------------------
56 
57 // ----------------------------------------------------------------------------
59 {
60  // Get input array
61  FairRootManager* ioman = FairRootManager::Instance();
62  if ( ! ioman ) Fatal("Init", "No FairRootManager");
63 
64  fmuSiTracks = (TClonesArray*) ioman->GetObject("muSiTrack");
65  //todo check
66 
67  // Register output array fmuSiHits
68  fmuSiVertices = new TClonesArray("ERmuSiVertex",1000);
69 
70  ioman->Register("muSiVertex", "muSi", fmuSiVertices, kTRUE);
71 
72  return kSUCCESS;
73 }
74 // -------------------------------------------------------------------------
75 
76 // ----- Public method Exec --------------------------------------------
77 void ERmuSiVertexFinder::Exec(Option_t* opt)
78 {
79  Reset();
80  std::cout << std::endl;
81  std::cout << "ERmuSiVertexFinder started:" << std::endl;
82  //Попарно ищем общий перепендикуляр к трекам
83  for(Int_t iTrack = 0; iTrack < fmuSiTracks->GetEntriesFast(); iTrack++){
84  ERmuSiTrack* track1 = (ERmuSiTrack*)fmuSiTracks->At(iTrack);
85 
86  //Фитируем трек
87  ROOT::Fit::BinData data(3,2);
88  double xx[2];
89  xx[0] = track1->Hit(0)->GetX();
90  xx[1] = track1->Hit(0)->GetY();
91  data.Add(xx,track1->Hit(0)->GetZ(), 0.001);
92  xx[0] = track1->Hit(1)->GetX();
93  xx[1] = track1->Hit(1)->GetY();
94  data.Add(xx,track1->Hit(1)->GetZ(), 0.001);
95  xx[0] = track1->Hit(2)->GetX();
96  xx[1] = track1->Hit(2)->GetY();
97  data.Add(xx,track1->Hit(2)->GetZ(), 0.001);
98 
99  TF2 * f = new TF2("f2","[0]*x + [1]*y + [2]*1");
100  f->SetParameters(2,2,2);
101  ROOT::Fit::Fitter fitter;
102  ROOT::Math::WrappedMultiTF1 wf(*f,2);
103  fitter.SetFunction(wf);
104  bool ret = fitter.Fit(data);
105  const ROOT::Fit::FitResult & res = fitter.Result();
106  //res.Print(std::cout);
107  f->SetFitResult(res);
108  //Параметры фита трека - направляющий вектор
109  TVector3 directTrack1(track1->Hit(0)->GetX()-track1->Hit(1)->GetX(),
110  track1->Hit(0)->GetY()-track1->Hit(1)->GetY(),
111  f->Eval(track1->Hit(0)->GetX(),track1->Hit(0)->GetY())
112  - f->Eval(track1->Hit(1)->GetX(),track1->Hit(1)->GetY()));
113  for(Int_t jTrack = iTrack+1; jTrack < fmuSiTracks->GetEntriesFast(); jTrack++){
114  if (iTrack == jTrack)
115  continue;
116  ERmuSiTrack* track2 = (ERmuSiTrack*)fmuSiTracks->At(jTrack);
117  //Фитируем трек
118  ROOT::Fit::BinData data2(3,2);
119  xx[0] = track2->Hit(0)->GetX();
120  xx[1] = track2->Hit(0)->GetY();
121  data2.Add(xx,track2->Hit(0)->GetZ(), 0.001);
122  xx[0] = track2->Hit(1)->GetX();
123  xx[1] = track2->Hit(1)->GetY();
124  data2.Add(xx,track2->Hit(1)->GetZ(), 0.001);
125  xx[0] = track2->Hit(2)->GetX();
126  xx[1] = track2->Hit(2)->GetY();
127  data2.Add(xx,track2->Hit(2)->GetZ(), 0.001);
128 
129  ROOT::Fit::Fitter fitter2;
130  ROOT::Math::WrappedMultiTF1 wf2(*f,3);
131  fitter2.SetFunction(wf2);
132  bool ret2 = fitter2.Fit(data2);
133  const ROOT::Fit::FitResult & res2 = fitter2.Result();
134  //res2.Print(std::cout);
135  f->SetFitResult(res2);
136  //Параметры фита трека - направляющий вектор
137  TVector3 directTrack2(track2->Hit(0)->GetX()-track2->Hit(1)->GetX(),
138  track2->Hit(0)->GetY()-track2->Hit(1)->GetY(),
139  f->Eval(track2->Hit(0)->GetX(),track2->Hit(0)->GetY())
140  - f->Eval(track2->Hit(1)->GetX(),track2->Hit(1)->GetY()));
141 
142  //Строим вектор перпендикулярный к обоим прямым
143  TVector3 p = directTrack1.Cross(directTrack2);
144 
145  //Для нахождения общего перпендикуляра записываем уравнения прямых в параметрическом виде.
146  //Разность между точками на прямых прямо пропорциональна вектору p
147  TMatrixT<double> mat(3,3);
148  mat(0,0) = directTrack1.X();
149  mat(0,1) = -directTrack2.X();
150  mat(0,2) = -p.X();
151  mat(1,0) = directTrack1.Y();
152  mat(1,1) = -directTrack2.Y();
153  mat(1,2) = -p.Y();
154  mat(2,0) = directTrack1.Z();
155  mat(2,1) = -directTrack2.Z();
156  mat(2,2) = -p.Z();
157 
158  TMatrixT<double> right(3,1);
159 
160  right(0,0) = track2->Hit(0)->GetX()-track1->Hit(0)->GetX();
161  right(1,0) = track2->Hit(0)->GetY()-track1->Hit(0)->GetY();
162  right(2,0) = track2->Hit(0)->GetZ()-track1->Hit(0)->GetZ();
163 
164  TMatrixT<double> matInv(3,3);
165  matInv = mat.Invert();
166  TMatrixT<double> lamda(3,1);
167  lamda = matInv*right;
168  TVector3 orig(track1->Hit(0)->GetX(), track1->Hit(0)->GetY(), track1->Hit(0)->GetZ());
169  TVector3 orig2(track2->Hit(0)->GetX(), track2->Hit(0)->GetY(), track2->Hit(0)->GetZ());
170  TVector3 vertex = orig + lamda(0,0)*directTrack1;
171  TVector3 vertex2 = orig2 + lamda(1,0)*directTrack2;
172  if (lamda(2,0) < fDistanceCut){
173  ERmuSiVertex* vert = AddVertex((vertex.X() + vertex2.X())/2., (vertex.Y() + vertex2.Y())/2.,(vertex.Z() + vertex2.Z())/2.);
174  vert->AddTrack(iTrack);
175  vert->AddTrack(jTrack);
176  }
177  }
178  }
179  Int_t rems = 0;
180  //merge vertices
181  for (Int_t iVert = 0; iVert < fmuSiVertices->GetEntriesFast(); iVert++){
182  ERmuSiVertex* vert1 = (ERmuSiVertex*)fmuSiVertices->At(iVert);
183  for (Int_t jVert = iVert+1; jVert < fmuSiVertices->GetEntriesFast(); jVert++){
184  ERmuSiVertex* vert2 = (ERmuSiVertex*)fmuSiVertices->At(jVert);
185  Float_t dist = TMath::Sqrt((vert2->X()-vert1->X())*(vert2->X()-vert1->X()) +
186  (vert2->Y()-vert1->Y())*(vert2->Y()-vert1->Y()) +
187  (vert2->Z()-vert1->Z())*(vert2->Z()-vert1->Z()));
188  if(dist < 0.5 ){
189  std::cout << "Vertecies merging!" << std::endl;
190  vert1->SetX((vert1->X()+vert2->X())/2.);
191  vert1->SetY((vert1->Y()+vert2->Y())/2.);
192  vert1->SetZ((vert1->Z()+vert2->Z())/2.);
193  for (Int_t iTrack = 0; iTrack < vert2->TrackNb(); iTrack++){
194  vert1->AddTrack(vert2->Track(iTrack));
195  }
196  rems++;
197  fmuSiVertices->RemoveAt(jVert);
198  }
199  fmuSiVertices->Compress();
200  }
201  }
202  std::cout << "Vertecies count: " << fmuSiVertices->GetEntriesFast() << std::endl;
203  for(Int_t iVert=0; iVert < fmuSiVertices->GetEntriesFast(); iVert++){
204  ERmuSiVertex* vert = (ERmuSiVertex*)fmuSiVertices->At(iVert);
205  std::cout << "Vertex "<< iVert << ": (" << vert->X() << "," << vert->Y() << "," << vert->Z() << ")" << std::endl;
206  }
207 }
208 //----------------------------------------------------------------------------
209 
210 //----------------------------------------------------------------------------
212 {
213  if (fmuSiVertices) {
214  fmuSiVertices->Delete();
215  }
216 }
217 // ----------------------------------------------------------------------------
218 
219 // ----------------------------------------------------------------------------
221 {
222 
223 }
224 //----------------------------------------------------------------------------
225 
226 //----------------------------------------------------------------------------
227 ERmuSiVertex* ERmuSiVertexFinder::AddVertex(Float_t x, Float_t y, Float_t z){
228  ERmuSiVertex *vertex = new((*fmuSiVertices)[fmuSiVertices->GetEntriesFast()])
229  ERmuSiVertex(x,y,z);
230  return vertex;
231 }
232 //----------------------------------------------------------------------------
233 
234 //-----------------------------------------------------------------------------
235 ClassImp(ERmuSiVertexFinder)
virtual void Exec(Option_t *opt)
virtual InitStatus Init()
TClonesArray * fmuSiTracks