CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
DD4hep_volumeHandle.cc
Go to the documentation of this file.
1 /*
2  * See header file for a description of this class.
3  *
4  * \author N. Amapane - INFN Torino (original developer)
5  */
6 
7 #include "DD4hep_volumeHandle.h"
8 
16 
17 #include <DD4hep/DD4hepUnits.h>
18 
19 #include <string>
20 #include <iterator>
21 
22 using namespace SurfaceOrientation;
23 using namespace std;
24 using namespace magneticfield;
25 using namespace edm;
26 
27 using DDBox = dd4hep::Box;
28 using DDTrap = dd4hep::Trap;
29 using DDTubs = dd4hep::Tube;
30 using DDCons = dd4hep::ConeSegment;
31 using DDTruncTubs = dd4hep::TruncatedTube;
32 
33 volumeHandle::volumeHandle(const cms::DDFilteredView &fv, bool expand2Pi, bool debugVal)
34  : BaseVolumeHandle(expand2Pi, debugVal), theShape(fv.legacyShape(fv.shape())), solid(fv) {
35  name = fv.name();
36  copyno = fv.copyNum();
37  const auto *const transArray = fv.trans();
38 
39  // Convert from DD4hep units to cm
40  center_ = GlobalPoint(transArray[0] / dd4hep::cm, transArray[1] / dd4hep::cm, transArray[2] / dd4hep::cm);
41 
42  // ASSUMPTION: volume names ends with "_NUM" where NUM is the volume number
43  string volName = name;
44  volName.erase(0, volName.rfind('_') + 1);
45  volumeno = static_cast<unsigned short>(std::atoi(volName.c_str()));
46 
47  for (int i = 0; i < 6; ++i) {
48  isAssigned[i] = false;
49  }
50  referencePlane(fv);
51  switch (theShape) {
52  case DDSolidShape::ddbox: {
53  DDBox box(solid.solid());
54  // Convert from DD4hep units to cm
55  double halfX = box.x() / dd4hep::cm;
56  double halfY = box.y() / dd4hep::cm;
57  double halfZ = box.z() / dd4hep::cm;
58  buildBox(halfX, halfY, halfZ);
59  } break;
60  case DDSolidShape::ddtrap: {
61  DDTrap trap(solid.solid());
62  double x1 = trap.bottomLow1() / dd4hep::cm;
63  double x2 = trap.topLow1() / dd4hep::cm;
64  double x3 = trap.bottomLow2() / dd4hep::cm;
65  double x4 = trap.topLow2() / dd4hep::cm;
66  double y1 = trap.high1() / dd4hep::cm;
67  double y2 = trap.high2() / dd4hep::cm;
68  double theta = trap.theta();
69  double phi = trap.phi();
70  double halfZ = trap.dZ() / dd4hep::cm;
71  double alpha1 = trap.alpha1();
72  double alpha2 = trap.alpha2();
73  buildTrap(x1, x2, x3, x4, y1, y2, theta, phi, halfZ, alpha1, alpha2);
74  } break;
75 
76  case DDSolidShape::ddcons: {
77  DDCons cons(solid.solid());
78  double zhalf = cons.dZ() / dd4hep::cm;
79  double rInMinusZ = cons.rMin1() / dd4hep::cm;
80  double rOutMinusZ = cons.rMax1() / dd4hep::cm;
81  double rInPlusZ = cons.rMin2() / dd4hep::cm;
82  double rOutPlusZ = cons.rMax2() / dd4hep::cm;
83  double startPhi = cons.startPhi();
84  double deltaPhi = reco::deltaPhi(cons.endPhi(), startPhi);
85  buildCons(zhalf, rInMinusZ, rOutMinusZ, rInPlusZ, rOutPlusZ, startPhi, deltaPhi);
86  } break;
87  case DDSolidShape::ddtubs: {
88  DDTubs tubs(solid.solid());
89  double zhalf = tubs.dZ() / dd4hep::cm;
90  double rIn = tubs.rMin() / dd4hep::cm;
91  double rOut = tubs.rMax() / dd4hep::cm;
92  double startPhi = tubs.startPhi();
93  double deltaPhi = tubs.endPhi() - startPhi;
94  buildTubs(zhalf, rIn, rOut, startPhi, deltaPhi);
95  } break;
97  vector<double> d = solid.parameters();
98 
99  // The pseudo-trapezoid parameters are:
100  // d[0] -- x1
101  // d[1] -- x2
102  // d[2] -- y1
103  // d[3] -- y2
104  // d[4] -- halfZ
105  // d[5] -- radius
106  // d[6] -- atMinusZ (0 or 1)
107  // Note all are lengths except for the last one. The lengths come from
108  // DD4hep in DD4hep units and must be converted to cm for use.
109 
110  if (d.size() >= 7)
111  LogTrace("MagGeoBuilder") << " Pseudo trap params raw = " << d[0] << ", " << d[1] << ", " << d[2] << ", "
112  << d[3] << ", " << d[4] << ", " << d[5] << ", " << d[6];
113 
114  // Convert all but last parameter to cm (last one is a boolean).
115  transform(d.begin(), --(d.end()), d.begin(), [](double val) { return val / dd4hep::cm; });
116 
117  if (d.size() >= 7)
118  LogTrace("MagGeoBuilder") << " Pseudo trap params converted = " << d[0] << ", " << d[1] << ", " << d[2] << ", "
119  << d[3] << ", " << d[4] << ", " << d[5] << ", " << d[6];
120 
121  buildPseudoTrap(d[0], d[1], d[2], d[3], d[4], d[5], static_cast<bool>(d[6]));
122  } break;
124  DDTruncTubs tubs(solid.solid());
125  double zhalf = tubs.dZ() / dd4hep::cm; // half of the z-Axis
126  double rIn = tubs.rMin() / dd4hep::cm; // inner radius
127  double rOut = tubs.rMax() / dd4hep::cm; // outer radius
128  double startPhi = tubs.startPhi(); // angular start of the tube-section
129  double deltaPhi = tubs.deltaPhi(); // angular span of the tube-section
130  double cutAtStart = tubs.cutAtStart() / dd4hep::cm; // truncation at begin of the tube-section
131  double cutAtDelta = tubs.cutAtDelta() / dd4hep::cm; // truncation at end of the tube-section
132  bool cutInside = tubs.cutInside(); // true, if truncation is on the inner side of the tube-section
133  buildTruncTubs(zhalf, rIn, rOut, startPhi, deltaPhi, cutAtStart, cutAtDelta, cutInside);
134  } break;
135  default:
136  LogError("magneticfield::volumeHandle")
137  << "ctor: Unexpected shape # " << static_cast<int>(theShape) << " for vol " << name;
138  }
139 
140  // The only materials used in the geometry are: materials:Air, d=0.001214; materials:Iron, d=7.87
141  if (fv.volume().material().density() > 3.)
142  isIronFlag = true;
143 
144  if (debug) {
145  LogTrace("MagGeoBuilder") << " RMin = " << theRMin << newln << " RMax = " << theRMax;
146 
147  if (theRMin < 0 || theRN < theRMin || theRMax < theRN)
148  LogTrace("MagGeoBuilder") << "*** WARNING: wrong RMin/RN/RMax";
149 
150  LogTrace("MagGeoBuilder") << "Summary: " << name << " " << copyno << " shape = " << theShape << " trasl "
151  << center() << " R " << center().perp() << " phi " << center().phi() << " magFile "
152  << magFile << " Material= " << fv.materialName() << " isIron= " << isIronFlag
153  << " masterSector= " << masterSector;
154 
155  LogTrace("MagGeoBuilder") << " Orientation of surfaces:";
156  std::string sideName[3] = {"positiveSide", "negativeSide", "onSurface"};
157  for (int i = 0; i < 6; ++i) {
158  if (surfaces[i] != nullptr)
159  LogTrace("MagGeoBuilder") << " " << i << ":" << sideName[surfaces[i]->side(center_, 0.3)];
160  }
161  }
162 }
163 
165  // The refPlane is the "main plane" for the solid. It corresponds to the
166  // x,y plane in the DDD local frame, and defines a frame where the local
167  // coordinates are the same as in DDD.
168  // In the geometry version 85l_030919, this plane is normal to the
169  // beam line for all volumes but pseudotraps, so that global R is along Y,
170  // global phi is along -X and global Z along Z:
171  //
172  // Global(for vol at pi/2) Local
173  // +R (+Y) +Y
174  // +phi(-X) -X
175  // +Z +Z
176  //
177  // For pseudotraps the refPlane is parallel to beam line and global R is
178  // along Z, global phi is along +-X and and global Z along Y:
179  //
180  // Global(for vol at pi/2) Local
181  // +R (+Y) +Z
182  // +phi(-X) +X
183  // +Z +Y
184  //
185  // Note that the frame is centered in the DDD volume center, which is
186  // inside the volume for DDD boxes and (pesudo)trapezoids, on the beam line
187  // for tubs, cons and trunctubs.
188 
189  // In geometry version 1103l, trapezoids have X and Z in the opposite direction
190  // than the above. Boxes are either oriented as described above or in some case
191  // have opposite direction for Y and X.
192 
193  // The global position
194  Surface::PositionType &posResult = center_;
195 
196  // The reference plane rotation
197  math::XYZVector x, y, z;
198  dd4hep::Rotation3D refRot;
199  fv.rot(refRot);
200  refRot.GetComponents(x, y, z);
201  if (debug) {
202  if (x.Cross(y).Dot(z) < 0.5) {
203  LogTrace("MagGeoBuilder") << "*** WARNING: Rotation is not RH ";
204  }
205  }
206 
207  // The global rotation
208  Surface::RotationType rotResult(float(x.X()),
209  float(x.Y()),
210  float(x.Z()),
211  float(y.X()),
212  float(y.Y()),
213  float(y.Z()),
214  float(z.X()),
215  float(z.Y()),
216  float(z.Z()));
217 
218  refPlane = new GloballyPositioned<float>(posResult, rotResult);
219 
220  // Check correct orientation
221  if (debug) {
222  LogTrace("MagGeoBuilder") << "Refplane pos " << refPlane->position();
223 
224  // See comments above for the conventions for orientation.
225  LocalVector globalZdir(0., 0., 1.); // Local direction of the axis along global Z
226 
228  globalZdir = LocalVector(0., 1., 0.);
229  }
230 
231  if (refPlane->toGlobal(globalZdir).z() < 0.) {
232  globalZdir = -globalZdir;
233  }
234  float chk = refPlane->toGlobal(globalZdir).dot(GlobalVector(0, 0, 1));
235  if (chk < .999)
236  LogTrace("MagGeoBuilder") << "*** WARNING RefPlane check failed!***" << chk;
237  }
238 }
239 
240 std::vector<VolumeSide> volumeHandle::sides() const {
241  std::vector<VolumeSide> result;
242  for (int i = 0; i < 6; ++i) {
243  // If this is just a master volume out of wich a 2pi volume
244  // should be built (e.g. central cylinder), skip the phi boundaries.
245  if (expand && (i == phiplus || i == phiminus))
246  continue;
247 
248  // FIXME: Skip null inner degenerate cylindrical surface
250  continue;
251 
252  ReferenceCountingPointer<Surface> s = const_cast<Surface *>(surfaces[i].get());
253  result.push_back(VolumeSide(s, GlobalFace(i), surfaces[i]->side(center_, 0.3)));
254  }
255  return result;
256 }
257 
258 #include "buildBox.icc"
259 #include "buildTrap.icc"
260 #include "buildTubs.icc"
261 #include "buildCons.icc"
262 #include "buildPseudoTrap.icc"
263 #include "buildTruncTubs.icc"
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
void buildBox(double halfX, double halfY, double halfZ)
MagGeoBuilderFromDDD::volumeHandle volumeHandle
A truncated tube section.
Definition: DDSolid.h:139
T perp() const
Definition: PV3DBase.h:69
Surface::LocalVector LocalVector
std::string_view materialName() const
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
Geom::Theta< T > theta() const
Log< level::Error, false > LogError
const PlacedVolume volume() const
The physical volume of the current node.
unsigned short volumeno
volume number
const char *const newln
#define LogTrace(id)
unsigned short copyno
copy number
tuple result
Definition: mps_fire.py:311
tuple d
Definition: ztail.py:151
unsigned short copyNum() const
GloballyPositioned< float > * refPlane
void referencePlane(const cms::DDFilteredView &fv)
double startPhi(void) const
Definition: DDSolid.cc:460
Surface::GlobalPoint GlobalPoint
T z() const
Definition: PV3DBase.h:61
void buildTrap(double x1, double x2, double x3, double x4, double y1, double y2, double theta, double phi, double halfZ, double alpha1, double alpha2)
const Double_t * rot() const
The absolute rotation of the current node.
void buildTruncTubs(double zhalf, double rIn, double rOut, double startPhi, double deltaPhi, double cutAtStart, double cutAtDelta, bool cutInside)
Interface to a Trapezoid.
Definition: DDSolid.h:88
int masterSector
The sector for which an interpolator for this class of volumes should be built.
std::string_view name() const
void buildPseudoTrap(double x1, double x2, double y1, double y2, double halfZ, double radius, bool atMinusZ)
const GlobalPoint & center() const
Return the center of the volume.
GlobalPoint toGlobal(const LocalPoint &lp) const
const Double_t * trans() const
The absolute translation of the current node.
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
Interface to a Box.
Definition: DDSolid.h:167
std::string name
Name of the volume.
void buildCons(double zhalf, double rInMinusZ, double rOutMinusZ, double rInPlusZ, double rOutPlusZ, double startPhi, double deltaPhi)
double startPhi(void) const
angular start of the tube-section
Definition: DDSolid.cc:172
std::vector< VolumeSide > sides() const override
The surfaces and they orientation, as required to build a MagVolume.
float x
const std::vector< double > parameters() const
extract shape parameters
const PositionType & position() const
dd4hep::Solid solid() const
std::string magFile
Name of magnetic field table file.
const cms::DDFilteredView & solid
Global3DVector GlobalVector
Definition: GlobalVector.h:10
void buildTubs(double zhalf, double rIn, double rOut, double startPhi, double deltaPhi)
unsigned transform(const HcalDetId &id, unsigned transformCode)