10 #include "TFitResult.h"
43 int main(
int argc,
char **argv)
47 using namespace KM3NETDAQ;
52 JMultipleFileScanner<JDAQTimesliceTypes_t> inputFile;
57 double laserFrequency_Hz;
58 bool overwriteDetector;
59 JROOTClassSelector selector;
65 JParser<> zap(
"Application for dark room time calibration.");
67 zap[
'f'] =
make_field(inputFile,
"input file (output from JCalibrateK40).");
69 zap[
'a'] =
make_field(detectorFile,
"detector file.");
71 "Set reference PMTs, e.g."
72 "\n-! \"808969848 0 808982077 23\" sets PMT 0 of module 808969848 and PMT 23 of module 808982077 as references.");
73 zap[
'n'] =
make_field(numberOfEvents) = JLimit::max();
74 zap[
'l'] =
make_field(laserFrequency_Hz,
"laser frequency [Hz]") = 10000;
75 zap[
'A'] =
make_field(overwriteDetector,
"overwrite detector file provided through '-a' with correct time offsets.");
76 zap[
'O'] =
make_field(option,
"ROOT fit option, see TH1::Fit.") =
"L";
77 zap[
'C'] =
make_field(selector,
"timeslice selector, e.g. JDAQTimesliceL1.") = getROOTClassSelection<JDAQTimesliceTypes_t>();
82 catch(
const exception& error) {
83 FATAL(error.what() << endl);
87 for (JTDC_t::const_iterator tdc = TDC.begin(); tdc != TDC.end(); ++tdc) {
89 FATAL(
"Illegal TDC (= readout channel) identifier: " << tdc->second <<
" {0, .., " <<
NUMBER_OF_PMTS - 1 <<
"}" << endl);
93 if (laserFrequency_Hz < 0.0) {
94 FATAL(
"Invalid laser frequency " << laserFrequency_Hz << endl);
98 const double laserPeriod_ns = 1.0e9 / laserFrequency_Hz;
105 load(detectorFile, detector);
107 catch(
const JException& error) {
111 const JModuleRouter moduleRouter(detector);
124 const int nx = 2 * (int) laserPeriod_ns;
125 const double xmin = -0.5 * laserPeriod_ns;
126 const double xmax = 0.5 * laserPeriod_ns;
129 for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
131 const range_type range = TDC.equal_range(module->getID());
133 for (JTDC_t::const_iterator i = range.first; i != range.second; ++i) {
136 <<
" string " << setw(3) << module->getString()
137 <<
" floor " << setw(2) << module->getFloor()
138 <<
" module " << setw(8) << module->getID()
139 <<
" channel " << setw(2) << i->second << endl);
143 os <<
"s" << module->getString()
144 <<
"_f" << module->getFloor()
145 <<
"_m" << module->getID()
146 <<
"_c" << setfill(
'0') << setw(2) << i->second;
148 zmap.insert(make_pair(JPMTIdentifier(module->getID(),i->second),
new TH1D(os.str().c_str(), NULL, nx, xmin, xmax)));
155 const JBuildL0<JHitL0> buildL0;
158 JObjectMultiplexer<JDAQTimesliceTypes_t, JDAQTimeslice> in(inputFile, selector);
160 for (
counter_type counter = 0; in.hasNext() && counter != inputFile.getLimit(); ++counter) {
162 STATUS(
"event: " << setw(10) << counter <<
'\r');
DEBUG(endl);
166 for (JDAQTimeslice::const_iterator frame = timeslice->begin(); frame != timeslice->end(); ++frame) {
168 const int id = frame->getModuleID();
170 DEBUG(
"Module id =" <<
id << endl);
175 t0 -= laserPeriod_ns;
180 buildL0(*frame, moduleRouter.getModule(
id), back_inserter(dataL0));
182 for (JDataL0_t::const_iterator hit = dataL0.begin(); hit != dataL0.end(); ++hit) {
184 map_type::const_iterator p = zmap.find(JPMTIdentifier(
id,hit->getPMTAddress()));
186 if (p != zmap.end()) {
188 double t1 = t0 + hit->getT();
191 t1 -= laserPeriod_ns;
194 t1 += laserPeriod_ns;
209 TF1 f1(
"f1",
"[0]*exp(-0.5*(x-[1])*(x-[1])/([2]*[2])) + [3]");
211 for (map_type::iterator it = zmap.begin(); it != zmap.end(); ++it) {
213 JPMTIdentifier pmt = it->first;
214 TH1D* h1 = it->second;
216 if (h1->GetEntries() == 0) {
217 WARNING(
"Histogram " << h1->GetName() <<
" empty" << endl);
221 STATUS(
"--- PMT = " << pmt <<
"; histogram " << h1->GetName() << endl);
227 Double_t sigma = 2.0;
230 for (
int i = 1; i != h1->GetNbinsX(); ++i) {
232 const Double_t x = h1->GetBinCenter (i);
233 const Double_t y = h1->GetBinContent(i);
241 f1.SetParameter(0, ymax);
242 f1.SetParameter(1, x0);
243 f1.SetParameter(2, sigma);
244 f1.SetParameter(3, ymin);
249 TFitResultPtr result = h1->Fit(&f1, option.c_str(),
"same", x0 - 3 * sigma, x0 + 3 * sigma);
253 cout <<
"Histogram " << h1->GetName() <<
" fit " << (result->IsValid() ?
"" :
"failed") << endl;
254 cout <<
"\tx0 = " <<
FIXED(12,3) << x0 << endl;
255 cout <<
"\tt0 = " <<
FIXED(12,3) << f1.GetParameter(1) << endl;
258 t0[pmt] = f1.GetParameter(1);
262 if (overwriteDetector) {
264 NOTICE(
"Store calibration data on file " << detectorFile << endl);
266 detector.comment.add(
JMeta(argc, argv));
268 for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
270 const range_type range = TDC.equal_range(module->getID());
272 if (range.first != range.second) {
274 const double t1 = t0[JPMTIdentifier(range.first->first,
275 range.first->second)];
282 module->getPMT(pmt).subT0(p->second);
284 module->getPMT(pmt).subT0(t1);
289 store(detectorFile, detector);
Utility class to parse command line options.
Long64_t counter_type
Type definition for counter.
Auxiliary data structure for floating point format specification.
Data structure for detector geometry and calibration.
double getTimeOfFrame(const int frame_index)
Get start time of frame in ns since start of run for a given frame index.
Basic data structure for L0 hit.
JLimit JLimit_t
Type definition of limit.
Basic data structure for time and time over threshold information of hit.
#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.
Scanning of objects from multiple files according a format that follows from the extension of each fi...
Direct access to module in detector data structure.
Utility class to parse command line options.
ROOT TTree parameter settings.
void store(const JString &file_name, const JDetector &detector)
Store detector to output file.
const JLimit & getLimit() const
Get limit.
static const int NUMBER_OF_PMTS
Total number of PMTs in module.
#define DEBUG(A)
Message macros.
bool putObject(TDirectory *dir, const T &object)
Write object to ROOT directory.
int main(int argc, char *argv[])