+ out.append(STARTGROUP).append(TAB).append(group).append(newline);
+ }
+ Map<String, List<SequenceFeature>> seqFeaturesMap = groupFeatures
+ .getValue();
+ for (Entry<String, List<SequenceFeature>> seqFeatures : seqFeaturesMap
+ .entrySet())
+ {
+ String sequenceName = seqFeatures.getKey();
+ for (SequenceFeature sf : seqFeatures.getValue())
+ {
+ formatJalviewFeature(out, sequenceName, sf);
+ }
+ }
+ if (!"".equals(group))
+ {
+ out.append(ENDGROUP).append(TAB).append(group).append(newline);
+ }
+ }
+
+ return count;
+ }
+
+ /**
+ * Answers a list of mapped features visible in the (CDS/protein) complement,
+ * with feature positions translated to local sequence coordinates
+ *
+ * @param seq
+ * @param fr2
+ * @return
+ */
+ protected List<SequenceFeature> findComplementaryFeatures(SequenceI seq,
+ FeatureRenderer fr2)
+ {
+ /*
+ * avoid duplication of features (e.g. peptide feature
+ * at all 3 mapped codon positions)
+ */
+ List<SequenceFeature> found = new ArrayList<>();
+ List<SequenceFeature> complementary = new ArrayList<>();
+
+ for (int pos = seq.getStart(); pos <= seq.getEnd(); pos++)
+ {
+ MappedFeatures mf = fr2.findComplementFeaturesAtResidue(seq, pos);
+
+ if (mf != null)
+ {
+ MapList mapping = mf.mapping.getMap();
+ for (SequenceFeature sf : mf.features)
+ {
+ /*
+ * make a virtual feature with local coordinates
+ */
+ if (!found.contains(sf))
+ {
+ String group = sf.getFeatureGroup();
+ if (group == null)
+ {
+ group = "";
+ }
+ found.add(sf);
+ int begin = sf.getBegin();
+ int end = sf.getEnd();
+ int[] range = mf.mapping.getTo() == seq.getDatasetSequence()
+ ? mapping.locateInTo(begin, end)
+ : mapping.locateInFrom(begin, end);
+ SequenceFeature sf2 = new SequenceFeature(sf, range[0],
+ range[1], group, sf.getScore());
+ complementary.add(sf2);
+ }
+ }