Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-02-28 01:32:39

0001 //
0002 //
0003 // Package:    Phase2TrackerDigitizer
0004 // Class:      Phase2TrackerDigitizer
0005 //
0006 // *\class SiPhase2TrackerDigitizer Phase2TrackerDigitizer.cc SimTracker/SiPhase2Digitizer/src/Phase2TrackerDigitizer.cc
0007 //
0008 // Author: Suchandra Dutta, Suvankar Roy Chowdhury, Subir Sarkar
0009 // Date: January 29, 2016
0010 // Description: <one line class summary>
0011 //
0012 // Implementation:
0013 //     <Notes on implementation>
0014 //
0015 #include <memory>
0016 #include <set>
0017 #include <iostream>
0018 
0019 #include "SimTracker/SiPhase2Digitizer/plugins/Phase2TrackerDigitizer.h"
0020 #include "SimTracker/SiPhase2Digitizer/plugins/Phase2TrackerDigitizerAlgorithm.h"
0021 #include "SimTracker/SiPhase2Digitizer/plugins/SSDigitizerAlgorithm.h"
0022 #include "SimTracker/SiPhase2Digitizer/plugins/PSSDigitizerAlgorithm.h"
0023 #include "SimTracker/SiPhase2Digitizer/plugins/PSPDigitizerAlgorithm.h"
0024 #include "SimTracker/SiPhase2Digitizer/plugins/PixelDigitizerAlgorithm.h"
0025 #include "SimTracker/SiPhase2Digitizer/plugins/Pixel3DDigitizerAlgorithm.h"
0026 #include "SimTracker/SiPhase2Digitizer/plugins/PixelBrickedDigitizerAlgorithm.h"
0027 #include "SimTracker/SiPhase2Digitizer/plugins/DigitizerUtility.h"
0028 
0029 #include "FWCore/Framework/interface/EventSetup.h"
0030 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0031 #include "FWCore/Utilities/interface/InputTag.h"
0032 #include "FWCore/ServiceRegistry/interface/Service.h"
0033 #include "FWCore/Framework/interface/ConsumesCollector.h"
0034 
0035 #include "FWCore/Framework/interface/Event.h"
0036 #include "FWCore/Framework/interface/LuminosityBlock.h"
0037 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0038 
0039 #include "DataFormats/Common/interface/Handle.h"
0040 #include "DataFormats/SiPixelDigi/interface/PixelDigi.h"
0041 #include "DataFormats/SiPixelDigi/interface/PixelDigiCollection.h"
0042 #include "DataFormats/Phase2TrackerDigi/interface/Phase2TrackerDigi.h"
0043 #include "DataFormats/Common/interface/DetSet.h"
0044 #include "DataFormats/Common/interface/DetSetVector.h"
0045 
0046 #include "SimDataFormats/TrackingHit/interface/PSimHit.h"
0047 #include "SimDataFormats/TrackerDigiSimLink/interface/PixelDigiSimLink.h"
0048 
0049 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
0050 #include "Geometry/CommonDetUnit/interface/PixelGeomDetUnit.h"
0051 
0052 #include "MagneticField/Engine/interface/MagneticField.h"
0053 
0054 #include "SimGeneral/MixingModule/interface/PileUpEventPrincipal.h"
0055 
0056 // Random Number
0057 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
0058 #include "FWCore/Utilities/interface/Exception.h"
0059 
0060 namespace cms {
0061 
0062   Phase2TrackerDigitizer::Phase2TrackerDigitizer(const edm::ParameterSet& iConfig,
0063                                                  edm::ProducesCollector producesCollector,
0064                                                  edm::ConsumesCollector& iC)
0065       : first_(true),
0066         hitsProducer_(iConfig.getParameter<std::string>("hitsProducer")),
0067         trackerContainers_(iConfig.getParameter<std::vector<std::string> >("ROUList")),
0068         pDDToken_(iC.esConsumes(edm::ESInputTag("", iConfig.getParameter<std::string>("GeometryType")))),
0069         pSetupToken_(iC.esConsumes()),
0070         tTopoToken_(iC.esConsumes()),
0071         isOuterTrackerReadoutAnalog_(iConfig.getParameter<bool>("isOTreadoutAnalog")),
0072         premixStage1_(iConfig.getParameter<bool>("premixStage1")),
0073         makeDigiSimLinks_(
0074             iConfig.getParameter<edm::ParameterSet>("AlgorithmCommon").getUntrackedParameter<bool>("makeDigiSimLinks")) {
0075     const std::string alias1("simSiPixelDigis");
0076     producesCollector.produces<edm::DetSetVector<PixelDigi> >("Pixel").setBranchAlias(alias1);
0077     if (makeDigiSimLinks_)
0078       producesCollector.produces<edm::DetSetVector<PixelDigiSimLink> >("Pixel").setBranchAlias(alias1);
0079 
0080     if (!iConfig.getParameter<bool>("isOTreadoutAnalog")) {
0081       const std::string alias2("simSiTrackerDigis");
0082       if (premixStage1_) {
0083         // Premixing exploits the ADC field of PixelDigi to store the collected charge
0084         // But we still want everything else to be treated like for Phase2TrackerDigi
0085         producesCollector.produces<edm::DetSetVector<PixelDigi> >("Tracker").setBranchAlias(alias2);
0086       } else {
0087         producesCollector.produces<edm::DetSetVector<Phase2TrackerDigi> >("Tracker").setBranchAlias(alias2);
0088       }
0089       if (makeDigiSimLinks_)
0090         producesCollector.produces<edm::DetSetVector<PixelDigiSimLink> >("Tracker").setBranchAlias(alias2);
0091     }
0092     // creating algorithm objects and pushing them into the map
0093     algomap_[AlgorithmType::InnerPixel] = std::make_unique<PixelDigitizerAlgorithm>(iConfig, iC);
0094     algomap_[AlgorithmType::InnerPixelBricked] = std::make_unique<PixelBrickedDigitizerAlgorithm>(iConfig, iC);
0095     algomap_[AlgorithmType::InnerPixel3D] = std::make_unique<Pixel3DDigitizerAlgorithm>(iConfig, iC);
0096     algomap_[AlgorithmType::PixelinPS] = std::make_unique<PSPDigitizerAlgorithm>(iConfig, iC);
0097     algomap_[AlgorithmType::StripinPS] = std::make_unique<PSSDigitizerAlgorithm>(iConfig, iC);
0098     algomap_[AlgorithmType::TwoStrip] = std::make_unique<SSDigitizerAlgorithm>(iConfig, iC);
0099   }
0100 
0101   Phase2TrackerDigitizer::~Phase2TrackerDigitizer() {}
0102   void Phase2TrackerDigitizer::accumulatePixelHits(edm::Handle<std::vector<PSimHit> > hSimHits,
0103                                                    size_t globalSimHitIndex,
0104                                                    const uint32_t tofBin) {
0105     if (hSimHits.isValid()) {
0106       std::set<uint32_t> detIds;
0107       auto const& simHits = *(hSimHits.product());
0108       for (auto it = std::begin(simHits), itEnd = std::end(simHits); it != itEnd; ++it, ++globalSimHitIndex) {
0109         uint32_t detId_raw = (*it).detUnitId();
0110         auto fiter = detectorUnits_.find(detId_raw);
0111         if (fiter == detectorUnits_.end())
0112           continue;
0113 
0114         if (detIds.insert(detId_raw).second) {
0115           // The insert succeeded, so this detector element has not yet been processed.
0116           const Phase2TrackerGeomDetUnit* phase2det = fiter->second;
0117 
0118           // access to magnetic field in global coordinates
0119           GlobalVector bfield = pSetup_->inTesla(phase2det->surface().position());
0120           LogDebug("PixelDigitizer") << "B-field(T) at " << phase2det->surface().position()
0121                                      << " (cm): " << pSetup_->inTesla(phase2det->surface().position());
0122 
0123           auto kiter = algomap_.find(getAlgoType(detId_raw));
0124           if (kiter != algomap_.end())
0125             kiter->second->accumulateSimHits(it, itEnd, globalSimHitIndex, tofBin, phase2det, bfield);
0126           else
0127             edm::LogInfo("Phase2TrackerDigitizer") << "Unsupported algorithm: ";
0128         }
0129       }
0130     }
0131   }
0132 
0133   void Phase2TrackerDigitizer::initializeEvent(edm::Event const& e, edm::EventSetup const& iSetup) {
0134     edm::Service<edm::RandomNumberGenerator> rng;
0135     if (!rng.isAvailable()) {
0136       throw cms::Exception("Configuration")
0137           << "Phase2TrackerDigitizer requires the RandomNumberGeneratorService\n"
0138              "which is not present in the configuration file.  You must add the service\n"
0139              "in the configuration file or remove the modules that require it.";
0140     }
0141 
0142     pSetup_ = &iSetup.getData(pSetupToken_);
0143     tTopo_ = &iSetup.getData(tTopoToken_);
0144 
0145     if (theTkDigiGeomWatcher_.check(iSetup)) {
0146       pDD_ = &iSetup.getData(pDDToken_);
0147 
0148       // reset cache
0149       ModuleTypeCache().swap(moduleTypeCache_);
0150       detectorUnits_.clear();
0151       for (auto const& det_u : pDD_->detUnits()) {
0152         uint32_t rawId = det_u->geographicalId().rawId();
0153         if (DetId(rawId).det() == DetId::Detector::Tracker) {
0154           const Phase2TrackerGeomDetUnit* pixdet = dynamic_cast<const Phase2TrackerGeomDetUnit*>(det_u);
0155           assert(pixdet);
0156           detectorUnits_.emplace(rawId, pixdet);
0157         }
0158       }
0159     }
0160 
0161     // Must initialize all the algorithms
0162     for (auto const& el : algomap_) {
0163       if (first_)
0164         el.second->init(iSetup);
0165 
0166       el.second->initializeEvent(rng->getEngine(e.streamID()));
0167     }
0168     first_ = false;
0169     // Make sure that the first crossing processed starts indexing the sim hits from zero.
0170     // This variable is used so that the sim hits from all crossing frames have sequential
0171     // indices used to create the digi-sim link (if configured to do so) rather than starting
0172     // from zero for each crossing.
0173     crossingSimHitIndexOffset_.clear();
0174   }
0175   void Phase2TrackerDigitizer::accumulate(edm::Event const& iEvent, edm::EventSetup const& iSetup) {
0176     accumulate_local<edm::Event>(iEvent, iSetup);
0177   }
0178 
0179   void Phase2TrackerDigitizer::accumulate(PileUpEventPrincipal const& iEvent,
0180                                           edm::EventSetup const& iSetup,
0181                                           edm::StreamID const&) {
0182     accumulate_local<PileUpEventPrincipal>(iEvent, iSetup);
0183   }
0184 
0185   template <class T>
0186   void Phase2TrackerDigitizer::accumulate_local(T const& iEvent, edm::EventSetup const& iSetup) {
0187     for (auto const& v : trackerContainers_) {
0188       edm::Handle<std::vector<PSimHit> > simHits;
0189       edm::InputTag tag(hitsProducer_, v);
0190       iEvent.getByLabel(tag, simHits);
0191 
0192       //edm::EDGetTokenT< std::vector<PSimHit> > simHitToken_(consumes< std::vector<PSimHit>(tag));
0193       //iEvent.getByToken(simHitToken_, simHits);
0194 
0195       uint32_t tofBin = PixelDigiSimLink::LowTof;
0196       if (v.find(std::string("HighTof")) != std::string::npos)
0197         tofBin = PixelDigiSimLink::HighTof;
0198       accumulatePixelHits(simHits, crossingSimHitIndexOffset_[tag.encode()], tofBin);
0199       // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
0200       // the global counter. Next time accumulateStripHits() is called it will count the sim hits
0201       // as though they were on the end of this collection.
0202       // Note that this is only used for creating digi-sim links (if configured to do so).
0203       if (simHits.isValid())
0204         crossingSimHitIndexOffset_[tag.encode()] += simHits->size();
0205     }
0206   }
0207 
0208   // For premixing
0209   void Phase2TrackerDigitizer::loadAccumulator(const std::map<uint32_t, std::map<int, float> >& accumulator) {
0210     for (const auto& detMap : accumulator) {
0211       AlgorithmType algoType = getAlgoType(detMap.first);
0212       auto& algo = *(algomap_.at(algoType));
0213       algo.loadAccumulator(detMap.first, detMap.second);
0214     }
0215   }
0216 
0217   void Phase2TrackerDigitizer::finalizeEvent(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0218     //Decide if we want analog readout for Outer Tracker.
0219     addPixelCollection(iEvent, iSetup, isOuterTrackerReadoutAnalog_);
0220     if (!isOuterTrackerReadoutAnalog_) {
0221       if (premixStage1_)
0222         addOuterTrackerCollection<PixelDigi>(iEvent, iSetup);
0223       else
0224         addOuterTrackerCollection<Phase2TrackerDigi>(iEvent, iSetup);
0225     }
0226   }
0227   Phase2TrackerDigitizer::AlgorithmType Phase2TrackerDigitizer::getAlgoType(uint32_t detId_raw) {
0228     // get mType either from the geometry or from our cache (faster)
0229     TrackerGeometry::ModuleType mType = TrackerGeometry::ModuleType::UNKNOWN;
0230     auto itr = moduleTypeCache_.find(detId_raw);
0231     if (itr != moduleTypeCache_.end()) {
0232       mType = itr->second;
0233     } else {
0234       mType = pDD_->getDetectorType(DetId(detId_raw));
0235       moduleTypeCache_.emplace(detId_raw, mType);
0236     }
0237 
0238     auto detUnit = detectorUnits_.find(detId_raw);
0239     const Phase2TrackerGeomDetUnit* pixdet = dynamic_cast<const Phase2TrackerGeomDetUnit*>(detUnit->second);
0240     const Phase2TrackerTopology* topol = &pixdet->specificTopology();
0241     AlgorithmType algotype = AlgorithmType::Unknown;
0242     switch (mType) {
0243       case TrackerGeometry::ModuleType::Ph1PXB:
0244         algotype = AlgorithmType::InnerPixel;
0245         break;
0246       case TrackerGeometry::ModuleType::Ph1PXF:
0247         algotype = AlgorithmType::InnerPixel;
0248         break;
0249       case TrackerGeometry::ModuleType::Ph2PXB:
0250         if (topol->isBricked())
0251           algotype = AlgorithmType::InnerPixelBricked;
0252         else
0253           algotype = AlgorithmType::InnerPixel;
0254         break;
0255       case TrackerGeometry::ModuleType::Ph2PXF:
0256         if (topol->isBricked())
0257           algotype = AlgorithmType::InnerPixelBricked;
0258         else
0259           algotype = AlgorithmType::InnerPixel;
0260         break;
0261       case TrackerGeometry::ModuleType::Ph2PXB3D:
0262         algotype = AlgorithmType::InnerPixel3D;
0263         break;
0264       case TrackerGeometry::ModuleType::Ph2PXF3D:
0265         algotype = AlgorithmType::InnerPixel3D;
0266         break;
0267       case TrackerGeometry::ModuleType::Ph2PSP:
0268         algotype = AlgorithmType::PixelinPS;
0269         break;
0270       case TrackerGeometry::ModuleType::Ph2PSS:
0271         algotype = AlgorithmType::StripinPS;
0272         break;
0273       case TrackerGeometry::ModuleType::Ph2SS:
0274         algotype = AlgorithmType::TwoStrip;
0275         break;
0276       default:
0277         edm::LogError("Phase2TrackerDigitizer") << "ERROR - Wrong Detector Type, No Algorithm available ";
0278     }
0279 
0280     return algotype;
0281   }
0282   void Phase2TrackerDigitizer::addPixelCollection(edm::Event& iEvent,
0283                                                   const edm::EventSetup& iSetup,
0284                                                   const bool ot_analog) {
0285     std::vector<edm::DetSet<PixelDigi> > digiVector;
0286     std::vector<edm::DetSet<PixelDigiSimLink> > digiLinkVector;
0287     for (auto const& det_u : pDD_->detUnits()) {
0288       uint32_t rawId = det_u->geographicalId().rawId();
0289       auto algotype = getAlgoType(rawId);
0290       auto fiter = algomap_.find(algotype);
0291       if (fiter == algomap_.end())
0292         continue;
0293 
0294       // Decide if we want analog readout for Outer Tracker.
0295       if (!ot_analog && algotype != AlgorithmType::InnerPixel && algotype != AlgorithmType::InnerPixel3D &&
0296           algotype != AlgorithmType::InnerPixelBricked)
0297         continue;
0298 
0299       std::map<int, DigitizerUtility::DigiSimInfo> digi_map;
0300       fiter->second->digitize(dynamic_cast<const Phase2TrackerGeomDetUnit*>(det_u), digi_map, tTopo_);
0301 
0302       edm::DetSet<PixelDigi> collector(rawId);
0303       edm::DetSet<PixelDigiSimLink> linkcollector(rawId);
0304       for (auto const& digi_p : digi_map) {
0305         DigitizerUtility::DigiSimInfo info = digi_p.second;
0306         const auto& ip = PixelDigi::channelToPixel(digi_p.first);
0307         collector.data.emplace_back(ip.first, ip.second, info.sig_tot);
0308         for (auto const& sim_p : info.simInfoList) {
0309           linkcollector.data.emplace_back(digi_p.first,
0310                                           sim_p.second->trackId(),
0311                                           sim_p.second->hitIndex(),
0312                                           sim_p.second->tofBin(),
0313                                           sim_p.second->eventId(),
0314                                           sim_p.first);
0315         }
0316       }
0317       if (!collector.data.empty())
0318         digiVector.push_back(std::move(collector));
0319       if (!linkcollector.data.empty())
0320         digiLinkVector.push_back(std::move(linkcollector));
0321     }
0322 
0323     // Step C: create collection with the cache vector of DetSet
0324     auto output = std::make_unique<edm::DetSetVector<PixelDigi> >(digiVector);
0325     auto outputlink = std::make_unique<edm::DetSetVector<PixelDigiSimLink> >(digiLinkVector);
0326 
0327     // Step D: write output to file
0328     iEvent.put(std::move(output), "Pixel");
0329     if (makeDigiSimLinks_)
0330       iEvent.put(std::move(outputlink), "Pixel");
0331   }
0332 }  // namespace cms
0333 namespace {
0334   void addToCollector(edm::DetSet<PixelDigi>& collector, const int channel, const DigitizerUtility::DigiSimInfo& info) {
0335     // For premixing stage1 the channel must be decoded with PixelDigi
0336     // so that when the row and column are inserted to PixelDigi the
0337     // coded channel stays the same (so that it can then be decoded
0338     // with Phase2TrackerDigi in stage2).
0339     const auto& ip = PixelDigi::channelToPixel(channel);
0340     collector.data.emplace_back(ip.first, ip.second, info.sig_tot);
0341   }
0342   void addToCollector(edm::DetSet<Phase2TrackerDigi>& collector,
0343                       const int channel,
0344                       const DigitizerUtility::DigiSimInfo& info) {
0345     const auto& ip = Phase2TrackerDigi::channelToPixel(channel);
0346     collector.data.emplace_back(ip.first, ip.second, info.ot_bit);
0347   }
0348 }  // namespace
0349 namespace cms {
0350   template <typename DigiType>
0351   void Phase2TrackerDigitizer::addOuterTrackerCollection(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0352     std::vector<edm::DetSet<DigiType> > digiVector;
0353     std::vector<edm::DetSet<PixelDigiSimLink> > digiLinkVector;
0354     for (auto const& det_u : pDD_->detUnits()) {
0355       uint32_t rawId = det_u->geographicalId().rawId();
0356       auto algotype = getAlgoType(rawId);
0357 
0358       auto fiter = algomap_.find(algotype);
0359       if (fiter == algomap_.end() || algotype == AlgorithmType::InnerPixel || algotype == AlgorithmType::InnerPixel3D ||
0360           algotype == AlgorithmType::InnerPixelBricked)
0361         continue;
0362 
0363       std::map<int, DigitizerUtility::DigiSimInfo> digi_map;
0364       fiter->second->digitize(dynamic_cast<const Phase2TrackerGeomDetUnit*>(det_u), digi_map, tTopo_);
0365 
0366       edm::DetSet<DigiType> collector(rawId);
0367       edm::DetSet<PixelDigiSimLink> linkcollector(rawId);
0368       for (auto const& digi_p : digi_map) {
0369         DigitizerUtility::DigiSimInfo info = digi_p.second;
0370         addToCollector(collector, digi_p.first, info);
0371         for (auto const& sim_p : info.simInfoList) {
0372           linkcollector.data.emplace_back(digi_p.first,
0373                                           sim_p.second->trackId(),
0374                                           sim_p.second->hitIndex(),
0375                                           sim_p.second->tofBin(),
0376                                           sim_p.second->eventId(),
0377                                           sim_p.first);
0378         }
0379       }
0380 
0381       if (!collector.data.empty())
0382         digiVector.push_back(std::move(collector));
0383       if (!linkcollector.data.empty())
0384         digiLinkVector.push_back(std::move(linkcollector));
0385     }
0386 
0387     // Step C: create collection with the cache vector of DetSet
0388     auto output = std::make_unique<edm::DetSetVector<DigiType> >(digiVector);
0389     auto outputlink = std::make_unique<edm::DetSetVector<PixelDigiSimLink> >(digiLinkVector);
0390 
0391     // Step D: write output to file
0392     iEvent.put(std::move(output), "Tracker");
0393     if (makeDigiSimLinks_)
0394       iEvent.put(std::move(outputlink), "Tracker");
0395   }
0396 }  // namespace cms
0397 
0398 #include "FWCore/Framework/interface/MakerMacros.h"
0399 #include "SimGeneral/MixingModule/interface/DigiAccumulatorMixModFactory.h"
0400 
0401 using cms::Phase2TrackerDigitizer;
0402 DEFINE_DIGI_ACCUMULATOR(Phase2TrackerDigitizer);