def test_addition(self): phase_1 = DummyPhaseImaging() phase_2 = DummyPhaseImaging() phase_3 = DummyPhaseImaging() pipeline1 = pl.PipelineImaging("", phase_1, phase_2) pipeline2 = pl.PipelineImaging("", phase_3) assert (phase_1, phase_2, phase_3) == (pipeline1 + pipeline2).phases
def make_pipeline(test_name): class MMPhase(ph.LensPlanePhase): pass phase1 = MMPhase( lens_galaxies=dict(lens=gm.GalaxyModel(light=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name="{}/phase1".format(test_name)) phase1.optimizer.n_live_points = 20 phase1.optimizer.sampling_efficiency = 0.8 phase1.optimizer.importance_nested_sampling = False class MMPhase2(ph.LensPlanePhase): def pass_priors(self, previous_results): self.lens_galaxies = previous_results[0].variable.lens_galaxies phase2 = MMPhase2( lens_galaxies=dict(lens=gm.GalaxyModel(light=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name="{}/phase2".format(test_name)) phase2.optimizer.n_live_points = 20 phase2.optimizer.sampling_efficiency = 0.8 phase2.optimizer.importance_nested_sampling = False return pl.PipelineImaging(test_name, phase1, phase2)
def make_pipeline(test_name): phase1 = ph.LensSourcePlanePhase(lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal)), source_galaxies=dict(source_0=gm.GalaxyModel(sersic=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name="{}/phase1".format(test_name)) phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 60 phase1.optimizer.sampling_efficiency = 0.7 class AddSourceGalaxyPhase(ph.LensSourcePlanePhase): def pass_priors(self, previous_results): self.lens_galaxies_lens = previous_results[0].variable.lens self.source_galaxies_source_0 = previous_results[0].variable.source_0 phase2 = AddSourceGalaxyPhase(lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal)), source_galaxies=dict(source_0=gm.GalaxyModel(sersic=lp.EllipticalSersic), source_1=gm.GalaxyModel(sersic=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name="{}/phase2".format(test_name)) phase2.optimizer.const_efficiency_mode = True phase2.optimizer.n_live_points = 60 phase2.optimizer.sampling_efficiency = 0.7 return pl.PipelineImaging(test_name, phase1, phase2)
def make_pipeline(test_name): class SensitivePhase(ph.SensitivityPhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.mass.centre_0 = 0.0 self.lens_galaxies.lens.mass.centre_1 = 0.0 self.lens_galaxies.lens.mass.einstein_radius = 1.6 self.source_galaxies.source.light.centre_0 = 0.0 self.source_galaxies.source.light.centre_1 = 0.0 self.source_galaxies.source.light.intensity = 1.0 self.source_galaxies.source.light.effective_radius = 0.5 self.source_galaxies.source.light.sersic_index = 1.0 self.sensitive_galaxies.subhalo.mass.centre_0 = prior.GaussianPrior( mean=0.0, sigma=1.0) self.sensitive_galaxies.subhalo.mass.centre_1 = prior.GaussianPrior( mean=0.0, sigma=1.0) self.sensitive_galaxies.subhalo.mass.kappa_s = 0.1 self.sensitive_galaxies.subhalo.mass.scale_radius = 5.0 phase1 = SensitivePhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.SphericalIsothermal)), source_galaxies=dict(source=gm.GalaxyModel(light=lp.SphericalSersic)), sensitive_galaxies=dict(subhalo=gm.GalaxyModel(mass=mp.SphericalNFW)), optimizer_class=nl.MultiNest, phase_name="{}/phase1".format(test_name)) phase1.optimizer.const_efficiency_mode = True return pl.PipelineImaging(test_name, phase1)
def make_pipeline(test_name): phase1 = ph.LensPlanePhase(lens_galaxies=[gm.GalaxyModel(sersic=lp.EllipticalSersic)], optimizer_class=nl.MultiNest, phase_name="{}/phase1".format(test_name)) phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 40 phase1.optimizer.sampling_efficiency = 0.8 phase1h = ph.LensLightHyperOnlyPhase(optimizer_class=nl.MultiNest, phase_name="{}/phase1h".format(test_name)) class LensHyperPhase(ph.LensPlaneHyperPhase): def pass_priors(self, previous_results): phase1_results = previous_results[-1] phase1h_results = previous_results[-1].hyper self.lens_galaxies = phase1_results.variable.lens_galaxies self.lens_galaxies[0].hyper_galaxy = phase1h_results.constant.lens_galaxies[0].hyper_galaxy phase2 = LensHyperPhase(lens_galaxies=[], optimizer_class=nl.MultiNest, phase_name="{}/phase2".format(test_name)) phase2.optimizer.const_efficiency_mode = True phase2.optimizer.n_live_points = 40 phase2.optimizer.sampling_efficiency = 0.8 return pl.PipelineImaging(test_name, phase1, phase1h, phase2)
def make_pipeline(test_name): class SensitivePhase(ph.SensitivityPhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.mass.centre_0 = 0.0 self.lens_galaxies.lens.mass.centre_1 = 0.0 self.lens_galaxies.lens.mass.einstein_radius = 1.6 self.source_galaxies.source.light.centre_0 = 0.0 self.source_galaxies.source.light.centre_1 = 0.0 self.source_galaxies.source.light.intensity = 1.0 self.source_galaxies.source.light.effective_radius = 0.5 self.source_galaxies.source.light.sersic_index = 1.0 self.sensitive_galaxies.subhalo.mass.centre_0 = prior.UniformPrior( lower_limit=-2.0, upper_limit=2.0) self.sensitive_galaxies.subhalo.mass.centre_1 = prior.UniformPrior( lower_limit=-2.0, upper_limit=2.0) self.sensitive_galaxies.subhalo.mass.kappa_s = 0.1 self.sensitive_galaxies.subhalo.mass.scale_radius = 5.0 phase1 = SensitivePhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.SphericalIsothermal)), source_galaxies=dict(source=gm.GalaxyModel(light=lp.SphericalSersic)), sensitive_galaxies=dict(subhalo=gm.GalaxyModel(mass=mp.SphericalNFW)), optimizer_class=nl.GridSearch, phase_name="{}/phase1".format(test_name)) return pl.PipelineImaging(test_name, phase1)
def make_pipeline(test_name): class LensPlanex2GalPhase(ph.LensPlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens_0.light.centre_0 = -1.0 self.lens_galaxies.lens_0.light.centre_1 = -1.0 self.lens_galaxies.lens_1.light.centre_0 = 1.0 self.lens_galaxies.lens_1.light.centre_1 = 1.0 def mask_function(image): return msk.Mask.circular(shape=image.shape, pixel_scale=image.pixel_scale, radius_arcsec=5.) phase1 = LensPlanex2GalPhase(lens_galaxies=dict( lens_0=gm.GalaxyModel(light=lp.EllipticalSersic), lens_1=gm.GalaxyModel(light=lp.EllipticalSersic)), mask_function=mask_function, optimizer_class=nl.MultiNest, phase_name="{}/phase1".format(test_name)) phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 40 phase1.optimizer.sampling_efficiency = 0.8 return pl.PipelineImaging(test_name, phase1)
def make_pipeline(test_name): class SensitivePhase(ph.SensitivityPhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.mass.centre_0 = 0.0 self.lens_galaxies.lens.mass.centre_1 = 0.0 self.lens_galaxies.lens.mass.einstein_radius = 1.6 self.source_galaxies.source.pixelization.shape_0 = 8.0 self.source_galaxies.source.pixelization.shape_1 = 8.0 self.source_galaxies.source.regularization.coefficients_0 = 1.0 self.sensitive_galaxies.subhalo.mass.centre_0 = prior.GaussianPrior( mean=0.0, sigma=1.0) self.sensitive_galaxies.subhalo.mass.centre_1 = prior.GaussianPrior( mean=0.0, sigma=1.0) self.sensitive_galaxies.subhalo.mass.kappa_s = 0.1 self.sensitive_galaxies.subhalo.mass.scale_radius = 5.0 phase1 = SensitivePhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.SphericalIsothermal)), source_galaxies=dict(source=gm.GalaxyModel( pixelization=pix.Rectangular, regularization=reg.Constant)), sensitive_galaxies=dict(subhalo=gm.GalaxyModel(mass=mp.SphericalNFW)), optimizer_class=nl.MultiNest, phase_name="{}/phase1".format(test_name)) phase1.optimizer.const_efficiency_mode = True return pl.PipelineImaging(test_name, phase1)
def make_pipeline(test_name): class MMPhase(ph.LensPlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.light.centre_0 = 1.0 self.lens_galaxies.lens.light.centre_1 = 2.0 phase1 = MMPhase( lens_galaxies=dict(lens=gm.GalaxyModel(light=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name="{}/phase1".format(test_name)) phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 20 phase1.optimizer.sampling_efficiency = 0.8 class MMPhase2(ph.LensPlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.light.centre_0 = previous_results[ 0].variable.lens.light.centre_0 self.lens_galaxies.lens.light.centre_1 = previous_results[ 0].variable.lens.light.centre_1 phase2 = MMPhase2( lens_galaxies=dict(lens=gm.GalaxyModel(light=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name="{}/phase2".format(test_name)) phase2.optimizer.const_efficiency_mode = True phase2.optimizer.n_live_points = 20 phase2.optimizer.sampling_efficiency = 0.8 return pl.PipelineImaging(test_name, phase1, phase2)
def test_run_pipeline(self): phase_1 = DummyPhaseImaging() phase_2 = DummyPhaseImaging() pipeline = pl.PipelineImaging("", phase_1, phase_2) pipeline.run(None) assert len(phase_1.previous_results) == 0 assert len(phase_2.previous_results) == 1
def test_pass_positions(self): positions = [[[1.0, 1.0], [2.0, 2.0]]] phase_1 = DummyPhaseImaging() phase_2 = DummyPhaseImaging() pipeline = pl.PipelineImaging("", phase_1, phase_2) pipeline.run(data=None, positions=positions) assert phase_1.positions == positions assert phase_2.positions == positions
def test_pass_mask(self): mask = MockMask() phase_1 = DummyPhaseImaging() phase_2 = DummyPhaseImaging() pipeline = pl.PipelineImaging("", phase_1, phase_2) pipeline.run(data=None, mask=mask) assert phase_1.mask is mask assert phase_2.mask is mask
def make_pipeline(test_name): phase1 = ph.LensPlanePhase( lens_galaxies=dict(lens=gm.GalaxyModel(sersic=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name="{}/phase1".format(test_name)) phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 40 phase1.optimizer.sampling_efficiency = 0.8 return pl.PipelineImaging(test_name, phase1)
def make_pipeline(test_name): class QuickPhase(ph.LensPlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.light.centre_0 = prior.UniformPrior( lower_limit=-0.01, upper_limit=0.01) self.lens_galaxies.lens.light.centre_1 = prior.UniformPrior( lower_limit=-0.01, upper_limit=0.01) self.lens_galaxies.lens.light.axis_ratio = prior.UniformPrior( lower_limit=0.79, upper_limit=0.81) self.lens_galaxies.lens.light.phi = prior.UniformPrior( lower_limit=-1.0, upper_limit=1.0) self.lens_galaxies.lens.light.intensity = prior.UniformPrior( lower_limit=0.99, upper_limit=1.01) self.lens_galaxies.lens.light.effective_radius = prior.UniformPrior( lower_limit=1.25, upper_limit=1.35) self.lens_galaxies.lens.light.sersic_index = prior.UniformPrior( lower_limit=3.95, upper_limit=4.05) phase1 = QuickPhase( lens_galaxies=dict(lens=gm.GalaxyModel(light=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name="{}/phase1".format(test_name)) phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 40 phase1.optimizer.sampling_efficiency = 0.8 class GridPhase(ph.LensPlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.light.centre_0 = 0.0 self.lens_galaxies.lens.light.centre_1 = 0.0 self.lens_galaxies.lens.light.axis_ratio = previous_results[ 0].constant.lens.light.axis_ratio self.lens_galaxies.lens.light.phi = previous_results[ 0].constant.lens.light.phi self.lens_galaxies.lens.light.intensity = previous_results[ 0].constant.lens.light.intensity self.lens_galaxies.lens.light.effective_radius = prior.UniformPrior( lower_limit=0.0, upper_limit=4.0) self.lens_galaxies.lens.light.sersic_index = prior.UniformPrior( lower_limit=1.0, upper_limit=8.0) phase2 = GridPhase( lens_galaxies=dict(lens=gm.GalaxyModel(light=lp.EllipticalSersic)), optimizer_class=nl.GridSearch, phase_name=test_type + '/phase2') phase2.optimizer.const_efficiency_mode = True return pl.PipelineImaging(test_name, phase1, phase2)
def make_pipeline(test_name): phase1 = ph.LensSourcePlanePhase( lens_galaxies=dict(lens=gm.GalaxyModel( light=lp.SphericalDevVaucouleurs, mass=mp.EllipticalIsothermal)), source_galaxies=dict(source=gm.GalaxyModel(light=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name="{}/phase1".format(test_name)) phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 60 phase1.optimizer.sampling_efficiency = 0.8 return pl.PipelineImaging(test_name, phase1)
def make_pipeline(test_name): class MMPhase(ph.LensPlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.light.intensity = self.lens_galaxies.lens.mass.einstein_radius phase1 = MMPhase(lens_galaxies=dict(lens=gm.GalaxyModel( light=lp.EllipticalSersic, mass=mp.SphericalIsothermal)), optimizer_class=nl.MultiNest, phase_name="{}/phase1".format(test_name)) phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 20 phase1.optimizer.sampling_efficiency = 0.8 return pl.PipelineImaging(test_name, phase1)
def make_pipeline(test_name): class MMPhase(ph.LensPlanePhase): pass phase1 = MMPhase( lens_galaxies=dict(lens=gm.GalaxyModel(light_0=lp.EllipticalSersic, light_1=lp.EllipticalSersic, mass=mp.EllipticalIsothermal, align_orientations=True)), optimizer_class=nl.MultiNest, phase_name="{}/phase1".format(test_name)) phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 20 phase1.optimizer.sampling_efficiency = 0.8 return pl.PipelineImaging(test_name, phase1)
def make_pipeline(pipeline_name): # This is the same phase 1 as the complex source pipeline, which we saw gave a good fit to the overall # structure of the lensed source and provided an accurate lens mass model. phase1 = ph.LensSourcePlanePhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal)), source_galaxies=dict(source=gm.GalaxyModel(light=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name=pipeline_name + '/phase_1_initialize') phase1.optimizer.sampling_efficiency = 0.3 phase1.optimizer.const_efficiency_mode = True # Now, in phase 2, lets use the lens mass model to fit the source with an inversion. class InversionPhase(ph.LensSourcePlanePhase): def pass_priors(self, previous_results): # We can customize the inversion's priors like we do our light and mass profiles. self.lens_galaxies.lens = previous_results[0].variable.lens self.source_galaxies.source.pixelization.shape_0 = mm.UniformPrior( lower_limit=20.0, upper_limit=40.0) self.source_galaxies.source.pixelization.shape_1 = mm.UniformPrior( lower_limit=20.0, upper_limit=40.0) # The expected value of the regularization coefficient depends on the details of the data reduction and # source galaxy. A broad log-uniform prior is thus an appropriate way to sample the large range of # possible values. self.source_galaxies.source.regularization.coefficients_0 = mm.LogUniformPrior( lower_limit=1.0e-6, upper_limit=10000.0) phase2 = InversionPhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal)), source_galaxies=dict(source=gm.GalaxyModel( pixelization=pix.Rectangular, regularization=reg.Constant)), optimizer_class=nl.MultiNest, phase_name=pipeline_name + '/phase_2_inversion') phase2.optimizer.sampling_efficiency = 0.3 phase2.optimizer.const_efficiency_mode = True return pipeline.PipelineImaging(pipeline_name, phase1, phase2)
def make_pipeline(test_name): class MMPhase(ph.LensPlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.light.axis_ratio = 0.2 self.lens_galaxies.lens.light.phi = 90.0 self.lens_galaxies.lens.light.intensity = 1.0 self.lens_galaxies.lens.light.effective_radius = 1.3 self.lens_galaxies.lens.light.sersic_index = 3.0 phase1 = MMPhase( lens_galaxies=dict(lens=gm.GalaxyModel(light=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name="{}/phase1".format(test_name)) phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 20 phase1.optimizer.sampling_efficiency = 0.8 return pl.PipelineImaging(test_name, phase1)
def make_pipeline(test_name): class MMPhase(ph.LensPlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.sersic.centre_0 = 0.0 self.lens_galaxies.lens.sersic.centre_1 = 0.0 self.lens_galaxies.lens.sersic.axis_ratio = prior.UniformPrior( lower_limit=-0.5, upper_limit=0.1) self.lens_galaxies.lens.sersic.phi = 90.0 self.lens_galaxies.lens.sersic.intensity = prior.UniformPrior( lower_limit=-0.5, upper_limit=0.1) self.lens_galaxies.lens.sersic.effective_radius = 1.3 self.lens_galaxies.lens.sersic.sersic_index = 3.0 phase1 = MMPhase( lens_galaxies=dict(lens=gm.GalaxyModel(sersic=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name="{}/phase1".format(test_name)) phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 20 phase1.optimizer.sampling_efficiency = 0.8 class MMPhase(ph.LensPlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.sersic.intensity = previous_results[ 0].variable.lens.sersic.intensity self.lens_galaxies.lens = previous_results[0].variable.lens phase2 = MMPhase( lens_galaxies=dict(lens=gm.GalaxyModel(sersic=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name="{}/phase2".format(test_name)) phase2.optimizer.const_efficiency_mode = True phase2.optimizer.n_live_points = 20 phase2.optimizer.sampling_efficiency = 0.8 return pl.PipelineImaging(test_name, phase1, phase2)
def make_pipeline(test_name): class SourcePix(ph.LensSourcePlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.mass.centre.centre_0 = 0.0 self.lens_galaxies.lens.mass.centre.centre_1 = 0.0 self.lens_galaxies.lens.mass.einstein_radius = 1.6 self.source_galaxies.source.pixelization.shape_0 = 20.0 self.source_galaxies.source.pixelization.shape_1 = 20.0 phase1 = SourcePix( lens_galaxies=dict(lens=gm.GalaxyModel(sie=mp.EllipticalIsothermal)), source_galaxies=dict(source=gm.GalaxyModel( pixelization=pix.Rectangular, regularization=reg.Constant)), optimizer_class=nl.MultiNest, phase_name="{}/phase1".format(test_name)) phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 60 phase1.optimizer.sampling_efficiency = 0.8 return pl.PipelineImaging(test_name, phase1)
def make_pipeline(test_name): phase1 = ph.LensSourcePlanePhase( lens_galaxies=[gm.GalaxyModel(sie=mp.EllipticalIsothermal)], source_galaxies=[gm.GalaxyModel(sersic=lp.EllipticalSersic)], optimizer_class=nl.MultiNest, phase_name="{}/phase1".format(test_name)) phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 60 phase1.optimizer.sampling_efficiency = 0.8 phase1h = ph.LensMassAndSourceProfileHyperOnlyPhase( optimizer_class=nl.MultiNest, phase_name="{}/phase1h".format(test_name)) class SourceHyperPhase(ph.LensSourcePlaneHyperPhase): def pass_priors(self, previous_results): phase1_results = previous_results[-1] phase1h_results = previous_results[-1].hyper # self.lens_galaxies[0] = previous_results[-1].variable.lens_galaxies[0] self.source_galaxies = phase1_results.variable.source_galaxies self.source_galaxies[ 0].hyper_galaxy = phase1h_results.constant.source_galaxies[ 0].hyper_galaxy phase2 = SourceHyperPhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal)), source_galaxies=dict(source=gm.GalaxyModel(light=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name="{}/phase2".format(test_name)) phase2.optimizer.const_efficiency_mode = True phase2.optimizer.n_live_points = 40 phase2.optimizer.sampling_efficiency = 0.8 return pl.PipelineImaging(test_name, phase1, phase1h, phase2)
def make_pipeline(test_name): class QuickPhase(ph.LensPlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.bulge.centre_0 = prior.UniformPrior( lower_limit=-0.01, upper_limit=0.01) self.lens_galaxies.lens.bulge.centre_1 = prior.UniformPrior( lower_limit=-0.01, upper_limit=0.01) self.lens_galaxies.lens.bulge.axis_ratio = prior.UniformPrior( lower_limit=0.79, upper_limit=0.81) self.lens_galaxies.lens.bulge.phi = prior.UniformPrior( lower_limit=-1.0, upper_limit=1.0) self.lens_galaxies.lens.bulge.intensity = prior.UniformPrior( lower_limit=0.99, upper_limit=1.01) self.lens_galaxies.lens.bulge.effective_radius = prior.UniformPrior( lower_limit=1.25, upper_limit=1.35) self.lens_galaxies.lens.bulge.sersic_index = prior.UniformPrior( lower_limit=3.95, upper_limit=4.05) self.lens_galaxies.lens.disk.centre_0 = prior.UniformPrior( lower_limit=-0.01, upper_limit=0.01) self.lens_galaxies.lens.disk.centre_1 = prior.UniformPrior( lower_limit=-0.01, upper_limit=0.01) self.lens_galaxies.lens.disk.axis_ratio = prior.UniformPrior( lower_limit=0.69, upper_limit=0.71) self.lens_galaxies.lens.disk.phi = prior.UniformPrior( lower_limit=-1.0, upper_limit=1.0) self.lens_galaxies.lens.disk.intensity = prior.UniformPrior( lower_limit=1.99, upper_limit=2.01) self.lens_galaxies.lens.disk.effective_radius = prior.UniformPrior( lower_limit=1.95, upper_limit=2.05) phase1 = QuickPhase(lens_galaxies=dict(lens=gm.GalaxyModel( bulge=lp.EllipticalSersic, disk=lp.EllipticalExponential)), optimizer_class=nl.MultiNest, phase_name="{}/phase1".format(test_name)) phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 40 phase1.optimizer.sampling_efficiency = 0.8 class GridPhase(autofit_ph.as_grid_search(ph.LensPlanePhase)): @property def grid_priors(self): return [self.variable.lens.bulge.sersic_index] def pass_priors(self, previous_results): self.lens_galaxies.lens.disk = previous_results[ 0].constant.lens.disk self.lens_galaxies.lens.bulge.centre_0 = prior.UniformPrior( lower_limit=-0.01, upper_limit=0.01) self.lens_galaxies.lens.bulge.centre_1 = prior.UniformPrior( lower_limit=-0.01, upper_limit=0.01) self.lens_galaxies.lens.bulge.axis_ratio = prior.UniformPrior( lower_limit=0.79, upper_limit=0.81) self.lens_galaxies.lens.bulge.phi = prior.UniformPrior( lower_limit=-1.0, upper_limit=1.0) self.lens_galaxies.lens.bulge.intensity = prior.UniformPrior( lower_limit=0.99, upper_limit=1.01) self.lens_galaxies.lens.bulge.effective_radius = prior.UniformPrior( lower_limit=1.25, upper_limit=1.35) phase2 = GridPhase(lens_galaxies=dict(lens=gm.GalaxyModel( bulge=lp.EllipticalSersic, disk=lp.EllipticalExponential)), number_of_steps=2, optimizer_class=nl.MultiNest, phase_name=test_name + '/phase2') phase2.optimizer.const_efficiency_mode = True return pl.PipelineImaging(test_name, phase1, phase2)
def make_pipeline(pipeline_path): pipeline_name = 'pipeline_lens_light_and_x1_source_parametric' pipeline_path = pipeline_path + pipeline_name ### PHASE 1 ### # In phase 1, we will fit only the lens galaxy's light, where we: # 1) Set our priors on the lens galaxy (y,x) centre such that we assume the image is centred around the lens galaxy. # 2) Use a circular mask which therefore also includes the source's light. # Whereas in the howtolens tutorial I used an anti-annular mask in this phase to remove the source galaxy, here I # use the default 3.0" circular mask. In general, I haven't found the choice of mask to make a big difference, # albeit this does depend on how much off the lens galaxy's light the lensed source galaxy's light obstructs. class LensPhase(ph.LensPlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.light.centre_0 = mm.GaussianPrior(mean=0.0, sigma=0.1) self.lens_galaxies.lens.light.centre_1 = mm.GaussianPrior(mean=0.0, sigma=0.1) phase1 = LensPhase(lens_galaxies=dict(lens=gm.GalaxyModel(light=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name=pipeline_path + '/phase_1_lens_light_only') # You'll see these lines throughout all of the example pipelines. They are used to make MultiNest sample the \ # non-linear parameter space faster (if you haven't already, checkout 'tutorial_7_multinest_black_magic' in # 'howtolens/chapter_2_lens_modeling'. phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 30 phase1.optimizer.sampling_efficiency = 0.3 ### PHASE 2 ### # In phase 2, we will fit the lens galaxy's mass and source galaxy's light, where we: # 1) Use a lens-subtracted image generated by subtracting model lens galaxy image from phase 1. # 2) Use a circular annular mask to only include the source-galaxy. # 3) Initialize the priors on the centre of the lens galaxy's mass-profile by linking them to those inferred for \ # its light profile in phase 1. def mask_function(image): return msk.Mask.circular_annular(shape=image.shape, pixel_scale=image.pixel_scale, inner_radius_arcsec=0.3, outer_radius_arcsec=3.0) class LensSubtractedPhase(ph.LensSourcePlanePhase): def modify_image(self, image, previous_results): return image - previous_results[-1].unmasked_model_image def pass_priors(self, previous_results): self.lens_galaxies.lens.mass.centre_0 = previous_results[0].variable.lens.light.centre_0 self.lens_galaxies.lens.mass.centre_1 = previous_results[0].variable.lens.light.centre_1 phase2 = LensSubtractedPhase(lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal, shear=mp.ExternalShear)), source_galaxies=dict(source=gm.GalaxyModel(light=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, mask_function=mask_function, phase_name=pipeline_path + '/phase_2_source_only') phase2.optimizer.const_efficiency_mode = True phase2.optimizer.n_live_points = 60 phase2.optimizer.sampling_efficiency = 0.2 ### PHASE 3 ### # In phase 3, we will fit simultaneously the lens and source galaxies, where we: # 1) Initialize the lens's light, mass, shear and source's light using the results of phases 1 and 2. class LensSourcePhase(ph.LensSourcePlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.light = previous_results[0].variable.lens.light self.lens_galaxies.lens.mass = previous_results[1].variable.lens.mass self.lens_galaxies.lens.shear = previous_results[1].variable.lens.shear self.source_galaxies.source = previous_results[1].variable.source phase3 = LensSourcePhase(lens_galaxies=dict(lens=gm.GalaxyModel(light=lp.EllipticalSersic, mass=mp.EllipticalIsothermal, shear=mp.ExternalShear)), source_galaxies=dict(source=gm.GalaxyModel(light=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name=pipeline_path + '/phase_3_both') phase3.optimizer.const_efficiency_mode = True phase3.optimizer.n_live_points = 75 phase3.optimizer.sampling_efficiency = 0.3 return pipeline.PipelineImaging(pipeline_path, phase1, phase2, phase3)
def make_pipeline(pipeline_path=''): pipeline_name = 'pipeline_complex_source' pipeline_path = pipeline_path + pipeline_name # To begin, we need to initialize the lens's mass model. We should be able to do this by using a simple source # model. It won't fit the complicated structure of the source, but it'll give us a reasonable estimate of the # einstein radius and the other lens-mass parameters. # This should run fine without any prior-passes. In general, a thick, giant ring of source light is something we # can be confident MultiNest will fit without much issue, especially when the lens galaxy's light isn't included # such that the parameter space is just 12 parameters. phase1 = ph.LensSourcePlanePhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal)), source_galaxies=dict(source=gm.GalaxyModel( light_0=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name=pipeline_path + '/phase_1_simple_source') phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 40 phase1.optimizer.sampling_efficiency = 0.5 # Now lets add another source component, using the previous model as the initialization on the lens / source # parameters. We'll vary the parameters of the lens mass model and first source galaxy component during the fit. class X2SourcePhase(ph.LensSourcePlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens = previous_results[0].variable.lens self.source_galaxies.source.light_0 = previous_results[ 0].variable.source.light_0 # You'll notice I've stop writing 'phase_1_results = previous_results[0]' - we know how # the previous results are structured now so lets not clutter our code! phase2 = X2SourcePhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal)), source_galaxies=dict(source=gm.GalaxyModel( light_0=lp.EllipticalExponential, light_1=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name=pipeline_path + '/phase_2_x2_source') phase2.optimizer.const_efficiency_mode = True phase2.optimizer.n_live_points = 40 phase2.optimizer.sampling_efficiency = 0.5 # Now lets do the same again, but with 3 source galaxy components. class X3SourcePhase(ph.LensSourcePlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens = previous_results[1].variable.lens self.source_galaxies.source.light_0 = previous_results[ 1].variable.source.light_0 self.source_galaxies.source.light_1 = previous_results[ 1].variable.source.light_1 phase3 = X3SourcePhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal)), source_galaxies=dict( source=gm.GalaxyModel(light_0=lp.EllipticalExponential, light_1=lp.EllipticalSersic, light_2=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name=pipeline_path + '/phase_3_x3_source') phase3.optimizer.const_efficiency_mode = True phase3.optimizer.n_live_points = 50 phase3.optimizer.sampling_efficiency = 0.5 # And one more for luck! class X4SourcePhase(ph.LensSourcePlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens = previous_results[2].variable.lens self.source_galaxies.source.light_0 = previous_results[ 2].variable.source.light_0 self.source_galaxies.source.light_1 = previous_results[ 2].variable.source.light_1 self.source_galaxies.source.light_2 = previous_results[ 2].variable.source.light_2 phase4 = X4SourcePhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal)), source_galaxies=dict( source=gm.GalaxyModel(light_0=lp.EllipticalExponential, light_1=lp.EllipticalSersic, light_2=lp.EllipticalSersic, light_3=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name=pipeline_path + '/phase_4_x4_source') phase4.optimizer.const_efficiency_mode = True phase4.optimizer.n_live_points = 50 phase4.optimizer.sampling_efficiency = 0.5 return pipeline.PipelineImaging(pipeline_path, phase1, phase2, phase3, phase4)
def make_pipeline(pipeline_path=''): pipeline_name = 'pipeline_multi_plane' pipeline_path = pipeline_path + pipeline_name # In phase 1, we will: # 1) Subtract the light of the main lens galaxy (located at (0.0", 0.0")) and the light of each line-of-sight # galaxy (located at (4.0", 4.0"), (3.6", -5.3") and (-3.1", -2.4")) class LensPhase(ph.LensPlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.light.centre_0 = prior.GaussianPrior( mean=0.0, sigma=0.1) self.lens_galaxies.lens.light.centre_1 = prior.GaussianPrior( mean=0.0, sigma=0.1) self.lens_galaxies.los0.light.centre_0 = prior.GaussianPrior( mean=4.0, sigma=0.1) self.lens_galaxies.los0.light.centre_1 = prior.GaussianPrior( mean=4.0, sigma=0.1) self.lens_galaxies.los1.light.centre_0 = prior.GaussianPrior( mean=3.6, sigma=0.1) self.lens_galaxies.los1.light.centre_1 = prior.GaussianPrior( mean=-5.3, sigma=0.1) self.lens_galaxies.los2.light.centre_0 = prior.GaussianPrior( mean=-3.1, sigma=0.1) self.lens_galaxies.los2.light.centre_1 = prior.GaussianPrior( mean=-2.4, sigma=0.1) phase1 = LensPhase(lens_galaxies=dict( lens=gm.GalaxyModel(light=lp.EllipticalSersic), los_0=gm.GalaxyModel(light=lp.SphericalSersic), los_1=gm.GalaxyModel(light=lp.SphericalSersic), los_2=gm.GalaxyModel(light=lp.SphericalSersic)), optimizer_class=nl.MultiNest, phase_name=pipeline_path + '/phase_1_light_subtraction') # Customize MultiNest so it runs fast phase1.optimizer.n_live_points = 80 phase1.optimizer.sampling_efficiency = 0.2 phase1.optimizer.const_efficiency_mode = True # In phase 2, we will: # 1) Fit this foreground subtracted image, using an SIE+Shear mass model and Sersic source. # 2) Use the input positions to resample inaccurate mass models. class LensSubtractedPhase(ph.LensSourcePlanePhase): def modify_image(self, image, previous_results): return image - previous_results[0].unmasked_lens_plane_model_image def pass_priors(self, previous_results): self.lens_galaxies.lens.mass.centre_0 = prior.GaussianPrior( mean=0.0, sigma=0.1) self.lens_galaxies.lens.mass.centre_1 = prior.GaussianPrior( mean=0.0, sigma=0.1) phase2 = LensSubtractedPhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal)), source_galaxies=dict(source=gm.GalaxyModel(light=lp.EllipticalSersic)), use_positions=True, optimizer_class=nl.MultiNest, phase_name=pipeline_path + '/phase_2_source_parametric') phase2.optimizer.n_live_points = 50 phase2.optimizer.sampling_efficiency = 0.2 phase2.optimizer.const_efficiency_mode = True # In phase 3, we will: # 1) Fit the foreground subtracted image using a source-inversion instead of parametric source, using lens galaxy # priors from phase 2. class InversionPhase(ph.LensSourcePlanePhase): def modify_image(self, image, previous_results): return image - previous_results[0].unmasked_lens_plane_model_image def pass_priors(self, previous_results): self.lens_galaxies.lens = previous_results[1].constant.lens self.source_galaxies.source.pixelization.shape_0 = prior.UniformPrior( lower_limit=20.0, upper_limit=45.0) self.source_galaxies.source.pixelization.shape_1 = prior.UniformPrior( lower_limit=20.0, upper_limit=45.0) phase3 = InversionPhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal)), source_galaxies=dict( source=gm.GalaxyModel(pixelization=pix.AdaptiveMagnification, regularization=reg.Constant)), optimizer_class=nl.MultiNest, phase_name=pipeline_path + '/phase_3_inversion_init') # Customize MultiNest so it runs fast phase3.optimizer.n_live_points = 10 phase3.optimizer.sampling_efficiency = 0.5 phase3.optimizer.const_efficiency_mode = True # In phase 4, we will: # 1) Fit the foreground subtracted image using a source-inversion with parameters initialized from phase 3. # 2) Initialize the lens galaxy priors using the results of phase 2, and include each line-of-sight galaxy's mass # contribution (keeping its centre fixed to the light profile centred inferred in phase 1). This will assume # a single lens plane for all line-of-sight galaxies. # 3) Use the input positions to resample inaccurate mass models. class SingleLensPlanePhase(ph.LensSourcePlanePhase): def modify_image(self, image, previous_results): return image - previous_results[0].unmasked_lens_plane_model_image def pass_priors(self, previous_results): self.lens_galaxies.lens.mass = previous_results[ 2].variable.lens.mass self.lens_galaxies.los_0.mass.centre_0 = previous_results[ 0].constant.los_0.light.centre_0 self.lens_galaxies.los_0.mass.centre_1 = previous_results[ 0].constant.los_0.light.centre_1 self.lens_galaxies.los_1.mass.centre_0 = previous_results[ 0].constant.los_1.light.centre_0 self.lens_galaxies.los_1.mass.centre_1 = previous_results[ 0].constant.los_1.light.centre_1 self.lens_galaxies.los_2.mass.centre_0 = previous_results[ 0].constant.los_2.light.centre_0 self.lens_galaxies.los_2.mass.centre_1 = previous_results[ 0].constant.los_2.light.centre_1 self.source_galaxies.source = previous_results[2].variable.source phase4 = SingleLensPlanePhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal), los_0=gm.GalaxyModel(mass=mp.SphericalIsothermal), los_1=gm.GalaxyModel(mass=mp.SphericalIsothermal), los_2=gm.GalaxyModel(mass=mp.SphericalIsothermal)), source_galaxies=dict( source=gm.GalaxyModel(pixelization=pix.AdaptiveMagnification, regularization=reg.Constant)), use_positions=True, optimizer_class=nl.MultiNest, phase_name=pipeline_path + '/phase_4_single_plane') # Customize MultiNest so it runs fast phase4.optimizer.n_live_points = 60 phase4.optimizer.sampling_efficiency = 0.2 phase4.optimizer.const_efficiency_mode = True # In phase 5, we will fit the foreground subtracted image using a multi-plane ray tracer. This means that the # redshift of each line-of-sight galaxy is included as a free parameter (we assume the lens and source redshifts # are known). class MultiPlanePhase(ph.MultiPlanePhase): def modify_image(self, image, previous_results): return image - previous_results[0].unmasked_lens_plane_model_image def pass_priors(self, previous_results): self.galaxies.lens = previous_results[3].variable.lens self.galaxies.los_0.mass = previous_results[3].variable.los_0.mass self.galaxies.los_1.mass = previous_results[3].variable.los_1.mass self.galaxies.los_2.mass = previous_results[3].variable.los_2.mass self.galaxies.source = previous_results[3].variable.source phase5 = MultiPlanePhase(galaxies=dict( lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal), los_0=gm.GalaxyModel(mass=mp.SphericalIsothermal, variable_redshift=True), los_1=gm.GalaxyModel(mass=mp.SphericalIsothermal, variable_redshift=True), los_2=gm.GalaxyModel(mass=mp.SphericalIsothermal, variable_redshift=True), source=gm.GalaxyModel(pixelization=pix.AdaptiveMagnification, regularization=reg.Constant)), use_positions=True, optimizer_class=nl.MultiNest, phase_name=pipeline_path + '/phase_5_multi_plane') # Customize MultiNest so it runs fast phase5.optimizer.n_live_points = 60 phase5.optimizer.sampling_efficiency = 0.2 phase5.optimizer.const_efficiency_mode = True return pipeline.PipelineImaging(pipeline_path, phase1, phase2, phase3, phase4, phase5)
def make_pipeline(pipeline_path=''): pipeline_name = 'pipeline_light_and_source_inversion' pipeline_path = pipeline_path + pipeline_name # We will switch between a circular mask which includes the lens light and an annular mask which removes it. def mask_function_circular(image): return msk.Mask.circular(shape=image.shape, pixel_scale=image.pixel_scale, radius_arcsec=3.0) def mask_function_annular(image): return msk.Mask.circular_annular(shape=image.shape, pixel_scale=image.pixel_scale, inner_radius_arcsec=0.3, outer_radius_arcsec=3.0) ### PHASE 1 ### # In phase 1, we will fit only the lens galaxy's light, where we: # 1) Set our priors on the lens galaxy (y,x) centre such that we assume the image is centred around the lens galaxy. # 2) Use a circular mask which includes the lens and source galaxy light. class LensPhase(ph.LensPlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.light.centre_0 = prior.GaussianPrior( mean=0.0, sigma=0.1) self.lens_galaxies.lens.light.centre_1 = prior.GaussianPrior( mean=0.0, sigma=0.1) phase1 = LensPhase( lens_galaxies=dict(lens=gm.GalaxyModel(light=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, mask_function=mask_function_circular, phase_name=pipeline_path + '/phase_1_lens_light_only') # You'll see these lines throughout all of the example pipelines. They are used to make MultiNest sample the \ # non-linear parameter space faster (if you haven't already, checkout the tutorial '' in howtolens/chapter_2). phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 30 phase1.optimizer.sampling_efficiency = 0.3 ### PHASE 2 ### # In phase 2, we will fit the lens galaxy's mass and source galaxy's light, where we: # 1) Use a lens-subtracted image generated by subtracting model lens galaxy image from phase 1. # 2) Use a circular annular mask which includes only the source-galaxy light. # 3) Initialize the priors on the centre of the lens galaxy's mass-profile by linking them to those inferred for \ # its light profile in phase 1. class LensSubtractedPhase(ph.LensSourcePlanePhase): def modify_image(self, image, previous_results): return image - previous_results[0].unmasked_lens_plane_model_image def pass_priors(self, previous_results): self.lens_galaxies.lens.mass.centre_0 = previous_results[ 0].variable.lens.light.centre_0 self.lens_galaxies.lens.mass.centre_1 = previous_results[ 0].variable.lens.light.centre_1 phase2 = LensSubtractedPhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal, shear=mp.ExternalShear)), source_galaxies=dict(source=gm.GalaxyModel(light=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, mask_function=mask_function_annular, phase_name=pipeline_path + '/phase_2_source_only') phase2.optimizer.const_efficiency_mode = True phase2.optimizer.n_live_points = 60 phase2.optimizer.sampling_efficiency = 0.2 ### PHASE 3 ### # In phase 3, we will fit simultaneously the lens and source galaxies, where we: # 1) Initialize the lens's light, mass, shear and source's light using the results of phases 1 and 2. class LensSourcePhase(ph.LensSourcePlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.light = previous_results[ 0].variable.lens.light self.lens_galaxies.lens.mass = previous_results[ 1].variable.lens.mass self.lens_galaxies.lens.shear = previous_results[ 1].variable.lens.shear self.source_galaxies.source = previous_results[1].variable.source phase3 = LensSourcePhase( lens_galaxies=dict(lens=gm.GalaxyModel(light=lp.EllipticalSersic, mass=mp.EllipticalIsothermal, shear=mp.ExternalShear)), source_galaxies=dict(source=gm.GalaxyModel(light=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name=pipeline_path + '/phase_3_both') phase3.optimizer.const_efficiency_mode = True phase3.optimizer.n_live_points = 75 phase3.optimizer.sampling_efficiency = 0.3 ### PHASE 4 ### # In phase 4, we initialize the inversion's resolution and regularization coefficient, where we: # 1) Use a lens-subtracted image generated by subtracting model lens galaxy image from phase 1. # 2) Fix our mass model to the lens galaxy mass-model from phase 2. # 3) Use a circular annular mask which includes only the source-galaxy light. class InversionPhase(ph.LensSourcePlanePhase): def modify_image(self, image, previous_results): return image - previous_results[2].unmasked_lens_plane_model_image def pass_priors(self, previous_results): self.lens_galaxies.lens.mass = previous_results[ 2].constant.lens.mass self.lens_galaxies.lens.shear = previous_results[ 2].constant.lens.shear phase4 = InversionPhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal, shear=mp.ExternalShear)), source_galaxies=dict( source=gm.GalaxyModel(pixelization=pix.AdaptiveMagnification, regularization=reg.Constant)), optimizer_class=nl.MultiNest, mask_function=mask_function_annular, phase_name=pipeline_path + '/phase_4_inversion_init') phase4.optimizer.const_efficiency_mode = True phase4.optimizer.n_live_points = 20 phase4.optimizer.sampling_efficiency = 0.8 ### PHASE 5 ### # In phase 5, we fit the len galaxy light, mass and source galxy simultaneously, using an inversion. We will: # 1) Initialize the priors of the lens galaxy and source galaxy from phases 3+4. # 2) Use a circular mask which includes the lens and source galaxy light. class InversionPhase(ph.LensSourcePlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.light = previous_results[ 2].variable.lens.light self.lens_galaxies.lens.mass = previous_results[ 2].variable.lens.mass self.lens_galaxies.lens.shear = previous_results[ 2].variable.lens.shear self.source_galaxies.source = previous_results[3].variable.source phase5 = InversionPhase( lens_galaxies=dict(lens=gm.GalaxyModel(light=lp.EllipticalSersic, mass=mp.EllipticalIsothermal, shear=mp.ExternalShear)), source_galaxies=dict( source=gm.GalaxyModel(pixelization=pix.AdaptiveMagnification, regularization=reg.Constant)), optimizer_class=nl.MultiNest, mask_function=mask_function_circular, phase_name=pipeline_path + '/phase_5_inversion') phase5.optimizer.const_efficiency_mode = True phase5.optimizer.n_live_points = 60 phase5.optimizer.sampling_efficiency = 0.4 return pipeline.PipelineImaging(pipeline_path, phase1, phase2, phase3, phase4, phase5)
def make_pipeline(pipeline_path=''): pipeline_name = 'pipeline_x2_lens_galaxies' pipeline_path = pipeline_path + pipeline_name ### PHASE 1 ### # The left-hand galaxy is at (0.0", -1.0"), so we're going to use a small circular mask centred on its location to # fit its light profile. Its important that light from the other lens galaxy and source galaxy don't contaminate # our fit. def mask_function(image): return msk.Mask.circular(image.shape, pixel_scale=image.pixel_scale, radius_arcsec=0.5, centre=(0.0, -1.0)) class LeftLensPhase(ph.LensPlanePhase): def pass_priors(self, previous_results): # Lets restrict the prior's on the centres around the pixel we know the galaxy's light centre peaks. self.lens_galaxies.left_lens.light.centre_0 = prior.GaussianPrior( mean=0.0, sigma=0.05) self.lens_galaxies.left_lens.light.centre_1 = prior.GaussianPrior( mean=-1.0, sigma=0.05) # Given we are only fitting the very central region of the lens galaxy, we don't want to let a parameter # like th Sersic index vary. Lets fix it to 4.0. self.lens_galaxies.left_lens.light.sersic_index = 4.0 phase1 = LeftLensPhase(lens_galaxies=dict(left_lens=gm.GalaxyModel( light=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, mask_function=mask_function, phase_name=pipeline_path + '/phase_1_left_lens_light') phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 30 phase1.optimizer.sampling_efficiency = 0.5 ### PHASE 2 ### # Now do the exact same with the lens galaxy on the right at (0.0", 1.0") def mask_function(image): return msk.Mask.circular(image.shape, pixel_scale=image.pixel_scale, radius_arcsec=0.5, centre=(0.0, 1.0)) class RightLensPhase(ph.LensPlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.right_lens.light.centre_0 = prior.GaussianPrior( mean=0.0, sigma=0.05) self.lens_galaxies.right_lens.light.centre_1 = prior.GaussianPrior( mean=1.0, sigma=0.05) self.lens_galaxies.right_lens.light.sersic_index = 4.0 phase2 = RightLensPhase(lens_galaxies=dict(right_lens=gm.GalaxyModel( light=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, mask_function=mask_function, phase_name=pipeline_path + '/phase_2_right_lens_light') phase2.optimizer.const_efficiency_mode = True phase2.optimizer.n_live_points = 30 phase2.optimizer.sampling_efficiency = 0.5 ### PHASE 3 ### # In the next phase, we fit the source of the lens subtracted image. class LensSubtractedPhase(ph.LensSourcePlanePhase): # To modify the image, we want to subtract both the left-hand and right-hand lens galaxies. To do this, we need # to subtract the unmasked model image of both galaxies! def modify_image(self, image, previous_results): phase_1_results = previous_results[0] phase_2_results = previous_results[1] return image - phase_1_results.unmasked_lens_plane_model_image - \ phase_2_results.unmasked_lens_plane_model_image def pass_priors(self, previous_results): phase_1_results = previous_results[0] phase_2_results = previous_results[1] # We're going to link the centres of the light profiles computed above to the centre of the lens galaxy # mass-profiles in this phase. Because the centres of the mass profiles were fixed in phases 1 and 2, # linking them using the 'variable' attribute means that they stay constant (which for now, is what we want). self.lens_galaxies.left_lens.mass.centre_0 = phase_1_results.variable.left_lens.light.centre_0 self.lens_galaxies.left_lens.mass.centre_1 = phase_1_results.variable.left_lens.light.centre_1 self.lens_galaxies.right_lens.mass.centre_0 = phase_2_results.variable.right_lens.light.centre_0 self.lens_galaxies.right_lens.mass.centre_1 = phase_2_results.variable.right_lens.light.centre_1 phase3 = LensSubtractedPhase(lens_galaxies=dict( left_lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal), right_lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal)), source_galaxies=dict(source=gm.GalaxyModel( light=lp.EllipticalExponential)), optimizer_class=nl.MultiNest, phase_name=pipeline_path + '/phase_3_fit_sources') phase3.optimizer.const_efficiency_mode = True phase3.optimizer.n_live_points = 50 phase3.optimizer.sampling_efficiency = 0.5 ### PHASE 4 ### # In phase 4, we'll fit both lens galaxy's light and mass profiles, as well as the source-galaxy, simultaneously. class FitAllPhase(ph.LensSourcePlanePhase): def pass_priors(self, previous_results): phase_1_results = previous_results[0] phase_2_results = previous_results[1] phase_3_results = previous_results[2] # Results are split over multiple phases, so we setup the light and mass profiles of each lens separately. self.lens_galaxies.left_lens.light = phase_1_results.variable.left_lens.light self.lens_galaxies.left_lens.mass = phase_3_results.variable.left_lens.mass self.lens_galaxies.right_lens.light = phase_2_results.variable.right_lens.light self.lens_galaxies.right_lens.mass = phase_3_results.variable.right_lens.mass # When we pass a a 'variable' galaxy from a previous phase, parameters fixed to constants remain constant. # Because centre_0 and centre_1 of the mass profile were fixed to constants in phase 3, they're still # constants after the line after. We need to therefore manually over-ride their priors. self.lens_galaxies.left_lens.mass.centre_0 = phase_3_results.variable.left_lens.mass.centre_0 self.lens_galaxies.left_lens.mass.centre_1 = phase_3_results.variable.left_lens.mass.centre_1 self.lens_galaxies.right_lens.mass.centre_0 = phase_3_results.variable.right_lens.mass.centre_0 self.lens_galaxies.right_lens.mass.centre_1 = phase_3_results.variable.right_lens.mass.centre_1 # We also want the Sersic index's to be free parameters now, so lets change it from a constant to a # variable. self.lens_galaxies.left_lens.light.sersic_index = prior.GaussianPrior( mean=4.0, sigma=2.0) self.lens_galaxies.right_lens.light.sersic_index = prior.GaussianPrior( mean=4.0, sigma=2.0) # Things are much simpler for the source galaxies - just like them togerther! self.source_galaxies.source = phase_3_results.variable.source phase4 = FitAllPhase(lens_galaxies=dict( left_lens=gm.GalaxyModel(light=lp.EllipticalSersic, mass=mp.EllipticalIsothermal), right_lens=gm.GalaxyModel(light=lp.EllipticalSersic, mass=mp.EllipticalIsothermal)), source_galaxies=dict(source=gm.GalaxyModel( light=lp.EllipticalExponential)), optimizer_class=nl.MultiNest, phase_name=pipeline_path + '/phase_4_fit_all') phase4.optimizer.const_efficiency_mode = True phase4.optimizer.n_live_points = 60 phase4.optimizer.sampling_efficiency = 0.5 return pipeline.PipelineImaging(pipeline_path, phase1, phase2, phase3, phase4)
def make_pipeline(pipeline_path=''): pipeline_name = 'pipeline_no_lens_light_and_source_inversion' pipeline_path = pipeline_path + pipeline_name # As there is no lens light component, we can use an annular mask throughout this pipeline which removes the # central regions of the image. def mask_function_annular(image): return msk.Mask.circular_annular(shape=image.shape, pixel_scale=image.pixel_scale, inner_radius_arcsec=0.2, outer_radius_arcsec=3.3) ### PHASE 1 ### # In phase 1, we will fit the lens galaxy's mass and one source galaxy, where we: # 1) Set our priors on the lens galaxy (y,x) centre such that we assume the image is centred around the lens galaxy. class LensSourceX1Phase(ph.LensSourcePlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.mass.centre_0 = prior.GaussianPrior( mean=0.0, sigma=0.1) self.lens_galaxies.lens.mass.centre_1 = prior.GaussianPrior( mean=0.0, sigma=0.1) phase1 = LensSourceX1Phase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal, shear=mp.ExternalShear)), source_galaxies=dict(source=gm.GalaxyModel(light=lp.EllipticalSersic)), mask_function=mask_function_annular, optimizer_class=nl.MultiNest, phase_name=pipeline_path + '/phase_1_x1_source') # You'll see these lines throughout all of the example pipelines. They are used to make MultiNest sample the \ # non-linear parameter space faster (if you haven't already, checkout 'tutorial_7_multinest_black_magic' in # 'howtolens/chapter_2_lens_modeling'. # Fitting the lens galaxy and source galaxy from uninitialized priors often risks MultiNest getting stuck in a # local maxima, especially for the image in this example which actually has two source galaxies. Therefore, whilst # I will continue to use constant efficiency mode to ensure fast run time, I've upped the number of live points # and decreased the sampling efficiency from the usual values to ensure the non-linear search is robust. phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 80 phase1.optimizer.sampling_efficiency = 0.2 ### PHASE 2 ### # In phase 2, we fit the lens's mass and source galaxy using an inversion, where we: # 1) Initialize the priors on the lens galaxy using the results of phase 1. # 2) Assume default priors for all source inversion parameters. class InversionPhase(ph.LensSourcePlanePhase): def pass_priors(self, previous_results): self.lens_galaxies.lens.mass = previous_results[ 0].variable.lens.mass self.lens_galaxies.lens.shear = previous_results[ 0].variable.lens.shear phase2 = InversionPhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal, shear=mp.ExternalShear)), source_galaxies=dict( source=gm.GalaxyModel(pixelization=pix.AdaptiveMagnification, regularization=reg.Constant)), optimizer_class=nl.MultiNest, mask_function=mask_function_annular, phase_name=pipeline_path + '/phase_2_inversion') phase2.optimizer.const_efficiency_mode = True phase2.optimizer.n_live_points = 50 phase2.optimizer.sampling_efficiency = 0.5 return pipeline.PipelineImaging(pipeline_path, phase1, phase2)
def make_pipeline(test_name): phase1 = ph.LensSourcePlanePhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal)), source_galaxies=dict(source_0=gm.GalaxyModel( sersic=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name="{}/phase1".format(test_name)) phase1.optimizer.const_efficiency_mode = True phase1.optimizer.n_live_points = 60 phase1.optimizer.sampling_efficiency = 0.7 phase1h = ph.LensMassAndSourceProfileHyperOnlyPhase( optimizer_class=nl.MultiNest, phase_name="{}/phase1h".format(test_name)) class AddSourceGalaxyPhase(ph.LensSourcePlaneHyperPhase): def pass_priors(self, previous_results): phase1_results = previous_results[-1] phase1h_results = previous_results[-1].hyper self.lens_galaxies.lens = phase1_results.variable.lens self.source_galaxies.source_0 = phase1_results.variable.source_0 self.source_galaxies.source_0.hyper_galaxy = phase1h_results.constant.source_0.hyper_galaxy phase2 = AddSourceGalaxyPhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal)), source_galaxies=dict( source_0=gm.GalaxyModel(sersic=lp.EllipticalSersic), source_1=gm.GalaxyModel(sersic=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name="{}/phase2".format(test_name)) phase2.optimizer.const_efficiency_mode = True phase2.optimizer.n_live_points = 60 phase2.optimizer.sampling_efficiency = 0.7 phase2h = ph.LensMassAndSourceProfileHyperOnlyPhase( optimizer_class=nl.MultiNest, phase_name="{}/phase1h".format(test_name)) class BothSourceGalaxiesPhase(ph.LensSourcePlaneHyperPhase): def pass_priors(self, previous_results): phase2_results = previous_results[1] phase2h_results = previous_results[1].hyper self.lens_galaxies.lens = phase2_results.variable.lens self.source_galaxies.source_0 = phase2_results.variable.source_0 self.source_galaxies.source_1 = phase2_results.variable.source_1 self.source_galaxies.source_0.hyper_galaxy = phase2h_results.constant.source_0.hyper_galaxy self.source_galaxies.source_1.hyper_galaxy = phase2h_results.constant.source_1.hyper_galaxy phase3 = BothSourceGalaxiesPhase( lens_galaxies=dict(lens=gm.GalaxyModel(mass=mp.EllipticalIsothermal)), source_galaxies=dict( source_0=gm.GalaxyModel(sersic=lp.EllipticalSersic), source_1=gm.GalaxyModel(sersic=lp.EllipticalSersic)), optimizer_class=nl.MultiNest, phase_name="{}/phase3".format(test_name)) return pl.PipelineImaging(test_name, phase1, phase1h, phase2, phase2h, phase3)