Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-04-04 01:27:03

0001 // -*- C++ -*-
0002 //
0003 // Package:    SiPixelDigitizer
0004 // Class:      SiPixelDigitizer
0005 //
0006 /**\class SiPixelDigitizer SiPixelDigitizer.cc SimTracker/SiPixelDigitizer/src/SiPixelDigitizer.cc
0007 
0008  Description: <one line class summary>
0009 
0010  Implementation:
0011      <Notes on implementation>
0012 */
0013 //
0014 // Original Author:  Michele Pioppi-INFN perugia
0015 //   Modifications: Freya Blekman - Cornell University
0016 //         Created:  Mon Sep 26 11:08:32 CEST 2005
0017 //
0018 //
0019 
0020 // system include files
0021 #include <memory>
0022 #include <set>
0023 
0024 // user include files
0025 #include "SiPixelDigitizer.h"
0026 #include "SimDataFormats/TrackerDigiSimLink/interface/PixelSimHitExtraInfo.h"
0027 #include "SimDataFormats/TrackerDigiSimLink/interface/PixelSimHitExtraInfoLite.h"
0028 #include "PixelDigiAddTempInfo.h"
0029 #include "SiPixelDigitizerAlgorithm.h"
0030 
0031 #include "SimDataFormats/TrackingHit/interface/PSimHit.h"
0032 #include "DataFormats/Common/interface/Handle.h"
0033 #include "FWCore/Framework/interface/ConsumesCollector.h"
0034 #include "FWCore/Framework/interface/EventSetup.h"
0035 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0036 #include "DataFormats/SiPixelDigi/interface/PixelDigi.h"
0037 #include "SimDataFormats/TrackerDigiSimLink/interface/PixelDigiSimLink.h"
0038 #include "DataFormats/Common/interface/DetSet.h"
0039 #include "DataFormats/Common/interface/DetSetVector.h"
0040 #include "DataFormats/SiPixelDigi/interface/PixelDigi.h"
0041 #include "DataFormats/SiPixelDigi/interface/PixelDigiCollection.h"
0042 #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h"
0043 #include "DataFormats/GeometryVector/interface/LocalPoint.h"
0044 #include "DataFormats/GeometryVector/interface/LocalVector.h"
0045 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
0046 #include "Geometry/CommonDetUnit/interface/PixelGeomDetUnit.h"
0047 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
0048 
0049 #include "Geometry/CommonTopologies/interface/PixelTopology.h"
0050 #include "Geometry/CommonDetUnit/interface/PixelGeomDetType.h"
0051 
0052 // user include files
0053 #include "FWCore/Framework/interface/Frameworkfwd.h"
0054 
0055 #include "FWCore/Framework/interface/Event.h"
0056 #include "FWCore/Framework/interface/MakerMacros.h"
0057 
0058 #include "MagneticField/Engine/interface/MagneticField.h"
0059 
0060 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0061 #include "SimGeneral/MixingModule/interface/PileUpEventPrincipal.h"
0062 #include "DataFormats/SiPixelDetId/interface/PixelFEDChannel.h"
0063 //Random Number
0064 #include "FWCore/AbstractServices/interface/RandomNumberGenerator.h"
0065 #include "FWCore/ServiceRegistry/interface/Service.h"
0066 #include "FWCore/Utilities/interface/StreamID.h"
0067 #include "FWCore/Utilities/interface/Exception.h"
0068 
0069 //
0070 // constants, enums and typedefs
0071 //
0072 
0073 //
0074 // static data member definitions
0075 //
0076 
0077 //
0078 // constructors and destructor
0079 //
0080 //using namespace std;
0081 
0082 namespace cms {
0083   SiPixelDigitizer::SiPixelDigitizer(const edm::ParameterSet& iConfig,
0084                                      edm::ProducesCollector producesCollector,
0085                                      edm::ConsumesCollector& iC)
0086       : firstInitializeEvent_(true),
0087         firstFinalizeEvent_(true),
0088         applyLateReweighting_(
0089             iConfig.exists("applyLateReweighting") ? iConfig.getParameter<bool>("applyLateReweighting") : false),
0090         usePixelExtraLiteFormat_(
0091             iConfig.exists("usePixelExtraLiteFormat") ? iConfig.getParameter<bool>("usePixelExtraLiteFormat") : false),
0092         store_SimHitEntryExitPoints_(iConfig.exists("store_SimHitEntryExitPoints")
0093                                          ? iConfig.getParameter<bool>("store_SimHitEntryExitPoints")
0094                                          : false),
0095         store_SimHitEntryExitPointsLite_(iConfig.exists("store_SimHitEntryExitPointsLite")
0096                                              ? iConfig.getParameter<bool>("store_SimHitEntryExitPointsLite")
0097                                              : false),
0098         _pixeldigialgo(),
0099         hitsProducer(iConfig.getParameter<std::string>("hitsProducer")),
0100         trackerContainers(iConfig.getParameter<std::vector<std::string> >("RoutList")),
0101         pilotBlades(iConfig.exists("enablePilotBlades") ? iConfig.getParameter<bool>("enablePilotBlades") : false),
0102         NumberOfEndcapDisks(iConfig.exists("NumPixelEndcap") ? iConfig.getParameter<int>("NumPixelEndcap") : 2),
0103         tTopoToken_(iC.esConsumes()),
0104         pDDToken_(iC.esConsumes(edm::ESInputTag("", iConfig.getParameter<std::string>("PixGeometryType")))),
0105         pSetupToken_(iC.esConsumes()) {
0106     edm::LogInfo("PixelDigitizer ") << "Enter the Pixel Digitizer";
0107 
0108     edm::LogInfo("PixelDigitizer ") << " applyLateReweighting_ " << applyLateReweighting_;
0109 
0110     const std::string alias("simSiPixelDigis");
0111 
0112     producesCollector.produces<edm::DetSetVector<PixelDigi> >().setBranchAlias(alias);
0113     producesCollector.produces<edm::DetSetVector<PixelDigiSimLink> >().setBranchAlias(alias + "siPixelDigiSimLink");
0114     if (store_SimHitEntryExitPoints_)
0115       producesCollector.produces<edm::DetSetVector<PixelSimHitExtraInfo> >().setBranchAlias(alias +
0116                                                                                             "siPixelExtraSimHit");
0117     if (store_SimHitEntryExitPointsLite_)
0118       producesCollector.produces<edm::DetSetVector<PixelSimHitExtraInfoLite> >().setBranchAlias(
0119           alias + "siPixelExtraSimHitLite");
0120 
0121     for (auto const& trackerContainer : trackerContainers) {
0122       edm::InputTag tag(hitsProducer, trackerContainer);
0123       iC.consumes<std::vector<PSimHit> >(edm::InputTag(hitsProducer, trackerContainer));
0124     }
0125     edm::Service<edm::RandomNumberGenerator> rng;
0126     if (!rng.isAvailable()) {
0127       throw cms::Exception("Configuration")
0128           << "SiPixelDigitizer requires the RandomNumberGeneratorService\n"
0129              "which is not present in the configuration file.  You must add the service\n"
0130              "in the configuration file or remove the modules that require it.";
0131     }
0132 
0133     _pixeldigialgo = std::make_unique<SiPixelDigitizerAlgorithm>(iConfig, iC);
0134     if (NumberOfEndcapDisks != 2)
0135       producesCollector.produces<PixelFEDChannelCollection>();
0136   }
0137 
0138   SiPixelDigitizer::~SiPixelDigitizer() { edm::LogInfo("PixelDigitizer ") << "Destruct the Pixel Digitizer"; }
0139 
0140   //
0141   // member functions
0142   //
0143 
0144   void SiPixelDigitizer::accumulatePixelHits(edm::Handle<std::vector<PSimHit> > hSimHits,
0145                                              size_t globalSimHitIndex,
0146                                              const unsigned int tofBin,
0147                                              edm::EventSetup const& iSetup) {
0148     if (hSimHits.isValid()) {
0149       std::set<unsigned int> detIds;
0150       std::vector<PSimHit> const& simHits = *hSimHits.product();
0151       const TrackerTopology* tTopo = &iSetup.getData(tTopoToken_);
0152       _pixeldigialgo->fillSimHitMaps(simHits, tofBin);
0153       for (std::vector<PSimHit>::const_iterator it = simHits.begin(), itEnd = simHits.end(); it != itEnd;
0154            ++it, ++globalSimHitIndex) {
0155         unsigned int detId = (*it).detUnitId();
0156         if (detIds.insert(detId).second) {
0157           // The insert succeeded, so this detector element has not yet been processed.
0158           assert(detectorUnits[detId]);
0159           if (detectorUnits[detId] &&
0160               detectorUnits[detId]
0161                   ->type()
0162                   .isTrackerPixel()) {  // this test could be avoided and changed into a check of pixdet!=0
0163             std::map<unsigned int, PixelGeomDetUnit const*>::iterator itDet = detectorUnits.find(detId);
0164             if (itDet == detectorUnits.end())
0165               continue;
0166             auto pixdet = itDet->second;
0167             assert(pixdet != nullptr);
0168             //access to magnetic field in global coordinates
0169             GlobalVector bfield = pSetup->inTesla(pixdet->surface().position());
0170             LogDebug("PixelDigitizer ") << "B-field(T) at " << pixdet->surface().position()
0171                                         << "(cm): " << pSetup->inTesla(pixdet->surface().position());
0172             _pixeldigialgo->accumulateSimHits(
0173                 it, itEnd, globalSimHitIndex, tofBin, pixdet, bfield, tTopo, randomEngine_);
0174           }
0175         }
0176       }
0177     }
0178   }
0179 
0180   void SiPixelDigitizer::initializeEvent(edm::Event const& e, edm::EventSetup const& iSetup) {
0181     if (firstInitializeEvent_) {
0182       _pixeldigialgo->init(iSetup);
0183       firstInitializeEvent_ = false;
0184     }
0185 
0186     // Make sure that the first crossing processed starts indexing the sim hits from zero.
0187     // This variable is used so that the sim hits from all crossing frames have sequential
0188     // indices used to create the digi-sim link (if configured to do so) rather than starting
0189     // from zero for each crossing.
0190     crossingSimHitIndexOffset_.clear();
0191 
0192     // Cache random number engine
0193     edm::Service<edm::RandomNumberGenerator> rng;
0194     randomEngine_ = &rng->getEngine(e.streamID());
0195 
0196     _pixeldigialgo->initializeEvent();
0197     pDD = &iSetup.getData(pDDToken_);
0198     pSetup = &iSetup.getData(pSetupToken_);
0199     const TrackerTopology* tTopo = &iSetup.getData(tTopoToken_);
0200 
0201     // FIX THIS! We only need to clear and (re)fill this map when the geometry type IOV changes.  Use ESWatcher to determine this.
0202     if (true) {  // Replace with ESWatcher
0203       detectorUnits.clear();
0204       for (const auto& iu : pDD->detUnits()) {
0205         unsigned int detId = iu->geographicalId().rawId();
0206         if (iu->type().isTrackerPixel()) {
0207           auto pixdet = dynamic_cast<const PixelGeomDetUnit*>(iu);
0208           assert(pixdet != nullptr);
0209           if (iu->subDetector() ==
0210               GeomDetEnumerators::SubDetector::PixelEndcap) {  // true ONLY for the phase 0 pixel deetctor
0211             unsigned int disk = tTopo->layer(detId);           // using the generic layer method
0212             //if using pilot blades, then allowing it for current detector only
0213             if ((disk == 3) && ((!pilotBlades) && (NumberOfEndcapDisks == 2)))
0214               continue;
0215           }
0216           detectorUnits.insert(std::make_pair(detId, pixdet));
0217         }
0218       }
0219     }
0220   }
0221 
0222   void SiPixelDigitizer::accumulate(edm::Event const& iEvent, edm::EventSetup const& iSetup) {
0223     // Step A: Get Inputs
0224     for (vstring::const_iterator i = trackerContainers.begin(), iEnd = trackerContainers.end(); i != iEnd; ++i) {
0225       edm::Handle<std::vector<PSimHit> > simHits;
0226       edm::InputTag tag(hitsProducer, *i);
0227 
0228       iEvent.getByLabel(tag, simHits);
0229       unsigned int tofBin = PixelDigiSimLink::LowTof;
0230       if ((*i).find(std::string("HighTof")) != std::string::npos)
0231         tofBin = PixelDigiSimLink::HighTof;
0232       accumulatePixelHits(simHits, crossingSimHitIndexOffset_[tag.encode()], tofBin, iSetup);
0233       // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
0234       // the global counter. Next time accumulateStripHits() is called it will count the sim hits
0235       // as though they were on the end of this collection.
0236       // Note that this is only used for creating digi-sim links (if configured to do so).
0237       //       std::cout << "index offset, current hit count = " << crossingSimHitIndexOffset_[tag.encode()] << ", " << simHits->size() << std::endl;
0238       if (simHits.isValid())
0239         crossingSimHitIndexOffset_[tag.encode()] += simHits->size();
0240     }
0241   }
0242 
0243   void SiPixelDigitizer::accumulate(PileUpEventPrincipal const& iEvent,
0244                                     edm::EventSetup const& iSetup,
0245                                     edm::StreamID const& streamID) {
0246     // Step A: Get Inputs
0247     for (vstring::const_iterator i = trackerContainers.begin(), iEnd = trackerContainers.end(); i != iEnd; ++i) {
0248       edm::Handle<std::vector<PSimHit> > simHits;
0249       edm::InputTag tag(hitsProducer, *i);
0250 
0251       iEvent.getByLabel(tag, simHits);
0252       unsigned int tofBin = PixelDigiSimLink::LowTof;
0253       if ((*i).find(std::string("HighTof")) != std::string::npos)
0254         tofBin = PixelDigiSimLink::HighTof;
0255       accumulatePixelHits(simHits, crossingSimHitIndexOffset_[tag.encode()], tofBin, iSetup);
0256       // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
0257       // the global counter. Next time accumulateStripHits() is called it will count the sim hits
0258       // as though they were on the end of this collection.
0259       // Note that this is only used for creating digi-sim links (if configured to do so).
0260       //       std::cout << "index offset, current hit count = " << crossingSimHitIndexOffset_[tag.encode()] << ", " << simHits->size() << std::endl;
0261       if (simHits.isValid())
0262         crossingSimHitIndexOffset_[tag.encode()] += simHits->size();
0263     }
0264   }
0265 
0266   // ------------ method called to produce the data  ------------
0267   void SiPixelDigitizer::finalizeEvent(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0268     const TrackerTopology* tTopo = &iSetup.getData(tTopoToken_);
0269 
0270     std::vector<edm::DetSet<PixelDigi> > theDigiVector;
0271     std::vector<edm::DetSet<PixelDigiSimLink> > theDigiLinkVector;
0272     std::vector<edm::DetSet<PixelSimHitExtraInfo> > theExtraSimHitInfoVector;
0273     std::vector<edm::DetSet<PixelSimHitExtraInfoLite> > theExtraSimHitInfoLiteVector;
0274 
0275     if (firstFinalizeEvent_) {
0276       _pixeldigialgo->init_DynIneffDB(iSetup);
0277       firstFinalizeEvent_ = false;
0278     }
0279     _pixeldigialgo->calculateInstlumiFactor(PileupInfo_.get());
0280 
0281     if (_pixeldigialgo->killBadFEDChannels()) {
0282       std::unique_ptr<PixelFEDChannelCollection> PixelFEDChannelCollection_ =
0283           _pixeldigialgo->chooseScenario(PileupInfo_.get(), randomEngine_);
0284       if (PixelFEDChannelCollection_ == nullptr) {
0285         throw cms::Exception("NullPointerError") << "PixelFEDChannelCollection not set in chooseScenario function.\n";
0286       }
0287       iEvent.put(std::move(PixelFEDChannelCollection_));
0288     }
0289 
0290     for (const auto& iu : pDD->detUnits()) {
0291       if (iu->type().isTrackerPixel()) {
0292         //
0293 
0294         edm::DetSet<PixelDigi> collector(iu->geographicalId().rawId());
0295         edm::DetSet<PixelDigiSimLink> linkcollector(iu->geographicalId().rawId());
0296         std::vector<PixelDigiAddTempInfo> tempcollector;
0297         edm::DetSet<PixelSimHitExtraInfo> tempSHcollector(iu->geographicalId().rawId());
0298         edm::DetSet<PixelSimHitExtraInfoLite> tempSHLitecollector(iu->geographicalId().rawId());
0299 
0300         _pixeldigialgo->digitize(dynamic_cast<const PixelGeomDetUnit*>(iu),
0301                                  collector.data,
0302                                  linkcollector.data,
0303                                  tempcollector,
0304                                  tTopo,
0305                                  randomEngine_);
0306 
0307         // transformation of the tempcollector  (October 15, 2021)
0308         if (!tempcollector.empty()) {
0309           std::vector<PixelDigiAddTempInfo>::const_iterator loopNewClass;
0310           unsigned int channelPrevious2 = -1;
0311           size_t hitFirstOne2 = -1;
0312           for (loopNewClass = tempcollector.begin(); loopNewClass != tempcollector.end(); ++loopNewClass) {
0313             //   check if the new SimHit already exists in the class
0314             //      if yes : add only the Digi info to the existing entry
0315             //      if not : create a new entry
0316             //          PixelSimHitExtraInfo(
0317             //          size_t Hindex, Local3DPoint entryP , Local3DPoint exitP, uint32_t detID, std::vector<unsigned int> ch, std::vector<float> InitCharge)
0318             //   what about the duplicates : 2 SimHits associated to the same Digis ?
0319             //
0320             //
0321 
0322             bool checkTwoSimHits = false;
0323             if (channelPrevious2 == loopNewClass->channel() && hitFirstOne2 != loopNewClass->hitIndex()) {
0324               // case of one Digi associated to a second SimHit
0325               checkTwoSimHits = true;
0326             } else {
0327               channelPrevious2 = loopNewClass->channel();
0328               hitFirstOne2 = loopNewClass->hitIndex();
0329             }
0330 
0331             bool checkInTheList = false;
0332             // To fill the PixelSimHitExtraInfo temporary collector
0333             if (!checkTwoSimHits) {
0334               std::vector<PixelSimHitExtraInfo>::iterator loopTempSH;
0335               for (loopTempSH = tempSHcollector.begin(); loopTempSH != tempSHcollector.end(); ++loopTempSH) {
0336                 if (loopNewClass->hitIndex() == loopTempSH->hitIndex()) {
0337                   checkInTheList = true;
0338                   loopTempSH->addDigiInfo(loopNewClass->channel());
0339                 }
0340               }
0341               if (!checkInTheList) {
0342                 PixelSimHitExtraInfo newSHEntry(loopNewClass->hitIndex(),
0343                                                 loopNewClass->entryPoint(),
0344                                                 loopNewClass->exitPoint(),
0345                                                 loopNewClass->channel());
0346                 tempSHcollector.push_back(newSHEntry);
0347               }
0348             }
0349             bool checkInTheListLite = false;
0350             // To fill the PixelSimHitExtraInfoLite temporary collector
0351             if (!checkTwoSimHits) {
0352               std::vector<PixelSimHitExtraInfoLite>::iterator loopTempSHLite;
0353               for (loopTempSHLite = tempSHLitecollector.begin(); loopTempSHLite != tempSHLitecollector.end();
0354                    ++loopTempSHLite) {
0355                 if (loopNewClass->hitIndex() == loopTempSHLite->hitIndex()) {
0356                   checkInTheListLite = true;
0357                   loopTempSHLite->addDigiInfo(loopNewClass->channel());
0358                 }
0359               }
0360               if (!checkInTheListLite) {
0361                 PixelSimHitExtraInfoLite newSHLiteEntry(loopNewClass->hitIndex(),
0362                                                         loopNewClass->entryPoint(),
0363                                                         loopNewClass->exitPoint(),
0364                                                         loopNewClass->channel());
0365                 tempSHLitecollector.push_back(newSHLiteEntry);
0366               }
0367             }
0368           }
0369         }
0370 
0371         if (applyLateReweighting_) {
0372           if (!usePixelExtraLiteFormat_) {
0373             // if applyLateReweighting_  is true, the charge reweighting has to be applied on top of the digis
0374             _pixeldigialgo->lateSignalReweight(
0375                 dynamic_cast<const PixelGeomDetUnit*>(iu), collector.data, tempSHcollector.data, tTopo, randomEngine_);
0376           } else {
0377             // if applyLateReweighting_  is true, the charge reweighting has to be applied on top of the digis
0378             _pixeldigialgo->lateSignalReweight(dynamic_cast<const PixelGeomDetUnit*>(iu),
0379                                                collector.data,
0380                                                tempSHLitecollector.data,
0381                                                tTopo,
0382                                                randomEngine_);
0383           }
0384         }
0385 
0386         if (!collector.data.empty()) {
0387           theDigiVector.push_back(std::move(collector));
0388         }
0389         if (!linkcollector.data.empty()) {
0390           theDigiLinkVector.push_back(std::move(linkcollector));
0391         }
0392         if (!tempSHcollector.data.empty()) {
0393           theExtraSimHitInfoVector.push_back(std::move(tempSHcollector));
0394         }
0395         if (!tempSHLitecollector.data.empty()) {
0396           theExtraSimHitInfoLiteVector.push_back(std::move(tempSHLitecollector));
0397         }
0398       }
0399     }
0400     _pixeldigialgo->resetSimHitMaps();
0401 
0402     // Step C: create collection with the cache vector of DetSet
0403     std::unique_ptr<edm::DetSetVector<PixelDigi> > output(new edm::DetSetVector<PixelDigi>(theDigiVector));
0404     std::unique_ptr<edm::DetSetVector<PixelDigiSimLink> > outputlink(
0405         new edm::DetSetVector<PixelDigiSimLink>(theDigiLinkVector));
0406     std::unique_ptr<edm::DetSetVector<PixelSimHitExtraInfo> > outputExtraSim(
0407         new edm::DetSetVector<PixelSimHitExtraInfo>(theExtraSimHitInfoVector));
0408     std::unique_ptr<edm::DetSetVector<PixelSimHitExtraInfoLite> > outputExtraSimLite(
0409         new edm::DetSetVector<PixelSimHitExtraInfoLite>(theExtraSimHitInfoLiteVector));
0410 
0411     // Step D: write output to file
0412     iEvent.put(std::move(output));
0413     iEvent.put(std::move(outputlink));
0414     if (store_SimHitEntryExitPoints_)
0415       iEvent.put(std::move(outputExtraSim));
0416     if (store_SimHitEntryExitPointsLite_)
0417       iEvent.put(std::move(outputExtraSimLite));
0418 
0419     randomEngine_ = nullptr;  // to prevent access outside event
0420   }
0421 }  // namespace cms