private List <AopNetwork> GetAopNetworks(string id = null) { var queryString = new SparqlParameterizedString(); queryString.Namespaces.AddNamespace("dc", new Uri("http://purl.org/dc/elements/1.1/")); queryString.Namespaces.AddNamespace("aopo", new Uri("http://aopkb.org/aop_ontology#")); queryString.Namespaces.AddNamespace("rdfs", new Uri("http://www.w3.org/2000/01/rdf-schema#")); if (!string.IsNullOrEmpty(id)) { queryString.SetUri("id", new Uri($@"http://identifiers.org/aop/{id}")); queryString.CommandText = (@" SELECT * WHERE { ?Aop a aopo:AdverseOutcomePathway ; dc:title ?AopName ; rdfs:label ?AopId . FILTER (?Aop = @id) } "); } else { queryString.CommandText = (@" SELECT * WHERE { ?Aop a aopo:AdverseOutcomePathway ; dc:title ?AopName ; rdfs:label ?AopId . } "); } queryString.SetUri("value", new Uri("http://aopwiki-rdf.prod.openrisknet.org/sparql/")); var parser = new SparqlQueryParser(); var processor = new RemoteQueryProcessor(new SparqlRemoteEndpoint(Endpoint)); var query = parser.ParseFromString(queryString); var resultSet = processor.ProcessQuery(query); if (resultSet is SparqlResultSet) { var result = new List <AopNetwork>(); foreach (var resultRow in (resultSet as SparqlResultSet)) { var recordId = ((ILiteralNode)resultRow["AopId"]).Value; var record = new AopNetwork() { Id = recordId.Replace("AOP ", ""), Name = recordId, Description = ((ILiteralNode)resultRow["AopName"]).Value, }; result.Add(record); } return(result); } else { return(null); } }
/// <summary> /// Gets sequential layers of the AOP network. /// </summary> /// <param name="aopNetwork"></param> /// <returns></returns> public static IList <AopNetworkLayer> GetAopNetworkLayers(this AopNetwork aopNetwork) { var cyclicKers = aopNetwork.FindFeedbackRelationships(); var kers = aopNetwork.KeyEventRelationships.Except(cyclicKers); var toNodesLookup = kers.ToLookup(r => r.ToNode, r => r.FromNode); var fromNodesLookup = kers.ToLookup(r => r.FromNode, r => r.ToNode); var rootNodes = aopNetwork.KeyEvents.Where(r => !toNodesLookup.Contains(r)).ToList(); return(GetAopNetworkLayersRecursive(rootNodes, toNodesLookup, fromNodesLookup, new HashSet <KeyEvent>())); }
/// <summary> /// Finds key-event relationships that feed-back to earlier key events, and therewith /// cause cycles. /// </summary> /// <param name="aopNetwork"></param> /// <returns></returns> public static ICollection <KeyEventRelationship> FindFeedbackRelationships(this AopNetwork aopNetwork) { var toNodesLookup = aopNetwork.KeyEventRelationships.ToLookup(r => r.ToNode, r => r.FromNode); var fromNodesLookup = aopNetwork.KeyEventRelationships.ToLookup(r => r.FromNode); var rootNodes = aopNetwork.KeyEvents.Where(r => !toNodesLookup.Contains(r)).ToList(); var result = aopNetwork.KeyEventRelationships .Where(r => rootNodes.Contains(r.FromNode)) .SelectMany(r => FindFeedbackRelationshipsRecursive(r, fromNodesLookup, new HashSet <KeyEventRelationship>())) .Distinct() .ToList(); return(result); }
/// <summary> /// Creates an svg of the AOP network graph and writes it to the specified file. /// </summary> /// <param name="aopNetwork"></param> /// <param name="fileName"></param> public void Create(AopNetwork aopNetwork, string fileName) { var layers = aopNetwork.GetAopNetworkLayers(); var title = !string.IsNullOrEmpty(aopNetwork.Name) ? aopNetwork.Name : null; var showTitle = title != null; var offsetX = 10D; var offsetY = showTitle ? 40D : 20D; var width = offsetX + layers.Count * (BlockWidth + HorizontalMargin) - HorizontalMargin + 1; var height = offsetY + layers.Max(r => r.KeyEvents.Count) * (BlockHeight + VerticalMargin) - VerticalMargin + 1; var doc = new SvgDocument() { Width = (float)(width), Height = (float)(height), FontSize = 10, FontFamily = "Arial", }; var defsElement = new SvgDefinitionList() { ID = "defsMap" }; doc.Children.Add(defsElement); defsElement.Children.Add(arrowMarker); if (showTitle) { var text = new SvgText() { FontSize = 14, FontWeight = SvgFontWeight.Bold, Nodes = { new SvgContentNode() { Content = title } }, TextAnchor = SvgTextAnchor.Middle, X = new SvgUnitCollection() { 0f }, Y = new SvgUnitCollection() { 0f }, Dx = new SvgUnitCollection() { (float)width / 2f }, Fill = new SvgColourServer(Color.Black), }; text.Dy = new SvgUnitCollection() { 2 * text.Bounds.Height }; doc.Children.Add(text); } var keyEventNodes = DrawKeyEvents( doc, layers, offsetX, offsetY ); var indirectKers = aopNetwork.GetIndirectKeyEventRelationships(); var cyclicKers = aopNetwork.FindFeedbackRelationships(); var kers = aopNetwork.KeyEventRelationships .Except(indirectKers) .Except(cyclicKers) .ToList(); DrawKeyEventRelationships(doc, kers, keyEventNodes); doc.FlushStyles(true); doc.Write(fileName); }
private static void createSvg(AopNetwork network, string fileName) { var visualizer = new AopNetworkGraphCreator(); visualizer.Create(network, Path.Combine(_outputPath, fileName)); }
/// <summary> /// Identifies key-event relationships that can also be reached indirectly (and may be /// non-adjecent). /// </summary> /// <param name="aopNetwork"></param> /// <returns></returns> public static ICollection <KeyEventRelationship> GetIndirectKeyEventRelationships(this AopNetwork aopNetwork) { var cyclicKers = aopNetwork.FindFeedbackRelationships(); var kers = aopNetwork.KeyEventRelationships.Except(cyclicKers); var toNodesLookup = kers.ToLookup(r => r.ToNode, r => r.FromNode); var fromNodesLookup = kers.ToLookup(r => r.FromNode, r => r); var rootNodes = aopNetwork.KeyEvents.Where(r => !toNodesLookup.Contains(r)).ToList(); var indirectRelationships = new HashSet <KeyEventRelationship>(); foreach (var node in rootNodes) { _ = GetIndirectRelationshipsRecursive(node, fromNodesLookup, indirectRelationships); } return(indirectRelationships); }