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 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.