]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONGeometryBuilder.cxx
Added <assert.h> include
[u/mrichter/AliRoot.git] / MUON / AliMUONGeometryBuilder.cxx
CommitLineData
d4bb94a1 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. *
6 * *
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 **************************************************************************/
15
16// $Id$
17//
18// Class AliMUONGeometryBuilder
19// ----------------------------
e118b27e 20// Manager class for geometry construction via geometry builders.
d4bb94a1 21//
22// Author: Ivana Hrivnacova, IPN Orsay
23
e118b27e 24#include <TObjArray.h>
d4bb94a1 25#include <TVirtualMC.h>
26
27#include "AliMUONGeometryBuilder.h"
d4bb94a1 28#include "AliMUONVGeometryBuilder.h"
e118b27e 29#include "AliMUONGeometryModule.h"
d4bb94a1 30#include "AliMUONGeometryEnvelope.h"
76497dec 31#include "AliMUONGeometryEnvelopeStore.h"
e118b27e 32#include "AliMUONGeometryDetElement.h"
33#include "AliMUONGeometryStore.h"
d4bb94a1 34#include "AliMUONGeometryConstituent.h"
e118b27e 35#include "AliModule.h"
8c343c7c 36#include "AliLog.h"
4a9de4af 37#include "AliRun.h"
38
d4bb94a1 39
40ClassImp(AliMUONGeometryBuilder)
41
067866a3 42// static functions
43
44//______________________________________________________________________________
45TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
46 const TGeoMatrix& m2)
47{
48/// Temporary fix for problem with matrix multiplication in Root 5.02/00
49
50 if (m1.IsIdentity() && m2.IsIdentity()) return TGeoHMatrix();
51
52 if (m1.IsIdentity()) return m2;
53
54 if (m2.IsIdentity()) return m1;
55
56 return m1 * m2;
57}
58
59//______________________________________________________________________________
60TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
61 const TGeoMatrix& m2,
62 const TGeoMatrix& m3)
63{
64/// Temporary fix for problem with matrix multiplication in Root 5.02/00
65
66 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity())
67 return TGeoHMatrix();
68
69 if (m1.IsIdentity()) return Multiply(m2, m3);
70
71 if (m2.IsIdentity()) return Multiply(m1, m3);
72
73 if (m3.IsIdentity()) return Multiply(m1, m2);
74
75 return m1 * m2 * m3;
76}
77
78//______________________________________________________________________________
79TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
80 const TGeoMatrix& m2,
81 const TGeoMatrix& m3,
82 const TGeoMatrix& m4)
83{
84/// Temporary fix for problem with matrix multiplication in Root 5.02/00
85
86 if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity() & m4.IsIdentity())
87 return TGeoHMatrix();
88
89 if (m1.IsIdentity()) return Multiply(m2, m3, m4);
90
91 if (m2.IsIdentity()) return Multiply(m1, m3, m4);
92
93 if (m3.IsIdentity()) return Multiply(m1, m2, m4);
94
95 if (m4.IsIdentity()) return Multiply(m1, m2, m3);
96
97 return m1 * m2 * m3 * m4;
98}
99
e118b27e 100//______________________________________________________________________________
101AliMUONGeometryBuilder::AliMUONGeometryBuilder(AliModule* module)
d4bb94a1 102 : TObject(),
e118b27e 103 fModule(module),
76497dec 104 fAlign(false),
e118b27e 105 fGlobalTransformation(),
d4bb94a1 106 fGeometryBuilders(0)
107{
692de412 108/// Standard constructor
e118b27e 109
110 fGeometryBuilders = new TObjArray(100);
111}
d4bb94a1 112
e118b27e 113//______________________________________________________________________________
114AliMUONGeometryBuilder::AliMUONGeometryBuilder()
d4bb94a1 115 : TObject(),
e118b27e 116 fModule(0),
76497dec 117 fAlign(false),
e118b27e 118 fGlobalTransformation(),
d4bb94a1 119 fGeometryBuilders(0)
120{
692de412 121/// Default constructor
e118b27e 122}
d4bb94a1 123
124//______________________________________________________________________________
125AliMUONGeometryBuilder::AliMUONGeometryBuilder(const AliMUONGeometryBuilder& right)
126 : TObject(right)
127{
692de412 128/// Copy constructor (not implemented)
d4bb94a1 129
8c343c7c 130 AliFatal("Copy constructor not provided.");
d4bb94a1 131}
132
133//______________________________________________________________________________
134AliMUONGeometryBuilder::~AliMUONGeometryBuilder()
135{
692de412 136/// Destructor
d4bb94a1 137 if (fGeometryBuilders){
138 fGeometryBuilders->Delete();
139 delete fGeometryBuilders;
140 }
141}
142
143//______________________________________________________________________________
144AliMUONGeometryBuilder&
145AliMUONGeometryBuilder::operator=(const AliMUONGeometryBuilder& right)
146{
692de412 147/// Assignement operator (not implemented)
d4bb94a1 148
149 // check assignement to self
150 if (this == &right) return *this;
151
8c343c7c 152 AliFatal("Assignement operator not provided.");
d4bb94a1 153
154 return *this;
155}
156
157//
158// private functions
159//
160
161//______________________________________________________________________________
162void 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
165{
692de412 166/// Place the volume specified by name with the given transformation matrix
d4bb94a1 167
168 // Do not apply global transformation
cfbf2f7d 169 // if mother volume was already placed in
170 // the new system of coordinates (that is MUON in negative Z)
e118b27e 171 // (as it is applied on the mother volume)
d4bb94a1 172 TGeoHMatrix transform(matrix);
cfbf2f7d 173 if (mName == TString("DDIP"))
e118b27e 174 transform = fGlobalTransformation.Inverse() * transform;
d4bb94a1 175
176 // Decompose transformation
177 const Double_t* xyz = transform.GetTranslation();
178 const Double_t* rm = transform.GetRotationMatrix();
179
180 //cout << "Got translation: "
181 // << xyz[0] << " " << xyz[1] << " " << xyz[2] << endl;
182
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;
187
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;
201
202 Int_t krot = 0;
203 if (isRotation) {
204 TGeoRotation rot;
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);
208
209 //cout << "angles: "
210 // << theta1 << " " << phi1 << " "
211 // << theta2 << " " << phi2 << " "
212 // << theta3 << " " << phi3 << endl;
213
e118b27e 214 fModule->AliMatrix(krot, theta1, phi1, theta2, phi2, theta3, phi3);
d4bb94a1 215 }
216
217 // Place the volume in ALIC
218 if (npar == 0)
219 gMC->Gspos(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only);
220 else
221 gMC->Gsposp(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only,
222 param, npar);
223
224}
225
e118b27e 226//______________________________________________________________________________
227void AliMUONGeometryBuilder::FillGlobalTransformations(
228 AliMUONVGeometryBuilder* builder)
229{
692de412 230/// Compute and set global transformations to detection elements
231/// for each chamber geometry
e118b27e 232
233 for (Int_t j=0; j<builder->NofGeometries(); j++) {
234
235 AliMUONGeometryModule* geometry = builder->Geometry(j);
236 AliMUONGeometryStore* detElements = geometry->GetDetElementStore();
237
238 for (Int_t k=0; k<detElements->GetNofEntries(); k++) {
239
240 AliMUONGeometryDetElement* detElement
241 = (AliMUONGeometryDetElement*)detElements->GetEntry(k);
242
243 if (!detElement) AliFatal("Detection element not found.")
244
245 const TGeoCombiTrans* localTransform
246 = detElement->GetLocalTransformation();
247
067866a3 248 TGeoCombiTrans appliedGlobalTransform;
249 if (builder->ApplyGlobalTransformation())
250 appliedGlobalTransform = fGlobalTransformation;
251
e118b27e 252 // Compose global transformation
253 TGeoHMatrix total
067866a3 254 = Multiply( appliedGlobalTransform,
255 (*geometry->GetTransformation()),
256 (*localTransform) );
e118b27e 257
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);
264
265 // Set the global transformation to detection element
266 detElement->SetGlobalTransformation(globalTransform);
267 }
268 }
269}
270
d4bb94a1 271//
272// public functions
273//
274
e118b27e 275//_____________________________________________________________________________
276void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
277{
067866a3 278/// Add the geometry builder to the list
e118b27e 279
280 fGeometryBuilders->Add(geomBuilder);
281}
282
d4bb94a1 283//______________________________________________________________________________
284void AliMUONGeometryBuilder::CreateGeometry()
285{
692de412 286/// Construct geometry using geometry builders.
d4bb94a1 287
288 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
289
290 // Get the builder
291 AliMUONVGeometryBuilder* builder
292 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
293
e118b27e 294 // Create geometry + envelopes
295 //
296 if (fAlign) {
067866a3 297 if (builder->ApplyGlobalTransformation())
298 builder->SetReferenceFrame(fGlobalTransformation);
e118b27e 299 builder->ReadTransformations();
300 builder->CreateGeometry();
d4bb94a1 301 }
e118b27e 302 else {
303 builder->CreateGeometry();
304 builder->SetTransformations();
305 }
d4bb94a1 306
cfbf2f7d 307 // Place module volumes and envelopes
e118b27e 308 //
309 for (Int_t j=0; j<builder->NofGeometries(); j++) {
d4bb94a1 310
e118b27e 311 AliMUONGeometryModule* geometry = builder->Geometry(j);
cfbf2f7d 312
067866a3 313 TGeoCombiTrans appliedGlobalTransform;
314 if (builder->ApplyGlobalTransformation())
315 appliedGlobalTransform = fGlobalTransformation;
316
cfbf2f7d 317 // Place the module volume
318 if ( !geometry->IsVirtual() ) {
319 TGeoHMatrix total
067866a3 320 = Multiply ( appliedGlobalTransform,
321 (*geometry->GetTransformation()) );
cfbf2f7d 322
323 PlaceVolume(geometry->GetVolume(), geometry->GetMotherVolume(),
324 1, total, 0, 0, "ONLY");
325 }
e118b27e 326
327 // Loop over envelopes
328 const TObjArray* kEnvelopes = geometry->GetEnvelopeStore()->GetEnvelopes();
329 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
330
331 // Get envelope
332 AliMUONGeometryEnvelope* env = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
333 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
334 const char* only = "ONLY";
335 if (env->IsMANY()) only = "MANY";
336
337 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
338 // virtual envelope + nof constituents = 0
339 // => not allowed;
340 // empty virtual envelope has no sense
341 AliFatal("Virtual envelope must have constituents.");
342 return;
343 }
d4bb94a1 344
e118b27e 345 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
346 // non virtual envelope + nof constituents > 0
347 // => not allowed;
348 // use VMC to place constituents
349 AliFatal("Non virtual envelope cannot have constituents.");
350 return;
351 }
352
353 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
354 // non virtual envelope + nof constituents = 0
355 // => place envelope in ALICE by composed transformation:
356 // Tglobal * Tch * Tenv
357
358 // Compound chamber transformation with the envelope one
cfbf2f7d 359 if (geometry->IsVirtual()) {
360 TGeoHMatrix total
067866a3 361 = Multiply( appliedGlobalTransform,
362 (*geometry->GetTransformation()),
363 (*kEnvTrans) );
cfbf2f7d 364 PlaceVolume(env->GetName(), geometry->GetMotherVolume(),
365 env->GetCopyNo(), total, 0, 0, only);
366 }
367 else {
368 TGeoHMatrix total
369 = (*kEnvTrans);
370 PlaceVolume(env->GetName(), geometry->GetVolume(),
371 env->GetCopyNo(), total, 0, 0, only);
372 }
e118b27e 373 }
374
375 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
376 // virtual envelope + nof constituents > 0
377 // => do not place envelope and place constituents
378 // in ALICE by composed transformation:
379 // Tglobal * Tch * Tenv * Tconst
d4bb94a1 380
e118b27e 381 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
382 AliMUONGeometryConstituent* constituent
383 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
384
385 // Compound chamber transformation with the envelope one + the constituent one
cfbf2f7d 386 if (geometry->IsVirtual()) {
387 TGeoHMatrix total
067866a3 388 = Multiply ( appliedGlobalTransform,
389 (*geometry->GetTransformation()),
390 (*kEnvTrans),
391 (*constituent->GetTransformation()) );
cfbf2f7d 392
393 PlaceVolume(constituent->GetName(), geometry->GetMotherVolume(),
394 constituent->GetCopyNo(), total,
395 constituent->GetNpar(), constituent->GetParam(), only);
396 }
397 else {
398 TGeoHMatrix total
067866a3 399 = Multiply ( (*kEnvTrans),
400 (*constituent->GetTransformation()) );
cfbf2f7d 401
402 PlaceVolume(constituent->GetName(), geometry->GetVolume(),
403 constituent->GetCopyNo(), total,
404 constituent->GetNpar(), constituent->GetParam(), only);
405 }
e118b27e 406 }
d4bb94a1 407 }
e118b27e 408 } // end of loop over envelopes
409 } // end of loop over builder geometries
410 } // end of loop over builders
d4bb94a1 411}
412
413//_____________________________________________________________________________
414void AliMUONGeometryBuilder::CreateMaterials()
415{
692de412 416/// Construct materials specific to modules via builders
d4bb94a1 417
418 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
419
420 // Get the builder
421 AliMUONVGeometryBuilder* builder
422 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
423
424 // Create materials with each builder
425 if (builder) builder->CreateMaterials();
426 }
427}
428
429//______________________________________________________________________________
430void AliMUONGeometryBuilder::InitGeometry()
431{
692de412 432/// Initialize geometry
d4bb94a1 433
d4bb94a1 434 // Set the chamber (sensitive region) GEANT identifier
435 //
436 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
437
438 // Get the builder
439 AliMUONVGeometryBuilder* builder
440 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
441
4a9de4af 442 // Read alignement data if geometry is read from Root file
443 if (gAlice->IsRootGeometry()) {
444 fAlign = true;
445 builder->ReadTransformations();
446 }
447
d4bb94a1 448 // Set sesitive volumes with each builder
76497dec 449 builder->SetSensitiveVolumes();
e118b27e 450
4a9de4af 451
76497dec 452 // Read sensitive volume map from a file
453 builder->ReadSVMap();
454 if (!fAlign) builder->FillTransformations();
e118b27e 455
456 // Compute global transformations of detection elements
457 FillGlobalTransformations(builder);
458 }
76497dec 459}
460
461//______________________________________________________________________________
462void AliMUONGeometryBuilder::WriteTransformations()
463{
067866a3 464/// Write transformations into files per builder
76497dec 465
466 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
467
468 // Get the builder
469 AliMUONVGeometryBuilder* builder
470 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
471
067866a3 472 // Set reference frame
473 // which the transformation will be written with respect to
474 if (builder->ApplyGlobalTransformation())
475 builder->SetReferenceFrame(fGlobalTransformation);
476
76497dec 477 // Write transformations
478 builder->WriteTransformations();
479 }
480}
481
482//______________________________________________________________________________
483void AliMUONGeometryBuilder::WriteSVMaps(Bool_t rebuild)
484{
067866a3 485/// Write sensitive volume maps into files per builder
76497dec 486
487 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
488
489 // Get the builder
490 AliMUONVGeometryBuilder* builder
491 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
492
493 // Write transformations
494 builder->WriteSVMap(rebuild);
d4bb94a1 495 }
496}
497
498//_____________________________________________________________________________
e118b27e 499void AliMUONGeometryBuilder::SetGlobalTransformation(
500 const TGeoCombiTrans& transform)
d4bb94a1 501{
067866a3 502/// Set the global transformation
d4bb94a1 503
e118b27e 504 fGlobalTransformation = transform;
505}
d4bb94a1 506
76497dec 507//_____________________________________________________________________________
508void AliMUONGeometryBuilder::SetAlign(Bool_t align)
509{
067866a3 510/// Set the option for alignement
76497dec 511
512 fAlign = align;
513
e118b27e 514 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
515
516 // Get the builder
517 AliMUONVGeometryBuilder* builder
518 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
76497dec 519
e118b27e 520 for (Int_t j=0; j<builder->NofGeometries(); j++) {
76497dec 521
e118b27e 522 AliMUONGeometryModule* geometry = builder->Geometry(j);
523
524 geometry->SetAlign(align);
525 }
76497dec 526 }
527}