EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
vc2020_03_20.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file vc2020_03_20.cc
1 
2 #include <TGeoArb8.h>
3 #include <TGeoTube.h>
4 #include <TGeoCone.h>
5 #include <TGeoCompositeShape.h>
6 
7 #include <EicToyModel.h>
8 #include <vc2020_03_20.h>
9 
10 // --------------------------------------------------------------------------------------
11 // These parameters describe the beam pipe layout as of 2020/03/20;
12 //
13 #define _BERYLLIUM_PIPE_INNER_DIAMETER_ ( 6.20 * etm::cm)
14 // "62mm" electron beam pipe has the outer diameter of 63.5mm;
15 #define _BERYLLIUM_PIPE_OUTER_DIAMETER_ ( 6.35 * etm::cm)
16 
17 // This beam pipe has a rectangular cross-section;
18 #define _ESIDE_ALUMINUM_PIPE_HEIGHT_ ( 6.80 * etm::cm)
19 // Just hardcode these two; 7.3mrad and 25mrad (presumably matching the crossing angle);
20 #define _ESIDE_ALUMINUM_PIPE_USLOPE_ ( 0.0073)
21 //#define _ESIDE_ALUMINUM_PIPE_DSLOPE_ ( 0.025)
22 
23 // Assume the conical beam pipe starts out of this circle; this is actually true;
24 #define _HSIDE_ALUMINUM_PIPE_DIAMETER_ ( 6.45 * etm::cm)
25 
26 // Beryllium section is asymmetric with respect to the IP;
27 #define _ESIDE_BERYLLIUM_PIPE_LENGTH_ (80.00 * etm::cm)
28 #define _HSIDE_BERYLLIUM_PIPE_LENGTH_ (67.00 * etm::cm)
29 
30 // In Charlie's model as of 2020/03/20: 0.5mrad "conical thickness";
31 #define _HADRON_PIPE_OPENING_DELTA_ ( 0.001)
32 
33 // These 0.127cm (kind of plate thickness) is present in several places -> make a #define;
34 #define _0_127_ ( 0.127 * etm::cm)
35 
36 // Hadron beam pipe *outer*side* *full* opening; ~51mrad;
37 #define _HADRON_PIPE_OPENING_DEFAULT_ ( 0.051)
38 // --------------------------------------------------------------------------------------
39 
40 // ---------------------------------------------------------------------------------------
41 // ---------------------------------------------------------------------------------------
42 
44 {
45  // FIXME: it seems these value will be overwritten every time .root file is imported new?;
46  //if (!mBerylliumBeamPipeDiameter)
47  //mBerylliumBeamPipeDiameter = _BERYLLIUM_PIPE_OUTER_DIAMETER_DEFAULT_;
48  //printf("%f\n", mHadronBeamPipeOpening);
51 
52  //CreateGeometry();
53 } // vc2020_03_20::vc2020_03_20()
54 
55 // ---------------------------------------------------------------------------------------
56 
57 //double vc2020_03_20::FixedCrossingAngle( void ) const
58 //{
59 //return _ESIDE_ALUMINUM_PIPE_DSLOPE_;
60 //} // vc2020_03_20::FixedCrossingAngle()
61 
62 // ---------------------------------------------------------------------------------------
63 // ---------------------------------------------------------------------------------------
64 
66 {
67  // FIXME: well, it's hard to get rid of this; would have to
68  auto eic = EicToyModel::Instance();
69 
70  double oslope = mHadronBeamPipeOpening/2, islope = oslope - _HADRON_PIPE_OPENING_DELTA_/2;
71  // FIXME: is it correct, or should be 'oslope'?;
72  double qslope = islope;
73 
74  int green = kGreen+2, cyan = kCyan, yellow = kYellow+1;
75 
76  // FIXME: need to clean up in case of a re-creation attempt (say with a different IP shift);
77  auto model = GetWorld(); assert(model);
78  auto world = model->GetTopVolume(); assert(world);
79 
80  auto assy = new TGeoVolumeAssembly("VC.ASSEMBLY");
81  world->AddNode(assy, 0, 0);
82 
83  //
84  // 1) Visualization of Boolean shapes is implemented in a crappy way in both ROOT and GEANT:
85  //
86  // - ROOT silently shows weird shapes;
87  // - in GEANT either G4Polyhedra or G4GenericPolycone shapes do not have GetPolyhedron() method
88  // implemented at all, therefore G4PhysicalVolumeModel::DescribeSolid() fails with a "has no
89  // polyhedron" message; who the hell needs shapes, which are useable in navigation, but can
90  // not be seen in an event display?!;
91  // - VecGeom (USolids) library does have these methods implemented, but GetPolyhedron() fails
92  // somewhere deep inside the boolean processor, and I have no time to debug this; a custom
93  // GEANT installation is required, which would only complicate usage in either fun4all or
94  // escalate;
95  //
96  // 2) Boolean shape TGeo->GEANT conversion through VGM, as well as TGeo export to GDML have more
97  // fundamental issues (both just fail if any complicated boolean objects are used);
98  //
99  // In order to have proper conversion(s), correct boolean cut of the integration volumes
100  // by the vacuum chamber outer shell, as well as proper visualization of both the vacuum chamber
101  // and the integration volumes have to resort to using a simplistic implementation. It is still
102  // adequately describes the layout;
103  //
104 
105  // Central portion of the beryllium pipe;
106  {
108  double zOffset = eic->GetIpLocation().X() +
109  (_HSIDE_BERYLLIUM_PIPE_LENGTH_ - _ESIDE_BERYLLIUM_PIPE_LENGTH_)/2;
110 
111  auto ocpipe = new TGeoTube("BE_PIPE_O",
112  0.0,
114  length/2);
115 
116  auto vocpipe = new TGeoVolume(ocpipe->GetName(), ocpipe, model->GetMedium("Be"));
117  // Strangely enough, SetFillColor() plays no role;
118  vocpipe->SetLineColor(yellow);
119  assy->AddNode(vocpipe, 0, new TGeoTranslation(0.0, 0.0, zOffset));
120 
121  {
122  auto icpipe = new TGeoTube("BE_PIPE_I",
123  0.0,
125  length/2);
126  auto vicpipe = new TGeoVolume(icpipe->GetName(), icpipe, model->GetMedium(_ACCELERATOR_VACUUM_));
127  vicpipe->SetLineColor(cyan);
128  vocpipe->AddNode(vicpipe, 0, new TGeoTranslation(0.0, 0.0, 0.0));
129  }
130  }
131 
132  {
133  // Electron-going direction;
134  double zr = eic->GetIpLocation().X() - _ESIDE_BERYLLIUM_PIPE_LENGTH_;
135  double zl = -eic->GetIrRegionLength()/2, dz = fabs(zr - zl);
136  double y0 = _ESIDE_ALUMINUM_PIPE_HEIGHT_/2;
137  double dyu = dz*tan(_ESIDE_ALUMINUM_PIPE_USLOPE_);
138  //double dyd = dz*tan(_ESIDE_ALUMINUM_PIPE_DSLOPE_);
139  double dyd = dz*tan(eic->GetCrossingAngle());//_ESIDE_ALUMINUM_PIPE_DSLOPE_);
140 
141  {
142  double z1 = eic->GetIpLocation().X() - _ESIDE_BERYLLIUM_PIPE_LENGTH_;
143  double z2 = eic->GetIpLocation().X() + _HSIDE_BERYLLIUM_PIPE_LENGTH_;
144  double z0 = -eic->GetIrRegionLength()/2, dz10 = fabs(z1 - z0);
145  // Do not bother to re-calculate shape precisely;
146  double zOffset = (z0+z1)/2, xy[8][2] = {
147  // Clock-wise; +X is the vertical direction in the detector view TCanvas;
148  { y0+dyu, -y0},
149  {-y0-dyd, -y0},
150  {-y0-dyd, y0},
151  { y0+dyu, y0},
152 
153  { y0, -y0},
154  {-y0, -y0},
155  {-y0, y0},
156  { y0, y0}
157  };
158 
159  // Looks like TGeoArb8 is the easiest?; this is the outer surface;
160  auto oearb8 = new TGeoArb8("E_PIPE_O", dz10/2, (double*)xy);
161  auto voepipe = new TGeoVolume(oearb8->GetName(), oearb8, model->GetMedium("Al"));
162  voepipe->SetLineColor(green);
163  assy->AddNode(voepipe, 0, new TGeoTranslation( 0.0, 0.0, zOffset));
164 
165  // This is the inner vacuum volume;
166  {
167  // 'Upstream' in the ROOT coordinate system, where +Z is in hadron-going direction;
168  for(unsigned du=0; du<2; du++) {
169  // FIXME: thickness on the upstream and downstream ends hardcoded;
170  double inwards = du ? _0_127_ : 0.300;
171 
172  for(unsigned ivtx=0; ivtx<4; ivtx++)
173  for(unsigned ixy=0; ixy<2; ixy++)
174  xy[du*4 + ivtx][ixy] += xy[du*4 + ivtx][ixy] > 0.0 ? -inwards : inwards;
175  } //for ud
176 
177  auto iearb8 = new TGeoArb8("E_PIPE_I", dz10/2, (double*)xy);
178  auto viepipe =
179  new TGeoVolume(iearb8->GetName(), iearb8, model->GetMedium(_ACCELERATOR_VACUUM_));
180  viepipe->SetLineColor(cyan);
181  voepipe->AddNode(viepipe, 0, new TGeoTranslation( 0.0, 0.0, 0.0));
182  }
183 
184  // Hadron pipe cone; boolean operations on a pair of cones as well as with
185  // TGeoHalfSpace may work, but look totally screwed up in TEve; a single hollow
186  // cone cut at an angle by TGeoBBox fails conversion to GDML; resort to a simple
187  // alu cone with a vacuum daughter cone volume;
188  {
189  // FIXME: need either an additional cut cylinder inbetween the beryllium and conical
190  // pipes or perhaps just cut beryllium cylinder at an angle; FIXME: calculate both length
191  // and additional small offset of this rotated cone properly;
192  double length = eic->GetIrRegionLength()/2 - eic->GetIpLocation().X() -
194  // Calculate cone apex distance from z3;
195  double apex2z3 = (_HSIDE_ALUMINUM_PIPE_DIAMETER_/2)/tan(oslope);
196  double rmax = (apex2z3 + length)*tan(oslope);
197 
198  auto ocone = new TGeoCone("H_PIPE_OCONE", length/2,
199  0.0,
200  apex2z3*tan(oslope),
201  0.0,
202  rmax);
203  auto rw = new TGeoRotation();
204  rw->RotateY(qslope*180/M_PI);
205  // FIXME: 0.1 hardcoded;
206  auto trq = new TGeoCombiTrans("TRQ", qslope*length/2, 0.0, z2 + 0.1 + length/2, rw);
207  trq->RegisterYourself();
208 
209  auto vocone = new TGeoVolume(ocone->GetName(), ocone, model->GetMedium("Al"));
210  assy->AddNode(vocone, 0, trq);
211  vocone->SetLineColor(green);
212 
213  {
214  auto icone = new TGeoCone("H_PIPE_ICONE", length/2,
215  0.0,
216  apex2z3 *tan(islope),
217  0.0,
218  (apex2z3 + length)*tan(islope));
219  auto vicone = new TGeoVolume(icone->GetName(), icone, model->GetMedium(_ACCELERATOR_VACUUM_));
220  vocone->AddNode(vicone, 0, new TGeoTranslation( 0.0, 0.0, 0.0));
221  }
222  }
223  }
224  }
225 } // vc2020_03_20::CreateGeometry()
226 
227 // ---------------------------------------------------------------------------------------
228 // ---------------------------------------------------------------------------------------
229