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 JCalibrateMuon.");
87 zap[
'f'] =
make_field(inputFile,
"input files (output from JCalibrateMuon).");
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.");
94 zap[
'O'] =
make_field(option,
"ROOT fit option, see TH1::Fit.") =
"";
99 catch(
const exception &error) {
100 FATAL(error.what() << endl);
104 if (!T_ns.is_valid()) {
105 FATAL(
"Invalid fit range [ns] " << T_ns << endl);
108 cpu.setPMTParameters(parameters);
110 if (option.find(
'S') == string::npos) { option +=
'S'; }
115 const Double_t x[] = {
116 -0.5, 3.5, 6.5, 9.5, 12.5, 15.5, 18.5,
117 20.5, 21.5, 22.5, 23.5, 24.5, 25.5, 26.5, 27.5, 28.5, 29.5,
118 30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5, 38.5, 39.5,
119 40.5, 42.5, 44.5, 46.5, 48.5,
120 50.5, 52.5, 54.5, 56.5, 58.5,
125 100.5, 120.5, 140.5, 160.5, 180.5, 200.5, 250.5
128 const int N =
sizeof(
x)/
sizeof(x[0]);
134 NOTICE(
"Processing " << *
i << endl);
136 TFile
in(
i->c_str(),
"exist");
139 FATAL(
"File " << *
i <<
" not opened." << endl);
142 TH2D* p =
dynamic_cast<TH2D*
>(
in.Get(h2_t));
145 FATAL(
"File " << *
i <<
" has no histogram <" << h2_t <<
">." << endl);
149 h2 = (TH2D*) p->Clone();
159 FATAL(
"No histogram <" << h2_t <<
">." << endl);
164 TH1D h0(
"h0", NULL,
N-1, x);
168 for (
int i = 1;
i <= h0.GetXaxis()->GetNbins(); ++
i) {
170 const Int_t imin = h2->GetXaxis()->FindBin(h0.GetXaxis()->GetBinLowEdge(
i));
171 const Int_t imax = h2->GetXaxis()->FindBin(h0.GetXaxis()->GetBinUpEdge (
i));
173 TH1D h1(
MAKE_CSTRING(
i <<
".1D"), NULL, h2->GetYaxis()->GetNbins(), h2->GetYaxis()->GetXmin(), h2->GetYaxis()->GetXmax());
179 Double_t
sigma = 3.5;
181 for (
int iy = 1; iy <= h2->GetYaxis()->GetNbins(); ++iy) {
183 Double_t x = h1.GetBinCenter (iy);
186 for (
int ix = imin; ix != imax; ++ix) {
187 y += h2->GetBinContent(ix,iy);
190 h1.SetBinContent(iy, y);
201 if (
function == gauss_t) {
203 f1 =
new TF1(
function.c_str(),
"[0]*TMath::Gaus(x,[1],[2]) + [3]");
205 f1->SetParameter(0, ymax);
206 f1->SetParameter(1, x0);
207 f1->SetParameter(2, sigma);
208 f1->SetParameter(3, 0.0);
210 f1->SetParLimits(3, 0.0, ymax);
212 }
else if (
function == emg_t) {
214 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]");
216 f1->SetParameter(0, ymax);
217 f1->SetParameter(1, x0 - 0.5*sigma);
218 f1->SetParameter(2, sigma);
219 f1->SetParameter(3, 0.04);
220 f1->SetParameter(4, 0.0);
222 f1->SetParLimits(4, 0.0, ymax);
226 FATAL(
"Unknown fit function " <<
function << endl);
231 Double_t
xmin = x0 + T_ns.getLowerLimit();
232 Double_t
xmax = x0 + T_ns.getUpperLimit();
234 if (xmin < h1.GetXaxis()->GetXmin()) { xmin = h1.GetXaxis()->GetXmin(); }
235 if (xmax > h1.GetXaxis()->GetXmax()) { xmax = h1.GetXaxis()->GetXmax(); }
237 TFitResultPtr
result = h1.Fit(f1, option.c_str(),
"same",
xmin,
xmax);
239 if (result.Get() == NULL) {
240 FATAL(
"Invalid TFitResultPtr " << h1.GetName() << endl);
245 << setw(4) <<
i <<
' '
246 <<
FIXED(7,3) << f1->GetParameter(1) <<
" +/- "
247 <<
FIXED(7,3) << f1->GetParError (1) <<
' '
248 <<
FIXED(7,3) << result->Chi2() <<
'/'
249 << result->Ndf() <<
' '
250 << (result->IsValid() ?
"" :
"failed") << endl;
253 if (result->IsValid()) {
254 h0.SetBinContent(
i, f1->GetParameter(1));
255 h0.SetBinError (
i, f1->GetParError (1));
267 TF1
f1(
"f1", getRisetime, x[0], x[
N-1], 3);
269 f1.SetParameter(0, 0.0);
270 f1.SetParameter(1, 2.0e-2);
271 f1.FixParameter(2, -7.0);
273 TFitResultPtr
result = h0.Fit(&f1,
"S",
"same",
X.constrain(x[0]),
X.constrain(x[
N-1]));
276 cout <<
"Time-slewing correction" << endl;
279 << (
result->IsValid() ?
"" :
"failed") << endl;
281 for (
int i = 0;
i != f1.GetNpar(); ++
i) {
282 cout <<
"parameter[" <<
i <<
"] = " <<
FIXED(8,4) << f1.GetParameter(
i) <<
" +/- " <<
FIXED(8,4) << f1.GetParError (
i) << endl;
286 cout <<
"// Produced by JFrodo.cc; to be included on JGetRiseTime.hh." << endl;
290 for (
int i = 0;
i != 256; ++
i) {
291 cout <<
"this->push_back(" <<
FIXED(6,2) << f1.Eval((Double_t)
i) - t0 <<
");" << endl;
Utility class to parse command line options.
int main(int argc, char *argv[])
Time 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.
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.
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Auxiliary data structure for floating point format specification.
const JPolynome f1(1.0, 2.0, 3.0)
Function.
Type definition of range.
I/O formatting auxiliaries.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
General purpose messaging.
PMT analogue signal processor.
then usage $script< input file >[option[primary[working directory]]] nWhere option can be N
Auxiliary class to define a range between two values.
Utility class to parse command line options.
no fit printf nominal n $STRING awk v X
PMT analogue signal processor.
Data structure for PMT parameters.
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
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable STRING $argv[2] set_array QUANTILES set_variable FORMULA *[0] exp(-0.5 *(x-[1])*(x-[1])/([2]*[2]))" set_variable MODULE `getModule -a $DETECTOR -L "$STRING 0"` source JAcousticsToolkit.sh typeset -A TRIPODS get_tripods $WORKDIR/tripod.txt TRIPODS XMEAN