]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONGeometryMisAligner.cxx
- Revised comments and adapted them for Doxygen
[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 /// \authors Bruce Becker, Javier Castillo
45
46 #include "AliMUONGeometryMisAligner.h"
47 #include "AliMUONGeometryTransformer.h"
48 #include "AliMUONGeometryModuleTransformer.h"
49 #include "AliMUONGeometryDetElement.h"
50 #include "AliMUONGeometryStore.h"
51 #include "AliMUONGeometryBuilder.h"
52
53 #include "AliLog.h"
54
55 #include <TGeoMatrix.h>
56 #include <TMath.h>
57 #include <TRandom.h>
58
59 /// \cond CLASSIMP
60 ClassImp(AliMUONGeometryMisAligner)
61 /// \endcond
62
63 //______________________________________________________________________________
64 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner(Double_t cartXMisAligM, Double_t cartXMisAligW, Double_t cartYMisAligM, Double_t cartYMisAligW, Double_t angMisAligM, Double_t angMisAligW)
65 :TObject(), fDisplacementGenerator(0)
66 {
67   /// Standard constructor
68   fCartXMisAligM = cartXMisAligM;
69   fCartXMisAligW = cartXMisAligW;       // 0.5 mm. Perhaps this should go into AliMUONConstants.h ? 
70   fCartYMisAligM = cartYMisAligM;
71   fCartYMisAligW = cartYMisAligW;       // 0.5 mm. Perhaps this should go into AliMUONConstants.h ? 
72   fAngMisAligM = angMisAligM;
73   fAngMisAligW = angMisAligW;
74   fXYAngMisAligFactor = 0.0;
75   fZCartMisAligFactor = 0.0;
76   fDisplacementGenerator = new TRandom(0);
77   fUseUni = kFALSE;
78   fUseGaus = kTRUE;
79 }
80
81 //______________________________________________________________________________
82 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner(Double_t cartMisAligM, Double_t cartMisAligW, Double_t angMisAligM, Double_t angMisAligW)
83 :TObject(), fDisplacementGenerator(0)
84 {
85   /// Standard constructor
86   fCartXMisAligM = cartMisAligM;
87   fCartXMisAligW = cartMisAligW;        // 0.5 mm. Perhaps this should go into AliMUONConstants.h ? 
88   fCartYMisAligM = cartMisAligM;
89   fCartYMisAligW = cartMisAligW;        // 0.5 mm. Perhaps this should go into AliMUONConstants.h ? 
90   fAngMisAligM = angMisAligM;
91   fAngMisAligW = angMisAligW;
92   fXYAngMisAligFactor = 0.0;
93   fZCartMisAligFactor = 0.0;
94   fDisplacementGenerator = new TRandom(0);
95   fUseUni = kFALSE;
96   fUseGaus = kTRUE;
97 }
98
99 //______________________________________________________________________________
100 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner(Double_t cartMisAlig, Double_t angMisAlig)
101 :TObject(), fDisplacementGenerator(0)
102 {
103   /// Standard constructor
104   fCartXMisAligM = 0.;
105   fCartXMisAligW = cartMisAlig; // 0.5 mm. Perhaps this should go into AliMUONConstants.h ? 
106   fCartYMisAligM = 0.;
107   fCartYMisAligW = cartMisAlig; // 0.5 mm. Perhaps this should go into AliMUONConstants.h ? 
108   fAngMisAligM = 0.;
109   fAngMisAligW = angMisAlig;
110   fXYAngMisAligFactor = 0.0;
111   fZCartMisAligFactor = 0.0;
112   fDisplacementGenerator = new TRandom(0);
113   fUseUni = kTRUE;
114   fUseGaus = kFALSE;
115 }
116
117 //_____________________________________________________________________________
118 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner()
119 :TObject(), fDisplacementGenerator(0)
120 {
121 /// Default constructor
122 }
123
124 //______________________________________________________________________________
125 AliMUONGeometryMisAligner::~AliMUONGeometryMisAligner()
126 {
127 /// Destructor
128
129   delete fDisplacementGenerator;
130 }
131
132 //_________________________________________________________________________
133 void
134 AliMUONGeometryMisAligner::SetXYAngMisAligFactor(Double_t factor)
135 {
136   /// Set XY angular misalign factor 
137
138   if (TMath::Abs(factor) > 1.0 && factor > 0.)
139     fXYAngMisAligFactor = factor;
140   else
141     AliError(Form("Invalid XY angular misalign factor, %d", factor));
142 }
143
144 //_________________________________________________________________________
145 void AliMUONGeometryMisAligner::SetZCartMisAligFactor(Double_t factor) 
146 {
147   /// Set XY angular misalign factor 
148   if (TMath::Abs(factor)<1.0 && factor>0.)
149     fZCartMisAligFactor = factor;
150   else
151     AliError(Form("Invalid Z cartesian misalign factor, %d", factor));
152 }
153
154 //_________________________________________________________________________
155 void AliMUONGeometryMisAligner::GetUniMisAlign(Double_t cartMisAlig[3], Double_t angMisAlig[3]) const
156 {
157   /// Misalign using uniform distribution
158   /**
159     misalign the centre of the local transformation
160     rotation axes : 
161     fAngMisAlig[1,2,3] = [x,y,z]
162     Assume that misalignment about the x and y axes (misalignment of z plane)
163     is much smaller, since the entire detection plane has to be moved (the 
164     detection elements are on a support structure), while rotation of the x-y
165     plane is more free.
166   */
167   cartMisAlig[0] = fDisplacementGenerator->Uniform(-fCartXMisAligW+fCartXMisAligM, fCartXMisAligM+fCartXMisAligW);
168   cartMisAlig[1] = fDisplacementGenerator->Uniform(-fCartYMisAligW+fCartYMisAligM, fCartYMisAligM+fCartYMisAligW);
169   cartMisAlig[2] = fDisplacementGenerator->Uniform(-fZCartMisAligFactor*(fCartXMisAligW+fCartXMisAligM), fZCartMisAligFactor*(fCartXMisAligM+fCartXMisAligW));  
170  
171   angMisAlig[0] = fDisplacementGenerator->Uniform(-fXYAngMisAligFactor*(fAngMisAligW+fAngMisAligM), fXYAngMisAligFactor*(fAngMisAligM+fAngMisAligW));
172   angMisAlig[1] = fDisplacementGenerator->Uniform(-fXYAngMisAligFactor*(fAngMisAligW+fAngMisAligM), fXYAngMisAligFactor*(fAngMisAligM+fAngMisAligW));
173   angMisAlig[2] = fDisplacementGenerator->Uniform(-fAngMisAligW+fAngMisAligM, fAngMisAligM+fAngMisAligW);       // degrees
174 }
175
176 //_________________________________________________________________________
177 void AliMUONGeometryMisAligner::GetGausMisAlign(Double_t cartMisAlig[3], Double_t angMisAlig[3]) const
178 {
179   /// Misalign using gaussian distribution
180   /**
181     misalign the centre of the local transformation
182     rotation axes : 
183     fAngMisAlig[1,2,3] = [x,y,z]
184     Assume that misalignment about the x and y axes (misalignment of z plane)
185     is much smaller, since the entire detection plane has to be moved (the 
186     detection elements are on a support structure), while rotation of the x-y
187     plane is more free.
188   */
189   cartMisAlig[0] = fDisplacementGenerator->Gaus(fCartXMisAligM, fCartXMisAligW);
190   cartMisAlig[1] = fDisplacementGenerator->Gaus(fCartYMisAligM, fCartYMisAligW);
191   cartMisAlig[2] = fDisplacementGenerator->Gaus(fCartXMisAligM, fZCartMisAligFactor*fCartXMisAligW);
192  
193   angMisAlig[0] = fDisplacementGenerator->Gaus(fAngMisAligM, fXYAngMisAligFactor*fAngMisAligW);
194   angMisAlig[1] = fDisplacementGenerator->Gaus(fAngMisAligM, fXYAngMisAligFactor*fAngMisAligW);
195   angMisAlig[2] = fDisplacementGenerator->Gaus(fAngMisAligM, fAngMisAligW);     // degrees
196 }
197
198 //_________________________________________________________________________
199 TGeoCombiTrans AliMUONGeometryMisAligner::MisAlign(const TGeoCombiTrans & transform) const
200 {
201   /// Misalign given transformation and return the misaligned transformation
202   
203   Double_t cartMisAlig[3] = {0,0,0};
204   Double_t angMisAlig[3] = {0,0,0};
205   const Double_t *trans = transform.GetTranslation();
206   TGeoRotation *rot;
207   // check if the rotation we obtain is not NULL
208   if (transform.GetRotation())
209     {
210       rot = transform.GetRotation();
211     }
212   else
213     {
214       rot = new TGeoRotation("rot");
215     }                   // default constructor.
216
217   if (fUseUni) { 
218     GetUniMisAlign(cartMisAlig,angMisAlig);
219   }
220   else { 
221     if (!fUseGaus) {
222       AliWarning("Neither uniform nor gausian distribution is set! Will use gausian...");
223     } 
224     GetGausMisAlign(cartMisAlig,angMisAlig);
225   }
226
227   TGeoTranslation newTrans(cartMisAlig[0] + trans[0], cartMisAlig[1] + trans[1], cartMisAlig[2] + trans[2]);
228   
229   AliInfo(Form("Rotated by %f about Z axis.", angMisAlig[2]));
230   rot->RotateX(angMisAlig[0]);
231   rot->RotateY(angMisAlig[1]);
232   rot->RotateZ(angMisAlig[2]);
233
234   return TGeoCombiTrans(newTrans, *rot);
235 }
236
237 //______________________________________________________________________
238 AliMUONGeometryTransformer *
239 AliMUONGeometryMisAligner::MisAlign(const AliMUONGeometryTransformer *
240                                  transformer, Bool_t verbose)
241 {
242   /// Takes the internal geometry module transformers, copies them
243   /// and gets the Detection Elements from them.
244   /// Calculates misalignment parameters and applies these
245   /// to the local transform of the Detection Element
246   /// Obtains the global transform by multiplying the module transformer
247   /// transformation with the local transformation 
248   /// Applies the global transform to a new detection element
249   /// Adds the new detection element to a new module transformer
250   /// Adds the new module transformer to a new geometry transformer
251   /// Returns the new geometry transformer
252
253
254   AliMUONGeometryTransformer *newGeometryTransformer =
255     new AliMUONGeometryTransformer(kTRUE);
256   for (Int_t iMt = 0; iMt < transformer->GetNofModuleTransformers(); iMt++)
257     {                           // module transformers
258       
259       const AliMUONGeometryModuleTransformer *kModuleTransformer =
260         transformer->GetModuleTransformer(iMt, true);
261       
262       AliMUONGeometryModuleTransformer *newModuleTransformer =
263         new AliMUONGeometryModuleTransformer(iMt);
264       newGeometryTransformer->AddModuleTransformer(newModuleTransformer);
265
266       TGeoCombiTrans moduleTransform =
267         TGeoCombiTrans(*kModuleTransformer->GetTransformation());
268       TGeoCombiTrans *newModuleTransform = new TGeoCombiTrans(moduleTransform); 
269               // same module transform as the previous one 
270               // no mis align object created
271       newModuleTransformer->SetTransformation(moduleTransform);
272
273       AliMUONGeometryStore *detElements =
274         kModuleTransformer->GetDetElementStore();
275
276       if (verbose)
277         AliInfo(Form
278                 ("%i DEs in old GeometryStore  %i",
279                  detElements->GetNofEntries(), iMt));
280
281       for (Int_t iDe = 0; iDe < detElements->GetNofEntries(); iDe++)
282         {                       // detection elements.
283           AliMUONGeometryDetElement *detElement =
284             (AliMUONGeometryDetElement *) detElements->GetEntry(iDe);
285           if (!detElement)
286             AliFatal("Detection element not found.");
287
288           /// make a new detection element
289           AliMUONGeometryDetElement *newDetElement =
290             new AliMUONGeometryDetElement(detElement->GetId(),
291                                           detElement->GetVolumePath());
292
293           // local transformation of this detection element.
294           TGeoCombiTrans localTransform
295             = TGeoCombiTrans(*detElement->GetLocalTransformation());
296           TGeoCombiTrans newLocalTransform = MisAlign(localTransform);
297           newDetElement->SetLocalTransformation(newLocalTransform);                                       
298
299           // global transformation
300           TGeoHMatrix newGlobalTransform =
301             AliMUONGeometryBuilder::Multiply(*newModuleTransform,
302                                               newLocalTransform);
303           newDetElement->SetGlobalTransformation(newGlobalTransform);
304           
305           // add this det element to module
306           newModuleTransformer->GetDetElementStore()->Add(newDetElement->GetId(),
307                                                           newDetElement);
308           // Get delta transformation: 
309           // Tdelta = Tnew * Told.inverse
310           TGeoHMatrix  deltaTransform
311             = AliMUONGeometryBuilder::Multiply(
312                 newGlobalTransform, 
313                 detElement->GetGlobalTransformation()->Inverse());
314           
315           // Create mis alignment matrix
316           newGeometryTransformer
317             ->AddMisAlignDetElement(detElement->GetId(), deltaTransform);
318         }
319       if (verbose)
320         AliInfo(Form("Added module transformer %i to the transformer", iMt));
321       newGeometryTransformer->AddModuleTransformer(newModuleTransformer);
322     }
323   return newGeometryTransformer;
324 }
325
326
327
328