Skip to content

Commit 9a4e467

Browse files
Merge pull request #119 from Stanford-NavLab/ashwin/doc-links
Ashwin/doc links
2 parents b284c02 + d06295a commit 9a4e467

4 files changed

Lines changed: 173 additions & 8 deletions

File tree

docs/source/conf.py

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
#
1313
import os
1414
import sys
15+
import inspect
16+
import subprocess
17+
from os.path import relpath, dirname
18+
19+
1520
sys.path.insert(0, os.path.abspath('.'))
1621
sys.path.insert(0, os.path.abspath('../'))
1722
sys.path.insert(0, os.path.abspath('../../'))
@@ -40,6 +45,7 @@
4045
extensions = [
4146
'sphinx.ext.autodoc',
4247
'sphinx.ext.napoleon',
48+
'sphinx.ext.linkcode',
4349
'nbsphinx',
4450
'nbsphinx_link',
4551
'IPython.sphinxext.ipython_console_highlighting',
@@ -104,3 +110,124 @@
104110

105111
# document __init__ methods
106112
autoclass_content = 'both'
113+
114+
# Function to find URLs for the source code on GitHub for built docs
115+
116+
# The original code to find the head tag was taken from:
117+
# https://gist.github.com/nlgranger/55ff2e7ff10c280731348a16d569cb73
118+
# This code was modified to use the current commit when the code differs from
119+
# main or a tag
120+
121+
#Default to the main branch
122+
linkcode_revision = "main"
123+
124+
125+
#Default to the main branch, default to main and tags not existing
126+
linkcode_revision = "main"
127+
in_main = False
128+
tagged = False
129+
130+
131+
# lock to commit number
132+
cmd = "git log -n1 --pretty=%H"
133+
head = subprocess.check_output(cmd.split()).strip().decode('utf-8')
134+
# if we are on main's HEAD, use main as reference irrespective of
135+
# what branch you are on
136+
cmd = "git log --first-parent main -n1 --pretty=%H"
137+
main = subprocess.check_output(cmd.split()).strip().decode('utf-8')
138+
if head == main:
139+
in_main = True
140+
141+
# if we have a tag, use tag as reference, irrespective of what branch
142+
# you are actually on
143+
try:
144+
cmd = "git describe --exact-match --tags " + head
145+
tag = subprocess.check_output(cmd.split(" ")).strip().decode('utf-8')
146+
linkcode_revision = tag
147+
tagged = True
148+
except subprocess.CalledProcessError:
149+
pass
150+
151+
# If the current branch is main, or a tag exists, use the branch name.
152+
# If not, use the commit number
153+
if not tagged and not in_main:
154+
linkcode_revision = head
155+
156+
linkcode_url = "https://github.com/Stanford-NavLab/gnss_lib_py/blob/" \
157+
+ linkcode_revision + "/{filepath}#L{linestart}-L{linestop}"
158+
159+
160+
161+
def linkcode_resolve(domain, info):
162+
"""Return GitHub link to Python file for docs.
163+
164+
This function does not return a link for non-Python objects.
165+
For Python objects, `domain == 'py'`, `info['module']` contains the
166+
name of the module containing the method being documented, and
167+
`info['fullname']` contains the name of the method.
168+
169+
Notes
170+
-----
171+
Based off the numpy implementation of linkcode_resolve:
172+
https://github.com/numpy/numpy/blob/2f375c0f9f19085684c9712d602d22a2b4cb4c8e/doc/source/conf.py#L443
173+
Retrieved on 1 Jul, 2023.
174+
"""
175+
if domain != 'py':
176+
return None
177+
178+
modname = info['module']
179+
fullname = info['fullname']
180+
submod = sys.modules.get(modname)
181+
if submod is None:
182+
return None
183+
184+
obj = submod
185+
for part in fullname.split('.'):
186+
try:
187+
obj = getattr(obj, part)
188+
except Exception:
189+
return None
190+
191+
# strip decorators, which would resolve to the source of the decorator
192+
# possibly an upstream bug in getsourcefile, bpo-1764286
193+
try:
194+
unwrap = inspect.unwrap
195+
except AttributeError:
196+
pass
197+
else:
198+
obj = unwrap(obj)
199+
filepath = None
200+
lineno = None
201+
202+
if filepath is None:
203+
try:
204+
filepath = inspect.getsourcefile(obj)
205+
except Exception:
206+
filepath = None
207+
if not filepath:
208+
return None
209+
#NOTE: Re-export filtering turned off because
210+
# # Ignore re-exports as their source files are not within the gnss_lib_py repo
211+
# module = inspect.getmodule(obj)
212+
# if module is not None and not module.__name__.startswith("gnss_lib_py"):
213+
# return "no_module_not_gnss_lib_py"
214+
215+
try:
216+
source, lineno = inspect.getsourcelines(obj)
217+
except Exception:
218+
lineno = ""
219+
# The following line of code first finds the relative path from
220+
# the location of conf.py and then goes up to the root directory
221+
222+
root_glp_path = os.path.join(dirname(os.path.abspath(__file__)), '../..')
223+
filepath = relpath(filepath, root_glp_path)
224+
225+
if lineno:
226+
linestart = lineno
227+
linestop = lineno + len(source) - 1
228+
else:
229+
linestart = ""
230+
linestop = ""
231+
codelink = linkcode_url.format(
232+
filepath=filepath, linestart=linestart, linestop=linestop)
233+
return codelink

docs/source/reference/reference.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,29 @@ in learning more about GNSS:
2626
a visually-appealing and interactive blog post about some of the
2727
basic principles of GNSS positioning.
2828

29+
Reference Documents for GNSS Standards
30+
--------------------------------------
31+
32+
GNSS constellations and receivers use standardized file formats to transfer
33+
information such as estimated receiver coordinates, broadcast ephemeris
34+
parameters, and precise ephimerides.
35+
The parsers in ``gnss_lib_py`` are based on standard documentation for
36+
the GNSS constellations and file types, which are listed below along with
37+
their use in ``gnss_lib_py``.
38+
39+
* *Rinex v2.11* (`version format document <https://geodesy.noaa.gov/corsdata/RINEX211.txt>`__
40+
retrieved on 2nd July, 2023): for parsing broadcast navigation ephimerides.
41+
* *Rinex v3.05* (`version format document <https://files.igs.org/pub/data/format/rinex305.pdf>`__
42+
retrieved on 2nd July, 2023): for parsing broadcast navigation ephimerides.
43+
* *Rinex v4.00* (`version format document <https://files.igs.org/pub/data/format/rinex_4.00.pdf>`__
44+
retrieved on 2nd July, 2023): currently not supported by ``gnss_lib_py``.
45+
* *NMEA* (`reference manual <https://www.sparkfun.com/datasheets/GPS/NMEA%20Reference%20Manual-Rev2.1-Dec07.pdf>`__
46+
retrieved on 23rd June, 2023): for parsing NMEA files with GGA and RMC messages.
47+
* *SP3*: used to determine SV positions for precise
48+
* *GLONASS ICD* (retrieved from this `link <https://www.unavco.org/help/glossary/docs/ICD_GLONASS_4.0_(1998)_en.pdf>`__
49+
retrieved on 27th June, 2023): for determining GLOASS SV states from
50+
broadcast satellite positions, velocities, and accelerations.
51+
2952
Package Architecture
3053
--------------------
3154

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "gnss-lib-py"
3-
version = "0.1.11"
3+
version = "0.1.12"
44
description = "Modular Python tool for parsing, analyzing, and visualizing Global Navigation Satellite Systems (GNSS) data and state estimates"
55
authors = ["Derek Knowles <dcknowles@stanford.edu>",
66
"Ashwin Kanhere <akanhere@stanford.edu>",

tests/parsers/test_ephemeris.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -256,12 +256,24 @@ def test_download_ephem(ephem_download_path, fileinfo):
256256

257257
remove_download_eph(ephem_download_path)
258258

259+
def download_igs(requests_url):
260+
"""Helper function to capture ConnectionError.
261+
262+
"""
263+
response = None
264+
try:
265+
response = requests.get(requests_url, timeout=5)
266+
except requests.exceptions.ConnectionError:
267+
print("ConnectionError.")
268+
269+
return response
270+
259271
@pytest.mark.parametrize('fileinfo',
260272
[
261273
{'filepath': 'IGS/BRDC/2023/099/BRDC00WRD_S_20230990000_01D_MN.rnx.gz',
262274
'url': 'http://igs.bkg.bund.de/root_ftp/'},
263275
])
264-
def test_request_igs(ephem_download_path, fileinfo):
276+
def test_request_igs(capsys, ephem_download_path, fileinfo):
265277
"""Test requests download for igs files.
266278
267279
The reason for this test is that Github workflow actions seem to
@@ -287,14 +299,17 @@ def test_request_igs(ephem_download_path, fileinfo):
287299

288300
requests_url = fileinfo['url'] + fileinfo['filepath']
289301

290-
291302
fail_count = 0
292-
while fail_count < 3:
293-
try:
294-
response = requests.get(requests_url, timeout=5)
295-
break
296-
except ConnectionError:
303+
while fail_count < 3:# download the ephemeris file
304+
response = download_igs(requests_url)
305+
captured = capsys.readouterr()
306+
if "ConnectionError." in captured.out:
297307
fail_count += 1
308+
else:
309+
break
310+
311+
if response is None:
312+
raise requests.exceptions.ConnectionError("IGS ConnectionError.")
298313

299314
with open(dest_filepath,'wb') as file:
300315
file.write(response.content)

0 commit comments

Comments
 (0)