CMS 3D CMS Logo

MisalignmentScenarioBuilder.cc

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #include <string>
00010 #include <iostream>
00011 #include <sstream>
00012 #include <stdlib.h>
00013 
00014 // Framework
00015 #include "FWCore/Utilities/interface/Exception.h"
00016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00017 
00018 // Alignment
00019 #include "Alignment/CommonAlignment/interface/MisalignmentScenarioBuilder.h"
00020 #include "Alignment/CommonAlignment/interface/Alignable.h" 
00021 
00022 
00023 //__________________________________________________________________________________________________
00024 // Gets the level name from the first alignable and hands over to the more general version
00025 void MisalignmentScenarioBuilder::decodeMovements_( const edm::ParameterSet& pSet, 
00026                                                     std::vector<Alignable*> alignables )
00027 {
00028 
00029   // Get name from first element
00030   std::string levelName = theAlignableObjectId.typeToName( alignables.front()->alignableObjectId() );
00031   this->decodeMovements_( pSet, alignables, levelName );
00032 
00033 }
00034 
00035 
00036 //__________________________________________________________________________________________________
00037 // Decode nested parameter sets: this is the tricky part... Recursively called on components
00038 void MisalignmentScenarioBuilder::decodeMovements_( const edm::ParameterSet& pSet, 
00039                                                     std::vector<Alignable*> alignables,
00040                                                     std::string levelName )
00041 {
00042 
00043   indent_ += " "; // For indented output!
00044 
00045   // Retrieve parameters for all components at this level
00046   std::ostringstream name;
00047   name << levelName << "s";
00048   edm::ParameterSet globalParameters = this->getParameterSet_( name.str(), pSet );
00049   if ( !globalParameters.empty() ) {
00050     LogDebug("PrintParameters") << indent_ << " *** " << levelName << ": found "
00051                                 << globalParameters.getParameterNames().size() 
00052                                 << " global parameters" << std::endl;
00053   }
00054   
00055   // Propagate down parameters from upper level
00056   this->propagateParameters_( pSet, name.str(), globalParameters );
00057   LogDebug("PrintParameters") << indent_ << " global parameter is now:" << std::endl;
00058   this->printParameters_( globalParameters, true );
00059 
00060   // Loop on alignables
00061   int iComponent = 0; // physical numbering starts at 1...
00062   for ( std::vector<Alignable*>::iterator iter = alignables.begin();
00063         iter != alignables.end(); ++iter ) {
00064     iComponent++;
00065 
00066     // Check for special parameters -> merge with global
00067     name.str("");
00068     name << levelName << iComponent;
00069     edm::ParameterSet localParameters = this->getParameterSet_( levelName, iComponent, pSet );
00070     LogDebug("PrintParameters") << indent_ << " ** " << name.str() << ": found "
00071                                 << localParameters.getParameterNames().size() 
00072                                 << " local parameters"  << std::endl;
00073     this->mergeParameters_( localParameters, globalParameters );
00074           
00075     // Retrieve and apply parameters
00076     LogDebug("PrintParameters")  << indent_ << " parameters to apply:" << std::endl;
00077     this->printParameters_( localParameters, true );
00078     if ( theModifier.modify( (*iter), localParameters ) ) {
00079       theModifierCounter++;
00080       LogDebug("PrintParameters") << indent_ << "Movements applied to " << name.str();
00081     }
00082 
00083     // Apply movements to components
00084     std::vector<std::string> parameterSetNames;
00085     localParameters.getParameterSetNames( parameterSetNames, true );
00086     if ( (*iter)->size() > 0 && parameterSetNames.size() > 0 )
00087       // Has components and remaining parameter sets
00088       this->decodeMovements_( localParameters, (*iter)->components() );
00089   }
00090 
00091   indent_ = indent_.substr( 0, indent_.length()-1 );
00092 
00093 }
00094 
00095 
00096 
00097 //__________________________________________________________________________________________________
00098 // Merge two sets of parameters into one. The local set overrides the global one
00099 // A recursive merging is done on parameter sets.
00100 void MisalignmentScenarioBuilder::mergeParameters_( edm::ParameterSet& localSet, 
00101                                                     const edm::ParameterSet& globalSet ) const
00102 {
00103 
00104   // Loop on globalSet. Add to localSet all non-existing parameters
00105   std::vector<std::string> globalParameterNames = globalSet.getParameterNames();
00106   for ( std::vector<std::string>::iterator iter = globalParameterNames.begin();
00107         iter != globalParameterNames.end(); iter ++ ) {
00108     if ( globalSet.retrieve( *iter ).typeCode() == 'P' ) {
00109       // This is a parameter set: check it
00110       edm::ParameterSet subLocalSet = this->getParameterSet_( (*iter), localSet );
00111       if ( subLocalSet.empty() ) {
00112         // No local subset exists: just insert it
00113         localSet.insert( false, (*iter), globalSet.retrieve(*iter) );
00114       } else {
00115         // Merge with local subset and replace
00116         this->mergeParameters_( subLocalSet, globalSet.getParameter<edm::ParameterSet>(*iter) );
00117         localSet.addParameter<edm::ParameterSet>( (*iter), subLocalSet );
00118       }
00119     } else {
00120       localSet.insert( false, (*iter), globalSet.retrieve(*iter) );
00121     }
00122   }
00123 
00124 }
00125 
00126 
00127 //__________________________________________________________________________________________________
00128 // Propagates some parameters from upper level.
00129 // Parameter sets are also propagated down (if name different from global name) or merged down.
00130 void MisalignmentScenarioBuilder::propagateParameters_( const edm::ParameterSet& pSet, 
00131                                                         const std::string& globalName,
00132                                                         edm::ParameterSet& subSet ) const
00133 {
00134 
00135   // Propagate some given parameters
00136   std::vector<std::string> parameterNames = pSet.getParameterNames();
00137   for ( std::vector<std::string>::iterator iter = parameterNames.begin();
00138         iter != parameterNames.end(); iter++ ) {
00139     if ( theModifier.isPropagated( *iter ) ) {
00140       LogDebug("PropagateParameters") << indent_ << " - adding parameter " << (*iter) << std::endl;
00141       subSet.insert( false, (*iter), pSet.retrieve(*iter) );
00142     }
00143   }
00144 
00145   // Propagate all tracked parameter sets
00146   std::vector<std::string> pSetNames;
00147   if ( pSet.getParameterSetNames( pSetNames, true ) > 0 ) {
00148     for ( std::vector<std::string>::const_iterator it = pSetNames.begin();
00149           it != pSetNames.end(); it++ ) {
00150       std::string rootName = this->rootName_( *it );
00151       if ( (*it).compare( 0, (*it).length()-1, 
00152                           this->rootName_(globalName) ) == 0 ) {
00153         // Parameter for this level: skip
00154         LogDebug("PropagateParameters") << indent_ << " - skipping PSet " << (*it) << std::endl;
00155       } else if ( this->isTopLevel_(*it) ) {
00156         // Top-level parameters should not be propagated
00157         LogDebug("PropagateParameters") << indent_ 
00158                                         << " - skipping top-level PSet " << (*it) << std::endl;
00159       } else if ( theAlignableObjectId.nameToType( rootName ) == align::invalid ) {
00160         // Parameter is not known!
00161         throw cms::Exception("BadConfig") << "Unknown parameter set name " << rootName;
00162       } else {
00163         // Pass down any other: in order to merge PSets, create dummy PSet
00164         // only containing this PSet and merge it recursively.
00165         LogDebug("PropagateParameters") << indent_ << " - adding PSet " << (*it) << std::endl;
00166         edm::ParameterSet m_subSet;
00167         m_subSet.addParameter<edm::ParameterSet>( (*it), 
00168                                                   pSet.getParameter<edm::ParameterSet>(*it) );
00169         this->mergeParameters_( subSet, m_subSet );
00170       }  
00171     }
00172   }
00173 
00174 }
00175 
00176 
00177 //__________________________________________________________________________________________________
00178 // Get parameter set corresponding to given name.
00179 // Return empty parameter set if does not exist.
00180 edm::ParameterSet MisalignmentScenarioBuilder::getParameterSet_( const std::string& name,
00181                                                                  const edm::ParameterSet& pSet ) const
00182 {
00183 
00184   edm::ParameterSet result;
00185 
00186   // Get list of parameter set names and retrieve requested one
00187   std::vector<std::string> parameterSetNames;
00188   if ( this->hasParameter_( name, pSet ) ) {
00189     result = pSet.getParameter<edm::ParameterSet>( name );
00190   }
00191 
00192   return result;
00193 }
00194 
00195 //__________________________________________________________________________________________________
00196 // Get parameter set corresponding to given level name and number.
00197 // Return empty parameter set if does not exist.
00198 edm::ParameterSet MisalignmentScenarioBuilder::getParameterSet_( const std::string& levelName, int iComponent, 
00199                                                                  const edm::ParameterSet& pSet ) const
00200 {
00201   edm::ParameterSet result;
00202   unsigned int nFittingPsets = 0;
00203 
00204   // Get list of parameter set names and look for requested one
00205   std::vector<std::string> pNames = pSet.getParameterNames();
00206   for (std::vector<std::string>::iterator iter = pNames.begin(); iter != pNames.end(); ++iter) {
00207     if (iter->find(levelName) != 0) continue; // parameter not starting with levelName
00208 
00209     const std::string numberString(*iter, levelName.size());
00210     //    if (numberString.empty() || numberString == "s") { // "s" only left means we have e.g. 'TOBs' 
00211     if (numberString.empty()) { // check on "s" not needed, see below
00212       continue;  // nothing left in levelName to be iComponent...
00213     }
00214     // now look for numbers (separated by '_', tolerating '__' or ending with '_')
00215     unsigned int lastPos = 0;
00216     unsigned int pos     = numberString.find_first_of('_', lastPos);
00217     while (std::string::npos != pos || std::string::npos != lastPos) {
00218       const std::string digit(numberString.substr(lastPos, pos - lastPos));
00219 
00220       bool isDigit = !digit.empty();
00221       for (std::string::const_iterator dIt = digit.begin(); dIt != digit.end(); ++dIt) {
00222         if (!isdigit(*dIt)) isDigit = false; // check all 'letters' to be a digit
00223       }
00224       if (!isDigit) {
00225         if (lastPos != 0) { // do not throw if e.g. after 'TOB' ('Det') you find only 's' (Unit<n>)
00226           throw cms::Exception("BadConfig") << "[MisalignmentScenarioBuilder::getParameterSet_] "
00227                                             << "Expect only numbers, separated by '_' after " 
00228                                             << levelName << " in " << *iter << std::endl;
00229         }
00230         break;
00231       }
00232 
00233       if (atoi(digit.c_str()) == iComponent) {
00234         ++nFittingPsets;
00235         LogDebug("getParameterSet_") << indent_ << "found " << *iter << " matching "
00236                                      << levelName << iComponent;
00237         result = pSet.getParameter<edm::ParameterSet>(*iter);
00238         break;
00239       }
00240       lastPos = numberString.find_first_not_of('_', pos);
00241       pos     = numberString.find_first_of('_', lastPos);
00242     }
00243   } // end loop on names of parameters in pSet
00244   
00245   if (nFittingPsets > 1) {
00246     throw cms::Exception("BadConfig") << "[MisalignmentScenarioBuilder::getParameterSet_] "
00247                                       << "Found " << nFittingPsets << " PSet for " 
00248                                       << levelName << " " << iComponent << "." << std::endl;
00249   }
00250 
00251   return result;
00252 }
00253 
00254 //__________________________________________________________________________________________________
00255 bool MisalignmentScenarioBuilder::hasParameter_( const std::string& name,
00256                                                  const edm::ParameterSet& pSet ) const
00257 {
00258 
00259   // Get list of parameter set names and look for requested one
00260   std::vector<std::string> names = pSet.getParameterNames();
00261   return ( std::find( names.begin(), names.end(), name ) != names.end() );
00262 
00263 }
00264 
00265 
00266 //__________________________________________________________________________________________________
00267 // Print parameter set. If showPsets is 'false', do not print PSets
00268 void MisalignmentScenarioBuilder::printParameters_( const edm::ParameterSet& pSet, 
00269                                                     const bool showPsets ) const
00270 {
00271 
00272   std::vector<std::string> parameterNames = pSet.getParameterNames();
00273   for ( std::vector<std::string>::iterator iter = parameterNames.begin();
00274         iter != parameterNames.end(); iter++ ) {
00275     if ( pSet.retrieve( *iter ).typeCode() != 'P' || showPsets ) {
00276       LogTrace("PrintParameters") << indent_ << "   " << (*iter) << " = " 
00277                                   << pSet.retrieve( *iter ).toString() << std::endl;
00278     }
00279   }
00280 }
00281 
00282 
00283 //__________________________________________________________________________________________________
00284 const bool MisalignmentScenarioBuilder::isTopLevel_( const std::string& parameterSetName ) const
00285 {
00286 
00287   // Get root name (strip last character)
00288   std::string root = this->rootName_( parameterSetName );
00289   if      ( root == "TOB" ) return true;
00290   else if ( root == "TIB" ) return true;
00291   else if ( root == "TPB" ) return true;
00292   else if ( root == "TEC" ) return true;
00293   else if ( root == "TID" ) return true;
00294   else if ( root == "TPE" ) return true;
00295   else if ( root == "DTSector" ) return true;
00296   else if ( root == "CSCSector" ) return true;
00297   else if ( root == "Muon" ) return true;
00298 
00299   return false;
00300 
00301 }
00302 
00303 //__________________________________________________________________________________________________
00304 // Get root name of parameter set (e.g. return 'Rod' from 'Rods' or 'Rod1')
00305 const std::string 
00306 MisalignmentScenarioBuilder::rootName_( const std::string& parameterSetName ) const
00307 {
00308 
00309   std::string result = parameterSetName; // Initialise to full string
00310   
00311   // Check if string ends with 's'
00312   const int lastChar = parameterSetName.length()-1;
00313   if ( parameterSetName[lastChar] == 's' ) {
00314     result =  parameterSetName.substr( 0, lastChar );
00315   } else {
00316     // Otherwise, look for numbers (assumes names have no numbers inside...)
00317     for ( unsigned int ichar = 0; ichar<parameterSetName.length(); ichar++ ) {
00318       if ( isdigit(parameterSetName[ichar]) ) {
00319         result = parameterSetName.substr( 0, ichar );
00320         break; // Stop at first digit
00321       }
00322     }
00323   }
00324 
00325   LogDebug("PrintParameters") << "Name was " << parameterSetName << ", root is " << result;
00326 
00327   return result;
00328 
00329 }

Generated on Tue Jun 9 17:23:45 2009 for CMSSW by  doxygen 1.5.4