CMS 3D CMS Logo

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