CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MisalignmentScenarioBuilder.cc
Go to the documentation of this file.
1 
9 #include <string>
10 #include <iostream>
11 #include <sstream>
12 #include <stdlib.h>
13 
14 // Framework
17 
18 // Alignment
21 
22 //__________________________________________________________________________________________________
23 // Call for each alignable the more general version with its appropriate level name.
25  const std::vector<Alignable*> &alignables)
26 {
27 
28  // first create a map with one std::vector<Alignable*> per type (=levelName)
29  typedef std::map<std::string, std::vector<Alignable*> > AlignablesMap;
30  AlignablesMap alisMap;
31  for (std::vector<Alignable*>::const_iterator iA = alignables.begin(); iA != alignables.end(); ++iA) {
32  const std::string &levelName = theAlignableObjectId.typeToName((*iA)->alignableObjectId());
33  alisMap[levelName].push_back(*iA); // either first entry of new level or add to an old one
34  }
35 
36  // Now call the more general version for each entry in the map.
37  //
38  // There is a hack to ensure that strip components are called in the same order
39  // as in old version of TrackerScenarioBuilder (TIB,TID,TOB,TEC) while
40  // std::map seems to order alphabetically (TECEndcap,TIBHalfBarrel,TIDEndcap,TOBHalfBarrel).
41  // Order matters due to random sequence. If scenarios are allowed to change
42  // 'numerically', remove this comment and the lines marked with 'HACK'.
43  const AlignablesMap::iterator itTec = alisMap.find("TECEndcap"); // HACK
44  for (AlignablesMap::iterator it = alisMap.begin(); it != alisMap.end(); ++it) {
45  if (it == itTec) continue; // HACK
46  this->decodeMovements_(pSet, it->second, it->first);
47  }
48  if (itTec != alisMap.end()) this->decodeMovements_(pSet, itTec->second, itTec->first); // HACK
49 }
50 
51 
52 //__________________________________________________________________________________________________
53 // Decode nested parameter sets: this is the tricky part... Recursively called on components
55  const std::vector<Alignable*> &alignables,
56  const std::string &levelName)
57 {
58 
59  indent_ += " "; // For indented output!
60 
61  // Retrieve parameters for all components at this level
62  std::ostringstream name;
63  name << levelName << "s";
64  edm::ParameterSet globalParameters = this->getParameterSet_( name.str(), pSet );
65  if ( !globalParameters.empty() ) {
66  LogDebug("PrintParameters") << indent_ << " *** " << levelName << ": found "
67  << globalParameters.getParameterNames().size()
68  << " global parameters" << std::endl;
69  }
70 
71  // Propagate down parameters from upper level
72  this->propagateParameters_( pSet, name.str(), globalParameters );
73  LogDebug("PrintParameters") << indent_ << " global parameter is now:" << std::endl;
74  this->printParameters_( globalParameters, true );
75 
76  // Loop on alignables
77  int iComponent = 0; // physical numbering starts at 1...
78  for (std::vector<Alignable*>::const_iterator iter = alignables.begin();
79  iter != alignables.end(); ++iter) {
80  iComponent++;
81 
82  // Check for special parameters -> merge with global
83  name.str("");
84  name << levelName << iComponent;
85 
86  edm::ParameterSet localParameters = this->getParameterSet_( levelName, iComponent, pSet );
87  LogDebug("PrintParameters") << indent_ << " ** " << name.str() << ": found "
88  << localParameters.getParameterNames().size()
89  << " local parameters" << std::endl;
90  this->mergeParameters_( localParameters, globalParameters );
91 
92  // Retrieve and apply parameters
93  LogDebug("PrintParameters") << indent_ << " parameters to apply:" << std::endl;
94  this->printParameters_( localParameters, true );
95  if ( theModifier.modify( (*iter), localParameters ) ) {
97  LogDebug("PrintParameters") << indent_ << "Movements applied to " << name.str();
98  }
99 
100  // Apply movements to components
101  std::vector<std::string> parameterSetNames;
102  localParameters.getParameterSetNames( parameterSetNames, true );
103  if ( (*iter)->size() > 0 && parameterSetNames.size() > 0 )
104  // Has components and remaining parameter sets
105  this->decodeMovements_( localParameters, (*iter)->components() );
106  }
107 
108  indent_ = indent_.substr( 0, indent_.length()-1 );
109 
110 }
111 
112 
113 
114 //__________________________________________________________________________________________________
115 // Merge two sets of parameters into one. The local set overrides the global one
116 // A recursive merging is done on parameter sets.
118  const edm::ParameterSet& globalSet ) const
119 {
120 
121  indent_ += " ";
122 
123  // Loop on globalSet. Add to localSet all non-existing parameters
124  std::vector<std::string> globalParameterNames = globalSet.getParameterNames();
125  for ( std::vector<std::string>::iterator iter = globalParameterNames.begin();
126  iter != globalParameterNames.end(); iter ++ ) {
127 
128  if (globalSet.existsAs<edm::ParameterSet>(*iter)) {
129  // This is a parameter set: check it
130  edm::ParameterSet subLocalSet = this->getParameterSet_( (*iter), localSet );
131  if ( subLocalSet.empty() ) {
132  // No local subset exists: just insert it
133  localSet.copyFrom(globalSet, (*iter));
134  } else {
135  // Merge with local subset and replace
136  this->mergeParameters_( subLocalSet, globalSet.getParameter<edm::ParameterSet>(*iter) );
137  localSet.addParameter<edm::ParameterSet>( (*iter), subLocalSet );
138  }
139  } else {
140  // If (*iter) exists, (silently...) not replaced:
141  localSet.copyFrom(globalSet, (*iter));
142  }
143  }
144 
145  indent_ = indent_.substr( 0, indent_.length()-1 );
146 
147 }
148 
149 
150 //__________________________________________________________________________________________________
151 // Propagates some parameters from upper level.
152 // Parameter sets are also propagated down (if name different from global name) or merged down.
154  const std::string& globalName,
155  edm::ParameterSet& subSet ) const
156 {
157  indent_ += " "; // For indented output!
158 
159  // Propagate some given parameters
160  std::vector<std::string> parameterNames = pSet.getParameterNames();
161  for ( std::vector<std::string>::iterator iter = parameterNames.begin();
162  iter != parameterNames.end(); iter++ ) {
163  if ( theModifier.isPropagated( *iter ) ) { // like 'distribution', 'scale', etc.
164  LogDebug("PropagateParameters") << indent_ << " - adding parameter " << (*iter) << std::endl;
165  subSet.copyFrom(pSet, (*iter)); // If existing, is not replaced.
166  }
167  }
168 
169  // Propagate all tracked parameter sets
170  std::vector<std::string> pSetNames;
171  if ( pSet.getParameterSetNames( pSetNames, true ) > 0 ) {
172  for ( std::vector<std::string>::const_iterator it = pSetNames.begin();
173  it != pSetNames.end(); it++ ) {
174  const std::string rootName = this->rootName_(*it);
175  const std::string globalRoot(this->rootName_(globalName));
176  if (rootName.compare(0, rootName.length(), globalRoot) == 0) {
177  // Parameter for this level: skip
178  LogDebug("PropagateParameters") << indent_ << " - skipping PSet " << (*it) << " from global "
179  << globalName << std::endl;
180  } else if ( this->isTopLevel_(*it) ) {
181  // Top-level parameters should not be propagated
182  LogDebug("PropagateParameters") << indent_
183  << " - skipping top-level PSet " << (*it)
184  << " global " << globalName << std::endl;
185 
186  } else if (!this->possiblyPartOf(*it, globalRoot)) {
187  // (*it) is a part of the detector that does not fit to globalName
188  LogDebug("PropagateParameters") << indent_
189  << " - skipping PSet " << (*it)
190  << " not fitting into global " << globalName << std::endl;
191 
192  } else if ( theAlignableObjectId.nameToType( rootName ) == align::invalid ) {
193  // Parameter is not known!
194  throw cms::Exception("BadConfig") << "Unknown parameter set name " << rootName;
195  } else {
196  // Pass down any other: in order to merge PSets, create dummy PSet
197  // only containing this PSet and merge it recursively.
198  LogDebug("PropagateParameters") << indent_ << " - adding PSet " << (*it)
199  << " global " << globalName << std::endl;
200  edm::ParameterSet m_subSet;
201  m_subSet.addParameter<edm::ParameterSet>( (*it),
202  pSet.getParameter<edm::ParameterSet>(*it) );
203  this->mergeParameters_( subSet, m_subSet );
204  }
205  }
206  }
207 
208  indent_ = indent_.substr( 0, indent_.length()-1 );
209 }
210 
211 
212 //__________________________________________________________________________________________________
213 // Get parameter set corresponding to given name.
214 // Return empty parameter set if does not exist.
216  const edm::ParameterSet& pSet ) const
217 {
218 
220 
221  // Get list of parameter set names and retrieve requested one
222  std::vector<std::string> parameterSetNames;
223  if ( this->hasParameter_( name, pSet ) ) {
224  result = pSet.getParameter<edm::ParameterSet>( name );
225  }
226 
227  return result;
228 }
229 
230 //__________________________________________________________________________________________________
231 // Get parameter set corresponding to given level name and number.
232 // Return empty parameter set if does not exist.
234  const edm::ParameterSet& pSet ) const
235 {
237  unsigned int nFittingPsets = 0;
238 
239  // Get list of parameter set names and look for requested one
240  std::vector<std::string> pNames = pSet.getParameterNames();
241  for (std::vector<std::string>::iterator iter = pNames.begin(); iter != pNames.end(); ++iter) {
242  if (iter->find(levelName) != 0) continue; // parameter not starting with levelName
243 
244  const std::string numberString(*iter, levelName.size());
245  // if (numberString.empty() || numberString == "s") { // "s" only left means we have e.g. 'TOBs'
246  if (numberString.empty()) { // check on "s" not needed, see below
247  continue; // nothing left in levelName to be iComponent...
248  }
249  // now look for numbers (separated by '_', tolerating '__' or ending with '_')
250  size_t lastPos = 0;
251  size_t pos = numberString.find_first_of('_', lastPos);
252  while (std::string::npos != pos || std::string::npos != lastPos) {
253  const std::string digit(numberString.substr(lastPos, pos - lastPos));
254 
255  bool isDigit = !digit.empty();
256  for (std::string::const_iterator dIt = digit.begin(); dIt != digit.end(); ++dIt) {
257  if (!isdigit(*dIt)) isDigit = false; // check all 'letters' to be a digit
258  }
259  if (!isDigit) {
260  if (lastPos != 0) { // do not throw if e.g. after 'TOB' ('Det') you find only 's' (Unit<n>)
261  throw cms::Exception("BadConfig") << "[MisalignmentScenarioBuilder::getParameterSet_] "
262  << "Expect only numbers, separated by '_' after "
263  << levelName << " in " << *iter << std::endl;
264  }
265  break;
266  }
267 
268  if (atoi(digit.c_str()) == iComponent) {
269  ++nFittingPsets;
270  LogDebug("getParameterSet_") << indent_ << "found " << *iter << " matching "
271  << levelName << iComponent;
272  result = pSet.getParameter<edm::ParameterSet>(*iter);
273  break;
274  }
275  lastPos = numberString.find_first_not_of('_', pos);
276  pos = numberString.find_first_of('_', lastPos);
277  }
278  } // end loop on names of parameters in pSet
279 
280  if (nFittingPsets > 1) {
281  throw cms::Exception("BadConfig") << "[MisalignmentScenarioBuilder::getParameterSet_] "
282  << "Found " << nFittingPsets << " PSet for "
283  << levelName << " " << iComponent << "." << std::endl;
284  }
285 
286  return result;
287 }
288 
289 //__________________________________________________________________________________________________
291  const edm::ParameterSet& pSet ) const
292 {
293 
294  // Get list of parameter set names and look for requested one
295  std::vector<std::string> names = pSet.getParameterNames();
296 
297  return ( std::find( names.begin(), names.end(), name ) != names.end() );
298 
299 }
300 
301 
302 //__________________________________________________________________________________________________
303 // Print parameter set. If showPsets is 'false', do not print PSets
305  const bool showPsets ) const
306 {
307 
308  std::vector<std::string> parameterNames = pSet.getParameterNames();
309  for ( std::vector<std::string>::iterator iter = parameterNames.begin();
310  iter != parameterNames.end(); iter++ ) {
311  if (showPsets || !pSet.existsAs<edm::ParameterSet>(*iter)) {
312 // LogTrace("PrintParameters") << indent_ << " " << (*iter) << " = "
313 // << pSet.retrieve( *iter ).toString() << std::endl;
314 // From Bill Tannenbaum:
315 // You can use
316 // pset.getParameterAsString(aString).
317 // This function was added with the new tag.
318 // However, there is a possible complication if the parameter in question is
319 // itself a ParameterSet or a vector of ParameterSets. In the new format, a
320 // ParameterSet cannot be converted to a string until its ID is calculated,
321 // which happens when it is registered. So, if you get error messages about
322 // not being able to convert an unregistered ParameterSet to a string, you can
323 // do one of two things:
324 // A) You can use ParameterSet::dump() to print the parameter set, instead of
325 // getParameterAsString(). This does not require registering. I'm not sure of
326 // the exact format of the dump output (Rick wrote this, I think).
327 // OR
328 // B) You can use ParameterSet::registerIt() to register the parameter set
329 // before calling getParameterAsString().
330 //
331 // In either case, you can use existsAs to determine which parameters are
332 // themselves parameter sets or vectors of parameter sets.
333 //
334 // Note that in the new parameter set format, ParameterSet::toString() does not
335 // write out nested parameter sets by value. It writes them out by
336 // "reference", i.e it writes the ID.
337  }
338  }
339 }
340 
341 
342 //__________________________________________________________________________________________________
343 bool MisalignmentScenarioBuilder::isTopLevel_( const std::string& parameterSetName ) const
344 {
345  // Get root name (strip last character[s])
346  std::string root = this->rootName_( parameterSetName );
347 
348  // tracker stuff treated in overwriting TrackerScenarioBuilder::isTopLevel_(..)
349  if ( root == "DTSector" ) return true;
350  else if ( root == "CSCSector" ) return true;
351  else if ( root == "Muon" ) return true;
352 
353  return false;
354 
355 }
356 
357 //__________________________________________________________________________________________________
358 bool MisalignmentScenarioBuilder::possiblyPartOf(const std::string & /*sub*/, const std::string &/*large*/) const
359 {
360  return true; // possibly overwrite in specific class
361 }
362 
363 
364 //__________________________________________________________________________________________________
365 // Get root name of parameter set (e.g. return 'Rod' from 'Rods' or 'Rod1')
366 const std::string
367 MisalignmentScenarioBuilder::rootName_( const std::string& parameterSetName ) const
368 {
369 
370  std::string result = parameterSetName; // Initialise to full string
371 
372  // Check if string ends with 's'
373  const int lastChar = parameterSetName.length()-1;
374  if ( parameterSetName[lastChar] == 's' ) {
375  result = parameterSetName.substr( 0, lastChar );
376  } else {
377  // Otherwise, look for numbers (assumes names have no numbers inside...)
378  for ( unsigned int ichar = 0; ichar<parameterSetName.length(); ichar++ ) {
379  if ( isdigit(parameterSetName[ichar]) ) {
380  result = parameterSetName.substr( 0, ichar );
381  break; // Stop at first digit
382  }
383  }
384  }
385 
386  LogDebug("PrintParameters") << "Name was " << parameterSetName << ", root is " << result;
387 
388  return result;
389 
390 }
#define LogDebug(id)
T getParameter(std::string const &) const
bool empty() const
Definition: ParameterSet.h:219
virtual bool possiblyPartOf(const std::string &subStruct, const std::string &largeStruct) const
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:187
static const HistoName names[]
const std::string & typeToName(align::StructureType type) const
Convert type to name.
void printParameters_(const edm::ParameterSet &pSet, const bool showPsets=false) const
Print all parameters and values for given set.
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
const std::string rootName_(const std::string &parameterSetName) const
Get root name of a parameter set (e.g. &#39;Rod&#39; in &#39;Rods&#39; or &#39;Rod1&#39;)
void copyFrom(ParameterSet const &from, std::string const &name)
AlignableObjectId theAlignableObjectId
Type to name converter.
void addParameter(std::string const &name, T const &value)
Definition: ParameterSet.h:145
tuple result
Definition: query.py:137
void propagateParameters_(const edm::ParameterSet &pSet, const std::string &globalName, edm::ParameterSet &subSet) const
Propagate global parameters to sub-parameters.
std::vector< std::string > getParameterNames() const
virtual bool isTopLevel_(const std::string &parameterSetName) const
Check if given parameter is for a top-level structure.
const char * levelName(LogLevel)
Definition: fwLog.cc:35
void decodeMovements_(const edm::ParameterSet &pSet, const std::vector< Alignable * > &alignables)
Decode movements defined in given parameter set for given set of alignables.
AlignableModifier theModifier
Helper class for random movements.
std::string indent_
Depth in hierarchy.
bool modify(Alignable *alignable, const edm::ParameterSet &pSet)
Modify given set of alignables according to parameters.
align::StructureType nameToType(const std::string &name) const
Convert name to type.
void mergeParameters_(edm::ParameterSet &localSet, const edm::ParameterSet &globalSet) const
Merge two sets of parameters into one (the first argument)
bool isPropagated(const std::string &parameterName) const
Check if given parameter should be propagated.
int theModifierCounter
Counter for applied modification.
size_t getParameterSetNames(std::vector< std::string > &output, bool trackiness=true) const
bool hasParameter_(const std::string &name, const edm::ParameterSet &pSet) const
Check if given parameter exists in parameter set.
edm::ParameterSet getParameterSet_(const std::string &name, const edm::ParameterSet &pSet) const
string root
initialization
Definition: dbtoconf.py:70