ATLAS Offline Software
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 
17 namespace
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 
31 {
32 
33  return new MDTTDCOfflineSpectrum( m_name );
34 }
35 
36 
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 ) {
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 
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 
162 void
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 
176 void 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 }
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
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:70
m_name
std::string m_name
Definition: ColumnarPhysliteTest.cxx:62
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
instance
std::map< std::string, double > instance
Definition: Run_To_Get_Tags.h:8
dqm_algorithms::MDTTDCOfflineSpectrum::MDTTDCOfflineSpectrum
MDTTDCOfflineSpectrum(const std::string &name)
Definition: MDTTDCOfflineSpectrum.cxx:23
tags
std::vector< std::string > tags
Definition: hcg.cxx:102
Result
ICscStripFitter::Result Result
Definition: CalibCscStripFitter.cxx:13
dqm_algorithms::MDTTDCOfflineSpectrum::MDTFitTDC
void MDTFitTDC(TH1 *h, double &t0, double &t0err, double &tmax, double &tmaxerr)
Definition: MDTTDCOfflineSpectrum.cxx:176
CalibCoolCompareRT.up
up
Definition: CalibCoolCompareRT.py:108
MDTTDCOfflineSpectrum.h
python.handimod.Green
int Green
Definition: handimod.py:523
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
python.handimod.Red
Red
Definition: handimod.py:550
dqm_algorithms::MDTTDCOfflineSpectrum::execute
dqm_core::Result * execute(const std::string &, const TObject &, const dqm_core::AlgorithmConfig &)
Definition: MDTTDCOfflineSpectrum.cxx:38
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
dqm_algorithms::MDTTDCOfflineSpectrum::clone
MDTTDCOfflineSpectrum * clone()
Definition: MDTTDCOfflineSpectrum.cxx:30
h
MdtMonUtils.MDTFitTDC
def MDTFitTDC(h)
Definition: MdtMonUtils.py:546
AlgorithmHelper.h
dqm_algorithms::MDTTDCOfflineSpectrum
Definition: MDTTDCOfflineSpectrum.h:22
dqm_algorithms::tools::GetFirstFromMap
double GetFirstFromMap(const std::string &paramName, const std::map< std::string, double > &params)
Definition: AlgorithmHelper.cxx:339
dqm_algorithms::MDTTDCOfflineSpectrum::printDescription
void printDescription(std::ostream &out)
Definition: MDTTDCOfflineSpectrum.cxx:163
histogram
std::string histogram
Definition: chains.cxx:52