54 bool overwriteDetector;
64 JParser<> zap(
"Program to fit time-residuals histogram in output of JCalibrateMuon.cc.");
66 zap[
'f'] =
make_field(inputFile,
"input files (output from JCalibrateMuon).");
68 zap[
'a'] =
make_field(detectorFile,
"detector file.");
69 zap[
'A'] =
make_field(overwriteDetector,
"overwrite detector file provided through '-a' with correct time offsets.");
70 zap[
'F'] =
make_field(
function,
"fit function") = gauss_t, landau_t, emg_t, breitwigner_t;
72 zap[
'O'] =
make_field(option,
"ROOT fit option, see TH1::Fit.") =
"";
74 zap[
'W'] =
make_field(WMin,
"minimal histogram contents.") = 100.0;
79 catch(
const exception &error) {
80 FATAL(error.what() << endl);
84 if (!T_ns.is_valid()) {
85 FATAL(
"Invalid fit range [ns] " << T_ns << endl);
93 catch(
const JException& error) {
97 if (option.find(
'S') == string::npos) { option +=
'S'; }
105 NOTICE(
"Processing " << *
i << endl);
107 TFile
in(
i->c_str(),
"exist");
110 FATAL(
"File " << *
i <<
" not opened." << endl);
113 TH2D* p =
dynamic_cast<TH2D*
>(
in.Get(h2_t));
116 FATAL(
"File " << *
i <<
" has no histogram <" << h2_t <<
">." << endl);
120 h2 = (TH2D*) p->Clone();
130 FATAL(
"No histogram <" << h2_t <<
">." << endl);
142 result_type(
double value,
159 const TAxis* x_axis = h2->GetXaxis();
160 const TAxis* y_axis = h2->GetYaxis();
162 TH1D h0(
"h0", NULL, x_axis->GetNbins(), -0.5, x_axis->GetNbins() - 0.5);
163 TH1D hc(
"hc", NULL, x_axis->GetNbins(), -0.5, x_axis->GetNbins() - 0.5);
164 TH1D hq(
"hq", NULL, x_axis->GetNbins(), -0.5, x_axis->GetNbins() - 0.5);
169 for (
int ix = 1; ix <= x_axis->GetNbins(); ++ix) {
171 if (
detector[ix - 1].getFloor() == 0) {
175 TH1D h1(
MAKE_CSTRING(
detector[ix - 1].getID() <<
".1D"), NULL, y_axis->GetNbins(), y_axis->GetXmin(), y_axis->GetXmax());
181 Double_t
sigma = 4.5;
184 for (
int iy = 1; iy <= y_axis->GetNbins(); ++iy) {
186 h1.SetBinContent(iy, h2->GetBinContent(ix,iy));
187 h1.SetBinError (iy, sqrt(h2->GetBinContent(ix,iy)));
189 const Double_t
x = h1.GetBinCenter (iy);
190 const Double_t
y = h1.GetBinContent(iy);
202 WARNING(
"Not enough entries for slice " << ix <<
' ' << W <<
"; skip fit." << endl);
208 const Double_t
xmin = x0 + T_ns.getLowerLimit();
209 const Double_t
xmax = x0 + T_ns.getUpperLimit();
214 if (
function == gauss_t) {
216 f1 =
new TF1(
function.c_str(),
"[0]*TMath::Gaus(x,[1],[2])");
218 f1->SetParameter(0, ymax);
219 f1->SetParameter(1, x0);
220 f1->SetParameter(2, sigma);
222 }
else if (
function == landau_t) {
224 f1 =
new TF1(
function.c_str(),
"[0]*TMath::Landau(x,[1],[2])");
226 f1->SetParameter(0, ymax);
227 f1->SetParameter(1, x0);
228 f1->SetParameter(2, sigma);
230 }
else if (
function == emg_t) {
232 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]))");
234 f1->SetParameter(0, ymax);
235 f1->SetParameter(1, x0 - sigma);
236 f1->SetParameter(2, sigma);
237 f1->SetParameter(3, 0.04);
239 }
else if (
function == breitwigner_t) {
241 f1 =
new TF1(
function.c_str(),
"(x <= [1])*[0]*[2]*TMath::BreitWigner(x,[1],[2])+(x > [1])*[0]*[3]*TMath::BreitWigner(x,[1],[3])");
243 f1->SetParameter(0, ymax);
244 f1->SetParameter(1, x0);
245 f1->SetParameter(2, 15.0);
246 f1->SetParameter(3, 25.0);
250 FATAL(
"Unknown fit function " <<
function << endl);
254 DEBUG(
"Start values:" << endl);
256 for (
int i = 0;
i != f1->GetNpar(); ++
i) {
257 DEBUG(left << setw(12) << f1->GetParName (
i) <<
' ' <<
263 TFitResultPtr
result = h1.Fit(f1, option.c_str(),
"same",
xmin,
xmax);
267 << setw(4) << ix <<
' '
268 << setw(16) << h1.GetName() <<
' '
269 <<
FIXED(7,3) << f1->GetParameter(1) <<
" +/- "
270 <<
FIXED(7,3) << f1->GetParError(1) <<
' '
271 <<
FIXED(7,3) << result->Chi2() <<
'/'
272 << result->Ndf() <<
' '
273 << (result->IsValid() ?
"" :
"failed") << endl;
276 if (result->IsValid()) {
277 zmap[ix] = result_type(f1->GetParameter(1), f1->GetParError (1));
280 if (result->Ndf() > 0) {
281 hc.SetBinContent(ix, result->Chi2() / result->Ndf());
283 hq.SetBinContent(ix, result->IsValid() ? 1.0 : 0.0);
297 for (map_type::const_iterator
i = zmap.begin();
i != zmap.end(); ++
i) {
298 t0 +=
i->second.value;
303 NOTICE(
"Average time offset [ns] " <<
FIXED(7,2) << t0 << endl);
305 for (map_type::iterator
i = zmap.begin();
i != zmap.end(); ++
i) {
306 i->second.value -= t0;
309 for (map_type::const_iterator
i = zmap.begin();
i != zmap.end(); ++
i) {
310 h0.SetBinContent(
i->first,
i->second.value);
311 h0.SetBinError (
i->first,
i->second.error);
320 string.getLength() + 1,
321 string.getLowerLimit() - 0.5,
322 string.getUpperLimit() + 0.5,
323 floor.getLength() + 1,
324 floor.getLowerLimit() - 0.5,
325 floor.getUpperLimit() + 0.5);
327 for (map_type::const_iterator
i = zmap.begin();
i != zmap.end(); ++
i) {
328 hi.SetBinContent(
detector[
i->first - 1].getString(),
337 if (overwriteDetector) {
339 NOTICE(
"Store calibration data on file " << detectorFile << endl);
341 detector.comment.add(JMeta(argc, argv));
343 for (map_type::const_iterator
i = zmap.begin();
i != zmap.end(); ++
i) {
345 if (E_ns(
i->second.error))
348 ERROR(
"Slice " << setw(4) <<
i->first <<
" fit uncertainty " <<
FIXED(5,2) <<
i->second.error <<
" outside specified range (option -E <E_ns>)" << endl);
356 NOTICE(
"No calibration results." << endl);
Utility class to parse command line options.
std::map< int, buffer_type > map_type
string -> hits
#define MAKE_CSTRING(A)
Make C-string.
Auxiliary data structure for floating point format specification.
JMODEL::JString getString(const JFit &fit)
Get model parameters of string.
const JPolynome f1(1.0, 2.0, 3.0)
Function.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
const array_type< JValue_t > & make_array(const JValue_t(&array)[N])
Method to create array of values.
void store(const std::string &file_name, const JDetector &detector)
Store detector to output file.
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
do set_variable DETECTOR_TXT $WORKDIR detector
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable INPUT_FILE $argv[2] eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY JAcoustics sh $DETECTOR_ID source JAcousticsToolkit sh CHECK_EXIT_CODE typeset A EMITTERS get_tripods $WORKDIR tripod txt EMITTERS get_transmitters $WORKDIR transmitter txt EMITTERS for EMITTER in
Auxiliary data structure for floating point format specification.
JTOOLS::JRange< double > JTimeRange
Type definition for time range (unit [s]).
#define DEBUG(A)
Message macros.