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.
19 {
20 const string base_error("ShapingWavelet object constructor: ");
21 try {
22
23
24 if (nfftin > 0)
25 this->nfft = nfftin;
26 else {
27 try {
28 nfft = md.
get_int(
"operator_nfft");
29 } catch (MetadataGetError &mderr) {
30 throw MsPASSError(base_error +
31 "Called constructor with nfft=0 but parameter "
32 "with key=operator_nfft is not in parameter file",
33 ErrorSeverity::Invalid);
34 }
35 }
36
37
38
39 gsl_fft_complex_wavetable *wavetable;
40 gsl_fft_complex_workspace *workspace;
41 wavetable = gsl_fft_complex_wavetable_alloc(nfft);
42 workspace = gsl_fft_complex_workspace_alloc(nfft);
43 string wavelettype = md.
get_string(
"shaping_wavelet_type");
44 wavelet_name = wavelettype;
46 double *r;
47 if (wavelettype == "gaussian") {
48 float fpeak = md.
get_double(
"shaping_wavelet_frequency");
49
50 r = gaussian(fpeak, (float)dt, nfft);
51 w = ComplexArray(nfft, r);
52 gsl_fft_complex_forward(w.ptr(), 1, nfft, wavetable, workspace);
53 delete[] r;
54 }
55
56
57
58
59 else if (wavelettype == "ricker") {
60 float fpeak = (float)md.
get_double(
"shaping_wavelet_frequency");
61
62 r = rickerwavelet(fpeak, (float)dt, nfft);
63
64
65
66 w = ComplexArray(nfft, r);
67 gsl_fft_complex_forward(w.ptr(), 1, nfft, wavetable, workspace);
68 delete[] r;
69 } else if (wavelettype == "butterworth") {
70 double f3db_lo, f3db_hi;
73 int npoles_lo, npoles_hi;
74 npoles_lo = md.
get_int(
"npoles_lo");
75 npoles_hi = md.
get_int(
"npoles_hi");
76 Butterworth bwf(true, true, true, npoles_lo, f3db_lo, npoles_hi, f3db_hi,
77 this->dt);
78 w = bwf.transfer_function(this->nfft);
79 }
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107 else if ((wavelettype == "slepian") || (wavelettype == "Slepian")) {
108 double tbp = md.
get_double(
"time_bandwidth_product");
109 double target_pulse_width = md.
get_double(
"target_pulse_width");
110
111 if (target_pulse_width > (nfft / 4) || (target_pulse_width < tbp)) {
112 stringstream ss;
113 ss << "ShapingWavelet Metadata constructor: bad input parameters for "
114 "Slepian shaping wavelet"
115 << endl
116 << "Specified target_pulse_width of " << target_pulse_width
117 << " samples" << endl
118 << "FFT buffer size=" << nfft
119 << " and time bandwidth product=" << tbp << endl
120 << "Pulse width should be small fraction of buffer size but ge than "
121 "tbp"
122 << endl;
123 throw MsPASSError(ss.str(), ErrorSeverity::Invalid);
124 }
125 double c = tbp / target_pulse_width;
126 int nwsize = round(c * (static_cast<double>(nfft)));
127 double *wtmp = slepian0(tbp, nwsize);
128 double *work = new double[nfft];
129 for (int k = 0; k < nfft; ++k)
130 work[k] = 0.0;
131 dcopy(nwsize, wtmp, 1, work, 1);
132 delete[] wtmp;
133 w = ComplexArray(nfft, work);
134 gsl_fft_complex_forward(w.ptr(), 1, nfft, wavetable, workspace);
135 delete[] work;
136 } else if (wavelettype == "none") {
137
138
139
140
141
142 double *r = new double[nfft];
143 for (int k = 0; k < nfft; ++k)
144 r[k] = 0.0;
145 r[0] = 1.0;
146 w = ComplexArray(nfft, r);
147 delete[] r;
148 } else {
149 throw MsPASSError(
150 base_error + "illegal value for shaping_wavelet_type=" + wavelettype,
151 ErrorSeverity::Invalid);
152 }
153 gsl_fft_complex_wavetable_free(wavetable);
154 gsl_fft_complex_workspace_free(workspace);
155 df = 1.0 / (dt * ((double)nfft));
156 } catch (MsPASSError &err) {
157 cerr << base_error
158 << "Something threw an unhandled MsPASSError with this message:"
159 << endl;
160 err.log_error();
161 cerr << "This is a nonfatal bug that needs to be fixed" << endl;
162 throw err;
163 } catch (...) {
164 throw;
165 }
166}