]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONGeometryMisAligner.cxx
New RAW I/O. I rolled my own, because I wasn't happy with the old
[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 // Class AliMUONGeometryMisAligner 
19 // ----------------------------
20 // Class for misalignment of geometry transformations
21 //
22 // Author:Bruce Becker
23
24 //__________________________________________________________________
25 //
26 /////////////////////////////////////////////////////////////////////
27 //This performs the misalignment on an existing muon arm geometry
28 //  based on the standard definition of the detector elements in 
29 //  $ALICE_ROOT/MUON/data
30 //
31 //  --> User has to specify the magnitude of the alignments, in the Cartesian 
32 //  co-ordiantes (which are used to apply translation misalignments) and in the
33 //  spherical co-ordinates (which are used to apply angular displacements)
34 //  --> If the constructor is used with no arguments, user has to set 
35 //  misalignment ranges by hand using the methods : 
36 //  SetApplyMisAlig, SetMaxCartMisAlig, SetMaxAngMisAlig, SetXYAngMisAligFactor
37 //  (last method takes account of the fact that the misalingment is greatest in 
38 //  the XY plane, since the detection elements are fixed to a support structure
39 //  in this plane. Misalignments in the XZ and YZ plane will be very small 
40 //  compared to those in the XY plane, which are small already - of the order 
41 //  of microns)
42
43 //  Note : If the detection elements are allowed to be misaligned in all
44 //  directions, this has consequences for the alignment algorithm
45 //  (AliMUONAlignment), which needs to know the number of free parameters. 
46 //  Eric only allowed 3 :  x,y,theta_xy, but in principle z and the other 
47 //  two angles are alignable as well.
48
49 #include "AliMUONGeometryMisAligner.h"
50 #include "AliMUONGeometryTransformer.h"
51 #include "AliMUONGeometryModuleTransformer.h"
52 #include "AliMUONGeometryDetElement.h"
53 #include "AliMUONGeometryStore.h"
54 #include "AliMUONGeometryBuilder.h"
55
56 #include "AliLog.h"
57
58 #include <TGeoManager.h>
59 #include <Riostream.h>
60 #include <TObjArray.h>
61 #include <TSystem.h>
62 #include <TMath.h>
63 #include <TRandom.h>
64
65 #include <sstream>
66
67 ClassImp(AliMUONGeometryMisAligner)
68 //______________________________________________________________________________
69 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner(Double_t cartMisAlig, Double_t angMisAlig)
70 :TObject(), fDisplacementGenerator(0)
71 {
72   /// Standard constructor
73   fMaxCartMisAlig = cartMisAlig;        // 0.5 mm. Perhaps this should go into AliMUONConstants.h ? 
74   fMaxAngMisAlig = angMisAlig;
75   fXYAngMisAligFactor = 1.0;
76   fDisplacementGenerator = new TRandom(0);
77 }
78
79 //_____________________________________________________________________________
80 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner()
81 :TObject(), fDisplacementGenerator(0)
82 {
83 /// Default constructor
84 }
85
86 //______________________________________________________________________________
87 AliMUONGeometryMisAligner::
88 AliMUONGeometryMisAligner(const AliMUONGeometryMisAligner & right):
89 TObject(right)
90 {
91   /// Copy constructor (not implemented)
92
93   AliFatal("Copy constructor not provided.");
94 }
95
96 //______________________________________________________________________________
97 AliMUONGeometryMisAligner::~AliMUONGeometryMisAligner()
98 {
99 /// Destructor
100
101   delete fDisplacementGenerator;
102 }
103
104 //______________________________________________________________________________
105 AliMUONGeometryMisAligner & AliMUONGeometryMisAligner::
106 operator=(const AliMUONGeometryMisAligner & right)
107 {
108   /// Assignement operator (not implemented)
109
110   // check assignement to self
111   if (this == &right)
112     return *this;
113
114   AliFatal("Assignement operator not provided.");
115
116   return *this;
117 }
118
119 //_________________________________________________________________________
120 void
121 AliMUONGeometryMisAligner::SetXYAngMisAligFactor(Double_t factor)
122 {
123   /// Set factor 
124
125   if (TMath::Abs(factor) > 1.0 && factor > 0.)
126     fXYAngMisAligFactor = factor;
127   else
128     AliError(Form("Invalid factor, %d", factor));
129 }
130
131 //_________________________________________________________________________
132 TGeoCombiTrans AliMUONGeometryMisAligner::MisAlign(const TGeoCombiTrans & transform) const
133 {
134   /// Misalign given transformation and return the misaligned transformation
135   
136   Double_t cartMisAlig[3] = {0,0,0};
137   Double_t angMisAlig[3] = {0,0,0};
138   const Double_t *trans = transform.GetTranslation();
139   TGeoRotation *rot;
140   // check if the rotation we obtain is not NULL
141   if (transform.GetRotation())
142     {
143       rot = transform.GetRotation();
144     }
145   else
146     {
147       rot = new TGeoRotation("rot");
148     }                   // default constructor.
149   
150   cartMisAlig[0] = fDisplacementGenerator->Uniform(-1. * fMaxCartMisAlig, fMaxCartMisAlig);
151   cartMisAlig[1] = fDisplacementGenerator->Uniform(-1. * fMaxCartMisAlig, fMaxCartMisAlig);
152   cartMisAlig[2] = fDisplacementGenerator->Uniform(-1. * fMaxCartMisAlig, fMaxCartMisAlig);
153   
154   TGeoTranslation newTrans(cartMisAlig[0] + trans[0], cartMisAlig[1] + trans[1], cartMisAlig[2] + trans[2]);
155   
156   /*
157     misalign the centre of the local transformation
158     rotation axes : 
159     fAngMisAlig[1,2,3] = [x,y,z]
160     Assume that misalignment about the x and y axes (misalignment of z plane)
161     is much smaller, since the entire detection plane has to be moved (the 
162     detection elements are on a support structure), while rotation of the x-y
163     plane is more free.
164   */
165   
166   angMisAlig[0] = fDisplacementGenerator->Uniform(fXYAngMisAligFactor * fMaxAngMisAlig,  1.0 * fMaxAngMisAlig);
167   angMisAlig[1] =    fDisplacementGenerator->Uniform(fXYAngMisAligFactor * fMaxAngMisAlig, 1.0 * fMaxAngMisAlig);
168   angMisAlig[2] = fDisplacementGenerator->Uniform(-1. * fMaxAngMisAlig, fMaxAngMisAlig);        // degrees
169   AliInfo(Form("Rotated by %f about Z axis.", angMisAlig[2]));
170   rot->RotateX(angMisAlig[0]);
171   rot->RotateY(angMisAlig[1]);
172   rot->RotateZ(angMisAlig[2]);
173
174   return TGeoCombiTrans(newTrans, *rot);
175 }
176
177
178 //______________________________________________________________________
179 AliMUONGeometryTransformer *
180 AliMUONGeometryMisAligner::MisAlign(const AliMUONGeometryTransformer *
181                                  transformer, Bool_t verbose)
182 {
183   /////////////////////////////////////////////////////////////////////
184   //   Takes the internal geometry module transformers, copies them
185   // and gets the Detection Elements from them.
186   // Calculates misalignment parameters and applies these
187   // to the local transform of the Detection Element
188   // Obtains the global transform by multiplying the module transformer
189   // transformation with the local transformation 
190   // Applies the global transform to a new detection element
191   // Adds the new detection element to a new module transformer
192   // Adds the new module transformer to a new geometry transformer
193   // Returns the new geometry transformer
194
195
196   AliMUONGeometryTransformer *newGeometryTransformer =
197     new AliMUONGeometryTransformer(kTRUE);
198   for (Int_t iMt = 0; iMt < transformer->GetNofModuleTransformers(); iMt++)
199     {                           // module transformers
200       
201       const AliMUONGeometryModuleTransformer *kModuleTransformer =
202         transformer->GetModuleTransformer(iMt, true);
203       
204       AliMUONGeometryModuleTransformer *newModuleTransformer =
205         new AliMUONGeometryModuleTransformer(iMt);
206       newGeometryTransformer->AddModuleTransformer(newModuleTransformer);
207
208       TGeoCombiTrans moduleTransform =
209         TGeoCombiTrans(*kModuleTransformer->GetTransformation());
210       TGeoCombiTrans *newModuleTransform = new TGeoCombiTrans(moduleTransform); 
211               // same module transform as the previous one 
212               // no mis align object created
213       newModuleTransformer->SetTransformation(moduleTransform);
214
215       AliMUONGeometryStore *detElements =
216         kModuleTransformer->GetDetElementStore();
217
218       if (verbose)
219         AliInfo(Form
220                 ("%i DEs in old GeometryStore  %i",
221                  detElements->GetNofEntries(), iMt));
222
223       for (Int_t iDe = 0; iDe < detElements->GetNofEntries(); iDe++)
224         {                       // detection elements.
225           AliMUONGeometryDetElement *detElement =
226             (AliMUONGeometryDetElement *) detElements->GetEntry(iDe);
227           if (!detElement)
228             AliFatal("Detection element not found.");
229
230           /// make a new detection element
231           AliMUONGeometryDetElement *newDetElement =
232             new AliMUONGeometryDetElement(detElement->GetId(),
233                                           detElement->GetVolumePath());
234
235           // local transformation of this detection element.
236           TGeoCombiTrans localTransform
237             = TGeoCombiTrans(*detElement->GetLocalTransformation());
238           TGeoCombiTrans newLocalTransform = MisAlign(localTransform);
239           newDetElement->SetLocalTransformation(newLocalTransform);                                       
240
241           // global transformation
242           TGeoHMatrix newGlobalTransform =
243             AliMUONGeometryBuilder::Multiply(*newModuleTransform,
244                                               newLocalTransform);
245           newDetElement->SetGlobalTransformation(newGlobalTransform);
246           
247           // add this det element to module
248           newModuleTransformer->GetDetElementStore()->Add(newDetElement->GetId(),
249                                                           newDetElement);
250           // Get delta transformation: 
251           // Tdelta = Tnew * Told.inverse
252           TGeoHMatrix  deltaTransform
253             = AliMUONGeometryBuilder::Multiply(
254                 newGlobalTransform, 
255                 detElement->GetGlobalTransformation()->Inverse());
256           
257           // Create mis alignment matrix
258           newGeometryTransformer
259             ->AddMisAlignDetElement(detElement->GetId(), deltaTransform);
260         }
261       if (verbose)
262         AliInfo(Form("Added module transformer %i to the transformer", iMt));
263       newGeometryTransformer->AddModuleTransformer(newModuleTransformer);
264     }
265   return newGeometryTransformer;
266 }
267
268
269
270