Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build_and_upload_wheels.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-22.04
strategy:
matrix:
python-version: [3.7, 3.8, 3.9, '3.10', 3.11]
python-version: ['3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v3

Expand Down
18 changes: 5 additions & 13 deletions .github/workflows/coverage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-22.04]
python-version: [3.9, "3.10", "3.11", "3.12", "3.13"]
python-version: ["3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@v4
Expand All @@ -24,20 +24,12 @@ jobs:
with:
python-version: ${{ matrix.python-version }}

- name: Install Python Dependencies for 3.12 and later
if: ${{ matrix.python-version >= '3.12' }}
- name: Install Python3 Dependencies
run: |
python -m pip install --upgrade pip pytest setuptools wheel
pip install -r requirements.txt
# Optional Dependency for HDF Checkpointing
pip install tables
python setup.py install
python setup.py build_ext --inplace
python -m pip list

- name: Standard Install Python3 Dependencies
run: |
python -m pip install --upgrade pip pytest
# Install hatchet first: pandas 3 support is on its develop branch, and
# requirements.txt cannot be resolved against released hatchet versions
python -m pip install git+https://github.com/LLNL/hatchet.git@develop
pip install -r requirements.txt
# Optional Dependency for HDF Checkpointing
pip install tables
Expand Down
103 changes: 0 additions & 103 deletions .github/workflows/test-for-pandas-3.yml

This file was deleted.

31 changes: 10 additions & 21 deletions .github/workflows/unit-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
matrix:
# TODO: add macos-latest
os: [ubuntu-latest]
python-version: [3.9, "3.10", "3.11", "3.12", "3.13"]
python-version: ["3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@v2
Expand All @@ -30,35 +30,26 @@ jobs:
# Obtain the latest cached version of npm (either local cache or action cache)
node-version: node

- name: Install Python3 dependencies for 3.12 and later
if: ${{ matrix.python-version >= '3.12' }}
- name: Install Python3 Dependencies
run: |
python -m pip install --upgrade pip pytest setuptools wheel
# Install hatchet first: pandas 3 support is on its develop branch, and
# requirements.txt cannot be resolved against released hatchet versions
python -m pip install git+https://github.com/LLNL/hatchet.git@develop
pip install -r requirements.txt
python -m pip install --upgrade --force-reinstall git+https://github.com/LLNL/hatchet.git@develop
python setup.py install
python setup.py build_ext --inplace
python -m pip list

- name: Standard Install Python3 Dependencies
run: |
python -m pip install --upgrade pip pytest
pip install -r requirements.txt
python -m pip install --upgrade --force-reinstall git+https://github.com/LLNL/hatchet.git@develop
python setup.py install
python setup.py build_ext --inplace
python -m pip list

- name: Update Black
if: ${{ matrix.python-version == 3.9 }}
if: ${{ matrix.python-version == '3.11' }}
run: |
pip install flake8-pytest-importorskip
pip install --upgrade click==8.0.4
pip install black==21.12b0
pip install flake8==4.0.1
pip install flake8==7.3.0

- name: Lint and Format Check with Flake8 and Black
if: ${{ matrix.python-version == 3.9 }}
if: ${{ matrix.python-version == '3.11' }}
run: |
black --diff --check .
flake8
Expand All @@ -67,10 +58,8 @@ jobs:
run: |
python license.py verify

- name: Install ExtraP
if: ${{ matrix.python-version >= 3.7 }}
run: |
pip install extrap
# Extra-P is not installed: all Extra-P releases require NumPy < 2, which
# pandas 3 does not support, so thicket/tests/test_model_extrap.py is skipped.

- name: Basic Test with pytest
run: |
Expand Down
4 changes: 2 additions & 2 deletions docs/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
Thicket has the following minimum requirements, which must be installed before Thicket
is run:

#. Python 3 (3.6 - 3.11)
#. Python 3 (3.11 or newer)
#. hatchet
#. pandas >= 1.1
#. pandas >= 3.0
#. numpy
#. matplotlib, and
#. scipy
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
scipy
numpy
pandas>=1.1,<3
llnl-hatchet
pandas>=3
llnl-hatchet>=2026.2.0
matplotlib
seaborn
beautifulsoup4
Expand Down
9 changes: 6 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def readme():
"Source Code": "https://github.com/LLNL/thicket",
"Documentation": "https://thicket.readthedocs.io/",
},
python_requires=">=3.6.1",
python_requires=">=3.11",
packages=[
"thicket",
"thicket.stats",
Expand All @@ -44,8 +44,11 @@ def readme():
install_requires=[
"scipy",
"numpy",
"pandas >= 1.1,<3",
"llnl-hatchet",
"pandas >= 3",
# pandas 3 support is on hatchet develop (LLNL/hatchet#185). The 2026.2.0
# release itself requires pandas<3, so this floor admits hatchet develop and
# later releases while excluding older releases that lack a pandas pin.
"llnl-hatchet >= 2026.2.0",
"tqdm",
"more-itertools",
],
Expand Down
52 changes: 32 additions & 20 deletions thicket/ensemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,9 @@ def _handle_metadata():
# Update index to reflect performance data table index
if metadata_key != inner_idx:
for i in range(len(thickets_cp)):
thickets_cp[i].metadata.reset_index(drop=True, inplace=True)
thickets_cp[i].metadata = thickets_cp[i].metadata.reset_index(
drop=True
)
if metadata_key is None:
for i in range(len(thickets_cp)):
thickets_cp[i].metadata.index.set_names(
Expand All @@ -163,8 +165,10 @@ def _handle_metadata():
else:
for i in range(len(thickets_cp)):
if metadata_key != inner_idx:
thickets_cp[i].metadata.set_index(metadata_key, inplace=True)
thickets_cp[i].metadata.sort_index(inplace=True)
thickets_cp[i].metadata = thickets_cp[i].metadata.set_index(
metadata_key
)
thickets_cp[i].metadata = thickets_cp[i].metadata.sort_index()

# Create multi-index columns
for i in range(len(thickets_cp)):
Expand Down Expand Up @@ -215,7 +219,9 @@ def _handle_perfdata():
thickets_cp[i].metadata_columns_to_perfdata(
"new_profiles", drop=True
)
thickets_cp[i].dataframe.reset_index(level=inner_idx, inplace=True)
thickets_cp[i].dataframe = thickets_cp[i].dataframe.reset_index(
level=inner_idx
)
new_mappings.update(
pd.Series(
thickets_cp[i]
Expand All @@ -225,9 +231,11 @@ def _handle_perfdata():
index=thickets_cp[i].dataframe[inner_idx],
).to_dict()
)
thickets_cp[i].dataframe.drop(inner_idx, axis=1, inplace=True)
thickets_cp[i].dataframe.set_index(
"new_profiles", append=True, inplace=True
thickets_cp[i].dataframe = thickets_cp[i].dataframe.drop(
inner_idx, axis=1
)
thickets_cp[i].dataframe = thickets_cp[i].dataframe.set_index(
"new_profiles", append=True
)
thickets_cp[i].dataframe.index.rename(
thickets_cp[i].profile_idx_name,
Expand All @@ -238,7 +246,9 @@ def _handle_perfdata():
for i in range(len(thickets_cp)):
if metadata_key not in thickets_cp[i].dataframe.index.names:
thickets_cp[i].metadata_columns_to_perfdata(metadata_key)
thickets_cp[i].dataframe.reset_index(level=inner_idx, inplace=True)
thickets_cp[i].dataframe = thickets_cp[i].dataframe.reset_index(
level=inner_idx
)
new_mappings.update(
pd.Series(
thickets_cp[i]
Expand All @@ -249,11 +259,13 @@ def _handle_perfdata():
).to_dict()
)
if inner_idx != metadata_key:
thickets_cp[i].dataframe.drop(inner_idx, axis=1, inplace=True)
thickets_cp[i].dataframe.set_index(
metadata_key, append=True, inplace=True
thickets_cp[i].dataframe = thickets_cp[i].dataframe.drop(
inner_idx, axis=1
)
thickets_cp[i].dataframe = thickets_cp[i].dataframe.set_index(
metadata_key, append=True
)
thickets_cp[i].dataframe.sort_index(inplace=True)
thickets_cp[i].dataframe = thickets_cp[i].dataframe.sort_index()

# Create tuple columns
new_columns = [
Expand Down Expand Up @@ -283,16 +295,16 @@ def _handle_perfdata():
)

# Extract "name" columns to upper level
nodes = list(set(combined_th.dataframe.reset_index()["node"]))
for node in nodes:
combined_th.dataframe.loc[node, "name"] = node.frame["name"]
combined_th.dataframe.drop(
combined_th.dataframe[("name", "")] = [
node.frame["name"]
for node in combined_th.dataframe.index.get_level_values("node")
]
combined_th.dataframe = combined_th.dataframe.drop(
columns=[(headers[i], "name") for i in range(len(headers))],
inplace=True,
)

# Sort DataFrame
combined_th.dataframe.sort_index(inplace=True)
combined_th.dataframe = combined_th.dataframe.sort_index()

return new_mappings

Expand Down Expand Up @@ -397,9 +409,9 @@ def _index(
unify_df = _fill_perfdata(unify_df)

# Sort PerfData
unify_df.sort_index(inplace=True)
unify_df = unify_df.sort_index()
# Sort Metadata
unify_metadata.sort_index(inplace=True)
unify_metadata = unify_metadata.sort_index()

# Remove duplicates in metrics
unify_inc_metrics = list(set(unify_inc_metrics))
Expand Down
4 changes: 2 additions & 2 deletions thicket/external/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ def render(self, roots, dataframe, **kwargs):
metric_series = (dataframe.xs(self.rank, level=1))[self.primary_metric]
else:
metric_series = dataframe[self.primary_metric]
isfinite_mask = np.isfinite(metric_series.values)
isfinite_mask = np.isfinite(metric_series.to_numpy())
filtered_series = pd.Series(
metric_series.values[isfinite_mask], metric_series.index[isfinite_mask]
metric_series.to_numpy()[isfinite_mask], metric_series.index[isfinite_mask]
)

self.max_metric = self.max_value if self.max_value else filtered_series.max()
Expand Down
Loading
Loading