52 int main(
int argc,
char **argv)
55 using namespace KM3NETDAQ;
74 bool monitorOccupancy;
79 JParser<> zap(
"Auxiliary program to estimate PMT and hit multiplicities.");
84 zap[
'n'] =
make_field(numberOfEvents) = JLimit::max();
88 zap[
'C'] =
make_field(selector) = getROOTClassSelection<JDAQTimesliceTypes_t>();
91 zap[
'F'] =
make_field(filterLevel,
"0 = raw data; 1 = filtered data; 2+ = only clean frames") = 1;
92 zap[
'D'] =
make_field(twoDim,
"2D mode for background subtraction");
93 zap[
'O'] =
make_field(monitorOccupancy,
"produces 2D PMT vs multiplicity plots");
94 zap[
'j'] =
make_field(notJoin,
"do not join consecutive hits on same PMT (diagnostic purpose)");
98 catch(
const exception &error) {
99 FATAL(error.what() << endl);
109 bool hasTriggerParameters =
true;
113 NOTICE(
"Get trigger parameters from input." << endl);
116 ERROR(
"No trigger parameters from input." << endl);
117 hasTriggerParameters =
false;
124 if (hasTriggerParameters) {
128 if (
parameters.writeL1.prescale > 0 && (selector ==
"JDAQTimeslice" || selector ==
"JDAQTimesliceL1") &&
130 FATAL(
"TMax_ns (-T) " << TMax_ns <<
" ns is larger than in the trigger " <<
parameters.TMaxLocal_ns <<
" ns." << endl);
133 if (selector ==
"JDAQTimeslice") {
138 if (selector ==
"JDAQTimesliceL0") {
142 if (selector ==
"JDAQTimesliceL1") {
146 if (selector ==
"JDAQTimesliceSN") {
153 FATAL(
"[R] According to trigger parameters, the " << selector <<
" stream should be empty.");
155 NOTICE(
"[R] Prescale factor is " << prescale << endl);
158 if (!totVeto_ns.is_valid()) {
159 FATAL(
"Invalid time over threshold " << totVeto_ns << endl);
176 FATAL(
"Empty detector." << endl);
193 NOTICE(
"[R] Tmax [ns] " << TMax_ns << endl);
194 NOTICE(
"[R] Rate range [Hz] " << rateVeto_Hz << endl);
195 NOTICE(
"[R] ToT range [ns] " << totVeto_ns << endl);
196 NOTICE(
"[R] Timeslice stream " << selector << endl);
197 NOTICE(
"[R] Detector file has " << detSize <<
" DOMs." << endl);
204 TH1D* h_livetime =
new TH1D(
"LiveTime",
"Livetime", 1 + detSize, 0.0, 1.0 + detSize);
207 h_livetime->GetXaxis()->SetBinLabel(ibin++,
"Nominal");
208 for (JDetector::iterator module =
detector.begin(); module !=
detector.end(); ++module) {
209 h_livetime->GetXaxis()->SetBinLabel(ibin++, TString(
getLabel(*module)));
212 h_livetime->GetYaxis()->SetTitle(
"Livetime (s)");
217 const double xmin = -0.5;
218 const double xmax = nx - 0.5;
222 JManager_t
H(
new TH1D(
"%_H", NULL, nx, xmin, xmax)); H->Sumw2();
223 JManager_t
P(
new TH1D(
"%_P", NULL, nx, xmin, xmax)); P->Sumw2();
225 JManager2D_t HT(
new TH2D(
"%_HT", NULL, nx, xmin, xmax, 100, -TMax_ns, +TMax_ns));
229 if (monitorOccupancy) {
230 JModuleAddressMap memo = getDetectorAddressMap<JKM3NeT_t>().getDefaultModuleAddressMap();
234 JManager2D_t CO(CO_proto);
237 const int sn_mul_min = 6;
238 TH1D* time_distr =
new TH1D(
"T_distr",
"Coincidence (M > 6) distribution in timeslice", 100, 0, 1e8);
253 int treeMismatchCount = 0;
272 bool hasMCHeader = true ;
273 bool isMupage =
false;
274 double liveTimeMC = 0 ;
275 double liveTimeMCErr = 0 ;
286 NOTICE(
"[R] File source is " << (hasMCHeader ?
"MC" :
"DAQ") <<
"." << endl);
288 liveTimeMC = mc_header.livetime.numberOfSeconds;
289 liveTimeMCErr = mc_header.livetime.errorOfSeconds;
290 if (liveTimeMC > 0) {
292 NOTICE(
"[R] mupage live time is (" << liveTimeMC <<
" +/- " << liveTimeMCErr <<
") s." << endl);
294 NOTICE(
"[R] aanet header found but mupage live time is zero. Likely not a mupage file.");
302 if (summaryFile.hasNext()) {
303 runNumber = summaryFile.getEntry(0)->getRunNumber();
304 NOTICE(
"[R] Processing run #" << runNumber << endl);
305 summaryFile.rewind();
312 for ( ; in.
hasNext() && counter != inputFile.getLimit(); ++counter) {
314 STATUS(
"Entry: " << setw(10) << counter <<
'\r');
317 const Long64_t index = summaryFile.find(*timeslice);
318 JDAQSummaryslice* summary = (index != -1 ? summaryFile.getEntry(index) : NULL);
320 summaryRouter.update(summary);
323 if (summary != NULL) {
326 ERROR(
"[R>T] Frame indices do not match [counter=" << counter <<
", timeslice=" << timeslice->
getFrameIndex() <<
", summaryslice=" << summary->
getFrameIndex() <<
"]" << endl);
327 if (treeMismatchCount > 1) {
328 FATAL(
"ROOT TTrees not aligned. Run #" << runNumber << endl);
337 for (JDAQTimeslice::const_iterator super_frame = timeslice->begin(); super_frame != timeslice->end(); ++super_frame) {
343 int moduleID = super_frame->getModuleID();
359 if (summary == NULL) {
360 WARNING(
"[R>T>F] Missing summary for timeslice." << endl);
375 if (!summaryRouter.hasSummaryFrame(super_frame->getModuleIdentifier())) {
376 summaryRouter.print(cout);
377 FATAL(
"[R>D>F] Summary frame not found, module = " << super_frame->getModuleID() << endl);
379 summary_frame = summaryRouter.getSummaryFrame(super_frame->getModuleID());
384 rate_Hz[i] = summary_frame.
getRate(i);
398 WARNING(
"[R>D>F] DAQ status not okay in timeslice #" << timeslice->
getFrameIndex() <<
", DOM=" << super_frame->getModuleID() << endl);
403 bool moduleLiveTime = 0;
414 int frame_URV_count = 0;
417 if (veto[i] = (veto[i] || !rateVeto_Hz(rate_Hz[i]))) {
422 count_HRV += frame_HRV_count;
423 count_FAF += frame_FAF_count;
424 count_URV += frame_URV_count;
426 int frame_VETO_count = frame_HRV_count + frame_FAF_count + frame_URV_count;
429 if (filterLevel >= 2 && frame_VETO_count > 0) {
431 fill(veto.begin(), veto.end(),
true);
432 }
else if (filterLevel >= 1 && frame_HRV_count + frame_FAF_count > 0) {
440 if (muteChannel != -1) {
443 int mute_VETO_count =
446 !rateVeto_Hz(rate_Hz[muteChannel] );
448 if (mute_VETO_count == frame_VETO_count) {
450 fill(veto.begin(), veto.end(),
false);
453 veto[muteChannel] =
true;
460 const TString moduleLabel =
getLabel(module);
463 if (moduleLiveTime) {
464 h_livetime->Fill(moduleLabel,
getFrameTime() * 1e-9 * moduleLiveTime);
471 JSuperFrame2D_t& buffer = JSuperFrame2D_t::demultiplex(*super_frame, router.
getModule(super_frame->getModuleID()));
474 for (JSuperFrame2D_t::iterator i = buffer.begin(); i != buffer.end(); ++i) {
479 JSuperFrame1D_t& data = JSuperFrame1D_t::multiplex(buffer);
481 filteredData.clear();
485 const int pmt = h->getPMT();
489 rateVeto_Hz(rate_Hz[pmt]) &&
490 totVeto_ns(h->getToT()) ) {
491 filteredData.push_back(*h);
497 if (filteredData.size() > 1) {
499 TH1D* h_hit = H[moduleLabel];
500 TH1D* h_pmt = P[moduleLabel];
502 TH2D* h2_hit = HT[moduleLabel];
503 TH2D* h2_co = CO[moduleLabel];
505 sort(filteredData.begin(), filteredData.end());
515 while (++q != filteredData.end() && q->getT() - p->getT() <= TMax_ns ) {}
518 int hit_multiplicity =
distance(p,q);
521 int pmt_multiplicity = pmthit.size() ;
524 h_pmt->Fill(pmt_multiplicity);
525 h_hit->Fill(hit_multiplicity);
527 if (twoDim && hit_multiplicity > 1) {
528 const double W =
factorial(hit_multiplicity, 2);
531 double dt = JCombinatorics::getSign(__p->getPMT(), __q->getPMT()) * (__q->getT() - __p->getT());
532 h2_hit->Fill(hit_multiplicity, dt, 1.0/W);
537 if (monitorOccupancy) {
540 TString pmtLabel(pmtAddress.
toString());
541 h2_co->Fill(pmt_multiplicity, pmtLabel, 1.0/pmt_multiplicity);
546 if (hit_multiplicity >= sn_mul_min) {
547 time_distr->Fill(p->getT());
560 NOTICE(
"[R] " << counter <<
" timeslices processed." << endl);
563 h_livetime->Scale(liveTimeMC / (
getFrameTime() * 1e-9 * counter * prescale));
567 double nominalLiveTime = (isMupage ? liveTimeMC : counter *
getFrameTime() * 1e-9) / prescale;
568 h_livetime->Fill(
"Nominal", nominalLiveTime);
572 int nLiveDOMs = H.size();
585 if (monitorOccupancy) {
591 double rate_HRV = count_HRV / (1.0 * counter);
592 double rate_FAF = count_FAF / (1.0 * counter);
593 double rate_URV = count_URV / (1.0 * counter);
594 double biolumIndex = (rate_HRV + rate_FAF) / (nLiveDOMs *
NUMBER_OF_PMTS);
595 NOTICE(
"[R] Average HRV count per timeslice: " << rate_HRV << endl);
596 NOTICE(
"[R] Average FIFO-almost-full count per timeslice: " << rate_FAF << endl);
597 NOTICE(
"[R] Average user rate veto count per timeslice: " << rate_URV << endl);
598 NOTICE(
"[R] " << H.size() <<
" DOMs were active in the run." << endl);
599 NOTICE(
"[R] Bioluminescence proxy index: " << biolumIndex << endl);
607 return (counter ? 0 : 1);
Utility class to parse command line options.
int main(int argc, char *argv[])
ROOT TTree parameter settings of various packages.
double getRate(const int tdc, const double factor=1.0) const
Get count rate.
int countFIFOStatus() const
Count FIFO status.
Basic data structure for L0 hit.
const JModule & getModule(const JObjectID &id) const
Get module parameters.
Data structure for a composite optical module.
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
std::string getLabel(const JLocation &location)
Get module label for monitoring and other applications.
Auxiliary class to select ROOT class based on class name.
Router for direct addressing of module data in detector data structure.
static const double H
Planck constant [eV s].
*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
Lookup table for PMT addresses in detector.
Long64_t counter_type
Type definition for counter.
Dynamic ROOT object management.
Auxiliary class for multiplexing object iterators.
static const JModuleCounter getNumberOfModules
Function object to count unique modules.
Basic data structure for time and time over threshold information of hit.
Data structure for detector geometry and calibration.
long long int factorial(const long long int n)
Determine factorial.
int getFrameIndex() const
Get frame index.
1-dimensional frame with time calibrated data from one optical module.
Head getHeader(const JMultipleFileScanner_t &file_list)
Get Monte Carlo header.
Auxiliary class for defining the range of iterations of objects.
Lookup table for PMT addresses in optical module.
Auxiliary class to manage set of compatible ROOT objects (e.g. histograms) using unique keys...
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
double getFrameTime()
Get frame time duration.
Data storage class for rate measurements of all PMTs in one module.
void setAxisLabels(TAxis *axis, const JModuleAddressMap &memo)
Set axis with PMT address labels.
virtual const pointer_type & next() override
Get next element.
Address of module in detector data structure.
Match operator for consecutive hits.
virtual bool hasNext() override
Check availability of next element.
bool putObject(TDirectory &dir, const TObject &object)
Write object to ROOT directory.
Router for fast addressing of summary data in JDAQSummaryslice data structure as a function of the op...
JDetectorAddressMap & getDetectorAddressMap()
Get detector address map.
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.
bool testHighRateVeto() const
Test high-rate veto status.
const JPMTAddressTranslator & getAddressTranslator(const int tdc) const
Get PMT address translator.
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
Auxiliary class to define a range between two values.
int countHighRateVeto() const
Count high-rate veto status.
General purpose class for object reading from a list of file names.
Utility class to parse command line options.
std::string toString() const
Convert PMT physical address to string.
const JModuleAddress & getAddress(const JObjectID &id) const
Get address of module.
bool hasModule(const JObjectID &id) const
Has module.
2-dimensional frame with time calibrated data from one optical module.
const JLimit & getLimit() const
Get limit.
Data structure for PMT physical address.
do set_variable DETECTOR_TXT $WORKDIR detector
KM3NeT DAQ constants, bit handling, etc.
static const int NUMBER_OF_PMTS
Total number of PMTs in module.
bool testDAQStatus() const
Test DAQ status of packets.
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 source JAcoustics sh $DETECTOR_ID CHECK_EXIT_CODE typeset A TRIPODS get_tripods $WORKDIR tripod txt TRIPODS for EMITTER in
const JDAQFrameStatus & getDAQFrameStatus() const
Get DAQ frame status.
JTriggerParameters getTriggerParameters(const JMultipleFileScanner_t &file_list)
Get trigger parameters.
bool testFIFOStatus() const
Test FIFO status.