diff --git a/scripts/database/directory/general.py b/scripts/database/directory/general.py index 3591c3b..b258ace 100644 --- a/scripts/database/directory/general.py +++ b/scripts/database/directory/general.py @@ -113,7 +113,7 @@ def save_attributes(self, paths: af.DirectoryPaths): """ __Database__ """ -from autoconf.test_mode import with_test_mode_segment +from autofit import with_test_mode_segment from autofit.aggregator.aggregator import Aggregator output_path = with_test_mode_segment(Path("output")) diff --git a/scripts/database/directory/multi_analysis.py b/scripts/database/directory/multi_analysis.py index 72849f5..a52e5ad 100644 --- a/scripts/database/directory/multi_analysis.py +++ b/scripts/database/directory/multi_analysis.py @@ -128,7 +128,7 @@ def save_attributes(self, paths: af.DirectoryPaths): """ __Database__ """ -from autoconf.test_mode import with_test_mode_segment +from autofit import with_test_mode_segment from autofit.aggregator.aggregator import Aggregator output_path = with_test_mode_segment(Path("output")) diff --git a/scripts/database/scrape/general.py b/scripts/database/scrape/general.py index 21089d9..054323a 100644 --- a/scripts/database/scrape/general.py +++ b/scripts/database/scrape/general.py @@ -111,7 +111,7 @@ def save_attributes(self, paths: af.DirectoryPaths): """ __Database__ """ -from autoconf.test_mode import with_test_mode_segment +from autofit import with_test_mode_segment from autofit.database.aggregator import Aggregator database_file = "database_scrape_general.sqlite" diff --git a/scripts/database/scrape/grid_search.py b/scripts/database/scrape/grid_search.py index 60ba9c8..7e035f1 100644 --- a/scripts/database/scrape/grid_search.py +++ b/scripts/database/scrape/grid_search.py @@ -17,7 +17,7 @@ from os import path from pathlib import Path import numpy as np -from autoconf.test_mode import with_test_mode_segment +from autofit import with_test_mode_segment """ ___Session__ diff --git a/scripts/database/scrape/multi_analysis.py b/scripts/database/scrape/multi_analysis.py index 1be9dde..7141daf 100644 --- a/scripts/database/scrape/multi_analysis.py +++ b/scripts/database/scrape/multi_analysis.py @@ -1,245 +1,245 @@ -""" -Feature: Database -================= - -Tests that the results of a fit which sums multiple Analysis classes together can be loaded from hard-disk via a -database built via a scrape. -""" - -# %matplotlib inline -# from pyprojroot import here -# workspace_path = str(here()) -# %cd $workspace_path -# print(f"Working Directory has been set to `{workspace_path}`") - +""" +Feature: Database +================= + +Tests that the results of a fit which sums multiple Analysis classes together can be loaded from hard-disk via a +database built via a scrape. +""" + +# %matplotlib inline +# from pyprojroot import here +# workspace_path = str(here()) +# %cd $workspace_path +# print(f"Working Directory has been set to `{workspace_path}`") + from pathlib import Path -import autofit as af - -import os -from os import path -import numpy as np - -""" -__Dataset Names__ - -Load the dataset from hard-disc, set up its `Analysis` class and fit it with a non-linear search. -""" -dataset_name = "gaussian_x1" - -""" -__Model__ - -Next, we create our model, which again corresponds to a single `Gaussian` with manual priors. -""" -model = af.Collection(gaussian=af.ex.Gaussian) - -model.gaussian.centre = af.UniformPrior(lower_limit=0.0, upper_limit=100.0) -model.gaussian.normalization = af.LogUniformPrior(lower_limit=1e-2, upper_limit=1e2) -model.gaussian.sigma = af.TruncatedGaussianPrior( - mean=10.0, sigma=5.0, lower_limit=0.0, upper_limit=np.inf -) - -""" -___Session__ - -To output results directly to the database, we start a session, which includes the name of the database `.sqlite` file -where results are stored. -""" -session = None - -""" -The code below loads the dataset and sets up the Analysis class. -""" -dataset_path = path.join("dataset", "example_1d", dataset_name) - -""" -__Dataset Auto-Simulation__ - -If the dataset does not already exist on your system, it will be created by running the corresponding -simulator script. This ensures that all example scripts can be run without manually simulating data first. -""" -if not path.exists(dataset_path): - import subprocess - import sys - - subprocess.run( - [sys.executable, "scripts/simulators/simulators.py"], - check=True, - ) - -data = af.util.numpy_array_from_json(file_path=path.join(dataset_path, "data.json")) -noise_map = af.util.numpy_array_from_json( - file_path=path.join(dataset_path, "noise_map.json") -) - -""" -Default example Analysis does not output a .pickle file and does not test pickle loading. - -We extend the Analysis class to output the data as a pickle file, which we test can be loaded below -""" - - -class Analysis(af.ex.Analysis): - def save_attributes(self, paths: af.DirectoryPaths): - super().save_attributes(paths=paths) - paths.save_object(name="data_pickled", obj=self.data) - - -analysis = Analysis(data=data, noise_map=noise_map) - -""" -This script tests loading tools works when multiple analysis classes are used and summed together. -""" -analysis_factor_list = [] - -for analysis in [analysis, analysis]: - - model_analysis = model.copy() - - analysis_factor = af.AnalysisFactor(prior_model=model_analysis, analysis=analysis) - - analysis_factor_list.append(analysis_factor) - -factor_graph = af.FactorGraphModel(*analysis_factor_list) - - -""" -Results are written directly to the `database.sqlite` file omitted hard-disc output entirely, which -can be important for performing large model-fitting tasks on high performance computing facilities where there -may be limits on the number of files allowed. The commented out code below shows how one would perform -direct output to the `.sqlite` file. -""" -name = "multi_analysis" - -search = af.DynestyStatic( - name=name, - path_prefix=path.join("database", "scrape"), - number_of_cores=1, - unique_tag=dataset_name, - session=session, - maxcall=100, - maxiter=100, -) - -result_list = search.fit( - model=factor_graph.global_prior_model, analysis=factor_graph, info={"hi": "there"} -) - -""" -__Database__ -""" -from autoconf.test_mode import with_test_mode_segment -from autofit.database.aggregator import Aggregator - -database_file = "database_scrape_multi_analysis.sqlite" - -output_path = with_test_mode_segment(Path("output")) - -try: - os.remove(output_path / database_file) -except FileNotFoundError: - pass - - -agg = Aggregator.from_database(path.join(database_file)) -agg.add_directory( - directory=output_path / "database" / "scrape" / dataset_name / name -) - -assert len(agg) > 0 - -""" -__Samples + Results__ - -Make sure database + agg can be used. -""" -print("\n\n***********************") -print("****RESULTS TESTING****") -print("***********************\n") - -for samples in agg.values("samples"): - print(samples.parameter_lists[0]) - -mp_instances = [samps.median_pdf() for samps in agg.values("samples")] -print(mp_instances) - -""" -__Queries__ -""" -print("\n\n***********************") -print("****QUERIES TESTING****") -print("***********************\n") - -path_prefix = agg.search.path_prefix -agg_query = agg.query(path_prefix == path.join("database", "session", dataset_name)) -print("Total Samples Objects via `path_prefix` model query = ", len(agg_query), "\n") - -name = agg.search.name -agg_query = agg.query(name == "general") -print("Total Samples Objects via `name` model query = ", len(agg_query), "\n") - -gaussian = agg.model.gaussian -agg_query = agg.query(gaussian == af.ex.Gaussian) -print("Total Samples Objects via `Gaussian` model query = ", len(agg_query), "\n") - -gaussian = agg.model.gaussian -agg_query = agg.query(gaussian.sigma > 3.0) -print("Total Samples Objects In Query `gaussian.sigma < 3.0` = ", len(agg_query), "\n") - -gaussian = agg.model.gaussian -agg_query = agg.query((gaussian == af.ex.Gaussian) & (gaussian.sigma < 3.0)) -print( - "Total Samples Objects In Query `Gaussian & sigma < 3.0` = ", len(agg_query), "\n" -) - -unique_tag = agg.search.unique_tag -agg_query = agg.query(unique_tag == "gaussian_x1_1") - -print(agg_query.values("samples")) -print("Total Samples Objects via unique tag Query = ", len(agg_query), "\n") - -""" -__Files__ - -Check that all other files stored in database (e.g. model, search) can be loaded and used. -""" -print("\n\n***********************") -print("*****FILES TESTING*****") -print("***********************\n") - -for model in agg.values("model"): - print(f"\n****Model Info (model)****\n\n{model.info}") - assert model.info[0] == "T" - -for search in agg.values("search"): - print(f"\n****Search (search)****\n\n{search}") - assert search.paths.name == "multi_analysis" - assert path.join("database", "scrape", dataset_name) in str( - search.paths.output_path - ) - -for samples_summary in agg.values("samples_summary"): - instance = samples_summary.max_log_likelihood() - print(f"\n****Max Log Likelihood (samples_summary)****\n\n{instance}") - assert instance[0].gaussian.centre > 0.0 - -for info in agg.values("info"): - print(f"\n****Info****\n\n{info}") - assert info["hi"] == "there" - -for data in agg.child_values("dataset.data"): - print(f"\n****Data (dataset.data)****\n\n{data}") - assert data[0][0] > -1.0e8 - -for noise_map in agg.child_values("dataset.noise_map"): - print(f"\n****Noise Map (dataset.noise_map)****\n\n{noise_map}") - assert noise_map[0][0] > 0.0 - -for data in agg.child_values("data_pickled"): - print(f"\n****Data (data_pickled)****\n\n{data}") - assert data[0][0] > -1.0e8 - -# for covariance in agg.values("covariance"): -# print(f"\n****Covariance (covariance)****\n\n{covariance}") -# assert covariance is not None +import autofit as af + +import os +from os import path +import numpy as np + +""" +__Dataset Names__ + +Load the dataset from hard-disc, set up its `Analysis` class and fit it with a non-linear search. +""" +dataset_name = "gaussian_x1" + +""" +__Model__ + +Next, we create our model, which again corresponds to a single `Gaussian` with manual priors. +""" +model = af.Collection(gaussian=af.ex.Gaussian) + +model.gaussian.centre = af.UniformPrior(lower_limit=0.0, upper_limit=100.0) +model.gaussian.normalization = af.LogUniformPrior(lower_limit=1e-2, upper_limit=1e2) +model.gaussian.sigma = af.TruncatedGaussianPrior( + mean=10.0, sigma=5.0, lower_limit=0.0, upper_limit=np.inf +) + +""" +___Session__ + +To output results directly to the database, we start a session, which includes the name of the database `.sqlite` file +where results are stored. +""" +session = None + +""" +The code below loads the dataset and sets up the Analysis class. +""" +dataset_path = path.join("dataset", "example_1d", dataset_name) + +""" +__Dataset Auto-Simulation__ + +If the dataset does not already exist on your system, it will be created by running the corresponding +simulator script. This ensures that all example scripts can be run without manually simulating data first. +""" +if not path.exists(dataset_path): + import subprocess + import sys + + subprocess.run( + [sys.executable, "scripts/simulators/simulators.py"], + check=True, + ) + +data = af.util.numpy_array_from_json(file_path=path.join(dataset_path, "data.json")) +noise_map = af.util.numpy_array_from_json( + file_path=path.join(dataset_path, "noise_map.json") +) + +""" +Default example Analysis does not output a .pickle file and does not test pickle loading. + +We extend the Analysis class to output the data as a pickle file, which we test can be loaded below +""" + + +class Analysis(af.ex.Analysis): + def save_attributes(self, paths: af.DirectoryPaths): + super().save_attributes(paths=paths) + paths.save_object(name="data_pickled", obj=self.data) + + +analysis = Analysis(data=data, noise_map=noise_map) + +""" +This script tests loading tools works when multiple analysis classes are used and summed together. +""" +analysis_factor_list = [] + +for analysis in [analysis, analysis]: + + model_analysis = model.copy() + + analysis_factor = af.AnalysisFactor(prior_model=model_analysis, analysis=analysis) + + analysis_factor_list.append(analysis_factor) + +factor_graph = af.FactorGraphModel(*analysis_factor_list) + + +""" +Results are written directly to the `database.sqlite` file omitted hard-disc output entirely, which +can be important for performing large model-fitting tasks on high performance computing facilities where there +may be limits on the number of files allowed. The commented out code below shows how one would perform +direct output to the `.sqlite` file. +""" +name = "multi_analysis" + +search = af.DynestyStatic( + name=name, + path_prefix=path.join("database", "scrape"), + number_of_cores=1, + unique_tag=dataset_name, + session=session, + maxcall=100, + maxiter=100, +) + +result_list = search.fit( + model=factor_graph.global_prior_model, analysis=factor_graph, info={"hi": "there"} +) + +""" +__Database__ +""" +from autofit import with_test_mode_segment +from autofit.database.aggregator import Aggregator + +database_file = "database_scrape_multi_analysis.sqlite" + +output_path = with_test_mode_segment(Path("output")) + +try: + os.remove(output_path / database_file) +except FileNotFoundError: + pass + + +agg = Aggregator.from_database(path.join(database_file)) +agg.add_directory( + directory=output_path / "database" / "scrape" / dataset_name / name +) + +assert len(agg) > 0 + +""" +__Samples + Results__ + +Make sure database + agg can be used. +""" +print("\n\n***********************") +print("****RESULTS TESTING****") +print("***********************\n") + +for samples in agg.values("samples"): + print(samples.parameter_lists[0]) + +mp_instances = [samps.median_pdf() for samps in agg.values("samples")] +print(mp_instances) + +""" +__Queries__ +""" +print("\n\n***********************") +print("****QUERIES TESTING****") +print("***********************\n") + +path_prefix = agg.search.path_prefix +agg_query = agg.query(path_prefix == path.join("database", "session", dataset_name)) +print("Total Samples Objects via `path_prefix` model query = ", len(agg_query), "\n") + +name = agg.search.name +agg_query = agg.query(name == "general") +print("Total Samples Objects via `name` model query = ", len(agg_query), "\n") + +gaussian = agg.model.gaussian +agg_query = agg.query(gaussian == af.ex.Gaussian) +print("Total Samples Objects via `Gaussian` model query = ", len(agg_query), "\n") + +gaussian = agg.model.gaussian +agg_query = agg.query(gaussian.sigma > 3.0) +print("Total Samples Objects In Query `gaussian.sigma < 3.0` = ", len(agg_query), "\n") + +gaussian = agg.model.gaussian +agg_query = agg.query((gaussian == af.ex.Gaussian) & (gaussian.sigma < 3.0)) +print( + "Total Samples Objects In Query `Gaussian & sigma < 3.0` = ", len(agg_query), "\n" +) + +unique_tag = agg.search.unique_tag +agg_query = agg.query(unique_tag == "gaussian_x1_1") + +print(agg_query.values("samples")) +print("Total Samples Objects via unique tag Query = ", len(agg_query), "\n") + +""" +__Files__ + +Check that all other files stored in database (e.g. model, search) can be loaded and used. +""" +print("\n\n***********************") +print("*****FILES TESTING*****") +print("***********************\n") + +for model in agg.values("model"): + print(f"\n****Model Info (model)****\n\n{model.info}") + assert model.info[0] == "T" + +for search in agg.values("search"): + print(f"\n****Search (search)****\n\n{search}") + assert search.paths.name == "multi_analysis" + assert path.join("database", "scrape", dataset_name) in str( + search.paths.output_path + ) + +for samples_summary in agg.values("samples_summary"): + instance = samples_summary.max_log_likelihood() + print(f"\n****Max Log Likelihood (samples_summary)****\n\n{instance}") + assert instance[0].gaussian.centre > 0.0 + +for info in agg.values("info"): + print(f"\n****Info****\n\n{info}") + assert info["hi"] == "there" + +for data in agg.child_values("dataset.data"): + print(f"\n****Data (dataset.data)****\n\n{data}") + assert data[0][0] > -1.0e8 + +for noise_map in agg.child_values("dataset.noise_map"): + print(f"\n****Noise Map (dataset.noise_map)****\n\n{noise_map}") + assert noise_map[0][0] > 0.0 + +for data in agg.child_values("data_pickled"): + print(f"\n****Data (data_pickled)****\n\n{data}") + assert data[0][0] > -1.0e8 + +# for covariance in agg.values("covariance"): +# print(f"\n****Covariance (covariance)****\n\n{covariance}") +# assert covariance is not None diff --git a/scripts/database/scrape/sensitivity.py b/scripts/database/scrape/sensitivity.py index fc489ef..e15dfd6 100644 --- a/scripts/database/scrape/sensitivity.py +++ b/scripts/database/scrape/sensitivity.py @@ -27,7 +27,7 @@ import numpy as np from os import path from pathlib import Path -from autoconf.test_mode import with_test_mode_segment +from autofit import with_test_mode_segment """ ___Session__ diff --git a/scripts/features/minimal_output.py b/scripts/features/minimal_output.py index 385879f..4aff556 100644 --- a/scripts/features/minimal_output.py +++ b/scripts/features/minimal_output.py @@ -1,203 +1,203 @@ -""" -Feature: Minimal Output -======================= - -The output of a PyAutoFit model-fit can be customized in order to reduce hard-disk space use and clutter in the -output folder. - -This script tests functionality when the minimal amount of samples and other files are output, including: - - 1) Resuming a fit and loading a completed fit. - 2) Search chaining and prior linking. - 3) Database functionality with files missing. - - __Config__ - -We begin by pointing to the minimal_output config folder, which has configuration file settings update to produce -minimal output. - -The following settings are listed as false in the `output.yaml` file, meaning the corresponding files will not be -outptu (which assertions test for below): - -covariance -""" - -import os -from os import path - -cwd = os.getcwd() - -from autoconf import conf - -conf.instance.push(new_path=path.join(cwd, "scripts", "features", "config")) - -# %matplotlib inline -# from pyprojroot import here -# workspace_path = str(here()) -# %cd $workspace_path -# print(f"Working Directory has been set to `{workspace_path}`") - -import numpy as np -import autofit as af - -""" -__Dataset Names__ - -Load the dataset from hard-disc, set up its `Analysis` class and fit it with a non-linear search. -""" -dataset_name = "gaussian_x1" - -""" -__Model__ - -Next, we create our model, which again corresponds to a single `Gaussian` with manual priors. -""" -model = af.Collection(gaussian=af.ex.Gaussian) - -model.gaussian.centre = af.UniformPrior(lower_limit=0.0, upper_limit=100.0) -model.gaussian.normalization = af.LogUniformPrior(lower_limit=1e-2, upper_limit=1e2) -model.gaussian.sigma = af.TruncatedGaussianPrior( - mean=10.0, sigma=5.0, lower_limit=0.0, upper_limit=np.inf -) - -""" -The code below loads the dataset and sets up the Analysis class. -""" -dataset_path = path.join("dataset", "example_1d", dataset_name) - -""" -__Dataset Auto-Simulation__ - -If the dataset does not already exist on your system, it will be created by running the corresponding -simulator script. This ensures that all example scripts can be run without manually simulating data first. -""" -if not path.exists(dataset_path): - import subprocess - import sys - - subprocess.run( - [sys.executable, "scripts/simulators/simulators.py"], - check=True, - ) - -data = af.util.numpy_array_from_json(file_path=path.join(dataset_path, "data.json")) -noise_map = af.util.numpy_array_from_json( - file_path=path.join(dataset_path, "noise_map.json") -) - -analysis = af.ex.Analysis(data=data, noise_map=noise_map) - -name = "simple" - -search = af.DynestyStatic( - name=name, - path_prefix=path.join("features", "minimal_output"), - number_of_cores=1, - unique_tag=dataset_name, - maxcall=1000, - maxiter=1000, -) - -result = search.fit(model=model, analysis=analysis) - -""" -__Completion__ - -Confirm that a completed run does not raise an exception. -""" -result = search.fit(model=model, analysis=analysis) - -""" -__Assertions__ - -The following files have been disabled via the ? config file. - -The assertions below check that the associated files have not been output. - - - The `search_internal` folder. -""" -assert not path.exists(search.paths._files_path / "search_internal") -assert not path.exists(search.paths._files_path / "covariance.csv") - -""" -__Database__ -""" -from autofit.aggregator.aggregator import Aggregator - -agg = Aggregator.from_directory( - directory=path.join("output", "features", "minimal_output", dataset_name, name), -) - -assert len(agg) > 0 - -""" -__Samples + Results__ - -Make sure database + agg can be used. -""" -for samples in agg.values("samples"): - assert samples is None - -""" -__Queries__ -""" -path_prefix = agg.search.path_prefix -agg_query = agg.query(path_prefix == path.join("database", "session", dataset_name)) -print("Total Samples Objects via `path_prefix` model query = ", len(agg_query), "\n") - -name = agg.search.name -agg_query = agg.query(name == "general") -print("Total Samples Objects via `name` model query = ", len(agg_query), "\n") - -gaussian = agg.model.gaussian -agg_query = agg.query(gaussian == af.ex.Gaussian) -print("Total Samples Objects via `Gaussian` model query = ", len(agg_query), "\n") - -gaussian = agg.model.gaussian -agg_query = agg.query(gaussian.sigma > 3.0) -print("Total Samples Objects In Query `gaussian.sigma < 3.0` = ", len(agg_query), "\n") - -gaussian = agg.model.gaussian -agg_query = agg.query((gaussian == af.ex.Gaussian) & (gaussian.sigma < 3.0)) -print( - "Total Samples Objects In Query `Gaussian & sigma < 3.0` = ", len(agg_query), "\n" -) - -unique_tag = agg.search.unique_tag -agg_query = agg.query(unique_tag == "gaussian_x1_1") - -print(agg_query.values("samples")) -print("Total Samples Objects via unique tag Query = ", len(agg_query), "\n") - -""" -__Files__ - -Check that all other files stored in database (e.g. model, search) can be loaded and used. -""" - -for model in agg.values("model"): - print(f"\n****Model Info (model)****\n\n{model.info}") - assert model.info[0] == "T" - -for search in agg.values("search"): - print(f"\n****Search (search)****\n\n{search}") - assert search.paths.name == "simple" - assert path.join("features") in str(search.paths.output_path) - -for samples_summary in agg.values("samples_summary"): - instance = samples_summary.max_log_likelihood() - print(f"\n****Max Log Likelihood (samples_summary)****\n\n{instance}") - assert instance.gaussian.centre > 0.0 - print(samples_summary.max_log_likelihood_sample.log_likelihood) - -for info in agg.values("info"): - assert info is None - -for data in agg.values("dataset.data"): - assert data is None - -for noise_map in agg.values("dataset.noise_map"): - assert noise_map is None - -for covariance in agg.values("covariance"): - assert covariance is None +""" +Feature: Minimal Output +======================= + +The output of a PyAutoFit model-fit can be customized in order to reduce hard-disk space use and clutter in the +output folder. + +This script tests functionality when the minimal amount of samples and other files are output, including: + + 1) Resuming a fit and loading a completed fit. + 2) Search chaining and prior linking. + 3) Database functionality with files missing. + + __Config__ + +We begin by pointing to the minimal_output config folder, which has configuration file settings update to produce +minimal output. + +The following settings are listed as false in the `output.yaml` file, meaning the corresponding files will not be +outptu (which assertions test for below): + +covariance +""" + +import os +from os import path + +cwd = os.getcwd() + +from autofit import conf + +conf.instance.push(new_path=path.join(cwd, "scripts", "features", "config")) + +# %matplotlib inline +# from pyprojroot import here +# workspace_path = str(here()) +# %cd $workspace_path +# print(f"Working Directory has been set to `{workspace_path}`") + +import numpy as np +import autofit as af + +""" +__Dataset Names__ + +Load the dataset from hard-disc, set up its `Analysis` class and fit it with a non-linear search. +""" +dataset_name = "gaussian_x1" + +""" +__Model__ + +Next, we create our model, which again corresponds to a single `Gaussian` with manual priors. +""" +model = af.Collection(gaussian=af.ex.Gaussian) + +model.gaussian.centre = af.UniformPrior(lower_limit=0.0, upper_limit=100.0) +model.gaussian.normalization = af.LogUniformPrior(lower_limit=1e-2, upper_limit=1e2) +model.gaussian.sigma = af.TruncatedGaussianPrior( + mean=10.0, sigma=5.0, lower_limit=0.0, upper_limit=np.inf +) + +""" +The code below loads the dataset and sets up the Analysis class. +""" +dataset_path = path.join("dataset", "example_1d", dataset_name) + +""" +__Dataset Auto-Simulation__ + +If the dataset does not already exist on your system, it will be created by running the corresponding +simulator script. This ensures that all example scripts can be run without manually simulating data first. +""" +if not path.exists(dataset_path): + import subprocess + import sys + + subprocess.run( + [sys.executable, "scripts/simulators/simulators.py"], + check=True, + ) + +data = af.util.numpy_array_from_json(file_path=path.join(dataset_path, "data.json")) +noise_map = af.util.numpy_array_from_json( + file_path=path.join(dataset_path, "noise_map.json") +) + +analysis = af.ex.Analysis(data=data, noise_map=noise_map) + +name = "simple" + +search = af.DynestyStatic( + name=name, + path_prefix=path.join("features", "minimal_output"), + number_of_cores=1, + unique_tag=dataset_name, + maxcall=1000, + maxiter=1000, +) + +result = search.fit(model=model, analysis=analysis) + +""" +__Completion__ + +Confirm that a completed run does not raise an exception. +""" +result = search.fit(model=model, analysis=analysis) + +""" +__Assertions__ + +The following files have been disabled via the ? config file. + +The assertions below check that the associated files have not been output. + + - The `search_internal` folder. +""" +assert not path.exists(search.paths._files_path / "search_internal") +assert not path.exists(search.paths._files_path / "covariance.csv") + +""" +__Database__ +""" +from autofit.aggregator.aggregator import Aggregator + +agg = Aggregator.from_directory( + directory=path.join("output", "features", "minimal_output", dataset_name, name), +) + +assert len(agg) > 0 + +""" +__Samples + Results__ + +Make sure database + agg can be used. +""" +for samples in agg.values("samples"): + assert samples is None + +""" +__Queries__ +""" +path_prefix = agg.search.path_prefix +agg_query = agg.query(path_prefix == path.join("database", "session", dataset_name)) +print("Total Samples Objects via `path_prefix` model query = ", len(agg_query), "\n") + +name = agg.search.name +agg_query = agg.query(name == "general") +print("Total Samples Objects via `name` model query = ", len(agg_query), "\n") + +gaussian = agg.model.gaussian +agg_query = agg.query(gaussian == af.ex.Gaussian) +print("Total Samples Objects via `Gaussian` model query = ", len(agg_query), "\n") + +gaussian = agg.model.gaussian +agg_query = agg.query(gaussian.sigma > 3.0) +print("Total Samples Objects In Query `gaussian.sigma < 3.0` = ", len(agg_query), "\n") + +gaussian = agg.model.gaussian +agg_query = agg.query((gaussian == af.ex.Gaussian) & (gaussian.sigma < 3.0)) +print( + "Total Samples Objects In Query `Gaussian & sigma < 3.0` = ", len(agg_query), "\n" +) + +unique_tag = agg.search.unique_tag +agg_query = agg.query(unique_tag == "gaussian_x1_1") + +print(agg_query.values("samples")) +print("Total Samples Objects via unique tag Query = ", len(agg_query), "\n") + +""" +__Files__ + +Check that all other files stored in database (e.g. model, search) can be loaded and used. +""" + +for model in agg.values("model"): + print(f"\n****Model Info (model)****\n\n{model.info}") + assert model.info[0] == "T" + +for search in agg.values("search"): + print(f"\n****Search (search)****\n\n{search}") + assert search.paths.name == "simple" + assert path.join("features") in str(search.paths.output_path) + +for samples_summary in agg.values("samples_summary"): + instance = samples_summary.max_log_likelihood() + print(f"\n****Max Log Likelihood (samples_summary)****\n\n{instance}") + assert instance.gaussian.centre > 0.0 + print(samples_summary.max_log_likelihood_sample.log_likelihood) + +for info in agg.values("info"): + assert info is None + +for data in agg.values("dataset.data"): + assert data is None + +for noise_map in agg.values("dataset.noise_map"): + assert noise_map is None + +for covariance in agg.values("covariance"): + assert covariance is None diff --git a/scripts/profiling/aggregator/mock_results.py b/scripts/profiling/aggregator/mock_results.py index 690f419..89de7a1 100644 --- a/scripts/profiling/aggregator/mock_results.py +++ b/scripts/profiling/aggregator/mock_results.py @@ -30,7 +30,7 @@ import numpy as np from PIL import Image -from autoconf import conf +from autofit import conf import autofit as af DEFAULT_ROOT = Path("output") / "profiling_aggregator" / "mock" diff --git a/scripts/simulators/util.py b/scripts/simulators/util.py index aa4ef60..aa359da 100644 --- a/scripts/simulators/util.py +++ b/scripts/simulators/util.py @@ -1,72 +1,72 @@ -from autoconf.dictable import to_dict - -import autofit as af - -import json -from os import path -import numpy as np -import matplotlib.pyplot as plt - - -def simulate_dataset_1d_via_gaussian_from(gaussian, dataset_path): - """ - Specify the number of pixels used to create the xvalues on which the 1D line of the profile is generated using and - thus defining the number of data-points in our data. - """ - pixels = 100 - xvalues = np.arange(pixels) - - """ - Evaluate this `Gaussian` model instance at every xvalues to create its model profile. - """ - model_data_1d = gaussian.model_data_from(xvalues=xvalues) - - """ - Determine the noise (at a specified signal to noise level) in every pixel of our model profile. - """ - signal_to_noise_ratio = 25.0 - noise = np.random.normal(0.0, 1.0 / signal_to_noise_ratio, pixels) - - """ - Add this noise to the model line to create the line data that is fitted, using the signal-to-noise ratio to compute - noise-map of our data which is required when evaluating the chi-squared value of the likelihood. - """ - data = model_data_1d + noise - noise_map = (1.0 / signal_to_noise_ratio) * np.ones(pixels) - - """ - Output the data and noise-map to the `autofit_workspace/dataset` folder so they can be loaded and used - in other example scripts. - """ - af.util.numpy_array_to_json( - array=data, file_path=path.join(dataset_path, "data.json"), overwrite=True - ) - af.util.numpy_array_to_json( - array=noise_map, - file_path=path.join(dataset_path, "noise_map.json"), - overwrite=True, - ) - plt.errorbar( - x=xvalues, - y=data, - yerr=noise_map, - color="k", - ecolor="k", - elinewidth=1, - capsize=2, - ) - plt.title("1D Gaussian Dataset.") - plt.xlabel("x values of profile") - plt.ylabel("Profile normalization") - plt.savefig(path.join(dataset_path, "image.png")) - plt.close() - - """ - __Model Json__ - - Output the model to a .json file so we can refer to its parameters in the future. - """ - model_file = path.join(dataset_path, "model.json") - - with open(model_file, "w+") as f: - json.dump(to_dict(gaussian), f, indent=4) +from autofit import to_dict + +import autofit as af + +import json +from os import path +import numpy as np +import matplotlib.pyplot as plt + + +def simulate_dataset_1d_via_gaussian_from(gaussian, dataset_path): + """ + Specify the number of pixels used to create the xvalues on which the 1D line of the profile is generated using and + thus defining the number of data-points in our data. + """ + pixels = 100 + xvalues = np.arange(pixels) + + """ + Evaluate this `Gaussian` model instance at every xvalues to create its model profile. + """ + model_data_1d = gaussian.model_data_from(xvalues=xvalues) + + """ + Determine the noise (at a specified signal to noise level) in every pixel of our model profile. + """ + signal_to_noise_ratio = 25.0 + noise = np.random.normal(0.0, 1.0 / signal_to_noise_ratio, pixels) + + """ + Add this noise to the model line to create the line data that is fitted, using the signal-to-noise ratio to compute + noise-map of our data which is required when evaluating the chi-squared value of the likelihood. + """ + data = model_data_1d + noise + noise_map = (1.0 / signal_to_noise_ratio) * np.ones(pixels) + + """ + Output the data and noise-map to the `autofit_workspace/dataset` folder so they can be loaded and used + in other example scripts. + """ + af.util.numpy_array_to_json( + array=data, file_path=path.join(dataset_path, "data.json"), overwrite=True + ) + af.util.numpy_array_to_json( + array=noise_map, + file_path=path.join(dataset_path, "noise_map.json"), + overwrite=True, + ) + plt.errorbar( + x=xvalues, + y=data, + yerr=noise_map, + color="k", + ecolor="k", + elinewidth=1, + capsize=2, + ) + plt.title("1D Gaussian Dataset.") + plt.xlabel("x values of profile") + plt.ylabel("Profile normalization") + plt.savefig(path.join(dataset_path, "image.png")) + plt.close() + + """ + __Model Json__ + + Output the model to a .json file so we can refer to its parameters in the future. + """ + model_file = path.join(dataset_path, "model.json") + + with open(model_file, "w+") as f: + json.dump(to_dict(gaussian), f, indent=4)