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 TPC Kalman filter implementation for TPC sector alignment.
18 Output of the AliTPCcalibAlign is used as a input for TPC global alignment.
19 In AliTPCcalibAlign histograms - track parameter matching at sector boundaries are created.
20 Each sector is aligned with 5 neighborhoud (sectors)
24 Sector alignment parameters are obtained finding the alignment parameters, minimizing
25 misalignmnet for all piars fo sectors.
27 Global minimization- MakeGlobalAlign
31 gSystem->Load("libANALYSIS");
32 gSystem->Load("libTPCcalib");
35 .x ConfigCalibTrain.C(run)
36 calibDB = AliTPCcalibDB::Instance()
38 AliTPCkalmanAlign kalmanAlign("TPC align", "TPC align"); // create the object
39 kalmanAlign.ReadAlign("CalibObjects.root"); // read the calibration form file
40 kalmanAlign.MakeGlobalAlign(); // do kalman alignment
41 kalmanAlign.DrawDeltaAlign(); // make QA plot
47 #include "TTreeStream.h"
49 #include "TGraphErrors.h"
51 #include "TClonesArray.h"
54 #include "AliXRDPROOFtoolkit.h"
58 #include "AliTPCcalibDB.h"
59 #include "AliTPCCalROC.h"
60 #include "AliCDBMetaData.h"
62 #include "AliCDBManager.h"
63 #include "AliCDBStorage.h"
64 #include "AliCDBEntry.h"
65 #include "AliAlignObjParams.h"
66 #include "AliTPCROC.h"
67 #include "AliTracker.h"
69 #include "TLinearFitter.h"
70 #include "AliTPCcalibAlign.h"
72 #include "AliTPCCalPad.h"
73 #include "AliTPCkalmanAlign.h"
74 #include "TStatToolkit.h"
75 #include "AliTPCPreprocessorOnline.h"
76 #include "TPostScript.h"
77 #include "AliGRPObject.h"
79 AliTPCkalmanAlign::AliTPCkalmanAlign():
81 fCalibAlign(0), // kalman alignnmnt
82 fOriginalAlign(0), // original alignment 0 read for the OCDB
89 // Default constructor
91 for (Int_t i=0; i<4; i++){
97 AliTPCkalmanAlign::AliTPCkalmanAlign(const char* name, const char* title):
99 fCalibAlign(0), // kalman alignnmnt
100 fOriginalAlign(0), // original alignment 0 read for the OCDB
107 // Default constructor
109 for (Int_t i=0; i<4; i++){
113 fFitCEGlobal = new TObjArray(6);
114 fFitCELocal = new TObjArray(6);
115 for (Int_t ipar=0; ipar<6;ipar++){
116 fFitCEGlobal->AddAt(new TVectorD(36),ipar);
117 fFitCELocal->AddAt(new TVectorD(36),ipar);
121 void AliTPCkalmanAlign::ReadAlign(const char *fname){
123 // Read old alignment used in the reco
124 // and the residual histograms
125 // WE ASSUME that the OCDB path is set in the same way as done in the calibration
128 TObjArray * array = (TObjArray*)fcalib.Get("TPCCalib");
130 if (array) fCalibAlign=( AliTPCcalibAlign *)array->FindObject("alignTPC");
131 fCalibAlign = ( AliTPCcalibAlign *)fcalib.Get("alignTPC");
133 // old alignment used
134 AliCDBEntry * cdbEntry= AliCDBManager::Instance()->Get("TPC/Align/Data");
137 fOriginalAlign = (TClonesArray*)cdbEntry->GetObject();
142 void AliTPCkalmanAlign::BookAlign1D(TMatrixD ¶m, TMatrixD &covar, Double_t mean, Double_t sigma){
144 // Book Align 1D parameters and covariance
146 param.ResizeTo(72,1);
147 covar.ResizeTo(72,72);
148 for (Int_t i=0;i<72;i++){
150 for (Int_t j=0;j<72;j++) covar(i,j)=0;
151 covar(i,i)=sigma*sigma;
156 void AliTPCkalmanAlign::UpdateAlign1D(Double_t delta, Double_t sigma, Int_t s1, Int_t s2, TMatrixD &vecXk, TMatrixD &covXk){
158 // Update 1D kalman filter
160 const Int_t knMeas=1;
161 const Int_t knElem=72;
162 TMatrixD mat1(72,72); // update covariance matrix
163 TMatrixD matHk(1,knElem); // vector to mesurement
164 TMatrixD vecYk(knMeas,1); // Innovation or measurement residual
165 TMatrixD matHkT(knElem,knMeas); // helper matrix Hk transpose
166 TMatrixD matSk(knMeas,knMeas); // Innovation (or residual) covariance
167 TMatrixD matKk(knElem,knMeas); // Optimal Kalman gain
168 TMatrixD covXk2(knElem,knElem); // helper matrix
169 TMatrixD covXk3(knElem,knElem); // helper matrix
173 measR(0,0)=sigma*sigma;
176 for (Int_t iel=0;iel<knElem;iel++)
177 for (Int_t ip=0;ip<knMeas;ip++) matHk(ip,iel)=0;
179 for (Int_t iel=0;iel<knElem;iel++) {
180 for (Int_t jel=0;jel<knElem;jel++) mat1(iel,jel)=0;
186 vecYk = vecZk-matHk*vecXk; // Innovation or measurement residual
187 matHkT=matHk.T(); matHk.T();
188 matSk = (matHk*(covXk*matHkT))+measR; // Innovation (or residual) covariance
190 matKk = (covXk*matHkT)*matSk; // Optimal Kalman gain
191 vecXk += matKk*vecYk; // updated vector
192 covXk2= (mat1-(matKk*matHk));
193 covXk3 = covXk2*covXk;
200 void AliTPCkalmanAlign::MakeGlobalAlign(){
202 // Combine all pairs of fitters and make global alignemnt
205 AliTPCkalmanAlign &kalmanAlign=*this;
206 TTreeSRedirector *pcstream = new TTreeSRedirector("AliTPCkalmanAlign.root");
207 Int_t run = AliCDBManager::Instance()->GetRun();
208 AliGRPObject * grp = AliTPCcalibDB::Instance()->GetGRP(run);
209 Float_t bz = AliTracker::GetBz();
210 UInt_t timeS = grp->GetTimeStart();
211 UInt_t timeE = grp->GetTimeEnd();
212 UInt_t time = (timeS+timeE)/2;
217 AliTPCCalPad *padTime0 = AliTPCcalibDB::Instance()->GetPadTime0();
218 TVectorD paramCE[72];
219 TMatrixD covarCE[72];
220 Int_t statUpDown=0; // statistic up down
221 Int_t statLeftRight=0; // statistic left-right
223 for (Int_t isec=0; isec<72; isec++){
224 AliTPCCalROC * roc0 = padTime0->GetCalROC(isec);
225 roc0->GlobalFit(0,kFALSE,paramCE[isec],covarCE[isec],chi2,0);
226 (*pcstream)<<"ceFit"<<
228 "p0.="<<¶mCE[isec]<<
232 DumpOldAlignment(pcstream);
233 const Int_t kMinEntries=400;
236 kalmanAlign.BookAlign1D(vec[0],cov[0], 0,0.5);
237 kalmanAlign.BookAlign1D(vec[1],cov[1], 0,0.5);
238 kalmanAlign.BookAlign1D(vec[2],cov[2], 0,0.01);
239 kalmanAlign.BookAlign1D(vec[3],cov[3], 0,0.01);
245 for (Int_t is0=0;is0<72;is0++)
246 for (Int_t is1=0;is1<72;is1++){
249 his = kalmanAlign.fCalibAlign->GetHisto(AliTPCcalibAlign::kY,is0,is1);
251 if (his->GetEntries()<kMinEntries) continue;
252 delta[0]=his->GetMean();
253 rms[0]=his->GetRMS();
254 stat[0]=his->GetEntries();
255 kalmanAlign.UpdateAlign1D(his->GetMean(),his->GetRMS(),is0,is1, vec[0],cov[0]);
257 his = kalmanAlign.fCalibAlign->GetHisto(AliTPCcalibAlign::kZ,is0,is1);
259 delta[1]=his->GetMean();
260 rms[1]=his->GetRMS();
261 stat[1]=his->GetEntries();
262 kalmanAlign.UpdateAlign1D(his->GetMean(),his->GetRMS(),is0,is1, vec[1],cov[1]);
264 his = kalmanAlign.fCalibAlign->GetHisto(AliTPCcalibAlign::kPhi,is0,is1);
266 delta[2] = his->GetMean();
267 rms[2]=his->GetRMS();
268 stat[2]=his->GetEntries();
269 kalmanAlign.UpdateAlign1D(his->GetMean(),his->GetRMS(),is0,is1, vec[2],cov[2]);
271 his = kalmanAlign.fCalibAlign->GetHisto(AliTPCcalibAlign::kTheta,is0,is1);
273 delta[3] = his->GetMean();
274 rms[3]=his->GetRMS();
275 stat[3]=his->GetEntries();
276 kalmanAlign.UpdateAlign1D(his->GetMean(),his->GetRMS(),is0,is1, vec[3],cov[3]);
277 if (is1==is0+36) statUpDown+=Int_t(stat[0]);
278 if (is1==is0+35) statLeftRight+=Int_t(stat[0]);
281 fDelta1D[0] = (TMatrixD*)vec[0].Clone();
282 fDelta1D[1] = (TMatrixD*)vec[1].Clone();
283 fDelta1D[2] = (TMatrixD*)vec[2].Clone();
284 fDelta1D[3] = (TMatrixD*)vec[3].Clone();
286 fCovar1D[0] = (TMatrixD*)cov[0].Clone();
287 fCovar1D[1] = (TMatrixD*)cov[1].Clone();
288 fCovar1D[2] = (TMatrixD*)cov[2].Clone();
289 fCovar1D[3] = (TMatrixD*)cov[3].Clone();
292 MakeNewAlignment(kTRUE);
294 for (Int_t is0=0;is0<72;is0++)
295 for (Int_t is1=0;is1<72;is1++){
296 Bool_t isPair=kFALSE;
297 if (TMath::Abs(is0%18-is1%18)<2) isPair=kTRUE;
298 if (TMath::Abs(is0%18-is1%18)==17) isPair=kTRUE;
299 if (!isPair) continue;
300 stat[0]=0; stat[1]=0; stat[2]=0; stat[3]=0;
303 his = kalmanAlign.fCalibAlign->GetHisto(AliTPCcalibAlign::kY,is0,is1);
305 delta[0]=his->GetMean();
306 rms[0]=his->GetRMS();
307 stat[0]=his->GetEntries();
310 his = kalmanAlign.fCalibAlign->GetHisto(AliTPCcalibAlign::kZ,is0,is1);
312 delta[1]=his->GetMean();
313 rms[1]=his->GetRMS();
314 stat[1]=his->GetEntries();
317 his = kalmanAlign.fCalibAlign->GetHisto(AliTPCcalibAlign::kPhi,is0,is1);
319 delta[2] = his->GetMean();
320 rms[2]=his->GetRMS();
321 stat[2]=his->GetEntries();
324 his = kalmanAlign.fCalibAlign->GetHisto(AliTPCcalibAlign::kTheta,is0,is1);
326 delta[3] = his->GetMean();
327 rms[3]=his->GetRMS();
328 stat[3]=his->GetEntries();
330 TVectorD fceG[8],fceL[6];
332 for (Int_t ipar=0; ipar<8;ipar++){
333 fceG[ipar].ResizeTo(36);
334 if (ipar<6) fceL[ipar].ResizeTo(36);
335 if (fFitCEGlobal->At(ipar)){
336 fceG[ipar]=*((TVectorD*)fFitCEGlobal->At(ipar));
338 fceL[ipar]=*((TVectorD*)fFitCELocal->At(ipar));
343 (*pcstream)<<"kalmanAlignDebug"<<
344 "run="<<run<< // runs
345 "time="<<time<< // time
346 "timeE="<<timeE<< // sart of tun time
347 "timeS="<<timeS<< // end od run time
351 "delta.="<<&delta<< // alignment deltas
352 "rms.="<<&rms<< // rms
358 "pceIn0.="<<¶mCE[is0%36]<< // default CE parameters
359 "pceOut0.="<<¶mCE[is0%36+36]<<
360 "pceIn1.="<<¶mCE[is1%36]<<
361 "pceOut1.="<<¶mCE[is1%36+36]<<
362 // // current CE parameters form last calibration - not used in Reco
363 "fceG0.="<<&fceG[0]<< // global fit of CE - offset
364 "fceG1.="<<&fceG[1]<< // global fit of CE - Gy gradient
365 "fceG2.="<<&fceG[2]<< // global fit of CE - Gx gradient
366 "fceG3.="<<&fceG[3]<< // global fit of CE - IROC-OROC offset
367 "fceG4.="<<&fceG[4]<< // global fit of CE - commont slope LX
368 "fceG5.="<<&fceG[5]<< // global fit of CE - delta slope LX
369 "fceG6.="<<&fceG[6]<< // global fit of CE - common slope LY
370 "fceG7.="<<&fceG[7]<< // global fit of CE - delta slope LY
372 "fceL0.="<<&fceL[0]<< // local fit of CE - offset to mean
373 "fceL1.="<<&fceL[1]<< // local fit of CE - IROC-OROC offset
374 "fceL2.="<<&fceL[2]<< // local fit of CE - common slope LX
375 "fceL3.="<<&fceL[3]<< // local fit of CE - delta slope LX
376 "fceL4.="<<&fceL[4]<< // local fit of CE - common slope LY
377 "fceL5.="<<&fceL[5]<< // local fit of CE - delta slope LY
381 (*pcstream)<<"runSummary"<<
382 "run="<<run<< // run number
383 "bz="<<bz<< // bz field
384 "statUpDown="<<statUpDown<< // stat up-down
385 "statLeftRight="<<statLeftRight<< // stat left-right
396 void AliTPCkalmanAlign::UpdateOCDBTime0( AliTPCCalPad *pad, Int_t ustartRun, Int_t uendRun, const char* storagePath ){
399 // .x ConfigCalibTrain.C(117116)
400 // AliTPCcalibDB::Instance()->GetPulserTmean()
401 // pad->Add(-pad->GetMean())
402 AliCDBMetaData *metaData= new AliCDBMetaData();
403 metaData->SetObjectClassName("TObjArray");
404 metaData->SetResponsible("Marian Ivanov");
405 metaData->SetBeamPeriod(1);
406 metaData->SetAliRootVersion("05-25-01"); //root version
407 metaData->SetComment("Calibration of the z - time misalignment");
409 id1=new AliCDBId("TPC/Calib/PadTime0", ustartRun, uendRun);
410 AliCDBStorage* gStorage = AliCDBManager::Instance()->GetStorage(storagePath);
411 gStorage->Put(pad, (*id1), metaData);
416 void AliTPCkalmanAlign::DrawDeltaAlign(){
418 // Draw the reuslts of the alignment
419 // Residual misalignment in respect with previous alignment shown
422 TFile f("AliTPCkalmanAlign.root","update");
423 TTree * treeDelta = (TTree*)f.Get("kalmanAlignDebug");
424 TH1::AddDirectory(0);
426 treeDelta->SetAlias("sector","is0");
427 treeDelta->SetAlias("dYmeas","10*(delta.fElements[0])");
428 treeDelta->SetAlias("dZmeas","10*(delta.fElements[1])");
429 treeDelta->SetAlias("dPhimeas","1000*(delta.fElements[2])");
430 treeDelta->SetAlias("dThetameas","1000*(delta.fElements[3])");
432 treeDelta->SetAlias("dYfit","10*(vec0.fElements[is0]-vec0.fElements[is1])");
433 treeDelta->SetAlias("dZfit","10*(vec1.fElements[is0]-vec1.fElements[is1])");
434 treeDelta->SetAlias("dPhifit","1000*(vec2.fElements[is0]-vec2.fElements[is1])");
435 treeDelta->SetAlias("dThetafit","1000*(vec3.fElements[is0]-vec3.fElements[is1])");
437 treeDelta->SetMarkerStyle(25);
438 treeDelta->SetMarkerColor(4);
439 treeDelta->SetLineColor(4);
440 const char *type[3]={"up-down","left-right","right-left"};
441 const char *gropt[3]={"alp","lp","lp"};
442 const char *varTypeY[3]={"dYmeas-dYfit:sector","dYfit:sector","10*vec0.fElements[is0]:sector"};
443 const char *varLegendY[3]={"#Delta_{y} fit residual","#Delta_{y} fit value difference","#Delta_{y} sector"};
444 const char *varTypeZ[3]={"dZmeas-dZfit:sector","dZfit:sector","10*vec1.fElements[is0]:sector"};
445 const char *varLegendZ[3]={"#Delta_{Z} fit residual","#Delta_{Z} fit value difference","#Delta_{Z} sector"};
446 const char *varTypeT[3]={"dThetameas-dThetafit:sector","dThetafit:sector","1000*vec3.fElements[is0]:sector"};
447 const char *varLegendT[3]={"#Delta_{#theta} fit residual","#Delta_{#theta} fit value difference","#Delta_{#theta} sector"};
448 const char *varTypeP[3]={"dPhimeas-dPhifit:sector","dPhifit:sector","1000*vec2.fElements[is0]:sector"};
449 const char *varLegendP[3]={"#Delta_{#phi} fit residual","#Delta_{#phi} fit value difference","#Delta_{#phi} sector"};
451 Int_t grcol[3]={2,1,4};
453 TGraph *grDelta[3]={0,0,0};
454 TCanvas * canvasDy=new TCanvas("canvasDy","canvasDy",1200,800);
455 TCanvas * canvasDz=new TCanvas("canvasDz","canvasDz",1200,800);
456 TCanvas * canvasDphi=new TCanvas("canvasDphi","canvasDphi",1200,800);
457 TCanvas * canvasDtheta=new TCanvas("canvasDtheta","canvasDtheta",1200,800);
458 canvasDy->Divide(2,2);
459 canvasDz->Divide(2,2);
460 canvasDtheta->Divide(2,2);
461 canvasDphi->Divide(2,2);
467 treeDelta->Draw("dYmeas:dYfit");
468 for (Int_t itype=0; itype<3; itype++){
469 canvasDy->cd(itype+2);
470 entries=treeDelta->Draw(varTypeY[itype],"is1==is0+36","goff");
471 grDelta[0]=new TGraph(entries,treeDelta->GetV2(),treeDelta->GetV1());
472 entries=treeDelta->Draw(varTypeY[itype],"is1==is0+35","goff");
473 grDelta[1]=new TGraph(entries,treeDelta->GetV2(),treeDelta->GetV1());
474 entries=treeDelta->Draw(varTypeY[itype],"is1==is0+37","goff");
475 grDelta[2]=new TGraph(entries,treeDelta->GetV2(),treeDelta->GetV1());
476 legend = new TLegend(0.5,0.7,0.9,0.9, varLegendY[itype]);
477 for (Int_t i=0; i<3; i++) {
478 grDelta[i]->SetMaximum(1.5);
479 grDelta[i]->SetMinimum(-1);
480 grDelta[i]->SetTitle(type[i]);
481 grDelta[i]->SetMarkerColor(grcol[i]);
482 grDelta[i]->SetLineColor(grcol[i]);
483 grDelta[i]->SetMarkerStyle(25+i);
484 grDelta[i]->GetXaxis()->SetTitle("sector");
485 grDelta[i]->GetYaxis()->SetTitle("#Delta_{y} (mm)");
486 if (itype==2 && i>0) continue;
487 grDelta[i]->Draw(gropt[i]);
488 legend->AddEntry(grDelta[i]);
497 treeDelta->Draw("dZmeas:dZfit");
498 for (Int_t itype=0; itype<3; itype++){
499 canvasDz->cd(itype+2);
500 entries=treeDelta->Draw(varTypeZ[itype],"is1==is0+36","goff");
501 grDelta[0]=new TGraph(entries,treeDelta->GetV2(),treeDelta->GetV1());
502 entries=treeDelta->Draw(varTypeZ[itype],"is1==is0+35","goff");
503 grDelta[1]=new TGraph(entries,treeDelta->GetV2(),treeDelta->GetV1());
504 entries=treeDelta->Draw(varTypeZ[itype],"is1==is0+37","goff");
505 grDelta[2]=new TGraph(entries,treeDelta->GetV2(),treeDelta->GetV1());
506 legend = new TLegend(0.5,0.7,0.9,0.9, varLegendZ[itype]);
507 for (Int_t i=0; i<3; i++) {
508 grDelta[i]->SetMaximum(1.5);
509 grDelta[i]->SetMinimum(-1);
510 grDelta[i]->SetTitle(type[i]);
511 grDelta[i]->SetMarkerColor(grcol[i]);
512 grDelta[i]->SetLineColor(grcol[i]);
513 grDelta[i]->SetMarkerStyle(25+i);
514 grDelta[i]->GetXaxis()->SetTitle("sector");
515 grDelta[i]->GetYaxis()->SetTitle("#Delta_{z} (mm)");
516 if (itype==2 && i>0) continue;
517 grDelta[i]->Draw(gropt[i]);
518 legend->AddEntry(grDelta[i]);
527 treeDelta->Draw("dThetameas:dThetafit");
528 for (Int_t itype=0; itype<3; itype++){
529 canvasDtheta->cd(itype+2);
530 entries=treeDelta->Draw(varTypeT[itype],"is1==is0+36","goff");
531 grDelta[0]=new TGraph(entries,treeDelta->GetV2(),treeDelta->GetV1());
532 entries=treeDelta->Draw(varTypeT[itype],"is1==is0+35","goff");
533 grDelta[1]=new TGraph(entries,treeDelta->GetV2(),treeDelta->GetV1());
534 entries=treeDelta->Draw(varTypeT[itype],"is1==is0+37","goff");
535 grDelta[2]=new TGraph(entries,treeDelta->GetV2(),treeDelta->GetV1());
536 legend = new TLegend(0.5,0.7,0.9,0.9, varLegendT[itype]);
537 for (Int_t i=0; i<3; i++) {
538 grDelta[i]->SetMaximum(4.);
539 grDelta[i]->SetMinimum(-3.);
540 grDelta[i]->SetTitle(type[i]);
541 grDelta[i]->SetMarkerColor(grcol[i]);
542 grDelta[i]->SetLineColor(grcol[i]);
543 grDelta[i]->SetMarkerStyle(25+i);
544 grDelta[i]->GetXaxis()->SetTitle("sector");
545 grDelta[i]->GetYaxis()->SetTitle("#Delta_{#theta} (mrad)");
546 if (itype==2 && i>0) continue;
547 grDelta[i]->Draw(gropt[i]);
548 legend->AddEntry(grDelta[i]);
558 treeDelta->Draw("dPhimeas:dPhifit");
559 for (Int_t itype=0; itype<3; itype++){
560 canvasDphi->cd(itype+2);
561 entries=treeDelta->Draw(varTypeP[itype],"is1==is0+36","goff");
562 grDelta[0]=new TGraph(entries,treeDelta->GetV2(),treeDelta->GetV1());
563 entries=treeDelta->Draw(varTypeP[itype],"is1==is0+35","goff");
564 grDelta[1]=new TGraph(entries,treeDelta->GetV2(),treeDelta->GetV1());
565 entries=treeDelta->Draw(varTypeP[itype],"is1==is0+37","goff");
566 grDelta[2]=new TGraph(entries,treeDelta->GetV2(),treeDelta->GetV1());
567 legend = new TLegend(0.5,0.7,0.9,0.9, varLegendP[itype]);
568 for (Int_t i=0; i<3; i++) {
569 grDelta[i]->SetMaximum(4.);
570 grDelta[i]->SetMinimum(-3.);
571 grDelta[i]->SetTitle(type[i]);
572 grDelta[i]->SetMarkerColor(grcol[i]);
573 grDelta[i]->SetLineColor(grcol[i]);
574 grDelta[i]->SetMarkerStyle(25+i);
575 grDelta[i]->GetXaxis()->SetTitle("sector");
576 grDelta[i]->GetYaxis()->SetTitle("#Delta_{#phi} (mrad)");
577 if (itype==2 && i>0) continue;
578 grDelta[i]->Draw(gropt[i]);
579 legend->AddEntry(grDelta[i]);
588 canvasDtheta->Write();
593 TPostScript *ps = new TPostScript("alignReport.ps", 112);
599 canvasDtheta->Draw();
608 void AliTPCkalmanAlign::DumpOldAlignment(TTreeSRedirector *pcstream){
609 // Dump the content of old alignemnt
610 // Expected that the old alignmnet is loaded
612 if (!fOriginalAlign) return;
614 TVectorD localTrans(3);
615 TVectorD globalTrans(3);
616 TVectorD localRot(3);
617 TVectorD globalRot(3);
618 AliGeomManager::ELayerID idLayer;
621 for (Int_t i=0; i<fOriginalAlign->GetEntries();i++){
622 AliAlignObjParams *params = (AliAlignObjParams*)fOriginalAlign->At(i);
623 params->GetVolUID(idLayer,idModule);
624 params->GetLocalTranslation(localTrans.GetMatrixArray());
625 params->GetLocalAngles(localRot.GetMatrixArray());
626 params->GetTranslation(globalTrans.GetMatrixArray());
627 params->GetAngles(globalRot.GetMatrixArray());
628 Int_t sector=idModule;
629 if (idLayer>7) sector+=36;
630 (*pcstream)<<"oldAlign"<<
631 //"idLayer="<<idLayer<<
632 "idModule="<<idModule<<
634 "lT.="<<&localTrans<<
635 "gT.="<<&localTrans<<
643 void AliTPCkalmanAlign::MakeNewAlignment(Bool_t badd, TTreeSRedirector * pcstream){
645 // make a new Alignment entry
647 if (!fOriginalAlign) return;
649 TVectorD localTrans(3);
650 TVectorD globalTrans(3);
651 TVectorD localRot(3);
652 TVectorD globalRot(3);
654 TVectorD localTransNew(3); // new entries
655 TVectorD globalTransNew(3);
656 TVectorD localRotNew(3);
657 TVectorD globalRotNew(3);
659 AliGeomManager::ELayerID idLayer;
662 fNewAlign = (TClonesArray*)fOriginalAlign->Clone();
663 for (Int_t i=0; i<fOriginalAlign->GetEntries();i++){
664 AliAlignObjParams *params = (AliAlignObjParams*)fOriginalAlign->At(i);
665 //AliAlignObjParams *paramsNew = (AliAlignObjParams*)fNewAlign->At(i);
666 params->GetVolUID(idLayer,idModule);
667 Int_t sector=(Int_t)idModule;
668 if (idLayer>7) sector+=36;
669 params->GetLocalTranslation(localTrans.GetMatrixArray());
670 params->GetLocalAngles(localRot.GetMatrixArray());
671 params->GetTranslation(globalTrans.GetMatrixArray());
672 params->GetAngles(globalRot.GetMatrixArray());
676 if (badd){ // addition if
677 localTransNew=localTrans;
678 localRotNew=localRot;
680 localTransNew[1]=localTransNew[1]-((*fDelta1D[0])(sector,0));
681 localRot[0] =localRot[0]-(*fDelta1D[2])(sector,0);
683 if (pcstream) (*pcstream)<<"alignParams"<<
684 //"idLayer="<<idLayer<<
685 "idModule="<<idModule<<
687 "olT.="<<&localTrans<<
689 "ogT.="<<&localTrans<<
690 "ogR.="<<&globalRot<<
691 "nlT.="<<&localTransNew<<
692 "nlR.="<<&localRotNew<<
693 "ngT.="<<&localTransNew<<
694 "ngR.="<<&globalRotNew<<
701 void AliTPCkalmanAlign::DrawAlignmentTrends(){
703 // Draw trends of alingment variables
706 //1. Create a list of align data
709 AliXRDPROOFtoolkit::FilterList("align.list","AliTPCkalmanAlign.root kalmanAlignDebug",0);
712 AliXRDPROOFtoolkit toolkit;
713 TChain * chain = toolkit.MakeChainRandom("align.list.Good","kalmanAlignDebug",0,2000);
714 TChain * chainRef = toolkit.MakeChainRandom("alignRef.list","kalmanAlignDebug",0,2000);
715 chain->AddFriend(chainRef,"R");
716 chainRef->AddFriend(chainRef,"T");
718 TCut cutS="stat.fElements[0]>200&&stat.fElements[1]>200&&stat.fElements[3]>200&&stat.fElements[3]>200"; //statistic in the bin
719 TCut cutST="T.stat.fElements[0]>200&&T.stat.fElements[1]>200&&T.stat.fElements[3]>200&&T.stat.fElements[3]>200"; //statistic in the bin
720 // TTree *tree = chain->CopyTree(cutS);
721 //TTree *treeR = chainRef->CopyTree(cutST);
723 TCanvas * canvasDy= new TCanvas("canvasDy","canvasDy");
726 // Int_t grcol[3]={2,1,4};
728 legend = new TLegend(0.7,0.6,0.9,0.9, "Alignment #Delta_{y}- Up-Down");
729 for (Int_t isec=0; isec<18; isec+=2){
730 chain->SetMarkerColor(1+(isec%5));
731 chain->SetMarkerStyle(isec+20);
732 chain->Draw("10*(delta.fElements[0]-R.delta.fElements[0]):run",cutS+Form("is1==is0+36&&is0==%d",isec),"profgoff");
733 his = (TH1*)(chain->GetHistogram()->Clone());
734 his->SetName(Form("#Delta_{Y} sector %d",isec));
735 his->SetTitle(Form("#Delta_{Y} sector %d",isec));
737 his->SetMinimum(-1.);
738 his->GetYaxis()->SetTitle("#Delta_{y} (mm)");
739 his->GetXaxis()->SetTitle("run Number");
740 if (isec==0) his->Draw("");
741 if (isec>0) his->Draw("same");
742 legend->AddEntry(his);
753 void AliTPCkalmanAlign::FitCE(){
756 // 1. Global fit - gy and gx
757 // 2. Local X fit common
760 AliTPCPreprocessorOnline * preprocesor = new AliTPCPreprocessorOnline;
762 AliTPCCalPad *padTime0 = AliTPCcalibDB::Instance()->GetPadTime0();
763 AliTPCCalPad *padNoise = AliTPCcalibDB::Instance()->GetPadNoise();
764 AliTPCCalPad * ceTmean = AliTPCcalibDB::Instance()->GetCETmean(); // CE information
765 AliTPCCalPad * ceTrms = AliTPCcalibDB::Instance()->GetCETrms();
766 AliTPCCalPad * ceQmean = AliTPCcalibDB::Instance()->GetCEQmean();
767 AliTPCCalPad * pulserTmean = AliTPCcalibDB::Instance()->GetPulserTmean(); //
768 AliTPCCalPad * pulserTrms = AliTPCcalibDB::Instance()->GetPulserTrms();
769 AliTPCCalPad * pulserQmean = AliTPCcalibDB::Instance()->GetPulserQmean();
770 AliTPCCalPad * dmap0 = AliTPCcalibDB::Instance()->GetDistortionMap(0); // distortion maps
771 AliTPCCalPad * dmap1 = AliTPCcalibDB::Instance()->GetDistortionMap(1);
772 AliTPCCalPad * dmap2 = AliTPCcalibDB::Instance()->GetDistortionMap(2);
773 pulserTmean->Add(-pulserTmean->GetMean());
775 preprocesor->AddComponent(padTime0->Clone());
776 preprocesor->AddComponent(padNoise->Clone());
777 preprocesor->AddComponent(pulserTmean->Clone());
778 preprocesor->AddComponent(pulserQmean->Clone());
779 preprocesor->AddComponent(pulserTrms->Clone());
780 preprocesor->AddComponent(ceTmean->Clone());
781 preprocesor->AddComponent(ceQmean->Clone());
782 preprocesor->AddComponent(ceTrms->Clone());
783 preprocesor->AddComponent(dmap0->Clone());
784 preprocesor->AddComponent(dmap1->Clone());
785 preprocesor->AddComponent(dmap2->Clone());
786 preprocesor->DumpToFile("cetmean.root");
788 TCut cutNoise="abs(PadNoise.fElements/PadNoise_Median-1)<0.3";
789 TCut cutPulserT="abs(PulserTrms.fElements/PulserTrms_Median-1)<0.2";
790 TCut cutPulserQ="abs(PulserQmean.fElements/PulserQmean_Median-1)<0.2";
791 TCut cutCEQ="CEQmean.fElements>50";
792 TCut cutCET="abs(CETmean.fElements)<2";
793 TCut cutAll=cutNoise+cutPulserT+cutPulserQ+cutCEQ+cutCET;
796 TFile * f = new TFile("cetmean.root");
797 TTree * chain = (TTree*) f->Get("calPads");
798 Int_t entries = chain->Draw("1",cutAll,"goff");
799 if (entries<200000) return; // no calibration available - pulser or CE or noise
801 TStatToolkit toolkit;
808 AliTPCkalmanAlign::MakeAliasCE(chain);
809 TString fstringG=""; // global part
811 fstringG+="Gy++"; // 1 - global y
812 fstringG+="Gx++"; // 2 - global x
814 fstringG+="isin++"; // 3 -delta IROC-OROC offset
815 fstringG+="Lx++"; // 4 -common slope
816 fstringG+="Lx*isin++"; // 5 -delta slope
817 fstringG+="Ly++"; // 6 -common slope
818 fstringG+="Ly*isin++"; // 7 -delta slope
821 TString * strFitLX=0;
823 strFitG = TStatToolkit::FitPlane(chain,"deltaT", fstringG.Data(),"sideA"+cutAll, chi2,npoints,vecG[0],covar,-1,0, 10000000, kFALSE);
824 chain->SetAlias("tfitGA",strFitG->Data());
825 strFitG->Tokenize("++")->Print();
826 printf("chi2=%f\n",TMath::Sqrt(chi2/npoints));
828 strFitG = TStatToolkit::FitPlane(chain,"deltaT", fstringG.Data(),"sideC"+cutAll, chi2,npoints,vecG[1],covar,-1,0, 10000000, kFALSE);
829 chain->SetAlias("tfitGC",strFitG->Data());
830 strFitG->Tokenize("++")->Print();
831 printf("chi2=%f\n",TMath::Sqrt(chi2/npoints));
833 AliTPCCalPad *padFitG =AliTPCCalPad::CreateCalPadFit("1++gy/500.++gx/500.++0+++0++0++0++0",vecG[0],vecG[1]);
834 AliTPCCalPad *padFitLX=AliTPCCalPad::CreateCalPadFit("0++0++0++(sector<36)++(lx-133)/100++(sector<36)*(lx-133)/100.++(ly)/100++(sector<36)*(ly)/100.",vecG[0],vecG[1]);
835 // swap a side and c side
836 AliTPCCalPad *padFitGSwap =AliTPCCalPad::CreateCalPadFit("1++gy/500.++gx/500.++0+++0++0++0++0",vecG[1],vecG[0]);
837 AliTPCCalPad *padFitLXSwap=AliTPCCalPad::CreateCalPadFit("0++0++0++(sector<36)++(lx-133)/100++(sector<36)*(lx-133)/100.++(ly)/100++(sector<36)*(ly)/100.",vecG[1],vecG[0]);
838 padFitG->SetName("CEG");
839 padFitLX->SetName("CELX");
840 padFitGSwap->SetName("CEGS");
841 padFitLXSwap->SetName("CELXS");
842 preprocesor->AddComponent(padFitG->Clone());
843 preprocesor->AddComponent(padFitLX->Clone());
844 preprocesor->AddComponent(padFitGSwap->Clone());
845 preprocesor->AddComponent(padFitLXSwap->Clone());
846 preprocesor->DumpToFile("cetmean.root"); // add it to the file
850 f = new TFile("cetmean.root");
851 chain = (TTree*) f->Get("calPads");
852 AliTPCkalmanAlign::MakeAliasCE(chain);
853 TString fstringL=""; // local fit
854 // // 0. delta common
855 fstringL+="isin++"; // 1. delta IROC-OROC offset
856 fstringL+="Lx++"; // 2. common slope
857 fstringL+="Lx*isin++"; // 3. delta slope
858 fstringL+="Ly++"; // 4. common slope
859 fstringL+="Ly*isin++"; // 5. delta slope
862 AliTPCCalPad *padFitLCE = new AliTPCCalPad("LocalCE","LocalCE");
863 AliTPCCalPad *padFitTmpCE;
864 for (Int_t isec=0; isec<36; isec++){
865 TCut cutSector=Form("(sector%36)==%d",isec);
866 strFitLX = TStatToolkit::FitPlane(chain,"deltaT-CEG.fElements-CELX.fElements", fstringL.Data(),cutSector+cutAll+"abs(deltaT-CEG.fElements-CELX.fElements)<0.4", chi2,npoints,vecL[isec],covar,-1,0, 10000000, kFALSE);
867 printf("sec=%d\tchi2=%f\n",isec,TMath::Sqrt(chi2/npoints));
869 TString fitL=Form("((sector%36)==%d)++((sector%36)==%d)*(sector<36)++((sector%36)==%d)*(lx-133)/100.++((sector%36)==%d)*(sector<36)*(lx-133)/100.++((sector%36)==%d)*(ly)/100.++((sector%36)==%d)*(sector<36)*(ly)/100.",isec,isec,isec,isec);
870 if (isec<18) padFitTmpCE=AliTPCCalPad::CreateCalPadFit(fitL.Data(),vecL[isec],dummy);
871 if (isec>=18) padFitTmpCE=AliTPCCalPad::CreateCalPadFit(fitL.Data(),dummy,vecL[isec]);
872 padFitLCE->Add(padFitTmpCE);
875 padFitLCE->SetName("CELocal");
876 preprocesor->AddComponent(padFitLCE->Clone());
877 preprocesor->DumpToFile("cetmean.root"); // add it to the file
879 // write data to array
881 fFitCELocal = new TObjArray(6);
882 fFitCEGlobal = new TObjArray(8);
883 for (Int_t ipar=0; ipar<8;ipar++){
885 fFitCEGlobal->AddAt(new TVectorD(36),ipar);
886 TVectorD &fvecG = *((TVectorD*)fFitCEGlobal->At(ipar));
887 for (Int_t isec=0; isec<36;isec++){
888 if (isec<18) fvecG[isec]=vecG[0][ipar];
889 if (isec>=18) fvecG[isec]=vecG[1][ipar];
892 fFitCELocal->AddAt(new TVectorD(36),ipar);
893 TVectorD &fvecL = *((TVectorD*)fFitCELocal->At(ipar));
894 for (Int_t isec=0; isec<36;isec++){
895 fvecL[isec]=vecL[isec][ipar];
901 void AliTPCkalmanAlign::MakeAliasCE(TTree * chain){
903 // make a aliases of pad variables
905 chain->SetAlias("side","(-1+(sector%36<18)*2)");
906 chain->SetAlias("sideA","(sector%36<18)");
907 chain->SetAlias("sideC","(sector%36>=18)");
908 chain->SetAlias("isin","(sector<36)");
909 chain->SetAlias("deltaT","CETmean.fElements-PulserTmean.fElements");
910 chain->SetAlias("timeP","PulserTmean.fElements");
911 chain->SetAlias("Gy","(gy.fElements/500.)");
912 chain->SetAlias("Gx","(gx.fElements/500.)");
913 chain->SetAlias("Lx","(lx.fElements-133)/100."); // lx in meters
914 chain->SetAlias("Ly","(ly.fElements)/100.");
915 chain->SetAlias("La","(ly.fElements/lx.fElements/0.155)");
916 chain->SetAlias("deltaT","(CETmean.fElements-PulserTmean.fElements)");