test
CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 // edm stuff
15 
16 // Tracker Geometry/Topology stuff
24 
25 // C++ stuff
26 #include <cassert>
27 #include <cstdint>
28 #include <iostream>
29 #include <iomanip>
30 
31 // WTH is this needed? clang wants it for linking...
33 
35  //loadFromAlignment(iSetup, iConfig);
36  loadFromTopology(iSetup, iConfig);
37  loadTimebased(iSetup, iConfig);
38  loadModuleLevel(iSetup, iConfig);
39  loadFEDCabling(iSetup, iConfig);
40  edm::LogInfo log("GeometryInterface");
41  log << "Known colum names:\n";
42  for (auto e : ids) log << "+++ column: " << e.first
43  << " ok " << bool(extractors[e.second]) << " min " << min_value[e.second] << " max " << max_value[e.second] << "\n";
44  is_loaded = true;
45 }
46 
48  // Get a Topology
49  edm::ESHandle<TrackerTopology> trackerTopologyHandle;
50  iSetup.get<TrackerTopologyRcd>().get(trackerTopologyHandle);
51  assert(trackerTopologyHandle.isValid());
52 
53  std::vector<ID> geomquantities;
54 
55  struct TTField {
56  const TrackerTopology* tt;
58  Value operator()(InterestingQuantities const& iq) {
59  if (tt->hasField(iq.sourceModule, field))
60  return tt->getField(iq.sourceModule, field);
61  else
62  return UNDEFINED;
63  };
64  };
65 
66  const TrackerTopology* tt = trackerTopologyHandle.operator->();
67 
68 
69  std::vector<std::pair<std::string, TTField>> namedPartitions {
70  {"PXEndcap" , {tt, TrackerTopology::PFSide}},
71 
72  {"PXLayer" , {tt, TrackerTopology::PBLayer}},
73  {"PXLadder" , {tt, TrackerTopology::PBLadder}},
74  {"PXBModule", {tt, TrackerTopology::PBModule}},
75 
76  {"PXBlade" , {tt, TrackerTopology::PFBlade}},
77  {"PXDisk" , {tt, TrackerTopology::PFDisk}},
78  {"PXPanel" , {tt, TrackerTopology::PFPanel}},
79  {"PXFModule", {tt, TrackerTopology::PFModule}},
80  };
81 
82  for (auto& e : namedPartitions) {
83  geomquantities.push_back(intern(e.first));
84  addExtractor(intern(e.first), e.second, UNDEFINED, UNDEFINED);
85  }
86 
87  auto pxbarrel = [] (InterestingQuantities const& iq) { return iq.sourceModule.subdetId() == PixelSubdetector::PixelBarrel ? 0 : UNDEFINED; };
88  auto pxforward = [] (InterestingQuantities const& iq) { return iq.sourceModule.subdetId() == PixelSubdetector::PixelEndcap ? 0 : UNDEFINED; };
89  addExtractor(intern("PXBarrel"), pxbarrel, 0, 0);
90  addExtractor(intern("PXForward"), pxforward, 0, 0);
91 
92  // Redefine the disk numbering to use the sign
93  auto pxendcap = extractors[intern("PXEndcap")];
94  auto diskid = intern("PXDisk");
95  auto pxdisk = extractors[diskid];
96  extractors[diskid] = [pxdisk, pxendcap] (InterestingQuantities const& iq) {
97  auto disk = pxdisk(iq);
98  if (disk == UNDEFINED) return UNDEFINED;
99  auto endcap = pxendcap(iq);
100  return endcap == 1 ? -disk : disk;
101  };
102 
103  // Get a Geometry
104  edm::ESHandle<TrackerGeometry> trackerGeometryHandle;
105  iSetup.get<TrackerDigiGeometryRecord>().get(trackerGeometryHandle);
106  assert(trackerGeometryHandle.isValid());
107 
108  // some parameters to record the ROCs here
109  auto module_rows = iConfig.getParameter<int>("module_rows") - 1;
110  auto module_cols = iConfig.getParameter<int>("module_cols") - 1;
111 
112  // We need to track some extra stuff here for the Shells later.
113  auto pxlayer = extractors[intern("PXLayer")];
114  auto pxladder = extractors[intern("PXLadder")];
115  auto pxmodule = extractors[intern("PXBModule")];
116  auto pxblade = extractors[intern("PXBlade")];
117  std::vector<Value> maxladders;
118  Value maxmodule = 0;
119  Value innerring = iConfig.getParameter<int>("n_inner_ring_blades");
120  Value outerring = 0;
121 
122  // Now travrse the detector and collect whatever we need.
123  auto detids = trackerGeometryHandle->detIds();
124  for (DetId id : detids) {
125  if (id.subdetId() != PixelSubdetector::PixelBarrel && id.subdetId() != PixelSubdetector::PixelEndcap) continue;
126  auto iq = InterestingQuantities{nullptr, id, 0, 0};
127  auto layer = pxlayer(iq);
128  if (layer != UNDEFINED) {
129  if (layer >= Value(maxladders.size())) maxladders.resize(layer+1);
130  auto ladder = pxladder(iq);
131  if (ladder > maxladders[layer]) maxladders[layer] = ladder;
132  }
133  auto module = pxmodule(iq);
134  if (module != UNDEFINED && module > maxmodule) maxmodule = module;
135  auto blade = pxblade(iq);
136  if (blade != UNDEFINED && blade > outerring) outerring = blade;
137 
138  // we record each module 4 times, one for each corner, so we also get ROCs
139  // in booking (at least for the ranges)
140  iq.row = 0; iq.col = 0;
141  all_modules.push_back(iq);
142  iq.row = module_rows; iq.col = 0;
143  all_modules.push_back(iq);
144  iq.row = 0; iq.col = module_cols;
145  all_modules.push_back(iq);
146  iq.row = module_rows; iq.col = module_cols;
147  all_modules.push_back(iq);
148  }
149 
150  outerring = outerring - innerring;
151 
152  // Shells are a concept that cannot be derived from bitmasks.
153  // Use hardcoded logic here.
154  // This contains a lot more assumptions about general geometry than the rest
155  // of the code, but it might work for Phase0 as well.
156  addExtractor(intern("PXRing"),
157  [pxblade, innerring] (InterestingQuantities const& iq) {
158  auto blade = pxblade(iq);
159  if (blade == UNDEFINED) return UNDEFINED;
160  if (blade <= innerring) return Value(1);
161  else return Value(2);
162  }
163  );
164 
165  addExtractor(intern("HalfCylinder"),
166  [pxendcap, pxblade, innerring, outerring] (InterestingQuantities const& iq) {
167  auto ec = pxendcap(iq);
168  if (ec == UNDEFINED) return UNDEFINED;
169  auto blade = pxblade(iq);
170  // blade 1 and 56 are at 3 o'clock. This is a mess.
171  auto inring = blade > innerring ? (innerring+outerring+1) - blade : blade;
172  auto perring = blade > innerring ? outerring : innerring;
173  // inring is now 1-based, 1 at 3 o'clock, upto perring.
174  int frac = (int) ((inring-1) / float(perring) * 4); // floor semantics here
175  if (frac == 0 || frac == 3) return 10*ec + 1; // inner half
176  if (frac == 1 || frac == 2) return 10*ec + 2; // outer half
177  assert(!"HalfCylinder logic problem");
178  return UNDEFINED;
179  }, 0, 0 // N/A
180  );
181 
182  // For the '+-shape' (ladder vs. module) plots, we need signed numbers with
183  // (unused) 0-ladder/module at x=0/z=0. This means a lot of messing with the
184  // ladder/shell numbering...
185  addExtractor(intern("signedLadder"),
186  [pxbarrel, pxladder, pxlayer, maxladders, maxmodule] (InterestingQuantities const& iq) {
187  if(pxbarrel(iq) == UNDEFINED) return UNDEFINED;
188  auto layer = pxlayer(iq);
189  auto ladder = pxladder(iq);
190  int frac = (int) ((ladder-1) / float(maxladders[layer]) * 4); // floor semantics
191  Value quarter = maxladders[layer] / 4;
192  if (frac == 0) return -ladder + quarter + 1; // top right - +1 for gap
193  if (frac == 1) return -ladder + quarter; // top left -
194  if (frac == 2) return -ladder + quarter; // bot left - same
195  if (frac == 3) return -ladder + 4*quarter + quarter + 1; // bot right - like top right but wrap around
196  assert(!"Shell logic problem");
197  return UNDEFINED;
198  }
199  );
200 
201  addExtractor(intern("signedModule"),
202  [pxmodule, maxmodule] (InterestingQuantities const& iq) {
203  Value mod = pxmodule(iq); // range 1..maxmodule
204  if (mod == UNDEFINED) return UNDEFINED;
205  mod -= (maxmodule/2 + 1); // range -(max_module/2)..-1, 0..
206  if (mod >= 0) mod += 1; // range -(max_module/2)..-1, 1..
207  return mod;
208  }
209  );
210 
211  auto signedladder = extractors[intern("signedLadder")];
212  auto signedmodule = extractors[intern("signedModule")];
213  addExtractor(intern("Shell"),
214  [signedladder, signedmodule] (InterestingQuantities const& iq) {
215  auto sl = signedladder(iq);
216  auto sm = signedmodule(iq);
217  if (sl == UNDEFINED) return UNDEFINED;
218  return Value((sm < 0 ? 10 : 20) + (sl < 0 ? 2 : 1)); // negative means outer shell!?
219  }, 0, 0 // N/A
220  );
221 
222  addExtractor(intern(""), // A dummy column. Not much special handling required.
223  [] (InterestingQuantities const& iq) { return 0; },
224  0, 0
225  );
226 
227 }
228 
230  // extractors for quantities that are roughly time-based. We cannot book plots based on these; they have to
231  // be grouped away in step1.
232  addExtractor(intern("Lumisection"),
233  [] (InterestingQuantities const& iq) {
234  if(!iq.sourceEvent) return UNDEFINED;
235  return Value(iq.sourceEvent->luminosityBlock());
236  },
237  1, iConfig.getParameter<int>("max_lumisection")
238  );
239  int onlineblock = iConfig.getParameter<int>("onlineblock");
240  int n_onlineblocks = iConfig.getParameter<int>("n_onlineblocks");
241  addExtractor(intern("OnlineBlock"),
242  [onlineblock] (InterestingQuantities const& iq) {
243  if(!iq.sourceEvent) return UNDEFINED;
244  return Value(onlineblock + iq.sourceEvent->luminosityBlock() / onlineblock);
245  },
246  // note: this range is not visible anywhere (if the RenderPlugin does its job),
247  // but the strange range allows the RenderPlugin to know the block size.
248  onlineblock, onlineblock+n_onlineblocks-1
249  );
250  addExtractor(intern("BX"),
251  [] (InterestingQuantities const& iq) {
252  if(!iq.sourceEvent) return UNDEFINED;
253  return Value(iq.sourceEvent->bunchCrossing());
254  },
255  1, iConfig.getParameter<int>("max_bunchcrossing")
256  );
257 }
258 
260  // stuff that is within modules. Might require some phase0/phase1/strip switching later
261  addExtractor(intern("row"),
262  [] (InterestingQuantities const& iq) {
263  return Value(iq.row);
264  },
265  0, iConfig.getParameter<int>("module_rows") - 1
266  );
267  addExtractor(intern("col"),
268  [] (InterestingQuantities const& iq) {
269  return Value(iq.col);
270  },
271  0, iConfig.getParameter<int>("module_cols") - 1
272  );
273 
274  int n_rocs = iConfig.getParameter<int>("n_rocs");
275  float roc_cols = iConfig.getParameter<int>("roc_cols");
276  float roc_rows = iConfig.getParameter<int>("roc_rows");
277  auto pxmodule = extractors[intern("PXBModule")];
278  auto pxpanel = extractors[intern("PXPanel")];
279  addExtractor(intern("ROC"),
280  [n_rocs, roc_cols, roc_rows] (InterestingQuantities const& iq) {
281  int fedrow = int(iq.row / roc_rows);
282  int fedcol = int(iq.col / roc_cols);
283  if (fedrow == 0) return Value(fedcol);
284  if (fedrow == 1) return Value(n_rocs - 1 - fedcol);
285  return UNDEFINED;
286  }
287  );
288 
289  // arbitrary per-ladder numbering (for inefficiencies)
290  auto roc = extractors[intern("ROC")];
291  addExtractor(intern("ROCinLadder"),
292  [pxmodule, roc, n_rocs] (InterestingQuantities const& iq) {
293  auto mod = pxmodule(iq);
294  if (mod == UNDEFINED) return UNDEFINED;
295  return Value(roc(iq) + n_rocs * (mod-1));
296  }
297  );
298  addExtractor(intern("ROCinBlade"),
299  [pxmodule, pxpanel, roc, n_rocs] (InterestingQuantities const& iq) {
300  auto mod = pxpanel(iq);
301  if (mod == UNDEFINED) return UNDEFINED;
302  return Value(roc(iq) + n_rocs * (mod-1));
303  }
304  );
305 
306  addExtractor(intern("DetId"),
307  [] (InterestingQuantities const& iq) {
308  uint32_t id = iq.sourceModule.rawId();
309  return Value(id);
310  },
311  0, 0 // No sane value possible here.
312  );
313 }
314 
316  auto cablingMapLabel = iConfig.getParameter<std::string>("CablingMapLabel");
318  iSetup.get<SiPixelFedCablingMapRcd>().get(cablingMapLabel, theCablingMap);
319  std::map<DetId, Value> fedmap;
320  uint32_t minFED = UNDEFINED, maxFED = 0;
321 
322  if (theCablingMap.isValid()) {
323  auto map = theCablingMap.product();
324 
325  for(auto iq : all_modules) {
326  std::vector<sipixelobjects::CablingPathToDetUnit> paths = map->pathToDetUnit(iq.sourceModule.rawId());
327  for (auto p : paths) {
328  //std::cout << "+++ cabling " << iq.sourceModule.rawId() << " " << p.fed << " " << p.link << " " << p.roc << "\n";
329  fedmap[iq.sourceModule] = Value(p.fed);
330  if (p.fed > maxFED) maxFED = p.fed;
331  if (p.fed < minFED) minFED = p.fed;
332  }
333  }
334  } else {
335  edm::LogError("GeometryInterface") << "+++ No cabling map. Cannot extract FEDs.\n";
336  }
337 
338  addExtractor(intern("FED"),
339  [fedmap] (InterestingQuantities const& iq) {
340  if (iq.sourceModule == 0xFFFFFFFF)
341  return Value(iq.col); // hijacked for the raw data plugin
342  auto it = fedmap.find(iq.sourceModule);
343  if (it == fedmap.end()) return GeometryInterface::UNDEFINED;
344  return it->second;
345  }
346  );
347  addExtractor(intern("FEDChannel"),
348  [] (InterestingQuantities const& iq) {
349  // TODO: we also should be able to compute the channel from the ROC.
350  // But for raw data, we only need this hack.
351  //if (iq.sourceModule == 0xFFFFFFFF)
352  return Value(iq.row); // hijacked for the raw data plugin
353  },
354  0, 39 // TODO: real range
355  );
356 }
std::map< ID, Value > max_value
T getParameter(std::string const &) const
std::map< std::string, ID > ids
void addExtractor(ID id, std::function< Value(InterestingQuantities const &iq)> func, Value min=UNDEFINED, Value max=UNDEFINED)
assert(m_qm.get())
int bunchCrossing() const
Definition: EventBase.h:64
edm::LuminosityBlockNumber_t luminosityBlock() const
Definition: EventBase.h:61
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
static const Value UNDEFINED
Definition: DetId.h:18
const T & get() const
Definition: EventSetup.h:56
void loadFEDCabling(edm::EventSetup const &iSetup, const edm::ParameterSet &iConfig)
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
Definition: vlib.h:208
void loadTimebased(edm::EventSetup const &iSetup, const edm::ParameterSet &iConfig)