1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 ///////////////////////////////////////////////////////////////////////////////
19 // Class to make a internal alignemnt of TPC chambers //
21 // Requierements - Warnings:
22 // 1. Before using this componenent the magnetic filed has to be set properly //
23 // 2. The systematic effects - unlinearities has to be understood
25 // If systematic and unlinearities are not under control
26 // the alignment is just effective alignment. Not second order corrction
29 // The histograming of the edge effects and unlineratities integral part
30 // of the component (currently only in debug stream)
32 // 3 general type of linear transformation investigated (see bellow)
34 // By default only 6 parameter alignment to be used - other just for QA purposes
36 // Different linear tranformation investigated
37 // 12 parameters - arbitrary linear transformation
38 // a00 a01 a02 a03 p[0] p[1] p[2] p[9]
39 // a10 a11 a12 a13 ==> p[3] p[4] p[5] p[10]
40 // a20 a21 a22 a23 p[6] p[7] p[8] p[11]
42 // 9 parameters - scaling fixed to 1
43 // a00 a01 a02 a03 1 p[0] p[1] p[6]
44 // a10 a11 a12 a13 ==> p[2] 1 p[3] p[7]
45 // a20 a21 a22 a23 p[4] p[5] 1 p[8]
47 // 6 parameters - x-y rotation x-z, y-z tiliting
48 // a00 a01 a02 a03 1 -p[0] 0 p[3]
49 // a10 a11 a12 a13 ==> p[0] 1 0 p[4]
50 // a20 a21 a22 a23 p[1] p[2] 1 p[5]
53 // Debug stream supported
54 // 0. Align - The main output of the Alignment component
55 // - Used for visualization of the misalignment between sectors
56 // - Results of the missalignment fit and the mean and sigmas of histograms
58 // 1. Tracklet - StreamLevel >1
59 // - Dump all information about tracklet match from sector1 to sector 2
60 // - Default histogram residulas created in parallel
61 // - Check this streamer in case of suspicious content of these histograms
62 // 2. Track - StreamLevel>5
63 // - For debugging of the edge effects
64 // - All information - extrapolation inside of one sectors
65 // - Created in order to distinguish between unlinearities inside of o
66 // sector and missalignment
71 gSystem->AddIncludePath("-I$ALICE_ROOT/TPC/macros");
72 gROOT->LoadMacro("$ALICE_ROOT/TPC/macros/AliXRDPROOFtoolkit.cxx+")
73 AliXRDPROOFtoolkit tool;
74 TChain * chain = tool.MakeChain("align.txt","Track",0,10200);
76 TCut cutA("abs(tp1.fP[1]-tp2.fP[1])<0.3&&abs(tp1.fP[0]-tp2.fP[0])<0.15&&abs(tp1.fP[3]-tp2.fP[3])<0.01&&abs(tp1.fP[2]-tp2.fP[2])<0.01");
77 TCut cutS("s1%36==s2%36");
80 .x $ALICE_ROOT/macros/loadlibsREC.C
82 gSystem->Load("$ROOTSYS/lib/libXrdClient.so");
83 gSystem->Load("libProof");
84 gSystem->Load("libANALYSIS");
85 gSystem->Load("libSTAT");
86 gSystem->Load("libTPCcalib");
89 TFile fcalib("CalibObjects.root");
90 TObjArray * array = (TObjArray*)fcalib.Get("TPCCalib");
92 AliTPCcalibAlign * align = ( AliTPCcalibAlign *)array->FindObject("alignTPC");
96 align->MakeTree("alignTree.root");
97 TFile falignTree("alignTree.root");
98 TTree * treeAlign = (TTree*)falignTree.Get("Align");
106 #include "TLinearFitter.h"
107 #include "AliTPCcalibAlign.h"
108 #include "AliExternalTrackParam.h"
109 #include "AliTPCTracklet.h"
112 #include "TVectorD.h"
113 #include "TTreeStream.h"
117 #include "TGraphErrors.h"
118 #include "AliTPCclusterMI.h"
119 #include "AliTPCseed.h"
120 #include "AliTracker.h"
121 #include "TClonesArray.h"
122 #include "AliExternalComparison.h"
125 #include "TTreeStream.h"
130 AliTPCcalibAlign* AliTPCcalibAlign::fgInstance = 0;
131 ClassImp(AliTPCcalibAlign)
136 AliTPCcalibAlign* AliTPCcalibAlign::Instance()
139 // Singleton implementation
140 // Returns an instance of this class, it is created if neccessary
142 if (fgInstance == 0){
143 fgInstance = new AliTPCcalibAlign();
151 AliTPCcalibAlign::AliTPCcalibAlign()
153 fDphiHistArray(72*72),
154 fDthetaHistArray(72*72),
158 fDyPhiHistArray(72*72), // array of residual histograms y -kYPhi
159 fDzThetaHistArray(72*72), // array of residual histograms z-z -kZTheta
160 fDphiZHistArray(72*72), // array of residual histograms phi -kPhiz
161 fDthetaZHistArray(72*72), // array of residual histograms theta -kThetaz
162 fDyZHistArray(72*72), // array of residual histograms y -kYz
163 fDzZHistArray(72*72), // array of residual histograms z -kZz
164 fFitterArray12(72*72),
165 fFitterArray9(72*72),
166 fFitterArray6(72*72),
167 fMatrixArray12(72*72),
168 fMatrixArray9(72*72),
169 fMatrixArray6(72*72),
170 fCombinedMatrixArray6(72),
171 fCompTracklet(0), // tracklet comparison
177 for (Int_t i=0;i<72*72;++i) {
182 AliTPCcalibAlign::AliTPCcalibAlign(const Text_t *name, const Text_t *title)
184 fDphiHistArray(72*72),
185 fDthetaHistArray(72*72),
188 fDyPhiHistArray(72*72), // array of residual histograms y -kYPhi
189 fDzThetaHistArray(72*72), // array of residual histograms z-z -kZTheta
190 fDphiZHistArray(72*72), // array of residual histograms phi -kPhiz
191 fDthetaZHistArray(72*72), // array of residual histograms theta -kThetaz
192 fDyZHistArray(72*72), // array of residual histograms y -kYz
193 fDzZHistArray(72*72), // array of residual histograms z -kZz //
194 fFitterArray12(72*72),
195 fFitterArray9(72*72),
196 fFitterArray6(72*72),
197 fMatrixArray12(72*72),
198 fMatrixArray9(72*72),
199 fMatrixArray6(72*72),
200 fCombinedMatrixArray6(72),
201 fCompTracklet(0), // tracklet comparison
209 for (Int_t i=0;i<72*72;++i) {
215 AliTPCcalibAlign::AliTPCcalibAlign(const AliTPCcalibAlign &align)
216 :AliTPCcalibBase(align),
217 fDphiHistArray(align.fDphiHistArray),
218 fDthetaHistArray(align.fDthetaHistArray),
219 fDyHistArray(align.fDyHistArray),
220 fDzHistArray(align.fDzHistArray),
221 fDyPhiHistArray(align.fDyPhiHistArray), // array of residual histograms y -kYPhi
222 fDzThetaHistArray(align.fDzThetaHistArray), // array of residual histograms z-z -kZTheta
223 fDphiZHistArray(align.fDphiZHistArray), // array of residual histograms phi -kPhiz
224 fDthetaZHistArray(align.fDthetaZHistArray), // array of residual histograms theta -kThetaz
225 fDyZHistArray(align.fDyZHistArray), // array of residual histograms y -kYz
226 fDzZHistArray(align.fDzZHistArray), // array of residual histograms z -kZz
228 fFitterArray12(align.fFitterArray12),
229 fFitterArray9(align.fFitterArray9),
230 fFitterArray6(align.fFitterArray6),
232 fMatrixArray12(align.fMatrixArray12),
233 fMatrixArray9(align.fMatrixArray9),
234 fMatrixArray6(align.fMatrixArray6),
235 fCombinedMatrixArray6(align.fCombinedMatrixArray6),
236 fCompTracklet(align.fCompTracklet), // tracklet comparison
237 fNoField(align.fNoField)
240 // copy constructor - copy also the content
244 const TObjArray *arr1=0;
245 for (Int_t index =0; index<72*72; index++){
246 for (Int_t iarray=0;iarray<10; iarray++){
248 arr0 = &fDyHistArray;
249 arr1 = &align.fDyHistArray;
252 arr0 = &fDzHistArray;
253 arr1 = &align.fDzHistArray;
256 arr0 = &fDphiHistArray;
257 arr1 = &align.fDphiHistArray;
260 arr0 = &fDthetaHistArray;
261 arr1 = &align.fDthetaHistArray;
264 arr0 = &fDyZHistArray;
265 arr1 = &align.fDyZHistArray;
268 arr0 = &fDzZHistArray;
269 arr1 = &align.fDzZHistArray;
272 arr0 = &fDphiZHistArray;
273 arr1 = &align.fDphiZHistArray;
275 if (iarray==kThetaZ){
276 arr0 = &fDthetaZHistArray;
277 arr1 = &align.fDthetaZHistArray;
281 arr0 = &fDyPhiHistArray;
282 arr1 = &align.fDyPhiHistArray;
284 if (iarray==kZTheta){
285 arr0 = &fDzThetaHistArray;
286 arr1 = &align.fDzThetaHistArray;
289 if (arr1->At(index)) {
290 his = (TH1*)arr1->At(index)->Clone();
291 his->SetDirectory(0);
292 arr0->AddAt(his,index);
299 AliTPCcalibAlign::~AliTPCcalibAlign() {
305 void AliTPCcalibAlign::Process(AliTPCseed *seed) {
311 AliTPCTracklet::CreateTracklets(seed,AliTPCTracklet::kKalman,
313 // TObjArray trackletsL=
314 // AliTPCTracklet::CreateTracklets(seed,AliTPCTracklet::kLinear,
316 // TObjArray trackletsQ=
317 // AliTPCTracklet::CreateTracklets(seed,AliTPCTracklet::kQuadratic,
319 // TObjArray trackletsR=
320 // AliTPCTracklet::CreateTracklets(seed,AliTPCTracklet::kRiemann,
322 tracklets.SetOwner();
323 // trackletsL.SetOwner();
324 // trackletsQ.SetOwner();
325 // trackletsR.SetOwner();
326 if (tracklets.GetEntries()==2) {
327 AliTPCTracklet *t1=static_cast<AliTPCTracklet*>(tracklets[0]);
328 AliTPCTracklet *t2=static_cast<AliTPCTracklet*>(tracklets[1]);
329 if (t1->GetSector()>t2->GetSector()) {
330 AliTPCTracklet* tmp=t1;
334 AliExternalTrackParam *common1=0,*common2=0;
335 if (AliTPCTracklet::PropagateToMeanX(*t1,*t2,common1,common2))
336 ProcessTracklets(*common1,*common2,seed, t1->GetSector(),t2->GetSector());
343 void AliTPCcalibAlign::Analyze(){
351 void AliTPCcalibAlign::Terminate(){
353 // Terminate function
354 // call base terminate + Eval of fitters
356 Info("AliTPCcalibAlign","Terminate");
358 AliTPCcalibBase::Terminate();
364 void AliTPCcalibAlign::ProcessTracklets(const AliExternalTrackParam &tp1,
365 const AliExternalTrackParam &tp2,
366 const AliTPCseed * seed,
374 // Process function to fill fitters
376 Double_t t1[10],t2[10];
377 Double_t &x1=t1[0], &y1=t1[1], &z1=t1[2], &dydx1=t1[3], &dzdx1=t1[4];
378 Double_t &x2=t2[0], &y2=t2[1], &z2=t2[2], &dydx2=t2[3], &dzdx2=t2[4];
382 Double_t snp1=tp1.GetSnp();
383 dydx1=snp1/TMath::Sqrt((1.-snp1)*(1.+snp1));
384 Double_t tgl1=tp1.GetTgl();
385 // dz/dx = 1/(cos(theta)*cos(phi))
386 dzdx1=tgl1/TMath::Sqrt((1.-snp1)*(1.+snp1));
390 Double_t snp2=tp2.GetSnp();
391 dydx2=snp2/TMath::Sqrt((1.-snp2)*(1.+snp2));
392 Double_t tgl2=tp2.GetTgl();
393 dzdx2=tgl2/TMath::Sqrt((1.-snp2)*(1.+snp2));
394 Int_t accept = AcceptTracklet(tp1,tp2);
398 if (fStreamLevel>1 && seed){
399 TTreeSRedirector *cstream = GetDebugStreamer();
401 static TVectorD vec1(5);
402 static TVectorD vec2(5);
403 vec1.SetElements(t1);
404 vec2.SetElements(t2);
405 AliExternalTrackParam *p1 = &((AliExternalTrackParam&)tp1);
406 AliExternalTrackParam *p2 = &((AliExternalTrackParam&)tp2);
407 (*cstream)<<"Tracklet"<<
409 "run="<<fRun<< // run number
410 "event="<<fEvent<< // event number
411 "time="<<fTime<< // time stamp of event
412 "trigger="<<fTrigger<< // trigger
413 "mag="<<fMagF<< // magnetic field
414 "isOK="<<accept<< // flag - used for alignment
424 if (accept>0) return;
428 t1[6]=TMath::Sqrt(tp1.GetSigmaY2()+tp2.GetSigmaY2()); t2[6]=t1[6];
429 t1[7]=TMath::Sqrt(tp1.GetSigmaZ2()+tp2.GetSigmaZ2()); t2[7]=t1[7];
430 t1[8]=TMath::Sqrt(tp1.GetSigmaSnp2()+tp2.GetSigmaSnp2()); t2[8]=t1[8];
431 t1[9]=TMath::Sqrt(tp1.GetSigmaTgl2()+tp2.GetSigmaTgl2()); t2[9]=t1[9];
433 if (GetDebugLevel()>50) printf("Process track\n");
434 if (GetDebugLevel()>50) printf("Filling track\n");
436 // fill resolution histograms - previous cut included
437 if (seed) ProcessDiff(tp1,tp2, seed,s1,s2);
438 FillHisto(tp1,tp2,s1,s2);
439 ProcessAlign(t1,t2,s1,s2);
442 void AliTPCcalibAlign::ProcessAlign(Double_t * t1,
446 // Do intersector alignment
448 Process12(t1,t2,GetOrMakeFitter12(s1,s2));
449 Process9(t1,t2,GetOrMakeFitter9(s1,s2));
450 Process6(t1,t2,GetOrMakeFitter6(s1,s2));
451 ++fPoints[GetIndex(s1,s2)];
454 void AliTPCcalibAlign::ProcessTree(TTree * chainTracklet, AliExternalComparison *comp){
456 // Process the debug streamer tree
457 // Possible to modify selection criteria
458 // Used with entry list
460 TTreeSRedirector * cstream = new TTreeSRedirector("aligndump.root");
462 AliTPCcalibAlign *align = this;
466 AliExternalTrackParam * tp1 = 0;
467 AliExternalTrackParam * tp2 = 0;
472 Int_t entries=chainTracklet->GetEntries();
473 for (Int_t i=0; i< entries; i++){
474 chainTracklet->GetBranch("tp1.")->SetAddress(&tp1);
475 chainTracklet->GetBranch("tp2.")->SetAddress(&tp2);
476 chainTracklet->GetBranch("v1.")->SetAddress(&vec1);
477 chainTracklet->GetBranch("v2.")->SetAddress(&vec2);
478 chainTracklet->GetBranch("s1")->SetAddress(&s1);
479 chainTracklet->GetBranch("s2")->SetAddress(&s2);
480 chainTracklet->GetEntry(i);
485 if (!vec1->GetMatrixArray()) continue;
486 if (!vec2->GetMatrixArray()) continue;
488 AliExternalTrackParam par1(*tp1);
489 AliExternalTrackParam par2(*tp2);
490 TVectorD svec1(*vec1);
491 TVectorD svec2(*vec2);
493 if (s1==s2) continue;
494 if (i%100==0) printf("%d\t%d\t%d\t%d\t\n",i, npoints,s1,s2);
495 AliExternalTrackParam cpar1(par1);
496 AliExternalTrackParam cpar2(par2);
497 Constrain1Pt(cpar1,par2,fNoField);
498 Constrain1Pt(cpar2,par1,fNoField);
499 Bool_t acceptComp = kFALSE;
500 if (comp) acceptComp=comp->AcceptPair(&par1,&par2);
501 if (comp) acceptComp&=comp->AcceptPair(&cpar1,&cpar2);
503 Int_t reject = align->AcceptTracklet(par1,par2);
504 Int_t rejectC =align->AcceptTracklet(cpar1,cpar2);
506 if (1||fStreamLevel>0){
507 (*cstream)<<"Tracklet"<<
511 "rejectC="<<rejectC<<
512 "acceptComp="<<acceptComp<<
526 if (acceptComp) comp->Process(&cpar1,&cpar2);
528 if (reject>0 || rejectC>0) continue;
530 align->ProcessTracklets(cpar1,cpar2,0,s1,s2);
531 align->ProcessTracklets(cpar2,cpar1,0,s2,s1);
538 Int_t AliTPCcalibAlign::AcceptTracklet(const AliExternalTrackParam &p1,
539 const AliExternalTrackParam &p2){
542 // Accept pair of tracklets?
546 TCut cutS0("sqrt(tp2.fC[0]+tp1.fC[0])<0.2");
547 TCut cutS1("sqrt(tp2.fC[2]+tp1.fC[2])<0.2");
548 TCut cutS2("sqrt(tp2.fC[5]+tp1.fC[5])<0.01");
549 TCut cutS3("sqrt(tp2.fC[9]+tp1.fC[9])<0.01");
550 TCut cutS4("sqrt(tp2.fC[14]+tp1.fC[14])<0.25");
551 TCut cutS=cutS0+cutS1+cutS2+cutS3+cutS4;
553 // parameters matching cuts
554 TCut cutP0("abs(tp1.fP[0]-tp2.fP[0])<0.6");
555 TCut cutP1("abs(tp1.fP[1]-tp2.fP[1])<0.6");
556 TCut cutP2("abs(tp1.fP[2]-tp2.fP[2])<0.03");
557 TCut cutP3("abs(tp1.fP[3]-tp2.fP[3])<0.03");
558 TCut cutP4("abs(tp1.fP[4]-tp2.fP[4])<0.5");
559 TCut cutPP4("abs(tp1.fP[4]-tp2.fP[4])/sqrt(tp2.fC[14]+tp1.fC[14])<3");
560 TCut cutP=cutP0+cutP1+cutP2+cutP3+cutP4+cutPP4;
565 const Double_t *cp1 = p1.GetCovariance();
566 const Double_t *cp2 = p2.GetCovariance();
567 if (TMath::Sqrt(cp1[0]+cp2[0])>0.2) reject|=1;;
568 if (TMath::Sqrt(cp1[2]+cp2[2])>0.2) reject|=2;
569 if (TMath::Sqrt(cp1[5]+cp2[5])>0.01) reject|=4;
570 if (TMath::Sqrt(cp1[9]+cp2[9])>0.01) reject|=8;
571 if (TMath::Sqrt(cp1[14]+cp2[14])>0.2) reject|=16;
573 //parameters difference
574 const Double_t *tp1 = p1.GetParameter();
575 const Double_t *tp2 = p2.GetParameter();
576 if (TMath::Abs(tp1[0]-tp2[0])>0.6) reject|=32;
577 if (TMath::Abs(tp1[1]-tp2[1])>0.6) reject|=64;
578 if (TMath::Abs(tp1[2]-tp2[2])>0.03) reject|=128;
579 if (TMath::Abs(tp1[3]-tp2[3])>0.03) reject|=526;
580 if (TMath::Abs(tp1[4]-tp2[4])>0.4) reject|=1024;
581 if (TMath::Abs(tp1[4]-tp2[4])/TMath::Sqrt(cp1[14]+cp2[14])>4) reject|=2048;
584 if (TMath::Abs(tp2[1])>235) reject|=2*4096;
595 void AliTPCcalibAlign::ProcessDiff(const AliExternalTrackParam &t1,
596 const AliExternalTrackParam &t2,
597 const AliTPCseed *seed,
601 // Process local residuals function
606 TVectorD vecClY(160);
607 TVectorD vecClZ(160);
608 TClonesArray arrCl("AliTPCclusterMI",160);
609 arrCl.ExpandCreateFast(160);
610 Int_t count1=0, count2=0;
612 for (Int_t i=0;i<160;++i) {
613 AliTPCclusterMI *c=seed->GetClusterPointer(i);
618 AliTPCclusterMI & cl = (AliTPCclusterMI&) (*arrCl[i]);
619 if (c->GetDetector()!=s1 && c->GetDetector()!=s2) continue;
620 vecClY[i] = c->GetY();
621 vecClZ[i] = c->GetZ();
623 const AliExternalTrackParam *par = (c->GetDetector()==s1)? &t1:&t2;
624 if (c->GetDetector()==s1) ++count1;
625 if (c->GetDetector()==s2) ++count2;
626 Double_t gxyz[3],xyz[3];
628 Float_t bz = AliTracker::GetBz(gxyz);
629 par->GetYAt(c->GetX(), bz, xyz[1]);
630 par->GetZAt(c->GetX(), bz, xyz[2]);
639 // huge output - cluster residuals to be investigated
641 TTreeSRedirector *cstream = GetDebugStreamer();
642 AliExternalTrackParam *p1 = &((AliExternalTrackParam&)t1);
643 AliExternalTrackParam *p2 = &((AliExternalTrackParam&)t2);
646 Track->Draw("Cl[].fY-vtY.fElements:vtY.fElements-vtX.fElements*tan(pi/18.)>>his(100,-10,0)","Cl.fY!=0&&abs(Cl.fY-vtY.fElements)<1","prof");
651 (*cstream)<<"Track"<<
652 "run="<<fRun<< // run number
653 "event="<<fEvent<< // event number
654 "time="<<fTime<< // time stamp of event
655 "trigger="<<fTrigger<< // trigger
656 "mag="<<fMagF<< // magnetic field
678 void AliTPCcalibAlign::Process12(const Double_t *t1,
680 TLinearFitter *fitter) {
681 // x2 = a00*x1 + a01*y1 + a02*z1 + a03
682 // y2 = a10*x1 + a11*y1 + a12*z1 + a13
683 // z2 = a20*x1 + a21*y1 + a22*z1 + a23
684 // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
685 // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
687 // a00 a01 a02 a03 p[0] p[1] p[2] p[9]
688 // a10 a11 a12 a13 ==> p[3] p[4] p[5] p[10]
689 // a20 a21 a22 a23 p[6] p[7] p[8] p[11]
693 const Double_t &x1=t1[0], &y1=t1[1], &z1=t1[2], &dydx1=t1[3], &dzdx1=t1[4];
694 const Double_t /*&x2=t2[0],*/ &y2=t2[1], &z2=t2[2], &dydx2=t2[3], &dzdx2=t2[4];
699 Double_t sdydx = t1[8];
700 Double_t sdzdx = t1[9];
705 // x2 = a00*x1 + a01*y1 + a02*z1 + a03
706 // y2 = a10*x1 + a11*y1 + a12*z1 + a13
707 // y2' = a10*x1 + a11*y1 + a12*z1 + a13 + (a01*y1 + a02*z1 + a03)*dydx2
708 for (Int_t i=0; i<12;i++) p[i]=0.;
713 p[0+1] = y1*dydx2; // a01
714 p[0+2] = z1*dydx2; // a02
715 p[9+0] = dydx2; // a03
717 fitter->AddPoint(p,value,sy);
719 // x2 = a00*x1 + a01*y1 + a02*z1 + a03
720 // z2 = a20*x1 + a21*y1 + a22*z1 + a23
721 // z2' = a20*x1 + a21*y1 + a22*z1 + a23 + (a01*y1 + a02*z1 + a03)*dzdx2;
722 for (Int_t i=0; i<12;i++) p[i]=0.;
727 p[0+1] = y1*dzdx2; // a01
728 p[0+2] = z1*dzdx2; // a02
729 p[9+0] = dzdx2; // a03
731 fitter->AddPoint(p,value,sz);
733 // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/( a00 + a01*dydx1 + a02*dzdx1)
734 // (a10 + a11*dydx1 + a12*dzdx1) - (a00 + a01*dydx1 + a02*dzdx1)*dydx2 = 0
735 for (Int_t i=0; i<12;i++) p[i]=0.;
737 p[3+1] = dydx1; // a11
738 p[3+2] = dzdx1; // a12
739 p[0+0] = -dydx2; // a00
740 p[0+1] = -dydx1*dydx2; // a01
741 p[0+2] = -dzdx1*dydx2; // a02
743 fitter->AddPoint(p,value,sdydx);
745 // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/( a00 + a01*dydx1 + a02*dzdx1)
746 // (a20 + a21*dydx1 + a22*dzdx1) - (a00 + a01*dydx1 + a02*dzdx1)*dzdx2 = 0
747 for (Int_t i=0; i<12;i++) p[i]=0.;
749 p[6+1] = dydx1; // a21
750 p[6+2] = dzdx1; // a22
751 p[0+0] = -dzdx2; // a00
752 p[0+1] = -dydx1*dzdx2; // a01
753 p[0+2] = -dzdx1*dzdx2; // a02
755 fitter->AddPoint(p,value,sdzdx);
758 void AliTPCcalibAlign::Process9(Double_t *t1,
760 TLinearFitter *fitter) {
761 // x2 = a00*x1 + a01*y1 + a02*z1 + a03
762 // y2 = a10*x1 + a11*y1 + a12*z1 + a13
763 // z2 = a20*x1 + a21*y1 + a22*z1 + a23
764 // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
765 // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
767 // a00 a01 a02 a03 1 p[0] p[1] p[6]
768 // a10 a11 a12 a13 ==> p[2] 1 p[3] p[7]
769 // a20 a21 a21 a23 p[4] p[5] 1 p[8]
772 Double_t &x1=t1[0], &y1=t1[1], &z1=t1[2], &dydx1=t1[3], &dzdx1=t1[4];
773 Double_t /*&x2=t2[0],*/ &y2=t2[1], &z2=t2[2], &dydx2=t2[3], &dzdx2=t2[4];
777 Double_t sdydx = t1[8];
778 Double_t sdzdx = t1[9];
783 // x2 = a00*x1 + a01*y1 + a02*z1 + a03
784 // y2 = a10*x1 + a11*y1 + a12*z1 + a13
785 // y2' = a10*x1 + a11*y1 + a12*z1 + a13 + (a01*y1 + a02*z1 + a03)*dydx2
786 for (Int_t i=0; i<12;i++) p[i]=0.;
791 p[0] += y1*dydx2; // a01
792 p[1] += z1*dydx2; // a02
793 p[6] += dydx2; // a03
794 value = y2-y1; //-a11
795 fitter->AddPoint(p,value,sy);
797 // x2 = a00*x1 + a01*y1 + a02*z1 + a03
798 // z2 = a20*x1 + a21*y1 + a22*z1 + a23
799 // z2' = a20*x1 + a21*y1 + a22*z1 + a23 + (a01*y1 + a02*z1 + a03)*dzdx2;
800 for (Int_t i=0; i<12;i++) p[i]=0.;
805 p[0] += y1*dzdx2; // a01
806 p[1] += z1*dzdx2; // a02
807 p[6] += dzdx2; // a03
808 value = z2-z1; //-a22
809 fitter->AddPoint(p,value,sz);
811 // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/( a00 + a01*dydx1 + a02*dzdx1)
812 // (a10 + a11*dydx1 + a12*dzdx1) - (a00 + a01*dydx1 + a02*dzdx1)*dydx2 = 0
813 for (Int_t i=0; i<12;i++) p[i]=0.;
815 //p[] += dydx1; // a11
816 p[3] += dzdx1; // a12
817 //p[] += -dydx2; // a00
818 p[0] += -dydx1*dydx2; // a01
819 p[1] += -dzdx1*dydx2; // a02
820 value = -dydx1+dydx2; // -a11 + a00
821 fitter->AddPoint(p,value,sdydx);
823 // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/( a00 + a01*dydx1 + a02*dzdx1)
824 // (a20 + a21*dydx1 + a22*dzdx1) - (a00 + a01*dydx1 + a02*dzdx1)*dzdx2 = 0
825 for (Int_t i=0; i<12;i++) p[i]=0.;
827 p[5] += dydx1; // a21
828 //p[] += dzdx1; // a22
829 //p[] += -dzdx2; // a00
830 p[0] += -dydx1*dzdx2; // a01
831 p[1] += -dzdx1*dzdx2; // a02
832 value = -dzdx1+dzdx2; // -a22 + a00
833 fitter->AddPoint(p,value,sdzdx);
836 void AliTPCcalibAlign::Process6(Double_t *t1,
838 TLinearFitter *fitter) {
839 // x2 = 1 *x1 +-a01*y1 + 0 +a03
840 // y2 = a01*x1 + 1 *y1 + 0 +a13
841 // z2 = a20*x1 + a21*y1 + 1 *z1 +a23
842 // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
843 // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
845 // a00 a01 a02 a03 1 -p[0] 0 p[3]
846 // a10 a11 a12 a13 ==> p[0] 1 0 p[4]
847 // a20 a21 a21 a23 p[1] p[2] 1 p[5]
849 Double_t &x1=t1[0], &y1=t1[1], &z1=t1[2], &dydx1=t1[3], &dzdx1=t1[4];
850 Double_t /*&x2=t2[0],*/ &y2=t2[1], &z2=t2[2], &dydx2=t2[3], &dzdx2=t2[4];
855 Double_t sdydx = t1[8];
856 Double_t sdzdx = t1[9];
860 // x2 = a00*x1 + a01*y1 + a02*z1 + a03
861 // y2 = a10*x1 + a11*y1 + a12*z1 + a13
862 // y2' = a10*x1 + a11*y1 + a12*z1 + a13 + (a01*y1 + a02*z1 + a03)*dydx2
863 for (Int_t i=0; i<12;i++) p[i]=0.;
868 p[0] += -y1*dydx2; // a01
869 //p[] += z1*dydx2; // a02
870 p[3] += dydx2; // a03
871 value = y2-y1; //-a11
872 fitter->AddPoint(p,value,sy);
874 // x2 = a00*x1 + a01*y1 + a02*z1 + a03
875 // z2 = a20*x1 + a21*y1 + a22*z1 + a23
876 // z2' = a20*x1 + a21*y1 + a22*z1 + a23 + (a01*y1 + a02*z1 + a03)*dzdx2;
877 for (Int_t i=0; i<12;i++) p[i]=0.;
882 p[0] += -y1*dzdx2; // a01
883 //p[] += z1*dzdx2; // a02
884 p[3] += dzdx2; // a03
885 value = z2-z1; //-a22
886 fitter->AddPoint(p,value,sz);
888 // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/( a00 + a01*dydx1 + a02*dzdx1)
889 // (a10 + a11*dydx1 + a12*dzdx1) - (a00 + a01*dydx1 + a02*dzdx1)*dydx2 = 0
890 for (Int_t i=0; i<12;i++) p[i]=0.;
892 //p[] += dydx1; // a11
893 //p[] += dzdx1; // a12
894 //p[] += -dydx2; // a00
895 //p[0] += dydx1*dydx2; // a01 FIXME- 0912 MI
896 //p[] += -dzdx1*dydx2; // a02
897 value = -dydx1+dydx2; // -a11 + a00
898 fitter->AddPoint(p,value,sdydx);
900 // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/( a00 + a01*dydx1 + a02*dzdx1)
901 // (a20 + a21*dydx1 + a22*dzdx1) - (a00 + a01*dydx1 + a02*dzdx1)*dzdx2 = 0
902 for (Int_t i=0; i<12;i++) p[i]=0.;
904 // p[2] += dydx1; // a21 FIXME- 0912 MI
905 //p[] += dzdx1; // a22
906 //p[] += -dzdx2; // a00
907 //p[0] += dydx1*dzdx2; // a01 FIXME- 0912 MI
908 //p[] += -dzdx1*dzdx2; // a02
909 value = -dzdx1+dzdx2; // -a22 + a00
910 fitter->AddPoint(p,value,sdzdx);
916 void AliTPCcalibAlign::EvalFitters() {
920 // Perform the fitting using linear fitters
922 Int_t kMinPoints =50;
924 TFile fff("alignDebug.root","recreate");
925 for (Int_t s1=0;s1<72;++s1)
926 for (Int_t s2=0;s2<72;++s2){
927 if ((f=GetFitter12(s1,s2))&&fPoints[GetIndex(s1,s2)]>kMinPoints) {
928 // cerr<<s1<<","<<s2<<": "<<fPoints[GetIndex(s1,s2)]<<endl;
930 cerr<<"Evaluation failed for "<<s1<<","<<s2<<endl;
931 f->Write(Form("f12_%d_%d",s1,s2));
933 f->Write(Form("f12_%d_%d",s1,s2));
936 if ((f=GetFitter9(s1,s2))&&fPoints[GetIndex(s1,s2)]>kMinPoints) {
937 // cerr<<s1<<","<<s2<<": "<<fPoints[GetIndex(s1,s2)]<<endl;
939 cerr<<"Evaluation failed for "<<s1<<","<<s2<<endl;
941 f->Write(Form("f9_%d_%d",s1,s2));
944 if ((f=GetFitter6(s1,s2))&&fPoints[GetIndex(s1,s2)]>kMinPoints) {
945 // cerr<<s1<<","<<s2<<": "<<fPoints[GetIndex(s1,s2)]<<endl;
947 cerr<<"Evaluation failed for "<<s1<<","<<s2<<endl;
949 f->Write(Form("f6_%d_%d",s1,s2));
954 for (Int_t s1=0;s1<72;++s1)
955 for (Int_t s2=0;s2<72;++s2){
956 if (GetTransformation12(s1,s2,mat)){
957 fMatrixArray12.AddAt(mat.Clone(), GetIndex(s1,s2));
959 if (GetTransformation9(s1,s2,mat)){
960 fMatrixArray9.AddAt(mat.Clone(), GetIndex(s1,s2));
962 if (GetTransformation6(s1,s2,mat)){
963 fMatrixArray6.AddAt(mat.Clone(), GetIndex(s1,s2));
966 //this->Write("align");
970 TLinearFitter* AliTPCcalibAlign::GetOrMakeFitter12(Int_t s1,Int_t s2) {
972 // get or make fitter - general linear transformation
974 static Int_t counter12=0;
975 static TF1 f12("f12","x[0]++x[1]++x[2]++x[3]++x[4]++x[5]++x[6]++x[7]++x[8]++x[9]++x[10]++x[11]");
976 TLinearFitter * fitter = GetFitter12(s1,s2);
977 if (fitter) return fitter;
978 // fitter =new TLinearFitter(12,"x[0]++x[1]++x[2]++x[3]++x[4]++x[5]++x[6]++x[7]++x[8]++x[9]++x[10]++x[11]");
979 fitter =new TLinearFitter(&f12,"");
980 fitter->StoreData(kFALSE);
981 fFitterArray12.AddAt(fitter,GetIndex(s1,s2));
983 if (GetDebugLevel()>0) cerr<<"Creating fitter12 "<<s1<<","<<s2<<" : "<<counter12<<endl;
987 TLinearFitter* AliTPCcalibAlign::GetOrMakeFitter9(Int_t s1,Int_t s2) {
989 //get or make fitter - general linear transformation - no scaling
991 static Int_t counter9=0;
992 static TF1 f9("f9","x[0]++x[1]++x[2]++x[3]++x[4]++x[5]++x[6]++x[7]++x[8]");
993 TLinearFitter * fitter = GetFitter9(s1,s2);
994 if (fitter) return fitter;
995 // fitter =new TLinearFitter(9,"x[0]++x[1]++x[2]++x[3]++x[4]++x[5]++x[6]++x[7]++x[8]");
996 fitter =new TLinearFitter(&f9,"");
997 fitter->StoreData(kFALSE);
998 fFitterArray9.AddAt(fitter,GetIndex(s1,s2));
1000 if (GetDebugLevel()>0) cerr<<"Creating fitter12 "<<s1<<","<<s2<<" : "<<counter9<<endl;
1004 TLinearFitter* AliTPCcalibAlign::GetOrMakeFitter6(Int_t s1,Int_t s2) {
1006 // get or make fitter - 6 paramater linear tranformation
1009 // - tilting x-z, y-z
1010 static Int_t counter6=0;
1011 static TF1 f6("f6","x[0]++x[1]++x[2]++x[3]++x[4]++x[5]");
1012 TLinearFitter * fitter = GetFitter6(s1,s2);
1013 if (fitter) return fitter;
1014 // fitter=new TLinearFitter(6,"x[0]++x[1]++x[2]++x[3]++x[4]++x[5]");
1015 fitter=new TLinearFitter(&f6,"");
1016 fitter->StoreData(kTRUE);
1017 fFitterArray6.AddAt(fitter,GetIndex(s1,s2));
1019 if (GetDebugLevel()>0) cerr<<"Creating fitter6 "<<s1<<","<<s2<<" : "<<counter6<<endl;
1027 Bool_t AliTPCcalibAlign::GetTransformation12(Int_t s1,Int_t s2,TMatrixD &a) {
1029 // GetTransformation matrix - 12 paramaters - generael linear transformation
1031 if (!GetFitter12(s1,s2))
1035 GetFitter12(s1,s2)->GetParameters(p);
1037 a[0][0]=p[0]; a[0][1]=p[1]; a[0][2]=p[2]; a[0][3]=p[9];
1038 a[1][0]=p[3]; a[1][1]=p[4]; a[1][2]=p[5]; a[1][3]=p[10];
1039 a[2][0]=p[6]; a[2][1]=p[7]; a[2][2]=p[8]; a[2][3]=p[11];
1040 a[3][0]=0.; a[3][1]=0.; a[3][2]=0.; a[3][3]=1.;
1045 Bool_t AliTPCcalibAlign::GetTransformation9(Int_t s1,Int_t s2,TMatrixD &a) {
1047 // GetTransformation matrix - 9 paramaters - general linear transformation
1050 if (!GetFitter9(s1,s2))
1054 GetFitter9(s1,s2)->GetParameters(p);
1056 a[0][0]=1; a[0][1]=p[0]; a[0][2]=p[1]; a[0][3]=p[6];
1057 a[1][0]=p[2]; a[1][1]=1; a[1][2]=p[3]; a[1][3]=p[7];
1058 a[2][0]=p[4]; a[2][1]=p[5]; a[2][2]=1; a[2][3]=p[8];
1059 a[3][0]=0.; a[3][1]=0.; a[3][2]=0.; a[3][3]=1.;
1064 Bool_t AliTPCcalibAlign::GetTransformation6(Int_t s1,Int_t s2,TMatrixD &a) {
1066 // GetTransformation matrix - 6 paramaters
1069 // 2 tilting x-z y-z
1070 if (!GetFitter6(s1,s2))
1074 GetFitter6(s1,s2)->GetParameters(p);
1076 a[0][0]=1; a[0][1]=-p[0];a[0][2]=0; a[0][3]=p[3];
1077 a[1][0]=p[0]; a[1][1]=1; a[1][2]=0; a[1][3]=p[4];
1078 a[2][0]=p[1]; a[2][1]=p[2]; a[2][2]=1; a[2][3]=p[5];
1079 a[3][0]=0.; a[3][1]=0.; a[3][2]=0.; a[3][3]=1.;
1084 void AliTPCcalibAlign::FillHisto(const AliExternalTrackParam &tp1,
1085 const AliExternalTrackParam &tp2,
1086 Int_t s1,Int_t s2) {
1088 // Fill residual histograms
1092 if (TMath::Abs(s2%36-s1%36)<2 || TMath::Abs(s2%18-s1%18)==0) {
1093 GetHisto(kPhi,s1,s2,kTRUE)->Fill(TMath::ASin(tp1.GetSnp())-TMath::ASin(tp2.GetSnp()));
1094 GetHisto(kTheta,s1,s2,kTRUE)->Fill(TMath::ATan(tp1.GetTgl())-TMath::ATan(tp2.GetTgl()));
1095 GetHisto(kY,s1,s2,kTRUE)->Fill(tp1.GetY()-tp2.GetY());
1096 GetHisto(kZ,s1,s2,kTRUE)->Fill(tp1.GetZ()-tp2.GetZ());
1098 GetHisto(kPhiZ,s1,s2,kTRUE)->Fill(tp1.GetZ(),TMath::ASin(tp1.GetSnp())-TMath::ASin(tp2.GetSnp()));
1099 GetHisto(kThetaZ,s1,s2,kTRUE)->Fill(tp1.GetZ(),TMath::ATan(tp1.GetTgl())-TMath::ATan(tp2.GetTgl()));
1100 GetHisto(kYz,s1,s2,kTRUE)->Fill(tp1.GetZ(),tp1.GetY()-tp2.GetY());
1101 GetHisto(kZz,s1,s2,kTRUE)->Fill(tp1.GetZ(),tp1.GetZ()-tp2.GetZ());
1103 GetHisto(kYPhi,s1,s2,kTRUE)->Fill(tp1.GetSnp(),tp1.GetY()-tp2.GetY());
1104 GetHisto(kZTheta,s1,s2,kTRUE)->Fill(tp1.GetTgl(),tp1.GetZ()-tp2.GetZ());
1112 TH1 * AliTPCcalibAlign::GetHisto(HistoType type, Int_t s1, Int_t s2, Bool_t force)
1115 // return specified residual histogram - it is only QA
1116 // if force specified the histogram and given histogram is not existing
1117 // new histogram is created
1119 if (GetIndex(s1,s2)>=72*72) return 0;
1120 TObjArray *histoArray=0;
1123 histoArray = &fDyHistArray; break;
1125 histoArray = &fDzHistArray; break;
1127 histoArray = &fDphiHistArray; break;
1129 histoArray = &fDthetaHistArray; break;
1131 histoArray = &fDyPhiHistArray; break;
1133 histoArray = &fDzThetaHistArray; break;
1135 histoArray = &fDyZHistArray; break;
1137 histoArray = &fDzZHistArray; break;
1139 histoArray = &fDphiZHistArray; break;
1141 histoArray = &fDthetaZHistArray; break;
1143 TH1 * histo= (TH1*)histoArray->At(GetIndex(s1,s2));
1144 if (histo) return histo;
1145 if (force==kFALSE) return 0;
1151 name<<"hist_y_"<<s1<<"_"<<s2;
1152 title<<"Y Missalignment for sectors "<<s1<<" and "<<s2;
1153 histo =new TH1D(name.str().c_str(),title.str().c_str(),512,-0.3,0.3); // +/- 3 mm
1156 name<<"hist_z_"<<s1<<"_"<<s2;
1157 title<<"Z Missalignment for sectors "<<s1<<" and "<<s2;
1158 histo = new TH1D(name.str().c_str(),title.str().c_str(),512,-0.3,0.3); // +/- 3 mm
1161 name<<"hist_phi_"<<s1<<"_"<<s2;
1162 title<<"Phi Missalignment for sectors "<<s1<<" and "<<s2;
1163 histo =new TH1D(name.str().c_str(),title.str().c_str(),512,-0.01,0.01); // +/- 10 mrad
1166 name<<"hist_theta_"<<s1<<"_"<<s2;
1167 title<<"Theta Missalignment for sectors "<<s1<<" and "<<s2;
1168 histo =new TH1D(name.str().c_str(),title.str().c_str(),512,-0.01,0.01); // +/- 10 mrad
1173 name<<"hist_yphi_"<<s1<<"_"<<s2;
1174 title<<"Y Missalignment for sectors Phi"<<s1<<" and "<<s2;
1175 histo =new TH2F(name.str().c_str(),title.str().c_str(),20,-1,1,128,-0.3,0.3); // +/- 3 mm
1178 name<<"hist_ztheta_"<<s1<<"_"<<s2;
1179 title<<"Z Missalignment for sectors Theta"<<s1<<" and "<<s2;
1180 histo = new TH2F(name.str().c_str(),title.str().c_str(),128,20,-1,1,-0.3,0.3); // +/- 3 mm
1186 name<<"hist_yz_"<<s1<<"_"<<s2;
1187 title<<"Y Missalignment for sectors Z"<<s1<<" and "<<s2;
1188 histo =new TH2F(name.str().c_str(),title.str().c_str(),20,-250,250,128,-0.3,0.3); // +/- 3 mm
1191 name<<"hist_zz_"<<s1<<"_"<<s2;
1192 title<<"Z Missalignment for sectors Z"<<s1<<" and "<<s2;
1193 histo = new TH2F(name.str().c_str(),title.str().c_str(),20,-250,250,128,-0.3,0.3); // +/- 3 mm
1196 name<<"hist_phiz_"<<s1<<"_"<<s2;
1197 title<<"Phi Missalignment for sectors Z"<<s1<<" and "<<s2;
1198 histo =new TH2F(name.str().c_str(),title.str().c_str(),20,-250,250,128,-0.01,0.01); // +/- 10 mrad
1201 name<<"hist_thetaz_"<<s1<<"_"<<s2;
1202 title<<"Theta Missalignment for sectors Z"<<s1<<" and "<<s2;
1203 histo =new TH2F(name.str().c_str(),title.str().c_str(),20,-250,250,128,-0.01,0.01); // +/- 10 mrad
1208 histo->SetDirectory(0);
1209 histoArray->AddAt(histo,GetIndex(s1,s2));
1213 TGraphErrors * AliTPCcalibAlign::MakeGraph(Int_t sec0, Int_t sec1, Int_t dsec,
1214 Int_t i0, Int_t i1, FitType type)
1220 //TObjArray *fitArray=0;
1221 Double_t xsec[1000];
1222 Double_t ysec[1000];
1224 for (Int_t isec = sec0; isec<=sec1; isec++){
1225 Int_t isec2 = (isec+dsec)%72;
1228 GetTransformation6(isec,isec2,mat);break;
1230 GetTransformation9(isec,isec2,mat);break;
1232 GetTransformation12(isec,isec2,mat);break;
1235 ysec[npoints]=mat(i0,i1);
1238 TGraphErrors *gr = new TGraphErrors(npoints,xsec,ysec,0,0);
1240 sprintf(name,"Mat[%d,%d] Type=%d",i0,i1,type);
1245 void AliTPCcalibAlign::MakeTree(const char *fname){
1247 // make tree with alignment cosntant -
1248 // For QA visualization
1251 TFile f("CalibObjects.root");
1252 TObjArray *array = (TObjArray*)f.Get("TPCCalib");
1253 AliTPCcalibAlign *alignTPC = (AliTPCcalibAlign *)array->At(0);
1254 alignTPC->MakeTree("alignTree.root");
1255 TFile falign("alignTree.root");
1258 const Int_t kMinPoints=50;
1259 TTreeSRedirector cstream(fname);
1260 for (Int_t s1=0;s1<72;++s1)
1261 for (Int_t s2=0;s2<72;++s2){
1266 Double_t dy=0, dz=0, dphi=0,dtheta=0;
1267 Double_t sy=0, sz=0, sphi=0,stheta=0;
1268 Double_t ny=0, nz=0, nphi=0,ntheta=0;
1269 Double_t chi2v12=0, chi2v9=0, chi2v6=0;
1271 TLinearFitter * fitter = 0;
1272 if (fPoints[GetIndex(s1,s2)]>kMinPoints){
1276 fitter = GetFitter12(s1,s2);
1277 npoints = fitter->GetNpoints();
1278 chi2v12 = TMath::Sqrt(fitter->GetChisquare()/npoints);
1280 fitter = GetFitter9(s1,s2);
1281 npoints = fitter->GetNpoints();
1282 chi2v9 = TMath::Sqrt(fitter->GetChisquare()/npoints);
1284 fitter = GetFitter6(s1,s2);
1285 npoints = fitter->GetNpoints();
1286 chi2v6 = TMath::Sqrt(fitter->GetChisquare()/npoints);
1289 GetTransformation6(s1,s2,m6);
1290 GetTransformation9(s1,s2,m9);
1291 GetTransformation12(s1,s2,m12);
1293 fitter = GetFitter6(s1,s2);
1294 fitter->FixParameter(3,0);
1296 GetTransformation6(s1,s2,m6FX);
1299 his = GetHisto(kY,s1,s2);
1300 if (his) { dy = his->GetMean(); sy = his->GetRMS(); ny = his->GetEntries();}
1301 his = GetHisto(kZ,s1,s2);
1302 if (his) { dz = his->GetMean(); sz = his->GetRMS(); nz = his->GetEntries();}
1303 his = GetHisto(kPhi,s1,s2);
1304 if (his) { dphi = his->GetMean(); sphi = his->GetRMS(); nphi = his->GetEntries();}
1305 his = GetHisto(kTheta,s1,s2);
1306 if (his) { dtheta = his->GetMean(); stheta = his->GetRMS(); ntheta = his->GetEntries();}
1311 // x2 = a00*x1 + a01*y1 + a02*z1 + a03
1312 // y2 = a10*x1 + a11*y1 + a12*z1 + a13
1313 // z2 = a20*x1 + a21*y1 + a22*z1 + a23
1314 // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
1315 // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
1317 // a00 a01 a02 a03 p[0] p[1] p[2] p[9]
1318 // a10 a11 a12 a13 ==> p[3] p[4] p[5] p[10]
1319 // a20 a21 a22 a23 p[6] p[7] p[8] p[11]
1323 // dy:-(134*m6.fElements[4]+m6.fElements[7])
1325 // dphi:-(m6.fElements[4])
1327 // dz:134*m6.fElements[8]+m6.fElements[11]
1329 // dtheta:m6.fElements[8]
1332 "s1="<<s1<< // reference sector
1333 "s2="<<s2<< // sector to align
1334 "m6FX.="<<&m6FX<< // tranformation matrix
1335 "m6.="<<&m6<< // tranformation matrix
1338 "chi2v12="<<chi2v12<<
1341 // histograms mean RMS and entries
1360 //_____________________________________________________________________
1361 Long64_t AliTPCcalibAlign::Merge(TCollection* list) {
1365 if (GetDebugLevel()>0) Info("AliTPCcalibAlign","Merge");
1368 if (list->IsEmpty())
1371 TIterator* iter = list->MakeIterator();
1376 TString str1(GetName());
1377 while((obj = iter->Next()) != 0)
1379 AliTPCcalibAlign* entry = dynamic_cast<AliTPCcalibAlign*>(obj);
1380 if (entry == 0) continue;
1381 if (str1.CompareTo(entry->GetName())!=0) continue;
1389 void AliTPCcalibAlign::Add(AliTPCcalibAlign * align){
1391 // Add entry - used for merging of compoents
1393 for (Int_t i=0; i<72;i++){
1394 for (Int_t j=0; j<72;j++){
1395 if (align->fPoints[GetIndex(i,j)]<10) continue;
1396 fPoints[GetIndex(i,j)]+=align->fPoints[GetIndex(i,j)];
1400 for (Int_t itype=0; itype<10; itype++){
1401 TH1 * his0=0, *his1=0;
1402 his0 = GetHisto((HistoType)itype,i,j);
1403 his1 = align->GetHisto((HistoType)itype,i,j);
1405 if (his0) his0->Add(his1);
1407 his0 = GetHisto(kY,i,j,kTRUE);
1414 TLinearFitter *f0=0;
1415 TLinearFitter *f1=0;
1416 for (Int_t i=0; i<72;i++){
1417 for (Int_t j=0; j<72;j++){
1418 if (align->fPoints[GetIndex(i,j)]<20) continue;
1422 f0 = GetFitter12(i,j);
1423 f1 = align->GetFitter12(i,j);
1424 if (f1 &&f1->Eval()){
1425 if (f0&&f0->GetNpoints()>10) f0->Add(f1);
1427 fFitterArray12.AddAt(f1->Clone(),GetIndex(i,j));
1432 f0 = GetFitter9(i,j);
1433 f1 = align->GetFitter9(i,j);
1434 if (f1&&f1->Eval()){
1435 if (f0&&f0->GetNpoints()>10) f0->Add(f1);
1437 fFitterArray9.AddAt(f1->Clone(),GetIndex(i,j));
1440 f0 = GetFitter6(i,j);
1441 f1 = align->GetFitter6(i,j);
1442 if (f1 &&f1->Eval()){
1443 if (f0&&f0->GetNpoints()>10) f0->Add(f1);
1445 fFitterArray6.AddAt(f1->Clone(),GetIndex(i,j));
1452 Double_t AliTPCcalibAlign::Correct(Int_t type, Int_t value, Int_t s1, Int_t s2, Double_t x1, Double_t y1, Double_t z1, Double_t dydx1,Double_t dzdx1){
1454 // GetTransformed value
1457 // x2 = a00*x1 + a01*y1 + a02*z1 + a03
1458 // y2 = a10*x1 + a11*y1 + a12*z1 + a13
1459 // z2 = a20*x1 + a21*y1 + a22*z1 + a23
1460 // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
1461 // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
1464 const TMatrixD * mat = GetTransformation(s1,s2,type);
1466 if (value==0) return x1;
1467 if (value==1) return y1;
1468 if (value==2) return z1;
1469 if (value==3) return dydx1;
1470 if (value==4) return dzdx1;
1472 if (value==5) return dydx1;
1473 if (value==6) return dzdx1;
1479 valT = (*mat)(0,0)*x1+(*mat)(0,1)*y1+(*mat)(0,2)*z1+(*mat)(0,3);
1483 valT = (*mat)(1,0)*x1+(*mat)(1,1)*y1+(*mat)(1,2)*z1+(*mat)(1,3);
1486 valT = (*mat)(2,0)*x1+(*mat)(2,1)*y1+(*mat)(2,2)*z1+(*mat)(2,3);
1489 // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
1490 valT = (*mat)(1,0) +(*mat)(1,1)*dydx1 +(*mat)(1,2)*dzdx1;
1491 valT/= ((*mat)(0,0) +(*mat)(0,1)*dydx1 +(*mat)(0,2)*dzdx1);
1495 // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
1496 valT = (*mat)(2,0) +(*mat)(2,1)*dydx1 +(*mat)(2,2)*dzdx1;
1497 valT/= ((*mat)(0,0) +(*mat)(0,1)*dydx1 +(*mat)(0,2)*dzdx1);
1501 // onlys shift in angle
1502 // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
1503 valT = (*mat)(1,0) +(*mat)(1,1)*dydx1;
1507 // only shift in angle
1508 // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
1509 valT = (*mat)(2,0) +(*mat)(2,1)*dydx1;
1516 void AliTPCcalibAlign::Constrain1Pt(AliExternalTrackParam &track1, const AliExternalTrackParam &track2, Bool_t noField){
1518 // Update track parameters t1
1520 TMatrixD vecXk(5,1); // X vector
1521 TMatrixD covXk(5,5); // X covariance
1522 TMatrixD matHk(1,5); // vector to mesurement
1523 TMatrixD measR(1,1); // measurement error
1524 //TMatrixD matQk(5,5); // prediction noise vector
1525 TMatrixD vecZk(1,1); // measurement
1527 TMatrixD vecYk(1,1); // Innovation or measurement residual
1528 TMatrixD matHkT(5,1);
1529 TMatrixD matSk(1,1); // Innovation (or residual) covariance
1530 TMatrixD matKk(5,1); // Optimal Kalman gain
1531 TMatrixD mat1(5,5); // update covariance matrix
1532 TMatrixD covXk2(5,5); //
1533 TMatrixD covOut(5,5);
1535 Double_t *param1=(Double_t*) track1.GetParameter();
1536 Double_t *covar1=(Double_t*) track1.GetCovariance();
1539 // copy data to the matrix
1540 for (Int_t ipar=0; ipar<5; ipar++){
1541 vecXk(ipar,0) = param1[ipar];
1542 for (Int_t jpar=0; jpar<5; jpar++){
1543 covXk(ipar,jpar) = covar1[track1.GetIndex(ipar, jpar)];
1549 vecZk(0,0) = track2.GetParameter()[4]; // 1/pt measurement from track 2
1550 measR(0,0) = track2.GetCovariance()[14]; // 1/pt measurement error
1552 measR(0,0)*=0.000000001;
1556 matHk(0,0)=0; matHk(0,1)= 0; matHk(0,2)= 0;
1557 matHk(0,3)= 0; matHk(0,4)= 1; // vector to measurement
1561 vecYk = vecZk-matHk*vecXk; // Innovation or measurement residual
1562 matHkT=matHk.T(); matHk.T();
1563 matSk = (matHk*(covXk*matHkT))+measR; // Innovation (or residual) covariance
1565 matKk = (covXk*matHkT)*matSk; // Optimal Kalman gain
1566 vecXk += matKk*vecYk; // updated vector
1567 mat1(0,0)=1; mat1(1,1)=1; mat1(2,2)=1; mat1(3,3)=1; mat1(4,4)=1;
1568 covXk2 = (mat1-(matKk*matHk));
1569 covOut = covXk2*covXk;
1573 // copy from matrix to parameters
1582 for (Int_t ipar=0; ipar<5; ipar++){
1583 param1[ipar]= vecXk(ipar,0) ;
1584 for (Int_t jpar=0; jpar<5; jpar++){
1585 covar1[track1.GetIndex(ipar, jpar)]=covOut(ipar,jpar);
1591 void AliTPCcalibAlign::GlobalAlign6(Int_t minPoints, Float_t sysError, Int_t niter){
1593 // Global Align -combine the partial alignment of pair of sectors
1594 // minPoints - minimal number of points - don't use sector alignment wit smaller number
1595 // sysError - error added to the alignemnt error
1597 AliTPCcalibAlign * align = this;
1598 TMatrixD * arrayAlign[72];
1599 TMatrixD * arrayAlignDiff[72];
1601 for (Int_t i=0;i<72; i++) {
1602 TMatrixD * mat = new TMatrixD(4,4);
1605 arrayAlignDiff[i]=(TMatrixD*)(mat->Clone());
1608 TTreeSRedirector *cstream = new TTreeSRedirector("galign6.root");
1609 for (Int_t iter=0; iter<niter;iter++){
1610 printf("Iter=\t%d\n",iter);
1611 for (Int_t is0=0;is0<72; is0++) {
1613 //TMatrixD *mati0 = arrayAlign[is0];
1614 TMatrixD matDiff(4,4);
1616 for (Int_t is1=0;is1<72; is1++) {
1617 Bool_t invers=kFALSE;
1621 const TMatrixD *mat = align->GetTransformation(is0,is1,0);
1623 npoints = align->GetFitter6(is0,is1)->GetNpoints();
1624 if (npoints>minPoints){
1625 align->GetFitter6(is0,is1)->GetCovarianceMatrix(covar);
1626 align->GetFitter6(is0,is1)->GetErrors(errors);
1631 mat = align->GetTransformation(is1,is0,0);
1633 npoints = align->GetFitter6(is1,is0)->GetNpoints();
1634 if (npoints>minPoints){
1635 align->GetFitter6(is1,is0)->GetCovarianceMatrix(covar);
1636 align->GetFitter6(is1,is0)->GetErrors(errors);
1641 if (npoints<minPoints) continue;
1644 if (is1/36>is0/36) weight*=2./3.; //IROC-OROC
1645 if (is1/36<is0/36) weight*=1./3.; //OROC-IROC
1646 if (is1/36==is0/36) weight*=1/3.; //OROC-OROC
1647 if (is1%36!=is0%36) weight*=1/2.; //Not up-down
1648 weight/=(errors[4]*errors[4]+sysError*sysError);
1651 TMatrixD matT = *mat;
1652 if (invers) matT.Invert();
1653 TMatrixD diffMat= (*(arrayAlign[is1]))*matT;
1654 diffMat-=(*arrayAlign[is0]);
1655 matDiff+=weight*diffMat;
1658 (*cstream)<<"LAlign"<<
1662 "npoints="<<npoints<<
1663 "m60.="<<arrayAlign[is0]<<
1664 "m61.="<<arrayAlign[is1]<<
1666 "diff.="<<&diffMat<<
1677 (*arrayAlignDiff[is0]) = matDiff;
1680 for (Int_t is0=0;is0<72; is0++) {
1681 if (is0<36) (*arrayAlign[is0]) += 0.4*(*arrayAlignDiff[is0]);
1682 if (is0>=36) (*arrayAlign[is0]) += 0.2*(*arrayAlignDiff[is0]);
1684 (*cstream)<<"GAlign"<<
1687 "m6.="<<arrayAlign[is0]<<
1692 for (Int_t isec=0;isec<72;isec++){
1693 fCombinedMatrixArray6.AddAt(arrayAlign[isec],isec);
1694 delete arrayAlignDiff[isec];
1702 gSystem->AddIncludePath("-I$ALICE_ROOT/TPC/macros");
1703 gROOT->LoadMacro("$ALICE_ROOT/TPC/macros/AliXRDPROOFtoolkit.cxx+")
1704 AliXRDPROOFtoolkit tool;
1705 TChain * chainTr = tool.MakeChain("align.txt","Track",0,10200);
1707 TChain * chainTracklet = tool.MakeChain("align.txt","Tracklet",0,20);
1708 chainTracklet->Lookup();
1711 TCut cutS0("sqrt(tp2.fC[0]+tp2.fC[0])<0.6");
1712 TCut cutS1("sqrt(tp2.fC[2]+tp2.fC[2])<0.6");
1713 TCut cutS2("sqrt(tp2.fC[5]+tp2.fC[5])<0.04");
1714 TCut cutS3("sqrt(tp2.fC[9]+tp2.fC[9])<0.02");
1715 TCut cutS4("sqrt(tp2.fC[14]+tp2.fC[14])<0.5");
1717 TCut cutS=cutS0+cutS1+cutS2+cutS3+cutS4;
1719 TCut cutP0("abs(tp1.fP[0]-tp2.fP[0])<0.6");
1720 TCut cutP1("abs(tp1.fP[1]-tp2.fP[1])<0.6");
1721 TCut cutP2("abs(tp1.fP[2]-tp2.fP[2])<0.02");
1722 TCut cutP3("abs(tp1.fP[3]-tp2.fP[3])<0.01");
1723 TCut cutE("abs(tp2.fP[1])<235");
1724 TCut cutP=cutP0+cutP1+cutP2+cutP3+cutE;
1729 TCut cutA = cutP+cutS;
1730 chainTr->Draw(">>listEL",cutA,"entryList");
1731 TEntryList *elist = (TEntryList*)gDirectory->Get("listEL");
1732 chainTr->SetEntryList(elist);
1739 TCut cutS("s1%36==s2%36");
1741 TCut cutN("c1>32&&c2>60");
1742 TCut cutC0("sqrt(tp2.fC[0])<1");
1744 TCut cutX("abs(tp2.fX-133.6)<2");
1746 TCut cutA = cutP+cutN;
1749 TCut cutY("abs(vcY.fElements-vtY.fElements)<0.3&&vcY.fElements!=0")
1750 TCut cutZ("abs(vcZ.fElements-vtZ.fElements)<0.3&&vcZ.fElements!=0")
1757 TCut cutA = cutP+cutS;
1758 chainTracklet->Draw(">>listEL",cutA,"entryList");
1759 TEntryList *elist = (TEntryList*)gDirectory->Get("listEL");
1760 chainTracklet->SetEntryList(elist);
1763 TVectorD * vec1 = 0;
1764 TVectorD * vec2 = 0;
1765 AliExternalTrackParam * tp1 = 0;
1766 AliExternalTrackParam * tp2 = 0;
1770 chainTracklet->GetBranch("v1.")->SetAddress(&vec1);
1771 chainTracklet->GetBranch("v2.")->SetAddress(&vec2);
1772 chainTracklet->GetBranch("s1")->SetAddress(&s1);
1773 chainTracklet->GetBranch("s2")->SetAddress(&s2);
1776 AliTPCcalibAlign align;
1778 for (Int_t i=0; i< elist->GetN(); i++){
1779 //for (Int_t i=0; i<100000; i++){
1780 chainTracklet->GetBranch("tp1.")->SetAddress(&tp1);
1781 chainTracklet->GetBranch("tp2.")->SetAddress(&tp2);
1782 chainTracklet->GetBranch("v1.")->SetAddress(&vec1);
1783 chainTracklet->GetBranch("v2.")->SetAddress(&vec2);
1784 chainTracklet->GetBranch("s1")->SetAddress(&s1);
1785 chainTracklet->GetBranch("s2")->SetAddress(&s2);
1787 chainTracklet->GetEntry(i);
1788 if (i%100==0) printf("%d\t%d\t%d\t%d\t\n",i,tentry, s1,s2);
1790 TLinearFitter * fitter = align.GetOrMakeFitter6(s1,s2);
1791 if (fitter) align.Process6(vec1->GetMatrixArray(),vec2->GetMatrixArray(),fitter);