version  0.0.1
Defines the C++ API for MsPASS
Public Member Functions | List of all members
mspass::algorithms::deconvolution::ShapingWavelet Class Reference

Frequency domain shaping wavelet. More...

#include <ShapingWavelet.h>

Public Member Functions

 ShapingWavelet (const mspass::utility::Metadata &md, int npts=0)
 Construct using a limited set of analytic forms for the wavelet. More...
 
 ShapingWavelet (mspass::seismic::CoreTimeSeries d, int nfft=0)
 
 ShapingWavelet (const double fpeak, const double dtin, const int n)
 
 ShapingWavelet (const int npolelo, const double f3dblo, const int npolehi, const double f3dbhi, const double dtin, const int n)
 
 ShapingWavelet (const ShapingWavelet &parent)
 
ShapingWaveletoperator= (const ShapingWavelet &parent)
 
ComplexArraywavelet ()
 
mspass::seismic::CoreTimeSeries impulse_response ()
 
double freq_bin_size ()
 
double sample_interval ()
 
std::string type ()
 

Detailed Description

Frequency domain shaping wavelet.

Frequency domain based deconvolution methods all use a shaping wavelet for output to avoid ringing. Frequency domain deconvolution methods in this Library contain an instance of this object. In all cases it is hidden behind the interface. A complexity, however, is that all frequency domain methods will call the Metadata driven constructor.

This version currently allows three shaping wavelets: Gaussin, Ricker, and Slepian0. The first two are standard. The last is novel and theoretically can produce an actual output with the smalle posible sidebands

Constructor & Destructor Documentation

◆ ShapingWavelet() [1/3]

mspass::algorithms::deconvolution::ShapingWavelet::ShapingWavelet ( const mspass::utility::Metadata md,
int  npts = 0 
)

Construct using a limited set of analytic forms for the wavelet.

This constructor is used to create a ricker or gaussian shaping wavelet with parameters defined by parameters passed through the Metadata object.

Parameters
md- Metadata object with parameters specifying the wavelet. \npts - length of signal to be generated which is the same as the fft size for real valued signals. If set 0 (the default) the constructor will attempt to get npts from md using the keyword "operator_nfft".
19 {
20  const string base_error("ShapingWavelet object constructor: ");
21  try {
22  /* We use this to allow a nfft to be set in md. A bit error prone
23  * we add a special error handler. */
24  if(nfftin>0)
25  this->nfft=nfftin;
26  else
27  {
28  try {
29  nfft=md.get_int("operator_nfft");
30  } catch(MetadataGetError& mderr)
31  {
32  throw MsPASSError(base_error
33  + "Called constructor with nfft=0 but parameter with key=operator_nfft is not in parameter file",
34  ErrorSeverity::Invalid);
35  }
36  }
37  /* these are workspaces used by gnu's fft algorithm. Other parts
38  * of this library cache them for efficiency, but this one we
39  * compute ever time the object is created and then discard it. */
40  gsl_fft_complex_wavetable *wavetable;
41  gsl_fft_complex_workspace *workspace;
42  wavetable = gsl_fft_complex_wavetable_alloc (nfft);
43  workspace = gsl_fft_complex_workspace_alloc (nfft);
44  string wavelettype=md.get_string("shaping_wavelet_type");
45  wavelet_name=wavelettype;
46  dt=md.get_double("shaping_wavelet_dt");
47  double *r;
48  if(wavelettype=="gaussian")
49  {
50  float fpeak=md.get_double("shaping_wavelet_frequency");
51  //construct wavelet and fft
52  r=gaussian(fpeak,(float)dt,nfft);
53  w=ComplexArray(nfft,r);
54  gsl_fft_complex_forward(w.ptr(), 1, nfft, wavetable, workspace);
55  delete [] r;
56  }
57  /* Note for CNR3CDecon the initial values on construction for
58  ricker or butterworth are irrelevant and wasted effort. We keep
59  them in this class because these forms are needed by the family of
60  scalar deconvolution algorithms */
61  else if(wavelettype=="ricker")
62  {
63  float fpeak=(float)md.get_double("shaping_wavelet_frequency");
64  //construct wavelet and fft
65  r=rickerwavelet(fpeak,(float)dt,nfft);
66 //DEBUG
67 //cerr << "Ricker shaping wavelet"<<endl;
68 //for(int k=0;k<nfft;++k) cerr << r[k]<<endl;
69  w=ComplexArray(nfft,r);
70  gsl_fft_complex_forward(w.ptr(), 1, nfft, wavetable, workspace);
71  delete [] r;
72  }
73  else if(wavelettype=="butterworth")
74  {
75  double f3db_lo, f3db_hi;
76  f3db_lo=md.get_double("f3db_lo");
77  f3db_hi=md.get_double("f3db_hi");
78  int npoles_lo,npoles_hi;
79  npoles_lo=md.get_int("npoles_lo");
80  npoles_hi=md.get_int("npoles_hi");
81  Butterworth bwf(true,true,true,npoles_lo,f3db_lo,npoles_hi,f3db_hi,
82  this->dt);
83  w=bwf.transfer_function(this->nfft);
84  }
85  /* This option requires a package to compute zero phase wavelets of
86  some specified type and bandwidth. Previous used antelope filters which
87  colides with open source goal of mspass. Another implementation of
88  TimeInvariantFilter and this could be restored.
89  */
90  /*
91  else if(wavelettype=="filter_response")
92  {
93  string filterparam=md.get_string("filter");
94  TimeInvariantFilter filt(filterparam);
95  TimeSeries dtmp(nfft);
96  dtmp.ns=nfft;
97  dtmp.dt=dt;
98  dtmp.live=true;
99  dtmp.t0=(-dt*static_cast<double>(nfft/2));
100  dtmp.tref=relative;
101  int i;
102  i=dtmp.sample_number(0.0);
103  dtmp.s[i]=1.0; // Delta function at 0
104  filt.zerophase(dtmp);
105  // We need to shift the filter response now back to
106  // zero to avoid time shifts in output
107  dtmp.s=circular_shift(dtmp.s,nfft/2);
108  w=ComplexArray(dtmp.s.size(), &(dtmp.s[0]));
109  gsl_fft_complex_forward(w.ptr(), 1, nfft, wavetable, workspace);
110  }
111  */
112  else if((wavelettype=="slepian") || (wavelettype=="Slepian") )
113  {
114  double tbp=md.get_double("time_bandwidth_product");
115  double target_pulse_width=md.get_double("target_pulse_width");
116  /* Sanity check on pulse width */
117  if(target_pulse_width>(nfft/4) || (target_pulse_width<tbp))
118  {
119  stringstream ss;
120  ss << "ShapingWavelet Metadata constructor: bad input parameters for Slepian shaping wavelet"
121  <<endl
122  << "Specified target_pulse_width of "<<target_pulse_width<<" samples"<<endl
123  << "FFT buffer size="<<nfft<<" and time bandwidth product="<<tbp<<endl
124  << "Pulse width should be small fraction of buffer size but ge than tbp"<<endl;
125  throw MsPASSError(ss.str(),ErrorSeverity::Invalid);
126  }
127  double c=tbp/target_pulse_width;
128  int nwsize=round(c*(static_cast<double>(nfft)));
129  double *wtmp=slepian0(tbp,nwsize);
130  double *work=new double[nfft];
131  for(int k=0;k<nfft;++k)work[k]=0.0;
132  dcopy(nwsize,wtmp,1,work,1);
133  delete [] wtmp;
134  w=ComplexArray(nfft,work);
135  gsl_fft_complex_forward(w.ptr(), 1, nfft, wavetable, workspace);
136  delete [] work;
137  }
138  else if(wavelettype=="none")
139  {
140  /* Prototype code issued an error in this condition, but we accept it
141  here as an option defined by none. We could do this by putting
142  all ones in the w array but using a delta function at zero lage
143  avoids scaling issues for little cost - this assumes this
144  object is created only occassionally and not millions of times */
145  double *r=new double[nfft];
146  for(int k=0;k<nfft;++k) r[k]=0.0;
147  r[0]=1.0;
148  w=ComplexArray(nfft,r);
149  delete [] r;
150  }
151  else
152  {
153  throw MsPASSError(base_error
154  + "illegal value for shaping_wavelet_type="+wavelettype,
155  ErrorSeverity::Invalid);
156  }
157  gsl_fft_complex_wavetable_free (wavetable);
158  gsl_fft_complex_workspace_free (workspace);
159  df=1.0/(dt*((double)nfft));
160  } catch(MsPASSError& err)
161  {
162  cerr <<base_error<<"Something threw an unhandled MsPASSError with this message:"<<endl;
163  err.log_error();
164  cerr << "This is a nonfatal bug that needs to be fixed"<<endl;
165  throw err;
166  } catch(...)
167  {
168  throw;
169  }
170 }
MsPASS implementation of Butterworth filter as processing object.
Definition: Butterworth.h:36
Error thrown when get operators fail.
Definition: Metadata.h:23
int get_int(const std::string key) const override
Definition: Metadata.h:159
std::string get_string(const std::string key) const override
Definition: Metadata.h:213
double get_double(const std::string key) const override
Definition: Metadata.h:135
Base class for error object thrown by MsPASS library routines.
Definition: MsPASSError.h:40
void log_error()
Definition: MsPASSError.h:89

References mspass::utility::Metadata::get_double(), mspass::utility::Metadata::get_int(), mspass::utility::Metadata::get_string(), mspass::utility::MsPASSError::log_error(), and mspass::algorithms::Butterworth::transfer_function().

◆ ShapingWavelet() [2/3]

mspass::algorithms::deconvolution::ShapingWavelet::ShapingWavelet ( const double  fpeak,
const double  dtin,
const int  n 
)

Construct a Ricker wavelet shaping filter with peak frequency fpeak.

175  : wavelet_name("ricker")
176 {
177  nfft=n;
178  dt=dtin;
179  df=1.0/(dt*static_cast<double>(n));
180  double *r;
181  r=rickerwavelet((float)fpeak,(float)dt,nfft);
182  w=ComplexArray(nfft,r);
183  gsl_fft_complex_wavetable *wavetable;
184  gsl_fft_complex_workspace *workspace;
185  wavetable = gsl_fft_complex_wavetable_alloc (nfft);
186  workspace = gsl_fft_complex_workspace_alloc (nfft);
187  gsl_fft_complex_forward(w.ptr(), 1, nfft, wavetable, workspace);
188  gsl_fft_complex_wavetable_free (wavetable);
189  gsl_fft_complex_workspace_free (workspace);
190  delete [] r;
191 }

◆ ShapingWavelet() [3/3]

mspass::algorithms::deconvolution::ShapingWavelet::ShapingWavelet ( const int  npolelo,
const double  f3dblo,
const int  npolehi,
const double  f3dbhi,
const double  dtin,
const int  n 
)

Construct a zero phase Butterworth filter wavelet.

This is the recommended constructor to use for adjustable bandwidth shaping. It is the default for CNR3CDecon.

Parameters
npolelois the number of poles for the low corner
f3dblois the 3db point for the low corner of the passband
nplolehiis the number of poles for the upper corner filter
f3dbhiis the 3db point for the high corner of the passband.
194  : wavelet_name("butterworth")
195 {
196  nfft=n;
197  dt=dtin;
198  df=1.0/(dt*static_cast<double>(n));
199  Butterworth bwf(true,true,true,npolelo,f3dblo,npolehi,f3dbhi,dtin);
200  w=bwf.transfer_function(nfft);
201 }

References mspass::algorithms::Butterworth::transfer_function().

Member Function Documentation

◆ impulse_response()

CoreTimeSeries mspass::algorithms::deconvolution::ShapingWavelet::impulse_response ( )

Return the impulse response of the shaping filter. Expect the result to be symmetric about 0 (i.e. output spans nfft/2 to nfft/2.

270 {
271  try {
272  int nfft=w.size();
273  gsl_fft_complex_wavetable *wavetable;
274  gsl_fft_complex_workspace *workspace;
275  wavetable = gsl_fft_complex_wavetable_alloc (nfft);
276  workspace = gsl_fft_complex_workspace_alloc (nfft);
277  /* We need to copy the current shaping wavelet or the inverse fft
278  * will make it invalid */
279  ComplexArray iwf(w);
280  gsl_fft_complex_inverse(iwf.ptr(), 1, nfft, wavetable, workspace);
281  gsl_fft_complex_wavetable_free (wavetable);
282  gsl_fft_complex_workspace_free (workspace);
283  CoreTimeSeries result(nfft);
284  /* old API
285  result.tref=TimeReferenceType::Relative;
286  result.ns=nfft;
287  result.dt=dt;
288  result.t0 = dt*(-(double)nfft/2);
289  result.live=true;
290  */
291 
292  result.set_tref(TimeReferenceType::Relative);
293  result.set_npts(nfft);
294  result.set_dt(dt);
295  result.set_t0(dt*(-(double)nfft/2));
296  result.set_live();
297  /* Unfold the fft output */
298  int k,shift;
299  shift=nfft/2;
300  // Need this because constructor fills initially with nfft zeros and
301  // we use this approach to unfold the fft output
302  result.s.clear();
303  for(k=0;k<nfft;++k) result.s.push_back(iwf[k].real());
304  result.s=circular_shift(result.s,shift);
305  return result;
306  } catch(...) {
307  throw;
308  };
309 }
Scalar time series data object.
Definition: CoreTimeSeries.h:18

References mspass::seismic::CoreTimeSeries::s, mspass::seismic::CoreTimeSeries::set_dt(), mspass::seismic::BasicTimeSeries::set_live(), mspass::seismic::CoreTimeSeries::set_npts(), mspass::seismic::CoreTimeSeries::set_t0(), and mspass::seismic::BasicTimeSeries::set_tref().

◆ wavelet()

ComplexArray* mspass::algorithms::deconvolution::ShapingWavelet::wavelet ( )
inline

Return a pointer to the shaping wavelet this object defines in the frequency domain.

74  {
75  return &w;
76  };

The documentation for this class was generated from the following files: