Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-12-01 03:53:51

0001 #include "FWCore/Framework/interface/stream/EDProducer.h"
0002 #include "FWCore/Framework/interface/MakerMacros.h"
0003 #include "FWCore/Framework/interface/ESHandle.h"
0004 #include "FWCore/Framework/interface/Event.h"
0005 #include "FWCore/Framework/interface/EventSetup.h"
0006 #include "FWCore/Utilities/interface/Exception.h"
0007 #include "FWCore/Utilities/interface/InputTag.h"
0008 #include "FWCore/Utilities/interface/ESGetToken.h"
0009 #include "FWCore/Framework/interface/ConsumesCollector.h"
0010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0012 
0013 #include "DataFormats/Common/interface/Handle.h"
0014 #include "DataFormats/GEMDigi/interface/GEMDigiCollection.h"
0015 #include "DataFormats/GEMDigi/interface/GEMPadDigiCollection.h"
0016 
0017 #include "Geometry/Records/interface/MuonGeometryRecord.h"
0018 #include "Geometry/GEMGeometry/interface/GEMGeometry.h"
0019 
0020 #include <set>
0021 
0022 /*
0023   \class GEMPadDigiProducer
0024   producer for GEM trigger pads
0025 
0026   In GE1/1: trigger pads are made from neighboring strip digis
0027   in the same eta partition
0028 
0029   In GE2/1: trigger pads are made from neighboring strip digis
0030   in neighboring eta partitions
0031 */
0032 
0033 class GEMPadDigiProducer : public edm::stream::EDProducer<> {
0034 public:
0035   explicit GEMPadDigiProducer(const edm::ParameterSet& ps);
0036 
0037   ~GEMPadDigiProducer() override;
0038 
0039   void beginRun(const edm::Run&, const edm::EventSetup&) override;
0040 
0041   void produce(edm::Event&, const edm::EventSetup&) override;
0042 
0043   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0044 
0045 private:
0046   void buildPads(const GEMDigiCollection& digis, GEMPadDigiCollection& out_pads) const;
0047   void buildPads16GE21(const GEMDigiCollection& digis, GEMPadDigiCollection& out_pads) const;
0048   void checkValid(const GEMPadDigi& pad, const GEMDetId& id) const;
0049   void checkGeometry() const;
0050 
0051   /// Name of input digi Collection
0052   edm::EDGetTokenT<GEMDigiCollection> digi_token_;
0053   edm::ESGetToken<GEMGeometry, MuonGeometryRecord> geom_token_;
0054   edm::InputTag digis_;
0055   bool use16GE21_;
0056 
0057   const GEMGeometry* geometry_;
0058 };
0059 
0060 GEMPadDigiProducer::GEMPadDigiProducer(const edm::ParameterSet& ps) : use16GE21_(false), geometry_(nullptr) {
0061   digis_ = ps.getParameter<edm::InputTag>("InputCollection");
0062 
0063   digi_token_ = consumes<GEMDigiCollection>(digis_);
0064   geom_token_ = esConsumes<GEMGeometry, MuonGeometryRecord, edm::Transition::BeginRun>();
0065 
0066   produces<GEMPadDigiCollection>();
0067   consumes<GEMDigiCollection>(digis_);
0068 }
0069 
0070 GEMPadDigiProducer::~GEMPadDigiProducer() {}
0071 
0072 void GEMPadDigiProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0073   edm::ParameterSetDescription desc;
0074   desc.add<edm::InputTag>("InputCollection", edm::InputTag("simMuonGEMDigis"));
0075 
0076   descriptions.add("simMuonGEMPadDigisDef", desc);
0077 }
0078 
0079 void GEMPadDigiProducer::beginRun(const edm::Run& run, const edm::EventSetup& eventSetup) {
0080   edm::ESHandle<GEMGeometry> hGeom = eventSetup.getHandle(geom_token_);
0081   geometry_ = &*hGeom;
0082   // check the number of parititions
0083   if (geometry_->hasGE21()) {
0084     use16GE21_ = (geometry_->chamber(GEMDetId(1, 1, 2, 1, 1, 0))->nEtaPartitions() ==
0085                   GEMPadDigi::NumberPartitions::GE21SplitStrip);
0086   }
0087 
0088   checkGeometry();
0089 }
0090 
0091 void GEMPadDigiProducer::produce(edm::Event& e, const edm::EventSetup& eventSetup) {
0092   edm::Handle<GEMDigiCollection> hdigis;
0093   e.getByToken(digi_token_, hdigis);
0094 
0095   // Create empty output
0096   std::unique_ptr<GEMPadDigiCollection> pPads(new GEMPadDigiCollection());
0097 
0098   // build the pads
0099   buildPads(*(hdigis.product()), *pPads);
0100   if (use16GE21_)
0101     buildPads16GE21(*(hdigis.product()), *pPads);
0102 
0103   // store them in the event
0104   e.put(std::move(pPads));
0105 }
0106 
0107 void GEMPadDigiProducer::buildPads(const GEMDigiCollection& det_digis, GEMPadDigiCollection& out_pads) const {
0108   for (const auto& p : geometry_->etaPartitions()) {
0109     // when using the GE2/1 geometry with 16 eta partitions
0110     // ->ignore GE2/1
0111     if (use16GE21_ and p->isGE21())
0112       continue;
0113 
0114     // set of <pad, bx, part> pairs, sorted first by pad then by bx
0115     std::set<std::tuple<int, int, unsigned> > proto_pads;
0116 
0117     // walk over digis in this partition,
0118     // and stuff them into a set of unique pads (equivalent of OR operation)
0119     auto digis = det_digis.get(p->id());
0120     for (auto d = digis.first; d != digis.second; ++d) {
0121       unsigned pad_num = static_cast<unsigned>(p->padOfStrip(d->strip()));
0122 
0123       auto nPart = GEMPadDigi::NumberPartitions::GE11;
0124       if (p->isME0()) {
0125         nPart = GEMPadDigi::NumberPartitions::ME0;
0126       } else if (p->isGE21()) {
0127         nPart = GEMPadDigi::NumberPartitions::GE21;
0128       }
0129       // check that the input digi is valid
0130       if ((p->isGE11() and pad_num == GEMPadDigi::GE11InValid) or
0131           (p->isGE21() and pad_num == GEMPadDigi::GE21InValid) or (p->isME0() and pad_num == GEMPadDigi::ME0InValid)) {
0132         edm::LogWarning("GEMPadDigiProducer") << "Invalid " << pad_num << " from  " << *d << " in " << p->id();
0133       }
0134       proto_pads.emplace(pad_num, d->bx(), nPart);
0135     }
0136 
0137     // fill the output collections
0138     for (const auto& d : proto_pads) {
0139       GEMPadDigi pad_digi(std::get<0>(d), std::get<1>(d), p->subsystem(), std::get<2>(d));
0140       checkValid(pad_digi, p->id());
0141       out_pads.insertDigi(p->id(), pad_digi);
0142     }
0143   }
0144 }
0145 
0146 void GEMPadDigiProducer::buildPads16GE21(const GEMDigiCollection& det_digis, GEMPadDigiCollection& out_pads) const {
0147   for (const auto& p : geometry_->etaPartitions()) {
0148     // when using the GE2/1 geometry with 16 eta partitions
0149     // ->ignore GE1/1
0150     if (!p->isGE21())
0151       continue;
0152 
0153     // ignore eta partition with even numbers
0154     // these are included in the odd numbered pads
0155     if (p->id().roll() % 2 == 0)
0156       continue;
0157 
0158     // set of <pad, bx> pairs, sorted first by pad then by bx
0159     std::set<std::pair<int, int> > proto_pads;
0160 
0161     // walk over digis in the first partition,
0162     // and stuff them into a set of unique pads (equivalent of OR operation)
0163     auto digis = det_digis.get(p->id());
0164 
0165     // proto pads for the odd partitions
0166     for (auto d = digis.first; d != digis.second; ++d) {
0167       proto_pads.emplace(d->strip(), d->bx());
0168     }
0169 
0170     GEMDetId gemId2(
0171         p->id().region(), p->id().ring(), p->id().station(), p->id().layer(), p->id().chamber(), p->id().roll() + 1);
0172     auto digis2 = det_digis.get(gemId2);
0173 
0174     // proto pads for the even partitions
0175     for (auto d = digis2.first; d != digis2.second; ++d) {
0176       proto_pads.emplace(d->strip(), d->bx());
0177     }
0178 
0179     // fill the output collections
0180     for (const auto& d : proto_pads) {
0181       GEMPadDigi pad_digi(d.first, d.second, p->subsystem(), GEMPadDigi::NumberPartitions::GE21SplitStrip);
0182       checkValid(pad_digi, p->id());
0183       out_pads.insertDigi(p->id(), pad_digi);
0184     }
0185   }
0186 }
0187 
0188 void GEMPadDigiProducer::checkValid(const GEMPadDigi& pad, const GEMDetId& id) const {
0189   // check if the pad is valid
0190   // in principle, invalid pads can appear in the CMS raw data
0191   if (!pad.isValid()) {
0192     edm::LogWarning("GEMPadDigiProducer") << "Invalid " << pad << " in " << id;
0193   }
0194 }
0195 
0196 void GEMPadDigiProducer::checkGeometry() const {
0197   // check that ME0 has 8-eta partitions
0198   if (geometry_->hasME0()) {
0199     if (geometry_->chamber(GEMDetId(1, 1, 0, 1, 1, 0))->nEtaPartitions() != GEMPadDigi::NumberPartitions::ME0) {
0200       edm::LogError("GEMPadDigiProducer") << "ME0 geometry appears corrupted";
0201     }
0202   }
0203 
0204   // check that GE1/1 has 8-eta partitions
0205   if (geometry_->hasGE11()) {
0206     if (geometry_->chamber(GEMDetId(1, 1, 1, 1, 1, 0))->nEtaPartitions() != GEMPadDigi::NumberPartitions::GE11) {
0207       edm::LogError("GEMPadDigiProducer") << "GE1/1 geometry appears corrupted";
0208     }
0209   }
0210 
0211   if (geometry_->hasGE21()) {
0212     if (!use16GE21_) {
0213       // check that GE2/1 has 8-eta partitions
0214       if (geometry_->chamber(GEMDetId(1, 1, 2, 1, 1, 0))->nEtaPartitions() != GEMPadDigi::NumberPartitions::GE21) {
0215         edm::LogError("GEMPadDigiProducer") << "GE2/1 geometry (8 partition) appears corrupted";
0216       }
0217     } else {
0218       // check that GE2/1 has 16-eta partitions
0219       if (geometry_->chamber(GEMDetId(1, 1, 2, 1, 1, 0))->nEtaPartitions() !=
0220           GEMPadDigi::NumberPartitions::GE21SplitStrip) {
0221         edm::LogError("GEMPadDigiProducer") << "GE2/1 geometry (16 partition) appears corrupted";
0222       }
0223     }
0224   }
0225 }
0226 
0227 DEFINE_FWK_MODULE(GEMPadDigiProducer);