Skip to content

Commit

Permalink
Fixes #169, and adds functions to drop cache entries matching regex
Browse files Browse the repository at this point in the history
In some cases for 2D DATA CDFs, the 2nd axis has a DEPEND0 while it
also is Non Record Vary. Speasy has to consider that those axes are not
time dependent.

Signed-off-by: Alexis Jeandet <[email protected]>
  • Loading branch information
jeandet committed Jan 16, 2025
1 parent 77dde09 commit 3688185
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 2 deletions.
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ classifiers = [
]
dependencies = ['requests', 'pandas', 'diskcache', 'appdirs', 'numpy', 'packaging', 'python-dateutil',
'astropy', 'astroquery', 'pyistp>=0.7.0', 'tqdm', 'matplotlib', 'urllib3>=1.26.0', "PyYAML", "scipy"]

[project.urls]
homepage = "https://github.com/SciQLop/speasy"

Expand Down
61 changes: 61 additions & 0 deletions speasy/core/cache/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
from typing import Union
import re
from .cache import Cache, CacheItem
from ._function_cache import CacheCall
from ._providers_caches import CACHE_ALLOWED_KWARGS, Cacheable, UnversionedProviderCache
from ._instance import _cache
import logging

log = logging.getLogger(__name__)


def cache_len():
"""Return the number of items in the cache"""
return len(_cache)


def cache_disk_size():
"""Return the size of the cache on disk"""
return _cache.disk_size()


Expand All @@ -17,16 +24,70 @@ def stats():


def entries():
"""Return all cache entries as a list of keys
Returns
-------
list
A list of all cache keys
"""
return _cache.keys()


def add_item(key, item, expires=None):
"""Add an item to the cache with an optional expiration time in seconds
Parameters
----------
key : str
The key under which the item will be stored
item : any
The item to be stored
expires : int, optional
The expiration time in seconds, by default None (no expiration)
"""
_cache.set(key, item, expires)


def drop_item(key):
"""Drop an item from the cache by key
Parameters
----------
key : str
The key of the item to be dropped
"""
_cache.drop(key)


def get_item(key, default_value=None):
"""Get an item from the cache by key
Parameters
----------
key : str
The key of the item to be retrieved
default_value : any, optional
The default value to return if the key does not exist, by default None
Returns
-------
any
The item stored under the key or the default value if the key does not exist
"""
return _cache.get(key, default_value)


def drop_matching_entries(pattern: Union[str, re.Pattern]):
"""Drop all cache entries that match a given pattern
Parameters
----------
pattern : str or re.Pattern
The pattern to match cache keys against
"""
if isinstance(pattern, str):
pattern = re.compile(pattern)
for key in filter(pattern.match, _cache.keys()):
log.debug(f"Dropping cache entry {key}")
_cache.drop(key)
4 changes: 2 additions & 2 deletions speasy/core/codecs/bundled_codecs/istp_cdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ def _fix_attributes_types(attributes: dict):

def _is_time_dependent(axis, time_axis_name):
if axis.attributes.get('DEPEND_TIME', '') == time_axis_name:
return True
return not axis.is_nrv
if axis.attributes.get('DEPEND_0', '') == time_axis_name:
return True
return not axis.is_nrv
return False


Expand Down
6 changes: 6 additions & 0 deletions tests/test_cdaweb.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,12 @@ def test_get_virtual_parameter_always_falls_back_to_api(self):
"2021-11-3", "2021-11-3T01", disable_proxy=True, disable_cache=True, method="FILE")
self.assertIsNotNone(mms1_fgm_b_bcs_srvy_l2_clean)

def test_wrong_time_dependency_axis(self):
result = spz.get_data(
"cda/MMS1_FEEPS_SRVY_L2_ELECTRON/mms1_epd_feeps_srvy_l2_electron_bottom_intensity_sensorid_2",
datetime(2018, 5, 26, 1, 0, 0), datetime(2018, 5, 26, 1, 10, 1))
self.assertIsNotNone(result)


@ddt
class DirectArchiveConverter(unittest.TestCase):
Expand Down
29 changes: 29 additions & 0 deletions tests/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from ddt import ddt, data, unpack

import speasy as spz
from speasy.core.cache import entries


@ddt
Expand Down Expand Up @@ -85,5 +86,33 @@ def test_epoch_to_dt64(self, input, expected):
np.allclose(spz.core.epoch_to_datetime64(input).astype('int64'), expected.astype('int64'), atol=1e-10))


class TestDroppingKeysFromCache(unittest.TestCase):

def test_dropping_specific_key(self):
spz.core.cache.add_item("key1", "value1")
spz.core.cache.add_item("key2", "value2")
spz.core.cache.add_item("key3", "value3")

spz.core.cache.drop_item("key2")

self.assertEqual(spz.core.cache.get_item("key1"), "value1")
self.assertIsNone(spz.core.cache.get_item("key2"))
self.assertEqual(spz.core.cache.get_item("key3"), "value3")
spz.core.cache.drop_matching_entries("key\\d")

def test_dropping_matching_keys(self):
spz.core.cache.add_item("key1", "value1")
spz.core.cache.add_item("key2", "value2")
spz.core.cache.drop_matching_entries("key\\d")
self.assertIsNone(spz.core.cache.get_item("key1"))
self.assertIsNone(spz.core.cache.get_item("key2"))

def test_dropping_speasy_variables(self):
spz.get_data(spz.inventories.tree.ssc.Trajectories.ace, "2008-01-01", "2008-01-02")
self.assertGreater(len(list(filter(lambda e: e.startswith("ssc_orbits/ace/gse"), spz.core.cache.entries()))), 0)
spz.core.cache.drop_matching_entries("^ssc_orbits/ace/gse")
self.assertEqual(len(list(filter(lambda e: e.startswith("ssc_orbits/ace/gse"), spz.core.cache.entries()))), 0)


if __name__ == '__main__':
unittest.main()

0 comments on commit 3688185

Please sign in to comment.