Skip to content

Commit 4b2c721

Browse files
authored
Merge pull request #48291 from Dr15Jones/consistenBeamSpotOnlineProducer
Make BeamSpotOnlineProducer return consistent results
2 parents 13d093d + 5944370 commit 4b2c721

File tree

1 file changed

+67
-62
lines changed

1 file changed

+67
-62
lines changed

RecoVertex/BeamSpotProducer/plugins/BeamSpotOnlineProducer.cc

Lines changed: 67 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ ________________________________________________________________**/
3131
#include "FWCore/Utilities/interface/ESGetToken.h"
3232
#include "FWCore/Utilities/interface/TypeDemangler.h"
3333

34+
#include <optional>
35+
3436
class BeamSpotOnlineProducer : public edm::stream::EDProducer<> {
3537
public:
3638
/// constructor
@@ -47,17 +49,19 @@ class BeamSpotOnlineProducer : public edm::stream::EDProducer<> {
4749
private:
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

8083
using 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
122124
void 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

129134
void 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

179180
template <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

294298
bool 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

Comments
 (0)