ProFound-Source-Finding

Aaron Robotham

2017-12-07

Introduction to ProFound Functions

The ProFound source finding and image utilites suite covers the following functions:

Very High Level

High Level

Mid Level

Low Level

Basic ProFound Usage

The profoundProFound function might be the only function many people need to use in order to extract photometry from a target image. In brief, in fully automatic mode using default option, the basic code flow of the source extraction is as follows:

  1. Make a rough sky map
  2. Using this rough sky map, make an initial segmentation map
  3. Using this segmentation map, make a better sky map
  4. Using this better sky map, extract basic photometric properties
  5. Using the current segmentation map, dilate segments and re-measure photometric properties for the new image segments (by default it iterates six times)
  6. Using the iterative dilation statistics, every object is checked for convergence (by default convergence of flux is used)
  7. Make final segmentation map by combining the segments when each source has converged in flux
  8. Make a conservative object mask by aggressively dilating the final segmentation map
  9. Using this conservative objects mask make a final sky map
  10. Using the final segmentation map and the final sky map compute the final comprehensive photometric properties
  11. Return a list containing the input image pixel-matched final segmentation map (called segim), the pre-dilation segmentation map (segim_orig) , the binary object/sky mask (objects), the conservatively dilated binary object/sky mask (objects_redo), the sky image (sky), the sky-RMS image (skyRMS) and the effective surface brightness limit image (SBlim)
  12. Return the data-frame of photometric properties for every detected source (segstats)

Some other simple properties are passed through and included in the output of ProFound: the header (header) if it is attached to the input image, the magnitude zero point specified (magzero), the gain in electrons per astronomical data unit (gain), the pixel scale in arc-seconds per pixel (pixscale) and finally the full function call (call).

Get the latest version of ProFound and ProFit:

library(devtools)
install_github('asgr/ProFound')

Load some libraries:

library(ProFound)

First read in some data.

image=readFITS(system.file("extdata", 'VIKING/mystery_VIKING_Z.fits',package="ProFound"))

Give it a quick look:

magimageWCS(image)

A basic example of the lower level profoundMakeSegim versus the higher level profoundProFound:

out_segim=segim=profoundMakeSegim(image$imDat, magzero=30, pixscale=0.339, header=image$hdr, plot=TRUE)

out_profound=profoundProFound(image, magzero=30, verbose=TRUE, plot=TRUE)
## Running ProFound:
## Supplied image contains image and header components
## Supplied image is 356 x 356 pixels
## Extracted pixel scale from header provided: 0.339 asec/pixel
## Supplied image is 2.011 x 2.011 amin,  0.001 deg-sq
## Making initial sky map - 0.003 sec
##  - Sky statistics :
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
## -2.3257 -0.1157  0.5354  0.5499  1.0154  4.0443
##  - Sky-RMS statistics :
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   8.318   8.915   9.122   9.121   9.273   9.882
## Making initial segmentation image - 0.218 sec
##  - Running MakeSegim:
##  - Skipping making initial local estimate of the sky - User provided sky
##  - Skipping making initial local estimate of the sky RMS - User provided sky RMS
##  - Smoothing the image - 0.004 sec
##  - Watershed de-blending - 0.013 sec
##  - Skipping segmentation plot - plot set to FALSE
##  - Skipping making final local estimate of the sky - User provided sky
##  - Skipping making initial local estimate of the sky RMS - User provided sky RMS
##  - Skipping segmentation statistics - segstats set to FALSE or no segments
##  - MakeSegim is finished! - 0.043 sec
## Doing initial aggressive dilation - 0.263 sec
##  - Running MakeSegimDilate:
##  - Dilating segments - 0.001 sec
##  - Skipping segmentation statistics - segstats set to FALSE
##  - profoundMakeSegimDilate is finished! - 0.039 sec
## Making better sky map - 0.304 sec
##  - Sky statistics :
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
## -2.32792 -0.73111 -0.42721 -0.45022 -0.03966  0.41956
##  - Sky-RMS statistics :
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   8.317   8.697   8.799   8.822   8.982   9.199
## Calculating initial segstats - 0.491 sec
## Doing dilations:
## Iteration 1 of 6 - 0.533 sec
##  - Running MakeSegimDilate:
##  - Dilating segments - 0.002 sec
##  - Calculating segstats - 0.018 sec
##  - profoundMakeSegimDilate is finished! - 0.055 sec
## Iteration 2 of 6 - 0.589 sec
##  - Running MakeSegimDilate:
##  - Dilating segments - 0.002 sec
##  - Calculating segstats - 0.019 sec
##  - profoundMakeSegimDilate is finished! - 0.14 sec
## Iteration 3 of 6 - 0.731 sec
##  - Running MakeSegimDilate:
##  - Dilating segments - 0.001 sec
##  - Calculating segstats - 0.015 sec
##  - profoundMakeSegimDilate is finished! - 0.056 sec
## Iteration 4 of 6 - 0.79 sec
##  - Running MakeSegimDilate:
##  - Dilating segments - 0.002 sec
##  - Calculating segstats - 0.018 sec
##  - profoundMakeSegimDilate is finished! - 0.063 sec
## Iteration 5 of 6 - 0.855 sec
##  - Running MakeSegimDilate:
##  - Dilating segments - 0.002 sec
##  - Calculating segstats - 0.02 sec
##  - profoundMakeSegimDilate is finished! - 0.071 sec
## Iteration 6 of 6 - 0.927 sec
##  - Running MakeSegimDilate:
##  - Dilating segments - 0.002 sec
##  - Calculating segstats - 0.02 sec
##  - profoundMakeSegimDilate is finished! - 0.078 sec
## Finding CoG convergence - 1.007 sec
## Constructing final segim - 1.01 sec
## Doing final aggressive dilation - 1.067 sec
##  - Running MakeSegimDilate:
##  - Dilating segments - 0.001 sec
##  - Skipping segmentation statistics - segstats set to FALSE
##  - profoundMakeSegimDilate is finished! - 0.028 sec
## Making final sky map - 1.097 sec
##  - Sky statistics :
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
## -2.3270 -0.7348 -0.5039 -0.4977 -0.1780  0.5313
##  - Sky-RMS statistics :
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   8.324   8.660   8.779   8.798   8.969   9.195
## Calculating final segstats for 86 objects - 1.257 sec
##  - magzero = 30
##  - gain = NULL (ignored)
##  - pixscale = 0.339
##  - rotstats = FALSE
##  - boundstats = FALSE
## Plotting segments - 1.312 sec
## ProFound is finished! - 2.809 sec

Notice in the two outputs (the first being profoundMakeSegim, the second being profoundProFound) that some segment have converged quickly (i.e. not grown much) but others have expanded a lot in order to capture all the flux present. profoundProFound in default mode with modern survey imaging data tends to extract very close to a true total magnitude, without too much error introduced by sky noise (a consequence of over-growing apertures).

Because it was run in verbose mode, the major profoundProFound steps mentioned above were printed out. For large images (a few thousand by a few thousand pixels plus) this is useful since it can take a few minutes to run with all the bells and whistles turned on, and it is nice to see it making progress. Note for more than a couple of hundred sources, you almost certainly do not want to plot the output, since this will be slow.

Note because we parsed profoundProFound a header we have RA and Dec coordinates in the photometric properties data-frame. We also parsed the appropriate magnitude zero-point and pixel scale so the mag properties are correctly scaled, and R/R50/R90 are in arc-seconds rather than pixels. It is is worth checking the output:

out_profound$segstats[1:10,]
##    segID uniqueID      xcen       ycen  xmax  ymax    RAcen    Deccen
## 1      1   222149 220.79105 148.792517 221.5 148.5 352.2866 -31.82505
## 2      2   227142 226.54757 140.893807 226.5 141.5 352.2860 -31.82579
## 3      3   194148 194.58182 147.245430 193.5 147.5 352.2895 -31.82519
## 4      4   122001 120.67586   2.229448 121.5   0.5 352.2977 -31.83885
## 5      5   175133 174.83841 132.824109 174.5 132.5 352.2917 -31.82655
## 6      6   178179 177.03286 179.329142 177.5 178.5 352.2915 -31.82217
## 7      7   175257 174.68049 257.602867 174.5 256.5 352.2918 -31.81480
## 8      8   155320 153.90857 319.910944 154.5 319.5 352.2941 -31.80894
## 9      9   149074 148.52417  73.628734 148.5  73.5 352.2947 -31.83213
## 10    10    48308  48.11695 307.182775  47.5 307.5 352.3058 -31.81013
##       RAmax    Decmax        sep        flux      mag     cenfrac
## 1  352.2866 -31.82508 0.25998956 2790717.014 13.88571 0.033702410
## 2  352.2860 -31.82574 0.20613114 1175345.490 14.82459 0.028589705
## 3  352.2897 -31.82517 0.37675542   71955.949 17.85733 0.024069923
## 4  352.2976 -31.83901 0.64944779    4781.655 20.80105 0.069507552
## 5  352.2918 -31.82658 0.15884957   30310.657 18.79601 0.008326382
## 6  352.2914 -31.82225 0.32261925   42012.730 18.44155 0.005392862
## 7  352.2918 -31.81491 0.37884550    8243.555 20.20971 0.027012702
## 8  352.2940 -31.80897 0.24414275    6295.636 20.50240 0.025621280
## 9  352.2947 -31.83214 0.04440331    4731.346 20.81254 0.036479397
## 10 352.3058 -31.81010 0.23517321    4644.687 20.83261 0.027647648
##          N50       N90 N100       R50      R90      R100   SB_N50   SB_N90
## 1   25.53866 125.76701 1177 1.0381943 2.303897  7.048031 15.80728 16.90002
## 2   31.65729 156.36020 1301 1.2019195 2.671171  7.705081 16.97934 18.07529
## 3   54.09739 546.88782 1084 1.8586611 5.909642  8.320065 20.59385 22.46747
## 4   14.86623  66.03757  214 0.9929451 2.092765  3.767313 22.13513 23.11592
## 5  118.82350 438.75100  773 2.8186292 5.416214  7.189133 22.38684 23.16695
## 6  162.36038 539.21549 1002 4.3075739 7.850076 10.701054 22.37132 23.03635
## 7   33.98117 122.49137  320 1.1934101 2.265809  3.662229 22.44138 23.19537
## 8   38.86339 146.78249  440 1.2489670 2.427268  4.202493 22.87983 23.68448
## 9   27.32216 103.06884  337 1.0421512 2.024123  3.660059 22.80740 23.61075
## 10  33.30340 119.42592  523 1.2328295 2.334576  4.885507 23.04240 23.79075
##     SB_N100      xsd      ysd       covxy       corxy       con asymm
## 1  19.21365 3.263228 3.219536   1.4857455  0.14141766 0.4506254    NA
## 2  20.26128 3.934452 3.695753   3.0363155  0.20881408 0.4499598    NA
## 3  23.09590 4.674415 8.042726  -4.5131667 -0.12004687 0.3145133    NA
## 4  24.27809 3.749027 2.070228  -0.2717819 -0.03501739 0.4744657    NA
## 5  23.66746 6.225887 5.858164 -19.5785947 -0.53680772 0.5204058    NA
## 6  23.59472 8.538110 8.381656 -58.2572767 -0.81406411 0.5487302    NA
## 7  24.12359 3.102251 3.409893   1.0301886  0.09738655 0.5267038    NA
## 8  24.76203 4.021562 3.918905  -1.4010978 -0.08890148 0.5145567    NA
## 9  24.78261 3.532646 3.349168   0.7528410  0.06363063 0.5148656    NA
## 10 25.27986 4.830392 4.370784  -4.1060251 -0.19448223 0.5280742    NA
##    flux_reflect mag_reflect   semimaj  semimin     axrat        ang signif
## 1            NA          NA  3.464032 3.002425 0.8667429 132.277466    Inf
## 2            NA          NA  4.211792 3.376286 0.8016271 126.652402    Inf
## 3            NA          NA  8.071914 4.623830 0.5728295   5.949694    Inf
## 4            NA          NA  3.750035 2.068403 0.5515689  88.407683    Inf
## 5            NA          NA  7.499609 4.103123 0.5471116  48.237135    Inf
## 6            NA          NA 11.395089 3.647387 0.3200841  45.650757    Inf
## 7            NA          NA  3.473122 3.031297 0.8727874 157.098432    Inf
## 8            NA          NA  4.150248 3.782355 0.9113564  53.109723    Inf
## 9            NA          NA  3.582007 3.296322 0.9202443 115.008490    Inf
## 10           NA          NA  5.082982 4.074277 0.8015525  58.623489    Inf
##       FPlim flux_err      mag_err flux_err_sky flux_err_skyRMS
## 1  2.353971 336.7937 0.0001310305   150.953395        301.0698
## 2  2.316502 367.0887 0.0003391015   188.692738        314.8796
## 3  2.384412 306.2594 0.0046211175   104.049566        288.0425
## 4  2.931150 127.8971 0.0290406827    12.922447        127.2426
## 5  2.506347 259.5075 0.0092956296    92.226481        242.5663
## 6  2.413217 298.5510 0.0077154622   102.896518        280.2588
## 7  2.803835 162.3792 0.0213865180     7.379683        162.2114
## 8  2.699539 187.3294 0.0323065560     3.240569        187.3014
## 9  2.787104 158.8931 0.0364623408    12.141246        158.4285
## 10 2.641525 201.3094 0.0470578369    22.530998        200.0446
##    flux_err_shot    sky_mean    sky_sum skyRMS_mean Nedge Nsky Nobject
## 1              0 -0.05442729  -64.06092    8.775595    NA   NA      NA
## 2              0  0.17785361  231.38754    8.729826    NA   NA      NA
## 3              0 -0.29206174 -316.59492    8.748622    NA   NA      NA
## 4              0 -0.13775000  -29.47850    8.698092    NA   NA      NA
## 5              0 -0.51450016 -397.70862    8.724495    NA   NA      NA
## 6              0 -0.60529210 -606.50268    8.853633    NA   NA      NA
## 7              0 -0.75607079 -241.94265    9.067889    NA   NA      NA
## 8              0 -0.60158232 -264.69622    8.929218    NA   NA      NA
## 9              0 -0.49235875 -165.92490    8.630146    NA   NA      NA
## 10             0 -0.51373854 -268.68526    8.747218    NA   NA      NA
##    Nborder Nmask edge_frac edge_excess flag_border iter  origfrac
## 1       NA    NA        NA          NA          NA    0 1.0000000
## 2       NA    NA        NA          NA          NA    0 1.0000000
## 3       NA    NA        NA          NA          NA    1 0.9819151
## 4       NA    NA        NA          NA          NA    2 0.9281625
## 5       NA    NA        NA          NA          NA    1 0.9611582
## 6       NA    NA        NA          NA          NA    1 0.9621054
## 7       NA    NA        NA          NA          NA    1 0.9587924
## 8       NA    NA        NA          NA          NA    2 0.8840524
## 9       NA    NA        NA          NA          NA    2 0.8693788
## 10      NA    NA        NA          NA          NA    3 0.8331838
##    flag_keep
## 1       TRUE
## 2       TRUE
## 3       TRUE
## 4       TRUE
## 5       TRUE
## 6       TRUE
## 7       TRUE
## 8       TRUE
## 9       TRUE
## 10      TRUE

Next we will check the before and after photometry for the brightest 40 sources (the lists differ a bit in detail due to the different sky estimation routines used):

magplot(out_segim$segstats[1:40,c("R50", "SB_N90")], col=hsv(magmap(out_segim$segstats$axrat, flip=TRUE)$map), log='x', xlim=c(0.4,5), ylim=c(22,25), grid=TRUE, xlab='R50 / asec', ylab='mag / asec^2')
points(out_profound$segstats[1:40,c("R50", "SB_N90")], col=hsv(magmap(out_segim$segstats$axrat, flip=TRUE)$map), pch=16)
arrows(out_segim$segstats$R50[1:40], out_segim$segstats$SB_N90[1:40], out_profound$segstats$R50[1:40], out_profound$segstats$SB_N90[1:40], col='lightgrey', length=0)
rect(0.9, 23.5, 1.3, 24.3)
legend('bottomleft', legend=c('profoundProFound', 'profoundMakeSegim'), pch=c(16,1))
magbar('topright', title='Axrat', titleshift=1)

magplot(out_segim$segstats[1:40,c("R50", "con")], col=hsv(magmap(out_segim$segstats$axrat, flip=TRUE)$map), log='x', xlim=c(0.4,5), ylim=c(0,1), grid=TRUE, xlab='R50 / asec', ylab='Concentration')
points(out_profound$segstats[1:40,c("R50", "con")], col=hsv(magmap(out_segim$segstats$axrat, flip=TRUE)$map), pch=16)
arrows(out_segim$segstats$R50[1:40], out_segim$segstats$con[1:40], out_profound$segstats$R50[1:40], out_profound$segstats$con[1:40], col='lightgrey', length=0)
rect(0.9, 0.4, 1.3, 0.6)
legend('bottomleft', legend=c('profoundProFound', 'profoundMakeSegim'), pch=c(16,1))
magbar('topright', title='Axrat', titleshift=1)

magplot(out_segim$segstats[1:40,c("R50", "mag")], col=hsv(magmap(out_segim$segstats$axrat, flip=TRUE)$map), log='x', xlim=c(0.4,5), ylim=c(17,24), grid=TRUE, xlab='R50 / asec', ylab='Mag')
points(out_profound$segstats[1:40,c("R50", "mag")], col=hsv(magmap(out_segim$segstats$axrat, flip=TRUE)$map), pch=16)
arrows(out_segim$segstats$R50[1:40], out_segim$segstats$mag[1:40], out_profound$segstats$R50[1:40], out_profound$segstats$mag[1:40], col='lightgrey', length=0)
rect(0.9, 20, 1.3, 22)
legend('bottomleft', legend=c('profoundProFound', 'profoundMakeSegim'), pch=c(16,1))
magbar('topright', title='Axrat', titleshift=1)

It is notable that low surface brightness objects are seen to systematically grow when processing the image with profoundProFound. The box represents the location of likely stars, where redder objects are more circular sources. It is clear that profoundProFound moves stars onto a more uniform value of R50 (remember for a Gaussian PSF FWHM=2*R50).

The profoundProFound function also returns a sky and sky RMS image matched to the input image:

maghist(out_profound$sky, xlab='Sky')
## [1] "Summary of used sample:"
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
## -2.3270 -0.7348 -0.5039 -0.4977 -0.1780  0.5313 
## [1] "sd / 1-sig / 2-sig range:"
## [1] 0.5001919 0.4446320 1.1021306
## [1] "Plotting 126736 out of 126736 (100%) data points (0 < xlo & 0 > xhi)"

maghist(out_profound$skyRMS, xlab='Sky RMS')
## [1] "Summary of used sample:"
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   8.324   8.660   8.779   8.798   8.969   9.195 
## [1] "sd / 1-sig / 2-sig range:"
## [1] 0.1922451 0.2086032 0.3505592
## [1] "Plotting 126736 out of 126736 (100%) data points (0 < xlo & 0 > xhi)"

magimageWCS(image)

magimageWCS(out_profound$sky, image$hdr)

magimageWCS(out_profound$skyRMS, image$hdr)

The background mask we used here (the default 100x100 option) looks to be pretty good, with not much correlation between the image and the sky map. However, even with a slightly too small sky grid the photometric outputs should be mostly pretty robust- differing by at worst a couple of counts per pixel. This is much less than the typical sky RMS (roughly 9 throughout).

maghist(out_profound$segstats[,'N100']/out_profound$segstats[,'flux'], xlab=' Worst case fraction error')
## [1] "Summary of used sample:"
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## 0.0004218 0.1313115 0.2107956 0.2453530 0.3010744 0.8381362 
## [1] "sd / 1-sig / 2-sig range:"
## [1] 0.1739166 0.1431703 0.3550237
## [1] "Plotting 86 out of 86 (100%) data points (0 < xlo & 0 > xhi)"

In summary, you probably want to use profoundProFound, unless you really know what you are doing and are feeling a bit adventurous!

ProFound Flags

ProFound offers a few useful flags that will help extract high fidelity photometry. To access the boundary flags we have to set boundstats=TRUE when we run ProFound:

out_profound=profoundProFound(image, magzero=30, verbose=TRUE, boundstats=TRUE)
## Running ProFound:
## Supplied image contains image and header components
## Supplied image is 356 x 356 pixels
## Extracted pixel scale from header provided: 0.339 asec/pixel
## Supplied image is 2.011 x 2.011 amin,  0.001 deg-sq
## Making initial sky map - 0.002 sec
##  - Sky statistics :
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
## -2.3257 -0.1157  0.5354  0.5499  1.0154  4.0443
##  - Sky-RMS statistics :
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   8.318   8.915   9.122   9.121   9.273   9.882
## Making initial segmentation image - 0.214 sec
##  - Running MakeSegim:
##  - Skipping making initial local estimate of the sky - User provided sky
##  - Skipping making initial local estimate of the sky RMS - User provided sky RMS
##  - Smoothing the image - 0.005 sec
##  - Watershed de-blending - 0.013 sec
##  - Skipping segmentation plot - plot set to FALSE
##  - Skipping making final local estimate of the sky - User provided sky
##  - Skipping making initial local estimate of the sky RMS - User provided sky RMS
##  - Skipping segmentation statistics - segstats set to FALSE or no segments
##  - MakeSegim is finished! - 0.044 sec
## Doing initial aggressive dilation - 0.26 sec
##  - Running MakeSegimDilate:
##  - Dilating segments - 0.001 sec
##  - Skipping segmentation statistics - segstats set to FALSE
##  - profoundMakeSegimDilate is finished! - 0.04 sec
## Making better sky map - 0.301 sec
##  - Sky statistics :
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
## -2.32792 -0.73111 -0.42721 -0.45022 -0.03966  0.41956
##  - Sky-RMS statistics :
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   8.317   8.697   8.799   8.822   8.982   9.199
## Calculating initial segstats - 0.487 sec
## Doing dilations:
## Iteration 1 of 6 - 0.527 sec
##  - Running MakeSegimDilate:
##  - Dilating segments - 0.002 sec
##  - Calculating segstats - 0.02 sec
##  - profoundMakeSegimDilate is finished! - 0.054 sec
## Iteration 2 of 6 - 0.582 sec
##  - Running MakeSegimDilate:
##  - Dilating segments - 0.002 sec
##  - Calculating segstats - 0.02 sec
##  - profoundMakeSegimDilate is finished! - 0.195 sec
## Iteration 3 of 6 - 0.78 sec
##  - Running MakeSegimDilate:
##  - Dilating segments - 0.002 sec
##  - Calculating segstats - 0.016 sec
##  - profoundMakeSegimDilate is finished! - 0.056 sec
## Iteration 4 of 6 - 0.837 sec
##  - Running MakeSegimDilate:
##  - Dilating segments - 0.002 sec
##  - Calculating segstats - 0.018 sec
##  - profoundMakeSegimDilate is finished! - 0.064 sec
## Iteration 5 of 6 - 0.904 sec
##  - Running MakeSegimDilate:
##  - Dilating segments - 0.002 sec
##  - Calculating segstats - 0.019 sec
##  - profoundMakeSegimDilate is finished! - 0.067 sec
## Iteration 6 of 6 - 0.974 sec
##  - Running MakeSegimDilate:
##  - Dilating segments - 0.001 sec
##  - Calculating segstats - 0.019 sec
##  - profoundMakeSegimDilate is finished! - 0.074 sec
## Finding CoG convergence - 1.051 sec
## Constructing final segim - 1.054 sec
## Doing final aggressive dilation - 1.111 sec
##  - Running MakeSegimDilate:
##  - Dilating segments - 0.001 sec
##  - Skipping segmentation statistics - segstats set to FALSE
##  - profoundMakeSegimDilate is finished! - 0.028 sec
## Making final sky map - 1.14 sec
##  - Sky statistics :
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
## -2.3270 -0.7348 -0.5039 -0.4977 -0.1780  0.5313
##  - Sky-RMS statistics :
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   8.324   8.660   8.779   8.798   8.969   9.195
## Calculating final segstats for 86 objects - 1.299 sec
##  - magzero = 30
##  - gain = NULL (ignored)
##  - pixscale = 0.339
##  - rotstats = FALSE
##  - boundstats = TRUE
## Skipping segmentation plot - plot set to FALSE
## ProFound is finished! - 1.521 sec

The output we get is in segstats is useful, telling us whether or not an object is isolated:

out_profound$segstats[1:10,c("Nedge", "Nsky", "Nobject", "Nborder", "edge_frac", "edge_excess", "flag_border")]
##    Nedge Nsky Nobject Nborder edge_frac edge_excess flag_border
## 1    181  103      78       0 0.5690608   1.4825964           0
## 2    187  141      46       0 0.7540107   1.4492189           0
## 3    183   57     126       0 0.3114754   1.4815620           0
## 4     55   30       0      25 0.5454545   0.9944579           1
## 5    114   63      51       0 0.5526316   1.0826823           0
## 6    138  108      30       0 0.7826087   0.9874888           0
## 7     58   58       0       0 1.0000000   0.9114713           0
## 8     65   58       7       0 0.8923077   0.8727323           0
## 9     58   58       0       0 1.0000000   0.8901146           0
## 10    75   59      16       0 0.7866667   0.9167230           0

The edge_frac column is simply Nsky/Nedge (the number of segment edge pixels purely touching sky divided by the number of pixels in the segment edge). Where it is 1 the segment must be well isolated, because none of its outer pixels are touching either an image boundary or another object.

We can easily plot the isolated segments and the non-isolated segments:

magimage(out_profound$segim*(out_profound$segim %in% out_profound$segstats[out_profound$segstats$edge_frac==1,"segID"]), col=c(0,rainbow(100)))

magimage(out_profound$segim*(out_profound$segim %in% out_profound$segstats[out_profound$segstats$edge_frac!=1,"segID"]), col=c(0,rainbow(100)))

You might be more interested in removing segments touching an image edge:

magimage(out_profound$segim*(out_profound$segim %in% out_profound$segstats[out_profound$segstats$Nborder==0,"segID"]), col=c(0,rainbow(100)))
legend('topleft',legend='Isolated Segment')

magimage(out_profound$segim*(out_profound$segim %in% out_profound$segstats[out_profound$segstats$Nborder>0,"segID"]), col=c(0,rainbow(100)))
legend('topleft',legend='Non_Isolated Segment')

The edge_excess column tells us how elliptical or non-elliptical the segments are. Generally values less than 1 are probably fairly sensible looking segments (i.e. ellipses). Larger than this and the segments might have weird gemoetry:

magimage(out_profound$segim*(out_profound$segim %in% out_profound$segstats[out_profound$segstats$edge_excess<1,"segID"]), col=c(0,rainbow(100)))
legend('topleft',legend='Fairly Elliptical Segment')

magimage(out_profound$segim*(out_profound$segim %in% out_profound$segstats[out_profound$segstats$edge_excess>1,"segID"]), col=c(0,rainbow(100)))
legend('topleft',legend='Non-Elliptical Segment')

The flag_border column tells us which border of the image the segment touches. The bottom of the image is flagged 1, left=2, top=4 and right=8. A summed combination of these flags indicate the segment is in a corner touching two borders: bottom-left=3, top-left=6, top-right=12, bottom-right=9. In our case we can see we should find segments touching the bottom, left and top of the image:

magimage(out_profound$segim*(out_profound$segim %in% out_profound$segstats[out_profound$segstats$flag_border==1,"segID"]), col=c(0,rainbow(100)))
legend('topleft',legend='Segment Borders Bottom')

magimage(out_profound$segim*(out_profound$segim %in% out_profound$segstats[out_profound$segstats$flag_border==2,"segID"]), col=c(0,rainbow(100)))
legend('topleft',legend='Segment Borders Left')

magimage(out_profound$segim*(out_profound$segim %in% out_profound$segstats[out_profound$segstats$flag_border==4,"segID"]), col=c(0,rainbow(100)))
## [1] "Too many same valued pixels: turning off magmap scaling!"
legend('topleft',legend='Segment Borders Top')

Depending on your science requirements, users might want to make use of some or all of these useful flags. Practically the most useful flag is probably edge_frac, where values above 0.8 are usually a good cut off for fairly reliable photometry (i.e. the confused or missing flux is the sub-dominant form of error), but this cannot be treated as a guarantee!

magimage(out_profound$segim*(out_profound$segim %in% out_profound$segstats[out_profound$segstats$edge_frac>0.8,"segID"]), col=c(0,rainbow(100)))
legend('topleft',legend='Reliable Photometry Segments')

magimage(out_profound$segim*(out_profound$segim %in% out_profound$segstats[out_profound$segstats$edge_frac<0.8,"segID"]), col=c(0,rainbow(100)))
legend('topleft',legend='Unreliable Photometry Segments')

Advanced ProFound Usage

The way ProFound handles the various inputs allows for great flexibility and power. AS an example, it is fairly trivial to run it in a mode where you can extract multiband photometry in pixel matched data. AS a pseudo code example imagine you have 3 pixel matched 2k*2K J/H/K band images with the same magnitude zero points. You can use the objects detected in, say, the K band to extract photometry in the others:

pro_det_K=profoundProFound(image=Kim)

Total Photometry

We can then extract matching photometry. Note that in practice pro_K_tot_fix = pro_det_K (since the K band was our detection band already), but we psuedo re-run it for clarity.

pro_J_tot_fix=profoundProFound(image=Jim, segim=pro_det_K$segim, iters=0)
pro_H_tot_fix=profoundProFound(image=Him, segim=pro_det_K$segim, iters=0)
pro_K_tot_fix=profoundProFound(image=Kim, segim=pro_det_K$segim, iters=0)

A second option is to allow each target band to dynamically dilate based on the original segmentation map. The might help in situations where the target image PSFs are quite mismatched. The dynamic dilation will ensure close to total magnitudes regardless of the differing PSFs. Note that in practice pro_K_tot_dil = pro_det_K (since the K band was our detection band already), but we psuedo re-run it for clarity.

pro_J_tot_dil=profoundProFound(image=Jim, segim=pro_det_K$segim_orig, objects=pro_det_K$objects)
pro_H_tot_dil=profoundProFound(image=Him, segim=pro_det_K$segim_orig, objects=pro_det_K$objects)
pro_K_tot_dil=profoundProFound(image=Kim, segim=pro_det_K$segim_orig, objects=pro_det_K$objects)

Colour Photometry

The above options would extract close to total photometry given the K-band detection segments. You often find better colours running with the high surface brightness non-dilated segmentation map, which is also returned by ProFound. In this case you would need to re-run the K too. Notice we also pass the objects matrix to ProFound. This ensures a better sky estimation, since we are now using the brighter inner part of detected objects to extract colour photometry, but we want to know the location of the full object to obtain a good sky estimate.

pro_J_col_fix=profoundProFound(image=Jim, segim=pro_det_K$segim_orig, objects=pro_det_K$objects, iters=0)
pro_H_col_fix=profoundProFound(image=Him, segim=pro_det_K$segim_orig, objects=pro_det_K$objects, iters=0)
pro_K_col_fix=profoundProFound(image=Kim, segim=pro_det_K$segim_orig, objects=pro_det_K$objects, iters=0)