CMS 3D CMS Logo

DDCutTubsFromPoints.cc
Go to the documentation of this file.
1 // File: DDCutTubsFromPoints.cc
3 // Description: Create a ring of CutTubs segments from points on the rim.
5 
6 #include <cmath>
7 #include <string>
8 
14 #include "CLHEP/Units/GlobalPhysicalConstants.h"
15 #include "CLHEP/Units/GlobalSystemOfUnits.h"
16 
17 
19  LogDebug("TrackerGeom") <<"DDCutTubsFromPoints info: Creating an instance";
20 }
21 
23 
25  const DDVectorArguments & vArgs,
26  const DDMapArguments & ,
27  const DDStringArguments & sArgs,
28  const DDStringVectorArguments &) {
29 
30  r_min = nArgs["rMin"];
31  r_max = nArgs["rMax"];
32  z_pos = nArgs["zPos"];
33  material = DDMaterial(sArgs["Material"]);
34 
35  auto phis_name = DDName(sArgs["Phi"]);
36  auto z_ls_name = DDName(sArgs["z_l"]);
37  auto z_ts_name = DDName(sArgs["z_t"]);
38  DDVector phis(phis_name);
39  DDVector z_ls(z_ls_name);
40  DDVector z_ts(z_ts_name);
41 
42  assert(phis.size() == z_ls.size());
43  assert(phis.size() == z_ts.size());
44 
45  for (unsigned i = 0; i < phis.size(); i++) {
46  Section s = {phis[i], z_ls[i], z_ts[i] };
47  sections.emplace_back(s);
48  }
49  assert(!sections.empty());
50 
51  solidOutput = DDName(sArgs["SolidName"]);
52 
53  std::string idNameSpace = DDCurrentNamespace::ns();
54  DDName parentName = parent().name();
55  LogDebug("TrackerGeom") << "DDCutTubsFromPoints debug: Parent " << parentName
56  << "\tSolid " << solidOutput << " NameSpace "
57  << idNameSpace
58  << "\tnumber of sections " << sections.size();
59 }
60 
61 static double square(double x) {
62  return x*x;
63 }
64 
65 
67 
68  // radius for plane calculations
69  // We use r_max here, since P3 later has a Z that is always more inside
70  // than the extreme points. This means the cutting planes have outwards
71  // slopes in r-Z, and the corner at r_max could stick out of the bounding
72  // volume otherwise.
73  double r = r_max;
74 
75  // min and max z for the placement in the end
76  double min_z = 1e9;
77  double max_z = -1e9;
78 
79  // counter of actually produced segments (excluding skipped ones)
80  int segment = 0;
81 
82  // the segments and their corresponding offset (absolute, as in the input)
83  std::vector<DDSolid> segments;
84  std::vector<double> offsets;
85 
86  Section s1 = sections[0];
87  for (Section s2 : sections) {
88  if (s1.phi != s2.phi) {
89  segment++;
90  // produce segment s1-s2.
91  DDName segname (solidOutput.name() + "_seg_" + std::to_string(segment),
92  solidOutput.ns());
93 
94  double phi1 = s1.phi;
95  double phi2 = s2.phi;
96 
97  // track the min/max to properly place&align later
98  if (s2.z_l < min_z) min_z = s2.z_l;
99  if (s2.z_t > max_z) max_z = s2.z_t;
100 
101  double P1_z_l = s1.z_l;
102  double P1_z_t = s1.z_t;
103  double P2_z_l = s2.z_l;
104  double P2_z_t = s2.z_t;
105 
106  double P1_x_t = cos(phi1) * r;
107  double P1_x_l = cos(phi1) * r;
108  double P1_y_t = sin(phi1) * r;
109  double P1_y_l = sin(phi1) * r;
110 
111  double P2_x_t = cos(phi2) * r;
112  double P2_x_l = cos(phi2) * r;
113  double P2_y_t = sin(phi2) * r;
114  double P2_y_l = sin(phi2) * r;
115 
116  // each cutting plane is defined by P1-3. P1-2 are corners of the
117  // segment, P3 is at r=0 with the "average" z to get a nice cut.
118  double P3_z_l = (P1_z_l + P2_z_l) / 2;
119  double P3_z_t = (P1_z_t + P2_z_t) / 2;
120 
121  // we only have one dz to position both planes. The anchor is implicitly
122  // between the P3's, we have to use an offset later to make the segments
123  // line up correctly.
124  double dz = (P3_z_t - P3_z_l) / 2;
125  double offset = (P3_z_t + P3_z_l) / 2;
126 
127  // the plane is defined by P1-P3 and P2-P3; since P3 is at r=0 we
128  // only need the z.
129  double D1_z_l = P1_z_l - P3_z_l;
130  double D2_z_l = P2_z_l - P3_z_l;
131 
132  // the normal is then the cross product...
133  double n_x_l = (P1_y_l * D2_z_l) - (D1_z_l * P2_y_l);
134  double n_y_l = (D1_z_l * P2_x_l) - (P1_x_l * D2_z_l);
135  double n_z_l = (P1_x_l * P2_y_l) - (P1_y_l * P2_x_l);
136 
137  // ... normalized.
138  // flip the sign here (but not for t) since root wants it like that.
139  double norm = -sqrt(square(n_x_l) + square(n_y_l) + square(n_z_l));
140  n_x_l /= norm;
141  n_y_l /= norm;
142  n_z_l /= norm;
143 
144  // same game for the t side.
145  double D1_z_t = P1_z_t - P3_z_t;
146  double D2_z_t = P2_z_t - P3_z_t;
147 
148  double n_x_t = (P1_y_t * D2_z_t) - (D1_z_t * P2_y_t);
149  double n_y_t = (D1_z_t * P2_x_t) - (P1_x_t * D2_z_t);
150  double n_z_t = (P1_x_t * P2_y_t) - (P1_y_t * P2_x_t);
151 
152  norm = sqrt(square(n_x_t) + square(n_y_t) + square(n_z_t));
153  n_x_t /= norm;
154  n_y_t /= norm;
155  n_z_t /= norm;
156 
157  // the cuttubs wants a delta phi
158  double dphi = phi2 - phi1;
159 
160  DDSolid seg = DDSolidFactory::cuttubs(segname, dz, r_min, r_max, phi1, dphi,
161  n_x_l, n_y_l, n_z_l,
162  n_x_t, n_y_t, n_z_t);
163  segments.emplace_back(seg);
164  offsets.emplace_back(offset);
165  }
166  s1 = s2;
167  }
168 
169  assert(segments.size() >= 2); // less would be special cases
170 
171  DDSolid solid = segments[0];
172  // placment happens relative to the first member of the union
173  double shift = offsets[0];
174 
175  for (unsigned i = 1; i < segments.size()-1; i++) {
176  // each sub-union needs a name. Well.
177  DDName unionname(solidOutput.name() + "_uni_" + std::to_string(i+1),
178  solidOutput.ns());
179  solid = DDSolidFactory::unionSolid(unionname, solid, segments[i],
180  DDTranslation(0, 0, offsets[i] - shift),
181  DDRotation());
182  }
183 
184  solid = DDSolidFactory::unionSolid(solidOutput, solid, segments[segments.size()-1],
185  DDTranslation(0, 0, offsets[segments.size()-1] - shift),
186  DDRotation());
187 
188  // remove the common offset from the input, to get sth. aligned at z=0.
189  double offset = - shift + (min_z + (max_z-min_z)/2);
190 
192 
193  // This is not as generic as the name promises, but it is hard to make a
194  // solid w/o placing it.
195  DDRotation rot180("pixfwdCommon:Z180");
196  cpv.position(logical, parent(), 1, DDTranslation(0, 0, z_pos - offset), DDRotation());
197  cpv.position(logical, parent(), 2, DDTranslation(0, 0, z_pos - offset), rot180);
198 
199 }
#define LogDebug(id)
DDMaterial is used to define and access material information.
Definition: DDMaterial.h:43
std::vector< Section > sections
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
size_t size() const
the size of the array of values
Definition: DDVector.h:38
const std::string & ns() const
Returns the namespace.
Definition: DDName.cc:67
DDName is used to identify DDD entities uniquely.
Definition: DDName.h:15
static std::string & ns()
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:80
A DDSolid represents the shape of a part.
Definition: DDSolid.h:39
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DDTranslation
Definition: DDTranslation.h:7
Represents a uniquely identifyable rotation matrix.
Definition: DDTransform.h:68
void initialize(const DDNumericArguments &nArgs, const DDVectorArguments &vArgs, const DDMapArguments &mArgs, const DDStringArguments &sArgs, const DDStringVectorArguments &vsArgs) override
static DDSolid cuttubs(const DDName &name, double zhalf, double rIn, double rOut, double startPhi, double deltaPhi, double lx, double ly, double lz, double tx, double ty, double tz)
Definition: DDSolid.cc:874
T sqrt(T t)
Definition: SSEVec.h:18
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
A DDLogicalPart aggregates information concerning material, solid and sensitveness ...
Definition: DDLogicalPart.h:93
a named constant corresponding to the DDL-XML tag <Constant> and <ConstantsVector> ...
Definition: DDVector.h:18
static double square(double x)
void position(const DDLogicalPart &self, const DDLogicalPart &parent, const std::string &copyno, const DDTranslation &trans, const DDRotation &rot, const DDDivision *div=0)
static unsigned int const shift
static DDSolid unionSolid(const DDName &name, const DDSolid &a, const DDSolid &b, const DDTranslation &t, const DDRotation &r)
Definition: DDSolid.cc:765
const std::string & name() const
Returns the name.
Definition: DDName.cc:53
void execute(DDCompactView &cpv) override