CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/Alignment/MillePedeAlignmentAlgorithm/src/PedeSteerer.cc

Go to the documentation of this file.
00001 
00011 #include "PedeSteerer.h"
00012 #include "PedeLabeler.h"
00013 
00014 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00015 
00016 #include "Alignment/CommonAlignment/interface/Alignable.h"
00017 #include <boost/cstdint.hpp> 
00018 #include "Alignment/CommonAlignment/interface/AlignableObjectId.h"
00019 #include "Alignment/CommonAlignment/interface/Utilities.h"
00020 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterStore.h"
00021 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterSelector.h"
00022 #include "Alignment/CommonAlignmentAlgorithm/interface/SelectionUserVariables.h"
00023 #include "Alignment/CommonAlignmentParametrization/interface/AlignmentParametersFactory.h"
00024 #include "Alignment/CommonAlignmentParametrization/interface/RigidBodyAlignmentParameters.h"
00025 
00026 #include "Alignment/TrackerAlignment/interface/TrackerAlignableId.h"
00027 // for 'type identification' as Alignable
00028 #include "Alignment/TrackerAlignment/interface/AlignableTracker.h"
00029 #include "Alignment/MuonAlignment/interface/AlignableMuon.h"
00030 #include "Alignment/CommonAlignment/interface/AlignableExtras.h"
00031 // GF doubts the need of these includes from include checker campaign:
00032 #include <FWCore/Framework/interface/EventSetup.h> 
00033 #include <Geometry/CommonDetUnit/interface/GeomDetUnit.h> 
00034 #include <Geometry/CommonDetUnit/interface/GeomDetType.h> 
00035 #include <DataFormats/GeometrySurface/interface/LocalError.h> 
00036 #include <Geometry/DTGeometry/interface/DTLayer.h> 
00037 // end of doubt
00038 
00039 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00040 
00041 #include <fstream>
00042 #include <sstream>
00043 #include <algorithm>
00044 
00045 // from ROOT
00046 #include <TSystem.h>
00047 #include <TMath.h>
00048 
00049 #include <iostream>
00050 
00051 PedeSteerer::PedeSteerer(AlignableTracker *aliTracker, AlignableMuon *aliMuon, AlignableExtras *aliExtras,
00052                          AlignmentParameterStore *store, const PedeLabeler *labels,
00053                          const edm::ParameterSet &config, const std::string &defaultDir,
00054                          bool noSteerFiles) :
00055   myParameterStore(store), myLabels(labels), myConfig(config),
00056   myDirectory(myConfig.getUntrackedParameter<std::string>("fileDir")),
00057   myNoSteerFiles(noSteerFiles),
00058   myIsSteerFileDebug(myConfig.getUntrackedParameter<bool>("steerFileDebug")),
00059   myParameterSign(myConfig.getUntrackedParameter<int>("parameterSign")),
00060   theMinHieraConstrCoeff(myConfig.getParameter<double>("minHieraConstrCoeff")),
00061   theMinHieraParPerConstr(myConfig.getParameter<unsigned int>("minHieraParPerConstr")),
00062   theCoordMaster(0)
00063 {
00064   if (myParameterSign != 1 && myParameterSign != -1) {
00065     cms::Exception("BadConfig") << "Expect PedeSteerer.parameterSign = +/-1, "
00066                                 << "found " << myParameterSign << ".";
00067   }
00068 
00069   // Correct directory, needed before asking for fileName(..):
00070   if (myDirectory.empty()) myDirectory = defaultDir;
00071   if (!myDirectory.empty() && myDirectory.find_last_of('/') != myDirectory.size() - 1) {
00072     myDirectory += '/'; // directory may need '/'
00073   }
00074 
00075   const std::vector<Alignable*> &alis = myParameterStore->alignables();
00076   if (!this->checkParameterChoices(alis)) {} // anyway thrown exception
00077 
00078   // Coordinate system selection and correction before everything
00079   theCoordDefiners = this->selectCoordinateAlis(alis);
00080   if (!theCoordDefiners.empty()) { // Create steering with constraints to define coordinate system:
00081     // OK, some hacks:
00082     // - we want a composite with global coordinates where tracker and muon are components
00083     //   (to call RigidBodyAl.Param.->globalParameters() in correctToReferenceSystem(..))
00084     // - so we create a AlignableComposite and add tracker and muon
00085     // - but the addComponent(..) method is so cute that it calculates position from 
00086     //   daughters' deepComponents()
00087     // - so we want to move it back to (0,0,0), but ali->move(..) would move daughters as well
00088     //   => cheat with a const_cast and move only the surface back
00089     // - this hacked master object does not have a label for its parameters
00090     //   => some warnings if debug output selected in pedeSteer files
00091     // - we must not delete our new master (little mem. leak...) since that would delete
00092     //   the daughters as well!
00093     if (aliTracker) {
00094       theCoordMaster = new AlignableComposite(aliTracker->id(), align::invalid);
00095       theCoordMaster->addComponent(aliTracker);
00096     } else if (aliMuon) {
00097       theCoordMaster = new AlignableComposite(aliMuon->id(), align::invalid);
00098     } else {
00099       throw cms::Exception("BadConfig")
00100         << "[PedeSteerer]" << "Cannot define global coordinate system "
00101         << "with neither tracker nor muon!";
00102     }
00103     if (aliMuon) theCoordMaster->addComponent(aliMuon); // tracker is already added if existing
00104     if (aliExtras) { // tracker and/or muon are already added if existing
00105       align::Alignables allExtras = aliExtras->components();
00106       for ( std::vector<Alignable*>::iterator it = allExtras.begin(); it != allExtras.end(); ++it ) {
00107         theCoordMaster->addComponent(*it);
00108       }
00109     }
00110 
00111     const Alignable::PositionType &tmpPos = theCoordMaster->globalPosition();
00112     AlignableSurface & masterSurf = const_cast<AlignableSurface&>(theCoordMaster->surface());
00113     masterSurf.move(align::GlobalVector(-tmpPos.x(),-tmpPos.y(),-tmpPos.z()));
00114 
00115     if (this->isCorrectToRefSystem(theCoordDefiners)) { // defined by 's' (MC): 'correct' misalignment
00116       this->correctToReferenceSystem(); // really before 'defineCoordinates'?
00117     }
00118   } 
00119 
00120 }
00121 
00122 //___________________________________________________________________________
00123 PedeSteerer::~PedeSteerer()
00124 {
00125   // delete theCoordMaster; NO, see above
00126 }
00127 
00128 //_________________________________________________________________________
00129 bool PedeSteerer::isNoHiera(const Alignable* ali) const
00130 {
00131   return (myNoHieraCollection.find(ali) != myNoHieraCollection.end());
00132 }
00133 
00134 //_________________________________________________________________________
00135 double PedeSteerer::cmsToPedeFactor(unsigned int parNum) const
00136 {
00137   return 1.; // mmh, otherwise would need to FIXME hierarchyConstraint...
00138 
00139   switch (parNum) {
00140   case RigidBodyAlignmentParameters::dx:
00141   case RigidBodyAlignmentParameters::dy:
00142     return 1000.; // cm to mum *1/10 to get smaller values
00143   case RigidBodyAlignmentParameters::dz:
00144     return 2500.;   // cm to mum *1/4 
00145   case RigidBodyAlignmentParameters::dalpha:
00146   case RigidBodyAlignmentParameters::dbeta:
00147     return 1000.; // rad to mrad (no first guess for sensitivity yet)
00148   case RigidBodyAlignmentParameters::dgamma:
00149     return 10000.; // rad to mrad *10 to get larger values
00150   default:
00151     return 1.;
00152   }
00153 }
00154 
00155 //_________________________________________________________________________
00156 unsigned int PedeSteerer::buildNoHierarchyCollection(const std::vector<Alignable*> &alis)
00157 {
00158   myNoHieraCollection.clear();  // just in case of re-use...
00159 
00160   for (std::vector<Alignable*>::const_iterator iAli = alis.begin() ; iAli != alis.end(); ++iAli) {
00161     AlignmentParameters *params = (*iAli)->alignmentParameters();
00162     SelectionUserVariables *selVar = dynamic_cast<SelectionUserVariables*>(params->userVariables());
00163     if (!selVar) continue;
00164     // Now check whether taking out of hierarchy is selected - must be consistent!
00165     unsigned int numNoHieraPar = 0;
00166     unsigned int numHieraPar = 0;
00167     for (unsigned int iParam = 0; static_cast<int>(iParam) < params->size(); ++iParam) {
00168       const char selector = selVar->fullSelection()[iParam];
00169       if (selector == 'C' || selector == 'F' || selector == 'H') {
00170         ++numNoHieraPar;
00171       } else if (selector == 'c' || selector == 'f' || selector == '1' || selector == 'r'
00172                  || selector == 's') {
00173         ++numHieraPar;
00174       } // else ... accept '0' as undetermined
00175     }
00176     if (numNoHieraPar) { // Selected to be taken out.
00177       if (numHieraPar) { // Inconsistent: Some parameters still in hierarchy ==> exception!
00178         throw cms::Exception("BadConfig") 
00179           << "[PedeSteerer::buildNoHierarchyCollection] All active parameters of alignables to be "
00180           << " taken out of the hierarchy must be marked with capital letters 'C', 'F' or 'H'!";
00181       }
00182       bool isInHiera = false; // Check whether Alignable is really part of hierarchy:
00183       Alignable *mother = *iAli;
00184       while ((mother = mother->mother())) {
00185         if (mother->alignmentParameters()) isInHiera = true; // could 'break;', but loop is short
00186       }
00187       // Complain, but keep collection short if not in hierarchy:
00188       if (isInHiera) myNoHieraCollection.insert(*iAli);
00189       else edm::LogWarning("Alignment") << "@SUB=PedeSteerer::buildNoHierarchyCollection"
00190                                         << "Alignable not in hierarchy, no need to remove it!";
00191     }
00192   } // end loop on alignables
00193 
00194   return myNoHieraCollection.size();
00195 }
00196 
00197 //_________________________________________________________________________
00198 bool PedeSteerer::checkParameterChoices(const std::vector<Alignable*> &alis) const
00199 {
00200   for (std::vector<Alignable*>::const_iterator iAli = alis.begin() ; iAli != alis.end(); ++iAli) {
00201     AlignmentParameters *paras = (*iAli)->alignmentParameters();
00202     SelectionUserVariables *selVar = dynamic_cast<SelectionUserVariables*>(paras->userVariables());
00203     if (!selVar) continue;
00204     for (unsigned int iParam = 0; static_cast<int>(iParam) < paras->size(); ++iParam) {
00205       const char sel = selVar->fullSelection()[iParam];
00206       if (sel != 'f' && sel != 'F' && sel != 'c' && sel != 'C' &&
00207           sel != '0' && sel != '1' && sel != 'H' && sel != 'r' && sel != 's') {
00208         throw cms::Exception("BadConfig")
00209           << "[PedeSteerer::unknownParameterChoices] " 
00210           << "Unexpected parameter selector '" << sel
00211           << "', use \n'f/F' (fix),\n'c/C' (fix at correct pos.),\n'1/H' (free),\n"
00212           << "'r/s' (free, but defining reference system, trying to correct misalignment if 's')"
00213           << " or \n'0' (ignore).\n"
00214           << "Capital letters mean that the Alignable is taken out of a possible hierarchy,\n"
00215           << "but must be used consistently for all its parameters.";
00216         return false; // unreached
00217       }
00218     }
00219   }
00220 
00221   return true;
00222 }
00223 
00224 //_________________________________________________________________________
00225 std::pair<unsigned int, unsigned int>
00226 PedeSteerer::fixParameters(const std::vector<Alignable*> &alis, const std::string &fileName)
00227 {
00228   // return number of parameters fixed at 0. and fixed at original position 
00229   std::pair<unsigned int, unsigned int> numFixNumFixCor(0, 0);
00230 
00231   std::ofstream *filePtr = 0;
00232 
00233   for (std::vector<Alignable*>::const_iterator iAli = alis.begin() ; iAli != alis.end(); ++iAli) {
00234     AlignmentParameters *params = (*iAli)->alignmentParameters();
00235     SelectionUserVariables *selVar = dynamic_cast<SelectionUserVariables*>(params->userVariables());
00236     if (!selVar) continue;
00237 
00238     for (unsigned int iParam = 0; static_cast<int>(iParam) < params->size(); ++iParam) {
00239       int whichFix = this->fixParameter(*iAli, iParam, selVar->fullSelection()[iParam], filePtr,
00240                                         fileName);
00241       if (whichFix == 1) {
00242         ++(numFixNumFixCor.first);
00243       } else if (whichFix == -1) {
00244         ++(numFixNumFixCor.second);
00245       }
00246     }
00247   }
00248 
00249   delete filePtr; // automatically flushes, no problem if NULL ptr.   
00250 
00251   return numFixNumFixCor;
00252 }
00253 
00254 //_________________________________________________________________________
00255 int PedeSteerer::fixParameter(Alignable *ali, unsigned int iParam, char selector,
00256                               std::ofstream* &filePtr, const std::string &fileName)
00257 {
00258   int result = 0;
00259   float fixAt = 0.;
00260   if (selector == 'c' || selector == 'C') {
00261     if (ali->alignmentParameters()->type() != AlignmentParametersFactory::kRigidBody) {
00262       throw cms::Exception("BadConfig") 
00263         << "PedeSteerer::fixParameter: correction (c/C) possible only for RigidBodyParameters";
00264     }
00265     fixAt = -this->parameterSign() * RigidBodyAlignmentParameters(ali, true).parameters()[iParam];
00266     result = -1;
00267   } else if (selector == 'f' || selector == 'F') {
00268     result = 1;
00269   }
00270 
00271   if (result) {
00272     if (!filePtr) {
00273       filePtr = this->createSteerFile(fileName, true);
00274       (*filePtr) << "Parameter\n";
00275     }
00276     std::ofstream &file = *filePtr;
00277 
00278     const unsigned int aliLabel = myLabels->alignableLabel(ali);
00279     file << myLabels->parameterLabel(aliLabel, iParam) << "  " 
00280          << fixAt * this->cmsToPedeFactor(iParam) << " -1.0";
00281     if (myIsSteerFileDebug) { // debug
00282       const GlobalPoint position(ali->globalPosition());
00283       file << "  * id " << ali->id() << ", eta " << position.eta() << ", z " << position.z()
00284            << ", r " << position.perp() << ", phi " << position.phi();
00285     }
00286     file << "\n";
00287   }
00288 
00289   return result;
00290 }
00291 
00292 //_________________________________________________________________________
00293 std::vector<Alignable*> PedeSteerer::selectCoordinateAlis(const std::vector<Alignable*> &alis) const
00294 {
00295   std::vector<Alignable*> coordAlis;
00296 
00297   for (std::vector<Alignable*>::const_iterator iAli = alis.begin() ; iAli != alis.end(); ++iAli) {
00298     AlignmentParameters *params = (*iAli)->alignmentParameters();
00299     SelectionUserVariables *selVar = dynamic_cast<SelectionUserVariables*>(params->userVariables());
00300     if (!selVar) continue;
00301     unsigned int refParam = 0;
00302     unsigned int nonRefParam = 0;
00303     for (unsigned int iParam = 0; static_cast<int>(iParam) < params->size(); ++iParam) {
00304       const char selector = selVar->fullSelection()[iParam];
00305       if (selector == 'r' || selector == 's') {
00306         ++refParam;
00307       } else if (selector != '0' && selector != 'f') { // allow also 'c'?
00308         ++nonRefParam;
00309       }
00310     }
00311     // Check whether some 'r/s' selection string. If yes and selection makes sense, add to result:
00312     if (refParam) {
00313       if (nonRefParam) {
00314         throw cms::Exception("BadConfig") 
00315           << "[PedeSteerer::selectCoordinateAlis] All active parameters of alignables defining "
00316           << "the coordinate system must be marked with 'r/s' (or fixed, 'f')!";
00317       } else {
00318         Alignable *mother = *iAli;
00319         while ((mother = mother->mother())) {
00320           if (mother->alignmentParameters()) {
00321             throw cms::Exception("BadConfig") << "[PedeSteerer::selectCoordinateAlis] "
00322                                               << "Alignables defining the coordinate system must "
00323                                               << "be highest level!";
00324           }
00325         }
00326         coordAlis.push_back(*iAli);
00327       }
00328     }
00329   } // end loop on alignables
00330 
00331   return coordAlis;
00332 }
00333 
00334 
00335 //_________________________________________________________________________
00336 void PedeSteerer::defineCoordinates(const std::vector<Alignable*> &alis, Alignable *aliMaster,
00337                                     const std::string &fileName)
00338 {
00339   std::ofstream *filePtr = this->createSteerFile(fileName, true);
00340   (*filePtr) << "* Constraints to define coordinate system:\n";
00341   if (!aliMaster || aliMaster->alignmentParameters()) {
00342     throw cms::Exception("BadConfig")
00343       << "[PedeSteerer::defineCoordinates] " << "No master alignable or it has parameters!";
00344   }
00345   if (myIsSteerFileDebug) { // See constructor comments about hack:
00346     edm::LogError("Alignment") << "@SUB=PedeSteerer::defineCoordinates"
00347                                << "Ignore following LogicErrors from PedeLabeler.";
00348   }
00349   AlignmentParameters *par = new RigidBodyAlignmentParameters(aliMaster, false);
00350   aliMaster->setAlignmentParameters(par); // hierarchyConstraint needs parameters
00351   this->hierarchyConstraint(aliMaster, alis, *filePtr);
00352   aliMaster->setAlignmentParameters(0); // erase dummy parameters
00353 
00354   delete filePtr; // automatically flushes, no problem if NULL ptr.   
00355 }
00356 
00357 //_________________________________________________________________________
00358 bool PedeSteerer::isCorrectToRefSystem(const std::vector<Alignable*> &coordDefiners) const
00359 {
00360   bool doCorrect = false;
00361   bool doNotCorrect = false;
00362   for (std::vector<Alignable*>::const_iterator it = coordDefiners.begin(), iE=coordDefiners.end();
00363        it != iE; ++it) {
00364     SelectionUserVariables *selVar = 
00365       ((*it)->alignmentParameters() ? 
00366        dynamic_cast<SelectionUserVariables*>((*it)->alignmentParameters()->userVariables()) : 0);
00367     if (!selVar) continue;  // is an error!?
00368 
00369     for (unsigned int i = 0; i < selVar->fullSelection().size(); ++i) {
00370       if (selVar->fullSelection()[i] == 'r') doNotCorrect = true;
00371       else if (selVar->fullSelection()[i] == 's') doCorrect = true;
00372     }
00373   }
00374 
00375   if (doCorrect && doNotCorrect) {
00376     throw cms::Exception("BadConfig")
00377       << "[PedeSteerer::doCorrectToRefSystem]: Parameter selection 's' and 'r' must not coexist!";
00378   }
00379 
00380   return doCorrect;
00381 }
00382 
00383 //_________________________________________________________________________
00384 void PedeSteerer::correctToReferenceSystem()
00385 {
00386   typedef RigidBodyAlignmentParameters RbPars;
00387   if (!theCoordMaster || theCoordDefiners.empty()) return; // nothing was defined
00388 
00389   std::vector<Alignable*> definerDets; // or ...DetUnits
00390   for (std::vector<Alignable*>::iterator it = theCoordDefiners.begin(), iE = theCoordDefiners.end();
00391        it != iE; ++it) {// find lowest level objects of alignables that define the coordinate system
00392     const std::vector<Alignable*> &comp = (*it)->deepComponents();
00393     definerDets.insert(definerDets.end(), comp.begin(), comp.end());
00394   }
00395 
00396   for (unsigned int iLoop = 0; ; ++iLoop) { // iterate: shifts and rotations are not independent
00397     AlgebraicVector meanPars(RbPars::N_PARAM);
00398     for (std::vector<Alignable*>::iterator it = definerDets.begin(), iE = definerDets.end();
00399          it != iE; ++it) { // sum up mean displacements/misrotations:
00400       meanPars += RbPars(*it, true).globalParameters();// requires theCoordMaster has global frame
00401     }
00402     meanPars /= definerDets.size();
00403     const align::Scalar squareSum = meanPars.normsq();
00404 
00405     if (squareSum < 1.e-20) break; // sqrt(1.e-20)=1.e-10: close enough to stop iterating
00406     if (iLoop == 0) {
00407       edm::LogInfo("Alignment") << "@SUB=PedeSteerer::correctToReferenceSystem"
00408                                 << "Loop " << iLoop << " "
00409                                 << "Mean misalignment of dets of defined coordinate system"
00410                                 << (squareSum < 1.e-20 ? ":" :
00411                                     " (will be iteratively corrected to < 1.e-10):") << meanPars;
00412     }
00413     if (iLoop >=5) { // 3 iterations should be safe, use 5 for 'more' safety...
00414         edm::LogError("Alignment") << "@SUB=PedeSteerer::correctToReferenceSystem"
00415                                    << "No convergence in " << iLoop << " iterations, " 
00416                                    << "remaining misalignment: " << meanPars;
00417       break;
00418     }
00419 
00420     const GlobalVector globalShift(meanPars[RbPars::dx],meanPars[RbPars::dy],meanPars[RbPars::dz]);
00421     theCoordMaster->move(-globalShift); // sign to revert
00422     align::EulerAngles globalAngles(3);
00423     globalAngles[0] = meanPars[RbPars::dalpha];
00424     globalAngles[1] = meanPars[RbPars::dbeta];
00425     globalAngles[2] = meanPars[RbPars::dgamma];
00426     theCoordMaster->rotateInGlobalFrame(align::toMatrix(-globalAngles)); // sign to revert
00427   }
00428   
00429 }
00430 
00431 //_________________________________________________________________________
00432 unsigned int PedeSteerer::hierarchyConstraints(const std::vector<Alignable*> &alis,
00433                                                const std::string &fileName)
00434 {
00435   std::ofstream *filePtr = 0;
00436 
00437   unsigned int nConstraints = 0;
00438   std::vector<Alignable*> aliDaughts;
00439   for (std::vector<Alignable*>::const_iterator iA = alis.begin(), iEnd = alis.end();
00440        iA != iEnd; ++iA) {
00441     aliDaughts.clear();
00442     if (!(*iA)->firstCompsWithParams(aliDaughts)) {
00443       static AlignableObjectId objId; // static since costly constructor FIXME?
00444       edm::LogWarning("Alignment") << "@SUB=PedeSteerer::hierarchyConstraints"
00445                                    << "Some but not all daughters of "
00446                                    << objId. typeToName((*iA)->alignableObjectId())
00447                                    << " with params!";
00448     }
00449 //     edm::LogInfo("Alignment") << "@SUB=PedeSteerer::hierarchyConstraints"
00450 //                            << aliDaughts.size() << " ali param components";
00451     if (aliDaughts.empty()) continue;
00452 //     edm::LogInfo("Alignment") << "@SUB=PedeSteerer::hierarchyConstraints"
00453 //                            << aliDaughts.size() << " alignable components ("
00454 //                            << (*iA)->size() << " in total) for " 
00455 //                            << aliId.alignableTypeName(*iA) 
00456 //                            << ", layer " << aliId.typeAndLayerFromAlignable(*iA).second
00457 //                            << ", position " << (*iA)->globalPosition()
00458 //                            << ", r = " << (*iA)->globalPosition().perp();
00459     if (!filePtr) filePtr = this->createSteerFile(fileName, true);
00460     ++nConstraints;
00461     this->hierarchyConstraint(*iA, aliDaughts, *filePtr);
00462   }
00463 
00464   delete filePtr; // automatically flushes, no problem if NULL ptr.   
00465 
00466   return nConstraints;
00467 }
00468 
00469 //_________________________________________________________________________
00470 void PedeSteerer::hierarchyConstraint(const Alignable *ali,
00471                                       const std::vector<Alignable*> &components,
00472                                       std::ofstream &file) const
00473 {
00474   typedef AlignmentParameterStore::ParameterId ParameterId;
00475 
00476   std::vector<std::vector<ParameterId> > paramIdsVec;
00477   std::vector<std::vector<double> > factorsVec;
00478   const bool allConstr = false; // true; // make configurable?
00479   static bool first = true;
00480   if (allConstr && first) {
00481     edm::LogWarning("Alignment") << "@SUB=PedeSteerer::hierarchyConstraint"
00482                                  << "changed to use all 6 constraints";
00483     first = false;
00484   }
00485   if (!myParameterStore->hierarchyConstraints(ali, components, paramIdsVec, factorsVec, allConstr,
00486                                               theMinHieraConstrCoeff)){
00487     edm::LogWarning("Alignment") << "@SUB=PedeSteerer::hierarchyConstraint"
00488                                  << "Problems from store.";
00489   }
00490 
00491   for (unsigned int iConstr = 0; iConstr < paramIdsVec.size(); ++iConstr) {
00492     std::ostringstream aConstr;
00493 
00494     const std::vector<ParameterId> &parIds = paramIdsVec[iConstr];
00495     const std::vector<double> &factors = factorsVec[iConstr];
00496     unsigned int nParPerConstr = 0; // keep track of used factor/parId pair
00497     // parIds.size() == factors.size() granted by myParameterStore->hierarchyConstraints
00498     for (unsigned int iParam = 0; iParam < parIds.size(); ++iParam) {
00499       Alignable *aliSubComp = parIds[iParam].first;
00500       const unsigned int compParNum = parIds[iParam].second;
00501       if (this->isNoHiera(aliSubComp)) {
00502         if (myIsSteerFileDebug) aConstr << "* Taken out of hierarchy: ";
00503         continue;
00504       }
00505       const unsigned int aliLabel = myLabels->alignableLabel(aliSubComp);
00506       const unsigned int paramLabel = myLabels->parameterLabel(aliLabel, compParNum);
00507       // FIXME: multiply by cmsToPedeFactor(subcomponent)/cmsToPedeFactor(mother) (or vice a versa?)
00508       aConstr << paramLabel << "    " << factors[iParam];
00509       if (myIsSteerFileDebug) { // debug
00510         AlignableObjectId objId; // costly constructor, but only debug here...
00511         aConstr << "   ! for param " << compParNum << " of a " 
00512                 << objId.typeToName(aliSubComp->alignableObjectId()) << " at " 
00513                 << aliSubComp->globalPosition() << ", r=" << aliSubComp->globalPosition().perp();
00514       }
00515       aConstr << "\n";
00516       ++nParPerConstr; // OK, we used one.
00517     } // end loop on params
00518 
00519     // 
00520     if (nParPerConstr && nParPerConstr >= theMinHieraParPerConstr) { // Enough to make sense?
00521       if (myIsSteerFileDebug) { //debug
00522         AlignableObjectId objId; // costly constructor, but only debug here...
00523         file << "\n* Nr. " << iConstr << " of a '"
00524              << objId.typeToName(ali->alignableObjectId()) << "' (label "
00525              << myLabels->alignableLabel(const_cast<Alignable*>(ali)) // ugly cast: FIXME!
00526              << "), position " << ali->globalPosition()
00527              << ", r = " << ali->globalPosition().perp();
00528       }
00529       file << "\nConstraint   0.\n" << aConstr.str(); // in future 'Wconstraint'?
00530     } else if (nParPerConstr > 0) { // no warning for trivial case...
00531       edm::LogWarning("Alignment") << "@SUB=PedeSteerer::hierarchyConstraint"
00532                                    << "Skip constraint on " << nParPerConstr
00533                                    << " parameter(s):\n" << aConstr.str();
00534     }
00535   } // end loop on constraints
00536 }
00537 
00538 //_________________________________________________________________________
00539 unsigned int PedeSteerer::presigmas(const std::vector<edm::ParameterSet> &cffPresi,
00540                                     const std::string &fileName,
00541                                     const std::vector<Alignable*> &alis,
00542                                     AlignableTracker *aliTracker, AlignableMuon *aliMuon, AlignableExtras *aliExtras)
00543 {
00544   // We loop on given PSet's, each containing a parameter selection and the presigma value
00545   // The resulting presigmas are stored in a map with Alignable* as key.
00546   // This map, 'fileName' and 'alis' are passed further to create the steering file.
00547 
00548   AlignmentParameterSelector selector(aliTracker, aliMuon, aliExtras);
00549   AlignablePresigmasMap aliPresiMap; // map to store alis with presigmas of their parameters 
00550   for (std::vector<edm::ParameterSet>::const_iterator iSet = cffPresi.begin(), iE = cffPresi.end();
00551        iSet != iE; ++iSet) { // loop on individual PSets defining ali-params with their presigma
00552     selector.clear();
00553     selector.addSelections((*iSet).getParameter<edm::ParameterSet>("Selector"));
00554     const std::vector<Alignable*> &alis = selector.selectedAlignables();
00555     const std::vector<std::vector<char> > &sels =  selector.selectedParameters();
00556     const float presigma = (*iSet).getParameter<double>("presigma");
00557     if (presigma <= 0.) { // given presigma > 0., 0. later used if not (yet) chosen for parameter
00558       throw cms::Exception("BadConfig")
00559         << "[PedeSteerer::presigmas]: Pre-sigma must be > 0., but is " << presigma << ".";
00560     }
00561     // now loop on alis of present selection
00562     for (unsigned int iAli = 0; iAli < alis.size(); ++iAli) {
00563       std::vector<float> &presigmas = aliPresiMap[alis[iAli]]; // existing or empty, so ensure length:
00564       if (presigmas.size() < sels[iAli].size()) presigmas.resize(sels[iAli].size(), 0.);
00565       for (unsigned int iParam = 0; iParam < sels[iAli].size(); ++iParam) { // loop on parameters
00566         if (sels[iAli][iParam] != '0') { // all but '0' means to apply the chosen presigma
00567           if (presigmas[iParam] != 0.) { // reset forbidden (would make it order dependent!)
00568             throw cms::Exception("BadConfig")
00569               << "[PedeSteerer::presigmas]: Try to set pre-sigma " << presigma << ", but already "
00570               << "set " << presigmas[iParam] << " (for a " 
00571               << AlignableObjectId().typeToName(alis[iAli]->alignableObjectId()) << ").";
00572           }
00573           presigmas[iParam] = presigma;
00574         } // end if selected for presigma
00575       } // end loop on params
00576     } // end loop on alignables for given selection and presigma
00577   } // end loop on PSets 
00578 
00579   if (aliPresiMap.empty()) return 0;
00580   else return this->presigmasFile(fileName, alis, aliPresiMap);
00581 }
00582 
00583 //_________________________________________________________________________
00584 unsigned int PedeSteerer::presigmasFile(const std::string &fileName,
00585                                         const std::vector<Alignable*> &alis,
00586                                         const AlignablePresigmasMap &aliPresiMap)
00587 {
00588   // Check if 'alis' are in aliPresiMap, 
00589   // if yes apply presigma - but NOT if parameter is fixed!
00590   std::ofstream *filePtr = 0;
00591   const AlignableObjectId aliObjId;
00592 
00593   unsigned int nPresiParam = 0;
00594   for (std::vector<Alignable*>::const_iterator iAli = alis.begin(), iAliE = alis.end();
00595        iAli != iAliE; ++iAli) {
00596     // Any presigma chosen for alignable?
00597     AlignablePresigmasMap::const_iterator presigmasIt = aliPresiMap.find(*iAli);
00598     if (presigmasIt == aliPresiMap.end()) continue; // no presigma chosen for alignable
00599 
00600     // Why does the following not work? It does with CMSSW_1_3_X on SLC3...
00601     // const AlignablePresigmasMap::data_type &presigmas = presigmasIt->second;
00602     const std::vector<float> &presigmas = presigmasIt->second; // I want to hide float or double...
00603     for (unsigned int iParam = 0; iParam < presigmas.size(); ++iParam) {
00604       // Now check whether a presigma value > 0. chosen: 
00605       if (presigmas[iParam] <= 0.) continue; // must be positive, '<' checked above
00606       // Do not apply presigma to inactive or fixed values.
00607       if (!(*iAli)->alignmentParameters()->selector()[iParam]) continue;
00608       SelectionUserVariables *selVar 
00609         = dynamic_cast<SelectionUserVariables*>((*iAli)->alignmentParameters()->userVariables());
00610       const char selChar = (selVar ? selVar->fullSelection()[iParam] : '1');
00611       if (selChar == 'f' || selChar == 'F' || selChar == 'c' || selChar == 'C') continue;
00612       // Finally create and write steering file:
00613       if (!filePtr) {
00614         filePtr = this->createSteerFile(fileName, true);
00615         (*filePtr) << "* Presigma values for active parameters: \nParameter\n";
00616       }
00617       const unsigned int aliLabel = myLabels->alignableLabel(*iAli);
00618       (*filePtr) << myLabels->parameterLabel(aliLabel, iParam) << "   0.   " 
00619                  << presigmas[iParam] * fabs(this->cmsToPedeFactor(iParam));
00620       if (myIsSteerFileDebug) {
00621         (*filePtr) << "  ! for a " << aliObjId.typeToName((*iAli)->alignableObjectId());
00622       }
00623       (*filePtr) << '\n';
00624 
00625       ++nPresiParam;
00626     } // end loop on parameters for alignables with chosen presigmas
00627   } // end loop on alignables
00628 
00629   delete filePtr; // close properly file
00630   return nPresiParam;
00631 }
00632 
00633 //_________________________________________________________________________
00634 std::ofstream* PedeSteerer::createSteerFile(const std::string &name, bool addToList)
00635 {
00636   const std::string realName(myNoSteerFiles ? "/dev/null" : name.c_str());
00637 
00638   std::ofstream *result = new std::ofstream(realName.c_str(), std::ios::out);
00639   if (!result || !result->is_open()) {
00640     delete result; // needed before exception in case just open failed
00641     throw cms::Exception("FileOpenProblem") << "[PedeSteerer::createSteerFile]" 
00642                                             << "Could not open " << realName 
00643                                             << " as output file.";
00644   } else if (addToList) {
00645     mySteeringFiles.push_back(realName); // keep track
00646   }
00647 
00648   return result;
00649 }
00650 
00651 
00652 //_________________________________________________________________________
00653 std::string PedeSteerer::fileName(const std::string &addendum) const
00654 {
00655 
00656   std::string name(myDirectory);
00657   name += myConfig.getParameter<std::string>("steerFile");
00658   name += addendum;
00659   name += ".txt";
00660 
00661   return name;
00662 }
00663 
00664 //___________________________________________________________________________
00665 void PedeSteerer::buildSubSteer(AlignableTracker *aliTracker, AlignableMuon *aliMuon, AlignableExtras *aliExtras)
00666 {
00667   const std::vector<Alignable*> &alis = myParameterStore->alignables();
00668 
00669   if (theCoordMaster && !theCoordDefiners.empty()) {
00670     const std::string nameCoordFile(this->fileName("Coord"));
00671     this->defineCoordinates(theCoordDefiners, theCoordMaster, nameCoordFile);
00672     edm::LogInfo("Alignment") << "@SUB=PedeSteerer::buildSubSteer" 
00673                               << theCoordDefiners.size() << " highest level objects define the "
00674                               << "coordinate system, steering file " << nameCoordFile << ".";
00675   }
00676 
00677   const std::string nameFixFile(this->fileName("FixPara"));
00678   const std::pair<unsigned int, unsigned int> nFixFixCor(this->fixParameters(alis, nameFixFile));
00679   if (nFixFixCor.first != 0 || nFixFixCor.second != 0) {
00680     edm::LogInfo("Alignment") << "@SUB=PedeSteerer::buildSubSteer" 
00681                               << nFixFixCor.first << " parameters fixed at 0. and "
00682                               << nFixFixCor.second << " at 'original' position, "
00683                               << "steering file " << nameFixFile << ".";
00684   } 
00685 
00686   if (this->buildNoHierarchyCollection(alis)) { // before hierarchyConstraints(..)
00687     edm::LogInfo("Alignment") << "@SUB=PedeSteerer::buildSubSteer"
00688                               << myNoHieraCollection.size()<<" alignables taken out of hierarchy.";
00689   }
00690 
00691   const std::string nameHierarchyFile(this->fileName("Hierarchy"));
00692   unsigned int nConstraint = this->hierarchyConstraints(alis, nameHierarchyFile);
00693   if (nConstraint) {
00694     edm::LogInfo("Alignment") << "@SUB=PedeSteerer::buildSubSteer" 
00695                               << "Hierarchy constraints for " << nConstraint << " alignables, "
00696                               << "steering file " << nameHierarchyFile << ".";
00697   }
00698 
00699   const std::string namePresigmaFile(this->fileName("Presigma"));
00700   unsigned int nPresigma = 
00701     this->presigmas(myConfig.getParameter<std::vector<edm::ParameterSet> >("Presigmas"),
00702                     namePresigmaFile, alis, aliTracker, aliMuon, aliExtras);
00703   if (nPresigma) {
00704     edm::LogInfo("Alignment") << "@SUB=PedeSteerer::buildSubSteer" 
00705                               << "Presigma values set for " << nPresigma << " parameters, "
00706                               << "steering file " << namePresigmaFile << ".";
00707   }
00708 
00709   // Delete all SelectionUserVariables now? They will anyway be overwritten by MillePedeVariables...
00710 }
00711 
00712 //_________________________________________________________________________
00713 std::string PedeSteerer::buildMasterSteer(const std::vector<std::string> &binaryFiles)
00714 {
00715   const std::string nameMasterSteer(this->fileName("Master"));
00716   std::ofstream *mainSteerPtr = this->createSteerFile(nameMasterSteer, false);
00717   if (!mainSteerPtr) return "";
00718 
00719   // add external steering files, if any
00720   std::vector<std::string> addfiles =  myConfig.getParameter<std::vector<std::string> >("additionalSteerFiles");
00721   mySteeringFiles.insert(mySteeringFiles.end(),
00722                   addfiles.begin(),
00723                   addfiles.end());
00724 
00725   // add steering files to master steering file
00726   std::ofstream &mainSteerRef = *mainSteerPtr;
00727   for (unsigned int iFile = 0; iFile < mySteeringFiles.size(); ++iFile) {
00728     mainSteerRef << mySteeringFiles[iFile] << "\n";
00729   }
00730 
00731   // add binary files to master steering file
00732   mainSteerRef << "\nCfiles\n";
00733   for (unsigned int iFile = 0; iFile < binaryFiles.size(); ++iFile) {
00734     mainSteerRef << binaryFiles[iFile] << "\n";
00735   }
00736 
00737   // add method
00738   mainSteerRef << "\nmethod  " << myConfig.getParameter<std::string>("method") << "\n";
00739 
00740   // add further options
00741   const std::vector<std::string> opt(myConfig.getParameter<std::vector<std::string> >("options"));
00742   mainSteerRef << "\n* Outlier treatment and other options \n";
00743   for (unsigned int i = 0; i < opt.size(); ++i) {
00744     mainSteerRef << opt[i] << "\n";
00745   }
00746 
00747   delete mainSteerPtr;  // close (and flush) again
00748 
00749   return nameMasterSteer;
00750 }
00751 
00752 //_________________________________________________________________________
00753 int PedeSteerer::runPede(const std::string &masterSteer) const
00754 {
00755   if (masterSteer.empty()) {
00756     edm::LogError("Alignment") << "@SUB=PedeSteerer::runPede" << "Empty master steer file, stop";
00757     return 0; //false;
00758   }
00759 
00760   std::string command(myConfig.getUntrackedParameter<std::string>("pedeCommand"));
00761   (command += " ") += masterSteer;
00762   const std::string dump(myConfig.getUntrackedParameter<std::string>("pedeDump"));
00763   if (!dump.empty()) {
00764     command += " > ";
00765     (command += myDirectory) += dump;
00766   }
00767 
00768   edm::LogInfo("Alignment") << "@SUB=PedeSteerer::runPede" << "Start running " << command;
00769   // FIXME: Recommended interface to system commands?
00770   int shellReturn = gSystem->Exec(command.c_str());
00771   edm::LogInfo("Alignment") << "@SUB=PedeSteerer::runPede" << "Command returns " << shellReturn;
00772 
00773   return shellReturn;
00774 }