SYNOPSIS
PERL PROGRAM NAME:
AUTHOR: Juan Lorenzo (Perl module only)
DATE:
DESCRIPTION:
Version:
USE
NOTES
Examples
SYNOPSIS
SEISMIC UNIX NOTES SULFAF - Low frequency array forming ",
sulfaf < stdin > stdout [optional parameters]
Optional Parameters:
key=ep header keyword describing the gathers
f1=3 lower frequency cutof
f2=20 high frequency cutof
fr=5 frequency ramp
vel=1000 surface wave velocity
dx=10 trace spacing
maxmix=tr.ntr default is the entire gather
adb=1.0 add back ratio 1.0=pure filtered 0.0=origibal
tri=0 1 Triangular weight in mixing window
Notes:
The traces transformed into the freqiency domain
where a trace mix is performed in the specifed frequency range
as Mix=vel/(freq*dx)
This program uses "get_gather" and "put_gather" so requires that
the data be sorted into ensembles designated by "key", with the ntr
field set to the number of traces in each respective ensemble.
Example:
susort ep offset < data.su > datasorted.su
suputgthr dir=Data verbose=1 < datasorted.su
sugetgthr dir=Data verbose=1 > dataupdated.su
sulfaf < dataupdated.su > ccfiltdata.su
(Work in progress, editing required)
define LOOKFAC 1 /* Look ahead factor for npfaro
define PFA_MAX 720720 /* Largest allowed nfft */
define PIP2 PI/2.0 /* IP/2 */
int
main( int argc, char *argv[] )
{
cwp_String key; /* header key word from segy.h */
cwp_String type; /* ... its type */
Value val; /* ... its value */
segy **rec_o; /* trace header+data matrix */
int first=0; /* true when we passed the first gather
int ng=0;
float dt; /* time sampling interval */
int nt; /* num time samples per trace */
int ntr; /* num of traces per ensemble */
int nfft=0; /* lenghth of padded array */
float snfft; /* scale factor for inverse fft
int nf=0; /* number of frequencies */
float d1; /* frequency sampling interval. */
float *rt=NULL; /* real trace */
complex *ct=NULL; /* complex trace */
float **ffdr=NULL; /* frequency domain data */
float **ffdi=NULL; /* frequency domain data */
float **ffdrm=NULL; /* frequency domain mixed data */
float **ffdim=NULL; /* frequency domain mixed data */
int verbose; /* flag: =0 silent; =1 chatty */
float f1; /* minimum frequency */
int if1; /* ... ... integerized */
float f2; /* maximum frequency */
int if2; /* ... ... integerized */
float fr; /* slope of frequency ramp */
int ifr; /* ... ... integerized */
float vel; /* velocity of guided waves */
float dx; /* spatial sampling intervall */
int maxmix; /* size of mix */
int tri; /* flag: =1 trianglular window */
float adb; /* add back ratio */
/* Initialize
initargs(argc, argv);
requestdoc(1);
if (!getparstring("key", &key)) key = "ep";
if (!getparfloat("f1", &f1)) f1 = 3.0;
if (!getparfloat("f2", &f2)) f2 = 20.0;
if (!getparfloat("dx", &dx)) dx = 10;
if (!getparfloat("vel", &vel)) vel = 1000;
if (!getparfloat("fr", &fr)) fr = 5;
if (!getparint("maxmix", &maxmix)) maxmix = -1;
if (!getparint("tri", &tri)) tri = 0;
if (!getparfloat("adb", &adb)) adb = 1.0;
if (!getparint("verbose", &verbose)) verbose = 0;
/* get the first record
rec_o = get_gather(&key,&type,&val,&nt,&ntr,&dt,&first);
if(ntr==0) err("Can't get first record\n");
/* set up the fft
nfft = npfaro(nt, LOOKFAC * nt);
if (nfft >= SU_NFLTS || nfft >= PFA_MAX)
err("Padded nt=0--too big", nfft);
nf = nfft/2 + 1;
snfft=1.0/nfft;
d1=1.0/(nfft*dt);
ct=ealloc1complex(nf);
rt=ealloc1float(nfft);
if1=NINT(f1/d1);
if2=NINT(f2/d1);
ifr=NINT(fr/d1);
do {
if(maxmix==-1) maxmix=ntr;
ng++;
/* Allocate arrays for fft
ffdr = ealloc2float(nf,ntr);
ffdi = ealloc2float(nf,ntr);
ffdrm = ealloc2float(if2+ifr,ntr);
ffdim = ealloc2float(if2+ifr,ntr);
{ int itr,iw;
for(itr=0;itr<ntr;itr++) {
memcpy( (void *) rt, (const void *) (*rec_o[itr]).data, nt*FSIZE);
memset( (void *) &rt[nt], 0,(nfft-nt)*FSIZE);
pfarc(1,nfft,rt,ct);
for(iw=0;iw<nf;iw++) {
ffdr[itr][iw] = ct[iw].r;
ffdi[itr][iw] = ct[iw].i;
}
}
}
/* Mixing
{ int mix,iw,nmix;
int ims,ime;
int itr,itrm,iww,ws;
float tmpr,tmpi,wh;
for(iw=if1;iw<if2+ifr;iw++) {
mix=MIN(NINT(vel/iw*d1*dx),maxmix);
if(!ISODD(mix)) mix -=1;
if (verbose) warn(" 0.000000 0",iw*d1,mix);
for(itr=0;itr<ntr;itr++) {
ims=MAX(itr-mix/2,0);
ime=MIN(ims+mix,ntr-1);
tmpr=0.0; tmpi=0.0;
wh=1.0; ws=mix/2;
nmix=0;
for(itrm=ims,iww=-mix/2;itrm<ime;++itrm,++iww) {
++nmix;
if(tri) wh = (float)(ws-abs(iww));
tmpr+=ffdr[itrm][iw]*wh;
tmpi+=ffdi[itrm][iw]*wh;
}
ffdrm[itr][iw]=tmpr/nmix;
ffdim[itr][iw]=tmpi/nmix;
}
}
for(iw=if1;iw<if2;iw++) {
for(itr=0;itr<ntr;itr++) {
ffdr[itr][iw]=ffdrm[itr][iw]*adb+ffdr[itr][iw]*(1.0-adb);
ffdi[itr][iw]=ffdim[itr][iw]*adb+ffdi[itr][iw]*(1.0-adb);
}
}
for(iw=if2,iww=0;iw<if2+ifr;iw++,iww++) {
wh=(float)(1.0-(float)iww/(float)ifr);
for(itr=0;itr<ntr;itr++) {
ffdr[itr][iw] = (wh*ffdrm[itr][iw]+ffdr[itr][iw]*(1.0-wh))*adb+ffdr[itr][iw]*(1.0-adb);
ffdi[itr][iw] = (wh*ffdim[itr][iw]+ffdi[itr][iw]*(1.0-wh))*adb+ffdi[itr][iw]*(1.0-adb);
}
}
}
{ int itr,iw;
for(itr=0;itr<ntr;itr++) {
for(iw=0;iw<nf;iw++) {
ct[iw].r = ffdr[itr][iw]*snfft;
ct[iw].i = ffdi[itr][iw]*snfft;
}
pfacr(-1,nfft,ct,rt);
memcpy( (void *) (*rec_o[itr]).data, (const void *) rt, nt*FSIZE);
}
}
rec_o = put_gather(rec_o,&nt,&ntr);
free2float(ffdr);
free2float(ffdi);
free2float(ffdrm);
free2float(ffdim);
rec_o = get_gather(&key,&type,&val,&nt,&ntr,&dt,&first);
} while(ntr);
warn("Number of gathers 0\n",ng);
return EXIT_SUCCESS;
}
User's notes (Juan Lorenzo) untested
CHANGES and their DATES
Import packages
instantiation of packages
Encapsulated hash of private variables
sub Step
collects switches and assembles bash instructions by adding the program name
sub note
collects switches and assembles bash instructions by adding the program name
sub clear
sub adb
sub ct
sub d1
sub dir
sub dx
sub f1
sub f2
sub ffdi
sub ffdim
sub ffdr
sub ffdrm
sub first
sub fr
sub i
sub if1
sub if2
sub ifr
sub ime
sub ims
sub itr
sub itrm
sub iw
sub key
sub maxmix
sub mix
sub nf
sub nfft
sub ng
sub nmix
sub nt
sub ntr
sub r
sub rec_o
sub rt
sub snfft
sub tmpr
sub tri
sub vel
sub verbose
sub wh
sub get_max_index
max index = number of input variables -1