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

#!/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()