Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
014d537
ci: add Ruff lint and format checks
rlaplaza May 18, 2026
bea4585
feat: API scores, VR tuning, and multi-platform CI
rlaplaza May 18, 2026
a3135f0
fix: remove incomplete project table from pyproject.toml
rlaplaza May 18, 2026
dfb0f02
fix(ci): use preinstalled Miniconda on Windows executor
rlaplaza May 18, 2026
c771d1d
Merge branch 'jv_branch' into master
rlaplaza May 18, 2026
11e1d9f
Merge upstream/jv_branch: sync CircleCI Windows fixes (#78)
rlaplaza May 18, 2026
308ca53
fix(ci): put Windows image Miniconda on PATH before tests
rlaplaza May 18, 2026
51b1922
fix(ci): install Miniconda on Windows when image has none
rlaplaza May 18, 2026
b6c2c03
fix(report): tolerate missing PFI plot pairs in AQME workflows
rlaplaza May 19, 2026
59c8176
fix(ci): prevent AQME tests from blocking before REPORT PDF
rlaplaza May 19, 2026
781bac2
test: filter known external and sklearn warnings in pytest
rlaplaza May 19, 2026
1da67eb
fix(tests): re-baseline GENERATE/VERIFY/AQME integration goldens
rlaplaza May 19, 2026
1d843e6
fix(ci): harden AQME fallback and deterministic best-model selection
rlaplaza May 20, 2026
9545187
Fix EasyROB Linux imports and stabilize GUI subprocess tests.
rlaplaza May 20, 2026
1a17bd2
Fix pyproject.toml syntax so ruff can parse per-file-ignores.
rlaplaza May 20, 2026
069232c
fix(aqme): ensure Linux qdescp uses conda python and remove placehold…
rlaplaza May 20, 2026
0c13b27
test: add platform golden helpers and rebaseline GENERATE/VERIFY on L…
rlaplaza May 20, 2026
40b8bf3
Document v2.2.0 dependency stack and extend PDF reproducibility.
rlaplaza May 20, 2026
27b5e77
fix(ci): stabilize AQME QDESCP subprocess and integration tests
rlaplaza May 20, 2026
ce854cc
fix(ci): install libgomp so xtb loads on CircleCI Linux
rlaplaza May 20, 2026
c004d91
fix(ci): read aqme version via importlib.metadata on Windows
rlaplaza May 20, 2026
4369fc3
fix(ci): silence conda progress bars to avoid 50 MB log cap
rlaplaza May 21, 2026
34c1057
fix(ci): drop invalid console_progress_bar conda config key
rlaplaza May 21, 2026
53f28b9
fix(ci): harden Windows xTB/AQME setup and diagnostics
rlaplaza May 21, 2026
5322373
fix(ci): avoid heredoc in CircleCI YAML preflight block
rlaplaza May 21, 2026
6fed5ca
fix(tests): rebaseline Windows integration goldens
rlaplaza May 21, 2026
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
179 changes: 159 additions & 20 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,73 @@ orbs:

commands:
install-miniconda:
description: Install Miniconda on machine executors (macOS only; Windows images ship with Miniconda)
description: Ensure conda is on PATH (install if missing on Windows/macOS)
steps:
- run:
name: Install Miniconda
command: |
set -euo pipefail

conda_present_at() {
local root="$1"
[ -n "${root}" ] && { [ -f "${root}/Scripts/conda.exe" ] || [ -f "${root}/bin/conda" ]; }
}

if command -v conda >/dev/null 2>&1; then
echo "Conda already available at $(command -v conda)"
conda config --set quiet true
conda --version
exit 0
fi
MINICONDA_DIR="${HOME}/miniconda3"
if [ -x "${MINICONDA_DIR}/Scripts/conda.exe" ] || [ -x "${MINICONDA_DIR}/bin/conda" ]; then
echo "Miniconda already present at ${MINICONDA_DIR}"
else
case "$(uname -s)" in
MINGW*|MSYS*|CYGWIN*)
echo "install-miniconda: unexpected Windows path without preinstalled conda"
exit 1
;;
Darwin)

MINICONDA_DIR=""
case "$(uname -s)" in
MINGW*|MSYS*|CYGWIN*)
for candidate in \
"${CONDA:-}" \
"/c/Miniconda" \
"/c/Miniconda3" \
"/c/ProgramData/miniconda3" \
"/c/ProgramData/Miniconda3" \
"${HOME}/miniconda3" \
"${HOME}/Miniconda3" \
"${HOME}/appdata/Local/miniconda3" \
"${HOME}/appdata/Local/Continuum/miniconda3"; do
if conda_present_at "${candidate}"; then
MINICONDA_DIR="${candidate}"
break
fi
done

if [ -z "${MINICONDA_DIR}" ]; then
conda_exe="$(cmd.exe //c "where conda 2>nul" 2>/dev/null | head -n1 | tr -d '\r' || true)"
if [ -n "${conda_exe}" ]; then
if command -v cygpath >/dev/null 2>&1; then
conda_exe="$(cygpath -u "${conda_exe}")"
else
conda_exe="$(echo "${conda_exe}" | sed 's|\\|/|g' | sed 's|^\([A-Za-z]\):|/\L\1|')"
fi
MINICONDA_DIR="$(cd "$(dirname "${conda_exe}")/.." && pwd)"
fi
fi

if [ -z "${MINICONDA_DIR}" ]; then
MINICONDA_DIR="${HOME}/miniconda3"
fi

if ! conda_present_at "${MINICONDA_DIR}"; then
echo "Installing Miniconda to %USERPROFILE%\\miniconda3 via cmd.exe..."
curl -fsSL -o miniconda-installer.exe \
"https://repo.anaconda.com/miniconda/Miniconda3-latest-Windows-x86_64.exe"
# /D= must be last and must not be quoted (NSIS installer requirement).
cmd.exe //c "miniconda-installer.exe /InstallationType=JustMe /RegisterPython=0 /S /D=%USERPROFILE%\\miniconda3"
rm -f miniconda-installer.exe
MINICONDA_DIR="${HOME}/miniconda3"
fi
;;
Darwin)
MINICONDA_DIR="${HOME}/miniconda3"
if ! conda_present_at "${MINICONDA_DIR}"; then
ARCH="$(uname -m)"
if [ "${ARCH}" = "arm64" ]; then
INSTALLER_URL="https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh"
Expand All @@ -38,13 +84,20 @@ commands:
curl -fsSL -o miniconda-installer.sh "${INSTALLER_URL}"
bash miniconda-installer.sh -b -p "${MINICONDA_DIR}"
rm -f miniconda-installer.sh
;;
*)
echo "install-miniconda: unsupported OS $(uname -s)"
exit 1
;;
esac
fi
;;
*)
echo "install-miniconda: unsupported OS $(uname -s)"
exit 1
;;
esac

if ! conda_present_at "${MINICONDA_DIR}"; then
echo "install-miniconda: conda not found under ${MINICONDA_DIR}"
exit 1
fi
echo "Using Miniconda at ${MINICONDA_DIR}"

{
echo "export MINICONDA_DIR=${MINICONDA_DIR}"
case "$(uname -s)" in
Expand All @@ -58,6 +111,7 @@ commands:
} >> "${BASH_ENV}"
# shellcheck source=/dev/null
source "${BASH_ENV}"
conda config --set quiet true
conda --version

run-conda-test-suite:
Expand All @@ -75,8 +129,9 @@ commands:
[ -f "${BASH_ENV}" ] && source "${BASH_ENV}"

eval "$(conda shell.bash hook)"
conda update -y conda
conda create -n cheminf python=3.12 -y
conda config --set quiet true
conda update -y -q conda
conda create -n cheminf python=3.11 -y -q
conda activate cheminf

python -m pip install --upgrade pip
Expand All @@ -93,6 +148,7 @@ commands:
Linux)
CONDA_PKGS+=(
libgfortran=14.2.0
libgomp
libxkbcommon
mscorefonts
fonts-conda-forge
Expand All @@ -101,8 +157,20 @@ commands:
Darwin)
CONDA_PKGS+=(libgfortran=14.2.0)
;;
MINGW*|MSYS*|CYGWIN*)
# xTB on win-64 is built with MinGW; match Linux/macOS Fortran/OpenMP runtimes.
CONDA_PKGS+=(
libgfortran=14.2.0
llvm-openmp
)
;;
esac
conda install -y -c conda-forge "${CONDA_PKGS[@]}"
if ! conda install -y -q -c conda-forge "${CONDA_PKGS[@]}" >conda-install.log 2>&1; then
echo "conda install failed; last 200 lines:"
tail -n 200 conda-install.log
exit 1
fi
echo "conda install finished ($(wc -c < conda-install.log) bytes of log)"

case "$(uname -s)" in
Linux)
Expand All @@ -120,6 +188,76 @@ commands:
pip install .
pip install pytest pytest-cov pytest-qt

# xtb needs OpenMP/Fortran runtimes from the conda env (verify before AQME tests).
case "$(uname -s)" in
Linux)
export LD_LIBRARY_PATH="$CONDA_PREFIX/lib:${LD_LIBRARY_PATH:-}"
;;
Darwin)
export DYLD_FALLBACK_LIBRARY_PATH="$CONDA_PREFIX/lib:${DYLD_FALLBACK_LIBRARY_PATH:-}"
;;
MINGW*|MSYS*|CYGWIN*)
export PATH="$CONDA_PREFIX/Library/bin:$CONDA_PREFIX/Scripts:$PATH"
;;
esac
command -v xtb
xtb --version
python -c "import importlib.metadata as m; import aqme; print('aqme', m.version('aqme'))"
# Windows-only preflight: Linux/macOS AQME tests already pass in CI.
case "$(uname -s)" in
MINGW*|MSYS*|CYGWIN*)
conda list | grep -E '^(xtb|aqme|libgfortran|libgomp|llvm-openmp)\s' || true
echo "=== Windows AQME/xTB preflight ==="
PREFLIGHT_DIR="$(mktemp -d)"
printf '%s\n' \
'3' \
'preflight' \
'C 0.000000 0.000000 0.000000' \
'H 1.089000 0.000000 0.000000' \
'H -0.363000 1.028000 0.000000' \
> "${PREFLIGHT_DIR}/preflight.xyz"
set +e
xtb_out="$(xtb "${PREFLIGHT_DIR}/preflight.xyz" --gfn 2 --chrg 0 --uhf 0 2>&1)"
xtb_rc=$?
set -e
echo "${xtb_out}" | tail -n 40
if [ "${xtb_rc}" -ne 0 ]; then
echo "xtb preflight failed (exit ${xtb_rc})"
exit 1
fi
if ! echo "${xtb_out}" | grep -qiE 'total energy|:: total energy'; then
echo "xtb preflight: no energy line in output"
exit 1
fi

printf 'code_name,SMILES\npreflight,C\n' > "${PREFLIGHT_DIR}/AQME_indiv.csv"
(
cd "${PREFLIGHT_DIR}"
python -u -m aqme --qdescp \
--input AQME_indiv.csv \
--program xtb \
--csv_name AQME_indiv.csv \
--nprocs 1 \
--sample 1 \
--robert
)
if [ ! -f "${PREFLIGHT_DIR}/AQME-ROBERT_interpret_AQME_indiv.csv" ]; then
echo "AQME preflight: expected CSV not created"
ls -la "${PREFLIGHT_DIR}" || true
for log in "${PREFLIGHT_DIR}/QDESCP/QDESCP_data.dat" \
"${PREFLIGHT_DIR}/CSEARCH/CSEARCH_data.dat"; do
if [ -f "${log}" ]; then
echo "--- tail ${log} ---"
tail -n 80 "${log}"
fi
done
exit 1
fi
echo "Windows AQME/xTB preflight passed"
rm -rf "${PREFLIGHT_DIR}"
;;
esac

set +e

python -m pytest \
Expand Down Expand Up @@ -279,6 +417,7 @@ jobs:
shell: bash.exe
steps:
- checkout
- install-miniconda
- run-conda-test-suite:
upload_coverage: false

Expand Down
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,14 @@ dmypy.json

# Pyre type checker
.pyre/

# ROBERT module run outputs (local working directory artifacts)
CURATE/
GENERATE/
VERIFY/
PREDICT/
AQME/
EVALUATE/
ROBERT_report.pdf
report_debug.txt
report.css
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Full documentation with installation instructions, technical details and example
Don't miss out the latest hands-on tutorials from our [YouTube channel](https://www.youtube.com/channel/UCHRqI8N61bYxWV9BjbUI4Xw)!

## Recommended installation
1. (Only once) Create new conda environment: `conda create -n robert python=3.10`
1. (Only once) Create new conda environment: `conda create -n robert python=3.12`
2. Activate conda environment: `conda activate robert`
3. Install ROBERT using pip: `pip install robert`
4. Install RDKit (only if you plan to use easyROB): `pip install rdkit`
Expand Down
2 changes: 1 addition & 1 deletion build_easyrob/config_files/backend_env.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ dependencies:
- mscorefonts
- pip
- pip:
- robert==2.0.2
- robert==2.2.0
- aqme==2.0.0
34 changes: 33 additions & 1 deletion docs/Examples/full_workflow/CSV/Robert_example.csv
Original file line number Diff line number Diff line change
@@ -1,6 +1,38 @@
Name,Target_values,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11
1,1.854766065,12,110.9270401,70.8240401,Csub-H,89.87553406,49.77253406,1,0,0,0,1
2,2.034511341,11.7,110.6553116,70.25231158,Csub-Csub,78.65235138,55.53135138,1,0,0,0,1
..., , , , , , , , , , , ,
3,0.860667495,-23.05,112.0635071,36.91050708,H-O,88.85021973,13.69721973,0,0,1,1,1
4,1.026447198,-16.24,112.101181,43.75818103,Csub-O,69.10329437,18.04229437,0,1,0,1,1
5,0.952469022,-31.94,111.8824539,27.83945392,H-O,88.58656311,4.54356311,1,0,1,1,2
6,0.308776518,-68.04,113.0647278,-7.078272217,H-O,89.46292114,-30.68007886,0,0,2,2,2
7,0.982261986,-34.71,110.7689209,23.9559209,Csub-Csub,79.076828,9.545828003,1,0,1,1,2
8,1.129601283,-34.94,111.5555725,24.51257251,Csub-Csub,78.75331879,8.992318787,1,0,1,1,2
9,1.047746118,-34.48,110.5679703,23.98497028,Csub-Csub,78.03665161,8.735651611,1,0,1,1,2
10,0.515551116,-62.34,110.4608917,-3.982108276,Csub-O,58.43679047,-38.72420953,0,1,1,2,2
11,0.515551116,-62.34,113.9221497,-0.520850342,Csub-O,69.55827332,-27.60272668,0,1,1,2,2
12,0.44305174,-62.34,112.8844147,-1.558585327,Csub-O,62.99021912,-34.17078088,0,1,1,2,2
13,2.221390241,0.29,110.5127563,58.69975635,Csub-Csub,77.87947083,43.34847083,2,0,0,0,2
14,2.138192104,-0.78,110.3923798,57.50937976,Csub-Csub,78.41550446,42.81450446,2,0,0,0,2
15,1.883806797,4.54,110.719635,63.15663501,Csub-H,89.83821106,42.27521106,2,0,0,0,2
16,2.091025544,4.12,111.3189087,63.33590869,Csub-H,89.78244019,41.79944019,2,0,0,0,2
17,1.902644865,4.29,110.7536316,62.94063159,Csub-H,89.6808548,41.8678548,2,0,0,0,2
18,2.312908191,-0.46,110.959137,58.39613696,Csub-Csub,78.64178467,43.36078467,2,0,0,0,2
19,1.16234335,-30.93,110.8476944,27.8146944,Csub-Csub,76.10786438,10.35686438,1,0,0,0,1
20,1.989080521,-32.41,111.2339783,26.72097827,Csub-H,82.79759216,5.392952454,2,0,0,0,2
21,2.801329141,-5.9,110.3707199,52.36771991,Csub-Csub,78.09907532,37.37807532,2,0,0,0,2
22,2.391560251,-5.9,110.9408264,52.93782642,Csub-Csub,78.66916656,37.94816656,2,0,0,0,2
23,2.011592734,-5.9,110.4220352,52.41903522,Csub-Csub,78.39561462,37.67461462,2,0,0,0,2
24,0.998633019,-27.6,110.4682465,30.76524646,Csub-O,66.3848114,3.963811401,1,1,0,1,2
25,1.031375085,-27.6,113.392807,33.68980701,Csub-O,69.00031281,6.579312805,1,1,0,1,2
26,1.006818535,-27.6,112.2061539,32.50315387,Csub-O,67.16915131,4.748151306,1,1,0,1,2
27,1.694401925,-29.7,110.9802704,29.17727039,Csub-Csub,77.10182953,51.03182953,1,0,0,0,1
28,0.515838419,-65.68,111.9355087,-5.847491272,H-O,78.45265198,-39.33034802,0,0,2,2,2
29,0.916777853,-24.3,111.7115936,35.30859363,Csub-O,70.3069458,17.6069458,0,1,0,1,1
30,0.837770564,-71.32,111.7983551,-11.6246449,H-O,76.89291382,-46.53008618,1,0,2,2,3
31,0.942297022,-30.67,111.0540771,28.28107715,H-O,86.16723633,3.394236328,1,0,1,1,2
32,0.965415203,-29.94,110.8601837,28.81718372,H-O,86.97593689,4.93293689,1,0,1,1,2
33,0.39762592,-101.6,111.0383148,-42.66468518,Csub-O,55.76971817,-71.26043939,0,2,1,3,3
34,1.178714383,-101.6,111.0308151,-42.67218488,H-O,84.12934875,-69.57365125,2,0,1,1,3
35,0.410599034,-101.6,111.6276932,-42.07530682,Csub-O,59.93067169,-76.49032831,0,2,1,3,3
36,0.321084552,-101.6,110.7593079,-42.94369214,Csub-O,59.81459808,-76.60640192,0,2,1,3,3
37,0.329517076,-101.6,115.2292938,-38.47370618,Csub-O,70.45233154,-65.96866846,0,2,1,3,3
14 changes: 11 additions & 3 deletions docs/Examples/full_workflow/full_workflow.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,19 @@ Executing the job
Execution time and versions
+++++++++++++++++++++++++++

Time: ~3.5 min
Time: ~10 min

System: 8 processors (11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz) using 16.0 GB RAM memory
System: 8 processors (x86_64 Linux) using 16.0 GB RAM memory

ROBERT version: 2.0.1
ROBERT version: 2.2.0

numpy version: 2.3.4

scikit-learn version: 1.7.2

xgboost version: 2.1.4

bayesian-optimization version: 3.1.0

scikit-learn-intelex version: 2025.2.0

Expand Down
14 changes: 11 additions & 3 deletions docs/Examples/full_workflow/full_workflow_test.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,19 @@ Executing the job
Execution time and versions
+++++++++++++++++++++++++++

Time: ~10 sec
Time: ~1.5 min

System: 8 processors (11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz) using 16.0 GB RAM memory
System: 8 processors (x86_64 Linux) using 16.0 GB RAM memory

ROBERT version: 2.0.1
ROBERT version: 2.2.0

numpy version: 2.3.4

scikit-learn version: 1.7.2

xgboost version: 2.1.4

bayesian-optimization version: 3.1.0

scikit-learn-intelex version: 2025.2.0

Expand Down
18 changes: 13 additions & 5 deletions docs/Examples/full_workflow/smiles_vaskas.rst
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,23 @@ Execution time and versions

Time: ~3 min

System: 4 processors (Intel Xeon Ice Lake 8352Y) using 8.0 GB RAM memory
System: 8 processors (x86_64 Linux) using 16.0 GB RAM memory

ROBERT version: 1.2.0
ROBERT version: 2.2.0

scikit-learn-intelex version: 2024.5.0
numpy version: 2.3.4

AQME version: 1.6.1
scikit-learn version: 1.7.2

xTB version: 6.6.1
xgboost version: 2.1.4

bayesian-optimization version: 3.1.0

scikit-learn-intelex version: 2025.2.0

AQME version: 2.0.0

xTB version: 6.7.1

Results
+++++++
Expand Down
Loading