ZDC_geo.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // Zero Degree Calorimeter Detector implementation
3 //--------------------------------------------------------------------------
4 // Build two towers of ZDC - small and large
5 // Sampling type calorimeter
6 // J.KIM
7 // Created 2020-07-21
8 // Modified 2020-07-22
9 //==========================================================================
10 #include "DD4hep/DetFactoryHelper.h"
11 #include "DD4hep/Printout.h"
12 #include <XML/Helper.h>
13 #include "TMath.h"
14 #include "DDRec/Surface.h"
15 #include "DDRec/DetectorData.h"
16 #include "XML/Layering.h"
17 #include "Math/Transform3D.h"
18 
19 using namespace std;
20 using namespace dd4hep;
21 using namespace dd4hep::rec;
22 using namespace dd4hep::detail;
23 
41 static Ref_t createDetector(Detector& lcdd, xml_h e, SensitiveDetector sens) {
42  xml_det_t x_det = e;
43  int det_id = x_det.id();
44  string det_name = x_det.nameStr();
45  xml_dim_t pos = x_det.position();
46  double x_pos = dd4hep::getAttrOrDefault(pos, _Unicode(x),0.0);
47  double y_pos = dd4hep::getAttrOrDefault(pos, _Unicode(y),0.0);
48  double z_pos = dd4hep::getAttrOrDefault(pos, _Unicode(z),0.0);
49  xml_dim_t dim = x_det.dimensions();
50  double pixel_x = dim.x();
51  double pixel_y = dim.y();
52  Material air = lcdd.material("Air");
53  double z = z_pos;
54  double zmin = z_pos;
55  DetElement det(det_name, det_id);
56 
57  int layer_num = 1;
58  int slice_num = 1;
59  double totWidth = Layering(x_det).totalThickness();
60  Box envelope (pixel_x/2.0, pixel_y/2.0,totWidth);
61  Volume envelopeVol(det_name+"_envelope",envelope,air);
62  PlacedVolume pv;
63 
64  xml_comp_t x_layer = x_det.child(_U(layer));
65 
66  // Read layers
67  for(xml_coll_t c(x_det,_U(layer)); c; ++c)
68  {
69  xml_comp_t x_layer = c;
70  int repeat = x_layer.repeat();
71  double layerWidth = 0;
72  for(xml_coll_t l(x_layer,_U(slice)); l; ++l)
73  layerWidth += xml_comp_t(l).thickness();
74 
75  // Loop over repeat#
76  for(int i=0; i< repeat; i++)
77  {
78  double zlayer = z;
79  string layer_name = det_name + _toString(layer_num,"_layer%d");
80  Volume layer_vol(layer_name,Box(pixel_x/2.0, pixel_y/2.0,layerWidth/2.0),air);
81 
82  // Loop over slices
83  for(xml_coll_t l(x_layer,_U(slice)); l; ++l)
84  {
85  xml_comp_t x_slice = l;
86  double w = x_slice.thickness();
87  string slice_name = layer_name + _toString(slice_num,"slice%d");
88  Material slice_mat = lcdd.material(x_slice.materialStr());
89  Volume slice_vol (slice_name,Box(pixel_x/2.0, pixel_y/2.0,w/2.0),slice_mat);
90  if(x_slice.isSensitive())
91  {
92  sens.setType("calorimeter");
93  slice_vol.setSensitiveDetector(sens);
94  }
95  slice_vol.setAttributes(lcdd,x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
96  pv = layer_vol.placeVolume(slice_vol, Transform3D(RotationZ(M_PI/2.0),Position(0.0,0.0,z-zlayer-layerWidth/2.0+w/2.0)));
97  pv.addPhysVolID("slice", slice_num);
98  z += w;
99  ++slice_num;
100  }
101  string layer_vis = dd4hep::getAttrOrDefault(x_layer, _Unicode(vis), "InvisibleWithDaughters");
102  layer_vol.setAttributes(lcdd, x_layer.regionStr(), x_layer.limitsStr(), layer_vis);
103  pv = envelopeVol.placeVolume(layer_vol, Transform3D(RotationZ(M_PI/4.0), Position(0,0,zlayer-zmin-totWidth/2.0+layerWidth/2.0)));
104  pv.addPhysVolID("layer", layer_num);
105  ++layer_num;
106  }
107  }
108  envelopeVol.setAttributes(lcdd,x_det.regionStr(), x_det.limitsStr(), "InvisibleWithDaughters");
109 
110  Volume motherVol = lcdd.pickMotherVolume(det);
111  PlacedVolume phv = motherVol.placeVolume(envelopeVol, Position(x_pos,y_pos,z_pos+totWidth/2.0));
112  phv.addPhysVolID("system", det.id());
113  det.setPlacement(phv);
114 
115  return det;
116 }
117 
118 DECLARE_DETELEMENT(ZDC, createDetector)
Detector
Definition: DDG4.py:69
Namespace for the AIDA detector description toolkit.
static Ref_t createDetector(Detector &lcdd, xml_h e, SensitiveDetector sens)
Definition: ZDC_geo.cpp:41