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. *
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 **************************************************************************/
18 //__________________________________________________________________
19 /// \class AliMUONGeometryMisAligner
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
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)
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
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.
44 /// \authors Bruce Becker, Javier Castillo
46 #include "AliMUONGeometryMisAligner.h"
47 #include "AliMUONGeometryTransformer.h"
48 #include "AliMUONGeometryModuleTransformer.h"
49 #include "AliMUONGeometryDetElement.h"
50 #include "AliMUONGeometryStore.h"
51 #include "AliMUONGeometryBuilder.h"
55 #include <TGeoMatrix.h>
60 ClassImp(AliMUONGeometryMisAligner)
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)
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);
81 //______________________________________________________________________________
82 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner(Double_t cartMisAligM, Double_t cartMisAligW, Double_t angMisAligM, Double_t angMisAligW)
83 :TObject(), fDisplacementGenerator(0)
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);
99 //______________________________________________________________________________
100 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner(Double_t cartMisAlig, Double_t angMisAlig)
101 :TObject(), fDisplacementGenerator(0)
103 /// Standard constructor
105 fCartXMisAligW = cartMisAlig; // 0.5 mm. Perhaps this should go into AliMUONConstants.h ?
107 fCartYMisAligW = cartMisAlig; // 0.5 mm. Perhaps this should go into AliMUONConstants.h ?
109 fAngMisAligW = angMisAlig;
110 fXYAngMisAligFactor = 0.0;
111 fZCartMisAligFactor = 0.0;
112 fDisplacementGenerator = new TRandom(0);
117 //_____________________________________________________________________________
118 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner()
119 :TObject(), fDisplacementGenerator(0)
121 /// Default constructor
124 //______________________________________________________________________________
125 AliMUONGeometryMisAligner::~AliMUONGeometryMisAligner()
129 delete fDisplacementGenerator;
132 //_________________________________________________________________________
134 AliMUONGeometryMisAligner::SetXYAngMisAligFactor(Double_t factor)
136 /// Set XY angular misalign factor
138 if (TMath::Abs(factor) > 1.0 && factor > 0.)
139 fXYAngMisAligFactor = factor;
141 AliError(Form("Invalid XY angular misalign factor, %d", factor));
144 //_________________________________________________________________________
145 void AliMUONGeometryMisAligner::SetZCartMisAligFactor(Double_t factor)
147 /// Set XY angular misalign factor
148 if (TMath::Abs(factor)<1.0 && factor>0.)
149 fZCartMisAligFactor = factor;
151 AliError(Form("Invalid Z cartesian misalign factor, %d", factor));
154 //_________________________________________________________________________
155 void AliMUONGeometryMisAligner::GetUniMisAlign(Double_t cartMisAlig[3], Double_t angMisAlig[3]) const
157 /// Misalign using uniform distribution
159 misalign the centre of the local transformation
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
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));
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
176 //_________________________________________________________________________
177 void AliMUONGeometryMisAligner::GetGausMisAlign(Double_t cartMisAlig[3], Double_t angMisAlig[3]) const
179 /// Misalign using gaussian distribution
181 misalign the centre of the local transformation
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
189 cartMisAlig[0] = fDisplacementGenerator->Gaus(fCartXMisAligM, fCartXMisAligW);
190 cartMisAlig[1] = fDisplacementGenerator->Gaus(fCartYMisAligM, fCartYMisAligW);
191 cartMisAlig[2] = fDisplacementGenerator->Gaus(fCartXMisAligM, fZCartMisAligFactor*fCartXMisAligW);
193 angMisAlig[0] = fDisplacementGenerator->Gaus(fAngMisAligM, fXYAngMisAligFactor*fAngMisAligW);
194 angMisAlig[1] = fDisplacementGenerator->Gaus(fAngMisAligM, fXYAngMisAligFactor*fAngMisAligW);
195 angMisAlig[2] = fDisplacementGenerator->Gaus(fAngMisAligM, fAngMisAligW); // degrees
198 //_________________________________________________________________________
199 TGeoCombiTrans AliMUONGeometryMisAligner::MisAlign(const TGeoCombiTrans & transform) const
201 /// Misalign given transformation and return the misaligned transformation
203 Double_t cartMisAlig[3] = {0,0,0};
204 Double_t angMisAlig[3] = {0,0,0};
205 const Double_t *trans = transform.GetTranslation();
207 // check if the rotation we obtain is not NULL
208 if (transform.GetRotation())
210 rot = transform.GetRotation();
214 rot = new TGeoRotation("rot");
215 } // default constructor.
218 GetUniMisAlign(cartMisAlig,angMisAlig);
222 AliWarning("Neither uniform nor gausian distribution is set! Will use gausian...");
224 GetGausMisAlign(cartMisAlig,angMisAlig);
227 TGeoTranslation newTrans(cartMisAlig[0] + trans[0], cartMisAlig[1] + trans[1], cartMisAlig[2] + trans[2]);
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]);
234 return TGeoCombiTrans(newTrans, *rot);
237 //______________________________________________________________________
238 AliMUONGeometryTransformer *
239 AliMUONGeometryMisAligner::MisAlign(const AliMUONGeometryTransformer *
240 transformer, Bool_t verbose)
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
254 AliMUONGeometryTransformer *newGeometryTransformer =
255 new AliMUONGeometryTransformer(kTRUE);
256 for (Int_t iMt = 0; iMt < transformer->GetNofModuleTransformers(); iMt++)
257 { // module transformers
259 const AliMUONGeometryModuleTransformer *kModuleTransformer =
260 transformer->GetModuleTransformer(iMt, true);
262 AliMUONGeometryModuleTransformer *newModuleTransformer =
263 new AliMUONGeometryModuleTransformer(iMt);
264 newGeometryTransformer->AddModuleTransformer(newModuleTransformer);
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);
273 AliMUONGeometryStore *detElements =
274 kModuleTransformer->GetDetElementStore();
278 ("%i DEs in old GeometryStore %i",
279 detElements->GetNofEntries(), iMt));
281 for (Int_t iDe = 0; iDe < detElements->GetNofEntries(); iDe++)
282 { // detection elements.
283 AliMUONGeometryDetElement *detElement =
284 (AliMUONGeometryDetElement *) detElements->GetEntry(iDe);
286 AliFatal("Detection element not found.");
288 /// make a new detection element
289 AliMUONGeometryDetElement *newDetElement =
290 new AliMUONGeometryDetElement(detElement->GetId(),
291 detElement->GetVolumePath());
293 // local transformation of this detection element.
294 TGeoCombiTrans localTransform
295 = TGeoCombiTrans(*detElement->GetLocalTransformation());
296 TGeoCombiTrans newLocalTransform = MisAlign(localTransform);
297 newDetElement->SetLocalTransformation(newLocalTransform);
299 // global transformation
300 TGeoHMatrix newGlobalTransform =
301 AliMUONGeometryBuilder::Multiply(*newModuleTransform,
303 newDetElement->SetGlobalTransformation(newGlobalTransform);
305 // add this det element to module
306 newModuleTransformer->GetDetElementStore()->Add(newDetElement->GetId(),
308 // Get delta transformation:
309 // Tdelta = Tnew * Told.inverse
310 TGeoHMatrix deltaTransform
311 = AliMUONGeometryBuilder::Multiply(
313 detElement->GetGlobalTransformation()->Inverse());
315 // Create mis alignment matrix
316 newGeometryTransformer
317 ->AddMisAlignDetElement(detElement->GetId(), deltaTransform);
320 AliInfo(Form("Added module transformer %i to the transformer", iMt));
321 newGeometryTransformer->AddModuleTransformer(newModuleTransformer);
323 return newGeometryTransformer;