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"
42 #include <TObjArray.h>
43 #include <TVirtualMC.h>
44 #include <TGeoManager.h>
46 // static data members
48 const TString AliMUONGeometryBuilder::fgkDefaultVolPathsFileName = "volpath.dat";
49 const TString AliMUONGeometryBuilder::fgkDefaultTransformFileName = "transform.dat";
50 const TString AliMUONGeometryBuilder::fgkDefaultSVMapFileName = "svmap.dat";
51 const TString AliMUONGeometryBuilder::fgkOutFileNameExtension = ".out";
54 ClassImp(AliMUONGeometryBuilder)
59 //______________________________________________________________________________
60 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
63 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
65 if (m1.IsIdentity() && m2.IsIdentity()) return TGeoHMatrix();
67 if (m1.IsIdentity()) return m2;
69 if (m2.IsIdentity()) return m1;
74 //______________________________________________________________________________
75 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
79 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
81 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity())
84 if (m1.IsIdentity()) return Multiply(m2, m3);
86 if (m2.IsIdentity()) return Multiply(m1, m3);
88 if (m3.IsIdentity()) return Multiply(m1, m2);
93 //______________________________________________________________________________
94 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
99 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
101 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity() & m4.IsIdentity())
102 return TGeoHMatrix();
104 if (m1.IsIdentity()) return Multiply(m2, m3, m4);
106 if (m2.IsIdentity()) return Multiply(m1, m3, m4);
108 if (m3.IsIdentity()) return Multiply(m1, m2, m4);
110 if (m4.IsIdentity()) return Multiply(m1, m2, m3);
112 return m1 * m2 * m3 * m4;
115 //______________________________________________________________________________
116 AliMUONGeometryBuilder::AliMUONGeometryBuilder(AliModule* module)
120 fTransformFileName(fgkDefaultTransformFileName),
121 fSVMapFileName(fgkDefaultSVMapFileName),
122 fGlobalTransformation(),
123 fGeometryBuilders(0),
126 /// Standard constructor
128 fGeometryBuilders = new TObjArray();
129 fGeometryBuilders->SetOwner(true);
131 fGeometry = new AliMUONGeometry(true);
133 // Define the global transformation:
134 // Transformation from the old ALICE coordinate system to a new one:
136 TGeoRotation* rotGlobal
137 = new TGeoRotation("rotGlobal", 90., 180., 90., 90., 180., 0.);
138 fGlobalTransformation = TGeoCombiTrans(0., 0., 0., rotGlobal);
141 //______________________________________________________________________________
142 AliMUONGeometryBuilder::AliMUONGeometryBuilder()
146 fTransformFileName(),
148 fGlobalTransformation(),
149 fGeometryBuilders(0),
152 /// Default constructor
155 //______________________________________________________________________________
156 AliMUONGeometryBuilder::~AliMUONGeometryBuilder()
160 delete fGeometryBuilders;
168 //______________________________________________________________________________
169 void AliMUONGeometryBuilder::PlaceVolume(const TString& name, const TString& mName,
170 Int_t copyNo, const TGeoHMatrix& matrix,
171 Int_t npar, Double_t* param, const char* only,
172 Bool_t makeAssembly) const
174 /// Place the volume specified by name with the given transformation matrix
177 gGeoManager->MakeVolumeAssembly(name.Data());
179 TGeoHMatrix transform(matrix);
180 // Do not apply global transformation
181 // if mother volume was already placed in
182 // the new system of coordinates (that is MUON in negative Z)
183 // (as it is applied on the mother volume)
184 if (mName == TString("DDIP"))
185 transform = fGlobalTransformation.Inverse() * transform;
187 // Decompose transformation
188 const Double_t* xyz = transform.GetTranslation();
189 const Double_t* rm = transform.GetRotationMatrix();
191 //cout << "Got translation: "
192 // << xyz[0] << " " << xyz[1] << " " << xyz[2] << endl;
194 //cout << "Got rotation: "
195 // << rm[0] << " " << rm[1] << " " << rm[2] << endl
196 // << rm[3] << " " << rm[4] << " " << rm[5] << endl
197 // << rm[6] << " " << rm[7] << " " << rm[8] << endl;
199 // Check for presence of rotation
200 // (will be nice to be available in TGeo)
201 const Double_t kTolerance = 1e-04;
202 Bool_t isRotation = true;
203 if (TMath::Abs(rm[0] - 1.) < kTolerance &&
204 TMath::Abs(rm[1] - 0.) < kTolerance &&
205 TMath::Abs(rm[2] - 0.) < kTolerance &&
206 TMath::Abs(rm[3] - 0.) < kTolerance &&
207 TMath::Abs(rm[4] - 1.) < kTolerance &&
208 TMath::Abs(rm[5] - 0.) < kTolerance &&
209 TMath::Abs(rm[6] - 0.) < kTolerance &&
210 TMath::Abs(rm[7] - 0.) < kTolerance &&
211 TMath::Abs(rm[8] - 1.) < kTolerance) isRotation = false;
216 rot.SetMatrix(const_cast<Double_t*>(transform.GetRotationMatrix()));
217 Double_t theta1, phi1, theta2, phi2, theta3, phi3;
218 rot.GetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
221 // << theta1 << " " << phi1 << " "
222 // << theta2 << " " << phi2 << " "
223 // << theta3 << " " << phi3 << endl;
225 fModule->AliMatrix(krot, theta1, phi1, theta2, phi2, theta3, phi3);
230 gMC->Gspos(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only);
232 gMC->Gsposp(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only,
236 //______________________________________________________________________________
237 void AliMUONGeometryBuilder::CreateGeometryWithTGeo()
239 /// Construct geometry using geometry builders.
240 /// Virtual modules/envelopes are placed as TGeoVolume assembly
243 // Read transformations from ASCII data file
244 fGeometry->GetTransformer()
245 ->LoadGeometryData(fTransformFileName);
248 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
251 AliMUONVGeometryBuilder* builder
252 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
254 // Create geometry + envelopes
256 builder->CreateGeometry();
257 builder->SetVolumes();
258 if (!fAlign) builder->SetTransformations();
260 // Place module volumes and envelopes
262 for (Int_t j=0; j<builder->NofGeometries(); j++) {
264 AliMUONGeometryModule* geometry = builder->Geometry(j);
265 AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
266 const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
267 TString volName = transformer->GetVolumeName();
268 TString motherVolName = transformer->GetMotherVolumeName();
270 // Place the module volume
271 PlaceVolume(volName, motherVolName,
272 1, *kModuleTransform, 0, 0, "ONLY", geometry->IsVirtual());
274 TGeoCombiTrans appliedGlobalTransform;
275 if (builder->ApplyGlobalTransformation())
276 appliedGlobalTransform = fGlobalTransformation;
278 // Loop over envelopes
279 const TObjArray* kEnvelopes
280 = geometry->GetEnvelopeStore()->GetEnvelopes();
281 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
284 AliMUONGeometryEnvelope* env
285 = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
287 // Check consistency of detElemId and module Id
288 if ( env->GetUniqueID() > 0 &&
289 AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
290 != geometry->GetModuleId() ) {
293 << "Detection element " << env->GetUniqueID()
294 << " is being placed in geometry module " << geometry->GetModuleId()
295 << " but should go in "
296 << AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
298 AliFatal("Inconsistent IDs");
301 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
302 const char* only = "ONLY";
303 if (env->IsMANY()) only = "MANY";
305 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
306 // virtual envelope + nof constituents = 0
308 // empty virtual envelope has no sense
309 AliFatal("Virtual envelope must have constituents.");
313 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
314 // non virtual envelope + nof constituents > 0
316 // use VMC to place constituents
317 AliFatal("Non virtual envelope cannot have constituents.");
321 // Place envelope in geometry module by composed transformation:
324 = Multiply( appliedGlobalTransform,
326 PlaceVolume(env->GetName(), volName,
327 env->GetCopyNo(), total, 0, 0, only, env->IsVirtual());
329 if ( env->IsVirtual() ) {
330 // Place constituents in the envelope
331 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
332 AliMUONGeometryConstituent* constituent
333 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
335 PlaceVolume(constituent->GetName(), env->GetName(),
336 constituent->GetCopyNo(),
337 *constituent->GetTransformation() ,
338 constituent->GetNpar(), constituent->GetParam(), only);
341 } // end of loop over envelopes
342 } // end of loop over builder geometries
343 } // end of loop over builders
346 //______________________________________________________________________________
347 void AliMUONGeometryBuilder::CreateGeometryWithoutTGeo()
349 /// Construct geometry using geometry builders.
350 /// Virtual modules/envelopes are not placed
353 // Read transformations from ASCII data file
354 fGeometry->GetTransformer()->LoadGeometryData(fTransformFileName);
357 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
360 AliMUONVGeometryBuilder* builder
361 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
363 // Create geometry + envelopes
365 builder->CreateGeometry();
366 if (!fAlign) builder->SetTransformations();
368 // Place module volumes and envelopes
370 for (Int_t j=0; j<builder->NofGeometries(); j++) {
372 AliMUONGeometryModule* geometry = builder->Geometry(j);
373 AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
374 const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
375 TString volName = transformer->GetVolumeName();
376 TString motherVolName = transformer->GetMotherVolumeName();
378 // Place the module volume
379 if ( !geometry->IsVirtual() ) {
380 PlaceVolume(volName, motherVolName,
381 1, *kModuleTransform, 0, 0, "ONLY");
384 TGeoCombiTrans appliedGlobalTransform;
385 if (builder->ApplyGlobalTransformation())
386 appliedGlobalTransform = fGlobalTransformation;
388 // Loop over envelopes
389 const TObjArray* kEnvelopes
390 = geometry->GetEnvelopeStore()->GetEnvelopes();
391 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
394 AliMUONGeometryEnvelope* env
395 = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
397 // Check consistency of detElemId and module Id
398 if ( env->GetUniqueID() > 0 &&
399 AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
400 != geometry->GetModuleId() ) {
403 << "Detection element " << env->GetUniqueID()
404 << " is being placed in geometry module " << geometry->GetModuleId()
405 << " but should go in "
406 << AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
408 AliFatal("Inconsistent IDs");
411 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
412 const char* only = "ONLY";
413 if (env->IsMANY()) only = "MANY";
415 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
416 // virtual envelope + nof constituents = 0
418 // empty virtual envelope has no sense
419 AliFatal("Virtual envelope must have constituents.");
423 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
424 // non virtual envelope + nof constituents > 0
426 // use VMC to place constituents
427 AliFatal("Non virtual envelope cannot have constituents.");
431 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
432 // non virtual envelope + nof constituents = 0
433 // => place envelope by composed transformation:
434 // Tch * [Tglobal] * Tenv
436 // Compound chamber transformation with the envelope one
437 if (geometry->IsVirtual()) {
439 = Multiply( (*kModuleTransform),
440 appliedGlobalTransform,
442 PlaceVolume(env->GetName(), motherVolName,
443 env->GetCopyNo(), total, 0, 0, only);
447 = Multiply( appliedGlobalTransform,
449 PlaceVolume(env->GetName(), volName,
450 env->GetCopyNo(), total, 0, 0, only);
454 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
455 // virtual envelope + nof constituents > 0
456 // => do not place envelope and place constituents
457 // by composed transformation:
458 // Tch * [Tglobal] * Tenv * Tconst
460 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
461 AliMUONGeometryConstituent* constituent
462 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
464 // Compound chamber transformation with the envelope one + the constituent one
465 if (geometry->IsVirtual()) {
467 = Multiply ( (*kModuleTransform),
468 appliedGlobalTransform,
470 (*constituent->GetTransformation()) );
472 PlaceVolume(constituent->GetName(), motherVolName,
473 constituent->GetCopyNo(), total,
474 constituent->GetNpar(), constituent->GetParam(), only);
478 = Multiply ( appliedGlobalTransform,
480 (*constituent->GetTransformation()) );
482 PlaceVolume(constituent->GetName(), volName,
483 constituent->GetCopyNo(), total,
484 constituent->GetNpar(), constituent->GetParam(), only);
488 } // end of loop over envelopes
489 } // end of loop over builder geometries
490 } // end of loop over builders
493 //_____________________________________________________________________________
494 void AliMUONGeometryBuilder::SetAlign(AliMUONVGeometryBuilder* builder)
496 /// Set align option to all geometry modules associated with the builder
498 for (Int_t j=0; j<builder->NofGeometries(); j++) {
500 AliMUONGeometryModule* geometry = builder->Geometry(j);
502 geometry->SetAlign(fAlign);
510 //_____________________________________________________________________________
511 void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
513 /// Add the geometry builder to the list
515 fGeometryBuilders->Add(geomBuilder);
517 // Pass geometry modules created in the to the geometry parametrisation
518 for (Int_t i=0; i<geomBuilder->NofGeometries(); i++) {
519 fGeometry->AddModule(geomBuilder->Geometry(i));
522 if (geomBuilder->ApplyGlobalTransformation())
523 geomBuilder->SetReferenceFrame(fGlobalTransformation);
525 SetAlign(geomBuilder);
528 //______________________________________________________________________________
529 void AliMUONGeometryBuilder::CreateGeometry()
531 /// Construct geometry using geometry builders.
533 if ( gMC->IsRootGeometrySupported() ) {
535 CreateGeometryWithTGeo();
538 CreateGeometryWithoutTGeo();
540 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
543 AliMUONVGeometryBuilder* builder
544 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
546 // Update detection elements from built geometry
547 Bool_t create = ! fAlign;
548 builder->UpdateDetElements(create);
552 //_____________________________________________________________________________
553 void AliMUONGeometryBuilder::CreateMaterials()
555 /// Construct materials specific to modules via builders
557 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
560 AliMUONVGeometryBuilder* builder
561 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
563 // Create materials with each builder
564 if (builder) builder->CreateMaterials();
568 //______________________________________________________________________________
569 void AliMUONGeometryBuilder::InitGeometry(const TString& svmapFileName)
571 /// Initialize geometry
573 // Load alignement data from geometry if geometry is read from Root file
574 if ( gAlice->IsRootGeometry() ) {
576 fGeometry->GetTransformer()->LoadGeometryData();
579 // Read sensitive volume map from a file
580 fGeometry->ReadSVMap(svmapFileName);
582 // Set the chamber (sensitive region) GEANT identifier
584 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
587 AliMUONVGeometryBuilder* builder
588 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
590 // Set sensitive volumes with each builder
591 builder->SetSensitiveVolumes();
595 //________________________________________________________________
596 void AliMUONGeometryBuilder::UpdateInternalGeometry()
598 /// Update geometry after applying mis-alignment:
599 /// reload transformations in geometry builder.
601 fGeometry->GetTransformer()->LoadTransformations();
604 //______________________________________________________________________________
605 void AliMUONGeometryBuilder::WriteSVMaps(const TString& fileName,
606 Bool_t rebuild, Bool_t writeEnvelopes)
608 /// Write sensitive volume maps into files per builder
613 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
615 AliMUONVGeometryBuilder* builder
616 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
618 builder->RebuildSVMaps(writeEnvelopes);
621 // Write maps in file
622 fGeometry->WriteSVMap(fileName);
625 //_____________________________________________________________________________
626 void AliMUONGeometryBuilder::SetAlign(Bool_t align)
628 /// Set the option for alignement
632 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
634 AliMUONVGeometryBuilder* builder
635 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
641 //_____________________________________________________________________________
642 void AliMUONGeometryBuilder::SetAlign(const TString& fileName, Bool_t align)
644 /// Set the option for alignement and the transformations file name
646 fTransformFileName = fileName;
649 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
651 AliMUONVGeometryBuilder* builder
652 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);