def __init__( self, pixelization_prior_model: af.PriorModel(pix.Pixelization), regularization_prior_model: af.PriorModel(reg.Regularization), inversion_pixels_fixed: float = None, ): """ The setup of the inversion source modeling of a pipeline, which controls how PyAutoGalaxy template pipelines run, for example controlling the `Pixelization` and `Regularization` used by the `Inversion`. Users can write their own pipelines which do not use or require the `SetupLightInversion` class. This class enables pipeline tagging, whereby the setup of the pipeline is used in the template pipeline scripts to tag the output path of the results depending on the setup parameters. This allows one to fit different models to a dataset in a structured path format. Parameters ---------- pixelization_prior_model : af.PriorModel(pix.Pixelization) If the pipeline uses an `Inversion` to reconstruct the galaxy's source, this determines the `Pixelization` used. regularization_prior_model : af.PriorModel(reg.Regularization) If the pipeline uses an `Inversion` to reconstruct the galaxy's source, this determines the `Regularization` scheme used. inversion_pixels_fixed : float The fixed number of source pixels used by a `Pixelization` class that takes as input a fixed number of pixels. """ super().__init__( pixelization_prior_model=pixelization_prior_model, regularization_prior_model=regularization_prior_model, inversion_pixels_fixed=inversion_pixels_fixed, )
def __init__(self, model_redshift=False, **kwargs): super().__init__() self.redshift = af.PriorModel(Redshift) if model_redshift else None self.__dict__.update({ key: af.PriorModel(value) if inspect.isclass(value) else value for key, value in kwargs.items() })
def make_pipeline(name, folders, real_space_mask, search=af.DynestyStatic()): mass = af.PriorModel(al.mp.EllipticalIsothermal) mass.centre.centre_0 = 0.0 mass.centre.centre_1 = 0.0 mass.einstein_radius = 1.6 pixelization = af.PriorModel(al.pix.Rectangular) pixelization.shape_0 = 20.0 pixelization.shape_1 = 20.0 phase1 = al.PhaseInterferometer( phase_name="phase_1", folders=folders, galaxies=dict( lens=al.GalaxyModel(redshift=0.5, bulge=al.lp.SphericalDevVaucouleurs, mass=mass), source=al.GalaxyModel(redshift=1.0, pixelization=pixelization, regularization=al.reg.Constant), ), real_space_mask=real_space_mask, search=search, ) phase1.search.const_efficiency_mode = True phase1.search.n_live_points = 60 phase1.search.facc = 0.8 return al.PipelineDataset(name, phase1)
def test_model(): identifier = af.PriorModel(af.Gaussian, centre=af.UniformPrior()).identifier assert identifier == af.PriorModel(af.Gaussian, centre=af.UniformPrior()).identifier assert identifier != af.PriorModel( af.Gaussian, centre=af.UniformPrior(upper_limit=0.5)).identifier
def make_mapper_with_list(): mapper = af.ModelMapper() mapper.list = [ af.PriorModel(af.m.MockClassx2), af.PriorModel(af.m.MockClassx2) ] return mapper
def test_collection(): identifier = af.CollectionPriorModel( gaussian=af.PriorModel(Gaussian, centre=af.UniformPrior())).identifier assert identifier == af.CollectionPriorModel( gaussian=af.PriorModel(Gaussian, centre=af.UniformPrior())).identifier assert identifier != af.CollectionPriorModel(gaussian=af.PriorModel( Gaussian, centre=af.UniformPrior(upper_limit=0.5))).identifier
def test_automatic_boxing(self): mapper = af.ModelMapper() mapper.list = [ af.PriorModel(af.m.MockClassx2), af.PriorModel(af.m.MockClassx2) ] assert isinstance(mapper.list, af.CollectionPriorModel)
def test_is_only_model(): collection = af.CollectionPriorModel(gaussian=af.PriorModel(af.Gaussian), gaussian_2=af.PriorModel(af.Gaussian)) assert collection.is_only_model(af.Gaussian) is True collection.other = af.PriorModel(af.m.MockClassx2) assert collection.is_only_model(af.Gaussian) is False
def test_mapper_plus_mapper(self): one = af.ModelMapper() two = af.ModelMapper() one.a = af.PriorModel(mock.MockClassx2) two.b = af.PriorModel(mock.MockClassx2) three = one + two assert three.prior_count == 4
def make_pipeline(name, folders, real_space_mask, search=af.DynestyStatic()): mass = af.PriorModel(al.mp.EllipticalIsothermal) mass.centre.centre_0 = 2.0 mass.centre.centre_1 = 2.0 mass.einstein_radius = 1.6 pixelization = af.PriorModel(al.pix.VoronoiMagnification) pixelization.shape_0 = 20.0 pixelization.shape_1 = 20.0 phase1 = al.PhaseInterferometer( phase_name="phase_1", folders=folders, galaxies=dict( lens=al.GalaxyModel(redshift=0.5, mass=mass), source=al.GalaxyModel(redshift=1.0, pixelization=pixelization, regularization=al.reg.Constant), ), real_space_mask=real_space_mask, search=search, ) phase1.search.const_efficiency_mode = True phase1.search.n_live_points = 60 phase1.search.facc = 0.8 phase1 = phase1.extend_with_inversion_phase() phase2 = al.PhaseInterferometer( phase_name="phase_2", folders=folders, galaxies=dict( lens=al.GalaxyModel(redshift=0.5, mass=phase1.result.model.galaxies.lens.mass), source=al.GalaxyModel( redshift=1.0, pixelization=phase1.results.settings_inversion.instance. galaxies.source.pixelization, regularization=phase1.results.settings_inversion.instance. galaxies.source.regularization, ), ), real_space_mask=real_space_mask, search=search, ) phase2.search.const_efficiency_mode = True phase2.search.n_live_points = 60 phase2.search.facc = 0.8 phase2 = phase2.extend_with_inversion_phase() return al.PipelineDataset(name, phase1, phase2)
def test_circular(self): one = af.PriorModel(af.m.MockClassx2) one.one = af.PriorModel(af.m.MockClassx2) one.one.one = one # noinspection PyUnresolvedReferences assert one.prior_count == one.one.prior_count assert copy.deepcopy(one).prior_count == one.prior_count
def __init__( self, with_shear=True, bulge_prior_model: af.PriorModel( lmp.LightMassProfile) = lmp.EllipticalSersic, disk_prior_model: af.PriorModel( lmp.LightMassProfile) = lmp.EllipticalExponential, envelope_prior_model: af.PriorModel(lmp.LightMassProfile) = None, dark_prior_model: af.PriorModel( mp.MassProfile) = mp.EllipticalNFWMCRLudlow, mass_centre: (float, float) = None, constant_mass_to_light_ratio: bool = False, align_bulge_dark_centre: bool = False, ): """ The setup of the mass modeling in a pipeline for `MassProfile`'s representing the decomposed light and dark mass distributions, which controls how PyAutoGalaxy template pipelines run, for example controlling assumptions about the bulge-disk model. Users can write their own pipelines which do not use or require the `SetupMassLightDark` class. This class enables pipeline tagging, whereby the setup of the pipeline is used in the template pipeline scripts to tag the output path of the results depending on the setup parameters. This allows one to fit different models to a dataset in a structured path format. Parameters ---------- with_shear : bool If `True` the `ExternalShear` `PriorModel` is omitted from the galaxy model. bulge_prior_model : af.PriorModel or al.lmp.LightMassProfile The `LightProfile` `PriorModel` used to represent the light distribution of a bulge. disk_prior_model : af.PriorModel(al.lmp.LightMassProfile) The `LightProfile` `PriorModel` used to represent the light distribution of a disk. envelope_prior_model : af.PriorModel(al.lmp.LightMassProfile) The `LightProfile` `PriorModel` used to represent the light distribution of a envelope. mass_centre : (float, float) If input, a fixed (y,x) centre of the mass profile is used which is not treated as a free parameter by the non-linear search. constant_mass_to_light_ratio : bool If True, and the mass model consists of multiple `LightProfile` and `MassProfile` coomponents, the mass-to-light ratio's of all components are fixed to one shared value. align_bulge_mass_centre : bool If True, and the mass model is a decomposed bulge, disk and dark matter model (e.g. EllipticalSersic + EllipticalExponential + SphericalNFW), the centre of the bulge and dark matter profiles are aligned. """ super().__init__( bulge_prior_model=bulge_prior_model, disk_prior_model=disk_prior_model, envelope_prior_model=envelope_prior_model, dark_prior_model=dark_prior_model, mass_centre=mass_centre, constant_mass_to_light_ratio=constant_mass_to_light_ratio, align_bulge_dark_centre=align_bulge_dark_centre, ) self.with_shear = with_shear
def bulge_light_and_mass_profile(self): """ The light and mass profile of a bulge component of a galaxy. By default, this is returned as an _EllipticalSersic_ profile without a radial gradient, however the _SetupPipeline_ inputs can be customized to change this to include a radial gradient. """ if not self.bulge_mass_to_light_ratio_gradient: return af.PriorModel(lmp.EllipticalSersic) return af.PriorModel(lmp.EllipticalSersicRadialGradient)
def test__duplication(self): phase_dataset_7x7 = toy.PhaseImaging( phase_name="test_phase", gaussians=[ af.PriorModel(cls=toy.SphericalGaussian), af.PriorModel(cls=toy.SphericalGaussian), ], ) toy.PhaseImaging(phase_name="test_phase") assert phase_dataset_7x7.gaussians is not None
def test_same_argument_name(self): mapper = af.ModelMapper() mapper.one = af.PriorModel(af.m.MockClassx2) mapper.two = af.PriorModel(af.m.MockClassx2) instance = mapper.instance_from_vector([0.1, 0.2, 0.3, 0.4]) assert instance.one.one == 0.1 assert instance.one.two == 0.2 assert instance.two.one == 0.3 assert instance.two.two == 0.4
def __init__( self, bulge_prior_model: af.PriorModel( lp.LightProfile) = lp.EllipticalSersic, disk_prior_model: af.PriorModel(lp.LightProfile) = None, envelope_prior_model: af.PriorModel(lp.LightProfile) = None, light_centre: (float, float) = None, align_bulge_disk_centre: bool = True, align_bulge_disk_elliptical_comps: bool = False, align_bulge_envelope_centre: bool = False, ): """ The setup of the light modeling in a pipeline, which controls how PyAutoGalaxy template pipelines runs, for example controlling assumptions about the bulge-disk model. Users can write their own pipelines which do not use or require the *SetupLightParametric* class. This class enables pipeline tagging, whereby the setup of the pipeline is used in the template pipeline scripts to tag the output path of the results depending on the setup parameters. This allows one to fit different models to a dataset in a structured path format. Parameters ---------- bulge_prior_model : af.PriorModel(lp.LightProfile) The `LightProfile` `PriorModel` used to represent the light distribution of a bulge. disk_prior_model : af.PriorModel(lp.LightProfile) The `LightProfile` `PriorModel` used to represent the light distribution of a disk. envelope_prior_model : af.PriorModel(lp.LightProfile) The `LightProfile` `PriorModel` used to represent the light distribution of a envelope. light_centre : (float, float) or None If input, a fixed (y,x) centre of the galaxy is used for the light profile model which is not treated as a free parameter by the non-linear search. align_bulge_disk_centre : bool or None If a bulge + disk light model (e.g. EllipticalSersic + EllipticalExponential) is used to fit the galaxy, `True` will align the centre of the bulge and disk components and not fit them separately. align_bulge_disk_elliptical_comps : bool or None If a bulge + disk light model (e.g. EllipticalSersic + EllipticalExponential) is used to fit the galaxy, `True` will align the elliptical components the bulge and disk components and not fit them separately. align_bulge_envelope_centre : bool or None If a bulge + envelope light model (e.g. EllipticalSersic + EllipticalExponential) is used to fit the galaxy, `True` will align the centre of the bulge and envelope components and not fit them separately. """ super().__init__( bulge_prior_model=bulge_prior_model, disk_prior_model=disk_prior_model, envelope_prior_model=envelope_prior_model, light_centre=light_centre, align_bulge_disk_centre=align_bulge_disk_centre, align_bulge_disk_elliptical_comps=align_bulge_disk_elliptical_comps, align_bulge_envelope_centre=align_bulge_envelope_centre, )
def test_float_argument(self): prior = af.UniformPrior(0.5, 2.0) prior_model = af.PriorModel(af.m.MockComponents, parameter=prior) assert prior_model.prior_count == 1 assert prior_model.priors[0] is prior prior_model = af.PriorModel(af.m.MockComponents, parameter=4.0) assert prior_model.prior_count == 0 assert prior_model.parameter == 4.0 instance = prior_model.instance_for_arguments({}) assert instance.parameter == 4.0
def test_list_arguments(self): prior_model = af.PriorModel(af.m.MockListClass) assert prior_model.prior_count == 0 prior_model = af.PriorModel(af.m.MockListClass, ls=[af.m.MockClassx2]) assert prior_model.prior_count == 2 prior_model = af.PriorModel(af.m.MockListClass, ls=[af.m.MockClassx2, af.m.MockClassx2]) assert prior_model.prior_count == 4
def test_add_prior_models(self): mock_cls_0 = af.PriorModel(af.m.MockChildTuplex2) mock_cls_1 = af.PriorModel(af.m.MockChildTuplex2) mock_cls_0.one = 1.0 mock_cls_1.two = 0.0 result = mock_cls_0 + mock_cls_1 assert isinstance(result, af.PriorModel) assert result.cls == af.m.MockChildTuplex2 assert isinstance(result.one, af.Prior) assert isinstance(result.two, af.Prior)
def test_add_prior_models(self): profile_1 = af.PriorModel(mock_real.EllProfile) profile_2 = af.PriorModel(mock_real.EllProfile) profile_1.axis_ratio = 1.0 profile_2.phi = 0.0 result = profile_1 + profile_2 assert isinstance(result, af.PriorModel) assert result.cls == mock_real.EllProfile assert isinstance(result.axis_ratio, af.Prior) assert isinstance(result.phi, af.Prior)
def test_parameter_name_distinction(self): mm = af.ModelMapper() mm.ls = af.CollectionPriorModel([ af.PriorModel(af.m.MockClassRelativeWidth), af.PriorModel(af.m.MockClassRelativeWidth), ]) assert mm.model_component_and_parameter_names == [ "ls_0_one", "ls_0_two", "ls_0_three", "ls_1_one", "ls_1_two", "ls_1_three", ]
def make_job(perturbation_model, search): instance = af.ModelInstance() instance.gaussian = af.Gaussian() base_instance = instance instance.perturbation = af.Gaussian() image = image_function(instance) # noinspection PyTypeChecker return s.Job(model=af.Collection(gaussian=af.PriorModel(af.Gaussian)), perturbation_model=af.PriorModel(af.Gaussian), base_instance=base_instance, perturbation_instance=instance, analysis_factory=MockAnalysisFactory(Analysis(image)), search=search, number=1)
def test__prior__samples_sample_priors(self): model = af.PriorModel(af.m.MockClassx4) model.one = af.UniformPrior(lower_limit=0.099, upper_limit=0.101) model.two = af.UniformPrior(lower_limit=0.199, upper_limit=0.201) model.three = af.UniformPrior(lower_limit=0.299, upper_limit=0.301) model.four = af.UniformPrior(lower_limit=0.399, upper_limit=0.401) initializer = af.InitializerPrior() unit_parameter_lists, parameter_lists, figure_of_merit_list = initializer.samples_from_model( total_points=2, model=model, fitness_function=MockFitness()) assert 0.0 < unit_parameter_lists[0][0] < 1.0 assert 0.0 < unit_parameter_lists[1][0] < 1.0 assert 0.0 < unit_parameter_lists[0][1] < 1.0 assert 0.0 < unit_parameter_lists[1][1] < 1.0 assert 0.0 < unit_parameter_lists[0][2] < 1.0 assert 0.0 < unit_parameter_lists[1][2] < 1.0 assert 0.0 < unit_parameter_lists[0][3] < 1.0 assert 0.0 < unit_parameter_lists[1][3] < 1.0 assert 0.099 < parameter_lists[0][0] < 0.101 assert 0.099 < parameter_lists[1][0] < 0.101 assert 0.199 < parameter_lists[0][1] < 0.201 assert 0.199 < parameter_lists[1][1] < 0.201 assert 0.299 < parameter_lists[0][2] < 0.301 assert 0.299 < parameter_lists[1][2] < 0.301 assert 0.399 < parameter_lists[0][3] < 0.401 assert 0.399 < parameter_lists[1][3] < 0.401 assert figure_of_merit_list == [1.0, 1.0]
def make_frozen_model(): model = af.PriorModel( af.Gaussian ) model.freeze() return model
def test_commit(session): model = af.PriorModel( m.Gaussian ) serialized = db.Object.from_object(model) session.add(serialized) session.commit()
def smbh_from_centre(self, centre, centre_sigma=0.1): """ Create a _PriorModel_ of a _PointMass_ _MassProfile_ if *include_smbh* is True, which is fitted for in the mass-model too represent a super-massive black-hole (smbh). The centre of the smbh is an input parameter of the functiono, and this centre is either fixed to the input values as an instance or fitted for as a model. Parameters ---------- centre : (float, float) The centre of the _PointMass_ that repreents the super-massive black hole. centre_fixed : bool If True, the centre is fixed to the input values, else it is fitted for as free parameters. centre_sigma : float If the centre is free, this is the sigma value of each centre's _GaussianPrior_. """ if not self.include_smbh: return None smbh = af.PriorModel(mp.PointMass) if self.smbh_centre_fixed: smbh.centre = centre else: smbh.centre.centre_0 = af.GaussianPrior(mean=centre[0], sigma=centre_sigma) smbh.centre.centre_1 = af.GaussianPrior(mean=centre[1], sigma=centre_sigma) return smbh
def test_update_identifiers_from_dict(): search = af.DynestyStatic(name="name") search.paths.model = af.PriorModel(af.Gaussian) old_directory_paths = search.paths initial_length = len(old_directory_paths._identifier.hash_list) old_directory_paths.save_all() old_directory_paths.zip_remove() update_identifiers_from_dict(output_directory, {"normalization": "magnitude"}) filename, = listdir(output_directory / "name") identifier, suffix = filename.split(".") assert identifier != old_directory_paths.identifier assert suffix == "zip" unzipped = output_directory / "unzipped" with zipfile.ZipFile(output_directory / "name" / filename, "r") as f: f.extractall(unzipped) with open(unzipped / ".identifier") as f: lines = f.read().split("\n") assert "normalization" not in lines assert "magnitude" in lines assert len(lines) == initial_length
def test__samples_in_test_model(self): model = af.PriorModel(af.m.MockClassx4) model.one = af.UniformPrior(lower_limit=0.099, upper_limit=0.101) model.two = af.UniformPrior(lower_limit=0.199, upper_limit=0.201) model.three = af.UniformPrior(lower_limit=0.299, upper_limit=0.301) model.four = af.UniformPrior(lower_limit=0.399, upper_limit=0.401) initializer = af.InitializerPrior() unit_parameter_lists, parameter_lists, figure_of_merit_list = initializer.samples_in_test_mode( total_points=2, model=model, ) assert 0.0 < unit_parameter_lists[0][0] < 1.0 assert 0.0 < unit_parameter_lists[1][0] < 1.0 assert 0.0 < unit_parameter_lists[0][1] < 1.0 assert 0.0 < unit_parameter_lists[1][1] < 1.0 assert 0.0 < unit_parameter_lists[0][2] < 1.0 assert 0.0 < unit_parameter_lists[1][2] < 1.0 assert 0.0 < unit_parameter_lists[0][3] < 1.0 assert 0.0 < unit_parameter_lists[1][3] < 1.0 assert 0.099 < parameter_lists[0][0] < 0.101 assert 0.099 < parameter_lists[1][0] < 0.101 assert 0.199 < parameter_lists[0][1] < 0.201 assert 0.199 < parameter_lists[1][1] < 0.201 assert 0.299 < parameter_lists[0][2] < 0.301 assert 0.299 < parameter_lists[1][2] < 0.301 assert 0.399 < parameter_lists[0][3] < 0.401 assert 0.399 < parameter_lists[1][3] < 0.401 assert figure_of_merit_list == [-1.0e99, -1.0e99]
def test__update_stellar_mass_priors_using_einstein_radius(self): grid = al.Grid2D.uniform(shape_native=(200, 200), pixel_scales=0.05) tracer = mock.MockTracer(einstein_radius=1.0, einstein_mass=4.0) fit = mock.MockFit(grid=grid) result = mock.MockResult(max_log_likelihood_tracer=tracer, max_log_likelihood_fit=fit) bulge_prior_model = af.PriorModel(al.lmp.SphericalSersic) bulge_prior_model.intensity = af.UniformPrior(lower_limit=0.99, upper_limit=1.01) bulge_prior_model.effective_radius = af.UniformPrior(lower_limit=0.99, upper_limit=1.01) bulge_prior_model.sersic_index = af.UniformPrior(lower_limit=2.99, upper_limit=3.01) setup = al.SetupMassLightDark(bulge_prior_model=bulge_prior_model) setup.update_stellar_mass_priors_from_result( prior_model=bulge_prior_model, result=result, einstein_mass_range=[0.001, 10.0], bins=10, ) assert setup.bulge_prior_model.mass_to_light_ratio.lower_limit == pytest.approx( 0.00040519, 1.0e-1) assert setup.bulge_prior_model.mass_to_light_ratio.upper_limit == pytest.approx( 4.051935, 1.0e-1)
def test__unfix_lens_mass_centre(self): mass = af.PriorModel(al.mp.SphericalIsothermal) mass.centre = (1.0, 2.0) source = al.slam.SLaMSource() mass = af.PriorModel(al.mp.SphericalIsothermal) source = al.slam.SLaMSource(lens_mass_centre=(5.0, 6.0)) mass = source.unfix_lens_mass_centre(mass=mass) assert mass.centre.centre_0.mean == 5.0 assert mass.centre.centre_0.sigma == 0.05 assert mass.centre.centre_1.mean == 6.0 assert mass.centre.centre_1.sigma == 0.05