EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MuMegasGeoParData-simple.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file MuMegasGeoParData-simple.cxx
1 //
2 // AYK (ayk@bnl.gov), 2015/01/28
3 //
4 // MuMegas geometry description file;
5 //
6 
7 #include <iostream>
8 using namespace std;
9 
10 #include <TGeoTube.h>
11 #include <TGeoVolume.h>
12 
13 #include <MuMegasGeoParData.h>
14 
15 // ---------------------------------------------------------------------------------------
16 
18 {
19  const char *detName = mDetName->Name().Data();
20 
21  // Loop through all wheels (or perhaps single modules) independently;
22  for(unsigned bl=0; bl<mBarrels.size(); bl++) {
23  MuMegasBarrel *barrel = mBarrels[bl];
24  MuMegasLayer *layer = barrel->mLayer;
25 
26  // Figure out thickness of the sector gas container volume;
27  double gasSectorThickness = layer->mReadoutPcbThickness + layer->mCopperStripThickness +
29  layer->mExitWindowThickness;
30 
31  // Figure out thickness of the overall air container volume;
32  double airContainerThickness = gasSectorThickness < layer->mInnerFrameThickness ?
33  layer->mInnerFrameThickness : gasSectorThickness;
34  if (airContainerThickness < layer->mOuterFrameThickness)
35  airContainerThickness = layer->mOuterFrameThickness;
36  //printf("%f\n", airContainerThickness); exit(0);
37 
38  // Define air container volume and place it into the top volume;
39  char barrelContainerVolumeName[128];
40  snprintf(barrelContainerVolumeName, 128-1, "%sBarrelContainerVolume%02d", detName, bl);
41 
42  TGeoTube *bcontainer = new TGeoTube(barrelContainerVolumeName,
43  0.1 * barrel->mRadius,
44  0.1 * (barrel->mRadius + airContainerThickness),
45  0.1 * barrel->mLength/2);
46  TGeoVolume *vbcontainer = new TGeoVolume(barrelContainerVolumeName, bcontainer, GetMedium(_AIR_));
47 
48  GetTopVolume()->AddNode(vbcontainer, 0, barrel->mTransformation);
49 
50 #if _NOW_
51  // Define and place a pair of outer frame rings;
52  char outerFrameVolumeName[128];
53  snprintf(outerFrameVolumeName, 128-1, "%sOuterFrameVolume%02d", detName, bl);
54 
55  TGeoTube *oframe = new TGeoTube(outerFrameVolumeName,
56  0.1 * barrel->mRadius,
57  0.1 * (barrel->mRadius + layer->mOuterFrameThickness),
58  0.1 * layer->mOuterFrameWidth/2);
59  TGeoVolume *voframe = new TGeoVolume(outerFrameVolumeName, oframe, GetMedium("MuMegasCarbonFiber"));
60  double zOffset = (barrel->mLength - layer->mOuterFrameWidth)/2;
61  for(unsigned fb=0; fb<2; fb++)
62  vbcontainer->AddNode(voframe, fb, new TGeoCombiTrans(0.0, 0.0, 0.1 * (fb ? -1.0 : 1.0)*zOffset, 0));
63 
64  // Then inner frame ring (in case of 2 sections);
65  assert(barrel->mBeamLineSectionNum == 1 || barrel->mBeamLineSectionNum == 2);
66  if (barrel->mBeamLineSectionNum == 2) {
67  char innerFrameVolumeName[128];
68  snprintf(innerFrameVolumeName, 128-1, "%sInnerFrameVolume%02d", detName, bl);
69 
70  TGeoTube *iframe = new TGeoTube(innerFrameVolumeName,
71  0.1 * barrel->mRadius,
72  0.1 * (barrel->mRadius + layer->mInnerFrameThickness),
73  0.1 * layer->mInnerFrameWidth/2);
74  TGeoVolume *viframe = new TGeoVolume(innerFrameVolumeName, iframe, GetMedium("MuMegasCarbonFiber"));
75 
76  vbcontainer->AddNode(viframe, 0, new TGeoCombiTrans(0.0, 0.0, 0.0, 0));
77  } //if
78 #endif
79 
80 #if 1
81  // Figure out asimuthal "clear acceptance" angular range occupied by each sector;
82  //+double circumference = 2.0 * TMath::Pi() * barrel->mRadius;
83  //+double clearAcceptanceFraction =
84  //+(circumference - barrel->mAsimuthalSectorNum*layer->mInnerFrameWidth)/circumference;
85  //printf("%f\n", clearAcceptanceFraction); exit(0);
86  double singleSectorAngle = 360.0;//+ * clearAcceptanceFraction / barrel->mAsimuthalSectorNum;
87  //printf("%f\n", singleSectorAngle);
88 
89  // Figure out sector length;
90  double singleSectorLength = barrel->mLength;
91  //+(barrel->mLength - 2.0 * layer->mOuterFrameWidth -
92  //+(barrel->mBeamLineSectionNum-1)*layer->mInnerFrameWidth)/barrel->mBeamLineSectionNum;
93  //printf("%f\n", singleSectorLength);
94 
95  // Define single sector gas container volume;
96  char sectorContainerVolumeName[128];
97  snprintf(sectorContainerVolumeName, 128-1, "%sSectorContainerVolume%02d", detName, bl);
98  {
99 
100  TGeoTube/*Seg*/ *sector = new TGeoTube/*Seg*/(sectorContainerVolumeName,
101  0.1 * barrel->mRadius,
102  0.1 * (barrel->mRadius + gasSectorThickness),
103  0.1 * singleSectorLength/2/*,
104  0.0,
105  singleSectorAngle*/);
106  TGeoVolume *vsector = new TGeoVolume(sectorContainerVolumeName, sector, GetMedium(layer->mGasMixture));
107 
108  // Place them all into the air container volume;
109  for(unsigned ir=0; ir<barrel->mAsimuthalSectorNum; ir++) {
110  TGeoRotation *rw = 0;
111  if (ir) {
112  rw = new TGeoRotation();
113  rw->RotateZ(ir*360./barrel->mAsimuthalSectorNum);
114  } //if
115 
116  for(unsigned iz=0; iz<barrel->mBeamLineSectionNum; iz++) {
117  // NB: this will work for 1 or 2 beam line segmentation;
118  double zOffset = barrel->mBeamLineSectionNum == 1 ? 0.0 :
119  (iz ? -1. : 1.)*(singleSectorLength + layer->mInnerFrameWidth)/2.;
120 
121  vbcontainer->AddNode(vsector, ir*barrel->mBeamLineSectionNum+iz,
122  new TGeoCombiTrans(0.0, 0.0, 0.1 * zOffset, rw));
123  } //for iz
124  } //for ir
125 
126 #if 1
127  // Populate gas sector with essential material layers;
128  {
129  double rOffset = barrel->mRadius;
130 
131  PlaceMaterialLayer(detName, "ReadoutPcb", bl, vsector,
132  layer->mReadoutPcbMaterial.Data(),
133  singleSectorLength, singleSectorAngle,
134  layer->mReadoutPcbThickness,
135  &rOffset);
136 
137  PlaceMaterialLayer(detName, "ReadoutStrips", bl, vsector,
138  "copper",
139  singleSectorLength, singleSectorAngle,
140  layer->mCopperStripThickness,
141  &rOffset);
142 
143  PlaceMaterialLayer(detName, "AmplificationRegion", bl, vsector,
144  layer->mGasMixture.Data(),
145  singleSectorLength, singleSectorAngle,
147  &rOffset);
148 
149  PlaceMaterialLayer(detName, "SteelMesh", bl, vsector,
150  "iron",
151  singleSectorLength, singleSectorAngle,
152  layer->mSteelMeshThickness,
153  &rOffset);
154 
155 
156  PlaceMaterialLayer(detName, "ConversionRegion", bl, vsector,
157  layer->mGasMixture.Data(),
158  singleSectorLength, singleSectorAngle,
160  &rOffset);
161 
162  PlaceMaterialLayer(detName, "ExitWindow", bl, vsector,
163  layer->mExitWindowMaterial.Data(),
164  singleSectorLength, singleSectorAngle,
165  layer->mExitWindowThickness,
166  &rOffset);
167  }
168 #endif
169  }
170 #endif
171 
172 #if _NOW_
173  // Define and place beam-aligned pieces of support frames;
174  char sectorFrameVolumeName[128];
175  snprintf(sectorFrameVolumeName, 128-1, "%sSectorFrameVolume%02d", detName, bl);
176  double singleSectorFrameAngle = 360./barrel->mAsimuthalSectorNum - singleSectorAngle;
177  //printf("%f\n", singleSectorFrameAngle);
178  TGeoTubeSeg *sframe = new TGeoTubeSeg(sectorFrameVolumeName,
179  0.1 * barrel->mRadius,
180  0.1 * (barrel->mRadius + layer->mInnerFrameThickness),
181  0.1 * singleSectorLength/2,
182  0.0,
183  singleSectorFrameAngle);
184  TGeoVolume *vsframe = new TGeoVolume(sectorFrameVolumeName, sframe, GetMedium("MuMegasCarbonFiber"));
185 
186  for(unsigned ir=0; ir<barrel->mAsimuthalSectorNum; ir++) {
187  //TGeoRotation *rw = 0;
188  //if (ir) {
189  TGeoRotation *rw = new TGeoRotation();
190  rw->RotateZ(ir*360./barrel->mAsimuthalSectorNum + singleSectorAngle);
191  //} //if
192 
193  for(unsigned iz=0; iz<barrel->mBeamLineSectionNum; iz++) {
194  // NB: this will work for 1 or 2 beam line segmentation;
195  double zOffset = barrel->mBeamLineSectionNum == 1 ? 0.0 :
196  (iz ? -1. : 1.)*(singleSectorLength + layer->mInnerFrameWidth)/2.;
197 
198  vbcontainer->AddNode(vsframe, ir*barrel->mBeamLineSectionNum+iz,
199  new TGeoCombiTrans(0.0, 0.0, 0.1 * zOffset, rw));
200  } //for iz
201  } //for ir
202 
203  // Yes, one map per layer; FIXME: conversion volume name should be calculated once;
204  // also may want to unify with the other [ir..iz] loop;
205  {
207 
208  EicGeoMap *fgmap = CreateNewMap();
209 
210  char conversionVolumeName[128];
211  snprintf(conversionVolumeName, 128-1, "%s%s%02d", detName, "ConversionRegion", bl);
212 
213  fgmap->AddGeantVolumeLevel(conversionVolumeName, 0);
214  fgmap->AddGeantVolumeLevel(sectorContainerVolumeName, barrel->mAsimuthalSectorNum * barrel->mBeamLineSectionNum);
215 
216  fgmap->SetSingleSensorContainerVolume(conversionVolumeName);
217 
218  for(unsigned ir=0; ir<barrel->mAsimuthalSectorNum; ir++)
219  for(unsigned iz=0; iz<barrel->mBeamLineSectionNum; iz++) {
220  UInt_t geant[2] = {0, ir*barrel->mBeamLineSectionNum+iz}, logical[3] = {ir, 0, iz};
221 
222  if (SetMappingTableEntry(fgmap, geant, bl, logical)) {
223  cout << "Failed to set mapping table entry!" << endl;
224  exit(0);
225  } //if
226  } //for ir..iz
227  }
228 #endif
229  } //for bl
230 
231  // Place this stuff as a whole into the top volume and write out;
232  FinalizeOutput();
233 
234  return 0;
235 } // MuMegasGeoParData::ConstructGeometry()
236 
237 // ---------------------------------------------------------------------------------------
238 
239 void MuMegasGeoParData::PlaceMaterialLayer(const char *detName, const char *volumeNamePrefix,
240  unsigned barrelID,
241  TGeoVolume *sectorContainer, const char *material,
242  double length, double angle,
243  double thickness, double *rOffset)
244 {
245  char volumeName[128];
246 
247  snprintf(volumeName, 128-1, "%s%s%02d", detName, volumeNamePrefix, barrelID);
248 
249  TGeoTube/*Seg*/ *shape = new TGeoTube/*Seg*/(volumeName,
250  0.1 * (*rOffset),
251  0.1 * (*rOffset + thickness),
252  0.1 * length/2/*,
253  0.0,
254  angle*/);
255  TGeoVolume *vshape = new TGeoVolume(volumeName, shape, GetMedium(material));
256 
257  sectorContainer->AddNode(vshape, 0, new TGeoCombiTrans(0.0, 0.0, 0.0, 0));
258 
259  *rOffset += thickness;
260 } // MuMegasGeoParData::PlaceMaterialLayer()
261 
262 // ---------------------------------------------------------------------------------------
263