ATLAS Offline Software
KillBinsByStrip.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /* KillBinsByStrip.cxx
6  Selects out outlier bins from a 2D histogram, by strip, by gradually re-calculating the strip average without those bins.
7  Assumes that y-axis (phi coordinates) is symmetric from detector design.
8  Author: Olivier Simard (CEA-Saclay)
9  Email: Olivier.Simard@cern.ch
10 */
11 
12 #include <dqm_core/AlgorithmConfig.h>
15 #include <dqm_core/AlgorithmManager.h>
16 
17 #include <TH1.h>
18 #include <TH2.h>
19 #include <TH1D.h>
20 #include <TClass.h>
21 #include <cmath>
22 
23 
24 bool mySortfunc(const bin2& i,const bin2& j){return (i.m_value > j.m_value);}
25 bool mySortfunc_ratio(const bin2& i, const bin2& j){return (i.m_deviation> j.m_deviation);}
26 static dqm_algorithms::KillBinsByStrip myInstance;
27 
28 //_________________________________________________________________________________________
32 
33 //_________________________________________________________________________________________
34 dqm_core::Result* dqm_algorithms::KillBinsByStrip::execute(const std::string& name,const TObject& object,const dqm_core::AlgorithmConfig& config)
35 {
36  // Runs KillBinsByStrip algorithm on the 2D-histogram provided in 'object'.
37 
38  const TH2* histogram = NULL;
39  if( object.IsA()->InheritsFrom("TH2") ){
40  histogram = static_cast<const TH2*>(&object);
41  if(histogram->GetDimension() != 2 ){ throw dqm_core::BadConfig( ERS_HERE, name, "Not a 2D-histogram" ); }
42  } else { throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1/TH2" ); }
43 
44  const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1);
45  //const double ignoreval = dqm_algorithms::tools::GetFirstFromMap( "ignoreval", config.getParameters(), -99999);
46  const bool publish = (bool) dqm_algorithms::tools::GetFirstFromMap( "PublishBins", config.getParameters(), 1);
47  const int Nmaxpublish = (int) dqm_algorithms::tools::GetFirstFromMap( "MaxPublish", config.getParameters(), 20);
48  const bool VisualMode = (bool) dqm_algorithms::tools::GetFirstFromMap( "VisualMode", config.getParameters(), 0);
49  const int NpublishRed = (int) dqm_algorithms::tools::GetFirstFromMap( "PublishRedBins",config.getParameters(), 0);
50 
51  if (histogram->GetEntries() < minstat) {
53  result->tags_["InsufficientEntries"] = histogram->GetEntries();
54  return result;
55  }
56 
57  double gthreshold = 0., rthreshold = 0.;
58  try {
59  rthreshold = dqm_algorithms::tools::GetFromMap( "MaxDeviation", config.getRedThresholds() );
60  gthreshold = dqm_algorithms::tools::GetFromMap( "MaxDeviation", config.getGreenThresholds() );
61  } catch( dqm_core::Exception & ex ) {
62  throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex );
63  }
64 
65  // get bin limits
66  std::vector<int> range = dqm_algorithms::tools::GetBinRange(histogram,config.getParameters());
68  std::vector<bin2> redbins;
69  std::vector<bin2> yellowbins;
70  std::vector<bin2> Allbins;
71 
72  // objects needed before loop
73  TH1D* projected_strip = NULL;
74  char hname[56];
75  int ix,iy;
76  int binphi,biny,binz;
77  int nmax = 0, nbins = 0;
78  double binval = 0., maxval = 0.;
79  //double average = 0.
80  double stripavg = 0.,striperr = 0.,striperr2 = 0.,testval = 0.;
81 
82  // Some parameters set by hand: move to jobOption
83  int poissonLimit = 5;
84 
85 
86  // loop over all strips (eta or x-axis)
87  for(ix = range[0]; ix <= range[1]; ++ix){
88 
89  double eta = histogram->GetXaxis()->GetBinCenter(ix);
90 
91  // make up some name for the 1D-projection so that ROOT::TName does not complain
92  sprintf(hname,"%s_py_bin%d",histogram->GetName(),ix);
93  projected_strip = histogram->ProjectionY(hname,ix,ix); // single strip projection
94  nmax = 0;
95  nbins = 0;
96 
97 
98  // then within each strip remove bins until the deviation stabilizes.
99  // note that because the maximum can be anywhere in the strip, one cannot
100  // loop systematically over all bins. we rather search for the maximum and test it directly.
101  // Here "TH1::GetMaximumBin()" is used but one can replace it by anything that
102  // would be more efficient or faster.
103  while(true){
104 
105  striperr = 0.;
106  striperr2 = 0.;
107 
108  // number of bins with data in the strip (does not include previous maxima, if nmax>0)
109  if(nmax==0) for(iy=1;iy<=projected_strip->GetXaxis()->GetNbins();iy++) if(projected_strip->GetBinContent(iy)>0) nbins += 1;
110 
111  // identify current maximum in the strip
112  projected_strip->GetMaximumBin(binphi,biny,binz); // projected x-axis means the bin in phi (y-axis)
113  maxval = projected_strip->GetBinContent(binphi);
114  binval = maxval;
115 
116  // get out of this loop if the strip is empty or when we have emptied the strip
117  if(nbins<=0) break;
118 
119  // arithmetic mean for this strip
120  stripavg = projected_strip->Integral()/(double)nbins;
121 
122  // error on the mean: we might have to consider switching to Poisson if the number of remaining bins is low
123  if(nbins<=poissonLimit){
124 
125  // Poisson error calculated from mean
126  striperr = std::sqrt(stripavg);
127 
128  } else {
129 
130  // calculate sigma^2
131  for(iy=1;iy<=projected_strip->GetXaxis()->GetNbins();iy++) if(projected_strip->GetBinContent(iy)>0) striperr2 += std::pow((projected_strip->GetBinContent(iy)-stripavg),2);
132  // calculate error on the mean
133  striperr = std::sqrt(striperr2)/std::sqrt((double)nbins);
134 
135  }
136 
137  // calculate deviation from stripavg
138  if(striperr>0.) testval = std::abs(maxval-stripavg)/striperr;
139  else testval = 0.;
140 
141  // decision
142  bool die = false;
143  double phi = projected_strip->GetXaxis()->GetBinCenter(binphi);
144  bin2 onebin = {eta,phi,ix,binphi,binval,testval};
145  if(testval > rthreshold) redbins.push_back(onebin);
146  else if(testval > gthreshold) yellowbins.push_back(onebin);
147  else { // no problem, write that bin but then exits
148  Allbins.push_back(onebin);
149  die = true;
150  }
151 
152  // if the while-loop is not broken, keep looking for secondary maxima after
153  // removing the maximum that was just found.
154  // if there are any other reason to stop testing one should implement it here
155  if(die) break;
156 
157  // apply KillBin method - remove the content of latest offending-bin
158  projected_strip->SetBinContent(binphi,0); // kill bin
159  nmax += 1; // register one more maximum in the strip
160  nbins -= 1; // remove one count from strip
161 
162  } // while
163 
164  delete projected_strip;
165 
166  } // for(ix)
167 
168 
169  // The following is more or less the same.
170  std::sort(redbins.begin(),redbins.end(),mySortfunc);
171  std::sort(yellowbins.begin(),yellowbins.end(),mySortfunc);
172  std::sort(Allbins.begin(),Allbins.end(),mySortfunc_ratio);
173  char tmpstr[500];
174  int count_red=0,count_yellow=0;
175 
176  // publish red bins
177  for(unsigned int i=0;i<redbins.size();i++){
178  if(VisualMode) continue;
179  if(publish){
180  sprintf(tmpstr,"R%i-(eta,phi)[OSRatio]=(%0.3f,%0.3f)[%0.2e]",count_red,redbins[i].m_eta,redbins[i].m_phi,redbins[i].m_deviation);
181  std::string tag = tmpstr;
182  result->tags_[tag] = redbins[i].m_value;
183  }
184  count_red++;
185  if(NpublishRed > 0){
186  if(count_red > NpublishRed) break;
187  }
188  }
189 
190  // publish yellow bins
191  for(unsigned int i=0;i<yellowbins.size();i++){
192  if(VisualMode) continue;
193  if(publish && (count_red+count_yellow) < Nmaxpublish ){
194  sprintf(tmpstr,"Y%i-(eta,phi)[OSRatio]=(%0.3f,%0.3f)[%.2e]",count_yellow,yellowbins[i].m_eta,yellowbins[i].m_phi,yellowbins[i].m_deviation);
195  std::string tag = tmpstr;
196  result->tags_[tag] = yellowbins[i].m_value;
197  }
198  count_yellow++;
199  }
200  result->tags_["NRedBins"] = count_red; // count_red is the number of red bins printed
201  result->tags_["NYellowBins"] = count_yellow; // count_yellow is the number of yellow bins printed
202 
203  if(count_red+count_yellow==0 && Allbins.size()>0){
204  for(unsigned int i=0;i<Allbins.size();i++){
205  sprintf(tmpstr,"LeadingBin%u-(eta,phi)=(%0.3f,%0.3f)",i,Allbins[i].m_eta,Allbins[i].m_phi);
206  std::string tagtag = tmpstr;
207  result->tags_[tagtag] = Allbins[i].m_value;
208  }
209  }
210 
211  if(count_red>0) result->status_ = dqm_core::Result::Red;
212  else if(count_yellow>0) result->status_ = dqm_core::Result::Yellow;
213  else result->status_ = dqm_core::Result::Green;
214 
215  return result;
216 }
217 
218 //_________________________________________________________________________________________
220 {
221  out<<"KillBinsByStrip: Selects out outlier bins from a 2D histogram, by strip, by gradually re-calculating the strip average without those bins."<<std::endl;
222  out<<" Assumes that y-axis (phi coordinates) is symmetric from detector design."<<std::endl;
223 
224  out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm"<<std::endl;
225  out<<"Optional Parameter: ignoreval: valued to be ignored for being processed"<<std::endl;
226  out<<"Optional Parameter: PublishBins: Save bins which are different from average in Result (on:1,off:0,default is 1)"<<std::endl;
227  out<<"Optional Parameter: MaxPublish: Max number of bins to save (default 20)"<<std::endl;
228  out<<"Optional Parameter: VisualMode: is to make the evaluation process similar to the shift work, so one will get resonable result efficiently."<<std::endl;
229  return;
230 }
231 
dqm_algorithms::tools::GetBinRange
std::vector< int > GetBinRange(const TH1 *histogram, const std::map< std::string, double > &params)
Definition: AlgorithmHelper.cxx:380
Undefined
@ Undefined
Definition: MaterialTypes.h:8
mySortfunc
bool mySortfunc(const bin2 &i, const bin2 &j)
Definition: KillBinsByStrip.cxx:24
get_generator_info.result
result
Definition: get_generator_info.py:21
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:64
IsA
#define IsA
Declare the TObject style functions.
Definition: xAODTEventBranch.h:59
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
dqt_zlumi_pandas.hname
string hname
Definition: dqt_zlumi_pandas.py:272
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
TH1D
Definition: rootspy.cxx:342
bin2::m_deviation
double m_deviation
Definition: KillBinsByStrip.h:41
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
mySortfunc_ratio
bool mySortfunc_ratio(const bin2 &i, const bin2 &j)
Definition: KillBinsByStrip.cxx:25
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
SCT_CalibAlgs::nbins
@ nbins
Definition: SCT_CalibNumbers.h:10
instance
std::map< std::string, double > instance
Definition: Run_To_Get_Tags.h:8
TH1D::GetBinContent
double GetBinContent(int) const
Definition: rootspy.cxx:347
lumiFormat.i
int i
Definition: lumiFormat.py:92
Result
ICscStripFitter::Result Result
Definition: CalibCscStripFitter.cxx:13
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
dqm_algorithms::KillBinsByStrip::execute
dqm_core::Result * execute(const std::string &, const TObject &, const dqm_core::AlgorithmConfig &)
Definition: KillBinsByStrip.cxx:34
python.handimod.Green
int Green
Definition: handimod.py:524
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
dqm_algorithms::KillBinsByStrip::~KillBinsByStrip
~KillBinsByStrip()
Definition: KillBinsByStrip.cxx:30
TH2
Definition: rootspy.cxx:373
bin2
Definition: KillBinsByStrip.h:34
dqm_algorithms::KillBinsByStrip
Definition: KillBinsByStrip.h:21
python.handimod.Red
Red
Definition: handimod.py:551
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
TH1D::SetBinContent
void SetBinContent(int, double)
Definition: rootspy.cxx:348
dqm_algorithms::KillBinsByStrip::clone
KillBinsByStrip * clone()
Definition: KillBinsByStrip.cxx:31
bin2::m_value
double m_value
Definition: KillBinsByStrip.h:40
AlgorithmHelper.h
dqm_algorithms::tools::GetFromMap
const T & GetFromMap(const std::string &pname, const std::map< std::string, T > &params)
Definition: AlgorithmHelper.h:114
pickleTool.object
object
Definition: pickleTool.py:30
dqm_algorithms::KillBinsByStrip::printDescription
void printDescription(std::ostream &out)
Definition: KillBinsByStrip.cxx:219
CaloCondBlobAlgs_fillNoiseFromASCII.tag
string tag
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:24
dqm_algorithms::tools::GetFirstFromMap
double GetFirstFromMap(const std::string &paramName, const std::map< std::string, double > &params)
Definition: AlgorithmHelper.cxx:339
xAOD::bool
setBGCode setTAP setLVL2ErrorBits bool
Definition: TrigDecision_v1.cxx:60
dqm_algorithms::KillBinsByStrip::KillBinsByStrip
KillBinsByStrip()
Definition: KillBinsByStrip.cxx:29
KillBinsByStrip.h
nmax
const int nmax(200)
histogram
std::string histogram
Definition: chains.cxx:52