Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-07-30 05:20:07

0001 #include "CondFormats/BeamSpotObjects/interface/BeamSpotOnlineObjects.h"
0002 #include "CondFormats/DataRecord/interface/BeamSpotObjectsRcd.h"
0003 #include "CondFormats/DataRecord/interface/BeamSpotOnlineHLTObjectsRcd.h"
0004 #include "CondFormats/DataRecord/interface/BeamSpotOnlineLegacyObjectsRcd.h"
0005 #include "CondFormats/DataRecord/interface/BeamSpotTransientObjectsRcd.h"
0006 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
0007 #include "FWCore/Framework/interface/ESHandle.h"
0008 #include "FWCore/Framework/interface/ESProducer.h"
0009 #include "FWCore/Framework/interface/ESProducer.h"
0010 #include "FWCore/Framework/interface/ESProductHost.h"
0011 #include "FWCore/Framework/interface/EventSetup.h"
0012 #include "FWCore/Framework/interface/ModuleFactory.h"
0013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0014 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0015 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0016 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0017 #include "FWCore/Utilities/interface/ReusableObjectHolder.h"
0018 #include "FWCore/Utilities/interface/do_nothing_deleter.h"
0019 #include <memory>
0020 #include <string>
0021 
0022 using namespace edm;
0023 
0024 class OnlineBeamSpotESProducer : public edm::ESProducer {
0025 public:
0026   OnlineBeamSpotESProducer(const edm::ParameterSet& p);
0027   std::shared_ptr<const BeamSpotObjects> produce(const BeamSpotTransientObjectsRcd&);
0028   static void fillDescriptions(edm::ConfigurationDescriptions& desc);
0029 
0030 private:
0031   const BeamSpotOnlineObjects* compareBS(const BeamSpotOnlineObjects* bs1, const BeamSpotOnlineObjects* bs2);
0032   const BeamSpotOnlineObjects* checkSingleBS(const BeamSpotOnlineObjects* bs1);
0033   bool isGoodBS(const BeamSpotOnlineObjects* bs1) const;
0034 
0035   edm::ESGetToken<BeamSpotObjects, BeamSpotTransientObjectsRcd> const bsToken_;
0036   edm::ESGetToken<BeamSpotOnlineObjects, BeamSpotOnlineHLTObjectsRcd> bsHLTToken_;
0037   edm::ESGetToken<BeamSpotOnlineObjects, BeamSpotOnlineLegacyObjectsRcd> bsLegacyToken_;
0038 
0039   BeamSpotObjects fakeBS_;
0040   const int timeThreshold_;
0041   const double sigmaZThreshold_;
0042   const double sigmaXYThreshold_;
0043 };
0044 
0045 OnlineBeamSpotESProducer::OnlineBeamSpotESProducer(const edm::ParameterSet& p)
0046     // get parameters
0047     : timeThreshold_(p.getParameter<int>("timeThreshold")),
0048       sigmaZThreshold_(p.getParameter<double>("sigmaZThreshold")),
0049       sigmaXYThreshold_(p.getParameter<double>("sigmaXYThreshold") * 1E-4) {
0050   auto cc = setWhatProduced(this);
0051 
0052   fakeBS_.setBeamWidthX(0.1);
0053   fakeBS_.setBeamWidthY(0.1);
0054   fakeBS_.setSigmaZ(15.);
0055   fakeBS_.setPosition(0.0001, 0.0001, 0.0001);
0056   fakeBS_.setType(-1);
0057   // Set diagonal covariance, i.e. errors on the parameters
0058   fakeBS_.setCovariance(0, 0, 5e-10);
0059   fakeBS_.setCovariance(1, 1, 5e-10);
0060   fakeBS_.setCovariance(2, 2, 0.002);
0061   fakeBS_.setCovariance(3, 3, 0.002);
0062   fakeBS_.setCovariance(4, 4, 5e-11);
0063   fakeBS_.setCovariance(5, 5, 5e-11);
0064   fakeBS_.setCovariance(6, 6, 1e-09);
0065 
0066   bsHLTToken_ = cc.consumesFrom<BeamSpotOnlineObjects, BeamSpotOnlineHLTObjectsRcd>();
0067   bsLegacyToken_ = cc.consumesFrom<BeamSpotOnlineObjects, BeamSpotOnlineLegacyObjectsRcd>();
0068 }
0069 
0070 void OnlineBeamSpotESProducer::fillDescriptions(edm::ConfigurationDescriptions& desc) {
0071   edm::ParameterSetDescription dsc;
0072   dsc.add<int>("timeThreshold", 48)->setComment("hours");
0073   dsc.add<double>("sigmaZThreshold", 2.)->setComment("cm");
0074   dsc.add<double>("sigmaXYThreshold", 4.)->setComment("um");
0075   desc.addWithDefaultLabel(dsc);
0076 }
0077 
0078 const BeamSpotOnlineObjects* OnlineBeamSpotESProducer::compareBS(const BeamSpotOnlineObjects* bs1,
0079                                                                  const BeamSpotOnlineObjects* bs2) {
0080   // Current time to be compared with the one read from the payload
0081   auto currentTime =
0082       std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch());
0083 
0084   // Get two beamspot creation times and compute the time difference wrt currentTime
0085   auto bs1time = std::chrono::microseconds(bs1->creationTime());
0086   auto diffBStime1 = (currentTime - bs1time).count();
0087   auto bs2time = std::chrono::microseconds(bs2->creationTime());
0088   auto diffBStime2 = (currentTime - bs2time).count();
0089 
0090   // Convert timeThreshold_ from hours to microseconds for comparison
0091   auto limitTime = std::chrono::microseconds((std::chrono::hours)timeThreshold_).count();
0092 
0093   // Logic to choose between the two BeamSpots:
0094   // 1. If both BS are older than limitTime retun fake BS
0095   // 2. If only one BS is newer than limitTime return it only if
0096   //     it passes isGoodBS (checks on sigmaZ, sigmaXY and fit convergence)
0097   // 3. If both are newer than the limit threshold return the BS that
0098   //     passes isGoodBS and has larger sigmaZ
0099   if (diffBStime1 > limitTime && diffBStime2 > limitTime) {
0100     edm::LogWarning("OnlineBeamSpotESProducer")
0101         << "Defaulting to fake (fallback to PCL) because both payloads are too old.";
0102     return nullptr;
0103   } else if (diffBStime2 > limitTime) {
0104     if (isGoodBS(bs1)) {
0105       return bs1;
0106     } else {
0107       edm::LogWarning("OnlineBeamSpotESProducer") << "Defaulting to fake (fallback to PCL) because the legacy Beam "
0108                                                      "Spot is not suitable and HLT one is too old.";
0109       return nullptr;
0110     }
0111   } else if (diffBStime1 > limitTime) {
0112     if (isGoodBS(bs2)) {
0113       return bs2;
0114     } else {
0115       edm::LogWarning("OnlineBeamSpotESProducer") << "Defaulting to fake (fallback to PCL) because the HLT Beam Spot "
0116                                                      "is not suitable and the legacy one too old.";
0117       return nullptr;
0118     }
0119   } else {
0120     if (bs1->sigmaZ() > bs2->sigmaZ() && isGoodBS(bs1)) {
0121       return bs1;
0122     } else if (bs2->sigmaZ() >= bs1->sigmaZ() && isGoodBS(bs2)) {
0123       return bs2;
0124     } else {
0125       edm::LogWarning("OnlineBeamSpotESProducer") << "Defaulting to fake (fallback to PCL) because despite both "
0126                                                      "payloads are young enough, none has passed the fit sanity checks";
0127       return nullptr;
0128     }
0129   }
0130 }
0131 
0132 const BeamSpotOnlineObjects* OnlineBeamSpotESProducer::checkSingleBS(const BeamSpotOnlineObjects* bs1) {
0133   // Current time to be compared with the one read from the payload
0134   auto currentTime =
0135       std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch());
0136 
0137   // Get the beamspot creation time and compute the time difference wrt currentTime
0138   auto bs1time = std::chrono::microseconds(bs1->creationTime());
0139   auto diffBStime1 = (currentTime - bs1time).count();
0140 
0141   // Convert timeThreshold_ from hours to microseconds for comparison
0142   auto limitTime = std::chrono::microseconds((std::chrono::hours)timeThreshold_).count();
0143 
0144   // Check that the BS is within the timeThreshold, converges and passes the sigmaZthreshold
0145   if (diffBStime1 < limitTime && isGoodBS(bs1)) {
0146     return bs1;
0147   } else {
0148     edm::LogWarning("OnlineBeamSpotESProducer") << "Defaulting to fake (fallback to PCL) because the only payload "
0149                                                    "is either too old or does not pass the fit sanity checks";
0150     return nullptr;
0151   }
0152 }
0153 
0154 // This method is used to check the quality of the beamspot fit
0155 bool OnlineBeamSpotESProducer::isGoodBS(const BeamSpotOnlineObjects* bs1) const {
0156   if (bs1->sigmaZ() > sigmaZThreshold_ && bs1->beamType() == reco::BeamSpot::Tracker &&
0157       bs1->beamWidthX() > sigmaXYThreshold_ && bs1->beamWidthY() > sigmaXYThreshold_)
0158     return true;
0159   else
0160     return false;
0161 }
0162 
0163 std::shared_ptr<const BeamSpotObjects> OnlineBeamSpotESProducer::produce(const BeamSpotTransientObjectsRcd& iRecord) {
0164   auto legacyRec = iRecord.tryToGetRecord<BeamSpotOnlineLegacyObjectsRcd>();
0165   auto hltRec = iRecord.tryToGetRecord<BeamSpotOnlineHLTObjectsRcd>();
0166   if (not legacyRec and not hltRec) {
0167     edm::LogWarning("OnlineBeamSpotESProducer")
0168         << "None of the Beam Spots in ES are available! \n returning a fake one (fallback to PCL).";
0169     return std::shared_ptr<const BeamSpotObjects>(&fakeBS_, edm::do_nothing_deleter());
0170   }
0171 
0172   const BeamSpotOnlineObjects* best;
0173   if (legacyRec and hltRec) {
0174     best = compareBS(&legacyRec->get(bsLegacyToken_), &hltRec->get(bsHLTToken_));
0175   } else if (legacyRec) {
0176     best = checkSingleBS(&legacyRec->get(bsLegacyToken_));
0177   } else {
0178     best = checkSingleBS(&hltRec->get(bsHLTToken_));
0179   }
0180   if (best) {
0181     return std::shared_ptr<const BeamSpotObjects>(best, edm::do_nothing_deleter());
0182   }
0183   edm::LogWarning("OnlineBeamSpotESProducer")
0184       << "None of the Online BeamSpots in the ES is suitable, \n returning a fake one (fallback to PCL).";
0185   return std::shared_ptr<const BeamSpotObjects>(&fakeBS_, edm::do_nothing_deleter());
0186 }
0187 
0188 DEFINE_FWK_EVENTSETUP_MODULE(OnlineBeamSpotESProducer);