Jpp 19.3.0-rc.3
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
7#include "TRandom3.h"
8
14
16#include "JDAQ/JHighRateVeto.hh"
20
21
22/**
23 * \author mdejong
24 */
25
26namespace JDETECTOR {}
27namespace JPP { using namespace JDETECTOR; }
28
29namespace JDETECTOR {
30
33
34
35 /**
36 * Default CLB simulation.
37 *
38 * This class provides for a default implementation of the JCLBSimulator interface
39 * which is based on a simulation of the TDC and the state machine inside the CLB.
40 * The actual number of hits may change due to the high-rate veto and UDP packet loss
41 * (loss of hits) and the dynamic range of the time-over-threshold (gain of hits).
42 *
43 * The nested class JStateMachine constitutes a user interface for the simulation
44 * of the state machine through method JStateMachine::maybeSwapped().
45 * With the default implementation, the overall time ordering if hits is maintained.
46 * For a realistic simulation of the CLB, a pointer to a designated implementation
47 * of this interface should be provided.
48 *
49 * The implementation of the virtual method JCLBDefaultSimulatorInterface::processData
50 * provides for the settings of the status of the data frame.\n
51 * In this, the high-rate veto is set when:
52 * - virtual method JCLBDefaultSimulatorInterface::getHighRateVeto returns true for the given PMT; or
53 * - number of hits from the PMT exceeds KM3NETDAQ::getMaximalNumberOfHits.
54 */
56 public JCLBSimulator
57 {
58 public:
59
63
64
65 /**
66 * Interface for TDC.
67 */
68 class JTDC {
69 public:
70 /**
71 * Virtual destructor.
72 */
73 virtual ~JTDC()
74 {}
75
76
77 /**
78 * Make DAQ hit.
79 *
80 * \param pmt PMT channel
81 * \param t_ns time of hit [ns]
82 * \param tot_ns time over threshold [ns]
83 * \return DAQ hit
84 */
85 virtual JDAQHit makeHit(const JPMT_t pmt,
86 const double t_ns,
87 const JTOT_t tot_ns) const
88 {
89 return JDAQHit(pmt, (JTDC_t) t_ns, tot_ns);
90 }
91 };
92
93
94 /**
95 * Interface to mimic hit ordering effects due to state machine inside CLB.
96 */
98 public:
99 /**
100 * Virtual destructor.
101 */
103 {}
104
105
106 /**
107 * Test whether two consecutive hits may be swapped.
108 *
109 * \param first first DAQ hit
110 * \param second second DAQ hit
111 * \return true if first and second hit may be swapped; else false
112 */
113 virtual bool maybeSwapped(const JDAQHit& first, const JDAQHit& second) const
114 {
115 return false;
116 }
117 };
118
119
120 /**
121 * Constructor.
122 *
123 * This class owns the objects pointed to.
124 *
125 * \param TDC pointer to TDC simulator
126 * \param state_machine pointer to state machine
127 */
133
134
135
136 /**
137 * Get DAQ frame status of given module.
138 *
139 * \param id module identifier
140 * \return DAQ frame status
141 */
143 {
144 using namespace KM3NETDAQ;
145
148 int status = DAQ_WHITE_RABBIT.write(1); // TDC status
149 int fifo = DAQ_UDP_TRAILER .write(hasUDPTrailer(id) ? 1 : 0); // FIFO status
150
151 for (size_t pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
152 JBit(pmt).set(status, getHighRateVeto(JPMTIdentifier(id,pmt)) ? 1 : 0) ; // high-rate veto
153 }
154
155 return JDAQFrameStatus(daq, status, fifo);
156 }
157
158
159 /**
160 * Process data.
161 *
162 * \param id module identifier
163 * \param input PMT data
164 * \param output CLB data
165 */
166 virtual void processData(const JModuleIdentifier& id, const JCLBInput& input, JDAQSuperFrame& output) const override
167 {
168 using namespace std;
169 using namespace KM3NETDAQ;
170
171
172 const double Tmin = 0.0; // Minimal TDC value [ns]
173 const double Tmax = getFrameTime(); // Maximal TDC value [ns]
174
176
177 buffer.clear();
178
179 size_t ns = 0; // current number of hits in data frame
180
181 for (size_t pmt = 0; pmt != input.size(); ++pmt) {
182
183 const JPMTData<JPMTPulse>& in = input[pmt];
184
185 // TDC
186
187 for (JPMTData<JPMTPulse>::const_iterator hit = in.begin(); hit != in.end(); ++hit) {
188
189 if (hit->t_ns >= Tmin && hit->t_ns <= Tmax) {
190
191 double t1 = hit->t_ns;
192 double tot = hit->tot_ns;
193
194 // generate multiple hits if time-over-threshold exceeds dynamic range
195
196 while (tot > JDAQHit::getMaximalToT()) {
197
198 buffer.push_back(TDC->makeHit((JPMT_t) pmt, t1, (JTOT_t) JDAQHit::getMaximalToT()));
199
201 tot -= JDAQHit::getMaximalToT();
202 }
203
204 if (tot > getMinimalToT()) {
205 buffer.push_back(TDC->makeHit((JPMT_t) pmt, t1, (JTOT_t) (tot + 0.5)));
206 }
207 }
208 }
209
210 if (buffer.size() > ns + getMaximalNumberOfHits()) {
211
212 output.setHighRateVeto(pmt, true);
213
214 buffer.resize(ns + getMaximalNumberOfHits());
215 }
216
217 inplace_merge(buffer.begin(), buffer.begin() + ns, buffer.end());
218
219 ns = buffer.size();
220 }
221
222
223 // simulate UDP packet loss
224
225 const int n1 = getUDPNumberOfReceivedPackets(id);
226 const int n2 = getUDPMaximalSequenceNumber (id);
227
228 if (n1 < n2 + 1) {
229
230 JTDC_t t0 = (JTDC_t) Tmin;
231 JTDC_t ts = (JTDC_t) ((Tmax - Tmin) / (n2 + 1));
232
233 for (int i = 0; i != n2 + 1; ++i, t0 += ts) {
234
235 if (gRandom->Rndm() * (n2 + 1) >= (double) n1) {
236
237 std::vector<JDAQHit>::iterator p = lower_bound(buffer.begin(), buffer.end(), t0, compare);
238 std::vector<JDAQHit>::iterator q = lower_bound(buffer.begin(), buffer.end(), t0 + ts, compare);
239
240 buffer.erase(p,q);
241 }
242 }
243 }
244
245
246 // process data through state machine
247
248 if (buffer.size() > 1) {
249
250 for (std::vector<JDAQHit>::iterator q = buffer.begin(), p = q++; q != buffer.end(); ++p, ++q) {
251
252 if (state_machine->maybeSwapped(*p,*q)) {
253 iter_swap(p,q);
254 }
255 }
256 }
257
258
259 // store data
260
261 output.add(buffer.size(), buffer.data());
262 }
263
264
265 /**
266 * Get number of received UDP packets.
267 *
268 * \param id module identifier
269 * \return 2
270 */
272 {
273 return 2;
274 }
275
276
277 /**
278 * Get maximal sequence number of UDP packet.
279 *
280 * \param id module identifier
281 * \return 1
282 */
284 {
285 return 1;
286 }
287
288
289 /**
290 * Get UDP trailer status.
291 *
292 * \param id module identifier
293 * \return true
294 */
295 virtual bool hasUDPTrailer(const JModuleIdentifier& id) const
296 {
297 return true;
298 }
299
300
301 /**
302 * Get high-rate veto of given PMT.
303 *
304 * \param id PMT identifier
305 * \return false
306 */
307 virtual bool getHighRateVeto(const JPMTIdentifier& id) const
308 {
309 return false;
310 }
311
312
313 /**
314 * Get minimal pulse length of time-over-threshold measurement.
315 *
316 * \return TDC value [ns]
317 */
318 static double getMinimalToT()
319 {
320 return 0.5;
321 }
322
323
324 /**
325 * Auxiliary data structure for sorting of hits.
326 */
327 static const struct compare {
328 /**
329 * Compare hits by time.
330 *
331 * \param first first hit
332 * \param second second hit
333 * \return true if first earlier than second; else false
334 */
335 bool operator()(const JDAQHit& first, const JDAQHit& second) const
336 {
337 return first.getT() < second.getT();
338 }
339
340
341 /**
342 * Compare hit and TDC value.
343 *
344 * \param hit hit
345 * \param tdc TDC
346 * \return true if hit earlier than given TDC value; else false
347 */
348 bool operator()(const JDAQHit& hit, const JTDC_t tdc) const
349 {
350 return hit.getT() < tdc;
351 }
353
354
355 private:
359 };
360}
361
362#endif
KM3NeT DAQ constants, bit handling, etc.
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.
static const struct JDETECTOR::JCLBDefaultSimulatorInterface::compare compare
JLANG::JSinglePointer< JStateMachine > state_machine
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 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.
Template data structure for PMT I/O.
std::vector< JElement_t >::const_iterator const_iterator
Auxiliary class for object identification.
Definition JObjectID.hh:25
The template JSinglePointer class can be used to hold a pointer to an object.
void setHighRateVeto(const int tdc, const bool value)
Set high-rate veto.
void setDAQFrameStatus(const JDAQFrameStatus &status)
Set DAQ frame status.
Hit data structure.
Definition JDAQHit.hh:35
unsigned int JTDC_t
leading edge [ns]
Definition JDAQHit.hh:39
unsigned char JTOT_t
time over threshold [ns]
Definition JDAQHit.hh:40
static JTOT_t getMaximalToT()
Get maximal time-over-threshold.
Definition JDAQHit.hh:108
JTDC_t getT() const
Get time.
Definition JDAQHit.hh:86
unsigned char JPMT_t
PMT channel in FPGA.
Definition JDAQHit.hh:38
Data frame of one optical module.
JDAQSuperFrame & add(const JDAQSuperFrame &super_frame)
Add data from same optical module.
bool write(const Vec &v, std::ostream &os)
Write a Vec(tor) to a stream.
Definition io_ascii.hh:155
file Auxiliary data structures and methods for detector calibration.
Definition JAnchor.hh:12
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.
Wrapper for CLB input.
Auxiliary data structure for single bit.
Definition JDAQ.hh:36
int write(const int value) const
Write given value as bit mask.
Definition JDAQ.hh:115
void set(int &mask) const
Set bit in given bit mask.
Definition JDAQ.hh:77
int write(const int value) const
Write given value as bit mask.
Definition JDAQ.hh:238