CMS 3D CMS Logo

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