]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONGeometryMisAligner.cxx
Version number incremented
[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
53 #include "AliMpExMap.h"
54
55 #include "AliLog.h"
56
57 #include <TGeoMatrix.h>
58 #include <TMath.h>
59 #include <TRandom.h>
60 #include <Riostream.h>
61
62 /// \cond CLASSIMP
63 ClassImp(AliMUONGeometryMisAligner)
64 /// \endcond
65
66 //______________________________________________________________________________
67 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner(Double_t cartXMisAligM, Double_t cartXMisAligW, Double_t cartYMisAligM, Double_t cartYMisAligW, Double_t angMisAligM, Double_t angMisAligW)
68   : TObject(),
69     fUseUni(kFALSE),
70     fUseGaus(kTRUE),
71     fXYAngMisAligFactor(0.0),
72     fZCartMisAligFactor(0.0),
73     fDisplacementGenerator(0)
74 {
75   /// Standard constructor
76   for (Int_t i=0; i<6; i++){
77     for (Int_t j=0; j<2; j++){
78       fDetElemMisAlig[i][j] = 0.0;
79       fModuleMisAlig[i][j] = 0.0;
80     }
81   }
82   fDetElemMisAlig[0][0] = cartXMisAligM; 
83   fDetElemMisAlig[0][1] = cartXMisAligW; 
84   fDetElemMisAlig[1][0] = cartYMisAligM; 
85   fDetElemMisAlig[1][1] = cartYMisAligW; 
86   fDetElemMisAlig[5][0] = angMisAligM; 
87   fDetElemMisAlig[5][1] = angMisAligW;
88
89   fDisplacementGenerator = new TRandom(0);
90 }
91
92 //______________________________________________________________________________
93 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner(Double_t cartMisAligM, Double_t cartMisAligW, Double_t angMisAligM, Double_t angMisAligW)
94   : TObject(), 
95     fUseUni(kFALSE),
96     fUseGaus(kTRUE),
97     fXYAngMisAligFactor(0.0),
98     fZCartMisAligFactor(0.0),
99     fDisplacementGenerator(0)
100 {
101   /// Standard constructor
102   for (Int_t i=0; i<6; i++){
103     for (Int_t j=0; j<2; j++){
104       fDetElemMisAlig[i][j] = 0.0;
105       fModuleMisAlig[i][j] = 0.0;
106     }
107   }
108   fDetElemMisAlig[0][0] = cartMisAligM; 
109   fDetElemMisAlig[0][1] = cartMisAligW; 
110   fDetElemMisAlig[1][0] = cartMisAligM; 
111   fDetElemMisAlig[1][1] = cartMisAligW; 
112   fDetElemMisAlig[5][0] = angMisAligM; 
113   fDetElemMisAlig[5][1] = angMisAligW;
114
115   fDisplacementGenerator = new TRandom(0);
116 }
117
118 //______________________________________________________________________________
119 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner(Double_t cartMisAlig, Double_t angMisAlig)
120   : TObject(), 
121     fUseUni(kTRUE),
122     fUseGaus(kFALSE),
123     fXYAngMisAligFactor(0.0),
124     fZCartMisAligFactor(0.0),
125     fDisplacementGenerator(0)
126 {
127   /// Standard constructor
128   for (Int_t i=0; i<6; i++){
129     for (Int_t j=0; j<2; j++){
130       fDetElemMisAlig[i][j] = 0.0;
131       fModuleMisAlig[i][j] = 0.0;
132     }
133   }
134   fDetElemMisAlig[0][1] = cartMisAlig; 
135   fDetElemMisAlig[1][1] = cartMisAlig; 
136   fDetElemMisAlig[5][1] = angMisAlig;
137
138   fDisplacementGenerator = new TRandom(0);
139 }
140
141 //_____________________________________________________________________________
142 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner()
143   : TObject(), 
144     fUseUni(kTRUE),
145     fUseGaus(kFALSE),
146     fXYAngMisAligFactor(0.0),
147     fZCartMisAligFactor(0.0),
148     fDisplacementGenerator(0)
149 {
150   /// Default constructor
151   for (Int_t i=0; i<6; i++){
152     for (Int_t j=0; j<2; j++){
153       fDetElemMisAlig[i][j] = 0.0;
154       fModuleMisAlig[i][j] = 0.0;
155     }
156   }
157 }
158
159 //______________________________________________________________________________
160 AliMUONGeometryMisAligner::~AliMUONGeometryMisAligner()
161 {
162 /// Destructor
163
164   if (fDisplacementGenerator) delete fDisplacementGenerator;
165 }
166
167 //_________________________________________________________________________
168 void
169 AliMUONGeometryMisAligner::SetXYAngMisAligFactor(Double_t factor)
170 {
171   /// Set XY angular misalign factor 
172
173   if (TMath::Abs(factor) > 1.0 && factor > 0.){
174     fXYAngMisAligFactor = factor;
175     fDetElemMisAlig[3][0] = fDetElemMisAlig[5][0]*factor; // These lines were 
176     fDetElemMisAlig[3][1] = fDetElemMisAlig[5][1]*factor; // added to keep
177     fDetElemMisAlig[4][0] = fDetElemMisAlig[5][0]*factor; // backward 
178     fDetElemMisAlig[4][1] = fDetElemMisAlig[5][1]*factor; // compatibility 
179   }
180   else
181     AliError(Form("Invalid XY angular misalign factor, %d", factor));
182 }
183
184 //_________________________________________________________________________
185 void AliMUONGeometryMisAligner::SetZCartMisAligFactor(Double_t factor) 
186 {
187   /// Set XY angular misalign factor 
188   if (TMath::Abs(factor)<1.0 && factor>0.) {
189     fZCartMisAligFactor = factor;
190     fDetElemMisAlig[2][0] = fDetElemMisAlig[0][0];        // These lines were added to 
191     fDetElemMisAlig[2][1] = fDetElemMisAlig[0][1]*factor; // keep backward compatibility
192   }
193   else
194     AliError(Form("Invalid Z cartesian misalign factor, %d", factor));
195 }
196
197 //_________________________________________________________________________
198 void AliMUONGeometryMisAligner::GetUniMisAlign(Double_t cartMisAlig[3], Double_t angMisAlig[3], const Double_t lParMisAlig[6][2]) const
199 {
200   /// Misalign using uniform distribution
201   /**
202     misalign the centre of the local transformation
203     rotation axes : 
204     fAngMisAlig[1,2,3] = [x,y,z]
205     Assume that misalignment about the x and y axes (misalignment of z plane)
206     is much smaller, since the entire detection plane has to be moved (the 
207     detection elements are on a support structure), while rotation of the x-y
208     plane is more free.
209   */
210   cartMisAlig[0] = fDisplacementGenerator->Uniform(-lParMisAlig[0][1]+lParMisAlig[0][0], lParMisAlig[0][0]+lParMisAlig[0][1]);
211   cartMisAlig[1] = fDisplacementGenerator->Uniform(-lParMisAlig[1][1]+lParMisAlig[1][0], lParMisAlig[1][0]+lParMisAlig[1][1]);
212   cartMisAlig[2] = fDisplacementGenerator->Uniform(-lParMisAlig[2][1]+lParMisAlig[2][0], lParMisAlig[2][0]+lParMisAlig[2][1]);  
213  
214   angMisAlig[0] = fDisplacementGenerator->Uniform(-lParMisAlig[3][1]+lParMisAlig[3][0], lParMisAlig[3][0]+lParMisAlig[3][1]);
215   angMisAlig[1] = fDisplacementGenerator->Uniform(-lParMisAlig[4][1]+lParMisAlig[4][0], lParMisAlig[4][0]+lParMisAlig[4][1]);
216   angMisAlig[2] = fDisplacementGenerator->Uniform(-lParMisAlig[5][1]+lParMisAlig[5][0], lParMisAlig[5][0]+lParMisAlig[5][1]);   // degrees
217 }
218
219 //_________________________________________________________________________
220 void AliMUONGeometryMisAligner::GetGausMisAlign(Double_t cartMisAlig[3], Double_t angMisAlig[3], const Double_t lParMisAlig[6][2]) const
221 {
222   /// Misalign using gaussian distribution
223   /**
224     misalign the centre of the local transformation
225     rotation axes : 
226     fAngMisAlig[1,2,3] = [x,y,z]
227     Assume that misalignment about the x and y axes (misalignment of z plane)
228     is much smaller, since the entire detection plane has to be moved (the 
229     detection elements are on a support structure), while rotation of the x-y
230     plane is more free.
231   */
232   cartMisAlig[0] = fDisplacementGenerator->Gaus(lParMisAlig[0][0], lParMisAlig[0][1]);
233   cartMisAlig[1] = fDisplacementGenerator->Gaus(lParMisAlig[1][0], lParMisAlig[1][1]);
234   cartMisAlig[2] = fDisplacementGenerator->Gaus(lParMisAlig[2][0], lParMisAlig[2][1]);
235  
236   angMisAlig[0] = fDisplacementGenerator->Gaus(lParMisAlig[3][0], lParMisAlig[3][1]);
237   angMisAlig[1] = fDisplacementGenerator->Gaus(lParMisAlig[4][0], lParMisAlig[4][1]);
238   angMisAlig[2] = fDisplacementGenerator->Gaus(lParMisAlig[5][0], lParMisAlig[5][1]);   // degrees
239 }
240
241 //_________________________________________________________________________
242 TGeoCombiTrans AliMUONGeometryMisAligner::MisAlignDetElem(const TGeoCombiTrans & transform) const
243 {
244   /// Misalign given transformation and return the misaligned transformation. 
245   /// Use misalignment parameters for detection elements.
246   /// Note that applied misalignments are small deltas with respect to the detection 
247   /// element own ideal local reference frame. Thus deltaTransf represents 
248   /// the transformation to go from the misaligned d.e. local coordinates to the 
249   /// ideal d.e. local coordinates. 
250   /// Also note that this -is not- what is in the ALICE alignment framework known 
251   /// as local nor global (see AliMUONGeometryMisAligner::MisAlign) 
252   
253   Double_t cartMisAlig[3] = {0,0,0};
254   Double_t angMisAlig[3] = {0,0,0};
255
256   if (fUseUni) { 
257     GetUniMisAlign(cartMisAlig,angMisAlig,fDetElemMisAlig);
258   }
259   else { 
260     if (!fUseGaus) {
261       AliWarning("Neither uniform nor gausian distribution is set! Will use gausian...");
262     } 
263     GetGausMisAlign(cartMisAlig,angMisAlig,fDetElemMisAlig);
264   }
265
266   TGeoTranslation deltaTrans(cartMisAlig[0], cartMisAlig[1], cartMisAlig[2]);
267   TGeoRotation deltaRot;
268   deltaRot.RotateX(angMisAlig[0]);
269   deltaRot.RotateY(angMisAlig[1]);
270   deltaRot.RotateZ(angMisAlig[2]);
271
272   TGeoCombiTrans deltaTransf(deltaTrans,deltaRot);
273   TGeoHMatrix newTransfMat = transform * deltaTransf;
274     
275   AliInfo(Form("Rotated DE by %f about Z axis.", angMisAlig[2]));
276
277   return TGeoCombiTrans(newTransfMat);
278 }
279
280 //_________________________________________________________________________
281 TGeoCombiTrans AliMUONGeometryMisAligner::MisAlignModule(const TGeoCombiTrans & transform) const
282 {
283   /// Misalign given transformation and return the misaligned transformation. 
284   /// Use misalignment parameters for modules.
285   /// Note that applied misalignments are small deltas with respect to the module 
286   /// own ideal local reference frame. Thus deltaTransf represents 
287   /// the transformation to go from the misaligned module local coordinates to the 
288   /// ideal module local coordinates. 
289   /// Also note that this -is not- what is in the ALICE alignment framework known 
290   /// as local nor global (see AliMUONGeometryMisAligner::MisAlign) 
291   
292   Double_t cartMisAlig[3] = {0,0,0};
293   Double_t angMisAlig[3] = {0,0,0};
294
295   if (fUseUni) { 
296     GetUniMisAlign(cartMisAlig,angMisAlig,fModuleMisAlig);
297   }
298   else { 
299     if (!fUseGaus) {
300       AliWarning("Neither uniform nor gausian distribution is set! Will use gausian...");
301     } 
302     GetGausMisAlign(cartMisAlig,angMisAlig,fModuleMisAlig);
303   }
304
305   TGeoTranslation deltaTrans(cartMisAlig[0], cartMisAlig[1], cartMisAlig[2]);
306   TGeoRotation deltaRot;
307   deltaRot.RotateX(angMisAlig[0]);
308   deltaRot.RotateY(angMisAlig[1]);
309   deltaRot.RotateZ(angMisAlig[2]);
310
311   TGeoCombiTrans deltaTransf(deltaTrans,deltaRot);
312   TGeoHMatrix newTransfMat = transform * deltaTransf;
313
314   AliInfo(Form("Rotated Module by %f about Z axis.", angMisAlig[2]));
315
316   return TGeoCombiTrans(newTransfMat);
317 }
318
319 //______________________________________________________________________
320 AliMUONGeometryTransformer *
321 AliMUONGeometryMisAligner::MisAlign(const AliMUONGeometryTransformer *
322                                     transformer, Bool_t verbose)
323 {
324   /// Takes the internal geometry module transformers, copies them to
325   /// new geometry module transformers. 
326   /// Calculates  module misalignment parameters and applies these
327   /// to the new module transformer.
328   /// Calculates the module misalignment delta transformation in the 
329   /// Alice Alignment Framework newTransf = delta * oldTransf.
330   /// Add a module misalignment to the new geometry transformer.
331   /// Gets the Detection Elements from the module transformer. 
332   /// Calculates misalignment parameters and applies these
333   /// to the local transformation of the Detection Element.
334   /// Obtains the new global transformation by multiplying the new 
335   /// module transformer transformation with the new local transformation. 
336   /// Applies the new global transform to a new detection element.
337   /// Adds the new detection element to a new module transformer.
338   /// Calculates the d.e. misalignment delta transformation in the 
339   /// Alice Alignment Framework (newGlobalTransf = delta * oldGlobalTransf).
340   /// Add a d.e. misalignment to the new geometry transformer.
341   /// Adds the new module transformer to a new geometry transformer.
342   /// Returns the new geometry transformer.
343
344
345   AliMUONGeometryTransformer *newGeometryTransformer =
346     new AliMUONGeometryTransformer();
347   for (Int_t iMt = 0; iMt < transformer->GetNofModuleTransformers(); iMt++)
348     {                           // module transformers
349       const AliMUONGeometryModuleTransformer *kModuleTransformer =
350         transformer->GetModuleTransformer(iMt, true);
351       
352       AliMUONGeometryModuleTransformer *newModuleTransformer =
353         new AliMUONGeometryModuleTransformer(iMt);
354       newGeometryTransformer->AddModuleTransformer(newModuleTransformer);
355
356       TGeoCombiTrans moduleTransform =
357         TGeoCombiTrans(*kModuleTransformer->GetTransformation());
358       // New module transformation
359       TGeoCombiTrans newModuleTransform = MisAlignModule(moduleTransform);
360       newModuleTransformer->SetTransformation(newModuleTransform);
361
362       // Get delta transformation: 
363       // Tdelta = Tnew * Told.inverse
364       TGeoHMatrix deltaModuleTransform = 
365         AliMUONGeometryBuilder::Multiply(
366           newModuleTransform, 
367           kModuleTransformer->GetTransformation()->Inverse());
368
369       // Create module mis alignment matrix
370       newGeometryTransformer
371         ->AddMisAlignModule(kModuleTransformer->GetModuleId(), deltaModuleTransform);
372
373       AliMpExMap *detElements = kModuleTransformer->GetDetElementStore();
374
375       if (verbose)
376         AliInfo(Form("%i DEs in old GeometryStore  %i",detElements->GetSize(), iMt));
377
378       for (Int_t iDe = 0; iDe < detElements->GetSize(); iDe++)
379         {                       // detection elements.
380           AliMUONGeometryDetElement *detElement =
381             (AliMUONGeometryDetElement *) detElements->GetObject(iDe);
382
383           if (!detElement)
384             AliFatal("Detection element not found.");
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
434