61int main(
int argc,
char **argv)
77 bool overwriteDetector;
101 JParser<> zap(
"Auxiliary program to fit PMT parameters from JMergeCalibrateK40 output.");
104 zap[
'f'] =
make_field(inputFile,
"input file (output from JMergeCalibrateK40).");
106 zap[
'a'] =
make_field(detectorFile,
"detector file.");
107 zap[
'P'] =
make_field(pmtFile,
"specify PMT file name that can be given to JTriggerEfficiency.") =
"";
109 "Fix time offset(s) of PMT(s) of certain module(s), e.g."
110 "\n-! \"808969848 0 808982077 23\" will fix time offsets of PMT 0 of module 808969848 and of PMT 23 of module 808982077."
111 "\nSame PMT offset can be fixed for all optical modules, e.g."
112 "\n-! \"-1 0 -1 23\" will fix time offsets of PMTs 0 and 23 of all optical modules.") =
JPARSER::initialised();
113 zap[
'r'] =
make_field(reverse,
"reverse TDC constraints due to option -! <TDC>.");
114 zap[
'A'] =
make_field(overwriteDetector,
"overwrite detector file provided through '-a' with fitted time offsets.");
115 zap[
'w'] =
make_field(writeFits,
"write fit results to ROOT file; -ww also write fitted TTS to PMT file.");
116 zap[
'D'] =
make_field(fitAngle,
"fit angular distribution; fix normalisation.");
117 zap[
'B'] =
make_field(fitNoise,
"fit background.");
118 zap[
'M'] =
make_field(fitModel,
"fit angular distribution as well as normalisation; fix PMT QEs = 1.0.");
119 zap[
'Q'] =
make_field(fixQE,
"fix PMT QEs = 1.0.");
126 catch(
const exception &error) {
127 FATAL(error.what() << endl);
131 if ((fitModel ? 1 : 0) +
134 (fixQE ? 1 : 0) > 1) {
135 FATAL(
"Use either option -M, -D, -B or -Q" << endl);
148 for (JTDC_t::const_iterator i = TDC.begin(); i != TDC.end(); ++i) {
149 DEBUG(
"PMT " << setw(10) << i->first <<
' ' << setw(2) << i->second <<
" constrain t0." << endl);
155 catch(
const exception &error) {
156 FATAL(error.what() << endl);
173 parameters.
load(pmtFile.c_str());
175 catch(
const exception& error) {}
181 TFile* in = TFile::Open(inputFile.c_str(),
"exist");
183 if (in == NULL || !in->IsOpen()) {
184 FATAL(
"File: " << inputFile <<
" not opened." << endl);
190 TH1D h0(
"chi2", NULL, 500, 0.0, 5.0);
191 TH1D hn(
"hn", NULL, 501, -0.5, 500.0);
192 TH1D hr(
"rate", NULL, 500, 0.0, 25.0);
193 TH1D h1(
"p1", NULL, 500, -5.0, +5.0);
194 TH1D h2(
"p2", NULL, 500, -5.0, +5.0);
195 TH1D h3(
"p3", NULL, 500, -5.0, +5.0);
196 TH1D h4(
"p4", NULL, 500, -5.0, +5.0);
197 TH1D hc(
"cc", NULL, 500, -0.1, +0.1);
202 TH2D H2(
"detector", NULL,
203 string.size() + 0, -0.5,
string.size() - 0.5,
206 for (Int_t i = 1; i <= H2.GetXaxis()->GetNbins(); ++i) {
207 H2.GetXaxis()->SetBinLabel(i,
MAKE_CSTRING(
string.at(i-1)));
209 for (Int_t i = 1; i <= H2.GetYaxis()->GetNbins(); ++i) {
216 for (JDetector::iterator module =
detector.begin(); module !=
detector.end(); ++module) {
218 if (module->getFloor() == 0) {
224 NOTICE(
"Module " << setw(10) << module->getID() <<
' ' <<
getLabel(module->getLocation()) <<
" !" <<
distance(range.first, range.second) << endl);
228 if (h2d == NULL || h2d->GetEntries() == 0) {
230 NOTICE(
"No data for module " << module->getID() <<
" -> set QEs to 0." << endl);
246 for (
int ix = 1; ix <= h2d->GetXaxis()->GetNbins(); ++ix) {
250 auto& buffer = data[
pair];
255 for (
int iy = 1; iy <= h2d->GetYaxis()->GetNbins(); ++iy) {
257 const double x = h2d->GetXaxis()->GetBinCenter(ix);
258 const double y = h2d->GetYaxis()->GetBinCenter(iy);
262 double value = h2d->GetBinContent(ix,iy);
263 double error = h2d->GetBinError (ix,iy);
265 buffer.push_back(
rate_type(y, value, error));
267 double width = h2d->GetYaxis()->GetBinWidth(iy);
279 if (V <= 0.0 - STDEV*W) {
280 count[0][
pair.first] += 1;
281 count[0][
pair.second] += 1;
284 if (V <= MINIMAL_RATE_HZ + STDEV*W) {
285 count[1][
pair.first] += 1;
286 count[1][
pair.second] += 1;
292 if (count[0][pmt] >= MAXIMAL_COUNTS) {
294 WARNING(
"PMT " << setw(10) << module->getID() <<
'.' <<
FILL(2,
'0') << pmt <<
FILL() <<
" some rates negative -> fit background" << endl);
296 if (fit.value.parameters[pmt].status) {
297 model.parameters[pmt].bg.set();
301 if (count[1][pmt] == NUMBER_OF_PMTS) {
303 WARNING(
"PMT " << setw(10) << module->getID() <<
'.' <<
FILL(2,
'0') << pmt <<
FILL() <<
" all rates to low -> disable" << endl);
305 model.parameters[pmt].disable();
309 DEBUG(
"Start value:" << endl <<
model << endl);
321 if (fit.value.parameters[pmt].QE() < QE_MIN && fit.value.parameters[pmt].status) {
323 WARNING(
"PMT " << setw(10) << module->getID() <<
'.' <<
FILL(2,
'0') << pmt <<
FILL() <<
' ' <<
FIXED(5,3) << fit.value.parameters[pmt].QE() <<
" < " <<
FIXED(5,3) << QE_MIN <<
" -> disable" << (!refit ?
" and refit" :
"") << endl);
325 fit.value.parameters[pmt].disable();
336 NOTICE(
"Fit result " << setw(10) << module->getID() <<
" chi2 / NDF " <<
FIXED(10,2) <<
result.chi2 <<
" / " << setw(5) <<
result.ndf <<
' ' << setw(5) << fit.numberOfIterations << endl);
343 hn.Fill(fit.numberOfIterations);
344 hr.Fill(fit.value.R );
345 h1.Fill(fit.value.p1);
346 h2.Fill(fit.value.p2);
347 h3.Fill(fit.value.p3);
348 h4.Fill(fit.value.p4);
349 hc.Fill(fit.value.cc);
351 TH1D h1t(
MAKE_CSTRING(module->getID() <<
".1t0"), NULL, NUMBER_OF_PMTS, -0.5, NUMBER_OF_PMTS - 0.5);
352 TH1D h1s(
MAKE_CSTRING(module->getID() <<
".1TTS"), NULL, NUMBER_OF_PMTS, -0.5, NUMBER_OF_PMTS - 0.5);
353 TH1D h1q(
MAKE_CSTRING(module->getID() <<
".1QE"), NULL, NUMBER_OF_PMTS, -0.5, NUMBER_OF_PMTS - 0.5);
356 h1t.SetBinContent(pmt + 1, fit.value.parameters[pmt].t0 ());
357 h1s.SetBinContent(pmt + 1, fit.value.parameters[pmt].TTS());
358 h1q.SetBinContent(pmt + 1, fit.value.parameters[pmt].QE ());
361 out << h1t << h1s << h1q;
363 for (
int ix = 1; ix <= h2d->GetXaxis()->GetNbins(); ++ix) {
367 for (
int iy = 1; iy <= h2d->GetYaxis()->GetNbins(); ++iy) {
369 const double dt_ns = h2d->GetYaxis()->GetBinCenter(iy);
371 h2d->SetBinContent(ix, iy, fit.value.getValue(
pair, dt_ns));
372 h2d->SetBinError (ix, iy, 0.0);
379 H2.Fill((
double)
string.
getIndex(module->getString()), (
double) module->getFloor(),
result.chi2 /
result.ndf);
382 const double t0 = (fit.value.hasFixedTimeOffset() ? fit.value.getFixedTimeOffset() : 0.0);
391 data.QE = fit.value.parameters[pmt].QE / P;
396 data.TTS_ns = fit.value.parameters[pmt].TTS();
399 module->getPMT(pmt).addT0(fit.value.parameters[pmt].t0.get() - t0);
402 catch(
const exception& error) {
404 ERROR(
"Module " << setw(10) << module->getID() <<
' ' << error.what() <<
" -> set QEs to 0." << endl);
417 JSTDObjectWriter <JMeta> writer(meta);
422 for (vector<JMeta>::const_reverse_iterator i = meta.rbegin(); i != meta.rend(); ++i) {
427 if (overwriteDetector) {
429 NOTICE(
"Store calibration data on file " << detectorFile << endl);
435 parameters.
store(pmtFile.c_str());
439 for (vector<JMeta>::const_iterator i = meta.begin(); i != meta.end(); ++i) {
448 out << h0 << hn << hr << h1 << h2 << h3 << h4 << hc << H2;