ATLAS Offline Software
AFP_DeadPixelTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 #include <cmath>
7 
8 int AFP_DeadPixelTool::Identify(std::shared_ptr<const TH2F> input, std::vector<TH2F>& output) const
9 {
10  if(output.size()!=1)
11  {
12  return 0;
13  }
14 
15  TH2F tmp_dead_pixels(*static_cast<TH2F*>(input->Clone("tmp_dead_pixels")));
16  tmp_dead_pixels.Reset();
17 
18  TH2F& deadpixels_output = output.at(0);
19  deadpixels_output.SetName(Form("deadpixels_%s",deadpixels_output.GetName()));
20  deadpixels_output.SetTitle(Form("dead pixels, %s",deadpixels_output.GetTitle()));
21  deadpixels_output.Reset();
22 
23  auto maxHitValue=input->GetMaximum();
24 
25  // first iteration (find singular dead pixels)
26  for(int col_ID=1; col_ID<=input->GetNbinsY(); col_ID++)
27  {
28  for(int row_ID=1; row_ID<=input->GetNbinsX(); row_ID++)
29  {
30  if(input->GetBinContent(row_ID, col_ID)==0 )
31  {
32  double nNeighbours=getNeighbours(input, row_ID,col_ID);
33 
34  int sum_neighbours=0;
35  int inactive_pixels_around=0;
36 
37  auto legit_pixels=getLegitPixels(input, col_ID, row_ID);
38  for(auto legpix : legit_pixels)
39  {
40  sum_neighbours+=input->GetBinContent(legpix.first, legpix.second);
41  if(input->GetBinContent(legpix.first, legpix.second)<1) ++inactive_pixels_around;
42  }
43 
44  if(inactive_pixels_around<4 && std::round(sum_neighbours/nNeighbours)>=m_range*maxHitValue)
45  {
46  deadpixels_output.Fill(row_ID, col_ID);
47  tmp_dead_pixels.SetBinContent(row_ID,col_ID, 1);
48  }
49  }
50  }
51  }
52 
53  // second iteration (find groups of dead pixels)
54  bool newDEAD=true;
55  while(newDEAD)
56  {
57  newDEAD=false;
58  for(int col_ID=1; col_ID<=input->GetNbinsY(); col_ID++)
59  {
60  for(int row_ID=1; row_ID<=input->GetNbinsX(); row_ID++)
61  {
62  if(tmp_dead_pixels.GetBinContent(row_ID,col_ID)==0 && input->GetBinContent(row_ID, col_ID)==0)
63  {
64  double nNeighbours=getNeighbours(input, row_ID,col_ID);
65 
66  int sum_neighbours=0;
67  int inactive_pixels_around=0;
68  int dead_pixels_around=0;
69 
70  auto legit_pixels=getLegitPixels(input, col_ID, row_ID);
71  for(auto legpix : legit_pixels)
72  {
73  sum_neighbours+=input->GetBinContent(legpix.first, legpix.second);
74  if(input->GetBinContent(legpix.first, legpix.second)<1) ++inactive_pixels_around;
75 
76  if(tmp_dead_pixels.GetBinContent(legpix.first, legpix.second)>0) dead_pixels_around++;
77  }
78 
79 
80  if(dead_pixels_around>0 && inactive_pixels_around>3 && std::round(sum_neighbours/nNeighbours)>=m_range*maxHitValue)
81  {
82  deadpixels_output.Fill(row_ID, col_ID);
83  tmp_dead_pixels.SetBinContent(row_ID,col_ID, 1);
84  newDEAD=true;
85  }
86  }
87  }
88  }
89  }
90 
91  return 0;
92 }
93 
94 
95 std::vector<std::pair<int,int>> AFP_DeadPixelTool::getLegitPixels(std::shared_ptr<const TH2F> input, const int col_ID, const int row_ID) const
96 {
97  std::vector<std::pair<int,int>> legit_pixels={};
98 
99  for(int r=-1; r<2; r++)
100  {
101  for(int c=-1; c<2; c++)
102  {
103  if( (row_ID+r)>=1 && (col_ID+c)>=1 && (col_ID+c)<=input->GetNbinsY() && (row_ID+r)<=input->GetNbinsX() && (r!=0 || c!=0))
104  {
105  legit_pixels.push_back(std::pair<int,int>(row_ID+r,col_ID+c));
106  }
107  }
108  }
109 
110  return legit_pixels;
111 }
112 
113 
114 double AFP_DeadPixelTool::getNeighbours(std::shared_ptr<const TH2F> input, int row_ID, int col_ID) const
115 {
116  if( row_ID!=input->GetNbinsX() && row_ID!=1 && col_ID!=1 && col_ID!=input->GetNbinsY()) return 8.; // inner pixels
117  else if( (row_ID==input->GetNbinsX() || row_ID==1) && (col_ID==1 || col_ID==input->GetNbinsY())) return 3.; // corner pixels
118  else return 5; // pixels along edges
119 }
beamspotman.r
def r
Definition: beamspotman.py:674
MuonGM::round
float round(const float toRound, const unsigned int decimals)
Definition: Mdt.cxx:27
python.TrigEgammaMonitorHelper.TH2F
def TH2F(name, title, nxbins, bins_par2, bins_par3, bins_par4, bins_par5=None, bins_par6=None, path='', **kwargs)
Definition: TrigEgammaMonitorHelper.py:45
AFP_DeadPixelTool::m_range
float m_range
Definition: AFP_DeadPixelTool.h:31
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
AFP_DeadPixelTool::getLegitPixels
std::vector< std::pair< int, int > > getLegitPixels(std::shared_ptr< const TH2F > input, const int col_ID, const int row_ID) const
Definition: AFP_DeadPixelTool.cxx:95
merge.output
output
Definition: merge.py:16
AFP_DeadPixelTool::getNeighbours
double getNeighbours(std::shared_ptr< const TH2F > input, int row_ID, int col_ID) const
Definition: AFP_DeadPixelTool.cxx:114
AFP_DeadPixelTool::Identify
int Identify(std::shared_ptr< const TH2F > input, std::vector< TH2F > &output) const override
Definition: AFP_DeadPixelTool.cxx:8
python.compressB64.c
def c
Definition: compressB64.py:93
AFP_DeadPixelTool.h
ActsTrk::nNeighbours
@ nNeighbours
Definition: StripInformationHelper.h:13