Skip to content
Merged
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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,10 @@ src/modernmolbert/eval/junk/
.prompt.md
.agents/
/*.prompt.md
repomix*.xml
/*plan*.md
*repomix*.xml
CLAUDE.md
.claude/

# eval
tmp_eval/
Expand Down
17 changes: 4 additions & 13 deletions src/modernmolbert/eval/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,7 @@ def _public_featurizer_params(featurizer: RepresentationFeaturizer) -> dict[str,
if is_dataclass(featurizer):
params = asdict(featurizer)
else:
params = {
key: value
for key, value in vars(featurizer).items()
if not key.startswith("_")
}
params = {key: value for key, value in vars(featurizer).items() if not key.startswith("_")}

# Exclude heavy/runtime objects if present.
for key in [
Expand All @@ -96,9 +92,7 @@ def featurizer_cache_identity(

return {
"name": featurizer.name,
"class": (
f"{featurizer.__class__.__module__}.{featurizer.__class__.__qualname__}"
),
"class": (f"{featurizer.__class__.__module__}.{featurizer.__class__.__qualname__}"),
"params": _public_featurizer_params(featurizer),
}

Expand Down Expand Up @@ -227,8 +221,7 @@ def _validate_cache_metadata(
observed = metadata.get(key)
if observed != expected:
raise ValueError(
f"Cache metadata mismatch for {key!r}: "
f"expected {expected!r}, observed {observed!r}"
f"Cache metadata mismatch for {key!r}: expected {expected!r}, observed {observed!r}"
)


Expand All @@ -251,9 +244,7 @@ def get_or_compute_features(
"""

if smiles_column not in frame.columns:
raise ValueError(
f"Split {split_name!r} is missing SMILES column {smiles_column!r}"
)
raise ValueError(f"Split {split_name!r} is missing SMILES column {smiles_column!r}")

smiles_values = frame[smiles_column].tolist()
molecule_hash = hash_molecule_values(smiles_values)
Expand Down
8 changes: 2 additions & 6 deletions src/modernmolbert/eval/cli/prepare_moleculenet.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description=(
"Prepare DeepChem/MoleculeNet datasets as local sanitized "
"SMILES/SELFIES Parquet files."
"Prepare DeepChem/MoleculeNet datasets as local sanitized SMILES/SELFIES Parquet files."
)
)

Expand All @@ -18,10 +17,7 @@ def parse_args() -> argparse.Namespace:
nargs="+",
default=list(CORE_SPECS),
choices=sorted(ALL_SPECS),
help=(
"Dataset names to prepare. Defaults to the core suite: "
+ ", ".join(CORE_SPECS)
),
help=("Dataset names to prepare. Defaults to the core suite: " + ", ".join(CORE_SPECS)),
)
parser.add_argument(
"--output_root",
Expand Down
26 changes: 7 additions & 19 deletions src/modernmolbert/eval/moleculenet.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,7 @@ def prepare_many(
for dataset_name in dataset_names:
if dataset_name not in ALL_SPECS:
valid = ", ".join(sorted(ALL_SPECS))
raise ValueError(
f"Unknown dataset {dataset_name!r}. Valid choices: {valid}"
)
raise ValueError(f"Unknown dataset {dataset_name!r}. Valid choices: {valid}")

prepare_dataset(
spec=ALL_SPECS[dataset_name],
Expand Down Expand Up @@ -294,12 +292,9 @@ def prepare_dataset(
"valid": frac_valid,
"test": frac_test,
},
"scaffold_stats": compute_scaffold_stats(split_frame)
if split == "scaffold"
else None,
"scaffold_stats": compute_scaffold_stats(split_frame) if split == "scaffold" else None,
"split_scaffold_stats": {
split_name: compute_scaffold_stats(split_df)
for split_name, split_df in splits.items()
split_name: compute_scaffold_stats(split_df) for split_name, split_df in splits.items()
}
if split == "scaffold"
else None,
Expand Down Expand Up @@ -374,9 +369,7 @@ def deepchem_dataset_to_frame(dataset: Any, tasks: Sequence[str]) -> pd.DataFram
if y.shape[1] == 1 and len(tasks) == 0:
tasks = ["label"]
else:
raise ValueError(
f"Task count mismatch: len(tasks)={len(tasks)}, y.shape={y.shape}"
)
raise ValueError(f"Task count mismatch: len(tasks)={len(tasks)}, y.shape={y.shape}")

rows: list[dict[str, Any]] = []

Expand Down Expand Up @@ -580,9 +573,7 @@ def split_sanitized_frame(
frac_valid=frac_valid,
)

raise ValueError(
f"Unsupported local split {split!r}. Use 'scaffold', 'random', or 'index'."
)
raise ValueError(f"Unsupported local split {split!r}. Use 'scaffold', 'random', or 'index'.")


def random_split_frame(
Expand Down Expand Up @@ -811,9 +802,7 @@ def compute_duplicate_stats(frame: pd.DataFrame) -> dict[str, Any]:
n_duplicate_rows = int(n_valid - n_unique)

duplicated_values = valid[valid.duplicated(keep=False)]
duplicate_group_sizes = (
duplicated_values.value_counts().sort_values(ascending=False).tolist()
)
duplicate_group_sizes = duplicated_values.value_counts().sort_values(ascending=False).tolist()

return {
"n_valid_rows": n_valid,
Expand All @@ -836,8 +825,7 @@ def grouped_random_split_frame(
rng = np.random.default_rng(seed)

groups = [
indices.to_list()
for _, indices in frame.groupby(group_column, sort=False).groups.items()
indices.to_list() for _, indices in frame.groupby(group_column, sort=False).groups.items()
]

rng.shuffle(groups)
Expand Down
12 changes: 3 additions & 9 deletions src/modernmolbert/paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ def find_project_root(
if env_root:
root = Path(env_root).expanduser().resolve()
if not root.exists():
raise FileNotFoundError(
f"MODERNMOLBERT_ROOT points to a missing path: {root}"
)
raise FileNotFoundError(f"MODERNMOLBERT_ROOT points to a missing path: {root}")
return root

if start is None:
Expand All @@ -44,9 +42,7 @@ def find_project_root(
)


def project_path(
*parts: str | os.PathLike[str], start: str | Path | None = None
) -> Path:
def project_path(*parts: str | os.PathLike[str], start: str | Path | None = None) -> Path:
"""Return an absolute path inside the project root."""

return find_project_root(start=start).joinpath(*parts)
Expand All @@ -58,9 +54,7 @@ def data_path(*parts: str | os.PathLike[str], start: str | Path | None = None) -
return project_path("data", *parts, start=start)


def outputs_path(
*parts: str | os.PathLike[str], start: str | Path | None = None
) -> Path:
def outputs_path(*parts: str | os.PathLike[str], start: str | Path | None = None) -> Path:
"""Return an absolute path inside the project outputs directory."""

return project_path("outputs", *parts, start=start)
Expand Down
Loading
Loading