Skip to content
39 changes: 35 additions & 4 deletions R/profuseMultiBand.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ profuseMultiBandFound2Fit = function(image_list,
star_con_fit = TRUE,
star_circ = TRUE,
tightcrop = TRUE,
offset_list = NULL,
wave = NULL,
smooth.parm = NULL,
parm_ProSpect = NULL,
Expand All @@ -37,6 +38,7 @@ profuseMultiBandFound2Fit = function(image_list,
intervals_ProSpect = NULL,
autoclip = TRUE,
roughpedestal = TRUE,
scat_scale = FALSE,
...){
Nim = length(image_list)

Expand All @@ -48,6 +50,25 @@ profuseMultiBandFound2Fit = function(image_list,
magzero = rep(magzero, Nim)
}

if(is.null(offset_list)){
offset_list = vector("list", Nim)
}else{
if(!is.list(offset_list)){
stop("offset_list must be a list when provided.")
}
if(length(offset_list) == 1){
offset_list = rep(list(offset_list[[1]]), Nim)
}
if(length(offset_list) != Nim){
stop("offset_list must be NULL, length 1, or the same length as image_list.")
}
for(i in 1:Nim){
if(!is.null(offset_list[[i]]) && (!is.numeric(offset_list[[i]]) || length(offset_list[[i]]) != 2)){
stop("Each non-NULL offset_list element must be a numeric [X,Y] vector of length 2.")
}
}
}

for(i in 1:Nim){
if(autoclip){
image_med = median(image_list[[i]], na.rm=TRUE)
Expand Down Expand Up @@ -267,6 +288,7 @@ profuseMultiBandFound2Fit = function(image_list,
magzero = magzero[i],
algo.func = 'LD',
verbose = FALSE,
offset = offset_list[[i]],
rough = fit_rough,
nbenchconv = nbenchconv
)
Expand Down Expand Up @@ -351,6 +373,10 @@ profuseMultiBandFound2Fit = function(image_list,
MF2F$logged_ProSpect = logged_ProSpect
MF2F$intervals_ProSpect = intervals_ProSpect

if(scat_scale){
MF2F$parm.names = c(MF2F$parm.names, 'log_scat_scale')
}

class(MF2F) = c(class(MF2F), 'MF2F')

return(invisible(MF2F))
Expand Down Expand Up @@ -406,8 +432,13 @@ profuseMultiBandDoFit = function(image_list,
lower_profit[logged_profit] = log10(lower_profit[logged_profit])
upper_profit[logged_profit] = log10(upper_profit[logged_profit])

lower = c(lower_profit, MF2F$intervals_ProSpect$lo)
upper = c(upper_profit, MF2F$intervals_ProSpect$hi)
lowers = c(lower_profit, MF2F$intervals_ProSpect$lo)
uppers = c(upper_profit, MF2F$intervals_ProSpect$hi)

if('log_scat_scale' %in% MF2F$parm.names){
lowers = c(lowers, -2)
uppers = c(uppers, 2)
}

}else{
#This implies we are in smooth.spline fitting mode, i.e. not using ProSpect (we don't use this)
Expand All @@ -423,8 +454,8 @@ profuseMultiBandDoFit = function(image_list,
Data = MF2F,
likefunc = profitLikeModel,
seed = seed,
lower = lower,
upper = upper,
lower = lowers,
upper = uppers,
applyintervals = TRUE,
applyconstraints = FALSE,
optim_iters = optim_iters,
Expand Down
10 changes: 10 additions & 0 deletions R/profuseMultiImage.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ profuseMultiImageFound2Fit = function(
resamp = NULL,
tightcrop = TRUE,
offset_list = NULL,
scat_scale = FALSE,
...
){
Nim = length(image_list)
Expand Down Expand Up @@ -95,6 +96,10 @@ profuseMultiImageFound2Fit = function(
F2F_multi$N = F2F_multi[[1]]$N
F2F_multi$Nim = Nim

if(scat_scale){
F2F_multi$parm.names = c(F2F_multi$parm.names, 'log_scat_scale')
}

names(F2F_multi)[1:Nim] = paste('image', 1:Nim, sep='')
class(F2F_multi) = c(class(F2F_multi), 'F2F_multi')

Expand Down Expand Up @@ -148,6 +153,11 @@ profuseMultiImageDoFit = function(image_list,
uppers[unlist(Data$tolog) == T] = log10(uppers[unlist(Data$tolog) == T])
uppers = as.numeric(uppers[which(unlist(Data$tofit))])

if(!is.null(F2F$parm.names) && 'log_scat_scale' %in% F2F$parm.names){
lowers = c(lowers, -2)
uppers = c(uppers, 2)
}

if(!is.null(Data$offset)){
xcen_loc = grep('xcen',Data$parm.names)
ycen_loc = grep('ycen',Data$parm.names)
Expand Down
10 changes: 10 additions & 0 deletions R/profuseSingleImage.R
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ profuseFound2Fit = function(image,
pos_delta = 10,
autoclip = TRUE,
roughpedestal = TRUE,
scat_scale = FALSE,
...) {
if(autoclip){
image_med = median(image, na.rm=TRUE)
Expand Down Expand Up @@ -732,6 +733,10 @@ profuseFound2Fit = function(image,

Data$Nmod = Ncomp + N_ext

if(scat_scale){
Data$parm.names = c(Data$parm.names, 'log_scat_scale')
}

F2F_single = list(profound = mini_profound, Data = Data)
class(F2F_single) = c(class(F2F_single), 'F2F_single')

Expand Down Expand Up @@ -785,6 +790,11 @@ profuseDoFit = function(image,
uppers[unlist(Data$tolog) == T] = log10(uppers[unlist(Data$tolog) == T])
uppers = as.numeric(uppers[which(unlist(Data$tofit))])

if('log_scat_scale' %in% Data$parm.names){
lowers = c(lowers, -2)
uppers = c(uppers, 2)
}

message('Running Highlander')
if(!requireNamespace("ProFound", quietly = TRUE)){stop('The Highander package is required to run this function!')}
highfit = Highlander::Highlander(
Expand Down
16 changes: 11 additions & 5 deletions man/profuseMultiBand.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ profuseMultiBandFound2Fit(image_list, segim_list = NULL, segim_global = NULL,
Ncomp = 2, loc = NULL, cutbox = NULL, psf_list = NULL, nbenchconv = 0L, magdiff = 2.5,
magzero = NULL, gain = NULL, resamp = NULL, doprofit = NULL, sing_nser = 2,
bulge_nser = 4, disk_nser = 1, sing_nser_fit = TRUE, bulge_nser_fit = FALSE,
disk_nser_fit = FALSE, bulge_circ = TRUE, nser_upper = 5.3, star_rough = TRUE,
fit_rough = FALSE, psf_dim = c(51, 51), star_con = 2, star_con_fit = TRUE,
star_circ = TRUE, tightcrop = TRUE, wave = NULL, smooth.parm = NULL,
parm_ProSpect = NULL, data_ProSpect = NULL, logged_ProSpect = NULL,
intervals_ProSpect = NULL, autoclip = TRUE, roughpedestal = TRUE, ...)
disk_nser_fit = FALSE, bulge_circ = TRUE, nser_upper = 5.3, star_rough = TRUE,
fit_rough = FALSE, psf_dim = c(51, 51), star_con = 2, star_con_fit = TRUE,
star_circ = TRUE, tightcrop = TRUE, offset_list = NULL, wave = NULL, smooth.parm = NULL,
parm_ProSpect = NULL, data_ProSpect = NULL, logged_ProSpect = NULL,
intervals_ProSpect = NULL, autoclip = TRUE, roughpedestal = TRUE, scat_scale = FALSE, ...)

profuseMultiBandDoFit(image_list, MF2F = NULL, parm_global = c("sersic.xcen1",
"sersic.ycen1", "sersic.re1", "sersic.ang2", "sersic.axrat2"), Ncomp = 2,
Expand Down Expand Up @@ -123,6 +123,9 @@ Logical; optional, should the star be forced to be circular? If TRUE this means
}
\item{tightcrop}{
Logical; optional, should the image be cut down to the tightest fitting box that fully contains the segmentation map? This might be a good idea if the parent image is very large (cuts down on memory allocation etc), but might be a bad idea if you want to know the exact position of your source with the frame, e.g. \option{xcen} and \option{ycen} in the \option{modellist} are relative to the new tightly cropped image not the original cropped image.
}
\item{offset_list}{
List; optional, per-band offsets to pass into \code{\link{profitSetupData}} \option{offset}. This can be used to track known [X,Y] positional shifts between images so a shared physical model is correctly projected into each band. If NULL (default) then no offsets are used. If length 1 it is recycled to all bands. Otherwise, \option{offset_list} must have the same length as \option{image_list}. Each non-NULL element should be a numeric [X,Y] vector of length 2.
}
\item{wave}{
Numeric vector; optional. This is only relevant if you are providing smoothing functions via \option{smooth.parm}. If provided it should be the wavelength of each image in \option{image_list}, where \option{image_list} then needs to be in ascending (blue to red) wavelength order.
Expand All @@ -147,6 +150,9 @@ Logical; should ihe provided \option{image} by automatically clipped for bad pix
}
\item{roughpedestal}{
Logical; when the initial "rough sky" is computed, should only a pedestal (based on the median of the sky map) be used for the sky? This is a good option if the image is known to contain a *very* large (many times the box size) galaxy that might otherwise be over subtracted by the initial rough sky map. This is the only \code{\link{profoundProFound}} option that is changed from the default, since our requirement is that all \option{image} inputs are already sky subracted properly.
}
\item{scat_scale}{
Logical; should \code{log_scat_scale} be included as a free parameter in fitting? If TRUE this passes a scatter scaling term through to \code{\link{profitLikeModel}}, allowing the effective likelihood scatter to be adjusted.
}
\item{seed}{
Integer scalar; random seed to start the \code{Highlander} function with.
Expand Down
6 changes: 5 additions & 1 deletion man/profuseMultiImage.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ Functions to easily take users from multiple image pixel data all the way to ful
\usage{
profuseMultiImageFound2Fit(image_list, segim_list = NULL, mask_list = NULL,
Ncomp = 2, loc = NULL, cutbox = NULL, psf_list = NULL, nbenchconv = 0L,
magzero = NULL, gain = NULL, resamp = NULL, tightcrop = TRUE, offset_list = NULL, ...)
magzero = NULL, gain = NULL, resamp = NULL, tightcrop = TRUE, offset_list = NULL,
scat_scale = FALSE, ...)

profuseMultiImageDoFit(image_list, F2F = NULL, Ncomp = 2, psf_list = NULL,
magzero = NULL, psf_dim = c(51, 51), plot = FALSE, seed = 666,
Expand Down Expand Up @@ -62,6 +63,9 @@ Logical; optional, should the image be cut down to the tightest fitting box that
}
\item{offset_list}{
List; optional, offsets to pass into \code{\link{profuseFound2Fit}} \option{offset}.
}
\item{scat_scale}{
Logical; should \code{log_scat_scale} be included as a free parameter in fitting? If TRUE this passes a scatter scaling term through to \code{\link{profitLikeModel}}, allowing the effective likelihood scatter to be adjusted.
}
\item{psf_dim}{
Integer vector; optional, the dimensions of the output PSF generated when fitting a star with \option{Ncomp} = 0.5. The PSF will be centrally located in the image. The dimensions will be forced to be odd (adding 1 if required) to ensure the PSF mode is at the centre of the middle pixel.
Expand Down
2 changes: 1 addition & 1 deletion vignettes/ProFuse-Multi-Images.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ HighFit2$parm

## Fully Automatic Multi-band Fitting

**ProFit** v2.0.0 and upwards support highly automated multi-band fitting via the **profuseMultiBandFound2Fit** and **profuseMultiBandDoFit** functions. These require the images provided to be exactly registered and cropped to the desired level (no offset or cut out options here). If this is not the case, then lower level functions (i.e. those above) probably need to be used instead. These functions will find stars and create per band PSFs automatically, so they might well cover the major use cases for many people.
**ProFit** v2.0.0 and upwards support highly automated multi-band fitting via the **profuseMultiBandFound2Fit** and **profuseMultiBandDoFit** functions. These require images to be cropped to the desired level, and now support per-band positional offsets via `offset_list` when required. If your data still need more complex registration/cutout handling than this, then lower level functions (i.e. those above) probably need to be used instead. These functions will find stars and create per band PSFs automatically, so they might well cover the major use cases for many people.

As an example we can load in 9 bands of data that come included in the **ProFound** package, and cut out around a bright spiral galaxy:

Expand Down