/*-------------------------------------------------------
* Package: Wavelet Analysis Tool
* File name: wdwt.cc
*-------------------------------------------------------
*/
//_______________________________________________________
// WaveDWT is the abstract base class for discrete wavelet
// transform methods. It includes methods, like getLayer,
// putLayer, t2w, w2t, etc.
#ifndef _STREAM_H
#include <stream.h>
#define _STREAM_H
#endif
#include "wavedwt.h"
#include "gsbmp.h"
#ifdef _USE_ROOT
ClassImp(WaveDWT)
#endif
WaveDWT::WaveDWT(int m, int ist, int brd)
{
// Constructor which creates object of class WSeries
// with N=m elements of data. Variable 'border'
// controls processing of data array boundaries.
pWDC = new WSeries(m);
pWDC->N = m;
IsTree=ist;
Level=0;
MaxLevel=0;
border=brd;
}
WaveDWT::~WaveDWT()
{
// Destructor.
delete pWDC;
}
void WaveDWT::t2w(const WaveData& td,int ldeep)
{
// Virtual procedure for forward wavelet transform that
// take initial data from WaveData "td" and places result
// in WSeries class.
// Only ldeep steps of decomposition will be done.
// By default ldeep=-1, which means do maximum number of allowed steps.
register int n=td.N;
register wavereal *in,*wd;
in = td.data;
Level=0;
if(td.N!=pWDC->N)
{
pWDC->Resize(td.N);
}
pWDC->Rate=td.Rate;
wd=pWDC->data;
for(int q=0;q<n;q++,in++,wd++) *wd=*in;
if (ldeep!=0) t2w(ldeep);
}
void WaveDWT::t2w(int ldeep)
{
// Virtual procedure for forward wavelet transform.
// Real code will appear in
// derivative classes since it depends of the type of wavelet.
// Only ldeep steps of decomposition will be done.
// By default ldeep=1, which means do one step.
getMaxLevel();
int levs=Level;
int levf=Level+ldeep;
if((ldeep==-1)||(levf>MaxLevel)) levf=MaxLevel;
int layf;
for(int level=levs;level<levf;level++)
{
layf=IsTree?1<<level:1;
for(int layer=0;layer<(layf);layer++)
{
decompose(level,layer);
}
Level=level+1;
}
Level=levf;
}
void WaveDWT::w2t(int ldeep)
{
// Virtual procedure for inverse wavelet transform that
// take initial data from current WSeries class without places
// result into object of WaveData class.
// Only ldeep steps of backward composition will be done.
// By default ldeep=1, which means do one step.
int levs=Level;
int levf=Level-ldeep;
if((ldeep==-1)||(levf<0)) levf=0;
int layf;
for(int level=levs-1;level>=levf;level--)
{
layf=IsTree?1<<level:1;
for(int layer=0;layer<(layf);layer++)
{
reconstruct(level,layer);
}
Level=level;
}
Level=levf;
}
void WaveDWT::w2t(WaveData &td, int ldeep)
{
// Virtual procedure for inverse wavelet transform that
// take initial data from current WSeries class and places
// result to object td of WaveData class.
// Only ldeep steps of backward composition will be done.
// By default ldeep=-1, which means do maximum allowed steps.
w2t(ldeep);
register int n=pWDC->N;
register wavereal *out, *d;
d = pWDC->data;
if(n!=td.N) td.Resize(n);
out = td.data;
td.Rate=pWDC->Rate;
for(int q=0;q<n;q++,out++,d++) *out = *d;
// memcpy(out,d,n*sizeof(out));
}
void WaveDWT::Denoise(wavereal cut)
{
// Simple denoising procedure. Sets to zero all elements of
// wavelet spectrum which absolute value less then "cut".
int n = pWDC->N;
if (cut < 0.) cut = -cut;
cout<<"Denoising array of "<< n << " elements, cut = "<< cut << "n";
for (int i = 0; i < n; i++) {
if (fabs(pWDC->data[i]) < cut) pWDC->data[i] = 0.;
}
}
void WaveDWT::getLayer(WaveData &td, int k)
{
// Get layer with given number k and put it into td array.
//
register int start, step;
if(k<0) { k=0; cout<<"getLayer() warning: Selected layer number 0.n";}
if(IsTree) {
int max_layers=1<<Level;
if(k>max_layers-1) k=max_layers-1;
int m = (pWDC->N)>>Level;
if (td.N!=m) td.Resize(m);
int k1=getIdA(Level,k);
for(int i=0;i<m;i++) td.data[i]=pWDC->data[(i<<Level)+k1];
}
else {
bool is_top=false;
if(k>MaxLevel){
k=MaxLevel;
cout<<"getLayer() warning: Selected layer with maximum number "
<<MaxLevel<<".n";
}
if(k==0) { is_top=true; k=Level; }
int m = (pWDC->N)>>k;
if (td.N!=m) td.Resize(m);
start = (is_top) ? 0: 1<<(k-1);
step = 1<<k;
register wavereal *out, *d;
out=td.data;
d=pWDC->data+start;
for(int i=0;i<m;i++,out++,d+=step) *out=*d;
}
}
void WaveDWT::putLayer(WaveData &td, int k)
{
// Replace content of the layer number k with data from array td.
//
register int start, step;
if(k<0) { k=0;cout<<"Selected layer number 0.n";}
if(IsTree){
int max_layers=1<<Level;
if(k>max_layers-1){
k=max_layers-1;
cout<<"putLayer() warning: Selected layer with maximum number "
<<max_layers-1<<".n";
}
int m=(pWDC->N)>>Level;
if(td.N!=m){
cout<<
"putLayer() warning: number of data is not correct! Does nothing.n";
return;
}
int k1=getIdA(Level,k);
for(int i=0;i<m;i++) pWDC->data[(i<<Level)+k1]=td.data[i];
}
else {
char is_top=0;
if(k>MaxLevel) {
k=MaxLevel;
cout<<"putLayer() warning: Selected layer with maximum number "
<<MaxLevel<<".n";
}
if(k==0) { is_top=1; k=Level; }
int m=(pWDC->N)>>k;
if(td.N!=m) {
cout<<
"putLayer() warning: number of data is not correct! Does nothing.n";
return;
}
start = (is_top) ? 0: 1<<(k-1);
step = 1<<k;
register wavereal *in, *d;
in=td.data;
d=pWDC->data+start;
for(int i=0;i<m;i++,in++,d+=step) *d=*in;
}
}
void WaveDWT::getFreqLayer(WaveData &td, int k)
{
// The same as getLayer, but select layers in frequency order.
int k1=getIdL(Level,k);
getLayer(td,k1);
}
void WaveDWT::putFreqLayer(WaveData &td, int k)
{
// The same as putLayer, but put layers in frequency order.
putLayer(td,getIdL(Level,k));
}
int WaveDWT::getMaxLevel()
{
// Calculate maximal level of wavelet decomposition.
// It depends on filter length.
MaxLevel=0;
int jc1=pWDC->N;//>>1;
for(;jc1>=nh;jc1=jc1>>1) MaxLevel++;
return MaxLevel;
}
int WaveDWT::getIdA(int level,int layer)
{
// Gets wavelet layer number for given level and layer.
int IdA=0;
for(int i=0;i<level;i++)
{
if((layer>>i)&1) IdA+=1<<(level-1-i); //some operations with bits
}
return IdA;
}
int WaveDWT::getIdF(int level,int IdL)
{
// Get frequency ID number for given level and layer.
//
int IdF=IdL;
for(int i=1;i<level;i++)
{
int j=((1<<i)&(IdF));
if(j)IdF=((1<<i)-1)^(IdF);
}
return IdF;
}
int WaveDWT::getIdL(int level,int IdF)
{
// Get the layer number in binary tree for given level and frequency ID number.
//
int IdL=IdF;
for(int i=level-1;i>=1;i--)
{
int j=((1<<i)&(IdL));
if(j)IdL=((1<<i)-1)^(IdL);
}
return IdL;
}
int WaveDWT::DumpWTAsBitmap(const char* fn,unsigned int palette)
{
//
if(IsTree==0) return 1;
if(pWDC==NULL) return 1;
unsigned int ni=1<<Level;
unsigned int nj=pWDC->N/ni;
unsigned char *bits=new unsigned char[pWDC->N];
double mx,mn;
mx=mn=pWDC->data[0];
for(int s=0;s<pWDC->N;s++){
if(pWDC->data[s]>mx) mx=pWDC->data[s];
if(pWDC->data[s]<mn) mn=pWDC->data[s];
}
WaveData l;
for(unsigned int i=0;i<ni;i++)
{
getFreqLayer(l,i);
for(unsigned int j=0;j<nj;j++) bits[j+nj*i]=(unsigned char)(255*(l.data[j]-mn)/(mx-mn));
}
cout<<"mn="<<mn<<" mx="<<mx<<"n";
// unsigned char *bits=new unsigned char[256*256];
// for(int i=0;i<256;i++)for(int j=0;j<256;j++)bits[i*256+j]=(i+j)>255?(i+j-255):(i+j);
gs_bm_write(fn,bits,nj,ni,palette);
delete [] bits;
return 0;
}
#ifdef _USE_DMT
void WaveDWT::t2w(const TSeries& ts,int ldeep)
{
unsigned int Ninput = ts.getNSample();
Interval ti = ts.getTStep();
wavereal rate = ti.GetSecs();
if(rate) rate = 1./rate;
else cout<<"warning: TSeries::GetSecs() returned 0.\n";
if((int)Ninput != pWDC->N) pWDC->Resize(Ninput);
pWDC->Rate = rate;
ts.getData(Ninput,(double *)pWDC->data);
t2w(ldeep);
}
void WaveDWT::w2t(TSeries& ts,int ldeep)
{
double rate = 1.;
w2t(ldeep);
if(pWDC->Rate > 0.) rate = 1./pWDC->Rate;
unsigned int Ninput = ts.getNSample();
if((int)Ninput!=pWDC->N) ts.ReSize(pWDC->N);
if(!ts.setData(Time(0.0),Interval(rate),pWDC->data,(unsigned int)pWDC->N))
cout<<"warning: TSeries::setData() returned 0.\n";
return;
}
#endif // use DMT
ROOT page - Class index - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.