/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Alignment/MillePedeAlignmentAlgorithm/src/PedeSteerer.cc
881 строка
40 KB
Shahzad Malik Muzaffar
[ALCA-DB] Drop Geometry/CommonDetUnit package
28 май 2026, 12:57
28 май 2026, 12:57
993d9d5
Код
Авторство
О чём код?
/** * \file PedeSteerer.cc * * \author : Gero Flucke * date : October 2006 * $Revision: 1.42 $ * $Date: 2013/06/18 15:47:55 $ * (last update by $Author: jbehr $) */ #include "PedeSteerer.h" #include "PedeSteererWeakModeConstraints.h" #include "Alignment/MillePedeAlignmentAlgorithm/interface/PedeLabelerBase.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "Alignment/CommonAlignment/interface/Alignable.h" #include "Alignment/CommonAlignment/interface/Utilities.h" #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterStore.h" #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterSelector.h" #include "Alignment/CommonAlignmentAlgorithm/interface/SelectionUserVariables.h" #include "Alignment/CommonAlignmentParametrization/interface/AlignmentParametersFactory.h" #include "Alignment/CommonAlignmentParametrization/interface/RigidBodyAlignmentParameters.h" #include "Alignment/TrackerAlignment/interface/TrackerAlignableId.h" // for 'type identification' as Alignable #include "Alignment/TrackerAlignment/interface/AlignableTracker.h" #include "Alignment/MuonAlignment/interface/AlignableMuon.h" #include "Alignment/CommonAlignment/interface/AlignableExtras.h" // GF doubts the need of these includes from include checker campaign: #include <FWCore/Framework/interface/EventSetup.h> #include <Geometry/CommonTopologies/interface/GeomDet.h> #include <Geometry/CommonTopologies/interface/GeomDetType.h> #include <DataFormats/GeometrySurface/interface/LocalError.h> #include <Geometry/DTGeometry/interface/DTLayer.h> // end of doubt #include "DataFormats/GeometryVector/interface/GlobalPoint.h" #include <atomic> #include <fstream> #include <sstream> #include <algorithm> // from ROOT #include <TSystem.h> #include <TMath.h> #include <iostream> //_________________________________________________________________________ PedeSteerer::PedeSteerer(AlignableTracker *aliTracker, AlignableMuon *aliMuon, AlignableExtras *aliExtras, AlignmentParameterStore *store, const PedeLabelerBase *labels, const edm::ParameterSet &config, const std::string &defaultDir, bool noSteerFiles) : myParameterStore(store), myLabels(labels), alignableObjectId_{AlignableObjectId::commonObjectIdProvider(aliTracker, aliMuon)}, myConfig(config), myDirectory(myConfig.getUntrackedParameter<std::string>("fileDir")), myRunDirectory(myConfig.getUntrackedParameter<std::string>("runDir")), myNoSteerFiles(noSteerFiles), myIsSteerFileDebug(myConfig.getUntrackedParameter<bool>("steerFileDebug")), myParameterSign(myConfig.getUntrackedParameter<int>("parameterSign")), theMinHieraConstrCoeff(myConfig.getParameter<double>("minHieraConstrCoeff")), theMinHieraParPerConstr(myConfig.getParameter<unsigned int>("minHieraParPerConstr")), theConstrPrecision(myConfig.getParameter<unsigned int>("constrPrecision")), theCoordMaster(nullptr) { if (myParameterSign != 1 && myParameterSign != -1) { cms::Exception("BadConfig") << "Expect PedeSteerer.parameterSign = +/-1, " << "found " << myParameterSign << "."; } // Correct directory, needed before asking for fileName(..): if (myDirectory.empty()) myDirectory = defaultDir; if (!myDirectory.empty() && myDirectory.find_last_of('/') != myDirectory.size() - 1) { myDirectory += '/'; // directory may need '/' } if (myRunDirectory.empty()) myRunDirectory = defaultDir; if (!myRunDirectory.empty() && myRunDirectory.find_last_of('/') != myRunDirectory.size() - 1) { myRunDirectory += '/'; // directory may need '/' myDirectory = myRunDirectory; } const auto &alis = myParameterStore->alignables(); if (!this->checkParameterChoices(alis)) { } // anyway thrown exception // Coordinate system selection and correction before everything theCoordDefiners = this->selectCoordinateAlis(alis); if (!theCoordDefiners.empty()) { // Create steering with constraints to define coordinate system: // OK, some hacks: // - we want a composite with global coordinates where tracker and muon are components // (to call RigidBodyAl.Param.->globalParameters() in correctToReferenceSystem(..)) // - so we create a AlignableComposite and add tracker and muon // - but the addComponent(..) method is so cute that it calculates position from // daughters' deepComponents() // - so we want to move it back to (0,0,0), but ali->move(..) would move daughters as well // => move only the surface back // - this master object does not have a label for its parameters // => some warnings if debug output selected in pedeSteer files // - we must not delete our new master (little mem. leak...) since that would delete // the daughters as well! if (aliTracker) { theCoordMaster = new AlignableComposite(aliTracker->id(), align::invalid); theCoordMaster->addComponent(aliTracker); } else if (aliMuon) { theCoordMaster = new AlignableComposite(aliMuon->id(), align::invalid); } else { throw cms::Exception("BadConfig") << "[PedeSteerer]" << "Cannot define global coordinate system " << "with neither tracker nor muon!"; } if (aliMuon) theCoordMaster->addComponent(aliMuon); // tracker is already added if existing if (aliExtras) { // tracker and/or muon are already added if existing align::Alignables allExtras = aliExtras->components(); for (const auto &it : allExtras) theCoordMaster->addComponent(it); } theCoordMaster->recenterSurface(); if (this->isCorrectToRefSystem(theCoordDefiners)) { // defined by 's' (MC): 'correct' misalignment this->correctToReferenceSystem(); // really before 'defineCoordinates'? } } } //___________________________________________________________________________ PedeSteerer::~PedeSteerer() { // delete theCoordMaster; NO, see above } //_________________________________________________________________________ bool PedeSteerer::isNoHiera(const Alignable *ali) const { return (myNoHieraCollection.find(ali) != myNoHieraCollection.end()); } //_________________________________________________________________________ double PedeSteerer::cmsToPedeFactor(unsigned int parNum) const { return 1.; // mmh, otherwise would need to FIXME hierarchyConstraint... switch (parNum) { case RigidBodyAlignmentParameters::dx: case RigidBodyAlignmentParameters::dy: return 1000.; // cm to mum *1/10 to get smaller values case RigidBodyAlignmentParameters::dz: return 2500.; // cm to mum *1/4 case RigidBodyAlignmentParameters::dalpha: case RigidBodyAlignmentParameters::dbeta: return 1000.; // rad to mrad (no first guess for sensitivity yet) case RigidBodyAlignmentParameters::dgamma: return 10000.; // rad to mrad *10 to get larger values default: return 1.; } } //_________________________________________________________________________ unsigned int PedeSteerer::buildNoHierarchyCollection(const align::Alignables &alis) { myNoHieraCollection.clear(); // just in case of re-use... for (const auto &iAli : alis) { AlignmentParameters *params = iAli->alignmentParameters(); SelectionUserVariables *selVar = dynamic_cast<SelectionUserVariables *>(params->userVariables()); if (!selVar) continue; // Now check whether taking out of hierarchy is selected - must be consistent! unsigned int numNoHieraPar = 0; unsigned int numHieraPar = 0; for (unsigned int iParam = 0; static_cast<int>(iParam) < params->size(); ++iParam) { const char selector = selVar->fullSelection()[iParam]; if (selector == 'C' || selector == 'F' || selector == 'H') { ++numNoHieraPar; } else if (selector == 'c' || selector == 'f' || selector == '1' || selector == 'r' || selector == 's') { ++numHieraPar; } // else ... accept '0' as undetermined } if (numNoHieraPar) { // Selected to be taken out. if (numHieraPar) { // Inconsistent: Some parameters still in hierarchy ==> exception! throw cms::Exception("BadConfig") << "[PedeSteerer::buildNoHierarchyCollection] All active parameters of alignables to be " << " taken out of the hierarchy must be marked with capital letters 'C', 'F' or 'H'!"; } bool isInHiera = false; // Check whether Alignable is really part of hierarchy: auto mother = iAli; while ((mother = mother->mother())) { if (mother->alignmentParameters()) isInHiera = true; // could 'break;', but loop is short } // Complain, but keep collection short if not in hierarchy: if (isInHiera) myNoHieraCollection.insert(iAli); else edm::LogWarning("Alignment") << "@SUB=PedeSteerer::buildNoHierarchyCollection" << "Alignable not in hierarchy, no need to remove it!"; } } // end loop on alignables return myNoHieraCollection.size(); } //_________________________________________________________________________ bool PedeSteerer::checkParameterChoices(const align::Alignables &alis) const { for (const auto &iAli : alis) { AlignmentParameters *paras = iAli->alignmentParameters(); SelectionUserVariables *selVar = dynamic_cast<SelectionUserVariables *>(paras->userVariables()); if (!selVar) continue; for (unsigned int iParam = 0; static_cast<int>(iParam) < paras->size(); ++iParam) { const char sel = selVar->fullSelection()[iParam]; if (sel != 'f' && sel != 'F' && sel != 'c' && sel != 'C' && sel != '0' && sel != '1' && sel != 'H' && sel != 'r' && sel != 's') { throw cms::Exception("BadConfig") << "[PedeSteerer::unknownParameterChoices] " << "Unexpected parameter selector '" << sel << "', use \n'f/F' (fix),\n'c/C' (fix at correct pos.),\n'1/H' (free),\n" << "'r/s' (free, but defining reference system, trying to correct misalignment if 's')" << " or \n'0' (ignore).\n" << "Capital letters mean that the Alignable is taken out of a possible hierarchy,\n" << "but must be used consistently for all its parameters."; return false; // unreached } } } return true; } //_________________________________________________________________________ std::pair<unsigned int, unsigned int> PedeSteerer::fixParameters(const align::Alignables &alis, const std::string &fileName) { // return number of parameters fixed at 0. and fixed at original position std::pair<unsigned int, unsigned int> numFixNumFixCor(0, 0); std::ofstream *filePtr = nullptr; for (const auto &iAli : alis) { AlignmentParameters *params = iAli->alignmentParameters(); SelectionUserVariables *selVar = dynamic_cast<SelectionUserVariables *>(params->userVariables()); if (!selVar) continue; for (unsigned int iParam = 0; static_cast<int>(iParam) < params->size(); ++iParam) { const unsigned int nInstances = myLabels->numberOfParameterInstances(iAli, iParam); for (unsigned int iInstance = 0; iInstance < nInstances; ++iInstance) { int whichFix = this->fixParameter(iAli, iInstance, iParam, selVar->fullSelection()[iParam], filePtr, fileName); if (whichFix == 1) { ++(numFixNumFixCor.first); } else if (whichFix == -1) { ++(numFixNumFixCor.second); } } } } delete filePtr; // automatically flushes, no problem if NULL ptr. return numFixNumFixCor; } //_________________________________________________________________________ int PedeSteerer::fixParameter(Alignable *ali, unsigned int iInstance, unsigned int iParam, char selector, std::ofstream *&filePtr, const std::string &fileName) { int result = 0; float fixAt = 0.; if (selector == 'c' || selector == 'C') { if (ali->alignmentParameters()->type() != AlignmentParametersFactory::kRigidBody) { throw cms::Exception("BadConfig") << "PedeSteerer::fixParameter: correction (c/C) possible only for RigidBodyParameters"; } fixAt = -this->parameterSign() * RigidBodyAlignmentParameters(ali, true).parameters()[iParam]; result = -1; } else if (selector == 'f' || selector == 'F') { result = 1; } if (result) { if (!filePtr) { filePtr = this->createSteerFile(fileName, true); (*filePtr) << "Parameter\n"; } std::ofstream &file = *filePtr; const unsigned int aliLabel = myLabels->alignableLabelFromParamAndInstance(ali, iParam, iInstance); file << myLabels->parameterLabel(aliLabel, iParam) << " " << fixAt * this->cmsToPedeFactor(iParam) << " -1.0"; if (myIsSteerFileDebug) { // debug const GlobalPoint position(ali->globalPosition()); file << " * id " << ali->id() << ", eta " << position.eta() << ", z " << position.z() << ", r " << position.perp() << ", phi " << position.phi(); } file << "\n"; } return result; } //_________________________________________________________________________ align::Alignables PedeSteerer::selectCoordinateAlis(const align::Alignables &alis) const { align::Alignables coordAlis; for (const auto &iAli : alis) { AlignmentParameters *params = iAli->alignmentParameters(); SelectionUserVariables *selVar = dynamic_cast<SelectionUserVariables *>(params->userVariables()); if (!selVar) continue; unsigned int refParam = 0; unsigned int nonRefParam = 0; for (unsigned int iParam = 0; static_cast<int>(iParam) < params->size(); ++iParam) { const char selector = selVar->fullSelection()[iParam]; if (selector == 'r' || selector == 's') { ++refParam; } else if (selector != '0' && selector != 'f') { // allow also 'c'? ++nonRefParam; } } // Check whether some 'r/s' selection string. If yes and selection makes sense, add to result: if (refParam) { if (nonRefParam) { throw cms::Exception("BadConfig") << "[PedeSteerer::selectCoordinateAlis] All active parameters of alignables defining " << "the coordinate system must be marked with 'r/s' (or fixed, 'f')!"; } else { auto mother = iAli; while ((mother = mother->mother())) { if (mother->alignmentParameters()) { throw cms::Exception("BadConfig") << "[PedeSteerer::selectCoordinateAlis] " << "Alignables defining the coordinate system must " << "be highest level!"; } } coordAlis.push_back(iAli); } } } // end loop on alignables return coordAlis; } //_________________________________________________________________________ void PedeSteerer::defineCoordinates(const align::Alignables &alis, Alignable *aliMaster, const std::string &fileName) { std::ofstream *filePtr = this->createSteerFile(fileName, true); (*filePtr) << "* Constraints to define coordinate system:\n"; if (!aliMaster || aliMaster->alignmentParameters()) { throw cms::Exception("BadConfig") << "[PedeSteerer::defineCoordinates] " << "No master alignable or it has parameters!"; } if (myIsSteerFileDebug) { // See constructor comments about hack: edm::LogError("Alignment") << "@SUB=PedeSteerer::defineCoordinates" << "Ignore following LogicErrors from PedeLabeler."; } AlignmentParameters *par = new RigidBodyAlignmentParameters(aliMaster, false); aliMaster->setAlignmentParameters(par); // hierarchyConstraint needs parameters this->hierarchyConstraint(aliMaster, alis, *filePtr); aliMaster->setAlignmentParameters(nullptr); // erase dummy parameters delete filePtr; // automatically flushes, no problem if NULL ptr. } //_________________________________________________________________________ bool PedeSteerer::isCorrectToRefSystem(const align::Alignables &coordDefiners) const { bool doCorrect = false; bool doNotCorrect = false; for (const auto &it : coordDefiners) { SelectionUserVariables *selVar = (it->alignmentParameters() ? dynamic_cast<SelectionUserVariables *>(it->alignmentParameters()->userVariables()) : nullptr); if (!selVar) continue; // is an error!? for (unsigned int i = 0; i < selVar->fullSelection().size(); ++i) { if (selVar->fullSelection()[i] == 'r') doNotCorrect = true; else if (selVar->fullSelection()[i] == 's') doCorrect = true; } } if (doCorrect && doNotCorrect) { throw cms::Exception("BadConfig") << "[PedeSteerer::doCorrectToRefSystem]: Parameter selection 's' and 'r' must not coexist!"; } return doCorrect; } //_________________________________________________________________________ void PedeSteerer::correctToReferenceSystem() { typedef RigidBodyAlignmentParameters RbPars; if (!theCoordMaster || theCoordDefiners.empty()) return; // nothing was defined align::Alignables definerDets; // or ...DetUnits for (const auto &it : theCoordDefiners) { // find lowest level objects of alignables that define the coordinate system const auto &comp = it->deepComponents(); definerDets.insert(definerDets.end(), comp.begin(), comp.end()); } for (unsigned int iLoop = 0;; ++iLoop) { // iterate: shifts and rotations are not independent AlgebraicVector meanPars(RbPars::N_PARAM); for (const auto &it : definerDets) { // sum up mean displacements/misrotations: meanPars += RbPars(it, true).globalParameters(); // requires theCoordMaster has global frame } meanPars /= definerDets.size(); const align::Scalar squareSum = meanPars.normsq(); if (squareSum < 1.e-20) break; // sqrt(1.e-20)=1.e-10: close enough to stop iterating if (iLoop == 0) { edm::LogInfo("Alignment") << "@SUB=PedeSteerer::correctToReferenceSystem" << "Loop " << iLoop << " " << "Mean misalignment of dets of defined coordinate system" << (squareSum < 1.e-20 ? ":" : " (will be iteratively corrected to < 1.e-10):") << meanPars; } if (iLoop >= 5) { // 3 iterations should be safe, use 5 for 'more' safety... edm::LogError("Alignment") << "@SUB=PedeSteerer::correctToReferenceSystem" << "No convergence in " << iLoop << " iterations, " << "remaining misalignment: " << meanPars; break; } const GlobalVector globalShift(meanPars[RbPars::dx], meanPars[RbPars::dy], meanPars[RbPars::dz]); theCoordMaster->move(-globalShift); // sign to revert align::EulerAngles globalAngles(3); globalAngles[0] = meanPars[RbPars::dalpha]; globalAngles[1] = meanPars[RbPars::dbeta]; globalAngles[2] = meanPars[RbPars::dgamma]; theCoordMaster->rotateInGlobalFrame(align::toMatrix(-globalAngles)); // sign to revert } } //_________________________________________________________________________ unsigned int PedeSteerer::hierarchyConstraints(const align::Alignables &alis, const std::string &fileName) { std::ofstream *filePtr = nullptr; unsigned int nConstraints = 0; align::Alignables aliDaughts; for (const auto &iA : alis) { aliDaughts.clear(); if (!(iA->firstCompsWithParams(aliDaughts))) { edm::LogWarning("Alignment") << "@SUB=PedeSteerer::hierarchyConstraints" << "Some but not all daughters of " << alignableObjectId_.idToString(iA->alignableObjectId()) << " with params!"; } // edm::LogInfo("Alignment") << "@SUB=PedeSteerer::hierarchyConstraints" // << aliDaughts.size() << " ali param components"; if (aliDaughts.empty()) continue; // edm::LogInfo("Alignment") << "@SUB=PedeSteerer::hierarchyConstraints" // << aliDaughts.size() << " alignable components (" // << iA->size() << " in total) for " // << aliId.alignableTypeName(iA) // << ", layer " << aliId.typeAndLayerFromAlignable(iA).second // << ", position " << (iA)->globalPosition() // << ", r = " << (iA)->globalPosition().perp(); if (!filePtr) filePtr = this->createSteerFile(fileName, true); ++nConstraints; this->hierarchyConstraint(iA, aliDaughts, *filePtr); } delete filePtr; // automatically flushes, no problem if NULL ptr. return nConstraints; } //_________________________________________________________________________ void PedeSteerer::hierarchyConstraint(const Alignable *ali, const align::Alignables &components, std::ofstream &file) const { typedef AlignmentParameterStore::ParameterId ParameterId; std::vector<std::vector<ParameterId> > paramIdsVec; std::vector<std::vector<double> > factorsVec; const bool allConstr = false; // true; // make configurable? static std::atomic<bool> allConstrWarning{false}; bool expected{false}; if (allConstr && allConstrWarning.compare_exchange_strong(expected, true)) { edm::LogWarning("Alignment") << "@SUB=PedeSteerer::hierarchyConstraint" << "changed to use all 6 constraints"; } if (!myParameterStore->hierarchyConstraints( ali, components, paramIdsVec, factorsVec, allConstr, theMinHieraConstrCoeff)) { edm::LogWarning("Alignment") << "@SUB=PedeSteerer::hierarchyConstraint" << "Problems from store."; } for (unsigned int iConstr = 0; iConstr < paramIdsVec.size(); ++iConstr) { std::ostringstream aConstr; const std::vector<ParameterId> &parIds = paramIdsVec[iConstr]; const std::vector<double> &factors = factorsVec[iConstr]; unsigned int nParPerConstr = 0; // keep track of used factor/parId pair // parIds.size() == factors.size() granted by myParameterStore->hierarchyConstraints for (unsigned int iParam = 0; iParam < parIds.size(); ++iParam) { Alignable *aliSubComp = parIds[iParam].first; const unsigned int compParNum = parIds[iParam].second; if (this->isNoHiera(aliSubComp)) { if (myIsSteerFileDebug) aConstr << "* Taken out of hierarchy: "; continue; } const unsigned int aliLabel = myLabels->alignableLabel(aliSubComp); const unsigned int paramLabel = myLabels->parameterLabel(aliLabel, compParNum); // FIXME: multiply by cmsToPedeFactor(subcomponent)/cmsToPedeFactor(mother) (or vice a versa?) if (theConstrPrecision > 0) aConstr << paramLabel << " " << std::setprecision(theConstrPrecision) << factors[iParam]; else aConstr << paramLabel << " " << factors[iParam]; if (myIsSteerFileDebug) { // debug aConstr << " ! for param " << compParNum << " of a " << alignableObjectId_.idToString(aliSubComp->alignableObjectId()) << " at " << aliSubComp->globalPosition() << ", r=" << aliSubComp->globalPosition().perp(); } aConstr << "\n"; ++nParPerConstr; // OK, we used one. } // end loop on params // if (nParPerConstr && nParPerConstr >= theMinHieraParPerConstr) { // Enough to make sense? if (myIsSteerFileDebug) { //debug file << "\n* Nr. " << iConstr << " of a '" << alignableObjectId_.idToString(ali->alignableObjectId()) << "' (label " << myLabels->alignableLabel(const_cast<Alignable *>(ali)) // ugly cast: FIXME! << "), position " << ali->globalPosition() << ", r = " << ali->globalPosition().perp(); } file << "\nConstraint 0.\n" << aConstr.str(); // in future 'Wconstraint'? } else if (nParPerConstr > 0) { // no warning for trivial case... edm::LogWarning("Alignment") << "@SUB=PedeSteerer::hierarchyConstraint" << "Skip constraint on " << nParPerConstr << " parameter(s):\n" << aConstr.str(); } } // end loop on constraints } //_________________________________________________________________________ unsigned int PedeSteerer::presigmas(const std::vector<edm::ParameterSet> &cffPresi, const std::string &fileName, const align::Alignables &alis, AlignableTracker *aliTracker, AlignableMuon *aliMuon, AlignableExtras *aliExtras) { // We loop on given PSet's, each containing a parameter selection and the presigma value // The resulting presigmas are stored in a map with Alignable* as key. // This map, 'fileName' and 'alis' are passed further to create the steering file. AlignmentParameterSelector selector(aliTracker, aliMuon, aliExtras); AlignablePresigmasMap aliPresiMap; // map to store alis with presigmas of their parameters for (std::vector<edm::ParameterSet>::const_iterator iSet = cffPresi.begin(), iE = cffPresi.end(); iSet != iE; ++iSet) { // loop on individual PSets defining ali-params with their presigma selector.clear(); selector.addSelections((*iSet).getParameter<edm::ParameterSet>("Selector")); const auto &alis = selector.selectedAlignables(); const std::vector<std::vector<char> > &sels = selector.selectedParameters(); const float presigma = (*iSet).getParameter<double>("presigma"); if (presigma <= 0.) { // given presigma > 0., 0. later used if not (yet) chosen for parameter throw cms::Exception("BadConfig") << "[PedeSteerer::presigmas]: Pre-sigma must be > 0., but is " << presigma << "."; } // now loop on alis of present selection for (unsigned int iAli = 0; iAli < alis.size(); ++iAli) { std::vector<float> &presigmas = aliPresiMap[alis[iAli]]; // existing or empty, so ensure length: if (presigmas.size() < sels[iAli].size()) presigmas.resize(sels[iAli].size(), 0.); for (unsigned int iParam = 0; iParam < sels[iAli].size(); ++iParam) { // loop on parameters if (sels[iAli][iParam] != '0') { // all but '0' means to apply the chosen presigma if (presigmas[iParam] != 0.) { // reset forbidden (would make it order dependent!) throw cms::Exception("BadConfig") << "[PedeSteerer::presigmas]: Try to set pre-sigma " << presigma << ", but already " << "set " << presigmas[iParam] << " (for a " << alignableObjectId_.idToString(alis[iAli]->alignableObjectId()) << ")."; } presigmas[iParam] = presigma; } // end if selected for presigma } // end loop on params } // end loop on alignables for given selection and presigma } // end loop on PSets if (aliPresiMap.empty()) return 0; else return this->presigmasFile(fileName, alis, aliPresiMap); } //_________________________________________________________________________ unsigned int PedeSteerer::presigmasFile(const std::string &fileName, const align::Alignables &alis, const AlignablePresigmasMap &aliPresiMap) { // Check if 'alis' are in aliPresiMap, // if yes apply presigma - but NOT if parameter is fixed! std::ofstream *filePtr = nullptr; unsigned int nPresiParam = 0; for (const auto &iAli : alis) { // Any presigma chosen for alignable? AlignablePresigmasMap::const_iterator presigmasIt = aliPresiMap.find(iAli); if (presigmasIt == aliPresiMap.end()) continue; // no presigma chosen for alignable // Why does the following not work? It does with CMSSW_1_3_X on SLC3... // const AlignablePresigmasMap::data_type &presigmas = presigmasIt->second; const std::vector<float> &presigmas = presigmasIt->second; // I want to hide float or double... for (unsigned int iParam = 0; iParam < presigmas.size(); ++iParam) { // Now check whether a presigma value > 0. chosen: if (presigmas[iParam] <= 0.) continue; // must be positive, '<' checked above // Do not apply presigma to inactive or fixed values. if (!(iAli->alignmentParameters()->selector()[iParam])) continue; SelectionUserVariables *selVar = dynamic_cast<SelectionUserVariables *>(iAli->alignmentParameters()->userVariables()); const char selChar = (selVar ? selVar->fullSelection()[iParam] : '1'); if (selChar == 'f' || selChar == 'F' || selChar == 'c' || selChar == 'C') continue; // Finally create and write steering file: if (!filePtr) { filePtr = this->createSteerFile(fileName, true); (*filePtr) << "* Presigma values for active parameters: \nParameter\n"; } const unsigned int aliLabel = myLabels->alignableLabel(iAli); (*filePtr) << myLabels->parameterLabel(aliLabel, iParam) << " 0. " << presigmas[iParam] * fabs(this->cmsToPedeFactor(iParam)); if (myIsSteerFileDebug) { (*filePtr) << " ! for a " << alignableObjectId_.idToString((iAli)->alignableObjectId()); } (*filePtr) << '\n'; ++nPresiParam; } // end loop on parameters for alignables with chosen presigmas } // end loop on alignables delete filePtr; // close properly file return nPresiParam; } //_________________________________________________________________________ std::ofstream *PedeSteerer::createSteerFile(const std::string &name, bool addToList) { const std::string realName(myNoSteerFiles ? "/dev/null" : name.c_str()); std::ofstream *result = new std::ofstream(realName.c_str(), std::ios::out); if (!result || !result->is_open()) { delete result; // needed before exception in case just open failed throw cms::Exception("FileOpenProblem") << "[PedeSteerer::createSteerFile]" << "Could not open " << realName << " as output file."; } else if (addToList) { mySteeringFiles.push_back(realName); // keep track } return result; } //_________________________________________________________________________ std::string PedeSteerer::fileName(const std::string &addendum) const { std::string name(myDirectory); name += myConfig.getParameter<std::string>("steerFile"); name += addendum; name += ".txt"; return name; } //___________________________________________________________________________ void PedeSteerer::buildSubSteer(AlignableTracker *aliTracker, AlignableMuon *aliMuon, AlignableExtras *aliExtras) { const auto &alis = myParameterStore->alignables(); if (theCoordMaster && !theCoordDefiners.empty()) { const std::string nameCoordFile(this->fileName("Coord")); this->defineCoordinates(theCoordDefiners, theCoordMaster, nameCoordFile); edm::LogInfo("Alignment") << "@SUB=PedeSteerer::buildSubSteer" << theCoordDefiners.size() << " highest level objects define the " << "coordinate system, steering file " << nameCoordFile << "."; } const std::string nameFixFile(this->fileName("FixPara")); const std::pair<unsigned int, unsigned int> nFixFixCor(this->fixParameters(alis, nameFixFile)); if (nFixFixCor.first != 0 || nFixFixCor.second != 0) { edm::LogInfo("Alignment") << "@SUB=PedeSteerer::buildSubSteer" << nFixFixCor.first << " parameters fixed at 0. and " << nFixFixCor.second << " at 'original' position, " << "steering file " << nameFixFile << "."; } if (this->buildNoHierarchyCollection(alis)) { // before hierarchyConstraints(..) edm::LogInfo("Alignment") << "@SUB=PedeSteerer::buildSubSteer" << myNoHieraCollection.size() << " alignables taken out of hierarchy."; } const std::string nameHierarchyFile(this->fileName("Hierarchy")); unsigned int nConstraint = this->hierarchyConstraints(alis, nameHierarchyFile); if (nConstraint) { edm::LogInfo("Alignment") << "@SUB=PedeSteerer::buildSubSteer" << "Hierarchy constraints for " << nConstraint << " alignables, " << "steering file " << nameHierarchyFile << "."; } //construct the systematic geometry deformations if (!(myConfig.getParameter<std::vector<edm::ParameterSet> >("constraints")).empty()) { PedeSteererWeakModeConstraints GeometryConstraints( aliTracker, myLabels, myConfig.getParameter<std::vector<edm::ParameterSet> >("constraints"), myConfig.getParameter<std::string>("steerFile")); //prepare the output files //Get the data structure in which the configuration data are stored. //The relation between the ostream* and the corresponding file name needs to be filled auto &ConstraintsConfigContainer = GeometryConstraints.getConfigData(); //loop over all configured constraints for (auto &it : ConstraintsConfigContainer) { //each level has its own constraint which means the output is stored in a separate file for (const auto &ilevelsFilename : it.levelsFilenames_) { it.mapFileName_.insert( std::make_pair(ilevelsFilename.second, this->createSteerFile(ilevelsFilename.second, true))); } } unsigned int nGeometryConstraint = GeometryConstraints.constructConstraints(alis); if (nGeometryConstraint) { edm::LogInfo("Alignment") << "@SUB=PedeSteerer::buildSubSteer" << "Geometry constraints for " << nGeometryConstraint << " alignables."; } } const std::string namePresigmaFile(this->fileName("Presigma")); unsigned int nPresigma = this->presigmas(myConfig.getParameter<std::vector<edm::ParameterSet> >("Presigmas"), namePresigmaFile, alis, aliTracker, aliMuon, aliExtras); if (nPresigma) { edm::LogInfo("Alignment") << "@SUB=PedeSteerer::buildSubSteer" << "Presigma values set for " << nPresigma << " parameters, " << "steering file " << namePresigmaFile << "."; } // Delete all SelectionUserVariables now? They will anyway be overwritten by MillePedeVariables... } //_________________________________________________________________________ std::string PedeSteerer::buildMasterSteer(const std::vector<std::string> &binaryFiles) { const std::string nameMasterSteer(this->fileName("Master")); std::ofstream *mainSteerPtr = this->createSteerFile(nameMasterSteer, false); if (!mainSteerPtr) return ""; // add external steering files, if any std::vector<std::string> addfiles = myConfig.getParameter<std::vector<std::string> >("additionalSteerFiles"); mySteeringFiles.insert(mySteeringFiles.end(), addfiles.begin(), addfiles.end()); // add steering files to master steering file std::ofstream &mainSteerRef = *mainSteerPtr; for (unsigned int iFile = 0; iFile < mySteeringFiles.size(); ++iFile) { mainSteerRef << mySteeringFiles[iFile] << "\n"; } // add binary files to master steering file mainSteerRef << "\nCfiles\n"; for (unsigned int iFile = 0; iFile < binaryFiles.size(); ++iFile) { if (myRunDirectory.empty()) mainSteerRef << binaryFiles[iFile] << "\n"; else mainSteerRef << "../" + binaryFiles[iFile] << "\n"; } // add method mainSteerRef << "\nmethod " << myConfig.getParameter<std::string>("method") << "\n"; // add further options const std::vector<std::string> opt(myConfig.getParameter<std::vector<std::string> >("options")); mainSteerRef << "\n* Outlier treatment and other options \n"; for (unsigned int i = 0; i < opt.size(); ++i) { mainSteerRef << opt[i] << "\n"; } delete mainSteerPtr; // close (and flush) again return nameMasterSteer; } //_________________________________________________________________________ int PedeSteerer::runPede(const std::string &masterSteer) const { if (masterSteer.empty()) { edm::LogError("Alignment") << "@SUB=PedeSteerer::runPede" << "Empty master steer file, stop"; return 0; //false; } // Change pede command if running in different directory std::string command; if (myRunDirectory.empty()) { command = myConfig.getUntrackedParameter<std::string>("pedeCommand"); (command += " ") += masterSteer; } else { command = "(cd " + myRunDirectory + " && "; command += myConfig.getUntrackedParameter<std::string>("pedeCommand"); (command += " ") += "../" + masterSteer; command += ")"; } const std::string dump(myConfig.getUntrackedParameter<std::string>("pedeDump")); if (!dump.empty()) { command += " > "; (command += myDirectory) += dump; } edm::LogInfo("Alignment") << "@SUB=PedeSteerer::runPede" << "Start running " << command; // as Pede does not return a meaningful // exit code, the gSystem->Exec return // can only tell us if pede was found. int shellReturn = gSystem->Exec(command.c_str()); // The real pede return flag is written into // a single-character 'millepede.end' // file. Read this here. std::string mpExit = "millepede.end"; if (!myRunDirectory.empty()) mpExit = myRunDirectory + "/" + mpExit; std::ifstream mpend(mpExit); // open the Pede exit code file std::string statusMessage = ""; if (shellReturn != 0 || !mpend.is_open()) { edm::LogError("Alignment") << "@SUB=PedeSteerer::runPede" << "Failed to call Pede"; } else { // read the pede exit code from the file. mpend >> shellReturn; // some acrobatics to get a nice formatting of the remaining text std::stringstream remainingCont; remainingCont << mpend.rdbuf(); statusMessage = remainingCont.str(); statusMessage = statusMessage.substr(statusMessage.find_first_not_of(' ')); statusMessage = statusMessage.substr(0, statusMessage.find_last_not_of(" \n") + 1); mpend.close(); } edm::LogInfo("Alignment") << "@SUB=PedeSteerer::runPede" << "Command returns " << shellReturn << " - " << statusMessage; // the return code actually does not // get checked by client code (as of 02/2026). // So warn the user if something went wrong. // Documentation of exit codes: // https://millepede.pages.desy.de/millepede-ii/exit_code_page.html if (shellReturn == -1) { edm::LogError("Alignment") << "@SUB=PedeSteerer::runPede" << "Pede crashed:\n " << statusMessage << "\n" << "Please check the millepede log files for more information."; } else if (shellReturn == 1) { edm::LogInfo("Alignment") << "@SUB=PedeSteerer::runPede" << "Pede exited with tolerable warnings:\n " << statusMessage << "\n" << "Please check the millepede log files for more information."; } else if (shellReturn > 1 && shellReturn < 5) { edm::LogWarning("Alignment") << "@SUB=PedeSteerer::runPede" << "Pede exited with severe warnings:\n " << statusMessage << "\n" << "Please check the millepede log files for more information."; } else if (shellReturn == 5) { edm::LogWarning("Alignment") << "@SUB=PedeSteerer::runPede" << "Pede did not find a solution:\n " << statusMessage << "\n" << "Please check the millepede log files for more information."; } else if (shellReturn > 9) { edm::LogError("Alignment") << "@SUB=PedeSteerer::runPede" << "Pede aborted due to errors:\n " << statusMessage << "\n" << "Please check the millepede log files for more information."; } return shellReturn; }