001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 * 021 */ 022package org.biojava.nbio.structure.basepairs; 023 024import org.biojava.nbio.structure.Atom; 025import org.biojava.nbio.structure.Chain; 026import org.biojava.nbio.structure.Group; 027import org.biojava.nbio.structure.Structure; 028import org.biojava.nbio.structure.contact.Pair; 029 030import javax.vecmath.Matrix4d; 031import java.util.ArrayList; 032import java.util.List; 033 034/** 035 * This class also finds the base pairing and base-pair step parameters but has a broader definition 036 * of a base pair so that non-canonical-WC base pairs will be detected and reported. This is useful 037 * for RNA that has folded into different regions, and for higher-order DNA structures. Intra-strand 038 * pairings are considered in this class (but in not the base class or MismatchedBasePairParameters class) 039 * @author Luke Czapla 040 * @since 5.0.0 041 * 042 */ 043public class TertiaryBasePairParameters extends BasePairParameters { 044 045 private static final long serialVersionUID = 2556427111533466577L; 046 047 public static final double DEFAULT_MAX_STAGGER = 2.0; 048 public static final double DEFAULT_MAX_PROPELLER = 60.0; 049 // These are the criteria used to select proper base pairs. 050 private double maxStagger = DEFAULT_MAX_STAGGER, 051 maxPropeller = DEFAULT_MAX_PROPELLER; 052 053 public TertiaryBasePairParameters(Structure structure, boolean RNA, boolean removeDups) { 054 super(structure, RNA, removeDups); 055 } 056 057 /** 058 * This is an alternative implementation of findPair() that looks for anything that would fit the 059 * criteria for a base-pair, useful for the context of tertiary structure of RNA. Intra-strand base pairs 060 * are found with this algorithm. 061 * @param chains The list of chains already found to be nucleic acids 062 * @return A list of the Pair of groups that match the base pair criteria, including intra-strand groups. 063 */ 064 @Override 065 public List<Pair<Group>> findPairs(List<Chain> chains) { 066 List<Pair<Group>> result = new ArrayList<>(); 067 boolean lastFoundPair = false; 068 for (int i = 0; i < chains.size(); i++) { 069 Chain c = chains.get(i); 070 String sequence = c.getAtomSequence(); 071 Integer type1, type2; 072 for (int j = 0; j < sequence.length(); j++) { 073 boolean foundPair = false; 074 for (int k = sequence.length()-1; k >= j + 3 && !foundPair; k--) { 075 Group g1 = c.getAtomGroup(j); 076 Group g2 = c.getAtomGroup(k); 077 type1 = BASE_MAP.get(g1.getPDBName()); 078 type2 = BASE_MAP.get(g2.getPDBName()); 079 if (type1 == null || type2 == null) continue; 080 Atom a1 = g1.getAtom("C1'"); 081 Atom a2 = g2.getAtom("C1'"); 082 if (a1 == null || a2 == null) continue; 083 // C1'-C1' distance is one useful criteria 084 if (Math.abs(a1.getCoordsAsPoint3d().distance(a2.getCoordsAsPoint3d())-10.0) > 4.0) continue; 085 Pair<Group> ga = new Pair<>(g1, g2); 086 // TODO is this call needed?? JD 2018-03-07 087 @SuppressWarnings("unused") 088 Matrix4d data = basePairReferenceFrame(ga); 089 // if the stagger is greater than 2 Å, it's not really paired. 090 if (Math.abs(pairParameters[5]) > maxStagger) continue; 091 // if the propeller is ridiculous it's also not that good of a pair. 092 if (Math.abs(pairParameters[1]) > maxPropeller) { 093 continue; 094 } 095 result.add(ga); 096 pairingNames.add(useRNA ? BASE_LIST_RNA[type1]+ BASE_LIST_RNA[type2]: BASE_LIST_DNA[type1]+ BASE_LIST_DNA[type2]); 097 foundPair = true; 098 } 099 if (!foundPair && lastFoundPair) { 100 if (pairSequence.length() > 0 && pairSequence.charAt(pairSequence.length()-1) != ' ') 101 pairSequence += ' '; 102 } 103 if (foundPair) pairSequence += (c.getAtomSequence().charAt(j)); 104 lastFoundPair = foundPair; 105 } 106 } 107 result.addAll(super.findPairs(chains)); 108 return result; 109 } 110 111 /** 112 * This method returns the maximum stagger between bases used as criteria for the characterization of two bases as being paired. 113 * @return the maximum stagger (in Å) allowed. 114 */ 115 public double getMaxStagger() { 116 return maxStagger; 117 } 118 119 /** 120 * This method sets the maximum stagger allowed for a base pair, prior to analyze() call 121 * @param maxStagger The maximum stagger (in Å) allowed to consider two bases paired 122 */ 123 public void setMaxStagger(double maxStagger) { 124 this.maxStagger = maxStagger; 125 } 126 127 /** 128 * This method returns the maximum propeller twist between bases used as criteria for the characterization of two bases as being paired. 129 * @return the maximum propeller ("propeller-twist", in degrees) allowed. 130 */ 131 public double getMaxPropeller() { 132 return maxPropeller; 133 } 134 135 /** 136 * This method sets the maximum propeller allowed for a base pair, prior to analyze() call 137 * @param maxPropeller The maximum propeller ("propeller-twist", in degrees) allowed to consider two bases paired 138 */ 139 public void setMaxPropeller(double maxPropeller) { 140 this.maxPropeller = maxPropeller; 141 } 142}