Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-06-10 02:54:29

0001 #ifndef CaloSimAlgos_CaloTDigitizer_h
0002 #define CaloSimAlgos_CaloTDigitizer_h
0003 
0004 /** Turns hits into digis.  Assumes that
0005     there's an ElectroncsSim class with the
0006     interface analogToDigital(CLHEP::HepRandomEngine*, const CaloSamples &, Digi
0007    &);
0008 
0009 */
0010 #include "SimCalorimetry/CaloSimAlgos/interface/CaloHitResponse.h"
0011 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVNoiseSignalGenerator.h"
0012 #include "SimDataFormats/CaloHit/interface/PCaloHit.h"
0013 #include "SimDataFormats/CrossingFrame/interface/MixCollection.h"
0014 #include <cassert>
0015 #include <vector>
0016 
0017 namespace CLHEP {
0018   class HepRandomEngine;
0019 }
0020 
0021 template <class Traits>
0022 class CaloTDigitizerDefaultRun {
0023 public:
0024   typedef typename Traits::ElectronicsSim ElectronicsSim;
0025   typedef typename Traits::Digi Digi;
0026   typedef typename Traits::DigiCollection DigiCollection;
0027 
0028   void operator()(DigiCollection &output,
0029                   CLHEP::HepRandomEngine *engine,
0030                   CaloSamples *analogSignal,
0031                   std::vector<DetId>::const_iterator idItr,
0032                   ElectronicsSim *theElectronicsSim) {
0033     Digi digi(*idItr);
0034     theElectronicsSim->analogToDigital(engine, *analogSignal, digi);
0035     output.push_back(std::move(digi));
0036   }
0037 };
0038 
0039 // second parameter changes the operation of run() slightly (default value for
0040 // old-style with edm::SortedCollection instead of edm::DataFrameContainer)
0041 template <class Traits, template <class> class runHelper = CaloTDigitizerDefaultRun>
0042 class CaloTDigitizer {
0043 public:
0044   /// these are the types that need to be defined in the Traits
0045   /// class.  The ElectronicsSim needs to have an interface
0046   /// that you'll see in the run() method
0047   typedef typename Traits::ElectronicsSim ElectronicsSim;
0048   typedef typename Traits::Digi Digi;
0049   typedef typename Traits::DigiCollection DigiCollection;
0050 
0051   CaloTDigitizer(CaloHitResponse *hitResponse, ElectronicsSim *electronicsSim, bool addNoise)
0052       : theHitResponse(hitResponse),
0053         theNoiseSignalGenerator(nullptr),
0054         theElectronicsSim(electronicsSim),
0055         theDetIds(nullptr),
0056         addNoise_(addNoise),
0057         debugCS_(false) {}
0058 
0059   /// doesn't delete the pointers passed in
0060   ~CaloTDigitizer() {}
0061 
0062   /// tell the digitizer which cells exist
0063   const std::vector<DetId> &detIds() const {
0064     assert(nullptr != theDetIds);
0065     return *theDetIds;
0066   }
0067   void setDetIds(const std::vector<DetId> &detIds) { theDetIds = &detIds; }
0068 
0069   void setNoiseSignalGenerator(CaloVNoiseSignalGenerator *generator) { theNoiseSignalGenerator = generator; }
0070 
0071   void setDebugCaloSamples(bool debug) { debugCS_ = debug; }
0072 
0073   const CaloSamplesCollection &getCaloSamples() const { return csColl_; }
0074 
0075   void add(const std::vector<PCaloHit> &hits, int bunchCrossing, CLHEP::HepRandomEngine *engine) {
0076     if (theHitResponse->withinBunchRange(bunchCrossing)) {
0077       for (std::vector<PCaloHit>::const_iterator it = hits.begin(), itEnd = hits.end(); it != itEnd; ++it) {
0078         theHitResponse->add(*it, engine);
0079       }
0080     }
0081   }
0082 
0083   void initializeHits() { theHitResponse->initializeHits(); }
0084 
0085   /// turns hits into digis
0086   void run(MixCollection<PCaloHit> &, DigiCollection &) { assert(0); }
0087 
0088   /// Collects the digis
0089 
0090   void run(DigiCollection &output, CLHEP::HepRandomEngine *engine) {
0091     assert(!theDetIds->empty());
0092 
0093     if (theNoiseSignalGenerator != nullptr)
0094       addNoiseSignals(engine);
0095 
0096     theHitResponse->finalizeHits(engine);
0097     // std::cout << " In CaloTDigitizer, after finalize hits " << std::endl;
0098 
0099     theElectronicsSim->newEvent(engine);
0100 
0101     // reserve space for how many digis we expect
0102     int nDigisExpected = addNoise_ ? theDetIds->size() : theHitResponse->nSignals();
0103     output.reserve(nDigisExpected);
0104     if (debugCS_) {
0105       csColl_.clear();
0106       csColl_.reserve(nDigisExpected);
0107       theHitResponse->setStorePrecise(true);
0108     }
0109 
0110     // make a raw digi for evey cell
0111     for (std::vector<DetId>::const_iterator idItr = theDetIds->begin(); idItr != theDetIds->end(); ++idItr) {
0112       CaloSamples *analogSignal = theHitResponse->findSignal(*idItr);
0113       if (analogSignal && debugCS_)
0114         csColl_.push_back(*analogSignal);
0115       bool needToDeleteSignal = false;
0116       // don't bother digitizing if no signal and no noise
0117       if (analogSignal == nullptr && addNoise_) {
0118         // I guess we need to make a blank signal for this cell.
0119         // Don't bother storing it anywhere.
0120         analogSignal = new CaloSamples(theHitResponse->makeBlankSignal(*idItr));
0121         needToDeleteSignal = true;
0122       }
0123       if (analogSignal != nullptr) {
0124         runAnalogToDigital(output, engine, analogSignal, idItr, theElectronicsSim);
0125         if (needToDeleteSignal)
0126           delete analogSignal;
0127       }
0128     }
0129 
0130     // free up some memory
0131     theHitResponse->clear();
0132   }
0133 
0134   void addNoiseSignals(CLHEP::HepRandomEngine *engine) {
0135     std::vector<CaloSamples> noiseSignals;
0136     // noise signals need to be in units of photoelectrons.  Fractional is OK
0137     theNoiseSignalGenerator->fillEvent(engine);
0138     theNoiseSignalGenerator->getNoiseSignals(noiseSignals);
0139     for (std::vector<CaloSamples>::const_iterator signalItr = noiseSignals.begin(), signalEnd = noiseSignals.end();
0140          signalItr != signalEnd;
0141          ++signalItr) {
0142       theHitResponse->add(*signalItr);
0143     }
0144   }
0145 
0146 private:
0147   runHelper<Traits> runAnalogToDigital;
0148   CaloHitResponse *theHitResponse;
0149   CaloVNoiseSignalGenerator *theNoiseSignalGenerator;
0150   ElectronicsSim *theElectronicsSim;
0151   const std::vector<DetId> *theDetIds;
0152   bool addNoise_;
0153   bool debugCS_;
0154   CaloSamplesCollection csColl_;
0155 };
0156 
0157 #endif