diff --git a/utils/kxwfilter.c b/utils/kxwfilter.c new file mode 100644 index 0000000000000000000000000000000000000000..8689028abeb8d60ecb5dbfe7d455f04057ffc736 --- /dev/null +++ b/utils/kxwfilter.c @@ -0,0 +1,131 @@ +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <genfft.h> + +#define ISODD(n) ((n) & 01) +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#define MIN(x,y) ((x) < (y) ? (x) : (y)) + +void kxwfilt(complex *data, float k, float dx, int nkx, float a1, float perc); + +void kxwfilter(float *data, int nt, int nx, float dt, float dx, float fmin, float fmax, float angle, float cp, float perc) +{ + int ntfft, nfreq, nkx, ix, it, iomin, iomax, xorig, iom, ikx; + float df, dkx, deltom, omin, omax, kp, om; + float *pdata; + complex *cdata; + + ntfft = optncr(nt); + nfreq = ntfft/2+1; + nkx = optncc(2*nx); + + df = 1.0/((float)ntfft*dt); + dkx = 2.0*M_PI/(nkx*dx); + deltom = 2.*M_PI*df; + omin = 2.*M_PI*fmin; + omax = 2.*M_PI*fmax; + + iomin = (int)MIN((omin/deltom), (nfreq-1)); + iomin = MAX(iomin, 1); + iomax = MIN((int)(omax/deltom), (nfreq-1)); + + pdata = (float *)calloc(ntfft*nkx,sizeof(float)); + cdata = (complex *)malloc(nfreq*nkx*sizeof(complex)); + + /* copy input data into extended arrays with padded zeroes */ + for (ix=0; ix<nx; ix++) { + memcpy(&pdata[ix*ntfft],&data[ix*nt],nt*sizeof(float)); + } + + /* transform from t-x to kx-w */ + xorig = nkx/2; + xt2wkx(pdata, cdata, ntfft, nkx, ntfft, nkx, xorig); + + + for (iom = iomin; iom <= iomax; iom++) { + om = iom*deltom; + kp = om/cp; + + kxwfilt(&cdata[iom*nkx], kp, dx, nkx, angle, perc); + } + + /* transform back to t-x */ + wkx2xt(cdata, pdata, ntfft, nkx, nkx, ntfft, xorig); + + /* reduce array to nt samples nx traces */ + for (ix=0; ix<nx; ix++) { + memcpy(&data[ix*nt],&pdata[ix*ntfft],nt*sizeof(float)); + } + + free(pdata); + free(cdata); + + return; +} + + +void kxwfilt(complex *data, float k, float dx, int nkx, float a1, float perc) +{ + int ikx, ik1, ik2, ntap; + float kxnyq, dkx, kxfmax, kfilt; + float kpos, band, li, *filter; + + kxnyq = M_PI/dx; + dkx = 2.0*M_PI/(nkx*dx); + if (a1 > 90.0) kpos = kxnyq; + else kpos = k*sin(M_PI*a1/180.0); + + filter = (float *)malloc(nkx*sizeof(float)); + + band = fabs(2*kpos); + ntap = (int)fabs((int)(perc*band/dkx)); + kfilt = fabs(dkx*ntap); + + if (perc > 0) { + if (kpos+kfilt < kxnyq) { + kxfmax = kpos+kfilt; + } + else { + kxfmax = kxnyq; + ntap = (int)(0.15*nkx/2); + } + } + else { + kxfmax = MIN(kpos, kxnyq); + } + + ik1 = (int)(kxfmax/dkx); + ik2 = ik1 - ntap; + + if (perc < -0.5 || perc > 1.0) { + if (kpos > 0.85*kxnyq) { + kpos = 0.85*kxnyq; + } + ik1 = nkx/2-1; + ik2 = (int)(kpos/dkx); + } + + li = 1.0/(ik1-ik2); + for (ikx = 0; ikx < ik2; ikx++) + filter[ikx] = 1.0; + for (ikx = ik2; ikx < ik1; ikx++) + filter[ikx] = 0.5*(cos(M_PI*(ikx-ik2)*li)+1); + for (ikx = ik1; ikx <= nkx/2; ikx++) + filter[ikx] = 0.0; + + for (ikx = 0; ikx <= (nkx/2); ikx++) { + data[ikx].r *= filter[ikx]; + data[ikx].i *= filter[ikx]; + } + for (ikx = (nkx/2+1); ikx < nkx; ikx++) { + data[ikx].r *= filter[nkx-ikx]; + data[ikx].i *= filter[nkx-ikx]; + } + + free(filter); + return; +} + +