CMS 3D CMS Logo

MillePedeAlignmentAlgorithm.cc

Go to the documentation of this file.
00001 
00011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00012 
00013 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00014 // in header, too
00015 // end in header, too
00016 
00017 #include "Alignment/MillePedeAlignmentAlgorithm/interface/MillePedeMonitor.h"
00018 #include "Alignment/MillePedeAlignmentAlgorithm/interface/MillePedeAlignmentAlgorithm.h"
00019 #include "Alignment/MillePedeAlignmentAlgorithm/interface/MillePedeVariables.h"
00020 #include "Alignment/MillePedeAlignmentAlgorithm/interface/MillePedeVariablesIORoot.h"
00021 #include "Mille.h"       // 'unpublished' interface located in src
00022 #include "PedeSteerer.h" // dito
00023 #include "PedeReader.h" // dito
00024 #include "PedeLabeler.h" // dito
00025 
00026 #include "Alignment/ReferenceTrajectories/interface/TrajectoryFactoryBase.h"
00027 #include "Alignment/ReferenceTrajectories/interface/TrajectoryFactoryPlugin.h"
00028 
00029 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterStore.h"
00030 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentIORoot.h"
00031 
00032 #include "Alignment/CommonAlignment/interface/AlignableNavigator.h"
00033 #include "Alignment/CommonAlignment/interface/AlignableDetOrUnitPtr.h"
00034 
00035 // includes to make known that they inherit from Alignable:
00036 #include "Alignment/TrackerAlignment/interface/AlignableTracker.h"
00037 #include "Alignment/MuonAlignment/interface/AlignableMuon.h"
00038 
00039 #include "DataFormats/CLHEP/interface/AlgebraicObjects.h"
00040 #include "DataFormats/TrackReco/interface/Track.h"
00041 
00042 
00043 #include <Geometry/CommonDetUnit/interface/GeomDetUnit.h>
00044 #include <Geometry/CommonDetUnit/interface/GeomDetType.h>
00045 
00046 #include "DataFormats/TrackerRecHit2D/interface/ProjectedSiStripRecHit2D.h"
00047 
00048 #include <fstream>
00049 #include <sstream>
00050 #include <algorithm>
00051 
00052 #include <TMath.h>
00053 #include <TMatrixDSymEigen.h>
00054 typedef TransientTrackingRecHit::ConstRecHitContainer ConstRecHitContainer;
00055 typedef TransientTrackingRecHit::ConstRecHitPointer   ConstRecHitPointer;
00056 
00057 // Constructor ----------------------------------------------------------------
00058 //____________________________________________________
00059 MillePedeAlignmentAlgorithm::MillePedeAlignmentAlgorithm(const edm::ParameterSet &cfg) :
00060   AlignmentAlgorithmBase(cfg), 
00061   theConfig(cfg), theMode(this->decodeMode(theConfig.getUntrackedParameter<std::string>("mode"))),
00062   theDir(theConfig.getUntrackedParameter<std::string>("fileDir")),
00063   theAlignmentParameterStore(0), theAlignables(), theAlignableNavigator(0),
00064   theMonitor(0), theMille(0), thePedeLabels(0), thePedeSteer(0),
00065   theTrajectoryFactory(0),
00066   theMinNumHits(cfg.getParameter<int>("minNumHits")),
00067   theMaximalCor2D(cfg.getParameter<double>("max2Dcorrelation")),
00068   theUseTrackTsos(cfg.getParameter<bool>("useTrackTsos"))
00069 {
00070   if (!theDir.empty() && theDir.find_last_of('/') != theDir.size()-1) theDir += '/';// may need '/'
00071   edm::LogInfo("Alignment") << "@SUB=MillePedeAlignmentAlgorithm" << "Start in mode '"
00072                             << theConfig.getUntrackedParameter<std::string>("mode")
00073                             << "' with output directory '" << theDir << "'.";
00074 }
00075 
00076 // Destructor ----------------------------------------------------------------
00077 //____________________________________________________
00078 MillePedeAlignmentAlgorithm::~MillePedeAlignmentAlgorithm()
00079 {
00080   delete theAlignableNavigator;
00081   delete theMille;
00082   delete theMonitor;
00083   delete thePedeSteer;
00084   delete thePedeLabels;
00085   delete theTrajectoryFactory;
00086 }
00087 
00088 // Call at beginning of job ---------------------------------------------------
00089 //____________________________________________________
00090 void MillePedeAlignmentAlgorithm::initialize(const edm::EventSetup &setup, 
00091                                              AlignableTracker *tracker, AlignableMuon *muon,
00092                                              AlignmentParameterStore *store)
00093 {
00094   if (muon) {
00095     edm::LogWarning("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::initialize"
00096                                << "Running with AlignabeMuon not yet tested.";
00097   }
00098 
00099   theAlignableNavigator = new AlignableNavigator(tracker, muon);
00100   theAlignmentParameterStore = store;
00101   theAlignables = theAlignmentParameterStore->alignables();
00102   thePedeLabels = new PedeLabeler(tracker, muon);
00103 
00104   // 1) Create PedeSteerer: correct alignable positions for coordinate system selection
00105   edm::ParameterSet pedeSteerCfg(theConfig.getParameter<edm::ParameterSet>("pedeSteerer"));
00106   thePedeSteer = new PedeSteerer(tracker, muon, theAlignmentParameterStore, thePedeLabels,
00107                                  pedeSteerCfg, theDir, !this->isMode(myPedeSteerBit));
00108 
00109   // 2) If requested, directly read in and apply result of previous pede run,
00110   //    assuming that correction from 1) was also applied to create the result:
00111   if (theConfig.getParameter<bool>("readPedeInput")) {
00112     edm::LogInfo("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::initialize"
00113                               << "Apply MillePede constants defined by PSet 'pedeReaderInput'.";
00114     this->readFromPede("pedeReaderInput", false); // false: do not erase SelectionUserVariables
00115     theAlignmentParameterStore->applyParameters();
00116     // Following needed to shut up later warning from checkAliParams? Test!
00117     // theAlignmentParameterStore->resetParameters();  FIXME
00118   }
00119 
00120   // 3) Now create steerings with 'final' start position:
00121   thePedeSteer->buildSubSteer(tracker, muon);
00122 
00123   // After (!) 1-3 of PedeSteerer which uses the SelectionUserVariables attached to the parameters:
00124   this->buildUserVariables(theAlignables); // for hit statistics and/or pede result
00125 
00126   if (this->isMode(myMilleBit)) {
00127     if (!theConfig.getParameter<std::vector<std::string> >("mergeBinaryFiles").empty() ||
00128         !theConfig.getParameter<std::vector<std::string> >("mergeTreeFiles").empty()) {
00129       throw cms::Exception("BadConfig")
00130         << "'vstring mergeTreeFiles' and 'vstring mergeBinaryFiles' must be empty for "
00131         << "modes running mille.";
00132     }
00133     theMille = new Mille((theDir + theConfig.getParameter<std::string>("binaryFile")).c_str());
00134     const std::string moniFile(theConfig.getUntrackedParameter<std::string>("monitorFile"));
00135     if (moniFile.size()) theMonitor = new MillePedeMonitor((theDir + moniFile).c_str());
00136 
00137     // Get trajectory factory. In case nothing found, FrameWork will throw...
00138     const edm::ParameterSet fctCfg(theConfig.getParameter<edm::ParameterSet>("TrajectoryFactory"));
00139     const std::string fctName(fctCfg.getParameter<std::string>("TrajectoryFactoryName"));
00140     theTrajectoryFactory = TrajectoryFactoryPlugin::get()->create(fctName, fctCfg);
00141   }
00142 
00143   // FIXME: for PlotMillePede hit statistics stuff we also might want doIO(0)... ?
00144   if (this->isMode(myPedeSteerBit) // for pedeRun and pedeRead we might want to merge
00145       || !theConfig.getParameter<std::vector<std::string> >("mergeTreeFiles").empty()) {
00146     this->doIO(0);
00147   }
00148 }
00149 
00150 // Call at end of job ---------------------------------------------------------
00151 //____________________________________________________
00152 void MillePedeAlignmentAlgorithm::terminate()
00153 {
00154   delete theMille;// delete to close binary before running pede below (flush would be enough...)
00155   theMille = 0;
00156 
00157   std::vector<std::string> files;
00158   if (this->isMode(myMilleBit) || !theConfig.getParameter<std::string>("binaryFile").empty()) {
00159     files.push_back(theDir + theConfig.getParameter<std::string>("binaryFile"));
00160   } else {
00161     const std::vector<std::string> plainFiles
00162       (theConfig.getParameter<std::vector<std::string> >("mergeBinaryFiles"));
00163     for (std::vector<std::string>::const_iterator i = plainFiles.begin(), iEnd = plainFiles.end();
00164          i != iEnd; ++i) {
00165       files.push_back(theDir + *i);
00166     }
00167   }
00168   const std::string masterSteer(thePedeSteer->buildMasterSteer(files));// do only if myPedeSteerBit?
00169   bool pedeOk = true;
00170   if (this->isMode(myPedeRunBit)) {
00171     pedeOk = thePedeSteer->runPede(masterSteer);
00172   }
00173   
00174   if (this->isMode(myPedeReadBit)) {
00175     if (!pedeOk || !this->readFromPede("pedeReader", true)) {
00176       edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::terminate"
00177                                  << "Problems running pede or reading result, but applying!";
00178     }
00179     // FIXME: problem if what is read in does not correspond to store
00180     theAlignmentParameterStore->applyParameters();
00181     // thePedeSteer->correctToReferenceSystem(); // Already done before, here for possible rounding reasons...??
00182   }
00183 
00184   if (this->isMode(myMilleBit)) { // if mille was run, we store trees with suffix _1...
00185     this->doIO(1);
00186   } else if (this->isMode(myPedeReadBit)) {// if pede runs otherwise, we use _2 (=> probably merge)
00187     this->doIO(2);
00188   }
00189 
00190   // FIXME: should we delete here or in destructor?
00191   delete theAlignableNavigator;
00192   theAlignableNavigator = 0;
00193   delete theMonitor;
00194   theMonitor = 0;
00195   delete thePedeSteer;
00196   thePedeSteer = 0;
00197   delete thePedeLabels;
00198   thePedeLabels = 0;
00199   delete theTrajectoryFactory;
00200   theTrajectoryFactory = 0;
00201 }
00202 
00203 // Run the algorithm on trajectories and tracks -------------------------------
00204 //____________________________________________________
00205 void MillePedeAlignmentAlgorithm::run(const edm::EventSetup &setup,
00206                                       const ConstTrajTrackPairCollection &tracks) 
00207 {
00208   if (!this->isMode(myMilleBit)) return; // no theMille created...
00209 
00210   typedef TrajectoryFactoryBase::ReferenceTrajectoryCollection RefTrajColl;
00211   const RefTrajColl trajectories(theTrajectoryFactory->trajectories(setup, tracks));
00212   // Assume that same container size means same order... :-(
00213   const bool canUseTrack = (trajectories.size() == tracks.size());
00214   const bool useTrackTsosBack = theUseTrackTsos;
00215   if (!canUseTrack) theUseTrackTsos = false;
00216 
00217   std::vector<TrajectoryStateOnSurface> trackTsos; // some buffer...
00218   // loop over ReferenceTrajectoryCollection and possibly over tracks  
00219   ConstTrajTrackPairCollection::const_iterator iTrajTrack = tracks.begin();
00220   for (RefTrajColl::const_iterator iRefTraj = trajectories.begin(), iRefTrajE = trajectories.end();
00221        iRefTraj != iRefTrajE; ++iRefTraj) {
00222 
00223     RefTrajColl::value_type refTrajPtr = *iRefTraj; 
00224     if (theMonitor) theMonitor->fillRefTrajectory(refTrajPtr);
00225     if (!refTrajPtr->isValid()) continue; // currently e.g. if any invalid hit (FIXME for cosmic?)
00226     
00227     if (canUseTrack) {
00228       if (!this->orderedTsos((*iTrajTrack).first, trackTsos)) continue; // first is Trajectory*
00229       if (theMonitor) theMonitor->fillTrack((*iTrajTrack).second); // second is reco::Track*
00230     } else {
00231       trackTsos.clear();
00232       trackTsos.resize((*iTrajTrack).second->recHitsSize());
00233     }
00234 
00235     std::vector<AlignmentParameters*> parVec(refTrajPtr->recHits().size());//to add hits if all fine
00236     std::vector<bool> validHitVecY(refTrajPtr->recHits().size()); // collect hit statistics...
00237     int nValidHitsX = 0;                                // ...assuming that there are no y-only hits
00238     // Use recHits from ReferenceTrajectory (since they have the right order!):
00239     for (unsigned int iHit = 0; iHit < refTrajPtr->recHits().size(); ++iHit) {
00240       const int flagXY = this->addMeasurementData(refTrajPtr,iHit,trackTsos[iHit],parVec[iHit]);
00241       if (flagXY < 0) { // problem
00242         nValidHitsX = -1;
00243         break;
00244       } else { // hit is fine, increase x/y statistics
00245         if (flagXY >= 1) ++nValidHitsX;
00246         validHitVecY[iHit] = (flagXY >= 2);
00247       } 
00248     } // end loop on hits
00249     
00250     if (nValidHitsX >= theMinNumHits) { // enough 'good' alignables hit: increase the hit statistics
00251       unsigned int nValidHitsY = 0;
00252       for (unsigned int iHit = 0; iHit < validHitVecY.size(); ++iHit) {
00253         if (!parVec[iHit]) continue; // in case a non-selected alignable was hit (flagXY == 0)
00254         MillePedeVariables *mpVar = static_cast<MillePedeVariables*>(parVec[iHit]->userVariables());
00255         mpVar->increaseHitsX(); // every hit has an x-measurement, cf. above...
00256         if (validHitVecY[iHit]) {
00257           mpVar->increaseHitsY();
00258           ++nValidHitsY;
00259         }
00260       }
00261       theMille->end();
00262       if (canUseTrack && theMonitor) {
00263         theMonitor->fillUsedTrack((*iTrajTrack).second, nValidHitsX, nValidHitsY);
00264       }
00265     } else {
00266       theMille->kill();
00267     }
00268     if (canUseTrack) ++iTrajTrack;
00269   } // end of reference trajectory and track loop
00270 
00271   theUseTrackTsos = useTrackTsosBack;
00272 }
00273 
00274 //____________________________________________________
00275 int MillePedeAlignmentAlgorithm::addMeasurementData
00276 (const ReferenceTrajectoryBase::ReferenceTrajectoryPtr &refTrajPtr, unsigned int iHit,
00277  const TrajectoryStateOnSurface &trackTsos, AlignmentParameters *&params)
00278 {
00279   params = 0;
00280   theFloatBufferX.clear();
00281   theFloatBufferY.clear();
00282   theIntBuffer.clear();
00283  
00284   const TrajectoryStateOnSurface &tsos = 
00285     (theUseTrackTsos ? trackTsos : refTrajPtr->trajectoryStates()[iHit]);
00286   const ConstRecHitPointer &recHitPtr = refTrajPtr->recHits()[iHit];
00287   // get AlignableDet/Unit for this hit
00288   AlignableDetOrUnitPtr alidet(theAlignableNavigator->alignableFromGeomDet(recHitPtr->det()));
00289   if (!this->globalDerivativesHierarchy(tsos, alidet, alidet, theFloatBufferX, // 2x alidet, sic!
00290                                         theFloatBufferY, theIntBuffer, params)) {
00291     return -1; // problem
00292   } else if (theFloatBufferX.empty()) {
00293     return 0; // empty for X: no alignable for hit
00294   } else { 
00295     return this->callMille2D(refTrajPtr, iHit, theIntBuffer, theFloatBufferX, theFloatBufferY);
00296   }
00297 }
00298 
00299 //____________________________________________________
00300 bool MillePedeAlignmentAlgorithm
00301 ::globalDerivativesHierarchy(const TrajectoryStateOnSurface &tsos,
00302                              Alignable *ali, const AlignableDetOrUnitPtr &alidet,
00303                              std::vector<float> &globalDerivativesX,
00304                              std::vector<float> &globalDerivativesY,
00305                              std::vector<int> &globalLabels,
00306                              AlignmentParameters *&lowestParams) const
00307 {
00308   // derivatives and labels are recursively attached
00309   if (!ali) return true; // no mother might be OK
00310 
00311   if (false && theMonitor && alidet != ali) theMonitor->fillFrameToFrame(alidet, ali);
00312 
00313   AlignmentParameters *params = ali->alignmentParameters();
00314   if (params) {
00315     if (!lowestParams) lowestParams = params; // set parameters of lowest level
00316 
00317     const unsigned int alignableLabel = thePedeLabels->alignableLabel(ali);
00318     if (0 == alignableLabel) { // FIXME: what about regardAllHits in Markus' code?
00319       edm::LogWarning("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::globalDerivativesHierarchy"
00320                                    << "Label not found, skip Alignable.";
00321       return false;
00322     }
00323     
00324     const std::vector<bool> &selPars = params->selector();
00325     const AlgebraicMatrix derivs(params->derivatives(tsos, alidet));
00326     // cols: 2, i.e. x&y, rows: parameters, usually RigidBodyAlignmentParameters::N_PARAM
00327     for (unsigned int iSel = 0; iSel < selPars.size(); ++iSel) {
00328       if (selPars[iSel]) {
00329         globalDerivativesX.push_back(derivs[iSel][kLocalX]
00330                                      /thePedeSteer->cmsToPedeFactor(iSel));
00331         globalLabels.push_back(thePedeLabels->parameterLabel(alignableLabel, iSel));
00332         globalDerivativesY.push_back(derivs[iSel][kLocalY]
00333                                      /thePedeSteer->cmsToPedeFactor(iSel));
00334       }
00335     }
00336     // Exclude mothers if Alignable selected to be no part of a hierarchy:
00337     if (thePedeSteer->isNoHiera(ali)) return true;
00338   }
00339   // Call recursively for mother, will stop if mother == 0:
00340   return this->globalDerivativesHierarchy(tsos, ali->mother(), alidet,
00341                                           globalDerivativesX, globalDerivativesY,
00342                                           globalLabels, lowestParams);
00343 }
00344 
00345 // //____________________________________________________
00346 // void MillePedeAlignmentAlgorithm
00347 // ::callMille(const ReferenceTrajectoryBase::ReferenceTrajectoryPtr &refTrajPtr,
00348 //             unsigned int iTrajHit, MeasurementDirection xOrY,
00349 //             const std::vector<float> &globalDerivatives, const std::vector<int> &globalLabels)
00350 // {
00351 //   const unsigned int xyIndex = iTrajHit*2 + xOrY;
00352 //   // FIXME: here for residuum and sigma we could use KALMAN-Filter results
00353 //   const float residuum =
00354 //     refTrajPtr->measurements()[xyIndex] - refTrajPtr->trajectoryPositions()[xyIndex];
00355 //   const float covariance = refTrajPtr->measurementErrors()[xyIndex][xyIndex];
00356 //   const float sigma = (covariance > 0. ? TMath::Sqrt(covariance) : 0.);
00357 
00358 //   const AlgebraicMatrix &locDerivMatrix = refTrajPtr->derivatives();
00359 
00360 //   std::vector<float> localDerivs(locDerivMatrix.num_col());
00361 //   for (unsigned int i = 0; i < localDerivs.size(); ++i) {
00362 //     localDerivs[i] = locDerivMatrix[xyIndex][i];
00363 //   }
00364 
00365 //   // &(vector[0]) is valid - as long as vector is not empty 
00366 //   // cf. https://www.parashift.com/c++-faq-lite/containers.html#faq-34.3
00367 //   theMille->mille(localDerivs.size(), &(localDerivs[0]),
00368 //                globalDerivatives.size(), &(globalDerivatives[0]), &(globalLabels[0]),
00369 //                residuum, sigma);
00370 //   if (theMonitor) {
00371 //     theMonitor->fillDerivatives(refTrajPtr->recHits()[iTrajHit],localDerivs, globalDerivatives,
00372 //                              (xOrY == kLocalY));
00373 //     theMonitor->fillResiduals(refTrajPtr->recHits()[iTrajHit],
00374 //                            refTrajPtr->trajectoryStates()[iTrajHit],
00375 //                            iTrajHit, residuum, sigma, (xOrY == kLocalY));
00376 //   }
00377 // }
00378 
00379 //____________________________________________________
00380 bool MillePedeAlignmentAlgorithm::is2D(const ConstRecHitPointer &recHit) const
00381 {
00382   // FIXME: Check whether this is a reliable and recommended way to find out...
00383 
00384   if (recHit->dimension() < 2) {
00385     return false; // some muon stuff really has RecHit1D
00386   } else if (recHit->detUnit()) { // detunit in strip is 1D, in pixel 2D 
00387     return recHit->detUnit()->type().isTrackerPixel();
00388   } else { // stereo strips  (FIXME: endcap trouble due to non-parallel strips (wedge sensors)?)
00389     if (dynamic_cast<const ProjectedSiStripRecHit2D*>(recHit->hit())) { // check persistent hit
00390       // projected: 1D measurement on 'glued' module
00391       return false;
00392     } else {
00393       return true;
00394     }
00395   }
00396 }
00397 
00398 //__________________________________________________________________________________________________
00399 bool MillePedeAlignmentAlgorithm::readFromPede(const std::string &psetName, bool setUserVars)
00400 {
00401   bool allEmpty = this->areEmptyParams(theAlignables);
00402   
00403   PedeReader reader(theConfig.getParameter<edm::ParameterSet>(psetName),
00404                     *thePedeSteer, *thePedeLabels);
00405   std::vector<Alignable*> alis;
00406   bool okRead = reader.read(alis, setUserVars);
00407   bool numMatch = true;
00408 
00409   std::stringstream out("Read ");
00410   out << alis.size() << " alignables";
00411   if (alis.size() != theAlignables.size()) {
00412     out << " while " << theAlignables.size() << " in store";
00413     numMatch = false; // FIXME: Should we check one by one? Or transfer 'alis' to the store?
00414   }
00415   if (!okRead) out << ", but problems in reading"; 
00416   if (!allEmpty) out << ", possibly overwriting previous settings";
00417   out << ".";
00418 
00419   if (okRead && allEmpty && numMatch) {
00420     edm::LogInfo("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::readFromPede" << out.str();
00421     return true;
00422   } else {
00423     edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::readFromPede" << out.str();
00424     return false;
00425   }
00426 }
00427 
00428 //__________________________________________________________________________________________________
00429 bool MillePedeAlignmentAlgorithm::areEmptyParams(const std::vector<Alignable*> &alignables) const
00430 {
00431   
00432   for (std::vector<Alignable*>::const_iterator iAli = alignables.begin();
00433        iAli != alignables.end(); ++iAli) {
00434     const AlignmentParameters *params = (*iAli)->alignmentParameters();
00435     if (params) {
00436       const AlgebraicVector &parVec(params->parameters());
00437       const AlgebraicMatrix &parCov(params->covariance());
00438       for (int i = 0; i < parVec.num_row(); ++i) {
00439         if (parVec[i] != 0.) return false;
00440         for (int j = i; j < parCov.num_col(); ++j) {
00441           if (parCov[i][j] != 0.) return false;
00442         }
00443       }
00444     }
00445   }
00446   
00447   return true;
00448 }
00449 
00450 //__________________________________________________________________________________________________
00451 unsigned int MillePedeAlignmentAlgorithm::doIO(int loop) const
00452 {
00453   unsigned int result = 0;
00454 
00455   const std::string outFilePlain(theConfig.getParameter<std::string>("treeFile"));
00456   if (outFilePlain.empty()) {
00457     edm::LogInfo("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::doIO"
00458                               << "treeFile parameter empty => skip writing for 'loop' " << loop;
00459     return result;
00460   }
00461 
00462   const std::string outFile(theDir + outFilePlain);
00463 
00464   AlignmentIORoot aliIO;
00465   int ioerr = 0;
00466   if (loop == 0) {
00467     aliIO.writeAlignableOriginalPositions(theAlignables, outFile.c_str(), loop, false, ioerr);
00468     if (ioerr) {
00469       edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::doIO"
00470                                  << "Problem " << ioerr << " in writeAlignableOriginalPositions";
00471       ++result;
00472     }
00473   } else {
00474     if (loop > 1) {
00475       const std::vector<std::string> inFiles
00476         (theConfig.getParameter<std::vector<std::string> >("mergeTreeFiles"));
00477       const std::vector<std::string> binFiles
00478         (theConfig.getParameter<std::vector<std::string> >("mergeBinaryFiles"));
00479       if (inFiles.size() != binFiles.size()) {
00480         edm::LogWarning("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::doIO"
00481                                      << "'vstring mergeTreeFiles' and 'vstring mergeBinaryFiles' "
00482                                      << "differ in size";
00483       }
00484       this->addHitStatistics(loop - 1, outFile, inFiles);
00485     }
00486     MillePedeVariablesIORoot millePedeIO;
00487     millePedeIO.writeMillePedeVariables(theAlignables, outFile.c_str(), loop, false, ioerr);
00488     if (ioerr) {
00489       edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::doIO"
00490                                  << "Problem " << ioerr << " writing MillePedeVariables";
00491       ++result;
00492     }
00493 // // problem with following writeOrigRigidBodyAlignmentParameters
00494 //     aliIO.writeAlignmentParameters(theAlignables, outFile.c_str(), loop, false, ioerr);
00495 //     if (ioerr) {
00496 //       edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::doIO"
00497 //                                  << "Problem " << ioerr << " in writeAlignmentParameters, " << loop;
00498 //       ++result;
00499 //     }
00500   }
00501   
00502   aliIO.writeOrigRigidBodyAlignmentParameters(theAlignables, outFile.c_str(), loop, false, ioerr);
00503   if (ioerr) {
00504     edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::doIO" << "Problem " << ioerr
00505                                << " in writeOrigRigidBodyAlignmentParameters, " << loop;
00506     ++result;
00507   }
00508   aliIO.writeAlignableAbsolutePositions(theAlignables, outFile.c_str(), loop, false, ioerr);
00509   if (ioerr) {
00510     edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::doIO" << "Problem " << ioerr
00511                                << " in writeAlignableAbsolutePositions, " << loop;
00512     ++result;
00513   }
00514   aliIO.writeAlignableRelativePositions(theAlignables, outFile.c_str(), loop, false, ioerr);
00515   if (ioerr) {
00516     edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::doIO" << "Problem " << ioerr
00517                                << " in writeAlignableRelativePositions, " << loop;
00518     ++result;
00519   }
00520 
00521   return result;
00522 }
00523 
00524 //__________________________________________________________________________________________________
00525 void MillePedeAlignmentAlgorithm::buildUserVariables(const std::vector<Alignable*> &alis) const
00526 {
00527   for (std::vector<Alignable*>::const_iterator iAli = alis.begin(); iAli != alis.end(); ++iAli) {
00528     AlignmentParameters *params = (*iAli)->alignmentParameters();
00529     if (!params) {
00530       throw cms::Exception("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::buildUserVariables"
00531                                         << "No parameters for alignable";
00532     }
00533     params->setUserVariables(new MillePedeVariables(params->size()));
00534   }
00535 }
00536 
00537 //__________________________________________________________________________________________________
00538 unsigned int MillePedeAlignmentAlgorithm::decodeMode(const std::string &mode) const
00539 {
00540   if (mode == "full") {
00541     return myMilleBit + myPedeSteerBit + myPedeRunBit + myPedeReadBit;
00542   } else if (mode == "mille") {
00543     return myMilleBit; // + myPedeSteerBit; // sic! Including production of steerig file. NO!
00544   } else if (mode == "pede") {
00545     return myPedeSteerBit + myPedeRunBit + myPedeReadBit;
00546   } else if (mode == "pedeSteer") {
00547     return myPedeSteerBit;
00548   } else if (mode == "pedeRun") {
00549     return myPedeSteerBit + myPedeRunBit + myPedeReadBit; // sic! Including steering and reading of result.
00550   } else if (mode == "pedeRead") {
00551     return myPedeReadBit;
00552   }
00553 
00554   throw cms::Exception("BadConfig") 
00555     << "Unknown mode '" << mode  
00556     << "', use 'full', 'mille', 'pede', 'pedeRun', 'pedeSteer' or 'pedeRead'.";
00557 
00558   return 0;
00559 }
00560 
00561 //__________________________________________________________________________________________________
00562 bool MillePedeAlignmentAlgorithm::addHitStatistics(int fromLoop, const std::string &outFile,
00563                                                    const std::vector<std::string> &inFiles) const
00564 {
00565   bool allOk = true;
00566   int ierr = 0;
00567   MillePedeVariablesIORoot millePedeIO;
00568   if (inFiles.empty()) {
00569     const std::vector<AlignmentUserVariables*> mpVars =
00570       millePedeIO.readMillePedeVariables(theAlignables, outFile.c_str(), fromLoop, ierr);
00571     if (ierr || !this->addHits(theAlignables, mpVars)) {
00572       edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::addHitStatistics"
00573                                  << "Error " << ierr << " reading from " << outFile 
00574                                  << ", tree " << fromLoop << ", or problems in addHits";
00575       allOk = false;
00576     }
00577     for (std::vector<AlignmentUserVariables*>::const_iterator i = mpVars.begin();
00578          i != mpVars.end(); ++i){
00579       delete *i; // clean created objects
00580     }
00581   } else {
00582     for (std::vector<std::string>::const_iterator iFile = inFiles.begin();
00583          iFile != inFiles.end(); ++iFile) {
00584       const std::string inFile(theDir + *iFile); 
00585       const std::vector<AlignmentUserVariables*> mpVars =
00586         millePedeIO.readMillePedeVariables(theAlignables, inFile.c_str(), fromLoop, ierr);
00587       if (ierr || !this->addHits(theAlignables, mpVars)) {
00588         edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::addHitStatistics"
00589                                    << "Error " << ierr << " reading from " << inFile 
00590                                    << ", tree " << fromLoop << ", or problems in addHits";
00591         allOk = false;
00592       }
00593       for (std::vector<AlignmentUserVariables*>::const_iterator i = mpVars.begin();
00594            i != mpVars.end(); ++i) {
00595         delete *i; // clean created objects
00596       }
00597     }
00598   }
00599 
00600   return allOk;
00601 }
00602 
00603 //__________________________________________________________________________________________________
00604 bool MillePedeAlignmentAlgorithm::addHits(const std::vector<Alignable*> &alis,
00605                                           const std::vector<AlignmentUserVariables*> &mpVars) const
00606 {
00607   bool allOk = (mpVars.size() == alis.size());
00608   std::vector<AlignmentUserVariables*>::const_iterator iUser = mpVars.begin();
00609   for (std::vector<Alignable*>::const_iterator iAli = alis.begin(); 
00610        iAli != alis.end() && iUser != mpVars.end(); ++iAli, ++iUser) {
00611     MillePedeVariables *mpVarNew = dynamic_cast<MillePedeVariables*>(*iUser);
00612     AlignmentParameters *ps = (*iAli)->alignmentParameters();
00613     MillePedeVariables *mpVarOld = (ps ? dynamic_cast<MillePedeVariables*>(ps->userVariables()) : 0);
00614     if (!mpVarNew || !mpVarOld || mpVarOld->size() != mpVarNew->size()) {
00615       allOk = false;
00616       continue; // FIXME error etc.?
00617     }
00618 
00619     mpVarOld->increaseHitsX(mpVarNew->hitsX());
00620     mpVarOld->increaseHitsY(mpVarNew->hitsY());
00621   }
00622   
00623   return allOk;
00624 }
00625 
00626 
00627 //__________________________________________________________________________________________________
00628 bool MillePedeAlignmentAlgorithm::orderedTsos(const Trajectory *traj, 
00629                                               std::vector<TrajectoryStateOnSurface> &trackTsos)const
00630 {
00631   trackTsos.clear();
00632   // FIXME: if (theUseTrackTsos == false) fill only first/last!
00633   Trajectory::DataContainer trajMeas(traj->measurements());
00634   PropagationDirection dir = traj->direction();
00635   if (dir == oppositeToMomentum) {
00636     // why does const_reverse_operator not compile?
00637     for (Trajectory::DataContainer::reverse_iterator rMeas = trajMeas.rbegin();
00638          rMeas != trajMeas.rend(); ++rMeas) {
00639       trackTsos.push_back((*rMeas).updatedState());
00640     }
00641   } else if (dir == alongMomentum) {
00642     for (Trajectory::DataContainer::const_iterator iMeas = trajMeas.begin();
00643          iMeas != trajMeas.end(); ++iMeas) {
00644       trackTsos.push_back((*iMeas).updatedState());
00645     }
00646   } else {
00647     edm::LogError("Alignment") << "$SUB=MillePedeAlignmentAlgorithm::orderedTsos"
00648                                << "Trajectory neither along nor opposite to momentum.";
00649     return false;
00650   }
00651 
00652   for (std::vector<TrajectoryStateOnSurface>::const_iterator iTraj = trackTsos.begin(),
00653          iEnd = trackTsos.end(); iTraj != iEnd; ++iTraj) {
00654     if (!(*iTraj).isValid()) {
00655       edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::orderedTsos"
00656                                  << "an invalid  TSOS...?";
00657       return false;
00658     }
00659   }
00660   
00661 
00662   return true;
00663 }
00664 
00665 //__________________________________________________________________________________________________
00666 void MillePedeAlignmentAlgorithm::makeGlobDerivMatrix(const std::vector<float> &globalDerivativesx,
00667                                                       const std::vector<float> &globalDerivativesy,
00668                                                       TMatrixF &aGlobalDerivativesM)
00669 {
00670 
00671   for (unsigned int i = 0; i < globalDerivativesx.size(); ++i) {
00672     aGlobalDerivativesM(0,i) = globalDerivativesx[i];
00673     aGlobalDerivativesM(1,i) = globalDerivativesy[i]; 
00674   }
00675 }
00676 
00677 //__________________________________________________________________________________________________
00678 void MillePedeAlignmentAlgorithm::diagonalize
00679 (TMatrixDSym &aHitCovarianceM, TMatrixF &aLocalDerivativesM, TMatrixF &aHitResidualsM,
00680  TMatrixF &aGlobalDerivativesM) const
00681 {
00682   TMatrixDSymEigen myDiag(aHitCovarianceM);
00683   TMatrixD aTranfoToDiagonalSystem = myDiag.GetEigenVectors();
00684   TMatrixD aTranfoToDiagonalSystemInv = myDiag.GetEigenVectors( );
00685   TMatrixF aTranfoToDiagonalSystemInvF = myDiag.GetEigenVectors( );
00686   TMatrixD aMatrix = aTranfoToDiagonalSystemInv.Invert() * aHitCovarianceM * aTranfoToDiagonalSystem;
00687   aHitCovarianceM = TMatrixDSym(2, aMatrix.GetMatrixArray());
00688   aTranfoToDiagonalSystemInvF.Invert();
00689   //edm::LogInfo("Alignment") << "NEW HIT loca in matrix"<<aLocalDerivativesM(0,0);
00690   aLocalDerivativesM = aTranfoToDiagonalSystemInvF * aLocalDerivativesM;
00691   
00692   //edm::LogInfo("Alignment") << "NEW HIT loca in matrix after diag:"<<aLocalDerivativesM(0,0);
00693   aHitResidualsM      = aTranfoToDiagonalSystemInvF * aHitResidualsM;
00694   aGlobalDerivativesM = aTranfoToDiagonalSystemInvF * aGlobalDerivativesM;
00695 }
00696 
00697 //__________________________________________________________________________________________________
00698 void MillePedeAlignmentAlgorithm
00699 ::addRefTrackData2D(const ReferenceTrajectoryBase::ReferenceTrajectoryPtr &refTrajPtr,
00700                     unsigned int iTrajHit, TMatrixDSym &aHitCovarianceM,
00701                     TMatrixF &aHitResidualsM, TMatrixF &aLocalDerivativesM)
00702 {
00703 
00704   // This Method is valid for 2D measurements only
00705   
00706   const unsigned int xIndex = iTrajHit*2;
00707   const unsigned int yIndex = iTrajHit*2+1;
00708   // Covariance into a TMatrixDSym
00709   
00710   //aHitCovarianceM = new TMatrixDSym(2);
00711   aHitCovarianceM(0,0)=refTrajPtr->measurementErrors()[xIndex][xIndex];
00712   aHitCovarianceM(0,1)=refTrajPtr->measurementErrors()[xIndex][yIndex];
00713   aHitCovarianceM(1,0)=refTrajPtr->measurementErrors()[yIndex][xIndex];
00714   aHitCovarianceM(1,1)=refTrajPtr->measurementErrors()[yIndex][yIndex];
00715   
00716   //theHitResidualsM= new TMatrixF(2,1);
00717   aHitResidualsM(0,0)= refTrajPtr->measurements()[xIndex] - refTrajPtr->trajectoryPositions()[xIndex];
00718   aHitResidualsM(1,0)= refTrajPtr->measurements()[yIndex] - refTrajPtr->trajectoryPositions()[yIndex];
00719   
00720   // Local Derivatives into a TMatrixDSym (to use matrix operations)
00721   const AlgebraicMatrix &locDerivMatrix = refTrajPtr->derivatives();
00722   //  theLocalDerivativeNumber = locDerivMatrix.num_col();
00723   
00724   //theLocalDerivativesM = new TMatrixF(2,locDerivMatrix.num_col());
00725   for (int i = 0; i < locDerivMatrix.num_col(); ++i) {
00726     aLocalDerivativesM(0,i) = locDerivMatrix[xIndex][i];
00727     aLocalDerivativesM(1,i) = locDerivMatrix[yIndex][i];
00728   }
00729 }
00730 
00731 //__________________________________________________________________________________________________
00732 int MillePedeAlignmentAlgorithm
00733 ::callMille2D(const ReferenceTrajectoryBase::ReferenceTrajectoryPtr &refTrajPtr,
00734               unsigned int iTrajHit, const std::vector<int> &globalLabels,
00735               const std::vector<float> &globalDerivativesx,
00736               const std::vector<float> &globalDerivativesy)
00737 {
00738   const ConstRecHitPointer aRecHit(refTrajPtr->recHits()[iTrajHit]);
00739   if((aRecHit)->dimension() != 2) {
00740     edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::callMille2D"
00741                                << "You try to call method for 2D hits for a " 
00742                                << (aRecHit)->dimension()
00743                                <<  "D Hit. Hit gets ignored!";
00744     return -1;
00745   }
00746 
00747   TMatrixDSym aHitCovarianceM(2);
00748   TMatrixF aHitResidualsM(2,1);
00749   TMatrixF aLocalDerivativesM(2, refTrajPtr->derivatives().num_col());
00750   // below method fills above 3 matrices
00751   this->addRefTrackData2D(refTrajPtr, iTrajHit, aHitCovarianceM,aHitResidualsM,aLocalDerivativesM);
00752   TMatrixF aGlobalDerivativesM(2,globalDerivativesx.size());
00753   this->makeGlobDerivMatrix(globalDerivativesx, globalDerivativesy, aGlobalDerivativesM);
00754  
00755   // calculates correlation between Hit measurements
00756   const double corr = aHitCovarianceM(0,1) / sqrt(aHitCovarianceM(0,0) * aHitCovarianceM(1,1));
00757   bool diag = false;
00758   if (TMath::Abs(corr) > theMaximalCor2D) {
00759     this->diagonalize(aHitCovarianceM, aLocalDerivativesM, aHitResidualsM, aGlobalDerivativesM);
00760     diag = true;
00761   }
00762 
00763   float newResidX = aHitResidualsM(0,0);
00764   float newResidY = aHitResidualsM(1,0);
00765   float newHitErrX = TMath::Sqrt(aHitCovarianceM(0,0));
00766   float newHitErrY = TMath::Sqrt(aHitCovarianceM(1,1));
00767   float *newLocalDerivsX = aLocalDerivativesM[0].GetPtr();
00768   float *newLocalDerivsY = aLocalDerivativesM[1].GetPtr();
00769   float *newGlobDerivsX  = aGlobalDerivativesM[0].GetPtr();
00770   float *newGlobDerivsY  = aGlobalDerivativesM[1].GetPtr();
00771   const int nLocal  = aLocalDerivativesM.GetNcols();
00772   const int nGlobal = aGlobalDerivativesM.GetNcols();
00773 
00774   if (diag && (newHitErrX > newHitErrY)) { // also for 2D hits?
00775     // measurement with smaller error is x-measurement (for !is2D do not fill y-measurement):
00776     std::swap(newResidX, newResidY);
00777     std::swap(newHitErrX, newHitErrY);
00778     std::swap(newLocalDerivsX, newLocalDerivsY);
00779     std::swap(newGlobDerivsX, newGlobDerivsY);
00780   }
00781   
00782   // &(globalLabels[0]) is valid - as long as vector is not empty 
00783   // cf. https://www.parashift.com/c++-faq-lite/containers.html#faq-34.3
00784   theMille->mille(nLocal, newLocalDerivsX, nGlobal, newGlobDerivsX,
00785                   &(globalLabels[0]), newResidX, newHitErrX);
00786   if (theMonitor) {
00787     theMonitor->fillDerivatives(aRecHit, newLocalDerivsX, nLocal, newGlobDerivsX, nGlobal);
00788     theMonitor->fillResiduals(aRecHit, refTrajPtr->trajectoryStates()[iTrajHit],
00789                               iTrajHit, newResidX, newHitErrX, false);
00790   }
00791   const bool isReal2DHit = this->is2D(aRecHit); // strip is 1D (except matched hits)
00792   if (isReal2DHit) {
00793     theMille->mille(nLocal, newLocalDerivsY, nGlobal, newGlobDerivsY,
00794                     &(globalLabels[0]), newResidY, newHitErrY);
00795     if (theMonitor) {
00796       theMonitor->fillDerivatives(aRecHit, newLocalDerivsY, nLocal, newGlobDerivsY, nGlobal);
00797       theMonitor->fillResiduals(aRecHit, refTrajPtr->trajectoryStates()[iTrajHit],
00798                                 iTrajHit, newResidY, newHitErrY, true);// true: y
00799     }
00800   }
00801 
00802   return (isReal2DHit ? 2 : 1);
00803 }

Generated on Tue Jun 9 17:24:11 2009 for CMSSW by  doxygen 1.5.4