- Revised comments and adapted them for Doxygen
[u/mrichter/AliRoot.git] / MUON / AliMUONGeometryMisAligner.cxx
CommitLineData
21dd83fc 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//
21dd83fc 18//__________________________________________________________________
a9aad96e 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
21dd83fc 45
21dd83fc 46#include "AliMUONGeometryMisAligner.h"
47#include "AliMUONGeometryTransformer.h"
48#include "AliMUONGeometryModuleTransformer.h"
49#include "AliMUONGeometryDetElement.h"
50#include "AliMUONGeometryStore.h"
51#include "AliMUONGeometryBuilder.h"
ef79ed3a 52
53#include "AliLog.h"
54
328e160e 55#include <TGeoMatrix.h>
21dd83fc 56#include <TMath.h>
57#include <TRandom.h>
58
a9aad96e 59/// \cond CLASSIMP
21dd83fc 60ClassImp(AliMUONGeometryMisAligner)
a9aad96e 61/// \endcond
62
21dd83fc 63//______________________________________________________________________________
328e160e 64AliMUONGeometryMisAligner::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//______________________________________________________________________________
82AliMUONGeometryMisAligner::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//______________________________________________________________________________
21dd83fc 100AliMUONGeometryMisAligner::AliMUONGeometryMisAligner(Double_t cartMisAlig, Double_t angMisAlig)
101:TObject(), fDisplacementGenerator(0)
102{
103 /// Standard constructor
328e160e 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;
21dd83fc 112 fDisplacementGenerator = new TRandom(0);
328e160e 113 fUseUni = kTRUE;
114 fUseGaus = kFALSE;
21dd83fc 115}
116
117//_____________________________________________________________________________
118AliMUONGeometryMisAligner::AliMUONGeometryMisAligner()
119:TObject(), fDisplacementGenerator(0)
120{
121/// Default constructor
122}
123
124//______________________________________________________________________________
21dd83fc 125AliMUONGeometryMisAligner::~AliMUONGeometryMisAligner()
126{
127/// Destructor
128
129 delete fDisplacementGenerator;
130}
131
490da820 132//_________________________________________________________________________
21dd83fc 133void
134AliMUONGeometryMisAligner::SetXYAngMisAligFactor(Double_t factor)
135{
328e160e 136 /// Set XY angular misalign factor
490da820 137
21dd83fc 138 if (TMath::Abs(factor) > 1.0 && factor > 0.)
139 fXYAngMisAligFactor = factor;
140 else
328e160e 141 AliError(Form("Invalid XY angular misalign factor, %d", factor));
142}
143
144//_________________________________________________________________________
145void 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//_________________________________________________________________________
a9aad96e 155void AliMUONGeometryMisAligner::GetUniMisAlign(Double_t cartMisAlig[3], Double_t angMisAlig[3]) const
328e160e 156{
157 /// Misalign using uniform distribution
a9aad96e 158 /**
328e160e 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//_________________________________________________________________________
177void AliMUONGeometryMisAligner::GetGausMisAlign(Double_t cartMisAlig[3], Double_t angMisAlig[3]) const
178{
179 /// Misalign using gaussian distribution
a9aad96e 180 /**
328e160e 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
21dd83fc 196}
197
198//_________________________________________________________________________
199TGeoCombiTrans 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.
328e160e 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
21dd83fc 227 TGeoTranslation newTrans(cartMisAlig[0] + trans[0], cartMisAlig[1] + trans[1], cartMisAlig[2] + trans[2]);
228
21dd83fc 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
21dd83fc 237//______________________________________________________________________
238AliMUONGeometryTransformer *
239AliMUONGeometryMisAligner::MisAlign(const AliMUONGeometryTransformer *
240 transformer, Bool_t verbose)
241{
a9aad96e 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
21dd83fc 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
ef79ed3a 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);
21dd83fc 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
ef79ed3a 288 /// make a new detection element
21dd83fc 289 AliMUONGeometryDetElement *newDetElement =
290 new AliMUONGeometryDetElement(detElement->GetId(),
ef79ed3a 291 detElement->GetVolumePath());
21dd83fc 292
ef79ed3a 293 // local transformation of this detection element.
294 TGeoCombiTrans localTransform
295 = TGeoCombiTrans(*detElement->GetLocalTransformation());
296 TGeoCombiTrans newLocalTransform = MisAlign(localTransform);
297 newDetElement->SetLocalTransformation(newLocalTransform);
21dd83fc 298
ef79ed3a 299 // global transformation
300 TGeoHMatrix newGlobalTransform =
301 AliMUONGeometryBuilder::Multiply(*newModuleTransform,
302 newLocalTransform);
21dd83fc 303 newDetElement->SetGlobalTransformation(newGlobalTransform);
ef79ed3a 304
305 // add this det element to module
306 newModuleTransformer->GetDetElementStore()->Add(newDetElement->GetId(),
21dd83fc 307 newDetElement);
ef79ed3a 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);
21dd83fc 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