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);