diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8006394..82afcdf 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -19,6 +19,10 @@ Features - Add support for SOLO RPW data. (`#62 <https://github.com/sunpy/radiospectra/pull/62>`__) +Features +-------- +- Add `sunpy.net.Fido` client `~radiospectra.net.sources.ilofar.ILOFARMode357` and spectrogram class `~radiospectra.spectrogram2.sources.ILOFARMode357` for ILOFAR mode 357 observations. (`#57 <https://github.com/sunpy/radiospectra/pull/57>`__) + 0.4.0 (2022-05-24) ================== diff --git a/radiospectra/mixins.py b/radiospectra/mixins.py index 05d44b0..6ecdfc5 100644 --- a/radiospectra/mixins.py +++ b/radiospectra/mixins.py @@ -37,7 +37,10 @@ def plot(self, axes=None, **kwargs): axes.set_title(title) axes.plot(self.times.datetime[[0, -1]], self.frequencies[[0, -1]], linestyle="None", marker="None") - ret = axes.pcolormesh(self.times.datetime, self.frequencies.value, data[:-1, :-1], shading="auto", **kwargs) + if self.times.shape[0] == self.data.shape[0] and self.frequencies.shape[0] == self.data.shape[1]: + ret = axes.pcolormesh(self.times.datetime, self.frequencies.value, data, shading="auto", **kwargs) + else: + ret = axes.pcolormesh(self.times.datetime, self.frequencies.value, data[:-1, :-1], shading="auto", **kwargs) axes.set_xlim(self.times.datetime[0], self.times.datetime[-1]) locator = mdates.AutoDateLocator(minticks=4, maxticks=8) formatter = mdates.ConciseDateFormatter(locator) diff --git a/radiospectra/net/__init__.py b/radiospectra/net/__init__.py index 3b3860e..a71ea41 100644 --- a/radiospectra/net/__init__.py +++ b/radiospectra/net/__init__.py @@ -1,9 +1,18 @@ from radiospectra.net.attrs import * from radiospectra.net.sources.ecallisto import eCALLISTOClient from radiospectra.net.sources.eovsa import EOVSAClient +from radiospectra.net.sources.ilofar import ILOFARMode357Client from radiospectra.net.sources.psp import RFSClient from radiospectra.net.sources.rstn import RSTNClient from radiospectra.net.sources.stereo import SWAVESClient from radiospectra.net.sources.wind import WAVESClient -__all__ = ["eCALLISTOClient", "EOVSAClient", "RFSClient", "SWAVESClient", "RSTNClient", "WAVESClient"] +__all__ = [ + "eCALLISTOClient", + "EOVSAClient", + "RFSClient", + "SWAVESClient", + "RSTNClient", + "WAVESClient", + "ILOFARMode357Client", +] diff --git a/radiospectra/net/sources/ilofar.py b/radiospectra/net/sources/ilofar.py new file mode 100644 index 0000000..c299fce --- /dev/null +++ b/radiospectra/net/sources/ilofar.py @@ -0,0 +1,124 @@ +import numpy as np + +import astropy.units as u +from sunpy.net import attrs as a +from sunpy.net.dataretriever.client import GenericClient, QueryResponse +from sunpy.net.scraper import Scraper +from sunpy.time import TimeRange + +from radiospectra.net.attrs import PolType + +__all__ = ["ILOFARMode357Client"] + +RECEIVER_FREQUENCIES = a.Wavelength(10.546875 * u.MHz, 244.53125 * u.MHz) +DATASET_NAMES = ["rcu357_1beam", "rcu357_1beam_datastream"] + + +class ILOFARMode357Client(GenericClient): + """ + Provides access to I-LOFAR mode 357 observations from the + data `archive <https://data.lofar.ie>`__ + + Examples + -------- + >>> import radiospectra.net + >>> from sunpy.net import Fido, attrs as a + >>> results = Fido.search(a.Time("2021/09/01", "2021/09/21"), + ... a.Instrument('ILOFAR')) # doctest: +REMOTE_DATA + >>> results #doctest: +REMOTE_DATA + <sunpy.net.fido_factory.UnifiedResponse object at ...> + Results from 1 Provider: + <BLANKLINE> + 10 Results from the ILOFARMode357Client: + <BLANKLINE> + Start Time End Time ... Provider Polarisation + ----------------------- ----------------------- ... -------- ------------ + 2021-09-14 07:39:13.000 2021-09-14 07:39:13.999 ... ILOFAR X + 2021-09-14 07:39:13.000 2021-09-14 07:39:13.999 ... ILOFAR Y + 2021-09-01 08:07:29.000 2021-09-01 08:07:29.999 ... ILOFAR X + 2021-09-01 08:07:29.000 2021-09-01 08:07:29.999 ... ILOFAR Y + 2021-09-07 08:07:52.000 2021-09-07 08:07:52.999 ... ILOFAR X + 2021-09-07 08:07:52.000 2021-09-07 08:07:52.999 ... ILOFAR Y + 2021-09-08 08:04:07.000 2021-09-08 08:04:07.999 ... ILOFAR X + 2021-09-08 08:04:07.000 2021-09-08 08:04:07.999 ... ILOFAR Y + 2021-09-08 10:34:31.000 2021-09-08 10:34:31.999 ... ILOFAR X + 2021-09-08 10:34:31.000 2021-09-08 10:34:31.999 ... ILOFAR Y + <BLANKLINE> + <BLANKLINE> + """ + + baseurl = r"https://data.lofar.ie/%Y/%m/%d/bst/kbt/{dataset}/" r"%Y%m%d_\d{{6}}_bst_00\S{{1}}.dat" + + pattern = r"{}/{year:4d}{month:2d}{day:2d}_{hour:2d}{minute:2d}{second:2d}" r"_bst_00{Polarisation}.dat" + + @classmethod + def _check_wavelengths(cls, wavelength): + """ + Check for overlap between given wavelength and receiver frequency coverage defined in + `RECEIVER_FREQUENCIES`. + + Parameters + ---------- + wavelength : `sunpy.net.attrs.Wavelength` + Input wavelength range to check + + Returns + ------- + `bool` + """ + return wavelength.min in RECEIVER_FREQUENCIES or wavelength.max in RECEIVER_FREQUENCIES + + def search(self, *args, **kwargs): + """ + Query this client for a list of results. + + Parameters + ---------- + *args: `tuple` + `sunpy.net.attrs` objects representing the query. + **kwargs: `dict` + Any extra keywords to refine the search. + + Returns + ------- + A `QueryResponse` instance containing the query result. + """ + matchdict = self._get_match_dict(*args, **kwargs) + metalist = [] + + wavelentgh = matchdict.get("Wavelength", False) + if wavelentgh and not self._check_wavelengths(wavelentgh): + return QueryResponse(metalist, client=self) + + tr = TimeRange(matchdict["Start Time"], matchdict["End Time"]) + + for dataset in DATASET_NAMES: + url = self.baseurl.format(dataset=dataset) + scraper = Scraper(url, regex=True) + filesmeta = scraper._extract_files_meta(tr, extractor=self.pattern) + for i in filesmeta: + rowdict = self.post_search_hook(i, matchdict) + metalist.append(rowdict) + + query_response = QueryResponse(metalist, client=self) + mask = np.full(len(query_response), True) + pol = matchdict.get("PolType") + if len(pol) == 1: + pol = pol.upper() + mask = mask & query_response["Polarisation"] == pol + + if query_response: + query_response.remove_column("PolType") + + return query_response[mask] + + @classmethod + def register_values(cls): + adict = { + a.Instrument: [("ILOFAR", "Irish LOFAR STATION (IE63)")], + a.Source: [("ILOFAR", "Irish LOFAR Data Archive")], + a.Provider: [("ILOFAR", "Irish LOFAR Data Archive")], + a.Wavelength: [("*")], + PolType: [("X", "X"), ("X Linear Polarisation", "Y Linear Polarisation")], + } + return adict diff --git a/radiospectra/net/sources/tests/data/ilofar_resp1.html b/radiospectra/net/sources/tests/data/ilofar_resp1.html new file mode 100644 index 0000000..c1d52ed --- /dev/null +++ b/radiospectra/net/sources/tests/data/ilofar_resp1.html @@ -0,0 +1,305 @@ +<ul id="items" class="clearfix"> + <li class="header"> + <a class="icon"></a> + <a class="label ascending" href="#"><span class="l10n-name">Name</span><img src="/_h5ai/public/images/ui/sort.svg" class="sort" alt="sort order"></a> + <a class="date" href="#"><img src="/_h5ai/public/images/ui/sort.svg" class="sort" alt="sort order"><span class="l10n-lastModified">Last modified</span></a> + <a class="size" href="#"><img src="/_h5ai/public/images/ui/sort.svg" class="sort" alt="sort order"><span class="l10n-size">Size</span></a> + </li> + <li class="item folder folder-parent"> + <a href="/2018/06/01/bst/kbt/"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/folder-parent.svg" alt="folder"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/folder-parent.svg" alt="folder"></span> + <span class="label" title="kbt">kbt</span> + <span class="date" data-time="1527880929000">2018-06-01 20:22</span> + <span class="size" data-bytes="null"></span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_100041_bst_00X.dat"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/file.svg" alt="file"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/file.svg" alt="file"></span> + <span class="label" title="20180601_100041_bst_00X.dat">20180601_100041_bst_00X.dat</span> + <span class="date" data-time="1527880954000">2018-06-01 20:22</span> + <span class="size" data-bytes="6012160">6.0 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_100041_bst_00X.png"> + <span class="icon square"><img src="/_h5ai/public/cache/thumbs/thumb-810b3d89f3f5b5e2a4222c38b0b1f1b6cad5d2b1-240x240.jpg" alt="img-png" class="thumb"></span> + <span class="icon landscape"><img src="/_h5ai/public/cache/thumbs/thumb-810b3d89f3f5b5e2a4222c38b0b1f1b6cad5d2b1-320x240.jpg" alt="img-png" class="thumb"></span> + <span class="label" title="20180601_100041_bst_00X.png">20180601_100041_bst_00X.png</span> + <span class="date" data-time="1623407437000">2021-06-11 11:30</span> + <span class="size" data-bytes="875355">875 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_100041_bst_00X_GOES_SWPC.png"> + <span class="icon square"><img src="/_h5ai/public/cache/thumbs/thumb-1df7acdb462acac00eff84f1705c82fd64a5ddfa-240x240.jpg" alt="img-png" class="thumb"></span> + <span class="icon landscape"><img src="/_h5ai/public/cache/thumbs/thumb-1df7acdb462acac00eff84f1705c82fd64a5ddfa-320x240.jpg" alt="img-png" class="thumb"></span> + <span class="label" title="20180601_100041_bst_00X_GOES_SWPC.png">20180601_100041_bst_00X_GOES_SWPC.png</span> + <span class="date" data-time="1623426564000">2021-06-11 16:49</span> + <span class="size" data-bytes="1482381">1.5 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_100041_bst_00X_s.png"> + <span class="icon square"><img src="/_h5ai/public/cache/thumbs/thumb-1a3e731601382b8f93b696a3f152fb489094dbf6-240x240.jpg" alt="img-png" class="thumb"></span> + <span class="icon landscape"><img src="/_h5ai/public/cache/thumbs/thumb-1a3e731601382b8f93b696a3f152fb489094dbf6-320x240.jpg" alt="img-png" class="thumb"></span> + <span class="label" title="20180601_100041_bst_00X_s.png">20180601_100041_bst_00X_s.png</span> + <span class="date" data-time="1527880964000">2018-06-01 20:22</span> + <span class="size" data-bytes="85304">85 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_100041_bst_00Y.dat"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/file.svg" alt="file"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/file.svg" alt="file"></span> + <span class="label" title="20180601_100041_bst_00Y.dat">20180601_100041_bst_00Y.dat</span> + <span class="date" data-time="1527880955000">2018-06-01 20:22</span> + <span class="size" data-bytes="6012160">6.0 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_100041_bst_00Y_GOES_SWPC.png"> + <span class="icon square"><img src="/_h5ai/public/cache/thumbs/thumb-b0f157004fb45a98b6d5745d61684674a294b251-240x240.jpg" alt="img-png" class="thumb"></span> + <span class="icon landscape"><img src="/_h5ai/public/cache/thumbs/thumb-b0f157004fb45a98b6d5745d61684674a294b251-320x240.jpg" alt="img-png" class="thumb"></span> + <span class="label" title="20180601_100041_bst_00Y_GOES_SWPC.png">20180601_100041_bst_00Y_GOES_SWPC.png</span> + <span class="date" data-time="1623426564000">2021-06-11 16:49</span> + <span class="size" data-bytes="1417682">1.4 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_100041_bst_00Y_s.png"> + <span class="icon square"><img src="/_h5ai/public/cache/thumbs/thumb-7d934f29ab238808295eaac41f94edf6f849c134-240x240.jpg" alt="img-png" class="thumb"></span> + <span class="icon landscape"><img src="/_h5ai/public/cache/thumbs/thumb-7d934f29ab238808295eaac41f94edf6f849c134-320x240.jpg" alt="img-png" class="thumb"></span> + <span class="label" title="20180601_100041_bst_00Y_s.png">20180601_100041_bst_00Y_s.png</span> + <span class="date" data-time="1527880965000">2018-06-01 20:22</span> + <span class="size" data-bytes="98566">99 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_134113_bst_00X.dat"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/file.svg" alt="file"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/file.svg" alt="file"></span> + <span class="label" title="20180601_134113_bst_00X.dat">20180601_134113_bst_00X.dat</span> + <span class="date" data-time="1527880956000">2018-06-01 20:22</span> + <span class="size" data-bytes="6750016">6.8 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_134113_bst_00X.png"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/img.svg" alt="img-png"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/img.svg" alt="img-png"></span> + <span class="label" title="20180601_134113_bst_00X.png">20180601_134113_bst_00X.png</span> + <span class="date" data-time="1623426564000">2021-06-11 16:49</span> + <span class="size" data-bytes="1287058">1.3 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_134113_bst_00X_s.png"> + <span class="icon square"><img src="/_h5ai/public/cache/thumbs/thumb-91804ce6eef92eb74cbf02ae75d33352afc24499-240x240.jpg" alt="img-png" class="thumb"></span> + <span class="icon landscape"><img src="/_h5ai/public/cache/thumbs/thumb-91804ce6eef92eb74cbf02ae75d33352afc24499-320x240.jpg" alt="img-png" class="thumb"></span> + <span class="label" title="20180601_134113_bst_00X_s.png">20180601_134113_bst_00X_s.png</span> + <span class="date" data-time="1527880964000">2018-06-01 20:22</span> + <span class="size" data-bytes="86655">87 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_134113_bst_00Y.dat"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/file.svg" alt="file"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/file.svg" alt="file"></span> + <span class="label" title="20180601_134113_bst_00Y.dat">20180601_134113_bst_00Y.dat</span> + <span class="date" data-time="1527880954000">2018-06-01 20:22</span> + <span class="size" data-bytes="6750016">6.8 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_134113_bst_00Y.png"> + <span class="icon square"><img src="/_h5ai/public/cache/thumbs/thumb-18a6bcdbb0e9cf9681b67bf8d04a4b99f12ec819-240x240.jpg" alt="img-png" class="thumb"></span> + <span class="icon landscape"><img src="/_h5ai/public/cache/thumbs/thumb-18a6bcdbb0e9cf9681b67bf8d04a4b99f12ec819-320x240.jpg" alt="img-png" class="thumb"></span> + <span class="label" title="20180601_134113_bst_00Y.png">20180601_134113_bst_00Y.png</span> + <span class="date" data-time="1623426564000">2021-06-11 16:49</span> + <span class="size" data-bytes="1347087">1.3 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_134113_bst_00Y_s.png"> + <span class="icon square"><img src="/_h5ai/public/cache/thumbs/thumb-4f567bc1ced8946af6f4de7ed3f14b071b4566c3-240x240.jpg" alt="img-png" class="thumb"></span> + <span class="icon landscape"><img src="/_h5ai/public/cache/thumbs/thumb-4f567bc1ced8946af6f4de7ed3f14b071b4566c3-320x240.jpg" alt="img-png" class="thumb"></span> + <span class="label" title="20180601_134113_bst_00Y_s.png">20180601_134113_bst_00Y_s.png</span> + <span class="date" data-time="1527880967000">2018-06-01 20:22</span> + <span class="size" data-bytes="85004">85 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_142212_bst_00X.dat"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/file.svg" alt="file"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/file.svg" alt="file"></span> + <span class="label" title="20180601_142212_bst_00X.dat">20180601_142212_bst_00X.dat</span> + <span class="date" data-time="1527880959000">2018-06-01 20:22</span> + <span class="size" data-bytes="20156352">20.2 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_142212_bst_00X.png"> + <span class="icon square"><img src="/_h5ai/public/cache/thumbs/thumb-cc436df615c747ae12cd62c92437805227729354-240x240.jpg" alt="img-png" class="thumb"></span> + <span class="icon landscape"><img src="/_h5ai/public/cache/thumbs/thumb-cc436df615c747ae12cd62c92437805227729354-320x240.jpg" alt="img-png" class="thumb"></span> + <span class="label" title="20180601_142212_bst_00X.png">20180601_142212_bst_00X.png</span> + <span class="date" data-time="1623426564000">2021-06-11 16:49</span> + <span class="size" data-bytes="1221061">1.2 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_142212_bst_00X_s.png"> + <span class="icon square"><img src="/_h5ai/public/cache/thumbs/thumb-0fb030296c4cf0f3c92f7c9219ca8d0a53a8d022-240x240.jpg" alt="img-png" class="thumb"></span> + <span class="icon landscape"><img src="/_h5ai/public/cache/thumbs/thumb-0fb030296c4cf0f3c92f7c9219ca8d0a53a8d022-320x240.jpg" alt="img-png" class="thumb"></span> + <span class="label" title="20180601_142212_bst_00X_s.png">20180601_142212_bst_00X_s.png</span> + <span class="date" data-time="1527880965000">2018-06-01 20:22</span> + <span class="size" data-bytes="111801">112 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_142212_bst_00Y.dat"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/file.svg" alt="file"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/file.svg" alt="file"></span> + <span class="label" title="20180601_142212_bst_00Y.dat">20180601_142212_bst_00Y.dat</span> + <span class="date" data-time="1527880957000">2018-06-01 20:22</span> + <span class="size" data-bytes="20156352">20.2 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_142212_bst_00Y.png"> + <span class="icon square"><img src="/_h5ai/public/cache/thumbs/thumb-4f861190ef4606bdf30b63621f29ba7803f904ff-240x240.jpg" alt="img-png" class="thumb"></span> + <span class="icon landscape"><img src="/_h5ai/public/cache/thumbs/thumb-4f861190ef4606bdf30b63621f29ba7803f904ff-320x240.jpg" alt="img-png" class="thumb"></span> + <span class="label" title="20180601_142212_bst_00Y.png">20180601_142212_bst_00Y.png</span> + <span class="date" data-time="1623426564000">2021-06-11 16:49</span> + <span class="size" data-bytes="1130386">1.1 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_142212_bst_00Y_s.png"> + <span class="icon square"><img src="/_h5ai/public/cache/thumbs/thumb-c1ae133755a22dc637eb44d1ea4b8df18e26c98c-240x240.jpg" alt="img-png" class="thumb"></span> + <span class="icon landscape"><img src="/_h5ai/public/cache/thumbs/thumb-c1ae133755a22dc637eb44d1ea4b8df18e26c98c-320x240.jpg" alt="img-png" class="thumb"></span> + <span class="label" title="20180601_142212_bst_00Y_s.png">20180601_142212_bst_00Y_s.png</span> + <span class="date" data-time="1527880965000">2018-06-01 20:22</span> + <span class="size" data-bytes="116455">116 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_155738_bst_00X.dat"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/file.svg" alt="file"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/file.svg" alt="file"></span> + <span class="label" title="20180601_155738_bst_00X.dat">20180601_155738_bst_00X.dat</span> + <span class="date" data-time="1527880963000">2018-06-01 20:22</span> + <span class="size" data-bytes="47652224">47.7 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_155738_bst_00X.png"> + <span class="icon square"><img src="/_h5ai/public/cache/thumbs/thumb-9055871efd45b3af449e506d67c7feb1592ca590-240x240.jpg" alt="img-png" class="thumb"></span> + <span class="icon landscape"><img src="/_h5ai/public/cache/thumbs/thumb-9055871efd45b3af449e506d67c7feb1592ca590-320x240.jpg" alt="img-png" class="thumb"></span> + <span class="label" title="20180601_155738_bst_00X.png">20180601_155738_bst_00X.png</span> + <span class="date" data-time="1623426564000">2021-06-11 16:49</span> + <span class="size" data-bytes="900661">901 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_155738_bst_00X_s.png"> + <span class="icon square"><img src="/_h5ai/public/cache/thumbs/thumb-40521a0afbf152de114232f93bcb54c2edb14e36-240x240.jpg" alt="img-png" class="thumb"></span> + <span class="icon landscape"><img src="/_h5ai/public/cache/thumbs/thumb-40521a0afbf152de114232f93bcb54c2edb14e36-320x240.jpg" alt="img-png" class="thumb"></span> + <span class="label" title="20180601_155738_bst_00X_s.png">20180601_155738_bst_00X_s.png</span> + <span class="date" data-time="1527880968000">2018-06-01 20:22</span> + <span class="size" data-bytes="110687">111 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_155738_bst_00Y.dat"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/file.svg" alt="file"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/file.svg" alt="file"></span> + <span class="label" title="20180601_155738_bst_00Y.dat">20180601_155738_bst_00Y.dat</span> + <span class="date" data-time="1527880953000">2018-06-01 20:22</span> + <span class="size" data-bytes="47652224">47.7 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_155738_bst_00Y.png"> + <span class="icon square"><img src="/_h5ai/public/cache/thumbs/thumb-56c18c3c2c0d078fa4aa51ac6f8ea8218b7b35a9-240x240.jpg" alt="img-png" class="thumb"></span> + <span class="icon landscape"><img src="/_h5ai/public/cache/thumbs/thumb-56c18c3c2c0d078fa4aa51ac6f8ea8218b7b35a9-320x240.jpg" alt="img-png" class="thumb"></span> + <span class="label" title="20180601_155738_bst_00Y.png">20180601_155738_bst_00Y.png</span> + <span class="date" data-time="1623426564000">2021-06-11 16:49</span> + <span class="size" data-bytes="875355">875 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/20180601_155738_bst_00Y_s.png"> + <span class="icon square"><img src="/_h5ai/public/cache/thumbs/thumb-fc441b5caa953f33c87acb8d2b490c818a99f7ae-240x240.jpg" alt="img-png" class="thumb"></span> + <span class="icon landscape"><img src="/_h5ai/public/cache/thumbs/thumb-fc441b5caa953f33c87acb8d2b490c818a99f7ae-320x240.jpg" alt="img-png" class="thumb"></span> + <span class="label" title="20180601_155738_bst_00Y_s.png">20180601_155738_bst_00Y_s.png</span> + <span class="date" data-time="1527880966000">2018-06-01 20:22</span> + <span class="size" data-bytes="106564">107 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/AntennaField.conf"> + <span class="icon square"><img src="/_h5ai/public/images/themes/comity/txt-script.svg" alt="txt-script"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/comity/txt-script.svg" alt="txt-script"></span> + <span class="label" title="AntennaField.conf">AntennaField.conf</span> + <span class="date" data-time="1527880949000">2018-06-01 20:22</span> + <span class="size" data-bytes="14002">14 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/beamctl.log"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/txt.svg" alt="txt-log"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/txt.svg" alt="txt-log"></span> + <span class="label" title="beamctl.log">beamctl.log</span> + <span class="date" data-time="1527880953000">2018-06-01 20:22</span> + <span class="size" data-bytes="2957">3 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/CalServer.orig"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/file.svg" alt="file"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/file.svg" alt="file"></span> + <span class="label" title="CalServer.orig">CalServer.orig</span> + <span class="date" data-time="1527880955000">2018-06-01 20:22</span> + <span class="size" data-bytes="1634">2 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/iHBADeltas.conf"> + <span class="icon square"><img src="/_h5ai/public/images/themes/comity/txt-script.svg" alt="txt-script"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/comity/txt-script.svg" alt="txt-script"></span> + <span class="label" title="iHBADeltas.conf">iHBADeltas.conf</span> + <span class="date" data-time="1527880954000">2018-06-01 20:22</span> + <span class="size" data-bytes="519">519 B</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/noaa_events_raw_20180601.txt"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/txt.svg" alt="txt"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/txt.svg" alt="txt"></span> + <span class="label" title="noaa_events_raw_20180601.txt">noaa_events_raw_20180601.txt</span> + <span class="date" data-time="1623426564000">2021-06-11 16:49</span> + <span class="size" data-bytes="843">843 B</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/obs_notes.txt"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/txt.svg" alt="txt"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/txt.svg" alt="txt"></span> + <span class="label" title="obs_notes.txt">obs_notes.txt</span> + <span class="date" data-time="1527880959000">2018-06-01 20:22</span> + <span class="size" data-bytes="28896">29 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/01/bst/kbt/rcu357_1beam/rspctl_beamlet.log"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/txt.svg" alt="txt-log"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/txt.svg" alt="txt-log"></span> + <span class="label" title="rspctl_beamlet.log">rspctl_beamlet.log</span> + <span class="date" data-time="1527880949000">2018-06-01 20:22</span> + <span class="size" data-bytes="928278">928 KB</span> + </a> + </li> +</ul> diff --git a/radiospectra/net/sources/tests/data/ilofar_resp2.html b/radiospectra/net/sources/tests/data/ilofar_resp2.html new file mode 100644 index 0000000..b86b1dc --- /dev/null +++ b/radiospectra/net/sources/tests/data/ilofar_resp2.html @@ -0,0 +1,337 @@ +<ul id="items" class="clearfix"> + <li class="header"> + <a class="icon"></a> + <a class="label ascending" href="#"><span class="l10n-name">Name</span><img + src="/_h5ai/public/images/ui/sort.svg" class="sort" alt="sort order"></a> + <a class="date" href="#"><img src="/_h5ai/public/images/ui/sort.svg" class="sort" + alt="sort order"><span + class="l10n-lastModified">Last modified</span></a> + <a class="size" href="#"><img src="/_h5ai/public/images/ui/sort.svg" class="sort" + alt="sort order"><span class="l10n-size">Size</span></a> + </li> + <li class="item folder folder-parent"> + <a href="/2018/06/02/bst/kbt/"> + <span class="icon square"><img + src="/_h5ai/public/images/themes/default/folder-parent.svg" alt="folder"></span> + <span class="icon landscape"><img + src="/_h5ai/public/images/themes/default/folder-parent.svg" alt="folder"></span> + <span class="label" title="kbt">kbt</span> + <span class="date" data-time="1527967502000">2018-06-02 20:25</span> + <span class="size" data-bytes="null"></span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/20180602_063247_bst_00X.dat"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/file.svg" + alt="file"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/file.svg" + alt="file"></span> + <span class="label" + title="20180602_063247_bst_00X.dat">20180602_063247_bst_00X.dat</span> + <span class="date" data-time="1527967552000">2018-06-02 20:25</span> + <span class="size" data-bytes="80937728">80.9 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/20180602_063247_bst_00X_GOES_SWPC.png"> + <span class="icon square"><img + src="/_h5ai/public/cache/thumbs/thumb-bb50678c7a148ce757107eaf3784b12d01fa90c9-240x240.jpg" + alt="img-png" class="thumb"></span> + <span class="icon landscape"><img + src="/_h5ai/public/cache/thumbs/thumb-bb50678c7a148ce757107eaf3784b12d01fa90c9-320x240.jpg" + alt="img-png" class="thumb"></span> + <span class="label" title="20180602_063247_bst_00X_GOES_SWPC.png">20180602_063247_bst_00X_GOES_SWPC.png</span> + <span class="date" data-time="1623426564000">2021-06-11 16:49</span> + <span class="size" data-bytes="1046399">1.0 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/20180602_063247_bst_00X_s.png"> + <span class="icon square"><img + src="/_h5ai/public/cache/thumbs/thumb-5683ba58c30f697583bd9bda6537bf4fe6ea955a-240x240.jpg" + alt="img-png" class="thumb"></span> + <span class="icon landscape"><img + src="/_h5ai/public/cache/thumbs/thumb-5683ba58c30f697583bd9bda6537bf4fe6ea955a-320x240.jpg" + alt="img-png" class="thumb"></span> + <span class="label" + title="20180602_063247_bst_00X_s.png">20180602_063247_bst_00X_s.png</span> + <span class="date" data-time="1527967554000">2018-06-02 20:25</span> + <span class="size" data-bytes="98903">99 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/20180602_063247_bst_00Y.dat"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/file.svg" + alt="file"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/file.svg" + alt="file"></span> + <span class="label" + title="20180602_063247_bst_00Y.dat">20180602_063247_bst_00Y.dat</span> + <span class="date" data-time="1527967539000">2018-06-02 20:25</span> + <span class="size" data-bytes="80937728">80.9 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/20180602_063247_bst_00Y_GOES_SWPC.png"> + <span class="icon square"><img + src="/_h5ai/public/cache/thumbs/thumb-f214ef26ec5424aeed1c2bc679cb150993006375-240x240.jpg" + alt="img-png" class="thumb"></span> + <span class="icon landscape"><img + src="/_h5ai/public/cache/thumbs/thumb-f214ef26ec5424aeed1c2bc679cb150993006375-320x240.jpg" + alt="img-png" class="thumb"></span> + <span class="label" title="20180602_063247_bst_00Y_GOES_SWPC.png">20180602_063247_bst_00Y_GOES_SWPC.png</span> + <span class="date" data-time="1623426564000">2021-06-11 16:49</span> + <span class="size" data-bytes="977711">978 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/20180602_063247_bst_00Y_s.png"> + <span class="icon square"><img + src="/_h5ai/public/cache/thumbs/thumb-f2690e67297fe6284046b3bd03c89e02f98b8644-240x240.jpg" + alt="img-png" class="thumb"></span> + <span class="icon landscape"><img + src="/_h5ai/public/cache/thumbs/thumb-f2690e67297fe6284046b3bd03c89e02f98b8644-320x240.jpg" + alt="img-png" class="thumb"></span> + <span class="label" + title="20180602_063247_bst_00Y_s.png">20180602_063247_bst_00Y_s.png</span> + <span class="date" data-time="1527967557000">2018-06-02 20:25</span> + <span class="size" data-bytes="100040">100 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/20180602_122439_bst_00X.dat"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/file.svg" + alt="file"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/file.svg" + alt="file"></span> + <span class="label" + title="20180602_122439_bst_00X.dat">20180602_122439_bst_00X.dat</span> + <span class="date" data-time="1527967532000">2018-06-02 20:25</span> + <span class="size" data-bytes="23256128">23.3 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/20180602_122439_bst_00X.png"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/img.svg" + alt="img-png"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/img.svg" + alt="img-png"></span> + <span class="label" + title="20180602_122439_bst_00X.png">20180602_122439_bst_00X.png</span> + <span class="date" data-time="1623426564000">2021-06-11 16:49</span> + <span class="size" data-bytes="1235377">1.2 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/20180602_122439_bst_00X_s.png"> + <span class="icon square"><img + src="/_h5ai/public/cache/thumbs/thumb-0b469719bc07feca48e50230c4e5c17a9bfdda86-240x240.jpg" + alt="img-png" class="thumb"></span> + <span class="icon landscape"><img + src="/_h5ai/public/cache/thumbs/thumb-0b469719bc07feca48e50230c4e5c17a9bfdda86-320x240.jpg" + alt="img-png" class="thumb"></span> + <span class="label" + title="20180602_122439_bst_00X_s.png">20180602_122439_bst_00X_s.png</span> + <span class="date" data-time="1527967559000">2018-06-02 20:25</span> + <span class="size" data-bytes="93643">94 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/20180602_122439_bst_00Y.dat"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/file.svg" + alt="file"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/file.svg" + alt="file"></span> + <span class="label" + title="20180602_122439_bst_00Y.dat">20180602_122439_bst_00Y.dat</span> + <span class="date" data-time="1527967524000">2018-06-02 20:25</span> + <span class="size" data-bytes="23256128">23.3 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/20180602_122439_bst_00Y.png"> + <span class="icon square"><img + src="/_h5ai/public/cache/thumbs/thumb-274e5dd876918cef35bcf4a040f4887dbe99bfb1-240x240.jpg" + alt="img-png" class="thumb"></span> + <span class="icon landscape"><img + src="/_h5ai/public/cache/thumbs/thumb-274e5dd876918cef35bcf4a040f4887dbe99bfb1-320x240.jpg" + alt="img-png" class="thumb"></span> + <span class="label" + title="20180602_122439_bst_00Y.png">20180602_122439_bst_00Y.png</span> + <span class="date" data-time="1623426564000">2021-06-11 16:49</span> + <span class="size" data-bytes="1346869">1.3 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/20180602_122439_bst_00Y_s.png"> + <span class="icon square"><img + src="/_h5ai/public/cache/thumbs/thumb-d5dcefe9396c2c2e32ce71248844d8c9ed6e4400-240x240.jpg" + alt="img-png" class="thumb"></span> + <span class="icon landscape"><img + src="/_h5ai/public/cache/thumbs/thumb-d5dcefe9396c2c2e32ce71248844d8c9ed6e4400-320x240.jpg" + alt="img-png" class="thumb"></span> + <span class="label" + title="20180602_122439_bst_00Y_s.png">20180602_122439_bst_00Y_s.png</span> + <span class="date" data-time="1527967557000">2018-06-02 20:25</span> + <span class="size" data-bytes="85913">86 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/20180602_143603_bst_00X.dat"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/file.svg" + alt="file"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/file.svg" + alt="file"></span> + <span class="label" + title="20180602_143603_bst_00X.dat">20180602_143603_bst_00X.dat</span> + <span class="date" data-time="1527967530000">2018-06-02 20:25</span> + <span class="size" data-bytes="67445504">67.4 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/20180602_143603_bst_00X.png"> + <span class="icon square"><img + src="/_h5ai/public/cache/thumbs/thumb-9436e0416d7ed06191ecb7b14fad47c184cb9db0-240x240.jpg" + alt="img-png" class="thumb"></span> + <span class="icon landscape"><img + src="/_h5ai/public/cache/thumbs/thumb-9436e0416d7ed06191ecb7b14fad47c184cb9db0-320x240.jpg" + alt="img-png" class="thumb"></span> + <span class="label" + title="20180602_143603_bst_00X.png">20180602_143603_bst_00X.png</span> + <span class="date" data-time="1623426564000">2021-06-11 16:49</span> + <span class="size" data-bytes="950781">951 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/20180602_143603_bst_00X_s.png"> + <span class="icon square"><img + src="/_h5ai/public/cache/thumbs/thumb-e8f0b3d78e06be218299786868a14ed816b69e68-240x240.jpg" + alt="img-png" class="thumb"></span> + <span class="icon landscape"><img + src="/_h5ai/public/cache/thumbs/thumb-e8f0b3d78e06be218299786868a14ed816b69e68-320x240.jpg" + alt="img-png" class="thumb"></span> + <span class="label" + title="20180602_143603_bst_00X_s.png">20180602_143603_bst_00X_s.png</span> + <span class="date" data-time="1527967555000">2018-06-02 20:25</span> + <span class="size" data-bytes="104724">105 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/20180602_143603_bst_00Y.dat"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/file.svg" + alt="file"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/file.svg" + alt="file"></span> + <span class="label" + title="20180602_143603_bst_00Y.dat">20180602_143603_bst_00Y.dat</span> + <span class="date" data-time="1527967545000">2018-06-02 20:25</span> + <span class="size" data-bytes="67445504">67.4 MB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/20180602_143603_bst_00Y.png"> + <span class="icon square"><img + src="/_h5ai/public/cache/thumbs/thumb-70d870f5dda0900ba8fb99130018bb2058d0c386-240x240.jpg" + alt="img-png" class="thumb"></span> + <span class="icon landscape"><img + src="/_h5ai/public/cache/thumbs/thumb-70d870f5dda0900ba8fb99130018bb2058d0c386-320x240.jpg" + alt="img-png" class="thumb"></span> + <span class="label" + title="20180602_143603_bst_00Y.png">20180602_143603_bst_00Y.png</span> + <span class="date" data-time="1623426564000">2021-06-11 16:49</span> + <span class="size" data-bytes="869960">870 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/20180602_143603_bst_00Y_s.png"> + <span class="icon square"><img + src="/_h5ai/public/cache/thumbs/thumb-0046bef135e588648d9492b986a90390620ca18e-240x240.jpg" + alt="img-png" class="thumb"></span> + <span class="icon landscape"><img + src="/_h5ai/public/cache/thumbs/thumb-0046bef135e588648d9492b986a90390620ca18e-320x240.jpg" + alt="img-png" class="thumb"></span> + <span class="label" + title="20180602_143603_bst_00Y_s.png">20180602_143603_bst_00Y_s.png</span> + <span class="date" data-time="1527967559000">2018-06-02 20:25</span> + <span class="size" data-bytes="95507">96 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/AntennaField.conf"> + <span class="icon square"><img src="/_h5ai/public/images/themes/comity/txt-script.svg" + alt="txt-script"></span> + <span class="icon landscape"><img + src="/_h5ai/public/images/themes/comity/txt-script.svg" alt="txt-script"></span> + <span class="label" title="AntennaField.conf">AntennaField.conf</span> + <span class="date" data-time="1527967522000">2018-06-02 20:25</span> + <span class="size" data-bytes="14002">14 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/beamctl.log"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/txt.svg" + alt="txt-log"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/txt.svg" + alt="txt-log"></span> + <span class="label" title="beamctl.log">beamctl.log</span> + <span class="date" data-time="1527967524000">2018-06-02 20:25</span> + <span class="size" data-bytes="2957">3 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/CalServer.orig"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/file.svg" + alt="file"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/file.svg" + alt="file"></span> + <span class="label" title="CalServer.orig">CalServer.orig</span> + <span class="date" data-time="1527967530000">2018-06-02 20:25</span> + <span class="size" data-bytes="1634">2 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/iHBADeltas.conf"> + <span class="icon square"><img src="/_h5ai/public/images/themes/comity/txt-script.svg" + alt="txt-script"></span> + <span class="icon landscape"><img + src="/_h5ai/public/images/themes/comity/txt-script.svg" alt="txt-script"></span> + <span class="label" title="iHBADeltas.conf">iHBADeltas.conf</span> + <span class="date" data-time="1527967524000">2018-06-02 20:25</span> + <span class="size" data-bytes="519">519 B</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/noaa_events_raw_20180602.txt"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/txt.svg" + alt="txt"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/txt.svg" + alt="txt"></span> + <span class="label" + title="noaa_events_raw_20180602.txt">noaa_events_raw_20180602.txt</span> + <span class="date" data-time="1623426564000">2021-06-11 16:49</span> + <span class="size" data-bytes="677">677 B</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/obs_notes.txt"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/txt.svg" + alt="txt"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/txt.svg" + alt="txt"></span> + <span class="label" title="obs_notes.txt">obs_notes.txt</span> + <span class="date" data-time="1527967552000">2018-06-02 20:25</span> + <span class="size" data-bytes="21672">22 KB</span> + </a> + </li> + <li class="item file"> + <a href="/2018/06/02/bst/kbt/rcu357_1beam/rspctl_beamlet.log"> + <span class="icon square"><img src="/_h5ai/public/images/themes/default/txt.svg" + alt="txt-log"></span> + <span class="icon landscape"><img src="/_h5ai/public/images/themes/default/txt.svg" + alt="txt-log"></span> + <span class="label" title="rspctl_beamlet.log">rspctl_beamlet.log</span> + <span class="date" data-time="1527967522000">2018-06-02 20:25</span> + <span class="size" data-bytes="1313598">1.3 MB</span> + </a> + </li> +</ul> diff --git a/radiospectra/net/sources/tests/test_ilofar.py b/radiospectra/net/sources/tests/test_ilofar.py new file mode 100644 index 0000000..79feced --- /dev/null +++ b/radiospectra/net/sources/tests/test_ilofar.py @@ -0,0 +1,110 @@ +from pathlib import Path +from unittest import mock + +import pytest + +import astropy.units as u +from sunpy.net import Fido +from sunpy.net import attrs as a + +from radiospectra.net.attrs import PolType +from radiospectra.net.sources.ilofar import ILOFARMode357Client + + +@pytest.fixture +def client(): + return ILOFARMode357Client() + + +@pytest.fixture +def html_responses(): + paths = [Path(__file__).parent / "data" / n for n in ["ilofar_resp1.html", "ilofar_resp2.html"]] + response_htmls = [] + for p in paths: + with p.open("r") as f: + response_htmls.append(f.read()) + + return response_htmls + + +@mock.patch("sunpy.net.scraper.urlopen") +def test_ilofar_client(mock_urlopen, client, html_responses): + mock_urlopen.return_value.read = mock.MagicMock() + mock_urlopen.return_value.read.side_effect = html_responses * 2 + mock_urlopen.close = mock.MagicMock(return_value=None) + atr = a.Time("2018/06/01", "2018/06/02") + query = client.search(atr) + + called_urls = [ + "https://data.lofar.ie/2018/06/01/bst/kbt/rcu357_1beam/", + "https://data.lofar.ie/2018/06/02/bst/kbt/rcu357_1beam/", + "https://data.lofar.ie/2018/06/01/bst/kbt/rcu357_1beam_datastream/", + "https://data.lofar.ie/2018/06/02/bst/kbt/rcu357_1beam_datastream/", + ] + assert called_urls == [call[0][0] for call in mock_urlopen.call_args_list] + assert len(query) == 8 + assert query[0]["Source"] == "ILOFAR" + assert query[0]["Provider"] == "ILOFAR" + assert query[0]["Start Time"].iso == "2018-06-01 10:00:41.000" + assert query[0]["Polarisation"] == "X" + + +@mock.patch("sunpy.net.scraper.urlopen") +def test_ilofar_client_polarisation(mock_urlopen, client, html_responses): + mock_urlopen.return_value.read = mock.MagicMock() + mock_urlopen.return_value.read.side_effect = html_responses * 2 + mock_urlopen.close = mock.MagicMock(return_value=None) + atr = a.Time("2018/06/01", "2018/06/02") + query_x = client.search(atr, PolType("X")) + query_y = client.search(atr, PolType("Y")) + + for query, pol in zip([query_x, query_y], ["X", "Y"]): + assert len(query) == 4 + assert query[0]["Source"] == "ILOFAR" + assert query[0]["Provider"] == "ILOFAR" + assert query[0]["Start Time"].iso == "2018-06-01 10:00:41.000" + assert query[0]["Polarisation"] == pol + + +@mock.patch("sunpy.net.scraper.urlopen") +def test_ilofar_client_polarisation(mock_urlopen, client, html_responses): + mock_urlopen.return_value.read = mock.MagicMock() + mock_urlopen.return_value.read.side_effect = html_responses * 6 + mock_urlopen.close = mock.MagicMock(return_value=None) + atr = a.Time("2018/06/01", "2018/06/02") + query_both_low = client.search(atr, a.Wavelength(1 * u.MHz, 5 * u.MHz)) + query_both_high = client.search(atr, a.Wavelength(1 * u.GHz, 2 * u.GHz)) + + assert len(query_both_low) == 0 + assert len(query_both_high) == 0 + + query_low_in = client.search(atr, a.Wavelength(90 * u.MHz, 1 * u.GHz)) + query_both_in = client.search(atr, a.Wavelength(15 * u.MHz, 230 * u.MHz)) + query_high_in = client.search(atr, a.Wavelength(5 * u.MHz, 90 * u.MHz)) + + for query in [query_low_in, query_both_in, query_high_in]: + assert len(query) == 8 + + +@pytest.mark.remote_data +def test_fido(): + atr = a.Time("2018/06/01", "2018/06/02") + query = Fido.search(atr, a.Instrument("ILOFAR")) + + assert isinstance(query[0].client, ILOFARMode357Client) + query = query[0] + assert len(query) == 8 + assert query[0]["Source"] == "ILOFAR" + assert query[0]["Provider"] == "ILOFAR" + assert query[0]["Start Time"].iso == "2018-06-01 10:00:41.000" + assert query[0]["Polarisation"] == "X" + + +@pytest.mark.remote_data +def test_fido_other_dataset(): + atr = a.Time("2021/08/01", "2021/10/01") + query = Fido.search(atr, a.Instrument("ILOFAR")) + + assert isinstance(query[0].client, ILOFARMode357Client) + query = query[0] + assert len(query) == 38 diff --git a/radiospectra/spectrogram/sources/__init__.py b/radiospectra/spectrogram/sources/__init__.py index 09316f4..60336ee 100644 --- a/radiospectra/spectrogram/sources/__init__.py +++ b/radiospectra/spectrogram/sources/__init__.py @@ -8,6 +8,7 @@ from ..spectrogram_factory import Spectrogram # NOQA from .callisto import * # NOQA from .eovsa import * # NOQA +from .ilofar357 import * # NOQA from .psp_rfs import * # NOQA from .rpw import * # NOQA from .rstn import * # NOQA @@ -21,4 +22,5 @@ "EOVSASpectrogram", "RSTNSpectrogram", "RPWSpectrogram", + "ILOFARMode357Spectrogram", ] diff --git a/radiospectra/spectrogram/sources/ilofar357.py b/radiospectra/spectrogram/sources/ilofar357.py new file mode 100644 index 0000000..1dd2273 --- /dev/null +++ b/radiospectra/spectrogram/sources/ilofar357.py @@ -0,0 +1,23 @@ +from radiospectra.spectrogram.spectrogrambase import GenericSpectrogram + +__all__ = [ + "ILOFARMode357Spectrogram", +] + + +class ILOFARMode357Spectrogram(GenericSpectrogram): + """ + Irish LOFAR Station mode 357 Spectrogram + """ + + @property + def mode(self): + return self.meta.get("mode") + + @property + def polarisation(self): + return self.meta.get("polarisation") + + @classmethod + def is_datasource_for(cls, data, meta, **kwargs): + return meta["instrument"] == "ILOFAR" diff --git a/radiospectra/spectrogram/sources/tests/test_ilofar357.py b/radiospectra/spectrogram/sources/tests/test_ilofar357.py new file mode 100644 index 0000000..86655eb --- /dev/null +++ b/radiospectra/spectrogram/sources/tests/test_ilofar357.py @@ -0,0 +1,28 @@ +from pathlib import Path +from unittest import mock + +import numpy as np + +from radiospectra.spectrogram import Spectrogram + + +@mock.patch("numpy.fromfile") +@mock.patch("sunpy.util.io.is_file") +def test_ilofar(mock_is_file, mock_fromfile): + mock_fromfile.return_value = np.ones(10117216) + mock_is_file.return_value = True + + spec = Spectrogram(Path("20180602_063247_bst_00X.dat")) + assert len(spec) == 3 + assert spec[0].polarisation == "X" + assert spec[0].start_time.iso == "2018-06-02 06:32:47.000" + assert spec[0].end_time.iso == "2018-06-02 12:18:18.000" + assert spec[0].mode == 3 + assert spec[0].frequencies[0].to_value("MHz") == 10.546875 + assert spec[0].frequencies[-1].to_value("MHz") == 88.28125 + assert spec[1].mode == 5 + assert spec[1].frequencies[0].to_value("MHz") == 110.546875 + assert spec[1].frequencies[-1].to_value("MHz") == 188.28125 + assert spec[2].mode == 7 + assert spec[2].frequencies[0].to_value("MHz") == 210.546875 + assert spec[2].frequencies[-1].to_value("MHz") == 244.53125 diff --git a/radiospectra/spectrogram/spectrogram_factory.py b/radiospectra/spectrogram/spectrogram_factory.py index f431d91..5988288 100644 --- a/radiospectra/spectrogram/spectrogram_factory.py +++ b/radiospectra/spectrogram/spectrogram_factory.py @@ -16,6 +16,7 @@ from astropy.io import fits from astropy.io.fits import Header from astropy.time import Time +from sunpy import log from sunpy.data import cache from sunpy.net import attrs as a from sunpy.time import parse_time @@ -32,6 +33,7 @@ from radiospectra.exceptions import NoSpectrogramInFileError, SpectraMetaValidationError from radiospectra.spectrogram.spectrogrambase import GenericSpectrogram +from radiospectra.utils import subband_to_freq SUPPORTED_ARRAY_TYPES = (np.ndarray,) try: @@ -236,7 +238,7 @@ def _read_file(self, file, **kwargs): extensions = file.suffixes first_extension = extensions[0].lower() if first_extension == ".dat": - return [self._read_dat(file)] + return self._read_dat(file) elif first_extension in (".r1", ".r2"): return [self._read_idl_sav(file, instrument="waves")] elif first_extension == ".cdf": @@ -276,6 +278,49 @@ def _read_dat(file): meta["times"] = meta["start_time"] + times meta["end_time"] = meta["start_time"] + times[-1] return data, meta + elif "bst" in file.name: + subbands = (np.arange(54, 454, 2), np.arange(54, 454, 2), np.arange(54, 230, 2)) + num_subbands = 488 + + data = np.fromfile(file) + polarisation = file.stem[-1] + + num_times = data.shape[0] / num_subbands + if not num_times.is_integer(): + log.warning("BST file seems incomplete dropping incomplete frequencies") + num_times = np.floor(num_times).astype(int) + truncate = num_times * num_subbands + data = data[:truncate] + data = data.reshape(-1, num_subbands).T # (Freq x Time).T = (Time x Freq) + dt = np.arange(num_times) * 1 * u.s + start_time = Time.strptime(file.name.split("_bst")[0], "%Y%m%d_%H%M%S") + times = start_time + dt + + obs_mode = (3, 5, 7) + + freqs = [subband_to_freq(sb, mode) for sb, mode in zip(subbands, obs_mode)] + + # 1st 200 sbs mode 3, next 200 sbs mode 5, last 88 sbs mode 7 + spec = {0: data[:200, :], 1: data[200:400, :], 2: data[400:, :]} + data_header_pairs = [] + for i in range(3): + meta = { + "instrument": "ILOFAR", + "observatory": "Birr (IE613)", + "start_time": times[0], + "mode": obs_mode[i], + "wavelength": a.Wavelength(freqs[i][0], freqs[i][-1]), + "freqs": freqs[i], + "times": times, + "end_time": times[-1], + "detector": "ILOFAR", + "polarisation": polarisation, + } + + data_header_pairs.append((spec[i], meta)) + return data_header_pairs + else: + raise ValueError(f"File {file} not supported.") @staticmethod def _read_srs(file): diff --git a/radiospectra/utils.py b/radiospectra/utils.py new file mode 100644 index 0000000..6f356ac --- /dev/null +++ b/radiospectra/utils.py @@ -0,0 +1,29 @@ +import astropy.units as u + +__all__ = ["subband_to_freq"] + + +def subband_to_freq(subband, obs_mode): + """ + Converts LOFAR single station subbands to frequency + + Parameters + ---------- + subband : `int` + Subband number. + obs_mode : `int` + Observation mode 3, 5, 7. + + Return + ------ + `astropy.units.Quantity` + Frequency in MHz + """ + nyq_zone_dict = {3: 1, 5: 2, 7: 3} + if obs_mode not in nyq_zone_dict: + raise ValueError(f"Observation mode {obs_mode} not supported, only 3, 5, 7 are supported.") + nyq_zone = nyq_zone_dict[obs_mode] + clock_dict = {3: 200, 4: 160, 5: 200, 6: 160, 7: 200} # MHz + clock = clock_dict[obs_mode] + freq = (nyq_zone - 1 + subband / 512) * (clock / 2) + return freq * u.MHz # MHz