CMS 3D CMS Logo

RPDigiProducer.cc
Go to the documentation of this file.
1 // user include files
12 
17 
23 
24 //Random Number
27 
33 
36 
37 // system include files
38 #include <memory>
39 #include <vector>
40 #include <map>
41 #include <string>
42 #include <iostream>
43 #include <cstdlib> // I need it for random numbers
44 
45 // user include files
46 
47 //
48 // class decleration
49 //
50 
51 namespace CLHEP {
52  class HepRandomEngine;
53 }
54 
56 public:
57  explicit RPDigiProducer(const edm::ParameterSet&);
58  ~RPDigiProducer() override = default;
59 
60  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
61 
62 private:
63  void beginRun(const edm::Run&, const edm::EventSetup&) override;
64  void produce(edm::Event&, const edm::EventSetup&) override;
65 
67 
68  // ----------member data ---------------------------
69  std::vector<std::string> RP_hit_containers_;
70  typedef std::map<unsigned int, std::vector<PSimHit>> simhit_map;
71  typedef simhit_map::iterator simhit_map_iterator;
72 
74  std::map<RPDetId, std::unique_ptr<RPDetDigitizer>> theAlgoMap;
75 
76  CLHEP::HepRandomEngine* rndEngine_ = nullptr;
78 
88 
93 };
94 
96  //now do what ever other initialization is needed
97  produces<edm::DetSetVector<TotemRPDigi>>();
98 
99  // register data to consume
100  tokenCrossingFrameTotemRP = consumes<CrossingFrame<PSimHit>>(edm::InputTag("mix", "g4SimHitsTotemHitsRP", ""));
101 
102  RP_hit_containers_ = conf.getParameter<std::vector<std::string>>("ROUList");
103  verbosity_ = conf.getParameter<int>("RPVerbosity");
104 
105  simulateDeadChannels = false;
106  if (conf.exists(
107  "simulateDeadChannels")) { //check if "simulateDeadChannels" variable is defined in configuration file
108  simulateDeadChannels = conf.getParameter<bool>("simulateDeadChannels");
109  }
110  if (simulateDeadChannels) {
112  }
114  geomToken = esConsumes();
115 }
116 
117 //
118 // member functions
119 //
120 
121 // ------------ method called to produce the data ------------
123  using namespace edm;
124 
125  // initialize random engine
126  if (!rndEngine_) {
128  if (!rng.isAvailable()) {
129  throw cms::Exception("Configuration")
130  << "This class requires the RandomNumberGeneratorService\n"
131  "which is not present in the configuration file. You must add the service\n"
132  "in the configuration file or remove the modules that require it.";
133  }
134  rndEngine_ = &(rng->getEngine(iEvent.streamID()));
135  }
136 
137  // Step A: Get Inputs
139  iEvent.getByLabel("mix", "g4SimHitsTotemHitsRP", cf);
140 
141  if (verbosity_) {
142  edm::LogInfo("RPDigiProducer") << "\n\n=================== Starting SimHit access"
143  << " ==================="
144  << "\n";
145 
146  MixCollection<PSimHit> col{cf.product(), std::pair(-0, 0)};
148  int count = 0;
149  for (cfi = col.begin(); cfi != col.end(); cfi++) {
150  edm::LogInfo("RPDigiProducer") << " Hit " << count << " has tof " << cfi->timeOfFlight() << " trackid "
151  << cfi->trackId() << " bunchcr " << cfi.bunch() << " trigger " << cfi.getTrigger()
152  << ", from EncodedEventId: " << cfi->eventId().bunchCrossing() << " "
153  << cfi->eventId().event() << " bcr from MixCol " << cfi.bunch() << "\n";
154  edm::LogInfo("RPDigiProducer") << " Hit: " << (*cfi) << "\n";
155  count++;
156  }
157  }
158 
159  MixCollection<PSimHit> allRPHits{cf.product(), std::pair(0, 0)};
160 
161  if (verbosity_)
162  edm::LogInfo("RPDigiProducer") << "Input MixCollection size = " << allRPHits.size() << "\n";
163 
164  //Loop on PSimHit
165  simhit_map simHitMap_;
166  simHitMap_.clear();
167 
169  for (isim = allRPHits.begin(); isim != allRPHits.end(); ++isim) {
170  simHitMap_[(*isim).detUnitId()].push_back((*isim));
171  }
172 
173  // Step B: LOOP on hits in event
174  std::vector<edm::DetSet<TotemRPDigi>> DigiVector;
175  DigiVector.reserve(400);
176  DigiVector.clear();
177 
178  CTPPSRPAlignmentCorrectionsData const* alignments = nullptr;
179  if (auto rec = iSetup.tryToGet<VeryForwardMisalignedGeometryRecord>()) {
180  alignments = &iSetup.getData(alignmentToken);
181  }
182  auto const& geom = iSetup.getData(geomToken);
183 
184  for (simhit_map_iterator it = simHitMap_.begin(); it != simHitMap_.end(); ++it) {
185  edm::DetSet<TotemRPDigi> digi_collector(it->first);
186 
187  if (theAlgoMap.find(it->first) == theAlgoMap.end()) {
188  theAlgoMap[it->first] = std::make_unique<RPDetDigitizer>(conf_, *rndEngine_, it->first, alignments, geom);
189  }
190 
191  std::vector<int> input_links;
192  simromanpot::DigiPrimaryMapType output_digi_links;
193 
194  (theAlgoMap.find(it->first)->second)
195  ->run(simHitMap_[it->first], input_links, digi_collector.data, output_digi_links);
196 
197  if (!digi_collector.data.empty()) {
198  DigiVector.push_back(convertRPStripDetSet(digi_collector));
199  }
200  }
201 
202  // Step C: create empty output collection
203  std::unique_ptr<edm::DetSetVector<TotemRPDigi>> digi_output(new edm::DetSetVector<TotemRPDigi>(DigiVector));
204 
205  if (verbosity_) {
206  edm::LogInfo("RPDigiProducer") << "digi_output->size()=" << digi_output->size() << "\n";
207  }
208  // Step D: write output to file
209  iEvent.put(std::move(digi_output));
210 }
211 
212 // ------------ method called once each job just before starting event loop ------------
213 void RPDigiProducer::beginRun(const edm::Run& beginrun, const edm::EventSetup& es) {
214  // get analysis mask to mask channels
215  if (simulateDeadChannels) {
216  //set analysisMask in deadChannelsManager
218  }
219 }
220 
222  edm::DetSet<TotemRPDigi> rpdigi_detset(rpstrip_detset.detId());
223  rpdigi_detset.reserve(rpstrip_detset.size());
224 
225  for (std::vector<TotemRPDigi>::const_iterator stripIterator = rpstrip_detset.data.begin();
226  stripIterator < rpstrip_detset.data.end();
227  ++stripIterator) {
228  rpdigi_detset.push_back(TotemRPDigi(stripIterator->stripNumber()));
229  }
230 
231  return rpdigi_detset;
232 }
233 
235  //RPSiDetDigitizer
236  //all distances in [mm]
238  desc.add<bool>("RPLandauFluctuations", true);
239  desc.add<bool>("RPDisplacementOn", false);
240  desc.add<int>("RPVerbosity", 0);
241  desc.add<double>("RPVFATThreshold", 9000.0);
242  desc.add<double>("RPTopEdgePosition", 1.5);
243  desc.add<double>("RPActiveEdgeSmearing", 0.013);
244  desc.add<double>("RPEquivalentNoiseCharge300um", 1000.0);
245  desc.add<int>("RPVFATTriggerMode", 2);
246  desc.add<std::vector<double>>("RPInterStripSmearing",
247  {
248  0.011,
249  });
250  desc.add<double>("RPSharingSigmas", 5.0); //how many sigmas taken into account for the edges and inter strips
251  desc.add<double>("RPGeVPerElectron", 3.61e-09);
252  desc.add<double>("RPActiveEdgePosition", 0.034); //from the physical edge
253  desc.add<bool>("RPDeadStripSimulationOn", false);
254  desc.add<std::vector<std::string>>("ROUList",
255  {
256  "TotemHitsRP",
257  });
258  desc.add<bool>("RPNoNoise", false);
259  desc.add<bool>("RPDigiSimHitRelationsPresistence", false); //save links betweend digi, clusters and OSCAR/Geant4 hits
260  desc.add<std::string>("mixLabel", "mix");
261  desc.add<int>("RPChargeDivisionsPerThickness", 5);
262  desc.add<double>("RPDeltaProductionCut", 0.120425); //[MeV]
263  desc.add<double>("RPBottomEdgePosition", 1.5);
264  desc.add<double>("RPBottomEdgeSmearing", 0.011);
265  desc.add<double>("RPTopEdgeSmearing", 0.011);
266  desc.add<std::string>("InputCollection", "g4SimHitsTotemHitsRP");
267  desc.add<double>("RPInterStripCoupling",
268  1.0); //fraction of charge going to the strip, the missing part is taken by its neighbours
269  desc.add<double>("RPDeadStripProbability", 0.001);
270  desc.add<int>("RPChargeDivisionsPerStrip", 15);
271  descriptions.add("RPSiDetDigitizer", desc);
272 }
273 
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
edm::ESGetToken< CTPPSRPAlignmentCorrectionsData, VeryForwardMisalignedGeometryRecord > alignmentToken
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
std::map< unsigned int, std::vector< PSimHit > > simhit_map
edm::ESGetToken< CTPPSGeometry, VeryForwardRealGeometryRecord > geomToken
edm::DetSet< TotemRPDigi > convertRPStripDetSet(const edm::DetSet< TotemRPDigi > &)
bool exists(std::string const &parameterName) const
checks if a parameter exists
T const * product() const
Definition: Handle.h:70
std::optional< T > tryToGet() const
Definition: EventSetup.h:103
simhit_map::iterator simhit_map_iterator
std::vector< std::vector< std::pair< int, double > > > DigiPrimaryMapType
Definition: RPSimTypes.h:22
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &)=0
Use this engine in event methods.
det_id_type detId() const
Definition: DetSet.h:74
edm::ESGetToken< TotemAnalysisMask, TotemReadoutRcd > tokenAnalysisMask
void reserve(size_t s)
Definition: DetSet.h:65
int iEvent
Definition: GenABIO.cc:224
edm::ParameterSet conf_
std::map< RPDetId, std::unique_ptr< RPDetDigitizer > > theAlgoMap
~RPDigiProducer() override=default
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
bool getData(T &iHolder) const
Definition: EventSetup.h:122
RPDigiProducer(const edm::ParameterSet &)
edm::EDGetTokenT< CrossingFrame< PSimHit > > tokenCrossingFrameTotemRP
std::vector< std::string > RP_hit_containers_
Log< level::Info, false > LogInfo
bool getTrigger() const
Definition: MixCollection.h:97
void add(std::string const &label, ParameterSetDescription const &psetDescription)
Container for CTPPS RP alignment corrections. The corrections are stored on two levels - RP and senso...
collection_type data
Definition: DetSet.h:80
void produce(edm::Event &, const edm::EventSetup &) override
HLT enums.
Event setup record containing the misaligned geometry information. It is used for alignment studies o...
DeadChannelsManager deadChannelsManager
col
Definition: cuy.py:1009
bool isAvailable() const
Definition: Service.h:40
size_type size() const
Definition: DetSet.h:61
def move(src, dest)
Definition: eostools.py:511
Definition: Run.h:45
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
void beginRun(const edm::Run &, const edm::EventSetup &) override
CLHEP::HepRandomEngine * rndEngine_