Source code for irfpy.swim.swimio
''' This is a packet that treats the SWIM data (counts, flux, and so on).
'''
# To update the version:
# Implement SwimStartDataVXXX
# Implement dump_vXXX
# Implement load_vXXX
# Increlemnt default_version
import io
import sys
import logging
import dateutil.parser
from io import StringIO
import numpy
import Sadppac
from irfpy.util import utc
import datetime
default_version = 1
[docs]class SwimCounterData:
''' Abstract class for SWIM counter data.
'''
def __init__(self):
pass
[docs]class SwimCounterDataV1(SwimCounterData):
''' The implementation, version 1.
Version 1 only contains the observation time (datetime object) and
the count rate (E=16xD=16 numpy array). Only 16x16 data is processed.
If there are no data available, -1 is recorded.
The data can be accessed by the attribute of utc and cnt.
You can also even set the cnt directly through the attribute.
'''
def __init__(self):
self.logger=logging.getLogger(self.__class__.__name__)
self.utc=None
self.cnt=-numpy.ones((16,16))
[docs] def setData(self, ut, arr16x16):
self.utc=utc.convert(ut, datetime.datetime)
self.cnt=numpy.array(arr16x16)
def __str__(self):
s=StringIO()
s.write('%s' % self.utc)
for ie in range(16):
for id in range(16):
s.write(" %g" % self.cnt[ie][id])
str=s.getvalue()
s.close()
return str
[docs] def setFromPacket(self, packet,
counter=Sadppac.SwimAccumTotMatx.START_COUNTER):
''' Set the contents of the instance from the packet.
The packet contents are directly loaded to the instance.
This is a specialized method, and no manipulation of the count data
is possible. Youmay use setData() method to make general way of
setting data to the instance.
'''
if packet.getDeflectionBins() != 8 or packet.getEnergyBins() != 32:
self.logger.warn('Data for %s is not in full mode. Skipped.'
% packet.getUtc())
return
self.utc=utc.tt2dt(packet.getUtc())
self.cnt=numpy.zeros((16,16))
accum=packet.getAccumTotMatx()
accum=accum.reform16x16()
for ie in range(16):
for id in range(16):
self.cnt[ie][id] = accum.get(ie, id, counter)
[docs] def setFromString(self, str):
''' Set the contents of the instance from the string.
The string, which is formatted by __str__() method, is analyzed
and the contents of the string is loaded to the string.
In this sense, this is the inverse function of __str__().
'''
dataarr=str.split()
if len(dataarr)!=258:
self.logger.warn('Data string is not consistent.\n%s\n'%str)
raise RuntimeError('Data string is not consistent.')
ut = dataarr[0] + 'T' + dataarr[1]
ut=dateutil.parser.parse(ut)
self.utc=ut
varr=[float(v) for v in dataarr[2:]]
varr=numpy.array(varr)
varr.shape=(16,16)
self.cnt=varr
[docs]def dump_v1(arrSwimCounterDataV1, file, header=None):
''' Dump the array of SwimCounterData into the
'''
logger = logging.getLogger('dump_v1')
logger.setLevel(logging.DEBUG)
print("#% irfpy.sara.swim.io.SwimCountData", file=file)
print("#% VERSION=1", file=file)
if header is not None:
for h in header.split('\n'):
print("# %s" % h, file=file)
for pac in arrSwimCounterDataV1:
print(pac, file=file)
[docs]def load_v1(file):
''' Loader of the file, version 1.
'''
arr=[]
for line in file:
l=line.strip()
if l.startswith('#'):
continue
s=SwimCounterDataV1()
try:
s.setFromString(l)
arr.append(s)
except RuntimeError:
pass
return arr
[docs]def dump(arrSwimCounterData, file, version=default_version, *arg, **kwds):
''' Dump swim packet to the specified file.
swimpacket is an object of SWIM packet. file is the file descripter,
i.e. instance which has write() method.
If version is specified, the corresponding version of the dump method
is used.
'''
logger = logging.getLogger('dump')
logger.setLevel(logging.DEBUG)
logger.debug(version)
logger.debug('Specified version=%d' % version)
if version == 1:
if "header" in kwds:
header=kwds["header"]
else:
header=None
dump_v1(arrSwimCounterData, file, header=header)
else:
raise RuntimeError('Failed to use the version %d.' % version)
[docs]def load(file, *arg, **kwds):
''' Load swim packet to the specified file.
'''
for line in file:
if line.startswith('#%'):
if not line.startswith('#% irfpy.sara.swim.io.SwimCountData'):
raise RuntimeError('Header (1) collapsed.')
else:
break
for line in file:
if line.startswith('#%'):
if not line.startswith('#% VERSION='):
raise RuntimeError('Header (2) collapsed.')
else:
h,v=line.strip().split('=')
version=int(v)
break
if version==1:
return load_v1(file)
else:
raise RuntimeError('Version %d is not supported' % version);