CylindricalDipoleMagnet_geo.cpp
Go to the documentation of this file.
1 #include "DD4hep/DetFactoryHelper.h"
2 #include "DD4hep/Printout.h"
3 #include "DD4hep/Shapes.h"
4 #include "TMath.h"
5 #include "DDRec/Surface.h"
6 #include "DDRec/DetectorData.h"
7 #include "XML/Layering.h"
8 
9 using namespace std;
10 using namespace dd4hep;
11 using namespace dd4hep::rec;
12 using namespace ROOT::Math;
13 
14 static Ref_t build_magnet(Detector& dtor, xml_h e, SensitiveDetector sens) {
15  xml_det_t x_det = e;
16  int det_id = x_det.id();
17  string det_name = x_det.nameStr();
18  xml_dim_t pos = x_det.child(_U(placement));
19  double pos_x = pos.x();
20  double pos_y = pos.y();
21  double pos_z = pos.z();
22  double pos_theta = pos.attr<double>(_U(theta));
23  xml_dim_t dims = x_det.dimensions();
24  double dim_r = dims.r();
25  double dim_z = dims.z();
26  xml_dim_t apperture = x_det.child(_Unicode(apperture));
27  double app_r = apperture.r();
28  xml_dim_t coil = x_det.child(_Unicode(coil));
29  double coil_x = coil.dx();
30  double coil_y = coil.dy();
31  Material iron = dtor.material("Vacuum");
32  Material niobium = dtor.material("Vacuum");
33 
34  std::cout << det_name << " positioned at z=" << pos.z() << ", x=" << pos.x() << "\n";
35 
36  DetElement sdet(det_name, det_id);
37  Assembly assembly(det_name + "_assembly");
38 
39  string module_name = "Quad_magnet";
40 
41  string vis0 = dd4hep::getAttrOrDefault(x_det, _Unicode(vis), "GreenVis");
42 
43  sdet.setAttributes(dtor, assembly, x_det.regionStr(), x_det.limitsStr(), "OrangeVis");
44 
45  // -- yoke
46  Tube yoke_tube(app_r + coil_y, dim_r, 0.5*dim_z);
47  Volume yoke_vol("yoke_vol", yoke_tube, iron);
48  auto yoke_pv = assembly.placeVolume(yoke_vol);
49  yoke_pv.addPhysVolID("element", 1);
50  DetElement yoke_de(sdet, "yoke_de", 1);
51  yoke_de.setPlacement(yoke_pv);
52  yoke_de.setAttributes(dtor, yoke_vol, x_det.regionStr(), x_det.limitsStr(), "GreenVis");
53 
54  // -- coils
55  double offset = 1.5 * coil_x;
56  double appc_r = app_r + 0.5 * coil_y;
57  double offset_angle = atan(offset / appc_r);
58 
59  Tube longrod(app_r, app_r + coil_y, 0.5*dim_z, atan(coil_x / app_r));
60  Tube connector(app_r, app_r + coil_y , coil_y, 0.5*M_PI - offset_angle);
61 
62  UnionSolid coil1(longrod, longrod, Transform3D(RotationZ(-offset_angle)));
63  UnionSolid coil2(coil1, longrod, Transform3D(RotationZ(0.5*M_PI)));
64  UnionSolid coil3(coil2, longrod, Transform3D(RotationZ(M_PI)));
65  UnionSolid coil4(coil3, longrod, Transform3D(RotationZ(1.5*M_PI)));
66 
67  UnionSolid coil5(coil4, longrod, Transform3D(RotationZ(0.5*M_PI - offset_angle)));
68  UnionSolid coil6(coil5, longrod, Transform3D(RotationZ(M_PI - offset_angle)));
69  UnionSolid coil7(coil6, longrod, Transform3D(RotationZ(1.5*M_PI - offset_angle)));
70 
71  UnionSolid coil8(coil7, connector, Transform3D(Translation3D(0.0, 0.0, -0.5*dim_z + coil_y)));
72  UnionSolid coil9(coil8, connector, Transform3D(Translation3D(0.0, 0.0, -0.5*dim_z + coil_y) * RotationZ(0.5*M_PI)));
73  UnionSolid coil10(coil9, connector, Transform3D(Translation3D(0.0, 0.0, -0.5*dim_z + coil_y) * RotationZ(M_PI)));
74  UnionSolid coil11(coil10, connector, Transform3D(Translation3D(0.0, 0.0, -0.5*dim_z + coil_y) * RotationZ(1.5*M_PI)));
75  UnionSolid coil12(coil11, connector, Transform3D(Translation3D(0.0, 0.0, 0.5*dim_z - coil_y)));
76  UnionSolid coil13(coil12, connector, Transform3D(Translation3D(0.0, 0.0, 0.5*dim_z - coil_y) * RotationZ(0.5*M_PI)));
77  UnionSolid coil14(coil13, connector, Transform3D(Translation3D(0.0, 0.0, 0.5*dim_z - coil_y) * RotationZ(M_PI)));
78  UnionSolid coil15(coil14, connector, Transform3D(Translation3D(0.0, 0.0, 0.5*dim_z - coil_y) * RotationZ(1.5*M_PI)));
79 
80  Volume coil_vol("coil_vol", coil14, niobium);
81 
82  auto coil_pos = Transform3D(RotationZ(0.5*M_PI - offset_angle));
83  auto coil_pv = assembly.placeVolume(coil_vol, coil_pos);
84  DetElement coil_de(sdet, "coil_de", 2);
85  coil_de.setAttributes(dtor, coil_vol, x_det.regionStr(), x_det.limitsStr(), "RedVis");
86  coil_de.setPlacement(coil_pv);
87 
88  // -- finishing steps
89  auto final_pos = Transform3D(Translation3D(pos_x, pos_y, pos_z) * RotationY(pos_theta));
90  auto pv = dtor.pickMotherVolume(sdet).placeVolume(assembly, final_pos);
91  pv.addPhysVolID("system", det_id);
92  sdet.setPlacement(pv);
93 
94  assembly->GetShape()->ComputeBBox();
95  return sdet;
96 }
97 
98 DECLARE_DETELEMENT(CylindricalDipoleMagnet, build_magnet)
static Ref_t build_magnet(Detector &dtor, xml_h e, SensitiveDetector sens)
Detector
Definition: DDG4.py:69
Namespace for the AIDA detector description toolkit.