Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 /**_________________________________________________________________
0002    class:   BeamSpotOnlineProducer.h
0003    package: RecoVertex/BeamSpotProducer
0004 
0005 
0006 
0007  author: Francisco Yumiceva, Fermilab (yumiceva@fnal.gov)
0008  modified by: Simone Gennai, INFN MIB
0009 
0010 
0011 ________________________________________________________________**/
0012 
0013 #include "CondFormats/BeamSpotObjects/interface/BeamSpotObjects.h"
0014 #include "CondFormats/DataRecord/interface/BeamSpotObjectsRcd.h"
0015 #include "CondFormats/DataRecord/interface/BeamSpotTransientObjectsRcd.h"
0016 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
0017 #include "DataFormats/Common/interface/Handle.h"
0018 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerEvmReadoutRecord.h"
0019 #include "DataFormats/Scalers/interface/BeamSpotOnline.h"
0020 #include "FWCore/Framework/interface/ESHandle.h"
0021 #include "FWCore/Framework/interface/ESWatcher.h"
0022 #include "FWCore/Framework/interface/Event.h"
0023 #include "FWCore/Framework/interface/EventSetup.h"
0024 #include "FWCore/Framework/interface/stream/EDProducer.h"
0025 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0026 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0027 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0028 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0029 #include "FWCore/Utilities/interface/ESGetToken.h"
0030 
0031 class BeamSpotOnlineProducer : public edm::stream::EDProducer<> {
0032 public:
0033   /// constructor
0034   explicit BeamSpotOnlineProducer(const edm::ParameterSet& iConf);
0035 
0036   /// produce a beam spot class
0037   void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override;
0038 
0039   ///Fill descriptor
0040   static void fillDescriptions(edm::ConfigurationDescriptions& iDesc);
0041 
0042 private:
0043   const bool changeFrame_;
0044   const double theMaxZ, theSetSigmaZ;
0045   double theMaxR2;
0046   const bool useTransientRecord_;
0047   const edm::EDGetTokenT<BeamSpotOnlineCollection> scalerToken_;
0048   const edm::EDGetTokenT<L1GlobalTriggerEvmReadoutRecord> l1GtEvmReadoutRecordToken_;
0049   const edm::ESGetToken<BeamSpotObjects, BeamSpotObjectsRcd> beamToken_;
0050   const edm::ESGetToken<BeamSpotObjects, BeamSpotTransientObjectsRcd> beamTransientToken_;
0051 
0052   // watch IOV transition to emit warnings
0053   edm::ESWatcher<BeamSpotTransientObjectsRcd> beamTransientRcdESWatcher_;
0054 
0055   const unsigned int theBeamShoutMode;
0056 };
0057 
0058 using namespace edm;
0059 
0060 BeamSpotOnlineProducer::BeamSpotOnlineProducer(const ParameterSet& iconf)
0061     : changeFrame_(iconf.getParameter<bool>("changeToCMSCoordinates")),
0062       theMaxZ(iconf.getParameter<double>("maxZ")),
0063       theSetSigmaZ(iconf.getParameter<double>("setSigmaZ")),
0064       useTransientRecord_(iconf.getParameter<bool>("useTransientRecord")),
0065       scalerToken_(consumes<BeamSpotOnlineCollection>(iconf.getParameter<InputTag>("src"))),
0066       l1GtEvmReadoutRecordToken_(consumes<L1GlobalTriggerEvmReadoutRecord>(iconf.getParameter<InputTag>("gtEvmLabel"))),
0067       beamToken_(esConsumes<BeamSpotObjects, BeamSpotObjectsRcd>()),
0068       beamTransientToken_(esConsumes<BeamSpotObjects, BeamSpotTransientObjectsRcd>()),
0069       theBeamShoutMode(iconf.getUntrackedParameter<unsigned int>("beamMode", 11)) {
0070   theMaxR2 = iconf.getParameter<double>("maxRadius");
0071   theMaxR2 *= theMaxR2;
0072 
0073   produces<reco::BeamSpot>();
0074 }
0075 
0076 void BeamSpotOnlineProducer::fillDescriptions(edm::ConfigurationDescriptions& iDesc) {
0077   edm::ParameterSetDescription ps;
0078   ps.add<bool>("changeToCMSCoordinates", false);
0079   ps.add<double>("maxZ", 40.);
0080   ps.add<double>("setSigmaZ", -1.);
0081   ps.addUntracked<unsigned int>("beamMode", 11);
0082   ps.add<InputTag>("src", InputTag("hltScalersRawToDigi"));
0083   ps.add<InputTag>("gtEvmLabel", InputTag(""));
0084   ps.add<double>("maxRadius", 2.0);
0085   ps.add<bool>("useTransientRecord", false);
0086   iDesc.addWithDefaultLabel(ps);
0087 }
0088 
0089 void BeamSpotOnlineProducer::produce(Event& iEvent, const EventSetup& iSetup) {
0090   // product is a reco::BeamSpot object
0091   auto result = std::make_unique<reco::BeamSpot>();
0092   reco::BeamSpot aSpot;
0093   //shout MODE only in stable beam
0094   bool shoutMODE = false;
0095   edm::Handle<L1GlobalTriggerEvmReadoutRecord> gtEvmReadoutRecord;
0096   if (iEvent.getByToken(l1GtEvmReadoutRecordToken_, gtEvmReadoutRecord)) {
0097     if (gtEvmReadoutRecord->gtfeWord().beamMode() == theBeamShoutMode)
0098       shoutMODE = true;
0099   } else {
0100     shoutMODE = true;
0101   }
0102   bool fallBackToDB = false;
0103   if (useTransientRecord_) {
0104     auto const& spotDB = iSetup.getData(beamTransientToken_);
0105     if (spotDB.beamType() != 2) {
0106       if (shoutMODE && beamTransientRcdESWatcher_.check(iSetup)) {
0107         edm::LogWarning("BeamSpotFromDB")
0108             << "Online Beam Spot producer falls back to DB value because the ESProducer returned a fake beamspot ";
0109       }
0110       fallBackToDB = true;
0111     } else {
0112       // translate from BeamSpotObjects to reco::BeamSpot
0113       // in case we need to switch to LHC reference frame
0114       // ignore for the moment rotations, and translations
0115       double f = 1.;
0116       if (changeFrame_)
0117         f = -1.;
0118       reco::BeamSpot::Point apoint(f * spotDB.x(), f * spotDB.y(), f * spotDB.z());
0119 
0120       reco::BeamSpot::CovarianceMatrix matrix;
0121       for (int i = 0; i < 7; ++i) {
0122         for (int j = 0; j < 7; ++j) {
0123           matrix(i, j) = spotDB.covariance(i, j);
0124         }
0125       }
0126       double sigmaZ = spotDB.sigmaZ();
0127       if (theSetSigmaZ > 0)
0128         sigmaZ = theSetSigmaZ;
0129 
0130       // this assume beam width same in x and y
0131       aSpot = reco::BeamSpot(apoint, sigmaZ, spotDB.dxdz(), spotDB.dydz(), spotDB.beamWidthX(), matrix);
0132       aSpot.setBeamWidthY(spotDB.beamWidthY());
0133       aSpot.setEmittanceX(spotDB.emittanceX());
0134       aSpot.setEmittanceY(spotDB.emittanceY());
0135       aSpot.setbetaStar(spotDB.betaStar());
0136       aSpot.setType(reco::BeamSpot::Tracker);
0137     }
0138   } else {
0139     // get scalar collection
0140     Handle<BeamSpotOnlineCollection> handleScaler;
0141     iEvent.getByToken(scalerToken_, handleScaler);
0142 
0143     // beam spot scalar object
0144     BeamSpotOnline spotOnline;
0145 
0146     // product is a reco::BeamSpot object
0147     auto result = std::make_unique<reco::BeamSpot>();
0148 
0149     if (!handleScaler->empty()) {
0150       // get one element
0151       spotOnline = *(handleScaler->begin());
0152 
0153       // in case we need to switch to LHC reference frame
0154       // ignore for the moment rotations, and translations
0155       double f = 1.;
0156       if (changeFrame_)
0157         f = -1.;
0158 
0159       reco::BeamSpot::Point apoint(f * spotOnline.x(), spotOnline.y(), f * spotOnline.z());
0160 
0161       reco::BeamSpot::CovarianceMatrix matrix;
0162       matrix(0, 0) = spotOnline.err_x() * spotOnline.err_x();
0163       matrix(1, 1) = spotOnline.err_y() * spotOnline.err_y();
0164       matrix(2, 2) = spotOnline.err_z() * spotOnline.err_z();
0165       matrix(3, 3) = spotOnline.err_sigma_z() * spotOnline.err_sigma_z();
0166 
0167       double sigmaZ = spotOnline.sigma_z();
0168       if (theSetSigmaZ > 0)
0169         sigmaZ = theSetSigmaZ;
0170 
0171       aSpot = reco::BeamSpot(apoint, sigmaZ, spotOnline.dxdz(), f * spotOnline.dydz(), spotOnline.width_x(), matrix);
0172 
0173       aSpot.setBeamWidthY(spotOnline.width_y());
0174       aSpot.setEmittanceX(0.);
0175       aSpot.setEmittanceY(0.);
0176       aSpot.setbetaStar(0.);
0177       aSpot.setType(reco::BeamSpot::LHC);  // flag value from scalars
0178 
0179       // check if we have a valid beam spot fit result from online DQM
0180       if (spotOnline.x() == 0 && spotOnline.y() == 0 && spotOnline.z() == 0 && spotOnline.width_x() == 0 &&
0181           spotOnline.width_y() == 0) {
0182         if (shoutMODE) {
0183           edm::LogWarning("BeamSpotFromDB")
0184               << "Online Beam Spot producer falls back to DB value because the scaler values are zero ";
0185         }
0186         fallBackToDB = true;
0187       }
0188       double r2 = spotOnline.x() * spotOnline.x() + spotOnline.y() * spotOnline.y();
0189       if (std::abs(spotOnline.z()) >= theMaxZ || r2 >= theMaxR2) {
0190         if (shoutMODE) {
0191           edm::LogError("BeamSpotFromDB")
0192               << "Online Beam Spot producer falls back to DB value because the scaler values are too big to be true :"
0193               << spotOnline.x() << " " << spotOnline.y() << " " << spotOnline.z();
0194         }
0195         fallBackToDB = true;
0196       }
0197     } else {
0198       //empty online beamspot collection: FED data was empty
0199       //the error should probably have been send at unpacker level
0200       fallBackToDB = true;
0201     }
0202   }
0203   if (fallBackToDB) {
0204     edm::ESHandle<BeamSpotObjects> beamhandle = iSetup.getHandle(beamToken_);
0205     const BeamSpotObjects* spotDB = beamhandle.product();
0206 
0207     // translate from BeamSpotObjects to reco::BeamSpot
0208     reco::BeamSpot::Point apoint(spotDB->x(), spotDB->y(), spotDB->z());
0209 
0210     reco::BeamSpot::CovarianceMatrix matrix;
0211     for (int i = 0; i < 7; ++i) {
0212       for (int j = 0; j < 7; ++j) {
0213         matrix(i, j) = spotDB->covariance(i, j);
0214       }
0215     }
0216 
0217     // this assume beam width same in x and y
0218     aSpot = reco::BeamSpot(apoint, spotDB->sigmaZ(), spotDB->dxdz(), spotDB->dydz(), spotDB->beamWidthX(), matrix);
0219     aSpot.setBeamWidthY(spotDB->beamWidthY());
0220     aSpot.setEmittanceX(spotDB->emittanceX());
0221     aSpot.setEmittanceY(spotDB->emittanceY());
0222     aSpot.setbetaStar(spotDB->betaStar());
0223     aSpot.setType(reco::BeamSpot::Tracker);
0224   }
0225 
0226   *result = aSpot;
0227 
0228   iEvent.put(std::move(result));
0229 }
0230 
0231 #include "FWCore/Framework/interface/MakerMacros.h"
0232 DEFINE_FWK_MODULE(BeamSpotOnlineProducer);