CMS 3D CMS Logo

DDCutTubsFromPoints.cc
Go to the documentation of this file.
1 #include "DD4hep/DetFactoryHelper.h"
4 
6 
7 using namespace cms_units::operators; // _deg and convertRadToDeg
8 
9 static long algorithm(dd4hep::Detector& /* description */, cms::DDParsingContext& ctxt, xml_h e) {
10  cms::DDNamespace ns(ctxt, e, true);
12 
13  dd4hep::Volume mother = ns.volume(args.parentName());
14 
15  struct Section {
16  float phi; // phi position of this edge
17  float z_l; // -Z end (cuttubs l plane)
18  float z_t; // +Z end (cuttubs t plane)
19  // radius is implicitly r_min
20  };
21 
22  std::vector<Section> sections;
23 
24  float r_min = args.value<float>("rMin");
25  float r_max = args.value<float>("rMax");
26  float z_pos = args.value<float>("zPos");
27 
28  const std::string solidOutput = args.value<std::string>("SolidName");
29  const std::string material = args.value<std::string>("Material");
30 
31  auto phis = ns.vecFloat(args.str("Phi"));
32  auto z_ls = ns.vecFloat(args.str("z_l"));
33  auto z_ts = ns.vecFloat(args.str("z_t"));
34 
35  assert(phis.size() == z_ls.size());
36  assert(phis.size() == z_ts.size());
37 
38  for (unsigned i = 0; i < phis.size(); i++) {
39  Section s = {phis[i], z_ls[i], z_ts[i]};
40 
41  edm::LogVerbatim("TrackerGeom") << "DDCutTubsFromPoints: Sections :" << phis[i] << " , " << z_ls[i] << " , "
42  << z_ts[i];
43  sections.emplace_back(s);
44  }
45 
46  assert(!sections.empty());
47 
48  // a segment is produced between each two consecutive sections that have a
49  // non-zero phi distance. Sections with zero phi distance can be used to
50  // create sharp jumps.
51 
52  edm::LogVerbatim("TrackerGeom") << "DDCutTubsFromPoints debug: Parent " << args.parentName() << "\tSolid "
53  << solidOutput << " NameSpace " << ns.name() << "\tnumber of sections "
54  << sections.size();
55 
56  // radius for plane calculations
57  // We use r_max here, since P3 later has a Z that is always more inside
58  // than the extreme points. This means the cutting planes have outwards
59  // slopes in r-Z, and the corner at r_max could stick out of the bounding
60  // volume otherwise.
61  float r = r_max;
62 
63  // min and max z for the placement in the end
64  float min_z = 1e9;
65  float max_z = -1e9;
66 
67  // counter of actually produced segments (excluding skipped ones)
68  int segment = 0;
69 
70  // the segments and their corresponding offset (absolute, as in the input)
71  std::vector<dd4hep::Solid> segments;
72  std::vector<float> offsets;
73 
74  Section s1 = sections[0];
75 
76  for (Section s2 : sections) {
77  if (s1.phi != s2.phi) {
78  segment++;
79  // produce segment s1-s2.
80  float phi1 = s1.phi;
81  float phi2 = s2.phi;
82 
83  // track the min/max to properly place&align later
84  if (s2.z_l < min_z)
85  min_z = s2.z_l;
86  if (s2.z_t > max_z)
87  max_z = s2.z_t;
88 
89  float P1_z_l = s1.z_l;
90  float P1_z_t = s1.z_t;
91  float P2_z_l = s2.z_l;
92  float P2_z_t = s2.z_t;
93 
94  float P1_x_t = cos(phi1) * r;
95  float P1_x_l = cos(phi1) * r;
96  float P1_y_t = sin(phi1) * r;
97  float P1_y_l = sin(phi1) * r;
98 
99  float P2_x_t = cos(phi2) * r;
100  float P2_x_l = cos(phi2) * r;
101  float P2_y_t = sin(phi2) * r;
102  float P2_y_l = sin(phi2) * r;
103 
104  // each cutting plane is defined by P1-3. P1-2 are corners of the
105  // segment, P3 is at r=0 with the "average" z to get a nice cut.
106  float P3_z_l = (P1_z_l + P2_z_l) / 2;
107  float P3_z_t = (P1_z_t + P2_z_t) / 2;
108 
109  edm::LogVerbatim("TrackerGeom").log([&](auto& log) {
110  std::string segname(solidOutput + "_seg_" + std::to_string(segment));
111  log << "DDCutTubsFromPoints: P1 l: " << segname << P1_x_l << " , " << P1_y_l << " , " << P1_z_l;
112  log << "DDCutTubsFromPoints: P1 t: " << segname << P1_x_t << " , " << P1_y_t << " , " << P1_z_t;
113  log << "DDCutTubsFromPoints: P2 l: " << segname << P2_x_l << " , " << P2_y_l << " , " << P2_z_l;
114  log << "DDCutTubsFromPoints: P2 t: " << segname << P2_x_t << " , " << P2_y_t << " , " << P2_z_t;
115  });
116 
117  // we only have one dz to position both planes. The anchor is implicitly
118  // between the P3's, we have to use an offset later to make the segments
119  // line up correctly.
120  float dz = 0.5 * (P3_z_t - P3_z_l);
121  float offset = 0.5 * (P3_z_t + P3_z_l);
122 
123  // the plane is defined by P1-P3 and P2-P3; since P3 is at r=0 we
124  // only need the z.
125  float D1_z_l = P1_z_l - P3_z_l;
126  float D2_z_l = P2_z_l - P3_z_l;
127 
128  // the normal is then the cross product...
129  float n_x_l = (P1_y_l * D2_z_l) - (D1_z_l * P2_y_l);
130  float n_y_l = (D1_z_l * P2_x_l) - (P1_x_l * D2_z_l);
131  float n_z_l = (P1_x_l * P2_y_l) - (P1_y_l * P2_x_l);
132 
133  edm::LogVerbatim("TrackerGeom") << "DDCutTubsFromPoints: l_Pos (" << n_x_l << "," << n_y_l << "," << n_z_l << ")";
134 
135  // ... normalized.
136  // flip the sign here (but not for t) since root wants it like that.
137  float norm = -sqrt(n_x_l * n_x_l + n_y_l * n_y_l + n_z_l * n_z_l);
138  n_x_l /= norm;
139  n_y_l /= norm;
140  n_z_l /= norm;
141 
142  edm::LogVerbatim("TrackerGeom") << "DDCutTubsFromPoints: l_norm " << norm;
143 
144  // same game for the t side.
145  float D1_z_t = P1_z_t - P3_z_t;
146  float D2_z_t = P2_z_t - P3_z_t;
147 
148  float n_x_t = (P1_y_t * D2_z_t) - (D1_z_t * P2_y_t);
149  float n_y_t = (D1_z_t * P2_x_t) - (P1_x_t * D2_z_t);
150  float n_z_t = (P1_x_t * P2_y_t) - (P1_y_t * P2_x_t);
151 
152  edm::LogVerbatim("TrackerGeom") << "DDCutTubsFromPoints: t_Pos (" << n_x_t << "," << n_y_t << "," << n_z_t << ")";
153 
154  norm = sqrt(n_x_t * n_x_t + n_y_t * n_y_t + n_z_t * n_z_t);
155 
156  edm::LogVerbatim("TrackerGeom") << "DDCutTubsFromPoints: t_norm " << norm;
157 
158  n_x_t /= norm;
159  n_y_t /= norm;
160  n_z_t /= norm;
161 
162  auto seg = dd4hep::CutTube(r_min, r_max, dz, phi1, phi2, n_x_l, n_y_l, n_z_l, n_x_t, n_y_t, n_z_t);
163 
164  edm::LogVerbatim("TrackerGeom") << "DDCutTubsFromPoints: CutTube(" << r_min << "," << r_max << "," << dz << ","
165  << phi1 << "," << phi2 << "," << n_x_l << "," << n_y_l << "," << n_z_l << ","
166  << n_x_t << "," << n_y_t << "," << n_z_t << ")";
167 
168  segments.emplace_back(seg);
169  offsets.emplace_back(offset);
170  }
171 
172  s1 = s2;
173  }
174 
175  assert(segments.size() >= 2); // less would be special cases
176 
177  dd4hep::Solid solid = segments[0];
178 
179  // placement happens relative to the first member of the union
180  float shift = offsets[0];
181 
182  for (unsigned i = 1; i < segments.size() - 1; i++) {
183  solid = dd4hep::UnionSolid(
184  solidOutput + "_uni" + std::to_string(i + 1), solid, segments[i], dd4hep::Position(0., 0., offsets[i] - shift));
185  }
186 
187  solid = dd4hep::UnionSolid(solidOutput,
188  solid,
189  segments[segments.size() - 1],
190  dd4hep::Position(0., 0., offsets[segments.size() - 1] - shift));
191 
192  // remove the common offset from the input, to get sth. aligned at z=0.
193  float offset = -shift + (min_z + 0.5 * (max_z - min_z));
194 
195  auto logical = dd4hep::Volume(solidOutput, solid, ns.material(material));
196 
197  int nCopy = 1;
198  auto pos = dd4hep::Position(0., 0., z_pos - offset);
199  mother.placeVolume(logical, nCopy, dd4hep::Transform3D(dd4hep::Rotation3D(), pos));
200 
201  mother.placeVolume(logical, nCopy + 1, dd4hep::Transform3D(ns.rotation("pixfwdCommon:Z180"), pos));
202 
203  return cms::s_executed;
204 }
205 
206 // first argument is the type from the xml file
207 DECLARE_DDCMS_DETELEMENT(DDCMS_track_DDCutTubsFromPoints, algorithm)
writedatasetfile.args
args
Definition: writedatasetfile.py:18
mps_fire.i
i
Definition: mps_fire.py:428
cms_units::operators
Definition: CMSUnits.h:13
MessageLogger.h
DECLARE_DDCMS_DETELEMENT
#define DECLARE_DDCMS_DETELEMENT(name, func)
Definition: DDPlugins.h:25
cms::DDNamespace::material
dd4hep::Material material(const std::string &name) const
Definition: DDNamespace.cc:116
cms::DDNamespace::vecFloat
std::vector< float > vecFloat(const std::string &name) const
Definition: DDNamespace.cc:270
cms::DDParsingContext
Definition: DDParsingContext.h:13
cms::DDNamespace
Definition: DDNamespace.h:16
algorithm
static long algorithm(dd4hep::Detector &, cms::DDParsingContext &ctxt, xml_h e)
Definition: DDCutTubsFromPoints.cc:9
pos
Definition: PixelAliasList.h:18
cms::cuda::assert
assert(be >=bs)
indexGen.s2
s2
Definition: indexGen.py:107
funct::sin
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
alignCSCRings.s
s
Definition: alignCSCRings.py:92
funct::cos
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
mathSSE::sqrt
T sqrt(T t)
Definition: SSEVec.h:19
PixelTestBeamValidation_cfi.Position
Position
Definition: PixelTestBeamValidation_cfi.py:75
cms::DDNamespace::rotation
const dd4hep::Rotation3D & rotation(const std::string &name) const
Definition: DDNamespace.cc:125
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
cms::Volume
dd4hep::Volume Volume
Definition: DDFilteredView.h:47
DDPlugins.h
cms::DDAlgoArguments
Definition: DDAlgoArguments.h:28
cms::s_executed
static constexpr long s_executed
Definition: DDAlgoArguments.h:16
alignCSCRings.r
r
Definition: alignCSCRings.py:93
align::Detector
Definition: StructureType.h:86
edm::shift
static unsigned const int shift
Definition: LuminosityBlockID.cc:7
PVValHelper::dz
Definition: PVValidationHelpers.h:50
edm::LogVerbatim
Log< level::Info, true > LogVerbatim
Definition: MessageLogger.h:128
CMSUnits.h
dqm-mbProfile.log
log
Definition: dqm-mbProfile.py:17
unpackBuffers-CaloStage1.offsets
offsets
Definition: unpackBuffers-CaloStage1.py:127
hltrates_dqm_sourceclient-live_cfg.offset
offset
Definition: hltrates_dqm_sourceclient-live_cfg.py:82
cms::DDNamespace::name
std::string_view name() const
Definition: DDNamespace.h:72
cms::DDNamespace::volume
dd4hep::Volume volume(const std::string &name, bool exc=true) const
Definition: DDNamespace.cc:205
MillePedeFileConverter_cfg.e
e
Definition: MillePedeFileConverter_cfg.py:37