-
Joeri Brackenhoff authoredJoeri Brackenhoff authored
HomG.c 13.78 KiB
#include "par.h"
#include "segy.h"
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <genfft.h>
#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))
#ifndef COMPLEX
typedef struct _complexStruct { /* complex number */
float r,i;
} complex;
#endif/* complex */
int getFileInfo(char *filename, int *n1, int *n2, int *ngath, float *d1, float *d2, float *f1, float *f2, float *xmin, float *xmax, float *sclsxgx, int *nxm);
int disp_fileinfo(char *file, int n1, int n2, float f1, float f2, float d1, float d2, segy *hdrs);
double wallclock_time(void);
int writeData(FILE *fp, float *data, segy *hdrs, int n1, int n2);
int readSnapData(char *filename, float *data, segy *hdr, int ngath, int nx, int ntfft, int sx, int ex, int sz, int ez);
int topdet(float *data, int nt);
void scl_data(float *data, int nsam, int nrec, float scl, float *datout, int nsamout);
void pad_data(float *data, int nsam, int nrec, int nsamout, float *datout);
void convol(float *data1, float *data2, float *con, int nrec, int nsam, float dt, int shift);
char *sdoc[] = {
" ",
" HomG - Calculate a Homogeneous Green's function ",
" ",
" authors : Joeri Brackenhoff (J.A.Brackenhoff@tudelft.nl)",
" : Jan Thorbecke (janth@xs4all.nl)",
" ",
" Required parameters: ",
"",
" file_in= ................. First file of the array of receivers",
" file_shot= ............... File containing the shot location",
" ",
" Optional parameters: ",
" ",
" file_out= ................ Filename of the output",
" numb= .................... integer number of first snapshot file",
" dnumb= ................... integer number of increment in snapshot files",
" zmax= .................... Integer number of maximum depth level",
" inx= ..................... Number of sources per depth level",
" zrcv= .................... z-coordinate of first receiver location",
" xrcv= .................... x-coordinate of first receiver location",
" dzrcv= ................... z-spacing of receivers",
" dxrcv= ................... x-spacing of receivers",
NULL};
int main (int argc, char **argv)
{
FILE *fp_in, *fp_shot, *fp_out;
char *fin, *fshot, *fout, *ptr, fbegin[100], fend[100], fins[100], fin2[100];
float *indata, *Ghom, *shotdata, *rtrace, *costaper, scl, rho;
float dt, dx, t0, x0, xmin, xmax1, sclsxgx, f1, f2, dxrcv, dzrcv, dxpos, offset, dw, *taper;
int nshots, nt, nw, nx, ntraces, ret, ix, it, is, ir, pos, ifile, file_det, nxs, nzs, sxmin, sxmax;
int pos1, xcount, zcount, npos, zmax, file_cl, ht, inx, numb, dnumb, indrcv, shift;
int rmt, smooth, *tol, tolside, tolset, mode, ntap, maxoffset, offset_tmp, count;
complex *chom, *cshot, *ctrace;
segy *hdr_in, *hdr_out, *hdr_shot;
initargs(argc, argv);
requestdoc(1);
if (!getparstring("fin", &fin)) fin = NULL;
if (!getparstring("fshot", &fshot)) fshot = NULL;
if (!getparstring("fout", &fout)) fout = "out.su";
if (!getparint("zmax", &zmax)) zmax = 0;
if (!getparint("inx", &inx)) inx = 0;
if (!getparfloat("zrcv", &f1)) f1 = 0;
if (!getparfloat("xrcv", &f2)) f2 = 0;
if (!getparfloat("dzrcv", &dzrcv)) dzrcv = -1;
if (!getparfloat("dxrcv", &dxrcv)) dxrcv = -1;
if (!getparfloat("rho", &rho)) rho=1000.0;
if (!getparint("numb", &numb)) numb=0;
if (!getparint("dnumb", &dnumb)) dnumb=1;
if (!getparint("tolset", &tolset)) tolset=10;
if (!getparint("mode", &mode)) mode=0;
if (!getparint("ntap", &ntap)) ntap=0;
if (!getparint("maxoffset", &maxoffset)) maxoffset=0;
if (fin == NULL) verr("Incorrect f2 input");
if (fshot == NULL) verr("Incorrect Green input");
if (dnumb == 0) dnumb = 1;
sprintf(fins,"z%d",numb);
ptr = strstr(fin,fins);
pos1 = ptr - fin + 1;
sprintf(fbegin,"%*.*s", pos1-1, pos1-1, fin);
sprintf(fend,"%s", fin+pos1+1);
file_det = 1;
zcount=0;
nzs=0;
while (file_det) {
sprintf(fins,"z%d",nzs*dnumb+numb);
sprintf(fin,"%s%s%s",fbegin,fins,fend);
fp_in = fopen(fin, "r");
if (fp_in == NULL) {
if (nzs == 0) {
verr("error on opening basefile=%s", fin);
}
else if (nzs == 1) {
vmess("1 file detected");
file_det = 0;
break;
}
else {
vmess("%d files detected",nzs);
file_det = 0;
break;
}
}
fclose(fp_in);
nzs++;
}
if (inx < 1) {
inx = 1;
}
if (zmax < 1) zmax=1;
if (zmax < nzs) nzs=zmax;
nxs = inx;
count=0;
npos = nxs*nzs;
vmess("nxs: %d, nzs: %d",nxs,nzs);
nshots = 0;
getFileInfo(fshot, &nt, &nx, &nshots, &dt, &dx, &t0, &x0, &xmin, &xmax1, &sclsxgx, &ntraces);
if (dxrcv < 0) dxrcv=dx;
if (dzrcv < 0) dzrcv=dx;
// ngath zijn het aantal schoten
shotdata = (float *)malloc(nt*nx*nshots*sizeof(float));
hdr_shot = (segy *)calloc(nx*nshots,sizeof(segy));
fp_shot = fopen(fshot,"r");
if (fp_shot == NULL) {
verr("Could not open file");
}
vmess("nt: %d nx: %d nshots: %d",nt,nx,nshots);
//nx = readData(fp_shot, shotdata, hdr_shot, nt);
fclose(fp_shot);
readSnapData(fshot, &shotdata[0], &hdr_shot[0], 1, nx, nt, 0, nx, 0, nt);
hdr_out = (segy *)calloc(nxs,sizeof(segy));
Ghom = (float *)malloc(nt*npos*sizeof(float));
ht = (int)ceil(nt/2);
nw = ht+1;
dw = 2.0*(M_PI)/(dt*nt);
cshot = (complex *)malloc(nw*nx*sizeof(complex));
tol = (int *)malloc(nxs*sizeof(float));
taper = (float *)malloc(nx*sizeof(float));
/*for (ix=0; ix<nx; ix++) {
taper[ix] = 1.0;
}
if (ntap > 0) {//Create taper
vmess("Tapering of %d points applied at edges",ntap);
for (ix=0; ix<ntap; ix++) {
taper[ix] = (cos((M_PI)*(ix-ntap)/ntap)+1)/2.0;
taper[nx-1-ix] = (cos((M_PI)*(ix-ntap)/ntap)+1)/2.0;
}
}*/
for (ix = 0; ix < nx; ix++) {
/*for (it=0; it<nt; it++) {
shotdata[ix*nt+it] *= taper[ix];
}*/
if (hdr_shot[ix].scalco < 0) {
offset_tmp = (hdr_shot[ix].sx-hdr_shot[ix].gx)/-hdr_shot[ix].scalco;
}
else if (hdr_shot[ix].scalco == 0) {
offset_tmp = hdr_shot[ix].sx-hdr_shot[ix].gx;
}
else {
offset_tmp = (hdr_shot[ix].sx-hdr_shot[ix].gx)*hdr_shot[ix].scalco;
}
if (maxoffset > 0 ) {
if (abs(offset_tmp) > maxoffset) {
for (it=0;it<nt;it++) {
shotdata[ix*nt+it] = 0.0;
}
vmess("Removed offset:%d",offset_tmp);
}
}
rc1fft(&shotdata[ix*nt],&cshot[ix*nw],nt,-1);
}
#pragma omp parallel default(shared) \
private(offset,ctrace,rtrace,chom,indrcv,rmt,ix,it,is) \
private(indata, hdr_in,fins,fin2,fp_in,offset_tmp)
{
chom = (complex *)calloc(nw,sizeof(complex));
ctrace = (complex *)malloc(nw*sizeof(complex));
rtrace = (float *)malloc(nt*sizeof(float));
indata = (float *)malloc(nt*nx*nxs*sizeof(float));
hdr_in = (segy *)calloc(nx*nxs,sizeof(segy));
#pragma omp for
for (ir = 0; ir < nzs; ir++) {
sprintf(fins,"z%d",ir*dnumb+numb);
sprintf(fin2,"%s%s%s",fbegin,fins,fend);
fp_in = fopen(fin2, "r");
if (fp_in == NULL) {
verr("Danger Will Robinson");
}
fclose(fp_in);
readSnapData(fin2, &indata[0], &hdr_in[0], nxs, nx, nt, 0, nx, 0, nt);
for (is = 0; is < nxs; is++) {
for (ix = 0; ix < nx; ix++) {
/*for (it=0; it<nt; it++) {
indata[is*nt*nx+ix*nt+it] *= taper[ix];
}*/
if (hdr_in[is*nx+ix].scalco < 0) {
offset_tmp = (hdr_in[is*nx+ix].sx-hdr_in[is*nx+ix].gx)/-hdr_in[is*nx+ix].scalco;
}
else if (hdr_in[is*nx+ix].scalco == 0) {
offset_tmp = hdr_in[is*nx+ix].sx-hdr_in[is*nx+ix].gx;
}
else {
offset_tmp = (hdr_in[is*nx+ix].sx-hdr_in[is*nx+ix].gx)*hdr_in[is*nx+ix].scalco;
}
if (maxoffset > 0 ) {
if (abs(offset_tmp) > maxoffset) {
for (it=0;it<nt;it++) {
indata[is*nt*nx+ix*nt+it] = 0.0;
}
//vmess("Removed offset:%d",offset_tmp);
}
}
rc1fft(&indata[is*nt*nx+ix*nt],ctrace,nt,-1);
if (mode==0) { //Single source
for (it = 1; it < nw; it++) {
//chom[it].r += (4/(rho*dw*it))*(ctrace[it].r*cshot[ix*nw+it].i + ctrace[it].i*cshot[ix*nw+it].r);
//chom[it].r += (4/(rho*dw*it))*2*(ctrace[it].r*cshot[ix*nw+it].r - ctrace[it].i*cshot[ix*nw+it].i);
chom[it].r += 2*(ctrace[it].r*cshot[ix*nw+it].r - ctrace[it].i*cshot[ix*nw+it].i);
//chom[it].r += ctrace[it].r*cshot[ix*nw+it].r - ctrace[it].i*cshot[ix*nw+it].i;
//chom[it].r += ctrace[it].r*cshot[ix*nw+it].i + ctrace[it].i*cshot[ix*nw+it].r;
}
}
else { //Multiple sources
for (it = 0; it < nw; it++) {
/*chom[it].r -= (2/(rho*dw*it))*(ctrace[it].r*cshot[ix*nw+it].i + ctrace[it].i*cshot[ix*nw+it].r);
chom[it].i += (2/(rho*dw*it))*(ctrace[it].r*cshot[ix*nw+it].r - ctrace[it].i*cshot[ix*nw+it].i);*/
chom[it].r -= (ctrace[it].r*cshot[ix*nw+it].i + ctrace[it].i*cshot[ix*nw+it].r);
chom[it].i += (ctrace[it].r*cshot[ix*nw+it].r - ctrace[it].i*cshot[ix*nw+it].i);
}
}
}
cr1fft(&chom[0],rtrace,nt,1);
indrcv = 0;
rmt = MIN(nt-indrcv,indrcv)-shift;
for (it = 0; it < ht; it++) {
if (it > ht-rmt) {
Ghom[it*nxs*nzs+is*nzs+ir] = 0.0;
}
else {
Ghom[it*nxs*nzs+is*nzs+ir] = rtrace[ht+it];
}
}
for (it = ht; it < nt; it++) {
if (it < ht+rmt) {
Ghom[it*nxs*nzs+is*nzs+ir] = 0.0;
}
else {
Ghom[it*nxs*nzs+is*nzs+ir] = rtrace[it-ht];
}
}
memset(&chom[0].r, 0, nw*2*sizeof(float));
}
//vmess("Creating Homogeneous Green's function at depth %d from %d depths",ir+1,nzs);
count+=1;
vmess("Creating Homogeneous Green's function at depth %d from %d depths",count,nzs);
}
free(chom);free(ctrace);free(rtrace);
free(indata);free(hdr_in);
}
free(shotdata);
vmess("nxs: %d nxz: %d f1: %.7f",nxs,nzs,f1);
fp_out = fopen(fout, "w+");
for (ir = 0; ir < nt; ir++) {
for (ix = 0; ix < nxs; ix++) {
hdr_out[ix].fldr = ir+1;
hdr_out[ix].tracl = ir*nxs+ix+1;
hdr_out[ix].tracf = ix+1;
hdr_out[ix].scalco = hdr_shot[0].scalco;
hdr_out[ix].scalel = hdr_shot[0].scalel;
hdr_out[ix].sdepth = hdr_shot[0].sdepth;
hdr_out[ix].trid = 1;
hdr_out[ix].ns = nzs;
hdr_out[ix].trwf = nxs;
hdr_out[ix].ntr = hdr_out[ix].fldr*hdr_out[ix].trwf;
hdr_out[ix].f1 = f1;
hdr_out[ix].f2 = f2/1000;
hdr_out[ix].dt = dt*(1E6);
hdr_out[ix].d1 = dzrcv;
hdr_out[ix].d2 = dxrcv;
hdr_out[ix].sx = hdr_shot[0].sx;
hdr_out[ix].gx = (int)roundf(f2 + (ix*hdr_out[ix].d2)*1000.0);
hdr_out[ix].offset = (hdr_out[ix].gx - hdr_out[ix].sx)/1000.0;
}
ret = writeData(fp_out, &Ghom[ir*nxs*nzs], hdr_out, nzs, nxs);
if (ret < 0 ) verr("error on writing output file.");
}
fclose(fp_out);
return 0;
}
void convol(float *data1, float *data2, float *con, int nrec, int nsam, float dt, int shift)
{
int i, j, n, optn, nfreq, sign;
float df, dw, om, tau, scl;
float *qr, *qi, *p1r, *p1i, *p2r, *p2i, *rdata1, *rdata2;
complex *cdata1, *cdata2, *ccon, tmp;
optn = optncr(nsam);
nfreq = optn/2+1;
cdata1 = (complex *)malloc(nfreq*nrec*sizeof(complex));
if (cdata1 == NULL) verr("memory allocation error for cdata1");
cdata2 = (complex *)malloc(nfreq*nrec*sizeof(complex));
if (cdata2 == NULL) verr("memory allocation error for cdata2");
ccon = (complex *)malloc(nfreq*nrec*sizeof(complex));
if (ccon == NULL) verr("memory allocation error for ccov");
rdata1 = (float *)malloc(optn*nrec*sizeof(float));
if (rdata1 == NULL) verr("memory allocation error for rdata1");
rdata2 = (float *)malloc(optn*nrec*sizeof(float));
if (rdata2 == NULL) verr("memory allocation error for rdata2");
/* pad zeroes until Fourier length is reached */
pad_data(data1, nsam, nrec, optn, rdata1);
pad_data(data2, nsam, nrec, optn, rdata2);
/* forward time-frequency FFT */
sign = -1;
rcmfft(&rdata1[0], &cdata1[0], optn, nrec, optn, nfreq, sign);
rcmfft(&rdata2[0], &cdata2[0], optn, nrec, optn, nfreq, sign);
/* apply convolution */
p1r = (float *) &cdata1[0];
p2r = (float *) &cdata2[0];
qr = (float *) &ccon[0].r;
p1i = p1r + 1;
p2i = p2r + 1;
qi = qr + 1;
n = nrec*nfreq;
for (j = 0; j < n; j++) {
*qr = (*p2r**p1r-*p2i**p1i);
*qi = (*p2r**p1i+*p2i**p1r);
qr += 2;
qi += 2;
p1r += 2;
p1i += 2;
p2r += 2;
p2i += 2;
}
free(cdata1);
free(cdata2);
if (shift) {
df = 1.0/(dt*optn);
dw = 2*PI*df;
tau = dt*(nsam/2);
for (j = 0; j < nrec; j++) {
om = 0.0;
for (i = 0; i < nfreq; i++) {
tmp.r = ccon[j*nfreq+i].r*cos(om*tau) + ccon[j*nfreq+i].i*sin(om*tau);
tmp.i = ccon[j*nfreq+i].i*cos(om*tau) - ccon[j*nfreq+i].r*sin(om*tau);
ccon[j*nfreq+i] = tmp;
om += dw;
}
}
}
/* inverse frequency-time FFT and scale result */
sign = 1;
scl = 1.0/((float)(optn));
crmfft(&ccon[0], &rdata1[0], optn, nrec, nfreq, optn, sign);
scl_data(rdata1,optn,nrec,scl,con,nsam);
free(ccon);
free(rdata1);
free(rdata2);
return;
}
void pad_data(float *data, int nsam, int nrec, int nsamout, float *datout)
{
int it,ix;
for (ix=0;ix<nrec;ix++) {
for (it=0;it<nsam;it++)
datout[ix*nsamout+it]=data[ix*nsam+it];
for (it=nsam;it<nsamout;it++)
datout[ix*nsamout+it]=0.0;
}
}
void scl_data(float *data, int nsam, int nrec, float scl, float *datout, int nsamout)
{
int it,ix;
for (ix = 0; ix < nrec; ix++) {
for (it = 0 ; it < nsamout ; it++)
datout[ix*nsamout+it] = scl*data[ix*nsam+it];
}
}