Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/164.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added remote FITS header fetching for the e-Callisto client to provide accurate start and end times in search results.
59 changes: 54 additions & 5 deletions radiospectra/net/sources/ecallisto.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
from sunpy.net.dataretriever.client import GenericClient

from radiospectra.net.attrs import Observatory

import zlib
import urllib.request
from astropy.io import fits
from astropy.time import Time

class eCALLISTOClient(GenericClient):
"""
Expand Down Expand Up @@ -62,10 +65,28 @@ def post_search_hook(self, exdict, matchdict):
original = super().post_search_hook(exdict, matchdict)
original["ID"] = original["suffix"].replace("_", "")
del original["suffix"]
# We don't know the end time for all files
# https://github.com/sunpy/radiospectra/issues/60
del original["End Time"]
return original
url = exdict.get('url')
if url:
start_h, end_h = self._fetch_remote_header(url)
if start_h:
try:
original["Start Time"] = Time(start_h)
except Exception:
pass

if end_h:
try:
original["End Time"] = Time(end_h)
except Exception:
original["End Time"] = end_h
else:
if "End Time" in original:
del original["End Time"]
else:
if "End Time" in original:
del original["End Time"]

return original

@classmethod
def register_values(cls):
Expand Down Expand Up @@ -97,3 +118,31 @@ def _can_handle_query(cls, *query):
):
return False
return True
def _fetch_remote_header(self, url):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a test or two maybe one mocked and one against the real server?

headers = {'User-Agent': 'SunPy/Radiospectra', 'Range': 'bytes=0-15360'}
req = urllib.request.Request(url, headers=headers)
try:
with urllib.request.urlopen(req, timeout=5) as response:
if response.getcode() == 206:
compressed_data = response.read()
# e-Callisto files are .gz, so we need to decompress
d = zlib.decompressobj(16 + zlib.MAX_WBITS)
header_bytes = d.decompress(compressed_data)
header = fits.Header.fromstring(header_bytes[:2880].decode('ascii', errors='ignore'))

# Get Date and Time keywords
date_obs = header.get('DATE-OBS')
time_obs = header.get('TIME-OBS', '')
date_end = header.get('DATE-END', date_obs)
time_end = header.get('TIME-END', '')

# Combine into strings for Astropy Time
start = f"{date_obs} {time_obs}".strip()
end = f"{date_end} {time_end}".strip()

return (start if date_obs else None), (end if date_end else None)
except Exception:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very broad exception need to narrow down a bit to what you expect

return None, None
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should probably log or warn the user

return None, None