Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JFit_HTR.cc
Go to the documentation of this file.
1 
2 #include <string>
3 #include <iostream>
4 #include <iomanip>
5 #include <vector>
6 #include <algorithm>
7 
8 #include "evt/Head.hh"
9 #include "evt/Evt.hh"
10 #include "JDAQ/JDAQEvent.hh"
11 #include "JDAQ/JDAQTimeslice.hh"
12 #include "JDAQ/JDAQSummaryslice.hh"
13 
14 #include "JDetector/JDetector.hh"
17 
18 #include "JTrigger/JHit.hh"
19 #include "JTrigger/JFrame.hh"
20 #include "JTrigger/JTimeslice.hh"
21 #include "JTrigger/JHitL0.hh"
22 #include "JTrigger/JBuildL0.hh"
24 
27 #include "JSupport/JTreeScanner.hh"
29 #include "JSupport/JSupport.hh"
30 
31 #include "JFit/JLine3Z.hh"
32 #include "JFit/JGandalf.hh"
33 #include "JFit/JFitToolkit.hh"
34 #include "JFit/JEvt.hh"
35 #include "JFit/JEvtToolkit.hh"
36 #include "JFit/JRegressor.hh"
37 
38 #include "JTools/JConstants.hh"
39 #include "JTools/JFunction1D_t.hh"
41 #include "JTools/JRange.hh"
42 
43 #include "JPhysics/JPDFTable.hh"
44 #include "JPhysics/JPDFToolkit.hh"
45 
46 #include "Jeep/JParser.hh"
47 #include "Jeep/JMessage.hh"
48 
49 #include "TKey.h"
50 #include "TH1D.h"
51 #include "TF1.h"
52 
53 namespace {
54 
55  using namespace JPP;
56  using namespace std ;
57 
58  bool selectHTRentry(const JFit& bf) {
59 
60  //double Q = bf.getQ() ;
61  double dz = bf.getDZ() ;
62  //int N = bf.getN() ;
63  //double NDF = bf.getNDF() ;
64  //double chi2 = 4.0*(Q-NDF)*NDF ; // inverse of JFIT::getQuality
65 
66  // selection criteria
67  if (dz > -0.97) { return false ; }
68 
69  return true ;
70 
71  }
72 
73  double logPoison(double n, double nhat, double logP_min = -999999.9) {
74  if (nhat < 0.0 || n < 0.0) { FATAL("logPoisson: n (" << n <<") or nhat (" << nhat << ") is < 0.0" << std::endl) ; }
75  if (n == 0.0 && nhat == 0.0) { return 0.0 ; }
76  if (n == 0.0 && nhat > 0.0) { return logP_min ; }
77  if (n >= 0.0 && nhat == 0.0) { return logP_min ; }
78  return TMath::Log(TMath::Poisson(n, nhat)) ;
79  }
80 
81  double getLogQuality(const TH1D* data, const TH1D* model, int di, double n_min = 0.0001, double nhat_min = 0.0001) {
82 
83  double q = 0.0 ;
84  const double logQ_min = -999999.9 ;
85  const double logQ_empty = TMath::Max(logQ_min, logPoison(n_min, nhat_min)) ;
86  int Nempty = 0 ;
87 
88  for (int i = 1 ; i <= data->GetNbinsX() ; ++i) {
89 
90  if (i+di < 1 || i+di > model->GetNbinsX()) {
91 
92  q += logQ_empty ;
93  Nempty++ ;
94 
95  continue ;
96 
97  }
98 
99  double n = TMath::Max(n_min, data->GetBinContent(i)) ;
100  double nhat = TMath::Max(nhat_min, model->GetBinContent(i+di)) ;
101 
102  q += TMath::Max(logQ_min, logPoison(n, nhat)) ;
103 
104  }
105 
106  return q ;
107 
108  }
109 
110 }
111 
112 /**
113  * \file
114  *
115  * Program to fit hit time residual distributions according to a MC model.
116  *
117  * If the option <tt>-A</tt> is set, the time calibration will be stored in the detector file.
118  * \author mkarel
119  */
120 int main(int argc, char **argv)
121 {
122  using namespace std;
123  using namespace JPP;
124  using namespace KM3NETDAQ;
125 
126  string detectorFile ;
127  string inputFile_data;
128  string inputFile_mc;
129  double livetime_data;
130  double livetime_mc;
131  string outputFile;
132  JRange<double> dtrange ;
133  bool noInterString ;
134  bool overwriteDetector;
135  int debug;
136 
137  try {
138 
139  JParser<> zap;
140 
141  zap['f'] = make_field(inputFile_data);
142  zap['m'] = make_field(inputFile_mc);
143  zap['F'] = make_field(livetime_data);
144  zap['M'] = make_field(livetime_mc);
145  zap['o'] = make_field(outputFile) = "HTR_plots.root";
146  zap['a'] = make_field(detectorFile);
147  zap['A'] = make_field(overwriteDetector);
148  zap['T'] = make_field(dtrange) = JRange<double>(-5.0, 5.0); // fit range for time change fit
149  zap['I'] = make_field(noInterString) ;
150  zap['d'] = make_field(debug) = 1;
151 
152  zap(argc, argv);
153  }
154  catch(const exception& error) {
155  FATAL(error.what() << endl);
156  }
157 
158 
160 
161  try {
162  load(detectorFile, detector);
163  }
164  catch(const JException& error) {
165  FATAL(error);
166  }
167 
168  double dt_min = -100.0 ;
169  double dt_max = 100.0 ;
170  double dt_N =+(dt_max-dt_min)+1 ;
171 
172  cout.tie(&cerr);
173 
174  TFile infile_data(inputFile_data.c_str(),"read") ;
175  TFile infile_mc(inputFile_mc.c_str(),"read") ;
176 
177  TFile outfile(outputFile.c_str(),"recreate") ;
178 
179  vector<double> timeshift(detector.size(), 0.0) ;
180 
181  for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
182 
183  int domid = module->getID() ;
184 
185  TString DOMID(Form("%d", domid)) ;
186  TTree* htr_tree_data = (TTree*)infile_data.Get(DOMID+".htr") ;
187  if (htr_tree_data == NULL) { WARNING("Couldn't find model " << DOMID << ".htr in data file " << inputFile_data << " skipping DOM " << endl) ; continue ; }
188 
189  NOTICE( "processing " << DOMID << endl ) ;
190 
191  double htr_dt ;
192  JFit* bestfit = new JFit() ;
193  htr_tree_data->SetBranchAddress("dt",&htr_dt);
194  htr_tree_data->SetBranchAddress("bestfit",&bestfit) ;
195 
196  TH1D htr_data(DOMID+".htr_data", DOMID+".htr_data", dt_N, dt_min-0.5, dt_max+0.5) ;
197 
198  Long64_t nentries = htr_tree_data->GetEntries();
199  for (Long64_t i=0;i<nentries;i++) {
200  htr_tree_data->GetEntry(i);
201 
202  // selection criteria
203  if (selectHTRentry(*bestfit)) { htr_data.Fill(htr_dt) ; }
204 
205  }
206 
207  if (htr_data.Integral() < 1) { WARNING("No data in data file " << inputFile_data << " skipping DOM " << DOMID << endl) ; continue ; }
208 
209  // find corresponding tree in model
210  TTree* htr_tree_mc = (TTree*)infile_mc.Get(htr_tree_data->GetName()) ;
211  if (htr_tree_mc == NULL) { WARNING("Couldn't find model " << htr_tree_data->GetName() << " in model file " << inputFile_mc << " skipping DOM " << endl) ; continue ; }
212  htr_tree_mc->SetBranchAddress("dt",&htr_dt);
213  htr_tree_mc->SetBranchAddress("bestfit",&bestfit) ;
214 
215  TH1D htr_mc(DOMID+".htr_mc", DOMID+".htr_mc", dt_N, dt_min-0.5, dt_max+0.5) ;
216 
217  nentries = htr_tree_mc->GetEntries();
218  for (Long64_t i=0;i<nentries;i++) {
219  htr_tree_mc->GetEntry(i);
220 
221  // selection criteria
222  if (selectHTRentry(*bestfit)) { htr_mc.Fill(htr_dt) ; }
223 
224  }
225 
226  if (htr_mc.Integral() < 1) { WARNING("No data in model file " << inputFile_mc << " skipping DOM " << DOMID << endl) ; continue ; }
227 
228  htr_mc.Sumw2() ;
229  htr_data.Sumw2() ;
230  htr_mc.Scale(1.0/livetime_mc) ;
231  htr_data.Scale(1.0/livetime_data) ;
232 
233  const double nmin = 0.01/livetime_mc ; // TODO: relatively arbitrary
234  TH1D q1(DOMID+".1q", DOMID+".q1", 41, -20.5, 20.5) ;
235 
236  for (int di = 0 ; di < q1.GetNbinsX() ; di++) {
237  q1.SetBinContent(di+1, getLogQuality(&htr_data, &htr_mc, q1.GetBinCenter(di+1), nmin, nmin)) ;
238  }
239 
240  double dt_bestfit = q1.GetXaxis()->GetBinCenter(q1.GetMaximumBin()) ;
241 
242  // fit peak with parabola for time changes more precise than 1ns.
243  TF1 f1(DOMID+".1f", "([0]*x+[1])*x+[2]", dt_bestfit+dtrange.getLowerLimit() , dt_bestfit+dtrange.getUpperLimit()) ;
244  f1.SetParameter(0, 1.0) ;
245  f1.SetParameter(1, 0.0) ;
246  f1.SetParameter(2, 10.0) ;
247  q1.Fit(&f1, "QR") ;
248 
249  if (fabs(dt_bestfit - -0.5*f1.GetParameter(1)/f1.GetParameter(0)) < 1.0) {
250  dt_bestfit = -0.5*f1.GetParameter(1)/f1.GetParameter(0) ;
251  }
252 
253  timeshift[distance(detector.begin(), module)] = dt_bestfit ;
254 
255  outfile.cd() ;
256  TDirectory* dir = outfile.mkdir(DOMID);
257  dir->cd() ;
258  htr_data.Write() ;
259  htr_mc.Write() ;
260  q1.Write() ;
261 
262  }
263 
264  for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
265 
266  // average shift to zero
267  double ave = 0.0 ;
268  int N = 0 ;
269  for (JDetector::iterator mod = detector.begin(); mod != detector.end(); ++mod) {
270 
271  if (noInterString && module->getString() != mod->getString()) { continue ; }
272 
273  ave += timeshift.at(distance(detector.begin(), mod)) ;
274  N++ ;
275 
276  }
277  ave /= N ;
278 
279  DEBUG( "Best fit shift " << module->getID() << " : " << timeshift[distance(detector.begin(), module)]-ave << " [ns] " << endl ) ;
280 
281  if (overwriteDetector) {
282  for (int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
283  module->getPMT(pmt).addT0(timeshift[distance(detector.begin(), module)]-ave);
284  }
285  }
286 
287  }
288 
289  if (overwriteDetector) {
290 
291  NOTICE("Store calibration data on file " << detectorFile << endl);
292 
293  store(detectorFile, detector);
294 
295  }
296 
297  outfile.Write() ;
298 
299 }
Auxiliary methods to evaluate Poisson probabilities and chi2.
Utility class to parse command line options.
Definition: JParser.hh:1410
General exception.
Definition: JException.hh:40
General purpose data regression method.
#define WARNING(A)
Definition: JMessage.hh:63
Auxiliary methods for PDF calculations.
Detector data structure.
Definition: JDetector.hh:77
Recording of objects on file according a format that follows from the file name extension.
string outputFile
Data structure for detector geometry and calibration.
Various implementations of functional maps.
Basic data structure for L0 hit.
Data structure for track fit results.
Definition: JEvt.hh:32
Basic data structure for time and time over threshold information of hit.
Constants.
Detector file.
Definition: JHead.hh:126
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1836
Parallel scanning of objects from a single file or multiple files according a format that follows fro...
#define NOTICE(A)
Definition: JMessage.hh:62
void load(const JString &file_name, JDetector &detector)
Load detector from input file.
int debug
debug level
Definition: JSirene.cc:59
General purpose messaging.
#define FATAL(A)
Definition: JMessage.hh:65
Scanning of objects from multiple files according a format that follows from the extension of each fi...
Direct access to module in detector data structure.
double getDZ() const
Get Z-slope.
Definition: JEvt.hh:149
Auxiliary class to define a range between two values.
Utility class to parse command line options.
ROOT TTree parameter settings.
void store(const JString &file_name, const JDetector &detector)
Store detector to output file.
static const int NUMBER_OF_PMTS
Total number of PMTs in module.
Definition: JDAQ.hh:26
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:60
int main(int argc, char *argv[])
Definition: Main.cpp:15