Skip to content

Commit

Permalink
update unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tkchafin committed Jun 6, 2024
1 parent 1e809f2 commit 1cf298e
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 196 deletions.
4 changes: 2 additions & 2 deletions src/resistnet/model_optimisation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1209,7 +1209,7 @@ def run_tpe(self, max_evals=100, threads=4, fitmetric="loglik",
max_shape=None, max_hof_size=None, only_keep=None,
use_full=False, verbose=True, report_all=False, nFail=50,
awsum=0.95, fixed_params=None, out=None, plot=True, reps=10,
n_startup=40, n_candidates=48, gamma=0.15):
n_startup=40, n_candidates=48, gamma=0.15, pweight=0.7):
"""
Runs the TPE optimization for optimizing the ResistNet model.
Expand Down Expand Up @@ -1277,7 +1277,7 @@ def run_tpe(self, max_evals=100, threads=4, fitmetric="loglik",
domain,
trials,
seed,
prior_weight=1.0,
prior_weight=pweight,
n_startup_jobs=n_startup,
n_EI_candidates=n_candidates,
gamma=gamma)
Expand Down
32 changes: 17 additions & 15 deletions src/resistnet/params.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import sys
import argparse


Expand Down Expand Up @@ -65,52 +66,52 @@ def __init__(self):

# Model optimization/selection options
parser.add_argument(
'-v', '--vars', type=str,
'-v', '--vars', type=str, required=False,
help='Comma-separated list of variables to use'
)
parser.add_argument(
'-V', '--varfile', type=str,
'-V', '--varfile', type=str, required=False,
help=(
'Optional file with variables provided as: '
'var \\t <Optional aggregator function>'
)
)
parser.add_argument(
'-F', '--nfail', type=int, default=50,
'-F', '--nfail', type=int, default=50, required=False,
help='Number of failed gens to stop optimization'
)
parser.add_argument(
'-i', '--max_iter', type=int, default=500,
'-i', '--max_iter', type=int, default=500, required=False,
help='Maximum number of generations'
)
parser.add_argument(
'-r', '--reps', type=int, default=10,
'-r', '--reps', type=int, default=10, required=False,
help='Number of independent TPE chains'
)
parser.add_argument(
'-P', '--pweight', type=float, default=0.7,
'-P', '--pweight', type=float, default=0.7, required=False,
help='Prior weight'
)
parser.add_argument(
'-S', '--nstart', type=int, default=20,
'-S', '--nstart', type=int, default=20, required=False,
help='Initial random evaluations'
)
parser.add_argument(
'-C', '--ncand', type=int, default=48,
'-C', '--ncand', type=int, default=48, required=False,
help='EI candidate points'
)
parser.add_argument(
'-G', '--gamma', type=float, default=0.15,
'-G', '--gamma', type=float, default=0.15, required=False,
help='Exploration factor'
)
parser.add_argument(
'-f', '--fitmetric', type=str, choices=['aic', 'loglik', 'r2m',
'delta'],
default='loglik',
default='loglik', required=False,
help='Fitness metric used to evaluate models'
)
parser.add_argument(
'--max_hof_size', type=int, default=100,
'--max_hof_size', type=int, default=100, required=False,
help='Maximum models retained'
)
parser.add_argument(
Expand All @@ -122,17 +123,17 @@ def __init__(self):
help='Fix the shape parameter during optimization'
)
parser.add_argument(
'--max_shape', type=int, default=100,
'--max_shape', type=int, default=100, required=False,
help='Maximum shape parameter'
)
parser.add_argument(
'--min_weight', type=float, default=0.0,
'--min_weight', type=float, default=0.0, required=False,
help='Minimum weight parameter'
)

# Multi-model inference options
parser.add_argument(
'-a', '--awsum', type=float, default=1.0,
'-a', '--awsum', type=float, default=1.0, required=False,
help='Cumulative Akaike weight threshold'
)
parser.add_argument(
Expand All @@ -159,5 +160,6 @@ def __init__(self):
var = line.strip().split('\t')[0]
self.variables.append(var)
else:
self.variables = None
print("Error: Either --vars or --varfile must be specified.")
sys.exit(1)
self.agg_opts = {var: "ARITH" for var in self.variables}
3 changes: 1 addition & 2 deletions tests/resistnet/test_hall_of_fame.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ def create_fake_population(num_models, num_variables):
model[f'var{var+1}_weight'] = 1.0
model[f'var{var+1}_trans'] = 0
model[f'var{var+1}_shape'] = 1.0
model[f'var{var+1}_asym'] = 0
model.update(
{'loglik': np.random.rand(), 'r2m': np.random.rand(),
'aic': -1 * np.random.rand(), 'delta_aic_null': np.random.rand()}
Expand Down Expand Up @@ -75,7 +74,7 @@ def test_hall_of_fame_initialization():
expected_columns = ["fitness"]
for v in variables:
expected_columns.extend(
[str(v), f"{v}_weight", f"{v}_trans", f"{v}_shape", f"{v}_asym"]
[str(v), f"{v}_weight", f"{v}_trans", f"{v}_shape"]
)
expected_columns.extend(["loglik", "r2m", "aic", "delta_aic_null"])

Expand Down
62 changes: 18 additions & 44 deletions tests/resistnet/test_model_optimisation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,17 @@
import tempfile
import resistnet
from resistnet.resistance_network import ResistanceNetwork
from resistnet.model_optimisation import ModelRunner
from resistnet.model_optimisation import ModelRunnerTPE


@pytest.fixture
def ga_parameters_fixture():
def tpe_parameters_fixture():
return {
'mutpb': 0.1,
'cxpb': 0.8,
'indpb': 0.05,
'popsize': 10,
'maxpopsize': 10,
'fixWeight': False,
'fixShape': True,
'min_weight': 0.5,
'max_shape': 2.0,
'max_hof_size': 100,
'tournsize': 3,
'fitmetric': 'aic',
'awsum': 0.75,
'only_keep': True,
Expand Down Expand Up @@ -86,7 +80,7 @@ def model_runner_fixture(resistance_network_fixture):
seed = 1234
verbose = True

model_runner = ModelRunner(
model_runner = ModelRunnerTPE(
resistance_network=resistance_network_fixture,
seed=seed, verbose=verbose)

Expand All @@ -97,7 +91,7 @@ def test_model_runner_initialization(resistance_network_fixture):
seed = 1234
verbose = True

model_runner = ModelRunner(
model_runner = ModelRunnerTPE(
resistance_network=resistance_network_fixture,
seed=seed, verbose=verbose)

Expand All @@ -109,72 +103,52 @@ def test_model_runner_initialization(resistance_network_fixture):
# Check if the default values are correctly initialized
assert isinstance(model_runner.workers, list)
assert model_runner.bests is None
assert model_runner.toolbox is None
assert isinstance(model_runner.logger, list)

# Check the default values of GA parameters
assert model_runner.cxpb is None
assert model_runner.mutpb is None
assert model_runner.indpb is None
assert model_runner.popsize is None
assert model_runner.maxpopsize is None
assert model_runner.fixWeight is None
assert model_runner.fixShape is None
assert model_runner.min_weight is None
assert model_runner.max_shape is None
assert model_runner.max_hof_size is None
assert model_runner.tournsize is None
assert model_runner.fitmetric is None
assert model_runner.awsum is None
assert model_runner.only_keep is None
assert model_runner.report_all is None


def test_set_ga_parameters(
model_runner_fixture, ga_parameters_fixture):
def test_set_tpe_parameters(
model_runner_fixture, tpe_parameters_fixture):
# Call set_ga_parameters on the fixture instance with the test parameters
model_runner_fixture.set_ga_parameters(
**ga_parameters_fixture
model_runner_fixture.set_tpe_parameters(
**tpe_parameters_fixture
)

# Assert that each parameter is set correctly
for param, value in ga_parameters_fixture.items():
for param, value in tpe_parameters_fixture.items():
assert getattr(model_runner_fixture, param) == \
value, f"Parameter {param} not set correctly"


def test_run_ga(model_runner_fixture, ga_parameters_fixture):
def test_run_tpe(model_runner_fixture, tpe_parameters_fixture):
with tempfile.TemporaryDirectory() as temp_dir:
out_prefix = os.path.join(temp_dir, "ga_output")
ga_parameters_fixture["verbose"] = False
ga_parameters_fixture["out"] = out_prefix
ga_parameters_fixture["threads"] = 1
ga_parameters_fixture["maxgens"] = 1
out_prefix = os.path.join(temp_dir, "tpe_output")
tpe_parameters_fixture["verbose"] = False
tpe_parameters_fixture["out"] = out_prefix
tpe_parameters_fixture["threads"] = 1
tpe_parameters_fixture["max_evals"] = 1

# Run the genetic algorithm with the modified parameters
try:
model_runner_fixture.run_ga(**ga_parameters_fixture)
model_runner_fixture.run_tpe(**tpe_parameters_fixture)
error_occurred = False
except Exception as e:
error_occurred = True
print(f"Error during GA run: {e}")
print(f"Error during TPE run: {e}")

# Assert that no errors occurred during the run
assert not error_occurred, "An error occurred during the GA run"
assert not error_occurred, "An error occurred during the TPE run"

# Assert that the best models are identified (bests is not None)
assert model_runner_fixture.bests is not None, \
"ModelRunner.bests missing"

# Assert that the expected output files are generated
expected_files = [
f"{out_prefix}.varImportance.tsv",
f"{out_prefix}.HallOfFame.tsv",
f"{out_prefix}.FitnessLog.tsv",
f"{out_prefix}.Model-Average.streamsByResistance.pdf"
]

for file in expected_files:
assert os.path.isfile(file), f"Expected output file not found: \
{file}"

Loading

0 comments on commit 1cf298e

Please sign in to comment.