示例#1
0
int disp_fileinfo(char *file, int n1, int n2, float f1, float f2, float d1, float d2, segy *hdrs)
{
	vmess("file %s contains", file);
    vmess("*** n1 = %d n2 = %d ntftt=%d", n1, n2, optncr(n1));
	vmess("*** d1 = %.5f d2 = %.5f", d1, d2);
	vmess("*** f1 = %.5f f2 = %.5f", f1, f2);
	vmess("*** fldr = %d sx = %d", hdrs[0].fldr, hdrs[0].sx);

	return 0;
}
示例#2
0
int getWaveletInfo(char *file_src, int *n1, int *n2, float *d1, float *d2, float *f1, float *f2, float *fmax, int *nxm, int verbose)
{
    FILE    *fp;
    size_t  nread, trace_sz;
    off_t   bytes;
    int     ret, one_shot, ntraces;
    int     optn, nfreq, i, iwmax;
    float   *trace;
	float   ampl, amplmax, tampl, tamplmax; 
    complex *ctrace;
    segy hdr;
    
    if (file_src == NULL) return 0; /* Input pipe can not be handled */
    else fp = fopen( file_src, "r" );
    assert( fp != NULL);
    nread = fread( &hdr, 1, TRCBYTES, fp );
    assert(nread == TRCBYTES);
    ret = fseeko( fp, 0, SEEK_END );
	if (ret<0) perror("fseeko");
    bytes = ftello( fp );

    *n1 = hdr.ns;
    if (hdr.trid == 1 || hdr.dt != 0) {
        *d1 = ((float) hdr.dt)*1.e-6;
        *f1 = ((float) hdr.delrt)/1000.;
		if (*d1 == 0.0) *d1 = hdr.d1;
    }
    else {
        *d1 = hdr.d1;
        *f1 = hdr.f1;
    }
    *f2 = hdr.f2;

    trace_sz = (size_t)(sizeof(float)*(*n1)+TRCBYTES);
    ntraces  = (int) (bytes/trace_sz);
	*n2 = ntraces;

    /* check to find out number of traces in shot gather */

	optn = optncr(*n1);
	nfreq = optn/2 + 1;
	ctrace = (complex *)malloc(nfreq*sizeof(complex));
    one_shot = 1;
    trace = (float *)malloc(optn*sizeof(float));
    fseeko( fp, TRCBYTES, SEEK_SET );

    while (one_shot) {
		memset(trace,0,optn*sizeof(float));
        nread = fread( trace, sizeof(float), *n1, fp );
        assert (nread == *n1);
		tamplmax = 0.0;
		for (i=0;i<(*n1);i++) {
			tampl = fabsf(trace[i]);
			if (tampl > tamplmax) tamplmax = tampl;
		}
		if (trace[0]*1e-3 > tamplmax) {
			fprintf(stderr,"WARNING: file_src has a large amplitude %f at t=0\n", trace[0]);
			fprintf(stderr,"This will introduce high frequencies and can cause dispersion.\n");
		}

		/* estimate maximum frequency assuming amplitude spectrum is smooth */
		rc1fft(trace,ctrace,optn,1);

		/* find maximum amplitude */
		amplmax = 0.0;
		iwmax = 0;
		for (i=0;i<nfreq;i++) {
			ampl = sqrt(ctrace[i].r*ctrace[i].r+ctrace[i].i*ctrace[i].i);
			if (ampl > amplmax) {
				amplmax = ampl;
				iwmax = i;
			}
		}
		/* from the maximum amplitude position look for the largest frequency
         * which has an amplitude 400 times weaker than the maximum amplitude */
		for (i=iwmax;i<nfreq;i++) {
			ampl = sqrt(ctrace[i].r*ctrace[i].r+ctrace[i].i*ctrace[i].i);
			if (400*ampl < amplmax) {
				*fmax = (i-1)*(1.0/(optn*(*d1)));
				break;
			}
		}

        nread = fread( &hdr, 1, TRCBYTES, fp );
        if (nread==0) break;
    }
	*nxm = (int)ntraces;

	if (verbose>2) {
		vmess("For file %s", file_src);
		vmess("nt=%d nx=%d", *n1, *n2);
		vmess("dt=%f dx=%f", *d1, *d2);
		vmess("fmax=%f", *fmax);
		vmess("tstart=%f", *f1);
	}

    fclose(fp);
    free(trace);
    free(ctrace);

    return 0;
}
示例#3
0
int main(int argc, char **argv)
{
	modPar mod;
	recPar rec;
	srcPar src;
	shotPar shot;
	rayPar ray;
    float *velocity, *slowness, *smooth, *trueslow, **inter;
	double t0, t1, t2, tinit, tray, tio;
	size_t size;
	int nw, n1, ix, iz, ir, ixshot, izshot;
	int nt, ntfft, nfreq, ig;
	int irec, sbox, ipos, nrx, nrz, nr;
    fcoord coordsx, coordgx, Time;
    icoord grid, isrc; 
    float Jr, *ampl, *time, *ttime, *ttime_p, cp_average, *wavelet, dw, dt;
	float dxrcv, dzrcv, rdelay, tr, dt_tmp;
    segy hdr;
    char filetime[1024], fileamp[1024], *method, *file_rcvtime, *file_src;
    size_t  nwrite, nread;
	int verbose;
    complex *cmute, *cwav;
    FILE *fpt, *fpa, *fpwav, *fprcv;

	t0= wallclock_time();
	initargs(argc,argv);
	requestdoc(0);

	if(!getparint("verbose",&verbose)) verbose=0;
    if(!getparint("sbox", &sbox)) sbox = 1;
    if(!getparstring("method", &method)) method="jesper";
	if (!getparfloat("rec_delay",&rdelay)) rdelay=0.0;

	getParameters(&mod, &rec, &src, &shot, &ray, verbose);

    /* read file_src if file_rcvtime is defined */

    if (!getparstring("file_rcvtime",&file_rcvtime)) file_rcvtime=NULL;

	if (file_rcvtime != NULL) {
    	if (!getparstring("file_src",&file_src)) file_src=NULL;
		if (!getparfloat("dt",&dt)) dt=0.004;
		if (file_src != NULL ) {
        	fpwav = fopen( file_src, "r" );
        	assert( fpwav != NULL);
        	nread = fread( &hdr, 1, TRCBYTES, fpwav );
        	assert(nread == TRCBYTES);
			ntfft = optncr(MAX(hdr.ns, rec.nt));
 			wavelet = (float *)calloc(ntfft,sizeof(float));
			/* read first trace */
        	nread = fread(wavelet, sizeof(float), hdr.ns, fpwav);
        	assert (nread == hdr.ns);
        	fclose(fpwav);
		}
		else {
			ntfft = optncr(rec.nt);
 			wavelet = (float *)calloc(ntfft,sizeof(float));
			wavelet[0] = 1.0;
		}
    	nfreq = ntfft/2+1;
    	cwav    = (complex *)calloc(nfreq,sizeof(complex));
    	cmute   = (complex *)calloc(nfreq,sizeof(complex));
        rc1fft(wavelet,cwav,ntfft,-1);
    	dw      = 2*M_PI/(ntfft*dt);
	}

	/* allocate arrays for model parameters: the different schemes use different arrays */

	n1 = mod.nz;
    if(!strcmp(method,"fd")) nw = 0;
    else nw = ray.smoothwindow;

	velocity = (float *)calloc(mod.nx*mod.nz,sizeof(float));
	slowness = (float *)calloc((mod.nx+2*nw)*(mod.nz+2*nw),sizeof(float));
    trueslow = (float *)calloc(mod.nx*mod.nz,sizeof(float));

    if(!strcmp(method,"fd")) {
		ttime = (float *)calloc(mod.nx*mod.nz,sizeof(float));
	}

	/* read velocity and density files */
	readModel(mod, velocity, slowness, nw);

	/* allocate arrays for wavefield and receiver arrays */

	size = shot.n*rec.n;
    time = (float *)calloc(size,sizeof(float));
    ampl = (float *)calloc(size,sizeof(float));

	/* Sinking source and receiver arrays: 
	   If P-velocity==0 the source and receiver 
	   postions are placed deeper until the P-velocity changes. 
	   Setting the option rec.sinkvel only sinks the receiver position 
       (not the source) and uses the velocity 
	   of the first receiver to sink through to the next layer. */

/* sink receivers to value different than sinkvel */
	for (ir=0; ir<rec.n; ir++) {
		iz = rec.z[ir];
		ix = rec.x[ir];
		while(velocity[(ix)*n1+iz] == rec.sinkvel) iz++;
		rec.z[ir]=iz+rec.sinkdepth;
		rec.zr[ir]=rec.zr[ir]+(rec.z[ir]-iz)*mod.dz;
//		rec.zr[ir]=rec.z[ir]*mod.dz;
		if (verbose>3) vmess("receiver position %d at grid[ix=%d, iz=%d] = (x=%f z=%f)", ir, ix, rec.z[ir], rec.xr[ir]+mod.x0, rec.zr[ir]+mod.z0);
	}
		vmess("   - method for ray-tracing       = %s", method);
/*
*/

/* sink sources to value different than zero */
	for (izshot=0; izshot<shot.nz; izshot++) {
		for (ixshot=0; ixshot<shot.nx; ixshot++) {
			iz = shot.z[izshot];
			ix = shot.x[ixshot];
			while(velocity[(ix)*n1+iz] == 0.0) iz++;
			shot.z[izshot]=iz+src.sinkdepth; 
		}
	}

	if (verbose>3) writeSrcRecPos(&mod, &rec, &src, &shot);

    /* smooth slowness grid */
    grid.x = mod.nx;
    grid.z = mod.nz;
    grid.y = 1;
    if ( nw != 0 ) { /* smooth slowness */ 
        smooth = (float *)calloc(grid.x*grid.z,sizeof(float));
        applyMovingAverageFilter(slowness, grid, nw, 2, smooth);
        memcpy(slowness,smooth,grid.x*grid.z*sizeof(float));
        free(smooth);
	}

    /* prepare output file and headers */
    strcpy(filetime, rec.file_rcv);
    name_ext(filetime, "_time");
    fpt = fopen(filetime, "w");
    assert(fpt != NULL);

	if (ray.geomspread) {
        strcpy(fileamp, rec.file_rcv);
        name_ext(fileamp, "_amp");
        fpa = fopen(fileamp, "w");
        assert(fpa != NULL);
	}
	if (file_rcvtime != NULL) {
        fprcv = fopen(file_rcvtime, "w");
        assert(fprcv != NULL);
	}

    memset(&hdr,0,sizeof(hdr));
    hdr.scalco = -1000;
    hdr.scalel = -1000;
    hdr.trid   = 0;

	t1=wallclock_time();
	tinit = t1-t0;
    tray=0.0;
    tio=0.0;

	/* Outer loop over number of shots */
	for (izshot=0; izshot<shot.nz; izshot++) {
		for (ixshot=0; ixshot<shot.nx; ixshot++) {

	        t2=wallclock_time();
        	if (verbose) {
            	vmess("Modeling source %d at gridpoints ix=%d iz=%d", (izshot*shot.n)+ixshot, shot.x[ixshot], shot.z[izshot]);
            	vmess(" which are actual positions x=%.2f z=%.2f", mod.x0+mod.dx*shot.x[ixshot], mod.z0+mod.dz*shot.z[izshot]);
            	vmess("Receivers at gridpoint x-range ix=%d - %d", rec.x[0], rec.x[rec.n-1]);
            	vmess(" which are actual positions x=%.2f - %.2f", mod.x0+rec.xr[0], mod.x0+rec.xr[rec.n-1]);
            	vmess("Receivers at gridpoint z-range iz=%d - %d", rec.z[0], rec.z[rec.n-1]);
            	vmess(" which are actual positions z=%.2f - %.2f", mod.z0+rec.zr[0], mod.z0+rec.zr[rec.n-1]);
        	}

        	coordsx.x = shot.x[ixshot]*mod.dx;
        	coordsx.z = shot.z[izshot]*mod.dz;
        	coordsx.y = 0;

	        t1=wallclock_time();
            tio += t1-t2;

            if (!strcmp(method,"jesper")) {
#pragma omp parallel for default(shared) \
private (coordgx,irec,Time,Jr) 
        		for (irec=0; irec<rec.n; irec++) {
            		coordgx.x=rec.xr[irec];
            		coordgx.z=rec.zr[irec];
            		coordgx.y = 0;
		
            		getWaveParameter(slowness, grid, mod.dx, coordsx, coordgx, ray, &Time, &Jr);
	
            		time[((izshot*shot.nx)+ixshot)*rec.n + irec] = Time.x + Time.y + 0.5*Time.z;
            		ampl[((izshot*shot.nx)+ixshot)*rec.n + irec] = Jr;
            		if (verbose>4) vmess("JS: shot=%f,%f receiver at %f,%f T0=%f T1=%f T2=%f Jr=%f",coordsx.x, coordsx.z, coordgx.x, coordgx.z, Time.x, Time.y, Time.z, Jr); 
        		}
			}
            else if(!strcmp(method,"fd")) {
	            int mzrcv;

                isrc.x = shot.x[ixshot];
                isrc.y = 0;
                isrc.z = shot.z[izshot];

                mzrcv = 0;
                for (irec = 0; irec < rec.n; irec++) mzrcv = MAX(rec.z[irec], mzrcv);

                vidale(ttime,slowness,&isrc,grid,mod.dx,sbox, mzrcv);
        		for (irec=0; irec<rec.n; irec++) {
            		coordgx.x=mod.x0+rec.xr[irec];
            		coordgx.z=mod.z0+rec.zr[irec];
            		coordgx.y = 0;
					ipos = ((izshot*shot.nx)+ixshot)*rec.n + irec;
	
            		time[ipos] = ttime[rec.z[irec]*mod.nx+rec.x[irec]];
					/* compute average velocity between source and receiver */
 					nrx = (rec.x[irec]-isrc.x);
 					nrz = (rec.z[irec]-isrc.z);
 					nr = abs(nrx) + abs(nrz);
					cp_average = 0.0;
        			for (ir=0; ir<nr; ir++) {
						ix = isrc.x + floor((ir*nrx)/nr);
						iz = isrc.z + floor((ir*nrz)/nr);
						//fprintf(stderr,"ir=%d ix=%d iz=%d velocity=%f\n", ir, ix, iz, velocity[ix*mod.nz+iz]);
						cp_average += velocity[ix*mod.nz+iz];
					}
					cp_average = cp_average/((float)nr);
            		ampl[ipos] = sqrt(time[ipos]*cp_average);
            		if (verbose>4) vmess("FD: shot=%f,%f receiver at %f(%d),%f(%d) T=%e V=%f Ampl=%f",coordsx.x, coordsx.z, coordgx.x, rec.x[irec], coordgx.z, rec.z[irec], time[ipos], cp_average, ampl[ipos]); 
        		}
            }
	        t2=wallclock_time();
            tray += t2-t1;

        	hdr.sx     = 1000*(mod.x0+mod.dx*shot.x[ixshot]);
        	hdr.sdepth = 1000*(mod.z0+mod.dz*shot.z[izshot]);
        	hdr.selev  = (int)(-1000.0*(mod.z0+mod.dz*shot.z[izshot]));
        	hdr.fldr   = ((izshot*shot.nx)+ixshot)+1;
        	hdr.tracl  = ((izshot*shot.nx)+ixshot)+1;
        	hdr.tracf  = ((izshot*shot.nx)+ixshot)+1;
        	hdr.ntr    = shot.n;
    		hdr.dt     = (unsigned short)1;
    		hdr.trwf   = shot.n;
    		hdr.ns     = rec.n;
        	//hdr.d1     = (rec.x[1]-rec.x[0])*mod.dx; // discrete
        	hdr.d1     = (rec.xr[1]-rec.xr[0]);
        	hdr.f1     = mod.x0+rec.x[0]*mod.dx;
        	hdr.d2     = (shot.x[MIN(shot.n-1,1)]-shot.x[0])*mod.dx;
        	hdr.f2     = mod.x0+shot.x[0]*mod.dx;
			dt_tmp = (fabs(hdr.d1*((float)hdr.scalco)));
			hdr.dt	   = (unsigned short)dt_tmp;
    
        	nwrite = fwrite( &hdr, 1, TRCBYTES, fpt);
        	assert(nwrite == TRCBYTES);
        	nwrite = fwrite( &time[((izshot*shot.nx)+ixshot)*rec.n], sizeof(float), rec.n, fpt);
        	assert(nwrite == rec.n);
	    	fflush(fpt);
	    	if (ray.geomspread) {
            	nwrite = fwrite( &hdr, 1, TRCBYTES, fpa);
            	assert(nwrite == TRCBYTES);
            	nwrite = fwrite( &ampl[((izshot*shot.nx)+ixshot)*rec.n], sizeof(float), rec.n, fpa);
            	assert(nwrite == rec.n);
	        	fflush(fpa);
        	}
			if (file_rcvtime != NULL) {
    			hdr.ns     = rec.nt;
    			hdr.trwf   = rec.n;
    			hdr.ntr    = ((izshot*shot.nx)+ixshot+1)*rec.n;
    			hdr.dt     = dt*1000000;
    			hdr.d1     = dt;
        		hdr.f1     = 0.0;
        		hdr.d2     = (rec.xr[1]-rec.xr[0]);
    			hdr.f2     = mod.x0+rec.x[0]*mod.dx;

        		for (irec=0; irec<rec.n; irec++) {
					ipos = ((izshot*shot.nx)+ixshot)*rec.n + irec;
        			hdr.tracf  = irec+1;
        			hdr.tracl  = ((izshot*shot.nx)+ixshot*shot.nz)+irec+1;
        			hdr.gx     = 1000*(mod.x0+rec.xr[irec]);
        			hdr.offset = (rec.xr[irec]-shot.x[ixshot]*mod.dx);
        			hdr.gelev  = (int)(-1000*(mod.z0+rec.zr[irec]));

					tr = time[ipos]+rdelay;
                    for (ig=0; ig<nfreq; ig++) {
                        cmute[ig].r = (cwav[ig].r*cos(ig*dw*tr-M_PI/4.0)-cwav[ig].i*sin(ig*dw*tr-M_PI/4.0))/(ntfft*ampl[ipos]);
                        cmute[ig].i = (cwav[ig].i*cos(ig*dw*tr-M_PI/4.0)+cwav[ig].r*sin(ig*dw*tr-M_PI/4.0))/(ntfft*ampl[ipos]);
                    }
                	cr1fft(cmute,wavelet,ntfft,-1);
        			nwrite = fwrite( &hdr, 1, TRCBYTES, fprcv);
        			nwrite = fwrite( wavelet, sizeof(float), rec.nt, fprcv );
				}
			}
	        t1=wallclock_time();
            tio += t1-t2;
    	} /* end of ixshot loop */
	} /* end of loop over number of shots */
	fclose(fpt);
	if (file_rcvtime != NULL) fclose(fprcv);
	if (ray.geomspread) fclose(fpa);

	t1= wallclock_time();
	if (verbose) {
		vmess("*******************************************");
		vmess("************* runtime info ****************");
		vmess("*******************************************");
		vmess("Total compute time ray-tracing    = %.2f s.", t1-t0);
		vmess("   - intializing arrays and model = %.3f", tinit);
		vmess("   - ray tracing                  = %.3f", tray);
		vmess("   - writing data to file         = %.3f", tio);
	}

	/* free arrays */

	initargs(argc,argv); /* this will free the arg arrays declared */
	free(velocity);
	free(slowness);
	
	return 0;
}
示例#4
0
int writeRec(recPar rec, modPar mod, bndPar bnd, wavPar wav, int ixsrc, int izsrc, int nsam, int ishot, int fileno, 
			 float *rec_vx, float *rec_vz, float *rec_txx, float *rec_tzz, float *rec_txz, 
			 float *rec_p, float *rec_pp, float *rec_ss, float *rec_udp, float *rec_udvz, int verbose)
{
    FILE    *fpvx, *fpvz, *fptxx, *fptzz, *fptxz, *fpp, *fppp, *fpss, *fpup, *fpdown;
	float *rec_up, *rec_down, *trace, *rec_vze, *rec_pe;
	float dx, dt, cp, rho, fmin, fmax;
	complex *crec_vz, *crec_p, *crec_up, *crec_dw;
    int irec, ntfft, nfreq, nkx, xorig, ix, iz, it, ibndx;
	int append;
	double ddt;
	char number[16], filename[1024];
    segy hdr;
    
	if (!rec.n) return 0;
	if (ishot) append=1;
	else append=0;

	/* if the total number of samples exceeds rec_ntsam then a new (numbered) file is opened */
	/* fileno has a non-zero value (from fdelmodc.c) if the number of samples exceeds rec_ntsam. */
	strcpy(filename, rec.file_rcv);
	if (fileno) {
		sprintf(number,"_%03d",fileno);
		name_ext(filename, number);
	}

	if (verbose>2) vmess("Writing receiver data to file %s", filename);
	if (nsam != rec.nt && verbose) vmess("Number of samples written to last file = %d",nsam);

	memset(&hdr,0,TRCBYTES);
	ddt = (double)mod.dt;/* to avoid rounding in 32 bit precision */
    dt  = (float)ddt*rec.skipdt;
	dx  = (rec.x[1]-rec.x[0])*mod.dx;
	hdr.dt     = (unsigned short)lround((((double)1.0e6*ddt*rec.skipdt)));
	hdr.scalco = -1000;
	hdr.scalel = -1000;
	hdr.sx     = 1000*(mod.x0+ixsrc*mod.dx);
	hdr.sdepth = 1000*(mod.z0+izsrc*mod.dz);
    hdr.selev  = (int)(-1000.0*(mod.z0+izsrc*mod.dz));
	hdr.fldr   = ishot+1;
	hdr.trid   = 1;
	hdr.ns     = nsam;
	hdr.trwf   = rec.n;
	hdr.ntr    = (ishot+1)*rec.n;
	hdr.f1     = 0.0;
	hdr.d1     = mod.dt*rec.skipdt;
	hdr.d2     = (rec.x[1]-rec.x[0])*mod.dx;
	hdr.f2     = mod.x0+rec.x[0]*mod.dx;

	if (rec.type.vx)  fpvx  = fileOpen(filename, "_rvx", append);
	if (rec.type.vz)  fpvz  = fileOpen(filename, "_rvz", append);
	if (rec.type.p)   fpp   = fileOpen(filename, "_rp", append);
	if (rec.type.txx) fptxx = fileOpen(filename, "_rtxx", append);
	if (rec.type.tzz) fptzz = fileOpen(filename, "_rtzz", append);
	if (rec.type.txz) fptxz = fileOpen(filename, "_rtxz", append);
	if (rec.type.pp)  fppp  = fileOpen(filename, "_rpp", append);
	if (rec.type.ss)  fpss  = fileOpen(filename, "_rss", append);

	/* decomposed wavefield */
	if (rec.type.ud && (mod.ischeme==1 || mod.ischeme==2) )  {
		fpup   = fileOpen(filename, "_ru", append);
		fpdown = fileOpen(filename, "_rd", append);
		ntfft = optncr(nsam);
		nfreq = ntfft/2+1;
		fmin = 0.0;
		fmax = wav.fmax;
		nkx = optncc(2*mod.nax);
		ibndx = mod.ioPx;
    	if (bnd.lef==4 || bnd.lef==2) ibndx += bnd.ntap;
		cp  = rec.cp;
		rho = rec.rho;
		if (verbose) vmess("Decomposition array at z=%.2f with cp=%.2f rho=%.2f", rec.zr[0]+mod.z0, cp, rho);
		rec_up  = (float *)calloc(ntfft*nkx,sizeof(float));
		rec_down= (float *)calloc(ntfft*nkx,sizeof(float));
		crec_vz = (complex *)malloc(nfreq*nkx*sizeof(complex));
		crec_p  = (complex *)malloc(nfreq*nkx*sizeof(complex));
		crec_up = (complex *)malloc(nfreq*nkx*sizeof(complex));
		crec_dw = (complex *)malloc(nfreq*nkx*sizeof(complex));

		rec_vze = rec_up;
		rec_pe  = rec_down;
		/* copy input data into extended arrays with padded zeroes */
		for (ix=0; ix<mod.nax; ix++) {
			memcpy(&rec_vze[ix*ntfft],&rec_udvz[ix*rec.nt],nsam*sizeof(float));
			memcpy(&rec_pe[ix*ntfft], &rec_udp[ix*rec.nt], nsam*sizeof(float));
		}

		/* transform from t-x to kx-w */
		xorig = ixsrc+ibndx;
		xt2wkx(rec_vze, crec_vz, ntfft, nkx, ntfft, nkx, xorig);
		xt2wkx(rec_pe, crec_p, ntfft, nkx, ntfft, nkx, xorig);

		/* apply decomposition operators */
		kxwdecomp(crec_p, crec_vz, crec_up, crec_dw,
               nkx, mod.dx, nsam, dt, fmin, fmax, cp, rho, verbose);

		/* transform back to t-x */
		wkx2xt(crec_up, rec_up, ntfft, nkx, nkx, ntfft, xorig);
		wkx2xt(crec_dw, rec_down, ntfft, nkx, nkx, ntfft, xorig);

		/* reduce array to rec.nt samples rec.n traces */
		for (irec=0; irec<rec.n; irec++) {
			ix = rec.x[irec]+ibndx;
			for (it=0; it<rec.nt; it++) {
				rec_up[irec*rec.nt+it]   = rec_up[ix*ntfft+it];
				rec_down[irec*rec.nt+it] = rec_down[ix*ntfft+it];
			}
		}
		free(crec_vz);
		free(crec_p);
		free(crec_up);
		free(crec_dw);
	}
	if (rec.type.ud && (mod.ischeme==3 || mod.ischeme==4) )  {
	}

	for (irec=0; irec<rec.n; irec++) {
		hdr.tracf  = irec+1;
		hdr.tracl  = ishot*rec.n+irec+1;
		hdr.gx     = 1000*(mod.x0+rec.x[irec]*mod.dx);
		hdr.offset = (rec.x[irec]-ixsrc)*mod.dx;
        hdr.gelev  = (int)(-1000*(mod.z0+rec.z[irec]*mod.dz));

		if (rec.type.vx) {
			traceWrite( &hdr, &rec_vx[irec*rec.nt], nsam, fpvx) ;
		}
		if (rec.type.vz) {
			traceWrite( &hdr, &rec_vz[irec*rec.nt], nsam, fpvz) ;
		}
		if (rec.type.p) {
			traceWrite( &hdr, &rec_p[irec*rec.nt], nsam, fpp) ;
		}
		if (rec.type.txx) {
			traceWrite( &hdr, &rec_txx[irec*rec.nt], nsam, fptxx) ;
		}
		if (rec.type.tzz) {
			traceWrite( &hdr, &rec_tzz[irec*rec.nt], nsam, fptzz) ;
		}
		if (rec.type.txz) {
			traceWrite( &hdr, &rec_txz[irec*rec.nt], nsam, fptxz) ;
		}
		if (rec.type.pp) {
			traceWrite( &hdr, &rec_pp[irec*rec.nt], nsam, fppp) ;
		}
		if (rec.type.ss) {
			traceWrite( &hdr, &rec_ss[irec*rec.nt], nsam, fpss) ;
		}
		if (rec.type.ud && mod.ischeme==1)  {
			traceWrite( &hdr, &rec_up[irec*rec.nt], nsam, fpup) ;
			traceWrite( &hdr, &rec_down[irec*rec.nt], nsam, fpdown) ;
		}
	}

	if (rec.type.vx) fclose(fpvx);
	if (rec.type.vz) fclose(fpvz);
	if (rec.type.p) fclose(fpp);
	if (rec.type.txx) fclose(fptxx);
	if (rec.type.tzz) fclose(fptzz);
	if (rec.type.txz) fclose(fptxz);
	if (rec.type.pp) fclose(fppp);
	if (rec.type.ss) fclose(fpss);
	if (rec.type.ud) {
		fclose(fpup);
		fclose(fpdown);
		free(rec_up);
		free(rec_down);
	}

    return 0;
}
int main (int argc, char **argv)
{
    FILE    *fp_out, *fp_f1plus, *fp_f1min;
    FILE    *fp_gmin, *fp_gplus, *fp_f2, *fp_pmin;
    int     i, j, l, ret, nshots, Nsyn, nt, nx, nts, nxs, ngath;
    int     size, n1, n2, ntap, tap, di, ntraces, nb, ib;
    int     nw, nw_low, nw_high, nfreq, *xnx, *xnxsyn, *synpos;
    int     reci, mode, ixa, ixb, n2out, verbose, ntfft;
    int     iter, niter, niterh, tracf, *muteW, pad, nt0, ampest, *hmuteW, *hxnxsyn;
    int     hw, smooth, above, shift, *ixpossyn, npossyn, ix, first=1;
    float   fmin, fmax, *tapersh, *tapersy, fxf, dxf, fxs2, *xsrc, *xrcv, *zsyn, *zsrc, *xrcvsyn;
	float	*hzsyn, *hxsyn, *hxrcvsyn, *hG_d, xloc, zloc, *HomG;
    double  t0, t1, t2, t3, tsyn, tread, tfft, tcopy, energyNi, *J;
    float   d1, d2, f1, f2, fxs, ft, fx, *xsyn, dxsrc, Q, f0, *Costdet;
    float   *green, *f2p, *pmin, *G_d, dt, dx, dxs, scl, mem, *Image, *Image2;
    float   *f1plus, *f1min, *iRN, *Ni, *trace, *Gmin, *Gplus, *Gm0;
    float   xmin, xmax, weight, tsq, *Gd, *amp, bstart, bend, db, *bdet, bp, b, bmin;
    complex *Refl, *Fop, *cshot;
    char    *file_tinv, *file_shot, *file_green, *file_iter, *file_wav, *file_ray, *file_amp, *file_img, *file_cp, *file_rays, *file_amps;
    char    *file_f1plus, *file_f1min, *file_gmin, *file_gplus, *file_f2, *file_pmin, *wavtype, *wavtype2, *file_homg, *file_tinvs;
    segy    *hdrs_im, *hdrs_homg;
	WavePar WP,WPs;
	modPar mod;
    recPar rec;
    srcPar src;
    shotPar shot;
    rayPar ray;

    initargs(argc, argv);
    requestdoc(1);

    tsyn = tread = tfft = tcopy = 0.0;
    t0   = wallclock_time();

	if (!getparstring("file_img", &file_img)) file_img = "img.su";
	if (!getparstring("file_homg", &file_homg)) file_homg = NULL;
    if (!getparstring("file_shot", &file_shot)) file_shot = NULL;
    if (!getparstring("file_tinv", &file_tinv)) file_tinv = NULL;
	if (!getparstring("file_tinvs", &file_tinvs)) file_tinvs = NULL;
    if (!getparstring("file_f1plus", &file_f1plus)) file_f1plus = NULL;
    if (!getparstring("file_f1min", &file_f1min)) file_f1min = NULL;
    if (!getparstring("file_gplus", &file_gplus)) file_gplus = NULL;
    if (!getparstring("file_gmin", &file_gmin)) file_gmin = NULL;
    if (!getparstring("file_pplus", &file_f2)) file_f2 = NULL;
    if (!getparstring("file_f2", &file_f2)) file_f2 = NULL;
    if (!getparstring("file_pmin", &file_pmin)) file_pmin = NULL;
    if (!getparstring("file_iter", &file_iter)) file_iter = NULL;
	if (!getparstring("file_wav", &file_wav)) file_wav=NULL;
	if (!getparstring("file_ray", &file_ray)) file_ray=NULL;
	if (!getparstring("file_amp", &file_amp)) file_amp=NULL;
	if (!getparstring("file_rays", &file_rays)) file_rays=NULL;
    if (!getparstring("file_amps", &file_amps)) file_amps=NULL;
	if (!getparstring("file_cp", &file_cp)) file_cp = NULL;
    if (!getparint("verbose", &verbose)) verbose = 0;
    if (file_tinv == NULL && file_shot == NULL) 
        verr("file_tinv and file_shot cannot be both input pipe");
    if (!getparstring("file_green", &file_green)) {
        if (verbose) vwarn("parameter file_green not found, assume pipe");
        file_green = NULL;
    }
    if (!getparfloat("fmin", &fmin)) fmin = 0.0;
    if (!getparfloat("fmax", &fmax)) fmax = 70.0;
    if (!getparint("ixa", &ixa)) ixa = 0;
    if (!getparint("ixb", &ixb)) ixb = ixa;
//    if (!getparint("reci", &reci)) reci = 0;
	reci=0; // source-receiver reciprocity is not yet fully build into the code
    if (!getparfloat("weight", &weight)) weight = 1.0;
	if (!getparfloat("tsq", &tsq)) tsq = 0.0;
	if (!getparfloat("Q", &Q)) Q = 0.0;
	if (!getparfloat("f0", &f0)) f0 = 0.0;
    if (!getparint("tap", &tap)) tap = 0;
    if (!getparint("ntap", &ntap)) ntap = 0;
	if (!getparint("pad", &pad)) pad = 0;

    if(!getparint("hw", &hw)) hw = 15;
    if(!getparint("smooth", &smooth)) smooth = 5;
    if(!getparint("above", &above)) above = 0;
    if(!getparint("shift", &shift)) shift=12;
	if(!getparint("ampest", &ampest)) ampest=0;
	if(!getparint("nb", &nb)) nb=0;
	if (!getparfloat("bstart", &bstart)) bstart = 1.0;
    if (!getparfloat("bend", &bend)) bend = 1.0;

    if (reci && ntap) vwarn("tapering influences the reciprocal result");

	/* Reading in wavelet parameters */
    if(!getparfloat("fpw", &WP.fp)) WP.fp = -1.0;
    if(!getparfloat("fminw", &WP.fmin)) WP.fmin = 10.0;
    if(!getparfloat("flefw", &WP.flef)) WP.flef = 20.0;
    if(!getparfloat("frigw", &WP.frig)) WP.frig = 50.0;
    if(!getparfloat("fmaxw", &WP.fmax)) WP.fmax = 60.0;
    else WP.fp = -1;
    if(!getparfloat("dbw", &WP.db)) WP.db = -20.0;
    if(!getparfloat("t0w", &WP.t0)) WP.t0 = 0.0;
    if(!getparint("shiftw", &WP.shift)) WP.shift = 0;
    if(!getparint("invw", &WP.inv)) WP.inv = 0;
    if(!getparfloat("epsw", &WP.eps)) WP.eps = 1.0;
    if(!getparfloat("scalew", &WP.scale)) WP.scale = 1.0;
    if(!getparint("scfftw", &WP.scfft)) WP.scfft = 1;
    if(!getparint("cmw", &WP.cm)) WP.cm = 10;
    if(!getparint("cnw", &WP.cn)) WP.cn = 1;
	if(!getparint("wav", &WP.wav)) WP.wav = 0;
	if(!getparstring("file_wav", &WP.file_wav)) WP.file_wav=NULL;
    if(!getparstring("w", &wavtype)) strcpy(WP.w, "g2");
    else strcpy(WP.w, wavtype);

	if(!getparfloat("fpws", &WPs.fp)) WPs.fp = -1.0;
    if(!getparfloat("fminws", &WPs.fmin)) WPs.fmin = 10.0;
    if(!getparfloat("flefws", &WPs.flef)) WPs.flef = 20.0;
    if(!getparfloat("frigws", &WPs.frig)) WPs.frig = 50.0;
    if(!getparfloat("fmaxws", &WPs.fmax)) WPs.fmax = 60.0;
    else WPs.fp = -1;
    if(!getparfloat("dbw", &WPs.db)) WPs.db = -20.0;
    if(!getparfloat("t0ws", &WPs.t0)) WPs.t0 = 0.0;
    if(!getparint("shiftws", &WPs.shift)) WPs.shift = 0;
    if(!getparint("invws", &WPs.inv)) WPs.inv = 0;
    if(!getparfloat("epsws", &WPs.eps)) WPs.eps = 1.0;
    if(!getparfloat("scalews", &WPs.scale)) WPs.scale = 1.0;
    if(!getparint("scfftws", &WPs.scfft)) WPs.scfft = 1;
    if(!getparint("cmws", &WPs.cm)) WPs.cm = 10;
    if(!getparint("cnws", &WPs.cn)) WPs.cn = 1;
    if(!getparint("wavs", &WPs.wav)) WPs.wav = 0;
    if(!getparstring("file_wavs", &WPs.file_wav)) WPs.file_wav=NULL;
    if(!getparstring("ws", &wavtype2)) strcpy(WPs.w, "g2");
    else strcpy(WPs.w, wavtype2);
	if(!getparint("niter", &niter)) niter = 10;
	if(!getparint("niterh", &niterh)) niterh = niter;

/*================ Reading info about shot and initial operator sizes ================*/

    ngath = 0; /* setting ngath=0 scans all traces; n2 contains maximum traces/gather */
	if (file_ray!=NULL && file_tinv==NULL) {
		ret = getFileInfo(file_ray, &n2, &n1, &ngath, &d1, &d2, &f2, &f1, &xmin, &xmax, &scl, &ntraces);
		n1 = 1;
		ntraces = n2*ngath;
		scl = 0.0010;
		d1 = -1.0*xmin;
		xmin = -1.0*xmax;
		xmax = d1;
		WP.wav = 1;
        WP.xloc = -123456.0;
        WP.zloc = -123456.0;
		synpos = (int *)calloc(ngath,sizeof(int));
		shot.nz = 1;
		shot.nx = ngath;
		shot.n = shot.nx*shot.nz;
		for (l=0; l<shot.nz; l++) {
            for (j=0; j<shot.nx; j++) {
                synpos[l*shot.nx+j] = j*shot.nz+l;
            }
        }
	}
	else if (file_ray==NULL && file_tinv==NULL) {
		getParameters(&mod, &rec, &src, &shot, &ray, verbose);
		n1 = 1;
		n2 = rec.n;
		ngath = shot.n;
		d1 = mod.dt;
		d2 = (rec.x[1]-rec.x[0])*mod.dx;
		f1 = 0.0;
		f2 = mod.x0+rec.x[0]*mod.dx;
		xmin = mod.x0+rec.x[0]*mod.dx;
		xmax = mod.x0+rec.x[rec.n-1]*mod.dx;
		scl = 0.0010;
		ntraces = n2*ngath;
		WP.wav = 1;
		WP.xloc = -123456.0;
		WP.zloc = -123456.0;
		synpos = (int *)calloc(ngath,sizeof(int));
		for (l=0; l<shot.nz; l++) {
			for (j=0; j<shot.nx; j++) {
				synpos[l*shot.nx+j] = j*shot.nz+l;
			}
		}
	}
	else {
    	ret = getFileInfo(file_tinv, &n1, &n2, &ngath, &d1, &d2, &f1, &f2, &xmin, &xmax, &scl, &ntraces);
	}

    Nsyn = ngath;
    nxs = n2; 
    nts = n1;
	nt0 = n1;
    dxs = d2; 
    fxs = f2;

    ngath = 0; /* setting ngath=0 scans all traces; nx contains maximum traces/gather */
    ret = getFileInfo(file_shot, &nt, &nx, &ngath, &d1, &dx, &ft, &fx, &xmin, &xmax, &scl, &ntraces);
    nshots = ngath;
	assert (nxs >= nshots);

    if (!getparfloat("dt", &dt)) dt = d1;

    ntfft = optncr(MAX(nt+pad, nts+pad)); 
    nfreq = ntfft/2+1;
    nw_low = (int)MIN((fmin*ntfft*dt), nfreq-1);
    nw_low = MAX(nw_low, 1);
    nw_high = MIN((int)(fmax*ntfft*dt), nfreq-1);
    nw  = nw_high - nw_low + 1;
    scl   = 1.0/((float)ntfft);

	if (nb > 1) {
		db	= (bend-bstart)/((float)(nb-1));
	}
	else if (nb == 1) {
		db = 0;
		bend = bstart;
	}
    
/*================ Allocating all data arrays ================*/

    green   = (float *)calloc(Nsyn*nxs*ntfft,sizeof(float));
    f2p     = (float *)calloc(Nsyn*nxs*ntfft,sizeof(float));
    pmin    = (float *)calloc(Nsyn*nxs*ntfft,sizeof(float));
    f1plus  = (float *)calloc(Nsyn*nxs*ntfft,sizeof(float));
    f1min   = (float *)calloc(Nsyn*nxs*ntfft,sizeof(float));
    G_d     = (float *)calloc(Nsyn*nxs*ntfft,sizeof(float));
    muteW   = (int *)calloc(Nsyn*nxs,sizeof(int));
    trace   = (float *)malloc(ntfft*sizeof(float));
    ixpossyn = (int *)malloc(nxs*sizeof(int));
    xrcvsyn = (float *)calloc(Nsyn*nxs,sizeof(float));
    xsyn    = (float *)malloc(Nsyn*sizeof(float));
    zsyn    = (float *)malloc(Nsyn*sizeof(float));
    xnxsyn  = (int *)calloc(Nsyn,sizeof(int));
    tapersy = (float *)malloc(nxs*sizeof(float));

    Refl    = (complex *)malloc(nw*nx*nshots*sizeof(complex));
    tapersh = (float *)malloc(nx*sizeof(float));
    xsrc    = (float *)calloc(nshots,sizeof(float));
    zsrc    = (float *)calloc(nshots,sizeof(float));
    xrcv    = (float *)calloc(nshots*nx,sizeof(float));
    xnx     = (int *)calloc(nshots,sizeof(int));

/*================ Read and define mute window based on focusing operator(s) ================*/
/* G_d = p_0^+ = G_d (-t) ~ Tinv */

	WPs.nt = ntfft;
	WPs.dt = dt;
	WP.nt = ntfft;
	WP.dt = dt;

	if (file_ray!=NULL || file_cp!=NULL) {
		makeWindow(WP, file_ray, file_amp, dt, xrcvsyn, xsyn, zsyn, xnxsyn,
             Nsyn, nxs, ntfft, mode, muteW, G_d, hw, verbose);
	}
	else {
    	mode=-1; /* apply complex conjugate to read in data */
    	readTinvData(file_tinv, dt, xrcvsyn, xsyn, zsyn, xnxsyn, 
			 Nsyn, nxs, ntfft, mode, muteW, G_d, hw, verbose);
	}
	/* reading data added zero's to the number of time samples to be the same as ntfft */
    nts   = ntfft;
                         
	/* define tapers to taper edges of acquisition */
    if (tap == 1 || tap == 3) {
        for (j = 0; j < ntap; j++)
            tapersy[j] = (cos(PI*(j-ntap)/ntap)+1)/2.0;
        for (j = ntap; j < nxs-ntap; j++)
            tapersy[j] = 1.0;
        for (j = nxs-ntap; j < nxs; j++)
            tapersy[j] =(cos(PI*(j-(nxs-ntap))/ntap)+1)/2.0;
    }
    else {
        for (j = 0; j < nxs; j++) tapersy[j] = 1.0;
    }
    if (tap == 1 || tap == 3) {
        if (verbose) vmess("Taper for operator applied ntap=%d", ntap);
        for (l = 0; l < Nsyn; l++) {
            for (i = 0; i < nxs; i++) {
                for (j = 0; j < nts; j++) {
                    G_d[l*nxs*nts+i*nts+j] *= tapersy[i];
                }   
            }   
        }   
    }

	/* check consistency of header values */
    dxf = (xrcvsyn[nxs-1] - xrcvsyn[0])/(float)(nxs-1);
    if (NINT(dxs*1e3) != NINT(fabs(dxf)*1e3)) {
        vmess("dx in hdr.d1 (%.3f) and hdr.gx (%.3f) not equal",d2, dxf);
        if (dxf != 0) dxs = fabs(dxf);
        vmess("dx in operator => %f", dxs);
    }
    if (xrcvsyn[0] != 0 || xrcvsyn[1] != 0 ) fxs = xrcvsyn[0];
    fxs2 = fxs + (float)(nxs-1)*dxs;

/*================ Reading shot records ================*/

    mode=1;
    readShotData(file_shot, xrcv, xsrc, zsrc, xnx, Refl, nw, nw_low, ngath, nx, nx, ntfft, 
         mode, weight, tsq, Q, f0, verbose);

    tapersh = (float *)malloc(nx*sizeof(float));
    if (tap == 2 || tap == 3) {
        for (j = 0; j < ntap; j++)
            tapersh[j] = (cos(PI*(j-ntap)/ntap)+1)/2.0;
        for (j = ntap; j < nx-ntap; j++)
            tapersh[j] = 1.0;
        for (j = nx-ntap; j < nx; j++)
            tapersh[j] =(cos(PI*(j-(nx-ntap))/ntap)+1)/2.0;
    }
    else {
        for (j = 0; j < nx; j++) tapersh[j] = 1.0;
    }
    if (tap == 2 || tap == 3) {
        if (verbose) vmess("Taper for shots applied ntap=%d", ntap);
        for (l = 0; l < nshots; l++) {
            for (j = 1; j < nw; j++) {
                for (i = 0; i < nx; i++) {
                    Refl[l*nx*nw+j*nx+i].r *= tapersh[i];
                    Refl[l*nx*nw+j*nx+i].i *= tapersh[i];
                }   
            }   
        }
    }
    free(tapersh);

	/* check consistency of header values */
    fxf = xsrc[0];
    if (nx > 1) dxf = (xrcv[0] - xrcv[nx-1])/(float)(nx-1);
    else dxf = d2;
    if (NINT(dx*1e3) != NINT(fabs(dxf)*1e3)) {
        vmess("dx in hdr.d1 (%.3f) and hdr.gx (%.3f) not equal",dx, dxf);
        if (dxf != 0) dx = fabs(dxf);
        else verr("gx hdrs not set");
        vmess("dx used => %f", dx);
    }
    
    dxsrc = (float)xsrc[1] - xsrc[0];
    if (dxsrc == 0) {
        vwarn("sx hdrs are not filled in!!");
        dxsrc = dx;
    }

/*================ Check the size of the files ================*/

    if (NINT(dxsrc/dx)*dx != NINT(dxsrc)) {
        vwarn("source (%.2f) and receiver step (%.2f) don't match",dxsrc,dx);
        if (reci == 2) vwarn("step used from operator (%.2f) ",dxs);
    }
    di = NINT(dxf/dxs);
    if ((NINT(di*dxs) != NINT(dxf)) && verbose) 
        vwarn("dx in receiver (%.2f) and operator (%.2f) don't match",dx,dxs);
    if (nt != nts) 
        vmess("Time samples in shot (%d) and focusing operator (%d) are not equal",nt, nts);
    if (verbose) {
        vmess("Number of focusing operators   = %d", Nsyn);
        vmess("Number of receivers in focusop = %d", nxs);
        vmess("number of shots                = %d", nshots);
        vmess("number of receiver/shot        = %d", nx);
        vmess("first model position           = %.2f", fxs);
        vmess("last model position            = %.2f", fxs2);
        vmess("first source position fxf      = %.2f", fxf);
        vmess("source distance dxsrc          = %.2f", dxsrc);
        vmess("last source position           = %.2f", fxf+(nshots-1)*dxsrc);
        vmess("receiver distance     dxf      = %.2f", dxf);
        vmess("direction of increasing traces = %d", di);
        vmess("number of time samples (nt,nts) = %d (%d,%d)", ntfft, nt, nts);
        vmess("time sampling                  = %e ", dt);
		if (ampest > 0) 		vmess("Amplitude correction estimation is switched on");
		if (nb > 0)				vmess("Scaling estimation in %d step(s) from %.3f to %.3f (db=%.3f)",nb,bstart,bend,db);
        if (file_green != NULL) vmess("Green output file              = %s ", file_green);
        if (file_gmin != NULL)  vmess("Gmin output file               = %s ", file_gmin);
        if (file_gplus != NULL) vmess("Gplus output file              = %s ", file_gplus);
        if (file_pmin != NULL)  vmess("Pmin output file               = %s ", file_pmin);
        if (file_f2 != NULL)    vmess("f2 (=pplus) output file        = %s ", file_f2);
        if (file_f1min != NULL) vmess("f1min output file              = %s ", file_f1min);
        if (file_f1plus != NULL)vmess("f1plus output file             = %s ", file_f1plus);
        if (file_iter != NULL)  vmess("Iterations output file         = %s ", file_iter);
    }

/*================ initializations ================*/

    if (ixa || ixb) n2out = ixa + ixb + 1;
    else if (reci) n2out = nxs;
    else n2out = nshots;
    mem = Nsyn*n2out*ntfft*sizeof(float)/1048576.0;
    if (verbose) {
        vmess("number of output traces        = %d", n2out);
        vmess("number of output samples       = %d", ntfft);
        vmess("Size of output data/file       = %.1f MB", mem);
    }

    //memcpy(Ni, G_d, Nsyn*nxs*ntfft*sizeof(float));
    
	if (file_homg!=NULL) {
		hG_d     = (float *)calloc(nxs*ntfft,sizeof(float));
    	hmuteW   = (int *)calloc(nxs,sizeof(int));
		hxrcvsyn = (float *)calloc(nxs,sizeof(float));
		hxsyn 	 = (float *)calloc(1,sizeof(float));
		hzsyn    = (float *)calloc(1,sizeof(float));
		hxnxsyn  = (int *)calloc(1,sizeof(int));
		cshot 	 = (complex *)calloc(nxs*nfreq,sizeof(complex));

		if(!getparfloat("xloc", &WPs.xloc)) WPs.xloc = -123456.0;
    	if(!getparfloat("zloc", &WPs.zloc)) WPs.zloc = -123456.0;
		if (WPs.xloc == -123456.0 && WPs.zloc == -123456.0) file_cp = NULL;
		if (WPs.xloc == -123456.0) WPs.xloc = 0.0;
		if (WPs.zloc == -123456.0) WPs.zloc = 0.0;
		xloc = WPs.xloc;
		zloc = WPs.zloc;
		ngath = 1;

		if (file_rays!=NULL || file_cp!=NULL) {
			WPs.wav=1;
			makeWindow(WPs, file_rays, file_amps, dt, hxrcvsyn, hxsyn, hzsyn, hxnxsyn, ngath, nxs, ntfft, mode, hmuteW, hG_d, hw, verbose);
    	}
    	else {
        	mode=-1; /* apply complex conjugate to read in data */
        	readTinvData(file_tinvs, dt, hxrcvsyn, hxsyn, hzsyn, hxnxsyn,
            	ngath, nxs, ntfft, mode, hmuteW, hG_d, hw, verbose);
    	}

		WPs.xloc = -123456.0;
		WPs.zloc = -123456.0;

		if (tap == 1 || tap == 3) {
        	if (verbose) vmess("Taper for operator applied ntap=%d", ntap);
            for (i = 0; i < nxs; i++) {
                for (j = 0; j < nts; j++) {
                    hG_d[i*nts+j] *= tapersy[i];
                }
            }
        }

		ngath   = omp_get_max_threads();
		
		synthesisPosistions(nx, nt, nxs, nts, dt, hxsyn, 1, xrcv, xsrc, fxs2, fxs,
        	dxs, dxsrc, dx, ixa, ixb, reci, nshots, ixpossyn, &npossyn, verbose);

		iterations(Refl,nx,nt,nxs,nts,dt,hxsyn,1,xrcv,xsrc,fxs2,fxs,dxs,dxsrc,dx,ixa,ixb,
        	ntfft,nw,nw_low,nw_high,mode,reci,nshots,ixpossyn,npossyn,pmin,f1min,f1plus,
        	f2p,hG_d,hmuteW,smooth,shift,above,pad,nt0,&first,niterh,verbose);

		/* compute full Green's function G = int R * f2(t) + f2(-t) = Pplus + Pmin */
        for (i = 0; i < npossyn; i++) {
            j = 0;
            /* set green to zero if mute-window exceeds nt/2 */
            if (hmuteW[ixpossyn[i]] >= nts/2) {
                memset(&green[i*nts],0, sizeof(float)*nt);
                continue;
            }
            green[i*nts+j] = f2p[i*nts+j] + pmin[i*nts+j];
            for (j = 1; j < nts; j++) {
                green[i*nts+j] = f2p[i*nts+nts-j] + pmin[i*nts+j];
            }
        }

		applyMute(green, hmuteW, smooth, 4, 1, nxs, nts, ixpossyn, npossyn, shift, pad, nt0);

        omp_set_num_threads(ngath);

        /* Transform the green position to the frequency domain */
        /*for (i = 0; i < npossyn; i++) {
        	rc1fft(&green[i*nts],&cshot[i*nfreq],ntfft,-1);
    	}*/
		//free(hG_d);free(hmuteW);free(hxrcvsyn);
		free(hmuteW);free(hxrcvsyn);
		free(hxsyn);free(hzsyn);free(hxnxsyn);free(cshot);
	}

    /* dry-run of synthesis to get all x-positions calcalated by the integration */
    synthesisPosistions(nx, nt, nxs, nts, dt, xsyn, Nsyn, xrcv, xsrc, fxs2, fxs, 
        dxs, dxsrc, dx, ixa, ixb,  reci, nshots, ixpossyn, &npossyn, verbose);
    if (verbose) {
        vmess("synthesisPosistions: nshots=%d npossyn=%d", nshots, npossyn);
    }


    t1    = wallclock_time();
    tread = t1-t0;

	iterations(Refl,nx,nt,nxs,nts,dt,xsyn,Nsyn,xrcv,xsrc,fxs2,fxs,dxs,dxsrc,dx,ixa,ixb,
		ntfft,nw,nw_low,nw_high,mode,reci,nshots,ixpossyn,npossyn,pmin,f1min,f1plus,
		f2p,G_d,muteW,smooth,shift,above,pad,nt0,&first,niter,verbose);

	/*if (niter==0) {
		for (l = 0; l < Nsyn; l++) {
        	for (i = 0; i < npossyn; i++) {
            	j = 0;
                ix = ixpossyn[i];
                f2p[l*nxs*nts+i*nts+j] = G_d[l*nxs*nts+ix*nts+j];
				f1plus[l*nxs*nts+i*nts+j] = G_d[l*nxs*nts+ix*nts+j];
                for (j = 1; j < nts; j++) {
                	f2p[l*nxs*nts+i*nts+j] = G_d[l*nxs*nts+ix*nts+j];
					f1plus[l*nxs*nts+i*nts+j] = G_d[l*nxs*nts+ix*nts+j];
                }
            }
    	}
	}*/

	

	if (niterh==0) {
        for (l = 0; l < Nsyn; l++) {
            for (i = 0; i < npossyn; i++) {
                j = 0;
                ix = ixpossyn[i];
                green[i*nts+j] = hG_d[ix*nts+j];
                for (j = 1; j < nts; j++) {
                    green[i*nts+j] = hG_d[ix*nts+nts-j];
                }
            }
        }
    }

	if (file_img!=NULL) {
	
		/*================ set variables for output data ================*/

    	hdrs_im = (segy *) calloc(shot.nx,sizeof(segy));
    	if (hdrs_im == NULL) verr("allocation for hdrs_out");
		Image   = (float *)calloc(Nsyn,sizeof(float));

		first=0;
		imaging(Image,WPs,Refl,nx,nt,nxs,nts,dt,xsyn,Nsyn,xrcv,xsrc,fxs2,fxs,dxs,dxsrc,dx,ixa,ixb,
       		ntfft,nw,nw_low,nw_high,mode,reci,nshots,ixpossyn,npossyn,pmin,f1min,f1plus,
       		f2p,G_d,muteW,smooth,shift,above,pad,nt0,synpos,verbose);

		/*============= write output files ================*/

		fp_out = fopen(file_img, "w+");

    	for (i = 0; i < shot.nx; i++) {
            hdrs_im[i].fldr    = 1;
            hdrs_im[i].tracl   = 1;
            hdrs_im[i].tracf   = i+1;
            hdrs_im[i].scalco  = -1000;
            hdrs_im[i].scalel  = -1000;
            hdrs_im[i].sdepth  = 0;
            hdrs_im[i].trid    = 1;
            hdrs_im[i].ns      = shot.nz;
            hdrs_im[i].trwf    = shot.nx;
            hdrs_im[i].ntr     = hdrs_im[i].fldr*hdrs_im[i].trwf;
            hdrs_im[i].f1      = zsyn[0];
            hdrs_im[i].f2      = xsyn[0];
            hdrs_im[i].dt      = dt*(1E6);
            hdrs_im[i].d1      = (float)zsyn[shot.nx]-zsyn[0];
            hdrs_im[i].d2      = (float)xsyn[1]-xsyn[0];
            hdrs_im[i].sx      = (int)roundf(xsyn[0] + (i*hdrs_im[i].d2));
            hdrs_im[i].gx      = (int)roundf(xsyn[0] + (i*hdrs_im[i].d2));
            hdrs_im[i].offset  = (hdrs_im[i].gx - hdrs_im[i].sx)/1000.0;
    	}
    	ret = writeData(fp_out, &Image[0], hdrs_im, shot.nz, shot.nx);
    	if (ret < 0 ) verr("error on writing output file.");

    	fclose(fp_out);
	}

	if (file_homg!=NULL) {

		/*================ set variables for output data ================*/

        hdrs_homg = (segy *) calloc(shot.nx,sizeof(segy));
        if (hdrs_homg == NULL) verr("allocation for hdrs_out");
        HomG	= (float *)calloc(Nsyn*ntfft,sizeof(float));

        homogeneousg(HomG,green,Refl,nx,nt,nxs,nts,dt,xsyn,Nsyn,xrcv,xsrc,fxs2,fxs,dxs,dxsrc,dx,ixa,ixb,
           	ntfft,nw,nw_low,nw_high,mode,reci,nshots,ixpossyn,npossyn,pmin,f1min,f1plus,
           	f2p,G_d,muteW,smooth,shift,above,pad,nt0,synpos,verbose);

        /*============= write output files ================*/

		 fp_out = fopen(file_homg, "w+");

		for (j = 0; j < ntfft; j++) {
        	for (i = 0; i < shot.nx; i++) {
            	hdrs_homg[i].fldr    = j+1;
            	hdrs_homg[i].tracl   = j*shot.nx+i+1;
            	hdrs_homg[i].tracf   = i+1;
            	hdrs_homg[i].scalco  = -1000;
            	hdrs_homg[i].scalel  = -1000;
            	hdrs_homg[i].sdepth  = (int)(zloc*1000.0);
            	hdrs_homg[i].trid    = 1;
            	hdrs_homg[i].ns      = shot.nz;
            	hdrs_homg[i].trwf    = shot.nx;
            	hdrs_homg[i].ntr     = hdrs_homg[i].fldr*hdrs_homg[i].trwf;
            	hdrs_homg[i].f1      = zsyn[0];
            	hdrs_homg[i].f2      = xsyn[0];
            	hdrs_homg[i].dt      = dt*(1E6);
            	hdrs_homg[i].d1      = (float)zsyn[shot.nx]-zsyn[0];
            	hdrs_homg[i].d2      = (float)xsyn[1]-xsyn[0];
            	hdrs_homg[i].sx      = (int)roundf(xsyn[0] + (i*hdrs_homg[i].d2));
            	hdrs_homg[i].gx      = (int)roundf(xsyn[0] + (i*hdrs_homg[i].d2));
            	hdrs_homg[i].offset  = (hdrs_homg[i].gx - hdrs_homg[i].sx)/1000.0;
        	}
        	ret = writeData(fp_out, &HomG[j*shot.n], hdrs_homg, shot.nz, shot.nx);
        	if (ret < 0 ) verr("error on writing output file.");
		}

        fclose(fp_out);
    }

    if (verbose) {
        t1 = wallclock_time();
        vmess("and CPU-time write data  = %.3f", t1-t2);
    }


    free(tapersy);

    exit(0);
}
示例#6
0
int main(int argc, char *argv[])
{
	FILE    *shot_file, *vel_file, *out_file, *beam_file;
	size_t  nread, bytes, size, trace_sz, size_out;
	int     verbose,  method, ntraces, verb_root;
	int     nxv, nyv, nzv, binary_file, dstep, id, id1, id2;
	int     d, nt, ndepth, i, j, conjg, conjgs, mode, out_su;
	int     ntap, tap_opt, order, McC, oplx, oply, fine, MB;
	int     stackmigr, imc, area, ixmin, ixmax, iymin, iymax, ns;
	int     nfft, nfreq, nw_high, nw_low, nw, sx, sy, ix, iy;
	int     npages_w, sxy, iw, one_shot, traces_shot, sign, is; 
	int     traces_read_in, nxy, fd, nx, ny, num_threads, nel, oper_opt;
	int		fldr_w, power_of_2, beam_su, nterms, filter_inc, beam;
	Area    shot_area;
	float   alpha, weight, scl, sclw;
	float   fmin, fmax, dt;
	float   *tot_beam, *beams, scale;
	float   *velocity, weights, tshift, zrcv;
	float   xvmin, yvmin, zvmin, dxv, dyv, dzv, vmin, vmax;
	float   dw, df, om, dtw, tdw, t_w, tr, ti;
	double  t0, t1, t2, t3, t_migr=0, t_io=0, t_table=0, t_init=0;
	double  t_comm=0;
	complex *rec_all, *rec_field, *rec;
	char    *file_vel, *file_in, *file_out, *file_beam, *file_table;
	char    *tmp_dir, sys_call[256];
	segy *hdr;
	int     npes, pe, root_pe=0, nlw, maxlw, *freq_index, fdist, ipe;
#ifdef MPI
	int *nlwcounts, *recvcounts, *displacements;
	int nlw_tag;
	complex  *gath_rec_field;
	MPI_Status status;
	MPI_Request request;

	MPI_Init( &argc, &argv );
	MPI_Comm_size( MPI_COMM_WORLD, &npes );
	MPI_Comm_rank( MPI_COMM_WORLD, &pe );
#else
	npes = 1;
	pe   = 0;
#endif

	t0 = wallclock_time();

/* Read in parameters */

	initargs(argc,argv);
	requestdoc(0);

	if(!getparstring("file_in", &file_in)) file_in=NULL;
	if(!getparstring("file_vel", &file_vel)) file_vel=NULL; 
	if(!getparstring("file_out", &file_out)) file_out=NULL;
	if(!getparstring("file_beam", &file_beam)) file_beam=" ";
	if(!getparstring("file_table", &file_table)) file_table=NULL;
	if(!getparstring("tmp_dir", &tmp_dir)) tmp_dir="/tmp";
	if(!getparfloat("fmin", &fmin)) fmin = 0.0;
	if(!getparfloat("fmax", &fmax)) fmax = 45.0;
	if(!getparint("mode", &mode)) mode = 1;
	if(!getparint("ntap", &ntap)) ntap = 0;
	if(!getparint("tap_opt", &tap_opt)) tap_opt = 1;
	if(!getparint("method", &method)) method = 1;
	if(!getparint("conjg", &conjg)) conjg = 0;
	if(!getparint("conjgs", &conjgs)) conjgs = 0;
	if(!getparint("area", &area)) area = 0;
	if(!getparint("oplx", &oplx)) oplx = 25;
	if(!getparint("oply", &oply)) oply = oplx;
	if(!getparint("order", &order)) order = 13;
	if(!getparint("McC", &McC)) McC = 1;
	if(!getparint("oper_opt", &oper_opt)) oper_opt = 1;
	if(!getparint("nterms", &nterms)) nterms = 1;
	if(!getparint("filter_inc", &filter_inc)) filter_inc = 1;
	if(!getparfloat("alpha", &alpha)) alpha = 65.0;
	if(!getparfloat("weight", &weight)) weight = 5e-5;
	if(!getparfloat("weights", &weights)) weights = 1e-2;
	if(!getparint("fine", &fine)) fine = 2;
	if(!getparint("beam", &beam)) beam = 0;
	if(!getparint("verbose", &verbose)) verbose = 0;
	
	if(!ISODD(oplx)) oplx += 1;
	if(!ISODD(oply)) oply += 1;
	if(conjg)  conjg  = -1; else  conjg = 1;
	if(conjgs)  conjgs  = -1; else  conjgs = 1;
	if(mode >= 0) mode = 1;
	if(mode < 0) mode = -1;
	assert(McC <= 2 && McC >= 1);
	assert(method <= 4 && method >= 1);
	assert(file_vel != NULL);
	assert(file_out != NULL);
	out_su = (strstr(file_out, ".su")!=NULL);
	beam_su = (strstr(file_beam, ".su")!=NULL);
    if (verbose && pe==root_pe) verb_root=verbose;
    else verb_root = 0;

	t1 = wallclock_time(); t_init += t1-t0;

	/* Clean up 'old' velocity files */
	    
	sprintf(sys_call,"rm -rf %s/velocity*.bin\n",tmp_dir);
	system(sys_call);
#ifdef MPI
	MPI_Barrier(MPI_COMM_WORLD);
#endif

/* Open velocity file and determine the size of the file */

	openVelocityFile(file_vel, &vel_file, &shot_area, verb_root);

#ifdef MPI
	MPI_Barrier(MPI_COMM_WORLD);
#endif
	xvmin = shot_area.xmin;
	yvmin = shot_area.ymin;
	zvmin = shot_area.zmin;
	nxv   = shot_area.nx;
	nyv   = shot_area.ny;
	nzv   = shot_area.nz;
	dxv   = shot_area.dx;  
	dyv   = shot_area.dy;
	dzv   = shot_area.dz;
	nxy   = shot_area.sxy;


	if(!getparfloat("zrcv", &zrcv)) zrcv = zvmin+(nzv-1)*dzv;
	ndepth = NINT((zrcv-zvmin)/dzv);
	if(!getparint("dstep", &dstep)) dstep = MIN(5, ndepth);
	if(!getparfloat("vmin", &vmin)) vmin = 1500;
	if(!getparfloat("vmax", &vmax)) vmax = 4800;


/* Open file_in file and read first header */
	
	hdr = (segy *)calloc(1,sizeof(segy));
	if (file_in == NULL) shot_file = stdin;
	else shot_file = fopen( file_in, "r" );
	assert( shot_file );
	nread = fread( hdr, 1, TRCBYTES, shot_file );
	assert (nread == TRCBYTES);

	fseek ( shot_file, 0, SEEK_END );
	bytes    = ftell(shot_file); 
	nt       = hdr[0].ns;
	dt       = 1e-6*hdr[0].dt;
	trace_sz = sizeof(float)*nt+TRCBYTES;
	ntraces  = (int) (bytes/trace_sz);
	nfft     = optncr(nt);
	nfreq    = nfft/2 + 1;
	df       = 1.0/(nfft*dt);
	dw       = 2.*M_PI*df;
	nw_high  = MIN( (int)(fmax/df), nfreq );
	nw_low   = MAX( (int)((fmin)/df), 1 );
	nw       = nw_high - nw_low + 1;
	sx       = hdr[0].sx;
	sy       = hdr[0].sy;
	if (hdr[0].scalco < 0) scl = 1.0/fabs(hdr[0].scalco);
	else if (hdr[0].scalco == 0) scl = 1.0;
	else scl = hdr[0].scalco;

	t2 = wallclock_time(); t_io += t2-t1;

/*======= compute frequency distribution for multiple CPU's ========*/

	fdist = 0;
	maxlw = ceil((float)nw/(float)npes);
	freq_index = (int *)malloc(maxlw*sizeof(int));
	nlw = frequency_distribution(nw_low, nw, npes, pe, maxlw, 
		freq_index, fdist );

#ifdef MPI
	if( verbose ) {
		/* print out all the frequencies for each process */
		MPI_Barrier(MPI_COMM_WORLD);
		for( ipe=0; ipe<npes; ipe++ ) {
			if( pe == ipe ) {
				fprintf(stderr, "pe=%d:\tf[%d] = df*{", pe, nlw );
				if( nlw > 0 )
				for( iw=0; iw<nlw; iw++ )
					fprintf(stderr, " %d", freq_index[iw] );
				fprintf( stderr, " }\n" );
				fflush(stderr);
			}
			MPI_Barrier(MPI_COMM_WORLD);
		}
	}
	if (npes == 1) nlw = nw;
	nlwcounts = (int *)malloc(npes*sizeof(int));
	recvcounts = (int *)malloc(npes*sizeof(int));
	displacements = (int *)malloc(npes*sizeof(int));
	nlw_tag = 1;
	if (pe == root_pe) {
		displacements[0] = 0;
		nlwcounts[0] = nlw;
		for( ipe=1; ipe<npes; ipe++ ) {
			MPI_Recv(&nlwcounts[ipe], 1, MPI_INT, ipe, nlw_tag, 
				MPI_COMM_WORLD, &status);
			displacements[ipe] = displacements[ipe-1]+nlwcounts[ipe-1];
		}
	}
	else {
		MPI_Send(&nlw, 1, MPI_INT, root_pe, nlw_tag, MPI_COMM_WORLD);
	}
#else
	nlw = nw;
#endif

	fmin = MAX(0,-df + df*freq_index[0]);
	fmax =  df + df*freq_index[nlw-1];

	assert( fmax < 1.0/(2.0*dt) ); /* Nyguist in time */
	assert( (2.0*fmax)/vmin < 1.0/dxv ); /* Nyguist in space */
	assert( (2.0*fmax)/vmin < 1.0/dyv ); /* Nyguist in space */

	size = (size_t)nlw*nxy*sizeof(complex);
	if (verb_root) {
		fprintf(stderr," minimum velocity = %.2f\n", vmin);
		fprintf(stderr," maximum velocity = %.2f\n", vmax);
		MB = 1024*1024;
		fprintf(stderr,"\n    DATA INFORMATION\n");
		fprintf(stderr," nw = %d\n", nw);
		fprintf(stderr," fmin = %.3f fmax = %.3f\n", nw_low*df, nw_high*df);
		fprintf(stderr," dt = %.4f nt = %d nfft = %d\n", dt, nt, nfft);
		fprintf(stderr," size of rec_field = %ld Mbytes\n", size/MB);
		size_out = (size_t)(nt)*(size_t)(nxy)*sizeof(float);
		if (out_su) size_out += (TRCBYTES*nxy);
		fprintf(stderr," size of output file = %ld Mbytes\n", size_out/MB);
	}

	/* Open beam file if beam == 1 */

    if (beam && pe == root_pe) {
		beam_file = fopen( file_beam, "w+" );
		assert( beam_file );
	}
	t1 = wallclock_time(); t_init += t1-t2;

/* Calculate operator tables */

	if (method == 1) {
		tablecalc_2D(oplx, oply, nxv, dxv, nyv, dyv, dzv, alpha, fmin, fmax,
			vmin, vmax, df, weight, fine, oper_opt, file_table, verb_root);
	} 
	else if (method == 2) {
		tablecalc_1D(order, nxv, dxv, dzv, alpha, fmin, fmax, vmin, vmax, df,
			fine, oper_opt, verb_root);
	}
	t2 = wallclock_time(); t_table = t2-t1;
	if (verb_root) 
		fprintf(stderr," time to calculate tables      : %.3f s.\n", t_table);

/* ============ INITIALIZE AND CHECK PARAMETERS =============== */

/* allocate rec field to zero and distribute along machine */

	rec_field = (complex *)calloc(nlw*nxy, sizeof(complex));
	assert(rec_field != NULL);
	velocity = (float *)malloc(dstep*nxy*sizeof(float));
	assert(velocity != NULL);
	if (beam) {
		beams = (float *)calloc(dstep*nxy, sizeof(float));
		assert(beams != NULL);
#ifdef MPI
		tot_beam = (float *)calloc(dstep*nxy, sizeof(float));
		assert(tot_beam != NULL);
#endif 
	}

#ifdef MPI
	if (pe == root_pe) {
		gath_rec_field = (complex *)calloc(nxy*nw,sizeof(complex));
		assert(gath_rec_field != NULL);
	}
#endif

	one_shot    = 1;
	traces_shot = 0;
	traces_read_in = 0;
	ixmin = nxv-1; ixmax = 0;
	iymin = nxv-1; iymax = 0;
	t1 = wallclock_time(); t_init += t1-t2;

	fseek(shot_file, 0, SEEK_SET);

	read_FFT_DataFile(shot_file, rec_field, shot_area, nfft, nlw, 
		freq_index[0], &traces_read_in, &traces_shot, 
		&ixmin, &ixmax, &iymin, &iymax, &sx, &sy, conjgs, verb_root);

	t2 = wallclock_time(); t_io += t2-t1;

	if (verb_root) 
		fprintf(stderr," time to initialize migration  : %.3f s.\n", t1-t0);


/* Loop over input traces */

	is = 0;
	while (one_shot) {
		t1 = wallclock_time(); 

		if (verb_root) {
			fprintf(stderr,"\n    EXTRAPOLATION INFORMATION\n");
			fprintf(stderr," source position (x,y) : %.2f, %.2f\n", 
				sx*scl, sy*scl);
			fprintf(stderr," number of traces in shot : %d\n", traces_shot);
			fprintf(stderr," traces done = %d to do %d\n", 
				traces_read_in-traces_shot, ntraces-traces_read_in+traces_shot);
			fprintf(stderr," shot region is      x:%d-%d        y:%d-%d\n", 
				ixmin, ixmax, iymin, iymax);
		}
		
	/* determine aperture to be extrapolated */

		if (area>0) {
			ixmin = MAX(0,ixmin-area);
			ixmax = MIN(nxv-1,ixmax+area);
			iymin = MAX(0,iymin-area);
			iymax = MIN(nyv-1,iymax+area);
		}
		else {
			ixmin = 0;
			iymin = 0;
			ixmax = nxv-1;
			iymax = nyv-1;
		}
		nx = ixmax-ixmin+1;
		ny = iymax-iymin+1;

		shot_area.ixmin = ixmin;
		shot_area.ixmax = ixmax;
		shot_area.iymin = iymin;
		shot_area.iymax = iymax;
		shot_area.dx    = dxv;
		shot_area.dy    = dyv;
		shot_area.dz    = dzv;
		shot_area.nx    = nxv;
		shot_area.ny    = nyv;
		shot_area.sxy   = nxy;
	
		if (verb_root) {
			fprintf(stderr," work area is x:%d-%d (%d) y:%d-%d (%d)\n",
				ixmin, ixmax, nx, iymin, iymax, ny);
		}

		t2 = wallclock_time(); t_init += t2-t1;

		/* write beam for depth=0 */
		if (beam)  {
			scale = 1.0/(float)(nw);
			for (iw=0; iw<nlw; iw++) {
				rec = (complex*) (rec_field + iw*nxy);
				for (ix = 0; ix < nxy; ix++) {
					beams[ix] += sqrt(rec[ix].r*rec[ix].r+rec[ix].i*rec[ix].i)*scale;
				}
			}
			t1 = wallclock_time(); t_init += t1-t2;
#ifdef MPI
			MPI_Reduce(beams, tot_beam, nxy, MPI_FLOAT, MPI_SUM, 0, MPI_COMM_WORLD);
#else
			tot_beam = beams;
#endif
			t2 = wallclock_time(); t_comm += t2-t1;

			/* write image to output file */
			if (pe == root_pe) {
				write_ImageFile(beam_file, tot_beam, shot_area, is, 0, beam_su, verbose);
			}
			t1 = wallclock_time(); t_io += t1-t2;
		}


	/* Start of depth loop */

		for (d=0; d<ndepth; d+=dstep) {
			t1 = wallclock_time();
			id1 = d;
			id2 = MIN(id1+dstep, ndepth);
			nel = (id2-id1)*nxy;

			/* Read dstep depth slices */

			for (id=id1,i=0; id<id2; id++,i++) {
				readVelocitySlice(vel_file, &velocity[i*nxy], id, nyv, nxv);
			}
			t2 = wallclock_time(); t_io += t2-t1;

			if (verb_root > 1) {
				fprintf(stderr," extrapolating from depth level ");
				fprintf(stderr,"%d (%.2f) to %d (%.2f) \n",
				id1, zvmin+dzv*id1, id2, zvmin+dzv*id2);
			}

			if (beam) memset(&beams[0], 0, nxy*dstep*sizeof(float));
			for (iw=0; iw<nlw; iw++) {
				om = freq_index[iw]*dw;
				rec = (complex*) (rec_field + iw*nxy);

				for (id=id1,i=0; id<id2; id++,i++) {

					/* Extrapolation */
					xwExtr3d(rec, &velocity[i*nxy], vmin, oplx, oply,
						order, McC, om, nterms, filter_inc, ntap, tap_opt,
						&shot_area, mode, method);

					if (beam) {
						for (ix = 0; ix < nxy; ix++) {
							beams[i*nxy+ix] += sqrt(rec[ix].r*rec[ix].r+rec[ix].i*rec[ix].i)*scale;
						}
					}

				} /* end of depth loop */
			} /* end of frequency loop */
			t1 = wallclock_time(); t_migr += t1-t2;

			if (beam) {
#ifdef MPI
				MPI_Reduce(beams, tot_beam, dstep*nxy, MPI_FLOAT, MPI_SUM, 0, MPI_COMM_WORLD);
#else
				tot_beam = beams;
#endif

				t3 = wallclock_time(); t_comm += t3-t1;

				/* write beam to output file */

				if (pe == root_pe) {
					for (id=id1,i=0; id<id2; id++,i++) {
						write_ImageFile(beam_file, &tot_beam[i*nxy], shot_area,
							is, id, beam_su, verbose);
					}
				}
				t2 = wallclock_time(); t_io += t2-t3;
			}

		} /* end of outer (dstep) depth loop */

		t2 = wallclock_time();

		/* communicate data from all PE's to root_pe */

#ifdef MPI
		fflush(stderr);
		if (pe == root_pe) {
			displacements[0] = 0;
			recvcounts[0] = nlw*nxy*2;
			for( ipe=1; ipe<npes; ipe++ ) {
				recvcounts[ipe] = nlwcounts[ipe]*nxy*2;
				displacements[ipe] = displacements[ipe-1]+recvcounts[ipe-1];
			}
		}
		MPI_Gatherv(rec_field, nxy*nlw*2, MPI_FLOAT, gath_rec_field, recvcounts,
			displacements, MPI_FLOAT, root_pe, MPI_COMM_WORLD);

		if (pe == root_pe) {
			rec_all = gath_rec_field;
		}
#else 
		rec_all = rec_field;
#endif

		t1 = wallclock_time(); t_comm += t1-t2;

		if (pe == root_pe) {
			/* Write modelling result to output file */
			if (verb_root) 
				fprintf(stderr," End of depth loop, writing data.\n");

			if (is == 0) 
				out_file = fopen( file_out, "w+" ); 
			else 
				out_file = fopen( file_out, "a" ); 

			assert( out_file );

			write_FFT_DataFile(out_file, rec_all, shot_area, (is+1),  
				nt, nfft, nw, nw_low, dt, out_su, conjg, verb_root);

			fclose(out_file);
		}


	/* Read next shot record */

		if (traces_read_in == ntraces) {
			one_shot = 0;
		}
		else {
			read_FFT_DataFile(shot_file, rec_field, shot_area, nfft, 
				nlw, freq_index[0], &traces_read_in, &traces_shot,
				&ixmin, &ixmax, &iymin, &iymax, &sx, &sy, conjgs, verb_root);
		}
		is++;

		t2 = wallclock_time(); t_io += t2-t1;

		if (verb_root) {
			fprintf(stderr," subtime for extrapolation : %.3f s.\n", t_migr);
			fprintf(stderr," subtime for io            : %.3f s.\n", t_io);
			fprintf(stderr," subtime for communication : %.3f s.\n\n", t_comm);
		}

	} /* end of while loop over input traces */

	free(velocity);
	free(hdr);
	free(rec_field);
	fclose(vel_file);
	if (beam) {
		if (pe == root_pe) fclose(beam_file);
		free(beams);
#ifdef MPI
		free(tot_beam);
#endif
	}

/* Write total image result to output file */

	fclose(shot_file);

	t2 = wallclock_time(); t_io += t2-t1;

/* clean temporary velocity files */

	sprintf(sys_call,"rm -rf %s/velocity%d.bin\n",tmp_dir, getpid());
	system(sys_call);

/* print the timing results */

	if (verb_root) {
		fprintf(stderr,"Time for total job        : %.3f s.\n", t2-t0);
		fprintf(stderr,"  time for extrapolation  : %.3f s.\n", t_migr);
		fprintf(stderr,"  time for tables         : %.3f s.\n", t_table);
		fprintf(stderr,"  time for io             : %.3f s.\n", t_io);
		fprintf(stderr,"  time for communication  : %.3f s.\n", t_comm);
		fprintf(stderr,"  time for initialization : %.3f s.\n", t_init);
	}

#ifdef MPI
	MPI_Barrier(MPI_COMM_WORLD);
	if (pe == root_pe) free(gath_rec_field);
	free(nlwcounts);
	free(recvcounts);
	free(displacements);
	MPI_Finalize();
#endif

	return;
}
示例#7
0
int main (int argc, char **argv)
{
    FILE    *fp;
	char    *file_gp, *file_fp, *file_wav;
    int     nx, nt, ngath, ntraces, ret, size, nxwav;
    int     ntfft, nfreq, nxfft, nkx, i, j, n;
    float   dx, dt, fx, ft, xmin, xmax, scl, *den, dentmp;
    float   df, dw, dkx, eps, reps, leps, sclfk;
    float   *Gpd, *f1pd, *G_pad, *f_pad, *wav, *wav_pad, *outdata;
    complex *G_w, *f_w, *Gf, *amp, *wav_w, *S, *ZS, *SS;
    segy    *hdr_gp, *hdr_fp, *hdr_wav, *hdr_out;

	initargs(argc, argv);
	requestdoc(1);

	if(!getparstring("file_gp", &file_gp)) file_gp=NULL;
    if (file_gp==NULL) verr("file %s does not exist",file_gp);
    if(!getparstring("file_fp", &file_fp)) file_fp=NULL;
    if (file_fp==NULL) verr("file %s does not exist",file_fp);
    if(!getparstring("file_wav", &file_wav)) file_wav=NULL;
    if (file_wav==NULL) verr("file %s does not exist",file_wav);
	if(!getparfloat("eps", &eps)) eps=0.00;
	if(!getparfloat("reps", &reps)) reps=0.01;

    ngath = 1;
    ret = getFileInfo(file_gp, &nt, &nx, &ngath, &dt, &dx, &ft, &fx, &xmin, &xmax, &scl, &ntraces);

    size    = nt*nx;

	Gpd     = (float *)malloc(size*sizeof(float));
	hdr_gp  = (segy *) calloc(nx,sizeof(segy));
    fp      = fopen(file_gp, "r");
	if (fp == NULL) verr("error on opening input file_in1=%s", file_gp);
    nx      = readData(fp, Gpd, hdr_gp, nt);
    fclose(fp);

	f1pd    = (float *)malloc(size*sizeof(float));
	hdr_fp  = (segy *) calloc(nx,sizeof(segy));
    fp      = fopen(file_fp, "r");
	if (fp == NULL) verr("error on opening input file_in1=%s", file_fp);
    nx      = readData(fp, f1pd, hdr_fp, nt);
    fclose(fp);

    wav     = (float *)malloc(nt*sizeof(float));
	hdr_wav = (segy *) calloc(1,sizeof(segy));
    fp      = fopen(file_wav, "r");
	if (fp == NULL) verr("error on opening input file_in1=%s", file_fp);
    nxwav   = readData(fp, wav, hdr_wav, nt);
    fclose(fp);

    /* Start the scaling */
    ntfft   = optncr(nt);
	nfreq   = ntfft/2+1;
	df      = 1.0/(ntfft*dt);
    dw      = 2.0*PI*df;
	nkx     = optncc(nx);
	dkx     = 2.0*PI/(nkx*dx);
	sclfk   = dt*(dt*dx)*(dt*dx);

    vmess("ntfft:%d, nfreq:%d, nkx:%d dx:%.3f dt:%.3f",ntfft,nfreq,nkx,dx,dt);

    /* Allocate the arrays */
    G_pad = (float *)calloc(ntfft*nkx,sizeof(float));
	if (G_pad == NULL) verr("memory allocation error for G_pad");
    f_pad = (float *)calloc(ntfft*nkx,sizeof(float));
	if (f_pad == NULL) verr("memory allocation error for f_pad");
    wav_pad = (float *)calloc(ntfft,sizeof(float));
	if (wav_pad == NULL) verr("memory allocation error for wav_pad");
    G_w   = (complex *)calloc(nfreq*nkx,sizeof(complex));
	if (G_w == NULL) verr("memory allocation error for G_w");
    f_w   = (complex *)calloc(nfreq*nkx,sizeof(complex));
	if (f_w == NULL) verr("memory allocation error for f_w");
    Gf    = (complex *)calloc(nfreq*nkx,sizeof(complex));
	if (Gf == NULL) verr("memory allocation error for Gf");
    wav_w = (complex *)calloc(nfreq*nkx,sizeof(complex));
	if (wav_w == NULL) verr("memory allocation error for wav_w");
    amp   = (complex *)calloc(nfreq*nkx,sizeof(complex));
	if (amp == NULL) verr("memory allocation error for amp");
    S   = (complex *)calloc(nfreq*nkx,sizeof(complex));
	if (S == NULL) verr("memory allocation error for S");
    ZS   = (complex *)calloc(nfreq*nkx,sizeof(complex));
	if (ZS == NULL) verr("memory allocation error for ZS");
    SS   = (complex *)calloc(nfreq*nkx,sizeof(complex));
	if (SS == NULL) verr("memory allocation error for SS");
    den   = (float *)calloc(nfreq*nkx,sizeof(float));
	if (den == NULL) verr("memory allocation error for den");

    /* pad zeroes in 2 directions to reach FFT lengths */
	pad2d_data(Gpd, nt,nx,ntfft,nkx,G_pad);
	pad2d_data(f1pd,nt,nx,ntfft,nkx,f_pad);
    pad_data(  wav, nt, 1,ntfft,  wav_pad);

    /* double forward FFT */
	xt2wkx(&G_pad[0], &G_w[0], ntfft, nkx, ntfft, nkx, 0);
	xt2wkx(&f_pad[0], &f_w[0], ntfft, nkx, ntfft, nkx, 0);
    rcmfft(&wav_pad[0], &Gf[0], ntfft, 1, ntfft, nfreq, -1);

    for (i=0; i<nkx; i++) {
        for (j=0; j<nfreq; j++) {
            wav_w[j*nkx+i].r = Gf[j].r;
            wav_w[j*nkx+i].i = Gf[j].i;	
		}
    }

	for (i = 0; i < nkx*nfreq; i++) {
		Gf[i].r = (G_w[i].r*f_w[i].r - G_w[i].i*f_w[i].i);
		Gf[i].i = (G_w[i].r*f_w[i].i + G_w[i].i*f_w[i].r);

		S[i].r = (wav_w[i].r*wav_w[i].r + wav_w[i].i*wav_w[i].i);
		S[i].i = (wav_w[i].r*wav_w[i].i - wav_w[i].i*wav_w[i].r);

		ZS[i].r = (Gf[i].r*S[i].r + Gf[i].i*S[i].i);
		ZS[i].i = (Gf[i].r*S[i].i - Gf[i].i*S[i].r);

		SS[i].r = (S[i].r*S[i].r + S[i].i*S[i].i);
		SS[i].i = (S[i].r*S[i].i - S[i].i*S[i].r);

		if (i==0) dentmp=SS[i].r;
		else dentmp=MAX(dentmp,SS[i].r);
	}

	leps = reps*dentmp+eps;
	vmess("dentmp:%.4e leps:%.4e",dentmp,leps);

	for (i = 0; i < nkx*nfreq; i++) {
		S[i].r = (ZS[i].r*SS[i].r+ZS[i].i*SS[i].i)/(SS[i].r*SS[i].r+SS[i].i*SS[i].i+leps);
		S[i].i = (ZS[i].i*SS[i].r-ZS[i].r*SS[i].i)/(SS[i].r*SS[i].r+SS[i].i*SS[i].i+leps);

		amp[i].r = sqrtf(S[i].r*S[i].r+S[i].i*S[i].i);
		amp[i].i = 0.0;
		
		// complex_sqrt(&amp[i]);
		if (isnan(amp[i].r)) amp[i].r = 0;
		if (isnan(amp[i].i)) amp[i].i = 0;
		if (isinf(amp[i].r)) amp[i].r = 0;
		if (isinf(amp[i].i)) amp[i].i = 0;

		Gf[i].r = (G_w[i].r*amp[i].r - G_w[i].i*amp[i].i);
		Gf[i].i = (G_w[i].r*amp[i].i + G_w[i].i*amp[i].r);
	}

	// for (i=0; i<nfreq; i++) {
	// 	for (j=0; j<nkx; j++) {
	// 		Gpd[j*nfreq+i] = sqrtf(amp[i*nkx+j].r*amp[i*nkx+j].r+amp[i*nkx+j].i*amp[i*nkx+j].i);
	// 	}
	// }
    
    // conv_small(G_w, amp, Gf, nkx, nfreq); // Scaled data

    /* inverse double FFT */
	wkx2xt(&Gf[0], &G_pad[0], ntfft, nkx, nkx, ntfft, 0);
	/* select original samples and traces */
	scl = (1.0)/(nkx*ntfft);
	scl_data(G_pad,ntfft,nx,scl,Gpd ,nt);

    fp      = fopen("out.su", "w+");
    ret = writeData(fp, Gpd, hdr_gp, nt, nx);
	if (ret < 0 ) verr("error on writing output file.");
    fclose(fp);

	// fp      = fopen("wav.su", "w+");
	// for (j=0; j<nkx; j++) {
	// 	hdr_gp[j].ns = nfreq;
	// }
    // ret = writeData(fp, Gpd, hdr_gp, nfreq, nkx);
	// if (ret < 0 ) verr("error on writing output file.");
    // fclose(fp);

    free(f1pd);free(Gpd);free(hdr_gp);free(hdr_fp);

	return 0;
}
示例#8
0
void xwBeam(float *data, int nx, int nt, float dt, float *velmod, int ndepth, float fmin, float fmax, int opl, int ntap, int conjg, float *beams, int nxm, float ox, float dxm, float *xrcv, int verbose)
{
	int    	iomin, iomax, iom, ix, d, hopl, hopl2, i, j, ixrcv;
	int	index1, nfreq, optn, lenx, i1, i2, hoplen;
	float  	dom, om, c, cprev, df, scale, scl;
	float	*taper, *locbeam, *pdata;
	complex	*opx, *cdata, *tmp1, *tmp2, wa;

	optn  = optncr(nt);
	nfreq = optn/2 + 1;
	tmp1 = (complex *)calloc(nx*nfreq,sizeof(complex)); 

	/* pad zero's to get fourier length */
	if( nt != optn ) {
		if (verbose >1) vmess("xwBeam: padding zeros to data from %d to %d",nt,optn);
			pdata = (float *)calloc(optn*nx,sizeof(float));
			for (i=0; i<nx; i++) {
				for (j=0; j<nt; j++) pdata[i*optn+j] = data[i*nt+j];
				for ( ; j<optn; j++) pdata[i*optn+j] = 0.0;
			}
	}
	else {
		pdata = &data[0];
	}

	xt2wx(pdata, tmp1, optn, nx, optn, nx);

	if( nt != optn ) free(pdata);

	if (conjg) scl = -1.0;
	else scl = 1.0;
	df    = 1.0/(optn*dt);
	dom   = 2.*PI*df;
	iomin = (int)MIN((fmin*dt*optn), (nfreq-1));
	iomin = MAX(iomin, 1);
	iomax = MIN((int)(fmax*dt*optn), (nfreq-1));
	hopl  = (opl+1)/2;
	hopl2 = hopl-1;
	lenx  = 2*hopl2+nxm;
	scale = 1.0/(float)(iomax-iomin+1);

/* plane wave correction (rotation) at the surface 

    for (iom = 0; iom < nfreq; iom++) {
        for (ix = 0; ix < nx; ix++) {
            xoff = -1500.0+ix*15.0;
            shift = sin(15.0*M_PI/180)*xoff/2000.;
            if (iom ==0 ) fprintf(stderr,"xoff = %f shift = %f \n",xoff, shift);
            om = iom*dom*shift;
            wa = cdata[iom*nx+ix];
            cdata[iom*nx+ix].r = wa.r*cos(-om) - wa.i*sin(-om);
            cdata[iom*nx+ix].i = wa.i*cos(-om) + wa.r*sin(-om);
        }
    }
*/

	taper = (float *)malloc(nxm*sizeof(float));
	for (ix = 0; ix < nxm; ix++) taper[ix] = 1.0;
	for (ix = 0; ix < ntap; ix++) {
		taper[ix] = exp(-1.0*(pow((0.4*(ntap-ix)/ntap), 2)));
		taper[nxm-1-ix] = taper[ix];
	}

	cdata = (complex *)calloc(nxm*nfreq,sizeof(complex));
	for (iom = iomin; iom <= iomax; iom++) {
		for (ix = 0; ix < nx; ix++) {
			ixrcv = NINT((xrcv[ix]-ox)/dxm);
			cdata[iom*nxm+ixrcv].r += tmp1[iom*nx+ix].r;
			cdata[iom*nxm+ixrcv].i += tmp1[iom*nx+ix].i*scl;
		}
	}
	free(tmp1);

	if(verbose) {
		fprintf(stderr,"    xwBeam: number of depth steps = %d\n", ndepth);
		fprintf(stderr,"    xwBeam: number of frequencies = %d\n", iomax-iomin+1);
	}


	tmp1  = (complex *)calloc(lenx, sizeof(complex));
	tmp2  = (complex *)calloc(lenx, sizeof(complex));
	opx   = (complex *)calloc(hopl, sizeof(complex));
	locbeam = (float *)calloc(nxm*ndepth, sizeof(float));

	for (iom = iomin; iom <= iomax; iom++) {
		om = iom*dom;
		cprev = 0;
		for (j = 0; j < nxm; j++) {
			tmp1[hopl2+j].r = cdata[iom*nxm+j].r*taper[j];
			tmp1[hopl2+j].i = cdata[iom*nxm+j].i*taper[j];
		}

		for (d = 0; d < ndepth; d++) {

			for (ix = 0; ix < nxm; ix++) {
				locbeam[d*nxm+ix] += sqrt(tmp1[hopl2+ix].r*tmp1[hopl2+ix].r+
						tmp1[hopl2+ix].i*tmp1[hopl2+ix].i)*scale;
			}

			for (ix = 0; ix < nxm; ix++) {
				c = velmod[d*nxm+ix];
				if (c != cprev && c!=0.0) {
					readtable_opt(opx, om/c, &hoplen);
					cprev = c;
				}
				if (c==0.0) hoplen=0;

				wa.r = wa.i = 0.0;
				index1 = ix + hopl2;
				for (j = 0; j < hoplen; j++) {
					i1 = index1+j;
					i2 = index1-j;
					wa.r += (tmp1[i1].r + tmp1[i2].r)*opx[j].r;
					wa.r -= (tmp1[i1].i + tmp1[i2].i)*opx[j].i;
					wa.i += (tmp1[i1].i + tmp1[i2].i)*opx[j].r;
					wa.i += (tmp1[i1].r + tmp1[i2].r)*opx[j].i;
				}
				if (hoplen != 0) tmp2[index1] = wa;
				else tmp2[index1] = tmp1[index1];
			}
			for (j = 0; j < lenx; j++) tmp1[j] = tmp2[j];
		}
	}

	for (d = 0; d < ndepth; d++) {
		for (ix = 0; ix < nxm; ix++) {
			beams[ix*ndepth+d] += locbeam[d*nxm+ix];
		}
	}

	free(opx);
	free(tmp1);
	free(tmp2);
	free(locbeam);
	free(cdata);
	free(taper);

	return;
}
示例#9
0
void kwZoMigr(float *data, int nx, int nt, float dt, float *velmod, int nxm, int nzm, int ixa, int ixb, float fmin, float fmax, float *xrcv, int izrcv, float ox, float dxm, float dz, int ntap, int conjg, int ndepth, float *image, int verbose, float *exrcv, int ndepthex)
{
    int     iomin, iomax, iom, ix, d, i, j;
    int     nfreq, optn, nkx, sign, endkx;
    int     ixrcv, ixmin, ixmax, ixo, ixn, ikx;
    float   k, k2, kz2, kx, kx2;
    float   dom, om, c, dkx, df, sr;
    float   *taper, scl, scl2, *pdata;
    float 	*trace;
    complex *ctrace;
    float   t0, t1;
    complex *cdata, tmp, ez;
    complex wa, *ctmp, da, *locdat;
    complex *cexrcv=(complex *) exrcv;

    /* define some constants */

    optn  = optncr(nt);
    nfreq = optn/2 + 1;
    df    = 1.0/(optn*dt);
    dom   = 2.0*M_PI*df;
    iomin = (int)MIN((fmin*dt*optn), (nfreq-1));
    iomin = MAX(iomin, 1);
    iomax = MIN((int)(fmax*dt*optn), (nfreq-1));

    /* transformation of shot record to frequency domain  */

    trace  = (float *)calloc(optn,sizeof(float));
    ctrace = (complex *)malloc(optn*sizeof(complex));
    cdata  = (complex *)calloc(nxm*nfreq, sizeof(complex));

    if (conjg) scl = -1.0;
    else scl = 1.0;

    sign  = -1;
    for (ix = 0; ix < nx; ix++) {

        memcpy(trace,&data[ix*nt],nt*sizeof(float));
        if (optn > nt)
            memset( &trace[nt], 0, sizeof(float)*(optn-nt) );

        rc1fft(trace,ctrace,optn,sign);

        ixrcv = NINT((xrcv[ix]-ox)/dxm);
        if (ixrcv < 0 || ixrcv > nxm-1) {
            fprintf(stderr,"kwZoMigr: ixrcv %f (%d) outside model\n", xrcv[ix], ixrcv);
            continue;
        }
        for (iom=0; iom<nfreq; iom++) {
            /* positioning of shot record into velocity model */
            cdata[iom*nxm+ixrcv].r = ctrace[iom].r;
            cdata[iom*nxm+ixrcv].i = ctrace[iom].i*scl;
        }
    }

    /* determine aperture to be calculated */

    ixo = nxm;
    ixn = 0;
    for (ix = 0; ix < nx; ix++) {
        ixrcv = NINT((xrcv[ix]-ox)/dxm);
        if (ixrcv < ixo) ixo = ixrcv;
        if (ixrcv > ixn) ixn = ixrcv;
    }
    ixmin = MAX(0, ixo-ixb-1);
    ixmax = MIN(ixn+ixa+1, nxm-1);
    nx    = (ixmax-ixmin)+1;

    if (verbose>=2) {
        vmess("kwZoMigr: calculation aperture: %.2f (%d) <--> %.2f (%d) (%d positions)", ixmin*dxm+ox, ixmin, ixmax*dxm+ox, ixmax, nx);
    }

    /* define some constants */

    scl   = 2.0/nfreq;
    scl   = 1.0/(dt*dxm*dxm);
    nkx   = optncc(2*ntap+nxm);
    ntap  = (nkx-nxm)/2;
    scl2  = 1.0/nkx;
    dkx   = 2.0*M_PI/(nkx*dxm);

    taper = (float *)malloc(ntap*sizeof(float));
    for (ix = 0; ix < ntap; ix++) {
        taper[ix] = exp(-1.0*(pow((0.4*(ntap-ix)/ntap), 2)));
    }

    /* calculate image at depth = 0 */

    if(izrcv==0 ) {
        for (ix = ixmin; ix <= ixmax; ix++) {
            for (iom = iomin; iom <= iomax; iom++) {
                image[ix*nzm+0] += scl*cdata[iom*nxm+ix].r;
            }
        }
    }

    t0 = wallclock_time();

    locdat  = (complex *)malloc(nkx*sizeof(complex));

    /* start extrapolation for all frequencies, depths and x-positions */

    for (iom = iomin; iom <= iomax; iom++) {
        memset(locdat,0,nkx*sizeof(complex));

        for (ix = ixmin; ix <= ixmax; ix++) {
            locdat[ntap+ix] = cdata[iom*nxm+ix];
        }
        om = iom*dom;
        d  = izrcv;

        /* start extrapolation of receiver arrays */

        for (; d < ndepth; d++) {

            /* transform to wavenumber domain */

            cc1fft(locdat, nkx, 1);

            /* Extrapolation of data */

            c = 0.0;
            for (ix = ixmin; ix <= ixmax; ix++) c += velmod[d*nxm+ix];
            k = nx*om/c;
            k2 = k*k;

            /* kx = 0 */
            ez.r = cos(k*dz);
            ez.i = -sin(k*dz);

            tmp.r  = ez.r*locdat[0].r;
            tmp.r += ez.i*locdat[0].i;
            tmp.i  = ez.r*locdat[0].i;
            tmp.i -= ez.i*locdat[0].r;
            locdat[0] = tmp;

            /* kx != 0 */
            endkx = MIN((int)(k/dkx),nkx/2);
            for (ikx = 1; ikx <= endkx; ikx++) {
                kx  = ikx*dkx;
                kx2 = kx*kx;
                kz2 = k2 - kx2;

                ez.r = cos(sqrt(kz2)*dz);
                ez.i = -sin(sqrt(kz2)*dz);

                tmp.r  = ez.r*locdat[ikx].r;
                tmp.r += ez.i*locdat[ikx].i;
                tmp.i  = ez.r*locdat[ikx].i;
                tmp.i -= ez.i*locdat[ikx].r;
                locdat[ikx] = tmp;

                tmp.r  = ez.r*locdat[nkx-ikx].r;
                tmp.r += ez.i*locdat[nkx-ikx].i;
                tmp.i  = ez.r*locdat[nkx-ikx].i;
                tmp.i -= ez.i*locdat[nkx-ikx].r;
                locdat[nkx-ikx] = tmp;
            }

            /* transform data back to space domain */

            cc1fft(locdat, nkx, -1);

            for (j = 0; j < nkx; j++) {
                locdat[j].r *= scl2;
                locdat[j].i *= scl2;
            }

            /* imaging condition */

            for (ix = ixmin; ix <= ixmax; ix++) {
                image[ix*nzm+d+1]+= scl*locdat[ntap+ix].r;
            }

            /* save extrapolated field at requested depth */

            if	(d==ndepthex-1) {
                if ( cexrcv != NULL ) {
                    for (ix = 0; ix < nxm; ix++) {
                        cexrcv[iom*nxm+ix] = locdat[ntap+ix];
                    }
                }
            }

            /* taper extrapolated data at edges */

            for (j = 0; j < ntap; j++) {
                locdat[j].r *= taper[j];
                locdat[j].i *= taper[j];
                locdat[nkx-j-1].r *= taper[j];
                locdat[nkx-j-1].i *= taper[j];
            }

        } /* end of depth loop */

    } /* end of iom loop */


    if(exrcv) wx2xt(cexrcv, exrcv, optn, nxm, nxm, optn);

    free(locdat);
    free(cdata);
    free(taper);

    t1 = wallclock_time();
    vmess("kwZoMigr took: %f seconds", t1-t0);

    return;
}
void convolhom(float *data1, float *data2, float *con, int nrec, int nsam, float dt, int shift, float rho, int mode)
{
    int     i, j, n, optn, nfreq, sign;
    float   df, dw, om, tau, scl;
    float   *qr, *qi, *p1r, *p1i, *p2r, *p2i, *rdata1, *rdata2;
    complex *cdata1, *cdata2, *ccon, tmp;

    optn = optncr(nsam);
    nfreq = optn/2+1;


    cdata1 = (complex *)malloc(nfreq*nrec*sizeof(complex));
    if (cdata1 == NULL) verr("memory allocation error for cdata1");
    cdata2 = (complex *)malloc(nfreq*nrec*sizeof(complex));
    if (cdata2 == NULL) verr("memory allocation error for cdata2");
    ccon = (complex *)malloc(nfreq*nrec*sizeof(complex));
    if (ccon == NULL) verr("memory allocation error for ccov");

    rdata1 = (float *)malloc(optn*nrec*sizeof(float));
    if (rdata1 == NULL) verr("memory allocation error for rdata1");
    rdata2 = (float *)malloc(optn*nrec*sizeof(float));
    if (rdata2 == NULL) verr("memory allocation error for rdata2");

    /* pad zeroes until Fourier length is reached */
    pad_data(data1, nsam, nrec, optn, rdata1);
    pad_data(data2, nsam, nrec, optn, rdata2);

    /* forward time-frequency FFT */
    sign = -1;
    rcmfft(&rdata1[0], &cdata1[0], optn, nrec, optn, nfreq, sign);
    rcmfft(&rdata2[0], &cdata2[0], optn, nrec, optn, nfreq, sign);

    /* apply convolution */
    p1r = (float *) &cdata1[0];
    p2r = (float *) &cdata2[0];
    qr = (float *) &ccon[0].r;
    p1i = p1r + 1;
    p2i = p2r + 1;
    qi = qr + 1;
    n = nrec*nfreq;
    for (j = 0; j < n; j++) {
        *qr = (*p2r**p1r-*p2i**p1i);
        *qi = (*p2r**p1i+*p2i**p1r);
        qr += 2;
        qi += 2;
        p1r += 2;
        p1i += 2;
        p2r += 2;
        p2i += 2;
    }
    free(cdata1);
    free(cdata2);

    if (shift) {
        df = 1.0/(dt*optn);
        dw = 2*PI*df;
        tau = dt*(nsam/2);
        for (j = 0; j < nrec; j++) {
            om = 0.0;
            for (i = 0; i < nfreq; i++) {
                tmp.r = ccon[j*nfreq+i].r*cos(om*tau) + ccon[j*nfreq+i].i*sin(om*tau);
                tmp.i = ccon[j*nfreq+i].i*cos(om*tau) - ccon[j*nfreq+i].r*sin(om*tau);
                ccon[j*nfreq+i] = tmp;
                om += dw;
            }
        }
    }

	/* Scaling for the homogeneous equation */
	if (mode==0) {//single source
    	df = 1.0/(dt*optn);
    	dw = 2.0*(M_PI)*df;
    	for (i=0; i<nrec; i++) {
			j=0;
			ccon[i*nfreq+j].r *= 0.0;
			ccon[i*nfreq+j].i *= 0.0;
        	for (j=1; j<nfreq; j++) {
            	ccon[i*nfreq+j].r *= (4.0/(rho*dw*j));
            	ccon[i*nfreq+j].i *= (4.0/(rho*dw*j));
        	}
    	}
	}
	else {//multiple sources
		df = 1.0/(dt*optn);
        dw = 2.0*(M_PI)*df;
        for (i=0; i<nrec; i++) {
			j=0;
            ccon[i*nfreq+j].r *= 0.0;
            ccon[i*nfreq+j].i *= 0.0;
            for (j=1; j<nfreq; j++) {
				tmp.r = (2.0/(rho*dw*j))*ccon[i*nfreq+j].i;
				tmp.i = (2.0/(rho*dw*j))*ccon[i*nfreq+j].r;
				ccon[i*nfreq+j]=tmp;
            }
        }
	}

    /* inverse frequency-time FFT and scale result */
    sign = 1;
    scl = 1.0/((float)(optn));
    crmfft(&ccon[0], &rdata1[0], optn, nrec, nfreq, optn, sign);
    scl_data(rdata1,optn,nrec,scl,con,nsam);

    free(ccon);
    free(rdata1);
    free(rdata2);
    return;
}
示例#11
0
int defineSource(wavPar wav, srcPar src, float **src_nwav, int reverse, int verbose)
{
    FILE    *fp;
    size_t  nread;
    int optn, nfreq, i, j, k, iwmax, tracesToDo;
	int iw, n1, namp;
    float scl, d1, df, deltom, om, tshift;
	float amp1, amp2, amp3;
	float *trace, maxampl;
    complex *ctrace, tmp;
    segy hdr;
    
	n1 = wav.nt;
	if (wav.random) { /* initialize random sequence */
		srand48(wav.seed+1);
		seedCMWC4096();
		for (i=0; i<8192; i++) {
			amp1 = dcmwc4096();
		}

	}
	else {

/* read first header and last byte to get file size */

    	fp = fopen( wav.file_src, "r" );
    	assert( fp != NULL);
    	nread = fread( &hdr, 1, TRCBYTES, fp );
    	assert(nread == TRCBYTES);
	
/* read all traces */

		tracesToDo = wav.nx;
		i = 0;
		while (tracesToDo) {
			memset(&src_nwav[i][0],0,n1*sizeof(float));
        	nread = fread(&src_nwav[i][0], sizeof(float), hdr.ns, fp);
        	assert (nread == hdr.ns);
	
        	nread = fread( &hdr, 1, TRCBYTES, fp );
        	if (nread==0) break;
			tracesToDo--;
			i++;
		}
    	fclose(fp);
	}


	optn = optncr(2*n1);
	nfreq = optn/2 + 1;
	ctrace = (complex *)calloc(nfreq,sizeof(complex));
	trace = (float *)calloc(optn,sizeof(float));

	df     = 1.0/(optn*wav.dt);
    deltom = 2.*M_PI*df;
	scl    = 1.0/optn;
	maxampl=0.0;
	iwmax = nfreq;

	for (i=0; i<wav.nx; i++) {
		if (wav.random) {
			randomWavelet(wav, src, &src_nwav[i][0], src.tbeg[i], src.tend[i], verbose);
		}
		else {
			memset(&ctrace[0].r,0,nfreq*sizeof(complex));
			memset(&trace[0],0,optn*sizeof(float));
			memcpy(&trace[0],&src_nwav[i][0],n1*sizeof(float));
			rc1fft(trace,ctrace,optn,-1);
			/* Scale source from file with -j/w (=1/(jw)) for volume source injections
         	   no scaling is applied for volume source injection rates */
            if (src.injectionrate==0) {
                for (iw=1;iw<iwmax;iw++) {
                    om = 1.0/(deltom*iw);
                    tmp.r = om*ctrace[iw].i;
                    tmp.i = -om*ctrace[iw].r;
                    ctrace[iw].r = tmp.r;
                    ctrace[iw].i = tmp.i;
                }
            }
/*
*/
            if (src.type < 6) { // shift wavelet with +1/2 DeltaT due to staggered in time 
				tshift=0.5*wav.dt;
                for (iw=1;iw<iwmax;iw++) {
            		om = deltom*iw*tshift;
            		tmp.r = ctrace[iw].r*cos(-om) - ctrace[iw].i*sin(-om);
            		tmp.i = ctrace[iw].i*cos(-om) + ctrace[iw].r*sin(-om);
                    ctrace[iw].r = tmp.r;
                    ctrace[iw].i = tmp.i;
                }
			}

			/* zero frequency iw=0 set to 0 if the next sample has amplitude==0*/
			amp1 = sqrt(ctrace[1].r*ctrace[1].r+ctrace[1].i*ctrace[1].i);
			if (amp1 == 0.0) {
				ctrace[0].r = ctrace[0].i = 0.0;
			}
			else { /* stabilization for w=0: extrapolate amplitudes to 0 */
				amp2 = sqrt(ctrace[2].r*ctrace[2].r+ctrace[2].i*ctrace[2].i);
				amp3 = sqrt(ctrace[3].r*ctrace[3].r+ctrace[3].i*ctrace[3].i);
				ctrace[0].r = amp1+(2.0*(amp1-amp2)-(amp2-amp3));
				ctrace[0].i = 0.0;
				if (ctrace[1].r < 0.0) {
					ctrace[0].r *= -1.0;
				}
			}
			for (iw=iwmax;iw<nfreq;iw++) {
				ctrace[iw].r = 0.0;
				ctrace[iw].i = 0.0;
			}
			cr1fft(ctrace,trace,optn,1);
			/* avoid a (small) spike in the last sample 
			   this is done to avoid diffraction from last wavelet sample
			   which will act as a pulse */
			if (reverse) {
				for (j=0; j<n1; j++) src_nwav[i][j] = scl*(trace[n1-j-1]-trace[0]);
//				for (j=0; j<n1; j++) src_nwav[i][j] = scl*(trace[j]-trace[optn-1]);
			}
			else {
				for (j=0; j<n1; j++) src_nwav[i][j] = scl*(trace[j]-trace[optn-1]);
			}
		}

    }
    free(ctrace);
    free(trace);

/* use random amplitude gain factor for each source */
	if (src.amplitude > 0.0) {
		namp=wav.nx*10;
		trace = (float *)calloc(2*namp,sizeof(float));
		for (i=0; i<wav.nx; i++) {
			if (src.distribution) {
				scl = gaussGen()*src.amplitude;
				k = (int)MAX(MIN(namp*(scl+5*src.amplitude)/(10*src.amplitude),namp-1),0);
				d1 = 10.0*src.amplitude/(namp-1);
			}
			else {
				scl = (float)(drand48()-0.5)*src.amplitude;
				k = (int)MAX(MIN(namp*(scl+1*src.amplitude)/(2*src.amplitude),namp-1),0);
				d1 = 2.0*src.amplitude/(namp-1);
			}

			trace[k] += 1.0;
/*			trace[i] = scl; */
			if (wav.random) n1 = wav.nsamp[i];
			else n1 = wav.nt;
			for (j=0; j<n1; j++) {
				src_nwav[i][j] *= scl;
			}
    	}
		if (verbose>2) writesufile("src_ampl.su", trace, namp, 1, -5*src.amplitude, 0.0, d1, 1);
/*
		qsort(trace,wav.nx,sizeof(float), comp);
		for (i=0; i<wav.nx; i++) {
			scl = trace[i];
			trace[i] = normal(scl, 0.0, src.amplitude);
		}
		if (verbose>2) writesufile("src_ampl.su", trace, wav.nx, 1, -5*src.amplitude, 0.0, d1, 1);
*/

		free(trace);
	}

	if (verbose>3) writesufilesrcnwav("src_nwav.su", src_nwav, wav, wav.nt, wav.nx, 0.0, 0.0, wav.dt, 1);

/* set maximum amplitude in source file to 1.0 */
/*
	assert(maxampl != 0.0);
	scl = wav.dt/(maxampl);
	scl = 1.0/(maxampl);
	for (i=0; i<wav.nx; i++) {
		for (j=0; j<n1; j++) {
			src_nwav[i*n1+j] *= scl;
		}
    }
*/

    return 0;
}
示例#12
0
int randomWavelet(wavPar wav, srcPar src, float *trace, float tbeg, float tend, int verbose)
{
    int optn, nfreq, j, iwmax;
	int iw, n1, itbeg, itmax, nsmth;
    float df, amp1;
	float *rtrace;
	float x1, x2, z1, z2, dzdx1, dzdx2, a, b, c, d, t;
    complex *ctrace;
    
	n1 = wav.nt; /* this is set to the maximum length (tlength/dt) */
	
	optn = optncr(2*n1);
	nfreq = optn/2 + 1;
	ctrace = (complex *)calloc(nfreq,sizeof(complex));
	rtrace = (float *)calloc(optn,sizeof(float));

	df     = 1.0/(optn*wav.dt);
    
	iwmax = MIN(NINT(wav.fmax/df),nfreq);
	
	for (iw=1;iw<iwmax;iw++) {
		ctrace[iw].r = (float)(drand48()-0.5);
		ctrace[iw].i = (float)(drand48()-0.5);
	}
	for (iw=iwmax;iw<nfreq;iw++) {
		ctrace[iw].r = 0.0;
		ctrace[iw].i = 0.0;
	}
	cr1fft(ctrace,rtrace,optn,1);
		
	/* find first zero crossing in wavelet */
	amp1 = rtrace[0];
	j = 1;
	if (amp1 < 0.0) {
		while (rtrace[j] < 0.0) j++;
	}
	else {
		while (rtrace[j] > 0.0) j++;
	}
	itbeg = j;
			
	/* find last zero crossing in wavelet */
//	itmax = itbeg+MIN(NINT((tend-tbeg)/wav.dt),n1);
	itmax = MIN(NINT(itbeg+(tend-tbeg)/wav.dt),n1);

	amp1 = rtrace[itmax-1];
	j = itmax;
	if (amp1 < 0.0) {
		while (rtrace[j] < 0.0 && j>itbeg) j--;
		}
	else {
		while (rtrace[j] > 0.0 && j>itbeg) j--;
	}
	itmax = j;
			
	/* make smooth transitions to zero aamplitude */
	nsmth=MIN(10,itmax);
	x1 = 0.0;
	z1 = 0.0;
	dzdx1 = 0.0;
	x2 = nsmth;
	z2 = rtrace[itbeg+nsmth];
//	dzdx2 = (rtrace[itbeg+(nsmth+1)]-rtrace[itbeg+(nsmth-1)])/(2.0);
	dzdx2 = (rtrace[itbeg+nsmth-2]-8.0*rtrace[itbeg+nsmth-1]+
			 8.0*rtrace[itbeg+nsmth+1]-rtrace[itbeg+nsmth+2])/(12.0);
	spline3(x1, x2, z1, z2, dzdx1, dzdx2, &a, &b, &c, &d);
	for (j=0; j<nsmth; j++) {
		t = j;
		rtrace[itbeg+j] = a*t*t*t+b*t*t+c*t+d;
	}
			
	x1 = 0.0;
	z1 = rtrace[itmax-nsmth];
//	dzdx1 = (rtrace[itmax-(nsmth-1)]-rtrace[itmax-(nsmth+1)])/(2.0);
	dzdx1 = (rtrace[itmax-nsmth-2]-8.0*rtrace[itmax-nsmth-1]+
			 8.0*rtrace[itmax-nsmth+1]-rtrace[itmax-nsmth+2])/(12.0);
	x2 = nsmth;
	z2 = 0.0;
	dzdx2 = 0.0;
			
//	fprintf(stderr,"x1=%f z1=%f d=%f x2=%f, z2=%f d=%f\n",x1,z1,dzdx1,x2,z2,dzdx2);
	spline3(x1, x2, z1, z2, dzdx1, dzdx2, &a, &b, &c, &d);
	for (j=0; j<nsmth; j++) {
		t = j;
		rtrace[itmax-nsmth+j] = a*t*t*t+b*t*t+c*t+d;
//		fprintf(stderr,"a=%f b=%f c=%f d=%f rtrace%d=%f \n",a,b,c,d,j,rtrace[itmax-nsmth+j]);
	}
			
	for (j=itbeg; j<itmax; j++) trace[j-itbeg] = rtrace[j];
	
    free(ctrace);
    free(rtrace);

    return 0;
}
示例#13
0
void xwVSP(float *data, int nx, int nt, float dt, float *xrcv, float *velmod, int nxm, int ndepth, float ox, float dxm, float fmin, float fmax, int opl, int ntap, int *xi, int *zi, int nvsp, int ispr, int nrec, float *vsp, int verbose)
{
	int    	iomin, iomax, iom, ix, d, hopl, hopl2, hoplen, i, j;
	int	index1, i1, i2, nfreq, optn, lenx, ixp, izp, ixrcv;
	float  	dom, om, c, cprev, df;
	float	*rdata, *taper, *pdata;
	complex	*opx, *cdata, *tmp1, *tmp2, wa, *cvsp;

	optn  = optncr(nt);
	nfreq = optn/2 + 1;
	tmp1  = (complex *)malloc(nx*nfreq*sizeof(complex));

	/* pad zero's to get fourier length */
	if( nt != optn ) {
		if (verbose >1) vmess("xwVSP: padding zeros to data from %d to %d",nt,optn);
        	pdata = (float *)calloc(optn*nx,sizeof(float));
        	for (i=0; i<nx; i++) {
                	for (j=0; j<nt; j++) pdata[i*optn+j] = data[i*nt+j];
                	for ( ; j<optn; j++) pdata[i*optn+j] = 0.0;
                	}
		}
	else {
		pdata = &data[0];
		}

        xt2wx(pdata, tmp1, optn, nx, optn, nx);

	if( nt != optn ) free(pdata);

/* positioning of shot record into velocity model */

	cdata = (complex *)calloc(nxm*nfreq, sizeof(complex));
	for (iom = 0; iom < nfreq; iom++) {\
		for (ix = 0; ix < nx; ix++) {
			ixrcv = NINT((xrcv[ix]-ox)/dxm);
			cdata[iom*nxm+ixrcv].r += tmp1[iom*nx+ix].r;
			cdata[iom*nxm+ixrcv].i += tmp1[iom*nx+ix].i;
		}
	}
	free(tmp1);

/* define some constants */

	nx    = nxm;
	df    = 1.0/(optn*dt);
	dom   = 2.*PI*df;
	iomin = (int)MIN((fmin*dt*optn), (nfreq-1));
	iomin = MAX(iomin, 1);
	iomax = MIN((int)(fmax*dt*optn), (nfreq-1));
	hopl  = (opl+1)/2;
	hopl2 = hopl-1;
	lenx  = 2*hopl2+nx;

	if(verbose) {
		fprintf(stderr,"    xwVSP: number of depth steps = %d\n",ndepth);
		fprintf(stderr,"    xwVSP: number of frequencies = %d\n",iomax-iomin+1);
	}
	cvsp  = calloc(nrec*nfreq*nvsp, sizeof(complex));

	taper  = (float *)malloc(nx*sizeof(float));
	for (ix = 0; ix < nx; ix++) taper[ix] = 1.0;
	for (ix = 0; ix < ntap; ix++) {
		taper[ix] = exp(-1.0*(pow((0.4*(ntap-ix)/ntap), 2)));
		taper[nx-1-ix] = taper[ix];
	}

	for (iom = 0; iom < iomin; iom++) {
		for (ix = 0; ix < nx; ix++) {
			cdata[iom*nx+ix].r = 0.0;
			cdata[iom*nx+ix].i = 0.0;
		}
	}
	for (iom = iomax; iom < nfreq; iom++) {
		for (ix = 0; ix < nx; ix++) {
			cdata[iom*nx+ix].r = 0.0;
			cdata[iom*nx+ix].i = 0.0;
		}
	}

#pragma omp parallel \
 shared(cdata, cvsp) \
 shared(hopl, hopl2, velmod, lenx, iomin, iomax, taper, dom) \
 shared(nx, ndepth, xi, zi, nvsp, ispr, nrec, nfreq, verbose) \
 private(iom, tmp1, tmp2, wa, cprev, d, ix, j, c, om, index1) \
 private(i1, i2, opx, ixp, izp) 
    { /* start of parallel region */

	tmp1  = (complex *)calloc(lenx, sizeof(complex));
	tmp2  = (complex *)calloc(lenx, sizeof(complex));
	opx   = (complex *)calloc(hopl, sizeof(complex));

#pragma omp for 
	for (iom = iomin; iom <= iomax; iom++) {
		om = iom*dom;
		cprev = 0;
		if (verbose>=2) fprintf(stderr,"    xwVSP: processing frequency %.3f\n", om/(2*PI));
		for (j = 0; j < nx; j++) {
			tmp1[hopl2+j].r = cdata[iom*nx+j].r*taper[j];
			tmp1[hopl2+j].i = cdata[iom*nx+j].i*taper[j];
		}

		for (d = 0; d < ndepth; d++) {

			for (j = 0; j < nvsp; j++) {
				for (ix = 0; ix < nrec; ix++) {
					ixp = xi[ix] + j*ispr;
					izp = zi[ix];
					if (izp == d) {
						cvsp[j*nfreq*nrec+iom*nrec+ix] = tmp1[hopl2+ixp];
					}
				}
			}


			for (ix = 0; ix < nx; ix++) {
				c = velmod[d*nxm+ix];
				if (c != cprev) {
					readtable_opt(opx, om/c, &hoplen);
					cprev = c;
				}

				wa.r = wa.i = 0.0;
				index1 = ix + hopl2;
                for (j = 0; j < hoplen; j++) {
					i1 = index1+j;
					i2 = index1-j;
					wa.r += (tmp1[i1].r + tmp1[i2].r)*opx[j].r;
					wa.r -= (tmp1[i1].i + tmp1[i2].i)*opx[j].i;
					wa.i += (tmp1[i1].i + tmp1[i2].i)*opx[j].r;
					wa.i += (tmp1[i1].r + tmp1[i2].r)*opx[j].i;
                }
				tmp2[index1] = wa;
			}
			for (ix = 0; ix < lenx; ix++) tmp1[ix] = tmp2[ix];
		}
		for (ix = 0; ix < nx; ix++) cdata[iom*nx+ix] = tmp2[hopl2+ix];
	}

	free(opx);
	free(tmp1);
	free(tmp2);

} /* end of parallel region */

	rdata  = (float *)malloc(nx*optn*sizeof(float));
	wx2xt(cdata, rdata, optn, nx, nx, optn);

	for (ix = 0; ix < nx; ix++) {
		for (j = 0; j < nt; j++) data[ix*nt+j] = rdata[ix*optn+j];
	}

	for (j = 0; j < nvsp; j++) {
		wx2xt(&cvsp[j*nfreq*nrec], (float *)&vsp[j*optn*nrec], optn, nrec, nrec, optn);
	}

	free(cdata);
	free(cvsp);
	free(taper);
	free(rdata);

	return;
}