<commit_before># inspired by:
# saddles.py by @nvictus
# https://github.com/nandankita/labUtilityTools
from functools import partial
import os.path as op
import sys
import pandas as pd
import numpy as np
import cooler
import bioframe
from .. import api

import click
from .util import validate_csv

from ..lib.common import make_cooler_view, mask_cooler_bad_bins, align_track_with_cooler
from ..lib.io import read_viewframe_from_file, read_expected_from_file
from ..lib.checks import is_track

from . import util
from . import cli

@cli.command()
@click.argument(
    "cool_path", metavar="COOL_PATH", type=str
)  # click.Path(exists=True, dir_okay=False),)
@click.argument(
    "track_path",
    metavar="TRACK_PATH",
    type=str,
    callback=partial(validate_csv, default_column="E1"),
)
@click.argument(
    "expected_path",
    metavar="EXPECTED_PATH",
    type=str,
    callback=partial(validate_csv, default_column="balanced.avg"),
)
@click.option(
    "-t",
    "--contact-type",
    help="Type of the contacts to aggregate",
    type=click.Choice(["cis", "trans"]),
    default="cis",
    show_default=True,
)
@click.option(
    "--min-dist",
    help="Minimal distance between bins to consider, bp. If negative, removes"
    "the first two diagonals of the data. Ignored with --contact-type trans.",
    type=int,
    default=-1,
    show_default=True,
)
@click.option(
    "--max-dist",
    help="Maximal distance between bins to consider, bp. Ignored, if negative."
    " Ignored with --contact-type trans.",
    type=int,
    default=-1,
    show_default=True,
)
@click.option(
    "-n",
    "--n-bins",
    help="Number of bins for digitizing track values.",
    type=int,
    default=50,
    show_default=True,
)
@click.option(
    "--vrange",
    "vrange",
    help="Low and high values used for binning genome-wide track values, e.g. "
    "if `range`=(-0.05, 0.05), `n-bins` equidistant bins would be generated. "
    "Use to prevent extreme track values from exploding the bin range and "
    "to ensure consistent bins across several runs of `compute_saddle` command "
    "using different track files.",
    type=(float, float),
    default=(None, None),
    nargs=2,
)
@click.option(
    "--qrange",
    help="Low and high values used for quantile bins of genome-wide track values,"
    "e.g. if `qrange`=(0.02, 0.98) the lower bin would "
    "start at the 2nd percentile and the upper bin would end at the 98th "
    "percentile of the genome-wide signal. "
    "Use to prevent the extreme track values from exploding the bin range.",
    type=(float, float),
    default=(None, None),
    show_default=True,
)
@click.option(
    "--clr-weight-name",
    help="Use balancing weight with this name.",
    type=str,
    default="weight",
    show_default=True,
)
@click.option(
    "--strength/--no-strength",
    help="Compute and save compartment 'saddle strength' profile",
    is_flag=True,
    default=False,
)
@click.option(
    "--view",
    "--regions",
    help="Path to a BED file containing genomic regions "
    "for which saddleplot will be calculated. Region names can "
    "be provided in a 4th column and should match regions and "
    "their names in expected."
    " Note that '--regions' is the deprecated name of the option. Use '--view' instead. ",
    type=click.Path(exists=True),
    required=False,
)
@click.option(
    "-o",
    "--out-prefix",
    help="Dump 'saddledata', 'binedges' and 'hist' arrays in a numpy-specific "
    ".npz container. Use numpy.load to load these arrays into a "
    "dict-like object. The digitized signal values are saved to a "
    "bedGraph-style TSV.",
    required=True,
)
@click.option(
    "--fig",
    type=click.Choice(["png", "jpg", "svg", "pdf", "ps", "eps"]),
    multiple=True,
    help="Generate a figure and save to a file of the specified format. "
    "If not specified - no image is generated. Repeat for multiple "
    "output formats.",
)
@click.option(
    "--scale",
    help="Value scale for the heatmap",
    type=click.Choice(["linear", "log"]),
    default="log",
    show_default=True,
)
@click.option(
    "--cmap", help="Name of matplotlib colormap", default="coolwarm", show_default=True
)
@click.option(
    "--vmin",
    help="Low value of the saddleplot colorbar. "
    "Note: value in original units irrespective of used scale, "
    "and therefore should be positive for both vmin and vmax.",
    type=float,
    default=0.5,
)
@click.option(
    "--vmax", help="High value of the saddleplot colorbar", type=float, default=2
)
@click.option("--hist-color", help="Face color of histogram bar chart")
@click.option(
    "-v", "--verbose", help="Enable verbose output", is_flag=True, default=False
)
def saddle(
    cool_path,
    track_path,
    expected_path,
    contact_type,
    min_dist,
    max_dist,
    n_bins,
    vrange,
    qrange,
    clr_weight_name,
    strength,
    view,
    out_prefix,
    fig,
    scale,
    cmap,
    vmin,
    vmax,
    hist_color,
    verbose,
):
    """
    Calculate saddle statistics and generate saddle plots for an arbitrary
    signal track on the genomic bins of a contact matrix.

    COOL_PATH : The paths to a .cool file with a balanced Hi-C map. Use the
    '::' syntax to specify a group path in a multicooler file.

    TRACK_PATH : The path to bedGraph-like file with a binned compartment track
    (eigenvector), including a header. Use the '::' syntax to specify a column
    name.

    EXPECTED_PATH : The paths to a tsv-like file with expected signal,
    including a header. Use the '::' syntax to specify a column name.

    Analysis will be performed for chromosomes referred to in TRACK_PATH, and
    therefore these chromosomes must be a subset of chromosomes referred to in
    COOL_PATH and EXPECTED_PATH.

    COOL_PATH, TRACK_PATH and EXPECTED_PATH must be binned at the same
    resolution (expect for  EXPECTED_PATH in case of trans contact type).

    EXPECTED_PATH must contain at least the following columns for cis contacts:
    'chrom', 'diag', 'n_valid', value_name and the following columns for trans
    contacts: 'chrom1', 'chrom2', 'n_valid', value_name value_name is controlled
    using options. Header must be present in a file.

    """
    #### Read inputs: ####
    clr = cooler.Cooler(cool_path)

    expected_path, expected_value_col = expected_path
    track_path, track_name = track_path

    #### Read track: ####
    # read bedGraph-file :
    track_columns = ["chrom", "start", "end", track_name]
    # specify dtype as a rudimentary form of validation:
    track_dtype = {
        "chrom": np.str_,
        "start": np.int64,
        "end": np.int64,
        track_name: np.float64,
    }
    track = pd.read_table(
        track_path,
        usecols=track_columns,
        dtype=track_dtype,
        comment=None,
        verbose=verbose,
    )

    #### Generate viewframes ####
    # 1:cooler_view_df. Generate viewframe from clr.chromsizes:
    cooler_view_df = make_cooler_view(clr)

    # 2:view_df. Define global view for calculating calling dots
    # use input "view" BED file or all chromosomes :
    if view is None:
        view_df = cooler_view_df
    else:
        view_df = read_viewframe_from_file(view, clr, check_sorting=True)

    # 3:track_view_df. Generate viewframe from track table:
    track_view_df = bioframe.make_viewframe(
        [
            (group.chrom.iloc[0], np.nanmin(group.start), np.nanmax(group.end))
            for i, group in track.reset_index().groupby("chrom")
        ]
    )

    #### Read expected: ####

    expected_summary_cols = [
        expected_value_col,
    ]

    expected = read_expected_from_file(
        expected_path,
        contact_type=contact_type,
        expected_value_cols=expected_summary_cols,
        verify_view=view_df,
        verify_cooler=clr,
    )

    if min_dist < 0:
        min_diag = 3
    else:
        min_diag = int(np.ceil(min_dist / clr.binsize))

    if max_dist >= 0:
        max_diag = int(np.floor(max_dist / clr.binsize))
    else:
        max_diag = -1

    if clr_weight_name:
        track = mask_cooler_bad_bins(
            (track, track_name), (clr.bins()[:], clr_weight_name)
        )

    if vrange[0] is None:
        vrange = None
    if qrange[0] is None:
        qrange = None
    if (qrange is not None) and (vrange is not None):
        raise ValueError("only one of vrange or qrange can be supplied")

    # digitize outside of saddle so that we have binedges to save below
    track = align_track_with_cooler(
        track,
        clr,
        view_df=view_df,
        clr_weight_name=clr_weight_name,
        mask_clr_bad_bins=True,
    )
    digitized_track, binedges = api.saddle.digitize(
        track.iloc[:, :4],
        n_bins,
        vrange=vrange,
        qrange=qrange,
        digitized_suffix=".d",
    )

    S, C = api.saddle.saddle(
        clr,
        expected,
        digitized_track,
        contact_type,
        None,
        vrange=None,
        qrange=None,
        view_df=view_df,
        clr_weight_name=clr_weight_name,
        expected_value_col=expected_value_col,
        view_name_col="name",
        min_diag=min_diag,
        max_diag=max_diag,
        verbose=verbose,
    )
    saddledata = S / C

    to_save = dict(
        saddledata=saddledata,
        binedges=binedges,
        digitized=digitized_track,
        saddlecounts=C,
    )

    if strength:
        ratios = api.saddle.saddle_strength(S, C)
        ratios = ratios[1:-1]  # drop outlier bins
        to_save["saddle_strength"] = ratios

    # Save data
    np.savez(out_prefix + ".saddledump", **to_save)  # .npz auto-added
    digitized_track.to_csv(out_prefix + ".digitized.tsv", sep="\t", index=False)

    # Generate figure
    if len(fig):
        try:
            import matplotlib as mpl

            mpl.use("Agg")  # savefig only for now:
            import matplotlib.pyplot as plt
        except ImportError:
            print("Install matplotlib to use ", file=sys.stderr)
            sys.exit(1)

        if hist_color is None:
            color = (
                0.41568627450980394,
                0.8,
                0.39215686274509803,
            )  # sns.color_palette('muted')[2]
        else:
            color = mpl.colors.colorConverter.to_rgb(hist_color)
        title = op.basename(cool_path) + " ({})".format(contact_type)

        if qrange is not None:
            track_label = track_name + " quantiles"
        else:
            track_label = track_name

        clabel = "(contact frequency / expected)"

        api.saddle.saddleplot(
            track,
            saddledata,
            n_bins,
            vrange=vrange,
            qrange=qrange,
            scale=scale,
            vmin=vmin,
            vmax=vmax,
            color=color,
            title=title,
            xlabel=track_label,
            ylabel=track_label,
            clabel=clabel,
            cmap=cmap,
        )

        for ext in fig:
            plt.savefig(out_prefix + "." + ext, bbox_inches="tight")
<commit_msg>Update saddle.py (#387)<commit_after># inspired by:
# saddles.py by @nvictus
# https://github.com/nandankita/labUtilityTools
from functools import partial
import os.path as op
import sys
import pandas as pd
import numpy as np
import cooler
import bioframe
from .. import api

import click
from .util import validate_csv

from ..lib.common import make_cooler_view, mask_cooler_bad_bins, align_track_with_cooler
from ..lib.io import read_viewframe_from_file, read_expected_from_file
from ..lib.checks import is_track

from . import util
from . import cli

@cli.command()
@click.argument(
    "cool_path", metavar="COOL_PATH", type=str
)  # click.Path(exists=True, dir_okay=False),)
@click.argument(
    "track_path",
    metavar="TRACK_PATH",
    type=str,
    callback=partial(validate_csv, default_column="E1"),
)
@click.argument(
    "expected_path",
    metavar="EXPECTED_PATH",
    type=str,
    callback=partial(validate_csv, default_column="balanced.avg"),
)
@click.option(
    "-t",
    "--contact-type",
    help="Type of the contacts to aggregate",
    type=click.Choice(["cis", "trans"]),
    default="cis",
    show_default=True,
)
@click.option(
    "--min-dist",
    help="Minimal distance between bins to consider, bp. If negative, removes"
    "the first two diagonals of the data. Ignored with --contact-type trans.",
    type=int,
    default=-1,
    show_default=True,
)
@click.option(
    "--max-dist",
    help="Maximal distance between bins to consider, bp. Ignored, if negative."
    " Ignored with --contact-type trans.",
    type=int,
    default=-1,
    show_default=True,
)
@click.option(
    "-n",
    "--n-bins",
    help="Number of bins for digitizing track values.",
    type=int,
    default=50,
    show_default=True,
)
@click.option(
    "--vrange",
    "vrange",
    help="Low and high values used for binning genome-wide track values, e.g. "
    "if `range`=(-0.05, 0.05), `n-bins` equidistant bins would be generated. "
    "Use to prevent extreme track values from exploding the bin range and "
    "to ensure consistent bins across several runs of `compute_saddle` command "
    "using different track files.",
    type=(float, float),
    default=(None, None),
    nargs=2,
)
@click.option(
    "--qrange",
    help="Low and high values used for quantile bins of genome-wide track values,"
    "e.g. if `qrange`=(0.02, 0.98) the lower bin would "
    "start at the 2nd percentile and the upper bin would end at the 98th "
    "percentile of the genome-wide signal. "
    "Use to prevent the extreme track values from exploding the bin range.",
    type=(float, float),
    default=(None, None),
    show_default=True,
)
@click.option(
    "--clr-weight-name",
    help="Use balancing weight with this name.",
    type=str,
    default="weight",
    show_default=True,
)
@click.option(
    "--strength/--no-strength",
    help="Compute and save compartment 'saddle strength' profile",
    is_flag=True,
    default=False,
)
@click.option(
    "--view",
    "--regions",
    help="Path to a BED file containing genomic regions "
    "for which saddleplot will be calculated. Region names can "
    "be provided in a 4th column and should match regions and "
    "their names in expected."
    " Note that '--regions' is the deprecated name of the option. Use '--view' instead. ",
    type=click.Path(exists=True),
    required=False,
)
@click.option(
    "-o",
    "--out-prefix",
    help="Dump 'saddledata', 'binedges' and 'hist' arrays in a numpy-specific "
    ".npz container. Use numpy.load to load these arrays into a "
    "dict-like object. The digitized signal values are saved to a "
    "bedGraph-style TSV.",
    required=True,
)
@click.option(
    "--fig",
    type=click.Choice(["png", "jpg", "svg", "pdf", "ps", "eps"]),
    multiple=True,
    help="Generate a figure and save to a file of the specified format. "
    "If not specified - no image is generated. Repeat for multiple "
    "output formats.",
)
@click.option(
    "--scale",
    help="Value scale for the heatmap",
    type=click.Choice(["linear", "log"]),
    default="log",
    show_default=True,
)
@click.option(
    "--cmap", help="Name of matplotlib colormap", default="coolwarm", show_default=True
)
@click.option(
    "--vmin",
    help="Low value of the saddleplot colorbar. "
    "Note: value in original units irrespective of used scale, "
    "and therefore should be positive for both vmin and vmax.",
    type=float,
    default=0.5,
)
@click.option(
    "--vmax", help="High value of the saddleplot colorbar", type=float, default=2
)
@click.option("--hist-color", help="Face color of histogram bar chart")
@click.option(
    "-v", "--verbose", help="Enable verbose output", is_flag=True, default=False
)
def saddle(
    cool_path,
    track_path,
    expected_path,
    contact_type,
    min_dist,
    max_dist,
    n_bins,
    vrange,
    qrange,
    clr_weight_name,
    strength,
    view,
    out_prefix,
    fig,
    scale,
    cmap,
    vmin,
    vmax,
    hist_color,
    verbose,
):
    """
    Calculate saddle statistics and generate saddle plots for an arbitrary
    signal track on the genomic bins of a contact matrix.

    COOL_PATH : The paths to a .cool file with a balanced Hi-C map. Use the
    '::' syntax to specify a group path in a multicooler file.

    TRACK_PATH : The path to bedGraph-like file with a binned compartment track
    (eigenvector), including a header. Use the '::' syntax to specify a column
    name.

    EXPECTED_PATH : The paths to a tsv-like file with expected signal,
    including a header. Use the '::' syntax to specify a column name.

    Analysis will be performed for chromosomes referred to in TRACK_PATH, and
    therefore these chromosomes must be a subset of chromosomes referred to in
    COOL_PATH and EXPECTED_PATH.

    COOL_PATH, TRACK_PATH and EXPECTED_PATH must be binned at the same
    resolution (expect for  EXPECTED_PATH in case of trans contact type).

    EXPECTED_PATH must contain at least the following columns for cis contacts:
    'chrom', 'diag', 'n_valid', value_name and the following columns for trans
    contacts: 'chrom1', 'chrom2', 'n_valid', value_name value_name is controlled
    using options. Header must be present in a file.

    """
    #### Read inputs: ####
    clr = cooler.Cooler(cool_path)

    expected_path, expected_value_col = expected_path
    track_path, track_name = track_path

    #### Read track: ####
    # read bedGraph-file :
    track_columns = ["chrom", "start", "end", track_name]
    # specify dtype as a rudimentary form of validation:
    track_dtype = {
        "chrom": np.str_,
        "start": np.int64,
        "end": np.int64,
        track_name: np.float64,
    }
    track = pd.read_table(
        track_path,
        usecols=track_columns,
        dtype=track_dtype,
        comment=None,
        verbose=verbose,
    )

    #### Generate viewframes ####
    # 1:cooler_view_df. Generate viewframe from clr.chromsizes:
    cooler_view_df = make_cooler_view(clr)

    # 2:view_df. Define global view for calculating calling dots
    # use input "view" BED file or all chromosomes :
    if view is None:
        view_df = cooler_view_df
    else:
        view_df = read_viewframe_from_file(view, clr, check_sorting=True)

    # 3:track_view_df. Generate viewframe from track table:
    track_view_df = bioframe.make_viewframe(
        [
            (group.chrom.iloc[0], np.nanmin(group.start), np.nanmax(group.end))
            for i, group in track.reset_index().groupby("chrom")
        ]
    )

    #### Read expected: ####

    expected_summary_cols = [
        expected_value_col,
    ]

    expected = read_expected_from_file(
        expected_path,
        contact_type=contact_type,
        expected_value_cols=expected_summary_cols,
        verify_view=view_df,
        verify_cooler=clr,
    )

    if min_dist < 0:
        min_diag = 3
    else:
        min_diag = int(np.ceil(min_dist / clr.binsize))

    if max_dist >= 0:
        max_diag = int(np.floor(max_dist / clr.binsize))
    else:
        max_diag = -1

    if clr_weight_name:
        track = mask_cooler_bad_bins(
            (track, track_name), (clr.bins()[:], clr_weight_name)
        )

    if vrange[0] is None:
        vrange = None
    if qrange[0] is None:
        qrange = None
    if (qrange is not None) and (vrange is not None):
        raise ValueError("only one of vrange or qrange can be supplied")

    # digitize outside of saddle so that we have binedges to save below
    track = align_track_with_cooler(
        track,
        clr,
        view_df=view_df,
        clr_weight_name=clr_weight_name,
        mask_clr_bad_bins=True,
        drop_track_na=False,
    )
    digitized_track, binedges = api.saddle.digitize(
        track.iloc[:, :4],
        n_bins,
        vrange=vrange,
        qrange=qrange,
        digitized_suffix=".d",
    )

    S, C = api.saddle.saddle(
        clr,
        expected,
        digitized_track,
        contact_type,
        None,
        vrange=None,
        qrange=None,
        view_df=view_df,
        clr_weight_name=clr_weight_name,
        expected_value_col=expected_value_col,
        view_name_col="name",
        min_diag=min_diag,
        max_diag=max_diag,
        verbose=verbose,
    )
    saddledata = S / C

    to_save = dict(
        saddledata=saddledata,
        binedges=binedges,
        digitized=digitized_track,
        saddlecounts=C,
    )

    if strength:
        ratios = api.saddle.saddle_strength(S, C)
        ratios = ratios[1:-1]  # drop outlier bins
        to_save["saddle_strength"] = ratios

    # Save data
    np.savez(out_prefix + ".saddledump", **to_save)  # .npz auto-added
    digitized_track.to_csv(out_prefix + ".digitized.tsv", sep="\t", index=False)

    # Generate figure
    if len(fig):
        try:
            import matplotlib as mpl

            mpl.use("Agg")  # savefig only for now:
            import matplotlib.pyplot as plt
        except ImportError:
            print("Install matplotlib to use ", file=sys.stderr)
            sys.exit(1)

        if hist_color is None:
            color = (
                0.41568627450980394,
                0.8,
                0.39215686274509803,
            )  # sns.color_palette('muted')[2]
        else:
            color = mpl.colors.colorConverter.to_rgb(hist_color)
        title = op.basename(cool_path) + " ({})".format(contact_type)

        if qrange is not None:
            track_label = track_name + " quantiles"
        else:
            track_label = track_name

        clabel = "(contact frequency / expected)"

        api.saddle.saddleplot(
            track,
            saddledata,
            n_bins,
            vrange=vrange,
            qrange=qrange,
            scale=scale,
            vmin=vmin,
            vmax=vmax,
            color=color,
            title=title,
            xlabel=track_label,
            ylabel=track_label,
            clabel=clabel,
            cmap=cmap,
        )

        for ext in fig:
            plt.savefig(out_prefix + "." + ext, bbox_inches="tight")
<|endoftext|>


<commit_before>"""
This module provides functionality for calculating molecular masses.
"""

# Built-ins
from __future__ import division

from collections import Iterable

# Core data analysis libraries

def _exact_mass(atoms):
    """
    Parameters
    ----------
    atoms : dict of str, int or iterable
        Atoms in molecule and their count. If the dictionary's values are
        integers, use average isotope weights. If values are iterables, use
        exact count of each isotope, in order of increasing weight.

    Returns
    -------
    float
        Molecular weight of molecule.

    Examples
    --------
    >>> _exact_mass({"H": 1})        # One hydrogen (Average isotope)
    1.007940721855
    >>> _exact_mass({"H": [1]})      # One hydrogen (Exact isotope)
    1.007825
    >>> _exact_mass({"H": [1, 1]})   # One hydrogen, one deuterium
    3.021927
    >>> _exact_mass({"H": [0, 1]})   # One deuterium (Exact isotope)
    2.014102
    """
    # Atom name mapping to molecular weight and frequency of that isotope
    molecular_weights = {
        "H": [
            (1.007825, 99.9885),
            (2.014102,  0.0115),
        ],
        "C": [
            (12.000000, 98.93),
            (13.003355,  1.07)
        ],
        "N": [
            (14.003074, 99.632),
            (15.000109,  0.368),
        ],
        "O": [
            (15.994915, 99.757),
            (16.999131,  0.038),
            (17.999159,  0.205),
        ],
        "S": [
            (31.972072, 94.93),
            (32.971459,  0.76),
            (33.967868,  4.29),
            (35.967079,  0.02),
        ],
        "P": [
            (30.973763, 100),
        ],
    }
    return sum(
        sum(
            weight[0] * count
            for weight, count in zip(molecular_weights[atom], counts)
        )
        if isinstance(counts, Iterable) else
        sum(
            weight * counts * frequency / 100
            for weight, frequency in molecular_weights[atom]
        )
        for atom, counts in atoms.items()
    )

ARGININE = _exact_mass({"H": [12], "C": [6], "O": [1], "N": [4]})
ASPARAGINE = _exact_mass({"H": [6], "C": [4], "O": [2], "N": [2]})
ASPARTATE = _exact_mass({"H": [5], "C": [4], "O": [3], "N": [1]})
CYSTEINE = _exact_mass({"H": [5], "C": [3], "O": [1], "N": [1], "S": [1]})
GLUTAMATE = _exact_mass({"H": [7], "C": [5], "O": [3], "N": [1]})
GLUTAMINE = _exact_mass({"H": [8], "C": [5], "O": [2], "N": [2]})
GLYCINE = _exact_mass({"H": [3], "C": [2], "O": [1], "N": [1]})
HISTIDINE = _exact_mass({"H": [7], "C": [6], "O": [1], "N": [3]})
ISOLEUCINE = _exact_mass({"H": [11], "C": [6], "O": [1], "N": [1]})
LEUCINE = _exact_mass({"H": [11], "C": [6], "O": [1], "N": [1]})
LYSINE = _exact_mass({"H": [12], "C": [6], "O": [1], "N": [2]})
METHIONINE = _exact_mass({"H": [9], "C": [5], "O": [1], "N": [1], "S": [1]})
PHENYLALANINE = _exact_mass({"H": [9], "C": [9], "O": [1], "N": [1]})
PROLINE = _exact_mass({"H": [7], "C": [5], "O": [1], "N": [1]})
SERINE = _exact_mass({"H": [5], "C": [3], "O": [2], "N": [1]})
THREONINE = _exact_mass({"H": [7], "C": [4], "O": [2], "N": [1]})
TYROSINE = _exact_mass({"H": [9], "C": [9], "O": [2], "N": [1]})
TRYPTOPHAN = _exact_mass({"H": [10], "C": [11], "O": [1], "N": [2]})
VALINE = _exact_mass({"H": [9], "C": [5], "O": [1], "N": [1]})

R = 0
ACETYL_LYSINE = 0
OXY_METHIONINE = 0
DIOXY_METHIONINE = 0
CARBAMIDOMETHYL_CYSTEINE = 0
PHOSPHO_SERINE = 0
PHOSPHO_THREONINE = 0
PHOSPHO_TYROSINE = 0

AMINE = _exact_mass({"N": [1], "H": [3]})
WATER = _exact_mass({"H": [2], "O": [1]})
PHOSPHORIC_ACID = _exact_mass({"H": [3], "P": [1], "O": [4]})
PHOSPHITE = _exact_mass({"H": [1], "P": [1], "O": [3]})
CARBON_DIOXIDE = _exact_mass({"C": [1], "O": [2]})
SOCH4 = _exact_mass({"S": [1], "O": [1], "C": [1], "H": [4]})
SO2CH4 = _exact_mass({"S": [1], "O": [2], "C": [1], "H": [4]})
<commit_msg>Added more molecular masses<commit_after>"""
This module provides functionality for calculating molecular masses.
"""

# Built-ins
from __future__ import division

from collections import Iterable

# Core data analysis libraries

def _exact_mass(atoms):
    """
    Parameters
    ----------
    atoms : dict of str, int or iterable
        Atoms in molecule and their count. If the dictionary's values are
        integers, use average isotope weights. If values are iterables, use
        exact count of each isotope, in order of increasing weight.

    Returns
    -------
    float
        Molecular weight of molecule.

    Examples
    --------
    >>> _exact_mass({"H": 1})        # One hydrogen (Average isotope)
    1.007940721855
    >>> _exact_mass({"H": [1]})      # One hydrogen (Exact isotope)
    1.007825
    >>> _exact_mass({"H": [1, 1]})   # One hydrogen, one deuterium
    3.021927
    >>> _exact_mass({"H": [0, 1]})   # One deuterium (Exact isotope)
    2.014102
    """
    # Atom name mapping to molecular weight and frequency of that isotope
    molecular_weights = {
        "H": [
            (1.007825, 99.9885),
            (2.014102,  0.0115),
        ],
        "C": [
            (12.000000, 98.93),
            (13.003355,  1.07)
        ],
        "N": [
            (14.003074, 99.632),
            (15.000109,  0.368),
        ],
        "O": [
            (15.994915, 99.757),
            (16.999131,  0.038),
            (17.999159,  0.205),
        ],
        "S": [
            (31.972072, 94.93),
            (32.971459,  0.76),
            (33.967868,  4.29),
            (35.967079,  0.02),
        ],
        "P": [
            (30.973763, 100),
        ],
    }
    return sum(
        sum(
            weight[0] * count
            for weight, count in zip(molecular_weights[atom], counts)
        )
        if isinstance(counts, Iterable) else
        sum(
            weight * counts * frequency / 100
            for weight, frequency in molecular_weights[atom]
        )
        for atom, counts in atoms.items()
    )

ARGININE = _exact_mass({"H": [12], "C": [6], "O": [1], "N": [4]})
ASPARAGINE = _exact_mass({"H": [6], "C": [4], "O": [2], "N": [2]})
ASPARTATE = _exact_mass({"H": [5], "C": [4], "O": [3], "N": [1]})
CYSTEINE = _exact_mass({"H": [5], "C": [3], "O": [1], "N": [1], "S": [1]})
GLUTAMATE = _exact_mass({"H": [7], "C": [5], "O": [3], "N": [1]})
GLUTAMINE = _exact_mass({"H": [8], "C": [5], "O": [2], "N": [2]})
GLYCINE = _exact_mass({"H": [3], "C": [2], "O": [1], "N": [1]})
HISTIDINE = _exact_mass({"H": [7], "C": [6], "O": [1], "N": [3]})
ISOLEUCINE = _exact_mass({"H": [11], "C": [6], "O": [1], "N": [1]})
LEUCINE = _exact_mass({"H": [11], "C": [6], "O": [1], "N": [1]})
LYSINE = _exact_mass({"H": [12], "C": [6], "O": [1], "N": [2]})
METHIONINE = _exact_mass({"H": [9], "C": [5], "O": [1], "N": [1], "S": [1]})
PHENYLALANINE = _exact_mass({"H": [9], "C": [9], "O": [1], "N": [1]})
PROLINE = _exact_mass({"H": [7], "C": [5], "O": [1], "N": [1]})
SERINE = _exact_mass({"H": [5], "C": [3], "O": [2], "N": [1]})
THREONINE = _exact_mass({"H": [7], "C": [4], "O": [2], "N": [1]})
TYROSINE = _exact_mass({"H": [9], "C": [9], "O": [2], "N": [1]})
TRYPTOPHAN = _exact_mass({"H": [10], "C": [11], "O": [1], "N": [2]})
VALINE = _exact_mass({"H": [9], "C": [5], "O": [1], "N": [1]})

R = 0
ACETYL_LYSINE = \
    _exact_mass({"H": [14], "C": [8], "O": [2], "N": [2]})
OXY_METHIONINE = \
    _exact_mass({"H": [9], "C": [5], "O": [2], "N": [1], "S": [1]})
DIOXY_METHIONINE = \
    _exact_mass({"H": [9], "C": [5], "O": [3], "N": [1], "S": [1]})
CARBAMIDOMETHYL_CYSTEINE = \
    _exact_mass({"H": [8], "C": [5], "O": [2], "N": [2], "S": [1]})
PHOSPHO_SERINE = \
    _exact_mass({"H": [6], "C": [3], "O": [5], "N": [1], "P": [1]})
PHOSPHO_THREONINE = \
    _exact_mass({"H": [8], "C": [4], "O": [5], "N": [1], "P": [1]})
PHOSPHO_TYROSINE = \
    _exact_mass({"H": [10], "C": [9], "O": [5], "N": [1], "P": [1]})

AMINE = _exact_mass({"N": [1], "H": [3]})
WATER = _exact_mass({"H": [2], "O": [1]})
PHOSPHORIC_ACID = _exact_mass({"H": [3], "P": [1], "O": [4]})
PHOSPHITE = _exact_mass({"H": [1], "P": [1], "O": [3]})
CARBON_DIOXIDE = _exact_mass({"C": [1], "O": [2]})
SOCH4 = _exact_mass({"S": [1], "O": [1], "C": [1], "H": [4]})
SO2CH4 = _exact_mass({"S": [1], "O": [2], "C": [1], "H": [4]})
<|endoftext|>


<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-

import cv2
import numpy as np

def object_pos(lower_color, upper_color, stream):
	AllColorsInRange = cv2.inRange(stream, lower_color, upper_color)
	Blurred = cv2.GaussianBlur(AllColorsInRange, (121, 121), 0)
	Thresh = cv2.threshold(Blurred, 37, 255, cv2.THRESH_BINARY)[1]
	Object = cv2.dilate(Thresh, (121, 121), iterations=1)
	(_, cnts, _) = cv2.findContours(Object.copy(), cv2.RETR_EXTERNAL,
									cv2.CHAIN_APPROX_SIMPLE)
	if cnts == []:
		return (None, None, None)
	else:
		c = max(cnts, key=cv2.contourArea)
		marker = cv2.minAreaRect(c)
		box = np.int0(cv2.boxPoints(marker))
		M = cv2.moments(c)
		if int(M['m00']) == 0:
			return (None, None, None)
		else:
			cX = int(M['m10'] / M['m00'])
			cY = int(M['m01'] / M['m00'])
		return (cX, cY, cnts)
<commit_msg>Delete colorDetector.py<commit_after><|endoftext|>


<commit_before>from pycket.cont import continuation
from pycket.error import SchemeException
from pycket.values import from_list, w_false, w_true, W_Object, W_Fixnum, W_SimplePrim, W_Symbol, w_null, W_Procedure, w_void
from pycket.exposeprim import make_call_method
from rpython.rlib import jit

#
# Structs are partially supported
#
# Not implemented:
# 1) prefab -- '#s(sprout bean): need update in expand.rkt
# 2) methods overriding (including equal) -- generic-interfaces.rkt
# 3) properties and super as an argument -- kw.rkt

# TODO: inspector currently does nothing
class W_StructInspector(W_Object):
    errorname = "struct-inspector"
    _immutable_fields_ = ["_super"]

    @staticmethod
    def make(inspector, issibling = False):
        super = inspector
        if issibling:
            super = inspector.super() if inspector is not None else None
        return W_StructInspector(super)

    def __init__(self, super):
        self._super = super
    def super(self):
        return self._super

current_inspector = W_StructInspector(None)

class W_StructType(W_Object):
    all_structs = {}
    errorname = "struct-type"
    _immutable_fields_ = ["_id", "_super", "_init_field_cnt", "_auto_field_cnt", "_auto_v", "_inspector", \
                          "_immutables", "_guard", "_constr_name"]
    @staticmethod
    def make(name, super_type, init_field_cnt, auto_field_cnt, auto_v, props, inspector, proc_spec, immutables, guard, constr_name):
        struct_id = W_StructTypeDescriptor(name)
        W_StructType.all_structs[struct_id] = w_result = W_StructType(struct_id, super_type, init_field_cnt, auto_field_cnt, \
            auto_v, props, inspector, proc_spec, immutables, guard, constr_name)
        return w_result

    @staticmethod
    def lookup_struct_type(struct_id):
        if struct_id in W_StructType.all_structs:
            return W_StructType.all_structs[struct_id]
        else:
            return w_false

    def __init__(self, struct_id, super_type, init_field_cnt, auto_field_cnt, \
            auto_v, props, inspector, proc_spec, immutables, guard, constr_name):
        self._super = W_StructType.lookup_struct_type(super_type) if super_type != w_false else None
        self._init_field_cnt = init_field_cnt.value
        self._auto_field_cnt = auto_field_cnt.value
        # Next arguments are optional
        self._auto_v = auto_v
        # self._props = props
        self._inspector = inspector
        # self._proc_spec = proc_spec
        self._immutables = immutables
        self._guard = guard
        if isinstance(constr_name, W_Symbol):
            self._constr_name = constr_name.value
        else:
            constr_name = struct_id.id()
            assert isinstance(constr_name, W_Symbol)
            self._constr_name = "make-" + constr_name.value

        # structure types are opaque by default
        self._isopaque = True if self._inspector != w_false else False

        self._desc = struct_id
        self._constr = W_StructConstructor(self._desc, self._super, self._init_field_cnt, self._auto_field_cnt, \
                                            self._auto_v, self._isopaque, self._guard, self._constr_name)
        self._pred = W_StructPredicate(self._desc)
        self._acc = W_StructAccessor(self._desc)
        self._mut = W_StructMutator(self._desc)

    def struct_id(self):
        return self._desc
    def super(self):
        return self._super
    def init_field_cnt(self):
        return self._init_field_cnt
    def auto_field_cnt(self):
        return self._auto_field_cnt
    def immutables(self):
        return self._immutables
    def isopaque(self):
        return self._opaque
    def setmutable(self, field):
        pass
        # TODO: save the mutability of field
    def constr(self):
        return self._constr
    def pred(self):
        return self._pred
    def acc(self):
        return self._acc
    def mut(self):
        return self._mut
    def make_struct_tuple(self):
        return [self._desc, self._constr, self._pred, self._acc, self._mut]
    def tostring(self):
        return "StructType<%s>" % self._desc.tostring()

class W_StructTypeDescriptor(W_Object):
    errorname = "struct-type-descriptor"
    _immutable_fields_ = ["_id"]
    def __init__(self, id):
        self._id = id
    def id(self):
        return self._id
    def tostring(self):
        return "#<struct-type:%s>" % self._id

class W_StructConstructor(W_Procedure):
    _immutable_fields_ = ["_struct_id", "_super_type", "_init_field_cnt", "_auto_values", "_isopaque", "_guard", "_name"]
    def __init__ (self, struct_id, super_type, init_field_cnt, auto_field_cnt, auto_v, isopaque, guard, name):
        self._struct_id = struct_id
        self._super_type = super_type
        self._init_field_cnt = init_field_cnt
        self._auto_values = [auto_v] * auto_field_cnt
        self._isopaque = isopaque
        self._guard = guard
        self._name = name

    def extcode(self, field_values, env, cont):
        if self._guard != w_false:
            cont = guard_check(self._guard, field_values, env, cont)
        super = None
        if self._super_type is not None:
            def split_list(list, num):
                assert num >= 0
                return list[:num], list[num:]
            split_position = len(field_values) - self._init_field_cnt
            super_field_values, field_values = split_list(field_values, split_position)
            super, env, cont = self._super_type.constr().extcode(super_field_values, env, cont)
        result = W_Struct(self._struct_id, super, self._isopaque, field_values + self._auto_values)
        return result, env, cont

    def call(self, args, env, cont):
        from pycket.interpreter import return_value
        result, env, cont = self.extcode(args, env, cont)
        return return_value(result, env, cont)

    def tostring(self):
        return "#<procedure:%s>" % self._name

@continuation
def guard_check(proc, field_values, env, cont, _vals):
    vals = _vals._get_full_list()
    struct = vals[0]
    assert isinstance(struct, W_Struct)
    args = [struct._type] + field_values
    return proc.call(args, env, cont)

class W_StructProperty(W_Object):
    errorname = "struct-type-property"
    _immutable_fields_ = ["name", "guard", "supers", "can_imp"]
    def __init__(self, name, guard, supers=w_null, can_imp=False):
        self.name = name
        self.guard = guard
        self.supers = supers
        self.can_imp = can_imp
    def tostring(self):
        return "#<struct-type-property:%s>"%self.name

class W_RootStruct(W_Object):
    errorname = "root-struct"
    _immutable_fields_ = ["_type", "_super", "_isopaque"]

    def __init__(self, struct_id, super, isopaque):
        self._type = struct_id
        self._super = super
        self._isopaque = isopaque

    @continuation
    def ref(self, struct_id, field, env, cont, _vals):
        raise NotImplementedError("base class")

    @continuation
    def set(self, struct_id, field, val, env, cont, _vals):
        raise NotImplementedError("base class")

    def vals(self):
        raise NotImplementedError("base class")

class W_Struct(W_RootStruct):
    errorname = "struct"
    _immutable_fields_ = ["_type", "_super", "_isopaque", "_fields"]
    def __init__(self, struct_id, super, isopaque, fields):
        W_RootStruct.__init__(self, struct_id, super, isopaque)
        #self._type = struct_id
        #self._super = super
        #self._isopaque = isopaque
        self._fields = fields

    def vals(self):
        result = self._fields
        if self._super is not None:
            return self._super.vals() + result
        else:
            return result

    # Rather than reference functions, we store the continuations. This is
    # necessarray to get constant stack usage without adding extra preamble
    # continuations.
    @continuation
    def ref(self, struct_id, field, env, cont, _vals):
        from pycket.interpreter import return_value, jump
        if self._type == struct_id:
            return return_value(self._fields[field], env, cont)
        elif self._type.id() == struct_id.id():
            raise SchemeException("given value instantiates a different structure type with the same name")
        elif self._super is not None:
            return jump(env, self._super.ref(struct_id, field, env, cont))
        else:
            assert False

    @continuation
    def set(self, struct_id, field, val, env, cont, _vals):
        from pycket.interpreter import return_value, jump
        type = jit.promote(self._type)
        if type == struct_id:
            self._fields[field] = val
            return return_value(w_void, env, cont)
        return jump(env, self._super.set(struct_id, field, val, env, cont))

    def tostring(self):
        if self._isopaque:
            result =  "#<%s>" % self._type.id().value
        else:
            result = "(%s %s)" % (self._type.id().value, ' '.join([val.tostring() for val in self.vals()]))
        return result

class W_StructPropertyPredicate(W_SimplePrim):
    errorname = "struct-property-predicate"
    _immutable_fields_ = ["property"]
    def __init__(self, prop):
        self.property = prop
    def code(self, args):
        raise SchemeException("StructPropertyPredicate NYI")

class W_StructPropertyAccessor(W_SimplePrim):
    errorname = "struct-property-accessor"
    _immutable_fields_ = ["property"]
    def __init__(self, prop):
        self.property = prop
    def code(self, args):
        raise SchemeException("StructPropertyAccessor NYI")

class W_StructPredicate(W_Procedure):
    errorname = "struct-predicate"
    _immutable_fields_ = ["_struct_id"]
    def __init__ (self, struct_id):
        self._struct_id = struct_id

    @make_call_method([W_Struct])
    def call(self, struct):
        result = w_false
        if (isinstance(struct, W_Struct)):
            while True:
                if struct._type == self._struct_id:
                    result = w_true
                    break
                if struct._super is None: break
                else: struct = struct._super
        return result
    def tostring(self):
        return "#<procedure:%s?>" % self._struct_id.id()

class W_StructFieldAccessor(W_Procedure):
    errorname = "struct-field-accessor"
    _immutable_fields_ = ["_accessor", "_field"]
    def __init__ (self, accessor, field):
        assert isinstance(accessor, W_StructAccessor)
        self._accessor = accessor
        self._field = field

    @make_call_method([W_Struct], simple=False)
    def call(self, struct, env, cont):
        return self._accessor.access(struct, self._field, env, cont)

class W_StructAccessor(W_Procedure):
    errorname = "struct-accessor"
    _immutable_fields_ = ["_struct_id"]
    def __init__ (self, struct_id):
        self._struct_id = struct_id

    def access(self, struct, field, env, cont):
        from pycket.interpreter import jump
        return jump(env, struct.ref(self._struct_id, field.value, env, cont))

    call = make_call_method([W_Struct, W_Fixnum], simple=False)(access)

    def tostring(self):
        return "#<procedure:%s-ref>" % self._struct_id.id()

class W_StructFieldMutator(W_Procedure):
    errorname = "struct-field-mutator"
    _immutable_fields_ = ["_mutator", "_field"]
    def __init__ (self, mutator, field):
        assert isinstance(mutator, W_StructMutator)
        self._mutator = mutator
        self._field = field
        mutator.setmutable(field)

    @make_call_method([W_Struct, W_Object], simple=False)
    def call(self, struct, val, env, cont):
        return self._mutator.mutate(struct, self._field, val, env, cont)

class W_StructMutator(W_Procedure):
    errorname = "struct-mutator"
    _immutable_fields_ = ["_struct_id"]
    def __init__ (self, struct_id):
        self._struct_id = struct_id

    def mutate(self, struct, field, val, env, cont):
        from pycket.interpreter import jump
        return jump(env, struct.set(self._struct_id, field.value, val, env, cont))

    call = make_call_method([W_Struct, W_Fixnum, W_Object], simple=False)(mutate)

    def setmutable(self, field):
        struct = W_StructType.lookup_struct_type(self._struct_id)
        struct.setmutable(field)
    def tostring(self):
        return "#<procedure:%s-set!>" % self._struct_id.id()

<commit_msg>Simplify struct type lookup<commit_after>from pycket.cont import continuation
from pycket.error import SchemeException
from pycket.values import from_list, w_false, w_true, W_Object, W_Fixnum, W_SimplePrim, W_Symbol, w_null, W_Procedure, w_void
from pycket.exposeprim import make_call_method
from rpython.rlib import jit

#
# Structs are partially supported
#
# Not implemented:
# 1) prefab -- '#s(sprout bean): need update in expand.rkt
# 2) methods overriding (including equal) -- generic-interfaces.rkt
# 3) properties and super as an argument -- kw.rkt

# TODO: inspector currently does nothing
class W_StructInspector(W_Object):
    errorname = "struct-inspector"
    _immutable_fields_ = ["_super"]

    @staticmethod
    def make(inspector, issibling = False):
        super = inspector
        if issibling:
            super = inspector.super() if inspector is not None else None
        return W_StructInspector(super)

    def __init__(self, super):
        self._super = super
    def super(self):
        return self._super

current_inspector = W_StructInspector(None)

class W_StructType(W_Object):
    all_structs = {}
    errorname = "struct-type"
    _immutable_fields_ = ["_id", "_super", "_init_field_cnt", "_auto_field_cnt", "_auto_v", "_inspector", \
                          "_immutables", "_guard", "_constr_name"]
    @staticmethod
    def make(name, super_type, init_field_cnt, auto_field_cnt, auto_v, props, inspector, proc_spec, immutables, guard, constr_name):
        struct_id = W_StructTypeDescriptor(name)
        W_StructType.all_structs[struct_id] = w_result = W_StructType(struct_id, super_type, init_field_cnt, auto_field_cnt, \
            auto_v, props, inspector, proc_spec, immutables, guard, constr_name)
        return w_result

    @staticmethod
    def lookup_struct_type(struct_id):
        return W_StructType.all_structs.get(struct_id, w_false)

    def __init__(self, struct_id, super_type, init_field_cnt, auto_field_cnt, \
            auto_v, props, inspector, proc_spec, immutables, guard, constr_name):
        self._super = W_StructType.lookup_struct_type(super_type) if super_type != w_false else None
        self._init_field_cnt = init_field_cnt.value
        self._auto_field_cnt = auto_field_cnt.value
        # Next arguments are optional
        self._auto_v = auto_v
        # self._props = props
        self._inspector = inspector
        # self._proc_spec = proc_spec
        self._immutables = immutables
        self._guard = guard
        if isinstance(constr_name, W_Symbol):
            self._constr_name = constr_name.value
        else:
            constr_name = struct_id.id()
            assert isinstance(constr_name, W_Symbol)
            self._constr_name = "make-" + constr_name.value

        # structure types are opaque by default
        self._isopaque = True if self._inspector != w_false else False

        self._desc = struct_id
        self._constr = W_StructConstructor(self._desc, self._super, self._init_field_cnt, self._auto_field_cnt, \
                                            self._auto_v, self._isopaque, self._guard, self._constr_name)
        self._pred = W_StructPredicate(self._desc)
        self._acc = W_StructAccessor(self._desc)
        self._mut = W_StructMutator(self._desc)

    def struct_id(self):
        return self._desc
    def super(self):
        return self._super
    def init_field_cnt(self):
        return self._init_field_cnt
    def auto_field_cnt(self):
        return self._auto_field_cnt
    def immutables(self):
        return self._immutables
    def isopaque(self):
        return self._opaque
    def setmutable(self, field):
        pass
        # TODO: save the mutability of field
    def constr(self):
        return self._constr
    def pred(self):
        return self._pred
    def acc(self):
        return self._acc
    def mut(self):
        return self._mut
    def make_struct_tuple(self):
        return [self._desc, self._constr, self._pred, self._acc, self._mut]
    def tostring(self):
        return "StructType<%s>" % self._desc.tostring()

class W_StructTypeDescriptor(W_Object):
    errorname = "struct-type-descriptor"
    _immutable_fields_ = ["_id"]
    def __init__(self, id):
        self._id = id
    def id(self):
        return self._id
    def tostring(self):
        return "#<struct-type:%s>" % self._id

class W_StructConstructor(W_Procedure):
    _immutable_fields_ = ["_struct_id", "_super_type", "_init_field_cnt", "_auto_values", "_isopaque", "_guard", "_name"]
    def __init__ (self, struct_id, super_type, init_field_cnt, auto_field_cnt, auto_v, isopaque, guard, name):
        self._struct_id = struct_id
        self._super_type = super_type
        self._init_field_cnt = init_field_cnt
        self._auto_values = [auto_v] * auto_field_cnt
        self._isopaque = isopaque
        self._guard = guard
        self._name = name

    def extcode(self, field_values, env, cont):
        if self._guard != w_false:
            cont = guard_check(self._guard, field_values, env, cont)
        super = None
        if self._super_type is not None:
            def split_list(list, num):
                assert num >= 0
                return list[:num], list[num:]
            split_position = len(field_values) - self._init_field_cnt
            super_field_values, field_values = split_list(field_values, split_position)
            super, env, cont = self._super_type.constr().extcode(super_field_values, env, cont)
        result = W_Struct(self._struct_id, super, self._isopaque, field_values + self._auto_values)
        return result, env, cont

    def call(self, args, env, cont):
        from pycket.interpreter import return_value
        result, env, cont = self.extcode(args, env, cont)
        return return_value(result, env, cont)

    def tostring(self):
        return "#<procedure:%s>" % self._name

@continuation
def guard_check(proc, field_values, env, cont, _vals):
    vals = _vals._get_full_list()
    struct = vals[0]
    assert isinstance(struct, W_Struct)
    args = [struct._type] + field_values
    return proc.call(args, env, cont)

class W_StructProperty(W_Object):
    errorname = "struct-type-property"
    _immutable_fields_ = ["name", "guard", "supers", "can_imp"]
    def __init__(self, name, guard, supers=w_null, can_imp=False):
        self.name = name
        self.guard = guard
        self.supers = supers
        self.can_imp = can_imp
    def tostring(self):
        return "#<struct-type-property:%s>"%self.name

class W_RootStruct(W_Object):
    errorname = "root-struct"
    _immutable_fields_ = ["_type", "_super", "_isopaque"]

    def __init__(self, struct_id, super, isopaque):
        self._type = struct_id
        self._super = super
        self._isopaque = isopaque

    @continuation
    def ref(self, struct_id, field, env, cont, _vals):
        raise NotImplementedError("base class")

    @continuation
    def set(self, struct_id, field, val, env, cont, _vals):
        raise NotImplementedError("base class")

    def vals(self):
        raise NotImplementedError("base class")

class W_Struct(W_RootStruct):
    errorname = "struct"
    _immutable_fields_ = ["_type", "_super", "_isopaque", "_fields"]
    def __init__(self, struct_id, super, isopaque, fields):
        W_RootStruct.__init__(self, struct_id, super, isopaque)
        #self._type = struct_id
        #self._super = super
        #self._isopaque = isopaque
        self._fields = fields

    def vals(self):
        result = self._fields
        if self._super is not None:
            return self._super.vals() + result
        else:
            return result

    # Rather than reference functions, we store the continuations. This is
    # necessarray to get constant stack usage without adding extra preamble
    # continuations.
    @continuation
    def ref(self, struct_id, field, env, cont, _vals):
        from pycket.interpreter import return_value, jump
        if self._type == struct_id:
            return return_value(self._fields[field], env, cont)
        elif self._type.id() == struct_id.id():
            raise SchemeException("given value instantiates a different structure type with the same name")
        elif self._super is not None:
            return jump(env, self._super.ref(struct_id, field, env, cont))
        else:
            assert False

    @continuation
    def set(self, struct_id, field, val, env, cont, _vals):
        from pycket.interpreter import return_value, jump
        type = jit.promote(self._type)
        if type == struct_id:
            self._fields[field] = val
            return return_value(w_void, env, cont)
        return jump(env, self._super.set(struct_id, field, val, env, cont))

    def tostring(self):
        if self._isopaque:
            result =  "#<%s>" % self._type.id().value
        else:
            result = "(%s %s)" % (self._type.id().value, ' '.join([val.tostring() for val in self.vals()]))
        return result

class W_StructPropertyPredicate(W_SimplePrim):
    errorname = "struct-property-predicate"
    _immutable_fields_ = ["property"]
    def __init__(self, prop):
        self.property = prop
    def code(self, args):
        raise SchemeException("StructPropertyPredicate NYI")

class W_StructPropertyAccessor(W_SimplePrim):
    errorname = "struct-property-accessor"
    _immutable_fields_ = ["property"]
    def __init__(self, prop):
        self.property = prop
    def code(self, args):
        raise SchemeException("StructPropertyAccessor NYI")

class W_StructPredicate(W_Procedure):
    errorname = "struct-predicate"
    _immutable_fields_ = ["_struct_id"]
    def __init__ (self, struct_id):
        self._struct_id = struct_id

    @make_call_method([W_Struct])
    def call(self, struct):
        result = w_false
        if (isinstance(struct, W_Struct)):
            while True:
                if struct._type == self._struct_id:
                    result = w_true
                    break
                if struct._super is None: break
                else: struct = struct._super
        return result
    def tostring(self):
        return "#<procedure:%s?>" % self._struct_id.id()

class W_StructFieldAccessor(W_Procedure):
    errorname = "struct-field-accessor"
    _immutable_fields_ = ["_accessor", "_field"]
    def __init__ (self, accessor, field):
        assert isinstance(accessor, W_StructAccessor)
        self._accessor = accessor
        self._field = field

    @make_call_method([W_Struct], simple=False)
    def call(self, struct, env, cont):
        return self._accessor.access(struct, self._field, env, cont)

class W_StructAccessor(W_Procedure):
    errorname = "struct-accessor"
    _immutable_fields_ = ["_struct_id"]
    def __init__ (self, struct_id):
        self._struct_id = struct_id

    def access(self, struct, field, env, cont):
        from pycket.interpreter import jump
        return jump(env, struct.ref(self._struct_id, field.value, env, cont))

    call = make_call_method([W_Struct, W_Fixnum], simple=False)(access)

    def tostring(self):
        return "#<procedure:%s-ref>" % self._struct_id.id()

class W_StructFieldMutator(W_Procedure):
    errorname = "struct-field-mutator"
    _immutable_fields_ = ["_mutator", "_field"]
    def __init__ (self, mutator, field):
        assert isinstance(mutator, W_StructMutator)
        self._mutator = mutator
        self._field = field
        mutator.setmutable(field)

    @make_call_method([W_Struct, W_Object], simple=False)
    def call(self, struct, val, env, cont):
        return self._mutator.mutate(struct, self._field, val, env, cont)

class W_StructMutator(W_Procedure):
    errorname = "struct-mutator"
    _immutable_fields_ = ["_struct_id"]
    def __init__ (self, struct_id):
        self._struct_id = struct_id

    def mutate(self, struct, field, val, env, cont):
        from pycket.interpreter import jump
        return jump(env, struct.set(self._struct_id, field.value, val, env, cont))

    call = make_call_method([W_Struct, W_Fixnum, W_Object], simple=False)(mutate)

    def setmutable(self, field):
        struct = W_StructType.lookup_struct_type(self._struct_id)
        struct.setmutable(field)
    def tostring(self):
        return "#<procedure:%s-set!>" % self._struct_id.id()

<|endoftext|>


<commit_before>"""distutils.command.clean

Implements the Distutils 'clean' command."""

# contributed by Bastian Kleineidam <calvin@cs.uni-sb.de>, added 2000-03-18

__revision__ = "$Id$"

import os
from distutils.core import Command
from distutils.util import remove_tree

class clean (Command):

    description = "clean up output of 'build' command"
    user_options = [
        ('build-base=', 'b',
         "base build directory (default: 'build.build-base')"),
        ('build-lib=', None,
         "build directory for all modules (default: 'build.build-lib')"),
        ('build-temp=', 't',
         "temporary build directory (default: 'build.build-temp')"),
        ('build-bdist=', None,
         "temporary directory for built distributions"),
        ('all', 'a',
         "remove all build output, not just temporary by-products")
    ]

    def initialize_options(self):
        self.build_base = None
        self.build_lib = None
        self.build_temp = None
        self.build_bdist = None
        self.all = None

    def finalize_options(self):
        if self.build_lib and not os.path.exists (self.build_lib):
            self.warn ("'%s' does not exist -- can't clean it" %
                       self.build_lib)
        if self.build_temp and not os.path.exists (self.build_temp):
            self.warn ("'%s' does not exist -- can't clean it" %
                       self.build_temp)

        self.set_undefined_options('build',
                                   ('build_base', 'build_base'),
                                   ('build_lib', 'build_lib'),
                                   ('build_temp', 'build_temp'),
                                   ('build_bdist', 'build_bdist'))

    def run(self):
        # remove the build/temp.<plat> directory (unless it's already
        # gone)
        if os.path.exists (self.build_temp):
            remove_tree (self.build_temp, self.verbose, self.dry_run)

        if self.all:
            # remove the module build directory (unless already gone)
            if os.path.exists (self.build_lib):
                remove_tree (self.build_lib, self.verbose, self.dry_run)
            # remove the temporary directory used for creating built
            # distributions (default "build/bdist") -- eg. type of
            # built distribution will have its own subdirectory under
            # "build/bdist", but they'll be taken care of by
            # 'remove_tree()'.
            if os.path.exists (self.build_bdist):
                remove_tree (self.build_bdist, self.verbose, self.dry_run)

        # just for the heck of it, try to remove the base build directory:
        # we might have emptied it right now, but if not we don't care
        if not self.dry_run:
            try:
                os.rmdir (self.build_base)
                self.announce ("removing '%s'" % self.build_base)
            except OSError:
                pass
<commit_msg>Rename 'build_bdist' to 'bdist_base', and get it by default from the "bdist" command rather than "build".<commit_after>"""distutils.command.clean

Implements the Distutils 'clean' command."""

# contributed by Bastian Kleineidam <calvin@cs.uni-sb.de>, added 2000-03-18

__revision__ = "$Id$"

import os
from distutils.core import Command
from distutils.util import remove_tree

class clean (Command):

    description = "clean up output of 'build' command"
    user_options = [
        ('build-base=', 'b',
         "base build directory (default: 'build.build-base')"),
        ('build-lib=', None,
         "build directory for all modules (default: 'build.build-lib')"),
        ('build-temp=', 't',
         "temporary build directory (default: 'build.build-temp')"),
        ('bdist-base=', None,
         "temporary directory for built distributions"),
        ('all', 'a',
         "remove all build output, not just temporary by-products")
    ]

    def initialize_options(self):
        self.build_base = None
        self.build_lib = None
        self.build_temp = None
        self.bdist_base = None
        self.all = None

    def finalize_options(self):
        if self.build_lib and not os.path.exists (self.build_lib):
            self.warn ("'%s' does not exist -- can't clean it" %
                       self.build_lib)
        if self.build_temp and not os.path.exists (self.build_temp):
            self.warn ("'%s' does not exist -- can't clean it" %
                       self.build_temp)

        self.set_undefined_options('build',
                                   ('build_base', 'build_base'),
                                   ('build_lib', 'build_lib'),
                                   ('build_temp', 'build_temp'))
        self.set_undefined_options('bdist',
                                   ('bdist_base', 'bdist_base'))

    def run(self):
        # remove the build/temp.<plat> directory (unless it's already
        # gone)
        if os.path.exists (self.build_temp):
            remove_tree (self.build_temp, self.verbose, self.dry_run)

        if self.all:
            # remove the module build directory (unless already gone)
            if os.path.exists (self.build_lib):
                remove_tree (self.build_lib, self.verbose, self.dry_run)
            # remove the temporary directory used for creating built
            # distributions (default "build/bdist") -- eg. type of
            # built distribution will have its own subdirectory under
            # "build/bdist", but they'll be taken care of by
            # 'remove_tree()'.
            if os.path.exists (self.bdist_base):
                remove_tree (self.bdist_base, self.verbose, self.dry_run)

        # just for the heck of it, try to remove the base build directory:
        # we might have emptied it right now, but if not we don't care
        if not self.dry_run:
            try:
                os.rmdir (self.build_base)
                self.announce ("removing '%s'" % self.build_base)
            except OSError:
                pass
<|endoftext|>


<commit_before># Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import spectral
import pycoal
import numpy

class MiningClassification:

    def __init__(self, classNames=None):
        """
        Construct a new MiningClassification object given a list of spectral
        class names corresponding to mines or other features.

        Args:
            classes (str[]): list of class names to identify.
        """

        self.classNames = classNames

    def classifyImage(self, imageFilename, classifiedFilename):

        """
        Classify mines or other features in a Pycoal classified image by copying
        relevant pixels and discarding the rest in a new file.

        Args:
            imageFilename (str):      filename of the image to be classified
            classifiedFilename (str): filename of the classified image

        Returns:
            None
        """

        # open the image
        image = spectral.open_image(imageFilename)
        data = image.asarray()
        M = image.shape[0]
        N = image.shape[1]

        # allocate a zero-initialized MxN array for the classified image
        classified = numpy.zeros(shape=(M,N), dtype=numpy.uint16)

        # get class numbers from names
        classList = image.metadata.get('class names')
        classNums = [classList.index(className) if className in classList else -1 for className in self.classNames]

        # for each pixel in the image
        for y in range(N):

            for x in range(M):

                pixel = data[x,y]

                if pixel[0] in classNums:

                    classified[x,y] = 1 + classNums.index(pixel[0])

        # save the classified image to a file
        spectral.io.envi.save_classification(classifiedFilename,
                                             classified,
                                             class_names=['No data']+self.classNames,
                                             metadata={
                                                 'data ignore value': 0,
                                                 'description': 'PyCOAL '+pycoal.version+' mining classified image.',
                                                 'map info': image.metadata.get('map info')
                                             })
<commit_msg>specify default mine classifications<commit_after># Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import spectral
import pycoal
import numpy

class MiningClassification:

    def __init__(self, classNames=[u'Schwertmannite BZ93-1 s06av95a=b',
                                   u'Renyolds_TnlSldgWet SM93-15w s06av95a=a',
                                   u'Renyolds_Tnl_Sludge SM93-15 s06av95a=a']):
        """
        Construct a new MiningClassification object given a list of spectral
        class names corresponding to mines or other features.

        Args:
            classes (str[]): list of class names to identify.
        """

        self.classNames = classNames

    def classifyImage(self, imageFilename, classifiedFilename):

        """
        Classify mines or other features in a Pycoal classified image by copying
        relevant pixels and discarding the rest in a new file.

        Args:
            imageFilename (str):      filename of the image to be classified
            classifiedFilename (str): filename of the classified image

        Returns:
            None
        """

        # open the image
        image = spectral.open_image(imageFilename)
        data = image.asarray()
        M = image.shape[0]
        N = image.shape[1]

        # allocate a zero-initialized MxN array for the classified image
        classified = numpy.zeros(shape=(M,N), dtype=numpy.uint16)

        # get class numbers from names
        classList = image.metadata.get('class names')
        classNums = [classList.index(className) if className in classList else -1 for className in self.classNames]

        # for each pixel in the image
        for y in range(N):

            for x in range(M):

                pixel = data[x,y]

                if pixel[0] in classNums:

                    classified[x,y] = 1 + classNums.index(pixel[0])

        # save the classified image to a file
        spectral.io.envi.save_classification(classifiedFilename,
                                             classified,
                                             class_names=['No data']+self.classNames,
                                             metadata={
                                                 'data ignore value': 0,
                                                 'description': 'PyCOAL '+pycoal.version+' mining classified image.',
                                                 'map info': image.metadata.get('map info')
                                             })
<|endoftext|>


<commit_before>import sys
import os
import subprocess

import shell
import file_explorer

from header import *
from text import Text
from log import Log

def _help(*args):

    print "\r"

    print "--- Main shell commands ---"
    print "!info: display version information."
    print "!log: display contents of log file."
    print "!help: display this help screen."
    print "!quit: quit the shell."
    print "!update: update txtsh to the latest version."
    print "!load DATA_TYPE, DATA: load DATA into database. \
DATA_TYPE must be 'string' or 'file'."
    print "!free ID: unload text object stored in ID."
    print "!use ID: go to subshell to manipulate text data stored in ID."
    print "!list: print all loaded objects."

    print "\n--- Subshell commands ---"
    print "!drop: Drop out of subshell created by '!use'."
    print "!print: Display loaded text."
    print "!words: Display word data for loaded text."
    print "!punct: Display punctuation data for loaded text."
    print "!nums: Display number data for loaded text."
    print "!hist: Histogram of word lengths in file."

    print "\r"

    return GO

def _info(*args):

    print "TXTSH Text Analysis Shell (ver. 0.0) on %s." % PLATFORM
    print "Type '!help' for a list of commands."

    return GO

def _log(*args):

    if len(args) > 0:
        if args[0] == 'clear':
            Log.get().clear()
        else:
            print "Unknown command to log: '{}'" .format(args[0])

    else:
        Log.get().view()

    return GO

def _load(*args):

    """
    data_type must be either 'string' or 'file'.

    If data_type is 'string', data will be
    loaded verbatim into a new Text object.

    If data_type is 'file', it will attempt to
    open the data as a read-only text file and
    load its contents into a new Text object.

    A file explorer will launch if file data is not provided.

    """

    if len(args) < 1:
        print "Error: load takes at least one argument."
        return GO

    data_type = args[0]

    if data_type != 'string' and data_type != 'file':
        print "Error: you must specify 'string' or 'file'"
        return GO

    if len(args) != 2 and data_type == 'string':
        print "Error: you must provide a single string to load."
        return GO

    if len(args) == 1 and data_type == 'file':
        explorer = file_explorer.Explorer()
        data = explorer.navigate()

        if data is None:
            print "Error: must provide a data file to load."
            return GO

    else:
        data = args[1]

    new = Text()

    try:
        new.load_data(data_type, data)

        return GO

    except:
        print "Loading text data failed."

        return GO

def _free(*args):

    id = int(args[0])

    object = None

    for member in Text.members:
        if member.id == id:

            object = member

    if not object:
        print "No object found with id '%d'." % id
        return GO

    Text.members.remove(object)

    return GO

def _list(*args):

    if len(Text.members) == 0:
        print "No objects loaded."

    else:
        print "ID\tSAMPLE\n"

        for member in Text.members:
            print '%2s' % member.id,
            print '\t',
            print '"%s"' % member.title

    return GO

def _use(*args):

    id = int(args[0])

    object = None

    for member in Text.members:
        if member.id == id:

            object = member

    if not object:
        print "No object found with id '%d'." % id
        return GO

    subsh = shell.Subshell(object)
    subsh.run()

    return GO

def _quit(*args):

    # Cleanup memory for any loaded objects
    for i in reversed(range(len(Text.members))):
        _free(Text.members[i].id)

    return STOP

def _restart(*args):

    ans = raw_input("Restart txtsh? All loaded objects will be freed! [y/n]: ")
    if ans.lower().strip() == 'y':

        print "\nRestarting...\n"

        # Cleanup memory for any loaded objects
        for i in reversed(range(len(Text.members))):
            _free(Text.members[i].id)

        python = sys.executable

        os.execl(python, python, * sys.argv)

    else:
        return GO

def _update(*args):

    print "Updating txtsh..."

    try:
        os.chdir(TXTSH_HOME_DIR)
        p = subprocess.Popen(['git', 'pull', 'origin', 'master'])
        code = p.wait()

        if code == 0:
            print "Update complete."
            print "If changes were made, restart \
                    (!restart) txtsh for changes to take effect."

        else:
            print "Update failed."

    except:
        print "Update command failed to execute."

    return GO

# ---- MAPPINGS -----

map = {
    '!help': _help,
    '!info': _info,
    '!log': _log,
    '!load': _load,
    '!free': _free,
    '!list': _list,
    '!use': _use,
    '!quit': _quit,
    '!restart': _restart,
    '!update': _update
       }
<commit_msg>Check arguments to _use.<commit_after>import sys
import os
import subprocess

import shell
import file_explorer

from header import *
from text import Text
from log import Log

def _help(*args):

    print "\r"
    print "--- Main shell commands ---"
    print "!info: display version information."
    print "!log: display contents of log file."
    print "!help: display this help screen."
    print "!quit: quit the shell."
    print "!update: update txtsh to the latest version."
    print "!load DATA_TYPE, DATA: load DATA into database. \
DATA_TYPE must be 'string' or 'file'."
    print "!free ID: unload text object stored in ID."
    print "!use ID: go to subshell to manipulate text data stored in ID."
    print "!list: print all loaded objects."

    print "\n--- Subshell commands ---"
    print "!drop: Drop out of subshell created by '!use'."
    print "!print: Display loaded text."
    print "!words: Display word data for loaded text."
    print "!punct: Display punctuation data for loaded text."
    print "!nums: Display number data for loaded text."
    print "!hist: Histogram of word lengths in file."
    print "\r"

    return GO

def _info(*args):

    print "TXTSH Text Analysis Shell (ver. 0.0) on %s." % PLATFORM
    print "Type '!help' for a list of commands."

    return GO

def _log(*args):

    if len(args) > 0:
        if args[0] == 'clear':
            Log.get().clear()
        else:
            print "Unknown command to log: '{}'" .format(args[0])

    else:
        Log.get().view()

    return GO

def _load(*args):

    """
    data_type must be either 'string' or 'file'.

    If data_type is 'string', data will be
    loaded verbatim into a new Text object.

    If data_type is 'file', it will attempt to
    open the data as a read-only text file and
    load its contents into a new Text object.

    A file explorer will launch if file data is not provided.

    """

    if len(args) < 1:
        print "Error: load takes at least one argument."
        return GO

    data_type = args[0]

    if data_type != 'string' and data_type != 'file':
        print "Error: you must specify 'string' or 'file'"
        return GO

    if len(args) != 2 and data_type == 'string':
        print "Error: you must provide a single string to load."
        return GO

    if len(args) == 1 and data_type == 'file':
        explorer = file_explorer.Explorer()
        data = explorer.navigate()

        if data is None:
            print "Error: must provide a data file to load."
            return GO

    else:
        data = args[1]

    new = Text()

    try:
        new.load_data(data_type, data)

        return GO

    except:
        print "Loading text data failed."

        return GO

def _free(*args):

    id = int(args[0])

    object = None

    for member in Text.members:
        if member.id == id:

            object = member

    if not object:
        print "No object found with id '%d'." % id
        return GO

    Text.members.remove(object)

    return GO

def _list(*args):

    if len(Text.members) == 0:
        print "No objects loaded."

    else:
        print "ID\tSAMPLE\n"

        for member in Text.members:
            print '%2s' % member.id,
            print '\t',
            print '"%s"' % member.title

    return GO

def _use(*args):

    try:
        id = int(args[0])
    except:
        print "Error: must specify an ID number."
        return GO

    object = None

    for member in Text.members:
        if member.id == id:

            object = member

    if not object:
        print "No object found with id '%d'." % id
        return GO

    subsh = shell.Subshell(object)
    subsh.run()

    return GO

def _quit(*args):

    # Cleanup memory for any loaded objects
    for i in reversed(range(len(Text.members))):
        _free(Text.members[i].id)

    return STOP

def _restart(*args):

    ans = raw_input("Restart txtsh? All loaded objects will be freed! [y/n]: ")
    if ans.lower().strip() == 'y':

        print "\nRestarting...\n"

        # Cleanup memory for any loaded objects
        for i in reversed(range(len(Text.members))):
            _free(Text.members[i].id)

        python = sys.executable

        os.execl(python, python, * sys.argv)

    else:
        return GO

def _update(*args):

    print "Updating txtsh..."

    try:
        os.chdir(TXTSH_HOME_DIR)
        p = subprocess.Popen(['git', 'pull', 'origin', 'master'])
        code = p.wait()

        if code == 0:
            print "Update complete."
            print "If changes were made, restart \
                    (!restart) txtsh for changes to take effect."

        else:
            print "Update failed."

    except:
        print "Update command failed to execute."

    return GO

# ---- MAPPINGS -----

map = {
    '!help': _help,
    '!info': _info,
    '!log': _log,
    '!load': _load,
    '!free': _free,
    '!list': _list,
    '!use': _use,
    '!quit': _quit,
    '!restart': _restart,
    '!update': _update
       }
<|endoftext|>


<commit_before>#!/usr/bin/env python

# Extra genetics functions
def ibs(g1, g2, checkmissing=True):
    """
    Returns the number of alleles identical by state between two genotypes
    Arguements: Two tuples
    Returns: an integer
    """
    a,b,c,d = g1 + g2
    # Missing genotypes are coded as 0s
    if 0 in {a,b,c,d}:
        return None
    if (a == c and b == d) or (a == d and b == c):
        return 2
    elif a == c or a == d:
        return 1
    return 0
<commit_msg>get_ibs_states function<commit_after>from itertools import izip

# Extra genetics functions
def ibs(g1, g2, checkmissing=True):
    """
    Returns the number of alleles identical by state between two genotypes
    Arguements: Two tuples
    Returns: an integer
    """
    a,b,c,d = g1 + g2
    # Missing genotypes are coded as 0s
    if 0 in {a,b,c,d}:
        return None
    if (a == c and b == d) or (a == d and b == c):
        return 2
    elif a == c or a == d:
        return 1
    return 0

def get_ibs_states(ind1, ind2, chromosome_index):
    genos1 = izip(*ind1.genotypes[chromosome_index])
    genos2 = izip(*ind2.genotypes[chromosome_index])
    return [ibs(x,y) for x,y in izip(genos1, genos2)]
<|endoftext|>