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 // AliTPCCalibGlobalMisalignment class //
20 // The class calculates the space point distortions due to simple //
21 // misalignments like shifts in caresian coordinates or a rotation //
22 // of the TPC read out planes (A and C side) //
23 // Optionaly possible to use it for visualization of the alignemnt form the Alignment OCDB //
24 // fUseGeoManager has to be set to kTRUE to enable this option
26 // date: 06/05/2010 //
27 // Authors: Stefan Rossegger, Jim Thomas, Magnus Mager //
28 ////////////////////////////////////////////////////////////////////////////
30 #include "AliTPCCalibGlobalMisalignment.h"
32 #include "TGeoMatrix.h"
33 #include "AliTPCROC.h"
34 #include "AliTPCcalibDB.h"
35 #include "AliTPCParam.h"
36 #include <TGeoPhysicalNode.h>
38 #include "AliAlignObjParams.h"
39 #include "AliGeomManager.h"
40 #include "AliCDBManager.h"
41 #include "AliCDBEntry.h"
43 AliTPCCalibGlobalMisalignment::AliTPCCalibGlobalMisalignment()
44 : AliTPCCorrection("mialign","Misalignment"),
45 fXShift(0.),fYShift(0.),fZShift(0.),
46 fRotPhiA(0.),fRotPhiC(0.),
49 fQuadrantQ0(0), //OROC medium pads -delta ly+ - ly - shift
50 fQuadrantRQ0(0), //OROC medium pads -delta ly+ - ly - rotation
51 fQuadrantQ1(0), //OROC long pads -delta ly+ - ly - shift
52 fQuadrantQ2(0), //OROC long pads -shift
53 fQuadrantRQ1(0), //OROC long pads -delta ly+ - ly - rotation
54 fQuadrantRQ2(0), //OROC long pads -rotation
55 fMatrixGlobal(0), // global Alignment common
56 fMatrixGlobalDelta(0), // global Alignment Delta A side-c side
57 fArraySector(0) // fArraySector
60 // default constructor
64 AliTPCCalibGlobalMisalignment::~AliTPCCalibGlobalMisalignment() {
68 delete fQuadrantQ0; //OROC medium pads -delta ly+ - ly - shift
69 delete fQuadrantRQ0; //OROC medium pads -delta ly+ - ly - rotation
70 delete fQuadrantQ1; //OROC long pads -delta ly+ - ly - shift
71 delete fQuadrantQ2; //OROC long pads -shift
72 delete fQuadrantRQ1; //OROC long pads -delta ly+ - ly - rotation
73 delete fQuadrantRQ2; //OROC long pads -rotation
74 delete fMatrixGlobal; // global matrix
75 delete fMatrixGlobal; // global matrix
76 delete fArraySector; // sector matrices
81 Bool_t AliTPCCalibGlobalMisalignment::AddCorrectionCompact(AliTPCCorrection* corr, Double_t weight){
83 // Add correction and make them compact
85 // - origin of distortion/correction are additive
86 // - only correction ot the same type supported ()
88 //AliError("Zerro pointer - correction");
91 AliTPCCalibGlobalMisalignment* corrC = dynamic_cast<AliTPCCalibGlobalMisalignment *>(corr);
93 //AliError(TString::Format("Inconsistent class types: %s\%s",IsA()->GetName(),corr->IsA()->GetName()).Data());
97 AliTPCCalibGlobalMisalignment & add = *corrC;
98 fXShift+=weight*add.fXShift; // Shift in global X [cm]
99 fYShift+=weight*add.fYShift; // Shift in global Y [cm]
100 fZShift+=weight*add.fZShift; // Shift in global Z [cm]
102 fRotPhiA+=weight*add.fRotPhiA; // simple rotation of A side read-out plane around the Z axis [rad]
103 fRotPhiC+=weight*add.fRotPhiC; // simple rotation of C side read-out plane around the Z axis [rad]
104 fdRPhiOffsetA+=weight*add.fdRPhiOffsetA; // add a constant offset of dRPhi (or local Y) in [cm]: purely for calibration purposes!
105 fdRPhiOffsetC+=weight*add.fdRPhiOffsetC; // add a constant offset of dRPhi (or local Y) in [cm]: purely for calibration purposes!
107 // Quadrant alignment
109 if (add.fQuadrantQ0) {
110 if (fQuadrantQ0) fQuadrantQ0->Add(weight*(*(add.fQuadrantQ0)));
112 fQuadrantQ0 = (TVectorD*)(add.fQuadrantQ0->Clone());
113 (*fQuadrantQ0)*=weight;
116 if (add.fQuadrantRQ0) {
117 if (fQuadrantRQ0) fQuadrantRQ0->Add(weight*(*(add.fQuadrantRQ0)));
119 fQuadrantRQ0 = (TVectorD*)(add.fQuadrantRQ0->Clone());
120 (*fQuadrantRQ0)*=weight;
124 if (add.fQuadrantQ1) {
125 if (fQuadrantQ1) fQuadrantQ1->Add(weight*(*(add.fQuadrantQ1)));
127 fQuadrantQ1 = (TVectorD*)(add.fQuadrantQ1->Clone());
128 (*fQuadrantQ1)*=weight;
131 if (add.fQuadrantRQ1) {
132 if (fQuadrantRQ1) fQuadrantRQ1->Add(weight*(*(add.fQuadrantRQ1)));
134 fQuadrantRQ1 = (TVectorD*)(add.fQuadrantRQ1->Clone());
135 (*fQuadrantRQ1)*=weight;
139 if (add.fQuadrantQ2) {
140 if (fQuadrantQ2) fQuadrantQ2->Add(weight*(*(add.fQuadrantQ2)));
142 fQuadrantQ2 = (TVectorD*)(add.fQuadrantQ2->Clone());
143 (*fQuadrantQ2)*=weight;
146 if (add.fQuadrantRQ2) {
147 if (fQuadrantRQ2) fQuadrantRQ2->Add(weight*(*(add.fQuadrantRQ2)));
149 fQuadrantRQ2 = (TVectorD*)(add.fQuadrantRQ2->Clone());
150 (*fQuadrantQ2)*=weight;
154 // Global alignment - use native ROOT representation
156 Double_t delta[3]={0};
157 if (add.fMatrixGlobal){
158 TGeoHMatrix matrixW=*(add.fMatrixGlobal);
159 TGeoHMatrix matrixScaled;
160 const Double_t *rotMatrix = matrixW.GetRotationMatrix();
161 const Double_t *transMatrix = matrixW.GetTranslation();
162 matrixScaled.RotateZ(-rotMatrix[1]*TMath::RadToDeg()*weight);
163 matrixScaled.RotateY(rotMatrix[2]*TMath::RadToDeg()*weight);
164 matrixScaled.RotateX(-rotMatrix[5]*TMath::RadToDeg()*weight);
165 for (Int_t i=0; i<3; i++) delta[i]=weight*transMatrix[i];
166 matrixScaled.SetTranslation(delta);
167 // (matrixScaled*matrixW).Print(); in case weight -1 should be unit matrix
169 if (!fMatrixGlobal) {
170 fMatrixGlobal = new TGeoHMatrix(matrixScaled);
172 ((TGeoHMatrix*)fMatrixGlobal)->Multiply(&matrixScaled);
175 if (add.fMatrixGlobalDelta){
176 TGeoHMatrix matrixW=*(add.fMatrixGlobalDelta);
177 TGeoHMatrix matrixScaled;
178 const Double_t *rotMatrix = matrixW.GetRotationMatrix();
179 const Double_t *transMatrix = matrixW.GetTranslation();
180 matrixScaled.RotateZ(-rotMatrix[1]*TMath::RadToDeg()*weight);
181 matrixScaled.RotateY(rotMatrix[2]*TMath::RadToDeg()*weight);
182 matrixScaled.RotateX(-rotMatrix[5]*TMath::RadToDeg()*weight);
183 for (Int_t i=0; i<3; i++) delta[i]=weight*transMatrix[i];
184 matrixScaled.SetTranslation(delta);
185 // (matrixScaled*matrixW).Print(); in case weight -1 should be unit matrix
187 if (!fMatrixGlobalDelta) {
188 fMatrixGlobalDelta = new TGeoHMatrix(matrixScaled);
190 ((TGeoHMatrix*)fMatrixGlobalDelta)->Multiply(&matrixScaled);
193 if (add.fArraySector){
195 fArraySector = new TObjArray(72);
196 for (Int_t isec=0; isec<72; isec++) fArraySector->AddAt(new TGeoHMatrix,isec);
198 for (Int_t isec=0; isec<72; isec++){
199 TGeoHMatrix *mat0= (TGeoHMatrix*)fArraySector->At(isec);
200 TGeoHMatrix *mat1= (TGeoHMatrix*)add.fArraySector->At(isec);
202 TGeoHMatrix matrixW=*(mat1);
203 TGeoHMatrix matrixScaled;
204 const Double_t *rotMatrix = matrixW.GetRotationMatrix();
205 const Double_t *transMatrix = matrixW.GetTranslation();
206 matrixScaled.RotateZ(-rotMatrix[1]*TMath::RadToDeg()*weight);
207 matrixScaled.RotateY(rotMatrix[2]*TMath::RadToDeg()*weight);
208 matrixScaled.RotateX(-rotMatrix[5]*TMath::RadToDeg()*weight);
209 for (Int_t i=0; i<3; i++) delta[i]=weight*transMatrix[i];
210 matrixScaled.SetTranslation(delta);
211 mat0->Multiply(&matrixScaled);
222 void AliTPCCalibGlobalMisalignment::SetQuadranAlign(const TVectorD *quadrantQ0, const TVectorD *quadrantRQ0, const TVectorD *quadrantQ1,const TVectorD *quadrantRQ1, const TVectorD *quadrantQ2, const TVectorD *quadrantRQ2){
224 // Set quadrant alignment
225 // 6 vectors for 36 (super) sectors
227 if (quadrantQ0) fQuadrantQ0 = new TVectorD(*quadrantQ0);
228 if (quadrantRQ0) fQuadrantRQ0 = new TVectorD(*quadrantRQ0);
230 if (quadrantQ1) fQuadrantQ1 = new TVectorD(*quadrantQ1);
231 if (quadrantQ1) fQuadrantRQ1 = new TVectorD(*quadrantRQ1);
232 if (quadrantQ2) fQuadrantQ2 = new TVectorD(*quadrantQ2);
233 if (quadrantQ2) fQuadrantRQ2 = new TVectorD(*quadrantRQ2);
238 void AliTPCCalibGlobalMisalignment::SetAlignGlobal(const TGeoMatrix * matrixGlobal){
240 // Set global misalignment
243 if (fMatrixGlobal) delete fMatrixGlobal;
245 if (matrixGlobal) fMatrixGlobal = new TGeoHMatrix(*matrixGlobal);
248 void AliTPCCalibGlobalMisalignment::SetAlignGlobalDelta(const TGeoMatrix * matrixGlobalDelta){
250 // Set global misalignment
253 if (fMatrixGlobalDelta) delete fMatrixGlobalDelta;
254 fMatrixGlobalDelta=0;
255 if (matrixGlobalDelta) fMatrixGlobalDelta = new TGeoHMatrix(*matrixGlobalDelta);
258 void AliTPCCalibGlobalMisalignment::SetAlignSectors(const TObjArray *arraySector){
260 // Set misalignment TObjArray of TGeoMatrices - for each sector
263 if (fArraySector) delete fArraySector;
265 if (arraySector) fArraySector = (TObjArray*)arraySector->Clone();
269 //void AliTPCCalibGlobalMisalignment::Init() {
271 // // Initialization funtion
274 // // nothing to be initialized, results of this calibration class will go to the global aligment structure
278 //void AliTPCCalibGlobalMisalignment::Update(const TTimeStamp &/*timeStamp*/) {
280 // // Update function
283 // // nothing to be updated, results of this calibration class will go to the global aligment structure
289 void AliTPCCalibGlobalMisalignment::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {
291 // Calculates the simple correction due to a shift (in x,y,z) or an rotation of the TPC (around z)
293 static AliTPCROC *tpcRoc =AliTPCROC::Instance();
294 Double_t xref = ( tpcRoc->GetPadRowRadii(0,0)+tpcRoc->GetPadRowRadii(36,tpcRoc->GetNRows(36)-1))*0.5;
295 Double_t xquadrant = tpcRoc->GetPadRowRadii(36,53); // row 53 from uli
296 Double_t xIO = ( tpcRoc->GetPadRowRadii(0,tpcRoc->GetNRows(0)-1)+tpcRoc->GetPadRowRadii(36,0))*0.5;
298 r = TMath::Sqrt( x[0]*x[0] + x[1]*x[1] );
299 phi = TMath::ATan2(x[1],x[0]);
301 Double_t sec=TMath::Nint(-0.5+(phi*9./TMath::Pi()));
303 Int_t isec = TMath::Nint(sec);
304 if (roc%36>=18) isec+=18;
306 // Get the point on the local coordiante frame
308 Double_t alpha=(sec+0.5)*TMath::Pi()/9;
309 Double_t pos[3]={0,0,x[2]};
310 pos[0]= TMath::Cos(alpha)*x[0]+TMath::Sin(alpha)*x[1];
311 pos[1]= -TMath::Sin(alpha)*x[0]+TMath::Cos(alpha)*x[1];
312 if (pos[0]>tpcRoc->GetPadRowRadiiUp(0)) isec+=36;
315 // apply quadrant alignment if available - in local coordinate frame
318 Double_t posQG[3]={x[0],x[1],x[2]};
321 Bool_t isQ0 = (pos[0]<xquadrant)&&(pos[0]>xIO);
322 Bool_t isQ1 = (pos[0]>xquadrant);
323 Double_t sign = (pos[1]>0)? 1.: -1.;
325 if (fQuadrantQ0) dly+=sign*(*fQuadrantQ0)[isec%36]; // shift in cm
326 if (fQuadrantRQ0) dly+=sign*(*fQuadrantRQ0)[isec%36]*(pos[0]-xref);
329 if (fQuadrantQ1) dly+=sign*(*fQuadrantQ1)[isec%36]; // shift in cm
330 if (fQuadrantRQ1) dly+=sign*(*fQuadrantRQ1)[isec%36]*(pos[0]-xref);
331 if (fQuadrantQ2) dly+=(*fQuadrantQ2)[isec%36]; // shift in cm
332 if (fQuadrantRQ2) dly+=(*fQuadrantRQ2)[isec%36]*(pos[0]-xref);
334 // Tranform the corrected point to the global frame
335 posQG[0]= TMath::Cos(alpha)*pos[0]-TMath::Sin(alpha)*(pos[1]+dly);
336 posQG[1]= TMath::Sin(alpha)*pos[0]+TMath::Cos(alpha)*(pos[1]+dly);
339 // rotation of the read-out planes
340 if (roc%36<18) // A side
345 // Simply adding a constant dRPHi residual. PURELY FOR CALIBRATION PURPOSES
346 if (roc%36<18) // A side
347 phi += fdRPhiOffsetA/r;
349 phi += fdRPhiOffsetC/r;
351 dx[0] = r * TMath::Cos(phi) - x[0];
352 dx[1] = r * TMath::Sin(phi) - x[1];
360 dx[0] += (posQG[0]-x[0]);
361 dx[1] += (posQG[1]-x[1]);
365 // apply global alignment matrix
366 Double_t ppos[3]={x[0],x[1],x[2]};
367 Double_t pposC[3]={x[0],x[1],x[2]};
368 fMatrixGlobal->LocalToMaster(ppos,pposC);
369 dx[0]+=pposC[0]-ppos[0];
370 dx[1]+=pposC[1]-ppos[1];
371 dx[2]+=pposC[2]-ppos[2];
373 if (fMatrixGlobalDelta){
374 // apply global alignment matrix A-C Side side
375 Double_t ppos[3]={x[0],x[1],x[2]};
376 Double_t pposC[3]={x[0],x[1],x[2]};
377 fMatrixGlobalDelta->LocalToMaster(ppos,pposC);
378 Double_t ssign=(roc%36<18) ? 1.:-1.;
379 dx[0]+=ssign*(pposC[0]-ppos[0]);
380 dx[1]+=ssign*(pposC[1]-ppos[1]);
381 dx[2]+=ssign*(pposC[2]-ppos[2]);
385 // apply global alignment matrix
386 TGeoMatrix *mat = (TGeoMatrix*)fArraySector->At(isec);
388 Double_t ppos[3]={x[0],x[1],x[2]};
389 Double_t pposC[3]={x[0],x[1],x[2]};
390 mat->LocalToMaster(ppos,pposC);
391 dx[0]+=pposC[0]-ppos[0];
392 dx[1]+=pposC[1]-ppos[1];
393 dx[2]+=pposC[2]-ppos[2];
398 void AliTPCCalibGlobalMisalignment::Print(Option_t* option ) const{
400 // Print function to check the settings
402 printf("%s",GetTitle());
403 printf(" - Trivial Misalignments for calibration purposes: \n");
404 printf(" - X-Shift: %1.3f cm, Y-Shift: %1.3f cm, Z-Shift: %1.3f cm \n",fXShift,fYShift,fZShift);
405 printf(" - Phi-Rotations: A side: %1.5f rad, C side: %1.5f rad\n",fRotPhiA,fRotPhiC);
406 printf(" - dRPhi offsets: A side: %1.5f cm, C side: %1.5f cm\n",fdRPhiOffsetA,fdRPhiOffsetC);
407 TString opt = option; opt.ToLower();
408 if (opt.Contains("a")){
409 if (GetAlignGlobal()){
410 printf("GetAlignGlobal()\n");
411 GetAlignGlobal()->Print();
413 if (GetAlignGlobalDelta()){
414 printf("GetAlignGlobalDelta()\n");
415 GetAlignGlobalDelta()->Print();
417 if (GetAlignSectors()){
418 printf("GetAlignSectors()\n");
419 GetAlignSectors()->Print();
424 void AliTPCCalibGlobalMisalignment::AddAlign(const AliTPCCalibGlobalMisalignment & add){
426 // Add the alignmnet to current object
428 fXShift+=add.fXShift; // Shift in global X [cm]
429 fYShift+=add.fYShift; // Shift in global Y [cm]
430 fZShift+=add.fZShift; // Shift in global Z [cm]
432 fRotPhiA+=add.fRotPhiA; // simple rotation of A side read-out plane around the Z axis [rad]
433 fRotPhiC+=add.fRotPhiC; // simple rotation of C side read-out plane around the Z axis [rad]
434 fdRPhiOffsetA+=add.fdRPhiOffsetA; // add a constant offset of dRPhi (or local Y) in [cm]: purely for calibration purposes!
435 fdRPhiOffsetC+=add.fdRPhiOffsetC; // add a constant offset of dRPhi (or local Y) in [cm]: purely for calibration purposes!
437 // Quadrant alignment
439 if (add.fQuadrantQ0) {
440 if (fQuadrantQ0) fQuadrantQ0->Add(*(add.fQuadrantQ0));
441 if (!fQuadrantQ0) fQuadrantQ0 = (TVectorD*)(add.fQuadrantQ0->Clone());
443 if (add.fQuadrantRQ0) {
444 if (fQuadrantRQ0) fQuadrantRQ0->Add(*(add.fQuadrantRQ0));
445 if (!fQuadrantRQ0) fQuadrantRQ0 = (TVectorD*)(add.fQuadrantRQ0->Clone());
448 if (add.fQuadrantQ1) {
449 if (fQuadrantQ1) fQuadrantQ1->Add(*(add.fQuadrantQ1));
450 if (!fQuadrantQ1) fQuadrantQ1 = (TVectorD*)(add.fQuadrantQ1->Clone());
452 if (add.fQuadrantRQ1) {
453 if (fQuadrantRQ1) fQuadrantRQ1->Add(*(add.fQuadrantRQ1));
454 if (!fQuadrantRQ1) fQuadrantRQ1 = (TVectorD*)(add.fQuadrantRQ1->Clone());
457 if (add.fQuadrantQ2) {
458 if (fQuadrantQ2) fQuadrantQ2->Add(*(add.fQuadrantQ2));
459 if (!fQuadrantQ2) fQuadrantQ2 = (TVectorD*)(add.fQuadrantQ2->Clone());
461 if (add.fQuadrantRQ2) {
462 if (fQuadrantRQ2) fQuadrantRQ2->Add(*(add.fQuadrantRQ2));
463 if (!fQuadrantRQ2) fQuadrantRQ2 = (TVectorD*)(add.fQuadrantRQ2->Clone());
466 // Global alignment - use native ROOT representation
468 if (add.fMatrixGlobal){
469 if (!fMatrixGlobal) fMatrixGlobal = new TGeoHMatrix(*(add.fMatrixGlobal));
470 if (fMatrixGlobal) ((TGeoHMatrix*)fMatrixGlobal)->Multiply(add.fMatrixGlobal);
472 if (add.fArraySector){
473 if (!fArraySector) {SetAlignSectors(add.fArraySector);
475 for (Int_t isec=0; isec<72; isec++){
476 TGeoHMatrix *mat0= (TGeoHMatrix*)fArraySector->At(isec);
477 TGeoHMatrix *mat1= (TGeoHMatrix*)add.fArraySector->At(isec);
478 if (mat0&&mat1) mat0->Multiply(mat1);
485 AliTPCCalibGlobalMisalignment * AliTPCCalibGlobalMisalignment::CreateOCDBAlign(){
487 // Create AliTPCCalibGlobalMisalignment from OCDB Alignment entry
488 // OCDB has to be initialized before in user code
489 // All storages (defualt and specific) and run number
491 AliCDBEntry * entry = AliCDBManager::Instance()->Get("TPC/Align/Data");
493 printf("Missing alignmnet entry. OCDB not initialized?\n");
496 TClonesArray * array = (TClonesArray*)entry->GetObject();
497 Int_t entries = array->GetEntries();
498 TGeoHMatrix matrixGlobal;
499 TObjArray *alignArrayOCDB= new TObjArray(73); // sector misalignment + global misalignment
500 // // global is number 72
502 { for (Int_t i=0;i<entries; i++){
506 AliAlignObjParams *alignP = (AliAlignObjParams*)array->UncheckedAt(i);
507 alignP->GetMatrix(matrix);
509 AliGeomManager::ELayerID ilayer;
510 alignP->GetVolUID(ilayer, imod);
511 if (ilayer==AliGeomManager::kInvalidLayer) {
512 alignArrayOCDB->AddAt(matrix.Clone(),72);
513 alignP->GetMatrix(matrixGlobal);
516 if (ilayer==AliGeomManager::kTPC2) sector+=36;
517 alignArrayOCDB->AddAt(matrix.Clone(),sector);
521 AliTPCCalibGlobalMisalignment *align = new AliTPCCalibGlobalMisalignment;
522 align->SetAlignGlobal(&matrixGlobal);
523 align->SetAlignSectors(alignArrayOCDB);
528 AliTPCCalibGlobalMisalignment * AliTPCCalibGlobalMisalignment::CreateMeanAlign(const AliTPCCalibGlobalMisalignment *alignIn){
530 // Create new object, disantangle common mean alignmnet and sector alignment
532 // 1. Try to get mean alignment
533 // 2. Remove mean alignment from sector alignment
534 // 3. Create new object
536 TObjArray * array = alignIn->GetAlignSectors();
537 TObjArray * arrayNew = new TObjArray(72);
539 //Get mean transformation
541 {for (Int_t isec=0; isec<72; isec++){
542 const TGeoMatrix* cmatrix=(TGeoMatrix*)array->At(isec);
543 if (!cmatrix) continue;
544 matrix.Multiply(cmatrix);
546 TGeoHMatrix matrixMean(matrix);
547 matrixMean.SetDx(matrix.GetTranslation()[0]/72.);
548 matrixMean.SetDy(matrix.GetTranslation()[1]/72.);
549 matrixMean.SetDz(matrix.GetTranslation()[2]/72.);
550 Double_t rotation[12];
551 {for (Int_t i=0; i<12; i++) {
553 if (TMath::Abs(matrix.GetRotationMatrix()[i]-1.)>0.1){
554 rotation[i]=matrix.GetRotationMatrix()[i]/72.;
557 matrixMean.SetRotation(rotation);
558 TGeoHMatrix matrixInv = matrixMean.Inverse();
560 {for (Int_t isec=0; isec<72; isec++){
561 TGeoHMatrix* amatrix=(TGeoHMatrix*)(array->At(isec)->Clone());
562 if (!amatrix) continue;
563 amatrix->Multiply(&matrixInv);
564 arrayNew->AddAt(amatrix,isec);
566 if (alignIn->GetAlignGlobal()) matrixMean.Multiply((alignIn->GetAlignGlobal()));
567 AliTPCCalibGlobalMisalignment *alignOut = new AliTPCCalibGlobalMisalignment;
568 alignOut->SetAlignGlobal(&matrixMean);
569 alignOut->SetAlignSectors(arrayNew);
571 Checks transformation:
572 AliTPCCalibGlobalMisalignment * alignIn = AliTPCCalibGlobalMisalignment::CreateOCDBAlign()
573 AliTPCCalibGlobalMisalignment * alignOut = AliTPCCalibGlobalMisalignment::CreateMeanAlign(alignIn)
574 alignOutM= (AliTPCCalibGlobalMisalignment*)alignOut->Clone();
575 alignOutS= (AliTPCCalibGlobalMisalignment*)alignOut->Clone();
576 alignOutS->SetAlignGlobal(0);
577 alignOutM->SetAlignSectors(0);
579 AliTPCCorrection::AddVisualCorrection(alignOut,0);
580 AliTPCCorrection::AddVisualCorrection(alignOutM,1);
581 AliTPCCorrection::AddVisualCorrection(alignOutS,2);
582 AliTPCCorrection::AddVisualCorrection(alignIn,3);
584 TF1 f0("f0","AliTPCCorrection::GetCorrSector(x,85,0.9,1,0)",0,18);
585 TF1 f1("f1","AliTPCCorrection::GetCorrSector(x,85,0.9,1,1)",0,18);
586 TF1 f2("f2","AliTPCCorrection::GetCorrSector(x,85,0.9,1,2)",0,18);
587 TF1 f3("f3","AliTPCCorrection::GetCorrSector(x,85,0.9,1,3)",0,18);
597 TF2 f2D("f2D","AliTPCCorrection::GetCorrSector(x,y,0.9,1,0)-AliTPCCorrection::GetCorrSector(x,y,0.9,1,3)",0,18,85,245);
603 void AliTPCCalibGlobalMisalignment::DumpAlignment( AliTPCCalibGlobalMisalignment* align, TTreeSRedirector *pcstream, const char *name){
605 // Dump alignment per sector into tree
607 TObjArray * array = align->GetAlignSectors();
610 //Get mean transformation
612 {for (Int_t isec=0; isec<72; isec++){
613 TGeoHMatrix* cmatrix=(TGeoHMatrix*)array->At(isec);
614 TGeoHMatrix* cmatrixDown=(TGeoHMatrix*)array->At(isec%36);
615 TGeoHMatrix* cmatrixUp=(TGeoHMatrix*)array->At(isec%36+36);
616 TGeoHMatrix diff(*cmatrixDown);
617 diff.Multiply(&(cmatrixUp->Inverse()));