Created
August 27, 2023 00:19
-
-
Save tenomoto/d4ab2921d8d7a9ce7949ca4ff8c44c89 to your computer and use it in GitHub Desktop.
Decode TEMP ship reports in TAC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import sys | |
def decode_meta(rep): | |
dd = rep[2][:2] | |
hh = rep[2][2:4] | |
lat = int(rep[6][2:]) * 0.1 | |
lon = int(rep[7][1:]) * 0.1 | |
meta = {"dd":dd, "hh":hh, "vessel":rep[4], "lon":lon, "lat":lat} | |
return meta | |
def decode_pres(fld, pmin=200): | |
p = int(fld[2:]) | |
if p < pmin: p += 1000 | |
return p | |
def decode_preshgt(fld, pmin=200): | |
lev = fld[:2] | |
if lev == "99": | |
p = decode_pres(fld) | |
z = 0.0 | |
else: | |
p = int(lev) | |
p *= 10 | |
if p == 0: p = 1000 | |
if p == 920: p +=5 | |
z = int(fld[2:]) | |
if p == 850: z += 1000 | |
elif p == 700: | |
if z > 500: z+= 2000 | |
else: z+= 3000 | |
elif p <= 500 and p >= 300: z *= 10 | |
elif p <= 250 : z = (z + 1000) * 10 | |
return p, z | |
def negate_odd(T): | |
return -2 * (T % 2) + 1 | |
def decode_ttd(fld): | |
if fld != "/////": | |
T = int(fld[:3]) | |
T = negate_odd(T) * T * 0.1 | |
TTdstr = fld[3:5] | |
if TTdstr != "//": | |
Td = T - int(TTdstr) * 0.1 | |
else: | |
Td = float("nan") | |
else: | |
T, Td = float("nan"), float("nan") | |
return T, Td | |
def decode_wind(fld): | |
dstr = fld[:3] | |
if fld[:3] != "///": | |
d = int(dstr) | |
dmod5 = d % 5 | |
d = d - dmod5 | |
sstr = fld[3:5] | |
if sstr != "///": | |
s = int(sstr) + dmod5 * 100 | |
else: | |
s = float("nan") | |
else: | |
d = float("nan") | |
return d, s | |
def decode_sst(fld): | |
sst = int(fld[2:5]) * 0.1 | |
if fld[1] != "0": sst *= -1 | |
return sst | |
def decode_aa(rep, r=9): | |
pres = [] | |
ghgt = [] | |
tcel = [] | |
tdew = [] | |
dire = [] | |
magn = [] | |
while rep[r][:2] != "88": | |
p, z = decode_preshgt(rep[r]) | |
pres.append(p) | |
ghgt.append(z) | |
T, Td = decode_ttd(rep[r+1]) | |
tcel.append(T) | |
tdew.append(Td) | |
d, s = decode_wind(rep[r+2]) | |
dire.append(d) | |
magn.append(s) | |
r += 3 | |
while rep[r] != "31313": r +=1 | |
while rep[r][0] != "9" : r +=1 | |
sst = decode_sst(rep[r]) | |
return pres, ghgt, tcel, tdew, dire, magn, sst | |
def decode_bb(rep, r=9): | |
prst = [] | |
tcel = [] | |
tdew = [] | |
prsw = [] | |
dire = [] | |
magn = [] | |
while rep[r] != "21212": | |
p = decode_pres(rep[r]) | |
prst.append(p) | |
T, Td = decode_ttd(rep[r+1]) | |
tcel.append(T) | |
tdew.append(Td) | |
r += 2 | |
r += 1 | |
while rep[r] != "31313": | |
p = decode_pres(rep[r]) | |
prsw.append(p) | |
d, s = decode_wind(rep[r+1]) | |
dire.append(d) | |
magn.append(s) | |
r += 2 | |
while rep[r][0] != "9" : r +=1 | |
sst = decode_sst(rep[r]) | |
while rep[r] != "61616": r +=1 | |
r +=1 | |
while True: | |
p = decode_pres(rep[r]) | |
prsw.append(p) | |
d, s = decode_wind(rep[r+1]) | |
dire.append(d) | |
magn.append(s) | |
if rep[r+1][-1] == "=": | |
break | |
else: | |
r += 2 | |
return prst, tcel, tdew, prsw, dire, magn, sst | |
def save_csv(outfname, meta, *record): | |
with open(outfname, "w") as g: | |
g.write(f"{meta['vessel']},{meta['dd']},{meta['hh']},{meta['lon']},{meta['lat']},{meta['sst']}\n") | |
for t in zip(*record): | |
r = ",".join(map(str,t)) + "\n" | |
g.write(r) | |
if __name__ == "__main__": | |
vessel_set = {"7JJW", "7JEJ", "7KBR", "7JAI"} # edit as needed | |
debug = False | |
if len(sys.argv) < 3: | |
print(f"Usage :: python {sys.argv[0]} infname outdir") | |
sys.exit() | |
infname = sys.argv[1] | |
outdir = sys.argv[2] | |
print(infname, outdir) | |
with open(infname, "r") as f: | |
rep = f.read().split() | |
meta = decode_meta(rep) | |
print(meta) | |
if meta["vessel"] in vessel_set: | |
part = rep[3][2:] | |
print(part) | |
if part == "AA": | |
pres, ghgt, tcel, tdew, dire, magn, sst = decode_aa(rep) | |
meta["sst"] = sst | |
if debug: | |
for p, z, T, Td, d, s in zip(pres, ghgt, tcel, tdew, dire, magn): | |
print(p, z, T, Td, d, s) | |
print(meta) | |
outfname = f"{meta['vessel']}-{meta['dd']}{meta['hh']}_{part}.csv" | |
outfname = os.path.join(outdir, outfname) | |
print(outfname) | |
save_csv(outfname, meta, pres, ghgt, tcel, tdew, dire, magn) | |
if part == "BB": | |
prst, tcel, tdew, prsw, dire, magn, sst = decode_bb(rep) | |
meta["sst"] = sst | |
print(meta) | |
if debug: | |
for p, T, Td in zip(prst, tcel, tdew): | |
print(p, T, Td) | |
for p, d, s in zip(prsw, dire, magn): | |
print(p, d, s) | |
print(sst) | |
outfname = f"{meta['vessel']}-{meta['dd']}{meta['hh']}_{part}_temp.csv" | |
outfname = os.path.join(outdir, outfname) | |
print(outfname) | |
save_csv(outfname, meta, prst, tcel, tdew) | |
outfname = f"{meta['vessel']}-{meta['dd']}{meta['hh']}_{part}_wind.csv" | |
outfname = os.path.join(outdir, outfname) | |
print(outfname) | |
save_csv(outfname, meta, prsw, dire, magn) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment