Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 11:56:34

0001 /**
0002  * \file RunRangeDependentPedeLabeler.cc
0003  *
0004  *  \author    : Gero Flucke
0005  *  date       : October 2006
0006  *  $Revision: 1.4 $
0007  *  $Date: 2012/08/10 09:01:11 $
0008  *  (last update by $Author: flucke $)
0009  */
0010 
0011 #include <algorithm>
0012 #include <atomic>
0013 
0014 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0015 #include "FWCore/Utilities/interface/Parse.h"
0016 
0017 #include "Alignment/CommonAlignment/interface/AlignableObjectId.h"
0018 #include "Alignment/CommonAlignment/interface/Alignable.h"
0019 #include "Alignment/TrackerAlignment/interface/AlignableTracker.h"
0020 #include "Alignment/MuonAlignment/interface/AlignableMuon.h"
0021 #include "Alignment/CommonAlignment/interface/AlignableExtras.h"
0022 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterSelector.h"
0023 #include "Alignment/CommonAlignmentParametrization/interface/RigidBodyAlignmentParameters.h"
0024 
0025 #include "RunRangeDependentPedeLabeler.h"
0026 
0027 //___________________________________________________________________________
0028 RunRangeDependentPedeLabeler::RunRangeDependentPedeLabeler(const PedeLabelerBase::TopLevelAlignables& alignables,
0029                                                            const edm::ParameterSet& config)
0030     : PedeLabelerBase(alignables, config), theMaxNumberOfParameterInstances(0) {
0031   align::Alignables alis;
0032   alis.push_back(alignables.aliTracker_);
0033   alis.push_back(alignables.aliMuon_);
0034 
0035   if (alignables.aliExtras_) {
0036     for (const auto& ali : alignables.aliExtras_->components()) {
0037       alis.push_back(ali);
0038     }
0039   }
0040 
0041   this->buildRunRangeDependencyMap(alignables.aliTracker_, alignables.aliMuon_, alignables.aliExtras_, config);
0042   this->buildMap(alis);
0043   this->buildReverseMap();  // needed already now to 'fill' theMaxNumberOfParameterInstances
0044 }
0045 
0046 //___________________________________________________________________________
0047 
0048 RunRangeDependentPedeLabeler::~RunRangeDependentPedeLabeler() {}
0049 
0050 //___________________________________________________________________________
0051 /// Return 32-bit unique label for alignable, 0 indicates failure.
0052 unsigned int RunRangeDependentPedeLabeler::alignableLabel(const Alignable* alignable) const {
0053   if (!alignable)
0054     return 0;
0055 
0056   AlignableToIdMap::const_iterator position = theAlignableToIdMap.find(alignable);
0057   if (position != theAlignableToIdMap.end()) {
0058     return position->second;
0059   } else {
0060     const DetId detId(alignable->id());
0061     //throw cms::Exception("LogicError")
0062     edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::alignableLabel"
0063                                 << "Alignable " << typeid(*alignable).name()
0064                                 << " not in map, det/subdet/alignableStructureType = " << detId.det() << "/"
0065                                 << detId.subdetId() << "/" << alignable->alignableObjectId();
0066     return 0;
0067   }
0068 }
0069 
0070 //___________________________________________________________________________
0071 // Return 32-bit unique label for alignable, 0 indicates failure.
0072 unsigned int RunRangeDependentPedeLabeler::alignableLabelFromParamAndInstance(const Alignable* alignable,
0073                                                                               unsigned int param,
0074                                                                               unsigned int instance) const {
0075   if (!alignable)
0076     return 0;
0077 
0078   AlignableToIdMap::const_iterator position = theAlignableToIdMap.find(alignable);
0079   if (position != theAlignableToIdMap.end()) {
0080     AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(alignable);
0081     if (positionAli != theAlignableToRunRangeRangeMap.end()) {
0082       RunRangeParamMap::const_iterator positionParam = (*positionAli).second.find(param);
0083       if (positionParam != (*positionAli).second.end()) {
0084         if (instance >= (*positionParam).second.size()) {
0085           throw cms::Exception("Alignment") << "RunRangeDependentPedeLabeler::alignableLabelFromParamAndRunRange: "
0086                                             << "RunRangeIdx out of bounds.\n";
0087         }
0088         return position->second + instance * theParamInstanceOffset;
0089       } else {
0090         return position->second;
0091       }
0092     } else {
0093       return position->second;
0094     }
0095   } else {
0096     const DetId detId(alignable->id());
0097     //throw cms::Exception("LogicError")
0098     edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::alignableLabel"
0099                                 << "Alignable " << typeid(*alignable).name()
0100                                 << " not in map, det/subdet/alignableStructureType = " << detId.det() << "/"
0101                                 << detId.subdetId() << "/" << alignable->alignableObjectId();
0102     return 0;
0103   }
0104 }
0105 
0106 //_________________________________________________________________________
0107 unsigned int RunRangeDependentPedeLabeler::lasBeamLabel(unsigned int lasBeamId) const {
0108   UintUintMap::const_iterator position = theLasBeamToLabelMap.find(lasBeamId);
0109   if (position != theLasBeamToLabelMap.end()) {
0110     return position->second;
0111   } else {
0112     //throw cms::Exception("LogicError")
0113     edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::lasBeamLabel"
0114                                 << "No label for beam Id " << lasBeamId;
0115     return 0;
0116   }
0117 }
0118 
0119 //_________________________________________________________________________
0120 unsigned int RunRangeDependentPedeLabeler::parameterLabel(unsigned int aliLabel, unsigned int parNum) const {
0121   if (parNum >= theMaxNumParam) {
0122     throw cms::Exception("Alignment") << "@SUB=RunRangeDependentPedeLabeler::parameterLabel"
0123                                       << "Parameter number " << parNum << " out of range 0 <= num < " << theMaxNumParam;
0124   }
0125   return aliLabel + parNum;
0126 }
0127 
0128 //_________________________________________________________________________
0129 unsigned int RunRangeDependentPedeLabeler::parameterLabel(Alignable* alignable,
0130                                                           unsigned int parNum,
0131                                                           const AlignmentAlgorithmBase::EventInfo& eventInfo,
0132                                                           const TrajectoryStateOnSurface& tsos) const {
0133   if (!alignable)
0134     return 0;
0135 
0136   if (parNum >= theMaxNumParam) {
0137     throw cms::Exception("Alignment") << "@SUB=RunRangeDependentPedeLabeler::parameterLabel"
0138                                       << "Parameter number " << parNum << " out of range 0 <= num < " << theMaxNumParam;
0139   }
0140 
0141   AlignableToIdMap::const_iterator position = theAlignableToIdMap.find(alignable);
0142   if (position != theAlignableToIdMap.end()) {
0143     AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(alignable);
0144     if (positionAli != theAlignableToRunRangeRangeMap.end()) {
0145       RunRangeParamMap::const_iterator positionParam = (*positionAli).second.find(parNum);
0146       if (positionParam != (*positionAli).second.end()) {
0147         int offset = 0;
0148         const RunRangeVector& runRanges = (*positionParam).second;
0149         for (const auto& iRunRange : runRanges) {
0150           if (eventInfo.eventId().run() >= iRunRange.first && eventInfo.eventId().run() <= iRunRange.second) {
0151             return position->second + offset * theParamInstanceOffset + parNum;
0152           }
0153           offset++;
0154         }
0155         const DetId detId(alignable->id());
0156         edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::parameterLabel"
0157                                     << "Instance for Alignable " << typeid(*alignable).name()
0158                                     << " not in map, det/subdet/alignableStructureType = " << detId.det() << "/"
0159                                     << detId.subdetId() << "/" << alignable->alignableObjectId() << " for run "
0160                                     << eventInfo.eventId().run();
0161         return 0;
0162       } else {
0163         return position->second + parNum;
0164       }
0165 
0166     } else {
0167       return position->second + parNum;
0168     }
0169   } else {
0170     const DetId detId(alignable->id());
0171     //throw cms::Exception("LogicError")
0172     edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::parameterLabel"
0173                                 << "Alignable " << typeid(*alignable).name()
0174                                 << " not in map, det/subdet/alignableStructureType = " << detId.det() << "/"
0175                                 << detId.subdetId() << "/" << alignable->alignableObjectId();
0176     return 0;
0177   }
0178 }
0179 
0180 //_________________________________________________________________________
0181 bool RunRangeDependentPedeLabeler::hasSplitParameters(Alignable* alignable) const {
0182   AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(alignable);
0183   if (positionAli != theAlignableToRunRangeRangeMap.end())
0184     return true;
0185   return false;
0186 }
0187 
0188 //_________________________________________________________________________
0189 unsigned int RunRangeDependentPedeLabeler::numberOfParameterInstances(Alignable* alignable, int param) const {
0190   AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(alignable);
0191   if (positionAli != theAlignableToRunRangeRangeMap.end()) {
0192     size_t nRunRanges = 1;
0193     if (param == -1) {
0194       for (const auto& iParam : (*positionAli).second) {
0195         nRunRanges = std::max(nRunRanges, iParam.second.size());
0196       }
0197       return nRunRanges;
0198     } else {
0199       RunRangeParamMap::const_iterator iParam = (*positionAli).second.find(param);
0200       if (iParam != (*positionAli).second.end()) {
0201         return iParam->second.size();
0202       } else {
0203         return 1;
0204       }
0205     }
0206   }
0207 
0208   return 1;
0209 }
0210 
0211 //___________________________________________________________________________
0212 unsigned int RunRangeDependentPedeLabeler::paramNumFromLabel(unsigned int paramLabel) const {
0213   if (paramLabel < theMinLabel) {
0214     edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::paramNumFromLabel"
0215                                 << "Label " << paramLabel << " should be >= " << theMinLabel;
0216     return 0;
0217   }
0218   return (paramLabel - theMinLabel) % theMaxNumParam;
0219 }
0220 
0221 //___________________________________________________________________________
0222 unsigned int RunRangeDependentPedeLabeler::alignableLabelFromLabel(unsigned int paramLabel) const {
0223   return paramLabel - this->paramNumFromLabel(paramLabel);
0224 }
0225 
0226 //___________________________________________________________________________
0227 Alignable* RunRangeDependentPedeLabeler::alignableFromLabel(unsigned int label) const {
0228   const unsigned int aliLabel = this->alignableLabelFromLabel(label);
0229   if (aliLabel < theMinLabel)
0230     return nullptr;  // error already given
0231 
0232   IdToAlignableMap::const_iterator position = theIdToAlignableMap.find(aliLabel);
0233   if (position != theIdToAlignableMap.end()) {
0234     return position->second;
0235   } else {
0236     // error only if not in lasBeamMap:
0237     UintUintMap::const_iterator position = theLabelToLasBeamMap.find(aliLabel);
0238     if (position == theLabelToLasBeamMap.end()) {
0239       edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::alignableFromLabel"
0240                                   << "Alignable label " << aliLabel << " not in map.";
0241     }
0242     return nullptr;
0243   }
0244 }
0245 
0246 //___________________________________________________________________________
0247 unsigned int RunRangeDependentPedeLabeler::lasBeamIdFromLabel(unsigned int label) const {
0248   const unsigned int aliLabel = this->alignableLabelFromLabel(label);
0249   if (aliLabel < theMinLabel)
0250     return 0;  // error already given
0251 
0252   UintUintMap::const_iterator position = theLabelToLasBeamMap.find(aliLabel);
0253   if (position != theLabelToLasBeamMap.end()) {
0254     return position->second;
0255   } else {
0256     edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::lasBeamIdFromLabel"
0257                                 << "Alignable label " << aliLabel << " not in map.";
0258     return 0;
0259   }
0260 }
0261 
0262 unsigned int RunRangeDependentPedeLabeler::runRangeIndexFromLabel(unsigned int label) const {
0263   Alignable* ali = alignableFromLabel(label);
0264   unsigned int firstLabel = alignableLabel(ali);
0265   return (label - firstLabel) / theMaxNumParam;
0266 }
0267 
0268 const RunRangeDependentPedeLabeler::RunRange& RunRangeDependentPedeLabeler::runRangeFromLabel(unsigned int label) const {
0269   Alignable* ali = alignableFromLabel(label);
0270 
0271   AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(ali);
0272   if (positionAli == theAlignableToRunRangeRangeMap.end())
0273     return theOpenRunRange;
0274 
0275   unsigned int firstLabel = alignableLabel(ali);
0276   unsigned int runRangeIndex = (label - firstLabel) / theParamInstanceOffset;
0277   unsigned int paramNum = this->paramNumFromLabel(label);
0278 
0279   RunRangeParamMap::const_iterator positionParam = (*positionAli).second.find(paramNum);
0280   if (positionParam == (*positionAli).second.end()) {
0281     return theOpenRunRange;
0282   }
0283 
0284   return positionParam->second[runRangeIndex];
0285 }
0286 
0287 //__________________________________________________________________________________________________
0288 std::vector<std::string> RunRangeDependentPedeLabeler::decompose(const std::string& s,
0289                                                                  std::string::value_type delimiter) const {
0290   std::vector<std::string> result;
0291 
0292   std::string::size_type previousPos = 0;
0293   while (true) {
0294     const std::string::size_type delimiterPos = s.find(delimiter, previousPos);
0295     if (delimiterPos == std::string::npos) {
0296       result.push_back(s.substr(previousPos));  // until end
0297       break;
0298     }
0299     result.push_back(s.substr(previousPos, delimiterPos - previousPos));
0300     previousPos = delimiterPos + 1;  // +1: skip delimiter
0301   }
0302 
0303   return result;
0304 }
0305 
0306 //__________________________________________________________________________________________________
0307 std::vector<unsigned int> RunRangeDependentPedeLabeler::convertParamSel(const std::string& selString) const {
0308   std::vector<unsigned int> result;
0309   for (std::string::size_type pos = 0; pos < selString.size(); ++pos) {
0310     if (selString[pos] == '1')
0311       result.push_back(pos);
0312   }
0313   return result;
0314 }
0315 
0316 unsigned int RunRangeDependentPedeLabeler::buildRunRangeDependencyMap(AlignableTracker* aliTracker,
0317                                                                       AlignableMuon* aliMuon,
0318                                                                       AlignableExtras* aliExtras,
0319                                                                       const edm::ParameterSet& config) {
0320   static std::atomic<bool> oldRunRangeSelectionWarning{false};
0321 
0322   theAlignableToRunRangeRangeMap.clear();
0323 
0324   AlignmentParameterSelector selector(aliTracker, aliMuon, aliExtras);
0325 
0326   std::vector<char> paramSelDummy(6, '1');
0327 
0328   const std::vector<edm::ParameterSet> RunRangeSelectionVPSet =
0329       config.getUntrackedParameter<std::vector<edm::ParameterSet> >("RunRangeSelection");
0330 
0331   for (const auto& runRangeSel : RunRangeSelectionVPSet) {
0332     const auto tempRunRanges = runRangeSel.getParameter<std::vector<std::string> >("RunRanges");
0333     if (tempRunRanges.empty()) {
0334       throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
0335                                         << "RunRanges empty\n";
0336     }
0337 
0338     RunRangeVector RunRanges;
0339     cond::Time_t first;
0340     long int temp;
0341     for (const auto& iRunRange : tempRunRanges) {
0342       if (iRunRange.find(':') == std::string::npos) {
0343         first = cond::timeTypeSpecs[cond::runnumber].beginValue;
0344         temp = strtol(iRunRange.c_str(), nullptr, 0);
0345         if (temp != -1)
0346           first = temp;
0347 
0348       } else {
0349         bool expected = false;
0350         if (oldRunRangeSelectionWarning.compare_exchange_strong(expected, true)) {
0351           edm::LogWarning("BadConfig")
0352               << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap"
0353               << "Config file contains old format for 'RunRangeSelection'. Only the start run\n"
0354               << "number is used internally. The number of the last run is ignored and can be\n"
0355               << "safely removed from the config file.\n";
0356         }
0357 
0358         std::vector<std::string> tokens = edm::tokenize(iRunRange, ":");
0359         first = cond::timeTypeSpecs[cond::runnumber].beginValue;
0360         temp = strtol(tokens[0].c_str(), nullptr, 0);
0361         if (temp != -1)
0362           first = temp;
0363       }
0364 
0365       RunRanges.push_back(std::pair<cond::Time_t, cond::Time_t>(first, cond::timeTypeSpecs[cond::runnumber].endValue));
0366     }
0367 
0368     for (unsigned int i = 0; i < RunRanges.size() - 1; ++i) {
0369       RunRanges[i].second = RunRanges[i + 1].first - 1;
0370       if (RunRanges[i].first > RunRanges[i].second) {
0371         throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
0372                                           << "Inconsistency in 'RunRangeSelection' parameter set.";
0373       }
0374     }
0375 
0376     const auto selStrings = runRangeSel.getParameter<std::vector<std::string> >("selector");
0377     for (const auto& iSel : selStrings) {
0378       std::vector<std::string> decompSel(this->decompose(iSel, ','));
0379 
0380       if (decompSel.size() != 2) {
0381         throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
0382                                           << iSel << " should have at least 2 ','-separated parts\n";
0383       }
0384 
0385       std::vector<unsigned int> selParam = this->convertParamSel(decompSel[1]);
0386       selector.clear();
0387       selector.addSelection(decompSel[0], paramSelDummy);
0388 
0389       const auto& alis = selector.selectedAlignables();
0390 
0391       for (const auto& iAli : alis) {
0392         if (iAli->alignmentParameters() == nullptr) {
0393           throw cms::Exception("BadConfig")
0394               << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
0395               << "Run dependence configured for alignable of type "
0396               << objectIdProvider().idToString(iAli->alignableObjectId()) << " at (" << iAli->globalPosition().x()
0397               << "," << iAli->globalPosition().y() << "," << iAli->globalPosition().z() << "), "
0398               << "but that has no parameters. Please check that all run "
0399               << "dependent parameters are also selected for alignment.\n";
0400         }
0401 
0402         for (const auto& iParam : selParam) {
0403           AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(iAli);
0404           if (positionAli != theAlignableToRunRangeRangeMap.end()) {
0405             AlignmentParameters* AliParams = (*positionAli).first->alignmentParameters();
0406             if (static_cast<int>(selParam[selParam.size() - 1]) >= AliParams->size()) {
0407               throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
0408                                                 << "mismatch in number of parameters\n";
0409             }
0410 
0411             RunRangeParamMap::const_iterator positionParam = (*positionAli).second.find(iParam);
0412             if (positionParam != (*positionAli).second.end()) {
0413               throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
0414                                                 << "RunRange range for parameter specified twice\n";
0415             }
0416           }
0417 
0418           theAlignableToRunRangeRangeMap[iAli][iParam] = RunRanges;
0419         }
0420       }
0421     }
0422   }
0423 
0424   return theAlignableToRunRangeRangeMap.size();
0425 }
0426 
0427 //_________________________________________________________________________
0428 unsigned int RunRangeDependentPedeLabeler::buildMap(const align::Alignables& alis) {
0429   theAlignableToIdMap.clear();  // just in case of re-use...
0430 
0431   align::Alignables allComps;
0432 
0433   for (const auto& iAli : alis) {
0434     if (iAli) {
0435       allComps.push_back(iAli);
0436       iAli->recursiveComponents(allComps);
0437     }
0438   }
0439 
0440   unsigned int id = theMinLabel;
0441   for (const auto& iter : allComps) {
0442     theAlignableToIdMap.insert(AlignableToIdPair(iter, id));
0443     id += theMaxNumParam;
0444   }
0445 
0446   // also care about las beams
0447   theLasBeamToLabelMap.clear();  // just in case of re-use...
0448   // FIXME: Temporarily hard code values stolen from
0449   // https://twiki.cern.ch/twiki/bin/view/CMS/TkLasTrackBasedInterface#Beam_identifier .
0450   unsigned int beamIds[] = {0,   10,  20,  30,  40,  50,  60,  70,    // TEC+ R4
0451                             1,   11,  21,  31,  41,  51,  61,  71,    // TEC+ R6
0452                             100, 110, 120, 130, 140, 150, 160, 170,   // TEC- R4
0453                             101, 111, 121, 131, 141, 151, 161, 171,   // TEC- R6
0454                             200, 210, 220, 230, 240, 250, 260, 270};  // AT
0455 
0456   const size_t nBeams = sizeof(beamIds) / sizeof(beamIds[0]);
0457   for (size_t iBeam = 0; iBeam < nBeams; ++iBeam) {
0458     //edm::LogInfo("Alignment") << "Las beam " << beamIds[iBeam] << " gets label " << id << ".";
0459     theLasBeamToLabelMap[beamIds[iBeam]] = id;
0460     id += theMaxNumParam;
0461   }
0462 
0463   if (id > theParamInstanceOffset) {  // 'overflow' per instance
0464     throw cms::Exception("Alignment") << "@SUB=RunRangeDependentPedeLabeler::buildMap: "
0465                                       << "Too many labels per instance (" << id - 1 << ") leading to double use, "
0466                                       << "increase PedeLabelerBase::theParamInstanceOffset!\n";
0467   }
0468   // return combined size
0469   return theAlignableToIdMap.size() + theLasBeamToLabelMap.size();
0470 }
0471 
0472 //_________________________________________________________________________
0473 unsigned int RunRangeDependentPedeLabeler::buildReverseMap() {
0474   // alignables
0475   theIdToAlignableMap.clear();  // just in case of re-use...
0476 
0477   for (const auto& it : theAlignableToIdMap) {
0478     const unsigned int key = it.second;
0479     Alignable* ali = it.first;
0480     const unsigned int nInstances = this->numberOfParameterInstances(ali, -1);
0481     theMaxNumberOfParameterInstances = std::max(nInstances, theMaxNumberOfParameterInstances);
0482     for (unsigned int iInstance = 0; iInstance < nInstances; ++iInstance) {
0483       theIdToAlignableMap[key + iInstance * theParamInstanceOffset] = ali;
0484     }
0485   }
0486 
0487   // las beams
0488   theLabelToLasBeamMap.clear();  // just in case of re-use...
0489 
0490   for (const auto& it : theLasBeamToLabelMap) {
0491     theLabelToLasBeamMap[it.second] = it.first;  //revert key/value
0492   }
0493 
0494   // return combined size
0495   return theIdToAlignableMap.size() + theLabelToLasBeamMap.size();
0496 }
0497 
0498 #include "Alignment/MillePedeAlignmentAlgorithm/interface/PedeLabelerPluginFactory.h"
0499 DEFINE_EDM_PLUGIN(PedeLabelerPluginFactory, RunRangeDependentPedeLabeler, "RunRangeDependentPedeLabeler");