Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-07-20 02:17:30

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_(useTransientRecord_ ? edm::EDGetTokenT<BeamSpotOnlineCollection>()
0066                                        : consumes<BeamSpotOnlineCollection>(iconf.getParameter<InputTag>("src"))),
0067       l1GtEvmReadoutRecordToken_(consumes<L1GlobalTriggerEvmReadoutRecord>(iconf.getParameter<InputTag>("gtEvmLabel"))),
0068       beamToken_(esConsumes<BeamSpotObjects, BeamSpotObjectsRcd>()),
0069       beamTransientToken_(esConsumes<BeamSpotObjects, BeamSpotTransientObjectsRcd>()),
0070       theBeamShoutMode(iconf.getUntrackedParameter<unsigned int>("beamMode", 11)) {
0071   theMaxR2 = iconf.getParameter<double>("maxRadius");
0072   theMaxR2 *= theMaxR2;
0073 
0074   produces<reco::BeamSpot>();
0075 }
0076 
0077 void BeamSpotOnlineProducer::fillDescriptions(edm::ConfigurationDescriptions& iDesc) {
0078   edm::ParameterSetDescription ps;
0079   ps.add<bool>("changeToCMSCoordinates", false);
0080   ps.add<double>("maxZ", 40.);
0081   ps.add<double>("setSigmaZ", -1.);
0082   ps.addUntracked<unsigned int>("beamMode", 11);
0083   ps.addOptional<InputTag>("src", InputTag("hltScalersRawToDigi"))->setComment("SCAL decommissioned after Run 2");
0084   ps.add<InputTag>("gtEvmLabel", InputTag(""));
0085   ps.add<double>("maxRadius", 2.0);
0086   ps.add<bool>("useTransientRecord", false);
0087   iDesc.addWithDefaultLabel(ps);
0088 }
0089 
0090 void BeamSpotOnlineProducer::produce(Event& iEvent, const EventSetup& iSetup) {
0091   // product is a reco::BeamSpot object
0092   auto result = std::make_unique<reco::BeamSpot>();
0093   reco::BeamSpot aSpot;
0094   //shout MODE only in stable beam
0095   bool shoutMODE = false;
0096   edm::Handle<L1GlobalTriggerEvmReadoutRecord> gtEvmReadoutRecord;
0097   if (iEvent.getByToken(l1GtEvmReadoutRecordToken_, gtEvmReadoutRecord)) {
0098     if (gtEvmReadoutRecord->gtfeWord().beamMode() == theBeamShoutMode)
0099       shoutMODE = true;
0100   } else {
0101     shoutMODE = true;
0102   }
0103   bool fallBackToDB = false;
0104   if (useTransientRecord_) {
0105     auto const& spotDB = iSetup.getData(beamTransientToken_);
0106     if (spotDB.beamType() != 2) {
0107       if (shoutMODE && beamTransientRcdESWatcher_.check(iSetup)) {
0108         edm::LogWarning("BeamSpotFromDB")
0109             << "Online Beam Spot producer falls back to DB value because the ESProducer returned a fake beamspot ";
0110       }
0111       fallBackToDB = true;
0112     } else {
0113       // translate from BeamSpotObjects to reco::BeamSpot
0114       // in case we need to switch to LHC reference frame
0115       // ignore for the moment rotations, and translations
0116       double f = 1.;
0117       if (changeFrame_)
0118         f = -1.;
0119       reco::BeamSpot::Point apoint(f * spotDB.x(), f * spotDB.y(), f * spotDB.z());
0120 
0121       reco::BeamSpot::CovarianceMatrix matrix;
0122       for (int i = 0; i < 7; ++i) {
0123         for (int j = 0; j < 7; ++j) {
0124           matrix(i, j) = spotDB.covariance(i, j);
0125         }
0126       }
0127       double sigmaZ = spotDB.sigmaZ();
0128       if (theSetSigmaZ > 0)
0129         sigmaZ = theSetSigmaZ;
0130 
0131       // this assume beam width same in x and y
0132       aSpot = reco::BeamSpot(apoint, sigmaZ, spotDB.dxdz(), spotDB.dydz(), spotDB.beamWidthX(), matrix);
0133       aSpot.setBeamWidthY(spotDB.beamWidthY());
0134       aSpot.setEmittanceX(spotDB.emittanceX());
0135       aSpot.setEmittanceY(spotDB.emittanceY());
0136       aSpot.setbetaStar(spotDB.betaStar());
0137       aSpot.setType(reco::BeamSpot::Tracker);
0138     }
0139   } else {
0140     // get scalar collection
0141     Handle<BeamSpotOnlineCollection> handleScaler;
0142     iEvent.getByToken(scalerToken_, handleScaler);
0143 
0144     // beam spot scalar object
0145     BeamSpotOnline spotOnline;
0146 
0147     // product is a reco::BeamSpot object
0148     auto result = std::make_unique<reco::BeamSpot>();
0149 
0150     if (!handleScaler->empty()) {
0151       // get one element
0152       spotOnline = *(handleScaler->begin());
0153 
0154       // in case we need to switch to LHC reference frame
0155       // ignore for the moment rotations, and translations
0156       double f = 1.;
0157       if (changeFrame_)
0158         f = -1.;
0159 
0160       reco::BeamSpot::Point apoint(f * spotOnline.x(), spotOnline.y(), f * spotOnline.z());
0161 
0162       reco::BeamSpot::CovarianceMatrix matrix;
0163       matrix(0, 0) = spotOnline.err_x() * spotOnline.err_x();
0164       matrix(1, 1) = spotOnline.err_y() * spotOnline.err_y();
0165       matrix(2, 2) = spotOnline.err_z() * spotOnline.err_z();
0166       matrix(3, 3) = spotOnline.err_sigma_z() * spotOnline.err_sigma_z();
0167 
0168       double sigmaZ = spotOnline.sigma_z();
0169       if (theSetSigmaZ > 0)
0170         sigmaZ = theSetSigmaZ;
0171 
0172       aSpot = reco::BeamSpot(apoint, sigmaZ, spotOnline.dxdz(), f * spotOnline.dydz(), spotOnline.width_x(), matrix);
0173 
0174       aSpot.setBeamWidthY(spotOnline.width_y());
0175       aSpot.setEmittanceX(0.);
0176       aSpot.setEmittanceY(0.);
0177       aSpot.setbetaStar(0.);
0178       aSpot.setType(reco::BeamSpot::LHC);  // flag value from scalars
0179 
0180       // check if we have a valid beam spot fit result from online DQM
0181       if (spotOnline.x() == 0 && spotOnline.y() == 0 && spotOnline.z() == 0 && spotOnline.width_x() == 0 &&
0182           spotOnline.width_y() == 0) {
0183         if (shoutMODE) {
0184           edm::LogWarning("BeamSpotFromDB")
0185               << "Online Beam Spot producer falls back to DB value because the scaler values are zero ";
0186         }
0187         fallBackToDB = true;
0188       }
0189       double r2 = spotOnline.x() * spotOnline.x() + spotOnline.y() * spotOnline.y();
0190       if (std::abs(spotOnline.z()) >= theMaxZ || r2 >= theMaxR2) {
0191         if (shoutMODE) {
0192           edm::LogError("BeamSpotFromDB")
0193               << "Online Beam Spot producer falls back to DB value because the scaler values are too big to be true :"
0194               << spotOnline.x() << " " << spotOnline.y() << " " << spotOnline.z();
0195         }
0196         fallBackToDB = true;
0197       }
0198     } else {
0199       //empty online beamspot collection: FED data was empty
0200       //the error should probably have been send at unpacker level
0201       fallBackToDB = true;
0202     }
0203   }
0204   if (fallBackToDB) {
0205     edm::ESHandle<BeamSpotObjects> beamhandle = iSetup.getHandle(beamToken_);
0206     const BeamSpotObjects* spotDB = beamhandle.product();
0207 
0208     // translate from BeamSpotObjects to reco::BeamSpot
0209     reco::BeamSpot::Point apoint(spotDB->x(), spotDB->y(), spotDB->z());
0210 
0211     reco::BeamSpot::CovarianceMatrix matrix;
0212     for (int i = 0; i < 7; ++i) {
0213       for (int j = 0; j < 7; ++j) {
0214         matrix(i, j) = spotDB->covariance(i, j);
0215       }
0216     }
0217 
0218     // this assume beam width same in x and y
0219     aSpot = reco::BeamSpot(apoint, spotDB->sigmaZ(), spotDB->dxdz(), spotDB->dydz(), spotDB->beamWidthX(), matrix);
0220     aSpot.setBeamWidthY(spotDB->beamWidthY());
0221     aSpot.setEmittanceX(spotDB->emittanceX());
0222     aSpot.setEmittanceY(spotDB->emittanceY());
0223     aSpot.setbetaStar(spotDB->betaStar());
0224     aSpot.setType(reco::BeamSpot::Tracker);
0225   }
0226 
0227   *result = aSpot;
0228 
0229   iEvent.put(std::move(result));
0230 }
0231 
0232 #include "FWCore/Framework/interface/MakerMacros.h"
0233 DEFINE_FWK_MODULE(BeamSpotOnlineProducer);