GenericTrackerBarrel_geo.cpp
Go to the documentation of this file.
1 #include "DD4hep/DetFactoryHelper.h"
2 #include "DD4hep/Printout.h"
3 #include "TMath.h"
4 #include "DDRec/Surface.h"
5 #include "DDRec/DetectorData.h"
6 
7 using namespace std;
8 using namespace dd4hep;
9 using namespace dd4hep::rec;
10 //using namespace DDSurfaces;
11 
12 static Ref_t create_detector(Detector& lcdd, xml_h e, SensitiveDetector sens)
13 {
14  typedef vector<PlacedVolume> Placements;
15 
16  xml_det_t x_det = e;
17  Material air = lcdd.air();
18  Material carbon = lcdd.material("CarbonFiber");
19  Material silicon = lcdd.material("SiliconOxide");
20  int det_id = x_det.id();
21  string det_name = x_det.nameStr();
22  PlacedVolume pv;
23 
24  double inner_r = x_det.attr<double>( _Unicode(inner_r) ) ;
25  DetElement sdet(det_name, det_id);
26  Assembly assembly(det_name+"_assembly");
27  //printout(INFO, "SiTrackerBarrelJLEIC", "In the Create Detector Function");
28 
29  sens.setType("tracker");
30  string module_name = "VtxBarrelModule";
31 
32  double init_layer_radius = inner_r;//380.0*dd4hep::mm;
33 
34  //Find number of layers and set number of modules
35  int N_layers=0;
36  std::vector<int> N_phi_modules;
37  std::vector<int> N_z_modules;
38  for(xml_coll_t i(x_det,_U(layer)); i; ++i) {
39  xml_comp_t x_layer = i;
40  N_layers++;
41  N_phi_modules.push_back(x_layer.nModules());
42  N_z_modules.push_back(x_layer.nz());
43  }
44 
45  double extra_module_width = 0.2*dd4hep::cm;
46  double module_x = (2.0*TMath::Pi()*init_layer_radius)/(N_phi_modules.at(0)*2.0);
47  double module_y = 5.0*dd4hep::cm/2.0;
48  double module_z = 2.0*dd4hep::mm;
49 
50  Position offset{ 0.0, 0.0, 1.0*dd4hep::m };
51 
52  // For each layer, calculate the delta_phi covered by each module
53  std::vector<double> delta_phi_layer;
54  std::for_each(N_phi_modules.begin(), N_phi_modules.end(),
55  [&](auto const& n){ delta_phi_layer.push_back( TMath::Pi()/double(n) ); });
56 
57  // Calculate the radius for each layer
58  std::vector<double> layer_radius;
59  std::for_each(delta_phi_layer.begin(), delta_phi_layer.end(),
60  [&](auto const& p){ layer_radius.push_back( module_x/p ); });
61 
62  Volume module_vol( module_name, Box(
63  module_x + extra_module_width,
64  module_y - 0.1*dd4hep::mm,
65  module_z
66  ), carbon);
67 
68  Volume sense_vol("sense_volume", Box(
69  module_x + extra_module_width - 0.1*dd4hep::mm,
70  module_y - 0.1*dd4hep::mm,
71  0.5*dd4hep::mm
72  ), silicon);
73 
74  PlacedVolume sensitive_pv = module_vol.placeVolume( sense_vol );
75  sensitive_pv.addPhysVolID( "sensor", 1 );
76 
77  // -------- create a measurement plane for the tracking surface attched to the sensitive volume -----
78  Vector3D u( 1. , 0. , 0. ) ;
79  Vector3D v( 0. , 1. , 0. ) ;
80  Vector3D n( 0. , 0. , 1. ) ;
81  Vector3D o( 0. , 0. , 0. ) ;
82 
83  // compute the inner and outer thicknesses that need to be assigned to the tracking surface
84  // depending on wether the support is above or below the sensor
85  // The tracking surface is used in reconstruction. It provides material thickness
86  // and radation lengths needed for various algorithms, routines, etc.
87  double inner_thickness = module_z/2.0;
88  double outer_thickness = module_z/2.0;
89 
90  SurfaceType type( SurfaceType::Sensitive ) ;
91  VolPlane surf( sense_vol, type, inner_thickness , outer_thickness , u,v,n,o ) ;
92 
93  //--------------------------------------------
94 
95  sens.setType("tracker");
96  sense_vol.setSensitiveDetector(sens);
97 
98  ROOT::Math::RotationX Rx( TMath::Pi()/2.0 );
99  ROOT::Math::RotationZ Rz( TMath::Pi()/2.0 );
100 
101  for(int i_layer=0; i_layer<N_layers; i_layer++){
102 
103  int layer_id = i_layer + 1;
104  string layer_name = std::string("layer") + std::to_string(layer_id) ;
105  double phi0 = 0;
106  double phi_tilt = 180.0*dd4hep::degree/(double(N_phi_modules.at(i_layer))+3.0);
107 
108  DetElement layer_DE( sdet, _toString(layer_id,"layer%d"), layer_id );
109  Assembly layer_assembly( layer_name+"_assembly" );
110  pv = assembly.placeVolume( layer_assembly );
111  pv.addPhysVolID( "layer", layer_id );
112  layer_DE.setPlacement(pv);
113  layer_DE.setAttributes(lcdd, layer_assembly, "", "", "SiVertexLayerVis");
114  std::cout << "Radius of layer " << layer_id << " is " << layer_radius.at(i_layer) << endl;
115 
116  // Loop over the number of modules in phi.
117  for (int i_phi = 0; i_phi < N_phi_modules.at(i_layer); i_phi++){
118 
119  double phi = phi0 + i_phi*2.0*delta_phi_layer.at(i_layer);
120 
121  // The radial displacement of the module
122  ROOT::Math::Polar3DVector rho_module( layer_radius.at(i_layer), TMath::Pi()/2.0, phi );
123 
124  double z0 = -1.0*module_y*double(N_z_modules.at(i_layer)) + module_y;
125  double dz = 2.0*module_y;
126 
127  // Loop over the number of modules in z.
128  for (int i_Z = 0; i_Z < N_z_modules.at(i_layer); i_Z++){
129 
130  ROOT::Math::XYZVector z_displacement(0.0, 0.0, z0 + double(i_Z)*dz);
131 
132  int i_module = 1 + i_Z + i_phi*N_z_modules.at(i_layer);
133  string a_module_name = _toString(i_module, "module%d");
134 
135  Transform3D tr( RotationZ(phi_tilt)*RotationZ(phi)*Rx, Rz*rho_module + z_displacement);
136 
137  DetElement module_DE(layer_DE, a_module_name, i_module);
138  module_vol.setVisAttributes(lcdd, x_det.visStr());
139  pv = layer_assembly.placeVolume( module_vol, tr );
140  pv.addPhysVolID( "module", i_module );
141  module_DE.setPlacement(pv);
142 
143  DetElement module_sense_DE( module_DE, std::string("sense_DE")+std::to_string(i_module), i_module );
144  module_sense_DE.setPlacement( sensitive_pv );
145 
146  }
147  layer_assembly->GetShape()->ComputeBBox() ;
148  }
149  }
150 
151  sdet.setAttributes(lcdd, assembly,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
152  assembly.setVisAttributes(lcdd.invisible());
153 
154  pv = lcdd.pickMotherVolume(sdet).placeVolume(assembly);
155  pv.addPhysVolID("system", det_id); // Set the subdetector system ID.
156  pv.addPhysVolID("barrel", 1); // Flag this as a barrel subdetector.
157  sdet.setPlacement(pv);
158 
159  assembly->GetShape()->ComputeBBox() ;
160 
161  return sdet;
162 }
163 
164 DECLARE_DETELEMENT(GenericTrackerBarrel,create_detector)
static Ref_t create_detector(Detector &lcdd, xml_h e, SensitiveDetector sens)
Detector
Definition: DDG4.py:69
Namespace for the AIDA detector description toolkit.