BOSS 7.0.4
BESIII Offline Software System
Loading...
Searching...
No Matches
ZddConverter.cxx
Go to the documentation of this file.
1#include "RawDataCnv/Util/ZddConverter.h"
2#include "ZddEvent/ZddBoard.h"
3#include "ZddEvent/ZddChannel.h"
4#include <cstring>
5#include <iomanip> //FIXME: for debugging
6
7ZddConverter* ZddConverter::s_instance = 0;
8
10{
11 if ( s_instance == 0 ) {
12 s_instance = new ZddConverter(runMode);
13 }
14
15 return s_instance;
16}
17
19{
20 if ( s_instance != 0 ) {
21 delete s_instance;
22 s_instance = 0;
23 }
24}
25
26bool ZddConverter::convert(uint32_t* pdata, int size, Event::ZddEvent* evt)
27{
28 // for debugging
29 //std::cout << "RAW buffer size: " << size << std::endl << std::hex;
30 //for ( int i = 0; i < size; ++i ) {
31 // if ( i%8 == 0 ) std::cout << "0x" << std::setw(8) << std::setfill('0') << i << ":";
32 // std::cout << " 0x" << std::setw(8) << std::setfill('0') << pdata[i];
33 // if ( i%8 == 7 ) std::cout << std::endl;
34 //}
35 //std::cout << std::dec << std::endl;
36 ///////////////////////////////////////////
37
38 uint32_t* pend = pdata + size;
39
40 while ( pdata < pend ) {
41 pdata = decodeBoard(pdata, evt);
42 }
43
44 if ( pdata != pend ) {
45 std::cout << "ZddConverter: there are problems within the event data size" << std::endl;
46 exit(1);
47 }
48
49 return true;
50}
51
52uint32_t* ZddConverter::decodeBoard(uint32_t* pevt, Event::ZddEvent* evt)
53{
54 if ( (pevt[0] >> 28) != 10 ) {
55 std::cout << "ZddConverter get wrong event marker!" << std::endl;
56 exit(1);
57 }
58
59 int size = pevt[0] & 0xFFFFFFF;
60 int board = pevt[1] >> 27;
61 uint32_t chMask = pevt[1] & 0xFF;
62
63 ZddBoard* zddBoard = new ZddBoard(evt);
64 zddBoard->setBoardId(board);
65 zddBoard->setCounter(pevt[2]&0xFFFFFF);
66 zddBoard->setTimeTag(pevt[3]);
67
68 int ich = 0;
69
70 uint32_t* pend = pevt + size;
71 uint32_t* pchannel = pevt + 4;
72
73 while ( pchannel < pend ) {
74 while ( (chMask&(1<<ich)) == 0 ) {
75 ++ich;
76 if ( ich > 7 ) {
77 std::cout << "ZddConverter get wrong channel mask!" << std::endl;
78 exit(1);
79 }
80 }
81 ZddChannel* zddCh = new ZddChannel();
82 zddCh->setChId(board*100+ich);
83 zddBoard->addChannel(zddCh);
84 pchannel = decodeChannel(pchannel, zddCh);
85 ++ich;
86 }
87
88 if ( pchannel != pend ) {
89 std::cout << "ZddConverter: there are problems within the channel data size" << std::endl;
90 exit(1);
91 }
92
93 return pend;
94}
95
96uint32_t* ZddConverter::decodeChannel(uint32_t* pch, ZddChannel* zddCh)
97{
98 uint32_t* pend = pch + pch[0];
99 uint32_t* pfrag = pch + 1;
100
101 ZddFragment zddFrag;
102
103 int nCtrlWord = 0; //FIXME: check the good/skip transfrom, N < 14
104
105 int lstat = 0;
106 int index = 0;
107 int samples = 800; // FIXME: writing 800 here is a bad idea
108
109 while ( pfrag < pend ) {
110 uint32_t& ctrl_word = pfrag[0];
111 int size = (ctrl_word & 0x1FFFFF) * 4; //from words to bytes
112
113 if ( ctrl_word >> 31 ) { //fragment passed threshold
114
115 if ( ctrl_word == 0xFEFEFEFE ) break; // CAEN FW bug discovered June 2014, not much serious:
116 // not really a control word, end of channel instead
117
118 // previous treatment by Jaheng
119 if ( (pfrag + size/4 + 1) > pend ) { //FIXME: error ZDD data
120 std::cout << "BAD ZDD RAW DATA!" << std::endl;
121 //exit(1);
122 break;
123 }
124 zddFrag.start_index = index;
125 zddFrag.length = size;
126 zddFrag.sample = new unsigned char[size];
127 memcpy(zddFrag.sample, pfrag+1, size);
128 zddCh->addFragments(zddFrag);
129 pfrag += size/4 + 1;
130 if ( lstat < 0 ) ++nCtrlWord;
131 lstat = 1;
132 }
133 else { //fragment skipped
134 pfrag += 1;
135 if ( lstat > 0 ) ++ nCtrlWord;
136 lstat = -1;
137 }
138
139 index += size;
140/* Following check UNNEEDED
141 if ( nCtrlWord == 14 ) { //FIXME: to be fixed
142 if ( pfrag < pend ) {
143 zddFrag.start_index = index;
144 zddFrag.length = (pend-pfrag)*4;
145 zddFrag.sample = new unsigned char[zddFrag.length];
146 memcpy(zddFrag.sample, pfrag, zddFrag.length);
147 zddCh->addFragments(zddFrag);
148 }
149 break;
150 }
151*/
152 }
153
154 if ( index < samples ) {
155 zddCh->setScanCode(-1); // mark channel as "Incomplete scan"
156// std::cout << "ZDD MISS channelId=" << zddCh->getChId()
157// << " missing samples:" << samples-index << " marked INCOMPLETE SCAN" << std::endl;
158 }
159
160 return pend;
161}
162
163ZddConverter::ZddConverter(int runMode)
164 : m_runMode(runMode)
165{
166}
167
168ZddConverter::~ZddConverter()
169{
170}
void addChannel(ZddChannel *ch)
Definition: ZddBoard.cxx:14
void addFragments(const ZddFragment &frag)
static ZddConverter * instance(int runMode=2)
Definition: ZddConverter.cxx:9
static void destroy()
bool convert(uint32_t *pdata, int size, Event::ZddEvent *evt)