Skip to content

Commit

Permalink
ais update (#722)
Browse files Browse the repository at this point in the history
* fixed squash conflicts

* removed comments

* added write_to_patch flag; fixed background image rendering

* added a rate-is-inf check to catch loglike nans

* added MCMC chains to the end of AIS for better posterior estimates

* println's to Log.info

* slicesample print statements to Log

* more printlns removed

* removed extra newline

* fixed squash conflicts

* removed comments

* added write_to_patch flag; fixed background image rendering

* added a rate-is-inf check to catch loglike nans

* added MCMC chains to the end of AIS for better posterior estimates

* println's to Log.info

* slicesample print statements to Log

* more printlns removed

* removed extra newline

* removed println
  • Loading branch information
andymiller authored and jeff-regier committed Oct 9, 2017
1 parent e2e9cba commit bd525cf
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 162 deletions.
2 changes: 1 addition & 1 deletion src/MCMC.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ using Celeste: Model, Transform, SensitiveFloats
import Celeste.Model: SkyPatch, Image
import Celeste.SDSSIO: SDSSBackground
using Distributions, StatsBase, DataFrames, StaticArrays, WCS
import Celeste: Config
import Celeste: Config, Log

# TODO move these to model/log_prob.jl
star_param_names = ["lnr", "cug", "cgr", "cri", "ciz", "ra", "dec"]
Expand Down
4 changes: 2 additions & 2 deletions src/ParallelRun.jl
Original file line number Diff line number Diff line change
Expand Up @@ -503,8 +503,8 @@ function process_source_mcmc(config::Config,
for i in 1:length(images)]

# render a background image on the active source (first in list)
background_images = [MCMC.render_patch(images[i], patches[1, i], neighbors)
for i in 1:length(images)]
background_images = [MCMC.render_patch_nmgy(patch_images[i], patches[1, i], neighbors)
for i in 1:length(patch_images)]

# run mcmc sampler on this image/patch/background initialized at entry
if use_ais
Expand Down
30 changes: 4 additions & 26 deletions src/Synthetic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,37 +14,15 @@ using StaticArrays

function write_star_nmgy!(img::Image, ce::CatalogEntry)
p = Model.SkyPatch(img, ce, radius_override_pix=25)
fs0m = SensitiveFloat{Float64}(length(StarPosParams), 1, false, false)

H2, W2 = size(p.active_pixel_bitmap)
for w2 in 1:W2, h2 in 1:H2
h = p.bitmap_offset[1] + h2
w = p.bitmap_offset[2] + w2
Model.star_light_density!(fs0m, p, h, w, ce.pos, false)
img.pixels[h, w] += fs0m.v[] * ce.star_fluxes[img.b]
end
Model.write_star_nmgy!(ce.pos, ce.star_fluxes[img.b], p, img.pixels)
end


function write_galaxy_nmgy!(img::Image, ce::CatalogEntry)
bvn_derivs = Model.BivariateNormalDerivatives{Float64}()
fs1m = SensitiveFloat{Float64}(length(GalaxyPosParams), 1, false, false)
patches = Model.get_sky_patches([img], [ce], radius_override_pix=25.0)
source_params = [[ce.pos[1], ce.pos[2], ce.gal_frac_dev, ce.gal_axis_ratio,
ce.gal_angle, ce.gal_radius_px],]
star_mcs, gal_mcs = Model.load_bvn_mixtures(1, patches,
source_params, [1,], length(img.psf), 1,
calculate_gradient=false,
calculate_hessian=false)
p = patches[1]
H2, W2 = size(p.active_pixel_bitmap)
for w2 in 1:W2, h2 in 1:H2
# (h2, w2) index the local patch, while (h, w) index the image
h = p.bitmap_offset[1] + h2
w = p.bitmap_offset[2] + w2
Model.populate_gal_fsm!(fs1m, bvn_derivs, 1, h, w, false, p.wcs_jacobian, gal_mcs)
img.pixels[h, w] += fs1m.v[] * ce.gal_fluxes[img.b]
end
Model.write_galaxy_nmgy!(ce.pos, ce.gal_fluxes[img.b],
ce.gal_frac_dev, ce.gal_axis_ratio, ce.gal_angle, ce.gal_radius_px,
img.psf, patches, img.pixels)
end


Expand Down
4 changes: 2 additions & 2 deletions src/mcmc/ais.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ function ais(lnpdf, lnpdf0, step, z0;
# unpack previous and current temperatures
tprev, tcurr = schedule[ti-1], schedule[ti]
if ti % 25 == 0
@printf " temp %2.3f (%d/%d): logpost = %2.4f logprior = %2.4f\n" tcurr ti length(schedule) lnpdf(z) lnpdf0(z)
Log.info(@sprintf " temp %2.3f (%d/%d): logpost = %2.4f logprior = %2.4f" tcurr ti length(schedule) lnpdf(z) lnpdf0(z))
end

# generate zt | zt-1 using tcurr --- this leaves the distribution
Expand Down Expand Up @@ -126,7 +126,7 @@ function ais_slicesample(logposterior::Function,
zsamps = zeros(D, num_samps)
wsamps = zeros(num_samps)
for n in 1:num_samps
@printf "ais samp %d / %d\n" n num_samps
Log.info(@sprintf "ais samp %d / %d" n num_samps)
z0 = prior_sample()
#step = (z, lnpdf) -> MCMC.slicesample(z, lnpdf)
z, w, llrats, _ = ais(logposterior, logprior, step, z0; schedule=schedule)
Expand Down
96 changes: 56 additions & 40 deletions src/mcmc/mcmc_functions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,7 @@ Args:
function make_star_loglike(imgs::Vector;
patches::Array{SkyPatch, 1}=nothing,
background_images::Array{Array{Float64, 2}, 1}=nothing,
pos_transform::Function=nothing,
use_raw_psf=false)
pos_transform::Function=nothing)
# create background images --- sky noise and neighbors if there
if background_images == nothing
background_images = make_empty_background_images(imgs)
Expand All @@ -131,9 +130,6 @@ function make_star_loglike(imgs::Vector;
# as a sum, so we can compute it here and cache it
lgamma_const = compute_lgamma_sum(imgs, active_bitmaps)

# create iota vecs --- number of elecs per nanomaggy fo reach image
nelec_per_nmgy_vec = [Float64(median(img.nelec_per_nmgy)) for img in imgs]

# create function to return
function star_loglike(th::Array{Float64, 1})

Expand All @@ -150,30 +146,38 @@ function make_star_loglike(imgs::Vector;
# sky pixel intensity (sky image)
background = background_images[ii]

# create and cache unit flux src image
src_pixels = zeros(img.H, img.W)
iota = nelec_per_nmgy_vec[ii]
if use_raw_psf
write_star_unit_flux_raw(pos, patches[ii], iota, src_pixels)
else
write_star_unit_flux(pos, img.psf, img.wcs, iota, src_pixels,
offset=offsets[:,ii])
end

# band-specific flux --- do bounds check
bflux = exp(lnfluxes[img.b])
if isinf(bflux) # if bflux overflows, then return -Inf logprob
return -Inf
end

# create source flux image
src_pixels = zeros(Float32, img.H, img.W)
Model.write_star_nmgy!(pos, bflux, patches[ii], src_pixels;
write_to_patch=true)

# add background, convert flux to ave elec count
src_pixels += background
src_pixels .*= img.nelec_per_nmgy

# sum per-pixel likelihood contribution
for h in 1:img.H, w in 1:img.W
rate_hw = src_pixels[h, w]
if isinf(rate_hw)
return -Inf
end
pixel_data = img.pixels[h,w]
is_active = active_bitmap[h, w]
if !isnan(pixel_data) && is_active
rate_hw = background[h,w] + bflux*src_pixels[h,w]
#ll += poisson_lnpdf(pixel_data, rate_hw)
ll += (pixel_data*log(rate_hw) - rate_hw)
#if isnan(ll)
# println("found nan in star loglike!")
# println("rate: ", rate_hw)
# println("pixel_data: ", pixel_data)
# println("Bflux: ", bflux)
# throw("NOOOOOO")
#end
end
end
end
Expand Down Expand Up @@ -239,13 +243,13 @@ function make_gal_loglike(imgs::Vector;
lnfluxes, unc_pos, ushape = th[1:5], th[6:7], th[8:end]
pos = constrain_pos(unc_pos)
gal_frac_dev, gal_ab, gal_angle, gal_scale = ushape
@printf "lnfluxes = %s \n" string(lnfluxes)
@printf "pos (ra,dec) = %2.4f, %2.4f \n" pos[1] pos[2]
@printf "gal shape:\n"
@printf " frac_dev = %2.4f \n" gal_frac_dev
@printf " ab ratio = %2.4f \n" gal_ab
@printf " angle = %2.4f \n" gal_angle
@printf " scale = %2.4f \n" gal_scale
Log.info(@sprintf "lnfluxes = %s \n" string(lnfluxes))
Log.info(@sprintf "pos (ra,dec) = %2.4f, %2.4f \n" pos[1] pos[2])
Log.info(@sprintf "gal shape:\n")
Log.info(@sprintf " frac_dev = %2.4f \n" gal_frac_dev)
Log.info(@sprintf " ab ratio = %2.4f \n" gal_ab)
Log.info(@sprintf " angle = %2.4f \n" gal_angle)
Log.info(@sprintf " scale = %2.4f \n" gal_scale)
end

# make galaxy log like function
Expand All @@ -269,26 +273,35 @@ function make_gal_loglike(imgs::Vector;
# sky pixel intensity (sky image)
background = background_images[ii]

# create and cache unit flux src image
src_pixels = zeros(img.H, img.W)
px_pos = WCS.world_to_pix(img.wcs, pos) - offsets[:,ii]
write_galaxy_unit_flux_pixel(px_pos, img.psf,
Float64(median(img.nelec_per_nmgy)),
gal_frac_dev, gal_ab, gal_angle, gal_scale, src_pixels)

# image specific flux
bflux = exp(lnfluxes[img.b])
if isinf(bflux)
return -Inf
end

# create and cache unit flux src image
src_pixels = zeros(Float32, img.H, img.W)
Model.write_galaxy_nmgy!(pos, bflux, gal_frac_dev, gal_ab,
gal_angle, gal_scale, img.psf, [patches[ii]][:,:], src_pixels;
write_to_patch=true)

#src_pixels2 = zeros(img.H, img.W)
#write_galaxy_unit_flux(pos, img.psf, img.wcs, 1.,
# gal_frac_dev, gal_ab, gal_angle, gal_scale, src_pixels2; flux=bflux)
#println("gal is approx", isapprox(src_pixels, src_pixels2))
#println(" ... rmse", mean( (src_pixels .- src_pixels2).^2 ))
src_pixels += background
src_pixels .*= img.nelec_per_nmgy

# sum per-pixel likelihood contribution
for h in 1:img.H, w in 1:img.W
rate_hw = src_pixels[h, w]
if isinf(rate_hw)
return -Inf
end
pixel_data = img.pixels[h,w]
is_active = active_bitmap[h,w]
if !isnan(pixel_data) && is_active
rate_hw = background[h,w] + bflux*src_pixels[h,w]
#ll += poisson_lnpdf(pixel_data, rate_hw)
ll += (pixel_data*log(rate_hw) - rate_hw)
end
end
Expand Down Expand Up @@ -322,8 +335,8 @@ function make_location_prior(img::Image,
# lower and upper bounds on the ra/dec
ra_lo, ra_hi = sort([pos0_world_lower[1], pos0_world_upper[1]])
dec_lo, dec_hi = sort([pos0_world_lower[2], pos0_world_upper[2]])
@printf " ... limiting RA to [%2.5f, %2.5f] \n" ra_lo ra_hi
@printf " ... limiting DEC to [%2.5f, %2.5f] \n" dec_lo dec_hi
Log.info(@sprintf " ... limiting RA to [%2.5f, %2.5f]" ra_lo ra_hi)
Log.info(@sprintf " ... limiting DEC to [%2.5f, %2.5f]" dec_lo dec_hi)

# corresponding uniform log likelihoods
llra = log(1./(ra_hi - ra_lo))
Expand Down Expand Up @@ -382,13 +395,14 @@ function make_gal_logprior()
llangle = -log(pi)
llscale = logpdf(prior.galaxy.gal_radius_px, gal_scale)
if isinf(llangle)
println(" angle bad!")
throw(" angle bad!")
end
if isinf(llscale)
println(" scale bad!")
throw(" scale bad!")
end
ll = MCMC.logflux_logprior(lnfluxes; is_star=false) + llangle + llscale
return ll

end
return gal_logprior
end
Expand All @@ -409,9 +423,11 @@ function make_empty_background_images(imgs::Vector)
background_images = []
for img in imgs
# sky pixel intensity (sky image)
epsilon = img.sky[1, 1]
iota = img.nelec_per_nmgy[1]
sky_pixels = [epsilon * iota for h=1:img.H, w=1:img.W]
#epsilon = img.sky[1, 1]
#iota = img.nelec_per_nmgy[1]
#sky_pixels = [epsilon * iota for h=1:img.H, w=1:img.W]
sky_pixels = img.sky
Log.info("sky image size : ", size(sky_pixels))
push!(background_images, sky_pixels)
end
return background_images
Expand Down
Loading

0 comments on commit bd525cf

Please sign in to comment.