Vane Calibration#
This notebook shows how to calibrate data that uses a vane (or a hot load) to determine the system temperature. In the case of the GBT this applies mainly to Argus, although the Q-band receiver also has a vane. For the background on the calibration please refer to Frayer et al. 2019.
Dysh commands#
The following dysh commands are introduced (leaving out all the function arguments):
filename = dysh_data()
sdf = GBTFITSLoad()
sb = sdf.getfs()
v = sdf.getvane()
ta = sb.timeaverage()
ta.baseline()
ta.average()
ta.plot()
ta1.oshow()
Loading Modules#
We start by loading the modules we will use for this example.
# These modules are required for the data reduction.
from dysh.fits import GBTFITSLoad
from astropy import units as u
from dysh.log import init_logging
# These modules are used for file I/O
from dysh.util.files import dysh_data
from pathlib import Path
Setup#
dysh uses a logger to communicate. If you are working in the command line, then the logging is setup for you. If you are working in a jupyter lab instance, then you need to set it up. You can do so using the init_logging function imported above. As an argument, init_logging takes a number, the verbosity level. level 0 is for error messages only, 1 for warning, 2 for info and 3 for debug. Here we set it to level 2.
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(example="vane")
23:09:23.171 I Resolving example=vane -> fs-Argus/data/AGBT20B_295_02.raw.vegas/AGBT20B_295_02.raw.vegas.A.fits
23:09:23.172 I url: http://www.gb.nrao.edu/dysh//example_data/fs-Argus/data/AGBT20B_295_02.raw.vegas/AGBT20B_295_02.raw.vegas.A.fits
Downloading AGBT20B_295_02.raw.vegas.A.fits from http://www.gb.nrao.edu/dysh//example_data/fs-Argus/data/AGBT20B_295_02.raw.vegas/AGBT20B_295_02.raw.vegas.A.fits
23:09:23.457 I Starting download...
23:09:24.609 I Saved AGBT20B_295_02.raw.vegas.A.fits to AGBT20B_295_02.raw.vegas.A.fits
Retrieved AGBT20B_295_02.raw.vegas.A.fits
Data Loading#
Next, we use GBTFITSLoad to load the data, and then its summary method to inspect its contents.
sdfits = GBTFITSLoad(filename)
sdfits.summary()
| SCAN | OBJECT | VELOCITY | PROC | PROCSEQN | RESTFREQ | # IF | # POL | # INT | # FEED | AZIMUTH | ELEVATION |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 10 | VANE | 65.0 | Track | 1 | 93.173777 | 1 | 1 | 25 | 2 | 166.9878 | 43.5400 |
| 11 | SKY | 65.0 | Track | 1 | 93.173777 | 1 | 1 | 25 | 2 | 166.9875 | 43.5399 |
| 12 | G24.789 | 65.0 | Track | 1 | 93.173777 | 1 | 1 | 151 | 2 | 167.4363 | 43.6122 |
This is a frequency switched observation with Argus. The first two scans, 10 and 11, are observations of the vane and the “cold” sky. The next scan, 12, are the observations of the target using frequency switching.
Data Reduction#
To calibrate data using a vane we can use the same methods as with any other observations, with the difference that we must specify the vane argument.
This argument can be an integer, with the scan number of the vane observations (in this case scan 10), or it can be a
VaneSpectrum
object.
Calibration with Vane#
We will show how to calibrate the data providing a scan number for the vane argument.
We call
getfs
with vane=10.
If working from one of the GBO data reduction hosts, this will initialize a
VaneSpectrum
and determine the zenith opacity and atmospheric temperature from the CLEO weather forecast scripts.
If working from elsewhere, then by default these values are not known and the vane calibration will use an approximation to determine the system temperature (equation (23) in Frayer et al. 2019).
For this data set we know that feeds 10 and 8 are available, we use fdnum=10, and only a single spectral window and polarization are available, so we use ifnum=0 and plnum=0.
ta = sdfits.getfs(scan=12, ifnum=0, plnum=0, fdnum=10, vane=10).timeaverage()
23:09:24.751 I Vane calibrated data will be calibrated to Ta* units by default.
23:09:25.709 I Weather forecast not available.
23:09:25.842 I Ignoring 1 blanked integration(s).
23:09:25.948 I Vane temperature (twarm): 400.15 K
23:09:25.949 I No zenith opacity nor atmospheric temperature available. Will approximate the calibration temperature to the vane temperature 400.15 K
23:09:25.950 I Mean calibration temperature (tcal): 400.15 K
The above messages tells us what values for the different parameters required to determine the system temperature were adopted.
Next, we plot the calibrated spectrum.
plot = ta.plot(xaxis_unit="GHz")
We see a clear signal at about 93.150 GHz, and it’s “ghost” at 93.055 GHz.
Changing default values#
The parameters required to determine the system temperature using a vane are: the zenith opacity (zenith_opacity), vane temperature (t_warm), atmospheric temperature (t_atm) and background temperature (t_bkg).
From these a calibration temperature (t_cal) is derived.
These can be modified by providing values for them as arguments to the calibration method.
In the following code, we modify the first four parameters used to derive the calibration temperature.
We set zenith_opacity=0.01 in nepers, t_warm=583 in K, t_atm=260 in K and t_bkg=3.
We use a higher vane temperature so we can see the difference when comparing the results.
ta2 = sdfits.getfs(scan=12, ifnum=0, plnum=0, fdnum=10, vane=10,
zenith_opacity=0.01,
t_warm=583,
t_atm=260,
t_bkg=3,
).timeaverage()
23:09:27.858 I Vane calibrated data will be calibrated to Ta* units by default.
23:09:28.229 I Weather forecast not available.
23:09:28.355 I Ignoring 1 blanked integration(s).
23:09:28.457 I Vane temperature (twarm): 583.00 K
23:09:28.458 I Mean calibration temperature (tcal): 584.97 K
Now we plot both results on top of each other, with the increased vane temperature spectrum in blue and the original spectrum in orange.
plot2 = ta2.plot(xaxis_unit="GHz")
plot2.oshow(ta)
The effect of having a larger vane temperature is to increase the derived system temperature, so the resulting spectrum is scaled up.
We can check the system temperature by inspecting the “TSYS” item of the Spectrum.meta dictionary.
print(ta.meta["TSYS"], ta2.meta["TSYS"])
173.0724666317342 253.01146158520933
Alternatively, we can directly provide a value for the calibration temperature, and get the same result. From the output of the previous example, we had a calibration temperature of 584.97 K.
ta3 = sdfits.getfs(scan=12, ifnum=0, plnum=0, fdnum=10, vane=10,
t_cal=584.97
).timeaverage()
23:09:30.416 I Vane calibrated data will be calibrated to Ta* units by default.
23:09:30.782 I Weather forecast not available.
23:09:30.908 I Ignoring 1 blanked integration(s).
We plot this and the previous result on top of each other to confirm that they are the same.
plot3 = ta3.plot(xaxis_unit="GHz")
plot3.oshow(ta2)
Creating a VaneSpectrum Object#
For more control, or developing alternative data reduction approaches, one could create a VaneSpectrum object directly. There are two ways of doing so, using getvane, or directly instantiating a VaneSpectrum object by directly providing the input values, or from a Spectrum object using VaneSpectrum.from_spectrum. Here we will show how to use getvane.
The arguments are the same as those provided for the calibration.
vane = sdfits.getvane(scan=10, ifnum=0, plnum=0, fdnum=10,
zenith_opacity=0.01,
t_warm=583,
t_atm=260,
t_bkg=3)
23:09:33.407 I Weather forecast not available.
The calibration temperature can be obtained using the VaneSpectrum.get_tcal method. This takes as input a reference Spectrum, For example:
ref = sdfits.gettp(scan=11, ifnum=0, plnum=0, fdnum=10).timeaverage()
23:09:33.460 I Using TSYS column
vane.get_tcal(ref)
23:09:33.686 I Vane temperature (twarm): 583.00 K
23:09:33.687 I Mean calibration temperature (tcal): 584.98 K
np.float64(584.9782633701202)
And the system temperature using the VaneSpectrum.get_tsys method, which also takes as input a reference Spectrum.
vane.get_tsys(ref)
23:09:33.693 I Vane temperature (twarm): 583.00 K
23:09:33.694 I Mean calibration temperature (tcal): 584.98 K
np.float64(250.1676896502541)
As mentioned earlier, it is also possible to directly provide a
VaneSpectrum
to the calibration methods. In this case, the additional parameters (t_warm, t_atm, t_bkg and t_cal are ignored).
For example:
ta4 = sdfits.getfs(scan=12, ifnum=0, plnum=0, fdnum=10, vane=vane).timeaverage()
plot4 = ta4.plot(xaxis_unit="GHz")
23:09:33.700 I Vane calibrated data will be calibrated to Ta* units by default.
23:09:33.701 I Will use a zenith opacity of 0.01 nepers. Taken from vane.
23:09:33.834 I Ignoring 1 blanked integration(s).
23:09:33.941 I Vane temperature (twarm): 583.00 K
23:09:33.942 I Mean calibration temperature (tcal): 584.97 K
We also note that when providing the vane argument during calibration, the system temperature argument t_sys is ignored.
Final Stats#
Finally, at the end we compute some statistics over a spectrum, merely as a checksum if the notebook is reproducible.
ta4.check_stats(2.05290008 * u.K)
23:09:35.615 I rms is OK
ta4[1500:8500].radiometer()
23:09:35.680 I Note: found 1 NaN (masked) values
np.float64(0.9100977688428992)