@@ -31,6 +31,8 @@ ________________________________________________________________**/
3131#include " FWCore/Utilities/interface/ESGetToken.h"
3232#include " FWCore/Utilities/interface/TypeDemangler.h"
3333
34+ #include < optional>
35+
3436class BeamSpotOnlineProducer : public edm ::stream::EDProducer<> {
3537public:
3638 // / constructor
@@ -47,17 +49,19 @@ class BeamSpotOnlineProducer : public edm::stream::EDProducer<> {
4749private:
4850 // helper methods
4951 bool shouldShout (const edm::Event& iEvent) const ;
50- bool processRecords (const edm::LuminosityBlock& iLumi, const edm::EventSetup& iSetup, bool shoutMODE);
51- void createBeamSpotFromRecord (const BeamSpotObjects& spotDB);
52+ std::optional<reco::BeamSpot> processRecords (const edm::LuminosityBlock& iLumi,
53+ const edm::EventSetup& iSetup,
54+ bool shoutMODE) const ;
55+ reco::BeamSpot createBeamSpotFromRecord (const BeamSpotObjects& spotDB) const ;
5256 template <typename RecordType, typename TokenType>
53- const BeamSpotOnlineObjects& getBeamSpotFromRecord (const TokenType& token,
57+ const BeamSpotOnlineObjects* getBeamSpotFromRecord (const TokenType& token,
5458 const edm::LuminosityBlock& lumi,
55- const edm::EventSetup& setup);
56- const BeamSpotOnlineObjects& chooseBS (const BeamSpotOnlineObjects& bs1, const BeamSpotOnlineObjects& bs2);
57- bool processScalers (const edm::Event& iEvent, bool shoutMODE);
58- void createBeamSpotFromScaler (const BeamSpotOnline& spotOnline);
59+ const edm::EventSetup& setup) const ;
60+ const BeamSpotOnlineObjects* chooseBS (const BeamSpotOnlineObjects* bs1, const BeamSpotOnlineObjects* bs2) const ;
61+ std::optional<reco::BeamSpot> processScalers (const edm::Event& iEvent, bool shoutMODE) const ;
62+ reco::BeamSpot createBeamSpotFromScaler (const BeamSpotOnline& spotOnline) const ;
5963 bool isInvalidScaler (const BeamSpotOnline& spotOnline, bool shoutMODE) const ;
60- void createBeamSpotFromDB (const edm::EventSetup& iSetup, bool shoutMODE);
64+ reco::BeamSpot createBeamSpotFromDB (const edm::EventSetup& iSetup, bool shoutMODE) const ;
6165
6266 // data members
6367 const bool changeFrame_;
@@ -72,9 +76,8 @@ class BeamSpotOnlineProducer : public edm::stream::EDProducer<> {
7276 const edm::ESGetToken<BeamSpotOnlineObjects, BeamSpotOnlineLegacyObjectsRcd> beamTokenLegacy_;
7377 const edm::ESGetToken<BeamSpotOnlineObjects, BeamSpotOnlineHLTObjectsRcd> beamTokenHLT_;
7478
75- reco::BeamSpot result ;
79+ std::optional< reco::BeamSpot> lumiResult_ ;
7680 const unsigned int theBeamShoutMode;
77- BeamSpotOnlineObjects fakeBS_;
7881};
7982
8083using namespace edm ;
@@ -90,13 +93,12 @@ BeamSpotOnlineProducer::BeamSpotOnlineProducer(const ParameterSet& iconf)
9093 scalerToken_(useBSOnlineRecords_ ? edm::EDGetTokenT<BeamSpotOnlineCollection>()
9194 : consumes<BeamSpotOnlineCollection>(iconf.getParameter<InputTag>(" src" ))),
9295 l1GtEvmReadoutRecordToken_(consumes<L1GlobalTriggerEvmReadoutRecord>(iconf.getParameter<InputTag>(" gtEvmLabel" ))),
93- beamToken_(esConsumes<BeamSpotObjects, BeamSpotObjectsRcd>()),
96+ beamToken_(esConsumes<BeamSpotObjects, BeamSpotObjectsRcd, edm::Transition::BeginLuminosityBlock >()),
9497 beamTokenLegacy_(
9598 esConsumes<BeamSpotOnlineObjects, BeamSpotOnlineLegacyObjectsRcd, edm::Transition::BeginLuminosityBlock>()),
9699 beamTokenHLT_(
97100 esConsumes<BeamSpotOnlineObjects, BeamSpotOnlineHLTObjectsRcd, edm::Transition::BeginLuminosityBlock>()),
98101 theBeamShoutMode(iconf.getUntrackedParameter<unsigned int >(" beamMode" , 11 )) {
99- fakeBS_.setType (reco::BeamSpot::Fake);
100102 theMaxR2 = iconf.getParameter <double >(" maxRadius" );
101103 theMaxR2 *= theMaxR2;
102104
@@ -122,29 +124,29 @@ void BeamSpotOnlineProducer::fillDescriptions(edm::ConfigurationDescriptions& iD
122124void BeamSpotOnlineProducer::beginLuminosityBlock (const edm::LuminosityBlock& lumi, const edm::EventSetup& setup) {
123125 // / fetch online records only at the beginning of a lumisection
124126 if (useBSOnlineRecords_) {
125- processRecords (lumi, setup, true );
127+ lumiResult_ = processRecords (lumi, setup, true );
128+ if (lumiResult_)
129+ return ;
126130 }
131+ lumiResult_ = createBeamSpotFromDB (setup, true );
127132}
128133
129134void BeamSpotOnlineProducer::produce (edm::Event& iEvent, const edm::EventSetup& iSetup) {
130135 // Determine if we should "shout" based on the beam mode
131136 bool shoutMODE = shouldShout (iEvent);
132- bool fallBackToDB{false };
133137
134- // Use online records if enabled
135- if (useBSOnlineRecords_) {
136- fallBackToDB = result.type () != reco::BeamSpot::Tracker;
137- } else {
138+ std::unique_ptr<reco::BeamSpot> toput;
139+ if (not useBSOnlineRecords_) {
138140 // Process online beam spot scalers
139- fallBackToDB = processScalers (iEvent, shoutMODE);
141+ auto bs = processScalers (iEvent, shoutMODE);
142+ if (bs) {
143+ toput = std::make_unique<reco::BeamSpot>(std::move (*bs));
144+ }
140145 }
141-
142- // Fallback to DB if necessary
143- if (fallBackToDB) {
144- createBeamSpotFromDB (iSetup, shoutMODE);
146+ if (not toput) {
147+ assert (lumiResult_);
148+ toput = std::make_unique<reco::BeamSpot>(*lumiResult_);
145149 }
146-
147- std::unique_ptr<reco::BeamSpot> toput = std::make_unique<reco::BeamSpot>(result);
148150 iEvent.put (std::move (toput));
149151}
150152
@@ -156,80 +158,82 @@ bool BeamSpotOnlineProducer::shouldShout(const edm::Event& iEvent) const {
156158 return true ; // Default to "shout" if the record is missing
157159}
158160
159- bool BeamSpotOnlineProducer::processRecords (const edm::LuminosityBlock& iLumi,
160- const edm::EventSetup& iSetup,
161- bool shoutMODE) {
162- auto const & spotDBLegacy = getBeamSpotFromRecord<BeamSpotOnlineLegacyObjectsRcd>(beamTokenLegacy_, iLumi, iSetup);
163- auto const & spotDBHLT = getBeamSpotFromRecord<BeamSpotOnlineHLTObjectsRcd>(beamTokenHLT_, iLumi, iSetup);
164- auto const & spotDB = chooseBS (spotDBLegacy, spotDBHLT);
161+ std::optional<reco::BeamSpot> BeamSpotOnlineProducer::processRecords (const edm::LuminosityBlock& iLumi,
162+ const edm::EventSetup& iSetup,
163+ bool shoutMODE) const {
164+ auto const * spotDBLegacy = getBeamSpotFromRecord<BeamSpotOnlineLegacyObjectsRcd>(beamTokenLegacy_, iLumi, iSetup);
165+ auto const * spotDBHLT = getBeamSpotFromRecord<BeamSpotOnlineHLTObjectsRcd>(beamTokenHLT_, iLumi, iSetup);
166+ auto const * spotDB = chooseBS (spotDBLegacy, spotDBHLT);
165167
166- if (spotDB. beamType () != reco::BeamSpot::Tracker ) {
168+ if (not spotDB ) {
167169 if (shoutMODE) {
168170 edm::LogWarning (" BeamSpotOnlineProducer" ) << " None of the online records holds a valid beam spot. The Online "
169171 " Beam Spot producer falls back to the PCL value." ;
170172 }
171- return true ; // Trigger fallback to DB
173+ return {} ; // Trigger fallback to DB
172174 }
173175
174176 // Create BeamSpot from transient record
175- createBeamSpotFromRecord (spotDB);
176- return false ; // No fallback needed
177+ return createBeamSpotFromRecord (*spotDB);
177178}
178179
179180template <typename RecordType, typename TokenType>
180- const BeamSpotOnlineObjects& BeamSpotOnlineProducer::getBeamSpotFromRecord (const TokenType& token,
181+ const BeamSpotOnlineObjects* BeamSpotOnlineProducer::getBeamSpotFromRecord (const TokenType& token,
181182 const LuminosityBlock& lumi,
182- const EventSetup& setup) {
183+ const EventSetup& setup) const {
183184 auto const bsRecord = setup.tryToGet <RecordType>();
184- const auto & recordTypeName = edm::typeDemangle (typeid (RecordType).name ());
185185 if (!bsRecord) {
186+ const auto & recordTypeName = edm::typeDemangle (typeid (RecordType).name ());
186187 edm::LogWarning (" BeamSpotOnlineProducer" ) << " No " << recordTypeName << " found in the EventSetup" ;
187- return fakeBS_ ;
188+ return nullptr ;
188189 }
189190 const auto & bsHandle = setup.getHandle (token);
190191 if (bsHandle.isValid ()) {
191192 const auto & bs = *bsHandle;
192193 if (bs.sigmaZ () < sigmaZThreshold_ || bs.beamWidthX () < sigmaXYThreshold_ || bs.beamWidthY () < sigmaXYThreshold_ ||
193194 bs.beamType () != reco::BeamSpot::Tracker) {
195+ const auto & recordTypeName = edm::typeDemangle (typeid (RecordType).name ());
194196 edm::LogWarning (" BeamSpotOnlineProducer" )
195197 << " The beam spot record does not pass the fit sanity checks (record: " << recordTypeName << " )" << std::endl
196198 << " sigmaZ: " << bs.sigmaZ () << std::endl
197199 << " sigmaX: " << bs.beamWidthX () << std::endl
198200 << " sigmaY: " << bs.beamWidthY () << std::endl
199201 << " type: " << bs.beamType ();
200- return fakeBS_ ;
202+ return nullptr ;
201203 }
202204 auto lumitime = std::chrono::seconds (lumi.beginTime ().unixTime ());
203205 auto bstime = std::chrono::microseconds (bs.creationTime ());
204206 auto threshold = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::hours (timeThreshold_)).count ();
205207 if ((lumitime - bstime).count () > threshold) {
208+ const auto & recordTypeName = edm::typeDemangle (typeid (RecordType).name ());
206209 edm::LogWarning (" BeamSpotOnlineProducer" )
207210 << " The beam spot record is too old. (record: " << recordTypeName << " )" << std::endl
208211 << " record creation time: " << std::chrono::duration_cast<std::chrono::seconds>(bstime).count ()
209212 << " lumi block time: " << std::chrono::duration_cast<std::chrono::seconds>(lumitime).count ();
210- return fakeBS_ ;
213+ return nullptr ;
211214 }
212- return bs;
215+ return & bs;
213216 } else {
217+ const auto & recordTypeName = edm::typeDemangle (typeid (RecordType).name ());
214218 edm::LogWarning (" BeamSpotOnlineProducer" ) << " Invalid online beam spot handle for the record: " << recordTypeName;
215- return fakeBS_ ;
219+ return nullptr ;
216220 }
217221}
218222
219- const BeamSpotOnlineObjects& BeamSpotOnlineProducer::chooseBS (const BeamSpotOnlineObjects& bs1,
220- const BeamSpotOnlineObjects& bs2) {
221- if (bs1. beamType () == reco::BeamSpot::Tracker && bs2. beamType () == reco::BeamSpot::Tracker) {
222- return bs1. sigmaZ () > bs2. sigmaZ () ? bs1 : bs2;
223- } else if (bs1. beamType () == reco::BeamSpot::Tracker) {
223+ const BeamSpotOnlineObjects* BeamSpotOnlineProducer::chooseBS (const BeamSpotOnlineObjects* bs1,
224+ const BeamSpotOnlineObjects* bs2) const {
225+ if (bs1 and bs2 and bs1-> beamType () == reco::BeamSpot::Tracker && bs2-> beamType () == reco::BeamSpot::Tracker) {
226+ return bs1-> sigmaZ () > bs2-> sigmaZ () ? bs1 : bs2;
227+ } else if (bs1 and bs1-> beamType () == reco::BeamSpot::Tracker) {
224228 return bs1;
225- } else if (bs2. beamType () == reco::BeamSpot::Tracker) {
229+ } else if (bs2 and bs2-> beamType () == reco::BeamSpot::Tracker) {
226230 return bs2;
227231 } else {
228- return fakeBS_ ;
232+ return nullptr ;
229233 }
230234}
231235
232- void BeamSpotOnlineProducer::createBeamSpotFromRecord (const BeamSpotObjects& spotDB) {
236+ reco::BeamSpot BeamSpotOnlineProducer::createBeamSpotFromRecord (const BeamSpotObjects& spotDB) const {
233237 double f = changeFrame_ ? -1.0 : 1.0 ;
234238 reco::BeamSpot::Point apoint (f * spotDB.x (), f * spotDB.y (), f * spotDB.z ());
235239
@@ -241,15 +245,16 @@ void BeamSpotOnlineProducer::createBeamSpotFromRecord(const BeamSpotObjects& spo
241245 }
242246
243247 double sigmaZ = (theSetSigmaZ > 0 ) ? theSetSigmaZ : spotDB.sigmaZ ();
244- result = reco::BeamSpot (apoint, sigmaZ, spotDB.dxdz (), spotDB.dydz (), spotDB.beamWidthX (), matrix);
248+ reco::BeamSpot result (apoint, sigmaZ, spotDB.dxdz (), spotDB.dydz (), spotDB.beamWidthX (), matrix);
245249 result.setBeamWidthY (spotDB.beamWidthY ());
246250 result.setEmittanceX (spotDB.emittanceX ());
247251 result.setEmittanceY (spotDB.emittanceY ());
248252 result.setbetaStar (spotDB.betaStar ());
249253 result.setType (reco::BeamSpot::Tracker);
254+ return result;
250255}
251256
252- bool BeamSpotOnlineProducer::processScalers (const edm::Event& iEvent, bool shoutMODE) {
257+ std::optional<reco::BeamSpot> BeamSpotOnlineProducer::processScalers (const edm::Event& iEvent, bool shoutMODE) const {
253258 edm::Handle<BeamSpotOnlineCollection> handleScaler;
254259 iEvent.getByToken (scalerToken_, handleScaler);
255260
@@ -258,21 +263,19 @@ bool BeamSpotOnlineProducer::processScalers(const edm::Event& iEvent, bool shout
258263 edm::LogWarning (" BeamSpotOnlineProducer" ) << " Scalers handle is empty. The Online "
259264 " Beam Spot producer falls back to the PCL value." ;
260265 }
261- return true ; // Fallback to DB if scaler collection is empty
266+ return {};
262267 }
263268
264269 // Extract data from scaler
265270 BeamSpotOnline spotOnline = *(handleScaler->begin ());
266- createBeamSpotFromScaler (spotOnline);
267-
268271 // Validate the scaler data
269272 if (isInvalidScaler (spotOnline, shoutMODE)) {
270- return true ; // Trigger fallback to DB
273+ return {} ; // Trigger fallback to DB
271274 }
272- return false ; // No fallback needed
275+ return createBeamSpotFromScaler (spotOnline);
273276}
274277
275- void BeamSpotOnlineProducer::createBeamSpotFromScaler (const BeamSpotOnline& spotOnline) {
278+ reco::BeamSpot BeamSpotOnlineProducer::createBeamSpotFromScaler (const BeamSpotOnline& spotOnline) const {
276279 double f = changeFrame_ ? -1.0 : 1.0 ;
277280 reco::BeamSpot::Point apoint (f * spotOnline.x (), spotOnline.y (), f * spotOnline.z ());
278281
@@ -283,12 +286,13 @@ void BeamSpotOnlineProducer::createBeamSpotFromScaler(const BeamSpotOnline& spot
283286 matrix (3 , 3 ) = spotOnline.err_sigma_z () * spotOnline.err_sigma_z ();
284287
285288 double sigmaZ = (theSetSigmaZ > 0 ) ? theSetSigmaZ : spotOnline.sigma_z ();
286- result = reco::BeamSpot (apoint, sigmaZ, spotOnline.dxdz (), f * spotOnline.dydz (), spotOnline.width_x (), matrix);
289+ reco::BeamSpot result (apoint, sigmaZ, spotOnline.dxdz (), f * spotOnline.dydz (), spotOnline.width_x (), matrix);
287290 result.setBeamWidthY (spotOnline.width_y ());
288291 result.setEmittanceX (0.0 );
289292 result.setEmittanceY (0.0 );
290293 result.setbetaStar (0.0 );
291294 result.setType (reco::BeamSpot::LHC);
295+ return result;
292296}
293297
294298bool BeamSpotOnlineProducer::isInvalidScaler (const BeamSpotOnline& spotOnline, bool shoutMODE) const {
@@ -313,7 +317,7 @@ bool BeamSpotOnlineProducer::isInvalidScaler(const BeamSpotOnline& spotOnline, b
313317 return false ;
314318}
315319
316- void BeamSpotOnlineProducer::createBeamSpotFromDB (const edm::EventSetup& iSetup, bool shoutMODE) {
320+ reco::BeamSpot BeamSpotOnlineProducer::createBeamSpotFromDB (const edm::EventSetup& iSetup, bool shoutMODE) const {
317321 edm::ESHandle<BeamSpotObjects> beamhandle = iSetup.getHandle (beamToken_);
318322 const BeamSpotObjects* spotDB = beamhandle.product ();
319323
@@ -326,7 +330,7 @@ void BeamSpotOnlineProducer::createBeamSpotFromDB(const edm::EventSetup& iSetup,
326330 }
327331 }
328332
329- result = reco::BeamSpot (apoint, spotDB->sigmaZ (), spotDB->dxdz (), spotDB->dydz (), spotDB->beamWidthX (), matrix);
333+ reco::BeamSpot result (apoint, spotDB->sigmaZ (), spotDB->dxdz (), spotDB->dydz (), spotDB->beamWidthX (), matrix);
330334 result.setBeamWidthY (spotDB->beamWidthY ());
331335 result.setEmittanceX (spotDB->emittanceX ());
332336 result.setEmittanceY (spotDB->emittanceY ());
@@ -337,6 +341,7 @@ void BeamSpotOnlineProducer::createBeamSpotFromDB(const edm::EventSetup& iSetup,
337341 if ((bse.cxx () <= 0.0 ) || (bse.cyy () <= 0.0 ) || (bse.czz () <= 0.0 )) {
338342 edm::LogError (" UnusableBeamSpot" ) << " Beamspot from DB fallback has invalid errors: " << result.covariance ();
339343 }
344+ return result;
340345}
341346
342347#include " FWCore/Framework/interface/MakerMacros.h"
0 commit comments