helical_dipole_magnet_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  double pos_psi = pos.attr<double>(_U(psi));
24  xml_dim_t dims = x_det.dimensions();
25  double dim_r = dims.r();
26  double dim_z = dims.z();
27  xml_dim_t apperture = x_det.child(_Unicode(apperture));
28  double app_r = apperture.r();
29  xml_dim_t coil = x_det.child(_Unicode(coil));
30  double coil_y = coil.dy();
31  Material aluminum = dtor.material("Aluminum");
32  Material niobium = dtor.material("Niobium");
33 
34  DetElement sdet(det_name, det_id);
35  Assembly assembly(det_name + "_assembly");
36 
37  string module_name = "Spin_polarizer";
38 
39  string vis0 = dd4hep::getAttrOrDefault(x_det, _Unicode(vis), "BlueVis");
40 
41  sdet.setAttributes(dtor, assembly, x_det.regionStr(), x_det.limitsStr(), "OrangeVis");
42 
43  int N = 45;
44  double segment_length = dim_z/(2*N);
45  double shell_delta = 10.0*dd4hep::mm;
46 
47  UnionSolid coil_rod;
48 
49  Tube shell_tube(app_r, dim_r, 0.5*dim_z);
50  Tube coil_segment(app_r + shell_delta, app_r + coil_y, segment_length/2, M_PI/N);
51 
52  coil_rod = UnionSolid(coil_segment, coil_segment, Transform3D( RotationZ(M_PI) ));
53 
54  for (double a = -M_PI/3; a < M_PI/3; a += 4*M_PI/N){
55  coil_rod = UnionSolid(coil_rod, coil_segment, Transform3D(RotationZ(a)));
56  }
57 
58  for (double a = -M_PI/3; a < M_PI/3; a += 4*M_PI/N){
59  coil_rod = UnionSolid(coil_rod, coil_segment, Transform3D(RotationZ(M_PI + a)));
60  }
61 
62  for (int i = 1; i < 2*N; i++){
63  for (double a = -M_PI/3; a < M_PI/3; a += 4*M_PI/N){
64  coil_rod = UnionSolid(coil_rod, coil_segment, Transform3D( RotationZ(a + i*M_PI/N) * Translation3D(0, 0, i*segment_length) ));
65  coil_rod = UnionSolid(coil_rod, coil_segment, Transform3D( RotationZ(M_PI + a + i*M_PI/N) * Translation3D(0, 0, i*segment_length) ));
66  }
67  }
68 
69  SubtractionSolid shell(shell_tube, coil_rod, Position(0.0, 0.0, -0.5*(dim_z - segment_length)));
70 
71  Volume coil_vol("coil_vol", coil_rod, niobium);
72  auto coil_pv = assembly.placeVolume(coil_vol, Position(0, 0, -0.5*(dim_z - segment_length)));
73  DetElement coil_de(sdet, "coil_de", 2);
74  coil_de.setAttributes(dtor, coil_vol, x_det.regionStr(), x_det.limitsStr(), "RedVis");
75  coil_de.setPlacement(coil_pv);
76 
77  Volume shell_vol("shell_vol", shell, niobium);
78  auto shell_pv = assembly.placeVolume(shell_vol);
79  DetElement shell_de(sdet, "shell_de", 2);
80  shell_de.setAttributes(dtor, shell_vol, x_det.regionStr(), x_det.limitsStr(), "BlueVis");
81  shell_de.setPlacement(shell_pv);
82 
83  // -- finishing steps
84  auto final_pos = Transform3D(Translation3D(pos_x, pos_y, pos_z) * RotationY(pos_theta) * RotationZ(pos_psi));
85  auto pv = dtor.pickMotherVolume(sdet).placeVolume(assembly, final_pos);
86  pv.addPhysVolID("system", det_id);
87  sdet.setPlacement(pv);
88 
89  assembly->GetShape()->ComputeBBox();
90  return sdet;
91 }
92 
93 DECLARE_DETELEMENT(HelicalDipole, 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.