53 bool overwriteDetector;
62 JParser<> zap(
"Program to fit time-residuals histogram in 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);
84 FATAL(
"Invalid fit range [ns] " << T_ns << endl);
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());
176 Double_t sigma = 4.5;
178 for (
int iy = 1; iy <= y_axis->GetNbins(); ++iy) {
180 h1.SetBinContent(iy, h2->GetBinContent(ix,iy));
181 h1.SetBinError (iy, sqrt(h2->GetBinContent(ix,iy)));
183 const Double_t x = h1.GetBinCenter (iy);
184 const Double_t y = h1.GetBinContent(iy);
199 if (
function == gauss_t) {
201 f1 =
new TF1(
function.c_str(),
"[0]*TMath::Gaus(x,[1],[2])");
203 f1->SetParameter(0, ymax);
204 f1->SetParameter(1, x0);
205 f1->SetParameter(2, sigma);
207 }
else if (
function == landau_t) {
209 f1 =
new TF1(
function.c_str(),
"[0]*TMath::Landau(x,[1],[2])");
211 f1->SetParameter(0, ymax);
212 f1->SetParameter(1, x0);
213 f1->SetParameter(2, sigma);
215 }
else if (
function == emg_t) {
217 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]))");
219 f1->SetParameter(0, ymax);
220 f1->SetParameter(1, x0 - sigma);
221 f1->SetParameter(2, sigma);
222 f1->SetParameter(3, 0.04);
224 }
else if (
function == breitwigner_t) {
226 f1 =
new TF1(
function.c_str(),
"(x <= [1])*[0]*[2]*TMath::BreitWigner(x,[1],[2])+(x > [1])*[0]*[3]*TMath::BreitWigner(x,[1],[3])");
228 f1->SetParameter(0, ymax);
229 f1->SetParameter(1, x0);
230 f1->SetParameter(2, 15.0);
231 f1->SetParameter(3, 25.0);
235 FATAL(
"Unknown fit function " <<
function << endl);
239 DEBUG(
"Start values:" << endl);
241 for (
int i = 0; i != f1->GetNpar(); ++i) {
242 DEBUG(left << setw(12) << f1->GetParName (i) <<
' ' <<
243 SCIENTIFIC(12,5) << f1->GetParameter(i) << endl);
248 TFitResultPtr
result = h1.Fit(f1, option.c_str(),
"same", xmin, xmax);
252 << setw(4) << ix <<
' '
253 << setw(16) << h1.GetName() <<
' '
254 <<
FIXED(7,3) << f1->GetParameter(1) <<
" +/- "
255 <<
FIXED(7,3) << f1->GetParError(1) <<
' '
258 << (
result->IsValid() ?
"" :
"failed") << endl;
262 zmap[ix] = result_type(f1->GetParameter(1), f1->GetParError (1));
268 hq.SetBinContent(ix,
result->IsValid() ? 1.0 : 0.0);
282 for (map_type::const_iterator i = zmap.begin(); i != zmap.end(); ++i) {
283 t0 += i->second.value;
288 NOTICE(
"Average time offset [ns] " <<
FIXED(7,2) << t0 << endl);
290 for (map_type::iterator i = zmap.begin(); i != zmap.end(); ++i) {
291 i->second.value -= t0;
294 for (map_type::const_iterator i = zmap.begin(); i != zmap.end(); ++i) {
295 h0.SetBinContent(i->first, i->second.value);
296 h0.SetBinError (i->first, i->second.error);
305 string.getLength() + 1,
306 string.getLowerLimit() - 0.5,
307 string.getUpperLimit() + 0.5,
308 floor.getLength() + 1,
309 floor.getLowerLimit() - 0.5,
310 floor.getUpperLimit() + 0.5);
312 for (map_type::const_iterator i = zmap.begin(); i != zmap.end(); ++i) {
313 hi.SetBinContent(
detector[i->first - 1].getString(),
322 if (overwriteDetector) {
324 NOTICE(
"Store calibration data on file " << detectorFile << endl);
328 for (map_type::const_iterator i = zmap.begin(); i != zmap.end(); ++i) {
330 if (E_ns(i->second.error))
331 detector[i->first - 1].sub(i->second.value);
333 ERROR(
"Slice " << setw(4) << i->first <<
" fit uncertainty " <<
FIXED(5,2) << i->second.error <<
" outside specified range (option -E <E_ns>)" << endl);
341 NOTICE(
"No calibration results." << endl);