Skip to content

Commit

Permalink
Merge pull request #80 from GreenBankObservatory/pedro-devel
Browse files Browse the repository at this point in the history
Adds GB 20m module and updates the docs
  • Loading branch information
astrofle authored Aug 31, 2023
2 parents 03ad87f + 7d15a04 commit cc13e81
Show file tree
Hide file tree
Showing 13 changed files with 261 additions and 104 deletions.
Binary file added docs/source/_static/examples/gbt_ps_2.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@
numpydoc_show_class_members = True
autosummary_generate = True

autodoc_docstring_signature = True
autodoc_default_options = {'members': None, 'undoc-members': None}

# Make sure the targets are unique
autosectionlabel_prefix_document = True

# TODO: These appear to have no effect
mermaid_init_js = "mermaid.initialize({startOnLoad:true, useMaxWidth:false});"

Expand Down
97 changes: 91 additions & 6 deletions docs/source/examples/positionswitch.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,87 @@
Position-Switched Data
**********************

Background
==========

Position switched observations are those in which the telescope observes a target (the ON position or signal) and another part of the sky, assumed to be devoid of emission (the OFF position or reference).

.. image:: ../_static/examples/gbt_ps_2.gif

While observing this is accomplished using the functions `OnOff` or `OffOn` in a scheduling block. For more details about these functions see Sections 6.4.2.2 and 6.4.2.3 of the |gbtog_link|.

.. |gbtog_link| raw:: html

<a href="http://www.gb.nrao.edu/scienceDocs/GBTog.pdf" target="_blank">GBT observer's guide</a>

A modified version of the scheduling block for the observations used in this example is copied below::

# Observing script for NGC 2415

# GBT Observing: TGBT21A_501
# Total power position switch, L-band, VEGAS
# Targets the HI 21 cm line and the four 18 cm OH lines.

# Setup configuration
HI_OH_config ='''
receiver = 'Rcvr1_2'
obstype = 'Spectroscopy'
backend = 'VEGAS'
restfreq = 1420.4057517,1612.231,1665.4018,1667.3590,1720.5299
nwin = 5
bandwidth = 23.44
nchan = 32768
swmode = 'tp'
swtype = 'none'
swper = 1.0
tint = 2
vframe = 'bary'
vdef = 'Optical'
noisecal = 'lo'
pol = 'Linear'
'''

# Setup catalog of calibrators.
Catalog('fluxcal')

# Define catalog of targets.
target_cat = """
format=spherical
coordmode=J2000
HEAD=NAME RA DEC
NGC2415 07:36:56.66 +35:14:30.55
"""
Catalog(target_cat)
# Slew to target.
Slew('NGC2415')

# Start finding pointing and focus corrections.i
# Without argument AutoPeakFocus will try to find
# a suitable pointing calibrator.
AutoPeakFocus()
# After an Auto procedure it is necessary to reconfigure.
Configure(HI_OH_config)

# Slew to the target and adjust the power levels.
Slew('NGC2415')
Balance()

# Observe a source of known flux density to find the
# equivalent temperature/flux of the noise diode.
# This will be used to calibrate the flux scale.
OnOff('3C196', Offset('J2000', 0.0, 1.0, cosv=True), 60)

# Observe the target using OnOff for a total of ~10 minutes.
numobs = 1
for i in range(numobs):
OnOff('NGC2415',
Offset('J2000', 0.4042, 0.263), 300)




Calibrating Position-Switched Data
==================================

Expand Down Expand Up @@ -31,19 +112,19 @@ You can also print a concise (or verbose if you choose `verbose=True`) summary :

>>> sdfits.summary()
SCAN OBJECT VELOCITY PROC PROCSEQN RESTFREQ DOPFREQ # IF # POL # INT # FEED AZIMUTH ELEVATIO
0 152.0 NGC2415 3784.0 OnOff 1.0 1.617185 1.420406 5 2 151 1 286.218008 41.62843
1 153.0 NGC2415 3784.0 OnOff 2.0 1.617185 1.420406 5 2 151 1 286.886521 41.118134
0 152 NGC2415 3784.0 OnOff 1 1.617185 1.420406 5 2 151 1 286.218008 41.62843
1 153 NGC2415 3784.0 OnOff 2 1.617185 1.420406 5 2 151 1 286.886521 41.118134

Retrieve a scan and its partner ON or OFF, selecting and IF number and polarization, then calibrate it::
Retrieve a scan and its partner ON or OFF, selecting an IF number and polarization, then calibrate it::

>>> psscan = sdfits.getps(152, ifnum=0, plnum=0)
>>> psscan.calibrate() # this will be eventually be subsumed into `calibrate=True` in `getps`
PSSCAN nrows = 302
The system temperature array (numpy.ndarray) is stored in `tsys`::
The system temperature array (`numpy.ndarray`) is stored in `tsys`::

>>> print(f"T_sys = {pscan.tsys.mean():.2f}:")
T_sys = 17.17
>>> print(f"T_sys = {pscan.tsys.mean():.2f} K")
T_sys = 17.17 K

Then time average the data, using system temperature weighting (other option is 'equal' weighting; 'tsys' is the default if no `weights` parameter is given. Future upgrade will allow the user to provide a numeric weights array). The returned object is :class:`~dysh.spectra.spectrum.Spectrum`, which has a default `matplotlib`-based plotter attached::

Expand All @@ -60,6 +141,10 @@ The :meth:`~dysh.spectra.spectrum.Spectrum.plot` command allows changing of axis

.. image:: ../_static/examples/ps_152_zoom.png

.. WARNING::
At this point, `dysh` does not handle Doppler corrections. So the frequency and velocity information will be wrong for observations requesting a reference frame other than Topocentric.


Removing a baseline
===================

Expand Down
68 changes: 39 additions & 29 deletions docs/source/examples/subbeamnod.rst
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
***************
SubBeamNod Data
***************
**********
SubBeamNod
**********

SubBeamNod scans with the GBT consist of using the subreflector to alternate between an on and an off position between two feeds on a receiver.

Calibrating SubBeamNod Data
===========================

For this example we will be using data from a receiver checkout, TRCO_230413_Ka. The data can be downloaded from this `link <http://www.gb.nrao.edu/dysh/example_data/subbeamnod-Ka/data/TRCO_230413_Ka.raw.vegas/TRCO_230413_Ka.raw.vegas.A.fits>`_. Or, using `wget`::

>>> import wget
>>> url = "http://www.gb.nrao.edu/dysh/example_data/subbeamnod-Ka/data/TRCO_230413_Ka.raw.vegas/TRCO_230413_Ka.raw.vegas.A.fits"
>>> filename = wget.download(url)
>>> print(filename)
TRCO_230413_Ka.raw.vegas.A.fits

SubBeamNod data is retrieved using :meth:`~dysh.fits.gbtfitsload.GBTFITSLoad.subbeamnod` which returns a :class:`~dysh.spectra.spectra.Spectrum` object.

SubBeamNod data, where a single pixel in a pixel camera is used to do a beam nod, is retrieved using :meth:`~dysh.fits.gbtfitsload.GBTFITSLoad.subbeamnod` which returns a :class:`~dysh.spectra.spectra.Spectrum` object. First, import the relevant module::
First, import the relevant module::

>>> from dysh.fits.gbtfitsload import GBTFITSLoad

.. (TODO need to replace fixed path with get_example_data() and explanation thereof)::

Then load your SDFITS file containing SubBeamNod data. In this example, we use a
`GBT SDFITS file downloadable from GBO <http://www.gb.nrao.edu/dysh/example_data/subbeamnod-Ka/data/TRCO_230413_Ka.raw.vegas/TRCO_230413_Ka.raw.vegas.A.fits'>_``
Then load your SDFITS file containing SubBeamNod data::

>>> f = 'TRCO_230413_Ka.raw.vegas.A.fits'
>>> sdfits = GBTFITSLoad(f)
>>> filename = 'TRCO_230413_Ka.raw.vegas.A.fits'
>>> sdfits = GBTFITSLoad(filename)

The returned `sdfits` can be probed for information::

Expand All @@ -26,31 +36,31 @@ The returned `sdfits` can be probed for information::
0 PRIMARY 1 PrimaryHDU 12 ()
1 SINGLE DISH 1 BinTableHDU 245 5280R x 74C ['32A', '1D', '22A', '1D', '1D', '1D', '1024E', '16A', '6A', '8A', '1D', '1D', '1D', '4A', '1D', '4A', '1D', '1I', '32A', '32A', '1J', '32A', '16A', '1E', '8A', '1D', '1D', '1D', '1D', '1D', '1D', '1D', '1D', '1D', '1D', '1D', '1D', '8A', '1D', '1D', '12A', '1I', '1I', '1D', '1D', '1I', '1A', '1I', '1I', '16A', '16A', '1J', '1J', '22A', '1D', '1D', '1I', '1A', '1D', '1E', '1D', '1D', '1D', '1D', '1D', '1A', '1A', '8A', '1E', '1E', '16A', '1I', '1I', '1I']

You can also print a concise (or verbose if you choose `verbose=True`) summary :meth:`~dysh.fits.gbtfitsload.GBTFITSLoad.summary` of the data::
You can also print a concise (or verbose if you choose `verbose=True`) :meth:`~dysh.fits.gbtfitsload.GBTFITSLoad.summary` of the data::

>>> sdfits.summary()
SCAN OBJECT VELOCITY PROC PROCSEQN RESTFREQ DOPFREQ # IF # POL # INT # FEED AZIMUTH ELEVATIO
0 32.0 1256-0547 0.0 Nod 1.0 26.5 26.5 1 2 30 2 160.975324 43.884984
1 33.0 1256-0547 0.0 Nod 2.0 26.5 26.5 1 2 30 2 161.174093 43.928449
2 34.0 1256-0547 0.0 Nod 1.0 30.5 30.5 1 2 30 2 161.589629 44.000491
3 35.0 1256-0547 0.0 Nod 2.0 30.5 30.5 1 2 30 2 161.783395 44.041622
4 36.0 1256-0547 0.0 Unknown 0.0 0.75 0.75 1 2 120 2 162.124052 44.100404
5 37.0 1256-0547 0.0 Nod 1.0 34.5 34.5 1 2 30 2 162.611075 44.183661
6 38.0 1256-0547 0.0 Nod 2.0 34.5 34.5 1 2 30 2 162.896506 44.237997
7 39.0 1256-0547 0.0 Nod 1.0 37.5 37.5 1 2 30 2 163.333508 44.306385
8 40.0 1256-0547 0.0 Nod 2.0 37.5 37.5 1 2 30 2 163.529285 44.343704
9 41.0 1256-0547 0.0 Nod 1.0 30.5 30.5 1 2 30 2 164.941425 44.559629
10 42.0 1256-0547 0.0 Nod 2.0 30.5 30.5 1 2 30 2 165.139436 44.593378
11 43.0 1256-0547 0.0 SubBeamNod 1.0 30.5 30.5 1 2 120 2 165.469522 44.639023
12 44.0 1256-0547 0.0 Nod 1.0 30.5 30.5 1 2 30 2 166.48287 44.776997
13 45.0 1256-0547 0.0 Nod 2.0 30.5 30.5 1 2 30 2 166.688378 44.808119
14 46.0 1256-0547 0.0 SubBeamNod 1.0 30.5 30.5 1 2 120 2 167.026583 44.849753
15 52.0 1256-0547 0.0 Nod 1.0 30.5 30.5 1 2 30 2 169.972904 45.179358
16 53.0 1256-0547 0.0 Nod 2.0 30.5 30.5 1 2 30 2 170.175815 45.201877
17 54.0 1256-0547 0.0 SubBeamNod 1.0 30.5 30.5 1 2 120 2 170.518885 45.232575
SCAN OBJECT VELOCITY PROC PROCSEQN RESTFREQ DOPFREQ # IF # POL # INT # FEED AZIMUTH ELEVATIO
0 32 1256-0547 0.0 Nod 1 26.5 26.5 1 2 60 2 160.975324 43.884984
1 33 1256-0547 0.0 Nod 2 26.5 26.5 1 2 60 2 161.174093 43.928449
2 34 1256-0547 0.0 Nod 1 30.5 30.5 1 2 60 2 161.589629 44.000491
3 35 1256-0547 0.0 Nod 2 30.5 30.5 1 2 60 2 161.783395 44.041622
4 36 1256-0547 0.0 Unknown 0 0.75 0.75 1 2 120 2 162.124052 44.100404
5 37 1256-0547 0.0 Nod 1 34.5 34.5 1 2 60 2 162.611075 44.183661
6 38 1256-0547 0.0 Nod 2 34.5 34.5 1 2 60 2 162.896506 44.237997
7 39 1256-0547 0.0 Nod 1 37.5 37.5 1 2 60 2 163.333508 44.306385
8 40 1256-0547 0.0 Nod 2 37.5 37.5 1 2 60 2 163.529285 44.343704
9 41 1256-0547 0.0 Nod 1 30.5 30.5 1 2 60 2 164.941425 44.559629
10 42 1256-0547 0.0 Nod 2 30.5 30.5 1 2 60 2 165.139436 44.593378
11 43 1256-0547 0.0 SubBeamNod 1 30.5 30.5 1 2 120 2 165.469522 44.639023
12 44 1256-0547 0.0 Nod 1 30.5 30.5 1 2 60 2 166.48287 44.776997
13 45 1256-0547 0.0 Nod 2 30.5 30.5 1 2 60 2 166.688378 44.808119
14 46 1256-0547 0.0 SubBeamNod 1 30.5 30.5 1 2 120 2 167.026583 44.849753
15 52 1256-0547 0.0 Nod 1 30.5 30.5 1 2 60 2 169.972904 45.179358
16 53 1256-0547 0.0 Nod 2 30.5 30.5 1 2 60 2 170.175815 45.201877
17 54 1256-0547 0.0 SubBeamNod 1 30.5 30.5 1 2 120 2 170.518885 45.232575

The SubBeamNod scans are 43, 46, and 54. Retrieve and calibrate a SubBeamNod scan, then plot it::

>>> sbn = sdfits.subbeamnod(scan=43,fdnum=1,ifnum=0,weights='tsys')
>>> sbn = sdfits.subbeamnod(scan=43, fdnum=1, ifnum=0, weights='tsys')
>>> sbn.plot()

12 changes: 11 additions & 1 deletion docs/source/for_beta_testers/beta_testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,14 @@
Instructions for Beta Testers
*****************************

Instructions
Instructions

Providing feedback
==================

If you encounter a problem with `dysh`, would like to request a new feature or enhancement or would like to leave feedback, please do so using `GitHub issues <https://github.com/GreenBankObservatory/dysh/issues>`_. There are some basic instructions of how to do this :ref:`here <for_developers/github_integrations:issues>`.

Example feedback
----------------

Give and example of how to provide useful feedback when facing an issue.
11 changes: 6 additions & 5 deletions docs/source/for_developers/github_integrations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ Actions

Tests should be named `test_*.py` and located within a `tests` directory of their parent module. To define a workflow that runs the tests, create a new `.yml` file in `dysh/.github/workflows/`.

To submit an issue, use the following steps:
* Go to https://github.com/GreenBankObservatory/dysh/issues
* Select "New Issue"

Issues
======

We use GitHub Issues to keep track of things that need doing. If you can't get to something right away, might as well make an issue so we remember to do it. Beta testers will also use issues to report on their findings.

To submit an issue, use the following steps:

1. Go to https://github.com/GreenBankObservatory/dysh/issues
2. Select "New Issue"

.. figure:: ../_static/for_developers/GitHub_Issue.png

Pre-Commit Hooks
Expand All @@ -26,4 +27,4 @@ Take a look at `dysh/.pre-commit-config.yaml`.
Projects
========

There are 2 GitHub Projects defined for this repository.
There are 2 GitHub Projects defined for this repository.
2 changes: 1 addition & 1 deletion src/dysh/fits/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
"""Classes and functions for importing SDFITS files"""
__all__ = [ "gbtfitsload", "sdfitsload" ]
__all__ = [ "gbtfitsload", "sdfitsload", "gb20mfitsload" ]
36 changes: 36 additions & 0 deletions src/dysh/fits/gb20mfitsload.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""Load SDFITS files produced for GBO's 20m telescope """

from dysh.fits.sdfitsload import SDFITSLoad


class GB20MFITSLoad(SDFITSLoad):

def __init__(self, filename, source=None, hdu=None, **kwargs):
SDFITSLoad.__init__(self, filename, source, hdu)
self._fix_columns()


def _str_idx(self, text, bad_char="\x00"):
"""
"""
try:
idx = text.index(bad_char)
except ValueError:
idx = None
return idx


def _fix_columns(self):
"""
"""

bad_char="\x00"

for i in range(len(self._bintable)):
for j in range(self._binheader[i]["NAXIS2"]):
text = self._bintable[i].data[j]["OBJECT"]
idx = self._str_idx(text, bad_char="\x00")
self._bintable[i].data[j]["OBJECT"] = text[:idx]
text = self._bintable[i].data[j]["OBSERVER"]
idx = self._str_idx(text, bad_char="\x00")
self._bintable[i].data[j]["OBSERVER"] = text[:idx]
6 changes: 6 additions & 0 deletions src/dysh/fits/gbtfitsload.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ def summary(self, scans=None, verbose=False, bintable=0):
"SCAN", "OBJECT", "VELOCITY", "PROC", "PROCSEQN",
"RESTFREQ", "DOPFREQ", "# IF","# POL", "# INT", "# FEED",
"AZIMUTH", "ELEVATIO"]
# In the process, some columns get cast to floats or others. Make sure we cast them
# back to an appropriate data type before return.
col_dtypes = {"SCAN": int, "PROCSEQN": int}
uncompressed_df = None
if self._ptable is None:
self._create_index()
Expand Down Expand Up @@ -118,7 +121,9 @@ def summary(self, scans=None, verbose=False, bintable=0):
uncompressed_df = pd.concat([uncompressed_df,_df.filter(show)])

if verbose:
uncompressed_df = uncompressed_df.astype(col_dtypes)
return uncompressed_df

# do the work to compress the info
# in the dataframe on a scan basis
compressed_df = pd.DataFrame(columns = comp_colnames)
Expand Down Expand Up @@ -153,6 +158,7 @@ def summary(self, scans=None, verbose=False, bintable=0):
compressed_df = pd.concat(
[compressed_df,ser.to_frame().T],
ignore_index=True)
compressed_df = compressed_df.astype(col_dtypes)
return compressed_df

def velocity_convention(self,veldef,velframe):
Expand Down
Loading

0 comments on commit cc13e81

Please sign in to comment.