CMS 3D CMS Logo

GeometryInterface.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: SiPixelPhase1Common
4 // Class: GeometryInterface
5 //
6 // Geometry depedence goes here.
7 //
8 // Original Author: Marcel Schneider
9 
11 
12 // general plotting helpers
14 
15 // edm stuff
18 
19 // Tracker Geometry/Topology stuff
30 
31 // Pixel names
34 
35 // C++ stuff
36 #include <cassert>
37 #include <cstdint>
38 #include <iostream>
39 #include <iomanip>
40 #include <memory>
41 
43 
45  //loadFromAlignment(iSetup, iConfig);
46  loadFromTopology(iSetup, iConfig);
47  loadTimebased(iSetup, iConfig);
48  loadModuleLevel(iSetup, iConfig);
49  loadFEDCabling(iSetup, iConfig);
51  edm::LogInfo log("GeometryInterface");
52  log << "Known colum names:\n";
53  for (auto e : ids) log << "+++ column: " << e.first
54  << " ok " << bool(extractors[e.second]) << " min " << min_value[e.second] << " max " << max_value[e.second] << "\n";
55  is_loaded = true;
56 }
57 
59  // Get a Topology
60  edm::ESHandle<TrackerTopology> trackerTopologyHandle;
61  iSetup.get<TrackerTopologyRcd>().get(trackerTopologyHandle);
62  assert(trackerTopologyHandle.isValid());
63 
64  std::vector<ID> geomquantities;
65 
66  struct TTField {
67  const TrackerTopology* tt;
69  Value operator()(InterestingQuantities const& iq) {
70  if (tt->hasField(iq.sourceModule, field))
71  return tt->getField(iq.sourceModule, field);
72  else
73  return UNDEFINED;
74  };
75  };
76 
77  const TrackerTopology* tt = trackerTopologyHandle.operator->();
78 
79 
80  std::vector<std::pair<std::string, TTField>> namedPartitions {
81  {"PXEndcap" , {tt, TrackerTopology::PFSide}},
82 
83  {"PXLayer" , {tt, TrackerTopology::PBLayer}},
84  {"PXLadder" , {tt, TrackerTopology::PBLadder}},
85  {"PXBModule", {tt, TrackerTopology::PBModule}},
86 
87  {"PXBlade" , {tt, TrackerTopology::PFBlade}},
88  {"PXDisk" , {tt, TrackerTopology::PFDisk}},
89  {"PXPanel" , {tt, TrackerTopology::PFPanel}},
90  {"PXFModule", {tt, TrackerTopology::PFModule}},
91  };
92 
93  for (auto& e : namedPartitions) {
94  geomquantities.push_back(intern(e.first));
95  addExtractor(intern(e.first), e.second, UNDEFINED, UNDEFINED);
96  }
97 
98  auto pxbarrel = [] (InterestingQuantities const& iq) { return iq.sourceModule.subdetId() == PixelSubdetector::PixelBarrel ? 0 : UNDEFINED; };
99  auto pxforward = [] (InterestingQuantities const& iq) { return iq.sourceModule.subdetId() == PixelSubdetector::PixelEndcap ? 0 : UNDEFINED; };
100  addExtractor(intern("PXBarrel"), pxbarrel, 0, 0);
101  addExtractor(intern("PXForward"), pxforward, 0, 0);
102 
103  // Redefine the disk numbering to use the sign
104  auto pxendcap = extractors[intern("PXEndcap")];
105  auto diskid = intern("PXDisk");
106  auto pxdisk = extractors[diskid];
107  extractors[diskid] = [pxdisk, pxendcap] (InterestingQuantities const& iq) {
108  auto disk = pxdisk(iq);
109  if (disk == UNDEFINED) return UNDEFINED;
110  auto endcap = pxendcap(iq);
111  return endcap == 1 ? -disk : disk;
112  };
113 
114  // DetId and module names
115  auto detid = [] (InterestingQuantities const& iq) {
116  uint32_t id = iq.sourceModule.rawId();
117  return Value(id);
118  };
119  addExtractor(intern("DetId"), detid,
120  0, 0 // No sane value possible here.
121  );
122  // these are just aliases with special handling in formatting
123  // the names are created with PixelBarrelName et. al. later
124  addExtractor(intern("PXModuleName"), detid, 0, 0);
125 
126  int phase = iConfig.getParameter<int>("upgradePhase");
127  bool isUpgrade = phase == 1;
128 
129  // Get a Geometry
130  edm::ESHandle<TrackerGeometry> trackerGeometryHandle;
131  iSetup.get<TrackerDigiGeometryRecord>().get(trackerGeometryHandle);
132  assert(trackerGeometryHandle.isValid());
133 
134  // Now traverse the detector and collect whatever we need.
135  auto detids = trackerGeometryHandle->detIds();
136  for (DetId id : detids) {
137  if (id.subdetId() != PixelSubdetector::PixelBarrel && id.subdetId() != PixelSubdetector::PixelEndcap) continue;
138  auto iq = InterestingQuantities{nullptr, id, 0, 0};
139 
140  // prepare pretty names
141  std::string name = "";
142  if (id.subdetId() == PixelSubdetector::PixelBarrel) { // Barrel
143  PixelBarrelName mod(id, tt, isUpgrade);
144  name = mod.name();
145  } else { // assume Endcap
146  PixelEndcapName mod(id, tt, isUpgrade);
147  name = mod.name();
148  }
149  format_value[std::make_pair(intern("PXModuleName"), Value(id.rawId()))] = name;
150 
151  // we record each module 4 times, one for each corner, so we also get ROCs
152  // in booking (at least for the ranges)
153  const PixelGeomDetUnit* detUnit = dynamic_cast<const PixelGeomDetUnit*>(trackerGeometryHandle->idToDetUnit(id));
154  assert(detUnit);
155  const PixelTopology* topo = &detUnit->specificTopology();
156  iq.row = 0; iq.col = 0;
157  all_modules.push_back(iq);
158  iq.row = topo->nrows()-1; iq.col = 0;
159  all_modules.push_back(iq);
160  iq.row = 0; iq.col = topo->ncolumns()-1;
161  all_modules.push_back(iq);
162  iq.row = topo->nrows()-1; iq.col = topo->ncolumns()-1;
163  all_modules.push_back(iq);
164  }
165 }
166 
168  // TODO: SiPixelCoordinates has a large overlap with theis GeometryInterface
169  // in general.
170  // Rough convention is to use own code for things that are easy and fast to
171  // determine, and use SiPixelCoordinates for complicated things.
172  // SiPixelCoordinates uses lookup maps for everything, so it is faster than
173  // most other code, but still slow on DQM scales.
174  int phase = iConfig.getParameter<int>("upgradePhase");
175 
176  // this shared pointer is kept alive by the references in the lambdas that follow.
177  // That is a bit less obvious than keeping it as a member but more correct.
178  auto coord = std::make_shared<SiPixelCoordinates>(phase);
179 
180  // note that we should reeinit for each event. But this probably won't explode
181  // thanks to the massive memoization in SiPixelCoordinates which is completely
182  // initialized while booking.
183  coord->init(iSetup);
184 
185  // SiPixelCoordinates uses a different convention for UNDEFINED:
186  auto from_coord = [](double in) { return (in == -9999.0) ? UNDEFINED : Value(in); };
187 
188  // Rings are a concept that cannot be derived from bitmasks.
189  addExtractor(intern("PXRing"),
190  [coord, from_coord] (InterestingQuantities const& iq) {
191  return from_coord(coord->ring(iq.sourceModule));
192  }
193  );
194 
195  // Quadrant names.
196  auto pxbarrel = extractors[intern("PXBarrel")];
197  addExtractor(intern("HalfCylinder"),
198  [coord, pxbarrel] (InterestingQuantities const& iq) {
199  if (pxbarrel(iq) != UNDEFINED) return UNDEFINED;
200  int quadrant = coord->quadrant(iq.sourceModule);
201  switch (quadrant) {
202  case 1: return Value(12); // mO
203  case 2: return Value(11); // mI
204  case 3: return Value(22); // pO
205  case 4: return Value(21); // pI
206  default: return UNDEFINED;
207  }
208  }, 0, 0 // N/A
209  );
210  addExtractor(intern("Shell"),
211  [coord, pxbarrel] (InterestingQuantities const& iq) {
212  if (pxbarrel(iq) == UNDEFINED) return UNDEFINED;
213  int quadrant = coord->quadrant(iq.sourceModule);
214  switch (quadrant) {
215  case 1: return Value(12); // mO
216  case 2: return Value(11); // mI
217  case 3: return Value(22); // pO
218  case 4: return Value(21); // pI
219  default: return UNDEFINED;
220  }
221  }, 0, 0 // N/A
222  );
223 
224  // Online Numbering.
225  addExtractor(intern("SignedLadder"),
226  [coord, from_coord] (InterestingQuantities const& iq) {
227  return from_coord(coord->signed_ladder(iq.sourceModule()));
228  }
229  );
230  addExtractor(intern("SignedModule"),
231  [coord, from_coord] (InterestingQuantities const& iq) {
232  return from_coord(coord->signed_module(iq.sourceModule()));
233  }
234  );
235  addExtractor(intern("SignedBlade"),
236  [coord, from_coord] (InterestingQuantities const& iq) {
237  return from_coord(coord->signed_blade(iq.sourceModule()));
238  }
239  );
240 
241  // Pixel Map axis.
242  // TODO: automatic range and binning for phase0 are incorrect.
243  // Should be set manually here.
244  addExtractor(intern("SignedModuleCoord"), // BPIX x
245  [coord, from_coord] (InterestingQuantities const& iq) {
246  return from_coord(coord->signed_module_coord(iq.sourceModule(),
247  std::make_pair(int(iq.row), int(iq.col))));
248  }, UNDEFINED, UNDEFINED, 1.0/8.0
249  );
250  addExtractor(intern("SignedLadderCoord"), // BPIX y
251  [coord, from_coord] (InterestingQuantities const& iq) {
252  return from_coord(coord->signed_ladder_coord(iq.sourceModule(),
253  std::make_pair(int(iq.row), int(iq.col))));
254  }, UNDEFINED, UNDEFINED, 1.0/2.0
255  );
256  addExtractor(intern("SignedDiskCoord"), // FPIX x (per-ring)
257  [coord, from_coord] (InterestingQuantities const& iq) {
258  return from_coord(coord->signed_disk_coord(iq.sourceModule(),
259  std::make_pair(int(iq.row), int(iq.col))));
260  }, UNDEFINED, UNDEFINED, 1.0/8.0
261  );
262  addExtractor(intern("SignedDiskRingCoord"), // FPIX x (FPIX-as-one-plot)
263  [coord, from_coord] (InterestingQuantities const& iq) {
264  return from_coord(coord->signed_disk_ring_coord(iq.sourceModule(),
265  std::make_pair(int(iq.row), int(iq.col))));
266  }, UNDEFINED, UNDEFINED, 1.0/16.0
267  );
268  addExtractor(intern("SignedBladePanelCoord"), // FPIX y
269  [coord, from_coord, phase] (InterestingQuantities const& iq) {
270  if (phase == 0) {
271  return from_coord(coord->signed_blade_coord(
272  iq.sourceModule(), std::make_pair(int(iq.row), int(iq.col))));
273  } else if (phase == 1) {
274  return from_coord(coord->signed_blade_panel_coord(
275  iq.sourceModule(), std::make_pair(int(iq.row), int(iq.col))));
276  } else {
277  return UNDEFINED; // TODO: phase2
278  }
279  }, UNDEFINED, UNDEFINED, phase == 1 ? 0.25 : 0.2
280  );
281  addExtractor(intern("SignedShiftedBladePanelCoord"), // FPIX-as-one y
282  [coord, from_coord, phase] (InterestingQuantities const& iq) {
283  if (phase == 0) {
284  return from_coord(coord->signed_blade_coord(
285  iq.sourceModule(), std::make_pair(int(iq.row), int(iq.col))));
286  } else if (phase == 1) {
287  return from_coord(coord->signed_shifted_blade_panel_coord(
288  iq.sourceModule(), std::make_pair(int(iq.row), int(iq.col))));
289  } else {
290  return UNDEFINED; // TODO: phase2
291  }
292  }, UNDEFINED, UNDEFINED, phase == 1 ? 0.25 : 0.1 // half-roc for phase0
293  );
294  addExtractor(intern("SignedBladePanel"), // per-module FPIX y
295  [coord, from_coord] (InterestingQuantities const& iq) {
296  return from_coord(coord->signed_blade_panel_coord(iq.sourceModule(), std::make_pair(int(iq.row), int(iq.col))));
297  }, UNDEFINED, UNDEFINED, 1.0/2.0
298  );
299 
300  addExtractor(intern("SignedBladePanel"),
301  [coord, from_coord] (InterestingQuantities const& iq) {
302  return from_coord(coord->signed_blade_panel_coord(iq.sourceModule(), std::make_pair(int(iq.row), int(iq.col))));
303  }, UNDEFINED, UNDEFINED, 1.0/2.0
304  );
305 
306  // more readout-related things.
307  addExtractor(intern("ROC"),
308  [coord, from_coord] (InterestingQuantities const& iq) {
309  return from_coord(coord->roc(iq.sourceModule(),
310  std::make_pair(int(iq.row), int(iq.col))));
311  }
312  );
313  addExtractor(intern("Sector"),
314  [coord, from_coord] (InterestingQuantities const& iq) {
315  return from_coord(coord->sector(iq.sourceModule()));
316  }
317  );
318  addExtractor(intern("Channel"),
319  [coord, from_coord] (InterestingQuantities const& iq) {
320  return from_coord(coord->channel(iq.sourceModule(), std::make_pair(int(iq.row), int(iq.col))));
321  }
322  );
323 
324 }
325 
327  // extractors for quantities that are roughly time-based. We cannot book plots based on these; they have to
328  // be grouped away in step1.
329  addExtractor(intern("Lumisection"),
330  [] (InterestingQuantities const& iq) {
331  if(!iq.sourceEvent) return UNDEFINED;
332  return Value(iq.sourceEvent->luminosityBlock());
333  },
334  1, iConfig.getParameter<int>("max_lumisection")
335  );
336  int onlineblock = iConfig.getParameter<int>("onlineblock");
337  int n_onlineblocks = iConfig.getParameter<int>("n_onlineblocks");
338  addExtractor(intern("OnlineBlock"),
339  [onlineblock] (InterestingQuantities const& iq) {
340  if(!iq.sourceEvent) return UNDEFINED;
341  return Value(onlineblock + iq.sourceEvent->luminosityBlock() / onlineblock);
342  },
343  // note: this range is not visible anywhere (if the RenderPlugin does its job),
344  // but the strange range allows the RenderPlugin to know the block size.
345  onlineblock, onlineblock+n_onlineblocks-1
346  );
347  addExtractor(intern("BX"),
348  [] (InterestingQuantities const& iq) {
349  if(!iq.sourceEvent) return UNDEFINED;
350  return Value(iq.sourceEvent->bunchCrossing());
351  },
352  1, iConfig.getParameter<int>("max_bunchcrossing")
353  );
354 }
355 
357  // stuff that is within modules. Might require some phase0/phase1/strip switching later
358  addExtractor(intern("row"),
359  [] (InterestingQuantities const& iq) {
360  return Value(iq.row);
361  },
362  0, iConfig.getParameter<int>("module_rows") - 1
363  );
364  addExtractor(intern("col"),
365  [] (InterestingQuantities const& iq) {
366  return Value(iq.col);
367  },
368  0, iConfig.getParameter<int>("module_cols") - 1
369  );
370 
371 }
372 
374  auto cablingMapLabel = iConfig.getParameter<std::string>("CablingMapLabel");
376  iSetup.get<SiPixelFedCablingMapRcd>().get(cablingMapLabel, theCablingMap);
377 
378  std::shared_ptr<SiPixelFrameReverter> siPixelFrameReverter =
379  // I think passing the bare pointer here is safe, but who knows...
380  std::make_shared<SiPixelFrameReverter>(iSetup, theCablingMap.operator->());
381 
382  addExtractor(intern("FED"),
383  [siPixelFrameReverter] (InterestingQuantities const& iq) {
384  if (iq.sourceModule == 0xFFFFFFFF)
385  return Value(iq.col); // hijacked for the raw data plugin
386  return Value(siPixelFrameReverter->findFedId(iq.sourceModule.rawId()));
387  }
388  );
389 
390  // TODO: ranges should be set manually below, since booking probably cannot
391  // infer them correctly (no ROC-level granularity)
392  // PERF: this is slow. Prefer SiPixelCordinates versions here.
393  addExtractor(intern("LinkInFed"),
394  [siPixelFrameReverter] (InterestingQuantities const& iq) {
395  if (iq.sourceModule == 0xFFFFFFFF)
396  return Value(iq.row); // hijacked for the raw data plugin
397  sipixelobjects::GlobalPixel gp = {iq.row, iq.col};
398  return Value(siPixelFrameReverter->findLinkInFed(iq.sourceModule.rawId(), gp));
399  }
400  );
401  // not sure if this is useful anywhere.
402  addExtractor(intern("RocInLink"),
403  [siPixelFrameReverter] (InterestingQuantities const& iq) {
405  return Value(siPixelFrameReverter->findRocInLink(iq.sourceModule.rawId(), gp));
406  }
407  );
408  // This might be equivalent to our ROC numbering.
409  addExtractor(intern("RocInDet"),
410  [siPixelFrameReverter] (InterestingQuantities const& iq) {
412  return Value(siPixelFrameReverter->findRocInDet(iq.sourceModule.rawId(), gp));
413  }
414  );
415 }
416 
418  auto it = format_value.find(std::make_pair(col, val));
419  if (it != format_value.end()) return it->second;
420 
421  // non-number output names (_pO etc.) are hardwired here.
422  std::string name = pretty(col);
423  std::string value = "_" + std::to_string(int(val));
424  if (val == 0) value = ""; // hide Barrel_0 etc.
425  if (name == "PXDisk" && val > 0) // +/- sign for disk num
426  value = "_+" + std::to_string(int(val));
427  // pretty (legacy?) names for Shells and HalfCylinders
428  std::map<int, std::string> shellname{
429  {11, "_mI"}, {12, "_mO"}, {21, "_pI"}, {22, "_pO"}};
430  if (name == "HalfCylinder" || name == "Shell") value = shellname[int(val)];
431  if (val == UNDEFINED) value = "_UNDEFINED";
432  return format_value[std::make_pair(col, val)] = name+value;
433 }
434 
std::map< ID, Value > max_value
bool hasField(const DetId &id, DetIdFields idx) const
T getParameter(std::string const &) const
const TrackerGeomDet * idToDetUnit(DetId) const
Return the pointer to the GeomDetUnit corresponding to a given DetId.
virtual int nrows() const =0
std::map< std::pair< Column, Value >, std::string > format_value
std::map< std::string, ID > ids
std::string pretty(Column col)
void addExtractor(ID id, std::function< Value(InterestingQuantities const &iq)> func, Value min=UNDEFINED, Value max=UNDEFINED, Value binwidth=1)
std::string formatValue(Column, Value)
int bunchCrossing() const
Definition: EventBase.h:64
edm::LuminosityBlockNumber_t luminosityBlock() const
Definition: EventBase.h:61
global coordinates (row and column in DetUnit, as in PixelDigi)
Definition: GlobalPixel.h:6
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
void loadFromTopology(edm::EventSetup const &iSetup, const edm::ParameterSet &iConfig)
void load(edm::EventSetup const &iSetup)
const edm::ParameterSet iConfig
std::vector< InterestingQuantities > all_modules
Definition: value.py:1
static const Value UNDEFINED
Definition: DetId.h:18
virtual std::string name() const
from base class
const T & get() const
Definition: EventSetup.h:56
virtual const PixelTopology & specificTopology() const
Returns a reference to the pixel proxy topology.
unsigned int getField(const DetId &id, DetIdFields idx) const
void loadFEDCabling(edm::EventSetup const &iSetup, const edm::ParameterSet &iConfig)
virtual std::string name() const
from base class
virtual int ncolumns() const =0
const DetIdContainer & detIds() const
Returm a vector of all GeomDet DetIds (including those of GeomDetUnits)
col
Definition: cuy.py:1008
void loadModuleLevel(edm::EventSetup const &iSetup, const edm::ParameterSet &iConfig)
std::vector< std::function< Value(InterestingQuantities const &iq)> > extractors
std::map< ID, Value > min_value
bool isValid() const
Definition: ESHandle.h:47
ID intern(std::string const &id)
T mod(const T &a, const T &b)
Definition: ecalDccMap.h:4
void loadTimebased(edm::EventSetup const &iSetup, const edm::ParameterSet &iConfig)
void loadFromSiPixelCoordinates(edm::EventSetup const &iSetup, const edm::ParameterSet &iConfig)