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 "AliMUONGeometryStore.h"
34 #include "AliMUONGeometryConstituent.h"
36 #include "AliModule.h"
40 #include <TObjArray.h>
41 #include <TVirtualMC.h>
42 #include <TGeoManager.h>
44 // static data members
46 const TString AliMUONGeometryBuilder::fgkDefaultVolPathsFileName = "volpath.dat";
47 const TString AliMUONGeometryBuilder::fgkDefaultTransformFileName = "transform.dat";
48 const TString AliMUONGeometryBuilder::fgkDefaultSVMapFileName = "svmap.dat";
49 const TString AliMUONGeometryBuilder::fgkOutFileNameExtension = ".out";
51 ClassImp(AliMUONGeometryBuilder)
55 //______________________________________________________________________________
56 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
59 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
61 if (m1.IsIdentity() && m2.IsIdentity()) return TGeoHMatrix();
63 if (m1.IsIdentity()) return m2;
65 if (m2.IsIdentity()) return m1;
70 //______________________________________________________________________________
71 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
75 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
77 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity())
80 if (m1.IsIdentity()) return Multiply(m2, m3);
82 if (m2.IsIdentity()) return Multiply(m1, m3);
84 if (m3.IsIdentity()) return Multiply(m1, m2);
89 //______________________________________________________________________________
90 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
95 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
97 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity() & m4.IsIdentity())
100 if (m1.IsIdentity()) return Multiply(m2, m3, m4);
102 if (m2.IsIdentity()) return Multiply(m1, m3, m4);
104 if (m3.IsIdentity()) return Multiply(m1, m2, m4);
106 if (m4.IsIdentity()) return Multiply(m1, m2, m3);
108 return m1 * m2 * m3 * m4;
111 //______________________________________________________________________________
112 AliMUONGeometryBuilder::AliMUONGeometryBuilder(AliModule* module)
116 fTransformFileName(fgkDefaultTransformFileName),
117 fSVMapFileName(fgkDefaultSVMapFileName),
118 fGlobalTransformation(),
119 fGeometryBuilders(0),
122 /// Standard constructor
124 fGeometryBuilders = new TObjArray();
125 fGeometryBuilders->SetOwner(true);
127 fGeometry = new AliMUONGeometry(true);
129 // Define the global transformation:
130 // Transformation from the old ALICE coordinate system to a new one:
132 TGeoRotation* rotGlobal
133 = new TGeoRotation("rotGlobal", 90., 180., 90., 90., 180., 0.);
134 fGlobalTransformation = TGeoCombiTrans(0., 0., 0., rotGlobal);
137 //______________________________________________________________________________
138 AliMUONGeometryBuilder::AliMUONGeometryBuilder()
142 fTransformFileName(),
144 fGlobalTransformation(),
145 fGeometryBuilders(0),
148 /// Default constructor
151 //______________________________________________________________________________
152 AliMUONGeometryBuilder::AliMUONGeometryBuilder(const AliMUONGeometryBuilder& right)
155 /// Copy constructor (not implemented)
157 AliFatal("Copy constructor not provided.");
160 //______________________________________________________________________________
161 AliMUONGeometryBuilder::~AliMUONGeometryBuilder()
165 delete fGeometryBuilders;
169 //______________________________________________________________________________
170 AliMUONGeometryBuilder&
171 AliMUONGeometryBuilder::operator=(const AliMUONGeometryBuilder& right)
173 /// Assignement operator (not implemented)
175 // check assignement to self
176 if (this == &right) return *this;
178 AliFatal("Assignement operator not provided.");
187 //______________________________________________________________________________
188 void AliMUONGeometryBuilder::PlaceVolume(const TString& name, const TString& mName,
189 Int_t copyNo, const TGeoHMatrix& matrix,
190 Int_t npar, Double_t* param, const char* only,
191 Bool_t makeAssembly) const
193 /// Place the volume specified by name with the given transformation matrix
196 gGeoManager->MakeVolumeAssembly(name.Data());
198 TGeoHMatrix transform(matrix);
199 // Do not apply global transformation
200 // if mother volume was already placed in
201 // the new system of coordinates (that is MUON in negative Z)
202 // (as it is applied on the mother volume)
203 if (mName == TString("DDIP"))
204 transform = fGlobalTransformation.Inverse() * transform;
206 // Decompose transformation
207 const Double_t* xyz = transform.GetTranslation();
208 const Double_t* rm = transform.GetRotationMatrix();
210 //cout << "Got translation: "
211 // << xyz[0] << " " << xyz[1] << " " << xyz[2] << endl;
213 //cout << "Got rotation: "
214 // << rm[0] << " " << rm[1] << " " << rm[2] << endl
215 // << rm[3] << " " << rm[4] << " " << rm[5] << endl
216 // << rm[6] << " " << rm[7] << " " << rm[8] << endl;
218 // Check for presence of rotation
219 // (will be nice to be available in TGeo)
220 const Double_t kTolerance = 1e-04;
221 Bool_t isRotation = true;
222 if (TMath::Abs(rm[0] - 1.) < kTolerance &&
223 TMath::Abs(rm[1] - 0.) < kTolerance &&
224 TMath::Abs(rm[2] - 0.) < kTolerance &&
225 TMath::Abs(rm[3] - 0.) < kTolerance &&
226 TMath::Abs(rm[4] - 1.) < kTolerance &&
227 TMath::Abs(rm[5] - 0.) < kTolerance &&
228 TMath::Abs(rm[6] - 0.) < kTolerance &&
229 TMath::Abs(rm[7] - 0.) < kTolerance &&
230 TMath::Abs(rm[8] - 1.) < kTolerance) isRotation = false;
235 rot.SetMatrix(const_cast<Double_t*>(transform.GetRotationMatrix()));
236 Double_t theta1, phi1, theta2, phi2, theta3, phi3;
237 rot.GetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
240 // << theta1 << " " << phi1 << " "
241 // << theta2 << " " << phi2 << " "
242 // << theta3 << " " << phi3 << endl;
244 fModule->AliMatrix(krot, theta1, phi1, theta2, phi2, theta3, phi3);
247 // Place the volume in ALIC
249 gMC->Gspos(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only);
251 gMC->Gsposp(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only,
255 //______________________________________________________________________________
256 void AliMUONGeometryBuilder::CreateGeometryWithTGeo()
258 /// Construct geometry using geometry builders.
259 /// Virtual modules/envelopes are placed as TGeoVolume assembly
262 // Read transformations from ASCII data file
263 fGeometry->GetTransformer()
264 ->ReadGeometryData(fgkDefaultVolPathsFileName, fTransformFileName);
267 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
270 AliMUONVGeometryBuilder* builder
271 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
273 // Create geometry + envelopes
275 builder->CreateGeometry();
276 if (!fAlign) builder->SetTransformations();
278 // Place module volumes and envelopes
280 for (Int_t j=0; j<builder->NofGeometries(); j++) {
282 AliMUONGeometryModule* geometry = builder->Geometry(j);
283 AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
284 const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
285 TString volName = transformer->GetVolumeName();
286 TString motherVolName = transformer->GetMotherVolumeName();
288 // Place the module volume
289 PlaceVolume(volName, motherVolName,
290 1, *kModuleTransform, 0, 0, "ONLY", geometry->IsVirtual());
292 TGeoCombiTrans appliedGlobalTransform;
293 if (builder->ApplyGlobalTransformation())
294 appliedGlobalTransform = fGlobalTransformation;
296 // Loop over envelopes
297 const TObjArray* kEnvelopes
298 = geometry->GetEnvelopeStore()->GetEnvelopes();
299 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
302 AliMUONGeometryEnvelope* env
303 = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
305 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
306 const char* only = "ONLY";
307 if (env->IsMANY()) only = "MANY";
309 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
310 // virtual envelope + nof constituents = 0
312 // empty virtual envelope has no sense
313 AliFatal("Virtual envelope must have constituents.");
317 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
318 // non virtual envelope + nof constituents > 0
320 // use VMC to place constituents
321 AliFatal("Non virtual envelope cannot have constituents.");
325 // Place envelope in geometry module by composed transformation:
328 = Multiply( appliedGlobalTransform,
330 PlaceVolume(env->GetName(), volName,
331 env->GetCopyNo(), total, 0, 0, only, env->IsVirtual());
333 if ( env->IsVirtual() ) {
334 // Place constituents in the envelope
335 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
336 AliMUONGeometryConstituent* constituent
337 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
339 PlaceVolume(constituent->GetName(), env->GetName(),
340 constituent->GetCopyNo(),
341 *constituent->GetTransformation() ,
342 constituent->GetNpar(), constituent->GetParam(), only);
345 } // end of loop over envelopes
346 } // end of loop over builder geometries
347 } // end of loop over builders
350 //______________________________________________________________________________
351 void AliMUONGeometryBuilder::CreateGeometryWithoutTGeo()
353 /// Construct geometry using geometry builders.
354 /// Virtual modules/enevlopes are not placed
357 // Read transformations from ASCII data file
358 fGeometry->GetTransformer()
359 ->ReadGeometryData(fgkDefaultVolPathsFileName, fTransformFileName);
362 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
365 AliMUONVGeometryBuilder* builder
366 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
368 // Create geometry + envelopes
370 builder->CreateGeometry();
371 if (!fAlign) builder->SetTransformations();
373 // Place module volumes and envelopes
375 for (Int_t j=0; j<builder->NofGeometries(); j++) {
377 AliMUONGeometryModule* geometry = builder->Geometry(j);
378 AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
379 const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
380 TString volName = transformer->GetVolumeName();
381 TString motherVolName = transformer->GetMotherVolumeName();
383 // Place the module volume
384 if ( !geometry->IsVirtual() ) {
385 PlaceVolume(volName, motherVolName,
386 1, *kModuleTransform, 0, 0, "ONLY");
389 TGeoCombiTrans appliedGlobalTransform;
390 if (builder->ApplyGlobalTransformation())
391 appliedGlobalTransform = fGlobalTransformation;
393 // Loop over envelopes
394 const TObjArray* kEnvelopes
395 = geometry->GetEnvelopeStore()->GetEnvelopes();
396 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
399 AliMUONGeometryEnvelope* env
400 = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
402 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
403 const char* only = "ONLY";
404 if (env->IsMANY()) only = "MANY";
406 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
407 // virtual envelope + nof constituents = 0
409 // empty virtual envelope has no sense
410 AliFatal("Virtual envelope must have constituents.");
414 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
415 // non virtual envelope + nof constituents > 0
417 // use VMC to place constituents
418 AliFatal("Non virtual envelope cannot have constituents.");
422 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
423 // non virtual envelope + nof constituents = 0
424 // => place envelope in ALICE by composed transformation:
425 // Tch * [Tglobal] * Tenv
427 // Compound chamber transformation with the envelope one
428 if (geometry->IsVirtual()) {
430 = Multiply( (*kModuleTransform),
431 appliedGlobalTransform,
433 PlaceVolume(env->GetName(), motherVolName,
434 env->GetCopyNo(), total, 0, 0, only);
438 = Multiply( appliedGlobalTransform,
440 PlaceVolume(env->GetName(), volName,
441 env->GetCopyNo(), total, 0, 0, only);
445 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
446 // virtual envelope + nof constituents > 0
447 // => do not place envelope and place constituents
448 // in ALICE by composed transformation:
449 // Tch * [Tglobal] * Tenv * Tconst
451 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
452 AliMUONGeometryConstituent* constituent
453 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
455 // Compound chamber transformation with the envelope one + the constituent one
456 if (geometry->IsVirtual()) {
458 = Multiply ( (*kModuleTransform),
459 appliedGlobalTransform,
461 (*constituent->GetTransformation()) );
463 PlaceVolume(constituent->GetName(), motherVolName,
464 constituent->GetCopyNo(), total,
465 constituent->GetNpar(), constituent->GetParam(), only);
469 = Multiply ( appliedGlobalTransform,
471 (*constituent->GetTransformation()) );
473 PlaceVolume(constituent->GetName(), volName,
474 constituent->GetCopyNo(), total,
475 constituent->GetNpar(), constituent->GetParam(), only);
479 } // end of loop over envelopes
480 } // end of loop over builder geometries
481 } // end of loop over builders
484 //_____________________________________________________________________________
485 void AliMUONGeometryBuilder::SetAlign(AliMUONVGeometryBuilder* builder)
487 /// Set align option to all geometry modules associated with the builder
489 for (Int_t j=0; j<builder->NofGeometries(); j++) {
491 AliMUONGeometryModule* geometry = builder->Geometry(j);
493 geometry->SetAlign(fAlign);
501 //_____________________________________________________________________________
502 void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
504 /// Add the geometry builder to the list
506 fGeometryBuilders->Add(geomBuilder);
508 // Pass geometry modules created in the to the geometry parametrisation
509 for (Int_t i=0; i<geomBuilder->NofGeometries(); i++) {
510 fGeometry->AddModule(geomBuilder->Geometry(i));
513 if (geomBuilder->ApplyGlobalTransformation())
514 geomBuilder->SetReferenceFrame(fGlobalTransformation);
516 SetAlign(geomBuilder);
519 //______________________________________________________________________________
520 void AliMUONGeometryBuilder::CreateGeometry()
522 /// Construct geometry using geometry builders.
524 if ( gMC->IsRootGeometrySupported() &&
525 TString(gMC->ClassName()) != "TGeant4" ) {
527 CreateGeometryWithTGeo();
530 CreateGeometryWithoutTGeo();
533 //_____________________________________________________________________________
534 void AliMUONGeometryBuilder::CreateMaterials()
536 /// Construct materials specific to modules via builders
538 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
541 AliMUONVGeometryBuilder* builder
542 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
544 // Create materials with each builder
545 if (builder) builder->CreateMaterials();
549 //______________________________________________________________________________
550 void AliMUONGeometryBuilder::InitGeometry(const TString& svmapFileName)
552 /// Initialize geometry
554 // Load alignement data from geometry if geometry is read from Root file
555 if ( gAlice->IsRootGeometry() ) {
558 fGeometry->GetTransformer()
559 ->ReadGeometryData(fgkDefaultVolPathsFileName, gGeoManager);
562 // Read sensitive volume map from a file
563 fGeometry->ReadSVMap(svmapFileName);
565 // Set the chamber (sensitive region) GEANT identifier
567 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
570 AliMUONVGeometryBuilder* builder
571 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
573 // Set sensitive volumes with each builder
574 builder->SetSensitiveVolumes();
577 // Create detection elements from built geometry
578 builder->CreateDetElements();
583 //______________________________________________________________________________
584 void AliMUONGeometryBuilder::WriteSVMaps(const TString& fileName,
587 /// Write sensitive volume maps into files per builder
592 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
594 AliMUONVGeometryBuilder* builder
595 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
597 Bool_t writeEnvelopes = false;
598 if ( gMC->IsRootGeometrySupported() &&
599 TString(gMC->ClassName()) != "TGeant4") writeEnvelopes = true;
601 builder->RebuildSVMaps(writeEnvelopes);
604 // Write maps in file
605 fGeometry->WriteSVMap(fileName);
608 //_____________________________________________________________________________
609 void AliMUONGeometryBuilder::SetAlign(Bool_t align)
611 /// Set the option for alignement
615 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
617 AliMUONVGeometryBuilder* builder
618 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
624 //_____________________________________________________________________________
625 void AliMUONGeometryBuilder::SetAlign(const TString& fileName, Bool_t align)
627 /// Set the option for alignement
629 fTransformFileName = fileName;
632 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
634 AliMUONVGeometryBuilder* builder
635 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);