diff --git a/.gitignore b/.gitignore index e5f481e..489d3b7 100644 --- a/.gitignore +++ b/.gitignore @@ -141,3 +141,5 @@ reference/ # Example results examples/*/config/ +test/example_init_shot/*/ +test/example_init_shot/data.out diff --git a/test/example_init_shot/parameter_output_1.yaml b/test/example_init_shot/parameter_output_1.yaml new file mode 100644 index 0000000..e1e91c6 --- /dev/null +++ b/test/example_init_shot/parameter_output_1.yaml @@ -0,0 +1,14 @@ + +iters: 20 + +optimiser: random + +parameters: + Young2: [20, 10, 30] + +output_parameters: + Young: Young2*10 + +objective: + name: analytical + expression: (Young-150)**2 diff --git a/test/example_init_shot/parameter_output_2.yaml b/test/example_init_shot/parameter_output_2.yaml new file mode 100644 index 0000000..d101c79 --- /dev/null +++ b/test/example_init_shot/parameter_output_2.yaml @@ -0,0 +1,16 @@ + +iters: 20 + +optimiser: random + +parameters: + Young2: [20, 10, 30] + +output_parameters: + Young: Young2*10 + +init_shot_from: parameter_output_1.yaml + +objective: + name: analytical + expression: (Young-150)**2 diff --git a/test/example_init_shot/parameter_output_3.yaml b/test/example_init_shot/parameter_output_3.yaml new file mode 100644 index 0000000..423dcf9 --- /dev/null +++ b/test/example_init_shot/parameter_output_3.yaml @@ -0,0 +1,20 @@ + +iters: 2 +max_func_calls: 0 + +optimiser: + name: botorch + acquisition: ucb + beta: 0.9 + n_test: 2 + export: data.out + + +parameters: + Young: [200, 100, 300] + + +objective: + name: analytical + expression: (Young-150)**2 + diff --git a/test/example_init_shot/parameter_output_4.yaml b/test/example_init_shot/parameter_output_4.yaml new file mode 100644 index 0000000..d519421 --- /dev/null +++ b/test/example_init_shot/parameter_output_4.yaml @@ -0,0 +1,20 @@ + +iters: 2 +max_func_calls: 0 + +optimiser: + name: botorch + acquisition: ucb + beta: 0.9 + n_test: 2 + load_file: data.out + + +parameters: + Young: [200, 100, 300] + + +objective: + name: analytical + expression: (Young-150)**2 + diff --git a/test/examples/bo_1call_ei.yaml b/test/examples/bo_1call_ei.yaml new file mode 100644 index 0000000..bd3fbfc --- /dev/null +++ b/test/examples/bo_1call_ei.yaml @@ -0,0 +1,18 @@ + +iters: 2 +max_func_calls: 0 + +optimiser: + name: botorch + acquisition: ei + beta: 0.9 + n_test: 2 + + +parameters: + Young: [200, 100, 300] + + +objective: + name: analytical + expression: (Young-150)**2 diff --git a/test/examples/bo_1call_kg.yaml b/test/examples/bo_1call_kg.yaml new file mode 100644 index 0000000..3ae2aaa --- /dev/null +++ b/test/examples/bo_1call_kg.yaml @@ -0,0 +1,18 @@ + +iters: 2 +max_func_calls: 0 + +optimiser: + name: botorch + acquisition: kg + beta: 0.9 + n_test: 2 + + +parameters: + Young: [200, 100, 300] + + +objective: + name: analytical + expression: (Young-150)**2 diff --git a/test/examples/bo_1call_pi.yaml b/test/examples/bo_1call_pi.yaml new file mode 100644 index 0000000..67815a1 --- /dev/null +++ b/test/examples/bo_1call_pi.yaml @@ -0,0 +1,18 @@ + +iters: 2 +max_func_calls: 0 + +optimiser: + name: botorch + acquisition: pi + beta: 0.9 + n_test: 2 + + +parameters: + Young: [200, 100, 300] + + +objective: + name: analytical + expression: (Young-150)**2 diff --git a/test/examples/bo_1call_qei.yaml b/test/examples/bo_1call_qei.yaml new file mode 100644 index 0000000..d7726fe --- /dev/null +++ b/test/examples/bo_1call_qei.yaml @@ -0,0 +1,18 @@ + +iters: 2 +max_func_calls: 0 + +optimiser: + name: botorch + acquisition: qei + beta: 0.9 + n_test: 2 + + +parameters: + Young: [200, 100, 300] + + +objective: + name: analytical + expression: (Young-150)**2 diff --git a/test/examples/bo_1call_qkg.yaml b/test/examples/bo_1call_qkg.yaml new file mode 100644 index 0000000..dc0a253 --- /dev/null +++ b/test/examples/bo_1call_qkg.yaml @@ -0,0 +1,18 @@ + +iters: 2 +max_func_calls: 0 + +optimiser: + name: botorch + acquisition: qkg + beta: 0.9 + n_test: 2 + + +parameters: + Young: [200, 100, 300] + + +objective: + name: analytical + expression: (Young-150)**2 diff --git a/test/examples/bo_1call_qpi.yaml b/test/examples/bo_1call_qpi.yaml new file mode 100644 index 0000000..9017a36 --- /dev/null +++ b/test/examples/bo_1call_qpi.yaml @@ -0,0 +1,18 @@ + +iters: 2 +max_func_calls: 0 + +optimiser: + name: botorch + acquisition: qpi + beta: 0.9 + n_test: 2 + + +parameters: + Young: [200, 100, 300] + + +objective: + name: analytical + expression: (Young-150)**2 diff --git a/test/examples/bo_1call_qucb.yaml b/test/examples/bo_1call_qucb.yaml new file mode 100644 index 0000000..e40bcbd --- /dev/null +++ b/test/examples/bo_1call_qucb.yaml @@ -0,0 +1,18 @@ + +iters: 2 +max_func_calls: 0 + +optimiser: + name: botorch + acquisition: qucb + beta: 0.9 + n_test: 2 + + +parameters: + Young: [200, 100, 300] + + +objective: + name: analytical + expression: (Young-150)**2 diff --git a/test/examples/design_integral.yaml b/test/examples/design_integral.yaml new file mode 100644 index 0000000..8a8ff03 --- /dev/null +++ b/test/examples/design_integral.yaml @@ -0,0 +1,26 @@ + +iters: 10 + +optimiser: random + + +parameters: + a: [2, 0.5, 4] + + + +objective: + name: design + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + targets: + 'integral_quantity': + quantity: integral + prediction: ['case_1'] + negate: False diff --git a/test/examples/design_missing_quantity_script.yaml b/test/examples/design_missing_quantity_script.yaml new file mode 100644 index 0000000..f93ed14 --- /dev/null +++ b/test/examples/design_missing_quantity_script.yaml @@ -0,0 +1,29 @@ + +iters: 10 + +optimiser: random + + +parameters: + a: [2, 0.5, 4] + + + +objective: + name: design + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + targets: + 'script_quantity': + quantity: + name: script + script: min_script.py # Path to the script + class: MinQuantity # Class name (must be derived from Quantity) + prediction: ['case_1'] + negate: True diff --git a/test/examples/dummy_composite_ei.yaml b/test/examples/dummy_composite_ei.yaml new file mode 100644 index 0000000..8bc8a86 --- /dev/null +++ b/test/examples/dummy_composite_ei.yaml @@ -0,0 +1,27 @@ + +iters: 10 + +optimiser: + name: botorch + acquisition: ei + + +parameters: + a: [0, -4, 4] + + + +objective: + name: fitting + composite: True + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + references: + 'reference_curve.txt': + prediction: ['case_1'] diff --git a/test/examples/dummy_composite_pi.yaml b/test/examples/dummy_composite_pi.yaml new file mode 100644 index 0000000..c71abb1 --- /dev/null +++ b/test/examples/dummy_composite_pi.yaml @@ -0,0 +1,27 @@ + +iters: 10 + +optimiser: + name: botorch + acquisition: pi + + +parameters: + a: [0, -4, 4] + + + +objective: + name: fitting + composite: True + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + references: + 'reference_curve.txt': + prediction: ['case_1'] diff --git a/test/examples/dummy_design_pred_str.yaml b/test/examples/dummy_design_pred_str.yaml new file mode 100644 index 0000000..6360b09 --- /dev/null +++ b/test/examples/dummy_design_pred_str.yaml @@ -0,0 +1,26 @@ + +iters: 10 + +optimiser: random + + +parameters: + a: [2, 0.5, 4] + + + +objective: + name: design + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + targets: + 'maximum_force': + quantity: max + prediction: case_1 + negate: False diff --git a/test/examples/dummy_simple_pred_str.yaml b/test/examples/dummy_simple_pred_str.yaml new file mode 100644 index 0000000..aaf7a02 --- /dev/null +++ b/test/examples/dummy_simple_pred_str.yaml @@ -0,0 +1,25 @@ + +iters: 10 + +optimiser: random + + +parameters: + a: [0, -4, 4] + + + +objective: + name: fitting + composite: False + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + references: + 'reference_curve.txt': + prediction: case_1 diff --git a/test/examples/min_script.py b/test/examples/min_script.py new file mode 100644 index 0000000..be4557d --- /dev/null +++ b/test/examples/min_script.py @@ -0,0 +1,22 @@ +from __future__ import annotations +import numpy as np +from piglot.solver.solver import OutputResult +from piglot.objectives.design import Quantity + +class MinQuantity(Quantity): + """Minimum value of a response.""" + + def compute(self, result: OutputResult) -> float: + """Get the minimum of a given response. + + Parameters + ---------- + result : OutputResult + Output result to compute the quantity for. + + Returns + ------- + float + Quantity value. + """ + return np.min(result.get_data()) diff --git a/test/examples/test_analytical_parallel.yaml b/test/examples/test_analytical_parallel.yaml new file mode 100644 index 0000000..1c8a517 --- /dev/null +++ b/test/examples/test_analytical_parallel.yaml @@ -0,0 +1,18 @@ + + +iters: 0 + + +optimiser: + name: botorch + q: 2 + acquisition: qucb + +parameters: + Young: [200, 100, 300] + poisson: [0.25, 0.1, 0.4] + + +objective: + name: analytical + expression: -((Young/poisson)-500)**2 diff --git a/test/examples_assertions/bo_equalbounds.yaml b/test/examples_assertions/bo_equalbounds.yaml new file mode 100644 index 0000000..3052721 --- /dev/null +++ b/test/examples_assertions/bo_equalbounds.yaml @@ -0,0 +1,18 @@ + +iters: 2 +max_func_calls: 0 + +optimiser: + name: botorch + acquisition: ucb + beta: 0.9 + n_test: 2 + + +parameters: + Young: [300, 100, 300] + + +objective: + name: analytical + expression: 1 diff --git a/test/examples_assertions/bo_q.yaml b/test/examples_assertions/bo_q.yaml new file mode 100644 index 0000000..7203b29 --- /dev/null +++ b/test/examples_assertions/bo_q.yaml @@ -0,0 +1,19 @@ + +iters: 2 +max_func_calls: 0 + +optimiser: + name: botorch + acquisition: ucb + beta: 0.9 + n_test: 2 + q: 2 + + +parameters: + Young: [200, 100, 300] + + +objective: + name: analytical + expression: (Young-150)**2 diff --git a/test/examples_assertions/bo_unkacq.yaml b/test/examples_assertions/bo_unkacq.yaml new file mode 100644 index 0000000..9f02528 --- /dev/null +++ b/test/examples_assertions/bo_unkacq.yaml @@ -0,0 +1,18 @@ + +iters: 2 +max_func_calls: 0 + +optimiser: + name: botorch + acquisition: ucbb + beta: 0.9 + n_test: 2 + + +parameters: + Young: [200, 100, 300] + + +objective: + name: analytical + expression: (Young-150)**2 diff --git a/test/examples_assertions/design_missing_pred.yaml b/test/examples_assertions/design_missing_pred.yaml new file mode 100644 index 0000000..17b0d67 --- /dev/null +++ b/test/examples_assertions/design_missing_pred.yaml @@ -0,0 +1,26 @@ + +iters: 10 + +optimiser: random + + +parameters: + a: [2, 0.5, 4] + + + +objective: + name: design + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + targets: + 'maximum_force': + quantity: max + # prediction: ['case_1'] + negate: False diff --git a/test/examples_assertions/design_missing_quantity.yaml b/test/examples_assertions/design_missing_quantity.yaml new file mode 100644 index 0000000..5fb8580 --- /dev/null +++ b/test/examples_assertions/design_missing_quantity.yaml @@ -0,0 +1,26 @@ + +iters: 10 + +optimiser: random + + +parameters: + a: [2, 0.5, 4] + + + +objective: + name: design + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + targets: + 'maximum_force': + # quantity: max + prediction: ['case_1'] + negate: False diff --git a/test/examples_assertions/design_missing_quantity_class.yaml b/test/examples_assertions/design_missing_quantity_class.yaml new file mode 100644 index 0000000..93dccc0 --- /dev/null +++ b/test/examples_assertions/design_missing_quantity_class.yaml @@ -0,0 +1,29 @@ + +iters: 10 + +optimiser: random + + +parameters: + a: [2, 0.5, 4] + + + +objective: + name: design + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + targets: + 'script_quantity': + quantity: + name: script + script: quantity_script.py # Path to the script + # class: QuantityClass # Class name (must be derived from Quantity) + prediction: ['case_1'] + negate: True diff --git a/test/examples_assertions/design_missing_quantity_name.yaml b/test/examples_assertions/design_missing_quantity_name.yaml new file mode 100644 index 0000000..27876a3 --- /dev/null +++ b/test/examples_assertions/design_missing_quantity_name.yaml @@ -0,0 +1,29 @@ + +iters: 10 + +optimiser: random + + +parameters: + a: [2, 0.5, 4] + + + +objective: + name: design + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + targets: + 'script_quantity': + quantity: + # name: script + script: quantity_script.py # Path to the script + class: QuantityClass # Class name (must be derived from Quantity) + prediction: ['case_1'] + negate: True diff --git a/test/examples_assertions/design_missing_quantity_script.yaml b/test/examples_assertions/design_missing_quantity_script.yaml new file mode 100644 index 0000000..ca7c0b1 --- /dev/null +++ b/test/examples_assertions/design_missing_quantity_script.yaml @@ -0,0 +1,29 @@ + +iters: 10 + +optimiser: random + + +parameters: + a: [2, 0.5, 4] + + + +objective: + name: design + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + targets: + 'script_quantity': + quantity: + name: script + # script: quantity_script.py # Path to the script + class: QuantityClass # Class name (must be derived from Quantity) + prediction: ['case_1'] + negate: True diff --git a/test/examples_assertions/design_missing_solver.yaml b/test/examples_assertions/design_missing_solver.yaml new file mode 100644 index 0000000..085f945 --- /dev/null +++ b/test/examples_assertions/design_missing_solver.yaml @@ -0,0 +1,26 @@ + +iters: 10 + +optimiser: random + + +parameters: + a: [2, 0.5, 4] + + + +objective: + name: design + # solver: + # name: curve + # cases: + # 'case_1': + # expression: * x ** 2 + # parametric: x + # bounds: [-5, 5] + # points: 100 + targets: + 'maximum_force': + quantity: max + prediction: ['case_1'] + negate: False diff --git a/test/examples_assertions/design_missing_targets.yaml b/test/examples_assertions/design_missing_targets.yaml new file mode 100644 index 0000000..8d5b26f --- /dev/null +++ b/test/examples_assertions/design_missing_targets.yaml @@ -0,0 +1,26 @@ + +iters: 10 + +optimiser: random + + +parameters: + a: [2, 0.5, 4] + + + +objective: + name: design + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + # targets: + # 'maximum_force': + # quantity: max + # prediction: ['case_1'] + # negate: False diff --git a/test/examples_assertions/duplicated_field.yaml b/test/examples_assertions/duplicated_field.yaml new file mode 100644 index 0000000..1bde6da --- /dev/null +++ b/test/examples_assertions/duplicated_field.yaml @@ -0,0 +1,45 @@ + +iters: 50 + +optimiser: + name: botorch + n_initial: 1 + n_test: 0 + beta: 1 + acquisition: ucb + + + +parameters: + Young: [300, 100, 300] + + +objective: + name: fitting + solver: + name: links + links: LINKS + cases: + 'prediction_1d.dat': + fields: + 'reaction_x': + name: Reaction + field: x + 'reaction_y': + name: Reaction + field: y + 'prediction_1d_1.dat': + fields: + 'reaction_x': + name: Reaction + field: x + 'reaction_y_1': + name: Reaction + field: y + references: + 'ref_x.reac': + prediction: ['reaction_x', 'reaction_x_1'] + filter_tol: 1e-6 + 'ref_y.reac': + prediction: ['reaction_y', 'reaction_y_1'] + filter_tol: 1e-6 diff --git a/test/examples_assertions/fitting_without_solver.yaml b/test/examples_assertions/fitting_without_solver.yaml new file mode 100644 index 0000000..018bd95 --- /dev/null +++ b/test/examples_assertions/fitting_without_solver.yaml @@ -0,0 +1,33 @@ + +iters: 10 + +optimiser: + name: botorch + + +parameters: + a: [0, -4, 4] + + +objective: + name: fitting + composite: True + stochastic: True + # solver: + # name: curve + # cases: + # 'case_1': + # expression: * x ** 2 + # parametric: x + # bounds: [-5, 5] + # points: 100 + # 'case_2': + # expression: 1.1 * * x ** 2 + # parametric: x + # bounds: [-5, 5] + # points: 100 + + + references: + 'reference_curve.txt': + prediction: ['case_1', 'case_2'] diff --git a/test/examples_assertions/invalid_pred.yaml b/test/examples_assertions/invalid_pred.yaml new file mode 100644 index 0000000..7ee164c --- /dev/null +++ b/test/examples_assertions/invalid_pred.yaml @@ -0,0 +1,20 @@ +iters: 10 + +optimiser: botorch + +parameters: + a: [1, 0, 4] + +objective: + name: fitting + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + references: + 'reference_curve.txt': + prediction: 2 \ No newline at end of file diff --git a/test/examples_assertions/invalid_pred_design.yaml b/test/examples_assertions/invalid_pred_design.yaml new file mode 100644 index 0000000..9b2e559 --- /dev/null +++ b/test/examples_assertions/invalid_pred_design.yaml @@ -0,0 +1,26 @@ + +iters: 10 + +optimiser: random + + +parameters: + a: [2, 0.5, 4] + + + +objective: + name: design + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + targets: + 'maximum_force': + quantity: max + prediction: 2 + negate: False diff --git a/test/examples_assertions/mae_reduction.yaml b/test/examples_assertions/mae_reduction.yaml new file mode 100644 index 0000000..5314d17 --- /dev/null +++ b/test/examples_assertions/mae_reduction.yaml @@ -0,0 +1,34 @@ + +iters: 10 + +optimiser: + name: botorch + + +parameters: + a: [0, -4, 4] + + +objective: + name: fitting + composite: True + stochastic: True + reduction: mae + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + 'case_2': + expression: 1.1 * * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + + + references: + 'reference_curve.txt': + prediction: ['case_1', 'case_2'] diff --git a/test/examples_assertions/missing_pred.yaml b/test/examples_assertions/missing_pred.yaml new file mode 100644 index 0000000..df4d999 --- /dev/null +++ b/test/examples_assertions/missing_pred.yaml @@ -0,0 +1,26 @@ + +iters: 10 + +optimiser: random + + +parameters: + a: [0, -4, 4] + + + +objective: + name: fitting + composite: False + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + references: + 'reference_curve.txt': + asd: False + # prediction: ['case_1'] diff --git a/test/examples_assertions/missing_references.yaml b/test/examples_assertions/missing_references.yaml new file mode 100644 index 0000000..ade2f7b --- /dev/null +++ b/test/examples_assertions/missing_references.yaml @@ -0,0 +1,33 @@ + +iters: 10 + +optimiser: + name: botorch + + +parameters: + a: [0, -4, 4] + + +objective: + name: fitting + composite: True + stochastic: True + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + 'case_2': + expression: 1.1 * * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + + + # references: + # 'reference_curve.txt': + # prediction: ['case_1', 'case_2'] diff --git a/test/examples_assertions/missing_solver_name.yaml b/test/examples_assertions/missing_solver_name.yaml new file mode 100644 index 0000000..cb73986 --- /dev/null +++ b/test/examples_assertions/missing_solver_name.yaml @@ -0,0 +1,20 @@ +iters: 10 + +optimiser: botorch + +parameters: + a: [1, 0, 4] + +objective: + name: fitting + solver: + #name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + references: + 'reference_curve.txt': + prediction: ['case_1'] \ No newline at end of file diff --git a/test/examples_assertions/reference_curve_2.txt b/test/examples_assertions/reference_curve_2.txt new file mode 100644 index 0000000..3d109ab --- /dev/null +++ b/test/examples_assertions/reference_curve_2.txt @@ -0,0 +1,6 @@ +-4.0 32.0 +-2.4 11.52 +-0.7999999999999998 1.2799999999999994 +0.8000000000000007 1.2800000000000022 +2.4000000000000004 11.520000000000003 +4.0 32.0 diff --git a/test/examples_assertions/unexistent_reference.yaml b/test/examples_assertions/unexistent_reference.yaml new file mode 100644 index 0000000..7d82bad --- /dev/null +++ b/test/examples_assertions/unexistent_reference.yaml @@ -0,0 +1,27 @@ + +iters: 10 + +optimiser: random + + +parameters: + a: [0, -4, 4] + + + +objective: + name: fitting + composite: False + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + references: + 'reference_curve.txt': + prediction: ['case_1'] + 'reference_curve_2.txt': + prediction: ['case_2'] diff --git a/test/examples_assertions/unexistent_targets.yaml b/test/examples_assertions/unexistent_targets.yaml new file mode 100644 index 0000000..21fc990 --- /dev/null +++ b/test/examples_assertions/unexistent_targets.yaml @@ -0,0 +1,30 @@ + +iters: 10 + +optimiser: random + + +parameters: + a: [2, 0.5, 4] + + + +objective: + name: design + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + targets: + 'maximum_force': + quantity: max + prediction: ['case_1'] + negate: False + 'integral_quantity': + quantity: integral + prediction: ['case_2'] + negate: False diff --git a/test/examples_assertions/wrong_solver_name.yaml b/test/examples_assertions/wrong_solver_name.yaml new file mode 100644 index 0000000..be955a6 --- /dev/null +++ b/test/examples_assertions/wrong_solver_name.yaml @@ -0,0 +1,20 @@ +iters: 10 + +optimiser: botorch + +parameters: + a: [1, 0, 4] + +objective: + name: fitting + solver: + name: curvefit + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + references: + 'reference_curve.txt': + prediction: ['case_1'] \ No newline at end of file diff --git a/test/examples_plots/dummy_composite_stochastic_design.yaml b/test/examples_plots/dummy_composite_stochastic_design.yaml new file mode 100644 index 0000000..d944514 --- /dev/null +++ b/test/examples_plots/dummy_composite_stochastic_design.yaml @@ -0,0 +1,36 @@ + +iters: 10 + +optimiser: + name: botorch + + +parameters: + a: [0, -4, 4] + + +objective: + name: design + composite: True + stochastic: True + solver: + name: curve + cases: + 'case_1': + expression: * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + 'case_2': + expression: 1.1 * * x ** 2 + parametric: x + bounds: [-5, 5] + points: 100 + + + targets: + 'maximum_force': + quantity: max + prediction: ['case_1', 'case_2'] + negate: False + diff --git a/test/examples_plots_assertions/analytical_parameters_3.yaml b/test/examples_plots_assertions/analytical_parameters_3.yaml new file mode 100644 index 0000000..d6271b2 --- /dev/null +++ b/test/examples_plots_assertions/analytical_parameters_3.yaml @@ -0,0 +1,17 @@ + + +iters: 1 + + +optimiser: random + + +parameters: + a: [200, 100, 300] + b: [0.25, 0.1, 0.4] + c: [0.025, 0.01, 0.04] + + +objective: + name: analytical + expression: ((a/b)-500)**2 + c**2 diff --git a/test/examples_plots_assertions/gp_error.yaml b/test/examples_plots_assertions/gp_error.yaml new file mode 100644 index 0000000..2effc38 --- /dev/null +++ b/test/examples_plots_assertions/gp_error.yaml @@ -0,0 +1,16 @@ + + +iters: 1 + + +optimiser: random + + +parameters: + Young: [200, 100, 300] + poisson: [0.25, 0.1, 0.4] + + +objective: + name: analytical + expression: ((Young/poisson)-500)**2 diff --git a/test/solver_utils/input_file_1.txt b/test/solver_utils/input_file_1.txt new file mode 100644 index 0000000..d89a624 --- /dev/null +++ b/test/solver_utils/input_file_1.txt @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/test/solver_utils/input_file_2.txt b/test/solver_utils/input_file_2.txt new file mode 100644 index 0000000..ef5ceca --- /dev/null +++ b/test/solver_utils/input_file_2.txt @@ -0,0 +1 @@ + diff --git a/test/solver_utils/input_file_3.txt b/test/solver_utils/input_file_3.txt new file mode 100644 index 0000000..8433c54 --- /dev/null +++ b/test/solver_utils/input_file_3.txt @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/test/solver_utils/test_module.py b/test/solver_utils/test_module.py new file mode 100644 index 0000000..8724927 --- /dev/null +++ b/test/solver_utils/test_module.py @@ -0,0 +1,3 @@ +# test_module.py + +test_attribute = "CM2S" \ No newline at end of file diff --git a/test/test_examples_assertions.py b/test/test_examples_assertions.py index e052da6..aaa017a 100644 --- a/test/test_examples_assertions.py +++ b/test/test_examples_assertions.py @@ -80,6 +80,90 @@ RuntimeError, "Failed to parse the config file: YAML syntax seems invalid.", ), + 'missing_solver_name.yaml': ( + ValueError, + "Missing name for solver.", + ), + 'wrong_solver_name.yaml': ( + ValueError, + "Unknown solver 'curvefit'.", + ), + 'fitting_without_solver.yaml': ( + ValueError, + "Missing solver for fitting objective.", + ), + 'invalid_pred.yaml': ( + ValueError, + "Invalid prediction '2' for reference 'reference_curve.txt'.", + ), + 'invalid_pred_design.yaml': ( + ValueError, + "Invalid prediction '2' for design target 'maximum_force'.", + ), + 'missing_references.yaml': ( + ValueError, + "Missing references for fitting objective.", + ), + 'missing_pred.yaml': ( + ValueError, + "Missing prediction for reference 'reference_curve.txt'.", + ), + 'unexistent_reference.yaml': ( + ValueError, + "Reference 'reference_curve_2.txt' is not associated to any case.", + ), + 'mae_reduction.yaml': ( + ValueError, + "Invalid reduction 'mae' for fitting objective.", + ), + 'design_missing_pred.yaml': ( + ValueError, + "Missing prediction for design target 'maximum_force'.", + ), + 'design_missing_quantity.yaml': ( + ValueError, + "Missing quantity for fitting objective.", + ), + 'design_missing_quantity_name.yaml': ( + ValueError, + "Missing name in quantity specification.", + ), + 'design_missing_quantity_script.yaml': ( + ValueError, + "Missing script in quantity specification.", + ), + 'design_missing_quantity_class.yaml': ( + ValueError, + "Missing class in quantity specification.", + ), + 'design_missing_solver.yaml': ( + ValueError, + "Missing solver for fitting objective.", + ), + 'design_missing_targets.yaml': ( + ValueError, + "Missing targets for fitting objective.", + ), + 'unexistent_targets.yaml': ( + ValueError, + "Design target 'integral_quantity' is not associated to any case.", + ), + 'bo_unkacq.yaml': ( + RuntimeError, + "Unkown acquisition function ucbb", + ), + 'bo_q.yaml': ( + RuntimeError, + "Can only use q != 1 for quasi-Monte Carlo acquisitions", + ), + 'duplicated_field.yaml': ( + ValueError, + "Duplicate output field 'reaction_x'.", + ), + 'bo_equalbounds.yaml': ( + RuntimeError, + "All observed points are equal: add more initial samples", + ), } diff --git a/test/test_examples_plots.py b/test/test_examples_plots.py index a2c8651..67d0b0b 100644 --- a/test/test_examples_plots.py +++ b/test/test_examples_plots.py @@ -8,12 +8,43 @@ def get_files(path: str) -> List[str]: + """Gets all the files in a directory. + + Parameters + ---------- + path : str + Path to the directory. + + Returns + ------- + List[str] + List of files in the directory. + """ return [ os.path.join(path, file) for file in os.listdir(path) if os.path.isfile(os.path.join(path, file)) and file.endswith('.yaml') ] +def get_first_hash(filename: str) -> str: + """Extracts the first hash from a file. + + Parameters + ---------- + filename : str + Path to the file. + + Returns + ------- + str + The first hash in the file. + """ + with open(filename, 'r', encoding='utf-8') as file: + next(file) # Skip the header line + first_line = next(file) # Get the second line + first_hash = first_line.split()[-1] # The hash is the last element on the line + return first_hash + @pytest.mark.parametrize('input_dir', get_files('test/examples_plots')) def test_input_files(input_dir: str): @@ -21,6 +52,8 @@ def test_input_files(input_dir: str): input_file = os.path.basename(input_dir) output_dir, _ = os.path.splitext(input_file) piglot_main(input_file) + filename = os.path.join(output_dir, 'func_calls') + first_hash = get_first_hash(filename) for kind in ('best', 'history', 'parameters', 'regret'): piglot_plot_main([ kind, @@ -46,5 +79,25 @@ def test_input_files(input_dir: str): '--log', '--time', ]) + piglot_plot_main([ + 'case', + input_file, + first_hash, + '--save_fig', + os.path.join(output_dir, 'case.png'), + ]) + piglot_plot_main([ + 'animation', + input_file, + '--save_fig', + os.path.join(output_dir, 'animation.png'), + ]) + if input_file != 'test_analytical.yaml': + piglot_plot_main([ + 'gp', + input_file, + '--save_fig', + os.path.join(output_dir, 'gp.png'), + ]) if os.path.isdir(output_dir): shutil.rmtree(output_dir) diff --git a/test/test_examples_plots_assertions.py b/test/test_examples_plots_assertions.py new file mode 100644 index 0000000..95f746c --- /dev/null +++ b/test/test_examples_plots_assertions.py @@ -0,0 +1,67 @@ +import unittest +import os +import shutil +from piglot.bin.piglot import main as piglot_main +from piglot.bin.piglot_plot import main as piglot_plot_main + +def get_first_hash(filename: str) -> str: + """Extracts the first hash from a file. + + Parameters + ---------- + filename : str + Path to the file. + + Returns + ------- + str + The first hash in the file. + """ + with open(filename, 'r', encoding='utf-8') as file: + next(file) # Skip the header line + first_line = next(file) # Get the second line + first_hash = first_line.split()[-1] # The hash is the last element on the line + return first_hash + +class TestExtractParameters(unittest.TestCase): + def test_analytical_error(self): + with self.assertRaises(RuntimeError) as ex: + input_file = os.path.join("test", "examples_plots_assertions", \ + "analytical_parameters_3.yaml") + output_dir = os.path.join("test", "examples_plots_assertions", \ + "analytical_parameters_3") + piglot_main(input_file) + filename = os.path.join(output_dir, 'func_calls') + first_hash = get_first_hash(filename) + piglot_plot_main([ + 'case', + input_file, + first_hash, + '--save_fig', + os.path.join(output_dir, 'case_analytical.png'), + ]) + if os.path.isdir(output_dir): + shutil.rmtree(output_dir) + self.assertEqual(str(ex.exception), "Plotting not supported for 3 or more parameters.") + + def test_gp_single_parameter(self): + with self.assertRaises(ValueError) as ex: + input_file = os.path.join("test", "examples_plots_assertions", \ + "gp_error.yaml") + output_dir = os.path.join("test", "examples_plots_assertions", \ + "gp_error") + piglot_main(input_file) + piglot_plot_main([ + 'gp', + input_file, + '--save_fig', + os.path.join(output_dir, 'gp_error.png'), + ]) + if os.path.isdir(output_dir): + shutil.rmtree(output_dir) + self.assertEqual(str(ex.exception), \ + "Can only plot a Gaussian process regression for a single parameter.") + + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_init_shot.py b/test/test_init_shot.py new file mode 100644 index 0000000..3927ce2 --- /dev/null +++ b/test/test_init_shot.py @@ -0,0 +1,18 @@ +from typing import List +import os +import pytest +from piglot.bin.piglot import main as piglot_main +from piglot.utils.assorted import change_cwd + +def get_files(path: str) -> List[str]: + return [ + os.path.join(path, file) + for file in os.listdir(path) + if os.path.isfile(os.path.join(path, file)) and file.endswith('.yaml') + ] + +@pytest.mark.parametrize('input_dir', get_files('test/example_init_shot')) +def test_input_files(input_dir: str): + with change_cwd(os.path.dirname(input_dir)): + input_file = os.path.basename(input_dir) + piglot_main(input_file) diff --git a/test/test_solver_utils.py b/test/test_solver_utils.py new file mode 100644 index 0000000..ceee937 --- /dev/null +++ b/test/test_solver_utils.py @@ -0,0 +1,77 @@ +import unittest +import os +from piglot.utils.solver_utils import extract_parameters, has_keyword, has_parameter, find_keyword, load_module_from_file +from piglot.parameter import ParameterSet + +INPUT_FILE_1 = os.path.join("test", "solver_utils", "input_file_1.txt") +INPUT_FILE_2 = os.path.join("test", "solver_utils", "input_file_2.txt") +INPUT_FILE_3 = os.path.join("test", "solver_utils", "input_file_3.txt") +INPUT_FILE_4 = os.path.join("test", "solver_utils", "test_module.py") + +class TestExtractParameters(unittest.TestCase): + def test_extract_parameters(self): + # Call the function with the test input file + parameters = extract_parameters(INPUT_FILE_1) + + # Verify the returned ParameterSet + self.assertIsInstance(parameters, ParameterSet) + self.assertEqual(len(parameters), 2) + self.assertEqual(parameters[0].inital_value, 1.0) + self.assertEqual(parameters[0].lbound, 0.0) + self.assertEqual(parameters[0].ubound, 2.0) + self.assertEqual(parameters[1].inital_value, 2.0) + self.assertEqual(parameters[1].lbound, 1.0) + self.assertEqual(parameters[1].ubound, 3.0) + + def test_extract_parameters_fail_1(self): + with self.assertRaises(RuntimeError) as ex: + extract_parameters(INPUT_FILE_2) + self.assertEqual(str(ex.exception), "Pattern parameter1 referenced but not defined!") + + def test_extract_parameters_fail_2(self): + with self.assertRaises(RuntimeError) as ex: + extract_parameters(INPUT_FILE_3) + self.assertEqual(str(ex.exception), "Repeated pattern parameter1 in file!") + + def test_has_keyword(self): + # Call the function with the test input file and a keyword that is in the file + result = has_keyword(INPUT_FILE_1, '') + + def test_find_keyword_fail(self): + with self.assertRaises(RuntimeError) as ex: + find_keyword(INPUT_FILE_1, '