CMS 3D CMS Logo

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