17 #include "dqm_core/exceptions.h"
18 #include "dqm_core/AlgorithmConfig.h"
19 #include "dqm_core/AlgorithmManager.h"
20 #include "dqm_core/Result.h"
39 : m_name(
"MDTmultiplicity")
64 if(
object.
IsA()->InheritsFrom(
"TH1" ) ) {
66 if (
hist->GetDimension() >= 2 ){
67 throw dqm_core::BadConfig( ERS_HERE,
name,
"dimension >= 2 " );
70 throw dqm_core::BadConfig( ERS_HERE,
name,
"does not inherit from TH1" );
76 ref =
static_cast<const TH1*
>(
config.getReference() );
78 catch ( dqm_core::Exception & ex ) {
79 throw dqm_core::BadRefHist(ERS_HERE,
name,
" Could not retreive reference");
81 if (
hist->GetDimension() !=
ref->GetDimension() ) {
82 throw dqm_core::BadRefHist( ERS_HERE,
name,
"Reference VS histo: Different dimension!" );
87 double thresh_on_difference=75;
88 double thresh_on_peak_content=15;
109 catch ( dqm_core::Exception & ex ) {
110 throw dqm_core::BadConfig( ERS_HERE,
name, ex.what(), ex );
114 if (
hist->GetEntries() < minstat ) {
115 ERS_INFO(
"Histogram does not satisfy MinStat requirement " <<
hist->GetName());
117 result->tags_[
"InsufficientEntries"] =
hist->GetEntries();
120 ERS_DEBUG(1,
"Statistics: "<<
hist->GetEntries()<<
" entries ");
125 std::vector<double> derivate;
126 std::vector<double> peak_candidate;
127 std::vector<double> peak;
128 std::vector<double> valley;
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;
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));
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;
153 if(derivate[0]>=0) valley.push_back(0);
155 peak_candidate.push_back(0);
156 highest_peak=
hist->GetBinContent(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);
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);
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);
186 valley.push_back(
hist->GetNbinsX());
187 valley_ref.push_back(
hist->GetNbinsX());
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;
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]);
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;
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]);
237 for(
i=0;
i<peak.size();
i++){
238 if(std::abs(peak[
i]-pos1)<=diff1){
240 diff1=std::abs(peak[
i]-pos1);
242 if(std::abs(peak[
i]-pos2)<=diff2){
244 diff2=std::abs(peak[
i]-pos2);
246 if(std::abs(peak[
i]-pos3)<=diff3 && pos3>0){
248 diff3=std::abs(peak[
i]-pos3);
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;
261 std::string peak_tag =
"-Peak";
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];
276 std::vector<double>
diff;
277 std::vector<double> peak_corrispondence;
278 for(
i=0;
i<peak.size();
i++){
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]);
291 for(
i=0;
i<peak.size();
i++){
299 std::string run_tag =
"a-";
300 std::string ref_tag =
"b-";
301 std::string
multi =
"Peak";
304 result->tags_[
"a-00-Number_of_found_peaks"] = peak.size();
305 result->tags_[
"b-00-Number_of_found_peaks_ref"] = peak_ref.size();
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;
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;
326 result->status_ = dqm_core::Result::Yellow;
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";