ATLAS Offline Software
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 
29 static dqm_algorithms::MDTMultiplicity staticInstance;
30 
31 
32 namespace 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 
46 {
47 }
48 
49 
52 {
53  return new MDTMultiplicity(*this);
54 }
55 
56 
58 MDTMultiplicity::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());
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 
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 
337 void
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
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
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
plotmaker.hist
hist
Definition: plotmaker.py:148
python.FakeAthena.Algorithm
def Algorithm(name)
Definition: FakeAthena.py:41
dqm_algorithms::MDTMultiplicity::m_name
std::string m_name
Definition: MDTMultiplicity.h:27
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
mc.diff
diff
Definition: mc.SFGenPy8_MuMu_DD.py:14
PlotCalibFromCool.multi
multi
Definition: PlotCalibFromCool.py:99
ReweightUtils.message
message
Definition: ReweightUtils.py:15
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
dqm_algorithms::MDTMultiplicity::MDTMultiplicity
MDTMultiplicity()
Definition: MDTMultiplicity.cxx:38
instance
std::map< std::string, double > instance
Definition: Run_To_Get_Tags.h:8
lumiFormat.i
int i
Definition: lumiFormat.py:92
Result
ICscStripFitter::Result Result
Definition: CalibCscStripFitter.cxx:13
python.handimod.Green
int Green
Definition: handimod.py:524
dqm_algorithms::MDTMultiplicity::printDescription
virtual void printDescription(std::ostream &out)
Definition: MDTMultiplicity.cxx:338
python.handimod.Red
Red
Definition: handimod.py:551
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
dqm_algorithms
Definition: AddReference.h:17
dqm_algorithms::MDTMultiplicity
Definition: MDTMultiplicity.h:15
ref
const boost::regex ref(r_ef)
TH1
Definition: rootspy.cxx:268
dqm_algorithms::MDTMultiplicity::execute
virtual dqm_core::Result * execute(const std::string &name, const TObject &data, const dqm_core::AlgorithmConfig &config)
Definition: MDTMultiplicity.cxx:58
AlgorithmHelper.h
MDTMultiplicity.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
CaloCondBlobAlgs_fillNoiseFromASCII.tag
string tag
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:24
dqm_algorithms::MDTMultiplicity::clone
virtual dqm_core::Algorithm * clone()
Definition: MDTMultiplicity.cxx:51
dqm_algorithms::tools::GetFirstFromMap
double GetFirstFromMap(const std::string &paramName, const std::map< std::string, double > &params)
Definition: AlgorithmHelper.cxx:339
fitman.k
k
Definition: fitman.py:528
dqm_algorithms::MDTMultiplicity::~MDTMultiplicity
virtual ~MDTMultiplicity()
Definition: MDTMultiplicity.cxx:45