001 /* 002 * Copyright 2007, 2012 Stephen Fisher and Junhyong Kim, University of 003 * Pennsylvania. 004 * 005 * This file is part of Glo-DB. 006 * 007 * Glo-DB is free software: you can redistribute it and/or modify it 008 * under the terms of the GNU General Public License as published by 009 * the Free Software Foundation, either version 3 of the License, or 010 * (at your option) any later version. 011 * 012 * Glo-DB is distributed in the hope that it will be useful, but 013 * WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * General Public License for more details. 016 * 017 * You should have received a copy of the GNU General Public License 018 * along with Glo-DB. If not, see <http://www.gnu.org/licenses/>. 019 * 020 * @(#)FuzzyFeature.java 021 */ 022 023 package edu.upenn.gloDB; 024 025 /** 026 * These objects code Features that don't have definite boundaries. 027 * It's not clear whether it's more advantagous to have separate class 028 * definitions: 029 * FuzzyFeature - make abstract class 030 * BetweenFeature - same fields as below 031 * AfterFeature - no stop -> stop = sequence length; stopExtension = 0 032 * BeforeFeature - no start -> start = 0; startExtension = 0 033 * 034 * @author Stephen Fisher 035 * @version $Id: FuzzyFeature.java,v 1.1.2.9 2007/03/01 21:17:32 fisher Exp $ 036 */ 037 038 public class FuzzyFeature extends AbstractFeature { 039 /** The initial position defining this Feature. */ 040 private int start; 041 042 /** The number of the positions defining the start position. */ 043 private int startExt; 044 045 /** The last position defining this Feature. */ 046 private int stop; 047 048 /** The number of the positions defining the stop position. */ 049 private int stopExt; 050 051 052 /** 053 * Create a new FuzzyFeature object and add it to the set of 054 * Feature objects. 055 */ 056 public FuzzyFeature(int start, int startExt, int stop, int stopExt, Sequence source) { 057 this(start, startExt, stop, stopExt, source, true); 058 } 059 060 /** 061 * Create a new FuzzyFeature object and add the newly created 062 * FuzzyFeature object to the set of Feature objects if addToPool 063 * is true. 064 * @XXX This should probably be 'protected' instead of 'public' 065 * because all FuzzyFeatures should really be added to 066 * featurePool. 067 */ 068 public FuzzyFeature(int start, int startExt, int stop, int stopExt, Sequence source, boolean addToPool) { 069 super(source); 070 071 // these aren't allowed to change, so this is the only place 072 // they should be set. 073 this.start = start; 074 this.startExt = startExt; 075 this.stop = stop; 076 this.stopExt = stopExt; 077 078 // add self to set of all Features 079 if (addToPool) ObjectHandles.addFeature(this); 080 } 081 082 083 //-------------------------------------------------------------------------- 084 // Setters and Getters 085 086 /** Returns the start position. */ 087 public int getStart() { return start; } 088 089 /** Returns the startExt position. */ 090 public int getStartExt() { return startExt; } 091 092 /** Returns the stop position. */ 093 public int getStop() { return stop; } 094 095 /** Returns the stopExt. */ 096 public int getStopExt() { return stopExt; } 097 098 //-------------------------------------------------------------------------- 099 // Miscellaneous Methods 100 101 /** 102 * Returns the Sequence data from start to stopExt. Note that 103 * this includes the fuzzy boundaries. 104 */ 105 public String getData() { 106 return getSource().getDataBounded(start, stopExt); 107 } 108 109 /** 110 * Returns the Sequence data from start to stopExt, with "\n" 111 * inserted every 80 characters. 112 */ 113 public String getDataFormatted() { 114 return getSource().getDataBoundedFormatted(start, stopExt); 115 } 116 117 /** 118 * Returns the maximum number of positions contained in the 119 * Feature (((stop + stopExt) - start) + 1). 120 */ 121 public int length() { return (((stop + stopExt) - start) + 1); } 122 123 /** 124 * Returns the initial position of the Feature. 125 */ 126 public int getMin() { return start; } 127 128 /** 129 * Returns the maximum position of the Feature. 130 */ 131 public int getMax() { return stopExt; } 132 133 /** 134 * Returns the minimum number of positions contained in the 135 * Feature ((stop - start) + 1). 136 */ 137 public int minLength() { return ((stop - start) + 1); } 138 139 /** 140 * This is the same as {@link #length() length()}. 141 */ 142 public int maxLength() { return length(); } 143 144 /** 145 * Inverts the positions, returning a new Feature object. For 146 * example, if the Feature had a start position of 10 and a stop 147 * position of 20 on a contig that was 100 positions long, then 148 * flipping the Feature would result in a new Feature object with 149 * a start position of 80 and a stop position of 90. 150 * @XXX Not yet implemented. 151 */ 152 public Feature flip() { return null; } 153 154 /** 155 * Returns '-1' if this Feature exists after the integer 'pos', 156 * returns '0' if 'pos' is contained in this Feature, and '1' if 157 * 'pos' occurs after this Feature. 158 * @XXX This assumes 'pos' is positive within this Feature's 159 * Sequence boundaries. 160 */ 161 public int contains(int pos) { 162 return FeatureUtils.contains(this, pos); 163 } 164 165 /** 166 * Returns 'true' if the Feature 'feature' is contained in this 167 * Feature. 168 */ 169 public boolean contains(Feature feature) { 170 return FeatureUtils.contains(this, feature); 171 } 172 173 /** 174 * Returns 'true' if the feature 'featCk' has positions that 175 * overlap positions in this feature. 176 */ 177 public boolean overlaps(Feature feature) { 178 return FeatureUtils.overlaps(this, feature); 179 } 180 181 /** 182 * Returns the overlapping region between the two Features. If no 183 * overlap, then null is returned. 184 */ 185 public Feature overlap(Feature feature) { 186 return FeatureUtils.overlap(this, feature); 187 } 188 189 /** 190 * Compares this object with the specified object for order. 191 * Returns a negative integer, zero, or a positive integer as this 192 * object is less than, equal to, or greater than the specified 193 * object. If can't cast argument as an Feature, then throws a 194 * java.lang.ClassCastException. If different sources, then sorts 195 * on the source ID. 196 * 197 */ 198 public int compareTo(Object o) throws ClassCastException { 199 // convert object to Feature 200 Feature featureTo; 201 try { 202 featureTo = (Feature) o; 203 } catch (ClassCastException e) { 204 throw new ClassCastException("FuzzyFeature.compareTo() requires an argument of type Feature."); 205 } 206 return FeatureUtils.compareFeatures(this, featureTo); 207 } 208 209 /** 210 * This will return true if the features are equal and the 211 * sources are the same. If can't cast argument as a 212 * FuzzyFeature, then throws a java.lang.ClassCastException. 213 */ 214 public boolean equals(Object o) throws ClassCastException { 215 // make sure we got an 'ExactFeature' object 216 if (GloDBUtils.getClassName(o) != "FuzzyFeature") return false; 217 218 // convert object to Feature 219 FuzzyFeature featureTo; 220 try { 221 featureTo = (FuzzyFeature) o; 222 } catch (ClassCastException e) { 223 throw new ClassCastException("FuzzyFeature.equals() requires an argument of type FuzzyFeature."); 224 } 225 226 // check of same source 227 if (source != featureTo.source) { return false; } 228 229 // check if start, stop, and extensions are all equal 230 if ((start == featureTo.getStart()) && 231 (startExt == featureTo.getStartExt()) && 232 (stop == featureTo.getStop()) && 233 (stopExt == featureTo.getStopExt())) { 234 return true; 235 } else { 236 return false; 237 } 238 } 239 240 /** Only returns basic Feature information. */ 241 public String toString() { 242 String out = "Fuzzy Feature (" + source + "): "; 243 out += "(" + Integer.toString(start) + ", " + Integer.toString(startExt) + ").."; 244 out += "(" + Integer.toString(stop) + ", " + Integer.toString(stopExt) + ") \n"; 245 return out; 246 } 247 248 /** Only returns start/stop position information. */ 249 public String toStringMin() { 250 String out = ""; 251 out += "(" + Integer.toString(start) + ", " + Integer.toString(startExt) + ").."; 252 out += "(" + Integer.toString(stop) + ", " + Integer.toString(stopExt) + ")"; 253 return out; 254 } 255 256 /** Returns all Feature information. */ 257 public String toStringFull() { 258 String out = "Fuzzy Feature:\n"; 259 // String out = "Fuzzy Feature (" + source + "): "; 260 // out += "(" + Integer.toString(start) + ", " + Integer.toString(startExt) + ").."; 261 // out += "(" + Integer.toString(stop) + ", " + Integer.toString(stopExt) + ") \n"; 262 263 out += "Start: " + Integer.toString(start) + "\n"; 264 out += "StartExt: " + Integer.toString(startExt) + "\n"; 265 out += "Stop: " + Integer.toString(stop) + "\n"; 266 out += "StopExt: " + Integer.toString(stopExt) + "\n"; 267 268 out += super.toString(); // get attributes and source info 269 270 return out; 271 } 272 273 } // FuzzyFeature.java