Files
MX_Pmodule/olex2
duan_j 2b5bb570ca olex2: do not preserve ownership when copying into PREFIX
First build failed in install: cp -a onto /opt/psi logs 'failed to
preserve ownership ... Permission denied' for every file (chown refused)
and exits non-zero, which tripped the die-guard although the copy itself
was fine. Use cp -r --preserve=mode,timestamps,links instead. Record the
pitfall in the new-module skill guardrails.
2026-10-16 17:26:28 +02:00
..

olex2

Olex2 — open-source (BSD) small-molecule crystal structure solution, refinement and analysis (olex2.refine / ShelX front-end, built on cctbx/smtbx). This module provides both the GUI and the console build:

launcher what it is
olex2 wxWidgets GUI (needs an X display)
olex2c console / "headless" Olex2 — same engine, no GUI, scriptable

How it is built

Upstream (install notes, "Linux"): "We do not provide installers for Linux – and provide zip files instead (Use the 'start' bash script to launch Olex2)" and "Nothing needs to be compiled". The official olex2-distro/1.5/olex2-linux64.zip (255 MB, ~1 GB unpacked) already contains everything (verified by listing the archive, 2026-10-16):

olex2/olex2      GUI binary                  olex2/olex2c   console binary (24 MB)
olex2/unirun     vendor auto-updater         olex2/start    vendor launcher (runs unirun, then olex2)
olex2/cctbx/     cctbx_build + cctbx_sources olex2/lib/     private CPython 3.8 + libpython, openblas, ssl, png, ...
olex2/ilib/      olex2/util/pyUtil/  olex2/etc/  olex2/sample_data/  NoSpherA2, hart, hart_mpi ...

The recipe (build):

  1. default pbuild::prep downloads the zip per urls: in files/config.yaml into the distfiles cache as olex2-<version>-linux64.zip, verifies the pinned sha256 and copies it to SRC_DIR (unpacker: none);
  2. configure runs unzip -t (truncated-download guard) and unzips;
  3. install copies the vendor tree flat into $PREFIX — Olex2 derives its BaseDir() from the binary location, so the layout must stay as shipped — fixes modes, switches usettings.dat to update=Never, and installs files/olex2-launcher twice as $PREFIX/bin/olex2 and $PREFIX/bin/olex2c. Only $PREFIX/bin goes on PATH.

files/olex2-launcher is the vendor start script minus the updater: it exports OLEX2_CCTBX_DIR, BOOST_ADAPTBX_*, OLEX2_GL_*, LD_LIBRARY_PATH=$PREFIX/lib:$PREFIX/ilib:$PREFIX/cctbx/cctbx_build/lib, PYTHONHOME=$PREFIX, unsets PYTHONPATH (an inherited one would be imported by the embedded Python 3.8 and break it), sets LIBGL_ALWAYS_SOFTWARE=1 for the GUI only, then execs the binary. unirun is never run: /opt/psi/MX is shared and read-only, updates are done by building a new module version.

Why the binary archive and not a source build

The user-facing "open source" route is this archive: Olex2 is BSD and the official binaries are the open-source build. Compiling from https://github.com/pcxod/olex2 is not a practical module recipe: the repo builds only olex2 (GUI, wxWidgets mandatory) and unirun — there is no olex2c target in its CMakeLists/SConstruct/Makefile — the HTML GUI is in a separate SVN, and the matching cctbx/smtbx build is not published. Its own README says to take the official distribution and only swap in self-built olex2/unirun binaries. The Headless.zip/Batch.zip next to the archive on the download server are 2 KB plugin stubs, not builds.

Building on Ra / RHEL9

module use unstable && module load modbuild/2.1.3
cd olex2
modbuild build \
    --tmpdir=/das/work/p21/p21515/.cache/Pmodules \
    --distdir=/das/work/p21/p21515/.cache/Pmodules \
    1.5-7665
module use MX unstable && module load olex2/1.5-7665

Expect a silent 10–20 min for the cp -a of ~12 000 files onto /opt/psi; watch du -sh /opt/psi/MX/olex2/1.5-7665 from a second shell. Needs unzip on the build host.

If the download server is unreachable from the build host (it is a plain https URL, no login), fetch the zip anywhere and pre-stage it under the exact name <distdir>/olex2-1.5-7665-linux64.zip; prep then skips the download but still checks the sha256.

RHEL9 runtime libraries. The binaries bundle their own python, ssl, png, jpeg, tiff, openblas, gfortran, but link system X11/GTK/OpenGL. On a fresh RHEL9 host check once:

module load olex2/1.5-7665
ldd /opt/psi/MX/olex2/1.5-7665/olex2c | grep 'not found'   # console: expect nothing
ldd /opt/psi/MX/olex2/1.5-7665/olex2  | grep 'not found'   # GUI: typically gtk/mesa libs

and dnf install whatever the GUI line reports (likely candidates: gtk3/gtk2, mesa-libGL, mesa-libGLU, libSM, libXxf86vm, libxkbcommon, libstdc++). olex2c has far fewer needs and is the one to verify first. Note ldd on the raw binary without the launcher's LD_LIBRARY_PATH also lists the bundled libs as missing — only lines that survive with the launcher env count:

LD_LIBRARY_PATH=$P/lib:$P/ilib:$P/cctbx/cctbx_build/lib ldd $P/olex2c | grep 'not found'   # P=/opt/psi/MX/olex2/1.5-7665

Verifying the install

which olex2c            # -> /opt/psi/MX/olex2/1.5-7665/bin/olex2c
which olex2             # -> /opt/psi/MX/olex2/1.5-7665/bin/olex2
cat /opt/psi/MX/olex2/1.5-7665/version.txt   # SVN Revision No. 7665

# console: starts, loads a shipped sample, refines, exits (writes to ~/.olex2
# and to a scratch copy of the sample - run it in a scratch dir)
cd $(mktemp -d) && cp /opt/psi/MX/olex2/1.5-7665/sample_data/sucrose/* .
olex2c                  # interactive prompt; then type:
#   reap sucrose.res
#   refine 4
#   exit

# GUI (needs X / x2go / NoMachine session):
olex2

Scripting olex2c: it reads commands from stdin, so a batch job can do printf 'reap %s\nrefine 10\nexit\n' x.ins | olex2c (to be confirmed on the first RHEL9 test — the Windows olex2c.exe is used this way by CrysAlisPro and the upstream NoSpherA2 release tests). The headless engine loads macrox.xld instead of macro.xld; GUI-only python calls print "not available in Headless Olex" rather than fail.

First-start notes: Olex2 keeps user data in ~/.olex2 (DataDir), copies sample data there and may try to delete runonce.* markers in BaseDir (read-only for users — harmless). The vendor start and unirun remain under $PREFIX but are intentionally not on PATH; do not run them against the shared install.

Adding a new version

1.5/olex2-linux64.zip is a rolling file — OlexSys replaces it in place (check Modified on https://secure.olex2.org/olex2-distro/1.5/, or the ALPHA/BETA series folders). The sha256 pinned in files/config.yaml will therefore fail against a newer drop; that is the signal to add a version, not to edit the hash:

  1. download the current zip and read its revision and hash: unzip -p olex2-linux64.zip olex2/version.txt → e.g. SVN Revision No. 7800, sha256sum olex2-linux64.zip;
  2. add 1.5-7800 under versions: (relstage: unstable) and olex2-1.5-7800-linux64.zip: <sha256> under shasums: — the urls: entry needs no change (${V_PKG} = series dir, ${V} = cache name); for a 1.6 series just use 1.6-<rev> and the URL follows;
  3. build as above; promote to stable only after olex2c and olex2 have been exercised on the target host.

History: 1.5 (stable) is the older Ra/RHEL8 module built by the previous recipe from a hand-downloaded olex2-linux64.zip placed next to build (never committed, *.zip is gitignored); it is kept in config.yaml so the installed module stays listed. Do not rebuild it with this recipe.