コード例 #1
0
ファイル: velcon.c プロジェクト: 1014511134/src
void velcon_init(int nt1   /* time samples */,
		 int nx1   /* space samples */,
		 float dt1 /* time sampling */,
		 float dx1 /* space sampling */,
		 float t1  /* time origin */,
		 int pad1, 
		 int pad2  /* padding in time */,
		 int next /* trace extension */)
/*< initialize >*/
{
    nt = nt1;
    nx = nx1;
    dt = dt1;
    dx = dx1;
    t0 = t1;

    n2 = pad1;
    n3 = pad2;

    /* t squared stretch */
    o2 = t0*t0;
    d2 = t0+(nt-1)*dt;
    d2 = (d2*d2 - o2)/(n2-1);

    str = fint1_init(next,nt,0);
    istr = fint1_init(next,n2,0);

    /* FFT in time */
    forw = kiss_fftr_alloc(n3,0,NULL,NULL);
    invs = kiss_fftr_alloc(n3,1,NULL,NULL);
    if (NULL == forw || NULL == invs) 
	sf_error("KISS FFT allocation error");

    nw = n3/2+1;
    dw = 2*SF_PI/(n3*d2);

    /* cosine FT in space */
    sf_cosft_init(nx);
    dx = SF_PI/(kiss_fft_next_fast_size(nx-1)*dx1);

    strace = sf_floatalloc(n3);
    ctrace = sf_complexalloc(nw);
}
コード例 #2
0
ファイル: Mfourvc2.c プロジェクト: 1014511134/src
int main(int argc, char* argv[])
{
    fint1 str, istr;
    int i1,i2, n1,n2,n3, ix,iv,ih, ib, ie, nb, nx,nv,nh, nw, next;
    float d1,o1,d2,o2, eps, w,x,k, v0,v2,v,v1,dv, dx, h0,dh,h, num, den, t, dw;
    float *trace=NULL, *strace=NULL, ***stack=NULL, ***stack2=NULL, ***cont=NULL, **image=NULL;
    sf_complex *ctrace=NULL, *ctrace0=NULL, shift;
    char *time=NULL, *space=NULL, *unit=NULL;
    size_t len;
    static kiss_fftr_cfg forw, invs;
    sf_file in=NULL, out=NULL;
    bool sembl;

    sf_init (argc,argv);
    in = sf_input("in");
    out = sf_output("out");

    if (!sf_histint(in,"n1",&n1)) sf_error("No n1= in input");
    if (!sf_histint(in,"n2",&nx)) sf_error("No n2= in input");
    if (!sf_histint(in,"n3",&nh)) sf_error("No n3= in input");

    if (!sf_getint("nb",&nb)) nb=2;
    if (!sf_getfloat("eps",&eps)) eps=0.01;
    if (!sf_getint("pad",&n2)) n2=n1;
    if (!sf_getint("pad2",&n3)) n3=2*kiss_fft_next_fast_size((n2+1)/2);

    nw = n3/2+1;
    forw = kiss_fftr_alloc(n3,0,NULL,NULL);
    invs = kiss_fftr_alloc(n3,1,NULL,NULL);
    if (NULL == forw || NULL == invs) 
	sf_error("KISS FFT allocation error");

    if (!sf_histfloat(in,"o1",&o1)) o1=0.;
    o2 = o1*o1;

    if(!sf_histfloat(in,"d1",&d1)) sf_error("No d1= in input");
    d2 = o1+(n1-1)*d1;
    d2 = (d2*d2 - o2)/(n2-1);

    if (!sf_getint("nv",&nv)) sf_error("Need nv=");
    if (!sf_getfloat("dv",&dv)) sf_error("Need dv=");
    if (!sf_getfloat("v0",&v0) && 
	!sf_histfloat(in,"v0",&v0)) sf_error("Need v0=");

    if (!sf_getbool("semblance",&sembl)) sembl=true;
    /* if y, compute semblance; if n, stack */

    if(!sf_histfloat(in,"o3",&h0)) sf_error("No o2= in input");
    if(!sf_histfloat(in,"d3",&dh)) sf_error("No d2= in input");
    if(!sf_histfloat(in,"d2",&dx)) sf_error("No d3= in input");

    sf_putfloat(out,"o3",v0+dv);
    sf_putfloat(out,"d3",dv);
    sf_putint(out,"n3",nv);

    sf_putstring(out,"label3","Velocity");

    if (NULL != (time = sf_histstring(in,"label1")) &&
	NULL != (space = sf_histstring(in,"label2"))) {
	len = strlen(time)+strlen(space)+2;
	unit = sf_charalloc(len);
	snprintf(unit,len,"%s/%s",space,time);
	sf_putstring(out,"unit3",unit);
	free(time);
	free(space);
    }

    dx = 2*SF_PI/(2*kiss_fft_next_fast_size(nx-1)*dx);
    dw = 16*SF_PI/(d2*n3); /* 2pi * 8 */

    stack = sf_floatalloc3(n1,nx,nv);
    stack2 = sf_floatalloc3(n1,nx,nv);
    cont = sf_floatalloc3(n1,nx,nv);
    image = sf_floatalloc2(n1,nx);
    trace = sf_floatalloc(n1);
    strace = sf_floatalloc(n3);
    ctrace = sf_complexalloc(nw);
    ctrace0 = sf_complexalloc(nw);

    if (!sf_getint("extend",&next)) next=4;
    /* trace extension */
    str = fint1_init(next,n1,0);
    istr = fint1_init(next,n2,0);

    for (i1=0; i1 < n1*nx*nv; i1++) {
	stack[0][0][i1] = 0.;
	stack2[0][0][i1] = 0.;
    }

    sf_cosft_init(nx);

    for (ih=0; ih < nh; ih++) {
	sf_warning("offset %d of %d;",ih+1,nh);

	h = h0 + ih*dh;
	h *= h * 0.5;

	sf_floatread(image[0],n1*nx,in);

	for (i1=0; i1 < n1; i1++) {
	    sf_cosft_frw(image[0],i1,n1);
	}

	for (ix=0; ix < nx; ix++) {
	    x = ix*dx; 
	    x *= x;

	    k = x * 0.5;

	    fint1_set(str,image[ix]);

	    for (i2=0; i2 < n2; i2++) {
		t = o2+i2*d2;
		t = sqrtf(t);
		t = (t-o1)/d1;
		i1 = t;
		if (i1 >= 0 && i1 < n1) {
		    strace[i2] = fint1_apply(str,i1,t-i1,false);
		} else {
		    strace[i2] = 0.;
		}
	    }

	    for (i2=n2; i2 < n3; i2++) {
		strace[i2] = 0.;
	    }

	    kiss_fftr(forw,strace, (kiss_fft_cpx *) ctrace0);   

	    for (iv=0; iv < nv; iv++) {
		v = v0 + (iv+1)* dv;

		v1 = h * (1./(v*v) - 1./(v0*v0));
		v2 = k * ((v0*v0) - (v*v));

		ctrace[0]=sf_cmplx(0.,0.); /* dc */

		for (i2=1; i2 < nw; i2++) {
		    w = i2*dw;
		    w = v2/w+(v1-0.125*o2)*w;
		    shift = sf_cmplx(cosf(w),sinf(w));

#ifdef SF_HAS_COMPLEX_H
		    ctrace[i2] = ctrace0[i2] * shift;
#else
		    ctrace[i2] = sf_cmul(ctrace0[i2],shift);
#endif
		} /* w */

		kiss_fftri(invs,(const kiss_fft_cpx *) ctrace, strace);
		
		fint1_set(istr,strace);
		
		for (i1=0; i1 < n1; i1++) {
		    t = o1+i1*d1;
		    t = t*t;
		    t = (t-o2)/d2;
		    i2 = t;
		    if (i2 >= 0 && i2 < n2) {
			cont[iv][ix][i1] = fint1_apply(istr,i2,t-i2,false);
		    } else {
			cont[iv][ix][i1] = 0.;
		    }
		}
	    } /* v */
	} /* x */

	for (iv=0; iv < nv; iv++) {
	    for (i1=0; i1 < n1; i1++) {
		sf_cosft_inv(cont[0][0],i1+iv*nx*n1,n1);
	    }
	}

	for (iv=0; iv < nv; iv++) {
	    for (ix=0; ix < nx; ix++) {
		for (i1=0; i1 < n1; i1++) {	
		    t = cont[iv][ix][i1];
		    stack[iv][ix][i1] += t;
		    stack2[iv][ix][i1] += t*t;
		} /* i1 */
	    } /* x */
        } /* v */
    } /* h */
    sf_warning(".");

    for (iv=0; iv < nv; iv++) {
	for (ix=0; ix < nx; ix++) {
	    for (i1=0; i1 < n1; i1++) {
		ib = i1-nb > 0? i1-nb: 0;
		ie = i1+nb+1 < n1? i1+nb+1: n1;

		    num = 0.;
		    den = 0.;

		if (sembl) {

		    for (i2=ib; i2 < ie; i2++) {
			t = stack[iv][ix][i2];
			num += t*t;
			den += stack2[iv][ix][i2];
		    }
		    
		    den *= nh;
		    
		    trace[i1] = den > 0.? num/den: 0.;
		} else {

		    for (i2=ib; i2 < ie; i2++) {
			t = stack[iv][ix][i2];
			num += t;
		    }

		    den = nh;
		    trace[i1] =  num/(den+ FLT_EPSILON);
		}
	    }
	    sf_floatwrite (trace,n1,out);
	}
    }

    exit(0);
}
コード例 #3
0
ファイル: Misin2ang.c プロジェクト: 1014511134/src
int main (int argc, char* argv[])
{
    bool top;

    fint1 sft;
    int  ext;

    float a,n,f,da,a0,t0,dt,s;
    int   fint,na,nx,nz,nt;

    sf_axis ax,az,at,aa;
    int ix,iz,it,ia;

    float   **stk=NULL, **ang=NULL, *tmp=NULL, *vel=NULL;
    sf_file  Fstk=NULL,  Fang=NULL, velocity=NULL;

    sf_init (argc,argv);

    /*------------------------------------------------------------*/
    Fstk = sf_input("in");
    Fang = sf_output("out");

    if (SF_FLOAT != sf_gettype(Fstk)) sf_error("Need float input");

    az=sf_iaxa(Fstk,1); nz=sf_n(az);
    at=sf_iaxa(Fstk,2); nt=sf_n(at); t0=sf_o(at); dt=sf_d(at);
    ax=sf_iaxa(Fstk,3); nx=sf_n(ax);

    if (!sf_getint  ("na",&na)) na=nt;          /* number of angles*/
    if (!sf_getfloat("da",&da)) da=90/(nt-1);   /* angle sampling */
    if (!sf_getfloat("a0",&a0)) a0=0.;          /* angle origin */
    aa = sf_maxa(na,a0,da);
    sf_oaxa(Fang,aa,2);

    if (!sf_getint("extend",&ext)) ext=4;       /* tmp extension */
    /*------------------------------------------------------------*/

    if (!sf_getbool("top",&top)) top=false;     /* velocity scaling option */

    if (top) {
	velocity = sf_input("velocity");
	vel = sf_floatalloc(nz);
    } else {
	velocity = NULL;
	vel = NULL;
    }

    stk = sf_floatalloc2(nz,nt);
    ang = sf_floatalloc2(nz,na);
    tmp = sf_floatalloc(nt);

    sft = fint1_init(ext,nt, 0);

    for (ix = 0; ix < nx; ix++) {
	sf_floatread(stk[0],nz*nt,Fstk);
	if (top) sf_floatread(vel,nz,velocity);

	/*------------------------------------------------------------*/
	for (iz = 0; iz < nz; iz++) {
	    for (it = 0; it < nt; it++) {
		tmp[it] = stk[it][iz];
	    }
	    fint1_set(sft,tmp);

	    for (ia=0; ia < na; ia++) {
		a = a0+ia*da;          /* ang or p */

		if (top) {
		    s = a*vel[iz];
		    if (s >= 1.) {
			n = t0 - 10.*dt;
		    } else {
			n = s/sqrtf(1.0-s*s);
		    }
		} else {
		    n = 1.0/(sinf(a/180.0*SF_PI)); /* 1/sin : no angle close to 0 */
		}

		f = (n - t0) / dt;
		fint = f;

		if (fint >= 0 && fint < nt) {
		    ang[ia][iz] = fint1_apply(sft,fint,f-fint,false);
		} else {
		    ang[ia][iz] = 0.;
		}
	    }
	}
	/*------------------------------------------------------------*/

	sf_floatwrite(ang[0],nz*na,Fang);
    }

    exit (0);
}
コード例 #4
0
ファイル: Mstacks.c プロジェクト: 1014511134/src
int main (int argc, char* argv[])
{
    fint1 nmo;
    bool half, squared, slow;
    int ix,ih,it,iv, nt,nx,nw, nh, nh2, m, CDPtype, mute, *mask, nv, *fold;
    float dt, t0, h0,dh,h, dy, str, v0,dv,v;
    float **traces, *trace, *off, *stack;
    double *dstack;
    mapfunc nmofunc;
    sf_file cmp, stk, offset, msk;

    sf_init (argc,argv);
    cmp = sf_input("in");
    stk = sf_output("out");
    nmofunc =  nmo_map;
    
    if (SF_FLOAT != sf_gettype(cmp)) sf_error("Need float input");
    if (!sf_histint  (cmp,"n1",&nt)) sf_error("No n1= in input");
    if (!sf_histfloat(cmp,"d1",&dt)) sf_error("No d1= in input");
    if (!sf_histfloat(cmp,"o1",&t0)) sf_error("No o1= in input");
    if (!sf_histint  (cmp,"n2",&nh)) sf_error("No n2= in input");
    nx = sf_leftsize(cmp,2);

    if (!sf_getbool("half",&half)) half=true;
    /* if y, the second axis is half-offset instead of full offset */
    if (!sf_getfloat("str",&str)) str=0.5;
    /* maximum stretch allowed */

    if (!sf_getint("mute",&mute)) mute=12;
    /* mute zone */

    if (!sf_getint("nv",&nv)) sf_error("Need nv=");
    /* number of velocities */
    
    if (!sf_getfloat("v0",&v0)) sf_error("Need v0=");
    /* first velocity */
    
    if (!sf_getfloat("dv",&dv)) sf_error("Need dv=");
    /* step in velocity */

    sf_putint(stk,"n2",nv);
    sf_putfloat(stk,"o2",v0);
    sf_putfloat(stk,"d2",dv);

    CDPtype=1;
    if (NULL != sf_getstring("offset")) {
	offset = sf_input("offset");
	if (SF_FLOAT != sf_gettype(offset)) sf_error("Need float offset");
	nh2 = sf_filesize(offset);
	if (nh2 != nh && nh2 != nh*nx) sf_error("Wrong dimensions in offset");

	off = sf_floatalloc(nh2);	
	sf_floatread (off,nh2,offset);
	sf_fileclose(offset);
    } else {
	if (!sf_histfloat(cmp,"d2",&dh)) sf_error("No d2= in input");
	if (!sf_histfloat(cmp,"o2",&h0)) sf_error("No o2= in input");

	if (sf_histfloat(cmp,"d3",&dy) && !sf_getint("CDPtype",&CDPtype)) {
	    CDPtype=half? 0.5+dh/dy : 0.5+0.5*dh/dy;
	    if (CDPtype < 1) {
		CDPtype=1;
	    } else if (1 != CDPtype) {
		sf_histint(cmp,"CDPtype",&CDPtype);
	    	sf_warning("CDPtype=%d",CDPtype);
	    }
	} 	    

	nh2 = nh;
	off = sf_floatalloc(nh2);
	for (ih = 0; ih < nh; ih++) {
	    off[ih] = h0 + ih*dh; 
	}

	offset = NULL;
    }
    
    if (NULL != sf_getstring("mask")) {
	msk = sf_input("mask");
	if (SF_INT != sf_gettype(msk)) sf_error("Need integer mask");
	nh2 = sf_filesize(msk);
	if (nh2 != nh && nh2 != nh*nx) sf_error("Wrong dimensions in mask");
	mask = sf_intalloc(nh2);
	sf_intread (mask,nh2,msk);
	sf_fileclose(msk);
    } else {
	msk = NULL;
	mask = NULL;
    }

    if (!sf_getbool("slowness",&slow)) slow=false;
    /* if y, use slowness instead of velocity */

    if (!sf_getbool("squared",&squared)) squared=false;
    /* if y, the slowness or velocity is squared */

    if (!sf_getfloat ("h0",&h0)) h0=0.;
    /* reference offset */
    if (half) h0 *= 2.;
    if (!sf_getint("extend",&nw)) nw=4;
    /* trace extension */

    traces = sf_floatalloc2(nt,nh);
    trace  = sf_floatalloc(nt);
    stack  = sf_floatalloc(nt);
    fold   = sf_intalloc(nt);
    dstack = (double*) sf_alloc(nt,sizeof(double));

    nmo = fint1_init (nw, nt, mute);
    
    for (ix = 0; ix < nx; ix++) {
	sf_warning("CMP %d of %d;",ix+1,nx);
	sf_floatread (traces[0],nt*nh,cmp);

	for (iv=0; iv < nv; iv++) {
	    v = v0+iv*dv;
	    if (!squared) v *=v;

	    for (it=0; it < nt; it++) {
		dstack[it] = 0.0;
		fold[it] = 0;
	    }

	    for (ih = 0; ih < nh; ih++) {
		/* skip dead traces */
		if (NULL != msk) {
		    m = (nh2 == nh)? mask[ih] + (dh/CDPtype)*(ix%CDPtype) : 
			mask[ix*nh+ih];	
		    if (0==m) continue;
		}
		
		for (it=0; it < nt; it++) {
		    trace[it] = traces[ih][it];
		}
	    
		fint1_set(nmo,trace);

		h = (nh2 == nh)? off[ih] + (dh/CDPtype)*(ix%CDPtype) : 
		    off[ix*nh+ih];
		if (half) h *= 2;
		h = h*h - h0*h0;
		v2 = slow ? h*v : h/v;

		stretch(nmo,nmofunc,nt,dt,t0,nt,dt,t0,trace,str);

		for (it=0; it < nt; it++) {
		    if (trace[it] != 0.0f) {
			fold[it]++;
			dstack[it] += trace[it];
		    }
		}
	    }

	    for (it=0; it < nt; it++) {
		if (fold[it] > 0) {
		    stack[it] = dstack[it]/fold[it];
		} else {
		    stack[it] = 0.0f;
		}
	    }
			
	    sf_floatwrite (stack,nt,stk);
	}
    }
    sf_warning(".");

    exit (0);
}
コード例 #5
0
ファイル: Mxlagtoang2d.c プロジェクト: 1014511134/src
int main(int argc, char* argv[])
{
    bool inv, verb;

    sf_file Fstk=NULL; /*    SS(h,z) file */
    sf_file Fang=NULL; /*     AD CIG file */
    sf_file Fgam=NULL; /* vpvs ratio file */
    sf_file Fdip=NULL; /*  dip field file */

    float **stk=NULL, *gam=NULL, *dip=NULL, **ang=NULL; /* I/O arrays */
    float *tmp=NULL;                     /* mapping arrays */

    sf_axis axz; /* depth axis */
    sf_axis axs; /*    SS axis */
    sf_axis axa; /* angle axis */

    int ext;
    int ncig, icig; /* CIG index */

    int   na;
    float oa,da;
    int   ia,iz,is;
    int   fint;

    fint1 sft;
    float a,t,g,d,n,f;

    /*------------------------------------------------------------*/
    sf_init (argc,argv);

    if (!sf_getbool("verb",&verb)) verb=false;  /* verbosity flag */
    if (!sf_getbool("inv", &inv))   inv=false;  /* inverse transformation flag */

    Fstk = sf_input (  "in"); /* SS(h,z) CIG */
    Fang = sf_output( "out"); /*  AD     CIG */
    Fgam = sf_input ("vpvs"); /*  vpvs ratio */
    Fdip = sf_input ( "dip"); /*  dip  field */

    if (SF_FLOAT != sf_gettype(Fstk)) sf_error("Need float input");

    axz = sf_iaxa(Fstk,1); /* depth axis */
    axs = sf_iaxa(Fstk,2); /*    SS axis */

    ncig = sf_leftsize(Fstk,2); /* number of CIGS to process */

    /* angle axis */
    if (!sf_getint  ("na",&na)) na=sf_n(axs);       
    if (!sf_getfloat("da",&da)) da=1./(sf_n(axs)-1);
    if (!sf_getfloat("oa",&oa)) oa=0.;         
    axa = sf_maxa(na,oa,da);
    sf_oaxa(Fang,axa,2);

    if (!sf_getint("extend",&ext)) ext=4;       /* tmp extension */
    /*------------------------------------------------------------*/

    /* I/O arrays */
    stk = sf_floatalloc2(sf_n(axz),sf_n(axs)); /* SS(h,z) CIG */
    gam = sf_floatalloc (sf_n(axz)         ); /*  vpvs ratio */
    dip = sf_floatalloc (sf_n(axz)         ); /*  dip  field */
    ang = sf_floatalloc2(sf_n(axz),sf_n(axa)); /*      AD CIG */

    /* temp array */
    tmp = sf_floatalloc(sf_n(axs));

    /*------------------------------------------------------------*/
    sft = fint1_init(ext,sf_n(axs),0);

    /*------------------------------------------------------------*/
    for (icig=0; icig < ncig; icig++) { /* loop over CIG */
	if(verb) sf_warning("%d of %d",icig+1,ncig);

	sf_floatread(stk[0],sf_n(axz)*sf_n(axs),Fstk);	
	sf_floatread(gam   ,sf_n(axz)         ,Fgam);
	sf_floatread(dip   ,sf_n(axz)         ,Fdip);

	/*------------------------------------------------------------*/
	for (iz=0; iz < sf_n(axz); iz++) {
	    /* loop over depth */

	    g = gam[iz];
	    d = dip[iz];

	    d*=(g*g-1.);

	    for (is = 0; is < sf_n(axs); is++) { 
		/* loop over slant-stack index */
		tmp[is] = stk[is][iz];
	    }
	    fint1_set(sft,tmp);

	    for (ia=0; ia < sf_n(axa); ia++) {
		a = sf_o(axa)+ia*sf_d(axa);          /* ang */
		t = tanf(a/180*SF_PI);             /* tan */
		
		/*
		 * mapping from tan(a) to slant-stack value (n)
		 */
		n = (4*g*t+d*(t*t+1.)) / ( t*t * (g-1)*(g-1) + (g+1)*(g+1) );

		f = (n - sf_o(axs)) / sf_d(axs);
		fint = f;

		if (fint >= 0 && fint < sf_n(axs)) {
		    ang[ia][iz] = fint1_apply(sft,fint,f-fint,false);
		} else {
		    ang[ia][iz] = 0.;
		}
	    } /* a */

	} /* z */
	/*------------------------------------------------------------*/

	sf_floatwrite(ang[0],sf_n(axz)*sf_n(axa),Fang);
    }

    exit(0);
}
コード例 #6
0
ファイル: Mfourvcd.c プロジェクト: 1014511134/src
int main(int argc, char* argv[])
{
    fint1 str, istr;
    int i1,i2, n1,n2,n3, ix,iv,ih, nx,nv,nh, nw, next;
    float d1,o1,d2,o2, eps, w,x,k, v0,v2,v,v1,dv, dx, h0,dh,h, t, t2;
    float *trace, *strace, ***prev, ***semb, ***cont, **image;
    float complex *ctrace, *ctrace0;
    static kiss_fftr_cfg forw, invs;
    sf_file in, out;

    sf_init (argc,argv);
    in = sf_input("in");
    out = sf_output("out");

    if (!sf_histint(in,"n1",&n1)) sf_error("No n1= in input");
    if (!sf_histint(in,"n2",&nx)) sf_error("No n2= in input");
    if (!sf_histint(in,"n3",&nh)) sf_error("No n3= in input");

    if (!sf_getfloat("eps",&eps)) eps=0.01;
    if (!sf_getint("pad",&n2)) n2=n1;
    if (!sf_getint("pad2",&n3)) n3=n2;

    if (n3%2) n3++;
    nw = n3/2+1;
    forw = kiss_fftr_alloc(n3,0,NULL,NULL);
    invs = kiss_fftr_alloc(n3,1,NULL,NULL);
    if (NULL == forw || NULL == invs) 
	sf_error("KISS FFT allocation error");

    if (!sf_histfloat(in,"o1",&o1)) o1=0.;  
    o2 = o1*o1;
 
    if(!sf_histfloat(in,"d1",&d1)) sf_error("No d1= in input");
    d2 = o1+(n1-1)*d1;
    d2 = (d2*d2 - o2)/(n2-1);

    if (!sf_getint("nv",&nv)) sf_error("Need nv=");
    if (!sf_getfloat("dv",&dv)) sf_error("Need dv=");
    if (!sf_getfloat("v0",&v0) && 
	!sf_histfloat(in,"v0",&v0)) sf_error("Need v0=");

    if(!sf_histfloat(in,"o3",&h0)) sf_error("No o2= in input");
    if(!sf_histfloat(in,"d3",&dh)) sf_error("No d2= in input");
    if(!sf_histfloat(in,"d2",&dx)) sf_error("No d3= in input");
    
    sf_putfloat(out,"o3",v0+dv);
    sf_putfloat(out,"d3",dv);
    sf_putint(out,"n3",nv);

    sf_putstring(out,"label3","Velocity (km/s)");

    dx = 2.*SF_PI/(2*(nx-1)*dx);

    prev = sf_floatalloc3(n1,nx,nv);
    semb = sf_floatalloc3(n1,nx,nv);
    cont = sf_floatalloc3(n1,nx,nv);
    image = sf_floatalloc2(n1,nx);
    trace = sf_floatalloc(n1);
    strace = sf_floatalloc(n3);
    ctrace = sf_complexalloc(nw);
    ctrace0 = sf_complexalloc(nw);

    if (!sf_getint("extend",&next)) next=4;
    /* trace extension */
    str = fint1_init(next,n1,0);
    istr = fint1_init(next,n2,0);

    for (i1=0; i1 < n1*nx*nv; i1++) {
	semb[0][0][i1] = 0.;
    }

    cosft_init(nx);

    for (ih=0; ih < nh; ih++) {
	sf_warning("offset %d of %d",ih+1,nh);

	h = h0 + ih*dh;
	h *= h;

	sf_floatread(image[0],n1*nx,in);

	for (i1=0; i1 < n1; i1++) {
	    cosft_frw(image[0],i1,n1);
	}

	for (ix=0; ix < nx; ix++) {
	    x = ix*dx; 
	    x *= x;

	    k = x * 0.25 * 0.25 * 0.5;

	    fint1_set(str,image[ix]);

	    for (i2=0; i2 < n2; i2++) {
		t = o2+i2*d2;
		t = sqrtf(t);
		t = (t-o1)/d1;
		i1 = t;
		if (i1 >= 0 && i1 < n1) {
		    strace[i2] = fint1_apply(str,i1,t-i1,false);
		} else {
		    strace[i2] = 0.;
		}
	    }
	    
	    for (i2=n2; i2 < n3; i2++) {
		strace[i2] = 0.;
	    }
		
	    kiss_fftr(forw,strace, (kiss_fft_cpx *) ctrace0);   

	    for (iv=0; iv < nv; iv++) {
		v = v0 + (iv+1)* dv;

		v1 = h * (1./(v*v) - 1./(v0*v0)) * 8.;
		v2 = k * ((v0*v0) - (v*v));

		ctrace[0]=0.; /* dc */

		for (i2=1; i2 < nw; i2++) {
		    w = i2*SF_PI/(d2*n3);
 
		    ctrace[i2] = ctrace0[i2] * cexpf(I*(v2/w+(v1-o2)*w));
		} /* w */

		kiss_fftri(invs,(const kiss_fft_cpx *) ctrace, strace);
		
		fint1_set(istr,strace);
		
		for (i1=0; i1 < n1; i1++) {
		    t = o1+i1*d1;
		    t = t*t;
		    t = (t-o2)/d2;
		    i2 = t;
		    if (i2 >= 0 && i2 < n2) {
			cont[iv][ix][i1] = fint1_apply(istr,i2,t-i2,false);
		    } else {
			cont[iv][ix][i1] = 0.;
		    }
		}
	    } /* v */
	} /* x */

	for (iv=0; iv < nv; iv++) {
	    for (i1=0; i1 < n1; i1++) {
		cosft_inv(cont[0][0],i1+iv*nx*n1,n1);
	    }
	}

	for (iv=0; iv < nv; iv++) {
	    for (ix=0; ix < nx; ix++) {
		for (i1=0; i1 < n1; i1++) {	
		    t = cont[iv][ix][i1];
		    if (ih > 0) {
			t2 = prev[iv][ix][i1]-t;
			semb[iv][ix][i1] += t2*t2;
		    }
		    prev[iv][ix][i1] = t;
		} /* i1 */
	    } /* x */
        } /* v */
    } /* h */

    sf_floatwrite (semb[0][0],n1*nx*nv,out);

    exit(0);
}
コード例 #7
0
ファイル: Mnmo.c プロジェクト: housian0724/src
int main (int argc, char* argv[])
{
    fint1 nmo;
    bool half;
    int ix,ih, nt,nx,nw, nh, noff, nmask, CDPtype, mute, *mask;
    float dt, t0, h0, dh, dy, str;
    float *trace, *off;
    mapfunc nmofunc;
    sf_file cmp, nmod, velocity, offset, msk, het;

    sf_init (argc,argv);
    cmp      = sf_input("in");
    velocity = sf_input("velocity");
    nmod     = sf_output("out");

    if (NULL != sf_getstring("s")) {
      	het = sf_input("s");
	nmofunc = shifted_nmo_map;	
    } else if (NULL != sf_getstring("a")) {
        het = sf_input("a");
        nmofunc = taner_nmo_map;
    } else {
	het = NULL;
	nmofunc =  nmo_map;
    } 

    if (SF_FLOAT != sf_gettype(cmp)) sf_error("Need float input");
    if (!sf_histint  (cmp,"n1",&nt)) sf_error("No n1= in input");
    if (!sf_histfloat(cmp,"d1",&dt)) sf_error("No d1= in input");
    if (!sf_histfloat(cmp,"o1",&t0)) sf_error("No o1= in input");
    if (!sf_histint  (cmp,"n2",&nh)) sf_error("No n2= in input");
    nx = sf_leftsize(cmp,2);

    if (!sf_getbool("half",&half)) half=true;
    /* if y, the second axis is half-offset instead of full offset */
    if (!sf_getfloat("str",&str)) str=0.5;
    /* maximum stretch allowed */

    if (!sf_getint("mute",&mute)) mute=12;
    /* mute zone */

    CDPtype=1;
    off = sf_floatalloc(nh);

    if (NULL != sf_getstring("offset")) {
	offset = sf_input("offset");
	if (SF_FLOAT != sf_gettype(offset)) sf_error("Need float offset");
	noff = sf_filesize(offset);
	if (noff == nh) {
	    sf_floatread (off,nh,offset);
	} else if (noff != nh*nx) {
	    sf_error("Wrong dimensions in offset");
	}
    } else {
	if (!sf_histfloat(cmp,"d2",&dh)) sf_error("No d2= in input");
	if (!sf_histfloat(cmp,"o2",&h0)) sf_error("No o2= in input");

	if (sf_histfloat(cmp,"d3",&dy) && !sf_getint("CDPtype",&CDPtype)) {
	    CDPtype=half? 0.5+dh/dy : 0.5+0.5*dh/dy;
	    if (CDPtype < 1) {
		CDPtype=1;
	    } else if (1 != CDPtype) {
		sf_histint(cmp,"CDPtype",&CDPtype);
	    	sf_warning("CDPtype=%d",CDPtype);
	    }
	} 	    

	for (ih = 0; ih < nh; ih++) {
	    off[ih] = h0 + ih*dh; 
	}

	noff = nh;
	offset = NULL;
    }
    
    if (NULL != sf_getstring("mask")) {
	msk = sf_input("mask");

	if (SF_INT != sf_gettype(msk)) sf_error("Need integer mask");
	nmask = sf_filesize(msk);
	mask = sf_intalloc(nh);

	if (nmask == nh) {
	    sf_intread (mask,nh,msk);
	} else if (nmask != nh*nx) {
	    sf_error("Wrong dimensions in mask");
	}
    } else {
	nmask = nh;

	msk = NULL;
	mask = NULL;
    }

    if (!sf_getbool("slowness",&slow)) slow=false;
    /* if y, use slowness instead of velocity */

    if (!sf_getbool("squared",&squared)) squared=false;
    /* if y, the slowness or velocity is squared */

    if (!sf_getfloat ("h0",&h0)) h0=0.;
    /* reference offset */
    if (half) h0 *= 2.;
    if (!sf_getint("extend",&nw)) nw=4;
    /* trace extension */

    trace = sf_floatalloc(nt);
    vel   = sf_floatalloc(nt);
    if (NULL != het) {
	par = sf_floatalloc(nt);
    } else {
	par = NULL;
    }

    nmo = fint1_init (nw, nt, mute);
    
    for (ix = 0; ix < nx; ix++) {
	sf_warning("CMP %d of %d;",ix+1,nx);

	sf_floatread (vel,nt,velocity);	
	if (NULL != het) sf_floatread(par,nt,het);
	if (NULL != offset && noff != nh) sf_floatread (off,nh,offset);
	if (NULL != msk && nmask != nh) sf_intread (mask,nh,msk);

	for (ih = 0; ih < nh; ih++) {
	    sf_floatread (trace,nt,cmp);
	    
	    /* skip dead traces */
	    if (NULL != msk && 0==mask[ih]) {
		sf_floatwrite (trace,nt,nmod);
		continue;
	    }
	    
	    fint1_set(nmo,trace);

	    h = off[ih];
	    if (NULL == offset) h += (dh/CDPtype)*(ix%CDPtype); 
	    if (half) h *= 2;
	    h = h*h - h0*h0;
	    
	    stretch(nmo,nmofunc,nt,dt,t0,nt,dt,t0,trace,str);
	    sf_floatwrite (trace,nt,nmod);
	}
    }
    sf_warning(".");

    exit (0);
}
コード例 #8
0
ファイル: Mstoltstretch.c プロジェクト: krushev36/src
int main(int argc, char* argv[])
{
    int nt, ns, nx, n2, it, nstr, ifix;
    float dt, t0, eps, v0, *v=NULL, *trace=NULL, *out=NULL, *ww=NULL, wsum;
    char buffer[20];
    map4 stolt;
    fint1 istolt;
    bool inv;
    sf_file in=NULL, st=NULL, vel=NULL;

    sf_init (argc,argv);
    in = sf_input("in");
    st = sf_output("out");
    vel = sf_input("velocity");

    if (!sf_getbool ("inv", &inv)) inv=false;
    /* if y, inverse stretch */

    if (!sf_getint("nstretch",&nstr)) nstr=1;
    /* number of steps */

    if (inv) {
        if (!sf_histint(in,"n1",&ns)) sf_error("No n1= in input");
        if (!sf_histint(vel,"n1",&nt)) sf_error("No n1= in velocity");
        sf_putint(st,"n1",nt);
    } else {
        if (!sf_histint(in,"n1",&nt)) sf_error("No n1= in input");
        if (!sf_getint("pad",&ns)) ns=nt;
        /* time axis padding */
        sf_putint(st,"n1",ns);
        sf_putint(st,"nstretch", nstr);
    }
    nx = sf_leftsize(in,1);
    n2 = sf_leftsize(vel,1);

    if (n2 != 1 && n2 != nx) sf_error("Wrong number of traces in velocity");

    if (!sf_histfloat(in,"d1",&dt)) sf_error("No d1= in input");
    if (!sf_histfloat(in,"o1",&t0) || 0. != t0) sf_error("Need o1=0 in input");
    if (!sf_getfloat("eps",&eps)) eps=0.01;
    /* stretch regularization */
    if (!sf_getfloat("vel",&v0)) sf_error("Need vel=");
    /* reference velocity */

    trace = sf_floatalloc(nt);
    v = sf_floatalloc(nt);
    str = sf_floatalloc2(nt,nx);
    out = sf_floatalloc(ns);
    ww = sf_floatalloc(nx);

    if (inv) {
        stolt = NULL;
        istolt = fint1_init(4,ns,0);
    } else {
        stolt =  stretch4_init (ns,t0,dt,nt,eps);
        istolt = NULL;
    }

    wsum = 0.;
    for (ix=0; ix < nx; ix++) {
        if (0==ix || n2 > 1) {
            sf_floatread(v,nt,vel);
            ww[ix] = vt2w (nt,v,str[ix]);
        } else if (1 == n2) {
            ww[ix] = ww[0];
            for (it=0; it < nt; it++) {
                str[ix][it] = str[0][it];
            }
        }
        wsum += ww[ix];
    }

    sf_warning("%d traces processed",nx);

    if (1==nstr) {
        sf_putfloat(st,"stretch", wsum/nx);
    } else {
        for (ix=0; ix < nstr; ix++) {
            ifix=SF_MAX(1,(int) (nx*ix/(nstr-1)));
            sf_warning("%d %d",ix,ifix);

            snprintf(buffer,20,"stretch%d",ix);
            sf_putfloat (st,buffer,ww[ifix]);

            snprintf(buffer,20,"node%d",ix);
            sf_putint (st,buffer,ifix);
        }
    }

    for (ix=0; ix < nx; ix++) {
        for (it=0; it < nt; it++) {
            str[ix][it] *= dt/v0;
        }
        if (inv) {
            sf_floatread(out,ns,in);
            fint1_set(istolt,out);
            stretch(istolt, map, ns, dt, t0, nt, dt, t0, trace, 0.);
            sf_floatwrite (trace,nt,st);
        } else {
            sf_floatread (trace,nt,in);
            stretch4_define (stolt, str[ix]);
            stretch4_apply (false,stolt, trace, out);
            sf_floatwrite (out,ns,st);
        }
    }

    exit(0);
}
コード例 #9
0
ファイル: Mvscan.c プロジェクト: housian0724/src
int main(int argc, char* argv[])
{
    fint1 nmo;
    bool sembl, half, slow, dsembl, asembl, weight, squared, trend, ratio;
    int it,ih,ix,iv, nt,nh,nx,nv, ib,ie,nb,i, nw, is, ns, CDPtype, mute, *mask;
    float amp, amp2, dt, dh, t0, h0, v0, dv, ds, smax, num, den, dy, str, sh=0., sh2=0.;
    float *trace, ***stack, ***stack2, ***stack2h, ***stackh, *hh, **bb;
    char *time, *space, *unit;
    const char *type;
    size_t len;
    sf_file cmp, scan, offset, msk, grd;
    mapfunc nmofunc;

    sf_init (argc,argv);
    cmp = sf_input("in");
    scan = sf_output("out");

    if (!sf_histint(cmp,"n1",&nt)) sf_error("No n1= in input");
    if (!sf_histint(cmp,"n2",&nh)) sf_error("No n2= in input");
    nx = sf_leftsize(cmp,2);

    if (!sf_getbool("semblance",&sembl)) sembl=false;
    /* if y, compute semblance; if n, stack */
    if (sembl || !sf_getbool("diffsemblance",&dsembl)) dsembl=false;
    /* if y, compute differential semblance */
    if (sembl || dsembl || !sf_getbool("avosemblance",&asembl)) asembl=false;
    /* if y, compute AVO-friendly semblance */

    if (NULL == (type = sf_getstring("type"))) {
	/* type of semblance (avo,diff,sembl,power,weighted) */
	if (asembl) {
	    type="avo";
	} else if (dsembl) {
	    type="diff";
	} else if (sembl) {
	    type="sembl";
	} else {
	    type="power";
	}
    }

    trend = (bool) ('a' == type[0] || 'w' == type[0]);
    ratio = (bool) ('p' != type[0] && 'd' != type[0]);

    if (!sf_getint("nb",&nb)) nb=2;
    /* semblance averaging */
    if (!sf_getbool("weight",&weight)) weight=true;
    /* if y, apply pseudo-unitary weighting */

    if (!sf_histfloat(cmp,"o1",&t0)) sf_error("No o1= in input");
    if (!sf_histfloat(cmp,"d1",&dt)) sf_error("No d1= in input");

    if (!sf_getbool("half",&half)) half=true;
    /* if y, the second axis is half-offset instead of full offset */

    CDPtype=1;
    if (NULL != sf_getstring("offset")) {
	offset = sf_input("offset");
	hh = sf_floatalloc(nh);

	h0 = dh = 0.;
    } else {
	if (!sf_histfloat(cmp,"o2",&h0)) sf_error("No o2= in input");
	if (!sf_histfloat(cmp,"d2",&dh)) sf_error("No d2= in input");
	
	sf_putfloat(scan,"h0",h0);
	sf_putfloat(scan,"dh",dh);
	sf_putint(scan,"nh",nh);

	if (sf_histfloat(cmp,"d3",&dy)) {
	    CDPtype=half? 0.5+dh/dy: 0.5+0.5*dh/dy;
	    if (0 == CDPtype) CDPtype=1;
	    if (1 != CDPtype) {
		sf_histint(cmp,"CDPtype",&CDPtype);
		sf_warning("CDPtype=%d",CDPtype);
	    }
	}

	offset = NULL;
	hh = NULL;
    }

    if (NULL != sf_getstring("mask")) {
	/* optional mask file */ 
	msk = sf_input("mask");
	mask = sf_intalloc(nh);
    } else {
	msk = NULL;
	mask = NULL;
    }

    if (!sf_getfloat("v0",&v0) && !sf_histfloat(cmp,"v0",&v0)) 
	sf_error("Need v0=");
    /*(v0 first scanned velocity )*/
    if (!sf_getfloat("dv",&dv) && !sf_histfloat(cmp,"dv",&dv)) 
	sf_error("Need dv=");
    /*(dv step in velocity )*/
    if (!sf_getint("nv",&nv) && !sf_histint(cmp,"nv",&nv)) 
	sf_error("Need nv=");
    /*(nv number of scanned velocities )*/

    sf_putfloat(scan,"o2",v0);
    sf_putfloat(scan,"d2",dv);
    sf_putint(scan,"n2",nv);

    if (!sf_getfloat("smax",&smax)) smax=2.0;
    /* maximum heterogeneity */
    if (!sf_getint("ns",&ns)) ns=1;
    /* number of heterogeneity scans */ 
    ds = ns>1? (smax-1.0)/(ns-1): 0.;

    if (ns > 1) {
	sf_putfloat(scan,"o3",1.0);
	sf_putfloat(scan,"d3",ds);
	sf_putint(scan,"n3",ns);

	sf_shiftdim(cmp, scan, 3);
    }

    if (!sf_getbool("slowness",&slow)) slow=false;
    /* if y, use slowness instead of velocity */
    sf_putstring(scan,"label2",slow? "Slowness": "Velocity");

    if (!sf_getbool("squared",&squared)) squared=false;
    /* if y, the slowness or velocity is squared */

    if (!sf_getfloat("v1",&v1)) {
	/*( v1 reference velocity )*/
	if (ns > 1) {
	    nmofunc = squared? noncurved: nonhyperb;
	} else {
	    nmofunc = squared? curved: hyperb;
	}
    } else {
	if (ns > 1) {
	    nmofunc = squared? noncurved1: nonhyperb1;
	} else {
	    nmofunc = squared? curved1: hyperb1;
	}
	if (!slow) v1 = 1./v1;
    }

    if (NULL != (time = sf_histstring(cmp,"unit1")) &&
	NULL != (space = sf_histstring(cmp,"unit2"))) {
	len = strlen(time)+strlen(space)+2;
	unit = sf_charalloc(len);
	if (slow) {
	    snprintf(unit,len,"%s/%s",time,space);
	} else {
	    snprintf(unit,len,"%s/%s",space,time);
	}
	sf_putstring(scan,"unit2",unit);
    }

    if (NULL != sf_getstring("grad")) {
	grd = sf_input("grad");

	bb = sf_floatalloc2(nt,nv);
	sf_floatread(bb[0],nt*nv,grd);

	sf_fileclose(grd);
    } else {
	bb = NULL;
    }

    stack =  sf_floatalloc3(nt,nv,ns);
    stack2 = ('p' != type[0])? sf_floatalloc3(nt,nv,ns): NULL;
    stackh = trend? sf_floatalloc3(nt,nv,ns): NULL;
    stack2h = ('w' == type[0])? sf_floatalloc3(nt,nv,ns): NULL;

    if (!sf_getint("extend",&nw)) nw=4;
    /* trace extension */

    if (!sf_getint("mute",&mute)) mute=12;
    /* mute zone */

    if (!sf_getfloat("str",&str)) str=0.5;
    /* maximum stretch allowed */

    trace = sf_floatalloc(nt);
    nmo = fint1_init(nw,nt,mute);

    for (ix=0; ix < nx; ix++) {
	sf_warning("cmp %d of %d;",ix+1,nx);

	for (it=0; it < nt*nv*ns; it++) {
	    stack[0][0][it] = 0.;
	    if (ratio) stack2[0][0][it] = 0.;
	    if (trend) stackh[0][0][it] = 0.;
	}

	if (NULL != offset) sf_floatread(hh,nh,offset);
	if (NULL != msk) sf_intread(mask,nh,msk);

	if (trend) sh = sh2 = 0.;

	for (ih=0; ih < nh; ih++) {
	    sf_floatread(trace,nt,cmp); 
	    if (NULL != msk && 0==mask[ih]) continue;

	    h = (NULL != offset)? hh[ih]: 
		h0 + ih * dh + (dh/CDPtype)*(ix%CDPtype);
	    if (half) h *= 2.;

	    if (trend) {
		sh  += h;    /* sf  */
		sh2 += h*h;  /* sf2 */
	    }

	    for (it=0; it < nt; it++) {
		trace[it] /= nt*nh;
	    }
	    fint1_set(nmo,trace);

	    for (is=0; is < ns; is++) {
		s = 1.0 + is*ds;

		for (iv=0; iv < nv; iv++) {
		    v = v0 + iv * dv;
		    v = slow? h*v: h/v;

		    stretch(nmo,nmofunc,nt,dt,t0,nt,dt,t0,trace,str);

		    for (it=0; it < nt; it++) {
			amp = weight? fabsf(v)*trace[it]: trace[it];
			if (NULL != bb) amp *= (1.0-bb[iv][it]*h);
			
			switch(type[0]) {
			    case 'd':
				if (ih > 0) {
				    amp2 = amp - stack2[is][iv][it];
				    stack[is][iv][it] += amp2*amp2;
				}
				stack2[is][iv][it] = amp;
				break;
			    case 's':
				stack2[is][iv][it] += amp*amp;
				stack[is][iv][it] += amp;
				break;
			    case 'a': 
				stackh[is][iv][it] += amp*h;    /* saf */
				stack2[is][iv][it] += amp*amp;  /* sa2 */
				stack[is][iv][it] += amp;       /* sa1 */
				break;
			    case 'w':
				stackh[is][iv][it] += amp*h;       /* saf */
				stack2h[is][iv][it] += amp*amp*h;  /* sfa2 */
				stack2[is][iv][it] += amp*amp;     /* sa2 */
				stack[is][iv][it] += amp;          /* sa1 */
				break;
			    case 'p':
			    default:
				stack[is][iv][it] += amp;
				break;				
			} 
		    } /* t */
		} /* v */
	    } /* s */
	} /* h */
	
	if (ratio) {
	    for (is=0; is < ns; is++) {
		for (iv=0; iv < nv; iv++) {
		    for (it=0; it < nt; it++) {
			ib = it-nb;
			ie = it+nb+1;
			if (ib < 0) ib=0;
			if (ie > nt) ie=nt;
			num = 0.;
			den = 0.;
			for (i=ib; i < ie; i++) {
			    switch(type[0]) {
				case 'a':
				    /* (N*saf^2 + sa1^2*sf2 - 2*sa1*saf*sf)/((N*sf2 - sf^2)*sa2) */

				    num += nh*stackh[is][iv][i]*stackh[is][iv][i] + 
					sh2*stack[is][iv][i]*stack[is][iv][i] - 
					2.*sh*stack[is][iv][i]*stackh[is][iv][i];
				    den += stack2[is][iv][i];
				    break;
				case 'w':
				    /* 4*(sa1*sfa2 - sa2*saf)*(N*saf - sa1*sf)/(N*sfa2 - sa2*sf)^2 */

				    num += 
					(stack[is][iv][i]*stack2h[is][iv][i]-
					 stack2[is][iv][i]*stackh[is][iv][i])*
					(nh*stackh[is][iv][i]-stack[is][iv][i]*sh);
				    den += 
					(nh*stack2h[is][iv][i]-stack2[is][iv][i]*sh)*
					(nh*stack2h[is][iv][i]-stack2[is][iv][i]*sh);
				    break;
				case 's':
				default:
				    num += stack[is][iv][i]*stack[is][iv][i];
				den += stack2[is][iv][i];
				break;
			    }
			}
			    
			switch(type[0]) {
			    case 'a':
				den *= (nh*sh2-sh*sh);
				break;
			    case 'w':
				num *= 4.0f;
				break;
			    case 's':
				den *= nh;
				break;
			}

			trace[it] = (den > 0.)? num/den: 0.;
		    }
		    sf_floatwrite(trace,nt,scan);
		} /* v */
	    } /* s */
	} else {
	    sf_floatwrite (stack[0][0],nt*nv*ns,scan);
	}
    } /* x */
    sf_warning(".");
    
    exit(0);
}
コード例 #10
0
ファイル: Mprestolt.c プロジェクト: 717524640/src
int main(int argc, char* argv[])
{
    fint1 str;
    bool inv, stack, depth;
    int nt,nw,nx,ny,nh,nf, it,iw,ix,iy,ih, iw2;
    float dw,dx,dy,dh, x,y,h,xh, vel, w0, wh, w2, sq;
    float *trace=NULL, *keep=NULL;
    sf_file in=NULL, out=NULL;

    sf_init (argc,argv);
    in = sf_input("in");
    out = sf_output("out");

    if (!sf_getbool("inv",&inv)) inv=false;
    /* y: modeling, n: migration */

    if (!sf_getbool("depth",&depth)) depth=false;
    /* y: depth migration, n: time migration */

    if (!sf_getbool ("stack",&stack)) stack=true;
    /* if y: stack migrated image */

    if (inv) { /* modelling */
	if (!sf_histint(in,"n1",&nt)) sf_error("No n1= in input");
	if (!sf_histint(in,"n2",&nx)) nx=1;
	if (!sf_histint(in,"n3",&ny)) ny=1;
	
	if (!sf_getint ("nh",&nh)) sf_error("Need nh=");
	/* number of offsets */

	if (!sf_getfloat ("dh",&dh)) sf_error("Need dh=");
	/* offset sampling */

	dh = 1./(2*(nh-1)*dh);

	if (!sf_histfloat(in,"d2",&dx)) sf_error("No d2= in input");
	if (!sf_histfloat(in,"d3",&dy)) dy=dx;

	sf_putint(out,"n2",nh); sf_putfloat(out,"d2",dh);
	sf_putint(out,"n3",nx); sf_putfloat(out,"d3",dx);
	sf_putint(out,"n4",ny); sf_putfloat(out,"d4",dy);
	sf_putfloat(out,"o4",0.);
    } else { /* migration */
	if (!sf_histint(in,"n1",&nt)) sf_error("No n1= in input");
	if (!sf_histint(in,"n2",&nh)) nh=1;
	if (!sf_histint(in,"n3",&nx)) nx=1;
	if (!sf_histint(in,"n4",&ny)) ny=1;

	if (!sf_histfloat(in,"d2",&dh)) sf_error("No d2= in input");
	if (!sf_histfloat(in,"d3",&dx)) sf_error("No d3= in input");
	if (!sf_histfloat(in,"d4",&dy)) dy=dx;

	if (stack) {
	    sf_putint(out,"n2",nx); sf_putfloat(out,"d2",dx);
	    sf_putint(out,"n3",ny); sf_putfloat(out,"d3",dy);
	    sf_putint(out,"n4",1);
	}
    }

    if (!sf_getfloat ("vel",&vel)) sf_error("Need vel=");
    /* constant velocity */

    if (!sf_histfloat(in,"o1",&w0)) w0=0.;
    if (!sf_histfloat(in,"d1",&dw)) sf_error("No d1= in input");

    if (!sf_getint ("pad",&nw)) nw=nt;
    /* padding on the time axis */
    nw=2*(nw-1);

    sf_cosft_init(nw);
    dw = 2.*SF_PI/(nw*dw);
    dh *= 2.*SF_PI;
    dx *= 2.*SF_PI;
    dy *= 2.*SF_PI;

    if (depth) {
	if (inv) {
	    dw *= vel;
	} else {
	    dw *= 1./vel;
	}
    } else {
	dh *= vel;
	dx *= vel;
	dy *= vel;
    }

    trace = sf_floatalloc(nw);

    if (stack) keep = sf_floatalloc(nw);

    if (!sf_getint("extend",&nf)) nf=4;
    /* trace extension */

    str = fint1_init(nf,nw,0);

    for (iy = 0; iy < ny; iy++) {
	y = iy*dy;
	y *= y;
	for (ix = 0; ix < nx; ix++) {
	    x = ix*dx;
	    x *= x;

	    if (inv) {
		sf_floatread(trace,nt,in);
		for (it=nt; it < nw; it++) { /* pad */
		    trace[it]=0.;
		}
		
		sf_cosft_frw (trace,0,1);
		fint1_set(str,trace);
	    } else if (stack) {
		for (it=0; it < nw; it++) {
		    keep[it] = 0.;
		}
	    }

	    for (ih = 0; ih < nh; ih++) {
		h = ih * dh;
		h *= h;
		xh = x*h;
		h += x + y;

		if (!inv) {
		    sf_floatread(trace,nt,in);
		    for (it=nt; it < nw; it++) { /* pad */
			trace[it]=0.;
		    }

		    sf_cosft_frw (trace,0,1);
		    fint1_set(str,trace);
		}

		for (iw = 0; iw < nw; iw++) {
		    w2 = iw*dw;
		    w2 *= w2;

		    if (inv) { /* modeling */
			wh = w2-h;
			sq = wh*wh - 4.*xh;

			if (wh > 0. && sq > 0.) {
			    w2 = sqrtf(0.5*(wh + sqrtf (sq)))/dw;
			    iw2 = w2;
			    trace[iw] = (iw2 < nw)? 
				fint1_apply(str,iw2,w2-iw2,false):0.;
			} else {
			    trace[iw] = 0.;
			}
		    } else { /* migration */
			if (w2 == 0.) {
			    trace[iw] = 0.;
			} else {
			    w2 = sqrtf (w2 + h + xh/w2)/dw;
			    iw2 = w2;
			    trace[iw] = (iw2 < nw)? 
				fint1_apply(str,iw2,w2-iw2,false):0.;
			}
		    }
		}

		if (inv || !stack) {
		    sf_cosft_inv (trace,0,1);
		    sf_floatwrite(trace,nt,out);
		} else {
		    for (iw=0; iw < nw; iw++) {
			keep[iw] += trace[iw];
		    }
		}
	    } /* h */
	    if (!inv && stack) {
		sf_cosft_inv (keep,0,1);
		sf_floatwrite(keep,nt,out);
	    }
	} /* x */
    } /* y */

    exit (0);
}