// PathVisio, // a tool for data visualization and analysis using Biological Pathways // Copyright 2006-2011 BiGCaT Bioinformatics // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // package org.pathvisio.core.util; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.pathvisio.core.debug.Logger; import org.pathvisio.core.model.LineType; import org.pathvisio.core.model.ObjectType; import org.pathvisio.core.model.Pathway; import org.pathvisio.core.model.PathwayElement; import org.pathvisio.core.model.GraphLink.GraphRefContainer; import org.pathvisio.core.model.PathwayElement.MAnchor; import org.pathvisio.core.model.PathwayElement.MPoint; /** * Class to parse a relation between GPML objects, e.g. a biochemical reaction. * A relation can be created from a line that connects two objects * of type datanode, shape or label. * The following fields will be created: * - LEFT: an element that acts on the left side of an interaction * - RIGHT: an element that acts on the right side of an interaction * - MEDIATOR: an element that acts as mediator of an interaction * - SOURCE: the pathway containing the relation * * The following example illustrates how the fields will be assigned. * * Consider the following interaction: * * F E * | / * v / * A ---o-----o---o--> B * / T * / | * D C(C1, C2) * * Where C is a group that contains C1 and C2. * * The line A-B will serve as base for the relation, A will be * added to the LEFT field, B to the RIGHT field. * For all other elements that are connected to anchors of this line, the * following rules apply: * * - If the line starts at the anchor and ends at the element, the element will * be added to the LEFT field * - If the line starts at the element, ends at the anchor and has *no* end * linetype (no arrow, T-bar or other shape), the element will be added to the RIGHT * field * - Else, the element will be added to the MEDIATOR field. * * Additionally, if the element to be added is a group, all nested elements will * be added recursively. * * So in the example, the following fields will be created: * A: LEFT * D: LEFT * F: MEDIATOR * C: MEDIATOR * C1:MEDIATOR * C2:MEDIATOR * E: RIGHT * B: RIGHT * * @author thomas */ public class Relation { private Set lefts = new HashSet(); private Set rights = new HashSet(); private Set mediators = new HashSet(); private Map mediatorLines = new HashMap(); /** * Parse a relation. * @param relationLine The line that defines the relation. */ public Relation(PathwayElement relationLine) { if(relationLine.getObjectType() != ObjectType.LINE) { throw new IllegalArgumentException("Object type should be line!"); } Pathway pathway = relationLine.getParent(); if(pathway == null) { throw new IllegalArgumentException("Object has no parent pathway"); } //Add obvious left and right addLeft(pathway.getElementById( relationLine.getMStart().getGraphRef() )); addRight(pathway.getElementById( relationLine.getMEnd().getGraphRef() )); //Find all connecting lines (via anchors) for(MAnchor ma : relationLine.getMAnchors()) { for(GraphRefContainer grc : ma.getReferences()) { if(grc instanceof MPoint) { MPoint mp = (MPoint)grc; PathwayElement line = mp.getParent(); if(line.getMStart() == mp) { //Start linked to anchor, make it a 'right' if(line.getMEnd().isLinked()) { addRight(pathway.getElementById(line.getMEnd().getGraphRef())); } } else { //End linked to anchor if(line.getEndLineType() == LineType.LINE) { //Add as 'left' addLeft(pathway.getElementById(line.getMStart().getGraphRef())); } else { //Add as 'mediator' addMediator(line, pathway.getElementById(line.getMStart().getGraphRef())); } } } else { Logger.log.warn("unsupported GraphRefContainer: " + grc); } } } } void addLeft(PathwayElement pwe) { addElement(pwe, lefts); } void addRight(PathwayElement pwe) { addElement(pwe, rights); } void addMediator(PathwayElement line, PathwayElement pwe) { Set added = addElement(pwe, mediators); for(PathwayElement m : added) mediatorLines.put(m, line); } Set addElement(PathwayElement pwe, Set set) { Set added = new HashSet(); if(pwe != null) { //If it's a group, add all subelements if(pwe.getObjectType() == ObjectType.GROUP) { for(PathwayElement ge : pwe.getParent().getGroupElements(pwe.getGroupId())) { added.addAll(addElement(ge, set)); } } set.add(pwe); added.add(pwe); } return added; } public Set getLefts() { return lefts; } public Set getRights() { return rights; } public Set getMediators() { return mediators; } /** * Get the line that connects the given mediator to the relation. This can be * used to determine how the mediator influences the relation (e.g. inhibition or activation). */ public PathwayElement getMediatorLine(PathwayElement mediator) { return mediatorLines.get(mediator); } }