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>
49 ClassImp(AliMUONGeometryBuilder)
56 //______________________________________________________________________________
57 const TString& AliMUONGeometryBuilder::GetDefaultTransformFileName()
59 ///< default transformations file name
60 static const TString kDefaultTransformFileName = "transform.dat";
61 return kDefaultTransformFileName;
64 //______________________________________________________________________________
65 const TString& AliMUONGeometryBuilder::GetDefaultSVMapFileName()
67 ///< default svmaps file name
68 static const TString kDefaultSVMapFileName = "svmap.dat";
69 return kDefaultSVMapFileName;
72 //______________________________________________________________________________
73 const TString& AliMUONGeometryBuilder::GetOutFileNameExtension()
75 ///< default output file name extension
76 static const TString kOutFileNameExtension = ".out";
77 return kOutFileNameExtension;
81 //______________________________________________________________________________
82 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
85 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
87 if (m1.IsIdentity() && m2.IsIdentity()) return TGeoHMatrix();
89 if (m1.IsIdentity()) return m2;
91 if (m2.IsIdentity()) return m1;
96 //______________________________________________________________________________
97 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
101 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
103 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity())
104 return TGeoHMatrix();
106 if (m1.IsIdentity()) return Multiply(m2, m3);
108 if (m2.IsIdentity()) return Multiply(m1, m3);
110 if (m3.IsIdentity()) return Multiply(m1, m2);
115 //______________________________________________________________________________
116 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
117 const TGeoMatrix& m2,
118 const TGeoMatrix& m3,
119 const TGeoMatrix& m4)
121 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
123 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity() & m4.IsIdentity())
124 return TGeoHMatrix();
126 if (m1.IsIdentity()) return Multiply(m2, m3, m4);
128 if (m2.IsIdentity()) return Multiply(m1, m3, m4);
130 if (m3.IsIdentity()) return Multiply(m1, m2, m4);
132 if (m4.IsIdentity()) return Multiply(m1, m2, m3);
134 return m1 * m2 * m3 * m4;
141 //______________________________________________________________________________
142 AliMUONGeometryBuilder::AliMUONGeometryBuilder(AliModule* module)
146 fTransformFileName(GetDefaultTransformFileName()),
147 fSVMapFileName(GetDefaultSVMapFileName()),
148 fGlobalTransformation(),
149 fGeometryBuilders(0),
152 /// Standard constructor
154 fGeometryBuilders = new TObjArray();
155 fGeometryBuilders->SetOwner(true);
157 fGeometry = new AliMUONGeometry(true);
159 // Define the global transformation:
160 // Transformation from the old ALICE coordinate system to a new one:
162 TGeoRotation* rotGlobal
163 = new TGeoRotation("rotGlobal", 90., 180., 90., 90., 180., 0.);
164 fGlobalTransformation = TGeoCombiTrans(0., 0., 0., rotGlobal);
167 //______________________________________________________________________________
168 AliMUONGeometryBuilder::AliMUONGeometryBuilder()
172 fTransformFileName(),
174 fGlobalTransformation(),
175 fGeometryBuilders(0),
178 /// Default constructor
181 //______________________________________________________________________________
182 AliMUONGeometryBuilder::~AliMUONGeometryBuilder()
186 delete fGeometryBuilders;
194 //______________________________________________________________________________
195 void AliMUONGeometryBuilder::PlaceVolume(const TString& name, const TString& mName,
196 Int_t copyNo, const TGeoHMatrix& matrix,
197 Int_t npar, Double_t* param, const char* only,
198 Bool_t makeAssembly) const
200 /// Place the volume specified by name with the given transformation matrix
203 gGeoManager->MakeVolumeAssembly(name.Data());
205 TGeoHMatrix transform(matrix);
206 // Do not apply global transformation
207 // if mother volume was already placed in
208 // the new system of coordinates (that is MUON in negative Z)
209 // (as it is applied on the mother volume)
210 if (mName == TString("DDIP"))
211 transform = fGlobalTransformation.Inverse() * transform;
213 // Decompose transformation
214 const Double_t* xyz = transform.GetTranslation();
215 const Double_t* rm = transform.GetRotationMatrix();
217 //cout << "Got translation: "
218 // << xyz[0] << " " << xyz[1] << " " << xyz[2] << endl;
220 //cout << "Got rotation: "
221 // << rm[0] << " " << rm[1] << " " << rm[2] << endl
222 // << rm[3] << " " << rm[4] << " " << rm[5] << endl
223 // << rm[6] << " " << rm[7] << " " << rm[8] << endl;
225 // Check for presence of rotation
226 // (will be nice to be available in TGeo)
227 const Double_t kTolerance = 1e-04;
228 Bool_t isRotation = true;
229 if (TMath::Abs(rm[0] - 1.) < kTolerance &&
230 TMath::Abs(rm[1] - 0.) < kTolerance &&
231 TMath::Abs(rm[2] - 0.) < kTolerance &&
232 TMath::Abs(rm[3] - 0.) < kTolerance &&
233 TMath::Abs(rm[4] - 1.) < kTolerance &&
234 TMath::Abs(rm[5] - 0.) < kTolerance &&
235 TMath::Abs(rm[6] - 0.) < kTolerance &&
236 TMath::Abs(rm[7] - 0.) < kTolerance &&
237 TMath::Abs(rm[8] - 1.) < kTolerance) isRotation = false;
242 rot.SetMatrix(const_cast<Double_t*>(transform.GetRotationMatrix()));
243 Double_t theta1, phi1, theta2, phi2, theta3, phi3;
244 rot.GetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
247 // << theta1 << " " << phi1 << " "
248 // << theta2 << " " << phi2 << " "
249 // << theta3 << " " << phi3 << endl;
251 fModule->AliMatrix(krot, theta1, phi1, theta2, phi2, theta3, phi3);
256 gMC->Gspos(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only);
258 gMC->Gsposp(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only,
262 //______________________________________________________________________________
263 void AliMUONGeometryBuilder::CreateGeometryWithTGeo()
265 /// Construct geometry using geometry builders.
266 /// Virtual modules/envelopes are placed as TGeoVolume assembly
269 // Read transformations from ASCII data file
270 fGeometry->GetTransformer()
271 ->LoadGeometryData(fTransformFileName);
274 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
277 AliMUONVGeometryBuilder* builder
278 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
280 // Create geometry + envelopes
282 builder->CreateGeometry();
283 builder->SetVolumes();
284 if (!fAlign) builder->SetTransformations();
286 // Place module volumes and envelopes
288 for (Int_t j=0; j<builder->NofGeometries(); j++) {
290 AliMUONGeometryModule* geometry = builder->Geometry(j);
291 AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
292 const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
293 TString volName = transformer->GetVolumeName();
294 TString motherVolName = transformer->GetMotherVolumeName();
296 // Place the module volume
297 PlaceVolume(volName, motherVolName,
298 1, *kModuleTransform, 0, 0, "ONLY", geometry->IsVirtual());
300 TGeoCombiTrans appliedGlobalTransform;
301 if (builder->ApplyGlobalTransformation())
302 appliedGlobalTransform = fGlobalTransformation;
304 // Loop over envelopes
305 const TObjArray* kEnvelopes
306 = geometry->GetEnvelopeStore()->GetEnvelopes();
307 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
310 AliMUONGeometryEnvelope* env
311 = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
313 // Check consistency of detElemId and module Id
314 if ( env->GetUniqueID() > 0 &&
315 AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
316 != geometry->GetModuleId() ) {
319 << "Detection element " << env->GetUniqueID()
320 << " is being placed in geometry module " << geometry->GetModuleId()
321 << " but should go in "
322 << AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
324 AliFatal("Inconsistent IDs");
327 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
328 const char* only = "ONLY";
329 if (env->IsMANY()) only = "MANY";
331 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
332 // virtual envelope + nof constituents = 0
334 // empty virtual envelope has no sense
335 AliFatal("Virtual envelope must have constituents.");
339 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
340 // non virtual envelope + nof constituents > 0
342 // use VMC to place constituents
343 AliFatal("Non virtual envelope cannot have constituents.");
347 // Place envelope in geometry module by composed transformation:
350 = Multiply( appliedGlobalTransform,
352 PlaceVolume(env->GetName(), volName,
353 env->GetCopyNo(), total, 0, 0, only, env->IsVirtual());
355 if ( env->IsVirtual() ) {
356 // Place constituents in the envelope
357 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
358 AliMUONGeometryConstituent* constituent
359 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
361 PlaceVolume(constituent->GetName(), env->GetName(),
362 constituent->GetCopyNo(),
363 *constituent->GetTransformation() ,
364 constituent->GetNpar(), constituent->GetParam(), only);
367 } // end of loop over envelopes
368 } // end of loop over builder geometries
369 } // end of loop over builders
372 //______________________________________________________________________________
373 void AliMUONGeometryBuilder::CreateGeometryWithoutTGeo()
375 /// Construct geometry using geometry builders.
376 /// Virtual modules/envelopes are not placed
379 // Read transformations from ASCII data file
380 fGeometry->GetTransformer()->LoadGeometryData(fTransformFileName);
383 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
386 AliMUONVGeometryBuilder* builder
387 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
389 // Create geometry + envelopes
391 builder->CreateGeometry();
392 if (!fAlign) builder->SetTransformations();
394 // Place module volumes and envelopes
396 for (Int_t j=0; j<builder->NofGeometries(); j++) {
398 AliMUONGeometryModule* geometry = builder->Geometry(j);
399 AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
400 const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
401 TString volName = transformer->GetVolumeName();
402 TString motherVolName = transformer->GetMotherVolumeName();
404 // Place the module volume
405 if ( !geometry->IsVirtual() ) {
406 PlaceVolume(volName, motherVolName,
407 1, *kModuleTransform, 0, 0, "ONLY");
410 TGeoCombiTrans appliedGlobalTransform;
411 if (builder->ApplyGlobalTransformation())
412 appliedGlobalTransform = fGlobalTransformation;
414 // Loop over envelopes
415 const TObjArray* kEnvelopes
416 = geometry->GetEnvelopeStore()->GetEnvelopes();
417 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
420 AliMUONGeometryEnvelope* env
421 = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
423 // Check consistency of detElemId and module Id
424 if ( env->GetUniqueID() > 0 &&
425 AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
426 != geometry->GetModuleId() ) {
429 << "Detection element " << env->GetUniqueID()
430 << " is being placed in geometry module " << geometry->GetModuleId()
431 << " but should go in "
432 << AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
434 AliFatal("Inconsistent IDs");
437 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
438 const char* only = "ONLY";
439 if (env->IsMANY()) only = "MANY";
441 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
442 // virtual envelope + nof constituents = 0
444 // empty virtual envelope has no sense
445 AliFatal("Virtual envelope must have constituents.");
449 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
450 // non virtual envelope + nof constituents > 0
452 // use VMC to place constituents
453 AliFatal("Non virtual envelope cannot have constituents.");
457 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
458 // non virtual envelope + nof constituents = 0
459 // => place envelope by composed transformation:
460 // Tch * [Tglobal] * Tenv
462 // Compound chamber transformation with the envelope one
463 if (geometry->IsVirtual()) {
465 = Multiply( (*kModuleTransform),
466 appliedGlobalTransform,
468 PlaceVolume(env->GetName(), motherVolName,
469 env->GetCopyNo(), total, 0, 0, only);
473 = Multiply( appliedGlobalTransform,
475 PlaceVolume(env->GetName(), volName,
476 env->GetCopyNo(), total, 0, 0, only);
480 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
481 // virtual envelope + nof constituents > 0
482 // => do not place envelope and place constituents
483 // by composed transformation:
484 // Tch * [Tglobal] * Tenv * Tconst
486 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
487 AliMUONGeometryConstituent* constituent
488 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
490 // Compound chamber transformation with the envelope one + the constituent one
491 if (geometry->IsVirtual()) {
493 = Multiply ( (*kModuleTransform),
494 appliedGlobalTransform,
496 (*constituent->GetTransformation()) );
498 PlaceVolume(constituent->GetName(), motherVolName,
499 constituent->GetCopyNo(), total,
500 constituent->GetNpar(), constituent->GetParam(), only);
504 = Multiply ( appliedGlobalTransform,
506 (*constituent->GetTransformation()) );
508 PlaceVolume(constituent->GetName(), volName,
509 constituent->GetCopyNo(), total,
510 constituent->GetNpar(), constituent->GetParam(), only);
514 } // end of loop over envelopes
515 } // end of loop over builder geometries
516 } // end of loop over builders
519 //_____________________________________________________________________________
520 void AliMUONGeometryBuilder::SetAlignToBuilder(AliMUONVGeometryBuilder* builder) const
522 /// Set align option to all geometry modules associated with the builder
524 for (Int_t j=0; j<builder->NofGeometries(); j++) {
526 AliMUONGeometryModule* geometry = builder->Geometry(j);
528 geometry->SetAlign(fAlign);
536 //_____________________________________________________________________________
537 void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
539 /// Add the geometry builder to the list
541 fGeometryBuilders->Add(geomBuilder);
543 // Pass geometry modules created in the to the geometry parametrisation
544 for (Int_t i=0; i<geomBuilder->NofGeometries(); i++) {
545 fGeometry->AddModule(geomBuilder->Geometry(i));
548 if (geomBuilder->ApplyGlobalTransformation())
549 geomBuilder->SetReferenceFrame(fGlobalTransformation);
551 SetAlignToBuilder(geomBuilder);
554 //______________________________________________________________________________
555 void AliMUONGeometryBuilder::CreateGeometry()
557 /// Construct geometry using geometry builders.
559 if ( gMC->IsRootGeometrySupported() ) {
561 CreateGeometryWithTGeo();
564 CreateGeometryWithoutTGeo();
566 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
569 AliMUONVGeometryBuilder* builder
570 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
572 // Update detection elements from built geometry
573 Bool_t create = ! fAlign;
574 builder->UpdateDetElements(create);
578 //_____________________________________________________________________________
579 void AliMUONGeometryBuilder::CreateMaterials()
581 /// Construct materials specific to modules via builders
583 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
586 AliMUONVGeometryBuilder* builder
587 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
589 // Create materials with each builder
590 if (builder) builder->CreateMaterials();
594 //______________________________________________________________________________
595 void AliMUONGeometryBuilder::InitGeometry(const TString& svmapFileName)
597 /// Initialize geometry
599 // Load alignement data from geometry if geometry is read from Root file
600 if ( AliSimulation::Instance()->IsGeometryFromFile() ) {
602 fGeometry->GetTransformer()->LoadGeometryData();
605 // Read sensitive volume map from a file
606 fGeometry->ReadSVMap(svmapFileName);
608 // Set the chamber (sensitive region) GEANT identifier
610 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
613 AliMUONVGeometryBuilder* builder
614 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
616 // Set sensitive volumes with each builder
617 builder->SetSensitiveVolumes();
621 //________________________________________________________________
622 void AliMUONGeometryBuilder::UpdateInternalGeometry()
624 /// Update geometry after applying mis-alignment:
625 /// reload transformations in geometry builder.
627 fGeometry->GetTransformer()->LoadTransformations();
630 //______________________________________________________________________________
631 void AliMUONGeometryBuilder::WriteSVMaps(const TString& fileName,
632 Bool_t rebuild, Bool_t writeEnvelopes)
634 /// Write sensitive volume maps into files per builder
639 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
641 AliMUONVGeometryBuilder* builder
642 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
644 builder->RebuildSVMaps(writeEnvelopes);
647 // Write maps in file
648 fGeometry->WriteSVMap(fileName);
651 //_____________________________________________________________________________
652 void AliMUONGeometryBuilder::SetAlign(Bool_t align)
654 /// Set the option for alignement
658 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
660 AliMUONVGeometryBuilder* builder
661 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
663 SetAlignToBuilder(builder);
667 //_____________________________________________________________________________
668 void AliMUONGeometryBuilder::SetAlign(const TString& fileName, Bool_t align)
670 /// Set the option for alignement and the transformations file name
672 fTransformFileName = fileName;
675 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
677 AliMUONVGeometryBuilder* builder
678 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
680 SetAlignToBuilder(builder);