Newer
Older
#!/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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# 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
##########################
# modification
# version: 2020.211
# author: Maeva Pourpoint
#
# Fixed issue with exec and variable scope (see GetBlk() and PutBlk())
##########################
import os
import string
import struct
import sys
import time
SPACE = " "
# VERSION = "2008.204"
class futils:
"""
file utilities class
"""
def __init__(self, infile):
self.infile = open(infile, 'rb')
def close(self):
self.infile.close()
def where(self):
return self.infile.tell()
#########################################################
class FixedHeader:
# first 20char
textblk = timeblk = sampblk = miscblk = []
textblk = []
Serial = DHQual = Res = Stat = Chan = Loc = Net = None
timeblk = []
Year = Day = Hour = Min = Sec = Micro = None
sampblk = []
NumSamp = SampFact = SampMult = None
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
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(list(map(str, (self.FH.Year,
# self.FH.Day,
# self.FH.Hour,
# self.FH.Min,
# self.FH.Sec))), ":")
templist = list(map(str, (self.FH.Year, self.FH.Day,
self.FH.Hour, self.FH.Min,
self.FH.Sec)))
self.time = ":".join(templist)
#########################################################
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)
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 Exception as 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 Exception:
#########################################################
def btime2time(self, seekval=0):
"""
reads file fixed header and returns time string from btime
"""
try:
hdrs = self.fixedhdr(seekval)
# time = string.join(list(map(str, (self.FH.Year, self.FH.Day,
# self.FH.Hour,self.FH.Min,
# self.FH.Sec))), ":")
templist = list(map(str, (self.FH.Year, self.FH.Day, self.FH.Hour,
self.FH.Min, self.FH.Sec)))
time = ":".join(templist)
return time
#########################################################
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 Exception:
#########################################################
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:
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
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 = "<"
#########################################################
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(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)
nextblock = newblock
n += 1
except Exception:
#########################################################
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)
#########################################################
def setEndian(self, endianess=""):
"""
set format string for endian type
"""
if endianess == "big":
fmtorderstr = self.fmt_order
#########################################################
#
# 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)
#########################################################
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
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)
"""
# self.sunpack=self.sunpack
try:
del self.FH
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])
fmtstr = self.fmt_order + "HHBBBBH"
self.FH.timeblk = self.sunpack(fmtstr, fhblk[20:30])
fmtstr = self.fmt_order + "Hhh"
self.FH.sampblk = self.sunpack(fmtstr, fhblk[30:36])
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 # noqa: E501
(self.FH.Year, self.FH.Day, self.FH.Hour, self.FH.Min, self.FH.Sec, junk, self.FH.Micro)\
= self.FH.timeblk # noqa: E501
(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 Exception:
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)
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
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)
self.infilewrite(pack_hdr)
return 48
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 blknum not in ValidBlk:
blk = locals()
callcmd = "blk=self.blk" + str(blknum) + "(" + str(seekval) + ")"
exec(callcmd, {}, 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 blknum not in ValidBlk:
bytes_written = locals()
callcmd = "bytes_written=self.Writeblk" + \
str(blknum) + "(indata" + "," + str(seekval) + ", endian)"
exec(callcmd, {}, 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)
#########################################################
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
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)
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
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)
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
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)
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
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)
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
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)
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)