-
David Verelst authoredDavid Verelst authored
sel_file.py 5.17 KiB
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))