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