Skip to content
31 changes: 22 additions & 9 deletions PyFina/PyFina.py
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid Exception IndexError: index 0 is out of bounds for axis 0 with size 0,
when finiteness_obj.sum() = 0.
from line 148 np.where(finiteness_obj)[0][0]

Copy link
Contributor

@alexandrecuer alexandrecuer Dec 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mano8 : Just a wondering after integrating your datas in the tests : why do you record temperature (I guess it is temperature but maybe something else) each 1 seconds ? do you use a wired sensor ? I guess no otherwise you wouldn't have so many nan :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the file size. This file was generated from other files, with NaN values intentionally added for testing purposes. The source files contain solar battery voltage records sampled every second. They were created for testing in a different project. Feel free to exclude this file from the repository. :-)

Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ def getMeta(feed_id: int, data_dir: str) -> Literal[False] | dict[str, int]:
npoints (4 bytes, Unsigned integer, Legacy : use instead filesize//4 )
interval (4 bytes, Unsigned integer)
start_time (4 bytes, Unsigned integer)
Returns:
dict with keys: interval, start_time, npoints, end_time
where end_time is the timestamp of the last data point
"""
with open(f"{data_dir}/{feed_id}.meta", "rb") as f:
f.seek(8, 0)
Expand All @@ -77,6 +80,7 @@ def getMeta(feed_id: int, data_dir: str) -> Literal[False] | dict[str, int]:
"start_time": decoded[1],
"npoints": os.path.getsize(f"{data_dir}/{feed_id}.dat") // 4,
}
meta['end_time'] = meta['start_time'] + (meta['npoints'] * meta['interval']) - meta['interval']
return meta

class PyFina(np.ndarray):
Expand Down Expand Up @@ -106,14 +110,19 @@ def __new__(
# pos = (time - meta["start_time"]) // meta["interval"]
# Nota : if remove_nan is True and a NAN is detected, the algorithm takes previous value
obj = super().__new__(cls, shape=(npts,))
#obj = np.zeros(npts).view(cls)
pyfina_logger.debug(obj)
obj.fill(np.nan)
raw_obj = np.empty(npts)

raw_obj.fill(np.nan)
pyfina_logger.debug(obj)
end = start + (npts - 1) * step
time = start
i = 0
nb_nan = 0
# Avoid Reading file if time >= end_time
if time >= meta['end_time']:
raise ValueError("Error: invalid start value, start must be less than end time value "
"defined by start_time + (npoints * interval) from meta."
)
with open(f"{data_dir}/{feed_id}.dat", "rb") as ts:
while time < end:
time = start + step * i
Expand All @@ -139,18 +148,22 @@ def __new__(
else:
message = f"unpacking problem {i} len is {len(aa)} position is {pos}"
pyfina_logger.error(message)
# End reading loop if pos out of bounds
else:
break
i += 1
first_non_nan_value = -1
first_non_nan_index = -1
starting_by_nan = np.isnan(raw_obj[0])
if nb_nan < npts:
finiteness_obj = np.isfinite(raw_obj)
first_non_nan_index = np.where(finiteness_obj)[0][0]
first_non_nan_value = raw_obj[finiteness_obj][0]
if starting_by_nan and remove_nan:
obj[:first_non_nan_index] = (
np.ones(first_non_nan_index) * first_non_nan_value
)
if finiteness_obj.sum() > 0:
first_non_nan_index = np.where(finiteness_obj)[0][0]
first_non_nan_value = raw_obj[finiteness_obj][0]
if starting_by_nan and remove_nan:
obj[:first_non_nan_index] = (
np.ones(first_non_nan_index) * first_non_nan_value
)
# storing the "signature" of the "sampled" feed
obj.start = start
obj.step = step
Expand Down
1,781 changes: 1,781 additions & 0 deletions tests/PyFina.ipynb

Large diffs are not rendered by default.

Binary file added tests/datas/2.dat
Binary file not shown.
Binary file added tests/datas/2.meta
Binary file not shown.
20 changes: 17 additions & 3 deletions tests/test.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
"""test : open feed and plot image."""

import datetime
import os
import time

import matplotlib
import matplotlib.pyplot as plt
from multigraph import check_starting_nan
from PyFina import getMeta, PyFina

FEED_NB = 1
DATA_DIR = "./datas"
DATA_DIR = os.path.join(
os.path.abspath(os.getcwd()),
"datas"
)
if not os.path.isdir(DATA_DIR):
DATA_DIR = os.path.join(
os.path.abspath(os.getcwd()),
"tests",
"datas"
)
if not os.path.isdir(DATA_DIR):
raise FileNotFoundError(f"Could not find data directory in any location: {DATA_DIR}")

meta = getMeta(FEED_NB, DATA_DIR)
print(meta)
STEP = 3600
Expand All @@ -23,7 +35,7 @@
check_starting_nan("température extérieure", temp_ext)

localstart = datetime.datetime.fromtimestamp(start)
utcstart = datetime.datetime.utcfromtimestamp(start)
utcstart = datetime.datetime.fromtimestamp(start, datetime.timezone.utc)
title = f"starting on :\nUTC {utcstart}\n{time.tzname[0]} {localstart}"
figure = plt.figure(figsize = (10, 10))
matplotlib.rc('font', size=8)
Expand All @@ -33,3 +45,5 @@
plt.xlabel("time in hours")
plt.plot(temp_ext)
figure.savefig(f"feed_{FEED_NB}.png")
if os.environ.get('DISPLAY_PLOTS', '').lower() == 'true':
plt.show()
Loading