Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:26:23

0001 /** SiPixelRecHitConverter.cc
0002  * ------------------------------------------------------
0003  * Description:  see SiPixelRecHitConverter.h
0004  * Authors:  P. Maksimovic (JHU), V.Chiochia (Uni Zurich)
0005  * History: Feb 27, 2006 -  initial version
0006  *          May 30, 2006 -  edm::DetSetVector and edm::Ref
0007  *          Aug 30, 2007 -  edmNew::DetSetVector
0008  *          Jan 31, 2008 -  change to use Lorentz angle from DB (Lotte Wilke)
0009  * ------------------------------------------------------
0010  */
0011 
0012 //---------------------------------------------------------------------------
0013 //! \class SiPixelRecHitConverter
0014 //!
0015 //! \brief EDProducer to covert SiPixelClusters into SiPixelRecHits
0016 //!
0017 //! SiPixelRecHitConverter is an EDProducer subclass (i.e., a module)
0018 //! which orchestrates the conversion of SiPixelClusters into SiPixelRecHits.
0019 //! Consequently, the input is a edm::DetSetVector<SiPixelCluster> and the output is
0020 //! SiPixelRecHitCollection.
0021 //!
0022 //! SiPixelRecHitConverter invokes one of descendents from
0023 //! ClusterParameterEstimator (templated on SiPixelCluster), e.g.
0024 //! CPEFromDetPosition (which is the only available option
0025 //! right now).  SiPixelRecHitConverter loads the SiPixelClusterCollection,
0026 //! and then iterates over DetIds, invoking the chosen CPE's methods
0027 //! localPosition() and localError() to perform the correction (some of which
0028 //! may be rather involved).  A RecHit is made on the spot, and appended
0029 //! to the output collection.
0030 //!
0031 //! The calibrations are not loaded at the moment,
0032 //! although that is being planned for the near future.
0033 //!
0034 //! \author Porting from ORCA by Petar Maksimovic (JHU). Implementation of the
0035 //!         DetSetVector by V.Chiochia (Zurich University).
0036 //!
0037 //! \version v2, May 30, 2006
0038 //! change to use Lorentz angle from DB Lotte Wilke, Jan. 31st, 2008
0039 //!
0040 //---------------------------------------------------------------------------
0041 
0042 //--- Base class for CPEs:
0043 
0044 #include "RecoLocalTracker/SiPixelRecHits/interface/PixelCPEBase.h"
0045 
0046 //--- Geometry + DataFormats
0047 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
0048 #include "DataFormats/SiPixelCluster/interface/SiPixelCluster.h"
0049 #include "DataFormats/TrackerRecHit2D/interface/SiPixelRecHitCollection.h"
0050 #include "DataFormats/Common/interface/DetSetVector.h"
0051 
0052 //--- Framework
0053 #include "FWCore/Framework/interface/stream/EDProducer.h"
0054 #include "FWCore/Framework/interface/Event.h"
0055 #include "FWCore/Framework/interface/EventSetup.h"
0056 #include "FWCore/Framework/interface/MakerMacros.h"
0057 #include "DataFormats/Common/interface/Handle.h"
0058 #include "FWCore/Framework/interface/ESHandle.h"
0059 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0060 #include "FWCore/Utilities/interface/InputTag.h"
0061 #include "FWCore/Utilities/interface/EDPutToken.h"
0062 #include "FWCore/Utilities/interface/ESGetToken.h"
0063 
0064 // Geometry
0065 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
0066 #include "Geometry/CommonDetUnit/interface/PixelGeomDetUnit.h"
0067 
0068 // Data Formats
0069 #include "DataFormats/DetId/interface/DetId.h"
0070 #include "DataFormats/Common/interface/Ref.h"
0071 #include "DataFormats/Common/interface/DetSet2RangeMap.h"
0072 
0073 // STL
0074 #include <vector>
0075 #include <memory>
0076 #include <string>
0077 #include <iostream>
0078 
0079 // MessageLogger
0080 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0081 
0082 #include "RecoLocalTracker/Records/interface/TkPixelCPERecord.h"
0083 
0084 // Make heterogeneous framework happy
0085 #include "CUDADataFormats/SiPixelCluster/interface/gpuClusteringConstants.h"
0086 #include "CUDADataFormats/Common/interface/HostProduct.h"
0087 
0088 using namespace std;
0089 
0090 namespace cms {
0091 
0092   class SiPixelRecHitConverter : public edm::stream::EDProducer<> {
0093   public:
0094     //--- Constructor, virtual destructor (just in case)
0095     explicit SiPixelRecHitConverter(const edm::ParameterSet& conf);
0096     ~SiPixelRecHitConverter() override;
0097 
0098     //--- Factory method to make CPE's depending on the ParameterSet
0099     //--- Not sure if we need to make more than one CPE to run concurrently
0100     //--- on different parts of the detector (e.g., one for the barrel and the
0101     //--- one for the forward).  The way the CPE's are written now, it's
0102     //--- likely we can use one (and they will switch internally), or
0103     //--- make two of the same but configure them differently.  We need a more
0104     //--- realistic use case...
0105 
0106     //--- The top-level event method.
0107     void produce(edm::Event& e, const edm::EventSetup& c) override;
0108 
0109     //--- Execute the position estimator algorithm(s).
0110     void run(edm::Event& e,
0111              edm::Handle<SiPixelClusterCollectionNew> inputhandle,
0112              SiPixelRecHitCollectionNew& output,
0113              TrackerGeometry const& geom);
0114 
0115   private:
0116     using HMSstorage = HostProduct<uint32_t[]>;
0117 
0118     // TO DO: maybe allow a map of pointers?
0119     PixelCPEBase const* cpe_ = nullptr;  // What we got (for now, one ptr to base class)
0120     edm::InputTag const src_;
0121     std::string const cpeName_;
0122     edm::EDGetTokenT<SiPixelClusterCollectionNew> const tPixelCluster_;
0123     edm::EDPutTokenT<SiPixelRecHitCollection> const tPut_;
0124     edm::EDPutTokenT<HMSstorage> const tHost_;
0125     edm::ESGetToken<TrackerGeometry, TrackerDigiGeometryRecord> const tTrackerGeom_;
0126     edm::ESGetToken<PixelClusterParameterEstimator, TkPixelCPERecord> const tCPE_;
0127     bool m_newCont;  // save also in emdNew::DetSetVector
0128   };
0129 
0130   //---------------------------------------------------------------------------
0131   //!  Constructor: set the ParameterSet and defer all thinking to setupCPE().
0132   //---------------------------------------------------------------------------
0133   SiPixelRecHitConverter::SiPixelRecHitConverter(edm::ParameterSet const& conf)
0134       : src_(conf.getParameter<edm::InputTag>("src")),
0135         cpeName_(conf.getParameter<std::string>("CPE")),
0136         tPixelCluster_(consumes<SiPixelClusterCollectionNew>(src_)),
0137         tPut_(produces<SiPixelRecHitCollection>()),
0138         tHost_(produces<HMSstorage>()),
0139         tTrackerGeom_(esConsumes<TrackerGeometry, TrackerDigiGeometryRecord>()),
0140         tCPE_(esConsumes<PixelClusterParameterEstimator, TkPixelCPERecord>(edm::ESInputTag("", cpeName_))) {}
0141 
0142   // Destructor
0143   SiPixelRecHitConverter::~SiPixelRecHitConverter() {}
0144 
0145   //---------------------------------------------------------------------------
0146   //! The "Event" entrypoint: gets called by framework for every event
0147   //---------------------------------------------------------------------------
0148   void SiPixelRecHitConverter::produce(edm::Event& e, const edm::EventSetup& es) {
0149     // Step A.1: get input data
0150     edm::Handle<SiPixelClusterCollectionNew> input;
0151     e.getByToken(tPixelCluster_, input);
0152 
0153     // Step A.2: get event setup
0154     auto const& geom = es.getData(tTrackerGeom_);
0155 
0156     // Step B: create empty output collection
0157     SiPixelRecHitCollectionNew output;
0158 
0159     // Step B*: create CPE
0160     cpe_ = dynamic_cast<const PixelCPEBase*>(&es.getData(tCPE_));
0161 
0162     // Step C: Iterate over DetIds and invoke the strip CPE algorithm
0163     // on each DetUnit
0164 
0165     run(e, input, output, geom);
0166 
0167     output.shrink_to_fit();
0168     e.emplace(tPut_, std::move(output));
0169   }
0170 
0171   //---------------------------------------------------------------------------
0172   //!  Iterate over DetUnits, then over Clusters and invoke the CPE on each,
0173   //!  and make a RecHit to store the result.
0174   //!  New interface reading DetSetVector by V.Chiochia (May 30th, 2006)
0175   //---------------------------------------------------------------------------
0176   void SiPixelRecHitConverter::run(edm::Event& iEvent,
0177                                    edm::Handle<SiPixelClusterCollectionNew> inputhandle,
0178                                    SiPixelRecHitCollectionNew& output,
0179                                    TrackerGeometry const& geom) {
0180     if (!cpe_) {
0181       edm::LogError("SiPixelRecHitConverter") << " at least one CPE is not ready -- can't run!";
0182       // TO DO: throw an exception here?  The user may want to know...
0183       assert(0);
0184       return;  // clusterizer is invalid, bail out
0185     }
0186 
0187     int numberOfDetUnits = 0;
0188     int numberOfClusters = 0;
0189 
0190     const SiPixelClusterCollectionNew& input = *inputhandle;
0191 
0192     // allocate a buffer for the indices of the clusters
0193     auto hmsp = std::make_unique<uint32_t[]>(gpuClustering::maxNumModules + 1);
0194     // hitsModuleStart is a non-owning pointer to the buffer
0195     auto hitsModuleStart = hmsp.get();
0196     // fill cluster arrays
0197     std::array<uint32_t, gpuClustering::maxNumModules + 1> clusInModule{};
0198     for (auto const& dsv : input) {
0199       unsigned int detid = dsv.detId();
0200       DetId detIdObject(detid);
0201       const GeomDetUnit* genericDet = geom.idToDetUnit(detIdObject);
0202       auto gind = genericDet->index();
0203       // FIXME to be changed to support Phase2
0204       if (gind >= int(gpuClustering::maxNumModules))
0205         continue;
0206       auto const nclus = dsv.size();
0207       assert(nclus > 0);
0208       clusInModule[gind] = nclus;
0209       numberOfClusters += nclus;
0210     }
0211     hitsModuleStart[0] = 0;
0212     assert(clusInModule.size() > gpuClustering::maxNumModules);
0213     for (int i = 1, n = clusInModule.size(); i < n; ++i)
0214       hitsModuleStart[i] = hitsModuleStart[i - 1] + clusInModule[i - 1];
0215     assert(numberOfClusters == int(hitsModuleStart[gpuClustering::maxNumModules]));
0216 
0217     // wrap the buffer in a HostProduct, and move it to the Event, without reallocating the buffer or affecting hitsModuleStart
0218     iEvent.emplace(tHost_, std::move(hmsp));
0219 
0220     numberOfClusters = 0;
0221     for (auto const& dsv : input) {
0222       numberOfDetUnits++;
0223       unsigned int detid = dsv.detId();
0224       DetId detIdObject(detid);
0225       const GeomDetUnit* genericDet = geom.idToDetUnit(detIdObject);
0226       const PixelGeomDetUnit* pixDet = dynamic_cast<const PixelGeomDetUnit*>(genericDet);
0227       assert(pixDet);
0228       SiPixelRecHitCollectionNew::FastFiller recHitsOnDetUnit(output, detid);
0229 
0230       edmNew::DetSet<SiPixelCluster>::const_iterator clustIt = dsv.begin(), clustEnd = dsv.end();
0231 
0232       for (; clustIt != clustEnd; clustIt++) {
0233         numberOfClusters++;
0234         std::tuple<LocalPoint, LocalError, SiPixelRecHitQuality::QualWordType> tuple =
0235             cpe_->getParameters(*clustIt, *genericDet);
0236         LocalPoint lp(std::get<0>(tuple));
0237         LocalError le(std::get<1>(tuple));
0238         SiPixelRecHitQuality::QualWordType rqw(std::get<2>(tuple));
0239         // Create a persistent edm::Ref to the cluster
0240         SiPixelClusterRefNew cluster = edmNew::makeRefTo(inputhandle, clustIt);
0241         // Make a RecHit and add it to the DetSet
0242         SiPixelRecHit hit(lp, le, rqw, *genericDet, cluster);
0243         recHitsOnDetUnit.push_back(hit);
0244 
0245         LogDebug("SiPixelRecHitConverter") << "RecHit " << (numberOfClusters - 1)  //
0246                                            << " with local position " << lp << " and local error " << le;
0247       }  //  <-- End loop on Clusters
0248 
0249       LogDebug("SiPixelRecHitConverter") << "Found " << recHitsOnDetUnit.size() << " RecHits on " << detid;
0250 
0251     }  //    <-- End loop on DetUnits
0252 
0253     LogDebug("SiPixelRecHitConverter") << cpeName_ << " converted " << numberOfClusters
0254                                        << " SiPixelClusters into SiPixelRecHits, in " << numberOfDetUnits
0255                                        << " DetUnits.";
0256   }
0257 }  // end of namespace cms
0258 
0259 using cms::SiPixelRecHitConverter;
0260 
0261 DEFINE_FWK_MODULE(SiPixelRecHitConverter);