From 868c46022654837ef718f6c15fbbd226f18229d0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 04:29:49 +0000 Subject: [PATCH 01/10] Simplify profitLikeModel using ParmOff for argument matching Agent-Logs-Url: https://github.com/ICRAR/ProFit/sessions/af38ea0f-5efe-46d5-bc04-bbc3cd502caa Co-authored-by: asgr <5617132+asgr@users.noreply.github.com> --- DESCRIPTION | 5 +++-- NAMESPACE | 1 + R/profitLikeModel.R | 40 ++++++++++++++-------------------------- 3 files changed, 18 insertions(+), 28 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index f66589a..ea7cf29 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -16,11 +16,12 @@ License: LGPL-3 URL: https://github.com/ICRAR/ProFit BugReports: https://github.com/ICRAR/ProFit/issues Depends: R (>= 3.0), Rfits (>= 1.8.0), magicaxis (>= 2.0.3) -Imports: cubature, RColorBrewer, LaplacesDemon, methods, celestial (>= 1.4.1), checkmate +Imports: cubature, RColorBrewer, LaplacesDemon, methods, celestial (>= 1.4.1), checkmate, ParmOff Suggests: fftw, knitr, rmarkdown, ProFound (>= 1.15.0), sn, Highlander (>= 0.1.7), ProSpect VignetteBuilder: knitr Remotes: asgr/Rfits, asgr/magicaxis, asgr/celestial, - asgr/ProFound + asgr/ProFound, + asgr/ParmOff diff --git a/NAMESPACE b/NAMESPACE index 4f8fc83..af33485 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -14,3 +14,4 @@ importFrom("cubature", "hcubature") importFrom("LaplacesDemon", "LaplaceApproximation", "LaplacesDemon") importFrom("methods", "new") importFrom("checkmate", "checkNumeric", "checkInteger", "checkLogical") +importFrom("ParmOff", "ParmOff") diff --git a/R/profitLikeModel.R b/R/profitLikeModel.R index b0fe5a7..f4e8865 100644 --- a/R/profitLikeModel.R +++ b/R/profitLikeModel.R @@ -22,17 +22,16 @@ openclenv=Data$openclenv if(identical(openclenv,new("externalptr"))) openclenv = NULL + makemodel_args = list( + modellist=modellist, magzero=Data$magzero, psf=psf, dim=dim(Data$image), psfdim=psfdim, + rough=rough, magmu=Data$magmu, finesample=finesample, convopt=Data$convopt, + openclenv=openclenv, omp_threads=Data$omp_threads, adjust_calcregion=FALSE + ) if(Data$usecalcregion){ - model = profitMakeModel(modellist=modellist, magzero = Data$magzero, psf=psf, dim=dim(Data$image), psfdim=psfdim, - rough=rough, calcregion=Data$calcregion, docalcregion=Data$usecalcregion, - magmu=Data$magmu,finesample=finesample, convopt=Data$convopt, openclenv=openclenv, omp_threads=Data$omp_threads, - adjust_calcregion = FALSE, ...) - }else{ - model = profitMakeModel(modellist=modellist, magzero = Data$magzero, psf=psf, dim=dim(Data$image), psfdim=psfdim, - rough=rough, - magmu=Data$magmu, finesample=finesample, convopt=Data$convopt, openclenv=openclenv, omp_threads=Data$omp_threads, - adjust_calcregion = FALSE, ...) + makemodel_args$calcregion = Data$calcregion + makemodel_args$docalcregion = Data$usecalcregion } + model = ParmOff(profitMakeModel, .args=makemodel_args, ...) return(model) } @@ -101,27 +100,16 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, args_names = names(Data$parm_ProSpect) args_names_comp = args_names[grepl(paste0('_',i), args_names)] args_loc_comp = match(args_names_comp, Data$parm.names) - args_names_comp = sub(paste0('_',i), '', args_names_comp) #Strip the component identifier - args = parm[args_loc_comp] - names(args) = args_names_comp #Rename + args_list = as.list(parm[args_loc_comp]) + names(args_list) = args_names_comp # names retain _i suffix; ParmOff .strip removes it below parm = parm[-args_loc_comp] Data$parm.names = Data$parm.names[-args_loc_comp] - args_list = as.list(args) #List if(!is.null(Data$data_ProSpect)){ - # Below means we assume global options are those without "_X" except then X=i (so then it is local to that component) - if(Data$Ncomp == 1){ - args_list = c(args_list, Data$data_ProSpect) - }else{ - data_names = names(Data$data_ProSpect) - data_loc = grepl(paste0('_',i), data_names) - data_list = Data$data_ProSpect[data_loc] - data_loc_global = ! (grepl('_1', data_names) | grepl('_2', data_names) | grepl('_3', data_names)) #Currently only works for up to 3 components, but this is all that is currently supported anyway - data_list = c(data_list, Data$data_ProSpect[data_loc_global]) - names(data_list) = sub(paste0('_',i), '', names(data_list)) - args_list = c(args_list, data_list) - } + # All data_ProSpect entries are included; ParmOff's formal-matching drops wrong-component + # entries (e.g. argname_2 after stripping _1 becomes argname_2, which is not a ProSpectSED formal) + args_list = c(args_list, Data$data_ProSpect) } - outSED = ProSpect::Jansky2magAB(do.call(ProSpect::ProSpectSED, c(args_list, returnall=FALSE), quote=TRUE)) + outSED = ProSpect::Jansky2magAB(ParmOff(ProSpect::ProSpectSED, .args=c(args_list, list(returnall=FALSE)), .strip=paste0('_',i))) if(length(Data[[1]]$modellist) == 1L){ for(j in 1:Data$Nim){ Data[[j]]$modellist[[1]]$mag[i] = outSED[j] From 16b7e96e92ee5ae226d13b4ce11ee2eab76af41a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 03:10:19 +0000 Subject: [PATCH 02/10] Use ParmOff .lower/.upper/.logged for interval clamping and log-unlogging Agent-Logs-Url: https://github.com/ICRAR/ProFit/sessions/89f423ac-37f0-4d52-bd2a-dfcd8a545fec Co-authored-by: asgr <5617132+asgr@users.noreply.github.com> --- R/profitLikeModel.R | 58 ++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/R/profitLikeModel.R b/R/profitLikeModel.R index f4e8865..627afd0 100644 --- a/R/profitLikeModel.R +++ b/R/profitLikeModel.R @@ -68,36 +68,23 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, args_names = names(Data$parm_ProSpect) args_loc = match(args_names, Data$parm.names) - parm_ProSpect = parm[args_loc] - #The below is pretty much as per ProSpectSEDlike + # Build named lower/upper bound lists keyed by param name (with _i suffix) for use in loop + lower_ProSpect = if(!is.null(Data$intervals_ProSpect)) + as.list(setNames(Data$intervals_ProSpect$lo, args_names)) else NULL + upper_ProSpect = if(!is.null(Data$intervals_ProSpect)) + as.list(setNames(Data$intervals_ProSpect$hi, args_names)) else NULL - if (!is.null(Data$intervals_ProSpect)) { - parm_ProSpect = pmin( - pmax(parm_ProSpect, Data$intervals_ProSpect$lo), - Data$intervals_ProSpect$hi - ) - } - - if (!is.null(Data$logged_ProSpect)) { + # Build character vector of logged param names (with _i suffix) for use in loop + all_logged_names = if (!is.null(Data$logged_ProSpect)) { if (length(Data$logged_ProSpect) == 1) { - if (Data$logged_ProSpect) { - parm_logged = 10 ^ parm_ProSpect - } else{ - parm_logged = parm_ProSpect - } - } else{ - parm_logged = parm_ProSpect - parm_logged[Data$logged_ProSpect] = 10 ^ parm_ProSpect[Data$logged_ProSpect] + if(Data$logged_ProSpect) args_names else character(0) + } else { + args_names[Data$logged_ProSpect] } - } else{ - parm_logged = parm_ProSpect - } - - parm[args_loc] = parm_logged + } else character(0) for(i in 1:Data$Ncomp){ - args_names = names(Data$parm_ProSpect) args_names_comp = args_names[grepl(paste0('_',i), args_names)] args_loc_comp = match(args_names_comp, Data$parm.names) args_list = as.list(parm[args_loc_comp]) @@ -109,7 +96,28 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, # entries (e.g. argname_2 after stripping _1 becomes argname_2, which is not a ProSpectSED formal) args_list = c(args_list, Data$data_ProSpect) } - outSED = ProSpect::Jansky2magAB(ParmOff(ProSpect::ProSpectSED, .args=c(args_list, list(returnall=FALSE)), .strip=paste0('_',i))) + + # Filter bounds and logged names to this component, strip _i suffix for ParmOff + strip_i = paste0('_', i) + lower_i = NULL + upper_i = NULL + if(!is.null(lower_ProSpect)) { + sel = grepl(strip_i, names(lower_ProSpect)) + if(any(sel)) { + stripped_names = sub(strip_i, '', names(lower_ProSpect)[sel]) + lower_i = setNames(lower_ProSpect[sel], stripped_names) + upper_i = setNames(upper_ProSpect[sel], stripped_names) + } + } + logged_i = sub(strip_i, '', all_logged_names[grepl(strip_i, all_logged_names)]) + + outSED = ProSpect::Jansky2magAB(ParmOff(ProSpect::ProSpectSED, + .args = c(args_list, list(returnall=FALSE)), + .strip = strip_i, + .lower = lower_i, + .upper = upper_i, + .logged = logged_i + )) if(length(Data[[1]]$modellist) == 1L){ for(j in 1:Data$Nim){ Data[[j]]$modellist[[1]]$mag[i] = outSED[j] From c3bb138aa54d6b851abfe99bb3bf256f855eca70 Mon Sep 17 00:00:00 2001 From: Aaron Robotham Date: Thu, 14 May 2026 12:11:45 +0800 Subject: [PATCH 03/10] Making some progress on adding scat_scale --- R/profitLikeModel.R | 99 +++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 43 deletions(-) diff --git a/R/profitLikeModel.R b/R/profitLikeModel.R index 627afd0..5e5ae64 100644 --- a/R/profitLikeModel.R +++ b/R/profitLikeModel.R @@ -31,21 +31,32 @@ makemodel_args$calcregion = Data$calcregion makemodel_args$docalcregion = Data$usecalcregion } - model = ParmOff(profitMakeModel, .args=makemodel_args, ...) + model = ParmOff(profitMakeModel, + .args=makemodel_args, + .check = FALSE, #keep things fast + ...) return(model) } -profitLikeModel=function(parm, Data, makeplots=FALSE, +profitLikeModel=function(parm, Data, makeplots=FALSE, whichcomponents=list(sersic="all",moffat="all",ferrer="all",pointsource="all"), rough=FALSE, cmap = rev(colorRampPalette(brewer.pal(9,'RdYlBu'))(100)), errcmap=cmap, plotchisq=FALSE, maxsigma=5, model=NULL) { - + if(inherits(Data, 'list') & inherits(Data[[1]], 'profit.data')){ - + # This is MultiBand and MultiImage mode. Most of what is here is to deal with the complexities of MultiBand mode. MultiImage mode is actually pretty simple. - + parm_in = parm - + + if('scat_scale' %in% Data$parm.names){ + scat_scale = parm_in[Data$parm.names == 'scat_scale'] + }else if('log_scat_scale' %in% parm_in){ + scat_scale = 10^parm_in[Data$parm.names == 'log_scat_scale'] + }else{ + scat_scale = 1 + } + if(!is.null(Data$smooth.parm) & !is.null(Data$wave) & is.null(Data$parm_ProSpect)){ #This is the smoothed parameter MultiBand mode. Don't really use this now we have full ProSpect mode. namevec = names(Data$smooth.parm) @@ -53,28 +64,28 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, parm = .smooth_parm(parm=parm, Data$parm.names, extract=namevec[i], wave=Data$wave, func=Data$smooth.parm[[i]]) } } - + args_loc = NULL - + #This is all the new ProFuse stuff. Roughly we: #1) Find all the ProSpect related parms #2) Strip those out #3) Update the modellist with the computed magnitudes #4) Proceed as before with the reduced parm vector. - + if(!is.null(Data$parm_ProSpect)){ #This is ProSpect MultiBand mode. if(!requireNamespace("ProSpect", quietly = TRUE)){stop('The ProSpect package is required to use SED fitting!')} - + args_names = names(Data$parm_ProSpect) args_loc = match(args_names, Data$parm.names) - + # Build named lower/upper bound lists keyed by param name (with _i suffix) for use in loop lower_ProSpect = if(!is.null(Data$intervals_ProSpect)) as.list(setNames(Data$intervals_ProSpect$lo, args_names)) else NULL upper_ProSpect = if(!is.null(Data$intervals_ProSpect)) as.list(setNames(Data$intervals_ProSpect$hi, args_names)) else NULL - + # Build character vector of logged param names (with _i suffix) for use in loop all_logged_names = if (!is.null(Data$logged_ProSpect)) { if (length(Data$logged_ProSpect) == 1) { @@ -96,7 +107,7 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, # entries (e.g. argname_2 after stripping _1 becomes argname_2, which is not a ProSpectSED formal) args_list = c(args_list, Data$data_ProSpect) } - + # Filter bounds and logged names to this component, strip _i suffix for ParmOff strip_i = paste0('_', i) lower_i = NULL @@ -110,13 +121,15 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, } } logged_i = sub(strip_i, '', all_logged_names[grepl(strip_i, all_logged_names)]) - + outSED = ProSpect::Jansky2magAB(ParmOff(ProSpect::ProSpectSED, - .args = c(args_list, list(returnall=FALSE)), + .args = args_list, .strip = strip_i, .lower = lower_i, .upper = upper_i, - .logged = logged_i + .logged = logged_i, + .check = FALSE, #keep things fast + returnall = FALSE #pass via dots )) if(length(Data[[1]]$modellist) == 1L){ for(j in 1:Data$Nim){ @@ -137,7 +150,7 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, } } } - + temp = {} for(i in 1:length(Data)){ # The below executes both MultiImage (same band, lots of exposures) and MultiBand mode, since by this point the structures are the same, and the mags have been updated as needed by ProSpect for the MultiBand to work. @@ -164,22 +177,22 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, # Here we compute LL for unresolved data via comparing just the ProSpect SED photometry versus the raw aperture photometry. # Won't work well for very confused data though. The idea is this is how we reasonably add in UV and MIR/FIR flux constraints. # THE BELOW STILL NEEDS SOME CAREFUL CHECKING AS OF 2/2/22 - + # The model sum needs to computed for each model, adding together the various flux components correctly in linear flux space. - + model_sum = 0 for(j in 1:length(Data[[i]]$modellist)){ for(k in 1:length(Data[[i]]$modellist[[j]][[1]])){ model_sum = model_sum + 10^(-0.4*(Data[[i]]$modellist[[j]]$mag[k] - 8.9)) } } - + # The below object_flux and object_var are pre-computed in profuseMultiBandFound2Fit (v0.2.7) at ~L237 cutsig = (model_sum - Data[[i]]$object_flux) / Data[[i]]$object_fluxerr - - LL = dnorm(x = cutsig, log = TRUE) + + LL = dnorm(x = cutsig, mean=0, sd=scat_scale, log = TRUE) #LL = -(abs(model_sum - Data[[i]]$object_flux) / Data[[i]]$object_var)/2 #to be LL scaled - + if(Data[[1]]$algo.func=='LA' | Data[[1]]$algo.func=='LD'){ out = list(LP=LL, Dev = -2*LL, Monitor = c(LL, LL, 0)) }else{ @@ -195,11 +208,11 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, temp = c(temp, list(out)) } } - + if(Data[[1]]$algo.func=='optim' | Data[[1]]$algo.func=='CMA'){ output = sum(unlist(temp)) } - + if(Data[[1]]$algo.func=='LA' | Data[[1]]$algo.func=='LD'){ output = temp[[1]] output$LP = 0 @@ -217,21 +230,21 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, } return(output) } - + # Below is what we execute for a normal single image profit.data instance. This is classic ProFit, and the sub component of MultiBand and MultiImage modes. - + priorsum = 0 - + if(is.null(model)){ remakeout=profitRemakeModellist(parm=parm, Data=Data) modellistnew=remakeout$modellist parm=remakeout$parm - + # Calculate priors with the new versus old modellist if(length(Data$priors)>0){ priorsum=Data$priors(modellistnew,Data$modellist) } - + model = .profitLikeModelEvaluation(Data, modellistnew, rough=rough, whichcomponents=whichcomponents, model_image_buff=Data$model_buff_image) } else { stopifnot(is.list(model) && !is.null(model$z)) @@ -241,7 +254,7 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, if(!is.null(Data$region_which)) { cutim = Data$image[Data$region_which] - cutsig = Data$sigma[Data$region_which] + cutsig = Data$sigma[Data$region_which] cutmod = model$z[Data$region_which] }else{ cutim = Data$image @@ -251,7 +264,7 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, #Force like.func to be lower case: like.func = profitParseLikefunc(Data$like.func) - + #Various allowed likelihoods: isnorm = like.func == "norm" ischisq = like.func == "chisq" @@ -271,7 +284,7 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, } skewtparm = Data$skewtparm if(isnorm){ - LL=sum(dnorm(cutsig, log=TRUE)) + LL=sum(dnorm(cutsig, mean=0, sd=scat_scale, log=TRUE)) } else if(ischisq) { ndata = length(cutim) if(!exists("chisq")) chisq = sum(cutsig^2) @@ -283,7 +296,7 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, dof=max(1, min(Inf, dof, na.rm = TRUE), na.rm = TRUE) LL=sum(dt(cutsig,dof,log=TRUE)) } else if(isst) { - dstlike = function(parm,Data) { + dstlike = function(parm,Data) { LP = sum(sn::dst(Data$chi, dp=parm, log=TRUE)) return(list(LP=LP,Dev=-2*LP,Monitor=numeric(0),yhat=1,parm=parm)) } @@ -328,7 +341,7 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, } else { stop(paste0("Error: unknown likelihood function: '",like.func,"'")) } - + if(makeplots){ skylevel = 0 if(!is.null(modellistnew$sky) && !is.null(modellistnew$sky$bg) && @@ -336,7 +349,7 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, profitMakePlots(Data$image-skylevel, model$z-skylevel, Data$region, Data$sigma, cmap=cmap, errcmap=errcmap,plotchisq=plotchisq, maxsigma=maxsigma, skewtparm=skewtparm) } - + LP=as.numeric(LL+priorsum) if(Data$verbose) { toprint = parm @@ -348,17 +361,17 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, } print(toprint,digits = 5) } - + if(Data$algo.func=='check') { out = list(model=model,psf=Data$psf) if(fitst) out$skewtparm = skewtparm return(out) } - + if(Data$algo.func=='optim' | Data$algo.func=='CMA'){ return(LP) } - + if(Data$algo.func=='LA' | Data$algo.func=='LD'){ Monitor=c(LL=LL,LP=LP) if("time" %in% Data$mon.names){ @@ -379,7 +392,7 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, .smooth_parm = function(parm, parm.names, extract='mag1', wave, func=smooth.spline){ parm_loc = grep(extract,parm.names) - + parm[parm_loc] = func(log(wave),parm[parm_loc])$y return(parm) } @@ -389,9 +402,9 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, # mpeak=10^inpar[2], # mperiod=10^inpar[3], # mskew=inpar[4], -# tau_birth=10^inpar[5], -# tau_screen=10^inpar[6], -# alpha_SF_birth=inpar[7], +# tau_birth=10^inpar[5], +# tau_screen=10^inpar[6], +# alpha_SF_birth=inpar[7], # alpha_SF_screen=inpar[8], # z=0.1, # Z=Zfunc_massmap_lin, From 4e958e735bd76f05441039d9ce48f11888a202ae Mon Sep 17 00:00:00 2001 From: Aaron Robotham Date: Thu, 14 May 2026 17:30:54 +0800 Subject: [PATCH 04/10] scat_scale fix --- R/profitLikeModel.R | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/R/profitLikeModel.R b/R/profitLikeModel.R index 5e5ae64..a571674 100644 --- a/R/profitLikeModel.R +++ b/R/profitLikeModel.R @@ -49,14 +49,6 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, parm_in = parm - if('scat_scale' %in% Data$parm.names){ - scat_scale = parm_in[Data$parm.names == 'scat_scale'] - }else if('log_scat_scale' %in% parm_in){ - scat_scale = 10^parm_in[Data$parm.names == 'log_scat_scale'] - }else{ - scat_scale = 1 - } - if(!is.null(Data$smooth.parm) & !is.null(Data$wave) & is.null(Data$parm_ProSpect)){ #This is the smoothed parameter MultiBand mode. Don't really use this now we have full ProSpect mode. namevec = names(Data$smooth.parm) @@ -235,10 +227,24 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, priorsum = 0 + if('scat_scale' %in% Data$parm.names){ + sel = which(Data$parm.names == 'scat_scale') + scat_scale = parm[sel] + parm = parm[-sel] + Data$parm.names = Data$parm.names[-sel] + }else if('log_scat_scale' %in% Data$parm.names){ + sel = which(Data$parm.names == 'log_scat_scale') + scat_scale = 10^parm[sel] + parm = parm[-sel] + Data$parm.names = Data$parm.names[-sel] + }else{ + scat_scale = 1 + } + if(is.null(model)){ - remakeout=profitRemakeModellist(parm=parm, Data=Data) - modellistnew=remakeout$modellist - parm=remakeout$parm + remakeout = profitRemakeModellist(parm=parm, Data=Data) + modellistnew = remakeout$modellist + parm = remakeout$parm # Calculate priors with the new versus old modellist if(length(Data$priors)>0){ @@ -282,7 +288,9 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, #dof=interval(dof,0,Inf) dof=max(1, min(Inf, dof, na.rm = TRUE), na.rm = TRUE) } + skewtparm = Data$skewtparm + if(isnorm){ LL=sum(dnorm(cutsig, mean=0, sd=scat_scale, log=TRUE)) } else if(ischisq) { From 1d631caa5b8256f00d06a13d75771f65e61ae2c9 Mon Sep 17 00:00:00 2001 From: Aaron Robotham Date: Fri, 22 May 2026 10:17:49 +0800 Subject: [PATCH 05/10] Moves scat_scale up in function --- R/profitLikeModel.R | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/R/profitLikeModel.R b/R/profitLikeModel.R index a571674..0ca5780 100644 --- a/R/profitLikeModel.R +++ b/R/profitLikeModel.R @@ -57,6 +57,20 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, } } + if('scat_scale' %in% Data$parm.names){ + sel = which(Data$parm.names == 'scat_scale') + scat_scale = parm[sel] + parm = parm[-sel] + Data$parm.names = Data$parm.names[-sel] + }else if('log_scat_scale' %in% Data$parm.names){ + sel = which(Data$parm.names == 'log_scat_scale') + scat_scale = 10^parm[sel] + parm = parm[-sel] + Data$parm.names = Data$parm.names[-sel] + }else{ + scat_scale = 1 + } + args_loc = NULL #This is all the new ProFuse stuff. Roughly we: @@ -227,20 +241,6 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, priorsum = 0 - if('scat_scale' %in% Data$parm.names){ - sel = which(Data$parm.names == 'scat_scale') - scat_scale = parm[sel] - parm = parm[-sel] - Data$parm.names = Data$parm.names[-sel] - }else if('log_scat_scale' %in% Data$parm.names){ - sel = which(Data$parm.names == 'log_scat_scale') - scat_scale = 10^parm[sel] - parm = parm[-sel] - Data$parm.names = Data$parm.names[-sel] - }else{ - scat_scale = 1 - } - if(is.null(model)){ remakeout = profitRemakeModellist(parm=parm, Data=Data) modellistnew = remakeout$modellist From 2feed9170ff704a8259b6c34f7bf0b06fd082c84 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 22 May 2026 02:32:34 +0000 Subject: [PATCH 06/10] Fix scat_scale handling for single-image norm likelihood Agent-Logs-Url: https://github.com/ICRAR/ProFit/sessions/0e0b7f90-f28f-437e-a9e5-a7d01f46ec3f Co-authored-by: asgr <5617132+asgr@users.noreply.github.com> --- R/profitLikeModel.R | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/R/profitLikeModel.R b/R/profitLikeModel.R index 0ca5780..00e1556 100644 --- a/R/profitLikeModel.R +++ b/R/profitLikeModel.R @@ -43,6 +43,21 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, cmap = rev(colorRampPalette(brewer.pal(9,'RdYlBu'))(100)), errcmap=cmap, plotchisq=FALSE, maxsigma=5, model=NULL) { + if('scat_scale' %in% Data$parm.names){ + sel = which(Data$parm.names == 'scat_scale') + scat_scale = parm[sel] + parm = parm[-sel] + Data$parm.names = Data$parm.names[-sel] + }else if('log_scat_scale' %in% Data$parm.names){ + sel = which(Data$parm.names == 'log_scat_scale') + scat_scale = 10^parm[sel] + parm = parm[-sel] + Data$parm.names = Data$parm.names[-sel] + }else{ + scat_scale = 1 + } + scat_scale = max(scat_scale, .Machine$double.eps, na.rm=TRUE) + if(inherits(Data, 'list') & inherits(Data[[1]], 'profit.data')){ # This is MultiBand and MultiImage mode. Most of what is here is to deal with the complexities of MultiBand mode. MultiImage mode is actually pretty simple. @@ -57,20 +72,6 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, } } - if('scat_scale' %in% Data$parm.names){ - sel = which(Data$parm.names == 'scat_scale') - scat_scale = parm[sel] - parm = parm[-sel] - Data$parm.names = Data$parm.names[-sel] - }else if('log_scat_scale' %in% Data$parm.names){ - sel = which(Data$parm.names == 'log_scat_scale') - scat_scale = 10^parm[sel] - parm = parm[-sel] - Data$parm.names = Data$parm.names[-sel] - }else{ - scat_scale = 1 - } - args_loc = NULL #This is all the new ProFuse stuff. Roughly we: From 960af9982020c79f99f0a6f0c549135df5f6c624 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 22 May 2026 02:40:02 +0000 Subject: [PATCH 07/10] Tighten ProSpect component suffix matching in profitLikeModel Agent-Logs-Url: https://github.com/ICRAR/ProFit/sessions/69adf167-357e-4a31-b8d9-ddb5b06abbab Co-authored-by: asgr <5617132+asgr@users.noreply.github.com> --- R/profitLikeModel.R | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/R/profitLikeModel.R b/R/profitLikeModel.R index 00e1556..f2ca29e 100644 --- a/R/profitLikeModel.R +++ b/R/profitLikeModel.R @@ -103,7 +103,9 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, } else character(0) for(i in 1:Data$Ncomp){ - args_names_comp = args_names[grepl(paste0('_',i), args_names)] + suffix_i = paste0('_', i) + suffix_i_re = paste0(suffix_i, '$') + args_names_comp = args_names[grepl(suffix_i_re, args_names)] args_loc_comp = match(args_names_comp, Data$parm.names) args_list = as.list(parm[args_loc_comp]) names(args_list) = args_names_comp # names retain _i suffix; ParmOff .strip removes it below @@ -114,24 +116,22 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, # entries (e.g. argname_2 after stripping _1 becomes argname_2, which is not a ProSpectSED formal) args_list = c(args_list, Data$data_ProSpect) } - # Filter bounds and logged names to this component, strip _i suffix for ParmOff - strip_i = paste0('_', i) lower_i = NULL upper_i = NULL if(!is.null(lower_ProSpect)) { - sel = grepl(strip_i, names(lower_ProSpect)) + sel = grepl(suffix_i_re, names(lower_ProSpect)) if(any(sel)) { - stripped_names = sub(strip_i, '', names(lower_ProSpect)[sel]) + stripped_names = sub(suffix_i_re, '', names(lower_ProSpect)[sel]) lower_i = setNames(lower_ProSpect[sel], stripped_names) upper_i = setNames(upper_ProSpect[sel], stripped_names) } } - logged_i = sub(strip_i, '', all_logged_names[grepl(strip_i, all_logged_names)]) + logged_i = sub(suffix_i_re, '', all_logged_names[grepl(suffix_i_re, all_logged_names)]) outSED = ProSpect::Jansky2magAB(ParmOff(ProSpect::ProSpectSED, .args = args_list, - .strip = strip_i, + .strip = suffix_i_re, .lower = lower_i, .upper = upper_i, .logged = logged_i, From a682e6ba97f0b557325d2a1c414d56643884a26d Mon Sep 17 00:00:00 2001 From: Aaron Robotham Date: Fri, 22 May 2026 17:04:04 +0800 Subject: [PATCH 08/10] Working locally now (need to remove and add back the scat_scale). --- R/profitLikeModel.R | 28 +++++++++++++++---------- vignettes/ProFit-Galaxy-Fit-Example.Rmd | 2 +- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/R/profitLikeModel.R b/R/profitLikeModel.R index f2ca29e..8738b81 100644 --- a/R/profitLikeModel.R +++ b/R/profitLikeModel.R @@ -47,12 +47,12 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, sel = which(Data$parm.names == 'scat_scale') scat_scale = parm[sel] parm = parm[-sel] - Data$parm.names = Data$parm.names[-sel] + #Data$parm.names = Data$parm.names[-sel] }else if('log_scat_scale' %in% Data$parm.names){ sel = which(Data$parm.names == 'log_scat_scale') scat_scale = 10^parm[sel] parm = parm[-sel] - Data$parm.names = Data$parm.names[-sel] + #Data$parm.names = Data$parm.names[-sel] }else{ scat_scale = 1 } @@ -103,9 +103,8 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, } else character(0) for(i in 1:Data$Ncomp){ - suffix_i = paste0('_', i) - suffix_i_re = paste0(suffix_i, '$') - args_names_comp = args_names[grepl(suffix_i_re, args_names)] + suffix_i = paste0('_', i, '$') + args_names_comp = args_names[grepl(suffix_i, args_names)] args_loc_comp = match(args_names_comp, Data$parm.names) args_list = as.list(parm[args_loc_comp]) names(args_list) = args_names_comp # names retain _i suffix; ParmOff .strip removes it below @@ -120,23 +119,24 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, lower_i = NULL upper_i = NULL if(!is.null(lower_ProSpect)) { - sel = grepl(suffix_i_re, names(lower_ProSpect)) + sel = grepl(suffix_i, names(lower_ProSpect)) if(any(sel)) { - stripped_names = sub(suffix_i_re, '', names(lower_ProSpect)[sel]) + stripped_names = sub(suffix_i, '', names(lower_ProSpect)[sel]) lower_i = setNames(lower_ProSpect[sel], stripped_names) upper_i = setNames(upper_ProSpect[sel], stripped_names) } } - logged_i = sub(suffix_i_re, '', all_logged_names[grepl(suffix_i_re, all_logged_names)]) + logged_i = sub(suffix_i, '', all_logged_names[grepl(suffix_i, all_logged_names)]) outSED = ProSpect::Jansky2magAB(ParmOff(ProSpect::ProSpectSED, .args = args_list, - .strip = suffix_i_re, + .strip = suffix_i, .lower = lower_i, .upper = upper_i, .logged = logged_i, .check = FALSE, #keep things fast - returnall = FALSE #pass via dots + .rem_args = c('scat_scale', 'log_scat_scale'), + returnall = FALSE, #pass via dots )) if(length(Data[[1]]$modellist) == 1L){ for(j in 1:Data$Nim){ @@ -247,9 +247,15 @@ profitLikeModel=function(parm, Data, makeplots=FALSE, modellistnew = remakeout$modellist parm = remakeout$parm + if('scat_scale' %in% Data$parm.names){ + parm = c(parm, scat_scale) + }else if('log_scat_scale' %in% Data$parm.names){ + parm = c(parm, log10(scat_scale)) + } + # Calculate priors with the new versus old modellist if(length(Data$priors)>0){ - priorsum=Data$priors(modellistnew,Data$modellist) + priorsum = Data$priors(modellistnew,Data$modellist) } model = .profitLikeModelEvaluation(Data, modellistnew, rough=rough, whichcomponents=whichcomponents, model_image_buff=Data$model_buff_image) diff --git a/vignettes/ProFit-Galaxy-Fit-Example.Rmd b/vignettes/ProFit-Galaxy-Fit-Example.Rmd index 2c8aab3..19ec710 100644 --- a/vignettes/ProFit-Galaxy-Fit-Example.Rmd +++ b/vignettes/ProFit-Galaxy-Fit-Example.Rmd @@ -351,7 +351,7 @@ First make sure that the `cmaeshpc` package is installed: ```{r, eval=FALSE} library(devtools) -install_github('taranu/cmaeshpc') +install_github('asgr/cmaeshpc') ``` It is recommended to use narrower priors than the very broad ones specified above to speed up convergence: From 5987889e9211b17c26d9fa594a237fdfaaa5af90 Mon Sep 17 00:00:00 2001 From: Aaron Robotham Date: Mon, 25 May 2026 15:00:01 +0800 Subject: [PATCH 09/10] Makevar updates removing C++11 --- src/Makevars.in | 2 -- src/Makevars.win | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/Makevars.in b/src/Makevars.in index 4154c9b..5898b23 100644 --- a/src/Makevars.in +++ b/src/Makevars.in @@ -1,5 +1,3 @@ -CXX_STD = CXX11 - PKG_CPPFLAGS = -Ilibprofit/src -Dprofit_EXPORTS PKG_CXXFLAGS = @profit_CXXFLAGS@ PKG_LIBS = @profit_LIBS@ diff --git a/src/Makevars.win b/src/Makevars.win index 663662e..89ed6fb 100644 --- a/src/Makevars.win +++ b/src/Makevars.win @@ -1,5 +1,3 @@ -CXX_STD = CXX11 - PKG_CPPFLAGS = -Ilibprofit/src -Dprofit_EXPORTS PKG_LIBS = From 99557c18234c7ed02a92bc9b574f4d01ba2bef7a Mon Sep 17 00:00:00 2001 From: Aaron Robotham Date: Tue, 26 May 2026 15:38:12 +0800 Subject: [PATCH 10/10] Version bump --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index ea7cf29..b130c12 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: ProFit Type: Package Title: Fit Projected 2D Profiles to Galaxy Images -Version: 2.6.4 -Date: 2026-05-13 +Version: 2.7.0 +Date: 2026-05-26 Authors@R: c( person(given='Aaron', family='Robotham', email='aaron.robotham@uwa.edu.au', role=c('aut', 'cre'), comment=c(ORCID='0000-0003-0429-3579')),