87{
   91 
   93 
   95  JLimit_t&          numberOfEvents = inputFile.getLimit();
 
   97  string             detectorFile;
   99  double             laserFrequency_Hz;
  100  bool               overwriteDetector;
  102  string             option;
  103  double             Wmin              =   1e3;    
  107 
  108  try { 
  109 
  111 
  113 
  114    JParser<> zap(
"Application for dark room time calibration.");
 
  115    
  116    zap[
'f'] = 
make_field(inputFile,         
"input file (time slice data from laser calibration).");
 
  118    zap[
'a'] = 
make_field(detectorFile,      
"detector file.");
 
  120                          "Set reference PMTs, e.g."
  121                          "\n-! \"808969848 0 808982077 23\" sets PMT 0 of module 808969848 and PMT 23 of module 808982077 as references.");
  123    zap[
'l'] = 
make_field(laserFrequency_Hz, 
"laser frequency [Hz]")                             = 10000;
 
  124    zap[
'A'] = 
make_field(overwriteDetector, 
"overwrite detector file provided through '-a' with correct time offsets.");
 
  125    zap[
'O'] = 
make_field(option,            
"ROOT fit option, see TH1::Fit.")                   = 
"LS";
 
  128    zap[
'T'] = 
make_field(T_ns,              
"time window for time-over-threshold monitor")      = 
JRange_t(-10.0, +10.0);
 
  131    
  132    zap(argc, argv);
  133  }
  134  catch(const exception& error) {
  135    FATAL(error.what() << endl);
 
  136  }
  137 
  138 
  140 
  141  if (laserFrequency_Hz <= 0.0) {
  142    FATAL(
"Invalid laser frequency " << laserFrequency_Hz << endl);
 
  143  }
  144 
  145  const double laserPeriod_ns = 1.0e9 / laserFrequency_Hz;
  146 
  147  if (option.find('R') == string::npos) { option += 'R'; }
  148  if (option.find('S') == string::npos) { option += 'S'; }
  150 
  151 
  153 
  154  try {
  156  }
  159  }
  160 
  162 
  163 
  164  
  165 
  167 
  169 
  171 
  172  map_type     zmap;
  173 
  176  const int    nx   =  2 * (int) (xmax - xmin);
  177 
  178  TH1D h0("h0", NULL, nx, xmin, xmax);
  179  TH1D h1("h1", NULL, 256, -0.5, +255.5);
  180 
  182 
  183  for (JDetector::iterator module = 
detector.begin(); module != 
detector.end(); ++module) {
 
  184 
  186 
  187    for (JTDC_t::const_iterator i = range.first; i != range.second; ++i) {
  188 
  190             << " string  " << setw(3) << module->getString() 
  191             << " floor   " << setw(2) << module->getFloor()
  192             << " module  " << setw(8) << module->getID() 
  193             << " channel " << setw(2) << i->second << endl);
  194 
  196      
  197      ostringstream os;
  198      
  200      
  201      zmap.insert(make_pair(id, new TH1D(os.str().c_str(), NULL, nx, xmin, xmax)));
  202    }
  203  }
  204 
  205 
  207 
  209 
  210 
  212  
  214 
  215  for ( ; in.hasNext() && counter != inputFile.getLimit(); ++counter) {
  216 
  217    STATUS(
"event: " << setw(10) << counter << 
'\r'); 
DEBUG(endl);
 
  218 
  220 
  221    for (JDAQTimeslice::const_iterator frame = timeslice->begin(); frame != timeslice->end(); ++frame) {
  222 
  224 
  225      if (range.first != range.second) {
  226 
  227        const double t0 = get_time(
getTimeOfFrame(frame->getFrameIndex()), laserPeriod_ns);
 
  228 
  229        JDataL0_t dataL0;
  230 
  231        buildL0(*frame, moduleRouter.getModule(frame->getModuleID()), back_inserter(dataL0));
  232 
  233        for (JDataL0_t::const_iterator hit = dataL0.begin(); hit != dataL0.end(); ++hit) {
  234 
  236 
  237          map_type::const_iterator p = zmap.find(id);
  238 
  239          if (p != zmap.end()) {
  240 
  241            const double t1 = get_time(t0 + hit->getT(), laserPeriod_ns);
  242 
  243            p->second->Fill(t1);
  244 
  245            h0.Fill(t1);
  246 
  247            if (T_ns(t1)) {
  248 
  249              h1.Fill(hit->getToT());
  250 
  251              counts[id] += 1;
  252            }
  253          }
  254        }
  255      }
  256    }
  257  }
  259 
  260 
  262 
  263 
  264  TF1 f1("f1", "[0]*exp(-0.5*(x-[1])*(x-[1])/([2]*[2]))/(TMath::Sqrt(2.0*TMath::Pi())*[2]) + [3]");
  265 
  266  for (map_type::iterator it = zmap.begin(); it != zmap.end(); ++it) {
  267 
  269    TH1D*          h1  = it->second;
  270 
  271    if (h1->GetEntries() == 0) {
  272      WARNING(
"Histogram " << h1->GetName() << 
" empty" << endl);
 
  273      continue;
  274    }
  275 
  276    STATUS(
"--- PMT = " << pmt << 
"; histogram " << h1->GetName() <<  endl);
 
  277 
  278    
  279    
  280    Double_t ymax  = 0.0;
  281    Double_t x0    = 0.0;    
  282    Double_t sigma = 2.0;    
  283    Double_t ymin  = 0.0;
  284    
  285    for (int i = 1; i != h1->GetNbinsX(); ++i) {
  286      
  287      const Double_t 
x = h1->GetBinCenter (i);
 
  288      const Double_t 
y = h1->GetBinContent(i);
 
  289      
  290      if (y > ymax) {
  293      }
  294    }
  295 
  296    f1.SetParameter(0, ymax/sigma);
  297    f1.SetParameter(1, x0);
  298    f1.SetParameter(2, sigma);
  299    f1.SetParameter(3, ymin);
  300 
  301    for (Int_t i = 0; i != f1.GetNpar(); ++i) {
  302      f1.SetParError(i, 0.0);
  303    }
  304    
  305    
  306    
  307    
  308    TFitResultPtr 
result = h1->Fit(&f1, option.c_str(), 
"same", x0 - 3 * sigma, x0 + 3 * sigma);
 
  309 
  310    if (
result.Get() == NULL) {
 
  311      FATAL(
"Invalid TFitResultPtr " << h1->GetName() << endl);
 
  312    }
  313    
  315      cout << 
"Histogram " << h1->GetName() << 
" fit " << (
result->IsValid() ? 
"ok" : 
"failed") << endl;
 
  316      cout << 
"\tw  = " << 
FIXED(12,3) << f1.GetParameter(0) << endl;
 
  317      cout << 
"\tx0 = " << 
FIXED(12,3) << x0                 << endl;
 
  318      cout << 
"\tt0 = " << 
FIXED(12,3) << f1.GetParameter(1) << endl;
 
  319    }
  320 
  321 
  322    
  323 
  324    int number_of_peaks = 0;
  325 
  326    Double_t dx = 2.0 * f1.GetParameter(2);
  327    Double_t W  = 0.0;
  328    Double_t Y  = f1.GetParameter(3);
  329 
  330    if (dx < (xmax - xmin) / nx) {
  331      dx = (xmax - xmin) / nx;                    
  332    }
  333 
  334    for (Int_t il = 1, ir = il; ir <= nx; ) {
  335 
  336      for ( ; ir <= nx && h1->GetBinCenter(ir) <= h1->GetBinCenter(il) + dx; ++ir) {
  337        W += h1->GetBinContent(ir) - Y;
  338      }
  339 
  340      if (W >= Wmin) {
  341 
  342        number_of_peaks += 1;
  343 
  344        W   = 0.0;                                
  345        il  = ir;
  346        ir  = il;
  347 
  348      } else {
  349 
  350        W  -= h1->GetBinContent(il) - Y;          
  351        il += 1;
  352      }
  353    }
  354 
  355    if (number_of_peaks != 1) {
  356      WARNING(
"Number of peaks " << h1->GetName() << 
' ' << number_of_peaks << 
" != 1" << endl);
 
  357    }
  358 
  359    if (
result->IsValid() && f1.GetParameter(0) >= Wmin) {
 
  360      t0[pmt] = f1.GetParameter(1);
  361    }
  362  }
  363 
  364  out.Write();
  365  out.Close();
  366 
  367 
  368  if (counter != 0) {
  369 
  370    const double W = laserFrequency_Hz * counter * 
getFrameTime() * 1.0e-9;
 
  371 
  372    NOTICE(
"Expection values [npe]" << endl);
 
  373 
  375      NOTICE(i->first << 
' ' << 
FIXED(7,3) << i->second / W << endl);
 
  376    }
  377  }
  378 
  379 
  380  if (overwriteDetector) { 
  381 
  382    int errors = 0;
  383 
  384    for (JDetector::iterator module = 
detector.begin(); module != 
detector.end(); ++module) {
 
  385 
  387 
  388      if (range.first != range.second) {
  389 
  391 
  393 
  394        if (p0 != t0.end()) {
  395 
  396          const double t1 = p0->second;
  397 
  399 
  401          
  403              module->getPMT(pmt).subT0(p1->second);                   
  404            else
  405              module->getPMT(pmt).subT0(t1);                           
  406          }
  407 
  408        } else {
  409 
  410          if (!module->getPMT(
id.getPMTAddress()).has(
PMT_DISABLE)) {
 
  411            ++errors;
  412          }
  413 
  415                << setw(10) << module->getID() << 
"/" << 
FILL(2,
'0') << 
id.getPMTAddress() << 
FILL() << 
' ' 
  416                << "missing or insufficient signal." << endl); 
  417        }
  418      }
  419    }
  420 
  421    if (errors == 0) {
  422 
  423      NOTICE(
"Store calibration data on file " << detectorFile << endl);
 
  424 
  426 
  428 
  429    } else {
  430 
  431      FATAL(
"Number of errors " << errors << 
" != 0" << endl);
 
  432    }
  433  }
  434}
#define DEBUG(A)
Message macros.
 
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
 
#define gmake_property(A)
macros to convert (template) parameter to JPropertiesElement object
 
Router for direct addressing of module data in detector data structure.
 
Utility class to parse parameter values.
 
Auxiliary class for multiplexing object iterators.
 
Utility class to parse command line options.
 
General purpose class for object reading from a list of file names.
 
std::string getLabel(const JLocation &location)
Get module label for monitoring and other applications.
 
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
 
void store(const std::string &file_name, const JDetector &detector)
Store detector to output file.
 
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
 
bool putObject(TDirectory &dir, const TObject &object)
Write object to ROOT directory.
 
std::set< JROOTClassSelector > getROOTClassSelection(const bool option=false)
Get ROOT class selection.
 
Long64_t counter_type
Type definition for counter.
 
KM3NeT DAQ data structures and auxiliaries.
 
double getFrameTime()
Get frame time duration.
 
double getTimeOfFrame(const int frame_index)
Get start time of frame in ns since start of run for a given frame index.
 
static const int NUMBER_OF_PMTS
Total number of PMTs in module.
 
std::map< int, range_type > map_type
 
static const int PMT_DISABLE
KM3NeT Data Definitions v3.6.1-2-g905a24d https://git.km3net.de/common/km3net-dataformat.
 
Auxiliary data structure for sequence of same character.
 
Auxiliary data structure for floating point format specification.
 
Type definition of range.
 
Auxiliary class for TDC constraints.
 
range_type equal_range(const int id)
Get range of constraints for given module.
 
bool is_valid(const bool option=false) const
Check validity of TDC constrants.
 
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
 
Auxiliary class to select ROOT class based on class name.
 
Auxiliary class for defining the range of iterations of objects.
 
static counter_type max()
Get maximum counter value.