-
Notifications
You must be signed in to change notification settings - Fork 4.3k
/
BeamSpotOnlineProducer.cc
239 lines (203 loc) · 9.57 KB
/
BeamSpotOnlineProducer.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
/**_________________________________________________________________
class: BeamSpotOnlineProducer.h
package: RecoVertex/BeamSpotProducer
author: Francisco Yumiceva, Fermilab ([email protected])
modified by: Simone Gennai, INFN MIB
________________________________________________________________**/
#include "CondFormats/BeamSpotObjects/interface/BeamSpotObjects.h"
#include "CondFormats/DataRecord/interface/BeamSpotObjectsRcd.h"
#include "CondFormats/DataRecord/interface/BeamSpotTransientObjectsRcd.h"
#include "DataFormats/BeamSpot/interface/BeamSpot.h"
#include "DataFormats/Common/interface/Handle.h"
#include "DataFormats/GeometryCommonDetAlgo/interface/GlobalError.h"
#include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerEvmReadoutRecord.h"
#include "DataFormats/Scalers/interface/BeamSpotOnline.h"
#include "FWCore/Framework/interface/ESHandle.h"
#include "FWCore/Framework/interface/ESWatcher.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/EventSetup.h"
#include "FWCore/Framework/interface/stream/EDProducer.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
#include "FWCore/Utilities/interface/ESGetToken.h"
class BeamSpotOnlineProducer : public edm::stream::EDProducer<> {
public:
/// constructor
explicit BeamSpotOnlineProducer(const edm::ParameterSet& iConf);
/// produce a beam spot class
void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override;
///Fill descriptor
static void fillDescriptions(edm::ConfigurationDescriptions& iDesc);
private:
const bool changeFrame_;
const double theMaxZ, theSetSigmaZ;
double theMaxR2;
const bool useTransientRecord_;
const edm::EDGetTokenT<BeamSpotOnlineCollection> scalerToken_;
const edm::EDGetTokenT<L1GlobalTriggerEvmReadoutRecord> l1GtEvmReadoutRecordToken_;
const edm::ESGetToken<BeamSpotObjects, BeamSpotObjectsRcd> beamToken_;
const edm::ESGetToken<BeamSpotObjects, BeamSpotTransientObjectsRcd> beamTransientToken_;
// watch IOV transition to emit warnings
edm::ESWatcher<BeamSpotTransientObjectsRcd> beamTransientRcdESWatcher_;
const unsigned int theBeamShoutMode;
};
using namespace edm;
BeamSpotOnlineProducer::BeamSpotOnlineProducer(const ParameterSet& iconf)
: changeFrame_(iconf.getParameter<bool>("changeToCMSCoordinates")),
theMaxZ(iconf.getParameter<double>("maxZ")),
theSetSigmaZ(iconf.getParameter<double>("setSigmaZ")),
useTransientRecord_(iconf.getParameter<bool>("useTransientRecord")),
scalerToken_(useTransientRecord_ ? edm::EDGetTokenT<BeamSpotOnlineCollection>()
: consumes<BeamSpotOnlineCollection>(iconf.getParameter<InputTag>("src"))),
l1GtEvmReadoutRecordToken_(consumes<L1GlobalTriggerEvmReadoutRecord>(iconf.getParameter<InputTag>("gtEvmLabel"))),
beamToken_(esConsumes<BeamSpotObjects, BeamSpotObjectsRcd>()),
beamTransientToken_(esConsumes<BeamSpotObjects, BeamSpotTransientObjectsRcd>()),
theBeamShoutMode(iconf.getUntrackedParameter<unsigned int>("beamMode", 11)) {
theMaxR2 = iconf.getParameter<double>("maxRadius");
theMaxR2 *= theMaxR2;
produces<reco::BeamSpot>();
}
void BeamSpotOnlineProducer::fillDescriptions(edm::ConfigurationDescriptions& iDesc) {
edm::ParameterSetDescription ps;
ps.add<bool>("changeToCMSCoordinates", false);
ps.add<double>("maxZ", 40.);
ps.add<double>("setSigmaZ", -1.);
ps.addUntracked<unsigned int>("beamMode", 11);
ps.addOptional<InputTag>("src", InputTag("hltScalersRawToDigi"))->setComment("SCAL decommissioned after Run 2");
ps.add<InputTag>("gtEvmLabel", InputTag(""));
ps.add<double>("maxRadius", 2.0);
ps.add<bool>("useTransientRecord", false);
iDesc.addWithDefaultLabel(ps);
}
void BeamSpotOnlineProducer::produce(Event& iEvent, const EventSetup& iSetup) {
// product is a reco::BeamSpot object
auto result = std::make_unique<reco::BeamSpot>();
reco::BeamSpot aSpot;
//shout MODE only in stable beam
bool shoutMODE = false;
edm::Handle<L1GlobalTriggerEvmReadoutRecord> gtEvmReadoutRecord;
if (iEvent.getByToken(l1GtEvmReadoutRecordToken_, gtEvmReadoutRecord)) {
if (gtEvmReadoutRecord->gtfeWord().beamMode() == theBeamShoutMode)
shoutMODE = true;
} else {
shoutMODE = true;
}
bool fallBackToDB = false;
if (useTransientRecord_) {
auto const& spotDB = iSetup.getData(beamTransientToken_);
if (spotDB.beamType() != 2) {
if (shoutMODE && beamTransientRcdESWatcher_.check(iSetup)) {
edm::LogWarning("BeamSpotOnlineProducer")
<< "Online Beam Spot producer falls back to DB value because the ESProducer returned a fake beamspot ";
}
fallBackToDB = true;
} else {
// translate from BeamSpotObjects to reco::BeamSpot
// in case we need to switch to LHC reference frame
// ignore for the moment rotations, and translations
double f = 1.;
if (changeFrame_)
f = -1.;
reco::BeamSpot::Point apoint(f * spotDB.x(), f * spotDB.y(), f * spotDB.z());
reco::BeamSpot::CovarianceMatrix matrix;
for (int i = 0; i < reco::BeamSpot::dimension; ++i) {
for (int j = 0; j < reco::BeamSpot::dimension; ++j) {
matrix(i, j) = spotDB.covariance(i, j);
}
}
double sigmaZ = spotDB.sigmaZ();
if (theSetSigmaZ > 0)
sigmaZ = theSetSigmaZ;
// this assume beam width same in x and y
aSpot = reco::BeamSpot(apoint, sigmaZ, spotDB.dxdz(), spotDB.dydz(), spotDB.beamWidthX(), matrix);
aSpot.setBeamWidthY(spotDB.beamWidthY());
aSpot.setEmittanceX(spotDB.emittanceX());
aSpot.setEmittanceY(spotDB.emittanceY());
aSpot.setbetaStar(spotDB.betaStar());
aSpot.setType(reco::BeamSpot::Tracker);
}
} else {
// get scalar collection
Handle<BeamSpotOnlineCollection> handleScaler;
iEvent.getByToken(scalerToken_, handleScaler);
// beam spot scalar object
BeamSpotOnline spotOnline;
// product is a reco::BeamSpot object
auto result = std::make_unique<reco::BeamSpot>();
if (!handleScaler->empty()) {
// get one element
spotOnline = *(handleScaler->begin());
// in case we need to switch to LHC reference frame
// ignore for the moment rotations, and translations
double f = 1.;
if (changeFrame_)
f = -1.;
reco::BeamSpot::Point apoint(f * spotOnline.x(), spotOnline.y(), f * spotOnline.z());
reco::BeamSpot::CovarianceMatrix matrix;
matrix(0, 0) = spotOnline.err_x() * spotOnline.err_x();
matrix(1, 1) = spotOnline.err_y() * spotOnline.err_y();
matrix(2, 2) = spotOnline.err_z() * spotOnline.err_z();
matrix(3, 3) = spotOnline.err_sigma_z() * spotOnline.err_sigma_z();
double sigmaZ = spotOnline.sigma_z();
if (theSetSigmaZ > 0)
sigmaZ = theSetSigmaZ;
aSpot = reco::BeamSpot(apoint, sigmaZ, spotOnline.dxdz(), f * spotOnline.dydz(), spotOnline.width_x(), matrix);
aSpot.setBeamWidthY(spotOnline.width_y());
aSpot.setEmittanceX(0.);
aSpot.setEmittanceY(0.);
aSpot.setbetaStar(0.);
aSpot.setType(reco::BeamSpot::LHC); // flag value from scalars
// check if we have a valid beam spot fit result from online DQM
if (spotOnline.x() == 0 && spotOnline.y() == 0 && spotOnline.z() == 0 && spotOnline.width_x() == 0 &&
spotOnline.width_y() == 0) {
if (shoutMODE) {
edm::LogWarning("BeamSpotOnlineProducer")
<< "Online Beam Spot producer falls back to DB value because the scaler values are zero ";
}
fallBackToDB = true;
}
double r2 = spotOnline.x() * spotOnline.x() + spotOnline.y() * spotOnline.y();
if (std::abs(spotOnline.z()) >= theMaxZ || r2 >= theMaxR2) {
if (shoutMODE) {
edm::LogError("BeamSpotOnlineProducer")
<< "Online Beam Spot producer falls back to DB value because the scaler values are too big to be true :"
<< spotOnline.x() << " " << spotOnline.y() << " " << spotOnline.z();
}
fallBackToDB = true;
}
} else {
//empty online beamspot collection: FED data was empty
//the error should probably have been send at unpacker level
fallBackToDB = true;
}
}
if (fallBackToDB) {
edm::ESHandle<BeamSpotObjects> beamhandle = iSetup.getHandle(beamToken_);
const BeamSpotObjects* spotDB = beamhandle.product();
// translate from BeamSpotObjects to reco::BeamSpot
reco::BeamSpot::Point apoint(spotDB->x(), spotDB->y(), spotDB->z());
reco::BeamSpot::CovarianceMatrix matrix;
for (int i = 0; i < reco::BeamSpot::dimension; ++i) {
for (int j = 0; j < reco::BeamSpot::dimension; ++j) {
matrix(i, j) = spotDB->covariance(i, j);
}
}
// this assume beam width same in x and y
aSpot = reco::BeamSpot(apoint, spotDB->sigmaZ(), spotDB->dxdz(), spotDB->dydz(), spotDB->beamWidthX(), matrix);
aSpot.setBeamWidthY(spotDB->beamWidthY());
aSpot.setEmittanceX(spotDB->emittanceX());
aSpot.setEmittanceY(spotDB->emittanceY());
aSpot.setbetaStar(spotDB->betaStar());
aSpot.setType(reco::BeamSpot::Tracker);
GlobalError bse(aSpot.rotatedCovariance3D());
if ((bse.cxx() <= 0.) || (bse.cyy() <= 0.) || (bse.czz() <= 0.)) {
edm::LogError("UnusableBeamSpot") << "Beamspot from fallback to DB with invalid errors: " << aSpot.covariance();
}
}
*result = aSpot;
iEvent.put(std::move(result));
}
#include "FWCore/Framework/interface/MakerMacros.h"
DEFINE_FWK_MODULE(BeamSpotOnlineProducer);