#include #include #include #include "TRandom3.h" #include "km3net-dataformat/online/JDAQTimeslice.hh" #include "JTimeslice/JRandomTimeslice.hh" #include "JSummaryslice/JSummaryslice.hh" #include "JPhysics/JK40Rates.hh" #include "JDetector/JDetector.hh" #include "JDetector/JDetectorToolkit.hh" #include "JDetector/JDetectorSupportkit.hh" #include "JDetector/JDetectorSimulator.hh" #include "JDetector/JK40DefaultSimulator.hh" #include "JDetector/JPMTDefaultSimulator.hh" #include "JDetector/JCLBDefaultSimulator.hh" #include "JDAQ/JHighRateVeto.hh" #include "JTrigger/JSuperFrame2D.hh" #include "JTrigger/JTriggerToolkit.hh" #include "Jeep/JPrint.hh" #include "Jeep/JParser.hh" #include "Jeep/JMessage.hh" namespace { using namespace JPP; /** * Auxiliary class to generate background. */ class JK40Simulator_t : public JK40DefaultSimulatorInterface { public: /** * Constructor. * * \param R_Hz rate [Hz] */ JK40Simulator_t(const double R_Hz) : R_Hz(R_Hz) {} /** * Get singles rate as a function of PMT. * * \param pmt PMT identifier * \return rate [Hz] */ virtual double getSinglesRate(const JPMTIdentifier& pmt) const { return R_Hz; } /** * Get multiples rate as a function of optical module. * * \param module optical module identifier * \param M multiplicity (M >= 2) * \return rate [Hz] */ virtual double getMultiplesRate(const JModuleIdentifier& module, const int M) const { return 0.0; } /** * Get probability of coincidence. * * \param ct cosine space angle between PMT axes * \return probability */ virtual double getProbability(const double ct) const { return 0.0; } double R_Hz; }; /** * Auxiliary class to simulate UDP pacjet loss. */ class JCLBSimulator_t : public JCLBDefaultSimulator { public: /** * Constructor. * * \param n1 number of received UDP packets * \param n2 maximal sequence number of UDP packets */ JCLBSimulator_t(const int n1, const int n2) : n1(n1), n2(n2) {} /** * Get number of received UDP packets. * * \param id module identifier * \return 2 */ virtual int getUDPNumberOfReceivedPackets(const JModuleIdentifier& id) const { return n1; } /** * Get maximal sequence number of UDP packet. * * \param id module identifier * \return 1 */ virtual int getUDPMaximalSequenceNumber(const JModuleIdentifier& id) const { return n2; } int n1; int n2; }; } /** * \file * Test program to test UDP packet loss. * * \author mdejong */ int main(int argc, char **argv) { using namespace std; using namespace JPP; using namespace KM3NETDAQ; UInt_t seed; int debug; try { JParser<> zap("Test program to test UDP packet loss."); zap['S'] = make_field(seed) = 0; zap['d'] = make_field(debug) = 3; zap(argc, argv); } catch(const exception &error) { FATAL(error.what() << endl); } gRandom->SetSeed(seed); JDetector detector; detector.setVersion(JDetectorVersion::V3); detector.push_back(getModule(1001)); JDetectorSimulator simbad(detector); DEBUG(detector); const double R_Hz = 0.5 * HIGH_RATE_VETO_HZ; const int n1 = 10; // number of received UDP packets const int n2 = 20; // maximal sequence number of UDP packets const int numberOfSlices = 1000; const int numberOfHits = (int) (numberOfSlices * R_Hz * getFrameTime() * 1.0e-9 * (double) n1 / (double) (n2 + 1)); const double sigma_numberOfHits = (int) ((double) numberOfHits / sqrt(numberOfSlices * n1)); DEBUG("Number of hits: " << numberOfHits << " +/- " << sigma_numberOfHits << endl); ASSERT(numberOfHits > 100, "Test number of remaining hits."); try { simbad.reset(new JK40Simulator_t(R_Hz)); simbad.reset(new JPMTDefaultSimulatorInterface()); simbad.reset(new JCLBSimulator_t(n1, n2)); } catch(const JException& error) { FATAL(error.what() << endl); } vector buffer(NUMBER_OF_PMTS, 0); for (int count = 0; count != numberOfSlices; ++count) { STATUS("slice: " << setw(10) << count << '\r'); DEBUG(endl); const JRandomTimeslice timeslice(JDAQChronometer(), simbad); for (JDAQTimeslice::const_iterator frame = timeslice.begin(); frame != timeslice.end(); ++frame) { ASSERT(frame->getUDPNumberOfReceivedPackets() == n1); ASSERT(frame->getUDPMaximalSequenceNumber() == n2); for (JDAQFrame::const_iterator hit = frame->begin(); hit != frame->end(); ++hit) { buffer[hit->getPMT()] += 1; } } } STATUS(endl); for (int i = 0; i != NUMBER_OF_PMTS; ++i) { DEBUG("PMT " << setw(2) << i << ' ' << setw(4) << buffer[i] << endl); ASSERT(buffer[i] >= numberOfHits - 5.0 * sigma_numberOfHits && buffer[i] <= numberOfHits + 5.0 * sigma_numberOfHits, "Test of background generation with UDP packet loss."); } JSummaryslice summary(JDAQChronometer(), simbad); for (JSummaryslice::const_iterator frame = summary.begin(); frame != summary.end(); ++frame) { for (int i = 0; i != NUMBER_OF_PMTS; ++i) { DEBUG("PMT " << setw(2) << i << ' ' << FIXED(5,0) << frame->getRate(i) << ' ' << getRate(*frame, i) << endl); ASSERT(frame->getRate(i) >= R_Hz * ((double) n1 / (double) (n2 + 1)) * 0.99 && frame->getRate(i) <= R_Hz * ((double) n1 / (double) (n2 + 1)) * 1.01, "Test of rate generation with UDP packet loss."); ASSERT(getRate(*frame, i) >= R_Hz * 0.99 && getRate(*frame, i) <= R_Hz * 1.01, "Test of rate generation with UDP packet loss."); } } return 0; }