CMS 3D CMS Logo

PedeSteerer.cc
Go to the documentation of this file.
1 
11 #include "PedeSteerer.h"
13 
15 
17 
19 #include <boost/cstdint.hpp>
26 
28 // for 'type identification' as Alignable
32 // GF doubts the need of these includes from include checker campaign:
38 // end of doubt
39 
41 
42 #include <atomic>
43 #include <fstream>
44 #include <sstream>
45 #include <algorithm>
46 
47 // from ROOT
48 #include <TSystem.h>
49 #include <TMath.h>
50 
51 #include <iostream>
52 
53 //_________________________________________________________________________
56  const edm::ParameterSet &config, const std::string &defaultDir,
57  bool noSteerFiles) :
58  myParameterStore(store), myLabels(labels),
59  alignableObjectId_{AlignableObjectId::commonObjectIdProvider(aliTracker, aliMuon)},
62  myNoSteerFiles(noSteerFiles),
63  myIsSteerFileDebug(myConfig.getUntrackedParameter<bool>("steerFileDebug")),
64  myParameterSign(myConfig.getUntrackedParameter<int>("parameterSign")),
65  theMinHieraConstrCoeff(myConfig.getParameter<double>("minHieraConstrCoeff")),
66  theMinHieraParPerConstr(myConfig.getParameter<unsigned int>("minHieraParPerConstr")),
67  theConstrPrecision(myConfig.getParameter<unsigned int>("constrPrecision")),
68  theCoordMaster(nullptr)
69 {
70  if (myParameterSign != 1 && myParameterSign != -1) {
71  cms::Exception("BadConfig") << "Expect PedeSteerer.parameterSign = +/-1, "
72  << "found " << myParameterSign << ".";
73  }
74 
75  // Correct directory, needed before asking for fileName(..):
76  if (myDirectory.empty()) myDirectory = defaultDir;
77  if (!myDirectory.empty() && myDirectory.find_last_of('/') != myDirectory.size() - 1) {
78  myDirectory += '/'; // directory may need '/'
79  }
80 
81  const auto& alis = myParameterStore->alignables();
82  if (!this->checkParameterChoices(alis)) {} // anyway thrown exception
83 
84  // Coordinate system selection and correction before everything
86  if (!theCoordDefiners.empty()) { // Create steering with constraints to define coordinate system:
87  // OK, some hacks:
88  // - we want a composite with global coordinates where tracker and muon are components
89  // (to call RigidBodyAl.Param.->globalParameters() in correctToReferenceSystem(..))
90  // - so we create a AlignableComposite and add tracker and muon
91  // - but the addComponent(..) method is so cute that it calculates position from
92  // daughters' deepComponents()
93  // - so we want to move it back to (0,0,0), but ali->move(..) would move daughters as well
94  // => move only the surface back
95  // - this master object does not have a label for its parameters
96  // => some warnings if debug output selected in pedeSteer files
97  // - we must not delete our new master (little mem. leak...) since that would delete
98  // the daughters as well!
99  if (aliTracker) {
100  theCoordMaster = new AlignableComposite(aliTracker->id(), align::invalid);
101  theCoordMaster->addComponent(aliTracker);
102  } else if (aliMuon) {
103  theCoordMaster = new AlignableComposite(aliMuon->id(), align::invalid);
104  } else {
105  throw cms::Exception("BadConfig")
106  << "[PedeSteerer]" << "Cannot define global coordinate system "
107  << "with neither tracker nor muon!";
108  }
109  if (aliMuon) theCoordMaster->addComponent(aliMuon); // tracker is already added if existing
110  if (aliExtras) { // tracker and/or muon are already added if existing
111  align::Alignables allExtras = aliExtras->components();
112  for (const auto& it: allExtras ) theCoordMaster->addComponent(it);
113  }
114 
116 
117  if (this->isCorrectToRefSystem(theCoordDefiners)) { // defined by 's' (MC): 'correct' misalignment
118  this->correctToReferenceSystem(); // really before 'defineCoordinates'?
119  }
120  }
121 
122 }
123 
124 //___________________________________________________________________________
126 {
127  // delete theCoordMaster; NO, see above
128 }
129 
130 //_________________________________________________________________________
131 bool PedeSteerer::isNoHiera(const Alignable* ali) const
132 {
133  return (myNoHieraCollection.find(ali) != myNoHieraCollection.end());
134 }
135 
136 //_________________________________________________________________________
137 double PedeSteerer::cmsToPedeFactor(unsigned int parNum) const
138 {
139  return 1.; // mmh, otherwise would need to FIXME hierarchyConstraint...
140 
141  switch (parNum) {
144  return 1000.; // cm to mum *1/10 to get smaller values
146  return 2500.; // cm to mum *1/4
149  return 1000.; // rad to mrad (no first guess for sensitivity yet)
151  return 10000.; // rad to mrad *10 to get larger values
152  default:
153  return 1.;
154  }
155 }
156 
157 //_________________________________________________________________________
159 {
160  myNoHieraCollection.clear(); // just in case of re-use...
161 
162  for (const auto& iAli: alis) {
163  AlignmentParameters *params = iAli->alignmentParameters();
164  SelectionUserVariables *selVar = dynamic_cast<SelectionUserVariables*>(params->userVariables());
165  if (!selVar) continue;
166  // Now check whether taking out of hierarchy is selected - must be consistent!
167  unsigned int numNoHieraPar = 0;
168  unsigned int numHieraPar = 0;
169  for (unsigned int iParam = 0; static_cast<int>(iParam) < params->size(); ++iParam) {
170  const char selector = selVar->fullSelection()[iParam];
171  if (selector == 'C' || selector == 'F' || selector == 'H') {
172  ++numNoHieraPar;
173  } else if (selector == 'c' || selector == 'f' || selector == '1' || selector == 'r'
174  || selector == 's') {
175  ++numHieraPar;
176  } // else ... accept '0' as undetermined
177  }
178  if (numNoHieraPar) { // Selected to be taken out.
179  if (numHieraPar) { // Inconsistent: Some parameters still in hierarchy ==> exception!
180  throw cms::Exception("BadConfig")
181  << "[PedeSteerer::buildNoHierarchyCollection] All active parameters of alignables to be "
182  << " taken out of the hierarchy must be marked with capital letters 'C', 'F' or 'H'!";
183  }
184  bool isInHiera = false; // Check whether Alignable is really part of hierarchy:
185  auto mother = iAli;
186  while ((mother = mother->mother())) {
187  if (mother->alignmentParameters()) isInHiera = true; // could 'break;', but loop is short
188  }
189  // Complain, but keep collection short if not in hierarchy:
190  if (isInHiera) myNoHieraCollection.insert(iAli);
191  else edm::LogWarning("Alignment") << "@SUB=PedeSteerer::buildNoHierarchyCollection"
192  << "Alignable not in hierarchy, no need to remove it!";
193  }
194  } // end loop on alignables
195 
196  return myNoHieraCollection.size();
197 }
198 
199 //_________________________________________________________________________
201 {
202  for (const auto& iAli: alis) {
203  AlignmentParameters *paras = iAli->alignmentParameters();
204  SelectionUserVariables *selVar = dynamic_cast<SelectionUserVariables*>(paras->userVariables());
205  if (!selVar) continue;
206  for (unsigned int iParam = 0; static_cast<int>(iParam) < paras->size(); ++iParam) {
207  const char sel = selVar->fullSelection()[iParam];
208  if (sel != 'f' && sel != 'F' && sel != 'c' && sel != 'C' &&
209  sel != '0' && sel != '1' && sel != 'H' && sel != 'r' && sel != 's') {
210  throw cms::Exception("BadConfig")
211  << "[PedeSteerer::unknownParameterChoices] "
212  << "Unexpected parameter selector '" << sel
213  << "', use \n'f/F' (fix),\n'c/C' (fix at correct pos.),\n'1/H' (free),\n"
214  << "'r/s' (free, but defining reference system, trying to correct misalignment if 's')"
215  << " or \n'0' (ignore).\n"
216  << "Capital letters mean that the Alignable is taken out of a possible hierarchy,\n"
217  << "but must be used consistently for all its parameters.";
218  return false; // unreached
219  }
220  }
221  }
222 
223  return true;
224 }
225 
226 //_________________________________________________________________________
227 std::pair<unsigned int, unsigned int>
229 {
230  // return number of parameters fixed at 0. and fixed at original position
231  std::pair<unsigned int, unsigned int> numFixNumFixCor(0, 0);
232 
233  std::ofstream *filePtr = nullptr;
234 
235  for (const auto& iAli: alis) {
236 
237  AlignmentParameters *params = iAli->alignmentParameters();
238  SelectionUserVariables *selVar = dynamic_cast<SelectionUserVariables*>(params->userVariables());
239  if (!selVar) continue;
240 
241  for (unsigned int iParam = 0; static_cast<int>(iParam) < params->size(); ++iParam) {
242  const unsigned int nInstances = myLabels->numberOfParameterInstances(iAli, iParam);
243  for (unsigned int iInstance=0;iInstance<nInstances;++iInstance) {
244  int whichFix = this->fixParameter(iAli, iInstance, iParam,
245  selVar->fullSelection()[iParam], filePtr,
246  fileName);
247  if (whichFix == 1) {
248  ++(numFixNumFixCor.first);
249  } else if (whichFix == -1) {
250  ++(numFixNumFixCor.second);
251  }
252  }
253  }
254  }
255 
256  delete filePtr; // automatically flushes, no problem if NULL ptr.
257 
258  return numFixNumFixCor;
259 }
260 
261 //_________________________________________________________________________
262 int PedeSteerer::fixParameter(Alignable *ali, unsigned int iInstance,
263  unsigned int iParam, char selector,
264  std::ofstream* &filePtr, const std::string &fileName)
265 {
266  int result = 0;
267  float fixAt = 0.;
268  if (selector == 'c' || selector == 'C') {
270  throw cms::Exception("BadConfig")
271  << "PedeSteerer::fixParameter: correction (c/C) possible only for RigidBodyParameters";
272  }
273  fixAt = -this->parameterSign() * RigidBodyAlignmentParameters(ali, true).parameters()[iParam];
274  result = -1;
275  } else if (selector == 'f' || selector == 'F') {
276  result = 1;
277  }
278 
279  if (result) {
280  if (!filePtr) {
281  filePtr = this->createSteerFile(fileName, true);
282  (*filePtr) << "Parameter\n";
283  }
284  std::ofstream &file = *filePtr;
285 
286  const unsigned int aliLabel = myLabels->alignableLabelFromParamAndInstance(ali, iParam, iInstance);
287  file << myLabels->parameterLabel(aliLabel, iParam) << " "
288  << fixAt * this->cmsToPedeFactor(iParam) << " -1.0";
289  if (myIsSteerFileDebug) { // debug
290  const GlobalPoint position(ali->globalPosition());
291  file << " * id " << ali->id() << ", eta " << position.eta() << ", z " << position.z()
292  << ", r " << position.perp() << ", phi " << position.phi();
293  }
294  file << "\n";
295  }
296 
297  return result;
298 }
299 
300 //_________________________________________________________________________
302 {
303  align::Alignables coordAlis;
304 
305  for (const auto& iAli: alis) {
306  AlignmentParameters *params = iAli->alignmentParameters();
307  SelectionUserVariables *selVar = dynamic_cast<SelectionUserVariables*>(params->userVariables());
308  if (!selVar) continue;
309  unsigned int refParam = 0;
310  unsigned int nonRefParam = 0;
311  for (unsigned int iParam = 0; static_cast<int>(iParam) < params->size(); ++iParam) {
312  const char selector = selVar->fullSelection()[iParam];
313  if (selector == 'r' || selector == 's') {
314  ++refParam;
315  } else if (selector != '0' && selector != 'f') { // allow also 'c'?
316  ++nonRefParam;
317  }
318  }
319  // Check whether some 'r/s' selection string. If yes and selection makes sense, add to result:
320  if (refParam) {
321  if (nonRefParam) {
322  throw cms::Exception("BadConfig")
323  << "[PedeSteerer::selectCoordinateAlis] All active parameters of alignables defining "
324  << "the coordinate system must be marked with 'r/s' (or fixed, 'f')!";
325  } else {
326  auto mother = iAli;
327  while ((mother = mother->mother())) {
328  if (mother->alignmentParameters()) {
329  throw cms::Exception("BadConfig") << "[PedeSteerer::selectCoordinateAlis] "
330  << "Alignables defining the coordinate system must "
331  << "be highest level!";
332  }
333  }
334  coordAlis.push_back(iAli);
335  }
336  }
337  } // end loop on alignables
338 
339  return coordAlis;
340 }
341 
342 
343 //_________________________________________________________________________
345  const std::string &fileName)
346 {
347  std::ofstream *filePtr = this->createSteerFile(fileName, true);
348  (*filePtr) << "* Constraints to define coordinate system:\n";
349  if (!aliMaster || aliMaster->alignmentParameters()) {
350  throw cms::Exception("BadConfig")
351  << "[PedeSteerer::defineCoordinates] " << "No master alignable or it has parameters!";
352  }
353  if (myIsSteerFileDebug) { // See constructor comments about hack:
354  edm::LogError("Alignment") << "@SUB=PedeSteerer::defineCoordinates"
355  << "Ignore following LogicErrors from PedeLabeler.";
356  }
357  AlignmentParameters *par = new RigidBodyAlignmentParameters(aliMaster, false);
358  aliMaster->setAlignmentParameters(par); // hierarchyConstraint needs parameters
359  this->hierarchyConstraint(aliMaster, alis, *filePtr);
360  aliMaster->setAlignmentParameters(nullptr); // erase dummy parameters
361 
362  delete filePtr; // automatically flushes, no problem if NULL ptr.
363 }
364 
365 //_________________________________________________________________________
366 bool PedeSteerer::isCorrectToRefSystem(const align::Alignables& coordDefiners) const
367 {
368  bool doCorrect = false;
369  bool doNotCorrect = false;
370  for (const auto& it: coordDefiners) {
371  SelectionUserVariables *selVar =
372  (it->alignmentParameters() ?
373  dynamic_cast<SelectionUserVariables*>(it->alignmentParameters()->userVariables()) : nullptr);
374  if (!selVar) continue; // is an error!?
375 
376  for (unsigned int i = 0; i < selVar->fullSelection().size(); ++i) {
377  if (selVar->fullSelection()[i] == 'r') doNotCorrect = true;
378  else if (selVar->fullSelection()[i] == 's') doCorrect = true;
379  }
380  }
381 
382  if (doCorrect && doNotCorrect) {
383  throw cms::Exception("BadConfig")
384  << "[PedeSteerer::doCorrectToRefSystem]: Parameter selection 's' and 'r' must not coexist!";
385  }
386 
387  return doCorrect;
388 }
389 
390 //_________________________________________________________________________
392 {
393  typedef RigidBodyAlignmentParameters RbPars;
394  if (!theCoordMaster || theCoordDefiners.empty()) return; // nothing was defined
395 
396  align::Alignables definerDets; // or ...DetUnits
397  for (const auto& it: theCoordDefiners) {// find lowest level objects of alignables that define the coordinate system
398  const auto& comp = it->deepComponents();
399  definerDets.insert(definerDets.end(), comp.begin(), comp.end());
400  }
401 
402  for (unsigned int iLoop = 0; ; ++iLoop) { // iterate: shifts and rotations are not independent
403  AlgebraicVector meanPars(RbPars::N_PARAM);
404  for (const auto& it: definerDets) { // sum up mean displacements/misrotations:
405  meanPars += RbPars(it, true).globalParameters();// requires theCoordMaster has global frame
406  }
407  meanPars /= definerDets.size();
408  const align::Scalar squareSum = meanPars.normsq();
409 
410  if (squareSum < 1.e-20) break; // sqrt(1.e-20)=1.e-10: close enough to stop iterating
411  if (iLoop == 0) {
412  edm::LogInfo("Alignment") << "@SUB=PedeSteerer::correctToReferenceSystem"
413  << "Loop " << iLoop << " "
414  << "Mean misalignment of dets of defined coordinate system"
415  << (squareSum < 1.e-20 ? ":" :
416  " (will be iteratively corrected to < 1.e-10):") << meanPars;
417  }
418  if (iLoop >=5) { // 3 iterations should be safe, use 5 for 'more' safety...
419  edm::LogError("Alignment") << "@SUB=PedeSteerer::correctToReferenceSystem"
420  << "No convergence in " << iLoop << " iterations, "
421  << "remaining misalignment: " << meanPars;
422  break;
423  }
424 
425  const GlobalVector globalShift(meanPars[RbPars::dx],meanPars[RbPars::dy],meanPars[RbPars::dz]);
426  theCoordMaster->move(-globalShift); // sign to revert
427  align::EulerAngles globalAngles(3);
428  globalAngles[0] = meanPars[RbPars::dalpha];
429  globalAngles[1] = meanPars[RbPars::dbeta];
430  globalAngles[2] = meanPars[RbPars::dgamma];
431  theCoordMaster->rotateInGlobalFrame(align::toMatrix(-globalAngles)); // sign to revert
432  }
433 
434 }
435 
436 //_________________________________________________________________________
438  const std::string &fileName)
439 {
440  std::ofstream *filePtr = nullptr;
441 
442  unsigned int nConstraints = 0;
443  align::Alignables aliDaughts;
444  for (const auto& iA: alis) {
445  aliDaughts.clear();
446  if (!(iA->firstCompsWithParams(aliDaughts))) {
447  edm::LogWarning("Alignment") << "@SUB=PedeSteerer::hierarchyConstraints"
448  << "Some but not all daughters of "
449  << alignableObjectId_.idToString(iA->alignableObjectId())
450  << " with params!";
451  }
452  // edm::LogInfo("Alignment") << "@SUB=PedeSteerer::hierarchyConstraints"
453  // << aliDaughts.size() << " ali param components";
454  if (aliDaughts.empty()) continue;
455  // edm::LogInfo("Alignment") << "@SUB=PedeSteerer::hierarchyConstraints"
456  // << aliDaughts.size() << " alignable components ("
457  // << iA->size() << " in total) for "
458  // << aliId.alignableTypeName(iA)
459  // << ", layer " << aliId.typeAndLayerFromAlignable(iA).second
460  // << ", position " << (iA)->globalPosition()
461  // << ", r = " << (iA)->globalPosition().perp();
462  if (!filePtr) filePtr = this->createSteerFile(fileName, true);
463  ++nConstraints;
464  this->hierarchyConstraint(iA, aliDaughts, *filePtr);
465  }
466 
467  delete filePtr; // automatically flushes, no problem if NULL ptr.
468 
469  return nConstraints;
470 }
471 //_________________________________________________________________________
474  std::ofstream &file) const
475 {
476  typedef AlignmentParameterStore::ParameterId ParameterId;
477 
478  std::vector<std::vector<ParameterId> > paramIdsVec;
479  std::vector<std::vector<double> > factorsVec;
480  const bool allConstr = false; // true; // make configurable?
481  static std::atomic<bool> allConstrWarning{false};
482  bool expected{false};
483  if (allConstr && allConstrWarning.compare_exchange_strong(expected, true)) {
484  edm::LogWarning("Alignment") << "@SUB=PedeSteerer::hierarchyConstraint"
485  << "changed to use all 6 constraints";
486  }
487  if (!myParameterStore->hierarchyConstraints(ali, components, paramIdsVec, factorsVec, allConstr,
489  edm::LogWarning("Alignment") << "@SUB=PedeSteerer::hierarchyConstraint"
490  << "Problems from store.";
491  }
492 
493  for (unsigned int iConstr = 0; iConstr < paramIdsVec.size(); ++iConstr) {
494  std::ostringstream aConstr;
495 
496  const std::vector<ParameterId> &parIds = paramIdsVec[iConstr];
497  const std::vector<double> &factors = factorsVec[iConstr];
498  unsigned int nParPerConstr = 0; // keep track of used factor/parId pair
499  // parIds.size() == factors.size() granted by myParameterStore->hierarchyConstraints
500  for (unsigned int iParam = 0; iParam < parIds.size(); ++iParam) {
501  Alignable *aliSubComp = parIds[iParam].first;
502  const unsigned int compParNum = parIds[iParam].second;
503  if (this->isNoHiera(aliSubComp)) {
504  if (myIsSteerFileDebug) aConstr << "* Taken out of hierarchy: ";
505  continue;
506  }
507  const unsigned int aliLabel = myLabels->alignableLabel(aliSubComp);
508  const unsigned int paramLabel = myLabels->parameterLabel(aliLabel, compParNum);
509  // FIXME: multiply by cmsToPedeFactor(subcomponent)/cmsToPedeFactor(mother) (or vice a versa?)
510  if (theConstrPrecision > 0)
511  aConstr << paramLabel << " " << std::setprecision(theConstrPrecision) << factors[iParam];
512  else
513  aConstr << paramLabel << " " << factors[iParam];
514  if (myIsSteerFileDebug) { // debug
515  aConstr << " ! for param " << compParNum << " of a "
516  << alignableObjectId_.idToString(aliSubComp->alignableObjectId()) << " at "
517  << aliSubComp->globalPosition() << ", r=" << aliSubComp->globalPosition().perp();
518  }
519  aConstr << "\n";
520  ++nParPerConstr; // OK, we used one.
521  } // end loop on params
522 
523  //
524  if (nParPerConstr && nParPerConstr >= theMinHieraParPerConstr) { // Enough to make sense?
525  if (myIsSteerFileDebug) { //debug
526  file << "\n* Nr. " << iConstr << " of a '"
527  << alignableObjectId_.idToString(ali->alignableObjectId()) << "' (label "
528  << myLabels->alignableLabel(const_cast<Alignable*>(ali)) // ugly cast: FIXME!
529  << "), position " << ali->globalPosition()
530  << ", r = " << ali->globalPosition().perp();
531  }
532  file << "\nConstraint 0.\n" << aConstr.str(); // in future 'Wconstraint'?
533  } else if (nParPerConstr > 0) { // no warning for trivial case...
534  edm::LogWarning("Alignment") << "@SUB=PedeSteerer::hierarchyConstraint"
535  << "Skip constraint on " << nParPerConstr
536  << " parameter(s):\n" << aConstr.str();
537  }
538  } // end loop on constraints
539 }
540 
541 //_________________________________________________________________________
542 unsigned int PedeSteerer::presigmas(const std::vector<edm::ParameterSet> &cffPresi,
543  const std::string &fileName,
544  const align::Alignables& alis,
545  AlignableTracker *aliTracker, AlignableMuon *aliMuon, AlignableExtras *aliExtras)
546 {
547  // We loop on given PSet's, each containing a parameter selection and the presigma value
548  // The resulting presigmas are stored in a map with Alignable* as key.
549  // This map, 'fileName' and 'alis' are passed further to create the steering file.
550 
551  AlignmentParameterSelector selector(aliTracker, aliMuon, aliExtras);
552  AlignablePresigmasMap aliPresiMap; // map to store alis with presigmas of their parameters
553  for (std::vector<edm::ParameterSet>::const_iterator iSet = cffPresi.begin(), iE = cffPresi.end();
554  iSet != iE; ++iSet) { // loop on individual PSets defining ali-params with their presigma
555  selector.clear();
556  selector.addSelections((*iSet).getParameter<edm::ParameterSet>("Selector"));
557  const auto& alis = selector.selectedAlignables();
558  const std::vector<std::vector<char> > &sels = selector.selectedParameters();
559  const float presigma = (*iSet).getParameter<double>("presigma");
560  if (presigma <= 0.) { // given presigma > 0., 0. later used if not (yet) chosen for parameter
561  throw cms::Exception("BadConfig")
562  << "[PedeSteerer::presigmas]: Pre-sigma must be > 0., but is " << presigma << ".";
563  }
564  // now loop on alis of present selection
565  for (unsigned int iAli = 0; iAli < alis.size(); ++iAli) {
566  std::vector<float> &presigmas = aliPresiMap[alis[iAli]]; // existing or empty, so ensure length:
567  if (presigmas.size() < sels[iAli].size()) presigmas.resize(sels[iAli].size(), 0.);
568  for (unsigned int iParam = 0; iParam < sels[iAli].size(); ++iParam) { // loop on parameters
569  if (sels[iAli][iParam] != '0') { // all but '0' means to apply the chosen presigma
570  if (presigmas[iParam] != 0.) { // reset forbidden (would make it order dependent!)
571  throw cms::Exception("BadConfig")
572  << "[PedeSteerer::presigmas]: Try to set pre-sigma " << presigma << ", but already "
573  << "set " << presigmas[iParam] << " (for a "
574  << alignableObjectId_.idToString(alis[iAli]->alignableObjectId()) << ").";
575  }
576  presigmas[iParam] = presigma;
577  } // end if selected for presigma
578  } // end loop on params
579  } // end loop on alignables for given selection and presigma
580  } // end loop on PSets
581 
582  if (aliPresiMap.empty()) return 0;
583  else return this->presigmasFile(fileName, alis, aliPresiMap);
584 }
585 
586 //_________________________________________________________________________
588  const align::Alignables& alis,
589  const AlignablePresigmasMap &aliPresiMap)
590 {
591  // Check if 'alis' are in aliPresiMap,
592  // if yes apply presigma - but NOT if parameter is fixed!
593  std::ofstream *filePtr = nullptr;
594 
595  unsigned int nPresiParam = 0;
596  for (const auto& iAli: alis) {
597  // Any presigma chosen for alignable?
598  AlignablePresigmasMap::const_iterator presigmasIt = aliPresiMap.find(iAli);
599  if (presigmasIt == aliPresiMap.end()) continue; // no presigma chosen for alignable
600 
601  // Why does the following not work? It does with CMSSW_1_3_X on SLC3...
602  // const AlignablePresigmasMap::data_type &presigmas = presigmasIt->second;
603  const std::vector<float> &presigmas = presigmasIt->second; // I want to hide float or double...
604  for (unsigned int iParam = 0; iParam < presigmas.size(); ++iParam) {
605  // Now check whether a presigma value > 0. chosen:
606  if (presigmas[iParam] <= 0.) continue; // must be positive, '<' checked above
607  // Do not apply presigma to inactive or fixed values.
608  if (!(iAli->alignmentParameters()->selector()[iParam])) continue;
609  SelectionUserVariables *selVar
610  = dynamic_cast<SelectionUserVariables*>(iAli->alignmentParameters()->userVariables());
611  const char selChar = (selVar ? selVar->fullSelection()[iParam] : '1');
612  if (selChar == 'f' || selChar == 'F' || selChar == 'c' || selChar == 'C') continue;
613  // Finally create and write steering file:
614  if (!filePtr) {
615  filePtr = this->createSteerFile(fileName, true);
616  (*filePtr) << "* Presigma values for active parameters: \nParameter\n";
617  }
618  const unsigned int aliLabel = myLabels->alignableLabel(iAli);
619  (*filePtr) << myLabels->parameterLabel(aliLabel, iParam) << " 0. "
620  << presigmas[iParam] * fabs(this->cmsToPedeFactor(iParam));
621  if (myIsSteerFileDebug) {
622  (*filePtr) << " ! for a " << alignableObjectId_.idToString((iAli)->alignableObjectId());
623  }
624  (*filePtr) << '\n';
625 
626  ++nPresiParam;
627  } // end loop on parameters for alignables with chosen presigmas
628  } // end loop on alignables
629 
630  delete filePtr; // close properly file
631  return nPresiParam;
632 }
633 
634 //_________________________________________________________________________
635 std::ofstream* PedeSteerer::createSteerFile(const std::string &name, bool addToList)
636 {
637  const std::string realName(myNoSteerFiles ? "/dev/null" : name.c_str());
638 
639  std::ofstream *result = new std::ofstream(realName.c_str(), std::ios::out);
640  if (!result || !result->is_open()) {
641  delete result; // needed before exception in case just open failed
642  throw cms::Exception("FileOpenProblem") << "[PedeSteerer::createSteerFile]"
643  << "Could not open " << realName
644  << " as output file.";
645  } else if (addToList) {
646  mySteeringFiles.push_back(realName); // keep track
647  }
648 
649  return result;
650 }
651 
652 
653 //_________________________________________________________________________
655 {
656 
658  name += myConfig.getParameter<std::string>("steerFile");
659  name += addendum;
660  name += ".txt";
661 
662  return name;
663 }
664 
665 //___________________________________________________________________________
667 {
668  const auto& alis = myParameterStore->alignables();
669 
670  if (theCoordMaster && !theCoordDefiners.empty()) {
671  const std::string nameCoordFile(this->fileName("Coord"));
672  this->defineCoordinates(theCoordDefiners, theCoordMaster, nameCoordFile);
673  edm::LogInfo("Alignment") << "@SUB=PedeSteerer::buildSubSteer"
674  << theCoordDefiners.size() << " highest level objects define the "
675  << "coordinate system, steering file " << nameCoordFile << ".";
676  }
677 
678  const std::string nameFixFile(this->fileName("FixPara"));
679  const std::pair<unsigned int, unsigned int> nFixFixCor(this->fixParameters(alis, nameFixFile));
680  if (nFixFixCor.first != 0 || nFixFixCor.second != 0) {
681  edm::LogInfo("Alignment") << "@SUB=PedeSteerer::buildSubSteer"
682  << nFixFixCor.first << " parameters fixed at 0. and "
683  << nFixFixCor.second << " at 'original' position, "
684  << "steering file " << nameFixFile << ".";
685  }
686 
687  if (this->buildNoHierarchyCollection(alis)) { // before hierarchyConstraints(..)
688  edm::LogInfo("Alignment") << "@SUB=PedeSteerer::buildSubSteer"
689  << myNoHieraCollection.size()<<" alignables taken out of hierarchy.";
690  }
691 
692  const std::string nameHierarchyFile(this->fileName("Hierarchy"));
693  unsigned int nConstraint = this->hierarchyConstraints(alis, nameHierarchyFile);
694  if (nConstraint) {
695  edm::LogInfo("Alignment") << "@SUB=PedeSteerer::buildSubSteer"
696  << "Hierarchy constraints for " << nConstraint << " alignables, "
697  << "steering file " << nameHierarchyFile << ".";
698  }
699 
700  //construct the systematic geometry deformations
701  if(!(myConfig.getParameter<std::vector<edm::ParameterSet> >("constraints")).empty()) {
702  PedeSteererWeakModeConstraints GeometryConstraints(aliTracker,
703  myLabels,
704  myConfig.getParameter<std::vector<edm::ParameterSet> >("constraints"),
705  myConfig.getParameter<std::string>("steerFile"));
706 
707  //prepare the output files
708  //Get the data structure in which the configuration data are stored.
709  //The relation between the ostream* and the corresponding file name needs to be filled
710  auto& ConstraintsConfigContainer = GeometryConstraints.getConfigData();
711 
712  //loop over all configured constraints
713  for(auto& it: ConstraintsConfigContainer) {
714  //each level has its own constraint which means the output is stored in a separate file
715  for(const auto& ilevelsFilename: it.levelsFilenames_) {
716  it.mapFileName_.insert(std::make_pair
717  (ilevelsFilename.second,this->createSteerFile(ilevelsFilename.second,true))
718  );
719  }
720  }
721 
722  unsigned int nGeometryConstraint = GeometryConstraints.constructConstraints(alis);
723  if (nGeometryConstraint) {
724  edm::LogInfo("Alignment") << "@SUB=PedeSteerer::buildSubSteer"
725  << "Geometry constraints for " << nGeometryConstraint << " alignables.";
726  }
727  }
728 
729  const std::string namePresigmaFile(this->fileName("Presigma"));
730  unsigned int nPresigma =
731  this->presigmas(myConfig.getParameter<std::vector<edm::ParameterSet> >("Presigmas"),
732  namePresigmaFile, alis, aliTracker, aliMuon, aliExtras);
733  if (nPresigma) {
734  edm::LogInfo("Alignment") << "@SUB=PedeSteerer::buildSubSteer"
735  << "Presigma values set for " << nPresigma << " parameters, "
736  << "steering file " << namePresigmaFile << ".";
737  }
738 
739  // Delete all SelectionUserVariables now? They will anyway be overwritten by MillePedeVariables...
740 }
741 
742 //_________________________________________________________________________
743 std::string PedeSteerer::buildMasterSteer(const std::vector<std::string> &binaryFiles)
744 {
745  const std::string nameMasterSteer(this->fileName("Master"));
746  std::ofstream *mainSteerPtr = this->createSteerFile(nameMasterSteer, false);
747  if (!mainSteerPtr) return "";
748 
749  // add external steering files, if any
750  std::vector<std::string> addfiles = myConfig.getParameter<std::vector<std::string> >("additionalSteerFiles");
751  mySteeringFiles.insert(mySteeringFiles.end(),
752  addfiles.begin(),
753  addfiles.end());
754 
755  // add steering files to master steering file
756  std::ofstream &mainSteerRef = *mainSteerPtr;
757  for (unsigned int iFile = 0; iFile < mySteeringFiles.size(); ++iFile) {
758  mainSteerRef << mySteeringFiles[iFile] << "\n";
759  }
760 
761  // add binary files to master steering file
762  mainSteerRef << "\nCfiles\n";
763  for (unsigned int iFile = 0; iFile < binaryFiles.size(); ++iFile) {
764  mainSteerRef << binaryFiles[iFile] << "\n";
765  }
766 
767  // add method
768  mainSteerRef << "\nmethod " << myConfig.getParameter<std::string>("method") << "\n";
769 
770  // add further options
771  const std::vector<std::string> opt(myConfig.getParameter<std::vector<std::string> >("options"));
772  mainSteerRef << "\n* Outlier treatment and other options \n";
773  for (unsigned int i = 0; i < opt.size(); ++i) {
774  mainSteerRef << opt[i] << "\n";
775  }
776 
777  delete mainSteerPtr; // close (and flush) again
778 
779  return nameMasterSteer;
780 }
781 
782 //_________________________________________________________________________
783 int PedeSteerer::runPede(const std::string &masterSteer) const
784 {
785  if (masterSteer.empty()) {
786  edm::LogError("Alignment") << "@SUB=PedeSteerer::runPede" << "Empty master steer file, stop";
787  return 0; //false;
788  }
789 
791  (command += " ") += masterSteer;
793  if (!dump.empty()) {
794  command += " > ";
795  (command += myDirectory) += dump;
796  }
797 
798  edm::LogInfo("Alignment") << "@SUB=PedeSteerer::runPede" << "Start running " << command;
799  // FIXME: Recommended interface to system commands?
800  int shellReturn = gSystem->Exec(command.c_str());
801  edm::LogInfo("Alignment") << "@SUB=PedeSteerer::runPede" << "Command returns " << shellReturn;
802 
803  return shellReturn;
804 }
void correctToReferenceSystem()
Definition: PedeSteerer.cc:391
T getParameter(std::string const &) const
align::ID id() const
Return the ID of Alignable, i.e. DetId of &#39;first&#39; component GeomDet(Unit).
Definition: Alignable.h:189
T getUntrackedParameter(std::string const &, T const &) const
const edm::ParameterSet myConfig
Definition: PedeSteerer.h:121
unsigned int constructConstraints(const align::Alignables &)
T perp() const
Definition: PV3DBase.h:72
std::pair< unsigned int, unsigned int > fixParameters(const align::Alignables &, const std::string &file)
Definition: PedeSteerer.cc:228
unsigned int presigmas(const std::vector< edm::ParameterSet > &cffPresi, const std::string &fileName, const align::Alignables &, AlignableTracker *aliTracker, AlignableMuon *aliMuon, AlignableExtras *aliExtras)
interprete content of presigma VPSet &#39;cffPresi&#39; and call presigmasFile
Definition: PedeSteerer.cc:542
double Scalar
Definition: Definitions.h:27
static AlignableObjectId commonObjectIdProvider(const AlignableObjectId &, const AlignableObjectId &)
std::pair< Alignable *, unsigned int > ParameterId
a single alignable parameter of an Alignable
PedeSteerer(AlignableTracker *aliTracker, AlignableMuon *aliMuon, AlignableExtras *aliExtras, AlignmentParameterStore *store, const PedeLabelerBase *labels, const edm::ParameterSet &config, const std::string &defaultDir, bool noSteerFiles)
Definition: PedeSteerer.cc:54
Alignable * theCoordMaster
Alignables deselected for hierarchy constr.
Definition: PedeSteerer.h:133
std::map< const Alignable *, std::vector< float > > AlignablePresigmasMap
Definition: PedeSteerer.h:71
unsigned int presigmasFile(const std::string &fileName, const align::Alignables &, const AlignablePresigmasMap &aliPresisMap)
look for active &#39;alis&#39; in map of presigma values and create steering file
Definition: PedeSteerer.cc:587
unsigned int hierarchyConstraints(const align::Alignables &, const std::string &file)
Definition: PedeSteerer.cc:437
std::string myDirectory
Definition: PedeSteerer.h:122
std::list< GeometryConstraintConfigData > & getConfigData()
virtual void move(const GlobalVector &displacement)=0
Movement with respect to the global reference frame.
Definition: config.py:1
align::Alignables selectCoordinateAlis(const align::Alignables &) const
Definition: PedeSteerer.cc:301
std::set< const Alignable * > myNoHieraCollection
keeps track of created &#39;secondary&#39; steering files
Definition: PedeSteerer.h:132
AlignmentParameters * alignmentParameters() const
Get the AlignmentParameters.
Definition: Alignable.h:61
virtual int type() const =0
tell type (AlignmentParametersFactory::ParametersType - but no circular dependency) ...
unsigned int theMinHieraParPerConstr
min absolute value of coefficients in hierarchy constraints
Definition: PedeSteerer.h:127
int fixParameter(Alignable *ali, unsigned int iRunRange, unsigned int iParam, char selector, std::ofstream *&filePtr, const std::string &fileName)
Definition: PedeSteerer.cc:262
const AlgebraicVector & parameters(void) const
Get alignment parameters.
std::ofstream * createSteerFile(const std::string &name, bool addToList)
create and open file with name, if (addToList) append to mySteeringFiles
Definition: PedeSteerer.cc:635
AlignmentUserVariables * userVariables(void) const
Get pointer to user variables.
void clear()
remove all selected Alignables and geometrical restrictions
virtual void recenterSurface()
Recenter surface object without moving possible components.
Definition: Alignable.cc:372
const std::vector< char > & fullSelection() const
virtual unsigned int numberOfParameterInstances(Alignable *alignable, int param=-1) const =0
returns the number of instances for a given parameter
virtual StructureType alignableObjectId() const =0
Return the alignable type identifier.
void setAlignmentParameters(AlignmentParameters *dap)
Set the AlignmentParameters.
Definition: Alignable.cc:127
bool isCorrectToRefSystem(const align::Alignables &coordDefiners) const
Definition: PedeSteerer.cc:366
bool hierarchyConstraints(const Alignable *aliMaster, const align::Alignables &aliComps, std::vector< std::vector< ParameterId > > &paramIdsVecOut, std::vector< std::vector< double > > &factorsVecOut, bool all, double epsilon) const
const PedeLabelerBase * myLabels
not the owner!
Definition: PedeSteerer.h:118
int runPede(const std::string &masterSteer) const
run pede, masterSteer should be as returned from buildMasterSteer(...)
Definition: PedeSteerer.cc:783
const AlignableObjectId alignableObjectId_
pointer to labeler (not the owner)
Definition: PedeSteerer.h:119
virtual unsigned int parameterLabel(unsigned int aliLabel, unsigned int parNum) const =0
returns the label for a given alignable parameter number combination
virtual void addComponent(Alignable *)=0
virtual unsigned int alignableLabelFromParamAndInstance(Alignable *alignable, unsigned int param, unsigned int instance) const =0
std::string buildMasterSteer(const std::vector< std::string > &binaryFiles)
construct (and return name of) master steering file from config, binaryFiles etc. ...
Definition: PedeSteerer.cc:743
int myParameterSign
whether or not to fill pede steering files with debug info
Definition: PedeSteerer.h:125
const align::Alignables & selectedAlignables() const
vector of alignables selected so far
double theMinHieraConstrCoeff
old pede versions (before May &#39;07) need a sign flip...
Definition: PedeSteerer.h:126
unsigned int theConstrPrecision
hierarchy constraints with less params are ignored
Definition: PedeSteerer.h:128
const AlignmentParameterStore * myParameterStore
Definition: PedeSteerer.h:117
CLHEP::HepVector AlgebraicVector
AlgebraicVector EulerAngles
Definition: Definitions.h:36
bool myNoSteerFiles
directory of all files
Definition: PedeSteerer.h:123
align::Alignables theCoordDefiners
master coordinates, must (?) be global frame
Definition: PedeSteerer.h:134
int size(void) const
Get number of parameters.
const char * idToString(align::StructureType type) const
virtual void rotateInGlobalFrame(const RotationType &rotation)=0
void buildSubSteer(AlignableTracker *aliTracker, AlignableMuon *aliMuon, AlignableExtras *aliExtras)
construct steering files about hierarchy, fixing etc. an keep track of their names ...
Definition: PedeSteerer.cc:666
virtual unsigned int alignableLabel(Alignable *alignable) const =0
void defineCoordinates(const align::Alignables &, Alignable *aliMaster, const std::string &fileName)
Definition: PedeSteerer.cc:344
std::vector< std::string > mySteeringFiles
precision for writing constraints to text file
Definition: PedeSteerer.h:130
double cmsToPedeFactor(unsigned int parNum) const
Definition: PedeSteerer.cc:137
std::string fileName(const std::string &addendum) const
full name with directory and &#39;idenitfier&#39;
Definition: PedeSteerer.cc:654
bool isNoHiera(const Alignable *ali) const
True if &#39;ali&#39; was deselected from hierarchy and any ancestor (e.g. mother) has parameters.
Definition: PedeSteerer.cc:131
std::vector< Alignable * > Alignables
Definition: Utilities.h:32
list command
Definition: mps_check.py:24
bool checkParameterChoices(const align::Alignables &) const
Definition: PedeSteerer.cc:200
bool myIsSteerFileDebug
flag to write steering files to /dev/null
Definition: PedeSteerer.h:124
static int position[264][3]
Definition: ReadPGInfo.cc:509
RotationType toMatrix(const EulerAngles &)
Convert rotation angles about x-, y-, z-axes to matrix.
Definition: Utilities.cc:42
unsigned int addSelections(const edm::ParameterSet &pSet)
const PositionType & globalPosition() const
Return the global position of the object.
Definition: Alignable.h:138
const std::vector< std::vector< char > > & selectedParameters() const
vector of selection &#39;strings&#39; for alignables, parallel to selectedAlignables()
void hierarchyConstraint(const Alignable *ali, const align::Alignables &components, std::ofstream &file) const
Definition: PedeSteerer.cc:472
Constructor of the full muon geometry.
Definition: AlignableMuon.h:37
unsigned int buildNoHierarchyCollection(const align::Alignables &)
Definition: PedeSteerer.cc:158
const align::Alignables & alignables(void) const
get all alignables
int parameterSign() const
results from pede (and start values for pede) might need a sign flip
Definition: PedeSteerer.h:66