+ * Returns a consolidated list of column ranges where at least one sequence
+ * has a CDS feature. This assumes CDS features are on genomic sequence i.e.
+ * are for contiguous CDS ranges (no gaps).
+ *
+ * @param seqs
+ * @return
+ */
+ public static List<int[]> findCdsColumns(SequenceI[] seqs)
+ {
+ // TODO use refactored code from AlignViewController
+ // markColumnsContainingFeatures, not reinvent the wheel!
+
+ List<int[]> result = new ArrayList<int[]>();
+ for (SequenceI seq : seqs)
+ {
+ result.addAll(findCdsColumns(seq));
+ }
+
+ /*
+ * sort and compact the list into ascending, non-overlapping ranges
+ */
+ Collections.sort(result, new Comparator<int[]>()
+ {
+ @Override
+ public int compare(int[] o1, int[] o2)
+ {
+ return Integer.compare(o1[0], o2[0]);
+ }
+ });
+ result = MapList.coalesceRanges(result);
+
+ return result;
+ }
+
+ public static List<int[]> findCdsColumns(SequenceI seq)
+ {
+ List<int[]> result = new ArrayList<int[]>();
+ SequenceOntologyI so = SequenceOntologyFactory.getInstance();
+ SequenceFeature[] sfs = seq.getSequenceFeatures();
+ if (sfs != null)
+ {
+ for (SequenceFeature sf : sfs)
+ {
+ if (so.isA(sf.getType(), SequenceOntologyI.CDS))
+ {
+ int colStart = seq.findIndex(sf.getBegin());
+ int colEnd = seq.findIndex(sf.getEnd());
+ result.add(new int[] { colStart, colEnd });
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Answers true if all sequences have a gap at (or do not extend to) the
+ * specified column position (base 1)
+ *
+ * @param seqs
+ * @param col
+ * @return
+ */
+ public static boolean isGappedColumn(List<SequenceI> seqs, int col)
+ {
+ if (seqs != null)
+ {
+ for (SequenceI seq : seqs)
+ {
+ if (!Comparison.isGap(seq.getCharAt(col - 1)))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns the column ranges (base 1) of each aligned sequence that are
+ * involved in any mapping. This is a helper method for aligning protein
+ * products of aligned transcripts.
+ *
+ * @param mappedSequences
+ * (possibly gapped) dna sequences
+ * @param mappings
+ * @return
+ */
+ protected static List<List<int[]>> getMappedColumns(
+ List<SequenceI> mappedSequences,
+ List<AlignedCodonFrame> mappings)
+ {
+ List<List<int[]>> result = new ArrayList<List<int[]>>();
+ for (SequenceI seq : mappedSequences)
+ {
+ List<int[]> columns = new ArrayList<int[]>();
+ List<AlignedCodonFrame> seqMappings = MappingUtils
+ .findMappingsForSequence(seq, mappings);
+ for (AlignedCodonFrame mapping : seqMappings)
+ {
+ List<Mapping> maps = mapping.getMappingsForSequence(seq);
+ for (Mapping map : maps)
+ {
+ /*
+ * Get the codon regions as { [2, 5], [7, 12], [14, 14] etc }
+ * Find and add the overall aligned column range for each
+ */
+ for (int[] cdsRange : map.getMap().getFromRanges())
+ {
+ int startPos = cdsRange[0];
+ int endPos = cdsRange[1];
+ int startCol = seq.findIndex(startPos);
+ int endCol = seq.findIndex(endPos);
+ columns.add(new int[] { startCol, endCol });
+ }
+ }
+ }
+ result.add(columns);
+ }
+ return result;
+ }
+
+ /**