13 #include "TFitResult.h" 
   31   const char* h2_t           =  
"h2";
 
   33   const char* gauss_t        =  
"Gauss";           
 
   34   const char* landau_t       =  
"Landau";          
 
   35   const char* emg_t          =  
"EMG";             
 
   36   const char* breitwigner_t  =  
"BreitWigner";     
 
   45 int main(
int argc, 
char **argv)
 
   53   bool            overwriteDetector;
 
   62     JParser<> zap(
"Program to fit output of JGandalf.cc in calibration mode.");
 
   64     zap[
'f'] = 
make_field(inputFile,         
"input files (output from JGandalf -c).");
 
   66     zap[
'a'] = 
make_field(detectorFile,      
"detector file.");
 
   67     zap[
'A'] = 
make_field(overwriteDetector, 
"overwrite detector file provided through '-a' with correct time offsets.");
 
   68     zap[
'F'] = 
make_field(
function,          
"fit function")                                                   = gauss_t, landau_t, emg_t, breitwigner_t;
 
   70     zap[
'O'] = 
make_field(option,            
"ROOT fit option, see TH1::Fit.")                                 = 
"";
 
   76   catch(
const exception &error) {
 
   77     FATAL(error.what() << endl);
 
   83   if (!T_ns.is_valid()) {
 
   84     FATAL(
"Invalid fit range [ns] " << T_ns << endl);
 
   90     load(detectorFile, detector);
 
   92   catch(
const JException& error) {
 
   96   if (option.find(
'S') == string::npos) { option += 
'S'; }
 
  104     NOTICE(
"Processing " << *i << endl);
 
  106     TFile in(i->c_str(), 
"exist");
 
  109       FATAL(
"File " << *i << 
" not opened." << endl);
 
  112     TH2D* p = 
dynamic_cast<TH2D*
>(in.Get(h2_t));
 
  115       FATAL(
"File " << *i << 
" has no histogram <" << h2_t << 
">." << endl);
 
  119       h2 = (TH2D*) p->Clone();
 
  129     FATAL(
"No histogram <" << h2_t << 
">." << endl);
 
  141     result_type(
double value,
 
  158   const TAxis* x_axis = h2->GetXaxis();
 
  159   const TAxis* y_axis = h2->GetYaxis();
 
  161   TH1D h0(
"h0", NULL, x_axis->GetNbins(), -0.5, x_axis->GetNbins() - 0.5);
 
  162   TH1D hc(
"hc", NULL, x_axis->GetNbins(), -0.5, x_axis->GetNbins() - 0.5);
 
  163   TH1D hq(
"hq", NULL, x_axis->GetNbins(), -0.5, x_axis->GetNbins() - 0.5);
 
  168   for (
int ix = 1; ix <= x_axis->GetNbins(); ++ix) {
 
  170     TH1D h1(
MAKE_CSTRING((detector.empty() ? ix : detector[ix - 1].getID()) << 
".1D"), NULL, y_axis->GetNbins(), y_axis->GetXmin(), y_axis->GetXmax());
 
  177     Double_t sigma  =  4.5;       
 
  179     for (
int iy = 1; iy <= y_axis->GetNbins(); ++iy) {
 
  181       h1.SetBinContent(iy,      h2->GetBinContent(ix,iy));
 
  182       h1.SetBinError  (iy, sqrt(h2->GetBinContent(ix,iy)));
 
  184       const Double_t x = h1.GetBinCenter (iy);
 
  185       const Double_t y = h1.GetBinContent(iy);
 
  194     const Double_t xmin = x0 + T_ns.getLowerLimit();
 
  195     const Double_t xmax = x0 + T_ns.getUpperLimit();
 
  197     const Int_t    imin = h1.GetXaxis()->FindBin(xmin);
 
  198     const Int_t    imax = h1.GetXaxis()->FindBin(xmax);
 
  203     if        (
function == gauss_t) {
 
  205       f1 = 
new TF1(
function.c_str(), 
"[0]*TMath::Gaus(x,[1],[2])");
 
  207       f1->SetParameter(0, ymax);
 
  208       f1->SetParameter(1, x0);
 
  209       f1->SetParameter(2, sigma);
 
  211     } 
else if (
function == landau_t) {
 
  213       f1 = 
new TF1(
function.c_str(), 
"[0]*TMath::Landau(x,[1],[2])");
 
  215       f1->SetParameter(0, ymax);
 
  216       f1->SetParameter(1, x0);
 
  217       f1->SetParameter(2, sigma);
 
  219     } 
else if (
function == emg_t) {
 
  221       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]))");
 
  223       f1->SetParameter(0, ymax);
 
  224       f1->SetParameter(1, x0 - sigma);
 
  225       f1->SetParameter(2, sigma);
 
  226       f1->SetParameter(3, 0.04);
 
  228     } 
else if (
function == breitwigner_t) {
 
  230       f1 = 
new TF1(
function.c_str(), 
"(x <= [1])*[0]*[2]*TMath::BreitWigner(x,[1],[2])+(x > [1])*[0]*[3]*TMath::BreitWigner(x,[1],[3])");
 
  232       f1->SetParameter(0, ymax);
 
  233       f1->SetParameter(1, x0);
 
  234       f1->SetParameter(2, 15.0);
 
  235       f1->SetParameter(3, 25.0);
 
  239       FATAL(
"Unknown fit function " << 
function << endl);
 
  243     if ((imax - imin) > f1->GetNpar()) {
 
  245       DEBUG(
"Start values:" << endl);
 
  247       for (
int i = 0; i != f1->GetNpar(); ++i) {
 
  248         DEBUG(left << setw(12) << f1->GetParName  (i) << 
' ' << 
 
  249               SCIENTIFIC(12,5) << f1->GetParameter(i) << endl);
 
  254       TFitResultPtr result = h1.Fit(f1, option.c_str(), 
"same", xmin, xmax);
 
  258              << setw(4)    << ix                    << 
' ' 
  259              << setw(16)   << h1.GetName()          << 
' ' 
  260              << 
FIXED(7,3) << f1->GetParameter(1)   << 
" +/- "  
  261              << 
FIXED(7,3) << f1->GetParError(1)    << 
' '  
  262              << 
FIXED(7,3) << result->Chi2()        << 
'/' 
  263              << result->Ndf()                       << 
' ' 
  264              << (result->IsValid() ? 
"" : 
"failed") << endl;
 
  267       zmap[ix] = result_type(f1->GetParameter(1), f1->GetParError (1)); 
 
  269       if (result->Ndf() > 0) {
 
  270         hc.SetBinContent(ix, result->Chi2() / result->Ndf());
 
  272       hq.SetBinContent(ix, result->IsValid() ? 1.0 : 0.0);
 
  278       ERROR(
"Slice: " << setw(4) << ix << 
" number of data points " << (imax - imin) << 
" < " << f1->GetNpar() << endl);
 
  291     for (map_type::const_iterator i = zmap.begin(); i != zmap.end(); ++i) {
 
  292       t0 += i->second.value;
 
  297     NOTICE(
"Average time offset [ns] " << 
FIXED(7,2) << t0 << endl);
 
  299     for (map_type::iterator i = zmap.begin(); i != zmap.end(); ++i) {
 
  300       i->second.value -= t0;
 
  303     for (map_type::const_iterator i = zmap.begin(); i != zmap.end(); ++i) {
 
  304       h0.SetBinContent(i->first, i->second.value);
 
  305       h0.SetBinError  (i->first, i->second.error);
 
  308     if (!detector.empty()) {
 
  310       const JRange<int> string(detector.begin(), detector.end(), &JModule::getString);
 
  311       const JRange<int> floor (detector.begin(), detector.end(), &JModule::getFloor);
 
  314               string.getLength() + 1,
 
  315               string.getLowerLimit() - 0.5,
 
  316               string.getUpperLimit() + 0.5,
 
  317               floor.getLength() + 1,
 
  318               floor.getLowerLimit() - 0.5,
 
  319               floor.getUpperLimit() + 0.5);
 
  321       for (map_type::const_iterator i = zmap.begin(); i != zmap.end(); ++i) {
 
  322         hi.SetBinContent(detector[i->first - 1].getString(), 
 
  323                          detector[i->first - 1].getFloor(),
 
  331     if (overwriteDetector) {
 
  333       NOTICE(
"Store calibration data on file " << detectorFile << endl);
 
  335       detector.comment.add(JMeta(argc, argv));
 
  337       for (map_type::const_iterator i = zmap.begin(); i != zmap.end(); ++i) {
 
  339         if (E_ns(i->second.error))
 
  340           detector[i->first - 1].add(i->second.value);
 
  342           ERROR(
"Slice " << setw(4) << i->first << 
" fit uncertainty " << 
FIXED(5,2) << i->second.error << 
" outside specified range (option -E <E_ns>)" << endl);
 
  345       store(detectorFile, detector);
 
  350     NOTICE(
"No calibration results." << endl);
 
Utility class to parse command line options. 
 
#define MAKE_CSTRING(A)
Make C-string. 
 
Auxiliary data structure for floating point format specification. 
 
Data structure for detector geometry and calibration. 
 
I/O formatting auxiliaries. 
 
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object 
 
void load(const JString &file_name, JDetector &detector)
Load detector from input file. 
 
General purpose messaging. 
 
Utility class to parse command line options. 
 
void store(const JString &file_name, const JDetector &detector)
Store detector to output file. 
 
Auxiliary data structure for floating point format specification. 
 
#define DEBUG(A)
Message macros. 
 
int main(int argc, char *argv[])