Jpp 20.0.0-27-g39925593c-D
the software that should make you happy
Loading...
Searching...
No Matches
JCLBDefaultSimulatorInterface.hh
Go to the documentation of this file.
1#ifndef __JDETECTOR__JCLBDEFAULTSIMULATORINTERFACE__
2#define __JDETECTOR__JCLBDEFAULTSIMULATORINTERFACE__
3
4#include <vector>
5#include <algorithm>
6#include <memory>
7
8#include "TRandom3.h"
9
15
17#include "JDAQ/JHighRateVeto.hh"
22
23
24/**
25 * \author mdejong
26 */
27
28namespace JDETECTOR {}
29namespace JPP { using namespace JDETECTOR; }
30
31namespace JDETECTOR {
32
35
36
37 /**
38 * Default CLB simulation.
39 *
40 * This class provides for a default implementation of the JCLBSimulator interface
41 * which is based on a simulation of the TDC and the state machine inside the CLB.
42 * The actual number of hits may change due to the high-rate veto and UDP packet loss
43 * (loss of hits) and the dynamic range of the time-over-threshold (gain of hits).
44 *
45 * The nested class JStateMachine constitutes a user interface for the simulation
46 * of the state machine through method JStateMachine::maybeSwapped().
47 * With the default implementation, the overall time ordering if hits is maintained.
48 * For a realistic simulation of the CLB, a pointer to a designated implementation
49 * of this interface should be provided.
50 *
51 * The implementation of the virtual method JCLBDefaultSimulatorInterface::processData
52 * provides for the settings of the status of the data frame.\n
53 * In this, the high-rate veto is set when:
54 * - virtual method JCLBDefaultSimulatorInterface::getHighRateVeto returns true for the given PMT; or
55 * - number of hits from the PMT exceeds KM3NETDAQ::getMaximalNumberOfHits.
56 */
58 public JCLBSimulator
59 {
60 public:
61
65
66
67 /**
68 * Interface for TDC.
69 */
70 class JTDC {
71 public:
72 /**
73 * Virtual destructor.
74 */
75 virtual ~JTDC()
76 {}
77
78
79 /**
80 * Make DAQ hit.
81 *
82 * \param pmt PMT channel
83 * \param t_ns time of hit [ns]
84 * \param tot_ns time over threshold [ns]
85 * \return DAQ hit
86 */
87 virtual JDAQHit makeHit(const JPMT_t pmt,
88 const double t_ns,
89 const JTOT_t tot_ns) const
90 {
91 return JDAQHit(pmt, (JTDC_t) t_ns, tot_ns);
92 }
93 };
94
95
96 /**
97 * Interface to mimic hit ordering effects due to state machine inside CLB.
98 */
100 public:
101 /**
102 * Virtual destructor.
103 */
105 {}
106
107
108 /**
109 * Test whether two consecutive hits may be swapped.
110 *
111 * \param first first DAQ hit
112 * \param second second DAQ hit
113 * \return true if first and second hit may be swapped; else false
114 */
115 virtual bool maybeSwapped(const JDAQHit& first, const JDAQHit& second) const
116 {
117 return false;
118 }
119 };
120
121
122 /**
123 * Constructor.
124 *
125 * This class owns the objects pointed to.
126 *
127 * \param TDC pointer to TDC simulator
128 * \param state_machine pointer to state machine
129 */
135
136
137
138 /**
139 * Get DAQ frame status of given module.
140 *
141 * \param id module identifier
142 * \return DAQ frame status
143 */
145 {
146 using namespace KM3NETDAQ;
147
150 int status = DAQ_WHITE_RABBIT.write(1); // TDC status
151 int fifo = DAQ_UDP_TRAILER .write(hasUDPTrailer(id) ? 1 : 0); // FIFO status
152
153 for (size_t pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
154 JBit(pmt).set(status, getHighRateVeto(JPMTIdentifier(id,pmt))); // high-rate veto
155 JBit(pmt).set(fifo, getFIFOStatus (JPMTIdentifier(id,pmt))); // FIFO (almost) full
156 }
157
158 return JDAQFrameStatus(daq, status, fifo);
159 }
160
161
162 /**
163 * Process data.
164 *
165 * \param id module identifier
166 * \param input PMT data
167 * \param output CLB data
168 */
169 virtual void processData(const JModuleIdentifier& id, const JCLBInput& input, JDAQSuperFrame& output) const override
170 {
171 using namespace std;
172 using namespace JPP;
173 using namespace KM3NETDAQ;
174
175
176 const double Tmin = 0.0; // Minimal TDC value [ns]
177 const double Tmax = getFrameTime(); // Maximal TDC value [ns]
178
180
181 vector<JDAQHit> buffer;
182
183 size_t ns = 0; // current number of hits in data frame
184
185 for (size_t pmt = 0; pmt != input.size(); ++pmt) {
186
187 const JPMTData<JPMTPulse>& in = input[pmt];
188
189 // TDC
190
191 for (JPMTData<JPMTPulse>::const_iterator hit = in.begin(); hit != in.end(); ++hit) {
192
193 if (hit->t_ns >= Tmin && hit->t_ns <= Tmax) {
194
195 double t1 = hit->t_ns;
196 double tot = hit->tot_ns;
197
198 // generate multiple hits if time-over-threshold exceeds dynamic range
199
200 while (tot > JDAQHit::getMaximalToT()) {
201
202 buffer.push_back(TDC->makeHit((JPMT_t) pmt, t1, (JTOT_t) JDAQHit::getMaximalToT()));
203
205 tot -= JDAQHit::getMaximalToT();
206 }
207
208 if (tot > getMinimalToT()) {
209 buffer.push_back(TDC->makeHit((JPMT_t) pmt, t1, (JTOT_t) (tot + 0.5)));
210 }
211 }
212 }
213
214 if (buffer.size() > ns + getMaximalNumberOfHits()) {
215
216 if (setHighRateVeto()) {
217 output.setHighRateVeto(pmt, true);
218 }
219
220 if (output.testHighRateVeto(pmt)) {
221 buffer.resize(ns + getMaximalNumberOfHits());
222 }
223 }
224
225 inplace_merge(buffer.begin(), buffer.begin() + ns, buffer.end());
226
227 ns = buffer.size();
228 }
229
230
231 // simulate UDP packet loss
232
233 const int n1 = getUDPNumberOfReceivedPackets(id);
234 const int n2 = getUDPMaximalSequenceNumber (id);
235
236 if (n1 < n2 + 1) {
237
238 const int ns = getBayesianMedian(n2, n1, 0);
239
240 JTDC_t t0 = (JTDC_t) Tmin;
241 JTDC_t ts = (JTDC_t) ((Tmax - Tmin) / ns);
242
243 for (int i = 0; i != ns; ++i, t0 += ts) {
244
245 if (gRandom->Rndm() * ns >= (double) n1) {
246
247 std::vector<JDAQHit>::iterator p = lower_bound(buffer.begin(), buffer.end(), t0, compare);
248 std::vector<JDAQHit>::iterator q = lower_bound(buffer.begin(), buffer.end(), t0 + ts, compare);
249
250 buffer.erase(p,q);
251 }
252 }
253 }
254
255
256 // process data through state machine
257
258 if (buffer.size() > 1) {
259
260 for (std::vector<JDAQHit>::iterator q = buffer.begin(), p = q++; q != buffer.end(); ++p, ++q) {
261
262 if (state_machine->maybeSwapped(*p,*q)) {
263 iter_swap(p,q);
264 }
265 }
266 }
267
268
269 // store data
270
271 output.add(buffer.size(), buffer.data());
272 }
273
274
275 /**
276 * Get number of received UDP packets.
277 *
278 * \param id module identifier
279 * \return 2
280 */
282 {
283 return 2;
284 }
285
286
287 /**
288 * Get maximal sequence number of UDP packet.
289 *
290 * \param id module identifier
291 * \return 1
292 */
294 {
295 return 1;
296 }
297
298
299 /**
300 * Get UDP trailer status.
301 *
302 * \param id module identifier
303 * \return true
304 */
305 virtual bool hasUDPTrailer(const JModuleIdentifier& id) const
306 {
307 return true;
308 }
309
310
311 /**
312 * Set high-rate veto based on number of hits.
313 *
314 * \return true
315 */
316 virtual bool setHighRateVeto() const
317 {
318 return true;
319 }
320
321
322 /**
323 * Get high-rate veto of given PMT.
324 *
325 * \param id PMT identifier
326 * \return false
327 */
328 virtual bool getHighRateVeto(const JPMTIdentifier& id) const
329 {
330 return false;
331 }
332
333
334 /**
335 * Get FIFO (almost) full of given PMT.
336 *
337 * \param id PMT identifier
338 * \return false
339 */
340 virtual bool getFIFOStatus(const JPMTIdentifier& id) const
341 {
342 return false;
343 }
344
345
346 /**
347 * Get minimal pulse length of time-over-threshold measurement.
348 *
349 * \return TDC value [ns]
350 */
351 static double getMinimalToT()
352 {
353 return 0.5;
354 }
355
356
357 /**
358 * Auxiliary data structure for sorting of hits.
359 */
360 static const struct compare {
361 /**
362 * Compare hits by time.
363 *
364 * \param first first hit
365 * \param second second hit
366 * \return true if first earlier than second; else false
367 */
368 bool operator()(const JDAQHit& first, const JDAQHit& second) const
369 {
370 return first.getT() < second.getT();
371 }
372
373
374 /**
375 * Compare hit and TDC value.
376 *
377 * \param hit hit
378 * \param tdc TDC
379 * \return true if hit earlier than given TDC value; else false
380 */
381 bool operator()(const JDAQHit& hit, const JTDC_t tdc) const
382 {
383 return hit.getT() < tdc;
384 }
386
387
388 private:
389 std::unique_ptr<JTDC> TDC;
390 std::unique_ptr<JStateMachine> state_machine;
391 };
392}
393
394#endif
KM3NeT DAQ constants, bit handling, etc.
Auxiliary methods for mathematics.
Interface to mimic hit ordering effects due to state machine inside CLB.
virtual bool maybeSwapped(const JDAQHit &first, const JDAQHit &second) const
Test whether two consecutive hits may be swapped.
virtual JDAQHit makeHit(const JPMT_t pmt, const double t_ns, const JTOT_t tot_ns) const
Make DAQ hit.
virtual bool getFIFOStatus(const JPMTIdentifier &id) const
Get FIFO (almost) full of given PMT.
static const struct JDETECTOR::JCLBDefaultSimulatorInterface::compare compare
static double getMinimalToT()
Get minimal pulse length of time-over-threshold measurement.
JDAQFrameStatus getDAQFrameStatus(const JModuleIdentifier &id) const
Get DAQ frame status of given module.
virtual bool hasUDPTrailer(const JModuleIdentifier &id) const
Get UDP trailer status.
virtual int getUDPMaximalSequenceNumber(const JModuleIdentifier &id) const
Get maximal sequence number of UDP packet.
virtual int getUDPNumberOfReceivedPackets(const JModuleIdentifier &id) const
Get number of received UDP packets.
JCLBDefaultSimulatorInterface(JTDC *TDC, JStateMachine *state_machine)
Constructor.
virtual bool setHighRateVeto() const
Set high-rate veto based on number of hits.
virtual bool getHighRateVeto(const JPMTIdentifier &id) const
Get high-rate veto of given PMT.
virtual void processData(const JModuleIdentifier &id, const JCLBInput &input, JDAQSuperFrame &output) const override
Process data.
Interface for CLB simulation.
std::vector< JElement_t >::const_iterator const_iterator
Auxiliary class for object identification.
Definition JObjectID.hh:25
Template definition of a multi-dimensional oscillation probability interpolation table.
JWriter & write(JWriter &out) const override final
Write from input.
void setHighRateVeto(const int tdc, const bool value)
Set high-rate veto.
bool testHighRateVeto() const
Test high-rate veto status.
void setDAQFrameStatus(const JDAQFrameStatus &status)
Set DAQ frame status.
Hit data structure.
Definition JDAQHit.hh:35
static JTOT_t getMaximalToT()
Get maximal time-over-threshold.
Definition JDAQHit.hh:108
JTDC_t getT() const
Get time.
Definition JDAQHit.hh:86
Data frame of one optical module.
JDAQSuperFrame & add(const JDAQSuperFrame &super_frame)
Add data from same optical module.
file Auxiliary data structures and methods for detector calibration.
Definition JAnchor.hh:12
size_t getBayesianMedian(const size_t m, const size_t k)
Get estimate of maximum number.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
void inplace_merge(T __begin, const size_t N, const size_t *delimiter)
Merge multiple sorted ranges.
Definition JMergeSort.cc:29
KM3NeT DAQ data structures and auxiliaries.
Definition DataQueue.cc:39
size_t getMaximalNumberOfHits()
Get maximal number of hits from one PMT within data frame.
double getFrameTime()
Get frame time duration.
Definition JDAQClock.hh:162
static const JBits DAQ_UDP_RECEIVED_PACKETS(0, 15)
Mask of UDP received packets.
static const JBits DAQ_UDP_SEQUENCE_NUMBER(16, 31)
Mask of UDP sequence number.
static const int NUMBER_OF_PMTS
Total number of PMTs in module.
Definition JDAQ.hh:26
static const JBit DAQ_WHITE_RABBIT(31)
White Rabbit status.
static const JBit DAQ_UDP_TRAILER(31)
UDP trailer.
bool operator()(const JDAQHit &first, const JDAQHit &second) const
Compare hits by time.
bool operator()(const JDAQHit &hit, const JTDC_t tdc) const
Compare hit and TDC value.
Auxiliary data structure for single bit.
Definition JDAQ.hh:36
void set(int &mask) const
Set bit in given bit mask.
Definition JDAQ.hh:77