⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sukfilter.c

📁 二维FK滤波程序的源代码
💻 C
字号:
/* Copyright (c) Colorado School of Mines, 2008.*//* All rights reserved.                       *//* SUKFILTER: $Revision: 1.6 $ ; $Date: 2006/11/07 22:58:42 $	*/#include "su.h"#include "segy.h"#include "header.h"/*********************** self documentation **********************/char *sdoc[] = {" 									"," SUKFILTER - radially symmetric K-domain, sin^2-tapered, polygonal	","		  filter						"," 									","     sukfilter <infile >outfile [optional parameters]			","									"," Optional parameters:							"," k=val1,val2,...	array of K filter wavenumbers			"," amps=a1,a2,...	array of K filter amplitudes			"," d1=tr.d1 or 1.0	sampling interval in first (fast) dimension	"," d2=tr.d1 or 1.0	sampling interval in second (slow) dimension	","									"," Defaults:								"," k=.10*(nyq),.15*(nyq),.45*(nyq),.50*(nyq)				"," amps=0.,1.,...,1.,0.  trapezoid-like bandpass filter			","									"," The nyquist wavenumbers, nyq=sqrt(nyq1^2 + nyq2^2) is  computed	"," internally.								","									"," Notes:								"," The filter is assumed to be symmetric, to yield real output.		","									"," Because the data are assumed to be purely spatial (i.e. non-seismic), "," the data are assumed to have trace id (30), corresponding to (z,x) data","									"," The relation: w = 2 pi F is well known for frequency, but there	"," doesn't seem to be a commonly used letter corresponding to F for the	"," spatial conjugate transform variables.  We use K1 and K2 for this.	"," More specifically we assume a phase:					","		-i(k1 x1 + k2 x2) = -2 pi i(K1 x1 + K2 x2).		"," and K1, K2 define our respective wavenumbers.				"," 									",NULL};/* Credits: *     CWP: John Stockwell, June 1997. * * Trace header fields accessed: ns, d1, d2 *//**************** end self doc ***********************************//* definitions */#define PFA_MAX	720720	/* Largest allowed nfft		  */#define LOOKFAC 2	/* look factor			  */#define FRAC0   0.10    /* Ratio of default k1 to Nyquist */#define FRAC1   0.15    /* Ratio of default k2 to Nyquist */#define FRAC2   0.45    /* Ratio of default k3 to Nyquist */#define FRAC3   0.50    /* Ratio of default k4 to Nyquist */#define N_PHI	3	/* arbitrary number of phi values *//* prototype of function used internally */void polygonalFilter(float *f, float *amps, int npoly,				int nfft, float dt, float *filter);segy tr;int main(int argc, char **argv){	int nx1,nx2;		/* numbers of samples			*/	float dx1,dx2,dx;	/* sampling intervals			*/	int verbose;		/* verbose flag				*/               float nyq;		/* K Nyquist wavenumber			*/	int npoly;		/* number of points defining k filter	*/	int namps;		/* number of amps defining k filter	*/        float *k;		/* wavenumber values defining k filter	*/	float **kphi;		/* k,phi array				*/	int nphi=1;		/* number of phi values for polartorect */	int iphi;		/* phi values				*/        float *amps;		/* amplitude values defining k filter	*/	float *kfilt;		/* k wavenumber filter			*/	float **karray;		/* array of filter values 		*/	float **kfilter;	/* wavenumber filter 			*/	int ix1,ix2;		/* sample indices			*/	int nx1fft,nx2fft,nxfft;/* dimensions after padding for FFT	*/	int nK1,nK2,nK;		/* transform (output) dimensions	*/        int ik;			/* k counter				*/        int ik1;		/* k1 counter				*/        int ik2;		/* k2 counter				*/        int iamps;		/* amplitude counter			*/        int icount;		/* zero counter				*/	register complex **ct;	/* complex FFT workspace		*/	register float **rt;	/* float FFT workspace			*/	FILE *tracefp;		/* temp file to hold traces		*/	FILE *hfp;		/* temp file to hold trace headers	*/	/* Hook up getpar to handle the parameters */	initargs(argc,argv);	requestdoc(1);	/* Get info from first trace */ 	if (!gettr(&tr))  err("can't get first trace");	if (tr.trid != TRID_DEPTH)				warn("tr.trid = %d",tr.trid);	nx1 = tr.ns;	/* get sampling intervals */	if (!getparfloat("d1", &dx1)) {		if (tr.d1) { /* is dt field set? */			dx1 = (float) tr.d1;		} else { /* d1 not set, assume 1.0 */			dx1 = 1.0;			warn("tr.d1 not set, assuming d1=1.0");		}	}	if (!getparfloat("d2",&dx2)) {		if (tr.d2) { /* is d2 field set? */			dx2 = tr.d2;		} else {			dx2 = 1.0;			warn("tr.d2 not set, assuming d2=1.0");		}	}	dx = NINT(sqrt(dx1*dx1 + dx2*dx2));	if (!getparint("verbose",&verbose))	verbose = 1;	/* Compute Nyquist wavenumber */	nyq = 0.5/dx;	/* Store traces in tmpfile while getting a count */	tracefp = etmpfile();	hfp = etmpfile();	nx2 = 0;	do { 		++nx2;		efwrite(&tr, HDRBYTES, 1, hfp);		efwrite(tr.data, FSIZE, nx1, tracefp);	} while (gettr(&tr));	/* Determine lengths for prime-factor FFTs */	nx1fft = npfaro(nx1, LOOKFAC*nx1);	nx2fft = npfa(nx2);	if (nx1fft >= SU_NFLTS || nx1fft >= PFA_MAX)		err("Padded nx1=%d--too big",nx1fft);	if (nx2fft >= PFA_MAX)		err("Padded nx2=%d--too big",nx2fft);	/* Determine number of wavenumbers in K1 and K2 */	nK1 = nx1fft/2 + 1;	nK2 = nx2fft/2 + 1;	nK = NINT(sqrt(nK1*nK1 + nK2*nK2));	nxfft = 2*( nK - 1); /* faked for polygonal filter in k */        /* Get wavenumbers that define the k filter */        if ((npoly = countparval("k"))!=0) {                k = ealloc1float(npoly);                getparfloat("k",k);        } else {                npoly = 4;                k = ealloc1float(npoly);                k[0] = FRAC0 * nyq;                k[1] = FRAC1 * nyq;                k[2] = FRAC2 * nyq;                k[3] = FRAC3 * nyq;        }	/* Check k values */	if(npoly < 2) warn("Only %d value defining filter",npoly);        for(ik=0; ik < npoly-1; ik++)		if(k[ik] < 0.0 || k[ik] > k[ik+1])                                err("Bad filter parameters");	/* Get k filter amplitude values */        if ((namps = countparval("amps"))!=0) {                amps = ealloc1float(namps);                getparfloat("amps",amps);        } else {                namps = npoly;                amps = ealloc1float(namps);		/* default is a trapezoidal bandpass filter */		for(iamps=1; iamps<namps-1; iamps++) amps[iamps]=1.;		amps[0]=0.;		amps[namps-1]=0.;        }	if (!(namps==npoly)) 		err("number of k values must = number of amps values");        /* Check amps values */        for(iamps = 0, icount=0; iamps < namps ; iamps++) {		icount+=amps[iamps];                if( amps[iamps] < 0.) err("amps values must be positive");        }        if (icount==0) err("All amps values are zero");        for(iamps = 0, icount=0; iamps < namps-1 ; ++iamps) {			if(!(amps[iamps]==amps[iamps+1])) ++icount;	}        if (icount==0) warn("All amps values are the same");	/* Allocate space */	rt = ealloc2float(nx1fft, nx2fft);	ct = ealloc2complex(nK1,nx2fft);	karray = ealloc2float(nx1fft,nx2fft);	kfilter = ealloc2float(nx1fft,nx2fft);	kfilt = ealloc1float(nK);	kphi = ealloc2float(1,nK);	/* Zero all arrays */	memset((void *) rt[0], 0, nx1fft*nx2fft*FSIZE);	memset((void *) kfilter[0], 0, nx1fft*nx2fft*FSIZE);	memset((void *) ct[0], 0, nK1*nx2fft*sizeof(complex));	memset((void *) kfilt, 0, nK*FSIZE);	memset((void *) kphi[0], 0, nK*FSIZE);	/* Build Filter */	polygonalFilter(k,amps,npoly,nxfft,dx,kfilt);	/* Build k,phi filter */	for (iphi=0; iphi<1 ; ++iphi)		for (ik=0; ik<nK; ++ik)			kphi[ik][iphi] = kfilt[ik]*kfilt[ik];	/* convert polar to rectangular coordinates */	polartorect(nphi,0,0,nK,1,0,			kphi,nx1fft,1,-nK1,nx2fft,			1,-nK2,karray);	/* positive k1, positive k2 */	for (ik2=0; ik2<nK2; ++ik2) 		for (ik1=0; ik1<nK1; ++ik1) 			kfilter[ik2][ik1]=karray[nK2-1-ik2][nK1-1-ik1];	/* positive k1, negative k2 */	for (ik2=nK2; ik2<nx2fft; ++ik2) 		for (ik1=0; ik1<nK1; ++ik1) 			kfilter[ik2][ik1]=karray[ik2-nK2][nK1-1-ik1];	/* Load traces into fft arrays and close tmpfile */	rewind(tracefp);	for (ix2=0; ix2<nx2; ++ix2)		efread(rt[ix2], FSIZE, nx1, tracefp);	efclose(tracefp);		/* Fourier transform dimension 1 */	pfa2rc(-1,1,nx1fft,nx2,rt[0],ct[0]);	/* Fourier transform dimension 2 */	pfa2cc(-1,2,nK1,nx2fft,ct[0]);	/* Apply filter */	for (ik2=0; ik2 < nx2fft; ++ik2)		for (ik1=0; ik1 < nK1; ++ik1)			ct[ik2][ik1] = crmul(ct[ik2][ik1], kfilter[ik2][ik1]);	/* Inverse Fourier transform dimension 2 */	pfa2cc(1,2,nK1,nx2fft,ct[0]);		/* Inverse Fourier transform dimension 1 */	pfa2cr(1,1,nx1fft,nx2,ct[0],rt[0]);	erewind(hfp);	/* Output filtered traces */	for (ix2=0; ix2 < nx2; ++ix2) { 		efread(&tr, HDRBYTES, 1, hfp);		for (ix1=0; ix1 <nx1 ; ++ix1) 			tr.data[ix1] = rt[ix2][ix1];		puttr(&tr);	}	efclose(hfp);	return(CWP_Exit());}void polygonalFilter(float *f, float *amps, int npoly, 				int nfft, float dt, float *filter)/*************************************************************************polygonalFilter -- polygonal filter with sin tapering**************************************************************************Input:f		array[npoly] of frequencies defining the filteramps		array[npoly] of amplitude valuesnpoly		size of input f and amps arraysdt		time sampling intervalnfft		number of points in the fftpow		power flag, use pow=1 for 1D usage, =2 for 2DOutput:filter		array[nfft] filter values**************************************************************************Notes: Filter is to be applied in the frequency domainAlso, this is not exactly the same filter that is used in "sufilter".That filter is sin^2. This done because the filter is squared inits application to make the amplitudes come out right.**************************************************************************Author:  CWP: John Stockwell   1992*************************************************************************/#define PIBY2   1.57079632679490{        int *intfr;             /* .... integerizations of f		*/        int icount,ifs;		/* loop counting variables              */	int taper=0;		/* flag counter				*/        int nf;                 /* number of frequencies (incl Nyq)     */        int nfm1;               /* nf-1                                 */        float onfft;            /* reciprocal of nfft                   */        float df;               /* frequency spacing (from dt)          */	intfr=alloc1int(npoly);        nf = nfft/2 + 1;        nfm1 = nf - 1;        onfft = 1.0 / nfft;        /* Compute array of integerized frequencies that define the filter*/        df = onfft / dt;        for(ifs=0; ifs < npoly ; ++ifs) {                intfr[ifs] = NINT(f[ifs]/df);                if (intfr[ifs] > nfm1) intfr[ifs] = nfm1;        }	/* Build filter, with scale, and taper specified by amps[] values*/	/* Do low frequency end first*/	for(icount=0; icount < intfr[0] ; ++icount) 		filter[icount] = amps[0] * onfft;	/* now do the middle frequencies */	for(ifs=0 ; ifs<npoly-1 ; ++ifs){	   if(amps[ifs] < amps[ifs+1]) {			++taper;		for(icount=intfr[ifs]; icount<=intfr[ifs+1]; ++icount) {		    float c = PIBY2 / (intfr[ifs+1] - intfr[ifs] + 2);		    float s = sin(c*(icount - intfr[ifs] + 1));		    float adiff = amps[ifs+1] - amps[ifs];		    filter[icount] = (amps[ifs] + adiff*s) * onfft;		}	   } else if (amps[ifs] > amps[ifs+1]) {			++taper;		for(icount=intfr[ifs]; icount<=intfr[ifs+1]; ++icount) {			   float c = PIBY2 / (intfr[ifs+1] - intfr[ifs] + 2);                	   float s = sin(c*(intfr[ifs+1] - icount + 1));			   float adiff = amps[ifs] - amps[ifs+1];                	   filter[icount] = (amps[ifs+1] + adiff*s) * onfft;		  }	   } else 		if(!(taper)){		for(icount=intfr[ifs]; icount <= intfr[ifs+1]; ++icount)		   	   filter[icount] = amps[ifs] * onfft;		} else {		for(icount=intfr[ifs]+1; icount <= intfr[ifs+1]; ++icount)		   	   filter[icount] = amps[ifs] * onfft;		}	}	/* finally do the high frequency end */	for(icount=intfr[npoly-1]+1; icount<nf; ++icount){		filter[icount] = amps[npoly-1] * onfft;	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -