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

📄 sugabor.c

📁 su 的源代码库
💻 C
字号:
/* Copyright (c) Colorado School of Mines, 2006.*//* All rights reserved.                       *//* SUGABOR: $Revision: 1.18 $ ; $Date: 2006/11/07 23:09:09 $	*/#include "su.h"#include "segy.h"/*********************** self documentation **********************/char *sdoc[] = {"									"," SUGABOR -  Outputs a time-frequency representation of seismic data via","	        the Gabor transform-like multifilter analysis technique ","		presented by Dziewonski, Bloch and  Landisman, 1969.	","									","    sugabor <stdin >stdout [optional parameters]			","									"," Required parameters:					 		","	if dt is not set in header, then dt is mandatory		","									"," Optional parameters:							","	dt=(from header)	time sampling interval (sec)		","	fmin=0			minimum frequency of filter array (hz)	","	fmax=NYQUIST 		maximum frequency of filter array (hz)	","	beta=3.0		ln[filter peak amp/filter endpoint amp]	","	band=.05*NYQUIST	filter bandwidth (hz) 			","	alpha=beta/band^2	filter width parameter			","	verbose=0		=1 supply additional info		","	holder=0		=1 output Holder regularity estimate	","				=2 output linear regularity estimate	","									"," Notes: This program produces a muiltifilter (as opposed to moving window)"," representation of the instantaneous amplitude of seismic data in the	"," time-frequency domain. (With Gaussian filters, moving window and multi-"," filter analysis can be shown to be equivalent.)			","									"," An input trace is passed through a collection of Gaussian filters	"," to produce a collection of traces, each representing a discrete frequency"," range in the input data. For each of these narrow bandwidth traces, a "," quadrature trace is computed via the Hilbert transform. Treating the narrow"," bandwidth trace and its quadrature trace as the real and imaginary parts"," of a \"complex\" trace permits the \"instantaneous\" amplitude of each"," narrow bandwidth trace to be compute. The output is thus a representation"," of instantaneous amplitude as a function of time and frequency.	","									"," Some experimentation with the \"band\" parameter may necessary to produce"," the desired time-frequency resolution. A good rule of thumb is to run "," sugabor with the default value for band and view the image. If band is"," too big, then the t-f plot will consist of stripes parallel to the frequency"," axis. Conversely, if band is too small, then the stripes will be parallel"," to the time axis. 							","									"," Caveat:								"," The Gabor transform is not a wavelet transform, but rather are sharp	"," frame basis. However, it is nearly a Morlet continuous wavelet transform"," so the concept of Holder regularity may have some meaning. If you are	"," computing Holder regularity of, say, a migrated seismic section, then"," set band to 1/3 of the frequency band of your data.			","									"," Examples:								","    suvibro | sugabor | suximage					","    suvibro | sugabor | suxmovie n1= n2= n3= 				","     (because suxmovie scales it's amplitudes off of the first panel,  ","      may have to experiment with the wclip and bclip parameters	","    suvibro | sugabor | supsimage | ... ( your local PostScript utility)","									",NULL};/* Credits: * *	CWP: John Stockwell, Oct 1994 *      CWP: John Stockwell Oct 2004, added holder=1 option * Algorithm: * * This programs takes an input seismic trace and passes it * through a collection of truncated Gaussian filters in the frequency * domain. * * The bandwidth of each filter is given by the parameter "band". The * decay of these filters is given by "alpha", and the number of filters * is given by nfilt = (fmax - fmin)/band. The result, upon inverse * Fourier transforming, is that nfilt traces are created, with each * trace representing a different frequency band in the original data. * * For each of the resulting bandlimited traces, a quadrature (i.e. pi/2 * phase shifted) trace is computed via the Hilbert transform. The  * bandlimited trace constitutes a "complex trace", with the bandlimited * trace being the "real part" and the quadrature trace being the  * "imaginary part".  The instantaneous amplitude of each bandlimited * trace is then computed by computing the modulus of each complex trace. * (See Taner, Koehler, and Sheriff, 1979, for a discussion of complex * trace analysis. * * The final output for a given input trace is a map of instantaneous * amplitude as a function of time and frequency. * * This is not a wavelet transform, but rather a redundant frame * representation. * * References: 	Dziewonski, Bloch, and Landisman, 1969, A technique *		for the analysis of transient seismic signals, *		Bull. Seism. Soc. Am., 1969, vol. 59, no.1, pp.427-444. * *		Taner, M., T., Koehler, F., and Sheriff, R., E., 1979, *		Complex seismic trace analysis, Geophysics, vol. 44, *		pp.1041-1063. * * 		Chui, C., K.,1992, Introduction to Wavelets, Academic *		Press, New York. * * Trace header fields accessed: ns, dt, trid, ntr * Trace header fields modified: tracl, tracr, d1, f2, d2, trid, ntr *//**************** end self doc ***********************************//* Prototype of function used internally */static void gaussianFilter(float fcent, float dt,			int nfft, float alpha, float  band, float *filter);/* constants used internally */#define FRAC0   0.0	/* Ratio of default fmin to Nyquist */#define FRAC1   1.0	/* Ratio of default fmax to Nyquist */#define FRAC2   0.05	/* Ratio of default band to Nyquist */#define BETA	3.0	/* Default value of beta */#define LOOKFAC 2	/* Look ahead factor for npfao	*/#define PFA_MAX 720720  /* Largest allowed nfft	   *//* global SEGY declaration */segy tr;intmain(int argc, char **argv){	register float *rt;	/* real trace				*/	register float *qt;	/* real quadrature trace		*/	register complex *ct;   /* complex transformed trace		*/	register complex *fct;  /* filtered complex transformed trace	*/	float *filter;		/* filter array				*/	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)	*/	cwp_Bool seismic;	/* is this seismic data?		*/	int ntr;		/* number of traces 			*/	int nfilt;		/* number of filters 			*/	int tracr=0;		/* tracr counter			*/	int verbose=0;		/* verbose flag				*/	int holder=0;		/* holder flag				*/	float fcent;		/* center frequency of filters		*/	float fmin;		/* minimum frequency to window		*/	float fmax;		/* maximum frequency to window		*/	float band;		/* frequency bandwidth of filters	*/	float alpha;		/* filter bandwidth parameter		*/	float beta;		/* ln[ filter peak amp/ filter end amp] */	float **tmpdata=NULL;	/* temporary data storage */		/* Initialize */	initargs(argc, argv);	requestdoc(1);	/* Get info from first trace */ 	if (!gettr(&tr))  err("can't get first trace");	seismic = ISSEISMIC(tr.trid);	ntr = tr.ntr;			if (!seismic)		warn("input is not seismic data, trid=%d", tr.trid);	nt = tr.ns;	if (!getparfloat("dt", &dt))	dt = ((double) 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 >= SU_NFLTS || nfft >= PFA_MAX)		err("Padded nt=%d -- too big", nfft);	nf = nfft/2 + 1;		/* Get parameters */	if (!getparint("verbose", &verbose))	verbose=0;	if (!getparint("holder", &holder))	holder=0;	if (!getparfloat("fmin", &fmin))	fmin = FRAC0*nyq;	if (!getparfloat("fmax", &fmax))	fmax = FRAC1*nyq;	if (!getparfloat("band", &band))	band = FRAC2*nyq;	if (!getparfloat("beta", &beta))	beta = BETA;	if (!getparfloat("alpha",&alpha))	alpha = beta/(band*band);	/* Compute number of filters */	nfilt = NINT( (fmax - fmin) / band );	if (verbose){		warn("            alpha = %f",alpha);		warn("             beta = %f",beta);		warn("             band = %f",band);		warn("number of filters = %d",nfilt);	}	/* Allocate fft arrays */	rt   = ealloc1float(nfft);	qt   = ealloc1float(nfft);	ct   = ealloc1complex(nf);	fct   = ealloc1complex(nf);	filter = ealloc1float(nf);	tmpdata = ealloc2float(nt,nfft);	/* Main loop over traces */	do {		register int i,j;		/* 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);		tracr =0;		/* Loop over filter center frequencies */		for (i = 0, fcent=fmin; i < nfilt; ++i, fcent+=band) {			/* compute Gaussian filter */			gaussianFilter(fcent, dt, nfft, alpha, band, filter);			/* apply filter */			for (j = 0; j < nf; ++j) 				 fct[j] = crmul(ct[j], filter[j]);			/* inverse fourier transform */			pfacr(-1, nfft, fct, rt);			/* construct quadrature trace via hilbert transform */			hilbert(nt, rt, qt);			if (!holder) {				/* compute instantaneous amplitude */				for (j = 0; j < nt ; ++j) 					tr.data[j] = sqrt(rt[j]*rt[j] + qt[j]*qt[j]);				tr.tracr = ++tracr;				tr.sx = tr.tracl;				tr.gx = tr.tracr;				tr.d1 = dt;				tr.f2 = fmin;				tr.d2 = band;				tr.trid = AMPLITUDE; 				tr.ntr = ntr*nfilt;				puttr(&tr); /* output time-freq panels */			} else {				/* compute instantaneous amplitude */				for (j = 0; j < nt ; ++j) 					tmpdata[j][i] = sqrt(rt[j]*rt[j] + qt[j]*qt[j]);			}		}		if (holder) { /* compute the Holder regularity traces */			float *x;			float *y;			float coeff[4];				x = ealloc1float(nfilt);			y = ealloc1float(nfilt);				                /* Compute an estimate of the Lipschitz (Holder)   */			/* regularity. Here we merely fit a straight line  */			/* through the log-log graph of the of our wavelet */			/* transformed data and return the slope + 1/2 as  */			/* the regularity measure. 			   */                	for ( j =0 ; j< nt ; ++j ) {                        	x[0]=0;                        	for ( i = 1 ; i < nfilt ; ++i ) {					if (holder==1) {                                		y[i] = log(ABS(tmpdata[j][i+1]                                               	              - tmpdata[j][0]));                                		x[i] = log(i);					} else if (holder==2) {                                		y[i] = ABS(tmpdata[j][i+1]                                               	              - tmpdata[j][0]);                                		x[i] = i;					} else {						err("holder must = 0,1,2!");					}                        	}                        	y[0] =y[1] - (y[3] - y[2]);                        	linear_regression(y, x, nfilt, coeff);                        	/*  coeff[0] is the slope of the line */                        	tr.data[j] = coeff[0] + 0.5;                	}			tr.tracr = ++tracr;			tr.sx = tr.tracl;			tr.gx = tr.tracr;			tr.d1 = dt;			tr.f2 = fmin;			tr.d2 = band;			tr.trid = AMPLITUDE; 			tr.ntr = ntr*nfilt;			puttr(&tr); /* output holder regularity traces */		}	} while (gettr(&tr));	return(CWP_Exit());}static void gaussianFilter(float fcent, float dt,			int nfft, float alpha, float  band, float *filter)/*************************************************************************gaussianFilter -- Gaussian filter**************************************************************************Input:fcent		center (peak) frequency of Gaussiandt		time sampling intervalnfft		number of points in the fftband		frequency band of filteralpha		filter windowing parameterOutput:filter		array[nfft] filter values**************************************************************************Notes: Filter is to be applied in the frequency domain.The parameter "band" here is the full bandwidth of the filter. In Dziewonski,et. al, it is the half-bandwitdth. Hence, there are factors of 2 thatappear in the definitions of iflower, ifupper, and alpha.**************************************************************************Reference: Dziewonski, Bloch, and Landisman, 1969, A technique		for the analysis of transient seismic signals,		Bull. Seism. Soc. Am., 1969, vol. 59, no.1, pp.427-444.**************************************************************************Author:  CWP: John Stockwell,   Oct 1994*************************************************************************/{	int i;			/* loop counter				*/	int iflower;		/* integerization of min frequency	*/	int ifupper;		/* integerization of max frequency	*/	int nf;			/* number of frequencies (incl Nyq)	*/	float onfft;		/* reciprocal of nfft			*/	float df;		/* frequency spacing (from dt)		*/	/* number of frequencies */	nf = nfft/2 + 1;	onfft = 1.0 / nfft;	df = onfft / dt;	/* compute integerized min, max frequencies defining filter window */	iflower = NINT((fcent - band/2)/df); 	if (iflower < 0) iflower=0;	ifupper = NINT((fcent + band/2)/df) ;	if (ifupper > nf) ifupper=nf;	/* zero out filter array */	memset( (void *) filter , 0, nf * FSIZE);	        /* loop over integerized frequencies to build filter */        for (i = 0 ; i < nf ; ++i) {		float f = i * df - fcent; /* freq's as floats */		if ( iflower <= i && i <= ifupper)			filter[i] = exp(-4.0 * alpha * f * f) * onfft;        }}

⌨️ 快捷键说明

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