예제 #1
0
파일: velconv.c 프로젝트: JOravetz/SeisUnix
/* compute z(t) from t(z) */
void tzzt(int nz, float dz, float fz, float tz[], float vfz, float vlz, 
	int nt, float dt, float ft, float zt[])
{
	int it;
	float t,lt=ft+(nt-1)*dt,lz=fz+(nz-1)*dz;

	yxtoxy(nz,dz,fz,tz,nt,dt,ft,0.0,0.0,zt);
	for (it=0,t=ft; t<=tz[0]; it++,t+=dt)
		zt[it] = 0.5*t*vfz;
	for (it=nt-1,t=lt; t>=tz[nz-1]; it--,t-=dt)
		zt[it] = lz+0.5*(t-tz[nz-1])*vlz;
}
예제 #2
0
파일: velconv.c 프로젝트: JOravetz/SeisUnix
/* compute t(z) from z(t) */
void zttz(int nt, float dt, float ft, float zt[], float vft, float vlt, 
	int nz, float dz, float fz, float tz[])
{
	int iz;
	float z,lt=ft+(nt-1)*dt,lz=fz+(nz-1)*dz;

	yxtoxy(nt,dt,ft,zt,nz,dz,fz,0.0,0.0,tz);
	for (iz=0,z=fz; z<=zt[0]; iz++,z+=dz)
		tz[iz] = 2.0*z/vft;
	for (iz=nz-1,z=lz; z>=zt[nt-1]; iz--,z-=dz)
		tz[iz] = lt+2.0*(z-zt[nt-1])/vlt;
}
예제 #3
0
파일: suztot.c 프로젝트: gwowen/seismicunix
static void tzzt(int nz, float dz, float fz, float tz[], float vfz, float vlz, 
	int nt, float dt, float ft, float zt[])
/************************************************************************
tzzt - compute z(t) from t(z)
*************************************************************************
Input:
nz	number of z values
dz	depth sampling interval
fz	first z value
tz[]	array of z values as a function of time
vfz	velocity at first time sample
vlz	velocity at last time sample
nt	number of time samples
dt	time sampling interval
ft	first time value
Output:
zt[] 	array of time values as a function of depth
*************************************************************************
Author: CWP: based on zttz by Dave Hale (c. 1992)
************************************************************************/
{
	int it;				/* depth counter */
	float t;			/* time */
	float lt=ft+(nt-1)*dt;		/* last time */

	/* switch from t(z) to z(t) */
	yxtoxy(nz,dz,fz,tz,nt,dt,ft,0.0,0.0,zt);

	/* for t values before ft, use first velocity to calculate z(t) */
	for (it=0,t=ft; t<=tz[0]; ++it,t+=dt)
		zt[it] = vfz*t/2.0;

	/* for t values from lt down to ft, calculate z(t) */
	for (it=nt-1,t=lt; t>=tz[nz-1]; it--,t-=dt)
		zt[it] = lt*vlz/2.0 + vlz*(t-tz[nz-1])/2.0;
}
예제 #4
0
파일: sunmo.c 프로젝트: gwowen/seismicunix
int
main(int argc, char **argv)
{
	int nt;		/* number of time samples per trace */
	float dt;	/* time sampling interval */
	float ft;	/* time of first sample */
	int it;		/* time sample index */
	int ncdp;	/* number of cdps specified */
	float *cdp;	/* array[ncdp] of cdps */
	int icdp;	/* index into cdp array */
	int jcdp;	/* index into cdp array */
	int nvnmo;	/* number of vnmos specified */
	float *vnmo;	/* array[nvnmo] of vnmos */
	int ntnmo;	/* number of tnmos specified */
	float *tnmo;	/* array[ntnmo] of tnmos */
	float **ovv;	/* array[ncdp][nt] of sloth (1/velocity^2) functions */
	float *ovvt;	/* array[nt] of sloth for a particular trace */
	int nanis1;	/* number of anis1's specified */
	int nanis2;	/* number of anis2's specified */
	float *anis1;	/* array[nanis1] of anis1's */
	float *anis2;	/* array[nanis2] of anis2's */
	float **oa1;	/* array[ncdp][nt] of anis1 functions */
	float **oa2;	/* array[ncdp][nt] of anis2 functions */
	float *oa1t;	/* array[nt] of anis1 for a particular trace */
	float *oa2t;	/* array[nt] of anis2 for a particular trace */
	float smute;	/* zero samples with NMO stretch exceeding smute */
	float osmute;	/* 1/smute */
	int lmute;	/* length in samples of linear ramp for mute */
	int itmute=0;	/* zero samples with indices less than itmute */
	int sscale;	/* if non-zero, apply NMO stretch scaling */
	int invert;	/* if non-zero, do inverse NMO */
	float sy;	/* cross-line offset component */
	int ixoffset;	/* indes for cross-line offset component */
	long oldoffset;	/* offset of previous trace */
	long oldcdp;	/* cdp of previous trace */
	int newsloth;	/* if non-zero, new sloth function was computed */
	float tn;	/* NMO time (time after NMO correction) */
	float v;	/* velocity */
	float *qtn;	/* NMO-corrected trace q(tn) */
	float *ttn;	/* time t(tn) for NMO */
	float *atn;	/* amplitude a(tn) for NMO */
	float *qt;	/* inverse NMO-corrected trace q(t) */
	float *tnt;	/* time tn(t) for inverse NMO */
	float *at;	/* amplitude a(t) for inverse NMO */
	float acdp;	/* temporary used to sort cdp array */
	float *aovv;	/* temporary used to sort ovv array */
	float *aoa1;	/* temporary used to sort oa1 array */
	float *aoa2;	/* temporary used to sort oa2 array */
	float temp;	/* temporary float */
	float tsq;	/* temporary float */
	int i;		/* index used in loop */
	int upward;	/* scans upward if it's nonzero. */

	/* hook up getpar */
	initargs(argc, argv);
	requestdoc(1);

	/* get information from the first header */
	if (!gettr(&tr)) err("can't get first trace");
	nt = tr.ns;
	dt = ((double) tr.dt)/1000000.0;
	ft = tr.delrt/1000.0;
	sy  = tr.sy;

	/* get velocity functions, linearly interpolated in time */
	ncdp = countparval("cdp");
	if (ncdp>0) {
		if (countparname("vnmo")!=ncdp)
			err("a vnmo array must be specified for each cdp");
		if (countparname("tnmo")!=ncdp)
			err("a tnmo array must be specified for each cdp");
		if (countparname("anis1")!=ncdp &&
		    countparname("anis1")!=0)
			err("an anis1 array must be specified for each cdp, "
			    "or omitted at all");
		if (countparname("anis2")!=ncdp &&
		    countparname("anis2")!=0)
			err("an anis2 array must be specified for each cdp, "
			    "or omitted at all");
	} else {
		ncdp = 1;
		if (countparname("vnmo")>1)
			err("only one (or no) vnmo array must be specified");
		if (countparname("tnmo")>1)
			err("only one (or no) tnmo array must be specified");
		if (countparname("anis1")>1)
			err("only one (or no) anis1 array must be specified");
		if (countparname("anis2")>1)
			err("only one (or no) anis2 array must be specified");
	}
	cdp = ealloc1float(ncdp);
	if (!getparfloat("cdp",cdp)) cdp[0] = tr.cdp;
	ovv = ealloc2float(nt,ncdp);
	oa1 = ealloc2float(nt,ncdp);
	oa2 = ealloc2float(nt,ncdp);
	for (icdp=0; icdp<ncdp; ++icdp) {
		nvnmo = countnparval(icdp+1,"vnmo");
		ntnmo = countnparval(icdp+1,"tnmo");
		nanis1 = countnparval(icdp+1,"anis1");
		nanis2 = countnparval(icdp+1,"anis2");
		if (nvnmo!=ntnmo && !(ncdp==1 && nvnmo==1 && ntnmo==0))
			err("number of vnmo and tnmo values must be equal");
		if (nanis1!=nvnmo && nanis1 != 0)
			err("number of vnmo and anis1 values must be equal");
		if (nanis2!=nvnmo && nanis2 != 0)
			err("number of vnmo and anis2 values must be equal");
		if (nvnmo==0) nvnmo = 1;
		if (ntnmo==0) ntnmo = nvnmo;
		if (nanis1==0) nanis1 = nvnmo;
		if (nanis2==0) nanis2 = nvnmo;
		/* equal numbers of parameters vnmo, tnmo, anis1, anis2 */
		vnmo = ealloc1float(nvnmo);
		tnmo = ealloc1float(nvnmo);
		anis1 = ealloc1float(nvnmo);
		anis2 = ealloc1float(nvnmo);
		if (!getnparfloat(icdp+1,"vnmo",vnmo)) vnmo[0] = 1500.0;
		if (!getnparfloat(icdp+1,"tnmo",tnmo)) tnmo[0] = 0.0;
		if (!getnparfloat(icdp+1,"anis1",anis1)) 
			for (i=0; i<nvnmo; i++) anis1[i] = 0.0;
		if (!getnparfloat(icdp+1,"anis2",anis2))
			for (i=0; i<nvnmo; i++) anis2[i] = 0.0;
		for (it=1; it<ntnmo; ++it)
			if (tnmo[it]<=tnmo[it-1])
				err("tnmo values must increase monotonically");
		for (it=0,tn=ft; it<nt; ++it,tn+=dt) {
			intlin(ntnmo,tnmo,vnmo,vnmo[0],vnmo[nvnmo-1],1,&tn,&v);
			ovv[icdp][it] = 1.0/(v*v);
		}
		for (it=0,tn=ft; it<nt; ++it,tn+=dt) {
			intlin(ntnmo,tnmo,anis1,anis1[0],anis1[nanis1-1],1,&tn,
			       &oa1[icdp][it]);
		}
		for (it=0,tn=ft; it<nt; ++it,tn+=dt) {
			intlin(ntnmo,tnmo,anis2,anis2[0],anis2[nanis2-1],1,&tn,
			       &oa2[icdp][it]);
		}
		free1float(vnmo);
		free1float(tnmo);
		free1float(anis1);
		free1float(anis2);
	}

	/* sort (by insertion) sloth and anis functions by increasing cdp */
	for (jcdp=1; jcdp<ncdp; ++jcdp) {
		acdp = cdp[jcdp];
		aovv = ovv[jcdp];
		aoa1 = oa1[jcdp];
		aoa2 = oa2[jcdp];
		for (icdp=jcdp-1; icdp>=0 && cdp[icdp]>acdp; --icdp) {
			cdp[icdp+1] = cdp[icdp];
			ovv[icdp+1] = ovv[icdp];
			oa1[icdp+1] = oa1[icdp];
			oa2[icdp+1] = oa2[icdp];
		}
		cdp[icdp+1] = acdp;
		ovv[icdp+1] = aovv;
		oa1[icdp+1] = aoa1;
		oa2[icdp+1] = aoa2;
	}

	/* get other optional parameters */
	if (!getparfloat("smute",&smute)) smute = 1.5;
	if (!getparint("ixoffset",&ixoffset)) ixoffset=0; 
	  if (ixoffset==0) sy = 0.0;
	if (smute<=0.0) err("smute must be greater than 0.0");
	if (!getparint("lmute",&lmute)) lmute = 25;
	if (!getparint("sscale",&sscale)) sscale = 1;
	if (!getparint("invert",&invert)) invert = 0;
	if (!getparint("upward",&upward)) upward = 0;

	/* allocate workspace */
	ovvt = ealloc1float(nt);
	oa1t = ealloc1float(nt);
	oa2t = ealloc1float(nt);
	ttn = ealloc1float(nt);
	atn = ealloc1float(nt);
	qtn = ealloc1float(nt);
	tnt = ealloc1float(nt);
	at = ealloc1float(nt);
	qt = ealloc1float(nt);

	/* interpolate sloth and anis function for first trace */
	interpovv(nt,ncdp,cdp,ovv,oa1,oa2,(float)tr.cdp,ovvt,oa1t,oa2t);

	/* set old cdp and old offset for first trace */
	oldcdp = tr.cdp;
	oldoffset = tr.offset-1;

	warn("sy = %f",sy);

	/* loop over traces */
	do {
		/* if necessary, compute new sloth and anis function */
		if (tr.cdp!=oldcdp && ncdp>1) {
			interpovv(nt,ncdp,cdp,ovv,oa1,oa2,(float)tr.cdp,
				  ovvt,oa1t,oa2t);
			newsloth = 1;
		} else {
			newsloth = 0;
		}

		/* if sloth and anis function or offset has changed */
		if (newsloth || tr.offset!=oldoffset) {
			/* compute time t(tn) (normalized) */
			temp = ((float) tr.offset*(float) tr.offset + sy*sy)/(dt*dt);
			for (it=0,tn=ft/dt; it<nt; ++it,tn+=1.0) {
				tsq = temp*ovvt[it] + \
				      oa1t[it]*temp*temp / (1.0+oa2t[it]*temp);
				if (tsq<0.0)
					err("negative moveout; check anis1, "
					    "anis2, or suwind far-offset "
					    "traces");
				if ((1.0+oa2t[it]*temp)<=0.0)
					err("anis2 negative and too small; "
					    "check anis2, or suwind far-offset"
					    " traces");
				ttn[it] = sqrt (tn*tn + tsq);
				}
			/* compute inverse of stretch factor a(tn) */
			atn[0] = ttn[1]-ttn[0];
			for (it=1; it<nt; ++it)
				atn[it] = ttn[it]-ttn[it-1];
			
			/* determine index of first sample to survive mute */
			osmute = 1.0/smute;
			if( !upward ) {
				for (it=0; it<nt-1 && atn[it]<osmute; ++it)
					;
			} else {
				/* scan samples from bottom to top */
				for (it=nt-1; it>0 && atn[it]>=osmute; --it)
					;
			}
			itmute = it;

			/* if inverse NMO will be performed */
			if (invert) {
							
				/* compute tn(t) from t(tn) */
				yxtoxy(nt-itmute,1.0,ft/dt+itmute,&ttn[itmute],
					nt-itmute,1.0,ft/dt+itmute,
					ft/dt-nt,ft/dt+nt,&tnt[itmute]);
			
				/* adjust mute time */
				itmute = 1.0+ttn[itmute]-ft/dt;
				itmute = MIN(nt-2,itmute);
								
				/* compute a(t) */
				if (sscale) {
					for (it=itmute+1; it<nt; ++it)
						at[it] = tnt[it]-tnt[it-1];
					at[itmute] = at[itmute+1];
				}
			}
		}
		
		/* if forward (not inverse) nmo */
		if (!invert) {
	
			/* do nmo via 8-point sinc interpolation */
			ints8r(nt,1.0,ft/dt,tr.data,0.0,0.0,
				nt-itmute,&ttn[itmute],&qtn[itmute]);
			
			/* apply mute */
			for (it=0; it<itmute; ++it)
				qtn[it] = 0.0;
			
			/* apply linear ramp */
			for (it=itmute; it<itmute+lmute && it<nt; ++it)
				qtn[it] *= (float)(it-itmute+1)/(float)lmute;
			
			/* if specified, scale by the NMO stretch factor */
			if (sscale)
				for (it=itmute; it<nt; ++it)
					qtn[it] *= atn[it];
			
			/* copy NMO corrected trace to output trace */
			memcpy( (void *) tr.data,
					(const void *) qtn, nt*sizeof(float));
		
		/* else inverse nmo */
		} else {
	
			/* do inverse nmo via 8-point sinc interpolation */
			ints8r(nt,1.0,ft/dt,tr.data,0.0,0.0,
				nt-itmute,&tnt[itmute],&qt[itmute]);
			
			/* apply mute */
			for (it=0; it<itmute; ++it)
				qt[it] = 0.0;
			
			/* if specified, undo NMO stretch factor scaling */
			if (sscale)
				for (it=itmute; it<nt; ++it)
					qt[it] *= at[it];
			
			/* copy inverse NMO corrected trace to output trace */
			memcpy( (void *) tr.data,
					(const void *) qt,nt*sizeof(float));
		}

		/* write output trace */
		puttr(&tr);

		/* remember offset and cdp */
		oldoffset = tr.offset;
		oldcdp = tr.cdp;

	} while (gettr(&tr));

	return(CWP_Exit());
}
예제 #5
0
void makeref (float dsmax, int nr, float *ar, 
	int *nu, float **xu, float **zu, Reflector **r)
/*****************************************************************************
Make piecewise cubic reflectors
******************************************************************************
Input:
dsmax		maximum length of reflector segment
nr		number of reflectors
ar		array[nr] of reflector amplitudes
nu		array[nr] of numbers of (x,z) pairs; u = 0, 1, ..., nu[ir]
xu		array[nr][nu[ir]] of reflector x coordinates x(u)
zu		array[nr][nu[ir]] of reflector z coordinates z(u)

Output:
r		array[nr] of reflectors
******************************************************************************
Notes:
Space for the ar, nu, xu, and zu arrays is freed by this function, since
they are only used to construct the reflectors.

This function is meant to be called only once, so it need not be very
efficient.  Once made, the reflectors are likely to be used many times, 
so the cost of making them is insignificant.
*****************************************************************************/
{
	int ir,iu,nuu,iuu,ns,is;
	float x,z,xlast,zlast,dx,dz,duu,uu,ds,fs,rsx,rsz,rsxd,rszd,
		*u,*s,(*xud)[4],(*zud)[4],*us;
	ReflectorSegment *rs;
	Reflector *rr;
	
	/* allocate space for reflectors */
	*r = rr = ealloc1(nr,sizeof(Reflector));

	/* loop over reflectors */
	for (ir=0; ir<nr; ++ir) {

		/* compute cubic spline coefficients for uniformly sampled u */
		u = ealloc1float(nu[ir]);
		for (iu=0; iu<nu[ir]; ++iu)
			u[iu] = iu;
		xud = (float(*)[4])ealloc1float(4*nu[ir]);
		csplin(nu[ir],u,xu[ir],xud);
		zud = (float(*)[4])ealloc1float(4*nu[ir]);
		csplin(nu[ir],u,zu[ir],zud);

		/* finely sample x(u) and z(u) and compute length s(u) */
		nuu = 20*nu[ir];
		duu = (u[nu[ir]-1]-u[0])/(nuu-1);
		s = ealloc1float(nuu);
		s[0] = 0.0;
		xlast = xu[ir][0];
		zlast = zu[ir][0];
		for (iuu=1,uu=duu; iuu<nuu; ++iuu,uu+=duu) {
			intcub(0,nu[ir],u,xud,1,&uu,&x);
			intcub(0,nu[ir],u,zud,1,&uu,&z);
			dx = x-xlast;
			dz = z-zlast;
			s[iuu] = s[iuu-1]+sqrt(dx*dx+dz*dz);
			xlast = x;
			zlast = z;
		}

		/* compute u(s) from s(u) */
		ns = 1+s[nuu-1]/dsmax;
		ds = s[nuu-1]/ns;
		fs = 0.5*ds;
		us = ealloc1float(ns);
		yxtoxy(nuu,duu,0.0,s,ns,ds,fs,0.0,(float)(nu[ir]-1),us);

		/* compute reflector segments uniformly sampled in s */
		rs = ealloc1(ns,sizeof(ReflectorSegment));
		for (is=0; is<ns; ++is) {
			intcub(0,nu[ir],u,xud,1,&us[is],&rsx);
			intcub(0,nu[ir],u,zud,1,&us[is],&rsz);
			intcub(1,nu[ir],u,xud,1,&us[is],&rsxd);
			intcub(1,nu[ir],u,zud,1,&us[is],&rszd);
			rs[is].x = rsx;
			rs[is].z = rsz;
			rs[is].c = rsxd/sqrt(rsxd*rsxd+rszd*rszd);
			rs[is].s = -rszd/sqrt(rsxd*rsxd+rszd*rszd);
		}
		
		/* fill in reflector structure */
		rr[ir].ns = ns;
		rr[ir].ds = ds;
		rr[ir].a = ar[ir];
		rr[ir].rs = rs;

		/* free workspace */
		free1float(us);
		free1float(s);
		free1float(u);
		free1float((float*)xud);
		free1float((float*)zud);

		/* free space replaced by reflector segments */
		free1(xu[ir]);
		free1(zu[ir]);
	}

	/* free space replaced by reflector segments */
	free1(nu);
	free1(xu);
	free1(zu);
}
예제 #6
0
파일: Mtahnmo.c 프로젝트: 1014511134/src
int main(int argc, char* argv[])
{
  int verbose;
  sf_file in=NULL, out=NULL;
  int n1_traces;
  int n1_headers;

  char* header_format=NULL;
  sf_datatype typehead;
  /* kls do I need to add this?  sf_datatype typein; */
  float* fheader=NULL;
  float* intrace=NULL;
  float o1;
  float d1;
  int indx_offset;
  float* local_sloth=NULL;
  float v0;
  int indx_time;
  float offset;
  float offset2;
  float* r_index_tx_of_it0=NULL;
  float* r_index_t0_of_itx=NULL;
  int start_indx_nmo;
  int start_indx_nmo_tx;
  float* outtrace=NULL;
  float itrace=0;
  float nmostretch;
  char* offsetname;
  float lmute;
  bool inv;
  /******************************************************/
  /* code block for standard tah Trace And Header setup */
  /******************************************************/

  sf_init (argc,argv);

  /*****************************/
  /* initialize verbose switch */
  /*****************************/
  if(!sf_getint("verbose",&verbose))verbose=1;
  /* \n
     flag to control amount of print
     0 terse, 1 informative, 2 chatty, 3 debug
  */
  sf_warning("verbose=%d",verbose);
 
  /******************************************/
  /* input and output data are stdin/stdout */
  /******************************************/

  if(verbose>0)fprintf(stderr,"read in file name\n");  
  in = sf_input ("in");

  if(verbose>0)fprintf(stderr,"read out file name\n");
  out = sf_output ("out");

  if (!sf_histint(in,"n1_traces",&n1_traces))
    sf_error("input data not define n1_traces");
  if (!sf_histint(in,"n1_headers",&n1_headers)) 
    sf_error("input data does not define n1_headers");

  header_format=sf_histstring(in,"header_format");
  if(strcmp (header_format,"native_int")==0) typehead=SF_INT;
  else                                       typehead=SF_FLOAT;

  if(verbose>0)fprintf(stderr,"allocate headers.  n1_headers=%d\n",n1_headers);
  fheader = sf_floatalloc(n1_headers);
 
  if(verbose>0)fprintf(stderr,"allocate intrace.  n1_traces=%d\n",n1_traces);
  intrace= sf_floatalloc(n1_traces);

  /* maybe I should add some validation that n1== n1_traces+n1_headers+2
     and the record length read in the second word is consistent with 
     n1.  */
  /**********************************************************/
  /* end code block for standard tah Trace And Header setup */
  /* continue with any sf_puthist this tah program calls to */
  /* add to the history file                                */
  /**********************************************************/

  /* put the history from the input file to the output */
  sf_fileflush(out,in);


  /********************************************************/
  /* continue initialization specific to this tah program */
  /********************************************************/
  if (!sf_histfloat(in,"d1",&d1))
    sf_error("input data does not define d1");
  if (!sf_histfloat(in,"o1",&o1))
    sf_error("input data does not define o1");
  /* Kls should read label1 and verify it is time  
  if (!sf_histstring(in,"label1",&label1))
    sf_error("input data not define label1");
  */

  /* segy_init gets the list header keys required by segykey function  */
  segy_init(n1_headers,in);
  /* get index to keys I will be using */
  if(NULL==(offsetname=sf_getstring("offset")))offsetname="offset";
  /* name of the header key to use for offset (usually just offset) */
  indx_offset=segykey(offsetname);
  /* kls what other header keys do I use?  inline? xline? cdp? */

  /* get the parameter for the maximum nmo stretch. */
  if (!sf_getfloat("str",&nmostretch)) nmostretch=0.5;
  /* maximum stretch allowed */

  if (!sf_getfloat("lmute",&lmute)) lmute=12.*d1; 
  /* length of the mute zone in seconds */
  if(verbose>0)  fprintf(stderr,"lmute=%f seconds.\n",lmute);
  lmute/=d1;
  if(!sf_getbool("inv",&inv)) inv=false;
  /* if y, do inverse nmo.  Otherwise forward nmo */ 
   
  if(verbose>0){
    if(inv)fprintf(stderr,"inv=true\n");
    else fprintf(stderr,"inv=false\n");
  }
   
  /* set up velocity function ( really (1/v)**2, sloth */
  local_sloth=sf_floatalloc(n1_traces);
  /* just constant velocity today */
  if(1==1){
    char** list_of_floats;
    float* vnmo;
    float* tnmo;
    int numvnmo;
    int numtnmo;
    float t0;

    if(verbose>1)fprintf(stderr,"read vnmo/tnmo\n");
    /* use this fundtion to find out number of velocities and time 
       input in vnmo and tnmo */
    list_of_floats=sf_getnstring("vnmo",&numvnmo);
    /* list of NMO velocities for the time in tnmo */
    if(verbose>1){
      int i;
      fprintf(stderr,"numvnmo=%d\n",numvnmo);
      for (i=0; i<numvnmo; i++){
	fprintf(stderr,"velocities=%s\n",list_of_floats[i]);
      }
    }
    /* should free this list of strings, but that is only a little memory */\
    list_of_floats=sf_getnstring("tnmo",&numtnmo);
    /* NMO times for the vnmo velocities. */
    if(verbose>1){
      int i;
      for (i=0; i<numtnmo; i++){
	fprintf(stderr,"times=%s\n",list_of_floats[i]);
      }
    }
    if(numvnmo!=numtnmo){
      sf_error("number vnmo floats=%d != number tnmo floats=%d",
	       numvnmo,numtnmo);
    }
    if(numvnmo==0)sf_error("vnmo parameter is required");
    vnmo=sf_floatalloc(numvnmo);
    tnmo=sf_floatalloc(numtnmo);
    if(verbose>1)fprintf(stderr,"sf_getfloats(vnmo)");
    if (!sf_getfloats("vnmo",vnmo,numvnmo))
      sf_error("unable to read vnmo");
    /* list of NMO velocities for the tnmo times. */
    if(verbose>1)fprintf(stderr,"sf_getfloats(tnmo)");
    if (!sf_getfloats("tnmo",tnmo,numtnmo))
      sf_error("unable to read tnmo");
    /* list of NMO times for the vnmo velocities. */
    if(verbose>1){
      for(indx_time=0; indx_time<numvnmo; indx_time++){
	fprintf(stderr,"indx=%d, vnmo=%f, tnmo=%f\n",
		indx_time,vnmo[indx_time],tnmo[indx_time]);
      }
    }
    if(verbose>1)fprintf(stderr,"interpolate the velocity\n");
    for(indx_time=0; indx_time<n1_traces; indx_time++){
      t0=indx_time*d1+o1;
      intlin(numtnmo,tnmo,vnmo,vnmo[0],vnmo[numvnmo-1],1,&t0,&v0);
      local_sloth[indx_time]=1.0/(v0*v0);
    }    
  } 
  /* kls
     previous if(1==1) clause if for it no input velocity file
     need to add else { set up the input velocity file (ie open the file(
     inside the trace loop need to get iline and xline form trace heder
     and use that to read the velocity at (iline,xline) into local_sloth
     then compute local_sloth as 1/(v*v)

     will need to get input velocity shape:
       if (!sf_histint(invelocity,"n1",&n1_velocity))
          sf_error("input velocity file does not define n1");
     test n1_velocity!=n1_trace error
     and do the same for d1, o2, d2, etc 
   */

  if(verbose>0)fprintf(stderr,"allocate arrays for the trace loop\n");
  r_index_tx_of_it0=sf_floatalloc(n1_traces);
  r_index_t0_of_itx=sf_floatalloc(n1_traces);
  outtrace         =sf_floatalloc(n1_traces);
  

  /***************************/
  /* start trace loop        */
  /***************************/
  if(verbose>0)fprintf(stderr,"start trace loop\n");
  while (0==get_tah(intrace, fheader, n1_traces, n1_headers, in)){
    if(verbose>1)fprintf(stderr,"process the tah in sftahnmo\n");
    /********************/
    /* process the tah. */
    /********************/
    /* this program applies moveout */
    /* kls this should be only be done when velocity (local_sloth) 
       or offset changes */
    if(typehead == SF_INT){   
      /* just cast the header to int so the print works */
      offset=((int*)fheader)[indx_offset];
    } else {
      offset=       fheader [indx_offset];
    }
    offset2=offset*offset;
    for(indx_time=0; indx_time<n1_traces; indx_time++){
      float tx, t0;
      t0=indx_time*d1+o1;
      tx=sqrt(t0*t0+offset2*local_sloth[indx_time]);
      r_index_tx_of_it0[indx_time]=(tx-o1)/d1;
      if(itrace==0 && verbose>4){
	fprintf(stderr,"indx_time=%d, tx=%f, sloth=%g, offset=%f, t0=%f\n",
		        indx_time   , tx   , local_sloth[indx_time]  ,
                                                       offset   , t0);
      }
    }
    /* kls nmo start time should depend on the nmo stretch limit.
       Find the excessive stretch closest to the bottom of the trace.  This 
       is the last time nmstrewtch is violated.  It is OK to apply nmo
       to the rest of the trace. */
    for (start_indx_nmo=n1_traces-1; start_indx_nmo>1; start_indx_nmo--){
      /* pfrintf(stderr,"r_indx[it]=%f, rindx */
      if((r_index_tx_of_it0[start_indx_nmo  ]-
	  r_index_tx_of_it0[start_indx_nmo-1])  <nmostretch) break;
    }
    if(inv){
      start_indx_nmo_tx = 1.0+r_index_tx_of_it0[start_indx_nmo];
      if(start_indx_nmo_tx>n1_traces-2)start_indx_nmo_tx = n1_traces-2;
      /* compute r_index_t0_of_itx from r_index_tx_of_it0 */
      yxtoxy(n1_traces-start_indx_nmo,1.0, start_indx_nmo,
	     &r_index_tx_of_it0[start_indx_nmo],
 
	     n1_traces-start_indx_nmo_tx,1.0, start_indx_nmo_tx,
	     -1,n1_traces,&r_index_t0_of_itx[start_indx_nmo_tx]);
    }
    /* kls inverse nmo? will need more code */
    /* do nmo via 8-point sinc interpolation */
    /* void ints8r (int nxin, float dxin, float fxin,      
                    float yin[], float yinl, float yinr, 
		    int nxout, float xout[], 
		    float yout[]) */
    if(!inv){
      ints8r(n1_traces,1.0,0,
	     intrace,0.0,0.0,
	     n1_traces-start_indx_nmo,&r_index_tx_of_it0[start_indx_nmo],
	     &outtrace[start_indx_nmo]);
      /* zero above the start time */
      for(indx_time=0; indx_time<start_indx_nmo; indx_time++){
	outtrace[indx_time]=0.0;
      }
      /* apply linear ramp kls */
      for (indx_time=start_indx_nmo; 
	   indx_time<start_indx_nmo+lmute && indx_time<n1_traces;
	   indx_time++){
	outtrace[indx_time] *= (float)(indx_time-start_indx_nmo+1)/(float)lmute;
      }
    }else{
      ints8r(n1_traces,1.0,0,
	     intrace,0.0,0.0,
	     n1_traces-start_indx_nmo_tx,&r_index_t0_of_itx[start_indx_nmo_tx],
	     &outtrace[start_indx_nmo_tx]);      
      /* zero above the start time */
      for(indx_time=0; indx_time<start_indx_nmo_tx; indx_time++){
	outtrace[indx_time]=0.0;
      }
    }
    /***************************/
    /* write trace and headers */
    /***************************/
    put_tah(outtrace, fheader, n1_traces, n1_headers, out);
    itrace++;
  }
  
  exit(0);
}
예제 #7
0
static void maketu (float offset, int itmin, float fmax,
	int nt, float dt, float ft, float *vrms, float **uoftp,
	int *nup, float *dup, float *fup, float **tofup, float *tconp)
/*****************************************************************************
make stretch and compress functions t(u) and u(t)
******************************************************************************
Input:
offset		source receiver offset
itmin		index of minimum first non-zero sample for this offset
fmax		maximum frequency
nt		number of time samples
dt		time sampling interval
ft		first time
vrms		array[nt] of rms velocities

Output:
uoftp		array[nt] of u(t)
nup		number of u (stretched t) samples
dup		u sampling interval
fup		first u
tofup		array[nu] of t(u)
tconp		time constant relating t(u) and u(t)
******************************************************************************
Author:  Dave Hale, Colorado School of Mines, 08/08/91
*****************************************************************************/
{
	int it,numax,nu;
	float tmin,dumin,et,eu,t1,t2,
		v2,v22,v44,gamma,
		v2m,v22m,v44m,gammam,t,dv2,vi2,vi4,v24,
		*uoft,du,fu,*tofu,tcon;

	/* determine maximum number of u */
	numax = 500+log((float)nt)*(float)(nt-1);

	/* allocate space for u(t) */
	uoft = ealloc1float(nt);

	/* determine t1 and t2, rounded to nearest sampled times */
	tmin = ft+itmin*dt;
	et = ft+(nt-1)*dt;
	t1 = MIN(et,MAX(ft+dt,tmin));
	if (offset!=0.0)
		t2 = MAX(t1,1.0/(1.0/et+0.2*dt*vrms[0]*vrms[0]/
			(offset*offset)));
	else
		t2 = t1;
	t1 = ft+NINT(t1/dt)*dt;
	t2 = ft+NINT(t2/dt)*dt;

	/* compute u(t) */
	v2 = vrms[0];
	v22 = v2*v2;
	v44 = v22*v22;
	gamma = 1.0;
	for (it=0,t=ft; it<nt; ++it,t+=dt) {
		v2m = v2;
		v22m = v22;
		v44m = v44;
		gammam = gamma;
		if (t>0.0) {
			v2 = vrms[it];
			v22 = v2*v2;
			vi2 = (t*v22-(t-dt)*v22m)/dt;
			vi4 = vi2*vi2;
			v44 = (dt*vi4+(t-dt)*v44m)/t;
		} else {
			v2 = v2m;
			v22 = v22m;
			v44 = v44m;
		}
		dv2 = (v2-v2m)/dt;
		v24 = v22*v22;
		gamma = 1.5*v44/v24-t*dv2/v2-0.5;
		if (t<=t1) {
			uoft[it] = t-t1;
		} else if (t>t1 && t<=t2) {
			du = t1*(gamma*log(t/(t-0.5*dt)) -
				gammam*log((t-dt)/(t-0.5*dt)));
			dumin = 0.1*dt*t1/t;
			uoft[it] = uoft[it-1]+MAX(dumin,du);
		} else if (t>t2) {
			uoft[it] = 2.0*uoft[it-1]-uoft[it-2];
		}
	}

	/* determine minimum u(t)-u(t-dt) */
	dumin = uoft[1]-uoft[0];
	for (it=1; it<nt; ++it)
		dumin = MIN(dumin,uoft[it]-uoft[it-1]);

	/* determine u sampling for t(u) to avoid aliasing */
	fu = 0.0;
	eu = uoft[nt-1];
	du = dumin/MIN(1.0,2.0*fmax*dt);
	nu = 1+NINT((eu-fu)/du);
	if (nu>numax) {
		nu = numax;
		du = (eu-fu)/(nu-1);
	}

	/* allocate space for t(u) */
	tofu = ealloc1float(nu);

	/* compute t(u) by inverse linear interpolation of u(t) */
	yxtoxy(nt,dt,ft,uoft,nu,du,fu,ft,et,tofu);

	/* set time constant */
	tcon = t1;

	/* set returned values */
	*uoftp = uoft;
	*nup = nu;
	*dup = du;
	*fup = fu;
	*tofup = tofu;
	*tconp = tcon;
}