14 #include "TFitResult.h" 
   15 #include "Math/MinimizerOptions.h" 
   42   double  QE_MIN_VALUE     =  0.01;       
 
   43   double  QE_MAX_ERROR     =  0.5;        
 
   44   double  MINIMAL_RATE_HZ  =  1.0e-2;     
 
   57   inline bool is_valid(
const double qe_value, 
const double qe_error)
 
   59     return (qe_value > QE_MIN_VALUE  +  STDEV * qe_error  &&
 
   60             qe_error < QE_MAX_ERROR);
 
   74 int main(
int argc, 
char **argv)
 
   78   using namespace KM3NETDAQ;
 
   82   const double      epsilon = 1.0e-10;    
 
   91   bool      overwriteDetector;
 
  114     JParser<> zap(
"Auxiliary program to fit PMT parameters from JMergeCalibrateK40 output.");
 
  117     zap[
'f'] = 
make_field(inputFile,         
"input file (output from JMergeCalibrateK40).");
 
  119     zap[
'a'] = 
make_field(detectorFile,      
"detector file.");
 
  120     zap[
'P'] = 
make_field(pmtFile,           
"specify PMT file name that can be given to JTriggerEfficiency.") = 
"";
 
  122                           "Fix time offset(s) of PMT(s) of certain module(s), e.g." 
  123                           "\n-! \"808969848 0 808982077 23\" will fix offset of PMT 0 of module 808969848 and of PMT 23 of module 808982077." 
  124                           "\nSame PMT offset can be fixed for all optical modules, e.g." 
  125                           "\n-! \"-1 0 -1 23\" will fix offsets of PMTs 0 and 23 for all optical modules.")
 
  127     zap[
'r'] = 
make_field(reverse,           
"reverse TDC constraints due to option -! <TDC>.");
 
  128     zap[
'A'] = 
make_field(overwriteDetector, 
"overwrite detector file provided through '-a' with correct time offsets.");
 
  129     zap[
'w'] = 
make_field(writeFits,         
"write fit results.");
 
  130     zap[
'D'] = 
make_field(fitAngDist,        
"fit angular distribution; fix normalisation.");
 
  131     zap[
'M'] = 
make_field(fitModel,          
"fit angular distribution; fix PMT QEs = 1.0.");
 
  132     zap[
'x'] = 
make_field(X,                 
"ROOT fit range (PMT pairs).")                                    = JRange_t();
 
  133     zap[
'y'] = 
make_field(
Y,                 
"ROOT fit range (time residual).")                                = JRange_t();
 
  134     zap[
'O'] = 
make_field(option,            
"ROOT fit option, see TH1::Fit.")                                 = 
"";
 
  139   catch(
const exception &error) {
 
  140     FATAL(error.what() << endl);
 
  144   ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls(1000000);
 
  151   for (JTDC_t::const_iterator i = TDC.begin(); i != TDC.end(); ++i) {
 
  152     DEBUG(
"PMT " << setw(10) << i->first << 
' ' << setw(2) << i->second << 
" constrain t0." << endl);
 
  187   if (option.find(
'O') == string::npos) { option += 
'0'; }
 
  188   if (option.find(
'S') == string::npos) { option += 
'S'; }
 
  192   TFile* 
in = TFile::Open(inputFile.c_str(), 
"exist");
 
  194   if (
in == NULL || !
in->IsOpen()) {
 
  195     FATAL(
"File: " << inputFile << 
" not opened." << endl);
 
  199   TDirectory::AddDirectory(NULL);
 
  205   TH1D hc(
"chi2", NULL, 500, 0.0, 5.0);
 
  207   TH1D 
p1(
"p1", NULL, 501, -5.0, +5.0);
 
  208   TH1D 
p2(
"p2", NULL, 501, -5.0, +5.0);
 
  209   TH1D 
p3(
"p3", NULL, 501, -5.0, +5.0);
 
  210   TH1D p4(
"p4", NULL, 501, -5.0, +5.0);
 
  211   TH1D bg(
"bg", NULL, 501, -0.1, +0.1);
 
  212   TH1D cc(
"cc", NULL, 501, -0.1, +0.1);
 
  219   for (JDetector::iterator module = 
detector.begin(); module != 
detector.end(); ++module) {
 
  221     NOTICE(
"Module " << setw(10) << module->getID() << 
' ' << module->getLocation() << endl);
 
  223     if (module->empty()) {
 
  233     if (h2s == NULL || h2s->GetEntries() == 0) {
 
  235       NOTICE(
"No data for module " << module->getID() << 
"; set corresponding QEs to 0." << endl);
 
  255                 h2s->GetXaxis()->GetXmin(),
 
  256                 h2s->GetXaxis()->GetXmax(),
 
  257                 h2s->GetYaxis()->GetXmin(),
 
  258                 h2s->GetYaxis()->GetXmax(),
 
  259                 range.first == range.second);
 
  261     fit.setModelParameters(fitk40.getModelParameters());
 
  263     for (JTDC_t::const_iterator i = range.first; i != range.second; ++i) {
 
  264       fixParameter(fit, fit.getModelParameter(i->second, &JPMTParameters_t::t0));
 
  269         fixParameter(fit, fit.getModelParameter(pmt, &JPMTParameters_t::QE));
 
  274       fixParameter(fit, fit.getModelParameter(&JFitK40::Rate_Hz));
 
  290     for (
int ix = 1; ix <= h2s->GetXaxis()->GetNbins(); ++ix) {
 
  292       Double_t value = 0.0;
 
  293       Double_t error = 0.0;
 
  295       for (
int iy = 1; iy <= h2s->GetYaxis()->GetNbins(); ++iy) {
 
  296         value += h2s->GetBinContent(ix,iy);
 
  297         error += h2s->GetBinError(ix,iy) * h2s->GetBinError(ix,iy);
 
  302       if (value  <  MINIMAL_RATE_HZ + STDEV*error) {
 
  306         buffer[pair.first]  += 1;
 
  307         buffer[pair.second] += 1;
 
  317           WARNING(
"PMT " << setw(10) << module->getID() << 
' ' << setw(2) << pmt << 
" too low a rate; switch off." << endl);
 
  325       NOTICE(
"Skip fit for module " << module->getID() << 
"; set corresponding QEs to 0." << endl);
 
  336     if (X != JRange_t()) {
 
  337       h2s->GetXaxis()->SetRangeUser(max(X.getLowerLimit(), h2s->GetXaxis()->GetXmin()),
 
  338                                     min(X.getUpperLimit(), h2s->GetXaxis()->GetXmax()));
 
  340     if (
Y != JRange_t()) {
 
  341       h2s->GetYaxis()->SetRangeUser(max(
Y.getLowerLimit(), h2s->GetYaxis()->GetXmin()),
 
  342                                     min(
Y.getUpperLimit(), h2s->GetYaxis()->GetXmax()));
 
  347     TH1D 
h1(
MAKE_CSTRING(module->getID() << 
_1D), NULL, h2s->GetXaxis()->GetNbins(), h2s->GetXaxis()->GetXmin(), h2s->GetXaxis()->GetXmax());
 
  349     const Double_t sigma[] = {
 
  351       (min(
Y.getUpperLimit(), h2s->GetYaxis()->GetXmax()) -
 
  352        max(
Y.getLowerLimit(), h2s->GetYaxis()->GetXmin())) / sqrt(12.0),
 
  358     for (Int_t ix = 1; ix <= h2s->GetXaxis()->GetNbins(); ++ix) {
 
  362       Double_t value = 0.0;
 
  363       Double_t error = 0.0;
 
  365       for (Int_t iy = 1; iy <= h2s->GetYaxis()->GetNbins(); ++iy) {
 
  367         const Double_t y = h2s->GetYaxis()->GetBinCenter(iy);
 
  368         const Double_t z = h2s->GetBinContent(ix, iy);
 
  369         const Double_t 
w = h2s->GetBinError  (ix, iy);
 
  385       h1.SetBinContent(ix, y0);
 
  386       h1.SetBinError  (ix, value > MINIMAL_RATE_HZ + STDEV * error ? sigma[1] * error / value : sigma[0]);
 
  392       TFitResultPtr 
result = f1(
h1, option.c_str());
 
  396         TH1D h2(
MAKE_CSTRING(module->getID() << 
_1F), NULL, 
h1.GetXaxis()->GetNbins(), 
h1.GetXaxis()->GetXmin(), 
h1.GetXaxis()->GetXmax());
 
  398         for (
int ix = 1; ix <= h2.GetXaxis()->GetNbins(); ++ix) {
 
  400           const Double_t x = h2.GetXaxis()->GetBinCenter(ix);
 
  402           h2.SetBinContent(ix, f1.Eval(x));
 
  403           h2.SetBinError  (ix, 0.0);
 
  411         cout << 
"Fit result chi2 / NDF " << result->Chi2() << 
' ' << result->Ndf() << 
' ' << (result->IsValid() ? 
"" : 
"failed") << endl;
 
  416                  << setw(2)    << pmt             << 
' ' 
  417                  << 
FIXED(7,2) << f1.getT0 (pmt)  << 
' ';
 
  418             cout << (result->IsParameterFixed(f1.getModelParameter(pmt, &JPMTParameters_t::t0))  ? 
" *** fixed t0  *** " : 
"");
 
  419             cout << (f1.is_disabled  (pmt) ? 
" (disabled)" : 
"");
 
  420             cout << (f1.is_average_t0(pmt) ? 
" (averaged)" : 
"");
 
  425       fit.setModelParameters(f1.getModelParameters());
 
  429     TFitResultPtr 
result = fit(*h2s, option);
 
  441         if (!result->IsParameterFixed(fit.getModelParameter(pmt, &JPMTParameters_t::QE))  &&  !
is_valid(
values.getQE(pmt), errors.getQE(pmt))) {
 
  443           WARNING(
"PMT " << setw(10) << module->getID() << 
' ' << setw(2) << pmt << 
' ' 
  446                   << 
FIXED(5,2) << errors.getQE(pmt) 
 
  447                   << 
" compatible with zero -> set QE = 0 and t0 = 0; -> refit." << endl);
 
  458       NOTICE(
"Skip fit for module " << module->getID() << 
"; set corresponding QEs to 0." << endl);
 
  474       fit.setModelParameters(f1.getModelParameters());
 
  476       result = fit(*h2s, option);
 
  483     hc.Fill(TMath::Log10(result->Chi2() / result->Ndf()));
 
  487              h2s->GetXaxis()->GetNbins(), h2s->GetXaxis()->GetXmin (), h2s->GetXaxis()->GetXmax (),
 
  488              h2s->GetYaxis()->GetNbins(), h2s->GetYaxis()->GetXmin (), h2s->GetYaxis()->GetXmax ());
 
  490     for (
int ix = 1; ix <= h2f.GetXaxis()->GetNbins(); ++ix) {
 
  491       for (
int iy = 1; iy <= h2f.GetYaxis()->GetNbins(); ++iy) {
 
  493         const Double_t x = h2f.GetXaxis()->GetBinCenter(ix);
 
  494         const Double_t y = h2f.GetYaxis()->GetBinCenter(iy);
 
  496         h2f.SetBinContent(ix, iy, fit.Eval(x,y));
 
  497         h2f.SetBinError  (ix, iy, 0.0);
 
  504       cout << 
"Fit result chi2 / NDF " << result->Chi2() << 
' ' << result->Ndf() << 
' ' << (result->IsValid() ? 
"" : 
"failed") << endl;
 
  506       cout << 
"Rate_Hz= " << 
FIXED(8,4) << 
values.Rate_Hz << (result->IsParameterFixed(fit.getModelParameter(&JFitK40::Rate_Hz)) ? 
" *** fixed *** " : 
"") << endl;
 
  508       cout << 
"p1=      " << 
FIXED(8,4) << 
values.p1      << (result->IsParameterFixed(fit.getModelParameter(&
JFitK40::p1))      ? 
" *** fixed *** " : 
"") << endl;
 
  509       cout << 
"p2=      " << 
FIXED(8,4) << 
values.p2      << (result->IsParameterFixed(fit.getModelParameter(&
JFitK40::p2))      ? 
" *** fixed *** " : 
"") << endl;
 
  510       cout << 
"p3=      " << 
FIXED(8,4) << 
values.p3      << (result->IsParameterFixed(fit.getModelParameter(&
JFitK40::p2))      ? 
" *** fixed *** " : 
"") << endl;
 
  511       cout << 
"p4=      " << 
FIXED(8,4) << 
values.p4      << (result->IsParameterFixed(fit.getModelParameter(&
JFitK40::p3))      ? 
" *** fixed *** " : 
"") << endl;
 
  513       cout << 
"Background (correlated):   " << 
FIXED(8,5) << 
values.bg << (result->IsParameterFixed(fit.getModelParameter(&JFitK40::bg)) ? 
" *** fixed *** " : 
"") << endl;
 
  514       cout << 
"Background (uncorrelated): " << 
FIXED(8,5) << 
values.cc << (result->IsParameterFixed(fit.getModelParameter(&JFitK40::cc)) ? 
" *** fixed *** " : 
"") << endl;
 
  516       cout << 
" PMT t0 [ns] TTS [ns]   R" << endl;
 
  523              << setw(2)    << pmt             << 
' ' 
  524              << 
FIXED(7,2) << fit.getT0 (pmt) << 
' ' 
  525              << 
FIXED(7,2) << fit.getTTS(pmt) << 
' ' 
  526              << 
FIXED(7,3) << fit.getQE (pmt);
 
  528         cout << (result->IsParameterFixed(fit.getModelParameter(pmt, &JPMTParameters_t::QE))  ? 
" *** fixed QE  *** " : 
"");
 
  529         cout << (result->IsParameterFixed(fit.getModelParameter(pmt, &JPMTParameters_t::TTS)) ? 
" *** fixed TTS *** " : 
"");
 
  530         cout << (result->IsParameterFixed(fit.getModelParameter(pmt, &JPMTParameters_t::t0))  ? 
" *** fixed t0  *** " : 
"");
 
  531         cout << (fit.is_disabled  (pmt) ? 
" (disabled)" : 
"");
 
  532         cout << (fit.is_average_t0(pmt) ? 
" (averaged)" : 
"");
 
  535         Q[0].
put(fit.getT0 (pmt));
 
  536         Q[1].
put(fit.getTTS(pmt));
 
  537         Q[2].
put(fit.getQE (pmt));
 
  574         h1t.SetBinContent(pmt + 1, 
values.getT0 (pmt));
 
  575         h1s.SetBinContent(pmt + 1, 
values.getTTS(pmt));
 
  576         h1q.SetBinContent(pmt + 1, 
values.getQE (pmt));
 
  578         h1t.SetBinError  (pmt + 1, max(errors.getT0 (pmt), epsilon));
 
  579         h1s.SetBinError  (pmt + 1, max(errors.getTTS(pmt), epsilon));
 
  580         h1q.SetBinError  (pmt + 1, max(errors.getQE (pmt), epsilon));
 
  583       out << h1t << h1s << h1q;
 
  602       if (overwriteDetector) {
 
  603         module->getPMT(pmt).addT0(fit.getT0(pmt));
 
  610     out << hc << p1 << p2 << p3 << p4 << bg << cc;
 
  624   if (overwriteDetector) {
 
  626     NOTICE(
"Store calibration data on file " << detectorFile << endl);
 
Utility class to parse command line options. 
 
JCombinatorics::pair_type pair_type
 
int main(int argc, char *argv[])
 
#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. 
 
Scanning of objects from a single file according a format that follows from the extension of each fil...
 
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. 
 
double getSurvivalProbability(const JPMTParameters ¶meters)
Get model dependent probability that a one photo-electron hit survives the simulation of the PMT assu...
 
bool fixParameter(TF1 &f1, const JFitParameter_t ¶meter)
Fix fit parameter. 
 
Object reading from a list of files. 
 
Data structure for PMT parameters. 
 
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 CHECK_EXIT_CODE typeset A TRIPODS get_tripods $WORKDIR tripod txt TRIPODS for EMITTER in
 
Fit parameters for two-fold coincidence rate due to K40. 
 
double QE
relative quantum efficiency 
 
static const char *const _1D
Name extension for 1D time offset. 
 
#define DEBUG(A)
Message macros.