CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_2_9_HLT1_bphpatch4/src/Alignment/CommonAlignmentProducer/plugins/AlignmentProducer.cc

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #include "AlignmentProducer.h"
00009 #include "FWCore/Framework/interface/LooperFactory.h" 
00010 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterBuilder.h" 
00011 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterStore.h" 
00012 #include "Alignment/CommonAlignment/interface/Alignable.h" 
00013 
00014 #include "TrackingTools/PatternTools/interface/TrajTrackAssociation.h"
00015 
00016 // System include files
00017 #include <memory>
00018 #include <sstream>
00019 
00020 // Framework
00021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00022 #include "FWCore/Framework/interface/Event.h"
00023 #include "FWCore/Framework/interface/EventSetup.h"
00024 #include "FWCore/Framework/interface/ESTransientHandle.h"
00025 #include "FWCore/Framework/interface/Run.h"
00026 
00027 #include "FWCore/Utilities/interface/Parse.h"
00028 
00029 // Conditions database
00030 #include "FWCore/ServiceRegistry/interface/Service.h"
00031 #include "CondCore/DBOutputService/interface/PoolDBOutputService.h"
00032 
00033 // Geometry
00034 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00035 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeomBuilderFromGeometricDet.h"
00036 #include "Geometry/DTGeometry/interface/DTGeometry.h"
00037 #include "Geometry/CSCGeometry/interface/CSCGeometry.h"
00038 #include "Geometry/Records/interface/MuonNumberingRecord.h"
00039 #include "Geometry/DTGeometryBuilder/src/DTGeometryBuilderFromDDD.h"
00040 #include "Geometry/CSCGeometryBuilder/src/CSCGeometryBuilderFromDDD.h"
00041 #include "Geometry/TrackingGeometryAligner/interface/GeometryAligner.h"
00042 #include "CondFormats/AlignmentRecord/interface/TrackerAlignmentRcd.h"
00043 #include "CondFormats/AlignmentRecord/interface/TrackerAlignmentErrorRcd.h"
00044 #include "CondFormats/AlignmentRecord/interface/TrackerSurfaceDeformationRcd.h"
00045 #include "CondFormats/AlignmentRecord/interface/DTAlignmentRcd.h"
00046 #include "CondFormats/AlignmentRecord/interface/DTAlignmentErrorRcd.h"
00047 #include "CondFormats/AlignmentRecord/interface/CSCAlignmentRcd.h"
00048 #include "CondFormats/AlignmentRecord/interface/CSCAlignmentErrorRcd.h"
00049 #include "CondFormats/AlignmentRecord/interface/TrackerSurveyRcd.h"
00050 #include "CondFormats/AlignmentRecord/interface/TrackerSurveyErrorRcd.h"
00051 #include "CondFormats/AlignmentRecord/interface/DTSurveyRcd.h"
00052 #include "CondFormats/AlignmentRecord/interface/DTSurveyErrorRcd.h"
00053 #include "CondFormats/AlignmentRecord/interface/CSCSurveyRcd.h"
00054 #include "CondFormats/AlignmentRecord/interface/CSCSurveyErrorRcd.h"
00055 #include "CondFormats/AlignmentRecord/interface/GlobalPositionRcd.h"
00056 #include "CondFormats/Alignment/interface/DetectorGlobalPosition.h"
00057 
00058 // Tracking, LAS and cluster flag map (fwd is enough!) 
00059 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
00060 #include "DataFormats/Alignment/interface/AliClusterValueMapFwd.h"
00061 #include "DataFormats/Alignment/interface/TkFittedLasBeamCollectionFwd.h"
00062 #include "Alignment/LaserAlignment/interface/TsosVectorCollection.h"
00063 
00064 // Alignment
00065 #include "CondFormats/Alignment/interface/SurveyErrors.h"
00066 #include "Alignment/TrackerAlignment/interface/TrackerScenarioBuilder.h"
00067 #include "Alignment/MuonAlignment/interface/MuonScenarioBuilder.h"
00068 #include "Alignment/CommonAlignment/interface/SurveyDet.h"
00069 #include "Alignment/CommonAlignmentParametrization/interface/RigidBodyAlignmentParameters.h"
00070 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentAlgorithmPluginFactory.h"
00071 #include "Alignment/CommonAlignmentMonitor/interface/AlignmentMonitorPluginFactory.h"
00072 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterSelector.h"
00073 
00074 //_____________________________________________________________________________
00075 AlignmentProducer::AlignmentProducer(const edm::ParameterSet& iConfig) :
00076   theAlignmentAlgo(0), theAlignmentParameterStore(0),
00077   theAlignableExtras(0), theAlignableTracker(0), theAlignableMuon(0), 
00078   globalPositions_(0),
00079   nevent_(0), theParameterSet(iConfig),
00080   theMaxLoops( iConfig.getUntrackedParameter<unsigned int>("maxLoops") ),
00081   stNFixAlignables_(iConfig.getParameter<int>("nFixAlignables") ),
00082   stRandomShift_(iConfig.getParameter<double>("randomShift")),
00083   stRandomRotation_(iConfig.getParameter<double>("randomRotation")),
00084   applyDbAlignment_( iConfig.getUntrackedParameter<bool>("applyDbAlignment")),
00085   doMisalignmentScenario_(iConfig.getParameter<bool>("doMisalignmentScenario")),
00086   saveToDB_(iConfig.getParameter<bool>("saveToDB")),
00087   saveApeToDB_(iConfig.getParameter<bool>("saveApeToDB")),
00088   saveDeformationsToDB_(iConfig.getParameter<bool>("saveDeformationsToDB")),
00089   doTracker_( iConfig.getUntrackedParameter<bool>("doTracker") ),
00090   doMuon_( iConfig.getUntrackedParameter<bool>("doMuon") ),
00091   useExtras_( iConfig.getUntrackedParameter<bool>("useExtras") ),
00092   useSurvey_( iConfig.getParameter<bool>("useSurvey") ),
00093   tjTkAssociationMapTag_(iConfig.getParameter<edm::InputTag>("tjTkAssociationMapTag")),
00094   beamSpotTag_(iConfig.getParameter<edm::InputTag>("beamSpotTag")),
00095   tkLasBeamTag_(iConfig.getParameter<edm::InputTag>("tkLasBeamTag")),
00096   clusterValueMapTag_(iConfig.getParameter<edm::InputTag>("hitPrescaleMapTag"))
00097 {
00098   edm::LogInfo("Alignment") << "@SUB=AlignmentProducer::AlignmentProducer";
00099 
00100   // Tell the framework what data is being produced
00101   if (doTracker_) {
00102      setWhatProduced(this, &AlignmentProducer::produceTracker);
00103   }
00104   if (doMuon_) {
00105      setWhatProduced(this, &AlignmentProducer::produceDT);
00106      setWhatProduced(this, &AlignmentProducer::produceCSC);
00107   }
00108 
00109   // Create the alignment algorithm
00110   edm::ParameterSet algoConfig = iConfig.getParameter<edm::ParameterSet>( "algoConfig" );
00111   edm::VParameterSet iovSelection = iConfig.getParameter<edm::VParameterSet>( "RunRangeSelection" );
00112   algoConfig.addUntrackedParameter<edm::VParameterSet>( "RunRangeSelection", iovSelection );
00113   std::string algoName = algoConfig.getParameter<std::string>( "algoName" );
00114   theAlignmentAlgo = AlignmentAlgorithmPluginFactory::get( )->create( algoName, algoConfig  );
00115 
00116   // Check if found
00117   if ( !theAlignmentAlgo )
00118         throw cms::Exception("BadConfig") << "Couldn't find algorithm called " << algoName;
00119 
00120   edm::ParameterSet monitorConfig = iConfig.getParameter<edm::ParameterSet>( "monitorConfig" );
00121   std::vector<std::string> monitors = monitorConfig.getUntrackedParameter<std::vector<std::string> >( "monitors" );
00122 
00123   for (std::vector<std::string>::const_iterator miter = monitors.begin();  miter != monitors.end();  ++miter) {
00124     AlignmentMonitorBase* newMonitor = AlignmentMonitorPluginFactory::get()->create(*miter, monitorConfig.getUntrackedParameter<edm::ParameterSet>(*miter));
00125 
00126     if (!newMonitor) throw cms::Exception("BadConfig") << "Couldn't find monitor named " << *miter;
00127 
00128     theMonitors.push_back(newMonitor);
00129   }
00130 }
00131 
00132 
00133 //_____________________________________________________________________________
00134 // Delete new objects
00135 AlignmentProducer::~AlignmentProducer()
00136 {
00137   delete theAlignmentParameterStore;
00138   delete theAlignableExtras;
00139   delete theAlignableTracker;
00140   delete theAlignableMuon;
00141 
00142   delete globalPositions_;
00143 }
00144 
00145 
00146 //_____________________________________________________________________________
00147 // Produce tracker geometry
00148 boost::shared_ptr<TrackerGeometry>
00149 AlignmentProducer::produceTracker( const TrackerDigiGeometryRecord& iRecord )
00150 {
00151   edm::LogInfo("Alignment") << "@SUB=AlignmentProducer::produceTracker";
00152   return theTracker;
00153 }
00154 
00155 //_____________________________________________________________________________
00156 // Produce muonDT geometry
00157 boost::shared_ptr<DTGeometry>
00158 AlignmentProducer::produceDT( const MuonGeometryRecord& iRecord )
00159 {
00160   edm::LogInfo("Alignment") << "@SUB=AlignmentProducer::produceDT";
00161   return theMuonDT;
00162 }
00163 
00164 //_____________________________________________________________________________
00165 // Produce muonCSC geometry
00166 boost::shared_ptr<CSCGeometry>
00167 AlignmentProducer::produceCSC( const MuonGeometryRecord& iRecord )
00168 {
00169   edm::LogInfo("Alignment") << "@SUB=AlignmentProducer::produceCSC";
00170   return theMuonCSC;  
00171 }
00172 
00173 
00174 //_____________________________________________________________________________
00175 // Initialize algorithm
00176 void AlignmentProducer::beginOfJob( const edm::EventSetup& iSetup )
00177 {
00178   edm::LogInfo("Alignment") << "@SUB=AlignmentProducer::beginOfJob";
00179 
00180   // Create the geometries from the ideal geometries (first time only)
00181   this->createGeometries_( iSetup );
00182   
00183   // Retrieve and apply alignments, if requested (requires DB setup)
00184   if ( applyDbAlignment_ ) {
00185     // we need GlobalPositionRcd - and have to keep track for later removal
00186     // before writing again to DB...
00187     edm::ESHandle<Alignments> globalPositionRcd;
00188     iSetup.get<GlobalPositionRcd>().get(globalPositionRcd);
00189     globalPositions_ = new Alignments(*globalPositionRcd);
00190 
00191     if ( doTracker_ ) {     // apply to tracker
00192       this->applyDB<TrackerGeometry,TrackerAlignmentRcd,TrackerAlignmentErrorRcd>
00193         (&(*theTracker), iSetup,  
00194          align::DetectorGlobalPosition(*globalPositions_, DetId(DetId::Tracker)));
00195       this->applyDB<TrackerGeometry,TrackerSurfaceDeformationRcd>(&(*theTracker), iSetup);
00196     }
00197     
00198     if ( doMuon_ ) { // apply to tracker
00199       this->applyDB<DTGeometry,DTAlignmentRcd,DTAlignmentErrorRcd>
00200         (&(*theMuonDT), iSetup,
00201          align::DetectorGlobalPosition(*globalPositions_, DetId(DetId::Muon)));
00202       this->applyDB<CSCGeometry,CSCAlignmentRcd,CSCAlignmentErrorRcd>
00203         (&(*theMuonCSC), iSetup,
00204          align::DetectorGlobalPosition(*globalPositions_, DetId(DetId::Muon)));
00205     }
00206   }
00207 
00208   // Create alignable tracker and muon 
00209   if (doTracker_) {
00210     theAlignableTracker = new AlignableTracker( &(*theTracker) );
00211   }
00212 
00213   if (doMuon_) {
00214      theAlignableMuon = new AlignableMuon( &(*theMuonDT), &(*theMuonCSC) );
00215   }
00216 
00217   if (useExtras_) {
00218     theAlignableExtras = new AlignableExtras();
00219   }
00220 
00221   // Create alignment parameter builder
00222   edm::LogInfo("Alignment") << "@SUB=AlignmentProducer::beginOfJob" 
00223                             << "Creating AlignmentParameterBuilder";
00224   edm::ParameterSet aliParamBuildCfg = 
00225     theParameterSet.getParameter<edm::ParameterSet>("ParameterBuilder");
00226   AlignmentParameterBuilder alignmentParameterBuilder(theAlignableTracker,
00227                                                       theAlignableMuon,
00228                                                       theAlignableExtras,
00229                                                       aliParamBuildCfg );
00230   // Fix alignables if requested
00231   if (stNFixAlignables_>0) alignmentParameterBuilder.fixAlignables(stNFixAlignables_);
00232 
00233   // Get list of alignables
00234   Alignables theAlignables = alignmentParameterBuilder.alignables();
00235   edm::LogInfo("Alignment") << "@SUB=AlignmentProducer::beginOfJob" 
00236                             << "got " << theAlignables.size() << " alignables";
00237 
00238   // Create AlignmentParameterStore 
00239   edm::ParameterSet aliParamStoreCfg = 
00240     theParameterSet.getParameter<edm::ParameterSet>("ParameterStore");
00241   theAlignmentParameterStore = new AlignmentParameterStore(theAlignables, aliParamStoreCfg);
00242   edm::LogInfo("Alignment") << "@SUB=AlignmentProducer::beginOfJob" 
00243                             << "AlignmentParameterStore created!";
00244 
00245   // Apply misalignment scenario to alignable tracker and muon if requested
00246   // WARNING: this assumes scenarioConfig can be passed to both muon and tracker
00247   if (doMisalignmentScenario_ && (doTracker_ || doMuon_)) {
00248     edm::LogInfo("Alignment") << "@SUB=AlignmentProducer::beginOfJob" 
00249                               << "Applying misalignment scenario to "
00250                               << (doTracker_ ? "tracker" : "")
00251                               << (doMuon_    ? (doTracker_ ? " and muon" : "muon") : ".");
00252     edm::ParameterSet scenarioConfig 
00253       = theParameterSet.getParameter<edm::ParameterSet>( "MisalignmentScenario" );
00254     if (doTracker_) {
00255       TrackerScenarioBuilder scenarioBuilder( theAlignableTracker );
00256       scenarioBuilder.applyScenario( scenarioConfig );
00257     }
00258     if (doMuon_) {
00259       MuonScenarioBuilder muonScenarioBuilder( theAlignableMuon );
00260       muonScenarioBuilder.applyScenario( scenarioConfig );
00261     }
00262   } else {
00263     edm::LogInfo("Alignment") << "@SUB=AlignmentProducer::beginOfJob" 
00264                               << "NOT applying misalignment scenario!";
00265   }
00266 
00267   // Apply simple misalignment
00268   const std::string sParSel(theParameterSet.getParameter<std::string>("parameterSelectorSimple"));
00269   this->simpleMisalignment_(theAlignables, sParSel, stRandomShift_, stRandomRotation_, true);
00270 
00271   // Initialize alignment algorithm
00272   theAlignmentAlgo->initialize( iSetup, 
00273                                 theAlignableTracker, theAlignableMuon, theAlignableExtras,
00274                                 theAlignmentParameterStore );
00275 
00276   for (std::vector<AlignmentMonitorBase*>::const_iterator monitor = theMonitors.begin();
00277        monitor != theMonitors.end();  ++monitor) {
00278      (*monitor)->beginOfJob(theAlignableTracker, theAlignableMuon, theAlignmentParameterStore);
00279   }
00280 }
00281 
00282 //_____________________________________________________________________________
00283 // Terminate algorithm
00284 void AlignmentProducer::endOfJob()
00285 {
00286   edm::LogInfo("Alignment") << "@SUB=AlignmentProducer::endOfJob";
00287 
00288   for (std::vector<AlignmentMonitorBase*>::const_iterator monitor = theMonitors.begin();  monitor != theMonitors.end();  ++monitor) {
00289      (*monitor)->endOfJob();
00290   }
00291 
00292   if (0 == nevent_) {
00293     edm::LogError("Alignment") << "@SUB=AlignmentProducer::endOfJob" << "Did not process any "
00294                                << "events in last loop, do not dare to store to DB.";
00295   } else {
00296     
00297     // Save alignments to database
00298     if (saveToDB_ || saveApeToDB_) {
00299       
00300       // Expand run ranges and make them unique
00301       edm::VParameterSet RunRangeSelectionVPSet = theParameterSet.getParameter<edm::VParameterSet>( "RunRangeSelection" );
00302       RunRanges uniqueRunRanges = makeNonOverlappingRunRanges(RunRangeSelectionVPSet);
00303 
00304       if ( doTracker_ ) { // first tracker
00305         const AlignTransform *trackerGlobal = 0; // will be 'removed' from constants 
00306         if (globalPositions_) { // i.e. applied before in applyDB
00307           trackerGlobal = &align::DetectorGlobalPosition(*globalPositions_,
00308                                                          DetId(DetId::Tracker));
00309         }
00310         // Get alignments+errors - ownership taken over by writeDB(..), so no delete
00311         
00312         for (std::vector<RunRange>::const_iterator iRunRange = uniqueRunRanges.begin();
00313              iRunRange != uniqueRunRanges.end();
00314              ++iRunRange) {
00315           theAlignmentAlgo->setParametersForRunRange(*iRunRange);
00316           Alignments *alignments = theAlignableTracker->alignments();
00317           AlignmentErrors *alignmentErrors = theAlignableTracker->alignmentErrors();
00318           this->writeDB(alignments, "TrackerAlignmentRcd",
00319                         alignmentErrors, "TrackerAlignmentErrorRcd", trackerGlobal,
00320                         (*iRunRange).first);
00321         }
00322       }
00323       
00324       if ( doMuon_ ) { // now muon
00325         const AlignTransform *muonGlobal = 0; // will be 'removed' from constants 
00326         if (globalPositions_) { // i.e. applied before in applyDB
00327           muonGlobal = &align::DetectorGlobalPosition(*globalPositions_,
00328                                                       DetId(DetId::Muon));
00329         }
00330         // Get alignments+errors, first DT - ownership taken over by writeDB(..), so no delete
00331         Alignments      *alignments       = theAlignableMuon->dtAlignments();
00332         AlignmentErrors *alignmentErrors  = theAlignableMuon->dtAlignmentErrors();
00333         this->writeDB(alignments, "DTAlignmentRcd",
00334                       alignmentErrors, "DTAlignmentErrorRcd", muonGlobal);
00335         
00336         // Get alignments+errors, now CSC - ownership taken over by writeDB(..), so no delete
00337         alignments       = theAlignableMuon->cscAlignments();
00338         alignmentErrors  = theAlignableMuon->cscAlignmentErrors();
00339         this->writeDB(alignments, "CSCAlignmentRcd",
00340                       alignmentErrors, "CSCAlignmentErrorRcd", muonGlobal);
00341       }
00342       
00343       // Save surface deformations to database
00344       if (saveDeformationsToDB_ && doTracker_) {
00345         AlignmentSurfaceDeformations *alignmentSurfaceDeformations = theAlignableTracker->surfaceDeformations();
00346         this->writeDB(alignmentSurfaceDeformations, "TrackerSurfaceDeformationRcd");
00347       }
00348       
00349     }
00350   }
00351   
00352   if (theAlignableExtras) theAlignableExtras->dump();
00353 }
00354 
00355 //_____________________________________________________________________________
00356 // Called at beginning of loop
00357 void AlignmentProducer::startingNewLoop(unsigned int iLoop )
00358 {
00359   edm::LogInfo("Alignment") << "@SUB=AlignmentProducer::startingNewLoop" 
00360                             << "Starting loop number " << iLoop;
00361 
00362   nevent_ = 0;
00363 
00364   theAlignmentAlgo->startNewLoop();
00365 
00366   for (std::vector<AlignmentMonitorBase*>::const_iterator monitor = theMonitors.begin();  monitor != theMonitors.end();  ++monitor) {
00367      (*monitor)->startingNewLoop();
00368   }
00369 
00370   edm::LogInfo("Alignment") << "@SUB=AlignmentProducer::startingNewLoop" 
00371                             << "Now physically apply alignments to  geometry...";
00372 
00373 
00374   // Propagate changes to reconstruction geometry (from initialisation or iteration)
00375   GeometryAligner aligner;
00376   if ( doTracker_ ) {
00377     std::auto_ptr<Alignments> alignments(theAlignableTracker->alignments());
00378     std::auto_ptr<AlignmentErrors> alignmentErrors(theAlignableTracker->alignmentErrors());
00379     aligner.applyAlignments<TrackerGeometry>( &(*theTracker),&(*alignments),&(*alignmentErrors), AlignTransform() ); // don't apply global a second time!
00380     std::auto_ptr<AlignmentSurfaceDeformations> aliDeforms(theAlignableTracker->surfaceDeformations());
00381     aligner.attachSurfaceDeformations<TrackerGeometry>(&(*theTracker), &(*aliDeforms));
00382 
00383   }
00384   if ( doMuon_ ) {
00385     std::auto_ptr<Alignments>      dtAlignments(       theAlignableMuon->dtAlignments());
00386     std::auto_ptr<AlignmentErrors> dtAlignmentErrors(  theAlignableMuon->dtAlignmentErrors());
00387     std::auto_ptr<Alignments>      cscAlignments(      theAlignableMuon->cscAlignments());
00388     std::auto_ptr<AlignmentErrors> cscAlignmentErrors( theAlignableMuon->cscAlignmentErrors());
00389 
00390     aligner.applyAlignments<DTGeometry>( &(*theMuonDT), &(*dtAlignments), &(*dtAlignmentErrors), AlignTransform() ); // don't apply global a second time!
00391     aligner.applyAlignments<CSCGeometry>( &(*theMuonCSC), &(*cscAlignments), &(*cscAlignmentErrors), AlignTransform() ); // nope!
00392   }
00393 }
00394 
00395 
00396 //_____________________________________________________________________________
00397 // Called at end of loop
00398 edm::EDLooper::Status 
00399 AlignmentProducer::endOfLoop(const edm::EventSetup& iSetup, unsigned int iLoop)
00400 {
00401 
00402   if (0 == nevent_) {
00403     // beginOfJob is usually called by the framework in the first event of the first loop
00404     // (a hack: beginOfJob needs the EventSetup that is not well defined without an event)
00405     // and the algorithms rely on the initialisations done in beginOfJob. We cannot call 
00406     // this->beginOfJob(iSetup); here either since that will access the EventSetup to get
00407     // some geometry information that is not defined either without having seen an event.
00408     edm::LogError("Alignment") << "@SUB=AlignmentProducer::endOfLoop" 
00409                                << "Did not process any events in loop " << iLoop
00410                                << ", stop processing without terminating algorithm.";
00411     return kStop;
00412   }
00413 
00414   edm::LogInfo("Alignment") << "@SUB=AlignmentProducer::endOfLoop" 
00415                             << "Ending loop " << iLoop << ", terminating algorithm.";
00416 
00417   theAlignmentAlgo->terminate();
00418 
00419   for (std::vector<AlignmentMonitorBase*>::const_iterator monitor = theMonitors.begin();  monitor != theMonitors.end();  ++monitor) {
00420      (*monitor)->endOfLoop(iSetup);
00421   }
00422 
00423   if ( iLoop == theMaxLoops-1 || iLoop >= theMaxLoops ) return kStop;
00424   else return kContinue;
00425 }
00426 
00427 //_____________________________________________________________________________
00428 // Called at each event
00429 edm::EDLooper::Status 
00430 AlignmentProducer::duringLoop( const edm::Event& event, 
00431                                const edm::EventSetup& setup )
00432 {
00433   ++nevent_;
00434 
00435   // reading in survey records
00436   this->readInSurveyRcds(setup);
00437         
00438   // Printout event number
00439   for ( int i=10; i<10000000; i*=10 )
00440     if ( nevent_<10*i && (nevent_%i)==0 )
00441       edm::LogInfo("Alignment") << "@SUB=AlignmentProducer::duringLoop" 
00442                                 << "Events processed: " << nevent_;
00443   
00444   // Retrieve trajectories and tracks from the event
00445   // -> merely skip if collection is empty
00446   edm::Handle<TrajTrackAssociationCollection> m_TrajTracksMap;
00447   if (event.getByLabel(tjTkAssociationMapTag_, m_TrajTracksMap)) {
00448     
00449     // Form pairs of trajectories and tracks
00450     ConstTrajTrackPairCollection trajTracks;
00451     for ( TrajTrackAssociationCollection::const_iterator iPair = m_TrajTracksMap->begin();
00452           iPair != m_TrajTracksMap->end(); ++iPair) {
00453       trajTracks.push_back( ConstTrajTrackPair( &(*(*iPair).key), &(*(*iPair).val) ) );
00454     }
00455     edm::Handle<reco::BeamSpot> beamSpot;
00456     event.getByLabel(beamSpotTag_, beamSpot);
00457 
00458     if (nevent_==1 && theAlignableExtras) {
00459       edm::LogInfo("Alignment") << "@SUB=AlignmentProducer::duringLoop"
00460                                 << "initializing AlignableBeamSpot" << std::endl;
00461       theAlignableExtras->initializeBeamSpot(beamSpot->x0(), beamSpot->y0(), beamSpot->z0(),
00462                                              beamSpot->dxdz(), beamSpot->dydz());
00463     }
00464 
00465     // Run the alignment algorithm with its input
00466     const AliClusterValueMap *clusterValueMapPtr = 0;
00467     if(clusterValueMapTag_.encode().size()){//check that the input tag is not empty
00468       edm::Handle<AliClusterValueMap> clusterValueMap;
00469       event.getByLabel(clusterValueMapTag_, clusterValueMap);
00470       clusterValueMapPtr = &(*clusterValueMap);
00471     }
00472 
00473     const AlignmentAlgorithmBase::EventInfo eventInfo(event.id(), trajTracks, *beamSpot,
00474                                                       clusterValueMapPtr);
00475     theAlignmentAlgo->run(setup, eventInfo);
00476 
00477 
00478     for (std::vector<AlignmentMonitorBase*>::const_iterator monitor = theMonitors.begin();
00479          monitor != theMonitors.end();  ++monitor) {
00480       (*monitor)->duringLoop(event, setup, trajTracks); // forward eventInfo?
00481     }
00482   } else {
00483     edm::LogError("Alignment") << "@SUB=AlignmentProducer::duringLoop" 
00484                                << "No track collection found: skipping event";
00485   }
00486   
00487 
00488   return kContinue;
00489 }
00490 
00491 // ----------------------------------------------------------------------------
00492 void AlignmentProducer::beginRun(const edm::Run &run, const edm::EventSetup &setup)
00493 {
00494   theAlignmentAlgo->beginRun(setup); // do not forward edm::Run...
00495 }
00496 
00497 // ----------------------------------------------------------------------------
00498 void AlignmentProducer::endRun(const edm::Run &run, const edm::EventSetup &setup)
00499 {
00500   // call with or without las beam info...
00501   typedef AlignmentAlgorithmBase::EndRunInfo EndRunInfo;
00502   if (tkLasBeamTag_.encode().size()) { // non-empty InputTag
00503     edm::Handle<TkFittedLasBeamCollection> lasBeams;
00504     edm::Handle<TsosVectorCollection> tsoses;
00505     run.getByLabel(tkLasBeamTag_, lasBeams);
00506     run.getByLabel(tkLasBeamTag_, tsoses);
00507     
00508     theAlignmentAlgo->endRun(EndRunInfo(run.id(), &(*lasBeams), &(*tsoses)), setup);
00509   } else {
00510     edm::LogInfo("Alignment") << "@SUB=AlignmentProducer::endRun"
00511                               << "No Tk LAS beams to forward to algorithm.";
00512     theAlignmentAlgo->endRun(EndRunInfo(run.id(), 0, 0), setup);
00513   }
00514 }
00515 
00516 // ----------------------------------------------------------------------------
00517 void AlignmentProducer::beginLuminosityBlock(const edm::LuminosityBlock &lumiBlock,
00518                                     const edm::EventSetup &setup)
00519 {
00520   theAlignmentAlgo->beginLuminosityBlock(setup); // do not forward edm::LuminosityBlock
00521 }
00522 
00523 // ----------------------------------------------------------------------------
00524 void AlignmentProducer::endLuminosityBlock(const edm::LuminosityBlock &lumiBlock,
00525                                   const edm::EventSetup &setup)
00526 {
00527   theAlignmentAlgo->endLuminosityBlock(setup); // do not forward edm::LuminosityBlock
00528 }
00529 
00530 // ----------------------------------------------------------------------------
00531 
00532 void AlignmentProducer::simpleMisalignment_(const Alignables &alivec, const std::string &selection, 
00533                                             float shift, float rot, bool local)
00534 {
00535 
00536   std::ostringstream output; // collecting output
00537 
00538   if (shift > 0. || rot > 0.) {
00539     output << "Adding random flat shift of max size " << shift
00540            << " and adding random flat rotation of max size " << rot <<" to ";
00541 
00542     std::vector<bool> commSel(0);
00543     if (selection != "-1") {
00544       AlignmentParameterSelector aSelector(0,0); // no alignable needed here...
00545       const std::vector<char> cSel(aSelector.convertParamSel(selection));
00546       if (cSel.size() < RigidBodyAlignmentParameters::N_PARAM) {
00547         throw cms::Exception("BadConfig") 
00548           << "[AlignmentProducer::simpleMisalignment_]\n"
00549           << "Expect selection string '" << selection << "' to be at least of length " 
00550           << RigidBodyAlignmentParameters::N_PARAM << " or to be '-1'.\n"
00551           << "(Most probably you have to adjust the parameter 'parameterSelectorSimple'.)";
00552       }
00553       for (std::vector<char>::const_iterator cIter = cSel.begin(); cIter != cSel.end(); ++cIter) {
00554         commSel.push_back(*cIter == '0' ? false : true);
00555       }
00556       output << "parameters defined by (" << selection 
00557              << "), representing (x,y,z,alpha,beta,gamma),";
00558     } else {
00559       output << "the active parameters of each alignable,";
00560     }
00561     output << " in " << (local ? "local" : "global") << " frame.";
00562 
00563     for (std::vector<Alignable*>::const_iterator it = alivec.begin(); it != alivec.end(); ++it) {
00564       Alignable* ali=(*it);
00565       std::vector<bool> mysel(commSel.empty() ? ali->alignmentParameters()->selector() : commSel);
00566       
00567       if (std::abs(shift)>0.00001) {
00568         double s0 = 0., s1 = 0., s2 = 0.;
00569         if (mysel[RigidBodyAlignmentParameters::dx]) s0 = shift * double(random()%1000-500)/500.;
00570         if (mysel[RigidBodyAlignmentParameters::dy]) s1 = shift * double(random()%1000-500)/500.;
00571         if (mysel[RigidBodyAlignmentParameters::dz]) s2 = shift * double(random()%1000-500)/500.;
00572         
00573         if (local) ali->move( ali->surface().toGlobal(align::LocalVector(s0,s1,s2)) );
00574         else       ali->move( align::GlobalVector(s0,s1,s2) );
00575 
00576       //AlignmentPositionError ape(dx,dy,dz);
00577       //ali->addAlignmentPositionError(ape);
00578       }
00579 
00580       if (std::abs(rot)>0.00001) {
00581         align::EulerAngles r(3);
00582         if (mysel[RigidBodyAlignmentParameters::dalpha]) r(1)=rot*double(random()%1000-500)/500.;
00583         if (mysel[RigidBodyAlignmentParameters::dbeta])  r(2)=rot*double(random()%1000-500)/500.;
00584         if (mysel[RigidBodyAlignmentParameters::dgamma]) r(3)=rot*double(random()%1000-500)/500.;
00585 
00586         const align::RotationType mrot = align::toMatrix(r);
00587         if (local) ali->rotateInLocalFrame(mrot);
00588         else       ali->rotateInGlobalFrame(mrot);
00589         
00590       //ali->addAlignmentPositionErrorFromRotation(mrot);
00591       }
00592     } // end loop on alignables
00593   } else {
00594     output << "No simple misalignment added!";
00595   }
00596   edm::LogInfo("Alignment")  << "@SUB=AlignmentProducer::simpleMisalignment_" << output.str();
00597 }
00598 
00599 
00600 //__________________________________________________________________________________________________
00601 void AlignmentProducer::createGeometries_( const edm::EventSetup& iSetup )
00602 {
00603    edm::ESTransientHandle<DDCompactView> cpv;
00604    iSetup.get<IdealGeometryRecord>().get( cpv );
00605 
00606    if (doTracker_) {
00607      edm::ESHandle<GeometricDet> geometricDet;
00608      iSetup.get<IdealGeometryRecord>().get( geometricDet );
00609      TrackerGeomBuilderFromGeometricDet trackerBuilder;
00610      theTracker = boost::shared_ptr<TrackerGeometry>( trackerBuilder.build(&(*geometricDet)) );
00611    }
00612 
00613    if (doMuon_) {
00614      edm::ESHandle<MuonDDDConstants> mdc;
00615      iSetup.get<MuonNumberingRecord>().get(mdc);
00616      DTGeometryBuilderFromDDD DTGeometryBuilder;
00617      CSCGeometryBuilderFromDDD CSCGeometryBuilder;
00618      theMuonDT = boost::shared_ptr<DTGeometry>(new DTGeometry );
00619      DTGeometryBuilder.build( theMuonDT, &(*cpv), *mdc);
00620      theMuonCSC = boost::shared_ptr<CSCGeometry>( new CSCGeometry );
00621      CSCGeometryBuilder.build( theMuonCSC, &(*cpv), *mdc );
00622    }
00623 }
00624 
00625 void AlignmentProducer::addSurveyInfo_(Alignable* ali)
00626 {
00627   const std::vector<Alignable*>& comp = ali->components();
00628 
00629   unsigned int nComp = comp.size();
00630 
00631   for (unsigned int i = 0; i < nComp; ++i) addSurveyInfo_(comp[i]);
00632 
00633   const SurveyError& error = theSurveyErrors->m_surveyErrors[theSurveyIndex];
00634 
00635   if ( ali->id() != error.rawId() ||
00636        ali->alignableObjectId() != error.structureType() )
00637   {
00638     throw cms::Exception("DatabaseError")
00639       << "Error reading survey info from DB. Mismatched id!";
00640   }
00641 
00642   const CLHEP::Hep3Vector&  pos = theSurveyValues->m_align[theSurveyIndex].translation();
00643   const CLHEP::HepRotation& rot = theSurveyValues->m_align[theSurveyIndex].rotation();
00644 
00645   AlignableSurface surf( align::PositionType( pos.x(), pos.y(), pos.z() ),
00646                          align::RotationType( rot.xx(), rot.xy(), rot.xz(),
00647                                               rot.yx(), rot.yy(), rot.yz(),
00648                                               rot.zx(), rot.zy(), rot.zz() ) );
00649 
00650   surf.setWidth( ali->surface().width() );
00651   surf.setLength( ali->surface().length() );
00652 
00653   ali->setSurvey( new SurveyDet( surf, error.matrix() ) );
00654 
00655   ++theSurveyIndex;
00656 }
00657 
00658 void AlignmentProducer::readInSurveyRcds( const edm::EventSetup& iSetup ){
00659         
00660   // Get Survey Rcds and add Survey Info
00661   if ( doTracker_ && useSurvey_ ){
00662     bool tkSurveyBool = watchTkSurveyRcd_.check(iSetup);
00663     bool tkSurveyErrBool = watchTkSurveyErrRcd_.check(iSetup);
00664     edm::LogInfo("Alignment") << "watcher tksurveyrcd: " << tkSurveyBool;
00665     edm::LogInfo("Alignment") << "watcher tksurveyerrrcd: " << tkSurveyErrBool;
00666     if ( tkSurveyBool || tkSurveyErrBool){
00667       
00668       edm::LogInfo("Alignment") << "ADDING THE SURVEY INFORMATION";
00669       edm::ESHandle<Alignments> surveys;
00670       edm::ESHandle<SurveyErrors> surveyErrors;
00671       
00672       iSetup.get<TrackerSurveyRcd>().get(surveys);
00673       iSetup.get<TrackerSurveyErrorRcd>().get(surveyErrors);
00674       
00675       theSurveyIndex  = 0;
00676       theSurveyValues = &*surveys;
00677       theSurveyErrors = &*surveyErrors;
00678       addSurveyInfo_(theAlignableTracker);
00679     }
00680   }
00681   
00682   if ( doMuon_ && useSurvey_) {
00683     bool DTSurveyBool = watchTkSurveyRcd_.check(iSetup);
00684     bool DTSurveyErrBool = watchTkSurveyErrRcd_.check(iSetup);
00685     bool CSCSurveyBool = watchTkSurveyRcd_.check(iSetup);
00686     bool CSCSurveyErrBool = watchTkSurveyErrRcd_.check(iSetup);
00687     
00688     if ( DTSurveyBool || DTSurveyErrBool || CSCSurveyBool || CSCSurveyErrBool ){
00689       edm::ESHandle<Alignments> dtSurveys;
00690       edm::ESHandle<SurveyErrors> dtSurveyErrors;
00691       edm::ESHandle<Alignments> cscSurveys;
00692       edm::ESHandle<SurveyErrors> cscSurveyErrors;
00693       
00694       iSetup.get<DTSurveyRcd>().get(dtSurveys);
00695       iSetup.get<DTSurveyErrorRcd>().get(dtSurveyErrors);
00696       iSetup.get<CSCSurveyRcd>().get(cscSurveys);
00697       iSetup.get<CSCSurveyErrorRcd>().get(cscSurveyErrors);
00698       
00699       theSurveyIndex  = 0;
00700       theSurveyValues = &*dtSurveys;
00701       theSurveyErrors = &*dtSurveyErrors;
00702       std::vector<Alignable*> barrels = theAlignableMuon->DTBarrel();
00703       for (std::vector<Alignable*>::const_iterator iter = barrels.begin();  iter != barrels.end();  ++iter) {
00704         addSurveyInfo_(*iter);
00705       }
00706       
00707       theSurveyIndex  = 0;
00708       theSurveyValues = &*cscSurveys;
00709       theSurveyErrors = &*cscSurveyErrors;
00710       std::vector<Alignable*> endcaps = theAlignableMuon->CSCEndcaps();
00711       for (std::vector<Alignable*>::const_iterator iter = endcaps.begin();  iter != endcaps.end();  ++iter) {
00712         addSurveyInfo_(*iter);
00713       }
00714     }
00715   }
00716 
00717 }
00718 
00719 
00721 // a templated method - but private, so not accessible from outside
00722 // ==> does not have to be in header file
00723 template<class G, class Rcd, class ErrRcd>
00724 void AlignmentProducer::applyDB(G* geometry, const edm::EventSetup &iSetup,
00725                                 const AlignTransform &globalCoordinates) const
00726 {
00727   // 'G' is the geometry class for that DB should be applied,
00728   // 'Rcd' is the record class for its Alignments 
00729   // 'ErrRcd' is the record class for its AlignmentErrors
00730   // 'globalCoordinates' are global transformation for this geometry
00731   edm::ESHandle<Alignments> alignments;
00732   iSetup.get<Rcd>().get(alignments);
00733 
00734   edm::ESHandle<AlignmentErrors> alignmentErrors;
00735   iSetup.get<ErrRcd>().get(alignmentErrors);
00736 
00737   GeometryAligner aligner;
00738   aligner.applyAlignments<G>(geometry, &(*alignments), &(*alignmentErrors),
00739                              globalCoordinates);
00740 }
00741 
00742 
00744 // a templated method - but private, so not accessible from outside
00745 // ==> does not have to be in header file
00746 template<class G, class DeformationRcd>
00747 void AlignmentProducer::applyDB(G* geometry, const edm::EventSetup &iSetup) const
00748 {
00749   // 'G' is the geometry class for that DB should be applied,
00750   // 'DeformationRcd' is the record class for its surface deformations 
00751   edm::ESHandle<AlignmentSurfaceDeformations> surfaceDeformations;
00752   iSetup.get<DeformationRcd>().get(surfaceDeformations);
00753 
00754   GeometryAligner aligner;
00755   aligner.attachSurfaceDeformations<G>(geometry, &(*surfaceDeformations));
00756 }
00757 
00758 
00760 void AlignmentProducer::writeDB(Alignments *alignments,
00761                                 const std::string &alignRcd,
00762                                 AlignmentErrors *alignmentErrors,
00763                                 const std::string &errRcd,
00764                                 const AlignTransform *globalCoordinates,
00765                                 cond::Time_t time) const
00766 {
00767   Alignments * tempAlignments = alignments;
00768   AlignmentErrors * tempAlignmentErrors = alignmentErrors;
00769 
00770   // Call service
00771   edm::Service<cond::service::PoolDBOutputService> poolDb;
00772   if (!poolDb.isAvailable()) { // Die if not available
00773     delete tempAlignments;      // promised to take over ownership...
00774     delete tempAlignmentErrors; // dito
00775     throw cms::Exception("NotAvailable") << "PoolDBOutputService not available";
00776   }
00777 
00778   if (globalCoordinates  // happens only if (applyDbAlignment_ == true)
00779       && globalCoordinates->transform() != AlignTransform::Transform::Identity) {
00780 
00781     tempAlignments = new Alignments();            // temporary storage for
00782     tempAlignmentErrors = new AlignmentErrors();  // final alignments and errors
00783 
00784     GeometryAligner aligner;
00785     aligner.removeGlobalTransform(alignments, alignmentErrors,
00786                                   *globalCoordinates,
00787                                   tempAlignments, tempAlignmentErrors);
00788     
00789     delete alignments;       // have to delete original alignments
00790     delete alignmentErrors;  // same thing for the errors
00791 
00792     edm::LogInfo("Alignment") << "@SUB=AlignmentProducer::writeDB"
00793                               << "globalCoordinates removed from alignments (" << alignRcd
00794                               << ") and errors (" << alignRcd << ").";
00795   }
00796   
00797   if (saveToDB_) {
00798     edm::LogInfo("Alignment") << "Writing Alignments to " << alignRcd << ".";
00799     poolDb->writeOne<Alignments>(tempAlignments, 0, time, alignRcd);
00800   } else { // poolDb->writeOne(..) takes over 'alignments' ownership,...
00801     delete tempAlignments; // ...otherwise we have to delete, as promised!
00802   }
00803 
00804   if (saveApeToDB_) {
00805     edm::LogInfo("Alignment") << "Writing AlignmentErrors to " << errRcd << ".";
00806     poolDb->writeOne<AlignmentErrors>(tempAlignmentErrors, 0, time, errRcd);
00807   } else { // poolDb->writeOne(..) takes over 'alignmentErrors' ownership,...
00808     delete tempAlignmentErrors; // ...otherwise we have to delete, as promised!
00809   }
00810 }
00811 
00812 
00814 void AlignmentProducer::writeDB(AlignmentSurfaceDeformations *alignmentSurfaceDeformations,
00815                                 const std::string &surfaceDeformationRcd) const
00816 {
00817   // Call service
00818   edm::Service<cond::service::PoolDBOutputService> poolDb;
00819   if (!poolDb.isAvailable()) { // Die if not available
00820     delete alignmentSurfaceDeformations; // promised to take over ownership...
00821     throw cms::Exception("NotAvailable") << "PoolDBOutputService not available";
00822   }
00823   
00824   if (saveDeformationsToDB_) {
00825     edm::LogInfo("Alignment") << "Writing AlignmentSurfaceDeformations to "
00826                               << surfaceDeformationRcd  << ".";
00827     poolDb->writeOne<AlignmentSurfaceDeformations>(alignmentSurfaceDeformations, poolDb->beginOfTime(),
00828                                                    surfaceDeformationRcd);
00829   } else { // poolDb->writeOne(..) takes over 'surfaceDeformation' ownership,...
00830     delete alignmentSurfaceDeformations; // ...otherwise we have to delete, as promised!
00831   }
00832 }
00833 
00834 AlignmentProducer::RunRanges
00835 AlignmentProducer::makeNonOverlappingRunRanges(const edm::VParameterSet& RunRangeSelectionVPSet)
00836 {
00837   const RunNumber beginValue = cond::timeTypeSpecs[cond::runnumber].beginValue;
00838   const RunNumber endValue = cond::timeTypeSpecs[cond::runnumber].endValue;
00839       
00840   RunRanges uniqueRunRanges;
00841   std::map<RunNumber,RunNumber> uniqueFirstRunNumbers;
00842   std::map<RunNumber,RunNumber> uniqueLastRunNumbers;
00843   if (RunRangeSelectionVPSet.size()==0) {
00844     uniqueFirstRunNumbers[beginValue] = beginValue;
00845     uniqueLastRunNumbers[endValue] = endValue;
00846   } else {
00847     for (std::vector<edm::ParameterSet>::const_iterator ipset = RunRangeSelectionVPSet.begin();
00848          ipset != RunRangeSelectionVPSet.end();
00849          ++ipset) {
00850       const std::vector<std::string> RunRangeStrings = (*ipset).getParameter<std::vector<std::string> >("RunRanges");
00851       for (std::vector<std::string>::const_iterator irange = RunRangeStrings.begin();
00852            irange != RunRangeStrings.end();
00853            ++irange) {
00854         std::vector<std::string> tokens = edm::tokenize(*irange, ":");
00855         long int temp;
00856         
00857         RunNumber first = beginValue;
00858         temp = strtol(tokens[0].c_str(), 0, 0);
00859         if (temp!=-1) first = temp;
00860         uniqueFirstRunNumbers[first] = first;
00861         
00862         RunNumber last = endValue;
00863         temp = strtol(tokens[1].c_str(), 0, 0);
00864         if (temp!=-1) last = temp;
00865         uniqueLastRunNumbers[last] = last;
00866       }
00867     }
00868   }
00869   
00870   for (std::map<RunNumber,RunNumber>::iterator iFirst = uniqueFirstRunNumbers.begin();
00871        iFirst!=uniqueFirstRunNumbers.end();
00872        ++iFirst) {
00873     for (std::map<RunNumber,RunNumber>::iterator iLast = uniqueLastRunNumbers.begin();
00874          iLast!=uniqueLastRunNumbers.end();
00875          ++iLast) {
00876       if ((*iLast).first>(*iFirst).first) {
00877         uniqueRunRanges.push_back(std::pair<RunNumber,RunNumber>((*iFirst).first, (*iLast).first));
00878         break;
00879       }
00880     }
00881   }
00882  
00883   return uniqueRunRanges;
00884 }
00885 
00886 DEFINE_FWK_LOOPER( AlignmentProducer );