importosimportjsonimportpickleimportloggingimportnumpyasnpfrompathlibimportPathfromopenpnm.ioimport_parse_filenamefromopenpnm.networkimportNetworklogger=logging.getLogger(__name__)def_validate_json(json_file):importjsonschema# Validate name of schema filerelative_path='../../utils/jgf_schema.pkl'schema_file=Path(os.path.realpath(__file__),relative_path)schema_file=_parse_filename(filename=schema_file,ext='pkl')# Load schema from pickle filewithopen(schema_file,'rb')asfile:jgf_schema=pickle.load(file)# Validate JSON agains schematry:jsonschema.validate(json_file,jgf_schema)returnTrueexceptjsonschema.exceptions.ValidationError:returnFalse
[docs]defnetwork_to_jsongraph(network,filename=''):r""" Write the network to disk as a JGF file. Parameters ---------- network : Network filename : str Desired file name, defaults to network name if not given """# Ensure output file is validfilename=_parse_filename(filename=filename,ext='json')# Ensure network contains the required propertiestry:required_props={'pore.diameter','pore.coords','throat.length','throat.conns','throat.diameter'}assertrequired_props.issubset(network.props())exceptAssertionError:raiseException('Error - network is missing one of: '+str(required_props))# Create 'metadata' JSON objectgraph_metadata_obj={'number_of_nodes':network.Np,'number_of_links':network.Nt}# Create 'nodes' JSON objectnodes_obj=[{'id':str(ps),'metadata':{'node_squared_radius':int(network['pore.diameter'][ps]/2)**2,'node_coordinates':{'x':int(network['pore.coords'][ps,0]),'y':int(network['pore.coords'][ps,1]),'z':int(network['pore.coords'][ps,2])}}}forpsinnetwork.Ps]# Create 'edges' JSON objectedges_obj=[{'id':str(ts),'source':str(network['throat.conns'][ts,0]),'target':str(network['throat.conns'][ts,1]),'metadata':{'link_length':float(network['throat.length'][ts]),'link_squared_radius':float(network['throat.diameter'][ts]/2)**2}}fortsinnetwork.Ts]# Build 'graph' JSON object from 'metadata', 'nodes' and 'edges'graph_obj={'metadata':graph_metadata_obj,'nodes':nodes_obj,'edges':edges_obj}# Build full JSON objectjson_obj={'graph':graph_obj}# Load and validate input JSONwithopen(filename,'w')asfile:json.dump(json_obj,file,indent=2)
[docs]defnetwork_from_jsongraph(filename):r""" Loads the JGF file onto the given project. Parameters ---------- filename : str The name of the file containing the data to import. The formatting of this file is outlined below. Returns ------- network : dict An OpenPNM Network dictionary """# Ensure input file is validfilename=_parse_filename(filename=filename,ext='json')# Load and validate input JSONwithopen(filename,'r')asfile:json_file=json.load(file)ifnot_validate_json(json_file):raiseException('File is not in the JSON Graph Format')# Extract graph metadata from JSONnumber_of_nodes=json_file['graph']['metadata']['number_of_nodes']number_of_links=json_file['graph']['metadata']['number_of_links']# Extract node properties from JSONnodes=sorted(json_file['graph']['nodes'],key=lambdanode:int(node['id']))x=np.array([node['metadata']['node_coordinates']['x']fornodeinnodes])y=np.array([node['metadata']['node_coordinates']['y']fornodeinnodes])z=np.array([node['metadata']['node_coordinates']['z']fornodeinnodes])# Extract link properties from JSONedges=sorted(json_file['graph']['edges'],key=lambdaedge:int(edge['id']))source=np.array([int(edge['source'])foredgeinedges])target=np.array([int(edge['target'])foredgeinedges])link_length=np.array([edge['metadata']['link_length']foredgeinedges])link_squared_radius=np.array([edge['metadata']['link_squared_radius']foredgeinedges])# Generate network objectnetwork=Network()network['pore.all']=np.ones([number_of_nodes,],dtype=bool)network['throat.all']=np.ones([number_of_links,],dtype=bool)# Define primitive throat propertiesnetwork['throat.length']=link_lengthnetwork['throat.conns']=np.column_stack([source,target])network['throat.diameter']=2.0*np.sqrt(link_squared_radius)# Define primitive pore propertiesnetwork['pore.index']=np.arange(number_of_nodes)network['pore.coords']=np.column_stack([x,y,z])network['pore.diameter']=np.zeros(number_of_nodes)returnnetwork