Jpp  18.3.0
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Functions
JFitK40.cc File Reference

Auxiliary program to fit PMT parameters from JMergeCalibrateK40.cc output. More...

#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <set>
#include <vector>
#include <algorithm>
#include "TROOT.h"
#include "TFile.h"
#include "TH1D.h"
#include "TH2D.h"
#include "km3net-dataformat/online/JDAQ.hh"
#include "km3net-dataformat/online/JDAQHeader.hh"
#include "JTools/JConstants.hh"
#include "JDetector/JDetector.hh"
#include "JDetector/JDetectorToolkit.hh"
#include "JDetector/JPMTParametersMap.hh"
#include "JDetector/JStringRouter.hh"
#include "JROOT/JRootFileWriter.hh"
#include "JROOT/JRootToolkit.hh"
#include "JTools/JRange.hh"
#include "JLang/JSTDObjectWriter.hh"
#include "JSupport/JMeta.hh"
#include "JSupport/JSingleFileScanner.hh"
#include "JCalibrate/JCalibrateK40.hh"
#include "JCalibrate/JTDC_t.hh"
#include "JFitK40.hh"
#include "Jeep/JProperties.hh"
#include "Jeep/JPrint.hh"
#include "Jeep/JParser.hh"
#include "Jeep/JMessage.hh"

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Detailed Description

Auxiliary program to fit PMT parameters from JMergeCalibrateK40.cc output.


Note that the contebts of the 2D histograms are converted to standard deviations.

Author
mdejong

Definition in file JFitK40.cc.

Function Documentation

int main ( int  argc,
char **  argv 
)

Definition at line 61 of file JFitK40.cc.

62 {
63  using namespace std;
64  using namespace JPP;
65  using namespace KM3NETDAQ;
66 
67  typedef JRange<double> JRange_t;
68 
70 
71  string inputFile;
72  string outputFile;
73  string detectorFile;
74  string pmtFile;
75  JTDC_t TDC;
76  bool reverse;
77  bool overwriteDetector;
78  JCounter writeFits;
79  bool fitAngle;
80  bool fitNoise;
81  bool fitModel;
82  bool fixQE;
83  JRange_t X;
84  JRange_t Y;
85  int debug;
86 
87  try {
88 
89  JProperties properties;
90 
91  properties.insert(gmake_property(MINIMAL_RATE_HZ));
92  properties.insert(gmake_property(STDEV));
93  properties.insert(gmake_property(MAXIMAL_COUNTS));
94  properties.insert(gmake_property(QE_MIN));
95  properties.insert(gmake_property(K40.R));
96  properties.insert(gmake_property(K40.p1));
97  properties.insert(gmake_property(K40.p2));
98  properties.insert(gmake_property(K40.p3));
99  properties.insert(gmake_property(K40.p4));
100 
101  JParser<> zap("Auxiliary program to fit PMT parameters from JMergeCalibrateK40 output.");
102 
103  zap['@'] = make_field(properties) = JPARSER::initialised();
104  zap['f'] = make_field(inputFile, "input file (output from JMergeCalibrateK40).");
105  zap['o'] = make_field(outputFile, "output file.") = "fit.root";
106  zap['a'] = make_field(detectorFile, "detector file.");
107  zap['P'] = make_field(pmtFile, "specify PMT file name that can be given to JTriggerEfficiency.") = "";
108  zap['!'] = make_field(TDC,
109  "Fix time offset(s) of PMT(s) of certain module(s), e.g."
110  "\n-! \"808969848 0 808982077 23\" will fix time offsets of PMT 0 of module 808969848 and of PMT 23 of module 808982077."
111  "\nSame PMT offset can be fixed for all optical modules, e.g."
112  "\n-! \"-1 0 -1 23\" will fix time offsets of PMTs 0 and 23 of all optical modules.") = JPARSER::initialised();
113  zap['r'] = make_field(reverse, "reverse TDC constraints due to option -! <TDC>.");
114  zap['A'] = make_field(overwriteDetector, "overwrite detector file provided through '-a' with fitted time offsets.");
115  zap['w'] = make_field(writeFits, "write fit results to ROOT file; -ww also write fitted TTS to PMT file.");
116  zap['D'] = make_field(fitAngle, "fit angular distribution; fix normalisation.");
117  zap['B'] = make_field(fitNoise, "fit background.");
118  zap['M'] = make_field(fitModel, "fit angular distribution as well as normalisation; fix PMT QEs = 1.0.");
119  zap['Q'] = make_field(fixQE, "fix PMT QEs = 1.0.");
120  zap['x'] = make_field(X, "fit range (PMT pairs).") = JRange_t();
121  zap['y'] = make_field(Y, "fit range (time residual [ns]).") = JRange_t();
122  zap['d'] = make_field(debug, "debug.") = 1;
123 
124  zap(argc, argv);
125  }
126  catch(const exception &error) {
127  FATAL(error.what() << endl);
128  }
129 
130 
131  if ((fitModel ? 1 : 0) +
132  (fitAngle ? 1 : 0) +
133  (fitNoise ? 1 : 0) +
134  (fixQE ? 1 : 0) > 1) {
135  FATAL("Use either option -M, -D, -B or -Q" << endl);
136  }
137 
138  const int option = (fitModel ? FIT_MODEL_t :
140  fitNoise ? FIT_PMTS_AND_BACKGROUND_t :
141  fixQE ? FIT_PMTS_QE_FIXED_t :
142  FIT_PMTS_t);
143 
144  if (reverse) {
145  TDC.reverse();
146  }
147 
148  for (JTDC_t::const_iterator i = TDC.begin(); i != TDC.end(); ++i) {
149  DEBUG("PMT " << setw(10) << i->first << ' ' << setw(2) << i->second << " constrain t0." << endl);
150  }
151 
152  try {
153  TDC.is_valid(true);
154  }
155  catch(const exception &error) {
156  FATAL(error.what() << endl);
157  }
158 
160 
161  try {
162  load(detectorFile, detector);
163  }
164  catch(const JException& error) {
165  FATAL(error);
166  }
167 
168 
170 
171  if (pmtFile != "") {
172  try {
173  parameters.load(pmtFile.c_str());
174  }
175  catch(const exception& error) {}
176  }
177 
178  parameters.comment.add(JMeta(argc, argv));
179 
180 
181  TFile* in = TFile::Open(inputFile.c_str(), "exist");
182 
183  if (in == NULL || !in->IsOpen()) {
184  FATAL("File: " << inputFile << " not opened." << endl);
185  }
186 
187 
188  TFile out(outputFile.c_str(), "recreate");
189 
190  TH1D h0("chi2", NULL, 500, 0.0, 5.0);
191  TH1D hn("hn", NULL, 501, -0.5, 500.0);
192  TH1D hr("rate", NULL, 500, 0.0, 25.0);
193  TH1D h1("p1", NULL, 500, -5.0, +5.0);
194  TH1D h2("p2", NULL, 500, -5.0, +5.0);
195  TH1D h3("p3", NULL, 500, -5.0, +5.0);
196  TH1D h4("p4", NULL, 500, -5.0, +5.0);
197  TH1D hc("cc", NULL, 500, -0.1, +0.1);
198 
201 
202  TH2D H2("detector", NULL,
203  string.size() + 0, -0.5, string.size() - 0.5,
204  range.getUpperLimit(), 1 - 0.5, range.getUpperLimit() + 0.5);
205 
206  for (Int_t i = 1; i <= H2.GetXaxis()->GetNbins(); ++i) {
207  H2.GetXaxis()->SetBinLabel(i, MAKE_CSTRING(string.at(i-1)));
208  }
209  for (Int_t i = 1; i <= H2.GetYaxis()->GetNbins(); ++i) {
210  H2.GetYaxis()->SetBinLabel(i, MAKE_CSTRING(i));
211  }
212 
213 
214  JFit fit(0, debug);
215 
216  for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
217 
218  if (module->getFloor() == 0) {
219  continue;
220  }
221 
222  const JTDC_t::range_type range = TDC.equal_range(module->getID());
223 
224  NOTICE("Module " << setw(10) << module->getID() << ' ' << getLabel(module->getLocation()) << " !" << distance(range.first, range.second) << endl);
225 
226  TH2D* h2d = (TH2D*) in->Get(MAKE_CSTRING(module->getID() << _2R));
227 
228  if (h2d == NULL || h2d->GetEntries() == 0) {
229 
230  NOTICE("No data for module " << module->getID() << " -> set QEs to 0." << endl);
231 
232  for (int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
233  parameters[JPMTIdentifier(module->getID(), pmt)].QE = 0.0;
234  }
235 
236  continue;
237  }
238 
239  JModel model(*module, K40, range, option);
240 
241  data_type data; // input data
242 
243  vector<size_t> count[2] = { vector<size_t>(NUMBER_OF_PMTS, 0), // counter (exclude self)
244  vector<size_t>(NUMBER_OF_PMTS, 1) }; // counter (include self)
245 
246  for (int ix = 1; ix <= h2d->GetXaxis()->GetNbins(); ++ix) {
247 
248  const pair_type pair = model.getPair(ix - 1);
249 
250  auto& buffer = data[pair]; // storage
251 
252  double V = 0.0; // integrated value
253  double W = 0.0; // integrated error
254 
255  for (int iy = 1; iy <= h2d->GetYaxis()->GetNbins(); ++iy) {
256 
257  const double x = h2d->GetXaxis()->GetBinCenter(ix);
258  const double y = h2d->GetYaxis()->GetBinCenter(iy);
259 
260  if (X(x) && Y(y)) {
261 
262  double value = h2d->GetBinContent(ix,iy);
263  double error = h2d->GetBinError (ix,iy);
264 
265  buffer.push_back(rate_type(y, value, error));
266 
267  double width = h2d->GetYaxis()->GetBinWidth(iy);
268 
269  value *= width;
270  error *= width;
271 
272  V += value;
273  W += error * error;
274  }
275  }
276 
277  W = sqrt(W);
278 
279  if (V <= 0.0 - STDEV*W) {
280  count[0][pair.first] += 1;
281  count[0][pair.second] += 1;
282  }
283 
284  if (V <= MINIMAL_RATE_HZ + STDEV*W) {
285  count[1][pair.first] += 1;
286  count[1][pair.second] += 1;
287  }
288  }
289 
290  for (int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
291 
292  if (count[0][pmt] >= MAXIMAL_COUNTS) { // too many paired rates negative
293 
294  WARNING("PMT " << setw(10) << module->getID() << '.' << FILL(2,'0') << pmt << FILL() << " some rates negative -> fit background" << endl);
295 
296  if (fit.value.parameters[pmt].status) {
297  model.parameters[pmt].bg.set();
298  }
299  }
300 
301  if (count[1][pmt] == NUMBER_OF_PMTS) { // all paired rates too low
302 
303  WARNING("PMT " << setw(10) << module->getID() << '.' << FILL(2,'0') << pmt << FILL() << " all rates to low -> disable" << endl);
304 
305  model.parameters[pmt].disable();
306  }
307  }
308 
309  DEBUG("Start value:" << endl << model << endl);
310 
311  try {
312 
313  fit.value = model; // start value
314 
315  auto result = fit(data);
316 
317  bool refit = false;
318 
319  for (int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
320 
321  if (fit.value.parameters[pmt].QE() < QE_MIN && fit.value.parameters[pmt].status) {
322 
323  WARNING("PMT " << setw(10) << module->getID() << '.' << FILL(2,'0') << pmt << FILL() << ' ' << FIXED(5,3) << fit.value.parameters[pmt].QE() << " < " << FIXED(5,3) << QE_MIN << " -> disable" << (!refit ? " and refit" : "") << endl);
324 
325  fit.value.parameters[pmt].disable();
326 
327  refit = true;
328  }
329  }
330 
331  if (refit) {
332  refit = false;
333  result = fit(data);
334  }
335 
336  NOTICE("Fit result " << setw(10) << module->getID() << " chi2 / NDF " << FIXED(10,2) << result.chi2 << " / " << setw(5) << result.ndf << ' ' << setw(5) << fit.numberOfIterations << endl);
337 
338  DEBUG(fit.value);
339 
340  if (writeFits) {
341 
342  h0.Fill(result.chi2 / result.ndf);
343  hn.Fill(fit.numberOfIterations);
344  hr.Fill(fit.value.R );
345  h1.Fill(fit.value.p1);
346  h2.Fill(fit.value.p2);
347  h3.Fill(fit.value.p3);
348  h4.Fill(fit.value.p4);
349  hc.Fill(fit.value.cc);
350 
351  for (int ix = 1; ix <= h2d->GetXaxis()->GetNbins(); ++ix) {
352 
353  const pair_type pair = fit.value.getPair(ix - 1);
354 
355  for (int iy = 1; iy <= h2d->GetYaxis()->GetNbins(); ++iy) {
356 
357  const double dt_ns = h2d->GetYaxis()->GetBinCenter(iy);
358 
359  h2d->SetBinContent(ix, iy, fit.value.getValue(pair, dt_ns));
360  h2d->SetBinError (ix, iy, 0.0);
361  }
362  }
363 
364  h2d->SetName(MAKE_CSTRING(module->getID() << _2F));
365  h2d->Write();
366 
367  H2.Fill((double) string.getIndex(module->getString()), (double) module->getFloor(), result.chi2 / result.ndf);
368  }
369 
370  const double t0 = (fit.value.hasFixedTimeOffset() ? fit.value.getFixedTimeOffset() : 0.0);
371 
372  for (int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
373 
374  JPMTParameters& data = parameters[JPMTIdentifier(module->getID(), pmt)];
375 
376  const double P = getSurvivalProbability(data);
377 
378  if (P > 0.0)
379  data.QE = fit.value.parameters[pmt].QE / P;
380  else
381  data.QE = 0.0;
382 
383  if (writeFits > 1) {
384  data.TTS_ns = fit.value.parameters[pmt].TTS();
385  }
386 
387  module->getPMT(pmt).addT0(fit.value.parameters[pmt].t0.get() - t0);
388  }
389  }
390  catch(const exception& error) {
391 
392  ERROR("Module " << setw(10) << module->getID() << ' ' << error.what() << " -> set QEs to 0." << endl);
393 
394  for (int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
395  parameters[JPMTIdentifier(module->getID(), pmt)].QE = 0.0;
396  }
397  }
398  }
399 
400 
401  vector<JMeta> meta(1, JMeta(argc, argv));
402 
403  {
404  JSingleFileScanner<JMeta> reader(inputFile);
405  JSTDObjectWriter <JMeta> writer(meta);
406 
407  writer << reader;
408  }
409 
410  for (vector<JMeta>::const_reverse_iterator i = meta.rbegin(); i != meta.rend(); ++i) {
411  parameters.comment.add(*i);
412  detector .comment.add(*i);
413  }
414 
415  if (overwriteDetector) {
416 
417  NOTICE("Store calibration data on file " << detectorFile << endl);
418 
419  store(detectorFile, detector);
420  }
421 
422  if (pmtFile != "") {
423  parameters.store(pmtFile.c_str());
424  }
425 
426 
427  for (vector<JMeta>::const_iterator i = meta.begin(); i != meta.end(); ++i) {
428  putObject(out,*i);
429  }
430 
431  for (JRootFileReader<JDAQHeader> in(inputFile.c_str()); in.hasNext(); ) {
432  putObject(out, *in.next());
433  }
434 
435  if (writeFits) {
436  out << h0 << hn << hr << h1 << h2 << h3 << h4 << hc << H2;
437  }
438 
439  out.Close();
440 
441  return 0;
442 }
Data structure for measured coincidence rate of pair of PMTs.
Definition: JFitK40.hh:64
Auxiliary class for ROOT I/O of application specific meta data.
Definition: JMeta.hh:70
Utility class to parse command line options.
Definition: JParser.hh:1514
General exception.
Definition: JException.hh:24
#define WARNING(A)
Definition: JMessage.hh:65
Acoustic counter.
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
#define gmake_property(A)
macros to convert (template) parameter to JPropertiesElement object
std::string getLabel(const JLocation &location)
Get module label for monitoring and other applications.
Definition: JLocation.hh:246
Detector data structure.
Definition: JDetector.hh:89
Auxiliary class for TDC constraints.
Definition: JTDC_t.hh:37
Utility class to parse parameter values.
Definition: JProperties.hh:497
Data structure for a pair of indices.
*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
Definition: diff-Tuna.sh:38
#define MAKE_CSTRING(A)
Make C-string.
Definition: JPrint.hh:136
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:83
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.
Definition: JManip.hh:446
V(JDAQEvent-JTriggerReprocessor)*1.0/(JDAQEvent+1.0e-10)
string outputFile
floor_range getRangeOfFloors(const JDetector &detector)
Get range of floors.
Acoustic single fit.
Implementation of object output from STD container.
Model for fit to acoustics data.
fit parameters of PMTs
Definition: JFitK40.hh:51
Type definition of range.
Definition: JHead.hh:41
static const char *const _2F
Name extension for 2F rate fitted.
Detector file.
Definition: JHead.hh:226
Fit parameters for two-fold coincidence rate due to K40.
Definition: JFitK40.hh:606
T & getInstance(const T &object)
Get static instance from temporary object.
Definition: JObject.hh:75
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1989
fit parameters of PMTs and background
Definition: JFitK40.hh:53
void store(const std::string &file_name, const JDetector &detector)
Store detector to output file.
fit parameters of PMTs and angular dependence of K40 rate
Definition: JFitK40.hh:52
#define NOTICE(A)
Definition: JMessage.hh:64
#define ERROR(A)
Definition: JMessage.hh:66
then awk string
static const char *const _2R
Name extension for 2D rate measured.
Auxiliary class for map of PMT parameters.
int getIndex()
Get index for user I/O manipulation.
Definition: JManip.hh:26
bool putObject(TDirectory &dir, const TObject &object)
Write object to ROOT directory.
Auxiliary data structure for sequence of same character.
Definition: JManip.hh:328
#define FATAL(A)
Definition: JMessage.hh:67
fit parameters of PMTs with QE fixed
Definition: JFitK40.hh:54
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.
double TTS_ns
transition time spread [ns]
Router for mapping of string identifier to index.
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
Definition: JCanberra.sh:48
fit parameters of K40 rate and TTSs of PMTs
Definition: JFitK40.hh:55
double getSurvivalProbability(const JPMTParameters &parameters)
Get model dependent probability that a one photo-electron hit survives the simulation of the PMT assu...
Data structure for measured coincidence rates of all pairs of PMTs in optical module.
Definition: JFitK40.hh:99
set_variable TDC
Definition: JPrintTDC.sh:20
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
static const int NUMBER_OF_PMTS
Total number of PMTs in module.
Definition: JDAQ.hh:26
double QE
relative quantum efficiency
Livetime of noise data.
Definition: JHead.hh:1062
ROOT file reader.
int debug
debug level
then $DIR JPlotNPE PDG P
Definition: JPlotNPE-PDG.sh:62
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62