Skip to content

Commit e90fb4f

Browse files
authored
Merge pull request #1160 from rhayes777/feature/build_fixes
feature/build_fixes
2 parents 42ea7c1 + c744db2 commit e90fb4f

52 files changed

Lines changed: 336 additions & 393 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

autofit/__init__.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from autoconf import jax_wrapper
12
from autoconf.dictable import register_parser
23
from . import conf
34

@@ -140,6 +141,4 @@ def save_abc(pickler, obj):
140141
pickle._Pickler.save_type(pickler, obj)
141142

142143

143-
144-
145-
__version__ = "2025.10.20.1"
144+
__version__ = "2025.11.5.1"

autofit/aggregator/search_output.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,17 @@ def samples_summary(self) -> SamplesSummary:
228228
summary.model = self.model
229229
return summary
230230

231+
@property
232+
def latent_summary(self) -> SamplesSummary:
233+
"""
234+
The summary of the samples, which includes the maximum log likelihood sample and the log evidence.
235+
236+
This is loaded from a JSON file.
237+
"""
238+
summary = self.value("latent.latent_summary")
239+
summary.model = self.model
240+
return summary
241+
231242
@property
232243
def instance(self):
233244
"""

autofit/aggregator/summary/aggregate_csv/column.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,9 @@ def __init__(self, name: str, compute: Callable):
105105
self.compute = compute
106106

107107
def value(self, row: "Row"):
108+
108109
try:
109-
return self.compute(row.result.samples)
110+
return self.compute(row.result)
110111
except AttributeError as e:
111112
raise AssertionError(
112113
"Cannot compute additional fields if no samples.json present"

autofit/aggregator/summary/aggregate_images.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@ def output_to_folder(
210210
else:
211211
output_name = name[i]
212212

213+
output_path = folder / output_name
214+
output_path.parent.mkdir(parents=True, exist_ok=True)
213215
image.save(folder / f"{output_name}.png")
214216

215217
@staticmethod

autofit/config/general.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
jax:
2-
use_jax: false # If True, PyAutoFit uses JAX internally, whereas False uses normal Numpy.
31
updates:
42
iterations_per_quick_update: 1e99 # Non-linear search iterations between every quick update, which just displays the maximum likelihood model fit.
53
iterations_per_full_update: 1e99 # Non-linear search iterations between every full update, which outputs all visuals and result fits (e.g. model.result, search.summary), this exits the search and can be slow.

autofit/example/analysis.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import numpy as np
22
from typing import Dict, Optional
33

4-
from autofit.jax_wrapper import numpy as xp
5-
64
import autofit as af
75

86
from autofit.example.result import ResultExample
@@ -38,7 +36,7 @@ class Analysis(af.Analysis):
3836

3937
LATENT_KEYS = ["gaussian.fwhm"]
4038

41-
def __init__(self, data: np.ndarray, noise_map: np.ndarray):
39+
def __init__(self, data: np.ndarray, noise_map: np.ndarray, use_jax=False):
4240
"""
4341
In this example the `Analysis` object only contains the data and noise-map. It can be easily extended,
4442
for more complex data-sets and model fitting problems.
@@ -51,12 +49,12 @@ def __init__(self, data: np.ndarray, noise_map: np.ndarray):
5149
A 1D numpy array containing the noise values of the data, used for computing the goodness of fit
5250
metric.
5351
"""
54-
super().__init__()
52+
super().__init__(use_jax=use_jax)
5553

5654
self.data = data
5755
self.noise_map = noise_map
5856

59-
def log_likelihood_function(self, instance: af.ModelInstance) -> float:
57+
def log_likelihood_function(self, instance: af.ModelInstance, xp=np) -> float:
6058
"""
6159
Determine the log likelihood of a fit of multiple profiles to the dataset.
6260
@@ -98,14 +96,15 @@ def model_data_1d_from(self, instance: af.ModelInstance) -> np.ndarray:
9896
The model data of the profiles.
9997
"""
10098

101-
xvalues = xp.arange(self.data.shape[0])
102-
model_data_1d = xp.zeros(self.data.shape[0])
99+
xvalues = self._xp.arange(self.data.shape[0])
100+
model_data_1d = self._xp.zeros(self.data.shape[0])
103101

104102
try:
105103
for profile in instance:
106104
try:
107105
model_data_1d += profile.model_data_from(
108-
xvalues=xvalues
106+
xvalues=xvalues,
107+
xp=self._xp
109108
)
110109
except AttributeError:
111110
pass

autofit/example/model.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
import numpy as np
33
from typing import Tuple
44

5-
from autofit.jax_wrapper import numpy as xp
6-
75
"""
86
The `Gaussian` class in this module is the model components that is fitted to data using a non-linear search. The
97
inputs of its __init__ constructor are the parameters which can be fitted for.
@@ -47,7 +45,7 @@ def fwhm(self) -> float:
4745
the free parameters of the model which we are interested and may want to store the full samples information
4846
on (e.g. to create posteriors).
4947
"""
50-
return 2 * xp.sqrt(2 * xp.log(2)) * self.sigma
48+
return 2 * np.sqrt(2 * np.log(2)) * self.sigma
5149

5250
def _tree_flatten(self):
5351
return (self.centre, self.normalization, self.sigma), None
@@ -64,7 +62,7 @@ def __eq__(self, other):
6462
and self.sigma == other.sigma
6563
)
6664

67-
def model_data_from(self, xvalues: np.ndarray) -> np.ndarray:
65+
def model_data_from(self, xvalues: np.ndarray, xp=np) -> np.ndarray:
6866
"""
6967
Calculate the normalization of the profile on a 1D grid of Cartesian x coordinates.
7068
@@ -82,7 +80,7 @@ def model_data_from(self, xvalues: np.ndarray) -> np.ndarray:
8280
xp.exp(-0.5 * xp.square(xp.divide(transformed_xvalues, self.sigma))),
8381
)
8482

85-
def f(self, x: float):
83+
def f(self, x: float, xp=np):
8684
return (
8785
self.normalization
8886
/ (self.sigma * xp.sqrt(2 * math.pi))
@@ -137,7 +135,7 @@ def __init__(
137135
self.normalization = normalization
138136
self.rate = rate
139137

140-
def model_data_from(self, xvalues: np.ndarray) -> np.ndarray:
138+
def model_data_from(self, xvalues: np.ndarray, xp=np) -> np.ndarray:
141139
"""
142140
Calculate the 1D Gaussian profile on a 1D grid of Cartesian x coordinates.
143141

autofit/graphical/declarative/abstract.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ class AbstractDeclarativeFactor(Analysis, ABC):
1919
optimiser: AbstractFactorOptimiser
2020
_plates: Tuple[Plate, ...] = ()
2121

22-
def __init__(self, include_prior_factors=False):
22+
def __init__(self, include_prior_factors=False, use_jax : bool = False):
2323
self.include_prior_factors = include_prior_factors
2424

25+
super().__init__(use_jax=use_jax)
26+
2527
@property
2628
@abstractmethod
2729
def name(self):

autofit/graphical/declarative/collection.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,15 @@
1111
from autofit.mapper.model import ModelInstance
1212
from autofit.mapper.prior_model.prior_model import Model
1313

14-
from autofit.jax_wrapper import register_pytree_node_class
1514
from ...non_linear.combined_result import CombinedResult
1615

17-
18-
@register_pytree_node_class
1916
class FactorGraphModel(AbstractDeclarativeFactor):
2017
def __init__(
2118
self,
2219
*model_factors: Union[AbstractDeclarativeFactor, HierarchicalFactor],
2320
name=None,
2421
include_prior_factors=True,
22+
use_jax : bool = False
2523
):
2624
"""
2725
A collection of factors that describe models, which can be
@@ -36,6 +34,7 @@ def __init__(
3634
"""
3735
super().__init__(
3836
include_prior_factors=include_prior_factors,
37+
use_jax=use_jax,
3938
)
4039
self._model_factors = list(model_factors)
4140
self._name = name or namer(self.__class__.__name__)
@@ -279,3 +278,16 @@ def visualize_combined(
279278
instance,
280279
during_analysis=during_analysis,
281280
)
281+
282+
def perform_quick_update(self, paths, instance):
283+
284+
try:
285+
self.model_factors[0].visualize_combined(
286+
analyses=self.model_factors,
287+
paths=paths,
288+
instance=instance,
289+
during_analysis=True,
290+
quick_update=True,
291+
)
292+
except Exception as e:
293+
pass

autofit/graphical/declarative/factor/analysis.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
from autofit.non_linear.paths.abstract import AbstractPaths
1111
from .abstract import AbstractModelFactor
1212

13-
from autofit.jax_wrapper import register_pytree_node_class
14-
1513

1614
class FactorCallable:
1715
def __init__(
@@ -45,8 +43,6 @@ def __call__(self, **kwargs: np.ndarray) -> float:
4543
instance = self.prior_model.instance_for_arguments(arguments)
4644
return self.analysis.log_likelihood_function(instance)
4745

48-
49-
@register_pytree_node_class
5046
class AnalysisFactor(AbstractModelFactor):
5147
@property
5248
def prior_model(self):

0 commit comments

Comments
 (0)