CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
PixelThresholdClusterizerForBricked.cc
Go to the documentation of this file.
1 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7 
8 // Our own includes
10 #include "SiPixelArrayBuffer.h"
12 // Geometry
15 //#include "Geometry/CommonTopologies/RectangularPixelTopology.h"
16 
17 // STL
18 #include <stack>
19 #include <vector>
20 #include <iostream>
21 #include <atomic>
22 using namespace std;
23 
24 //----------------------------------------------------------------------------
28 //----------------------------------------------------------------------------
30  : PixelThresholdClusterizer(conf) {}
33 
34 //----------------------------------------------------------------------------
40 //----------------------------------------------------------------------------
41 template <typename T>
43  const PixelGeomDetUnit* pixDet,
44  const TrackerTopology* tTopo,
45  const std::vector<short>& badChannels,
47  typename T::const_iterator begin = input.begin();
48  typename T::const_iterator end = input.end();
49 
50  edm::LogInfo("PixelThresholdClusterizerForBricked::clusterizeDetUnitT()");
51 
52  // this should never happen and the raw2digi does not create empty detsets
53  if (begin == end) {
54  edm::LogError("PixelThresholdClusterizerForBricked")
55  << "@SUB=PixelThresholdClusterizerForBricked::clusterizeDetUnitT()"
56  << " No digis to clusterize";
57  }
58 
59  // Set up the clusterization on this DetId.
60  if (!setup(pixDet))
61  return;
62 
63  theDetid = input.detId();
64 
66  // Set separate cluster threshold for L1 (needed for phase1)
67  auto clusterThreshold = theClusterThreshold;
68  theLayer = (DetId(theDetid).subdetId() == 1) ? tTopo->pxbLayer(theDetid) : 0;
69  if (theLayer == 1)
70  clusterThreshold = theClusterThreshold_L1;
71 
72  // Copy PixelDigis to the buffer array; select the seed pixels
73  // on the way, and store them in theSeeds.
74  if (end > begin)
75  copy_to_buffer(begin, end);
76 
77  assert(output.empty());
78  // Loop over all seeds. TO DO: wouldn't using iterators be faster?
79  for (unsigned int i = 0; i < theSeeds.size(); i++) {
80  // Gavril : The charge of seeds that were already inlcuded in clusters is set to 1 electron
81  // so we don't want to call "make_cluster" for these cases
82  if (theBuffer(theSeeds[i]) >= theSeedThreshold) { // Is this seed still valid?
83  // Make a cluster around this seed
84  SiPixelCluster cluster;
85  if ((&pixDet->specificTopology())->isBricked()) {
86  cluster = make_cluster_bricked(theSeeds[i], output, isBarrel);
87  } else {
88  cluster = make_cluster(theSeeds[i], output);
89  }
90 
91  // Check if the cluster is above threshold
92  // (TO DO: one is signed, other unsigned, gcc warns...)
93  if (cluster.charge() >= clusterThreshold) {
94  // sort by row (x)
95  output.push_back(std::move(cluster));
96  std::push_heap(output.begin(), output.end(), [](SiPixelCluster const& cl1, SiPixelCluster const& cl2) {
97  return cl1.minPixelRow() < cl2.minPixelRow();
98  });
99  }
100  }
101  }
102  // sort by row (x) maybe sorting the seed would suffice....
103  std::sort_heap(output.begin(), output.end(), [](SiPixelCluster const& cl1, SiPixelCluster const& cl2) {
104  return cl1.minPixelRow() < cl2.minPixelRow();
105  });
106 
107  // Erase the seeds.
108  theSeeds.clear();
109 
110  // Need to clean unused pixels from the buffer array.
111  clear_buffer(begin, end);
112 
113  theFakePixels.clear();
114 }
115 
116 //----------------------------------------------------------------------------
118 //----------------------------------------------------------------------------
121  //First we acquire the seeds for the clusters
122  int seed_adc;
123  stack<SiPixelCluster::PixelPos, vector<SiPixelCluster::PixelPos> > dead_pixel_stack;
124 
125  //The individual modules have been loaded into a buffer.
126  //After each pixel has been considered by the clusterizer, we set the adc count to 1
127  //to mark that we have already considered it.
128  //The only difference between dead/noisy pixels and standard ones is that for dead/noisy pixels,
129  //We consider the charge of the pixel to always be zero.
130 
131  seed_adc = theBuffer(pix.row(), pix.col());
132  theBuffer.set_adc(pix, 1);
133 
134  AccretionCluster acluster;
135  acluster.add(pix, seed_adc);
136 
137  //Here we search all pixels adjacent to all pixels in the cluster.
138  bool dead_flag = false;
139  while (!acluster.empty()) {
140  //This is the standard algorithm to find and add a pixel
141  auto curInd = acluster.top();
142  acluster.pop();
143 
144  for (auto r = std::max(0, int(acluster.x[curInd]) - 1); r < std::min(int(acluster.x[curInd]) + 2, theBuffer.rows());
145  ++r) {
146  int LowerAccLimity = 0;
147  int UpperAccLimity = 0;
148 
149  if (r % 2 == int(acluster.x[curInd]) % 2) {
150  LowerAccLimity = std::max(0, int(acluster.y[curInd]) - 1);
151  UpperAccLimity = std::min(int(acluster.y[curInd]) + 2, theBuffer.columns());
152  }
153 
154  else {
155  int parity_curr = int(acluster.x[curInd]) % 2;
156  int parity_hit = r % 2;
157 
158  LowerAccLimity = std::max(0, int(acluster.y[curInd]) - parity_hit);
159  UpperAccLimity = std::min(int(acluster.y[curInd]) + parity_curr + 1, theBuffer.columns());
160  }
161 
162  /*
163  for (auto c = std::max(0, int(acluster.y[curInd]) - 1);
164  c < std::min(int(acluster.y[curInd]) + 2, theBuffer.columns());
165  ++c)
166  */
167  for (auto c = LowerAccLimity; c < UpperAccLimity; ++c) {
168  if (theBuffer(r, c) >= thePixelThreshold) {
169  SiPixelCluster::PixelPos newpix(r, c);
170  if (!acluster.add(newpix, theBuffer(r, c)))
171  goto endClus;
172  if (isbarrel)
173  edm::LogInfo("make_cluster_bricked()") << "add" << r << c << theBuffer(r, c);
174  theBuffer.set_adc(newpix, 1);
175  //std::cout<<"col "<<c<<" row "<<r<<std::endl;
176  }
177  }
178  }
179 
180  } // while accretion
181 endClus:
182  SiPixelCluster cluster(acluster.isize, acluster.adc, acluster.x, acluster.y, acluster.xmin, acluster.ymin);
183  //Here we split the cluster, if the flag to do so is set and we have found a dead or noisy pixel.
184 
185  if (dead_flag && doSplitClusters) {
186  // Set separate cluster threshold for L1 (needed for phase1)
187  auto clusterThreshold = theClusterThreshold;
188  if (theLayer == 1)
189  clusterThreshold = theClusterThreshold_L1;
190 
191  //Set the first cluster equal to the existing cluster.
192  SiPixelCluster first_cluster = cluster;
193  bool have_second_cluster = false;
194  while (!dead_pixel_stack.empty()) {
195  //consider each found dead pixel
196  SiPixelCluster::PixelPos deadpix = dead_pixel_stack.top();
197  dead_pixel_stack.pop();
198  theBuffer.set_adc(deadpix, 1);
199 
200  //Clusterize the split cluster using the dead pixel as a seed
201  SiPixelCluster second_cluster = make_cluster_bricked(deadpix, output, isbarrel);
202 
203  //If both clusters would normally have been found by the clusterizer, put them into output
204  if (second_cluster.charge() >= clusterThreshold && first_cluster.charge() >= clusterThreshold) {
205  output.push_back(second_cluster);
206  have_second_cluster = true;
207  }
208 
209  //We also want to keep the merged cluster in data and let the RecHit algorithm decide which set to keep
210  //This loop adds the second cluster to the first.
211  const std::vector<SiPixelCluster::Pixel>& branch_pixels = second_cluster.pixels();
212  for (unsigned int i = 0; i < branch_pixels.size(); i++) {
213  int temp_x = branch_pixels[i].x;
214  int temp_y = branch_pixels[i].y;
215  int temp_adc = branch_pixels[i].adc;
216  SiPixelCluster::PixelPos newpix(temp_x, temp_y);
217  cluster.add(newpix, temp_adc);
218  }
219  }
220 
221  //Remember to also add the first cluster if we added the second one.
222  if (first_cluster.charge() >= clusterThreshold && have_second_cluster) {
223  output.push_back(first_cluster);
224  std::push_heap(output.begin(), output.end(), [](SiPixelCluster const& cl1, SiPixelCluster const& cl2) {
225  return cl1.minPixelRow() < cl2.minPixelRow();
226  });
227  }
228  }
229 
230  return cluster;
231 }
void push_back(data_type const &d)
SiPixelArrayBuffer theBuffer
Data storage.
const edm::EventSetup & c
SiPixelCluster make_cluster(const SiPixelCluster::PixelPos &pix, edmNew::DetSetVector< SiPixelCluster >::FastFiller &output)
The actual clustering algorithm: group the neighboring pixels around the seed.
int charge() const
Log< level::Error, false > LogError
assert(be >=bs)
void set_adc(int row, int col, int adc)
static std::string const input
Definition: EdmProvDump.cc:47
int minPixelRow() const
def move
Definition: eostools.py:511
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
void add(const PixelPos &pix, int adc)
constexpr int col() const
unsigned int pxbLayer(const DetId &id) const
Log< level::Info, false > LogInfo
void clusterizeDetUnitT(const T &input, const PixelGeomDetUnit *pixDet, const TrackerTopology *tTopo, const std::vector< short > &badChannels, edmNew::DetSetVector< SiPixelCluster >::FastFiller &output)
Cluster pixels. This method operates on a matrix of pixels and finds the largest contiguous cluster a...
Definition: DetId.h:17
void clear_buffer(DigiIterator begin, DigiIterator end)
Clear the internal buffer array.
virtual const PixelTopology & specificTopology() const
Returns a reference to the pixel proxy topology.
SiPixelCluster make_cluster_bricked(const SiPixelCluster::PixelPos &pix, edmNew::DetSetVector< SiPixelCluster >::FastFiller &output, bool isbarrel)
The actual clustering algorithm: group the neighboring pixels around the seed.
Pixel cluster – collection of neighboring pixels above threshold.
string end
Definition: dataset.py:937
bool setup(const PixelGeomDetUnit *pixDet)
Private helper methods:
bool add(SiPixelCluster::PixelPos const &p, uint16_t const iadc)
std::vector< SiPixelCluster::PixelPos > theSeeds
PixelThresholdClusterizerForBricked(edm::ParameterSet const &conf)
long double T
constexpr int row() const
const std::vector< Pixel > pixels() const
void copy_to_buffer(DigiIterator begin, DigiIterator end)
Copy adc counts from PixelDigis into the buffer, identify seeds.
A specific threshold-based pixel clustering algorithm.