+
+ @Override
+ public List<SequenceFeature[]> adjustFeatures(int fromColumn, int toColumn)
+ {
+ List<SequenceFeature[]> amended = new ArrayList<>();
+
+ if (toColumn < fromColumn)
+ {
+ return amended;
+ }
+
+ synchronized (sequenceFeatureStore)
+ {
+ /*
+ * get features that overlap or span the cut region
+ */
+ List<SequenceFeature> overlaps = findFeatures(fromColumn, toColumn);
+ int cutWidth = toColumn - fromColumn + 1;
+
+ /*
+ * get features that strictly follow the cut region,
+ * and shift them left by the width of the cut
+ */
+ List<SequenceFeature> follow = findFeatures(toColumn + 1,
+ Integer.MAX_VALUE);
+ follow.removeAll(overlaps);
+ for (SequenceFeature sf : follow)
+ {
+ SequenceFeature copy = new SequenceFeature(sf, sf.getBegin()
+ - cutWidth, sf.getEnd() - cutWidth, sf.getFeatureGroup(),
+ sf.getScore());
+ deleteFeature(sf);
+ addSequenceFeature(copy);
+ }
+
+ /*
+ * adjust start-end of overlapping features, and delete if enclosed by
+ * the cut, or a partially overlapping contact feature
+ */
+ for (SequenceFeature sf : overlaps)
+ {
+ // TODO recode to compute newBegin, newEnd, isDelete
+ // then perform the action
+ int sfBegin = sf.getBegin();
+ int sfEnd = sf.getEnd();
+ int startCol = findIndex(sfBegin);
+ int endCol = findIndex(sfEnd);
+ if (startCol >= fromColumn && endCol <= toColumn)
+ {
+ // within cut region - delete feature
+ deleteFeature(sf);
+ amended.add(new SequenceFeature[] { sf, null });
+ continue;
+ }
+ if (startCol < fromColumn && endCol > toColumn)
+ {
+ // feature spans cut region - shift end left
+ SequenceFeature copy = new SequenceFeature(sf, sf.getBegin(),
+ sf.getEnd() - cutWidth, sf.getFeatureGroup(),
+ sf.getScore());
+ deleteFeature(sf);
+ addSequenceFeature(copy);
+ amended.add(new SequenceFeature[] { sf, copy });
+ continue;
+ }
+ // todo partial overlap - delete if contact feature
+ }
+ }
+
+ return amended;
+ }