test
CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
GeometryInterface.h
Go to the documentation of this file.
1 #ifndef SiPixel_GeometryInterface_h
2 #define SiPixel_GeometryInterface_h
3 // -*- C++ -*-
4 //
5 // Package: SiPixelPhase1Common
6 // Class: GeometryInterface
7 //
8 // The histogram manager uses this class to gather information about a sample.
9 // All geometry dependence goes here. This is a singleton, (ed::Service) but
10 // only for performance reasons.
11 // At some point we might need to switch to sth. more complicated (if we want
12 // to deal with more than one geometry per process).
13 //
14 // Original Author: Marcel Schneider
15 //
16 
21 
22 #include <functional>
23 #include <map>
24 #include <string>
25 #include <array>
26 
28  public:
29  // an ID is produced by interning a string name.
30  typedef int ID;
31  // A column can have multiple IDs if it is a or-form. If not, only [0] is
32  // used, the other entries are 0. A limit of 2 is arbitrary here.
33  // Once a value is assigned, the column is "normalized", and only the ID
34  // of the extracted value is in [0]. Fuzzy matching is used to find a
35  // normalized column when a multicolumn is given and vice versa.
36  // Increasing the max number of columns needs fixing some todos.
37  typedef std::array<ID, 2> Column;
38  typedef int Value;
39  static const Value UNDEFINED = 0x0FFFFFFF;
40 
41  // Essentially a map backed by a vector (for the small counts here
42  // this should always be faster), with special handling for multi-colums.
43  struct Values {
44  std::vector<std::pair<Column, Value>> values;
45 
46  static bool columnMatch(Column const& a, Column const& b) {
47  return a == b // trivial case TODO: loops for size > 2
48  || (a[0] == b[0] && a[1] == 0) // normalized case 1
49  || (a[0] == b[1] && a[1] == 0) // normalized case 2
50  || (b[0] == a[0] && b[1] == 0) // normalized case 1 (inv)
51  || (b[0] == a[1] && b[1] == 0); // normalized case 2 (inv)
52  }
53 
54  void put(Column c, Value v) {
55  for (auto& e : values)
56  if (columnMatch(e.first, c)) {
57  e.first = c;
58  e.second = v;
59  return;
60  }
61  values.push_back(make_pair(c, v)); // else
62  };
63  void put(std::pair<Column, Value> v) { put(v.first, v.second); };
64  std::pair<Column, Value> get(Column c) const {
65  for (auto& e : values)
66  if (columnMatch(e.first, c)) return e;
67  return make_pair(Column{{0, 0}}, UNDEFINED);
68  };
69  void erase(Column c) {
70  for (auto it = values.begin(); it != values.end(); ++it)
71  if (columnMatch(it->first, c)) {
72  values.erase(it);
73  return;
74  }
75  }
76  void clear() { values.clear(); };
77  Value operator[](Column c) { return get(c).second; };
78  bool operator<(Values const& other) const {
79  return this->values < other.values;
80  };
81  };
82 
84 
85  bool loaded() { return is_loaded; };
86 
87  // The hard work happens here.
88  // this is _not_ thread save, but it should only be called in
89  // booking/harvesting.
90  void load(edm::EventSetup const& iSetup);
91 
93  // in this order the struct should fit 2 64bit words and is cheap to copy.
96  int16_t col;
97  int16_t row;
98  };
99 
100  // This has to be fast, _should_ not malloc.
101  void extractColumns(std::vector<Column> const& names,
102  InterestingQuantities const& iq, Values& out) {
103  out.clear();
104  for (Column const& col : names) {
105  auto val = extract(col, iq);
106  out.put(val.first, val.second);
107  }
108  };
109 
110  std::pair<Column, Value> extract(Column const& col, InterestingQuantities const& iq) {
111  assert(col[0] != 0 || !"Extracting invalid column.");
112  for (ID id : col) {
113  if (id == 0) break; // all set columns failed
114  assert(ID(extractors.size()) > id || !"extractors vector too small!");
115  auto& ex = extractors[id];
116  if (!ex) { // we have never heard about this. This is a typo for sure.
117  edm::LogError("GeometryInterface")
118  << "Undefined column used: " << unintern(id)
119  << ". Check your spelling.\n";
120  } else {
121  auto val = ex(iq);
122  if (val != UNDEFINED) {
123  return std::make_pair(Column{{id, 0}}, val); // double braces for g++
124  break;
125  }
126  }
127  }
128  return std::make_pair(col, UNDEFINED);
129  }
130 
131  Value extract(ID id, DetId did, edm::Event* ev = nullptr, int16_t col = 0,
132  int16_t row = 0) {
133  InterestingQuantities iq = {ev, did, col, row};
134  return extractors[id](iq);
135  }
136 
137  std::vector<InterestingQuantities> const& allModules() {
138  return all_modules;
139  };
140  Value maxValue(ID id) { return max_value[id]; };
141  Value minValue(ID id) { return min_value[id]; };
142 
143  // turn string into an ID, adding it if needed.
144  // needs the lock since this will be called from the spec builder, which will
145  // run in the constructor and this is parallel.
146  ID intern(std::string const& id) {
147  auto it = ids.find(id);
148  if (it == ids.end()) {
149  ids[id] = ++max_id;
150  extractors.resize(max_id + 1);
151  }
152  return ids[id];
153  };
154 
155  // turn an ID back into a string. Only for pretty output (including histo
156  // labels), so it can be slow (though intern() does not have to be fast
157  // either). Also locks, might not be needed but better save than sorry.
159  for (auto& e : ids)
160  if (e.second == id) return e.first;
161  return "INVALID";
162  }
163 
165  if (col[1] == 0) // normal column
166  return unintern(col[0]);
167  else
168  return unintern(col[0]) +
169  /*"|" +*/ unintern(col[1]); // TODO: should loop.
170  }
171 
172  private:
173  // void loadFromAlignment(edm::EventSetup const& iSetup, const
174  // edm::ParameterSet& iConfig);
175  void loadFromTopology(edm::EventSetup const& iSetup,
176  const edm::ParameterSet& iConfig);
177  void loadTimebased(edm::EventSetup const& iSetup,
178  const edm::ParameterSet& iConfig);
179  void loadModuleLevel(edm::EventSetup const& iSetup,
180  const edm::ParameterSet& iConfig);
181  void loadFEDCabling(edm::EventSetup const& iSetup,
182  const edm::ParameterSet& iConfig);
183 
185 
186  bool is_loaded = false;
187 
188  // This holds closures that compute the column values in step1.
189  // can be a Vector since ids are dense.
190  std::vector<std::function<Value(InterestingQuantities const& iq)>> extractors;
191  // quantity range if it is known. Can be UNDEFINED, in this case booking will
192  // determine the range.
193  // map for ease of use.
194  std::map<ID, Value> max_value;
195  std::map<ID, Value> min_value;
196 
197  void addExtractor(ID id,
200  max_value[id] = max;
201  min_value[id] = min;
202  extractors[id] = func;
203  }
204 
205  std::vector<InterestingQuantities> all_modules;
206 
207  // interning table. Maps string IDs to a dense set of integer IDs
208  std::map<std::string, ID> ids{std::make_pair(std::string("INVALID"), ID(0))};
209  ID max_id = 0;
210 };
211 
212 #endif
std::map< ID, Value > max_value
void put(std::pair< Column, Value > v)
std::map< std::string, ID > ids
static const HistoName names[]
GeometryInterface(const edm::ParameterSet &conf)
void addExtractor(ID id, std::function< Value(InterestingQuantities const &iq)> func, Value min=UNDEFINED, Value max=UNDEFINED)
std::string pretty(Column col)
assert(m_qm.get())
bool operator<(Values const &other) const
bool ev
std::string unintern(ID id)
std::vector< std::pair< Column, Value > > values
U second(std::pair< T, U > const &p)
void loadFromTopology(edm::EventSetup const &iSetup, const edm::ParameterSet &iConfig)
void load(edm::EventSetup const &iSetup)
void extractColumns(std::vector< Column > const &names, InterestingQuantities const &iq, Values &out)
helper::RootFunctionHelper< F, args >::root_function function(F &f)
Definition: rootFunction.h:14
const edm::ParameterSet iConfig
std::vector< InterestingQuantities > all_modules
T min(T a, T b)
Definition: MathUtil.h:58
static const Value UNDEFINED
std::array< ID, 2 > Column
Value extract(ID id, DetId did, edm::Event *ev=0, int16_t col=0, int16_t row=0)
Definition: DetId.h:18
double b
Definition: hdecay.h:120
void loadFEDCabling(edm::EventSetup const &iSetup, const edm::ParameterSet &iConfig)
static bool columnMatch(Column const &a, Column const &b)
std::pair< Column, Value > extract(Column const &col, InterestingQuantities const &iq)
double a
Definition: hdecay.h:121
void loadModuleLevel(edm::EventSetup const &iSetup, const edm::ParameterSet &iConfig)
std::vector< std::function< Value(InterestingQuantities const &iq)> > extractors
std::vector< InterestingQuantities > const & allModules()
std::map< ID, Value > min_value
int col
Definition: cuy.py:1008
ID intern(std::string const &id)
void loadTimebased(edm::EventSetup const &iSetup, const edm::ParameterSet &iConfig)
void put(Column c, Value v)