/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Alignment/CommonAlignment/src/MisalignmentScenarioBuilder.cc
357 строк
17 KB
Cms Build
Clang-Format
20 май 2019, 13:01
20 май 2019, 13:01
125ebea
Код
Авторство
О чём код?
/// \file /// /// $Date: 2010/11/29 20:41:55 $ /// $Revision: 1.11 $ /// /// $Author: wmtan $ /// \author Frederic Ronga - CERN-PH-CMG #include <string> #include <iostream> #include <sstream> #include <cstdlib> // Framework #include "FWCore/Utilities/interface/Exception.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" // Alignment #include "Alignment/CommonAlignment/interface/MisalignmentScenarioBuilder.h" #include "Alignment/CommonAlignment/interface/Alignable.h" //______________________________________________________________________________ MisalignmentScenarioBuilder::MisalignmentScenarioBuilder(AlignableObjectId::Geometry geometry) : alignableObjectId_(geometry) {} //__________________________________________________________________________________________________ // Call for each alignable the more general version with its appropriate level name. void MisalignmentScenarioBuilder::decodeMovements_(const edm::ParameterSet& pSet, const align::Alignables& alignables) { // first create a map with one align::Alignables per type (=levelName) using AlignablesMap = std::map<std::string, align::Alignables>; AlignablesMap alisMap; for (align::Alignables::const_iterator iA = alignables.begin(); iA != alignables.end(); ++iA) { const std::string& levelName = alignableObjectId_.idToString((*iA)->alignableObjectId()); alisMap[levelName].push_back(*iA); // either first entry of new level or add to an old one } // Now call the more general version for each entry in the map. // // There is a hack to ensure that strip components are called in the same order // as in old version of TrackerScenarioBuilder (TIB,TID,TOB,TEC) while // std::map seems to order alphabetically (TECEndcap,TIBHalfBarrel,TIDEndcap,TOBHalfBarrel). // Order matters due to random sequence. If scenarios are allowed to change // 'numerically', remove this comment and the lines marked with 'HACK'. const AlignablesMap::iterator itTec = alisMap.find("TECEndcap"); // HACK for (AlignablesMap::iterator it = alisMap.begin(); it != alisMap.end(); ++it) { if (it == itTec) continue; // HACK this->decodeMovements_(pSet, it->second, it->first); } if (itTec != alisMap.end()) this->decodeMovements_(pSet, itTec->second, itTec->first); // HACK } //__________________________________________________________________________________________________ // Decode nested parameter sets: this is the tricky part... Recursively called on components void MisalignmentScenarioBuilder::decodeMovements_(const edm::ParameterSet& pSet, const align::Alignables& alignables, const std::string& levelName) { indent_ += " "; // For indented output! // Retrieve parameters for all components at this level std::ostringstream name; name << levelName << "s"; edm::ParameterSet globalParameters = this->getParameterSet_(name.str(), pSet); if (!globalParameters.empty()) { LogDebug("PrintParameters") << indent_ << " *** " << levelName << ": found " << globalParameters.getParameterNames().size() << " global parameters" << std::endl; } // Propagate down parameters from upper level this->propagateParameters_(pSet, name.str(), globalParameters); LogDebug("PrintParameters") << indent_ << " global parameter is now:" << std::endl; this->printParameters_(globalParameters, true); // Loop on alignables int iComponent = 0; // physical numbering starts at 1... for (align::Alignables::const_iterator iter = alignables.begin(); iter != alignables.end(); ++iter) { iComponent++; // Check for special parameters -> merge with global name.str(""); name << levelName << iComponent; edm::ParameterSet localParameters = this->getParameterSet_(levelName, iComponent, pSet); LogDebug("PrintParameters") << indent_ << " ** " << name.str() << ": found " << localParameters.getParameterNames().size() << " local parameters" << std::endl; this->mergeParameters_(localParameters, globalParameters); // Retrieve and apply parameters LogDebug("PrintParameters") << indent_ << " parameters to apply:" << std::endl; this->printParameters_(localParameters, true); if (theModifier.modify((*iter), localParameters)) { theModifierCounter++; LogDebug("PrintParameters") << indent_ << "Movements applied to " << name.str(); } // Apply movements to components std::vector<std::string> parameterSetNames; localParameters.getParameterSetNames(parameterSetNames, true); if ((*iter)->size() > 0 && !parameterSetNames.empty()) // Has components and remaining parameter sets this->decodeMovements_(localParameters, (*iter)->components()); } indent_ = indent_.substr(0, indent_.length() - 1); } //__________________________________________________________________________________________________ // Merge two sets of parameters into one. The local set overrides the global one // A recursive merging is done on parameter sets. void MisalignmentScenarioBuilder::mergeParameters_(edm::ParameterSet& localSet, const edm::ParameterSet& globalSet) const { indent_ += " "; // Loop on globalSet. Add to localSet all non-existing parameters std::vector<std::string> globalParameterNames = globalSet.getParameterNames(); for (std::vector<std::string>::iterator iter = globalParameterNames.begin(); iter != globalParameterNames.end(); iter++) { if (globalSet.existsAs<edm::ParameterSet>(*iter)) { // This is a parameter set: check it edm::ParameterSet subLocalSet = this->getParameterSet_((*iter), localSet); if (subLocalSet.empty()) { // No local subset exists: just insert it localSet.copyFrom(globalSet, (*iter)); } else { // Merge with local subset and replace this->mergeParameters_(subLocalSet, globalSet.getParameter<edm::ParameterSet>(*iter)); localSet.addParameter<edm::ParameterSet>((*iter), subLocalSet); } } else { // If (*iter) exists, (silently...) not replaced: localSet.copyFrom(globalSet, (*iter)); } } indent_ = indent_.substr(0, indent_.length() - 1); } //__________________________________________________________________________________________________ // Propagates some parameters from upper level. // Parameter sets are also propagated down (if name different from global name) or merged down. void MisalignmentScenarioBuilder::propagateParameters_(const edm::ParameterSet& pSet, const std::string& globalName, edm::ParameterSet& subSet) const { indent_ += " "; // For indented output! // Propagate some given parameters std::vector<std::string> parameterNames = pSet.getParameterNames(); for (std::vector<std::string>::iterator iter = parameterNames.begin(); iter != parameterNames.end(); ++iter) { if (theModifier.isPropagated(*iter)) { // like 'distribution', 'scale', etc. LogDebug("PropagateParameters") << indent_ << " - adding parameter " << (*iter) << std::endl; subSet.copyFrom(pSet, (*iter)); // If existing, is not replaced. } } // Propagate all tracked parameter sets std::vector<std::string> pSetNames; if (pSet.getParameterSetNames(pSetNames, true) > 0) { for (std::vector<std::string>::const_iterator it = pSetNames.begin(); it != pSetNames.end(); ++it) { const std::string rootName = this->rootName_(*it); const std::string globalRoot(this->rootName_(globalName)); if (rootName.compare(0, rootName.length(), globalRoot) == 0) { // Parameter for this level: skip LogDebug("PropagateParameters") << indent_ << " - skipping PSet " << (*it) << " from global " << globalName << std::endl; } else if (this->isTopLevel_(*it)) { // Top-level parameters should not be propagated LogDebug("PropagateParameters") << indent_ << " - skipping top-level PSet " << (*it) << " global " << globalName << std::endl; } else if (!this->possiblyPartOf(*it, globalRoot)) { // (*it) is a part of the detector that does not fit to globalName LogDebug("PropagateParameters") << indent_ << " - skipping PSet " << (*it) << " not fitting into global " << globalName << std::endl; } else if (alignableObjectId_.stringToId(rootName) == align::invalid) { // Parameter is not known! throw cms::Exception("BadConfig") << "Unknown parameter set name " << rootName; } else { // Pass down any other: in order to merge PSets, create dummy PSet // only containing this PSet and merge it recursively. LogDebug("PropagateParameters") << indent_ << " - adding PSet " << (*it) << " global " << globalName << std::endl; edm::ParameterSet m_subSet; m_subSet.addParameter<edm::ParameterSet>((*it), pSet.getParameter<edm::ParameterSet>(*it)); this->mergeParameters_(subSet, m_subSet); } } } indent_ = indent_.substr(0, indent_.length() - 1); } //__________________________________________________________________________________________________ // Get parameter set corresponding to given name. // Return empty parameter set if does not exist. edm::ParameterSet MisalignmentScenarioBuilder::getParameterSet_(const std::string& name, const edm::ParameterSet& pSet) const { edm::ParameterSet result; // Get list of parameter set names and retrieve requested one std::vector<std::string> parameterSetNames; if (this->hasParameter_(name, pSet)) { result = pSet.getParameter<edm::ParameterSet>(name); } return result; } //__________________________________________________________________________________________________ // Get parameter set corresponding to given level name and number. // Return empty parameter set if does not exist. edm::ParameterSet MisalignmentScenarioBuilder::getParameterSet_(const std::string& levelName, int iComponent, const edm::ParameterSet& pSet) const { edm::ParameterSet result; unsigned int nFittingPsets = 0; // Get list of parameter set names and look for requested one std::vector<std::string> pNames = pSet.getParameterNames(); for (std::vector<std::string>::iterator iter = pNames.begin(); iter != pNames.end(); ++iter) { if (iter->find(levelName) != 0) continue; // parameter not starting with levelName const std::string numberString(*iter, levelName.size()); // if (numberString.empty() || numberString == "s") { // "s" only left means we have e.g. 'TOBs' if (numberString.empty()) { // check on "s" not needed, see below continue; // nothing left in levelName to be iComponent... } // now look for numbers (separated by '_', tolerating '__' or ending with '_') size_t lastPos = 0; size_t pos = numberString.find_first_of('_', lastPos); while (std::string::npos != pos || std::string::npos != lastPos) { const std::string digit(numberString.substr(lastPos, pos - lastPos)); bool isDigit = !digit.empty(); for (std::string::const_iterator dIt = digit.begin(); dIt != digit.end(); ++dIt) { if (!isdigit(*dIt)) isDigit = false; // check all 'letters' to be a digit } if (!isDigit) { if (lastPos != 0) { // do not throw if e.g. after 'TOB' ('Det') you find only 's' (Unit<n>) throw cms::Exception("BadConfig") << "[MisalignmentScenarioBuilder::getParameterSet_] " << "Expect only numbers, separated by '_' after " << levelName << " in " << *iter << std::endl; } break; } if (atoi(digit.c_str()) == iComponent) { ++nFittingPsets; LogDebug("getParameterSet_") << indent_ << "found " << *iter << " matching " << levelName << iComponent; result = pSet.getParameter<edm::ParameterSet>(*iter); break; } lastPos = numberString.find_first_not_of('_', pos); pos = numberString.find_first_of('_', lastPos); } } // end loop on names of parameters in pSet if (nFittingPsets > 1) { throw cms::Exception("BadConfig") << "[MisalignmentScenarioBuilder::getParameterSet_] " << "Found " << nFittingPsets << " PSet for " << levelName << " " << iComponent << "." << std::endl; } return result; } //__________________________________________________________________________________________________ bool MisalignmentScenarioBuilder::hasParameter_(const std::string& name, const edm::ParameterSet& pSet) const { // Get list of parameter set names and look for requested one std::vector<std::string> names = pSet.getParameterNames(); return (std::find(names.begin(), names.end(), name) != names.end()); } //__________________________________________________________________________________________________ // Print parameter set. If showPsets is 'false', do not print PSets void MisalignmentScenarioBuilder::printParameters_(const edm::ParameterSet& pSet, const bool showPsets) const { std::vector<std::string> parameterNames = pSet.getParameterNames(); for (std::vector<std::string>::iterator iter = parameterNames.begin(); iter != parameterNames.end(); ++iter) { if (showPsets || !pSet.existsAs<edm::ParameterSet>(*iter)) { // LogTrace("PrintParameters") << indent_ << " " << (*iter) << " = " // << pSet.retrieve( *iter ).toString() << std::endl; // From Bill Tannenbaum: // You can use // pset.getParameterAsString(aString). // This function was added with the new tag. // However, there is a possible complication if the parameter in question is // itself a ParameterSet or a vector of ParameterSets. In the new format, a // ParameterSet cannot be converted to a string until its ID is calculated, // which happens when it is registered. So, if you get error messages about // not being able to convert an unregistered ParameterSet to a string, you can // do one of two things: // A) You can use ParameterSet::dump() to print the parameter set, instead of // getParameterAsString(). This does not require registering. I'm not sure of // the exact format of the dump output (Rick wrote this, I think). // OR // B) You can use ParameterSet::registerIt() to register the parameter set // before calling getParameterAsString(). // // In either case, you can use existsAs to determine which parameters are // themselves parameter sets or vectors of parameter sets. // // Note that in the new parameter set format, ParameterSet::toString() does not // write out nested parameter sets by value. It writes them out by // "reference", i.e it writes the ID. } } } //__________________________________________________________________________________________________ bool MisalignmentScenarioBuilder::isTopLevel_(const std::string& parameterSetName) const { // Get root name (strip last character[s]) std::string root = this->rootName_(parameterSetName); // tracker stuff treated in overwriting TrackerScenarioBuilder::isTopLevel_(..) if (root == "DTSector") return true; else if (root == "CSCSector") return true; else if (root == "Muon") return true; return false; } //__________________________________________________________________________________________________ bool MisalignmentScenarioBuilder::possiblyPartOf(const std::string& /*sub*/, const std::string& /*large*/) const { return true; // possibly overwrite in specific class } //__________________________________________________________________________________________________ // Get root name of parameter set (e.g. return 'Rod' from 'Rods' or 'Rod1') const std::string MisalignmentScenarioBuilder::rootName_(const std::string& parameterSetName) const { std::string result{parameterSetName}; // Initialise to full string // Check if string ends with 's' const auto lastChar = parameterSetName.length() - 1; if (parameterSetName[lastChar] == 's') { result = parameterSetName.substr(0, lastChar); } else { // Otherwise, look for numbers at the end // (assumes that numbers at the end are not part of the name) for (auto ichar = lastChar; ichar != 0; --ichar) { if (!isdigit(parameterSetName[ichar])) { result = parameterSetName.substr(0, ichar + 1); break; // Stop at first non-digit } } } LogDebug("PrintParameters") << "Name was " << parameterSetName << ", root is " << result; return result; }