CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/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( const edm::EventSetup& setup )
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(setup);
00207     throw exception;
00208   }
00209 }
00210 
00211 
00212 void KalmanAlignmentAlgorithm::initializeAlignmentParameters( const edm::EventSetup& setup )
00213 {
00214   //Retrieve tracker topology from geometry
00215   edm::ESHandle<TrackerTopology> tTopoHandle;
00216   setup.get<IdealGeometryRecord>().get(tTopoHandle);
00217   const TrackerTopology* const tTopo = tTopoHandle.product();
00218 
00219   // Just to be sure, set all APEs to zero ...
00220   setAPEToZero();
00221 
00222   const edm::ParameterSet initConfig = theConfiguration.getParameter< edm::ParameterSet >( "ParameterConfig" );
00223 
00224   int updateGraph = initConfig.getUntrackedParameter< int >( "UpdateGraphs", 100 );
00225 
00226   bool addPositionError = false;// = initConfig.getUntrackedParameter< bool >( "AddPositionError", true );
00227 
00228   int seed  = initConfig.getUntrackedParameter< int >( "RandomSeed", 1726354 );
00229   CLHEP::HepRandom::createInstance();
00230   CLHEP::HepRandom::setTheSeed( seed );
00231 
00232   bool applyXShifts =  initConfig.getUntrackedParameter< bool >( "ApplyXShifts", false );
00233   bool applyYShifts =  initConfig.getUntrackedParameter< bool >( "ApplyYShifts", false );
00234   bool applyZShifts =  initConfig.getUntrackedParameter< bool >( "ApplyZShifts", false );
00235   bool applyXRots =  initConfig.getUntrackedParameter< bool >( "ApplyXRotations", false );
00236   bool applyYRots =  initConfig.getUntrackedParameter< bool >( "ApplyYRotations", false );
00237   bool applyZRots =  initConfig.getUntrackedParameter< bool >( "ApplyZRotations", false );
00238 
00239   bool applyRandomStartValues = initConfig.getUntrackedParameter< bool >( "ApplyRandomStartValues", false );
00240   if ( applyRandomStartValues )
00241     cout << "[KalmanAlignmentAlgorithm::initializeAlignmentParameters] ADDING RANDOM START VALUES!!!" << endl;
00242 
00243   bool applyCurl =  initConfig.getUntrackedParameter< bool >( "ApplyCurl", false );
00244   double curlConst =  initConfig.getUntrackedParameter< double >( "CurlConstant", 1e-6 );
00245 
00246   bool applyShifts = applyXShifts || applyYShifts || applyZShifts;
00247   bool applyRots = applyXRots || applyYRots || applyZRots;
00248   //bool applyMisalignment = applyShifts || applyRots || applyCurl;
00249 
00250   AlgebraicVector displacement( 3 );
00251   AlgebraicVector eulerAngles( 3 );
00252 
00253   AlgebraicVector startParameters( 6, 0 );
00254   AlgebraicSymMatrix startError( 6, 0 );
00255 
00256   AlgebraicVector randSig( 6, 0 );
00257 
00258   vector< string > initSelection = initConfig.getParameter< vector<string> >( "InitializationSelector" );
00259 
00260   vector< string >::iterator itInitSel;
00261   for ( itInitSel = initSelection.begin(); itInitSel != initSelection.end(); ++itInitSel )
00262   {
00263     const edm::ParameterSet config = initConfig.getParameter< edm::ParameterSet >( *itInitSel );
00264 
00265     addPositionError = initConfig.getUntrackedParameter< bool >( "AddPositionError", false );
00266 
00267     double xAPEError = initConfig.getUntrackedParameter< double >( "SigmaXPositionError", 2e-2 );
00268     double yAPEError = initConfig.getUntrackedParameter< double >( "SigmaYPositionError", 2e-2  );
00269     double zAPEError = initConfig.getUntrackedParameter< double >( "SigmaZPositionError", 2e-2  );
00270 
00271     double sigmaXShift = config.getUntrackedParameter< double >( "SigmaXShifts", 4e-2 );
00272     double sigmaYShift = config.getUntrackedParameter< double >( "SigmaYShifts", 4e-2 );
00273     double sigmaZShift = config.getUntrackedParameter< double >( "SigmaZShifts", 4e-2 );
00274     double sigmaXRot = config.getUntrackedParameter< double >( "SigmaXRotations", 5e-4 );
00275     double sigmaYRot = config.getUntrackedParameter< double >( "SigmaYRotations", 5e-4 );
00276     double sigmaZRot = config.getUntrackedParameter< double >( "SigmaZRotations", 5e-4 );
00277 
00278     randSig[0] = sigmaXShift; randSig[1] = sigmaYShift; randSig[2] = sigmaZShift;
00279     randSig[3] = sigmaXRot; randSig[4] = sigmaYRot; randSig[5] = sigmaZRot;
00280 
00281     startError[0][0] = config.getUntrackedParameter< double >( "XShiftsStartError", 4e-4 );
00282     startError[1][1] = config.getUntrackedParameter< double >( "YShiftsStartError", 4e-4 );
00283     startError[2][2] = config.getUntrackedParameter< double >( "ZShiftsStartError", 4e-4 );
00284     startError[3][3] = config.getUntrackedParameter< double >( "XRotationsStartError", 3e-5 );
00285     startError[4][4] = config.getUntrackedParameter< double >( "YRotationsStartError", 3e-5 );
00286     startError[5][5] = config.getUntrackedParameter< double >( "ZRotationsStartError", 3e-5 );
00287 
00288     const vector< char > dummyParamSelector( 6, '0' );
00289     const vector< string > alignableSelector = config.getParameter< vector<string> >( "AlignableSelection" );
00290 
00291     vector< string >::const_iterator itAliSel;
00292     for ( itAliSel = alignableSelector.begin(); itAliSel != alignableSelector.end(); ++itAliSel )
00293     {
00294       theSelector->addSelection( *itAliSel, dummyParamSelector );
00295       cout << "[" << *itInitSel << "] add selection: " << *itAliSel << endl;
00296     }
00297 
00298     vector< Alignable* >::iterator itAlignable;
00299     vector< Alignable* > alignables;
00300     vector< Alignable* > alignablesFromSelector = theSelector->selectedAlignables();
00301     for ( itAlignable = alignablesFromSelector.begin(); itAlignable != alignablesFromSelector.end(); ++itAlignable )
00302       //if ( (*itAlignable)->alignmentParameters() )
00303       alignables.push_back( *itAlignable );
00304 
00305     cout << "[" << *itInitSel << "] total number of selected alignables = " << alignables.size() << endl;
00306 
00307     sort( alignables.begin(), alignables.end(), *this );
00308 
00309     // Apply existing alignment parameters.
00310     map< Alignable*, vector< AlignmentParameters* > > alignmentParametersMap;
00311 
00312     int iApply = 0;
00313     bool readParam = config.getUntrackedParameter< bool >( "ReadParametersFromFile", false );
00314     bool readCovar = config.getUntrackedParameter< bool >( "ReadCovarianceFromFile", false );
00315     bool applyParam = config.getUntrackedParameter< bool >( "ApplyParametersFromFile", false );
00316     bool applyCovar = config.getUntrackedParameter< bool >( "ApplyErrorFromFile", false );
00317     if ( readParam || readCovar || applyParam || applyCovar )
00318     {
00319       string file = config.getUntrackedParameter< string >( "FileName", "Input.root" );
00320       int ierr = 0;
00321       int iter = 1;
00322 
00323       AlignmentIORoot alignmentIO;
00324       while ( !ierr )
00325       {
00326         cout << "[" << *itInitSel << "] read alignment parameters. file / iteration = " << file << " / " << iter << endl;
00327         vector< AlignmentParameters* > alignmentParameters = alignmentIO.readAlignmentParameters( alignables, file.c_str(), iter, ierr );
00328         cout << "[" << *itInitSel << "] #param / ierr = " << alignmentParameters.size() << " / " << ierr << endl;
00329 
00330         vector< AlignmentParameters* >::iterator itParam;
00331         for ( itParam = alignmentParameters.begin(); itParam != alignmentParameters.end(); ++itParam )
00332           alignmentParametersMap[(*itParam)->alignable()].push_back( *itParam );
00333 
00334         ++iter;
00335       }
00336     }
00337 
00338     int iAlign = 0;
00339 
00340     for ( itAlignable = alignables.begin(); itAlignable != alignables.end(); itAlignable++ )
00341     {
00342       if ( (*itAlignable)->alignmentParameters() == 0 )
00343       {
00344         cout << "[KalmanAlignmentAlgorithm::initializeAlignmentParameters] "
00345              << "alignable is not associated with alignment parameters --> skip" << endl;
00346         continue;
00347       }
00348 
00349       if ( (*itAlignable)->alignmentParameters()->type() != AlignmentParametersFactory::kRigidBody )
00350       {
00351         cout << "[KalmanAlignmentAlgorithm::initializeAlignmentParameters] "
00352              << "alignable is not associated with rigid body alignment parameters --> skip" << endl;
00353         continue;
00354       }
00355 
00356       displacement[0] = applyXShifts ? sigmaXShift*CLHEP::RandGauss::shoot() : 0.;
00357       displacement[1] = applyYShifts ? sigmaZShift*CLHEP::RandGauss::shoot() : 0.;
00358       displacement[2] = applyZShifts ? sigmaYShift*CLHEP::RandGauss::shoot() : 0.;
00359 
00360       if ( applyShifts ) 
00361       {
00362         align::LocalVector localShift( displacement[0], displacement[1], displacement[2] );
00363         align::GlobalVector globalShift = ( *itAlignable )->surface().toGlobal( localShift );
00364         ( *itAlignable )->move( globalShift );
00365       }
00366 
00367       align::EulerAngles eulerAngles( 3 );
00368 
00369       eulerAngles[0] = applyXRots ? sigmaXRot*CLHEP::RandGauss::shoot() : 0.;
00370       eulerAngles[1] = applyYRots ? sigmaYRot*CLHEP::RandGauss::shoot() : 0.;
00371       eulerAngles[2] = applyZRots ? sigmaZRot*CLHEP::RandGauss::shoot() : 0.;
00372 
00373       if ( applyRots )
00374       {
00375         align::RotationType localRotation = align::toMatrix( eulerAngles );
00376         ( *itAlignable )->rotateInLocalFrame( localRotation );
00377       }
00378 
00379       if ( applyCurl )
00380       {
00381         double radius = ( *itAlignable )->globalPosition().perp();
00382         ( *itAlignable )->rotateAroundGlobalZ( curlConst*radius );
00383       }
00384 
00385       if ( addPositionError )
00386       {
00387         LocalVector localError( sqrt(xAPEError), sqrt(yAPEError), sqrt(zAPEError) );
00388         GlobalVector globalError = (*itAlignable)->surface().toGlobal( localError );
00389         AlignmentPositionError ape( globalError.x(), globalError.y(), globalError.z() );
00390         // FIXME (GF): The above does not seem to be a correct error transformation!
00391         ( *itAlignable )->setAlignmentPositionError( ape, true ); // true: propagate down
00392       }
00393 
00394       //AlgebraicVector trueParameters( 6 );
00395       //trueParameters[0] = -displacement[0];
00396       //trueParameters[1] = -displacement[1];
00397       //trueParameters[2] = -displacement[2];
00398       //trueParameters[3] = -eulerAngles[0];
00399       //trueParameters[4] = -eulerAngles[1];
00400       //trueParameters[5] = -eulerAngles[2];
00401 
00402       if ( (*itAlignable)->alignmentParameters() != 0 )
00403       {
00404         AlignmentParameters* alignmentParameters;
00405         if ( readParam && readCovar )
00406         {
00407           if ( alignmentParametersMap.find( *itAlignable ) == alignmentParametersMap.end() )
00408           {
00409             //cout << "apply param and cov from FILE -> none stored, apply DEFAULT " << endl;
00410             alignmentParameters = (*itAlignable)->alignmentParameters()->clone( startParameters, startError );
00411             alignmentParameters->setUserVariables( new KalmanAlignmentUserVariables( *itAlignable, tTopo, updateGraph ) );
00412           }
00413           else
00414           {
00415             //cout << "apply param and cov from FILE" << endl;
00416             alignmentParameters = alignmentParametersMap[*itAlignable].back();
00417             KalmanAlignmentUserVariables* userVariables = new KalmanAlignmentUserVariables( *itAlignable, tTopo, updateGraph );
00418             userVariables->update( alignmentParameters );
00419             alignmentParameters->setUserVariables( userVariables );
00420           }
00421         }
00422         else if ( readParam )
00423         {
00424           if ( alignmentParametersMap.find( *itAlignable ) == alignmentParametersMap.end() )
00425           {
00426             alignmentParameters = (*itAlignable)->alignmentParameters()->clone( startParameters, startError );
00427             alignmentParameters->setUserVariables( new KalmanAlignmentUserVariables( *itAlignable, tTopo, updateGraph ) );
00428           }
00429           else
00430           {
00431             AlgebraicVector parameters = alignmentParametersMap[*itAlignable].back()->parameters();
00432             alignmentParameters = (*itAlignable)->alignmentParameters()->clone( parameters, startError );
00433             KalmanAlignmentUserVariables* userVariables = new KalmanAlignmentUserVariables( *itAlignable, tTopo, updateGraph );
00434             userVariables->update( alignmentParameters );
00435             alignmentParameters->setUserVariables( userVariables );
00436           }
00437         }
00438         else
00439         {
00440           //cout << "apply DEFAULT param and cov" << endl;
00441           alignmentParameters = (*itAlignable)->alignmentParameters()->clone( startParameters, startError );
00442           //alignmentParameters = (*itAlignable)->alignmentParameters()->clone( trueParameters, startError );
00443           alignmentParameters->setUserVariables( new KalmanAlignmentUserVariables( *itAlignable, tTopo, updateGraph ) );
00444         }
00445 
00446         (*itAlignable)->setAlignmentParameters( alignmentParameters );
00447         //if ( applyParam ) theParameterStore->applyParameters( *itAlignable );
00448 
00449         if ( applyRandomStartValues )
00450         {
00451           cout << "applying random start values" << endl;
00452 
00453           AlgebraicVector randomStartParameters = alignmentParameters->parameters();
00454           AlgebraicSymMatrix randomStartErrors = alignmentParameters->covariance();
00455 
00456           for ( int iParam = 0; iParam < randomStartParameters.num_row(); ++iParam )
00457           {
00458             randomStartParameters[iParam] += sqrt(randSig[iParam])*CLHEP::RandGauss::shoot();
00459             //randomStartErrors[iParam][iParam] += randSig[iParam]*randSig[iParam];
00460           }
00461 
00462           //cout << randomStartParameters << endl;
00463 
00464           alignmentParameters = (*itAlignable)->alignmentParameters()->clone( randomStartParameters, randomStartErrors );
00465           (*itAlignable)->setAlignmentParameters( alignmentParameters );
00466         }
00467 
00468         (*itAlignable)->alignmentParameters()->setValid( true );
00469 
00470       }
00471 
00472       if ( ( applyParam || applyCovar ) && alignmentParametersMap.find( *itAlignable ) != alignmentParametersMap.end() )
00473       {
00474         ++iApply;
00475 
00476         vector< AlignmentParameters* > allAlignmentParameters = alignmentParametersMap[*itAlignable];
00477         vector< AlignmentParameters* >::iterator itParam;
00478 
00479         for ( itParam = allAlignmentParameters.begin(); itParam != allAlignmentParameters.end(); ++itParam )
00480           applyAlignmentParameters( *itAlignable, *itParam, applyParam, applyCovar );
00481 
00482         if ( ( *itAlignable )->alignmentParameters() )
00483         {
00484           KalmanAlignmentUserVariables* userVariables =
00485             dynamic_cast< KalmanAlignmentUserVariables* >( ( *itAlignable )->alignmentParameters()->userVariables() );
00486           if ( userVariables ) { ++iAlign; userVariables->setAlignmentFlag( true ); }
00487         }
00488       }
00489     }
00490 
00491     cout << "[" << *itInitSel << "] Set the alignment flag for " << iAlign << " alignables." << endl;
00492     cout << "[" << *itInitSel << "] number of applied parameters: " << iApply << endl; 
00493     theSelector->clear();
00494   }
00495 
00496 }
00497 
00498 
00499 void KalmanAlignmentAlgorithm::initializeAlignmentSetups( const edm::EventSetup& setup )
00500 {
00501   // Read the setups from the config-file. They define which rec-hits are refitted to tracklets and whether they are used
00502   // as an external measurement or not.
00503 
00504   const edm::ParameterSet initConfig = theConfiguration.getParameter< edm::ParameterSet >( "AlgorithmConfig" );
00505   const vector<string> selSetup = initConfig.getParameter< vector<string> >( "Setups" );
00506 
00507   for ( vector<string>::const_iterator itSel = selSetup.begin(); itSel != selSetup.end(); ++itSel )
00508   {
00509     cout << "[KalmanAlignmentAlgorithm::initializeAlignmentSetups] Add AlignmentSetup: " << *itSel << endl;
00510 
00511     const edm::ParameterSet confSetup = initConfig.getParameter< edm::ParameterSet >( *itSel );
00512 
00513     string strPropDir = confSetup.getUntrackedParameter< string >( "PropagationDirection", "alongMomentum" );
00514     string strSortingDir = confSetup.getUntrackedParameter< string >( "SortingDirection", "SortInsideOut" );
00515     vector<int> trackingIDs = confSetup.getParameter< vector<int> >( "Tracking" );
00516     unsigned int minTrackingHits = confSetup.getUntrackedParameter< unsigned int >( "MinTrackingHits", 0 );
00517     
00518     string strExternalPropDir = confSetup.getUntrackedParameter< string >( "ExternalPropagationDirection", "alongMomentum" );
00519     string strExternalSortingDir = confSetup.getUntrackedParameter< string >( "ExternalSortingDirection", "SortInsideOut" );
00520     vector<int> externalIDs = confSetup.getParameter< vector<int> >( "External" );
00521     unsigned int minExternalHits = confSetup.getUntrackedParameter< unsigned int >( "MinExternalHits", 0 );
00522 
00523     edm::ESHandle< TrajectoryFitter > aTrajectoryFitter;
00524     string fitterName = confSetup.getUntrackedParameter< string >( "Fitter", "KFFittingSmoother" );
00525     setup.get<TrajectoryFitter::Record>().get( fitterName, aTrajectoryFitter );
00526 
00527     double outlierEstimateCut = 5.;
00528 
00529     const KFFittingSmoother* aFittingSmoother = dynamic_cast< const KFFittingSmoother* >( aTrajectoryFitter.product() );
00530     if ( aFittingSmoother )
00531     {
00532       KFTrajectoryFitter* fitter = 0;
00533       KFTrajectorySmoother* smoother = 0;
00534       CurrentAlignmentKFUpdator* updator = new CurrentAlignmentKFUpdator( theNavigator );
00535 
00536       KFTrajectoryFitter* externalFitter = 0;
00537       KFTrajectorySmoother* externalSmoother = 0;
00538 
00539       PropagationDirection fitterDir = getDirection( strPropDir );
00540       PropagationDirection externalFitterDir = getDirection( strExternalPropDir );
00541 
00542       PropagationDirection smootherDir = oppositeDirection( fitterDir );
00543       PropagationDirection externalSmootherDir = oppositeDirection( externalFitterDir );
00544 
00545       const KFTrajectoryFitter* aKFFitter = dynamic_cast< const KFTrajectoryFitter* >( aFittingSmoother->fitter() );
00546       if ( aKFFitter )
00547       {
00548         PropagatorWithMaterial propagator( fitterDir, 0.106, aKFFitter->propagator()->magneticField() );
00549         Chi2MeasurementEstimator estimator( 30. );
00550         fitter = new KFTrajectoryFitter( &propagator, updator, &estimator );
00551 //      fitter = new KFTrajectoryFitter( &propagator, aKFFitter->updator(), &estimator );
00552 
00553         AnalyticalPropagator externalPropagator( aKFFitter->propagator()->magneticField(), externalFitterDir );
00554         Chi2MeasurementEstimator externalEstimator( 1000. );
00555         externalFitter = new KFTrajectoryFitter( &externalPropagator, aKFFitter->updator(), &externalEstimator );
00556       }
00557 
00558       const KFTrajectorySmoother* aKFSmoother = dynamic_cast< const KFTrajectorySmoother* >( aFittingSmoother->smoother() );
00559       if ( aKFSmoother )
00560       {
00561 
00562         PropagatorWithMaterial propagator( smootherDir, 0.106, aKFSmoother->propagator()->magneticField() );
00563         Chi2MeasurementEstimator estimator( 30. );
00564         smoother = new KFTrajectorySmoother( &propagator, updator, &estimator );
00565 //      smoother = new KFTrajectorySmoother( &propagator, aKFFitter->updator(), &estimator );
00566 
00567         AnalyticalPropagator externalPropagator( aKFSmoother->propagator()->magneticField(), externalSmootherDir );
00568         Chi2MeasurementEstimator externalEstimator( 1000. );
00569         externalSmoother = new KFTrajectorySmoother( &externalPropagator, aKFSmoother->updator(), &externalEstimator );
00570       }
00571 
00572       if ( fitter && smoother )
00573       {
00574         KFFittingSmoother* fittingSmoother = new KFFittingSmoother( *fitter, *smoother, outlierEstimateCut );
00575         KFFittingSmoother* externalFittingSmoother = new KFFittingSmoother( *externalFitter, *externalSmoother );
00576 //      KFFittingSmoother* fittingSmoother = aFittingSmoother->clone();
00577 //      KFFittingSmoother* externalFittingSmoother = aFittingSmoother->clone();
00578 
00579         string identifier;
00580         edm::ParameterSet config;
00581 
00582         config = confSetup.getParameter< edm::ParameterSet >( "TrajectoryFactory" );
00583         identifier = config.getParameter< string >( "TrajectoryFactoryName" );
00584         cout << "TrajectoryFactoryPlugin::get() ... " << identifier << endl;
00585         TrajectoryFactoryBase* trajectoryFactory = TrajectoryFactoryPlugin::get()->create( identifier, config );
00586 
00587         config = confSetup.getParameter< edm::ParameterSet >( "AlignmentUpdator" );
00588         identifier = config.getParameter< string >( "AlignmentUpdatorName" );
00589         KalmanAlignmentUpdator* alignmentUpdator = KalmanAlignmentUpdatorPlugin::get()->create( identifier, config );
00590 
00591         config = confSetup.getParameter< edm::ParameterSet >( "MetricsUpdator" );
00592         identifier = config.getParameter< string >( "MetricsUpdatorName" );
00593         KalmanAlignmentMetricsUpdator* metricsUpdator = KalmanAlignmentMetricsUpdatorPlugin::get()->create( identifier, config );
00594 
00595         KalmanAlignmentSetup::SortingDirection sortingDir = getSortingDirection( strSortingDir );
00596         KalmanAlignmentSetup::SortingDirection externalSortingDir = getSortingDirection( strExternalSortingDir );
00597 
00598         AlignmentSetup* anAlignmentSetup
00599           = new AlignmentSetup( *itSel,
00600                                 fittingSmoother, fitter->propagator(), trackingIDs, minTrackingHits, sortingDir,
00601                                 externalFittingSmoother, externalFitter->propagator(), externalIDs, minExternalHits, externalSortingDir,
00602                                 trajectoryFactory, alignmentUpdator, metricsUpdator );
00603 
00604         theAlignmentSetups.push_back( anAlignmentSetup );
00605 
00606         delete fittingSmoother;
00607         delete fitter;
00608         delete smoother;
00609 
00610         delete externalFittingSmoother;
00611         delete externalFitter;
00612         delete externalSmoother;
00613       }
00614       else
00615       {
00616         throw cms::Exception( "BadConfig" ) << "[KalmanAlignmentAlgorithm::initializeAlignmentSetups] "
00617                                             << "Instance of class KFFittingSmoother has no KFTrajectoryFitter/KFTrajectorySmoother.";
00618       }
00619 
00620       delete updator;
00621     }
00622     else
00623     {
00624       throw cms::Exception( "BadConfig" ) << "[KalmanAlignmentAlgorithm::initializeAlignmentSetups] "
00625                                           << "No instance of class KFFittingSmoother registered to the TrackingComponentsRecord.";
00626     }
00627   }
00628 
00629   cout << "[KalmanAlignmentAlgorithm::initializeAlignmentSetups] I'm using " << theAlignmentSetups.size() << " AlignmentSetup(s)." << endl;
00630 
00631 }
00632 
00633 
00634 const KalmanAlignmentSetup::SortingDirection
00635 KalmanAlignmentAlgorithm::getSortingDirection( const std::string& sortDir ) const
00636 {
00637   if ( sortDir == "SortInsideOut" ) { return KalmanAlignmentSetup::sortInsideOut; }
00638   if ( sortDir == "SortOutsideIn" ) { return KalmanAlignmentSetup::sortOutsideIn; }
00639   if ( sortDir == "SortUpsideDown" ) { return KalmanAlignmentSetup::sortUpsideDown; }
00640   if ( sortDir == "SortDownsideUp" ) { return KalmanAlignmentSetup::sortDownsideUp; }
00641 
00642   throw cms::Exception( "BadConfig" ) << "[KalmanAlignmentAlgorithm::getSortingDirection] "
00643                                       << "Unknown sorting direction: " << sortDir << std::endl;
00644 }
00645 
00646 
00647 void
00648 KalmanAlignmentAlgorithm::applyAlignmentParameters( Alignable* ali, AlignmentParameters* par,
00649                                                     bool applyPar, bool applyCov ) const
00650 {
00651   RigidBodyAlignmentParameters* rbap = dynamic_cast<RigidBodyAlignmentParameters*>( par );
00652 
00653   if ( !rbap )
00654     throw cms::Exception( "BadConfig" ) << "applyParameters: provided alignable does not have rigid body alignment parameters";
00655 
00656   if ( applyPar )
00657   {
00658     AlgebraicVector shift = rbap->translation();
00659     const AlignableSurface& alignableSurface = ali->surface();
00660     ali->move( alignableSurface.toGlobal( align::LocalVector( shift[0], shift[1], shift[2] ) ) );
00661 
00662     align::EulerAngles angles = rbap->rotation();
00663     if ( angles.normsq() > 1e-10 ) ali->rotateInLocalFrame( align::toMatrix( angles ) );
00664   }
00665 
00666   if ( applyCov )
00667   {
00668     const AlgebraicSymMatrix& aliCov = rbap->covariance();
00669     LocalVector localError( sqrt(aliCov[0][0]), sqrt(aliCov[1][1]), sqrt(aliCov[2][2]) );
00670     GlobalVector globalError = ali->surface().toGlobal( localError );
00671     AlignmentPositionError ape( globalError.x(), globalError.y(), globalError.z() );
00672     // FIXME (GF): The above does not seem to be a correct error transformation!
00673     ali->setAlignmentPositionError( ape, true );  // true: propagate down
00674   }
00675 }
00676 
00677 
00678 void KalmanAlignmentAlgorithm::getComponents( Alignable* ali,
00679                                               vector<Alignable*>& comps ) const
00680 {
00681   comps.push_back( ali );
00682   vector<Alignable*> nextComps = ali->components();
00683   vector<Alignable*>::iterator it;
00684   for ( it = nextComps.begin(); it != nextComps.end(); ++it ) getComponents( *it, comps );
00685 }
00686 
00687 
00688 void KalmanAlignmentAlgorithm::mergeResults( void ) const
00689 {
00690   std::cout << "[KalmanAlignmentAlgorithm::mergeResults] START MERGING RESULTS" << std::endl;
00691 
00692   edm::ParameterSet mergeConf = theConfiguration.getParameter<edm::ParameterSet>( "Merger" );
00693 
00694   vector<string> inFileNames = mergeConf.getParameter< vector<string> >( "InputMergeFileNames" );
00695   string outFileName = mergeConf.getParameter<string>( "OutputMergeFileName" );
00696 
00697   bool applyPar = mergeConf.getParameter<bool>( "ApplyParameters" );
00698   bool applyCov = mergeConf.getParameter<bool>( "ApplyErrors" );
00699 
00700   map< Alignable*, vector< AlignmentParameters* > > alignmentParametersMap;
00701 
00702   vector< Alignable* > allAlignables;
00703   getComponents( theTracker, allAlignables );
00704 
00705   cout << "allAlignables.size() = " << allAlignables.size() << endl;
00706 
00707   AlignmentIORoot alignmentIO;
00708 
00709   for ( vector<string>::iterator itFile = inFileNames.begin(); itFile != inFileNames.end(); ++itFile )
00710   {
00711     int iter = 1;
00712     int ierr = 0;
00713 
00714     while ( !ierr )
00715     {
00716       cout << "Read alignment parameters. file / iteration = " << *itFile << " / " << iter << endl;
00717 
00718       vector< AlignmentParameters* > alignmentParameters =
00719         alignmentIO.readAlignmentParameters( allAlignables, (*itFile).c_str(), iter, ierr );
00720 
00721       cout << "#param / ierr = " << alignmentParameters.size() << " / " << ierr << endl;
00722       
00723       vector< AlignmentParameters* >::iterator itParam;
00724       for ( itParam = alignmentParameters.begin(); itParam != alignmentParameters.end(); ++itParam )
00725           alignmentParametersMap[(*itParam)->alignable()].push_back( *itParam );
00726 
00727       ++iter;
00728     }
00729   }
00730 
00731   vector< Alignable* > alignablesToWrite;
00732   alignablesToWrite.reserve( alignmentParametersMap.size() );
00733 
00734   map< Alignable*, vector< AlignmentParameters* > >::iterator itMap;
00735   for ( itMap = alignmentParametersMap.begin(); itMap != alignmentParametersMap.end(); ++itMap )
00736   {
00737     //cout << "merge param for alignable" << itMap->first << endl;
00738 
00739     AlgebraicVector mergedParam( 6, 0 );
00740     AlgebraicSymMatrix mergedCov( 6, 0 );
00741     int nMerge = 0;
00742 
00743     vector< AlignmentParameters* >& vecParam = itMap->second;
00744     vector< AlignmentParameters* >::iterator itParam;
00745     for ( itParam = vecParam.begin(); itParam != vecParam.end(); ++itParam, ++nMerge )
00746       mergedParam += (*itParam)->parameters();
00747 
00748     mergedParam /= nMerge;
00749 
00750     // no merging of errors up to now
00751     AlignmentParameters* mergedAliParam = vecParam.front()->clone( mergedParam, mergedCov );
00752     itMap->first->setAlignmentParameters( mergedAliParam );
00753 
00754     alignablesToWrite.push_back( itMap->first );
00755 
00756     if ( applyPar || applyCov ) applyAlignmentParameters( itMap->first, mergedAliParam, applyPar, applyCov );
00757   }
00758 
00759   cout << "alignablesToWrite.size() = " << alignablesToWrite.size() << endl;
00760 
00761   int ierr = 0;
00762   // Write output to "iteration 1", ...
00763   alignmentIO.writeAlignmentParameters( alignablesToWrite, outFileName.c_str(), 1, false, ierr );
00764   // ... or, if "iteration 1" already exists, write it to "highest iteration + 1"
00765   if ( ierr == -1 ) alignmentIO.writeAlignmentParameters( alignablesToWrite, outFileName.c_str(), -1, false, ierr );
00766 
00767   std::cout << "[KalmanAlignmentAlgorithm::mergeResults] DONE" << std::endl;
00768 }
00769 
00770 
00771 void KalmanAlignmentAlgorithm::setAPEToZero( void )
00772 {
00773   AlignmentPositionError zeroAPE( 0., 0., 0. );
00774   theTracker->setAlignmentPositionError( zeroAPE, true );
00775 }
00776 
00777 DEFINE_EDM_PLUGIN( AlignmentAlgorithmPluginFactory, KalmanAlignmentAlgorithm, "KalmanAlignmentAlgorithm");