4 #ifndef artdaq_dune_Overlays_FelixDecode_hh 5 #define artdaq_dune_Overlays_FelixDecode_hh 17 #include "artdaq-core/Data/ContainerFragment.hh" 18 #include "artdaq-core/Data/Fragment.hh" 30 std::vector<artdaq::Fragment>
frags_;
32 std::vector<unsigned>
Uch = {3, 4, 5, 6, 7, 24, 25, 26, 27, 28};
33 std::vector<unsigned>
Vch = {0, 1, 2, 8, 9, 22, 23, 29, 30, 31};
34 std::vector<unsigned>
Wch = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
77 uint64_t prevtimestamp = flxfrag.
timestamp(0);
78 for (
unsigned fr = 1; fr < flxfrag.
total_frames(); ++fr) {
80 if (flxfrag.
timestamp(fr) - prevtimestamp != 25) {
81 std::cout <<
"Timestamp does not increase by 25 at frame " << fr
82 <<
" in fragment " << frag_num <<
"!\n";
83 std::cout <<
"It instead increases by " 84 << flxfrag.
timestamp(fr) - prevtimestamp <<
"\n";
85 std::cout <<
"Fiber " << (unsigned)flxfrag.
fiber_no(fr) <<
", slot " 86 << (unsigned)flxfrag.
slot_no(fr) <<
", crate " 87 << (unsigned)flxfrag.
crate_no(fr) <<
'\n';
101 std::cout <<
"Going through " << frags_.size() <<
" fragments.\n";
102 for (
unsigned i = 0; i < frags_.size(); ++i) {
103 std::cout << i <<
'\r';
108 std::cout <<
"Timestamp check failed.\n";
110 std::cout <<
"Timestamp check succeeded.\n";
124 for (
unsigned fr = 1; fr < flxfrag.
total_frames(); ++fr) {
129 std::cout <<
"CCC1 does not increase by 1 at frame " << fr
130 <<
" in fragment " << frag_num <<
"!\n";
131 std::cout <<
"It instead increases by " 140 std::cout <<
"CCC2 does not increase by 1 at frame " << fr
141 <<
" in fragment " << frag_num <<
"!\n";
142 std::cout <<
"It instead increases by " 156 std::cout <<
"CCC in frame " << fr <<
" do not correspond!\n";
167 for (
unsigned i = 0; i < frags_.size(); ++i) {
172 std::cout <<
"CCC check failed.\n";
174 std::cout <<
"CCC check succeeded.\n";
185 unsigned fiber_no = flxfrag.
fiber_no();
186 unsigned crate_no = flxfrag.
crate_no();
187 unsigned slot_no = flxfrag.
slot_no();
194 for (
unsigned fi = 1; fi < flxfrag.
total_frames(); ++fi) {
196 if (flxfrag.
fiber_no(fi) != fiber_no) {
197 std::cout <<
"Non-constant fiber_no in fragment " << frag_num
198 <<
" frame " << fi <<
": " << (unsigned)(flxfrag.
fiber_no(fi))
199 <<
" instead of " << fiber_no <<
'\n';
205 if (flxfrag.
crate_no(fi) != crate_no) {
206 std::cout <<
"Non-constant crate_no in fragment " << frag_num
207 <<
" frame " << fi <<
": " << (unsigned)(flxfrag.
crate_no(fi))
208 <<
" instead of " << crate_no <<
'\n';
214 if (flxfrag.
slot_no(fi) != slot_no) {
215 std::cout <<
"Non-constant slot_no in fragment " << frag_num
216 <<
" frame " << fi <<
": " << (unsigned)(flxfrag.
slot_no(fi))
217 <<
" instead of " << slot_no <<
'\n';
229 for (
unsigned i = 0; i < frags_.size(); ++i) {
234 std::cout <<
"ID check failed.\n";
236 std::cout <<
"ID check succeeded.\n";
243 artdaq::Fragment
Fragment(
const size_t& frag_num)
const {
245 std::cout <<
"Fragment index out of range.\n";
246 artdaq::Fragment emptyfrag;
249 return frags_[frag_num];
256 typedef std::complex<double>
Complex;
260 for (
unsigned i = 0; i < 16; ++i) {
261 if (N << 1 <
x.size()) {
269 unsigned int k =
N,
n;
270 double thetaT = 3.14159265358979323846264338328L /
N;
271 Complex phiT =
Complex(cos(thetaT), -sin(thetaT)),
T;
277 for (
unsigned int l = 0;
l <
k;
l++) {
278 for (
unsigned int a =
l;
a <
N;
a +=
n) {
279 unsigned int b =
a +
k;
280 Complex
t =
x[
a] -
x[
b];
288 unsigned int m = (
unsigned int)log2(N);
289 for (
unsigned int a = 0;
a <
N;
a++) {
292 b = (((b & 0xaaaaaaaa) >> 1) | ((b & 0x55555555) << 1));
293 b = (((b & 0xcccccccc) >> 2) | ((b & 0x33333333) << 2));
294 b = (((b & 0xf0f0f0f0) >> 4) | ((b & 0x0f0f0f0f) << 4));
295 b = (((b & 0xff00ff00) >> 8) | ((b & 0x00ff00ff) << 8));
296 b = ((b >> 16) | (b << 16)) >> (32 - m);
313 std::cout <<
"Testing fragments for integrity.\n";
314 for (
unsigned frag_num = 0; frag_num <
num_frags_ana; ++frag_num) {
315 bool data_good =
true;
321 frag_good[frag_num] = data_good;
328 std::cout <<
"Calculating channel averages.\n";
329 for (
unsigned frag_num = 0; frag_num <
num_frags_ana; ++frag_num) {
330 if (!frag_good[frag_num]) {
335 artdaq::Fragment frag =
Fragment(frag_num);
337 unsigned ch_num_base =
340 for (
unsigned fr_num = 0; fr_num < flxfrag.
total_frames(); ++fr_num) {
341 for (
unsigned u = 0; u < Uch.size(); ++u) {
342 ch_avgsU[ch_num_base + Uch[u]] += flxfrag.
get_ADC(fr_num, Uch[u]);
343 ch_freqU[ch_num_base + Uch[u]]++;
345 for (
unsigned v = 0; v < Vch.size(); ++v) {
346 ch_avgsV[ch_num_base + Vch[v]] += flxfrag.
get_ADC(fr_num, Vch[v]);
347 ch_freqV[ch_num_base + Vch[v]]++;
349 for (
unsigned w = 0;
w < Wch.size(); ++
w) {
350 ch_avgsW[ch_num_base + Wch[
w]] += flxfrag.
get_ADC(fr_num, Wch[
w]);
351 ch_freqW[ch_num_base + Wch[
w]]++;
355 for (
unsigned ch_num = 0; ch_num < ch_avgsU.size(); ++ch_num) {
356 if (ch_freqU[ch_num] != 0) {
357 ch_avgsU[ch_num] /= ch_freqU[ch_num];
360 for (
unsigned ch_num = 0; ch_num < ch_avgsV.size(); ++ch_num) {
361 if (ch_freqV[ch_num] != 0) {
362 ch_avgsV[ch_num] /= ch_freqV[ch_num];
365 for (
unsigned ch_num = 0; ch_num < ch_avgsW.size(); ++ch_num) {
366 if (ch_freqW[ch_num] != 0) {
367 ch_avgsW[ch_num] /= ch_freqW[ch_num];
374 std::cout <<
"Calculating noise RMS values per channel.\n";
375 for (
unsigned frag_num = 0; frag_num <
num_frags_ana; ++frag_num) {
376 if (!frag_good[frag_num]) {
381 artdaq::Fragment frag =
Fragment(frag_num);
387 unsigned ch_num_base =
391 for (
unsigned u = 0; u < Uch.size(); ++u) {
392 for (
unsigned fr_num = 0; fr_num < flxfrag.
total_frames(); ++fr_num) {
393 ch_rmsU[ch_num_base + Uch[u]] +=
pow(
394 ch_avgsU[ch_num_base + Uch[u]] - flxfrag.
get_ADC(fr_num, Uch[u]),
398 for (
unsigned v = 0; v < Vch.size(); ++v) {
399 for (
unsigned fr_num = 0; fr_num < flxfrag.
total_frames(); ++fr_num) {
400 ch_rmsV[ch_num_base + Vch[v]] +=
pow(
401 ch_avgsV[ch_num_base + Vch[v]] - flxfrag.
get_ADC(fr_num, Vch[v]),
405 for (
unsigned w = 0;
w < Wch.size(); ++
w) {
406 for (
unsigned fr_num = 0; fr_num < flxfrag.
total_frames(); ++fr_num) {
407 ch_rmsW[ch_num_base + Wch[
w]] +=
pow(
408 ch_avgsW[ch_num_base + Wch[
w]] - flxfrag.
get_ADC(fr_num, Wch[
w]),
415 unsigned num_bad_channels = 0;
416 for (
unsigned ch = 0; ch < 2560; ++ch) {
417 ch_rmsU[ch] = sqrt(ch_rmsU[ch] / ch_freqU[ch]);
418 ch_rmsV[ch] = sqrt(ch_rmsV[ch] / ch_freqV[ch]);
419 ch_rmsW[ch] = sqrt(ch_rmsW[ch] / ch_freqW[ch]);
422 if (ch_rmsU[ch] > bad_channel_threshold_ ||
423 ch_rmsV[ch] > bad_channel_threshold_ ||
424 ch_rmsW[ch] > bad_channel_threshold_ || (ch_rmsU[ch]<bad_channel_threshold_lower_ && ch_rmsV[ch]<bad_channel_threshold_lower_ && ch_rmsW[ch]<bad_channel_threshold_lower_)) {
425 bad_channel_[ch] =
true;
429 std::cout <<
"Number of bad channels: " << num_bad_channels <<
".\n";
434 std::vector<unsigned> FEMB_freq(20, 0);
435 for (
unsigned frag_num = 0; frag_num <
num_frags_ana; ++frag_num) {
436 if (!frag_good[frag_num]) {
441 artdaq::Fragment frag =
Fragment(frag_num);
453 for (
unsigned frag_num = 0; frag_num <
num_frags_ana; ++frag_num) {
454 if (!frag_good[frag_num]) {
459 artdaq::Fragment frag =
Fragment(frag_num);
462 for (
unsigned ch_num = 0; ch_num < 256; ++ch_num) {
464 std::vector<std::complex<double>> ch_fft_waveform(
466 for (
unsigned fr_num = 0; fr_num < flxfrag.
total_frames(); ++fr_num) {
468 ch_fft_waveform[fr_num] = flxfrag.
get_ADC(fr_num, ch_num);
470 FFT(ch_fft_waveform);
472 unsigned FEMB_num = (flxfrag.
slot_no() - 0) * 4 +
473 (flxfrag.
fiber_no() - 1) * 2 + ch_num / 128;
474 if(bad_channel_[FEMB_num*128 + ch_num]) {
continue; }
479 for (
unsigned i = 0; i < ch_fft_waveform.size(); ++i) {
480 FEMB_FFT[FEMB_num][i] +=
481 std::abs(ch_fft_waveform[i])/(FEMB_freq[FEMB_num]*128);
490 std::cout <<
"calculateNoiseRMS: found " << frags_.size()
492 num_frags_ana = std::min<unsigned>(frags_.size(), 100);
495 ch_avgsU.resize(2 * 5 * 256, 0);
496 ch_avgsV.resize(2 * 5 * 256, 0);
497 ch_avgsW.resize(2 * 5 * 256, 0);
498 ch_rmsU.resize(2 * 5 * 256, 0);
499 ch_rmsV.resize(2 * 5 * 256, 0);
500 ch_rmsW.resize(2 * 5 * 256, 0);
501 ch_freqU.resize(2 * 5 * 256, 0);
502 ch_freqV.resize(2 * 5 * 256, 0);
503 ch_freqW.resize(2 * 5 * 256, 0);
504 frag_good.resize(num_frags_ana,
false);
505 FEMB_FFT.resize(20, std::vector<double>(
total_frames(), 0));
506 bad_channel_.resize(2 * 5 * 256, 0);
518 std::cout <<
"Writing to file " << destination +
"/RMSU.dat" 520 std::ofstream rmsfileU(destination +
"/RMSU.dat");
521 rmsfileU <<
"#WIB Fibre Channel Global Noise RMS U\n";
522 for (
unsigned ch_num = 0; ch_num < ch_rmsU.size(); ++ch_num) {
523 if (ch_freqU[ch_num] == 0) {
526 rmsfileU << ch_num / 512 + 1 <<
" " << (ch_num % 512) / 256 + 1
527 <<
" " << ch_num % 256 <<
" " << ch_num <<
" " 528 << ch_rmsU[ch_num] <<
'\n';
532 std::cout <<
"Writing to file " << destination +
"/RMSV.dat" 534 std::ofstream rmsfileV(destination +
"/RMSV.dat");
535 rmsfileV <<
"#WIB Fibre Channel Global Noise RMS V\n";
536 for (
unsigned ch_num = 0; ch_num < ch_rmsV.size(); ++ch_num) {
537 if (ch_freqV[ch_num] == 0) {
540 rmsfileV << ch_num / 512 + 1 <<
" " << (ch_num % 512) / 256 + 1
541 <<
" " << ch_num % 256 <<
" " << ch_num <<
" " 542 << ch_rmsV[ch_num] <<
'\n';
546 std::cout <<
"Writing to file " << destination +
"/RMSW.dat" 548 std::ofstream rmsfileW(destination +
"/RMSW.dat");
549 rmsfileW <<
"#WIB Fibre Channel Global Noise RMS W\n";
550 for (
unsigned ch_num = 0; ch_num < ch_rmsW.size(); ++ch_num) {
551 if (ch_freqW[ch_num] == 0) {
554 rmsfileW << ch_num / 512 + 1 <<
" " << (ch_num % 512) / 256 + 1
555 <<
" " << ch_num % 256 <<
" " << ch_num <<
" " 556 << ch_rmsW[ch_num] <<
'\n';
561 std::string fftfilename = destination +
"/FFT.dat";
562 std::cout <<
"Writing to file " << fftfilename <<
".\n";
563 std::ofstream fftfile(fftfilename);
565 fftfile <<
"#Slot -> ";
566 for (
unsigned f = 0;
f < 20; ++
f) {
569 fftfile <<
'\n' <<
"#Fiber -> ";
570 for (
unsigned f = 0;
f < 20; ++
f) {
573 fftfile <<
'\n' <<
"#FEMB -> ";
574 for (
unsigned f = 0;
f < 20; ++
f) {
577 fftfile <<
'\n' <<
"#Global ->";
578 for (
unsigned f = 0;
f < 20; ++
f) {
585 for (
unsigned femb = 0; femb < 20; ++femb) {
586 fftfile <<
std::setw(15) << log10(
pow(FEMB_FFT[femb][0], 2));
594 for (
unsigned femb = 0; femb < 20; ++femb) {
604 void printFrames(
const size_t& begin_frame = 0,
const size_t& end_frame = 1,
605 const size_t& frag_num = 0)
const {
606 artdaq::Fragment frag(
Fragment(frag_num));
608 for (
unsigned i = begin_frame; i < end_frame; ++i) {
609 std::cout <<
"Frame " << i <<
'\n';
616 void loadFiles(
const std::vector<std::string>& input_files) {
617 filenames = input_files;
626 unsigned num_evts = 0;
630 evt.getValidHandle<std::vector<artdaq::Fragment>>(
tag);
631 for (
const auto& frag : *frags) {
632 artdaq::ContainerFragment cont_frag(frag);
633 for (
unsigned b = 0;
b < cont_frag.block_count(); ++
b) {
634 if(cont_frag[
b]->dataSizeBytes() != 0) {
635 frags_.push_back(*cont_frag[
b]);
639 std::cout <<
"Event " << num_evts <<
" loaded.\n";
640 if (frags_.size() >= 50) {
644 std::cout <<
"Loaded " <<
total_fragments() <<
" fragments in " << num_evts
648 unsigned Usize = Uch.size();
649 unsigned Vsize = Vch.size();
650 unsigned Wsize = Wch.size();
651 for (
unsigned j = 0; j < 8; ++j) {
652 for (
unsigned i = 0; i < Usize; ++i) {
653 Uch.push_back(Uch[i] + 32 * j);
655 for (
unsigned i = 0; i < Vsize; ++i) {
656 Vch.push_back(Vch[i] + 32 * j);
658 for (
unsigned i = 0; i < Wsize; ++i) {
659 Wch.push_back(Wch[i] + 32 * j);
std::vector< double > ch_avgsU
bool check_all_IDs() const
size_t total_frames() const
std::vector< bool > frag_good
std::vector< double > ch_avgsW
uint8_t slot_no(const unsigned &frame_ID=0) const
uint8_t crate_no(const unsigned &frame_ID=0) const
std::vector< unsigned > ch_freqU
size_t total_frames(const size_t i=0) const
artdaq::Fragment Fragment(const size_t &frag_num) const
void FFT(std::vector< std::complex< double >> &x)
std::vector< unsigned > Uch
std::vector< double > ch_avgsV
adc_t get_ADC(const unsigned &frame_ID, const uint8_t channel_ID) const
void calculateAveragesAndFreqs()
size_t total_fragments() const
std::vector< double > ch_rmsW
void loadFiles(const std::string &filename)
size_t total_events() const
std::vector< bool > bad_channel_
bool check_CCCs(unsigned frag_num) const
bool check_IDs(unsigned frag_num) const
std::vector< unsigned > Wch
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
uint16_t coldata_convert_count(const unsigned &frame_ID, const uint8_t &block_num) const
void analyse(std::string destination)
std::vector< std::string > filenames
long long numberOfEventsInFile() const
Q_EXPORT QTSManip setw(int w)
uint8_t fiber_no(const unsigned &frame_ID=0) const
std::vector< double > ch_rmsU
std::vector< unsigned > ch_freqV
bool check_all_timestamps() const
void loadFiles(const std::vector< std::string > &input_files)
bool check_timestamps(unsigned frag_num) const
std::vector< unsigned > ch_freqW
std::vector< double > ch_rmsV
std::vector< artdaq::Fragment > frags_
bool check_all_CCCs() const
void printFrames(const size_t &begin_frame=0, const size_t &end_frame=1, const size_t &frag_num=0) const
void print(const unsigned i) const
const unsigned bad_channel_threshold_lower_
FelixDecoder(const T &input_files)
std::vector< std::vector< double > > FEMB_FFT
const unsigned bad_channel_threshold_
std::vector< unsigned > Vch
uint64_t timestamp(const unsigned &frame_ID=0) const