package nl.tudelft.lifetiles.graph.traverser; import java.util.Iterator; import nl.tudelft.lifetiles.core.util.IteratorUtils; import nl.tudelft.lifetiles.core.util.Timer; import nl.tudelft.lifetiles.graph.model.BreadthFirstIterator; import nl.tudelft.lifetiles.graph.model.Edge; import nl.tudelft.lifetiles.graph.model.Graph; import nl.tudelft.lifetiles.sequence.model.Sequence; import nl.tudelft.lifetiles.sequence.model.SequenceSegment; /** * Traverser which generates for each segment the coordinates in comparison with * the reference sequence. * * @author Jos * @author Joren Hammudoglu * */ public final class ReferencePositionTraverser { /** * Don't instantiate. */ private ReferencePositionTraverser() { } /** * Traverses the graph. Computes the position of the vertices in * comparison * to the reference sequence. Reference coordinates are needed to indicate * mutations. * * @param graph * Graph to be traversed. * @param reference * The reference sequence. */ public static void referenceMapGraph(final Graph<SequenceSegment> graph, final Sequence reference) { Timer timer = Timer.getAndStart(); referenceMapGraphForward(graph, reference); referenceMapGraphBackward(graph, reference); timer.stopAndLog("Mapping graph onto reference"); } /** * Traverses the graph forward to generate reference start * positions. * * @param graph * Graph to be traversed. * @param reference * The reference sequence. */ private static void referenceMapGraphForward( final Graph<SequenceSegment> graph, final Sequence reference) { for (SequenceSegment source : graph.getSources()) { source.setReferenceStart(1); } Iterator<SequenceSegment> iterator = new BreadthFirstIterator<>(graph); for (SequenceSegment vertex : IteratorUtils.toIterable(iterator)) { long position = vertex.getReferenceStart(); if (vertex.getSources().contains(reference) && !vertex.getContent().isEmpty()) { position += vertex.getContent().getLength(); } for (Edge<SequenceSegment> edge : graph.getOutgoing(vertex)) { SequenceSegment destination = graph.getDestination(edge); if (destination.getReferenceStart() < position) { destination.setReferenceStart(position); } } } } /** * Traverses the graph backward to generate reference end position. * * @param graph * Graph to be traversed. * @param reference * The reference sequence. */ private static void referenceMapGraphBackward( final Graph<SequenceSegment> graph, final Sequence reference) { for (SequenceSegment sink : graph.getSinks()) { long referenceEnd = sink.getReferenceStart() - 1; if (sink.getSources().contains(reference)) { referenceEnd += sink.getContent().getLength(); } sink.setReferenceEnd(referenceEnd); } Iterator<SequenceSegment> iterator = new BreadthFirstIterator<>(graph, true); for (SequenceSegment vertex : IteratorUtils.toIterable(iterator)) { long position = vertex.getReferenceEnd(); if (vertex.getSources().contains(reference) && !vertex.getContent().isEmpty()) { position -= vertex.getContent().getLength(); } for (Edge<SequenceSegment> edge : graph.getIncoming(vertex)) { SequenceSegment source = graph.getSource(edge); if (source.getReferenceEnd() > position) { source.setReferenceEnd(position); } } } } }