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"
39 #include "AliSimulation.h"
43 #include <TObjArray.h>
44 #include <TVirtualMC.h>
45 #include <TGeoManager.h>
48 ClassImp(AliMUONGeometryBuilder)
55 //______________________________________________________________________________
56 const TString& AliMUONGeometryBuilder::GetDefaultTransformFileName()
58 ///< default transformations file name
59 static const TString kDefaultTransformFileName = "transform.dat";
60 return kDefaultTransformFileName;
63 //______________________________________________________________________________
64 const TString& AliMUONGeometryBuilder::GetDefaultSVMapFileName()
66 ///< default svmaps file name
67 static const TString kDefaultSVMapFileName = "svmap.dat";
68 return kDefaultSVMapFileName;
71 //______________________________________________________________________________
72 const TString& AliMUONGeometryBuilder::GetOutFileNameExtension()
74 ///< default output file name extension
75 static const TString kOutFileNameExtension = ".out";
76 return kOutFileNameExtension;
80 //______________________________________________________________________________
81 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
84 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
86 if (m1.IsIdentity() && m2.IsIdentity()) return TGeoHMatrix();
88 if (m1.IsIdentity()) return m2;
90 if (m2.IsIdentity()) return m1;
95 //______________________________________________________________________________
96 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
100 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
102 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity())
103 return TGeoHMatrix();
105 if (m1.IsIdentity()) return Multiply(m2, m3);
107 if (m2.IsIdentity()) return Multiply(m1, m3);
109 if (m3.IsIdentity()) return Multiply(m1, m2);
114 //______________________________________________________________________________
115 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
116 const TGeoMatrix& m2,
117 const TGeoMatrix& m3,
118 const TGeoMatrix& m4)
120 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
122 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity() & m4.IsIdentity())
123 return TGeoHMatrix();
125 if (m1.IsIdentity()) return Multiply(m2, m3, m4);
127 if (m2.IsIdentity()) return Multiply(m1, m3, m4);
129 if (m3.IsIdentity()) return Multiply(m1, m2, m4);
131 if (m4.IsIdentity()) return Multiply(m1, m2, m3);
133 return m1 * m2 * m3 * m4;
140 //______________________________________________________________________________
141 AliMUONGeometryBuilder::AliMUONGeometryBuilder(AliModule* module)
145 fTransformFileName(GetDefaultTransformFileName()),
146 fSVMapFileName(GetDefaultSVMapFileName()),
147 fGlobalTransformation(),
148 fGeometryBuilders(0),
151 /// Standard constructor
153 fGeometryBuilders = new TObjArray();
154 fGeometryBuilders->SetOwner(true);
156 fGeometry = new AliMUONGeometry(true);
158 // Define the global transformation:
159 // Transformation from the old ALICE coordinate system to a new one:
161 TGeoRotation* rotGlobal
162 = new TGeoRotation("rotGlobal", 90., 180., 90., 90., 180., 0.);
163 fGlobalTransformation = TGeoCombiTrans(0., 0., 0., rotGlobal);
166 //______________________________________________________________________________
167 AliMUONGeometryBuilder::AliMUONGeometryBuilder()
171 fTransformFileName(),
173 fGlobalTransformation(),
174 fGeometryBuilders(0),
177 /// Default constructor
180 //______________________________________________________________________________
181 AliMUONGeometryBuilder::~AliMUONGeometryBuilder()
185 delete fGeometryBuilders;
193 //______________________________________________________________________________
194 void AliMUONGeometryBuilder::PlaceVolume(const TString& name, const TString& mName,
195 Int_t copyNo, const TGeoHMatrix& matrix,
196 Int_t npar, Double_t* param, const char* only,
197 Bool_t makeAssembly) const
199 /// Place the volume specified by name with the given transformation matrix
202 gGeoManager->MakeVolumeAssembly(name.Data());
204 TGeoHMatrix transform(matrix);
205 // Do not apply global transformation
206 // if mother volume was already placed in
207 // the new system of coordinates (that is MUON in negative Z)
208 // (as it is applied on the mother volume)
209 if (mName == TString("DDIP"))
210 transform = fGlobalTransformation.Inverse() * transform;
212 // Decompose transformation
213 const Double_t* xyz = transform.GetTranslation();
214 const Double_t* rm = transform.GetRotationMatrix();
216 //cout << "Got translation: "
217 // << xyz[0] << " " << xyz[1] << " " << xyz[2] << endl;
219 //cout << "Got rotation: "
220 // << rm[0] << " " << rm[1] << " " << rm[2] << endl
221 // << rm[3] << " " << rm[4] << " " << rm[5] << endl
222 // << rm[6] << " " << rm[7] << " " << rm[8] << endl;
224 // Check for presence of rotation
225 // (will be nice to be available in TGeo)
226 const Double_t kTolerance = 1e-04;
227 Bool_t isRotation = true;
228 if (TMath::Abs(rm[0] - 1.) < kTolerance &&
229 TMath::Abs(rm[1] - 0.) < kTolerance &&
230 TMath::Abs(rm[2] - 0.) < kTolerance &&
231 TMath::Abs(rm[3] - 0.) < kTolerance &&
232 TMath::Abs(rm[4] - 1.) < kTolerance &&
233 TMath::Abs(rm[5] - 0.) < kTolerance &&
234 TMath::Abs(rm[6] - 0.) < kTolerance &&
235 TMath::Abs(rm[7] - 0.) < kTolerance &&
236 TMath::Abs(rm[8] - 1.) < kTolerance) isRotation = false;
241 rot.SetMatrix(const_cast<Double_t*>(transform.GetRotationMatrix()));
242 Double_t theta1, phi1, theta2, phi2, theta3, phi3;
243 rot.GetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
246 // << theta1 << " " << phi1 << " "
247 // << theta2 << " " << phi2 << " "
248 // << theta3 << " " << phi3 << endl;
250 fModule->AliMatrix(krot, theta1, phi1, theta2, phi2, theta3, phi3);
255 gMC->Gspos(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only);
257 gMC->Gsposp(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only,
261 //______________________________________________________________________________
262 void AliMUONGeometryBuilder::CreateGeometryWithTGeo()
264 /// Construct geometry using geometry builders.
265 /// Virtual modules/envelopes are placed as TGeoVolume assembly
268 // Read transformations from ASCII data file
269 fGeometry->GetTransformer()
270 ->LoadGeometryData(fTransformFileName);
273 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
276 AliMUONVGeometryBuilder* builder
277 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
279 // Create geometry + envelopes
281 builder->CreateGeometry();
282 builder->SetVolumes();
283 if (!fAlign) builder->SetTransformations();
285 // Place module volumes and envelopes
287 for (Int_t j=0; j<builder->NofGeometries(); j++) {
289 AliMUONGeometryModule* geometry = builder->Geometry(j);
290 AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
291 const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
292 TString volName = transformer->GetVolumeName();
293 TString motherVolName = transformer->GetMotherVolumeName();
295 // Place the module volume
296 PlaceVolume(volName, motherVolName,
297 1, *kModuleTransform, 0, 0, "ONLY", geometry->IsVirtual());
299 TGeoCombiTrans appliedGlobalTransform;
300 if (builder->ApplyGlobalTransformation())
301 appliedGlobalTransform = fGlobalTransformation;
303 // Loop over envelopes
304 const TObjArray* kEnvelopes
305 = geometry->GetEnvelopeStore()->GetEnvelopes();
306 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
309 AliMUONGeometryEnvelope* env
310 = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
312 // Check consistency of detElemId and module Id
313 if ( env->GetUniqueID() > 0 &&
314 AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
315 != geometry->GetModuleId() ) {
318 << "Detection element " << env->GetUniqueID()
319 << " is being placed in geometry module " << geometry->GetModuleId()
320 << " but should go in "
321 << AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
323 AliFatal("Inconsistent IDs");
326 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
327 const char* only = "ONLY";
328 if (env->IsMANY()) only = "MANY";
330 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
331 // virtual envelope + nof constituents = 0
333 // empty virtual envelope has no sense
334 AliFatal("Virtual envelope must have constituents.");
338 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
339 // non virtual envelope + nof constituents > 0
341 // use VMC to place constituents
342 AliFatal("Non virtual envelope cannot have constituents.");
346 // Place envelope in geometry module by composed transformation:
349 = Multiply( appliedGlobalTransform,
351 PlaceVolume(env->GetName(), volName,
352 env->GetCopyNo(), total, 0, 0, only, env->IsVirtual());
354 if ( env->IsVirtual() ) {
355 // Place constituents in the envelope
356 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
357 AliMUONGeometryConstituent* constituent
358 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
360 PlaceVolume(constituent->GetName(), env->GetName(),
361 constituent->GetCopyNo(),
362 *constituent->GetTransformation() ,
363 constituent->GetNpar(), constituent->GetParam(), only);
366 } // end of loop over envelopes
367 } // end of loop over builder geometries
368 } // end of loop over builders
371 //______________________________________________________________________________
372 void AliMUONGeometryBuilder::CreateGeometryWithoutTGeo()
374 /// Construct geometry using geometry builders.
375 /// Virtual modules/envelopes are not placed
378 // Read transformations from ASCII data file
379 fGeometry->GetTransformer()->LoadGeometryData(fTransformFileName);
382 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
385 AliMUONVGeometryBuilder* builder
386 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
388 // Create geometry + envelopes
390 builder->CreateGeometry();
391 if (!fAlign) builder->SetTransformations();
393 // Place module volumes and envelopes
395 for (Int_t j=0; j<builder->NofGeometries(); j++) {
397 AliMUONGeometryModule* geometry = builder->Geometry(j);
398 AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
399 const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
400 TString volName = transformer->GetVolumeName();
401 TString motherVolName = transformer->GetMotherVolumeName();
403 // Place the module volume
404 if ( !geometry->IsVirtual() ) {
405 PlaceVolume(volName, motherVolName,
406 1, *kModuleTransform, 0, 0, "ONLY");
409 TGeoCombiTrans appliedGlobalTransform;
410 if (builder->ApplyGlobalTransformation())
411 appliedGlobalTransform = fGlobalTransformation;
413 // Loop over envelopes
414 const TObjArray* kEnvelopes
415 = geometry->GetEnvelopeStore()->GetEnvelopes();
416 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
419 AliMUONGeometryEnvelope* env
420 = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
422 // Check consistency of detElemId and module Id
423 if ( env->GetUniqueID() > 0 &&
424 AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
425 != geometry->GetModuleId() ) {
428 << "Detection element " << env->GetUniqueID()
429 << " is being placed in geometry module " << geometry->GetModuleId()
430 << " but should go in "
431 << AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
433 AliFatal("Inconsistent IDs");
436 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
437 const char* only = "ONLY";
438 if (env->IsMANY()) only = "MANY";
440 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
441 // virtual envelope + nof constituents = 0
443 // empty virtual envelope has no sense
444 AliFatal("Virtual envelope must have constituents.");
448 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
449 // non virtual envelope + nof constituents > 0
451 // use VMC to place constituents
452 AliFatal("Non virtual envelope cannot have constituents.");
456 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
457 // non virtual envelope + nof constituents = 0
458 // => place envelope by composed transformation:
459 // Tch * [Tglobal] * Tenv
461 // Compound chamber transformation with the envelope one
462 if (geometry->IsVirtual()) {
464 = Multiply( (*kModuleTransform),
465 appliedGlobalTransform,
467 PlaceVolume(env->GetName(), motherVolName,
468 env->GetCopyNo(), total, 0, 0, only);
472 = Multiply( appliedGlobalTransform,
474 PlaceVolume(env->GetName(), volName,
475 env->GetCopyNo(), total, 0, 0, only);
479 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
480 // virtual envelope + nof constituents > 0
481 // => do not place envelope and place constituents
482 // by composed transformation:
483 // Tch * [Tglobal] * Tenv * Tconst
485 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
486 AliMUONGeometryConstituent* constituent
487 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
489 // Compound chamber transformation with the envelope one + the constituent one
490 if (geometry->IsVirtual()) {
492 = Multiply ( (*kModuleTransform),
493 appliedGlobalTransform,
495 (*constituent->GetTransformation()) );
497 PlaceVolume(constituent->GetName(), motherVolName,
498 constituent->GetCopyNo(), total,
499 constituent->GetNpar(), constituent->GetParam(), only);
503 = Multiply ( appliedGlobalTransform,
505 (*constituent->GetTransformation()) );
507 PlaceVolume(constituent->GetName(), volName,
508 constituent->GetCopyNo(), total,
509 constituent->GetNpar(), constituent->GetParam(), only);
513 } // end of loop over envelopes
514 } // end of loop over builder geometries
515 } // end of loop over builders
518 //_____________________________________________________________________________
519 void AliMUONGeometryBuilder::SetAlignToBuilder(AliMUONVGeometryBuilder* builder) const
521 /// Set align option to all geometry modules associated with the builder
523 for (Int_t j=0; j<builder->NofGeometries(); j++) {
525 AliMUONGeometryModule* geometry = builder->Geometry(j);
527 geometry->SetAlign(fAlign);
535 //_____________________________________________________________________________
536 void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
538 /// Add the geometry builder to the list
540 fGeometryBuilders->Add(geomBuilder);
542 // Pass geometry modules created in the to the geometry parametrisation
543 for (Int_t i=0; i<geomBuilder->NofGeometries(); i++) {
544 fGeometry->AddModule(geomBuilder->Geometry(i));
547 if (geomBuilder->ApplyGlobalTransformation())
548 geomBuilder->SetReferenceFrame(fGlobalTransformation);
550 SetAlignToBuilder(geomBuilder);
553 //______________________________________________________________________________
554 void AliMUONGeometryBuilder::CreateGeometry()
556 /// Construct geometry using geometry builders.
558 if ( gMC->IsRootGeometrySupported() ) {
560 CreateGeometryWithTGeo();
563 CreateGeometryWithoutTGeo();
565 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
568 AliMUONVGeometryBuilder* builder
569 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
571 // Update detection elements from built geometry
572 Bool_t create = ! fAlign;
573 builder->UpdateDetElements(create);
577 //_____________________________________________________________________________
578 void AliMUONGeometryBuilder::CreateMaterials()
580 /// Construct materials specific to modules via builders
582 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
585 AliMUONVGeometryBuilder* builder
586 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
588 // Create materials with each builder
589 if (builder) builder->CreateMaterials();
593 //______________________________________________________________________________
594 void AliMUONGeometryBuilder::InitGeometry(const TString& svmapFileName)
596 /// Initialize geometry
598 // Load alignement data from geometry if geometry is read from Root file
599 if ( AliSimulation::Instance()->IsGeometryFromFile() ) {
601 fGeometry->GetTransformer()->LoadGeometryData();
604 // Read sensitive volume map from a file
605 fGeometry->ReadSVMap(svmapFileName);
607 // Set the chamber (sensitive region) GEANT identifier
609 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
612 AliMUONVGeometryBuilder* builder
613 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
615 // Set sensitive volumes with each builder
616 builder->SetSensitiveVolumes();
620 //________________________________________________________________
621 void AliMUONGeometryBuilder::UpdateInternalGeometry()
623 /// Update geometry after applying mis-alignment:
624 /// reload transformations in geometry builder.
626 fGeometry->GetTransformer()->LoadTransformations();
629 //______________________________________________________________________________
630 void AliMUONGeometryBuilder::WriteSVMaps(const TString& fileName,
631 Bool_t rebuild, Bool_t writeEnvelopes)
633 /// Write sensitive volume maps into files per builder
638 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
640 AliMUONVGeometryBuilder* builder
641 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
643 builder->RebuildSVMaps(writeEnvelopes);
646 // Write maps in file
647 fGeometry->WriteSVMap(fileName);
650 //_____________________________________________________________________________
651 void AliMUONGeometryBuilder::SetAlign(Bool_t align)
653 /// Set the option for alignement
657 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
659 AliMUONVGeometryBuilder* builder
660 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
662 SetAlignToBuilder(builder);
666 //_____________________________________________________________________________
667 void AliMUONGeometryBuilder::SetAlign(const TString& fileName, Bool_t align)
669 /// Set the option for alignement and the transformations file name
671 fTransformFileName = fileName;
674 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
676 AliMUONVGeometryBuilder* builder
677 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
679 SetAlignToBuilder(builder);