CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_3/src/Alignment/KalmanAlignmentAlgorithm/plugins/KalmanAlignmentAlgorithm.cc

Go to the documentation of this file.
00001 
00002 #include "KalmanAlignmentAlgorithm.h"
00003 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentAlgorithmPluginFactory.h"
00004 
00005 // includes for alignment
00006 #include "Alignment/CommonAlignment/interface/AlignableNavigator.h"
00007 #include "Alignment/CommonAlignment/interface/Utilities.h"
00008 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentIORoot.h"
00009 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterSelector.h"
00010 
00011 #include "Alignment/CommonAlignmentParametrization/interface/AlignmentParametersFactory.h"
00012 #include "Alignment/CommonAlignmentParametrization/interface/RigidBodyAlignmentParameters.h"
00013 
00014 #include "Alignment/KalmanAlignmentAlgorithm/interface/KalmanAlignmentUpdatorPlugin.h"
00015 #include "Alignment/KalmanAlignmentAlgorithm/interface/KalmanAlignmentMetricsUpdatorPlugin.h"
00016 #include "Alignment/KalmanAlignmentAlgorithm/interface/KalmanAlignmentUserVariables.h"
00017 #include "Alignment/KalmanAlignmentAlgorithm/interface/KalmanAlignmentDataCollector.h"
00018 #include "Alignment/KalmanAlignmentAlgorithm/interface/CurrentAlignmentKFUpdator.h"
00019 
00020 #include "Alignment/ReferenceTrajectories/interface/TrajectoryFactoryPlugin.h"
00021 
00022 #include "Alignment/TrackerAlignment/interface/TrackerAlignableId.h"
00023 #include "Alignment/TrackerAlignment/interface/AlignableTracker.h"
00024 
00025 #include "TrackingTools/TrackFitters/interface/KFFittingSmoother.h"
00026 #include "TrackingTools/TrackFitters/interface/KFTrajectoryFitter.h"
00027 #include "TrackingTools/TrackFitters/interface/KFTrajectorySmoother.h"
00028 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h"
00029 #include "TrackingTools/GeomPropagators/interface/AnalyticalPropagator.h"
00030 #include "TrackingTools/MaterialEffects/interface/PropagatorWithMaterial.h"
00031 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00032 
00033 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" 
00034 
00035 #include "DataFormats/TrackingRecHit/interface/AlignmentPositionError.h"
00036 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
00037 
00038 // miscellaneous includes
00039 #include "FWCore/Utilities/interface/Exception.h"
00040 #include "CLHEP/Random/RandGauss.h"
00041 #include <fstream>
00042 
00043 using namespace std;
00044 
00045 
00046 KalmanAlignmentAlgorithm::KalmanAlignmentAlgorithm( const edm::ParameterSet& config ) :
00047   AlignmentAlgorithmBase( config ),
00048   theConfiguration( config )
00049 {}
00050 
00051 
00052 KalmanAlignmentAlgorithm::~KalmanAlignmentAlgorithm( void ) {}
00053 
00054 
00055 void KalmanAlignmentAlgorithm::initialize( const edm::EventSetup& setup, 
00056                                            AlignableTracker* tracker, 
00057                                            AlignableMuon* muon,
00058                                            AlignableExtras* extras,
00059                                            AlignmentParameterStore* store )
00060 {
00061   theTracker = tracker;
00062 
00063   theMergerFlag = theConfiguration.getParameter<bool>( "MergeResults" );
00064 
00065   if ( theMergerFlag )
00066   {
00067     mergeResults();
00068   } else {
00069     theParameterStore = store;
00070     theNavigator = new AlignableNavigator( tracker->components() );
00071     theSelector = new AlignmentParameterSelector( tracker );
00072 
00073     theRefitter = new KalmanAlignmentTrackRefitter( theConfiguration.getParameter< edm::ParameterSet >( "TrackRefitter" ), theNavigator );
00074 
00075     initializeAlignmentParameters( setup );
00076     initializeAlignmentSetups( setup );
00077 
00078     KalmanAlignmentDataCollector::configure( theConfiguration.getParameter< edm::ParameterSet >( "DataCollector" ) );
00079   }
00080 }
00081 
00082 
00083 void KalmanAlignmentAlgorithm::terminate( void )
00084 {
00085   if ( theMergerFlag )
00086   {
00087     return; // only merging mode. nothing to do here.
00088   }
00089 
00090   cout << "[KalmanAlignmentAlgorithm::terminate] start ..." << endl;
00091 
00092   set< Alignable* > allAlignables;
00093   vector< Alignable* > alignablesToWrite;
00094 
00095   AlignmentSetupCollection::const_iterator itSetup;
00096   for ( itSetup = theAlignmentSetups.begin(); itSetup != theAlignmentSetups.end(); ++itSetup )
00097   {
00098     delete (*itSetup)->alignmentUpdator();
00099 
00100     const vector< Alignable* >& alignablesFromMetrics  = (*itSetup)->metricsUpdator()->alignables();
00101     cout << "[KalmanAlignmentAlgorithm::terminate] The metrics updator for setup \'" << (*itSetup)->id()
00102          << "\' holds " << alignablesFromMetrics.size() << " alignables" << endl;
00103     allAlignables.insert( alignablesFromMetrics.begin(), alignablesFromMetrics.end() );
00104   }
00105 
00106   for ( set< Alignable* >::iterator it = allAlignables.begin(); it != allAlignables.end(); ++it )
00107   {
00108     AlignmentParameters* alignmentParameters = ( *it )->alignmentParameters();
00109 
00110     if ( alignmentParameters != 0 )
00111     {
00112       KalmanAlignmentUserVariables* userVariables =
00113         dynamic_cast< KalmanAlignmentUserVariables* >( alignmentParameters->userVariables() );
00114 
00115       if ( userVariables != 0 && userVariables->numberOfUpdates() > 0 )
00116       {
00117         userVariables->update( true );
00118         userVariables->histogramParameters( "KalmanAlignmentAlgorithm" );
00119         alignablesToWrite.push_back( *it );
00120       }
00121     }
00122   }
00123 
00124   if ( theConfiguration.getUntrackedParameter< bool >( "WriteAlignmentParameters", false ) )
00125   {
00126     AlignmentIORoot alignmentIO;
00127     int ierr = 0;
00128     string output = theConfiguration.getParameter< string >( "OutputFile" );
00129 
00130     cout << "Write data for " << alignablesToWrite.size() << " alignables ..." << endl;
00131 
00132     // Write output to "iteration 1", ...
00133     alignmentIO.writeAlignmentParameters( alignablesToWrite, output.c_str(), 1, false, ierr );
00134     // ... or, if "iteration 1" already exists, write it to "highest iteration + 1"
00135     if ( ierr == -1 ) alignmentIO.writeAlignmentParameters( alignablesToWrite, output.c_str(), -1, false, ierr );
00136   }
00137 
00138   KalmanAlignmentDataCollector::write();
00139 
00140   string timingLogFile = theConfiguration.getUntrackedParameter< string >( "TimingLogFile", "timing.log" );
00141   cout << "The usage of TimingReport from Utilities/Timing! Timing not written to log file" << endl;
00142   
00143   delete theNavigator;
00144 
00145   cout << "[KalmanAlignmentAlgorithm::terminate] ... done." << endl;
00146 }
00147 
00148 
00149 void KalmanAlignmentAlgorithm::run( const edm::EventSetup & setup, const EventInfo &eventInfo )
00150 {
00151   if ( theMergerFlag ) return; // only merging mode. nothing to do here.
00152 
00153   static int iEvent = 1;
00154   if ( iEvent % 100 == 0 ) cout << "[KalmanAlignmentAlgorithm::run] Event Nr. " << iEvent << endl;
00155   iEvent++;
00156 
00157   edm::ESHandle< MagneticField > aMagneticField;
00158   setup.get< IdealMagneticFieldRecord >().get( aMagneticField );  
00159 
00160   try
00161   {
00162     // Run the refitter algorithm
00163     const ConstTrajTrackPairCollection &tracks = eventInfo.trajTrackPairs_;
00164     const reco::BeamSpot &beamSpot = eventInfo.beamSpot_;
00165     TrackletCollection refittedTracklets = theRefitter->refitTracks( setup, theAlignmentSetups, tracks, &beamSpot );
00166 
00167     // Associate tracklets to alignment setups
00168     map< AlignmentSetup*, TrackletCollection > setupToTrackletMap;
00169     TrackletCollection::iterator itTracklet;
00170     for ( itTracklet = refittedTracklets.begin(); itTracklet != refittedTracklets.end(); ++itTracklet )
00171       setupToTrackletMap[(*itTracklet)->alignmentSetup()].push_back( *itTracklet );
00172 
00173     // Iterate on alignment setups
00174     map< AlignmentSetup*, TrackletCollection >::iterator itMap;
00175     for ( itMap = setupToTrackletMap.begin(); itMap != setupToTrackletMap.end(); ++itMap )
00176     {
00177       ConstTrajTrackPairCollection tracklets;
00178       ExternalPredictionCollection external;
00179 
00180       TrackletCollection::iterator itTracklet;
00181       for ( itTracklet = itMap->second.begin(); itTracklet != itMap->second.end(); ++itTracklet )
00182       {
00183         tracklets.push_back( (*itTracklet)->trajTrackPair() );
00184         external.push_back( (*itTracklet)->externalPrediction() );
00185       }
00186 
00187       // Construct reference trajectories
00188       ReferenceTrajectoryCollection trajectories =
00189         itMap->first->trajectoryFactory()->trajectories( setup, tracklets, external, eventInfo.beamSpot_ );
00190 
00191       ReferenceTrajectoryCollection::iterator itTrajectories;
00192 
00193       // Run the alignment algorithm.
00194       for ( itTrajectories = trajectories.begin(); itTrajectories != trajectories.end(); ++itTrajectories )
00195       {
00196         itMap->first->alignmentUpdator()->process( *itTrajectories, theParameterStore, theNavigator,
00197                                                    itMap->first->metricsUpdator(), aMagneticField.product() );
00198 
00199         KalmanAlignmentDataCollector::fillHistogram( "Trajectory_RecHits", (*itTrajectories)->recHits().size() );
00200       }
00201     }
00202   }
00203   catch( cms::Exception& exception )
00204   {
00205     cout << exception.what() << endl;
00206     terminate();
00207     throw exception;
00208   }
00209 }
00210 
00211 
00212 void KalmanAlignmentAlgorithm::initializeAlignmentParameters( const edm::EventSetup& setup )
00213 {
00214   // Just to be sure, set all APEs to zero ...
00215   setAPEToZero();
00216 
00217   const edm::ParameterSet initConfig = theConfiguration.getParameter< edm::ParameterSet >( "ParameterConfig" );
00218 
00219   int updateGraph = initConfig.getUntrackedParameter< int >( "UpdateGraphs", 100 );
00220 
00221   bool addPositionError = false;// = initConfig.getUntrackedParameter< bool >( "AddPositionError", true );
00222 
00223   int seed  = initConfig.getUntrackedParameter< int >( "RandomSeed", 1726354 );
00224   CLHEP::HepRandom::createInstance();
00225   CLHEP::HepRandom::setTheSeed( seed );
00226 
00227   bool applyXShifts =  initConfig.getUntrackedParameter< bool >( "ApplyXShifts", false );
00228   bool applyYShifts =  initConfig.getUntrackedParameter< bool >( "ApplyYShifts", false );
00229   bool applyZShifts =  initConfig.getUntrackedParameter< bool >( "ApplyZShifts", false );
00230   bool applyXRots =  initConfig.getUntrackedParameter< bool >( "ApplyXRotations", false );
00231   bool applyYRots =  initConfig.getUntrackedParameter< bool >( "ApplyYRotations", false );
00232   bool applyZRots =  initConfig.getUntrackedParameter< bool >( "ApplyZRotations", false );
00233 
00234   bool applyRandomStartValues = initConfig.getUntrackedParameter< bool >( "ApplyRandomStartValues", false );
00235   if ( applyRandomStartValues )
00236     cout << "[KalmanAlignmentAlgorithm::initializeAlignmentParameters] ADDING RANDOM START VALUES!!!" << endl;
00237 
00238   bool applyCurl =  initConfig.getUntrackedParameter< bool >( "ApplyCurl", false );
00239   double curlConst =  initConfig.getUntrackedParameter< double >( "CurlConstant", 1e-6 );
00240 
00241   bool applyShifts = applyXShifts || applyYShifts || applyZShifts;
00242   bool applyRots = applyXRots || applyYRots || applyZRots;
00243   //bool applyMisalignment = applyShifts || applyRots || applyCurl;
00244 
00245   AlgebraicVector displacement( 3 );
00246   AlgebraicVector eulerAngles( 3 );
00247 
00248   AlgebraicVector startParameters( 6, 0 );
00249   AlgebraicSymMatrix startError( 6, 0 );
00250 
00251   AlgebraicVector randSig( 6, 0 );
00252 
00253   vector< string > initSelection = initConfig.getParameter< vector<string> >( "InitializationSelector" );
00254 
00255   vector< string >::iterator itInitSel;
00256   for ( itInitSel = initSelection.begin(); itInitSel != initSelection.end(); ++itInitSel )
00257   {
00258     const edm::ParameterSet config = initConfig.getParameter< edm::ParameterSet >( *itInitSel );
00259 
00260     addPositionError = initConfig.getUntrackedParameter< bool >( "AddPositionError", false );
00261 
00262     double xAPEError = initConfig.getUntrackedParameter< double >( "SigmaXPositionError", 2e-2 );
00263     double yAPEError = initConfig.getUntrackedParameter< double >( "SigmaYPositionError", 2e-2  );
00264     double zAPEError = initConfig.getUntrackedParameter< double >( "SigmaZPositionError", 2e-2  );
00265 
00266     double sigmaXShift = config.getUntrackedParameter< double >( "SigmaXShifts", 4e-2 );
00267     double sigmaYShift = config.getUntrackedParameter< double >( "SigmaYShifts", 4e-2 );
00268     double sigmaZShift = config.getUntrackedParameter< double >( "SigmaZShifts", 4e-2 );
00269     double sigmaXRot = config.getUntrackedParameter< double >( "SigmaXRotations", 5e-4 );
00270     double sigmaYRot = config.getUntrackedParameter< double >( "SigmaYRotations", 5e-4 );
00271     double sigmaZRot = config.getUntrackedParameter< double >( "SigmaZRotations", 5e-4 );
00272 
00273     randSig[0] = sigmaXShift; randSig[1] = sigmaYShift; randSig[2] = sigmaZShift;
00274     randSig[3] = sigmaXRot; randSig[4] = sigmaYRot; randSig[5] = sigmaZRot;
00275 
00276     startError[0][0] = config.getUntrackedParameter< double >( "XShiftsStartError", 4e-4 );
00277     startError[1][1] = config.getUntrackedParameter< double >( "YShiftsStartError", 4e-4 );
00278     startError[2][2] = config.getUntrackedParameter< double >( "ZShiftsStartError", 4e-4 );
00279     startError[3][3] = config.getUntrackedParameter< double >( "XRotationsStartError", 3e-5 );
00280     startError[4][4] = config.getUntrackedParameter< double >( "YRotationsStartError", 3e-5 );
00281     startError[5][5] = config.getUntrackedParameter< double >( "ZRotationsStartError", 3e-5 );
00282 
00283     const vector< char > dummyParamSelector( 6, '0' );
00284     const vector< string > alignableSelector = config.getParameter< vector<string> >( "AlignableSelection" );
00285 
00286     vector< string >::const_iterator itAliSel;
00287     for ( itAliSel = alignableSelector.begin(); itAliSel != alignableSelector.end(); ++itAliSel )
00288     {
00289       theSelector->addSelection( *itAliSel, dummyParamSelector );
00290       cout << "[" << *itInitSel << "] add selection: " << *itAliSel << endl;
00291     }
00292 
00293     vector< Alignable* >::iterator itAlignable;
00294     vector< Alignable* > alignables;
00295     vector< Alignable* > alignablesFromSelector = theSelector->selectedAlignables();
00296     for ( itAlignable = alignablesFromSelector.begin(); itAlignable != alignablesFromSelector.end(); ++itAlignable )
00297       //if ( (*itAlignable)->alignmentParameters() )
00298       alignables.push_back( *itAlignable );
00299 
00300     cout << "[" << *itInitSel << "] total number of selected alignables = " << alignables.size() << endl;
00301 
00302     sort( alignables.begin(), alignables.end(), *this );
00303 
00304     // Apply existing alignment parameters.
00305     map< Alignable*, vector< AlignmentParameters* > > alignmentParametersMap;
00306 
00307     int iApply = 0;
00308     bool readParam = config.getUntrackedParameter< bool >( "ReadParametersFromFile", false );
00309     bool readCovar = config.getUntrackedParameter< bool >( "ReadCovarianceFromFile", false );
00310     bool applyParam = config.getUntrackedParameter< bool >( "ApplyParametersFromFile", false );
00311     bool applyCovar = config.getUntrackedParameter< bool >( "ApplyErrorFromFile", false );
00312     if ( readParam || readCovar || applyParam || applyCovar )
00313     {
00314       string file = config.getUntrackedParameter< string >( "FileName", "Input.root" );
00315       int ierr = 0;
00316       int iter = 1;
00317 
00318       AlignmentIORoot alignmentIO;
00319       while ( !ierr )
00320       {
00321         cout << "[" << *itInitSel << "] read alignment parameters. file / iteration = " << file << " / " << iter << endl;
00322         vector< AlignmentParameters* > alignmentParameters = alignmentIO.readAlignmentParameters( alignables, file.c_str(), iter, ierr );
00323         cout << "[" << *itInitSel << "] #param / ierr = " << alignmentParameters.size() << " / " << ierr << endl;
00324 
00325         vector< AlignmentParameters* >::iterator itParam;
00326         for ( itParam = alignmentParameters.begin(); itParam != alignmentParameters.end(); ++itParam )
00327           alignmentParametersMap[(*itParam)->alignable()].push_back( *itParam );
00328 
00329         ++iter;
00330       }
00331     }
00332 
00333     int iAlign = 0;
00334 
00335     for ( itAlignable = alignables.begin(); itAlignable != alignables.end(); itAlignable++ )
00336     {
00337       if ( (*itAlignable)->alignmentParameters() == 0 )
00338       {
00339         cout << "[KalmanAlignmentAlgorithm::initializeAlignmentParameters] "
00340              << "alignable is not associated with alignment parameters --> skip" << endl;
00341         continue;
00342       }
00343 
00344       if ( (*itAlignable)->alignmentParameters()->type() != AlignmentParametersFactory::kRigidBody )
00345       {
00346         cout << "[KalmanAlignmentAlgorithm::initializeAlignmentParameters] "
00347              << "alignable is not associated with rigid body alignment parameters --> skip" << endl;
00348         continue;
00349       }
00350 
00351       displacement[0] = applyXShifts ? sigmaXShift*CLHEP::RandGauss::shoot() : 0.;
00352       displacement[1] = applyYShifts ? sigmaZShift*CLHEP::RandGauss::shoot() : 0.;
00353       displacement[2] = applyZShifts ? sigmaYShift*CLHEP::RandGauss::shoot() : 0.;
00354 
00355       if ( applyShifts ) 
00356       {
00357         align::LocalVector localShift( displacement[0], displacement[1], displacement[2] );
00358         align::GlobalVector globalShift = ( *itAlignable )->surface().toGlobal( localShift );
00359         ( *itAlignable )->move( globalShift );
00360       }
00361 
00362       align::EulerAngles eulerAngles( 3 );
00363 
00364       eulerAngles[0] = applyXRots ? sigmaXRot*CLHEP::RandGauss::shoot() : 0.;
00365       eulerAngles[1] = applyYRots ? sigmaYRot*CLHEP::RandGauss::shoot() : 0.;
00366       eulerAngles[2] = applyZRots ? sigmaZRot*CLHEP::RandGauss::shoot() : 0.;
00367 
00368       if ( applyRots )
00369       {
00370         align::RotationType localRotation = align::toMatrix( eulerAngles );
00371         ( *itAlignable )->rotateInLocalFrame( localRotation );
00372       }
00373 
00374       if ( applyCurl )
00375       {
00376         double radius = ( *itAlignable )->globalPosition().perp();
00377         ( *itAlignable )->rotateAroundGlobalZ( curlConst*radius );
00378       }
00379 
00380       if ( addPositionError )
00381       {
00382         LocalVector localError( sqrt(xAPEError), sqrt(yAPEError), sqrt(zAPEError) );
00383         GlobalVector globalError = (*itAlignable)->surface().toGlobal( localError );
00384         AlignmentPositionError ape( globalError.x(), globalError.y(), globalError.z() );
00385         // FIXME (GF): The above does not seem to be a correct error transformation!
00386         ( *itAlignable )->setAlignmentPositionError( ape, true ); // true: propagate down
00387       }
00388 
00389       //AlgebraicVector trueParameters( 6 );
00390       //trueParameters[0] = -displacement[0];
00391       //trueParameters[1] = -displacement[1];
00392       //trueParameters[2] = -displacement[2];
00393       //trueParameters[3] = -eulerAngles[0];
00394       //trueParameters[4] = -eulerAngles[1];
00395       //trueParameters[5] = -eulerAngles[2];
00396 
00397       if ( (*itAlignable)->alignmentParameters() != 0 )
00398       {
00399         AlignmentParameters* alignmentParameters;
00400         if ( readParam && readCovar )
00401         {
00402           if ( alignmentParametersMap.find( *itAlignable ) == alignmentParametersMap.end() )
00403           {
00404             //cout << "apply param and cov from FILE -> none stored, apply DEFAULT " << endl;
00405             alignmentParameters = (*itAlignable)->alignmentParameters()->clone( startParameters, startError );
00406             alignmentParameters->setUserVariables( new KalmanAlignmentUserVariables( *itAlignable, updateGraph ) );
00407           }
00408           else
00409           {
00410             //cout << "apply param and cov from FILE" << endl;
00411             alignmentParameters = alignmentParametersMap[*itAlignable].back();
00412             KalmanAlignmentUserVariables* userVariables = new KalmanAlignmentUserVariables( *itAlignable, updateGraph );
00413             userVariables->update( alignmentParameters );
00414             alignmentParameters->setUserVariables( userVariables );
00415           }
00416         }
00417         else if ( readParam )
00418         {
00419           if ( alignmentParametersMap.find( *itAlignable ) == alignmentParametersMap.end() )
00420           {
00421             alignmentParameters = (*itAlignable)->alignmentParameters()->clone( startParameters, startError );
00422             alignmentParameters->setUserVariables( new KalmanAlignmentUserVariables( *itAlignable, updateGraph ) );
00423           }
00424           else
00425           {
00426             AlgebraicVector parameters = alignmentParametersMap[*itAlignable].back()->parameters();
00427             alignmentParameters = (*itAlignable)->alignmentParameters()->clone( parameters, startError );
00428             KalmanAlignmentUserVariables* userVariables = new KalmanAlignmentUserVariables( *itAlignable, updateGraph );
00429             userVariables->update( alignmentParameters );
00430             alignmentParameters->setUserVariables( userVariables );
00431           }
00432         }
00433         else
00434         {
00435           //cout << "apply DEFAULT param and cov" << endl;
00436           alignmentParameters = (*itAlignable)->alignmentParameters()->clone( startParameters, startError );
00437           //alignmentParameters = (*itAlignable)->alignmentParameters()->clone( trueParameters, startError );
00438           alignmentParameters->setUserVariables( new KalmanAlignmentUserVariables( *itAlignable, updateGraph ) );
00439         }
00440 
00441         (*itAlignable)->setAlignmentParameters( alignmentParameters );
00442         //if ( applyParam ) theParameterStore->applyParameters( *itAlignable );
00443 
00444         if ( applyRandomStartValues )
00445         {
00446           cout << "applying random start values" << endl;
00447 
00448           AlgebraicVector randomStartParameters = alignmentParameters->parameters();
00449           AlgebraicSymMatrix randomStartErrors = alignmentParameters->covariance();
00450 
00451           for ( int iParam = 0; iParam < randomStartParameters.num_row(); ++iParam )
00452           {
00453             randomStartParameters[iParam] += sqrt(randSig[iParam])*CLHEP::RandGauss::shoot();
00454             //randomStartErrors[iParam][iParam] += randSig[iParam]*randSig[iParam];
00455           }
00456 
00457           //cout << randomStartParameters << endl;
00458 
00459           alignmentParameters = (*itAlignable)->alignmentParameters()->clone( randomStartParameters, randomStartErrors );
00460           (*itAlignable)->setAlignmentParameters( alignmentParameters );
00461         }
00462 
00463         (*itAlignable)->alignmentParameters()->setValid( true );
00464 
00465       }
00466 
00467       if ( ( applyParam || applyCovar ) && alignmentParametersMap.find( *itAlignable ) != alignmentParametersMap.end() )
00468       {
00469         ++iApply;
00470 
00471         vector< AlignmentParameters* > allAlignmentParameters = alignmentParametersMap[*itAlignable];
00472         vector< AlignmentParameters* >::iterator itParam;
00473 
00474         for ( itParam = allAlignmentParameters.begin(); itParam != allAlignmentParameters.end(); ++itParam )
00475           applyAlignmentParameters( *itAlignable, *itParam, applyParam, applyCovar );
00476 
00477         if ( ( *itAlignable )->alignmentParameters() )
00478         {
00479           KalmanAlignmentUserVariables* userVariables =
00480             dynamic_cast< KalmanAlignmentUserVariables* >( ( *itAlignable )->alignmentParameters()->userVariables() );
00481           if ( userVariables ) { ++iAlign; userVariables->setAlignmentFlag( true ); }
00482         }
00483       }
00484     }
00485 
00486     cout << "[" << *itInitSel << "] Set the alignment flag for " << iAlign << " alignables." << endl;
00487     cout << "[" << *itInitSel << "] number of applied parameters: " << iApply << endl; 
00488     theSelector->clear();
00489   }
00490 
00491 }
00492 
00493 
00494 void KalmanAlignmentAlgorithm::initializeAlignmentSetups( const edm::EventSetup& setup )
00495 {
00496   // Read the setups from the config-file. They define which rec-hits are refitted to tracklets and whether they are used
00497   // as an external measurement or not.
00498 
00499   const edm::ParameterSet initConfig = theConfiguration.getParameter< edm::ParameterSet >( "AlgorithmConfig" );
00500   const vector<string> selSetup = initConfig.getParameter< vector<string> >( "Setups" );
00501 
00502   for ( vector<string>::const_iterator itSel = selSetup.begin(); itSel != selSetup.end(); ++itSel )
00503   {
00504     cout << "[KalmanAlignmentAlgorithm::initializeAlignmentSetups] Add AlignmentSetup: " << *itSel << endl;
00505 
00506     const edm::ParameterSet confSetup = initConfig.getParameter< edm::ParameterSet >( *itSel );
00507 
00508     string strPropDir = confSetup.getUntrackedParameter< string >( "PropagationDirection", "alongMomentum" );
00509     string strSortingDir = confSetup.getUntrackedParameter< string >( "SortingDirection", "SortInsideOut" );
00510     vector<int> trackingIDs = confSetup.getParameter< vector<int> >( "Tracking" );
00511     unsigned int minTrackingHits = confSetup.getUntrackedParameter< unsigned int >( "MinTrackingHits", 0 );
00512     
00513     string strExternalPropDir = confSetup.getUntrackedParameter< string >( "ExternalPropagationDirection", "alongMomentum" );
00514     string strExternalSortingDir = confSetup.getUntrackedParameter< string >( "ExternalSortingDirection", "SortInsideOut" );
00515     vector<int> externalIDs = confSetup.getParameter< vector<int> >( "External" );
00516     unsigned int minExternalHits = confSetup.getUntrackedParameter< unsigned int >( "MinExternalHits", 0 );
00517 
00518     edm::ESHandle< TrajectoryFitter > aTrajectoryFitter;
00519     string fitterName = confSetup.getUntrackedParameter< string >( "Fitter", "KFFittingSmoother" );
00520     setup.get<TrajectoryFitter::Record>().get( fitterName, aTrajectoryFitter );
00521 
00522     double outlierEstimateCut = 5.;
00523 
00524     const KFFittingSmoother* aFittingSmoother = dynamic_cast< const KFFittingSmoother* >( aTrajectoryFitter.product() );
00525     if ( aFittingSmoother )
00526     {
00527       KFTrajectoryFitter* fitter = 0;
00528       KFTrajectorySmoother* smoother = 0;
00529       CurrentAlignmentKFUpdator* updator = new CurrentAlignmentKFUpdator( theNavigator );
00530 
00531       KFTrajectoryFitter* externalFitter = 0;
00532       KFTrajectorySmoother* externalSmoother = 0;
00533 
00534       PropagationDirection fitterDir = getDirection( strPropDir );
00535       PropagationDirection externalFitterDir = getDirection( strExternalPropDir );
00536 
00537       PropagationDirection smootherDir = oppositeDirection( fitterDir );
00538       PropagationDirection externalSmootherDir = oppositeDirection( externalFitterDir );
00539 
00540       const KFTrajectoryFitter* aKFFitter = dynamic_cast< const KFTrajectoryFitter* >( aFittingSmoother->fitter() );
00541       if ( aKFFitter )
00542       {
00543         PropagatorWithMaterial propagator( fitterDir, 0.106, aKFFitter->propagator()->magneticField() );
00544         Chi2MeasurementEstimator estimator( 30. );
00545         fitter = new KFTrajectoryFitter( &propagator, updator, &estimator );
00546 //      fitter = new KFTrajectoryFitter( &propagator, aKFFitter->updator(), &estimator );
00547 
00548         AnalyticalPropagator externalPropagator( aKFFitter->propagator()->magneticField(), externalFitterDir );
00549         Chi2MeasurementEstimator externalEstimator( 1000. );
00550         externalFitter = new KFTrajectoryFitter( &externalPropagator, aKFFitter->updator(), &externalEstimator );
00551       }
00552 
00553       const KFTrajectorySmoother* aKFSmoother = dynamic_cast< const KFTrajectorySmoother* >( aFittingSmoother->smoother() );
00554       if ( aKFSmoother )
00555       {
00556 
00557         PropagatorWithMaterial propagator( smootherDir, 0.106, aKFSmoother->propagator()->magneticField() );
00558         Chi2MeasurementEstimator estimator( 30. );
00559         smoother = new KFTrajectorySmoother( &propagator, updator, &estimator );
00560 //      smoother = new KFTrajectorySmoother( &propagator, aKFFitter->updator(), &estimator );
00561 
00562         AnalyticalPropagator externalPropagator( aKFSmoother->propagator()->magneticField(), externalSmootherDir );
00563         Chi2MeasurementEstimator externalEstimator( 1000. );
00564         externalSmoother = new KFTrajectorySmoother( &externalPropagator, aKFSmoother->updator(), &externalEstimator );
00565       }
00566 
00567       if ( fitter && smoother )
00568       {
00569         KFFittingSmoother* fittingSmoother = new KFFittingSmoother( *fitter, *smoother, outlierEstimateCut );
00570         KFFittingSmoother* externalFittingSmoother = new KFFittingSmoother( *externalFitter, *externalSmoother );
00571 //      KFFittingSmoother* fittingSmoother = aFittingSmoother->clone();
00572 //      KFFittingSmoother* externalFittingSmoother = aFittingSmoother->clone();
00573 
00574         string identifier;
00575         edm::ParameterSet config;
00576 
00577         config = confSetup.getParameter< edm::ParameterSet >( "TrajectoryFactory" );
00578         identifier = config.getParameter< string >( "TrajectoryFactoryName" );
00579         cout << "TrajectoryFactoryPlugin::get() ... " << identifier << endl;
00580         TrajectoryFactoryBase* trajectoryFactory = TrajectoryFactoryPlugin::get()->create( identifier, config );
00581 
00582         config = confSetup.getParameter< edm::ParameterSet >( "AlignmentUpdator" );
00583         identifier = config.getParameter< string >( "AlignmentUpdatorName" );
00584         KalmanAlignmentUpdator* alignmentUpdator = KalmanAlignmentUpdatorPlugin::get()->create( identifier, config );
00585 
00586         config = confSetup.getParameter< edm::ParameterSet >( "MetricsUpdator" );
00587         identifier = config.getParameter< string >( "MetricsUpdatorName" );
00588         KalmanAlignmentMetricsUpdator* metricsUpdator = KalmanAlignmentMetricsUpdatorPlugin::get()->create( identifier, config );
00589 
00590         KalmanAlignmentSetup::SortingDirection sortingDir = getSortingDirection( strSortingDir );
00591         KalmanAlignmentSetup::SortingDirection externalSortingDir = getSortingDirection( strExternalSortingDir );
00592 
00593         AlignmentSetup* anAlignmentSetup
00594           = new AlignmentSetup( *itSel,
00595                                 fittingSmoother, fitter->propagator(), trackingIDs, minTrackingHits, sortingDir,
00596                                 externalFittingSmoother, externalFitter->propagator(), externalIDs, minExternalHits, externalSortingDir,
00597                                 trajectoryFactory, alignmentUpdator, metricsUpdator );
00598 
00599         theAlignmentSetups.push_back( anAlignmentSetup );
00600 
00601         delete fittingSmoother;
00602         delete fitter;
00603         delete smoother;
00604 
00605         delete externalFittingSmoother;
00606         delete externalFitter;
00607         delete externalSmoother;
00608       }
00609       else
00610       {
00611         throw cms::Exception( "BadConfig" ) << "[KalmanAlignmentAlgorithm::initializeAlignmentSetups] "
00612                                             << "Instance of class KFFittingSmoother has no KFTrajectoryFitter/KFTrajectorySmoother.";
00613       }
00614 
00615       delete updator;
00616     }
00617     else
00618     {
00619       throw cms::Exception( "BadConfig" ) << "[KalmanAlignmentAlgorithm::initializeAlignmentSetups] "
00620                                           << "No instance of class KFFittingSmoother registered to the TrackingComponentsRecord.";
00621     }
00622   }
00623 
00624   cout << "[KalmanAlignmentAlgorithm::initializeAlignmentSetups] I'm using " << theAlignmentSetups.size() << " AlignmentSetup(s)." << endl;
00625 
00626 }
00627 
00628 
00629 const KalmanAlignmentSetup::SortingDirection
00630 KalmanAlignmentAlgorithm::getSortingDirection( const std::string& sortDir ) const
00631 {
00632   if ( sortDir == "SortInsideOut" ) { return KalmanAlignmentSetup::sortInsideOut; }
00633   if ( sortDir == "SortOutsideIn" ) { return KalmanAlignmentSetup::sortOutsideIn; }
00634   if ( sortDir == "SortUpsideDown" ) { return KalmanAlignmentSetup::sortUpsideDown; }
00635   if ( sortDir == "SortDownsideUp" ) { return KalmanAlignmentSetup::sortDownsideUp; }
00636 
00637   throw cms::Exception( "BadConfig" ) << "[KalmanAlignmentAlgorithm::getSortingDirection] "
00638                                       << "Unknown sorting direction: " << sortDir << std::endl;
00639 }
00640 
00641 
00642 void
00643 KalmanAlignmentAlgorithm::applyAlignmentParameters( Alignable* ali, AlignmentParameters* par,
00644                                                     bool applyPar, bool applyCov ) const
00645 {
00646   RigidBodyAlignmentParameters* rbap = dynamic_cast<RigidBodyAlignmentParameters*>( par );
00647 
00648   if ( !rbap )
00649     throw cms::Exception( "BadConfig" ) << "applyParameters: provided alignable does not have rigid body alignment parameters";
00650 
00651   if ( applyPar )
00652   {
00653     AlgebraicVector shift = rbap->translation();
00654     const AlignableSurface& alignableSurface = ali->surface();
00655     ali->move( alignableSurface.toGlobal( align::LocalVector( shift[0], shift[1], shift[2] ) ) );
00656 
00657     align::EulerAngles angles = rbap->rotation();
00658     if ( angles.normsq() > 1e-10 ) ali->rotateInLocalFrame( align::toMatrix( angles ) );
00659   }
00660 
00661   if ( applyCov )
00662   {
00663     const AlgebraicSymMatrix& aliCov = rbap->covariance();
00664     LocalVector localError( sqrt(aliCov[0][0]), sqrt(aliCov[1][1]), sqrt(aliCov[2][2]) );
00665     GlobalVector globalError = ali->surface().toGlobal( localError );
00666     AlignmentPositionError ape( globalError.x(), globalError.y(), globalError.z() );
00667     // FIXME (GF): The above does not seem to be a correct error transformation!
00668     ali->setAlignmentPositionError( ape, true );  // true: propagate down
00669   }
00670 }
00671 
00672 
00673 void KalmanAlignmentAlgorithm::getComponents( Alignable* ali,
00674                                               vector<Alignable*>& comps ) const
00675 {
00676   comps.push_back( ali );
00677   vector<Alignable*> nextComps = ali->components();
00678   vector<Alignable*>::iterator it;
00679   for ( it = nextComps.begin(); it != nextComps.end(); ++it ) getComponents( *it, comps );
00680 }
00681 
00682 
00683 void KalmanAlignmentAlgorithm::mergeResults( void ) const
00684 {
00685   std::cout << "[KalmanAlignmentAlgorithm::mergeResults] START MERGING RESULTS" << std::endl;
00686 
00687   edm::ParameterSet mergeConf = theConfiguration.getParameter<edm::ParameterSet>( "Merger" );
00688 
00689   vector<string> inFileNames = mergeConf.getParameter< vector<string> >( "InputMergeFileNames" );
00690   string outFileName = mergeConf.getParameter<string>( "OutputMergeFileName" );
00691 
00692   bool applyPar = mergeConf.getParameter<bool>( "ApplyParameters" );
00693   bool applyCov = mergeConf.getParameter<bool>( "ApplyErrors" );
00694 
00695   map< Alignable*, vector< AlignmentParameters* > > alignmentParametersMap;
00696 
00697   vector< Alignable* > allAlignables;
00698   getComponents( theTracker, allAlignables );
00699 
00700   cout << "allAlignables.size() = " << allAlignables.size() << endl;
00701 
00702   AlignmentIORoot alignmentIO;
00703 
00704   for ( vector<string>::iterator itFile = inFileNames.begin(); itFile != inFileNames.end(); ++itFile )
00705   {
00706     int iter = 1;
00707     int ierr = 0;
00708 
00709     while ( !ierr )
00710     {
00711       cout << "Read alignment parameters. file / iteration = " << *itFile << " / " << iter << endl;
00712 
00713       vector< AlignmentParameters* > alignmentParameters =
00714         alignmentIO.readAlignmentParameters( allAlignables, (*itFile).c_str(), iter, ierr );
00715 
00716       cout << "#param / ierr = " << alignmentParameters.size() << " / " << ierr << endl;
00717       
00718       vector< AlignmentParameters* >::iterator itParam;
00719       for ( itParam = alignmentParameters.begin(); itParam != alignmentParameters.end(); ++itParam )
00720           alignmentParametersMap[(*itParam)->alignable()].push_back( *itParam );
00721 
00722       ++iter;
00723     }
00724   }
00725 
00726   vector< Alignable* > alignablesToWrite;
00727   alignablesToWrite.reserve( alignmentParametersMap.size() );
00728 
00729   map< Alignable*, vector< AlignmentParameters* > >::iterator itMap;
00730   for ( itMap = alignmentParametersMap.begin(); itMap != alignmentParametersMap.end(); ++itMap )
00731   {
00732     //cout << "merge param for alignable" << itMap->first << endl;
00733 
00734     AlgebraicVector mergedParam( 6, 0 );
00735     AlgebraicSymMatrix mergedCov( 6, 0 );
00736     int nMerge = 0;
00737 
00738     vector< AlignmentParameters* >& vecParam = itMap->second;
00739     vector< AlignmentParameters* >::iterator itParam;
00740     for ( itParam = vecParam.begin(); itParam != vecParam.end(); ++itParam, ++nMerge )
00741       mergedParam += (*itParam)->parameters();
00742 
00743     mergedParam /= nMerge;
00744 
00745     // no merging of errors up to now
00746     AlignmentParameters* mergedAliParam = vecParam.front()->clone( mergedParam, mergedCov );
00747     itMap->first->setAlignmentParameters( mergedAliParam );
00748 
00749     alignablesToWrite.push_back( itMap->first );
00750 
00751     if ( applyPar || applyCov ) applyAlignmentParameters( itMap->first, mergedAliParam, applyPar, applyCov );
00752   }
00753 
00754   cout << "alignablesToWrite.size() = " << alignablesToWrite.size() << endl;
00755 
00756   int ierr = 0;
00757   // Write output to "iteration 1", ...
00758   alignmentIO.writeAlignmentParameters( alignablesToWrite, outFileName.c_str(), 1, false, ierr );
00759   // ... or, if "iteration 1" already exists, write it to "highest iteration + 1"
00760   if ( ierr == -1 ) alignmentIO.writeAlignmentParameters( alignablesToWrite, outFileName.c_str(), -1, false, ierr );
00761 
00762   std::cout << "[KalmanAlignmentAlgorithm::mergeResults] DONE" << std::endl;
00763 }
00764 
00765 
00766 void KalmanAlignmentAlgorithm::setAPEToZero( void )
00767 {
00768   AlignmentPositionError zeroAPE( 0., 0., 0. );
00769   theTracker->setAlignmentPositionError( zeroAPE, true );
00770 }
00771 
00772 DEFINE_EDM_PLUGIN( AlignmentAlgorithmPluginFactory, KalmanAlignmentAlgorithm, "KalmanAlignmentAlgorithm");