Compare commits

..

No commits in common. "8bea18af4d5b14610063461e76b7a251bb2157a5" and "ff0891f345789d6d125bcc6fd57d740daec9b7ac" have entirely different histories.

2 changed files with 25 additions and 78 deletions

View file

@ -25,9 +25,7 @@ class RAOBSounding():
def __init__(self, station: str, timestamp: str): def __init__(self, station: str, timestamp: str):
self.station = station self.station = station
self.timestamp = timestamp self.timestamp = timestamp
self.samples = dict()
self.samples_by_pressure = dict()
self.samples_by_height = dict()
def parse_timestamp(self, token: str): def parse_timestamp(self, token: str):
if token[0:2] == '//': if token[0:2] == '//':
@ -60,25 +58,14 @@ class RAOBSounding():
sounding.timestamp_observed = timestamp sounding.timestamp_observed = timestamp
sounding.timestamp_released = timestamp - datetime.timedelta(minutes=45) sounding.timestamp_released = timestamp - datetime.timedelta(minutes=45)
seen = dict() for pressure in sorted(self.samples.keys(), reverse=True):
sounding.samples.append(self.samples[pressure])
for pressure in sorted(self.samples_by_pressure.keys(), reverse=True):
sample = self.samples_by_pressure[pressure]
seen[sample] = True
sounding.samples.append(sample)
for height in sorted(self.samples_by_height.keys()):
sample = self.samples_by_height[height]
if sample not in seen:
sounding.samples.append(sample)
return sounding return sounding
def sample_by_pressure(self, pressure: float): def sample(self, pressure: float):
if pressure in self.samples_by_pressure: if pressure in self.samples:
return self.samples_by_pressure[pressure] return self.samples[pressure]
sample = SoundingSample() sample = SoundingSample()
sample.pressure = pressure sample.pressure = pressure
@ -86,42 +73,19 @@ class RAOBSounding():
sample.height_qa = ' ' sample.height_qa = ' '
sample.temp_qa = ' ' sample.temp_qa = ' '
self.samples_by_pressure[pressure] = sample self.samples[pressure] = sample
return sample
def sample_by_height(self, height: float):
if height in self.samples_by_height:
return self.samples_by_height[height]
sample = SoundingSample()
sample.height = height
sample.pressure_qa = ' '
sample.height_qa = ' '
sample.temp_qa = ' '
self.samples_by_height[height] = sample
return sample return sample
def record_height(self, pressure: float, height: float): def record_height(self, pressure: float, height: float):
if height is None or pressure is None: sample = self.sample(pressure)
return
sample = self.sample_by_pressure(pressure)
sample.height = height sample.height = height
if height not in self.samples_by_height:
self.samples_by_height[height] = sample
def record_temp_dewpoint(self, def record_temp_dewpoint(self,
pressure: float, pressure: float,
temp: float, temp: float,
dewpoint: float): dewpoint: float):
if pressure is None: sample = self.sample(pressure)
return
sample = self.sample_by_pressure(pressure)
sample.temp = temp sample.temp = temp
sample.dewpoint = dewpoint sample.dewpoint = dewpoint
@ -129,10 +93,7 @@ class RAOBSounding():
pressure: float, pressure: float,
wind_speed: float, wind_speed: float,
wind_dir: float): wind_dir: float):
if pressure is None: sample = self.sample(pressure)
return
sample = self.sample_by_pressure(pressure)
sample.wind_speed = wind_speed sample.wind_speed = wind_speed
sample.wind_dir = wind_dir sample.wind_dir = wind_dir
@ -412,29 +373,21 @@ class RAOBObs():
} }
def parse_ppbb_samples(self, tokens: list[str]) -> dict: def parse_ppbb_samples(self, tokens: list[str]) -> dict:
ret = dict()
heights = tokens[0] heights = tokens[0]
if heights[0] != '9': if heights[0] != '9':
return dict() return dict()
if heights[1] != '/': tens = int(heights[1])
tens = int(heights[1]) h1 = 0.3048 * (10000 * tens) + (1000 * int(heights[2]))
h2 = 0.3048 * (10000 * tens) + (1000 * int(heights[3]))
h3 = 0.3048 * (10000 * tens) + (1000 * int(heights[4]))
if len(heights) > 1 and heights[2] != '/' and len(tokens) > 1: return {
h = 0.3048 * (10000 * tens) + (1000 * int(heights[2])) h1: self.parse_wind(tokens[1]),
ret[h] = self.parse_wind(tokens[1]) h2: self.parse_wind(tokens[2]),
h3: self.parse_wind(tokens[3])
if len(heights) > 2 and heights[3] != '/' and len(tokens) > 2: }
h = 0.3048 * (10000 * tens) + (1000 * int(heights[3]))
ret[h] = self.parse_wind(tokens[2])
if len(heights) > 3 and heights[4] != '/' and len(tokens) > 3:
h = 0.3048 * (10000 * tens) + (1000 * int(heights[4]))
ret[h] = self.parse_wind(tokens[3])
return ret
def parse_ppbb(self) -> dict: def parse_ppbb(self) -> dict:
timestamp = self.tokens[0] timestamp = self.tokens[0]
@ -507,8 +460,6 @@ class RAOBChunk():
data = obs.parse_ttaa() data = obs.parse_ttaa()
elif obs.kind == 'TTBB': elif obs.kind == 'TTBB':
data = obs.parse_ttbb() data = obs.parse_ttbb()
elif obs.kind == 'PPBB':
data = obs.parse_ppbb()
if data is None or len(data['samples']) == 0: if data is None or len(data['samples']) == 0:
continue continue
@ -607,13 +558,10 @@ class RAOBReader():
sounding = self.sounding(station, timestamp) sounding = self.sounding(station, timestamp)
for data in samples: for data in samples:
pressure = data.get('pressure') pressure = data['pressure']
height = data.get('height')
if pressure is None and height is not None: if pressure is None:
sample = sounding.sample_by_height(height) continue
sample.wind_speed = data.get('wind_speed')
sample.wind_dir = data.get('wind_dir')
sounding.record_height(pressure, data.get('height')) sounding.record_height(pressure, data.get('height'))

View file

@ -54,10 +54,9 @@ class SoundingSample(DatabaseTable):
self.wind_speed: float = None self.wind_speed: float = None
def __str__(self): def __str__(self):
parts = list() parts = [
("%.2fmb" % self.pressure)
if self.pressure is not None: ]
parts.append("%.2fmb" % self.pressure)
if self.height is not None: if self.height is not None:
parts.append("%.1fm" % self.height) parts.append("%.1fm" % self.height)