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 "AliMUONGeometryModule.h"
30 #include "AliMUONGeometryEnvelope.h"
31 #include "AliMUONGeometryEnvelopeStore.h"
32 #include "AliMUONGeometryDetElement.h"
33 #include "AliMUONGeometryStore.h"
34 #include "AliMUONGeometryConstituent.h"
35 #include "AliModule.h"
40 ClassImp(AliMUONGeometryBuilder)
44 //______________________________________________________________________________
45 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
48 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
50 if (m1.IsIdentity() && m2.IsIdentity()) return TGeoHMatrix();
52 if (m1.IsIdentity()) return m2;
54 if (m2.IsIdentity()) return m1;
59 //______________________________________________________________________________
60 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() & m3.IsIdentity())
69 if (m1.IsIdentity()) return Multiply(m2, m3);
71 if (m2.IsIdentity()) return Multiply(m1, m3);
73 if (m3.IsIdentity()) return Multiply(m1, m2);
78 //______________________________________________________________________________
79 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
84 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
86 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity() & m4.IsIdentity())
89 if (m1.IsIdentity()) return Multiply(m2, m3, m4);
91 if (m2.IsIdentity()) return Multiply(m1, m3, m4);
93 if (m3.IsIdentity()) return Multiply(m1, m2, m4);
95 if (m4.IsIdentity()) return Multiply(m1, m2, m3);
97 return m1 * m2 * m3 * m4;
100 //______________________________________________________________________________
101 AliMUONGeometryBuilder::AliMUONGeometryBuilder(AliModule* module)
105 fGlobalTransformation(),
108 /// Standard constructor
110 fGeometryBuilders = new TObjArray(100);
113 //______________________________________________________________________________
114 AliMUONGeometryBuilder::AliMUONGeometryBuilder()
118 fGlobalTransformation(),
121 /// Default constructor
124 //______________________________________________________________________________
125 AliMUONGeometryBuilder::AliMUONGeometryBuilder(const AliMUONGeometryBuilder& right)
128 /// Copy constructor (not implemented)
130 AliFatal("Copy constructor not provided.");
133 //______________________________________________________________________________
134 AliMUONGeometryBuilder::~AliMUONGeometryBuilder()
137 if (fGeometryBuilders){
138 fGeometryBuilders->Delete();
139 delete fGeometryBuilders;
143 //______________________________________________________________________________
144 AliMUONGeometryBuilder&
145 AliMUONGeometryBuilder::operator=(const AliMUONGeometryBuilder& right)
147 /// Assignement operator (not implemented)
149 // check assignement to self
150 if (this == &right) return *this;
152 AliFatal("Assignement operator not provided.");
161 //______________________________________________________________________________
162 void AliMUONGeometryBuilder::PlaceVolume(const TString& name, const TString& mName,
163 Int_t copyNo, const TGeoHMatrix& matrix,
164 Int_t npar, Double_t* param, const char* only) const
166 /// Place the volume specified by name with the given transformation matrix
168 // Do not apply global transformation
169 // if mother volume was already placed in
170 // the new system of coordinates (that is MUON in negative Z)
171 // (as it is applied on the mother volume)
172 TGeoHMatrix transform(matrix);
173 if (mName == TString("DDIP"))
174 transform = fGlobalTransformation.Inverse() * transform;
176 // Decompose transformation
177 const Double_t* xyz = transform.GetTranslation();
178 const Double_t* rm = transform.GetRotationMatrix();
180 //cout << "Got translation: "
181 // << xyz[0] << " " << xyz[1] << " " << xyz[2] << endl;
183 //cout << "Got rotation: "
184 // << rm[0] << " " << rm[1] << " " << rm[2] << endl
185 // << rm[3] << " " << rm[4] << " " << rm[5] << endl
186 // << rm[6] << " " << rm[7] << " " << rm[8] << endl;
188 // Check for presence of rotation
189 // (will be nice to be available in TGeo)
190 const Double_t kTolerance = 1e-04;
191 Bool_t isRotation = true;
192 if (TMath::Abs(rm[0] - 1.) < kTolerance &&
193 TMath::Abs(rm[1] - 0.) < kTolerance &&
194 TMath::Abs(rm[2] - 0.) < kTolerance &&
195 TMath::Abs(rm[3] - 0.) < kTolerance &&
196 TMath::Abs(rm[4] - 1.) < kTolerance &&
197 TMath::Abs(rm[5] - 0.) < kTolerance &&
198 TMath::Abs(rm[6] - 0.) < kTolerance &&
199 TMath::Abs(rm[7] - 0.) < kTolerance &&
200 TMath::Abs(rm[8] - 1.) < kTolerance) isRotation = false;
205 rot.SetMatrix(const_cast<Double_t*>(transform.GetRotationMatrix()));
206 Double_t theta1, phi1, theta2, phi2, theta3, phi3;
207 rot.GetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
210 // << theta1 << " " << phi1 << " "
211 // << theta2 << " " << phi2 << " "
212 // << theta3 << " " << phi3 << endl;
214 fModule->AliMatrix(krot, theta1, phi1, theta2, phi2, theta3, phi3);
217 // Place the volume in ALIC
219 gMC->Gspos(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only);
221 gMC->Gsposp(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only,
226 //______________________________________________________________________________
227 void AliMUONGeometryBuilder::FillGlobalTransformations(
228 AliMUONVGeometryBuilder* builder)
230 /// Compute and set global transformations to detection elements
231 /// for each chamber geometry
233 for (Int_t j=0; j<builder->NofGeometries(); j++) {
235 AliMUONGeometryModule* geometry = builder->Geometry(j);
236 AliMUONGeometryStore* detElements = geometry->GetDetElementStore();
238 for (Int_t k=0; k<detElements->GetNofEntries(); k++) {
240 AliMUONGeometryDetElement* detElement
241 = (AliMUONGeometryDetElement*)detElements->GetEntry(k);
243 if (!detElement) AliFatal("Detection element not found.")
245 const TGeoCombiTrans* localTransform
246 = detElement->GetLocalTransformation();
248 TGeoCombiTrans appliedGlobalTransform;
249 if (builder->ApplyGlobalTransformation())
250 appliedGlobalTransform = fGlobalTransformation;
252 // Compose global transformation
254 = Multiply( appliedGlobalTransform,
255 (*geometry->GetTransformation()),
258 // Convert TGeoHMatrix to TGeoCombiTrans
259 TGeoCombiTrans globalTransform(localTransform->GetName());
260 globalTransform.SetTranslation(total.GetTranslation());
261 TGeoRotation rotation;
262 rotation.SetMatrix(total.GetRotationMatrix());
263 globalTransform.SetRotation(rotation);
265 // Set the global transformation to detection element
266 detElement->SetGlobalTransformation(globalTransform);
271 //_____________________________________________________________________________
272 void AliMUONGeometryBuilder::SetAlign(AliMUONVGeometryBuilder* builder)
274 /// Set align option to all geometry modules associated with the builder
276 for (Int_t j=0; j<builder->NofGeometries(); j++) {
278 AliMUONGeometryModule* geometry = builder->Geometry(j);
280 geometry->SetAlign(fAlign);
288 //_____________________________________________________________________________
289 void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
291 /// Add the geometry builder to the list
293 fGeometryBuilders->Add(geomBuilder);
295 SetAlign(geomBuilder);
298 //______________________________________________________________________________
299 void AliMUONGeometryBuilder::CreateGeometry()
301 /// Construct geometry using geometry builders.
303 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
306 AliMUONVGeometryBuilder* builder
307 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
309 // Create geometry + envelopes
312 if (builder->ApplyGlobalTransformation())
313 builder->SetReferenceFrame(fGlobalTransformation);
314 builder->ReadTransformations();
315 builder->CreateGeometry();
318 builder->CreateGeometry();
319 builder->SetTransformations();
322 // Place module volumes and envelopes
324 for (Int_t j=0; j<builder->NofGeometries(); j++) {
326 AliMUONGeometryModule* geometry = builder->Geometry(j);
328 TGeoCombiTrans appliedGlobalTransform;
329 if (builder->ApplyGlobalTransformation())
330 appliedGlobalTransform = fGlobalTransformation;
332 // Place the module volume
333 if ( !geometry->IsVirtual() ) {
335 = Multiply ( appliedGlobalTransform,
336 (*geometry->GetTransformation()) );
338 PlaceVolume(geometry->GetVolume(), geometry->GetMotherVolume(),
339 1, total, 0, 0, "ONLY");
342 // Loop over envelopes
343 const TObjArray* kEnvelopes = geometry->GetEnvelopeStore()->GetEnvelopes();
344 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
347 AliMUONGeometryEnvelope* env = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
348 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
349 const char* only = "ONLY";
350 if (env->IsMANY()) only = "MANY";
352 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
353 // virtual envelope + nof constituents = 0
355 // empty virtual envelope has no sense
356 AliFatal("Virtual envelope must have constituents.");
360 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
361 // non virtual envelope + nof constituents > 0
363 // use VMC to place constituents
364 AliFatal("Non virtual envelope cannot have constituents.");
368 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
369 // non virtual envelope + nof constituents = 0
370 // => place envelope in ALICE by composed transformation:
371 // Tglobal * Tch * Tenv
373 // Compound chamber transformation with the envelope one
374 if (geometry->IsVirtual()) {
376 = Multiply( appliedGlobalTransform,
377 (*geometry->GetTransformation()),
379 PlaceVolume(env->GetName(), geometry->GetMotherVolume(),
380 env->GetCopyNo(), total, 0, 0, only);
385 PlaceVolume(env->GetName(), geometry->GetVolume(),
386 env->GetCopyNo(), total, 0, 0, only);
390 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
391 // virtual envelope + nof constituents > 0
392 // => do not place envelope and place constituents
393 // in ALICE by composed transformation:
394 // Tglobal * Tch * Tenv * Tconst
396 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
397 AliMUONGeometryConstituent* constituent
398 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
400 // Compound chamber transformation with the envelope one + the constituent one
401 if (geometry->IsVirtual()) {
403 = Multiply ( appliedGlobalTransform,
404 (*geometry->GetTransformation()),
406 (*constituent->GetTransformation()) );
408 PlaceVolume(constituent->GetName(), geometry->GetMotherVolume(),
409 constituent->GetCopyNo(), total,
410 constituent->GetNpar(), constituent->GetParam(), only);
414 = Multiply ( (*kEnvTrans),
415 (*constituent->GetTransformation()) );
417 PlaceVolume(constituent->GetName(), geometry->GetVolume(),
418 constituent->GetCopyNo(), total,
419 constituent->GetNpar(), constituent->GetParam(), only);
423 } // end of loop over envelopes
424 } // end of loop over builder geometries
425 } // end of loop over builders
428 //_____________________________________________________________________________
429 void AliMUONGeometryBuilder::CreateMaterials()
431 /// Construct materials specific to modules via builders
433 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
436 AliMUONVGeometryBuilder* builder
437 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
439 // Create materials with each builder
440 if (builder) builder->CreateMaterials();
444 //______________________________________________________________________________
445 void AliMUONGeometryBuilder::InitGeometry()
447 /// Initialize geometry
449 // Set the chamber (sensitive region) GEANT identifier
451 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
454 AliMUONVGeometryBuilder* builder
455 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
457 // Read alignement data if geometry is read from Root file
458 if (gAlice->IsRootGeometry()) {
460 builder->ReadTransformations();
463 // Set sesitive volumes with each builder
464 builder->SetSensitiveVolumes();
467 // Read sensitive volume map from a file
468 builder->ReadSVMap();
469 if (!fAlign) builder->FillTransformations();
471 // Compute global transformations of detection elements
472 FillGlobalTransformations(builder);
476 //______________________________________________________________________________
477 void AliMUONGeometryBuilder::WriteTransformations()
479 /// Write transformations into files per builder
481 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
484 AliMUONVGeometryBuilder* builder
485 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
487 // Set reference frame
488 // which the transformation will be written with respect to
489 if (builder->ApplyGlobalTransformation())
490 builder->SetReferenceFrame(fGlobalTransformation);
492 // Write transformations
493 builder->WriteTransformations();
497 //______________________________________________________________________________
498 void AliMUONGeometryBuilder::WriteSVMaps(Bool_t rebuild)
500 /// Write sensitive volume maps into files per builder
502 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
505 AliMUONVGeometryBuilder* builder
506 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
508 // Write transformations
509 builder->WriteSVMap(rebuild);
513 //_____________________________________________________________________________
514 void AliMUONGeometryBuilder::SetGlobalTransformation(
515 const TGeoCombiTrans& transform)
517 /// Set the global transformation
519 fGlobalTransformation = transform;
522 //_____________________________________________________________________________
523 void AliMUONGeometryBuilder::SetAlign(Bool_t align)
525 /// Set the option for alignement
529 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
531 AliMUONVGeometryBuilder* builder
532 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);