The proto-Nucleic-Acid Builder (pNAB)
Advanced Manual

Compiling and Testing the Package

Clone the GitHub repository at https://github.com/alenaizan/pnab. And compile the package. All the dependcies can be satisfied through conda.

conda install -c conda-forge python numpy cmake openbabel eigen pybind11 pyyaml nglview

The C++ compiler in linux can also be installed using Conda.

conda install -c conda-forge gcc_linux-64 gxx_linux-64

The code has been tested using the gcc 7.3 and 9.3 compilers in Linux, clang 8.0 and 10.0 compilers in Mac, and Visual Studio 2015/

The code uses the pytest package for testing. To test that the code works, first install pytest:

conda install pytest

Then, execute:

python -c "import pnab; pnab.test()"

Accessing the C++ Classes through Python

All the code for manipulating the molecule and computing the energies is written in C++. The main C++ classes that are used for defining the options can be accessed in python. It is sufficient to write an input file and call the program using this syntax:

import pnab
run = pnab.pNAB('RNA.yaml')
run.run()

The advantage of this approach is that it performs basic validation of the user defined options. Additionally, for runs with multiple helical configurations, the independent configurations can be run in parallel using the multiprocessing library. This is managed internally by the python program. However, if the user wants to access the C++ classes directly through python, then this can be performed as follows:

from pnab import bind
backbone = bind.Backbone()
backbone.file_path = 'rna_bb.pdb'
backbone.interconnects = [10, 1]
backbone.linker = [13, 14]
base = bind.Base()
base.file_path = 'adenine.pdb'
base.code = 'A'
base.linker = [5, 11]
base.name = 'Adenine'
base.pair_name = 'Uracil'
bases = [base]
hp = bind.HelicalParameters()
hp.h_twist = 32.39
hp.h_rise = 2.53
hp.inclination = 22.9
hp.tip = 0.08
hp.x_displacement = -4.54
hp.y_displacement = -0.02
rp = bind.RuntimeParameters()
rp.search_algorithm = 'weighted random search'
rp.num_steps = 1000000
rp.ff_type = 'GAFF'
rp.energy_filter = [10000.0, 10000.0, 10000.0, 10000.0]
rp.max_distance = 0.2
rp.strand = ['Adenine']*5
output = bind.run(rp, backbone, bases, hp, 'test')
print(output)

The output from the run is a string containing the data in CSV format.

The C++ classes exposed to python are only for defining options and running the program. The other classes can be accessed through the C++ code.