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

📄 sufilter.c

📁 seismic software,very useful
💻 C
字号:
/* SUFILTER: $Revision: 1.2 $ ; $Date: 92/10/22 14:15:45 $        *//*---------------------------------------------------------------------- * Copyright (c) Colorado School of Mines, 1990. * All rights reserved. * * This code is part of SU.  SU stands for Seismic Unix, a processing line * developed at the Colorado School of Mines, partially based on Stanford * Exploration Project (SEP) software.  Inquiries should be addressed to: * *  Jack K. Cohen, Center for Wave Phenomena, Colorado School of Mines, *  Golden, CO 80401  (jkc@dix.mines.colorado.edu) *---------------------------------------------------------------------- */void buildpolyfilt(float *f, float *amps, int npoly, int nfft, 					float dt, float *filter);#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 rate (sec)        	","									"," 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};/**************** end self doc ***********************************//* Credits: *      CWP: John Stockwell, Jack Cohen * * Possible optimization: Do assignments instead of crmuls where * filter is 0.0. */#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;main(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 *intfr;             /* .... integerizations of f		*/        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 taper=0;		/* flag counter				*/        int nf;                 /* number of frequencies (incl Nyq)     */        float onfft;            /* reciprocal of nfft                   */        float df;               /* frequency spacing (from dt)          */                /* Initialize */        initargs(argc, argv);        requestdoc(1);        /* Get info from first trace */         if (!gettr(&tr))  err("can't get first trace");        if (tr.trid && tr.trid != TREAL)                err("input is not seismic data, trid=%d", tr.trid);        nt = tr.ns;        if (!getparfloat("dt", &dt))    dt = (float) tr.dt/1000000.0;        if (!dt) err("dt field is zero and not getparred");        nyq = 0.5/dt;        /* Set up FFT parameters */        nfft = npfaro(nt, LOOKFAC * nt);        if (nfft >= MIN(SU_NFLTS, PFA_MAX))                err("Padded nt=%d -- too big", nfft);        nf = nfft/2 + 1;        onfft = 1.0 / nfft;        /* Get frequencies that define the filter */        if ((npoly = countparval("f"))!=0) {                f = ealloc1float(npoly);                intfr = ealloc1int(npoly);                getparfloat("f",f);        } else {                npoly = 4;                f = ealloc1float(npoly);                intfr = ealloc1int(npoly);                f[0] = FRAC0 * nyq;                f[1] = FRAC1 * nyq;                f[2] = FRAC2 * nyq;                f[3] = FRAC3 * nyq;        }	/* Check f values */	if(npoly < 3) warn("Only %d value(s) 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++) {		icount+=amps[iamps];                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[]*/	buildpolyfilt(f,amps,npoly,nfft,dt,filter);        /* Main loop over traces */        do {                register int i;                /* Load trace into rt (zero-padded) */                memcpy((char*)rt, (char*)tr.data, nt*FSIZE);                bzero(rt + nt, (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 EXIT_SUCCESS;}/* BUILDPOLYFILT  -- Build a POLYgonal FILTer with sin^2 tapering *			--filter to be applied in the frequency domain *Credits:   CWP: John Stockwell *	float *f		array of frequencies defining the filter *      float *amps;            array of amplitude values *      int npoly;              size of f/amps *      float dt;               sampling rate *      int nfft;               number of points in the fft *      float *filter;          array filter values */void buildpolyfilt(float *f, float *amps, int npoly, int nfft, 					float dt, float *filter)#define PIBY2   1.57079632679490{        int *intfr;             /* .... integerizations of f		*/        int icount,ifs,iamps;   /* loop counting variables              */        float nyq;              /* nyquist frequency                    */        int nt;                 /* number of points on input trace      */	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 + -