Skip to content

Commit

Permalink
added ability to read new .cac format
Browse files Browse the repository at this point in the history
  • Loading branch information
kujaku11 committed Jun 3, 2015
1 parent 1297f3c commit 3d451af
Showing 1 changed file with 195 additions and 21 deletions.
216 changes: 195 additions & 21 deletions mtpy/usgs/zen.py
Original file line number Diff line number Diff line change
Expand Up @@ -2488,11 +2488,6 @@ def plot_spectra(self, fig_num=2):
# Cache files
#==============================================================================
class Cache_Metadata(object):
"""
read .cac metadata
"""

def __init__(self, fn=None, **kwargs):
self.fn = fn
self.ch_adcardsn = None
Expand Down Expand Up @@ -2541,37 +2536,216 @@ def __init__(self, fn=None, **kwargs):
self.ts_npnt = None
self.unit_length = None

self._file_pointer_len = 10


for key in kwargs.keys():
setattr(self, key, kwargs[key])

def read_metadata(self, fn=None):
def read_meta_string(self, meta_string=None):
"""
read in metadata
read in a meta from the raw string
"""
if fn is not None:
self.fn = fn

if meta_string is not None:
self._meta_string = meta_string

line_str_find = -1
with open(self.fn, 'rb') as fid:
# need to skip the file pointer pointer
fid.seek(self._file_pointer_len)

while line_str_find == -1:
line_str = fid.readline().lower()
line_str_find = line_str.find('calibrate')
line_list = line_str.strip().split(',')
l_key = line_list[0].replace('.', '_')
meta_list = self._meta_string.split('\n')
for m_str in meta_list:
line_list = m_str.strip().split(',')
l_key = line_list[0].replace('.', '_').lower()
l_value = line_list[1:]
if len(l_value) == 1:
try:
l_value = float(l_value[0])
except ValueError:
l_value = l_value[0]
setattr(self, l_key, l_value)

class Board_Calibration(object):
"""
deal with baord calibration
"""

def __init__(self, board_cal_str=None, **kwargs):
self.board_cal_str = board_cal_str

self.cal_sys = {}
self.cal_ant = {}

for key in kwargs.keys():
setattr(self, key, kwargs[key])

def read_board_cal_str(self, board_cal_str=None):
"""
read board calibration data
"""

if board_cal_str is not None:
self.board_cal_str = board_cal_str


cal_list = self.board_cal_str.split('\n')
for c_str in cal_list:
c_list = c_str.split(',')
c_key = c_list[0].replace('.', '_').lower()
if len(c_list) == 2:
c_value = c_list[1]
setattr(self, c_key, c_value)
elif len(c_list) > 2:
c_key2 = c_list[1]
c_arr = np.zeros(len(c_list[2:]),
dtype=[('frequency', np.float),
('amplitude', np.float),
('phase', np.float)])
for ii, cc in enumerate(c_list[2:]):
c_arr[ii] = np.array([float(kk) for kk in cc.split(':')])

self.__dict__[c_key][c_key2] = c_arr

class Cache(object):
"""
deal with Zonge .cac files
"""
def __init__(self, fn=None, **kwargs):
self.fn = fn

self.metadata = None
self.time_series = None
self.other = None
self.calibration = None

self._flag_len = 10
self._len_bytes = 4
self._flag_dtype = [('length', np.int32),
('flag', np.int32),
('type', np.int16)]


self._type_dict = {4:'navigation',
514:'metadata',
768:'calibration',
16:'time_series',
15:'other',
640:'status'}

self._f_tell = 0

def _read_file_block(self, file_id):
"""
read a cache block
"""
file_pointer = np.fromstring(file_id.read(self._flag_len),
dtype=self._flag_dtype)
f_str = file_id.read(file_pointer['length']-2)
end_len = np.fromstring(file_id.read(self._len_bytes),
dtype=np.int32)

if self._validate_block_len(file_pointer, end_len) is True:
self._f_tell = file_id.tell()
return file_pointer, f_str

def _validate_block_len(self, file_pointer, end_length):
"""
validate that the block lengths as defined at the beginning and
the end are the same
"""

try:
assert file_pointer['length'] == end_length
return True
except AssertionError:
raise ValueError('File pointer length {0} != end length {1}'.format(
file_pointer['length'], end_length))

def read_cache_metadata(self, fn=None):
"""
read .cac file
"""
if fn is not None:
self.fn = fn

f_pointer = True
with open(self.fn, 'rb') as fid:
while f_pointer:
# read in first pointer
f_pointer, f_str = self._read_file_block(fid)

# if the data type is the meta data
if int(f_pointer['type']) == 514:
meta_obj = Cache_Metadata()
meta_obj.read_meta_string(f_str)

key = self._type_dict[int(f_pointer['type'])]
setattr(self, key, meta_obj)
print 'Read in metadata'
return


def read_cache_file(self, fn=None):
"""
read .cac file
"""
if fn is not None:
self.fn = fn

f_pointer = True
with open(self.fn, 'rb') as fid:
while f_pointer:
# read in first pointer
f_pointer, f_str = self._read_file_block(fid)

# if the data type is the meta data
if int(f_pointer['type']) == 514:
meta_obj = Cache_Metadata()
meta_obj.read_meta_string(f_str)

key = self._type_dict[int(f_pointer['type'])]
setattr(self, key, meta_obj)
print 'Read in metadata'
continue

# if the data type is calibration
elif int(f_pointer['type']) == 768:
cal_obj = Board_Calibration(f_str)
cal_obj.read_board_cal_str()

key = self._type_dict[int(f_pointer['type'])]
setattr(self, key, cal_obj)
print 'Read in calibration'
continue

# if the data type is time series
elif int(f_pointer['type']) == 16:
ts_arr = np.fromstring(f_str, dtype=np.int32)
ts_arr = np.resize(ts_arr, (int(self.metadata.ts_npnt),
len(self.metadata.ch_cmp)))


ts = np.zeros(1,
dtype=[(cc.lower(), np.int32,
(int(self.metadata.ts_npnt),)) for
cc in self.metadata.ch_cmp])

for ii, cc in enumerate(self.metadata.ch_cmp):
ts[cc.lower()][:] = ts_arr[:, ii]
key = self._type_dict[int(f_pointer['type'])]
setattr(self, key, ts)
print 'Read in time series, # points = {0}'.format(
self.metadata.ts_npnt)
return
# if the data type is time series
elif int(f_pointer['type']) == 15:
ts = np.fromstring(f_str, dtype=np.int32)



key = self._type_dict[int(f_pointer['type'])]
setattr(self, key, ts)
print 'Read in other'
continue

#==============================================================================
#
#==============================================================================
class ZenCache(object):
"""
deals with cache files or combined time series files.
Expand Down

0 comments on commit 3d451af

Please sign in to comment.