Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
ckMseed
Manage
Activity
Members
Labels
Plan
Issues
1
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
1
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Software Public
PASSOFT
ckMseed
Commits
0638d591
Commit
0638d591
authored
6 years ago
by
Lloyd Carothers
Browse files
Options
Downloads
Patches
Plain Diff
Add libtrace to package. TODO remove and use as a dependency.
parent
66b86c80
No related branches found
Branches containing commit
No related tags found
Tags containing commit
1 merge request
!1
Init pkg
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
ckMseed/LibTrace.py
+1651
-0
1651 additions, 0 deletions
ckMseed/LibTrace.py
with
1651 additions
and
0 deletions
ckMseed/LibTrace.py
0 → 100755
+
1651
−
0
View file @
0638d591
#!/usr/bin/env python
#
# LibTrace
#
# classes for Segy & Mseed
# identify file types
# read mseed headers
#
# author: bcb
# Notes 2004.101
# SEED
# build a writer
# SEGY
# SEGY needs to be expanded
# build a writer
##########################
# 2004.141
# Modification
# Author: bcb
#
# MSEED
# created UbytetoStr to decompose Ubyte to bit fields
# modified blks 200, 201, 300, 310, 320, 390 and fixhdr to utilize
##########################
# 2004.295
# Modification
# Author: bcb
#
# corrected bug in mseed.calcrate
##########################
# 2005.026
# Modification
# Author: bcb
#
# added blockette 2000 to Mseed class
# Blockettes with BTime time definitions now pass the BTime
# as a tuple within the blk list
# changed unpack formats to use native byte order with standard size & alignment
##########################
# 2005.035
# Modification
# Author: bcb
#
# added check for endianess in Mseed & Segy classes, self.ByteOrder
# changed all unpack formats to reflect above change in Mseed & Segy classes
# NOTE: for mseed it is possible to have mixed endianess (e.g. little-endian headers
# and big-endian data). At this time, this library does not handle data and makes
# the determination of endianess based soley on the header.
##########################
# 2005.138
# Modification
# Author: bcb
#
# added
# Mseed.Pad, Mseed.FlagStrtoInt, Mseed.WriteFixedHdr and all of Mseed.Writeblk???
# fixed improper casting of Time Correction in Mseed.fixedhdr to signed long
##########################
# 2006.179
# bug fix
# Author: bcb
#
# text for little endian in class Segy:ByteOrder had an error such that
# little endian files would never be found
##########################
# 2006.271
# bug fix
# Author: bcb
#
# index error in Mseed:tracelength that caused trace length calculation
# to be 1 sample too long.
##########################
# 2006.335
# bug fix
# Author: bcb
#
# changed Mseed.__init__ to populate identification header fields
# fixed oversight in handling flags in blk100 reads (forgot to
# implement UbyteToStr
# fixed improper handling of res fields in blk100, blk201 and blk400
##########################
# 2007.342
# cleanup
# Author: bcb
#
# Re-organized WriteFixedHdr to pack all packets prior to any writes. Avoids
# partially written fixed header
##########################
# 2008.038
#
# Author: bcb
#
# added GetBlk, PutBlk
##########################
# 2008.179
#
# Author: bcb
#
# minimized file reads
# introduced FixedHeader class
# maintained old functionality for now.
##########################
# 2008.204
#
# Author: bcb
#
# corrected typo from DHQaul to DHQual
# added local variables to class Mseed
import
os
,
string
,
sys
,
struct
,
exceptions
,
time
SPACE
=
"
"
#VERSION = "2008.204"
class
futils
:
"""
file utilities class
"""
def
__init__
(
self
,
infile
):
self
.
infile
=
open
(
infile
,
'
r+b
'
)
def
close
(
self
):
self
.
infile
.
close
()
def
where
(
self
):
return
self
.
infile
.
tell
()
#########################################################
class
FixedHeader
:
"""
mseed fixhdr
"""
#first 20char
textblk
=
timeblk
=
sampblk
=
miscblk
=
[]
textblk
=
[]
Serial
=
DHQual
=
Res
=
Stat
=
Chan
=
Loc
=
Net
=
None
# 20:30
timeblk
=
[]
Year
=
Day
=
Hour
=
Min
=
Sec
=
Micro
=
None
# 30:36
sampblk
=
[]
NumSamp
=
SampFact
=
SampMult
=
None
# 36:48
miscblk
=
[]
act
=
io
=
DataDHQualFL
=
numblock
=
timcorr
=
bdata
=
bbblock
=
None
#########################################################
class
Mseed
(
futils
):
def
__init__
(
self
,
infile
):
"""
initialize file, determine byteorder, sizes, time, and load first fixed header
"""
self
.
type
=
self
.
rate
=
None
try
:
futils
.
__init__
(
self
,
infile
)
#local variable to class
self
.
infileseek
=
self
.
infile
.
seek
self
.
infilewrite
=
self
.
infile
.
write
self
.
infileread
=
self
.
infile
.
read
self
.
sunpack
=
struct
.
unpack
self
.
spack
=
struct
.
pack
self
.
byteorder
=
self
.
ByteOrder
()
if
self
.
byteorder
!=
"
unknown
"
:
#otherwise it might be mseed
self
.
type
=
"
mseed
"
# read 1st fixed header in file
hdrs
=
self
.
fixedhdr
()
(
self
.
filesize
,
self
.
blksize
)
=
self
.
sizes
()
(
self
.
numblocks
,
odd_size
)
=
divmod
(
self
.
filesize
,
self
.
blksize
)
if
odd_size
:
pass
# starttime of trace
self
.
time
=
string
.
join
(
map
(
str
,
(
self
.
FH
.
Year
,
self
.
FH
.
Day
,
self
.
FH
.
Hour
,
\
self
.
FH
.
Min
,
self
.
FH
.
Sec
)),
"
:
"
)
except
:
pass
#########################################################
def
isMseed
(
self
)
:
"""
determines if processed file is mseed (return 1) or unknown type (return 0)
"""
#if we don't know byteorder it must not be mseed
if
self
.
byteorder
==
"
unknown
"
:
return
0
else
:
return
1
#########################################################
def
idhdr
(
self
):
"""
trace id info
"""
return
self
.
type
,
self
.
FH
.
Stat
,
self
.
FH
.
Chan
,
self
.
FH
.
Loc
,
self
.
FH
.
Net
,
self
.
time
,
self
.
rate
#########################################################
def
FirstLastTime
(
self
):
"""
returns first and last block times in epoch
"""
try
:
#get first fixed header and calculate beginning epoch
btime_str
=
time
.
strptime
(
self
.
time
,
'
%Y:%j:%H:%M:%S
'
)
bepoch
=
time
.
mktime
(
btime_str
)
+
(
self
.
FH
.
Micro
*
0.0001
)
#figure out where the end of the file is and read the last fixed header
# and calculate eepoch
(
numblocks
,
odd_size
)
=
divmod
(
self
.
filesize
,
self
.
blksize
)
self
.
infileseek
(
-
self
.
blksize
,
2
)
loc
=
self
.
infile
.
tell
()
etime
=
self
.
btime2time
(
loc
)
etime_str
=
time
.
strptime
(
etime
,
'
%Y:%j:%H:%M:%S
'
)
eepoch
=
time
.
mktime
(
etime_str
)
+
(
self
.
FH
.
Micro
*
0.0001
)
#
return
bepoch
,
eepoch
except
StandardError
,
e
:
return
e
#########################################################
def
tracelength
(
self
):
"""
returns tracelength in seconds
"""
try
:
#get first fixed header and calculate beginning epoch
(
bepoch
,
eepoch
)
=
self
.
FirstLastTime
()
# #here I have to get the last few samples and calculate how much time is accounted for
self
.
infileseek
(
-
self
.
blksize
+
30
,
2
)
sampblock
=
self
.
infileread
(
2
)
fmtstr
=
self
.
fmt_order
+
"
H
"
numsamp
=
self
.
sunpack
(
fmtstr
,
sampblock
)[
0
]
lastsamples
=
(
numsamp
-
1
)
/
self
.
rate
return
((
eepoch
+
lastsamples
)
-
bepoch
)
except
:
pass
#########################################################
def
btime2time
(
self
,
seekval
=
0
)
:
"""
reads file fixed header and returns time string from btime
"""
try
:
hdrs
=
self
.
fixedhdr
(
seekval
)
time
=
string
.
join
(
map
(
str
,
(
self
.
FH
.
Year
,
self
.
FH
.
Day
,
self
.
FH
.
Hour
,
\
self
.
FH
.
Min
,
self
.
FH
.
Sec
)),
"
:
"
)
return
time
except
:
pass
#########################################################
def
idread
(
self
,
seekval
=
0
)
:
"""
read file as if it is mseed just pulling necessary info
from fixed header
"""
try
:
hdrs
=
self
.
fixedhdr
(
seekval
)
return
self
.
FH
.
Stat
,
self
.
FH
.
Chan
,
self
.
FH
.
Loc
,
self
.
FH
.
Net
,
\
self
.
rate
,
self
.
FH
.
Year
,
self
.
FH
.
Day
,
self
.
FH
.
Hour
,
self
.
FH
.
Min
,
self
.
FH
.
Sec
,
self
.
FH
.
Micro
except
:
return
#########################################################
def
calcrate
(
self
):
"""
this routine assumes that idread has been called first
calculate the sample rate of mseed data
If Sample rate factor > 0 and Sample rate Multiplier > 0,
rate = Sampfact X Sampmult
If Sample rate factor > 0 and Sample rate Multiplier < 0,
rate = -1 X Sampfact/Sampmult
If Sample rate factor < 0 and Sample rate Multiplier > 0,
rate = -1 X Sampmult/Sampfact
If Sample rate factor < 0 and Sample rate Multiplier < 0,
rate = 1/(Sampfact X Sampmult)
"""
sampFact
=
float
(
self
.
FH
.
SampFact
)
sampMult
=
float
(
self
.
FH
.
SampMult
)
if
sampFact
>
0
and
sampMult
>
0
:
rate
=
sampFact
*
sampMult
elif
sampFact
>
0
and
sampMult
<
0
:
rate
=
-
1.0
*
(
sampFact
/
sampMult
)
elif
sampFact
<
0
and
sampMult
>
0
:
rate
=
-
1.0
*
(
sampMult
/
sampFact
)
elif
sampFact
<
0
and
sampMult
<
0
:
rate
=
1.0
/
(
sampFact
*
sampMult
)
else
:
rate
=
sampFact
return
rate
#########################################################
def
ByteOrder
(
self
,
seekval
=
20
)
:
"""
read file as if it is mseed just pulling time info
from fixed header and determine if it makes sense unpacked
as big endian or little endian
"""
Order
=
"
unknown
"
try
:
#seek to timeblock and read
self
.
infileseek
(
seekval
)
timeblock
=
self
.
infileread
(
10
)
# timeblock=self.TraceBuffer[seekval:seekval+10]
#assume big endian
(
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
)
=
\
self
.
sunpack
(
'
>HHBBBBH
'
,
timeblock
)
#test if big endian read makes sense
if
1950
<=
Year
<=
2050
and
\
1
<=
Day
<=
366
and
\
0
<=
Hour
<=
23
and
\
0
<=
Min
<=
59
and
\
0
<=
Sec
<=
59
:
Order
=
"
big
"
self
.
fmt_order
=
"
>
"
else
:
#try little endian read
(
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
)
=
\
self
.
sunpack
(
'
<HHBBBBH
'
,
timeblock
)
#test if little endian read makes sense
if
1950
<=
Year
<=
2050
and
\
1
<=
Day
<=
366
and
\
0
<=
Hour
<=
23
and
\
0
<=
Min
<=
59
and
\
0
<=
Sec
<=
59
:
Order
=
"
little
"
self
.
fmt_order
=
"
<
"
except
:
pass
return
Order
#########################################################
def
sizes
(
self
,
seekval
=
0
):
"""
Finds Blockette 1000 and returns file size & Data Record Length
"""
try
:
#determine file size
self
.
infileseek
(
0
,
2
)
filesize
=
self
.
infile
.
tell
()
#proceed to seekval
self
.
infileseek
(
seekval
)
#self.infileseek(39)
#assign number of blockettes and offset to next blockette
nblock
=
self
.
FH
.
miscblk
[
3
]
nextblock
=
self
.
FH
.
miscblk
[
6
]
n
=
0
#find blockette 1000
while
n
<
nblock
:
self
.
infileseek
(
nextblock
)
(
blktype
,
newblock
)
=
self
.
typenxt
(
nextblock
)
if
not
blktype
:
return
None
,
None
if
blktype
==
1000
:
(
type
,
next
,
encode
,
order
,
length
,
res
)
=
self
.
blk1000
(
nextblock
)
return
filesize
,
2
**
length
nextblock
=
newblock
n
+=
1
except
:
return
None
,
None
#########################################################
def
typenxt
(
self
,
seekval
=
0
):
"""
Reads first 4 bytes of blockette
Returns blockette type and next blockette offset
"""
try
:
self
.
infileseek
(
seekval
)
fmtstr
=
self
.
fmt_order
+
"
HH
"
(
type
,
next
)
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
4
))
#reset back to beginning of blockette
self
.
infileseek
(
-
4
,
1
)
return
type
,
next
except
:
return
None
,
None
#########################################################
def
setEndian
(
self
,
endianess
=
""
):
"""
set format string for endian type
"""
if
endianess
==
"
big
"
:
fmtorderstr
=
"
>
"
elif
endianess
==
"
little
"
:
fmtorderstr
=
"
<
"
else
:
fmtorderstr
=
self
.
fmt_order
return
fmtorderstr
#########################################################
#
# for blockette descriptions below
# from SEED manual
#
# Field nbits Description
# UBYTE 8 Unsigned quantity
# BYTE 8 Two's complement signed quantity
# UWORD 16 Unsigned quantity
# WORD 16 Two's complement signed quantity
# ULONG 32 Unsigned quantity
# LONG 32 Two's complement signed quantity
# CHAR*n n*8 n characters, each 8 bit and each with
# a 7-bit ASCII character (high bit always 0)
# FLOAT 32 IEEE Floating point number
#
# BTIME
# UWORD 16 Year (e.g. 1987)
# UWORD 16 J-Day
# UBYTE 8 Hours of day (0-23)
# UBYTE 8 Minutes of hour (0-59)
# UBYTE 8 Seconds of minute (0-59, 60 for leap seconds)
# UBYTE 8 Unused for data (required for alignment)(
# UWORD 16 .0001 seconds (0-9999)
#########################################################
def
fixedhdr
(
self
,
seekval
=
0
):
"""
Reads fixed header of 48 bytes (see SEED manual)
Returns four tuples
textblk (SeqNum, DHQual, res, Stat, Loc, Chan, Net)
Sequence Number (CHAR*6)
Data header/quality indicator (CHAR*1)
Reserved (CHAR*1)
Station identifier code (CHAR*5)
Location identifier (CHAR*2)
Channel identifier (CHAR*3)
Network Code (CHAR*2)
timeblk (Year, Day, Hour, Min, Sec, junk, Micro)
Year (UWORD, 2)
Jday (UWORD, 2)
Hour (UBYTE, 1)
Min (UBYTE, 1)
Sec (UBYTE, 1)
unused (UBYTE, 1)
.0001 seconds (0-9999) (UWORD, 2)
sampblk (NumSamp, SampFact, SampMult)
Number of samples (UWORD, 2)
Sample rate factor (see calcrate) (WORD, 2)
Sample rate multiplier (see calcrate) (WORD, 2)
miscblk (act, io, DataDHQualFl, numblock, timcorr, bdata, bblock)
Activity flags (UBYTE, 1)
I/O and clock flags (UBYTE, 1)
Data quality flags (UBYTE, 1)
Number of blockettes that follow (UBYTE, 1)
Time correction (LONG, 4)
Offset to beginning of data (UWORD, 2)
Offset to beginning of next blockette (UWORD, 2)
"""
#local variable
# self.sunpack=self.sunpack
try
:
del
self
.
FH
except
:
pass
self
.
FH
=
FixedHeader
()
try
:
self
.
infileseek
(
seekval
)
fhblk
=
self
.
infileread
(
48
)
#station info
fmtstr
=
self
.
fmt_order
+
"
6scc5s2s3s2s
"
self
.
FH
.
textblk
=
self
.
sunpack
(
fmtstr
,
fhblk
[
0
:
20
])
#time info
fmtstr
=
self
.
fmt_order
+
"
HHBBBBH
"
self
.
FH
.
timeblk
=
self
.
sunpack
(
fmtstr
,
fhblk
[
20
:
30
])
#sample info
fmtstr
=
self
.
fmt_order
+
"
Hhh
"
self
.
FH
.
sampblk
=
self
.
sunpack
(
fmtstr
,
fhblk
[
30
:
36
])
#misc info
fmtstr
=
self
.
fmt_order
+
"
BBBBlHH
"
tmpblk
=
self
.
sunpack
(
fmtstr
,
fhblk
[
36
:
48
])
#decompose tmpblk[0-2] into bit fields, create miscblk
for
i
in
range
(
3
):
self
.
FH
.
miscblk
=
self
.
UbytetoStr
(
tmpblk
,
i
)
tmpblk
=
self
.
FH
.
miscblk
#recast tmpblk as list
(
self
.
FH
.
Serial
,
self
.
FH
.
DHQual
,
res
,
self
.
FH
.
Stat
,
self
.
FH
.
Loc
,
self
.
FH
.
Chan
,
self
.
FH
.
Net
)
\
=
self
.
FH
.
textblk
(
self
.
FH
.
Year
,
self
.
FH
.
Day
,
self
.
FH
.
Hour
,
self
.
FH
.
Min
,
self
.
FH
.
Sec
,
junk
,
self
.
FH
.
Micro
)
\
=
self
.
FH
.
timeblk
(
self
.
FH
.
NumSamp
,
self
.
FH
.
SampFact
,
self
.
FH
.
SampMult
)
\
=
self
.
FH
.
sampblk
self
.
rate
=
self
.
calcrate
()
return
self
.
FH
.
textblk
,
self
.
FH
.
timeblk
,
self
.
FH
.
sampblk
,
self
.
FH
.
miscblk
# return textblk,timeblk,sampblk,miscblk
except
:
print
"
error reading fixed header
"
pass
#########################################################
def
WriteFixedHdr
(
self
,
hdrlist
,
seekval
=
0
,
endianess
=
""
):
"""
Writes fixed header of 48 bytes (see SEED manual)
Requires four tuples (see self.fixedhdr)
"""
try
:
self
.
infileseek
(
seekval
)
fmtorderstr
=
self
.
setEndian
(
endianess
)
#station info
#left justify values
#fmtstr0 = fmtorderstr + "6scc5s2s3s2s"
SeqNum
=
self
.
Pad
(
hdrlist
[
0
][
0
],
6
)
#SeqNum
DQual
=
hdrlist
[
0
][
1
]
#DataQual
Res
=
hdrlist
[
0
][
2
]
#Reserved
Stat
=
self
.
Pad
(
hdrlist
[
0
][
3
],
5
)
#Stat
Loc
=
self
.
Pad
(
hdrlist
[
0
][
4
],
2
)
#Loc
Chan
=
self
.
Pad
(
hdrlist
[
0
][
5
],
3
)
#Chan
Net
=
self
.
Pad
(
hdrlist
[
0
][
6
],
2
)
#Net
#time info
#fmtstr1 = fmtorderstr + "HHBBBBH"
(
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
)
=
hdrlist
[
1
]
Micro
=
int
(
Micro
)
#sample info
#fmtstr2 = fmtorderstr + "Hhh"
(
NumSamp
,
SampFact
,
SampMult
)
=
hdrlist
[
2
]
#misc info
#fmtstr3 = fmtorderstr + "BBBBlHH"
(
actFlags
,
ioFlags
,
dqFlags
,
numblk
,
timecor
,
offsetData
,
offsetBlktt
)
=
hdrlist
[
3
]
#convert flag string to integer
actFlags
=
self
.
FlagStrtoInt
(
actFlags
)
ioFlags
=
self
.
FlagStrtoInt
(
ioFlags
)
dqFlags
=
self
.
FlagStrtoInt
(
dqFlags
)
#pack fields
fmtstr
=
fmtorderstr
+
"
6scc5s2s3s2sHHBBBBHHhhBBBBlHH
"
pack_hdr
=
self
.
spack
(
fmtstr
,
SeqNum
,
DQual
,
Res
,
Stat
,
Loc
,
Chan
,
Net
,
\
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
,
\
NumSamp
,
SampFact
,
SampMult
,
\
actFlags
,
ioFlags
,
dqFlags
,
numblk
,
timecor
,
offsetData
,
offsetBlktt
)
#write header
self
.
infilewrite
(
pack_hdr
)
return
48
except
:
print
"
error writing fixed header
"
return
0
#########################################################
def
GetBlk
(
self
,
blknum
,
seekval
=
0
):
ValidBlk
=
(
100
,
200
,
201
,
300
,
310
,
320
,
390
,
395
,
400
,
405
,
500
,
1000
,
1001
,
2000
)
if
not
blknum
in
ValidBlk
:
return
0
else
:
callcmd
=
"
blk=self.blk
"
+
str
(
blknum
)
+
"
(
"
+
str
(
seekval
)
+
"
)
"
exec
callcmd
return
blk
#########################################################
def
PutBlk
(
self
,
blknum
,
indata
,
endian
,
seekval
=
0
):
"""
test for valid blockette, if true write blockette
"""
ValidBlk
=
(
100
,
200
,
201
,
300
,
310
,
320
,
390
,
395
,
400
,
405
,
500
,
1000
,
1001
,
2000
)
if
not
blknum
in
ValidBlk
:
return
0
else
:
callcmd
=
"
bytes_written=self.Writeblk
"
+
str
(
blknum
)
+
"
(indata
"
+
"
,
"
+
str
(
seekval
)
+
"
, endian)
"
exec
callcmd
return
bytes_written
#########################################################
def
blk100
(
self
,
seekval
=
0
):
"""
Sample Rate Blockette 100 (12 bytes)
Returns tuple
blk
Blockette type (UWORD, 2)
Next blockette
'
s byte offset relative to fixed section of header
(UWORD, 2)
Actual sample rate (FLOAT, 4)
Flags (BYTE, 1)
Reserved (UBYTE, 3)
"""
self
.
infileseek
(
seekval
)
fmtstr
=
self
.
fmt_order
+
"
HHfb3B
"
blk
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
12
))
scrblk
=
self
.
UbytetoStr
(
blk
,
3
)
blk
=
scrblk
return
blk
#########################################################
def
Writeblk100
(
self
,
inblk
,
seekval
=
0
,
endianess
=
""
):
"""
writes Sample Rate Blockette 100 (12 bytes)
requires tuple inblk=(blkette, nextblk, actrate, flags, res0, res1, res2)
"""
try
:
self
.
infileseek
(
seekval
)
fmtorderstr
=
self
.
setEndian
(
endianess
)
fmtstr
=
fmtorderstr
+
"
HHfb3B
"
(
blkette
,
nextblk
,
actrate
,
flags
,
res0
,
res1
,
res2
)
=
inblk
flags
=
self
.
FlagStrtoInt
(
flags
)
pack_blk
=
self
.
spack
(
fmtstr
,
blkette
,
nextblk
,
actrate
,
flags
,
res0
,
res1
,
res2
)
self
.
infilewrite
(
pack_blk
)
return
12
except
:
print
"
error writing blockette 100
"
return
0
#########################################################
def
blk200
(
self
,
seekval
=
0
):
"""
Generic Event Detection Blockette 200 (52 bytes)
Returns tuple
blk
Blockette type (UWORD, 2)
Next blockette
'
s byte offset relative to fixed section of header
(UWORD, 2)
Signal amplitude (FLOAT, 4)
Signal period (FLOAT,4)
Background estimate (FLOAT,4)
Event detection flags (UBYTE, 1)
Reserved (UBYTE, 1)
Signal onset time (BTime expanded, 10)
Detector Name (CHAR*24)
"""
self
.
infileseek
(
seekval
)
fmtstr
=
self
.
fmt_order
+
"
HHfffBB
"
blk1
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
18
))
fmtstr
=
self
.
fmt_order
+
"
HHBBBBH
"
timeblk
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
10
))
fmtstr
=
self
.
fmt_order
+
"
24s
"
blk2
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
24
))
# incorporate timeblk tuple into blk list
tmpblk
=
list
(
blk1
)
tmpblk
.
append
(
timeblk
)
tmpblk
=
tmpblk
+
list
(
blk2
)
#apply bit mask to Ubyte
blk
=
self
.
UbytetoStr
(
tmpblk
,
5
)
return
blk
#########################################################
def
Writeblk200
(
self
,
inblk
,
seekval
=
0
,
endianess
=
""
):
"""
writes Generic Event Detection Blockette 200 (52 bytes)
requires tuple inblk
inblk=(blkette, nextblk, amp, period, bg, flags,
\
Year, Day, Hour, Min, Sec, junk, Micro, charstr)
"""
try
:
self
.
infileseek
(
seekval
)
fmtorderstr
=
self
.
setEndian
(
endianess
)
fmtstr
=
fmtorderstr
+
"
HHfffBBHHBBBBH24s
"
(
blkette
,
nextblk
,
amp
,
period
,
bg
,
flags
,
\
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
,
charstr
)
=
inblk
flags
=
FlagsStrtoInt
(
flags
)
pack_blk
=
self
.
spack
(
fmtstr
,
blkette
,
nextblk
,
amp
,
period
,
bg
,
flags
,
\
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
,
charstr
)
self
.
infilewrite
(
pack_blk
)
return
52
except
:
print
"
error writing blockette 200
"
return
0
#########################################################
def
blk201
(
self
,
seekval
=
0
):
"""
Murdock Event Detection Blockette 201 (60 bytes)
Returns tuple
blk
Blockette type (UWORD, 2)
Next blockette
'
s byte offset relative to fixed section of header
(UWORD, 2)
Signal amplitude (FLOAT, 4)
Signal period (FLOAT,4)
Background estimate (FLOAT,4)
Event detection flags (UBYTE, 1)
Reserved (UBYTE, 1)
Signal onset time (BTime expanded, 10)
Signal-to-noise ration values (UBYTE*6)
Lookback value (UBYTE, 1)
Pick algorithym (UBYTE, 1)
Detector Name (CHAR*24)
"""
self
.
infileseek
(
seekval
)
fmtstr
=
self
.
fmt_order
+
"
HHfffBB
"
blk1
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
18
))
fmtstr
=
self
.
fmt_order
+
"
HHBBBBH
"
timeblk
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
10
))
fmtstr
=
self
.
fmt_order
+
"
6BBB24s
"
blk2
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
32
))
# incorporate timeblk tuple into blk list
tmpblk
=
list
(
blk1
)
tmpblk
.
append
(
timeblk
)
tmpblk
=
tmpblk
+
list
(
blk2
)
#apply bit mask to Ubyte
blk
=
self
.
UbytetoStr
(
tmpblk
,
5
)
return
blk
#########################################################
def
Writeblk201
(
self
,
inblk
,
seekval
=
0
,
endianess
=
""
):
"""
writes Murdock Event Detection Blockette 201 (60 bytes)
requires tuple inblk
inblk=(blkette, nextblk, amp, period, bg, flags, res,
Year, Day, Hour, Min, Sec, junk, Micro, SN0, SN1, SN2, SN3, SN4, SN5, loop, algo, Name)
"""
try
:
self
.
infileseek
(
seekval
)
fmtorderstr
=
self
.
setEndian
(
endianess
)
fmtstr
=
fmtorderstr
+
"
HHfffBBHHBBBBH6BBB24s
"
(
blkette
,
nextblk
,
amp
,
period
,
bg
,
flags
,
res
,
\
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
,
SN0
,
SN1
,
SN2
,
SN3
,
SN4
,
SN5
,
\
loop
,
algo
,
Name
)
=
inblk
flags
=
self
.
FlagStrtoInt
(
flags
)
pack_blk
=
self
.
spack
(
fmtstr
,
blkette
,
nextblk
,
amp
,
period
,
bg
,
flags
,
res
,
\
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
,
SN0
,
SN1
,
SN2
,
SN3
,
SN4
,
SN5
,
loop
,
algo
,
Name
)
self
.
infilewrite
(
pack_blk
)
return
60
except
:
print
"
error writing blockette 201
"
return
0
#########################################################
def
blk300
(
self
,
seekval
=
0
):
"""
Step Calibration Blockette 300 (60 bytes)
Returns tuple
blk
Blockette type (UWORD, 2)
Next blockette
'
s byte offset relative to fixed section of header
(UWORD, 2)
Beginning of calibration time (BTime expanded, 10)
Number of step calibrations (UBYTE, 1)
Calibrations flags (UBYTE, 1)
Step duration (ULONG, 4)
Interval durations (ULONG, 4)
Calibration signal amplitude (FLOAT, 4)
Channel with calibration input (CHAR*3)
Reserved (UBYTE, 1)
Reference amplitude (ULONG, 4)
Coupling (CHAR*12)
Rolloff (CHAR*12)
"""
self
.
infileseek
(
seekval
)
fmtstr
=
self
.
fmt_order
+
"
HH
"
blk1
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
4
))
fmtstr
=
self
.
fmt_order
+
"
HHBBBBH
"
timeblk
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
10
))
fmtstr
=
self
.
fmt_order
+
"
BBIIf3sBI12s12s
"
blk2
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
46
))
# incorporate timeblk tuple into blk list
tmpblk
=
list
(
blk1
)
tmpblk
.
append
(
timeblk
)
tmpblk
=
tmpblk
+
list
(
blk2
)
#apply bit mask to Ubyte
blk
=
self
.
UbytetoStr
(
tmpblk
,
4
)
return
blk
#########################################################
def
Writeblk300
(
self
,
inblk
,
seekval
=
0
,
endianess
=
""
):
"""
writes Step Calibration Blockette 300 (60 bytes)
requires tuples inblk
inblk=(blkette, nextblk, Year, Day, Hour, Min, Sec, junk, Micro,
\
numst, flags, dur, interv, amp, chan, res, ref, couple, rolloff)
"""
try
:
self
.
infileseek
(
seekval
)
fmtorderstr
=
self
.
setEndian
(
endianess
)
fmtstr
=
fmtorderstr
+
"
HHHHBBBBHBBIIf3sBI12s12s
"
(
blkette
,
nextblk
,
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
,
\
numst
,
flags
,
dur
,
interv
,
amp
,
chan
,
res
,
ref
,
couple
,
rolloff
)
=
inblk
flags
=
self
.
FlagStrtoInt
(
flags
)
pack_blk
=
self
.
spack
(
fmtstr
,
blkette
,
nextblk
,
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
,
\
numst
,
flags
,
dur
,
interv
,
amp
,
chan
,
res
,
ref
,
couple
,
rolloff
)
self
.
infilewrite
(
pack_blk
)
return
60
except
:
print
"
error writing blockette 300
"
return
0
#########################################################
def
blk310
(
self
,
seekval
=
0
):
"""
Sine Calibration Blockette 310 (60 bytes)
Returns tuple
blk
Blockette type (UWORD, 2)
Next blockette
'
s byte offset relative to fixed section of header
(UWORD, 2)
Beginning of calibration time (BTime expanded, 10)
Reserved (UBYTE, 1)
Calibrations flags (UBYTE, 1)
Calibration duration (ULONG, 4)
Period of signal (FLOAT, 4)
Amplitude of signal (FLOAT, 4)
Channel with calibration input (CHAR*3)
Reserved (UBYTE, 1)
Reference amplitued (ULONG, 4)
Coupling (CHAR*12)
Rolloff (CHAR*12)
"""
self
.
infileseek
(
seekval
)
fmtstr
=
self
.
fmt_order
+
"
HH
"
blk1
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
4
))
fmtstr
=
self
.
fmt_order
+
"
HHBBBBH
"
timeblk
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
10
))
fmtstr
=
self
.
fmt_order
+
"
BBIff3sBI12s12s
"
blk2
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
46
))
# incorporate timeblk tuple into blk list
tmpblk
=
list
(
blk1
)
tmpblk
.
append
(
timeblk
)
tmpblk
=
tmpblk
+
list
(
blk2
)
#apply bit mask to Ubyte
blk
=
self
.
UbytetoStr
(
tmpblk
,
4
)
return
blk
#########################################################
def
Writeblk310
(
self
,
inblk
,
seekval
=
0
,
endianess
=
""
):
"""
writes Sine Calibration Blockette 310 (60 bytes)
requires tuples inblk
inblk=(blkette, nextblk, Year, Day, Hour, Min, Sec, junk, Micro,
\
res, flags, dura,per,ampsig,chan, res2,refamp,coup,rolloff)
"""
try
:
self
.
infileseek
(
seekval
)
fmtorderstr
=
self
.
setEndian
(
endianess
)
fmtstr
=
fmtorderstr
+
"
HHHHBBBBHBBIff3sBI12s12s
"
(
blkette
,
nextblk
,
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
,
\
res
,
flags
,
dura
,
per
,
ampsig
,
chan
,
res2
,
refamp
,
coup
,
rolloff
)
=
inblk
flags
=
self
.
FlagStrtoInt
(
flags
)
pack_blk
=
self
.
spack
(
fmtstr
,
blkette
,
nextblk
,
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
,
\
res
,
flags
,
dura
,
per
,
ampsig
,
chan
,
res2
,
refamp
,
coup
,
rolloff
)
self
.
infilewrite
(
pack_blk
)
return
60
except
:
print
"
error writing blockette 310
"
return
0
#########################################################
def
blk320
(
self
,
seekval
=
0
):
"""
Pseudo-random Calibraton Blockette 320 (64 bytes)
Returns tuple
blk
Blockette type (UWORD, 2)
Next blockette
'
s byte offset relative to fixed section of header
(UWORD, 2)
Beginning of calibration time (BTime expanded, 10)
Reserved (UBYTE, 1)
Calibrations flags (UBYTE, 1)
Calibration duration (ULONG, 4)
Peak-to-peak amplitude of steps (FLOAT, 4)
Channel with calibration input (CHAR*3)
Reserved (UBYTE, 1)
Reference amplitued (ULONG, 4)
Coupling (CHAR*12)
Rolloff (CHAR*12)
Noise type (CHAR*8)
"""
self
.
infileseek
(
seekval
)
fmtstr
=
self
.
fmt_order
+
"
HH
"
blk1
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
4
))
fmtstr
=
self
.
fmt_order
+
"
HHBBBBH
"
timeblk
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
10
))
fmtstr
=
self
.
fmt_order
+
"
BBIf3sBI12s12s8s
"
blk2
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
50
))
# incorporate timeblk tuple into blk list
tmpblk
=
list
(
blk1
)
tmpblk
.
append
(
timeblk
)
tmpblk
=
tmpblk
+
list
(
blk2
)
#apply bit mask to Ubyte
blk
=
self
.
UbytetoStr
(
tmpblk
,
4
)
return
blk
#########################################################
def
Writeblk320
(
self
,
inblk
,
seekval
=
0
,
endianess
=
""
):
"""
writes Pseudo-random Calibraton Blockette 320 (64 bytes)
requires tuples inblk
inblk=(blkette, nextblk, Year, Day, Hour, Min, Sec, junk, Micro,
\
res, flags, dura,ptop,chan, res2,refamp,coup,rolloff,noise)
"""
try
:
self
.
infileseek
(
seekval
)
fmtorderstr
=
self
.
setEndian
(
endianess
)
fmtstr
=
fmtorderstr
+
"
HHHHBBBBHBBIf3sBI12s12s8s
"
(
blkette
,
nextblk
,
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
,
\
res
,
flags
,
dura
,
ptop
,
chan
,
res2
,
refamp
,
coup
,
rolloff
,
noise
)
=
inblk
flags
=
self
.
FlagStrtoInt
(
flags
)
pack_blk
=
self
.
spack
(
fmtstr
,
blkette
,
nextblk
,
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
,
\
res
,
flags
,
dura
,
ptop
,
chan
,
res2
,
refamp
,
coup
,
rolloff
,
noise
)
self
.
infilewrite
(
pack_blk
)
return
64
except
:
print
"
error writing blockette 320
"
return
0
#########################################################
def
blk390
(
self
,
seekval
=
0
):
"""
Generic Calibraton Blockette 390 (28 bytes)
Returns tuple
blk
Blockette type (UWORD, 2)
Next blockette
'
s byte offset relative to fixed section of header
(UWORD, 2)
Beginning of calibration time (BTime expanded, 10)
Reserved (UBYTE, 1)
Calibrations flags (UBYTE, 1)
Calibration duration (ULONG, 4)
Calibration signal amplitude (FLOAT, 4)
Channel with calibration input (CHAR*3)
Reserved (UBYTE, 1)
"""
self
.
infileseek
(
seekval
)
fmtstr
=
self
.
fmt_order
+
"
HH
"
blk1
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
4
))
fmtstr
=
self
.
fmt_order
+
"
HHBBBBH
"
timeblk
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
10
))
fmtstr
=
self
.
fmt_order
+
"
BBIf3sB
"
blk2
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
14
))
# incorporate timeblk tuple into blk list
tmpblk
=
list
(
blk1
)
tmpblk
.
append
(
timeblk
)
tmpblk
=
tmpblk
+
list
(
blk2
)
#apply bit mask to Ubyte
blk
=
self
.
UbytetoStr
(
tmpblk
,
4
)
return
blk
#########################################################
def
Writeblk390
(
self
,
inblk
,
seekval
=
0
,
endianess
=
""
):
"""
writes Generic Calibraton Blockette 390 (28 bytes)
requires tuples inblk
inblk=(blkette, nextblk, Year, Day, Hour, Min, Sec, junk, Micro,
\
res, flags, dura,amp,chan, res2)
"""
try
:
self
.
infileseek
(
seekval
)
fmtorderstr
=
self
.
setEndian
(
endianess
)
fmtstr
=
fmtorderstr
+
"
HHHHBBBBHBBIf3sB
"
(
blkette
,
nextblk
,
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
,
\
res
,
flags
,
dura
,
amp
,
chan
,
res2
)
=
inblk
flags
=
self
.
FlagStrtoInt
(
flags
)
pack_blk
=
self
.
spack
(
fmtstr
,
blkette
,
nextblk
,
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
,
\
res
,
flags
,
dura
,
amp
,
chan
,
res2
)
self
.
infilewrite
(
pack_blk
)
return
28
except
:
print
"
error writing blockette 390
"
return
0
#########################################################
def
blk395
(
self
,
seekval
=
0
):
"""
Calibraton Abort Blockette 395 (16 bytes)
Returns tuple
blk
Blockette type (UWORD, 2)
Next blockette
'
s byte offset relative to fixed section of header
(UWORD, 2)
End of calibration time (BTime expanded, 10)
Reserved (UBYTE, 2)
"""
self
.
infileseek
(
seekval
)
fmtstr
=
self
.
fmt_order
+
"
HHHHBBBBH2s
"
blk
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
16
))
return
list
(
blk
)
#########################################################
def
Writeblk395
(
self
,
inblk
,
seekval
=
0
,
endianess
=
""
):
"""
writes Calibraton Abort Blockette 395 (16 bytes)
requires tuples inblk
inblk=(blkette, nextblk, Year, Day, Hour, Min, Sec, junk, Micro, res)
"""
try
:
self
.
infileseek
(
seekval
)
fmtorderstr
=
self
.
setEndian
(
endianess
)
fmtstr
=
fmtorderstr
+
"
HHHHBBBBH2s
"
(
blkette
,
nextblk
,
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
,
res
)
=
inblk
pack_blk
=
self
.
spack
(
fmtstr
,
blkette
,
nextblk
,
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
,
res
)
self
.
infilewrite
(
pack_blk
)
return
16
except
:
print
"
error writing blockette 395
"
return
0
#########################################################
def
blk400
(
self
,
seekval
=
0
):
"""
Beam Blockette 400 (16 bytes)
Returns tuple
blk
Blockette type (UWORD, 2)
Next blockette
'
s byte offset relative to fixed section of header
(UWORD, 2)
Beam azimuth (degrees) (FLOAT, 4)
Beam slowness (sec/degree) (FLOAT, 4)
Beam configuration (UWORD, 2)
Reserved (UBYTE, 2)
"""
self
.
infileseek
(
seekval
)
fmtstr
=
self
.
fmt_order
+
"
HHffH2B
"
blk
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
16
))
return
list
(
blk
)
#########################################################
def
Writeblk400
(
self
,
inblk
,
seekval
=
0
,
endianess
=
""
):
"""
writes Beam Blockette 400 (16 bytes)
requires tuples inblk
inblk=(blkette, nextblk, baz,bslw,bconf,res0,res1)
"""
try
:
self
.
infileseek
(
seekval
)
fmtorderstr
=
self
.
setEndian
(
endianess
)
fmtstr
=
fmtorderstr
+
"
HHffH2B
"
(
blkette
,
nextblk
,
baz
,
bslw
,
bconf
,
res0
,
res1
)
=
inblk
pack_blk
=
self
.
spack
(
fmtstr
,
blkette
,
nextblk
,
baz
,
bslw
,
bconf
,
res0
,
res1
)
self
.
infilewrite
(
pack_blk
)
return
16
except
:
print
"
error writing blockette 400
"
return
0
#########################################################
def
blk405
(
self
,
seekval
=
0
):
"""
Beam Delay Blockette 405 (6 bytes)
Returns tuple
blk
Blockette type (UWORD, 2)
Next blockette
'
s byte offset relative to fixed section of header
(UWORD, 2)
Array of delay values (UWORD, 2)
"""
self
.
infileseek
(
seekval
)
fmtstr
=
self
.
fmt_order
+
"
HHH
"
blk
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
6
))
return
list
(
blk
)
#########################################################
def
Writeblk405
(
self
,
inblk
,
seekval
=
0
,
endianess
=
""
):
"""
writes Beam Delay Blockette 405 (6 bytes)
requires tuples inblk
inblk=(blkette, nextblk, delay)
"""
try
:
self
.
infileseek
(
seekval
)
fmtorderstr
=
self
.
setEndian
(
endianess
)
fmtstr
=
fmtorderstr
+
"
HHH
"
(
blkette
,
nextblk
,
delay
)
=
inblk
pack_blk
=
self
.
spack
(
fmtstr
,
blkette
,
nextblk
,
delay
)
self
.
infilewrite
(
pack_blk
)
return
6
except
:
print
"
error writing blockette 405
"
return
0
#########################################################
def
blk500
(
self
,
seekval
=
0
):
"""
Timing Blockette 500 (200 bytes)
Returns tuple
blk
Blockette type (UWORD, 2)
Next blockette
'
s byte offset relative to fixed section of header
(UWORD, 2)
VCO correction (FLOAT, 4)
Time of exception (BTime expanded, 10)
microsec (UBYTE, 1)
Reception quality (UBYTE, 1)
Exception count (ULONG, 4)
Exception type (CHAR*16)
Clock model (CHAR*32)
Clock status (CHAR*128)
"""
self
.
infileseek
(
seekval
)
fmtstr
=
self
.
fmt_order
+
"
HHf
"
blk1
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
8
))
fmtstr
=
self
.
fmt_order
+
"
HHBBBBH
"
timeblk
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
10
))
fmtstr
=
self
.
fmt_order
+
"
BBI16s32s128s
"
blk2
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
182
))
# incorporate timeblk tuple into blk list
blk
=
list
(
blk1
)
blk
.
append
(
timeblk
)
blk
=
blk
+
list
(
blk2
)
return
blk
#########################################################
def
Writeblk500
(
self
,
inblk
,
seekval
=
0
,
endianess
=
""
):
"""
writes Timing Blockette 500 (200 bytes)
requires tuples inblk
inblk=(blkette, nextblk, vcocorr,Year, Day, Hour, Min, Sec, junk, Micro, Micro2,
\
qual,cnt,type,mod,stat)
"""
try
:
self
.
infileseek
(
seekval
)
fmtorderstr
=
self
.
setEndian
(
endianess
)
fmtstr
=
fmtorderstr
+
"
HHfHHBBBBHBBI16s32s128s
"
(
blkette
,
nextblk
,
vcocorr
,
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
,
Micro2
,
\
qual
,
cnt
,
type
,
mod
,
stat
)
=
inblk
pack_blk
=
self
.
spack
(
fmtstr
,
blkette
,
nextblk
,
vcocorr
,
Year
,
Day
,
Hour
,
Min
,
Sec
,
junk
,
Micro
,
Micro2
,
\
qual
,
cnt
,
type
,
mod
,
stat
)
self
.
infilewrite
(
pack_blk
)
return
200
except
:
print
"
error writing blockette 500
"
return
0
#########################################################
def
blk1000
(
self
,
seekval
=
0
):
"""
Data Only SEED Blockette 1000 (8 bytes)
Returns tuple
blk
Blockette type (UWORD, 2)
Next blockette
'
s byte offset relative to fixed section of header
(UWORD, 2)
Encoding Format (BYTE, 1)
Word Order (UBYTE, 1)
Data Record Length (UBYTE, 1)
Reserved (UBYTE, 1)
"""
self
.
infileseek
(
seekval
)
fmtstr
=
self
.
fmt_order
+
"
HHbBBB
"
blk
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
8
))
return
list
(
blk
)
#########################################################
def
Writeblk1000
(
self
,
inblk
,
seekval
=
0
,
endianess
=
""
):
"""
writes Data Only SEED Blockette 1000 (8 bytes)
requires tuples inblk
inblk=(blkette, nextblk, fmt,order,length,res)
"""
try
:
self
.
infileseek
(
seekval
)
fmtorderstr
=
self
.
setEndian
(
endianess
)
fmtstr
=
fmtorderstr
+
"
HHbBBB
"
(
blkette
,
nextblk
,
fmt
,
order
,
length
,
res
)
=
inblk
pack_blk
=
self
.
spack
(
fmtstr
,
blkette
,
nextblk
,
fmt
,
order
,
length
,
res
)
self
.
infilewrite
(
pack_blk
)
return
8
except
:
print
"
error writing blockette 1000
"
return
0
#########################################################
def
blk1001
(
self
,
seekval
=
0
):
"""
Data Extension Blockette 1001 (8 bytes)
Returns tuple
blk
Blockette type (UWORD, 2)
Next blockette
'
s byte offset relative to fixed section of header
(UWORD, 2)
Timing Quality (UBYTE, 1)
microsec (UBYTE, 1)
Reserved (UBYTE, 1)
Frame count (UBYTE, 1)
"""
self
.
infileseek
(
seekval
)
fmtstr
=
self
.
fmt_order
+
"
HHBBBB
"
blk
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
8
))
return
list
(
blk
)
#########################################################
def
Writeblk1001
(
self
,
inblk
,
seekval
=
0
,
endianess
=
""
):
"""
writes Data Extension Blockette 1001 (8 bytes)
requires tuples inblk
inblk=(blkette, nextblk, tqual,micro,res,fcnt)
"""
try
:
self
.
infileseek
(
seekval
)
fmtorderstr
=
self
.
setEndian
(
endianess
)
fmtstr
=
fmtorderstr
+
"
HHBBBB
"
(
blkette
,
nextblk
,
tqual
,
micro
,
res
,
fcnt
)
=
inblk
pack_blk
=
self
.
spack
(
fmtstr
,
blkette
,
nextblk
,
tqual
,
micro
,
res
,
fcnt
)
self
.
infilewrite
(
pack_blk
)
return
8
except
:
print
"
error writing blockette 1001
"
return
0
#########################################################
def
blk2000
(
self
,
seekval
=
0
):
"""
Variable Length Opaque Data Blockette
Returns two tuples
blk, opaque
Blockette type (UWORD, 2)
Next blockette
'
s byte offset relative to fixed section of header. Use 0 if no
more blockettes will follow. (UWORD, 2)
Total Blockette length kin Bytes (UWORD, 2)
Offset to Opaque Data (UWORD, 2)
Record number (ULONG, 4)
Data Word order (UBYTE, 1)
0 = little endian (VAX or 80x86 byte order).
1 = big endian (68000 or SPARC byte order).
Opaque Data flags (UBYTE, 1)
[bit 0] Opaque blockette orientation.
0 = record oriented.
1 = stream oriented.
[bit 1] Packaging bit.
0 = Blockette 2000s from multiple SEED data records with different timetags
may be packaged into a single SEED data record. The exact original
timetag in each SEED Fixed Data Header is not required for each
blockette 2000.
1= Blockette 2000s from multiple SEED data records with differing timetags
may NOT be repackaged into a single SEED data record. Set this bit
if the timetag in the SEED Fixed Data Header is required to properly
interpret the opaque data.
[bits 2-3] Opaque blockette fragmentation flags.
00 = opaque record identified by record number is completely contained in
this opaque blockette.
01 = first opaque blockette for record spanning multiple blockettes.
11 = continuation blockette 2...N-1 of record spanning N blockettes.
10 = final blockette for record spanning N blockettes.
[bits 4-5] File blockette information.
00 = not file oriented.
01 = first blockette of file.
10 = continuation of file.
11 = last blockette of file.
Number of Opaque Header fields (UBYTE, 1)
Opaque Data Header fields (VAR)
a Record type
b Vendor type
c Model type
d Software
e Firmware
Opaque Data Opaque - bytes of opaque data. Total length of opaque data
in bytes is blockette_length-15-length (opaque_data_header_string)
(Opaque)
"""
self
.
infileseek
(
seekval
)
fmtstr
=
self
.
fmt_order
+
"
HHHHIBBB
"
blk
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
15
))
#decompose tmpblk[6] into bit fields, create blk
tmpblk
=
self
.
UbytetoStr
(
blk
,
6
)
blk
=
tmpblk
#recast blk as list
#Now decipher Opaque Header
charlist
=
[]
char
=
""
length_data_string
=
0
NumOpaqueHeaders
=
int
(
blk
[
7
])
fmtstr
=
self
.
fmt_order
+
"
s
"
for
i
in
range
(
NumOpaqueHeaders
):
tmpchar
=
""
while
tmpchar
!=
"
~
"
:
tupchar
=
self
.
sunpack
(
fmtstr
,
self
.
infileread
(
1
))
tmpchar
=
str
(
tupchar
[
0
])
if
tmpchar
!=
"
~
"
:
char
=
char
+
tmpchar
length_data_string
+=
1
charlist
.
append
(
char
)
blk
.
append
(
charlist
)
# opaque = ""
# rdbyte = int(tmpblk[2]) - 15 - length_data_string
# fmt = "=%ds" % rdbyte
# opaque=self.sunpack(fmt, self.infileread(rdbyte))
#
# #
# print opaque
# #
return
blk
#########################################################
def
UbytetoStr
(
self
,
tup
,
offset
):
"""
converts unsign byte to string values
"""
list
=
[]
strval
=
""
# mask bit fields and build string
for
i
in
range
(
8
):
mask
=
2
**
i
if
tup
[
offset
]
&
mask
:
strval
=
"
1
"
+
strval
else
:
strval
=
"
0
"
+
strval
# build new list with decomposed bit string
for
i
in
range
(
len
(
tup
)):
if
i
==
offset
:
list
.
append
(
strval
)
else
:
list
.
append
(
tup
[
i
])
return
list
#########################################################
def
FlagStrtoInt
(
self
,
flagstr
):
"""
converts Flag String to Integer
"""
flagint
=
0
n
=
len
(
flagstr
)
-
1
for
a
in
flagstr
:
if
int
(
a
):
flagint
=
flagint
+
2
**
n
n
-=
1
return
flagint
#########################################################
def
Pad
(
self
,
var
,
num
):
"""
pad header values to specified length with blank space
right justified
"""
varlength
=
len
(
var
)
if
varlength
==
num
:
return
var
elif
varlength
<
num
:
pad
=
num
-
varlength
newvar
=
var
+
SPACE
*
pad
return
newvar
#########################################################
### END MSEED
#########################################################
class
Segy
(
futils
):
def
__init__
(
self
,
infile
):
self
.
type
=
self
.
serial
=
self
.
chan
=
self
.
time
=
self
.
rate
=
None
futils
.
__init__
(
self
,
infile
)
# self.byteorder: byte order of input file.
# "big"
# "little"
# or "unknown"
self
.
byteorder
=
self
.
ByteOrder
()
# self.fmt_order: companion to self.byteorder. Format string for stuct.pack
# ">" big endian
# "<" little endian
#########################################################
def
isSegy
(
self
)
:
"""
determines if processed file is segy or unknown type
"""
#if we don't know byteorder it must not be segy
if
self
.
byteorder
==
"
unknown
"
:
return
0
#otherwise it might be segy
(
Sserial
,
Schan
,
Srate
,
Syear
,
Sday
,
Shour
,
Smin
,
Ssec
)
=
self
.
idread
()
#we have already tested for a valid time in self.ByteOrder, this test is
#to ensure that we were able to read a complete idhdr header
if
Sserial
==
Schan
==
Srate
==
Syear
==
Sday
==
Shour
==
\
Smin
==
Ssec
==
None
:
return
0
#if we're this far it must be segy
self
.
type
=
"
segy
"
if
Sserial
<
36864
:
self
.
serial
=
Sserial
else
:
self
.
serial
=
self
.
to_hex
(
Sserial
)
self
.
time
=
string
.
join
(
map
(
str
,
(
Syear
,
Sday
,
Shour
,
Smin
,
Ssec
)),
"
:
"
)
self
.
chan
=
Schan
self
.
rate
=
Srate
return
1
#########################################################
def
idhdr
(
self
):
return
self
.
type
,
self
.
serial
,
self
.
chan
,
self
.
time
,
self
.
rate
#########################################################
def
tracelength
(
self
):
"""
returns trace length in seconds
"""
self
.
infile
.
seek
(
228
)
fmtstr
=
self
.
fmt_order
+
"
L
"
numsamp
=
struct
.
unpack
(
fmtstr
,
self
.
infile
.
read
(
4
))[
0
]
length
=
numsamp
/
self
.
rate
return
length
#########################################################
def
idread
(
self
)
:
"""
Read file as if SEGY file trying to extract
channel, time block, sample rate, and serial number
"""
try
:
self
.
infile
.
seek
(
0
)
SH
=
self
.
infile
.
read
(
240
)
# self.infile.seek(12)
fmtstr
=
self
.
fmt_order
+
"
L
"
# chan = struct.unpack(fmtstr, self.infile.read(4))[0]
# print chan
chan
=
struct
.
unpack
(
fmtstr
,
SH
[
12
:
16
])[
0
]
# self.infile.seek(156)
# timeblock=self.infile.read(10)
fmtstr
=
self
.
fmt_order
+
"
HHHHH
"
# (year,day,hour,min,sec)=struct.unpack(fmtstr, timeblock)
(
year
,
day
,
hour
,
min
,
sec
)
=
struct
.
unpack
(
fmtstr
,
SH
[
156
:
166
])
# self.infile.seek(200)
fmtstr
=
self
.
fmt_order
+
"
L
"
# samp=struct.unpack(fmtstr, self.infile.read(4))[0]
# print samp
samp
=
struct
.
unpack
(
fmtstr
,
SH
[
200
:
204
])[
0
]
rate
=
int
(
1
/
(
samp
/
1e6
))
# self.infile.seek(224)
fmtstr
=
self
.
fmt_order
+
"
H
"
# serial = struct.unpack(fmtstr, self.infile.read(2))[0]
serial
=
struct
.
unpack
(
fmtstr
,
SH
[
224
:
226
])[
0
]
return
serial
,
chan
,
rate
,
year
,
day
,
hour
,
min
,
sec
except
:
return
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
#########################################################
def
ByteOrder
(
self
,
seekval
=
156
)
:
"""
read file as if it is segy just pulling time info
from header and determine if it makes sense unpacked
as big endian or little endian
"""
Order
=
"
unknown
"
try
:
#seek to timeblock and read
self
.
infile
.
seek
(
seekval
)
timeblock
=
self
.
infile
.
read
(
10
)
#assume big endian
(
Year
,
Day
,
Hour
,
Min
,
Sec
)
=
\
struct
.
unpack
(
'
>HHHHH
'
,
timeblock
)
#test if big endian read makes sense
if
1950
<=
Year
<=
2050
and
\
1
<=
Day
<=
366
and
\
0
<=
Hour
<=
23
and
\
0
<=
Min
<=
59
and
\
0
<=
Sec
<=
59
:
Order
=
"
big
"
self
.
fmt_order
=
"
>
"
else
:
#try little endian read
(
Year
,
Day
,
Hour
,
Min
,
Sec
)
=
\
struct
.
unpack
(
'
<HHHHH
'
,
timeblock
)
#test if little endian read makes sense
if
1950
<=
Year
<=
2050
and
\
1
<=
Day
<=
366
and
\
0
<=
Hour
<=
23
and
\
0
<=
Min
<=
59
and
\
0
<=
Sec
<=
59
:
Order
=
"
little
"
self
.
fmt_order
=
"
<
"
except
:
pass
return
Order
#########################################################
def
to_int
(
self
,
input
)
:
"""
conversion routine from hex to integer
"""
HEXCHAR
=
[
"
0
"
,
"
1
"
,
"
2
"
,
"
3
"
,
"
4
"
,
"
5
"
,
"
6
"
,
"
7
"
,
"
8
"
,
"
9
"
,
"
A
"
,
"
B
"
,
"
C
"
,
"
D
"
,
"
E
"
,
"
F
"
]
hexnum
=
str
(
input
)
retval
=
0
input_length
=
len
(
hexnum
)
for
i
in
range
(
input_length
)
:
for
index
in
range
(
len
(
HEXCHAR
))
:
if
string
.
upper
(
hexnum
[
i
])
==
HEXCHAR
[
index
]
:
retval
=
retval
+
index
*
(
16
**
(
input_length
-
(
1
+
i
)))
return
retval
#########################################################
def
to_hex
(
self
,
number
)
:
"""
conversion routine from integer to hex
"""
retval
=
0
hexnum
=
hex
(
number
)
return
hexnum
[
2
:]
#########################################################
### END SEGY
#########################################################
if
__name__
==
"
__main__
"
:
VERSION
=
"
2008.204
"
filecnt
=
0
# based on traverse routine in "python standard library", Lundh pg 34
def
GetTrace
(
DataDir
)
:
global
filecnt
stack
=
[]
rwError
=
0
for
k
in
range
(
len
(
DataDir
))
:
stack
.
append
(
DataDir
[
k
])
files
=
[]
file_list
=
{}
errcnt
=
0
while
stack
:
directory
=
stack
.
pop
()
if
not
os
.
path
.
isdir
(
directory
):
print
"
\n
***WARNING*** Directory
\"
%s
\"
not found.
\n
"
%
directory
continue
# else :
for
file
in
os
.
listdir
(
directory
):
fullname
=
os
.
path
.
join
(
directory
,
file
)
if
not
os
.
access
(
fullname
,
6
):
rwError
+=
1
continue
if
os
.
path
.
isfile
(
fullname
)
:
filecnt
+=
1
try
:
newfile
=
Segy
(
fullname
)
if
newfile
.
isSegy
():
(
type
,
serial
,
chan
,
time
,
rate
)
=
newfile
.
idhdr
()
length
=
newfile
.
tracelength
()
# length = "NULL"
file_list
[
fullname
]
=
(
type
,
serial
,
chan
,
time
,
rate
,
length
,
newfile
.
ByteOrder
())
newfile
.
close
()
except
:
rwError
+=
1
pass
else
:
try
:
newfile
=
Mseed
(
fullname
)
if
newfile
.
isMseed
():
try
:
#simple test to determine if correct size file
filesize
=
newfile
.
filesize
blksize
=
newfile
.
blksize
(
numblocks
,
odd_size
)
=
divmod
(
filesize
,
blksize
)
if
odd_size
:
rwError
+=
1
continue
except
:
rwError
+=
1
continue
type
=
newfile
.
type
serial
=
string
.
strip
(
newfile
.
FH
.
Stat
)
chan
=
string
.
strip
(
newfile
.
FH
.
Chan
)
loc
=
string
.
strip
(
newfile
.
FH
.
Loc
)
net
=
string
.
strip
(
newfile
.
FH
.
Net
)
time
=
newfile
.
time
rate
=
newfile
.
rate
length
=
newfile
.
tracelength
()
# length = "NULL"
file_list
[
fullname
]
=
(
type
,
serial
,
chan
,
time
,
rate
,
length
,
newfile
.
ByteOrder
())
newfile
.
close
()
except
:
rwError
+=
1
pass
# if os.path.isdir(fullname) and not os.path.islink(fullname) :
if
os
.
path
.
isdir
(
fullname
)
or
(
os
.
path
.
islink
(
fullname
)
and
not
os
.
path
.
isfile
(
fullname
)):
stack
.
append
(
fullname
)
return
file_list
,
rwError
if
len
(
sys
.
argv
)
>
1
:
if
sys
.
argv
[
1
]
==
"
-#
"
:
print
VERSION
sys
.
exit
(
1
)
else
:
print
"
Unknown arguement %s
"
%
sys
.
argv
[
1
:]
sys
.
exit
(
1
)
segynum
=
0
mseednum
=
0
unknownnum
=
0
Dirs
=
[]
# Dirs.append(",")
Dirs
.
append
(
"
.
"
)
# Dirs.append("/Users/bruce/data/uniq")
(
file_list
,
rwError
)
=
GetTrace
(
Dirs
)
for
file
in
file_list
.
keys
()
:
file_type
=
file_list
[
file
][
0
]
if
file_type
==
"
segy
"
:
segynum
+=
1
# print "\n SEGY \n"
# print "segy: ", file_list[file][1], file_list[file][2], file_list[file][3], \
# file_list[file][4], file_list[file][5], file_list[file][6]
elif
file_type
==
"
mseed
"
:
# if file_type == "mseed" :
mseednum
+=
1
# print "\n MSEED \n"
# print "mseed: ", file_list[file][1], file_list[file][2], file_list[file][3], \
# file_list[file][4], file_list[file][5], file_list[file][6]
#else :
#unknownnum += 1
#print "\n Format Not Recognized \n"
print
"
\n
Total Files Found = %i
"
%
filecnt
print
"
SEGY Files Processed = %i
\n
MSEED Files Processed = %i
"
%
(
segynum
,
mseednum
)
print
"
Total RWErrors = %i
"
%
rwError
print
"
Total Files Identified = %i
"
%
len
(
file_list
)
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment