Beampipe_geo.cpp
Go to the documentation of this file.
1 //==========================================================================
2 //
3 // <detector name ="DetName" type="Beampipe" >
4 // <layer id="#(int)" inner_r="#(double)" outer_z="#(double)" >
5 // <slice material="string" thickness="#(double)" >
6 // </layer>
7 // </detector>
8 //==========================================================================
9 #include "DD4hep/DetFactoryHelper.h"
10 #include "DD4hep/Printout.h"
11 #include "TMath.h"
12 
13 using namespace std;
14 using namespace dd4hep;
15 
16 static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector sens) {
17 
18  using namespace ROOT::Math;
19  xml_det_t x_det = e;
20  string det_name = x_det.nameStr();
21  Material air = det.air();
22  DetElement sdet (det_name,x_det.id());
23  Assembly assembly (det_name+"_assembly");
24  Material m_Al = det.material("Aluminum");
25  Material m_Be = det.material("Beryllium");
26 
27  PlacedVolume pv;
28  int n = 0;
29  std::cout << " BEAM PIPE \n";
30 
31  // Final Focusing Quads (FFQ)
32  // these are just guesses
33  double upstream_e_FFQ_face = 2.5*m;
34  double downstream_e_FFQ_face = 3.0*m;
35  double e_FFQ_length = 0.75*m;
36 
37  struct {
38  double length = 0.60*m;
39  double inner_radius = 3.0*cm;
40  double Au_thickness = 0.01*mm;
41  double Be1_thickness = 0.5*mm;
42  double coolant_thickness = 1.0*mm;
43  double Be2_thickness = 0.6*mm;
44  double z_position = 0.0*mm;
45  } bp0_pars;
46 
47  struct {
48  double length = 0.8*m;
49  double inner_radius = 3.0*cm;
50  double inner_radius2 = 6.0*cm;
51  double Au_thickness = 0.01*mm;
52  double Be1_thickness = 0.5*mm;
53  double coolant_thickness = 1.0*mm;
54  double Be2_thickness = 0.6*mm;
55  double z_position = 0.0*mm;
56  double taper_angle = 0.100*rad;
57  } bp1_pars;
58  bp1_pars.z_position = bp0_pars.length/2.0 + bp1_pars.length/2.0;
59  bp1_pars.inner_radius2 = bp1_pars.inner_radius + bp1_pars.length*TMath::Sin(bp1_pars.taper_angle);
60 
61  struct {
62  double length = 0.20*m;
63  double inner_radius = 6.0*cm;
64  double inner_radius2 = 3.1*cm;
65  double Au_thickness = 0.01*mm;
66  double Be1_thickness = 0.5*mm;
67  double coolant_thickness = 1.0*mm;
68  double Be2_thickness = 0.6*mm;
69  double z_position = 0.0*mm;
70  double taper_angle = 0.150*rad;
71  } bp2_pars;
72  bp2_pars.inner_radius = bp1_pars.inner_radius2;
73  bp2_pars.z_position = bp0_pars.length/2.0 + bp1_pars.length + bp2_pars.length/2.0;
74  bp2_pars.inner_radius2 = bp2_pars.inner_radius - bp2_pars.length*TMath::Sin(bp2_pars.taper_angle);
75 
76  // get the parameters
77  for(xml_coll_t bp(x_det,"beampipe"); bp; ++bp) {
78  std::cout << bp << std::endl;
79  xml_comp_t beampipe_comp = bp;
80  if(beampipe_comp.nameStr() == std::string("CentralBeamPipe")) {
81  std::cout << " CentralBeamPipe\n";
82  bp0_pars.inner_radius = getAttrOrDefault<double>(beampipe_comp,_Unicode(inner_raius),bp0_pars.inner_radius);
83  }
84  }
85 
86  Tube s_bp0(bp0_pars.inner_radius, bp0_pars.inner_radius+2.0*mm, bp0_pars.length/2.0);//,2.0*TMath::Pi()+0.01);
87  Cone s_bp1( bp1_pars.length/2.0, bp1_pars.inner_radius, bp1_pars.inner_radius+2.0*mm, bp1_pars.inner_radius2, bp1_pars.inner_radius2+2.0*mm);
88  Cone s_bp2( bp2_pars.length/2.0, bp2_pars.inner_radius, bp2_pars.inner_radius+2.0*mm, bp2_pars.inner_radius2, bp2_pars.inner_radius2+2.0*mm);
89 
90  Transform3D tr1( ROOT::Math::EulerAngles(0.0, 0.0*rad, 0.0), XYZVector{0,0,0} );
91  Transform3D tr_bp1( ROOT::Math::EulerAngles(0.0, 0.0*rad, 0.0), XYZVector{0,0,bp1_pars.z_position} );
92  Transform3D tr_bp2( ROOT::Math::EulerAngles(0.0, 0.0*rad, 0.0), XYZVector{0,0,bp2_pars.z_position} );
93 
94  Volume v_bp0( "tub0", s_bp0, m_Be);
95  pv = assembly.placeVolume(v_bp0,tr1);
96  Volume v_bp1( "pb1", s_bp1, m_Al);
97  pv = assembly.placeVolume(v_bp1,tr_bp1);
98  Volume v_bp2( "pb2", s_bp2, m_Al);
99  pv = assembly.placeVolume(v_bp2,tr_bp2);
100 
101  // ion upstream
102 
103  struct {
104  double length = 0.6*m;
105  double inner_radius = 3.0*cm;
106  double inner_radius2 = 6.0*cm;
107  double Au_thickness = 0.01*mm;
108  double Be1_thickness = 0.5*mm;
109  double coolant_thickness = 1.0*mm;
110  double Be2_thickness = 0.6*mm;
111  double z_position = 0.0*mm;
112  double taper_angle = 0.100*rad;
113  } bp3_pars;
114  bp3_pars.z_position = bp0_pars.length/2.0 + bp3_pars.length/2.0;
115  bp3_pars.inner_radius2 = bp3_pars.inner_radius + bp3_pars.length*TMath::Sin(bp3_pars.taper_angle);
116 
117  struct {
118  double length = 0.20*m;
119  double inner_radius = 6.0*cm;
120  double inner_radius2 = 3.0*cm;
121  double Au_thickness = 0.01*mm;
122  double Be1_thickness = 0.5*mm;
123  double coolant_thickness = 1.0*mm;
124  double Be2_thickness = 0.6*mm;
125  double z_position = 0.0*mm;
126  double taper_angle = 0.150*rad;
127  } bp4_pars;
128 
129  bp4_pars.inner_radius = bp3_pars.inner_radius2;
130  bp4_pars.length = (bp4_pars.inner_radius - bp4_pars.inner_radius2)/(TMath::Sin(bp4_pars.taper_angle));
131  bp4_pars.z_position = bp0_pars.length/2.0 + bp3_pars.length + bp4_pars.length/2.0;
132 
133  Cone s_bp3( bp3_pars.length/2.0, bp3_pars.inner_radius, bp3_pars.inner_radius+2.0*mm, bp3_pars.inner_radius2, bp3_pars.inner_radius2+2.0*mm);
134  Cone s_bp4( bp4_pars.length/2.0, bp4_pars.inner_radius, bp4_pars.inner_radius+2.0*mm, bp4_pars.inner_radius2, bp4_pars.inner_radius2+2.0*mm);
135 
136  Transform3D tr_bp3( ROOT::Math::EulerAngles(0.0, 180.0*degree, 0.0), XYZVector{0,0,-bp3_pars.z_position} );
137  Transform3D tr_bp4( ROOT::Math::EulerAngles(0.0, 180.0*degree, 0.0), XYZVector{0,0,-bp4_pars.z_position} );
138 
139  Volume v_bp3( "pb3", s_bp3, m_Al);
140  pv = assembly.placeVolume(v_bp3,tr_bp3);
141  Volume v_bp4( "pb4", s_bp4, m_Al);
142  pv = assembly.placeVolume(v_bp4,tr_bp4);
143 
144  v_bp0.setVisAttributes(det,"GrayVis");
145  v_bp1.setVisAttributes(det,"RedVis");
146  v_bp2.setVisAttributes(det,"GrayVis");
147  v_bp3.setVisAttributes(det,"RedVis");
148  v_bp4.setVisAttributes(det,"GrayVis");
149 
150  // ------------------------------------------
151  // ion downstream exit pipe
152  double ion_sep_flange_pos = bp0_pars.length/2.0 + bp1_pars.length + bp2_pars.length;
153  std::cout << "ion_sep_flange_pos " << ion_sep_flange_pos/cm << " m\n";
154 
155  double ion_exit_pipe_inner_radius = 1.5*cm;
156  double ion_exit_pipe_length = 7.0*m;
157  double ion_exit_pipe_angle = 0.01154*rad;
158  double ion_crossing_angle = 0.05*rad;
159  double ion_exit_pipe_zpos = bp0_pars.length/2.0 + bp1_pars.length + bp2_pars.length + ion_exit_pipe_length/2.0;
160  double ion_exit_pipe_inner_radius2 = ion_exit_pipe_inner_radius + ion_exit_pipe_length*TMath::Sin(ion_exit_pipe_angle);
161  Cone s_ion_exit(ion_exit_pipe_length/2.0,ion_exit_pipe_inner_radius, ion_exit_pipe_inner_radius+2.0*mm, ion_exit_pipe_inner_radius2, ion_exit_pipe_inner_radius2 + 2.0*mm);
162 
163  XYZVector ion_exit_pos{0,0,ion_exit_pipe_zpos};
164  RotationY ion_exit_rot( -1.0*ion_crossing_angle);
165  XYZVector ion_exit_pos2 = ion_exit_rot*ion_exit_pos;
166  Transform3D tr_ion_exit(ion_exit_rot , ion_exit_pos2 );
167  Volume v_ion_exit("ion_exit_pipe", s_ion_exit, m_Al);
168  pv = assembly.placeVolume(v_ion_exit,tr_ion_exit);
169  v_ion_exit.setVisAttributes(det,"OrangeVis");
170 
171  // ------------------------------------------
172  // ion upstream entrance pipe
173  double ion_enter_pipe_inner_radius = 1.5*cm;
174  double ion_enter_pipe_length = 7.0*m;
175  double ion_enter_pipe_angle = 0.01154*rad;
176  double ion_enter_pipe_zpos = bp0_pars.length/2.0 + bp3_pars.length + ion_enter_pipe_length/2.0;
177  double ion_enter_pipe_inner_radius2 = ion_enter_pipe_inner_radius + ion_enter_pipe_length*TMath::Sin(ion_enter_pipe_angle);
178  // note the order of the radii are switched here:
179  Cone s_ion_enter(ion_enter_pipe_length/2.0,
180  ion_enter_pipe_inner_radius2, ion_enter_pipe_inner_radius2 + 2.0*mm,
181  ion_enter_pipe_inner_radius, ion_enter_pipe_inner_radius+2.0*mm);
182  XYZVector ion_enter_pos{0,0,-ion_enter_pipe_zpos};
183  RotationY ion_enter_rot( -1.0*ion_crossing_angle);
184  XYZVector ion_enter_pos2 = ion_enter_rot*ion_enter_pos;
185  Transform3D tr_ion_enter(ion_enter_rot , ion_enter_pos2 );
186  Volume v_ion_enter("ion_enter_pipe", s_ion_enter, m_Al);
187  pv = assembly.placeVolume(v_ion_enter,tr_ion_enter);
188  v_ion_enter.setVisAttributes(det,"OrangeVis");
189 
190  // -------------------------------
191  // FFQs
192  double e_FFQ0_z_pos = upstream_e_FFQ_face + e_FFQ_length/2.0;
193  Tube s_FFQ0(3.0*cm, 8.0*cm, e_FFQ_length/2.0);
194  Transform3D tr_FFQ0( XYZVector{0,0, -e_FFQ0_z_pos} );
195  Volume v_FFQ0("ion_enter_pipe", s_FFQ0, m_Al);
196  pv = assembly.placeVolume(v_FFQ0,tr_FFQ0);
197  v_FFQ0.setVisAttributes(det,"BlueVis");
198 
199  //for(xml_coll_t i(x_det,_U(layer)); i; ++i, ++n) {
200  // xml_comp_t x_layer = i;
201  // string l_name = det_name+_toString(n,"_layer%d");
202  // double z = x_layer.outer_z();
203  // double rmin = x_layer.inner_r();
204  // double z_offset = 0.0;
205  // if(x_layer.hasAttr(_Unicode(z_offset))) {
206  // z_offset = x_layer.z_offset();
207  // }
208  // double r = rmin;
209  // DetElement layer(sdet,_toString(n,"layer%d"),x_layer.id());
210  // int m = 0;
211 
212  // printout(INFO, "GenericShapeJLEIC", "Creating a Generic Layer");
213  // for(xml_coll_t j(x_layer,_U(slice)); j; ++j, ++m) {
214  // xml_comp_t x_slice = j;
215  // Material mat = det.material(x_slice.materialStr());
216  // string s_name= l_name+_toString(m,"_slice%d");
217  // double thickness = x_slice.thickness();
218  // Tube s_tub(r, r+thickness,z);//,2.0*TMath::Pi()+0.01);
219  // Volume s_vol(s_name, s_tub, mat);
220 
221  // r += thickness;
222  // s_vol.setVisAttributes(det,x_det.visStr());
223  // pv = assembly.placeVolume(s_vol,Position(0, 0, z_offset));
224  // // Slices have no extra id. Take the ID of the layer!
225  // pv.addPhysVolID("slice",m);
226  // printout(INFO, "GenericShapeJLEIC", "Creating Generic Slice");
227  // }
228  // //cout << l_name << " " << rmin << " " << r << " " << z << endl;
229  //
230  //}
231 
232  pv = det.pickMotherVolume(sdet).placeVolume(assembly);
233  pv.addPhysVolID("system",sdet.id()).addPhysVolID("barrel",0);
234  sdet.setPlacement(pv);
235  assembly->GetShape()->ComputeBBox() ;
236  return sdet;
237 }
238 
239 DECLARE_DETELEMENT(JLEICBeampipe,create_detector)
Detector
Definition: DDG4.py:69
Namespace for the AIDA detector description toolkit.
static Ref_t create_detector(Detector &det, xml_h e, SensitiveDetector sens)