Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 : * *
4 : * Author: The ALICE Off-line Project. *
5 : * Contributors are mentioned in the code where appropriate. *
6 : * *
7 : * Permission to use, copy, modify and distribute this software and its *
8 : * documentation strictly for non-commercial purposes is hereby granted *
9 : * without fee, provided that the above copyright notice appears in all *
10 : * copies and that both the copyright notice and this permission notice *
11 : * appear in the supporting documentation. The authors make no claims *
12 : * about the suitability of this software for any purpose. It is *
13 : * provided "as is" without express or implied warranty. *
14 : **************************************************************************/
15 :
16 :
17 : /// \class AliTPCCalibGlobalMisalignment
18 : ///
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
25 : ///
26 : /// \author Stefan Rossegger, Jim Thomas, Magnus Mager
27 : /// \date 06/05/2010
28 :
29 : #include "AliTPCCalibGlobalMisalignment.h"
30 : #include "TMath.h"
31 : #include "TGeoMatrix.h"
32 : #include "AliTPCROC.h"
33 : #include "AliTPCcalibDB.h"
34 : #include "AliTPCParam.h"
35 : #include <TGeoPhysicalNode.h>
36 : //
37 : #include "AliAlignObjParams.h"
38 : #include "AliGeomManager.h"
39 : #include "AliCDBManager.h"
40 : #include "AliCDBEntry.h"
41 :
42 : AliTPCCalibGlobalMisalignment::AliTPCCalibGlobalMisalignment()
43 6 : : AliTPCCorrection("mialign","Misalignment"),
44 6 : fXShift(0.),fYShift(0.),fZShift(0.),
45 6 : fRotPhiA(0.),fRotPhiC(0.),
46 6 : fdRPhiOffsetA(0.),
47 6 : fdRPhiOffsetC(0.),
48 6 : fQuadrantQ0(0), //OROC medium pads -delta ly+ - ly - shift
49 6 : fQuadrantRQ0(0), //OROC medium pads -delta ly+ - ly - rotation
50 6 : fQuadrantQ1(0), //OROC long pads -delta ly+ - ly - shift
51 6 : fQuadrantQ2(0), //OROC long pads -shift
52 6 : fQuadrantRQ1(0), //OROC long pads -delta ly+ - ly - rotation
53 6 : fQuadrantRQ2(0), //OROC long pads -rotation
54 6 : fMatrixGlobal(0), // global Alignment common
55 6 : fMatrixGlobalDelta(0), // global Alignment Delta A side-c side
56 6 : fArraySector(0) // fArraySector
57 30 : {
58 : /// default constructor
59 :
60 12 : }
61 :
62 0 : AliTPCCalibGlobalMisalignment::~AliTPCCalibGlobalMisalignment() {
63 : /// destructor
64 :
65 0 : delete fQuadrantQ0; //OROC medium pads -delta ly+ - ly - shift
66 0 : delete fQuadrantRQ0; //OROC medium pads -delta ly+ - ly - rotation
67 0 : delete fQuadrantQ1; //OROC long pads -delta ly+ - ly - shift
68 0 : delete fQuadrantQ2; //OROC long pads -shift
69 0 : delete fQuadrantRQ1; //OROC long pads -delta ly+ - ly - rotation
70 0 : delete fQuadrantRQ2; //OROC long pads -rotation
71 0 : delete fMatrixGlobal; // global matrix
72 0 : delete fMatrixGlobal; // global matrix
73 0 : delete fArraySector; // sector matrices
74 0 : }
75 :
76 :
77 :
78 : Bool_t AliTPCCalibGlobalMisalignment::AddCorrectionCompact(AliTPCCorrection* corr, Double_t weight){
79 : /// Add correction and make them compact
80 : /// Assumptions:
81 : /// - origin of distortion/correction are additive
82 : /// - only correction ot the same type supported ()
83 :
84 0 : if (corr==NULL) {
85 : //AliError("Zerro pointer - correction");
86 0 : return kFALSE;
87 : }
88 0 : AliTPCCalibGlobalMisalignment* corrC = dynamic_cast<AliTPCCalibGlobalMisalignment *>(corr);
89 0 : if (corrC == NULL) {
90 : //AliError(TString::Format("Inconsistent class types: %s\%s",IsA()->GetName(),corr->IsA()->GetName()).Data());
91 0 : return kFALSE;
92 : }
93 : //
94 : AliTPCCalibGlobalMisalignment & add = *corrC;
95 0 : fXShift+=weight*add.fXShift; // Shift in global X [cm]
96 0 : fYShift+=weight*add.fYShift; // Shift in global Y [cm]
97 0 : fZShift+=weight*add.fZShift; // Shift in global Z [cm]
98 :
99 0 : fRotPhiA+=weight*add.fRotPhiA; // simple rotation of A side read-out plane around the Z axis [rad]
100 0 : fRotPhiC+=weight*add.fRotPhiC; // simple rotation of C side read-out plane around the Z axis [rad]
101 0 : fdRPhiOffsetA+=weight*add.fdRPhiOffsetA; // add a constant offset of dRPhi (or local Y) in [cm]: purely for calibration purposes!
102 0 : fdRPhiOffsetC+=weight*add.fdRPhiOffsetC; // add a constant offset of dRPhi (or local Y) in [cm]: purely for calibration purposes!
103 : //
104 : // Quadrant alignment
105 : //
106 0 : if (add.fQuadrantQ0) {
107 0 : if (!fQuadrantQ0) fQuadrantQ0 = new TVectorD(add.fQuadrantQ0->GetNrows());
108 0 : fQuadrantQ0->Add(weight*(*(add.fQuadrantQ0)));
109 0 : }
110 0 : if (add.fQuadrantRQ0) {
111 0 : if (!fQuadrantRQ0) fQuadrantRQ0 = new TVectorD(add.fQuadrantRQ0->GetNrows());
112 0 : fQuadrantRQ0->Add(weight*(*(add.fQuadrantRQ0)));
113 0 : }
114 : //
115 0 : if (add.fQuadrantQ1) {
116 0 : if (!fQuadrantQ1) fQuadrantQ1 = new TVectorD(add.fQuadrantQ1->GetNrows());
117 0 : fQuadrantQ1->Add(weight*(*(add.fQuadrantQ1)));
118 0 : }
119 0 : if (add.fQuadrantRQ1) {
120 0 : if (!fQuadrantRQ1) fQuadrantRQ1 = new TVectorD(add.fQuadrantRQ1->GetNrows());
121 0 : fQuadrantRQ1->Add(weight*(*(add.fQuadrantRQ1)));
122 0 : }
123 : //
124 0 : if (add.fQuadrantQ2) {
125 0 : if (!fQuadrantQ2) fQuadrantQ2 = new TVectorD(add.fQuadrantQ2->GetNrows());
126 0 : fQuadrantQ2->Add(weight*(*(add.fQuadrantQ2)));
127 0 : }
128 0 : if (add.fQuadrantRQ2) {
129 0 : if (!fQuadrantRQ2) fQuadrantRQ2 = new TVectorD(add.fQuadrantRQ2->GetNrows());
130 0 : fQuadrantRQ2->Add(weight*(*(add.fQuadrantRQ2)));
131 0 : }
132 : //
133 : // Global alignment - use native ROOT representation
134 : //
135 0 : Double_t delta[3]={0};
136 0 : if (add.fMatrixGlobal){
137 0 : TGeoHMatrix matrixW=*(add.fMatrixGlobal);
138 0 : TGeoHMatrix matrixScaled;
139 0 : const Double_t *rotMatrix = matrixW.GetRotationMatrix();
140 0 : const Double_t *transMatrix = matrixW.GetTranslation();
141 0 : matrixScaled.RotateZ(-rotMatrix[1]*TMath::RadToDeg()*weight);
142 0 : matrixScaled.RotateY(rotMatrix[2]*TMath::RadToDeg()*weight);
143 0 : matrixScaled.RotateX(-rotMatrix[5]*TMath::RadToDeg()*weight);
144 0 : for (Int_t i=0; i<3; i++) delta[i]=weight*transMatrix[i];
145 0 : matrixScaled.SetTranslation(delta);
146 : // (matrixScaled*matrixW).Print(); in case weight -1 should be unit matrix
147 : //
148 0 : if (!fMatrixGlobal) {
149 0 : fMatrixGlobal = new TGeoHMatrix(matrixScaled);
150 0 : }else{
151 0 : ((TGeoHMatrix*)fMatrixGlobal)->Multiply(&matrixScaled);
152 : }
153 0 : }
154 0 : if (add.fMatrixGlobalDelta){
155 0 : TGeoHMatrix matrixW=*(add.fMatrixGlobalDelta);
156 0 : TGeoHMatrix matrixScaled;
157 0 : const Double_t *rotMatrix = matrixW.GetRotationMatrix();
158 0 : const Double_t *transMatrix = matrixW.GetTranslation();
159 0 : matrixScaled.RotateZ(-rotMatrix[1]*TMath::RadToDeg()*weight);
160 0 : matrixScaled.RotateY(rotMatrix[2]*TMath::RadToDeg()*weight);
161 0 : matrixScaled.RotateX(-rotMatrix[5]*TMath::RadToDeg()*weight);
162 0 : for (Int_t i=0; i<3; i++) delta[i]=weight*transMatrix[i];
163 0 : matrixScaled.SetTranslation(delta);
164 : // (matrixScaled*matrixW).Print(); in case weight -1 should be unit matrix
165 : //
166 0 : if (!fMatrixGlobalDelta) {
167 0 : fMatrixGlobalDelta = new TGeoHMatrix(matrixScaled);
168 0 : }else{
169 0 : ((TGeoHMatrix*)fMatrixGlobalDelta)->Multiply(&matrixScaled);
170 : }
171 0 : }
172 0 : if (add.fArraySector){
173 0 : if (!fArraySector) {
174 0 : fArraySector = new TObjArray(72);
175 0 : for (Int_t isec=0; isec<72; isec++) fArraySector->AddAt(new TGeoHMatrix,isec);
176 0 : }
177 0 : for (Int_t isec=0; isec<72; isec++){
178 0 : TGeoHMatrix *mat0= (TGeoHMatrix*)fArraySector->At(isec);
179 0 : TGeoHMatrix *mat1= (TGeoHMatrix*)add.fArraySector->At(isec);
180 0 : if (mat0&&mat1){
181 0 : TGeoHMatrix matrixW=*(mat1);
182 0 : TGeoHMatrix matrixScaled;
183 0 : const Double_t *rotMatrix = matrixW.GetRotationMatrix();
184 0 : const Double_t *transMatrix = matrixW.GetTranslation();
185 0 : matrixScaled.RotateZ(-rotMatrix[1]*TMath::RadToDeg()*weight);
186 0 : matrixScaled.RotateY(rotMatrix[2]*TMath::RadToDeg()*weight);
187 0 : matrixScaled.RotateX(-rotMatrix[5]*TMath::RadToDeg()*weight);
188 0 : for (Int_t i=0; i<3; i++) delta[i]=weight*transMatrix[i];
189 0 : matrixScaled.SetTranslation(delta);
190 0 : mat0->Multiply(&matrixScaled);
191 0 : }
192 : }
193 0 : }
194 : //
195 : return kTRUE;
196 0 : }
197 :
198 :
199 :
200 :
201 : void AliTPCCalibGlobalMisalignment::SetQuadranAlign(const TVectorD *quadrantQ0, const TVectorD *quadrantRQ0, const TVectorD *quadrantQ1,const TVectorD *quadrantRQ1, const TVectorD *quadrantQ2, const TVectorD *quadrantRQ2){
202 : /// Set quadrant alignment
203 : /// 6 vectors for 36 (super) sectors
204 :
205 0 : if (quadrantQ0) fQuadrantQ0 = new TVectorD(*quadrantQ0);
206 0 : if (quadrantRQ0) fQuadrantRQ0 = new TVectorD(*quadrantRQ0);
207 : //
208 0 : if (quadrantQ1) fQuadrantQ1 = new TVectorD(*quadrantQ1);
209 0 : if (quadrantQ1) fQuadrantRQ1 = new TVectorD(*quadrantRQ1);
210 0 : if (quadrantQ2) fQuadrantQ2 = new TVectorD(*quadrantQ2);
211 0 : if (quadrantQ2) fQuadrantRQ2 = new TVectorD(*quadrantRQ2);
212 0 : }
213 :
214 :
215 :
216 : void AliTPCCalibGlobalMisalignment::SetAlignGlobal(const TGeoMatrix * matrixGlobal){
217 : /// Set global misalignment
218 : /// Object is OWNER
219 :
220 0 : if (fMatrixGlobal) delete fMatrixGlobal;
221 0 : fMatrixGlobal=0;
222 0 : if (matrixGlobal) fMatrixGlobal = new TGeoHMatrix(*matrixGlobal);
223 0 : }
224 :
225 : void AliTPCCalibGlobalMisalignment::SetAlignGlobalDelta(const TGeoMatrix * matrixGlobalDelta){
226 : /// Set global misalignment
227 : /// Object is OWNER
228 :
229 0 : if (fMatrixGlobalDelta) delete fMatrixGlobalDelta;
230 0 : fMatrixGlobalDelta=0;
231 0 : if (matrixGlobalDelta) fMatrixGlobalDelta = new TGeoHMatrix(*matrixGlobalDelta);
232 0 : }
233 :
234 : void AliTPCCalibGlobalMisalignment::SetAlignSectors(const TObjArray *arraySector){
235 : /// Set misalignment TObjArray of TGeoMatrices - for each sector
236 : /// Object is OWNER
237 :
238 0 : if (fArraySector) delete fArraySector;
239 0 : fArraySector=0;
240 0 : if (arraySector) fArraySector = (TObjArray*)arraySector->Clone();
241 0 : }
242 :
243 :
244 : //void AliTPCCalibGlobalMisalignment::Init() {
245 : // //
246 : // // Initialization funtion
247 : // //
248 :
249 : // // nothing to be initialized, results of this calibration class will go to the global aligment structure
250 :
251 : //}
252 :
253 : //void AliTPCCalibGlobalMisalignment::Update(const TTimeStamp &/*timeStamp*/) {
254 : // //
255 : // // Update function
256 : // //
257 : //
258 : // // nothing to be updated, results of this calibration class will go to the global aligment structure
259 : //
260 : //}
261 :
262 :
263 :
264 : void AliTPCCalibGlobalMisalignment::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {
265 : /// Calculates the simple correction due to a shift (in x,y,z) or an rotation of the TPC (around z)
266 :
267 0 : static AliTPCROC *tpcRoc =AliTPCROC::Instance();
268 0 : Double_t xref = ( tpcRoc->GetPadRowRadii(0,0)+tpcRoc->GetPadRowRadii(36,tpcRoc->GetNRows(36)-1))*0.5;
269 0 : Double_t xquadrant = tpcRoc->GetPadRowRadii(36,53); // row 53 from uli
270 0 : Double_t xIO = ( tpcRoc->GetPadRowRadii(0,tpcRoc->GetNRows(0)-1)+tpcRoc->GetPadRowRadii(36,0))*0.5;
271 : Double_t r=0, phi=0;
272 0 : r = TMath::Sqrt( x[0]*x[0] + x[1]*x[1] );
273 0 : phi = TMath::ATan2(x[1],x[0]);
274 : // Getsector number
275 0 : Double_t sec=TMath::Nint(-0.5+(phi*9./TMath::Pi()));
276 0 : if (sec<0) sec+=18;
277 0 : Int_t isec = TMath::Nint(sec);
278 0 : if (roc%36>=18) isec+=18;
279 : //
280 : // Get the point on the local coordiante frame
281 : //
282 0 : Double_t alpha=(sec+0.5)*TMath::Pi()/9;
283 0 : Double_t pos[3]={0,0,x[2]};
284 0 : pos[0]= TMath::Cos(alpha)*x[0]+TMath::Sin(alpha)*x[1];
285 0 : pos[1]= -TMath::Sin(alpha)*x[0]+TMath::Cos(alpha)*x[1];
286 0 : if (pos[0]>tpcRoc->GetPadRowRadiiUp(0)) isec+=36;
287 :
288 : //
289 : // apply quadrant alignment if available - in local coordinate frame
290 : //
291 : //
292 0 : Double_t posQG[3]={x[0],x[1],x[2]};
293 : {
294 : Double_t dly=0;
295 0 : Bool_t isQ0 = (pos[0]<xquadrant)&&(pos[0]>xIO);
296 0 : Bool_t isQ1 = (pos[0]>xquadrant);
297 0 : Double_t sign = (pos[1]>0)? 1.: -1.;
298 0 : if (isQ0){
299 0 : if (fQuadrantQ0) dly+=sign*(*fQuadrantQ0)[isec%36]; // shift in cm
300 0 : if (fQuadrantRQ0) dly+=sign*(*fQuadrantRQ0)[isec%36]*(pos[0]-xref);
301 : }
302 0 : if (isQ1){
303 0 : if (fQuadrantQ1) dly+=sign*(*fQuadrantQ1)[isec%36]; // shift in cm
304 0 : if (fQuadrantRQ1) dly+=sign*(*fQuadrantRQ1)[isec%36]*(pos[0]-xref);
305 0 : if (fQuadrantQ2) dly+=(*fQuadrantQ2)[isec%36]; // shift in cm
306 0 : if (fQuadrantRQ2) dly+=(*fQuadrantRQ2)[isec%36]*(pos[0]-xref);
307 : }
308 : // Tranform the corrected point to the global frame
309 0 : posQG[0]= TMath::Cos(alpha)*pos[0]-TMath::Sin(alpha)*(pos[1]+dly);
310 0 : posQG[1]= TMath::Sin(alpha)*pos[0]+TMath::Cos(alpha)*(pos[1]+dly);
311 : }
312 : //
313 : // rotation of the read-out planes
314 0 : if (roc%36<18) // A side
315 0 : phi += fRotPhiA;
316 : else // C side
317 0 : phi += fRotPhiC;
318 :
319 : // Simply adding a constant dRPHi residual. PURELY FOR CALIBRATION PURPOSES
320 0 : if (roc%36<18) // A side
321 0 : phi += fdRPhiOffsetA/r;
322 : else // C side
323 0 : phi += fdRPhiOffsetC/r;
324 :
325 0 : dx[0] = r * TMath::Cos(phi) - x[0];
326 0 : dx[1] = r * TMath::Sin(phi) - x[1];
327 0 : dx[2] = 0.;
328 :
329 : // Simple shifts
330 0 : dx[0] -= fXShift;
331 0 : dx[1] -= fYShift;
332 0 : dx[2] -= fZShift;
333 : // quadrant shifts
334 0 : dx[0] += (posQG[0]-x[0]);
335 0 : dx[1] += (posQG[1]-x[1]);
336 : //
337 : //
338 0 : if (fMatrixGlobal){
339 : // apply global alignment matrix
340 0 : Double_t ppos[3]={x[0],x[1],x[2]};
341 0 : Double_t pposC[3]={x[0],x[1],x[2]};
342 0 : fMatrixGlobal->LocalToMaster(ppos,pposC);
343 0 : dx[0]+=pposC[0]-ppos[0];
344 0 : dx[1]+=pposC[1]-ppos[1];
345 0 : dx[2]+=pposC[2]-ppos[2];
346 0 : }
347 0 : if (fMatrixGlobalDelta){
348 : // apply global alignment matrix A-C Side side
349 0 : Double_t ppos[3]={x[0],x[1],x[2]};
350 0 : Double_t pposC[3]={x[0],x[1],x[2]};
351 0 : fMatrixGlobalDelta->LocalToMaster(ppos,pposC);
352 0 : Double_t ssign=(roc%36<18) ? 1.:-1.;
353 0 : dx[0]+=ssign*(pposC[0]-ppos[0]);
354 0 : dx[1]+=ssign*(pposC[1]-ppos[1]);
355 0 : dx[2]+=ssign*(pposC[2]-ppos[2]);
356 0 : }
357 :
358 0 : if (fArraySector){
359 : // apply global alignment matrix
360 0 : TGeoMatrix *mat = (TGeoMatrix*)fArraySector->At(isec);
361 0 : if (mat){
362 0 : Double_t ppos[3]={x[0],x[1],x[2]};
363 0 : Double_t pposC[3]={x[0],x[1],x[2]};
364 0 : mat->LocalToMaster(ppos,pposC);
365 0 : dx[0]+=pposC[0]-ppos[0];
366 0 : dx[1]+=pposC[1]-ppos[1];
367 0 : dx[2]+=pposC[2]-ppos[2];
368 0 : }
369 0 : }
370 0 : }
371 :
372 : void AliTPCCalibGlobalMisalignment::Print(Option_t* option ) const{
373 : /// Print function to check the settings
374 :
375 0 : printf("%s",GetTitle());
376 0 : printf(" - Trivial Misalignments for calibration purposes: \n");
377 0 : printf(" - X-Shift: %1.3f cm, Y-Shift: %1.3f cm, Z-Shift: %1.3f cm \n",fXShift,fYShift,fZShift);
378 0 : printf(" - Phi-Rotations: A side: %1.5f rad, C side: %1.5f rad\n",fRotPhiA,fRotPhiC);
379 0 : printf(" - dRPhi offsets: A side: %1.5f cm, C side: %1.5f cm\n",fdRPhiOffsetA,fdRPhiOffsetC);
380 0 : TString opt = option; opt.ToLower();
381 0 : if (opt.Contains("a")){
382 0 : if (GetAlignGlobal()){
383 0 : printf("GetAlignGlobal()\n");
384 0 : GetAlignGlobal()->Print();
385 : }
386 0 : if (GetAlignGlobalDelta()){
387 0 : printf("GetAlignGlobalDelta()\n");
388 0 : GetAlignGlobalDelta()->Print();
389 : }
390 0 : if (GetAlignSectors()){
391 0 : printf("GetAlignSectors()\n");
392 0 : GetAlignSectors()->Print();
393 : }
394 : }
395 0 : }
396 :
397 : void AliTPCCalibGlobalMisalignment::AddAlign(const AliTPCCalibGlobalMisalignment & add){
398 : /// Add the alignmnet to current object
399 :
400 0 : fXShift+=add.fXShift; // Shift in global X [cm]
401 0 : fYShift+=add.fYShift; // Shift in global Y [cm]
402 0 : fZShift+=add.fZShift; // Shift in global Z [cm]
403 :
404 0 : fRotPhiA+=add.fRotPhiA; // simple rotation of A side read-out plane around the Z axis [rad]
405 0 : fRotPhiC+=add.fRotPhiC; // simple rotation of C side read-out plane around the Z axis [rad]
406 0 : fdRPhiOffsetA+=add.fdRPhiOffsetA; // add a constant offset of dRPhi (or local Y) in [cm]: purely for calibration purposes!
407 0 : fdRPhiOffsetC+=add.fdRPhiOffsetC; // add a constant offset of dRPhi (or local Y) in [cm]: purely for calibration purposes!
408 : //
409 : // Quadrant alignment
410 : //
411 0 : if (add.fQuadrantQ0) {
412 0 : if (fQuadrantQ0) fQuadrantQ0->Add(*(add.fQuadrantQ0));
413 0 : if (!fQuadrantQ0) fQuadrantQ0 = (TVectorD*)(add.fQuadrantQ0->Clone());
414 : }
415 0 : if (add.fQuadrantRQ0) {
416 0 : if (fQuadrantRQ0) fQuadrantRQ0->Add(*(add.fQuadrantRQ0));
417 0 : if (!fQuadrantRQ0) fQuadrantRQ0 = (TVectorD*)(add.fQuadrantRQ0->Clone());
418 : }
419 : //
420 0 : if (add.fQuadrantQ1) {
421 0 : if (fQuadrantQ1) fQuadrantQ1->Add(*(add.fQuadrantQ1));
422 0 : if (!fQuadrantQ1) fQuadrantQ1 = (TVectorD*)(add.fQuadrantQ1->Clone());
423 : }
424 0 : if (add.fQuadrantRQ1) {
425 0 : if (fQuadrantRQ1) fQuadrantRQ1->Add(*(add.fQuadrantRQ1));
426 0 : if (!fQuadrantRQ1) fQuadrantRQ1 = (TVectorD*)(add.fQuadrantRQ1->Clone());
427 : }
428 : //
429 0 : if (add.fQuadrantQ2) {
430 0 : if (fQuadrantQ2) fQuadrantQ2->Add(*(add.fQuadrantQ2));
431 0 : if (!fQuadrantQ2) fQuadrantQ2 = (TVectorD*)(add.fQuadrantQ2->Clone());
432 : }
433 0 : if (add.fQuadrantRQ2) {
434 0 : if (fQuadrantRQ2) fQuadrantRQ2->Add(*(add.fQuadrantRQ2));
435 0 : if (!fQuadrantRQ2) fQuadrantRQ2 = (TVectorD*)(add.fQuadrantRQ2->Clone());
436 : }
437 : //
438 : // Global alignment - use native ROOT representation
439 : //
440 0 : if (add.fMatrixGlobal){
441 0 : if (!fMatrixGlobal) fMatrixGlobal = new TGeoHMatrix(*(add.fMatrixGlobal));
442 0 : if (fMatrixGlobal) ((TGeoHMatrix*)fMatrixGlobal)->Multiply(add.fMatrixGlobal);
443 : }
444 0 : if (add.fArraySector){
445 0 : if (!fArraySector) {SetAlignSectors(add.fArraySector);
446 0 : }else{
447 0 : for (Int_t isec=0; isec<72; isec++){
448 0 : TGeoHMatrix *mat0= (TGeoHMatrix*)fArraySector->At(isec);
449 0 : TGeoHMatrix *mat1= (TGeoHMatrix*)add.fArraySector->At(isec);
450 0 : if (mat0&&mat1) mat0->Multiply(mat1);
451 : }
452 : }
453 : }
454 0 : }
455 :
456 :
457 : AliTPCCalibGlobalMisalignment * AliTPCCalibGlobalMisalignment::CreateOCDBAlign(){
458 : /// Create AliTPCCalibGlobalMisalignment from OCDB Alignment entry
459 : /// OCDB has to be initialized before in user code
460 : /// All storages (defualt and specific) and run number
461 :
462 0 : AliCDBEntry * entry = AliCDBManager::Instance()->Get("TPC/Align/Data");
463 0 : if (!entry){
464 0 : printf("Missing alignmnet entry. OCDB not initialized?\n");
465 0 : return 0;
466 : }
467 0 : TClonesArray * array = (TClonesArray*)entry->GetObject();
468 0 : Int_t entries = array->GetEntries();
469 0 : TGeoHMatrix matrixGlobal;
470 0 : TObjArray *alignArrayOCDB= new TObjArray(73); // sector misalignment + global misalignment
471 : // // global is number 72
472 : //
473 0 : { for (Int_t i=0;i<entries; i++){
474 : //
475 : //
476 0 : TGeoHMatrix matrix;
477 0 : AliAlignObjParams *alignP = (AliAlignObjParams*)array->UncheckedAt(i);
478 0 : alignP->GetMatrix(matrix);
479 0 : Int_t imod;
480 0 : AliGeomManager::ELayerID ilayer;
481 0 : alignP->GetVolUID(ilayer, imod);
482 0 : if (ilayer==AliGeomManager::kInvalidLayer) {
483 0 : alignArrayOCDB->AddAt(matrix.Clone(),72);
484 0 : alignP->GetMatrix(matrixGlobal);
485 : }else{
486 0 : Int_t sector=imod;
487 0 : if (ilayer==AliGeomManager::kTPC2) sector+=36;
488 0 : alignArrayOCDB->AddAt(matrix.Clone(),sector);
489 : }
490 0 : }
491 : }
492 0 : AliTPCCalibGlobalMisalignment *align = new AliTPCCalibGlobalMisalignment;
493 0 : align->SetAlignGlobal(&matrixGlobal);
494 0 : align->SetAlignSectors(alignArrayOCDB);
495 : return align;
496 0 : }
497 :
498 :
499 : AliTPCCalibGlobalMisalignment * AliTPCCalibGlobalMisalignment::CreateMeanAlign(const AliTPCCalibGlobalMisalignment *alignIn){
500 : /// Create new object, disantangle common mean alignmnet and sector alignment
501 : ///
502 : /// 1. Try to get mean alignment
503 : /// 2. Remove mean alignment from sector alignment
504 : /// 3. Create new object
505 :
506 0 : TObjArray * array = alignIn->GetAlignSectors();
507 0 : TObjArray * arrayNew = new TObjArray(72);
508 : //
509 : //Get mean transformation
510 0 : TGeoHMatrix matrix;
511 0 : {for (Int_t isec=0; isec<72; isec++){
512 0 : const TGeoMatrix* cmatrix=(TGeoMatrix*)array->At(isec);
513 0 : if (!cmatrix) continue;
514 0 : matrix.Multiply(cmatrix);
515 0 : }}
516 0 : TGeoHMatrix matrixMean(matrix);
517 0 : matrixMean.SetDx(matrix.GetTranslation()[0]/72.);
518 0 : matrixMean.SetDy(matrix.GetTranslation()[1]/72.);
519 0 : matrixMean.SetDz(matrix.GetTranslation()[2]/72.);
520 0 : Double_t rotation[12];
521 0 : {for (Int_t i=0; i<12; i++) {
522 0 : rotation[i]=1.0;
523 0 : if (TMath::Abs(matrix.GetRotationMatrix()[i]-1.)>0.1){
524 0 : rotation[i]=matrix.GetRotationMatrix()[i]/72.;
525 0 : }
526 : }}
527 0 : matrixMean.SetRotation(rotation);
528 0 : TGeoHMatrix matrixInv = matrixMean.Inverse();
529 : //
530 0 : {for (Int_t isec=0; isec<72; isec++){
531 0 : TGeoHMatrix* amatrix=(TGeoHMatrix*)(array->At(isec)->Clone());
532 0 : if (!amatrix) continue;
533 0 : amatrix->Multiply(&matrixInv);
534 0 : arrayNew->AddAt(amatrix,isec);
535 0 : }}
536 0 : if (alignIn->GetAlignGlobal()) matrixMean.Multiply((alignIn->GetAlignGlobal()));
537 0 : AliTPCCalibGlobalMisalignment *alignOut = new AliTPCCalibGlobalMisalignment;
538 0 : alignOut->SetAlignGlobal(&matrixMean);
539 0 : alignOut->SetAlignSectors(arrayNew);
540 : /*
541 : Checks transformation:
542 : AliTPCCalibGlobalMisalignment * alignIn = AliTPCCalibGlobalMisalignment::CreateOCDBAlign()
543 : AliTPCCalibGlobalMisalignment * alignOut = AliTPCCalibGlobalMisalignment::CreateMeanAlign(alignIn)
544 : alignOutM= (AliTPCCalibGlobalMisalignment*)alignOut->Clone();
545 : alignOutS= (AliTPCCalibGlobalMisalignment*)alignOut->Clone();
546 : alignOutS->SetAlignGlobal(0);
547 : alignOutM->SetAlignSectors(0);
548 : //
549 : AliTPCCorrection::AddVisualCorrection(alignOut,0);
550 : AliTPCCorrection::AddVisualCorrection(alignOutM,1);
551 : AliTPCCorrection::AddVisualCorrection(alignOutS,2);
552 : AliTPCCorrection::AddVisualCorrection(alignIn,3);
553 :
554 : TF1 f0("f0","AliTPCCorrection::GetCorrSector(x,85,0.9,1,0)",0,18);
555 : TF1 f1("f1","AliTPCCorrection::GetCorrSector(x,85,0.9,1,1)",0,18);
556 : TF1 f2("f2","AliTPCCorrection::GetCorrSector(x,85,0.9,1,2)",0,18);
557 : TF1 f3("f3","AliTPCCorrection::GetCorrSector(x,85,0.9,1,3)",0,18);
558 : f0->SetLineColor(1);
559 : f1->SetLineColor(2);
560 : f2->SetLineColor(3);
561 : f3->SetLineColor(4);
562 : f0->Draw();
563 : f1->Draw("same");
564 : f2->Draw("same");
565 : f3->Draw("same");
566 :
567 : TF2 f2D("f2D","AliTPCCorrection::GetCorrSector(x,y,0.9,1,0)-AliTPCCorrection::GetCorrSector(x,y,0.9,1,3)",0,18,85,245);
568 : */
569 : return alignOut;
570 0 : }
571 :
572 :
573 : void AliTPCCalibGlobalMisalignment::DumpAlignment( AliTPCCalibGlobalMisalignment* align, TTreeSRedirector *pcstream, const char *name){
574 : /// Dump alignment per sector into tree
575 :
576 0 : TObjArray * array = align->GetAlignSectors();
577 0 : if (!array) return;
578 : //
579 : //Get mean transformation
580 0 : TGeoHMatrix matrix;
581 0 : {for (Int_t isec=0; isec<72; isec++){
582 0 : TGeoHMatrix* cmatrix=(TGeoHMatrix*)array->At(isec);
583 0 : TGeoHMatrix* cmatrixDown=(TGeoHMatrix*)array->At(isec%36);
584 0 : TGeoHMatrix* cmatrixUp=(TGeoHMatrix*)array->At(isec%36+36);
585 0 : TGeoHMatrix diff(*cmatrixDown);
586 0 : diff.Multiply(&(cmatrixUp->Inverse()));
587 0 : (*pcstream)<<name<<
588 0 : "isec="<<isec<<
589 0 : "m0.="<<cmatrix<<
590 0 : "diff.="<<&diff<<
591 : "\n";
592 0 : }
593 : }
594 :
595 0 : }
|