#include #include namespace CTA { namespace ACTL { namespace CDTS { Simulator::Simulator(Socket_ptr&& pSocket, double pFrequencyInHz, double pRMSInPS) : Processor(0), fSocket(std::move(pSocket)), fFrequencyInHz(pFrequencyInHz), fRMSInPS(pRMSInPS), fBunchCounterErrorEnabled(false), fEventCounterErrorEnabled(false), fTimeStampMissingEnabled(false), fSecondErrorEnabled(false), fPicoSecondErrorEnabled(false), fTriggerBunch(), fBunchCounter(0u), fEventCounter(0u), fLast(Clock::now()), fRandom(0) {} bool Simulator::Process() { TimePoint now = Clock::now(); TriggerMessage& trigger = *fTriggerBunch.add_triggers(); trigger.set_telescope(1); trigger.set_event_counter(fEventCounter); if (!GetEventCounterErrorEnabled() || fRandom.Rndm() < 0.99) ++fEventCounter; TimeStamp& time = *trigger.mutable_time(); double frequency = GetFrequencyInHz(); if (!GetTimeStampMissingEnabled() || fRandom.Rndm() < 0.95) { Seconds seconds = std::chrono::duration_cast(now.time_since_epoch()); if (!GetSecondErrorEnabled() || fRandom.Rndm() < 0.9) time.set_seconds(seconds.count()); else { time.set_seconds(seconds.count() - 1); now = now - Seconds(1); } Nanoseconds nano_seconds = std::chrono::duration_cast(now.time_since_epoch()); if (!GetPicoSecondErrorEnabled() || fRandom.Rndm() < 0.9) time.set_pico_seconds(1e3 * (nano_seconds.count() - time.seconds() * 1e9)); else time.set_pico_seconds(1e3 * (nano_seconds.count() - time.seconds() * 1e9) - 5e11 / frequency); } double deltaT = fRandom.Gaus(1. / frequency * 1e12, GetRMSInPS()); usleep(deltaT / 1e6); if (std::chrono::duration_cast(now - fLast).count() > 100) { fLast = now; fTriggerBunch.set_bunch_counter(fBunchCounter); if (!GetBunchCounterErrorEnabled() || fRandom.Rndm() < 0.98) ++fBunchCounter; fTriggerBunch.set_telescope(1); fSocket->SendMessage(fTriggerBunch); fTriggerBunch.Clear(); } return true; } } } }