pycoustic 0.1.9__tar.gz → 0.1.10__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pycoustic-0.1.9 → pycoustic-0.1.10}/PKG-INFO +1 -1
- {pycoustic-0.1.9 → pycoustic-0.1.10}/pycoustic/survey.py +113 -12
- {pycoustic-0.1.9 → pycoustic-0.1.10}/pyproject.toml +1 -1
- {pycoustic-0.1.9 → pycoustic-0.1.10}/README.md +0 -0
- {pycoustic-0.1.9 → pycoustic-0.1.10}/pycoustic/__init__.py +0 -0
- {pycoustic-0.1.9 → pycoustic-0.1.10}/pycoustic/log.py +0 -0
- {pycoustic-0.1.9 → pycoustic-0.1.10}/pycoustic/pycoustic_gui_app-ai.py +0 -0
- {pycoustic-0.1.9 → pycoustic-0.1.10}/pycoustic/pycoustic_gui_app.py +0 -0
- {pycoustic-0.1.9 → pycoustic-0.1.10}/pycoustic/pycoustic_streamlit_gpt5.py +0 -0
- {pycoustic-0.1.9 → pycoustic-0.1.10}/pycoustic/streamlit-ai.py +0 -0
- {pycoustic-0.1.9 → pycoustic-0.1.10}/pycoustic/streamlit-new.py +0 -0
- {pycoustic-0.1.9 → pycoustic-0.1.10}/pycoustic/streamlit_pycoustic_gpt5_dead.py +0 -0
- {pycoustic-0.1.9 → pycoustic-0.1.10}/pycoustic/tkgui.py +0 -0
- {pycoustic-0.1.9 → pycoustic-0.1.10}/pycoustic/weather.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
import pandas as pd
|
2
2
|
import numpy as np
|
3
|
-
from .weather import WeatherHistory
|
3
|
+
# from .weather import WeatherHistory
|
4
4
|
|
5
5
|
|
6
6
|
DECIMALS=1
|
@@ -193,17 +193,17 @@ class Survey:
|
|
193
193
|
pos_summary = []
|
194
194
|
# Daytime
|
195
195
|
period_headers = ["Daytime"]
|
196
|
-
days = log.get_modal(data=log.
|
196
|
+
days = log.get_modal(data=log.get_period(data=log.as_interval(t=day_t), period="days"), by_date=by_date, cols=cols)
|
197
197
|
days.sort_index(inplace=True)
|
198
198
|
pos_summary.append(days)
|
199
199
|
# Evening
|
200
200
|
if log.is_evening():
|
201
201
|
period_headers.append("Evening")
|
202
|
-
evenings = log.get_modal(data=log.
|
202
|
+
evenings = log.get_modal(data=log.get_period(data=log.as_interval(t=evening_t), period="evenings"), by_date=by_date, cols=cols)
|
203
203
|
evenings.sort_index(inplace=True)
|
204
204
|
pos_summary.append(evenings)
|
205
205
|
# Night time
|
206
|
-
nights = log.get_modal(data=log.
|
206
|
+
nights = log.get_modal(data=log.get_period(data=log.as_interval(t=night_t), period="nights"), by_date=by_date, cols=cols)
|
207
207
|
nights.sort_index(inplace=True)
|
208
208
|
pos_summary.append(nights)
|
209
209
|
period_headers.append("Night-time")
|
@@ -234,17 +234,17 @@ class Survey:
|
|
234
234
|
pos_summary = []
|
235
235
|
# Daytime
|
236
236
|
period_headers = ["Daytime"]
|
237
|
-
days = log.counts(data=log.
|
237
|
+
days = log.counts(data=log.get_period(data=log.as_interval(t=day_t), period="days"), cols=cols)
|
238
238
|
days.sort_index(inplace=True)
|
239
239
|
pos_summary.append(days)
|
240
240
|
# Evening
|
241
241
|
if log.is_evening():
|
242
242
|
period_headers.append("Evening")
|
243
|
-
evenings = log.counts(data=log.
|
243
|
+
evenings = log.counts(data=log.get_period(data=log.as_interval(t=evening_t), period="evenings"), cols=cols)
|
244
244
|
evenings.sort_index(inplace=True)
|
245
245
|
pos_summary.append(evenings)
|
246
246
|
# Night time
|
247
|
-
nights = log.counts(data=log.
|
247
|
+
nights = log.counts(data=log.get_period(data=log.as_interval(t=night_t), period="nights"), cols=cols)
|
248
248
|
nights.sort_index(inplace=True)
|
249
249
|
pos_summary.append(nights)
|
250
250
|
period_headers.append("Night-time")
|
@@ -276,7 +276,7 @@ class Survey:
|
|
276
276
|
for key in self._logs.keys():
|
277
277
|
log = self._logs[key]
|
278
278
|
combined_list = []
|
279
|
-
maxes = log.get_nth_high_low(n=n, data=log.
|
279
|
+
maxes = log.get_nth_high_low(n=n, data=log.get_period(data=log.as_interval(t=t), period=period))[["Lmax", "Time"]]
|
280
280
|
maxes.sort_index(inplace=True)
|
281
281
|
combined_list.append(maxes)
|
282
282
|
summary = pd.concat(objs=combined_list, axis=1)
|
@@ -299,15 +299,15 @@ class Survey:
|
|
299
299
|
for key in self._logs.keys():
|
300
300
|
log = self._logs[key]
|
301
301
|
# Day
|
302
|
-
days = log.
|
302
|
+
days = log.get_period(data=log.get_antilogs(), period="days")
|
303
303
|
days = days[leq_cols].apply(lambda x: np.round(10*np.log10(np.mean(x)), DECIMALS))
|
304
304
|
# Night-time
|
305
|
-
nights = log.
|
305
|
+
nights = log.get_period(data=log.get_antilogs(), period="nights")
|
306
306
|
nights = nights[leq_cols].apply(lambda x: np.round(10*np.log10(np.mean(x)), DECIMALS))
|
307
307
|
df = pd.DataFrame
|
308
308
|
# Evening
|
309
309
|
if log.is_evening():
|
310
|
-
evenings = log.
|
310
|
+
evenings = log.get_period(data=log.get_antilogs(), period="evenings")
|
311
311
|
evenings = evenings[leq_cols].apply(lambda x: np.round(10 * np.log10(np.mean(x)), DECIMALS))
|
312
312
|
df = pd.concat([days, evenings, nights], axis=1, keys=["Daytime", "Evening", "Night-time"])
|
313
313
|
else:
|
@@ -344,6 +344,101 @@ class Survey:
|
|
344
344
|
index=["Min", "Max", "Mean"]).drop(columns=["dt"]).round(decimals=1)
|
345
345
|
|
346
346
|
|
347
|
+
|
348
|
+
appid = ""
|
349
|
+
# with open("tests/openweather_app_id.txt") as f:
|
350
|
+
# appid = f.readlines()[0]
|
351
|
+
|
352
|
+
w_dict = {
|
353
|
+
"start": "2022-09-16 12:00:00",
|
354
|
+
"end": "2022-09-17 18:00:00",
|
355
|
+
"interval": 6,
|
356
|
+
"api_key": appid,
|
357
|
+
"country": "GB",
|
358
|
+
"postcode": "WC1",
|
359
|
+
"tz": "GB"
|
360
|
+
}
|
361
|
+
|
362
|
+
|
363
|
+
def test_weather_obj(weather_test_dict):
|
364
|
+
hist = WeatherHistory(start=w_dict["start"], end=w_dict["end"], interval=w_dict["interval"],
|
365
|
+
api_key=w_dict["api_key"], country=w_dict["country"], postcode=w_dict["postcode"],
|
366
|
+
tz=w_dict["tz"])
|
367
|
+
hist.compute_weather_history()
|
368
|
+
return hist
|
369
|
+
|
370
|
+
#TODO: Make this take the start and end times of a Survey object.
|
371
|
+
#TODO: Implement post codes instead of coordinates
|
372
|
+
#TODO: Implement the WeatherHistory as methods within Survey.
|
373
|
+
class WeatherHistory:
|
374
|
+
def __init__(self):
|
375
|
+
return
|
376
|
+
|
377
|
+
def reinit(self, start=None, end=None, interval=6, api_key="", country="GB", postcode="WC1", tz="",
|
378
|
+
units="metric"):
|
379
|
+
if api_key==None:
|
380
|
+
raise ValueError("API key is missing")
|
381
|
+
if type(start) == str:
|
382
|
+
self._start = dt.datetime.strptime(start, "%Y-%m-%d %H:%M:%S")
|
383
|
+
else:
|
384
|
+
self._start = start
|
385
|
+
if type(end) == str:
|
386
|
+
self._end = dt.datetime.strptime(end, "%Y-%m-%d %H:%M:%S")
|
387
|
+
else:
|
388
|
+
self._end = end
|
389
|
+
self._interval = interval
|
390
|
+
self._api_key = str(api_key)
|
391
|
+
self._lat, self._lon = self.get_latlon(api_key=api_key, country=country, postcode=postcode)
|
392
|
+
self._hist = None
|
393
|
+
self._units = units
|
394
|
+
|
395
|
+
def get_latlon(self, api_key="", country="GB", postcode=""):
|
396
|
+
query = str("http://api.openweathermap.org/geo/1.0/zip?zip=" + postcode + "," + country + "&appid=" + api_key)
|
397
|
+
resp = requests.get(query)
|
398
|
+
return resp.json()["lat"], resp.json()["lon"]
|
399
|
+
|
400
|
+
def _construct_api_call(self, timestamp):
|
401
|
+
base = "https://api.openweathermap.org/data/3.0/onecall/timemachine?"
|
402
|
+
query = str(base + "lat=" + str(self._lat) + "&" + "lon=" + str(self._lon) + "&" + "units=" + self._units + \
|
403
|
+
"&" + "dt=" + str(timestamp) + "&" + "appid=" + self._api_key)
|
404
|
+
return query
|
405
|
+
|
406
|
+
def _construct_timestamps(self):
|
407
|
+
next_time = (self._start + dt.timedelta(hours=self._interval))
|
408
|
+
timestamps = [int(self._start.timestamp())]
|
409
|
+
while next_time < self._end:
|
410
|
+
timestamps.append(int(next_time.timestamp()))
|
411
|
+
next_time += dt.timedelta(hours=self._interval)
|
412
|
+
return timestamps
|
413
|
+
|
414
|
+
def _make_and_parse_api_call(self, query):
|
415
|
+
response = requests.get(query)
|
416
|
+
# This drops some unwanted cols like lat, lon, timezone and tz offset.
|
417
|
+
resp_dict = response.json()["data"][0]
|
418
|
+
del resp_dict["weather"] # delete weather key as not useful.
|
419
|
+
# TODO: parse 'weather' nested dict.
|
420
|
+
return resp_dict
|
421
|
+
|
422
|
+
def compute_weather_history(self, drop_cols):
|
423
|
+
# construct timestamps
|
424
|
+
timestamps = self._construct_timestamps()
|
425
|
+
# make calls to API
|
426
|
+
responses = []
|
427
|
+
for ts in timestamps:
|
428
|
+
query = self._construct_api_call(timestamp=ts)
|
429
|
+
response_dict = self._make_and_parse_api_call(query=query)
|
430
|
+
responses.append(pd.Series(response_dict))
|
431
|
+
df = pd.concat(responses, axis=1).transpose()
|
432
|
+
for col in ["dt", "sunrise", "sunset"]:
|
433
|
+
df[col] = df[col].apply(lambda x: dt.datetime.fromtimestamp(int(x))) # convert timestamp into datetime
|
434
|
+
df.drop(columns=drop_cols, inplace=True)
|
435
|
+
return df
|
436
|
+
|
437
|
+
def get_weather_history(self):
|
438
|
+
return self._hist
|
439
|
+
|
440
|
+
|
441
|
+
|
347
442
|
# TODO: Fix this bug in weatherhist
|
348
443
|
# survey.weather(api_key=r"eef3f749e018627b70c2ead1475a1a32", postcode="HA8")
|
349
444
|
# dt temp pressure humidity clouds wind_speed wind_deg \
|
@@ -429,4 +524,10 @@ class Survey:
|
|
429
524
|
# File "C:\Users\tonyr\PycharmProjects\pycoustic\.venv2\Lib\site-packages\numpy\_core\_methods.py", line 48, in _amin
|
430
525
|
# return umr_minimum(a, axis, None, out, keepdims, initial, where)
|
431
526
|
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
432
|
-
# TypeError: '<=' not supported between instances of 'dict' and 'dict'
|
527
|
+
# TypeError: '<=' not supported between instances of 'dict' and 'dict'
|
528
|
+
|
529
|
+
|
530
|
+
#TODO: Fix this error:
|
531
|
+
#
|
532
|
+
# C:\Users\tonyr\PycharmProjects\pycoustic\pycoustic\survey.py:316: FutureWarning:
|
533
|
+
# The behavior of pd.concat with len(keys) != len(objs) is deprecated. In a future version this will raise instead of truncating to the smaller of the two sequences
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|