00001
00011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00012
00013 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00014
00015
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"
00022 #include "PedeSteerer.h"
00023 #include "PedeReader.h"
00024 #include "PedeLabeler.h"
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
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
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 += '/';
00071 edm::LogInfo("Alignment") << "@SUB=MillePedeAlignmentAlgorithm" << "Start in mode '"
00072 << theConfig.getUntrackedParameter<std::string>("mode")
00073 << "' with output directory '" << theDir << "'.";
00074 }
00075
00076
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
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
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
00110
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);
00115 theAlignmentParameterStore->applyParameters();
00116
00117
00118 }
00119
00120
00121 thePedeSteer->buildSubSteer(tracker, muon);
00122
00123
00124 this->buildUserVariables(theAlignables);
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
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
00144 if (this->isMode(myPedeSteerBit)
00145 || !theConfig.getParameter<std::vector<std::string> >("mergeTreeFiles").empty()) {
00146 this->doIO(0);
00147 }
00148 }
00149
00150
00151
00152 void MillePedeAlignmentAlgorithm::terminate()
00153 {
00154 delete theMille;
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));
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
00180 theAlignmentParameterStore->applyParameters();
00181
00182 }
00183
00184 if (this->isMode(myMilleBit)) {
00185 this->doIO(1);
00186 } else if (this->isMode(myPedeReadBit)) {
00187 this->doIO(2);
00188 }
00189
00190
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
00204
00205 void MillePedeAlignmentAlgorithm::run(const edm::EventSetup &setup,
00206 const ConstTrajTrackPairCollection &tracks)
00207 {
00208 if (!this->isMode(myMilleBit)) return;
00209
00210 typedef TrajectoryFactoryBase::ReferenceTrajectoryCollection RefTrajColl;
00211 const RefTrajColl trajectories(theTrajectoryFactory->trajectories(setup, tracks));
00212
00213 const bool canUseTrack = (trajectories.size() == tracks.size());
00214 const bool useTrackTsosBack = theUseTrackTsos;
00215 if (!canUseTrack) theUseTrackTsos = false;
00216
00217 std::vector<TrajectoryStateOnSurface> trackTsos;
00218
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;
00226
00227 if (canUseTrack) {
00228 if (!this->orderedTsos((*iTrajTrack).first, trackTsos)) continue;
00229 if (theMonitor) theMonitor->fillTrack((*iTrajTrack).second);
00230 } else {
00231 trackTsos.clear();
00232 trackTsos.resize((*iTrajTrack).second->recHitsSize());
00233 }
00234
00235 std::vector<AlignmentParameters*> parVec(refTrajPtr->recHits().size());
00236 std::vector<bool> validHitVecY(refTrajPtr->recHits().size());
00237 int nValidHitsX = 0;
00238
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) {
00242 nValidHitsX = -1;
00243 break;
00244 } else {
00245 if (flagXY >= 1) ++nValidHitsX;
00246 validHitVecY[iHit] = (flagXY >= 2);
00247 }
00248 }
00249
00250 if (nValidHitsX >= theMinNumHits) {
00251 unsigned int nValidHitsY = 0;
00252 for (unsigned int iHit = 0; iHit < validHitVecY.size(); ++iHit) {
00253 if (!parVec[iHit]) continue;
00254 MillePedeVariables *mpVar = static_cast<MillePedeVariables*>(parVec[iHit]->userVariables());
00255 mpVar->increaseHitsX();
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 }
00270
00271 theUseTrackTsos = useTrackTsosBack;
00272 }
00273
00274
00275 int MillePedeAlignmentAlgorithm::addMeasurementData
00276 (const ReferenceTrajectoryBase::ReferenceTrajectoryPtr &refTrajPtr, unsigned int iHit,
00277 const TrajectoryStateOnSurface &trackTsos, AlignmentParameters *¶ms)
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
00288 AlignableDetOrUnitPtr alidet(theAlignableNavigator->alignableFromGeomDet(recHitPtr->det()));
00289 if (!this->globalDerivativesHierarchy(tsos, alidet, alidet, theFloatBufferX,
00290 theFloatBufferY, theIntBuffer, params)) {
00291 return -1;
00292 } else if (theFloatBufferX.empty()) {
00293 return 0;
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
00309 if (!ali) return true;
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;
00316
00317 const unsigned int alignableLabel = thePedeLabels->alignableLabel(ali);
00318 if (0 == alignableLabel) {
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
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
00337 if (thePedeSteer->isNoHiera(ali)) return true;
00338 }
00339
00340 return this->globalDerivativesHierarchy(tsos, ali->mother(), alidet,
00341 globalDerivativesX, globalDerivativesY,
00342 globalLabels, lowestParams);
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 bool MillePedeAlignmentAlgorithm::is2D(const ConstRecHitPointer &recHit) const
00381 {
00382
00383
00384 if (recHit->dimension() < 2) {
00385 return false;
00386 } else if (recHit->detUnit()) {
00387 return recHit->detUnit()->type().isTrackerPixel();
00388 } else {
00389 if (dynamic_cast<const ProjectedSiStripRecHit2D*>(recHit->hit())) {
00390
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;
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
00494
00495
00496
00497
00498
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;
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;
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;
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;
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;
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
00633 Trajectory::DataContainer trajMeas(traj->measurements());
00634 PropagationDirection dir = traj->direction();
00635 if (dir == oppositeToMomentum) {
00636
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
00690 aLocalDerivativesM = aTranfoToDiagonalSystemInvF * aLocalDerivativesM;
00691
00692
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
00705
00706 const unsigned int xIndex = iTrajHit*2;
00707 const unsigned int yIndex = iTrajHit*2+1;
00708
00709
00710
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
00717 aHitResidualsM(0,0)= refTrajPtr->measurements()[xIndex] - refTrajPtr->trajectoryPositions()[xIndex];
00718 aHitResidualsM(1,0)= refTrajPtr->measurements()[yIndex] - refTrajPtr->trajectoryPositions()[yIndex];
00719
00720
00721 const AlgebraicMatrix &locDerivMatrix = refTrajPtr->derivatives();
00722
00723
00724
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
00751 this->addRefTrackData2D(refTrajPtr, iTrajHit, aHitCovarianceM,aHitResidualsM,aLocalDerivativesM);
00752 TMatrixF aGlobalDerivativesM(2,globalDerivativesx.size());
00753 this->makeGlobDerivMatrix(globalDerivativesx, globalDerivativesy, aGlobalDerivativesM);
00754
00755
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)) {
00775
00776 std::swap(newResidX, newResidY);
00777 std::swap(newHitErrX, newHitErrY);
00778 std::swap(newLocalDerivsX, newLocalDerivsY);
00779 std::swap(newGlobDerivsX, newGlobDerivsY);
00780 }
00781
00782
00783
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);
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);
00799 }
00800 }
00801
00802 return (isReal2DHit ? 2 : 1);
00803 }