Example #1
0
def draw(data,
         size=(400, 225),
         node_size=2.0,
         edge_size=0.25,
         default_node_color="0xaaaaaa",
         default_edge_color="0x777777",
         z=20):
    """Draws an interactive 3D visualization of the inputted graph.

    Args:
        data: Either an adjacency list of tuples (ie. [(1,2),...]) or json
        size: (Optional) Dimensions of visualization, in pixels
        node_size: (Optional) Defaults to 2.0
        edge_size: (Optional) Defaults to 0.25
        default_node_color: (Optional) If loading data without specified
            "color" properties, this will be used. Default is "0xaaaaaa"
        default_edge_color: (Optional) If loading data without specified
            "color" properties, this will be used. Default is "0x222222"
        z: (Optional) Starting z position of the camera. Default is 20

    Inputting an adjacency list into `data` results in a "default" graph type.
    For more customization, generate a json file using other methods before
    running the drawer.
    """

    # Guess the input format and handle accordingly
    if isinstance(data, list):
        graph = json_formatter.dumps(generate(data))
    elif isinstance(data, dict):
        graph = json_formatter.dumps(data)
    else:
        # Support both files and strings
        try:
            with open(data) as in_file:
                graph = in_file.read()
        except:
            graph = data

    # This calls igraph and uses some IPython magic to get everything linked
    script = ("var $d = $('<div/>').attr('id', 'graph_' + utils.uuid());"
              "$d.width(%d); $d.height(%d);"
              "igraph.create($d, {nodeSize: %f, edgeSize: %f,"
              "               defaultNodeColor: '%s',"
              "               defaultEdgeColor: '%s'});"
              "igraph.draw(%s);"
              "container.show();"
              "element.append($d);" %
              (size[0], size[1], node_size, edge_size, default_node_color,
               default_edge_color, graph))

    # Execute js and display the results in a div (see script for more)
    display(Javascript(data=lib_script + script))
Example #2
0
def to_json(data, compress=False):
    """Converts the output of `generate(...)` to formatted json.

    Floats are rounded to three decimals and positional vectors are printed on
    one line with some whitespace buffer.
    """
    return json.compress(data) if compress else json.dumps(data)
Example #3
0
def run(structure, input_type="cif", output_type="cif", l=1.2, h_i0=-2.0,
        charge_precision=3, method="ewald", m_r=2, m_k=2, eta=50.0,
        ionization_data_path=DEFAULT_IONIZATION_PATH,
        charge_data_path=DEFAULT_CHARGE_PATH):
    """Runs EQeq on the inputted structure, returning charge data.

    Args:
        structure: Either a filename or data encoding a chemical.
        input_type: (Optional) Specifies input type. Can be anything supported
            by openbabel, as well as "json"
        output_type: (Optional) Specifies the output type. Currently, options
            are "cif", "mol", "pdb", "car", "json", "list", and "files". The
            first four return modified chemical data formats, "list" returns
            a Python object, "json" is that object serialized, and "files"
            saves files of all possible output types.
        l: (Optional) Lambda, the dielectric screening parameter.
        h_i0: (Optional) The electron affinity of hydrogen.
        charge_precision: (Optional) Number of decimals to use for charges.
        method: (Optional) Method to use. Can be "direct" (default),
            "nonperiodic", or "ewald".
        m_r: (Optional) Number of unit cells to consider in "real space". This
            is measured radially, so m_r = 1 evaluates 27 unit cells.
        m_k: (Optional) Number of unit cells to consider in "frequency space".
            This is measured radially, so m_k = 1 evaluates 27 unit cells.
        eta: (Optional) Ewald splitting parameter
        ionization_data_path: (Optional) A path to the file containing ion-
            ization data. By default, assumes the data is in the EQeq folder
            and saved as "ionizationdata.dat".
        charge_data_path: (Optional) A path to the file containing charge-
            center data. By default, assumes the data is in the EQeq folder
            and saved as "chargecenters.dat".
    Returns:
        A string representing the charged crystal. Returns nothing if the
        output type is set to "files"
    """
    # Error handling on string params. Should spare users some annoyance.
    o, m = output_type.lower(), method.lower()
    if o not in ["cif", "pdb", "car", "mol", "json", "list", "files"]:
        raise NotImplementedError("Output format '%s' is not supported!" % o)
    if m not in ["direct", "nonperiodic", "ewald"]:
        raise NotImplementedError("Method '%s' is not supported!" % m)
    # If linked to openbabel, use it to handle json interconversion externally
    if input_type != "cif":
        structure = format_converter.convert(structure, input_type, "cif")
    structure = structure.replace("\t", "  ")
    # Calls libeqeq.so's run method, returning a string of data
    result = eqeq.run(structure, ("json" if output_type == "list" else
                      output_type), l, h_i0, charge_precision, method, m_r,
                      m_k, eta, ionization_data_path, charge_data_path)
    if output_type == "list":
        return json.loads(result)
    # This option appends atoms in json/object data with a "charge" attribute
    if output_type == "json":
        obj = format_converter.convert(structure, "cif", "object")
        result = json.loads(result)
        for atom, charge in zip(obj["atoms"], result):
            atom["charge"] = charge
        result = json.dumps(obj)
    return result
Example #4
0
def draw(data, size=(400, 225), node_size=2.0, edge_size=0.25,
         default_node_color="0xaaaaaa", default_edge_color="0x777777", z=20):
    """Draws an interactive 3D visualization of the inputted graph.

    Args:
        data: Either an adjacency list of tuples (ie. [(1,2),...]) or json
        size: (Optional) Dimensions of visualization, in pixels
        node_size: (Optional) Defaults to 2.0
        edge_size: (Optional) Defaults to 0.25
        default_node_color: (Optional) If loading data without specified
            "color" properties, this will be used. Default is "0xaaaaaa"
        default_edge_color: (Optional) If loading data without specified
            "color" properties, this will be used. Default is "0x222222"
        z: (Optional) Starting z position of the camera. Default is 20

    Inputting an adjacency list into `data` results in a "default" graph type.
    For more customization, generate a json file using other methods before
    running the drawer.
    """

    # Guess the input format and handle accordingly
    if isinstance(data, list):
        graph = json_formatter.dumps(generate(data))
    elif isinstance(data, dict):
        graph = json_formatter.dumps(data)
    else:
        # Support both files and strings
        try:
            with open(data) as in_file:
                graph = in_file.read()
        except:
            graph = data

    # This calls igraph and uses some IPython magic to get everything linked
    script = ("var $d = $('<div/>').attr('id', 'graph_' + utils.uuid());"
              "$d.width(%d); $d.height(%d);"
              "igraph.create($d, {nodeSize: %f, edgeSize: %f,"
              "               defaultNodeColor: '%s',"
              "               defaultEdgeColor: '%s'});"
              "igraph.draw(%s);"
              "container.show();"
              "element.append($d);" % (size[0], size[1], node_size, edge_size,
              default_node_color, default_edge_color, graph))

    # Execute js and display the results in a div (see script for more)
    display(Javascript(data=lib_script + script))
Example #5
0
def to_json(data):
    """Converts the output of `generate(...)` to formatted json.

    Args:
        data: The data structure outputted by `generate()`

    Floats are rounded to three decimals and positional vectors are printed on
    one line with some whitespace buffer.
    """
    return json_formatter.dumps(data)
Example #6
0
def to_json(data):
    """Converts the output of `generate(...)` to formatted json.

    Args:
        data: The data structure outputted by `generate()`

    Floats are rounded to three decimals and positional vectors are printed on
    one line with some whitespace buffer.
    """
    return json_formatter.dumps(data)
Example #7
0
def convert(data, in_format, out_format, pretty=False):
    """Converts between two inputted chemical formats.

    Args:
        data: A string representing the chemical file to be converted. If the
            `in_format` is "json", this can also be a Python object
        in_format: The format of the `data` string. Can be "json" or any format
            recognized by Open Babel
        out_format: The format to convert to. Can be "json" or any format
            recognized by Open Babel
        pretty: (Optional) If True and `out_format` is "json", will pretty-
            print the output for human readability
    Returns:
        A string representing the inputted `data` in the specified `out_format`
    """

    # Decide on a json formatter depending on desired prettiness
    dumps = json.dumps if pretty else json.compress

    # If it's a json string, load it
    if in_format == "json" and isinstance(data, basestring):
        data = json.loads(data)

    # A little "hack" to format inputted json
    if in_format == "json" and out_format == "json":
        return json.dumps(data)

    # These are converted manually to retain crystallographic information
    if in_format == "json" and out_format == "cif":
        return json_to_cif(data)

    # These use the open babel library to interconvert, with additions for json
    mol = (json_to_pybel(data) if in_format == "json" else
           pybel.readstring(in_format.encode("ascii"),
                            "".join(i for i in data if ord(i) < 128)
                            .encode("ascii")))

    # Infer structure in cases where the input format has no specification
    if not mol.OBMol.HasNonZeroCoords():
        mol.make3D()
    mol.OBMol.Center()

    # EQeq takes a specific cif format that openbabel does not output.
    # This manually overrides that.
    if out_format == "cif":
        return json_to_cif(pybel_to_json(mol))

    if out_format == "object":
        return pybel_to_json(mol)
    elif out_format == "json":
        return dumps(pybel_to_json(mol))
    else:
        return mol.write(out_format)
Example #8
0
def convert(data, in_format, out_format, pretty=False):
    """Converts between two inputted chemical formats.

    Args:
        data: A string representing the chemical file to be converted. If the
            `in_format` is "json", this can also be a Python object
        in_format: The format of the `data` string. Can be "json" or any format
            recognized by Open Babel
        out_format: The format to convert to. Can be "json" or any format
            recognized by Open Babel
        pretty: (Optional) If True and `out_format` is "json", will pretty-
            print the output for human readability
    Returns:
        A string representing the inputted `data` in the specified `out_format`
    """

    # Decide on a json formatter depending on desired prettiness
    dumps = json.dumps if pretty else json.compress

    # If it's a json string, load it
    if in_format == "json" and isinstance(data, basestring):
        data = json.loads(data)

    # A little "hack" to format inputted json
    if in_format == "json" and out_format == "json":
        return json.dumps(data)

    # These are converted manually to retain crystallographic information
    if in_format == "json" and out_format == "cif":
        return json_to_cif(data)

    # These use the open babel library to interconvert, with additions for json
    mol = (json_to_pybel(data) if in_format == "json" else pybel.readstring(
        in_format.encode("ascii"), "".join(i for i in data
                                           if ord(i) < 128).encode("ascii")))

    # Infer structure in cases where the input format has no specification
    if not mol.OBMol.HasNonZeroCoords():
        mol.make3D()
    mol.OBMol.Center()

    # EQeq takes a specific cif format that openbabel does not output.
    # This manually overrides that.
    if out_format == "cif":
        return json_to_cif(pybel_to_json(mol))

    if out_format == "object":
        return pybel_to_json(mol)
    elif out_format == "json":
        return dumps(pybel_to_json(mol))
    else:
        return mol.write(out_format)
Example #9
0
def convert(data, in_format, out_format, filename=None, pretty=False):
    """Converts between two inputted chemical formats.

    Args:
        data: A string representing the chemical file to be converted. If the
            `in_format` is "json", this can also be a Python object
        in_format: The format of the `data` string. Can be "json" or any format
            recognized by Open Babel
        out_format: The format to convert to. Can be "json" or any format
            recognized by Open Babel
        filename: (Optional) The name of the file containing `data`. This is
            used primarily to encode data saved in the file naming scheme of
            the old building-block format
        pretty: (Optional) If True and `out_format` is "json", will pretty-
            print the output for human readability
    Returns:
        A string representing the inputted `data` in the specified `out_format`
    """

    # Decide on a json formatter depending on desired prettiness
    dumps = json.dumps if pretty else json.compress

    # If it's a json string, load it
    if in_format == "json" and isinstance(data, basestring):
        data = json.loads(data)

    # A little "hack" to format inputted json
    if in_format == "json" and out_format == "json":
        return json.dumps(data)

    # These use the open babel library to interconvert, with additions for json
    mol = (json_to_pybel(data) if in_format == "json" else
           pybel.readstring(in_format.encode("ascii"),
                            "".join(i for i in data if ord(i) < 128)
                            .encode("ascii")))

    # Infer structure in cases where the input format has no specification
    if not mol.OBMol.HasNonZeroCoords():
        mol.make3D()
    mol.OBMol.Center()

    return (dumps(pybel_to_json(mol, name=filename)) if out_format == "json"
            else mol.write(out_format.encode("ascii")))
Example #10
0
File: eqeq.py Project: solccp/EQeq
def run(structure,
        input_type="cif",
        output_type="cif",
        l=1.2,
        h_i0=-2.0,
        charge_precision=3,
        method="ewald",
        m_r=2,
        m_k=2,
        eta=50.0,
        ionization_data_path=DEFAULT_IONIZATION_PATH,
        charge_data_path=DEFAULT_CHARGE_PATH):
    """Runs EQeq on the inputted structure, returning charge data.

    Args:
        structure: Either a filename or data encoding a chemical.
        input_type: (Optional) Specifies input type. Can be anything supported
            by openbabel, as well as "json"
        output_type: (Optional) Specifies the output type. Currently, options
            are "cif", "mol", "pdb", "car", "json", "list", and "files". The
            first four return modified chemical data formats, "list" returns
            a Python object, "json" is that object serialized, and "files"
            saves files of all possible output types.
        l: (Optional) Lambda, the dielectric screening parameter.
        h_i0: (Optional) The electron affinity of hydrogen.
        charge_precision: (Optional) Number of decimals to use for charges.
        method: (Optional) Method to use. Can be "direct" (default),
            "nonperiodic", or "ewald".
        m_r: (Optional) Number of unit cells to consider in "real space". This
            is measured radially, so m_r = 1 evaluates 27 unit cells.
        m_k: (Optional) Number of unit cells to consider in "frequency space".
            This is measured radially, so m_k = 1 evaluates 27 unit cells.
        eta: (Optional) Ewald splitting parameter
        ionization_data_path: (Optional) A path to the file containing ion-
            ization data. By default, assumes the data is in the EQeq folder
            and saved as "ionizationdata.dat".
        charge_data_path: (Optional) A path to the file containing charge-
            center data. By default, assumes the data is in the EQeq folder
            and saved as "chargecenters.dat".
    Returns:
        A string representing the charged crystal. Returns nothing if the
        output type is set to "files"
    """
    # Error handling on string params. Should spare users some annoyance.
    o, m = output_type.lower(), method.lower()
    if o not in ["cif", "pdb", "car", "mol", "json", "list", "files"]:
        raise NotImplementedError("Output format '%s' is not supported!" % o)
    if m not in ["direct", "nonperiodic", "ewald"]:
        raise NotImplementedError("Method '%s' is not supported!" % m)
    # If linked to openbabel, use it to handle json interconversion externally
    if input_type != "cif":
        structure = format_converter.convert(structure, input_type, "cif")
    structure = structure.replace("\t", "  ")
    # Calls libeqeq.so's run method, returning a string of data
    result = eqeq.run(structure,
                      ("json" if output_type == "list" else output_type), l,
                      h_i0, charge_precision, method, m_r, m_k, eta,
                      ionization_data_path, charge_data_path)
    if output_type == "list":
        return json.loads(result)
    # This option appends atoms in json/object data with a "charge" attribute
    if output_type == "json":
        obj = format_converter.convert(structure, "cif", "object")
        result = json.loads(result)
        for atom, charge in zip(obj["atoms"], result):
            atom["charge"] = charge
        result = json.dumps(obj)
    return result
Example #11
0
            if ind > 0:
                metInfo[row[1]] = {}
                metInfo[row[1]]['name'] = row[0]
                metInfo[row[1]]['KEGGID'] = row[2]
                metInfo[row[1]]['fullname'] = row[3]
                metInfo[row[1]]['centralcarbon'] = int(row[9])
                metInfo[row[1]]['aminoacid'] = int(row[8])
                metInfo[row[1]]['nucleotide'] = int(row[7])
                metInfo[row[1]]['cofactor'] = int(row[6])
                metInfo[row[1]]['fattyacid'] = int(row[5])
                metInfo[row[1]]['other'] = int(row[4])

    with open(sys.argv[-1]) as in_file:
        network = json.load(in_file)

    for key in network['nodes'].keys():
        if metInfo[key]['centralcarbon']:
            network['nodes'][key]['color'] = 'red'
        elif metInfo[key]['aminoacid']:
            network['nodes'][key]['color'] = 'green'
        elif metInfo[key]['nucleotide']:
            network['nodes'][key]['color'] = 'blue'
        elif metInfo[key]['cofactor']:
            network['nodes'][key]['color'] = 'yellow'
        elif metInfo[key]['fattyacid']:
            network['nodes'][key]['color'] = 'purple'
        elif metInfo[key]['other']:
            network['nodes'][key]['color'] = 'gray'

    print(json_formatter.dumps(network))
    # creates the initial arrangement for the nodes based on the starting node
    master_nodes = layer(edges,
                         available_nodes,
                         start_node=starting_node,
                         depth=0)

    # get the range of depth and counts for each layer
    depth_count = {}
    for node in master_nodes.keys():
        if master_nodes[node]["depth"] in depth_count.keys():
            depth_count[master_nodes[node]["depth"]] = depth_count[
                master_nodes[node]["depth"]] + 1
        else:
            depth_count[master_nodes[node]["depth"]] = 1

    # space out particular layers based on how many nodes are in a particular
    # layer
    for layer_of_interest, count in depth_count.items():
        if count > threshold_for_spacing:
            nodes_of_interest = []
            for node in master_nodes.keys():
                if master_nodes[node]["depth"] == layer_of_interest:
                    nodes_of_interest.append(node)

            master_nodes = space(master_nodes,
                                 nodes_of_interest,
                                 force_iter=10)

    # Convert to json and print
    print(json_formatter.dumps({"edges": edges, "nodes": master_nodes}))
Example #13
0

if __name__ == '__main__':
    import sys
    import json
    import json_formatter

    # See if input is a file
    try:
        with open(sys.argv[-1]) as in_file:
            edges = json.load(in_file)
    except IOError:
        edges = json.loads(sys.argv[-1])

    # Convert to internal representation
    edges = [{'source': str(s), 'target': str(t)} for s, t in edges]

    # Handle additional args
    kwargs = {'force_strength': 5.0, 'is_3d': True}
    for i, arg in enumerate(sys.argv):
        if arg == '--force-strength':
            kwargs['force_strength'] = float(sys.argv[i + 1])
        elif arg == '--2D':
            kwargs['is_3d'] = False

    # Generate nodes
    nodes = run(edges, **kwargs)

    # Convert to json and print
    print(json_formatter.dumps({'edges': edges, 'nodes': nodes}))
    available_nodes = set(e["source"]
                          for e in edges) | set(e["target"] for e in edges)

    # creates the initial arrangement for the nodes based on the starting node
    master_nodes = layer(edges, available_nodes,
                         start_node=starting_node, depth=0)

    # get the range of depth and counts for each layer
    depth_count = {}
    for node in master_nodes.keys():
        if master_nodes[node]["depth"] in depth_count.keys():
            depth_count[master_nodes[node]["depth"]] = depth_count[
                master_nodes[node]["depth"]] + 1
        else:
            depth_count[master_nodes[node]["depth"]] = 1

    # space out particular layers based on how many nodes are in a particular
    # layer
    for layer_of_interest, count in depth_count.items():
        if count > threshold_for_spacing:
            nodes_of_interest = []
            for node in master_nodes.keys():
                if master_nodes[node]["depth"] == layer_of_interest:
                    nodes_of_interest.append(node)

            master_nodes = space(
                master_nodes, nodes_of_interest, force_iter=10)

    # Convert to json and print
    print(json_formatter.dumps({"edges": edges, "nodes": master_nodes}))
Example #15
0
            if ind > 0:
                metInfo[row[1]] = {}
                metInfo[row[1]]['name'] = row[0]
                metInfo[row[1]]['KEGGID'] = row[2]
                metInfo[row[1]]['fullname'] = row[3]
                metInfo[row[1]]['centralcarbon'] = int(row[9])
                metInfo[row[1]]['aminoacid'] = int(row[8])
                metInfo[row[1]]['nucleotide'] = int(row[7])
                metInfo[row[1]]['cofactor'] = int(row[6])
                metInfo[row[1]]['fattyacid'] = int(row[5])
                metInfo[row[1]]['other'] = int(row[4])

    with open(sys.argv[-1]) as in_file:
        network = json.load(in_file)

    for key in network['nodes'].keys():
        if metInfo[key]['centralcarbon']:
            network['nodes'][key]['color'] = 'red'
        elif metInfo[key]['aminoacid']:
            network['nodes'][key]['color'] = 'green'
        elif metInfo[key]['nucleotide']:
            network['nodes'][key]['color'] = 'blue'
        elif metInfo[key]['cofactor']:
            network['nodes'][key]['color'] = 'yellow'
        elif metInfo[key]['fattyacid']:
            network['nodes'][key]['color'] = 'purple'
        elif metInfo[key]['other']:
            network['nodes'][key]['color'] = 'gray'

    print(json_formatter.dumps(network))
Example #16
0
        edges = json.loads(sys.argv[-1])

    # Convert to internal representation
    edges = [{"source": str(s), "target": str(t)} for s, t in edges]

    # Handle additional args
    kwargs = {
        "edge_length": 20,
        "separation": 5,
        "density": 0,
        "is_concentric": False,
        "is_3d": True
    }
    for i, arg in enumerate(sys.argv):
        if arg == "--edge-length":
            kwargs["edge_length"] = float(sys.argv[i + 1])
        elif arg == "--separation":
            kwargs["separation"] = float(sys.argv[i + 1])
        elif arg == "--density":
            kwargs["density"] = float(sys.argv[i + 1])
        elif arg == "--concentric":
            kwargs["is_concentric"] = True
        elif arg == "--2D":
            kwargs["is_3d"] = False

    # Generate nodes
    nodes = run(edges, **kwargs)

    # Convert to json and print
    print json_formatter.dumps({"edges": edges, "nodes": nodes})
Example #17
0
    # See if input is a file
    try:
        with open(sys.argv[-1]) as in_file:
            edges = json.load(in_file)
    except IOError:
        edges = json.loads(sys.argv[-1])

    # Convert to internal representation
    edges = [{"source": str(s), "target": str(t)} for s, t in edges]

    # Handle additional args
    kwargs = {"edge_length": 20, "separation": 5, "density": 0,
              "is_concentric": False, "is_3d": True}
    for i, arg in enumerate(sys.argv):
        if arg == "--edge-length":
            kwargs["edge_length"] = float(sys.argv[i + 1])
        elif arg == "--separation":
            kwargs["separation"] = float(sys.argv[i + 1])
        elif arg == "--density":
            kwargs["density"] = float(sys.argv[i + 1])
        elif arg == "--concentric":
            kwargs["is_concentric"] = True
        elif arg == "--2D":
            kwargs["is_3d"] = False

    # Generate nodes
    nodes = run(edges, **kwargs)

    # Convert to json and print
    print json_formatter.dumps({"edges": edges, "nodes": nodes})