ATLAS Offline Software
Loading...
Searching...
No Matches
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>
31
32
33namespace 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
49
50
51dqm_core::Algorithm*
53{
54 return new MDTCluster(*this);
55}
56
57
58dqm_core::Result*
59MDTCluster::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());
108 dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined);
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());
124 dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined);
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());
131 dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined);
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");
182 dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined);
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
223 dqm_core::Result* result = new dqm_core::Result();
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
277void
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
const boost::regex ref(r_ef)
static dqm_algorithms::AveragePrint staticInstance
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
Definition Jet.cxx:631
virtual dqm_core::Result * execute(const std::string &name, const TObject &object, const dqm_core::AlgorithmConfig &config)
virtual dqm_core::Algorithm * clone()
virtual void printDescription(std::ostream &out)
double GetFirstFromMap(const std::string &paramName, const std::map< std::string, double > &params)
const T & GetFromMap(const std::string &pname, const std::map< std::string, T > &params)
#define IsA
Declare the TObject style functions.