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 AliMUONGeometryBuilder
19 // ----------------------------
20 // Manager class for geometry construction via geometry builders.
22 // Author: Ivana Hrivnacova, IPN Orsay
24 #include <TObjArray.h>
25 #include <TVirtualMC.h>
27 #include "AliMUONGeometryBuilder.h"
28 #include "AliMUONVGeometryBuilder.h"
29 #include "AliMUONGeometry.h"
30 #include "AliMUONGeometryTransformer.h"
31 #include "AliMUONGeometryModule.h"
32 #include "AliMUONGeometryModuleTransformer.h"
33 #include "AliMUONGeometryEnvelope.h"
34 #include "AliMUONGeometryEnvelopeStore.h"
35 #include "AliMUONGeometryDetElement.h"
36 #include "AliMUONGeometryStore.h"
37 #include "AliMUONGeometryConstituent.h"
38 #include "AliModule.h"
43 ClassImp(AliMUONGeometryBuilder)
47 //______________________________________________________________________________
48 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
51 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
53 if (m1.IsIdentity() && m2.IsIdentity()) return TGeoHMatrix();
55 if (m1.IsIdentity()) return m2;
57 if (m2.IsIdentity()) return m1;
62 //______________________________________________________________________________
63 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
67 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
69 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity())
72 if (m1.IsIdentity()) return Multiply(m2, m3);
74 if (m2.IsIdentity()) return Multiply(m1, m3);
76 if (m3.IsIdentity()) return Multiply(m1, m2);
81 //______________________________________________________________________________
82 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
87 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
89 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity() & m4.IsIdentity())
92 if (m1.IsIdentity()) return Multiply(m2, m3, m4);
94 if (m2.IsIdentity()) return Multiply(m1, m3, m4);
96 if (m3.IsIdentity()) return Multiply(m1, m2, m4);
98 if (m4.IsIdentity()) return Multiply(m1, m2, m3);
100 return m1 * m2 * m3 * m4;
103 //______________________________________________________________________________
104 AliMUONGeometryBuilder::AliMUONGeometryBuilder(AliModule* module)
108 fGlobalTransformation(),
109 fGeometryBuilders(0),
112 /// Standard constructor
114 fGeometryBuilders = new TObjArray();
115 fGeometryBuilders->SetOwner(true);
117 fGeometry = new AliMUONGeometry(true);
119 // Define the global transformation:
120 // Transformation from the old ALICE coordinate system to a new one:
122 TGeoRotation* rotGlobal
123 = new TGeoRotation("rotGlobal", 90., 180., 90., 90., 180., 0.);
124 fGlobalTransformation = TGeoCombiTrans(0., 0., 0., rotGlobal);
127 //______________________________________________________________________________
128 AliMUONGeometryBuilder::AliMUONGeometryBuilder()
132 fGlobalTransformation(),
133 fGeometryBuilders(0),
136 /// Default constructor
139 //______________________________________________________________________________
140 AliMUONGeometryBuilder::AliMUONGeometryBuilder(const AliMUONGeometryBuilder& right)
143 /// Copy constructor (not implemented)
145 AliFatal("Copy constructor not provided.");
148 //______________________________________________________________________________
149 AliMUONGeometryBuilder::~AliMUONGeometryBuilder()
153 delete fGeometryBuilders;
157 //______________________________________________________________________________
158 AliMUONGeometryBuilder&
159 AliMUONGeometryBuilder::operator=(const AliMUONGeometryBuilder& right)
161 /// Assignement operator (not implemented)
163 // check assignement to self
164 if (this == &right) return *this;
166 AliFatal("Assignement operator not provided.");
175 //______________________________________________________________________________
176 void AliMUONGeometryBuilder::PlaceVolume(const TString& name, const TString& mName,
177 Int_t copyNo, const TGeoHMatrix& matrix,
178 Int_t npar, Double_t* param, const char* only) const
180 /// Place the volume specified by name with the given transformation matrix
182 TGeoHMatrix transform(matrix);
183 // Do not apply global transformation
184 // if mother volume was already placed in
185 // the new system of coordinates (that is MUON in negative Z)
186 // (as it is applied on the mother volume)
187 if (mName == TString("DDIP"))
188 transform = fGlobalTransformation.Inverse() * transform;
190 // Decompose transformation
191 const Double_t* xyz = transform.GetTranslation();
192 const Double_t* rm = transform.GetRotationMatrix();
194 //cout << "Got translation: "
195 // << xyz[0] << " " << xyz[1] << " " << xyz[2] << endl;
197 //cout << "Got rotation: "
198 // << rm[0] << " " << rm[1] << " " << rm[2] << endl
199 // << rm[3] << " " << rm[4] << " " << rm[5] << endl
200 // << rm[6] << " " << rm[7] << " " << rm[8] << endl;
202 // Check for presence of rotation
203 // (will be nice to be available in TGeo)
204 const Double_t kTolerance = 1e-04;
205 Bool_t isRotation = true;
206 if (TMath::Abs(rm[0] - 1.) < kTolerance &&
207 TMath::Abs(rm[1] - 0.) < kTolerance &&
208 TMath::Abs(rm[2] - 0.) < kTolerance &&
209 TMath::Abs(rm[3] - 0.) < kTolerance &&
210 TMath::Abs(rm[4] - 1.) < kTolerance &&
211 TMath::Abs(rm[5] - 0.) < kTolerance &&
212 TMath::Abs(rm[6] - 0.) < kTolerance &&
213 TMath::Abs(rm[7] - 0.) < kTolerance &&
214 TMath::Abs(rm[8] - 1.) < kTolerance) isRotation = false;
219 rot.SetMatrix(const_cast<Double_t*>(transform.GetRotationMatrix()));
220 Double_t theta1, phi1, theta2, phi2, theta3, phi3;
221 rot.GetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
224 // << theta1 << " " << phi1 << " "
225 // << theta2 << " " << phi2 << " "
226 // << theta3 << " " << phi3 << endl;
228 fModule->AliMatrix(krot, theta1, phi1, theta2, phi2, theta3, phi3);
231 // Place the volume in ALIC
233 gMC->Gspos(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only);
235 gMC->Gsposp(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only,
240 //_____________________________________________________________________________
241 void AliMUONGeometryBuilder::SetAlign(AliMUONVGeometryBuilder* builder)
243 /// Set align option to all geometry modules associated with the builder
245 for (Int_t j=0; j<builder->NofGeometries(); j++) {
247 AliMUONGeometryModule* geometry = builder->Geometry(j);
249 geometry->SetAlign(fAlign);
257 //_____________________________________________________________________________
258 void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
260 /// Add the geometry builder to the list
262 fGeometryBuilders->Add(geomBuilder);
264 // Pass geometry modules created in the to the geometry parametrisation
265 for (Int_t i=0; i<geomBuilder->NofGeometries(); i++) {
266 fGeometry->AddModule(geomBuilder->Geometry(i));
269 if (geomBuilder->ApplyGlobalTransformation())
270 geomBuilder->SetReferenceFrame(fGlobalTransformation);
272 SetAlign(geomBuilder);
275 //______________________________________________________________________________
276 void AliMUONGeometryBuilder::CreateGeometry()
278 /// Construct geometry using geometry builders.
280 if (fAlign) ReadTransformations();
282 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
285 AliMUONVGeometryBuilder* builder
286 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
288 // Create geometry + envelopes
290 builder->CreateGeometry();
291 if (!fAlign) builder->SetTransformations();
293 // Place module volumes and envelopes
295 for (Int_t j=0; j<builder->NofGeometries(); j++) {
297 AliMUONGeometryModule* geometry = builder->Geometry(j);
298 const TGeoCombiTrans* kModuleTransform
299 = geometry->GetTransformer()->GetTransformation();
301 // Place the module volume
302 if ( !geometry->IsVirtual() ) {
303 PlaceVolume(geometry->GetVolume(), geometry->GetMotherVolume(),
304 1, *kModuleTransform, 0, 0, "ONLY");
307 TGeoCombiTrans appliedGlobalTransform;
308 if (builder->ApplyGlobalTransformation())
309 appliedGlobalTransform = fGlobalTransformation;
311 // Loop over envelopes
312 const TObjArray* kEnvelopes
313 = geometry->GetEnvelopeStore()->GetEnvelopes();
314 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
317 AliMUONGeometryEnvelope* env
318 = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
320 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
321 const char* only = "ONLY";
322 if (env->IsMANY()) only = "MANY";
324 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
325 // virtual envelope + nof constituents = 0
327 // empty virtual envelope has no sense
328 AliFatal("Virtual envelope must have constituents.");
332 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
333 // non virtual envelope + nof constituents > 0
335 // use VMC to place constituents
336 AliFatal("Non virtual envelope cannot have constituents.");
340 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
341 // non virtual envelope + nof constituents = 0
342 // => place envelope in ALICE by composed transformation:
343 // Tch * [Tglobal] * Tenv
345 // Compound chamber transformation with the envelope one
346 if (geometry->IsVirtual()) {
348 = Multiply( (*kModuleTransform),
349 appliedGlobalTransform,
351 PlaceVolume(env->GetName(), geometry->GetMotherVolume(),
352 env->GetCopyNo(), total, 0, 0, only);
356 = Multiply( appliedGlobalTransform,
358 PlaceVolume(env->GetName(), geometry->GetVolume(),
359 env->GetCopyNo(), total, 0, 0, only);
363 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
364 // virtual envelope + nof constituents > 0
365 // => do not place envelope and place constituents
366 // in ALICE by composed transformation:
367 // Tch * [Tglobal] * Tenv * Tconst
369 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
370 AliMUONGeometryConstituent* constituent
371 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
373 // Compound chamber transformation with the envelope one + the constituent one
374 if (geometry->IsVirtual()) {
376 = Multiply ( (*kModuleTransform),
377 appliedGlobalTransform,
379 (*constituent->GetTransformation()) );
381 PlaceVolume(constituent->GetName(), geometry->GetMotherVolume(),
382 constituent->GetCopyNo(), total,
383 constituent->GetNpar(), constituent->GetParam(), only);
387 = Multiply ( appliedGlobalTransform,
389 (*constituent->GetTransformation()) );
391 PlaceVolume(constituent->GetName(), geometry->GetVolume(),
392 constituent->GetCopyNo(), total,
393 constituent->GetNpar(), constituent->GetParam(), only);
397 } // end of loop over envelopes
398 } // end of loop over builder geometries
399 } // end of loop over builders
402 //_____________________________________________________________________________
403 void AliMUONGeometryBuilder::CreateMaterials()
405 /// Construct materials specific to modules via builders
407 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
410 AliMUONVGeometryBuilder* builder
411 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
413 // Create materials with each builder
414 if (builder) builder->CreateMaterials();
418 //______________________________________________________________________________
419 void AliMUONGeometryBuilder::InitGeometry(const TString& svmapFileName)
421 /// Initialize geometry
423 // Read alignement data if geometry is read from Root file
424 if ( gAlice->IsRootGeometry() ) {
426 ReadTransformations();
429 // Read sensitive volume map from a file
430 fGeometry->ReadSVMap(svmapFileName);
432 // Set the chamber (sensitive region) GEANT identifier
434 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
437 AliMUONVGeometryBuilder* builder
438 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
440 // Set sensitive volumes with each builder
441 builder->SetSensitiveVolumes();
444 // Fill local transformations from built geometry
445 builder->FillTransformations();
450 //______________________________________________________________________________
451 void AliMUONGeometryBuilder::ReadTransformations(const TString& fileName)
453 /// Read transformations from ASCII files
454 /// and store them in the geometry parametrisation
456 // Read transformations
458 AliMUONGeometryTransformer* geomTransformer = fGeometry->GetTransformer();
459 geomTransformer->ReadTransformations(fileName);
462 //______________________________________________________________________________
463 void AliMUONGeometryBuilder::WriteTransformations(const TString& fileName)
465 /// Write transformations into files per builder
467 AliMUONGeometryTransformer* geomTransformer = fGeometry->GetTransformer();
468 geomTransformer->WriteTransformations(fileName);
471 //______________________________________________________________________________
472 void AliMUONGeometryBuilder::WriteSVMaps(Bool_t rebuild,
473 const TString& fileName)
475 /// Write sensitive volume maps into files per builder
480 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
482 AliMUONVGeometryBuilder* builder
483 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
485 builder->RebuildSVMaps();
488 // Write maps in file
489 fGeometry->WriteSVMap(fileName);
492 //_____________________________________________________________________________
493 void AliMUONGeometryBuilder::SetAlign(Bool_t align)
495 /// Set the option for alignement
499 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
501 AliMUONVGeometryBuilder* builder
502 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);