00001 #include "RawDataCnv/Util/ZddConverter.h"
00002 #include "ZddEvent/ZddBoard.h"
00003 #include "ZddEvent/ZddChannel.h"
00004 #include <cstring>
00005 #include <iomanip>
00006
00007 ZddConverter* ZddConverter::s_instance = 0;
00008
00009 ZddConverter* ZddConverter::instance(int runMode)
00010 {
00011 if ( s_instance == 0 ) {
00012 s_instance = new ZddConverter(runMode);
00013 }
00014
00015 return s_instance;
00016 }
00017
00018 void ZddConverter::destroy()
00019 {
00020 if ( s_instance != 0 ) {
00021 delete s_instance;
00022 s_instance = 0;
00023 }
00024 }
00025
00026 bool ZddConverter::convert(uint32_t* pdata, int size, Event::ZddEvent* evt)
00027 {
00028
00029
00030
00031
00032
00033
00034
00035
00037
00038 uint32_t* pend = pdata + size;
00039
00040 while ( pdata < pend ) {
00041 pdata = decodeBoard(pdata, evt);
00042 }
00043
00044 if ( pdata != pend ) {
00045 std::cout << "ZddConverter: there are problems within the event data size" << std::endl;
00046 exit(1);
00047 }
00048
00049 return true;
00050 }
00051
00052 uint32_t* ZddConverter::decodeBoard(uint32_t* pevt, Event::ZddEvent* evt)
00053 {
00054 if ( (pevt[0] >> 28) != 10 ) {
00055 std::cout << "ZddConverter get wrong event marker!" << std::endl;
00056 exit(1);
00057 }
00058
00059 int size = pevt[0] & 0xFFFFFFF;
00060 int board = pevt[1] >> 27;
00061 uint32_t chMask = pevt[1] & 0xFF;
00062
00063 ZddBoard* zddBoard = new ZddBoard(evt);
00064 zddBoard->setBoardId(board);
00065 zddBoard->setCounter(pevt[2]&0xFFFFFF);
00066 zddBoard->setTimeTag(pevt[3]);
00067
00068 int ich = 0;
00069
00070 uint32_t* pend = pevt + size;
00071 uint32_t* pchannel = pevt + 4;
00072
00073 while ( pchannel < pend ) {
00074 while ( (chMask&(1<<ich)) == 0 ) {
00075 ++ich;
00076 if ( ich > 7 ) {
00077 std::cout << "ZddConverter get wrong channel mask!" << std::endl;
00078 exit(1);
00079 }
00080 }
00081 ZddChannel* zddCh = new ZddChannel();
00082 zddCh->setChId(board*100+ich);
00083 zddBoard->addChannel(zddCh);
00084 pchannel = decodeChannel(pchannel, zddCh);
00085 ++ich;
00086 }
00087
00088 if ( pchannel != pend ) {
00089 std::cout << "ZddConverter: there are problems within the channel data size" << std::endl;
00090 exit(1);
00091 }
00092
00093 return pend;
00094 }
00095
00096 uint32_t* ZddConverter::decodeChannel(uint32_t* pch, ZddChannel* zddCh)
00097 {
00098 uint32_t* pend = pch + pch[0];
00099 uint32_t* pfrag = pch + 1;
00100
00101 ZddFragment zddFrag;
00102
00103 int nCtrlWord = 0;
00104
00105 int lstat = 0;
00106 int index = 0;
00107 int samples = 800;
00108
00109 while ( pfrag < pend ) {
00110 uint32_t& ctrl_word = pfrag[0];
00111 int size = (ctrl_word & 0x1FFFFF) * 4;
00112
00113 if ( ctrl_word >> 31 ) {
00114
00115 if ( ctrl_word == 0xFEFEFEFE ) break;
00116
00117
00118
00119 if ( (pfrag + size/4 + 1) > pend ) {
00120 std::cout << "BAD ZDD RAW DATA!" << std::endl;
00121
00122 break;
00123 }
00124 zddFrag.start_index = index;
00125 zddFrag.length = size;
00126 zddFrag.sample = new unsigned char[size];
00127 memcpy(zddFrag.sample, pfrag+1, size);
00128 zddCh->addFragments(zddFrag);
00129 pfrag += size/4 + 1;
00130 if ( lstat < 0 ) ++nCtrlWord;
00131 lstat = 1;
00132 }
00133 else {
00134 pfrag += 1;
00135 if ( lstat > 0 ) ++ nCtrlWord;
00136 lstat = -1;
00137 }
00138
00139 index += size;
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 }
00153
00154 if ( index < samples ) {
00155 zddCh->setScanCode(-1);
00156
00157
00158 }
00159
00160 return pend;
00161 }
00162
00163 ZddConverter::ZddConverter(int runMode)
00164 : m_runMode(runMode)
00165 {
00166 }
00167
00168 ZddConverter::~ZddConverter()
00169 {
00170 }