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