EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FstGeoParData.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file FstGeoParData.cxx
1 //
2 // AYK (ayk@bnl.gov), 2014/08/07
3 //
4 // FST MAPS geometry description file;
5 //
6 
7 #include <cmath>
8 #include <assert.h>
9 
10 #include <TGeoTube.h>
11 #include <FstGeoParData.h>
12 
13 //
14 // FIXME:
15 // - mapping table missing;
16 // - staves need to be done as TGeoCompositeShape to come close to the beam pipe;
17 // - half of the staves should be Y-rotated by 180 degrees to bring chips close to beam pipe;
18 // - if TGeoCompositeShape does not work, beam pipe diameter should be made ~2mm smaller
19 // - pipe pieces should be oriented correctly;
20 //
21 
22 // ---------------------------------------------------------------------------------------
23 
24 int FstGeoParData::ConstructGeometry(bool root, bool gdml, bool check)
25 {
26  // Running variables used to give unique indices to all staves; and to count chips;
27  // FIXME: may want to put these into MapsGeoParData?!;
28  unsigned staveGlobalCounter = 0, chipGlobalCounter = 0;
29 
30 #if _NOW_
31  SetLogicalDimensions(GetNumberOfLayers(), maxStaveNumPerLayer, 0, maxChipNumPerStave);
32 #endif
33 
34  for(unsigned dc=0; dc<mDiscs.size(); dc++) {
35  FstDisc *disc = mDiscs[dc];
36  MapsMimosaAssembly *mcell = disc->mChipAssembly;
37  char mountingRingName[128], discName[128];
38  const char *detName = mDetName->Name().Data();
39 
40  // Used to identify odd and even stave indices inside one disc;
41  unsigned staveLocalCounter = 0, nChipsMax = 0;
42 
43  double staveWidth = GetAssemblyContainerWidth(mcell);
44 
45  snprintf(discName, 128-1, "%sContainerVolume%02d", detName, dc);
46  snprintf(mountingRingName, 128-1, "%sMountingRing%02d", detName, dc);
47 
48  // Cook a TGeoTube air container volume;
49  TGeoTube *mdisc = new TGeoTube(discName,
50  0.1 * disc->mMinRadius,
51  0.1 * disc->mMaxRadius,
52  0.1 * (mMountingRingBeamLineThickness + 2*mcell->GetAssemblyHeight())/2);
53  TGeoVolume *vdisc = new TGeoVolume(discName, mdisc, GetMedium(_AIR_));
54  GetTopVolume()->AddNode(vdisc, 0, disc->mTransformation);
55 
56  {
57  // Calculate stave configuration based on min/max radius, min stave-to-stave
58  // overlap and single stave size; NB: assume, that stave assembly width and height
59  // determine the fiducial volume (not exactly intelligent);
60  double hOffset = disc->mMinRadius + staveWidth/2;
61 
62  // Place new staves as long as do not run out of horizontal space;
63  for( ; ; ) {
64  if (hOffset + mcell->mAssemblyBaseWidth/2 > disc->mMaxRadius) break;
65 
66  // See how many chips can put on a stave at thi hOffset;
67  {
68  unsigned nChips;
69 
70  for(nChips=0; ; nChips++) {
71  double staveLength = GetExpectedStaveLength(nChips+1, mcell);
72 
73  double xx = hOffset + staveWidth/2;
74  double yy = staveLength/2;
75  double rr = sqrt(xx*xx + yy*yy);
76 
77  if (rr > disc->mMaxRadius) break;
78  } //for n
79 
80  if (nChips > nChipsMax) nChipsMax = nChips;
81 
82  //printf("%7.2f -> %3d\n", hOffset, nChips);
83  if (!nChips) break;
84 
85  // Add a stave with given number of chips at this location;
86  {
87  //MapsStave *stave = ConstructStave(nChips, staveGlobalCounter++, mcell);
88 
89  //AddStaveMappingTable(stave);
90 
91  bool odd = (staveLocalCounter++)%2;
92 
93  double zOffset = (odd ? -1.0 : 1.0)*
95  //printf("%d\n", staveLocalCounter);
96  for(unsigned lr=0; lr<2; lr++) {
97  TGeoRotation *rw;
98 
99  if (!lr && !odd)
100  // NB: default (!lr && !odd): no rotation;
101  rw = 0;
102  else {
103  rw = new TGeoRotation();
104 
105  if ( !lr && odd)
106  rw->SetAngles(90.0, 0.0, 90.0, 270.0, 180.0, 0.0);
107  else if ( lr && !odd)
108  rw->SetAngles(90.0, 180.0, 90.0, 270.0, 0.0, 0.0);
109  else if ( lr && odd)
110  rw->SetAngles(90.0, 180.0, 90.0, 90.0, 180.0, 0.0);
111  } //if
112 
113  chipGlobalCounter += nChips;
114  // Yes, for now define *all* staves independently; later on group them by chip number;
115  MapsStave *stave = ConstructStaveWithMapping(nChips, staveGlobalCounter++, mcell);
116  vdisc->AddNode(stave->GetVolume(), /*lr*/0, new TGeoCombiTrans(0.1 * (lr ? -1.0 : 1.0)*hOffset,
117  0.0,
118  0.1 * zOffset, rw));
119  } //for lr
120  }
121  }
122 
123  hOffset += disc->mStaveSpacing;
124  }
125  } //for inf
126 
127  // Place two central staves;
128 #if 1
129  {
130  unsigned nChips;
131 
132  for(nChips=0; ; nChips++) {
133  double staveLength = GetExpectedStaveLength(nChips+1, mcell);
134 
135  double xx = staveWidth/2;
136  double yy = disc->mMinRadius + staveLength;
137  double rr = sqrt(xx*xx + yy*yy);
138 
139  if (rr > disc->mMaxRadius) break;
140  } //for n
141 
142  // Can hardly fail;
143  assert(nChips);
144 
145  // Add a stave with given number of chips at this location;
146  {
147  //MapsStave *stave = ConstructStave(nChips, staveGlobalCounter++, mcell);
148 
149  //TGeoRotation *rw = new TGeoRotation();
150  double zOffset = (mMountingRingBeamLineThickness + mcell->GetAssemblyHeight())/2;
151  for(unsigned tb=0; tb<2; tb++) {
152  TGeoRotation *rw = 0;
153 
154  if (tb) {
155  rw = new TGeoRotation();
156  rw->RotateZ(180);
157  } //if
158 
159  chipGlobalCounter += nChips;
160  MapsStave *stave = ConstructStaveWithMapping(nChips, staveGlobalCounter++, mcell);
161  vdisc->AddNode(stave->GetVolume(), /*tb*/0,
162  new TGeoCombiTrans(0.1 * (tb ? -1.0 : 1.0) * mcell->mChipDeadAreaWidth/2,
163  0.1 * (tb ? -1.0 : 1.0)*(disc->mMinRadius + stave->GetLength()/2),
164  0.1 * zOffset, rw));
165  } //for tb
166  }
167  }
168 #endif
169 
170 #if 1
171  // Place 2x2 next-to-central staves;
172  {
173  unsigned nChips;
174  double hOffset = disc->mStaveSpacing, dx = hOffset - staveWidth/2;
175  // This trick does not work if I want to offset chip core by +/-1mm as well;
176  //double y0 = sqrt(disc->mMinRadius*disc->mMinRadius - dx*dx);
177  double y0 = disc->mMinRadius;
178 
179  for(nChips=0; ; nChips++) {
180  double staveLength = GetExpectedStaveLength(nChips+1, mcell);
181 
182  double xx = staveWidth/2;
183  double yy = y0 + staveLength;
184  double rr = sqrt(xx*xx + yy*yy);
185 
186  if (rr > disc->mMaxRadius) break;
187  } //for n
188 
189  // Can hardly fail;
190  assert(nChips);
191 
192  // Add a stave with given number of chips at this location;
193  {
194  //MapsStave *stave = ConstructStave(nChips, staveGlobalCounter++, mcell);
195 
196  double zOffset = -(mMountingRingBeamLineThickness + mcell->GetAssemblyHeight())/2;
197  for(unsigned lr=0; lr<2; lr++)
198  for(unsigned tb=0; tb<2; tb++) {
199  TGeoRotation *rw = new TGeoRotation();
200 
201  if (!tb)
202  rw->RotateY(180);
203  else
204  rw->RotateX(180);
205 
206  chipGlobalCounter += nChips;
207  MapsStave *stave = ConstructStaveWithMapping(nChips, staveGlobalCounter++, mcell);
208  vdisc->AddNode(stave->GetVolume(), /*lr*2+tb*/0,
209  new TGeoCombiTrans(0.1 * ((lr ? -1.0 : 1.0) * hOffset +
210  (tb ? 1.0 :-1.0) * mcell->mChipDeadAreaWidth/2),
211  0.1 * (tb ? -1.0 : 1.0)*(y0 + stave->GetLength()/2),
212  0.1 * zOffset, rw));
213  } //for lr..tb
214  }
215  }
216 #endif
217 
218  // Place mounting ring;
219  if (WithMountingRings())
220  {
221  TGeoTube *mring = new TGeoTube(mountingRingName,
223  0.1 * disc->mMaxRadius,
225  TGeoVolume *vmring = new TGeoVolume(mountingRingName, mring, GetMedium(mCarbonFiberMaterial));
226 
227  vdisc->AddNode(vmring, 0, new TGeoCombiTrans(0.0, 0.0, 0.0, 0));
228  } //if
229 
230 #if _LATER_
231  // Set up a mapping table (more or less dummy for now);
232  AddLogicalVolumeGroup(staveGlobalCounter, nChipsMax);
233 
234  // Yes, carelessly create one map per layer; same as for VST;
235  EicGeoMap *fgmap = CreateNewMap();
238  fgmap->AddGeantVolumeLevel(mCellAssemblyName, blayer->mMimosaChipNum);
239  fgmap->AddGeantVolumeLevel(stave->GetName(), blayer->mStaveNum);
240 
242 #endif
243  } //for dc
244 
245 #if 0
246  // Place a fake beam pipe spot for eye guidance;
247  {
248  TGeoTube *bpipe = new TGeoTube("Pipe",
249  0.0,
250  0.1 * 18.0,
251  0.1 * 10.0);
252  TGeoVolume *vbpipe = new TGeoVolume("Pipe", bpipe, GetMedium("MapsCarbonFiber"));
253 
254  GetTopVolume()->AddNode(vbpipe, 0, new TGeoCombiTrans(0.0, 0.0, 0.1 * 350., 0));
255  }
256 #endif
257 
258  printf("%5d chip(s) and %5d stave(s) total\n", chipGlobalCounter, staveGlobalCounter);
259 
260  // And put this stuff as a whole into the top volume;
261  FinalizeOutput(root, gdml, check);
262 
263  return 0;
264 } // FstGeoParData::ConstructGeometry()
265 
266 // ---------------------------------------------------------------------------------------
267