You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
8.9 KiB
Plaintext
279 lines
8.9 KiB
Plaintext
2 years ago
|
#!/usr/bin/env seiscomp-python
|
||
|
|
||
|
from __future__ import print_function
|
||
|
import sys, os
|
||
|
import csv
|
||
|
from optparse import OptionParser
|
||
|
|
||
|
def quote(instr):
|
||
|
return '"'+instr+'"'
|
||
|
|
||
|
class base(object):
|
||
|
def __init__(self, filename, fields):
|
||
|
self.att = {}
|
||
|
fd = open(filename)
|
||
|
try:
|
||
|
try:
|
||
|
fieldNames = None
|
||
|
for row in csv.DictReader(fd, fieldNames):
|
||
|
id = row['id']
|
||
|
if id in self.att:
|
||
|
print("multiple %s found in %s" % (id, filename))
|
||
|
continue
|
||
|
|
||
|
for key in fields:
|
||
|
if not row[key]:
|
||
|
del(row[key])
|
||
|
|
||
|
del row['id']
|
||
|
|
||
|
try:
|
||
|
row['low_freq'] = float(row['low_freq'])
|
||
|
except KeyError:
|
||
|
pass
|
||
|
|
||
|
try:
|
||
|
row['high_freq'] = float(row['high_freq'])
|
||
|
except KeyError:
|
||
|
pass
|
||
|
|
||
|
self.att[id] = row
|
||
|
|
||
|
except KeyError as e:
|
||
|
raise Exception("column %s missing in %s" % (str(e), filename))
|
||
|
|
||
|
except (TypeError, ValueError) as e:
|
||
|
raise Exception("error reading %s: %s" % (filename, str(e)))
|
||
|
|
||
|
finally:
|
||
|
fd.close()
|
||
|
|
||
|
def keys(self):
|
||
|
return list(self.att.keys())
|
||
|
|
||
|
def screname(self, what):
|
||
|
nc = ""
|
||
|
nu = True
|
||
|
for c in what:
|
||
|
if c == '_':
|
||
|
nu = True
|
||
|
continue
|
||
|
if nu:
|
||
|
nc += c.upper()
|
||
|
nu = False
|
||
|
else:
|
||
|
nc += c
|
||
|
|
||
|
if nc == 'LowFreq': nc = 'LowFrequency'
|
||
|
if nc == 'HighFreq': nc = 'HighFrequency'
|
||
|
|
||
|
return nc
|
||
|
|
||
|
def reorder(self):
|
||
|
att = {}
|
||
|
if not self.att:
|
||
|
return None
|
||
|
|
||
|
for (code, row) in self.att.items():
|
||
|
for (k, v) in row.items():
|
||
|
k = self.screname(k)
|
||
|
try:
|
||
|
dk = att[k]
|
||
|
except:
|
||
|
dk = {}
|
||
|
att[k] = dk
|
||
|
|
||
|
try:
|
||
|
dv = dk[str(v)]
|
||
|
except:
|
||
|
dv = []
|
||
|
dk[str(v)] = dv
|
||
|
|
||
|
dv.append(code)
|
||
|
return att
|
||
|
|
||
|
def dump(self, fdo):
|
||
|
att = self.reorder()
|
||
|
lastK=None
|
||
|
|
||
|
for (k, v) in att.items():
|
||
|
if not lastK: lastK = k
|
||
|
if lastK != k:
|
||
|
fdo.write("\n")
|
||
|
for (kv, ids) in v.items():
|
||
|
fdo.write("Ia: %s=%s" % (k,quote(kv)))
|
||
|
for id in ids:
|
||
|
fdo.write(" %s" % id)
|
||
|
fdo.write("\n")
|
||
|
fdo.write("\n")
|
||
|
|
||
|
class sensorAttributes(base):
|
||
|
def __init__(self, filename):
|
||
|
base.__init__(self, filename, ['id', 'type','unit', 'low_freq', 'high_freq', 'model', 'manufacturer', 'remark'])
|
||
|
|
||
|
class dataloggerAttributes(base):
|
||
|
def __init__(self, filename):
|
||
|
base.__init__(self, filename, ['id', 'digitizer_model', 'digitizer_manufacturer', 'recorder_model', 'recorder_manufacturer', 'clock_model', 'clock_manufacturer', 'clock_type', 'remark'])
|
||
|
|
||
|
class INST(object):
|
||
|
def cleanID(self, id):
|
||
|
nc = ""
|
||
|
for c in id:
|
||
|
nc += c
|
||
|
if c == '_':
|
||
|
nc = ""
|
||
|
|
||
|
return nc
|
||
|
|
||
|
def __init__(self, filename, attS, attD):
|
||
|
self.filename = filename
|
||
|
self.sensorA = sensorAttributes(attS)
|
||
|
self.dataloggerA = dataloggerAttributes(attD)
|
||
|
lines = []
|
||
|
f = open(filename)
|
||
|
for line in f:
|
||
|
line = line.strip()
|
||
|
if not line or line[0] == '#':
|
||
|
# Add comments line types
|
||
|
lines.append({ 'content': line, 'type': 'C', 'id': None})
|
||
|
else:
|
||
|
(id, line) = line.split(">", 1)
|
||
|
id = id.strip()
|
||
|
line = line.strip()
|
||
|
# Add undefined line types
|
||
|
lines.append({ 'content': line, 'type': 'U', 'id': id})
|
||
|
f.close()
|
||
|
self.lines = lines
|
||
|
self._filltypes()
|
||
|
|
||
|
def _filltypes(self):
|
||
|
for line in self.lines:
|
||
|
if line['type'] != 'U': continue
|
||
|
id = line['id']
|
||
|
if id.find('_FIR_') != -1:
|
||
|
line['type'] = 'F'
|
||
|
elif id.find('Sngl-gain_') != -1:
|
||
|
line['type'] = 'L'
|
||
|
line['id'] = self.cleanID(id)
|
||
|
elif id.find('_digipaz_') != -1:
|
||
|
line['type'] = 'P'
|
||
|
elif id.find('_iirpaz_') != -1:
|
||
|
line['type'] = 'I'
|
||
|
|
||
|
for line in self.lines:
|
||
|
if line['type'] != 'U': continue
|
||
|
id = self.cleanID(line['id'])
|
||
|
|
||
|
if id in list(self.sensorA.keys()):
|
||
|
line['type'] = 'S'
|
||
|
line['id'] = id
|
||
|
elif id in list(self.dataloggerA.keys()):
|
||
|
line['type'] = 'D'
|
||
|
line['id'] = id
|
||
|
# Those we are forcing !
|
||
|
elif id in ['OSIRIS-SC', 'Gaia', 'LE24', 'MALI', 'PSS', 'FDL', 'CMG-SAM', 'CMG-DCM', 'EDAS-24', 'SANIAC']:
|
||
|
line['id'] = id
|
||
|
line['type'] = 'D'
|
||
|
elif id in ['Trillium-Compact', 'Reftek-151/120', 'BBVS-60', 'CMG-3ESP/60F', 'LE-1D/1', 'L4-3D/BW', 'S13', 'GS13', 'SH-1', 'MP', 'MARKL22', 'CM-3', 'CMG-6T', 'SM-6/BW']:
|
||
|
line['id'] = id
|
||
|
line['type'] = 'S'
|
||
|
|
||
|
for line in self.lines:
|
||
|
if line['type'] == 'U':
|
||
|
print("'"+self.cleanID(line['id'])+"', ", end=' ')
|
||
|
|
||
|
def dump(self, fdo):
|
||
|
sa = False
|
||
|
da = False
|
||
|
|
||
|
dataloggerFieldSize = 0
|
||
|
sensorFieldSize = 0
|
||
|
for line in self.lines:
|
||
|
if line['type'] == 'C': continue
|
||
|
if line['type'] == 'S':
|
||
|
if len(line['id']) > sensorFieldSize:
|
||
|
sensorFieldSize = len(line['id'])
|
||
|
if line['type'] == 'D':
|
||
|
if len(line['id']) > dataloggerFieldSize:
|
||
|
dataloggerFieldSize = len(line['id'])
|
||
|
|
||
|
seLine = "Se: %%%ss %%s\n" % (-1*(sensorFieldSize+1))
|
||
|
dtLine = "Dl: %%%ss %%s\n" % (-1*(dataloggerFieldSize+1))
|
||
|
for line in self.lines:
|
||
|
if line['type'] == 'C':
|
||
|
fdo.write(line['content'] + "\n")
|
||
|
continue
|
||
|
|
||
|
if line['type'] == 'S':
|
||
|
if not sa:
|
||
|
self.sensorA.dump(fdo)
|
||
|
sa = True
|
||
|
fdo.write(seLine % (line['id'], line['content']))
|
||
|
continue
|
||
|
|
||
|
if line['type'] == 'D':
|
||
|
if not da:
|
||
|
self.dataloggerA.dump(fdo)
|
||
|
da = True
|
||
|
fdo.write(dtLine % (line['id'], line['content']))
|
||
|
continue
|
||
|
|
||
|
if line['type'] == 'L':
|
||
|
fdo.write("Cl: %s %s\n" % (line['id'], line['content']))
|
||
|
continue
|
||
|
|
||
|
if line['type'] == 'F':
|
||
|
fdo.write("Ff: %s %s\n" % (line['id'], line['content']))
|
||
|
continue
|
||
|
|
||
|
if line['type'] == 'P':
|
||
|
fdo.write("Pz: %s %s\n" % (line['id'], line['content']))
|
||
|
continue
|
||
|
|
||
|
|
||
|
if line['type'] == 'I':
|
||
|
fdo.write("If: %s %s\n" % (line['id'], line['content']))
|
||
|
continue
|
||
|
|
||
|
def main():
|
||
|
|
||
|
parser = OptionParser(usage="Old tab to New tab converter", version="1.0", add_help_option=True)
|
||
|
|
||
|
parser.add_option("", "--sat", type="string",
|
||
|
help="Indicates the sensor attribute file to use", dest="sat", default="sensor_attr.csv")
|
||
|
parser.add_option("", "--dat", type="string",
|
||
|
help="Indicates the station attribute file to use", dest="dat", default="datalogger_attr.csv")
|
||
|
parser.add_option("-c", "--clean", action="store_true",
|
||
|
help="Remove the comments and blank lines", dest="cleanFile", default=False)
|
||
|
|
||
|
# Parsing & Error check
|
||
|
(options, args) = parser.parse_args()
|
||
|
errors = []
|
||
|
|
||
|
if len(args) != 1:
|
||
|
errors.append("need an Input filename")
|
||
|
|
||
|
if not os.path.isfile(options.sat):
|
||
|
errors.append("sensor attribute file '%s' not found." % options.sat)
|
||
|
|
||
|
if not os.path.isfile(options.dat):
|
||
|
errors.append("datalogger attribute file '%s' not found." % options.dat)
|
||
|
|
||
|
if len(args) == 2 and os.path.isfile(args[1]):
|
||
|
errors.append("output file already exists, will not overwrite.")
|
||
|
|
||
|
if errors:
|
||
|
print("Found error while processing the command line:", file=sys.stderr)
|
||
|
for error in errors:
|
||
|
print(" %s" % error, file=sys.stderr)
|
||
|
return 1
|
||
|
|
||
|
inputName = args[0]
|
||
|
i= INST(inputName, options.sat, options.dat)
|
||
|
fdo = sys.stdout if len(args) < 2 else open(args[1],"w")
|
||
|
i.dump(fdo)
|
||
|
fdo.close()
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main()
|