File indexing completed on 2025-06-30 07:56:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include "DD4hep/DetFactoryHelper.h"
0013 #include "DD4hep/Printout.h"
0014 #include "TMath.h"
0015 #include <XML/Helper.h>
0016 #include "XML/Utilities.h"
0017 #include "DD4hepDetectorHelper.h"
0018 #include <tuple>
0019
0020 using namespace std;
0021 using namespace dd4hep;
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector ) {
0038 using namespace ROOT::Math;
0039 xml_det_t x_det = e;
0040 string det_name = x_det.nameStr();
0041 xml_comp_t x_dettype = x_det.child(dd4hep::xml::Strng_t("type_flags"));
0042 unsigned int typeFlag = x_dettype.type();
0043 DetElement sdet(det_name, x_det.id());
0044 Assembly assembly(det_name + "_assembly");
0045
0046 xml::Component IP_pipe_c = x_det.child(_Unicode(IP_pipe));
0047
0048 Material IP_beampipe_wall_material =
0049 det.material(IP_pipe_c.attr<string>(_Unicode(wall_material)));
0050 Material IP_beampipe_coating_material =
0051 det.material(IP_pipe_c.attr<string>(_Unicode(coating_material)));
0052 Material m_Vacuum = det.material("Vacuum");
0053 Material m_Wall = det.material("StainlessSteelP506");
0054 Material m_Coating = det.material("Copper");
0055
0056
0057 double IP_beampipe_ID = IP_pipe_c.attr<double>(_Unicode(ID));
0058 double IP_beampipe_wall_thickness = IP_pipe_c.attr<double>(_Unicode(wall_thickness));
0059 double IP_beampipe_coating_thickness = IP_pipe_c.attr<double>(_Unicode(coating_thickness));
0060 double IP_acts_beampipe_OD = IP_beampipe_ID - 5.0 * mm;
0061 double IP_acts_beampipe_ID = IP_acts_beampipe_OD - 1.0 * mm;
0062
0063 double upstream_straight_length = IP_pipe_c.attr<double>(_Unicode(upstream_straight_length));
0064 double downstream_straight_length = IP_pipe_c.attr<double>(_Unicode(downstream_straight_length));
0065
0066
0067 auto wallVis = det.visAttributes(x_det.attr<std::string>(_Unicode(vis_wall)));
0068 auto coatingVis = det.visAttributes(x_det.attr<std::string>(_Unicode(vis_coating)));
0069 auto IPwallVis = det.visAttributes(x_det.attr<std::string>(_Unicode(vis_IPwall)));
0070 auto IPcoatingVis = det.visAttributes(x_det.attr<std::string>(_Unicode(vis_IPcoating)));
0071
0072
0073 wallVis.setColor(0.0, 0.0, 1.0, 1.0);
0074 coatingVis.setColor(1.0, 0.0, 0.0, 1.0);
0075 IPwallVis.setColor(0.0, 1.0, 0.0, 1.0);
0076 IPcoatingVis.setColor(1.0, 1.0, 0.0, 1.0);
0077
0078
0079 Tube central_tube(0.5 * IP_acts_beampipe_ID, 0.5 * IP_acts_beampipe_OD,
0080 0.5 * (upstream_straight_length + downstream_straight_length));
0081 Volume central_volume("acts_central_beampipe_vol", central_tube, m_Vacuum);
0082 const double central_offset = -.5 * (upstream_straight_length - downstream_straight_length);
0083 DetElement central_det(sdet, "acts_beampipe_central", 1);
0084
0085
0086 central_det.setTypeFlag(typeFlag);
0087 auto& params = DD4hepDetectorHelper::ensureExtension<dd4hep::rec::VariantParameters>(central_det);
0088 int nBinPhi = 144;
0089 int nBinZ = 10;
0090 params.set<bool>("layer_material", true);
0091 params.set<bool>("layer_material_representing", true);
0092 params.set<int>("layer_material_representing_binPhi", nBinPhi);
0093 params.set<int>("layer_material_representing_binZ", nBinZ);
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 Tube downstream_IP_tube(IP_beampipe_ID / 2.0, IP_beampipe_ID / 2.0 + IP_beampipe_wall_thickness,
0107 downstream_straight_length / 2.0);
0108 Tube downstream_IP_coating(IP_beampipe_ID / 2.0 - IP_beampipe_coating_thickness,
0109 IP_beampipe_ID / 2.0, downstream_straight_length / 2.0);
0110 Tube downstream_IP_vacuum_padding(IP_acts_beampipe_OD / 2.0,
0111 IP_beampipe_ID / 2.0 - IP_beampipe_coating_thickness,
0112 downstream_straight_length / 2.0);
0113 Tube downstream_IP_acts_beampipe(IP_acts_beampipe_ID / 2.0, IP_acts_beampipe_OD / 2.0,
0114 downstream_straight_length / 2.0);
0115 Tube downstream_IP_vacuum_fill(0.0, IP_acts_beampipe_ID / 2.0, downstream_straight_length / 2.0);
0116
0117 Tube upstream_IP_tube(IP_beampipe_ID / 2.0, IP_beampipe_ID / 2.0 + IP_beampipe_wall_thickness,
0118 upstream_straight_length / 2.0);
0119 Tube upstream_IP_coating(IP_beampipe_ID / 2.0 - IP_beampipe_coating_thickness,
0120 IP_beampipe_ID / 2.0, upstream_straight_length / 2.0);
0121 Tube upstream_IP_vacuum_padding(IP_acts_beampipe_OD / 2.0,
0122 IP_beampipe_ID / 2.0 - IP_beampipe_coating_thickness,
0123 upstream_straight_length / 2.0);
0124 Tube upstream_IP_acts_beampipe(IP_acts_beampipe_ID / 2.0, IP_acts_beampipe_OD / 2.0,
0125 upstream_straight_length / 2.0);
0126 Tube upstream_IP_vacuum_fill(0.0, IP_acts_beampipe_ID / 2.0, upstream_straight_length / 2.0);
0127
0128
0129 Volume v_downstream_IP_vacuum_fill("v_downstream_IP_vacuum_fill", downstream_IP_vacuum_fill,
0130 m_Vacuum);
0131 Volume v_downstream_IP_acts_beampipe("v_downstream_IP_acts_beampipe", downstream_IP_acts_beampipe,
0132 m_Vacuum);
0133 Volume v_downstream_IP_vacuum_padding("v_downstream_IP_vacuum_padding",
0134 downstream_IP_vacuum_padding, m_Vacuum);
0135 Volume v_downstream_IP_coating("v_downstream_IP_coating", downstream_IP_coating,
0136 IP_beampipe_coating_material);
0137 Volume v_downstream_IP_tube("v_downstream_IP_tube", downstream_IP_tube,
0138 IP_beampipe_wall_material);
0139 Volume v_upstream_IP_vacuum_fill("v_upstream_IP_vacuum_fill", upstream_IP_vacuum_fill, m_Vacuum);
0140 Volume v_upstream_IP_acts_beampipe("v_upstream_IP_acts_beampipe", upstream_IP_acts_beampipe,
0141 m_Vacuum);
0142 Volume v_upstream_IP_vacuum_padding("v_upstream_IP_vacuum_padding", upstream_IP_vacuum_padding,
0143 m_Vacuum);
0144 Volume v_upstream_IP_coating("v_upstream_IP_coating", upstream_IP_coating,
0145 IP_beampipe_coating_material);
0146 Volume v_upstream_IP_tube("v_upstream_IP_tube", upstream_IP_tube, IP_beampipe_wall_material);
0147
0148
0149 sdet.setAttributes(det, v_upstream_IP_coating, x_det.regionStr(), x_det.limitsStr(),
0150 x_det.attr<std::string>(_Unicode(vis_IPcoating)));
0151 sdet.setAttributes(det, v_upstream_IP_tube, x_det.regionStr(), x_det.limitsStr(),
0152 x_det.attr<std::string>(_Unicode(vis_IPwall)));
0153 sdet.setAttributes(det, v_downstream_IP_coating, x_det.regionStr(), x_det.limitsStr(),
0154 x_det.attr<std::string>(_Unicode(vis_IPcoating)));
0155 sdet.setAttributes(det, v_downstream_IP_tube, x_det.regionStr(), x_det.limitsStr(),
0156 x_det.attr<std::string>(_Unicode(vis_IPwall)));
0157
0158
0159 assembly.placeVolume(v_upstream_IP_vacuum_fill, Position(0, 0, -upstream_straight_length / 2.0));
0160 central_volume.placeVolume(v_upstream_IP_acts_beampipe,
0161 Position(0, 0, -upstream_straight_length / 2.0 - central_offset));
0162 assembly.placeVolume(v_upstream_IP_vacuum_padding,
0163 Position(0, 0, -upstream_straight_length / 2.0));
0164 assembly.placeVolume(v_upstream_IP_coating, Position(0, 0, -upstream_straight_length / 2.0));
0165 assembly.placeVolume(v_upstream_IP_tube, Position(0, 0, -upstream_straight_length / 2.0));
0166
0167 assembly.placeVolume(v_downstream_IP_vacuum_fill,
0168 Position(0, 0, downstream_straight_length / 2.0));
0169 central_volume.placeVolume(v_downstream_IP_acts_beampipe,
0170 Position(0, 0, downstream_straight_length / 2.0 - central_offset));
0171 assembly.placeVolume(v_downstream_IP_vacuum_padding,
0172 Position(0, 0, downstream_straight_length / 2.0));
0173 assembly.placeVolume(v_downstream_IP_coating, Position(0, 0, downstream_straight_length / 2.0));
0174 assembly.placeVolume(v_downstream_IP_tube, Position(0, 0, downstream_straight_length / 2.0));
0175
0176 auto central_pv = assembly.placeVolume(central_volume, Position(0, 0, +central_offset));
0177 central_det.setPlacement(central_pv);
0178
0179
0180
0181 auto zplane_to_polycones = [](xml::Component& x_pipe) {
0182 std::vector<double> zero, z;
0183 std::vector<double> rmax_wall, rmax_coating, rmax_vacuum;
0184 std::vector<double> rmin_wall, rmin_coating, rmin_vacuum;
0185
0186 auto wall_thickness = getAttrOrDefault(x_pipe, _Unicode(wall_thickness), 1 * mm);
0187 auto coating_thickness = getAttrOrDefault(x_pipe, _Unicode(coating_thickness), 30 * um);
0188
0189 for (xml_coll_t x_zplane_i(x_pipe, _Unicode(zplane)); x_zplane_i; ++x_zplane_i) {
0190 xml_comp_t x_zplane = x_zplane_i;
0191
0192 z.push_back(x_zplane.attr<double>(_Unicode(z)));
0193
0194 rmax_wall.push_back(x_zplane.attr<double>(_Unicode(ID)) / 2.0 + wall_thickness);
0195 rmax_coating.push_back(x_zplane.attr<double>(_Unicode(ID)) / 2.0);
0196 rmax_vacuum.push_back(x_zplane.attr<double>(_Unicode(ID)) / 2.0 - coating_thickness);
0197
0198 rmin_wall.push_back(x_zplane.attr<double>(_Unicode(ID)) / 2.0);
0199 rmin_coating.push_back(x_zplane.attr<double>(_Unicode(ID)) / 2.0 - coating_thickness);
0200 rmin_vacuum.push_back(0);
0201 }
0202 return std::tuple<Polycone, Polycone, Polycone>({0, 2.0 * M_PI, rmin_wall, rmax_wall, z},
0203 {0, 2.0 * M_PI, rmin_coating, rmax_coating, z},
0204 {0, 2.0 * M_PI, rmin_vacuum, rmax_vacuum, z});
0205 };
0206
0207
0208 auto create_racetrack_solids = [](xml::Component& x_racetrack) {
0209
0210 double semiCircle_rmin = getAttrOrDefault(x_racetrack, _Unicode(semiCircle_rmin), 0.0);
0211 double wall_thickness = getAttrOrDefault(x_racetrack, _Unicode(wall_thickness), 0.0);
0212 double coating_thickness = getAttrOrDefault(x_racetrack, _Unicode(coating_thickness), 0.0);
0213 double length = getAttrOrDefault(x_racetrack, _Unicode(length), 0.0);
0214 double rectangle_h = getAttrOrDefault(x_racetrack, _Unicode(rectangle_h), 0.0);
0215
0216
0217 Tube wall_semiCircle(0, semiCircle_rmin + wall_thickness, length / 2.);
0218 Box wall_rectangle(semiCircle_rmin + wall_thickness, rectangle_h / 2., length / 2.);
0219
0220 Tube coating_semiCircle(0, semiCircle_rmin, length / 2.);
0221 Box coating_rectangle(semiCircle_rmin, rectangle_h / 2., length / 2.);
0222
0223 Tube vacuum_semiCircle(0, semiCircle_rmin - coating_thickness, length / 2.);
0224 Box vacuum_rectangle(semiCircle_rmin - coating_thickness, rectangle_h / 2., length / 2.);
0225
0226
0227 Transform3D upShift_tf(RotationZYX(0, 0, 0), Position(0, rectangle_h / 2., 0));
0228 Transform3D downShift_tf(RotationZYX(0, 0, 0), Position(0, -rectangle_h / 2., 0));
0229
0230 UnionSolid wall_solid, coating_solid, vacuum_solid;
0231
0232 wall_solid = UnionSolid("wall_solid_tmp", wall_rectangle, wall_semiCircle, upShift_tf);
0233 wall_solid = UnionSolid("wall_solid", wall_solid, wall_semiCircle, downShift_tf);
0234
0235 coating_solid =
0236 UnionSolid("coating_solid_tmp", coating_rectangle, coating_semiCircle, upShift_tf);
0237 coating_solid = UnionSolid("coating_solid", coating_solid, coating_semiCircle, downShift_tf);
0238
0239 vacuum_solid = UnionSolid("vacuum_solid_tmp", vacuum_rectangle, vacuum_semiCircle, upShift_tf);
0240 vacuum_solid = UnionSolid("vacuum_solid", vacuum_solid, vacuum_semiCircle, downShift_tf);
0241
0242
0243 BooleanSolid wall_subtract, coating_subtract, vacuum_subtract;
0244
0245 wall_subtract = SubtractionSolid("wall_subtract", wall_solid, coating_solid, Transform3D());
0246 coating_subtract =
0247 SubtractionSolid("coating_subtract", coating_solid, vacuum_solid, Transform3D());
0248 vacuum_subtract = vacuum_solid;
0249
0250 return std::tuple<Solid, Solid, Solid>(wall_subtract, coating_subtract, vacuum_subtract);
0251 };
0252
0253
0254 auto build_interface_cones = [](std::vector<double>& wall_interface_cone1_rmax,
0255 std::vector<double>& coating_interface_cone1_rmax,
0256 std::vector<double>& vacuum_interface_cone1_rmax,
0257 std::vector<double>& wall_interface_cone2_rmax,
0258 std::vector<double>& coating_interface_cone2_rmax,
0259 std::vector<double>& vacuum_interface_cone2_rmax,
0260 std::vector<double>& interface_rmin,
0261 std::vector<double>& interface_z, double offset1_y,
0262 double offset2_y) {
0263
0264 Polycone wall_interface_cone1(0, 2.0 * M_PI, interface_rmin, wall_interface_cone1_rmax,
0265 interface_z);
0266 Polycone wall_interface_cone2(0, 2.0 * M_PI, interface_rmin, wall_interface_cone2_rmax,
0267 interface_z);
0268
0269 Polycone coating_interface_cone1(0, 2.0 * M_PI, interface_rmin, coating_interface_cone1_rmax,
0270 interface_z);
0271 Polycone coating_interface_cone2(0, 2.0 * M_PI, interface_rmin, coating_interface_cone2_rmax,
0272 interface_z);
0273
0274 Polycone vacuum_interface_cone1(0, 2.0 * M_PI, interface_rmin, vacuum_interface_cone1_rmax,
0275 interface_z);
0276 Polycone vacuum_interface_cone2(0, 2.0 * M_PI, interface_rmin, vacuum_interface_cone2_rmax,
0277 interface_z);
0278
0279 Transform3D tf1(RotationZYX(0, 0, 0), Position(0, offset1_y, 0));
0280 Transform3D tf2(RotationZYX(0, 0, 0), Position(0, offset2_y, 0));
0281
0282
0283
0284 auto wall_interface_final = UnionSolid(wall_interface_cone1, wall_interface_cone2, tf1);
0285 wall_interface_final = UnionSolid(wall_interface_final, wall_interface_cone2, tf2);
0286 Solid wall_interface_vac_cut(
0287 wall_interface_final);
0288
0289 wall_interface_final =
0290 SubtractionSolid(wall_interface_final, coating_interface_cone1, Transform3D());
0291 wall_interface_final = SubtractionSolid(wall_interface_final, coating_interface_cone2, tf1);
0292 wall_interface_final = SubtractionSolid(wall_interface_final, coating_interface_cone2, tf2);
0293
0294
0295
0296 auto coating_interface_final =
0297 UnionSolid(coating_interface_cone1, coating_interface_cone2, tf1);
0298 coating_interface_final = UnionSolid(coating_interface_final, coating_interface_cone2, tf2);
0299
0300 coating_interface_final =
0301 SubtractionSolid(coating_interface_final, vacuum_interface_cone1, Transform3D());
0302 coating_interface_final =
0303 SubtractionSolid(coating_interface_final, vacuum_interface_cone2, tf1);
0304 coating_interface_final =
0305 SubtractionSolid(coating_interface_final, vacuum_interface_cone2, tf2);
0306
0307
0308
0309 auto vacuum_interface_final = UnionSolid(vacuum_interface_cone1, vacuum_interface_cone2, tf1);
0310 vacuum_interface_final = UnionSolid(vacuum_interface_final, vacuum_interface_cone2, tf2);
0311
0312 return std::tuple<Solid, Solid, Solid, Solid>(wall_interface_final, coating_interface_final,
0313 vacuum_interface_final, wall_interface_vac_cut);
0314 };
0315
0316
0317 auto create_interface_solids = [&](xml::Component& x_racetrack) {
0318
0319 double semiCircle_rmin = getAttrOrDefault(x_racetrack, _Unicode(semiCircle_rmin), 2.3 * cm);
0320 double wall_thickness = getAttrOrDefault(x_racetrack, _Unicode(wall_thickness), 1.0 * mm);
0321 double coating_thickness = getAttrOrDefault(x_racetrack, _Unicode(coating_thickness), 30 * um);
0322 double rectangle_h = getAttrOrDefault(x_racetrack, _Unicode(rectangle_h), 1.6 * cm);
0323 double cylRadius1 = getAttrOrDefault(x_racetrack, _Unicode(cylRadius1), 6.2 / 2. * cm);
0324 double cylRadius2 = getAttrOrDefault(x_racetrack, _Unicode(cylRadius2), 2.6 / 2. * cm);
0325 double straight_pipe_endz =
0326 getAttrOrDefault(x_racetrack, _Unicode(straight_pipe_endz), 66.385 * cm);
0327 double offset_z = getAttrOrDefault(x_racetrack, _Unicode(offset_z), 72.385 * cm);
0328 double length = getAttrOrDefault(x_racetrack, _Unicode(length), 125.420 * cm);
0329 double interface_length_1 =
0330 getAttrOrDefault(x_racetrack, _Unicode(interface_length_1), 6.0 * cm);
0331 double interface_length_2 =
0332 getAttrOrDefault(x_racetrack, _Unicode(interface_length_2), 13.495 * cm);
0333
0334 if (cylRadius2 - rectangle_h / 2. < 0) {
0335 printout(ERROR, "IP6BeamPipe_geo", "Negative cone base size: (%f - %f/2) < 0", cylRadius2,
0336 rectangle_h);
0337 throw std::runtime_error("IP6BeamPipe failed to build a cone");
0338 }
0339
0340 std::vector<double> interface_rmin = {0, 0};
0341
0342
0343 std::vector<double> interface_z_1 = {straight_pipe_endz,
0344 straight_pipe_endz + interface_length_1};
0345
0346 std::vector<double> interface_z_2 = {offset_z + length, offset_z + length + interface_length_2};
0347
0348
0349
0350 std::vector<double> wall_interface_cone1_rmax_1 = {cylRadius1 + wall_thickness,
0351 semiCircle_rmin + wall_thickness};
0352 std::vector<double> coating_interface_cone1_rmax_1 = {cylRadius1, semiCircle_rmin};
0353 std::vector<double> vacuum_interface_cone1_rmax_1 = {cylRadius1 - coating_thickness,
0354 semiCircle_rmin - coating_thickness};
0355
0356 std::vector<double> wall_interface_cone1_rmax_2 = {semiCircle_rmin + wall_thickness,
0357 cylRadius2 + wall_thickness};
0358 std::vector<double> coating_interface_cone1_rmax_2 = {semiCircle_rmin, cylRadius2};
0359 std::vector<double> vacuum_interface_cone1_rmax_2 = {semiCircle_rmin - coating_thickness,
0360 cylRadius2 - coating_thickness};
0361
0362
0363
0364 std::vector<double> wall_interface_cone2_rmax_1 = {semiCircle_rmin + wall_thickness,
0365 semiCircle_rmin + wall_thickness};
0366 std::vector<double> coating_interface_cone2_rmax_1 = {semiCircle_rmin, semiCircle_rmin};
0367 std::vector<double> vacuum_interface_cone2_rmax_1 = {semiCircle_rmin - coating_thickness,
0368 semiCircle_rmin - coating_thickness};
0369
0370 std::vector<double> wall_interface_cone2_rmax_2 = {
0371 semiCircle_rmin + wall_thickness, (cylRadius2 - rectangle_h / 2.) + wall_thickness};
0372 std::vector<double> coating_interface_cone2_rmax_2 = {semiCircle_rmin,
0373 (cylRadius2 - rectangle_h / 2.)};
0374 std::vector<double> vacuum_interface_cone2_rmax_2 = {
0375 semiCircle_rmin - coating_thickness, (cylRadius2 - rectangle_h / 2.) - coating_thickness};
0376
0377
0378 double offset1_y = rectangle_h / 2.;
0379 double offset2_y = -rectangle_h / 2.;
0380
0381
0382
0383 auto interface_cones_1 = build_interface_cones(
0384 wall_interface_cone1_rmax_1, coating_interface_cone1_rmax_1, vacuum_interface_cone1_rmax_1,
0385 wall_interface_cone2_rmax_1, coating_interface_cone2_rmax_1, vacuum_interface_cone2_rmax_1,
0386 interface_rmin, interface_z_1, offset1_y, offset2_y);
0387
0388 auto interface_cones_2 = build_interface_cones(
0389 wall_interface_cone1_rmax_2, coating_interface_cone1_rmax_2, vacuum_interface_cone1_rmax_2,
0390 wall_interface_cone2_rmax_2, coating_interface_cone2_rmax_2, vacuum_interface_cone2_rmax_2,
0391 interface_rmin, interface_z_2, offset1_y, offset2_y);
0392
0393 return std::tuple<Solid, Solid, Solid, Solid, Solid, Solid, Solid, Solid>(
0394 std::get<0>(interface_cones_1), std::get<1>(interface_cones_1),
0395 std::get<2>(interface_cones_1), std::get<3>(interface_cones_1),
0396 std::get<0>(interface_cones_2), std::get<1>(interface_cones_2),
0397 std::get<2>(interface_cones_2), std::get<3>(interface_cones_2));
0398 };
0399
0400
0401 auto create_volumes = [&](const std::string& name, xml::Component& x_pipe1,
0402 xml::Component& x_pipe2, xml_coll_t& x_additional_subtraction_i) {
0403 auto pipe1_polycones = zplane_to_polycones(x_pipe1);
0404 auto pipe2_polycones = zplane_to_polycones(x_pipe2);
0405
0406 auto crossing_angle = getAttrOrDefault(x_pipe2, _Unicode(crossing_angle), 0.0);
0407 auto axis_intersection = getAttrOrDefault(x_pipe2, _Unicode(axis_intersection), 0.0);
0408
0409 auto tf = Transform3D(Position(0, 0, axis_intersection)) *
0410 Transform3D(RotationY(crossing_angle)) *
0411 Transform3D(Position(0, 0, -axis_intersection));
0412
0413
0414 BooleanSolid wall_union =
0415 UnionSolid(std::get<0>(pipe1_polycones), std::get<0>(pipe2_polycones), tf);
0416 BooleanSolid coating_union =
0417 UnionSolid(std::get<1>(pipe1_polycones), std::get<1>(pipe2_polycones), tf);
0418 BooleanSolid vacuum_union =
0419 UnionSolid(std::get<2>(pipe1_polycones), std::get<2>(pipe2_polycones), tf);
0420
0421 BooleanSolid wall_racetrack_final, coating_racetrack_final;
0422 BooleanSolid wall_interface_final_1, coating_interface_final_1;
0423 BooleanSolid wall_interface_final_2, coating_interface_final_2;
0424 BooleanSolid vacuum_interface, lepton_pipe_vac;
0425
0426
0427
0428 std::vector<double> posz_vac = {
0429 getAttrOrDefault(x_pipe1, _Unicode(lepton_pipe_vac_tube_startz), 66.10 * cm),
0430 getAttrOrDefault(x_pipe1, _Unicode(lepton_pipe_vac_tube_endz), 494.556 * cm)};
0431 std::vector<double> rmin_vac = {0, 0};
0432 std::vector<double> rmax_vac = {
0433 getAttrOrDefault(x_pipe1, _Unicode(ipBeampipe_ID), 6.2 / 2. * cm) / 2. +
0434 getAttrOrDefault(x_pipe1, _Unicode(wall_thickness), 1.0 * mm),
0435 getAttrOrDefault(x_pipe1, _Unicode(ipBeampipe_ID), 6.2 / 2. * cm) / 2. +
0436 getAttrOrDefault(x_pipe1, _Unicode(wall_thickness), 1.0 * mm)};
0437 Polycone lepton_pipe_vac_tube(0, 2.0 * M_PI, rmin_vac, rmax_vac, posz_vac);
0438
0439
0440 if (name == "downstream") {
0441
0442 vacuum_union = SubtractionSolid("vacuum_union", vacuum_union, lepton_pipe_vac_tube);
0443
0444 xml::Component racetrack_lepton_c = x_pipe1.child(_Unicode(racetrack_lepton));
0445
0446
0447 double cylRadius1 =
0448 getAttrOrDefault(racetrack_lepton_c, _Unicode(cylRadius1), 6.2 / 2. * cm);
0449 double rtRadius =
0450 getAttrOrDefault(racetrack_lepton_c, _Unicode(semiCircle_rmin), 2.3 * cm);
0451 double wall_thickness =
0452 getAttrOrDefault(racetrack_lepton_c, _Unicode(wall_thickness), 1.0 * mm);
0453 double coating_thickness =
0454 getAttrOrDefault(racetrack_lepton_c, _Unicode(coating_thickness), 30.0 * um);
0455 double straight_pipe_startz =
0456 getAttrOrDefault(racetrack_lepton_c, _Unicode(straight_pipe_startz), 66.10 * cm);
0457 double straight_pipe_endz =
0458 getAttrOrDefault(racetrack_lepton_c, _Unicode(straight_pipe_endz), 66.385 * cm);
0459 double elliptical_cut_rx_1 =
0460 getAttrOrDefault(racetrack_lepton_c, _Unicode(elliptical_cut_rx_1), 0.305 * m);
0461 double elliptical_cut_ry_1 =
0462 getAttrOrDefault(racetrack_lepton_c, _Unicode(elliptical_cut_ry_1), 0.021 * m);
0463 double elliptical_cut_rx_2 =
0464 getAttrOrDefault(racetrack_lepton_c, _Unicode(elliptical_cut_rx_2), 0.152 * m);
0465 double elliptical_cut_ry_2 =
0466 getAttrOrDefault(racetrack_lepton_c, _Unicode(elliptical_cut_ry_2), 0.021 * m);
0467 double rectangular_cut_a =
0468 getAttrOrDefault(racetrack_lepton_c, _Unicode(rectangular_cut_a), 0.81 / 2. * m);
0469 double rectangular_cut_b =
0470 getAttrOrDefault(racetrack_lepton_c, _Unicode(rectangular_cut_b), 0.021 * m);
0471 double elliptical_cut_dz =
0472 getAttrOrDefault(racetrack_lepton_c, _Unicode(elliptical_cut_dz), 0.7 * cm);
0473 double elliptical_cut_offset_z_1 =
0474 getAttrOrDefault(racetrack_lepton_c, _Unicode(elliptical_cut_offset_z_1), (0.976) * m);
0475 double elliptical_cut_offset_z_2 =
0476 getAttrOrDefault(racetrack_lepton_c, _Unicode(elliptical_cut_offset_z_2),
0477 (0.976 + 0.810) * m);
0478 double rectangular_cut_offset_z =
0479 getAttrOrDefault(racetrack_lepton_c, _Unicode(rectangular_cut_offset_z),
0480 (0.976 + 0.810 / 2.) * m);
0481
0482
0483 auto racetrack_solids = create_racetrack_solids(racetrack_lepton_c);
0484
0485
0486 auto interface_solids = create_interface_solids(racetrack_lepton_c);
0487 vacuum_interface =
0488 UnionSolid("vacuum_interface", std::get<2>(interface_solids),
0489 std::get<6>(interface_solids), Transform3D());
0490
0491
0492 std::vector<double> z = {straight_pipe_startz, straight_pipe_endz};
0493 std::vector<double> wall_rmin = {cylRadius1, cylRadius1};
0494 std::vector<double> wall_rmax = {cylRadius1 + wall_thickness, cylRadius1 + wall_thickness};
0495 std::vector<double> coating_rmin = {cylRadius1 - coating_thickness,
0496 cylRadius1 - coating_thickness};
0497 std::vector<double> coating_rmax = wall_rmin;
0498
0499 Polycone wall_pipe(0, 2.0 * M_PI, wall_rmin, wall_rmax, z);
0500 Polycone coating_pipe(0, 2.0 * M_PI, coating_rmin, coating_rmax, z);
0501
0502 Polycone wall_pipe_2(0, 2.0 * M_PI, wall_rmin, wall_rmax, z);
0503
0504
0505 double offset_z = getAttrOrDefault(racetrack_lepton_c, _Unicode(offset_z), 0.0);
0506 double length = getAttrOrDefault(racetrack_lepton_c, _Unicode(length), 0.0);
0507 Transform3D racetrack_tf(RotationZYX(0, 0, 0), Position(0, 0, offset_z + length / 2.));
0508
0509 UnionSolid wall_racetrack_pipe =
0510 UnionSolid("wall_racetrack_pipe", wall_pipe, std::get<0>(racetrack_solids), racetrack_tf);
0511 UnionSolid coating_racetrack_pipe = UnionSolid("coating_racetrack_pipe", coating_pipe,
0512 std::get<1>(racetrack_solids), racetrack_tf);
0513
0514
0515 lepton_pipe_vac = SubtractionSolid("vacuum_racetrack_cut_1", lepton_pipe_vac_tube,
0516 wall_racetrack_pipe, Transform3D());
0517 lepton_pipe_vac = SubtractionSolid("vacuum_racetrack_cut_2", lepton_pipe_vac,
0518 coating_racetrack_pipe, Transform3D());
0519 lepton_pipe_vac = SubtractionSolid("vacuum_interface_cut_3", lepton_pipe_vac,
0520 std::get<3>(interface_solids), Transform3D());
0521 lepton_pipe_vac = SubtractionSolid("vacuum_interface_cut_4", lepton_pipe_vac,
0522 std::get<7>(interface_solids), Transform3D());
0523
0524 lepton_pipe_vac =
0525 SubtractionSolid("vacuum_interface_cut_5", lepton_pipe_vac, wall_union, Transform3D());
0526 lepton_pipe_vac =
0527 SubtractionSolid("vacuum_interface_cut_6", lepton_pipe_vac, coating_union, Transform3D());
0528
0529
0530 EllipticalTube elliptical_cut_1("elliptical_cut_1", elliptical_cut_rx_1, elliptical_cut_ry_1,
0531 elliptical_cut_dz);
0532 EllipticalTube elliptical_cut_2("elliptical_cut_2", elliptical_cut_rx_2, elliptical_cut_ry_2,
0533 elliptical_cut_dz);
0534 Box rectangular_cut_3("rectangular_cut_3", rectangular_cut_a, rectangular_cut_b,
0535 elliptical_cut_dz);
0536 Transform3D tf_cut_1(RotationZYX(0, M_PI_2, 0),
0537 Position(-rtRadius, 0, elliptical_cut_offset_z_1));
0538 Transform3D tf_cut_2(RotationZYX(0, M_PI_2, 0),
0539 Position(-rtRadius, 0, elliptical_cut_offset_z_2));
0540 Transform3D tf_cut_3(RotationZYX(0, M_PI_2, 0),
0541 Position(-rtRadius, 0, rectangular_cut_offset_z));
0542
0543
0544 SubtractionSolid wall_racetrack_cut_1 =
0545 SubtractionSolid("wall_racetrack_cut_1", wall_racetrack_pipe, elliptical_cut_1, tf_cut_1);
0546 SubtractionSolid wall_racetrack_cut_2 = SubtractionSolid(
0547 "wall_racetrack_cut_1", wall_racetrack_cut_1, elliptical_cut_2, tf_cut_2);
0548 wall_racetrack_final = SubtractionSolid("wall_racetrack_final", wall_racetrack_cut_2,
0549 rectangular_cut_3, tf_cut_3);
0550
0551
0552 SubtractionSolid coating_racetrack_cut_1 = SubtractionSolid(
0553 "coating_racetrack_cut_1", coating_racetrack_pipe, elliptical_cut_1, tf_cut_1);
0554 SubtractionSolid coating_racetrack_cut_2 = SubtractionSolid(
0555 "coating_racetrack_cut_2", coating_racetrack_cut_1, elliptical_cut_2, tf_cut_2);
0556 coating_racetrack_final = SubtractionSolid("coating_racetrack_final", coating_racetrack_cut_2,
0557 rectangular_cut_3, tf_cut_3);
0558
0559 lepton_pipe_vac =
0560 UnionSolid("lepton_pipe_vac_uni_7", lepton_pipe_vac, elliptical_cut_1, tf_cut_1);
0561 lepton_pipe_vac =
0562 UnionSolid("lepton_pipe_vac_uni_8", lepton_pipe_vac, elliptical_cut_2, tf_cut_2);
0563 lepton_pipe_vac =
0564 UnionSolid("lepton_pipe_vac_uni_9", lepton_pipe_vac, rectangular_cut_3, tf_cut_3);
0565
0566
0567 vacuum_union =
0568 SubtractionSolid("vacuum_union_sub_1", vacuum_union, elliptical_cut_1, tf_cut_1);
0569 vacuum_union =
0570 SubtractionSolid("vacuum_union_sub_2", vacuum_union, elliptical_cut_2, tf_cut_2);
0571 vacuum_union =
0572 SubtractionSolid("vacuum_union_sub_3", vacuum_union, rectangular_cut_3, tf_cut_3);
0573
0574
0575 wall_interface_final_1 = SubtractionSolid(
0576 "wall_interface_final_1", std::get<0>(interface_solids), elliptical_cut_1, tf_cut_1);
0577
0578
0579 coating_interface_final_1 = SubtractionSolid(
0580 "coating_interface_final_1", std::get<1>(interface_solids), elliptical_cut_1, tf_cut_1);
0581
0582
0583 vacuum_interface =
0584 SubtractionSolid("vacuum_interface", vacuum_interface, elliptical_cut_1, tf_cut_1);
0585
0586
0587 wall_interface_final_2 = std::get<4>(interface_solids);
0588 coating_interface_final_2 = std::get<5>(interface_solids);
0589 }
0590
0591 Solid wall_racetrack(wall_racetrack_final);
0592 Solid coating_racetrack(coating_racetrack_final);
0593 Solid wall_interface_1(wall_interface_final_1);
0594 Solid coating_interface_1(coating_interface_final_1);
0595 Solid wall_interface_2(wall_interface_final_2);
0596 Solid coating_interface_2(coating_interface_final_2);
0597
0598
0599 for (; x_additional_subtraction_i; ++x_additional_subtraction_i) {
0600 xml_comp_t x_additional_subtraction = x_additional_subtraction_i;
0601 auto additional_polycones = zplane_to_polycones(x_additional_subtraction);
0602 auto additional_crossing_angle =
0603 getAttrOrDefault(x_additional_subtraction, _Unicode(crossing_angle), 0.0);
0604 auto additional_axis_intersection =
0605 getAttrOrDefault(x_additional_subtraction, _Unicode(axis_intersection), 0.0);
0606 auto additional_tf = Transform3D(Position(0, 0, additional_axis_intersection)) *
0607 Transform3D(RotationY(additional_crossing_angle)) *
0608 Transform3D(Position(0, 0, -additional_axis_intersection));
0609
0610 wall_union = SubtractionSolid(wall_union, std::get<2>(additional_polycones), additional_tf);
0611 coating_union =
0612 SubtractionSolid(coating_union, std::get<2>(additional_polycones), additional_tf);
0613 vacuum_union =
0614 SubtractionSolid(vacuum_union, std::get<2>(additional_polycones), additional_tf);
0615 }
0616
0617 Solid wall, coating, vacuum, wall_ipflange, coating_ipflange, vacuum_ipflange;
0618
0619 if (name == "upstream")
0620 {
0621
0622 coating = SubtractionSolid(coating_union, vacuum_union);
0623
0624
0625 wall = SubtractionSolid(wall_union, vacuum_union);
0626
0627
0628 vacuum = vacuum_union;
0629 } else
0630 {
0631
0632 vacuum_union =
0633 SubtractionSolid("vacuum_union_sub_2", vacuum_union, wall_union, Transform3D());
0634 vacuum_union =
0635 SubtractionSolid("vacuum_union_sub_3", vacuum_union, coating_union, Transform3D());
0636
0637
0638 vacuum = vacuum_union;
0639
0640
0641 wall = wall_union;
0642
0643
0644 coating = coating_union;
0645
0646
0647 xml::Component fwdipflange_c = x_pipe1.child(_Unicode(fwdipflange));
0648 auto fwdipflange_polycones = zplane_to_polycones(fwdipflange_c);
0649
0650 wall_ipflange = std::get<0>(fwdipflange_polycones);
0651 coating_ipflange = std::get<1>(fwdipflange_polycones);
0652 vacuum_ipflange = std::get<2>(fwdipflange_polycones);
0653 }
0654
0655 return std::tuple<Volume, Volume, Volume, Volume, Volume, Volume, Volume, Volume, Volume,
0656 Volume, Volume, Volume, Volume, Volume>(
0657 {"v_" + name + "_wall", wall, m_Wall}, {"v_" + name + "_coating", coating, m_Coating},
0658 {"v_" + name + "_vacuum", vacuum, m_Vacuum},
0659 {"v_" + name + "_vacuum_ipflange", vacuum_ipflange, m_Vacuum},
0660 {"v_" + name + "_wall_racetrack", wall_racetrack, m_Wall},
0661 {"v_" + name + "_coating_racetrack", coating_racetrack, m_Coating},
0662 {"v_" + name + "_wall_ipflange", wall_ipflange, m_Wall},
0663 {"v_" + name + "_coating_ipflange", coating_ipflange, m_Coating},
0664 {"v_" + name + "_wall_interface_1", wall_interface_1, m_Wall},
0665 {"v_" + name + "_coating_interface_1", coating_interface_1, m_Coating},
0666 {"v_" + name + "_wall_interface_2", wall_interface_2, m_Wall},
0667 {"v_" + name + "_coating_interface_2", coating_interface_2, m_Coating},
0668 {"v_" + name + "_vacuum_interface", vacuum_interface, m_Vacuum},
0669 {"v_" + name + "_lepton_pipe_vac", lepton_pipe_vac, m_Vacuum});
0670 };
0671
0672
0673
0674
0675
0676
0677 xml::Component upstream_c = x_det.child(_Unicode(upstream));
0678 xml::Component incoming_hadron_c = upstream_c.child(_Unicode(incoming_hadron));
0679 xml::Component outgoing_lepton_c = upstream_c.child(_Unicode(outgoing_lepton));
0680 xml_coll_t additional_subtractions_upstream(upstream_c, _Unicode(additional_subtraction));
0681 auto volumes_upstream = create_volumes("upstream", outgoing_lepton_c, incoming_hadron_c,
0682 additional_subtractions_upstream);
0683
0684 std::get<0>(volumes_upstream).setVisAttributes(wallVis);
0685 std::get<1>(volumes_upstream).setVisAttributes(coatingVis);
0686
0687 auto tf_upstream = Transform3D(RotationZYX(0, 0, 0));
0688 if (getAttrOrDefault<bool>(upstream_c, _Unicode(reflect), true)) {
0689 tf_upstream = Transform3D(RotationZYX(0, M_PI, 0));
0690 }
0691
0692 assembly.placeVolume(std::get<0>(volumes_upstream), tf_upstream);
0693
0694 assembly.placeVolume(std::get<1>(volumes_upstream), tf_upstream);
0695
0696 if (getAttrOrDefault<bool>(upstream_c, _Unicode(place_vacuum), true)) {
0697 assembly.placeVolume(std::get<2>(volumes_upstream), tf_upstream);
0698 }
0699
0700
0701
0702
0703
0704
0705 xml::Component downstream_c = x_det.child(_Unicode(downstream));
0706 xml::Component incoming_lepton_c = downstream_c.child(_Unicode(incoming_lepton));
0707 xml::Component outgoing_hadron_c = downstream_c.child(_Unicode(outgoing_hadron));
0708 xml_coll_t additional_subtractions_downstream(downstream_c, _Unicode(additional_subtraction));
0709 auto volumes_downstream = create_volumes("downstream", incoming_lepton_c, outgoing_hadron_c,
0710 additional_subtractions_downstream);
0711
0712
0713 std::get<0>(volumes_downstream).setVisAttributes(wallVis);
0714 std::get<1>(volumes_downstream).setVisAttributes(coatingVis);
0715 std::get<4>(volumes_downstream).setVisAttributes(wallVis);
0716 std::get<5>(volumes_downstream).setVisAttributes(coatingVis);
0717 std::get<6>(volumes_downstream).setVisAttributes(wallVis);
0718 std::get<7>(volumes_downstream).setVisAttributes(coatingVis);
0719 std::get<8>(volumes_downstream).setVisAttributes(wallVis);
0720 std::get<9>(volumes_downstream).setVisAttributes(coatingVis);
0721 std::get<10>(volumes_downstream).setVisAttributes(wallVis);
0722 std::get<11>(volumes_downstream).setVisAttributes(coatingVis);
0723
0724 auto tf_downstream = Transform3D(RotationZYX(0, 0, 0));
0725 if (getAttrOrDefault<bool>(downstream_c, _Unicode(reflect), true)) {
0726 tf_downstream = Transform3D(RotationZYX(0, M_PI, 0));
0727 }
0728
0729
0730 assembly.placeVolume(std::get<0>(volumes_downstream), tf_downstream);
0731
0732 assembly.placeVolume(std::get<1>(volumes_downstream), tf_downstream);
0733
0734 if (getAttrOrDefault<bool>(downstream_c, _Unicode(place_vacuum), true)) {
0735 assembly.placeVolume(std::get<2>(volumes_downstream), tf_downstream);
0736 assembly.placeVolume(std::get<3>(volumes_downstream), tf_downstream);
0737 assembly.placeVolume(std::get<12>(volumes_downstream), tf_downstream);
0738 assembly.placeVolume(std::get<13>(volumes_downstream), tf_downstream);
0739 }
0740
0741 assembly.placeVolume(std::get<4>(volumes_downstream), tf_downstream);
0742
0743 assembly.placeVolume(std::get<5>(volumes_downstream), tf_downstream);
0744
0745 assembly.placeVolume(std::get<6>(volumes_downstream), tf_downstream);
0746
0747 assembly.placeVolume(std::get<7>(volumes_downstream), tf_downstream);
0748
0749 assembly.placeVolume(std::get<8>(volumes_downstream), tf_downstream);
0750 assembly.placeVolume(std::get<10>(volumes_downstream), tf_downstream);
0751
0752 assembly.placeVolume(std::get<9>(volumes_downstream), tf_downstream);
0753 assembly.placeVolume(std::get<11>(volumes_downstream), tf_downstream);
0754
0755
0756
0757 auto pv_assembly = det.pickMotherVolume(sdet).placeVolume(assembly);
0758 pv_assembly.addPhysVolID("system", sdet.id());
0759 sdet.setPlacement(pv_assembly);
0760 assembly->GetShape()->ComputeBBox();
0761
0762 return sdet;
0763 }
0764
0765 DECLARE_DETELEMENT(IP6BeamPipe, create_detector)