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 */ 021package org.biojava.nbio.structure.contact; 022 023import org.biojava.nbio.structure.Atom; 024 025import java.io.Serializable; 026import java.util.*; 027 028 029/** 030 * A set of atom-atom contacts to hold the results of intra and inter-chain contact calculations 031 * 032 * @author duarte_j 033 * 034 */ 035public class AtomContactSet implements Serializable, Iterable<AtomContact> { 036 037 038 private static final long serialVersionUID = 1L; 039 040 private HashMap<Pair<AtomIdentifier>, AtomContact> contacts; 041 private double cutoff; 042 043 public AtomContactSet(double cutoff) { 044 this.cutoff = cutoff; 045 this.contacts = new HashMap<Pair<AtomIdentifier>,AtomContact>(); 046 } 047 048 public void add(AtomContact contact) { 049 this.contacts.put(getAtomIdPairFromContact(contact), contact); 050 } 051 052 public void addAll(Collection<AtomContact> list) { 053 for (AtomContact contact:list) { 054 this.contacts.put(getAtomIdPairFromContact(contact), contact); 055 } 056 } 057 058 public boolean hasContact(Atom atom1, Atom atom2) { 059 return hasContact( 060 new AtomIdentifier(atom1.getPDBserial(),atom1.getGroup().getChainId()), 061 new AtomIdentifier(atom2.getPDBserial(),atom2.getGroup().getChainId()) ); 062 } 063 064 public boolean hasContact(AtomIdentifier atomId1, AtomIdentifier atomId2) { 065 return contacts.containsKey(new Pair<AtomIdentifier>(atomId1,atomId2)); 066 } 067 068 /** 069 * Returns the corresponding AtomContact or null if no contact exists between the 2 given atoms 070 * @param atom1 071 * @param atom2 072 * @return 073 */ 074 public AtomContact getContact(Atom atom1, Atom atom2) { 075 return contacts.get(new Pair<AtomIdentifier>( 076 new AtomIdentifier(atom1.getPDBserial(),atom1.getGroup().getChainId()), 077 new AtomIdentifier(atom2.getPDBserial(),atom2.getGroup().getChainId()) )); 078 } 079 080 public int size() { 081 return contacts.size(); 082 } 083 084 @Override 085 public Iterator<AtomContact> iterator() { 086 return contacts.values().iterator(); 087 } 088 089 private Pair<AtomIdentifier> getAtomIdPairFromContact(AtomContact contact) { 090 Pair<AtomIdentifier> pair = new Pair<AtomIdentifier>( 091 new AtomIdentifier(contact.getPair().getFirst().getPDBserial(),contact.getPair().getFirst().getGroup().getChainId()), 092 new AtomIdentifier(contact.getPair().getSecond().getPDBserial(),contact.getPair().getSecond().getGroup().getChainId())); 093 094 return pair; 095 } 096 097 /** 098 * Returns true if at least 1 contact from this set is within the given distance. 099 * Note that if the distance given is larger than the distance cutoff used to 100 * calculate the contacts then nothing will be found. 101 * @param distance 102 * @return 103 * @throws IllegalArgumentException if given distance is larger than distance cutoff 104 * used for calculation of contacts 105 */ 106 public boolean hasContactsWithinDistance(double distance) { 107 108 if (distance>=cutoff) 109 throw new IllegalArgumentException("Given distance "+ 110 String.format("%.2f", distance)+" is larger than contacts' distance cutoff "+ 111 String.format("%.2f", cutoff)); 112 113 for (AtomContact contact:this.contacts.values()) { 114 if (contact.getDistance()<distance) { 115 return true; 116 } 117 } 118 return false; 119 } 120 121 /** 122 * Returns the list of contacts from this set that are within the given distance. 123 * @param distance 124 * @return 125 * @throws IllegalArgumentException if given distance is larger than distance cutoff 126 * used for calculation of contacts 127 */ 128 public List<AtomContact> getContactsWithinDistance(double distance) { 129 130 if (distance>=cutoff) 131 throw new IllegalArgumentException("Given distance "+ 132 String.format("%.2f", distance)+" is larger than contacts' distance cutoff "+ 133 String.format("%.2f", cutoff)); 134 135 List<AtomContact> list = new ArrayList<AtomContact>(); 136 for (AtomContact contact:this.contacts.values()) { 137 if (contact.getDistance()<distance) { 138 list.add(contact); 139 } 140 } 141 return list; 142 } 143}