/* * The MIT License (MIT) * * Copyright (c) 2007-2015 Broad Institute * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.broad.igv.feature; import org.jgrapht.graph.DefaultDirectedGraph; import java.util.Collection; import java.util.HashMap; import java.util.Map; /** * Takes a set of features, which are assumed to alternative * versions of the same feature. For example, multiple * alternative splicings of a single gene. Generates the simplest * graph for these features * <p/> * User: jacob * Date: 2012/03/28 */ public class AlternativeSpliceGraph<T> extends DefaultDirectedGraph<IExon, Object> { private IExon lastExon = null; /** * For storing information about each exon. */ private Map<IExon, T> parameters = new HashMap<IExon, T>(); public AlternativeSpliceGraph() { super(Object.class); } public AlternativeSpliceGraph(Collection<? extends IGVFeature> features) { this(); addFeatures(features); } /** * Add exon to graph, and parameter to map. * Note that even if exon already exists in * graph, the parameter will be overwritten * * @param exon * @param parameter * @return */ public boolean put(IExon exon, T parameter) { parameters.put(exon, parameter); return addExon(exon); } public T getParameter(IExon exon) { return parameters.get(exon); } public boolean hasParameter(IExon exon) { return parameters.containsKey(exon); } /** * If an exon overlaps exactly a different exon, * we add appropriate edges. * <p/> * If we find a new exon, we add a node for it. * <p/> * If an exon partially overlaps, we * treat that as a different exon. * TODO Treat overlapping regions as same * * @param exon The exon to add */ public boolean addExon(IExon exon) { //Should be a no-op if exon already there boolean added = addVertex(exon); if (lastExon != null) { if (getEdge(lastExon, exon) == null) { addEdge(lastExon, exon); } } lastExon = exon; return added; } private void addFeature(IGVFeature feature) { startFeature(); for (Exon exon : feature.getExons()) { addExon(exon); } } /** * Convenience method for calling * {@link #addFeature} on each. * * @param features */ private void addFeatures(Collection<? extends IGVFeature> features) { for (IGVFeature feature : features) { addFeature(feature); } } public void startFeature() { lastExon = null; } }