Giter VIP home page Giter VIP logo

primaryodors / primarydock Goto Github PK

View Code? Open in Web Editor NEW
6.0 3.0 3.0 184.34 MB

PrimaryOdors.org molecular docker.

License: Other

C++ 70.83% C 0.91% HTML 6.48% Makefile 0.66% Shell 1.90% CMake 0.16% PHP 18.59% CSS 0.41% JavaScript 0.06%
gpcr molecular-docking molecular-viewer molecular-visualization olfaction protein-function-prediction protein-ligand-interactions side-chain-orientation path-based-docking side-chain-flexion

primarydock's People

Contributors

electronicsbyjulie avatar objarni avatar primaryodors avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

primarydock's Issues

Display of histidine hydrogen flip in viewer.

In the code that flexes receptor sidechains. Histidine's 5-membered ring contains two nitrogens, one with a hydrogen and one without, and this hydrogen can jump from one nitrogen to the other. Technically it can pull a hydrogen off a ligand or add one, like many enzymes do, and it can cause a nearby cysteine to form a disulfide bond with a thiol ligand, so that enzymatic action might be something to explore simulating eventually.

Make sure not to hard code this to histidine, but rather write the code to look for the structural motif (in this case N=C-NH but also do not limit it to just that) capable of the hydrogen flip. All amino acid properties and methods must be fully functional for hypothetical alien amino acids (and I will be using some for testing).

Collisions in paths.

Sometimes, the starting position of a dock path gives a nice non-colliding pose, and then subsequently along the path the ligand gets ensnared in a side chain, producing an unacceptable pose and a negative binding.

When this happens, the node should be omitted, as should all subsequent nodes of the same pose - simply don't compute them. Reason being if a ligand in a given pose cannot pass through a bottleneck in the binding pocket, then that pose will not make it deeper into the pocket.

Incorrect peptide structure from protein_test.

./protest TTTTTTTTTTTTTTTTTTTTTTT

The result is a coiled strand where the atoms are too close together. This conformation would be impossible in a real protein.

polythreonine_wrong

There is a function call in protest.cpp to straighten the chain, but every iteration shows zero as the molecular energy, so no bonds are rotated.

Iteration 0
0 v. 0
0 vs. 0
Iteration 1
0 v. 0
0 vs. 0
Iteration 2
0 v. 0
0 vs. 0
Iteration 3
0 v. 0
0 vs. 0
Iteration 4
0 v. 0
0 vs. 0
Iteration 5
0 v. 0
0 vs. 0
...

Offer the option of kcal/mol output.

Currently the program only outputs energies in kJ/mol, but some users might still want kcal/mol. Make it an option in the podock.config file.

Multiple "best bind" coordinations.

Currently, when putrescine or cadaverine are docked inside TAAR6 or TAAR8, only one of the receptor's two amino-binding ASP residues is coordinated to the ligand's amino groups. One of the ASPs is located on TMR3, and the other on TMR5. Since the TMR3:ASP is the earlier one in the sequence, it is always being given priority and becoming the "best bind" alignment site.

Allow up to three "best bind" coordinations: bb0, bb1, and bb2. Let each one correspond to a heavy atom of the ligand, and its bound hydrogen if it has one. Let each one correspond to a feature in the binding pocket, such as a residue sidechain or a metal ion. The strongest potential binding would be bb0, followed by bb1 and then bb2.

Coordinate bb0 first. This is the existing simple whole-molecule rotation to align its bb0 with alignment feature zero.

Then coordinate bb1. Start by taking the normal of the plane defined by LIG:bb0, LIG:bb1, and Prot:bb1. Rotate the ligand about this normal, with ligand bb0 as the center of rotation, to align LIG:bb1 with Prot:bb1.

Then use the imaginary line of LIG:bb0-LIG:bb1 as the axis of rotation to align LIG:bb2 as close to Prot:bb2 as possible.

SMILES parse issue: numbers only work with already-bonded atoms.

For example:

$ ./mol_assem_test C1.C2.C12

The resulting .sdf has all three carbons at [0,0,0] and all hydrogens' xyz coordinates as nan.

The following works more as anticipated, except for the ring being distorted due to an unrelated issue:

$ ./mol_assem_test C1CC1

Conjugated atoms to remain coplanar.

A "single" bond of a conjugated system, including a conjugated substitution of an aromatic ring, has partial double bond quality and should not be free to rotate. Examples of molecules showing this phenomenon include polyenes, cinnamaldehyde, and benzamidine. The phenomenon also extends to compounds like aniline, where the two hydrogens of the amino moiety have partial aromatic character and lie between the ring plane and their expected tetrahedral angles. With the exception of some of the hydrogens, all of these compounds should always remain coplanar.

Further info:

https://pubs.rsc.org/en/content/articlehtml/2015/cp/c5cp02582f

Potential bug in get_sum_cardinality

This algorithm:

int Atom::get_sum_cardinality()
{
    if (!bonded_to) return 0;
    int i, retval=0;
    for (i=0; i<geometry; i++) if (bonded_to[i].btom) retval += bonded_to[i].cardinality;
    return retval;
}

.. returns an integer. However, cardinality is a float, and by its declaration says can be "1.5". This means retval will get +1 (implicit rounding to int --> becomes 1).

Is this intentional?

Compiler compatibility/std::vector/performance testing.

I'm having trouble running make on my Mac machine, and after squashing a lot of small issues, I started reading on the va_args behaviour/specification in the standard, and while googling found this interesting article:

https://www.linkedin.com/pulse/modern-c-variadic-functions-how-shoot-yourself-foot-avoid-zinin/

(The actual build error was squashed by adding -Wno-non-pod-varargs to CFLAGS in makefile, but it feels wrong to sweep a semantic issue/concern like this under the carpet)

Is this function essential to the code base? I notice there are at least 1 more version of it?

BTW - My "long-term" intention with getting up regression/automatic tests is to enable refactoring to std::vector instead of so much pointers/arrays, i.e. using modern C++ constructs instead (it was one of the first things I read about podock, and felt I could contribute to). It would mean passing a variable number of objects/values to a function would be much simplified - just pass a (reference) to a vector object - so while I like va_args it seems a bit over-the-top.

Allow SMILES instead of SDF for the ligand in the config file.

Right now the app requires a SDF input file to contian the ligand.

Allow the user to instead specify a name and a SMILES string, for example:

LIG NAME dihydrocarvone SMILES C[C@@H]1CC[C@H](CC1=O)C(=C)C

Note issues #4, #5, and #12 should be resolved before this feature is brought live.

-fpermissive gives weird semantics

I noticed the flag permissive is used in the makefile.

This means the compiler allows strange things like disregarding const qualifiers, basically invalidating the use of const at all (since you cannot trust the 'I won't change this state'-promise of const).

I'm working on removing the flag by adding / removing const in different places.

Note: You may see me use the syntax char const * order instead of const char *. This is known as the right-to-left-rule, and means you can actually read and understand the type better. The former is read (from right to left): "pointer to constant character", which is precisely what it is (the letter cannot be changed / is constant), while the latter, while meaning the same to the compiler/language, is utterly non-readable for a human. (you just have to know what it means through years of programming in C++).

(Semantically, const 'talks about what is left of it'. And then there is this weird exception, if there is nothing left of it, it talks about what is right of it! See e.g this thread on the topic of understanding complicated const type declarations https://stackoverflow.com/questions/7526152/easy-rule-to-read-complicated-const-declarations)

Spike performance tests.

Creating this for the conversation from #49 (note spike performance is not present in the macbuild branch, only the main branch, so if I merge macbuild then it marks closed the separate spike performance convo).

There is now a spike performance test here: https://github.com/primaryodors/podock/tree/main/src/spikes/vector_vs_array

Any performance hit is potentially bad since docking is a CPU intensive calculation. If it's a small hit, then the benefits can outweigh the lost performance. If element access/iterations are not slowed then it'll be perfectly fine for docking.

Unfortunately the performance hit is pretty severe, 211% greater on my machine. :( For the volume of processing my purposes require, a threefold difference is just not usable.

Config file is required to have an empty line at the end.

Otherwise podock thinks the last line is missing its last parameter and throws a segfault.

This is a tricky one. The segfault is happening in podock.cpp (on line 117 if the last config line is an ITER parameter) when chop_spaced_fields() has been called and its return value assigned to the fields[] array, and the code is trying to get the value of fields[1]. That should be the number from the ITER param, but instead it is a null or invalid pointer that causes the segfault.

The actual problem must be happening in the chop_spaced_fields() function in point.cpp, specifically the lack of a terminal newline character preventing the code from parsing the final space-separated value, but so far my attempts have not solved the issue.

Figure out rotating bonds in rings.

Mostly applicable to larger rings, i.e. more than 6 members. If rotating a bond, iterate through the ring a few times rotating other bonds to bring the atoms as close to their proper distances and geometries as possible. This may mean partially undoing the initial bond rotation.

This kind of functionality is important for molecules like the macrocyclic musks that can bend to conform to a protein's active site.

To avoid recursion, write a separate private rotation function that does the circular iterating.

If the algorithm is correct, it will generate chair and boat forms for cyclohexane, as well as the two twisted forms, all on its own.

One thing this will affect is the ring of proline doesn't actually fully preclude the N-CA bond from rotating, merely limits its rotation severely. Backbone rotation functions currently prohibit rotating this bond, but that will have to change once the main issue of ring flexibility is resolved.

I believe other dockers solve the problem not with bond rotations, but by settling atoms into their lowest energy level configuration. For our purposes, that would make a mess of the atom geometries and necessitate relocating large numbers of atoms, potentially even up to the entire remainder of a protein strand.

Change "collision" to "clash" in code.

In standard chemistry computing terminology, a clash is when two or more atoms are too close together.

More specifically, each atom behaves like a sphere, and for the most part, no two atoms' spheres may intersect. The radius of this sphere is the van der Waals radius. The sum of vdW radii is the closest the atoms are normally allowed to be, the smallest possible distance between their centers.

An exception is if two atoms are bonded together; instead of the sum of vdW radii, they will have a bond radius that is smaller than the sum vdW. Atoms that are bonded together cannot be said to clash with each other.

Another exception happens when atoms of a single molecule are unavoidably close enough to clash (this is very common actually) or when two molecules are pulled together by attractive forces strongly enough that a small amount of clash is allowed. So clashes do occur in real life molecules.

In the code, the phenomenon is called a "collision". It should be renamed to "clash" in order to match current scientific terminology.

mol_assem_report varies with each run

It seems there is some indeterministic behaviour w.r.t the mol_assem_test:

diff --git a/mol_assem_test.approved.txt b/mol_assem_test.approved.txt
index aaeeed8..6fdcda4 100644
--- a/mol_assem_test.approved.txt
+++ b/mol_assem_test.approved.txt
@@ -1,8 +1,8 @@
 Created empty molecule named Test.
 Added a carbon atom. Its location is [0.000000,0.000000,0.000000].
 Added another carbon atom. Its location is [0.000000,1.540000,-0.000000].
-Added an oxygen atom. Its location is [-0.565498,2.016666,-1.223888].
-Internal collisions: 0.417545 cu.A.
+Added an oxygen atom. Its location is [-1.215392,2.016667,0.583532].
+Internal collisions: 0.0106636 cu.A.
 Minimizing internal collisions...
-Internal collisions: 3.27826e-07 cu.A.
+Internal collisions: 6.14673e-08 cu.A.
 Saved test.sdf

This is a typical diff after running make reports (which regenerates all tests and overwrites the *.approved.txt files).

Is there some rand() calls hidden underneath here, or am I missing something?

amino_test terminates prematurely

The amino_test seems broken. I get only this similar to this output in every .approved.txt file:

Covalent bond parameters not found for C to N cardinality 1. Please check bindings.dat.

Perhaps there is a missing new file bindings.dat?

This is the log when running make amino_report:

olof@pop-os:~/repos/github/podock$ make amino_report
bash src/amino_tests.bash ARNDCEQGHILKMFPUSTWYV
Running amino A test
terminate called after throwing an instance of 'int'
Running amino R test
terminate called after throwing an instance of 'int'
Running amino N test
terminate called after throwing an instance of 'int'
Running amino D test
terminate called after throwing an instance of 'int'
Running amino C test
terminate called after throwing an instance of 'int'
Running amino E test
terminate called after throwing an instance of 'int'
Running amino Q test
terminate called after throwing an instance of 'int'
Running amino G test
terminate called after throwing an instance of 'int'
Running amino H test
terminate called after throwing an instance of 'int'
Running amino I test
terminate called after throwing an instance of 'int'
Running amino L test
terminate called after throwing an instance of 'int'
Running amino K test
terminate called after throwing an instance of 'int'
Running amino M test
terminate called after throwing an instance of 'int'
Running amino F test
terminate called after throwing an instance of 'int'
Running amino P test
terminate called after throwing an instance of 'int'
Running amino U test
terminate called after throwing an instance of 'int'
Running amino S test
terminate called after throwing an instance of 'int'
Running amino T test
terminate called after throwing an instance of 'int'
Running amino W test
terminate called after throwing an instance of 'int'
Running amino Y test
terminate called after throwing an instance of 'int'
Running amino V test
terminate called after throwing an instance of 'int'

Ionic interactions not working.

Using protonated cadaverine with the formula [NH3+]CCCCC[NH3+] and TAAR8.

The result is zero ionic bonding.

Total ionic: -0
Total H-bond: -18.3215
Total pi stack: -0
Total polar-pi and cation-pi: -0.427101
Total metal coordination: -0
Total van der Waals: -11.236
Total: -21.4182

Segfault in protest_report

REPORT="protest.approved.txt"
./protest ARNDCEQGHILKMFPUSTWYV >"protest.approved.txt"
Segmentation fault (core dumped)

This is when invocing make protest_report.

It did work some day ago. The sequence run is more complicated than it used to be, perhaps this is why it is now crashing?

Root directory is getting crowded - ideas for subdirectories

There are now almost 100 files in the root folder on my machine. I would like to move .approved.txt files to a subfolder "approved_files", as a start. There might be more sub folders that make sense, e.g. separating the 'basic code files' (point, atom etc) from the more application-level files (e.g podock) or the _test files.

Thoughts?

When generating peptides from sequence, certain rings fail.

Tryptophan and proline for sure fail. Histidine, phenylalanine, and tyrosine appear to work okay.

Example command that demonstrates the unwanted behavior:

./protest TWERP

The strand is broken in two, hydrogens are strewn asunder, and tryptophan's cycles are both broken.

In the case of tryptophan, it creates the 5-membered ring okay, so you just have to identify the two shared carbons, average them, step to an imaginary point at the right distance in the direction opposite the center of the 5-membered ring, use that point as the 6-membered ring center, and place the remaining 4 carbons in a semicircle. It sounds complex, but all the 3D functions already exist that are required for writing this feature.

SMILES: add support for chirality specifiers and E-Z specifiers.

Chirality is specified using @ or @@ inside a bracketed expression. For example, a SMILES string for l-alanine would be:

N[C@@H](C)C(=O)O

Whereas d-alanine has only one @ and is otherwise the same.

E-Z isomerism is self explanatory; CC/C=C\CCO or CC\C=C/CCO is cis-3-hexen-1-ol or leaf alcohol; the trans isomer could be written either CC/C=C/CCO or CC\C=C\CCO.

Where are file formats .sdf and .pdb described?

When running podock tests', there are output files '.pdb' and '.sdf' created at various occasions.

Is there any documentation for these file formats? I couldn't find any browsing FAQ and some more pages on primaryodors.org.

(I did find the 3d visualization of a molecule though, really nice to see what this software is used for in the end!! :D )

Torsion angle: omega.

This is the angle of the peptide bond, normally stuck in the trans position but typically distorted by steric effects from other atoms in the strand.

From https://en.wikipedia.org/wiki/Pi_helix:

The general formula for the rotation angle Ω per residue of any polypeptide helix with trans isomers is given by the equation
image

So the function in the Protein class that creates helices should make use of the above equation to rotate the omega bond according to the specified phi and psi angles. This can be done by applying a rotation to the whole amino acids, about the axis of the omega bond, without having to rotate any bonds within any amino acid.

Lots of unused variables

Adding -Wall gives a lot of valuable feedback about the code base health. There are a lot of things that are not being used, which could clarify the code based a lot (I hope).

Would you mind if I start removing unused things? Or is this software compiled/used in other things, that would not be detected by the makefile?

Sample output from make with -Wall:

src/classes/atom.cpp: In constructor ‘Atom::Atom(FILE*)’:
src/classes/atom.cpp:261:9: warning: variable ‘resno’ set but not used [-Wunused-but-set-variable]
  261 |     int resno=0;
      |         ^~~~~
src/classes/atom.cpp: In member function ‘SCoord* Atom::get_basic_geometry()’:
src/classes/atom.cpp:1046:12: warning: unused variable ‘j’ [-Wunused-variable]
 1046 |     int i, j;
      |            ^
src/classes/atom.cpp:1047:11: warning: unused variable ‘x’ [-Wunused-variable]
 1047 |     float x, y, z;
      |           ^
src/classes/atom.cpp:1047:14: warning: unused variable ‘y’ [-Wunused-variable]
 1047 |     float x, y, z;
      |              ^
src/classes/atom.cpp:1047:17: warning: unused variable ‘z’ [-Wunused-variable]
 1047 |     float x, y, z;
      |                 ^
src/classes/atom.cpp: In member function ‘SCoord* Atom::get_geometry_aligned_to_bonds()’:
src/classes/atom.cpp:1365:15: warning: unused variable ‘angle’ [-Wunused-variable]
 1365 |         float angle;
      |               ^~~~~
src/classes/atom.cpp:1282:10: warning: unused variable ‘doswings’ [-Wunused-variable]
 1282 |     bool doswings = false;
      |          ^~~~~~~~
g++ -c src/classes/intera.cpp -o obj/intera.o -g -Wall -fextended-identifiers -std=c++14
src/classes/intera.cpp: In static member function ‘static float InteratomicForce::total_binding(Atom*, Atom*)’:
src/classes/intera.cpp:476:13: warning: unused variable ‘abc’ [-Wunused-variable]
  476 |         int abc = a->get_bonded_atoms_count();
      |             ^~~
src/classes/intera.cpp:477:13: warning: unused variable ‘bbc’ [-Wunused-variable]
  477 |         int bbc = b->get_bonded_atoms_count();
      |             ^~~
src/classes/intera.cpp: In static member function ‘static float InteratomicForce::covalent_bond_radius(Atom*, Atom*, int)’:
src/classes/intera.cpp:679:24: warning: unused variable ‘retval’ [-Wunused-variable]
  679 |     InteratomicForce** retval = new InteratomicForce*[16] {};
      |                        ^~~~~~
src/classes/intera.cpp:681:12: warning: unused variable ‘j’ [-Wunused-variable]
  681 |     int i, j=0;
      |            ^
src/classes/intera.cpp: In static member function ‘static float InteratomicForce::coordinate_bond_radius(Atom*, Atom*, intera_type)’:
src/classes/intera.cpp:714:24: warning: unused variable ‘retval’ [-Wunused-variable]
  714 |     InteratomicForce** retval = new InteratomicForce*[16] {};
      |                        ^~~~~~
src/classes/intera.cpp:716:12: warning: unused variable ‘j’ [-Wunused-variable]
  716 |     int i, j=0;
      |            ^
In file included from src/classes/intera.h:2,
                 from src/classes/intera.cpp:9:
src/classes/atom.h: At global scope:
src/classes/atom.h:173:13: warning: ‘read_elem_syms’ defined but not used [-Wunused-variable]
  173 | static bool read_elem_syms = false;
      |             ^~~~~~~~~~~~~~
g++ -c src/classes/molecule.cpp -o obj/molecule.o -g -Wall -fextended-identifiers -std=c++14
src/classes/molecule.cpp: In member function ‘int Molecule::from_sdf(const char*)’:
src/classes/molecule.cpp:361:13: warning: variable ‘nb’ set but not used [-Wunused-but-set-variable]
  361 |     int na, nb;
      |             ^~
src/classes/molecule.cpp: In member function ‘int Molecule::identify_rings()’:
src/classes/molecule.cpp:903:50: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
  903 |                                     for (p=0; ra = ring_atoms[ringcount][p]; p++)
      |                                               ~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
src/classes/molecule.cpp:943:50: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
  943 |                                     for (p=0; ra = ring_atoms[ringcount][p]; p++)
      |                                               ~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
src/classes/molecule.cpp:946:45: warning: unused variable ‘card’ [-Wunused-variable]
  946 |                                         int card = ra->is_bonded_to(rb);
      |                                             ^~~~
src/classes/molecule.cpp:778:10: warning: variable ‘is_ring’ set but not used [-Wunused-but-set-variable]
  778 |     bool is_ring[256];
      |          ^~~~~~~
src/classes/molecule.cpp:863:1: warning: label ‘_done_l’ defined but not used [-Wunused-label]
  863 | _done_l:
      | ^~~~~~~
src/classes/molecule.cpp: In member function ‘void Molecule::identify_acidbase()’:
src/classes/molecule.cpp:1126:19: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
 1126 |             if (c = atoms[i]->is_bonded_to("C"))
      |                 ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/classes/molecule.cpp: In member function ‘float Molecule::get_internal_clashes()’:
src/classes/molecule.cpp:1337:11: warning: unused variable ‘a’ [-Wunused-variable]
 1337 |     Atom* a, *b;
      |           ^
src/classes/molecule.cpp:1337:15: warning: unused variable ‘b’ [-Wunused-variable]
 1337 |     Atom* a, *b;
      |               ^
src/classes/molecule.cpp: In member function ‘float Molecule::get_intermol_clashes(Molecule**)’:
src/classes/molecule.cpp:1381:11: warning: unused variable ‘a’ [-Wunused-variable]
 1381 |     Atom* a, *b;
      |           ^
src/classes/molecule.cpp:1381:15: warning: unused variable ‘b’ [-Wunused-variable]
 1381 |     Atom* a, *b;
      |               ^
src/classes/molecule.cpp: In member function ‘void Molecule::minimize_internal_clashes()’:
src/classes/molecule.cpp:1653:12: warning: unused variable ‘j’ [-Wunused-variable]
 1653 |     int i, j, iter;
      |            ^
src/classes/molecule.cpp: In member function ‘void Molecule::intermol_conform(Molecule**, int, Molecule**)’:
src/classes/molecule.cpp:1794:23: warning: unused variable ‘newy’ [-Wunused-variable]
 1794 |                 float newy = get_barycenter().y;
      |                       ^~~~
src/classes/molecule.cpp:1781:19: warning: unused variable ‘oldy’ [-Wunused-variable]
 1781 |             float oldy = get_barycenter().y;
      |                   ^~~~
src/classes/molecule.cpp:1734:15: warning: unused variable ‘i’ [-Wunused-variable]
 1734 |     int iter, i, j;
      |               ^
src/classes/molecule.cpp:1734:18: warning: unused variable ‘j’ [-Wunused-variable]
 1734 |     int iter, i, j;
      |                  ^
src/classes/molecule.cpp: In member function ‘void Molecule::intermol_conform_norecen(Molecule**, int, Molecule**, float)’:
src/classes/molecule.cpp:1896:15: warning: unused variable ‘i’ [-Wunused-variable]
 1896 |     int iter, i, j;
      |               ^
src/classes/molecule.cpp:1896:18: warning: unused variable ‘j’ [-Wunused-variable]
 1896 |     int iter, i, j;
      |                  ^
src/classes/molecule.cpp: In member function ‘void Molecule::intermol_conform_flexonly(Molecule**, int, Molecule**, float)’:
src/classes/molecule.cpp:1982:15: warning: unused variable ‘i’ [-Wunused-variable]
 1982 |     int iter, i, j, k, l;
      |               ^
src/classes/molecule.cpp:1982:24: warning: unused variable ‘l’ [-Wunused-variable]
 1982 |     int iter, i, j, k, l;
      |                        ^
src/classes/molecule.cpp: In member function ‘bool Molecule::from_smiles(const char*, Atom*)’:
src/classes/molecule.cpp:2588:49: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
 2588 |                 preva->EZ_flip = EZgiven[dbi-1] = sgn(EZ) != sgn(lastEZ);
      |                                  ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
src/classes/molecule.cpp:2461:11: warning: unused variable ‘stack’ [-Wunused-variable]
 2461 |     Atom* stack[256];
      |           ^~~~~
src/classes/molecule.cpp:2484:11: warning: variable ‘EZatom0’ set but not used [-Wunused-but-set-variable]
 2484 |     Atom* EZatom0[numdb+4];
      |           ^~~~~~~
src/classes/molecule.cpp:2485:11: warning: variable ‘EZatom1’ set but not used [-Wunused-but-set-variable]
 2485 |     Atom* EZatom1[numdb+4];
      |           ^~~~~~~
src/classes/molecule.cpp: In member function ‘float Molecule::close_loop(Atom**, float)’:
src/classes/molecule.cpp:3040:11: warning: unused variable ‘oclash’ [-Wunused-variable]
 3040 |     float oclash = iclash;
      |           ^~~~~~
In file included from src/classes/molecule.h:2,
                 from src/classes/molecule.cpp:11:
src/classes/intera.h: At global scope:
src/classes/intera.h:75:13: warning: ‘reading_forces’ defined but not used [-Wunused-variable]
   75 | static bool reading_forces = false;
      |             ^~~~~~~~~~~~~~
src/classes/intera.h:74:13: warning: ‘read_forces_dat’ defined but not used [-Wunused-variable]
   74 | static bool read_forces_dat = false;
      |             ^~~~~~~~~~~~~~~
src/classes/intera.h:73:27: warning: ‘forces_by_Z’ defined but not used [-Wunused-variable]
   73 | static InteratomicForce** forces_by_Z[36][36] = {};    // Good for H thru Br. Includes BCNOFPSKNaClBrMgCaFeCuZn.
      |                           ^~~~~~~~~~~
src/classes/intera.h:72:26: warning: ‘all_forces’ defined but not used [-Wunused-variable]
   72 | static InteratomicForce* all_forces[65536];
      |                          ^~~~~~~~~~
In file included from src/classes/intera.h:2,
                 from src/classes/molecule.h:2,
                 from src/classes/molecule.cpp:11:
src/classes/atom.h:173:13: warning: ‘read_elem_syms’ defined but not used [-Wunused-variable]
  173 | static bool read_elem_syms = false;
      |             ^~~~~~~~~~~~~~
g++ -c src/classes/aminoacid.cpp -o obj/aminoacid.o -g -Wall -fextended-identifiers -std=c++14
src/classes/aminoacid.cpp: In member function ‘void AminoAcid::load_aa_defs()’:
src/classes/aminoacid.cpp:462:16: warning: unused variable ‘j’ [-Wunused-variable]
  462 |         int i, j;
      |                ^
src/classes/aminoacid.cpp: In function ‘std::ostream& operator<<(std::ostream&, const AminoAcid&)’:
src/classes/aminoacid.cpp:658:10: warning: the compiler can assume that the address of ‘aa’ will never be NULL [-Waddress]
  658 |     if (!&aa) return os;
      |          ^~~
src/classes/aminoacid.cpp: In member function ‘float AminoAcid::get_intermol_binding(AminoAcid**, bool)’:
src/classes/aminoacid.cpp:1185:27: warning: unused variable ‘r’ [-Wunused-variable]
 1185 |                     float r = neighbs[i]->atoms[k]->get_location().get_3d_distance(&aloc);
      |                           ^
In file included from src/classes/molecule.h:2,
                 from src/classes/aminoacid.cpp:10:
src/classes/intera.h: At global scope:
src/classes/intera.h:75:13: warning: ‘reading_forces’ defined but not used [-Wunused-variable]
   75 | static bool reading_forces = false;
      |             ^~~~~~~~~~~~~~
src/classes/intera.h:74:13: warning: ‘read_forces_dat’ defined but not used [-Wunused-variable]
   74 | static bool read_forces_dat = false;
      |             ^~~~~~~~~~~~~~~
src/classes/intera.h:73:27: warning: ‘forces_by_Z’ defined but not used [-Wunused-variable]
   73 | static InteratomicForce** forces_by_Z[36][36] = {};    // Good for H thru Br. Includes BCNOFPSKNaClBrMgCaFeCuZn.
      |                           ^~~~~~~~~~~
src/classes/intera.h:72:26: warning: ‘all_forces’ defined but not used [-Wunused-variable]
   72 | static InteratomicForce* all_forces[65536];
      |                          ^~~~~~~~~~
In file included from src/classes/intera.h:2,
                 from src/classes/molecule.h:2,
                 from src/classes/aminoacid.cpp:10:
src/classes/atom.h:173:13: warning: ‘read_elem_syms’ defined but not used [-Wunused-variable]
  173 | static bool read_elem_syms = false;
      |             ^~~~~~~~~~~~~~
src/classes/aminoacid.cpp: In function ‘std::ostream& operator<<(std::ostream&, const AminoAcid&)’:
src/classes/aminoacid.cpp:658:5: warning: ‘nonnull’ argument ‘aa’ compared to NULL [-Wnonnull-compare]
  658 |     if (!&aa) return os;
      |     ^~
g++ -c src/classes/protein.cpp -o obj/protein.o -g -Wall -fextended-identifiers -std=c++14
src/classes/protein.cpp: In member function ‘AminoAcid** Protein::get_residues_can_clash(int)’:
src/classes/protein.cpp:312:12: warning: unused variable ‘j’ [-Wunused-variable]
  312 |     int i, j;
      |            ^
src/classes/protein.cpp: In member function ‘Molecule* Protein::metals_as_molecule()’:
src/classes/protein.cpp:472:22: warning: unused variable ‘l’ [-Wunused-variable]
  472 |         int i, j, k, l, m, n;
      |                      ^
src/classes/protein.cpp:472:25: warning: unused variable ‘m’ [-Wunused-variable]
  472 |         int i, j, k, l, m, n;
      |                         ^
src/classes/protein.cpp:472:28: warning: unused variable ‘n’ [-Wunused-variable]
  472 |         int i, j, k, l, m, n;
      |                            ^
src/classes/protein.cpp: In member function ‘void Protein::rotate_backbone(int, bb_rot_dir, float)’:
src/classes/protein.cpp:514:35: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
  514 |         for (i=resno+inc; movable = get_residue(i); i+=inc)
      |                           ~~~~~~~~^~~~~~~~~~~~~~~~
src/classes/protein.cpp: In member function ‘void Protein::rotate_backbone_partial(int, int, bb_rot_dir, float)’:
src/classes/protein.cpp:542:38: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
  542 |         for (i=startres+inc; movable = get_residue(i); i+=inc)
      |                              ~~~~~~~~^~~~~~~~~~~~~~~~
src/classes/protein.cpp: In member function ‘void Protein::conform_backbone(int, int, Atom*, Point, Atom*, Point, int, bool)’:
src/classes/protein.cpp:576:17: warning: unused variable ‘j’ [-Wunused-variable]
  576 |     int res, i, j, iter;
      |                 ^
src/classes/protein.cpp: In member function ‘void Protein::make_helix(int, int, int, float, float)’:
src/classes/protein.cpp:739:39: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
  739 |                 for (i=res+1; movable = get_residue(i); i+=inc)
      |                               ~~~~~~~~^~~~~~~~~~~~~~~~
src/classes/protein.cpp:763:37: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
  763 |             for (i=res+inc; movable = get_residue(i); i+=inc)
      |                             ~~~~~~~~^~~~~~~~~~~~~~~~
src/classes/protein.cpp:777:37: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
  777 |             for (i=res+inc; movable = get_residue(i); i+=inc)
      |                             ~~~~~~~~^~~~~~~~~~~~~~~~
src/classes/protein.cpp:722:20: warning: unused variable ‘iter’ [-Wunused-variable]
  722 |     int res, i, j, iter;
      |                    ^~~~
src/classes/protein.cpp: In member function ‘float Protein::orient_helix(int, int, int, float, int)’:
src/classes/protein.cpp:1103:16: warning: unused variable ‘aa’ [-Wunused-variable]
 1103 |     AminoAcid* aa = get_residue(startres-1);
      |                ^~
In file included from src/classes/molecule.h:2,
                 from src/classes/aminoacid.h:4,
                 from src/classes/protein.h:2,
                 from src/classes/protein.cpp:7:
src/classes/intera.h: At global scope:
src/classes/intera.h:75:13: warning: ‘reading_forces’ defined but not used [-Wunused-variable]
   75 | static bool reading_forces = false;
      |             ^~~~~~~~~~~~~~
src/classes/intera.h:74:13: warning: ‘read_forces_dat’ defined but not used [-Wunused-variable]
   74 | static bool read_forces_dat = false;
      |             ^~~~~~~~~~~~~~~
src/classes/intera.h:73:27: warning: ‘forces_by_Z’ defined but not used [-Wunused-variable]
   73 | static InteratomicForce** forces_by_Z[36][36] = {};    // Good for H thru Br. Includes BCNOFPSKNaClBrMgCaFeCuZn.
      |                           ^~~~~~~~~~~
src/classes/intera.h:72:26: warning: ‘all_forces’ defined but not used [-Wunused-variable]
   72 | static InteratomicForce* all_forces[65536];
      |                          ^~~~~~~~~~
In file included from src/classes/intera.h:2,
                 from src/classes/molecule.h:2,
                 from src/classes/aminoacid.h:4,
                 from src/classes/protein.h:2,
                 from src/classes/protein.cpp:7:
src/classes/atom.h:173:13: warning: ‘read_elem_syms’ defined but not used [-Wunused-variable]
  173 | static bool read_elem_syms = false;
      |             ^~~~~~~~~~~~~~
g++ src/point_test.cpp obj/point.o -o test/point_test -g -Wall -fextended-identifiers -std=c++14
g++ src/atom_test.cpp obj/atom.o obj/point.o -o test/atom_test -g -Wall -fextended-identifiers -std=c++14
In file included from src/atom_test.cpp:4:
src/classes/atom.h:173:13: warning: ‘read_elem_syms’ defined but not used [-Wunused-variable]
  173 | static bool read_elem_syms = false;
      |             ^~~~~~~~~~~~~~
g++ src/molecule_test.cpp obj/atom.o obj/point.o obj/intera.o obj/molecule.o -o test/molecule_test -g -Wall -fextended-identifiers -std=c++14
In file included from src/classes/molecule.h:2,
                 from src/molecule_test.cpp:7:
src/classes/intera.h:75:13: warning: ‘reading_forces’ defined but not used [-Wunused-variable]
   75 | static bool reading_forces = false;
      |             ^~~~~~~~~~~~~~
src/classes/intera.h:74:13: warning: ‘read_forces_dat’ defined but not used [-Wunused-variable]
   74 | static bool read_forces_dat = false;
      |             ^~~~~~~~~~~~~~~
src/classes/intera.h:73:27: warning: ‘forces_by_Z’ defined but not used [-Wunused-variable]
   73 | static InteratomicForce** forces_by_Z[36][36] = {};    // Good for H thru Br. Includes BCNOFPSKNaClBrMgCaFeCuZn.
      |                           ^~~~~~~~~~~
src/classes/intera.h:72:26: warning: ‘all_forces’ defined but not used [-Wunused-variable]
   72 | static InteratomicForce* all_forces[65536];
      |                          ^~~~~~~~~~
In file included from src/classes/intera.h:2,
                 from src/classes/molecule.h:2,
                 from src/molecule_test.cpp:7:
src/classes/atom.h:173:13: warning: ‘read_elem_syms’ defined but not used [-Wunused-variable]
  173 | static bool read_elem_syms = false;
      |             ^~~~~~~~~~~~~~
g++ src/mol_assem_test.cpp obj/atom.o obj/point.o obj/intera.o obj/molecule.o -o test/mol_assem_test -g -Wall -fextended-identifiers -std=c++14
In file included from src/classes/molecule.h:2,
                 from src/mol_assem_test.cpp:7:
src/classes/intera.h:75:13: warning: ‘reading_forces’ defined but not used [-Wunused-variable]
   75 | static bool reading_forces = false;
      |             ^~~~~~~~~~~~~~
src/classes/intera.h:74:13: warning: ‘read_forces_dat’ defined but not used [-Wunused-variable]
   74 | static bool read_forces_dat = false;
      |             ^~~~~~~~~~~~~~~
src/classes/intera.h:73:27: warning: ‘forces_by_Z’ defined but not used [-Wunused-variable]
   73 | static InteratomicForce** forces_by_Z[36][36] = {};    // Good for H thru Br. Includes BCNOFPSKNaClBrMgCaFeCuZn.
      |                           ^~~~~~~~~~~
src/classes/intera.h:72:26: warning: ‘all_forces’ defined but not used [-Wunused-variable]
   72 | static InteratomicForce* all_forces[65536];
      |                          ^~~~~~~~~~
In file included from src/classes/intera.h:2,
                 from src/classes/molecule.h:2,
                 from src/mol_assem_test.cpp:7:
src/classes/atom.h:173:13: warning: ‘read_elem_syms’ defined but not used [-Wunused-variable]
  173 | static bool read_elem_syms = false;
      |             ^~~~~~~~~~~~~~
g++ src/amino_test.cpp obj/atom.o obj/point.o obj/intera.o obj/molecule.o obj/aminoacid.o -o test/amino_test -g -Wall -fextended-identifiers -std=c++14
src/amino_test.cpp: In function ‘int main(int, char**)’:
src/amino_test.cpp:55:19: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
   55 |         while (aa = aa->get_next());
      |                ~~~^~~~~~~~~~~~~~~~
In file included from src/classes/molecule.h:2,
                 from src/classes/aminoacid.h:4,
                 from src/amino_test.cpp:6:
src/classes/intera.h: At global scope:
src/classes/intera.h:75:13: warning: ‘reading_forces’ defined but not used [-Wunused-variable]
   75 | static bool reading_forces = false;
      |             ^~~~~~~~~~~~~~
src/classes/intera.h:74:13: warning: ‘read_forces_dat’ defined but not used [-Wunused-variable]
   74 | static bool read_forces_dat = false;
      |             ^~~~~~~~~~~~~~~
src/classes/intera.h:73:27: warning: ‘forces_by_Z’ defined but not used [-Wunused-variable]
   73 | static InteratomicForce** forces_by_Z[36][36] = {};    // Good for H thru Br. Includes BCNOFPSKNaClBrMgCaFeCuZn.
      |                           ^~~~~~~~~~~
src/classes/intera.h:72:26: warning: ‘all_forces’ defined but not used [-Wunused-variable]
   72 | static InteratomicForce* all_forces[65536];
      |                          ^~~~~~~~~~
In file included from src/classes/intera.h:2,
                 from src/classes/molecule.h:2,
                 from src/classes/aminoacid.h:4,
                 from src/amino_test.cpp:6:
src/classes/atom.h:173:13: warning: ‘read_elem_syms’ defined but not used [-Wunused-variable]
  173 | static bool read_elem_syms = false;
      |             ^~~~~~~~~~~~~~
g++ src/aniso_test.cpp obj/atom.o obj/point.o obj/intera.o obj/molecule.o -o test/aniso_test -g -Wall -fextended-identifiers -std=c++14
In file included from src/classes/molecule.h:2,
                 from src/aniso_test.cpp:6:
src/classes/intera.h:75:13: warning: ‘reading_forces’ defined but not used [-Wunused-variable]
   75 | static bool reading_forces = false;
      |             ^~~~~~~~~~~~~~
src/classes/intera.h:74:13: warning: ‘read_forces_dat’ defined but not used [-Wunused-variable]
   74 | static bool read_forces_dat = false;
      |             ^~~~~~~~~~~~~~~
src/classes/intera.h:73:27: warning: ‘forces_by_Z’ defined but not used [-Wunused-variable]
   73 | static InteratomicForce** forces_by_Z[36][36] = {};    // Good for H thru Br. Includes BCNOFPSKNaClBrMgCaFeCuZn.
      |                           ^~~~~~~~~~~
src/classes/intera.h:72:26: warning: ‘all_forces’ defined but not used [-Wunused-variable]
   72 | static InteratomicForce* all_forces[65536];
      |                          ^~~~~~~~~~
In file included from src/classes/intera.h:2,
                 from src/classes/molecule.h:2,
                 from src/aniso_test.cpp:6:
src/classes/atom.h:173:13: warning: ‘read_elem_syms’ defined but not used [-Wunused-variable]
  173 | static bool read_elem_syms = false;
      |             ^~~~~~~~~~~~~~
g++ src/protein_test.cpp obj/atom.o obj/point.o obj/intera.o obj/molecule.o obj/aminoacid.o obj/protein.o -o test/protein_test -g -Wall -fextended-identifiers -std=c++14
src/protein_test.cpp: In function ‘int main(int, char**)’:
src/protein_test.cpp:12:9: warning: unused variable ‘i’ [-Wunused-variable]
   12 |     int i, seqarg=1, namearg=0;
      |         ^
In file included from src/classes/molecule.h:2,
                 from src/classes/aminoacid.h:4,
                 from src/classes/protein.h:2,
                 from src/protein_test.cpp:6:
src/classes/intera.h: At global scope:
src/classes/intera.h:75:13: warning: ‘reading_forces’ defined but not used [-Wunused-variable]
   75 | static bool reading_forces = false;
      |             ^~~~~~~~~~~~~~
src/classes/intera.h:74:13: warning: ‘read_forces_dat’ defined but not used [-Wunused-variable]
   74 | static bool read_forces_dat = false;
      |             ^~~~~~~~~~~~~~~
src/classes/intera.h:73:27: warning: ‘forces_by_Z’ defined but not used [-Wunused-variable]
   73 | static InteratomicForce** forces_by_Z[36][36] = {};    // Good for H thru Br. Includes BCNOFPSKNaClBrMgCaFeCuZn.
      |                           ^~~~~~~~~~~
src/classes/intera.h:72:26: warning: ‘all_forces’ defined but not used [-Wunused-variable]
   72 | static InteratomicForce* all_forces[65536];
      |                          ^~~~~~~~~~
In file included from src/classes/intera.h:2,
                 from src/classes/molecule.h:2,
                 from src/classes/aminoacid.h:4,
                 from src/classes/protein.h:2,
                 from src/protein_test.cpp:6:
src/classes/atom.h:173:13: warning: ‘read_elem_syms’ defined but not used [-Wunused-variable]
  173 | static bool read_elem_syms = false;
      |             ^~~~~~~~~~~~~~
g++ src/backbone_test.cpp obj/atom.o obj/point.o obj/intera.o obj/molecule.o obj/aminoacid.o obj/protein.o -o test/backbone_test -g -Wall -fextended-identifiers -std=c++14
In file included from src/classes/molecule.h:2,
                 from src/classes/aminoacid.h:4,
                 from src/classes/protein.h:2,
                 from src/backbone_test.cpp:7:
src/classes/intera.h:75:13: warning: ‘reading_forces’ defined but not used [-Wunused-variable]
   75 | static bool reading_forces = false;
      |             ^~~~~~~~~~~~~~
src/classes/intera.h:74:13: warning: ‘read_forces_dat’ defined but not used [-Wunused-variable]
   74 | static bool read_forces_dat = false;
      |             ^~~~~~~~~~~~~~~
src/classes/intera.h:73:27: warning: ‘forces_by_Z’ defined but not used [-Wunused-variable]
   73 | static InteratomicForce** forces_by_Z[36][36] = {};    // Good for H thru Br. Includes BCNOFPSKNaClBrMgCaFeCuZn.
      |                           ^~~~~~~~~~~
src/classes/intera.h:72:26: warning: ‘all_forces’ defined but not used [-Wunused-variable]
   72 | static InteratomicForce* all_forces[65536];
      |                          ^~~~~~~~~~
In file included from src/classes/intera.h:2,
                 from src/classes/molecule.h:2,
                 from src/classes/aminoacid.h:4,
                 from src/classes/protein.h:2,
                 from src/backbone_test.cpp:7:
src/classes/atom.h:173:13: warning: ‘read_elem_syms’ defined but not used [-Wunused-variable]
  173 | static bool read_elem_syms = false;
      |             ^~~~~~~~~~~~~~
g++ src/metal.cpp obj/atom.o obj/point.o obj/intera.o obj/molecule.o obj/aminoacid.o obj/protein.o -o bin/metal -g -Wall -fextended-identifiers -std=c++14
src/metal.cpp: In function ‘int main(int, char**)’:
src/metal.cpp:39:10: warning: unused variable ‘pocketset’ [-Wunused-variable]
   39 |     bool pocketset = false;
      |          ^~~~~~~~~
src/metal.cpp:42:11: warning: unused variable ‘rcpinfo’ [-Wunused-variable]
   42 |     char* rcpinfo = NULL;
      |           ^~~~~~~
src/metal.cpp:168:43: warning: unused variable ‘res’ [-Wunused-variable]
  168 |     int startres, hxstart, hxend, endres, res;
      |                                           ^~~
In file included from src/classes/molecule.h:2,
                 from src/classes/aminoacid.h:4,
                 from src/classes/protein.h:2,
                 from src/metal.cpp:7:
src/classes/intera.h: At global scope:
src/classes/intera.h:75:13: warning: ‘reading_forces’ defined but not used [-Wunused-variable]
   75 | static bool reading_forces = false;
      |             ^~~~~~~~~~~~~~
src/classes/intera.h:74:13: warning: ‘read_forces_dat’ defined but not used [-Wunused-variable]
   74 | static bool read_forces_dat = false;
      |             ^~~~~~~~~~~~~~~
src/classes/intera.h:73:27: warning: ‘forces_by_Z’ defined but not used [-Wunused-variable]
   73 | static InteratomicForce** forces_by_Z[36][36] = {};    // Good for H thru Br. Includes BCNOFPSKNaClBrMgCaFeCuZn.
      |                           ^~~~~~~~~~~
src/classes/intera.h:72:26: warning: ‘all_forces’ defined but not used [-Wunused-variable]
   72 | static InteratomicForce* all_forces[65536];
      |                          ^~~~~~~~~~
In file included from src/classes/intera.h:2,
                 from src/classes/molecule.h:2,
                 from src/classes/aminoacid.h:4,
                 from src/classes/protein.h:2,
                 from src/metal.cpp:7:
src/classes/atom.h:173:13: warning: ‘read_elem_syms’ defined but not used [-Wunused-variable]
  173 | static bool read_elem_syms = false;
      |             ^~~~~~~~~~~~~~
g++ src/podock.cpp obj/atom.o obj/point.o obj/intera.o obj/molecule.o obj/aminoacid.o obj/protein.o -o bin/podock -g -Wall -fextended-identifiers -std=c++14
src/podock.cpp: In function ‘int main(int, char**)’:
src/podock.cpp:427:19: warning: variable ‘lastnodecen’ set but not used [-Wunused-but-set-variable]
  427 |             Point lastnodecen = nodecen;
      |                   ^~~~~~~~~~~
src/podock.cpp:589:17: warning: unused variable ‘iters_div’ [-Wunused-variable]
  589 |             int iters_div = iters*0.259;
      |                 ^~~~~~~~~
src/podock.cpp:105:10: warning: variable ‘configset’ set but not used [-Wunused-but-set-variable]
  105 |     bool configset=false, protset=false, ligset=false, pktset=false;
      |          ^~~~~~~~~
src/podock.cpp:105:27: warning: variable ‘protset’ set but not used [-Wunused-but-set-variable]
  105 |     bool configset=false, protset=false, ligset=false, pktset=false;
      |                           ^~~~~~~
src/podock.cpp:105:42: warning: variable ‘ligset’ set but not used [-Wunused-but-set-variable]
  105 |     bool configset=false, protset=false, ligset=false, pktset=false;
      |                                          ^~~~~~
src/podock.cpp:105:56: warning: variable ‘pktset’ set but not used [-Wunused-but-set-variable]
  105 |     bool configset=false, protset=false, ligset=false, pktset=false;
      |                                                        ^~~~~~
src/podock.cpp:349:23: warning: unused variable ‘iter’ [-Wunused-variable]
  349 |     int pose, nodeno, iter;
      |                       ^~~~
In file included from src/classes/molecule.h:2,
                 from src/classes/aminoacid.h:4,
                 from src/classes/protein.h:2,
                 from src/podock.cpp:9:
src/classes/intera.h: At global scope:
src/classes/intera.h:75:13: warning: ‘reading_forces’ defined but not used [-Wunused-variable]
   75 | static bool reading_forces = false;
      |             ^~~~~~~~~~~~~~
src/classes/intera.h:74:13: warning: ‘read_forces_dat’ defined but not used [-Wunused-variable]
   74 | static bool read_forces_dat = false;
      |             ^~~~~~~~~~~~~~~
src/classes/intera.h:73:27: warning: ‘forces_by_Z’ defined but not used [-Wunused-variable]
   73 | static InteratomicForce** forces_by_Z[36][36] = {};    // Good for H thru Br. Includes BCNOFPSKNaClBrMgCaFeCuZn.
      |                           ^~~~~~~~~~~
src/classes/intera.h:72:26: warning: ‘all_forces’ defined but not used [-Wunused-variable]
   72 | static InteratomicForce* all_forces[65536];
      |                          ^~~~~~~~~~
In file included from src/classes/intera.h:2,
                 from src/classes/molecule.h:2,
                 from src/classes/aminoacid.h:4,
                 from src/classes/protein.h:2,
                 from src/podock.cpp:9:
src/classes/atom.h:173:13: warning: ‘read_elem_syms’ defined but not used [-Wunused-variable]
  173 | static bool read_elem_syms = false;
      |             ^~~~~~~~~~~~~~

The classes likely still leak some memory.

This is not a huge issue, because a docker by its nature runs one task for a few seconds to a few hours then exits; it does not stay running like a daemon or a UI application.

Nevertheless, let's try to minimize memory leaks.

There are a lot of arrays of pointers (Atom**, AminoAcid**, etc) in the code. Some of these are temporary arrays that should be deleted only one level deep when out of scope. The objects themselves are necessary for the entire program execution, and should not be prematurely deleted or segfaults will happen.

molecule_report varies

There seems to be some variance left in molecule_report:

image

This means I cannot trust the molecule_test/report as a regression shield when refactoring molecule.cpp to vector (see #32 ).

I could just filter out the lines that cause variation, however I feel uncertain if the test is then still good enough (would catch regressions/refactoring mistakes) to protect me then? I'd rather fix the output to not be variable, as we did with an if FAIL/SUCCESS at some time.

Squash warnings/error

I'm adding this issue to keep track for small:ish things I do to reduce number of build warnings/errors primarily from the clang based more nitty-gritty compiler on mac.

mol_report indeterministic

It seems every run of mol_report causes new output values:

image

Also, I'd like to rename the test to molecule_test as per convention in repo.

Partial charges.

In any molecule, every atom carries a partial charge caused by the electronegativities of its neighbors (and their neighbors, etc). These partial charges are the cause of hydrogen bonding, pi stacking, metal coordination, etc. Improved accuracy would result by scoring poses based not on static values in bindings.dat but on partial charges instead.

However, calculating them is a huge challenge:

https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3716427/

I do not have the background in math to attempt this one.

Unclear code, or potential bug in Molecule constructor

This looks weird:

image

The first for-loop has no statement; it basically only counts up i until a nullptr value is found in collection. Is this a way to calculate the length of the array?

Written as a vector algorithm, and extracting the get-length logic to separate functin arrayLength it this would look like this instead:

    int i = arrayLength(collection);
    for (int j=0; j<i; j++)
        atoms.push_back(collection[j]);

Bad output from amino_test.

Related to #25.

Certain amino acids are failing pretty badly, e.g.

./amino_test Y

Which produces this monstrosity:
bad tyrosine

The hydrogens attached to the benzene ring should be in the plane of the ring. This seems to be due to the call to make_coplanar_ring() in the AminoAcid constructor.

Tryptophan segfaults or causes an infinite loop.

./amino_test W

Some code files are changing a lot, hot spots?

Did a little source code analysis, inspired by the book "Your code as a crime scene". These are the 10 most changed files last 100 commits:

 ('src/molecule_test.cpp', 98),
 ('src/classes/atom.cpp', 94),
 ('src/classes/atom.h', 94),
 ('src/classes/constants.h', 94),
 ('src/classes/intera.cpp', 94),
 ('src/classes/point.cpp', 94),
 ('src/classes/point.h', 94),
 ('src/podock.cpp', 91),
 ('src/classes/molecule.h', 84)]

I know the source is very actively changing, but it does point towards molecule and atom classes being 'bug zones'. Does this align with your gut feeling @ssepeq ?

Multiple SMILES issues, including aromatic rings not being made coplanar.

Results of the test/mol_assem_tests.sh test:

benzene 🟢
toluene (ring last) 🟢
toluene (ring first) 🟢
cyclohexane 🟢
cyclopentane 🟢
cyclobutane 🟢
cyclobutene 🟡 (hydrogenation.)
cyclobutadiene 🟡 (hydrogenation.)
cyclopropane 🟢
cyclopropene ❌ (hydrogenation.)
calicene ❌ (first ring fails to close.)
2,6-xylenol 🟢
proline 🟡 (hydrogenation)
total substitution test 🟢
o-methylfuranium 🟡 (distorted.)
naphthalene ❌
diphenyl ether ❌ (Ar-O angles.)
azobenzene ❌ (double bond should be planar.)
leaf alcohol/cis-3-hexen-1-ol 🟢
imidazole 🟡 (N-H bond should be coplanar.)
glucose ❌ (the last carbon is in the wrong chirality, even if a [@] symbol is added.)
tetrathioglucose 🟡 (distorted.)
hexathioglucose 🟡 (distorted.)

This post will be periodically edited with the current status.

Switch public-only classes to structs.

Classes and structs are semantically very similar in C++, in fact, the only difference that I know of is that structs start with 'public:' implicitly, while classes start with 'private:' implicitly. This means that class declarations such as this:

class LocatedVector : public SCoord
{
	public:
	LocatedVector() { r = theta = phi = origin.x = origin.y = origin.z = 0; }
	LocatedVector(SCoord sc) { copy(sc); }
	void copy(SCoord sc) { r=sc.r; theta=sc.theta; phi=sc.phi; }
        Point origin;
};

.. can be simlified to this:

struct LocatedVector : public SCoord
{
	LocatedVector() { r = theta = phi = origin.x = origin.y = origin.z = 0; }
	LocatedVector(SCoord sc) { copy(sc); }
	void copy(SCoord sc) { r=sc.r; theta=sc.theta; phi=sc.phi; }
        Point origin;
};

Molecule::reallocate nulls all atoms

void Molecule::reallocate()
{
    if (!(atcount % _def_atc))
    {
        int oac = atcount;
        int ac1 = oac + _def_atc;
        Atom** latoms = new Atom*[ac1+10];

        int i;
        if (!atoms.empty() && oac)
        {
            for (i=0; i<oac; i++) latoms[i] = atoms[i];
        }
        for (i=oac; i<ac1; i++) latoms[i] = nullptr;
        // delete[] atoms;
        atoms = latoms;
    }
    rotatable_bonds = nullptr;
}

The 3rd for-loop sets all items for latoms array (and _def_atc additional elements) to nullptr.

Then atoms is reassigned to latoms, which makes me think this is a bug? Reallocate "clears" all atoms by the looks of it ...

Data for odorophore identification.

In the output for each pose and path node, include for each heavy atom of the ligand, the sum of its and its hydrogens' binding energies to the protein. This will enable determining which moieties and structural features are important for binding with the given receptor.

Offer the option to hydrogenate input files.

Create a new true/false value in the config file to determine whether to use the Molecule::hydrogenate() function on the input protein. Make a second option to do the same for the input SDF.

Important! Make sure the code does not add extra hydrogens where they don't belong. Check that Molecule::hydrogenate() minds the charges of atoms and the number of existing bonds, including cardinality, and make sure to fix any problems you might find.

Water in the binding pocket.

Real life receptors contain water in the binding pocket along with the ligand. The application should simulate water molecules as many as will fit up to a configurable number count, with zero as an acceptable value.

What effect these water molecules would have on the final output binding energies deserves more research into the literature. For sure, the energy level of a pocket containing only water would serve as a baseline, and any effect would be a differential between ligand present vs. no ligand present.

Utility for adding metals.

There is a file called metal.cpp that currently loads a protein and creates an alpha helix in a hard coded location.

The HXXCD/E motif in EXR2 of most ORs is currently the only putative metal binding site thought to form a helix. Its metal should be placed above the ligand binding pocket and the HEAD region moved out of the way if necessary.

This issue is to document ongoing development on the metal binding feature.

(Urgent because a dock results cron is waiting on having better metalloprotein models of the receptors.)

Automatic tests for point/vector missing

Thanks for adding me as contributor @ssepeq !

Here's something I'd love to help out with:

While the point_test.cpp does a good job of verifying (by human eye inspection) the function of point, it would be even more valuable if the checks were automatic, so that refactoring is made easier by catching errors without resorting to human memory. It also serves as a form of documentation of the domain problem/solution.

Suggestions:

  • add automatic tests (checks) for point/vector
  • prefer modern C++ tooling for this, like doctest and CMake
  • unit tests are good enough, but approval tests may be even easier to maintain.

Is this something that would be of interest?

Equal and opposite backbone rotations.

When using the backbone conform functions, often even a slight rotation of one bond can swing the remainder of the strand wildly into another part of the program, causing a clash.

For every bond rotation it tries, have it also do an equal-and-opposite rotation a certain number of residues later in the strand. If rotating an N-CA bond, rotate the CA-C bond of the later residue, and vice versa. How many steps forward to rotate can be dynamically adjusted during the iteration loop.

As a variant, the second rotation can be a smaller angle than the original, so that the peptide chain can still bend. Technically this means it would no longer be equal and opposite motion. The angle of the second rotation would be that of the first times a number between 0 and 1, and it would be dynamically adjusted during iterations.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.