64{
68
70
72
73 string inputFile;
75 string detectorFile;
76 string pmtFile;
78 bool reverse;
79 bool overwriteDetector;
81 bool fitAngle;
82 bool fitNoise;
83 bool fitModel;
84 bool fixQE;
88
89 try {
90
92
103
104 JParser<> zap(
"Auxiliary program to fit PMT parameters from JMergeCalibrateK40 output.");
105
107 zap[
'f'] =
make_field(inputFile,
"input file (output from JMergeCalibrateK40).");
109 zap[
'a'] =
make_field(detectorFile,
"detector file.");
110 zap[
'P'] =
make_field(pmtFile,
"specify PMT file name that can be given to JTriggerEfficiency.") =
"";
112 "Fix time offset(s) of PMT(s) of certain module(s), e.g."
113 "\n-! \"808969848 0 808982077 23\" will fix time offsets of PMT 0 of module 808969848 and of PMT 23 of module 808982077."
114 "\nSame PMT offset can be fixed for all optical modules, e.g."
115 "\n-! \"-1 0 -1 23\" will fix time offsets of PMTs 0 and 23 of all optical modules.") =
JPARSER::initialised();
116 zap[
'r'] =
make_field(reverse,
"reverse TDC constraints due to option -! <TDC>.");
117 zap[
'A'] =
make_field(overwriteDetector,
"overwrite detector file provided through '-a' with fitted time offsets.");
118 zap[
'w'] =
make_field(writeFits,
"write fit results to ROOT file; -ww also write fitted TTS to PMT file.");
119 zap[
'D'] =
make_field(fitAngle,
"fit angular distribution; fix normalisation.");
120 zap[
'B'] =
make_field(fitNoise,
"fit background.");
121 zap[
'M'] =
make_field(fitModel,
"fit angular distribution as well as normalisation; fix PMT QEs = 1.0.");
122 zap[
'Q'] =
make_field(fixQE,
"fix PMT QEs = 1.0.");
126
127 zap(argc, argv);
128 }
129 catch(const exception &error) {
130 FATAL(error.what() << endl);
131 }
132
133
134 if ((fitModel ? 1 : 0) +
135 (fitAngle ? 1 : 0) +
136 (fitNoise ? 1 : 0) +
137 (fixQE ? 1 : 0) > 1) {
138 FATAL(
"Use either option -M, -D, -B or -Q" << endl);
139 }
140
146
147 if (reverse) {
149 }
150
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);
153 }
154
155 try {
157 }
158 catch(const exception &error) {
159 FATAL(error.what() << endl);
160 }
161
163
164 try {
166 }
169 }
170
171
173
174 if (pmtFile != "") {
175 try {
176 parameters.
load(pmtFile.c_str());
177 }
178 catch(const exception& error) {}
179 }
180
182
183
184 TFile* in = TFile::Open(inputFile.c_str(), "exist");
185
186 if (in == NULL || !in->IsOpen()) {
187 FATAL(
"File: " << inputFile <<
" not opened." << endl);
188 }
189
190
192
193 TH1D h0("chi2", NULL, 500, 0.0, 5.0);
194 TH1D hn("hn", NULL, 501, -0.5, 500.0);
195 TH1D hr("rate", NULL, 500, 0.0, 25.0);
196 TH1D h1("p1", NULL, 500, -5.0, +5.0);
197 TH1D h2("p2", NULL, 500, -5.0, +5.0);
198 TH1D h3("p3", NULL, 500, -5.0, +5.0);
199 TH1D h4("p4", NULL, 500, -5.0, +5.0);
200 TH1D hc("cc", NULL, 500, -0.1, +0.1);
201 TH1D hb("bc", NULL, 500, -0.1, +0.1);
202
205
206 TH2D H2("detector", NULL,
207 string.size() + 0, -0.5, string.size() - 0.5,
209
210 for (Int_t i = 1; i <= H2.GetXaxis()->GetNbins(); ++i) {
211 H2.GetXaxis()->SetBinLabel(i,
MAKE_CSTRING(
string.at(i-1)));
212 }
213 for (Int_t i = 1; i <= H2.GetYaxis()->GetNbins(); ++i) {
215 }
216
217 TH2D* HN = (TH2D*) H2.Clone("iterations");
218
220
221 for (JDetector::iterator module =
detector.begin(); module !=
detector.end(); ++module) {
222
223 if (module->getFloor() == 0) {
224 continue;
225 }
226
228
229 NOTICE(
"Module " << setw(10) << module->getID() <<
' ' <<
getLabel(module->getLocation()) <<
" !" <<
distance(range.first, range.second) << endl);
230
232
233 if (h2d == NULL || h2d->GetEntries() == 0) {
234
235 NOTICE(
"No data for module " << module->getID() <<
" -> set QEs to 0." << endl);
236
239 }
240
241 continue;
242 }
243
245
247
250
251 for (int ix = 1; ix <= h2d->GetXaxis()->GetNbins(); ++ix) {
252
254
256
257 double V = 0.0;
258 double W = 0.0;
259
260 for (int iy = 1; iy <= h2d->GetYaxis()->GetNbins(); ++iy) {
261
262 const double x = h2d->GetXaxis()->GetBinCenter(ix);
263 const double y = h2d->GetYaxis()->GetBinCenter(iy);
264
265 if (X(x) && Y(y)) {
266
267 double value = h2d->GetBinContent(ix,iy);
268 double error = h2d->GetBinError (ix,iy);
269
270 buffer.push_back(
rate_type(y, value, error));
271
272 double width = h2d->GetYaxis()->GetBinWidth(iy);
273
274 value *= width;
275 error *= width;
276
277 V += value;
278 W += error * error;
279 }
280 }
281
282 W = sqrt(W);
283
284 if (V <= 0.0 - STDEV*W) {
285 count[0][
pair.first] += 1;
286 count[0][
pair.second] += 1;
287 }
288
289 if (V <= MINIMAL_RATE_HZ + STDEV*W) {
290 count[1][
pair.first] += 1;
291 count[1][
pair.second] += 1;
292 }
293 }
294
296
297 if (count[0][pmt] >= MAXIMAL_COUNTS) {
298
299 WARNING(
"PMT " << setw(10) << module->getID() <<
'.' <<
FILL(2,
'0') << pmt <<
FILL() <<
" some rates negative -> fit background" << endl);
300
301 if (fit.value.parameters[pmt].status) {
302 model.parameters[pmt].bg.set();
303 }
304 }
305
306 if (count[1][pmt] == NUMBER_OF_PMTS) {
307
308 WARNING(
"PMT " << setw(10) << module->getID() <<
'.' <<
FILL(2,
'0') << pmt <<
FILL() <<
" all rates to low -> disable" << endl);
309
310 model.parameters[pmt].disable();
311 }
312 }
313
314 DEBUG(
"Start value:" << endl <<
model << endl);
315
316 try {
317
319
321
323
324 ERROR(
"Fit result " << setw(10) << module->getID() <<
" NDF " << setw(5) <<
result.ndf <<
" -> skip" << endl);
325
326 continue;
327 }
328
329 bool refit = false;
330
332
333 if (fit.value.parameters[pmt].status) {
334
335 if (fit.value.parameters[pmt].QE() <= QE_MIN ||
336 fit.value.parameters[pmt].QE() <= 0.0 + STDEV * fit.error.parameters[pmt].QE()) {
337
338 WARNING(
"PMT " << setw(10) << module->getID() <<
'.' <<
FILL(2,
'0') << pmt <<
FILL() <<
' '
339 << "QE = "
340 <<
FIXED(5,3) << fit.value.parameters[pmt].QE() <<
" +/- "
341 <<
FIXED(5,3) << fit.error.parameters[pmt].QE() <<
" "
342 << " -> disable" << (!refit ? " and refit" : "") << endl);
343
344 fit.value.parameters[pmt].disable();
345
346 refit = true;
347 }
348
349 if (fit.value.parameters[pmt].t0.atLimit(T0_NS)) {
350
351 WARNING(
"PMT " << setw(10) << module->getID() <<
'.' <<
FILL(2,
'0') << pmt <<
FILL() <<
' '
352 << "t0 at limit "
353 <<
FIXED(5,3) << fit.value.parameters[pmt].t0() <<
" +/- "
354 <<
FIXED(5,3) << fit.error.parameters[pmt].t0() <<
" "
355 << " -> disable" << (!refit ? " and refit" : "") << endl);
356
357 fit.value.parameters[pmt].disable();
358
359 refit = true;
360 }
361 }
362 }
363
364 if (refit) {
365
367 if (fit.value.parameters[pmt].status) {
369 }
370 }
371
372 refit = false;
374 }
375
376 NOTICE(
"Fit result " << setw(10) << module->getID() <<
" chi2 / NDF " <<
FIXED(10,2) <<
result.chi2 <<
" / " << setw(5) <<
result.ndf <<
' ' << setw(5) << fit.numberOfIterations << endl);
377
380 }
381
383
384 if (writeFits) {
385
387 hn.Fill(fit.numberOfIterations);
388 hr.Fill(fit.value.R );
389 h1.Fill(fit.value.p1);
390 h2.Fill(fit.value.p2);
391 h3.Fill(fit.value.p3);
392 h4.Fill(fit.value.p4);
393 hc.Fill(fit.value.cc);
394 hb.Fill(fit.value.bc);
395
396 TH1D h1t(
MAKE_CSTRING(module->getID() <<
".1t0"), NULL, NUMBER_OF_PMTS, -0.5, NUMBER_OF_PMTS - 0.5);
397 TH1D h1s(
MAKE_CSTRING(module->getID() <<
".1TTS"), NULL, NUMBER_OF_PMTS, -0.5, NUMBER_OF_PMTS - 0.5);
398 TH1D h1q(
MAKE_CSTRING(module->getID() <<
".1QE"), NULL, NUMBER_OF_PMTS, -0.5, NUMBER_OF_PMTS - 0.5);
399
401 h1t.SetBinContent(pmt + 1, fit.value.parameters[pmt].t0 ());
402 h1t.SetBinError (pmt + 1, fit.error.parameters[pmt].t0 () + numeric_limits<double>::epsilon());
403 h1s.SetBinContent(pmt + 1, fit.value.parameters[pmt].TTS());
404 h1s.SetBinError (pmt + 1, fit.error.parameters[pmt].TTS() + numeric_limits<double>::epsilon());
405 h1q.SetBinContent(pmt + 1, fit.value.parameters[pmt].QE ());
406 h1q.SetBinError (pmt + 1, fit.error.parameters[pmt].QE () + numeric_limits<double>::epsilon());
407 }
408
409 out << h1t << h1s << h1q;
410
411 for (int ix = 1; ix <= h2d->GetXaxis()->GetNbins(); ++ix) {
412
414
415 for (int iy = 1; iy <= h2d->GetYaxis()->GetNbins(); ++iy) {
416
417 const double dt_ns = h2d->GetYaxis()->GetBinCenter(iy);
418
419 h2d->SetBinContent(ix, iy, fit.value.getValue(
pair, dt_ns));
420 h2d->SetBinError (ix, iy, 0.0);
421 }
422 }
423
425 h2d->Write();
426
427 const double x =
string.getIndex(module->getString());
428 const double y =
module->getFloor();
429
431 HN->Fill(x, y, fit.numberOfIterations);
432 }
433
434 const double t0 = (fit.value.hasFixedTimeOffset() ? fit.value.getFixedTimeOffset() : 0.0);
435
437
439
441
442 if (P > 0.0)
443 data.QE = fit.value.parameters[pmt].QE / P;
444 else
446
447 if (writeFits > 1) {
448 data.TTS_ns = fit.value.parameters[pmt].TTS();
449 }
450
451 module->getPMT(pmt).addT0(fit.value.parameters[pmt].t0.get() - t0);
452 }
453 }
454 catch(const exception& error) {
455
456 ERROR(
"Module " << setw(10) << module->getID() <<
' ' << error.what() <<
" -> set QEs to 0." << endl);
457
460 }
461 }
462 }
463
464
466
467 {
469 JSTDObjectWriter <JMeta> writer(meta);
470
471 writer << reader;
472 }
473
474 for (vector<JMeta>::const_reverse_iterator i = meta.rbegin(); i != meta.rend(); ++i) {
477 }
478
479 if (overwriteDetector) {
480
481 NOTICE(
"Store calibration data on file " << detectorFile << endl);
482
484 }
485
486 if (pmtFile != "") {
487 parameters.
store(pmtFile.c_str());
488 }
489
490
491 for (vector<JMeta>::const_iterator i = meta.begin(); i != meta.end(); ++i) {
493 }
494
497 }
498
499 if (writeFits) {
500 out << h0 << hn << hr << h1 << h2 << h3 << h4 << hc << hb << H2 << *HN;
501 }
502
503 out.Close();
504
505 return 0;
506}
#define DEBUG(A)
Message macros.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
#define MAKE_CSTRING(A)
Make C-string.
#define gmake_property(A)
macros to convert (template) parameter to JPropertiesElement object
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
Auxiliary class for map of PMT parameters.
Data structure for PMT parameters.
Utility class to parse parameter values.
Utility class to parse command line options.
Object reading from a list of files.
static const char *const _2F
Name extension for 2F rate fitted.
@ FIT_PMTS_QE_FIXED_t
fit parameters of PMTs with QE fixed
@ FIT_PMTS_AND_ANGULAR_DEPENDENCE_t
fit parameters of PMTs and angular dependence of K40 rate
@ FIT_MODEL_t
fit parameters of K40 rate and TTSs of PMTs
@ FIT_PMTS_AND_BACKGROUND_t
fit parameters of PMTs and background
@ FIT_PMTS_t
fit parameters of PMTs
static const char *const _2R
Name extension for 2D rate measured.
std::string getLabel(const JLocation &location)
Get module label for monitoring and other applications.
floor_range getRangeOfFloors(const JDetector &detector)
Get range of floors.
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
void store(const std::string &file_name, const JDetector &detector)
Store detector to output file.
double getSurvivalProbability(const JPMTParameters ¶meters)
Get model dependent probability that a one photo-electron hit survives the simulation of the PMT assu...
void model(JModel_t &value)
Auxiliary function to constrain model during fit.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
bool putObject(TDirectory &dir, const TObject &object)
Write object to ROOT directory.
KM3NeT DAQ data structures and auxiliaries.
static const int NUMBER_OF_PMTS
Total number of PMTs in module.
Auxiliary data structure for sequence of same character.
Auxiliary data structure for floating point format specification.
Type definition of range.
Model for fit to acoustics data.
Fit parameters for two-fold coincidence rate due to K40.
static const JK40Parameters & getInstance()
Get default values.
static const JPMTParameters_t & getInstance()
Get default values.
Auxiliary class for TDC constraints.
range_type equal_range(const int id)
Get range of constraints for given module.
void reverse()
Reverse constraints.
bool is_valid(const bool option=false) const
Check validity of TDC constrants.
Data structure for measured coincidence rates of all pairs of PMTs in optical module.
Data structure for measured coincidence rate of pair of PMTs.
Router for mapping of string identifier to index.
void store(const char *file_name) const
Store to output file.
void load(const char *file_name)
Load from input file.
Empty structure for specification of parser element that is initialised (i.e. does not require input)...