Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:11:04

0001 // system includes
0002 #include <cmath>
0003 #include <cstdlib>
0004 #include <ctime>
0005 #include <iostream>
0006 #include <sstream>
0007 #include <string>
0008 #include <vector>
0009 
0010 // user includes
0011 #include "CLHEP/Random/RandFlat.h"
0012 #include "CLHEP/Random/RandGauss.h"
0013 #include "CondFormats/DataRecord/interface/SiStripFedCablingRcd.h"
0014 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
0015 #include "DataFormats/Common/interface/DetSetVector.h"
0016 #include "DataFormats/SiStripCommon/interface/SiStripConstants.h"
0017 #include "DataFormats/SiStripDigi/interface/SiStripDigi.h"
0018 #include "DataFormats/SiStripDigi/interface/SiStripRawDigi.h"
0019 #include "FWCore/Framework/interface/ESHandle.h"
0020 #include "FWCore/Framework/interface/Event.h"
0021 #include "FWCore/Framework/interface/EventSetup.h"
0022 #include "FWCore/Framework/interface/global/EDProducer.h"
0023 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0024 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0025 
0026 /**
0027     @file EventFilter/SiStripRawToDigi/test/plugins/SiStripTrivialDigiSource.h
0028     @class SiStripTrivialDigiSource
0029 
0030     @brief Creates a DetSetVector of SiStripDigis created using random
0031     number generators and attaches the collection to the Event. Allows
0032     to test the final DigiToRaw and RawToDigi converters.  
0033 */
0034 class SiStripTrivialDigiSource : public edm::global::EDProducer<> {
0035 public:
0036   SiStripTrivialDigiSource(const edm::ParameterSet&);
0037   ~SiStripTrivialDigiSource();
0038 
0039   virtual void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
0040 
0041 private:
0042   const edm::ESGetToken<SiStripFedCabling, SiStripFedCablingRcd> esTokenCabling_;
0043   const float meanOcc_;
0044   const float rmsOcc_;
0045   const int ped_;
0046   const bool raw_;
0047   const bool useFedKey_;
0048 };
0049 
0050 // -----------------------------------------------------------------------------
0051 //
0052 SiStripTrivialDigiSource::SiStripTrivialDigiSource(const edm::ParameterSet& pset)
0053     : esTokenCabling_(esConsumes()),
0054       meanOcc_(pset.getUntrackedParameter<double>("MeanOccupancy", 1.)),
0055       rmsOcc_(pset.getUntrackedParameter<double>("RmsOccupancy", 0.1)),
0056       ped_(pset.getUntrackedParameter<int>("PedestalLevel", 100)),
0057       raw_(pset.getUntrackedParameter<bool>("FedRawDataMode", false)),
0058       useFedKey_(pset.getUntrackedParameter<bool>("UseFedKey", false)) {
0059   LogTrace("TrivialDigiSource") << "[SiStripTrivialDigiSource::" << __func__ << "]"
0060                                 << " Constructing object...";
0061   produces<edm::DetSetVector<SiStripDigi>>();
0062 }
0063 
0064 // -----------------------------------------------------------------------------
0065 //
0066 SiStripTrivialDigiSource::~SiStripTrivialDigiSource() {
0067   LogTrace("TrivialDigiSource") << "[SiStripTrivialDigiSource::" << __func__ << "]"
0068                                 << " Destructing object...";
0069 }
0070 
0071 // -----------------------------------------------------------------------------
0072 //
0073 void SiStripTrivialDigiSource::produce(edm::StreamID, edm::Event& event, const edm::EventSetup& setup) const {
0074   LogTrace("TrivialDigiSource") << "[SiStripRawToDigiModule::" << __func__ << "]"
0075                                 << " Analyzing run/event " << event.id().run() << "/" << event.id().event();
0076 
0077   // Retrieve cabling
0078   edm::ESHandle<SiStripFedCabling> cabling = setup.getHandle(esTokenCabling_);
0079 
0080   // Temp container
0081   typedef std::vector<edm::DetSet<SiStripDigi>> digi_work_vector;
0082   digi_work_vector zero_suppr_vector;
0083 
0084   // Some init
0085   uint32_t nchans = 0;
0086   uint32_t ndigis = 0;
0087 
0088   // Retrieve fed ids
0089   auto fed_ids = cabling->fedIds();
0090 
0091   // Iterate through fed ids and channels
0092   for (auto ifed = fed_ids.begin(); ifed != fed_ids.end(); ifed++) {
0093     auto conns = cabling->fedConnections(*ifed);
0094     for (auto iconn = conns.begin(); iconn != conns.end(); iconn++) {
0095       // Build FED key
0096       uint32_t fed_key = ((iconn->fedId() & sistrip::invalid_) << 16) | (iconn->fedCh() & sistrip::invalid_);
0097 
0098       // Determine key (FED key or DetId) to index DSV
0099       uint32_t key = useFedKey_ ? fed_key : iconn->detId();
0100 
0101       // Determine APV pair number
0102       uint16_t ipair = useFedKey_ ? 0 : iconn->apvPairNumber();
0103 
0104       // Check key is non-zero and valid
0105       if (!key || (key == sistrip::invalid32_)) {
0106         continue;
0107       }
0108 
0109       // Random number of digis
0110       double tmp = 0.;
0111       float rdm = 2.56 * CLHEP::RandGauss::shoot(meanOcc_, rmsOcc_);
0112       bool extra = (CLHEP::RandFlat::shoot() > modf(rdm, &tmp));
0113       uint16_t ndigi = static_cast<uint16_t>(rdm) + static_cast<uint16_t>(extra);
0114 
0115       // Create DetSet
0116       if (zero_suppr_vector.empty()) {
0117         zero_suppr_vector.reserve(40000);
0118       }
0119       zero_suppr_vector.push_back(edm::DetSet<SiStripDigi>(key));
0120       edm::DetSet<SiStripDigi>& zs = zero_suppr_vector.back();
0121       zs.data.reserve(768);
0122 
0123       // Remember strips used
0124       std::vector<uint16_t> used_strips;
0125       used_strips.reserve(ndigi);
0126 
0127       // Create digis
0128       uint16_t idigi = 0;
0129       while (idigi < ndigi) {
0130         // Random values
0131         uint16_t str = static_cast<uint16_t>(256. * CLHEP::RandFlat::shoot());
0132         uint16_t adc = static_cast<uint16_t>(256. * CLHEP::RandFlat::shoot());
0133 
0134         // Generate and check strip number
0135         uint16_t nstrips = iconn->nDetStrips();
0136         uint16_t strip = str + 256 * ipair;
0137         if (strip >= nstrips) {
0138           continue;
0139         }
0140 
0141         // Create digi object
0142         std::vector<uint16_t>::iterator iter = find(used_strips.begin(), used_strips.end(), strip);
0143         if (iter == used_strips.end() && adc) {  // require non-zero adc!
0144           uint16_t level = raw_ ? ped_ + adc : adc;
0145           zs.data.push_back(SiStripDigi(strip, level));
0146           used_strips.push_back(strip);
0147           ndigis++;
0148           idigi++;
0149         }
0150       }
0151 
0152       // Populate DetSet with remaining "raw" digis
0153       if (raw_) {
0154         for (uint16_t istr = 256 * ipair; istr < 256 * (ipair + 1); ++istr) {
0155           if (find(used_strips.begin(), used_strips.end(), istr) == used_strips.end()) {
0156             zs.data.push_back(SiStripDigi(istr, ped_));
0157           }
0158         }
0159       }
0160     }
0161   }
0162 
0163   // Create final DetSetVector container
0164   auto collection = std::make_unique<edm::DetSetVector<SiStripDigi>>();
0165 
0166   // Populate final DetSetVector container with ZS data
0167   if (!zero_suppr_vector.empty()) {
0168     std::sort(zero_suppr_vector.begin(), zero_suppr_vector.end());
0169     std::vector<edm::DetSet<SiStripDigi>> sorted_and_merged;
0170     sorted_and_merged.reserve(zero_suppr_vector.size());
0171 
0172     edm::det_id_type old_id = 0;
0173     std::vector<edm::DetSet<SiStripDigi>>::iterator ii = zero_suppr_vector.begin();
0174     std::vector<edm::DetSet<SiStripDigi>>::iterator jj = zero_suppr_vector.end();
0175     for (; ii != jj; ++ii) {
0176       if (old_id == ii->detId()) {
0177         sorted_and_merged.back().data.insert(sorted_and_merged.back().end(), ii->begin(), ii->end());
0178       } else {
0179         sorted_and_merged.push_back(*ii);
0180         old_id = ii->detId();
0181       }
0182     }
0183 
0184     std::vector<edm::DetSet<SiStripDigi>>::iterator iii = sorted_and_merged.begin();
0185     std::vector<edm::DetSet<SiStripDigi>>::iterator jjj = sorted_and_merged.end();
0186     for (; iii != jjj; ++iii) {
0187       std::sort(iii->begin(), iii->end());
0188     }
0189 
0190     edm::DetSetVector<SiStripDigi> zero_suppr_dsv(sorted_and_merged, true);
0191     collection->swap(zero_suppr_dsv);
0192   }
0193 
0194   // Put collection in event
0195   event.put(std::move(collection));
0196 
0197   // Some debug
0198   if (edm::isDebugEnabled() && nchans) {
0199     std::stringstream ss;
0200     ss << "[SiStripTrivialDigiSource::" << __func__ << "]"
0201        << " Generated " << ndigis << " digis for " << nchans << " channels with a mean occupancy of " << std::dec
0202        << std::setprecision(2) << (1. / 2.56) * (float)ndigis / (float)nchans << " %";
0203     LogTrace("TrivialDigiSource") << ss.str();
0204   }
0205 }
0206 
0207 #include "FWCore/PluginManager/interface/ModuleDef.h"
0208 #include "FWCore/Framework/interface/MakerMacros.h"
0209 DEFINE_FWK_MODULE(SiStripTrivialDigiSource);