Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-01-07 23:36:47

0001 #ifndef SimMuon_GEMDigitizer_ME0DigiProducer_h
0002 #define SimMuon_GEMDigitizer_ME0DigiProducer_h
0003 
0004 #include "FWCore/Framework/interface/stream/EDProducer.h"
0005 #include "FWCore/Framework/interface/MakerMacros.h"
0006 #include "FWCore/Framework/interface/ESHandle.h"
0007 #include "FWCore/Utilities/interface/ESGetToken.h"
0008 #include "FWCore/Framework/interface/Event.h"
0009 #include "FWCore/Framework/interface/EventSetup.h"
0010 #include "FWCore/Framework/interface/ConsumesCollector.h"
0011 #include "FWCore/ServiceRegistry/interface/Service.h"
0012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0013 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0014 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
0015 #include "FWCore/Utilities/interface/Exception.h"
0016 
0017 #include "DataFormats/Common/interface/Handle.h"
0018 #include "DataFormats/Common/interface/DetSetVector.h"
0019 #include "SimDataFormats/CrossingFrame/interface/CrossingFrame.h"
0020 #include "SimDataFormats/CrossingFrame/interface/MixCollection.h"
0021 #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h"
0022 #include "SimDataFormats/GEMDigiSimLink/interface/ME0DigiSimLink.h"
0023 
0024 #include "SimMuon/GEMDigitizer/interface/ME0DigiModelFactory.h"
0025 #include "SimMuon/GEMDigitizer/interface/ME0DigiModel.h"
0026 
0027 #include "Geometry/Records/interface/MuonGeometryRecord.h"
0028 #include "Geometry/GEMGeometry/interface/ME0Geometry.h"
0029 
0030 #include <sstream>
0031 #include <string>
0032 #include <map>
0033 #include <vector>
0034 
0035 namespace CLHEP {
0036   class HepRandomEngine;
0037 }
0038 
0039 class ME0DigiProducer : public edm::stream::EDProducer<> {
0040 public:
0041   typedef edm::DetSetVector<ME0DigiSimLink> ME0DigiSimLinks;
0042 
0043   explicit ME0DigiProducer(const edm::ParameterSet& ps);
0044 
0045   ~ME0DigiProducer() override;
0046 
0047   void beginRun(const edm::Run&, const edm::EventSetup&) override;
0048 
0049   void produce(edm::Event&, const edm::EventSetup&) override;
0050 
0051 private:
0052   //Name of Collection used for create the XF
0053   edm::EDGetTokenT<CrossingFrame<PSimHit> > cf_token;
0054   edm::ESGetToken<ME0Geometry, MuonGeometryRecord> geom_token_;
0055 
0056   std::unique_ptr<ME0DigiModel> ME0DigiModel_;
0057 };
0058 
0059 ME0DigiProducer::ME0DigiProducer(const edm::ParameterSet& ps)
0060     : ME0DigiModel_{
0061           ME0DigiModelFactory::get()->create("ME0" + ps.getParameter<std::string>("digiModelString") + "Model", ps)} {
0062   produces<ME0DigiCollection>();
0063   produces<ME0DigiSimLinks>("ME0");
0064 
0065   edm::Service<edm::RandomNumberGenerator> rng;
0066   if (!rng.isAvailable()) {
0067     throw cms::Exception("Configuration")
0068         << "ME0DigiProducer::ME0DigiProducer() - RandomNumberGeneratorService is not present in configuration file.\n"
0069         << "Add the service in the configuration file or remove the modules that require it.";
0070   }
0071 
0072   LogDebug("ME0DigiProducer") << "Using ME0" + ps.getParameter<std::string>("digiModelString") + "Model";
0073 
0074   std::string mix_(ps.getParameter<std::string>("mixLabel"));
0075   std::string collection_(ps.getParameter<std::string>("inputCollection"));
0076 
0077   cf_token = consumes<CrossingFrame<PSimHit> >(edm::InputTag(mix_, collection_));
0078   geom_token_ = esConsumes<ME0Geometry, MuonGeometryRecord, edm::Transition::BeginRun>();
0079 }
0080 
0081 ME0DigiProducer::~ME0DigiProducer() = default;
0082 
0083 void ME0DigiProducer::beginRun(const edm::Run&, const edm::EventSetup& eventSetup) {
0084   edm::ESHandle<ME0Geometry> hGeom = eventSetup.getHandle(geom_token_);
0085   ME0DigiModel_->setGeometry(&*hGeom);
0086   ME0DigiModel_->setup();
0087 }
0088 
0089 void ME0DigiProducer::produce(edm::Event& e, const edm::EventSetup& eventSetup) {
0090   edm::Service<edm::RandomNumberGenerator> rng;
0091   CLHEP::HepRandomEngine* engine = &rng->getEngine(e.streamID());
0092 
0093   edm::Handle<CrossingFrame<PSimHit> > cf;
0094   e.getByToken(cf_token, cf);
0095 
0096   MixCollection<PSimHit> hits{cf.product()};
0097 
0098   // Create empty output
0099   auto digis = std::make_unique<ME0DigiCollection>();
0100   auto me0DigiSimLinks = std::make_unique<ME0DigiSimLinks>();
0101 
0102   // arrange the hits by eta partition
0103   std::map<uint32_t, edm::PSimHitContainer> hitMap;
0104   for (const auto& hit : hits) {
0105     hitMap[hit.detUnitId()].emplace_back(hit);
0106   }
0107 
0108   // simulate signal and noise for each eta partition
0109   const auto& etaPartitions(ME0DigiModel_->getGeometry()->etaPartitions());
0110 
0111   for (const auto& roll : etaPartitions) {
0112     const ME0DetId detId(roll->id());
0113     const uint32_t rawId(detId.rawId());
0114     const auto& simHits(hitMap[rawId]);
0115 
0116     LogDebug("ME0DigiProducer") << "ME0DigiProducer: found " << simHits.size() << " hit(s) in eta partition" << rawId;
0117 
0118     ME0DigiModel_->simulateSignal(roll, simHits, engine);
0119     ME0DigiModel_->simulateNoise(roll, engine);
0120     ME0DigiModel_->fillDigis(rawId, *digis);
0121     (*me0DigiSimLinks).insert(ME0DigiModel_->me0DigiSimLinks());
0122   }
0123 
0124   // store them in the event
0125   e.put(std::move(digis));
0126   e.put(std::move(me0DigiSimLinks), "ME0");
0127 }
0128 
0129 DEFINE_FWK_MODULE(ME0DigiProducer);
0130 #endif