Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//==========================================================================
// AIDA Detector description implementation
//--------------------------------------------------------------------------
// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
// All rights reserved.
//
// For the licensing terms see $DD4hepINSTALL/LICENSE.
// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
//
// Author : M.Frank
//
//==========================================================================
//
// Modified for TOPSiDE detector
//
//==========================================================================
#include "DD4hep/DetFactoryHelper.h"
#include "XML/Layering.h"
using namespace std;
using namespace dd4hep;
using namespace dd4hep::detail;
static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
xml_det_t x_det = e;
xml_dim_t dim = x_det.dimensions();
int det_id = x_det.id();
bool reflect = x_det.reflect(true);
string det_name = x_det.nameStr();
Material air = description.air();
int numsides = dim.numsides();
double rmin = dim.rmin();
double rmax = dim.rmax() * std::cos(M_PI / numsides);
double zmin = dim.zmin();
Layering layering(x_det);
double totalThickness = layering.totalThickness();
Volume endcapVol("endcap", PolyhedraRegular(numsides, rmin, rmax, totalThickness), air);
DetElement endcap("endcap", det_id);
int l_num = 1;
int layerType = 0;
double layerZ = -totalThickness / 2;
endcapVol.setAttributes(description, x_det.regionStr(), x_det.limitsStr(), x_det.visStr());
for (xml_coll_t xc(x_det, _U(layer)); xc; ++xc) {
xml_comp_t x_layer = xc;
double l_thick = layering.layer(l_num - 1)->thickness();
string l_name = _toString(layerType, "layer%d");
int l_repeat = x_layer.repeat();
Volume l_vol(l_name, PolyhedraRegular(numsides, rmin, rmax, l_thick), air);
vector<PlacedVolume> sensitives;
int s_num = 1;
double sliceZ = -l_thick / 2;
for (xml_coll_t xs(x_layer, _U(slice)); xs; ++xs) {
xml_comp_t x_slice = xs;
string s_name = _toString(s_num, "slice%d");
double s_thick = x_slice.thickness();
Material s_mat = description.material(x_slice.materialStr());
Volume s_vol(s_name, PolyhedraRegular(numsides, rmin, rmax, s_thick), s_mat);
s_vol.setVisAttributes(description.visAttributes(x_slice.visStr()));
sliceZ += s_thick / 2;
PlacedVolume s_phv = l_vol.placeVolume(s_vol, Position(0, 0, sliceZ));
s_phv.addPhysVolID("slice", s_num);
if (x_slice.isSensitive()) {
sens.setType("calorimeter");
s_vol.setSensitiveDetector(sens);
sensitives.push_back(s_phv);
}
sliceZ += s_thick / 2;
s_num++;
}
l_vol.setVisAttributes(description.visAttributes(x_layer.visStr()));
if (l_repeat <= 0) throw std::runtime_error(x_det.nameStr() + "> Invalid repeat value");
for (int j = 0; j < l_repeat; ++j) {
string phys_lay = _toString(l_num, "layer%d");
layerZ += l_thick / 2;
DetElement layer_elt(endcap, phys_lay, l_num);
PlacedVolume pv = endcapVol.placeVolume(l_vol, Position(0, 0, layerZ));
pv.addPhysVolID("layer", l_num);
layer_elt.setPlacement(pv);
for (size_t ic = 0; ic < sensitives.size(); ++ic) {
PlacedVolume sens_pv = sensitives[ic];
DetElement comp_elt(layer_elt, sens_pv.volume().name(), l_num);
comp_elt.setPlacement(sens_pv);
}
layerZ += l_thick / 2;
++l_num;
}
++layerType;
}
double z_pos = zmin + totalThickness / 2;
PlacedVolume pv;
// Reflect it.
Assembly assembly(det_name);
DetElement endcapAssyDE(det_name, det_id);
Volume motherVol = description.pickMotherVolume(endcapAssyDE);
if (reflect) {
pv = assembly.placeVolume(endcapVol,
Transform3D(RotationZYX(M_PI / numsides, M_PI, 0), Position(0, 0, -z_pos)));
pv.addPhysVolID("barrel", 2);
Ref_t(endcap)->SetName((det_name + "_backward").c_str());
endcap.setPlacement(pv);
} else {
pv = assembly.placeVolume(endcapVol,
Transform3D(RotationZYX(M_PI / numsides, 0, 0), Position(0, 0, z_pos)));
pv.addPhysVolID("barrel", 1);
Ref_t(endcap)->SetName((det_name + "_forward").c_str());
endcap.setPlacement(pv);
}
endcapAssyDE.add(endcap);
pv = motherVol.placeVolume(assembly);
pv.addPhysVolID("system", det_id);
endcapAssyDE.setPlacement(pv);
return endcapAssyDE;
}
// clang-format off
DECLARE_DETELEMENT(refdet_PolyhedraEndcapCalorimeter2, create_detector)