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>
47 // static data members
49 const TString AliMUONGeometryBuilder::fgkDefaultVolPathsFileName = "volpath.dat";
50 const TString AliMUONGeometryBuilder::fgkDefaultTransformFileName = "transform.dat";
51 const TString AliMUONGeometryBuilder::fgkDefaultSVMapFileName = "svmap.dat";
52 const TString AliMUONGeometryBuilder::fgkOutFileNameExtension = ".out";
55 ClassImp(AliMUONGeometryBuilder)
60 //______________________________________________________________________________
61 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
64 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
66 if (m1.IsIdentity() && m2.IsIdentity()) return TGeoHMatrix();
68 if (m1.IsIdentity()) return m2;
70 if (m2.IsIdentity()) return m1;
75 //______________________________________________________________________________
76 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
80 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
82 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity())
85 if (m1.IsIdentity()) return Multiply(m2, m3);
87 if (m2.IsIdentity()) return Multiply(m1, m3);
89 if (m3.IsIdentity()) return Multiply(m1, m2);
94 //______________________________________________________________________________
95 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() & m4.IsIdentity())
103 return TGeoHMatrix();
105 if (m1.IsIdentity()) return Multiply(m2, m3, m4);
107 if (m2.IsIdentity()) return Multiply(m1, m3, m4);
109 if (m3.IsIdentity()) return Multiply(m1, m2, m4);
111 if (m4.IsIdentity()) return Multiply(m1, m2, m3);
113 return m1 * m2 * m3 * m4;
116 //______________________________________________________________________________
117 AliMUONGeometryBuilder::AliMUONGeometryBuilder(AliModule* module)
121 fTransformFileName(fgkDefaultTransformFileName),
122 fSVMapFileName(fgkDefaultSVMapFileName),
123 fGlobalTransformation(),
124 fGeometryBuilders(0),
127 /// Standard constructor
129 fGeometryBuilders = new TObjArray();
130 fGeometryBuilders->SetOwner(true);
132 fGeometry = new AliMUONGeometry(true);
134 // Define the global transformation:
135 // Transformation from the old ALICE coordinate system to a new one:
137 TGeoRotation* rotGlobal
138 = new TGeoRotation("rotGlobal", 90., 180., 90., 90., 180., 0.);
139 fGlobalTransformation = TGeoCombiTrans(0., 0., 0., rotGlobal);
142 //______________________________________________________________________________
143 AliMUONGeometryBuilder::AliMUONGeometryBuilder()
147 fTransformFileName(),
149 fGlobalTransformation(),
150 fGeometryBuilders(0),
153 /// Default constructor
156 //______________________________________________________________________________
157 AliMUONGeometryBuilder::~AliMUONGeometryBuilder()
161 delete fGeometryBuilders;
169 //______________________________________________________________________________
170 void AliMUONGeometryBuilder::PlaceVolume(const TString& name, const TString& mName,
171 Int_t copyNo, const TGeoHMatrix& matrix,
172 Int_t npar, Double_t* param, const char* only,
173 Bool_t makeAssembly) const
175 /// Place the volume specified by name with the given transformation matrix
178 gGeoManager->MakeVolumeAssembly(name.Data());
180 TGeoHMatrix transform(matrix);
181 // Do not apply global transformation
182 // if mother volume was already placed in
183 // the new system of coordinates (that is MUON in negative Z)
184 // (as it is applied on the mother volume)
185 if (mName == TString("DDIP"))
186 transform = fGlobalTransformation.Inverse() * transform;
188 // Decompose transformation
189 const Double_t* xyz = transform.GetTranslation();
190 const Double_t* rm = transform.GetRotationMatrix();
192 //cout << "Got translation: "
193 // << xyz[0] << " " << xyz[1] << " " << xyz[2] << endl;
195 //cout << "Got rotation: "
196 // << rm[0] << " " << rm[1] << " " << rm[2] << endl
197 // << rm[3] << " " << rm[4] << " " << rm[5] << endl
198 // << rm[6] << " " << rm[7] << " " << rm[8] << endl;
200 // Check for presence of rotation
201 // (will be nice to be available in TGeo)
202 const Double_t kTolerance = 1e-04;
203 Bool_t isRotation = true;
204 if (TMath::Abs(rm[0] - 1.) < kTolerance &&
205 TMath::Abs(rm[1] - 0.) < kTolerance &&
206 TMath::Abs(rm[2] - 0.) < kTolerance &&
207 TMath::Abs(rm[3] - 0.) < kTolerance &&
208 TMath::Abs(rm[4] - 1.) < kTolerance &&
209 TMath::Abs(rm[5] - 0.) < kTolerance &&
210 TMath::Abs(rm[6] - 0.) < kTolerance &&
211 TMath::Abs(rm[7] - 0.) < kTolerance &&
212 TMath::Abs(rm[8] - 1.) < kTolerance) isRotation = false;
217 rot.SetMatrix(const_cast<Double_t*>(transform.GetRotationMatrix()));
218 Double_t theta1, phi1, theta2, phi2, theta3, phi3;
219 rot.GetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
222 // << theta1 << " " << phi1 << " "
223 // << theta2 << " " << phi2 << " "
224 // << theta3 << " " << phi3 << endl;
226 fModule->AliMatrix(krot, theta1, phi1, theta2, phi2, theta3, phi3);
231 gMC->Gspos(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only);
233 gMC->Gsposp(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only,
237 //______________________________________________________________________________
238 void AliMUONGeometryBuilder::CreateGeometryWithTGeo()
240 /// Construct geometry using geometry builders.
241 /// Virtual modules/envelopes are placed as TGeoVolume assembly
244 // Read transformations from ASCII data file
245 fGeometry->GetTransformer()
246 ->LoadGeometryData(fTransformFileName);
249 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
252 AliMUONVGeometryBuilder* builder
253 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
255 // Create geometry + envelopes
257 builder->CreateGeometry();
258 builder->SetVolumes();
259 if (!fAlign) builder->SetTransformations();
261 // Place module volumes and envelopes
263 for (Int_t j=0; j<builder->NofGeometries(); j++) {
265 AliMUONGeometryModule* geometry = builder->Geometry(j);
266 AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
267 const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
268 TString volName = transformer->GetVolumeName();
269 TString motherVolName = transformer->GetMotherVolumeName();
271 // Place the module volume
272 PlaceVolume(volName, motherVolName,
273 1, *kModuleTransform, 0, 0, "ONLY", geometry->IsVirtual());
275 TGeoCombiTrans appliedGlobalTransform;
276 if (builder->ApplyGlobalTransformation())
277 appliedGlobalTransform = fGlobalTransformation;
279 // Loop over envelopes
280 const TObjArray* kEnvelopes
281 = geometry->GetEnvelopeStore()->GetEnvelopes();
282 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
285 AliMUONGeometryEnvelope* env
286 = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
288 // Check consistency of detElemId and module Id
289 if ( env->GetUniqueID() > 0 &&
290 AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
291 != geometry->GetModuleId() ) {
294 << "Detection element " << env->GetUniqueID()
295 << " is being placed in geometry module " << geometry->GetModuleId()
296 << " but should go in "
297 << AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
299 AliFatal("Inconsistent IDs");
302 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
303 const char* only = "ONLY";
304 if (env->IsMANY()) only = "MANY";
306 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
307 // virtual envelope + nof constituents = 0
309 // empty virtual envelope has no sense
310 AliFatal("Virtual envelope must have constituents.");
314 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
315 // non virtual envelope + nof constituents > 0
317 // use VMC to place constituents
318 AliFatal("Non virtual envelope cannot have constituents.");
322 // Place envelope in geometry module by composed transformation:
325 = Multiply( appliedGlobalTransform,
327 PlaceVolume(env->GetName(), volName,
328 env->GetCopyNo(), total, 0, 0, only, env->IsVirtual());
330 if ( env->IsVirtual() ) {
331 // Place constituents in the envelope
332 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
333 AliMUONGeometryConstituent* constituent
334 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
336 PlaceVolume(constituent->GetName(), env->GetName(),
337 constituent->GetCopyNo(),
338 *constituent->GetTransformation() ,
339 constituent->GetNpar(), constituent->GetParam(), only);
342 } // end of loop over envelopes
343 } // end of loop over builder geometries
344 } // end of loop over builders
347 //______________________________________________________________________________
348 void AliMUONGeometryBuilder::CreateGeometryWithoutTGeo()
350 /// Construct geometry using geometry builders.
351 /// Virtual modules/envelopes are not placed
354 // Read transformations from ASCII data file
355 fGeometry->GetTransformer()->LoadGeometryData(fTransformFileName);
358 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
361 AliMUONVGeometryBuilder* builder
362 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
364 // Create geometry + envelopes
366 builder->CreateGeometry();
367 if (!fAlign) builder->SetTransformations();
369 // Place module volumes and envelopes
371 for (Int_t j=0; j<builder->NofGeometries(); j++) {
373 AliMUONGeometryModule* geometry = builder->Geometry(j);
374 AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
375 const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
376 TString volName = transformer->GetVolumeName();
377 TString motherVolName = transformer->GetMotherVolumeName();
379 // Place the module volume
380 if ( !geometry->IsVirtual() ) {
381 PlaceVolume(volName, motherVolName,
382 1, *kModuleTransform, 0, 0, "ONLY");
385 TGeoCombiTrans appliedGlobalTransform;
386 if (builder->ApplyGlobalTransformation())
387 appliedGlobalTransform = fGlobalTransformation;
389 // Loop over envelopes
390 const TObjArray* kEnvelopes
391 = geometry->GetEnvelopeStore()->GetEnvelopes();
392 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
395 AliMUONGeometryEnvelope* env
396 = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
398 // Check consistency of detElemId and module Id
399 if ( env->GetUniqueID() > 0 &&
400 AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
401 != geometry->GetModuleId() ) {
404 << "Detection element " << env->GetUniqueID()
405 << " is being placed in geometry module " << geometry->GetModuleId()
406 << " but should go in "
407 << AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
409 AliFatal("Inconsistent IDs");
412 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
413 const char* only = "ONLY";
414 if (env->IsMANY()) only = "MANY";
416 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
417 // virtual envelope + nof constituents = 0
419 // empty virtual envelope has no sense
420 AliFatal("Virtual envelope must have constituents.");
424 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
425 // non virtual envelope + nof constituents > 0
427 // use VMC to place constituents
428 AliFatal("Non virtual envelope cannot have constituents.");
432 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
433 // non virtual envelope + nof constituents = 0
434 // => place envelope by composed transformation:
435 // Tch * [Tglobal] * Tenv
437 // Compound chamber transformation with the envelope one
438 if (geometry->IsVirtual()) {
440 = Multiply( (*kModuleTransform),
441 appliedGlobalTransform,
443 PlaceVolume(env->GetName(), motherVolName,
444 env->GetCopyNo(), total, 0, 0, only);
448 = Multiply( appliedGlobalTransform,
450 PlaceVolume(env->GetName(), volName,
451 env->GetCopyNo(), total, 0, 0, only);
455 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
456 // virtual envelope + nof constituents > 0
457 // => do not place envelope and place constituents
458 // by composed transformation:
459 // Tch * [Tglobal] * Tenv * Tconst
461 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
462 AliMUONGeometryConstituent* constituent
463 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
465 // Compound chamber transformation with the envelope one + the constituent one
466 if (geometry->IsVirtual()) {
468 = Multiply ( (*kModuleTransform),
469 appliedGlobalTransform,
471 (*constituent->GetTransformation()) );
473 PlaceVolume(constituent->GetName(), motherVolName,
474 constituent->GetCopyNo(), total,
475 constituent->GetNpar(), constituent->GetParam(), only);
479 = Multiply ( appliedGlobalTransform,
481 (*constituent->GetTransformation()) );
483 PlaceVolume(constituent->GetName(), volName,
484 constituent->GetCopyNo(), total,
485 constituent->GetNpar(), constituent->GetParam(), only);
489 } // end of loop over envelopes
490 } // end of loop over builder geometries
491 } // end of loop over builders
494 //_____________________________________________________________________________
495 void AliMUONGeometryBuilder::SetAlignToBuilder(AliMUONVGeometryBuilder* builder) const
497 /// Set align option to all geometry modules associated with the builder
499 for (Int_t j=0; j<builder->NofGeometries(); j++) {
501 AliMUONGeometryModule* geometry = builder->Geometry(j);
503 geometry->SetAlign(fAlign);
511 //_____________________________________________________________________________
512 void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
514 /// Add the geometry builder to the list
516 fGeometryBuilders->Add(geomBuilder);
518 // Pass geometry modules created in the to the geometry parametrisation
519 for (Int_t i=0; i<geomBuilder->NofGeometries(); i++) {
520 fGeometry->AddModule(geomBuilder->Geometry(i));
523 if (geomBuilder->ApplyGlobalTransformation())
524 geomBuilder->SetReferenceFrame(fGlobalTransformation);
526 SetAlignToBuilder(geomBuilder);
529 //______________________________________________________________________________
530 void AliMUONGeometryBuilder::CreateGeometry()
532 /// Construct geometry using geometry builders.
534 if ( gMC->IsRootGeometrySupported() ) {
536 CreateGeometryWithTGeo();
539 CreateGeometryWithoutTGeo();
541 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
544 AliMUONVGeometryBuilder* builder
545 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
547 // Update detection elements from built geometry
548 Bool_t create = ! fAlign;
549 builder->UpdateDetElements(create);
553 //_____________________________________________________________________________
554 void AliMUONGeometryBuilder::CreateMaterials()
556 /// Construct materials specific to modules via builders
558 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
561 AliMUONVGeometryBuilder* builder
562 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
564 // Create materials with each builder
565 if (builder) builder->CreateMaterials();
569 //______________________________________________________________________________
570 void AliMUONGeometryBuilder::InitGeometry(const TString& svmapFileName)
572 /// Initialize geometry
574 // Load alignement data from geometry if geometry is read from Root file
575 if ( AliSimulation::Instance()->IsGeometryFromFile() ) {
577 fGeometry->GetTransformer()->LoadGeometryData();
580 // Read sensitive volume map from a file
581 fGeometry->ReadSVMap(svmapFileName);
583 // Set the chamber (sensitive region) GEANT identifier
585 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
588 AliMUONVGeometryBuilder* builder
589 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
591 // Set sensitive volumes with each builder
592 builder->SetSensitiveVolumes();
596 //________________________________________________________________
597 void AliMUONGeometryBuilder::UpdateInternalGeometry()
599 /// Update geometry after applying mis-alignment:
600 /// reload transformations in geometry builder.
602 fGeometry->GetTransformer()->LoadTransformations();
605 //______________________________________________________________________________
606 void AliMUONGeometryBuilder::WriteSVMaps(const TString& fileName,
607 Bool_t rebuild, Bool_t writeEnvelopes)
609 /// Write sensitive volume maps into files per builder
614 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
616 AliMUONVGeometryBuilder* builder
617 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
619 builder->RebuildSVMaps(writeEnvelopes);
622 // Write maps in file
623 fGeometry->WriteSVMap(fileName);
626 //_____________________________________________________________________________
627 void AliMUONGeometryBuilder::SetAlign(Bool_t align)
629 /// Set the option for alignement
633 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
635 AliMUONVGeometryBuilder* builder
636 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
638 SetAlignToBuilder(builder);
642 //_____________________________________________________________________________
643 void AliMUONGeometryBuilder::SetAlign(const TString& fileName, Bool_t align)
645 /// Set the option for alignement and the transformations file name
647 fTransformFileName = fileName;
650 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
652 AliMUONVGeometryBuilder* builder
653 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
655 SetAlignToBuilder(builder);