/* qmipstosegy * * qmips format to segy format conversion program. * * * Options: -f first_rec First record to examine * -c create a SEGY disk file * -t create a SEGY tape file * -d decimate the input qmips file to disk file * * * TFO USGS 8 November 1994. Modified listqmips for conversion * * TFO USGS 12 June 1998. Modified to zeropad output array for pressure depth * */ #include #include #include #include #include #include #include #include #include "segy.h" #include "ebcdic.h" #include "sonar.h" #include "getqmips.c" #define QMIPS_FOOTER_SIZE 256 /* * Ellipsoid definitions */ #define WGS84 1 #define CLARKE1866 2 char *progname; BCDHeader bhead, *bcdhead = &bhead; typedef union { ShotHeader thead; float dummies[60]; } ForceFloat; ForceFloat floatSegy; main (argc, argv) int argc; char **argv; { int i; int j; int c; int in_fd; /* file descriptor */ int outlu; int loglu; /* segy logger file i.d. */ int start_rec; int recs_to_disk; /* scan counter */ int recs_to_tape; int count; int recsread; int bytes_written; int bytes_read; int char_holder; /* used to find the filename from header */ int numberOfBits; int numberOfPixels; int numberOfSamples; int numberOfChannels; int zeroPad; /* how much memory to clear for water column */ int tseq_reel; int tseq_line; int pingNum; int asciiIndex; int outflag; int tape_flag; int decimate_flag; int decimate_factor; int decimate_count; int julianDay; int year; int inbytes; int channelNumber; int doShorts; int doFloats; ShotHeader *THead; short sweepLength; short origSweepLength; short sampInterval; unsigned short minValue, maxValue; unsigned short pixelValue; extern int optind; /* used by getopt() */ extern char *optarg; off_t offset; /* offset for seeking starting record */ off_t where; off_t current_pos; off_t lseek(); char filename[255]; /* used to hold filename from header */ char segyFile[255]; /* used to hold filename from header */ char *namePtr; char samps_per_shot[10]; char *file_ptr, *tempPtr; char tempFileName[255]; char *ebcdic[3200]; /* ebcdic header */ char ebcbuf[3200]; char *tape_name; char goodHead; char tempBuffer[21]; unsigned char header[HEADSIZE]; unsigned char footer[QMIPS_FOOTER_SIZE]; unsigned char *inbuf; /* float convertToVolts = 0.0048828125 / 8; */ float convertToVolts; float tempFloat; float delayFloat; float oldDelayFloat; double lon, lat, oldlat, oldlon; double centralLon; double course, shipsSpeed; double distanceTravelled; double east, north, previousEast, previousNorth; double sonarRange; double metersPerPixel; double maxDepth; int ellipsoid; float get_float (); double get_double (); short get_short (); float floatFlip(); double getcentlon(); void err_exit (); void ascebc (); void ieeibm (); void getBuffer(); void exit(); void geoutm(); /* * Process arguments */ THead = &floatSegy.thead; sweepLength = 0; minValue = 32767; maxValue = 0; tseq_reel = 1; tseq_line = 1; outflag = 0; tape_flag = 0; decimate_flag = 0; decimate_factor = 1; decimate_count = 0; start_rec = 0; recs_to_disk = 0; /* scan counter */ recs_to_tape = 0; recsread = 0; convertToVolts = 0.0; channelNumber = 3; doFloats = 0; doShorts = 0; oldlat = 0; oldlon = 0; previousEast = 0; previousNorth = 0; year = 0; julianDay = 0; zeroPad = 0; maxDepth = 0; pingNum = 0; progname = argv[0]; while ((c = getopt (argc, argv, "FIf:d:t:cv:S:J:Y:")) != EOF) { switch (c) { case 'F': doFloats++; break; case 'I': doShorts++; break; case 'f': start_rec = atoi (optarg); fprintf (stdout, "start record = %d\n", start_rec); break; case 'd': decimate_flag++; decimate_factor = atoi (optarg); /* fprintf(stdout,"decimate factor = %d\n", decimate_factor); */ break; case 't': tape_flag++; tape_name = (char *) optarg; /* fprintf (stdout,"tape name = %s\n", tape_name); */ break; case 'c': outflag++; break; case 'v': convertToVolts = atof (optarg); break; case 'S': origSweepLength = (short) atoi (optarg); break; case 'Y': year = (short) atoi (optarg); break; case 'J': julianDay = (short) atoi (optarg); break; case '?': err_exit (); break; } } if ((argc - optind) < 1) err_exit (); if(INTEL) fprintf(stderr, "machine byte order is INTEL\n"); else if (MOTOROLA) fprintf(stderr, "machine byte order is MOTOROLA\n"); else { fprintf(stderr, "machine byte order is UNDEFINED\n"); fprintf(stderr, "Exiting...check sonar_struct.h for machine type."); } /* * If sweep length was not entered, exit. */ if(!origSweepLength) { fprintf(stdout,"\nMust choose a sweep length.\n"); fflush (stdout); err_exit (); } /* * open the disk file for saving converted Qmips data * to SEGY and also check if user wants to log SEGY * to an output file, ie. 8mm tape */ if ((in_fd = open (argv[optind], O_RDONLY)) == -1) { fprintf (stderr, "%s: cannot open %s\n", argv[optind], progname); perror ("open"); err_exit (); } optind++; /* bump pointer */ /* Get past the western digital file header */ if (read (in_fd, header, HEADSIZE) != HEADSIZE) { fprintf (stderr, "%s: error in input buffer\n", progname); perror ("read"); err_exit (); } goodHead = header[0]; if (goodHead != 50) { /* get the qmips file header */ if (read (in_fd, header, HEADSIZE) != HEADSIZE) { fprintf (stderr, "%s: error in input buffer\n", progname); perror ("read"); err_exit (); } } /* * Get the current position to revert to before main * processing begins. */ current_pos = lseek(in_fd, 0L, SEEK_CUR); /* * Get the size of each ping */ numberOfBits = get_short (&header[32]); numberOfChannels = get_short (&header[30]); numberOfPixels = get_short (&header[34]); numberOfSamples = numberOfPixels; /* Do this to remember original */ /* number of samples in shot */ fprintf (stdout, " %d %d %d \n", numberOfBits, numberOfChannels, numberOfPixels); if (numberOfChannels < 2) { fprintf (stderr, "Sorry no subbottom in this file\n"); fflush (stderr); exit (0); } if (numberOfBits == 16) { RAWDATASIZE = (numberOfChannels * numberOfPixels * sizeof (short)); TRECSIZE = RAWDATASIZE + 256; /* fprintf (stdout, "TRECSIZE = %d\n", TRECSIZE); */ SUB_BOTTOM_OFFSET = ((channelNumber - 1) * numberOfPixels * sizeof (short)); DATASIZE = numberOfPixels * sizeof (short); /* * Convert to volts: 10 / 32768 = 10 volt range normalized to 2 ^ 15 */ if(!convertToVolts) convertToVolts = .003051757; /* Allocate some memory for input buffer */ inbuf = (unsigned char *) calloc (DATASIZE, sizeof (unsigned char)); if (inbuf == NULL) { fprintf (stdout, "Error allocating memory\n"); fflush (stdout); perror ("reason"); exit (0); } fprintf (stderr, "bits = 16, size = %d\n", DATASIZE); } else if (numberOfBits == 8) { RAWDATASIZE = (numberOfChannels * numberOfPixels * sizeof (char)); TRECSIZE = RAWDATASIZE + 256; SUB_BOTTOM_OFFSET = ((channelNumber - 1) * numberOfPixels * sizeof (char)); DATASIZE = numberOfPixels * sizeof (char); inbuf = (unsigned char *) calloc (DATASIZE + 1, sizeof (char)); if(!convertToVolts) convertToVolts = .0390625; fprintf (stderr, "bits = 8, size = %d\n", DATASIZE); } else { fprintf (stderr, "don't know about number of bits\n"); fflush (stderr); err_exit (); } /* * Get filename from sonar header (this does not work with this older * data set... no filename was saved in the header!) */ i = 484; file_ptr = filename; char_holder = header[484]; namePtr = (char *) &header[484]; strcpy(tempFileName, namePtr); if((tempPtr = strrchr(tempFileName, '\\')) == NULL && (tempPtr = strrchr(tempFileName, '/')) == NULL && (tempPtr = strrchr(tempFileName, ':')) == NULL) tempPtr = tempFileName; else tempPtr++; while (char_holder != 46) char_holder = *file_ptr++ = tolower(*tempPtr++); *file_ptr = '\0'; fprintf (stdout, " Qmips file I.D. is %s \n", filename); strcpy(segyFile, filename); if (outflag) { strcat (segyFile, "sgy"); fprintf (stdout, "Creating disk file for processing %s\n", filename); } /* * Open output disk file if we have outflag set */ if (outflag) { if((outlu = open(segyFile, O_WRONLY | O_CREAT | O_TRUNC, PMODE)) == -1) { fprintf (stderr, "%s: cannot open %s\n", filename, progname); perror ("open"); err_exit (); } } /* * Now open the SEGY tape file if tape_flag set */ if (tape_flag) { if ((loglu = open (tape_name, O_RDWR)) == -1) { fprintf (stderr, "%s: cannot open %s\n", tape_name, progname); perror ("open"); err_exit (); } } if (!outflag && !tape_flag) { fprintf (stderr, "no output file specified why bother?\n"); fflush (stdout); err_exit (); } /* * Read input file and output desired data */ if (start_rec > 1) { offset = (off_t) (TRECSIZE * (start_rec - 1)); where = lseek (in_fd, offset, SEEK_CUR); } /* * Read the first record to get the Julian Day and * year for the EBCDIC header. */ offset = (off_t) (SUB_BOTTOM_OFFSET); where = lseek (in_fd, offset, SEEK_CUR); if((inbytes = read (in_fd, inbuf, DATASIZE)) == DATASIZE) { if ((bytes_read = read (in_fd, footer, QMIPS_FOOTER_SIZE)) != QMIPS_FOOTER_SIZE) { fprintf(stderr, "Error reading first record, exiting ...\n"); perror("Reason"); fflush (stderr); exit(-1); } else { if(!julianDay) julianDay = (int) get_short(&footer[252]); /* day of recording */ if(!year) year = (int) footer[2] + 1900; /* year of recording */ fprintf(stdout, "Year is %d\n", year); sonarRange = (double) get_short (&footer[104]); /* sonar range */ } } else { fprintf(stderr, "Error reading first record, exiting ...\n"); perror("Reason"); fflush (stderr); exit(-1); } /* * O.K. now skip past the two sonar channels to the subbottom channel * (reposition the file pointer to read first record again) */ where = lseek (in_fd, current_pos, SEEK_SET); /* * First thing, we scan through the file looking for the largest * vehicle depth value. Then we make it into the number of pixels * from zero to max depth. Then we set up the putput array that length * plus the record length. */ /* Lets get the current file position so we may return to * it when finished getting depths. */ count = 1; bytes_read = 1; while (bytes_read != 0) { offset = (off_t) RAWDATASIZE; where = lseek (in_fd,offset, SEEK_CUR); bytes_read = read (in_fd, footer, QMIPS_FOOTER_SIZE); if(!(count % 100)) fprintf(stderr, "Reading record # %d\r", count); if (bytes_read < QMIPS_FOOTER_SIZE) break; if (get_float(&footer[62]) > maxDepth) maxDepth = get_float(&footer[62]); count++; } fprintf(stdout,"\nMaximum depth of towfish = %f\n",maxDepth); /* O.K. Gone through the file and gathered up depths * now backup to where we started this. */ where = lseek (in_fd, current_pos, SEEK_SET); offset = (off_t) (SUB_BOTTOM_OFFSET); where = lseek (in_fd, offset, SEEK_CUR); /* * Set the sample interval based on input sweep length. Do this * explicitly rather than calculate from QMIPS footer (sonar * range as we've noted that the range sometimes is incorrectly * inserted into the QMIPS footer. Bug ??? */ sampInterval = (short) ((float)origSweepLength / (float) numberOfPixels * 1000.0); fprintf(stdout, "Sample interval is %d\n", sampInterval); /* * Now compute the number of pixels in the shot based on * the maximum fish depth plus the original number of pixels. */ sonarRange = (double) origSweepLength * 0.75; metersPerPixel = sonarRange / (double) numberOfPixels; zeroPad = (int) (maxDepth / metersPerPixel); numberOfPixels = numberOfPixels + zeroPad; fprintf(stdout, "New number of samples based on towfish depth is %d\n", numberOfPixels); fprintf(stdout, "Average resolution is %.6f\n", metersPerPixel); /* * Recompute the sweep length based on the new number * of pixels added (zeroPad). */ sweepLength = (short) (metersPerPixel / 0.75 * numberOfPixels + 0.5); /* * Copy the EBCDIC template to an ASCII buffer that * can be manipulated before converting back to EBCDIC. */ memcpy (ebcbuf, ebcdicTemplate[0], 80); ebcbuf[80] = '\0'; for (i = 1, asciiIndex = 160; i < 40; i++, asciiIndex += 80) { strcat (ebcbuf, ebcdicTemplate[i]); ebcbuf[asciiIndex] = '\0'; } ebcbuf[3199] = '\0'; /* * Now fill in the EBCDIC header with stuff that we need */ strncpy (&ebcbuf[11], "U.S.G.S.", (size_t) 8); strncpy (&ebcbuf[42], "WHFC", (size_t) 4); i = (int) strlen (filename); strncpy (&ebcbuf[89], filename, (size_t) i); strncpy (&ebcbuf[343], "1", (size_t) 1); fprintf(stderr, "Location (21 chars max): "); getBuffer(tempBuffer, 21); strncpy (&ebcbuf[106], tempBuffer, (size_t) strlen(tempBuffer)); fprintf(stderr, "Acoustic source (21 chars max): "); getBuffer(tempBuffer, 21); strncpy (&ebcbuf[1701], tempBuffer, (size_t) strlen(tempBuffer)); fprintf(stderr, "Fire rate (7 digits max): "); getBuffer(tempBuffer, 7); strncpy (&ebcbuf[1737], tempBuffer, (size_t) strlen(tempBuffer)); i = sprintf (samps_per_shot, "%d", numberOfPixels); strncpy (&ebcbuf[443], samps_per_shot, (size_t) i); strncpy (&ebcbuf[257], "Triton", (size_t) 6); strncpy (&ebcbuf[277], "ISIS", (size_t) 4); /* * Check and set IBM floating point numbers */ if(doFloats) { strncpy (&ebcbuf[475], "4", (size_t) 1); /* bytes per sample */ strncpy (&ebcbuf[501], "1", (size_t) 1); /* recording format */ strncpy (&ebcbuf[577], "IBM Floating Point", (size_t) 18); } /* * Check and set short ints */ if(doShorts) { strncpy (&ebcbuf[475], "2", (size_t) 1); /* bytes per sample */ strncpy (&ebcbuf[501], "3", (size_t) 1); /* recording format */ strncpy (&ebcbuf[577], "Short Integers", (size_t) 14); } i = sprintf (tempBuffer, "%03d", julianDay); strncpy (&ebcbuf[200], tempBuffer, (size_t) 3); i = sprintf (tempBuffer, "%04d", year); strncpy (&ebcbuf[209], tempBuffer, (size_t) 4); /* * Set up the BCD header */ if (MOTOROLA) { bhead.line = 1; /* line number 1 */ bhead.reel = 1; /* reel number */ bhead.ntr = 1; /* number of traces */ bhead.mdt = sampInterval; /* sample interval in mimusec */ bhead.nt = numberOfPixels; /* number of samples per * channel */ if(doFloats) bhead.dform = 1; /* 4 byte floating point */ if(doShorts) bhead.dform = 3; /* 2 byte fixed point (short ints) */ bhead.omdt = sampInterval; } if (INTEL) { bhead.line = htonl(1); /* line number 1 */ bhead.reel = htonl(1); /* reel number */ bhead.ntr = htons(1); /* number of traces */ bhead.mdt = bhead.omdt = htons(sampInterval); /* sample interval in mimusec */ bhead.swlen = htons(sweepLength); /* sample interval in mimusec */ bhead.nt = htons (numberOfPixels); /* number of samples per * channel */ if(doFloats) bhead.dform = htons(1); /* 4 byte floating point */ if(doShorts) bhead.dform = htons(3); /* 2 byte fixed point (short ints) */ bhead.omdt = htons (sampInterval); } /* * Place the sample interval and sweep length into the EBCDIC header */ i = sprintf (tempBuffer, "%d", sampInterval); if(strlen(tempBuffer) < (size_t) 7) strncpy (&ebcbuf[420], tempBuffer, (size_t) strlen(tempBuffer)); else strncpy (&ebcbuf[420], tempBuffer, (size_t) 7); i = sprintf (tempBuffer, "%d", sweepLength); if(strlen(tempBuffer) < (size_t) 5) strncpy (&ebcbuf[1004], tempBuffer, (size_t) strlen(tempBuffer)); else strncpy (&ebcbuf[1004], tempBuffer, (size_t) 4); /* * convert ascii to ebcdic */ ascebc (ebcbuf, ebcdic, EBCHDLEN); /* * Write EBCDIC header to output file */ if (outflag) { if ((bytes_written = write (outlu, ebcdic, EBCHDLEN)) != EBCHDLEN) { fprintf (stderr, "error writing EBCDIC header\n"); perror ("write"); err_exit (); } } if (tape_flag) { if ((bytes_written = write (loglu, ebcdic, EBCHDLEN)) != EBCHDLEN) { fprintf (stderr, "error writing EBCDIC header\n"); perror ("write"); err_exit (); } } /* * Write BCD header to output file */ if (outflag) { if (write (outlu, bcdhead, BCDHDLEN) != BCDHDLEN) { fprintf (stderr, "error writing BCD header \n"); perror ("write"); err_exit (); } } if (tape_flag) { if (write (loglu, bcdhead, BCDHDLEN) != BCDHDLEN) { fprintf (stderr, "error writing BCD header \n"); perror ("write"); err_exit (); } } oldDelayFloat = 1.0; /* * Main loop writing traces to output file */ fprintf(stderr, "\nProcessing ... \n"); while ((inbytes = read (in_fd, inbuf, DATASIZE)) == DATASIZE) { recsread++; decimate_count++; pingNum++; if(!(recsread % 100)) fprintf(stderr, "Records read = %d\r", recsread); /* * Get the footer record next as we need to get * vehicle depth data to calculate how many zero's * to pad in the outout buffer */ if ((bytes_read = read (in_fd, footer, QMIPS_FOOTER_SIZE)) != QMIPS_FOOTER_SIZE) { fprintf (stderr, "qmips footer wrong size, must be end of file\n"); fprintf (stdout, "records read = %d disk recs = %d tape recs = %d\n", recsread, recs_to_disk, recs_to_tape); fprintf (stdout, "bytes_read = %d\n", bytes_read); fflush (stdout); fflush (stderr); close (in_fd); if (outflag) close (outlu); if (tape_flag) close (loglu); exit (0); } /* * now figure out number of meters per pixel * and divide that into depth value. This will * give us the number of memory locations to clear * out. Use "numberOfSamples" (set to original number of * samples after reading first footer) as "numberOfPixels" * now represents the new number of samples for the entire * record. */ metersPerPixel = sonarRange / (double) numberOfSamples; zeroPad = (int) (get_float(&footer[62]) / metersPerPixel); /* fprintf(stdout,"sonarRange = %f depth = %f zeropad = %d\n",sonarRange, get_float(&footer[62]),zeroPad); fprintf(stdout,"metersPerPixel = %f\n", metersPerPixel); fflush(stdout); */ /* * zero memory before transfering data */ for (i = 0; i < (sizeof(floatSig) / sizeof (float)); i++) floatSig[i] = 0.0; for (i = 0; i < (sizeof(shortSig)/ sizeof (short)); i++) shortSig[i] = 0; /* * now start moving data from the input buffer */ for (i = zeroPad, j = 0; i < numberOfSamples + zeroPad; i++, j += 2) { if (numberOfBits == 16) { if(doFloats) floatSig[i] =((float)get_short(&inbuf[j]) * convertToVolts); if(doShorts) shortSig[i] = htons(get_short(&inbuf[j])); pixelValue = get_short(&inbuf[j]); } else { if(doFloats) floatSig[i] =((float) inbuf[i] * convertToVolts); if(doShorts) shortSig[i] = htons((short) inbuf[i]); pixelValue = (short) inbuf[i]; } if(i > 100 && pixelValue > 5 && pixelValue < 28000) { if(pixelValue < minValue) minValue = pixelValue; if(pixelValue > maxValue) maxValue = pixelValue; } } /* * Convert IEEE Floating Point Numbers to IBM * Single Precision Floating Point Numbers */ if(doFloats) { ieeibm (floatSig, floatSig, &numberOfPixels); if(INTEL) for(i = 0; i < numberOfPixels; i++) floatSig[i] = floatFlip(&floatSig[i]); } /* set up segy header */ floatSegy.thead.tseq_line = htonl(tseq_line++); /* sequence number */ floatSegy.thead.tseq_reel = htonl(tseq_reel++); /* bump again */ floatSegy.thead.fldrec = htonl(pingNum);/* ping number */ floatSegy.thead.fldtr = htonl(1); /* trace number */ floatSegy.thead.trcode = htons(1); /* Seismic data */ floatSegy.thead.nttr = htons(numberOfPixels); /* samples this trace */ floatSegy.thead.dt = bhead.mdt; /* sampling interval */ floatSegy.thead.gaincon = htons(header[150]); /* gain constant */ floatSegy.thead.aafilt = htons(20000); /* anti-alias filter */ floatSegy.thead.aaslope = htons(80); /* filter slope */ floatSegy.thead.year = htons((short) year); /* year of recording */ floatSegy.thead.julday = htons((short) julianDay);/* day of recording */ floatSegy.thead.hour = htons((short) footer[3]); /* hour of recording */ floatSegy.thead.minute = htons((short) footer[4]); /* minute of recording */ floatSegy.thead.second = htons((short) footer[5]); /* second of recording */ floatSegy.thead.tbasis = htons(2); /* gmt time */ floatSegy.thead.swplen = htons(sweepLength); floatSegy.thead.swptyp = htons(1); floatSegy.thead.elev = htonl(0); floatSegy.thead.selev = htonl(0); /* source elevation = 0 */ /* * get fathometer values into segy header for depth, water depth * at source and water depth a receiver. */ if(get_float(&footer[28]) != 0.0) floatSegy.thead.depth = floatSegy.thead.swdepth = floatSegy.thead.rwdepth = htonl((int) (get_float(&footer[28]) * 10.0)); else floatSegy.thead.depth = floatSegy.thead.swdepth = htonl((int) ((get_float(&footer[78]) + get_float(&footer[62])) * 10.0)); /* * make shot depth = 0, and scale factor at 10 */ floatSegy.thead.sdepth = htonl(0); floatSegy.thead.survey_scale = htonl(10); /* * check for hard wired delay */ floatSegy.thead.delay = htons(0); delayFloat = 0; if(delayFloat <= 0) delayFloat = oldDelayFloat; /* * do some latitude/longitude stuff */ lon = get_double(&footer[238]); lat = get_double(&footer[206]); centralLon = getcentlon(lon); ellipsoid = WGS84; geoutm (lat, lon, centralLon, &east, &north, ellipsoid); if(oldlat == lat || oldlon == lon) { course = (double) get_float(&footer[230]) / RAD_TO_DEG; shipsSpeed = (double) get_short(&footer[26]) / 100.0; distanceTravelled = shipsSpeed / 3600.0 * 1852.0 * ((double) origSweepLength / 1000.0); east = sin(course) * distanceTravelled + previousEast; north = cos(course) * distanceTravelled + previousNorth; previousEast = east; previousNorth = north; } else { floatSegy.thead.xsc = htonl((int) east); floatSegy.thead.xrc = htonl((int) east); floatSegy.thead.ysc = htonl((int) north); floatSegy.thead.yrc = htonl((int) north); previousEast = east; previousNorth = north; } oldlat = lat; oldlon = lon; floatSegy.thead.initgain = htons((short) footer[151]); if(MOTOROLA) { if(get_float(&footer[62]) != 0.0) floatSegy.dummies[45] = get_float(&footer[62]); /* in meters */ else floatSegy.dummies[45] = get_float(&footer[28]) - get_float(&footer[78]); } else { if(get_float(&footer[62]) != 0.0) tempFloat = get_float(&footer[62]); /* in meters */ else tempFloat = get_float(&footer[28]) - get_float(&footer[78]); floatSegy.dummies[45] = floatFlip(&tempFloat); /* in meters */ } /* floatSegy.thead.layback = htonl((int) (get_short(&footer[152]))); */ /* layback meters * 10 */ /* fprintf(stdout, "ships speed is %.1f, distance travel = %.1f, course = %.1f\n", shipsSpeed, distanceTravelled, course * RAD_TO_DEG); fprintf(stdout, "east = %.1f, north = %.1f\n", east, north); fprintf(stdout, "lat = %f, lon = %f\n\n", lat, lon); fprintf(stdout, "fish aux alt = %f, depth = %f\n", get_float(&footer[82]), get_float(&footer[62])); fprintf(stdout, "float 140 = %f, computed delay = %f\n", get_float(&footer[140]), get_float(&footer[62]) / .75); */ /* * O.K. now write to output file */ if (outflag) { if (decimate_count == decimate_factor) { if (write (outlu, THead, TRHDLEN) != TRHDLEN) { fprintf (stderr, "error writing trace header to output file\n"); perror ("write"); exit (-1); } if(doFloats) { if (write (outlu, floatSig, (numberOfPixels * sizeof (float))) != (numberOfPixels * sizeof (float))) { fprintf (stderr, "error writing trace to output file\n"); perror ("write"); exit (-1); } } if(doShorts) { if (write (outlu, shortSig, (numberOfPixels * sizeof (short))) != (numberOfPixels * sizeof (short))) { fprintf (stderr, "error writing trace to output file\n"); perror ("write"); exit (-1); } } if (!tape_flag) decimate_count = 0; recs_to_disk++; } } if (tape_flag) { if (decimate_count == decimate_factor) { if (write (loglu, THead, TRHDLEN) != TRHDLEN) { fprintf (stderr, "error writing trace header to output file\n"); perror ("write"); exit (-1); } if(doFloats) { if (write (loglu, floatSig, (numberOfPixels * sizeof (float))) != (numberOfPixels * sizeof (float))) { fprintf (stderr, "error writing trace to output file\n"); perror ("write"); exit (-1); } } if(doShorts) { if (write (loglu, shortSig, (numberOfPixels * sizeof (short))) != (numberOfPixels * sizeof (short))) { fprintf (stderr, "error writing trace to output file\n"); perror ("write"); exit (-1); } } recs_to_tape++; decimate_count = 0; } } /* * O.K. now skip past the two sonar channels to the subbottom * channel */ offset = (off_t) (SUB_BOTTOM_OFFSET); where = lseek (in_fd, offset, SEEK_CUR); } fprintf (stdout, "\n\nrecords read = %d disk recs = %d tape recs = %d\n", recsread, recs_to_disk, recs_to_tape); fprintf (stdout, "maxValue = %d minValue = %d\n", maxValue, minValue); fflush (stdout); close (in_fd); if (outflag) close (outlu); if (tape_flag) close (loglu); exit (0); } /* * err_exit() * * prints error message and exits */ void err_exit () { fprintf (stderr, "\n\nqmipstosegy converts the subbottom chirp data from the\n"); fprintf (stderr, "Datasonics SIS-1000 Side Scan SONAR and subbottom\n"); fprintf (stderr, "system. It assumes data were recorded with a Triton\n"); fprintf (stderr, "Technology ISIS Data Logger system in the ISIS Qmips\n"); fprintf (stderr, "recording format. This program expects the input file\n"); fprintf (stderr, "to be on disk. It will create a SEGY disk\n"); fprintf (stderr, "with the name of the file extracted from the Qmips\n"); fprintf (stderr, "header (-c option). Using the -d option you may\n"); fprintf (stderr, "also decimate the number of disk file records\n"); fprintf (stderr, "you store in the SEGY output file\n"); fprintf (stderr, " It will optionally create a SEGY\n"); fprintf (stderr, "tape file (-t tape device name)\n\n"); fprintf (stderr, "Usage: %s inputfile\n", progname); fprintf (stderr, "\n"); fprintf (stderr, "Required:\n"); fprintf (stderr, "\t-S sweep (in milliseconds)\n"); fprintf (stderr, "Options:\n"); fprintf (stderr, "\t[-J julian day] Replace julian day in header\n"); fprintf (stderr, "\t[-Y year (4 digits)] Replace year in header\n"); fprintf (stderr, "\t[-f First record to process]\n"); fprintf (stderr, "\t[-d decimation factor] ie -d 4 take save every fourth\n"); fprintf (stderr, "\t\tinput shot to the SEGY disk file\n"); fprintf (stderr, "\t[-t Tape device name] create a SEGY output tape\n"); fprintf (stderr, "\t[-c] Create a SEGY disk file\n"); fprintf (stderr, "\t[-v voltage scalar for floating point] Default = .003051757 \n"); fprintf (stderr, "\t[-F] Convert input values to floating point \n"); fprintf (stderr, "\t[-I] Convert input values to 16 bit integers \n"); exit (-1); } void getBuffer(tempBuffer, numberOfChars) char *tempBuffer; int numberOfChars; { char charHolder; char *ptr; int numberOfCharsRead; ptr = tempBuffer; numberOfCharsRead = 0; charHolder = 0; while(charHolder != 10) { fscanf(stdin, "%c", &charHolder); if(charHolder != 10) { *ptr++ = charHolder; numberOfCharsRead++; } } if(numberOfCharsRead < numberOfChars) tempBuffer[numberOfCharsRead] = '\0'; else tempBuffer[numberOfChars] = '\0'; return; }