99#include " DataFormats/Common/interface/DetSetVectorNew.h"
1010#include " DataFormats/DetId/interface/DetId.h"
1111#include " DataFormats/SiPixelDigi/interface/PixelDigi.h"
12+ #include " DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
13+ #include " DataFormats/TrackerCommon/interface/TrackerTopology.h"
14+ #include " Geometry/Records/interface/TrackerTopologyRcd.h"
1215
16+ #include < boost/algorithm/string.hpp>
1317#include < bitset>
1418#include < iterator>
1519
20+ typedef std::pair<uint32_t , uint32_t > range;
21+ typedef std::vector<range> region;
22+
1623class SiPixelDigiMorphing : public edm ::stream::EDProducer<> {
1724public:
1825 explicit SiPixelDigiMorphing (const edm::ParameterSet& conf);
@@ -24,6 +31,10 @@ class SiPixelDigiMorphing : public edm::stream::EDProducer<> {
2431private:
2532 edm::EDGetTokenT<edm::DetSetVector<PixelDigi>> tPixelDigi_;
2633 edm::EDPutTokenT<edm::DetSetVector<PixelDigi>> tPutPixelDigi_;
34+ edm::ESGetToken<TrackerTopology, TrackerTopologyRcd> trackerTopologyToken_;
35+
36+ const std::vector<region> theBarrelRegions_;
37+ const std::vector<region> theEndcapRegions_;
2738
2839 const int32_t nrows_;
2940 const int32_t ncols_;
@@ -41,11 +52,19 @@ class SiPixelDigiMorphing : public edm::stream::EDProducer<> {
4152 enum MorphOption { kDilate , kErode };
4253
4354 void morph (uint64_t * const imap, uint64_t * omap, uint64_t * const kernel, MorphOption op) const ;
55+ std::vector<region> parseRegions (const std::vector<std::string>& regionStrings, size_t size);
56+ bool skipDetId (const TrackerTopology* tTopo,
57+ const DetId& detId,
58+ const std::vector<region>& theBarrelRegions,
59+ const std::vector<region>& theEndcapRegions) const ;
4460};
4561
4662SiPixelDigiMorphing::SiPixelDigiMorphing (edm::ParameterSet const & conf)
4763 : tPixelDigi_(consumes(conf.getParameter<edm::InputTag>(" src" ))),
4864 tPutPixelDigi_(produces<edm::DetSetVector<PixelDigi>>()),
65+ trackerTopologyToken_(esConsumes()),
66+ theBarrelRegions_(parseRegions(conf.getParameter<std::vector<std::string>>(" barrelRegions" ), 3)),
67+ theEndcapRegions_(parseRegions(conf.getParameter<std::vector<std::string>>(" endcapRegions" ), 4)),
4968 nrows_(conf.getParameter<int32_t >(" nrows" )),
5069 ncols_(conf.getParameter<int32_t >(" ncols" )),
5170 nrocs_(conf.getParameter<int32_t >(" nrocs" )),
@@ -93,6 +112,10 @@ void SiPixelDigiMorphing::fillDescriptions(edm::ConfigurationDescriptions& descr
93112 edm::ParameterSetDescription desc;
94113
95114 desc.add <edm::InputTag>(" src" , edm::InputTag (" siPixelDigis" ));
115+ // LAYER,LADDER,MODULE (coordinates can also be specified as a range FIRST-LAST where appropriate)
116+ desc.add <std::vector<std::string>>(" barrelRegions" , {" 1,1-12,1-2" , " 1,1-12,7-8" , " 2,1-28,1" , " 1,1-28,8" });
117+ // DISK,BLADE,SIDE,PANEL (coordinates can also be specified as a range FIRST-LAST where appropriate)
118+ desc.add <std::vector<std::string>>(" endcapRegions" , {});
96119 desc.add <int32_t >(" nrows" , 160 );
97120 desc.add <int32_t >(" ncols" , 416 );
98121 desc.add <int32_t >(" nrocs" , 8 );
@@ -109,6 +132,9 @@ void SiPixelDigiMorphing::produce(edm::Event& e, const edm::EventSetup& es) {
109132
110133 auto outputDigis = std::make_unique<edm::DetSetVector<PixelDigi>>();
111134
135+ // use the TrackerTopology for the layer/disk number, etc.
136+ const TrackerTopology* tTopo = &es.getData (trackerTopologyToken_);
137+
112138 const int rocSize = nrows_ + 2 * iters_;
113139 const int arrSize = nrocs_ * rocSize;
114140
@@ -118,6 +144,15 @@ void SiPixelDigiMorphing::produce(edm::Event& e, const edm::EventSetup& es) {
118144
119145 for (auto const & ds : inputDigi) {
120146 auto rawId = ds.detId ();
147+
148+ const DetId detId (rawId);
149+
150+ // skip DetIds for which digi morphing has not been requested
151+ if (skipDetId (tTopo, detId, theBarrelRegions_, theEndcapRegions_)) {
152+ outputDigis->insert (ds);
153+ continue ;
154+ }
155+
121156 edm::DetSet<PixelDigi>* detDigis = nullptr ;
122157 detDigis = &(outputDigis->find_or_insert (rawId));
123158
@@ -204,4 +239,98 @@ void SiPixelDigiMorphing::morph(uint64_t* const imap, uint64_t* omap, uint64_t*
204239 }
205240}
206241
242+ std::vector<region> SiPixelDigiMorphing::parseRegions (const std::vector<std::string>& regionStrings, size_t size) {
243+ std::vector<region> regions;
244+
245+ for (auto const & str : regionStrings) {
246+ region reg;
247+
248+ std::vector<std::string> ranges;
249+ boost::split (ranges, str, boost::is_any_of (" ," ));
250+
251+ if (ranges.size () != size) {
252+ throw cms::Exception (" Configuration" ) << " [SiPixelDigiMorphing]:"
253+ << " invalid number of coordinates provided in " << str << " (" << size
254+ << " expected, " << ranges.size () << " provided)\n " ;
255+ }
256+
257+ for (auto const & r : ranges) {
258+ std::vector<std::string> limits;
259+ boost::split (limits, r, boost::is_any_of (" -" ));
260+
261+ try {
262+ // if range specified
263+ if (limits.size () > 1 ) {
264+ reg.push_back (std::make_pair (std::stoi (limits.at (0 )), std::stoi (limits.at (1 ))));
265+ // otherwise store single value as a range
266+ } else {
267+ reg.push_back (std::make_pair (std::stoi (limits.at (0 )), std::stoi (limits.at (0 ))));
268+ }
269+ } catch (...) {
270+ throw cms::Exception (" Configuration" ) << " [SiPixelDigiMorphing]:"
271+ << " invalid coordinate value provided in " << str << " \n " ;
272+ }
273+ }
274+ regions.push_back (reg);
275+ }
276+
277+ return regions;
278+ }
279+
280+ // apply regional digi morphing logic
281+ bool SiPixelDigiMorphing::skipDetId (const TrackerTopology* tTopo,
282+ const DetId& detId,
283+ const std::vector<region>& theBarrelRegions,
284+ const std::vector<region>& theEndcapRegions) const {
285+ // barrel
286+ if (detId.subdetId () == static_cast <int >(PixelSubdetector::PixelBarrel)) {
287+ // no barrel region specified
288+ if (theBarrelRegions.empty ()) {
289+ return true ;
290+ } else {
291+ uint32_t layer = tTopo->pxbLayer (detId.rawId ());
292+ uint32_t ladder = tTopo->pxbLadder (detId.rawId ());
293+ uint32_t module = tTopo->pxbModule (detId.rawId ());
294+
295+ bool inRegion = false ;
296+
297+ for (auto const & reg : theBarrelRegions) {
298+ if ((layer >= reg.at (0 ).first && layer <= reg.at (0 ).second ) &&
299+ (ladder >= reg.at (1 ).first && ladder <= reg.at (1 ).second ) &&
300+ (module >= reg.at (2 ).first && module <= reg.at (2 ).second )) {
301+ inRegion = true ;
302+ break ;
303+ }
304+ }
305+
306+ return !inRegion;
307+ }
308+ // endcap
309+ } else {
310+ // no endcap region specified
311+ if (theEndcapRegions.empty ()) {
312+ return true ;
313+ } else {
314+ uint32_t disk = tTopo->pxfDisk (detId.rawId ());
315+ uint32_t blade = tTopo->pxfBlade (detId.rawId ());
316+ uint32_t side = tTopo->pxfSide (detId.rawId ());
317+ uint32_t panel = tTopo->pxfPanel (detId.rawId ());
318+
319+ bool inRegion = false ;
320+
321+ for (auto const & reg : theEndcapRegions) {
322+ if ((disk >= reg.at (0 ).first && disk <= reg.at (0 ).second ) &&
323+ (blade >= reg.at (1 ).first && blade <= reg.at (1 ).second ) &&
324+ (side >= reg.at (2 ).first && side <= reg.at (2 ).second ) &&
325+ (panel >= reg.at (3 ).first && panel <= reg.at (3 ).second )) {
326+ inRegion = true ;
327+ break ;
328+ }
329+ }
330+
331+ return !inRegion;
332+ }
333+ }
334+ }
335+
207336DEFINE_FWK_MODULE (SiPixelDigiMorphing);
0 commit comments