package nl.tudelft.lifetiles.graph.model; import java.util.Set; import java.util.TreeSet; import nl.tudelft.lifetiles.core.util.SetUtils; import nl.tudelft.lifetiles.core.util.Settings; import nl.tudelft.lifetiles.core.util.Timer; import nl.tudelft.lifetiles.graph.traverser.EmptySegmentTraverser; import nl.tudelft.lifetiles.graph.traverser.MutationIndicationTraverser; import nl.tudelft.lifetiles.graph.traverser.ReferencePositionTraverser; import nl.tudelft.lifetiles.graph.traverser.UnifiedPositionTraverser; import nl.tudelft.lifetiles.sequence.model.Sequence; import nl.tudelft.lifetiles.sequence.model.SequenceSegment; /** * The Tile holds the graph and will be transformed to this modelgraph so * that the graph can be drawn on the screen. * */ public class GraphContainer { /** * The setting key for empty segments. */ private static final String SETTING_EMPTY = "empty_segments"; /** * The setting key for mutation indication. */ private static final String SETTING_MUTATION = "mutations"; /** * The Current graph that this model is holding. */ private final Graph<SequenceSegment> graph; /** * The Current graph that this model is holding in bucket cache form. */ private final BucketCache segmentBuckets; /** * The set of currently visible sequencesegments. */ private Set<SequenceSegment> visibles; /** * The set of visible sequences. */ private Set<Sequence> visibleSequences; /** * The minimap model. */ private MiniMap miniMap; /** * The amount of vertices to be placed in one bucket. */ private static final int VERTICES_BUCKET = Integer.parseInt(Settings .get("num_vertices_bucket")); /** * create a new Tile. * * @param graph * The initial graph * @param reference * Reference currently active in the graph controller. */ public GraphContainer(final Graph<SequenceSegment> graph, final Sequence reference) { this.graph = graph; for (SequenceSegment segment : this.graph.getAllVertices()) { segment.setReferenceStart(1); segment.setReferenceEnd(Long.MAX_VALUE); segment.setMutation(null); } alignGraph(); if (reference != null) { findMutations(reference); } segmentBuckets = new BucketCache(Math.max(1, graph.getAllVertices() .size() / VERTICES_BUCKET), this.graph); visibles = graph.getAllVertices(); } /** * @return the {@link MiniMap} model */ public final MiniMap getMiniMap() { if (this.miniMap == null) { miniMap = new MiniMap(segmentBuckets); } return miniMap; } /** * Aligns the graph by calculating the unified positions of the segments * and if set also generates the empty segments. */ private void alignGraph() { UnifiedPositionTraverser.unifyGraph(graph); if (Settings.getBoolean(SETTING_EMPTY)) { EmptySegmentTraverser.addEmptySegmentsGraph(graph); } } /** * Find the mutations on the graph if set, by calculating the reference * positions of the segments. * * @param reference * Reference of the graph which is used to indicate mutations. */ private void findMutations(final Sequence reference) { if (!Settings.getBoolean(SETTING_MUTATION)) { return; } ReferencePositionTraverser.referenceMapGraph(graph, reference); MutationIndicationTraverser.indicateGraphMutations(graph, reference); } /** * Change the graph by selecting the sequences to draw. * * @param visibleSequences * the sequences to display */ public void setVisible(final Set<Sequence> visibleSequences) { Timer timer = Timer.getAndStart(); // Find out which vertices are visible now Set<SequenceSegment> vertices = new TreeSet<SequenceSegment>(); for (SequenceSegment segment : graph.getAllVertices()) { int intersectionSize; if (visibleSequences == null) { intersectionSize = segment.getSources().size(); } else { intersectionSize = SetUtils.intersectionSize(segment .getSources(), visibleSequences); } if (intersectionSize > 0) { vertices.add(segment); } } visibles = vertices; this.visibleSequences = visibleSequences; timer.stopAndLog("Creating visible graph"); } /** * Get the visible segments that this model is holding. * * @param start * starting bucket position * @param end * the last bucket position * @return graph */ public Set<SequenceSegment> getVisibleSegments(final int start, final int end) { Set<SequenceSegment> copy = new TreeSet<SequenceSegment>(); for (SequenceSegment seg : segmentBuckets.getSegments(start, end)) { @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") SequenceSegment newSegment = new SequenceSegment(seg); copy.add(newSegment); } // Keep only the sequencesegments that are visible copy.retainAll(visibles); // Set the sources so they only contain the visible sequences if (visibleSequences != null) { for (SequenceSegment vertex : copy) { vertex.getSources().retainAll(visibleSequences); } } return copy; } /** * Returns the bucketCache to check the current position. * * @return the bucketCache of the graph. */ public BucketCache getBucketCache() { return segmentBuckets; } }