33 HuffDataCompressor::HuffDataCompressor()
60 void HuffDataCompressor::SetEncoding()
65 std::map<short, std::string> codeMap;
71 codeMap[-3] =
"000001";
72 codeMap[3] =
"0000001";
80 m_SeqEnable = (m_NSeqRep > 0);
90 for(it = codeMap.begin();it!=codeMap.end();it++)
93 short deltaval = it->first;
94 string bincode = it->second;
99 bincode =
"0" + bincode;
102 size_t codesize = (bincode).
size();
103 if(codesize > m_MaxCodeSize)
104 m_MaxCodeSize = codesize;
105 if(codesize < m_MinCodeSize)
106 m_MinCodeSize = codesize;
109 m_CmMap[deltaval] = bincode;
115 m_NSeqRepVal = m_MaxDiff + m_NSeqRep;
116 m_CmMap[m_NSeqRepVal] =
"1";
122 m_UCmMap.resize( m_MaxCodeSize );
123 for(it = m_CmMap.begin();it!=m_CmMap.end();it++)
125 short deltaval = it->first;
126 string bincode = it->second;
127 m_UCmMap[bincode.size()-1] = std::make_pair(bincode, deltaval);
135 void HuffDataCompressor::PrintEncoding()
137 cout<<
endl<<
"Huffman coding scheme: "<<
endl;
140 for(
size_t i=0;i<m_UCmMap.size();i++)
142 if(i == 0 && m_SeqEnable)
144 cout<<
setw(10)<<m_UCmMap[i].first
145 <<
setw(5)<<m_NSeqRep<<
" x no change" 146 <<
setw(4)<<i+1<<
" bit code length"<<
endl;
151 cout<<
setw(10)<<m_UCmMap[i].first<<
setw(5)<<m_UCmMap[i].second
152 <<
setw(4)<<i+1<<
" bit code length"<<
endl;
169 string emptystr =
"";
171 if(
std::abs(val) > m_MaxDiff && val != m_NSeqRepVal)
173 msg_err<<__FILE__<<
", "<<__LINE__<<
" the value '"<<val<<
"' exceeds range"<<
endl;
178 it = m_CmMap.find( val );
179 if(it != m_CmMap.end())
183 msg_err<<__FILE__<<
", "<<__LINE__<<
" the value '"<<val<<
"' could not be found"<<
endl;
192 void HuffDataCompressor::AddToHuffBuffer(
short val,
bool rawadc)
200 tmp.
codestr = GetCodeFromValue(val);
203 HuffBuffer.push_back( tmp );
208 if( HuffBuffer.back().value == tmp.
value &&
209 !HuffBuffer.back().codestr.empty() )
212 HuffBuffer.back().nrep += 1;
217 HuffBuffer.push_back( tmp );
230 return s.substr(s.size() - strsize);
233 msg_warn<<__FILE__<<
", "<<__LINE__<<
" the string looks too long"<<
endl;
234 while(s.size() < strsize) s =
"0" + s;
242 bool HuffDataCompressor::SetNbitsAdc(
short nbadc )
244 if( nbadc > m_MaxAdcBits )
return false;
250 m_PacketSize = m_NbitsHC + m_NbitsHead;
261 std::vector<BYTE> &buf,
264 if( words.empty() && partbyte.empty() )
return;
267 if( words.size() < m_NbitsByte && partbyte.empty() )
274 if(words.empty() && !partbyte.empty())
277 while(partbyte.size() < m_NbitsByte) partbyte +=
"0";
278 buf.push_back( (strtoul(partbyte.c_str(), 0, 2) & 0xff) );
283 for(
size_t i=0;i<words.size();i++)
285 if(partbyte.size() == m_NbitsByte)
287 buf.push_back( (strtoul(partbyte.c_str(), 0, 2) & 0xff) );
291 partbyte += words[i];
301 void HuffDataCompressor::CompressChData(
short nbadc, std::vector<adc16_t> &raw_in,
302 std::vector<BYTE> &bin_out )
304 if(!SetNbitsAdc( nbadc ))
307 msg_err<<
"ADC "<<nbadc<<
" bits exceeds max supported "<<m_MaxAdcBits<<
endl;
316 for(
size_t i=0;i<raw_in.size();i++)
318 if(i==0) delta = m_MaxDiff + 1;
319 else delta = raw_in[i] - raw_in[i-1];
322 AddToHuffBuffer( (
short)raw_in[i], true );
324 AddToHuffBuffer( delta,
false );
329 string bitrepcode =
"";
332 bitrepcode = GetCodeFromValue( m_NSeqRepVal );
333 if(bitrepcode.empty())
335 msg_err<<__FILE__<<
", "<<__LINE__
336 <<
" encoding repetion failed. Aborting ..."<<
endl;
343 string bitword, bitcode, partbyte;
347 for(
size_t i=0;i<HuffBuffer.size();i++)
356 if(HuffBuffer[i].codestr.empty())
359 if(bitword.size() > m_NbitsHead)
362 while(bitword.size() < m_PacketSize) bitword +=
"0";
363 AddWordsToByteBuffer( bitword, bin_out, partbyte );
367 bitword =
"0" + GetBinaryString( HuffBuffer[i].
value, m_NbitsHC );
370 AddWordsToByteBuffer( bitword, bin_out, partbyte );
376 bitcode = HuffBuffer[i].codestr;
377 nhcrep = HuffBuffer[i].nrep;
379 for(
short jj=0;jj<=nhcrep;jj++)
384 else if(jj+m_NSeqRep <= nhcrep && m_SeqEnable)
386 bitword += bitrepcode;
394 if(bitword.size() >= m_PacketSize)
396 if(bitword.size() == m_PacketSize)
398 AddWordsToByteBuffer( bitword, bin_out, partbyte );
404 string towrite = bitword.substr(0, m_PacketSize);
405 string tosave = bitword.substr(m_PacketSize);
408 AddWordsToByteBuffer( towrite, bin_out, partbyte );
411 bitword =
"1" + tosave;
421 if(bitword.size() > m_NbitsHead)
422 AddWordsToByteBuffer( bitword, bin_out, partbyte );
427 AddWordsToByteBuffer(
"", bin_out, partbyte );
435 void HuffDataCompressor::CompressEventData(
short nbadc,
size_t nch,
size_t seqlen,
436 std::vector<adc16_t> &raw_in,
437 std::vector<BYTE> &bin_out )
440 if(!SetNbitsAdc( nbadc ))
442 msg_err<<
"ADC "<<nbadc<<
" bits exceeds max supported "<<m_MaxAdcBits<<
endl;
446 if( seqlen * nch != raw_in.size() )
448 msg_err<<
"Length of raw data vector does not match with expected "<<
endl;
452 for(
size_t i=0;i<nch;i++)
454 size_t istart = i*seqlen;
456 std::vector<adc16_t> chdata(&raw_in[istart], &raw_in[istart+seqlen]);
457 CompressChData( nbadc, chdata, bin_out );
465 void HuffDataCompressor::CompressEventData(
short nbadc,
size_t nch,
size_t seqlen,
467 std::vector<BYTE> &bin_out )
470 if(!SetNbitsAdc( nbadc ))
472 msg_err<<
"ADC "<<nbadc<<
" bits exceeds max supported "<<m_MaxAdcBits<<
endl;
476 if( nch != raw_in.size() )
478 msg_err<<
"Number of ch in raw data vector does not match with expected "<<
endl;
482 for(
size_t i=0;i<nch;i++)
484 if( raw_in[i].
size() != seqlen )
486 msg_err<<
"No support for compression of unequal sequence lenghts at the moment"<<
endl;
491 CompressChData( nbadc, raw_in[i], bin_out );
500 void HuffDataCompressor::ReadNextByte(
size_t &byteidx,
const char *buf,
501 std::deque<bitset<1> > &bits)
503 unsigned short bitmask = 1 << (m_NbitsByte - 1);
506 for(
size_t i=0;i<m_NbitsByte;i++)
507 bits.push_back( bitset<1>( (buf[byteidx] & (bitmask >> i)) != 0) );
517 void HuffDataCompressor::ReadNextByte(std::ifstream &fin, std::deque< std::bitset<1> > &bits,
523 if(!fin.get(byteword))
529 unsigned short bitmask = 1 << (m_NbitsByte - 1);
532 for(
size_t i=0;i<m_NbitsByte;i++)
533 bits.push_back( bitset<1>( (byteword & (bitmask >> i)) != 0) );
542 void HuffDataCompressor::DecompressEventData(
short nbadc,
545 const char *buf,
size_t bufsize,
size_t &byteidx,
546 std::vector<adc16_t> &
adc )
548 if(!SetNbitsAdc( nbadc ))
550 msg_err<<
"ADC "<<nbadc<<
" bits exceeds max supported "<<m_MaxAdcBits<<
endl;
555 vector< adc16_t > chdata;
556 deque< bitset<1> > bitqueue;
559 short lastdelta = -999;
569 while( adc.size() != nch*seqlen )
571 if(byteidx<bufsize) ReadNextByte(byteidx, buf, bitqueue);
576 msg_err<<
"There seems to be a problem with decoding"<<
endl 577 <<
"Bytes read "<<byteidx<<
" out of "<<bufsize<<
endl 578 <<
"Samples accumulated in this channel "<<chdata.size()<<
endl 579 <<
"Remaining bits are "<<bitqueue.size()<<
" "<<bitqueue.empty()<<
endl;
584 if( bitqueue.size() < m_PacketSize && byteidx != bufsize)
587 bool iscomp = bitqueue.front().test(0);
589 bitqueue.pop_front();
595 if( bitqueue.size() < m_NbitsHC )
597 msg_err<<
"Fatal decoding error has been encountered : "<<
endl 598 <<
" Number of bits in the uncompressed stream should be at least " 599 <<m_NbitsHC<<
" the current value is "<<bitqueue.size()<<
endl;
603 size_t bitcounter = 0;
604 while(bitcounter < m_NbitsHC)
606 ss << bitqueue.front();
607 bitqueue.pop_front();
610 bitsread += bitcounter;
612 adc16_t val = ( strtoul(ss.str().c_str(), 0, 2) & 0x7FFF );
613 chdata.push_back( val );
618 size_t bitcounter = 0;
619 size_t bitstoread = m_NbitsHC;
620 if( bitqueue.size() < m_NbitsHC )
621 bitstoread = bitqueue.size();
623 while( bitcounter < bitstoread )
625 ss << bitqueue.front();
626 bitqueue.pop_front();
630 size_t strsize = ss.str().size();
631 if( strsize >= m_MinCodeSize && strsize <= m_MaxCodeSize )
633 bool ok = (m_UCmMap[strsize-1].first == ss.str());
635 short val = m_UCmMap[strsize-1].second;
644 chdata.push_back( newval );
647 else if(val == m_NSeqRepVal)
649 for(
short j=0;j<m_NSeqRep;j++)
651 adc16_t newval = chdata.back() + lastdelta;
652 chdata.push_back( newval );
658 if(chdata.size() == seqlen)
break;
664 if(chdata.size() == seqlen)
668 size_t padbits = bitsread % m_NbitsByte;
669 if(padbits > 0) padbits = m_NbitsByte - padbits;
674 <<
"Bits read : "<<bitsread<<
endl 675 <<
"Bits to boundary : "<<padbits<<
endl 676 <<
"Last value : "<<chdata.back()<<
" ADC "<<
endl;
680 if( bitqueue.size() < padbits )
682 msg_err<<
"Fatal decoding error has been encountered : "<<
endl 683 <<
"Byte boundary does not appear to be valid"<<
endl 684 <<
"Check that the codes are padded with 0 to the next byte boundary"<<
endl;
691 bitqueue.pop_front();
696 if(!bitqueue.empty())
698 if(bitqueue.front().test(0) && chread <= (nch-1) )
700 msg_err<<
"Fatal decoding error had been encounter : "<<
endl 701 <<
"The first bit of the next ch sequence should always be 0 and not " 702 <<bitqueue.front()<<
endl;
711 adc.insert(adc.end(), chdata.begin(), chdata.end() );
716 cout<<
"Decoded "<<adc.size()<<
" samples"<<
endl<<
endl;
723 if(bitqueue.size() > 0)
725 msg_info<<
"Bits remaning in the queue "<<bitqueue.size()<<
endl;
733 msg_info<<
"Bits remaning in the queue "<<bitqueue.size()<<
endl;
750 void HuffDataCompressor::DecompressEventData( std::ifstream &fin,
754 std::vector< adc16_t > &
adc)
756 if(!SetNbitsAdc( nbadc ))
758 msg_err<<
"ADC "<<nbadc<<
" bits exceeds max supported "<<m_MaxAdcBits<<
endl;
763 vector< adc16_t > chdata;
764 deque< bitset<1> > bitqueue;
767 short lastdelta = -999;
779 while( adc.size() != nch*seqlen )
781 ReadNextByte(fin, bitqueue, flag);
786 msg_err<<
"There seems to be a problem with decoding"<<
endl 787 <<
"Samples accumulated in this channel "<<chdata.size()<<
endl 788 <<
"Remaining bits are "<<bitqueue.size()<<
" "<<bitqueue.empty()<<
endl;
793 if( bitqueue.size() < m_PacketSize && noread < 1)
796 bool iscomp = bitqueue.front().test(0);
798 bitqueue.pop_front();
804 if( bitqueue.size() < m_NbitsHC )
806 msg_err<<
"Fatal decoding error has been encountered : "<<
endl 807 <<
"Number of bits in the uncompressed stream should be at least " 808 <<m_NbitsHC<<
" the current value is "<<bitqueue.size()<<
endl;
812 size_t bitcounter = 0;
813 while(bitcounter < m_NbitsHC)
815 ss << bitqueue.front();
816 bitqueue.pop_front();
819 bitsread += bitcounter;
821 adc16_t val = ( strtoul(ss.str().c_str(), 0, 2) & 0x7FFF );
822 chdata.push_back( val );
827 size_t bitcounter = 0;
828 size_t bitstoread = m_NbitsHC;
829 if( bitqueue.size() < m_NbitsHC )
830 bitstoread = bitqueue.size();
832 while( bitcounter < bitstoread )
834 ss << bitqueue.front();
835 bitqueue.pop_front();
839 size_t strsize = ss.str().size();
840 if( strsize >= m_MinCodeSize && strsize <= m_MaxCodeSize )
842 bool ok = (m_UCmMap[strsize-1].first == ss.str());
844 short val = m_UCmMap[strsize-1].second;
853 chdata.push_back( newval );
856 else if(val == m_NSeqRepVal)
858 for(
short j=0;j<m_NSeqRep;j++)
860 adc16_t newval = chdata.back() + lastdelta;
861 chdata.push_back( newval );
867 if(chdata.size() == seqlen)
break;
873 if(chdata.size() == seqlen)
877 size_t padbits = bitsread % m_NbitsByte;
878 if(padbits > 0) padbits = m_NbitsByte - padbits;
883 <<
"Bits read : "<<bitsread<<
endl 884 <<
"Bits to boundary : "<<padbits<<
endl 885 <<
"Last value : "<<chdata.back()<<
" ADC "<<
endl;
889 if( bitqueue.size() < padbits )
891 msg_err<<
"Fatal decoding error has been encountered : "<<
endl 892 <<
" Byte boundary does not appear to be valid"<<
endl 893 <<
" Check that the codes are padded with 0 to the next byte boundary"<<
endl;
900 bitqueue.pop_front();
905 if(!bitqueue.empty())
907 if(bitqueue.front().test(0) && chread <= (nch-1) )
909 msg_err<<
"Fatal decoding error had been encounter : "<<
endl 910 <<
" The first bit of the next ch sequence should always be 0 and not " 911 <<bitqueue.front()<<
endl;
920 adc.insert(adc.end(), chdata.begin(), chdata.end() );
932 if(bitqueue.size() > 0)
934 msg_info<<
"Bits remaning in the queue "<<bitqueue.size()<<
endl;
935 msg_info<<
"Current position in file "<<fin.tellg();
936 fin.seekg( -1, std::ios::cur );
937 msg_info<<
" Prv position in the file "<<fin.tellg()<<
endl;
944 msg_info<<
"Bits remaning in the queue "<<bitqueue.size()<<
endl;
static LogStream msg_warn(std::cout, _strwarn)
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Q_EXPORT QTSManip setw(int w)
static LogStream msg_info(std::cout, _strinfo)
static LogStream msg_err(std::cerr, _strerror)
std::string to_string(ModuleType const mt)
QTextStream & endl(QTextStream &s)