ATLAS Offline Software
MDTCluster.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // **********************************************************************
6 // $Id: MDTCluster.cxx,v 1.0 2008/10/08 Valerio Consorti
7 // **********************************************************************
8 
10 
11 
12 
13 #include <TClass.h>
14 #include <TH1.h>
15 #include <TAxis.h>
16 #include <utility>
17 #include <string>
18 #include <vector>
19 
20 
21 #include "dqm_core/exceptions.h"
22 #include "dqm_core/AlgorithmConfig.h"
23 #include "dqm_core/AlgorithmManager.h"
24 #include "dqm_core/Result.h"
26 #include "ers/ers.h"
27 #include <cmath>
28 #include <iostream>
29 #include <map>
30 static dqm_algorithms::MDTCluster staticInstance;
31 
32 
33 namespace dqm_algorithms {
34 
35 // *********************************************************************
36 // Public Methods
37 // *********************************************************************
38 
40  : m_name("MDTcluster")
41 {
42  dqm_core::AlgorithmManager::instance().registerAlgorithm( m_name, this );
43 }
44 
45 
47 {
48 }
49 
50 
51 dqm_core::Algorithm*
53 {
54  return new MDTCluster(*this);
55 }
56 
57 
59 MDTCluster::execute( const std::string& name, const TObject& object, const dqm_core::AlgorithmConfig& config)
60 {
61  const TH1 * hist;
62  TH1 * ref;
63 
64  if( object.IsA()->InheritsFrom( "TH1" ) ) {
65  hist = static_cast<const TH1*>(&object);
66  if (hist->GetDimension() >= 2 ){
67  throw dqm_core::BadConfig( ERS_HERE, name, "dimension >= 2 " );
68  }
69  } else {
70  throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" );
71  }
72 
73  //Get Parameters and Thresholds
74  double minstat;
75  double n_sigma;
76  double greenTh;
77  double redTh;
78  try {
79  minstat = dqm_algorithms::tools::GetFirstFromMap("MinStat", config.getParameters(), 500);
80  n_sigma = dqm_algorithms::tools::GetFirstFromMap("N_sigma", config.getParameters());
81  redTh = dqm_algorithms::tools::GetFromMap( "ClusterSize", config.getRedThresholds());
82  greenTh = dqm_algorithms::tools::GetFromMap( "ClusterSize", config.getGreenThresholds() );
83  }
84  catch ( dqm_core::Exception & ex ) {
85  throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex );
86  }
87 
88  double cluster_size=greenTh;
89 
90  //Get Reference Histo
91 
92  try {
93  ref = static_cast<TH1*>( config.getReference() );
94  }
95  catch ( dqm_core::Exception & ex ) {
96  throw dqm_core::BadRefHist(ERS_HERE,name," Could not retrieve reference");
97  }
98  if (hist->GetDimension() != ref->GetDimension() ) {
99  throw dqm_core::BadRefHist( ERS_HERE, name, "Reference VS histo: Different dimension!" );
100  }
101  if (hist->GetNbinsX() != ref->GetNbinsX() ) {
102  throw dqm_core::BadRefHist( ERS_HERE, name, "Reference VS histo: Different bin number in X axis!" );
103  }
104 
105  //Check of statistics
106  if (hist->GetEntries() < minstat ) {
107  ERS_INFO("Histogram does not satisfy MinStat requirement " <<hist->GetName());
109  result->tags_["InsufficientEntries"] = hist->GetEntries();
110  return result;
111  }
112  ERS_DEBUG(1,"Statistics: "<< hist->GetEntries()<< " entries ");
113 
114 
115 //Algo
116  double N;
117  double N_ref;
118 
119  N= hist->GetEntries();
120  N_ref= ref->GetEntries();
121 
122  if(N == 0){
123  ERS_INFO("Histogram has no entries" <<hist->GetName());
125  result->tags_["InsufficientEntries"] = hist->GetEntries();
126  return result;
127  };
128 
129  if(N_ref == 0){
130  ERS_INFO("Reference histogram has no entries" <<hist->GetName());
132  result->tags_["InsufficientRefEntries"] = ref->GetEntries();
133  return result;
134  };
135 
136  //Scaling reference to histo
137 
138  double norm= (double) N/N_ref;
139  ref->Scale(norm);
140 
141 
142  //Storing bin-bin differences between histo and reference
143  unsigned int i=1;
144  int j=1;
145  std::vector<double> diff;
146 
147  for(j=1;j<=hist->GetNbinsX();j++){
148  diff.push_back(hist->GetBinContent(j)-ref->GetBinContent(j));
149  };
150 
151 
152 
153  //looking for clusters:
154  //the custer begins when the difference between hist and ref is larger than
155  //n_sigma*sqrt(hist_N_bin_entries+ref_N_bin_entries*norm*norm)
156  //and finishes when the difference is smaller.
157 
158  i=0;
159  bool cluster_open=false;
160  std::pair<int,int> bin_start_end;
161  std::pair<int , std::pair<int,int> > cluster_size_binStart_binEnd;
162  std::vector< std::pair< int , std::pair< int, int> > > clusters;
163  int size=0;
164 
165  for(i=0;i<diff.size();i++){
166  if(std::abs(diff[i])>n_sigma*std::sqrt(hist->GetBinContent(i+1)+ref->GetBinContent(i+1)*norm)){
167  if(cluster_open){
168  if(i!=0){
169  if(diff[i-1]*diff[i]>0){
170  size++;
171  } else { //diff[i-1]*diff[i]<=0
172  if(size>=cluster_size){
173  bin_start_end.second=i;
174  cluster_size_binStart_binEnd.first=size;
175  cluster_size_binStart_binEnd.second=bin_start_end;
176  clusters.push_back(cluster_size_binStart_binEnd);
177  };
178  cluster_open=false;
179  };
180  } else { //i ===0
181  ERS_INFO("Cluster searching fail");
183  result->tags_["i"] = i;
184  return result;
185  };
186  };
187 
188  if(!cluster_open){
189  cluster_open=true;
190  size=0;
191  bin_start_end.first=i+1;
192  size++;
193  };
194  };
195 
196  if(std::abs(diff[i])<=n_sigma*std::sqrt(hist->GetBinContent(i+1)+ref->GetBinContent(i+1)*norm)){
197  if(cluster_open){
198  if(size>=cluster_size){
199  bin_start_end.second=i;
200  cluster_size_binStart_binEnd.first=size;
201  cluster_size_binStart_binEnd.second=bin_start_end;
202  clusters.push_back(cluster_size_binStart_binEnd);
203  };
204  cluster_open=false;
205  };
206  };
207  if(i==diff.size()-1){
208  if(cluster_open){
209  if(size>=cluster_size){
210  bin_start_end.second=i+1;
211  cluster_size_binStart_binEnd.first=size;
212  cluster_size_binStart_binEnd.second=bin_start_end;
213  clusters.push_back(cluster_size_binStart_binEnd);
214  };
215  cluster_open=false;
216  };
217  };
218  };
219 
220 
221 //Result
222 
224  result->tags_["00-N_clusters"] = clusters.size();
225 
226  std::string Cluster="Cluster_";
227  char num[12];
228  std::string Size="_info_1_size";
229  std::string start_at_bin="_info_2_start_at_bin";
230  std::string finish_at_bin="_info_3_finish_at_bin";
231  std::string message1;
232  std::string message2;
233  std::string message3;
234 
235  for(i=0;i<clusters.size();i++){
236  if((i+1)<10){
237  sprintf(num,"0%u",(i+1));
238  };
239 
240  if((i+1)>=10){
241  sprintf(num,"%u",(i+1));
242  };
243 
244  message1 = Cluster + (std::string) num + Size;
245  message2 = Cluster + (std::string) num + start_at_bin;
246  message3 = Cluster + (std::string) num + finish_at_bin;
247 
248  result->tags_[message1] = clusters[i].first;
249  result->tags_[message2] = clusters[i].second.first;
250  result->tags_[message3] = clusters[i].second.second;
251  };
252 
253 
254  i=0;
255  int flag=0;
256  for(i=0;i<clusters.size();i++){
257  if(clusters[i].first<redTh) flag++;
258  if(clusters[i].first>=redTh) flag+=2;
259  };
260 
261 
262  if (flag<1) {
263  result->status_ = dqm_core::Result::Green;
264  ERS_DEBUG(1,"Green");
265  } else if ( flag>=1 && flag<2 ) {
266  result->status_ = dqm_core::Result::Yellow;
267  ERS_DEBUG(1,"Yellow");
268  } else if (flag>=2) {
269  result->status_ = dqm_core::Result::Red;
270  ERS_DEBUG(1,"Red");
271  }
272 
273  return result;
274 }
275 
276 
277 void
279 {
280  std::string message;
281  message += "\n";
282  message += "Algorithm: \"" + m_name + "\"\n";
283  message += "Description: look for clusters of adiacent bins where each bin differ from reference more then n sigma\n";
284  message += "Mandatory Green/Red Threshold: ClusterSize: the green threshold is the minimum cluster size, each cluster\n";
285  message += " smaller than this size will not recorded as cluster by this algorithm\n";
286  message += " red threshold is the limit size of a cluster, if there is just one cluster\n";
287  message += " bigger then this limit the flag will be red;\n";
288  message += " otherwise the flag will be red if it find more at last 2 clusters\n";
289  message += " N_sigma : maximum distance in standard deviation of a bin of the histo from the reference one\n";
290  message += "Optional Parameters: MinStat = Minimum histogram statistics needed to perform Algorithm\n";
291  message += "\n";
292 
293  out << message;
294 }
295 
296 } // namespace dqm_algorithms
PlotCalibFromCool.norm
norm
Definition: PlotCalibFromCool.py:100
Undefined
@ Undefined
Definition: MaterialTypes.h:8
get_generator_info.result
result
Definition: get_generator_info.py:21
IsA
#define IsA
Declare the TObject style functions.
Definition: xAODTEventBranch.h:59
TrigConf::JetWindowSize::Size
Size
Definition: TriggerThresholdValue.h:17
plotmaker.hist
hist
Definition: plotmaker.py:148
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
mc.diff
diff
Definition: mc.SFGenPy8_MuMu_DD.py:14
JetTiledMap::N
@ N
Definition: TiledEtaPhiMap.h:44
ReweightUtils.message
message
Definition: ReweightUtils.py:15
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
dqm_algorithms::MDTCluster::~MDTCluster
virtual ~MDTCluster()
Definition: MDTCluster.cxx:46
instance
std::map< std::string, double > instance
Definition: Run_To_Get_Tags.h:8
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
lumiFormat.i
int i
Definition: lumiFormat.py:85
dqm_algorithms::MDTCluster
Definition: MDTCluster.h:16
Result
ICscStripFitter::Result Result
Definition: CalibCscStripFitter.cxx:13
master.flag
bool flag
Definition: master.py:29
python.handimod.Green
int Green
Definition: handimod.py:524
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
dqm_algorithms::MDTCluster::execute
virtual dqm_core::Result * execute(const std::string &name, const TObject &object, const dqm_core::AlgorithmConfig &config)
Definition: MDTCluster.cxx:59
MDTCluster.h
trigbs_pickEvents.num
num
Definition: trigbs_pickEvents.py:76
python.handimod.Red
Red
Definition: handimod.py:551
dqm_algorithms::MDTCluster::MDTCluster
MDTCluster()
Definition: MDTCluster.cxx:39
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
dqm_algorithms::MDTCluster::clone
virtual dqm_core::Algorithm * clone()
Definition: MDTCluster.cxx:52
dqm_algorithms
Definition: AddReference.h:17
ref
const boost::regex ref(r_ef)
DeMoScan.first
bool first
Definition: DeMoScan.py:536
RunTileMonitoring.clusters
clusters
Definition: RunTileMonitoring.py:133
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::MDTCluster::m_name
std::string m_name
Definition: MDTCluster.h:29
dqm_algorithms::tools::GetFirstFromMap
double GetFirstFromMap(const std::string &paramName, const std::map< std::string, double > &params)
Definition: AlgorithmHelper.cxx:339
dqm_algorithms::MDTCluster::printDescription
virtual void printDescription(std::ostream &out)
Definition: MDTCluster.cxx:278