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

📄 sufilter.c

📁 su 的源代码库
💻 C
字号:
/* Copyright (c) Colorado School of Mines, 2006.*//* All rights reserved.                       *//* SUFILTER: $Revision: 1.22 $ ; $Date: 2006/11/07 22:58:42 $        */#include "su.h"#include "segy.h"/*********************** self documentation **********************/char *sdoc[] = {"									"," SUFILTER - applies a zero-phase, sine-squared tapered filter		","									"," sufilter <stdin >stdout [optional parameters]         		","									"," Required parameters:                                         		","       if dt is not set in header, then dt is mandatory        	","									"," Optional parameters:							","       f=f1,f2,...             array of filter frequencies(HZ) 	","       amps=a1,a2,...          array of filter amplitudes		","       dt = (from header)      time sampling interval (sec)        	","	verbose=0		=1 for advisory messages		","									"," Defaults:f=.10*(nyquist),.15*(nyquist),.45*(nyquist),.50*(nyquist)	","                        (nyquist calculated internally)		","          amps=0.,1.,...,1.,0.  trapezoid-like bandpass filter		","									"," Examples of filters:							"," Bandpass:   sufilter <data f=10,20,40,50 | ...			"," Bandreject: sufilter <data f=10,20,30,40 amps=1.,0.,0.,1. | ..	"," Lowpass:    sufilter <data f=10,20,40,50 amps=1.,1.,0.,0. | ...	"," Highpass:   sufilter <data f=10,20,40,50 amps=0.,0.,1.,1. | ...	"," Notch:      sufilter <data f=10,12.5,35,50,60 amps=1.,.5,0.,.5,1. |..	",NULL};/* Credits: *      CWP: John Stockwell, Jack Cohen *	CENPET: Werner M. Heigl - added well log support * * Possible optimization: Do assignments instead of crmuls where * filter is 0.0. * * Trace header fields accessed: ns, dt, d1 *//**************** end self doc ***********************************//* Prototype of function used internally */void polygonalFilter(float *f, float *amps,			int npoly, int nfft, float dt, float *filter);#define PIBY2   1.57079632679490#define FRAC0   0.10    /* Ratio of default f1 to Nyquist */#define FRAC1   0.15    /* Ratio of default f2 to Nyquist */#define FRAC2   0.45    /* Ratio of default f3 to Nyquist */#define FRAC3   0.50    /* Ratio of default f4 to Nyquist */#define LOOKFAC 2       /* Look ahead factor for npfao    */#define PFA_MAX 720720  /* Largest allowed nfft           */segy tr;intmain(int argc, char **argv){        register float *rt;     /* real trace                           */        register complex *ct;   /* complex transformed trace            */        float *filter;          /* filter array                         */        float *f;               /* array of filter frequencies		*/        int npoly;              /* .... sizes of f and intfr	        */        float *amps;            /* array of amplitude values		*/        int namps;              /* .... size of amps                    */        int icount,ifs,iamps;   /* loop counting variables              */        float dt;               /* sample spacing                       */        float nyq;              /* nyquist frequency                    */        int nt;                 /* number of points on input trace      */        int nfft;               /* number of points for fft trace       */        int nf;                 /* number of frequencies (incl Nyq)     */	int verbose;		/* flag to get advisory messages	*/	cwp_Bool seismic;	/* is this seismic data?		*/                /* Initialize */        initargs(argc, argv);        requestdoc(1);        /* Get info from first trace */ 	if (!getparint("verbose", &verbose))	verbose=0;        if (!gettr(&tr))  err("can't get first trace");	seismic = ISSEISMIC(tr.trid);	if (seismic) {		if (verbose)	warn("input is seismic data, trid=%d",tr.trid);		dt = ((double) tr.dt)/1000000.0;	}	else {		if (verbose) warn("input is not seismic data, trid=%d",tr.trid);		dt = tr.d1;        }	/* error trapping so that the user can have a default value of dt */	if (!(dt || getparfloat("dt", &dt))) {		dt = .004;		if (verbose) {			warn("neither dt nor d1 are set, nor is dt getparred!");			warn("assuming .004 sec sampling!");		}	}        nt = tr.ns;        nyq = 0.5/dt;        /* Set up FFT parameters */        nfft = npfaro(nt, LOOKFAC * nt);        if (nfft >= SU_NFLTS || nfft >= PFA_MAX)                err("Padded nt=%d -- too big", nfft);        nf = nfft/2 + 1;        /* Get frequencies that define the filter */        if ((npoly = countparval("f"))!=0) {                f = ealloc1float(npoly);                getparfloat("f",f);        } else {                npoly = 4;                f = ealloc1float(npoly);                f[0] = FRAC0 * nyq;                f[1] = FRAC1 * nyq;                f[2] = FRAC2 * nyq;                f[3] = FRAC3 * nyq;        }	/* Check f values */	if(npoly < 2) warn("Only %d value defining filter",npoly);        for(ifs=0; ifs < npoly-1; ++ifs)		if(f[ifs] < 0.0 || f[ifs] > f[ifs+1])                                err("Bad filter parameters");		/* Get 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=0; iamps<namps; ++iamps)               		amps[iamps]=1.;				amps[0]=0.; amps[namps-1]=0.;        }	if (!(namps==npoly)) 		err("number of f values must = number of amps values");                /* Check amps values */        for(iamps = 0, icount=0; iamps < namps ; ++iamps) {		if( amps[iamps] > 0. ) ++icount;                if( amps[iamps] < 0.) err("amp 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 fft arrays */        rt   = ealloc1float(nfft);        ct   = ealloc1complex(nf);        filter = ealloc1float(nf);	/* Build the polygonal filter filter[]*/	polygonalFilter(f,amps,npoly,nfft,dt,filter);        /* Main loop over traces */        do {                register int i;                /* Load trace into rt (zero-padded) */                memcpy((void *) rt, (const void *) tr.data, nt*FSIZE);                memset((void *) (rt + nt), 0 , (nfft-nt)*FSIZE);                /* FFT, filter, inverse FFT */                pfarc(1, nfft, rt, ct);                for (i = 0; i < nf; ++i)  ct[i] = crmul(ct[i], filter[i]);                pfacr(-1, nfft, ct, rt);                /* Load traces back in, recall filter had nfft factor */                for (i = 0; i < nt; ++i)  tr.data[i] = rt[i];                puttr(&tr);        } while (gettr(&tr));        return(CWP_Exit());}void polygonalFilter(float *f, float *amps, int npoly,				int nfft, float dt, float *filter)/*************************************************************************polygonalFilter -- polygonal filter with sin^2 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 fftOutput:filter		array[nfft] filter values**************************************************************************Notes: Filter is to be applied in the frequency domain**************************************************************************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*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*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 + -