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 // Class AliMUONGeometryBuilder
19 // ----------------------------
20 // Manager class for geometry construction via geometry builders.
22 // Author: Ivana Hrivnacova, IPN Orsay
24 #include <TObjArray.h>
25 #include <TVirtualMC.h>
27 #include "AliMUONGeometryBuilder.h"
28 #include "AliMUONVGeometryBuilder.h"
29 #include "AliMUONGeometry.h"
30 #include "AliMUONGeometryTransformer.h"
31 #include "AliMUONGeometryModule.h"
32 #include "AliMUONGeometryModuleTransformer.h"
33 #include "AliMUONGeometryEnvelope.h"
34 #include "AliMUONGeometryEnvelopeStore.h"
35 #include "AliMUONGeometryDetElement.h"
36 #include "AliMUONGeometryStore.h"
37 #include "AliMUONGeometryConstituent.h"
38 #include "AliModule.h"
43 ClassImp(AliMUONGeometryBuilder)
45 // static data members
47 const TString AliMUONGeometryBuilder::fgkDefaultTransformFileName = "transform.dat";
48 const TString AliMUONGeometryBuilder::fgkDefaultSVMapFileName = "svmap.dat";
49 const TString AliMUONGeometryBuilder::fgkOutFileNameExtension = ".out";
53 //______________________________________________________________________________
54 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
57 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
59 if (m1.IsIdentity() && m2.IsIdentity()) return TGeoHMatrix();
61 if (m1.IsIdentity()) return m2;
63 if (m2.IsIdentity()) return m1;
68 //______________________________________________________________________________
69 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
73 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
75 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity())
78 if (m1.IsIdentity()) return Multiply(m2, m3);
80 if (m2.IsIdentity()) return Multiply(m1, m3);
82 if (m3.IsIdentity()) return Multiply(m1, m2);
87 //______________________________________________________________________________
88 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
93 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
95 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity() & m4.IsIdentity())
98 if (m1.IsIdentity()) return Multiply(m2, m3, m4);
100 if (m2.IsIdentity()) return Multiply(m1, m3, m4);
102 if (m3.IsIdentity()) return Multiply(m1, m2, m4);
104 if (m4.IsIdentity()) return Multiply(m1, m2, m3);
106 return m1 * m2 * m3 * m4;
109 //______________________________________________________________________________
110 AliMUONGeometryBuilder::AliMUONGeometryBuilder(AliModule* module)
114 fTransformFileName(fgkDefaultTransformFileName),
115 fSVMapFileName(fgkDefaultSVMapFileName),
116 fGlobalTransformation(),
117 fGeometryBuilders(0),
120 /// Standard constructor
122 fGeometryBuilders = new TObjArray();
123 fGeometryBuilders->SetOwner(true);
125 fGeometry = new AliMUONGeometry(true);
127 // Define the global transformation:
128 // Transformation from the old ALICE coordinate system to a new one:
130 TGeoRotation* rotGlobal
131 = new TGeoRotation("rotGlobal", 90., 180., 90., 90., 180., 0.);
132 fGlobalTransformation = TGeoCombiTrans(0., 0., 0., rotGlobal);
135 //______________________________________________________________________________
136 AliMUONGeometryBuilder::AliMUONGeometryBuilder()
140 fTransformFileName(),
142 fGlobalTransformation(),
143 fGeometryBuilders(0),
146 /// Default constructor
149 //______________________________________________________________________________
150 AliMUONGeometryBuilder::AliMUONGeometryBuilder(const AliMUONGeometryBuilder& right)
153 /// Copy constructor (not implemented)
155 AliFatal("Copy constructor not provided.");
158 //______________________________________________________________________________
159 AliMUONGeometryBuilder::~AliMUONGeometryBuilder()
163 delete fGeometryBuilders;
167 //______________________________________________________________________________
168 AliMUONGeometryBuilder&
169 AliMUONGeometryBuilder::operator=(const AliMUONGeometryBuilder& right)
171 /// Assignement operator (not implemented)
173 // check assignement to self
174 if (this == &right) return *this;
176 AliFatal("Assignement operator not provided.");
185 //______________________________________________________________________________
186 void AliMUONGeometryBuilder::PlaceVolume(const TString& name, const TString& mName,
187 Int_t copyNo, const TGeoHMatrix& matrix,
188 Int_t npar, Double_t* param, const char* only) const
190 /// Place the volume specified by name with the given transformation matrix
192 TGeoHMatrix transform(matrix);
193 // Do not apply global transformation
194 // if mother volume was already placed in
195 // the new system of coordinates (that is MUON in negative Z)
196 // (as it is applied on the mother volume)
197 if (mName == TString("DDIP"))
198 transform = fGlobalTransformation.Inverse() * transform;
200 // Decompose transformation
201 const Double_t* xyz = transform.GetTranslation();
202 const Double_t* rm = transform.GetRotationMatrix();
204 //cout << "Got translation: "
205 // << xyz[0] << " " << xyz[1] << " " << xyz[2] << endl;
207 //cout << "Got rotation: "
208 // << rm[0] << " " << rm[1] << " " << rm[2] << endl
209 // << rm[3] << " " << rm[4] << " " << rm[5] << endl
210 // << rm[6] << " " << rm[7] << " " << rm[8] << endl;
212 // Check for presence of rotation
213 // (will be nice to be available in TGeo)
214 const Double_t kTolerance = 1e-04;
215 Bool_t isRotation = true;
216 if (TMath::Abs(rm[0] - 1.) < kTolerance &&
217 TMath::Abs(rm[1] - 0.) < kTolerance &&
218 TMath::Abs(rm[2] - 0.) < kTolerance &&
219 TMath::Abs(rm[3] - 0.) < kTolerance &&
220 TMath::Abs(rm[4] - 1.) < kTolerance &&
221 TMath::Abs(rm[5] - 0.) < kTolerance &&
222 TMath::Abs(rm[6] - 0.) < kTolerance &&
223 TMath::Abs(rm[7] - 0.) < kTolerance &&
224 TMath::Abs(rm[8] - 1.) < kTolerance) isRotation = false;
229 rot.SetMatrix(const_cast<Double_t*>(transform.GetRotationMatrix()));
230 Double_t theta1, phi1, theta2, phi2, theta3, phi3;
231 rot.GetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
234 // << theta1 << " " << phi1 << " "
235 // << theta2 << " " << phi2 << " "
236 // << theta3 << " " << phi3 << endl;
238 fModule->AliMatrix(krot, theta1, phi1, theta2, phi2, theta3, phi3);
241 // Place the volume in ALIC
243 gMC->Gspos(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only);
245 gMC->Gsposp(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only,
250 //_____________________________________________________________________________
251 void AliMUONGeometryBuilder::SetAlign(AliMUONVGeometryBuilder* builder)
253 /// Set align option to all geometry modules associated with the builder
255 for (Int_t j=0; j<builder->NofGeometries(); j++) {
257 AliMUONGeometryModule* geometry = builder->Geometry(j);
259 geometry->SetAlign(fAlign);
267 //_____________________________________________________________________________
268 void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
270 /// Add the geometry builder to the list
272 fGeometryBuilders->Add(geomBuilder);
274 // Pass geometry modules created in the to the geometry parametrisation
275 for (Int_t i=0; i<geomBuilder->NofGeometries(); i++) {
276 fGeometry->AddModule(geomBuilder->Geometry(i));
279 if (geomBuilder->ApplyGlobalTransformation())
280 geomBuilder->SetReferenceFrame(fGlobalTransformation);
282 SetAlign(geomBuilder);
285 //______________________________________________________________________________
286 void AliMUONGeometryBuilder::CreateGeometry()
288 /// Construct geometry using geometry builders.
290 if (fAlign) ReadTransformations();
292 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
295 AliMUONVGeometryBuilder* builder
296 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
298 // Create geometry + envelopes
300 builder->CreateGeometry();
301 if (!fAlign) builder->SetTransformations();
303 // Place module volumes and envelopes
305 for (Int_t j=0; j<builder->NofGeometries(); j++) {
307 AliMUONGeometryModule* geometry = builder->Geometry(j);
308 const TGeoCombiTrans* kModuleTransform
309 = geometry->GetTransformer()->GetTransformation();
311 // Place the module volume
312 if ( !geometry->IsVirtual() ) {
313 PlaceVolume(geometry->GetVolume(), geometry->GetMotherVolume(),
314 1, *kModuleTransform, 0, 0, "ONLY");
317 TGeoCombiTrans appliedGlobalTransform;
318 if (builder->ApplyGlobalTransformation())
319 appliedGlobalTransform = fGlobalTransformation;
321 // Loop over envelopes
322 const TObjArray* kEnvelopes
323 = geometry->GetEnvelopeStore()->GetEnvelopes();
324 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
327 AliMUONGeometryEnvelope* env
328 = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
330 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
331 const char* only = "ONLY";
332 if (env->IsMANY()) only = "MANY";
334 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
335 // virtual envelope + nof constituents = 0
337 // empty virtual envelope has no sense
338 AliFatal("Virtual envelope must have constituents.");
342 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
343 // non virtual envelope + nof constituents > 0
345 // use VMC to place constituents
346 AliFatal("Non virtual envelope cannot have constituents.");
350 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
351 // non virtual envelope + nof constituents = 0
352 // => place envelope in ALICE by composed transformation:
353 // Tch * [Tglobal] * Tenv
355 // Compound chamber transformation with the envelope one
356 if (geometry->IsVirtual()) {
358 = Multiply( (*kModuleTransform),
359 appliedGlobalTransform,
361 PlaceVolume(env->GetName(), geometry->GetMotherVolume(),
362 env->GetCopyNo(), total, 0, 0, only);
366 = Multiply( appliedGlobalTransform,
368 PlaceVolume(env->GetName(), geometry->GetVolume(),
369 env->GetCopyNo(), total, 0, 0, only);
373 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
374 // virtual envelope + nof constituents > 0
375 // => do not place envelope and place constituents
376 // in ALICE by composed transformation:
377 // Tch * [Tglobal] * Tenv * Tconst
379 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
380 AliMUONGeometryConstituent* constituent
381 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
383 // Compound chamber transformation with the envelope one + the constituent one
384 if (geometry->IsVirtual()) {
386 = Multiply ( (*kModuleTransform),
387 appliedGlobalTransform,
389 (*constituent->GetTransformation()) );
391 PlaceVolume(constituent->GetName(), geometry->GetMotherVolume(),
392 constituent->GetCopyNo(), total,
393 constituent->GetNpar(), constituent->GetParam(), only);
397 = Multiply ( appliedGlobalTransform,
399 (*constituent->GetTransformation()) );
401 PlaceVolume(constituent->GetName(), geometry->GetVolume(),
402 constituent->GetCopyNo(), total,
403 constituent->GetNpar(), constituent->GetParam(), only);
407 } // end of loop over envelopes
408 } // end of loop over builder geometries
409 } // end of loop over builders
412 //_____________________________________________________________________________
413 void AliMUONGeometryBuilder::CreateMaterials()
415 /// Construct materials specific to modules via builders
417 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
420 AliMUONVGeometryBuilder* builder
421 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
423 // Create materials with each builder
424 if (builder) builder->CreateMaterials();
428 //______________________________________________________________________________
429 void AliMUONGeometryBuilder::InitGeometry(const TString& svmapFileName)
431 /// Initialize geometry
433 // Read alignement data if geometry is read from Root file
434 if ( gAlice->IsRootGeometry() ) {
436 ReadTransformations();
439 // Read sensitive volume map from a file
440 fGeometry->ReadSVMap(svmapFileName);
442 // Set the chamber (sensitive region) GEANT identifier
444 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
447 AliMUONVGeometryBuilder* builder
448 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
450 // Set sensitive volumes with each builder
451 builder->SetSensitiveVolumes();
454 // Fill local transformations from built geometry
455 builder->FillTransformations();
462 //______________________________________________________________________________
463 void AliMUONGeometryBuilder::ReadTransformations(const TString& fileName)
465 /// Read transformations from ASCII files
466 /// and store them in the geometry parametrisation
468 // Read transformations
470 AliMUONGeometryTransformer* geomTransformer = fGeometry->GetTransformer();
471 geomTransformer->ReadTransformations(fileName);
474 //______________________________________________________________________________
475 void AliMUONGeometryBuilder::WriteTransformations(const TString& fileName)
477 /// Write transformations into files per builder
479 AliMUONGeometryTransformer* geomTransformer = fGeometry->GetTransformer();
480 geomTransformer->WriteTransformations(fileName);
483 //______________________________________________________________________________
484 void AliMUONGeometryBuilder::WriteSVMaps(const TString& fileName,
487 /// Write sensitive volume maps into files per builder
492 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
494 AliMUONVGeometryBuilder* builder
495 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
497 builder->RebuildSVMaps();
500 // Write maps in file
501 fGeometry->WriteSVMap(fileName);
504 //_____________________________________________________________________________
505 void AliMUONGeometryBuilder::SetAlign(Bool_t align)
507 /// Set the option for alignement
511 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
513 AliMUONVGeometryBuilder* builder
514 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
520 //_____________________________________________________________________________
521 void AliMUONGeometryBuilder::SetAlign(const TString& fileName, Bool_t align)
523 /// Set the option for alignement
525 fTransformFileName = fileName;
528 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
530 AliMUONVGeometryBuilder* builder
531 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);