CMS 3D CMS Logo

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