Hi Cadet-Devs,
I’m running into an issue when trying to evaluate a list of parameters for variables. evaluate_objectives
works fine, but when I include evaluate_callbacks
I get a value error regarding the output bound. Same for both functions when using populations which is the goal here.
I don’t get what the output bounds are doing and how to influence them.
I’m using the add_fractionation_metric branch atm with Python 3.10.13 on VS Code. See my MinExample:
#Process setup
import numpy as np
import CADETProcess
CADETProcess.settings.working_directory = 'C:/CADET_working_directory'
# Example import
from examples.batch_elution.process import process as process1
components = ['A', 'B']
process1.flow_sheet.column.binding_model.adsorption_rate=[0.011, 0.02]
process1.flow_sheet.column.binding_model.desorption_rate=[1, 1]
process1.flow_sheet.column.binding_model.is_kinetic = True
# simulate processes
from CADETProcess.simulator import Cadet
simulator = Cadet(install_path = 'C:\\ProgramData\\Anaconda3\\envs\\cadet_feat_FracMetric\\')
simulation_result = simulator.simulate(process1)
# Reference data
def gaussian(x, mu, sigma, amplitude):
return amplitude * np.exp(-((x - mu) ** 2) / (2 * sigma ** 2))
timepoints = np.arange(0, 601)
y_values_1A = gaussian(timepoints, 5 * 60, 80, 9)
y_values_1B = gaussian(timepoints, 8 * 60, 50, 3)
ref_data1 =np.column_stack((y_values_1A, y_values_1B))
# Comparator
from CADETProcess.comparison import Comparator
from CADETProcess.reference import ReferenceIO
reference = ReferenceIO('ref_' + process1.name, timepoints, ref_data1, component_system= process1.component_system)
# add references to comparator and define difference_metric
comparator = Comparator()
comparator.name = 'comparator'
comparator.add_reference(reference)
comparator.add_difference_metric(
'SSE', reference, 'column.outlet',
components = components
)
# Setup optimization problem
from CADETProcess.optimization import OptimizationProblem
optimization_problem = OptimizationProblem('Min_Example')
optimization_problem.add_evaluation_object(process1, name = process1.name)
optimization_problem.add_evaluator(simulator)
optimization_problem.add_objective(
comparator,
evaluation_objects = process1,
name = 'obj_' + process1.name,
n_objectives = comparator.n_metrics,
requires = [simulator]
)
# Adding variables
optimization_problem.add_variable(
parameter_path = 'flow_sheet.column.binding_model.adsorption_rate',
name = ('adsorption_rate'),
lb = 1e-10, ub=1e15,
transform = 'log',
)
# Callbacks
def callback(results, individual, callbacks_dir = './'):
x_values = ', '.join(f"{num:.5g}" for num in individual.x)
comparator.plot_comparison(
results,
show=0,
file_name=f'''{callbacks_dir}/{comparator.name}_x=[{x_values}]_{individual.id}.png''',
)
optimization_problem.add_callback(
callback,
requires=[simulator],
keep_progress = True
)
should_evaluate = 1
from CADETProcess.optimization import Individual
if should_evaluate == True:
def log_distributed_values(start, end, num_values):
res = np.logspace(np.log10(start), np.log10(end), num_values)
res = res.reshape(-1,1)
return res
def lin_distributed_values(start, end, num_values):
return np.linspace(start, end, num_values)
if optimization_problem.callbacks[0].callbacks_dir == None:
optimization_problem.callbacks[0].callbacks_dir = CADETProcess.settings.working_directory/'callbacks' # must be set for testing callback
values_log = values_lin = []
values_log = log_distributed_values(1e-5, 1e3, 10)
# values_lin = lin_distributed_values(1, 9, 20)
values = np.append(values_log, values_lin)
pop = []
for i, val in enumerate(values):
pop.append(Individual(x = np.array([val])))
optimization_problem.delete_cache()
optimization_problem.setup_cache()
# print(optimization_problem.evaluate_objectives(values[6], force = True)) # works
# print(optimization_problem.evaluate_objectives_population(np.column_stack([values]), force = True))
optimization_problem.evaluate_callbacks(pop[6]) # does not work
# optimization_problem.evaluate_callbacks_population(pop, force = True)
The error message:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[37], line 35
32 print(optimization_problem.evaluate_objectives(1, force = True)) # works
33 # print(optimization_problem.evaluate_objectives_population(np.column_stack([values]), force = True))
---> 35 optimization_problem.evaluate_callbacks(pop[6]) # does not work
36 # optimization_problem.evaluate_callbacks_population(pop, current_iteration = 0, force = True)
File c:\ProgramData\Anaconda3\envs\cadet_feat_FracMetric\lib\site-packages\CADETProcess\optimization\optimizationProblem.py:1588, in OptimizationProblem.evaluate_callbacks(self, ind, current_iteration, force)
1585 callback._current_iteration = current_iteration
1587 try:
-> 1588 self._evaluate(ind.x_transformed, callback, force, untransform=True)
1589 except CADETProcessError:
1590 self.logger.warning(
1591 f'Evaluation of {callback} failed at {ind.x}.'
1592 )
File c:\ProgramData\Anaconda3\envs\cadet_feat_FracMetric\lib\site-packages\CADETProcess\optimization\optimizationProblem.py:136, in OptimizationProblem.untransforms.<locals>.wrapper(self, x, untransform, *args, **kwargs)
134 x = np.array(x, ndmin=1)
135 if untransform:
--> 136 x = self.untransform(x)
138 return func(self, x, *args, **kwargs)
File c:\ProgramData\Anaconda3\envs\cadet_feat_FracMetric\lib\site-packages\CADETProcess\optimization\optimizationProblem.py:2601, in OptimizationProblem.untransform(self, x_transformed)
2598 untransform = np.zeros(x_transformed_2d.shape)
2600 for i, ind in enumerate(x_transformed_2d):
-> 2601 untransform[i, :] = [
2602 var.untransform_fun(value)
2603 for value, var in zip(ind, self.independent_variables)
2604 ]
2606 return untransform.reshape(x_transformed.shape).tolist()
File c:\ProgramData\Anaconda3\envs\cadet_feat_FracMetric\lib\site-packages\CADETProcess\optimization\optimizationProblem.py:2602, in <listcomp>(.0)
2598 untransform = np.zeros(x_transformed_2d.shape)
2600 for i, ind in enumerate(x_transformed_2d):
2601 untransform[i, :] = [
-> 2602 var.untransform_fun(value)
2603 for value, var in zip(ind, self.independent_variables)
2604 ]
2606 return untransform.reshape(x_transformed.shape).tolist()
File c:\ProgramData\Anaconda3\envs\cadet_feat_FracMetric\lib\site-packages\CADETProcess\optimization\optimizationProblem.py:3298, in OptimizationVariable.untransform_fun(self, x)
3297 def untransform_fun(self, x):
-> 3298 return self._transform.untransform(x)
File c:\ProgramData\Anaconda3\envs\cadet_feat_FracMetric\lib\site-packages\CADETProcess\transform.py:205, in TransformBase.untransform(self, x)
186 """Transform the output parameter space to the input parameter space.
187
188 Applies the transformation function _untransform to x after performing output
(...)
200 Transformed parameter values.
201 """
202 if (
203 not self.allow_extended_output and
204 not np.all((self.lb <= x) * (x <= self.ub))):
--> 205 raise ValueError("Value exceeds output bounds.")
206 x = self._untransform(x)
207 if (
208 not self.allow_extended_input and
209 not np.all((self.lb_input <= x) * (x <= self.ub_input))):
ValueError: Value exceeds output bounds.