]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/AliTPCLaserTracks.cxx
fee43ab6f4f4551886a3209200806c3ad2678bcf
[u/mrichter/AliRoot.git] / TPC / AliTPCLaserTracks.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16
17 ///////////////////////////////////////////////////////////////////////////////
18 //                                                                           //
19 //  This class is a container class for the laser beam positions of          //
20 //  the TPC laser system (ALICE-INT-2002-022  v.1 ).                         //
21 //  The system consits of 6 Laser Rods, each contains four mirror bundels    //
22 //  on each side of the TPC. Each bundle has seven mirrors.                  //
23 //                                                                           //
24 //  The TPC side 0 corresponds to the "Shaft Side (A)", side 1 corresponds   //
25 //  to the "Muon Side (C)".
26 //  The laser rods are counted counter clockwise starting with the one       //
27 //  with the smalles phi angle.                                              //
28 //  The mirror bundles in one rod for each side are counted starting from    //
29 //  form the greatest z value to the smalles.                                //
30 //  The beams in each bundel are counted counter clockwise. Having all beams //
31 //  pointing downward, the first beam will be the leftmost.                  //
32 //                                                                           //
33 ///////////////////////////////////////////////////////////////////////////////
34
35 /*
36  Create File with design positions
37
38  .L AliTPCLaserTrack.cxx+
39  AliTPCLaserTracks ltracks
40  ltracks.WriteTreeDesignData()
41  TFile f("LaserTracksDesing.root");
42  TTree * tree =(TTree*)f.Get("LaserTracks");
43  
44 */
45
46 #include <Riostream.h>
47 #include <TString.h>
48 #include <TPolyLine3D.h>
49 #include <TMath.h>
50 #include <TTree.h>
51 #include <TFile.h>
52 #include <TEventList.h>
53 #include <TVector2.h>
54 #include <TVector3.h>
55 #include <TROOT.h>
56
57 #include <TGraph.h>
58
59
60 #include "AliTPCLaserTracks.h"
61
62 ////////////////////////////////////////////////////////////////////////
63 //              Class AliTPCLaserTracks
64 ////////////////////////////////////////////////////////////////////////
65
66 ClassImp(AliTPCLaserTracks)
67
68   AliTPCLaserTracks::AliTPCLaserTracks():TObject(),
69     fId(-1),
70     fSide(-1),
71     fRod(-1),
72     fBundle(-1),
73     fBeam(-1),
74     fX(0.),
75     fY(0.),
76     fZ(0.),
77     fTime(0.),
78     fPhi(0.),
79     fTheta(0.),
80     fMaxSize(0),
81     fNpoints(0),
82     fXarr(0x0),
83     fYarr(0x0),
84     fZarr(0x0)
85
86 {
87     //
88     //  AliTPCLaserTracks default constructor
89     //
90 }
91
92 //_______________________________________________________________________
93 AliTPCLaserTracks::AliTPCLaserTracks(Int_t npoints):TObject(),
94     fId(-1),
95     fSide(-1),
96     fRod(-1),
97     fBundle(-1),
98     fBeam(-1),
99     fX(0.),
100     fY(0.),
101     fZ(0.),
102     fTime(0.),
103     fPhi(0.),
104     fTheta(0.),
105     fMaxSize(0),
106     fNpoints(0),
107     fXarr(0x0),
108     fYarr(0x0),
109     fZarr(0x0)
110
111 {
112     //
113     //  AliTPCLaserTracks constructor to initialise array of points
114     //
115     fNpoints = npoints;
116     InitPoints();
117 }
118 //______________________________________________________________________
119 AliTPCLaserTracks::AliTPCLaserTracks(const AliTPCLaserTracks &param):TObject(),
120     fId(-1),
121     fSide(-1),
122     fRod(-1),
123     fBundle(-1),
124     fBeam(-1),
125     fX(0.),
126     fY(0.),
127     fZ(0.),
128     fTime(0.),
129     fPhi(0.),
130     fTheta(0.),
131     fMaxSize(0),
132     fNpoints(0),
133     fXarr(0x0),
134     fYarr(0x0),
135     fZarr(0x0)
136 {
137   //
138   // dummy
139   //
140   fPhi=param.fPhi;
141 }
142 //______________________________________________________________________
143 AliTPCLaserTracks & AliTPCLaserTracks::operator=(const AliTPCLaserTracks & param)
144 {
145   //
146   // assignment operator - dummy
147   //
148   if (this == &param) return (*this);
149
150   fPhi=param.fPhi;
151   return (*this);
152 }
153
154 //_______________________________________________________________________
155 Double_t AliTPCLaserTracks::FindBeamLength(TVector3 vF, TVector3 vP)
156 {
157     //
158     //  Find distance between mirror and the intersection between
159     //  inner and outer field cage respectively
160     //
161     //  use the pq formula to find the intersection point between
162     //  the beam and the inner and outer fieldcage cylinders
163     //  The formulae solved are
164     //
165     //                        line = zylinder
166     //  xPoint = vF.X() + n*vP.X() = r*cos(phi)
167     //  yPoint = vF.Y() + n*vP.Y() = r*sin(phi)
168     //  zPoint = vF.Y() + n*vP.Y()
169     //
170     //  get n from the first two equations, calculate x,y,zPoint
171     //
172     //  vF is the mirror position and vP the beam direction
173     Double_t r[2];  //smalles r[0] and largest r[1] pad radius
174     r[0] = 80.0;  //smalles pad radius
175     r[1] = 260.0;   //largest pad radius
176
177     Double_t fxpxfypy = vF.X()*vP.X()+vF.Y()*vP.Y();
178     Double_t px2py2   = vP.X()*vP.X()+vP.Y()*vP.Y();
179
180     for (Int_t i=0; i<2; i++){
181         Double_t rad = (fxpxfypy/px2py2)*(fxpxfypy/px2py2)-
182                       (vF.X()*vF.X()+vF.Y()*vF.Y()-r[i]*r[i])/px2py2;
183
184         if ( rad >= 0 ){
185             Double_t n1   = -(fxpxfypy)/px2py2+TMath::Sqrt(rad);
186             TVector3 vI1(vF.X()+n1*vP.X(),
187                          vF.Y()+n1*vP.Y(),
188                          vF.Z()+n1*vP.Z());
189
190             Double_t n2   = -(fxpxfypy)/px2py2-TMath::Sqrt(rad);
191             TVector3 vI2(vF.X()+n2*vP.X(),
192                          vF.Y()+n2*vP.Y(),
193                          vF.Z()+n2*vP.Z());
194
195
196             //if we cross two boarders on our way return the closer boarder
197             if ( (n1>0) && (n2>0) ) {
198                 if ( (vF-vI1).Mag() <= (vF-vI2).Mag() )
199                     return (vF-vI1).Mag();
200                 else
201                     return (vF-vI2).Mag();
202             }
203
204             if ( n1>0 )
205                 return (vF-vI1).Mag();
206
207             if ( n2>0 )
208                 return (vF-vI2).Mag();
209
210         }
211     }
212
213     return 3.4e38;  //not found!!
214 }
215
216 //_______________________________________________________________________
217 void AliTPCLaserTracks::WriteTreeDesignData()
218 {
219     //
220     //   Write a tree with the design data of the laser track positions
221     //
222
223     TFile *f = TFile::Open("LaserTracksDesing.root","recreate");
224
225     AliTPCLaserTracks *ltp = new AliTPCLaserTracks(2);
226
227     TTree *t = new TTree("LaserTracks","LaserTracks");
228     t->Branch("LaserTracks","AliTPCLaserTracks",&ltp);
229     t->AutoSave();
230
231     Double_t phiBeam[7]         = {-31.8,-16.,-9.2,2.5,9.2,16.,31.8};
232     Double_t phiRod[6]          = {40.,100.,160.,220.,280.,340.};     //-20. for the muon side
233 //    Double_t zBundleCorse[2][4] = {{10,79,163,241},{13,85,169,247}};
234     Double_t zBundleCorse[2][4] = {{241.,163.,79.,10.},{247.,169.,85.,13.}};
235     Double_t zBeamFine[7]       = {1.45,1.3,1.15,1.3,1.15,1.3,1.45};
236
237     Int_t id=0;
238     //loop over TPC side -- 0:A (Shaft) side -- 1:C (Muon) side
239     for (Int_t side=0; side<2; side++){
240         //loop over laser rods -- counterclockwise
241         for (Int_t rod=0; rod<6; rod++){
242             //center of the rod
243             TVector2 vRod;
244
245             Double_t phiRod2 = phiRod[rod]-side*20;
246             vRod.SetMagPhi(254.25,                   //center of the rod at 254.25cm
247                            TMath::DegToRad()*
248                            (phiRod2)  //-20 deg on C-Side
249                           );
250
251             //loop over bundle -- counted from large z to small z
252             for (Int_t bundle=0; bundle<4; bundle++){
253                 //center of the bundle; not yet rotated
254                 Int_t bundleS = bundle;
255                 //              if ( side == 1 ) bundleS = 4-bundle;
256                 if ( side == 1 ) bundleS = 3-bundle;
257
258                 TVector2 vBundle;
259                 vBundle.SetMagPhi(.65,
260                                   TMath::DegToRad()*
261                                 //?  TMath::Power(-1,side)*
262                                   (phiRod2+180.-90.*bundleS)
263                                  );
264
265                 //loop over beam
266                 Int_t i=0;
267                 for (Int_t beam=0; beam<7; beam++){
268                     TVector2 vBeam;
269                     if ( beam == 3 )
270                         vBeam.Set(0.,0.);
271                     else{
272                         vBeam.SetMagPhi(1.,TMath::DegToRad()*(phiRod2+i*60));
273                         i++;
274                     }
275
276                     TVector2 xyMirror = vRod+vBundle+vBeam;
277                     Double_t zMirror   = (zBundleCorse[rod%2][bundleS]+zBeamFine[beam])*TMath::Power(-1,side);
278                     TVector3 v3Mirror(xyMirror.X(),xyMirror.Y(),zMirror);
279
280                     Double_t phi      = TMath::DegToRad()*(phiRod2+180+phiBeam[beam]*TMath::Power(-1,side));
281                     Double_t theta    = TMath::DegToRad()*90;
282
283                     TVector3 v3Beam;
284                     v3Beam.SetMagThetaPhi(1,theta,phi);  //Direction Vector
285                     v3Beam.SetMagThetaPhi(FindBeamLength(v3Mirror,v3Beam), theta, phi);
286
287
288
289                     ltp->SetId(id);
290                     ltp->SetSide(side);
291                     ltp->SetRod(rod);
292                     ltp->SetBundle(bundleS);
293                     ltp->SetBeam(beam);
294
295                     ltp->SetX(xyMirror.X());
296                     ltp->SetY(xyMirror.Y());
297                     ltp->SetZ(zMirror);
298
299                     ltp->SetPhi(phi);
300                     ltp->SetTheta(theta);
301
302 //                  ltp->InitPoints(2);
303                     ltp->SetPoint(0,xyMirror.X(),xyMirror.Y(),zMirror);
304                     ltp->SetPoint(1,xyMirror.X()+v3Beam.X(),xyMirror.Y()+v3Beam.Y(),zMirror+v3Beam.Z());
305
306                     cout<< "Id: " << id
307                         << "  Side: " << side
308                         << "  Rod: " << rod
309                         << "  Bundle: " << bundleS
310                         << "  Beam: " << beam
311                         << endl;
312
313
314                     t->Fill();
315                     //delete line;
316                     id++;
317 //                  cout << "Filled!!!" << endl;
318                 }
319             }
320         }
321     }
322
323     t->Write();
324     delete f;
325 //    delete t;
326 //    delete ltp;
327 //    delete line;
328 }
329
330 //_______________________________________________________________________
331 TPolyLine3D* AliTPCLaserTracks::GetLine()
332 {
333   //
334   // Make a polilyne object oout of the points
335   //
336    if ( fNpoints ) return new TPolyLine3D(fNpoints,fXarr,fYarr,fZarr);
337
338     return 0x0;
339 }
340
341 //_______________________________________________________________________
342 TObjArray* AliTPCLaserTracks::GetLines(const Char_t* file, const Char_t *cuts)
343 {
344   //
345   // Read the input files with the laser track 
346   // Make a array of polylines for visualization
347   
348     TObjArray *array = new TObjArray;
349
350     TFile *f = TFile::Open(file,"read");
351     TTree *tree = (TTree*)f->Get("LaserTracks");
352
353     AliTPCLaserTracks *ltp = new AliTPCLaserTracks();
354 //    TEventList *evList = new TEventList("evList");
355     TEventList evList("evList");
356
357     tree->SetBranchAddress("LaserTracks",&ltp);
358
359     tree->Draw(">>evList",cuts,"goff");
360
361 //    cout << "N: " << evList.GetN() << endl;
362     gROOT->cd();
363     for (Int_t ev = 0; ev < evList.GetN(); ev++){
364 //        cout << ev << endl;
365         tree->GetEntry( evList.GetEntry(ev) );
366         array->Add(ltp->GetLine());
367     }
368 //    cout << "delte f"<< endl;
369 //    delete f;
370
371 //    cout << "evlist" << endl;
372
373     return array;
374 }
375
376 //_______________________________________________________________________
377 void AliTPCLaserTracks::InitPoints()
378 {
379     //
380     //  Init point arrays
381     //
382
383     fMaxSize = fNpoints;
384     fXarr = new Double_t[fMaxSize];
385     fYarr = new Double_t[fMaxSize];
386     fZarr = new Double_t[fMaxSize];
387 }
388
389 //_______________________________________________________________________
390 Int_t AliTPCLaserTracks::SetPoint(Int_t point, Double_t x, Double_t y, Double_t z)
391 {
392     //
393     // Set point to point arrays
394     //
395
396     if ( !fXarr || !fYarr || !fZarr ) return 1;
397     if ( point > fNpoints-1 ) return 1;
398
399     fXarr[point] = x;
400     fYarr[point] = y;
401     fZarr[point] = z;
402     return 0;
403 }
404
405 //_______________________________________________________________________
406 Int_t AliTPCLaserTracks::FindMirror(Char_t *file, Double_t x, Double_t y, Double_t z, Double_t phi)
407 {
408     //
409     //  return the id of the mirror in 'file' that maches best the given parameters
410     //
411
412     TFile *f = TFile::Open(file,"read");
413     TTree *tree = (TTree*)f->Get("LaserTracks");
414
415     AliTPCLaserTracks *ltp = new AliTPCLaserTracks();
416     TEventList evList("evList");
417
418     tree->SetBranchAddress("LaserTracks",&ltp);
419
420     TString s;
421     s = "abs(fX-"; s+= x;
422     s+= ")<3&&abs(fY-"; s+=y;
423     s+= ")<3&&abs(fZ-"; s+= z;
424     s+= ")<1.5";
425 //    s+= "&&((abs(fPhi-";s+= phi;
426 //    s+= ")<.06)||(abs(fPhi-";s+= (phi-TMath::DegToRad()*180);
427 //    s+= ")<.06))";
428     cout << s.Data() << endl;
429
430     tree->Draw(">>evList",s.Data());
431
432     Double_t dphiMin=TMath::Pi();
433     Int_t id=-1;
434
435     cout << "nev: " << evList.GetN() << endl;
436     for (Int_t i=0; i<evList.GetN(); i++){
437         tree->GetEntry( evList.GetEntry(i) );
438         Double_t dphi = TMath::Abs(ltp->GetPhi() - phi);
439         if ( dphi > TMath::DegToRad()*180 ) dphi-=TMath::DegToRad()*180;
440         if ( dphi<dphiMin ) {
441             dphiMin = dphi;
442             id = ltp->GetId();
443         }
444     }
445     delete f;
446     return id;
447 }
448
449 //_______________________________________________________________________
450 AliTPCLaserTracks::~AliTPCLaserTracks()
451 {
452     //
453     //  standard destructor
454     //
455
456 //    if ( fP ) delete fP;
457     if ( fXarr ) delete [] fXarr;
458     if ( fYarr ) delete [] fYarr;
459     if ( fZarr ) delete [] fZarr;
460 }