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  // Do not bother for empty detectors
53  if (begin == end)
54  edm::LogWarning("clusterizeDetUnit()") << "No digis to clusterize";
55 
56  // Set up the clusterization on this DetId.
57  if (!setup(pixDet))
58  return;
59 
60  theDetid = input.detId();
61 
63  // Set separate cluster threshold for L1 (needed for phase1)
64  auto clusterThreshold = theClusterThreshold;
65  theLayer = (DetId(theDetid).subdetId() == 1) ? tTopo->pxbLayer(theDetid) : 0;
66  if (theLayer == 1)
67  clusterThreshold = theClusterThreshold_L1;
68 
69  // Copy PixelDigis to the buffer array; select the seed pixels
70  // on the way, and store them in theSeeds.
71  if (end > begin)
72  copy_to_buffer(begin, end);
73 
74  assert(output.empty());
75  // Loop over all seeds. TO DO: wouldn't using iterators be faster?
76  for (unsigned int i = 0; i < theSeeds.size(); i++) {
77  // Gavril : The charge of seeds that were already inlcuded in clusters is set to 1 electron
78  // so we don't want to call "make_cluster" for these cases
79  if (theBuffer(theSeeds[i]) >= theSeedThreshold) { // Is this seed still valid?
80  // Make a cluster around this seed
81  SiPixelCluster cluster;
82  if ((&pixDet->specificTopology())->isBricked()) {
83  cluster = make_cluster_bricked(theSeeds[i], output, isBarrel);
84  } else {
85  cluster = make_cluster(theSeeds[i], output);
86  }
87 
88  // Check if the cluster is above threshold
89  // (TO DO: one is signed, other unsigned, gcc warns...)
90  if (cluster.charge() >= clusterThreshold) {
91  // sort by row (x)
92  output.push_back(std::move(cluster));
93  std::push_heap(output.begin(), output.end(), [](SiPixelCluster const& cl1, SiPixelCluster const& cl2) {
94  return cl1.minPixelRow() < cl2.minPixelRow();
95  });
96  }
97  }
98  }
99  // sort by row (x) maybe sorting the seed would suffice....
100  std::sort_heap(output.begin(), output.end(), [](SiPixelCluster const& cl1, SiPixelCluster const& cl2) {
101  return cl1.minPixelRow() < cl2.minPixelRow();
102  });
103 
104  // Erase the seeds.
105  theSeeds.clear();
106 
107  // Need to clean unused pixels from the buffer array.
108  clear_buffer(begin, end);
109 
110  theFakePixels.clear();
111 }
112 
113 //----------------------------------------------------------------------------
115 //----------------------------------------------------------------------------
118  //First we acquire the seeds for the clusters
119  int seed_adc;
120  stack<SiPixelCluster::PixelPos, vector<SiPixelCluster::PixelPos> > dead_pixel_stack;
121 
122  //The individual modules have been loaded into a buffer.
123  //After each pixel has been considered by the clusterizer, we set the adc count to 1
124  //to mark that we have already considered it.
125  //The only difference between dead/noisy pixels and standard ones is that for dead/noisy pixels,
126  //We consider the charge of the pixel to always be zero.
127 
128  seed_adc = theBuffer(pix.row(), pix.col());
129  theBuffer.set_adc(pix, 1);
130 
131  AccretionCluster acluster;
132  acluster.add(pix, seed_adc);
133 
134  //Here we search all pixels adjacent to all pixels in the cluster.
135  bool dead_flag = false;
136  while (!acluster.empty()) {
137  //This is the standard algorithm to find and add a pixel
138  auto curInd = acluster.top();
139  acluster.pop();
140 
141  for (auto r = std::max(0, int(acluster.x[curInd]) - 1); r < std::min(int(acluster.x[curInd]) + 2, theBuffer.rows());
142  ++r) {
143  int LowerAccLimity = 0;
144  int UpperAccLimity = 0;
145 
146  if (r % 2 == int(acluster.x[curInd]) % 2) {
147  LowerAccLimity = std::max(0, int(acluster.y[curInd]) - 1);
148  UpperAccLimity = std::min(int(acluster.y[curInd]) + 2, theBuffer.columns());
149  }
150 
151  else {
152  int parity_curr = int(acluster.x[curInd]) % 2;
153  int parity_hit = r % 2;
154 
155  LowerAccLimity = std::max(0, int(acluster.y[curInd]) - parity_hit);
156  UpperAccLimity = std::min(int(acluster.y[curInd]) + parity_curr + 1, theBuffer.columns());
157  }
158 
159  /*
160  for (auto c = std::max(0, int(acluster.y[curInd]) - 1);
161  c < std::min(int(acluster.y[curInd]) + 2, theBuffer.columns());
162  ++c)
163  */
164  for (auto c = LowerAccLimity; c < UpperAccLimity; ++c) {
165  if (theBuffer(r, c) >= thePixelThreshold) {
166  SiPixelCluster::PixelPos newpix(r, c);
167  if (!acluster.add(newpix, theBuffer(r, c)))
168  goto endClus;
169  if (isbarrel)
170  edm::LogInfo("make_cluster_bricked()") << "add" << r << c << theBuffer(r, c);
171  theBuffer.set_adc(newpix, 1);
172  //std::cout<<"col "<<c<<" row "<<r<<std::endl;
173  }
174  }
175  }
176 
177  } // while accretion
178 endClus:
179  SiPixelCluster cluster(acluster.isize, acluster.adc, acluster.x, acluster.y, acluster.xmin, acluster.ymin);
180  //Here we split the cluster, if the flag to do so is set and we have found a dead or noisy pixel.
181 
182  if (dead_flag && doSplitClusters) {
183  // Set separate cluster threshold for L1 (needed for phase1)
184  auto clusterThreshold = theClusterThreshold;
185  if (theLayer == 1)
186  clusterThreshold = theClusterThreshold_L1;
187 
188  //Set the first cluster equal to the existing cluster.
189  SiPixelCluster first_cluster = cluster;
190  bool have_second_cluster = false;
191  while (!dead_pixel_stack.empty()) {
192  //consider each found dead pixel
193  SiPixelCluster::PixelPos deadpix = dead_pixel_stack.top();
194  dead_pixel_stack.pop();
195  theBuffer.set_adc(deadpix, 1);
196 
197  //Clusterize the split cluster using the dead pixel as a seed
198  SiPixelCluster second_cluster = make_cluster_bricked(deadpix, output, isbarrel);
199 
200  //If both clusters would normally have been found by the clusterizer, put them into output
201  if (second_cluster.charge() >= clusterThreshold && first_cluster.charge() >= clusterThreshold) {
202  output.push_back(second_cluster);
203  have_second_cluster = true;
204  }
205 
206  //We also want to keep the merged cluster in data and let the RecHit algorithm decide which set to keep
207  //This loop adds the second cluster to the first.
208  const std::vector<SiPixelCluster::Pixel>& branch_pixels = second_cluster.pixels();
209  for (unsigned int i = 0; i < branch_pixels.size(); i++) {
210  int temp_x = branch_pixels[i].x;
211  int temp_y = branch_pixels[i].y;
212  int temp_adc = branch_pixels[i].adc;
213  SiPixelCluster::PixelPos newpix(temp_x, temp_y);
214  cluster.add(newpix, temp_adc);
215  }
216  }
217 
218  //Remember to also add the first cluster if we added the second one.
219  if (first_cluster.charge() >= clusterThreshold && have_second_cluster) {
220  output.push_back(first_cluster);
221  std::push_heap(output.begin(), output.end(), [](SiPixelCluster const& cl1, SiPixelCluster const& cl2) {
222  return cl1.minPixelRow() < cl2.minPixelRow();
223  });
224  }
225  }
226 
227  return cluster;
228 }
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
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)
T min(T a, T b)
Definition: MathUtil.h:58
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)
Log< level::Warning, false > LogWarning
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.