def test_two_node_one_edge_network(self): net = NiceCXNetwork() net.create_node('first') net.create_node('second') net.create_edge(edge_source=0, edge_target=1) net.set_name('bob') fac = DefaultNetworkXFactory() g = fac.get_graph(net) self.assertEqual('bob', g.graph['name']) self.assertEqual(2, len(g)) self.assertEqual(1, g.number_of_edges()) self.assertTrue(0 in g) if float(networkx.__version__) >= 2: nodelist = list(g.nodes(data=True)) edgelist = list(g.edges(data=True)) else: nodelist = g.nodes(data=True) edgelist = g.edges(data=True) self.assertEqual('first', nodelist[0][1]['name']) self.assertEqual('second', nodelist[1][1]['name']) self.assertEqual(0, edgelist[0][0]) self.assertEqual(1, edgelist[0][1]) self.assertEqual(None, edgelist[0][2]['interaction'])
def test_add_int_attr(self): niceCx = NiceCXNetwork() int_node = niceCx.create_node(node_name="testint") niceCx.add_node_attribute(property_of=int_node, name='Size', values=1, type="integer") upload_message = niceCx.upload_to(upload_server, upload_username, upload_password) UUID = upload_message.split('/')[-1] time.sleep(1) imported_cx = ndex2.create_nice_cx_from_server(server='dev.ndexbio.org', uuid=UUID, username=upload_username, password=upload_password) for i in imported_cx.get_node_attributes(0): self.assertEqual(i.get('d'), "integer")
def test_one_node_no_edge_network(self): net = NiceCXNetwork() net.create_node('first') net.set_name('bob') fac = LegacyNetworkXVersionTwoPlusFactory() g = fac.get_graph(net) self.assertEqual('bob', g.graph['name']) self.assertEqual(1, len(g)) self.assertEqual(0, g.number_of_edges()) self.assertTrue('first' in g) nodelist = g.nodes(data=True) self.assertEqual('first', nodelist['first']['represents'])
def test_add_lst_flt(self): niceCx = NiceCXNetwork() list_float_node = niceCx.create_node(node_name="testlstflt") niceCx.add_node_attribute(property_of=list_float_node, name='Too many scores', values=[15.3,43.6,-34.0,43.3], type="list_of_float") upload_message = niceCx.upload_to(upload_server, upload_username, upload_password) UUID = upload_message.split('/')[-1] time.sleep(1) imported_cx = ndex2.create_nice_cx_from_server(server='dev.ndexbio.org', uuid=UUID, username=upload_username, password=upload_password) for i in imported_cx.get_node_attributes(0): self.assertEqual(i.get('d'), "list_of_double")
def test_one_node_no_edge_network(self): net = NiceCXNetwork() net.create_node('first') net.set_name('bob') fac = DefaultNetworkXFactory() g = fac.get_graph(net) self.assertEqual('bob', g.graph['name']) self.assertEqual(1, len(g)) self.assertEqual(0, g.number_of_edges()) self.assertTrue(0 in g) nodelist = g.nodes(data=True) if float(networkx.__version__) >= 2: self.assertEqual('first', nodelist[0]['name']) else: self.assertEqual('first', nodelist[0][1]['name'])
def __init__(self, cx=None, server=None, username='******', password='******', uuid=None, networkx_G=None, data=None, **attr): from ndex2.nice_cx_network import NiceCXNetwork self.nice_cx = NiceCXNetwork(user_agent='niceCx Builder') self.node_id_lookup = {} self.node_id_counter = 0 self.edge_id_counter = 0 self.node_inventory = {} self.node_attribute_inventory = [] self.node_attribute_map = {} self.edge_inventory = {} self.edge_attribute_inventory = [] self.edge_attribute_map = {} self.opaque_aspect_inventory = [] self.context_inventory = [] self.network_attribute_inventory = {} self.user_base64 = None self.username = None self.password = None if username and password: self.username = username self.password = password if sys.version_info.major == 3: encode_string = '%s:%s' % (username, password) byte_string = encode_string.encode() self.user_base64 = base64.b64encode(byte_string)#.replace('\n', '') else: self.user_base64 = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
def test_add_bad_net_attrs(self): niceCx_creatures = NiceCXNetwork() niceCx_creatures.set_name("Test") niceCx_creatures.create_node(node_name="Fox") niceCx_creatures.set_network_attribute(name="version", values="1.0") print(niceCx_creatures) upload_message = niceCx_creatures.upload_to(upload_server, upload_username, upload_password) self.assertTrue(upload_message)
def test_bad_edge_attr(self): niceCx_creatures = NiceCXNetwork() niceCx_creatures.set_name("Test Network") node1_id = niceCx_creatures.create_node(node_name=324) node2_id = niceCx_creatures.create_node(node_name=453) edge = niceCx_creatures.create_edge(edge_source=node1_id, edge_target=node2_id, edge_interaction='inte') niceCx_creatures.add_edge_attribute(property_of=edge, name= "djks", values= "jfkl") upload_message = niceCx_creatures.upload_to(upload_server, upload_username, upload_password) self.assertTrue(upload_message)
def test_bad_nodes_add_edge(self): niceCx_creatures = NiceCXNetwork() niceCx_creatures.set_name("Test Network") node1_id = niceCx_creatures.create_node(node_name=324) node2_id = niceCx_creatures.create_node(node_name=453) niceCx_creatures.create_edge(edge_source=node1_id, edge_target=node2_id, edge_interaction=['inte']) upload_message = niceCx_creatures.upload_to(upload_server, upload_username, upload_password) self.assertTrue(upload_message)
def test_bad_node_attr(self): niceCx_creatures = NiceCXNetwork() niceCx_creatures.set_name("Test Network") fox_node = niceCx_creatures.create_node(node_name=453) niceCx_creatures.add_node_attribute(property_of=fox_node, name='Color', values=['Red',"tree"]) upload_message = niceCx_creatures.upload_to(upload_server, upload_username, upload_password) self.assertTrue(upload_message)
def test_two_node_one_edge_network(self): net = NiceCXNetwork() net.create_node('first') net.create_node('second') net.create_edge(edge_source=0, edge_target=1) net.set_name('bob') fac = LegacyNetworkXVersionTwoPlusFactory() g = fac.get_graph(net) self.assertEqual('bob', g.graph['name']) self.assertEqual(2, len(g)) self.assertEqual(1, g.number_of_edges()) self.assertTrue('first' in g) self.assertTrue('second' in g) edgelist = list(g.edges(data=True)) self.assertTrue(('first' == edgelist[0][0] and 'second' == edgelist[0][1]) or ('second' == edgelist[0][0] and 'first' == edgelist[0][1])) self.assertEqual(None, edgelist[0][2]['interaction'])
def test_context(self): niceCx_creatures = NiceCXNetwork() niceCx_creatures.set_name("Test") niceCx_creatures.create_node(node_name="Fox") try: self.assertRaises(Exception, niceCx_creatures.set_context("hkjhnk")) except Exception as e: print('Bad context exception was caught')
def test_set_network_attributes_from_style_network_complete_net(self): net = NiceCXNetwork() net.set_name(ndexloadncipid.COMPLETE_INTERACTION_NAME) templatenet = NiceCXNetwork() templatenet.set_name('well') templatenet.set_network_attribute('description', values='hi', type='string') templatenet.set_network_attribute('organism', values='some', type='string') loader = NDExNciPidLoader(None) loader._template = templatenet res = loader._set_network_attributes_from_style_network(net) self.assertEqual(0, len(res)) self.assertTrue( 'This network' in net.get_network_attribute('description')['v']) self.assertEqual('some', net.get_network_attribute('organism')['v'])
def test_set_network_attributes_from_style_network_description_set_org_not( self): net = NiceCXNetwork() net.set_name('foo') templatenet = NiceCXNetwork() templatenet.set_name('well') templatenet.set_network_attribute('description', values='hi', type='string') loader = NDExNciPidLoader(None) loader._template = templatenet res = loader._set_network_attributes_from_style_network(net) self.assertEqual(1, len(res)) self.assertTrue('organism network' in res[0]) self.assertEqual('hi', net.get_network_attribute('description')['v']) self.assertEqual(None, net.get_network_attribute('organism'))
def test_update_network_empty(self): updator = NodeLocationUpdator() net = NiceCXNetwork() self.assertEqual([], updator.update(net))
def test_update_network_containing_all_types(self): updator = NodeLocationUpdator() net = NiceCXNetwork() comp_attr = NodeLocationUpdator.LOCATION no_attr = net.create_node('somenode', node_represents='rep1') e_attr = net.create_node('somenode2', node_represents='uniprot:rep2') net.set_node_attribute(e_attr, NodeLocationUpdator.LOCATION, '') o_attr = net.create_node('somenode2', node_represents='uniprot:rep2') net.set_node_attribute(o_attr, NodeLocationUpdator.LOCATION, 'blah') ph_attr = net.create_node('anothernode', node_represents='rep3') net.set_node_attribute(ph_attr, NodeLocationUpdator.LOCATION, NodeLocationUpdator.PHENOTYPESLIST) self.assertEqual([], updator.update(net)) self.assertEqual(NodeLocationUpdator.CYTOPLASM, net.get_node_attribute(no_attr, comp_attr)['v']) self.assertEqual(NodeLocationUpdator.CYTOPLASM, net.get_node_attribute(e_attr, comp_attr)['v']) self.assertEqual('blah', net.get_node_attribute(o_attr, comp_attr)['v']) self.assertEqual('', net.get_node_attribute(ph_attr, comp_attr)['v'])
def test_remove_if_redundant_with_multiple_edges_same_citations(self): net = NiceCXNetwork() adjud = RedundantEdgeAdjudicator() nid = net.create_edge(edge_source=0, edge_target=1, edge_interaction='neighbor-of') net.set_edge_attribute(nid, RedundantEdgeAdjudicator.CITATION, ['pubmed:4', 'pubmed:123'], type='list_of_string') cid = net.create_edge(edge_source=0, edge_target=1, edge_interaction='controls-state-change-of') net.set_edge_attribute(cid, RedundantEdgeAdjudicator.CITATION, ['pubmed:555', 'pubmed:4'], type='list_of_string') cidtwo = net.create_edge(edge_source=0, edge_target=1, edge_interaction='controls-state-change-of') net.set_edge_attribute(cidtwo, RedundantEdgeAdjudicator.CITATION, ['pubmed:4', 'pubmed:123'], type='list_of_string') self.assertEqual('neighbor-of', net.get_edge(nid)['i']) adjud._remove_if_redundant(net, nid, [cid, cidtwo]) self.assertEqual(None, net.get_edge(nid))
def create_empty_nice_cx(): my_nicecx = NiceCXNetwork() return my_nicecx
def test_basic_network(self): net = NiceCXNetwork() adjud = RedundantEdgeAdjudicator() nid = net.create_edge(edge_source=0, edge_target=1, edge_interaction='neighbor-of') cid = net.create_edge(edge_source=0, edge_target=1, edge_interaction='controls-state-change-of') net.set_edge_attribute(cid, RedundantEdgeAdjudicator.CITATION, ['pubmed:123'], type='list_of_string') oid = net.create_edge(edge_source=0, edge_target=1, edge_interaction='someother') net.set_edge_attribute(oid, RedundantEdgeAdjudicator.CITATION, ['pubmed:123'], type='list_of_string') self.assertEqual('neighbor-of', net.get_edge(nid)['i']) self.assertEqual('controls-state-change-of', net.get_edge(cid)['i']) self.assertEqual('someother', net.get_edge(oid)['i']) self.assertEqual([], adjud.update(net)) self.assertEqual(None, net.get_edge(nid)) self.assertEqual(None, net.get_edge(cid)) self.assertEqual('someother', net.get_edge(oid)['i'])
def create_nice_cx_from_pandas(df, source_field=None, target_field=None, source_node_attr=[], target_node_attr=[], edge_attr=[], edge_interaction=None, source_represents=None, target_represents=None): """ Create a NiceCXNetwork from a pandas dataframe in which each row specifies one edge in the network. If only the df argument is provided the dataframe is treated as 'SIF' format, where the first two columns specify the source and target node ids of the edge and all other columns are ignored. The edge interaction is defaulted to "interacts-with" If both the source_field and target_field arguments are provided, the those and any other arguments refer to headers in the dataframe, controlling the mapping of columns to the attributes of nodes, and edges in the resulting NiceCXNetwork. If a header is not mapped the corresponding column is ignored. If the edge_interaction is not specified it defaults to "interacts-with" :param df: pandas dataframe to process :param source_field: header name specifying the name of the source node. :param target_field: header name specifying the name of the target node. :param source_node_attr: list of header names specifying attributes of the source node. :param target_node_attr: list of header names specifying attributes of the target node. :param edge_attr: list of header names specifying attributes of the edge. :param edge_interaction: the relationship between the source node and the target node, defaulting to "interacts-with" :return: NiceCXNetwork """ my_nicecx = NiceCXNetwork() # ==================================================== # IF NODE FIELD NAME (SOURCE AND TARGET) IS PROVIDED # THEN USE THOSE FIELDS OTHERWISE USE INDEX 0 & 1 # ==================================================== my_nicecx.set_name('Pandas Upload') #my_nicecx.add_metadata_stub('networkAttributes') count = 0 source_predicate = '' target_predicate = '' niceCxBuilder = NiceCXBuilder() if source_field and target_field: for index, row in df.iterrows(): if count % 1000 == 0: print(count) count += 1 # ============= # ADD NODES # ============= if source_represents is not None: source_node_id = niceCxBuilder.add_node(name=source_predicate + str(row[source_field]), represents=source_predicate + str(row[source_represents])) else: source_node_id = niceCxBuilder.add_node(name=source_predicate + str(row[source_field]), represents=source_predicate + str(row[source_field])) if target_represents is not None: target_node_id = niceCxBuilder.add_node(name=target_predicate + str(row[target_field]), represents=target_predicate + str(row[target_represents])) else: target_node_id = niceCxBuilder.add_node(name=target_predicate + str(row[target_field]), represents=target_predicate + str(row[target_field])) # ============= # ADD EDGES # ============= if edge_interaction: if row.get(edge_interaction): use_this_interaction = row[edge_interaction] else: use_this_interaction = edge_interaction else: use_this_interaction = 'interacts-with' niceCxBuilder.add_edge(id=index, source=source_node_id, target=target_node_id, interaction=use_this_interaction) # ============================== # ADD SOURCE NODE ATTRIBUTES # ============================== for sp in source_node_attr: #TODO - need to be smarter about how data type is inferred #row[sp], attr_type = _infer_data_type(row[sp]) attr_type = None #attr_type = None #if type(row[sp]) is float and math.isnan(row[sp]): # row[sp] = '' # attr_type = 'float' #elif type(row[sp]) is float and math.isinf(row[sp]): # row[sp] = 'Inf' # attr_type = 'float' #elif type(row[sp]) is float: # attr_type = 'float' #elif isinstance(row[sp], int): # attr_type = 'integer' if sp == 'citation' and not isinstance(row[sp], list): row[sp] = [row[sp]] attr_type = 'list_of_string' niceCxBuilder.add_node_attribute(source_node_id, sp, str(row[sp]), type=attr_type) # ============================== # ADD TARGET NODE ATTRIBUTES # ============================== for tp in target_node_attr: #TODO - need to be smarter about how data type is inferred #row[tp], attr_type = _infer_data_type(row[tp]) attr_type = None #attr_type = None #if type(row[tp]) is float and math.isnan(row[tp]): # row[tp] = '' # attr_type = 'float' #elif type(row[tp]) is float and math.isinf(row[tp]): # row[tp] = 'Inf' # attr_type = 'float' #elif type(row[tp]) is float: # attr_type = 'float' #elif isinstance(row[tp], int): # attr_type = 'integer' if tp == 'citation' and not isinstance(row[tp], list): row[tp] = [row[tp]] attr_type = 'list_of_string' niceCxBuilder.add_node_attribute(target_node_id, tp, str(row[tp]), type=attr_type) # ============================== # ADD EDGE ATTRIBUTES # ============================== for ep in edge_attr: #TODO - need to be smarter about how data type is inferred #row[ep], attr_type = _infer_data_type(row[ep]) attr_type = None #attr_type = None #if type(row[ep]) is float and math.isnan(row[ep]): # row[ep] = '' # attr_type = 'float' #elif type(row[ep]) is float and math.isinf(row[ep]): # row[ep] = 'INFINITY' # attr_type = 'float' if ep == 'citation' and not isinstance(row[ep], list): row[ep] = [row[ep]] attr_type = 'list_of_string' niceCxBuilder.add_edge_attribute(property_of=index, name=ep, values=row[ep], type=attr_type) else: for index, row in df.iterrows(): # ============= # ADD NODES # ============= source_node_id = niceCxBuilder.add_node(name=str(row[0]), represents=str(row[0])) target_node_id = niceCxBuilder.add_node(name=str(row[1]), represents=str(row[1])) # ============= # ADD EDGES # ============= if len(row) > 2: niceCxBuilder.add_edge(id=index, source=source_node_id, target=target_node_id, interaction=row[2]) else: niceCxBuilder.add_edge(id=index, source=source_node_id, target=target_node_id, interaction='interacts-with') return niceCxBuilder.get_nice_cx() # my_nicecx
def test_basic_network_where_neighbor_of_citations_merges_enabled(self): net = NiceCXNetwork() adjud = RedundantEdgeAdjudicator() edge_map = {} nid = net.create_edge(edge_source=0, edge_target=1, edge_interaction='neighbor-of') net.set_edge_attribute(nid, RedundantEdgeAdjudicator.CITATION, ['pubmed:5'], type='list_of_string') cid = net.create_edge(edge_source=0, edge_target=1, edge_interaction='controls-state-change-of') net.set_edge_attribute(cid, RedundantEdgeAdjudicator.CITATION, ['pubmed:6'], type='list_of_string') neighbor_of_map = {} controls_state_change_map = {} other_edge_exists = {} for k, v in net.get_edges(): s = v['s'] t = v['t'] i = v['i'] if i == 'neighbor-of': if not s in neighbor_of_map: neighbor_of_map[s] = {} if not t in neighbor_of_map: neighbor_of_map[t] = {} neighbor_of_map[s][t] = k neighbor_of_map[t][s] = k elif i == 'controls-state-change-of': adjud._add_to_edge_map(controls_state_change_map, k, s, t) else: adjud._add_to_edge_map(other_edge_exists, k, s, t) adjud.remove_and_merge_neighbor_of(net, neighbor_of_map, edge_map) net.print_summary()
def test_basic_network_where_neighbor_of_citations_merges_disabled(self): net = NiceCXNetwork() adjud = RedundantEdgeAdjudicator(disablcitededgemerge=True) nid = net.create_edge(edge_source=0, edge_target=1, edge_interaction='neighbor-of') net.set_edge_attribute(nid, RedundantEdgeAdjudicator.CITATION, ['pubmed:5'], type='list_of_string') cid = net.create_edge(edge_source=0, edge_target=1, edge_interaction='controls-state-change-of') oid = net.create_edge(edge_source=0, edge_target=1, edge_interaction='someother') self.assertEqual('neighbor-of', net.get_edge(nid)['i']) self.assertEqual('controls-state-change-of', net.get_edge(cid)['i']) self.assertEqual('someother', net.get_edge(oid)['i']) self.assertEqual([], adjud.update(net)) self.assertEqual('neighbor-of', net.get_edge(nid)['i']) self.assertEqual(None, net.get_edge(cid)) self.assertEqual('someother', net.get_edge(oid)['i']) res = net.get_edge_attribute(nid, RedundantEdgeAdjudicator.CITATION) res['v'].sort() self.assertEqual(['pubmed:5'], res['v']) res = net.get_edge_attribute(oid, RedundantEdgeAdjudicator.CITATION) self.assertEqual((None, None), res)
def test_update_network_containing_all_types(self): pfdict = {'a': ['2', '3'], 'SIGNOR-PF10': ['7', '8']} cdict = {'e': ['5', '6'], 'SIGNOR-C1': ['9', '10']} net = NiceCXNetwork() aid = net.create_node('a') net.set_node_attribute(aid, NodeMemberUpdator.TYPE, 'proteinfamily') eid = net.create_node('e') net.set_node_attribute(eid, NodeMemberUpdator.TYPE, 'complex') oid = net.create_node('c') o2id = net.create_node('d') net.set_node_attribute(o2id, NodeMemberUpdator.TYPE, 'protein') notinid = net.create_node('x') net.set_node_attribute(notinid, NodeMemberUpdator.TYPE, 'proteinfamily') notinid2 = net.create_node('y') net.set_node_attribute(notinid2, NodeMemberUpdator.TYPE, 'complex') mock = GeneSymbolSearcher(bclient=None) mock.get_symbol = MagicMock(side_effect=['AA', 'BB', 'CC', 'DD']) updator = NodeMemberUpdator(pfdict, cdict, genesearcher=mock) res = updator.update(net) self.assertTrue("No entry in proteinfamily map for node: {" in res[0]) self.assertTrue("No entry in complexes map for node: {" in res[1]) res = net.get_node_attribute(aid, NodeMemberUpdator.MEMBER) self.assertTrue('hgnc.symbol:AA' in res['v']) self.assertTrue('hgnc.symbol:BB' in res['v']) res = net.get_node_attribute(eid, NodeMemberUpdator.MEMBER) self.assertTrue('hgnc.symbol:CC' in res['v']) self.assertTrue('hgnc.symbol:DD' in res['v']) res = net.get_node_attribute(oid, NodeMemberUpdator.MEMBER) self.assertEqual(None, res) res = net.get_node_attribute(o2id, NodeMemberUpdator.MEMBER) self.assertEqual(None, res)
def test_remove_nonexistant_edge(self): adjud = RedundantEdgeAdjudicator() self.assertTrue('Removes' in adjud.get_description()) net = NiceCXNetwork() adjud._remove_edge(net, 1)
def create_nice_cx_from_networkx(G): """ Creates a NiceCXNetwork based on a networkx graph. The resulting NiceCXNetwork contains the nodes edges and their attributes from the networkx graph and also preserves the graph 'pos' attribute as a CX cartesian coordinates aspect. Node name is taken from the networkx node id. Node 'represents' is taken from the networkx node attribute 'represents' :param G: networkx graph :type G: networkx graph :return: NiceCXNetwork :rtype: NiceCXNetwork """ niceCxBuilder = NiceCXBuilder() if G is None: raise Exception('Networkx input is empty') my_nicecx = NiceCXNetwork() if G.graph.get('name'): my_nicecx.set_name(G.graph.get('name')) else: my_nicecx.set_name('created from networkx') my_nicecx.add_metadata_stub('networkAttributes') #========================================= # Check to see if the node label is same # (case insensitive) as 'name' attribute #========================================= #use_node_label = False #for n, d in G.nodes_iter(data=True): # if not isinstance(n, int) and d and d.get('name'): # if n.lower() == d.get('name').lower(): # use_node_label = True # break for n, d in G.nodes(data=True): # ============= # ADD NODES # ============= #if d and d.get('name'): # if isinstance(n, int): # node_id = niceCxBuilder.add_node(name=d.get('name'),represents=d.get('name'), id=n, map_node_ids=True) # else: # # If networkx node is of type string then maybe the 'name' atribute is no longer accurate # if use_node_label: # node_id = niceCxBuilder.add_node(name=n,represents=n, map_node_ids=True) # else: # node_id = niceCxBuilder.add_node(name=d.get('name'),represents=d.get('name'), map_node_ids=True) #else: if isinstance(n, int): node_id = niceCxBuilder.add_node(name=n,represents=d.get('represents'), id=n, map_node_ids=True) else: node_id = niceCxBuilder.add_node(name=n, represents=d.get('represents'), map_node_ids=True) # ====================== # ADD NODE ATTRIBUTES # ====================== for k, v in d.items(): use_this_value, attr_type = niceCxBuilder._infer_data_type(v, split_string=True) if k == 'citation' and not isinstance(use_this_value, list): use_this_value = [use_this_value] attr_type = 'list_of_string' if use_this_value is not None: niceCxBuilder.add_node_attribute(node_id, k, use_this_value, type=attr_type) index = 0 for u, v, d in G.edges(data=True): # ============= # ADD EDGES # ============= if d.get('interaction') is None or d.get('interaction') == 'null': interaction = 'neighbor-of' else: interaction = d.get('interaction') if isinstance(u, int): niceCxBuilder.add_edge(source=u, target=v, interaction=interaction, id=index) else: niceCxBuilder.add_edge(source=niceCxBuilder.node_id_lookup.get(u), target=niceCxBuilder.node_id_lookup.get(v), interaction=interaction, id=index) # ============================== # ADD EDGE ATTRIBUTES # ============================== for k, val in d.items(): if k != 'interaction': use_this_value, attr_type = niceCxBuilder._infer_data_type(val, split_string=True) if k == 'citation' and not isinstance(use_this_value, list): use_this_value = [use_this_value] attr_type = 'list_of_string' if use_this_value is not None: niceCxBuilder.add_edge_attribute(property_of=index, name=k, values=use_this_value, type=attr_type) index += 1 if hasattr(G, 'pos'): aspect = _create_cartesian_coordinates_aspect_from_networkx(G) niceCxBuilder.add_opaque_aspect('cartesianLayout', aspect) return niceCxBuilder.get_nice_cx()
def test_load_edges(self): self.assertFalse(upload_username == 'username') nice_cx = NiceCXNetwork() node_id_1 = nice_cx.create_node(node_name='node%s' % str(1), node_represents='ABC') node_id_2 = nice_cx.create_node(node_name='node%s' % str(2), node_represents='DEF') edge_id_1 = nice_cx.create_edge(edge_source=node_id_1, edge_target=node_id_2, edge_interaction='neighbor') citation1 = nice_cx.add_citation(id=0, title='Hi 1', identifier='pmid:28947956') nice_cx.add_edge_citations(edge_id_1, citation1.get('@id')) supports1 = nice_cx.add_support(id=0, text='Hi supports 1') nice_cx.add_edge_supports(edge_id_1, supports1.get('@id')) nice_cx.set_name('Citation testing') upload_message = nice_cx.upload_to(upload_server, upload_username, upload_password) print(upload_message)
def test_two_node_one_edge_network(self): net = NiceCXNetwork() net.create_node('first') net.create_node('second') edge_one = net.create_edge(edge_source=0, edge_target=1) net.set_name('bob') net.set_edge_attribute(edge_one, 'booleanattrib', 'false', type='boolean') net.set_edge_attribute(edge_one, 'integerattrib', '1', type='integer') net.set_edge_attribute(edge_one, 'doubleattrib', '2.0', type='double') net.set_edge_attribute(edge_one, 'longattrib', '3', type='long') net.set_edge_attribute(edge_one, 'stringattrib', 'false', type='string') net.set_edge_attribute(edge_one, 'list_of_booleanattrib', ['True'], type='list_of_boolean') net.set_edge_attribute(edge_one, 'list_of_doubleattrib', ['4.0'], type='list_of_double') net.set_edge_attribute(edge_one, 'list_of_integerattrib', ['5'], type='list_of_integer') net.set_edge_attribute(edge_one, 'list_of_longattrib', ['6'], type='list_of_long') net.set_edge_attribute(edge_one, 'list_of_stringattrib', ['false'], type='list_of_string') fac = DefaultNetworkXFactory() g = fac.get_graph(net) self.assertEqual('bob', g.graph['name']) self.assertEqual(2, len(g)) self.assertEqual(1, g.number_of_edges()) self.assertTrue(0 in g) if NETWORKX_MAJOR_VERSION >= 2: nodelist = list(g.nodes(data=True)) edgelist = list(g.edges(data=True)) else: nodelist = g.nodes(data=True) edgelist = g.edges(data=True) self.assertEqual('first', nodelist[0][1]['name']) self.assertEqual('second', nodelist[1][1]['name']) self.assertEqual(0, edgelist[0][0]) self.assertEqual(1, edgelist[0][1]) self.assertEqual(None, edgelist[0][2]['interaction']) self.assertEqual('false', edgelist[0][2]['booleanattrib']) self.assertEqual('1', edgelist[0][2]['integerattrib']) self.assertEqual('2.0', edgelist[0][2]['doubleattrib']) self.assertEqual('3', edgelist[0][2]['longattrib']) self.assertEqual('false', edgelist[0][2]['stringattrib']) self.assertEqual(['True'], edgelist[0][2]['list_of_booleanattrib']) self.assertEqual(['4.0'], edgelist[0][2]['list_of_doubleattrib']) self.assertEqual(['5'], edgelist[0][2]['list_of_integerattrib']) self.assertEqual(['6'], edgelist[0][2]['list_of_longattrib']) self.assertEqual(['false'], edgelist[0][2]['list_of_stringattrib'])
class NiceCXBuilder(object): def __init__(self, cx=None, server=None, username='******', password='******', uuid=None, networkx_G=None, data=None, **attr): from ndex2.nice_cx_network import NiceCXNetwork self.nice_cx = NiceCXNetwork(user_agent='niceCx Builder') self.node_id_lookup = {} self.node_id_counter = 0 self.edge_id_counter = 0 self.node_inventory = {} self.node_attribute_inventory = [] self.node_attribute_map = {} self.edge_inventory = {} self.edge_attribute_inventory = [] self.edge_attribute_map = {} self.opaque_aspect_inventory = [] self.context_inventory = [] self.network_attribute_inventory = {} self.user_base64 = None self.username = None self.password = None if username and password: self.username = username self.password = password if sys.version_info.major == 3: encode_string = '%s:%s' % (username, password) byte_string = encode_string.encode() self.user_base64 = base64.b64encode(byte_string)#.replace('\n', '') else: self.user_base64 = base64.encodestring('%s:%s' % (username, password)).replace('\n', '') def set_context(self, context): """ Set the @context information of the network. This information maps namespace prefixes to their defining URIs Example: ``set_context({'pmid': 'https://www.ncbi.nlm.nih.gov/pubmed/'})`` :param context: dict of name, URI pairs :type context: dict :return: None :rtype: none """ if isinstance(context, dict): self.context_inventory = context elif isinstance(context, list): if len(context) > 0: self.context_inventory = context[0] def set_name(self, network_name): """ Set the network name :param network_name: Network name :type network_name: string :return: None :rtype:none """ self.network_attribute_inventory['name'] = {'n': 'name', 'v': network_name, 'd': 'string'} def add_network_attribute(self, name=None, values=None, type=None, cx_element=None): """ Add an attribute to the network :param name: Name of the attribute :type name: str :param values: The value(s) of the attribute :type values: One of the allowable CX types. See `Supported data types`_ :param type: They type of data supplied in values. Default is string. See `Supported data types`_ :type type: str :return: None :rtype: None """ add_this_network_attribute = {'n': name, 'v': values} if type: add_this_network_attribute['d'] = type self.network_attribute_inventory[name] = add_this_network_attribute def add_node(self, name=None, represents=None, id=None, data_type=None, map_node_ids=False): """ Adds a new node with the corresponding name and represents (external id) :param node_name: Name of the node :type node_name: str :param represents: Representation of the node (alternate identifier) :type represents: str :param id: :type id: :return: Node ID :rtype: int """ if self.node_inventory.get(name) is not None: return self.node_inventory.get(name).get('@id') if id: node_id = id else: node_id = self.node_id_counter self.node_id_counter += 1 add_this_node = {'@id': node_id, 'n': name} if represents: add_this_node['r'] = represents if data_type: add_this_node['d'] = data_type self.node_inventory[name] = add_this_node if map_node_ids: self.node_id_lookup[name] = node_id return node_id def add_edge(self, source=None, target=None, interaction=None, id=None): """ Adds a new edge in the network by specifying source-interaction-target :param source: The source node of this edge, either its id or the node object itself. :type source: int, dict (with @id property) :param target: The target node of this edge, either its id or the node object itself. :type target: int, dict (with @id property) :param interaction: The interaction that describes the relationship between the source and target nodes :type interaction: str :param id: Edge id for this edge. If none is provided the builder will create one :type id: int :return: Edge ID :rtype: int """ if id is not None: edge_id = id else: edge_id = self.edge_id_counter self.edge_id_counter += 1 add_this_edge = {'@id': edge_id, 's': source, 't': target} if interaction: add_this_edge['i'] = interaction else: add_this_edge['i'] = 'interacts-with' self.edge_inventory[edge_id] = add_this_edge return edge_id def add_node_attribute(self, property_of, name, values, type=None): """ Set an attribute of a node, where the node may be specified by its id or passed in as a node dict. :param property_of: Node ID to add the attribute to :type property_of: int :param name: Attribute name :type name: str :param value: A value or list of values of the attribute :type value: list, string, int or float :param type: The datatype of the attribute values, defaults is string. See `Supported data types`_ :type type: str :return: None :rtype: None """ if property_of is None: raise TypeError('Node value is None') if name is None: raise TypeError('Property name is None') if values is None: raise TypeError('Attribute value is None') add_this_node_attribute = {'po': property_of, 'n': name, 'v': values} if self.node_attribute_map.get(property_of) is None: self.node_attribute_map[property_of] = {} elif self.node_attribute_map[property_of].get(name) is not None: # TODO - Raise warning/exception for duplicate attribute return if type: if type == 'float' or type == 'double': type = 'double' try: if not isinstance(values, float): add_this_node_attribute['v'] = float(values) except ValueError as e: raise ValueError('Value was not of type %s' % type) if type == 'list_of_float' or type == 'list_of_double': try: if isinstance(values, list): for value in values: if not isinstance(value, float): value = float(value) except ValueError as e: raise ValueError('Value was not of type %s' % type) type = 'list_of_double' add_this_node_attribute['d'] = type else: use_this_value, attr_type = self._infer_data_type(values) add_this_node_attribute['v'] = use_this_value add_this_node_attribute['d'] = attr_type if add_this_node_attribute['v'] is not None: self.node_attribute_inventory.append(add_this_node_attribute) self.node_attribute_map[property_of][name] = True def add_edge_attribute(self, property_of=None, name=None, values=None, type=None): """ Set the value(s) of attribute of an edge, where the edge may be specified by its id or passed in an object. Example: ``set_edge_attribute(0, 'weight', 0.5, type='float')`` or ``set_edge_attribute(edge, 'Disease', 'Atherosclerosis')`` :param property_of: Edge to add the attribute to :type property_of: int or edge dict with @id attribute :param name: Attribute name :type name: str :param values: A value or list of values of the attribute :type values: list, string, int or float :param type: The datatype of the attribute values, defaults to the python datatype of the values. See `Supported data types`_ :type type: str :return: None :rtype: None """ if property_of is None: raise TypeError('Edge value is None') if name is None: raise TypeError('Property name is None') if values is None: raise TypeError('Attribute value is None') add_this_edge_attribute = {'po': property_of, 'n': name, 'v': values} if self.edge_attribute_map.get(property_of) is None: self.edge_attribute_map[property_of] = {} elif self.edge_attribute_map[property_of].get(name) is not None: return if type: if type == 'float' or type == 'double': type = 'double' try: if not isinstance(values, float): add_this_edge_attribute['v'] = float(values) except ValueError as e: raise ValueError('Value was not of type %s' % type) if type == 'list_of_float' or type == 'list_of_double': try: if isinstance(values, list): for value in values: if not isinstance(value, float): value = float(value) except ValueError as e: raise ValueError('Value was not of type %s' % type) type = 'list_of_double' add_this_edge_attribute['d'] = type else: use_this_value, attr_type = self._infer_data_type(values) add_this_edge_attribute['v'] = use_this_value add_this_edge_attribute['d'] = attr_type if add_this_edge_attribute['v'] is not None: self.edge_attribute_inventory.append(add_this_edge_attribute) self.edge_attribute_map[property_of][name] = True def add_opaque_aspect(self, oa_name, oa_list): self.opaque_aspect_inventory.append({oa_name: oa_list}) #=================================== # methods to add data by fragment #=================================== def _add_network_attributes_from_fragment(self, fragment): self.nice_cx.networkAttributes.append(fragment) def _add_node_from_fragment(self, fragment): self.nice_cx.nodes[fragment.get('@id')] = fragment def _add_edge_from_fragment(self, fragment): self.nice_cx.edges[fragment.get('@id')] = fragment def _add_node_attribute_from_fragment(self, fragment): if self.nice_cx.nodeAttributes.get(fragment.get('po')) is None: self.nice_cx.nodeAttributes[fragment.get('po')] = [] self.nice_cx.nodeAttributes[fragment.get('po')].append(fragment) def _add_edge_attribute_from_fragment(self, fragment): if self.nice_cx.edgeAttributes.get(fragment.get('po')) is None: self.nice_cx.edgeAttributes[fragment.get('po')] = [] self.nice_cx.edgeAttributes[fragment.get('po')].append(fragment) def _add_citation_from_fragment(self, fragment): self.nice_cx.citations[fragment.get('@id')] = fragment def _add_supports_from_fragment(self, fragment): self.nice_cx.supports[fragment.get('@id')] = fragment def _add_edge_supports_from_fragment(self, fragment): for po_id in fragment.get('po'): self.nice_cx.edgeSupports[po_id] = fragment.get('supports') def _add_node_citations_from_fragment(self, fragment): for po_id in fragment.get('po'): self.nice_cx.nodeCitations[po_id] = fragment.get('citations') def _add_edge_citations_from_fragment(self, fragment): for po_id in fragment.get('po'): self.nice_cx.edgeCitations[po_id] = fragment.get('citations') def get_nice_cx(self): #========================== # ADD CONTEXT #========================== if isinstance(self.context_inventory, dict): self.nice_cx.set_context(self.context_inventory) else: for c in self.context_inventory: self.nice_cx.set_context(c) #============================= # ASSEMBLE NETWORK ATTRIBUTES #============================= #{'n': 'name', 'v': network_name, 'd': 'string'} for k, v in self.network_attribute_inventory.items(): self.nice_cx.add_network_attribute(name=v.get('n'), values=v.get('v'), type=v.get('d')) #========================== # ASSEMBLE NODES #========================== for k, v in self.node_inventory.items(): self.nice_cx.nodes[v.get('@id')] = v #========================== # ASSEMBLE NODE ATTRIBUTES #========================== for a in self.node_attribute_inventory: property_of = a.get('po') if self.nice_cx.nodeAttributes.get(property_of) is None: self.nice_cx.nodeAttributes[property_of] = [] self.nice_cx.nodeAttributes[property_of].append(a) #========================== # ASSEMBLE EDGES #========================== for k, v in self.edge_inventory.items(): self.nice_cx.edges[k] = v #========================== # ASSEMBLE EDGE ATTRIBUTES #========================== for a in self.edge_attribute_inventory: property_of = a.get('po') if self.nice_cx.edgeAttributes.get(property_of) is None: self.nice_cx.edgeAttributes[property_of] = [] self.nice_cx.edgeAttributes[property_of].append(a) #========================== # ASSEMBLE OPAQUE ASPECTS #========================== for oa in self.opaque_aspect_inventory: for k, v in oa.items(): self.nice_cx.add_opaque_aspect(k, v) return self.nice_cx def get_frag_from_list_by_key(self, cx, key): return_list = [] for aspect in cx: if key in aspect: if isinstance(aspect[key], list): for a_item in aspect[key]: return_list.append(a_item) else: return_list.append(aspect[key]) return return_list def load_aspect(self, aspect_name): #with open('Signal1.cx', mode='r') as cx_f: with open('network1.cx', mode='r') as cx_f: aspect_json = json.loads(cx_f.read()) for aspect in aspect_json: if aspect.get(aspect_name) is not None: return aspect.get(aspect_name) def stream_all_aspects(self, uuid): return ijson.items(urlopen('http://dev2.ndexbio.org/v2/network/' + uuid), 'item') def stream_aspect(self, uuid, aspect_name): if aspect_name == 'metaData': print('http://dev2.ndexbio.org/v2/network/' + uuid + '/aspect') md_response = requests.get('http://dev2.ndexbio.org/v2/network/' + uuid + '/aspect') json_respone = md_response.json() return json_respone.get('metaData') else: #password_mgr = HTTPPasswordMgrWithDefaultRealm() #top_level_url = 'http://dev2.ndexbio.org' #password_mgr.add_password(None, top_level_url, self.username, self.password) #handler = HTTPBasicAuthHandler(password_mgr) #opener = build_opener(handler) #install_opener(opener) # Create an OpenerDirector with support for Basic HTTP Authentication... #auth_handler = HTTPBasicAuthHandler() #auth_handler.add_password(None, 'http://dev2.ndexbio.org', 'scratch', 'scratch') #opener = build_opener(auth_handler) # ...and install it globally so it can be used with urlopen. #install_opener(opener) request = Request('http://dev2.ndexbio.org/v2/network/' + uuid + '/aspect/' + aspect_name) base64string = base64.b64encode('%s:%s' % ('scratch', 'scratch')) request.add_header("Authorization", "Basic %s" % base64string) #result = urllib2.urlopen(request) urlopen_result = None try: urlopen_result = urlopen(request) #'http://dev2.ndexbio.org/v2/network/' + uuid + '/aspect/' + aspect_name) except HTTPError as e: print(e.code) return [] except URLError as e: print('Other error') print('URL Error %s' % e.message()) return [] return ijson.items(urlopen_result, 'item') def stream_aspect_raw(self, uuid, aspect_name): return ijson.parse(urlopen('http://dev2.ndexbio.org/v2/network/' + uuid + '/aspect/' + aspect_name)) def _infer_data_type(self, val, split_string=False): if val is None: return None, None attr_type = 'string' if split_string: if isinstance(val, str): val = val.replace('"', '') if ',' in val: val = val.split(',') elif ';' in val: val = val.split(';') processed_value = val if isinstance(val, float) or isinstance(val, np.float) or isinstance(val, np.double): if math.isnan(val): # do something (skip?) processed_value = None elif math.isinf(val): processed_value = 'INFINITY' attr_type = 'double' # CX spec dropped support for float and instead uses double precision elif isinstance(val, int) or isinstance(val, np.int): attr_type = 'integer' elif isinstance(val, list): if len(val) > 0: if isinstance(val[0], float) or isinstance(val[0], np.float) or isinstance(val[0], np.double): attr_type = 'list_of_double' elif isinstance(val[0], int) or isinstance(val[0], np.int): attr_type = 'list_of_integer' else: attr_type = 'list_of_string' return processed_value, attr_type
def create_nice_cx_from_server(server, username=None, password=None, uuid=None): """ Create a NiceCXNetwork based on a network retrieved from NDEx, specified by its UUID. If the network is not public, then username and password arguments for an account on the server with permission to access the network must be supplied. :param server: the URL of the NDEx server hosting the network. :param username: the user name of an account with permission to access the network. :param password: the password of an account with permission to access the network. :param uuid: the UUID of the network. :return: NiceCXNetwork """ niceCxBuilder = NiceCXBuilder() if server and uuid: my_nicecx = NiceCXNetwork() # =================== # METADATA # =================== available_aspects = [] md_aspect_iter = my_nicecx.get_aspect(uuid, 'metaData', server, username, password) if md_aspect_iter: for ae in (o for o in md_aspect_iter): available_aspects.append(ae.get('name')) else: if not username or not password: raise Exception('Network is not available. Username and/or password not supplied') else: raise Exception('Network not available') opaque_aspects = set(available_aspects).difference(known_aspects_min) # ==================== # NETWORK ATTRIBUTES # ==================== if 'networkAttributes' in available_aspects: objects = my_nicecx.get_aspect(uuid, 'networkAttributes', server, username, password) for network_item in objects: niceCxBuilder._add_network_attributes_from_fragment(network_item) #niceCxBuilder.add_network_attribute(network_item.get('n'), network_item.get('v'), network_item.get('d')) # =================== # @CONTEXT # =================== if '@context' in available_aspects: objects = my_nicecx.get_aspect(uuid, '@context', server, username, password) niceCxBuilder.set_context(objects) #nice_cx.set_namespaces(objects) #niceCxBuilder.set_context(objects) # =================== # NODES # =================== if 'nodes' in available_aspects: objects = my_nicecx.get_aspect(uuid, 'nodes', server, username, password) for node_item in objects: niceCxBuilder._add_node_from_fragment(node_item) #niceCxBuilder.add_node(node_item.get('n'), node_item.get('r'), id=node_item.get('@id')) # =================== # EDGES # =================== if 'edges' in available_aspects: objects = my_nicecx.get_aspect(uuid, 'edges', server, username, password) for edge_item in objects: niceCxBuilder._add_edge_from_fragment(edge_item) #niceCxBuilder.add_edge(source=edge_item.get('s'), target=edge_item.get('t'), # interaction=edge_item.get('i'), id=edge_item.get('@id')) # =================== # NODE ATTRIBUTES # =================== if 'nodeAttributes' in available_aspects: objects = my_nicecx.get_aspect(uuid, 'nodeAttributes', server, username, password) for att in objects: niceCxBuilder._add_node_attribute_from_fragment(att) #niceCxBuilder.add_node_attribute(att.get('po'), att.get('n'), att.get('v'), type=att.get('d')) # =================== # EDGE ATTRIBUTES # =================== if 'edgeAttributes' in available_aspects: objects = my_nicecx.get_aspect(uuid, 'edgeAttributes', server, username, password) for att in objects: niceCxBuilder._add_edge_attribute_from_fragment(att) #niceCxBuilder.add_edge_attribute(property_of=att.get('po'), name=att.get('n'), # values=att.get('v'), type=att.get('d')) # =================== # CITATIONS # =================== if 'citations' in available_aspects: objects = my_nicecx.get_aspect(uuid, 'citations', server, username, password) for cit in objects: niceCxBuilder._add_citation_from_fragment(cit) #my_nicecx.citations[cit.get('@id')] = cit #my_nicecx.add_metadata_stub('citations') # =================== # SUPPORTS # =================== if 'supports' in available_aspects: objects = my_nicecx.get_aspect(uuid, 'supports', server, username, password) for sup in objects: niceCxBuilder._add_supports_from_fragment(sup) #my_nicecx.supports[sup.get('@id')] = sup #my_nicecx.add_metadata_stub('supports') # =================== # EDGE SUPPORTS # =================== if 'edgeSupports' in available_aspects: objects = my_nicecx.get_aspect(uuid, 'edgeSupports', server, username, password) for add_this_edge_sup in objects: niceCxBuilder._add_edge_supports_from_fragment(add_this_edge_sup) #for po_id in add_this_edge_sup.get('po'): # my_nicecx.edgeSupports[po_id] = add_this_edge_sup.get('supports') #my_nicecx.add_metadata_stub('edgeSupports') # =================== # NODE CITATIONS # =================== if 'nodeCitations' in available_aspects: objects = my_nicecx.get_aspect(uuid, 'nodeCitations', server, username, password) for node_cit in objects: niceCxBuilder._add_node_citations_from_fragment(node_cit) #for po_id in node_cit.get('po'): # my_nicecx.nodeCitations[po_id] = node_cit.get('citations') #my_nicecx.add_metadata_stub('nodeCitations') # =================== # EDGE CITATIONS # =================== if 'edgeCitations' in available_aspects: objects = my_nicecx.get_aspect(uuid, 'edgeCitations', server, username, password) for edge_cit in objects: niceCxBuilder._add_edge_citations_from_fragment(edge_cit) #for po_id in edge_cit.get('po'): # my_nicecx.nodeCitations[po_id] = edge_cit.get('citations') #my_nicecx.add_metadata_stub('edgeCitations') # =================== # OPAQUE ASPECTS # =================== for oa in opaque_aspects: objects = my_nicecx.get_aspect(uuid, oa, server, username, password) niceCxBuilder.add_opaque_aspect(oa, objects) else: raise Exception('Server and uuid not specified') return niceCxBuilder.get_nice_cx()
def test_simple_create(self): niceCx_creatures = NiceCXNetwork() niceCx_creatures.set_name("Food Web") fox_node = niceCx_creatures.create_node(node_name='Fox') mouse_node = niceCx_creatures.create_node(node_name='Mouse') bird_node = niceCx_creatures.create_node(node_name='Bird') fox_bird_edge = niceCx_creatures.create_edge(edge_source=fox_node, edge_target=bird_node, edge_interaction='interacts-with') fox_mouse_edge = niceCx_creatures.create_edge(edge_source=fox_node, edge_target=mouse_node, edge_interaction='interacts-with') niceCx_creatures.add_node_attribute(property_of=fox_node, name='Color', values='Red') niceCx_creatures.add_node_attribute(property_of=mouse_node, name='Color', values='Gray') niceCx_creatures.add_node_attribute(property_of=bird_node, name='Color', values='Blue') niceCx_creatures.add_edge_attribute(property_of=fox_mouse_edge, name='Hunted', values='On the ground') print(niceCx_creatures.get_node_attribute(fox_node, 'Color'))
def test_set_name(self): niceCx_creatures = NiceCXNetwork() niceCx_creatures.set_name(43) niceCx_creatures.create_node(node_name="tree") upload_message = niceCx_creatures.upload_to(upload_server, upload_username, upload_password) self.assertTrue(upload_message)
def test_bad_name_add_node(self): niceCx_creatures = NiceCXNetwork() niceCx_creatures.set_name("Test Network") node1_id = niceCx_creatures.create_node(node_name=54, node_represents="Tree") upload_message = niceCx_creatures.upload_to(upload_server, upload_username, upload_password) self.assertTrue(upload_message)
def test_update_network_empty(self): updator = NodeMemberUpdator(None, None) net = NiceCXNetwork() self.assertEqual([], updator.update(net))