14 #include "TFitResult.h" 
   15 #include "Math/MinimizerOptions.h" 
   40   double  QE_MIN_VALUE     =  0.01;       
 
   41   double  QE_MAX_ERROR     =  0.5;        
 
   42   double  MINIMAL_RATE_HZ  =  1.0e-2;     
 
   55   inline bool is_valid(
const double qe_value, 
const double qe_error)
 
   57     return (qe_value > QE_MIN_VALUE  +  STDEV * qe_error  &&
 
   58             qe_error < QE_MAX_ERROR);
 
   72 int main(
int argc, 
char **argv)
 
   76   using namespace KM3NETDAQ;
 
   80   const double      epsilon = 1.0e-10;    
 
   89   bool      overwriteDetector;
 
  112     JParser<> zap(
"Auxiliary program to fit PMT parameters from JMergeCalibrateK40 output.");
 
  115     zap[
'f'] = 
make_field(inputFile,         
"input file (output from JMergeCalibrateK40).");
 
  117     zap[
'a'] = 
make_field(detectorFile,      
"detector file.");
 
  118     zap[
'P'] = 
make_field(pmtFile,           
"specify PMT file name that can be given to JTriggerEfficiency.") = 
"";
 
  120                           "Fix time offset(s) of PMT(s) of certain module(s), e.g." 
  121                           "\n-! \"808969848 0 808982077 23\" will fix offset of PMT 0 of module 808969848 and of PMT 23 of module 808982077." 
  122                           "\nSame PMT offset can be fixed for all optical modules, e.g." 
  123                           "\n-! \"-1 0 -1 23\" will fix offsets of PMTs 0 and 23 for all optical modules.")
 
  125     zap[
'r'] = 
make_field(reverse,           
"reverse TDC constraints due to option -! <TDC>.");
 
  126     zap[
'A'] = 
make_field(overwriteDetector, 
"overwrite detector file provided through '-a' with correct time offsets.");
 
  127     zap[
'w'] = 
make_field(writeFits,         
"write fit results.");
 
  128     zap[
'D'] = 
make_field(fitAngDist,        
"fit angular distribution; fix normalisation.");
 
  129     zap[
'M'] = 
make_field(fitModel,          
"fit angular distribution; fix PMT QEs = 1.0.");
 
  130     zap[
'x'] = 
make_field(X,                 
"ROOT fit range (PMT pairs).")                                    = JRange_t();
 
  131     zap[
'y'] = 
make_field(
Y,                 
"ROOT fit range (time residual).")                                = JRange_t();
 
  132     zap[
'O'] = 
make_field(option,            
"ROOT fit option, see TH1::Fit.")                                 = 
"";
 
  137   catch(
const exception &error) {
 
  138     FATAL(error.what() << endl);
 
  142   ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls(1000000);
 
  149   for (JTDC_t::const_iterator i = TDC.begin(); i != TDC.end(); ++i) {
 
  150     DEBUG(
"PMT " << setw(10) << i->first << 
' ' << setw(2) << i->second << 
" constrain t0." << endl);
 
  184   if (option.find(
'O') == string::npos) { option += 
'0'; }
 
  185   if (option.find(
'S') == string::npos) { option += 
'S'; }
 
  189   TFile* 
in = TFile::Open(inputFile.c_str(), 
"exist");
 
  191   if (
in == NULL || !
in->IsOpen()) {
 
  192     FATAL(
"File: " << inputFile << 
" not opened." << endl);
 
  196   TDirectory::AddDirectory(NULL);
 
  202   TH1D hc(
"chi2", NULL, 500, 0.0, 5.0);
 
  204   TH1D 
p1(
"p1", NULL, 501, -5.0, +5.0);
 
  205   TH1D 
p2(
"p2", NULL, 501, -5.0, +5.0);
 
  206   TH1D 
p3(
"p3", NULL, 501, -5.0, +5.0);
 
  207   TH1D p4(
"p4", NULL, 501, -5.0, +5.0);
 
  208   TH1D bg(
"bg", NULL, 501, -0.1, +0.1);
 
  209   TH1D cc(
"cc", NULL, 501, -0.1, +0.1);
 
  216   for (JDetector::iterator module = 
detector.begin(); module != 
detector.end(); ++module) {
 
  218     NOTICE(
"Module " << setw(10) << module->getID() << 
' ' << module->getLocation() << endl);
 
  220     if (module->empty()) {
 
  230     if (h2s == NULL || h2s->GetEntries() == 0) {
 
  232       NOTICE(
"No data for module " << module->getID() << 
"; set corresponding QEs to 0." << endl);
 
  252                 h2s->GetXaxis()->GetXmin(),
 
  253                 h2s->GetXaxis()->GetXmax(),
 
  254                 h2s->GetYaxis()->GetXmin(),
 
  255                 h2s->GetYaxis()->GetXmax(),
 
  256                 range.first == range.second);
 
  258     fit.setModelParameters(fitk40.getModelParameters());
 
  260     for (JTDC_t::const_iterator i = range.first; i != range.second; ++i) {
 
  261       fixParameter(fit, fit.getModelParameter(i->second, &JPMTParameters_t::t0));
 
  266         fixParameter(fit, fit.getModelParameter(pmt, &JPMTParameters_t::QE));
 
  271       fixParameter(fit, fit.getModelParameter(&JFitK40::Rate_Hz));
 
  287     for (
int ix = 1; ix <= h2s->GetXaxis()->GetNbins(); ++ix) {
 
  289       Double_t value = 0.0;
 
  290       Double_t error = 0.0;
 
  292       for (
int iy = 1; iy <= h2s->GetYaxis()->GetNbins(); ++iy) {
 
  293         value += h2s->GetBinContent(ix,iy);
 
  294         error += h2s->GetBinError(ix,iy) * h2s->GetBinError(ix,iy);
 
  299       if (value  <  MINIMAL_RATE_HZ + STDEV*error) {
 
  303         buffer[pair.first]  += 1;
 
  304         buffer[pair.second] += 1;
 
  314           WARNING(
"PMT " << setw(10) << module->getID() << 
' ' << setw(2) << pmt << 
" too low a rate; switch off." << endl);
 
  322       NOTICE(
"Skip fit for module " << module->getID() << 
"; set corresponding QEs to 0." << endl);
 
  333     if (X != JRange_t()) {
 
  334       h2s->GetXaxis()->SetRangeUser(max(X.getLowerLimit(), h2s->GetXaxis()->GetXmin()),
 
  335                                     min(X.getUpperLimit(), h2s->GetXaxis()->GetXmax()));
 
  337     if (
Y != JRange_t()) {
 
  338       h2s->GetYaxis()->SetRangeUser(max(
Y.getLowerLimit(), h2s->GetYaxis()->GetXmin()),
 
  339                                     min(
Y.getUpperLimit(), h2s->GetYaxis()->GetXmax()));
 
  344     TH1D 
h1(
MAKE_CSTRING(module->getID() << 
_1D), NULL, h2s->GetXaxis()->GetNbins(), h2s->GetXaxis()->GetXmin(), h2s->GetXaxis()->GetXmax());
 
  346     const Double_t sigma[] = {
 
  348       (min(
Y.getUpperLimit(), h2s->GetYaxis()->GetXmax()) -
 
  349        max(
Y.getLowerLimit(), h2s->GetYaxis()->GetXmin())) / sqrt(12.0),
 
  355     for (Int_t ix = 1; ix <= h2s->GetXaxis()->GetNbins(); ++ix) {
 
  359       Double_t value = 0.0;
 
  360       Double_t error = 0.0;
 
  362       for (Int_t iy = 1; iy <= h2s->GetYaxis()->GetNbins(); ++iy) {
 
  364         const Double_t y = h2s->GetYaxis()->GetBinCenter(iy);
 
  365         const Double_t z = h2s->GetBinContent(ix, iy);
 
  366         const Double_t 
w = h2s->GetBinError  (ix, iy);
 
  382       h1.SetBinContent(ix, y0);
 
  383       h1.SetBinError  (ix, value > MINIMAL_RATE_HZ + STDEV * error ? sigma[1] * error / value : sigma[0]);
 
  389       TFitResultPtr 
result = f1(
h1, option.c_str());
 
  393         TH1D h2(
MAKE_CSTRING(module->getID() << 
_1F), NULL, 
h1.GetXaxis()->GetNbins(), 
h1.GetXaxis()->GetXmin(), 
h1.GetXaxis()->GetXmax());
 
  395         for (
int ix = 1; ix <= h2.GetXaxis()->GetNbins(); ++ix) {
 
  397           const Double_t x = h2.GetXaxis()->GetBinCenter(ix);
 
  399           h2.SetBinContent(ix, f1.Eval(x));
 
  400           h2.SetBinError  (ix, 0.0);
 
  408         cout << 
"Fit result chi2 / NDF " << result->Chi2() << 
' ' << result->Ndf() << 
' ' << (result->IsValid() ? 
"" : 
"failed") << endl;
 
  413                  << setw(2)    << pmt             << 
' ' 
  414                  << 
FIXED(7,2) << f1.getT0 (pmt)  << 
' ';
 
  415             cout << (result->IsParameterFixed(f1.getModelParameter(pmt, &JPMTParameters_t::t0))  ? 
" *** fixed t0  *** " : 
"");
 
  416             cout << (f1.is_disabled  (pmt) ? 
" (disabled)" : 
"");
 
  417             cout << (f1.is_average_t0(pmt) ? 
" (averaged)" : 
"");
 
  422       fit.setModelParameters(f1.getModelParameters());
 
  426     TFitResultPtr 
result = fit(*h2s, option);
 
  438         if (!result->IsParameterFixed(fit.getModelParameter(pmt, &JPMTParameters_t::QE))  &&  !
is_valid(
values.getQE(pmt), errors.getQE(pmt))) {
 
  440           WARNING(
"PMT " << setw(10) << module->getID() << 
' ' << setw(2) << pmt << 
' ' 
  443                   << 
FIXED(5,2) << errors.getQE(pmt) 
 
  444                   << 
" compatible with zero -> set QE = 0 and t0 = 0; -> refit." << endl);
 
  455       NOTICE(
"Skip fit for module " << module->getID() << 
"; set corresponding QEs to 0." << endl);
 
  471       fit.setModelParameters(f1.getModelParameters());
 
  473       result = fit(*h2s, option);
 
  480     hc.Fill(TMath::Log10(result->Chi2() / result->Ndf()));
 
  484              h2s->GetXaxis()->GetNbins(), h2s->GetXaxis()->GetXmin (), h2s->GetXaxis()->GetXmax (),
 
  485              h2s->GetYaxis()->GetNbins(), h2s->GetYaxis()->GetXmin (), h2s->GetYaxis()->GetXmax ());
 
  487     for (
int ix = 1; ix <= h2f.GetXaxis()->GetNbins(); ++ix) {
 
  488       for (
int iy = 1; iy <= h2f.GetYaxis()->GetNbins(); ++iy) {
 
  490         const Double_t x = h2f.GetXaxis()->GetBinCenter(ix);
 
  491         const Double_t y = h2f.GetYaxis()->GetBinCenter(iy);
 
  493         h2f.SetBinContent(ix, iy, fit.Eval(x,y));
 
  494         h2f.SetBinError  (ix, iy, 0.0);
 
  501       cout << 
"Fit result chi2 / NDF " << result->Chi2() << 
' ' << result->Ndf() << 
' ' << (result->IsValid() ? 
"" : 
"failed") << endl;
 
  503       cout << 
"Rate_Hz= " << 
FIXED(8,4) << 
values.Rate_Hz << (result->IsParameterFixed(fit.getModelParameter(&JFitK40::Rate_Hz)) ? 
" *** fixed *** " : 
"") << endl;
 
  505       cout << 
"p1=      " << 
FIXED(8,4) << 
values.p1      << (result->IsParameterFixed(fit.getModelParameter(&
JFitK40::p1))      ? 
" *** fixed *** " : 
"") << endl;
 
  506       cout << 
"p2=      " << 
FIXED(8,4) << 
values.p2      << (result->IsParameterFixed(fit.getModelParameter(&
JFitK40::p2))      ? 
" *** fixed *** " : 
"") << endl;
 
  507       cout << 
"p3=      " << 
FIXED(8,4) << 
values.p3      << (result->IsParameterFixed(fit.getModelParameter(&
JFitK40::p2))      ? 
" *** fixed *** " : 
"") << endl;
 
  508       cout << 
"p4=      " << 
FIXED(8,4) << 
values.p4      << (result->IsParameterFixed(fit.getModelParameter(&
JFitK40::p3))      ? 
" *** fixed *** " : 
"") << endl;
 
  510       cout << 
"Background (correlated):   " << 
FIXED(8,5) << 
values.bg << (result->IsParameterFixed(fit.getModelParameter(&JFitK40::bg)) ? 
" *** fixed *** " : 
"") << endl;
 
  511       cout << 
"Background (uncorrelated): " << 
FIXED(8,5) << 
values.cc << (result->IsParameterFixed(fit.getModelParameter(&JFitK40::cc)) ? 
" *** fixed *** " : 
"") << endl;
 
  513       cout << 
" PMT t0 [ns] TTS [ns]   R" << endl;
 
  520              << setw(2)    << pmt             << 
' ' 
  521              << 
FIXED(7,2) << fit.getT0 (pmt) << 
' ' 
  522              << 
FIXED(7,2) << fit.getTTS(pmt) << 
' ' 
  523              << 
FIXED(7,3) << fit.getQE (pmt);
 
  525         cout << (result->IsParameterFixed(fit.getModelParameter(pmt, &JPMTParameters_t::QE))  ? 
" *** fixed QE  *** " : 
"");
 
  526         cout << (result->IsParameterFixed(fit.getModelParameter(pmt, &JPMTParameters_t::TTS)) ? 
" *** fixed TTS *** " : 
"");
 
  527         cout << (result->IsParameterFixed(fit.getModelParameter(pmt, &JPMTParameters_t::t0))  ? 
" *** fixed t0  *** " : 
"");
 
  528         cout << (fit.is_disabled  (pmt) ? 
" (disabled)" : 
"");
 
  529         cout << (fit.is_average_t0(pmt) ? 
" (averaged)" : 
"");
 
  532         Q[0].
put(fit.getT0 (pmt));
 
  533         Q[1].
put(fit.getTTS(pmt));
 
  534         Q[2].
put(fit.getQE (pmt));
 
  571         h1t.SetBinContent(pmt + 1, 
values.getT0 (pmt));
 
  572         h1s.SetBinContent(pmt + 1, 
values.getTTS(pmt));
 
  573         h1q.SetBinContent(pmt + 1, 
values.getQE (pmt));
 
  575         h1t.SetBinError  (pmt + 1, max(errors.getT0 (pmt), epsilon));
 
  576         h1s.SetBinError  (pmt + 1, max(errors.getTTS(pmt), epsilon));
 
  577         h1q.SetBinError  (pmt + 1, max(errors.getQE (pmt), epsilon));
 
  580       out << h1t << h1s << h1q;
 
  590       if (overwriteDetector) {
 
  591         module->getPMT(pmt).addT0(fit.getT0(pmt));
 
  598     out << hc << p1 << p2 << p3 << p4 << bg << cc;
 
  604   if (overwriteDetector) {
 
  606     NOTICE(
"Store calibration data on file " << detectorFile << endl);
 
Utility class to parse command line options. 
 
JCombinatorics::pair_type pair_type
 
#define gmake_property(A)
macro to convert (template) parameter to JPropertiesElement object 
 
Auxiliary class for TDC constraints. 
 
Template specialisation of two-fold coincidence rate due to K40 and other radioactive decays...
 
Utility class to parse parameter values. 
 
*fatal Wrong number of arguments esac JCookie sh typeset Z DETECTOR typeset Z SOURCE_RUN typeset Z TARGET_RUN set_variable PARAMETERS_FILE $WORKDIR parameters
 
#define MAKE_CSTRING(A)
Make C-string. 
 
then for HISTOGRAM in h0 h1
 
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
 
Template specialisation of two-fold coincidence rate due to K40 and other radioactive decays...
 
then fatal Wrong number of arguments fi set_variable STRING $argv[1] set_variable DETECTORXY_TXT $WORKDIR $DETECTORXY_TXT tail read X Y CHI2 RMS printf optimum n $X $Y $CHI2 $RMS awk v Y
 
Auxiliary data structure for floating point format specification. 
 
Data structure for detector geometry and calibration. 
 
Utility class to parse parameter values. 
 
static const char *const _1F
Name extension for 1D time offset fit. 
 
static const char *const _2F
Name extension for 2F rate fitted. 
 
I/O formatting auxiliaries. 
 
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object 
 
bool is_valid(const json &js)
Check validity of JSon data. 
 
void store(const std::string &file_name, const JDetector &detector)
Store detector to output file. 
 
static const char *const _2R
Name extension for 2D rate measured. 
 
Auxiliary class for map of PMT parameters. 
 
General purpose messaging. 
 
Fit parameters for single PMT. 
 
z range($ZMAX-$ZMIN)< $MINIMAL_DZ." fi fi mv $WORKDIR/fit.root $MODULE_ROOT typeset -Z 4 STRING typeset -Z 2 FLOOR JPlot1D -f $
 
void load(const std::string &file_name, JDetector &detector)
Load detector from input file. 
 
Auxiliary class to define a range between two values. 
 
Utility class to parse command line options. 
 
bool fixParameter(TF1 &f1, const JFitParameter_t ¶meter)
Fix fit parameter. 
 
do set_variable DETECTOR_TXT $WORKDIR detector
 
KM3NeT DAQ constants, bit handling, etc. 
 
static const int NUMBER_OF_PMTS
Total number of PMTs in module. 
 
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable INPUT_FILE $argv[2] eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY source JAcoustics sh $DETECTOR_ID typeset A TRIPODS get_tripods $WORKDIR tripod txt TRIPODS for EMITTER in
 
Fit parameters for two-fold coincidence rate due to K40. 
 
static const char *const _1D
Name extension for 1D time offset. 
 
#define DEBUG(A)
Message macros. 
 
int main(int argc, char *argv[])