Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-22 04:02:30

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