Skip to content

Commit 6a7284a

Browse files
committed
Issue biojava#582 and some more work towards biojava#545
1 parent 89f710c commit 6a7284a

8 files changed

Lines changed: 125 additions & 53 deletions

File tree

biojava-structure/src/main/java/org/biojava/nbio/structure/Atom.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
import java.util.List;
2727

28+
import javax.vecmath.Point3d;
29+
2830
/**
2931
* A simple interface for an Atom.
3032
* The coordinates can be accessed via the
@@ -94,10 +96,21 @@ public interface Atom extends Cloneable, PDBRecord {
9496

9597
/**
9698
* Get the coordinates.
97-
* @return an array of doubles representing the coords value
99+
* @return a new array of doubles representing the coords value
98100
* @see #setCoords
101+
* @see #getCoordsAsPoint3d()
99102
*/
100103
public double[] getCoords() ;
104+
105+
/**
106+
* Get the coordinates.
107+
* <p>
108+
* Internally the coordinates are represented as Point3d so this
109+
* is recommended over {@link #getCoords()}
110+
* @return a reference to the Point3d coordinates
111+
* @see #getCoords()
112+
*/
113+
public Point3d getCoordsAsPoint3d();
101114

102115
/**
103116
* Set the X coordinate.

biojava-structure/src/main/java/org/biojava/nbio/structure/AtomImpl.java

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import java.util.ArrayList;
3030
import java.util.List;
3131

32+
import javax.vecmath.Point3d;
33+
3234

3335
/**
3436
* Implementation of an Atom of a PDB file.
@@ -47,11 +49,11 @@ public class AtomImpl implements Atom, Serializable, PDBRecord {
4749
*/
4850
public static final int BONDS_INITIAL_CAPACITY = 3;
4951

50-
private String name ;
51-
private Element element;
52-
private double[] coords ;
53-
private int pdbserial ;
54-
private short charge ;
52+
private String name;
53+
private Element element;
54+
private Point3d coords;
55+
private int pdbserial;
56+
private short charge;
5557

5658
private float occupancy ;
5759
private float tempfactor;
@@ -62,15 +64,15 @@ public class AtomImpl implements Atom, Serializable, PDBRecord {
6264
private List<Bond> bonds;
6365

6466
public AtomImpl () {
65-
name = null ;
67+
name = null;
6668
element = Element.R;
67-
coords = new double[3];
68-
occupancy = 0.0f ;
69-
tempfactor = 0.0f ;
69+
coords = new Point3d();
70+
occupancy = 0.0f;
71+
tempfactor = 0.0f;
7072
altLoc = 0;
7173
parent = null;
7274
bonds = null; // let's save some memory and let's not initialise this until it's needed - JD 2016-03-02
73-
charge = 0 ;
75+
charge = 0;
7476
}
7577

7678
/**
@@ -101,44 +103,60 @@ public AtomImpl () {
101103
* {@inheritDoc}
102104
*/
103105
@Override
104-
public void setCoords( double[] c ) { coords = c ; }
106+
public void setCoords( double[] c ) {
107+
coords = new Point3d(c);
108+
}
105109

106110
/**
107111
* {@inheritDoc}
108112
*/
109113
@Override
110-
public double[] getCoords() { return coords ; }
114+
public double[] getCoords() {
115+
double[] c = new double[3];
116+
coords.get(c);
117+
return c;
118+
}
119+
120+
/**
121+
* {@inheritDoc}
122+
*/
123+
@Override
124+
public Point3d getCoordsAsPoint3d() {
125+
return coords;
126+
}
111127

112128
@Override
113129
public void setX(double x) {
114-
coords[0] = x ;
130+
coords.x = x ;
115131
}
132+
116133
@Override
117134
public void setY(double y) {
118-
coords[1] = y ;
135+
coords.y = y ;
119136
}
137+
120138
@Override
121139
public void setZ(double z) {
122-
coords[2] = z ;
140+
coords.z = z ;
123141
}
124142

125143
/**
126144
* {@inheritDoc}
127145
*/
128146
@Override
129-
public double getX() { return coords[0]; }
147+
public double getX() { return coords.x; }
130148

131149
/**
132150
* {@inheritDoc}
133151
*/
134152
@Override
135-
public double getY() { return coords[1]; }
153+
public double getY() { return coords.y; }
136154

137155
/**
138156
* {@inheritDoc}
139157
*/
140158
@Override
141-
public double getZ() { return coords[2]; }
159+
public double getZ() { return coords.z; }
142160

143161
/**
144162
* Set alternate Location.
@@ -167,7 +185,7 @@ public Character getAltLoc() {
167185

168186
@Override
169187
public String toString() {
170-
return name + " " + element + " " + pdbserial + " " + coords[0] + " " + coords[1] + " " + coords[2];
188+
return name + " " + element + " " + pdbserial + " " + coords.x + " " + coords.y + " " + coords.z;
171189
}
172190

173191
@Override

biojava-structure/src/main/java/org/biojava/nbio/structure/Calc.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,8 @@ public static final double amount(Atom a) {
190190
*/
191191
public static final double angle(Atom a, Atom b) {
192192

193-
Vector3d va = new Vector3d(a.getCoords());
194-
Vector3d vb = new Vector3d(b.getCoords());
193+
Vector3d va = new Vector3d(a.getCoordsAsPoint3d());
194+
Vector3d vb = new Vector3d(b.getCoordsAsPoint3d());
195195

196196
return Math.toDegrees(va.angle(vb));
197197

@@ -1197,7 +1197,7 @@ public static void shift(Atom[] ca, Atom b) {
11971197
*/
11981198
public static Matrix4d getTransformation(Matrix rot, Atom trans) {
11991199
return new Matrix4d(new Matrix3d(rot.getColumnPackedCopy()),
1200-
new Vector3d(trans.getCoords()), 1.0);
1200+
new Vector3d(trans.getCoordsAsPoint3d()), 1.0);
12011201
}
12021202

12031203
/**
@@ -1225,7 +1225,7 @@ public static Atom getTranslationVector(Matrix4d transform) {
12251225
public static Point3d[] atomsToPoints(Atom[] atoms) {
12261226
Point3d[] points = new Point3d[atoms.length];
12271227
for (int i = 0; i < atoms.length; i++) {
1228-
points[i] = new Point3d(atoms[i].getCoords());
1228+
points[i] = atoms[i].getCoordsAsPoint3d();
12291229
}
12301230
return points;
12311231
}

biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,8 @@ public void setPDBName(String s) {
169169
public void addAtom(Atom atom){
170170
atom.setGroup(this);
171171
atoms.add(atom);
172-
if (atom.getCoords() != null){
172+
// TODO this check is useless, coords are always !=null since they are initialized to 0,0,0 in AtomImpl constructor. We need to review this - JD 2016-09-14
173+
if (atom.getCoordsAsPoint3d() != null){
173174
// we have got coordinates!
174175
setPDBFlag(true);
175176
}

biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ public void run() {
9494
}
9595

9696

97+
private Point3d[] atomCoords;
9798
private Atom[] atoms;
9899
private double[] radii;
99100
private double probe;
@@ -115,12 +116,13 @@ public void run() {
115116
*/
116117
public AsaCalculator(Structure structure, double probe, int nSpherePoints, int nThreads, boolean hetAtoms) {
117118
this.atoms = StructureTools.getAllNonHAtomArray(structure, hetAtoms);
119+
this.atomCoords = Calc.atomsToPoints(atoms);
118120
this.probe = probe;
119121
this.nThreads = nThreads;
120122

121123
// initialising the radii by looking them up through AtomRadii
122-
radii = new double[atoms.length];
123-
for (int i=0;i<atoms.length;i++) {
124+
radii = new double[atomCoords.length];
125+
for (int i=0;i<atomCoords.length;i++) {
124126
radii[i] = getRadius(atoms[i]);
125127
}
126128

@@ -142,6 +144,7 @@ public AsaCalculator(Structure structure, double probe, int nSpherePoints, int n
142144
*/
143145
public AsaCalculator(Atom[] atoms, double probe, int nSpherePoints, int nThreads) {
144146
this.atoms = atoms;
147+
this.atomCoords = Calc.atomsToPoints(atoms);
145148
this.probe = probe;
146149
this.nThreads = nThreads;
147150

@@ -162,6 +165,41 @@ public AsaCalculator(Atom[] atoms, double probe, int nSpherePoints, int nThreads
162165
cons = 4.0 * Math.PI / nSpherePoints;
163166
}
164167

168+
/**
169+
* Constructs a new AsaCalculator. Subsequently call {@link #calcSingleAsa(int)}
170+
* to calculate the atom ASAs. The given radius parameter will be taken as the radius for
171+
* all points given. No ASA calculation per group will be possible with this constructor, so
172+
* usage of {@link #getGroupAsas()} will result in a NullPointerException.
173+
* @param atomCoords
174+
* the coordinates representing the center of atoms
175+
* @param probe
176+
* the probe size
177+
* @param nSpherePoints
178+
* the number of points to be used in generating the spherical
179+
* dot-density, the more points the more accurate (and slower) calculation
180+
* @param nThreads
181+
* the number of parallel threads to use for the calculation
182+
* @param radius
183+
* the radius that will be assign to all given coordinates
184+
*/
185+
public AsaCalculator(Point3d[] atomCoords, double probe, int nSpherePoints, int nThreads, double radius) {
186+
this.atoms = null;
187+
this.atomCoords = atomCoords;
188+
this.probe = probe;
189+
this.nThreads = nThreads;
190+
191+
// initialising the radii to the given radius for all atoms
192+
radii = new double[atomCoords.length];
193+
for (int i=0;i<atomCoords.length;i++) {
194+
radii[i] = radius;
195+
}
196+
197+
// initialising the sphere points to sample
198+
spherePoints = generateSpherePoints(nSpherePoints);
199+
200+
cons = 4.0 * Math.PI / nSpherePoints;
201+
}
202+
165203
/**
166204
* Calculates ASA for all atoms and return them as a GroupAsa
167205
* array (one element per residue in structure) containing ASAs per residue
@@ -175,7 +213,7 @@ public GroupAsa[] getGroupAsas() {
175213

176214
double[] asasPerAtom = calculateAsas();
177215

178-
for (int i=0;i<atoms.length;i++) {
216+
for (int i=0;i<atomCoords.length;i++) {
179217
Group g = atoms[i].getGroup();
180218
if (!asas.containsKey(g.getResidueNumber())) {
181219
GroupAsa groupAsa = new GroupAsa(g);
@@ -198,10 +236,10 @@ public GroupAsa[] getGroupAsas() {
198236
*/
199237
public double[] calculateAsas() {
200238

201-
double[] asas = new double[atoms.length];
239+
double[] asas = new double[atomCoords.length];
202240

203241
if (nThreads<=1) { // (i.e. it will also be 1 thread if 0 or negative number specified)
204-
for (int i=0;i<atoms.length;i++) {
242+
for (int i=0;i<atomCoords.length;i++) {
205243
asas[i] = calcSingleAsa(i);
206244
}
207245

@@ -246,7 +284,7 @@ public double[] calculateAsas() {
246284
ExecutorService threadPool = Executors.newFixedThreadPool(nThreads);
247285

248286

249-
for (int i=0;i<atoms.length;i++) {
287+
for (int i=0;i<atomCoords.length;i++) {
250288
threadPool.submit(new AsaCalcWorker(i,asas));
251289
}
252290

@@ -289,12 +327,12 @@ private ArrayList<Integer> findNeighborIndices(int k) {
289327

290328
double radius = radii[k] + probe + probe;
291329

292-
for (int i=0;i<atoms.length;i++) {
330+
for (int i=0;i<atomCoords.length;i++) {
293331
if (i==k) continue;
294332

295333
double dist = 0;
296334

297-
dist = Calc.getDistance(atoms[i], atoms[k]);
335+
dist = atomCoords[i].distance(atomCoords[k]);
298336

299337
if (dist < radius + radii[i]) {
300338
neighbor_indices.add(i);
@@ -306,7 +344,7 @@ private ArrayList<Integer> findNeighborIndices(int k) {
306344
}
307345

308346
private double calcSingleAsa(int i) {
309-
Atom atom_i = atoms[i];
347+
Point3d atom_i = atomCoords[i];
310348
ArrayList<Integer> neighbor_indices = findNeighborIndices(i);
311349
int n_neighbor = neighbor_indices.size();
312350
int j_closest_neighbor = 0;
@@ -316,9 +354,9 @@ private double calcSingleAsa(int i) {
316354

317355
for (Point3d point: spherePoints){
318356
boolean is_accessible = true;
319-
Point3d test_point = new Point3d(point.x*radius + atom_i.getX(),
320-
point.y*radius + atom_i.getY(),
321-
point.z*radius + atom_i.getZ());
357+
Point3d test_point = new Point3d(point.x*radius + atom_i.x,
358+
point.y*radius + atom_i.y,
359+
point.z*radius + atom_i.z);
322360

323361
int[] cycled_indices = new int[n_neighbor];
324362
int arind = 0;
@@ -332,9 +370,9 @@ private double calcSingleAsa(int i) {
332370
}
333371

334372
for (int j: cycled_indices) {
335-
Atom atom_j = atoms[neighbor_indices.get(j)];
373+
Point3d atom_j = atomCoords[neighbor_indices.get(j)];
336374
double r = radii[neighbor_indices.get(j)] + probe;
337-
double diff_sq = test_point.distanceSquared(new Point3d(atom_j.getCoords()));
375+
double diff_sq = test_point.distanceSquared(atom_j);
338376
if (diff_sq < r*r) {
339377
j_closest_neighbor = j;
340378
is_accessible = false;

biojava-structure/src/main/java/org/biojava/nbio/structure/quaternary/BioAssemblyTools.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import java.util.Arrays;
2727
import java.util.List;
2828

29+
import javax.vecmath.Point3d;
30+
2931

3032

3133

@@ -150,10 +152,10 @@ public static double[][] getBiologicalMoleculeBounds(Structure asymStructure,Li
150152
for (BiologicalAssemblyTransformation m: transformations) {
151153
if ( ! m.getChainId().equals(intChainID))
152154
continue;
153-
double[] coords = a.getCoords();
154-
transformedCoords[0] = coords[0];
155-
transformedCoords[1] = coords[1];
156-
transformedCoords[2] = coords[2];
155+
Point3d coords = a.getCoordsAsPoint3d();
156+
transformedCoords[0] = coords.x;
157+
transformedCoords[1] = coords.y;
158+
transformedCoords[2] = coords.z;
157159

158160
if (transformedCoords[0] < coordinateBounds[0][0] ) {
159161
coordinateBounds[0][0] = transformedCoords[0]; // min x
@@ -184,7 +186,7 @@ public static double[][] getBiologicalMoleculeBounds(Structure asymStructure,Li
184186
}
185187
public static double[][] getAtomCoordinateBounds(Structure s){
186188

187-
org.biojava.nbio.structure.Atom[] atoms = StructureTools.getAllAtomArray(s);
189+
Atom[] atoms = StructureTools.getAllAtomArray(s);
188190
int atomCount = atoms.length;
189191
final double[][] coordinateBounds = new double[2][3];
190192
if ( atomCount <= 0 ) {
@@ -299,10 +301,10 @@ public static double[] getBiologicalMoleculeCentroid( final Structure asymUnit,L
299301
if (! m.getChainId().equals(intChainID))
300302
continue;
301303

302-
double[] coords = atom.getCoords();
303-
transformedCoordinate[0] = coords[0];
304-
transformedCoordinate[1] = coords[1];
305-
transformedCoordinate[2] = coords[2];
304+
Point3d coords = atom.getCoordsAsPoint3d();
305+
transformedCoordinate[0] = coords.x;
306+
transformedCoordinate[1] = coords.y;
307+
transformedCoordinate[2] = coords.z;
306308
m.transformPoint(transformedCoordinate);
307309
centroid[0] += transformedCoordinate[0];
308310
centroid[1] += transformedCoordinate[1];

0 commit comments

Comments
 (0)