entry : featureStore.entrySet())
{
String type = entry.getKey();
if (!entry.getValue().isEmpty() && isOntologyTerm(type, soTerm))
{
types.add(type);
}
}
return types;
}
/**
* Answers true if the given type matches one of the specified terms (or is a
* sub-type of one in the Sequence Ontology), or if no terms are supplied.
* Answers false if filter terms are specified and the given term does not
* match any of them.
*
* @param type
* @param soTerm
* @return
*/
protected boolean isOntologyTerm(String type, String... soTerm)
{
if (soTerm == null || soTerm.length == 0)
{
return true;
}
SequenceOntologyI so = SequenceOntologyFactory.getSequenceOntology();
for (String term : soTerm)
{
if (type.equals(term) || so.isA(type, term))
{
return true;
}
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public float getMinimumScore(String type, boolean positional)
{
return featureStore.containsKey(type) ? featureStore.get(type)
.getMinimumScore(positional) : Float.NaN;
}
/**
* {@inheritDoc}
*/
@Override
public float getMaximumScore(String type, boolean positional)
{
return featureStore.containsKey(type) ? featureStore.get(type)
.getMaximumScore(positional) : Float.NaN;
}
/**
* A convenience method to sort features by start position ascending (if on
* forward strand), or end position descending (if on reverse strand)
*
* @param features
* @param forwardStrand
*/
public static void sortFeatures(List extends IntervalI> features,
final boolean forwardStrand)
{
IntervalI.sortIntervals(features, forwardStrand);
}
/**
* {@inheritDoc} This method is 'semi-optimised': it only inspects features
* for types that include the specified group, but has to inspect every
* feature of those types for matching feature group. This is efficient unless
* a sequence has features that share the same type but are in different
* groups - an unlikely case.
*
* For example, if RESNUM feature is created with group = PDBID, then features
* would only be retrieved for those sequences associated with the target
* PDBID (group).
*/
@Override
public List getFeaturesForGroup(boolean positional,
String group, String... type)
{
List result = new ArrayList<>();
for (FeatureStoreI featureSet : varargToTypes(type))
{
if (featureSet.getFeatureGroups(positional).contains(group))
{
result.addAll(featureSet.getFeaturesForGroup(positional, group));
}
}
return result;
}
/**
* {@inheritDoc}
*/
@Override
public boolean shiftFeatures(int fromPosition, int shiftBy)
{
boolean modified = false;
for (FeatureStoreI fs : featureStore.values())
{
modified |= fs.shiftFeatures(fromPosition, shiftBy);
}
return modified;
}
/**
* {@inheritDoc}
*/
@Override
public void deleteAll()
{
featureStore.clear();
}
/**
* Simplified find for features associated with a given position.
*
* JavaScript set to not use IntervalI, but easily testable by setting false
* to true in javadoc
*
* FeatureRenderer has checked already that featureStore does contain type.
*
* @author Bob Hanson 2019.07.30
*/
@Override
public List findFeatures(int pos, String type,
List list)
{
FeatureStoreI fs = featureStore.get(type);
return fs.findOverlappingFeatures(pos, pos, list);
}
// Chrome; developer console closed
// BH 2019.08.01 useIntervalStore true, redraw false:
// Platform: timer mark 13.848 0.367 overviewrender 16000 pixels row:14
// Platform: timer mark 15.391 0.39 overviewrender 16000 pixels row:14
// Platform: timer mark 16.498 0.39 overviewrender 16000 pixels row:14
// Platform: timer mark 17.596 0.401 overviewrender 16000 pixels row:14
// Platform: timer mark 18.738 0.363 overviewrender 16000 pixels row:14
// Platform: timer mark 19.659 0.358 overviewrender 16000 pixels row:14
// Platform: timer mark 20.737 0.359 overviewrender 16000 pixels row:14
// Platform: timer mark 21.797 0.391 overviewrender 16000 pixels row:14
// Platform: timer mark 22.851 0.361 overviewrender 16000 pixels row:14
// Platform: timer mark 24.019 0.395 overviewrender 16000 pixels row:14
// BH 2019.08.01 useIntervalStore false, redraw false:
// Platform: timer mark 19.011 0.181 overviewrender 16000 pixels row:14
// Platform: timer mark 20.311 0.183 overviewrender 16000 pixels row:14
// Platform: timer mark 21.368 0.175 overviewrender 16000 pixels row:14
// Platform: timer mark 22.347 0.178 overviewrender 16000 pixels row:14
// Platform: timer mark 23.605 0.216 overviewrender 16000 pixels row:14
// Platform: timer mark 24.836 0.191 overviewrender 16000 pixels row:14
// Platform: timer mark 26.016 0.181 overviewrender 16000 pixels row:14
// Platform: timer mark 27.278 0.178 overviewrender 16000 pixels row:14
// Platform: timer mark 28.158 0.181 overviewrender 16000 pixels row:14
// Platform: timer mark 29.227 0.196 overviewrender 16000 pixels row:14
// Platform: timer mark 30.1 0.171 overviewrender 16000 pixels row:14
// Platform: timer mark 31.684 0.196 overviewrender 16000 pixels row:14
// Platform: timer mark 32.779 0.18 overviewrender 16000 pixels row:14
// Platform: timer mark 52.355 0.185 overviewrender 16000 pixels row:14
// Platform: timer mark 53.829 0.186 overviewrender 16000 pixels row:14
/**
* @author Bob Hanson 2019.08.01
*/
@Override
public boolean hasFeatures(String type)
{
return featureStore.containsKey(type);
}
}