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";
52 ClassImp(AliMUONGeometryBuilder)
57 //______________________________________________________________________________
58 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
61 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
63 if (m1.IsIdentity() && m2.IsIdentity()) return TGeoHMatrix();
65 if (m1.IsIdentity()) return m2;
67 if (m2.IsIdentity()) return m1;
72 //______________________________________________________________________________
73 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
77 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
79 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity())
82 if (m1.IsIdentity()) return Multiply(m2, m3);
84 if (m2.IsIdentity()) return Multiply(m1, m3);
86 if (m3.IsIdentity()) return Multiply(m1, m2);
91 //______________________________________________________________________________
92 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
97 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
99 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity() & m4.IsIdentity())
100 return TGeoHMatrix();
102 if (m1.IsIdentity()) return Multiply(m2, m3, m4);
104 if (m2.IsIdentity()) return Multiply(m1, m3, m4);
106 if (m3.IsIdentity()) return Multiply(m1, m2, m4);
108 if (m4.IsIdentity()) return Multiply(m1, m2, m3);
110 return m1 * m2 * m3 * m4;
113 //______________________________________________________________________________
114 AliMUONGeometryBuilder::AliMUONGeometryBuilder(AliModule* module)
118 fTransformFileName(fgkDefaultTransformFileName),
119 fSVMapFileName(fgkDefaultSVMapFileName),
120 fGlobalTransformation(),
121 fGeometryBuilders(0),
124 /// Standard constructor
126 fGeometryBuilders = new TObjArray();
127 fGeometryBuilders->SetOwner(true);
129 fGeometry = new AliMUONGeometry(true);
131 // Define the global transformation:
132 // Transformation from the old ALICE coordinate system to a new one:
134 TGeoRotation* rotGlobal
135 = new TGeoRotation("rotGlobal", 90., 180., 90., 90., 180., 0.);
136 fGlobalTransformation = TGeoCombiTrans(0., 0., 0., rotGlobal);
139 //______________________________________________________________________________
140 AliMUONGeometryBuilder::AliMUONGeometryBuilder()
144 fTransformFileName(),
146 fGlobalTransformation(),
147 fGeometryBuilders(0),
150 /// Default constructor
153 //______________________________________________________________________________
154 AliMUONGeometryBuilder::~AliMUONGeometryBuilder()
158 delete fGeometryBuilders;
166 //______________________________________________________________________________
167 void AliMUONGeometryBuilder::PlaceVolume(const TString& name, const TString& mName,
168 Int_t copyNo, const TGeoHMatrix& matrix,
169 Int_t npar, Double_t* param, const char* only,
170 Bool_t makeAssembly) const
172 /// Place the volume specified by name with the given transformation matrix
175 gGeoManager->MakeVolumeAssembly(name.Data());
177 TGeoHMatrix transform(matrix);
178 // Do not apply global transformation
179 // if mother volume was already placed in
180 // the new system of coordinates (that is MUON in negative Z)
181 // (as it is applied on the mother volume)
182 if (mName == TString("DDIP"))
183 transform = fGlobalTransformation.Inverse() * transform;
185 // Decompose transformation
186 const Double_t* xyz = transform.GetTranslation();
187 const Double_t* rm = transform.GetRotationMatrix();
189 //cout << "Got translation: "
190 // << xyz[0] << " " << xyz[1] << " " << xyz[2] << endl;
192 //cout << "Got rotation: "
193 // << rm[0] << " " << rm[1] << " " << rm[2] << endl
194 // << rm[3] << " " << rm[4] << " " << rm[5] << endl
195 // << rm[6] << " " << rm[7] << " " << rm[8] << endl;
197 // Check for presence of rotation
198 // (will be nice to be available in TGeo)
199 const Double_t kTolerance = 1e-04;
200 Bool_t isRotation = true;
201 if (TMath::Abs(rm[0] - 1.) < kTolerance &&
202 TMath::Abs(rm[1] - 0.) < kTolerance &&
203 TMath::Abs(rm[2] - 0.) < kTolerance &&
204 TMath::Abs(rm[3] - 0.) < kTolerance &&
205 TMath::Abs(rm[4] - 1.) < kTolerance &&
206 TMath::Abs(rm[5] - 0.) < kTolerance &&
207 TMath::Abs(rm[6] - 0.) < kTolerance &&
208 TMath::Abs(rm[7] - 0.) < kTolerance &&
209 TMath::Abs(rm[8] - 1.) < kTolerance) isRotation = false;
214 rot.SetMatrix(const_cast<Double_t*>(transform.GetRotationMatrix()));
215 Double_t theta1, phi1, theta2, phi2, theta3, phi3;
216 rot.GetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
219 // << theta1 << " " << phi1 << " "
220 // << theta2 << " " << phi2 << " "
221 // << theta3 << " " << phi3 << endl;
223 fModule->AliMatrix(krot, theta1, phi1, theta2, phi2, theta3, phi3);
228 gMC->Gspos(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only);
230 gMC->Gsposp(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only,
234 //______________________________________________________________________________
235 void AliMUONGeometryBuilder::CreateGeometryWithTGeo()
237 /// Construct geometry using geometry builders.
238 /// Virtual modules/envelopes are placed as TGeoVolume assembly
241 // Read transformations from ASCII data file
242 fGeometry->GetTransformer()
243 ->ReadGeometryData(fgkDefaultVolPathsFileName, fTransformFileName);
246 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
249 AliMUONVGeometryBuilder* builder
250 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
252 // Create geometry + envelopes
254 builder->CreateGeometry();
255 if (!fAlign) builder->SetTransformations();
257 // Place module volumes and envelopes
259 for (Int_t j=0; j<builder->NofGeometries(); j++) {
261 AliMUONGeometryModule* geometry = builder->Geometry(j);
262 AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
263 const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
264 TString volName = transformer->GetVolumeName();
265 TString motherVolName = transformer->GetMotherVolumeName();
267 // Place the module volume
268 PlaceVolume(volName, motherVolName,
269 1, *kModuleTransform, 0, 0, "ONLY", geometry->IsVirtual());
271 TGeoCombiTrans appliedGlobalTransform;
272 if (builder->ApplyGlobalTransformation())
273 appliedGlobalTransform = fGlobalTransformation;
275 // Loop over envelopes
276 const TObjArray* kEnvelopes
277 = geometry->GetEnvelopeStore()->GetEnvelopes();
278 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
281 AliMUONGeometryEnvelope* env
282 = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
284 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
285 const char* only = "ONLY";
286 if (env->IsMANY()) only = "MANY";
288 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
289 // virtual envelope + nof constituents = 0
291 // empty virtual envelope has no sense
292 AliFatal("Virtual envelope must have constituents.");
296 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
297 // non virtual envelope + nof constituents > 0
299 // use VMC to place constituents
300 AliFatal("Non virtual envelope cannot have constituents.");
304 // Place envelope in geometry module by composed transformation:
307 = Multiply( appliedGlobalTransform,
309 PlaceVolume(env->GetName(), volName,
310 env->GetCopyNo(), total, 0, 0, only, env->IsVirtual());
312 if ( env->IsVirtual() ) {
313 // Place constituents in the envelope
314 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
315 AliMUONGeometryConstituent* constituent
316 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
318 PlaceVolume(constituent->GetName(), env->GetName(),
319 constituent->GetCopyNo(),
320 *constituent->GetTransformation() ,
321 constituent->GetNpar(), constituent->GetParam(), only);
324 } // end of loop over envelopes
325 } // end of loop over builder geometries
326 } // end of loop over builders
329 //______________________________________________________________________________
330 void AliMUONGeometryBuilder::CreateGeometryWithoutTGeo()
332 /// Construct geometry using geometry builders.
333 /// Virtual modules/envelopes are not placed
336 // Read transformations from ASCII data file
337 fGeometry->GetTransformer()
338 ->ReadGeometryData(fgkDefaultVolPathsFileName, fTransformFileName);
341 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
344 AliMUONVGeometryBuilder* builder
345 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
347 // Create geometry + envelopes
349 builder->CreateGeometry();
350 if (!fAlign) builder->SetTransformations();
352 // Place module volumes and envelopes
354 for (Int_t j=0; j<builder->NofGeometries(); j++) {
356 AliMUONGeometryModule* geometry = builder->Geometry(j);
357 AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
358 const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
359 TString volName = transformer->GetVolumeName();
360 TString motherVolName = transformer->GetMotherVolumeName();
362 // Place the module volume
363 if ( !geometry->IsVirtual() ) {
364 PlaceVolume(volName, motherVolName,
365 1, *kModuleTransform, 0, 0, "ONLY");
368 TGeoCombiTrans appliedGlobalTransform;
369 if (builder->ApplyGlobalTransformation())
370 appliedGlobalTransform = fGlobalTransformation;
372 // Loop over envelopes
373 const TObjArray* kEnvelopes
374 = geometry->GetEnvelopeStore()->GetEnvelopes();
375 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
378 AliMUONGeometryEnvelope* env
379 = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
381 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
382 const char* only = "ONLY";
383 if (env->IsMANY()) only = "MANY";
385 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
386 // virtual envelope + nof constituents = 0
388 // empty virtual envelope has no sense
389 AliFatal("Virtual envelope must have constituents.");
393 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
394 // non virtual envelope + nof constituents > 0
396 // use VMC to place constituents
397 AliFatal("Non virtual envelope cannot have constituents.");
401 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
402 // non virtual envelope + nof constituents = 0
403 // => place envelope by composed transformation:
404 // Tch * [Tglobal] * Tenv
406 // Compound chamber transformation with the envelope one
407 if (geometry->IsVirtual()) {
409 = Multiply( (*kModuleTransform),
410 appliedGlobalTransform,
412 PlaceVolume(env->GetName(), motherVolName,
413 env->GetCopyNo(), total, 0, 0, only);
417 = Multiply( appliedGlobalTransform,
419 PlaceVolume(env->GetName(), volName,
420 env->GetCopyNo(), total, 0, 0, only);
424 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
425 // virtual envelope + nof constituents > 0
426 // => do not place envelope and place constituents
427 // by composed transformation:
428 // Tch * [Tglobal] * Tenv * Tconst
430 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
431 AliMUONGeometryConstituent* constituent
432 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
434 // Compound chamber transformation with the envelope one + the constituent one
435 if (geometry->IsVirtual()) {
437 = Multiply ( (*kModuleTransform),
438 appliedGlobalTransform,
440 (*constituent->GetTransformation()) );
442 PlaceVolume(constituent->GetName(), motherVolName,
443 constituent->GetCopyNo(), total,
444 constituent->GetNpar(), constituent->GetParam(), only);
448 = Multiply ( appliedGlobalTransform,
450 (*constituent->GetTransformation()) );
452 PlaceVolume(constituent->GetName(), volName,
453 constituent->GetCopyNo(), total,
454 constituent->GetNpar(), constituent->GetParam(), only);
458 } // end of loop over envelopes
459 } // end of loop over builder geometries
460 } // end of loop over builders
463 //_____________________________________________________________________________
464 void AliMUONGeometryBuilder::SetAlign(AliMUONVGeometryBuilder* builder)
466 /// Set align option to all geometry modules associated with the builder
468 for (Int_t j=0; j<builder->NofGeometries(); j++) {
470 AliMUONGeometryModule* geometry = builder->Geometry(j);
472 geometry->SetAlign(fAlign);
480 //_____________________________________________________________________________
481 void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
483 /// Add the geometry builder to the list
485 fGeometryBuilders->Add(geomBuilder);
487 // Pass geometry modules created in the to the geometry parametrisation
488 for (Int_t i=0; i<geomBuilder->NofGeometries(); i++) {
489 fGeometry->AddModule(geomBuilder->Geometry(i));
492 if (geomBuilder->ApplyGlobalTransformation())
493 geomBuilder->SetReferenceFrame(fGlobalTransformation);
495 SetAlign(geomBuilder);
498 //______________________________________________________________________________
499 void AliMUONGeometryBuilder::CreateGeometry()
501 /// Construct geometry using geometry builders.
503 if ( gMC->IsRootGeometrySupported() &&
504 TString(gMC->ClassName()) != "TGeant4" ) {
506 CreateGeometryWithTGeo();
509 CreateGeometryWithoutTGeo();
512 //_____________________________________________________________________________
513 void AliMUONGeometryBuilder::CreateMaterials()
515 /// Construct materials specific to modules via builders
517 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
520 AliMUONVGeometryBuilder* builder
521 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
523 // Create materials with each builder
524 if (builder) builder->CreateMaterials();
528 //______________________________________________________________________________
529 void AliMUONGeometryBuilder::InitGeometry(const TString& svmapFileName)
531 /// Initialize geometry
533 // Load alignement data from geometry if geometry is read from Root file
534 if ( gAlice->IsRootGeometry() ) {
537 fGeometry->GetTransformer()
538 ->ReadGeometryData(fgkDefaultVolPathsFileName, gGeoManager);
541 // Read sensitive volume map from a file
542 fGeometry->ReadSVMap(svmapFileName);
544 // Set the chamber (sensitive region) GEANT identifier
546 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
549 AliMUONVGeometryBuilder* builder
550 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
552 // Set sensitive volumes with each builder
553 builder->SetSensitiveVolumes();
556 // Create detection elements from built geometry
557 builder->CreateDetElements();
562 //______________________________________________________________________________
563 void AliMUONGeometryBuilder::WriteSVMaps(const TString& fileName,
566 /// Write sensitive volume maps into files per builder
571 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
573 AliMUONVGeometryBuilder* builder
574 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
576 Bool_t writeEnvelopes = false;
577 if ( gMC->IsRootGeometrySupported() &&
578 TString(gMC->ClassName()) != "TGeant4") writeEnvelopes = true;
580 builder->RebuildSVMaps(writeEnvelopes);
583 // Write maps in file
584 fGeometry->WriteSVMap(fileName);
587 //_____________________________________________________________________________
588 void AliMUONGeometryBuilder::SetAlign(Bool_t align)
590 /// Set the option for alignement
594 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
596 AliMUONVGeometryBuilder* builder
597 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
603 //_____________________________________________________________________________
604 void AliMUONGeometryBuilder::SetAlign(const TString& fileName, Bool_t align)
606 /// Set the option for alignement and the transformations file name
608 fTransformFileName = fileName;
611 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
613 AliMUONVGeometryBuilder* builder
614 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);