X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=srcjar%2Ffr%2Forsay%2Flri%2Fvarna%2Fmodels%2Ftreealign%2FRNATree.java;fp=srcjar%2Ffr%2Forsay%2Flri%2Fvarna%2Fmodels%2Ftreealign%2FRNATree.java;h=8a72fbfcdb618f7d829d9972d11b4f078569b3a4;hb=ec8f3cedf60fb1feed6d34de6b49f6bfa78b9dd8;hp=0000000000000000000000000000000000000000;hpb=056dad85a910551cc95e44d451a61f6b8c4dd35d;p=jalview.git diff --git a/srcjar/fr/orsay/lri/varna/models/treealign/RNATree.java b/srcjar/fr/orsay/lri/varna/models/treealign/RNATree.java new file mode 100644 index 0000000..8a72fbf --- /dev/null +++ b/srcjar/fr/orsay/lri/varna/models/treealign/RNATree.java @@ -0,0 +1,158 @@ +package fr.orsay.lri.varna.models.treealign; + +import java.util.ArrayList; +import java.util.List; + +import fr.orsay.lri.varna.exceptions.MappingException; +import fr.orsay.lri.varna.models.rna.Mapping; +import fr.orsay.lri.varna.models.rna.ModeleBase; +import fr.orsay.lri.varna.models.rna.ModeleBaseNucleotide; +import fr.orsay.lri.varna.models.rna.ModeleBP; +import fr.orsay.lri.varna.models.rna.RNA; + + + +/** + * This class contains all functions that are specific to trees + * (class Tree) of RNA. + * + * @author Raphael Champeimont + * + */ +public class RNATree { + /** + * Convert an RNA object into a RNA tree. + * The root node will have a null value because it is a fake + * node added to have a tree (otherwise we would have a forest). + */ + public static Tree RNATreeFromRNA(RNA rna) { + ConvertToTree converter = new ConvertToTree(rna); + return converter.toTreeAux(0); + } + + private static class ConvertToTree { + private RNA rna; + + private int i = 0; + + /** Starts at the current position i in the sequence and converts the sequence + * to a tree. + * @return the created tree + */ + public Tree toTreeAux(int depth) { + Tree tree = new Tree(); + List> children = tree.getChildren(); + // No value because it is a fake root + tree.setValue(null); + + int length = rna.getSize(); + while (i < length) { + ModeleBase base = rna.getBaseAt(i); + int indexOfAssociatedBase = base.getElementStructure(); + if (indexOfAssociatedBase >= 0) { + if (indexOfAssociatedBase > i) { + // left parenthesis, we must analyze the children + RNANodeValue childValue = new RNANodeValue(); + childValue.setLeftBasePosition(i); + childValue.setRightBasePosition(indexOfAssociatedBase); + childValue.setOrigin(RNANodeValue.Origin.BASE_PAIR_FROM_HELIX); + + if (base instanceof ModeleBaseNucleotide) { + childValue.setLeftNucleotide(((ModeleBaseNucleotide) base).getBase()); + childValue.setRightNucleotide(((ModeleBaseNucleotide) rna.getBaseAt(indexOfAssociatedBase)).getBase()); + } + i++; + Tree child = toTreeAux(depth+1); + child.setValue(childValue); + children.add(child); + } else { + // right parenthesis, we have finished analyzing the children + i++; + break; + } + } else { + // we have a non-paired base + Tree child = new Tree(); + RNANodeValue childValue = new RNANodeValue(); + childValue.setLeftBasePosition(i); + if (base instanceof ModeleBaseNucleotide) { + childValue.setLeftNucleotide(((ModeleBaseNucleotide) base).getBase()); + } + + // Even in this case (getElementStructure() < 0) + // this base may still come from an helix which may have + // been broken to remove a pseudoknot. + childValue.setOrigin(RNANodeValue.Origin.BASE_FROM_UNPAIRED_REGION); + ArrayList auxBasePairs = rna.getAuxBPs(i); + for (ModeleBP auxBasePair: auxBasePairs) { + if (auxBasePair.isCanonical()) { + int partner5 = ((ModeleBaseNucleotide) auxBasePair.getPartner5()).getIndex(); + int partner3 = ((ModeleBaseNucleotide) auxBasePair.getPartner3()).getIndex(); + if (i == partner5) { + childValue.setOrigin(RNANodeValue.Origin.BASE_FROM_HELIX_STRAND5); + } else if (i == partner3) { + childValue.setOrigin(RNANodeValue.Origin.BASE_FROM_HELIX_STRAND3); + } else { + System.err.println("Warning: Base index is " + i + " but neither endpoint matches it (edge endpoints are " + partner5 + " and " + partner3 + ")."); + } + + } + } + + child.setValue(childValue); + children.add(child); + i++; + } + } + + return tree; + } + + public ConvertToTree(RNA rna) { + this.rna = rna; + } + } + + + /** + * Convert an RNA tree alignment into a Mapping. + */ + public static Mapping mappingFromAlignment(Tree> alignment) throws MappingException { + ConvertToMapping converter = new ConvertToMapping(); + return converter.convert(alignment); + } + + private static class ConvertToMapping { + private Mapping m; + + public Mapping convert(Tree> tree) throws MappingException { + m = new Mapping(); + convertSubTree(tree); + return m; + } + + private void convertSubTree(Tree> tree) throws MappingException { + AlignedNode alignedNode = tree.getValue(); + Tree leftNode = alignedNode.getLeftNode(); + Tree rightNode = alignedNode.getRightNode(); + if (leftNode != null && rightNode != null) { + RNANodeValue v1 = leftNode.getValue(); + RNANodeValue v2 = rightNode.getValue(); + int l1 = v1.getLeftBasePosition(); + int r1 = v1.getRightBasePosition(); + int l2 = v2.getLeftBasePosition(); + int r2 = v2.getRightBasePosition(); + if (l1 >= 0 && l2 >= 0) { + m.addCouple(l1, l2); + } + if (r1 >= 0 && r2 >= 0) { + m.addCouple(r1, r2); + } + } + for (Tree> child: tree.getChildren()) { + convertSubTree(child); + } + } + } + +}