static void seektable(int dim, off_t *n, int *m, off_t *f, int *j, int n1, int n2, int n3, off_t *table) { off_t t, t2; int i2, i, ii[SF_MAX_DIM]; t2 = sf_large_cart2line (dim-1, n+1, f+1); table[0] = t2*n[0] + f[0]; for (i2=1; i2 < n2; i2++) { t = i2; for (i = 1; i < dim-1; i++) { /* cartesian coordinates in window */ ii[i] = t%m[i]; t /= m[i]; } t = f[dim-1] + t*j[dim-1]; for (i = dim-2; i >= 1; i--) { /* line coordinates in input */ t = t*n[i] + f[i] + ii[i]*j[i]; } table[i2] = (t-t2)*n[0]-n1; t2 = t; } table[n2] = (n3-t2)*n[0]-f[0]-n1; }
int main(int argc, char* argv[]) { sf_file in=NULL, out=NULL; int n1_traces; int n1_headers; char* header_format=NULL; sf_datatype typehead; /* kls do I need to add this? sf_datatype typein; */ float* fheader=NULL; float* intrace=NULL; int dim; off_t n_in[SF_MAX_DIM]; int iaxis; int dim_output; int *indx_of_keys; bool label_argparmread,n_argparmread,o_argparmread,d_argparmread; char parameter[13]; char* label[SF_MAX_DIM]; off_t n_output[SF_MAX_DIM]; off_t n_outheaders[SF_MAX_DIM]; float o_output[SF_MAX_DIM]; float d_output[SF_MAX_DIM]; sf_axis output_axa_array[SF_MAX_DIM]; sf_file output=NULL, outheaders=NULL; char* output_filename=NULL; char* outheaders_filename=NULL; sf_init (argc,argv); /*****************************/ /* initialize verbose switch */ /*****************************/ /* verbose flag controls ammount of print */ /*( verbose=1 0 terse, 1 informative, 2 chatty, 3 debug ) */ /* fprintf(stderr,"read verbose switch. getint reads command line.\n"); */ if(!sf_getint("verbose",&verbose))verbose=1; /* \n flag to control amount of print 0 terse, 1 informative, 2 chatty, 3 debug */ fprintf(stderr,"verbose=%d\n",verbose); /******************************************/ /* input and output data are stdin/stdout */ /******************************************/ if(verbose>0)fprintf(stderr,"read infile name\n"); in = sf_input ("in"); if(verbose>0) fprintf(stderr,"read outfile name (probably default to stdout\n"); out = sf_output ("out"); if (!sf_histint(in,"n1_traces",&n1_traces)) sf_error("input data not define n1_traces"); if (!sf_histint(in,"n1_headers",&n1_headers)) sf_error("input data does not define n1_headers"); header_format=sf_histstring(in,"header_format"); if(strcmp (header_format,"native_int")==0) typehead=SF_INT; else typehead=SF_FLOAT; fprintf(stderr,"allocate headers. n1_headers=%d\n",n1_headers); fheader = sf_floatalloc(n1_headers); fprintf(stderr,"allocate intrace. n1_traces=%d\n",n1_traces); intrace= sf_floatalloc(n1_traces); /* maybe I should add some validation that n1== n1_traces+n1_headers+2 and the record length read in the second word is consistent with n1. */ /* put the history from the input file to the output */ sf_fileflush(out,in); /********************************************************************/ /* set up the output and outheaders files for the traces and headers */ /********************************************************************/ output_filename=sf_getstring("output"); /* \n output trace filename. Required parameter with no default. */ if(NULL==output_filename) sf_error("output is a required parameter"); output=sf_output(output_filename); outheaders_filename=sf_getstring("outheaders"); /* \n Output trace header file name. Default is the input data file name, with the final .rsf changed to _hdr.rsf. */ if(outheaders_filename==NULL){ /* compute headers_filename from output_filename by replacing the final .rsf with _hdr.rsf */ if(!(0==strcmp(output_filename+strlen(output_filename)-4,".rsf"))){ fprintf(stderr,"parameter output, the name of the output file,\n"); fprintf(stderr,"does not end with .rsf, so header filename cannot\n"); fprintf(stderr,"be computed by replacing the final .rsf with\n"); fprintf(stderr,"_hdr.rsf.\n"); sf_error("default for outheaders parameter cannot be computed."); } outheaders_filename=malloc(strlen(output_filename)+60); strcpy(outheaders_filename,output_filename); strcpy(outheaders_filename+strlen(output_filename)-4,"_hdr.rsf\0"); if(verbose>1) fprintf(stderr,"parameter outheader defaulted. Computed to be #%s#\n", outheaders_filename); } if(verbose>1)fprintf(stderr,"parameter outheader input or computed #%s#\n", outheaders_filename); outheaders=sf_output(outheaders_filename); /* get each of the axis information: label2, n2, o2, d2, label3, n3, o3, d3, etc label1, n1, o1, d1 is always defaulted from input */ sf_putint (output ,"n1" ,n1_traces ); sf_putint (outheaders,"n1" ,n1_headers); sf_putfloat (outheaders,"d1" ,1 ); sf_putfloat (outheaders,"o1" ,0 ); sf_putstring(outheaders,"label1","none" ); sf_putstring(outheaders,"unit1" ,"none" ); dim_output=1; for (iaxis=1; iaxis<SF_MAX_DIM; iaxis++){ label_argparmread=n_argparmread=o_argparmread=d_argparmread=false; sprintf(parameter,"label%d",iaxis+1); fprintf(stderr,"try to read %s\n",parameter); if ((label[iaxis]=sf_getstring(parameter))) { /*(label#=(2,...) name of each of the axes. label1 is not changed from input. Each label must be a header key like cdp, cdpt, or ep. The trace header values are used to define the output trace location in the output file. )*/ fprintf(stderr,"got %s=%s\n",parameter,label[iaxis]); sf_putstring(output ,parameter,label[iaxis]); sf_putstring(outheaders,parameter,label[iaxis]); label_argparmread=true; } sprintf(parameter,"n%d",iaxis+1); fprintf(stderr,"try to read %s\n",parameter); if (sf_getlargeint (parameter,&n_output[iaxis])) { /*( n#=(2,...) number of locations in the #-th dimension )*/ fprintf(stderr,"got %s=%lld\n",parameter,(long long) n_output[iaxis]); sf_putint(output ,parameter,n_output[iaxis]); sf_putint(outheaders,parameter,n_output[iaxis]); n_argparmread=true; } sprintf(parameter,"o%d",iaxis+1); if (sf_getfloat(parameter,&o_output[iaxis])) { /*( o#=(2,...) origin of the #-th dimension )*/ sf_putfloat(output ,parameter,o_output[iaxis]); sf_putfloat(outheaders,parameter,o_output[iaxis]); o_argparmread=true; } sprintf(parameter,"d%d",iaxis+1); if (sf_getfloat(parameter,&d_output[iaxis])) { /*( d#=(2,...) delta in the #-th dimension )*/ sf_putfloat(output ,parameter,d_output[iaxis]); sf_putfloat(outheaders,parameter,d_output[iaxis]); d_argparmread=true; } if(!label_argparmread && !n_argparmread && ! o_argparmread && !d_argparmread){ /* none of the parameter were read you read all the parameters in the previous iteration compute the output dimension and exit the loop */ dim_output=iaxis; break; } if(label_argparmread && n_argparmread && o_argparmread && d_argparmread){ /* all the parameters for thisi axis were read. loop for next iaxis */ if(verbose>0){ fprintf(stderr,"label, n, i, and d read for iaxis%d\n",iaxis+1); } } else { sf_warning("working on iaxis=%d. Program expects to read\n",iaxis+1); sf_warning("label%d, n%d, i%d, and d%d from command line.\n", iaxis+1,iaxis+1,iaxis+1,iaxis+1); if(!label_argparmread) sf_error("unable to read label%d\n",iaxis+1); if(!n_argparmread ) sf_error("unable to read n%d \n",iaxis+1); if(!o_argparmread ) sf_error("unable to read o%d \n",iaxis+1); if(!d_argparmread ) sf_error("unable to read d$d \n",iaxis+1); } } /* if the input file is higher dimention than the output, then the size of all the higher dimensions must be set to 1. */ /* kls use sf_axis to get structure for each axis with n, o, d, l, and u this can be used to compute the index for sf_seek */ dim = sf_largefiledims(in,n_in); for (iaxis=dim_output; iaxis<dim; iaxis++){ sprintf(parameter,"n%d",iaxis+1); sf_putint(output,parameter,1); sf_putint(outheaders,parameter,1); } /* for a test zero n_output and dim_output and see it you can read the history file */ sf_largefiledims(output,n_output); sf_largefiledims(outheaders,n_outheaders); if(verbose>1){ for (iaxis=0; iaxis<SF_MAX_DIM; iaxis++){ fprintf(stderr,"from sf_largefiledims(output.. n%d=%lld outheaders=%lld\n", iaxis+1,(long long) n_output[iaxis],(long long) n_outheaders[iaxis]); } } /* the list header keys (including any extras) and get the index into the header vector */ segy_init(n1_headers,in); indx_of_keys=sf_intalloc(dim_output); for (iaxis=1; iaxis<dim_output; iaxis++){ /* kls need to check each of these key names are in the segy header and make error message for invalid keys. Of does segykey do this? NO, just segmentation fault. */ if(verbose>0)fprintf(stderr,"get index of key for %s\n",label[iaxis]); indx_of_keys[iaxis]=segykey(label[iaxis]); } sf_fileflush(output,in); sf_putint(outheaders,"n1",n1_headers); if(0==strcmp("native_int",sf_histstring(in,"header_format"))){ sf_settype(outheaders,SF_INT); } else { sf_settype(outheaders,SF_FLOAT); } sf_fileflush(outheaders,in); fprintf(stderr,"start trace loop\n"); /* kls maybe this should be in function sf_tahwritemapped_init */ { off_t file_offset; off_t i_output[SF_MAX_DIM]; float temp_float=0.0; for(iaxis=0; iaxis<SF_MAX_DIM; iaxis++){ i_output[iaxis]=n_output[iaxis]-1; } file_offset=sf_large_cart2line(dim_output,n_output,i_output)*sizeof(float); sf_seek(output,file_offset,SEEK_SET); sf_floatwrite(&temp_float,1,output); i_output[0]=n_outheaders[0]-1; file_offset=sf_large_cart2line(dim_output,n_outheaders,i_output)* sizeof(float); sf_seek(outheaders,file_offset,SEEK_SET); sf_floatwrite(&temp_float,1,outheaders); } for (iaxis=0; iaxis<SF_MAX_DIM; iaxis++){ /* sf_axis temp; */ output_axa_array[iaxis]=sf_iaxa(output,iaxis+1); if(verbose>2){ /* temp=output_axa_array[iaxis]; */ fprintf(stderr,"axis=%d sf_n(output_axa_array[iaxis])=%d\n", iaxis+1,sf_n(output_axa_array[iaxis])); } /* kls why does this fail? fprintf(stderr,"temp->n=%d\n",temp->n); */ } /***************************/ /* start trace loop */ /***************************/ fprintf(stderr,"start trace loop\n"); while (0==get_tah(intrace, fheader, n1_traces, n1_headers, in)){ if(verbose>1){ for(iaxis=2; iaxis<dim_output; iaxis++){ fprintf(stderr,"label[%d]=%s", iaxis,label[iaxis]); if(typehead == SF_INT)fprintf(stderr,"%d", ((int*)fheader)[indx_of_keys[iaxis]]); else fprintf(stderr,"%f", fheader[indx_of_keys[iaxis]]); } fprintf(stderr,"\n"); } tahwritemapped(verbose,intrace, fheader, n1_traces, n1_headers, output, outheaders, typehead, output_axa_array, indx_of_keys, dim_output, n_output,n_outheaders); /**********************************************/ /* write trace and headers to the output pipe */ /**********************************************/ put_tah(intrace, fheader, n1_traces, n1_headers, out); } exit(0); }
void tahwritemapped(int verbose, float* trace, void* iheader, int n1_traces, int n1_headers, sf_file output,sf_file outheaders, sf_datatype typehead, sf_axis* output_axa_array, int* indx_of_keys, int dim_output, off_t* n_output, off_t* n_outheaders) /*< tah write mapped >*/ { int iaxis; double header[SF_MAX_DIM]; off_t i_output[SF_MAX_DIM]; off_t file_offset; bool trace_fits_in_output_file; static int number_traces_rejected=0; if(verbose>2) for (iaxis=0; iaxis<SF_MAX_DIM; iaxis++){ fprintf(stderr,"axis=%d sf_n(output_axa_array[iaxis])=%d\n", iaxis+1,sf_n(output_axa_array[iaxis])); } /* compute the i_output, the output trace index array. Use the trace headers and axis definitions. Axis definitions are label#, n#, o#, and d# */ /* make sure the trace fits in the output file. A trace does not fit if if falls outside the range defined by n#, o#, and d#. A trace must fall on the o#, d# locations (ie if you say o1=10 d1=10 n1=10, traces -500, 10000, and 15 do not fit in the output file. */ trace_fits_in_output_file=true; i_output[0]=0; for (iaxis=1; iaxis<dim_output; iaxis++){ double doubleindex; if(SF_INT == typehead) header[iaxis]=(double)(((int *)iheader)[indx_of_keys[iaxis]]); else header[iaxis]=(double)(((float*)iheader)[indx_of_keys[iaxis]]); doubleindex=(header[iaxis]-sf_o(output_axa_array[iaxis]))/ sf_d(output_axa_array[iaxis]); i_output[iaxis]=llround(doubleindex); if(0.01<fabs(doubleindex-i_output[iaxis]) || i_output[iaxis]<0 || i_output[iaxis]>=sf_n(output_axa_array[iaxis]) ){ trace_fits_in_output_file=false; number_traces_rejected++; if(number_traces_rejected<10){ fprintf(stderr,"trace rejection #%d\n",number_traces_rejected); } if(number_traces_rejected==10){ fprintf(stderr,"another rejected trace. reporting will stop.\n"); } break; } if(verbose>2){ fprintf(stderr,"iaxis=%d n=%d o=%f d=%f header=%f \n", iaxis, sf_n(output_axa_array[iaxis]), sf_o(output_axa_array[iaxis]), sf_d(output_axa_array[iaxis]), header[iaxis]); } } /* kls need to check doubleindex is about the same as i_output[iaxis] this will allow you to write every third trace to an output file by using a large increment. This is good to write gathers every km for velocity analysis of qc. kls also need to check index is in the range [0,sf_n(output_axa_array[iaxis]) */ /* kls why does this fail? fprintf(stderr,"axis=%d output_axa_array[iaxis]->n=%d\n", iaxis+1,output_axa_array[iaxis]->n); */ if(trace_fits_in_output_file){ file_offset=sf_large_cart2line(dim_output,n_output,i_output)*sizeof(float); if(verbose>2)fprintf(stderr,"file_offset=%lld\n",(long long) file_offset); sf_seek(output,file_offset,SEEK_SET); sf_floatwrite(trace,n1_traces,output); file_offset=sf_large_cart2line(dim_output,n_outheaders,i_output)* sizeof(float); sf_seek(outheaders,file_offset,SEEK_SET); if(SF_INT == typehead) sf_intwrite ((int *)iheader,n1_headers,outheaders); else sf_floatwrite((float*)iheader,n1_headers,outheaders); if(verbose>2){ for(iaxis=2; iaxis<dim_output; iaxis++){ fprintf(stderr,"indx_of_keys[%d]=%d ", iaxis,indx_of_keys[iaxis]); if(typehead == SF_INT)fprintf(stderr,"%d\n", ((int *)iheader)[indx_of_keys[iaxis]]); else fprintf(stderr,"%g\n", ((float*)iheader)[indx_of_keys[iaxis]]); } fprintf(stderr,"\n"); } } }