17 #include "TFitResult.h" 
   18 #include "Math/MinimizerOptions.h" 
   45   double  QE_MIN_VALUE     =  0.01;       
 
   46   double  QE_MAX_ERROR     =  0.5;        
 
   47   double  MINIMAL_RATE_HZ  =  1.0e-2;     
 
   60   inline bool is_valid(
const double qe_value, 
const double qe_error)
 
   62     return (qe_value > QE_MIN_VALUE  +  STDEV * qe_error  &&
 
   63             qe_error < QE_MAX_ERROR);
 
   77 int main(
int argc, 
char **argv)
 
   81   using namespace KM3NETDAQ;
 
   94   bool      overwriteDetector;
 
  117     JParser<> zap(
"Auxiliary program to fit PMT parameters from JMergeCalibrateK40 output.");
 
  120     zap[
'f'] = 
make_field(inputFile,         
"input file (output from JMergeCalibrateK40).");
 
  122     zap[
'a'] = 
make_field(detectorFile,      
"detector file.");
 
  123     zap[
'P'] = 
make_field(pmtFile,           
"specify PMT file name that can be given to JTriggerEfficiency.") = 
"";
 
  125                           "Fix time offset(s) of PMT(s) of certain module(s), e.g." 
  126                           "\n-! \"808969848 0 808982077 23\" will fix offset of PMT 0 of module 808969848 and of PMT 23 of module 808982077." 
  127                           "\nSame PMT offset can be fixed for all optical modules, e.g." 
  128                           "\n-! \"-1 0 -1 23\" will fix offsets of PMTs 0 and 23 for all optical modules.")
 
  130     zap[
'r'] = 
make_field(reverse,           
"reverse TDC constraints due to option -! <TDC>.");
 
  131     zap[
'A'] = 
make_field(overwriteDetector, 
"overwrite detector file provided through '-a' with correct time offsets.");
 
  132     zap[
'w'] = 
make_field(writeFits,         
"write fit results.");
 
  133     zap[
'D'] = 
make_field(fitAngDist,        
"fit angular distribution; fix normalisation.");
 
  134     zap[
'M'] = 
make_field(fitModel,          
"fit angular distribution; fix PMT QEs = 1.0.");
 
  137     zap[
'O'] = 
make_field(option,            
"ROOT fit option, see TH1::Fit.")                                 = 
"";
 
  142   catch(
const exception &error) {
 
  143     FATAL(error.what() << endl);
 
  147   ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls(1000000);
 
  154   for (JTDC_t::const_iterator i = 
TDC.begin(); i != 
TDC.end(); ++i) {
 
  155     DEBUG(
"PMT " << setw(10) << i->first << 
' ' << setw(2) << i->second << 
" constrain t0." << endl);
 
  190   if (option.find(
'O') == string::npos) { option += 
'0'; }
 
  191   if (option.find(
'S') == string::npos) { option += 
'S'; }
 
  195   TFile* 
in = TFile::Open(inputFile.c_str(), 
"exist");
 
  197   if (
in == NULL || !
in->IsOpen()) {
 
  198     FATAL(
"File: " << inputFile << 
" not opened." << endl);
 
  202   TDirectory::AddDirectory(NULL);
 
  208   TH1D hc(
"chi2", NULL, 500, 0.0, 5.0);
 
  210   TH1D 
p1(
"p1", NULL, 501, -5.0, +5.0);
 
  211   TH1D 
p2(
"p2", NULL, 501, -5.0, +5.0);
 
  212   TH1D 
p3(
"p3", NULL, 501, -5.0, +5.0);
 
  213   TH1D 
p4(
"p4", NULL, 501, -5.0, +5.0);
 
  214   TH1D bg(
"bg", NULL, 501, -0.1, +0.1);
 
  215   TH1D cc(
"cc", NULL, 501, -0.1, +0.1);
 
  222   for (JDetector::iterator module = 
detector.begin(); module != 
detector.end(); ++module) {
 
  224     NOTICE(
"Module " << setw(10) << module->getID() << 
' ' << module->getLocation() << endl);
 
  226     if (module->empty()) {
 
  236     if (h2s == NULL || h2s->GetEntries() == 0) {
 
  238       NOTICE(
"No data for module " << module->getID() << 
"; set corresponding QEs to 0." << endl);
 
  258                 h2s->GetXaxis()->GetXmin(),
 
  259                 h2s->GetXaxis()->GetXmax(),
 
  260                 h2s->GetYaxis()->GetXmin(),
 
  261                 h2s->GetYaxis()->GetXmax(),
 
  262                 range.first == range.second);
 
  264     fit.setModelParameters(fitk40.getModelParameters());
 
  266     for (JTDC_t::const_iterator i = range.first; i != range.second; ++i) {
 
  267       fixParameter(fit, fit.getModelParameter(i->second, &JPMTParameters_t::t0));
 
  272         fixParameter(fit, fit.getModelParameter(pmt, &JPMTParameters_t::QE));
 
  277       fixParameter(fit, fit.getModelParameter(&JFitK40::Rate_Hz));
 
  293     for (
int ix = 1; ix <= h2s->GetXaxis()->GetNbins(); ++ix) {
 
  295       Double_t value = 0.0;
 
  296       Double_t error = 0.0;
 
  298       for (
int iy = 1; iy <= h2s->GetYaxis()->GetNbins(); ++iy) {
 
  299         value += h2s->GetBinContent(ix,iy);
 
  300         error += h2s->GetBinError(ix,iy) * h2s->GetBinError(ix,iy);
 
  305       if (value  <  MINIMAL_RATE_HZ + STDEV*error) {
 
  309         buffer[pair.first]  += 1;
 
  310         buffer[pair.second] += 1;
 
  320           WARNING(
"PMT " << setw(10) << module->getID() << 
' ' << setw(2) << pmt << 
" too low a rate; switch off." << endl);
 
  328       NOTICE(
"Skip fit for module " << module->getID() << 
"; set corresponding QEs to 0." << endl);
 
  340       h2s->GetXaxis()->SetRangeUser(max(
X.getLowerLimit(), h2s->GetXaxis()->GetXmin()),
 
  341                                     min(
X.getUpperLimit(), h2s->GetXaxis()->GetXmax()));
 
  344       h2s->GetYaxis()->SetRangeUser(max(
Y.getLowerLimit(), h2s->GetYaxis()->GetXmin()),
 
  345                                     min(
Y.getUpperLimit(), h2s->GetYaxis()->GetXmax()));
 
  350     TH1D h1(
MAKE_CSTRING(module->getID() << 
_1D), NULL, h2s->GetXaxis()->GetNbins(), h2s->GetXaxis()->GetXmin(), h2s->GetXaxis()->GetXmax());
 
  352     const Double_t 
sigma[] = {
 
  354       (min(
Y.getUpperLimit(), h2s->GetYaxis()->GetXmax()) -
 
  355        max(
Y.getLowerLimit(), h2s->GetYaxis()->GetXmin())) / sqrt(12.0),
 
  361     for (Int_t ix = 1; ix <= h2s->GetXaxis()->GetNbins(); ++ix) {
 
  365       Double_t value = 0.0;
 
  366       Double_t error = 0.0;
 
  368       for (Int_t iy = 1; iy <= h2s->GetYaxis()->GetNbins(); ++iy) {
 
  370         const Double_t y = h2s->GetYaxis()->GetBinCenter(iy);
 
  371         const Double_t z = h2s->GetBinContent(ix, iy);
 
  372         const Double_t 
w = h2s->GetBinError  (ix, iy);
 
  388       h1.SetBinContent(ix, y0);
 
  389       h1.SetBinError  (ix, value > MINIMAL_RATE_HZ + STDEV * error ? sigma[1] * error / value : sigma[0]);
 
  395       TFitResultPtr 
result = 
f1(h1, option.c_str());
 
  397       if (result.Get() == NULL) {
 
  398         FATAL(
"Invalid TFitResultPtr " << h1.GetName() << endl);
 
  403         TH1D h2(
MAKE_CSTRING(module->getID() << 
_1F), NULL, h1.GetXaxis()->GetNbins(), h1.GetXaxis()->GetXmin(), h1.GetXaxis()->GetXmax());
 
  405         for (
int ix = 1; ix <= h2.GetXaxis()->GetNbins(); ++ix) {
 
  407           const Double_t 
x = h2.GetXaxis()->GetBinCenter(ix);
 
  409           h2.SetBinContent(ix, f1.Eval(x));
 
  410           h2.SetBinError  (ix, 0.0);
 
  418         cout << 
"Fit result chi2 / NDF " << result->Chi2() << 
' ' << result->Ndf() << 
' ' << (result->IsValid() ? 
"" : 
"failed") << endl;
 
  423                  << setw(2)    << pmt             << 
' ' 
  424                  << 
FIXED(7,2) << f1.getT0 (pmt)  << 
' ';
 
  425             cout << (result->IsParameterFixed(f1.getModelParameter(pmt, &JPMTParameters_t::t0))  ? 
" *** fixed t0  *** " : 
"");
 
  426             cout << (f1.is_disabled  (pmt) ? 
" (disabled)" : 
"");
 
  427             cout << (f1.is_average_t0(pmt) ? 
" (averaged)" : 
"");
 
  432       fit.setModelParameters(f1.getModelParameters());
 
  436     TFitResultPtr 
result = fit(*h2s, option);
 
  448         if (!result->IsParameterFixed(fit.getModelParameter(pmt, &JPMTParameters_t::QE))  &&  !
is_valid(
values.getQE(pmt), errors.getQE(pmt))) {
 
  450           WARNING(
"PMT " << setw(10) << module->getID() << 
' ' << setw(2) << pmt << 
' ' 
  453                   << 
FIXED(5,2) << errors.getQE(pmt) 
 
  454                   << 
" compatible with zero -> set QE = 0 and t0 = 0; -> refit." << endl);
 
  465       NOTICE(
"Skip fit for module " << module->getID() << 
"; set corresponding QEs to 0." << endl);
 
  481       fit.setModelParameters(f1.getModelParameters());
 
  483       result = fit(*h2s, option);
 
  490     hc.Fill(TMath::Log10(result->Chi2() / result->Ndf()));
 
  494              h2s->GetXaxis()->GetNbins(), h2s->GetXaxis()->GetXmin (), h2s->GetXaxis()->GetXmax (),
 
  495              h2s->GetYaxis()->GetNbins(), h2s->GetYaxis()->GetXmin (), h2s->GetYaxis()->GetXmax ());
 
  497     for (
int ix = 1; ix <= h2f.GetXaxis()->GetNbins(); ++ix) {
 
  498       for (
int iy = 1; iy <= h2f.GetYaxis()->GetNbins(); ++iy) {
 
  500         const Double_t 
x = h2f.GetXaxis()->GetBinCenter(ix);
 
  501         const Double_t y = h2f.GetYaxis()->GetBinCenter(iy);
 
  503         h2f.SetBinContent(ix, iy, fit.Eval(x,y));
 
  504         h2f.SetBinError  (ix, iy, 0.0);
 
  511       cout << 
"Fit result chi2 / NDF " << result->Chi2() << 
' ' << result->Ndf() << 
' ' << (result->IsValid() ? 
"" : 
"failed") << endl;
 
  513       cout << 
"Rate_Hz= " << 
FIXED(8,4) << 
values.Rate_Hz << (result->IsParameterFixed(fit.getModelParameter(&JFitK40::Rate_Hz)) ? 
" *** fixed *** " : 
"") << endl;
 
  515       cout << 
"p1=      " << 
FIXED(8,4) << 
values.p1      << (result->IsParameterFixed(fit.getModelParameter(&
JFitK40::p1))      ? 
" *** fixed *** " : 
"") << endl;
 
  516       cout << 
"p2=      " << 
FIXED(8,4) << 
values.p2      << (result->IsParameterFixed(fit.getModelParameter(&
JFitK40::p2))      ? 
" *** fixed *** " : 
"") << endl;
 
  517       cout << 
"p3=      " << 
FIXED(8,4) << 
values.p3      << (result->IsParameterFixed(fit.getModelParameter(&
JFitK40::p2))      ? 
" *** fixed *** " : 
"") << endl;
 
  518       cout << 
"p4=      " << 
FIXED(8,4) << 
values.p4      << (result->IsParameterFixed(fit.getModelParameter(&
JFitK40::p3))      ? 
" *** fixed *** " : 
"") << endl;
 
  520       cout << 
"Background (correlated):   " << 
FIXED(8,5) << 
values.bg << (result->IsParameterFixed(fit.getModelParameter(&JFitK40::bg)) ? 
" *** fixed *** " : 
"") << endl;
 
  521       cout << 
"Background (uncorrelated): " << 
FIXED(8,5) << 
values.cc << (result->IsParameterFixed(fit.getModelParameter(&JFitK40::cc)) ? 
" *** fixed *** " : 
"") << endl;
 
  523       cout << 
" PMT t0 [ns] TTS [ns]   R" << endl;
 
  530              << setw(2)    << pmt             << 
' ' 
  531              << 
FIXED(7,2) << fit.getT0 (pmt) << 
' ' 
  532              << 
FIXED(7,2) << fit.getTTS(pmt) << 
' ' 
  533              << 
FIXED(7,3) << fit.getQE (pmt);
 
  535         cout << (result->IsParameterFixed(fit.getModelParameter(pmt, &JPMTParameters_t::QE))  ? 
" *** fixed QE  *** " : 
"");
 
  536         cout << (result->IsParameterFixed(fit.getModelParameter(pmt, &JPMTParameters_t::TTS)) ? 
" *** fixed TTS *** " : 
"");
 
  537         cout << (result->IsParameterFixed(fit.getModelParameter(pmt, &JPMTParameters_t::t0))  ? 
" *** fixed t0  *** " : 
"");
 
  538         cout << (fit.is_disabled  (pmt) ? 
" (disabled)" : 
"");
 
  539         cout << (fit.is_average_t0(pmt) ? 
" (averaged)" : 
"");
 
  542         Q[0].
put(fit.getT0 (pmt));
 
  543         Q[1].
put(fit.getTTS(pmt));
 
  544         Q[2].
put(fit.getQE (pmt));
 
  581         h1t.SetBinContent(pmt + 1, 
values.getT0 (pmt));
 
  582         h1s.SetBinContent(pmt + 1, 
values.getTTS(pmt));
 
  583         h1q.SetBinContent(pmt + 1, 
values.getQE (pmt));
 
  585         h1t.SetBinError  (pmt + 1, max(errors.getT0 (pmt), 
epsilon));
 
  586         h1s.SetBinError  (pmt + 1, max(errors.getTTS(pmt), 
epsilon));
 
  587         h1q.SetBinError  (pmt + 1, max(errors.getQE (pmt), 
epsilon));
 
  590       out << h1t << h1s << h1q;
 
  609       if (overwriteDetector) {
 
  610         module->getPMT(pmt).addT0(fit.getT0(pmt));
 
  620     out << hc << p1 << p2 << p3 << p4 << bg << cc;
 
  634   if (overwriteDetector) {
 
  636     NOTICE(
"Store calibration data on file " << detectorFile << endl);
 
Utility class to parse command line options. 
 
JCombinatorics::pair_type pair_type
 
Q(UTCMax_s-UTCMin_s)-livetime_s
 
int main(int argc, char *argv[])
 
#define gmake_property(A)
macro to convert (template) parameter to JPropertiesElement object 
 
bool is_valid(const json &js)
Check validity of JSon data. 
 
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. 
 
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...
 
const JPolynome f1(1.0, 2.0, 3.0)
Function. 
 
Type definition of range. 
 
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 
 
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. 
 
bool putObject(TDirectory &dir, const TObject &object)
Write object to ROOT directory. 
 
General purpose messaging. 
 
Fit parameters for single PMT. 
 
z range($ZMAX-$ZMIN)< $MINIMAL_DZ." fi fi 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. 
 
no fit printf nominal n $STRING awk v X
 
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 JAcoustics sh $DETECTOR_ID source JAcousticsToolkit sh CHECK_EXIT_CODE typeset A EMITTERS get_tripods $WORKDIR tripod txt EMITTERS get_transmitters $WORKDIR transmitter txt EMITTERS 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.