+package jalview.analysis;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.AlignmentI;
+
+/**
+ * grab bag of useful alignment manipulation operations
+ * Expect these to be refactored elsewhere at some point.
+ * @author jimp
+ *
+ */
+public class AlignmentUtils
+{
+
+ /**
+ * given an existing alignment, create a new alignment including all, or up to flankSize additional symbols from each sequence's dataset sequence
+ * @param core
+ * @param flankSize
+ * @return AlignmentI
+ */
+ public static AlignmentI expandContext(AlignmentI core, int flankSize)
+ {
+ List<SequenceI> sq = new ArrayList<SequenceI>();
+ int maxoffset = 0;
+ for (SequenceI s:core.getSequences())
+ {
+ SequenceI newSeq = s.deriveSequence();
+ if (newSeq.getStart()>maxoffset)
+ {
+ maxoffset = newSeq.getStart();
+ }
+ sq.add(newSeq);
+ }
+ if (flankSize>-1) {
+ maxoffset = flankSize;
+ }
+ // now add offset to create a new expanded alignment
+ for (SequenceI s:sq)
+ {
+ SequenceI ds = s;
+ while (ds.getDatasetSequence()!=null) {
+ ds=ds.getDatasetSequence();
+ }
+ // find available flanking residues for sequence
+ int ustream_ds=s.getStart()-ds.getStart(),dstream_ds=ds.getEnd()-s.getEnd();
+
+ // build new flanked sequence
+
+ // compute gap padding to start of flanking sequence
+ int offset=maxoffset - ustream_ds;
+
+ // padding is gapChar x ( maxoffset - min(ustream_ds, flank)
+ if (flankSize>=0) {
+ if (flankSize<ustream_ds)
+ {
+ // take up to flankSize residues
+ offset = maxoffset-flankSize;
+ ustream_ds = flankSize;
+ }
+ if (flankSize<dstream_ds)
+ {
+ dstream_ds=flankSize;
+ }
+ }
+ char[] upstream = new String(ds.getSequence(s.getStart()-1-ustream_ds, s.getStart()-1)).toLowerCase().toCharArray();
+ char[] downstream = new String(ds.getSequence(s.getEnd()+1,s.getEnd()+1+dstream_ds)).toLowerCase().toCharArray();
+ char[] coreseq=s.getSequence();
+ char[] nseq = new char[offset+upstream.length+downstream.length+coreseq.length];
+ char c = core.getGapCharacter();
+ // TODO could lowercase the flanking regions
+ int p=0;
+ for (; p<offset;p++)
+ {
+ nseq[p] = c;
+ }
+// s.setSequence(new String(upstream).toLowerCase()+new String(coreseq) + new String(downstream).toLowerCase());
+ System.arraycopy(upstream, 0, nseq, p, upstream.length);
+ System.arraycopy(coreseq, 0, nseq, p+upstream.length, coreseq.length);
+ System.arraycopy(downstream, 0, nseq, p+coreseq.length+upstream.length, downstream.length);
+ s.setSequence(new String(nseq));
+ s.setStart(s.getStart()-ustream_ds);
+ s.setEnd(s.getEnd()+downstream.length);
+ }
+ AlignmentI newAl = new jalview.datamodel.Alignment(sq.toArray(new SequenceI[0]));
+ newAl.setDataset(core.getDataset());
+ return newAl;
+ }
+}