MolSSI / QCFractal

A distributed compute and database platform for quantum chemistry.
https://molssi.github.io/QCFractal/
BSD 3-Clause "New" or "Revised" License
148 stars 48 forks source link

Exception raised in dataset status() #586

Closed bennybp closed 4 years ago

bennybp commented 4 years ago

Describe the bug When calling status() on datasets, an exception is raised. This occurs when following the documentation examples (https://qcarchive.molssi.org/examples)

To Reproduce

Follow the documentation

import qcportal as ptl
client = ptl.FractalClient()
ds = client.get_collection("OptimizationDataset", "SMIRNOFF Coverage Set 1")
ds.status(["default"])

The exception is

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~/miniconda3/envs/qca14/lib/python3.7/site-packages/pandas/core/arrays/categorical.py in __init__(self, values, categories, ordered, dtype, fastpath)
    354             try:
--> 355                 codes, categories = factorize(values, sort=True)
    356             except TypeError:

~/miniconda3/envs/qca14/lib/python3.7/site-packages/pandas/core/algorithms.py in factorize(values, sort, na_sentinel, size_hint)
    635         codes, uniques = _factorize_array(
--> 636             values, na_sentinel=na_sentinel, size_hint=size_hint, na_value=na_value
    637         )

~/miniconda3/envs/qca14/lib/python3.7/site-packages/pandas/core/algorithms.py in _factorize_array(values, na_sentinel, size_hint, na_value)
    483     table = hash_klass(size_hint or len(values))
--> 484     uniques, codes = table.factorize(values, na_sentinel=na_sentinel, na_value=na_value)
    485

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.factorize()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable._unique()

TypeError: unhashable type: 'OptimizationRecord'

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
<ipython-input-1-240f10e80330> in <module>
      2 client = ptl.FractalClient()
      3 ds = client.get_collection("OptimizationDataset", "SMIRNOFF Coverage Set 1")
----> 4 ds.status(["default"])

~/miniconda3/envs/qca14/lib/python3.7/site-packages/qcportal/collections/collection.py in status(self, specs, collapse, status, detail)
    594
    595             # apply status by column then by row
--> 596             df = self.df[list_specs].apply(lambda col: col.apply(get_status))
    597
    598             if status:

~/miniconda3/envs/qca14/lib/python3.7/site-packages/pandas/core/frame.py in __getitem__(self, key)
   2804             if is_iterator(key):
   2805                 key = list(key)
-> 2806             indexer = self.loc._get_listlike_indexer(key, axis=1, raise_missing=True)[1]
   2807
   2808         # take() does not accept boolean indexers

~/miniconda3/envs/qca14/lib/python3.7/site-packages/pandas/core/indexing.py in _get_listlike_indexer(self, key, axis, raise_missing)
   1545             if len(ax) or not len(key):
   1546                 key = self._convert_for_reindex(key, axis)
-> 1547             indexer = ax.get_indexer_for(key)
   1548             keyarr = ax.reindex(keyarr)[0]
   1549         else:

~/miniconda3/envs/qca14/lib/python3.7/site-packages/pandas/core/indexes/base.py in get_indexer_for(self, target, **kwargs)
   4499         """
   4500         if self.is_unique:
-> 4501             return self.get_indexer(target, **kwargs)
   4502         indexer, _ = self.get_indexer_non_unique(target, **kwargs)
   4503         return indexer

~/miniconda3/envs/qca14/lib/python3.7/site-packages/pandas/core/indexes/base.py in get_indexer(self, target, method, limit, tolerance)
   2707     def get_indexer(self, target, method=None, limit=None, tolerance=None):
   2708         method = missing.clean_reindex_fill_method(method)
-> 2709         target = ensure_index(target)
   2710         if tolerance is not None:
   2711             tolerance = self._convert_tolerance(tolerance, target)

~/miniconda3/envs/qca14/lib/python3.7/site-packages/pandas/core/indexes/base.py in ensure_index(index_like, copy)
   5344             from pandas.core.indexes.multi import MultiIndex
   5345
-> 5346             return MultiIndex.from_arrays(converted)
   5347         else:
   5348             index_like = converted

~/miniconda3/envs/qca14/lib/python3.7/site-packages/pandas/core/indexes/multi.py in from_arrays(cls, arrays, sortorder, names)
    425                 raise ValueError("all arrays must be same length")
    426
--> 427         codes, levels = factorize_from_iterables(arrays)
    428         if names is lib.no_default:
    429             names = [getattr(arr, "name", None) for arr in arrays]

~/miniconda3/envs/qca14/lib/python3.7/site-packages/pandas/core/arrays/categorical.py in factorize_from_iterables(iterables)
   2706         # For consistency, it should return a list of 2 lists.
   2707         return [[], []]
-> 2708     return map(list, zip(*(factorize_from_iterable(it) for it in iterables)))

~/miniconda3/envs/qca14/lib/python3.7/site-packages/pandas/core/arrays/categorical.py in <genexpr>(.0)
   2706         # For consistency, it should return a list of 2 lists.
   2707         return [[], []]
-> 2708     return map(list, zip(*(factorize_from_iterable(it) for it in iterables)))

~/miniconda3/envs/qca14/lib/python3.7/site-packages/pandas/core/arrays/categorical.py in factorize_from_iterable(values)
   2678         # but only the resulting categories, the order of which is independent
   2679         # from ordered. Set ordered to False as default. See GH #15457
-> 2680         cat = Categorical(values, ordered=False)
   2681         categories = cat.categories
   2682         codes = cat.codes

~/miniconda3/envs/qca14/lib/python3.7/site-packages/pandas/core/arrays/categorical.py in __init__(self, values, categories, ordered, dtype, fastpath)
    355                 codes, categories = factorize(values, sort=True)
    356             except TypeError:
--> 357                 codes, categories = factorize(values, sort=False)
    358                 if dtype.ordered:
    359                     # raise, as we don't have a sortable data structure and so

~/miniconda3/envs/qca14/lib/python3.7/site-packages/pandas/core/algorithms.py in factorize(values, sort, na_sentinel, size_hint)
    634
    635         codes, uniques = _factorize_array(
--> 636             values, na_sentinel=na_sentinel, size_hint=size_hint, na_value=na_value
    637         )
    638

~/miniconda3/envs/qca14/lib/python3.7/site-packages/pandas/core/algorithms.py in _factorize_array(values, na_sentinel, size_hint, na_value)
    482
    483     table = hash_klass(size_hint or len(values))
--> 484     uniques, codes = table.factorize(values, na_sentinel=na_sentinel, na_value=na_value)
    485
    486     codes = ensure_platform_int(codes)

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.factorize()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable._unique()

TypeError: unhashable type: 'OptimizationRecord'

Expected behavior

According to the documentation, an overview of the status of the computations

Additional context

Installed via conda

qcelemental               0.14.0                     py_0    conda-forge
qcengine                  0.14.0                     py_0    conda-forge
qcfractal                 0.13.1                   py37_0    conda-forge
qcfractal-core            0.13.1                   py37_0    conda-forge
doaa-altarawy commented 4 years ago

Also, ds.status(detail=True) returns error if no INCOMPLETE jobs exist.

doaa-altarawy commented 4 years ago

Those work without error:

ds.status()
ds.status(collapse=False)
ds.status(status='complete')
doaa-altarawy commented 4 years ago

Finally, this sequence works:

import qcportal as ptl
client = ptl.FractalClient()
ds = client.get_collection("OptimizationDataset", "SMIRNOFF Coverage Set 1")

ds.status()
ds.status(["default"])

That is, calling ds.status() before calling it with specs will work.

bennybp commented 4 years ago

Fixed in PR #588