Jpp  pmt_effective_area_update_2
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JFitToT.cc
Go to the documentation of this file.
1 #include <string>
2 #include <iostream>
3 #include <iomanip>
4 
5 #include "TROOT.h"
6 #include "TFile.h"
7 #include "TH1D.h"
8 #include "TH2D.h"
9 #include "TF1.h"
10 #include "TFitResult.h"
11 #include "TMath.h"
12 
13 #include "JLang/JLangToolkit.hh"
14 #include "JPhysics/JConstants.hh"
16 
17 #include "JDetector/JDetector.hh"
21 
22 #include "JROOT/JRootToolkit.hh"
23 
24 #include "JTools/JRange.hh"
25 
26 #include "JSupport/JMeta.hh"
27 #include "JSupport/JSupport.hh"
30 
32 #include "JCalibrate/JFitToT.hh"
33 
34 #include "Jeep/JPrint.hh"
35 #include "Jeep/JParser.hh"
36 #include "Jeep/JMessage.hh"
37 
38 namespace {
39 
40  /**
41  * Wild card for histogram naming.\n
42  * The wild card will replaced by the module identifier.
43  */
44  static const char* const WILDCARD = "%";
45 }
46 
47 
48 /**
49  * \file
50  *
51  * Auxiliary program to fit time-over-threshold distributions.
52  * The fitted parameters are the PMT gain and gain spread.
53  * \author mkarel
54  */
55 int main(int argc, char **argv)
56 {
57  using namespace std;
58  using namespace JPP;
59  using namespace KM3NETDAQ;
60 
61  typedef JRange<double> JRange_t;
63 
64  string inputFile;
66  string detectorFile;
67  string pmtFile;
68  bool writeFits;
69 
70  double Wmin = 5e3; //!< Minimal histogram weight in fit range
71  double LeftMargin = 10.0; //!< Fit range left of time-over-threshold peak
72  double RightMargin = 10.0; //!< Fit range right of time-over-threshold peak
73  double gradientThreshold = -0.005; //!< Minimal right-to-left gradient value in time-over-threshold peak-search,\n
74  //!<normalized with respect to the total number of histogram entries
75 
76  JRange_t fitRange;
77  string option;
78 
79  string regexp;
80  int debug;
81 
82  try {
83 
84  JProperties properties;
85 
86  properties.insert(gmake_property(Wmin));
87  properties.insert(gmake_property(LeftMargin));
88  properties.insert(gmake_property(RightMargin));
89  properties.insert(gmake_property(gradientThreshold));
90 
91  JParser<> zap("Auxiliary program to fit time-over-threshold distributions.");
92 
93  zap['f'] = make_field(inputFile, "input file (output from JCalibrateToT).");
94  zap['o'] = make_field(outputFile, "output file.") = "fit.root";
95  zap['a'] = make_field(detectorFile, "detector file.");
96  zap['P'] = make_field(pmtFile, "specify PMT file name that can be given to JTriggerEfficiency.") = "";
97  zap['w'] = make_field(writeFits, "write fit results.");
98  zap['O'] = make_field(option, "ROOT fit options, see TH1::Fit") = "";
99  zap['@'] = make_field(properties) = JPARSER::initialised();
100  zap['x'] = make_field(fitRange, "ROOT fit range (time-over-threshold).") = JRange_t(0.0, 35.0);
101  zap['R'] = make_field(regexp, "regular expression for histogram name.") = MAKE_CSTRING(WILDCARD << _2SToT);
102  zap['d'] = make_field(debug, "debug.") = 1;
103 
104  zap(argc, argv);
105  }
106  catch(const exception &error) {
107  FATAL(error.what() << endl);
108  }
109 
110 
111  //----------------------------------------------------------
112  // load detector file and PMT parameters
113  //----------------------------------------------------------
114 
116 
117  try {
118  load(detectorFile, detector);
119  }
120  catch(const JException& error) {
121  FATAL(error);
122  }
123 
124 
125  JPMTParametersMap parametersMap;
126 
127  if (!pmtFile.empty()) {
128 
129  try {
130  parametersMap.load(pmtFile.c_str());
131  }
132  catch(const JException& error) {}
133  }
134 
135  parametersMap.comment.add(JMeta(argc, argv));
136 
137  // Set ROOT fit options
138  if (option.find('R') == string::npos) { option += 'R'; }
139  if (option.find('S') == string::npos) { option += 'S'; }
140  if (option.find('Q') == string::npos && debug < JEEP::debug_t) { option += 'Q'; }
141 
142 
143  TFile* in = TFile::Open(inputFile.c_str(), "exist");
144 
145  if (in == NULL || !in->IsOpen()) {
146  FATAL("File: " << inputFile << " not opened." << endl);
147  }
148 
149 
150  TH2D gain("gain", NULL,
151  100, 0.0, 2.0,
152  100, 0.0, 1.0);
153  TH1D chi2("chi2", NULL, 100, 0.0, 5.0);
154 
155  outputFile.open();
156 
157  if (!outputFile.is_open()) {
158  FATAL("Error opening file " << outputFile << endl);
159  }
160 
161  outputFile.put(JMeta(argc, argv));
162 
163  //----------------------------------------------------------
164  // loop over modules in detector file to fit histogram
165  //----------------------------------------------------------
166 
167  for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
168 
169  NOTICE("Module " << setw(10) << module->getID() << ' ' << module->getLocation() << endl);
170 
171  if (module->empty()) {
172  continue;
173  }
174 
175  //----------------------------------------------------------
176  // get histogram for this module
177  //----------------------------------------------------------
178 
179  TH2D* h2s = (TH2D*) in->Get(replace(regexp, WILDCARD, MAKE_STRING(module->getID())).c_str());
180 
181  if (h2s == NULL) {
182 
183  WARNING("No histogram " << module->getID() << "; skip fit." << endl);
184 
185  continue;
186  }
187 
188  const double ny = h2s->GetYaxis()->GetNbins();
189  const double ymin = h2s->GetYaxis()->GetXmin();
190  const double ymax = h2s->GetYaxis()->GetXmax();
191 
192  TH1D chi2_1d (MAKE_CSTRING(module->getID() << ".1chi2"), NULL, NUMBER_OF_PMTS, -0.5, NUMBER_OF_PMTS-0.5);
193  TH1D gain_1d (MAKE_CSTRING(module->getID() << ".1gain"), NULL, NUMBER_OF_PMTS, -0.5, NUMBER_OF_PMTS-0.5);
194  TH1D gainspread_1d(MAKE_CSTRING(module->getID() << ".1gainspread"), NULL, NUMBER_OF_PMTS, -0.5, NUMBER_OF_PMTS-0.5);
195 
196  for (int ix = 1; ix <= h2s->GetXaxis()->GetNbins(); ++ix) {
197 
198  const JPMTIdentifier id(module->getID(), ix-1);
199 
200  const string name = MAKE_STRING(module->getID() << '.' << FILL(2,'0') <<
201  id.getPMTAddress() << FITTOT_SUFFIX);
202 
203  DEBUG("Processing histogram " << name << endl);
204 
205  TH1D h1(name.c_str(), NULL, ny, ymin, ymax);
206 
207  h1.Sumw2();
208 
209  for (int iy = h2s->GetNbinsY(); iy >= 1; --iy) {
210 
211  const double w = h1.GetBinWidth (iy);
212  const double y = h2s->GetBinContent(ix, iy);
213 
214  h1.SetBinContent(iy, y/w);
215  h1.SetBinError (iy, sqrt(y)/w);
216  }
217 
218  JRange_t range(fitRange);
219 
220  const double weight = h1.Integral(h1.FindBin(range.getLowerLimit()),
221  h1.FindBin(range.getUpperLimit()));
222 
223  if (weight <= Wmin) {
224 
225  WARNING("Insufficient histogram entries for PMT " << id <<
226  "(" << weight << " < " << Wmin << "); skip fit." << endl);
227 
228  if (writeFits) {
229  outputFile.put(h1);
230  }
231 
232  continue;
233  }
234 
235  //----------------------------------------------------------
236  // find the mode of the time-over-threshold distribution
237  //----------------------------------------------------------
238 
239  double max = 0.0;
240  double ToTmode = JDETECTOR::TIME_OVER_THRESHOLD_NS;
241 
242  JPMTParameters& parameters = parametersMap[id];
243 
244  DEBUG(RIGHT(10) << "ToT" << RIGHT(10) << "Counts" << RIGHT(10) << "gradient" <<
245  RIGHT(10) << "threshold" << RIGHT(10) << "Mode" << RIGHT(10) << "Max" << endl);
246 
247  for (int i = h1.GetBinCenter(ny-1);
248  i > h1.GetBinCenter(h1.FindBin(parameters.mean_ns + parameters.sigma_ns));
249  --i) {
250 
251  const double x = h1.GetBinCenter (i);
252  const double y = h1.GetBinContent(i);
253 
254  const double gradient = ( (h1.GetBinContent(i-1) - h1.GetBinContent(i+1)) /
255  (h1.GetBinCenter (i+1) - h1.GetBinCenter (i-1)) );
256 
257  DEBUG(FIXED(10,1) << x << FIXED(10,1) << y << FIXED(10,1) << gradient <<
258  FIXED(10,1) << -fabs(gradientThreshold) * h1.Integral() << FIXED(10,1) << ToTmode << FIXED(10,1) << max << endl);
259 
260 
261  if (y > max) {
262 
263  ToTmode = x;
264  max = y;
265 
266  } else if (gradient < -fabs(gradientThreshold) * h1.Integral()) {
267 
268  break;
269  }
270  }
271 
272  //----------------------------------------------------------
273  // set fit range
274  //----------------------------------------------------------
275 
276  if (!range.is_valid()) {
277  range.setRange(ToTmode - LeftMargin,
278  ToTmode + RightMargin);
279  }
280 
281  range.setRange(std::max(h1.GetXaxis()->GetXmin(), range.getLowerLimit()),
282  std::min(h1.GetXaxis()->GetXmax(), range.getUpperLimit()));
283 
284  DEBUG(LEFT(10) << "Fit-range: " << FIXED(20,1) << range << endl);
285 
286  //----------------------------------------------------------
287  // perform minimum chi-square fit
288  //----------------------------------------------------------
289 
290  JFitToT fit(parameters, range);
291 
292  const double initGain = fit.getCPU().getNPE(ToTmode);
293  const double initGainSpread = initGain / 3.0;
294 
295  if (initGain > FITTOT_GAIN_MAX || initGain < FITTOT_GAIN_MIN) { // Invalid initial gain value
296 
297  WARNING("Invalid initial gain for PMT " << id << "; set default values." << endl);
298 
299  parameters.gain = (initGain > FITTOT_GAIN_MAX ? FITTOT_GAIN_MAX : FITTOT_GAIN_MIN);
301 
302  if (writeFits) {
303  outputFile.put(h1);
304  }
305 
306  continue;
307  }
308 
309  fit.gain = initGain;
310  fit.gainSpread = initGainSpread;
311 
312  const TFitResultPtr result = fit(h1, option);
313 
314  if (int(result) < 0 || !result->IsValid()) { // Fit failed
315 
316  WARNING("Fit failure for PMT " << id << "; set initialization values." << endl);
317 
318  h1.GetListOfFunctions()->Clear();
319 
320  parameters.gain = initGain;
321  parameters.gainSpread = initGainSpread;
322 
323  if (writeFits) {
324  outputFile.put(h1);
325  }
326 
327  continue;
328  }
329 
330  if ((ymin < range.getLowerLimit() || ymax > range.getUpperLimit()) &&
331  (option.find("0") == string::npos && option.find("N") == string::npos)) {
332 
333  // add function with full range
334 
335  TF1* f1 = new TF1(MAKE_CSTRING(FITTOT_FNAME << "_fullRange"),
336  &fit,
338  ymin,
339  ymax,
340  JFitToT::getNumberOfModelParameters());
341  f1->SetParameters(fit.GetParameters());
342  f1->SetLineStyle(kDotted);
343  f1->SetNpx(1000);
344 
345  h1.GetListOfFunctions()->Add(f1);
346  }
347 
348  // store fit results
349 
350  const double reducedChi2 = result->Chi2() / result->Ndf();
351 
352  const JFitToTParameters values(fit.GetParameters());
353  const JFitToTParameters errors(fit.GetParErrors());
354 
355  chi2_1d. SetBinContent(ix, reducedChi2);
356  gain_1d. SetBinContent(ix, values.gain);
357  gain_1d. SetBinError (ix, errors.gain);
358  gainspread_1d.SetBinContent(ix, values.gainSpread);
359  gainspread_1d.SetBinError (ix, errors.gainSpread);
360 
361  gain.Fill(fit.gain, fit.gainSpread);
362  chi2.Fill(TMath::Log10(reducedChi2));
363 
364  NOTICE("PMT " << id << " chi2 / NDF " << result->Chi2() << ' ' << result->Ndf() << endl);
365 
366  parameters.gain = fit.gain;
367  parameters.gainSpread = fit.gainSpread;
368 
369  if (writeFits) {
370  outputFile.put(h1);
371  }
372  }
373 
374  if (writeFits) {
375  outputFile.put(chi2_1d);
376  outputFile.put(gain_1d);
377  outputFile.put(gainspread_1d);
378  }
379  }
380 
381  for (JSingleFileScanner<JMeta> in(inputFile); in.hasNext(); ) {
382 
383  const JMeta& meta = *in.next();
384 
385  parametersMap.comment.add(meta);
386 
387  outputFile.put(meta);
388  }
389 
390  if (pmtFile != "") {
391  parametersMap.store(pmtFile.c_str());
392  }
393 
394  outputFile.put(gain);
395  outputFile.put(chi2);
396 
397  outputFile.close();
398 }
399 
400 
Auxiliary class for ROOT I/O of application specific meta data.
Definition: JMeta.hh:70
Object writing to file.
Utility class to parse command line options.
Definition: JParser.hh:1500
General exception.
Definition: JException.hh:23
double gain
gain [unit]
data_type w[N+1][M+1]
Definition: JPolint.hh:741
#define WARNING(A)
Definition: JMessage.hh:65
double getValue(const JScale_t scale)
Get numerical value corresponding to scale.
Definition: JScale.hh:47
debug
Definition: JMessage.hh:29
int main(int argc, char *argv[])
Definition: Main.cc:15
ROOT TTree parameter settings of various packages.
TString replace(const TString &target, const TRegexp &regexp, const T &replacement)
Replace regular expression in input by given replacement.
Definition: JPrintResult.cc:63
#define gmake_property(A)
macro to convert (template) parameter to JPropertiesElement object
double gainSpread
gain spread [unit]
static const double FITTOT_GAIN_MAX
Default maximal gain.
Definition: JFitToT.hh:44
Detector data structure.
Definition: JDetector.hh:81
Double_t gainSpread
PMT gain spread.
Definition: JFitToT.hh:169
const double TIME_OVER_THRESHOLD_NS
Specification for time-over-threshold corresponding to a one photo-electron pulse.
static const double FITTOT_GAIN_MIN
Default minimal gain.
Definition: JFitToT.hh:43
Recording of objects on file according a format that follows from the file name extension.
then echo Enter input within $TIMEOUT_S seconds echo n User name
Definition: JCookie.sh:42
Utility class to parse parameter values.
Definition: JProperties.hh:496
*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:151
then for HISTOGRAM in h0 h1
Definition: JMatrixNZ.sh:71
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:66
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:446
string outputFile
Parametrisation of time-over-threshold distribution.
Definition: JFitToT.hh:179
Data structure for detector geometry and calibration.
Fit parameters for two-fold coincidence rate due to K40.
Definition: JFitToT.hh:53
#define MAKE_STRING(A)
Make string.
Definition: JPrint.hh:142
const JPMTAnalogueSignalProcessor & getCPU() const
Access method for the analogue signal processor.
Definition: JFitToT.hh:210
static const std::string FITTOT_SUFFIX
Definition: JFitToT.hh:36
Type list.
Definition: JTypeList.hh:22
Scanning of objects from a single file according a format that follows from the extension of each fil...
I/O formatting auxiliaries.
double mean_ns
mean time-over-threshold of threshold-band hits [ns]
Detector file.
Definition: JHead.hh:196
double sigma_ns
time-over-threshold standard deviation of threshold-band hits [ns]
static const double FITTOT_GAINSPREAD_MAX
Default maximal gain spread.
Definition: JFitToT.hh:47
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1961
return result
Definition: JPolint.hh:727
ROOT I/O of application specific meta data.
#define NOTICE(A)
Definition: JMessage.hh:64
Physics constants.
Auxiliary class for map of PMT parameters.
Double_t gain
PMT gain.
Definition: JFitToT.hh:168
int debug
debug level
Definition: JSirene.cc:63
General purpose messaging.
Auxiliary data structure for sequence of same character.
Definition: JManip.hh:328
#define FATAL(A)
Definition: JMessage.hh:67
void load(const char *file_name)
Load from input file.
z range($ZMAX-$ZMIN)< $MINIMAL_DZ." fi fi typeset -Z 4 STRING typeset -Z 2 FLOOR JPlot1D -f $
then $JPP_DIR examples JDetector JToT o $OUTPUT_FILE n N $NPE P gain
Definition: JToT.sh:47
virtual double getNPE(const double tot_ns, const double eps=1.0e-3) const
Get number of photo-electrons.
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.
then usage $script< input_file >< detector_file > fi set_variable OUTPUT_DIR set_variable SELECTOR JDAQTimesliceL1 set_variable DEBUG case set_variable DEBUG
static const char *const _2SToT
Histogram naming.
PMT analogue signal processor.
static const double FITTOT_GAINSPREAD_MIN
Default minimal gain spread.
Definition: JFitToT.hh:46
Object reading from a list of files.
possible values
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.
Definition: JDAQ.hh:26
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
Definition: JCanberra.sh:40
static const std::string FITTOT_FNAME
Definition: JFitToT.hh:37
std::vector< double > weight
Definition: JAlgorithm.hh:417