From 8fb9b3f86d81c56cb4ab643020bee91b20931307 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 07:59:16 +0000 Subject: [PATCH 01/10] Add offset_list support to profuseMultiBandFound2Fit Agent-Logs-Url: https://github.com/asgr/ProFuse/sessions/01d5aec8-11cf-4bf5-97fc-610ab52c296c Co-authored-by: asgr <5617132+asgr@users.noreply.github.com> --- R/profuseMultiBand.R | 27 ++++++++++++++++++++------- man/profuseMultiBand.Rd | 13 ++++++++----- vignettes/ProFuse-Multi-Images.Rmd | 2 +- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/R/profuseMultiBand.R b/R/profuseMultiBand.R index 18e3bb4..24d21f6 100644 --- a/R/profuseMultiBand.R +++ b/R/profuseMultiBand.R @@ -25,13 +25,14 @@ profuseMultiBandFound2Fit = function(image_list, 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, + 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, #perhaps need a way to specify extra data going to bulge/disk. Naming or list? logged_ProSpect = NULL, intervals_ProSpect = NULL, @@ -48,6 +49,17 @@ profuseMultiBandFound2Fit = function(image_list, magzero = rep(magzero, Nim) } + if(is.null(offset_list)){ + offset_list = vector("list", Nim) + }else{ + if(length(offset_list) == 1){ + offset_list = rep(offset_list, 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(autoclip){ image_med = median(image_list[[i]], na.rm=TRUE) @@ -267,6 +279,7 @@ profuseMultiBandFound2Fit = function(image_list, magzero = magzero[i], algo.func = 'LD', verbose = FALSE, + offset = offset_list[[i]], rough = fit_rough, nbenchconv = nbenchconv ) diff --git a/man/profuseMultiBand.Rd b/man/profuseMultiBand.Rd index a165ee1..172a2e7 100644 --- a/man/profuseMultiBand.Rd +++ b/man/profuseMultiBand.Rd @@ -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, ...) profuseMultiBandDoFit(image_list, MF2F = NULL, parm_global = c("sersic.xcen1", "sersic.ycen1", "sersic.re1", "sersic.ang2", "sersic.axrat2"), Ncomp = 2, @@ -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 length 1 it is recycled to all bands. } \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. diff --git a/vignettes/ProFuse-Multi-Images.Rmd b/vignettes/ProFuse-Multi-Images.Rmd index 4ff2a33..f59ab65 100644 --- a/vignettes/ProFuse-Multi-Images.Rmd +++ b/vignettes/ProFuse-Multi-Images.Rmd @@ -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, but now support per-band positional offsets via `offset_list` when required. 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. 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: From 27fecbee568549d3fe30f681ec01401e640cba59 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 08:00:13 +0000 Subject: [PATCH 02/10] Address review feedback for offset_list support Agent-Logs-Url: https://github.com/asgr/ProFuse/sessions/01d5aec8-11cf-4bf5-97fc-610ab52c296c Co-authored-by: asgr <5617132+asgr@users.noreply.github.com> --- R/profuseMultiBand.R | 2 +- vignettes/ProFuse-Multi-Images.Rmd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/R/profuseMultiBand.R b/R/profuseMultiBand.R index 24d21f6..1102ce0 100644 --- a/R/profuseMultiBand.R +++ b/R/profuseMultiBand.R @@ -53,7 +53,7 @@ profuseMultiBandFound2Fit = function(image_list, offset_list = vector("list", Nim) }else{ if(length(offset_list) == 1){ - offset_list = rep(offset_list, Nim) + 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.") diff --git a/vignettes/ProFuse-Multi-Images.Rmd b/vignettes/ProFuse-Multi-Images.Rmd index f59ab65..6087a9a 100644 --- a/vignettes/ProFuse-Multi-Images.Rmd +++ b/vignettes/ProFuse-Multi-Images.Rmd @@ -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 images to be cropped to the desired level, but now support per-band positional offsets via `offset_list` when required. 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: From 28adc1ae2a1e404156e6cfe5188b50043acd6f69 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 08:00:59 +0000 Subject: [PATCH 03/10] Harden offset_list validation and formatting Agent-Logs-Url: https://github.com/asgr/ProFuse/sessions/01d5aec8-11cf-4bf5-97fc-610ab52c296c Co-authored-by: asgr <5617132+asgr@users.noreply.github.com> --- R/profuseMultiBand.R | 3 +++ 1 file changed, 3 insertions(+) diff --git a/R/profuseMultiBand.R b/R/profuseMultiBand.R index 1102ce0..c564f2c 100644 --- a/R/profuseMultiBand.R +++ b/R/profuseMultiBand.R @@ -52,6 +52,9 @@ profuseMultiBandFound2Fit = function(image_list, 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) } From c0f714c2fe2fc468344c76b3733e3a0bd172f1e8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 08:02:14 +0000 Subject: [PATCH 04/10] Accept single offset vector and clarify defaults Agent-Logs-Url: https://github.com/asgr/ProFuse/sessions/01d5aec8-11cf-4bf5-97fc-610ab52c296c Co-authored-by: asgr <5617132+asgr@users.noreply.github.com> --- R/profuseMultiBand.R | 3 +++ man/profuseMultiBand.Rd | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/R/profuseMultiBand.R b/R/profuseMultiBand.R index c564f2c..c4aa2de 100644 --- a/R/profuseMultiBand.R +++ b/R/profuseMultiBand.R @@ -52,6 +52,9 @@ profuseMultiBandFound2Fit = function(image_list, if(is.null(offset_list)){ offset_list = vector("list", Nim) }else{ + if(is.numeric(offset_list) && length(offset_list) == 2){ + offset_list = list(offset_list) + } if(!is.list(offset_list)){ stop("offset_list must be a list when provided.") } diff --git a/man/profuseMultiBand.Rd b/man/profuseMultiBand.Rd index 172a2e7..39e1238 100644 --- a/man/profuseMultiBand.Rd +++ b/man/profuseMultiBand.Rd @@ -125,7 +125,7 @@ Logical; optional, should the star be forced to be circular? If TRUE this means 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 length 1 it is recycled to all bands. +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. A single numeric [X,Y] vector is also accepted and treated as length 1. } \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. From 7766c164a555f6c2cb6f2e47baa6f602985a07ad Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 08:03:08 +0000 Subject: [PATCH 05/10] Normalize formatting and validate numeric offsets Agent-Logs-Url: https://github.com/asgr/ProFuse/sessions/01d5aec8-11cf-4bf5-97fc-610ab52c296c Co-authored-by: asgr <5617132+asgr@users.noreply.github.com> --- R/profuseMultiBand.R | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/R/profuseMultiBand.R b/R/profuseMultiBand.R index c4aa2de..83a1e4a 100644 --- a/R/profuseMultiBand.R +++ b/R/profuseMultiBand.R @@ -25,14 +25,14 @@ profuseMultiBandFound2Fit = function(image_list, 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, + 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, #perhaps need a way to specify extra data going to bulge/disk. Naming or list? logged_ProSpect = NULL, intervals_ProSpect = NULL, @@ -52,8 +52,12 @@ profuseMultiBandFound2Fit = function(image_list, if(is.null(offset_list)){ offset_list = vector("list", Nim) }else{ - if(is.numeric(offset_list) && length(offset_list) == 2){ - offset_list = list(offset_list) + if(is.numeric(offset_list)){ + if(length(offset_list) == 2){ + offset_list = list(offset_list) + }else{ + stop("Numeric offset_list input must be a single [X,Y] vector.") + } } if(!is.list(offset_list)){ stop("offset_list must be a list when provided.") From 011902bf8a9a62fdfb0c62d09d7a500385961bc3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 08:03:51 +0000 Subject: [PATCH 06/10] Clarify offset_list length requirement in docs Agent-Logs-Url: https://github.com/asgr/ProFuse/sessions/01d5aec8-11cf-4bf5-97fc-610ab52c296c Co-authored-by: asgr <5617132+asgr@users.noreply.github.com> --- man/profuseMultiBand.Rd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/profuseMultiBand.Rd b/man/profuseMultiBand.Rd index 39e1238..2970135 100644 --- a/man/profuseMultiBand.Rd +++ b/man/profuseMultiBand.Rd @@ -125,7 +125,7 @@ Logical; optional, should the star be forced to be circular? If TRUE this means 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. A single numeric [X,Y] vector is also accepted and treated as length 1. +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. A single numeric [X,Y] vector is also accepted and treated as length 1. Otherwise, \option{offset_list} must have the same length as \option{image_list}. } \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. From ccd97696ebc056b504e5a8959b1e5442cc692438 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 08:05:01 +0000 Subject: [PATCH 07/10] Require list-based per-band offset vectors Agent-Logs-Url: https://github.com/asgr/ProFuse/sessions/01d5aec8-11cf-4bf5-97fc-610ab52c296c Co-authored-by: asgr <5617132+asgr@users.noreply.github.com> --- R/profuseMultiBand.R | 12 +++++------- man/profuseMultiBand.Rd | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/R/profuseMultiBand.R b/R/profuseMultiBand.R index 83a1e4a..3edd5e5 100644 --- a/R/profuseMultiBand.R +++ b/R/profuseMultiBand.R @@ -52,13 +52,6 @@ profuseMultiBandFound2Fit = function(image_list, if(is.null(offset_list)){ offset_list = vector("list", Nim) }else{ - if(is.numeric(offset_list)){ - if(length(offset_list) == 2){ - offset_list = list(offset_list) - }else{ - stop("Numeric offset_list input must be a single [X,Y] vector.") - } - } if(!is.list(offset_list)){ stop("offset_list must be a list when provided.") } @@ -68,6 +61,11 @@ profuseMultiBandFound2Fit = function(image_list, 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){ diff --git a/man/profuseMultiBand.Rd b/man/profuseMultiBand.Rd index 2970135..eac0fc9 100644 --- a/man/profuseMultiBand.Rd +++ b/man/profuseMultiBand.Rd @@ -125,7 +125,7 @@ Logical; optional, should the star be forced to be circular? If TRUE this means 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. A single numeric [X,Y] vector is also accepted and treated as length 1. Otherwise, \option{offset_list} must have the same length as \option{image_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. From 6f24faeac60f2d2d6a91dd53911892622bf29c3b Mon Sep 17 00:00:00 2001 From: Aaron Robotham Date: Wed, 27 May 2026 14:44:39 +0800 Subject: [PATCH 08/10] scat_scale added (need to check this properly) --- R/profuseMultiBand.R | 18 ++++++++++++++---- R/profuseSingleImage.R | 10 ++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/R/profuseMultiBand.R b/R/profuseMultiBand.R index 3edd5e5..5efad4e 100644 --- a/R/profuseMultiBand.R +++ b/R/profuseMultiBand.R @@ -38,6 +38,7 @@ profuseMultiBandFound2Fit = function(image_list, intervals_ProSpect = NULL, autoclip = TRUE, roughpedestal = TRUE, + scat_scale = FALSE, ...){ Nim = length(image_list) @@ -372,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)) @@ -427,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% Data$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) @@ -444,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, diff --git a/R/profuseSingleImage.R b/R/profuseSingleImage.R index 521f148..25944d7 100644 --- a/R/profuseSingleImage.R +++ b/R/profuseSingleImage.R @@ -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) @@ -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') @@ -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( From bd7b296c0535875eeb1b1c13bad43eb851e8e12d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 27 May 2026 08:09:23 +0000 Subject: [PATCH 09/10] Fix scat_scale wiring and add multi-image support --- R/profuseMultiBand.R | 2 +- R/profuseMultiImage.R | 10 ++++++++++ man/profuseMultiBand.Rd | 5 ++++- man/profuseMultiImage.Rd | 6 +++++- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/R/profuseMultiBand.R b/R/profuseMultiBand.R index 5efad4e..beb63d3 100644 --- a/R/profuseMultiBand.R +++ b/R/profuseMultiBand.R @@ -435,7 +435,7 @@ profuseMultiBandDoFit = function(image_list, lowers = c(lower_profit, MF2F$intervals_ProSpect$lo) uppers = c(upper_profit, MF2F$intervals_ProSpect$hi) - if('log_scat_scale' %in% Data$parm.names){ + if('log_scat_scale' %in% MF2F$parm.names){ lowers = c(lowers, -2) uppers = c(uppers, 2) } diff --git a/R/profuseMultiImage.R b/R/profuseMultiImage.R index 103bc32..fbfb903 100644 --- a/R/profuseMultiImage.R +++ b/R/profuseMultiImage.R @@ -12,6 +12,7 @@ profuseMultiImageFound2Fit = function( resamp = NULL, tightcrop = TRUE, offset_list = NULL, + scat_scale = FALSE, ... ){ Nim = length(image_list) @@ -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') @@ -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('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) diff --git a/man/profuseMultiBand.Rd b/man/profuseMultiBand.Rd index eac0fc9..b26ae85 100644 --- a/man/profuseMultiBand.Rd +++ b/man/profuseMultiBand.Rd @@ -19,7 +19,7 @@ profuseMultiBandFound2Fit(image_list, segim_list = NULL, segim_global = NULL, 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, ...) + 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, @@ -150,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. diff --git a/man/profuseMultiImage.Rd b/man/profuseMultiImage.Rd index 4187830..a5c1216 100644 --- a/man/profuseMultiImage.Rd +++ b/man/profuseMultiImage.Rd @@ -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, @@ -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. From ec7dda510255c696cfd3036488530f1ccaed0d8c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 27 May 2026 08:09:52 +0000 Subject: [PATCH 10/10] Guard multi-image scat_scale bounds check --- R/profuseMultiImage.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/profuseMultiImage.R b/R/profuseMultiImage.R index fbfb903..de8121a 100644 --- a/R/profuseMultiImage.R +++ b/R/profuseMultiImage.R @@ -153,7 +153,7 @@ profuseMultiImageDoFit = function(image_list, uppers[unlist(Data$tolog) == T] = log10(uppers[unlist(Data$tolog) == T]) uppers = as.numeric(uppers[which(unlist(Data$tofit))]) - if('log_scat_scale' %in% F2F$parm.names){ + if(!is.null(F2F$parm.names) && 'log_scat_scale' %in% F2F$parm.names){ lowers = c(lowers, -2) uppers = c(uppers, 2) }