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
24 #include "AliMUONGeometryBuilder.h"
25 #include "AliMUONVGeometryBuilder.h"
26 #include "AliMUONGeometry.h"
27 #include "AliMUONGeometryTransformer.h"
28 #include "AliMUONGeometryModule.h"
29 #include "AliMUONGeometryModuleTransformer.h"
30 #include "AliMUONGeometryEnvelope.h"
31 #include "AliMUONGeometryEnvelopeStore.h"
32 #include "AliMUONGeometryDetElement.h"
33 #include "AliMUONGeometryConstituent.h"
35 #include "AliMpDEManager.h"
37 #include "AliModule.h"
41 #include <TObjArray.h>
42 #include <TVirtualMC.h>
43 #include <TGeoManager.h>
45 // static data members
47 const TString AliMUONGeometryBuilder::fgkDefaultVolPathsFileName = "volpath.dat";
48 const TString AliMUONGeometryBuilder::fgkDefaultTransformFileName = "transform.dat";
49 const TString AliMUONGeometryBuilder::fgkDefaultSVMapFileName = "svmap.dat";
50 const TString AliMUONGeometryBuilder::fgkOutFileNameExtension = ".out";
53 ClassImp(AliMUONGeometryBuilder)
58 //______________________________________________________________________________
59 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
62 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
64 if (m1.IsIdentity() && m2.IsIdentity()) return TGeoHMatrix();
66 if (m1.IsIdentity()) return m2;
68 if (m2.IsIdentity()) return m1;
73 //______________________________________________________________________________
74 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
78 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
80 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity())
83 if (m1.IsIdentity()) return Multiply(m2, m3);
85 if (m2.IsIdentity()) return Multiply(m1, m3);
87 if (m3.IsIdentity()) return Multiply(m1, m2);
92 //______________________________________________________________________________
93 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
98 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
100 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity() & m4.IsIdentity())
101 return TGeoHMatrix();
103 if (m1.IsIdentity()) return Multiply(m2, m3, m4);
105 if (m2.IsIdentity()) return Multiply(m1, m3, m4);
107 if (m3.IsIdentity()) return Multiply(m1, m2, m4);
109 if (m4.IsIdentity()) return Multiply(m1, m2, m3);
111 return m1 * m2 * m3 * m4;
114 //______________________________________________________________________________
115 AliMUONGeometryBuilder::AliMUONGeometryBuilder(AliModule* module)
119 fTransformFileName(fgkDefaultTransformFileName),
120 fSVMapFileName(fgkDefaultSVMapFileName),
121 fGlobalTransformation(),
122 fGeometryBuilders(0),
125 /// Standard constructor
127 fGeometryBuilders = new TObjArray();
128 fGeometryBuilders->SetOwner(true);
130 fGeometry = new AliMUONGeometry(true);
132 // Define the global transformation:
133 // Transformation from the old ALICE coordinate system to a new one:
135 TGeoRotation* rotGlobal
136 = new TGeoRotation("rotGlobal", 90., 180., 90., 90., 180., 0.);
137 fGlobalTransformation = TGeoCombiTrans(0., 0., 0., rotGlobal);
140 //______________________________________________________________________________
141 AliMUONGeometryBuilder::AliMUONGeometryBuilder()
145 fTransformFileName(),
147 fGlobalTransformation(),
148 fGeometryBuilders(0),
151 /// Default constructor
154 //______________________________________________________________________________
155 AliMUONGeometryBuilder::~AliMUONGeometryBuilder()
159 delete fGeometryBuilders;
167 //______________________________________________________________________________
168 void AliMUONGeometryBuilder::PlaceVolume(const TString& name, const TString& mName,
169 Int_t copyNo, const TGeoHMatrix& matrix,
170 Int_t npar, Double_t* param, const char* only,
171 Bool_t makeAssembly) const
173 /// Place the volume specified by name with the given transformation matrix
176 gGeoManager->MakeVolumeAssembly(name.Data());
178 TGeoHMatrix transform(matrix);
179 // Do not apply global transformation
180 // if mother volume was already placed in
181 // the new system of coordinates (that is MUON in negative Z)
182 // (as it is applied on the mother volume)
183 if (mName == TString("DDIP"))
184 transform = fGlobalTransformation.Inverse() * transform;
186 // Decompose transformation
187 const Double_t* xyz = transform.GetTranslation();
188 const Double_t* rm = transform.GetRotationMatrix();
190 //cout << "Got translation: "
191 // << xyz[0] << " " << xyz[1] << " " << xyz[2] << endl;
193 //cout << "Got rotation: "
194 // << rm[0] << " " << rm[1] << " " << rm[2] << endl
195 // << rm[3] << " " << rm[4] << " " << rm[5] << endl
196 // << rm[6] << " " << rm[7] << " " << rm[8] << endl;
198 // Check for presence of rotation
199 // (will be nice to be available in TGeo)
200 const Double_t kTolerance = 1e-04;
201 Bool_t isRotation = true;
202 if (TMath::Abs(rm[0] - 1.) < kTolerance &&
203 TMath::Abs(rm[1] - 0.) < kTolerance &&
204 TMath::Abs(rm[2] - 0.) < kTolerance &&
205 TMath::Abs(rm[3] - 0.) < kTolerance &&
206 TMath::Abs(rm[4] - 1.) < kTolerance &&
207 TMath::Abs(rm[5] - 0.) < kTolerance &&
208 TMath::Abs(rm[6] - 0.) < kTolerance &&
209 TMath::Abs(rm[7] - 0.) < kTolerance &&
210 TMath::Abs(rm[8] - 1.) < kTolerance) isRotation = false;
215 rot.SetMatrix(const_cast<Double_t*>(transform.GetRotationMatrix()));
216 Double_t theta1, phi1, theta2, phi2, theta3, phi3;
217 rot.GetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
220 // << theta1 << " " << phi1 << " "
221 // << theta2 << " " << phi2 << " "
222 // << theta3 << " " << phi3 << endl;
224 fModule->AliMatrix(krot, theta1, phi1, theta2, phi2, theta3, phi3);
229 gMC->Gspos(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only);
231 gMC->Gsposp(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only,
235 //______________________________________________________________________________
236 void AliMUONGeometryBuilder::CreateGeometryWithTGeo()
238 /// Construct geometry using geometry builders.
239 /// Virtual modules/envelopes are placed as TGeoVolume assembly
242 // Read transformations from ASCII data file
243 fGeometry->GetTransformer()
244 ->LoadGeometryData(fTransformFileName);
247 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
250 AliMUONVGeometryBuilder* builder
251 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
253 // Create geometry + envelopes
255 builder->CreateGeometry();
256 if (!fAlign) builder->SetTransformations();
258 // Place module volumes and envelopes
260 for (Int_t j=0; j<builder->NofGeometries(); j++) {
262 AliMUONGeometryModule* geometry = builder->Geometry(j);
263 AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
264 const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
265 TString volName = transformer->GetVolumeName();
266 TString motherVolName = transformer->GetMotherVolumeName();
268 // Place the module volume
269 PlaceVolume(volName, motherVolName,
270 1, *kModuleTransform, 0, 0, "ONLY", geometry->IsVirtual());
272 TGeoCombiTrans appliedGlobalTransform;
273 if (builder->ApplyGlobalTransformation())
274 appliedGlobalTransform = fGlobalTransformation;
276 // Loop over envelopes
277 const TObjArray* kEnvelopes
278 = geometry->GetEnvelopeStore()->GetEnvelopes();
279 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
282 AliMUONGeometryEnvelope* env
283 = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
285 // Check consistency of detElemId and module Id
286 if ( env->GetUniqueID() > 0 &&
287 AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
288 != geometry->GetModuleId() ) {
291 << "Detection element " << env->GetUniqueID()
292 << " is being placed in geometry module " << geometry->GetModuleId()
293 << " but should go in "
294 << AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
296 AliFatal("Inconsistent IDs");
299 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
300 const char* only = "ONLY";
301 if (env->IsMANY()) only = "MANY";
303 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
304 // virtual envelope + nof constituents = 0
306 // empty virtual envelope has no sense
307 AliFatal("Virtual envelope must have constituents.");
311 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
312 // non virtual envelope + nof constituents > 0
314 // use VMC to place constituents
315 AliFatal("Non virtual envelope cannot have constituents.");
319 // Place envelope in geometry module by composed transformation:
322 = Multiply( appliedGlobalTransform,
324 PlaceVolume(env->GetName(), volName,
325 env->GetCopyNo(), total, 0, 0, only, env->IsVirtual());
327 if ( env->IsVirtual() ) {
328 // Place constituents in the envelope
329 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
330 AliMUONGeometryConstituent* constituent
331 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
333 PlaceVolume(constituent->GetName(), env->GetName(),
334 constituent->GetCopyNo(),
335 *constituent->GetTransformation() ,
336 constituent->GetNpar(), constituent->GetParam(), only);
339 } // end of loop over envelopes
340 } // end of loop over builder geometries
341 } // end of loop over builders
344 //______________________________________________________________________________
345 void AliMUONGeometryBuilder::CreateGeometryWithoutTGeo()
347 /// Construct geometry using geometry builders.
348 /// Virtual modules/envelopes are not placed
351 // Read transformations from ASCII data file
352 fGeometry->GetTransformer()->LoadGeometryData(fTransformFileName);
355 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
358 AliMUONVGeometryBuilder* builder
359 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
361 // Create geometry + envelopes
363 builder->CreateGeometry();
364 if (!fAlign) builder->SetTransformations();
366 // Place module volumes and envelopes
368 for (Int_t j=0; j<builder->NofGeometries(); j++) {
370 AliMUONGeometryModule* geometry = builder->Geometry(j);
371 AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
372 const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
373 TString volName = transformer->GetVolumeName();
374 TString motherVolName = transformer->GetMotherVolumeName();
376 // Place the module volume
377 if ( !geometry->IsVirtual() ) {
378 PlaceVolume(volName, motherVolName,
379 1, *kModuleTransform, 0, 0, "ONLY");
382 TGeoCombiTrans appliedGlobalTransform;
383 if (builder->ApplyGlobalTransformation())
384 appliedGlobalTransform = fGlobalTransformation;
386 // Loop over envelopes
387 const TObjArray* kEnvelopes
388 = geometry->GetEnvelopeStore()->GetEnvelopes();
389 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
392 AliMUONGeometryEnvelope* env
393 = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
395 // Check consistency of detElemId and module Id
396 if ( env->GetUniqueID() > 0 &&
397 AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
398 != geometry->GetModuleId() ) {
401 << "Detection element " << env->GetUniqueID()
402 << " is being placed in geometry module " << geometry->GetModuleId()
403 << " but should go in "
404 << AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
406 AliFatal("Inconsistent IDs");
409 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
410 const char* only = "ONLY";
411 if (env->IsMANY()) only = "MANY";
413 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
414 // virtual envelope + nof constituents = 0
416 // empty virtual envelope has no sense
417 AliFatal("Virtual envelope must have constituents.");
421 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
422 // non virtual envelope + nof constituents > 0
424 // use VMC to place constituents
425 AliFatal("Non virtual envelope cannot have constituents.");
429 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
430 // non virtual envelope + nof constituents = 0
431 // => place envelope by composed transformation:
432 // Tch * [Tglobal] * Tenv
434 // Compound chamber transformation with the envelope one
435 if (geometry->IsVirtual()) {
437 = Multiply( (*kModuleTransform),
438 appliedGlobalTransform,
440 PlaceVolume(env->GetName(), motherVolName,
441 env->GetCopyNo(), total, 0, 0, only);
445 = Multiply( appliedGlobalTransform,
447 PlaceVolume(env->GetName(), volName,
448 env->GetCopyNo(), total, 0, 0, only);
452 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
453 // virtual envelope + nof constituents > 0
454 // => do not place envelope and place constituents
455 // by composed transformation:
456 // Tch * [Tglobal] * Tenv * Tconst
458 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
459 AliMUONGeometryConstituent* constituent
460 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
462 // Compound chamber transformation with the envelope one + the constituent one
463 if (geometry->IsVirtual()) {
465 = Multiply ( (*kModuleTransform),
466 appliedGlobalTransform,
468 (*constituent->GetTransformation()) );
470 PlaceVolume(constituent->GetName(), motherVolName,
471 constituent->GetCopyNo(), total,
472 constituent->GetNpar(), constituent->GetParam(), only);
476 = Multiply ( appliedGlobalTransform,
478 (*constituent->GetTransformation()) );
480 PlaceVolume(constituent->GetName(), volName,
481 constituent->GetCopyNo(), total,
482 constituent->GetNpar(), constituent->GetParam(), only);
486 } // end of loop over envelopes
487 } // end of loop over builder geometries
488 } // end of loop over builders
491 //_____________________________________________________________________________
492 void AliMUONGeometryBuilder::SetAlign(AliMUONVGeometryBuilder* builder)
494 /// Set align option to all geometry modules associated with the builder
496 for (Int_t j=0; j<builder->NofGeometries(); j++) {
498 AliMUONGeometryModule* geometry = builder->Geometry(j);
500 geometry->SetAlign(fAlign);
508 //_____________________________________________________________________________
509 void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
511 /// Add the geometry builder to the list
513 fGeometryBuilders->Add(geomBuilder);
515 // Pass geometry modules created in the to the geometry parametrisation
516 for (Int_t i=0; i<geomBuilder->NofGeometries(); i++) {
517 fGeometry->AddModule(geomBuilder->Geometry(i));
520 if (geomBuilder->ApplyGlobalTransformation())
521 geomBuilder->SetReferenceFrame(fGlobalTransformation);
523 SetAlign(geomBuilder);
526 //______________________________________________________________________________
527 void AliMUONGeometryBuilder::CreateGeometry()
529 /// Construct geometry using geometry builders.
531 if ( gMC->IsRootGeometrySupported() ) {
533 CreateGeometryWithTGeo();
536 CreateGeometryWithoutTGeo();
538 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
541 AliMUONVGeometryBuilder* builder
542 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
544 // Create detection elements from built geometry
545 builder->CreateDetElements();
549 //_____________________________________________________________________________
550 void AliMUONGeometryBuilder::CreateMaterials()
552 /// Construct materials specific to modules via builders
554 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
557 AliMUONVGeometryBuilder* builder
558 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
560 // Create materials with each builder
561 if (builder) builder->CreateMaterials();
565 //______________________________________________________________________________
566 void AliMUONGeometryBuilder::InitGeometry(const TString& svmapFileName)
568 /// Initialize geometry
570 // Load alignement data from geometry if geometry is read from Root file
571 if ( gAlice->IsRootGeometry() ) {
573 fGeometry->GetTransformer()->LoadGeometryData();
576 // Read sensitive volume map from a file
577 fGeometry->ReadSVMap(svmapFileName);
579 // Set the chamber (sensitive region) GEANT identifier
581 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
584 AliMUONVGeometryBuilder* builder
585 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
587 // Set sensitive volumes with each builder
588 builder->SetSensitiveVolumes();
592 //______________________________________________________________________________
593 void AliMUONGeometryBuilder::WriteSVMaps(const TString& fileName,
594 Bool_t rebuild, Bool_t writeEnvelopes)
596 /// Write sensitive volume maps into files per builder
601 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
603 AliMUONVGeometryBuilder* builder
604 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
606 builder->RebuildSVMaps(writeEnvelopes);
609 // Write maps in file
610 fGeometry->WriteSVMap(fileName);
613 //_____________________________________________________________________________
614 void AliMUONGeometryBuilder::SetAlign(Bool_t align)
616 /// Set the option for alignement
620 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
622 AliMUONVGeometryBuilder* builder
623 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
629 //_____________________________________________________________________________
630 void AliMUONGeometryBuilder::SetAlign(const TString& fileName, Bool_t align)
632 /// Set the option for alignement and the transformations file name
634 fTransformFileName = fileName;
637 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
639 AliMUONVGeometryBuilder* builder
640 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);