Retrieving EXAFS Spectra for Materials with Fe as the Absorbing Element Results in an Error

Hello!

I am trying to use my API to retrieve EXAFS spectra for materials with Fe as the absorbing element, but the following code:

from mp_api.client import MPRester
from emmet.core.xas import Edge, XASDoc, Type

with MPRester(My_API) as mpr:
    fe_xas = mpr.materials.xas.search(edge=Edge.K,
                                      spectrum_type=Type.EXAFS,
                                      absorbing_element="Fe",
                                      fields=["material_id","xas_id","spectrum","formula_pretty","edge","spectrum_type"])

results in the following error:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[3], line 2
      1 with MPRester(My_API) as mpr:
----> 2     fe_xas = mpr.materials.xas.search(edge=Edge.K,
      3                                       spectrum_type=Type.EXAFS,
      4                                       absorbing_element="Fe",
      5                                       fields=["material_id","xas_id","spectrum","formula_pretty","edge","spectrum_type"])

File d:\ANACONDA\envs\XANES\Lib\site-packages\mp_api\client\routes\materials\xas.py:101, in XASRester.search(self, edge, absorbing_element, formula, chemsys, elements, material_ids, spectrum_type, spectrum_ids, num_chunks, chunk_size, all_fields, fields)
     93     query_params.update({"spectrum_ids": ",".join(spectrum_ids)})
     95 query_params = {
     96     entry: query_params[entry]
     97     for entry in query_params
     98     if query_params[entry] is not None
     99 }
--> 101 return super()._search(
    102     num_chunks=num_chunks,
    103     chunk_size=chunk_size,
    104     all_fields=all_fields,
    105     fields=fields,
    106     **query_params,
    107 )

File d:\ANACONDA\envs\XANES\Lib\site-packages\mp_api\client\core\client.py:1185, in BaseRester._search(self, num_chunks, chunk_size, all_fields, fields, **kwargs)
   1163 """A generic search method to retrieve documents matching specific parameters.
   1164 
   1165 Arguments:
   (...)
   1180     A list of documents.
   1181 """
   1182 # This method should be customized for each end point to give more user friendly,
   1183 # documented kwargs.
-> 1185 return self._get_all_documents(
   1186     kwargs,
   1187     all_fields=all_fields,
   1188     fields=fields,
   1189     chunk_size=chunk_size,
   1190     num_chunks=num_chunks,
   1191 )

File d:\ANACONDA\envs\XANES\Lib\site-packages\mp_api\client\core\client.py:1258, in BaseRester._get_all_documents(self, query_params, all_fields, fields, chunk_size, num_chunks)
   1244 list_entries = sorted(
   1245     (
   1246         (key, len(entry.split(",")))
   (...)
   1253     reverse=True,
   1254 )
   1256 chosen_param = list_entries[0][0] if len(list_entries) > 0 else None
-> 1258 results = self._query_resource(
   1259     query_params,
   1260     fields=fields,
   1261     parallel_param=chosen_param,
   1262     chunk_size=chunk_size,
   1263     num_chunks=num_chunks,
   1264 )
   1266 return results["data"]

File d:\ANACONDA\envs\XANES\Lib\site-packages\mp_api\client\core\client.py:569, in BaseRester._query_resource(self, criteria, fields, suburl, use_document_model, parallel_param, num_chunks, chunk_size, timeout)
    567         data["meta"]["total_doc"] = len(data["data"])
    568     else:
--> 569         data = self._submit_requests(
    570             url=url,
    571             criteria=criteria,
    572             use_document_model=not query_s3 and use_document_model,
    573             parallel_param=parallel_param,
    574             num_chunks=num_chunks,
    575             chunk_size=chunk_size,
    576             timeout=timeout,
    577         )
    578     return data
    580 except RequestException as ex:

File d:\ANACONDA\envs\XANES\Lib\site-packages\mp_api\client\core\client.py:874, in BaseRester._submit_requests(self, url, criteria, use_document_model, chunk_size, parallel_param, num_chunks, timeout)
    871         remaining -= crit["_limit"]
    873 # Submit requests and process data
--> 874 data_tuples = self._multi_thread(
    875     self._submit_request_and_process, params_list, pbar
    876 )
    878 for data, _, _ in data_tuples:
    879     total_data["data"].extend(data["data"])

File d:\ANACONDA\envs\XANES\Lib\site-packages\mp_api\client\core\client.py:938, in BaseRester._multi_thread(self, func, params_list, progress_bar)
    935 finished, futures = wait(futures, return_when=FIRST_COMPLETED)
    937 for future in finished:
--> 938     data, subtotal = future.result()
    940     if progress_bar is not None:
    941         if isinstance(data, dict):

File d:\ANACONDA\envs\XANES\Lib\concurrent\futures\_base.py:449, in Future.result(self, timeout)
    447     raise CancelledError()
    448 elif self._state == FINISHED:
--> 449     return self.__get_result()
    451 self._condition.wait(timeout)
    453 if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]:

File d:\ANACONDA\envs\XANES\Lib\concurrent\futures\_base.py:401, in Future.__get_result(self)
    399 if self._exception:
    400     try:
--> 401         raise self._exception
    402     finally:
    403         # Break a reference cycle with the exception in self._exception
    404         self = None

File d:\ANACONDA\envs\XANES\Lib\concurrent\futures\thread.py:58, in _WorkItem.run(self)
     55     return
     57 try:
---> 58     result = self.fn(*self.args, **self.kwargs)
     59 except BaseException as exc:
     60     self.future.set_exception(exc)

File d:\ANACONDA\envs\XANES\Lib\site-packages\mp_api\client\core\client.py:1003, in BaseRester._submit_request_and_process(self, url, verify, params, use_document_model, timeout)
   1001 if response.status_code == 200:
   1002     if self.monty_decode:
-> 1003         data = json.loads(response.text, cls=MontyDecoder)
   1004     else:
   1005         data = json.loads(response.text)

File d:\ANACONDA\envs\XANES\Lib\json\__init__.py:359, in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    357 if parse_constant is not None:
    358     kw['parse_constant'] = parse_constant
--> 359 return cls(**kw).decode(s)

File d:\ANACONDA\envs\XANES\Lib\site-packages\monty\json.py:875, in MontyDecoder.decode(self, s)
    873 else:
    874     d = json.loads(s)
--> 875 return self.process_decoded(d)

File d:\ANACONDA\envs\XANES\Lib\site-packages\monty\json.py:853, in MontyDecoder.process_decoded(self, d)
    845         elif (
    846             (bson is not None)
    847             and modname == "bson.objectid"
    848             and classname == "ObjectId"
    849         ):
    850             return bson.objectid.ObjectId(d["oid"])
    852     return {
--> 853         self.process_decoded(k): self.process_decoded(v) for k, v in d.items()
    854     }
    856 if isinstance(d, list):
    857     return [self.process_decoded(x) for x in d]

File d:\ANACONDA\envs\XANES\Lib\site-packages\monty\json.py:857, in MontyDecoder.process_decoded(self, d)
    852     return {
    853         self.process_decoded(k): self.process_decoded(v) for k, v in d.items()
    854     }
    856 if isinstance(d, list):
--> 857     return [self.process_decoded(x) for x in d]
    859 return d

File d:\ANACONDA\envs\XANES\Lib\site-packages\monty\json.py:853, in MontyDecoder.process_decoded(self, d)
    845         elif (
    846             (bson is not None)
    847             and modname == "bson.objectid"
    848             and classname == "ObjectId"
    849         ):
    850             return bson.objectid.ObjectId(d["oid"])
    852     return {
--> 853         self.process_decoded(k): self.process_decoded(v) for k, v in d.items()
    854     }
    856 if isinstance(d, list):
    857     return [self.process_decoded(x) for x in d]

File d:\ANACONDA\envs\XANES\Lib\site-packages\monty\json.py:790, in MontyDecoder.process_decoded(self, d)
    788 data = {k: v for k, v in d.items() if not k.startswith("@")}
    789 if hasattr(cls_, "from_dict"):
--> 790     return cls_.from_dict(data)
    791 if issubclass(cls_, Enum):
    792     return cls_(d["value"])

File d:\ANACONDA\envs\XANES\Lib\site-packages\monty\json.py:249, in MSONable.from_dict(cls, d)
    236 """
    237 
    238 Args:
   (...)
    242     MSONable class.
    243 """
    244 decoded = {
    245     k: MontyDecoder().process_decoded(v)
    246     for k, v in d.items()
    247     if not k.startswith("@")
    248 }
--> 249 return cls(**decoded)

File d:\ANACONDA\envs\XANES\Lib\site-packages\pymatgen\analysis\xas\spectrum.py:77, in XAS.__init__(self, x, y, structure, absorbing_element, edge, spectrum_type, absorbing_index)
     75 # check for empty spectra and negative intensities
     76 if sum(1 for i in self.y if i <= 0) / len(self.y) > 0.05:
---> 77     raise ValueError("Double check the intensities. Most of them are non-positive.")

ValueError: Double check the intensities. Most of them are non-positive.

However, I don’t encounter any errors when retrieving EXAFS data for other elements, such as Co.

We’ve got a data release in the works and a pymatgen release pending that should take care of this. In the meantime, try the solution in this thread. Also consider searching the forum for solutions before posting a new question. Thanks!