?? segyread.c
字號:
/* Copyright (c) Colorado School of Mines, 2007.*//* All rights reserved. *//* SEGYREAD: $Revision: 1.63 $ ; $Date: 2006/10/31 22:25:37 $ */#include "su.h"#include "segy.h"#include "tapesegy.h"#include "tapebhdr.h"#include "bheader.h"#include "header.h"/*********************** self documentation **********************/char *sdoc[] = {" "," SEGYREAD - read an SEG-Y tape "," "," segyread > stdout tape= "," "," or "," "," SEG-Y data stream ... | segyread tape=- > stdout "," "," Required parameter: "," tape= input tape device or seg-y filename (see notes) "," "," Optional parameters: "," buff=1 for buffered device (9-track reel tape drive) "," =0 possibly useful for 8mm EXABYTE drives "," verbose=0 silent operation "," =1 ; echo every 'vblock' traces "," vblock=50 echo every 'vblock' traces under verbose option "," hfile=header file to store ebcdic block (as ascii) "," bfile=binary file to store binary block "," over=0 quit if bhed format not equal 1, 2, 3, 5, or 8 "," = 1 ; override and attempt conversion "," format=bh.format if over=1 try to convert assuming format value "," conv=1 convert data to native format "," = 0 ; assume data is in native format "," ns=bh.hns number of samples (use if bhed ns wrong) "," trcwt=1 apply trace weighting factor (bytes 169-170) "," =0, do not apply. (Default is 0 for formats 1 and 5) "," trmin=1 first trace to read "," trmax=INT_MAX last trace to read "," endian=1 set =0 for little-endian machines(PC's,DEC,etc.) "," errmax=0 allowable number of consecutive tape IO errors "," remap=...,... remap key(s) "," byte=...,... formats to use for header remapping "," "," Notes: "," Traditionally tape=/dev/rmt0. However, in the modern world tape device"," names are much less uniform. The magic name can often be deduced by "," \"ls /dev\". Likely man pages with the names of the tape devices are:"," \"mt\", \"sd\" \"st\". Also try \"man -k scsi\", \" man mt\", etc. "," Sometimes \"mt status\" will tell the device name. "," "," For a SEG-Y diskfile use tape=filename. "," "," Remark: a SEG-Y file is not the same as an su file. A SEG-Y file "," consists of three parts: an ebcdic header, a binary reel header, and "," the traces. The traces are (usually) in 32 bit IBM floating point "," format. An SU file consists only of the trace portion written in the "," native binary floats. "," "," Formats supported: "," 1: IBM floating point, 4 byte (32 bits) "," 2: two's complement integer, 4 byte (32 bits) "," 3: two's complement integer, 2 byte (16 bits) "," 5: IEEE floating point, 4 byte (32 bits) "," 8: two's complement integer, 1 byte (8 bits) "," "," tape=- read from standard input. Caveat, under Solaris, you will "," need to use the buff=1 option, as well. "," "," Header remap: "," The value of header word remap is mapped from the values of byte "," "," Map a float at location 221 to sample spacing d1: "," segyread <data >outdata remap=d1 byte=221f "," "," Map a long at location 225 to source location sx: "," segyread <data >outdata remap=sx byte=225l "," "," Map a short at location 229 to gain constant igc: "," segyread <data >outdata remap=igc byte=229s "," "," Or all combined: "," segyread <data >outdata remap=d1,sx,igc byte=221f,225l,229s "," "," Segy header words are accessed as Xt where X denotes the byte number "," starting at 1 in correspondance with the SEGY standard (1975) "," Known types include: f float (4 bytes) "," l long int (4 bytes) "," s short int (2 bytes) "," b byte (1 bytes) "," "," type: sudoc segyread for further information "," ",NULL};/* * Note: * If you have a tape with multiple sequences of ebcdic header, * binary header,traces, use the device that * invokes the no-rewind option and issue multiple segyread * commands (making an appropriate shell script if you * want to save all the headers). Consider using >> if * you want a single trace file in the end. Similar * considerations apply for multiple reels of tapes, * but use the standard rewind on end of file. * * Note: For buff=1 (default) tape is accessed with 'read', for buff=0 * tape is accessed with fread. We suggest that you try buff=1 * even with EXABYTE tapes. * Caveat: may be slow on an 8mm streaming (EXABYTE) tapedrive * Warning: segyread or segywrite to 8mm tape is fragile. Allow sufficient * time between successive reads and writes. * Warning: may return the error message "efclose: fclose failed" * intermittently when segyreading/segywriting to 8mm (EXABYTE) tape * even if actual segyread/segywrite is successful. However, this * error message may be returned if your tape drive has a fixed * block size set. * Caution: When reading or writing SEG-Y tapes, the tape * drive should be set to be able to read variable block length * tape files. *//* Credits: * SEP: Einar Kjartansson * CWP: Jack K. Cohen, Brian Sumner, Chris Liner * : John Stockwell (added 8mm tape stuff) * conv parameter added by: * Tony Kocurko * Department of Earth Sciences * Memorial University of Newfoundland * St. John's, Newfoundland * read from stdin via tape=- added by Tony Kocurko * bhed format = 2,3 conversion by: * Remco Romijn (Applied Geophysics, TU Delft) * J.W. de Bruijn (Applied Geophysics, TU Delft) * bhed format = 8 conversion by: John Stockwell * header remap feature added by: * Matthias Imhof, Virginia Tech *-------------------------- * Additional Notes: * Brian's subroutine, ibm_to_float, which converts IBM floating * point to IEEE floating point is NOT portable and must be * altered for non-IEEE machines. See the subroutine notes below. * * A direct read by dd would suck up the entire tape; hence the * dancing around with buffers and files. * *//**************** end self doc ***********************************//* Subroutine prototypes */static void ibm_to_float(int from[], int to[], int n, int endian);static void long_to_float(long from[], float to[], int n, int endian);static void short_to_float(short from[], float to[], int n, int endian);static void integer1_to_float(signed char from[], float to[], int n);static void tapebhed_to_bhed(const tapebhed *tapebhptr, bhed *bhptr);static void tapesegy_to_segy(const tapesegy *tapetrptr, segy *trptr);static void ugethval(cwp_String type1, Value *valp1, char type2, int ubyte, char *tr, int endian, int conv);/* Globals */tapesegy tapetr;tapebhed tapebh;segy tr;bhed bh;intmain(int argc, char **argv){ char *tape; /* name of raw tape device */ char *bfile; /* name of binary header file */ char *hfile; /* name of ascii header file */ int tapefd=0; /* file descriptor for tape */ FILE *tapefp=NULL; /* file pointer for tape */ FILE *binaryfp; /* file pointer for bfile */ FILE *headerfp; /* file pointer for hfile */ FILE *pipefp; /* file pointer for popen write */ size_t nsegy; /* size of whole trace in bytes */ int i; /* counter */ int itr; /* current trace number */ int trmin; /* first trace to read */ int trmax; /* last trace to read */ int ns; /* number of data samples */ int over; /* flag for bhed.float override */ int format; /* flag for to specify override format */ cwp_Bool format_set = cwp_false; /* flag to see if new format is set */ int conv; /* flag for data conversion */ int trcwt; /* flag for trace weighting */ int verbose; /* echo every ... */ int vblock; /* ... vblock traces with verbose=1 */ int buff; /* flag for buffered/unbuffered device */ int endian; /* flag for big=1 or little=0 endian */ int errmax; /* max consecutive tape io errors */ int errcount = 0; /* counter for tape io errors */ cwp_Bool nsflag; /* flag for error in tr.ns */ char cmdbuf[BUFSIZ]; /* dd command buffer */ char ebcbuf[EBCBYTES]; /* ebcdic data buffer */ cwp_String key1[SU_NKEYS]; /* output key(s) */ cwp_String key2[SU_NKEYS]; /* first input key(s) */ cwp_String type1[SU_NKEYS]; /* array of types for key1 */ char type2[SU_NKEYS]; /* array of types for key2 */ int ubyte[SU_NKEYS]; int nkeys; /* number of keys to be computed*/ int n; /* counter of keys getparred */ int ikey; /* loop counter of keys */ int index1[SU_NKEYS]; /* array of indexes for key1 */ Value val1; /* value of key1 */ /* Initialize */ initargs(argc, argv); requestdoc(0); /* stdin not used */ /* Make sure stdout is a file or pipe */ switch(filestat(STDOUT)) { case TTY: err("stdout can't be tty"); break; case DIRECTORY: err("stdout must be a file, not a directory"); break; case BADFILETYPE: err("stdout is illegal filetype"); break; default: /* Others OK */ break; } /* Set filenames */ MUSTGETPARSTRING("tape", &tape); if (!getparstring("hfile", &hfile)) hfile = "header"; if (!getparstring("bfile", &bfile)) bfile = "binary"; /* Set parameters */ if (!getparint("trmin", &trmin)) trmin = 1; if (!getparint("trmax", &trmax)) trmax = INT_MAX; if (!getparint("verbose", &verbose)) verbose = 0; if (!getparint("vblock", &vblock)) vblock = 50; if (!getparint("endian", &endian)) endian = 1; if (!getparint("errmax", &errmax)) errmax = 0; if (!getparint("buff", &buff)) buff = 1; /* Override binary format value */ if (!getparint("over", &over)) over = 0; if (getparint("format", &format)) format_set = cwp_true; if (((over!=0) && (format_set))) { bh.format = format; if ( !( (format==1) || (format==2) || (format==3) || (format==5) || (format==8) ) ) { warn("Specified format=%d not supported", format); warn("Assuming IBM floating point format, instead"); } } /* Override conversion of IBM floating point data? */ if (!getparint("conv", &conv)) conv = 1; /* Get parameters */ /* get key1's */ if ((n=countparval("remap"))!=0){ nkeys=n; getparstringarray("remap",key1); } else { /* set default */ nkeys=0; } /* get key2's */ if ((n=countparval("byte"))!=0){ if (n!=nkeys) err("number of byte's and remap's must be equal!"); getparstringarray("byte",key2); } for (ikey=0; ikey<nkeys; ++ikey) { /* get types and index values */ type1[ikey] = hdtype(key1[ikey]); index1[ikey] = getindex(key1[ikey]); } for (ikey=0; ikey<nkeys; ++ikey) { #if 0 fprintf(stderr, "%s\t", key2[ikey]); #endif if (sscanf(key2[ikey],"%d%c",&ubyte[ikey],&type2[ikey])!=2) err("user format XXXt"); #if 0 sscanf(key2[ikey],"%d%c",&ubyte[ikey],&type2[ikey]); fprintf(stderr, "%d\t%c\n", ubyte[ikey], type2[ikey]); #endif } /* Open files - first the tape */ if (buff) { if ( tape[0] == '-' && tape[1] == '\0' ) tapefd = 0; else tapefd = eopen(tape, O_RDONLY, 0444); } else { if ( tape[0] == '-' && tape[1] == '\0' ) tapefp = stdin; else tapefp = efopen(tape, "r"); } /* - the ebcdic header file in ascii */ headerfp = efopen(hfile, "w"); if (verbose) warn("header file opened successfully"); /* - the binary data file */ binaryfp = efopen(bfile, "w"); if (verbose) warn("binary file opened successfully"); /* Read the ebcdic raw bytes from the tape into the buffer */ if (buff) { if (-1 == (int) read(tapefd, ebcbuf, EBCBYTES)) { if (verbose) warn("tape read error on ebcdic header"); if (++errcount > errmax) err("exceeded maximum io errors"); } else { /* Reset counter on successful tape IO */ errcount = 0; } } else { (int) fread(ebcbuf, 1, EBCBYTES, tapefp); if (ferror(tapefp)) { if (verbose) warn("tape read error on ebcdic header"); if (++errcount > errmax) err("exceeded maximum io errors"); clearerr(tapefp); } else { /* Reset counter on successful tape IO */ errcount = 0; } } /* Open pipe to use dd to convert ascii to ebcdic */ sprintf(cmdbuf, "dd ibs=3200 of=%s conv=ascii cbs=80 count=1", hfile); pipefp = epopen(cmdbuf, "w"); /* Write ebcdic stream from buffer into pipe */ efwrite(ebcbuf, EBCBYTES, 1, pipefp); /* Read binary header from tape to bh structure */ if (buff) { if (-1 == read(tapefd, (char *) &tapebh, BNYBYTES)) { if (verbose) warn("tape read error on binary header"); if (++errcount > errmax) err("exceeded maximum io errors"); } else { /* Reset counter on successful tape IO */ errcount = 0; } } else { fread((char *) &tapebh, 1, BNYBYTES, tapefp); if (ferror(tapefp)) { if (verbose) warn("tape read error on binary header"); if (++errcount > errmax) err("exceeded maximum io errors"); clearerr(tapefp); } else { /* Reset counter on successful tape IO */ errcount = 0; } } /* Convert from bytes to ints/shorts */ tapebhed_to_bhed(&tapebh, &bh); /* if little endian machine, swap bytes in binary header */ if (endian==0) for (i = 0; i < BHED_NKEYS; ++i) swapbhval(&bh,i); /* Override binary format value */ if (!getparint("over", &over)) over = 0; if (getparint("format", &format)) format_set = cwp_true; if (((over!=0) && (format_set))) bh.format = format; /* Override application of trace weighting factor? */ /* Default no for floating point formats, yes for integer formats. */ if (!getparint("trcwt",&trcwt)) trcwt = (bh.format==1 || bh.format==5) ? 0 : 1; switch (bh.format) { case 1: if (verbose) warn("assuming IBM floating point input"); break; case 2: if (verbose) warn("assuming 4 byte integer input"); break; case 3: if (verbose) warn("assuming 2 byte integer input"); break; case 5: if (verbose) warn("assuming IEEE floating point input"); break; case 8: if (verbose) warn("assuming 1 byte integer input"); break; default: (over) ? warn("ignoring bh.format ... continue") : err("format not SEGY standard (1, 2, 3, 5, or 8)"); } /* Compute length of trace (can't use sizeof here!) */ if (!getparint("ns", &ns)) ns = bh.hns; /* let user override */ if (!ns) err("samples/trace not set in binary header"); bh.hns = ns; switch (bh.format) { case 8: nsegy = ns + SEGY_HDRBYTES; break; case 3: nsegy = ns*2 + SEGY_HDRBYTES; break; case 1: case 2: case 5: default: nsegy = ns*4 + SEGY_HDRBYTES; } /* Write binary header from bhed structure to binary file */ efwrite( (char *) &bh,1, BNYBYTES, binaryfp); /* Close binary and header files now to allow pipe into segywrite */ efclose(binaryfp); if (verbose) warn("binary file closed successfully"); efclose(headerfp); epclose(pipefp); if (verbose) warn("header file closed successfully"); /* Read the traces */ nsflag = cwp_false;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -