CMS 3D CMS Logo

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