diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2134824..dfe20e3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,10 +15,6 @@ jobs: os: [ubuntu-latest] python-version: ["3.12"] imp-branch: [main, develop] - include: - - os: [ubuntu-latest] - python-version: "2.7" - imp-branch: main runs-on: ${{ matrix.os }} steps: @@ -37,8 +33,7 @@ jobs: source ${CONDA_PREFIX}/etc/conda/activate.d/activate-gxx_linux-64.sh cd modules/foo mkdir build && cd build - if test "${{ matrix.python-version }}" = "2.7" ; then PY2=on; else PY2=off; fi - cmake .. -DIMP_DIR=${CONDA_PREFIX}/lib/cmake/IMP -DUSE_PYTHON2=${PY2} -DCMAKE_CXX_FLAGS="-fprofile-arcs -ftest-coverage" + cmake .. -DIMP_DIR=${CONDA_PREFIX}/lib/cmake/IMP -DCMAKE_CXX_FLAGS="-fprofile-arcs -ftest-coverage" make ./setup_environment.sh pytest --cov=.. --cov-branch --cov-report=xml -v ../test/test_*.py test/*/*.py ${GCC/gcc/gcov} */*/*/*.gcno diff --git a/doc/coding.ipynb b/doc/coding.ipynb index de12e82..a2a131b 100644 --- a/doc/coding.ipynb +++ b/doc/coding.ipynb @@ -29,13 +29,13 @@ "# Introduction\n", "\n", "In this tutorial we will cover creating a new IMP module, and writing a\n", - "new [restraint](https://integrativemodeling.org/2.21.0/doc/ref/classIMP_1_1Restraint.html) in C++.\n", + "new [restraint](https://integrativemodeling.org/2.22.0/doc/ref/classIMP_1_1Restraint.html) in C++.\n", "\n", "For more information, see the\n", - "[section on developing IMP in the manual](https://integrativemodeling.org/2.21.0/doc/manual/developing.html).\n", + "[section on developing IMP in the manual](https://integrativemodeling.org/2.22.0/doc/manual/developing.html).\n", "\n", "First, we need to build IMP from source code. See the\n", - "[installation instructions in the manual](https://integrativemodeling.org/2.21.0/doc/manual/installation.html#installation_source) for\n", + "[installation instructions in the manual](https://integrativemodeling.org/2.22.0/doc/manual/installation.html#installation_source) for\n", "more details.\n", "\n", "# Add a new module\n", @@ -72,12 +72,12 @@ "\n", "Let\u2019s add a new class to our module, `MyRestraint`, a simple restraint that\n", "restrains a particle to the xy plane (see the\n", - "[ExampleRestraint class](https://integrativemodeling.org/2.21.0/doc/ref/classIMP_1_1example_1_1ExampleRestraint.html) in\n", + "[ExampleRestraint class](https://integrativemodeling.org/2.22.0/doc/ref/classIMP_1_1example_1_1ExampleRestraint.html) in\n", "`modules/example/` for a similar class).\n", "\n", "> the convention in IMP is for class names (and the files declaring\n", "> and defining them) to be [CamelCase](https://en.wikipedia.org/wiki/Camel_case).\n", - "> See the [naming conventions section in the manual](https://integrativemodeling.org/2.21.0/doc/manual/conventions.html#conventions_names)\n", + "> See the [naming conventions section in the manual](https://integrativemodeling.org/2.22.0/doc/manual/conventions.html#conventions_names)\n", "> for more details.\n", "\n", "We do this by creating a file `MyRestraint.h` in the `modules/foo/include/`\n", @@ -109,7 +109,7 @@ "`foo_config.h` header file.\n", "\n", "We are going to declare a restraint, so the compiler needs the declaration\n", - "of the [IMP::Restraint](https://integrativemodeling.org/2.21.0/doc/ref/classIMP_1_1Restraint.html) base class, which is in [IMP/Restraint.h](https://integrativemodeling.org/2.21.0/doc/ref/Restraint_8h.html).\n", + "of the [IMP::Restraint](https://integrativemodeling.org/2.22.0/doc/ref/classIMP_1_1Restraint.html) base class, which is in [IMP/Restraint.h](https://integrativemodeling.org/2.22.0/doc/ref/Restraint_8h.html).\n", "\n", "The next part of the header declares our new class:\n", "\n", @@ -135,9 +135,9 @@ "and ensures the class can be used outside of the module (e.g. in Python).\n", "\n", "The `IMP_OBJECT_METHODS` macro adds standard methods that all IMP objects\n", - "(like [IMP::Restraint](https://integrativemodeling.org/2.21.0/doc/ref/classIMP_1_1Restraint.html)) are expected to provide.\n", + "(like [IMP::Restraint](https://integrativemodeling.org/2.22.0/doc/ref/classIMP_1_1Restraint.html)) are expected to provide.\n", "\n", - "Our constructor takes an [IMP::Model](https://integrativemodeling.org/2.21.0/doc/ref/classIMP_1_1Model.html), a particle in that model, and a force\n", + "Our constructor takes an [IMP::Model](https://integrativemodeling.org/2.22.0/doc/ref/classIMP_1_1Model.html), a particle in that model, and a force\n", "constant. We also declare the necessary methods to return the score and\n", "inputs for the restraint - we will define these later in the `.cpp` file. \n", "\n", @@ -173,7 +173,7 @@ "Similarly to the header file, we need to put everything in the `IMP::foo`\n", "namespace and include any needed header files. Here we include the previous\n", "declaration of the `MyRestraint` class. We also need the declaration of the\n", - "[XYZ decorator](https://integrativemodeling.org/2.21.0/doc/ref/classIMP_1_1core_1_1XYZ.html) from the [IMP::core](https://integrativemodeling.org/2.21.0/doc/ref/namespaceIMP_1_1core.html) module since we are\n", + "[XYZ decorator](https://integrativemodeling.org/2.22.0/doc/ref/classIMP_1_1core_1_1XYZ.html) from the [IMP::core](https://integrativemodeling.org/2.22.0/doc/ref/namespaceIMP_1_1core.html) module since we are\n", "going to be using the particle\u2019s coordinates to calculate the score.\n", "\n", "Next, we define the constructor of the class:\n", @@ -183,8 +183,8 @@ " : Restraint(m, \"MyRestraint%1%\"), p_(p), k_(k) {}\n", "```\n", "\n", - "The constructor simply calls the [IMP::Restraint](https://integrativemodeling.org/2.21.0/doc/ref/classIMP_1_1Restraint.html) base class constructor (which\n", - "takes the [IMP::Model](https://integrativemodeling.org/2.21.0/doc/ref/classIMP_1_1Model.html) and a human-readable name) and stores the `p` and `k`\n", + "The constructor simply calls the [IMP::Restraint](https://integrativemodeling.org/2.22.0/doc/ref/classIMP_1_1Restraint.html) base class constructor (which\n", + "takes the [IMP::Model](https://integrativemodeling.org/2.22.0/doc/ref/classIMP_1_1Model.html) and a human-readable name) and stores the `p` and `k`\n", "arguments in the class attributes `p_` and `k_` (IMP convention is for class\n", "attributes to end in an underscore). `%1%` is replaced with a unique\n", "number, so multiple restraints will be named MyRestraint1, MyRestraint2, etc.\n", @@ -208,10 +208,10 @@ "metadata": {}, "source": [ "We apply a simple harmonic restraint to the z coordinate to keep the particle\n", - "in the xy plane; we use the [IMP::core::XYZ](https://integrativemodeling.org/2.21.0/doc/ref/classIMP_1_1core_1_1XYZ.html) decorator to treat the particle\n", + "in the xy plane; we use the [IMP::core::XYZ](https://integrativemodeling.org/2.22.0/doc/ref/classIMP_1_1core_1_1XYZ.html) decorator to treat the particle\n", "as a coordinate.\n", "\n", - "The [IMP::ScoreAccumulator](https://integrativemodeling.org/2.21.0/doc/ref/classIMP_1_1ScoreAccumulator.html) class is given the score, and analytic first\n", + "The [IMP::ScoreAccumulator](https://integrativemodeling.org/2.22.0/doc/ref/classIMP_1_1ScoreAccumulator.html) class is given the score, and analytic first\n", "derivatives as well if requested.\n", "\n", "We also need to tell IMP which particles our restraint acts on by\n", @@ -228,7 +228,7 @@ "This is used to order the evaluation of restraints and constraints\n", "(a constraint which moves particle A must be evaluated before any restraint\n", "with A as an input) and for parallelization.\n", - "See [the IMP manual](https://integrativemodeling.org/2.21.0/doc/manual/internal_dependencies.html) for more details.\n", + "See [the IMP manual](https://integrativemodeling.org/2.22.0/doc/manual/internal_dependencies.html) for more details.\n", "\n", "Finally, the file ends with:\n", "\n", @@ -258,13 +258,13 @@ "IMP_SWIG_OBJECT(IMP::foo, MyRestraint, MyRestraints);\n", "```\n", "\n", - "This tells SWIG that `MyRestraint` is an IMP [Object](https://integrativemodeling.org/2.21.0/doc/ref/classIMP_1_1Object.html).\n", - "Most IMP classes are subclasses of [IMP::Object](https://integrativemodeling.org/2.21.0/doc/ref/classIMP_1_1Object.html). These are heavyweight objects\n", + "This tells SWIG that `MyRestraint` is an IMP [Object](https://integrativemodeling.org/2.22.0/doc/ref/classIMP_1_1Object.html).\n", + "Most IMP classes are subclasses of [IMP::Object](https://integrativemodeling.org/2.22.0/doc/ref/classIMP_1_1Object.html). These are heavyweight objects\n", "which are always passed by reference-counted pointers, and are generally not\n", - "copied. Some simple classes (e.g. [IMP::algebra::Vector3D](https://integrativemodeling.org/2.21.0/doc/ref/namespaceIMP_1_1algebra.html#ac775f2279108541ab50c89452791ddcc)) are subclasses of\n", - "[IMP::Value](https://integrativemodeling.org/2.21.0/doc/ref/classIMP_1_1Value.html) instead. These are lightweight objects which are generally passed\n", + "copied. Some simple classes (e.g. [IMP::algebra::Vector3D](https://integrativemodeling.org/2.22.0/doc/ref/namespaceIMP_1_1algebra.html#ac775f2279108541ab50c89452791ddcc)) are subclasses of\n", + "[IMP::Value](https://integrativemodeling.org/2.22.0/doc/ref/classIMP_1_1Value.html) instead. These are lightweight objects which are generally passed\n", "by value or reference, and can be trivially copied. See the\n", - "[IMP manual](https://integrativemodeling.org/2.21.0/doc/manual/conventions.html#conventions_values) for more details.\n", + "[IMP manual](https://integrativemodeling.org/2.22.0/doc/manual/conventions.html#conventions_values) for more details.\n", "\n", "Next, we tell SWIG to parse our C++ header file for the class by adding the\n", "line:\n", @@ -298,7 +298,7 @@ "All comments are parsed by the [doxygen](http://www.doxygen.nl/) tool, which\n", "uses the special comment markers `//!` and\u2028", "`/** */`.\n", - "See the [IMP manual](https://integrativemodeling.org/2.21.0/doc/manual/documenting.html) for more details.\n", + "See the [IMP manual](https://integrativemodeling.org/2.22.0/doc/manual/documenting.html) for more details.\n", "\n", "You should also fill in\u2028", "`modules/foo/README.md` with a description of the\n", @@ -336,7 +336,7 @@ "own `IMP.foo` module. The imports from `__future__` help to ensure that our\n", "test works in the same way in both Python 2 and Python 3.\n", "\n", - "All tests should be classes that use the [IMP.test](https://integrativemodeling.org/2.21.0/doc/ref/namespaceIMP_1_1test.html) module, which adds some\n", + "All tests should be classes that use the [IMP.test](https://integrativemodeling.org/2.22.0/doc/ref/namespaceIMP_1_1test.html) module, which adds some\n", "IMP-specific functionality to the standard Python\n", "[unittest](https://docs.python.org/3/library/unittest.html#module-unittest) module.\n", "\n", @@ -364,7 +364,7 @@ "(`evaluate`), and asks for inputs (`get_inputs`). Here we simply test by\n", "comparing to known good values using the\n", "[standard unittest methods](https://docs.python.org/3/library/unittest.html#assert-methods)\n", - "`assertAlmostEqual`, `assertLess`, and `assertEqual`. (The [IMP.test.TestCase](https://integrativemodeling.org/2.21.0/doc/ref/classIMP_1_1test_1_1TestCase.html)\n", + "`assertAlmostEqual`, `assertLess`, and `assertEqual`. (The [IMP.test.TestCase](https://integrativemodeling.org/2.22.0/doc/ref/classIMP_1_1test_1_1TestCase.html)\n", "class provides some additional methods helpful for IMP tests.)\n", "\n", "> Always use `assertAlmostEqual` for floating point comparisons,\n", @@ -412,11 +412,11 @@ "optional_dependencies = ''\n", "```\n", "\n", - "Since we use the [IMP::core](https://integrativemodeling.org/2.21.0/doc/ref/namespaceIMP_1_1core.html) and [IMP::algebra](https://integrativemodeling.org/2.21.0/doc/ref/namespaceIMP_1_1algebra.html) modules, we need to declare them\n", + "Since we use the [IMP::core](https://integrativemodeling.org/2.22.0/doc/ref/namespaceIMP_1_1core.html) and [IMP::algebra](https://integrativemodeling.org/2.22.0/doc/ref/namespaceIMP_1_1algebra.html) modules, we need to declare them\n", "as requirements for this module.\n", "\n", "`required_dependencies` and `optional_dependencies` can also be used to make\n", - "use of 3rd party libraries. See [the IMP manual](https://integrativemodeling.org/2.21.0/doc/manual/extdepends.html) for more\n", + "use of 3rd party libraries. See [the IMP manual](https://integrativemodeling.org/2.22.0/doc/manual/extdepends.html) for more\n", "information.\n", "\n", "(For reference, the whole file is also available [at GitHub](https://github.com/salilab/imp_coding_tutorial/tree/main/modules/foo/dependencies.py))." @@ -428,7 +428,7 @@ "source": [ "# Pure Python modules\n", "\n", - "If there is no C++ code in your module at all - i.e. it is pure Python - then you can speed up building of your module by marking it as Python only. This is done by adding `python_only = True` to the `dependencies.py` file. SWIG is not used in Python-only modules; instead, put any Python code you want in the top-level module in the `pyext/src/__init__.py` file. For an example, see the [IMP.test module](https://github.com/salilab/imp/tree/develop/modules/test). See the [IMP manual](https://integrativemodeling.org/2.21.0/doc/manual/pyonlymod.html) for more information." + "If there is no C++ code in your module at all - i.e. it is pure Python - then you can speed up building of your module by marking it as Python only. This is done by adding `python_only = True` to the `dependencies.py` file. SWIG is not used in Python-only modules; instead, put any Python code you want in the top-level module in the `pyext/src/__init__.py` file. For an example, see the [IMP.test module](https://github.com/salilab/imp/tree/develop/modules/test). See the [IMP manual](https://integrativemodeling.org/2.22.0/doc/manual/pyonlymod.html) for more information." ] }, { @@ -454,7 +454,7 @@ "# Build and test\n", "\n", "To build the custom module, build IMP from source code\n", - "[in the usual way](https://integrativemodeling.org/2.21.0/doc/manual/installation.html#installation_compilation).\n", + "[in the usual way](https://integrativemodeling.org/2.22.0/doc/manual/installation.html#installation_compilation).\n", "`cmake` should detect the new module and configure it, and then your build\n", "tool (usually `make` or `ninja`) will build it.\n", "\n", @@ -465,7 +465,7 @@ "```\n", "\n", "You can also run all of your module's test cases using the `ctest` tool;\n", - "see the [IMP manual](https://integrativemodeling.org/2.21.0/doc/manual/installation.html#installation_testing) for more details." + "see the [IMP manual](https://integrativemodeling.org/2.22.0/doc/manual/installation.html#installation_testing) for more details." ] }, { @@ -501,7 +501,7 @@ "repository and a `tools/setup_ci.sh` script. See the\n", "[build.yml](https://github.com/salilab/pmi/blob/develop/.github/workflows/build.yml) and\n", "[setup_ci.sh](https://github.com/salilab/pmi/blob/develop/tools/setup_ci.sh)\n", - "from the [IMP.pmi](https://integrativemodeling.org/2.21.0/doc/ref/namespaceIMP_1_1pmi.html) repository for templates. These two files instruct GitHub Actions to:\n", + "from the [IMP.pmi](https://integrativemodeling.org/2.22.0/doc/ref/namespaceIMP_1_1pmi.html) repository for templates. These two files instruct GitHub Actions to:\n", "\n", "1. Set up an environment on a virtual machine in the cloud in which to build\n", " your module (they install\n", @@ -534,7 +534,7 @@ " * *static* information (that does not change during the course of a simulation): the name of the restraint, and the particles it acts on; and\n", " * *dynamic* information (which generally changes from frame to frame): the total score of the restraint.\n", "\n", - "We can add extra static or dynamic information to the RMF file, by overriding the [get_static_info](https://integrativemodeling.org/2.21.0/doc/ref/classIMP_1_1Restraint.html#af07a7d34ad419288411fd39b97cfd2b2) or [get_dynamic_info](https://integrativemodeling.org/2.21.0/doc/ref/classIMP_1_1Restraint.html#a38bbb37b0e8dc92785b1834233f577c6) methods, respectively. Each returns an [IMP::RestraintInfo](https://integrativemodeling.org/2.21.0/doc/ref/classIMP_1_1RestraintInfo.html) object which is a simple list of key:value pairs. Here we'll add the force constant (which is static information) to the RMF file by declaring the method in the [C++ header file](https://github.com/salilab/imp_coding_tutorial/tree/main/modules/foo/include/MyRestraint2.h), `include/MyRestraint2.h`:\n", + "We can add extra static or dynamic information to the RMF file, by overriding the [get_static_info](https://integrativemodeling.org/2.22.0/doc/ref/classIMP_1_1Restraint.html#af07a7d34ad419288411fd39b97cfd2b2) or [get_dynamic_info](https://integrativemodeling.org/2.22.0/doc/ref/classIMP_1_1Restraint.html#a38bbb37b0e8dc92785b1834233f577c6) methods, respectively. Each returns an [IMP::RestraintInfo](https://integrativemodeling.org/2.22.0/doc/ref/classIMP_1_1RestraintInfo.html) object which is a simple list of key:value pairs. Here we'll add the force constant (which is static information) to the RMF file by declaring the method in the [C++ header file](https://github.com/salilab/imp_coding_tutorial/tree/main/modules/foo/include/MyRestraint2.h), `include/MyRestraint2.h`:\n", "\n", "```cpp\n", "RestraintInfo *get_static_info() const override;\n", @@ -565,7 +565,7 @@ "source": [ "# Serialization support\n", "\n", - "We can further extend our `MyRestraint2` class by adding support for [serialization](https://integrativemodeling.org/2.21.0/doc/manual/serialization.html).\n", + "We can further extend our `MyRestraint2` class by adding support for [serialization](https://integrativemodeling.org/2.22.0/doc/manual/serialization.html).\n", "When an IMP object is serialized its internal state - such as the values of its member variables - is\n", "written to or read in from a file, string or stream. This allows for individual objects or an entire IMP run to be saved and later restored, or to be sent from one machine to another. IMP uses the [cereal library](https://uscilab.github.io/cereal/) to implement serialization in C++. In Python, the objects can be loaded or saved using the [pickle](https://docs.python.org/3/library/pickle.html#module-pickle) module.\n", "\n", diff --git a/support/setup_ci.sh b/support/setup_ci.sh index 34837ce..3568105 100755 --- a/support/setup_ci.sh +++ b/support/setup_ci.sh @@ -18,17 +18,7 @@ if [ ${imp_branch} = "develop" ]; then else IMP_CONDA="imp" fi -if [ ${python_version} = "2.7" ]; then - BOOST="" - pip="pip<=19.3.1" - # Python.h includes crypt.h, which is no longer provided by default - crypt="libxcrypt" -else - BOOST="libboost-devel" - pip="pip" - crypt="" -fi -conda create --yes -q -n python${python_version} -c salilab python=${python_version} ${pip} ${crypt} ${IMP_CONDA} ${BOOST} gxx_linux-64 eigen cereal swig cmake numpy +conda create --yes -q -n python${python_version} -c salilab python=${python_version} pip ${IMP_CONDA} libboost-devel gxx_linux-64 eigen cereal swig cmake numpy eval "$(conda shell.bash hook)" conda activate python${python_version} diff --git a/support/tutorial_tools b/support/tutorial_tools index a9d3f4c..ced187b 160000 --- a/support/tutorial_tools +++ b/support/tutorial_tools @@ -1 +1 @@ -Subproject commit a9d3f4cee4c863cda4dfab97bd086be5cb928b58 +Subproject commit ced187b5723aacc0fb97a5a5a12174e531438743