64int main(
int argc, 
char **argv)
 
   80  bool         overwriteDetector;
 
  109    JParser<> zap(
"Auxiliary program to fit PMT parameters from JMergeCalibrateK40 output.");
 
  112    zap[
'f'] = 
make_field(inputFile,         
"input file (output from JMergeCalibrateK40).");
 
  114    zap[
'a'] = 
make_field(detectorFile,      
"detector file.");
 
  115    zap[
'P'] = 
make_field(pmtFile,           
"specify PMT file name that can be given to JTriggerEfficiency.") = 
"";
 
  117                          "Fix time offset(s) of PMT(s) of certain module(s), e.g." 
  118                          "\n-! \"808969848 0 808982077 23\" will fix time offsets of PMT 0 of module 808969848 and of PMT 23 of module 808982077." 
  119                          "\nSame PMT offset can be fixed for all optical modules, e.g." 
  120                          "\n-! \"-1 0 -1 23\" will fix time offsets of PMTs 0 and 23 of all optical modules.") = 
JPARSER::initialised();
 
  121    zap[
'r'] = 
make_field(reverse,           
"reverse TDC constraints due to option -! <TDC>.");
 
  122    zap[
'A'] = 
make_field(overwriteDetector, 
"overwrite detector file provided through '-a' with fitted time offsets.");
 
  123    zap[
'w'] = 
make_field(writeFits,         
"write fit results to ROOT file; -ww also write fitted TTS to PMT file.");
 
  124    zap[
'D'] = 
make_field(fitAngle,          
"fit angular distribution; fix normalisation.");
 
  125    zap[
'B'] = 
make_field(fitNoise,          
"fit background.");
 
  126    zap[
'M'] = 
make_field(fitModel,          
"fit angular distribution as well as normalisation; fix PMT QEs = 1.0.");
 
  127    zap[
'Q'] = 
make_field(fixQE,             
"fix PMT QEs = 1.0.");
 
  134  catch(
const exception &error) {
 
  135    FATAL(error.what() << endl);
 
  139  if ((fitModel ? 1 : 0)  +
 
  142      (fixQE    ? 1 : 0)  >  1) {
 
  143    FATAL(
"Use either option -M, -D, -B or -Q" << endl);
 
  156  for (JTDC_t::const_iterator i = TDC.begin(); i != TDC.end(); ++i) {
 
  157    DEBUG(
"PMT " << setw(10) << i->first << 
' ' << setw(2) << i->second << 
" constrain t0." << endl);
 
  163  catch(
const exception &error) {
 
  164    FATAL(error.what() << endl);
 
  181      parameters.
load(pmtFile.c_str());
 
  183    catch(
const exception& error) {}
 
  189  TFile* in = TFile::Open(inputFile.c_str(), 
"exist");
 
  191  if (in == NULL || !in->IsOpen()) {
 
  192    FATAL(
"File: " << inputFile << 
" not opened." << endl);
 
  198  TH1D h0(
"chi2", NULL, 500,  0.0,   5.0);
 
  199  TH1D hn(
"hn",   NULL, 501, -0.5, 500.0);
 
  200  TH1D hr(
"rate", NULL, 500,  0.0,  25.0);
 
  201  TH1D h1(
"p1",   NULL, 500, -5.0,  +5.0);
 
  202  TH1D h2(
"p2",   NULL, 500, -5.0,  +5.0);
 
  203  TH1D h3(
"p3",   NULL, 500, -5.0,  +5.0);
 
  204  TH1D h4(
"p4",   NULL, 500, -5.0,  +5.0);
 
  205  TH1D hc(
"cc",   NULL, 500, -0.1,  +0.1);
 
  206  TH1D hb(
"bc",   NULL, 500, -0.1,  +0.1);
 
  211  TH2D H2(
"detector", NULL,
 
  212          string.size() + 0, -0.5, 
string.size() - 0.5,
 
  215  for (Int_t i = 1; i <= H2.GetXaxis()->GetNbins(); ++i) {
 
  216    H2.GetXaxis()->SetBinLabel(i, 
MAKE_CSTRING(
string.at(i-1)));
 
  218  for (Int_t i = 1; i <= H2.GetYaxis()->GetNbins(); ++i) {
 
  222  TH2D* HN = (TH2D*) H2.Clone(
"iterations");
 
  226  for (JDetector::iterator module = 
detector.begin(); module != 
detector.end(); ++module) {
 
  228    if (module->getFloor() == 0) { 
 
  234    NOTICE(
"Module " << setw(10) << module->getID() << 
' ' << 
getLabel(module->getLocation()) << 
" !" << 
distance(range.first, range.second) << endl);
 
  238    if (h2d == NULL || h2d->GetEntries() == 0) {
 
  240      NOTICE(
"No data for module " << module->getID() << 
" -> set QEs to 0." << endl);
 
  256    for (
int ix = 1; ix <= h2d->GetXaxis()->GetNbins(); ++ix) {
 
  260      auto& buffer = data[
pair];                                       
 
  265      for (
int iy = 1; iy <= h2d->GetYaxis()->GetNbins(); ++iy) {
 
  267        const double x = h2d->GetXaxis()->GetBinCenter(ix);
 
  268        const double y = h2d->GetYaxis()->GetBinCenter(iy);
 
  272          double value = h2d->GetBinContent(ix,iy);
 
  273          double error = h2d->GetBinError  (ix,iy);
 
  275          buffer.push_back(
rate_type(y, value, error));
 
  277          double width = h2d->GetYaxis()->GetBinWidth(iy);
 
  289      if (V  <=  0.0             - STDEV*W) {
 
  290        count[0][
pair.first]  += 1;
 
  291        count[0][
pair.second] += 1;
 
  294      if (V  <=  MINIMAL_RATE_HZ + STDEV*W) {
 
  295        count[1][
pair.first]  += 1;
 
  296        count[1][
pair.second] += 1;
 
  302      if (count[0][pmt] >= MAXIMAL_COUNTS) {                           
 
  304        WARNING(
"PMT " << setw(10) << module->getID() << 
'.' << 
FILL(2,
'0') << pmt << 
FILL() << 
" some rates negative -> fit background" << endl);
 
  306        if (fit.value.parameters[pmt].status) {
 
  307          model.parameters[pmt].bg.set();
 
  311      if (count[1][pmt] == NUMBER_OF_PMTS) {                           
 
  313        WARNING(
"PMT " << setw(10) << module->getID() << 
'.' << 
FILL(2,
'0') << pmt << 
FILL() << 
" all rates to low -> disable" << endl);
 
  315        model.parameters[pmt].disable();
 
  319    DEBUG(
"Start value:" << endl << 
model << endl);
 
  329        ERROR(
"Fit result " << setw(10) << module->getID() << 
" NDF  " << setw(5) << 
result.ndf << 
" -> skip" << endl);
 
  338        if (fit.value.parameters[pmt].status) {
 
  340          if (fit.value.parameters[pmt].QE() <= QE_MIN  ||
 
  341              fit.value.parameters[pmt].QE() <= 0.0 + STDEV * fit.error.parameters[pmt].QE()) {
 
  343            WARNING(
"PMT " << setw(10) << module->getID() << 
'.' << 
FILL(2,
'0') << pmt << 
FILL() << 
' ' 
  345                    << 
FIXED(5,3) << fit.value.parameters[pmt].QE() << 
" +/- "  
  346                    << 
FIXED(5,3) << fit.error.parameters[pmt].QE() << 
" " 
  347                    << 
" -> disable" << (!refit ? 
" and refit" : 
"") << endl);
 
  349            fit.value.parameters[pmt].disable();
 
  354          if (fit.value.parameters[pmt].t0.atLimit(T0_NS)) {
 
  356            WARNING(
"PMT " << setw(10) << module->getID() << 
'.' << 
FILL(2,
'0') << pmt << 
FILL() << 
' ' 
  358                    << 
FIXED(5,3) << fit.value.parameters[pmt].t0() << 
" +/- "  
  359                    << 
FIXED(5,3) << fit.error.parameters[pmt].t0() << 
" " 
  360                    << 
" -> disable" << (!refit ? 
" and refit" : 
"") << endl);
 
  362            fit.value.parameters[pmt].disable();
 
  372          if (fit.value.parameters[pmt].status) {
 
  381      NOTICE(
"Fit result " << setw(10) << module->getID() << 
" chi2 / NDF  " << 
FIXED(10,2) << 
result.chi2 << 
" / " << setw(5) << 
result.ndf << 
' ' << setw(5) << fit.numberOfIterations << endl);
 
  392        hn.Fill(fit.numberOfIterations);
 
  393        hr.Fill(fit.value.R );
 
  394        h1.Fill(fit.value.p1);
 
  395        h2.Fill(fit.value.p2);
 
  396        h3.Fill(fit.value.p3);
 
  397        h4.Fill(fit.value.p4);
 
  398        hc.Fill(fit.value.cc);
 
  399        hb.Fill(fit.value.bc);
 
  401        TH1D h1t(
MAKE_CSTRING(module->getID() << 
".1t0"),  NULL, NUMBER_OF_PMTS, -0.5, NUMBER_OF_PMTS - 0.5);
 
  402        TH1D h1s(
MAKE_CSTRING(module->getID() << 
".1TTS"), NULL, NUMBER_OF_PMTS, -0.5, NUMBER_OF_PMTS - 0.5);
 
  403        TH1D h1q(
MAKE_CSTRING(module->getID() << 
".1QE"),  NULL, NUMBER_OF_PMTS, -0.5, NUMBER_OF_PMTS - 0.5);
 
  406          h1t.SetBinContent(pmt + 1, fit.value.parameters[pmt].t0 ());
 
  407          h1t.SetBinError  (pmt + 1, fit.error.parameters[pmt].t0 ()  + numeric_limits<double>::epsilon());
 
  408          h1s.SetBinContent(pmt + 1, fit.value.parameters[pmt].TTS());
 
  409          h1s.SetBinError  (pmt + 1, fit.error.parameters[pmt].TTS()  + numeric_limits<double>::epsilon());
 
  410          h1q.SetBinContent(pmt + 1, fit.value.parameters[pmt].QE ());
 
  411          h1q.SetBinError  (pmt + 1, fit.error.parameters[pmt].QE ()  + numeric_limits<double>::epsilon());
 
  414        out << h1t << h1s << h1q;
 
  416        for (
int ix = 1; ix <= h2d->GetXaxis()->GetNbins(); ++ix) {
 
  420          for (
int iy = 1; iy <= h2d->GetYaxis()->GetNbins(); ++iy) {
 
  422            const double dt_ns = h2d->GetYaxis()->GetBinCenter(iy);
 
  424            h2d->SetBinContent(ix, iy, fit.value.getValue(
pair, dt_ns));
 
  425            h2d->SetBinError  (ix, iy, 0.0);
 
  432        const double x = 
string.getIndex(module->getString());
 
  433        const double y = 
module->getFloor();
 
  436        HN->Fill(x, y, fit.numberOfIterations);
 
  439      const double t0 = (fit.value.hasFixedTimeOffset() ? fit.value.getFixedTimeOffset() : 0.0);
 
  448          data.QE = fit.value.parameters[pmt].QE / P;
 
  453          data.TTS_ns = fit.value.parameters[pmt].TTS();
 
  456        module->getPMT(pmt).addT0(fit.value.parameters[pmt].t0.get() - t0);
 
  459    catch(
const exception& error) {
 
  461      ERROR(
"Module " << setw(10) << module->getID() << 
' ' << error.what() << 
" -> set QEs to 0." << endl);
 
  474    JSTDObjectWriter  <JMeta> writer(meta);
 
  479  for (vector<JMeta>::const_reverse_iterator i = meta.rbegin(); i != meta.rend(); ++i) {
 
  484  if (overwriteDetector) {
 
  486    NOTICE(
"Store calibration data on file " << detectorFile << endl);
 
  492    parameters.
store(pmtFile.c_str());
 
  496  for (vector<JMeta>::const_iterator i = meta.begin(); i != meta.end(); ++i) {
 
  505    out << h0 << hn << hr << h1 << h2 << h3 << h4 << hc << hb << H2 << *HN;