diff --git a/CITATIONS.md b/CITATIONS.md new file mode 100644 index 000000000..1000bcca5 --- /dev/null +++ b/CITATIONS.md @@ -0,0 +1,10 @@ +# Citations & References + +The bibtex entries for **PyAutoFit** and its affiliated software packages can be found +[here](https://github.com/rhayes777/PyAutoFit/blob/main/files/citations.bib), with example text for citing **PyAutoFit** +in [.tex format here](https://github.com/rhayes777/PyAutoFit/blob/main/files/citation.tex) format here and +[.md format here](https://github.com/rhayes777/PyAutoFit/blob/main/files/citations.md). As shown in the examples, we +would greatly appreciate it if you mention **PyAutoFit** by name and include a link to our GitHub page! + +**PyAutoFit** is published in the [Journal of Open Source Software](https://joss.theoj.org/papers/10.21105/joss.02550#) and its +entry in the above .bib file is under the key `pyautofit`. diff --git a/CITATIONS.rst b/CITATIONS.rst deleted file mode 100644 index e4f5798e8..000000000 --- a/CITATIONS.rst +++ /dev/null @@ -1,13 +0,0 @@ -.. _references: - -Citations & References -====================== - -The bibtex entries for **PyAutoFit** and its affiliated software packages can be found -`here `_, with example text for citing **PyAutoFit** -in `.tex format here `_ format here and -`.md format here `_. As shown in the examples, we -would greatly appreciate it if you mention **PyAutoFit** by name and include a link to our GitHub page! - -**PyAutoFit** is published in the `Journal of Open Source Software `_ and its -entry in the above .bib file is under the key ``pyautofit``. \ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in index 2e5f0f0aa..523813de5 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,8 +1,8 @@ # MANIFEST.in exclude .gitignore -include README.rst +include README.md include setup.cfg -include CITATIONS.rst +include CITATIONS.md include LICENSE include requirements.txt include optional_requirements.txt diff --git a/README.md b/README.md new file mode 100644 index 000000000..e70f6bb2c --- /dev/null +++ b/README.md @@ -0,0 +1,145 @@ +# PyAutoFit: Classy Probabilistic Programming + +[![Project Status: Active](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) +[![Python Versions](https://img.shields.io/pypi/pyversions/autofit)](https://pypi.org/project/autofit/) +[![PyPI Version](https://img.shields.io/pypi/v/autofit.svg)](https://pypi.org/project/autofit/) +[![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/PyAutoLabs/autofit_workspace/blob/2026.5.1.4/start_here.ipynb) +[![Tests](https://github.com/rhayes777/PyAutoFit/actions/workflows/main.yml/badge.svg)](https://github.com/rhayes777/PyAutoFit/actions) +[![Build](https://github.com/rhayes777/PyAutoBuild/actions/workflows/release.yml/badge.svg)](https://github.com/rhayes777/PyAutoBuild/actions) +[![Documentation Status](https://readthedocs.org/projects/pyautofit/badge/?version=latest)](https://pyautofit.readthedocs.io/en/latest/?badge=latest) +[![JOSS](https://joss.theoj.org/papers/10.21105/joss.02550/status.svg)](https://doi.org/10.21105/joss.02550) + +[Installation Guide](https://pyautofit.readthedocs.io/en/latest/installation/overview.html) | +[readthedocs](https://pyautofit.readthedocs.io/en/latest/index.html) | +[Introduction on Colab](https://colab.research.google.com/github/PyAutoLabs/autofit_workspace/blob/2026.5.1.4/notebooks/overview/overview_1_the_basics.ipynb) | +[HowToFit](https://github.com/PyAutoLabs/HowToFit) + +**PyAutoFit** is a Python based probabilistic programming language for model fitting and Bayesian inference +of large datasets. + +The basic **PyAutoFit** API allows us a user to quickly compose a probabilistic model and fit it to data via a +log likelihood function, using a range of non-linear search algorithms (e.g. MCMC, nested sampling). + +Users can then set up **PyAutoFit** scientific workflow, which enables streamlined modeling of small +datasets with tools to scale up to large datasets. + +**PyAutoFit** supports advanced statistical methods, most +notably [a big data framework for Bayesian hierarchical analysis](https://pyautofit.readthedocs.io/en/latest/features/graphical.html). + +## Getting Started + +The following links are useful for new starters: + +- [The PyAutoFit readthedocs](https://pyautofit.readthedocs.io/en/latest), which includes an [installation guide](https://pyautofit.readthedocs.io/en/latest/installation/overview.html) and an overview of **PyAutoFit**'s core features. +- [The introduction Jupyter Notebook on Colab](https://colab.research.google.com/github/PyAutoLabs/autofit_workspace/blob/2026.5.1.4/notebooks/overview/overview_1_the_basics.ipynb), where you can try **PyAutoFit** in a web browser (without installation). +- [The autofit_workspace GitHub repository](https://github.com/Jammy2211/autofit_workspace), which includes example scripts demonstrating **PyAutoFit**'s features. +- [The standalone HowToFit repository](https://github.com/PyAutoLabs/HowToFit), a series of Jupyter notebook lectures which give new users a step-by-step introduction to **PyAutoFit**. + +## Support + +Support for installation issues, help with Fit modeling and using **PyAutoFit** is available by +[raising an issue on the GitHub issues page](https://github.com/rhayes777/PyAutoFit/issues). + +We also offer support on the **PyAutoFit** [Slack channel](https://pyautoFit.slack.com/), where we also provide the +latest updates on **PyAutoFit**. Slack is invitation-only, so if you'd like to join send +an [email](https://github.com/Jammy2211) requesting an invite. + +## HowToFit + +For users less familiar with Bayesian inference and scientific analysis you may wish to read through +the **HowToFits** lectures. These teach you the basic principles of Bayesian inference, with the +content pitched at undergraduate level and above. + +The lectures are available in the [standalone HowToFit repository](https://github.com/PyAutoLabs/HowToFit). + +## API Overview + +To illustrate the **PyAutoFit** API, we use an illustrative toy model of fitting a one-dimensional Gaussian to +noisy 1D data. Here's the `data` (black) and the model (red) we'll fit: + + + +We define our model, a 1D Gaussian by writing a Python class using the format below: + +```python +class Gaussian: + + def __init__( + self, + centre=0.0, # <- PyAutoFit recognises these + normalization=0.1, # <- constructor arguments are + sigma=0.01, # <- the Gaussian's parameters. + ): + self.centre = centre + self.normalization = normalization + self.sigma = sigma + + """ + An instance of the Gaussian class will be available during model fitting. + + This method will be used to fit the model to data and compute a likelihood. + """ + + def model_data_from(self, xvalues): + + transformed_xvalues = xvalues - self.centre + + return (self.normalization / (self.sigma * (2.0 * np.pi) ** 0.5)) * \ + np.exp(-0.5 * (transformed_xvalues / self.sigma) ** 2.0) +``` + +**PyAutoFit** recognises that this Gaussian may be treated as a model component whose parameters can be fitted for via +a non-linear search like [emcee](https://github.com/dfm/emcee). + +To fit this Gaussian to the `data` we create an Analysis object, which gives **PyAutoFit** the `data` and a +`log_likelihood_function` describing how to fit the `data` with the model: + +```python +class Analysis(af.Analysis): + + def __init__(self, data, noise_map): + + self.data = data + self.noise_map = noise_map + + def log_likelihood_function(self, instance): + + """ + The 'instance' that comes into this method is an instance of the Gaussian class + above, with the parameters set to values chosen by the non-linear search. + """ + + print("Gaussian Instance:") + print("Centre = ", instance.centre) + print("normalization = ", instance.normalization) + print("Sigma = ", instance.sigma) + + """ + We fit the ``data`` with the Gaussian instance, using its + "model_data_from" function to create the model data. + """ + + xvalues = np.arange(self.data.shape[0]) + + model_data = instance.model_data_from(xvalues=xvalues) + residual_map = self.data - model_data + chi_squared_map = (residual_map / self.noise_map) ** 2.0 + log_likelihood = -0.5 * sum(chi_squared_map) + + return log_likelihood +``` + +We can now fit our model to the `data` using a non-linear search: + +```python +model = af.Model(Gaussian) + +analysis = Analysis(data=data, noise_map=noise_map) + +emcee = af.Emcee(nwalkers=50, nsteps=2000) + +result = emcee.fit(model=model, analysis=analysis) +``` + +The `result` contains information on the model-fit, for example the parameter samples, maximum log likelihood +model and marginalized probability density functions. diff --git a/README.rst b/README.rst deleted file mode 100644 index 335d87fe8..000000000 --- a/README.rst +++ /dev/null @@ -1,175 +0,0 @@ -PyAutoFit: Classy Probabilistic Programming -=========================================== - -.. |colab| image:: https://colab.research.google.com/assets/colab-badge.svg - :target: https://colab.research.google.com/github/PyAutoLabs/autofit_workspace/blob/2026.5.1.4/start_here.ipynb - -.. |RTD| image:: https://readthedocs.org/projects/pyautofit/badge/?version=latest - :target: https://pyautofit.readthedocs.io/en/latest/?badge=latest - :alt: Documentation Status - -.. |Tests| image:: https://github.com/rhayes777/PyAutoFit/actions/workflows/main.yml/badge.svg - :target: https://github.com/rhayes777/PyAutoFit/actions - -.. |Build| image:: https://github.com/rhayes777/PyAutoBuild/actions/workflows/release.yml/badge.svg - :target: https://github.com/rhayes777/PyAutoBuild/actions - -.. |JOSS| image:: https://joss.theoj.org/papers/10.21105/joss.02550/status.svg - :target: https://doi.org/10.21105/joss.02550 - -.. image:: https://www.repostatus.org/badges/latest/active.svg - :target: https://www.repostatus.org/#active - :alt: Project Status: Active - -.. image:: https://img.shields.io/pypi/pyversions/autofit - :target: https://pypi.org/project/autofit/ - :alt: Python Versions - -.. image:: https://img.shields.io/pypi/v/autofit.svg - :target: https://pypi.org/project/autofit/ - :alt: PyPI Version - -|colab| |Tests| |Build| |RTD| |JOSS| - -`Installation Guide `_ | -`readthedocs `_ | -`Introduction on Colab `_ | -`HowToFit `_ - -**PyAutoFit** is a Python based probabilistic programming language for model fitting and Bayesian inference -of large datasets. - -The basic **PyAutoFit** API allows us a user to quickly compose a probabilistic model and fit it to data via a -log likelihood function, using a range of non-linear search algorithms (e.g. MCMC, nested sampling). - -Users can then set up **PyAutoFit** scientific workflow, which enables streamlined modeling of small -datasets with tools to scale up to large datasets. - -**PyAutoFit** supports advanced statistical methods, most -notably `a big data framework for Bayesian hierarchical analysis `_. - -Getting Started ---------------- - -The following links are useful for new starters: - -- `The PyAutoFit readthedocs `_, which includes an `installation guide `_ and an overview of **PyAutoFit**'s core features. - -- `The introduction Jupyter Notebook on Colab `_, where you can try **PyAutoFit** in a web browser (without installation). - -- `The autofit_workspace GitHub repository `_, which includes example scripts demonstrating **PyAutoFit**'s features. - -- `The standalone HowToFit repository `_, a series of Jupyter notebook lectures which give new users a step-by-step introduction to **PyAutoFit**. - -Support -------- - -Support for installation issues, help with Fit modeling and using **PyAutoFit** is available by -`raising an issue on the GitHub issues page `_. - -We also offer support on the **PyAutoFit** `Slack channel `_, where we also provide the -latest updates on **PyAutoFit**. Slack is invitation-only, so if you'd like to join send -an `email `_ requesting an invite. - -HowToFit --------- - -For users less familiar with Bayesian inference and scientific analysis you may wish to read through -the **HowToFits** lectures. These teach you the basic principles of Bayesian inference, with the -content pitched at undergraduate level and above. - -The lectures are available in the `standalone HowToFit repository `_. - -API Overview ------------- - -To illustrate the **PyAutoFit** API, we use an illustrative toy model of fitting a one-dimensional Gaussian to -noisy 1D data. Here's the ``data`` (black) and the model (red) we'll fit: - -.. image:: https://raw.githubusercontent.com/rhayes777/PyAutoFit/main/files/toy_model_fit.png - :width: 400 - -We define our model, a 1D Gaussian by writing a Python class using the format below: - -.. code-block:: python - - class Gaussian: - - def __init__( - self, - centre=0.0, # <- PyAutoFit recognises these - normalization=0.1, # <- constructor arguments are - sigma=0.01, # <- the Gaussian's parameters. - ): - self.centre = centre - self.normalization = normalization - self.sigma = sigma - - """ - An instance of the Gaussian class will be available during model fitting. - - This method will be used to fit the model to data and compute a likelihood. - """ - - def model_data_from(self, xvalues): - - transformed_xvalues = xvalues - self.centre - - return (self.normalization / (self.sigma * (2.0 * np.pi) ** 0.5)) * \ - np.exp(-0.5 * (transformed_xvalues / self.sigma) ** 2.0) - -**PyAutoFit** recognises that this Gaussian may be treated as a model component whose parameters can be fitted for via -a non-linear search like `emcee `_. - -To fit this Gaussian to the ``data`` we create an Analysis object, which gives **PyAutoFit** the ``data`` and a -``log_likelihood_function`` describing how to fit the ``data`` with the model: - -.. code-block:: python - - class Analysis(af.Analysis): - - def __init__(self, data, noise_map): - - self.data = data - self.noise_map = noise_map - - def log_likelihood_function(self, instance): - - """ - The 'instance' that comes into this method is an instance of the Gaussian class - above, with the parameters set to values chosen by the non-linear search. - """ - - print("Gaussian Instance:") - print("Centre = ", instance.centre) - print("normalization = ", instance.normalization) - print("Sigma = ", instance.sigma) - - """ - We fit the ``data`` with the Gaussian instance, using its - "model_data_from" function to create the model data. - """ - - xvalues = np.arange(self.data.shape[0]) - - model_data = instance.model_data_from(xvalues=xvalues) - residual_map = self.data - model_data - chi_squared_map = (residual_map / self.noise_map) ** 2.0 - log_likelihood = -0.5 * sum(chi_squared_map) - - return log_likelihood - -We can now fit our model to the ``data`` using a non-linear search: - -.. code-block:: python - - model = af.Model(Gaussian) - - analysis = Analysis(data=data, noise_map=noise_map) - - emcee = af.Emcee(nwalkers=50, nsteps=2000) - - result = emcee.fit(model=model, analysis=analysis) - -The ``result`` contains information on the model-fit, for example the parameter samples, maximum log likelihood -model and marginalized probability density functions. \ No newline at end of file diff --git a/autofit/config/README.md b/autofit/config/README.md new file mode 100644 index 000000000..56f5982cb --- /dev/null +++ b/autofit/config/README.md @@ -0,0 +1,13 @@ +The `config` folder contains configuration files which customize default **PyAutoLens**. + +# Folders + +- `priors`: Configs defining default priors assumed on every lens model component and set of parameters. +- `visualize`: Configs defining what images are output by a lens model fit. + +# Files + +- `general.yaml`: Customizes general **PyAutoLens** settings. +- `non-linear.yaml`: Configs for default non-linear search (e.g. MCMC, nested sampling) settings. +- `logging.yaml`: Customizes the logging behaviour of **PyAutoLens**. +- `notation.yaml`: Configs defining labels and formatting of model parameters when used for visualization. diff --git a/autofit/config/README.rst b/autofit/config/README.rst deleted file mode 100644 index 7151fb9c0..000000000 --- a/autofit/config/README.rst +++ /dev/null @@ -1,15 +0,0 @@ -The ``config`` folder contains configuration files which customize default **PyAutoLens**. - -Folders -------- - -- ``priors``: Configs defining default priors assumed on every lens model component and set of parameters. -- ``visualize``: Configs defining what images are output by a lens model fit. - -Files ------ - -- ``general.yaml``: Customizes general **PyAutoLens** settings. -- ``non-linear.yaml``: Configs for default non-linear search (e.g. MCMC, nested sampling) settings. -- ``logging.yaml``: Customizes the logging behaviour of **PyAutoLens**. -- ``notation.yaml``: Configs defining labels and formatting of model parameters when used for visualization. diff --git a/autofit/config/non_linear/README.md b/autofit/config/non_linear/README.md new file mode 100644 index 000000000..3b9312061 --- /dev/null +++ b/autofit/config/non_linear/README.md @@ -0,0 +1,8 @@ +The `non_linear` folder contains configuration files which customize the default behaviour of non-linear searches in +**PyAutoLens**. + +# Files + +- `mcmc.yaml`: Settings default behaviour of MCMC non-linear searches (e.g. Emcee). +- `nest.yaml`: Settings default behaviour of nested sampler non-linear searches (e.g. Dynesty). +- `mle.yaml`: Settings default behaviour of maximum likelihood estimator (mle) searches (e.g. BFGS). diff --git a/autofit/config/non_linear/README.rst b/autofit/config/non_linear/README.rst deleted file mode 100644 index 23ec96cd2..000000000 --- a/autofit/config/non_linear/README.rst +++ /dev/null @@ -1,9 +0,0 @@ -The ``non_linear`` folder contains configuration files which customize the default behaviour of non-linear searches in -**PyAutoLens**. - -Files ------ - -- ``mcmc.yaml``: Settings default behaviour of MCMC non-linear searches (e.g. Emcee). -- ``nest.yaml``: Settings default behaviour of nested sampler non-linear searches (e.g. Dynesty). -- ``mle.yaml``: Settings default behaviour of maximum likelihood estimator (mle) searches (e.g. BFGS). \ No newline at end of file diff --git a/autofit/config/priors/README.md b/autofit/config/priors/README.md new file mode 100644 index 000000000..cc2bb6fe8 --- /dev/null +++ b/autofit/config/priors/README.md @@ -0,0 +1,42 @@ +The prior config files contain the default priors and related variables for every model component when it is used as a +model. + +They appear as follows: + +```bash +Gaussian: + centre: + type: Uniform + lower_limit: 0.0 + upper_limit: 100.0 + width_modifier: + type: Absolute + value: 20.0 + limits: + lower: -inf + upper: inf +``` + +The sections of this example config set the following: + +> type {Uniform, Gaussian, LogUniform} +> +> : The default prior given to this parameter when used by the non-linear search. In the example above, a +> UniformPrior is used with lower_limit of 0.0 and upper_limit of 4.0. A GaussianPrior could be used by +> putting "Gaussian" in the "type" box, with "mean" and "sigma" used to set the default values. Any prior can be +> set in an analogous fashion (see the example configs). +> +> width_modifier +> +> : When the results of a search are passed to a subsequent search to set up the priors of its non-linear search, +> this entry describes how the Prior is passed. For a full description of prior passing, checkout the examples +> in 'autolens_workspace/examples/complex/linking'. +> +> limits +> +> : When the results of a search are passed to a subsequent search, they are passed using a GaussianPrior. The +> limits set the physical lower and upper limits of this GaussianPrior, such that parameter samples +> can not go beyond these limits. + +The files `template_module.yaml` and `TemplateObject.yaml` give templates one can use to set up prior default +configs for your own model components. diff --git a/autofit/config/priors/README.rst b/autofit/config/priors/README.rst deleted file mode 100644 index 91c6147f3..000000000 --- a/autofit/config/priors/README.rst +++ /dev/null @@ -1,37 +0,0 @@ -The prior config files contain the default priors and related variables for every model component when it is used as a -model. - -They appear as follows: - -.. code-block:: bash - - Gaussian: - centre: - type: Uniform - lower_limit: 0.0 - upper_limit: 100.0 - width_modifier: - type: Absolute - value: 20.0 - limits: - lower: -inf - upper: inf - -The sections of this example config set the following: - - type {Uniform, Gaussian, LogUniform} - The default prior given to this parameter when used by the non-linear search. In the example above, a - UniformPrior is used with lower_limit of 0.0 and upper_limit of 4.0. A GaussianPrior could be used by - putting "Gaussian" in the "type" box, with "mean" and "sigma" used to set the default values. Any prior can be - set in an analogous fashion (see the example configs). - width_modifier - When the results of a search are passed to a subsequent search to set up the priors of its non-linear search, - this entry describes how the Prior is passed. For a full description of prior passing, checkout the examples - in 'autolens_workspace/examples/complex/linking'. - limits - When the results of a search are passed to a subsequent search, they are passed using a GaussianPrior. The - limits set the physical lower and upper limits of this GaussianPrior, such that parameter samples - can not go beyond these limits. - -The files ``template_module.yaml`` and ``TemplateObject.yaml`` give templates one can use to set up prior default -configs for your own model components. \ No newline at end of file diff --git a/autofit/config/visualize/README.md b/autofit/config/visualize/README.md new file mode 100644 index 000000000..f5c614645 --- /dev/null +++ b/autofit/config/visualize/README.md @@ -0,0 +1,6 @@ +The `config` folder contains configuration files which customize default **PyAutoLens**. + +# Files + +- `general.yaml`: Customizes general visualization settings (e.g. the matplotlib backend). +- `plots_search.yaml`: Customize which non-linear search figures are output during a model-fit. diff --git a/autofit/config/visualize/README.rst b/autofit/config/visualize/README.rst deleted file mode 100644 index 200fa3c53..000000000 --- a/autofit/config/visualize/README.rst +++ /dev/null @@ -1,7 +0,0 @@ -The ``config`` folder contains configuration files which customize default **PyAutoLens**. - -Files ------ - -- ``general.yaml``: Customizes general visualization settings (e.g. the matplotlib backend). -- ``plots_search.yaml``: Customize which non-linear search figures are output during a model-fit. \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 0811412c4..f6db1e5bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta" name = "autofit" dynamic = ["version"] description = "Classy Probabilistic Programming" -readme = { file = "README.rst", content-type = "text/x-rst" } +readme = { file = "README.md", content-type = "text/markdown" } license = { text = "MIT" } requires-python = ">=3.9" authors = [ diff --git a/test_autofit/config/non_linear/README.md b/test_autofit/config/non_linear/README.md new file mode 100644 index 000000000..3b9312061 --- /dev/null +++ b/test_autofit/config/non_linear/README.md @@ -0,0 +1,8 @@ +The `non_linear` folder contains configuration files which customize the default behaviour of non-linear searches in +**PyAutoLens**. + +# Files + +- `mcmc.yaml`: Settings default behaviour of MCMC non-linear searches (e.g. Emcee). +- `nest.yaml`: Settings default behaviour of nested sampler non-linear searches (e.g. Dynesty). +- `mle.yaml`: Settings default behaviour of maximum likelihood estimator (mle) searches (e.g. BFGS). diff --git a/test_autofit/config/non_linear/README.rst b/test_autofit/config/non_linear/README.rst deleted file mode 100644 index 23ec96cd2..000000000 --- a/test_autofit/config/non_linear/README.rst +++ /dev/null @@ -1,9 +0,0 @@ -The ``non_linear`` folder contains configuration files which customize the default behaviour of non-linear searches in -**PyAutoLens**. - -Files ------ - -- ``mcmc.yaml``: Settings default behaviour of MCMC non-linear searches (e.g. Emcee). -- ``nest.yaml``: Settings default behaviour of nested sampler non-linear searches (e.g. Dynesty). -- ``mle.yaml``: Settings default behaviour of maximum likelihood estimator (mle) searches (e.g. BFGS). \ No newline at end of file