From 8e19c4b51518cdf2fd9fb22394730e507391bd5b Mon Sep 17 00:00:00 2001 From: madsmpedersen <m@madsp.dk> Date: Thu, 5 Nov 2015 12:23:17 +0100 Subject: [PATCH] added sel_file.py + tests/test_sel_file.py --- wetb/hawc2/sel_file.py | 134 ++++++++++++++++++++++++++++++ wetb/hawc2/tests/test_sel_file.py | 50 +++++++++++ 2 files changed, 184 insertions(+) create mode 100644 wetb/hawc2/sel_file.py create mode 100644 wetb/hawc2/tests/test_sel_file.py diff --git a/wetb/hawc2/sel_file.py b/wetb/hawc2/sel_file.py new file mode 100644 index 0000000..f6f0e6a --- /dev/null +++ b/wetb/hawc2/sel_file.py @@ -0,0 +1,134 @@ +from datetime import datetime +import os +import numpy as np + + +BINARY = "BINARY" +ASCII = "ASCII" +class SelFile(): + """Class for reading HAWC2 sel-files + Attributes + ---------- + version_id : str + Version id + created : datetime.datetime + Date and Time of creation + result_file : str + Result file name read from file. Note that dat-filename are often used instead + dat_filename : str + Result file name (sel-basename + ".dat") + scans : int + Number of observations/rows/scans + channels : int + Number of channels/sensors/columns (same as 'no_sensors') + no_sensors : int + Number of channels/sensors/columns (same as 'channels') + time : float + Duration of simulation (same as duration) + duration : float + Duration of simulation (same as time) + format : {"BINARY", "ASCII"} + Result file format + sensors : array_like + List of (id, name, unit, description)-tuples + scalefactors : array_like + Array of scale factors. Only if format is BINARY + """ + + def __init__(self, sel_filename): + if not os.path.isfile(sel_filename) or os.path.splitext(sel_filename)[1] != ".sel": + raise Warning("%s cannot be found or is not a legal *.sel file" % os.path.realpath(sel_filename)) + with open(sel_filename) as f: + lines = f.readlines() + + + # parse info lines + def val(line): + return line.split(" : ")[1].strip() + try: + self.version_id = val(lines[1]) + _created = "%s %s" % (val(lines[3]), val(lines[2])) + self.created = datetime.strptime(_created, "%d:%m.%Y %H:%M:%S") + self.result_file = os.path.basename(val(lines[5])) + + except: + pass + + self.dat_filename = sel_filename[:-4] + ".dat" + + _info = lines[8].split() + self.scans = int(_info[0]) + self.no_sensors = self.channels = int(_info[1]) + self.duration = self.time = float(_info[2]) + if len(_info) > 3: + self.format = _info[3].upper() + elif self.no_sensors * self.scans * 2 == os.path.getsize(self.dat_filename): + self.format = "BINARY" + else: + self.format = "ASCII" + + # parse sensor info + self.sensors = [] + for i, line in enumerate(lines[12:12 + self.no_sensors]): + try: + ch = int(line[:7]) + name = str(line[7:43]).strip() + unit = str(line[43:48]).strip() + description = str(line[49:]).strip() + self.sensors.append((ch, name, unit, description)) + except ValueError: + raise Warning("Value error in '%s'\nLine %d supposed to contain number, name, unit and description of sensor %d, but contained:\n%s" % (sel_filename, i + 13, i, line.strip())) + + # parse scalefactors + if self.format == "BINARY": + self.scale_factors = np.array([float(factor) for factor in lines[12 + self.no_sensors + 2:]]) + + +def save(sel_filename, version, time, scans, no_sensors, duration, sensors, scale_factors=None): + """Create HAWC2 sel-file + + Parameters + ---------- + sel_filename : str + Filename + version : str + Version tag + time : datetime.datetime + Date and time of creation + scans : int + Number of scans/observations/rows + no_sensors : int + Number of sensors/channels/columns + duration : int, float + Duration of simulation + sensors : array_like + List of (name, unit, description)-tuples + scale_factors : array_like, optional + Array of scale factors. Only for BINARY format + """ + lines = [] + linesep = "_" * 120 + lines.append(linesep) + lines.append(" Version ID : %s" % version) + lines.append(" " * 60 + "Time : %s" % time.strftime("%H:%M:%S")) + lines.append(" " * 60 + "Date : %s" % time.strftime("%d:%m.%Y")) + lines.append(linesep) + lines.append(" Result file : %s.dat" % sel_filename[:-4]) + lines.append(linesep) + lines.append(" Scans Channels Time [sec] Format") + lines.append(" %8s %3s %8.3f %s" % (scans, no_sensors, duration, ("BINARY", "ASCII")[scale_factors is None])) + lines.append("") + lines.append(' Channel Variable Description ') + lines.append("") + for nr, sensor in enumerate(sensors, 1): + name, unit, description = sensor + lines.append(" %4s %-30s %-10s %s" % (nr, name[:30], unit[:10], description[:512])) + lines.append(linesep) + if scale_factors is not None: + lines.append("Scale factors:") + for sf in scale_factors: + lines.append(" %.5E" % sf) + + with open(sel_filename, 'w') as f: + f.write("\n".join(lines)) + diff --git a/wetb/hawc2/tests/test_sel_file.py b/wetb/hawc2/tests/test_sel_file.py new file mode 100644 index 0000000..a96be5d --- /dev/null +++ b/wetb/hawc2/tests/test_sel_file.py @@ -0,0 +1,50 @@ +''' +Created on 17/07/2014 + +@author: MMPE +''' +import unittest +from wetb.hawc2.sel_file import SelFile, BINARY, ASCII +from datetime import datetime + + +class Test(unittest.TestCase): + + def setUp(self): + unittest.TestCase.setUp(self) + self.testfilepath = "test_files/hawc2io/" + + def test_sel_file_ascii(self): + sf = SelFile(self.testfilepath + "Hawc2ascii.sel") + self.assertEqual(sf.version_id, "HAWC2AERO 2.4w") + self.assertEqual(sf.created, datetime(2013, 1, 24, 10, 2, 19)) + self.assertEqual(sf.result_file, "Hawc2ascii.dat") + self.assertEqual(sf.scans, 800) + self.assertEqual(sf.channels, 28) + self.assertEqual(sf.no_sensors, 28) + self.assertEqual(sf.duration, 20) + self.assertEqual(sf.time, 20) + self.assertEqual(sf.format, ASCII) + self.assertEqual(sf.sensors[0], (1, 'Time', 's', 'Time')) + self.assertEqual(sf.sensors[1], (2, 'WSP gl. coo.,Vy', 'm/s', 'Free wind speed Vy, gl. coo, of gl. pos 2.50, -1.00, -47.50')) + + + def test_sel_file_bin(self): + sf = SelFile(self.testfilepath + "Hawc2bin.sel") + self.assertEqual(sf.version_id, "HAWC2AERO 2.4w") + self.assertEqual(sf.created, datetime(2013, 1, 24, 10, 4, 37)) + self.assertEqual(sf.result_file, "Hawc2bin.dat") + self.assertEqual(sf.scans, 800) + self.assertEqual(sf.channels, 28) + self.assertEqual(sf.no_sensors, 28) + self.assertEqual(sf.duration, 20) + self.assertEqual(sf.time, 20) + self.assertEqual(sf.format, BINARY) + self.assertEqual(sf.sensors[0], (1, 'Time', 's', 'Time')) + self.assertEqual(sf.sensors[1], (2, 'WSP gl. coo.,Vy', 'm/s', 'Free wind speed Vy, gl. coo, of gl. pos 2.50, -1.00, -47.50')) + self.assertEqual(sf.scale_factors[0], 6.25000E-04) + self.assertEqual(sf.scale_factors[1], 5.65540E-02) + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() -- GitLab