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 // MUON manager class for geometry construction,
21 // separated form AliMUONv1
23 // Author: Ivana Hrivnacova, IPN Orsay
25 #include <TClonesArray.h>
26 #include <TGeoMatrix.h>
27 #include <TVirtualMC.h>
29 #include "AliMUONGeometryBuilder.h"
31 #include "AliMUONChamber.h"
32 #include "AliMUONConstants.h"
33 #include "AliMUONVGeometryBuilder.h"
34 #include "AliMUONChamberGeometry.h"
35 #include "AliMUONGeometryEnvelope.h"
36 #include "AliMUONGeometryEnvelopeStore.h"
37 #include "AliMUONGeometryConstituent.h"
42 ClassImp(AliMUONGeometryBuilder)
44 //______________________________________________________________________________//___________________________________________
45 AliMUONGeometryBuilder::AliMUONGeometryBuilder()
49 fGlobalTransformation(0),
52 // Default constructor
55 //______________________________________________________________________________//___________________________________________
56 AliMUONGeometryBuilder::AliMUONGeometryBuilder(AliMUON* muon)
60 fGlobalTransformation(0),
63 // Standars constructor
65 // Define the global transformation:
66 // Transformation from the old ALICE coordinate system to a new one:
68 TGeoRotation* rotGlobal
69 = new TGeoRotation("rotGlobal", 90., 180., 90., 90., 180., 0.);
70 fGlobalTransformation = new TGeoCombiTrans(0., 0., 0., rotGlobal);
72 fGeometryBuilders = new TObjArray(AliMUONConstants::NCh());
75 //______________________________________________________________________________
76 AliMUONGeometryBuilder::AliMUONGeometryBuilder(const AliMUONGeometryBuilder& right)
79 // copy constructor (not implemented)
81 AliFatal("Copy constructor not provided.");
84 //______________________________________________________________________________
85 AliMUONGeometryBuilder::~AliMUONGeometryBuilder()
89 delete fGlobalTransformation;
91 if (fGeometryBuilders){
92 fGeometryBuilders->Delete();
93 delete fGeometryBuilders;
97 //______________________________________________________________________________
98 AliMUONGeometryBuilder&
99 AliMUONGeometryBuilder::operator=(const AliMUONGeometryBuilder& right)
101 // assignement operator (not implemented)
103 // check assignement to self
104 if (this == &right) return *this;
106 AliFatal("Assignement operator not provided.");
115 //______________________________________________________________________________
116 void AliMUONGeometryBuilder::PlaceVolume(const TString& name, const TString& mName,
117 Int_t copyNo, const TGeoHMatrix& matrix,
118 Int_t npar, Double_t* param, const char* only) const
120 // Place the volume specified by name with the given transformation matrix
123 // Do not apply global transformation
124 // if mother volume == DDIP
125 // (as it is applied on this volume)
126 TGeoHMatrix transform(matrix);
127 if (mName == TString("DDIP")) {
128 transform = (*fGlobalTransformation) * transform;
129 // To be changed to (*fGlobalTransformation).inverse()
130 // when available in TGeo
131 // To make this correct also for a general case when
132 // (*fGlobalTransformation) * *fGlobalTransformation) != 1
135 // Decompose transformation
136 const Double_t* xyz = transform.GetTranslation();
137 const Double_t* rm = transform.GetRotationMatrix();
139 //cout << "Got translation: "
140 // << xyz[0] << " " << xyz[1] << " " << xyz[2] << endl;
142 //cout << "Got rotation: "
143 // << rm[0] << " " << rm[1] << " " << rm[2] << endl
144 // << rm[3] << " " << rm[4] << " " << rm[5] << endl
145 // << rm[6] << " " << rm[7] << " " << rm[8] << endl;
147 // Check for presence of rotation
148 // (will be nice to be available in TGeo)
149 const Double_t kTolerance = 1e-04;
150 Bool_t isRotation = true;
151 if (TMath::Abs(rm[0] - 1.) < kTolerance &&
152 TMath::Abs(rm[1] - 0.) < kTolerance &&
153 TMath::Abs(rm[2] - 0.) < kTolerance &&
154 TMath::Abs(rm[3] - 0.) < kTolerance &&
155 TMath::Abs(rm[4] - 1.) < kTolerance &&
156 TMath::Abs(rm[5] - 0.) < kTolerance &&
157 TMath::Abs(rm[6] - 0.) < kTolerance &&
158 TMath::Abs(rm[7] - 0.) < kTolerance &&
159 TMath::Abs(rm[8] - 1.) < kTolerance) isRotation = false;
164 rot.SetMatrix(const_cast<Double_t*>(transform.GetRotationMatrix()));
165 Double_t theta1, phi1, theta2, phi2, theta3, phi3;
166 rot.GetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
169 // << theta1 << " " << phi1 << " "
170 // << theta2 << " " << phi2 << " "
171 // << theta3 << " " << phi3 << endl;
173 fMUON->AliMatrix(krot, theta1, phi1, theta2, phi2, theta3, phi3);
176 // Place the volume in ALIC
178 gMC->Gspos(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only);
180 gMC->Gsposp(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only,
189 //______________________________________________________________________________
190 void AliMUONGeometryBuilder::CreateGeometry()
193 // Construct geometry using geometry builders.
196 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
199 AliMUONVGeometryBuilder* builder
200 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
202 // Create geometry with each builder
205 builder->ReadTransformations();
206 builder->CreateGeometry();
209 builder->CreateGeometry();
210 builder->SetTransformations();
215 for (Int_t j=0; j<AliMUONConstants::NCh(); j++) {
217 AliMUONChamberGeometry* geometry = fMUON->Chamber(j).GetGeometry();
219 if (!geometry) continue;
220 // Skip chambers with not defined geometry
222 // Loop over envelopes
223 const TObjArray* kEnvelopes = geometry->GetEnvelopeStore()->GetEnvelopes();
224 for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
227 AliMUONGeometryEnvelope* env = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
228 const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
229 const char* only = "ONLY";
230 if (env->IsMANY()) only = "MANY";
232 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
233 // virtual envelope + nof constituents = 0
235 // empty virtual envelope has no sense
236 AliFatal("Virtual envelope must have constituents.");
240 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
241 // non virtual envelope + nof constituents > 0
243 // use VMC to place constituents
244 AliFatal("Non virtual envelope cannot have constituents.");
248 if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
249 // non virtual envelope + nof constituents = 0
250 // => place envelope in ALICE by composed transformation:
251 // Tglobal * Tch * Tenv
253 // Compound chamber transformation with the envelope one
255 = (*fGlobalTransformation) *
256 (*geometry->GetTransformation()) *
258 PlaceVolume(env->GetName(), geometry->GetMotherVolume(),
259 env->GetCopyNo(), total, 0, 0, only);
262 if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
263 // virtual envelope + nof constituents > 0
264 // => do not place envelope and place constituents
265 // in ALICE by composed transformation:
266 // Tglobal * Tch * Tenv * Tconst
268 for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
269 AliMUONGeometryConstituent* constituent
270 = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
272 // Compound chamber transformation with the envelope one + the constituent one
274 = (*fGlobalTransformation) *
275 (*geometry->GetTransformation()) *
277 (*constituent->GetTransformation());
279 PlaceVolume(constituent->GetName(), geometry->GetMotherVolume(),
280 constituent->GetCopyNo(), total,
281 constituent->GetNpar(), constituent->GetParam(), only);
288 //_____________________________________________________________________________
289 void AliMUONGeometryBuilder::CreateMaterials()
291 // Definition of common materials
295 // Ar-CO2 gas (80%+20%)
296 Float_t ag1[3] = { 39.95,12.01,16. };
297 Float_t zg1[3] = { 18.,6.,8. };
298 Float_t wg1[3] = { .8,.0667,.13333 };
299 Float_t dg1 = .001821;
301 // Ar-buthane-freon gas -- trigger chambers
302 Float_t atr1[4] = { 39.95,12.01,1.01,19. };
303 Float_t ztr1[4] = { 18.,6.,1.,9. };
304 Float_t wtr1[4] = { .56,.1262857,.2857143,.028 };
305 Float_t dtr1 = .002599;
308 Float_t agas[3] = { 39.95,12.01,16. };
309 Float_t zgas[3] = { 18.,6.,8. };
310 Float_t wgas[3] = { .74,.086684,.173316 };
311 Float_t dgas = .0018327;
313 // Ar-Isobutane gas (80%+20%) -- tracking
314 Float_t ag[3] = { 39.95,12.01,1.01 };
315 Float_t zg[3] = { 18.,6.,1. };
316 Float_t wg[3] = { .8,.057,.143 };
317 Float_t dg = .0019596;
319 // Ar-Isobutane-Forane-SF6 gas (49%+7%+40%+4%) -- trigger
320 Float_t atrig[5] = { 39.95,12.01,1.01,19.,32.066 };
321 Float_t ztrig[5] = { 18.,6.,1.,9.,16. };
322 Float_t wtrig[5] = { .49,1.08,1.5,1.84,0.04 };
323 Float_t dtrig = .0031463;
326 Float_t abak[3] = {12.01 , 1.01 , 16.};
327 Float_t zbak[3] = {6. , 1. , 8.};
328 Float_t wbak[3] = {6. , 6. , 1.};
331 Int_t iSXFLD = gAlice->Field()->Integ();
332 Float_t sXMGMX = gAlice->Field()->Max();
334 // --- Define the various materials for GEANT ---
335 fMUON->AliMaterial(9, "ALUMINIUM$", 26.98, 13., 2.7, 8.9, 37.2);
336 fMUON->AliMaterial(10, "ALUMINIUM$", 26.98, 13., 2.7, 8.9, 37.2);
338 Float_t aAir[4]={12.0107,14.0067,15.9994,39.948};
339 Float_t zAir[4]={6.,7.,8.,18.};
340 Float_t wAir[4]={0.000124,0.755267,0.231781,0.012827};
341 Float_t dAir = 1.20479E-3;
342 fMUON->AliMixture(15, "AIR$ ", aAir, zAir, dAir,4, wAir);
343 // fMUON->AliMaterial(15, "AIR$ ", 14.61, 7.3, .001205, 30423.24, 67500);
344 fMUON->AliMixture(19, "Bakelite$", abak, zbak, dbak, -3, wbak);
345 fMUON->AliMixture(20, "ArC4H10 GAS$", ag, zg, dg, 3, wg);
346 fMUON->AliMixture(21, "TRIG GAS$", atrig, ztrig, dtrig, -5, wtrig);
347 fMUON->AliMixture(22, "ArCO2 80%$", ag1, zg1, dg1, 3, wg1);
348 fMUON->AliMixture(23, "Ar-freon $", atr1, ztr1, dtr1, 4, wtr1);
349 fMUON->AliMixture(24, "ArCO2 GAS$", agas, zgas, dgas, 3, wgas);
351 // materials for slat:
352 // Sensitive area: gas (already defined)
354 // insulating material: vetronite -> replacing by G10 Ch. Finck
355 // spacer: noryl Ch. Finck
356 // panel sandwich: carbon, nomex, carbon replacing rohacell by nomex Ch. Finck
358 // G10: SiO2(60%) + C8H14O4(40%)
359 Float_t aglass[5] = {12.01, 28.09, 16., 1.01, 16.};
360 Float_t zglass[5] = { 6., 14., 8., 1., 8.};
361 Float_t wglass[5] = { 0.22, 0.28, 0.32, 0.03, 0.15};
362 Float_t dglass = 1.7;
364 // rohacell: C9 H13 N1 O2
365 Float_t arohac[4] = {12.01, 1.01, 14.010, 16.};
366 Float_t zrohac[4] = { 6., 1., 7., 8.};
367 Float_t wrohac[4] = { 9., 13., 1., 2.};
368 Float_t drohac = 0.03;
370 // Nomex: C22 H10 N2 O5
371 Float_t aNomex[4] = {12.01, 1.01, 14.010, 16.};
372 Float_t zNomex[4] = { 6., 1., 7., 8.};
373 Float_t wNomex[4] = { 22., 10., 2., 5.};
374 Float_t dNomex = 0.024; //honey comb
375 Float_t dNomex2 = 1.43; //bulk material
378 // Noryl: C8 H8 O polyphenylene oxyde (di-methyl not sure)
379 Float_t aNoryl[3] = {12.01, 1.01, 16.};
380 Float_t zNoryl[3] = { 6., 1., 8.};
381 Float_t wNoryl[3] = { 8., 8., 1.};
382 Float_t dNoryl = 1.06;
384 fMUON->AliMaterial(31, "COPPER$", 63.54, 29., 8.96, 1.4, 0.);
385 fMUON->AliMixture( 32, "G10$", aglass, zglass, dglass, -5, wglass);
386 fMUON->AliMaterial(33, "Carbon$", 12.01, 6., 2.265, 18.8, 49.9);
387 fMUON->AliMixture( 34, "Rohacell$", arohac, zrohac, drohac, -4, wrohac);
388 fMUON->AliMixture( 35, "Nomex$", aNomex, zNomex, dNomex, -4, wNomex);
389 fMUON->AliMixture( 36, "Noryl$", aNoryl, zNoryl, dNoryl, -3, wNoryl);
390 fMUON->AliMixture( 37, "Nomex_bulk$",aNomex, zNomex, dNomex2, -4, wNomex);
392 Float_t epsil = .001; // Tracking precision,
393 Float_t stemax = -1.; // Maximum displacement for multiple scat
394 Float_t tmaxfd = -20.; // Maximum angle due to field deflection
395 Float_t deemax = -.3; // Maximum fractional energy loss, DLS
397 Float_t maxDestepAlu = fMUON->GetMaxDestepAlu();
398 Float_t maxDestepGas = fMUON->GetMaxDestepGas();
399 Float_t maxStepAlu = fMUON->GetMaxStepAlu();
400 Float_t maxStepGas = fMUON->GetMaxStepGas();
404 fMUON->AliMedium(1, "AIR_CH_US ", 15, 1, iSXFLD, sXMGMX, tmaxfd, stemax, deemax, epsil, stmin);
408 fMUON->AliMedium(4, "ALU_CH_US ", 9, 0, iSXFLD, sXMGMX, tmaxfd, maxStepAlu,
409 maxDestepAlu, epsil, stmin);
410 fMUON->AliMedium(5, "ALU_CH_US ", 10, 0, iSXFLD, sXMGMX, tmaxfd, maxStepAlu,
411 maxDestepAlu, epsil, stmin);
414 fMUON->AliMedium(6, "AR_CH_US ", 20, 1, iSXFLD, sXMGMX, tmaxfd, maxStepGas,
415 maxDestepGas, epsil, stmin);
417 // Ar-Isobuthane-Forane-SF6 gas
418 fMUON->AliMedium(7, "GAS_CH_TRIGGER ", 21, 1, iSXFLD, sXMGMX, tmaxfd, stemax, deemax, epsil, stmin);
420 fMUON->AliMedium(8, "BAKE_CH_TRIGGER ", 19, 0, iSXFLD, sXMGMX, tmaxfd, maxStepAlu,
421 maxDestepAlu, epsil, stmin);
424 fMUON->AliMedium(9, "ARG_CO2 ", 22, 1, iSXFLD, sXMGMX, tmaxfd, maxStepGas,
425 maxDestepAlu, epsil, stmin);
427 // tracking media for slats: check the parameters!!
428 fMUON->AliMedium(11, "PCB_COPPER ", 31, 0, iSXFLD, sXMGMX, tmaxfd,
429 maxStepAlu, maxDestepAlu, epsil, stmin);
430 fMUON->AliMedium(12, "G10 ", 32, 0, iSXFLD, sXMGMX, tmaxfd,
431 maxStepAlu, maxDestepAlu, epsil, stmin);
432 fMUON->AliMedium(13, "CARBON ", 33, 0, iSXFLD, sXMGMX, tmaxfd,
433 maxStepAlu, maxDestepAlu, epsil, stmin);
434 fMUON->AliMedium(14, "Rohacell ", 34, 0, iSXFLD, sXMGMX, tmaxfd,
435 maxStepAlu, maxDestepAlu, epsil, stmin);
436 fMUON->AliMedium(15, "Nomex ", 35, 0, iSXFLD, sXMGMX, tmaxfd,
437 maxStepAlu, maxDestepAlu, epsil, stmin);
438 fMUON->AliMedium(16, "Noryl ", 36, 0, iSXFLD, sXMGMX, tmaxfd,
439 maxStepAlu, maxDestepAlu, epsil, stmin);
440 fMUON->AliMedium(17, "Nomex bulk ", 37, 0, iSXFLD, sXMGMX, tmaxfd,
441 maxStepAlu, maxDestepAlu, epsil, stmin);
442 //.Materials specific to stations
443 // created via builders
445 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
448 AliMUONVGeometryBuilder* builder
449 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
451 // Create materials with each builder
452 if (builder) builder->CreateMaterials();
456 //______________________________________________________________________________
457 void AliMUONGeometryBuilder::InitGeometry()
459 // Initialize geometry
463 // Set the chamber (sensitive region) GEANT identifier
465 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
468 AliMUONVGeometryBuilder* builder
469 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
471 // Set sesitive volumes with each builder
472 builder->SetSensitiveVolumes();
474 // Read sensitive volume map from a file
475 builder->ReadSVMap();
476 if (!fAlign) builder->FillTransformations();
480 //______________________________________________________________________________
481 void AliMUONGeometryBuilder::WriteTransformations()
483 // Writes transformations into files per builder
486 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
489 AliMUONVGeometryBuilder* builder
490 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
492 // Write transformations
493 builder->WriteTransformations();
497 //______________________________________________________________________________
498 void AliMUONGeometryBuilder::WriteSVMaps(Bool_t rebuild)
500 // Writes sensitive volume maps into files per builder
503 for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
506 AliMUONVGeometryBuilder* builder
507 = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
509 // Write transformations
510 builder->WriteSVMap(rebuild);
514 //_____________________________________________________________________________
515 void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
517 // Adds the geometry builder to the list
520 fGeometryBuilders->Add(geomBuilder);
523 //_____________________________________________________________________________
524 void AliMUONGeometryBuilder::SetAlign(Bool_t align)
526 // Sets the option for alignement
531 for (Int_t j=0; j<AliMUONConstants::NCh(); j++) {
533 AliMUONChamberGeometry* geometry = fMUON->Chamber(j).GetGeometry();
535 if (!geometry) continue;
536 // Skip chambers with not defined geometry
538 geometry->SetAlign(align);