Skip to content

Commit

Permalink
updating data in Containers
Browse files Browse the repository at this point in the history
  • Loading branch information
mstraut committed Aug 17, 2023
1 parent 9e38b35 commit b6ef7f2
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 61 deletions.
18 changes: 12 additions & 6 deletions src/progpy/ProgPyDataFrame.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,18 @@ def get_progpy_dict(self):
return self.to_dict('records')[0]

def add_row(self, row):
if not row.empty:
if isinstance(row, ProgPyDataFrame):
row = row.get_progpy_dict()
elif self.empty:
self.loc[0] = row
elif not self.empty:
if isinstance(row, ProgPyDataFrame):
row_check = row.empty
else:
row_check = row
if not row_check:
if self.empty:
for col in row.columns:
self[col] = row[col]
self.reset_index(drop=True)
else:
if isinstance(row, ProgPyDataFrame):
row = row.get_progpy_dict()
self.loc[len(self)] = row

# def __repr__(self) -> str:
Expand Down
18 changes: 10 additions & 8 deletions src/progpy/models/battery_electrochem.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ def output(self, x):
params = self.parameters
An = params['An']
# Negative Surface
xnS = x['qnS']/params['qSMax']
xnS = x['qnS'][0] /params['qSMax']
xnS2 = xnS+xnS # Note: in python x+x is more efficient than 2*x

one_minus_xnS = 1 - xnS
Expand All @@ -526,7 +526,7 @@ def output(self, x):
An[11]*(xnS2_minus_1**12 - (22*xnS*one_minus_xnS)*xnS2_minus_1**10)/F, #Ven11
An[12]*(xnS2_minus_1**13 - (24*xnS*one_minus_xnS)*xnS2_minus_1**11)/F #Ven12
]
Ven = params['U0n'] + R*x['tb']/F*np.log(one_minus_xnS/xnS) + sum(VenParts)
Ven = params['U0n'] + R*x['tb'][0]/F*np.log(one_minus_xnS/xnS) + sum(VenParts)

# Positive Surface
Ap = params['Ap']
Expand All @@ -549,12 +549,14 @@ def output(self, x):
Ap[11]*((xpS2_minus_1)**12 - (22*xpS*one_minus_xpS)*(xpS2_minus_1)**(10))/F, #Vep11
Ap[12]*((xpS2_minus_1)**13 - (24*xpS*one_minus_xpS)*(xpS2_minus_1)**(11))/F #Vep12
]
Vep = params['U0p'] + R*x['tb']/F*np.log(one_minus_xpS/xpS) + sum(VepParts)

return self.OutputContainer(np.array([
np.atleast_1d(x['tb'] - 273.15),
np.atleast_1d(Vep - Ven - x['Vo'] - x['Vsn'] - x['Vsp'])
]))
Vep = params['U0p'] + R*x['tb'][0]/F*np.log(one_minus_xpS/xpS) + sum(VepParts)
columns = ['t', 'v']
data = np.array([
np.atleast_1d(x['tb'][0] - 273.15),
np.atleast_1d(Vep - Ven - x['Vo'][0] - x['Vsn'][0] - x['Vsp'][0])
])
batt_elec_dict = dict(zip(columns, data))
return self.OutputContainer(batt_elec_dict)

def threshold_met(self, x) -> dict:
z = self.output(x)
Expand Down
10 changes: 5 additions & 5 deletions src/progpy/prognostics_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ def apply_process_noise(self, x, dt: float = 1):
Example
-------
>>> from prog_models.models import BatteryCircuit
>>> from progpy.models import BatteryCircuit
>>> m = BatteryCircuit() # Replace with specific model being simulated
>>> u = m.InputContainer([{'i': 2.0}])
>>> z = m.OutputContainer([{'v': 3.2, 't': 295}])
Expand Down Expand Up @@ -357,7 +357,7 @@ def next_state(self, x, u, dt: float):
Example
-------
>>> from prog_models.models import BatteryCircuit
>>> from progpy.models import BatteryCircuit
>>> m = BatteryCircuit() # Replace with specific model being simulated
>>> u = m.InputContainer([{'i': 2.0}])
>>> z = m.OutputContainer([{'v': 3.2, 't': 295}])
Expand Down Expand Up @@ -553,7 +553,7 @@ def event_state(self, x) -> dict:
# Neither Threshold Met nor Event States are overridden
return {}

return {key: 1.0-float(t_met) for (key, t_met) in self.threshold_met(x).items()}
return {key: 1.0-float(t_met) for (key, t_met) in self.threshold_met(x).items()} # BookMark!

def threshold_met(self, x) -> dict:
"""
Expand All @@ -570,7 +570,7 @@ def threshold_met(self, x) -> dict:
e.g., thresholds_met = {'EOL': False} given events = ['EOL']
Example:
>>> from prog_models.models import BatteryCircuit
>>> from progpy.models import BatteryCircuit
>>> m = BatteryCircuit() # Replace with specific model being simulated
>>> u = m.InputContainer([{'i': 2.0}])
>>> z = m.OutputContainer([{'v': 3.2, 't': 295}])
Expand Down Expand Up @@ -942,7 +942,7 @@ def check_thresholds(thresholds_met):
saved_inputs = ProgPyDataFrame()
saved_states = ProgPyDataFrame()
saved_outputs = ProgPyDataFrame()
saved_event_states = []
saved_event_states = ProgPyDataFrame()
horizon = t+config['horizon']
if isinstance(config['save_freq'], tuple):
# Tuple used to specify start and frequency
Expand Down
13 changes: 6 additions & 7 deletions src/progpy/state_estimators/particle_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ def __init__(self, model, x0, **kwargs):
self.parameters['num_particles'] = int(self.parameters['num_particles'])
sample_gen = x0.sample(self.parameters['num_particles'])
samples = [array(sample_gen.key(k), dtype=float64) for k in x0.keys()]

self.particles = model.StateContainer(array(samples, dtype=float64))
self.particles = model.StateContainer(columns=x0.keys(), data=array(samples, dtype=float64).T)

if 'R' in self.parameters:
# For backwards compatibility
Expand Down Expand Up @@ -113,9 +112,9 @@ def estimate(self, t : float, u, z, dt = None):

# Check Types
if isinstance(u, dict):
u = self.model.InputContainer(u)
u = self.model.InputContainer([u])
if isinstance(z, dict):
z = self.model.OutputContainer(z)
z = self.model.OutputContainer([z])

# Optimization
particles = self.particles
Expand All @@ -127,7 +126,7 @@ def estimate(self, t : float, u, z, dt = None):
noise_params = self.parameters['measurement_noise']
num_particles = self.parameters['num_particles']
# Check which output keys are present (i.e., output of measurement function)
measurement_keys = output(self.model.StateContainer({key: particles[key][0] for key in particles.keys()})).keys()
measurement_keys = output(self.model.StateContainer([particles.iloc[0]])).columns
zPredicted = {key: empty(num_particles) for key in measurement_keys}

if self.model.is_vectorized:
Expand All @@ -144,10 +143,10 @@ def estimate(self, t : float, u, z, dt = None):
# Propagate and calculate weights
for i in range(num_particles):
t_i = self.t # Used to mark time for each particle
x = self.model.StateContainer({key: particles[key][i] for key in particles.keys()})
x = self.model.StateContainer([particles])
while t_i < t:
dt_i = min(dt, t-t_i)
x = next_state(x, u, dt_i)
x = next_state(x, u, dt_i)
x = apply_process_noise(x, dt_i)
x = apply_limits(x)
t_i += dt_i
Expand Down
11 changes: 7 additions & 4 deletions src/progpy/utils/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from progpy.utils.next_state import next_state_functions, SciPyIntegrateNextState
from progpy.utils.noise_functions import measurement_noise_functions, process_noise_functions
from progpy.ProgPyDataFrame import ProgPyDataFrame
from progpy.utils.serialization import CustomEncoder, custom_decoder
from progpy.utils.size import getsizeof

Expand Down Expand Up @@ -123,14 +124,16 @@ def __setitem__(self, key: str, value: float, _copy: bool = False) -> None:
# Process noise is single number - convert to dict
if isinstance(self['process_noise'], Number):
self['process_noise'] = self._m.StateContainer([{key: self['process_noise'] for key in self._m.states}])
elif isinstance(self['process_noise'], dict):
if isinstance(self['process_noise'], dict):
noise = self['process_noise']
for key in self._m.states:
# Set any missing keys to 0
if key not in noise.keys():
noise[key] = 0

self['process_noise'] = self._m.StateContainer(noise)
self['process_noise'] = self._m.StateContainer([noise])
# elif isinstance(self['process_noise'], ProgPyDataFrame):
# noise = self['process_noise']
# self['process_noise'] = self._m.StateContainer(noise)

# Process distribution type
if 'process_noise_dist' in self and self['process_noise_dist'].lower() not in process_noise_functions:
Expand Down Expand Up @@ -166,7 +169,7 @@ def __setitem__(self, key: str, value: float, _copy: bool = False) -> None:
# Set any missing keys to 0
if key not in noise.keys():
noise[key] = 0
self['measurement_noise'] = self._m.OutputContainer(noise)
self['measurement_noise'] = self._m.OutputContainer([noise])

# Process distribution type
if 'measurement_noise_dist' in self and self['measurement_noise_dist'].lower() not in measurement_noise_functions:
Expand Down
62 changes: 31 additions & 31 deletions tests/benchmarking.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,42 @@
if __name__ == "__main__":
print('| Test | Time (s) |\n| --- | --- |')

# print(FORMAT_STR.format('import main'), end='')
# t = timeit.timeit('import progpy', timer=process_time)
# print(f'{t} |')
#
# print(FORMAT_STR.format('import thrown object'), end='')
# t = timeit.timeit('from progpy.models import ThrownObject', timer=process_time)
# print(f'{t} |')
#
# print(FORMAT_STR.format('model initialization'), end='')
# t = timeit.timeit('ThrownObject()', 'from progpy.models import ThrownObject', number=1000, timer=process_time)
# print(f'{t} |')
#
# m = ThrownObject()
#
# print(FORMAT_STR.format('set noise'), end='')
# t = timeit.timeit("m.parameters['process_dist'] = 'none'", 'from progpy.models import ThrownObject; m = ThrownObject()', timer=process_time)
# print(f'{t} |')
print(FORMAT_STR.format('import main'), end='')
t = timeit.timeit('import progpy', timer=process_time)
print(f'{t} |')

# print(FORMAT_STR.format('simulate'), end='')
# t = timeit.timeit("m.simulate_to_threshold(future_load, threshold_keys='impact')", 'from progpy.models import ThrownObject; m = ThrownObject(); future_load = lambda t, x=None : m.InputContainer([{}])', number=1000, timer=process_time)
# print(f'{t} |')
print(FORMAT_STR.format('import thrown object'), end='')
t = timeit.timeit('from progpy.models import ThrownObject', timer=process_time)
print(f'{t} |')

# print(FORMAT_STR.format('simulate with saving'), end='')
# t = timeit.timeit("m.simulate_to_threshold(future_load, threshold_keys='impact', save_freq = 0.5)", 'from progpy.models import ThrownObject; m = ThrownObject(); future_load = lambda t, x=None : m.InputContainer({})', number=1000, timer=process_time)
# print(f'{t} |')
print(FORMAT_STR.format('model initialization'), end='')
t = timeit.timeit('ThrownObject()', 'from progpy.models import ThrownObject', number=1000, timer=process_time)
print(f'{t} |')

# print(FORMAT_STR.format('simulate with saving, dt'), end='')
# t = timeit.timeit("m.simulate_to_threshold(future_load, threshold_keys='impact', save_freq = 0.5, dt=0.1)", 'from progpy.models import ThrownObject; m = ThrownObject(); future_load = lambda t, x=None : m.InputContainer({})', number=500, timer=process_time)
# print(f'{t} |')
m = ThrownObject()

print(FORMAT_STR.format('set noise'), end='')
t = timeit.timeit("m.parameters['process_dist'] = 'none'", 'from progpy.models import ThrownObject; m = ThrownObject()', timer=process_time)
print(f'{t} |')

print(FORMAT_STR.format('simulate'), end='')
t = timeit.timeit("m.simulate_to_threshold(future_load, threshold_keys='impact')", 'from progpy.models import ThrownObject; m = ThrownObject(); future_load = lambda t, x=None : m.InputContainer([{}])', number=1000, timer=process_time)
print(f'{t} |')

print(FORMAT_STR.format('simulate with saving'), end='')
t = timeit.timeit("m.simulate_to_threshold(future_load, threshold_keys='impact', save_freq = 0.5)", 'from progpy.models import ThrownObject; m = ThrownObject(); future_load = lambda t, x=None : m.InputContainer({})', number=1000, timer=process_time)
print(f'{t} |')

print(FORMAT_STR.format('simulate with printing results, dt'), end='')
temp_out = StringIO()
sys.stdout = temp_out
t = timeit.timeit("m.simulate_to_threshold(future_load, threshold_keys='impact', save_freq = 0.5, dt=0.1, print = True)", 'from progpy.models import ThrownObject; m = ThrownObject(); future_load = lambda t, x=None : m.InputContainer({})', number=500, timer=process_time)
sys.stdout = sys.__stdout__
print(FORMAT_STR.format('simulate with saving, dt'), end='')
t = timeit.timeit("m.simulate_to_threshold(future_load, threshold_keys='impact', save_freq = 0.5, dt=0.1)", 'from progpy.models import ThrownObject; m = ThrownObject(); future_load = lambda t, x=None : m.InputContainer({})', number=500, timer=process_time)
print(f'{t} |')

# print(FORMAT_STR.format('simulate with printing results, dt'), end='')
# temp_out = StringIO()
# sys.stdout = temp_out
# t = timeit.timeit("m.simulate_to_threshold(future_load, threshold_keys='impact', save_freq = 0.5, dt=0.1, print = True)", 'from progpy.models import ThrownObject; m = ThrownObject(); future_load = lambda t, x=None : m.InputContainer({})', number=500, timer=process_time)
# sys.stdout = sys.__stdout__
# print(f'{t} |')
#
# # print(FORMAT_STR.format('Plot results'), end='')
# # t = timeit.timeit("result.outputs.plot()", "from prog_models.models import ThrownObject; m = ThrownObject(); future_load = lambda t, x=None : m.InputContainer({}); result = m.simulate_to_threshold(future_load, threshold_keys='impact', save_freq = 0.5, dt=0.1)", number=1000, timer=process_time)
Expand Down

0 comments on commit b6ef7f2

Please sign in to comment.