mirror of
https://github.com/rdk/p2rank.git
synced 2026-06-04 12:44:24 +08:00
Add ca_atoms_centroid site evaluation center method with tests
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package cz.siret.prank.domain
|
||||
|
||||
import cz.siret.prank.geom.Atoms
|
||||
import cz.siret.prank.geom.Struct
|
||||
import cz.siret.prank.program.params.Parametrized
|
||||
import cz.siret.prank.utils.PdbUtils
|
||||
import groovy.transform.CompileStatic
|
||||
@@ -106,6 +107,12 @@ class Ligand implements BindingSite, Parametrized {
|
||||
return atoms.centerOfMass
|
||||
case SiteCentroidMethod.sas_points_centroid:
|
||||
return getSasPoints().centroid
|
||||
case SiteCentroidMethod.ca_atoms_centroid:
|
||||
// Select contact residues and compute geometric centroid of their CA atoms
|
||||
List<Residue> contactResidues = protein.residues.getDistinctForAtoms(
|
||||
protein.proteinAtoms.cutoutShell(atoms, params.ligand_protein_contact_distance)
|
||||
)
|
||||
return Struct.calcCaCentroid(contactResidues)
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported site_eval_center_method: '${method}'")
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cz.siret.prank.domain
|
||||
|
||||
import cz.siret.prank.geom.Atoms
|
||||
import cz.siret.prank.geom.Struct
|
||||
import cz.siret.prank.program.params.Parametrized
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.util.logging.Slf4j
|
||||
@@ -68,6 +69,8 @@ class ResidueSite implements BindingSite, Parametrized {
|
||||
return getSasPoints().centroid
|
||||
case SiteCentroidMethod.atoms_center_of_mass:
|
||||
return getAtoms().centerOfMass
|
||||
case SiteCentroidMethod.ca_atoms_centroid:
|
||||
return Struct.calcCaCentroid(residues)
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported site_eval_center_method: '${method}'")
|
||||
}
|
||||
|
||||
@@ -15,7 +15,10 @@ enum SiteCentroidMethod {
|
||||
atoms_center_of_mass(true, true),
|
||||
|
||||
/** Centroid of SAS points around site atoms */
|
||||
sas_points_centroid(true, true)
|
||||
sas_points_centroid(true, true),
|
||||
|
||||
/** Geometric centroid of CA atoms of contact residues */
|
||||
ca_atoms_centroid(true, true)
|
||||
|
||||
/** Supported for ligand-defined sites */
|
||||
final boolean supportedForLigandSites
|
||||
|
||||
@@ -203,6 +203,29 @@ class Struct {
|
||||
return getGroups(struc).findAll{ isHetGroup(it) }.asList()
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate geometric centroid of CA atoms from the given residues.
|
||||
* Residues without CA atoms (e.g. non-standard residues) are skipped.
|
||||
* @return centroid atom or null if no CA atoms found
|
||||
*/
|
||||
@Nullable
|
||||
static Atom calcCaCentroid(List<Residue> residues) {
|
||||
List<Atom> caAtoms = new ArrayList<>()
|
||||
for (Residue res : residues) {
|
||||
AminoAcid aa = res.aminoAcid
|
||||
if (aa != null) {
|
||||
Atom ca = aa.getCA()
|
||||
if (ca != null) {
|
||||
caAtoms.add(ca)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (caAtoms.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
return new Atoms(caAtoms).centroid
|
||||
}
|
||||
|
||||
/**
|
||||
* single linkage clustering
|
||||
* @param clusters
|
||||
|
||||
@@ -829,11 +829,15 @@ class Params {
|
||||
boolean vis_highlight_ligands = false
|
||||
|
||||
/**
|
||||
* Method for computing binding site center for evaluation (DCC criterion).
|
||||
* Values: explicit, atoms_center_of_mass, sas_points_centroid
|
||||
* Method for computing binding site center of observed pocket for evaluation (used by DCC criterion).
|
||||
* Observed pocket can be defined by ligand or can be explicit (set of residues defined in the dataset).
|
||||
* Values: explicit, atoms_center_of_mass, sas_points_centroid, ca_atoms_centroid
|
||||
*
|
||||
* Note: atoms_center_of_mass uses mass-weighted center of ligand/residue atoms for both site types.
|
||||
* explicit is only supported for explicitly defined sites (not ligand-defined).
|
||||
* ca_atoms_centroid uses geometric centroid of CA atoms of contact residues
|
||||
* (for ligand sites: contact residues within ligand_protein_contact_distance;
|
||||
* for explicit sites: the defined residues directly).
|
||||
*
|
||||
* @see cz.siret.prank.domain.SiteCentroidMethod
|
||||
*/
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package cz.siret.prank.domain
|
||||
|
||||
import cz.siret.prank.geom.Atoms
|
||||
import cz.siret.prank.geom.Struct
|
||||
import cz.siret.prank.prediction.pockets.PrankPocket
|
||||
import cz.siret.prank.prediction.pockets.criteria.DCA
|
||||
import cz.siret.prank.program.params.Params
|
||||
import cz.siret.prank.program.routines.results.EvalContext
|
||||
import cz.siret.prank.program.routines.results.Evaluation
|
||||
import groovy.transform.CompileStatic
|
||||
@@ -243,6 +245,51 @@ class SiteMetricsTest {
|
||||
// TODO: test evaluation getStats() with site-based results
|
||||
// TODO: test with sites that are far from any pocket (unidentified case)
|
||||
|
||||
//===========================================================================================================//
|
||||
// ca_atoms_centroid tests
|
||||
//===========================================================================================================//
|
||||
|
||||
@Test
|
||||
void caCentroidMethodWorksForResidueSite() {
|
||||
List<Residue> residues = protein.residues.toList().subList(0, 10)
|
||||
ResidueSite site = makeSite("ca_test", residues)
|
||||
|
||||
String savedMethod = Params.inst.site_eval_center_method
|
||||
try {
|
||||
Params.inst.site_eval_center_method = "ca_atoms_centroid"
|
||||
|
||||
def result = site.getCenterForEval()
|
||||
def expected = Struct.calcCaCentroid(residues)
|
||||
|
||||
assertNotNull(result)
|
||||
assertEquals(expected.x, result.x, 0.001)
|
||||
assertEquals(expected.y, result.y, 0.001)
|
||||
assertEquals(expected.z, result.z, 0.001)
|
||||
} finally {
|
||||
Params.inst.site_eval_center_method = savedMethod
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void caCentroidMethodWorksForLigand() {
|
||||
Ligand ligand = protein.ligands.relevantLigands[0]
|
||||
assertNotNull(ligand, "Test protein should have at least one relevant ligand")
|
||||
|
||||
String savedMethod = Params.inst.site_eval_center_method
|
||||
try {
|
||||
Params.inst.site_eval_center_method = "ca_atoms_centroid"
|
||||
|
||||
def result = ligand.getCenterForEval()
|
||||
assertNotNull(result, "ca_atoms_centroid should return non-null for a ligand with nearby protein residues")
|
||||
|
||||
// Result should be within reasonable distance of the ligand
|
||||
double dist = protein.proteinAtoms.dist(result)
|
||||
assertTrue(dist < 20.0, "CA centroid should be near the protein surface")
|
||||
} finally {
|
||||
Params.inst.site_eval_center_method = savedMethod
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================================================//
|
||||
// Helpers
|
||||
//===========================================================================================================//
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package cz.siret.prank.geom
|
||||
|
||||
import cz.siret.prank.domain.Protein
|
||||
import cz.siret.prank.domain.Residue
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.util.logging.Slf4j
|
||||
import org.biojava.nbio.structure.AminoAcid
|
||||
import org.biojava.nbio.structure.Atom
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||
import static org.junit.jupiter.api.Assertions.*
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -38,4 +41,33 @@ class StructTest {
|
||||
// TODo add test for chain with phosphorylated residue
|
||||
}
|
||||
|
||||
@Test
|
||||
void calcCaCentroidReturnsGeometricCenterOfCaAtoms() {
|
||||
Protein p = Protein.load("$dataDir/2nbr.pdb.gz")
|
||||
List<Residue> residues = p.residues.toList().subList(0, 5)
|
||||
|
||||
Atom result = Struct.calcCaCentroid(residues)
|
||||
assertNotNull(result)
|
||||
|
||||
// Manually compute expected centroid from CA atoms
|
||||
List<Atom> caAtoms = []
|
||||
for (Residue res : residues) {
|
||||
AminoAcid aa = res.aminoAcid
|
||||
if (aa != null) {
|
||||
Atom ca = aa.getCA()
|
||||
if (ca != null) caAtoms.add(ca)
|
||||
}
|
||||
}
|
||||
Atom expected = new Atoms(caAtoms).centroid
|
||||
|
||||
assertEquals(expected.x, result.x, 0.001)
|
||||
assertEquals(expected.y, result.y, 0.001)
|
||||
assertEquals(expected.z, result.z, 0.001)
|
||||
}
|
||||
|
||||
@Test
|
||||
void calcCaCentroidReturnsNullForEmptyList() {
|
||||
assertNull(Struct.calcCaCentroid([]))
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user