/** * Gets the van der Waals radius of the given atom following the values defined by Chothia (1976) * J.Mol.Biol.105,1-14 NOTE: the vdw values defined by the paper assume no Hydrogens and thus * "inflates" slightly the heavy atoms to account for Hydrogens. Thus this method cannot be used * in a structure that contains Hydrogens! * * <p>If atom is neither part of a nucleotide nor of a standard aminoacid, the default vdw radius * for the element is returned. If atom is of unknown type (element) the vdw radius of {@link * #Element().N} is returned * * @param atom * @return */ public static double getRadius(Atom atom) { if (atom.getElement() == null) { System.err.println( "Warning: unrecognised atom " + atom.getName() + " with serial " + atom.getPDBserial() + ", assigning the default vdw radius (Nitrogen vdw radius)."); return Element.N.getVDWRadius(); } Group res = atom.getGroup(); if (res == null) { System.err.println( "Warning: unknown parent residue for atom " + atom.getName() + " with serial " + atom.getPDBserial() + ", assigning its default vdw radius"); return atom.getElement().getVDWRadius(); } String type = res.getType(); if (type.equals(GroupType.AMINOACID)) return getRadiusForAmino(((AminoAcid) res), atom); if (type.equals(GroupType.NUCLEOTIDE)) return getRadiusForNucl((NucleotideImpl) res, atom); return atom.getElement().getVDWRadius(); }
/** * Constructs a new AsaCalculator. Subsequently call {@link #calculateAsas()} or {@link * #getGroupAsas()} to calculate the ASAs. * * @param atoms an array of atoms not containing Hydrogen atoms * @param probe the probe size * @param nSpherePoints the number of points to be used in generating the spherical dot-density, * the more points the more accurate (and slower) calculation * @param nThreads the number of parallel threads to use for the calculation * @throws IllegalArgumentException if any atom in the array is a Hydrogen atom */ public AsaCalculator(Atom[] atoms, double probe, int nSpherePoints, int nThreads) { this.atoms = atoms; this.probe = probe; this.nThreads = nThreads; for (Atom atom : atoms) { if (atom.getElement() == Element.H) throw new IllegalArgumentException( "Can't calculate ASA for an array that contains Hydrogen atoms "); } // initialising the radii by looking them up through AtomRadii radii = new double[atoms.length]; for (int i = 0; i < atoms.length; i++) { radii[i] = getRadius(atoms[i]); } // initialising the sphere points to sample spherePoints = generateSpherePoints(nSpherePoints); cons = 4.0 * Math.PI / (double) nSpherePoints; }
/** * Gets the radius for given nucleotide atom * * @param atom * @return */ private static double getRadiusForNucl(NucleotideImpl nuc, Atom atom) { if (atom.getElement().equals(Element.H)) return Element.H.getVDWRadius(); if (atom.getElement().equals(Element.D)) return Element.D.getVDWRadius(); if (atom.getElement() == Element.C) return NUC_CARBON_VDW; if (atom.getElement() == Element.N) return NUC_NITROGEN_VDW; if (atom.getElement() == Element.P) return PHOSPHOROUS_VDW; if (atom.getElement() == Element.O) return OXIGEN_VDW; System.err.println( "Warning: unexpected atom " + atom.getName() + " for nucleotide " + nuc.getPDBName() + ", assigning its standard vdw radius"); return atom.getElement().getVDWRadius(); }
private double calcSingleAsa(int i) { Atom atom_i = atoms[i]; ArrayList<Integer> neighbor_indices = findNeighborIndices(i); int n_neighbor = neighbor_indices.size(); int j_closest_neighbor = 0; double radius = probe + radii[i]; int n_accessible_point = 0; for (Point3d point : spherePoints) { boolean is_accessible = true; Point3d test_point = new Point3d( point.x * radius + atom_i.getX(), point.y * radius + atom_i.getY(), point.z * radius + atom_i.getZ()); int[] cycled_indices = new int[n_neighbor]; int arind = 0; for (int ind = j_closest_neighbor; ind < n_neighbor; ind++) { cycled_indices[arind] = ind; arind++; } for (int ind = 0; ind < j_closest_neighbor; ind++) { cycled_indices[arind] = ind; arind++; } for (int j : cycled_indices) { Atom atom_j = atoms[neighbor_indices.get(j)]; double r = radii[neighbor_indices.get(j)] + probe; double diff_sq = test_point.distanceSquared(new Point3d(atom_j.getCoords())); if (diff_sq < r * r) { j_closest_neighbor = j; is_accessible = false; break; } } if (is_accessible) { n_accessible_point++; } } return cons * n_accessible_point * radius * radius; }
/** * Gets the radius for given amino acid and atom * * @param aa * @param atom * @return */ private static double getRadiusForAmino(AminoAcid amino, Atom atom) { if (atom.getElement().equals(Element.H)) return Element.H.getVDWRadius(); // some unusual entries (e.g. 1tes) contain Deuterium atoms in standard aminoacids if (atom.getElement().equals(Element.D)) return Element.D.getVDWRadius(); String atomCode = atom.getName(); char aa = amino.getAminoType(); // here we use the values that Chothia gives in his paper (as NACCESS does) if (atom.getElement() == Element.O) { return OXIGEN_VDW; } else if (atom.getElement() == Element.S) { return SULFUR_VDW; } else if (atom.getElement() == Element.N) { if (atomCode.equals("NZ")) return TETRAHEDRAL_NITROGEN_VDW; // tetrahedral Nitrogen return TRIGONAL_NITROGEN_VDW; // trigonal Nitrogen } else if (atom.getElement() == Element.C) { // it must be a carbon if (atomCode.equals("C") || atomCode.equals("CE1") || atomCode.equals("CE2") || atomCode.equals("CE3") || atomCode.equals("CH2") || atomCode.equals("CZ") || atomCode.equals("CZ2") || atomCode.equals("CZ3")) { return TRIGONAL_CARBON_VDW; // trigonal Carbon } else if (atomCode.equals("CA") || atomCode.equals("CB") || atomCode.equals("CE") || atomCode.equals("CG1") || atomCode.equals("CG2")) { return TETRAHEDRAL_CARBON_VDW; // tetrahedral Carbon } // the rest of the cases (CD, CD1, CD2, CG) depend on amino acid else { switch (aa) { case 'F': case 'W': case 'Y': case 'H': case 'D': case 'N': return TRIGONAL_CARBON_VDW; case 'P': case 'K': case 'R': case 'M': case 'I': case 'L': return TETRAHEDRAL_CARBON_VDW; case 'Q': case 'E': if (atomCode.equals("CD")) return TRIGONAL_CARBON_VDW; else if (atomCode.equals("CG")) return TETRAHEDRAL_CARBON_VDW; default: System.err.println( "Warning: unexpected carbon atom " + atomCode + " for aminoacid " + aa + ", assigning its standard vdw radius"); return Element.C.getVDWRadius(); } } // not any of the expected atoms } else { System.err.println( "Warning: unexpected atom " + atomCode + " for aminoacid " + aa + ", assigning its standard vdw radius"); return atom.getElement().getVDWRadius(); } }