package org.seqcode.genome.location; import java.util.regex.Pattern; import java.util.regex.Matcher; import org.seqcode.genome.Genome; public class StrandedRegion extends Region implements Stranded { protected char strand; public StrandedRegion(StrandedRegion nr) { super(nr); strand = nr.strand; } public StrandedRegion(Region r) { super(r); strand = 1; } public StrandedRegion(Region r, char st) { super(r); strand = st; } public StrandedRegion(Genome g, String c, int start, int end, char str) { super(g,c,start,end); strand = str; } public char getStrand() { return strand; } public int getFivePrime() { if (strand == '+') { return getStart(); } else if (strand == '-') { return getEnd(); } else { throw new IllegalArgumentException("Unknown strand " + getStrand()); } } public int getThreePrime() { if (strand == '-') { return getStart(); } else if (strand == '+') { return getEnd(); } else { throw new IllegalArgumentException("Unknown strand " + getStrand()); } } public String toString() { return getLocationString() + ":" + strand; } public boolean equals(Object o) { if(!(o instanceof StrandedRegion)) { return false; } StrandedRegion nr = (StrandedRegion)o; if(nr.strand != strand) { return false; } return super.equals(nr); } public StrandedRegion expand(int upstream, int downstream) { if (strand == '+') { int ns = getStart() - upstream; int ne = getEnd() + downstream; if (ns < 1) {ns = 1;} return new StrandedRegion(getGenome(),getChrom(),ns,ne,strand); } else if (strand == '-') { int ns = getStart() - downstream; int ne = getEnd() + upstream; if (ns < 1) {ns = 1;} return new StrandedRegion(getGenome(),getChrom(),ns,ne,strand); } else { throw new IllegalArgumentException("Strand isn't + or - so I don't know what to do"); } } public static StrandedRegion fromString(Genome genome, String input) throws NumberFormatException { String trimmed = input.trim(); String regionregex = "^\\s*([\\w\\d]+):\\s*([,\\d]+[mMkK]?)\\s*-\\s*([,\\d]+[mMkK]?):([\\+\\-])\\s*"; Pattern regionpattern = Pattern.compile(regionregex); Matcher regionmatcher = regionpattern.matcher(trimmed); if (regionmatcher.find()) { if(regionmatcher.groupCount() != 4) { return null; } String chromStr = regionmatcher.group(1); String startStr = regionmatcher.group(2); String endStr = regionmatcher.group(3); char strand = regionmatcher.group(4).charAt(0); if(chromStr.startsWith("chr")) { chromStr = chromStr.substring(3, chromStr.length()); } startStr = startStr.replaceAll(",", ""); endStr = endStr.replaceAll(",", ""); int start = Math.min(stringToNum(startStr), stringToNum(endStr)); int end = Math.max(stringToNum(startStr), stringToNum(endStr)); return new StrandedRegion(genome, chromStr, start, end, strand); } return null; } /** * Returns the mid-point (as Point) that corresponds to this region. * Correction for even-length region midpoints when reverse-complemented * @return */ public StrandedPoint getMidpoint() { int middle = (this.getStart() + this.getEnd()) / 2; if(this.getStrand()=='-' && (this.getWidth())%2==0) middle++; return new StrandedPoint(this.getGenome(), this.getChrom(), middle, strand); } public int hashCode() { int code = super.hashCode(); code += strand; code *= 37; return code; } }