-
Notifications
You must be signed in to change notification settings - Fork 4.3k
/
RPDigiProducer.cc
261 lines (216 loc) · 9.91 KB
/
RPDigiProducer.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
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
// user include files
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "FWCore/Framework/interface/Frameworkfwd.h"
#include "FWCore/Framework/interface/EDProducer.h"
#include "FWCore/Framework/interface/EventSetup.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/MakerMacros.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/Utilities/interface/Exception.h"
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
#include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
#include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h"
#include "SimDataFormats/TrackingHit/interface/PSimHit.h"
#include "SimDataFormats/CrossingFrame/interface/CrossingFrame.h"
#include "SimDataFormats/CrossingFrame/interface/MixCollection.h"
#include "DataFormats/CTPPSDigi/interface/TotemRPDigi.h"
#include "DataFormats/CTPPSDigi/interface/TotemRPDigi.h"
#include "DataFormats/Common/interface/DetSetVector.h"
#include "DataFormats/CTPPSDetId/interface/TotemRPDetId.h"
#include "DataFormats/Common/interface/DetSet.h"
//Random Number
#include "FWCore/ServiceRegistry/interface/Service.h"
#include "FWCore/Utilities/interface/RandomNumberGenerator.h"
#include "CondFormats/PPSObjects/interface/TotemAnalysisMask.h"
#include "CondFormats/DataRecord/interface/TotemReadoutRcd.h"
#include "SimPPS/RPDigiProducer/interface/RPSimTypes.h"
#include "SimPPS/RPDigiProducer/plugins/RPDetDigitizer.h"
#include "SimPPS/RPDigiProducer/plugins/DeadChannelsManager.h"
// system include files
#include <memory>
#include <vector>
#include <map>
#include <string>
#include <iostream>
#include <cstdlib> // I need it for random numbers
// user include files
//
// class decleration
//
namespace CLHEP {
class HepRandomEngine;
}
class RPDigiProducer : public edm::EDProducer {
public:
explicit RPDigiProducer(const edm::ParameterSet&);
~RPDigiProducer() override = default;
static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
private:
void beginRun(const edm::Run&, const edm::EventSetup&) override;
void produce(edm::Event&, const edm::EventSetup&) override;
edm::DetSet<TotemRPDigi> convertRPStripDetSet(const edm::DetSet<TotemRPDigi>&);
// ----------member data ---------------------------
std::vector<std::string> RP_hit_containers_;
typedef std::map<unsigned int, std::vector<PSimHit>> simhit_map;
typedef simhit_map::iterator simhit_map_iterator;
edm::ParameterSet conf_;
std::map<RPDetId, std::unique_ptr<RPDetDigitizer>> theAlgoMap;
CLHEP::HepRandomEngine* rndEngine_ = nullptr;
int verbosity_;
/**
* this variable answers the question whether given channel is dead or not
*/
DeadChannelsManager deadChannelsManager;
/**
* this variable indicates whether we take into account dead channels or simulate as if all
* channels work ok (by default we do not simulate dead channels)
*/
bool simulateDeadChannels;
edm::EDGetTokenT<CrossingFrame<PSimHit>> tokenCrossingFrameTotemRP;
edm::ESGetToken<TotemAnalysisMask, TotemReadoutRcd> tokenAnalysisMask;
};
RPDigiProducer::RPDigiProducer(const edm::ParameterSet& conf) : conf_(conf) {
//now do what ever other initialization is needed
produces<edm::DetSetVector<TotemRPDigi>>();
// register data to consume
tokenCrossingFrameTotemRP = consumes<CrossingFrame<PSimHit>>(edm::InputTag("mix", "g4SimHitsTotemHitsRP", ""));
RP_hit_containers_ = conf.getParameter<std::vector<std::string>>("ROUList");
verbosity_ = conf.getParameter<int>("RPVerbosity");
simulateDeadChannels = false;
if (conf.exists(
"simulateDeadChannels")) { //check if "simulateDeadChannels" variable is defined in configuration file
simulateDeadChannels = conf.getParameter<bool>("simulateDeadChannels");
}
if (simulateDeadChannels) {
tokenAnalysisMask = esConsumes();
}
}
//
// member functions
//
// ------------ method called to produce the data ------------
void RPDigiProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
using namespace edm;
// initialize random engine
if (!rndEngine_) {
Service<RandomNumberGenerator> rng;
if (!rng.isAvailable()) {
throw cms::Exception("Configuration")
<< "This class requires the RandomNumberGeneratorService\n"
"which is not present in the configuration file. You must add the service\n"
"in the configuration file or remove the modules that require it.";
}
rndEngine_ = &(rng->getEngine(iEvent.streamID()));
}
// Step A: Get Inputs
edm::Handle<CrossingFrame<PSimHit>> cf;
iEvent.getByLabel("mix", "g4SimHitsTotemHitsRP", cf);
if (verbosity_) {
edm::LogInfo("RPDigiProducer") << "\n\n=================== Starting SimHit access"
<< " ==================="
<< "\n";
MixCollection<PSimHit> col{cf.product(), std::pair(-0, 0)};
MixCollection<PSimHit>::iterator cfi;
int count = 0;
for (cfi = col.begin(); cfi != col.end(); cfi++) {
edm::LogInfo("RPDigiProducer") << " Hit " << count << " has tof " << cfi->timeOfFlight() << " trackid "
<< cfi->trackId() << " bunchcr " << cfi.bunch() << " trigger " << cfi.getTrigger()
<< ", from EncodedEventId: " << cfi->eventId().bunchCrossing() << " "
<< cfi->eventId().event() << " bcr from MixCol " << cfi.bunch() << "\n";
edm::LogInfo("RPDigiProducer") << " Hit: " << (*cfi) << "\n";
count++;
}
}
MixCollection<PSimHit> allRPHits{cf.product(), std::pair(0, 0)};
if (verbosity_)
edm::LogInfo("RPDigiProducer") << "Input MixCollection size = " << allRPHits.size() << "\n";
//Loop on PSimHit
simhit_map simHitMap_;
simHitMap_.clear();
MixCollection<PSimHit>::iterator isim;
for (isim = allRPHits.begin(); isim != allRPHits.end(); ++isim) {
simHitMap_[(*isim).detUnitId()].push_back((*isim));
}
// Step B: LOOP on hits in event
std::vector<edm::DetSet<TotemRPDigi>> DigiVector;
DigiVector.reserve(400);
DigiVector.clear();
for (simhit_map_iterator it = simHitMap_.begin(); it != simHitMap_.end(); ++it) {
edm::DetSet<TotemRPDigi> digi_collector(it->first);
if (theAlgoMap.find(it->first) == theAlgoMap.end()) {
theAlgoMap[it->first] = std::make_unique<RPDetDigitizer>(conf_, *rndEngine_, it->first, iSetup);
}
std::vector<int> input_links;
simromanpot::DigiPrimaryMapType output_digi_links;
(theAlgoMap.find(it->first)->second)
->run(simHitMap_[it->first], input_links, digi_collector.data, output_digi_links);
if (!digi_collector.data.empty()) {
DigiVector.push_back(convertRPStripDetSet(digi_collector));
}
}
// Step C: create empty output collection
std::unique_ptr<edm::DetSetVector<TotemRPDigi>> digi_output(new edm::DetSetVector<TotemRPDigi>(DigiVector));
if (verbosity_) {
edm::LogInfo("RPDigiProducer") << "digi_output->size()=" << digi_output->size() << "\n";
}
// Step D: write output to file
iEvent.put(std::move(digi_output));
}
// ------------ method called once each job just before starting event loop ------------
void RPDigiProducer::beginRun(const edm::Run& beginrun, const edm::EventSetup& es) {
// get analysis mask to mask channels
if (simulateDeadChannels) {
//set analysisMask in deadChannelsManager
deadChannelsManager = DeadChannelsManager(&es.getData(tokenAnalysisMask));
}
}
edm::DetSet<TotemRPDigi> RPDigiProducer::convertRPStripDetSet(const edm::DetSet<TotemRPDigi>& rpstrip_detset) {
edm::DetSet<TotemRPDigi> rpdigi_detset(rpstrip_detset.detId());
rpdigi_detset.reserve(rpstrip_detset.size());
for (std::vector<TotemRPDigi>::const_iterator stripIterator = rpstrip_detset.data.begin();
stripIterator < rpstrip_detset.data.end();
++stripIterator) {
rpdigi_detset.push_back(TotemRPDigi(stripIterator->stripNumber()));
}
return rpdigi_detset;
}
void RPDigiProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
//RPSiDetDigitizer
//all distances in [mm]
edm::ParameterSetDescription desc;
desc.add<bool>("RPLandauFluctuations", true);
desc.add<bool>("RPDisplacementOn", false);
desc.add<int>("RPVerbosity", 0);
desc.add<double>("RPVFATThreshold", 9000.0);
desc.add<double>("RPTopEdgePosition", 1.5);
desc.add<double>("RPActiveEdgeSmearing", 0.013);
desc.add<double>("RPEquivalentNoiseCharge300um", 1000.0);
desc.add<int>("RPVFATTriggerMode", 2);
desc.add<std::vector<double>>("RPInterStripSmearing",
{
0.011,
});
desc.add<double>("RPSharingSigmas", 5.0); //how many sigmas taken into account for the edges and inter strips
desc.add<double>("RPGeVPerElectron", 3.61e-09);
desc.add<double>("RPActiveEdgePosition", 0.034); //from the physical edge
desc.add<bool>("RPDeadStripSimulationOn", false);
desc.add<std::vector<std::string>>("ROUList",
{
"TotemHitsRP",
});
desc.add<bool>("RPNoNoise", false);
desc.add<bool>("RPDigiSimHitRelationsPresistence", false); //save links betweend digi, clusters and OSCAR/Geant4 hits
desc.add<std::string>("mixLabel", "mix");
desc.add<int>("RPChargeDivisionsPerThickness", 5);
desc.add<double>("RPDeltaProductionCut", 0.120425); //[MeV]
desc.add<double>("RPBottomEdgePosition", 1.5);
desc.add<double>("RPBottomEdgeSmearing", 0.011);
desc.add<double>("RPTopEdgeSmearing", 0.011);
desc.add<std::string>("InputCollection", "g4SimHitsTotemHitsRP");
desc.add<double>("RPInterStripCoupling",
1.0); //fraction of charge going to the strip, the missing part is taken by its neighbours
desc.add<double>("RPDeadStripProbability", 0.001);
desc.add<int>("RPChargeDivisionsPerStrip", 15);
descriptions.add("RPSiDetDigitizer", desc);
}
DEFINE_FWK_MODULE(RPDigiProducer);