12 #include "TFitResult.h" 
   27   const char* h2_t           =  
"ha";
 
   29   const char* gauss_t        =  
"Gauss";           
 
   30   const char* emg_t          =  
"EMG";             
 
   44   Double_t getRisetime(Double_t* x, Double_t* 
parameters)
 
   46     const double t0  = parameters[0];
 
   47     const double p1  = parameters[1];
 
   48     const double t1  = parameters[2];
 
   50     const double npe = cpu.getNPE(x[0]);
 
   52     double ts = t0  +  cpu.getRiseTime(npe)  +  t1 * (1.0 - 
exp(-npe*p1));
 
   64 int main(
int argc, 
char **argv)
 
   83     JProperties properties = parameters.getProperties();
 
   85     JParser<> zap(
"Program to fit time-slewing histogram in output of JGandalf.cc in calibration mode.");
 
   87     zap[
'f'] = 
make_field(inputFile,         
"input files (output from JGandalf -c).");
 
   89     zap[
'F'] = 
make_field(
function,          
"fit function")                                    = gauss_t, emg_t;
 
   90     zap[
'T'] = 
make_field(T_ns,              
"ROOT fit range around maximum [ns].")             = 
JRange_t(-7.5,+7.5);
 
   91     zap[
'w'] = 
make_field(writeFits,         
"write fit results.");
 
   93     zap[
'x'] = 
make_field(X,                 
"ROOT fit range for time-over threshold")          = 
JRange_t(0.0, 256.0);
 
   94     zap[
'O'] = 
make_field(option,            
"ROOT fit option, see TH1::Fit.")                  = 
"";
 
   99   catch(
const exception &error) {
 
  100     FATAL(error.what() << endl);
 
  106   if (!T_ns.is_valid()) {
 
  107     FATAL(
"Invalid fit range [ns] " << T_ns << endl);
 
  110   cpu.setPMTParameters(parameters);
 
  112   if (option.find(
'S') == string::npos) { option += 
'S'; }
 
  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,
 
  127     100.5, 120.5, 140.5, 160.5, 180.5, 200.5, 250.5
 
  130   const int N = 
sizeof(x)/
sizeof(x[0]);
 
  136     NOTICE(
"Processing " << *i << endl);
 
  138     TFile 
in(i->c_str(), 
"exist");
 
  141       FATAL(
"File " << *i << 
" not opened." << endl);
 
  144     TH2D* p = 
dynamic_cast<TH2D*
>(
in.Get(h2_t));
 
  147       FATAL(
"File " << *i << 
" has no histogram <" << h2_t << 
">." << endl);
 
  151       h2 = (TH2D*) p->Clone();
 
  161     FATAL(
"No histogram <" << h2_t << 
">." << endl);
 
  166   TH1D h0(
"h0", NULL, 
N-1, x);
 
  170   for (
int i = 1; i <= h0.GetXaxis()->GetNbins(); ++i) {
 
  172     const Int_t imin = h2->GetXaxis()->FindBin(h0.GetXaxis()->GetBinLowEdge(i));
 
  173     const Int_t imax = h2->GetXaxis()->FindBin(h0.GetXaxis()->GetBinUpEdge (i));
 
  175     TH1D 
h1(
MAKE_CSTRING(i << 
".1D"), NULL, h2->GetYaxis()->GetNbins(), h2->GetYaxis()->GetXmin(), h2->GetYaxis()->GetXmax());
 
  181     Double_t sigma  =  3.5;       
 
  183     for (
int iy = 1; iy <= h2->GetYaxis()->GetNbins(); ++iy) {
 
  185       Double_t x = 
h1.GetBinCenter (iy);
 
  188       for (
int ix = imin; ix != imax; ++ix) {
 
  189         y += h2->GetBinContent(ix,iy);
 
  192       h1.SetBinContent(iy, y);
 
  203     if        (
function == gauss_t) {
 
  205       f1 = 
new TF1(
function.c_str(), 
"[0]*TMath::Gaus(x,[1],[2]) + [3]");
 
  207       f1->SetParameter(0, ymax);
 
  208       f1->SetParameter(1, x0);
 
  209       f1->SetParameter(2, sigma);
 
  210       f1->SetParameter(3, 0.0);
 
  212       f1->SetParLimits(3, 0.0, ymax);
 
  214     } 
else if (
function == emg_t) {
 
  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]");
 
  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);
 
  224       f1->SetParLimits(4, 0.0, ymax);
 
  228       FATAL(
"Unknown fit function " << 
function << endl);
 
  233     Double_t xmin = x0 + T_ns.getLowerLimit();
 
  234     Double_t xmax = x0 + T_ns.getUpperLimit();
 
  236     if (xmin < 
h1.GetXaxis()->GetXmin()) { xmin = 
h1.GetXaxis()->GetXmin(); }
 
  237     if (xmax > 
h1.GetXaxis()->GetXmax()) { xmax = 
h1.GetXaxis()->GetXmax(); }
 
  239     TFitResultPtr 
result = 
h1.Fit(f1, option.c_str(), 
"same", xmin, xmax);
 
  243            << setw(4)    << i                     << 
' ' 
  244            << 
FIXED(7,3) << f1->GetParameter(1)   << 
" +/- " 
  245            << 
FIXED(7,3) << f1->GetParError (1)   << 
' ' 
  246            << 
FIXED(7,3) << result->Chi2()        << 
'/' 
  247            << result->Ndf()                       << 
' ' 
  248            << (result->IsValid() ? 
"" : 
"failed") << endl;
 
  251     if (result->IsValid()) {
 
  252       h0.SetBinContent(i, f1->GetParameter(1));
 
  253       h0.SetBinError  (i, f1->GetParError (1));
 
  265   TF1 f1(
"f1", getRisetime, x[0], x[
N-1], 3);
 
  267   f1.SetParameter(0,   0.0);
 
  268   f1.SetParameter(1,   2.0e-2);
 
  269   f1.FixParameter(2,  -7.0);
 
  271   TFitResultPtr 
result = h0.Fit(&f1, 
"S", 
"same", X.constrain(x[0]), X.constrain(x[
N-1]));
 
  274     cout << 
"Time-slewing correction"           << endl;
 
  277          << (
result->IsValid() ? 
"" : 
"failed") << endl;
 
  279     for (
int i = 0; i != f1.GetNpar(); ++i) {
 
  280       cout << 
"parameter[" << i << 
"] = " << 
FIXED(8,4) << f1.GetParameter(i) << 
" +/- " << 
FIXED(8,4) << f1.GetParError (i) << endl;
 
  284   cout << 
"// Produced by JFrodo.cc; to be included on JGetRiseTime.hh." << endl;
 
  288   for (
int i = 0; i != 256; ++i) {
 
  289     cout << 
"this->push_back(" << 
FIXED(6,2) << f1.Eval((Double_t) i) - t0 << 
");" << endl;
 
Utility class to parse command line options. 
 
PMT calibration (including definition of sign of time offset). 
 
const double TIME_OVER_THRESHOLD_NS
Specification for time-over-threshold corresponding to a one photo-electron pulse. 
 
esac print_variable DETECTOR INPUT_FILE OUTPUT_FILE CDF for TYPE in
 
Utility class to parse parameter values. 
 
*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
 
#define MAKE_CSTRING(A)
Make C-string. 
 
then for HISTOGRAM in h0 h1
 
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
 
Auxiliary data structure for floating point format specification. 
 
I/O formatting auxiliaries. 
 
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object 
 
General purpose messaging. 
 
JRange< Double_t > JRange_t
 
PMT analogue signal processor. 
 
Auxiliary class to define a range between two values. 
 
Utility class to parse command line options. 
 
PMT analogue signal processor. 
 
Data structure for PMT parameters. 
 
then usage $script[input file[working directory[option]]] nWhere option can be N
 
then set_variable FORMULA *[0] exp(-0.5 *(x-[1])*(x-[1])/([2]*[2]))" set_variable OUTPUT_FILE histogram.root JHistogram1D -o $WORKDIR/$OUTPUT_FILE -F "$FORMULA" -
 
int main(int argc, char *argv[])