Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:29:31

0001 #ifndef HcalSimAlgos_HcalSignalGenerator_h
0002 #define HcalSimAlgos_HcalSignalGenerator_h
0003 
0004 #include "SimCalorimetry/HcalSimAlgos/interface/HcalBaseSignalGenerator.h"
0005 #include "FWCore/Framework/interface/EventSetup.h"
0006 #include "FWCore/Framework/interface/Event.h"
0007 #include "FWCore/Framework/interface/EventPrincipal.h"
0008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0009 #include "CalibFormats/HcalObjects/interface/HcalCoderDb.h"
0010 #include "CalibFormats/HcalObjects/interface/HcalCalibrations.h"
0011 #include "CalibFormats/HcalObjects/interface/HcalDbService.h"
0012 #include "CalibFormats/HcalObjects/interface/HcalDbRecord.h"
0013 #include "SimCalorimetry/HcalSimAlgos/interface/HcalElectronicsSim.h"
0014 #include "SimCalorimetry/HcalSimAlgos/interface/HcalDigitizerTraits.h"
0015 #include "SimCalorimetry/HcalSimAlgos/interface/HcalQIE1011Traits.h"
0016 #include "DataFormats/Common/interface/Handle.h"
0017 #include "DataFormats/HcalDetId/interface/HcalSubdetector.h"
0018 
0019 /** Converts digis back into analog signals, to be used
0020  *  as noise 
0021  */
0022 
0023 #include <iostream>
0024 
0025 namespace edm {
0026   class ModuleCallingContext;
0027 }
0028 
0029 template <class Traits>
0030 class HcalSignalGenerator : public HcalBaseSignalGenerator {
0031 public:
0032   typedef typename Traits::Digi DIGI;
0033   typedef typename Traits::DigiCollection COLLECTION;
0034 
0035   HcalSignalGenerator() : HcalBaseSignalGenerator() {}
0036 
0037   HcalSignalGenerator(const edm::InputTag& inputTag, const edm::EDGetTokenT<COLLECTION>& t)
0038       : HcalBaseSignalGenerator(), theEvent(nullptr), theEventPrincipal(nullptr), theInputTag(inputTag), tok_(t) {}
0039 
0040   ~HcalSignalGenerator() override {}
0041 
0042   void initializeEvent(const edm::Event* event,
0043                        const edm::EventSetup* eventSetup,
0044                        const edm::ESGetToken<HcalDbService, HcalDbRecord>& tok) {
0045     theEvent = event;
0046     theConditions = &(eventSetup->getData(tok));
0047     theParameterMap->setDbService(theConditions);
0048   }
0049 
0050   /// some users use EventPrincipals, not Events.  We support both
0051   void initializeEvent(const edm::EventPrincipal* eventPrincipal,
0052                        const edm::EventSetup* eventSetup,
0053                        const edm::ESGetToken<HcalDbService, HcalDbRecord>& tok) {
0054     theEventPrincipal = eventPrincipal;
0055     theConditions = &(eventSetup->getData(tok));
0056     theParameterMap->setDbService(theConditions);
0057   }
0058 
0059   virtual void fill(edm::ModuleCallingContext const* mcc) {
0060     theNoiseSignals.clear();
0061     edm::Handle<COLLECTION> pDigis;
0062     const COLLECTION* digis = nullptr;
0063     // try accessing by whatever is set, Event or EventPrincipal
0064     if (theEvent) {
0065       if (theEvent->getByToken(tok_, pDigis)) {
0066         digis = pDigis.product();  // get a ptr to the product
0067         LogTrace("HcalSignalGenerator") << "total # digis  for " << theInputTag << " " << digis->size();
0068       } else {
0069         throw cms::Exception("HcalSignalGenerator") << "Cannot find input data " << theInputTag;
0070       }
0071     } else if (theEventPrincipal) {
0072       std::shared_ptr<edm::Wrapper<COLLECTION> const> digisPTR =
0073           edm::getProductByTag<COLLECTION>(*theEventPrincipal, theInputTag, mcc);
0074       if (digisPTR) {
0075         digis = digisPTR->product();
0076       }
0077     } else {
0078       throw cms::Exception("HcalSignalGenerator") << "No Event or EventPrincipal was set";
0079     }
0080 
0081     if (digis)
0082       fillDigis(digis);
0083   }
0084 
0085 private:
0086   virtual void fillDigis(const COLLECTION* digis) {
0087     // loop over digis, adding these to the existing maps
0088     for (typename COLLECTION::const_iterator it = digis->begin(); it != digis->end(); ++it) {
0089       // for the first signal, set the starting cap id
0090       if ((it == digis->begin()) && theElectronicsSim) {
0091         int startingCapId = (*it)[0].capid();
0092         theElectronicsSim->setStartingCapId(startingCapId);
0093         // theParameterMap->setFrameSize(it->id(), it->size()); //don't need this
0094       }
0095       if (validDigi(*it)) {
0096         theNoiseSignals.push_back(samplesInPE(*it));
0097       }
0098     }
0099   }
0100 
0101   void fillNoiseSignals(CLHEP::HepRandomEngine*) override {}
0102   void fillNoiseSignals() override {}
0103 
0104   bool validDigi(const DIGI& digi) {
0105     int DigiSum = 0;
0106     for (int id = 0; id < digi.size(); id++) {
0107       if (digi[id].adc() > 0)
0108         ++DigiSum;
0109     }
0110     return (DigiSum > 0);
0111   }
0112 
0113   CaloSamples samplesInPE(const DIGI& digi) {
0114     // For PreMixing, (Note that modifications will need to be made for DataMixing) the
0115     // energy for each channel is kept as fC*10, but stored as an integer in ADC.  If this
0116     // results in an overflow, the "standard" ADC conversion is used and that channel is marked
0117     // with an error that allows the "standard" decoding to convert ADC back to fC.  So, most
0118     // channels get to fC by just dividing ADC/10; some require special treatment.
0119 
0120     // calibration, for future reference:  (same block for all Hcal types)
0121     HcalDetId cell = digi.id();
0122     CaloSamples result = CaloSamples(cell, digi.size());
0123 
0124     // first, check if there was an overflow in this fake digi:
0125     bool overflow = false;
0126     // find and list them
0127 
0128     for (int isample = 0; isample < digi.size(); ++isample) {
0129       if (digi[isample].er())
0130         overflow = true;
0131     }
0132 
0133     if (overflow) {  // do full conversion, go back and overwrite fake entries
0134 
0135       const HcalQIECoder* channelCoder = theConditions->getHcalCoder(cell);
0136       const HcalQIEShape* channelShape = theConditions->getHcalShape(cell);
0137       HcalCoderDb coder(*channelCoder, *channelShape);
0138       coder.adc2fC(digi, result);
0139 
0140       // overwrite with coded information
0141       for (int isample = 0; isample < digi.size(); ++isample) {
0142         if (!digi[isample].er())
0143           result[isample] = float(digi[isample].adc()) / Traits::PreMixFactor;
0144       }
0145     } else {  // saves creating the coder, etc., every time
0146       // use coded information
0147       for (int isample = 0; isample < digi.size(); ++isample) {
0148         result[isample] = float(digi[isample].adc()) / Traits::PreMixFactor;
0149       }
0150       result.setPresamples(digi.presamples());
0151     }
0152 
0153     // translation done in fC, convert to pe:
0154     fC2pe(result);
0155 
0156     return result;
0157   }
0158 
0159   /// these fields are set in initializeEvent()
0160   const edm::Event* theEvent;
0161   const edm::EventPrincipal* theEventPrincipal;
0162   const HcalDbService* theConditions;
0163   /// these come from the ParameterSet
0164   edm::InputTag theInputTag;
0165   edm::EDGetTokenT<COLLECTION> tok_;
0166 };
0167 
0168 //forward declarations of specializations
0169 template <>
0170 bool HcalSignalGenerator<HcalQIE10DigitizerTraits>::validDigi(
0171     const HcalSignalGenerator<HcalQIE10DigitizerTraits>::DIGI& digi);
0172 template <>
0173 CaloSamples HcalSignalGenerator<HcalQIE10DigitizerTraits>::samplesInPE(
0174     const HcalSignalGenerator<HcalQIE10DigitizerTraits>::DIGI& digi);
0175 template <>
0176 void HcalSignalGenerator<HcalQIE10DigitizerTraits>::fillDigis(
0177     const HcalSignalGenerator<HcalQIE10DigitizerTraits>::COLLECTION* digis);
0178 template <>
0179 bool HcalSignalGenerator<HcalQIE11DigitizerTraits>::validDigi(
0180     const HcalSignalGenerator<HcalQIE11DigitizerTraits>::DIGI& digi);
0181 template <>
0182 CaloSamples HcalSignalGenerator<HcalQIE11DigitizerTraits>::samplesInPE(
0183     const HcalSignalGenerator<HcalQIE11DigitizerTraits>::DIGI& digi);
0184 template <>
0185 void HcalSignalGenerator<HcalQIE11DigitizerTraits>::fillDigis(
0186     const HcalSignalGenerator<HcalQIE11DigitizerTraits>::COLLECTION* digis);
0187 
0188 typedef HcalSignalGenerator<HBHEDigitizerTraits> HBHESignalGenerator;
0189 typedef HcalSignalGenerator<HODigitizerTraits> HOSignalGenerator;
0190 typedef HcalSignalGenerator<HFDigitizerTraits> HFSignalGenerator;
0191 typedef HcalSignalGenerator<ZDCDigitizerTraits> ZDCSignalGenerator;
0192 typedef HcalSignalGenerator<HcalQIE10DigitizerTraits> QIE10SignalGenerator;
0193 typedef HcalSignalGenerator<HcalQIE11DigitizerTraits> QIE11SignalGenerator;
0194 
0195 #endif