CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2_patch1/src/Alignment/MillePedeAlignmentAlgorithm/src/MomentumDependentPedeLabeler.cc

Go to the documentation of this file.
00001 
00011 #include <algorithm>
00012 
00013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00014 #include "FWCore/Utilities/interface/Parse.h"
00015 
00016 #include "Alignment/CommonAlignment/interface/Alignable.h"
00017 #include "Alignment/TrackerAlignment/interface/AlignableTracker.h"
00018 #include "Alignment/MuonAlignment/interface/AlignableMuon.h"
00019 #include "Alignment/CommonAlignment/interface/AlignableExtras.h"
00020 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterSelector.h"
00021 #include "Alignment/CommonAlignmentParametrization/interface/RigidBodyAlignmentParameters.h"
00022 
00023 #include "MomentumDependentPedeLabeler.h"
00024 
00025 //___________________________________________________________________________
00026 MomentumDependentPedeLabeler::MomentumDependentPedeLabeler(const PedeLabelerBase::TopLevelAlignables &alignables,
00027                                                            const edm::ParameterSet &config)
00028   : PedeLabelerBase(alignables, config),
00029     theOpenMomentumRange(std::pair<float,float>(0.0, 10000.0)),
00030     theMaxNumberOfParameterInstances(0)
00031 {
00032   std::vector<Alignable*> alis;
00033   alis.push_back(alignables.aliTracker_);
00034   alis.push_back(alignables.aliMuon_);
00035   
00036   if (alignables.aliExtras_) {
00037     align::Alignables allExtras = alignables.aliExtras_->components();
00038     for ( std::vector<Alignable*>::iterator it = allExtras.begin(); it != allExtras.end(); ++it ) {
00039       alis.push_back(*it);
00040     }
00041   }
00042   
00043   this->buildMomentumDependencyMap(alignables.aliTracker_,
00044                                    alignables.aliMuon_,
00045                                    alignables.aliExtras_, 
00046                                    config);
00047   this->buildMap(alis);
00048   this->buildReverseMap(); // needed already now to 'fill' theMaxNumberOfParameterInstances
00049 }
00050 
00051 //___________________________________________________________________________
00052 
00053 MomentumDependentPedeLabeler::~MomentumDependentPedeLabeler()
00054 {
00055 }
00056 
00057 //___________________________________________________________________________
00059 unsigned int MomentumDependentPedeLabeler::alignableLabel(Alignable *alignable) const
00060 {
00061   if (!alignable) return 0;
00062 
00063   AlignableToIdMap::const_iterator position = theAlignableToIdMap.find(alignable);
00064   if (position != theAlignableToIdMap.end()) {
00065     return position->second;
00066   } else {
00067     const DetId detId(alignable->id());
00068     //throw cms::Exception("LogicError") 
00069     edm::LogError("LogicError")
00070       << "@SUB=MomentumDependentPedeLabeler::alignableLabel" << "Alignable "
00071       << typeid(*alignable).name() << " not in map, det/subdet/alignableStructureType = "
00072       << detId.det() << "/" << detId.subdetId() << "/" << alignable->alignableObjectId();
00073     return 0;
00074   }
00075 }
00076 
00077 //___________________________________________________________________________
00078 // Return 32-bit unique label for alignable, 0 indicates failure.
00079 unsigned int MomentumDependentPedeLabeler::alignableLabelFromParamAndInstance(Alignable *alignable,
00080                                                                               unsigned int param,
00081                                                                               unsigned int instance) const
00082 {
00083   if (!alignable) return 0;
00084   
00085   AlignableToIdMap::const_iterator position = theAlignableToIdMap.find(alignable);
00086   if (position != theAlignableToIdMap.end()) {
00087     AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(alignable);
00088     if (positionAli != theAlignableToMomentumRangeMap.end()) {
00089       MomentumRangeParamMap::const_iterator positionParam = (*positionAli).second.find(param);
00090       if (positionParam!=(*positionAli).second.end()) {
00091         if (instance>=(*positionParam).second.size()) {
00092           throw cms::Exception("Alignment") << "@SUB=MomentumDependentPedeLabeler::alignableLabelFromParamAndMomentum" 
00093                                             << "iovIdx out of bounds";
00094         }
00095         return position->second + instance * theParamInstanceOffset;
00096       } else {
00097         return position->second;
00098       }
00099     } else {
00100       return position->second;
00101     }
00102   } else {
00103     const DetId detId(alignable->id());
00104     //throw cms::Exception("LogicError") 
00105     edm::LogError("LogicError")
00106       << "@SUB=MomentumDependentPedeLabeler::alignableLabel" << "Alignable "
00107       << typeid(*alignable).name() << " not in map, det/subdet/alignableStructureType = "
00108       << detId.det() << "/" << detId.subdetId() << "/" << alignable->alignableObjectId();
00109     return 0;
00110   }
00111 }
00112 
00113 //_________________________________________________________________________
00114 unsigned int MomentumDependentPedeLabeler::lasBeamLabel(unsigned int lasBeamId) const
00115 {
00116   UintUintMap::const_iterator position = theLasBeamToLabelMap.find(lasBeamId);
00117   if (position != theLasBeamToLabelMap.end()) {
00118     return position->second;
00119   } else {
00120     //throw cms::Exception("LogicError") 
00121     edm::LogError("LogicError") << "@SUB=MomentumDependentPedeLabeler::lasBeamLabel"
00122                                 << "No label for beam Id " << lasBeamId;
00123     return 0;
00124   }
00125 }
00126 
00127 //_________________________________________________________________________
00128 unsigned int MomentumDependentPedeLabeler::parameterLabel(unsigned int aliLabel, unsigned int parNum) const
00129 {
00130   if (parNum >= theMaxNumParam) {
00131     throw cms::Exception("Alignment") << "@SUB=MomentumDependentPedeLabeler::parameterLabel" 
00132                                       << "Parameter number " << parNum 
00133                                       << " out of range 0 <= num < " << theMaxNumParam;
00134   }
00135   return aliLabel + parNum;
00136 }
00137 
00138 //_________________________________________________________________________
00139 unsigned int MomentumDependentPedeLabeler::parameterLabel(Alignable *alignable, unsigned int parNum,
00140                                                           const AlignmentAlgorithmBase::EventInfo &eventInfo,
00141                                                           const TrajectoryStateOnSurface &tsos) const
00142 {
00143   if (!alignable) return 0;
00144   
00145   if (parNum >= theMaxNumParam) {
00146     throw cms::Exception("Alignment") << "@SUB=MomentumDependentPedeLabeler::parameterLabel" 
00147                                       << "Parameter number " << parNum 
00148                                       << " out of range 0 <= num < " << theMaxNumParam;
00149   }
00150 
00151   AlignableToIdMap::const_iterator position = theAlignableToIdMap.find(alignable);
00152   if (position != theAlignableToIdMap.end()) {
00153 
00154     AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(alignable);
00155     if (positionAli != theAlignableToMomentumRangeMap.end()) {
00156       
00157       MomentumRangeParamMap::const_iterator positionParam = (*positionAli).second.find(parNum);
00158       if (positionParam!=(*positionAli).second.end()) {
00159         
00160         int offset = 0;
00161         float mom = tsos.globalMomentum().mag();
00162         const MomentumRangeVector & momentumRanges = (*positionParam).second;
00163         for (MomentumRangeVector::const_iterator iMomentum = momentumRanges.begin();
00164              iMomentum != momentumRanges.end();
00165              ++iMomentum) {
00166           
00167           if (iMomentum->first<=mom && mom<iMomentum->second) {
00168             return position->second + offset * theParamInstanceOffset + parNum;
00169           }
00170           offset++;
00171         }
00172         const DetId detId(alignable->id());
00173         edm::LogError("LogicError")
00174           << "@SUB=MomentumDependentPedeLabeler::alignableLabel" << "Alignable "
00175           << typeid(*alignable).name() << " not in map, det/subdet/alignableStructureType = "
00176           << detId.det() << "/" << detId.subdetId() << "/" << alignable->alignableObjectId();
00177         return 0;
00178       } else {
00179         return position->second + parNum;
00180       }
00181 
00182     } else {
00183       return position->second + parNum;
00184     }
00185   } else {
00186     const DetId detId(alignable->id());
00187     //throw cms::Exception("LogicError") 
00188     edm::LogError("LogicError")
00189       << "@SUB=MomentumDependentPedeLabeler::alignableLabel" << "Alignable "
00190       << typeid(*alignable).name() << " not in map, det/subdet/alignableStructureType = "
00191       << detId.det() << "/" << detId.subdetId() << "/" << alignable->alignableObjectId();
00192     return 0;
00193   } 
00194 }
00195 
00196 //_________________________________________________________________________
00197 bool MomentumDependentPedeLabeler::hasSplitParameters(Alignable *alignable) const
00198 {
00199   AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(alignable);
00200   if (positionAli != theAlignableToMomentumRangeMap.end()) return true;
00201   return false;
00202 }
00203 
00204 //_________________________________________________________________________
00205 unsigned int MomentumDependentPedeLabeler::numberOfParameterInstances(Alignable *alignable, int param) const
00206 {
00207   AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(alignable);
00208   if (positionAli != theAlignableToMomentumRangeMap.end()) {
00209 
00210     size_t nMomentums = 1;
00211     if (param==-1) {
00212       for (MomentumRangeParamMap::const_iterator iParam = (*positionAli).second.begin();
00213            iParam != (*positionAli).second.end();
00214            ++iParam) {
00215         nMomentums = std::max(nMomentums, iParam->second.size());
00216       }
00217       return nMomentums;
00218     } else {
00219       MomentumRangeParamMap::const_iterator iParam = (*positionAli).second.find(param);
00220       if (iParam != (*positionAli).second.end()) {
00221         return iParam->second.size();
00222       } else {
00223         return 1;
00224       }
00225     }
00226   }
00227   
00228   return 1;
00229 }
00230 
00231 //___________________________________________________________________________
00232 unsigned int MomentumDependentPedeLabeler::paramNumFromLabel(unsigned int paramLabel) const
00233 {
00234   if (paramLabel < theMinLabel) {
00235     edm::LogError("LogicError") << "@SUB=MomentumDependentPedeLabeler::paramNumFromLabel"
00236                                 << "Label " << paramLabel << " should be >= " << theMinLabel;
00237     return 0;
00238   }
00239   return (paramLabel - theMinLabel) % theParamInstanceOffset;
00240 }
00241 
00242 //___________________________________________________________________________
00243 unsigned int MomentumDependentPedeLabeler::alignableLabelFromLabel(unsigned int paramLabel) const
00244 {
00245   return paramLabel - this->paramNumFromLabel(paramLabel);
00246 }
00247 
00248 //___________________________________________________________________________
00249 Alignable* MomentumDependentPedeLabeler::alignableFromLabel(unsigned int label) const
00250 {
00251   const unsigned int aliLabel = this->alignableLabelFromLabel(label);
00252   if (aliLabel < theMinLabel) return 0; // error already given
00253   
00254   if (theIdToAlignableMap.empty()) const_cast<MomentumDependentPedeLabeler*>(this)->buildReverseMap();
00255   IdToAlignableMap::const_iterator position = theIdToAlignableMap.find(aliLabel);
00256   if (position != theIdToAlignableMap.end()) {
00257     return position->second;
00258   } else {
00259     // error only if not in lasBeamMap:
00260     UintUintMap::const_iterator position = theLabelToLasBeamMap.find(aliLabel);
00261     if (position == theLabelToLasBeamMap.end()) {
00262       edm::LogError("LogicError") << "@SUB=MomentumDependentPedeLabeler::alignableFromLabel"
00263                                   << "Alignable label " << aliLabel << " not in map.";
00264     }
00265     return 0;
00266   }
00267 }
00268 
00269 //___________________________________________________________________________
00270 unsigned int MomentumDependentPedeLabeler::lasBeamIdFromLabel(unsigned int label) const
00271 {
00272   const unsigned int aliLabel = this->alignableLabelFromLabel(label);
00273   if (aliLabel < theMinLabel) return 0; // error already given
00274   
00275   if (theLabelToLasBeamMap.empty()) const_cast<MomentumDependentPedeLabeler*>(this)->buildReverseMap();
00276   UintUintMap::const_iterator position = theLabelToLasBeamMap.find(aliLabel);
00277   if (position != theLabelToLasBeamMap.end()) {
00278     return position->second;
00279   } else {
00280     edm::LogError("LogicError") << "@SUB=MomentumDependentPedeLabeler::lasBeamIdFromLabel"
00281                                 << "Alignable label " << aliLabel << " not in map.";
00282     return 0;
00283   }
00284 }
00285 
00286 //__________________________________________________________________________________________________
00287 std::vector<std::string> MomentumDependentPedeLabeler::decompose(const std::string &s,
00288                                                                  std::string::value_type delimiter) const
00289 {
00290   std::vector<std::string> result;
00291   
00292   std::string::size_type previousPos = 0;
00293   while (true) {
00294     const std::string::size_type delimiterPos = s.find(delimiter, previousPos);
00295     if (delimiterPos == std::string::npos) {
00296       result.push_back(s.substr(previousPos)); // until end
00297       break;
00298     }
00299     result.push_back(s.substr(previousPos, delimiterPos - previousPos));
00300     previousPos = delimiterPos + 1; // +1: skip delimiter
00301   }
00302 
00303   return result;
00304 }
00305 
00306 //__________________________________________________________________________________________________
00307 std::vector<unsigned int> MomentumDependentPedeLabeler::convertParamSel(const std::string &selString) const
00308 {
00309   std::vector<unsigned int> result;
00310   for (std::string::size_type pos = 0; pos < selString.size(); ++pos) {
00311     if (selString[pos]=='1') result.push_back(pos);
00312   }
00313   return result;
00314 }
00315 
00316 unsigned int MomentumDependentPedeLabeler::buildMomentumDependencyMap(AlignableTracker *aliTracker,
00317                                                                       AlignableMuon* aliMuon,
00318                                                                       AlignableExtras *aliExtras,
00319                                                                       const edm::ParameterSet &config)
00320 {
00321   theAlignableToMomentumRangeMap.clear();
00322   
00323   AlignmentParameterSelector selector(aliTracker, aliMuon, aliExtras);
00324   
00325   std::vector<char> paramSelDumthe(6, '1');
00326   
00327   const std::vector<edm::ParameterSet> parameterInstancesVPSet =
00328     config.getParameter<std::vector<edm::ParameterSet> >("parameterInstances");
00329   
00330   for (std::vector<edm::ParameterSet>::const_iterator iter = parameterInstancesVPSet.begin();
00331        iter != parameterInstancesVPSet.end();
00332        ++iter) {
00333 
00334     const std::vector<std::string> tempMomentumRanges = (*iter).getParameter<std::vector<std::string> >("momentumRanges");
00335     if (tempMomentumRanges.size()==0) {
00336       throw cms::Exception("BadConfig") << "@SUB=MomentumDependentPedeLabeler::buildMomentumDependencyMap\n"
00337                                         << "MomentumRanges empty\n";
00338     }
00339 
00340     MomentumRangeVector MomentumRanges;
00341     float lower;
00342     float upper;
00343     for (unsigned int iMomentum=0;iMomentum<tempMomentumRanges.size();++iMomentum) {
00344       std::vector<std::string> tokens = edm::tokenize(tempMomentumRanges[iMomentum], ":");
00345       
00346       lower = strtod(tokens[0].c_str(), 0);
00347       upper = strtod(tokens[1].c_str(), 0);
00348 
00349       MomentumRanges.push_back(std::pair<float,float>(lower, upper));
00350     }
00351     
00352     const std::vector<std::string> selStrings = (*iter).getParameter<std::vector<std::string> >("selector");
00353     for (std::vector<std::string>::const_iterator iSel = selStrings.begin();
00354          iSel != selStrings.end();
00355          ++iSel) {
00356       std::vector<std::string> decompSel(this->decompose(*iSel, ','));
00357       
00358       if (decompSel.size()!=2) {
00359         throw cms::Exception("BadConfig") << "@SUB=MomentumDependentPedeLabeler::buildMomentumDependencyMap\n"
00360                                           << *iSel <<" should have at least 2 ','-separated parts\n";
00361       }
00362 
00363       std::vector<unsigned int> selParam = this->convertParamSel(decompSel[1]);
00364       selector.clear();
00365       selector.addSelection(decompSel[0], paramSelDumthe);
00366 
00367       const std::vector<Alignable*> &alis = selector.selectedAlignables();
00368       for (std::vector<Alignable*>::const_iterator iAli = alis.begin();
00369            iAli != alis.end();
00370            ++iAli) {
00371         for (std::vector<unsigned int>::const_iterator iParam = selParam.begin();
00372              iParam != selParam.end();
00373              ++iParam) {
00374           AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(*iAli);
00375           if (positionAli!=theAlignableToMomentumRangeMap.end()) {
00376             
00377             AlignmentParameters *AliParams = (*positionAli).first->alignmentParameters();
00378             if (static_cast<int>(selParam[selParam.size()-1]) >= AliParams->size()) {
00379               throw cms::Exception("BadConfig") << "@SUB=MomentumDependentPedeLabeler::buildMomentumDependencyMap\n"
00380                                                 << "mismatch in number of parameters\n";
00381             }
00382             
00383             MomentumRangeParamMap::const_iterator positionParam = (*positionAli).second.find(*iParam);
00384             if (positionParam!=(*positionAli).second.end()) {
00385               throw cms::Exception("BadConfig") << "@SUB=MomentumDependentPedeLabeler::buildMomentumDependencyMap\n"
00386                                                 << "Momentum range for parameter specified twice\n";
00387             }
00388           }
00389           
00390           theAlignableToMomentumRangeMap[*iAli][*iParam] = MomentumRanges;
00391         }
00392       }
00393     }
00394   }
00395   
00396   return theAlignableToMomentumRangeMap.size();
00397 }
00398 
00399 //_________________________________________________________________________
00400 unsigned int MomentumDependentPedeLabeler::buildMap(const std::vector<Alignable*> &alis)
00401 {
00402   theAlignableToIdMap.clear(); // just in case of re-use...
00403 
00404   std::vector<Alignable*> allComps;
00405   
00406   for (std::vector<Alignable*>::const_iterator iAli = alis.begin(); iAli != alis.end(); ++iAli) {
00407     if (*iAli) {
00408       allComps.push_back(*iAli);
00409       (*iAli)->recursiveComponents(allComps);
00410     }
00411   }
00412 
00413   unsigned int id = theMinLabel;
00414   for (std::vector<Alignable*>::const_iterator iter = allComps.begin();
00415        iter != allComps.end(); ++iter) {
00416     theAlignableToIdMap.insert(AlignableToIdPair(*iter, id));
00417     id += theMaxNumParam;
00418   }
00419   
00420   // also care about las beams
00421   theLasBeamToLabelMap.clear(); // just in case of re-use...
00422   // FIXME: Temporarily hard code values stolen from 
00423   // https://twiki.cern.ch/twiki/bin/view/CMS/TkLasTrackBasedInterface#Beam_identifier .
00424   unsigned int beamIds[] = {  0,  10,  20,  30,  40,  50,  60,  70, // TEC+ R4
00425                               1,  11,  21,  31,  41,  51,  61,  71, // TEC+ R6
00426                             100, 110, 120, 130, 140, 150, 160, 170, // TEC- R4
00427                             101, 111, 121, 131, 141, 151, 161, 171, // TEC- R6
00428                             200, 210, 220, 230, 240, 250, 260, 270};// AT
00429 
00430   const size_t nBeams = sizeof(beamIds)/sizeof(beamIds[0]);
00431   for (size_t iBeam = 0; iBeam < nBeams; ++iBeam) {
00432     //edm::LogInfo("Alignment") << "Las beam " << beamIds[iBeam] << " gets label " << id << ".";
00433     theLasBeamToLabelMap[beamIds[iBeam]] = id;
00434     id += theMaxNumParam;
00435   }
00436 
00437   if (id > theParamInstanceOffset) { // 'overflow' per instance
00438     throw cms::Exception("Alignment") << "@SUB=MomentumDependentPedeLabeler::buildMap: " 
00439                                       << "Too many labels per instance (" << id-1 << ") leading to double use, "
00440                                       << "increase PedeLabelerBase::theParamInstanceOffset!\n";
00441   }
00442   // return combined size
00443   return theAlignableToIdMap.size() + theLasBeamToLabelMap.size();
00444 }
00445 
00446 //_________________________________________________________________________
00447 unsigned int MomentumDependentPedeLabeler::buildReverseMap()
00448 {
00449   // alignables
00450   theIdToAlignableMap.clear();  // just in case of re-use...
00451 
00452   for (AlignableToIdMap::iterator it = theAlignableToIdMap.begin();
00453        it != theAlignableToIdMap.end(); ++it) {
00454     const unsigned int key = (*it).second;
00455     Alignable *ali = (*it).first;
00456     const unsigned int nInstances = this->numberOfParameterInstances(ali, -1);
00457     theMaxNumberOfParameterInstances = std::max(nInstances, theMaxNumberOfParameterInstances);
00458     for (unsigned int iInstance=0;iInstance<nInstances;++iInstance) {
00459       theIdToAlignableMap[key+iInstance*theParamInstanceOffset] = ali;
00460     }
00461   }
00462   
00463   // las beams
00464   theLabelToLasBeamMap.clear(); // just in case of re-use...
00465 
00466   for (UintUintMap::const_iterator it = theLasBeamToLabelMap.begin();
00467        it != theLasBeamToLabelMap.end(); ++it) {
00468     theLabelToLasBeamMap[it->second] = it->first; //revert key/value
00469   }
00470 
00471   // return combined size
00472   return theIdToAlignableMap.size() + theLabelToLasBeamMap.size();
00473 }
00474 
00475 #include "Alignment/MillePedeAlignmentAlgorithm/interface/PedeLabelerPluginFactory.h"
00476 DEFINE_EDM_PLUGIN(PedeLabelerPluginFactory, MomentumDependentPedeLabeler, "MomentumDependentPedeLabeler");