#include #include #include #include "TRandom3.h" #include "km3net-dataformat/offline/Head.hh" #include "km3net-dataformat/online/JDAQClock.hh" #include "JAAnet/JHead.hh" #include "JAAnet/JHeadToolkit.hh" #include "JDetector/JDetector.hh" #include "JDetector/JDetectorToolkit.hh" #include "JDetector/JPMTParametersMap.hh" #include "JDetector/JK40DefaultSimulator.hh" #include "JDetector/JPMTDefaultSimulator.hh" #include "JDetector/JCLBDefaultSimulator.hh" #include "JDetector/JDetectorSimulator.hh" #include "JDAQ/JDAQSummarysliceIO.hh" #include "JDAQ/JDAQTimesliceIO.hh" #include "JTimeslice/JRandomTimeslice.hh" #include "JTrigger/JSummaryRouter.hh" #include "JTrigger/JK40RunByRunSimulator.hh" #include "JTrigger/JPMTRunByRunSimulator.hh" #include "JSupport/JSingleFileScanner.hh" #include "JSupport/JFileRecorder.hh" #include "JSupport/JSupport.hh" #include "JSupport/JSupportToolkit.hh" #include "JSupport/JRunByRun.hh" #include "JSupport/JMeta.hh" #include "Jeep/JTimer.hh" #include "Jeep/JParser.hh" #include "Jeep/JMessage.hh" /** * \file * * Auxiliary program to write KM3NETDAQ::JDAQTimeslice with random data.\n * To pipe data to application JTriggerProcessor.cc whilst maintaining header and meta data, two output files can be specified.\n * The file names should have extensions ".root" and ".dat", respectively. \n * The first corresponds to a ROOT formatted file with header and meta data and the second to the pipe with timeslice data. * \author mdejong */ int main(int argc, char **argv) { using namespace std; using namespace JPP; using namespace KM3NETDAQ; typedef JFileRecorder::typelist> JFileRecorder_t; vector outputFile; string detectorFile; Long64_t numberOfSlices; JDAQHit::JTDC_t TCLB_ns; JPMTParametersMap pmtParameters; JK40Rates rates_Hz; int run; JRunByRun runbyrun; pair recycling; double sigma_ns; bool fast; UInt_t seed; int debug; try { JParser<> zap("Auxiliary program to write time slices with random data."); zap['o'] = make_field(outputFile, "output file"); zap['n'] = make_field(numberOfSlices); zap['a'] = make_field(detectorFile, "detector."); zap['R'] = make_field(run, "run number") = -1; zap['r'] = make_field(runbyrun, "option for run-by-run mode") = JPARSER::initialised(); zap['P'] = make_field(pmtParameters, "PMT simulation data (or corresponding file name)") = JPARSER::initialised(); zap['B'] = make_field(rates_Hz, "background rates [Hz]") = JPARSER::initialised(); zap['T'] = make_field(TCLB_ns, "CLB state-machine time jitter") = 256; // [ns] zap['N'] = make_field(recycling, "number of recycles / time interval for sampling data [ns]") = make_pair(0, 0.0); zap['s'] = make_field(sigma_ns, "intrinsic time smearing of K40 coincidences [ns]") = JK40DefaultSimulatorInterface::getSigma(); zap['F'] = make_field(fast, "fast - disable PMT simulation"); zap['S'] = make_field(seed, "seed") = 0; zap['d'] = make_field(debug, "debug") = 0; zap(argc, argv); } catch(const exception &error) { FATAL(error.what() << endl); } if (outputFile.size() != 1 && outputFile.size() != 2) { FATAL("Invalid number of output files; should be 1 or 2." << endl); } gRandom->SetSeed(seed); JK40DefaultSimulatorInterface::setSigma(sigma_ns); setDAQLongprint(debug >= JEEP::debug_t); if (pmtParameters.getQE() != 1.0) { WARNING("Correct background rates with global efficiency " << pmtParameters.getQE() << endl); rates_Hz.correct(pmtParameters.getQE()); } DEBUG("PMT parameters: " << endl << pmtParameters << endl); DEBUG("K40 rates: " << endl << rates_Hz << endl); JDetector detector; try { load(detectorFile, detector); } catch(const JException& error) { FATAL(error); } JPMTParametersMap::Throw(false); JDetectorSimulator simbad(detector); JSummaryRouter summaryRouter; if (runbyrun.is_valid()) { NOTICE("Using run-by-run:" << endl << runbyrun << endl); if (!runbyrun.hasNext()) { FATAL("Run-by-run simulation yields no input." << endl); } if (rates_Hz.getSinglesRate() != 0.0) { WARNING("Run-by-run simulation discards singles rate [Hz] " << rates_Hz.getSinglesRate() << endl); } try { simbad.reset(new JK40RunByRunSimulator(summaryRouter, rates_Hz)); simbad.reset(new JPMTDefaultSimulator(pmtParameters, detector)); simbad.reset(new JCLBDefaultSimulator()); } catch(const JException& error) { FATAL(error.what() << endl); } } else { NOTICE("Using fixed rates [Hz]: " << rates_Hz << endl); try { simbad.reset(new JK40DefaultSimulator(rates_Hz)); simbad.reset(fast ? new JPMTDefaultSimulatorInterface() : new JPMTDefaultSimulator(pmtParameters, detector)); simbad.reset(new JCLBDefaultSimulator()); } catch(const JException& error) { FATAL(error.what() << endl); } } JTimer timerco("constructor"); JTimer timerrc("recycle"); JTimer timerIO("I/O"); for (size_t i = 0; i != outputFile.size(); ++i) { outputFile[i].open(); if (!outputFile[i].is_open()) { FATAL("Error opening file " << outputFile[i] << endl); } } outputFile[0].put(JMeta(argc, argv)); outputFile[0].put(*gRandom); int counter = 0; for ( ; counter != numberOfSlices; ) { STATUS("slice: " << setw(10) << counter << '\r'); DEBUG(endl); int frame_index = counter + 1; if (runbyrun.hasNext()) { summaryRouter.update(runbyrun.next()); summaryRouter.correct(dynamic_cast(simbad.getPMTSimulator())); frame_index = summaryRouter.getFrameIndex(); run = summaryRouter.getRunNumber(); } JDAQUTCExtended utc(JDAQUTCExtended::getInstance().getTimeNanoSecond() + getTimeOfFrame(frame_index)); // ensure incremental UTC times (e.g. for JDAQSplit.cc) const JDAQChronometer chronometer(detector.getID(), run, frame_index, utc); timerco.start(); JRandomTimeslice timeslice(chronometer, simbad); timerco.stop(); timerIO.start(); outputFile.rbegin()->put(timeslice); ++counter; timerIO.stop(); for (size_t i = 1; i <= recycling.first && counter != numberOfSlices; ++i) { STATUS("slice: " << setw(10) << counter << '\r'); DEBUG(endl); timerrc.start(); timeslice.recycle(recycling.second); timerrc.stop(); timerIO.start(); outputFile.rbegin()->put(timeslice); ++counter; timerIO.stop(); } } STATUS(endl); if (debug >= notice_t) { timerco.print(cout, true); timerrc.print(cout, true); timerIO.print(cout, true); } Head header; { JHead buffer; buffer.DAQ.livetime_s = getLivetime(runbyrun->getFilelist()); buffer.K40.livetime_s = counter * getFrameTime() * 1.0e-9; buffer.push(&JHead::DAQ); buffer.push(&JHead::K40); copy(buffer, header); } outputFile[0].put(header); outputFile[0].put(*gRandom); for (size_t i = 0; i != outputFile.size(); ++i) { outputFile[i].close(); } }