CMS 3D CMS Logo

RunRangeDependentPedeLabeler.cc
Go to the documentation of this file.
1 
11 #include <algorithm>
12 #include <atomic>
13 
16 
24 
26 
27 //___________________________________________________________________________
30  : PedeLabelerBase(alignables, config), theMaxNumberOfParameterInstances(0) {
31  align::Alignables alis;
32  alis.push_back(alignables.aliTracker_);
33  alis.push_back(alignables.aliMuon_);
34 
35  if (alignables.aliExtras_) {
36  for (const auto& ali : alignables.aliExtras_->components()) {
37  alis.push_back(ali);
38  }
39  }
40 
41  this->buildRunRangeDependencyMap(alignables.aliTracker_, alignables.aliMuon_, alignables.aliExtras_, config);
42  this->buildMap(alis);
43  this->buildReverseMap(); // needed already now to 'fill' theMaxNumberOfParameterInstances
44 }
45 
46 //___________________________________________________________________________
47 
49 
50 //___________________________________________________________________________
53  if (!alignable)
54  return 0;
55 
56  AlignableToIdMap::const_iterator position = theAlignableToIdMap.find(alignable);
57  if (position != theAlignableToIdMap.end()) {
58  return position->second;
59  } else {
60  const DetId detId(alignable->id());
61  //throw cms::Exception("LogicError")
62  edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::alignableLabel"
63  << "Alignable " << typeid(*alignable).name()
64  << " not in map, det/subdet/alignableStructureType = " << detId.det() << "/"
65  << detId.subdetId() << "/" << alignable->alignableObjectId();
66  return 0;
67  }
68 }
69 
70 //___________________________________________________________________________
71 // Return 32-bit unique label for alignable, 0 indicates failure.
73  unsigned int param,
74  unsigned int instance) const {
75  if (!alignable)
76  return 0;
77 
78  AlignableToIdMap::const_iterator position = theAlignableToIdMap.find(alignable);
79  if (position != theAlignableToIdMap.end()) {
80  AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(alignable);
81  if (positionAli != theAlignableToRunRangeRangeMap.end()) {
82  RunRangeParamMap::const_iterator positionParam = (*positionAli).second.find(param);
83  if (positionParam != (*positionAli).second.end()) {
84  if (instance >= (*positionParam).second.size()) {
85  throw cms::Exception("Alignment") << "RunRangeDependentPedeLabeler::alignableLabelFromParamAndRunRange: "
86  << "RunRangeIdx out of bounds.\n";
87  }
88  return position->second + instance * theParamInstanceOffset;
89  } else {
90  return position->second;
91  }
92  } else {
93  return position->second;
94  }
95  } else {
96  const DetId detId(alignable->id());
97  //throw cms::Exception("LogicError")
98  edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::alignableLabel"
99  << "Alignable " << typeid(*alignable).name()
100  << " not in map, det/subdet/alignableStructureType = " << detId.det() << "/"
101  << detId.subdetId() << "/" << alignable->alignableObjectId();
102  return 0;
103  }
104 }
105 
106 //_________________________________________________________________________
107 unsigned int RunRangeDependentPedeLabeler::lasBeamLabel(unsigned int lasBeamId) const {
108  UintUintMap::const_iterator position = theLasBeamToLabelMap.find(lasBeamId);
109  if (position != theLasBeamToLabelMap.end()) {
110  return position->second;
111  } else {
112  //throw cms::Exception("LogicError")
113  edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::lasBeamLabel"
114  << "No label for beam Id " << lasBeamId;
115  return 0;
116  }
117 }
118 
119 //_________________________________________________________________________
120 unsigned int RunRangeDependentPedeLabeler::parameterLabel(unsigned int aliLabel, unsigned int parNum) const {
121  if (parNum >= theMaxNumParam) {
122  throw cms::Exception("Alignment") << "@SUB=RunRangeDependentPedeLabeler::parameterLabel"
123  << "Parameter number " << parNum << " out of range 0 <= num < " << theMaxNumParam;
124  }
125  return aliLabel + parNum;
126 }
127 
128 //_________________________________________________________________________
130  unsigned int parNum,
132  const TrajectoryStateOnSurface& tsos) const {
133  if (!alignable)
134  return 0;
135 
136  if (parNum >= theMaxNumParam) {
137  throw cms::Exception("Alignment") << "@SUB=RunRangeDependentPedeLabeler::parameterLabel"
138  << "Parameter number " << parNum << " out of range 0 <= num < " << theMaxNumParam;
139  }
140 
141  AlignableToIdMap::const_iterator position = theAlignableToIdMap.find(alignable);
142  if (position != theAlignableToIdMap.end()) {
143  AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(alignable);
144  if (positionAli != theAlignableToRunRangeRangeMap.end()) {
145  RunRangeParamMap::const_iterator positionParam = (*positionAli).second.find(parNum);
146  if (positionParam != (*positionAli).second.end()) {
147  int offset = 0;
148  const RunRangeVector& runRanges = (*positionParam).second;
149  for (const auto& iRunRange : runRanges) {
150  if (eventInfo.eventId().run() >= iRunRange.first && eventInfo.eventId().run() <= iRunRange.second) {
151  return position->second + offset * theParamInstanceOffset + parNum;
152  }
153  offset++;
154  }
155  const DetId detId(alignable->id());
156  edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::parameterLabel"
157  << "Instance for Alignable " << typeid(*alignable).name()
158  << " not in map, det/subdet/alignableStructureType = " << detId.det() << "/"
159  << detId.subdetId() << "/" << alignable->alignableObjectId() << " for run "
160  << eventInfo.eventId().run();
161  return 0;
162  } else {
163  return position->second + parNum;
164  }
165 
166  } else {
167  return position->second + parNum;
168  }
169  } else {
170  const DetId detId(alignable->id());
171  //throw cms::Exception("LogicError")
172  edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::parameterLabel"
173  << "Alignable " << typeid(*alignable).name()
174  << " not in map, det/subdet/alignableStructureType = " << detId.det() << "/"
175  << detId.subdetId() << "/" << alignable->alignableObjectId();
176  return 0;
177  }
178 }
179 
180 //_________________________________________________________________________
182  AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(alignable);
183  if (positionAli != theAlignableToRunRangeRangeMap.end())
184  return true;
185  return false;
186 }
187 
188 //_________________________________________________________________________
189 unsigned int RunRangeDependentPedeLabeler::numberOfParameterInstances(Alignable* alignable, int param) const {
190  AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(alignable);
191  if (positionAli != theAlignableToRunRangeRangeMap.end()) {
192  size_t nRunRanges = 1;
193  if (param == -1) {
194  for (const auto iParam : (*positionAli).second) {
195  nRunRanges = std::max(nRunRanges, iParam.second.size());
196  }
197  return nRunRanges;
198  } else {
199  RunRangeParamMap::const_iterator iParam = (*positionAli).second.find(param);
200  if (iParam != (*positionAli).second.end()) {
201  return iParam->second.size();
202  } else {
203  return 1;
204  }
205  }
206  }
207 
208  return 1;
209 }
210 
211 //___________________________________________________________________________
213  if (paramLabel < theMinLabel) {
214  edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::paramNumFromLabel"
215  << "Label " << paramLabel << " should be >= " << theMinLabel;
216  return 0;
217  }
218  return (paramLabel - theMinLabel) % theMaxNumParam;
219 }
220 
221 //___________________________________________________________________________
223  return paramLabel - this->paramNumFromLabel(paramLabel);
224 }
225 
226 //___________________________________________________________________________
228  const unsigned int aliLabel = this->alignableLabelFromLabel(label);
229  if (aliLabel < theMinLabel)
230  return nullptr; // error already given
231 
232  IdToAlignableMap::const_iterator position = theIdToAlignableMap.find(aliLabel);
233  if (position != theIdToAlignableMap.end()) {
234  return position->second;
235  } else {
236  // error only if not in lasBeamMap:
237  UintUintMap::const_iterator position = theLabelToLasBeamMap.find(aliLabel);
238  if (position == theLabelToLasBeamMap.end()) {
239  edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::alignableFromLabel"
240  << "Alignable label " << aliLabel << " not in map.";
241  }
242  return nullptr;
243  }
244 }
245 
246 //___________________________________________________________________________
247 unsigned int RunRangeDependentPedeLabeler::lasBeamIdFromLabel(unsigned int label) const {
248  const unsigned int aliLabel = this->alignableLabelFromLabel(label);
249  if (aliLabel < theMinLabel)
250  return 0; // error already given
251 
252  UintUintMap::const_iterator position = theLabelToLasBeamMap.find(aliLabel);
253  if (position != theLabelToLasBeamMap.end()) {
254  return position->second;
255  } else {
256  edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::lasBeamIdFromLabel"
257  << "Alignable label " << aliLabel << " not in map.";
258  return 0;
259  }
260 }
261 
263  Alignable* ali = alignableFromLabel(label);
264  unsigned int firstLabel = alignableLabel(ali);
265  return (label - firstLabel) / theMaxNumParam;
266 }
267 
269  Alignable* ali = alignableFromLabel(label);
270 
271  AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(ali);
272  if (positionAli == theAlignableToRunRangeRangeMap.end())
273  return theOpenRunRange;
274 
275  unsigned int firstLabel = alignableLabel(ali);
276  unsigned int runRangeIndex = (label - firstLabel) / theParamInstanceOffset;
277  unsigned int paramNum = this->paramNumFromLabel(label);
278 
279  RunRangeParamMap::const_iterator positionParam = (*positionAli).second.find(paramNum);
280  if (positionParam == (*positionAli).second.end()) {
281  return theOpenRunRange;
282  }
283 
284  return positionParam->second[runRangeIndex];
285 }
286 
287 //__________________________________________________________________________________________________
288 std::vector<std::string> RunRangeDependentPedeLabeler::decompose(const std::string& s,
290  std::vector<std::string> result;
291 
292  std::string::size_type previousPos = 0;
293  while (true) {
294  const std::string::size_type delimiterPos = s.find(delimiter, previousPos);
295  if (delimiterPos == std::string::npos) {
296  result.push_back(s.substr(previousPos)); // until end
297  break;
298  }
299  result.push_back(s.substr(previousPos, delimiterPos - previousPos));
300  previousPos = delimiterPos + 1; // +1: skip delimiter
301  }
302 
303  return result;
304 }
305 
306 //__________________________________________________________________________________________________
307 std::vector<unsigned int> RunRangeDependentPedeLabeler::convertParamSel(const std::string& selString) const {
308  std::vector<unsigned int> result;
309  for (std::string::size_type pos = 0; pos < selString.size(); ++pos) {
310  if (selString[pos] == '1')
311  result.push_back(pos);
312  }
313  return result;
314 }
315 
317  AlignableMuon* aliMuon,
318  AlignableExtras* aliExtras,
319  const edm::ParameterSet& config) {
320  static std::atomic<bool> oldRunRangeSelectionWarning{false};
321 
323 
324  AlignmentParameterSelector selector(aliTracker, aliMuon, aliExtras);
325 
326  std::vector<char> paramSelDummy(6, '1');
327 
328  const std::vector<edm::ParameterSet> RunRangeSelectionVPSet =
329  config.getUntrackedParameter<std::vector<edm::ParameterSet> >("RunRangeSelection");
330 
331  for (const auto& runRangeSel : RunRangeSelectionVPSet) {
332  const auto tempRunRanges = runRangeSel.getParameter<std::vector<std::string> >("RunRanges");
333  if (tempRunRanges.empty()) {
334  throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
335  << "RunRanges empty\n";
336  }
337 
340  long int temp;
341  for (const auto& iRunRange : tempRunRanges) {
342  if (iRunRange.find(':') == std::string::npos) {
344  temp = strtol(iRunRange.c_str(), nullptr, 0);
345  if (temp != -1)
346  first = temp;
347 
348  } else {
349  bool expected = false;
350  if (oldRunRangeSelectionWarning.compare_exchange_strong(expected, true)) {
351  edm::LogWarning("BadConfig")
352  << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap"
353  << "Config file contains old format for 'RunRangeSelection'. Only the start run\n"
354  << "number is used internally. The number of the last run is ignored and can be\n"
355  << "safely removed from the config file.\n";
356  }
357 
358  std::vector<std::string> tokens = edm::tokenize(iRunRange, ":");
360  temp = strtol(tokens[0].c_str(), nullptr, 0);
361  if (temp != -1)
362  first = temp;
363  }
364 
365  RunRanges.push_back(std::pair<cond::Time_t, cond::Time_t>(first, cond::timeTypeSpecs[cond::runnumber].endValue));
366  }
367 
368  for (unsigned int i = 0; i < RunRanges.size() - 1; ++i) {
369  RunRanges[i].second = RunRanges[i + 1].first - 1;
370  if (RunRanges[i].first > RunRanges[i].second) {
371  throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
372  << "Inconsistency in 'RunRangeSelection' parameter set.";
373  }
374  }
375 
376  const auto selStrings = runRangeSel.getParameter<std::vector<std::string> >("selector");
377  for (const auto& iSel : selStrings) {
378  std::vector<std::string> decompSel(this->decompose(iSel, ','));
379 
380  if (decompSel.size() != 2) {
381  throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
382  << iSel << " should have at least 2 ','-separated parts\n";
383  }
384 
385  std::vector<unsigned int> selParam = this->convertParamSel(decompSel[1]);
386  selector.clear();
387  selector.addSelection(decompSel[0], paramSelDummy);
388 
389  const auto& alis = selector.selectedAlignables();
390 
391  for (const auto& iAli : alis) {
392  if (iAli->alignmentParameters() == nullptr) {
393  throw cms::Exception("BadConfig")
394  << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
395  << "Run dependence configured for alignable of type "
396  << objectIdProvider().idToString(iAli->alignableObjectId()) << " at (" << iAli->globalPosition().x()
397  << "," << iAli->globalPosition().y() << "," << iAli->globalPosition().z() << "), "
398  << "but that has no parameters. Please check that all run "
399  << "dependent parameters are also selected for alignment.\n";
400  }
401 
402  for (const auto& iParam : selParam) {
403  AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(iAli);
404  if (positionAli != theAlignableToRunRangeRangeMap.end()) {
405  AlignmentParameters* AliParams = (*positionAli).first->alignmentParameters();
406  if (static_cast<int>(selParam[selParam.size() - 1]) >= AliParams->size()) {
407  throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
408  << "mismatch in number of parameters\n";
409  }
410 
411  RunRangeParamMap::const_iterator positionParam = (*positionAli).second.find(iParam);
412  if (positionParam != (*positionAli).second.end()) {
413  throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
414  << "RunRange range for parameter specified twice\n";
415  }
416  }
417 
419  }
420  }
421  }
422  }
423 
424  return theAlignableToRunRangeRangeMap.size();
425 }
426 
427 //_________________________________________________________________________
429  theAlignableToIdMap.clear(); // just in case of re-use...
430 
431  align::Alignables allComps;
432 
433  for (const auto& iAli : alis) {
434  if (iAli) {
435  allComps.push_back(iAli);
436  iAli->recursiveComponents(allComps);
437  }
438  }
439 
440  unsigned int id = theMinLabel;
441  for (const auto& iter : allComps) {
442  theAlignableToIdMap.insert(AlignableToIdPair(iter, id));
443  id += theMaxNumParam;
444  }
445 
446  // also care about las beams
447  theLasBeamToLabelMap.clear(); // just in case of re-use...
448  // FIXME: Temporarily hard code values stolen from
449  // https://twiki.cern.ch/twiki/bin/view/CMS/TkLasTrackBasedInterface#Beam_identifier .
450  unsigned int beamIds[] = {0, 10, 20, 30, 40, 50, 60, 70, // TEC+ R4
451  1, 11, 21, 31, 41, 51, 61, 71, // TEC+ R6
452  100, 110, 120, 130, 140, 150, 160, 170, // TEC- R4
453  101, 111, 121, 131, 141, 151, 161, 171, // TEC- R6
454  200, 210, 220, 230, 240, 250, 260, 270}; // AT
455 
456  const size_t nBeams = sizeof(beamIds) / sizeof(beamIds[0]);
457  for (size_t iBeam = 0; iBeam < nBeams; ++iBeam) {
458  //edm::LogInfo("Alignment") << "Las beam " << beamIds[iBeam] << " gets label " << id << ".";
459  theLasBeamToLabelMap[beamIds[iBeam]] = id;
460  id += theMaxNumParam;
461  }
462 
463  if (id > theParamInstanceOffset) { // 'overflow' per instance
464  throw cms::Exception("Alignment") << "@SUB=RunRangeDependentPedeLabeler::buildMap: "
465  << "Too many labels per instance (" << id - 1 << ") leading to double use, "
466  << "increase PedeLabelerBase::theParamInstanceOffset!\n";
467  }
468  // return combined size
469  return theAlignableToIdMap.size() + theLasBeamToLabelMap.size();
470 }
471 
472 //_________________________________________________________________________
474  // alignables
475  theIdToAlignableMap.clear(); // just in case of re-use...
476 
477  for (const auto& it : theAlignableToIdMap) {
478  const unsigned int key = it.second;
479  Alignable* ali = it.first;
480  const unsigned int nInstances = this->numberOfParameterInstances(ali, -1);
482  for (unsigned int iInstance = 0; iInstance < nInstances; ++iInstance) {
483  theIdToAlignableMap[key + iInstance * theParamInstanceOffset] = ali;
484  }
485  }
486 
487  // las beams
488  theLabelToLasBeamMap.clear(); // just in case of re-use...
489 
490  for (const auto& it : theLasBeamToLabelMap) {
491  theLabelToLasBeamMap[it.second] = it.first; //revert key/value
492  }
493 
494  // return combined size
495  return theIdToAlignableMap.size() + theLabelToLasBeamMap.size();
496 }
497 
RunNumber_t run() const
Definition: EventID.h:38
const TimeTypeSpecs timeTypeSpecs[]
Definition: Time.cc:16
align::ID id() const
Return the ID of Alignable, i.e. DetId of &#39;first&#39; component GeomDet(Unit).
Definition: Alignable.h:180
T getUntrackedParameter(std::string const &, T const &) const
AlignableToIdMap::value_type AlignableToIdPair
UintUintMap theLabelToLasBeamMap
labels for las beams
unsigned int alignableLabelFromLabel(unsigned int label) const override
alignable label from parameter label (works also for alignable label...)
Time_t beginValue
Definition: Time.h:41
static PFTauRenderPlugin instance
unsigned int paramNumFromLabel(unsigned int paramLabel) const override
parameter number, 0 <= .. < theMaxNumParam, belonging to unique parameter label
unsigned int alignableLabel(Alignable *alignable) const override
Return 32-bit unique label for alignable, 0 indicates failure.
static const unsigned int theMinLabel
unsigned int alignableLabelFromParamAndInstance(Alignable *alignable, unsigned int param, unsigned int instance) const override
Definition: config.py:1
const edm::EventID eventId() const
uint16_t size_type
const RunRange theOpenRunRange
unsigned int theMaxNumberOfParameterInstances
reverse of the above
define event information passed to algorithms
static const unsigned int theMaxNumParam
const RunRange & runRangeFromLabel(unsigned int label) const override
U second(std::pair< T, U > const &p)
char const * label
void clear()
remove all selected Alignables and geometrical restrictions
unsigned long long Time_t
Definition: Time.h:14
unsigned int buildReverseMap()
returns size of map
virtual StructureType alignableObjectId() const =0
Return the alignable type identifier.
AlignableToRunRangeRangeMap theAlignableToRunRangeRangeMap
providing unique ID for alignable, space for param IDs
const Alignables & components() const
IdToAlignableMap theIdToAlignableMap
providing unique ID for alignable, space for param IDs
unsigned int parameterLabel(unsigned int aliLabel, unsigned int parNum) const override
returns the label for a given alignable parameter number combination
const align::Alignables & selectedAlignables() const
vector of alignables selected so far
Definition: DetId.h:17
unsigned int runRangeIndexFromLabel(unsigned int label) const
align::RunRange RunRange
bool hasSplitParameters(Alignable *alignable) const override
returns true if the alignable has parameters that are split into various bins
int size(void) const
Get number of parameters.
const char * idToString(align::StructureType type) const
UintUintMap theLasBeamToLabelMap
reverse map
unsigned int lasBeamLabel(unsigned int lasBeamId) const override
static const unsigned int theParamInstanceOffset
std::vector< Alignable * > Alignables
Definition: Utilities.h:31
unsigned int addSelection(const std::string &name, const std::vector< char > &paramSel)
unsigned int buildRunRangeDependencyMap(AlignableTracker *aliTracker, AlignableMuon *aliMuon, AlignableExtras *extras, const edm::ParameterSet &config)
RunRangeDependentPedeLabeler(const PedeLabelerBase::TopLevelAlignables &alignables, const edm::ParameterSet &config)
constructor from three Alignables (null pointers allowed )
static int position[264][3]
Definition: ReadPGInfo.cc:289
unsigned int lasBeamIdFromLabel(unsigned int label) const override
#define DEFINE_EDM_PLUGIN(factory, type, name)
std::vector< unsigned int > convertParamSel(const std::string &selString) const
align::RunRanges RunRanges
Constructor of the full muon geometry.
Definition: AlignableMuon.h:33
unsigned int numberOfParameterInstances(Alignable *alignable, int param=-1) const override
returns the number of instances for a given parameter
const AlignableObjectId & objectIdProvider() const
Return tracker alignable object ID provider derived from the tracker&#39;s geometry.
std::vector< std::string > decompose(const std::string &s, std::string::value_type delimiter) const
unsigned int buildMap(const align::Alignables &)
returns size of map
Alignable * alignableFromLabel(unsigned int label) const override
std::vector< std::string > tokenize(std::string const &input, std::string const &separator)
breaks the input string into tokens, delimited by the separator