Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-12-14 11:45:28

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 
0034   edm::ESGetToken<BeamSpotObjects, BeamSpotTransientObjectsRcd> const bsToken_;
0035   edm::ESGetToken<BeamSpotOnlineObjects, BeamSpotOnlineHLTObjectsRcd> bsHLTToken_;
0036   edm::ESGetToken<BeamSpotOnlineObjects, BeamSpotOnlineLegacyObjectsRcd> bsLegacyToken_;
0037 
0038   BeamSpotObjects fakeBS_;
0039   const int timeThreshold_;
0040   const double sigmaZThreshold_;
0041 };
0042 
0043 OnlineBeamSpotESProducer::OnlineBeamSpotESProducer(const edm::ParameterSet& p)
0044     // get parameters
0045     : timeThreshold_(p.getParameter<int>("timeThreshold")),
0046       sigmaZThreshold_(p.getParameter<double>("sigmaZThreshold")) {
0047   auto cc = setWhatProduced(this);
0048 
0049   fakeBS_.setBeamWidthX(0.1);
0050   fakeBS_.setBeamWidthY(0.1);
0051   fakeBS_.setSigmaZ(15.);
0052   fakeBS_.setPosition(0.0001, 0.0001, 0.0001);
0053   fakeBS_.setType(-1);
0054 
0055   bsHLTToken_ = cc.consumesFrom<BeamSpotOnlineObjects, BeamSpotOnlineHLTObjectsRcd>();
0056   bsLegacyToken_ = cc.consumesFrom<BeamSpotOnlineObjects, BeamSpotOnlineLegacyObjectsRcd>();
0057 }
0058 
0059 void OnlineBeamSpotESProducer::fillDescriptions(edm::ConfigurationDescriptions& desc) {
0060   edm::ParameterSetDescription dsc;
0061   dsc.add<int>("timeThreshold", 48)->setComment("hours");
0062   dsc.add<double>("sigmaZThreshold", 2.)->setComment("cm");
0063   desc.addWithDefaultLabel(dsc);
0064 }
0065 
0066 const BeamSpotOnlineObjects* OnlineBeamSpotESProducer::compareBS(const BeamSpotOnlineObjects* bs1,
0067                                                                  const BeamSpotOnlineObjects* bs2) {
0068   // Current time to be compared with the one read from the payload
0069   auto currentTime =
0070       std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch());
0071 
0072   // Get two beamspot creation times and compute the time difference wrt currentTime
0073   auto bs1time = std::chrono::microseconds(bs1->creationTime());
0074   auto diffBStime1 = (currentTime - bs1time).count();
0075   auto bs2time = std::chrono::microseconds(bs2->creationTime());
0076   auto diffBStime2 = (currentTime - bs2time).count();
0077 
0078   // Convert timeThreshold_ from hours to microseconds for comparison
0079   auto limitTime = std::chrono::microseconds((std::chrono::hours)timeThreshold_).count();
0080 
0081   // Logic to choose between the two BeamSpots:
0082   // 1. If both BS are older than limitTime retun fake BS
0083   // 2. If only one BS is newer than limitTime return it only if it has
0084   //    sigmaZ larger than sigmaZthreshold_ and the fit converged (BeamType 2)
0085   // 3. If both are newer than the limit threshold return
0086   //    the BS that converged and has larger sigmaZ
0087   if (diffBStime1 > limitTime && diffBStime2 > limitTime) {
0088     edm::LogInfo("OnlineBeamSpotESProducer") << "Defaulting to fake becuase both payloads are too old.";
0089     return nullptr;
0090   } else if (diffBStime2 > limitTime) {
0091     if (bs1->sigmaZ() > sigmaZThreshold_ && bs1->beamType() == 2) {
0092       return bs1;
0093     } else {
0094       edm::LogInfo("OnlineBeamSpotESProducer")
0095           << "Defaulting to fake because the legacy Beam Spot is not suitable and HLT one is too old.";
0096       return nullptr;
0097     }
0098   } else if (diffBStime1 > limitTime) {
0099     if (bs2->sigmaZ() > sigmaZThreshold_ && bs2->beamType() == 2) {
0100       return bs2;
0101     } else {
0102       edm::LogInfo("OnlineBeamSpotESProducer")
0103           << "Defaulting to fake because the HLT Beam Spot is not suitable and the legacy one too old.";
0104       return nullptr;
0105     }
0106   } else {
0107     if (bs1->sigmaZ() > bs2->sigmaZ() && bs1->beamType() == 2) {
0108       return bs1;
0109     } else if (bs2->sigmaZ() >= bs1->sigmaZ() && bs2->beamType() == 2) {
0110       return bs2;
0111     } else {
0112       edm::LogInfo("OnlineBeamSpotESProducer")
0113           << "Defaulting to fake because despite both payloads are young enough, none has the right BeamType.";
0114       return nullptr;
0115     }
0116   }
0117 }
0118 
0119 const BeamSpotOnlineObjects* OnlineBeamSpotESProducer::checkSingleBS(const BeamSpotOnlineObjects* bs1) {
0120   // Current time to be compared with the one read from the payload
0121   auto currentTime =
0122       std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch());
0123 
0124   // Get the beamspot creation time and compute the time difference wrt currentTime
0125   auto bs1time = std::chrono::microseconds(bs1->creationTime());
0126   auto diffBStime1 = (currentTime - bs1time).count();
0127 
0128   // Convert timeThreshold_ from hours to microseconds for comparison
0129   auto limitTime = std::chrono::microseconds((std::chrono::hours)timeThreshold_).count();
0130 
0131   // Check that the BS is within the timeThreshold, converges and passes the sigmaZthreshold
0132   if (diffBStime1 < limitTime && bs1->sigmaZ() > sigmaZThreshold_ && bs1->beamType() == 2) {
0133     return bs1;
0134   } else {
0135     return nullptr;
0136   }
0137 }
0138 
0139 std::shared_ptr<const BeamSpotObjects> OnlineBeamSpotESProducer::produce(const BeamSpotTransientObjectsRcd& iRecord) {
0140   auto legacyRec = iRecord.tryToGetRecord<BeamSpotOnlineLegacyObjectsRcd>();
0141   auto hltRec = iRecord.tryToGetRecord<BeamSpotOnlineHLTObjectsRcd>();
0142   if (not legacyRec and not hltRec) {
0143     edm::LogInfo("OnlineBeamSpotESProducer") << "None of the Beam Spots in ES are available! \n returning a fake one.";
0144     return std::shared_ptr<const BeamSpotObjects>(&fakeBS_, edm::do_nothing_deleter());
0145   }
0146 
0147   const BeamSpotOnlineObjects* best;
0148   if (legacyRec and hltRec) {
0149     best = compareBS(&legacyRec->get(bsLegacyToken_), &hltRec->get(bsHLTToken_));
0150   } else if (legacyRec) {
0151     best = checkSingleBS(&legacyRec->get(bsLegacyToken_));
0152   } else {
0153     best = checkSingleBS(&hltRec->get(bsHLTToken_));
0154   }
0155   if (best) {
0156     return std::shared_ptr<const BeamSpotObjects>(best, edm::do_nothing_deleter());
0157   } else {
0158     return std::shared_ptr<const BeamSpotObjects>(&fakeBS_, edm::do_nothing_deleter());
0159     edm::LogInfo("OnlineBeamSpotESProducer")
0160         << "None of the Online BeamSpots in the ES is suitable, \n returning a fake one. ";
0161   }
0162 };
0163 
0164 DEFINE_FWK_EVENTSETUP_MODULE(OnlineBeamSpotESProducer);