Jpp 21.0.0-rc.3
the software that should make you happy
Loading...
Searching...
No Matches
JRandomTimeslice.hh
Go to the documentation of this file.
1#ifndef __JTIMESLICE__JRANDOMTIMESLICE__
2#define __JTIMESLICE__JRANDOMTIMESLICE__
3
4#include <vector>
5#include <set>
6
7#include <TRandom3.h>
8
17
18
19/**
20 * \author mdejong
21 */
22
23namespace KM3NETDAQ {
24
26
27
28 /**
29 * Timeslice with random data.
30 */
32 public JTimesliceL0
33 {
34 /**
35 * Default constructor.
36 */
39
40
41 /**
42 * Constructor.
43 *
44 * \param chronometer chronometer
45 * \param simbad detector simulator
46 */
48 const JDetectorSimulator& simbad)
49 {
50 using namespace JPP;
51
52 setDAQChronometer(chronometer);
53
54 if (simbad.hasK40Simulator() &&
55 simbad.hasPMTSimulator() &&
56 simbad.hasCLBSimulator()) {
57
58 const double Tmin = getTimeSinceRTS(chronometer.getFrameIndex()); // [ns]
59
60 const JTimeRange period(Tmin, Tmin + getFrameTime()); // [ns]
61
62 // generate hits per module
63
64 vector<JModuleData> buffer(simbad->size());
65
66 for (size_t i = 0; i != simbad->size(); ++i) {
67
68 const JModule& module = (*simbad)[i];
69
70 if (!module.empty() && simbad.getCLBSimulator().hasCLB(module.getID())) {
71
72 buffer[i].resize(module.size());
73
74 simbad.generateHits(module, period, buffer[i]);
75 }
76 }
77
78
79 // generate mixed L0/L1 hits per unique module pair
80
81 for (size_t m1 = 0; m1 != simbad->size(); ++m1) {
82
83 for (size_t m2 = 0; m2 != m1; ++m2) {
84
85 const JModule& M1 = (*simbad)[m1];
86 const JModule& M2 = (*simbad)[m2];
87
88 if (!M1.empty() && simbad.getCLBSimulator().hasCLB(M1.getID()) &&
89 !M2.empty() && simbad.getCLBSimulator().hasCLB(M2.getID())) {
90
91 if (neighbours(M1, M2)) {
92
93 buffer[m1].resize(M1.size());
94 buffer[m2].resize(M2.size());
95
96 simbad.generateHits({M1,M2}, period, {buffer[m1],buffer[m2]});
97 }
98 }
99 }
100 }
101
102
103 // store data
104
105 for (size_t i = 0; i != simbad->size(); ++i) {
106
107 if (!(*simbad)[i].empty()) {
108
109 this->push_back(JDAQSuperFrame(JDAQSuperFrameHeader(chronometer, (*simbad)[i].getID())));
110
111 simbad((*simbad)[i], buffer[i], this->back());
112 }
113 }
114 }
115 }
116
117
118 /**
119 * Recycle time slice by randomly shuffling time intervals of data.
120 *
121 * Hits within one time interval are swapped with hits within another -randomly selected- time interval.\n
122 * Time intervals in which a high-rate veto occurred are excluded.
123 *
124 * Note that the time interval should be:
125 * - (much) larger than time differences of hits in L1 coincidence; and
126 * - (much) smaller than time covered by data (as per KM3NETDAQ::getFrameTime()).
127 *
128 * \param T_ns time interval
129 */
130 void recycle(const double T_ns)
131 {
132 using namespace std;
133 using namespace JPP;
134
136 typedef JDAQHit::JTDC_t JTDC_t;
137
138 size_t N = (size_t) (getFrameTime() / T_ns + 0.5); // number of time intervals
139
140 if (N < 100) { N = 100; } // allow to keep indices at time of high-rate veto
141 if (N > 50000) { N = 50000; } // maximum expected number of hits due to high-rate veto
142
143 const JTDC_t Ts = (JTDC_t) (getFrameTime() / N); // TDC interval
144
145 random_indices_t index (N); // indices of time intervals for swapping
146 vector<buffer_type> buffer(N); // data per time interval
147
148 for (iterator frame = this->begin(); frame != this->end(); ++frame) {
149
150 if (!frame->empty()) {
151
152 for (size_t i = 0; i != buffer.size(); ++i) {
153 buffer[i].clear();
154 }
155
156 // store data per time interval
157
158 vector<JTDC_t> T_max(NUMBER_OF_PMTS,
159 numeric_limits<JTDC_t>::max()); // maximal time per PMT, e.g. due to high-rate veto
160
161 for (JDAQSuperFrame::const_iterator hit = frame->begin(); hit != frame->end(); ++hit) {
162
163 T_max[hit->getPMT()] = hit->getT();
164
165 size_t i = hit->getT() / Ts;
166
167 if (i >= N) { i = N-1; }
168
169 buffer[i].push_back(*hit);
170 }
171
172 set<size_t> keep; // indices corresponding to times of high-rate veto
173
174 for (int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
175
176 if (frame->testHighRateVeto(pmt)) {
177
178 size_t i = T_max[pmt] / Ts;
179
180 if (i >= N) { i = N-1; }
181
182 keep.insert(i);
183 }
184 }
185
186 index.random_shuffle(keep); // randomly shuffle values between kept indices
187
188 // Wall street shuflle
189
190 JDAQSuperFrame::iterator hit = frame->begin();
191
192 for (size_t in = 0; in != N; ++in) {
193
194 const size_t out = index [in];
195 buffer_type& zbuf = buffer[out];
196
197 const JTDC_t T_in = in * Ts;
198 const JTDC_t T_out = out * Ts;
199
200 for (buffer_type::iterator i = zbuf.begin(); i != zbuf.end(); ++i, ++hit) {
201 *hit = JDAQHit(i->getPMT(), (i->getT() - T_out) + T_in, i->getToT());
202 }
203 }
204 }
205 }
206 }
207
208
209 /**
210 * Auxiliary data structure for randomisation of indices.
211 */
213 public std::vector<size_t>
214 {
215 /**
216 * Constructor.
217 *
218 * \param N number of indices
219 */
220 random_indices_t(const size_t N) :
221 std::vector<size_t>(N)
222 {}
223
224 /**
225 * Randomly shuffle values between fixed indices.
226 *
227 * \param keep fixed indices
228 */
229 inline void random_shuffle(const std::set<size_t>& keep)
230 {
231 for (size_t i = 0; i != this->size(); ++i) {
232 (*this)[i] = i;
233 }
234
235 size_t i1 = 0;
236
237 for (const size_t i2 : keep) {
238
239 random_shuffle(i1, i2);
240
241 i1 = i2 + 1;
242 }
243
244 random_shuffle(i1, this->size());
245 }
246
247 private:
248 /**
249 * Randomly shuffle values between given indices.
250 *
251 * \param i1 first index (included)
252 * \param i2 last index (excluded)
253 */
254 inline void random_shuffle(const int i1, const int i2)
255 {
256 for (int i = i2 - 1; i > i1; --i) {
257
258 const int l = i1 + gRandom->Integer(i - i1);
259
260 std::swap((*this)[i], (*this)[l]);
261 }
262 }
263 };
264 };
265}
266
267#endif
268
KM3NeT DAQ constants, bit handling, etc.
Auxiliaries for creation of time slice data.
virtual bool hasCLB(const JModuleIdentifier &id) const
Check if CLB exist.
const JCLBSimulator & getCLBSimulator() const
Get CLB simulator.
virtual void generateHits(const JModule &module, const JTimeRange &period, JModuleData &output) const override
Generate hits.
bool hasPMTSimulator() const
Check availability of PMT simulator.
bool hasK40Simulator() const
Check availability of K40 simulator.
bool hasCLBSimulator() const
Check availability of CLB simulator.
Data structure for a composite optical module.
Definition JModule.hh:76
int getID() const
Get identifier.
Definition JObjectID.hh:63
void setDAQChronometer(const JDAQChronometer &chronometer)
Set DAQ chronometer.
int getFrameIndex() const
Get frame index.
Hit data structure.
Definition JDAQHit.hh:35
unsigned int JTDC_t
leading edge [ns]
Definition JDAQHit.hh:39
Data frame of one optical module.
bool neighbours(const JLocation &first, const JLocation &second)
Check if two locations are neighbours.
Definition JLocation.hh:263
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
std::vector< JHitW0 > buffer_type
hits
Definition JPerth.cc:74
KM3NeT DAQ data structures and auxiliaries.
Definition DataQueue.cc:39
double getFrameTime()
Get frame time duration.
Definition JDAQClock.hh:162
double getTimeSinceRTS(const int frame_index)
Get time in ns since last RTS for a given frame index.
Definition JDAQClock.hh:263
static const int NUMBER_OF_PMTS
Total number of PMTs in module.
Definition JDAQ.hh:26
Auxiliary class for TDC constraints.
Definition JTDC_t.hh:39
Auxiliary data structure for randomisation of indices.
void random_shuffle(const int i1, const int i2)
Randomly shuffle values between given indices.
void random_shuffle(const std::set< size_t > &keep)
Randomly shuffle values between fixed indices.
Timeslice with random data.
JRandomTimeslice(const JDAQChronometer &chronometer, const JDetectorSimulator &simbad)
Constructor.
JRandomTimeslice()
Default constructor.
void recycle(const double T_ns)
Recycle time slice by randomly shuffling time intervals of data.
Base class class for generation of time slice data.