10 #include "TFitResult.h"
37 static const char*
const WILDCARD =
"%";
48 int main(
int argc,
char **argv)
54 typedef JRange<double> JRange_t;
69 JParser<> zap(
"Auxiliary program to fit time-over-threshold distributions.");
71 zap[
'f'] =
make_field(inputFile,
"input file (output from JCalibrateToT).");
73 zap[
'a'] =
make_field(detectorFile,
"detector file.");
74 zap[
'P'] =
make_field(pmtFile,
"specify PMT file name that can be given to JTriggerEfficiency.") =
"";
75 zap[
'w'] =
make_field(writeFits,
"write fit results.");
76 zap[
'x'] =
make_field(X,
"ROOT fit range (time-over-threshold).") = JRange_t(10.0, 35.0);
77 zap[
'O'] =
make_field(option,
"ROOT fit option, see TH1::Fit.") =
"";
78 zap[
'W'] =
make_field(WMin,
"minimal histogram contents.") = 1000.0;
84 catch(
const exception &error) {
85 FATAL(error.what() << endl);
96 load(detectorFile, detector);
98 catch(
const JException& error) {
103 JPMTParametersMap parameters;
107 parameters.load(pmtFile.c_str());
109 catch(
const JException& error) {}
112 parameters.comment.add(JMeta(argc, argv));
115 if (option.find(
'R') == string::npos) { option +=
'R'; }
116 if (option.find(
'S') == string::npos) { option +=
'S'; }
120 TFile* in = TFile::Open(inputFile.c_str(),
"exist");
122 if (in == NULL || !in->IsOpen()) {
123 FATAL(
"File: " << inputFile <<
" not opened." << endl);
127 TH2D gain(
"gain", NULL,
130 TH1D chi2(
"chi2", NULL, 100, 0.0, 5.0);
139 for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
141 DEBUG(
"Module " << module->getID() << endl);
147 TH2D* h2s = (TH2D*) in->Get(
replace(regexp, WILDCARD,
MAKE_STRING(module->getID())).c_str());
151 WARNING(
"No histogram " << module->getID() <<
"; skip fit." << endl);
156 const int ny = h2s->GetYaxis()->GetNbins();
157 const double ymin = h2s->GetYaxis()->GetXmin();
158 const double ymax = h2s->GetYaxis()->GetXmax();
164 for (
int ix = 1; ix <= h2s->GetXaxis()->GetNbins(); ++ix) {
166 const JPMTIdentifier id(module->getID(), ix-1);
168 TH1D h1(
MAKE_CSTRING(module->getID() <<
"." <<
id.getPMTAddress() <<
".1ToT"), NULL, ny, ymin, ymax);
174 for (
int iy = 1; iy <= h2s->GetNbinsY(); ++iy) {
176 const double x = h1.GetBinCenter(iy);
177 const double z = h1.GetBinWidth (iy);
178 const double y = h2s->GetBinContent(ix, iy);
184 h1.SetBinContent(iy, y/z);
185 h1.SetBinError (iy, sqrt(y)/z);
190 WARNING(
"Not enough entries for PMT " <<
id <<
' ' << W <<
"; skip fit." << endl);
195 h1.Scale(1.0/h1.Integral());
202 JFitToT fit(parameters.getPMTParameters(
id),
204 min(ymax, X.second));
207 const TFitResultPtr
result = fit(h1, option.c_str());
209 chi2.Fill(TMath::Log10(
result->Chi2() /
result->Ndf()));
212 cout <<
"PMT " <<
id <<
" chi2 / NDF " <<
result->Chi2() <<
' ' <<
result->Ndf() <<
' ' << (
result->IsValid() ?
"" :
"failed") << endl;
217 WARNING(
"Fit failure for PMT " <<
id <<
"; skip." << endl);
222 if (ymin < X.getLowerLimit() || ymax > X.getUpperLimit()) {
226 TF1* p =
new TF1(
"f1&",
230 JFitToT::getNumberOfModelParameters());
232 p->SetParameters(fit.GetParameters());
235 h1.GetListOfFunctions()->Add(p);
241 const JFitToTParameters values(fit.GetParameters());
242 const JFitToTParameters errors(fit.GetParErrors());
244 chi2_1d. SetBinContent(ix,
result->Chi2() /
result->Ndf());
245 gain_1d. SetBinContent(ix, values.gain);
246 gain_1d. SetBinError (ix, errors.gain);
247 gainspread_1d.SetBinContent(ix, values.gainSpread);
248 gainspread_1d.SetBinError (ix, errors.gainSpread);
250 gain.Fill(fit.gain, fit.gainSpread);
252 if (fit.gain > 0.0) {
254 parameters[id].gain = fit.gain;
255 parameters[id].gainSpread = fit.gainSpread;
259 WARNING(
"Error fit of PMT " <<
id <<
"; set default values." << endl);
261 parameters[id].gain = 0.0;
262 parameters[id].gainSpread = parameters.getDefaultPMTParameters().gainSpread;
271 out << chi2_1d << gain_1d << gainspread_1d;
276 parameters.store(pmtFile.c_str());