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 AliMUONGeometryBuilder
20 // ----------------------------
21 // Manager class for geometry construction via geometry builders.
22 // Author: Ivana Hrivnacova, IPN Orsay
23 //-----------------------------------------------------------------------------
25 #include "AliMUONGeometryBuilder.h"
26 #include "AliMUONVGeometryBuilder.h"
27 #include "AliMUONGeometry.h"
28 #include "AliMUONGeometryTransformer.h"
29 #include "AliMUONGeometryModule.h"
30 #include "AliMUONGeometryModuleTransformer.h"
31 #include "AliMUONGeometryEnvelope.h"
32 #include "AliMUONGeometryEnvelopeStore.h"
33 #include "AliMUONGeometryDetElement.h"
34 #include "AliMUONGeometryConstituent.h"
36 #include "AliMpDEManager.h"
38 #include "AliModule.h"
42 #include <TObjArray.h>
43 #include <TVirtualMC.h>
44 #include <TGeoManager.h>
46 // static data members
48 const TString AliMUONGeometryBuilder::fgkDefaultVolPathsFileName = "volpath.dat";
49 const TString AliMUONGeometryBuilder::fgkDefaultTransformFileName = "transform.dat";
50 const TString AliMUONGeometryBuilder::fgkDefaultSVMapFileName = "svmap.dat";
51 const TString AliMUONGeometryBuilder::fgkOutFileNameExtension = ".out";
54 ClassImp(AliMUONGeometryBuilder)
59 //______________________________________________________________________________
60 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
63 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
65 if (m1.IsIdentity() && m2.IsIdentity()) return TGeoHMatrix();
67 if (m1.IsIdentity()) return m2;
69 if (m2.IsIdentity()) return m1;
74 //______________________________________________________________________________
75 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
79 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
81 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity())
84 if (m1.IsIdentity()) return Multiply(m2, m3);
86 if (m2.IsIdentity()) return Multiply(m1, m3);
88 if (m3.IsIdentity()) return Multiply(m1, m2);
93 //______________________________________________________________________________
94 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
99 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
101 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity() & m4.IsIdentity())
102 return TGeoHMatrix();
104 if (m1.IsIdentity()) return Multiply(m2, m3, m4);
106 if (m2.IsIdentity()) return Multiply(m1, m3, m4);
108 if (m3.IsIdentity()) return Multiply(m1, m2, m4);
110 if (m4.IsIdentity()) return Multiply(m1, m2, m3);
112 return m1 * m2 * m3 * m4;
115 //______________________________________________________________________________
116 AliMUONGeometryBuilder::AliMUONGeometryBuilder(AliModule* module)
120 fTransformFileName(fgkDefaultTransformFileName),
121 fSVMapFileName(fgkDefaultSVMapFileName),
122 fGlobalTransformation(),
123 fGeometryBuilders(0),
126 /// Standard constructor
128 fGeometryBuilders = new TObjArray();
129 fGeometryBuilders->SetOwner(true);
131 fGeometry = new AliMUONGeometry(true);
133 // Define the global transformation:
134 // Transformation from the old ALICE coordinate system to a new one:
136 TGeoRotation* rotGlobal
137 = new TGeoRotation("rotGlobal", 90., 180., 90., 90., 180., 0.);
138 fGlobalTransformation = TGeoCombiTrans(0., 0., 0., rotGlobal);
141 //______________________________________________________________________________
142 AliMUONGeometryBuilder::AliMUONGeometryBuilder()
146 fTransformFileName(),
148 fGlobalTransformation(),
149 fGeometryBuilders(0),
152 /// Default constructor
155 //______________________________________________________________________________
156 AliMUONGeometryBuilder::~AliMUONGeometryBuilder()
160 delete fGeometryBuilders;
168 //______________________________________________________________________________
169 void AliMUONGeometryBuilder::PlaceVolume(const TString& name, const TString& mName,
170 Int_t copyNo, const TGeoHMatrix& matrix,
171 Int_t npar, Double_t* param, const char* only,
172 Bool_t makeAssembly) const
174 /// Place the volume specified by name with the given transformation matrix
177 gGeoManager->MakeVolumeAssembly(name.Data());
179 TGeoHMatrix transform(matrix);
180 // Do not apply global transformation
181 // if mother volume was already placed in
182 // the new system of coordinates (that is MUON in negative Z)
183 // (as it is applied on the mother volume)
184 if (mName == TString("DDIP"))
185 transform = fGlobalTransformation.Inverse() * transform;
187 // Decompose transformation
188 const Double_t* xyz = transform.GetTranslation();
189 const Double_t* rm = transform.GetRotationMatrix();
191 //cout << "Got translation: "
192 // << xyz[0] << " " << xyz[1] << " " << xyz[2] << endl;
194 //cout << "Got rotation: "
195 // << rm[0] << " " << rm[1] << " " << rm[2] << endl
196 // << rm[3] << " " << rm[4] << " " << rm[5] << endl
197 // << rm[6] << " " << rm[7] << " " << rm[8] << endl;
199 // Check for presence of rotation
200 // (will be nice to be available in TGeo)
201 const Double_t kTolerance = 1e-04;
202 Bool_t isRotation = true;
203 if (TMath::Abs(rm[0] - 1.) < kTolerance &&
204 TMath::Abs(rm[1] - 0.) < kTolerance &&
205 TMath::Abs(rm[2] - 0.) < kTolerance &&
206 TMath::Abs(rm[3] - 0.) < kTolerance &&
207 TMath::Abs(rm[4] - 1.) < kTolerance &&
208 TMath::Abs(rm[5] - 0.) < kTolerance &&
209 TMath::Abs(rm[6] - 0.) < kTolerance &&
210 TMath::Abs(rm[7] - 0.) < kTolerance &&
211 TMath::Abs(rm[8] - 1.) < kTolerance) isRotation = false;
216 rot.SetMatrix(const_cast<Double_t*>(transform.GetRotationMatrix()));
217 Double_t theta1, phi1, theta2, phi2, theta3, phi3;
218 rot.GetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
221 // << theta1 << " " << phi1 << " "
222 // << theta2 << " " << phi2 << " "
223 // << theta3 << " " << phi3 << endl;
225 fModule->AliMatrix(krot, theta1, phi1, theta2, phi2, theta3, phi3);
230 gMC->Gspos(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only);
232 gMC->Gsposp(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only,
236 //______________________________________________________________________________
237 void AliMUONGeometryBuilder::CreateGeometryWithTGeo()
239 /// Construct geometry using geometry builders.
240 /// Virtual modules/envelopes are placed as TGeoVolume assembly
243 // Read transformations from ASCII data file
244 fGeometry->GetTransformer()
245 ->LoadGeometryData(fTransformFileName);
248 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
251 AliMUONVGeometryBuilder* builder
252 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
254 // Create geometry + envelopes
256 builder->CreateGeometry();
257 if (!fAlign) builder->SetTransformations();
259 // Place module volumes and envelopes
261 for (Int_t j=0; j<builder->NofGeometries(); j++) {
263 AliMUONGeometryModule* geometry = builder->Geometry(j);
264 AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
265 const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
266 TString volName = transformer->GetVolumeName();
267 TString motherVolName = transformer->GetMotherVolumeName();
269 // Place the module volume
270 PlaceVolume(volName, motherVolName,
271 1, *kModuleTransform, 0, 0, "ONLY", geometry->IsVirtual());
273 TGeoCombiTrans appliedGlobalTransform;
274 if (builder->ApplyGlobalTransformation())
275 appliedGlobalTransform = fGlobalTransformation;
277 // Loop over envelopes
278 const TObjArray* kEnvelopes
279 = geometry->GetEnvelopeStore()->GetEnvelopes();
280 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
283 AliMUONGeometryEnvelope* env
284 = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
286 // Check consistency of detElemId and module Id
287 if ( env->GetUniqueID() > 0 &&
288 AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
289 != geometry->GetModuleId() ) {
292 << "Detection element " << env->GetUniqueID()
293 << " is being placed in geometry module " << geometry->GetModuleId()
294 << " but should go in "
295 << AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
297 AliFatal("Inconsistent IDs");
300 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
301 const char* only = "ONLY";
302 if (env->IsMANY()) only = "MANY";
304 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
305 // virtual envelope + nof constituents = 0
307 // empty virtual envelope has no sense
308 AliFatal("Virtual envelope must have constituents.");
312 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
313 // non virtual envelope + nof constituents > 0
315 // use VMC to place constituents
316 AliFatal("Non virtual envelope cannot have constituents.");
320 // Place envelope in geometry module by composed transformation:
323 = Multiply( appliedGlobalTransform,
325 PlaceVolume(env->GetName(), volName,
326 env->GetCopyNo(), total, 0, 0, only, env->IsVirtual());
328 if ( env->IsVirtual() ) {
329 // Place constituents in the envelope
330 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
331 AliMUONGeometryConstituent* constituent
332 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
334 PlaceVolume(constituent->GetName(), env->GetName(),
335 constituent->GetCopyNo(),
336 *constituent->GetTransformation() ,
337 constituent->GetNpar(), constituent->GetParam(), only);
340 } // end of loop over envelopes
341 } // end of loop over builder geometries
342 } // end of loop over builders
345 //______________________________________________________________________________
346 void AliMUONGeometryBuilder::CreateGeometryWithoutTGeo()
348 /// Construct geometry using geometry builders.
349 /// Virtual modules/envelopes are not placed
352 // Read transformations from ASCII data file
353 fGeometry->GetTransformer()->LoadGeometryData(fTransformFileName);
356 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
359 AliMUONVGeometryBuilder* builder
360 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
362 // Create geometry + envelopes
364 builder->CreateGeometry();
365 if (!fAlign) builder->SetTransformations();
367 // Place module volumes and envelopes
369 for (Int_t j=0; j<builder->NofGeometries(); j++) {
371 AliMUONGeometryModule* geometry = builder->Geometry(j);
372 AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
373 const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
374 TString volName = transformer->GetVolumeName();
375 TString motherVolName = transformer->GetMotherVolumeName();
377 // Place the module volume
378 if ( !geometry->IsVirtual() ) {
379 PlaceVolume(volName, motherVolName,
380 1, *kModuleTransform, 0, 0, "ONLY");
383 TGeoCombiTrans appliedGlobalTransform;
384 if (builder->ApplyGlobalTransformation())
385 appliedGlobalTransform = fGlobalTransformation;
387 // Loop over envelopes
388 const TObjArray* kEnvelopes
389 = geometry->GetEnvelopeStore()->GetEnvelopes();
390 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
393 AliMUONGeometryEnvelope* env
394 = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
396 // Check consistency of detElemId and module Id
397 if ( env->GetUniqueID() > 0 &&
398 AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
399 != geometry->GetModuleId() ) {
402 << "Detection element " << env->GetUniqueID()
403 << " is being placed in geometry module " << geometry->GetModuleId()
404 << " but should go in "
405 << AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
407 AliFatal("Inconsistent IDs");
410 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
411 const char* only = "ONLY";
412 if (env->IsMANY()) only = "MANY";
414 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
415 // virtual envelope + nof constituents = 0
417 // empty virtual envelope has no sense
418 AliFatal("Virtual envelope must have constituents.");
422 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
423 // non virtual envelope + nof constituents > 0
425 // use VMC to place constituents
426 AliFatal("Non virtual envelope cannot have constituents.");
430 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
431 // non virtual envelope + nof constituents = 0
432 // => place envelope by composed transformation:
433 // Tch * [Tglobal] * Tenv
435 // Compound chamber transformation with the envelope one
436 if (geometry->IsVirtual()) {
438 = Multiply( (*kModuleTransform),
439 appliedGlobalTransform,
441 PlaceVolume(env->GetName(), motherVolName,
442 env->GetCopyNo(), total, 0, 0, only);
446 = Multiply( appliedGlobalTransform,
448 PlaceVolume(env->GetName(), volName,
449 env->GetCopyNo(), total, 0, 0, only);
453 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
454 // virtual envelope + nof constituents > 0
455 // => do not place envelope and place constituents
456 // by composed transformation:
457 // Tch * [Tglobal] * Tenv * Tconst
459 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
460 AliMUONGeometryConstituent* constituent
461 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
463 // Compound chamber transformation with the envelope one + the constituent one
464 if (geometry->IsVirtual()) {
466 = Multiply ( (*kModuleTransform),
467 appliedGlobalTransform,
469 (*constituent->GetTransformation()) );
471 PlaceVolume(constituent->GetName(), motherVolName,
472 constituent->GetCopyNo(), total,
473 constituent->GetNpar(), constituent->GetParam(), only);
477 = Multiply ( appliedGlobalTransform,
479 (*constituent->GetTransformation()) );
481 PlaceVolume(constituent->GetName(), volName,
482 constituent->GetCopyNo(), total,
483 constituent->GetNpar(), constituent->GetParam(), only);
487 } // end of loop over envelopes
488 } // end of loop over builder geometries
489 } // end of loop over builders
492 //_____________________________________________________________________________
493 void AliMUONGeometryBuilder::SetAlign(AliMUONVGeometryBuilder* builder)
495 /// Set align option to all geometry modules associated with the builder
497 for (Int_t j=0; j<builder->NofGeometries(); j++) {
499 AliMUONGeometryModule* geometry = builder->Geometry(j);
501 geometry->SetAlign(fAlign);
509 //_____________________________________________________________________________
510 void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
512 /// Add the geometry builder to the list
514 fGeometryBuilders->Add(geomBuilder);
516 // Pass geometry modules created in the to the geometry parametrisation
517 for (Int_t i=0; i<geomBuilder->NofGeometries(); i++) {
518 fGeometry->AddModule(geomBuilder->Geometry(i));
521 if (geomBuilder->ApplyGlobalTransformation())
522 geomBuilder->SetReferenceFrame(fGlobalTransformation);
524 SetAlign(geomBuilder);
527 //______________________________________________________________________________
528 void AliMUONGeometryBuilder::CreateGeometry()
530 /// Construct geometry using geometry builders.
532 if ( gMC->IsRootGeometrySupported() ) {
534 CreateGeometryWithTGeo();
537 CreateGeometryWithoutTGeo();
539 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
542 AliMUONVGeometryBuilder* builder
543 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
545 // Create detection elements from built geometry
546 builder->CreateDetElements();
550 //_____________________________________________________________________________
551 void AliMUONGeometryBuilder::CreateMaterials()
553 /// Construct materials specific to modules via builders
555 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
558 AliMUONVGeometryBuilder* builder
559 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
561 // Create materials with each builder
562 if (builder) builder->CreateMaterials();
566 //______________________________________________________________________________
567 void AliMUONGeometryBuilder::InitGeometry(const TString& svmapFileName)
569 /// Initialize geometry
571 // Load alignement data from geometry if geometry is read from Root file
572 if ( gAlice->IsRootGeometry() ) {
574 fGeometry->GetTransformer()->LoadGeometryData();
577 // Read sensitive volume map from a file
578 fGeometry->ReadSVMap(svmapFileName);
580 // Set the chamber (sensitive region) GEANT identifier
582 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
585 AliMUONVGeometryBuilder* builder
586 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
588 // Set sensitive volumes with each builder
589 builder->SetSensitiveVolumes();
593 //______________________________________________________________________________
594 void AliMUONGeometryBuilder::WriteSVMaps(const TString& fileName,
595 Bool_t rebuild, Bool_t writeEnvelopes)
597 /// Write sensitive volume maps into files per builder
602 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
604 AliMUONVGeometryBuilder* builder
605 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
607 builder->RebuildSVMaps(writeEnvelopes);
610 // Write maps in file
611 fGeometry->WriteSVMap(fileName);
614 //_____________________________________________________________________________
615 void AliMUONGeometryBuilder::SetAlign(Bool_t align)
617 /// Set the option for alignement
621 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
623 AliMUONVGeometryBuilder* builder
624 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
630 //_____________________________________________________________________________
631 void AliMUONGeometryBuilder::SetAlign(const TString& fileName, Bool_t align)
633 /// Set the option for alignement and the transformations file name
635 fTransformFileName = fileName;
638 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
640 AliMUONVGeometryBuilder* builder
641 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);