Rfits: Methods in the Madness

Aaron Robotham

2024-01-22

Rfits comes with a number of useful methods that operate on Rfits_image and Rfits_pointer objects. Using these you can do a lot of useful thing!

library(Rfits)
library(Rwcs)

Subsetting

First we will load up an image in RAM (temp_image) and as a pointer to the disk object (temp_point)

file_image = system.file('extdata', 'image.fits', package = "Rfits")

temp_image = Rfits_read_image(file_image)
temp_point = Rfits_point(file_image)

We can look at both of these, since they have distinct print methods by default:

print(temp_image)
#> Class: Rfits_image
#> File path: /Library/Frameworks/R.framework/Versions/4.2/Resources/library/Rfits/extdata/image.fits 
#> Ext num: 1 
#> Ext name: 
#> RAM size: 0.9871 MB
#> BITPIX: -32 
#> NAXIS1: 356 
#> NAXIS2: 356 
#> Key N: 23
print(temp_point)
#> File path: /Library/Frameworks/R.framework/Versions/4.2/Resources/library/Rfits/extdata/image.fits 
#> Ext num: 1 
#> Ext name: 
#> Class: Rfits_pointer
#> Type: image 
#> Dim: 356 356 
#> Disk size: 0.4889 MB
#> BITPIX: -32 
#> Key N: 23

The two data structures are a bit different, but we can still plot both directly:

plot(temp_image)
plot(temp_point)

Behind the scene the S3 plot method does different things depending on the Rfits object encountered. If it is an Rfits_image then it will directly plot it using Rwcs_image with a WCS. If it is a Rfits_pointer then it will first fully load the data into RAM, and then plot it using Rwcs_image.

If you have a Rfits_pointer object then you can convert it to a Rfits_image very easily:

temp_point[]
#> Class: Rfits_image
#> File path: /Library/Frameworks/R.framework/Versions/4.2/Resources/library/Rfits/extdata/image.fits 
#> Ext num: 1 
#> Ext name: 
#> RAM size: 0.9871 MB
#> BITPIX: -32 
#> NAXIS1: 356 
#> NAXIS2: 356 
#> Key N: 23

This is because Rfits has special subset operation that work specifically on Rfits_image and Rfits_pointer objects. This means we can plot a subset:

plot(temp_image[50:150,50:150])
plot(temp_point[50:150,50:150])

For convenience the following will achieve the same outcomes:

plot(temp_image[c(50,150),c(50,150)])
plot(temp_point[c(50,150),c(50,150)])

And we can also cutout a box on a specific location:

plot(temp_image[101, 101, box=100])
plot(temp_point[101, 101, box=100])

We can also subset based on RA/Dec coordinates:

coords = Rwcs_p2s(101,101,temp_image$keyvalues)
print(coords)
#>         RA      Dec
#> [1,] 352.3 -31.8296
plot(temp_image[coords[1], coords[2], box=100, type='coord'])
plot(temp_point[coords[1], coords[2], box=100, type='coord'])

Useful Class Methods

Rfits comes with a whole lot of specific Rfits_image and Rfits_pointer class methods (for details see ?Rfits_methods):

They are designed to give identical results, i.e.:

print(temp_image)
#> Class: Rfits_image
#> File path: /Library/Frameworks/R.framework/Versions/4.2/Resources/library/Rfits/extdata/image.fits 
#> Ext num: 1 
#> Ext name: 
#> RAM size: 0.9871 MB
#> BITPIX: -32 
#> NAXIS1: 356 
#> NAXIS2: 356 
#> Key N: 23
print(temp_point)
#> File path: /Library/Frameworks/R.framework/Versions/4.2/Resources/library/Rfits/extdata/image.fits 
#> Ext num: 1 
#> Ext name: 
#> Class: Rfits_pointer
#> Type: image 
#> Dim: 356 356 
#> Disk size: 0.4889 MB
#> BITPIX: -32 
#> Key N: 23
length(temp_image)
#> [1] 126736
length(temp_point)
#> [1] 126736
dim(temp_image)
#> [1] 356 356
dim(temp_point)
#> [1] 356 356
centre(temp_image)
#>            RA      Dec
#> [1,] 352.2914 -31.8223
centre(temp_point)
#>            RA      Dec
#> [1,] 352.2914 -31.8223
corners(temp_image)
#>          RA       Dec
#> BL 352.3111 -31.83906
#> TL 352.3111 -31.80554
#> TR 352.2717 -31.80554
#> BR 352.2717 -31.83906
corners(temp_point)
#>          RA       Dec
#> BL 352.3111 -31.83906
#> TL 352.3111 -31.80554
#> TR 352.2717 -31.80554
#> BR 352.2717 -31.83906
extremes(temp_image)
#>             RA        Dec
#> min   352.2717 -31.839059
#> max   352.3111 -31.805535
#> range   2.0114   2.011401
extremes(temp_point)
#>             RA        Dec
#> min   352.2717 -31.839059
#> max   352.3111 -31.805535
#> range   2.0114   2.011401
pixscale(temp_image)
#> [1] 0.3390001
pixscale(temp_point)
#> [1] 0.3390001
pixarea(temp_image)
#> [1] 0.114921
pixarea(temp_point)
#> [1] 0.114921
rotation(temp_image)
#>      North East
#> [1,]     0  180
rotation(temp_point)
#>      North East
#> [1,]     0  180

Pixel Manipulation Methods

Rfits_image objects can be usefully operated on as if they were matrices:

plot(temp_image^5, qdiff=TRUE)

plot(temp_image - 10, qdiff=TRUE)

Most R mathematical operators will work. You can also directly operate with Rfits_image and Rfits_point objects:

plot(temp_image * temp_image, qdiff=TRUE)

plot(temp_image - temp_image, qdiff=TRUE) #blank, since the image should now be 0

plot(temp_point - temp_point, qdiff=TRUE) #blank, since the image should now be 0

If you mix Rfits object types you will need to convert the Rfits_pointer to a Rfits_image using the subset operation:

plot(temp_image * temp_point[], qdiff=TRUE)

plot(temp_image - temp_point[], qdiff=TRUE) #blank, since the image should now be 0