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 // Class AliMUONGeometryMisAligner
19 // ----------------------------
20 // Class for misalignment of geometry transformations
22 // Author:Bruce Becker
24 //__________________________________________________________________
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
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
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.
49 #include "AliMUONGeometryMisAligner.h"
50 #include "AliMUONGeometryTransformer.h"
51 #include "AliMUONGeometryModuleTransformer.h"
52 #include "AliMUONGeometryDetElement.h"
53 #include "AliMUONGeometryStore.h"
54 #include "AliMUONGeometryBuilder.h"
58 #include <TGeoManager.h>
59 #include <Riostream.h>
60 #include <TObjArray.h>
67 ClassImp(AliMUONGeometryMisAligner)
68 //______________________________________________________________________________
69 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner(Double_t cartMisAlig, Double_t angMisAlig)
70 :TObject(), fDisplacementGenerator(0)
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);
79 //_____________________________________________________________________________
80 AliMUONGeometryMisAligner::AliMUONGeometryMisAligner()
81 :TObject(), fDisplacementGenerator(0)
83 /// Default constructor
86 //______________________________________________________________________________
87 AliMUONGeometryMisAligner::
88 AliMUONGeometryMisAligner(const AliMUONGeometryMisAligner & right):
91 /// Copy constructor (not implemented)
93 AliFatal("Copy constructor not provided.");
96 //______________________________________________________________________________
97 AliMUONGeometryMisAligner::~AliMUONGeometryMisAligner()
101 delete fDisplacementGenerator;
104 //______________________________________________________________________________
105 AliMUONGeometryMisAligner & AliMUONGeometryMisAligner::
106 operator=(const AliMUONGeometryMisAligner & right)
108 /// Assignement operator (not implemented)
110 // check assignement to self
114 AliFatal("Assignement operator not provided.");
120 AliMUONGeometryMisAligner::SetXYAngMisAligFactor(Double_t factor)
122 if (TMath::Abs(factor) > 1.0 && factor > 0.)
123 fXYAngMisAligFactor = factor;
125 AliError(Form("Invalid factor, %d", factor));
128 //_________________________________________________________________________
129 TGeoCombiTrans AliMUONGeometryMisAligner::MisAlign(const TGeoCombiTrans & transform) const
131 /// Misalign given transformation and return the misaligned transformation
133 Double_t cartMisAlig[3] = {0,0,0};
134 Double_t angMisAlig[3] = {0,0,0};
135 const Double_t *trans = transform.GetTranslation();
137 // check if the rotation we obtain is not NULL
138 if (transform.GetRotation())
140 rot = transform.GetRotation();
144 rot = new TGeoRotation("rot");
145 } // default constructor.
147 cartMisAlig[0] = fDisplacementGenerator->Uniform(-1. * fMaxCartMisAlig, fMaxCartMisAlig);
148 cartMisAlig[1] = fDisplacementGenerator->Uniform(-1. * fMaxCartMisAlig, fMaxCartMisAlig);
149 cartMisAlig[2] = fDisplacementGenerator->Uniform(-1. * fMaxCartMisAlig, fMaxCartMisAlig);
151 TGeoTranslation newTrans(cartMisAlig[0] + trans[0], cartMisAlig[1] + trans[1], cartMisAlig[2] + trans[2]);
154 misalign the centre of the local transformation
156 fAngMisAlig[1,2,3] = [x,y,z]
157 Assume that misalignment about the x and y axes (misalignment of z plane)
158 is much smaller, since the entire detection plane has to be moved (the
159 detection elements are on a support structure), while rotation of the x-y
163 angMisAlig[0] = fDisplacementGenerator->Uniform(fXYAngMisAligFactor * fMaxAngMisAlig, 1.0 * fMaxAngMisAlig);
164 angMisAlig[1] = fDisplacementGenerator->Uniform(fXYAngMisAligFactor * fMaxAngMisAlig, 1.0 * fMaxAngMisAlig);
165 angMisAlig[2] = fDisplacementGenerator->Uniform(-1. * fMaxAngMisAlig, fMaxAngMisAlig); // degrees
166 AliInfo(Form("Rotated by %f about Z axis.", angMisAlig[2]));
167 rot->RotateX(angMisAlig[0]);
168 rot->RotateY(angMisAlig[1]);
169 rot->RotateZ(angMisAlig[2]);
171 return TGeoCombiTrans(newTrans, *rot);
175 //______________________________________________________________________
176 AliMUONGeometryTransformer *
177 AliMUONGeometryMisAligner::MisAlign(const AliMUONGeometryTransformer *
178 transformer, Bool_t verbose)
180 /////////////////////////////////////////////////////////////////////
181 // Takes the internal geometry module transformers, copies them
182 // and gets the Detection Elements from them.
183 // Calculates misalignment parameters and applies these
184 // to the local transform of the Detection Element
185 // Obtains the global transform by multiplying the module transformer
186 // transformation with the local transformation
187 // Applies the global transform to a new detection element
188 // Adds the new detection element to a new module transformer
189 // Adds the new module transformer to a new geometry transformer
190 // Returns the new geometry transformer
193 AliMUONGeometryTransformer *newGeometryTransformer =
194 new AliMUONGeometryTransformer(kTRUE);
195 for (Int_t iMt = 0; iMt < transformer->GetNofModuleTransformers(); iMt++)
196 { // module transformers
198 const AliMUONGeometryModuleTransformer *kModuleTransformer =
199 transformer->GetModuleTransformer(iMt, true);
201 AliMUONGeometryModuleTransformer *newModuleTransformer =
202 new AliMUONGeometryModuleTransformer(iMt);
203 newGeometryTransformer->AddModuleTransformer(newModuleTransformer);
205 TGeoCombiTrans moduleTransform =
206 TGeoCombiTrans(*kModuleTransformer->GetTransformation());
207 TGeoCombiTrans *newModuleTransform = new TGeoCombiTrans(moduleTransform);
208 // same module transform as the previous one
209 // no mis align object created
210 newModuleTransformer->SetTransformation(moduleTransform);
212 AliMUONGeometryStore *detElements =
213 kModuleTransformer->GetDetElementStore();
217 ("%i DEs in old GeometryStore %i",
218 detElements->GetNofEntries(), iMt));
220 for (Int_t iDe = 0; iDe < detElements->GetNofEntries(); iDe++)
221 { // detection elements.
222 AliMUONGeometryDetElement *detElement =
223 (AliMUONGeometryDetElement *) detElements->GetEntry(iDe);
225 AliFatal("Detection element not found.");
227 /// make a new detection element
228 AliMUONGeometryDetElement *newDetElement =
229 new AliMUONGeometryDetElement(detElement->GetId(),
230 detElement->GetVolumePath());
232 // local transformation of this detection element.
233 TGeoCombiTrans localTransform
234 = TGeoCombiTrans(*detElement->GetLocalTransformation());
235 TGeoCombiTrans newLocalTransform = MisAlign(localTransform);
236 newDetElement->SetLocalTransformation(newLocalTransform);
238 // global transformation
239 TGeoHMatrix newGlobalTransform =
240 AliMUONGeometryBuilder::Multiply(*newModuleTransform,
242 newDetElement->SetGlobalTransformation(newGlobalTransform);
244 // add this det element to module
245 newModuleTransformer->GetDetElementStore()->Add(newDetElement->GetId(),
247 // Get delta transformation:
248 // Tdelta = Tnew * Told.inverse
249 TGeoHMatrix deltaTransform
250 = AliMUONGeometryBuilder::Multiply(
252 detElement->GetGlobalTransformation()->Inverse());
254 // Create mis alignment matrix
255 newGeometryTransformer
256 ->AddMisAlignDetElement(detElement->GetId(), deltaTransform);
259 AliInfo(Form("Added module transformer %i to the transformer", iMt));
260 newGeometryTransformer->AddModuleTransformer(newModuleTransformer);
262 return newGeometryTransformer;