ATLAS Offline Software
Loading...
Searching...
No Matches
MDTMultiplicity.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: MDTMultiplicity.cxx,v 2.0 2008/10/08 Valerio Consorti
7// **********************************************************************
8
10
11
12
13#include <TClass.h>
14#include <TH1.h>
15#include <TF1.h>
16
17#include "dqm_core/exceptions.h"
18#include "dqm_core/AlgorithmConfig.h"
19#include "dqm_core/AlgorithmManager.h"
20#include "dqm_core/Result.h"
22#include "ers/ers.h"
23#include <cmath>
24#include <iostream>
25#include <map>
26#include <vector>
27#include <string>
28
30
31
32namespace dqm_algorithms {
33
34// *********************************************************************
35// Public Methods
36// *********************************************************************
37
39 : m_name("MDTmultiplicity")
40{
41 dqm_core::AlgorithmManager::instance().registerAlgorithm( m_name, this );
42}
43
44
48
49
50dqm_core::Algorithm*
52{
53 return new MDTMultiplicity(*this);
54}
55
56
57dqm_core::Result*
58MDTMultiplicity::execute( const std::string& name, const TObject& object, const dqm_core::AlgorithmConfig& config)
59{
60
61 const TH1 * hist;
62 const 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 Reference Histo
74
75 try {
76 ref = static_cast<const TH1*>( config.getReference() );
77 }
78 catch ( dqm_core::Exception & ex ) {
79 throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference");
80 }
81 if (hist->GetDimension() != ref->GetDimension() ) {
82 throw dqm_core::BadRefHist( ERS_HERE, name, "Reference VS histo: Different dimension!" );
83 }
84
85 //Get Parameters and Thresholds
86 double minstat;
87 double thresh_on_difference=75;
88 double thresh_on_peak_content=15;
89 //double peak_number=2;
90 double pos1=3;
91 double pos2=6;
92 double pos3=-1;
93 double greenTh=1;
94 double redTh=2;
95 double ref_y_n=1;
96
97 try {
98 minstat = dqm_algorithms::tools::GetFirstFromMap("MinStat", config.getParameters(), 100);
99 thresh_on_difference = dqm_algorithms::tools::GetFirstFromMap("IsolationThresh", config.getParameters(), 75);
100 thresh_on_peak_content = dqm_algorithms::tools::GetFirstFromMap("StatisticThresh", config.getParameters(), 15);
101 //peak_number = dqm_algorithms::tools::GetFirstFromMap("NumberOfPeaks", config.getParameters());
102 pos1 = dqm_algorithms::tools::GetFirstFromMap("FirstPeakPosition", config.getParameters(), 4);
103 pos2 = dqm_algorithms::tools::GetFirstFromMap("SecondPeakPosition", config.getParameters(), 8);
104 pos3 = dqm_algorithms::tools::GetFirstFromMap("ThirdPeakPosition", config.getParameters(), -1);
105 ref_y_n = dqm_algorithms::tools::GetFirstFromMap("UseRef", config.getParameters(), 0);
106 redTh = dqm_algorithms::tools::GetFromMap( "PeakShift", config.getRedThresholds());
107 greenTh = dqm_algorithms::tools::GetFromMap( "PeakShift", config.getGreenThresholds() );
108 }
109 catch ( dqm_core::Exception & ex ) {
110 throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex );
111 }
112
113 //Check of statistics
114 if (hist->GetEntries() < minstat ) {
115 ERS_INFO("Histogram does not satisfy MinStat requirement " <<hist->GetName());
116 dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined);
117 result->tags_["InsufficientEntries"] = hist->GetEntries();
118 return result;
119 }
120 ERS_DEBUG(1,"Statistics: "<< hist->GetEntries()<< " entries ");
121
122 //Algo
123 unsigned int i=0;
124 unsigned int k=0;
125 std::vector<double> derivate;
126 std::vector<double> peak_candidate;
127 std::vector<double> peak;
128 std::vector<double> valley;
129
130 std::vector<double> derivate_ref;
131 std::vector<double> peak_candidate_ref;
132 std::vector<double> peak_ref;
133 std::vector<double> valley_ref;
134
135 //Filling vector of derivate
136 for(i=1;i<=(unsigned int)hist->GetNbinsX();i++){
137 if((i+1)<=(unsigned int)hist->GetNbinsX()) derivate.push_back(hist->GetBinContent(i+1)-hist->GetBinContent(i));
138 if((i+1)<=(unsigned int)ref->GetNbinsX() && ref_y_n==1) derivate_ref.push_back(ref->GetBinContent(i+1)-ref->GetBinContent(i));
139 };
140
141 i=0;
142
143 //Look for peaks and valley
144 Double_t highest_peak=0;
145 Double_t peak_content;
146 Double_t first_valley_content;
147 Double_t second_valley_content;
148 Double_t highest_peak_ref=0;
149 Double_t peak_content_ref;
150 Double_t first_valley_content_ref;
151 Double_t second_valley_content_ref;
152
153 if(derivate[0]>=0) valley.push_back(0);
154 if(derivate[0]<0){
155 peak_candidate.push_back(0);
156 highest_peak=hist->GetBinContent(1);
157 }
158 if(ref_y_n==1){
159 if(derivate_ref[0]>=0) valley_ref.push_back(0);
160 if(derivate_ref[0]<0){
161 peak_candidate_ref.push_back(0);
162 highest_peak_ref=ref->GetBinContent(1);
163 }
164 };
165
166 for(i=0;i<(derivate.size()-1);i++){
167 if(derivate[i]>0 && derivate[i+1]<0){
168 peak_candidate.push_back(i+1);
169 peak_content=hist->GetBinContent(i+2);
170 if(peak_content>highest_peak) highest_peak=peak_content;
171 }else if(derivate[i]<0 && derivate[i+1]>0){
172 valley.push_back(i+1);
173 };
174
175 if(ref_y_n==1){
176 if(derivate_ref[i]>0 && derivate_ref[i+1]<0){
177 peak_candidate_ref.push_back(i+1);
178 peak_content_ref=ref->GetBinContent(i+2);
179 if(peak_content_ref>highest_peak_ref) highest_peak_ref=peak_content_ref;
180 }else if(derivate_ref[i]<0 && derivate_ref[i+1]>0){
181 valley_ref.push_back(i+1);
182 };
183 };
184 };
185
186 valley.push_back(hist->GetNbinsX());
187 valley_ref.push_back(hist->GetNbinsX());
188
189 //Peak Definition (isolation and high statistic)
190 i=0;
191
192 for(i=0;i<peak_candidate.size();i++){
193 peak_content=hist->GetBinContent((Int_t)peak_candidate[i]+1);
194 first_valley_content=hist->GetBinContent((Int_t)valley[i]+1);
195 second_valley_content=hist->GetBinContent((Int_t)valley[i+1]+1);
196 if(first_valley_content==0) first_valley_content=1;
197 if(second_valley_content==0) second_valley_content=1;
198
199 if((first_valley_content<=second_valley_content) && (peak_content>(thresh_on_peak_content*highest_peak/100)) && (first_valley_content<(thresh_on_difference*peak_content/100))){
200 peak.push_back(peak_candidate[i]);
201 }else if((first_valley_content>second_valley_content) && (peak_content>(thresh_on_peak_content*highest_peak/100)) && (second_valley_content<(thresh_on_difference*peak_content/100))){
202 peak.push_back(peak_candidate[i]);
203 };
204 };
205
206 i=0;
207 if(ref_y_n==1){
208 for(i=0;i<peak_candidate_ref.size();i++){
209 peak_content_ref=ref->GetBinContent((Int_t)peak_candidate_ref[i]+1);
210 first_valley_content_ref=ref->GetBinContent((Int_t)valley_ref[i]+1);
211 second_valley_content_ref=ref->GetBinContent((Int_t)valley_ref[i+1]+1);
212 if(first_valley_content_ref==0) first_valley_content_ref=1;
213 if(second_valley_content_ref==0) second_valley_content_ref=1;
214
215 if((first_valley_content_ref<=second_valley_content_ref) && (peak_content_ref>(thresh_on_peak_content*highest_peak_ref/100)) && (first_valley_content_ref<(thresh_on_difference*peak_content_ref/100))){
216 peak_ref.push_back(peak_candidate_ref[i]);
217 }else if((first_valley_content_ref>second_valley_content_ref) && (peak_content_ref>(thresh_on_peak_content*highest_peak_ref/100)) && (second_valley_content_ref<(thresh_on_difference*peak_content_ref/100))){
218 peak_ref.push_back(peak_candidate_ref[i]);
219 };
220 };
221 };
222
223 //Result
224
225 dqm_core::Result* result = new dqm_core::Result();
226
227 double count=0;
228 //double first_peak=-1;
229 //double second_peak=-1;
230 //double third_peak=-1;
231 double diff1=9999;
232 double diff2=9999;
233 double diff3=9999;
234
235 if(ref_y_n==0){
236 i=0;
237 for(i=0;i<peak.size();i++){
238 if(std::abs(peak[i]-pos1)<=diff1){
239 //first_peak=i;
240 diff1=std::abs(peak[i]-pos1);
241 };
242 if(std::abs(peak[i]-pos2)<=diff2){
243 //second_peak=i;
244 diff2=std::abs(peak[i]-pos2);
245 };
246 if(std::abs(peak[i]-pos3)<=diff3 && pos3>0){
247 //third_peak=i;
248 diff3=std::abs(peak[i]-pos3);
249 };
250 };
251 //if(peak.size() != peak_number) count = 10;
252 if(diff1>greenTh) count++;
253 if(diff2>greenTh) count++;
254 if(diff3>greenTh && pos3>0) count++;
255 if(diff1>redTh) count+=2;
256 if(diff2>redTh) count+=2;
257 if(diff3>redTh && pos3>0) count+=2;
258
259 i=0;
260 std::string tag_n_r;
261 std::string peak_tag = "-Peak";
262 char numb_n_r[4];
263
264 result->tags_["00-Number_of_found_peaks"] = peak.size();
265 for(i=0;i<peak.size();i++){
266 if(i<10) snprintf(numb_n_r,sizeof(numb_n_r),"0%u",(i+1));
267 if(i>=10) snprintf(numb_n_r,sizeof(numb_n_r),"%u",(i+1));
268 tag_n_r=(std::string)numb_n_r+peak_tag;
269 result->tags_[tag_n_r] = peak[i];
270 };
271 };
272
273 if(ref_y_n==1){
274 i=0;
275 k=0;
276 std::vector<double> diff;
277 std::vector<double> peak_corrispondence;
278 for(i=0;i<peak.size();i++){
279 diff1=9999;
280 peak_corrispondence.push_back(99999);
281 diff.push_back(99999);
282 for(k=0;k<peak_ref.size();k++){
283 if(std::abs(peak[i]-peak_ref[k])<=diff1){
284 peak_corrispondence[i]=k;
285 diff[i]=std::abs(peak[i]-peak_ref[k]);
286 diff1=std::abs(peak[i]-peak_ref[k]);
287 };
288 };
289 };
290 i=0;
291 for(i=0;i<peak.size();i++){
292 if(diff[i]>greenTh) count++;
293 if(diff[i]>redTh) count+=2;
294 };
295
296 //if(peak.size()!=peak_ref.size()) count+=10;
297
298 std::string tag;
299 std::string run_tag ="a-";
300 std::string ref_tag ="b-";
301 std::string multi = "Peak";
302 char numb[4];
303
304 result->tags_["a-00-Number_of_found_peaks"] = peak.size();
305 result->tags_["b-00-Number_of_found_peaks_ref"] = peak_ref.size();
306
307 for(i=0;i<peak.size();i++){
308 if(i<10) snprintf(numb,sizeof(numb),"0%u",(i+1));
309 if(i>=10) snprintf(numb,sizeof(numb),"%u",(i+1));
310 tag=run_tag+(std::string)numb+multi;
311 result->tags_[tag] = peak[i];
312 };
313 i=0;
314 for(i=0;i<peak_ref.size();i++){
315 if(i<10) snprintf(numb,sizeof(numb),"0%u",(i+1));
316 if(i>=10) snprintf(numb,sizeof(numb),"%u",(i+1));
317 tag=ref_tag+(std::string)numb+multi;
318 result->tags_[tag] = peak_ref[i];
319 };
320 };
321
322 if(count==0){
323 result->status_ = dqm_core::Result::Green;
324 };
325 if(count>=1 && count<3){
326 result->status_ = dqm_core::Result::Yellow;
327 };
328 if(count>=3){
329 result->status_ = dqm_core::Result::Red;
330 };
331
332 // Return the result
333 return result;
334}
335
336
337void
339 std::string message;
340 message += "\n";
341 message += "Algorithm: \"" + m_name + "\"\n";
342 message += "Description: it look for peaks in the histogram and it compare their position with user defined position or with reference histogram peak position. The algorithm define a peak first looking for the higher statistic bin then it look for other bins with at last a user defined percent of the entrance of the maximum bin \n";
343 message += "Green/Red Thresh: PeakShift: the number of bins tollerated for the shift of a peak\n";
344 message += "Mandatory Params: MinStat: minimum statistical requirement\n";
345 message += " IsolationThresh: The alghorithm need it to define a peak. It define the minumum difference,in percent, between the peak entrance and the closer 'valley' entrance(valley is defined as the bin where the derivate change sign from negative to positive).\n";
346 message += " StatisticThresh: The minimum bin entrance required expressed in percent compared with the maximum bin. If the bin has less then this percent of entrance it can't be defined as a peak.\n";
347 message += " FirstPeakPosition: Mandatory in no reference mode. It is the position expected for the first peak\n";
348 message += " SecondPeakPosition: Mandatory in no reference mode. It is the position expected for the second peak\n";
349 message += " ThirdPeakPosition: Mandatory in no reference mode. It is the position expected for the third peak\n";
350 message += " UseRef: 1 to use a reference histogram, 0 to use user definition for the peaks position without a reference comparison\n";
351 message += "Optional Params: NumberOfPeaks: In the no reference mode it define how many peaks the algorithm has to looking for. if it find more then this number of peack it set the flag red\n";
352 out << message;
353}
354
355} // 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::Algorithm * clone()
virtual dqm_core::Result * execute(const std::string &name, const TObject &data, const dqm_core::AlgorithmConfig &config)
virtual void printDescription(std::ostream &out)
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146
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.