CMS 3D CMS Logo

MkFitGeometryESProducer.cc
Go to the documentation of this file.
3 
11 
14 
15 // mkFit includes
21 
22 #include <sstream>
23 
24 // #define DUMP_MKF_GEO
25 
26 //------------------------------------------------------------------------------
27 
29 public:
31 
32  static void fillDescriptions(edm::ConfigurationDescriptions &descriptions);
33 
34  std::unique_ptr<MkFitGeometry> produce(const TrackerRecoGeometryRecord &iRecord);
35 
36 private:
37  struct GapCollector {
38  struct Interval {
39  float x, y;
40  };
41 
43  void extend_current(float q) {
46  }
48 
49  void add_interval(float x, float y);
50 
51  void sqrt_elements();
52  bool find_gap(Interval &itvl, float eps);
53  void print_gaps(std::ostream &ostr);
54 
55  std::list<Interval> m_coverage;
57  };
58  typedef std::unordered_map<int, GapCollector> layer_gap_map_t;
59 
60  void considerPoint(const GlobalPoint &gp, mkfit::LayerInfo &lay_info);
61  void fillShapeAndPlacement(const GeomDet *det, mkfit::TrackerInfo &trk_info, layer_gap_map_t *lgc_map = nullptr);
62  void addPixBGeometry(mkfit::TrackerInfo &trk_info);
63  void addPixEGeometry(mkfit::TrackerInfo &trk_info);
64  void addTIBGeometry(mkfit::TrackerInfo &trk_info);
65  void addTOBGeometry(mkfit::TrackerInfo &trk_info);
66  void addTIDGeometry(mkfit::TrackerInfo &trk_info);
67  void addTECGeometry(mkfit::TrackerInfo &trk_info);
68 
72 
73  const TrackerTopology *trackerTopo_ = nullptr;
74  const TrackerGeometry *trackerGeom_ = nullptr;
76 };
77 
79  auto cc = setWhatProduced(this);
80  geomToken_ = cc.consumes();
81  ttopoToken_ = cc.consumes();
82  trackerToken_ = cc.consumes();
83 }
84 
87  descriptions.addWithDefaultLabel(desc);
88 }
89 
90 //------------------------------------------------------------------------------
91 
93  if (x > y)
94  std::swap(x, y);
95  bool handled = false;
96  for (auto i = m_coverage.begin(); i != m_coverage.end(); ++i) {
97  if (y < i->x) { // fully on 'left'
98  m_coverage.insert(i, {x, y});
99  handled = true;
100  break;
101  } else if (x > i->y) { // fully on 'right'
102  continue;
103  } else if (x < i->x) { // sticking out on 'left'
104  i->x = x;
105  handled = true;
106  break;
107  } else if (y > i->y) { // sticking out on 'right'
108  i->y = y;
109  // check for overlap with the next interval, potentially merge
110  auto j = i;
111  ++j;
112  if (j != m_coverage.end() && i->y >= j->x) {
113  i->y = j->y;
114  m_coverage.erase(j);
115  }
116  handled = true;
117  break;
118  } else { // contained in current interval
119  handled = true;
120  break;
121  }
122  }
123  if (!handled) {
124  m_coverage.push_back({x, y});
125  }
126 }
127 
129  for (auto &itvl : m_coverage) {
130  itvl.x = std::sqrt(itvl.x);
131  itvl.y = std::sqrt(itvl.y);
132  }
133 }
134 
136  auto i = m_coverage.begin();
137  while (i != m_coverage.end()) {
138  auto j = i;
139  ++j;
140  if (j != m_coverage.end()) {
141  if (j->x - i->y > eps) {
142  itvl = {i->y, j->x};
143  return true;
144  }
145  i = j;
146  } else {
147  break;
148  }
149  }
150  return false;
151 }
152 
154  auto i = m_coverage.begin();
155  while (i != m_coverage.end()) {
156  auto j = i;
157  ++j;
158  if (j != m_coverage.end()) {
159  ostr << "(" << i->y << ", " << j->x << ")->" << j->x - i->y;
160  i = j;
161  } else {
162  break;
163  }
164  }
165 }
166 
167 //------------------------------------------------------------------------------
168 
170  // Use radius squared during bounding-region search.
171  float r = gp.perp2(), z = gp.z();
172  li.extend_limits(r, z);
173 }
174 
176  mkfit::TrackerInfo &trk_info,
177  layer_gap_map_t *lgc_map) {
178  DetId detid = det->geographicalId();
179 
180  float xy[4][2];
181  float dz;
182  const Bounds *b = &((det->surface()).bounds());
183 
184  if (const TrapezoidalPlaneBounds *b2 = dynamic_cast<const TrapezoidalPlaneBounds *>(b)) {
185  // See sec. "TrapezoidalPlaneBounds parameters" in doc/reco-geom-notes.txt
186  std::array<const float, 4> const &par = b2->parameters();
187  xy[0][0] = -par[0];
188  xy[0][1] = -par[3];
189  xy[1][0] = -par[1];
190  xy[1][1] = par[3];
191  xy[2][0] = par[1];
192  xy[2][1] = par[3];
193  xy[3][0] = par[0];
194  xy[3][1] = -par[3];
195  dz = par[2];
196 
197 #ifdef DUMP_MKF_GEO
198  printf("TRAP 0x%x %f %f %f %f ", detid.rawId(), par[0], par[1], par[2], par[3]);
199 #endif
200  } else if (const RectangularPlaneBounds *b2 = dynamic_cast<const RectangularPlaneBounds *>(b)) {
201  // Rectangular
202  float dx = b2->width() * 0.5; // half width
203  float dy = b2->length() * 0.5; // half length
204  xy[0][0] = -dx;
205  xy[0][1] = -dy;
206  xy[1][0] = -dx;
207  xy[1][1] = dy;
208  xy[2][0] = dx;
209  xy[2][1] = dy;
210  xy[3][0] = dx;
211  xy[3][1] = -dy;
212  dz = b2->thickness() * 0.5; // half thickness
213 
214 #ifdef DUMP_MKF_GEO
215  printf("RECT 0x%x %f %f %f ", detid.rawId(), dx, dy, dz);
216 #endif
217  } else {
218  throw cms::Exception("UnimplementedFeature") << "unsupported Bounds class";
219  }
220 
221  const bool useMatched = false;
222  int lay =
224  trackerTopo_->layer(detid),
225  useMatched,
226  trackerTopo_->isStereo(detid),
227  trackerTopo_->side(detid) == static_cast<unsigned>(TrackerDetSide::PosEndcap));
228 #ifdef DUMP_MKF_GEO
229  printf(" subdet=%d layer=%d side=%d is_stereo=%d --> mkflayer=%d\n",
230  detid.subdetId(),
231  trackerTopo_->layer(detid),
232  trackerTopo_->side(detid),
233  trackerTopo_->isStereo(detid),
234  lay);
235 #endif
236 
237  mkfit::LayerInfo &layer_info = trk_info.layer_nc(lay);
238  if (lgc_map) {
239  (*lgc_map)[lay].reset_current();
240  }
241  for (int i = 0; i < 4; ++i) {
242  Local3DPoint lp1(xy[i][0], xy[i][1], -dz);
243  Local3DPoint lp2(xy[i][0], xy[i][1], dz);
244  GlobalPoint gp1 = det->surface().toGlobal(lp1);
245  GlobalPoint gp2 = det->surface().toGlobal(lp2);
246  considerPoint(gp1, layer_info);
247  considerPoint(gp2, layer_info);
248  if (lgc_map) {
249  (*lgc_map)[lay].extend_current(gp1.perp2());
250  (*lgc_map)[lay].extend_current(gp2.perp2());
251  }
252  }
253  if (lgc_map) {
254  (*lgc_map)[lay].add_current();
255  }
256  // Module information
257  const auto &p = det->position();
258  auto z = det->rotation().z();
259  auto x = det->rotation().x();
260  layer_info.register_module({{p.x(), p.y(), p.z()}, {z.x(), z.y(), z.z()}, {x.x(), x.y(), x.z()}, detid.rawId()});
261  // Set some layer parameters (repeatedly, would require hard-coding otherwise)
262  layer_info.set_subdet(detid.subdetId());
263  layer_info.set_is_pixel(detid.subdetId() <= 2);
264  layer_info.set_is_stereo(trackerTopo_->isStereo(detid));
265 }
266 
267 //==============================================================================
268 
269 // These functions do the following:
270 // 0. Detect bounding cylinder of each layer.
271 // 1. Setup LayerInfo data.
272 // 2. Establish short module ids.
273 // 3. Store module normal and strip direction vectors.
274 // 4. Extract stereo coverage holes where they exist (TEC, all but last 3 double-layers).
275 //
276 // See python/dumpMkFitGeometry.py and dumpMkFitGeometryPhase2.py
277 
279 #ifdef DUMP_MKF_GEO
280  printf("\n*** addPixBGeometry\n\n");
281 #endif
282  for (auto &det : trackerGeom_->detsPXB()) {
283  fillShapeAndPlacement(det, trk_info);
284  }
285 }
286 
288 #ifdef DUMP_MKF_GEO
289  printf("\n*** addPixEGeometry\n\n");
290 #endif
291  for (auto &det : trackerGeom_->detsPXF()) {
292  fillShapeAndPlacement(det, trk_info);
293  }
294 }
295 
297 #ifdef DUMP_MKF_GEO
298  printf("\n*** addTIBGeometry\n\n");
299 #endif
300  for (auto &det : trackerGeom_->detsTIB()) {
301  fillShapeAndPlacement(det, trk_info);
302  }
303 }
304 
306 #ifdef DUMP_MKF_GEO
307  printf("\n*** addTOBGeometry\n\n");
308 #endif
309  for (auto &det : trackerGeom_->detsTOB()) {
310  fillShapeAndPlacement(det, trk_info);
311  }
312 }
313 
315 #ifdef DUMP_MKF_GEO
316  printf("\n*** addTIDGeometry\n\n");
317 #endif
318  for (auto &det : trackerGeom_->detsTID()) {
319  fillShapeAndPlacement(det, trk_info);
320  }
321 }
322 
324 #ifdef DUMP_MKF_GEO
325  printf("\n*** addTECGeometry\n\n");
326 #endif
327  // For TEC we also need to discover hole in radial extents.
328  layer_gap_map_t lgc_map;
329  for (auto &det : trackerGeom_->detsTEC()) {
330  fillShapeAndPlacement(det, trk_info, &lgc_map);
331  }
332  // Now loop over the GapCollectors and see if there is a coverage gap.
333  std::ostringstream ostr;
334  ostr << "addTECGeometry() gap report:\n";
336  for (auto &[layer, gcol] : lgc_map) {
337  gcol.sqrt_elements();
338  if (gcol.find_gap(itvl, 0.5)) {
339  ostr << " layer: " << layer << ", gap: " << itvl.x << " -> " << itvl.y << " width = " << itvl.y - itvl.x << "\n";
340  ostr << " all gaps: ";
341  gcol.print_gaps(ostr);
342  ostr << "\n";
343  trk_info.layer_nc(layer).set_r_hole_range(itvl.x, itvl.y);
344  }
345  }
346  edm::LogVerbatim("MkFitGeometryESProducer") << ostr.str();
347 }
348 
349 //------------------------------------------------------------------------------
350 // clang-format off
351 namespace {
352  const float phase1QBins[] = {
353  // PIXB, TIB, TOB
354  2.0, 2.0, 2.0, 2.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 9.5, 9.5, 9.5, 9.5, 9.5, 9.5, 9.5, 9.5,
355  // PIXE+, TID+, TEC+
356  1.0, 1.0, 1.0, 5.6, 5.6, 5.6, 5.6, 5.6, 5.6, 10.25, 7.5, 10.25, 7.5, 10.25, 7.5, 10.25, 7.5, 10.25, 7.5, 10.25, 7.5, 10.25, 7.5, 10.25, 7.5, 10.25, 7.5,
357  // PIXE-, TID-, TEC-
358  1.0, 1.0, 1.0, 5.6, 5.6, 5.6, 5.6, 5.6, 5.6, 10.25, 7.5, 10.25, 7.5, 10.25, 7.5, 10.25, 7.5, 10.25, 7.5, 10.25, 7.5, 10.25, 7.5, 10.25, 7.5, 10.25, 7.5
359  };
360  const float phase2QBins[] = {
361  // TODO: Review these numbers.
362  // PIXB, TOB
363  2.0, 2.0, 2.0, 2.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
364  // PIXE+, TEC+
365  1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 5.6, 5.6, 5.6, 5.6, 5.6, 5.6, 5.6, 5.6, 5.6, 5.6,
366  // PIXE-, TEC-
367  1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 5.6, 5.6, 5.6, 5.6, 5.6, 5.6, 5.6, 5.6, 5.6, 5.6
368  };
369 }
370 // clang-format on
371 //------------------------------------------------------------------------------
372 
373 std::unique_ptr<MkFitGeometry> MkFitGeometryESProducer::produce(const TrackerRecoGeometryRecord &iRecord) {
374  auto trackerInfo = std::make_unique<mkfit::TrackerInfo>();
375 
376  trackerGeom_ = &iRecord.get(geomToken_);
377  trackerTopo_ = &iRecord.get(ttopoToken_);
378 
379  const float *qBinDefaults = nullptr;
380 
381  // std::string path = "Geometry/TrackerCommonData/data/";
383  edm::LogInfo("MkFitGeometryESProducer") << "Extracting PhaseI geometry";
384  trackerInfo->create_layers(18, 27, 27);
385  qBinDefaults = phase1QBins;
388  edm::LogInfo("MkFitGeometryESProducer") << "Extracting PhaseII geometry";
390  trackerInfo->create_layers(16, 22, 22);
391  qBinDefaults = phase2QBins;
392  } else {
393  throw cms::Exception("UnimplementedFeature") << "unsupported / unknowen geometry version";
394  }
395 
396  // Prepare layer boundaries for bounding-box search
397  for (int i = 0; i < trackerInfo->n_layers(); ++i) {
398  auto &li = trackerInfo->layer_nc(i);
399  li.set_limits(
401  li.reserve_modules(256);
402  }
403  // This is sort of CMS-phase1 specific ... but fireworks code uses it for PhaseII as well.
404  addPixBGeometry(*trackerInfo);
405  addPixEGeometry(*trackerInfo);
406  addTIBGeometry(*trackerInfo);
407  addTIDGeometry(*trackerInfo);
408  addTOBGeometry(*trackerInfo);
409  addTECGeometry(*trackerInfo);
410 
411  // r_in/out kept as squares until here, root them
412  unsigned int n_mod = 0;
413  for (int i = 0; i < trackerInfo->n_layers(); ++i) {
414  auto &li = trackerInfo->layer_nc(i);
415  li.set_r_in_out(std::sqrt(li.rin()), std::sqrt(li.rout()));
416  li.set_propagate_to(li.is_barrel() ? li.r_mean() : li.z_mean());
417  li.set_q_bin(qBinDefaults[i]);
418  unsigned int maxsid = li.shrink_modules();
419 
420  n_mod += maxsid;
421 
422  // Make sure the short id fits in the 14 bits...
423  assert(maxsid < 1u << 13);
424  assert(n_mod > 0);
425  }
426 #ifdef DUMP_MKF_GEO
427  printf("Total number of modules %u, 14-bits fit up to %u modules\n", n_mod, 1u << 13);
428 #endif
429 
430  return std::make_unique<MkFitGeometry>(iRecord.get(geomToken_),
431  iRecord.get(trackerToken_),
432  iRecord.get(ttopoToken_),
433  std::move(trackerInfo),
434  layerNrConv_);
435 }
436 
const DetContainer & detsTIB() const
Log< level::Info, true > LogVerbatim
auto setWhatProduced(T *iThis, const es::Label &iLabel={})
Definition: ESProducer.h:163
void extend_limits(float r, float z)
Definition: TrackerInfo.cc:15
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
bool find_gap(Interval &itvl, float eps)
void addPixBGeometry(mkfit::TrackerInfo &trk_info)
void set_r_hole_range(float rh1, float rh2)
Definition: TrackerInfo.cc:31
const DetContainer & detsPXB() const
void addTOBGeometry(mkfit::TrackerInfo &trk_info)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
edm::ESGetToken< GeometricSearchTracker, TrackerRecoGeometryRecord > trackerToken_
const DetContainer & detsPXF() const
bool isStereo(const DetId &id) const
const TrackerTopology * trackerTopo_
unsigned int side(const DetId &id) const
assert(be >=bs)
MkFitGeometryESProducer(const edm::ParameterSet &iConfig)
LayerInfo & layer_nc(int l)
Definition: TrackerInfo.h:163
constexpr bool useMatched
unsigned int layer(const DetId &id) const
constexpr std::array< uint8_t, layerIndexSize > layer
const Surface::RotationType & rotation() const
The rotation defining the local R.F.
Definition: GeomDet.h:46
Basic3DVector< T > x() const
const DetContainer & detsTOB() const
edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > ttopoToken_
const TrackerGeometry * trackerGeom_
bool isThere(GeomDetEnumerators::SubDetector subdet) const
void addTIDGeometry(mkfit::TrackerInfo &trk_info)
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
T sqrt(T t)
Definition: SSEVec.h:19
Basic3DVector< T > z() const
void considerPoint(const GlobalPoint &gp, mkfit::LayerInfo &lay_info)
weight_default_t b2[10]
Definition: b2.h:9
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:64
#define DEFINE_FWK_EVENTSETUP_MODULE(type)
Definition: ModuleFactory.h:61
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
Definition: Surface.h:79
Log< level::Info, false > LogInfo
void fillShapeAndPlacement(const GeomDet *det, mkfit::TrackerInfo &trk_info, layer_gap_map_t *lgc_map=nullptr)
Definition: DetId.h:17
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
double b
Definition: hdecay.h:118
T perp2() const
Definition: PV3DBase.h:68
const Surface::PositionType & position() const
The position (origin of the R.F.)
Definition: GeomDet.h:43
void addPixEGeometry(mkfit::TrackerInfo &trk_info)
mkfit::LayerNumberConverter layerNrConv_
float x
std::unique_ptr< MkFitGeometry > produce(const TrackerRecoGeometryRecord &iRecord)
const DetContainer & detsTEC() const
Definition: Bounds.h:18
edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > geomToken_
ProductT const & get(ESGetToken< ProductT, DepRecordT > const &iToken) const
int convertLayerNumber(int det, int lay, bool useMatched, int isStereo, bool posZ) const
def move(src, dest)
Definition: eostools.py:511
void addTIBGeometry(mkfit::TrackerInfo &trk_info)
const DetContainer & detsTID() const
void addTECGeometry(mkfit::TrackerInfo &trk_info)
std::unordered_map< int, GapCollector > layer_gap_map_t