Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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