def test_infer_data_type_empty_list(self): builder = NiceCXBuilder() self.assertEqual(([], 'list_of_string'), builder._infer_data_type([])) self.assertEqual(([], 'list_of_string'), builder._infer_data_type([], split_string=True))
def test_add_network_attribute_no_type(self): builder = NiceCXBuilder() builder.add_network_attribute(name='foo', values='somevalue') net = builder.get_nice_cx() self.assertEqual(['foo'], list(net.get_network_attribute_names())) self.assertEqual({ 'n': 'foo', 'v': 'somevalue' }, net.get_network_attribute('foo'))
def test_add_network_attribute_no_with_type(self): builder = NiceCXBuilder() builder.add_network_attribute(name='foo', values='1.0', type='double') net = builder.get_nice_cx() self.assertEqual(['foo'], list(net.get_network_attribute_names())) self.assertEqual({ 'd': 'double', 'n': 'foo', 'v': '1.0' }, net.get_network_attribute('foo'))
def test_add_edge_no_interaction_no_id(self): builder = NiceCXBuilder() builder.add_edge(source=0, target=1) net = builder.get_nice_cx() self.assertEqual({ '@id': 0, 'i': 'interacts-with', 's': 0, 't': 1 }, net.get_edge(0))
def test_infer_data_type_str_split_is_false(self): builder = NiceCXBuilder() # empty string self.assertEqual(('', 'string'), builder._infer_data_type('')) # string with space self.assertEqual((' ', 'string'), builder._infer_data_type(' ')) # simple string self.assertEqual(('foo', 'string'), builder._infer_data_type('foo')) # simple string with double quote self.assertEqual(('foo"', 'string'), builder._infer_data_type('foo"')) # string with comma delimiter, but split_string is left # to default which is False self.assertEqual(('item1,item2', 'string'), builder._infer_data_type('item1,item2')) # string with comma delimiter, but split_string is left # to default which is False self.assertEqual(('item1;item2', 'string'), builder._infer_data_type('item1;item2')) # string with comma and semicolon delimiter and double quote, # but split_string is left to default which is False self.assertEqual(('item1;item2,item3"', 'string'), builder._infer_data_type('item1;item2,item3"'))
def test_infer_data_type_bool(self): """ Test added for bug: https://github.com/ndexbio/ndex2-client/issues/83 :return: """ builder = NiceCXBuilder() self.assertEqual((True, 'boolean'), builder._infer_data_type(True)) self.assertEqual((True, 'boolean'), builder._infer_data_type(True, split_string=True))
def test_infer_data_type_list_of_integer(self): """ Test added for bug: https://github.com/ndexbio/ndex2-client/issues/83 :return: """ builder = NiceCXBuilder() self.assertEqual(([1], 'list_of_integer'), builder._infer_data_type([1])) self.assertEqual(([1], 'list_of_integer'), builder._infer_data_type([1], split_string=True))
def test_add_node_with_type(self): builder = NiceCXBuilder() builder.add_node(name='xname', represents='xrepresents', data_type='string') net = builder.get_nice_cx() self.assertEqual( { '@id': 0, 'd': 'string', 'n': 'xname', 'r': 'xrepresents' }, net.get_node(0))
def test_set_context(self): # set context as list builder = NiceCXBuilder() builder.set_context([{'a': 'a_url', 'b': 'b_url'}]) res = builder.get_nice_cx() self.assertEqual({'a': 'a_url', 'b': 'b_url'}, res.get_context()) # set context as dict builder = NiceCXBuilder() builder.set_context({'a': 'a_url', 'b': 'b_url'}) res = builder.get_nice_cx() self.assertEqual({'a': 'a_url', 'b': 'b_url'}, res.get_context())
def test_pandas_loading(self): print('Testing: edge_list_network_adrian_small.txt') path_to_network = os.path.join(path_this, 'edge_list_network_adrian_small.txt') niceCxBuilder = NiceCXBuilder() context = { 'signor': 'http://signor.uniroma2.it/relation_result.php?id=', 'BTO': 'http://identifiers.org/bto/BTO:', 'uniprot': 'http://identifiers.org/uniprot/', 'pubmed': 'http://identifiers.org/pubmed/', 'CID': 'http://identifiers.org/pubchem.compound/', 'SID': 'http://identifiers.org/pubchem.substance/', 'chebi': 'http://identifiers.org/chebi/CHEBI:' } with open(path_to_network, 'r') as tsvfile: header = ['Source', 'Target'] df = pd.read_csv(tsvfile, delimiter='\t', engine='python', names=header) nice_cx = ndex2.create_nice_cx_from_pandas( df) #NiceCXNetwork(pandas_df=df) nice_cx.set_context(context) upload_message = nice_cx.upload_to(upload_server, upload_username, upload_password) self.assertTrue('error' not in upload_message)
def test_load_edges(self): print('Testing: NiceCXBuilder') niceCxBuilder = NiceCXBuilder() node_id_1 = niceCxBuilder.add_node(name='node%s' % str(1), represents='ABC') node_id_2 = niceCxBuilder.add_node(name='node%s' % str(2), represents='DEF') niceCxBuilder.add_edge(id=1, source=node_id_1, target=node_id_2, interaction='neighbor') niceCxBuilder.set_name('Network manual build') niceCxBuilder.nice_cx.set_namespaces({'ndex context': 'http://dev.ndexbio.org'}) niceCx = niceCxBuilder.get_nice_cx() #niceCx.set_provenance(['Provenance']) upload_message = niceCx.upload_to(upload_server, upload_username, upload_password) self.assertTrue(upload_message)
def test_infer_data_type_int(self): """ Test added for bug: https://github.com/ndexbio/ndex2-client/issues/83 :return: """ builder = NiceCXBuilder() self.assertEqual((1, 'integer'), builder._infer_data_type(1)) self.assertEqual((1, 'integer'), builder._infer_data_type(1, split_string=True)) self.assertEqual((0, 'integer'), builder._infer_data_type(0)) self.assertEqual((0, 'integer'), builder._infer_data_type(0, split_string=True)) self.assertEqual((-1, 'integer'), builder._infer_data_type(-1)) self.assertEqual((-1, 'integer'), builder._infer_data_type(-1, split_string=True))
def test_load_nodes(self): print('Testing: Manual network build') niceCxBuilder = NiceCXBuilder() #niceCx = ndex2.create_empty_nice_cx() #NiceCXNetwork() gene_list = ['OR2J3', 'AANAT', 'CCDC158', 'PLAC8L1', 'CLK1', 'GLTP', 'PITPNM2','TRAPPC8', 'EIF2S2', 'ST14', 'NXF1', 'H3F3B','FOSB', 'MTMR4', 'USP46', 'CDH11', 'ENAH', 'CNOT7', 'STK39', 'CAPZA1', 'STIM2', 'DLL4', 'WEE1', 'MYO1D', 'TEAD3'] max_edge = 1004 for i in range(1,max_edge): node_id = niceCxBuilder.add_node(name='node%s' % str(i), represents=gene_list[i % 10]) if i > 1 and i < (max_edge - 1): niceCxBuilder.add_edge(i - 1, i, 'neighbor-of') #niceCx.create_node(id=i, node_name='node%s' % str(i), node_represents=gene_list[i]) niceCx = niceCxBuilder.get_nice_cx() upload_message = niceCx.upload_to(upload_server, upload_username, upload_password) self.assertTrue(upload_message)
def test_pandas_loading(self): print('Testing: MDA1.txt') path_to_network = os.path.join(path_this, 'MDA1.txt') niceCxBuilder = NiceCXBuilder() with open(path_to_network, 'r') as tsvfile: header = [h.strip() for h in tsvfile.readline().split('\t')] df = pd.read_csv(tsvfile,delimiter='\t',engine='python',names=header) for index, row in df.iterrows(): node_id_1 = niceCxBuilder.add_node(name=row['Bait'], represents=row['Bait']) node_id_2 = niceCxBuilder.add_node(name=row['Prey'], represents=row['Prey']) niceCxBuilder.add_edge(id=index, source=node_id_1, target=node_id_2, interaction='interacts-with') niceCx = niceCxBuilder.get_nice_cx() upload_message = niceCx.upload_to(upload_server, upload_username, upload_password) my_df = pd.DataFrame(data=[(4,14),(5,15),(6,16),(7,17)], index=range(0,4), columns=['A','B']) self.assertIsNotNone(my_df)
def create_nice_cx_from_raw_cx(cx): """ Create a NiceCXNetwork from a CX json object. (see http://www.home.ndexbio.org/data-model) :param cx: a valid CX document :return: NiceCXNetwork """ niceCxBuilder = NiceCXBuilder() #my_nicecx = NiceCXNetwork() if cx: # =================== # METADATA # =================== available_aspects = [] for ae in (o for o in niceCxBuilder.get_frag_from_list_by_key( cx, 'metaData')): available_aspects.append(ae.get('name')) opaque_aspects = set(available_aspects).difference(known_aspects_min) # ==================== # NETWORK ATTRIBUTES # ==================== if 'networkAttributes' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key( cx, 'networkAttributes') for network_item in objects: niceCxBuilder._add_network_attributes_from_fragment( network_item) # =================== # NODES # =================== if 'nodes' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'nodes') for node_item in objects: niceCxBuilder._add_node_from_fragment(node_item) # =================== # EDGES # =================== if 'edges' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'edges') for edge_item in objects: niceCxBuilder._add_edge_from_fragment(edge_item) # =================== # NODE ATTRIBUTES # =================== if 'nodeAttributes' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key( cx, 'nodeAttributes') for att in objects: niceCxBuilder._add_node_attribute_from_fragment(att) # =================== # EDGE ATTRIBUTES # =================== if 'edgeAttributes' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key( cx, 'edgeAttributes') for att in objects: niceCxBuilder._add_edge_attribute_from_fragment(att) # =================== # CITATIONS # =================== if 'citations' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'citations') for cit in objects: niceCxBuilder._add_citation_from_fragment(cit) # =================== # SUPPORTS # =================== if 'supports' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'supports') for sup in objects: niceCxBuilder._add_supports_from_fragment(sup) # =================== # EDGE SUPPORTS # =================== if 'edgeSupports' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key( cx, 'edgeSupports') for add_this_edge_sup in objects: niceCxBuilder._add_edge_supports_from_fragment( add_this_edge_sup) # =================== # NODE CITATIONS # =================== if 'nodeCitations' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key( cx, 'nodeCitations') for node_cit in objects: niceCxBuilder._add_node_citations_from_fragment(node_cit) # =================== # EDGE CITATIONS # =================== if 'edgeCitations' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key( cx, 'edgeCitations') for edge_cit in objects: niceCxBuilder._add_edge_citations_from_fragment(edge_cit) # =================== # OPAQUE ASPECTS # =================== for oa in opaque_aspects: #TODO - Add context to builder if oa == '@context': objects = niceCxBuilder.get_frag_from_list_by_key(cx, oa) niceCxBuilder.set_context( objects) #nice_cx.set_namespaces(objects) else: objects = niceCxBuilder.get_frag_from_list_by_key(cx, oa) niceCxBuilder.add_opaque_aspect(oa, objects) return niceCxBuilder.get_nice_cx() else: raise Exception('CX is empty')
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_manual_build(self): print('Testing: Manual build with NiceCXBuilder') nice_cx_builder = NiceCXBuilder() node_id_1 = nice_cx_builder.add_node(name=1, represents=2) node_id_2 = nice_cx_builder.add_node(name='node%s' % str(2), represents='DEF') try: nice_cx_builder.add_node_attribute(node_id_1, 'testing_attr', None) except TypeError as te: print('Correctly identified bad node value') nice_cx_builder.add_node_attribute(node_id_1, 'testing_attr_double', [1.2, 2.5, 2.7]) nice_cx_builder.add_node_attribute(node_id_1, 'testing_attr_int', [16, 4, 8]) nice_cx_builder.add_node_attribute( node_id_1, 'testing_attr_int', [16, 4, 8]) # duplicate - should be ignored nice_cx_builder.add_node_attribute( node_id_1, 'testing_attr_int', [16, 4, 8]) # duplicate - should be ignored try: nice_cx_builder.add_node_attribute(node_id_1, 'testing_attr2', [10.2, 20.5, 'abc'], type='list_of_float') except ValueError: print('Correctly identified bad value in node attribute list') edge_id = nice_cx_builder.add_edge(id=1, source=node_id_1, target=node_id_2, interaction='test-relationship') nice_cx_builder.add_edge_attribute(edge_id, 'testing_attr', [1.2, 2.5, '2.7'], type='list_of_float') nice_cx_builder.add_edge_attribute( edge_id, 'testing_attr', [1.2, 2.5, '2.7'], type='list_of_float') # duplicate - should be ignored nice_cx_builder.add_edge_attribute( edge_id, 'testing_attr', [1.2, 2.5, '2.7'], type='list_of_float') # duplicate - should be ignored try: nice_cx_builder.add_edge_attribute(edge_id, 'testing_attr2', [10.2, 20.5, 'abc'], type='list_of_float') except ValueError: print('Correctly identified bad value in list') nice_cx_builder.set_name('Network manual build') nice_cx_builder.nice_cx.set_namespaces( {'ndex context': 'http://dev.ndexbio.org'}) nice_cx = nice_cx_builder.get_nice_cx() node_attrs = nice_cx.get_node_attributes(node_id_1) edge_attrs = nice_cx.get_edge_attributes(edge_id) upload_message = nice_cx.upload_to(upload_server, upload_username, upload_password) self.assertTrue(upload_message) node1_attr_double = nice_cx.get_node_attribute(node_id_1, 'testing_attr_double') self.assertTrue(node1_attr_double.get('d') == 'list_of_double') node1_attr_int = nice_cx.get_node_attribute(node_id_1, 'testing_attr_int') self.assertTrue(node1_attr_int.get('d') == 'list_of_integer') self.assertTrue(len(node_attrs) == 2) self.assertTrue(len(edge_attrs) == 1)
def test_context(self): print('Testing: context') context = { 'signor': 'http://signor.uniroma2.it/relation_result.php?id=', 'BTO': 'http://identifiers.org/bto/BTO:', 'uniprot': 'http://identifiers.org/uniprot/', 'pubmed': 'http://identifiers.org/pubmed/', 'CID': 'http://identifiers.org/pubchem.compound/', 'SID': 'http://identifiers.org/pubchem.substance/', 'chebi': 'http://identifiers.org/chebi/CHEBI:' } nice_cx_builder = NiceCXBuilder() nice_cx_builder.set_context(context) node_id_1 = nice_cx_builder.add_node(name='ABC', represents='ABC') node_id_2 = nice_cx_builder.add_node(name='DEF', represents='DEF') nice_cx_builder.add_node_attribute(node_id_1, 'testing_attr_double', [1.2, 2.5, 2.7]) nice_cx_builder.add_node_attribute(node_id_1, 'diffusion_output_heat', '1.4599107187941883E-4') nice_cx_builder.add_node_attribute(node_id_2, 'diffusion_output_heat', '1.2387941883E-4') nice_cx_builder.add_node_attribute(node_id_1, 'aliases', [ 'uniprot knowledgebase:Q5I2A4', 'uniprot knowledgebase:Q8N7E5', 'uniprot knowledgebase:Q8TAZ6' ]) nice_cx_builder.add_node_attribute(node_id_1, 'diffusion_output_rank', 1) nice_cx_builder.add_node_attribute(node_id_2, 'diffusion_output_rank', 2) edge_id = nice_cx_builder.add_edge(id=1, source=node_id_1, target=node_id_2, interaction='test-relationship') nice_cx_builder.add_edge_attribute(edge_id, 'citation', ['pubmed:21880741'], type='list_of_string') nice_cx = nice_cx_builder.get_nice_cx() node_attr_to_change = nice_cx.get_node_attribute( node_id_1, 'testing_attr_double') node_attr_to_change['v'] = [1.0, 2.0, 3.0] #for node_id, node in nice_cx.get_nodes(): #node_attr_to_condition = nice_cx.get_node_attribute(node_id, 'diffusion_output_heat') #node_attr_to_condition['v'] = ("%0.15f" % float(node_attr_to_condition.get('v'))) #node_attr_array_to_string = nice_cx.get_node_attribute(node_id, 'aliases') #node_attr_to_condition['v'] = ("%0.15f" % float(node_attr_to_condition.get('v'))) #nice_cx.remove_node_attribute(node_id, 'aliases') R = nice_cx.to_networkx() nos = [] for n in R.nodes(): if R.node[n]['diffusion_output_rank'] < 10: R.node[n]['nid'] = n nos.append(R.node[n]) nos = sorted(nos, key=lambda k: k['diffusion_output_rank']) for no in nos: print("id: " + str(no['nid']) + " name: " + no['nid'] + " rank: " + str(no['diffusion_output_rank']) + " heat: " + str(no['diffusion_output_heat'])) node_list2 = next(iter(nice_cx.nodes)) node_list = list(nice_cx.get_nodes()) print(list(nice_cx.get_nodes())) with open('my_cx.cx', 'w') as file: json.dump(nice_cx.to_cx(), file) upload_message = nice_cx.upload_to(upload_server, upload_username, upload_password) self.assertTrue(upload_message)
def test_context(self): print('Testing: context') context = { 'signor': 'http://signor.uniroma2.it/relation_result.php?id=', 'BTO': 'http://identifiers.org/bto/BTO:', 'uniprot': 'http://identifiers.org/uniprot/', 'pubmed': 'http://identifiers.org/pubmed/', 'CID': 'http://identifiers.org/pubchem.compound/', 'SID': 'http://identifiers.org/pubchem.substance/', 'chebi': 'http://identifiers.org/chebi/CHEBI:' } nice_cx_builder = NiceCXBuilder() nice_cx_builder.set_context(context) node_id_1 = nice_cx_builder.add_node(name='ABC', represents='ABC') node_id_2 = nice_cx_builder.add_node(name='DEF', represents='DEF') nice_cx_builder.add_node_attribute(node_id_1, 'testing_attr_double', [1.2, 2.5, 2.7]) nice_cx_builder.add_node_attribute(node_id_1, 'diffusion_output_heat', '1.4599107187941883E-4') nice_cx_builder.add_node_attribute(node_id_2, 'diffusion_output_heat', '1.2387941883E-4') nice_cx_builder.add_node_attribute(node_id_1, 'aliases', ['uniprot knowledgebase:Q5I2A4', 'uniprot knowledgebase:Q8N7E5', 'uniprot knowledgebase:Q8TAZ6']) nice_cx_builder.add_node_attribute(node_id_1, 'diffusion_output_rank', 1) nice_cx_builder.add_node_attribute(node_id_2, 'diffusion_output_rank', 2) edge_id = nice_cx_builder.add_edge(id=1, source=node_id_1, target=node_id_2, interaction='test-relationship') nice_cx_builder.add_edge_attribute(edge_id, 'citation', ['pubmed:21880741'], type='list_of_string') nice_cx = nice_cx_builder.get_nice_cx() node_attr_to_change = nice_cx.get_node_attribute(node_id_1, 'testing_attr_double') node_attr_to_change['v'] = [1.0, 2.0, 3.0] #for node_id, node in nice_cx.get_nodes(): #node_attr_to_condition = nice_cx.get_node_attribute(node_id, 'diffusion_output_heat') #node_attr_to_condition['v'] = ("%0.15f" % float(node_attr_to_condition.get('v'))) #node_attr_array_to_string = nice_cx.get_node_attribute(node_id, 'aliases') #node_attr_to_condition['v'] = ("%0.15f" % float(node_attr_to_condition.get('v'))) #nice_cx.remove_node_attribute(node_id, 'aliases') R = nice_cx.to_networkx() nos = [] for n in R.nodes(): if R.node[n]['diffusion_output_rank'] < 10: R.node[n]['nid'] = n nos.append(R.node[n]) nos = sorted(nos, key=lambda k: k['diffusion_output_rank']) for no in nos: print("id: " + str(no['nid']) + " name: " + no['nid'] + " rank: " + str( no['diffusion_output_rank']) + " heat: " + str(no['diffusion_output_heat'])) node_list2 = next(iter(nice_cx.nodes)) node_list = list(nice_cx.get_nodes()) print(list(nice_cx.get_nodes())) with open('my_cx.cx', 'w') as file: json.dump(nice_cx.to_cx(), file) upload_message = nice_cx.upload_to(upload_server, upload_username, upload_password) self.assertTrue(upload_message)
def test_manual_build(self): print('Testing: Manual build with NiceCXBuilder') nice_cx_builder = NiceCXBuilder() node_id_1 = nice_cx_builder.add_node(name=1, represents=2) node_id_2 = nice_cx_builder.add_node(name='node%s' % str(2), represents='DEF') try: nice_cx_builder.add_node_attribute(node_id_1, 'testing_attr', None) except TypeError as te: print('Correctly identified bad node value') nice_cx_builder.add_node_attribute(node_id_1, 'testing_attr_double', [1.2, 2.5, 2.7]) nice_cx_builder.add_node_attribute(node_id_1, 'testing_attr_int', [16, 4, 8]) nice_cx_builder.add_node_attribute(node_id_1, 'testing_attr_int', [16, 4, 8]) # duplicate - should be ignored nice_cx_builder.add_node_attribute(node_id_1, 'testing_attr_int', [16, 4, 8]) # duplicate - should be ignored try: nice_cx_builder.add_node_attribute(node_id_1, 'testing_attr2', [10.2, 20.5, 'abc'], type='list_of_float') except ValueError: print('Correctly identified bad value in node attribute list') edge_id = nice_cx_builder.add_edge(id=1, source=node_id_1, target=node_id_2, interaction='test-relationship') nice_cx_builder.add_edge_attribute(edge_id, 'testing_attr', [1.2, 2.5, '2.7'], type='list_of_float') nice_cx_builder.add_edge_attribute(edge_id, 'testing_attr', [1.2, 2.5, '2.7'], type='list_of_float') # duplicate - should be ignored nice_cx_builder.add_edge_attribute(edge_id, 'testing_attr', [1.2, 2.5, '2.7'], type='list_of_float') # duplicate - should be ignored try: nice_cx_builder.add_edge_attribute(edge_id, 'testing_attr2', [10.2, 20.5, 'abc'], type='list_of_float') except ValueError: print('Correctly identified bad value in list') nice_cx_builder.set_name('Network manual build') nice_cx_builder.nice_cx.set_namespaces({'ndex context': 'http://dev.ndexbio.org'}) nice_cx = nice_cx_builder.get_nice_cx() node_attrs = nice_cx.get_node_attributes(node_id_1) edge_attrs = nice_cx.get_edge_attributes(edge_id) upload_message = nice_cx.upload_to(upload_server, upload_username, upload_password) self.assertTrue(upload_message) node1_attr_double = nice_cx.get_node_attribute(node_id_1, 'testing_attr_double') self.assertTrue(node1_attr_double.get('d') == 'list_of_double') node1_attr_int = nice_cx.get_node_attribute(node_id_1, 'testing_attr_int') self.assertTrue(node1_attr_int.get('d') == 'list_of_integer') self.assertTrue(len(node_attrs) == 2) self.assertTrue(len(edge_attrs) == 1)
def create_nice_cx_from_networkx(G): """ Creates a :py:class:`~ndex2.nice_cx_network.NiceCXNetwork` based on a networkx graph. The resulting :py:class:`~ndex2.nice_cx_network.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. The 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: :py:class:`~ndex2.nice_cx_network.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 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 :py:func:`~ndex2.nice_cx_network.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 :py:func:`~ndex2.nice_cx_network.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 :rtype: :py:func:`~ndex2.nice_cx_network.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_infer_data_type_double(self): """ Test added for bug: https://github.com/ndexbio/ndex2-client/issues/83 :return: """ builder = NiceCXBuilder() self.assertEqual((1.5, 'double'), builder._infer_data_type(1.5)) self.assertEqual((1.5, 'double'), builder._infer_data_type(1.5, split_string=True)) self.assertEqual((0.0, 'double'), builder._infer_data_type(0.0)) self.assertEqual((0.0, 'double'), builder._infer_data_type(0.0, split_string=True)) self.assertEqual((-1.0, 'double'), builder._infer_data_type(-1.0)) self.assertEqual((-1.0, 'double'), builder._infer_data_type(-1.0, split_string=True)) self.assertEqual((-1.0, 'double'), builder._infer_data_type(-1.0)) self.assertEqual((-1.0, 'double'), builder._infer_data_type(-1.0, split_string=True)) self.assertEqual((None, 'double'), builder._infer_data_type(math.nan)) self.assertEqual((None, 'double'), builder._infer_data_type(math.nan, split_string=True)) self.assertEqual(('INFINITY', 'double'), builder._infer_data_type(math.inf)) self.assertEqual(('INFINITY', 'double'), builder._infer_data_type(math.inf, split_string=True))
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 :py:func:`~ndex2.nice_cx_network.NiceCXNetwork` from a :py:class:`pandas.DataFrame` in which each row specifies one edge in the network. .. versionchanged:: 3.5.0 Removed print statements showing progress and network name is now being set If only the **df** argument is provided the :py:class:`pandas.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, then those and any other arguments refer to headers in the :py:class:`pandas.DataFrame`, controlling the mapping of columns to the attributes of nodes, and edges in the resulting :py:func:`~ndex2.nice_cx_network.NiceCXNetwork`. If a header is not mapped, the corresponding column is ignored. If the edge_interaction is not specified, interaction is set to "interacts-with" .. code-block:: python import ndex2 import pandas as pd data = {'source': ['Node 1','Node 2'], 'target': ['Node 2','Node 3'], 'interaction': ['helps', 'hurts']} df = pd.DataFrame.from_dict(data) net = ndex2.create_nice_cx_from_pandas(df, source_field='source', target_field='target', edge_interaction='interaction') print(net.get_nodes()) print(net.get_edges()) .. note:: The datatype for everything added to the network is the CX string type :param df: Pandas dataframe to process :type df: :py:class:`pandas.DataFrame` :param source_field: header name specifying the name of the source node. :type source_field: str :param target_field: header name specifying the name of the target node. :type target_field: str :param source_node_attr: list of header names specifying attributes of the source node. :type source_node_attr: list :param target_node_attr: list of header names specifying attributes of the target node. :type target_node_attr: list :param edge_attr: list of header names specifying attributes of the edge. :type edge_attr: list :param edge_interaction: the relationship between the source node and the target node, defaulting to "interacts-with" :type edge_interaction: str :param source_represents: :type source_represents: str :param target_represents: :type target_represents: str :return: NiceCXNetwork :rtype: :py:func:`~ndex2.nice_cx_network.NiceCXNetwork` """ # ==================================================== # IF NODE FIELD NAME (SOURCE AND TARGET) IS PROVIDED # THEN USE THOSE FIELDS OTHERWISE USE INDEX 0 & 1 # ==================================================== source_predicate = '' target_predicate = '' cx_builder = NiceCXBuilder() cx_builder.set_name('created from pandas by ' 'ndex2.create_nice_cx_from_pandas()') if source_field and target_field: for index, row in df.iterrows(): # ============= # ADD NODES # ============= if source_represents is not None: source_node_id = cx_builder.add_node( name=source_predicate + str(row[source_field]), represents=source_predicate + str(row[source_represents])) else: source_node_id = cx_builder.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 = cx_builder.add_node( name=target_predicate + str(row[target_field]), represents=target_predicate + str(row[target_represents])) else: target_node_id = cx_builder.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' cx_builder.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' cx_builder.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' cx_builder.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' cx_builder.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 = cx_builder.add_node(name=str(row[0]), represents=str(row[0])) target_node_id = cx_builder.add_node(name=str(row[1]), represents=str(row[1])) # ============= # ADD EDGES # ============= if len(row) > 2: cx_builder.add_edge(id=index, source=source_node_id, target=target_node_id, interaction=row[2]) else: cx_builder.add_edge(id=index, source=source_node_id, target=target_node_id, interaction='interacts-with') return cx_builder.get_nice_cx() # my_nicecx
def create_nice_cx_from_server(server, username=None, password=None, uuid=None): """ Create a :py:func:`~ndex2.nice_cx_network.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 :rtype: :py:func:`~ndex2.nice_cx_network.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 load_matrix_to_ndex(x, x_cols, x_rows, server, username, password, name): """ Testing 1 :param X: param 1 :type X: :param X_cols: :type X_cols: :param X_rows: :type X_rows: :param server: :type server: :param username: :type username: :param password: :type password: :param name: :type name: :return: :rtype: """ if not isinstance(x, np.ndarray): raise Exception('Provided matrix is not of type numpy.ndarray') if not isinstance(x_cols, list): raise Exception('Provided column header is not in the correct format. Please provide a list of strings') if not isinstance(x_rows, list): raise Exception('Provided row header is not in the correct format. Please provide a list of strings') if not x.flags['C_CONTIGUOUS']: x = np.ascontiguousarray(x) serialized = base64.b64encode(x.tobytes()) nice_cx_builder = NiceCXBuilder() nice_cx_builder.set_name(name) nice_cx_builder.add_node(name='Sim Matrix', represents='Sim Matrix') nice_cx_builder.add_opaque_aspect('matrix', [{'v': serialized}]) nice_cx_builder.add_opaque_aspect('matrix_cols', [{'v': x_cols}]) nice_cx_builder.add_opaque_aspect('matrix_rows', [{'v': x_rows}]) nice_cx_builder.add_opaque_aspect('matrix_dtype', [{'v': x.dtype.name}]) nice_cx = nice_cx_builder.get_nice_cx() #print(x) ont_url = nice_cx.upload_to(server, username, password) return ont_url
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 create_nice_cx_from_raw_cx(cx): """ Create a NiceCXNetwork from a CX json object. (see http://www.home.ndexbio.org/data-model) :param cx: a valid CX document :return: NiceCXNetwork """ niceCxBuilder = NiceCXBuilder() #my_nicecx = NiceCXNetwork() if cx: # =================== # METADATA # =================== available_aspects = [] for ae in (o for o in niceCxBuilder.get_frag_from_list_by_key(cx, 'metaData')): available_aspects.append(ae.get('name')) opaque_aspects = set(available_aspects).difference(known_aspects_min) # ==================== # NETWORK ATTRIBUTES # ==================== if 'networkAttributes' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'networkAttributes') for network_item in objects: niceCxBuilder._add_network_attributes_from_fragment(network_item) # =================== # NODES # =================== if 'nodes' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'nodes') for node_item in objects: niceCxBuilder._add_node_from_fragment(node_item) # =================== # EDGES # =================== if 'edges' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'edges') for edge_item in objects: niceCxBuilder._add_edge_from_fragment(edge_item) # =================== # NODE ATTRIBUTES # =================== if 'nodeAttributes' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'nodeAttributes') for att in objects: niceCxBuilder._add_node_attribute_from_fragment(att) # =================== # EDGE ATTRIBUTES # =================== if 'edgeAttributes' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'edgeAttributes') for att in objects: niceCxBuilder._add_edge_attribute_from_fragment(att) # =================== # CITATIONS # =================== if 'citations' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'citations') for cit in objects: niceCxBuilder._add_citation_from_fragment(cit) # =================== # SUPPORTS # =================== if 'supports' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'supports') for sup in objects: niceCxBuilder._add_supports_from_fragment(sup) # =================== # EDGE SUPPORTS # =================== if 'edgeSupports' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'edgeSupports') for add_this_edge_sup in objects: niceCxBuilder._add_edge_supports_from_fragment(add_this_edge_sup) # =================== # NODE CITATIONS # =================== if 'nodeCitations' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'nodeCitations') for node_cit in objects: niceCxBuilder._add_node_citations_from_fragment(node_cit) # =================== # EDGE CITATIONS # =================== if 'edgeCitations' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'edgeCitations') for edge_cit in objects: niceCxBuilder._add_edge_citations_from_fragment(edge_cit) # =================== # OPAQUE ASPECTS # =================== for oa in opaque_aspects: #TODO - Add context to builder if oa == '@context': objects = niceCxBuilder.get_frag_from_list_by_key(cx, oa) niceCxBuilder.set_context(objects) #nice_cx.set_namespaces(objects) else: objects = niceCxBuilder.get_frag_from_list_by_key(cx, oa) niceCxBuilder.add_opaque_aspect(oa, objects) return niceCxBuilder.get_nice_cx() else: raise Exception('CX is empty')
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 create_nice_cx_from_raw_cx(cx): """ Create a :py:func:`~ndex2.nice_cx_network.NiceCXNetwork` from a as a `list` of `dict` objects in `CX format <https://www.home.ndexbio.org/data-model/>`__ Example: .. code-block:: python import json import ndex2 # cx_as_str is a str containing JSON in CX format above net_cx = ndex2.create_nice_cx_from_raw_cx(json.loads(cx_as_str)) :param cx: CX as a `list` of `dict` objects :type cx: list :return: NiceCXNetwork :rtype: :py:func:`~ndex2.nice_cx_network.NiceCXNetwork` """ if not cx: raise Exception('CX is empty') niceCxBuilder = NiceCXBuilder() # =================== # METADATA # =================== available_aspects = [] for ae in ( o for o in niceCxBuilder.get_frag_from_list_by_key(cx, 'metaData')): available_aspects.append(ae.get('name')) opaque_aspects = set(available_aspects).difference(known_aspects_min) # ==================== # NETWORK ATTRIBUTES # ==================== if 'networkAttributes' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key( cx, 'networkAttributes') for network_item in objects: niceCxBuilder._add_network_attributes_from_fragment(network_item) # =================== # NODES # =================== if 'nodes' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'nodes') for node_item in objects: niceCxBuilder._add_node_from_fragment(node_item) # =================== # EDGES # =================== if 'edges' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'edges') for edge_item in objects: niceCxBuilder._add_edge_from_fragment(edge_item) # =================== # NODE ATTRIBUTES # =================== if 'nodeAttributes' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'nodeAttributes') for att in objects: niceCxBuilder._add_node_attribute_from_fragment(att) # =================== # EDGE ATTRIBUTES # =================== if 'edgeAttributes' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'edgeAttributes') for att in objects: niceCxBuilder._add_edge_attribute_from_fragment(att) # =================== # CITATIONS # =================== if 'citations' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'citations') for cit in objects: niceCxBuilder._add_citation_from_fragment(cit) # =================== # SUPPORTS # =================== if 'supports' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'supports') for sup in objects: niceCxBuilder._add_supports_from_fragment(sup) # =================== # EDGE SUPPORTS # =================== if 'edgeSupports' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'edgeSupports') for add_this_edge_sup in objects: niceCxBuilder._add_edge_supports_from_fragment(add_this_edge_sup) # =================== # NODE CITATIONS # =================== if 'nodeCitations' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'nodeCitations') for node_cit in objects: niceCxBuilder._add_node_citations_from_fragment(node_cit) # =================== # EDGE CITATIONS # =================== if 'edgeCitations' in available_aspects: objects = niceCxBuilder.get_frag_from_list_by_key(cx, 'edgeCitations') for edge_cit in objects: niceCxBuilder._add_edge_citations_from_fragment(edge_cit) # =================== # OPAQUE ASPECTS # =================== for oa in opaque_aspects: #TODO - Add context to builder if oa == '@context': objects = niceCxBuilder.get_frag_from_list_by_key(cx, oa) niceCxBuilder.set_context( objects) #nice_cx.set_namespaces(objects) else: objects = niceCxBuilder.get_frag_from_list_by_key(cx, oa) niceCxBuilder.add_opaque_aspect(oa, objects) return niceCxBuilder.get_nice_cx()
def test_add_node_attribute(self): builder = NiceCXBuilder() # property_of is None try: builder.add_node_attribute(None, 'xname', 'xvalue') self.fail('Expected TypeError') except TypeError as te: self.assertEqual('Node value is None', str(te)) # name is None try: builder.add_node_attribute(0, None, 'xvalue') self.fail('Expected TypeError') except TypeError as te: self.assertEqual('Property name is None', str(te)) # values is None try: builder.add_node_attribute(0, 'xname', None) self.fail('Expected TypeError') except TypeError as te: self.assertEqual('Attribute value is None', str(te)) # duplicate check builder.add_node('node 0') builder.add_node_attribute(0, 'xname', 'xvalue') net = builder.get_nice_cx() self.assertEqual({ 'd': 'string', 'n': 'xname', 'po': 0, 'v': 'xvalue' }, net.get_node_attribute(0, 'xname')) builder.add_node_attribute(0, 'xname', 'NEW_VALUE') net = builder.get_nice_cx() self.assertEqual({ 'd': 'string', 'n': 'xname', 'po': 0, 'v': 'xvalue' }, net.get_node_attribute(0, 'xname')) # test type is double builder.add_node_attribute(0, 'dcheck', '2.0', type='double') net = builder.get_nice_cx() self.assertEqual({ 'd': 'double', 'n': 'dcheck', 'po': 0, 'v': 2.0 }, net.get_node_attribute(0, 'dcheck')) # test type is list_of_double builder.add_node_attribute(0, 'dchecklist', [2.0], type='list_of_double') net = builder.get_nice_cx() self.assertEqual( { 'd': 'list_of_double', 'n': 'dchecklist', 'po': 0, 'v': [2.0] }, net.get_node_attribute(0, 'dchecklist'))
def load_matrix_to_ndex(x, x_cols, x_rows, server, username, password, name): """ Testing 1 :param X: param 1 :type X: :param X_cols: :type X_cols: :param X_rows: :type X_rows: :param server: :type server: :param username: :type username: :param password: :type password: :param name: :type name: :return: :rtype: """ if not isinstance(x, np.ndarray): raise Exception('Provided matrix is not of type numpy.ndarray') if not isinstance(x_cols, list): raise Exception( 'Provided column header is not in the correct format. Please provide a list of strings' ) if not isinstance(x_rows, list): raise Exception( 'Provided row header is not in the correct format. Please provide a list of strings' ) if not x.flags['C_CONTIGUOUS']: x = np.ascontiguousarray(x) serialized = base64.b64encode(x.tobytes()) nice_cx_builder = NiceCXBuilder() nice_cx_builder.set_name(name) nice_cx_builder.add_node(name='Sim Matrix', represents='Sim Matrix') nice_cx_builder.add_opaque_aspect('matrix', [{'v': serialized}]) nice_cx_builder.add_opaque_aspect('matrix_cols', [{'v': x_cols}]) nice_cx_builder.add_opaque_aspect('matrix_rows', [{'v': x_rows}]) nice_cx_builder.add_opaque_aspect('matrix_dtype', [{'v': x.dtype.name}]) nice_cx = nice_cx_builder.get_nice_cx() ont_url = nice_cx.upload_to(server, username, password) return ont_url
def test_infer_data_type_none_val(self): builder = NiceCXBuilder() self.assertEqual((None, None), builder._infer_data_type(None))
def convert_pandas_to_nice_cx_with_load_plan(pandas_dataframe, load_plan, max_rows=None, name=None, description=None, network_attributes=None, provenance=None): # open the schema first here = path.abspath(path.dirname(__file__)) with open(path.join(here, 'loading_plan_schema.json')) as json_file: plan_schema = json.load(json_file) jsonschema.validate(load_plan, plan_schema) node_lookup = {} nice_cx_builder = NiceCXBuilder() row_count = 0 t1 = int(time.time() * 1000) #Add context if they are defined context = load_plan.get('context') if context: if network_attributes is None: network_attributes = [] network_attributes.append({"n": "@context", "v": json.dumps(context)}) total_row_count = pandas_dataframe.shape if len(total_row_count) > 1: total_row_count = str(total_row_count[0]) for index, row in pandas_dataframe.iterrows(): # As each row is processed, self.G_nx is updated process_row(nice_cx_builder, load_plan, row, node_lookup) row_count = row_count + 1 if max_rows and row_count > max_rows + 2: break if row_count % 2500 == 0: logger.info('processing %s out of %s edges' % (str(row_count), total_row_count)) if network_attributes: for attribute in network_attributes: if attribute.get("n") == "name": nice_cx_builder.set_name(attribute.get("v")) else: nice_cx_builder.add_network_attribute( name=attribute.get('n'), values=attribute.get('v'), type=attribute.get('d')) tsv_data_event = { "inputs": None, "startedAtTime": t1, "endedAtTime": int(time.time() * 1000), "eventType": "TSV network generation", "properties": [{ "name": "TSV loader version", "value": version }] } # name and description take precedence over any prior values if name: nice_cx_builder.set_name(name) if description: nice_cx_builder.add_network_attribute(name='description', values=description) return nice_cx_builder.get_nice_cx()
def create_nice_cx_from_networkx(G): """ Creates a :py:class:`~ndex2.nice_cx_network.NiceCXNetwork` based on a :class:`networkx.Graph` graph. .. versionchanged:: 3.5.0 Major refactor to fix multiple bugs #83, #84, #90 .. code-block:: python import ndex2 import networkx as nx G = nx.Graph() G.add_node(1, someval=1.5, name='node 1') G.add_node(2, someval=2.5, name='node 2') G.add_edge(1, 2, weight=5) print(ndex2.create_nice_cx_from_networkx(G).to_cx()) The resulting :py:class:`~ndex2.nice_cx_network.NiceCXNetwork` contains the nodes, edges and their attributes from the :class:`networkx.Graph` graph and also preserves the graph 'pos' attribute as a CX cartesian coordinates aspect :py:const:`~ndex2.constants.CARTESIAN_LAYOUT_ASPECT` with the values of `Y` inverted Description of how conversion is performed: **Network:** * Network name is set value of ``G.graph.get('name')`` or to ``created from networkx by ndex2.create_nice_cx_networkx()`` if `name` is ``None`` or not present **Nodes:** * Node id is value of ``n`` from this for loop: ``for n, d G.nodes(data=True):`` if ``n`` is **NOT** an :py:class:`int`, new ids starting from ``0`` are used * Node name is value of `name` attribute on the node or is set to id of node if `name` is not present. * Node `represents` is value of `represents` attribute on the node or set is to node `name` if ``None`` or not present **Edges:** * Interaction is value of `interaction` attribute on the edge or is set to ``neighbor-of`` if ``None`` or not present .. note:: Data types are inferred by using :py:func:`isinstance` and converted to corresponding CX data types. For list items, only the 1st item is examined to determine type :param G: Graph to convert :type G: :class:`networkx.Graph` :raises Exception: if **G** parameter is ``None`` or there is another error in conversion :return: Converted network :rtype: :py:class:`~ndex2.nice_cx_network.NiceCXNetwork` """ cx_builder = NiceCXBuilder() if G is None: raise Exception('Networkx input is empty') network_name = G.graph.get('name') if network_name is not None: cx_builder.set_name(network_name) else: cx_builder.set_name('created from networkx by ' 'ndex2.create_nice_cx_networkx()') for n, d in G.nodes(data=True): if isinstance(n, int): n_name = d.get('name') if n_name is None: n_name = str(n) node_id = cx_builder.add_node(name=n_name, represents=d.get('represents'), id=n, map_node_ids=True) else: node_id = cx_builder.add_node(name=n, represents=d.get('represents'), map_node_ids=True) # ====================== # ADD NODE ATTRIBUTES # ====================== for k, v in d.items(): # if node attribute is 'name' skip it cause that will be used # for name of node, also skip 'represents' # fix for https://github.com/ndexbio/ndex2-client/issues/84 if k == 'name' or k == 'represents': continue use_this_value, attr_type = cx_builder._infer_data_type( v, split_string=False) # This might go away, waiting on response to # https://ndexbio.atlassian.net/browse/UD-2181 if k == 'citation' and not isinstance(use_this_value, list): use_this_value = [str(use_this_value)] attr_type = constants.LIST_OF_STRING if use_this_value is not None: cx_builder.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): cx_builder.add_edge(source=u, target=v, interaction=interaction, id=index) else: cx_builder.add_edge(source=cx_builder.node_id_lookup.get(u), target=cx_builder.node_id_lookup.get(v), interaction=interaction, id=index) # ============================== # ADD EDGE ATTRIBUTES # ============================== for k, val in d.items(): if k == 'interaction': continue use_this_value, attr_type = cx_builder._infer_data_type( val, split_string=False) # This might go away, waiting on response to # https://ndexbio.atlassian.net/browse/UD-2181 if k == 'citation' and not isinstance(use_this_value, list): use_this_value = [str(use_this_value)] attr_type = constants.LIST_OF_STRING if use_this_value is not None: cx_builder.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) cx_builder.add_opaque_aspect(constants.CARTESIAN_LAYOUT_ASPECT, aspect) return cx_builder.get_nice_cx()