SciQLop / speasy

Space Physics made EASY! A simple Python package to deal with main Space Physics WebServices (CDA,SSC,AMDA,..)
Other
24 stars 7 forks source link

AttributeError: module 'pycdfpp' has no attribute 'CDF_CHAR #98

Closed Beforerr closed 8 months ago

Beforerr commented 9 months ago

Description

Trying to download STEREO B Field data from cda raised errors. AttributeError: module 'pycdfpp' has no attribute 'CDF_CHAR'

What I Did

sat_fgm_product = 'cda/STA_L1_MAG_RTN/BFIELD'
products = [sat_fgm_product]
dataset = spz.get_data(products, test_trange, disable_proxy=True)

{
    "name": "AttributeError",
    "message": "module 'pycdfpp' has no attribute 'CDF_CHAR'",
    "stack": "---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/Users/zijin/projects/planet/nbs/03_stereo.ipynb Cell 15 line <cell line: 4>()
      <a href='vscode-notebook-cell:/Users/zijin/projects/planet/nbs/03_stereo.ipynb#X15sZmlsZQ%3D%3D?line=1'>2</a> sat_fgm_product = 'cda/STA_L1_MAG_RTN/BFIELD'
      <a href='vscode-notebook-cell:/Users/zijin/projects/planet/nbs/03_stereo.ipynb#X15sZmlsZQ%3D%3D?line=2'>3</a> products = [sat_fgm_product]
----> <a href='vscode-notebook-cell:/Users/zijin/projects/planet/nbs/03_stereo.ipynb#X15sZmlsZQ%3D%3D?line=3'>4</a> dataset = spz.get_data(products, test_trange, disable_proxy=True)

File ~/mambaforge/envs/cool_planet/lib/python3.10/site-packages/speasy/core/requests_scheduling/request_dispatch.py:309, in get_data(*args, **kwargs)
    307 product = args[0]
    308 if is_collection(product) and not isinstance(product, SpeasyIndex):
--> 309     return list(map(lambda p: get_data(p, *args[1:], **kwargs), progress_bar(leave=True, **kwargs)(product)))
    311 if len(args) == 1:
    312     return _get_catalog_or_timetable(*args, **kwargs)

File ~/mambaforge/envs/cool_planet/lib/python3.10/site-packages/speasy/core/requests_scheduling/request_dispatch.py:309, in get_data.<locals>.<lambda>(p)
    307 product = args[0]
    308 if is_collection(product) and not isinstance(product, SpeasyIndex):
--> 309     return list(map(lambda p: get_data(p, *args[1:], **kwargs), progress_bar(leave=True, **kwargs)(product)))
    311 if len(args) == 1:
    312     return _get_catalog_or_timetable(*args, **kwargs)

File ~/mambaforge/envs/cool_planet/lib/python3.10/site-packages/speasy/core/requests_scheduling/request_dispatch.py:316, in get_data(*args, **kwargs)
    314 t_range = args[1]
    315 if _is_dtrange(t_range):
--> 316     return _get_timeserie1(*args, **kwargs)
    317 if is_collection(t_range):
    318     return list(
    319         map(lambda r: get_data(product, r, *args[2:], **kwargs),
    320             progress_bar(leave=False, **kwargs)(t_range)))

File ~/mambaforge/envs/cool_planet/lib/python3.10/site-packages/speasy/core/requests_scheduling/request_dispatch.py:159, in _get_timeserie1(index, dtrange, **kwargs)
    158 def _get_timeserie1(index, dtrange, **kwargs):
--> 159     return _scalar_get_data(index, dtrange[0], dtrange[1], **kwargs)

File ~/mambaforge/envs/cool_planet/lib/python3.10/site-packages/speasy/core/requests_scheduling/request_dispatch.py:150, in _scalar_get_data(index, *args, **kwargs)
    148 provider_uid, product_uid = provider_and_product(index)
    149 if provider_uid in PROVIDERS:
--> 150     return PROVIDERS[provider_uid].get_data(product_uid, *args, **kwargs)
    151 raise ValueError(f\"Can't find a provider for {index}\")

File ~/mambaforge/envs/cool_planet/lib/python3.10/site-packages/speasy/core/__init__.py:221, in AllowedKwargs.__call__.<locals>.wrapped(*args, **kwargs)
    218 unexpected_args = list(
    219     filter(lambda arg_name: arg_name not in self.allowed_list, kwargs.keys()))
    220 if not unexpected_args:
--> 221     return func(*args, **kwargs)
    222 raise TypeError(
    223     f\"Unexpected keyword argument {unexpected_args}, allowed keyword arguments are {self.allowed_list}\")

File ~/mambaforge/envs/cool_planet/lib/python3.10/site-packages/speasy/core/dataprovider.py:30, in ParameterRangeCheck.__call__.<locals>.wrapped(wrapped_self, product, start_time, stop_time, **kwargs)
     28     log.warning(f\"You are requesting {product} outside of its definition range {p_range}\")
     29     return None
---> 30 return get_data(wrapped_self, product=product, start_time=start_time, stop_time=stop_time, **kwargs)

File ~/mambaforge/envs/cool_planet/lib/python3.10/site-packages/speasy/core/cache/_providers_caches.py:247, in UnversionedProviderCache.__call__.<locals>.wrapped(wrapped_self, product, start_time, stop_time, **kwargs)
    243 fragment_duration = timedelta(hours=fragment_hours)
    244 data_chunks, maybe_outdated_fragments, missing_fragments = self.split_fragments(fragments, product,
    245                                                                                 fragment_duration, **kwargs)
    246 data_chunks += \\
--> 247     list(filter(lambda d: d is not None, [
    248         self._cache.add_to_cache(
    249             get_data(
    250                 wrapped_self, product=product, start_time=fragment_group[0],
    251                 stop_time=fragment_group[-1] + fragment_duration, **kwargs),
    252             fragments=fragment_group, product=product, fragment_duration_hours=fragment_hours,
    253             version=datetime.utcnow(), **kwargs)
    254         for fragment_group
    255         in progress_bar(leave=False, desc=\"Downloading missing fragments from cache\", **kwargs)(
    256             missing_fragments)]))
    258 for group in progress_bar(leave=False, desc=\"Checking if cache fragments are outdated\", **kwargs)(
    259     maybe_outdated_fragments):
    260     oldest = max(group, key=lambda item: item[1].version)[1].version

File ~/mambaforge/envs/cool_planet/lib/python3.10/site-packages/speasy/core/cache/_providers_caches.py:249, in <listcomp>(.0)
    243 fragment_duration = timedelta(hours=fragment_hours)
    244 data_chunks, maybe_outdated_fragments, missing_fragments = self.split_fragments(fragments, product,
    245                                                                                 fragment_duration, **kwargs)
    246 data_chunks += \\
    247     list(filter(lambda d: d is not None, [
    248         self._cache.add_to_cache(
--> 249             get_data(
    250                 wrapped_self, product=product, start_time=fragment_group[0],
    251                 stop_time=fragment_group[-1] + fragment_duration, **kwargs),
    252             fragments=fragment_group, product=product, fragment_duration_hours=fragment_hours,
    253             version=datetime.utcnow(), **kwargs)
    254         for fragment_group
    255         in progress_bar(leave=False, desc=\"Downloading missing fragments from cache\", **kwargs)(
    256             missing_fragments)]))
    258 for group in progress_bar(leave=False, desc=\"Checking if cache fragments are outdated\", **kwargs)(
    259     maybe_outdated_fragments):
    260     oldest = max(group, key=lambda item: item[1].version)[1].version

File ~/mambaforge/envs/cool_planet/lib/python3.10/site-packages/speasy/core/requests_scheduling/split_large_requests.py:21, in SplitLargeRequests.__call__.<locals>.wrapped(wrapped_self, product, start_time, stop_time, **kwargs)
     19 max_range_per_request = self.threshold(product)
     20 if duration <= max_range_per_request:
---> 21     return get_data(wrapped_self, product=product, start_time=start_time, stop_time=stop_time, **kwargs)
     22 else:
     23     fragments = range.split(max_range_per_request)

File ~/mambaforge/envs/cool_planet/lib/python3.10/site-packages/speasy/core/proxy/__init__.py:130, in Proxyfiable.__call__.<locals>.wrapped(*args, **kwargs)
    128     except:  # lgtm [py/catch-base-exception]
    129         log.error(f\"Can't get data from proxy server {proxy_cfg.url()}\")
--> 130 return func(*args, **kwargs)

File ~/mambaforge/envs/cool_planet/lib/python3.10/site-packages/speasy/webservices/cda/__init__.py:178, in CDA_Webservice.get_data(self, product, start_time, stop_time, if_newer_than, extra_http_headers)
    169 @AllowedKwargs(
    170     PROXY_ALLOWED_KWARGS + CACHE_ALLOWED_KWARGS + GET_DATA_ALLOWED_KWARGS + ['if_newer_than'])
    171 @ParameterRangeCheck()
   (...)
    175 def get_data(self, product, start_time: datetime, stop_time: datetime, if_newer_than: datetime or None = None,
    176              extra_http_headers: Dict or None = None):
    177     dataset, variable = self._to_dataset_and_variable(product)
--> 178     return self._dl_variable(start_time=start_time, stop_time=stop_time, dataset=dataset,
    179                              variable=variable, if_newer_than=if_newer_than, extra_http_headers=extra_http_headers)

File ~/mambaforge/envs/cool_planet/lib/python3.10/site-packages/speasy/webservices/cda/__init__.py:160, in CDA_Webservice._dl_variable(self, dataset, variable, start_time, stop_time, if_newer_than, extra_http_headers)
    158 log.debug(resp.url)
    159 if resp.status_code == 200 and 'FileDescription' in resp.json():
--> 160     return _read_cdf(resp.json()['FileDescription'][0]['Name'], variable)
    161 elif not resp.ok:
    162     if resp.status_code == 404 and \"No data available\" in resp.json().get('Message', [\"\"])[0]:

File ~/mambaforge/envs/cool_planet/lib/python3.10/site-packages/speasy/webservices/cda/__init__.py:59, in _read_cdf(url, variable)
     57 def _read_cdf(url: str, variable: str) -> SpeasyVariable:
     58     with urlopen_with_retry(url) as remote_cdf:
---> 59         return load_variable(buffer=remote_cdf.read(), variable=variable)

File ~/mambaforge/envs/cool_planet/lib/python3.10/site-packages/speasy/core/cdf/__init__.py:41, in load_variable(variable, file, buffer)
     40 def load_variable(variable=\"\", file=None, buffer=None) -> SpeasyVariable or None:
---> 41     istp = pyistp.load(file=file, buffer=buffer)
     42     if istp:
     43         if variable in istp.data_variables():

File ~/.local/lib/python3.10/site-packages/pyistp/__init__.py:11, in load(file, buffer)
     10 def load(file=None, buffer=None) -> _ISTPLoader:
---> 11     return _ISTPLoader(file=file, buffer=buffer)

File ~/.local/lib/python3.10/site-packages/pyistp/loader.py:9, in ISTPLoader.__init__(self, file, buffer)
      7 def __init__(self, file=None, buffer=None):
      8     from ._impl import ISTPLoaderImpl
----> 9     self._impl = ISTPLoaderImpl(file=file, buffer=buffer)

File ~/.local/lib/python3.10/site-packages/pyistp/_impl.py:92, in ISTPLoaderImpl.__init__(self, file, buffer)
     90 self.cdf = current_driver(file or buffer)
     91 self.data_variables = []
---> 92 self._update_data_vars_lis()

File ~/.local/lib/python3.10/site-packages/pyistp/_impl.py:108, in ISTPLoaderImpl._update_data_vars_lis(self)
    105 var_type = self.cdf.variable_attribute_value(var, 'VAR_TYPE')
    106 param_type = (self.cdf.variable_attribute_value(var,
    107                                                 'PARAMETER_TYPE') or \"\").lower()  # another cluster CSA crap
--> 108 if (var_type == 'data' or param_type == 'data') and not self.cdf.is_char(var):
    109     self.data_variables.append(var)

File ~/.local/lib/python3.10/site-packages/pyistp/drivers/pycdfpp.py:27, in Driver.is_char(self, var)
     26 def is_char(self, var):
---> 27     return self.cdf[var].type == pycdfpp.CDF_CHAR

AttributeError: module 'pycdfpp' has no attribute 'CDF_CHAR'"
}```
jeandet commented 9 months ago

@Beforerr, weird, can you tell me which version of pycdfpp you have installed? It looks like you have the latest which is not compatible yet with Speasy. This should have prevented it.

Beforerr commented 9 months ago

Hi @jeandet , thanks for prompt reply. I am using CDFpp v0.5.0. Downgrading pycdfpp helped solve this problem.

jeandet commented 8 months ago

The latest speasy version is now compatible with the latest pycdfpp version.