Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

163 model filter deprecation warnings #164

Merged
merged 2 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions src/progpy/state_estimators/unscented_kalman_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from filterpy import kalman
from numpy import diag, array
from warnings import warn
from warnings import warn, catch_warnings, simplefilter

from progpy.state_estimators import state_estimator
from progpy.uncertain_data import MultivariateNormalDist, UncertainData
Expand Down Expand Up @@ -54,22 +54,28 @@ def __init__(self, model, x0, **kwargs):
# Saving for reduce pickling

def measure(x):
# Disable deprecation warnings for internal progpy code.
x = model.StateContainer({key: value for (key, value) in zip(x0.keys(), x)})
R_err = model.parameters['measurement_noise'].copy()
model.parameters['measurement_noise'] = dict.fromkeys(R_err, 0)
z = model.output(x)
model.parameters['measurement_noise'] = R_err
return array(list(z.values())).ravel()
with catch_warnings():
simplefilter("ignore", DeprecationWarning)
model.parameters['measurement_noise'] = dict.fromkeys(R_err, 0)
z = model.output(x)
model.parameters['measurement_noise'] = R_err
return array(list(z.values())).ravel()

if 'Q' not in self.parameters:
self.parameters['Q'] = diag([1.0e-3 for _ in x0.keys()])

def state_transition(x, dt):
# Disable deprecation warnings for internal progpy code.
x = model.StateContainer({key: value for (key, value) in zip(x0.keys(), x)})
Q_err = model.parameters['process_noise'].copy()
model.parameters['process_noise'] = dict.fromkeys(Q_err, 0)
x = model.next_state(x, self.__input, dt)
return array(list(x.values())).ravel()
with catch_warnings():
simplefilter("ignore", DeprecationWarning)
model.parameters['process_noise'] = dict.fromkeys(Q_err, 0)
x = model.next_state(x, self.__input, dt)
return array(list(x.values())).ravel()

num_states = len(x0.keys())
num_measurements = model.n_outputs
Expand Down
48 changes: 25 additions & 23 deletions src/progpy/utils/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,21 @@ def frame(self) -> pd.DataFrame:
Returns: frame - pd.DataFrame
"""
warn('frame will be deprecated after version 1.5 of ProgPy.', DeprecationWarning, stacklevel=2)
self._frame = pd.DataFrame(self.matrix.T, columns=self._keys)
self._frame = pd.DataFrame(self._matrix.T, columns=self._keys)
return self._frame

def __reduce__(self):
"""
reduce is overridden for pickles
"""
return (DictLikeMatrixWrapper, (self._keys, self.matrix))
return (DictLikeMatrixWrapper, (self._keys, self._matrix))

def __getitem__(self, key: str) -> int:
"""
get all values associated with a key, ex: all values of 'i'
"""
row = self.matrix[self._keys.index(key)] # creates list from a row of matrix
# Disable deprecation warnings for internal progpy code.
row = self._matrix[self._keys.index(key)] # creates list from a row of matrix
if len(row) == 1: # list contains 1 value, returns that value (non-vectorized)
return row[0]
return row # returns entire row/list (vectorized case)
Expand All @@ -92,20 +93,20 @@ def __setitem__(self, key: str, value: int) -> None:
sets a row at the key given
"""
index = self._keys.index(key) # the int value index for the key given
self.matrix[index] = np.atleast_1d(value)
self._matrix[index] = np.atleast_1d(value)

def __delitem__(self, key: str) -> None:
"""
removes row associated with key
"""
self.matrix = np.delete(self.matrix, self._keys.index(key), axis=0)
self._matrix = np.delete(self._matrix, self._keys.index(key), axis=0)
self._keys.remove(key)

def __add__(self, other: "DictLikeMatrixWrapper") -> "DictLikeMatrixWrapper":
"""
add another matrix to the existing matrix
"""
return DictLikeMatrixWrapper(self._keys, self.matrix + other.matrix)
return DictLikeMatrixWrapper(self._keys, self._matrix + other.matrix)

def __iter__(self):
"""
Expand All @@ -124,11 +125,11 @@ def equals(self, other):
if isinstance(other, dict): # checks that the list of keys for each matrix match
list_key_check = (list(self.keys()) == list(
other.keys())) # checks that the list of keys for each matrix are equal
matrix_check = (self.matrix == np.array(
matrix_check = (self._matrix == np.array(
[[other[key]] for key in self._keys])).all() # checks to see that each row matches
return list_key_check and matrix_check
list_key_check = self.keys() == other.keys()
matrix_check = (self.matrix == other.matrix).all()
matrix_check = (self._matrix == other.matrix).all()
return list_key_check and matrix_check

def __eq__(self, other: "DictLikeMatrixWrapper") -> bool:
Expand All @@ -143,7 +144,7 @@ def __hash__(self):
returns hash value sum for keys and matrix
"""
warn('hash will be deprecated after version 1.5 of ProgPy, will be replace with pandas.util.hash_pandas_object.', DeprecationWarning, stacklevel=2)
return hash(self.keys) + hash(self.matrix)
return hash(self.keys) + hash(self._matrix)

def __str__(self) -> str:
"""
Expand All @@ -163,7 +164,7 @@ def copy(self) -> "DictLikeMatrixWrapper":
"""
creates copy of object
"""
return DictLikeMatrixWrapper(self._keys, self.matrix.copy())
return DictLikeMatrixWrapper(self._keys, self._matrix.copy())

def keys(self) -> list:
"""
Expand All @@ -176,19 +177,20 @@ def values(self) -> np.array:
returns array of matrix values
"""
warn("After v1.5, values will be a property instead of a function.", DeprecationWarning, stacklevel=2)
if len(self.matrix) > 0 and len(
self.matrix[0]) == 1: # if the first row of the matrix has one value (i.e., non-vectorized)
return np.array([value[0] for value in self.matrix]) # the value from the first row
return self.matrix # the matrix (vectorized case)
if len(self._matrix) > 0 and len(
self._matrix[0]) == 1: # if the first row of the matrix has one value (i.e., non-vectorized)
return np.array([value[0] for value in self._matrix]) # the value from the first row
return self._matrix # the matrix (vectorized case)

def items(self) -> zip:
"""
returns keys and values as a list of tuples (for iterating)
"""
if len(self.matrix) > 0 and len(
self.matrix[0]) == 1: # first row of the matrix has one value (non-vectorized case)
return zip(self._keys, np.array([value[0] for value in self.matrix]))
return zip(self._keys, self.matrix)
# Disable deprecation warnings for internal progpy code.
if len(self._matrix) > 0 and len(
self._matrix[0]) == 1: # first row of the matrix has one value (non-vectorized case)
return zip(self._keys, np.array([value[0] for value in self._matrix]))
return zip(self._keys, self._matrix)

def update(self, other: "DictLikeMatrixWrapper") -> None:
"""
Expand All @@ -201,7 +203,7 @@ def update(self, other: "DictLikeMatrixWrapper") -> None:
else: # else it isn't it is appended to self._keys list
# A new key!
self._keys.append(key)
self.matrix = np.vstack((self.matrix, np.array([other[key]])))
self._matrix = np.vstack((self._matrix, np.array([other[key]])))

def __contains__(self, key: str) -> bool:
"""
Expand All @@ -222,10 +224,10 @@ def __repr__(self) -> str:

returns: a string of dictionaries containing all the keys and associated matrix values
"""
if len(self.matrix) > 0 and len(
self.matrix[0]) == 1: # the matrix has rows and the first row/list has one value in it
return str({key: value[0] for key, value in zip(self._keys, self.matrix)})
return str(dict(zip(self._keys, self.matrix)))
if len(self._matrix) > 0 and len(
self._matrix[0]) == 1: # the matrix has rows and the first row/list has one value in it
return str({key: value[0] for key, value in zip(self._keys, self._matrix)})
return str(dict(zip(self._keys, self._matrix)))

InputContainer = DictLikeMatrixWrapper

Expand Down
60 changes: 37 additions & 23 deletions src/progpy/utils/parameters.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright © 2021 United States Government as represented by the Administrator of the
# National Aeronautics and Space Administration. All Rights Reserved.

from warnings import catch_warnings, simplefilter
from collections import UserDict, abc
from copy import deepcopy
import json
Expand All @@ -9,6 +10,7 @@
from scipy.integrate import OdeSolver
import types


from progpy.utils.containers import DictLikeMatrixWrapper
from progpy.utils.next_state import next_state_functions, SciPyIntegrateNextState
from progpy.utils.noise_functions import measurement_noise_functions, process_noise_functions
Expand Down Expand Up @@ -143,18 +145,24 @@ def __setitem__(self, key: str, value: float, _copy: bool = False) -> None:
if 'process_noise_dist' in self and self['process_noise_dist'].lower() not in process_noise_functions:
raise ValueError(f"Unsupported process noise distribution {self['process_noise_dist']}")

if all(value == 0 for value in self['process_noise'].values()):
# No noise, use none function
fcn = process_noise_functions['none']
self._m.apply_process_noise = types.MethodType(fcn, self._m)
elif 'process_noise_dist' in self:
fcn = process_noise_functions[self['process_noise_dist'].lower()]
self._m.apply_process_noise = types.MethodType(fcn, self._m)
else:
# Default to gaussian
fcn = process_noise_functions['gaussian']
self._m.apply_process_noise = types.MethodType(fcn, self._m)
# Disable deprecation warnings for internal progpy code.
with catch_warnings():
simplefilter("ignore", DeprecationWarning)

if all(value == 0 for value in self['process_noise'].values()):
# No noise, use none function
fcn = process_noise_functions['none']
self._m.apply_process_noise = types.MethodType(fcn, self._m)
elif 'process_noise_dist' in self:
fcn = process_noise_functions[self['process_noise_dist'].lower()]
self._m.apply_process_noise = types.MethodType(fcn, self._m)
else:
# Default to gaussian
fcn = process_noise_functions['gaussian']
self._m.apply_process_noise = types.MethodType(fcn, self._m)

#resetwarnings()

# Make sure every key is present
# (single value already handled above)
for key in self._m.states:
Expand Down Expand Up @@ -186,18 +194,24 @@ def __setitem__(self, key: str, value: float, _copy: bool = False) -> None:
if 'measurement_noise_dist' in self and self['measurement_noise_dist'].lower() not in measurement_noise_functions:
raise ValueError(f"Unsupported measurement noise distribution {self['measurement_noise_dist']}")

if all(value == 0 for value in self['measurement_noise'].values()):
# No noise, use none function
fcn = measurement_noise_functions['none']
self._m.apply_measurement_noise = types.MethodType(fcn, self._m)
elif 'measurement_noise_dist' in self:
fcn = measurement_noise_functions[self['measurement_noise_dist'].lower()]
self._m.apply_measurement_noise = types.MethodType(fcn, self._m)
else:
# Default to gaussian
fcn = measurement_noise_functions['gaussian']
self._m.apply_measurement_noise = types.MethodType(fcn, self._m)

# Disable deprecation warnings for internal progpy code.
with catch_warnings():
simplefilter("ignore", category=DeprecationWarning)

if all(value == 0 for value in self['measurement_noise'].values()):
# No noise, use none function
fcn = measurement_noise_functions['none']
self._m.apply_measurement_noise = types.MethodType(fcn, self._m)
elif 'measurement_noise_dist' in self:
fcn = measurement_noise_functions[self['measurement_noise_dist'].lower()]
self._m.apply_measurement_noise = types.MethodType(fcn, self._m)
else:
# Default to gaussian
fcn = measurement_noise_functions['gaussian']
self._m.apply_measurement_noise = types.MethodType(fcn, self._m)

#resetwarnings()

# Make sure every key is present
# (single value already handled above)
if not all([key in self['measurement_noise'] for key in self._m.outputs]):
Expand Down
Loading