Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-01-21 00:19:04

0001 #include "Alignment/CommonAlignmentProducer/interface/AlignmentProducerBase.h"
0002 
0003 #include "Alignment/CommonAlignment/interface/AlignableExtras.h"
0004 #include "Alignment/CommonAlignment/interface/SurveyDet.h"
0005 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentAlgorithmPluginFactory.h"
0006 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterBuilder.h"
0007 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterSelector.h"
0008 #include "Alignment/CommonAlignmentAlgorithm/interface/IntegratedCalibrationPluginFactory.h"
0009 #include "Alignment/CommonAlignmentMonitor/interface/AlignmentMonitorPluginFactory.h"
0010 #include "Alignment/CommonAlignmentParametrization/interface/BeamSpotAlignmentParameters.h"
0011 #include "Alignment/CommonAlignmentParametrization/interface/RigidBodyAlignmentParameters.h"
0012 #include "Alignment/MuonAlignment/interface/MuonScenarioBuilder.h"
0013 #include "Alignment/TrackerAlignment/interface/TrackerScenarioBuilder.h"
0014 
0015 #include "CondCore/DBOutputService/interface/PoolDBOutputService.h"
0016 
0017 #include "CondFormats/Alignment/interface/DetectorGlobalPosition.h"
0018 #include "CondFormats/Alignment/interface/SurveyError.h"
0019 #include "CondFormats/Alignment/interface/SurveyErrors.h"
0020 
0021 #include "FWCore/Framework/interface/ESTransientHandle.h"
0022 #include "FWCore/Framework/interface/Run.h"
0023 #include "FWCore/ServiceRegistry/interface/Service.h"
0024 
0025 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeomBuilderFromGeometricDet.h"
0026 
0027 //------------------------------------------------------------------------------
0028 AlignmentProducerBase::AlignmentProducerBase(const edm::ParameterSet& config, edm::ConsumesCollector iC)
0029     : doTracker_{config.getUntrackedParameter<bool>("doTracker")},
0030       doMuon_{config.getUntrackedParameter<bool>("doMuon")},
0031       useExtras_{config.getUntrackedParameter<bool>("useExtras")},
0032       tjTkAssociationMapTag_{config.getParameter<edm::InputTag>("tjTkAssociationMapTag")},
0033       beamSpotTag_{config.getParameter<edm::InputTag>("beamSpotTag")},
0034       tkLasBeamTag_{config.getParameter<edm::InputTag>("tkLasBeamTag")},
0035       clusterValueMapTag_{config.getParameter<edm::InputTag>("hitPrescaleMapTag")},
0036       uniqueRunRanges_{align::makeUniqueRunRanges(config.getParameter<edm::VParameterSet>("RunRangeSelection"),
0037                                                   cond::timeTypeSpecs[cond::runnumber].beginValue)},
0038       config_{config},
0039       stNFixAlignables_{config.getParameter<int>("nFixAlignables")},
0040       stRandomShift_{config.getParameter<double>("randomShift")},
0041       stRandomRotation_{config.getParameter<double>("randomRotation")},
0042       applyDbAlignment_{config.getUntrackedParameter<bool>("applyDbAlignment")},
0043       checkDbAlignmentValidity_{config.getUntrackedParameter<bool>("checkDbAlignmentValidity")},
0044       doMisalignmentScenario_{config.getParameter<bool>("doMisalignmentScenario")},
0045       saveToDB_{config.getParameter<bool>("saveToDB")},
0046       saveApeToDB_{config.getParameter<bool>("saveApeToDB")},
0047       saveDeformationsToDB_{config.getParameter<bool>("saveDeformationsToDB")},
0048       useSurvey_{config.getParameter<bool>("useSurvey")},
0049       enableAlignableUpdates_{config.getParameter<bool>("enableAlignableUpdates")},
0050       tkAliRcdName_{config.getParameter<std::string>("trackerAlignmentRcdName")},
0051       ttopoToken_(iC.esConsumes<edm::Transition::BeginRun>()),
0052       geomDetToken_(iC.esConsumes<edm::Transition::BeginRun>()),
0053       ptpToken_(iC.esConsumes<edm::Transition::BeginRun>()),
0054       dtGeomToken_(iC.esConsumes<edm::Transition::BeginRun>(edm::ESInputTag("", "idealForAlignmentProducerBase"))),
0055       cscGeomToken_(iC.esConsumes<edm::Transition::BeginRun>(edm::ESInputTag("", "idealForAlignmentProducerBase"))),
0056       gemGeomToken_(iC.esConsumes<edm::Transition::BeginRun>(edm::ESInputTag("", "idealForAlignmentProducerBase"))),
0057       tkAliToken_(iC.esConsumes<edm::Transition::BeginRun>()),
0058       dtAliToken_(iC.esConsumes<edm::Transition::BeginRun>()),
0059       cscAliToken_(iC.esConsumes<edm::Transition::BeginRun>()),
0060       gemAliToken_(iC.esConsumes<edm::Transition::BeginRun>()),
0061       tkAliErrToken_(iC.esConsumes<edm::Transition::BeginRun>()),
0062       dtAliErrToken_(iC.esConsumes<edm::Transition::BeginRun>()),
0063       cscAliErrToken_(iC.esConsumes<edm::Transition::BeginRun>()),
0064       gemAliErrToken_(iC.esConsumes<edm::Transition::BeginRun>()),
0065       tkSurfDefToken_(iC.esConsumes<edm::Transition::BeginRun>()),
0066       gprToken_(iC.esConsumes<edm::Transition::BeginRun>()),
0067       tkSurveyToken_(iC.esConsumes<edm::Transition::BeginRun>()),
0068       tkSurvErrorToken_(iC.esConsumes<edm::Transition::BeginRun>()),
0069       dtSurveyToken_(iC.esConsumes<edm::Transition::BeginRun>()),
0070       dtSurvErrorToken_(iC.esConsumes<edm::Transition::BeginRun>()),
0071       cscSurveyToken_(iC.esConsumes<edm::Transition::BeginRun>()),
0072       cscSurvErrorToken_(iC.esConsumes<edm::Transition::BeginRun>()) {
0073   edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::AlignmentProducerBase";
0074 
0075   const auto& algoConfig = config_.getParameterSet("algoConfig");
0076   if (config_.existsAs<bool>("runAtPCL")) {
0077     // configured in main config?
0078     runAtPCL_ = config_.getParameter<bool>("runAtPCL");
0079 
0080     if (algoConfig.existsAs<bool>("runAtPCL") && (runAtPCL_ != algoConfig.getParameter<bool>("runAtPCL"))) {
0081       throw cms::Exception("BadConfig") << "Inconsistent settings for 'runAtPCL' in configuration of the "
0082                                         << "alignment producer and the alignment algorithm.";
0083     }
0084 
0085   } else if (algoConfig.existsAs<bool>("runAtPCL")) {
0086     // configured in algo config?
0087     runAtPCL_ = algoConfig.getParameter<bool>("runAtPCL");
0088 
0089   } else {
0090     // assume 'false' if it was not configured
0091     runAtPCL_ = false;
0092   }
0093 
0094   createAlignmentAlgorithm(iC);
0095   createMonitors(iC);
0096   createCalibrations(iC);
0097 }
0098 
0099 //------------------------------------------------------------------------------
0100 AlignmentProducerBase::~AlignmentProducerBase() noexcept(false) {}
0101 
0102 //------------------------------------------------------------------------------
0103 void AlignmentProducerBase::startProcessing() {
0104   if (isDuringLoop_)
0105     return;
0106 
0107   edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::startProcessing"
0108                             << "Begin";
0109 
0110   if (!isAlgoInitialized_) {
0111     throw cms::Exception("LogicError") << "@SUB=AlignmentProducerBase::startProcessing\n"
0112                                        << "Trying to start event processing before initializing the alignment "
0113                                        << "algorithm.";
0114   }
0115 
0116   nevent_ = 0;
0117 
0118   alignmentAlgo_->startNewLoop();
0119 
0120   // FIXME: Should this be done in algorithm::startNewLoop()??
0121   for (const auto& iCal : calibrations_)
0122     iCal->startNewLoop();
0123   for (const auto& monitor : monitors_)
0124     monitor->startingNewLoop();
0125 
0126   applyAlignmentsToGeometry();
0127   isDuringLoop_ = true;
0128 }
0129 
0130 //------------------------------------------------------------------------------
0131 void AlignmentProducerBase::terminateProcessing(const edm::EventSetup* setup) {
0132   if (!isDuringLoop_)
0133     return;
0134 
0135   edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::terminateProcessing"
0136                             << "Terminating algorithm.";
0137   if (setup) {
0138     alignmentAlgo_->terminate(*setup);
0139   } else {
0140     alignmentAlgo_->terminate();
0141   }
0142 
0143   // FIXME: Should this be done in algorithm::terminate()??
0144   for (const auto& iCal : calibrations_)
0145     iCal->endOfLoop();
0146   for (const auto& monitor : monitors_)
0147     monitor->endOfLoop();
0148 
0149   isDuringLoop_ = false;
0150 }
0151 
0152 //------------------------------------------------------------------------------
0153 bool AlignmentProducerBase::processEvent(const edm::Event& event, const edm::EventSetup& setup) {
0154   if (setupChanged(setup)) {
0155     edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::processEvent"
0156                               << "EventSetup-Record changed.";
0157 
0158     // updatable alignables are currently not used at PCL, but event setup
0159     // changes require a complete re-initialization
0160     if (runAtPCL_) {
0161       initAlignmentAlgorithm(setup, /* update = */ false);
0162     } else if (enableAlignableUpdates_) {
0163       initAlignmentAlgorithm(setup, /* update = */ true);
0164     }
0165   }
0166 
0167   initBeamSpot(event);  // must happen every event and before incrementing 'nevent_'
0168 
0169   ++nevent_;  // must happen before the check below;
0170               // otherwise subsequent checks fail for "EmptySource"
0171 
0172   if (!alignmentAlgo_->processesEvents()) {
0173     edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::processEvent"
0174                               << "Skipping event. The current configuration of the alignment algorithm "
0175                               << "does not need to process any events.";
0176     return false;
0177   }
0178 
0179   // reading in survey records
0180   readInSurveyRcds(setup);
0181 
0182   // Printout event number
0183   for (int i = 10; i < 10000000; i *= 10) {
0184     if (nevent_ < 10 * i && (nevent_ % i) == 0) {
0185       edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::processEvent"
0186                                 << "Events processed: " << nevent_;
0187     }
0188   }
0189 
0190   // Retrieve trajectories and tracks from the event
0191   // -> merely skip if collection is empty
0192   edm::Handle<TrajTrackAssociationCollection> handleTrajTracksCollection;
0193 
0194   if (getTrajTrackAssociationCollection(event, handleTrajTracksCollection)) {
0195     // Form pairs of trajectories and tracks
0196     ConstTrajTrackPairs trajTracks;
0197     for (auto iter = handleTrajTracksCollection->begin(); iter != handleTrajTracksCollection->end(); ++iter) {
0198       trajTracks.push_back(ConstTrajTrackPair(&(*(*iter).key), &(*(*iter).val)));
0199     }
0200 
0201     // Run the alignment algorithm with its input
0202     const AliClusterValueMap* clusterValueMapPtr{nullptr};
0203     if (!clusterValueMapTag_.encode().empty()) {
0204       edm::Handle<AliClusterValueMap> clusterValueMap;
0205       getAliClusterValueMap(event, clusterValueMap);
0206       clusterValueMapPtr = &(*clusterValueMap);
0207     }
0208 
0209     const AlignmentAlgorithmBase::EventInfo eventInfo{event.id(), trajTracks, *beamSpot_, clusterValueMapPtr};
0210     alignmentAlgo_->run(setup, eventInfo);
0211 
0212     for (const auto& monitor : monitors_) {
0213       monitor->duringLoop(event, setup, trajTracks);  // forward eventInfo?
0214     }
0215   } else {
0216     edm::LogError("Alignment") << "@SUB=AlignmentProducerBase::processEvent"
0217                                << "No track collection found: skipping event";
0218   }
0219 
0220   return true;
0221 }
0222 
0223 //------------------------------------------------------------------------------
0224 void AlignmentProducerBase::beginRunImpl(const edm::Run& run, const edm::EventSetup& setup) {
0225   const bool changed{setupChanged(setup)};
0226   if (changed) {
0227     edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::beginRunImpl"
0228                               << "EventSetup-Record changed.";
0229 
0230     // updatable alignables are currently not used at PCL, but event setup
0231     // changes require a complete re-initialization
0232     if (runAtPCL_) {
0233       initAlignmentAlgorithm(setup, /* update = */ false);
0234     } else if (enableAlignableUpdates_) {
0235       initAlignmentAlgorithm(setup, /* update = */ true);
0236     }
0237   }
0238 
0239   alignmentAlgo_->beginRun(run, setup, changed && (runAtPCL_ || enableAlignableUpdates_));
0240 
0241   for (const auto& iCal : calibrations_)
0242     iCal->beginRun(run, setup);
0243 
0244   //store the first run analyzed to be used for setting the IOV (for PCL)
0245   if (firstRun_ > static_cast<cond::Time_t>(run.id().run())) {
0246     firstRun_ = static_cast<cond::Time_t>(run.id().run());
0247   }
0248 }
0249 
0250 //------------------------------------------------------------------------------
0251 void AlignmentProducerBase::endRunImpl(const edm::Run& run, const edm::EventSetup& setup) {
0252   if (!tkLasBeamTag_.encode().empty()) {
0253     edm::Handle<TkFittedLasBeamCollection> lasBeams;
0254     edm::Handle<TsosVectorCollection> tsoses;
0255     getTkFittedLasBeamCollection(run, lasBeams);
0256     getTsosVectorCollection(run, tsoses);
0257 
0258     alignmentAlgo_->endRun(EndRunInfo(run.id(), &(*lasBeams), &(*tsoses)), setup);
0259   } else {
0260     edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::endRunImpl"
0261                               << "No Tk LAS beams to forward to algorithm.";
0262     alignmentAlgo_->endRun(EndRunInfo(run.id(), nullptr, nullptr), setup);
0263   }
0264 }
0265 
0266 //------------------------------------------------------------------------------
0267 void AlignmentProducerBase::beginLuminosityBlockImpl(const edm::LuminosityBlock&, const edm::EventSetup& setup) {
0268   // Do not forward edm::LuminosityBlock
0269   alignmentAlgo_->beginLuminosityBlock(setup);
0270 }
0271 
0272 //------------------------------------------------------------------------------
0273 void AlignmentProducerBase::endLuminosityBlockImpl(const edm::LuminosityBlock&, const edm::EventSetup& setup) {
0274   // Do not forward edm::LuminosityBlock
0275   alignmentAlgo_->endLuminosityBlock(setup);
0276 }
0277 
0278 //------------------------------------------------------------------------------
0279 void AlignmentProducerBase::createAlignmentAlgorithm(edm::ConsumesCollector& iC) {
0280   auto algoConfig = config_.getParameter<edm::ParameterSet>("algoConfig");
0281   algoConfig.addUntrackedParameter("RunRangeSelection", config_.getParameter<edm::VParameterSet>("RunRangeSelection"));
0282   algoConfig.addUntrackedParameter<align::RunNumber>("firstIOV", runAtPCL_ ? 1 : uniqueRunRanges_.front().first);
0283   algoConfig.addUntrackedParameter("enableAlignableUpdates", enableAlignableUpdates_);
0284 
0285   const auto& algoName = algoConfig.getParameter<std::string>("algoName");
0286   alignmentAlgo_ = AlignmentAlgorithmPluginFactory::get()->create(algoName, algoConfig, iC);
0287 }
0288 
0289 //------------------------------------------------------------------------------
0290 void AlignmentProducerBase::createMonitors(edm::ConsumesCollector& iC) {
0291   const auto& monitorConfig = config_.getParameter<edm::ParameterSet>("monitorConfig");
0292   auto monitors = monitorConfig.getUntrackedParameter<std::vector<std::string> >("monitors");
0293   for (const auto& miter : monitors) {
0294     monitors_.emplace_back(
0295         AlignmentMonitorPluginFactory::get()->create(miter, monitorConfig.getUntrackedParameterSet(miter), iC));
0296   }
0297 }
0298 
0299 //------------------------------------------------------------------------------
0300 void AlignmentProducerBase::createCalibrations(edm::ConsumesCollector& iC) {
0301   const auto& calibrations = config_.getParameter<edm::VParameterSet>("calibrations");
0302   for (const auto& iCalib : calibrations) {
0303     calibrations_.emplace_back(IntegratedCalibrationPluginFactory::get()->create(
0304         iCalib.getParameter<std::string>("calibrationName"), iCalib, iC));
0305   }
0306 }
0307 
0308 //------------------------------------------------------------------------------
0309 bool AlignmentProducerBase::setupChanged(const edm::EventSetup& setup) {
0310   bool changed{false};
0311 
0312   if (watchIdealGeometryRcd_.check(setup)) {
0313     changed = true;
0314   }
0315 
0316   if (watchGlobalPositionRcd_.check(setup)) {
0317     changed = true;
0318   }
0319 
0320   if (doTracker_) {
0321     if (watchTrackerAlRcd_.check(setup)) {
0322       changed = true;
0323     }
0324 
0325     if (watchTrackerAlErrorExtRcd_.check(setup)) {
0326       changed = true;
0327     }
0328 
0329     if (watchTrackerSurDeRcd_.check(setup)) {
0330       changed = true;
0331     }
0332   }
0333 
0334   if (doMuon_) {
0335     if (watchDTAlRcd_.check(setup)) {
0336       changed = true;
0337     }
0338 
0339     if (watchDTAlErrExtRcd_.check(setup)) {
0340       changed = true;
0341     }
0342 
0343     if (watchCSCAlRcd_.check(setup)) {
0344       changed = true;
0345     }
0346 
0347     if (watchCSCAlErrExtRcd_.check(setup)) {
0348       changed = true;
0349     }
0350   }
0351 
0352   /* TODO: ExtraAlignables: Which record(s) to check?
0353    *
0354    if (useExtras_) {}
0355   */
0356 
0357   return changed;
0358 }
0359 
0360 //------------------------------------------------------------------------------
0361 void AlignmentProducerBase::initAlignmentAlgorithm(const edm::EventSetup& setup, bool update) {
0362   edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::initAlignmentAlgorithm"
0363                             << "Begin";
0364 
0365   auto isTrueUpdate = update && isAlgoInitialized_;
0366 
0367   // Retrieve tracker topology from geometry
0368   const TrackerTopology* const tTopo = &setup.getData(ttopoToken_);
0369 
0370   // Create the geometries from the ideal geometries
0371   createGeometries(setup, tTopo);
0372 
0373   applyAlignmentsToDB(setup);
0374   createAlignables(tTopo, isTrueUpdate);
0375   buildParameterStore();
0376   applyMisalignment();
0377 
0378   // Initialize alignment algorithm and integrated calibration and pass the
0379   // latter to algorithm
0380   edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::initAlignmentAlgorithm"
0381                             << "Initializing alignment algorithm.";
0382   alignmentAlgo_->initialize(
0383       setup, alignableTracker_.get(), alignableMuon_.get(), alignableExtras_.get(), alignmentParameterStore_.get());
0384 
0385   // Not all algorithms support calibrations - so do not pass empty vector
0386   // and throw if non-empty and not supported:
0387   if (!calibrations_.empty()) {
0388     if (alignmentAlgo_->supportsCalibrations()) {
0389       alignmentAlgo_->addCalibrations(calibrations_);
0390     } else {
0391       throw cms::Exception("BadConfig") << "@SUB=AlignmentProducerBase::createCalibrations\n"
0392                                         << "Configured " << calibrations_.size() << " calibration(s) "
0393                                         << "for algorithm not supporting it.";
0394     }
0395   }
0396 
0397   isAlgoInitialized_ = true;
0398 
0399   applyAlignmentsToGeometry();
0400 
0401   if (!isTrueUpdate) {  // only needed the first time
0402     for (const auto& iCal : calibrations_) {
0403       iCal->beginOfJob(alignableTracker_.get(), alignableMuon_.get(), alignableExtras_.get());
0404     }
0405     for (const auto& monitor : monitors_) {
0406       monitor->beginOfJob(alignableTracker_.get(), alignableMuon_.get(), alignmentParameterStore_.get());
0407     }
0408   }
0409   startProcessing();  // needed if derived class is non-EDLooper-based
0410                       // has no effect, if called during loop
0411 
0412   edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::initAlignmentAlgorithm"
0413                             << "End";
0414 }
0415 
0416 //------------------------------------------------------------------------------
0417 void AlignmentProducerBase::initBeamSpot(const edm::Event& event) {
0418   getBeamSpot(event, beamSpot_);
0419 
0420   if (nevent_ == 0 && alignableExtras_) {
0421     edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::initBeamSpot"
0422                               << "Initializing AlignableBeamSpot";
0423 
0424     alignableExtras_->initializeBeamSpot(
0425         beamSpot_->x0(), beamSpot_->y0(), beamSpot_->z0(), beamSpot_->dxdz(), beamSpot_->dydz());
0426   }
0427 }
0428 
0429 //------------------------------------------------------------------------------
0430 void AlignmentProducerBase::createGeometries(const edm::EventSetup& iSetup, const TrackerTopology* tTopo) {
0431   if (doTracker_) {
0432     const GeometricDet* geometricDet = &iSetup.getData(geomDetToken_);
0433     const PTrackerParameters* ptp = &iSetup.getData(ptpToken_);
0434     TrackerGeomBuilderFromGeometricDet trackerBuilder;
0435     trackerGeometry_ = std::shared_ptr<TrackerGeometry>(trackerBuilder.build(geometricDet, *ptp, tTopo));
0436   }
0437 
0438   if (doMuon_) {
0439     muonDTGeometry_ = iSetup.getHandle(dtGeomToken_);
0440     muonCSCGeometry_ = iSetup.getHandle(cscGeomToken_);
0441     muonGEMGeometry_ = iSetup.getHandle(gemGeomToken_);
0442   }
0443 }
0444 
0445 //------------------------------------------------------------------------------
0446 void AlignmentProducerBase::applyAlignmentsToDB(const edm::EventSetup& setup) {
0447   // Retrieve and apply alignments, if requested (requires z setup)
0448   if (applyDbAlignment_) {
0449     // we need GlobalPositionRcd - and have to keep track for later removal
0450     // before writing again to DB...
0451 
0452     const Alignments* globalAlignments = &setup.getData(gprToken_);
0453     globalPositions_ = std::make_unique<Alignments>(*globalAlignments);
0454 
0455     if (doTracker_) {
0456       applyDB<TrackerGeometry, TrackerAlignmentRcd, TrackerAlignmentErrorExtendedRcd>(
0457           trackerGeometry_.get(),
0458           setup,
0459           tkAliToken_,
0460           tkAliErrToken_,
0461           align::DetectorGlobalPosition(*globalPositions_, DetId(DetId::Tracker)));
0462 
0463       applyDB<TrackerGeometry, TrackerSurfaceDeformationRcd>(trackerGeometry_.get(), setup, tkSurfDefToken_);
0464     }
0465 
0466     if (doMuon_) {
0467       applyDB<DTGeometry, DTAlignmentRcd, DTAlignmentErrorExtendedRcd>(
0468           &*muonDTGeometry_,
0469           setup,
0470           dtAliToken_,
0471           dtAliErrToken_,
0472           align::DetectorGlobalPosition(*globalPositions_, DetId(DetId::Muon)));
0473 
0474       applyDB<CSCGeometry, CSCAlignmentRcd, CSCAlignmentErrorExtendedRcd>(
0475           &*muonCSCGeometry_,
0476           setup,
0477           cscAliToken_,
0478           cscAliErrToken_,
0479           align::DetectorGlobalPosition(*globalPositions_, DetId(DetId::Muon)));
0480 
0481       applyDB<GEMGeometry, GEMAlignmentRcd, GEMAlignmentErrorExtendedRcd>(
0482           &*muonGEMGeometry_,
0483           setup,
0484           gemAliToken_,
0485           gemAliErrToken_,
0486           align::DetectorGlobalPosition(*globalPositions_, DetId(DetId::Muon)));
0487     }
0488   }
0489 }
0490 
0491 //------------------------------------------------------------------------------
0492 void AlignmentProducerBase::createAlignables(const TrackerTopology* tTopo, bool update) {
0493   if (doTracker_) {
0494     if (update) {
0495       alignableTracker_->update(trackerGeometry_.get(), tTopo);
0496     } else {
0497       alignableTracker_ = std::make_unique<AlignableTracker>(trackerGeometry_.get(), tTopo);
0498     }
0499   }
0500 
0501   if (doMuon_) {
0502     if (update) {
0503       alignableMuon_->update(&*muonDTGeometry_, &*muonCSCGeometry_, &*muonGEMGeometry_);
0504     } else {
0505       alignableMuon_ = std::make_unique<AlignableMuon>(&*muonDTGeometry_, &*muonCSCGeometry_, &*muonGEMGeometry_);
0506     }
0507   }
0508 
0509   if (useExtras_) {
0510     if (update) {
0511       // FIXME: Requires further code changes to track beam spot condition changes
0512     } else {
0513       alignableExtras_ = std::make_unique<AlignableExtras>();
0514     }
0515   }
0516 }
0517 
0518 //------------------------------------------------------------------------------
0519 void AlignmentProducerBase::buildParameterStore() {
0520   // Create alignment parameter builder
0521   edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::buildParameterStore"
0522                             << "Creating AlignmentParameterBuilder";
0523 
0524   const auto& alParamBuildCfg = config_.getParameter<edm::ParameterSet>("ParameterBuilder");
0525   const auto& alParamStoreCfg = config_.getParameter<edm::ParameterSet>("ParameterStore");
0526 
0527   AlignmentParameterBuilder alignmentParameterBuilder{
0528       alignableTracker_.get(), alignableMuon_.get(), alignableExtras_.get(), alParamBuildCfg};
0529 
0530   // Fix alignables if requested
0531   if (stNFixAlignables_ > 0) {
0532     alignmentParameterBuilder.fixAlignables(stNFixAlignables_);
0533   }
0534 
0535   // Get list of alignables
0536   const auto& alignables = alignmentParameterBuilder.alignables();
0537   edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::buildParameterStore"
0538                             << "got " << alignables.size() << " alignables";
0539 
0540   // Create AlignmentParameterStore
0541   alignmentParameterStore_ = std::make_unique<AlignmentParameterStore>(alignables, alParamStoreCfg);
0542   edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::buildParameterStore"
0543                             << "AlignmentParameterStore created!";
0544 }
0545 
0546 //------------------------------------------------------------------------------
0547 void AlignmentProducerBase::applyMisalignment() {
0548   // Apply misalignment scenario to alignable tracker and muon if requested
0549   // WARNING: this assumes scenarioConfig can be passed to both muon and tracker
0550 
0551   if (doMisalignmentScenario_ && (doTracker_ || doMuon_)) {
0552     edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::applyMisalignment"
0553                               << "Applying misalignment scenario to " << (doTracker_ ? "tracker" : "")
0554                               << (doMuon_ ? (doTracker_ ? " and muon" : "muon") : ".");
0555 
0556     const auto& scenarioConfig = config_.getParameterSet("MisalignmentScenario");
0557 
0558     if (doTracker_) {
0559       TrackerScenarioBuilder scenarioBuilder(alignableTracker_.get());
0560       scenarioBuilder.applyScenario(scenarioConfig);
0561     }
0562     if (doMuon_) {
0563       MuonScenarioBuilder muonScenarioBuilder(alignableMuon_.get());
0564       muonScenarioBuilder.applyScenario(scenarioConfig);
0565     }
0566 
0567   } else {
0568     edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::applyMisalignment"
0569                               << "NOT applying misalignment scenario!";
0570   }
0571 
0572   // Apply simple misalignment
0573   const auto& sParSel = config_.getParameter<std::string>("parameterSelectorSimple");
0574   simpleMisalignment(alignmentParameterStore_->alignables(), sParSel, stRandomShift_, stRandomRotation_, true);
0575 }
0576 
0577 // ----------------------------------------------------------------------------
0578 void AlignmentProducerBase::simpleMisalignment(
0579     const align::Alignables& alivec, const std::string& selection, float shift, float rot, bool local) {
0580   std::ostringstream output;  // collecting output
0581 
0582   if (shift > 0. || rot > 0.) {
0583     output << "Adding random flat shift of max size " << shift << " and adding random flat rotation of max size " << rot
0584            << " to ";
0585 
0586     std::vector<bool> commSel(0);
0587     if (selection != "-1") {
0588       AlignmentParameterSelector aSelector(nullptr, nullptr);  // no alignable needed here...
0589       const std::vector<char> cSel(aSelector.convertParamSel(selection));
0590       if (cSel.size() < RigidBodyAlignmentParameters::N_PARAM) {
0591         throw cms::Exception("BadConfig")
0592             << "[AlignmentProducerBase::simpleMisalignment_]\n"
0593             << "Expect selection string '" << selection << "' to be at least of length "
0594             << RigidBodyAlignmentParameters::N_PARAM << " or to be '-1'.\n"
0595             << "(Most probably you have to adjust the parameter 'parameterSelectorSimple'.)";
0596       }
0597       for (const auto& cIter : cSel) {
0598         commSel.push_back(cIter == '0' ? false : true);
0599       }
0600       output << "parameters defined by (" << selection << "), representing (x,y,z,alpha,beta,gamma),";
0601     } else {
0602       output << "the active parameters of each alignable,";
0603     }
0604     output << " in " << (local ? "local" : "global") << " frame.";
0605 
0606     for (const auto& ali : alivec) {
0607       std::vector<bool> mysel(commSel.empty() ? ali->alignmentParameters()->selector() : commSel);
0608 
0609       if (std::abs(shift) > 0.00001) {
0610         double s0 = 0., s1 = 0., s2 = 0.;
0611         if (mysel[RigidBodyAlignmentParameters::dx])
0612           s0 = shift * double(random() % 1000 - 500) / 500.;
0613         if (mysel[RigidBodyAlignmentParameters::dy])
0614           s1 = shift * double(random() % 1000 - 500) / 500.;
0615         if (mysel[RigidBodyAlignmentParameters::dz])
0616           s2 = shift * double(random() % 1000 - 500) / 500.;
0617 
0618         if (local)
0619           ali->move(ali->surface().toGlobal(align::LocalVector(s0, s1, s2)));
0620         else
0621           ali->move(align::GlobalVector(s0, s1, s2));
0622 
0623         //AlignmentPositionError ape(dx,dy,dz);
0624         //ali->addAlignmentPositionError(ape);
0625       }
0626 
0627       if (std::abs(rot) > 0.00001) {
0628         align::EulerAngles r(3);
0629         if (mysel[RigidBodyAlignmentParameters::dalpha])
0630           r(1) = rot * double(random() % 1000 - 500) / 500.;
0631         if (mysel[RigidBodyAlignmentParameters::dbeta])
0632           r(2) = rot * double(random() % 1000 - 500) / 500.;
0633         if (mysel[RigidBodyAlignmentParameters::dgamma])
0634           r(3) = rot * double(random() % 1000 - 500) / 500.;
0635 
0636         const align::RotationType mrot = align::toMatrix(r);
0637         if (local)
0638           ali->rotateInLocalFrame(mrot);
0639         else
0640           ali->rotateInGlobalFrame(mrot);
0641 
0642         //ali->addAlignmentPositionErrorFromRotation(mrot);
0643       }
0644     }  // end loop on alignables
0645   } else {
0646     output << "No simple misalignment added!";
0647   }
0648   edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::simpleMisalignment" << output.str();
0649 }
0650 
0651 //------------------------------------------------------------------------------
0652 void AlignmentProducerBase::applyAlignmentsToGeometry() {
0653   edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::applyAlignmentsToGeometry"
0654                             << "Now physically apply alignments to  geometry...";
0655 
0656   // Propagate changes to reconstruction geometry (from initialisation or iteration)
0657   GeometryAligner aligner;
0658 
0659   if (doTracker_) {
0660     if (!alignableTracker_) {
0661       throw cms::Exception("LogicError") << "@SUB=AlignmentProducerBase::applyAlignmentsToGeometry\n"
0662                                          << "Trying to apply tracker alignment before creating it.";
0663     }
0664 
0665     std::unique_ptr<Alignments> alignments{alignableTracker_->alignments()};
0666     std::unique_ptr<AlignmentErrorsExtended> alignmentErrExt{alignableTracker_->alignmentErrors()};
0667     std::unique_ptr<AlignmentSurfaceDeformations> aliDeforms{alignableTracker_->surfaceDeformations()};
0668 
0669     aligner.applyAlignments(trackerGeometry_.get(), alignments.get(), alignmentErrExt.get(), AlignTransform());
0670     aligner.attachSurfaceDeformations(trackerGeometry_.get(), aliDeforms.get());
0671   }
0672 
0673   if (doMuon_) {
0674     if (!alignableMuon_) {
0675       throw cms::Exception("LogicError") << "@SUB=AlignmentProducerBase::applyAlignmentsToGeometry\n"
0676                                          << "Trying to apply muon alignment before creating it.";
0677     }
0678 
0679     std::unique_ptr<Alignments> dtAlignments{alignableMuon_->dtAlignments()};
0680     std::unique_ptr<Alignments> cscAlignments{alignableMuon_->cscAlignments()};
0681     std::unique_ptr<Alignments> gemAlignments{alignableMuon_->gemAlignments()};
0682 
0683     std::unique_ptr<AlignmentErrorsExtended> dtAlignmentErrExt{alignableMuon_->dtAlignmentErrorsExtended()};
0684     std::unique_ptr<AlignmentErrorsExtended> cscAlignmentErrExt{alignableMuon_->cscAlignmentErrorsExtended()};
0685     std::unique_ptr<AlignmentErrorsExtended> gemAlignmentErrExt{alignableMuon_->gemAlignmentErrorsExtended()};
0686 
0687     aligner.applyAlignments(&*muonDTGeometry_, dtAlignments.get(), dtAlignmentErrExt.get(), AlignTransform());
0688     aligner.applyAlignments(&*muonCSCGeometry_, cscAlignments.get(), cscAlignmentErrExt.get(), AlignTransform());
0689     aligner.applyAlignments(&*muonGEMGeometry_, gemAlignments.get(), gemAlignmentErrExt.get(), AlignTransform());
0690   }
0691 }
0692 
0693 //------------------------------------------------------------------------------
0694 void AlignmentProducerBase::readInSurveyRcds(const edm::EventSetup& iSetup) {
0695   // Get Survey Rcds and add Survey Info
0696   if (doTracker_ && useSurvey_) {
0697     bool tkSurveyBool = watchTkSurveyRcd_.check(iSetup);
0698     bool tkSurveyErrBool = watchTkSurveyErrExtRcd_.check(iSetup);
0699     edm::LogInfo("Alignment") << "watcher tksurveyrcd: " << tkSurveyBool;
0700     edm::LogInfo("Alignment") << "watcher tksurveyerrrcd: " << tkSurveyErrBool;
0701     if (tkSurveyBool || tkSurveyErrBool) {
0702       edm::LogInfo("Alignment") << "ADDING THE SURVEY INFORMATION";
0703       const Alignments* surveys = &iSetup.getData(tkSurveyToken_);
0704       const SurveyErrors* surveyErrors = &iSetup.getData(tkSurvErrorToken_);
0705 
0706       surveyIndex_ = 0;
0707       surveyValues_ = &*surveys;
0708       surveyErrors_ = &*surveyErrors;
0709       addSurveyInfo(alignableTracker_.get());
0710     }
0711   }
0712 
0713   if (doMuon_ && useSurvey_) {
0714     bool DTSurveyBool = watchTkSurveyRcd_.check(iSetup);
0715     bool DTSurveyErrBool = watchTkSurveyErrExtRcd_.check(iSetup);
0716     bool CSCSurveyBool = watchTkSurveyRcd_.check(iSetup);
0717     bool CSCSurveyErrBool = watchTkSurveyErrExtRcd_.check(iSetup);
0718 
0719     if (DTSurveyBool || DTSurveyErrBool || CSCSurveyBool || CSCSurveyErrBool) {
0720       const Alignments* dtSurveys = &iSetup.getData(dtSurveyToken_);
0721       const SurveyErrors* dtSurveyErrors = &iSetup.getData(dtSurvErrorToken_);
0722       const Alignments* cscSurveys = &iSetup.getData(cscSurveyToken_);
0723       const SurveyErrors* cscSurveyErrors = &iSetup.getData(cscSurvErrorToken_);
0724 
0725       surveyIndex_ = 0;
0726       surveyValues_ = &*dtSurveys;
0727       surveyErrors_ = &*dtSurveyErrors;
0728       const auto& barrels = alignableMuon_->DTBarrel();
0729       for (const auto& barrel : barrels)
0730         addSurveyInfo(barrel);
0731 
0732       surveyIndex_ = 0;
0733       surveyValues_ = &*cscSurveys;
0734       surveyErrors_ = &*cscSurveyErrors;
0735       const auto& endcaps = alignableMuon_->CSCEndcaps();
0736       for (const auto& endcap : endcaps)
0737         addSurveyInfo(endcap);
0738     }
0739   }
0740 }
0741 
0742 //------------------------------------------------------------------------------
0743 void AlignmentProducerBase::addSurveyInfo(Alignable* ali) {
0744   const auto& comps = ali->components();
0745 
0746   for (const auto& comp : comps)
0747     addSurveyInfo(comp);
0748 
0749   const SurveyError& error = surveyErrors_->m_surveyErrors[surveyIndex_];
0750 
0751   if (ali->id() != error.rawId() || ali->alignableObjectId() != error.structureType()) {
0752     throw cms::Exception("DatabaseError") << "Error reading survey info from DB. Mismatched id!";
0753   }
0754 
0755   const auto& pos = surveyValues_->m_align[surveyIndex_].translation();
0756   const auto& rot = surveyValues_->m_align[surveyIndex_].rotation();
0757 
0758   AlignableSurface surf(
0759       align::PositionType(pos.x(), pos.y(), pos.z()),
0760       align::RotationType(rot.xx(), rot.xy(), rot.xz(), rot.yx(), rot.yy(), rot.yz(), rot.zx(), rot.zy(), rot.zz()));
0761 
0762   surf.setWidth(ali->surface().width());
0763   surf.setLength(ali->surface().length());
0764 
0765   ali->setSurvey(new SurveyDet(surf, error.matrix()));
0766 
0767   ++surveyIndex_;
0768 }
0769 
0770 //------------------------------------------------------------------------------
0771 bool AlignmentProducerBase::finish() {
0772   for (const auto& monitor : monitors_)
0773     monitor->endOfJob();
0774 
0775   if (alignmentAlgo_->processesEvents() && nevent_ == 0) {
0776     return false;
0777   }
0778 
0779   if (saveToDB_ || saveApeToDB_ || saveDeformationsToDB_) {
0780     if (alignmentAlgo_->storeAlignments())
0781       storeAlignmentsToDB();
0782   } else {
0783     edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::finish"
0784                               << "No payload to be stored!";
0785   }
0786 
0787   // takes care of storing output of calibrations, but needs to be called only
0788   // after 'storeAlignmentsToDB()'
0789   for (const auto& iCal : calibrations_)
0790     iCal->endOfJob();
0791 
0792   return true;
0793 }
0794 
0795 //------------------------------------------------------------------------------
0796 void AlignmentProducerBase::storeAlignmentsToDB() {
0797   const auto runRangeSelectionVPSet = config_.getParameterSetVector("RunRangeSelection");
0798 
0799   // handle PCL use case
0800   const auto& uniqueRunRanges =
0801       (runAtPCL_ ? align::makeUniqueRunRanges(runRangeSelectionVPSet, firstRun_) : uniqueRunRanges_);
0802 
0803   std::vector<AlgebraicVector> beamSpotParameters;
0804 
0805   for (const auto& iRunRange : uniqueRunRanges) {
0806     alignmentAlgo_->setParametersForRunRange(iRunRange);
0807 
0808     // Save alignments to database
0809     if (saveToDB_ || saveApeToDB_ || saveDeformationsToDB_) {
0810       writeForRunRange(iRunRange.first);
0811     }
0812 
0813     // Deal with extra alignables, e.g. beam spot
0814     if (alignableExtras_) {
0815       auto& alis = alignableExtras_->beamSpot();
0816       if (!alis.empty()) {
0817         auto beamSpotAliPars = dynamic_cast<BeamSpotAlignmentParameters*>(alis[0]->alignmentParameters());
0818         if (!beamSpotAliPars) {
0819           throw cms::Exception("LogicError") << "@SUB=AlignmentProducerBase::storeAlignmentsToDB\n"
0820                                              << "First alignable of alignableExtras_ does not have "
0821                                              << "'BeamSpotAlignmentParameters', while it should have.";
0822         }
0823 
0824         beamSpotParameters.push_back(beamSpotAliPars->parameters());
0825       }
0826     }
0827   }
0828 
0829   if (alignableExtras_) {
0830     std::ostringstream bsOutput;
0831 
0832     auto itPar = beamSpotParameters.cbegin();
0833     for (auto iRunRange = uniqueRunRanges.cbegin(); iRunRange != uniqueRunRanges.cend(); ++iRunRange, ++itPar) {
0834       bsOutput << "Run range: " << (*iRunRange).first << " - " << (*iRunRange).second << "\n";
0835       bsOutput << "  Displacement: x=" << (*itPar)[0] << ", y=" << (*itPar)[1] << "\n";
0836       bsOutput << "  Slope: dx/dz=" << (*itPar)[2] << ", dy/dz=" << (*itPar)[3] << "\n";
0837     }
0838 
0839     edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::storeAlignmentsToDB"
0840                               << "Parameters for alignable beamspot:\n"
0841                               << bsOutput.str();
0842   }
0843 }
0844 
0845 //------------------------------------------------------------------------------
0846 void AlignmentProducerBase::writeForRunRange(cond::Time_t time) {
0847   if (doTracker_ and alignableTracker_) {          // first tracker
0848     const AlignTransform* trackerGlobal{nullptr};  // will be 'removed' from constants
0849     if (globalPositions_) {                        // i.e. applied before in applyDB
0850       trackerGlobal = &align::DetectorGlobalPosition(*globalPositions_, DetId(DetId::Tracker));
0851     }
0852 
0853     auto alignments = alignableTracker_->alignments();
0854     auto alignmentErrors = alignableTracker_->alignmentErrors();
0855     this->writeDB(alignments, tkAliRcdName_, alignmentErrors, "TrackerAlignmentErrorExtendedRcd", trackerGlobal, time);
0856 
0857     // Save surface deformations to database
0858     if (saveDeformationsToDB_) {
0859       const auto alignmentSurfaceDeformations = *(alignableTracker_->surfaceDeformations());
0860       this->writeDB(alignmentSurfaceDeformations, "TrackerSurfaceDeformationRcd", time);
0861     }
0862   }
0863 
0864   if (doMuon_ and alignableMuon_) {             // now muon
0865     const AlignTransform* muonGlobal{nullptr};  // will be 'removed' from constants
0866     if (globalPositions_) {                     // i.e. applied before in applyDB
0867       muonGlobal = &align::DetectorGlobalPosition(*globalPositions_, DetId(DetId::Muon));
0868     }
0869     // Get alignments+errors, first DT - ownership taken over by writeDB(..), so no delete
0870     auto alignments = alignableMuon_->dtAlignments();
0871     auto alignmentErrors = alignableMuon_->dtAlignmentErrorsExtended();
0872     this->writeDB(alignments, "DTAlignmentRcd", alignmentErrors, "DTAlignmentErrorExtendedRcd", muonGlobal, time);
0873 
0874     // Get alignments+errors, now CSC - ownership taken over by writeDB(..), so no delete
0875     alignments = alignableMuon_->cscAlignments();
0876     alignmentErrors = alignableMuon_->cscAlignmentErrorsExtended();
0877     this->writeDB(alignments, "CSCAlignmentRcd", alignmentErrors, "CSCAlignmentErrorExtendedRcd", muonGlobal, time);
0878   }
0879 }
0880 
0881 //------------------------------------------------------------------------------
0882 void AlignmentProducerBase::writeDB(Alignments* alignments,
0883                                     const std::string& alignRcd,
0884                                     AlignmentErrorsExtended* alignmentErrors,
0885                                     const std::string& errRcd,
0886                                     const AlignTransform* globalCoordinates,
0887                                     cond::Time_t time) const {
0888   Alignments* tempAlignments = alignments;
0889   AlignmentErrorsExtended* tempAlignmentErrorsExtended = alignmentErrors;
0890 
0891   // Call service
0892   edm::Service<cond::service::PoolDBOutputService> poolDb;
0893   if (!poolDb.isAvailable()) {           // Die if not available
0894     delete tempAlignments;               // promised to take over ownership...
0895     delete tempAlignmentErrorsExtended;  // ditto
0896     throw cms::Exception("NotAvailable") << "PoolDBOutputService not available";
0897   }
0898 
0899   if (globalCoordinates  // happens only if (applyDbAlignment_ == true)
0900       && globalCoordinates->transform() != AlignTransform::Transform::Identity) {
0901     tempAlignments = new Alignments();                            // temporary storage for
0902     tempAlignmentErrorsExtended = new AlignmentErrorsExtended();  // final alignments and errors
0903 
0904     GeometryAligner aligner;
0905     aligner.removeGlobalTransform(
0906         alignments, alignmentErrors, *globalCoordinates, tempAlignments, tempAlignmentErrorsExtended);
0907 
0908     delete alignments;       // have to delete original alignments
0909     delete alignmentErrors;  // same thing for the errors
0910 
0911     edm::LogInfo("Alignment") << "@SUB=AlignmentProducerBase::writeDB"
0912                               << "globalCoordinates removed from alignments (" << alignRcd << ") and errors ("
0913                               << alignRcd << ").";
0914   }
0915 
0916   if (saveToDB_) {
0917     edm::LogInfo("Alignment") << "Writing Alignments for run " << time << " to " << alignRcd << ".";
0918     poolDb->writeOneIOV<Alignments>(*tempAlignments, time, alignRcd);
0919   } else {
0920     delete tempAlignments;  // ...otherwise we have to delete, as promised!
0921   }
0922 
0923   if (saveApeToDB_) {
0924     edm::LogInfo("Alignment") << "Writing AlignmentErrorsExtended for run " << time << " to " << errRcd << ".";
0925     poolDb->writeOneIOV<AlignmentErrorsExtended>(*tempAlignmentErrorsExtended, time, errRcd);
0926   } else {
0927     delete tempAlignmentErrorsExtended;  // ...otherwise we have to delete, as promised!
0928   }
0929 }
0930 
0931 //------------------------------------------------------------------------------
0932 void AlignmentProducerBase::writeDB(const AlignmentSurfaceDeformations& alignmentSurfaceDeformations,
0933                                     const std::string& surfaceDeformationRcd,
0934                                     cond::Time_t time) const {
0935   // Call service
0936   edm::Service<cond::service::PoolDBOutputService> poolDb;
0937   if (!poolDb.isAvailable()) {  // Die if not available
0938     throw cms::Exception("NotAvailable") << "PoolDBOutputService not available";
0939   }
0940 
0941   if (saveDeformationsToDB_) {
0942     edm::LogInfo("Alignment") << "Writing AlignmentSurfaceDeformations for run " << time << " to "
0943                               << surfaceDeformationRcd << ".";
0944     poolDb->writeOneIOV<AlignmentSurfaceDeformations>(alignmentSurfaceDeformations, time, surfaceDeformationRcd);
0945   }
0946 }