+ /**
+ *
+ * @return mapping from positions in S1 to corresponding positions in S2
+ */
+ public jalview.datamodel.Mapping getMappingFromS1(boolean allowmismatch)
+ {
+ ArrayList<Integer> as1 = new ArrayList<Integer>(),
+ as2 = new ArrayList<Integer>();
+ int pdbpos = s2.getStart() + getSeq2Start() - 2;
+ int alignpos = s1.getStart() + getSeq1Start() - 2;
+ int lp2 = pdbpos - 3, lp1 = alignpos - 3;
+ boolean lastmatch = false;
+ // and now trace the alignment onto the atom set.
+ for (int i = 0; i < astr1.length(); i++)
+ {
+ char c1 = astr1.charAt(i), c2 = astr2.charAt(i);
+ if (c1 != '-')
+ {
+ alignpos++;
+ }
+
+ if (c2 != '-')
+ {
+ pdbpos++;
+ }
+
+ // ignore case differences
+ if (allowmismatch || (c1 == c2) || (Math.abs(c2-c1)==('a'-'A')))
+ {
+ // extend mapping interval
+ if (lp1 + 1 != alignpos || lp2 + 1 != pdbpos)
+ {
+ as1.add(Integer.valueOf(alignpos));
+ as2.add(Integer.valueOf(pdbpos));
+ }
+ lastmatch = true;
+ lp1 = alignpos;
+ lp2 = pdbpos;
+ }
+ else
+ {
+ // extend mapping interval
+ if (lastmatch)
+ {
+ as1.add(Integer.valueOf(lp1));
+ as2.add(Integer.valueOf(lp2));
+ }
+ lastmatch = false;
+ }
+ }
+ // construct range pairs
+
+ int[] mapseq1 = new int[as1.size() + (lastmatch ? 1 : 0)],
+ mapseq2 = new int[as2.size() + (lastmatch ? 1 : 0)];
+ int i = 0;
+ for (Integer ip : as1)
+ {
+ mapseq1[i++] = ip;
+ }
+ ;
+ i = 0;
+ for (Integer ip : as2)
+ {
+ mapseq2[i++] = ip;
+ }
+ ;
+ if (lastmatch)
+ {
+ mapseq1[mapseq1.length - 1] = alignpos;
+ mapseq2[mapseq2.length - 1] = pdbpos;
+ }
+ MapList map = new MapList(mapseq1, mapseq2, 1, 1);
+
+ jalview.datamodel.Mapping mapping = new Mapping(map);
+ mapping.setTo(s2);
+ return mapping;
+ }
+
+ /**
+ * matches ochains against al and populates seqs with the best match between
+ * each ochain and the set in al
+ *
+ * @param ochains
+ * @param al
+ * @param dnaOrProtein
+ * @param removeOldAnnots
+ * when true, old annotation is cleared before new annotation
+ * transferred
+ * @return List<List<SequenceI> originals, List<SequenceI> replacement,
+ * List<AlignSeq> alignment between each>
+ */
+ public static List<List<? extends Object>> replaceMatchingSeqsWith(
+ List<SequenceI> seqs, List<AlignmentAnnotation> annotations,
+ List<SequenceI> ochains, AlignmentI al, String dnaOrProtein,
+ boolean removeOldAnnots)
+ {
+ List<SequenceI> orig = new ArrayList<SequenceI>(),
+ repl = new ArrayList<SequenceI>();
+ List<AlignSeq> aligs = new ArrayList<AlignSeq>();
+ if (al != null && al.getHeight() > 0)
+ {
+ ArrayList<SequenceI> matches = new ArrayList<SequenceI>();
+ ArrayList<AlignSeq> aligns = new ArrayList<AlignSeq>();
+
+ for (SequenceI sq : ochains)
+ {
+ SequenceI bestm = null;
+ AlignSeq bestaseq = null;
+ float bestscore = 0;
+ for (SequenceI msq : al.getSequences())
+ {
+ AlignSeq aseq = doGlobalNWAlignment(msq, sq, dnaOrProtein);
+ if (bestm == null || aseq.getMaxScore() > bestscore)
+ {
+ bestscore = aseq.getMaxScore();
+ bestaseq = aseq;
+ bestm = msq;
+ }
+ }
+ // System.out.println("Best Score for " + (matches.size() + 1) + " :"
+ // + bestscore);
+ matches.add(bestm);
+ aligns.add(bestaseq);
+ al.deleteSequence(bestm);
+ }
+ for (int p = 0, pSize = seqs.size(); p < pSize; p++)
+ {
+ SequenceI sq, sp = seqs.get(p);
+ int q;
+ if ((q = ochains.indexOf(sp)) > -1)
+ {
+ seqs.set(p, sq = matches.get(q));
+ orig.add(sp);
+ repl.add(sq);
+ sq.setName(sp.getName());
+ sq.setDescription(sp.getDescription());
+ Mapping sp2sq;
+ sq.transferAnnotation(sp,
+ sp2sq = aligns.get(q).getMappingFromS1(false));
+ aligs.add(aligns.get(q));
+ int inspos = -1;
+ for (int ap = 0; ap < annotations.size();)
+ {
+ if (annotations.get(ap).sequenceRef == sp)
+ {
+ if (inspos == -1)
+ {
+ inspos = ap;
+ }
+ if (removeOldAnnots)
+ {
+ annotations.remove(ap);
+ }
+ else
+ {
+ AlignmentAnnotation alan = annotations.remove(ap);
+ alan.liftOver(sq, sp2sq);
+ alan.setSequenceRef(sq);
+ sq.addAlignmentAnnotation(alan);
+ }
+ }
+ else
+ {
+ ap++;
+ }
+ }
+ if (sq.getAnnotation() != null && sq.getAnnotation().length > 0)
+ {
+ annotations.addAll(inspos == -1 ? annotations.size() : inspos,
+ Arrays.asList(sq.getAnnotation()));
+ }
+ }
+ }
+ }
+ return Arrays.asList(orig, repl, aligs);
+ }