Skip to content
Snippets Groups Projects
readTinvData.c 8.35 KiB
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "segy.h"
#include <assert.h>

typedef struct { /* complex number */
        float r,i;
} complex;

#ifndef MAX
#define MAX(x,y) ((x) > (y) ? (x) : (y))
#endif
#ifndef MIN
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#endif
#define NINT(x) ((int)((x)>0.0?(x)+0.5:(x)-0.5))

int optncr(int n);
void cc1fft(complex *data, int n, int sign);
void rc1fft(float *rdata, complex *cdata, int n, int sign);
void findShotInMute(float *xrcvMute, float xrcvShot, int nxs, int *imute);

int readTinvData(char *filename, float *xrcv, float *xsrc, float *zsrc, int *xnx, complex *cdata, int nw, int nw_low, int Nsyn, int nx, int ntfft, int mode, float *maxval, float *tinv, int hw, int verbose)
{
	FILE *fp;
	segy hdr;
	size_t nread;
	int fldr_shot, sx_shot, itrace, one_shot, ig, isyn, iw, i, j, k;
	int end_of_file, nt, ir, is;
	int nx1, jmax, imax, tstart, tend;
	float xmin, xmax, tmax, lmax;
	float scl, scel, dt, *trace;
	complex *ctrace;

	/* Reading first header  */

	if (filename == NULL) fp = stdin;
	else fp = fopen( filename, "r" );
	if ( fp == NULL ) {
		fprintf(stderr,"input file %s has an error\n", filename);
		perror("error in opening file: ");
		fflush(stderr);
		return -1;
	}

	fseek(fp, 0, SEEK_SET);
	nread = fread( &hdr, 1, TRCBYTES, fp );
	assert(nread == TRCBYTES);
	if (hdr.scalco < 0) scl = 1.0/fabs(hdr.scalco);
	else if (hdr.scalco == 0) scl = 1.0;
	else scl = hdr.scalco;
	if (hdr.scalel < 0) scel = 1.0/fabs(hdr.scalel);
	else if (hdr.scalel == 0) scel = 1.0;
	else scel = hdr.scalel;
	fseek(fp, 0, SEEK_SET);

	nt     = hdr.ns;
	trace  = (float *)calloc(ntfft,sizeof(float));
	ctrace = (complex *)malloc(ntfft*sizeof(complex));

	end_of_file = 0;
	one_shot    = 1;
	isyn        = 0;

	/* Read shots in file */

	while (!end_of_file) {
		/* start reading data (shot records) */
		itrace     = 0;
		nread = fread( &hdr, 1, TRCBYTES, fp );
		if (nread != TRCBYTES) { /* no more data in file */
			break;
		}

		sx_shot    = hdr.sx;
		fldr_shot  = hdr.fldr;
		xsrc[isyn] = sx_shot*scl;
		zsrc[isyn] = hdr.selev*scel;
		xnx[isyn]  = 0;
        ig = isyn*nx*ntfft;
		while (one_shot) {
			xrcv[isyn*nx+itrace] = hdr.gx*scl;
			nread = fread( trace, sizeof(float), nt, fp );
			assert (nread == hdr.ns);

			/* copy trace to data array */
            memcpy( &tinv[ig+itrace*ntfft], trace, nt*sizeof(float));

			/* transform to frequency domain */
			if (ntfft > hdr.ns) 
				memset( &trace[nt], 0, sizeof(float)*(ntfft-nt) );

        	rc1fft(trace,ctrace,ntfft,-1);
        	for (iw=0; iw<nw; iw++) {
        		cdata[isyn*nx*nw+iw*nx+itrace].r = ctrace[nw_low+iw].r;
        		cdata[isyn*nx*nw+iw*nx+itrace].i = mode*ctrace[nw_low+iw].i;
        	}
			itrace++;

			/* read next hdr of next trace */
			nread = fread( &hdr, 1, TRCBYTES, fp );
			if (nread != TRCBYTES) { 
				one_shot = 0;
				end_of_file = 1;
				break;
			}
			if ((sx_shot != hdr.sx) || (fldr_shot != hdr.fldr) ) break;
		}
		if (verbose>2) {
			fprintf(stderr,"finished reading shot %d (%d) with %d traces\n",sx_shot,isyn,itrace);
			//disp_fileinfo(filename, nt, xnx[isyn], hdr.f1, xrcv[isyn*nxm], d1, d2, &hdr);
		}

		/* look for maximum in shot record to define mute window */
        /* find consistent (one event) maximum related to maximum value */
		nx1 = itrace;
		xnx[isyn]=nx1;
        /* find global maximum */
		xmax=0.0;
		for (i = 0; i < nx1; i++) {
            tmax=0.0;
            jmax = 0;
            for (j = 0; j < nt; j++) {
                lmax = fabs(tinv[ig+i*ntfft+j]);
                if (lmax > tmax) {
                    jmax = j;
                    tmax = lmax;
                    if (lmax > xmax) {
                        imax = i;
                        xmax=lmax;
                    }
                }
            }
            maxval[isyn*nx+i] = jmax;
		}

        /* search forward in trace direction from maximum in file */
        for (i = imax+1; i < nx1; i++) {
            tstart = MAX(0, (maxval[isyn*nx+i-1]-hw));
            tend   = MIN(nt-1, (maxval[isyn*nx+i-1]+hw));
            jmax=tstart;
            tmax=0.0;
            for(j = tstart; j <= tend; j++) {
                lmax = fabs(tinv[ig+i*ntfft+j]);
                if (lmax > tmax) {
                    jmax = j;
                    tmax = lmax;
                }
            }
            maxval[isyn*nx+i] = jmax;
        }
        /* search backward in trace direction from maximum in file */
        for (i = imax-1; i >=0; i--) {
            tstart = MAX(0, (maxval[isyn*nx+i+1]-hw));
            tend   = MIN(nt-1, (maxval[isyn*nx+i+1]+hw));
            jmax=tstart;
            tmax=0.0;
            for(j = tstart; j <= tend; j++) {
                lmax = fabs(tinv[ig+i*ntfft+j]);
                if (lmax > tmax) {
                    jmax = j;
                    tmax = lmax;
                }
            }
            maxval[isyn*nx+i] = jmax;
        }

		if (itrace != 0) { /* end of shot record, but not end-of-file */
			fseek( fp, -TRCBYTES, SEEK_CUR );
			isyn++;
		}
		else {
			end_of_file = 1;
		}

		/* copy trace to data array for mode=-1 */
        /* time reverse trace */
		if (mode==-1) {
			for (i = 0; i < nx1; i++) {
            	memcpy( trace, &tinv[ig+i*ntfft], ntfft*sizeof(float));
				j=0;
				tinv[ig+i*ntfft+j] = trace[j];
				for (j=1; j<ntfft; j++) tinv[ig+i*ntfft+ntfft-j] = trace[j];
			}
		}
	}

	free(ctrace);
	free(trace);

	return 0;
}


void applyMute( float *data, float *mute, int smooth, int above, int Nsyn, int nxs, int nt, float *xsrc, int *xrcvsyn, int nx, int shift)
//void applyMute( float *data, float *mute, int smooth, int above, int Nsyn, int nx, int nt, int shift)
{
 	int i, j, k, l, isyn;
	float *costaper, scl, xrcvShot;
	int ixrcvMute, imute, tmute;

	if (smooth) {
        costaper = (float *)malloc(smooth*sizeof(float));
        scl = M_PI/((float)smooth);
        for (i=0; i<smooth; i++) {
            costaper[i] = 0.5*(1.0+cos((i+1)*scl));
        }
    }

	for (isyn = 0; isyn < Nsyn; isyn++) {
		if (above==1) {
            for (i = 0; i < nx; i++) {
				//xrcvShot = xsrc[i];
				/* this is an expensive search method TODO; try to find a better search method-quicksort */
				//findShotInMute(&xrcvsyn[isyn*nxs], xrcvShot, nxs, &imute);
				imute = xrcvsyn[i];
				tmute = mute[isyn*nxs+imute];
                for (j = 0; j < tmute-shift-smooth; j++) {
                    data[isyn*nx*nt+i*nt+j] = 0.0;
                }
                for (j = tmute-shift-smooth,0,l=0; j < tmute-shift; j++,l++) {
                    data[isyn*nx*nt+i*nt+j] *= costaper[smooth-l-1];
                }
            }
        }
        else if (above==0){
            for (i = 0; i < nx; i++) {
				//xrcvShot = xsrc[i];
				/* this is an expensive search method TODO; try to find a better search method-quicksort */
				//findShotInMute(&xrcvsyn[isyn*nxs], xrcvShot, nxs, &imute);
				imute = xrcvsyn[i];
				tmute = mute[isyn*nxs+imute];
                for (j = tmute-shift,l=0; j < tmute-shift+smooth; j++,l++) {
                    data[isyn*nx*nt+i*nt+j] *= costaper[l];
                }
                for (j = tmute-shift+smooth+1; j < nt+1-tmute+shift-smooth; j++) {
                    data[isyn*nx*nt+i*nt+j] = 0.0;
                }
                for (j = nt-tmute+shift-smooth,l=0; j < nt-tmute+shift; j++,l++) {
                    data[isyn*nx*nt+i*nt+j] *= costaper[smooth-l-1];
                }
            }
        }
        else if (above==-1){
            for (i = 0; i < nx; i++) {
                for (j = mute[isyn*nx+i]-shift,l=0; j < mute[isyn*nx+i]-shift+smooth; j++,l++) {
                    data[isyn*nx*nt+i*nt+j] *= costaper[l];
                }
                for (j = mute[isyn*nx+i]-shift+smooth; j < nt; j++) {
                    data[isyn*nx*nt+i*nt+j] = 0.0;
                }
            }
        }
	}
	if (smooth) free(costaper);

	return;
}

/* simple sort algorithm */
void findShotInMute(float *xrcvMute, float xrcvShot, int nxs, int *imute)
{
	int i, sign;
	float diff1, diff2;

	*imute=0;

	if (xrcvMute[0] < xrcvMute[1]) sign = 1;
	else sign = -1;

	if (sign == 1) {
		i = 0;
		while (xrcvMute[i] < xrcvShot && i < nxs) {
			i++;
		}
		/* i is now position larger than xrcvShot */
	}
	else {
		i = 0;
		while (xrcvMute[i] > xrcvShot && i < nxs) {
			i++;
		}
		/* i is now position smaller than xrcvShot */
	}

	diff1 = fabsf(xrcvMute[i]-xrcvShot);
	diff2 = fabsf(xrcvMute[i-1]-xrcvShot);
	if (diff1 < diff2) *imute = i;
	else *imute = i-1;

	return;
}