1#! /usr/bin/env python 2# -*- coding: utf-8 -*- 3from __future__ import (absolute_import, division, print_function, 4 unicode_literals) 5from future.builtins import * # NOQA 6 7import locale 8import os 9import struct 10import sys 11import time 12 13 14locale.setlocale(locale.LC_ALL, 'C') 15 16formats = (str, str, float, int, int, int, float, int, float, float, float, 17 str, str, str, str, str, str, int, int, str) 18 19 20def main(wfdisc): 21 # read wfdisc file line by line 22 for line in wfdisc: 23 # split line into separate fields 24 parts = line.split() 25 26 i = 0 27 for data in parts: 28 # convert each field to desired format (string, float, int) 29 parts[i] = formats[i](data) 30 i += 1 31 32 # build destination name 33 destname = "%s-%s-%s-%s.ASC" % \ 34 (os.path.splitext(parts[16])[0], parts[0], parts[1], 35 time.strftime("%Y%m%d-%H%M%S", time.gmtime(parts[2]))) 36 print("station %s, component %s, %u samples" % (parts[0], parts[1], 37 parts[7])) 38 print("=> %s ..." % destname) 39 40 # check if already there 41 if os.path.exists(destname): 42 print("I won't overwrite existing file \"%s\", skipping..." % 43 os.path.split(destname)[1]) 44 continue 45 46 # read unnormalized data 47 datatonorm = convert(parts) 48 49 # normalize data 50 normalized = [] 51 for i in datatonorm: 52 normalized.append(i * parts[9]) 53 54 # write ASCII file 55 out = open(destname, "w") 56 # write headers 57 for header in buildheader(parts): 58 out.write("%s\n" % header) 59 # write data 60 for value in normalized: 61 out.write("%e\n" % value) 62 out.close() 63 64 65def convert(parts): 66 # open binary data file 67 datafile = open(parts[16], "rb") 68 69 fmt, size = calcfmt(format=parts[13], samples=parts[7]) 70 71 try: 72 datafile.seek(parts[17]) 73 values = struct.unpack(fmt, datafile.read(size)) 74 except Exception: 75 print("error reading binary packed data from \"%s\"" % 76 os.path.split(parts[16])[1]) 77 return False 78 79 datafile.close() 80 81 # if its 4 byte format, we are done 82 if parts[13].lower() in ["t4", "s4"]: 83 return values 84 # 3 byte format 85 86 return False 87 88 89def calcfmt(format, samples): 90 # four byte floats 91 if format.lower() == "s4": 92 fmt = ">" + "i" * samples 93 return (fmt, struct.calcsize(fmt)) 94 # 4 byte integer 95 elif format.lower() == "t4": 96 fmt = ">" + "f" * samples 97 return (fmt, struct.calcsize(fmt)) 98 # 3 byte floats 99 elif format.lower() == "s3": 100 return (False, False) 101 else: 102 return (False, False) 103 104 105def buildheader(parts): 106 headers = [] 107 108 headers.append("DELTA: %e" % (1.0 / parts[8])) 109 headers.append("LENGTH: %u" % parts[7]) 110 headers.append("STATION: %s" % parts[0]) 111 if len(parts[1]) == 3: 112 comp = parts[1][2] 113 else: 114 comp = parts[1] 115 headers.append("COMP: %s" % comp.upper()) 116 headers.append("START: %s" % time.strftime("%Y-%b-%d_%H:%M:%S", 117 time.gmtime(parts[2]))) 118 119 return headers 120 121 122if __name__ == '__main__': 123 try: 124 wfdisc = open(sys.argv[1]) 125 except IndexError: 126 print(""" 127 Usage: css2asc wfdisc-file 128 129 All traces referenced by the given wfdisc file will be converted 130 to ASCII 131 """) 132 except IOError: 133 print("Cannot access file \"%s\"!" % sys.argv[1]) 134 135 main(wfdisc) 136 137 # close file 138 try: 139 wfdisc.close() 140 except Exception: 141 pass 142