segy_drv_xstar
index
/Users/schwehr/projects/xcore/src/segy-py/segy_drv_xstar.py

Module to read EdgeTech xstar segy files.  No writing at this time.
 
These files are produced by the SunOS 5.5 based Xstar workstation that
is used on Neal W. Driscolls chirp fish that was in use at SIO from
2002-2005 and at WHOI before that.  Ask Neal for the fish details.
 
     Copyright (C) 2005  Kurt Schwehr
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
$Id: segy_drv_xstar.py,v 1.12 2005/09/17 19:12:35 schwehr Exp $
 
According to the manual, this file is compatible with software
revisions 4.2.3, 4.3, 4.4 and 6.0.  Data collected with the special
5.0 revision does no adhere to this stucture.
 
 
Here is the manuals description of the trace data:
 
  4.3.1.2.2 Trace Data
 
  The trace data constsis of 6400-bytes of data and 1552-byte of
  zeros.  The trace begins life as the recording from the receivers.
 
  Bytes 0241-6640  Integer No. 120-3319
 
  Correlated return (3200 Short integers) The first 724 shor integers
  (from 120 to 843) represent the displayed processed envelope where
  each value is within 0-1024 range.
 
  Bytes 6641-8192 Integer No. 3320-4095
 
  776 zeros
 
Here is what is done by Jeff Dingler/Jeff Babcock in C_ConvertXstar
via Henkart's sioseis:
 
sioseis << eof1
procs diskin xstar header diskoa end
 
diskin
    format edgetech
    ipath $1 end
end
 
xstar
   type 2 dummies 2 end
end
 
 
header
     fno 0 lno 999999 ftr 0 ltr 999999
     l3 = l1 l6 = l3 end
end
 
diskoa
  opath ${BASE}.segy end
end
 
end
eof1
####################################
# Use SIOSEIS to output lat, long, shot, speed, course, shot (.xykcs)
# l21 & l22 are longitude and latitude (integers)
# i63 & i64 are course and speed (integers)
# l1 is trace sequence number in the line (effectively shot #)
 
set LATLONFILE = ${BASE}.xykcs
set LLSFILE    = ${BASE}.yxscs  #temporary file
 
sioseis << ! > $LLSFILE
procs diskin prout end
 
diskin
    ipath ${BASE}.segy end
end
 
prout 
    indices l21 l22 i64 i63 l1 format (5(1X,F10)) fno 1 lno 999999 end    
end
 
end
######################################################################
 
So looking at a database output, I can start to see the real,imaginary traces:
 
sqlite bpsegy.db 'select traceNo,X/3600.0,Y/3600.0 FROM  segyTrace' | head -10
 
 
15790|-120.101111111111|34.4061111111111
15790|-120.101111111111|34.4061111111111
15791|-120.101111111111|34.4061111111111
15791|-120.101111111111|34.4061111111111
15792|-120.101111111111|34.4061111111111
15792|-120.101111111111|34.4061111111111
15793|-120.101111111111|34.4061111111111
15793|-120.101111111111|34.4061111111111
15794|-120.101111111111|34.4061111111111
15794|-120.101111111111|34.4061111111111
 
 
There are two each of each TraceNo (which is basically shot number)
 
For more info, see Paul Henkart's Seiseis XSTAR notes:
 
http://sioseis.ucsd.edu/xstar.html
 
KNOWN BUGS:
 
* It seems that the EdgeTech xstar software occasionally drops the
  negative for longitues in the Western Hemisphere.  There is no
  detection for this.
 
* Have not varified all of the quirks that P. Henkart has found
 
* No detection of dropped/dead pings
 
* This driver currently fails when using the 'short' list

 
Modules
       
copy
segy_drv_rev1
unittest

 
Classes
       
unittest.TestCase(__builtin__.object)
TestXstar

 
class TestXstar(unittest.TestCase)
    Test as much as we can of the xstar driver
 
 
Method resolution order:
TestXstar
unittest.TestCase
__builtin__.object

Methods defined here:
test001TextHeader(self)
testIntToBytes(self)
testTraceHeaders(self)
Make sure all trace headers do not overlap

Methods inherited from unittest.TestCase:
__call__(self, *args, **kwds)
__init__(self, methodName='runTest')
Create an instance of the class that will use the named test
method when executed. Raises a ValueError if the instance does
not have a method with the specified name.
__repr__(self)
__str__(self)
assertAlmostEqual = failUnlessAlmostEqual(self, first, second, places=7, msg=None)
Fail if the two objects are unequal as determined by their
difference rounded to the given number of decimal places
(default 7) and comparing to zero.
 
Note that decimal places (from zero) are usually not the same
as significant digits (measured from the most signficant digit).
assertAlmostEquals = failUnlessAlmostEqual(self, first, second, places=7, msg=None)
Fail if the two objects are unequal as determined by their
difference rounded to the given number of decimal places
(default 7) and comparing to zero.
 
Note that decimal places (from zero) are usually not the same
as significant digits (measured from the most signficant digit).
assertEqual = failUnlessEqual(self, first, second, msg=None)
Fail if the two objects are unequal as determined by the '=='
operator.
assertEquals = failUnlessEqual(self, first, second, msg=None)
Fail if the two objects are unequal as determined by the '=='
operator.
assertFalse = failIf(self, expr, msg=None)
Fail the test if the expression is true.
assertNotAlmostEqual = failIfAlmostEqual(self, first, second, places=7, msg=None)
Fail if the two objects are equal as determined by their
difference rounded to the given number of decimal places
(default 7) and comparing to zero.
 
Note that decimal places (from zero) are usually not the same
as significant digits (measured from the most signficant digit).
assertNotAlmostEquals = failIfAlmostEqual(self, first, second, places=7, msg=None)
Fail if the two objects are equal as determined by their
difference rounded to the given number of decimal places
(default 7) and comparing to zero.
 
Note that decimal places (from zero) are usually not the same
as significant digits (measured from the most signficant digit).
assertNotEqual = failIfEqual(self, first, second, msg=None)
Fail if the two objects are equal as determined by the '=='
operator.
assertNotEquals = failIfEqual(self, first, second, msg=None)
Fail if the two objects are equal as determined by the '=='
operator.
assertRaises = failUnlessRaises(self, excClass, callableObj, *args, **kwargs)
Fail unless an exception of class excClass is thrown
by callableObj when invoked with arguments args and keyword
arguments kwargs. If a different type of exception is
thrown, it will not be caught, and the test case will be
deemed to have suffered an error, exactly as for an
unexpected exception.
assertTrue = failUnless(self, expr, msg=None)
Fail the test unless the expression is true.
assert_ = failUnless(self, expr, msg=None)
Fail the test unless the expression is true.
countTestCases(self)
debug(self)
Run the test without collecting errors in a TestResult
defaultTestResult(self)
fail(self, msg=None)
Fail immediately, with the given message.
failIf(self, expr, msg=None)
Fail the test if the expression is true.
failIfAlmostEqual(self, first, second, places=7, msg=None)
Fail if the two objects are equal as determined by their
difference rounded to the given number of decimal places
(default 7) and comparing to zero.
 
Note that decimal places (from zero) are usually not the same
as significant digits (measured from the most signficant digit).
failIfEqual(self, first, second, msg=None)
Fail if the two objects are equal as determined by the '=='
operator.
failUnless(self, expr, msg=None)
Fail the test unless the expression is true.
failUnlessAlmostEqual(self, first, second, places=7, msg=None)
Fail if the two objects are unequal as determined by their
difference rounded to the given number of decimal places
(default 7) and comparing to zero.
 
Note that decimal places (from zero) are usually not the same
as significant digits (measured from the most signficant digit).
failUnlessEqual(self, first, second, msg=None)
Fail if the two objects are unequal as determined by the '=='
operator.
failUnlessRaises(self, excClass, callableObj, *args, **kwargs)
Fail unless an exception of class excClass is thrown
by callableObj when invoked with arguments args and keyword
arguments kwargs. If a different type of exception is
thrown, it will not be caught, and the test case will be
deemed to have suffered an error, exactly as for an
unexpected exception.
id(self)
run(self, result=None)
setUp(self)
Hook method for setting up the test fixture before exercising it.
shortDescription(self)
Returns a one-line description of the test, or None if no
description has been provided.
 
The default implementation of this method returns the first line of
the specified test method's docstring.
tearDown(self)
Hook method for deconstructing the test fixture after testing it.

Data and other attributes inherited from unittest.TestCase:
__dict__ = <dictproxy object>
dictionary for instance variables (if defined)
__weakref__ = <attribute '__weakref__' of 'TestCase' objects>
list of weak references to the object (if defined)
failureException = <class exceptions.AssertionError>
Assertion failed.

 
Functions
       
b(i)
c(num)
return the starting byte of a C text header line
getTextHeaderEntry(data, headerEntryName)
getTextHeaderStr(asciiStr, start, end)
traceIntToBytes(integerNo)
Translate from 4.3.1.2.1 240 Byte Trace Identification Header

 
Data
        DRIVER_NAME = 'xstar'
binaryHeaderEntries = {'EnsembleFold': [3227, 3228, 'The expected number of data traces per trace ensemble - the CMP fold'], 'FixedLenTraceFlag': [3503, 3504, '1 indeicates that all trances in this file are all the same length'], 'LineNo': [3205, 3208, 'Line number'], 'NumExtendedTextHeaders': [3505, 3506, 'Number of 3200B ext text headers after the bin header'], 'SampleFormat': [3225, 3226, 'Data sample format code'], 'SamplesPerTrace': [3221, 3222, 'Number of samples per data trace'], 'SegYRev': [3501, 3502, 'SEG Y Format Revision Number. Rev 1.0 is 0100'], 'SweepEnd': [3235, 3236, 'Sweep frequence at end (Hz)'], 'SweepStart': [3233, 3234, 'Sweep frequence at start (Hz)'], 'TraceSorting': [3229, 3230, 'The sorting code or type of ensemble'], ...}
coordUnits = {1: 'Length (meters or feet)', 2: 'Seconds of arc', 3: 'Decimal degrees', 4: 'Degrees, minutes, seconds (DMS)Note: To encode +...6 + MM*104 + SS*102 with bytes 71-72 set to -100.'}
dataFormatStruct = {1: None, 2: '>i', 3: '>h', 4: None, 5: 'f', 6: None, 7: None, 8: '>b'}
dataFormats = {1: '4-byte IBM floating point', 2: '4-byte, twos complement integer', 3: '2-byte, twos complement integer', 4: '4-byte, fixed-point with gain(obsolete)', 5: '4-byte IEEE floating-point', 6: 'Not currently used', 7: 'Not currently used', 8: '1-byte, twos complement integer'}
dataUse = {1: 'Production', 2: 'Test'}
fileHeaderShortList = ['LineNo', 'SamplesPerTrace', 'SampleFormat', 'SweepStart', 'SweepEnd', 'FixedLenTraceFlag']
fileHeaderTables = {'SampleFormat': {1: '4-byte IBM floating point', 2: '4-byte, twos complement integer', 3: '2-byte, twos complement integer', 4: '4-byte, fixed-point with gain(obsolete)', 5: '4-byte IEEE floating-point', 6: 'Not currently used', 7: 'Not currently used', 8: '1-byte, twos complement integer'}, 'TraceSorting': {-1: 'Other', 0: 'Unknown', 1: 'As recorded', 2: 'CDP ensemble', 3: 'Single fold continuous profile', 4: 'Horizontally stacked', 5: 'Common source point', 6: 'Common receiver point', 7: 'Common offset point', 8: 'Common mid-point', ...}}
gainType = {1: 'fixed', 2: 'binary', 3: 'floating point'}
overTravel = {1: 'down (or behind) ', 2: 'up (or ahead)'}
pulseTypes = {'L': [50, 1, 6], 'M': [35, 1, 6], 'N': [20, 3, 15], 'O': [20, 2.5, 12.5], 'P': [10, 1, 5.5], 'Q': [10, 3.5, 15.5], 'R': [10, 1, 15], 'S': [3, 1, 15], 'T': [30, 1, 15]}
srcMeasUnits = {-1: 'Other (should be described in Source Measurement Unit stanza, page 39)', 0: 'Unknown', 1: 'Joule (J)', 2: 'Kilowatt (kW)', 3: 'Pascal (Pa)', 4: 'Bar (Bar)', 5: 'Bar-meter (Bar-m)', 6: 'Newton (N)', 7: 'Kilograms (kg)'}
srcTypeOrient = {-1: 'Other (should be described in Source Type/Orientation stanza, page 38)', 0: 'Unknown', 1: 'Vibratory - Vertical orientation', 2: 'Vibratory - Cross-line orientation', 3: 'Vibratory - In-line orientation', 4: 'Impulsive - Vertical orientation', 5: 'Impulsive - Cross-line orientation', 6: 'Impulsive - In-line orientation', 7: 'Distributed Impulsive - Vertical orientation', 8: 'Distributed Impulsive - Cross-line orientation', ...}
structIntCodes = {1: '>b', 2: '>h', 4: '>i', 8: '>q'}
sweepTypeCodes = {1: 'linear', 2: 'parabolic', 3: 'exponential', 4: 'other'}
taperType = {1: 'linear ', 2: 'cos2', 3: 'other'}
textFileHeaderEntries = {'AREA': [2, 11], 'COMPANY': [12, 79], 'LINE': [89, 100], 'MAP ID': [2, 49], 'REAL NO': [3, 5]}
timeBasis = {1: 'Local', 2: 'GMT (Greenwich Mean Time)', 3: 'Other, should be explained in a user defined stanza in the Extended Textual File Header', 4: 'UTC (Coordinated Universal Time)'}
traceHdrSize = 240
traceHeader = {'AliasFiltFreq': [141, 142, 'Sample freq/2 (Hz)'], 'ChanBDelay': [107, 108, 'Channel-B delay (samples) (SB-0408 only)'], 'CoordUnits': [89, 90, '1=meters, 2=seconds of arc'], 'Correlated': [125, 126, 'Correlated: 2 = yes'], 'Course': [193, 194, 'NMEA0183 course'], 'Day': [159, 160, 'Computer day of year'], 'Delay': [109, 110, 'Delay between transmission and start of sampling (ms) (Rev4.2 only)'], 'DistFishBehindAnt': [37, 38, 'Distance of fish behind antenna (cm)'], 'DistFishStarboardAnt': [39, 40, 'Distance from antenna to fish in starboard direction(cm)'], 'GrpX': [81, 84, 'NMEA Long mm or .0001 min of arc is GrpX in Segy Rev1'], ...}
traceHeaderShortList = ['Shotpoint', 'X', 'Y', 'GrpX', 'GrpY', 'PulsePowerUser', 'TriggerWidthHeaveComp', 'Delay', 'SampleInterval', 'SweepFreqStart', 'SweepFreqEnd', 'SweepLen', 'Year', 'Day', 'Hour', 'Min', 'Sec', 'Trigger', 'Course', 'Speed', ...]
traceHeaderTables = {'CoordUnits': {1: 'Length (meters or feet)', 2: 'Seconds of arc', 3: 'Decimal degrees', 4: 'Degrees, minutes, seconds (DMS)Note: To encode +...6 + MM*104 + SS*102 with bytes 71-72 set to -100.'}, 'SweepType': {1: 'linear', 2: 'parabolic', 3: 'exponential', 4: 'other'}, 'TaperType': {1: 'linear ', 2: 'cos2', 3: 'other'}, 'TimeBasis': {1: 'Local', 2: 'GMT (Greenwich Mean Time)', 3: 'Other, should be explained in a user defined stanza in the Extended Textual File Header', 4: 'UTC (Coordinated Universal Time)'}, 'TraceId': {-1: 'Other', 0: 'Unknown', 1: 'Seismic data', 2: 'Dead', 3: 'Dummy', 4: 'Time break', 5: 'Uphole', 6: 'Sweep', 7: 'Timing', 8: 'Waterbreak', ...}}
traceIdCode = {-1: 'Other', 0: 'Unknown', 1: 'Seismic data', 2: 'Dead', 3: 'Dummy', 4: 'Time break', 5: 'Uphole', 6: 'Sweep', 7: 'Timing', 8: 'Waterbreak', ...}
traceSortingCodes = {-1: 'Other', 0: 'Unknown', 1: 'As recorded', 2: 'CDP ensemble', 3: 'Single fold continuous profile', 4: 'Horizontally stacked', 5: 'Common source point', 6: 'Common receiver point', 7: 'Common offset point', 8: 'Common mid-point', ...}
traceUnits = {-1: 'Other (should be described in Data Sample Measurement Units Stanza)', 0: 'Unknown', 1: 'Pascal (Pa)', 2: 'Volts (v)', 3: 'Millivolts (mV)', 4: 'Amperes (A)', 5: 'Meters (m)', 6: 'Meters per second (m/s)', 7: 'Meters per second squared (m/s2)', 8: 'Newton (N)', ...}
transdUnits = {-1: 'Other (should be described in Data Sample Measurement Unit stanza, page 36)', 0: 'Unknown', 1: 'Pascal (Pa)', 2: 'Volts (v)', 3: 'Millivolts (mV)', 4: 'Amperes (A)', 5: 'Meters (m)', 6: 'Meters per second (m/s)', 7: 'Meters per second squared (m/s2)', 8: 'Newton (N)', ...}