Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ polychrom/_polymer_math.cpp
*.dat
.idea
dist
polychrom/*.so
3 changes: 1 addition & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ def setup(app):
"simtk",
"simtk.unit",
"simtk.unit.nanometer",
"simtk.openmm",
"joblib",
"simtk.openmm",
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing whitespace after 'simtk.openmm'. Remove the extra spaces at the end of the line.

Suggested change
"simtk.openmm",
"simtk.openmm",

Copilot uses AI. Check for mistakes.
"scipy.interpolate.fitpack2",
]
for mod_name in MOCK_MODULES:
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Polychrom requires OpenMM, which can be installed through conda: ``conda install

CUDA is the fastest GPU-assisted backend to OpenMM. You would need to have the required version of CUDA, or install OpenMM compiled for your version of CUDA.

Other dependencies are simple, and are listed in requirements.txt. All but joblib are installable from either conda/pip, and joblib installs well with pip.
Other dependencies are simple, and are listed in requirements.txt. All are installable through pip or conda.

Installation errors and possible fixes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
18 changes: 18 additions & 0 deletions polychrom/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,19 @@
__version__ = "0.1.1"

# Check for OpenMM installation
try:
import openmm
except ImportError:
import warnings
warnings.warn(
"\n"
"OpenMM is not installed. Polychrom requires OpenMM for molecular dynamics simulations.\n"
"\n"
"Please install OpenMM with the appropriate backend for your system:\n"
" - For CUDA: pip install openmm[cuda13]\n"
" - For CPU: pip install openmm\n"
"\n"
"Visit https://openmm.org for more information.",
ImportWarning,
stacklevel=2
)
1 change: 0 additions & 1 deletion polychrom/__polymer_math.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include <cmath>
#include <vector>
#include <ctime>
#include <omp.h>

using namespace std;

Expand Down
3 changes: 1 addition & 2 deletions polychrom/cli/show
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import os
import sys
import tempfile

import joblib
import numpy as np

usage = """
Expand Down Expand Up @@ -43,7 +42,7 @@ start, end, step will basically select data[start:end:step]


if len(sys.argv) < 2:
print(useage)
print(usage)
exit()


Expand Down
1 change: 0 additions & 1 deletion polychrom/cli/xyz
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import sys
import tempfile
import textwrap

import joblib
import numpy as np

usage = """
Expand Down
55 changes: 9 additions & 46 deletions polychrom/polymerutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@
import io
import os

import joblib
import numpy as np
import six

from polychrom.hdf5_format import load_URI

Expand All @@ -49,8 +47,7 @@ def load(filename):

New-style URIs (HDF5 based storage)

Text files in openmm-polymer format
joblib files in openmm-polymer format
Joblib and text files were deprecated.

Parameters
----------
Expand All @@ -61,24 +58,10 @@ def load(filename):
"""
if "::" in filename:
return hdf5_format.load_URI(filename)["pos"]

raise ValueError("Only URIs are supported in this version of polychrom")

if not os.path.exists(filename):
raise IOError("File not found :( \n %s" % filename)

try: # loading from a joblib file here
return dict(joblib.load(filename)).pop("data")
except Exception: # checking for a text file
data_file = open(filename)
line0 = data_file.readline()
try:
N = int(line0)
except (ValueError, UnicodeDecodeError):
raise TypeError("Could not read the file. Not text or joblib.")
data = [list(map(float, i.split())) for i in data_file.readlines()]

if len(data) != N:
raise ValueError("N does not correspond to the number of lines!")
return np.array(data)


def fetch_block(folder, ind, full_output=False):
Expand Down Expand Up @@ -129,45 +112,25 @@ def fetch_block(folder, ind, full_output=False):
pos = exists.index(True)
block = load_URI(blocksh5[pos] + f"::{ind}")
if not full_output:
block = block["pos"]
return block["pos"]

Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing return statement when full_output=True for HDF5 files. When full_output=True, the function should return the full block dictionary but currently falls through without returning it. Add return block after line 115 or change line 115 to return block['pos'] and add an else: return block clause.

Suggested change
return block

Copilot uses AI. Check for mistakes.
if len(blocksdat) > 0:
block = load(os.path.join(folder, f"block{ind}.dat"))
return block
return load(os.path.join(folder, f"block{ind}.dat"))
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line will always raise a ValueError since the load() function no longer supports .dat files (line 62 raises ValueError for non-URI filenames). The function should either handle .dat files differently or remove this deprecated code path entirely. If .dat files are still expected to be supported for backward compatibility, the load() function needs to be updated, or this should call a different function.

Copilot uses AI. Check for mistakes.
raise ValueError(f"Cannot find the block {ind} in the folder {folder}")


def save(data, filename, mode="txt", pdbGroups=None):
"""
Basically unchanged polymerutils.save function from openmm-polymer

It can save into txt or joblib formats used by old openmm-polymer


It is also very useful for saving files to PDB format to make them compatible
with nglview, pymol_show and others
"""
data = np.asarray(data, dtype=np.float32)

if mode.lower() == "joblib":
joblib.dump({"data": data}, filename=filename, compress=9)
return

if mode.lower() == "txt":
lines = [str(len(data)) + "\n"]

for particle in data:
lines.append("{0:.3f} {1:.3f} {2:.3f}\n".format(*particle))
if filename is None:
return lines

elif isinstance(filename, six.string_types):
with open(filename, "w") as myfile:
myfile.writelines(lines)
elif hasattr(filename, "writelines"):
filename.writelines(lines)
else:
raise ValueError("Not sure what to do with filename {0}".format(filename))

elif mode == "pdb":
if mode == "pdb":
data = data - np.minimum(np.min(data, axis=0), np.zeros(3, float) - 100)[None, :]
retret = ""

Expand Down Expand Up @@ -212,7 +175,7 @@ def add(st, n):
filename.write("C {0} {1} {2}".format(*i))

else:
raise ValueError("Unknown mode : %s, use h5dict, joblib, txt or pdb" % mode)
raise ValueError("Unknown mode : %s, use or pdb" % mode)
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error message is grammatically incorrect. 'use or pdb' should be 'use pdb' since pdb is now the only supported mode after removing txt and joblib modes.

Suggested change
raise ValueError("Unknown mode : %s, use or pdb" % mode)
raise ValueError("Unknown mode: %s. Only 'pdb' is supported." % mode)

Copilot uses AI. Check for mistakes.


def rotation_matrix(rotate):
Expand Down
58 changes: 54 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,59 @@
[build-system]
requires = ["setuptools>=45", "wheel", "cython>=0.29", "numpy>=1.9"]
build-backend = "setuptools.build_meta"

[project]
name = "polychrom"
version = "0.1.1"
description = "A library for polymer simulations and their analyses."
readme = "README.md"
requires-python = ">=3.7"
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description claims 'Bumped python version to 3.13', but requires-python is set to '>=3.7'. This is inconsistent. If the intention is to require Python 3.13 as the minimum version, this should be requires-python = '>=3.13'. If Python 3.7+ is the correct minimum version, the PR description should be updated to reflect that Python 3.13 is added to the classifiers (supported versions) rather than being the minimum requirement.

Suggested change
requires-python = ">=3.7"
requires-python = ">=3.13"

Copilot uses AI. Check for mistakes.
license = "MIT"
authors = [
{name = "Mirny Lab", email = "espresso@mit.edu"}
]
keywords = ["genomics", "polymer", "Hi-C", "molecular dynamics", "chromosomes"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Science/Research",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]

dependencies = [
"cython>=0.29",
"numpy>=1.9",
"scipy>=0.16",
"h5py>=2.5",
"pandas>=0.19",
]

[project.optional-dependencies]
dev = [
"pytest",
"black",
"isort",
]

[project.urls]
Homepage = "https://github.com/open2c/polychrom"
Repository = "https://github.com/open2c/polychrom"

[project.scripts]
polychrom = "polychrom.cli:cli"

[tool.setuptools.packages.find]
include = ["polychrom*"]
exclude = ["utilities*", "build*", "docs*", "examples*"]

[tool.black]
line-length = 120

[tool.isort]
profile = "black"

[build-system]
requires = ["setuptools", "setuptools-scm", "cython"]
build-backend = "setuptools.build_meta"
3 changes: 0 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
six
cython
numpy>=1.9
scipy>=0.16
h5py>=2.5
pandas>=0.19
joblib
pyknotid
pytest
76 changes: 11 additions & 65 deletions setup.py
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,70 +1,16 @@
import io
import os
import re
from setuptools import setup, Extension
from Cython.Build import cythonize
from Cython.Distutils import build_ext
from setuptools import find_packages
from distutils.core import setup
from distutils.extension import Extension

cmdclass = {}


def _read(*parts, **kwargs):
filepath = os.path.join(os.path.dirname(__file__), *parts)
encoding = kwargs.pop("encoding", "utf-8")
with io.open(filepath, encoding=encoding) as fh:
text = fh.read()
return text


def get_version():
version = re.search(
r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]',
_read("polychrom", "__init__.py"),
re.MULTILINE,
).group(1)
return version


def get_long_description():
return _read("README.md")


def get_requirements(path):
content = _read(path)
return [req for req in content.split("\n") if req != "" and not req.startswith("#")]


cmdclass.update({"build_ext": build_ext})

ext_modules = cythonize(
[
Extension(
"polychrom._polymer_math",
["polychrom/_polymer_math.pyx", "polychrom/__polymer_math.cpp"],
)
]
)
import numpy

# Define Cython extensions
Comment on lines +3 to +5
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The setup.py imports setuptools.Extension and Cython.Build.cythonize directly, but these should be available at build time from the build-system requirements. However, importing numpy directly at the module level can cause issues if numpy is not yet installed. Consider using a try-except block or ensuring numpy is installed before this import executes, or use the PEP 517 isolated build which should handle this correctly.

Suggested change
import numpy
# Define Cython extensions
# Define Cython extensions
import numpy

Copilot uses AI. Check for mistakes.
ext_modules = [
Extension(
"polychrom._polymer_math",
["polychrom/_polymer_math.pyx", "polychrom/__polymer_math.cpp"],
include_dirs=[numpy.get_include()],
)
]

setup(
name="polychrom",
author="Mirny Lab",
author_email="espresso@mit.edu",
version=get_version(),
url="http://github.com/mirnylab/polychrom",
description=("A library for polymer simulations and their analyses."),
long_description=get_long_description(),
long_description_content_type="text/markdown",
keywords=["genomics", "polymer", "Hi-C", "molecular dynamics", "chromosomes"],
ext_modules=ext_modules,
cmdclass=cmdclass,
packages=find_packages(),
setup_requires=["cython"],
entry_points={
"console_scripts": [
"polychrom = polychrom.cli:cli",
]
},
ext_modules=cythonize(ext_modules, language_level="3"),
)
5 changes: 1 addition & 4 deletions utilities/showChainWithRasmol.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
import sys
import tempfile
import textwrap

import joblib
import polychrom.polymerutils as polymerutils
import numpy as np

if len(sys.argv) < 2:
Expand Down Expand Up @@ -100,8 +99,6 @@ def convertData(data, colors):


def load(filename):
from openmmlib import polymerutils

return polymerutils.load(filename)


Expand Down
Loading