ATLAS Offline Software
Loading...
Searching...
No Matches
MDTTDCOfflineSpectrum.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6#include <dqm_core/AlgorithmConfig.h>
9#include <TF1.h>
10#include <TClass.h>
11#include <ers/ers.h>
12
13#include <iostream>
14
15#include <dqm_core/AlgorithmManager.h>
16
17namespace
18{
19 dqm_algorithms::MDTTDCOfflineSpectrum MDTTDCOfflineSpectrum( "AlgMDTTDCOfflineSpectrum" );
20}
21
22
24 : m_name( name )
25{
26 dqm_core::AlgorithmManager::instance().registerAlgorithm(name, this);
27}
28
35
36
37dqm_core::Result *
39 const TObject & object,
40 const dqm_core::AlgorithmConfig & config )
41{
42
43
44 if (!object.IsA()->InheritsFrom("TH1")) {
45 throw dqm_core::BadConfig(ERS_HERE, name, "does not inherit from TH1");
46 }
47 std::unique_ptr<TH1> histogram(static_cast<TH1 *>(object.Clone())); // we just checked that this is really a TH1, so we can safely type-cast the pointer
48 if (histogram->GetDimension() > 2) {
49 throw dqm_core::BadConfig(ERS_HERE, name, "dimension > 2");
50 }
51
52 const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1);
53
54 if (histogram->GetEntries() < minstat ) {
55 dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined);
56 result->tags_["InsufficientEntries"] = histogram->GetEntries();
57 return result;
58 }
59
60 double t0_low_warning;
61 double t0_low_error;
62 double t0_high_warning;
63 double t0_high_error;
64 double tmax_low_warning;
65 double tmax_low_error;
66 double tmax_high_warning;
67 double tmax_high_error;
68 try {
69 t0_low_warning = dqm_algorithms::tools::GetFirstFromMap( "t0_low_Warning", config.getParameters() );
70 t0_low_error = dqm_algorithms::tools::GetFirstFromMap( "t0_low_Error", config.getParameters() );
71 t0_high_warning = dqm_algorithms::tools::GetFirstFromMap( "t0_high_Warning", config.getParameters() );
72 t0_high_error = dqm_algorithms::tools::GetFirstFromMap( "t0_high_Error", config.getParameters() );
73 tmax_low_warning = dqm_algorithms::tools::GetFirstFromMap( "tMax_low_Warning", config.getParameters() );
74 tmax_low_error = dqm_algorithms::tools::GetFirstFromMap( "tMax_low_Error", config.getParameters() );
75 tmax_high_warning = dqm_algorithms::tools::GetFirstFromMap( "tMax_high_Warning", config.getParameters() );
76 tmax_high_error = dqm_algorithms::tools::GetFirstFromMap( "tMax_high_Error", config.getParameters() );
77 }
78 catch ( dqm_core::Exception & ex ) {
79 throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex );
80 }
81
82
83 dqm_core::Result* result = new dqm_core::Result();
84
85 double t0;
86 double tmax;
87 double tdrift;
88 double t0Err;
89 double tmaxErr;
90
91 TF1* t0Fit = histogram->GetFunction("func1");
92 TF1* tmaxFit = histogram->GetFunction("func2");
93
94 if(!t0Fit || !tmaxFit){
95 MDTFitTDC(histogram.get(), t0, t0Err, tmax, tmaxErr);
96 tdrift = tmax - t0;
97 }else{
98 t0 = t0Fit->GetParameter(1);
99 tmax = tmaxFit->GetParameter(1);
100 tdrift = tmax - t0;
101 t0Err = t0Fit->GetParameter(2);
102 tmaxErr = tmaxFit->GetParameter(2);
103 }
104
105
106 ERS_DEBUG(1, m_name << " TDrift " << " is " << tdrift );
107 ERS_DEBUG(1,"Green threshold: "<< t0_low_warning << " < t0 < "<< t0_high_warning << " && " << tmax_low_warning <<" < tmax < " << tmax_high_warning <<
108 " ; Red threshold : t0 < " << t0_low_error << "\n" <<
109 "t0 > " << t0_high_error << "\n" <<
110 "tmax > " << tmax_high_error << "\n" <<
111 "tmax < " << tmax_low_error
112 );
113
114 std::map<std::string,double> tags;
115
116 if (t0 > t0_low_warning && t0 < t0_high_warning && tmax < tmax_high_warning && tmax > tmax_low_warning && std::abs(tdrift) < 1000) {
117 result->status_ = dqm_core::Result::Green;
118 }
119 else if (t0 > t0_low_error && t0 < t0_high_error && tmax < tmax_high_error && tmax > tmax_low_error && std::abs(tdrift) < 1200) {
120 if(t0 < t0_low_warning) tags["t0_low_Warning"] = t0;
121 else if(t0 > t0_high_warning) tags["t0_high_Warning"] = t0;
122 else tags["t0"] = t0;
123 if(tmax > tmax_high_warning) tags["tMax_high_Warning"] = tmax;
124 else if(tmax < tmax_low_warning) tags["tMax_low_Warning"] = tmax;
125 else tags["tMax"] = tmax;
126 if( std::abs(tdrift) > 1200 ) tags["tDrift_Warning"] = tdrift;
127 else tags["tdrift"] = tdrift;
128 result->status_ = dqm_core::Result::Yellow;
129 }
130 else {
131 result->status_ = dqm_core::Result::Red;
132 if(t0 < t0_low_error) tags["t0_low_Error"] = t0;
133 else if(t0 > t0_high_error) tags["t0_high_Error"] = t0;
134 else tags["t0"] = t0;
135 if(tmax > tmax_high_error) tags["tMax_high_Error"] = tmax;
136 else if(tmax < tmax_low_error) tags["tMax_low_Error"] = tmax;
137 else tags["tMax"] = tmax;
138 if( std::abs(tdrift) > 1400 ) tags["tDrift_Error"] = tdrift;
139 else tags["tdrift"] = tdrift;
140 }
141
142 if(tags.size()==0) {
143 tags["t0"] = t0;
144 tags["tmax"] = tmax;
145 tags["tdrift"] = tdrift;
146 }
147 if(t0Err > 2.*t0){
148 tags["t0_FitError"] = t0Err;
149 result->status_ = dqm_core::Result::Red;
150 }
151 if(tmaxErr > 2.*tmax) {
152 tags["tmax_FitError"] = tmaxErr;
153 result->status_ = dqm_core::Result::Red;
154 }
155
156 result->tags_ = std::move(tags);
157
158 return result;
159
160}
161
162void
164{
165
166 out << "Analyze pre-fitted MDTTDC spectra histograms" << std::endl;
167 out << "Required Parameters: name " << m_name << ", t0Warning threshold" << ", tMaxWarning threshold" << std::endl;
168 out << "Required parameters: t0Error" << ", tMaxError " << std::endl;
169 out << "Returns yellow if t0 < t0Warning or t0 > 800 or if tMax > tMaxWarning or tMax < 800" << std::endl;
170 out << "Returns red if t0 < t0Error or t0 > 1000 or if tMax > tMaxError or tMax < 700" << std::endl;
171 out << "Returns red if t0Err > 2.*t0 or tMaxErr > 2.*tMax" << std::endl;
172 out << "Requires that a histogram has a function named \"func1\" for the t0 fit and \"func2\" for the tMax fit" << std::endl;
173
174}
175
176void dqm_algorithms::MDTTDCOfflineSpectrum::MDTFitTDC(TH1* h, double &t0, double &t0err, double &tmax, double &tmaxerr)
177{
178 t0 = tmax = 0;
179 t0err = tmaxerr = 0;
180 double up = h->GetBinCenter(h->GetMaximumBin()+1);
181 if( up > 200 ) up = 200;
182 double down = up + 650;
183 if( up < 50 ) up = 50;
184 double parESD0 = h->GetBinContent(h->GetMinimumBin());
185 double parESD1 = up;
186 double parESD2 = 20;
187 double parESD3 = h->GetBinContent(h->GetMaximumBin()) - h->GetBinContent(h->GetMinimumBin());
188 std::unique_ptr<TF1> func1 = std::make_unique<TF1>("func1", "[0]+([3]/(1+(TMath::Exp((-x+[1])/[2]))))", 0, up); // tzero
189 func1->SetParameters(parESD0, parESD1, parESD2, parESD3);
190 if(h->GetEntries()>100){
191 h->Fit("func1","NRQ");
192 t0 = func1->GetParameter(1) ;
193 t0err = func1->GetParError(1);
194 double binAtT0 = (double)h->GetBinContent(h->FindBin(t0));
195 if(binAtT0<1) binAtT0 = 1;
196 t0err += 10.0 * func1->GetChisquare() / (0.01*binAtT0*binAtT0*(double)func1->GetNumberFitPoints()); // to additionally account for bad fits
197 }
198
199 parESD0 = h->GetBinContent(h->GetMinimumBin());
200 parESD1 = down;
201 parESD2 = 50;
202 parESD3 = (h->GetBinContent(h->GetMaximumBin())-h->GetBinContent(h->GetMinimumBin()))/10.;
203 std::unique_ptr<TF1> func2 = std::make_unique<TF1>("func2", "[0]+([3]/(1+(TMath::Exp((x-[1])/[2]))))", down-135, down+135); // tmax
204 func2->SetParameters(parESD0,parESD1,parESD2,parESD3);
205 if(h->GetEntries()>100){
206 func2->SetParLimits(0, parESD0, 2.0*parESD0+1);
207 func2->SetParLimits(2, 5, 90);
208 func2->SetParLimits(3, 0.2*parESD3, 7*parESD3);
209 h->Fit("func2","WWNRQ+");
210 tmax = func2->GetParameter(1);
211 tmaxerr = func2->GetParError(1);
212 double binAtTmax = (double)h->GetBinContent(h->FindBin(tmax));
213 if(binAtTmax<1) binAtTmax = 1;
214 tmaxerr += 10.0 * func2->GetChisquare() / (0.01*binAtTmax*binAtTmax*(double)func2->GetNumberFitPoints()); // to additionally account for bad fits
215 }
216
217}
static Double_t t0
author Elena Solfaroli and Valerio Consorti.
std::string histogram
Definition chains.cxx:52
Header file for AthHistogramAlgorithm.
std::vector< std::string > tags
Definition hcg.cxx:105
double GetFirstFromMap(const std::string &paramName, const std::map< std::string, double > &params)
dqm_core::Result * execute(const std::string &, const TObject &, const dqm_core::AlgorithmConfig &)
void MDTFitTDC(TH1 *h, double &t0, double &t0err, double &tmax, double &tmaxerr)
#define IsA
Declare the TObject style functions.