When your science is related to extended emission (like the example here) and you are presenting your results in a scientific conference, usually the first thing that someone will ask (if you do not explicitly say it!), is the dataset’s surface brightness limit (a standard measure of the noise level), and your target’s surface brightness (a measure of the signal, either in the center or outskirts, depending on context). For more on the basics of these important concepts please see Quantifying measurement limits. So in this section of the tutorial, we will measure these values for the single-exposure SDSS image of the M51 group that we downloaded in Downloading and validating input data.
Before measuring the surface brightness limit, let’s see how reliable our detection was. In other words, let’s see how “clean” our noise is (after masking all detections, as described previously in Skewness caused by signal and its measurement):
$ aststatistics det-masked.fits --quantofmean 0.5111848629
Showing that the mean is indeed very close to the median, although just about 1 quantile larger. As we saw in NoiseChisel optimization, a very small residual signal still remains in the undetected regions and this very small difference is a quantitative measure of that undetected signal. It was up to you as an exercise to improve it, so we will continue with this dataset.
The surface brightness limit of the image can be measured from the masked image and the equation in Quantifying measurement limits. Let’s do it for a \(3\sigma\) surface brightness limit over an area of \(25 \rm{arcsec}^2\):
$ nsigma=3 $ zeropoint=22.5 $ areaarcsec2=25 $ std=$(aststatistics det-masked.fits --sigclip-std) $ pixarcsec2=$(astfits det-masked.fits --pixelscale --quiet \ | awk '{print $3*3600*3600}') $ astarithmetic --quiet $nsigma $std x \ $areaarcsec2 $pixarcsec2 x \ sqrt / $zeropoint counts-to-mag 26.0241
The customizable steps above are good for any type of mask.
For example, your field of view may contain a very deep part so you need to mask all the shallow parts as well as the detections before these steps.
But when your image is flat (like this), there is a much simpler method to obtain the same value through MakeCatalog (when the standard deviation image is made by NoiseChisel).
NoiseChisel has already calculated the minimum (MINSTD
), maximum (MAXSTD
) and median (MEDSTD
) standard deviation within the tiles during its processing and has stored them as FITS keywords within the SKY_STD
HDU.
You can see them by piping all the keywords in this HDU into grep
.
In Grep, each ‘.’ represents one character that can be anything so M..STD
will match all three keywords mentioned above.
$ astfits r_detected.fits --hdu=SKY_STD | grep 'M..STD'
The MEDSTD
value is very similar to the standard deviation derived above, so we can safely use it instead of having to mask and run Statistics.
|
Fortunately, MakeCatalog will use this keyword and will report the dataset’s \(n\sigma\) surface brightness limit as keywords in the output (not as measurement columns, since it is related to the noise, not labeled signal) as described below.
$ astmkcatalog r_detected.fits -hDETECTIONS --output=sbl.fits \ --forcereadstd --ids
Before looking into the measured surface brightness limits, let’s review some important points about this call to MakeCatalog first:
With the command below you can see all the keywords that were measured with the table. Notice the group of keywords that are under the “Surface brightness limit (SBL)” title.
$ astfits sbl.fits -h1
Since all the keywords of interest here start with SBL
, we can get a more cleaner view with this command.
$ astfits sbl.fits -h1 | grep ^SBL
Notice how the SBLSTD
has the same value as NoiseChisel’s MEDSTD
above.
Using SBLSTD
, MakeCatalog has determined the \(n\sigma\) surface brightness limiting magnitude in these header keywords.
The multiple of \(\sigma\), or \(n\), is the value of the SBLNSIG
keyword which you can change with the --sfmagnsigma.
The surface brightness limiting magnitude within a pixel (SBLNSIG
) and within a pixel-agnostic area of SBLAREA
arcsec\(^2\) are stored in SBLMAG
.
You will notice that the two surface brightness limiting magnitudes above have values around 3 and 4 (which is not correct!).
This is because we have not given a zero point magnitude to MakeCatalog, so it uses the default value of 0
.
SDSS image pixel values are calibrated in units of “nanomaggy” which are defined to have a zero point magnitude of 22.551.
So with the first command below we give the zero point value and with the second we can see the surface brightness limiting magnitudes with the correct values (around 25 and 26)
$ astmkcatalog r_detected.fits -hDETECTIONS --zeropoint=22.5 \ --output=sbl.fits --forcereadstd --ids $ astfits sbl.fits -h1 | grep ^SBL
As you see from SBLNSIG
and SBLAREA
, the default multiple of sigma is 1 and the default area is 1 arcsec\(^2\).
Usually higher values are used for these two parameters.
Following the manual example we did above, you can ask for the multiple of sigma to be 3 and the area to be 25 arcsec\(^2\):
$ astmkcatalog r_detected.fits -hDETECTIONS --zeropoint=22.5 \ --output=sbl.fits --sfmagarea=25 --sfmagnsigma=3 \ --forcereadstd --ids $ astfits sbl.fits -h1 | awk '/^SBLMAG /{print $3}' 26.02296
You see that the value is identical to the custom surface brightness limiting magnitude we measured above (a difference of \(0.00114\) magnitudes is negligible and hundreds of times larger than the typical errors in the zero point magnitude or magnitude measurements). But it is much more easier to have MakeCatalog do this measurement, because these values will be appended (as keywords) into your final catalog of objects within that image.
Custom STD for MakeCatalog’s Surface brightness limit: You can manually change/set the value of the $ std=$(aststatistics masked.fits --sigclip-std) $ astfits noisechisel.fits -hSKY_STD --update=MEDSTD,$std With this change, MakeCatalog will use your custom standard deviation for the surface brightness limit. This is necessary in scenarios where your image has multiple depths and during your masking, you also mask the shallow regions (as well as the detections of course). |
We have successfully measured the image’s \(3\sigma\) surface brightness limiting magnitude over 25 arcsec\(^2\). However, as discussed in Quantifying measurement limits this value is just an extrapolation of the per-pixel standard deviation. Issues like correlated noise will cause the real noise over a large area to be different. So for a more robust measurement, let’s use the upper-limit magnitude of similarly sized region. For more on the upper-limit magnitude, see the respective item in Quantifying measurement limits.
In summary, the upper-limit measurements involve randomly placing the footprint of an object in undetected parts of the image many times. This results in a random distribution of brightness measurements, the standard deviation of that distribution is then converted into magnitudes. To be comparable with the results above, let’s make a circular aperture that has an area of 25 arcsec\(^2\) (thus with a radius of \(2.82095\) arcsec).
zeropoint=22.5 r_arcsec=2.82095 ## Convert the radius (in arcseconds) to pixels. r_pixel=$(astfits r_detected.fits --pixelscale -q \ | awk '{print '$r_arcsec'/($1*3600)}') ## Make circular aperture at pixel (100,100) position is irrelevant. echo "1 100 100 5 $r_pixel 0 0 1 1 1" \ | astmkprof --background=r_detected.fits \ --clearcanvas --mforflatpix --type=uint8 \ --output=lab.fits ## Do the upper-limit measurement, ignoring all NoiseChisel's ## detections as a mask for the upper-limit measurements. astmkcatalog lab.fits -h1 --zeropoint=$zeropoint -osbl.fits \ --sfmagarea=25 --sfmagnsigma=3 --forcereadstd \ --valuesfile=r_detected.fits --valueshdu=INPUT-NO-SKY \ --upmaskfile=r_detected.fits --upmaskhdu=DETECTIONS \ --upnsigma=3 --checkuplim=1 --upnum=1000 \ --ids --upperlimit-sb
The sbl.fits catalog now contains the upper-limit surface brightness for a circle with an area of 25 arcsec\(^2\). You can check the value with the command below, but the great thing is that now you have both of the surface brightness limiting magnitude in the headers discussed above, and the upper-limit surface brightness within the table. You can also add more profiles with different shapes and sizes if necessary. Of course, you can also use --upperlimit-sb in your actual science objects and clumps to get an object-specific or clump-specific value.
$ asttable sbl.fits -cUPPERLIMIT_SB 25.9119
You will get a slightly different value from the command above. In fact, if you run the MakeCatalog command again and look at the measured upper-limit surface brightness, it will be slightly different with your first trial! Please try exactly the same MakeCatalog command above a few times to see how it changes.
This is because of the random factor in the upper-limit measurements: every time you run it, different random points will be checked, resulting in a slightly different distribution. You can decrease the random scatter by increasing the number of random checks (for example, setting --upnum=100000, compared to 1000 in the command above). But this will be slower and the results will not be exactly reproducible. The only way to ensure you get an identical result later is to fix the random number generator function and seed like the command below52. This is a very important point regarding any statistical process involving random numbers, please see Generating random numbers.
export GSL_RNG_TYPE=ranlxs1 export GSL_RNG_SEED=1616493518 astmkcatalog lab.fits -h1 --zeropoint=$zeropoint -osbl.fits \ --sfmagarea=25 --sfmagnsigma=3 --forcereadstd \ --valuesfile=r_detected.fits --valueshdu=INPUT-NO-SKY \ --upmaskfile=r_detected.fits --upmaskhdu=DETECTIONS \ --upnsigma=3 --checkuplim=1 --upnum=1000 \ --ids --upperlimit-sb --envseed
But where do all the random apertures of the upper-limit measurement fall on the image?
It is good to actually inspect their location to get a better understanding for the process and also detect possible bugs/biases.
When MakeCatalog is run with the --checkuplim option, it will print all the random locations and their measured brightness as a table in a file with the suffix _upcheck.fits.
With the first command below you can use Gnuastro’s asttable
and astscript-ds9-region
to convert the successful aperture locations into a DS9 region file, and with the second can load the region file into the detections and sky-subtracted image to visually see where they are.
## Create a DS9 region file from the check table (activated ## with '--checkuplim') asttable sbl_upcheck.fits --noblank=RANDOM_SUM \ | astscript-ds9-region -c1,2 --mode=img \ --radius=$r_pixel ## Have a look at the regions in relation with NoiseChisel's ## detections. ds9 r_detected.fits[INPUT-NO-SKY] -regions load ds9.reg ds9 r_detected.fits[DETECTIONS] -regions load ds9.reg
In this example, we were looking at a single-exposure image that has no correlated noise. Because of this, the surface brightness limit and the upper-limit surface brightness are very close. They will have a bigger difference on deep datasets with stronger correlated noise (that are the result of stacking many individual exposures). As an exercise, please try measuring the upper-limit surface brightness level and surface brightness limit for the deep HST data that we used in the previous tutorial (General program usage tutorial).
Recall that NoiseChisel’s output is a binary image: 0-valued pixels are noise and 1-valued pixel are signal. NoiseChisel does not identify sub-structure over the signal, this is the job of Segment, see Extract clumps and objects (Segmentation).
From https://www.sdss.org/dr12/algorithms/magnitudes
You can use any integer for the seed. One recommendation is to run MakeCatalog without --envseed once and use the randomly generated seed that is printed on the terminal.
JavaScript license information
GNU Astronomy Utilities 0.23 manual, July 2024.