/** * Provided only for convenience. * * @see #fastaToAfpChain(ProteinSequence, ProteinSequence, Structure, Structure) * @throws StructureException */ public static AFPChain fastaToAfpChain( SequencePair<Sequence<AminoAcidCompound>, AminoAcidCompound> alignment, Structure structure1, Structure structure2) throws StructureException { List<AlignedSequence<Sequence<AminoAcidCompound>, AminoAcidCompound>> seqs = alignment.getAlignedSequences(); StringBuilder sb1 = new StringBuilder(); for (AminoAcidCompound a : seqs.get(0)) { sb1.append(a.getBase()); } try { ProteinSequence seq1 = new ProteinSequence(sb1.toString()); StringBuilder sb2 = new StringBuilder(); for (AminoAcidCompound a : seqs.get(1)) { sb1.append(a.getBase()); } ProteinSequence seq2 = new ProteinSequence(sb2.toString()); LinkedHashMap<String, ProteinSequence> map = new LinkedHashMap<String, ProteinSequence>(); map.put(structure1.getName(), seq1); map.put(structure2.getName(), seq2); return fastaToAfpChain(map, structure1, structure2); } catch (CompoundNotFoundException e) { logger.error( "Unexpected error while creating protein sequences: {}. This is most likely a bug.", e.getMessage()); return null; } }
/** * Print an alignment map in a concise representation. Edges are given as two numbers separated by * '>'. They are chained together where possible, or separated by spaces where disjoint or * branched. * * <p>Note that more concise representations may be possible. Examples: * <li>1>2>3>1 * <li>1>2>3>2 4>3 * * @param alignment The input function, as a map (see {@link * AlignmentTools#alignmentAsMap(AFPChain)}) * @param identity An identity-like function providing the isomorphism between the codomain of * alignment (of type <T>) and the domain (type <S>). * @return */ public static <S, T> String toConciseAlignmentString(Map<S, T> alignment, Map<T, S> identity) { // Clone input to prevent changes Map<S, T> alig = new HashMap<S, T>(alignment); // Generate inverse alignment Map<S, List<S>> inverse = new HashMap<S, List<S>>(); for (Entry<S, T> e : alig.entrySet()) { S val = identity.get(e.getValue()); if (inverse.containsKey(val)) { List<S> l = inverse.get(val); l.add(e.getKey()); } else { List<S> l = new ArrayList<S>(); l.add(e.getKey()); inverse.put(val, l); } } StringBuilder str = new StringBuilder(); while (!alig.isEmpty()) { // Pick an edge and work upstream to a root or cycle S seedNode = alig.keySet().iterator().next(); S node = seedNode; if (inverse.containsKey(seedNode)) { node = inverse.get(seedNode).iterator().next(); while (node != seedNode && inverse.containsKey(node)) { node = inverse.get(node).iterator().next(); } } // Now work downstream, deleting edges as we go seedNode = node; str.append(node); while (alig.containsKey(node)) { S lastNode = node; node = identity.get(alig.get(lastNode)); // Output str.append('>'); str.append(node); // Remove edge alig.remove(lastNode); List<S> inv = inverse.get(node); if (inv.size() > 1) { inv.remove(node); } else { inverse.remove(node); } } if (!alig.isEmpty()) { str.append(' '); } } return str.toString(); }