Jpp 20.0.0-72-g597b30bc9
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() && !M2.empty()) {
89
90 if (neighbours(M1, M2)) {
91
92 buffer[m1].resize(M1.size());
93 buffer[m2].resize(M2.size());
94
95 simbad.generateHits({M1,M2}, period, {buffer[m1],buffer[m2]});
96 }
97 }
98 }
99 }
100
101
102 // store data
103
104 for (size_t i = 0; i != simbad->size(); ++i) {
105
106 if (!(*simbad)[i].empty()) {
107
108 this->push_back(JDAQSuperFrame(JDAQSuperFrameHeader(chronometer, (*simbad)[i].getID())));
109
110 simbad((*simbad)[i], buffer[i], this->back());
111 }
112 }
113 }
114 }
115
116
117 /**
118 * Recycle time slice by randomly shuffling time intervals of data.
119 *
120 * Hits within one time interval are swapped with hits within another -randomly selected- time interval.\n
121 * Time intervals in which a high-rate veto occurred are excluded.
122 *
123 * Note that the time interval should be:
124 * - (much) larger than time differences of hits in L1 coincidence; and
125 * - (much) smaller than time covered by data (as per KM3NETDAQ::getFrameTime()).
126 *
127 * \param T_ns time interval
128 */
129 void recycle(const double T_ns)
130 {
131 using namespace std;
132 using namespace JPP;
133
135 typedef JDAQHit::JTDC_t JTDC_t;
136
137 size_t N = (size_t) (getFrameTime() / T_ns + 0.5); // number of time intervals
138
139 if (N < 100) { N = 100; } // allow to keep indices at time of high-rate veto
140 if (N > 50000) { N = 50000; } // maximum expected number of hits due to high-rate veto
141
142 const JTDC_t Ts = (JTDC_t) (getFrameTime() / N); // TDC interval
143
144 random_indices_t index (N); // indices of time intervals for swapping
145 vector<buffer_type> buffer(N); // data per time interval
146
147 for (iterator frame = this->begin(); frame != this->end(); ++frame) {
148
149 if (!frame->empty()) {
150
151 for (size_t i = 0; i != N; ++i) {
152 buffer[i].clear();
153 }
154
155 // store data per time interval
156
157 vector<JTDC_t> T_max(NUMBER_OF_PMTS,
158 numeric_limits<JTDC_t>::max()); // maximal time per PMT, e.g. due to high-rate veto
159
160 for (JDAQSuperFrame::const_iterator hit = frame->begin(); hit != frame->end(); ++hit) {
161
162 T_max[hit->getPMT()] = hit->getT();
163
164 const int i = hit->getT() / Ts;
165
166 buffer[i].push_back(*hit);
167 }
168
169 set<size_t> keep; // indices corresponding to times of high-rate veto
170
171 for (int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
172 if (frame->testHighRateVeto(pmt)) {
173 keep.insert(T_max[pmt] / Ts);
174 }
175 }
176
177 index.random_shuffle(keep); // randomly shuffle values between kept indices
178
179 // Wall street shuflle
180
181 JDAQSuperFrame::iterator hit = frame->begin();
182
183 for (size_t in = 0; in != N; ++in) {
184
185 const size_t out = index [in];
186 buffer_type& zbuf = buffer[out];
187
188 const JTDC_t T_in = in * Ts;
189 const JTDC_t T_out = out * Ts;
190
191 for (buffer_type::iterator i = zbuf.begin(); i != zbuf.end(); ++i, ++hit) {
192 *hit = JDAQHit(i->getPMT(), (i->getT() - T_out) + T_in, i->getToT());
193 }
194 }
195 }
196 }
197 }
198
199
200 /**
201 * Auxiliary data structure for randomisation of indices.
202 */
204 public std::vector<size_t>
205 {
206 /**
207 * Constructor.
208 *
209 * \param N number of indices
210 */
211 random_indices_t(const size_t N) :
212 std::vector<size_t>(N)
213 {}
214
215 /**
216 * Randomly shuffle values between fixed indices.
217 *
218 * \param keep fixed indices
219 */
220 inline void random_shuffle(const std::set<size_t>& keep)
221 {
222 for (size_t i = 0; i != this->size(); ++i) {
223 (*this)[i] = i;
224 }
225
226 size_t i1 = 0;
227
228 for (const size_t i2 : keep) {
229
230 random_shuffle(i1, i2);
231
232 i1 = i2 + 1;
233 }
234
235 random_shuffle(i1, this->size());
236 }
237
238 private:
239 /**
240 * Randomly shuffle values between given indices.
241 *
242 * \param i1 first index (included)
243 * \param i2 last index (excluded)
244 */
245 inline void random_shuffle(const int i1, const int i2)
246 {
247 for (int i = i2 - 1; i > i1; --i) {
248
249 const int l = i1 + gRandom->Integer(i - i1);
250
251 std::swap((*this)[i], (*this)[l]);
252 }
253 }
254 };
255 };
256}
257
258#endif
259
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:50
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:70
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.