示例#1
0
int main(int argc, char **argv)      /*argc, argv - the arguments to the main() function*/
{ 
int nt;                              /*number of time samples*/
int nz;			             /*number of migrated depth samples*/
int nx;                              /*number of midpoints (traces)*/
int ix;
int iz;

float dt;                            /*time sampling interval*/                
float dx;                            /*spatial sampling interval*/
float dz;                            /*migrated depth sampling interval*/           
float **data;                        /*input seismic data*/
complex **image;                     /*migrated image*/      
float **rimage;                      /*migrated image*/ 
float **v;                           /*velocity model*/
FILE *vfp;

char *vfile="";                      /*name of velocity file*/
int verbose=1;
char *tmpdir;		             /* directory path for tmp files*/
cwp_Bool istmpdir=cwp_false;         /* true for user-given path*/

/******************************* Intialize *********************************************/
initargs(argc,argv);
requestdoc(1);

/********************************* Get parameters **************************************/
/*get info from first trace*/
if (!gettr(&tr))  err("can't get first trace");  /*fgettr: get a fixed-length segy trace from a file by file pointer*/
nt = tr.ns;                         /*nt*/       /*gettr: macro using fgettr to get a trace from stdin*/

if (!getparfloat("dt", &dt)) {      /*dt*/
if (tr.dt) { 
dt = ((double) tr.dt)/1000000.0;
} 
else {err("dt is not set");}
}

if (!getparfloat("dx", &dx)) {       /*dx*/
if (tr.d2) {
dx = tr.d2;
} 
else {
err("dx is not set");
}
}

/*get optional parameters*/
if (!getparint("nz",&nz)) err("nz must be specified"); 
if (!getparfloat("dz",&dz)) err("dz must be specified");
if (!getparstring("vfile", &vfile)) err("velocity file must be specified");
if (!getparint("verbose", &verbose)) verbose = 0;
/****************************************************************************************/

/* Look for user-supplied tmpdir */
if (!getparstring("tmpdir",&tmpdir) &&
 !(tmpdir = getenv("CWP_TMPDIR"))) tmpdir="";
if (!STREQ(tmpdir, "") && access(tmpdir, WRITE_OK))
err("you can't write in %s (or it doesn't exist)", tmpdir);
checkpars();

/**************************** Count trace number nx ******************************/
/* store traces and headers in tempfiles while getting a count */
	if (STREQ(tmpdir,"")) {
		tracefp = etmpfile();
		headerfp = etmpfile();
		if (verbose) warn("using tmpfile() call");
	} 
     else { /* user-supplied tmpdir */
		char directory[BUFSIZ];
		strcpy(directory, tmpdir);
		strcpy(tracefile, temporary_filename(directory));
		strcpy(headerfile, temporary_filename(directory));
		/* Trap signals so can remove temp files */
		signal(SIGINT,  (void (*) (int)) closefiles);
		signal(SIGQUIT, (void (*) (int)) closefiles);
		signal(SIGHUP,  (void (*) (int)) closefiles);
		signal(SIGTERM, (void (*) (int)) closefiles);
		tracefp = efopen(tracefile, "w+");
		headerfp = efopen(headerfile, "w+");
      		istmpdir=cwp_true;		
		if (verbose) warn("putting temporary files in %s", directory);
	}

	nx = 0;
	do {
		 ++nx;                                   /*get the number of traces nx*/
		efwrite(&tr,HDRBYTES,1,headerfp);
		efwrite(tr.data, FSIZE, nt, tracefp);
	} while (gettr(&tr));

	erewind(tracefp);                    /*Set position of stream to the beginning*/
	erewind(headerfp);

/******************************************************************************************/

/*allocate memory*/
data = alloc2float(nt,nx);                   /*2D array nx by nt*/
image = alloc2complex(nz,nx);                /*2D array nx by nz*/
rimage = alloc2float(nz,nx);                 /*2D array nx by nz*/
v= alloc2float(nz,nx);                       /*2D array, in Fortran the velocity model is nz by nx 2D array*/ 
                                             /*in binary, it is actually 1D*/

/* load traces into the zero-offset array and close tmpfile */
efread(*data, FSIZE, nt*nx, tracefp);        /*read traces to data*/
efclose(tracefp);                 

/*load velicoty file*/
vfp=efopen(vfile,"r");	
efread(v[0],FSIZE,nz*nx,vfp);                    /*load velocity*/
efclose(vfp);			

/***********************finish reading data*************************************************/
/* call pspi migration function*/
pspimig(data,image,v,nt,nx,nz,dt,dx,dz);

/*get real part of image*/
for (iz=0;iz<nz;iz++){
for (ix=0;ix<nx;ix++){
rimage[ix][iz] = image[ix][iz].r;
}
}

/* restore header fields and write output */
for (ix=0; ix<nx; ix++) {
efread(&tr,HDRBYTES,1,headerfp);
tr.ns = nz;
tr.d1 = dz;
memcpy( (void *) tr.data, (const void *) rimage[ix],nz*FSIZE);
puttr(&tr);
}
	
/* Clean up */
efclose(headerfp);
if (istmpdir) eremove(headerfile);
if (istmpdir) eremove(tracefile);
return(CWP_Exit());	
}
示例#2
0
int
main(int argc, char **argv)
{
	char *key=NULL;		/* header key word from segy.h		*/
	char *type=NULL;	/* ... its type				*/
	int index;		/* ... its index			*/
	Value val;		/* ... its value			*/
	float fval;		/* ... its value cast to float		*/

	float *xshift=NULL;	/* array of key shift curve values	*/
	float *tshift=NULL;	/* ...		shift curve time values */

	int nxshift;		/* number of key shift values		*/
	int ntshift;		/* ...		shift time values 	*/

	int nxtshift;		/* number of shift values 		*/

	int it;			/* sample counter			*/
	int itr;		/* trace counter			*/
	int nt;			/* number of time samples 		*/
	int ntr=0;		/* number of traces			*/
	int *inshift=NULL;	/* array of (integer) time shift values
				   used for positioning shifted trace in
				   data[][]				*/

	float dt;		/* time sampling interval		*/

	cwp_String xfile="";	/* file containing positions by key	*/
	FILE *xfilep=NULL;	/* ... its file pointer			*/
	cwp_String tfile="";	/* file containing times	 	*/
	FILE *tfilep=NULL;	/* ... its file pointer			*/

	int verbose;		/* flag for printing information	*/
	char *tmpdir=NULL;	/* directory path for tmp files		*/
	cwp_Bool istmpdir=cwp_false;/* true for user-given path		*/

	int median;		/* flag for median filter		*/
	int nmed;		/* no. of traces to median filter	*/
	int nmix;		/* number of traces to mix over		*/
	int imix;		/* mixing counter			*/
	float *mix=NULL;	/* array of mix values			*/
	int sign;		/* flag for up/down shift		*/
	int shiftmin=0;		/* minimum time shift (in samples)	*/
	int shiftmax=0;		/* maximum time shift (in samples)	*/
	int ntdshift;		/* nt + shiftmax			*/

	size_t mixbytes;	/* size of mixing array			*/
	size_t databytes;	/* size of data array			*/
	size_t shiftbytes;	/* size of data array			*/
	float *temp=NULL;	/* temporary array			*/
	float *dtemp=NULL;	/* temporary array			*/
	float *stemp=NULL;	/* rwh median sort array		*/
	float **data=NULL;	/* mixing array 			*/
	int subtract;		/* flag for subtracting shifted data	*/

	/* rwh extra pointers for median sort */
	int first;		/* start pointer in ring buffer */
	int middle;		/* middle pointer in ring buffer */
	int last;		/* last pointer in ring buffer */
	int halfwidth;		/* mid point */
	int trcount;		/* pointer to current start trace number */
	float tmp;		/* temp storage for bubble sort */
	int rindex;		/* wrap around index for ring buffer */
	int jmix;		/* internal pointer for bubble sort */
	

	/* Initialize */
	initargs(argc, argv);
	requestdoc(1);

	/* Get parameters */
	if (!(getparstring("xfile",&xfile) && getparstring("tfile",&tfile))) {
		if (!(nxshift = countparval("xshift")))
			err("must give xshift= vector");
		if (!(ntshift = countparval("tshift")))
			err("must give tshift= vector");
		if (nxshift != ntshift)
			err("lengths of xshift, tshift must be the same");
		xshift = ealloc1float(nxshift);	getparfloat("xshift", xshift);
		tshift = ealloc1float(nxshift);	getparfloat("tshift", tshift);
	} else {
		MUSTGETPARINT("nshift",&nxtshift);
		nxshift = nxtshift;
		xshift = ealloc1float(nxtshift);
		tshift = ealloc1float(nxtshift);

		if((xfilep=fopen(xfile,"r"))==NULL)
			err("cannot open xfile=%s\n",xfile);
		if (fread(xshift,sizeof(float),nxtshift,xfilep)!=nxtshift)
			err("error reading xfile=%s\n",xfile);
		fclose(xfilep);

		if((tfilep=fopen(tfile,"r"))==NULL)
			err("cannot open tfile=%s\n",tfile);
		if (fread(tshift,sizeof(float),nxtshift,tfilep)!=nxtshift)
			err("error reading tfile=%s\n",tfile);
		fclose(tfilep);
	}
	if (!getparstring("key", &key))		key = "tracl";

	/* Get key type and index */
	type = hdtype(key);
	index = getindex(key);   

	/* Get mix weighting values values */
	if ((nmix = countparval("mix"))!=0) {
		mix = ealloc1float(nmix);
		getparfloat("mix",mix);
		/* rwh check nmix is odd */
		if (nmix%2==0) {
			err("number of mixing coefficients must be odd");
		}		
	} else {
		nmix = 5;
		mix = ealloc1float(nmix);
		mix[0] = VAL0;
		mix[1] = VAL1;
		mix[2] = VAL2;
		mix[3] = VAL3;
		mix[4] = VAL4;
	}
	
	/* Get remaning parameters */
	if (!getparint("median",&median))	median = 0;
	if (!getparint("nmed",&nmed) && median)	nmed = 5;
	if (!getparint("sign",&sign))		sign = -1;
	if (!getparint("subtract",&subtract))	subtract = 1;
	if (!getparint("verbose", &verbose))	verbose = 0;

	/* rwh check nmed is odd */
	if (median && nmed%2==0) {
		nmed=nmed+1;
		warn("increased nmed by 1 to ensure it is odd");
	}

	/* Look for user-supplied tmpdir */
	if (!getparstring("tmpdir",&tmpdir) &&
	    !(tmpdir = getenv("CWP_TMPDIR"))) tmpdir="";
	if (!STREQ(tmpdir, "") && access(tmpdir, WRITE_OK))
		err("you can't write in %s (or it doesn't exist)", tmpdir);

	/* rwh fix for median filter if median true set nmix=nmed */
	if (!median) {
		/* Divide mixing weights by number of traces to mix */
		for (imix = 0; imix < nmix; ++imix)
			mix[imix]=mix[imix]/((float) nmix);
	} else {
		nmix=nmed;
	}

	/* Get info from first trace */
	if (!gettr(&tr)) err("can't read first trace");
	if (!tr.dt) err("dt header field must be set");
	dt   = ((double) tr.dt)/1000000.0;
	nt = (int) tr.ns;
	databytes = FSIZE*nt;

	/* Tempfiles */
	if (STREQ(tmpdir,"")) {
		tracefp = etmpfile();
		headerfp = etmpfile();
		if (verbose) warn("using tmpfile() call");
	} else { /* user-supplied tmpdir */
		char directory[BUFSIZ];
		strcpy(directory, tmpdir);
		strcpy(tracefile, temporary_filename(directory));
		strcpy(headerfile, temporary_filename(directory));
		/* Trap signals so can remove temp files */
		signal(SIGINT,  (void (*) (int)) closefiles);
		signal(SIGQUIT, (void (*) (int)) closefiles);
		signal(SIGHUP,  (void (*) (int)) closefiles);
		signal(SIGTERM, (void (*) (int)) closefiles);
		tracefp = efopen(tracefile, "w+");
		headerfp = efopen(headerfile, "w+");
      		istmpdir=cwp_true;		
		if (verbose) warn("putting temporary files in %s", directory);
	}

	/* Read headers and data while getting a count */
	do {
		++ntr;
		efwrite(&tr, 1, HDRBYTES, headerfp);
		efwrite(tr.data, 1, databytes, tracefp);   

	} while (gettr(&tr));
	rewind(headerfp);
	rewind(tracefp);
	
	/* Allocate space for inshift vector */
	inshift = ealloc1int(ntr);

	/* Loop over headers */
 	for (itr=0; itr<ntr; ++itr) {
		float tmin=tr.delrt/1000.0;
		float t;

		/* Read header values */
		efread(&tr, 1, HDRBYTES, headerfp);

		/* Get value of key and convert to float */
		gethval(&tr, index, &val);
		fval = vtof(type,val);

		/* Linearly interpolate between (xshift,tshift) values */
		intlin(nxshift,xshift,tshift,tmin,tshift[nxshift-1],1,&fval,&t);
		
		/* allow for fractional shifts -> requires interpolation */ 
		inshift[itr] = NINT((t - tmin)/dt);
		
		/* Find minimum and maximum shifts */
		if (itr==0) {
			 shiftmax=inshift[0];
			 shiftmin=inshift[0];
		} else {
			shiftmax = MAX(inshift[itr],shiftmax);
			shiftmin = MIN(inshift[itr],shiftmin);
		}
	}
	rewind(headerfp);
	rewind(tracefp);

	if (verbose) {
		for (itr=0;itr<ntr;itr++)
			warn("inshift[%d]=%d",itr,inshift[itr]);
	}

	/* Compute databytes per trace and bytes in mixing panel */
	ntdshift = nt + shiftmax;
	shiftbytes = FSIZE*ntdshift;
	mixbytes = shiftbytes*nmix;
	if (verbose) {
		warn("nt=%d  shiftmax=%d  shiftmin=%d",nt,shiftmax,shiftmin);
		warn("ntdshift=%d  shiftbytes=%d  mixbytes=%d",
						ntdshift,shiftbytes,mixbytes);
	}
	
	/* Allocate space and zero  data array */
	data = ealloc2float(ntdshift,nmix);
	temp = ealloc1float(ntdshift);
	dtemp = ealloc1float(nt);
	memset( (void *) data[0], 0, mixbytes);

	/* rwh array for out of place bubble sort (so we do not corrupt order in ring buffer */ 
	stemp = ealloc1float(nmix);

	/* rwh first preload ring buffer symmetrically (now you know why nmix must be odd) */
	trcount=-1;
	halfwidth=(nmix-1)/2+1;
	first = 0;
	last  = nmix-1;
	middle = (nmix-1)/2;

	for (itr=0; itr<halfwidth; itr++) {
		efread(tr.data, 1, databytes, tracefp);
		trcount++;
		for(it=0; it<nt; ++it) {
			/* sign to account for positive or negative shift */
			/* tr.data needs to be interpolated for non-integer shifts */
			data[middle-itr][it + shiftmax + sign*inshift[itr]] = tr.data[it];
			data[middle+itr][it + shiftmax + sign*inshift[itr]] = tr.data[it];
		}
	}
	
	/* Loop over traces performing median filtering  */
 	for (itr=0; itr<ntr; ++itr) {

		/* paste header and data on output trace */
		efread(&tr, 1, HDRBYTES, headerfp);

		/* Zero out temp and dtemp */
		memset((void *) temp, 0, shiftbytes);
		memset((void *) dtemp, 0, databytes);

		/* Loop over time samples */
		for (it=0; it<nt; ++it) {

			/* Weighted moving average (mix) ? */
			if (!median) {
				for(imix=0; imix<nmix; ++imix) {
					temp[it] += data[imix][it] * mix[imix];
				}
			} else {
			
			/* inlcude median stack */
			/* rwh do bubble sort and choose median value */
				for(imix=0; imix<nmix; ++imix) {
					stemp[imix]=data[imix][it];
				}
				for (imix=0; imix<nmix-1; imix++) {
					for (jmix=0; jmix<nmix-1-imix; jmix++) {
						if (stemp[jmix+1] < stemp[jmix]) {
							tmp = stemp[jmix];
							stemp[jmix] = stemp[jmix+1];
							stemp[jmix+1] = tmp;
						}
					}
				}
				temp[it] = stemp[middle];
			}

			/* shift back mixed data and put into dtemp */
			if (subtract) {
				if ((it - shiftmax - sign*inshift[itr])>=0)
					dtemp[it - shiftmax - sign*inshift[itr]] = data[middle][it]-temp[it];
			} else {
				if ((it - shiftmax)>=0)
				dtemp[it - shiftmax - sign*inshift[itr]] = temp[it];
			}
		}
		memcpy((void *) tr.data,(const void *) dtemp,databytes);
			
		/* Bump rows of data[][] over by 1 to free first row for next tr.data */
		for (imix=nmix-1; 0<imix; --imix)
			memcpy((void *) data[imix],(const void *) data[imix-1],shiftbytes);
			/*for (it=0; it<nt; ++it)
				data[imix][it] = data[imix-1][it];*/

		/* Write output trace */
		tr.ns = nt;
		puttr(&tr);

		/* read next trace into buffer */
		if (trcount < ntr) {
			efread(tr.data, 1, databytes, tracefp);
			trcount++;

			/* read tr.data into first row of mixing array */
			/* WMH: changed ntdshift to nt */
			for(it=0; it<nt; ++it) {
				/* sign to account for positive or negative shift */
				/* tr.data needs to be interpolated for non-integer shifts */
				data[0][it + shiftmax + sign*inshift[trcount]] = tr.data[it];
			}
		} else {
			rindex=2*(trcount-ntr);
			memcpy((void *) data[0],(const void *) data[rindex],shiftbytes);
			trcount++;
		}

	}

	if (verbose && subtract)	warn("filtered data subtracted from input");

	/* Clean up */
	efclose(headerfp);
	if (istmpdir) eremove(headerfile);
	efclose(tracefp);
	if (istmpdir) eremove(tracefile);

	return(CWP_Exit());
}
示例#3
0
int main(int argc, char **argv)
{
	char *plotcmd;		/* build pswigb command for popen	*/
	float *trbuf;		/* trace buffer				*/
	FILE *plotfp;		/* fp for plot data			*/
	int nt;			/* number of samples on trace	  	*/
	int ntr;		/* number of traces			*/
	int verbose;		/* verbose flag				*/
	float d1;		/* time/depth sample rate		*/
	float d2;		/* trace/dx sample rate			*/
	float f1;		/* tmin/zmin			   	*/
	float f2;		/* tracemin/xmin			*/
	cwp_Bool seismic;	/* is this seismic data?		*/
	cwp_Bool have_ntr=cwp_false;/* is ntr known from header or user?	*/
	char *tmpdir;		/* directory path for tmp files		*/
	cwp_Bool istmpdir=cwp_false;/* true for user given path		*/

	char *cwproot;		/* value of CWPROOT environment variable*/
	char *bindir;		/* directory path for tmp files		*/

	/* Support for irregularly spaced data */
	cwp_String key;		/* header key word with x2 information  */
	cwp_String type1=NULL;	/* ... its type				*/
	int index1=0;		/* ... its index			*/
	Value val;		/* value of key				*/
	Value scale;		/* Value of scaler			*/
	cwp_String type2=NULL;	/* ... its type				*/
	int index2=0;		/* ... its index			*/
	cwp_Bool isDepth=cwp_false;	/* Is this key a type of depth?		*/
	cwp_Bool isCoord=cwp_false;	/* Is this key a type of coordinate?	*/
	cwp_Bool irregular=cwp_false;  /* if true, reading x2 from header	*/ 
	cwp_String x2string;	/* string of x2 values			*/
	off_t x2len;		/* ... its length 			*/
	cwp_String style;	/* style parameter			*/


	/* Initialize */
	initargs(argc, argv);
	requestdoc(1);
	
	/* Get info from first trace */
	if (!gettr(&tr)) err("can't get first trace");
	seismic = ISSEISMIC(tr.trid); 
	nt = tr.ns;
	ntr = tr.ntr;
	if (ntr) have_ntr = cwp_true; 

	if (!getparint("verbose", &verbose))    verbose=0;
	if (!getparfloat("d1", &d1)) {
		if      (tr.d1)  d1 = tr.d1;
		else if (tr.dt)  d1 = ((double) tr.dt)/1000000.0;
		else {
			if (seismic) {
				d1 = 0.004;
				warn("tr.dt not set, assuming dt=0.004");
			} else { /* non-seismic data */
				d1 = 1.0;
				warn("tr.d1 not set, assuming d1=1.0");
			}
		}
	}


	if (!getparfloat("f1", &f1)) {
		if      (tr.f1)     f1 = tr.f1;
		else if (tr.delrt)  f1 = (float) tr.delrt/1000.0;
		else		f1 = 0.0;
	}

	/* Get or set ntr */
	if (getparint("n2", &ntr) || getparint("ntr", &ntr)) have_ntr = cwp_true;
	if (!getparfloat("d2", &d2)) d2 = (tr.d2) ? tr.d2 : 1.0;


	if (!getparfloat("f2", &f2)) {
		if	(tr.f2)	f2 = tr.f2;
		else if (tr.tracr)  f2 = (float) tr.tracr;
		else if (tr.tracl)  f2 = (float) tr.tracl;
		else if (seismic)   f2 = 1.0;
		else		    f2 = 0.0;
	}

	if (!getparstring("style", &style)) style = "seismic";
	 	
	if (getparstring("key", &key)) {
		type1 = hdtype(key);
		if ( (index1 = getindex(key)) == -1 )
			err("%s: keyword not in segy.h: '%s'", __FILE__, key);
		irregular = cwp_true;
		isDepth = IS_DEPTH(key);
		isCoord = IS_COORD(key);
		if (isDepth) {
		   index2 = getindex("scalel");
		   type2 = hdtype("scalel");
		} else if (isCoord) {
		   index2 = getindex("scalco");
		   type2 = hdtype("scalco");
		}
	}


	/* Look for user-supplied tmpdir */
	if (!getparstring("tmpdir",&tmpdir) &&
	    !(tmpdir = getenv("CWP_TMPDIR"))) tmpdir="";
	if (!STREQ(tmpdir, "") && access(tmpdir, WRITE_OK))
		err("you can't write in %s (or it doesn't exist)", tmpdir);

	/* See if CWPBIN environment variable is not set */
	if (!(bindir = getenv("CWPBIN"))) { /* construct bindir from CWPROOT */

		bindir = (char *) emalloc(BUFSIZ);

		/* Get value of CWPROOT environment variable */
		if (!(cwproot = getenv("CWPROOT"))) cwproot ="" ;
		if (STREQ(cwproot, "")) {
			warn("CWPROOT environment variable is not set! ");
			err("Set CWPROOT in shell environment as per instructions in CWP/SU Installation README files");
		}
		/* then bindir = $CWPROOT/bin */
		sprintf(bindir, "%s/bin", cwproot);
	}
	strcat(bindir,"/");   /* put / at the end of bindir */


	/* Allocate trace buffer */
	trbuf = ealloc1float(nt);


	if (!have_ntr || irregular ) { /* count traces */
		if (verbose) {
			if (irregular) {
				warn("trace spacing from header field %s",key);
				warn("... getting positions");

			} else {
				warn("n2 not getparred and "
				     "ntr header field not set");
				warn("....  counting traces");
			}
		}

		/* Create temporary "file" to hold data */
		if (STREQ(tmpdir,"")) {
			datafp = etmpfile();
			if (irregular) x2fp = etmpfile();
			if (verbose) warn("using tmpfile() call");
		} else { /* user-supplied tmpdir */
			char directory[BUFSIZ];
			strcpy(directory, tmpdir);
			strcpy(datafile, temporary_filename(directory));
			strcpy(x2file, temporary_filename(directory));
			/* Handle user interrupts */
			signal(SIGINT, (void (*) (int)) closefiles);
			signal(SIGQUIT, (void (*) (int)) closefiles);
			signal(SIGHUP,  (void (*) (int)) closefiles);
			signal(SIGTERM, (void (*) (int)) closefiles);
			datafp = efopen(datafile, "w+");
			if (irregular) x2fp = efopen(x2file, "w+");
			istmpdir=cwp_true;		
			if (verbose)
			      warn("putting temporary files in %s", directory);
		}

		/* Loop over input data and read to temporary file */
		ntr = 0;
		if(irregular ) {
		     float x,xmin=FLT_MAX,xmax=-FLT_MAX;

		     fprintf(x2fp,"x2=");
		     do {
			if(ntr) fprintf(x2fp,",");
			++ntr;
			gethval(&tr,index1,&val);
			if (isDepth || isCoord) {
			   gethval(&tr,index2,&scale);
			   x = (float) (vtod(type1,val) *
				 pow(10.0,vtod(type2,scale)));
			} else
			   x = vtof(type1,val);
			fprintf(x2fp,"%g",x);
			xmin = MIN(xmin,x);
			xmax = MAX(xmax,x);
			if (isDepth && STREQ(style,"vsp")) {
				int i;
				for (i = 0; i < nt; ++i) tr.data[i] *= -1.0;
			}
			efwrite(tr.data, FSIZE, nt, datafp);
		     } while (gettr(&tr));

		     /* Flip vertical axis if style = vsp */
		     if (isDepth && STREQ(style,"vsp")) {
			fprintf(x2fp," x2beg=%g x2end=%g",xmax,xmin);
			style = "normal";
		     }

		     if(xmin==xmax) {
			warn("values in header %s all equal,",key);
			warn("using f2=%f d2=%f",f2,d2);
			irregular=cwp_false;
			have_ntr=cwp_false;
			efclose(x2fp);
			if (istmpdir) eremove(x2file);
		     }

		} else {
			do {
				++ntr;
				efwrite(tr.data, FSIZE, nt, datafp);
			} while (gettr(&tr));
			/* Save naive user */
			if (STREQ(style,"vsp")) {
				style = "normal";
				warn("style=vsp requires key= to be set");
			}
		}


	}

	/* Set up pswigb command line */
	if (irregular ) {
		x2len = (off_t) eftell( x2fp );
		x2string = (char *) emalloc( ++x2len );
		rewind(x2fp);
		fread(x2string,sizeof(char),x2len,x2fp);
		plotcmd = (char *) emalloc(x2len+BUFSIZ);
		if (STREQ(style,"vsp")) {
			style = "normal";
		}
		sprintf(plotcmd, "%spswigb n1=%d d1=%f f1=%f %s style=%s", bindir,
			   nt, d1, f1, x2string, style);
		free(x2string);
	} else {
		if (STREQ(style,"vsp")) {
			style = "normal";
		}
		plotcmd = (char *) emalloc(BUFSIZ);
		sprintf(plotcmd,
			"%spswigb n1=%d n2=%d d1=%f d2=%f f1=%f f2=%f style=%s", bindir,
			   nt, ntr, d1, d2, f1, f2, style);
	}


	for (--argc, ++argv; argc; --argc, ++argv) {
		if (strncmp(*argv, "d1=", 3) && /* skip those already set */
		    strncmp(*argv, "d2=", 3) &&
		    strncmp(*argv, "f1=", 3) &&
		    strncmp(*argv, "f2=", 3) &&
		    strncmp(*argv, "style=", 6)){
		    
			strcat(plotcmd, " ");   /* put a space between args */
			strcat(plotcmd, "\"");  /* user quotes are stripped */
			strcat(plotcmd, *argv); /* add the arg */
			strcat(plotcmd, "\"");  /* user quotes are stripped */
		}
	}


	/* Open pipe to pswigb and send the traces */
	plotfp = epopen(plotcmd, "w");
	free(plotcmd);

	if (!have_ntr || irregular) { /* send out stored traces one by one */
		rewind(datafp);
		{ register int itr;
			for (itr = 0; itr < ntr; ++itr) {
				efread (trbuf, FSIZE, nt, datafp);
				efwrite(trbuf, FSIZE, nt, plotfp);
			}
		}
	} else { /* just pump out traces and let pswigb do the work */
		do {
			efwrite(tr.data, FSIZE, nt, plotfp);
		} while (gettr(&tr));
	}


	/* Clean up */
	epclose(plotfp);
	if (!have_ntr) {
		efclose(datafp);
		if (istmpdir) eremove(datafile);
	}
	if (irregular) {
		efclose(x2fp);
		if (istmpdir) eremove(x2file);
	}

	return EXIT_SUCCESS;
}
示例#4
0
int
main (int argc, char **argv)
{
	int nt;			/* number of time samples */
	int ntau;		/* number of migrated time samples */
	int nx;			/* number of midpoints 	*/
	int ik,ix,it,itau,itmig;/* loop counters 	*/
	int nxfft;		/* fft size		*/
	int nk;			/* number of wave numbers */	

	int ntmig,nvmig;	

	float dt;		/* time sampling interval 	*/
	float ft;		/* first time sample		*/
	float dtau;		/* migrated time sampling interval */
	float ftau;		/* first migrated time value 	*/
	float dk;		/* wave number sampling interval */
	float fk;		/* first wave number 		*/
	float Q, ceil;		/* quality factor, ceiling of amplitude */
	float t,k;		/* time,wave number		*/
	float *tmig, *vmig;	/* arrays of time, interval velocities */
	float dx;		/* spatial sampling interval	*/
	float *vt;		/* velocity v(t)		*/
	float **p,**q;		/* input, output data		*/

	complex **cp,**cq;	/* complex input,output		*/

	char *vfile="";		/* name of file containing velocities */
	int verbose=0;		/* flag for echoing info		*/
	char *tmpdir;		/* directory path for tmp files		*/
	cwp_Bool istmpdir=cwp_false;/* true for user-given path		*/

	/* hook up getpar to handle the parameters */
	initargs(argc,argv);
	requestdoc(1);

	/* get info from first trace */
	if (!gettr(&tr))  err("can't get first trace");
	nt = tr.ns;

	/* let user give dt and/or dx from command line */
	if (!getparfloat("dt", &dt)) {
		if (tr.dt) { /* is dt field set? */
			dt = ((double) tr.dt)/1000000.0;
		} else { /* dt not set, assume 4 ms */
			dt = 0.004;
			warn("tr.dt not set, assuming dt=0.004");
		}
	}
	if (!getparfloat("dx",&dx)) {
		if (tr.d2) { /* is d2 field set? */
			dx = tr.d2;
		} else {
			dx = 1.0;
			warn("tr.d2 not set, assuming d2=1.0");
		}
	}


	/* get optional parameters */
	if (!getparfloat("ft",&ft)) ft = 0.0;
	if (!getparint("ntau",&ntau)) ntau = nt; CHECK_NT("ntau",ntau);
	if (!getparfloat("dtau",&dtau)) dtau = dt;
	if (!getparfloat("ftau",&ftau)) ftau = ft;
	if (!getparfloat("Q",&Q)) Q = 1.0e6;
	if (!getparfloat("ceil",&ceil)) ceil = 1.0e6; 
		if (verbose)warn("Q=%f ceil=%f",Q,ceil); 

	if (!getparint("verbose", &verbose)) verbose = 0;

	/* Look for user-supplied tmpdir */
	if (!getparstring("tmpdir",&tmpdir) &&
	    !(tmpdir = getenv("CWP_TMPDIR"))) tmpdir="";
	if (!STREQ(tmpdir, "") && access(tmpdir, WRITE_OK))
		err("you can't write in %s (or it doesn't exist)", tmpdir);


	/* store traces and headers in tempfiles while getting a count */
	if (STREQ(tmpdir,"")) {
		tracefp = etmpfile();
		headerfp = etmpfile();
		if (verbose) warn("using tmpfile() call");
	} else { /* user-supplied tmpdir */
		char directory[BUFSIZ];
		strcpy(directory, tmpdir);
		strcpy(tracefile, temporary_filename(directory));
		strcpy(headerfile, temporary_filename(directory));
		/* Trap signals so can remove temp files */
		signal(SIGINT,  (void (*) (int)) closefiles);
		signal(SIGQUIT, (void (*) (int)) closefiles);
		signal(SIGHUP,  (void (*) (int)) closefiles);
		signal(SIGTERM, (void (*) (int)) closefiles);
		tracefp = efopen(tracefile, "w+");
		headerfp = efopen(headerfile, "w+");
      		istmpdir=cwp_true;		
		if (verbose) warn("putting temporary files in %s", directory);
	}

	nx = 0;
	do {
		 ++nx;
		efwrite(&tr,HDRBYTES,1,headerfp);
		efwrite(tr.data, FSIZE, nt, tracefp);
	} while (gettr(&tr));
	erewind(tracefp);
	erewind(headerfp);
	
	/* determine wavenumber sampling (for real to complex FFT) */
	nxfft = npfar(nx);
	nk = nxfft/2+1;
	dk = 2.0*PI/(nxfft*dx);
	fk = 0.0;
	
	/* allocate space */
	p = alloc2float(nt,nxfft);
	q = alloc2float(ntau,nxfft);
	cp = alloc2complex(nt,nk);
	cq = alloc2complex(ntau,nk);

	/* load traces into the zero-offset array and close tmpfile */
	efread(*p, FSIZE, nt*nx, tracefp);
	efclose(tracefp);

	/* determine velocity function v(t) */
	vt = ealloc1float(ntau);
	if (!getparstring("vfile",&vfile)) {
		ntmig = countparval("tmig");
		if (ntmig==0) ntmig = 1;
		tmig = ealloc1float(ntmig);
		if (!getparfloat("tmig",tmig)) tmig[0] = 0.0;
		nvmig = countparval("vmig");
		if (nvmig==0) nvmig = 1;
		if (nvmig!=ntmig) err("number of tmig and vmig must be equal");
		vmig = ealloc1float(nvmig);
		if (!getparfloat("vmig",vmig)) vmig[0] = 1500.0;
		for (itmig=1; itmig<ntmig; ++itmig)
			if (tmig[itmig]<=tmig[itmig-1])
				err("tmig must increase monotonically");
		for (it=0,t=0.0; it<ntau; ++it,t+=dt)
			intlin(ntmig,tmig,vmig,vmig[0],vmig[ntmig-1],
				1,&t,&vt[it]);
	} else {
		if (fread(vt,sizeof(float),nt,fopen(vfile,"r"))!=nt)
			err("cannot read %d velocities from file %s",nt,vfile);
	}
	
        checkpars();

	/* pad with zeros and Fourier transform x to k */
	for (ix=nx; ix<nxfft; ix++)
		for (it=0; it<nt; it++)
			p[ix][it] = 0.0;
	pfa2rc(-1,2,nt,nxfft,p[0],cp[0]);
	
	/* migrate each wavenumber */
	for (ik=0,k=fk; ik<nk; ik++,k+=dk)
		gazdagvt(k,nt,dt,ft,ntau,dtau,ftau,vt,cp[ik],cq[ik], Q, ceil);
	
	/* Fourier transform k to x (including FFT scaling) */
	pfa2cr(1,2,ntau,nxfft,cq[0],q[0]);
	for (ix=0; ix<nx; ix++)
		for (itau=0; itau<ntau; itau++)
			q[ix][itau] /= nxfft;

	/* restore header fields and write output */
	for (ix=0; ix<nx; ++ix) {
		efread(&tr,HDRBYTES,1,headerfp);
		tr.ns = ntau ;
		tr.dt = dtau * 1000000.0 ;
		tr.delrt = ftau * 1000.0 ;
		memcpy( (void *) tr.data, (const void *) q[ix],ntau*FSIZE);
		puttr(&tr);
	}
	
	/* Clean up */
	efclose(headerfp);
	if (istmpdir) eremove(headerfile);
	if (istmpdir) eremove(tracefile);

	return(CWP_Exit());	
}
示例#5
0
int
main(int argc, char **argv)
{
   char *tmpdir ;                 /* directory path for tmp files */
   cwp_Bool istmpdir=cwp_false ;  /* true for user given path */
   float *hedr ;                  /* the headers */
   float *data ;                  /* the data */

   int nt ;                       /* number of trace samples */
   float dt ;                     /* sample interval, sec */
   float delrt ;                  /* delay recording time, sec */
   cwp_String key[SU_NKEYS] ;     /* array of keywords */
   cwp_String type ;              /* key string type */
   int nkeys ;                    /* number of keywords */
   int ikey,ntr = 0 ;	          /* counters */
   int num ;                      /* number of traces to dump */
   int numtr = 4 ;                /* number of traces to dump */
   int hpf ;                      /* header print format */

   /* Initialize */
   initargs(argc, argv) ;
   requestdoc(1) ;

   /* Look for user-supplied tmpdir */
   if (!getparstring("tmpdir",&tmpdir) &&
       !(tmpdir = getenv("CWP_TMPDIR"))) tmpdir="";
   if (!STREQ(tmpdir, "") && access(tmpdir, WRITE_OK))
       err("you can't write in %s (or it doesn't exist)", tmpdir);

   /* Get values from first trace */
   if (!gettr(&tr)) err("can't get first trace");
   nt = (int) tr.ns ;                  /* Get nt */
   dt = ((double) tr.dt)/1000000.0 ;   /* microsecs to secs */
   if (!dt) getparfloat("dt", &dt) ;
   if (!dt) MUSTGETPARFLOAT("dt", &dt) ;
   delrt = ((double) tr.delrt)/1000.0 ; /* millisecs to secs */

   /* Get parameters */
   if (getparint ("num", &num)) numtr = num ;
   if ((nkeys=countparval("key"))!=0) getparstringarray("key",key) ;
   hedr = ealloc1float(nkeys*numtr) ;  /* make space for headers */
   if (!getparint ("hpf", &hpf)) hpf = 0 ;

   /* Store traces, headers in tempfiles */
   if (STREQ(tmpdir,""))
   {
      tracefp = etmpfile();
      headerfp = etmpfile();

      do
      {
         ++ntr;
         efwrite(&tr, HDRBYTES, 1, headerfp);
         efwrite(tr.data, FSIZE, nt, tracefp);

         /* Get header values */
         for (ikey=0; ikey<nkeys; ++ikey)
         {
            Value val;
            float fval;

            gethdval(&tr, key[ikey], &val) ;
            type = hdtype(key[ikey]) ;
            fval = vtof(type,val) ;
            hedr[(ntr-1)*nkeys+ikey] = fval ;
         }

      }
      while (ntr<numtr  &&  gettr(&tr)) ;

   }
   else  /* user-supplied tmpdir */
   {
      char directory[BUFSIZ];
      strcpy(directory, tmpdir);
      strcpy(tracefile, temporary_filename(directory));
      strcpy(headerfile, temporary_filename(directory));
      /* Handle user interrupts */
      signal(SIGINT, (void (*) (int)) closefiles);
      signal(SIGQUIT, (void (*) (int)) closefiles);
      signal(SIGHUP,  (void (*) (int)) closefiles);
      signal(SIGTERM, (void (*) (int)) closefiles);
      tracefp = efopen(tracefile, "w+");
      headerfp = efopen(headerfile, "w+");
      istmpdir=cwp_true;      

      do
      {
         ++ntr;
         efwrite(&tr, HDRBYTES, 1, headerfp);
         efwrite(tr.data, FSIZE, nt, tracefp);

         /* Get header values */
         for (ikey=0; ikey<nkeys; ++ikey)
         {
            Value val;
            float fval;

            gethdval(&tr, key[ikey], &val) ;
            type = hdtype(key[ikey]) ;
            fval = vtof(type,val) ;
            hedr[(ntr-1)*nkeys+ikey] = fval ;
         }

      }
      while (ntr<numtr  &&  gettr(&tr)) ;

   }

   /* Rewind after read, allocate space */
   erewind(tracefp);
   erewind(headerfp);
   data = ealloc1float(nt*ntr);

   /* Load traces into data and close tmpfile */
   efread(data, FSIZE, nt*ntr, tracefp);
   efclose(tracefp);
   if (istmpdir) eremove(tracefile);

   rewind(headerfp);
   rewind(tracefp);

   /* Do trace work */
   dump(data, dt, hedr, key, delrt, nkeys, ntr, nt, hpf) ;

   /* close */
   efclose(headerfp);
   if (istmpdir) eremove(headerfile);

   free1(hedr) ;
   free1(data) ;

   return(CWP_Exit()) ;
}
示例#6
0
int
main(int argc, char **argv)
{
	char plotcmd[BUFSIZ];	/* build psmovie command for popen 	*/
	float *trbuf;		/* trace buffer			 	*/
	FILE *plotfp;		/* fp for plot data			*/
	int nt;			/* number of samples on trace		*/
	int n2;			/* number of traces per frame		*/
	int n3;			/* number of frames in data		*/
	int ntr;		/* number of traces			*/
	int verbose;		/* verbose flag				*/
	float d1;		/* time/depth sample rate 		*/
	float d2;		/* trace/dx sample rate 		*/
	float f1;		/* tmin/zmin				*/
	float f2;		/* tracemin/xmin	 		*/
	cwp_Bool seismic;	/* is this seismic data?		*/
	cwp_Bool have_n2 = cwp_false;/* was n2 getparred?			*/
	cwp_Bool have_n3 = cwp_false;/* was n3 getparred?			*/
	cwp_Bool have_ntr = cwp_false;/* was ntr set in header?		*/
	char *tmpdir;		/* directory path for tmp files		*/
	cwp_Bool istmpdir=cwp_false;/* true for user given path		*/

	char *cwproot;		/* value of CWPROOT environment variable*/
	char *bindir;		/* directory path for tmp files		*/

	/* Initialize */
	initargs(argc, argv);
	requestdoc(1);
	

	/* Get info from first trace */
	if (!gettr(&tr)) err("can't get first trace");
	seismic = ISSEISMIC(tr.trid); 
	nt = tr.ns;
	ntr = tr.ntr;
	if (ntr) have_ntr = cwp_true; 

	if (!getparint("verbose", &verbose))	verbose=0;

	if (!getparfloat("d1", &d1)) {
		if      (tr.d1)  d1 = tr.d1;
		else if (tr.dt)  d1 = ((double) tr.dt)/1000000.0;
		else {
			if (seismic) {
				d1 = 0.004;
				warn("tr.dt not set, assuming dt=0.004");
			} else { /* non-seismic data */
				d1 = 1.0;
				warn("tr.d1 not set, assuming d1=1.0");
			}
		}
	}

	if (!getparfloat("d2", &d2)) d2 = (tr.d2) ? tr.d2 : 1.0;

	if (!getparfloat("f1", &f1)) {
		if      (tr.f1)     f1 = tr.f1;
		else if (tr.delrt)  f1 = (float) tr.delrt/1000.0;
		else                f1 = 0.0;
	}

	if (!getparfloat("f2", &f2)) {
		if      (tr.f2)     f2 = tr.f2;
		else if (tr.tracr)  f2 = (float) tr.tracr;
		else if (tr.tracl)  f2 = (float) tr.tracl;
		else if (seismic)   f2 = 1.0;
		else 		    f2 = 0.0;
	}

	if (!getparfloat("f2", &f2)) f2 = 1.0;

	/* Look for user-supplied tmpdir */
	if (!getparstring("tmpdir",&tmpdir) &&
	    !(tmpdir = getenv("CWP_TMPDIR"))) tmpdir="";
	if (!STREQ(tmpdir, "") && access(tmpdir, WRITE_OK))
		err("you can't write in %s (or it doesn't exist)", tmpdir);

	/* See if CWPBIN environment variable is not set */
	if (!(bindir = getenv("CWPBIN"))) { /* construct bindir from CWPROOT */

		bindir = (char *) emalloc(BUFSIZ);

		/* Get value of CWPROOT environment variable */
		if (!(cwproot = getenv("CWPROOT"))) cwproot ="" ;
		if (STREQ(cwproot, "")) {
			warn("CWPROOT environment variable is not set! ");
			err("Set CWPROOT in shell environment as per instructions in CWP/SU Installation README files");
		}
		/* then bindir = $CWPROOT/bin */
		sprintf(bindir, "%s/bin", cwproot);
	}
	strcat(bindir,"/");   /* put / at the end of bindir */

	/* Allocate trace buffer */
	trbuf = ealloc1float(nt);

	/* Get or set n2 and n3 */
	if (getparint("n2", &n2)) have_n2 = cwp_true;
	if (getparint("n3", &n3)) have_n3 = cwp_true;
	if (have_n2 && have_n3) have_ntr = cwp_true;

	if (!have_ntr) { /* count traces */
		if (verbose) {
		   warn("n2 or n3 not getparred, or ntr header field not set");
		   warn("         ... counting traces");
		}

		/* Create temporary "file" to hold data */
		if (STREQ(tmpdir,"")) {
			tracefp = etmpfile();
			if (verbose) warn("using tmpfile() call");
		} else { /* user-supplied tmpdir */
			char directory[BUFSIZ];
			strcpy(directory, tmpdir);
			strcpy(tracefile, temporary_filename(directory));
			/* Handle user interrupts */
			signal(SIGINT, (void (*) (int)) closefiles);
			signal(SIGTERM, (void (*) (int)) closefiles);
			tracefp = efopen(tracefile, "w+");
			istmpdir=cwp_true;		
			if (verbose)
			      warn("putting temporary files in %s", directory);
		}

       
		/* Loop over input frames & put them into the data file */
		ntr = 0;
		do {
			++ntr;
			efwrite(tr.data, FSIZE, nt, tracefp);
		} while (gettr(&tr));

	} 

	/* Set dimensions of movie */
	if (!have_n2 && !have_n3) { n2 = ntr; n3=1; } 
	if (have_n2 && !have_n3) n3 = ntr/n2;
	if (!have_n2 && have_n3) n2 = ntr/n3;

	/* Set up psmovie command line */
	sprintf(plotcmd,
		"%spsmovie n1=%d n2=%d n3=%d d1=%f d2=%f f1=%f f2=%f", bindir,
			   nt, n2, n3, d1, d2, f1, f2);

	fprintf(stderr, "%s\n", plotcmd);

	for (--argc, ++argv; argc; --argc, ++argv) {
		if (strncmp(*argv, "d1=", 3) && /* skip those already set */
		    strncmp(*argv, "d2=", 3) &&
		    strncmp(*argv, "f1=", 3) &&
		    strncmp(*argv, "f2=", 3)) {
		    
			strcat(plotcmd, " ");   /* put a space between args */
			strcat(plotcmd, "\"");  /* user quotes are stripped */
			strcat(plotcmd, *argv); /* add the arg */
			strcat(plotcmd, "\"");  /* user quotes are stripped */
		}
	}


	/* Open pipe to psmovie and send the traces */
	plotfp = epopen(plotcmd, "w");
	
	if (!have_ntr){
			/* send out stored traces one by one */
		rewind(tracefp);
		{ register int itr;
			for (itr = 0; itr < ntr; ++itr) {
				efread (trbuf, FSIZE, nt, tracefp);
				efwrite(trbuf, FSIZE, nt, plotfp);
			}
		}
	} else { /* just pump out traces and let psmovie do the work */
		do {
			efwrite(tr.data, FSIZE, nt, plotfp);
		} while (gettr(&tr));
	}


	/* Clean up */
	epclose(plotfp);
	if (!have_ntr) {
		efclose(tracefp);
		if (istmpdir) eremove(tracefile);
	} 


	return EXIT_SUCCESS;
}
示例#7
0
int
main(int argc, char **argv)
{
	int nt;		/* number of time samples per trace */
	float dt;	/* time sampling interval */
	float ft;	/* time of first sample */
	int it;		/* time sample index */
	int cdpmin;	/* minimum cdp to process */
	int cdpmax;	/* maximum cdp to process */
	float dxcdp;	/* cdp sampling interval */
	int noffmix;	/* number of offsets to mix */
	float offmax;	/* maximum offset */
	float tmute;	/* mute time at far offset */
	float vrms;	/* rms velocity at mute time */
	int nsmax;	/* maximum number of time shifts per trace in DMO */
	int ns;		/* actual number of time shifts per trace in DMO */
	float *p;	/* input trace */
	float **q;	/* output DMO-corrected traces */
	float *temp;	/* temporary array */
	float *ts;	/* table of time shifts for DMO */
	float *as;	/* table of amplitudes for DMO */
	float offset=0.0;/* source-receiver offset of current trace */
	float oldoffset;/* offset of previous trace */
	int cdp=0;	/* cdp number of current trace */
	int ncdp;	/* number of cdps */
	int icdp;	/* cdp index */
	int jcdp;	/* cdp index */
	int jcdplo;	/* lower bound for jcdp */
	int jcdphi;	/* upper bound for jcdp */
	int ntrace;	/* number of traces processed in current mix */
	int itrace;	/* trace index */
	int noff;	/* number of offsets processed in current mix */
	int gottrace;	/* non-zero if an input trace was read */
	int done;	/* non-zero if done */
	float *ds;	/* shaping filter to complete DMO processing */
	int lds=125;	/* length of shaping filter */
	int ifds=-100;	/* time index of first sample in shaping filter */
	int verbose;	/* =1 for diagnostic print */
	char *tmpdir;	/* directory path for tmp files	*/
	cwp_Bool istmpdir=cwp_false;/* true for user given path */

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

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

	/* get parameters */
	if (!getparint("cdpmin",&cdpmin)) err("must specify cdpmin");
	if (!getparint("cdpmax",&cdpmax)) err("must specify cdpmax");
	if (cdpmin>cdpmax) err("cdpmin must be less than cdpmax");
	if (!getparfloat("dxcdp",&dxcdp)) err("must specify dxcdp");
	if (!getparint("noffmix",&noffmix)) err("must specify noffmix");
	if (!getparfloat("offmax",&offmax)) offmax=3000.0;
	if (!getparfloat("tmute",&tmute)) tmute=2.0;
	if (!getparfloat("vrms",&vrms)) vrms=1500.0;
	if (!getparint("nsmax",&nsmax)) nsmax=400;
	if (!getparint("verbose",&verbose)) verbose=0;

	/* Look for user-supplied tmpdir */
	if (!getparstring("tmpdir",&tmpdir) &&
	    !(tmpdir = getenv("CWP_TMPDIR"))) tmpdir="";
	if (!STREQ(tmpdir, "") && access(tmpdir, WRITE_OK))
		err("you can't write in %s (or it doesn't exist)", tmpdir);
	
        checkpars();

	/* determine number of cdps */
	ncdp = cdpmax-cdpmin+1;

	/* allocate workspace */
	q = ealloc2float(nt,ncdp);
	p = ealloc1float(nt);
	temp = ealloc1float(nt);
	ts = ealloc1float(nsmax);
	as = ealloc1float(nsmax);
	ds = ealloc1float(lds);
	
	/* tabulate time shifts and amplitudes for dmo */
	maketa(dxcdp,dt,offmax,tmute,vrms,nsmax,&ns,ts,as);
	if (verbose) 
		fprintf(stderr,"\tDMO will be performed via %d time shifts\n",
			ns);
	
	/* compute shaping filter for dmo horizontal reflection response */
	makeds(ns,ts,as,lds,ifds,ds);
	
	/* open temporary file for headers */
	if (STREQ(tmpdir,"")) {
		headerfp = etmpfile();
		if (verbose) warn("using tmpfile() call");
	} else { /* user-supplied tmpdir */
		char directory[BUFSIZ];
		strcpy(directory, tmpdir);
		strcpy(headerfile, temporary_filename(directory));
		/* Trap signals so can remove temp files */
		signal(SIGINT,  (void (*) (int)) closefiles);
		signal(SIGQUIT, (void (*) (int)) closefiles);
		signal(SIGHUP,  (void (*) (int)) closefiles);
		signal(SIGTERM, (void (*) (int)) closefiles);
		headerfp = efopen(headerfile, "w+");
      		istmpdir=cwp_true;		
		if (verbose)
			warn("putting temporary header file in %s", directory);
	}
	
	/* initialize */
	oldoffset = tr.offset;
	gottrace = 1;
	done = 0;
	ntrace = 0;
	noff = 0;
	for (icdp=0; icdp<ncdp; ++icdp)
		for (it=0; it<nt; ++it)
			q[icdp][it] = 0.0;

	/* loop over traces */
	do {
		
		/* if got a trace */
		if (gottrace) {

			/* determine offset and cdp */
			offset = tr.offset;
			cdp = tr.cdp;
		
			/* update number of offsets mixed */
			if (offset!=oldoffset) noff++;

			/* get trace samples */
 			memcpy( (void *) p,
				  (const void *) tr.data, nt*sizeof(float));
		}
		
		/* if a mix of offsets is complete */
		if (noff==noffmix || !gottrace) {
			
			/* update number of offsets mixed */
			if (!gottrace) noff++; 
			
			/* apply shaping filter to complete dmo processing */
			for (icdp=0; icdp<ncdp; ++icdp) {
				convolve_cwp(lds,ifds,ds,nt,0,q[icdp],nt,0,temp);
				memcpy( (void *) q[icdp],
					(const void *) temp, nt*sizeof(float));
			}
			
			/* rewind trace header file */
			erewind(headerfp);
			
			/* loop over all output traces */
			for (itrace=0; itrace<ntrace; ++itrace) {
			
				/* read trace header and determine cdp index */
				efread(&tro,HDRBYTES,1,headerfp);
				icdp = tro.cdp-cdpmin;
				
				/* get dmo-corrected data */
				memcpy((void *) tro.data,
				      (const void *) q[icdp],nt*sizeof(float));
				
				/* write output trace */
				puttr(&tro);
			}
			
			/* report */
			if (verbose) 
				fprintf(stderr,"\tCompleted mix of "
					"%d offsets with %d traces\n",
					noff,ntrace);
			
			/* if no more traces, break */
			if (!gottrace) break;
			
			/* rewind trace header file */
			erewind(headerfp);
			
			/* reset number of offsets and traces */
			noff = 0;
			ntrace = 0;
			
			/* zero dmo accumulators */
			for (icdp=0; icdp<ncdp; ++icdp)
				for (it=0; it<nt; ++it)
					q[icdp][it] = 0.0;
		}
				
		/* if cdp is within range of cdps to process */
		if (cdp>=cdpmin && cdp<=cdpmax) {
		
			/* save trace header and update number of traces */
			efwrite(&tr,HDRBYTES,1,headerfp);
			ntrace++;
			
			/* determine output traces potentially modified
			   by input */
			icdp = cdp-cdpmin;
			jcdplo = MAX(0,icdp-0.5*ABS(offset/dxcdp));
			jcdphi = MIN(ncdp-1,icdp+0.5*ABS(offset/dxcdp));
			
			/* loop over potentially modified output traces */
			for (jcdp=jcdplo; jcdp<=jcdphi; ++jcdp) {
		
				/* do dmo for one output trace */
				dmotx(ns,ts,as,offset,(jcdp-icdp)*dxcdp,dxcdp,
				      0,nt,dt,ft,p,q[jcdp]);
			}

			/* remember offset */
			oldoffset = offset;
		}

		/* get next trace (if there is one) */
		if (!gettr(&tr)) gottrace = 0;
		
	} while (!done);

	/* clean up */
	efclose(headerfp);
	if (istmpdir) eremove(headerfile);
	return(CWP_Exit());
}
示例#8
0
int
main(int argc, char **argv)
{
	char plotcmd[BUFSIZ];	/* build command for popen		*/
	FILE *plotfp;		/* fp for plot data			*/
	float d1;		/* time/depth sample rate 		*/
	float d2;		/* trace/dx sample rate 		*/
	float f1;		/* tmin/zmin				*/
	float f2;		/* tracemin/xmin			*/
	int nt;			/* number of samples on trace		*/
	int ntr;		/* number of traces			*/
	int verbose;		/* verbose flag				*/
	cwp_Bool seismic;	/* is this seismic data?		*/
	cwp_Bool have_ntr=cwp_false;/* is ntr known from header or user?	*/
	cwp_String mode;	/* sumax mode parameter			*/
	char *tmpdir;		/* directory path for tmp files		*/
	cwp_Bool istmpdir=cwp_false;/* true for user given path		*/

	char *cwproot;		/* value of CWPROOT environment variable*/
	char *bindir;		/* directory path for tmp files		*/

	/* Initialize */
	initargs(argc, argv);
	requestdoc(1);
	
	/* Get info from first trace */
	if (!gettr(&tr)) err("can't get first trace");
	seismic = ISSEISMIC(tr.trid); 
	nt = tr.ns;
	ntr = tr.ntr;
	if (ntr) have_ntr = cwp_true; 

	if (!getparint("verbose", &verbose))	verbose=0;
	if (!getparfloat("d1", &d1)) {
		if      (tr.d1)  d1 = tr.d1;
		else if (tr.dt)  d1 = ((double) tr.dt)/1000000.0;
		else {
			if (seismic) {
				d1 = 0.004;
				warn("tr.dt not set, assuming dt=0.004");
			} else { /* non-seismic data */
				d1 = 1.0;
				warn("tr.d1 not set, assuming d1=1.0");
			}
		}
	}

	if (!getparfloat("d2", &d2)) d2 = (tr.d2) ? tr.d2 : 1.0;

	if (!getparfloat("f1", &f1)) {
		if      (tr.f1)     f1 = tr.f1;
		else if (tr.delrt)  f1 = (float) tr.delrt/1000.0;
		else                f1 = 0.0;
	}

	if (!getparfloat("f2", &f2)) {
		if      (tr.f2)     f2 = tr.f2;
		else if (tr.tracr)  f2 = (float) tr.tracr;
		else if (tr.tracl)  f2 = (float) tr.tracl;
		else if (seismic)   f2 = 1.0;
		else 		    f2 = 0.0;
	}
	
	if (getparint("n2", &ntr) || getparint("ntr", &ntr)) have_ntr = cwp_true;
	if (!getparstring("mode", &mode)) mode = "max";

	/* Look for user-supplied tmpdir */
	if (!getparstring("tmpdir",&tmpdir) &&
	    !(tmpdir = getenv("CWP_TMPDIR"))) tmpdir="";
	if (!STREQ(tmpdir, "") && access(tmpdir, WRITE_OK))
		err("you can't write in %s (or it doesn't exist)", tmpdir);

	/* See if CWPBIN environment variable is not set */
	if (!(bindir = getenv("CWPBIN"))) { /* construct bindir from CWPROOT */

		bindir = (char *) emalloc(BUFSIZ);

		/* Get value of CWPROOT environment variable */
		if (!(cwproot = getenv("CWPROOT"))) cwproot ="" ;
		if (STREQ(cwproot, "")) {
			warn("CWPROOT environment variable is not set! ");
			err("Set CWPROOT in shell environment as per instructions in CWP/SU Installation README files");
		}
		/* then bindir = $CWPROOT/bin */
		sprintf(bindir, "%s/bin", cwproot);
	}
	strcat(bindir,"/");   /* put / at the end of bindir */


	/* Allocate trace buffer */
	if (!have_ntr) {
		/* Store traces and headers in tmpfile while getting a count */
		if (verbose) {
			warn(" n2 not getparred or header field ntr not set");
			warn(" ....    counting traces");
		}

		/* Store traces and headers in tmpfile while getting a count */
		if (STREQ(tmpdir,"")) {
			tracefp = etmpfile();
			headerfp = etmpfile();
			if (verbose) warn("using tmpfile() call");
		} else { /* user-supplied tmpdir */
			char directory[BUFSIZ];
			strcpy(directory, tmpdir);
			strcpy(tracefile, temporary_filename(directory));
			strcpy(headerfile, temporary_filename(directory));
			/* Trap signals so can remove temp files */
			signal(SIGINT,  (void (*) (int)) closefiles);
			signal(SIGQUIT, (void (*) (int)) closefiles);
			signal(SIGHUP,  (void (*) (int)) closefiles);
			signal(SIGTERM, (void (*) (int)) closefiles);
			tracefp = efopen(tracefile, "w+");
			headerfp = efopen(headerfile, "w+");
			istmpdir=cwp_true;		
			if (verbose)
			     warn("putting temporary files in %s", directory);
		}

		/* Loop over input data and read to temporary file */
		ntr = 0;
		do {
			   ++ntr;
			   efwrite(&tr, 1, HDRBYTES, headerfp);
			   efwrite(tr.data, FSIZE, nt, tracefp);
		   } while (gettr(&tr));

	}

	/* System call to xgraph */
	sprintf(plotcmd, "%ssumax output=binary mode=%s | %sxgraph n=%d", 
			 bindir, mode, bindir, ntr);
	for (--argc, ++argv; argc; --argc, ++argv) {
		if ( 
			strncmp(*argv, "output=", 7)  &&
			strncmp(*argv, "mode=", 5)  &&
			strncmp(*argv, "n=", 2) &&
			strncmp(*argv, "n2=", 3) &&/*xgraph honors n2,nplot*/
			strncmp(*argv, "nplot=", 6) ) { 

			strcat(plotcmd, " ");   /* put a space between args */
			strcat(plotcmd, "\"");  /* user quotes are stripped */
			strcat(plotcmd, *argv); /* add the arg */
			strcat(plotcmd, "\"");  /* user quotes are stripped */
		}
	}


	/* Open pipe; write data to plotcmd */
	plotfp = epopen(plotcmd, "w");
	
	if (!have_ntr) {
		rewind(headerfp);
		rewind(tracefp);
		{ register int itr;
		for (itr = 0; itr < ntr; ++itr) {
			efread(&tr, 1, HDRBYTES, headerfp);
			efread(tr.data, FSIZE, nt, tracefp);
			fputtr(plotfp, &tr);
		}
		}
	} else { /* pump out traces and let sumax and psimage do the work */
                do {
                        fputtr(plotfp,&tr);
                } while (gettr(&tr));
        }


	/* Clean up */
	epclose(plotfp);
	efclose(headerfp);
	if (istmpdir) eremove(headerfile);
	if (!have_ntr) {
		efclose(tracefp);
		if (istmpdir) eremove(tracefile);
	}

	return EXIT_SUCCESS;
}
示例#9
0
int
main(int argc, char **argv)
{
	int nt;		/* number of time samples			*/
	float dt;	/* time sampling interval			*/
	int ntr;	/* number of traces				*/
	float dx;	/* trace spacing (spatial sampling interval)	*/
	int nslopes;	/* number of slopes specified			*/
	float *slopes;	/* slopes at which amplitudes are specified	*/
	int namps;	/* number of amplitudes specified		*/
	float *amps;	/* amplitudes corresponding to slopes		*/
	float bias;	/* slope bias					*/
	int verbose;	/* flag for echoing info			*/
	char *tmpdir;	/* directory path for tmp files			*/
	cwp_Bool istmpdir=cwp_false;/* true for user-given path		*/


	/* Hook up getpar to handle the parameters */
	initargs(argc,argv);
	requestdoc(1);


	/* Get info from first trace */ 
	if (!gettr(&tr))  err("can't get first trace");
	nt = tr.ns;


	/* Get parameters */
	if (!getparint("verbose", &verbose))	verbose = 0;

	/* Look for user-supplied tmpdir */
	if (!getparstring("tmpdir",&tmpdir) &&
	    !(tmpdir = getenv("CWP_TMPDIR"))) tmpdir="";
	if (!STREQ(tmpdir, "") && access(tmpdir, WRITE_OK))
		err("you can't write in %s (or it doesn't exist)", tmpdir);

	if (!getparfloat("dt", &dt))	dt = ((double) tr.dt)/1000000.0;
	if (!dt) err("dt field is zero and not getparred");
	if (!getparfloat("dx", &dx) && !getparfloat("d2", &dx))	dx = tr.d2;
	if (!dx) err("d2 field is zero and dx not getparred");

	nslopes = countparval("slopes");
	if (nslopes) {
		slopes = alloc1float(nslopes);
		getparfloat("slopes", slopes);
	} else {
		nslopes = 1;
		slopes = alloc1float(nslopes);
		slopes[0] = 0.0;
	}

	namps = countparval("amps");
	if (namps) {
		amps = alloc1float(namps);
		getparfloat("amps", amps);
	} else {
		namps = 1;
		amps = alloc1float(namps);
		amps[0] = 1.0;
		warn("no amps given--doing no-op");
	}

	if (!getparfloat("bias", &bias)) bias = 0.0;


	/* Check parameters */
	if (nslopes != namps)
		err("number of slopes (%d) must equal number of amps(%d)",
			nslopes, namps);
	{ register int i;
	  for (i=1; i<nslopes; ++i)
		if (slopes[i] <= slopes[i-1])
			err("slopes must be monotonically increasing");
	}


	/* Store traces and headers in tmpfile while getting a count */
	if (STREQ(tmpdir,"")) {
		tracefp = etmpfile();
		headerfp = etmpfile();
		if (verbose) warn("using tmpfile() call");
	} else { /* user-supplied tmpdir */
		char directory[BUFSIZ];
		strcpy(directory, tmpdir);
		strcpy(tracefile, temporary_filename(directory));
		strcpy(headerfile, temporary_filename(directory));
		/* Trap signals so can remove temp files */
		signal(SIGINT,  (void (*) (int)) closefiles);
		signal(SIGQUIT, (void (*) (int)) closefiles);
		signal(SIGHUP,  (void (*) (int)) closefiles);
		signal(SIGTERM, (void (*) (int)) closefiles);
		tracefp = efopen(tracefile, "w+");
		headerfp = efopen(headerfile, "w+");
      		istmpdir=cwp_true;		
		if (verbose) warn("putting temporary files in %s", directory);
	}

	ntr = 0;
	do { 
		++ntr;
		efwrite(&tr, 1, HDRBYTES, headerfp);
		efwrite(tr.data, FSIZE, nt, tracefp);
	} while (gettr(&tr));
	

	/* Apply slope filter */
	slopefilter(nslopes,slopes,amps,bias,nt,dt,ntr,dx,tracefp);


	/* Output filtered traces */
	erewind(headerfp);
	erewind(tracefp);
	{ register int itr;
	  for (itr = 0; itr < ntr; ++itr) {
		efread(&tr, 1, HDRBYTES, headerfp);
		efread(tr.data, FSIZE, nt, tracefp);
		puttr(&tr);
	  }
	}


	/* Clean up */
	efclose(headerfp);
	if (istmpdir) eremove(headerfile);
	efclose(tracefp);
	if (istmpdir) eremove(tracefile);
	free1float(slopes);
	free1float(amps);

	return(CWP_Exit());
}
示例#10
0
int
main(int argc, char **argv)
{
	int ix,it;		/* loop counters */
	int i,j,k;
	int ntr;		/* number of input traces */
	int nt;			/* number of time samples */
	int nx;			/* number of horizontal samples */
	float dt;               /* Time sample interval */
        float dx=1;               /* horizontal sample interval */
        float pminf;             /* Minimum slope for Tau-P transform */
        float pmaxf;             /* Maximum slope for Tau-P transform */
	float dpf;		/* slope sampling interval */
	int np;			/* number of slopes for slant stack */
	int nwin;		/* spatial window length */
	int npoints;		/* number of points for rho filter */
	float **twin;		/* array[nwin][nt] of window traces */	
	float **pwin;		/* array[np][nt] of sl traces */
	int ntrw;		/* number of traces in processing window */
				/* full multiple of nwin */	
	int ist;		/* start processing from this window */
	int ntfft;
	float **traces;
	int w;			/* flag to apply semblance weights */
	int s;			/* flag to apply smoothing weights */
	int sl1;		/* length of smoothing window */
	int sl2;		/* length of smoothing window */
	float *smb;		/* semblance weights */
	double pw;
	float smbwin;
	int sn;
	float *spw;		/* array of spatial weights */
	float **out_traces;	/* array[nx][nt] of output traces */	
	int verbose;		/* flag for echoing information */
	char *tmpdir;		/* directory path for tmp files */
	cwp_Bool istmpdir=cwp_false;/* true for user-given path */
	float fh1;		/* maximum frequency before taper */
	float fh2;		/* maximum frequency */
	float prw;		/* prewithening */
	
	
        /* hook up getpar to handle the parameters */
        initargs(argc,argv);
        requestdoc(1);

	if (!getparint("verbose", &verbose))	verbose = 0;

	/* Look for user-supplied tmpdir */
	if (!getparstring("tmpdir",&tmpdir) &&
	    !(tmpdir = getenv("CWP_TMPDIR"))) tmpdir="";
	if (!STREQ(tmpdir, "") && access(tmpdir, WRITE_OK))
		err("you can't write in %s (or it doesn't exist)", tmpdir);

        /* get info from first trace */
        if (!gettr(&tr))  err("can't get first trace");
        nt = tr.ns;
        dt = (float) tr.dt/1000000.0;

        /* Store traces in tmpfile while getting a count */
	if (STREQ(tmpdir,"")) {
		tracefp = etmpfile();
		headerfp = etmpfile();
		if (verbose) warn("using tmpfile() call");
	} else { /* user-supplied tmpdir */
		char directory[BUFSIZ];
		strcpy(directory, tmpdir);
		strcpy(tracefile, temporary_filename(directory));
		strcpy(headerfile, temporary_filename(directory));
		/* Trap signals so can remove temp files */
		signal(SIGINT,  (void (*) (int)) closefiles);
		signal(SIGQUIT, (void (*) (int)) closefiles);
		signal(SIGHUP,  (void (*) (int)) closefiles);
		signal(SIGTERM, (void (*) (int)) closefiles);
		tracefp = efopen(tracefile, "w+");
		headerfp = efopen(headerfile, "w+");
      		istmpdir=cwp_true;		
		if (verbose) warn("putting temporary files in %s", directory);
	}
        ntr = 0;
        do {
                ++ntr;
                efwrite(&tr, 1, HDRBYTES, headerfp);
                efwrite(tr.data, FSIZE, nt, tracefp);
        } while (gettr(&tr));

        /* get general flags and parameters and set defaults */
        if (!getparint("np",&np))             	np = 25;
        if (!getparfloat("pminf",&pminf))	pminf = -0.01;
        if (!getparfloat("pmaxf",&pmaxf))	pmaxf = 0.01;
        if (!getparfloat("fh1",&fh1))		fh1 = 100;
        if (!getparfloat("fh2",&fh2))		fh2 = 120;
        if (!getparfloat("prw",&prw))		prw = 0.01;
	if (!getparfloat("dx",&dx))		dx = 1.0;
	if (!getparint("npoints",&npoints))	npoints = 71;
	if (!getparint("nwin",&nwin))		nwin= 5;
	if (!getparfloat("dt",&dt))		dt = dt;
	if (!getparfloat("smbwin",&smbwin))	smbwin = 0.05;
	if (!getpardouble("pw",&pw))		pw = 1.0;
	if (!getparint("w",&w))			w = 0;
	if (!getparint("s",&s))			s = 0;
	if (!getparint("sl1",&sl1))		sl1 = 2*nwin;
	if (!getparint("sl2",&sl2))		sl2 = nwin;
	
        nx = ntr;
	if (dt == 0.0)
		err("header field dt not set, must be getparred");

	/* allocate space */
	ntfft=npfar(nt);
	ntrw=nwin;
	while (ntrw < ntr) {
		ntrw+=nwin;
	}
	ist = ntrw-ntr/2;
	twin = alloc2float(nt, nwin);
	pwin = ealloc2float(ntfft,np);
        traces = alloc2float(nt, ntr);
        out_traces = alloc2float(nt, ntr);
	smb = ealloc1float(nt);
	
	/* Set up some constans*/
	dpf=(pmaxf-pminf)/(np-1);
	sn = (int)(smbwin/dt+0.5);
	if(sn%2==0) sn++;
	if(nwin%2==0) nwin++;
	
	/* spatial trace weigths */
	spw = ealloc1float(nwin);
	for(k=0,i=1;k<nwin/2+1;k++,i++) spw[k] = (float)i; 
	for(k=nwin/2+1,i=nwin/2;k<nwin;k++,i--) spw[k] = (float)i; 
/*	for(k=0,i=1;k<nwin;k++,i++) spw[k] =1.0; */
	
	
	
        /* load traces into an array and close temp file */
	erewind(headerfp);
        erewind(tracefp);
	
	memset( (void *) traces[0], (int) '\0', (nt*ntr)*FSIZE);
	memset( (void *) out_traces[0], (int) '\0', (nt*ntr)*FSIZE);
	
        for (ix=0; ix<ntr; ix++)
                fread (traces[ix], FSIZE, nt, tracefp);
        efclose (tracefp);
	if (istmpdir) eremove(tracefile);

	/* do requested operation */
	 
	for(i=0; i<ntr; i+=nwin/2) {
		memcpy( (void *) twin[0], (const void *) traces[i],
			nt*nwin*FSIZE);	

		/* compute forward slant stack */
/*		fwd_tx_sstack (dt, nt, nwin, -nwin/2*dx, dx, np, pminf, dpf,
	       		twin, pwin);
*/		forward_p_transform(nwin,nt,dt,pmaxf*1000.0,pminf*1000.0,dpf*1000.0,
                                    0.0,fh1,fh2,3.0,30.0,400,5,1,0,0,1,prw,
				    0.0,nwin*dx,1,dx,0.0,0.0,0.0,twin,pwin);
/*		fwd_FK_sstack (dt, nt, nwin, -nwin/2*dx, dx, np, pminf, dpf,0,
	       		twin, pwin);
*/		
		/* compute semplance */
		if(w==1) {
			semb(sn,pwin,np,nt,smb);
			/* apply weights */
			for(j=0;j<nt;j++)
				for(k=0;k<np;k++) pwin[k][j] *=smb[j];
		}
		if(s==1) {
			gaussian2d_smoothing (np,nt,sl2,sl1,pwin);
		}
		if(s==2) {
			dlsq_smoothing (nt,np,0,nt,0,np,sl1,sl2,0,pwin);
		}
		/* compute inverse slant stack */
/*		inv_tx_sstack (dt, nt, nwin, npoints,-nwin/2*dx, dx, np,pminf,dpf,
			pwin, twin);
*/		inverse_p_transform(nwin,nt,dt,pmaxf*1000.0,pminf*1000.0,dpf*1000.0,
                                    0.0,fh1,fh2,0.0,nwin*dx,1,dx,0.0,
				    pwin,twin);
/*		inv_FK_sstack (dt, nt, nwin,-nwin/2*dx, dx, np,pminf,dpf,0,
			pwin, twin);
*/			
		{ register int itr,it,spind;;
			for(itr=0;itr<nwin;itr++) {
				spind=i+itr;
				for(it=0;it<nt;it++) {
					if(spind>0 && spind<ntr) 
							out_traces[spind][it] += spw[itr]*twin[itr][it];
						/*	out_traces[spind][it] = twin[itr][it]; */
				}
			}
		}

/*		fprintf(stderr," Trace #= %5d\n",i); */	
        }
	/* write output traces */
        erewind(headerfp);
	{       register int itr;
		for (itr=0; itr<ntr; itr++) {
			efread(&tr, 1, HDRBYTES, headerfp);
			for (it=0; it<nt; it++) 
				tr.data[it]=out_traces[itr][it];
			puttr(&tr);
		}
	}
	efclose(headerfp);
	if (istmpdir) eremove(headerfile);

	/* free allocated space */
	free2float(out_traces);
	free1float(spw);

	return EXIT_SUCCESS;

}
示例#11
0
int
main(int argc, char **argv)
{
	int nt,nx;		/* numbers of samples			*/
	float dt;		/* sampling intervals			*/
	int it,ix;		/* sample indices			*/
	int ntfft;		/* dimensions after padding for FFT	*/
	int nF;			/* transform (output) dimensions	*/
	int iF;			/* transform sample indices		*/

	register complex **ct=NULL;	/* complex FFT workspace	*/
	register float **rt=NULL;	/* float FFT workspace		*/

	int verbose;		/* flag for echoing information		*/

	char *tmpdir=NULL;	/* directory path for tmp files		*/
	cwp_Bool istmpdir=cwp_false;/* true for user-given path		*/

	float v,fv,dv;		/* phase velocity, first, step	 	*/
	float amp,oamp;		/* temp vars for amplitude spectrum	*/
	int nv,iv;		/* number of phase vels, counter	*/
	float x;		/* offset  				*/
	float omega;		/* circular frequency			*/
	float domega;		/* circular frequency spacing (from dt)	*/
	float onfft;		/* 1 / nfft				*/
	float phi;		/* omega/phase_velocity			*/
	complex *cDisp=NULL;	/* temp array for complex dispersion	*/
	float arg;		/* temp var for phase calculation	*/
	complex cExp;		/* temp vars for phase calculation	*/
	float *offs=NULL;	/* input data offsets			*/
	float fmax;		/* max freq to proc (Hz)    		*/

	int out;		/* output real or abs v(f) spectrum	*/
	int norm;		/* normalization flag			*/

	float xmax;		/* maximum abs(offset) of input		*/
	float twopi, f;		/* constant and frequency (Hz)		*/



	/* Hook up getpar to handle the parameters */
	initargs(argc,argv);
	requestdoc(1);


	/* Get info from first trace */ 
	if (!gettr(&intrace))  err("can't get first trace");
	nt = intrace.ns;

	/* dt is used only to set output header value d1 */
	if (!getparfloat("dt", &dt)) {
		if (intrace.dt) { /* is dt field set? */
			dt = ((double) intrace.dt)/ 1000000.0;
		} else { /* dt not set, exit */
			err("tr.dt not set, stop.");
		}
	}
	warn("dt=%f",dt);
	if (!getparfloat("fv",&fv))	fv   = 330;
	if (!getparfloat("dv",&dv))     dv   = 25;
	if (!getparint("nv",&nv))       nv   = 100;
	if (!getparint("out",&out))     out  = 0;
	if (!getparint("norm",&norm))   norm = 0;
	if (!getparfloat("fmax",&fmax)) fmax = 50;

	if (!getparint("verbose", &verbose))	verbose = 0;

	/* Look for user-supplied tmpdir */
	if (!getparstring("tmpdir",&tmpdir) &&
	    !(tmpdir = getenv("CWP_TMPDIR"))) tmpdir="";
	if (!STREQ(tmpdir, "") && access(tmpdir, WRITE_OK))
		err("you can't write in %s (or it doesn't exist)", tmpdir);


        checkpars();

	/* Set up tmpfile */
	if (STREQ(tmpdir,"")) {
		tracefp = etmpfile();
		if (verbose) warn("using tmpfile() call");
	} else { /* user-supplied tmpdir */
		char directory[BUFSIZ];
		strcpy(directory, tmpdir);
		strcpy(tracefile, temporary_filename(directory));
		/* Trap signals so can remove temp files */
		signal(SIGINT,  (void (*) (int)) closefiles);
		signal(SIGQUIT, (void (*) (int)) closefiles);
		signal(SIGHUP,  (void (*) (int)) closefiles);
		signal(SIGTERM, (void (*) (int)) closefiles);
		tracefp = efopen(tracefile, "w+");
      		istmpdir=cwp_true;		
		if (verbose) warn("putting temporary files in %s", directory);
	}
	
	/* we have to allocate offs(nx) before we know nx */
	offs = alloc1float(MAX_OFFS);	

	ix = 0;
	nx = 0;
	xmax = 0.0;
	
	/* get nx and max abs(offset) */
	do { 
		++nx;
		efwrite(intrace.data, FSIZE, nt, tracefp);
		offs[ix] = intrace.offset;
		if ( abs(intrace.offset) > xmax ) xmax = abs(intrace.offset);
		++ix;
	} while (gettr(&intrace));
	
	/* confirm that offsets are set */
	if ( xmax == 0.0 ) err("tr.offset not set, stop.");


	/* Determine lengths for prime-factor FFTs */
	ntfft = npfar(nt);
	if (ntfft >= SU_NFLTS || ntfft >= PFA_MAX)
			err("Padded nt=%d--too big",ntfft);

	/* Determine complex transform sizes */
	nF = ntfft/2+1;  /* must be this nF for fft */
        onfft = 1.0 / ntfft;
	twopi = 2.0 * PI;
	domega = twopi * onfft / dt;

	/* Allocate space */
	ct = alloc2complex(nF,nx);
	rt = alloc2float(ntfft,nx);

	/* Load traces into fft arrays and close tmpfile */
	erewind(tracefp);
	for (ix=0; ix<nx; ++ix) {

		efread(rt[ix], FSIZE, nt, tracefp);

		/* pad dimension 1 with zeros */
		for (it=nt; it<ntfft; ++it)  rt[ix][it] = 0.0;
	}
	efclose(tracefp);
	
	/* Fourier transform dimension 1 */
	pfa2rc(1,1,ntfft,nx,rt[0],ct[0]);

	/* set nF for processing */
	if (fmax == 0) { 	
		/* process to nyquist */
		nF = ntfft/2+1;
	} else {
		/* process to given fmax */
		nF = (int) (twopi * fmax / domega);
	}
	
	/* data now in (w,x) domain 
	   allocate arrays  */
	cDisp = alloc1complex(nF);	
	
	/* if requested, normalize by amplitude spectrum 
	    (normalizing by amplitude blows up aliasing and other artifacts) */			
	if (norm == 1) {
		for (iF=0; iF<nF; ++iF)  {
			/* calc this frequency */
			omega = iF * domega;
			f = omega / twopi;
			/* loop over traces */
			for (ix=0; ix<nx; ++ix) {
				/* calc amplitude at this (f,x) location */
				amp = rcabs(ct[ix][iF]);
				oamp = 1.0/amp;
				/* scale field by amp spectrum */
				ct[ix][iF] = crmul(ct[ix][iF],oamp);
			}
		}
	}
	
	/* set global output trace headers */
	outtrace.ns = 2 * nF;
	outtrace.dt = dt*1000000.;  
	outtrace.trid = FUNPACKNYQ;
	outtrace.d1 = 1.0 / (ntfft * dt); /* Hz */
	outtrace.f1 = 0;
	outtrace.d2 = dv;
	outtrace.f2 = fv;

	/* loop over phase velocities */
	for (iv=0; iv<nv; ++iv) {

		/* this velocity */
		v = fv + iv*dv;
	
		/* loop over frequencies */
		for (iF=0; iF<nF; ++iF)  {

			/* this frequency and phase */
			omega = iF * domega;
			f = omega / twopi;
			phi = omega / v;

			/* initialize */
			cDisp[iF] = cmplx(0.0,0.0);		

			/* sum over abs offset (this is ok for 3D, too) */
			for (ix=0; ix<nx; ++ix) {

				/* get this x */
				x = abs(offs[ix]);

				/* target phase */
				arg = - phi * x;
				cExp = cwp_cexp(crmul(cmplx(0.0,1.0), arg));
				
				/* phase vel profile for this frequency */				 
				cDisp[iF] = cadd(cDisp[iF],cmul(ct[ix][iF],cExp));
			}
			
		}
		
		/* set trace counter */
		outtrace.tracl = iv + 1;
			
		/* copy results to output trace 
		   interleaved format like sufft.c */
		for (iF = 0; iF < nF; ++iF) {
			outtrace.data[2*iF]   = cDisp[iF].r;
			outtrace.data[2*iF+1] = cDisp[iF].i;
		}
		
		/* output freqs at this vel */
		puttr(&outtrace);

	}  /* next frequency */
	
	
	/* Clean up */
	if (istmpdir) eremove(tracefile);
	return(CWP_Exit());
}
示例#12
0
int
main(int argc, char **argv)
{
	cwp_String key;	/* header key word from segy.h		*/
	cwp_String type;/* ... its type				*/
	int index;	/* ... its index			*/
	int nsegy;	/* number of bytes in the segy		*/
	Value val;	/* value of key in current gather	*/
	Value valnew;	/* value of key in trace being treated	*/
	int verbose;	/* verbose flag				*/
	int val_i;	/* key value as an integer		*/

	int ntr=0;	/* count of number of traces in an ensemble */
	int numlength;	/* length of numerical part of filenames */
	
	FILE *tmpfp=NULL;		/* file pointer			*/
	FILE *outfp=NULL;	/* file pointer			*/
	cwp_String dir;		/* directory name		*/
	cwp_String suffix;	/* suffix of output files	*/

	char directory[BUFSIZ];		/* storage for directory name	*/
 	char tempfilename[BUFSIZ];	/* 	...temporary filename	*/
	char middle[BUFSIZ];		/*      ...middle of final filename */
	char stem[BUFSIZ];		/*      ...stem of final filename */
 	char format[BUFSIZ];		/* 	...format of numeric part */
	char outfile[BUFSIZ];		/*      ...final filename	*/

	/* Initialize */
	initargs(argc, argv);
	requestdoc(1);


	/* Get parameters */
	MUSTGETPARSTRING("dir", &dir);
	if (!getparint   ("verbose", &verbose))	 	verbose = 0;
	if (!getparstring("key", &key))		 	key = "ep";
	if (!getparstring("suffix", &suffix))		suffix = ".hsu";
	if (!getparint("numlength", &numlength)) 	numlength=7;

	/* Initialize */
	/* tempfilename = ealloc1(strlen(tmplt)+3,sizeof(char)); */
	type = hdtype(key);
	index = getindex(key);

	/* Set up for first trace (must compare new key field each time) */
	nsegy = gettr(&intrace);
	
	/* Create temporary filename for the first gather */
	strcpy(directory, dir);
	strcpy(tempfilename, temporary_filename(directory));
	if((tmpfp = fopen(tempfilename,"w+")) == NULL)
		err("Cannot open file %s\n",tempfilename);

	if (verbose) warn(" temporary filename = %s", tempfilename);

	/* get key header value */
	gethval(&intrace, index, &val);
	
	ntr=0;
	do {

		++ntr;
		/* Get header value */				 
		gethval(&intrace, index, &valnew);

		/* compare past header value to current value */
		if (valcmp(type, val, valnew) || !nsegy) {
		 /* Either val and valnew differ, indicating a  */
		 /* new gather or nsegy is zero, indicating the */
		 /* end of the traces.			  */
			
			/* capture key field value */
			/* and build output filename */
			val_i=vtoi(type,val);

			/* zero out name parts */
			strcpy(outfile,"");
			strcpy(middle,"");
			strcpy(stem,"");

			/* build output name parts */
			strcat(middle,directory);
			strcat(middle,"/");
			strcat(stem,key);
			strcat(stem,"=");

			/* format for numeric part */
			(void)sprintf(format, "%%s%%s%%0%dd%%s",numlength);
		
			/* build name of output file */
			(void)sprintf(outfile, format,middle,stem,
					val_i, suffix);

			if (verbose) warn(" outfile = %s", outfile);

			/* rewind file */
			rewind(tmpfp);

			/* open the new file */
			if((outfp = fopen(outfile,"w+")) == NULL)
				err("Cannot open file %s\n",outfile);
			/* loop over traces setting ntr field */
			/*  and write to finalfile */	
			while(fgettr(tmpfp,&tmptr))  {
				tmptr.ntr = ntr;
				fputtr(outfp,&tmptr);
			}
			/* Close files */
			fclose(tmpfp);
			fclose(outfp);
			remove(tempfilename);

			if (verbose) warn("val= %i", val_i);

			/* Set up for next gather */
			/* create new tempfname first */
			strcpy(tempfilename, temporary_filename(directory));
			
			/* open filename */
			if((tmpfp = fopen(tempfilename,"w+")) == NULL)
				err("Cannot open file %s\n",tempfilename);
			val = valnew;
			ntr=0;
		}
		fputtr(tmpfp,&intrace);
	} while(gettr(&intrace));
	
	/* Close file */
	rewind(tmpfp);
	val_i=vtoi(type,val);
	
	/* Move last gather into new location */
	/* capture key field value */
	/* and build output filename */

	/* null out name parts */
	strcpy(outfile,"");
	strcpy(middle,"");
	strcpy(stem,"");

	/* build name parts */
	strcat(middle,directory);
	strcat(middle,"/");
	strcat(stem,key);
	strcat(stem,"=");
	
	/* write format of numeric part of output filename */
	(void)sprintf(format, "%%s%%s%%0%dd%%s",numlength);

	/* write output filename */
	(void)sprintf(outfile, format,middle,stem,
				val_i, suffix);

	/* open the output file */
	if((outfp = fopen(outfile,"w+")) == NULL)
			err("Cannot open file %s\n",outfile);
	/* loop over traces setting ntr field */
	while(fgettr(tmpfp,&tmptr))  {
		tmptr.ntr = ntr;
		fputtr(outfp,&tmptr);
	}
	/* Close file */
	fclose(tmpfp);
	fclose(outfp);
	remove(tempfilename);

	if (verbose) warn(" outfile = %s", outfile);
	if (verbose) warn("val= %i",val_i);

	return(CWP_Exit());

}
示例#13
0
static opcode_status_ty
spawn(string_list_ty *args, string_ty *input, int *pid_p,
    string_ty *host_binding, opcode_context_ty *ocp)
{
    size_t          j;
    int             fd;
    string_ty       *iname;
    int             pid;
    opcode_status_ty status;
    static char     **argv;
    static size_t   argvlen;
    string_list_ty  cmd;
    sub_context_ty  *scp;
    char            *shell;

    trace(("spawn()\n{\n"));
    assert(args);

    /*
     * build the input file, if required
     */
    status = opcode_status_error;
    fd = -1;
    iname = 0;
    if (input)
    {
        /*
         * He has given a string to be used as input to the command,
         * so write it out to a file, and then redirect the input.
         */
        iname = temporary_filename();
        fd = open(iname->str_text, O_RDWR | O_CREAT | O_TRUNC, 0666);
        if (fd < 0)
            fatal_intl_open(iname->str_text);
        if (unlink(iname->str_text))
        {
            error_intl_unlink(iname->str_text);
            goto done;
        }
        if
        (
            write(fd, input->str_text, input->str_length) < 0
        ||
            lseek(fd, 0L, SEEK_SET)
        )
        {
            error_intl_write(iname->str_text);
            goto done;
        }
    }

    /*
     * See if there is a host_binding in effect.
     */
    if (host_binding)
    {
        static string_ty *key;
        string_list_ty  *slp;
        string_ty       *s;
        string_ty       *rcmd;
        string_ty       *rcmdq;
        string_ty       *result_fn;
        FILE            *result_fp;
        string_ty       *cwd;
        string_ty       *script_fn;
        FILE            *script_fp;

        /*
         * Work out the name of the remote shell command.
         */
        if (!key)
            key = str_from_c("parallel_rsh");
        slp = id_var_search(ocp, key);
        if (slp)
            string_list_copy_constructor(&cmd, slp);
        else
        {
            static string_ty *rsh;

            if (!rsh)
                rsh = str_from_c(CONF_REMOTE_SHELL);
            string_list_constructor(&cmd);
            string_list_append(&cmd, rsh);
        }

        /*
         * Add the name of the host.
         */
        string_list_append(&cmd, host_binding);

        /*
         * The remote end will need to change directory to where
         * we are now, since it is *highly* unlikely that we are
         * in our home directory.
         */
        cwd = os_curdir(); /* do not str_free this */

        /*
         * We are going to create a small shell script contining
         * the command to be executed.  This deals with various
         * weird and obscure $SHELL settings, and it also deals
         * with command lines so long that rsh barfs.
         *
         * Yes, there is a potential race condition here.
         * Between writing the script and executing it, we
         * could be tricked into executing something else.
         * Especially if there is a symlink lying in wait.
         */
        script_fn = dot_temporary_filename();
        script_fp = fopen_and_check(script_fn->str_text, "w");

        /*
         * what shell are we using
         */
        shell = getenv("SHELL");
        if (!shell || !*shell)
            shell = CONF_SHELL;
        fprintf(script_fp, "#!%s\n", shell);

        /*
         * Now write the actual command to the script file.
         */
        rcmd = wl2str(args, 0, args->nstrings, (char *)0);
        fprintf(script_fp, "%s\n", rcmd->str_text);
        str_free(rcmd);

        fflush_and_check(script_fp, script_fn->str_text);
        fclose_and_check(script_fp, script_fn->str_text);
        chmod_and_check(script_fn->str_text, 0755);

        /*
         * This is the result file.  It is where the remote
         * command will stash its exit status.    We seed it with
         * failure in case the rsh fails altogether.
         *
         * And, yes, there is a race conditon and we could be
         * lied to if they are quick.
         */
        result_fn = dot_temporary_filename();
        result_fp = fopen_and_check(result_fn->str_text, "w");
        fprintf(result_fp, "42\n");
        fflush_and_check(result_fp, result_fn->str_text);
        fclose_and_check(result_fp, result_fn->str_text);

        /*
         * Because rsh(1) always returns an exit status of zero,
         * we have to make other arrangements to obtain the exit
         * status.
         *
         * We actually need to be a more devious, so that we can
         * get the exit status back.  Write it to a temporary
         * file server side, then read and remove it client side.
         *
         * This is the server side command.  It gets quoted
         * again to protect it from the client side shell.
         *
         * We use sh explicitly, because the shell at the other
         * end could be csh, tcsh, or something even stranger,
         * and we need to guarantee the command will execute
         * exactly the way we need.
         */
        rcmd =
            str_format
            (
                "sh -c 'cd %s && sh %s %s/%s; echo $? > %s/%s'",
                cwd->str_text,
                (option_test(OPTION_ERROK) ? "-c" : "-ce"),
                cwd->str_text,
                script_fn->str_text,
                cwd->str_text,
                result_fn->str_text
            );
        rcmdq = str_quote_shell(rcmd);
        str_free(rcmd);
        string_list_append(&cmd, rcmdq);
        str_free(rcmdq);

        /*
         * This is the rest of the server side command.
         *
         * On some systems this gives ``Text file busy'' errors,
         * as if the script file has yet to be released by
         * the kernel.    Since we *aren't* executing it when the
         * RM command runs, I have no idea how to avoid this
         * (other than ignoring it with -f).  Maybe this is some
         * kind of NFS latency?
         */
        s =
            str_format
            (
                "&& exit `cat %s;rm -f %s %s`",
                result_fn->str_text,
                result_fn->str_text,
                script_fn->str_text
            );
        string_list_append(&cmd, s);
        str_free(s);
        str_free(result_fn);
        str_free(script_fn);

        /*
         * Because the command has a semicolon and back quotes,
         * we need to hand it to a shell (as alluded to above).
         * Assemble into a single string.
         */
        rcmd = wl2str(&cmd, 0, cmd.nstrings, (char *)0);
        string_list_destructor(&cmd);

        /*
         * Build the final command to be executed.
         * It even cleans up after itself.
         */
        s = str_from_c("sh");
        string_list_append(&cmd, s);
        str_free(s);
        s = str_from_c("-c");
        string_list_append(&cmd, s);
        str_free(s);
        string_list_append(&cmd, rcmd);
        str_free(rcmd);
    }
    else
    {
        /*
         * build the command
         */
        if (os_execute_magic_characters_list(args))
        {
            string_ty       *str;

            /*
             * what shell are we using
             */
            shell = getenv("SHELL");
            if (!shell || !*shell)
                shell = CONF_SHELL;

            string_list_constructor(&cmd);
            str = str_from_c(shell);
            string_list_append(&cmd, str);
            str_free(str);
            if (option_test(OPTION_ERROK))
                str = str_from_c("-c");
            else
                str = str_from_c("-ce");
            string_list_append(&cmd, str);
            str_free(str);
            str = wl2str(args, 0, args->nstrings - 1, (char *)0);
            string_list_append(&cmd, str);
            str_free(str);
        }
        else
            string_list_copy_constructor(&cmd, args);
    }

    /*
     * build the argv array
     */
    if (!argv)
    {
        argvlen = cmd.nstrings + 1;
        argv = mem_alloc(argvlen * sizeof(char *));
    }
    else if (argvlen < cmd.nstrings + 1)
    {
        argvlen = cmd.nstrings + 1;
        argv = mem_change_size(argv, argvlen * sizeof(char *));
    }
    if (cmd.nstrings == 0)
    {
        string_list_destructor(&cmd);
        status = opcode_status_success;
        goto done;
    }
    for (j = 0; j < cmd.nstrings; ++j)
        argv[j] = cmd.string[j]->str_text;
    argv[cmd.nstrings] = 0;

    /*
     * spawn the child process
     */
    switch (pid = fork())
    {
    case -1:
        scp = sub_context_new();
        sub_errno_set(scp);
        error_intl(scp, i18n("fork(): $errno"));
        sub_context_delete(scp);
        break;

    case 0:
        /*
         * child
         */
        if (fd >= 0)
        {
            if (close(0) && errno != EBADF)
            {
                string_ty       *fn0;
                int             err;

                err = errno;
                scp = sub_context_new();
                fn0 = subst_intl(scp, "standard input");
                /* re-use substitution context */
                sub_errno_setx(scp, err);
                sub_var_set_string(scp, "File_Name", fn0);
                fatal_intl
                (
                    scp,
                    i18n("close $filename: $errno")
                );
                /* NOTREACHED */
                sub_context_delete(scp);
                str_free(fn0);
            }
            if (dup(fd) < 0)
            {
                scp = sub_context_new();
                sub_errno_set(scp);
                fatal_intl(scp, i18n("dup(): $errno"));
                /* NOTREACHED */
                sub_context_delete(scp);
            }
            close(fd);
        }
        if (argv[0][0] == '/')
            execv(argv[0], argv);
        else
            execvp(argv[0], argv);
        scp = sub_context_new();
        sub_errno_set(scp);
        sub_var_set_charstar(scp, "File_Name", argv[0]);
        fatal_intl(scp, i18n("exec $filename: $errno"));
        /* NOTREACHED */
        sub_context_delete(scp);

    default:
        /*
         * parent
         */
        if (fd >= 0)
        {
            close(fd);
            fd = -1;
        }
        string_list_destructor(&cmd);
        status = opcode_status_wait;
        trace(("pid = %d;\n", pid));
        *pid_p = pid;
        break;
    }
    done:
    if (fd >= 0)
        close(fd);
    if (iname)
        str_free(iname);
    trace(("return %s;\n", opcode_status_name(status)));
    trace(("}\n"));
    return status;
}
示例#14
0
int
main(int argc, char **argv)
{
	int nt;		/* number of time samples per trace */
	float dt;	/* time sampling interval */
	float ft;	/* time of first sample */
	int it;		/* time sample index */
	int cdpmin;	/* minimum cdp to process */
	int cdpmax;	/* maximum cdp to process */
	float dx;	/* cdp sampling interval */
	int nx;		/* number of cdps to process */
	int nxfft;	/* number of cdps after zero padding for fft */
	int nxpad;	/* minimum number of cdps for zero padding */
	int ix;		/* cdp index, starting with ix=0 */
	int noffmix;	/* number of offsets to mix */
	float *tdmo;	/* times at which rms velocities are specified */
	float *vdmo;	/* rms velocities at times specified in tdmo */
	float sdmo;	/* DMO stretch factor */
	int ntdmo;	/* number tnmo values specified */
	int itdmo;	/* index into tnmo array */
	int nvdmo;	/* number vnmo values specified */
	float fmax;	/* maximum frequency */
	float *vrms;	/* uniformly sampled vrms(t) */
	float **p;	/* traces for one offset - common-offset gather */
	float **q;	/* DMO-corrected and mixed traces to be output */
	float offset;	/* source-receiver offset of current trace */
	float oldoffset;/* offset of previous trace */
	int noff;	/* number of offsets processed in current mix */
	int ntrace;	/* number of traces processed in current mix */
	int itrace;	/* trace index */
	int gottrace;	/* non-zero if an input trace was read */
	int done;	/* non-zero if done */
	int verbose;	/* =1 for diagnostic print */
	char *tmpdir;	/* directory path for tmp files	*/
	cwp_Bool istmpdir=cwp_false;/* true for user given path */

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

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

	/* get parameters */
	if (!getparint("cdpmin",&cdpmin)) err("must specify cdpmin");
	if (!getparint("cdpmax",&cdpmax)) err("must specify cdpmax");
	if (cdpmin>cdpmax) err("cdpmin must not be greater than cdpmax");
	if (!getparfloat("dxcdp",&dx)) err("must specify dxcdp");
	if (!getparint("noffmix",&noffmix)) err("must specify noffmix");
	ntdmo = countparval("tdmo");
	if (ntdmo==0) ntdmo = 1;
	tdmo = ealloc1float(ntdmo);
	if (!getparfloat("tdmo",tdmo)) tdmo[0] = 0.0;
	nvdmo = countparval("vdmo");
	if (nvdmo==0) nvdmo = 1;
	if (nvdmo!=ntdmo) err("number of tdmo and vdmo must be equal");
	vdmo = ealloc1float(nvdmo);
	if (!getparfloat("vdmo",vdmo)) vdmo[0] = 1500.0;
	for (itdmo=1; itdmo<ntdmo; ++itdmo)
		if (tdmo[itdmo]<=tdmo[itdmo-1])
			err("tdmo must increase monotonically");
	if (!getparfloat("sdmo",&sdmo)) sdmo = 1.0;
	if (!getparfloat("fmax",&fmax)) fmax = 0.5/dt;
	if (!getparint("verbose",&verbose)) verbose=0;
	
	/* Look for user-supplied tmpdir */
	if (!getparstring("tmpdir",&tmpdir) &&
	    !(tmpdir = getenv("CWP_TMPDIR"))) tmpdir="";
	if (!STREQ(tmpdir, "") && access(tmpdir, WRITE_OK))
		err("you can't write in %s (or it doesn't exist)", tmpdir);
	
	/* make uniformly sampled rms velocity function of time */
	vrms = ealloc1float(nt);
	mkvrms(ntdmo,tdmo,vdmo,nt,dt,ft,vrms);
	
	/* determine number of cdps to process */
	nx = cdpmax-cdpmin+1;
	
	/* allocate and zero common-offset gather p(t,x) */
	nxpad = 0.5*ABS(offset/dx);
	nxfft = npfar(nx+nxpad);
	p = ealloc2float(nt,nxfft+2);
	for (ix=0; ix<nxfft; ++ix)
		for (it=0; it<nt; ++it)
			p[ix][it] = 0.0;

	/* allocate and zero offset mix accumulator q(t,x) */
	q = ealloc2float(nt,nx);
	for (ix=0; ix<nx; ++ix)
		for (it=0; it<nt; ++it)
			q[ix][it] = 0.0;
		
	/* open temporary file for headers */
	if (STREQ(tmpdir,"")) {
		headerfp = etmpfile();
		if (verbose) warn("using tmpfile() call");
	} else { /* user-supplied tmpdir */
		char directory[BUFSIZ];
		strcpy(directory, tmpdir);
		strcpy(headerfile, temporary_filename(directory));
		/* Trap signals so can remove temp files */
		signal(SIGINT,  (void (*) (int)) closefiles);
		signal(SIGQUIT, (void (*) (int)) closefiles);
		signal(SIGHUP,  (void (*) (int)) closefiles);
		signal(SIGTERM, (void (*) (int)) closefiles);
		headerfp = efopen(headerfile, "w+");
      		istmpdir=cwp_true;		
		if (verbose)
			warn("putting temporary header file in %s", directory);
	}

	/* initialize */
	oldoffset = offset;
	gottrace = 1;
	done = 0;
	ntrace = 0;
	noff = 0;

	/* loop over traces */
	do {
		/* if got a trace, determine offset */
		if (gottrace) offset = tr.offset;
		
		/* if an offset is complete */
		if ((gottrace && offset!=oldoffset) || !gottrace) {
		
			/* do dmo for old common-offset gather */
			dmooff(oldoffset,fmax,sdmo,nx,dx,nt,dt,ft,vrms,p);
			
			/* add dmo-corrected traces to mix */
			for (ix=0; ix<nx; ++ix)
				for (it=0; it<nt; ++it)
					q[ix][it] += p[ix][it];
			
			/* count offsets in mix */
			noff++;
							
			/* free space for old common-offset gather */
			free2float(p);
			
			/* if beginning a new offset */
			if (offset!=oldoffset) {
				
				/* allocate space for new offset */
				nxpad = 0.5*ABS(offset/dx);
				nxfft = npfar(nx+nxpad);
				p = ealloc2float(nt,nxfft+2);
				for (ix=0; ix<nxfft; ++ix)
					for (it=0; it<nt; ++it)
						p[ix][it] = 0.0;
			}
		}
		
		/* if a mix of offsets is complete */
		if (noff==noffmix || !gottrace) {
			
			/* rewind trace header file */
			erewind(headerfp);
			
			/* loop over all output traces */
			for (itrace=0; itrace<ntrace; ++itrace) {
			
				/* read trace header and determine cdp index */
				efread(&tro,HDRBYTES,1,headerfp);
				
				/* get dmo-corrected data */
				memcpy( (void *) tro.data,
					(const void *)	q[tro.cdp-cdpmin],
					nt*sizeof(float));
				
				/* write output trace */
				puttr(&tro);
			}
			
			/* report */
			if (verbose) 
				fprintf(stderr,"\tCompleted mix of "
					"%d offsets with %d traces\n",
					noff,ntrace);
			
			/* if no more traces, break */
			if (!gottrace) break;
			
			/* rewind trace header file */
			erewind(headerfp);

			/* reset number of offsets and traces in mix */
			noff = 0;
			ntrace = 0;
			
			/* zero offset mix accumulator */
			for (ix=0; ix<nx; ++ix)
				for (it=0; it<nt; ++it)
					q[ix][it] = 0.0;
		}
			
		/* if cdp is within range to process */
		if (tr.cdp>=cdpmin && tr.cdp<=cdpmax) {
	
			/* save trace header and update number of traces */
			efwrite(&tr,HDRBYTES,1,headerfp);
			ntrace++;

			/* remember offset */
			oldoffset = offset;

			/* get trace samples */
			memcpy( (void *) p[tr.cdp-cdpmin],
				   (const void *) tr.data, nt*sizeof(float));
		}

		/* get next trace (if there is one) */
		if (!gettr(&tr)) gottrace = 0;
		
	} while (!done);

	/* clean up */
	efclose(headerfp);
	if (istmpdir) eremove(headerfile);
	return(CWP_Exit());
}