from __future__ import unicode_literals from __future__ import print_function from __future__ import division from __future__ import absolute_import from io import open from builtins import str from builtins import int from future import standard_library standard_library.install_aliases() from builtins import object from datetime import datetime import os import numpy as np BINARY = "BINARY" ASCII = "ASCII" class SelFile(object): """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, encoding='utf-8') 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', encoding='utf-8') as f: f.write("\n".join(lines))