Skip to content

Commit 71a50cc

Browse files
committed
Version bump
Merge branch 'master' of https://github.com/asgr/ProFound # Conflicts: # DESCRIPTION
2 parents 543c2ee + edb34c5 commit 71a50cc

10 files changed

Lines changed: 90 additions & 120 deletions

DESCRIPTION

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package: ProFound
22
Type: Package
33
Title: Photometry Tools
4-
Version: 1.34.3
4+
Version: 1.34.5
55
Date: 2026-03-04
66
Author: Aaron Robotham
77
Maintainer: Aaron Robotham <aaron.robotham@uwa.edu.au>
@@ -10,6 +10,14 @@ License: LGPL-3
1010
Depends: R (>= 3.1), Rfits (>= 1.8.0), magicaxis (>= 2.0.8), Rcpp (>= 1.0.2)
1111
Imports: data.table, celestial (>= 1.4.1), foreach, matrixStats, doParallel
1212
Suggests: ProFit, knitr, rmarkdown, EBImage, imager, LaplacesDemon, Rfast, Rfast2, fastmatch, snow, doSNOW, bigmemory, mvtnorm, Rwcs, Highlander (>= 0.1.7), ProPane, plotrix, RANN
13+
Remotes:
14+
asgr/cmaeshpc,
15+
asgr/Highlander,
16+
asgr/imager,
17+
asgr/LaplacesDemon,
18+
ICRAR/ProFit,
19+
asgr/Rfits,
20+
asgr/Rwcs
1321
VignetteBuilder: knitr
1422
LinkingTo: Rcpp
1523
NeedsCompilation: yes

README.md

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -10,62 +10,6 @@ Core package containing all the tools for simple and advanced source extraction.
1010

1111
## Installation
1212

13-
### Getting R
14-
15-
First things first, you will probably want to install a recent version of **R** that lets you build packages from source. The advantage of choosing this route is you can then update bleeding edge versions directly from GitHub. If you rely on the pre-built binaries on CRAN you might be waiting much longer.
16-
17-
#### Mac
18-
19-
For Mac just get the latest binaries from the **R** project pages:
20-
21-
<https://cloud.r-project.org/bin/macosx/>
22-
23-
#### Windows
24-
25-
For Windows just get the latest binaries from the **R** project pages:
26-
27-
<https://cloud.r-project.org/bin/windows/>
28-
29-
#### Linux
30-
31-
Debian: `sudo apt-get install r-base r-base-dev`
32-
33-
Fedora: `sudo yum install R`
34-
35-
Suse: More of a pain, see here <https://cloud.r-project.org/bin/linux/suse/README.html>
36-
37-
Ubuntu: `sudo apt-get install r-base-dev`
38-
39-
All the info on binaries is here: <https://cloud.r-project.org/bin/linux/>
40-
41-
If you have a poorly supported version of Linux (e.g. CentOS) you will need to install **R** from source with the development flags (this bit is important). You can read more here: <https://cloud.r-project.org/sources.html>
42-
43-
Now you have the development version of **R** installed (hopefully) I would also suggest you get yourself **R-Studio**. It is a very popular and well maintained **R** IDE that gives you a lot of helpful shortcuts to scripting and analysing with **R**. The latest version can be grabbed from <https://www.rstudio.com/products/rstudio/> where you almost certainly want the free Desktop version.
44-
45-
If you wish to use the command line version of **R** on Mac (why?!) then you might need to separately install **XQuartz** and set the DISPLAY system variable via something like export DISPLAY=:0 (this is not an issue for most people however).
46-
47-
### Build Tools
48-
49-
Some of **ProFound** requires compiling, so here is what you might need depending on your platform.
50-
51-
#### Linux Users
52-
53-
You know what you are doing. You do you!
54-
55-
#### Mac Users
56-
57-
You should not need to install separate compilers with any **R** after v4.0.0, but in case you are stuck on a museum version you can follow the extra instructions here:
58-
59-
[https://mac.r-project.org/tools/](https://mac.r-project.org/tools/)
60-
61-
#### Windows Users
62-
63-
Windows users might need to go through a couple of additional steps depending on how their system is set up, but most likely you will need to at least install *Rtools* for later parts of this course, which are available at [https://cran.r-project.org/bin/windows/Rtools/](https://cran.r-project.org/bin/windows/Rtools/) and follow the instructions about how to link these into your system path. You will know it is working because the following will not be empty:
64-
65-
```R
66-
Sys.which("make")
67-
```
68-
6913
### Getting ProFound
7014

7115
Source installation from GitHub should be easy:

src/akima.cpp

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -306,11 +306,24 @@ void interpolateLinearGrid(NumericVector xseq, NumericVector yseq, NumericMatrix
306306
int ncol=tempmat_sky.ncol();
307307
int nrow=tempmat_sky.nrow();
308308

309+
// Precompute y-bracket indices for all output columns (independent of row i)
310+
std::vector<int> top_indices(myynpts, -1), bottom_indices(myynpts, -1);
311+
for (int j = 1; j <= myynpts; j++) {
312+
double y = -0.5+j;
313+
for (int jj = 1; jj < ncol; jj++) {
314+
if (myy[jj-1] <= y && myy[jj] >= y) {
315+
top_indices[j-1] = jj-1;
316+
bottom_indices[j-1] = jj;
317+
break;
318+
}
319+
}
320+
}
321+
309322
// For each vertical row
310323
for (int i = 1; i <= myxnpts; i++) {
311324
// For a spline to interpolate vertically along the elements of the row
312325
double x = -0.5+i;
313-
// find the left and right index ibnto xseq
326+
// find the left and right index into xseq
314327
int left_index = -1;
315328
int right_index = -1;
316329
for (int ii = 1; ii < nrow; ii++) {
@@ -321,34 +334,28 @@ void interpolateLinearGrid(NumericVector xseq, NumericVector yseq, NumericMatrix
321334
}
322335
}
323336

324-
//Rcpp::Rcout << "x="<<x<<" xindex="<<left_index<<" "<<right_index<<"\n";
325-
//Rcpp::Rcout << "x="<<x<<" xleft="<<myx[left_index]<<" "<<myx[right_index]<<"\n";
326-
int top_index = -1;
327-
int bottom_index = -1;
337+
if (left_index < 0) continue;
338+
const double xlambda = (x-myx[left_index])/(myx[right_index]-myx[left_index]);
339+
328340
for (int j = 1; j <= myynpts; j++) {
341+
int top_index = top_indices[j-1];
342+
int bottom_index = bottom_indices[j-1];
343+
if (top_index < 0) continue;
344+
345+
// p1...p2
346+
// . .
347+
// . .
348+
// p3...p4
349+
double p1 = tempmat_sky(left_index,top_index);
350+
double p2 = tempmat_sky(right_index,top_index);
351+
double p3 = tempmat_sky(left_index,bottom_index);
352+
double p4 = tempmat_sky(right_index,bottom_index);
353+
329354
double y = -0.5+j;
330-
for (int jj = 1; jj < ncol; jj++) {
331-
if (myy[jj-1] <= y && myy[jj] >= y) {
332-
top_index = jj-1;
333-
bottom_index = jj;
334-
// p1...p2
335-
// . .
336-
// . .
337-
// p3...p4
338-
double p1 = tempmat_sky(left_index,top_index);
339-
double p2 = tempmat_sky(right_index,top_index);
340-
double p3 = tempmat_sky(left_index,bottom_index);
341-
double p4 = tempmat_sky(right_index,bottom_index);
342-
343-
double xlambda = (x-myx[left_index])/(myx[right_index]-myx[left_index]);
344-
double ylambda = (y-myy[top_index])/(myy[bottom_index]-myy[top_index]);
345-
double ztop = p1 * (1.0-xlambda) + p2 * xlambda;
346-
double zbottom = p3 * (1.0-xlambda) + p4 * xlambda;
347-
output(i-1,j-1) = ztop * (1.0-ylambda) +zbottom * ylambda;
348-
//Rcpp::Rcout << "y="<<y<<" yindex="<<top_index<<" "<<bottom_index<<" "<<p1<<" "<<p2<<" "<<p3<<" "<<p4<<" result="<<output(i-1,j-1)<<"\n";
349-
break;
350-
}
351-
}
355+
double ylambda = (y-myy[top_index])/(myy[bottom_index]-myy[top_index]);
356+
double ztop = p1 * (1.0-xlambda) + p2 * xlambda;
357+
double zbottom = p3 * (1.0-xlambda) + p4 * xlambda;
358+
output(i-1,j-1) = ztop * (1.0-ylambda) +zbottom * ylambda;
352359
}
353360
}
354361
}

src/aper_cover.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,7 @@ NumericVector profoundAperCover(NumericVector x,
7979
const double delta_2 = (delta_x * delta_x) + (delta_y * delta_y);
8080
result[i] = pixelCoverAper(delta_x, delta_y, delta_2,
8181
rad_2, rad_min_2, rad_max_2, depth);
82-
} else {
83-
result[i] = 0.0;
8482
}
85-
} else {
86-
result[i] = 0.0;
8783
}
8884
}
8985

@@ -194,9 +190,13 @@ NumericMatrix profoundAperWeight(NumericVector cx,
194190
const double PC_temp = pixelCoverAper(delta_x, delta_y, delta_2,
195191
rad_2, rad_min_2, rad_max_2, depth);
196192
if(rad_re[k] == 0){
197-
weight(i,j) += wt_use[k] * PC_temp;
193+
double cover = wt_use[k] * PC_temp;
194+
#pragma omp atomic
195+
weight(i,j) += cover;
198196
}else{
199-
weight(i,j) += wt_use[k] * PC_temp * exp(-bn[k]*pow(sqrt(delta_2) / rad_re[k], 1/nser[k]));
197+
double cover = wt_use[k] * PC_temp * exp(-bn[k]*pow(sqrt(delta_2) / rad_re[k], 1/nser[k]));
198+
#pragma omp atomic
199+
weight(i,j) += cover;
200200
}
201201
}
202202
}

src/ellip_cover.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,7 @@ NumericVector profoundEllipCover(NumericVector x, NumericVector y, double cx, do
8585
}else if(delta_2 < rad_plus * rad_plus){
8686
result[i] = pixelCoverEllip(delta_x, delta_y, x_term, y_term, xy_term, depth);
8787
}
88-
} else {
89-
result[i] = 0.0;
9088
}
91-
} else {
92-
result[i] = 0.0;
9389
}
9490
}
9591

@@ -229,18 +225,25 @@ NumericMatrix profoundEllipWeight(NumericVector cx,
229225
const double delta_2 = (delta_x * delta_x) + (delta_y * delta_y);
230226
if(rad_re[k] == 0){
231227
if(delta_2 < semi_min_min * semi_min_min){
228+
#pragma omp atomic
232229
weight(i,j) += wt_use[k];
233230
}else if(delta_2 < rad_plus * rad_plus){
234-
weight(i,j) += wt_use[k] * pixelCoverEllip(delta_x, delta_y, x_term, y_term, xy_term, depth);
231+
double cover = wt_use[k] * pixelCoverEllip(delta_x, delta_y, x_term, y_term, xy_term, depth);
232+
#pragma omp atomic
233+
weight(i,j) += cover;
235234
}
236235
}else{
237236
const double mod_x = (delta_x * cos_ang + delta_y * sin_ang) / axrat_loc;
238237
const double mod_y = (-delta_x * sin_ang + delta_y * cos_ang);
239238
const double mod_delta_2 = (mod_x * mod_x) + (mod_y * mod_y);
240239
if(delta_2 < semi_min_min * semi_min_min){
241-
weight(i,j) += wt_use[k] * exp(-bn[k]*pow(sqrt(mod_delta_2) / rad_re[k], 1/nser[k]));
240+
double cover = wt_use[k] * exp(-bn[k]*pow(sqrt(mod_delta_2) / rad_re[k], 1/nser[k]));
241+
#pragma omp atomic
242+
weight(i,j) += cover;
242243
}else if(delta_2 < rad_plus * rad_plus){
243-
weight(i,j) += wt_use[k] * pixelCoverEllip(delta_x, delta_y, x_term, y_term, xy_term, depth) * exp(-bn[k]*pow(sqrt(mod_delta_2) / rad_re[k], 1/nser[k]));
244+
double cover = wt_use[k] * pixelCoverEllip(delta_x, delta_y, x_term, y_term, xy_term, depth) * exp(-bn[k]*pow(sqrt(mod_delta_2) / rad_re[k], 1/nser[k]));
245+
#pragma omp atomic
246+
weight(i,j) += cover;
244247
}
245248
}
246249
}

src/skygrid.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -233,28 +233,25 @@ Rcpp::NumericVector Cadacs_FindSkyCellValues(
233233

234234
// Rcpp::Rcout << skyN << "\n";
235235

236-
Rcpp::NumericVector vec(skyN);
237-
int k=0;
236+
std::vector<double> vec;
237+
vec.reserve(skyN);
238238
for (int j = sscol; j <= eecol; j++) {
239239
int ii=(j-1)*nrow+(ssrow-1);
240240
for (int i = ssrow; i <= eerow; i++,ii++) {
241-
//Rcpp::Rcout << i << "\n";
242-
//Rcpp::Rcout << ii << "\n";
243241
if ((iiobjects!=NULL)) {
244242
if (iiobjects[ii]==0 && (iimask==NULL || iimask[ii]==0)) {
245-
vec[k++] = iiimage[ii];
243+
vec.push_back(iiimage[ii]);
246244
}
247245
} else if (iimask!=NULL) {
248246
if (iimask[ii]==0) {
249-
vec[k++] = iiimage[ii];
247+
vec.push_back(iiimage[ii]);
250248
}
251249
} else {
252-
vec[k++] = iiimage[ii];
250+
vec.push_back(iiimage[ii]);
253251
}
254252
}
255253
}
256-
// Rcpp::Rcout << vec[k-1] << k << " FINE!\n";
257-
return vec;
254+
return Rcpp::NumericVector(vec.begin(), vec.end());
258255
}
259256

260257
//==================================================================================

src/sum_segim.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,36 @@ NumericVector profoundSegimFlux(NumericMatrix image, NumericMatrix segim, int nt
1414
NumericVector fluxes(max_seg, 0.0);
1515

1616
#ifdef _OPENMP
17-
// Parallelize the main loop
18-
#pragma omp parallel for schedule(static) num_threads(nthreads)
19-
#endif
17+
#pragma omp parallel num_threads(nthreads)
18+
{
19+
// Thread-local copy to avoid data races on shared fluxes
20+
NumericVector local_fluxes(max_seg, 0.0);
21+
#pragma omp for schedule(static)
22+
for (int i = 0; i < nrow; ++i) {
23+
for (int j = 0; j < ncol; ++j) {
24+
if(segim(i, j) > 0){
25+
if(!NumericMatrix::is_na(image(i, j))){
26+
local_fluxes[segim(i, j) - 1] += image(i, j);
27+
}
28+
}
29+
}
30+
}
31+
#pragma omp critical
32+
for (int k = 0; k < max_seg; ++k) {
33+
fluxes[k] += local_fluxes[k];
34+
}
35+
}
36+
#else
2037
for (int i = 0; i < nrow; ++i) {
2138
for (int j = 0; j < ncol; ++j) {
2239
if(segim(i, j) > 0){
2340
if(!NumericMatrix::is_na(image(i, j))){
24-
fluxes(segim(i, j) - 1) += image(i, j);
41+
fluxes[segim(i, j) - 1] += image(i, j);
2542
}
2643
}
2744
}
2845
}
46+
#endif
2947

3048
return fluxes;
3149
}

src/this_in_that.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ LogicalVector vec_this_in_vec_that(IntegerVector vec_this, IntegerVector vec_tha
1212
LogicalVector ref_ID(max(vec_that) + 1, false);
1313
LogicalVector result(vec_this.size(), invert);
1414

15-
#ifdef _OPENMP
16-
// Parallelize the main loop
17-
#pragma omp parallel for schedule(static) num_threads(nthreads)
18-
#endif
1915
for (int i = 0; i < vec_that.size(); ++i) {
2016
if (!IntegerVector::is_na(vec_that[i])) {
2117
ref_ID[vec_that[i]] = true;
@@ -53,9 +49,6 @@ LogicalMatrix mat_this_in_vec_that(IntegerMatrix mat_this, IntegerVector vec_tha
5349
LogicalMatrix result(mat_this.nrow(), mat_this.ncol());
5450

5551
// Populate the reference vector
56-
#ifdef _OPENMP
57-
#pragma omp parallel for schedule(static) num_threads(nthreads)
58-
#endif
5952
for (int i = 0; i < vec_that.size(); ++i) {
6053
if (!IntegerVector::is_na(vec_that[i])) {
6154
ref_ID[vec_that[i]] = true;

vignettes/ProFound-Source-Finding.Rmd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ The **ProFound** source finding and image utilities suite covers the following f
3434
- profoundMakeSegimPropagate: Propagate segmentation map segments over adjacent sky pixels
3535
- profoundMakeSigma: Make a Sigma Map
3636
- profoundMakeSkyMap: Calculate coarse sky maps
37-
- profoundMakeStack: Create a stacked image
37+
- propaneStackFlatInVar (ProPane): Create an inverse-variance weighted stacked image
3838
- profoundPixelCorrelation: Calculate pixel-to-pixel correlation and 2D image FFT
3939
- profoundSegimGroup: Find the IDs of groups of touching segments
4040
- profoundSegimMerge: Optimally merge segmentation maps

vignettes/ProFound-Stack-Images.Rmd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ If you have many images of the same area (even in different bands) a photometric
3737

3838
To convince yourself consider you have 8 exposures with sky RMS equal to 16 originally: 4 you combine, so the sky RMS becomes $\frac{1}{\sqrt{\frac{1}{16^2}+\frac{1}{16^2}+\frac{1}{16^2}+\frac{1}{16^2}}}=\frac{1}{\sqrt{\frac{4}{16^2}}}=8$. Now later on you want to combine the 5 images you have. Clearly the optimal weighting you can possibly get will be $\frac{1}{\sqrt{\frac{8}{16^2}}}=\frac{8}{\sqrt{2}}=5.65$ (the direct stack of the original 8 images). With our already stacked image added to our 4 others we can achieve the same S/N by weighting our stacks by the inverse variance: $\frac{1}{\sqrt{\frac{1}{16^2}+\frac{1}{16^2}+\frac{1}{16^2}+\frac{1}{16^2}+\frac{1}{8^2}}}=\frac{1}{\sqrt{\frac{4}{16^2}+\frac{1}{8^2}}}=\frac{1}{\sqrt{\frac{8}{16^2}}}=\frac{8}{\sqrt{2}}=5.65$.
3939

40-
**ProFound** comes with a handy function that does all the weight-watching for us called **profoundMakeStack**. In this vignette we will make a simulated image (with a trivially predictable improvement in S/N) and check to see that our stacking behaves as expected.
40+
**ProPane** comes with a handy function that does all the weight-watching for us called **propaneStackFlatInVar**. In this vignette we will make a simulated image (with a trivially predictable improvement in S/N) and check to see that our stacking behaves as expected.
4141

42-
First we generate a random image with 200 stars and 200 extended sources. The value used roughly correspoond to the source densities and magnitude distributions you might expect to find in a Z-band VIKING frame (this was used to derive the image statistics).
42+
First we generate a random image with 200 stars and 200 extended sources. The value used roughly correspond to the source densities and magnitude distributions you might expect to find in a Z-band VIKING frame (this was used to derive the image statistics).
4343

4444
```{r, eval=evalglobal}
4545
set.seed(666)

0 commit comments

Comments
 (0)