EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BeamPipeGeoParData.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file BeamPipeGeoParData.cxx
1 //
2 // AYK (ayk@bnl.gov), 2014/08/13
3 //
4 // Beam pipe geometry description around the IP;
5 //
6 
7 #include <assert.h>
8 
9 #include <TGeoTube.h>
10 #include <TGeoCone.h>
11 #include <TGeoPcon.h>
12 
13 #include <BeamPipeGeoParData.h>
14 
15 // ---------------------------------------------------------------------------------------
16 
18 {
19  //int ipElementID = -1;
20 
21  // Loop through all the elements and check, that they match each other
22  // (no gaps or diameter mismatch), IP piece is present, etc;
23  for(unsigned el=0; el<mElements.size(); el++) {
24  BeamPipeElement *element = mElements[el];
25 
26  // At least 2 sections must be present;
27  if (element->mSections.size() < 2) {
28  printf("\n Less than 2 sections per piece!\n");
29  return false;
30  } //if
31 
32  // Check whether it is an IP-area element;
33  if (element->mIpElement) {
34  if (mIpElementID != -1) {
35  printf("\n Duplicate IP area beam pipe element!\n");
36  return false;
37  } //if
38 
39  mIpElementID = el;
40  } //if
41 
42  // Check end section match;
43  if (el) {
44  const BeamPipeSection *lh = mElements[el-1]->GetLastOrientedSection();
45  const BeamPipeSection *rh = element->GetFirstOrientedSection();
46 
47  // Require an overlap (sort of vacuum tight);
48  if ((lh->mOuterDiameter/2 < rh->mOuterDiameter/2 - element->mThickness) ||
49  (lh->mOuterDiameter/2 - mElements[el-1]->mThickness > rh->mOuterDiameter/2)) {
50  printf("\n Neighboring piece diameter mismatch (vacuum gap)!\n");
51  return false;
52  } //if
53  } //if
54 
55  // Check section order;
56  for(unsigned sc=0; sc<element->mSections.size()-1; sc++) {
57  // NB: 'lh' & 'rh' assignment does not necessarily reflect "swap" flag here;
58  const BeamPipeSection *lh = element->mSections[sc+0];
59  const BeamPipeSection *rh = element->mSections[sc+1];
60 
61  if ((( element->mSwapped == BeamPipeElement::Swap) && (-rh->mOffset > -lh->mOffset)) ||
62  (((!element->mSwapped) != BeamPipeElement::Swap) && ( lh->mOffset > rh->mOffset))) {
63  printf("\n Neighboring sections are out of order!\n");
64  return false;
65  } //if
66  } //for sc
67  } //for el
68 
69  if (mIpElementID == -1) {
70  printf("\n No IP area beam pipe element defined!\n");
71  return false;
72  } //if
73 
74  // Loop once again and adjust offsets of non-IP pieces;
75  if (mIpElementID != 0)
76  {
77  double accuOffset = mElements[mIpElementID]->GetFirstSection()->mOffset;
78 
79  for(int el=mIpElementID-1; el>=0; el--) {
80  BeamPipeElement *element = mElements[el];
81 
82  accuOffset -= element->GetLength();
83  element->mAccuOffset = accuOffset;
84  } //for el
85  } //if
86  if (mIpElementID != mElements.size()-1)
87  {
88  double accuOffset = mElements[mIpElementID]->GetLastSection()->mOffset;
89 
90  for(unsigned el=mIpElementID+1; el<mElements.size(); el++) {
91  BeamPipeElement *element = mElements[el];
92 
93  element->mAccuOffset = accuOffset;
94  accuOffset += element->GetLength();
95  } //for el
96  } //if
97 
98  return true;
99 } // BeamPipeGeoParData::CheckGeometry()
100 
101 // ---------------------------------------------------------------------------------------
102 
104 {
105  // Error message will be printed out there, don't worry;
106  if (!CheckGeometry()) return false;
107 
108  for(unsigned el=0; el<mElements.size(); el++) {
109  const BeamPipeElement *element = mElements[el];
110 
111  char name[128];
112  // FIXME: do it better later; will hopefully never need more than 100 pieces?;
113  assert(mElements.size() <= 100);
114  snprintf(name, 128-1, "%s%02d", mDetName->Name().Data(), el);
115 
116  TGeoRotation *rY180 = new TGeoRotation();
117  rY180->RotateY(180);
118 
119  TGeoVolume *vwpipe;
120 
121  // Check which representation would fit best;
122  if (element->mSections.size() == 2) {
123  const BeamPipeSection *lh = element->GetFirstSection();
124  const BeamPipeSection *rh = element->GetLastSection();
125 
126  // Yet it can be either a cylinder or a cone;
127  if (lh->mOuterDiameter == rh->mOuterDiameter) {
128  // Fine, cook a TGeoTube;
129  TGeoTube *tpipe = new TGeoTube(name,
130  0.1 * (lh->mOuterDiameter/2 - element->mThickness),
131  0.1 * lh->mOuterDiameter/2,
132  0.1 * element->GetLength()/2);
133  vwpipe = new TGeoVolume(name, tpipe, GetMedium(element->mMaterial));
134  }
135  else {
136  // Fine, cook a TGeoCone;
137  TGeoCone *cpipe = new TGeoCone(name,
138  0.1 * element->GetLength()/2,
139  0.1 * (lh->mOuterDiameter/2 - element->mThickness),
140  0.1 * lh->mOuterDiameter/2,
141  0.1 * (rh->mOuterDiameter/2 - element->mThickness),
142  0.1 * rh->mOuterDiameter/2);
143  vwpipe = new TGeoVolume(name, cpipe, GetMedium(element->mMaterial));
144  } //if
145  }
146  else
147  {
148  // Then it's a TGeoPcon;
149  TGeoPcon *ppipe = new TGeoPcon(name, 0.0, 360.0, element->mSections.size());
150 
151  // Simplify th esituation: place element middle to z=0 (unless it is an IP one);
152  double zLocalOffset = element->mIpElement ? 0.0 :
153  (element->mSections[0]->mOffset + element->mSections[element->mSections.size()-1]->mOffset)/2;
154 
155  for(unsigned sc=0; sc<element->mSections.size(); sc++) {
156  const BeamPipeSection *section = element->mSections[sc];
157 
158  ppipe->DefineSection(sc,
159  0.1 * (section->mOffset - zLocalOffset),
160  0.1 * (section->mOuterDiameter/2 - element->mThickness),
161  0.1 * section->mOuterDiameter/2);
162  vwpipe = new TGeoVolume(name, ppipe, GetMedium(element->mMaterial));
163  } //for sc
164  } //if
165 
166  // Either acknowledge local offsets (absolute placement) or ignore them;
167  double zOffset = element->mIpElement ? /*zOffset =*/ 0.0 : element->mAccuOffset + element->GetLength()/2;
168  GetTopVolume()->AddNode(vwpipe, 0,
169  new TGeoCombiTrans(0.0, 0.0, 0.1 * zOffset,
170  element->mSwapped == BeamPipeElement::Swap ? rY180 : 0));
171 
172  } //for el
173 
174  // And put this stuff as a whole into the top volume;
175  FinalizeOutput();
176 
177  return 0;
178 } // BeamPipeGeoParData::ConstructGeometry()
179 
180 // ---------------------------------------------------------------------------------------
181