"""
http://www.unidata.ucar.edu/data/lightning/nldn.html
"""
import struct
from datetime import datetime, timedelta, timezone
import pandas as pd
[docs]
class NLDNProduct:
"""Simple class representing obs found in a NLDNProduct."""
def __init__(self):
"""Constructor."""
self.header = ""
self.df = None
[docs]
def sql(self, cursor):
"""Persist data to the database"""
if self.df is None:
return
for _, row in self.df.iterrows():
table = f"nldn{row['valid']:%Y_%m}"
giswkt = f"SRID=4326;POINT({row['longitude']} {row['latitude']})"
cursor.execute(
f"INSERT into {table} (valid, geom, signal, multiplicity, "
"axis, eccentricity, ellipse, chisqr) VALUES (%s, "
"%s, %s, %s, %s, %s, %s, %s)",
(
row["valid"],
giswkt,
row["signal"],
row["multiplicity"],
row["axis"],
row["eccentricity"],
row["ellipse"],
row["chisqr"],
),
)
[docs]
def parser(buf):
"""NLDN (unencrypted product)"""
np = NLDNProduct()
_ = buf.read(4) # NLDN
records = struct.unpack(">i", buf.read(4))
np.header = buf.read(records[0] * 28 - 8) # SGDS SUNY@ALBANY Thu Sep ...
rows = []
while True:
chunk = buf.read(28)
if not chunk:
break
(tsec, nsec, lat1000, lon1000) = struct.unpack(">4i", chunk[:16])
secs = float(tsec) + (nsec / 1000000.0)
ts = datetime(1970, 1, 1) + timedelta(seconds=secs)
ts = ts.replace(tzinfo=timezone.utc)
(_, sgnl10, _) = struct.unpack(">3h", chunk[16:22])
(multi, _, axis, eccentricity, ellipse, chisqr) = struct.unpack(
"6b", chunk[22:28]
)
rows.append(
dict(
valid=ts,
latitude=lat1000 / 1000.0,
longitude=lon1000 / 1000.0,
signal=sgnl10 / 10.0,
multiplicity=multi,
axis=axis,
eccentricity=eccentricity,
ellipse=ellipse,
chisqr=chisqr,
)
)
if rows:
np.df = pd.DataFrame(rows)
return np