CMS 3D CMS Logo

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