
org.biojava.nbio.structure.ResidueRangeAndLength Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of biojava-structure Show documentation
Show all versions of biojava-structure Show documentation
The protein structure modules of BioJava.
/*
* BioJava development code
*
* This code may be freely distributed and modified under the
* terms of the GNU Lesser General Public Licence. This should
* be distributed with the code. If you do not have a copy,
* see:
*
* http://www.gnu.org/copyleft/lesser.html
*
* Copyright for this code is held jointly by the individual
* authors. These should be listed in @author doc comments.
*
* For more information on the BioJava project and its aims,
* or to join the biojava-l mailing list, visit the home page
* at:
*
* http://www.biojava.org/
*
*/
package org.biojava.nbio.structure;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A chain, a start residue, and an end residue.
*
* Also stores a length. Because of insertion codes, this length is not necessarily {@code end − start}.
*/
public class ResidueRangeAndLength extends ResidueRange {
private static final Logger logger = LoggerFactory.getLogger(ResidueRangeAndLength.class);
private final int length;
public ResidueRangeAndLength(String chain, ResidueNumber start, ResidueNumber end, int length) {
super(chain, start, end);
this.length = length;
}
public ResidueRangeAndLength(String chain, String start, String end, int length) {
super(chain, start, end);
this.length = length;
}
/**
* Returns a new Iterator over every {@link ResidueNumber} in this ResidueRange.
* Stores the contents of {@code map} until the iterator is finished, so calling code should set the iterator to {@code null} if it did not finish.
*/
@Override
public Iterator iterator(AtomPositionMap map) {
return super.iterator(map); // just a bit faster
}
/**
* Calculates the combined number of residues of the ResidueRanges in {@code rrs}.
*
* Assumes no overlap. If two or more ranges cover the same residues, will over-count the union of the residues.
*
* @param rrs
* A list of ResidueRanges
* @return The combined length
* @throws IllegalArgumentException
* If the {@link #getLength() length} of one or more ResidueRange is null
* @see #getLength()
*/
public static int calcLength(List rrs) {
int l = 0;
for (ResidueRangeAndLength rr : rrs) {
l += rr.getLength();
}
return l;
}
/**
* Parses a residue range.
*
* The AtomPositionMap is used to calculate the length and fill in missing
* information, such as for whole chains ('A:'). Supports the special chain
* name '_' for single-chain structures.
*
* If residues are specified outside of the range given in the map,
* attempts to decrease the input range to valid values. In extreme cases
* where this process fails fails to find any valid indices, returns null.
*
* For a function which more conservatively represents the input range,
* without chain inference and error fixes, use {@link ResidueRange#parse(String)}.
* @param s
* A string of the form chain_start-end. For example: A.5-100
.
* @return The unique ResidueRange corresponding to {@code s}.
*/
public static ResidueRangeAndLength parse(String s, AtomPositionMap map) {
ResidueRange rr = parse(s);
ResidueNumber start = rr.getStart();
String chain = rr.getChainId();
// handle special "_" chain
if(chain == null || chain.equals("_")) {
ResidueNumber first = map.getNavMap().firstKey();
chain = first.getChainId();
// Quick check for additional chains. Not guaranteed if the atoms are out of order.
if( ! map.getNavMap().lastKey().getChainId().equals(chain) ) {
logger.warn("Multiple possible chains match '_'. Using chain {}",chain);
}
}
// get a non-null start and end
// if it's the whole chain, choose the first and last residue numbers in the chain
if (start==null) {
start = map.getFirst(chain);
}
ResidueNumber end = rr.getEnd();
if (end==null) { // should happen iff start==null
end = map.getLast(chain);
}
// Replace '_'
start.setChainId(chain);
end.setChainId(chain);
// Now fix any errors and calculate the length
return map.trimToValidResidues(new ResidueRange(chain, start, end));
}
public static List parseMultiple(List ranges, AtomPositionMap map) {
List rrs = new ArrayList(ranges.size());
for (String range : ranges) {
ResidueRangeAndLength rr = ResidueRangeAndLength.parse(range, map);
if (rr != null) rrs.add(rr);
}
return rrs;
}
/**
* @param s
* A string of the form chain_start-end,chain_start-end, ... For example:
* A.5-100,R_110-190,Z_200-250
.
* @return The unique ResidueRange corresponding to {@code s}.
*/
public static List parseMultiple(String s, AtomPositionMap map) {
String[] parts = s.split(",");
List list = new ArrayList(parts.length);
for (String part : parts) {
list.add(parse(part, map));
}
return list;
}
/**
* @return The number of residues in this ResidueRange
*/
public int getLength() {
return length;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
if (!super.equals(o)) {
return false;
}
ResidueRangeAndLength that = (ResidueRangeAndLength) o;
return length == that.length;
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + length;
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy