]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONGeometryMisAligner.cxx
AliEveTrackCounter, AliEveTrackCounterEditor
[u/mrichter/AliRoot.git] / MUON / AliMUONGeometryMisAligner.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *      SigmaEffect_thetadegrees                                          * 
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 purpeateose. It is      *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 // $Id$
17 //
18 //-----------------------------------------------------------------------------
19 /// \class AliMUONGeometryMisAligner
20 ///
21 /// This performs the misalignment on an existing muon arm geometry
22 /// based on the standard definition of the detector elements in 
23 /// $ALICE_ROOT/MUON/data
24 ///
25 /// --> User has to specify the magnitude of the alignments, in the Cartesian 
26 /// co-ordiantes (which are used to apply translation misalignments) and in the
27 /// spherical co-ordinates (which are used to apply angular displacements)
28 ///
29 /// --> If the constructor is used with no arguments, user has to set 
30 /// misalignment ranges by hand using the methods : 
31 /// SetApplyMisAlig, SetMaxCartMisAlig, SetMaxAngMisAlig, SetXYAngMisAligFactor
32 /// (last method takes account of the fact that the misalingment is greatest in 
33 /// the XY plane, since the detection elements are fixed to a support structure
34 /// in this plane. Misalignments in the XZ and YZ plane will be very small 
35 /// compared to those in the XY plane, which are small already - of the order 
36 /// of microns)
37 ///
38 /// Note : If the detection elements are allowed to be misaligned in all
39 /// directions, this has consequences for the alignment algorithm
40 /// (AliMUONAlignment), which needs to know the number of free parameters. 
41 /// Eric only allowed 3 :  x,y,theta_xy, but in principle z and the other 
42 /// two angles are alignable as well.
43 ///
44 /// \author Bruce Becker, Javier Castillo
45 //-----------------------------------------------------------------------------
46
47 #include "AliMUONGeometryMisAligner.h"
48 #include "AliMUONGeometryTransformer.h"
49 #include "AliMUONGeometryModuleTransformer.h"
50 #include "AliMUONGeometryDetElement.h"
51 #include "AliMUONGeometryBuilder.h"
52 #include "AliMpExMap.h"
53 #include "AliMpExMapIterator.h"
54
55 #include "AliAlignObjMatrix.h"
56 #include "AliLog.h"
57
58 #include <TClonesArray.h>
59 #include <TGeoMatrix.h>
60 #include <TMatrixDSym.h>
61 #include <TMath.h>
62 #include <TRandom.h>
63 #include <Riostream.h>
64
65 /// \cond CLASSIMP
66 ClassImp(AliMUONGeometryMisAligner)
67 /// \endcond
68
69 //______________________________________________________________________________
70 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner(Double_t cartXMisAligM, Double_t cartXMisAligW, Double_t cartYMisAligM, Double_t cartYMisAligW, Double_t angMisAligM, Double_t angMisAligW)
71   : TObject(),
72     fUseUni(kFALSE),
73     fUseGaus(kTRUE),
74     fXYAngMisAligFactor(0.0),
75     fZCartMisAligFactor(0.0),
76     fDisplacementGenerator(0)
77 {
78   /// Standard constructor
79   for (Int_t i=0; i<6; i++){
80     for (Int_t j=0; j<2; j++){
81       fDetElemMisAlig[i][j] = 0.0;
82       fModuleMisAlig[i][j] = 0.0;
83     }
84   }
85   fDetElemMisAlig[0][0] = cartXMisAligM; 
86   fDetElemMisAlig[0][1] = cartXMisAligW; 
87   fDetElemMisAlig[1][0] = cartYMisAligM; 
88   fDetElemMisAlig[1][1] = cartYMisAligW; 
89   fDetElemMisAlig[5][0] = angMisAligM; 
90   fDetElemMisAlig[5][1] = angMisAligW;
91
92   fDisplacementGenerator = new TRandom(0);
93 }
94
95 //______________________________________________________________________________
96 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner(Double_t cartMisAligM, Double_t cartMisAligW, Double_t angMisAligM, Double_t angMisAligW)
97   : TObject(), 
98     fUseUni(kFALSE),
99     fUseGaus(kTRUE),
100     fXYAngMisAligFactor(0.0),
101     fZCartMisAligFactor(0.0),
102     fDisplacementGenerator(0)
103 {
104   /// Standard constructor
105   for (Int_t i=0; i<6; i++){
106     for (Int_t j=0; j<2; j++){
107       fDetElemMisAlig[i][j] = 0.0;
108       fModuleMisAlig[i][j] = 0.0;
109     }
110   }
111   fDetElemMisAlig[0][0] = cartMisAligM; 
112   fDetElemMisAlig[0][1] = cartMisAligW; 
113   fDetElemMisAlig[1][0] = cartMisAligM; 
114   fDetElemMisAlig[1][1] = cartMisAligW; 
115   fDetElemMisAlig[5][0] = angMisAligM; 
116   fDetElemMisAlig[5][1] = angMisAligW;
117
118   fDisplacementGenerator = new TRandom(0);
119 }
120
121 //______________________________________________________________________________
122 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner(Double_t cartMisAlig, Double_t angMisAlig)
123   : TObject(), 
124     fUseUni(kTRUE),
125     fUseGaus(kFALSE),
126     fXYAngMisAligFactor(0.0),
127     fZCartMisAligFactor(0.0),
128     fDisplacementGenerator(0)
129 {
130   /// Standard constructor
131   for (Int_t i=0; i<6; i++){
132     for (Int_t j=0; j<2; j++){
133       fDetElemMisAlig[i][j] = 0.0;
134       fModuleMisAlig[i][j] = 0.0;
135     }
136   }
137   fDetElemMisAlig[0][1] = cartMisAlig; 
138   fDetElemMisAlig[1][1] = cartMisAlig; 
139   fDetElemMisAlig[5][1] = angMisAlig;
140
141   fDisplacementGenerator = new TRandom(0);
142 }
143
144 //_____________________________________________________________________________
145 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner()
146   : TObject(), 
147     fUseUni(kTRUE),
148     fUseGaus(kFALSE),
149     fXYAngMisAligFactor(0.0),
150     fZCartMisAligFactor(0.0),
151     fDisplacementGenerator(0)
152 {
153   /// Default constructor
154   for (Int_t i=0; i<6; i++){
155     for (Int_t j=0; j<2; j++){
156       fDetElemMisAlig[i][j] = 0.0;
157       fModuleMisAlig[i][j] = 0.0;
158     }
159   }
160 }
161
162 //______________________________________________________________________________
163 AliMUONGeometryMisAligner::~AliMUONGeometryMisAligner()
164 {
165 /// Destructor
166
167   if (fDisplacementGenerator) delete fDisplacementGenerator;
168 }
169
170 //_________________________________________________________________________
171 void
172 AliMUONGeometryMisAligner::SetXYAngMisAligFactor(Double_t factor)
173 {
174   /// Set XY angular misalign factor 
175
176   if (TMath::Abs(factor) > 1.0 && factor > 0.){
177     fXYAngMisAligFactor = factor;
178     fDetElemMisAlig[3][0] = fDetElemMisAlig[5][0]*factor; // These lines were 
179     fDetElemMisAlig[3][1] = fDetElemMisAlig[5][1]*factor; // added to keep
180     fDetElemMisAlig[4][0] = fDetElemMisAlig[5][0]*factor; // backward 
181     fDetElemMisAlig[4][1] = fDetElemMisAlig[5][1]*factor; // compatibility 
182   }
183   else
184     AliError(Form("Invalid XY angular misalign factor, %d", factor));
185 }
186
187 //_________________________________________________________________________
188 void AliMUONGeometryMisAligner::SetZCartMisAligFactor(Double_t factor) 
189 {
190   /// Set XY angular misalign factor 
191   if (TMath::Abs(factor)<1.0 && factor>0.) {
192     fZCartMisAligFactor = factor;
193     fDetElemMisAlig[2][0] = fDetElemMisAlig[0][0];        // These lines were added to 
194     fDetElemMisAlig[2][1] = fDetElemMisAlig[0][1]*factor; // keep backward compatibility
195   }
196   else
197     AliError(Form("Invalid Z cartesian misalign factor, %d", factor));
198 }
199
200 //_________________________________________________________________________
201 void AliMUONGeometryMisAligner::GetUniMisAlign(Double_t cartMisAlig[3], Double_t angMisAlig[3], const Double_t lParMisAlig[6][2]) const
202 {
203   /// Misalign using uniform distribution
204   /**
205     misalign the centre of the local transformation
206     rotation axes : 
207     fAngMisAlig[1,2,3] = [x,y,z]
208     Assume that misalignment about the x and y axes (misalignment of z plane)
209     is much smaller, since the entire detection plane has to be moved (the 
210     detection elements are on a support structure), while rotation of the x-y
211     plane is more free.
212   */
213   cartMisAlig[0] = fDisplacementGenerator->Uniform(-lParMisAlig[0][1]+lParMisAlig[0][0], lParMisAlig[0][0]+lParMisAlig[0][1]);
214   cartMisAlig[1] = fDisplacementGenerator->Uniform(-lParMisAlig[1][1]+lParMisAlig[1][0], lParMisAlig[1][0]+lParMisAlig[1][1]);
215   cartMisAlig[2] = fDisplacementGenerator->Uniform(-lParMisAlig[2][1]+lParMisAlig[2][0], lParMisAlig[2][0]+lParMisAlig[2][1]);  
216  
217   angMisAlig[0] = fDisplacementGenerator->Uniform(-lParMisAlig[3][1]+lParMisAlig[3][0], lParMisAlig[3][0]+lParMisAlig[3][1]);
218   angMisAlig[1] = fDisplacementGenerator->Uniform(-lParMisAlig[4][1]+lParMisAlig[4][0], lParMisAlig[4][0]+lParMisAlig[4][1]);
219   angMisAlig[2] = fDisplacementGenerator->Uniform(-lParMisAlig[5][1]+lParMisAlig[5][0], lParMisAlig[5][0]+lParMisAlig[5][1]);   // degrees
220 }
221
222 //_________________________________________________________________________
223 void AliMUONGeometryMisAligner::GetGausMisAlign(Double_t cartMisAlig[3], Double_t angMisAlig[3], const Double_t lParMisAlig[6][2]) const
224 {
225   /// Misalign using gaussian distribution
226   /**
227     misalign the centre of the local transformation
228     rotation axes : 
229     fAngMisAlig[1,2,3] = [x,y,z]
230     Assume that misalignment about the x and y axes (misalignment of z plane)
231     is much smaller, since the entire detection plane has to be moved (the 
232     detection elements are on a support structure), while rotation of the x-y
233     plane is more free.
234   */
235   cartMisAlig[0] = fDisplacementGenerator->Gaus(lParMisAlig[0][0], lParMisAlig[0][1]);
236   cartMisAlig[1] = fDisplacementGenerator->Gaus(lParMisAlig[1][0], lParMisAlig[1][1]);
237   cartMisAlig[2] = fDisplacementGenerator->Gaus(lParMisAlig[2][0], lParMisAlig[2][1]);
238  
239   angMisAlig[0] = fDisplacementGenerator->Gaus(lParMisAlig[3][0], lParMisAlig[3][1]);
240   angMisAlig[1] = fDisplacementGenerator->Gaus(lParMisAlig[4][0], lParMisAlig[4][1]);
241   angMisAlig[2] = fDisplacementGenerator->Gaus(lParMisAlig[5][0], lParMisAlig[5][1]);   // degrees
242 }
243
244 //_________________________________________________________________________
245 TGeoCombiTrans AliMUONGeometryMisAligner::MisAlignDetElem(const TGeoCombiTrans & transform) const
246 {
247   /// Misalign given transformation and return the misaligned transformation. 
248   /// Use misalignment parameters for detection elements.
249   /// Note that applied misalignments are small deltas with respect to the detection 
250   /// element own ideal local reference frame. Thus deltaTransf represents 
251   /// the transformation to go from the misaligned d.e. local coordinates to the 
252   /// ideal d.e. local coordinates. 
253   /// Also note that this -is not- what is in the ALICE alignment framework known 
254   /// as local nor global (see AliMUONGeometryMisAligner::MisAlign) 
255   
256   Double_t cartMisAlig[3] = {0,0,0};
257   Double_t angMisAlig[3] = {0,0,0};
258
259   if (fUseUni) { 
260     GetUniMisAlign(cartMisAlig,angMisAlig,fDetElemMisAlig);
261   }
262   else { 
263     if (!fUseGaus) {
264       AliWarning("Neither uniform nor gausian distribution is set! Will use gausian...");
265     } 
266     GetGausMisAlign(cartMisAlig,angMisAlig,fDetElemMisAlig);
267   }
268
269   TGeoTranslation deltaTrans(cartMisAlig[0], cartMisAlig[1], cartMisAlig[2]);
270   TGeoRotation deltaRot;
271   deltaRot.RotateX(angMisAlig[0]);
272   deltaRot.RotateY(angMisAlig[1]);
273   deltaRot.RotateZ(angMisAlig[2]);
274
275   TGeoCombiTrans deltaTransf(deltaTrans,deltaRot);
276   TGeoHMatrix newTransfMat = transform * deltaTransf;
277     
278   AliInfo(Form("Rotated DE by %f about Z axis.", angMisAlig[2]));
279
280   return TGeoCombiTrans(newTransfMat);
281 }
282
283 //_________________________________________________________________________
284 TGeoCombiTrans AliMUONGeometryMisAligner::MisAlignModule(const TGeoCombiTrans & transform) const
285 {
286   /// Misalign given transformation and return the misaligned transformation. 
287   /// Use misalignment parameters for modules.
288   /// Note that applied misalignments are small deltas with respect to the module 
289   /// own ideal local reference frame. Thus deltaTransf represents 
290   /// the transformation to go from the misaligned module local coordinates to the 
291   /// ideal module local coordinates. 
292   /// Also note that this -is not- what is in the ALICE alignment framework known 
293   /// as local nor global (see AliMUONGeometryMisAligner::MisAlign) 
294   
295   Double_t cartMisAlig[3] = {0,0,0};
296   Double_t angMisAlig[3] = {0,0,0};
297
298   if (fUseUni) { 
299     GetUniMisAlign(cartMisAlig,angMisAlig,fModuleMisAlig);
300   }
301   else { 
302     if (!fUseGaus) {
303       AliWarning("Neither uniform nor gausian distribution is set! Will use gausian...");
304     } 
305     GetGausMisAlign(cartMisAlig,angMisAlig,fModuleMisAlig);
306   }
307
308   TGeoTranslation deltaTrans(cartMisAlig[0], cartMisAlig[1], cartMisAlig[2]);
309   TGeoRotation deltaRot;
310   deltaRot.RotateX(angMisAlig[0]);
311   deltaRot.RotateY(angMisAlig[1]);
312   deltaRot.RotateZ(angMisAlig[2]);
313
314   TGeoCombiTrans deltaTransf(deltaTrans,deltaRot);
315   TGeoHMatrix newTransfMat = transform * deltaTransf;
316
317   AliInfo(Form("Rotated Module by %f about Z axis.", angMisAlig[2]));
318
319   return TGeoCombiTrans(newTransfMat);
320 }
321
322 //______________________________________________________________________
323 AliMUONGeometryTransformer *
324 AliMUONGeometryMisAligner::MisAlign(const AliMUONGeometryTransformer *
325                                     transformer, Bool_t verbose)
326 {
327   /// Takes the internal geometry module transformers, copies them to
328   /// new geometry module transformers. 
329   /// Calculates  module misalignment parameters and applies these
330   /// to the new module transformer.
331   /// Calculates the module misalignment delta transformation in the 
332   /// Alice Alignment Framework newTransf = delta * oldTransf.
333   /// Add a module misalignment to the new geometry transformer.
334   /// Gets the Detection Elements from the module transformer. 
335   /// Calculates misalignment parameters and applies these
336   /// to the local transformation of the Detection Element.
337   /// Obtains the new global transformation by multiplying the new 
338   /// module transformer transformation with the new local transformation. 
339   /// Applies the new global transform to a new detection element.
340   /// Adds the new detection element to a new module transformer.
341   /// Calculates the d.e. misalignment delta transformation in the 
342   /// Alice Alignment Framework (newGlobalTransf = delta * oldGlobalTransf).
343   /// Add a d.e. misalignment to the new geometry transformer.
344   /// Adds the new module transformer to a new geometry transformer.
345   /// Returns the new geometry transformer.
346
347
348   AliMUONGeometryTransformer *newGeometryTransformer =
349     new AliMUONGeometryTransformer();
350   for (Int_t iMt = 0; iMt < transformer->GetNofModuleTransformers(); iMt++)
351     {                           // module transformers
352       const AliMUONGeometryModuleTransformer *kModuleTransformer =
353         transformer->GetModuleTransformer(iMt, true);
354       
355       AliMUONGeometryModuleTransformer *newModuleTransformer =
356         new AliMUONGeometryModuleTransformer(iMt);
357       newGeometryTransformer->AddModuleTransformer(newModuleTransformer);
358
359       TGeoCombiTrans moduleTransform =
360         TGeoCombiTrans(*kModuleTransformer->GetTransformation());
361       // New module transformation
362       TGeoCombiTrans newModuleTransform = MisAlignModule(moduleTransform);
363       newModuleTransformer->SetTransformation(newModuleTransform);
364
365       // Get delta transformation: 
366       // Tdelta = Tnew * Told.inverse
367       TGeoHMatrix deltaModuleTransform = 
368         AliMUONGeometryBuilder::Multiply(
369           newModuleTransform, 
370           kModuleTransformer->GetTransformation()->Inverse());
371
372       // Create module mis alignment matrix
373       newGeometryTransformer
374         ->AddMisAlignModule(kModuleTransformer->GetModuleId(), deltaModuleTransform);
375
376       AliMpExMap *detElements = kModuleTransformer->GetDetElementStore();
377
378       if (verbose)
379         AliInfo(Form("%i DEs in old GeometryStore  %i",detElements->GetSize(), iMt));
380
381       TIter next(detElements->CreateIterator());
382       AliMUONGeometryDetElement *detElement;
383       
384       while ( ( detElement = static_cast<AliMUONGeometryDetElement*>(next()) ) )
385       {
386           /// make a new detection element
387           AliMUONGeometryDetElement *newDetElement =
388             new AliMUONGeometryDetElement(detElement->GetId(),
389                                           detElement->GetVolumePath());
390
391           // local transformation of this detection element.
392           TGeoCombiTrans localTransform
393             = TGeoCombiTrans(*detElement->GetLocalTransformation());
394           TGeoCombiTrans newLocalTransform = MisAlignDetElem(localTransform);
395           newDetElement->SetLocalTransformation(newLocalTransform);
396
397
398           // global transformation
399           TGeoHMatrix newGlobalTransform =
400             AliMUONGeometryBuilder::Multiply(newModuleTransform,
401                                              newLocalTransform);
402           newDetElement->SetGlobalTransformation(newGlobalTransform);
403           
404           // add this det element to module
405           newModuleTransformer->GetDetElementStore()->Add(newDetElement->GetId(),
406                                                           newDetElement);
407
408           // In the Alice Alignment Framework misalignment objects store
409           // global delta transformation
410           // Get detection "intermediate" global transformation
411           TGeoHMatrix newOldGlobalTransform = newModuleTransform * localTransform;
412           // Get detection element global delta transformation: 
413           // Tdelta = Tnew * Told.inverse
414           TGeoHMatrix  deltaGlobalTransform
415             = AliMUONGeometryBuilder::Multiply(
416                 newGlobalTransform, 
417                 newOldGlobalTransform.Inverse());
418           
419           // Create mis alignment matrix
420           newGeometryTransformer
421             ->AddMisAlignDetElement(detElement->GetId(), deltaGlobalTransform);
422         }
423
424       
425       if (verbose)
426         AliInfo(Form("Added module transformer %i to the transformer", iMt));
427       newGeometryTransformer->AddModuleTransformer(newModuleTransformer);
428     }
429   return newGeometryTransformer;
430 }
431
432
433 void AliMUONGeometryMisAligner::SetAlignmentResolution(const TClonesArray* misAlignArray, Int_t rChId, Double_t rChResX, Double_t rChResY, Double_t rDeResX, Double_t rDeResY){
434
435   Int_t chIdMin = (rChId<0)? 0 : rChId;
436   Int_t chIdMax = (rChId<0)? 9 : rChId;
437   Double_t chResX = (rChResX<0)? fModuleMisAlig[0][1] : rChResX;
438   Double_t chResY = (rChResY<0)? fModuleMisAlig[1][1] : rChResY;
439   Double_t deResX = (rDeResX<0)? fDetElemMisAlig[0][1] : rDeResX;
440   Double_t deResY = (rDeResY<0)? fDetElemMisAlig[1][1] : rDeResY;
441
442   TMatrixDSym mChCorrMatrix(6);
443   mChCorrMatrix[0][0]=chResX*chResX;
444   mChCorrMatrix[1][1]=chResY*chResY;
445   //  mChCorrMatrix.Print();
446
447   TMatrixDSym mDECorrMatrix(6);
448   mDECorrMatrix[0][0]=deResX*deResX;
449   mDECorrMatrix[1][1]=deResY*deResY;
450   //  mDECorrMatrix.Print();
451
452   AliAlignObjMatrix *alignMat = 0x0;
453
454   for(Int_t chId=chIdMin; chId<=chIdMax; chId++) {
455     TString chName1;
456     TString chName2;
457     if (chId<4){
458       chName1 = Form("GM%d",chId);
459       chName2 = Form("GM%d",chId);
460     } else {
461       chName1 = Form("GM%d",4+(chId-4)*2);
462       chName2 = Form("GM%d",4+(chId-4)*2+1);
463     }
464     
465     for (int i=0; i<misAlignArray->GetEntries(); i++) {
466       alignMat = (AliAlignObjMatrix*)misAlignArray->At(i);
467       TString volName(alignMat->GetSymName());
468       if((volName.Contains(chName1)&&
469           ((volName.Last('/')==volName.Index(chName1)+chName1.Length())||
470            (volName.Length()==volName.Index(chName1)+chName1.Length())))||
471          (volName.Contains(chName2)&&
472           ((volName.Last('/')==volName.Index(chName2)+chName2.Length())||
473            (volName.Length()==volName.Index(chName2)+chName2.Length())))){
474         volName.Remove(0,volName.Last('/')+1);
475         if (volName.Contains("GM")) {
476           //    alignMat->Print("NULL");
477           alignMat->SetCorrMatrix(mChCorrMatrix);
478         } else if (volName.Contains("DE")) {
479           //    alignMat->Print("NULL");
480           alignMat->SetCorrMatrix(mDECorrMatrix);
481         }
482       }
483     }
484   }
485 }
486
487
488