Merging SDFITS Files#
This notebook shows how to merge SDFITS files.
There is no built-in function to merge SDFITS files (yet), so we will put the files we want to merge in the same directory, and then load them and write them to a single SDFITS file.
For this recipe we will use a single SDFITS file to generate two files from subsets of its data. We will need to use getsigref instead of getps to pull out a spectrum.
The following dysh commands are (re)introduced (leaving out all the function arguments):
filename = dysh_data()
sdf = GBTFITSLoad()
sdf.summary()
sdf.getsigref()
sdf.write()
Loading Modules#
We start by loading the modules we will use for this recipe.
# These modules are required for loading and writing data.
from dysh.fits import GBTFITSLoad
from dysh.log import init_logging
from astropy import units as u
# These modules are used for file I/O
from dysh.util.files import dysh_data
from pathlib import Path
Setup#
We start the dysh logging, so we get more information about what is happening.
This is only needed if working on a notebook.
If using the CLI through the dysh command, then logging is setup for you.
init_logging(2)
# also create a local "output" directory where temporary notebook files can be stored.
output_dir = Path.cwd() / "output"
output_dir.mkdir(exist_ok=True)
Data Retrieval#
Download the example SDFITS data, if necessary.
filename = dysh_data(test="getps")
23:06:57.940 I Resolving test=getps -> AGBT05B_047_01/AGBT05B_047_01.raw.acs/
Data Loading#
Next, we use GBTFITSLoad to load the data, and then its summary method to inspect its contents.
sdfits = GBTFITSLoad(filename)
23:06:58.027 I Index loaded from .index file (44/93 columns). Missing columns (TCAL, WCS, calibration metadata, etc.) will be automatically loaded from FITS file when first accessed.
sdfits.summary()
| SCAN | OBJECT | VELOCITY | PROC | PROCSEQN | RESTFREQ | # IF | # POL | # INT | # FEED | AZIMUTH | ELEVATION |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 51 | NGC5291 | 4386.0 | OnOff | 1 | 1.420405 | 1 | 2 | 11 | 1 | 198.3431 | 18.6427 |
| 52 | NGC5291 | 4386.0 | OnOff | 2 | 1.420405 | 1 | 2 | 11 | 1 | 198.9306 | 18.7872 |
| 53 | NGC5291 | 4386.0 | OnOff | 1 | 1.420405 | 1 | 2 | 11 | 1 | 199.3305 | 18.3561 |
| 54 | NGC5291 | 4386.0 | OnOff | 2 | 1.420405 | 1 | 2 | 11 | 1 | 199.9157 | 18.4927 |
| 55 | NGC5291 | 4386.0 | OnOff | 1 | 1.420405 | 1 | 2 | 11 | 1 | 200.3042 | 18.0575 |
| 56 | NGC5291 | 4386.0 | OnOff | 2 | 1.420405 | 1 | 2 | 11 | 1 | 200.8906 | 18.1860 |
| 57 | NGC5291 | 4386.0 | OnOff | 1 | 1.420405 | 1 | 2 | 11 | 1 | 202.3275 | 17.3853 |
| 58 | NGC5291 | 4386.0 | OnOff | 2 | 1.420405 | 1 | 2 | 11 | 1 | 202.9192 | 17.4949 |
Writing SDFITS Files#
To show how to merge SDFITS files, we will create two separate SDFITS files first. We use the GBTFITSLoad.write method to write the data. We will write scans 51 and 52 to two separate files.
Create an Output Directory#
The approach we will use to merge SDFITS files relies on having the files to be merged in the same directory.
We create a new temporary directory ./output/merge_sdfits
tmp_dir = output_dir / "merge_sdfits"
tmp_dir.mkdir(exist_ok=True, parents=True) # Create the output directory if it does not exist.
Write the Intermediate SDFITS Files#
Now we write scans 51 and 52 to the directory we created.
sdfits.write(tmp_dir / "scan51.fits", scan=51, overwrite=True)
sdfits.write(tmp_dir / "scan52.fits", scan=52, overwrite=True)
23:06:58.094 I write: bintable 0: 44 rows, 32768 channels, 1 chunk(s) of 5000
23:06:58.126 I write: chunk [0:44] of 44 rows built (0.0s)
23:06:58.139 I write: chunk written to disk (0.0s)
23:06:58.170 I write: bintable 0: 44 rows, 32768 channels, 1 chunk(s) of 5000
23:06:58.203 I write: chunk [0:44] of 44 rows built (0.0s)
23:06:58.215 I write: chunk written to disk (0.0s)
ID TAG SCAN # SELECTED
--- --------- ---- ----------
0 26291873b 51 44
ID TAG SCAN # SELECTED
--- --------- ---- ----------
0 d381daad3 52 44
Merge SDFITS Files#
Now that we have two SDFITS files we want to merge, we can do this by loading them using
GBTFITSLoad
by passing the directory containing the files we want to merge.
In this case, that would be ./output/merge_sdfits.
sdfits_merged = GBTFITSLoad(tmp_dir)
sdfits_merged.files
23:06:58.303 I Loaded 2 FITS files
[PosixPath('/home/docs/checkouts/readthedocs.org/user_builds/dysh/checkouts/release-1.0.0/docs/source/users_guide/output/merge_sdfits/scan51.fits'),
PosixPath('/home/docs/checkouts/readthedocs.org/user_builds/dysh/checkouts/release-1.0.0/docs/source/users_guide/output/merge_sdfits/scan52.fits')]
sdfits_merged.summary()
| SCAN | OBJECT | VELOCITY | PROC | PROCSEQN | RESTFREQ | # IF | # POL | # INT | # FEED | AZIMUTH | ELEVATION |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 51 | NGC5291 | 4386.0 | OnOff | 1 | 1.420405 | 1 | 2 | 11 | 1 | 198.3431 | 18.6427 |
| 52 | NGC5291 | 4386.0 | OnOff | 2 | 1.420405 | 1 | 2 | 11 | 1 | 198.9306 | 18.7872 |
Write the Merged SDFITS Files to a New File#
Now we can write the merged SDFITS files to a new file using
GBTFITSLoad.write
We tell it to write to a single file with the multifile=False argument.
We write to a new directory to show that this is only one file now.
new_dir = output_dir / "merged_sdfits"
new_dir.mkdir(exist_ok=True)
sdfits_merged.write(new_dir / "merged_sdfits.fits", multifile=False, overwrite=True)
23:06:58.341 I write: bintable 0: 44 rows, 32768 channels, 1 chunk(s) of 5000
23:06:58.365 I write: chunk [0:44] of 44 rows built (0.0s)
23:06:58.377 I write: chunk written to disk (0.0s)
23:06:58.380 I write: bintable 0: 44 rows, 32768 channels, 1 chunk(s) of 5000
23:06:58.404 I write: chunk [0:44] of 44 rows built (0.0s)
23:06:58.418 I write: chunk written to disk (0.0s)
Load the merged SDFITS file.
sdfits_merged = GBTFITSLoad(new_dir)
sdfits_merged.summary()
| SCAN | OBJECT | VELOCITY | PROC | PROCSEQN | RESTFREQ | # IF | # POL | # INT | # FEED | AZIMUTH | ELEVATION |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 51 | NGC5291 | 4386.0 | OnOff | 1 | 1.420405 | 1 | 2 | 11 | 1 | 198.3431 | 18.6427 |
| 52 | NGC5291 | 4386.0 | OnOff | 2 | 1.420405 | 1 | 2 | 11 | 1 | 198.9306 | 18.7872 |
You can check that it is indeed a single file by looking at the files attribute of the GBTFITSLoad object.
sdfits_merged.files
[PosixPath('/home/docs/checkouts/readthedocs.org/user_builds/dysh/checkouts/release-1.0.0/docs/source/users_guide/output/merged_sdfits/merged_sdfits.fits')]
The same principles can be applied to more complex examples, like selecting an IF for certain scans, and another for others, and then merging them all in a single file.
Final Stats#
We then use getsigref to obtain two spectra, which using the Spectrum.stats should give the same answer
A note on this, the
getps
procedure does not work here, because after the merge, the ON and OFF are in different BINTABLES, and getps does not support this mode.
sdfits.getsigref(51,52,ifnum=0,plnum=0,fdnum=0)[0].timeaverage().check_stats(0.09095205 * u.K)
23:06:59.907 I rms is OK
sdfits_merged.getsigref(51,52,ifnum=0,plnum=0,fdnum=0).timeaverage().check_stats(0.09095205 * u.K)
23:07:00.434 I rms is OK
See Also#
There is also an example of writing multiple SDFITS files in the dataIO notebook
here