2022-06-18 09:44:39 -06:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
import os
|
|
|
|
import re
|
|
|
|
|
|
|
|
import numpy as np
|
|
|
|
|
2022-06-18 10:01:38 -06:00
|
|
|
from datetime import datetime, timedelta
|
|
|
|
|
2022-06-18 09:44:39 -06:00
|
|
|
class Spectrogram:
|
|
|
|
"""Spectrogram class"""
|
|
|
|
|
|
|
|
def __init__(self, path, prefix, ifile, nsub, siteid):
|
|
|
|
"""Define a spectrogram"""
|
|
|
|
|
|
|
|
# Read first file to get number of channels
|
2022-06-18 10:01:38 -06:00
|
|
|
fname = os.path.join(path, f"{prefix}_{ifile:06d}.bin")
|
2022-06-18 09:44:39 -06:00
|
|
|
with open(fname, "rb") as fp:
|
|
|
|
header = parse_header(fp.read(256))
|
|
|
|
|
|
|
|
# Set frequencies
|
2022-06-18 10:01:38 -06:00
|
|
|
freq_cen, bw, nchan = header["freq"], header["bw"], header["nchan"]
|
|
|
|
freq_min, freq_max = -0.5 * bw, 0.5 * bw
|
|
|
|
freq = freq_cen + np.linspace(freq_min, freq_max, nchan, endpoint=False) + freq_max / nchan
|
2022-06-18 09:44:39 -06:00
|
|
|
|
|
|
|
# Loop over subints and files
|
|
|
|
zs = []
|
2022-06-18 10:01:38 -06:00
|
|
|
t = []
|
2022-06-18 09:44:39 -06:00
|
|
|
isub = 0;
|
|
|
|
while isub<nsub:
|
|
|
|
# File name of file
|
2022-06-18 10:01:38 -06:00
|
|
|
fname = os.path.join(path, f"{prefix}_{ifile:06d}.bin")
|
2022-06-18 09:44:39 -06:00
|
|
|
with open(fname, "rb") as fp:
|
|
|
|
next_header = fp.read(256)
|
|
|
|
while next_header:
|
|
|
|
header = parse_header(next_header)
|
2022-06-18 10:01:38 -06:00
|
|
|
t.append(header["utc_start"] + timedelta(seconds=0.5 * header["length"]))
|
|
|
|
zs.append(np.fromfile(fp, dtype=np.float32, count=nchan))
|
2022-06-18 09:44:39 -06:00
|
|
|
next_header = fp.read(256)
|
|
|
|
isub += 1
|
|
|
|
ifile += 1
|
|
|
|
|
|
|
|
self.z = np.transpose(np.vstack(zs))
|
2022-06-18 10:01:38 -06:00
|
|
|
self.t = t
|
2022-06-18 09:44:39 -06:00
|
|
|
self.freq = freq
|
|
|
|
self.siteid = siteid
|
|
|
|
self.nchan = self.z.shape[0]
|
|
|
|
self.nsub = self.z.shape[1]
|
|
|
|
|
|
|
|
|
|
|
|
def parse_header(header_b):
|
|
|
|
header_s = header_b.decode('ASCII').strip('\x00')
|
|
|
|
regex = r"^HEADER\nUTC_START (.*)\nFREQ (.*) Hz\nBW (.*) Hz\nLENGTH (.*) s\nNCHAN (.*)\nNSUB (.*)\nEND\n$"
|
|
|
|
try:
|
|
|
|
match = re.fullmatch(regex, header_s, re.MULTILINE)
|
|
|
|
except AttributeError:
|
|
|
|
match = re.match(regex, header_s, flags=re.MULTILINE)
|
|
|
|
|
|
|
|
utc_start = datetime.strptime(match.group(1), '%Y-%m-%dT%H:%M:%S.%f')
|
|
|
|
|
|
|
|
return {'utc_start': utc_start,
|
|
|
|
'freq': float(match.group(2)),
|
|
|
|
'bw': float(match.group(3)),
|
|
|
|
'length': float(match.group(4)),
|
|
|
|
'nchan': int(match.group(5)),
|
|
|
|
'nsub': int(match.group(6))}
|
|
|
|
|