mol-hume 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. mol_hume-0.1.0/CHANGELOG.md +41 -0
  2. mol_hume-0.1.0/CMakeLists.txt +82 -0
  3. mol_hume-0.1.0/LICENSE +29 -0
  4. mol_hume-0.1.0/METHODS.md +780 -0
  5. mol_hume-0.1.0/PKG-INFO +199 -0
  6. mol_hume-0.1.0/README.md +179 -0
  7. mol_hume-0.1.0/cpp/ac_tables.h +214 -0
  8. mol_hume-0.1.0/cpp/ac_weights.h +128 -0
  9. mol_hume-0.1.0/cpp/chiwalk_tables.h +114 -0
  10. mol_hume-0.1.0/cpp/constit_tables.h +223 -0
  11. mol_hume-0.1.0/cpp/crippen_tables.h +156 -0
  12. mol_hume-0.1.0/cpp/eigen_small.h +477 -0
  13. mol_hume-0.1.0/cpp/estate_tables.h +152 -0
  14. mol_hume-0.1.0/cpp/frag_prog_types.h +67 -0
  15. mol_hume-0.1.0/cpp/frag_program.h +2235 -0
  16. mol_hume-0.1.0/cpp/frag_tables.h +151 -0
  17. mol_hume-0.1.0/cpp/lu_small.h +177 -0
  18. mol_hume-0.1.0/cpp/pickle_tables.h +1005 -0
  19. mol_hume-0.1.0/cpp/qed_alert_program.h +3107 -0
  20. mol_hume-0.1.0/cpp/topo_io.h +99 -0
  21. mol_hume-0.1.0/cpp/vsa_tables.h +96 -0
  22. mol_hume-0.1.0/pyproject.toml +160 -0
  23. mol_hume-0.1.0/src/hume_core/autocorr.h +211 -0
  24. mol_hume-0.1.0/src/hume_core/bindings.cpp +1634 -0
  25. mol_hume-0.1.0/src/hume_core/chi.h +437 -0
  26. mol_hume-0.1.0/src/hume_core/constit.h +1537 -0
  27. mol_hume-0.1.0/src/hume_core/counts_ext.h +516 -0
  28. mol_hume-0.1.0/src/hume_core/crippen_typer.h +641 -0
  29. mol_hume-0.1.0/src/hume_core/emit_filter.h +105 -0
  30. mol_hume-0.1.0/src/hume_core/estate_ext.h +279 -0
  31. mol_hume-0.1.0/src/hume_core/estate_typer.h +545 -0
  32. mol_hume-0.1.0/src/hume_core/eta.h +772 -0
  33. mol_hume-0.1.0/src/hume_core/frag_matcher.h +532 -0
  34. mol_hume-0.1.0/src/hume_core/hume_blocks.h +2316 -0
  35. mol_hume-0.1.0/src/hume_core/ic_tables.h +49 -0
  36. mol_hume-0.1.0/src/hume_core/infocontent.h +1499 -0
  37. mol_hume-0.1.0/src/hume_core/misc_ext.h +1713 -0
  38. mol_hume-0.1.0/src/hume_core/molpickle.h +724 -0
  39. mol_hume-0.1.0/src/hume_core/pathcount.h +160 -0
  40. mol_hume-0.1.0/src/hume_core/rdkcore.h +535 -0
  41. mol_hume-0.1.0/src/hume_core/ringcount.h +426 -0
  42. mol_hume-0.1.0/src/hume_core/spectral.h +803 -0
  43. mol_hume-0.1.0/src/hume_core/sps.h +1922 -0
  44. mol_hume-0.1.0/src/hume_core/topocharge.h +236 -0
  45. mol_hume-0.1.0/src/hume_core/topomisc.h +337 -0
  46. mol_hume-0.1.0/src/hume_core/u128.h +111 -0
  47. mol_hume-0.1.0/src/hume_core/vsa_bins.h +967 -0
  48. mol_hume-0.1.0/src/mol_hume/__init__.py +19 -0
  49. mol_hume-0.1.0/src/molhume/__init__.py +548 -0
  50. mol_hume-0.1.0/src/molhume/_additional.py +171 -0
  51. mol_hume-0.1.0/src/molhume/_columns.py +210 -0
  52. mol_hume-0.1.0/src/molhume/_extract.py +669 -0
  53. mol_hume-0.1.0/src/molhume/_rings.py +207 -0
@@ -0,0 +1,41 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 — 2026-09-01
4
+
5
+ First release.
6
+
7
+ - `molhume.featurize(smiles, ...)` — SMILES (or RDKit `Mol` objects) to one
8
+ `(n_molecules, n_features)` array. 1,269 descriptors per molecule, about 285 us/molecule
9
+ including the fingerprint.
10
+ Column names are not returned, since they are identical for a given set of flags;
11
+ `molhume.feature_names(**flags)` gives them in the same order.
12
+ - The default output is the 1,269 descriptors followed by 2,048 ECFP bits. The bits are
13
+ appended *after* the descriptors, so descriptor column indices do not shift when
14
+ `fingerprint` is turned off.
15
+ - `standardize` has no silent default: leaving it unset behaves as `"none"` and warns once,
16
+ because what molecule the descriptors describe is the caller's decision.
17
+ - `columns`, `additional_descriptors`, `on_error`, `threads`, `fingerprint`, `fp_radius`,
18
+ `fp_size`, `optional`, `batch_size`.
19
+ - `mol_hume` is an alias for `molhume`.
20
+ - BSD 3-Clause, matching rdkit and mordred.
21
+ - Requires `rdkit>=2024.09.1,<2026.09`. The MolPickler blob is read directly and that format is
22
+ not a stable API, so the range is measured rather than assumed. Pickle formats 16.2.0
23
+ (rdkit 2024.09 - 2025.09) and 16.3.0 (rdkit 2026.03) are both supported: the two differ only
24
+ in `AtomMonomerInfo`, which a SMILES molecule never carries, and all 1,269 columns over 8,000
25
+ molecules are bit-identical between rdkit 2025.9.2 and 2026.3.5.
26
+ - Released against RDKit 2025.9.2 as the reference; the published wheel reproduces the
27
+ committed fixture bit-for-bit on macOS arm64, and installs and runs against RDKit 2026.3.5.
28
+ - Verified against RDKit 2025.9.2 and Mordred 1.2.0 over a 42,000-molecule corpus: 167/186
29
+ RDKit and 412/968 Mordred columns bit-identical, 99.99% and 99.23% of values within 1e-9.
30
+ Divergences are enumerated in `METHODS.md`.
31
+ - Wheels for CPython 3.11-3.14 on Linux (x86_64, aarch64), macOS (arm64, x86_64) and Windows.
32
+ - Values are bit-identical across RDKit releases in the supported range, but **not across
33
+ architectures**: the exactness numbers are from macOS arm64/clang, and x86-64 moves 594
34
+ columns (gcc) or 595 (MSVC) by at most 1.1e-14 of each column's range. NaN patterns are
35
+ identical everywhere. See "Values are not bit-identical across architectures" in the README.
36
+
37
+ ### Regenerating the test fixture
38
+
39
+ `tests/data/fixture_expected.npz` records what this build produces. When a descriptor value
40
+ changes on purpose, regenerate it with `tools/gen_fixture.py` and say here which columns moved
41
+ and why. A value that moves without an entry here is a bug.
@@ -0,0 +1,82 @@
1
+ # Build for src/molhume/_core, the pybind11 extension around the verified blocks.
2
+ #
3
+ # NO -march=native. It compiles for whatever core happens to be present, so the binary cannot
4
+ # ship; plain -O3 is what the verification harness is built with
5
+ # (`c++ -O3 -std=c++17 hume.cpp`) and matching it is what makes the bit-identity claim mean
6
+ # something. It also costs nothing to leave out: on arm64 the two flags produce BYTE-IDENTICAL
7
+ # object files for this source, re-checked after the BLAS removal -- see PACKAGING.md.
8
+ #
9
+ # This file is also what makes the wheels buildable off macOS at all; the per-toolchain flags
10
+ # below are the whole of the difference between the three platforms.
11
+ cmake_minimum_required(VERSION 3.15...3.31)
12
+ project(hume_core LANGUAGES CXX)
13
+
14
+ set(CMAKE_CXX_STANDARD 17)
15
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
16
+ set(CMAKE_CXX_EXTENSIONS OFF)
17
+
18
+ find_package(pybind11 CONFIG REQUIRED)
19
+
20
+ pybind11_add_module(_core src/hume_core/bindings.cpp)
21
+ target_include_directories(_core PRIVATE src/hume_core)
22
+
23
+ # OPTIMIZATION AND FLOATING-POINT CONTRACTION, per toolchain.
24
+ #
25
+ # -O3 is what the verification harness is built with (`c++ -O3 -std=c++17 hume.cpp`), and
26
+ # matching it is what makes the bit-identity claim mean something. /O2 is its MSVC equivalent;
27
+ # MSVC has no /O3. /bigobj because these headers put more than 2^16 sections in one object.
28
+ #
29
+ # ffp-contract is NOT a tuning knob here, it is part of the specification. constit.h writes
30
+ # every `a + b * c` across two statements ON PURPOSE, because clang's default `on` contracts
31
+ # within an expression but not across statements, and contracting would produce a more accurate
32
+ # number than the python that is being reproduced -- measured: Vabc differs from mordred on 43
33
+ # of 300 molecules, FilterItLogS on 74, qed on 240. hume_blocks.h documents the opposite case,
34
+ # where `off` makes the resistance disagreement fifty times worse. The rule is to match the
35
+ # reference, not to maximise accuracy, and both of those hold only at `on`.
36
+ #
37
+ # gcc defaults to `fast`, which contracts ACROSS statements and would walk straight through
38
+ # constit.h's defense. It has to be said explicitly or Linux wheels are quietly not the same
39
+ # library as macOS ones. MSVC's /fp:precise does not contract at all, which is the `off` case;
40
+ # /fp:contract restores expression-level contraction.
41
+ if(MSVC)
42
+ target_compile_options(_core PRIVATE /O2 /bigobj /fp:contract)
43
+ else()
44
+ target_compile_options(_core PRIVATE -O3 -ffp-contract=on)
45
+ endif()
46
+
47
+ # NO BLAS, NO LAPACK, NO PLATFORM CHECK -- and that is the point of this file's history.
48
+ #
49
+ # This build used to REFUSE to configure off macOS. src/hume_core/hume_blocks.h asked Accelerate
50
+ # for `dgesv$NEWLAPACK` and `dgemm$NEWLAPACK` by asm label, because Accelerate ships two LAPACKs
51
+ # that do not round the same way and the resistance block had been verified against the modern
52
+ # one. Those symbols exist in no other library, so failing loudly was better than shipping a
53
+ # wheel whose numbers quietly differed. The cost was that HUME was a macOS-only package.
54
+ #
55
+ # Both call sites are now gone, replaced by two header-only implementations with no external
56
+ # dependency at all: cpp/eigen_small.h (BCUT2D's extremal eigenvalues) and cpp/lu_small.h
57
+ # (resistance's per-component solve and rw_returns' matrix powers). There is no longer any
58
+ # `target_link_libraries` here, and no `if(APPLE)`.
59
+ #
60
+ # WHAT CHANGED NUMERICALLY, because "portable now" is not the same as "same numbers":
61
+ # * BCUT2D moved in the last bits on 795 of 98,905 molecules, max 1.9e-10 relative -- inside
62
+ # the rtol 1e-9 the block is graded at.
63
+ # * The resistance BIN columns (RATSC*/RPAIR*) moved on up to 8.1% of molecules. Those
64
+ # columns turn out not to be well defined in floating point at all: exact rational
65
+ # arithmetic shows the flipping pairs sit EXACTLY on a bin edge, and Accelerate's own two
66
+ # LAPACKs disagree with each other on 9.00% of the corpus -- more than reference LU
67
+ # disagrees with either. See the note above resistance() in hume_blocks.h.
68
+ # Neither of those is caused by the build system, but this is where the dependency was declared
69
+ # and this is where someone will come looking.
70
+ #
71
+ # PROVEN, not assumed. Both of these configure and compile clean, and the resulting extension
72
+ # links no BLAS (checked with otool -L / ldd):
73
+ # cmake -S . -B build/nolapack -DCMAKE_DISABLE_FIND_PACKAGE_BLAS=ON \
74
+ # -DCMAKE_DISABLE_FIND_PACKAGE_LAPACK=ON -DCMAKE_FIND_FRAMEWORK=NEVER \
75
+ # -DCMAKE_SYSTEM_FRAMEWORK_PATH= -DCMAKE_OSX_SYSROOT=
76
+ # c++ -O3 -std=c++17 -o hume cpp/hume.cpp # no -framework Accelerate
77
+ #
78
+ # The two headers live under cpp/ and are pulled in by relative path from hume_blocks.h, so no
79
+ # include directory is needed here -- but they MUST be present in the sdist. Both are tracked by
80
+ # git, which is what scikit-build-core uses to decide what an sdist contains.
81
+
82
+ install(TARGETS _core DESTINATION molhume)
mol_hume-0.1.0/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Leif Sieben
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.