67{
   70 
   72 
   75  string          function;
   77  bool            writeFits;
   80  string          option;
   82 
   83  try {
   84 
   86 
   87    JParser<> zap(
"Program to fit time-slewing histogram in output of JCalibrateMuon.");
 
   88 
   89    zap[
'f'] = 
make_field(inputFile,         
"input files (output from JCalibrateMuon).");
 
   91    zap[
'F'] = 
make_field(function,          
"fit function")                                    = gauss_t, emg_t;
 
   92    zap[
'T'] = 
make_field(T_ns,              
"ROOT fit range around maximum [ns].")             = 
JRange_t(-7.5,+7.5);
 
   93    zap[
'w'] = 
make_field(writeFits,         
"write fit results.");
 
   95    zap[
'x'] = 
make_field(X,                 
"ROOT fit range for time-over threshold")          = 
JRange_t(0.0, 256.0);
 
   96    zap[
'O'] = 
make_field(option,            
"ROOT fit option, see TH1::Fit.")                  = 
"";
 
   98 
   99    zap(argc, argv);
  100  }
  101  catch(const exception &error) {
  102    FATAL(error.what() << endl);
 
  103  }
  104 
  105 
  107    FATAL(
"Invalid fit range [ns] " << T_ns << endl);
 
  108  }
  109 
  110  cpu.setPMTParameters(parameters);
  111 
  112  if (option.find('S') == string::npos) { option += 'S'; }
  114 
  115  
  116 
  117  const Double_t 
x[] = {
 
  118    -0.5,  3.5,  6.5,  9.5, 12.5, 15.5, 18.5, 
  119    20.5, 21.5, 22.5, 23.5, 24.5, 25.5, 26.5, 27.5, 28.5, 29.5,
  120    30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5, 38.5, 39.5,
  121    40.5, 42.5, 44.5, 46.5, 48.5,
  122    50.5, 52.5, 54.5, 56.5, 58.5,
  123    60.5, 65.5,
  124    70.5, 75.5,
  125    80.5, 85.5,
  126    90.5, 95.5,
  127    100.5, 120.5, 140.5, 160.5, 180.5, 200.5, 250.5
  128  };
  129 
  130  const int N = 
sizeof(
x)/
sizeof(x[0]);
 
  131 
  132  TH2D* h2 = NULL;
  133 
  134  for (vector<string>::const_iterator i = inputFile.begin(); i != inputFile.end(); ++i) {
  135 
  136    NOTICE(
"Processing " << *i << endl);
 
  137 
  138    TFile in(i->c_str(), "exist");
  139 
  140    if (!in.IsOpen()) {
  141      FATAL(
"File " << *i << 
" not opened." << endl);
 
  142    }
  143 
  144    TH2D* p = 
dynamic_cast<TH2D*
>(in.Get(
h2_t));
 
  145      
  146    if (p == NULL) {
  147      FATAL(
"File " << *i << 
" has no histogram <" << 
h2_t << 
">." << endl);
 
  148    }
  149 
  150    if (h2 == NULL)
  151      h2 = (TH2D*) p->Clone();
  152    else
  153      h2->Add(p);
  154 
  155    h2->SetDirectory(0);
  156 
  157    in.Close();
  158  }
  159 
  160  if (h2 == NULL) {
  161    FATAL(
"No histogram <" << 
h2_t << 
">." << endl);
 
  162  }
  163 
  164  
  165 
  166  TH1D h0("h0", NULL, N-1, x);
  167 
  169 
  170  for (int i = 1; i <= h0.GetXaxis()->GetNbins(); ++i) {
  171 
  172    const Int_t imin = h2->GetXaxis()->FindBin(h0.GetXaxis()->GetBinLowEdge(i));
  173    const Int_t imax = h2->GetXaxis()->FindBin(h0.GetXaxis()->GetBinUpEdge (i));
  174 
  175    TH1D h1(
MAKE_CSTRING(i << 
".1D"), NULL, h2->GetYaxis()->GetNbins(), h2->GetYaxis()->GetXmin(), h2->GetYaxis()->GetXmax());
 
  176 
  177    
  178    
  179    Double_t ymax   =  0.0;
  180    Double_t x0     =  0.0;       
  181    Double_t sigma  =  3.5;       
  182    
  183    for (int iy = 1; iy <= h2->GetYaxis()->GetNbins(); ++iy) {
  184 
  185      Double_t 
x = h1.GetBinCenter (iy);
 
  187 
  188      for (int ix = imin; ix != imax; ++ix) {
  189        y += h2->GetBinContent(ix,iy);
 
  190      }
  191 
  192      h1.SetBinContent(iy, y);
  193 
  194      if (y > ymax) {
  197      }
  198    }
  199 
  200 
  201    TF1* f1 = NULL;
  202 
  203    if        (function == gauss_t) {
  204 
  205      f1 = new TF1(function.c_str(), "[0]*TMath::Gaus(x,[1],[2]) + [3]");
  206 
  207      f1->SetParameter(0, ymax);
  208      f1->SetParameter(1, x0);
  209      f1->SetParameter(2, sigma);
  210      f1->SetParameter(3, 0.0);
  211 
  212      f1->SetParLimits(3, 0.0, ymax);
  213    
  214    } else if (function == emg_t) {
  215 
  216      f1 = new TF1(function.c_str(), "[0]*TMath::Exp(0.5*[3]*(2.0*[1]+[3]*[2]*[2]-2.0*x))*TMath::Erfc(([1]+[3]*[2]*[2]-x)/(TMath::Sqrt(2.0)*[2])) +[4]");
  217 
  218      f1->SetParameter(0, ymax);
  219      f1->SetParameter(1, x0 - 0.5*sigma);
  220      f1->SetParameter(2, sigma);
  221      f1->SetParameter(3, 0.04);
  222      f1->SetParameter(4, 0.0);
  223 
  224      f1->SetParLimits(4, 0.0, ymax);
  225 
  226    } else {
  227 
  228      FATAL(
"Unknown fit function " << function << endl);
 
  229    }
  230 
  231    
  232 
  235 
  236    if (xmin < h1.GetXaxis()->GetXmin()) { xmin = h1.GetXaxis()->GetXmin(); }
  237    if (xmax > h1.GetXaxis()->GetXmax()) { xmax = h1.GetXaxis()->GetXmax(); }
  238      
  239    TFitResultPtr 
result = h1.Fit(f1, option.c_str(), 
"same", xmin, xmax);
 
  240 
  241    if (
result.Get() == NULL) {
 
  242      FATAL(
"Invalid TFitResultPtr " << h1.GetName() << endl);
 
  243    }
  244 
  246      cout << "Bin: "
  247           << setw(4)    << i                     << ' '
  248           << 
FIXED(7,3) << f1->GetParameter(1)   << 
" +/- " 
  249           << 
FIXED(7,3) << f1->GetParError (1)   << 
' ' 
  252           << (
result->IsValid() ? 
"" : 
"failed") << endl;
 
  253    }
  254 
  256      h0.SetBinContent(i, f1->GetParameter(1));
  257      h0.SetBinError  (i, f1->GetParError (1));
  258    }
  259 
  260    if (writeFits) {
  261      h1.Write();
  262    }
  263 
  264    delete f1;
  265  }
  266 
  267  
  268 
  269  TF1 f1("f1", getRisetime, x[0], x[N-1], 3);
  270 
  271  f1.SetParameter(0,   0.0);
  272  f1.SetParameter(1,   2.0e-2);
  273  f1.FixParameter(2,  -7.0);
  274 
  276 
  278    cout << "Time-slewing correction"           << endl;
  281         << (
result->IsValid() ? 
"" : 
"failed") << endl;
 
  282 
  283    for (int i = 0; i != f1.GetNpar(); ++i) {
  284      cout << 
"parameter[" << i << 
"] = " << 
FIXED(8,4) << f1.GetParameter(i) << 
" +/- " << 
FIXED(8,4) << f1.GetParError (i) << endl;
 
  285    }
  286  }
  287 
  288  cout << "// Produced by JFrodo.cc; to be included on JGetRiseTime.hh." << endl;
  289 
  291 
  292  for (int i = 0; i != 256; ++i) {
  293    cout << 
"this->push_back(" << 
FIXED(6,2) << f1.Eval((Double_t) i) - t0 << 
");" << endl;
 
  294  }
  295 
  296  h0.Write();
  297 
  298  out.Close();
  299}
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
 
#define MAKE_CSTRING(A)
Make C-string.
 
Data structure for PMT parameters.
 
JProperties getProperties(const JEquationParameters &equation=JPMTParameters::getEquationParameters())
Get properties of this class.
 
Utility class to parse parameter values.
 
Utility class to parse command line options.
 
const double TIME_OVER_THRESHOLD_NS
Specification for time-over-threshold corresponding to a one photo-electron pulse.
 
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
 
const char *const h2_t
Name of histogram with results from JMuonCompass.cc.
 
Auxiliary data structure for floating point format specification.
 
Type definition of range.
 
Empty structure for specification of parser element that is initialised (i.e. does not require input)...