Correct character constantness
[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   fPhi=param.fPhi;
149   return (*this);
150 }
151
152 //_______________________________________________________________________
153 Double_t AliTPCLaserTracks::FindBeamLength(TVector3 vF, TVector3 vP)
154 {
155     //
156     //  Find distance between mirror and the intersection between
157     //  inner and outer field cage respectively
158     //
159     //  use the pq formula to find the intersection point between
160     //  the beam and the inner and outer fieldcage cylinders
161     //  The formulae solved are
162     //
163     //                        line = zylinder
164     //  xPoint = vF.X() + n*vP.X() = r*cos(phi)
165     //  yPoint = vF.Y() + n*vP.Y() = r*sin(phi)
166     //  zPoint = vF.Y() + n*vP.Y()
167     //
168     //  get n from the first two equations, calculate x,y,zPoint
169     //
170     //  vF is the mirror position and vP the beam direction
171     Double_t r[2];  //smalles r[0] and largest r[1] pad radius
172     r[0] = 80.0;  //smalles pad radius
173     r[1] = 260.0;   //largest pad radius
174
175     Double_t fxpxfypy = vF.X()*vP.X()+vF.Y()*vP.Y();
176     Double_t px2py2   = vP.X()*vP.X()+vP.Y()*vP.Y();
177
178     for (Int_t i=0; i<2; i++){
179         Double_t rad = (fxpxfypy/px2py2)*(fxpxfypy/px2py2)-
180                       (vF.X()*vF.X()+vF.Y()*vF.Y()-r[i]*r[i])/px2py2;
181
182         if ( rad >= 0 ){
183             Double_t n1   = -(fxpxfypy)/px2py2+TMath::Sqrt(rad);
184             TVector3 vI1(vF.X()+n1*vP.X(),
185                          vF.Y()+n1*vP.Y(),
186                          vF.Z()+n1*vP.Z());
187
188             Double_t n2   = -(fxpxfypy)/px2py2-TMath::Sqrt(rad);
189             TVector3 vI2(vF.X()+n2*vP.X(),
190                          vF.Y()+n2*vP.Y(),
191                          vF.Z()+n2*vP.Z());
192
193
194             //if we cross two boarders on our way return the closer boarder
195             if ( (n1>0) && (n2>0) ) {
196                 if ( (vF-vI1).Mag() <= (vF-vI2).Mag() )
197                     return (vF-vI1).Mag();
198                 else
199                     return (vF-vI2).Mag();
200             }
201
202             if ( n1>0 )
203                 return (vF-vI1).Mag();
204
205             if ( n2>0 )
206                 return (vF-vI2).Mag();
207
208         }
209     }
210
211     return 3.4e38;  //not found!!
212 }
213
214 //_______________________________________________________________________
215 void AliTPCLaserTracks::WriteTreeDesignData()
216 {
217     //
218     //   Write a tree with the design data of the laser track positions
219     //
220
221     TFile *f = TFile::Open("LaserTracksDesing.root","recreate");
222
223     AliTPCLaserTracks *ltp = new AliTPCLaserTracks(2);
224
225     TTree *t = new TTree("LaserTracks","LaserTracks");
226     t->Branch("LaserTracks","AliTPCLaserTracks",&ltp);
227     t->AutoSave();
228
229     Double_t phiBeam[7]         = {-31.8,-16.,-9.2,2.5,9.2,16.,31.8};
230     Double_t phiRod[6]          = {40.,100.,160.,220.,280.,340.};     //-20. for the muon side
231 //    Double_t zBundleCorse[2][4] = {{10,79,163,241},{13,85,169,247}};
232     Double_t zBundleCorse[2][4] = {{241.,163.,79.,10.},{247.,169.,85.,13.}};
233     Double_t zBeamFine[7]       = {1.45,1.3,1.15,1.3,1.15,1.3,1.45};
234
235     Int_t id=0;
236     //loop over TPC side -- 0:A (Shaft) side -- 1:C (Muon) side
237     for (Int_t side=0; side<2; side++){
238         //loop over laser rods -- counterclockwise
239         for (Int_t rod=0; rod<6; rod++){
240             //center of the rod
241             TVector2 vRod;
242
243             Double_t phiRod2 = phiRod[rod]-side*20;
244             vRod.SetMagPhi(254.25,                   //center of the rod at 254.25cm
245                            TMath::DegToRad()*
246                            (phiRod2)  //-20 deg on C-Side
247                           );
248
249             //loop over bundle -- counted from large z to small z
250             for (Int_t bundle=0; bundle<4; bundle++){
251                 //center of the bundle; not yet rotated
252                 Int_t bundleS = bundle;
253                 //              if ( side == 1 ) bundleS = 4-bundle;
254                 if ( side == 1 ) bundleS = 3-bundle;
255
256                 TVector2 vBundle;
257                 vBundle.SetMagPhi(.65,
258                                   TMath::DegToRad()*
259                                 //?  TMath::Power(-1,side)*
260                                   (phiRod2+180.-90.*bundleS)
261                                  );
262
263                 //loop over beam
264                 Int_t i=0;
265                 for (Int_t beam=0; beam<7; beam++){
266                     TVector2 vBeam;
267                     if ( beam == 3 )
268                         vBeam.Set(0.,0.);
269                     else{
270                         vBeam.SetMagPhi(1.,TMath::DegToRad()*(phiRod2+i*60));
271                         i++;
272                     }
273
274                     TVector2 xyMirror = vRod+vBundle+vBeam;
275                     Double_t zMirror   = (zBundleCorse[rod%2][bundleS]+zBeamFine[beam])*TMath::Power(-1,side);
276                     TVector3 v3Mirror(xyMirror.X(),xyMirror.Y(),zMirror);
277
278                     Double_t phi      = TMath::DegToRad()*(phiRod2+180+phiBeam[beam]*TMath::Power(-1,side));
279                     Double_t theta    = TMath::DegToRad()*90;
280
281                     TVector3 v3Beam;
282                     v3Beam.SetMagThetaPhi(1,theta,phi);  //Direction Vector
283                     v3Beam.SetMagThetaPhi(FindBeamLength(v3Mirror,v3Beam), theta, phi);
284
285
286
287                     ltp->SetId(id);
288                     ltp->SetSide(side);
289                     ltp->SetRod(rod);
290                     ltp->SetBundle(bundleS);
291                     ltp->SetBeam(beam);
292
293                     ltp->SetX(xyMirror.X());
294                     ltp->SetY(xyMirror.Y());
295                     ltp->SetZ(zMirror);
296
297                     ltp->SetPhi(phi);
298                     ltp->SetTheta(theta);
299
300 //                  ltp->InitPoints(2);
301                     ltp->SetPoint(0,xyMirror.X(),xyMirror.Y(),zMirror);
302                     ltp->SetPoint(1,xyMirror.X()+v3Beam.X(),xyMirror.Y()+v3Beam.Y(),zMirror+v3Beam.Z());
303
304                     cout<< "Id: " << id
305                         << "  Side: " << side
306                         << "  Rod: " << rod
307                         << "  Bundle: " << bundleS
308                         << "  Beam: " << beam
309                         << endl;
310
311
312                     t->Fill();
313                     //delete line;
314                     id++;
315 //                  cout << "Filled!!!" << endl;
316                 }
317             }
318         }
319     }
320
321     t->Write();
322     delete f;
323 //    delete t;
324 //    delete ltp;
325 //    delete line;
326 }
327
328 //_______________________________________________________________________
329 TPolyLine3D* AliTPCLaserTracks::GetLine()
330 {
331   //
332   // Make a polilyne object oout of the points
333   //
334    if ( fNpoints ) return new TPolyLine3D(fNpoints,fXarr,fYarr,fZarr);
335
336     return 0x0;
337 }
338
339 //_______________________________________________________________________
340 TObjArray* AliTPCLaserTracks::GetLines(Char_t* file, Char_t *cuts)
341 {
342   //
343   // Read the input files with the laser track 
344   // Make a array of polylines for visualization
345   
346     TObjArray *array = new TObjArray;
347
348     TFile *f = TFile::Open(file,"read");
349     TTree *tree = (TTree*)f->Get("LaserTracks");
350
351     AliTPCLaserTracks *ltp = new AliTPCLaserTracks();
352 //    TEventList *evList = new TEventList("evList");
353     TEventList evList("evList");
354
355     tree->SetBranchAddress("LaserTracks",&ltp);
356
357     tree->Draw(">>evList",cuts,"goff");
358
359 //    cout << "N: " << evList.GetN() << endl;
360     gROOT->cd();
361     for (Int_t ev = 0; ev < evList.GetN(); ev++){
362 //        cout << ev << endl;
363         tree->GetEntry( evList.GetEntry(ev) );
364         array->Add(ltp->GetLine());
365     }
366 //    cout << "delte f"<< endl;
367 //    delete f;
368
369 //    cout << "evlist" << endl;
370
371     return array;
372 }
373
374 //_______________________________________________________________________
375 void AliTPCLaserTracks::InitPoints()
376 {
377     //
378     //  Init point arrays
379     //
380
381     fMaxSize = fNpoints;
382     fXarr = new Double_t[fMaxSize];
383     fYarr = new Double_t[fMaxSize];
384     fZarr = new Double_t[fMaxSize];
385 }
386
387 //_______________________________________________________________________
388 Int_t AliTPCLaserTracks::SetPoint(Int_t point, Double_t x, Double_t y, Double_t z)
389 {
390     //
391     // Set point to point arrays
392     //
393
394     if ( !fXarr || !fYarr || !fZarr ) return 1;
395     if ( point > fNpoints-1 ) return 1;
396
397     fXarr[point] = x;
398     fYarr[point] = y;
399     fZarr[point] = z;
400     return 0;
401 }
402
403 //_______________________________________________________________________
404 Int_t AliTPCLaserTracks::FindMirror(Char_t *file, Double_t x, Double_t y, Double_t z, Double_t phi)
405 {
406     //
407     //  return the id of the mirror in 'file' that maches best the given parameters
408     //
409
410     TFile *f = TFile::Open(file,"read");
411     TTree *tree = (TTree*)f->Get("LaserTracks");
412
413     AliTPCLaserTracks *ltp = new AliTPCLaserTracks();
414     TEventList evList("evList");
415
416     tree->SetBranchAddress("LaserTracks",&ltp);
417
418     TString s;
419     s = "abs(fX-"; s+= x;
420     s+= ")<3&&abs(fY-"; s+=y;
421     s+= ")<3&&abs(fZ-"; s+= z;
422     s+= ")<1.5";
423 //    s+= "&&((abs(fPhi-";s+= phi;
424 //    s+= ")<.06)||(abs(fPhi-";s+= (phi-TMath::DegToRad()*180);
425 //    s+= ")<.06))";
426     cout << s.Data() << endl;
427
428     tree->Draw(">>evList",s.Data());
429
430     Double_t dphiMin=TMath::Pi();
431     Int_t id=-1;
432
433     cout << "nev: " << evList.GetN() << endl;
434     for (Int_t i=0; i<evList.GetN(); i++){
435         tree->GetEntry( evList.GetEntry(i) );
436         Double_t dphi = TMath::Abs(ltp->GetPhi() - phi);
437         if ( dphi > TMath::DegToRad()*180 ) dphi-=TMath::DegToRad()*180;
438         if ( dphi<dphiMin ) {
439             dphiMin = dphi;
440             id = ltp->GetId();
441         }
442     }
443     delete f;
444     return id;
445 }
446
447 //_______________________________________________________________________
448 AliTPCLaserTracks::~AliTPCLaserTracks()
449 {
450     //
451     //  standard destructor
452     //
453
454 //    if ( fP ) delete fP;
455     if ( fXarr ) delete [] fXarr;
456     if ( fYarr ) delete [] fYarr;
457     if ( fZarr ) delete [] fZarr;
458 }