Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:30:54

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/Common/interface/DigitizerUtility.h"
0027 
0028 #include "FWCore/Framework/interface/EventSetup.h"
0029 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0030 #include "FWCore/Utilities/interface/InputTag.h"
0031 #include "FWCore/ServiceRegistry/interface/Service.h"
0032 #include "FWCore/Framework/interface/ConsumesCollector.h"
0033 
0034 #include "FWCore/Framework/interface/Event.h"
0035 #include "FWCore/Framework/interface/LuminosityBlock.h"
0036 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0037 
0038 #include "DataFormats/Common/interface/Handle.h"
0039 #include "DataFormats/SiPixelDigi/interface/PixelDigi.h"
0040 #include "DataFormats/SiPixelDigi/interface/PixelDigiCollection.h"
0041 #include "DataFormats/Phase2TrackerDigi/interface/Phase2TrackerDigi.h"
0042 #include "DataFormats/Common/interface/DetSet.h"
0043 #include "DataFormats/Common/interface/DetSetVector.h"
0044 
0045 #include "SimDataFormats/TrackingHit/interface/PSimHit.h"
0046 #include "SimDataFormats/TrackerDigiSimLink/interface/PixelDigiSimLink.h"
0047 
0048 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
0049 #include "Geometry/CommonDetUnit/interface/PixelGeomDetUnit.h"
0050 
0051 #include "MagneticField/Engine/interface/MagneticField.h"
0052 
0053 #include "SimGeneral/MixingModule/interface/PileUpEventPrincipal.h"
0054 
0055 // Random Number
0056 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
0057 #include "FWCore/Utilities/interface/Exception.h"
0058 
0059 namespace cms {
0060 
0061   Phase2TrackerDigitizer::Phase2TrackerDigitizer(const edm::ParameterSet& iConfig,
0062                                                  edm::ProducesCollector producesCollector,
0063                                                  edm::ConsumesCollector& iC)
0064       : first_(true),
0065         hitsProducer_(iConfig.getParameter<std::string>("hitsProducer")),
0066         trackerContainers_(iConfig.getParameter<std::vector<std::string> >("ROUList")),
0067         pDDToken_(iC.esConsumes(edm::ESInputTag("", iConfig.getParameter<std::string>("GeometryType")))),
0068         pSetupToken_(iC.esConsumes()),
0069         tTopoToken_(iC.esConsumes()),
0070         isOuterTrackerReadoutAnalog_(iConfig.getParameter<bool>("isOTreadoutAnalog")),
0071         usePseudoPixel3DAlgo_(iConfig.getParameter<bool>("usePseudoPixel3DAlgo")),
0072         premixStage1_(iConfig.getParameter<bool>("premixStage1")),
0073 
0074         makeDigiSimLinks_(
0075             iConfig.getParameter<edm::ParameterSet>("AlgorithmCommon").getUntrackedParameter<bool>("makeDigiSimLinks")) {
0076     const std::string alias1("simSiPixelDigis");
0077     producesCollector.produces<edm::DetSetVector<PixelDigi> >("Pixel").setBranchAlias(alias1);
0078     if (makeDigiSimLinks_)
0079       producesCollector.produces<edm::DetSetVector<PixelDigiSimLink> >("Pixel").setBranchAlias(alias1);
0080 
0081     if (!iConfig.getParameter<bool>("isOTreadoutAnalog")) {
0082       const std::string alias2("simSiTrackerDigis");
0083       if (premixStage1_) {
0084         // Premixing exploits the ADC field of PixelDigi to store the collected charge
0085         // But we still want everything else to be treated like for Phase2TrackerDigi
0086         producesCollector.produces<edm::DetSetVector<PixelDigi> >("Tracker").setBranchAlias(alias2);
0087       } else {
0088         producesCollector.produces<edm::DetSetVector<Phase2TrackerDigi> >("Tracker").setBranchAlias(alias2);
0089       }
0090       if (makeDigiSimLinks_)
0091         producesCollector.produces<edm::DetSetVector<PixelDigiSimLink> >("Tracker").setBranchAlias(alias2);
0092     }
0093     // creating algorithm objects and pushing them into the map
0094     algomap_[AlgorithmType::InnerPixel] = std::make_unique<PixelDigitizerAlgorithm>(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     AlgorithmType algotype = AlgorithmType::Unknown;
0239     switch (mType) {
0240       case TrackerGeometry::ModuleType::Ph1PXB:
0241         algotype = AlgorithmType::InnerPixel;
0242         break;
0243       case TrackerGeometry::ModuleType::Ph1PXF:
0244         algotype = AlgorithmType::InnerPixel;
0245         break;
0246       case TrackerGeometry::ModuleType::Ph2PXB:
0247         algotype = AlgorithmType::InnerPixel;
0248         break;
0249       case TrackerGeometry::ModuleType::Ph2PXF:
0250         algotype = AlgorithmType::InnerPixel;
0251         break;
0252       case TrackerGeometry::ModuleType::Ph2PXB3D: {
0253         algotype = (usePseudoPixel3DAlgo_) ? AlgorithmType::InnerPixel : AlgorithmType::InnerPixel3D;
0254       } break;
0255       case TrackerGeometry::ModuleType::Ph2PXF3D: {
0256         algotype = (usePseudoPixel3DAlgo_) ? AlgorithmType::InnerPixel : AlgorithmType::InnerPixel3D;
0257       } break;
0258       case TrackerGeometry::ModuleType::Ph2PSP:
0259         algotype = AlgorithmType::PixelinPS;
0260         break;
0261       case TrackerGeometry::ModuleType::Ph2PSS:
0262         algotype = AlgorithmType::StripinPS;
0263         break;
0264       case TrackerGeometry::ModuleType::Ph2SS:
0265         algotype = AlgorithmType::TwoStrip;
0266         break;
0267       default:
0268         edm::LogError("Phase2TrackerDigitizer") << "ERROR - Wrong Detector Type, No Algorithm available ";
0269     }
0270 
0271     return algotype;
0272   }
0273   void Phase2TrackerDigitizer::addPixelCollection(edm::Event& iEvent,
0274                                                   const edm::EventSetup& iSetup,
0275                                                   const bool ot_analog) {
0276     std::vector<edm::DetSet<PixelDigi> > digiVector;
0277     std::vector<edm::DetSet<PixelDigiSimLink> > digiLinkVector;
0278     for (auto const& det_u : pDD_->detUnits()) {
0279       uint32_t rawId = det_u->geographicalId().rawId();
0280       auto algotype = getAlgoType(rawId);
0281       auto fiter = algomap_.find(algotype);
0282       if (fiter == algomap_.end())
0283         continue;
0284 
0285       // Decide if we want analog readout for Outer Tracker.
0286       if (!ot_analog && algotype != AlgorithmType::InnerPixel && algotype != AlgorithmType::InnerPixel3D)
0287         continue;
0288 
0289       std::map<int, digitizerUtility::DigiSimInfo> digi_map;
0290       fiter->second->digitize(dynamic_cast<const Phase2TrackerGeomDetUnit*>(det_u), digi_map, tTopo_);
0291 
0292       edm::DetSet<PixelDigi> collector(rawId);
0293       edm::DetSet<PixelDigiSimLink> linkcollector(rawId);
0294       for (auto const& digi_p : digi_map) {
0295         digitizerUtility::DigiSimInfo info = digi_p.second;
0296         const auto& ip = PixelDigi::channelToPixel(digi_p.first);
0297         collector.data.emplace_back(ip.first, ip.second, info.sig_tot);
0298         for (auto const& sim_p : info.simInfoList) {
0299           linkcollector.data.emplace_back(digi_p.first,
0300                                           sim_p.second->trackId(),
0301                                           sim_p.second->hitIndex(),
0302                                           sim_p.second->tofBin(),
0303                                           sim_p.second->eventId(),
0304                                           sim_p.first);
0305         }
0306       }
0307       if (!collector.data.empty())
0308         digiVector.push_back(std::move(collector));
0309       if (!linkcollector.data.empty())
0310         digiLinkVector.push_back(std::move(linkcollector));
0311     }
0312 
0313     // Step C: create collection with the cache vector of DetSet
0314     auto output = std::make_unique<edm::DetSetVector<PixelDigi> >(digiVector);
0315     auto outputlink = std::make_unique<edm::DetSetVector<PixelDigiSimLink> >(digiLinkVector);
0316 
0317     // Step D: write output to file
0318     iEvent.put(std::move(output), "Pixel");
0319     if (makeDigiSimLinks_)
0320       iEvent.put(std::move(outputlink), "Pixel");
0321   }
0322 }  // namespace cms
0323 namespace {
0324   void addToCollector(edm::DetSet<PixelDigi>& collector, const int channel, const digitizerUtility::DigiSimInfo& info) {
0325     // For premixing stage1 the channel must be decoded with PixelDigi
0326     // so that when the row and column are inserted to PixelDigi the
0327     // coded channel stays the same (so that it can then be decoded
0328     // with Phase2TrackerDigi in stage2).
0329     const auto& ip = PixelDigi::channelToPixel(channel);
0330     collector.data.emplace_back(ip.first, ip.second, info.sig_tot);
0331   }
0332   void addToCollector(edm::DetSet<Phase2TrackerDigi>& collector,
0333                       const int channel,
0334                       const digitizerUtility::DigiSimInfo& info) {
0335     const auto& ip = Phase2TrackerDigi::channelToPixel(channel);
0336     collector.data.emplace_back(ip.first, ip.second, info.ot_bit);
0337   }
0338 }  // namespace
0339 namespace cms {
0340   template <typename DigiType>
0341   void Phase2TrackerDigitizer::addOuterTrackerCollection(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0342     std::vector<edm::DetSet<DigiType> > digiVector;
0343     std::vector<edm::DetSet<PixelDigiSimLink> > digiLinkVector;
0344     for (auto const& det_u : pDD_->detUnits()) {
0345       uint32_t rawId = det_u->geographicalId().rawId();
0346       auto algotype = getAlgoType(rawId);
0347 
0348       auto fiter = algomap_.find(algotype);
0349       if (fiter == algomap_.end() || algotype == AlgorithmType::InnerPixel || algotype == AlgorithmType::InnerPixel3D)
0350         continue;
0351 
0352       std::map<int, digitizerUtility::DigiSimInfo> digi_map;
0353       fiter->second->digitize(dynamic_cast<const Phase2TrackerGeomDetUnit*>(det_u), digi_map, tTopo_);
0354 
0355       edm::DetSet<DigiType> collector(rawId);
0356       edm::DetSet<PixelDigiSimLink> linkcollector(rawId);
0357       for (auto const& digi_p : digi_map) {
0358         digitizerUtility::DigiSimInfo info = digi_p.second;
0359         addToCollector(collector, digi_p.first, info);
0360         for (auto const& sim_p : info.simInfoList) {
0361           linkcollector.data.emplace_back(digi_p.first,
0362                                           sim_p.second->trackId(),
0363                                           sim_p.second->hitIndex(),
0364                                           sim_p.second->tofBin(),
0365                                           sim_p.second->eventId(),
0366                                           sim_p.first);
0367         }
0368       }
0369 
0370       if (!collector.data.empty())
0371         digiVector.push_back(std::move(collector));
0372       if (!linkcollector.data.empty())
0373         digiLinkVector.push_back(std::move(linkcollector));
0374     }
0375 
0376     // Step C: create collection with the cache vector of DetSet
0377     auto output = std::make_unique<edm::DetSetVector<DigiType> >(digiVector);
0378     auto outputlink = std::make_unique<edm::DetSetVector<PixelDigiSimLink> >(digiLinkVector);
0379 
0380     // Step D: write output to file
0381     iEvent.put(std::move(output), "Tracker");
0382     if (makeDigiSimLinks_)
0383       iEvent.put(std::move(outputlink), "Tracker");
0384   }
0385 }  // namespace cms
0386 
0387 #include "FWCore/Framework/interface/MakerMacros.h"
0388 #include "SimGeneral/MixingModule/interface/DigiAccumulatorMixModFactory.h"
0389 
0390 using cms::Phase2TrackerDigitizer;
0391 DEFINE_DIGI_ACCUMULATOR(Phase2TrackerDigitizer);