All pastes #2024 Raw Edit

bioTTY

public java v1 · immutable
#2024 ·published 2004-11-10 19:21 UTC
rendered paste body
package org.flymine.bj.bio;import java.util.Collection;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.Map;import java.util.Set;import org.apache.log4j.Logger;import org.biojava.bio.BioException;import org.biojava.bio.seq.AbstractFeatureHolder;import org.biojava.bio.seq.Feature;import org.biojava.bio.seq.FeatureFilter;import org.biojava.bio.seq.FeatureHolder;import org.biojava.bio.seq.FilterUtils;import org.biojava.bio.seq.StrandedFeature;import org.biojava.utils.walker.Walker;import org.biojava.utils.walker.WalkerFactory;import org.flymine.bj.exceptions.ModelExceptionFM;import org.flymine.bj.query.QueryFM;import org.flymine.bj.query.VisitorSeq;import org.flymine.model.genomic.BioEntity;import org.intermine.objectstore.query.Query;/** * Implementation of a FlyMine (FM) specific BioJava FeatureHolder *  * @author Markus Brosch */public class FeatureHolderFM extends AbstractFeatureHolder implements FeatureHolder {  // =======================================================================  // Attributes  // =======================================================================  /**   * logger   */  private static Logger _log = Logger.getLogger(FeatureHolderFM.class);  /**   * the source/root SequenceFM   */  private final SequenceFM _sourceSeq; //required  /**   * if this FeatureHolder holds _all_ features of a chromosome, this flag ist true; <br>   * if this FeatureHolder is a result of a filter and a subset of features of a chromosome, this   * flag is false   */  private final boolean _isAllFeatures;  /**   * chromosome ID which represents the _sourceSeq; can be extracted from sourceSeq, but it is   * called many times, therefore a attribute is   */  private final Integer _chromosomeID;  /**   * ID's of Features (BioEntities) represented by this FeatureHolder   */  private Collection _ids;  /**   * Set of FeatureFM Objects which are held by this FeatureHolder   */  private Collection _features = null;  // =======================================================================  // Constructors  // =======================================================================  /**   * Constructor   *    * @param pSourceSeq   *          represents the source / root Sequence (FlyMine Chromosome). All operations are based   *          on this underlying sequence. Therefore, all Features of this sequence are taken into   *          account. If you want to build a subset of features, use the extended constructor and   *          pass in the ids of these features   */  public FeatureHolderFM(final SequenceFM pSourceSeq) {    this(pSourceSeq, null);  }  /**   * Constructor   *    * @param pSourceSeq   *          represents the source / root Sequence (FlyMine Chromosome).   * @param pIds   *          the IDs of Features (FlyMine BioEntities) this FeatureHolder holds; <br>   *          If IDs are provided, all operations and methods only work on this subset of features   *          according to the ID set.   */  public FeatureHolderFM(final SequenceFM pSourceSeq, final Set pIds) {    if (pSourceSeq == null) { throw new NullPointerException("SequenceFM must not be null"); }    _sourceSeq = pSourceSeq;    _chromosomeID = pSourceSeq.getBioEntityID();    _ids = pIds;    if (pIds == null) {      _isAllFeatures = true;    } else {      _isAllFeatures = false;    }    if (_log.isDebugEnabled()) {      _log.debug("constructor():");      _log.debug("\t sourceSequence was set; name: " + _sourceSeq.getName());      _log.debug("\t chromosomeID was set: " + _chromosomeID);      if (_isAllFeatures) {        _log.debug("constructor(): ids=null; => FH ~> whole Chromosome ");      } else {        _log.debug("\t : ids were set; => FH for Features with these IDs");      }    }  }  // =======================================================================  // Implements FeatureHolder interface  // =======================================================================  /**   * Count how many features (BioEntities) are contained on this Sequence (Chromosome)   *    * @return a positive integer or zero, equal to the number of features contained   */  public final int countFeatures() {    if (_ids != null) {      _log.info("countFeatures(): ids.size();");      return _ids.size();    }    if (_features != null) {      _log.info("countFeatures(): features.size();");      return _features.size();    }    final QueryFM q = new QueryFM(_chromosomeID);    try {      _log.info("countFeatures(): q.countResult(q.byClass(BioEntity.class));");      return q.countResult(q.byClass(BioEntity.class));    } catch (ModelExceptionFM e) {      throw new RuntimeException("Not a BioEntity", e);    }  }  /**   * @see FeatureHolder#features()   */  public final Iterator features() {    return getFeatures().iterator();  }  /**   * @param pFilter   *          Your FeatureFilter. Be aware, that this implementation does not provide any hierarchy,   *          therefore the Filters: FeatureFilter.ByChild(), FeatureFilter.ByParent(),   *          FeatureFilter.ByAncestor() are returning an empty FeatureHolder.   * @param pRecurse   *          you can set it true or false, in both cases it will not change the result as we don't   *          provide a hierarchy in this implementation.   * @return FeatureFM Objects in a FeatureHolder which fulfil the filter ff   * @deprecated   * @see FeatureHolder#filter(org.biojava.bio.seq.FeatureFilter, boolean)   */  public final FeatureHolder filter(final FeatureFilter pFilter, final boolean pRecurse) {    return filter(pFilter, false);  }  /**   * @param pFilter   *          Your FeatureFilter. Be aware, that this implementation does not provide any hierarchy,   *          therefore the Filters: FeatureFilter.ByChild(), FeatureFilter.ByParent(),   *          FeatureFilter.ByAncestor() are returning an empty FeatureHolder.   * @return FeatureFM Objects in a FeatureHolder which fulfil the filter ff   * @see FeatureHolder#filter(org.biojava.bio.seq.FeatureFilter)   */  public final FeatureHolder filter(final FeatureFilter pFilter) {    _log.info("filter(filter):");    //IF in memory processing    if (_sourceSeq.isMemoryMode()) {      _log.info("\t isMemoryMode ~> super.filter(filter, false);");      //note: features() is called in super.filter()      return super.filter(pFilter, false);    }    //IF on the fly processing / non memory mode: query dynamically    final QueryFM q = new QueryFM(_chromosomeID);    //check if features of featureFilter tree are disjoint    final FeatureFilter childF = new FeatureFilter.Not(FeatureFilter.top_level);    if (FilterUtils.areDisjoint(pFilter, childF)) { return FeatureHolder.EMPTY_FEATURE_HOLDER; }    //get a visitor & walk the filter tree, get the generated Query & return FH with resulting IDs    final VisitorSeq visitor = new VisitorSeq(q);    final WalkerFactory wf = WalkerFactory.getInstance();    _log.info("\t !isMemoryMode ~> walker / visitor used");    try {      final Walker walker = wf.getWalker(visitor);      walker.walk(pFilter, visitor);      Query query = (Query) walker.getValue();      _log.info("\t walker.getValue() -> query -> \n" + query.toString());      assert (query != null) : "something went wrong by walking the feature filter tree";      if (_ids != null && !_isAllFeatures) {        query = q.constrainQueryByIDs(query, _ids); //constrain by given IDs        _log.info("\t constrained query: \n" + query.toString());      }      final Set resultIDs = q.getIds(query);      _log.info("\t return new FeatureHolderFM(_sourceSeq, resulIds of query)");      return new FeatureHolderFM(_sourceSeq, resultIDs);    } catch (BioException e) {      _log.fatal("Problem getting the walker from WalkerFactory" + e.getMessage());      throw new RuntimeException("Problem getting the walker from WalkerFactory", e);    }  }  /**   * @see FeatureHolder#containsFeature(org.biojava.bio.seq.Feature)   */  public final boolean containsFeature(final Feature pFeature) {    if (pFeature instanceof FeatureFM) { return getFeatures().contains(pFeature); }    return false; //FeatureHolderFM can only hold instances of FeatureFM  }  /**   * @see FeatureHolder#getSchema()   */  public final FeatureFilter getSchema() {    return FeatureFilter.all;  }  // -----------------------------------------------------------------------  // private helpers for implementation of FeatureHolder  // -----------------------------------------------------------------------  /**   * method to get features of this featureHolder. If features are already allocated, simply return.   * Else: depending on the memory mode, create features and return. In memoryMode, the whole   * Feature object is instantiated, in non memory mode, it is lazily instantiated by only passing   * in the id (the Feature itself then can retrive it's data - once it is needed)   *    * @return an ArrayList of features   */  private Collection getFeatures() {    _log.info("getFeatures()");    if (_features == null) {      _log.info("\t features == null");      final QueryFM q = new QueryFM(_chromosomeID);      _features = new HashSet();      if (_sourceSeq.isMemoryMode()) {        _log.info("\t isMemoryMode");        templatesFeatures(q); //memory mode - load all data      } else { //non memory mode - lazy instantiation, Features keep only ID        _log.info("\t !isMemoryMode");        if (_ids == null) {          _log.info("\t ids == null ~> query for ids");          try {            _ids = q.getIds(q.byClass(BioEntity.class));          } catch (ModelExceptionFM e) {            throw new RuntimeException("Not a BioEntity", e);          }        }        assert (_ids != null);        _log.info("\t iterate over ids and add new lazy Features to features");        for (Iterator it = _ids.iterator(); it.hasNext();) {          final Integer id = (Integer) it.next();          _features.add(new FeatureFM(_sourceSeq, id));        }      } //else not in memory    } //if featuresAllocated    return _features;  }  /**   * part of getFeatures() - helper method   *    * @param pQueryFM   *          the QueryFM of getFeatures()   */  private void templatesFeatures(final QueryFM pQueryFM) {    final Map map;    if (_isAllFeatures) {      _log.info("\t isAllFeatures");      //if this featureHolder has ALL features of the underlying chromosome      _log.info("\t get map [ID-Template], iterate and add !lazy new Features to features");      map = (pQueryFM.getTemplate(null)); //get ALL feature templates of this sequence      for (Iterator it = map.keySet().iterator(); it.hasNext();) {        final Integer id = (Integer) it.next();        final StrandedFeature.Template templ = (StrandedFeature.Template) map.get(id);        _features.add(new FeatureFM(_sourceSeq, id, templ));      }    } else { //if subset of all features      _log.info("\t !isAllFeaures");      map = new HashMap();      //if this featureHolder keeps only a subset of features of the underlying chromosome      final int packageSize = 10000; //chop ids to bunches of 10000's - avoid too complex sql query      _log.info("\t get.Templates of given IDs");      final Iterator iterateIds = _ids.iterator();      for (int i = 0; i < _ids.size(); i += packageSize) {        for (int j = i; j < (i + packageSize); j++) {          final Set bunchOfIds = new HashSet();          if (iterateIds.hasNext()) {            bunchOfIds.add(iterateIds.next());          } else {            break;          }          map.putAll(pQueryFM.getTemplate(bunchOfIds));        } //inner for        if (!iterateIds.hasNext()) {          break;        }      } //outer for      _log.info("\t iterate map [ID-Template] and add !lazy features to features");      for (Iterator it = map.keySet().iterator(); it.hasNext();) {        final Integer id = (Integer) it.next();        final StrandedFeature.Template templ = (StrandedFeature.Template) map.get(id);        _features.add(new FeatureFM(_sourceSeq, id, templ));      }    } //else  }  }