/** * Overlay a single disease reaction onto a normal reaction. * * @param normalReaction * @param diseaseReaction * @param overlaidObjects */ private void overlayDiseaseReaction(HyperEdge normalReaction, GKInstance diseaseReaction) throws Exception { // Make a copy of the HyperEdge for future process that is related to Vertex and JSON generation HyperEdge reactionCopy = normalReaction.shallowCopy(); reactionCopy.setReactomeId(diseaseReaction.getDBID()); reactionCopy.setDisplayName(diseaseReaction.getDisplayName()); reactionCopy.setLineColor(DefaultRenderConstants.DEFAULT_DISEASE_BACKGROUND); displayedObject.addComponent(reactionCopy); overlaidObjects.add(reactionCopy); // Want to handle inputs, outputs and catalysts since regulators can // be ignored List<Node> nodes = new ArrayList<Node>(); nodes.addAll(normalReaction.getInputNodes()); nodes.addAll(normalReaction.getOutputNodes()); nodes.addAll(normalReaction.getHelperNodes()); // List objects not listed in the disease reaction as crossed objects Set<GKInstance> participants = InstanceUtilities.getReactionParticipants(diseaseReaction); Set<Long> diseaseIds = new HashSet<Long>(); for (GKInstance participant : participants) { diseaseIds.add(participant.getDBID()); if (participant.getSchemClass().isValidAttribute(ReactomeJavaConstants.hasMember)) { List<GKInstance> list = participant.getAttributeValuesList(ReactomeJavaConstants.hasMember); if (list != null && list.size() > 0) { for (GKInstance inst : list) diseaseIds.add(inst.getDBID()); } } if (participant.getSchemClass().isValidAttribute(ReactomeJavaConstants.hasCandidate)) { List<GKInstance> list = participant.getAttributeValuesList(ReactomeJavaConstants.hasCandidate); if (list != null && list.size() > 0) { for (GKInstance inst : list) diseaseIds.add(inst.getDBID()); } } } Set<GKInstance> lofInstances = new HashSet<GKInstance>(); Map<Node, GKInstance> normalToDiseaseEntity = mapMutatedToNormalNodes(diseaseReaction, normalReaction, nodes, lofInstances); for (Node node : nodes) { if (!diseaseIds.contains(node.getReactomeId())) { // Check if it should be mapped to a normal entity GKInstance diseaseEntity = normalToDiseaseEntity.get(node); if (diseaseEntity == null) crossedObjects.add(node); // Just crossed out else { Node diseaseNode = replaceNormalNode(node, diseaseEntity, contains(diseaseEntity, lofInstances)); if (diseaseNode == null) continue; // Just in case // Re-link to diseaseNode ConnectInfo connectInfo = reactionCopy.getConnectInfo(); List<?> widgets = connectInfo.getConnectWidgets(); for (Object obj : widgets) { ConnectWidget widget = (ConnectWidget) obj; if (widget.getConnectedNode() == node) widget.replaceConnectedNode(diseaseNode); } } } else overlaidObjects.add(node); } }
/** * Map mutated nodes in a disease reaction to displayed nodes in a normal reaction. The mapping is * based on sharing of referenceEntity. This may not be reliable! * * @param diseaseReaction * @param nodes * @throws InvalidAttributeException * @throws Exception @TODO: add a new attribute normalEntity in the PhysicalEntity class. */ private Map<Node, GKInstance> mapMutatedToNormalNodes( GKInstance diseaseReaction, HyperEdge normalReaction, List<Node> nodes, Set<GKInstance> lofInstances) throws InvalidAttributeException, Exception { List<GKInstance> efs = diseaseReaction.getAttributeValuesList(ReactomeJavaConstants.entityFunctionalStatus); // Map mutated entities to normal entities via ReferenceGeneProduct Map<Node, GKInstance> normalToDiseaseEntity = new HashMap<Node, GKInstance>(); if (efs == null) return normalToDiseaseEntity; for (GKInstance ef : efs) { GKInstance pe = (GKInstance) ef.getAttributeValue(ReactomeJavaConstants.physicalEntity); if (pe != null) { Set<GKInstance> refEntities = getReferenceEntity(pe); // want to find the matched node for (Node node : nodes) { if (node.getReactomeId() == null) continue; GKInstance nodeInst = adaptor.fetchInstance(node.getReactomeId()); Set<GKInstance> nodeRefEntities = getReferenceEntity(nodeInst); nodeRefEntities.retainAll(refEntities); if (nodeRefEntities.size() > 0) { normalToDiseaseEntity.put(node, pe); if (isLOFEntity(ef)) { lofInstances.add(pe); } break; } } } } // TODO: May have to consider stoichiometries too!!! // In gain of functions, some inputs or outputs may not be used by normal reactions. // This method will do its best to map these reaction participants Collection<GKInstance> mapped = normalToDiseaseEntity.values(); // First check inputs List<GKInstance> diseaseInputs = diseaseReaction.getAttributeValuesList(ReactomeJavaConstants.input); List<Node> normalNodes = normalReaction.getInputNodes(); randomlyMapDiseaseNodesToNormalNodes(normalToDiseaseEntity, mapped, diseaseInputs, normalNodes); // Check outputs List<GKInstance> diseaseOutputs = diseaseReaction.getAttributeValuesList(ReactomeJavaConstants.output); normalNodes = normalReaction.getOutputNodes(); randomlyMapDiseaseNodesToNormalNodes( normalToDiseaseEntity, mapped, diseaseOutputs, normalNodes); // Check helpers GKInstance ca = (GKInstance) diseaseReaction.getAttributeValue(ReactomeJavaConstants.catalystActivity); if (ca != null) { List<GKInstance> catalysts = ca.getAttributeValuesList(ReactomeJavaConstants.physicalEntity); normalNodes = normalReaction.getHelperNodes(); randomlyMapDiseaseNodesToNormalNodes(normalToDiseaseEntity, mapped, catalysts, normalNodes); } return normalToDiseaseEntity; }