<commit_before># We recommend you to see [the original paper](https://arxiv.org/abs/1404.3606)
# before reading the code below.

# TODO use sphinx
import itertools

import numpy as np
from sklearn.decomposition import PCA

def steps(image_shape, filter_shape, step_shape):
    h, w = image_shape
    fh, fw = filter_shape
    sh, sw = step_shape

    ys = range(0, h-fh+1, sh)
    xs = range(0, w-fw+1, sw)
    return ys, xs

def output_shape(ys, xs):
    return len(ys), len(xs)

class Patches(object):
    def __init__(self, image, filter_shape, step_shape):
        self.image = image
        self.filter_shape = filter_shape

        self.ys, self.xs = steps(image.shape, filter_shape, step_shape)

    @property
    def patches_with_indices(self):
        """
        Yields patches with its location indices.
        Kernel visits the image from the left top into right bottom.

        Yields
        ------
        j : int
            Index of the patch along y axis
        i : int
            Index of the patch along x axis
        patch : np.ndarray
            (j, i)th patch
        """

        # The behaviour is same as below:
        # ```
        # for j, y in enumerate(self.ys):
        #     for i, x in enumerate(self.xs):
        #         yield j, i, self.image[y:y+sh, x:x+sw]
        # ```
        # But the code above does not work when the second time calling,
        # so we create a generator object every time of function call.
        fh, fw = self.filter_shape
        it = itertools.product(enumerate(self.ys), enumerate(self.xs))
        return ((j, i, self.image[y:y+fh, x:x+fw]) for (j, y), (i, x) in it)

    @property
    def patches(self):
        """
        Return patches
        """
        return np.array([p for j, i, p in self.patches_with_indices])

    @property
    def output_shape(self):
        return output_shape(self.ys, self.xs)

def heaviside_step(X):
    X[X > 0] = 1
    X[X <= 0] = 0
    return X

def normalize(X):
    """Subtract mean so that the mean of X be a zero vector"""
    return X - X.mean(axis=0, keepdims=True)

def images_to_patches(images, filter_shape, step_shape):
    """
    Each row of X represents a flattened patch
    The number of columns is N x M where
    N is the number of images and
    M is the number of patches that can be obtained from one image.
    """
    def f(image):
        X = Patches(image, filter_shape, step_shape).patches
        X = X.reshape(X.shape[0], -1)  # reshape each patch into a vector
        return normalize(X)

    return np.vstack([f(image) for image in images])

def convolution(images, filter_, filter_shape, step_shape):
    def convolution_(patches):
        L = np.empty(patches.output_shape)
        for j, i, patch in patches.patches_with_indices:
            L[j, i] = np.dot(filter_.flatten(), patch.flatten())
        return L

    it = (Patches(image, filter_shape, step_shape) for image in images)
    return np.array([convolution_(patches) for patches in it])

def convolutions(images, filters, filter_shape, step_shape):
    # TODO use numpy.vectorize
    c = [convolution(images, f, filter_shape, step_shape) for f in filters]
    return np.array(c)

def binarize(images):
    output = np.zeros(images.shape[1:3])
    for i, image in enumerate(reversed(images)):
        output += np.power(2, i) * heaviside_step(image)
    return output

def to_tuple_if_int(value):
    """
    If int is given, duplicate it and return as a 2 element tuple.
    """
    if isinstance(value, int):
        return (value, value)
    return value

class PCANet(object):
    def __init__(self,
                 filter_shape_l1, step_shape_l1, n_l1_output,
                 filter_shape_l2, step_shape_l2, n_l2_output,
                 block_shape):
        """
        Parameters
        ----------
        filter_shape_l1: int or sequence of ints
            The shape of the kernel in the first convolution layer.
        step_shape_l1: int or sequence of ints
            The shape of kernel step in the first convolution layer.
        n_l1_output:
            L1 in the original paper. The number of outputs obtained
            from a set of input images.
        filter_shape_l2: int or sequence of ints
            The shape of the kernel in the second convolution layer.
        step_shape_l2: int or sequence of ints
            The shape of kernel step in the second convolution layer.
        n_l2_output:
            L2 in the original paper. The number of outputs obtained
            from each L1 output.
        block_shape: int or sequence of ints
            The shape of each block in the pooling layer.
        """

        self.filter_shape_l1 = to_tuple_if_int(filter_shape_l1)
        self.step_shape_l1 = to_tuple_if_int(step_shape_l1)
        self.n_l1_output = n_l1_output

        self.filter_shape_l2 = to_tuple_if_int(filter_shape_l2)
        self.step_shape_l2 = to_tuple_if_int(step_shape_l2)
        self.n_l2_output = n_l2_output

        self.block_shape = to_tuple_if_int(block_shape)
        self.n_bins = None  # TODO make n_bins specifiable

        self.pca_l1 = PCA(n_l1_output)
        self.pca_l2 = PCA(n_l2_output)

    def convolution_l1(self, images):
        return convolutions(images, self.pca_l1.components_,
                            self.filter_shape_l1,
                            self.step_shape_l1)

    def convolution_l2(self, images):
        return convolutions(images, self.pca_l2.components_,
                            self.filter_shape_l2,
                            self.step_shape_l2)

    def histogram(self, binary_image):
        """
        Separate a given image into blocks and calculate a histogram
        in each block.

        Supporse data in a block is in range [0, 3] and the acutual
        values are

        ::

            [0 0 1]
            [2 2 2]
            [2 3 3]

        If default bins ``[-0.5 0.5 1.5 2.5 3.5]`` applied,
        then the histogram will be ``[2 1 4 2]``.
        If ``n_bins`` is specified, the range of data divided equally.
        For example, if the data is in range ``[0, 3]`` and ``n_bins = 2``,
        bins will be ``[-0.5 1.5 3.5]`` and the histogram will be ``[3 6]``.
        """

        k = pow(2, self.n_l2_output)
        if self.n_bins is None:
            self.n_bins = k + 1
        bins = np.linspace(-0.5, k - 0.5, self.n_bins)

        patches = Patches(binary_image, self.block_shape, self.block_shape)

        hist = []
        for patch in patches.patches:
            h, _ = np.histogram(patch, bins)
            hist.append(h)
        return np.concatenate(hist)

    def fit(self, images):
        n_images = images.shape[0]
        patches = images_to_patches(images,
                                    self.filter_shape_l1,
                                    self.step_shape_l1)
        self.pca_l1.fit(patches)

        # images.shape == (L1, n_images, y, x)
        images = self.convolution_l1(images)

        # np.vstack(images).shape == (L1 * n_images, y, x)
        patches = images_to_patches(np.vstack(images),
                                    self.filter_shape_l2,
                                    self.step_shape_l2)
        self.pca_l2.fit(patches)
        return self

    def transform(self, images):
        assert(np.ndim(images) == 3)  # input image must be grayscale

        n_images = images.shape[0]

        # images.shape == (n_images, y, x)
        L1 = self.convolution_l1(images)

        # L1.shape == (L1, n_images, y, x)
        # iterate over each L1 output
        X = []
        for maps in L1:
            # maps.shape == (n_images, y, x)
            maps = self.convolution_l2(maps)
            # feature maps are generated.
            # maps.shape == (L2, n_images, y, x) right here
            maps = np.swapaxes(maps, 0, 1)
            # maps.shape == (n_images, L2, y, x)
            x = [self.histogram(binarize(m)) for m in maps]
            X.append(x)
        X = np.array(X)
        # transform X into the form (n_images, n_features).
        # now X.shape == (L1, n_images, n) where n is a value derived
        # from block_shape and the dimensions of each histogram.
        X = np.swapaxes(X, 0, 1)  # X.shape == (n_images, L1, n)
        X = X.reshape(n_images, -1)  # flatten each subarray
        return X  # now X.shape == (n_images, L1*n)

    def structure_is_valid(self, image_shape):
        """
        Check that the filter visits all pixels of input images without
        dropping any information.
        """
        def is_valid_(image_shape, filter_shape, step_shape):
            ys, xs = steps(image_shape, filter_shape, step_shape)
            fh, fw = filter_shape
            h, w = image_shape
            assert(ys[-1]+fh == h)
            assert(xs[-1]+fw == w)
            return output_shape(ys, xs)

        image_shape = to_tuple_if_int(image_shape)

        try:
            output_shape_l1 = is_valid_(image_shape,
                                        self.filter_shape_l1,
                                        self.step_shape_l1)
            output_shape_l2 = is_valid_(output_shape_l1,
                                        self.filter_shape_l2,
                                        self.step_shape_l2)
            is_valid_(output_shape_l2, self.block_shape, self.block_shape)
        except AssertionError:
            return False
        return True
<commit_msg>Return matrix as np.float64. Allow only 3d array for fit()<commit_after># We recommend you to see [the original paper](https://arxiv.org/abs/1404.3606)
# before reading the code below.

# TODO use sphinx
import itertools

import numpy as np
from sklearn.decomposition import PCA

def steps(image_shape, filter_shape, step_shape):
    h, w = image_shape
    fh, fw = filter_shape
    sh, sw = step_shape

    ys = range(0, h-fh+1, sh)
    xs = range(0, w-fw+1, sw)
    return ys, xs

def output_shape(ys, xs):
    return len(ys), len(xs)

class Patches(object):
    def __init__(self, image, filter_shape, step_shape):
        self.image = image
        self.filter_shape = filter_shape

        self.ys, self.xs = steps(image.shape, filter_shape, step_shape)

    @property
    def patches_with_indices(self):
        """
        Yields patches with its location indices.
        Kernel visits the image from the left top into right bottom.

        Yields
        ------
        j : int
            Index of the patch along y axis
        i : int
            Index of the patch along x axis
        patch : np.ndarray
            (j, i)th patch
        """

        # The behaviour is same as below:
        # ```
        # for j, y in enumerate(self.ys):
        #     for i, x in enumerate(self.xs):
        #         yield j, i, self.image[y:y+sh, x:x+sw]
        # ```
        # But the code above does not work when the second time calling,
        # so we create a generator object every time of function call.
        fh, fw = self.filter_shape
        it = itertools.product(enumerate(self.ys), enumerate(self.xs))
        return ((j, i, self.image[y:y+fh, x:x+fw]) for (j, y), (i, x) in it)

    @property
    def patches(self):
        """
        Return patches
        """
        return np.array([p for j, i, p in self.patches_with_indices])

    @property
    def output_shape(self):
        return output_shape(self.ys, self.xs)

def heaviside_step(X):
    X[X > 0] = 1
    X[X <= 0] = 0
    return X

def normalize(X):
    """Subtract mean so that the mean of X be a zero vector"""
    return X - X.mean(axis=0, keepdims=True)

def images_to_patches(images, filter_shape, step_shape):
    """
    Each row of X represents a flattened patch
    The number of columns is N x M where
    N is the number of images and
    M is the number of patches that can be obtained from one image.
    """
    def f(image):
        X = Patches(image, filter_shape, step_shape).patches
        X = X.reshape(X.shape[0], -1)  # reshape each patch into a vector
        return normalize(X)

    return np.vstack([f(image) for image in images])

def convolution(images, filter_, filter_shape, step_shape):
    def convolution_(patches):
        L = np.empty(patches.output_shape)
        for j, i, patch in patches.patches_with_indices:
            L[j, i] = np.dot(filter_.flatten(), patch.flatten())
        return L

    it = (Patches(image, filter_shape, step_shape) for image in images)
    return np.array([convolution_(patches) for patches in it])

def convolutions(images, filters, filter_shape, step_shape):
    # TODO use numpy.vectorize
    c = [convolution(images, f, filter_shape, step_shape) for f in filters]
    return np.array(c)

def binarize(images):
    output = np.zeros(images.shape[1:3])
    for i, image in enumerate(reversed(images)):
        output += np.power(2, i) * heaviside_step(image)
    return output

def to_tuple_if_int(value):
    """
    If int is given, duplicate it and return as a 2 element tuple.
    """
    if isinstance(value, int):
        return (value, value)
    return value

class PCANet(object):
    def __init__(self,
                 filter_shape_l1, step_shape_l1, n_l1_output,
                 filter_shape_l2, step_shape_l2, n_l2_output,
                 block_shape):
        """
        Parameters
        ----------
        filter_shape_l1: int or sequence of ints
            The shape of the kernel in the first convolution layer.
        step_shape_l1: int or sequence of ints
            The shape of kernel step in the first convolution layer.
        n_l1_output:
            L1 in the original paper. The number of outputs obtained
            from a set of input images.
        filter_shape_l2: int or sequence of ints
            The shape of the kernel in the second convolution layer.
        step_shape_l2: int or sequence of ints
            The shape of kernel step in the second convolution layer.
        n_l2_output:
            L2 in the original paper. The number of outputs obtained
            from each L1 output.
        block_shape: int or sequence of ints
            The shape of each block in the pooling layer.
        """

        self.filter_shape_l1 = to_tuple_if_int(filter_shape_l1)
        self.step_shape_l1 = to_tuple_if_int(step_shape_l1)
        self.n_l1_output = n_l1_output

        self.filter_shape_l2 = to_tuple_if_int(filter_shape_l2)
        self.step_shape_l2 = to_tuple_if_int(step_shape_l2)
        self.n_l2_output = n_l2_output

        self.block_shape = to_tuple_if_int(block_shape)
        self.n_bins = None  # TODO make n_bins specifiable

        self.pca_l1 = PCA(n_l1_output)
        self.pca_l2 = PCA(n_l2_output)

    def convolution_l1(self, images):
        return convolutions(images, self.pca_l1.components_,
                            self.filter_shape_l1,
                            self.step_shape_l1)

    def convolution_l2(self, images):
        return convolutions(images, self.pca_l2.components_,
                            self.filter_shape_l2,
                            self.step_shape_l2)

    def histogram(self, binary_image):
        """
        Separate a given image into blocks and calculate a histogram
        in each block.

        Supporse data in a block is in range [0, 3] and the acutual
        values are

        ::

            [0 0 1]
            [2 2 2]
            [2 3 3]

        If default bins ``[-0.5 0.5 1.5 2.5 3.5]`` applied,
        then the histogram will be ``[2 1 4 2]``.
        If ``n_bins`` is specified, the range of data divided equally.
        For example, if the data is in range ``[0, 3]`` and ``n_bins = 2``,
        bins will be ``[-0.5 1.5 3.5]`` and the histogram will be ``[3 6]``.
        """

        k = pow(2, self.n_l2_output)
        if self.n_bins is None:
            self.n_bins = k + 1
        bins = np.linspace(-0.5, k - 0.5, self.n_bins)

        patches = Patches(binary_image, self.block_shape, self.block_shape)

        hist = []
        for patch in patches.patches:
            h, _ = np.histogram(patch, bins)
            hist.append(h)
        return np.concatenate(hist)

    def fit(self, images):
        assert(np.ndim(images) == 3)  # input image must be grayscale
        n_images = images.shape[0]
        patches = images_to_patches(images,
                                    self.filter_shape_l1,
                                    self.step_shape_l1)
        self.pca_l1.fit(patches)

        # images.shape == (L1, n_images, y, x)
        images = self.convolution_l1(images)

        # np.vstack(images).shape == (L1 * n_images, y, x)
        patches = images_to_patches(np.vstack(images),
                                    self.filter_shape_l2,
                                    self.step_shape_l2)
        self.pca_l2.fit(patches)
        return self

    def transform(self, images):
        assert(np.ndim(images) == 3)  # input image must be grayscale

        n_images = images.shape[0]

        # images.shape == (n_images, y, x)
        L1 = self.convolution_l1(images)

        # L1.shape == (L1, n_images, y, x)
        # iterate over each L1 output
        X = []
        for maps in L1:
            # maps.shape == (n_images, y, x)
            maps = self.convolution_l2(maps)
            # feature maps are generated.
            # maps.shape == (L2, n_images, y, x) right here
            maps = np.swapaxes(maps, 0, 1)
            # maps.shape == (n_images, L2, y, x)
            x = [self.histogram(binarize(m)) for m in maps]
            X.append(x)
        X = np.array(X)
        # transform X into the form (n_images, n_features).
        # now X.shape == (L1, n_images, n) where n is a value derived
        # from block_shape and the dimensions of each histogram.
        X = np.swapaxes(X, 0, 1)  # X.shape == (n_images, L1, n)
        X = X.reshape(n_images, -1)  # flatten each subarray
        return X.astype(np.float64)  # now X.shape == (n_images, L1*n)

    def structure_is_valid(self, image_shape):
        """
        Check that the filter visits all pixels of input images without
        dropping any information.
        """
        def is_valid_(image_shape, filter_shape, step_shape):
            ys, xs = steps(image_shape, filter_shape, step_shape)
            fh, fw = filter_shape
            h, w = image_shape
            assert(ys[-1]+fh == h)
            assert(xs[-1]+fw == w)
            return output_shape(ys, xs)

        image_shape = to_tuple_if_int(image_shape)

        try:
            output_shape_l1 = is_valid_(image_shape,
                                        self.filter_shape_l1,
                                        self.step_shape_l1)
            output_shape_l2 = is_valid_(output_shape_l1,
                                        self.filter_shape_l2,
                                        self.step_shape_l2)
            is_valid_(output_shape_l2, self.block_shape, self.block_shape)
        except AssertionError:
            return False
        return True
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
===========================================================================
Crystal unit cell classes (:mod:`sknano.core.crystallography._unit_cells`)
===========================================================================

.. currentmodule:: sknano.core.crystallography._unit_cells

"""
from __future__ import absolute_import, division, print_function, \
    unicode_literals
# from builtins import super
# from builtins import dict
from future import standard_library
standard_library.install_aliases()
# from future.utils import with_metaclass

__docformat__ = 'restructuredtext en'

import copy
# import numbers
# from abc import ABCMeta, abstractproperty

import numpy as np

from sknano.core.math import Vector
from sknano.core.atoms import BasisAtoms as Atoms

__all__ = ['UnitCell']

class UnitCell:
    """Abstract base class for crystal unit cell."""

    def __init__(self, lattice=None, basis=None, coords=None, cartesian=False):

        if basis is None:
            basis = Atoms()
        elif basis is not None:
            basis = Atoms(basis, lattice=lattice)
            if coords is not None:
                for atom, pos in zip(basis, coords):
                    atom.lattice = lattice
                    if not cartesian:
                        atom.rs = pos
                    else:
                        atom.rs = lattice.cartesian_to_fractional(pos)

        self.lattice = lattice
        self.basis = basis
        # self.fmtstr = "lattice={lattice!r}, basis={basis!r}"
        self.fmtstr = "{lattice!r}, {basis!r}, {coords!r}, cartesian=False"

    def __repr__(self):
        return "{}({})".format(self.__class__.__name__,
                               self.fmtstr.format(**self.todict()))

    # @property
    # def basis(self):
    #     return self._basis

    # @basis.setter
    # def basis(self, value):
    #     lattice = self.lattice
    #     coords = self.coords
    #     if value is None:
    #         value = Atoms()
    #     elif value is not None:
    #         value = Atoms(value, lattice=lattice)
    #         if coords is not None:
    #             for atom, pos in zip(basis, coords):
    #                 atom.lattice = lattice
    #                 if not cartesian:
    #                     atom.rs = pos
    #                 else:
    #                     atom.rs = lattice.cartesian_to_fractional(pos)

    # @property
    # def lattice(self):
    #     return self._lattice

    # @lattice.setter
    # def lattice(self, value):
    #     self._lattice = value

    def __getattr__(self, name):
        return getattr(self.lattice, name)
        # if name != '_lattice':
        #     return getattr(self._lattice, name)

    # def __setattr__(self, name, value):
    #     if name.startswith('_'):
    #         super().__setattr__(name, value)
    #     else:
    #         setattr(self._lattice, name, value)

    def rotate(self, **kwargs):
        self.lattice.rotate(**kwargs)
        self.basis.rotate(**kwargs)

    def todict(self):
        """Return `dict` of `CrystalStructure` parameters."""
        return dict(lattice=self.lattice, basis=self.basis.symbols.tolist(),
                    coords=self.basis.rs.tolist())
<commit_msg>cleaning up old commented out code<commit_after># -*- coding: utf-8 -*-
"""
===========================================================================
Crystal unit cell classes (:mod:`sknano.core.crystallography._unit_cells`)
===========================================================================

.. currentmodule:: sknano.core.crystallography._unit_cells

"""
from __future__ import absolute_import, division, print_function, \
    unicode_literals
# from builtins import super
# from builtins import dict
from future import standard_library
standard_library.install_aliases()
# from future.utils import with_metaclass

__docformat__ = 'restructuredtext en'

import copy
# import numbers
# from abc import ABCMeta, abstractproperty

import numpy as np

from sknano.core.math import Vector
from sknano.core.atoms import BasisAtoms as Atoms

__all__ = ['UnitCell']

class UnitCell:
    """Abstract base class for crystal unit cell."""

    def __init__(self, lattice=None, basis=None, coords=None, cartesian=False):

        if basis is None:
            basis = Atoms()
        elif basis is not None:
            basis = Atoms(basis, lattice=lattice)
            if coords is not None:
                for atom, pos in zip(basis, coords):
                    atom.lattice = lattice
                    if not cartesian:
                        atom.rs = pos
                    else:
                        atom.rs = lattice.cartesian_to_fractional(pos)

        self.lattice = lattice
        self.basis = basis
        self.fmtstr = "{lattice!r}, {basis!r}, {coords!r}, cartesian=False"

    def __repr__(self):
        return "{}({})".format(self.__class__.__name__,
                               self.fmtstr.format(**self.todict()))

    # @property
    # def basis(self):
    #     return self._basis

    # @basis.setter
    # def basis(self, value):
    #     lattice = self.lattice
    #     coords = self.coords
    #     if value is None:
    #         value = Atoms()
    #     elif value is not None:
    #         value = Atoms(value, lattice=lattice)
    #         if coords is not None:
    #             for atom, pos in zip(basis, coords):
    #                 atom.lattice = lattice
    #                 if not cartesian:
    #                     atom.rs = pos
    #                 else:
    #                     atom.rs = lattice.cartesian_to_fractional(pos)

    # @property
    # def lattice(self):
    #     return self._lattice

    # @lattice.setter
    # def lattice(self, value):
    #     self._lattice = value

    def __getattr__(self, name):
        return getattr(self.lattice, name)
        # if name != '_lattice':
        #     return getattr(self._lattice, name)

    # def __setattr__(self, name, value):
    #     if name.startswith('_'):
    #         super().__setattr__(name, value)
    #     else:
    #         setattr(self._lattice, name, value)

    def rotate(self, **kwargs):
        self.lattice.rotate(**kwargs)
        self.basis.rotate(**kwargs)

    def todict(self):
        """Return `dict` of `CrystalStructure` parameters."""
        return dict(lattice=self.lattice, basis=self.basis.symbols.tolist(),
                    coords=self.basis.rs.tolist())
<|endoftext|>


<commit_before># ######################################################################
# Copyright (c) 2014, Brookhaven Science Associates, Brookhaven        #
# National Laboratory. All rights reserved.                            #
#                                                                      #
# Original code:                                                       #
# @author: Andrei Fluerasu, Brookhaven National Laboratory and         #
# Pawel Kwasniewski, European Synchrotron Radiation Facility           #
#                                                                      #
# Developed at the NSLS-II, Brookhaven National Laboratory             #
# Developed by Sameera K. Abeykoon, June 2015                          #
#                                                                      #
# Redistribution and use in source and binary forms, with or without   #
# modification, are permitted provided that the following conditions   #
# are met:                                                             #
#                                                                      #
# * Redistributions of source code must retain the above copyright     #
#   notice, this list of conditions and the following disclaimer.      #
#                                                                      #
# * Redistributions in binary form must reproduce the above copyright  #
#   notice this list of conditions and the following disclaimer in     #
#   the documentation and/or other materials provided with the         #
#   distribution.                                                      #
#                                                                      #
# * Neither the name of the Brookhaven Science Associates, Brookhaven  #
#   National Laboratory nor the names of its contributors may be used  #
#   to endorse or promote products derived from this software without  #
#   specific prior written permission.                                 #
#                                                                      #
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  #
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    #
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    #
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE       #
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,           #
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES   #
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR   #
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)   #
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,  #
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OTHERWISE) ARISING   #
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE   #
# POSSIBILITY OF SUCH DAMAGE.                                          #
########################################################################

"""
    This module will provide fitting tools for
    X-ray Speckle Visibility Spectroscopy (XSVS)
"""

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
import six

from six.moves import zip
from six import string_types

import logging

import numpy as np
from time import time

from scipy.stats import nbinom
from scipy.special import gamma, gammaln

from lmfit import minimize, Parameters

logger = logging.getLogger(__name__)

def negative_binom_distribution(K, M, bin_centers):
    """
    Negative Binomial (Poisson-Gamma) distribution function
    Parameters
    ----------
    K : int
        number of photons

    M : int
        number of coherent modes

    bin_centers : array
        normalized bin centers

    Returns
    -------
    poisson_dist : array
        Negative Binomial (Poisson-Gamma) distribution function

    Note
    ----
    These implementation is based on following references
    References: text [1]_, text [2]_

    .. [1] L. Li, P. Kwasniewski, D. Oris, L Wiegart, L. Cristofolini,
       C. Carona and A. Fluerasu , "Photon statistics and speckle visibility
       spectroscopy with partially coherent x-rays" J. Synchrotron Rad.,
       vol 21, p 1288-1295, 2014.

    .. [2] R. Bandyopadhyay, A. S. Gittings, S. S. Suh, P.K. Dixon and
       D.J. Durian "Speckle-visibilty Spectroscopy: A tool to study
       time-varying dynamics" Rev. Sci. Instrum. vol 76, p  093110, 2005.

    """
    co_eff = np.exp(gammaln(bin_centers + M) -
                    gammaln(bin_centers + 1) - gammaln(M))

    poisson_gamma = co_eff * np.power(M / (K + M), M)
    co_eff2 = np.power(K / (M + K), bin_centers)
    poisson_gamma *= co_eff2
    return poisson_gamma

def poisson_distribution(K, bin_centers):
    """
    Poisson Distribution

    Parameters
    ---------
    K : int
        number of photons

    bin_centers : array

    Returns
    -------
    poisson_dist : array
       Poisson Distribution

    Note
    ----
    These implementation based on the references under
    nbinom_distribution() function Note

    """
    poisson_dist = np.exp(-K) * np.power(K, bin_centers)/gamma(bin_centers + 1)
    return poisson_dist

def gamma_distribution(M, K, bin_centers):
    """
    Gamma distribution function

    Parameters
    ----------
    M : int
        number of coherent modes

    K : int
        number of photons

    bin_centers : array
        normalized bin centers

    Returns
    -------
    gamma_dist : array
        Gamma distribution

    Note
    ----
    These implementation based on the references under
    negative_binom_distribution() function Note
    """

    co_eff = np.exp(M * np.log(M) + (M - 1) * np.log(bin_centers) -
                   gammaln(M) - M * np.log(K))
    gamma_dist = co_eff * np.exp(- M * bin_centers / K)
    return gamma_dist

def model_residuals(params, bin_centers, y, yerr=1):
    """
    Residuals function for least squares fitting,
    K may be a fixed parameter

    Parameters
    ----------
    M : int
        number of coherent modes

    K : int
        number of photons

    y : array
        probability of detecting speckles

    bin_centers : array
        normalized bin centers

    yerr : array, optional
        standard error of y

    Returns
    -------
    model_residual : array
        Residuals function for least squares fitting
    """
    # create set of parameters
    M = params['M'].value
    K = params['K'].value

    return (y - negative_binom_distribution(K, M, bin_centers))/yerr

def eval_binomal_dist(params, bin_centers, data, err=1):
    """
    Function will minimize difference between probability of the detecting
    speckles and negative binomial distribution for the given set of
    input parameters.

    Parameters
    ----------
    M : int
        number of coherent modes

    K : int
        average number of photons

    bin_centers : array
        normalized bin centers

    data : array
        probability of detecting speckles

    err : array, optional
        standard error of y

    Returns
    -------
    final_result : array

    """
    result = minimize(model_residuals, params, args=(bin_centers, data, err))
    return data + result.residual

def diffusive_motion_contrast_factor(times, relaxation_rate,
                                     contrast_factor, cf_baseline=0):
    """
    Parameters
    ----------
    times : array

    relaxation_rate : float

    contrast_factor : float

    cf_baseline : float, optional

    Return
    ------
    diff_contrast_factor : array

    """
    co_eff = (np.exp(-2*relaxation_rate*times) - 1 +
              2*relaxation_rate*times)/2*(relaxation_rate*times)**2

    return contrast_factor*co_eff + cf_baseline

def cf_residuals(params, times, data, err):
    """
    Parameters
    ----------
    params :

    times : array

    data : array

    err : array

    Returns
    --------
    """
    # create set of parameters
    relax_rate = params['relaxation_rate'].value
    cf = params['contrast_factor'].value
    cf_baseline = params['cf_baseline'].value

    return (data - diffusive_motion_contrast_factor(times, relax_rate,
                                                    cf, cf_baseline))

def minimize_dm_cf(params, times, data, err=1):
    result = minimize(cf_residuals, params, args=(times, data, err))
    return data + result.residual<commit_msg>ENH: working with diffusion coff functions<commit_after># ######################################################################
# Copyright (c) 2014, Brookhaven Science Associates, Brookhaven        #
# National Laboratory. All rights reserved.                            #
#                                                                      #
# Original code:                                                       #
# @author: Andrei Fluerasu, Brookhaven National Laboratory and         #
# Pawel Kwasniewski, European Synchrotron Radiation Facility           #
#                                                                      #
# Developed at the NSLS-II, Brookhaven National Laboratory             #
# Developed by Sameera K. Abeykoon, June 2015                          #
#                                                                      #
# Redistribution and use in source and binary forms, with or without   #
# modification, are permitted provided that the following conditions   #
# are met:                                                             #
#                                                                      #
# * Redistributions of source code must retain the above copyright     #
#   notice, this list of conditions and the following disclaimer.      #
#                                                                      #
# * Redistributions in binary form must reproduce the above copyright  #
#   notice this list of conditions and the following disclaimer in     #
#   the documentation and/or other materials provided with the         #
#   distribution.                                                      #
#                                                                      #
# * Neither the name of the Brookhaven Science Associates, Brookhaven  #
#   National Laboratory nor the names of its contributors may be used  #
#   to endorse or promote products derived from this software without  #
#   specific prior written permission.                                 #
#                                                                      #
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  #
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    #
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    #
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE       #
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,           #
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES   #
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR   #
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)   #
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,  #
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OTHERWISE) ARISING   #
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE   #
# POSSIBILITY OF SUCH DAMAGE.                                          #
########################################################################

"""
    This module will provide fitting tools for
    X-ray Speckle Visibility Spectroscopy (XSVS)
"""

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
import six

from six.moves import zip
from six import string_types

import logging

import numpy as np
from time import time

from scipy.stats import nbinom
from scipy.special import gamma, gammaln

from lmfit import minimize, Parameters

logger = logging.getLogger(__name__)

def negative_binom_distribution(K, M, bin_centers):
    """
    Negative Binomial (Poisson-Gamma) distribution function
    Parameters
    ----------
    K : int
        number of photons

    M : int
        number of coherent modes

    bin_centers : array
        normalized speckle count bin centers

    Returns
    -------
    poisson_dist : array
        Negative Binomial (Poisson-Gamma) distribution function

    Note
    ----
    These implementation is based on following references
    References: text [1]_, text [2]_

    .. [1] L. Li, P. Kwasniewski, D. Oris, L Wiegart, L. Cristofolini,
       C. Carona and A. Fluerasu , "Photon statistics and speckle visibility
       spectroscopy with partially coherent x-rays" J. Synchrotron Rad.,
       vol 21, p 1288-1295, 2014.

    .. [2] R. Bandyopadhyay, A. S. Gittings, S. S. Suh, P.K. Dixon and
       D.J. Durian "Speckle-visibilty Spectroscopy: A tool to study
       time-varying dynamics" Rev. Sci. Instrum. vol 76, p  093110, 2005.

    """
    co_eff = np.exp(gammaln(bin_centers + M) -
                    gammaln(bin_centers + 1) - gammaln(M))

    poisson_gamma = co_eff * np.power(M / (K + M), M)
    co_eff2 = np.power(K / (M + K), bin_centers)
    poisson_gamma *= co_eff2
    return poisson_gamma

def poisson_distribution(K, bin_centers):
    """
    Poisson Distribution

    Parameters
    ---------
    K : int
        number of photons

    bin_centers : array
        normalized speckle count bin centers

    Returns
    -------
    poisson_dist : array
       Poisson Distribution

    Note
    ----
    These implementations are based on the references under
    nbinom_distribution() function Note

    """
    poisson_dist = np.exp(-K) * np.power(K, bin_centers)/gamma(bin_centers + 1)
    return poisson_dist

def gamma_distribution(M, K, bin_centers):
    """
    Gamma distribution function

    Parameters
    ----------
    M : int
        number of coherent modes

    K : int
        number of photons

    bin_centers : array
        normalized speckle count bin centers

    Returns
    -------
    gamma_dist : array
        Gamma distribution

    Note
    ----
    These implementations are based on the references under
    negative_binom_distribution() function Note
    """

    co_eff = np.exp(M * np.log(M) + (M - 1) * np.log(bin_centers) -
                   gammaln(M) - M * np.log(K))
    gamma_dist = co_eff * np.exp(- M * bin_centers / K)
    return gamma_dist

def model_residuals(params, bin_centers, y, yerr):
    """
    Residuals function for least squares fitting,
    K may be a fixed parameter

    Parameters
    ----------
    M : int
        number of coherent modes

    K : int
        number of photons

    y : array
        probability of detecting speckles

    bin_centers : array
        normalized speckle count bin centers

    yerr : array, optional
        standard error of y

    Returns
    -------
    model_residual : array
        Residuals function for least squares fitting

    Note
    ----
    These implementations are based on the references under
    negative_binom_distribution() function Note
    """
    # create set of parameters
    M = params['M'].value
    K = params['K'].value

    return (y - negative_binom_distribution(K, M, bin_centers))/yerr

def eval_binomal_dist(params, bin_centers, data, err):
    """
    Function will minimize difference between probability of the detecting
    speckles and negative binomial distribution for the given set of
    input parameters.

    Parameters
    ----------
    M : int
        number of coherent modes

    K : int
        average number of photons

    bin_centers : array
        normalized speckle count bin centers

    data : array
        probability of detecting speckles

    err : array
        standard error of data

    Returns
    -------
    final_result : array

    Note
    ----
    These implementations are based on the references under
    negative_binom_distribution() function Note

    """
    result = minimize(model_residuals, params, args=(bin_centers, data, err))
    return data + result.residual

def diffusive_motion_contrast_factor(times, relaxation_rate,
                                     contrast_factor, cf_baseline=0):
    """
    This will provide the speckle contrast factor of samples undergoing
    a diffusive motion.

    Parameters
    ----------
    times : array
        integration times

    relaxation_rate : float

    contrast_factor : float

    cf_baseline : float, optional

    Return
    ------
    diff_contrast_factor : array
        speckle contrast factor for samples undergoing a diffusive motion

    Note
    ----
    integration times more information - geometric_series function in
    skxray.core module

    These implementations are based on the references under
    negative_binom_distribution() function Note

    """
    co_eff = (np.exp(-2*relaxation_rate*times) - 1 +
              2*relaxation_rate*times)/(2*(relaxation_rate*times)**2)

    return contrast_factor*co_eff + cf_baseline

def cf_residuals(params, times, data, err):
    """
    The dynamic information of the sample motions extracted by fitting
    experimental speckle contrast factor.

    Parameters
    ----------
    params : dict or Parameters
        relaxation_rate - float, relaxation time associated with the
        samples dynamics,
        contrast_factor - float, optical contrast (speckle contrast),
        cf_baseline - float, baseline of contrast factor (usually ~zero)
        Have to give either as a dictionary or Parameters
        # create a dictionary
        {'relaxation_rate': 6.7, 'contrast_factor': 0.23, 'cf_baseline':1}

        # create a set of Parameters
        from lmfit import Parameters
        params = Parameters()
        params.add('contrast_factor',  value=0.22,  min=0.19, max=0.0.23)
        params.add('relaxation_rate', value=6.7, min=6.68, max=6.74)
        params.add('cf_baseline', value=0)

    times : array
        integration times

    data : array
        contrast factor for sample undergoing diffusive motion

    err : array
        standard error of the contrast factor

    Returns
    --------
    model_residual : array
        Residuals function for least squares fitting

    Note
    ----
    integration times more information - geometric_series function in
    skxray.core module

    These implementations are based on the references under
    negative_binom_distribution() function Note

    """
    # create set of parameters
    relax_rate = params['relaxation_rate'].value
    cf = params['contrast_factor'].value
    cf_baseline = params['cf_baseline'].value

    return (data - diffusive_motion_contrast_factor(times, relax_rate,
                                                    cf, cf_baseline))

def minimize_dm_cf(params, times, data, err):
    """

    Parameters
    ----------
    params :dict or Parameters
        relaxation_rate - float, relaxation time associated with the
        samples dynamics,
        contrast_factor - float, optical contrast (speckle contrast),
        cf_baseline - float, baseline of contrast factor (usually ~zero)
        Have to give either as a dictionary or Parameters
        # create a dictionary
        {'relaxation_rate': 6.7, 'contrast_factor': 0.23, 'cf_baseline':1}

        # create a set of Parameters
        from lmfit import Parameters
        params = Parameters()
        params.add('contrast_factor',  value=0.22,  min=0.19, max=0.0.23)
        params.add('relaxation_rate', value=6.7, min=6.68, max=6.74)
        params.add('cf_baseline', value=0)

    times : array
        integration times

    data : array
        contrast factor for sample undergoing diffusive motion

    err : array
        standard error of the contrast factor

    Returns
    -------
     final_result : array
        minimized fitting to results using least square model

    Note
    ----
    integration times more information - geometric_series function in
    skxray.core module

    These implementations are based on the references under
    negative_binom_distribution() function Note

    """
    result = minimize(cf_residuals, params, args=(times, data, err))
    return data + result.residual

def diffusive_coefficient(relaxation_rates, q_values):
    """
    For Brownian samples, the diffusive coefficient can be obtained

    Parameters
    ---------
    relaxation_rates : array
        relaxation rates of the sample Brownian motion

    q_values : array
        scattering vectors for each relaxation rates
        (same shape as relaxation_rates)

    Returns
    -------
    diff_co : float
        diffusive coefficient for Brownian samples

    Note
    ----
    These implementations are based on the references under
    negative_binom_distribution() function Note

    """
    return relaxation_rates/(q_values**2)

def diff_co_residuals(params, diff_co, q_values):
    """
    Parameters
    ----------
    params : dict or Parameters
        relax_rate - float, relaxation time associated with the
        samples dynamics,

    diff_co : array
        diffusive coefficients

    q_values:

    Return
    ------

    """
    # create set of parameters
    relax_rate = params['relaxation_rate'].value

    return (diff_co - diffusive_coefficient(relax_rate, q_values))

def minimize_diff_co(params, q_values,  diff_co, err):

    result = minimize(diffusive_coefficient, params, args=(1/q_values**2,
                                                           diff_co, err))
    return diff_co + result.residual
<|endoftext|>


<commit_before>class x264(Wig):
  git_uri = 'http://git.videolan.org/git/x264.git'

  def setup(self):
    self.configure_flags += ['--enable-static']
<commit_msg>Update x264.py<commit_after>class x264(Wig):
  git_uri = 'http://git.videolan.org/git/x264.git'

  def setup(self):
    self.configure_flags += ['--enable-static', '--enable-shared']
<|endoftext|>


<commit_before>import json
import time
import http.client

from paste import config

def get(alias):
    # connect to API
    if config.store_https:
        conn = http.client.HTTPSConnection(config.store)
    else:
        conn = http.client.HTTPConnection(config.store)

    # request given alias
    conn.request('GET', config.store_endpoint + 'store/paste/' + alias)

    # get response
    response = conn.getresponse()

    # check for 404
    if response.status == 404:
        raise KeyError()

    # get metadata
    name = response.getheader('Content-Filename')
    date = response.getheader('Last-Modified')
    expire = response.getheader('Expires')
    language = response.getheader('Content-Type')

    # store the code
    code = response.read().decode('utf-8')

    return name, date, expire, language, code

def put(alias, name, language, code):
    if isinstance(code, str):
        code = code.encode('utf-8')

    # connect to API
    if config.store_https:
        conn = http.client.HTTPSConnection(config.store)
    else:
        conn = http.client.HTTPConnection(config.store)

    # request given alias
    conn.request('HEAD', config.store_endpoint + 'store/paste/' + alias)

    # get response
    response = conn.getresponse()
    response.read()

    # check for existing alias
    if response.status == 200:
        raise KeyError()
    elif response.status == 400:
        raise NameError()
    elif response.status != 404:
        raise ValueError()

    # determine if this is a put or a post
    if alias:
        method = 'PUT'
    else:
        method = 'POST'

    # make a metadata request
    conn.request(method, config.store_endpoint + 'api/paste/' + alias, headers={'Content-Type': 'application/json'}, body=json.dumps({'filename': name, 'size': len(code), 'type': language, 'expire': time.time() + config.interval, 'locked': True}).encode('utf-8'))

    # get response
    response = conn.getresponse()

    # load data response
    data = json.loads(response.read().decode('utf-8'))

    # note bad requests
    if response.status != 201:
        raise ValueError()

    # make a data request
    conn.request('PUT', config.store_endpoint + 'store/paste/' + data['alias'], body=code)

    # get response
    response = conn.getresponse()
    response.read()

    # note bad requests
    if response.status != 204:
        raise KeyError()

    return data['alias']
<commit_msg>fix error message for invalid alias<commit_after>import json
import time
import http.client

from paste import config

def get(alias):
    # connect to API
    if config.store_https:
        conn = http.client.HTTPSConnection(config.store)
    else:
        conn = http.client.HTTPConnection(config.store)

    # request given alias
    conn.request('GET', config.store_endpoint + 'store/paste/' + alias)

    # get response
    response = conn.getresponse()

    # check for 404
    if response.status == 404:
        raise KeyError()

    # get metadata
    name = response.getheader('Content-Filename')
    date = response.getheader('Last-Modified')
    expire = response.getheader('Expires')
    language = response.getheader('Content-Type')

    # store the code
    code = response.read().decode('utf-8')

    return name, date, expire, language, code

def put(alias, name, language, code):
    if isinstance(code, str):
        code = code.encode('utf-8')

    # connect to API
    if config.store_https:
        conn = http.client.HTTPSConnection(config.store)
    else:
        conn = http.client.HTTPConnection(config.store)

    # request given alias
    conn.request('HEAD', config.store_endpoint + 'store/paste/' + alias)

    # get response
    response = conn.getresponse()
    response.read()

    # check for existing alias
    if response.status == 200:
        raise KeyError()
    elif response.status == 400:
        raise NameError()
    elif response.status != 404:
        raise ValueError()

    # determine if this is a put or a post
    if alias:
        method = 'PUT'
    else:
        method = 'POST'

    # make a metadata request
    conn.request(method, config.store_endpoint + 'api/paste/' + alias, headers={'Content-Type': 'application/json'}, body=json.dumps({'filename': name, 'size': len(code), 'type': language, 'expire': time.time() + config.interval, 'locked': True}).encode('utf-8'))

    # get response
    response = conn.getresponse()

    # load data response
    data = json.loads(response.read().decode('utf-8'))

    # note bad requests
    if response.status == 404:
        raise NameError()
    elif response.status != 201:
        raise ValueError()

    # make a data request
    conn.request('PUT', config.store_endpoint + 'store/paste/' + data['alias'], body=code)

    # get response
    response = conn.getresponse()
    response.read()

    # note bad requests
    if response.status != 204:
        raise KeyError()

    return data['alias']
<|endoftext|>


<commit_before># Copyright 2017 The Bazel Authors. All rights reserved.
#
# 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.

load("@build_bazel_rules_typescript//internal:build_defs.bzl", "tsc_wrapped_tsconfig")

load(
    "@build_bazel_rules_typescript//internal:common/compilation.bzl",
    "COMMON_ATTRIBUTES", "compile_ts", "ts_providers_dict_to_struct"
)

load("@build_bazel_rules_typescript//internal:common/json_marshal.bzl", "json_marshal")

# Calculate the expected output of the template compiler for every source in
# in the library. Most of these will be produced as empty files but it is
# unknown, without parsing, which will be empty.
def _expected_outs(ctx):
  result = []

  for src in ctx.files.srcs:
    if src.short_path.endswith(".ts"):
      basename = src.short_path[len(ctx.label.package) + 1:-3]
      result += [ctx.new_file(ctx.bin_dir, basename + ext) for ext in [
        ".ngfactory.js",
        ".ngfactory.d.ts",
        ".ngsummary.js",
        ".ngsummary.d.ts",
        ".ngsummary.json",
      ]]
    elif src.short_path.endswith(".css"):
      basename = src.short_path[len(ctx.label.package) + 1:-4]
      result += [ctx.new_file(ctx.bin_dir, basename + ext) for ext in [
        ".css.shim.ngstyle.js",
        ".css.shim.ngstyle.d.ts",
        ".css.ngstyle.js",
        ".css.ngstyle.d.ts",
      ]]
  return result

def _ngc_tsconfig(ctx, files, srcs, **kwargs):
  return dict(tsc_wrapped_tsconfig(ctx, files, srcs, **kwargs), **{
      "angularCompilerOptions": {
          "expectedOut": [o.path for o in _expected_outs(ctx)],
      }
  })

def _compile_action(ctx, inputs, outputs, config_file_path):
  externs_files = []
  non_externs_files = []
  for output in outputs:
    if output.basename.endswith(".es5.MF"):
      ctx.file_action(output, content="")
    else:
      non_externs_files.append(output)

  # TODO(alexeagle): For now we mock creation of externs files
  for externs_file in externs_files:
    ctx.file_action(output=externs_file, content="")

  action_inputs = inputs
  if ctx.file.tsconfig:
    action_inputs += [ctx.file.tsconfig]

  # One at-sign makes this a params-file, enabling the worker strategy.
  # Two at-signs escapes the argument so it's passed through to ngc
  # rather than the contents getting expanded.
  if ctx.attr.supports_workers:
    arguments = ["@@" + config_file_path]
  else:
    arguments = ["-p", config_file_path]

  ctx.action(
      progress_message = "Compiling Angular templates (ngc) %s" % ctx,
      mnemonic = "AngularTemplateCompile",
      inputs = action_inputs,
      outputs = non_externs_files,
      arguments = arguments,
      executable = ctx.executable.compiler,
      execution_requirements = {
          "supports-workers": str(int(ctx.attr.supports_workers)),
      },
  )

def _devmode_compile_action(ctx, inputs, outputs, config_file_path):
  # TODO(alexeagle): compile for feeding to Closure Compiler
  _compile_action(ctx, inputs, outputs + _expected_outs(ctx), config_file_path)

def _compile_ng(ctx):
  declarations = []
  for dep in ctx.attr.deps:
    if hasattr(dep, "typescript"):
      declarations += dep.typescript.transitive_declarations

  tsconfig_json = ctx.new_file(ctx.label.name + "_tsconfig.json")
  ctx.file_action(output=tsconfig_json, content=json_marshal(
      _ngc_tsconfig(ctx, ctx.files.srcs + declarations, ctx.files.srcs)))

  _devmode_compile_action(ctx, ctx.files.srcs + declarations + [tsconfig_json], [], tsconfig_json.path)

  return {
    "files": set(_expected_outs(ctx)),
    "typescript": {
      # FIXME: expose the right outputs so this looks like a ts_library
      "declarations": [],
      "transitive_declarations": [],
      "type_blacklisted_declarations": [],
    },
  }

def _ng_module_impl(ctx):
  if ctx.attr.write_ng_outputs_only:
    ts_providers = _compile_ng(ctx)
  else:
    ts_providers = compile_ts(ctx, is_library=True,
                              compile_action=_compile_action,
                              devmode_compile_action=_devmode_compile_action,
                              tsc_wrapped_tsconfig=_ngc_tsconfig)

  addl_declarations = [o for o in _expected_outs(ctx) if o.path.endswith(".d.ts")]
  ts_providers["typescript"]["declarations"] += addl_declarations
  ts_providers["typescript"]["transitive_declarations"] += addl_declarations

  return ts_providers_dict_to_struct(ts_providers)

ng_module = rule(
    implementation = _ng_module_impl,
    attrs = dict(COMMON_ATTRIBUTES, **{
        "srcs": attr.label_list(allow_files = True),

        # To be used only to bootstrap @angular/core compilation,
        # since we want to compile @angular/core with ngc, but ngc depends on
        # @angular/core typescript output.
        "write_ng_outputs_only": attr.bool(default = False),
        "tsconfig": attr.label(allow_files = True, single_file = True),
        "no_i18n": attr.bool(default = False),
        # TODO(alexeagle): enable workers for ngc
        "supports_workers": attr.bool(default = False),
        "compiler": attr.label(
            default = Label("//internal/ngc"),
            executable = True,
            cfg = "host",
        ),
    }),
)
<commit_msg>Run compilers using an explicit dependency on node_modules, rather than finding their content in the runfiles of whatever nodejs_binary executes the compiler.<commit_after># Copyright 2017 The Bazel Authors. All rights reserved.
#
# 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.

load("@build_bazel_rules_typescript//internal:build_defs.bzl", "tsc_wrapped_tsconfig")

load(
    "@build_bazel_rules_typescript//internal:common/compilation.bzl",
    "COMMON_ATTRIBUTES", "compile_ts", "ts_providers_dict_to_struct"
)

load("@build_bazel_rules_typescript//internal:common/json_marshal.bzl", "json_marshal")

# Calculate the expected output of the template compiler for every source in
# in the library. Most of these will be produced as empty files but it is
# unknown, without parsing, which will be empty.
def _expected_outs(ctx):
  result = []

  for src in ctx.files.srcs:
    if src.short_path.endswith(".ts"):
      basename = src.short_path[len(ctx.label.package) + 1:-3]
      result += [ctx.new_file(ctx.bin_dir, basename + ext) for ext in [
        ".ngfactory.js",
        ".ngfactory.d.ts",
        ".ngsummary.js",
        ".ngsummary.d.ts",
        ".ngsummary.json",
      ]]
    elif src.short_path.endswith(".css"):
      basename = src.short_path[len(ctx.label.package) + 1:-4]
      result += [ctx.new_file(ctx.bin_dir, basename + ext) for ext in [
        ".css.shim.ngstyle.js",
        ".css.shim.ngstyle.d.ts",
        ".css.ngstyle.js",
        ".css.ngstyle.d.ts",
      ]]
  return result

def _ngc_tsconfig(ctx, files, srcs, **kwargs):
  return dict(tsc_wrapped_tsconfig(ctx, files, srcs, **kwargs), **{
      "angularCompilerOptions": {
          "expectedOut": [o.path for o in _expected_outs(ctx)],
      }
  })

def _compile_action(ctx, inputs, outputs, config_file_path):
  externs_files = []
  non_externs_files = []
  for output in outputs:
    if output.basename.endswith(".es5.MF"):
      ctx.file_action(output, content="")
    else:
      non_externs_files.append(output)

  # TODO(alexeagle): For now we mock creation of externs files
  for externs_file in externs_files:
    ctx.file_action(output=externs_file, content="")

  action_inputs = inputs
  if hasattr(ctx.attr, "node_modules"):
    action_inputs += [f for f in ctx.files.node_modules
                      if f.path.endswith(".ts") or f.path.endswith(".json")]
  if ctx.file.tsconfig:
    action_inputs += [ctx.file.tsconfig]

  # One at-sign makes this a params-file, enabling the worker strategy.
  # Two at-signs escapes the argument so it's passed through to ngc
  # rather than the contents getting expanded.
  if ctx.attr.supports_workers:
    arguments = ["@@" + config_file_path]
  else:
    arguments = ["-p", config_file_path]

  ctx.action(
      progress_message = "Compiling Angular templates (ngc) %s" % ctx,
      mnemonic = "AngularTemplateCompile",
      inputs = action_inputs,
      outputs = non_externs_files,
      arguments = arguments,
      executable = ctx.executable.compiler,
      execution_requirements = {
          "supports-workers": str(int(ctx.attr.supports_workers)),
      },
  )

def _devmode_compile_action(ctx, inputs, outputs, config_file_path):
  # TODO(alexeagle): compile for feeding to Closure Compiler
  _compile_action(ctx, inputs, outputs + _expected_outs(ctx), config_file_path)

def _compile_ng(ctx):
  declarations = []
  for dep in ctx.attr.deps:
    if hasattr(dep, "typescript"):
      declarations += dep.typescript.transitive_declarations

  tsconfig_json = ctx.new_file(ctx.label.name + "_tsconfig.json")
  ctx.file_action(output=tsconfig_json, content=json_marshal(
      _ngc_tsconfig(ctx, ctx.files.srcs + declarations, ctx.files.srcs)))

  _devmode_compile_action(ctx, ctx.files.srcs + declarations + [tsconfig_json], [], tsconfig_json.path)

  return {
    "files": set(_expected_outs(ctx)),
    "typescript": {
      # FIXME: expose the right outputs so this looks like a ts_library
      "declarations": [],
      "transitive_declarations": [],
      "type_blacklisted_declarations": [],
    },
  }

def _ng_module_impl(ctx):
  if ctx.attr.write_ng_outputs_only:
    ts_providers = _compile_ng(ctx)
  else:
    ts_providers = compile_ts(ctx, is_library=True,
                              compile_action=_compile_action,
                              devmode_compile_action=_devmode_compile_action,
                              tsc_wrapped_tsconfig=_ngc_tsconfig)

  addl_declarations = [o for o in _expected_outs(ctx) if o.path.endswith(".d.ts")]
  ts_providers["typescript"]["declarations"] += addl_declarations
  ts_providers["typescript"]["transitive_declarations"] += addl_declarations

  return ts_providers_dict_to_struct(ts_providers)

ng_module = rule(
    implementation = _ng_module_impl,
    attrs = dict(COMMON_ATTRIBUTES, **{
        "srcs": attr.label_list(allow_files = True),

        # To be used only to bootstrap @angular/core compilation,
        # since we want to compile @angular/core with ngc, but ngc depends on
        # @angular/core typescript output.
        "write_ng_outputs_only": attr.bool(default = False),
        "tsconfig": attr.label(allow_files = True, single_file = True),
        "no_i18n": attr.bool(default = False),
        # TODO(alexeagle): enable workers for ngc
        "supports_workers": attr.bool(default = False),
        "compiler": attr.label(
            default = Label("//internal/ngc"),
            executable = True,
            cfg = "host",
        ),
        # @// is special syntax for the "main" repository
        # The default assumes the user specified a target "node_modules" in their
        # root BUILD file.
        "node_modules": attr.label(
            default = Label("@//:node_modules")
        ),
    }),
)
<|endoftext|>


<commit_before>"""
This module cleans up conda CRAN skeletons to make it compliant with
conda-forge requirements.
"""

import subprocess as sp
import os
import logging
import re
from itertools import zip_longest
import argparse
from conda_build.api import skeletonize
from .utils import run, setup_logger

logger = setup_logger(__name__, 'debug')

# Some dependencies are listed in CRAN that are actually in Bioconductor. Use
# this dict to map these to bioconductor package names.
INVALID_NAME_MAP = {
    'r-edger': 'bioconductor-edger',
}

# Raw strings needed to support the awkward backslashes needed when adding the
# command to yaml
gpl2_short = r"  license_family: GPL2"
gpl2_long = (
    "  license_family: GPL2\n  license_file: '{{ environ[\"PREFIX\"] }}"
    "\/lib\/R\/share\/licenses\/GPL-2'  # [unix]\n  "
    "license_file: '{{ environ[\"PREFIX\"] }}"
    "\\\R\\\share\\\licenses\\\GPL-2'  # [win]"
)

gpl3_short = r"  license_family: GPL3"
gpl3_long = (
    "  license_family: GPL3\n  license_file: '{{ environ[\"PREFIX\"] }}"
    "\/lib\/R\/share\/licenses\/GPL-3'  # [unix]\n  "
    "license_file: '{{ environ[\"PREFIX\"] }}"
    "\\\R\\\share\\\licenses\\\GPL-3'  # [win]"
)
win32_string = 'number: 0\n  skip: true  # [win32]'

def write_recipe(package, recipe_dir='.', no_windows=True, config=None, force=False, bioc_version=None,
                 pkg_version=None, versioned=False, recursive=False, seen_dependencies=[]):
        """
        Call out to to `conda skeleton cran`.

        Kwargs are accepted for uniformity with
        `bioconductor_skeleton.write_recipe`; the only one handled here is
        `recursive`.

        Parameters
        ----------

        package : str
            Package name. Can be case-sensitive CRAN name, or sanitized
            "r-pkgname" conda package name.

        recipe_dir : str
            Recipe will be created as a subdirectory in `recipe_dir`

        recursive : bool
            Add the `--recursive` argument to `conda skeleton cran` to
            recursively build CRAN recipes.

        force : bool
            If True, then remove the directory `<recipe_dir>/<pkgname>`, where
            `<pkgname>` the sanitized conda version of the package name,
            regardless of which format was provided as `package`.
        """
        if recursive:
            sp.call(['conda skeleton cran ' + package + ' --output-dir ' + recipe_dir + " --recursive"], shell=True)
        else:
            sp.call(['conda skeleton cran ' + package + ' --output-dir ' + recipe_dir], shell=True)

def clean_skeleton_files(package, no_windows=True):
    """
    Cleans output files created by `conda skeleton cran` to make them
    conda-forge compatible.

    Parameters
    ----------
    package : str
        Package name. Can be case-sensitive CRAN name, or sanitized
        "r-pkgname" conda package name.

    no_windows : bool
        If True, no bld.bat will be created and no `[win]` preprocess selectors
        will be added to the yaml
    """
    clean_yaml_file(package, no_windows)
    clean_build_file(package, no_windows)
    clean_bld_file(package, no_windows)

def clean_yaml_file(package, no_windows):
    """
    Cleans the YAML file output by `conda skeleton cran` to make it conda-forge
    compatible.

    Parameters
    ----------
    package : str
        Must be sanitized "r-pkgname" package name.

    no_windows : bool
        If True, then adds a "build: skip: True # [win32]" line to skip Windows
        builds.
    """
    path = os.path.join(package, 'meta.yaml')
    with open(path, 'r') as yaml:
        lines = list(yaml.readlines())

        # Remove lines consisting only of comments
        lines = filter_lines_regex(lines, r'^\s*#.*$', '')
        lines = remove_empty_lines(lines)

        # Remove file license
        lines = filter_lines_regex(lines, r' [+|] file LICEN[SC]E', '')

        # Replace GPL2 or GPL3 string created by conda skeleton cran with long
        # format
        lines = filter_lines_regex(lines, gpl2_short, gpl2_long)
        lines = filter_lines_regex(lines, gpl3_short, gpl3_long)

        if no_windows:
            # Inserts `skip: true # [win32]` after `number: 0` to skip windows
            # builds
            lines = filter_lines_regex(lines, r'number: 0', win32_string)

        # Add contents of maintainers file to the end of the recipe
        add_maintainers(lines)

    with open(path, 'w') as yaml:
        out = "".join(lines)
        out = out.replace('{indent}', '\n    - ')

        # Edit INVALID_NAME_MAP if additional fixes needed
        for wrong, correct in INVALID_NAME_MAP.items():
            out = out.replace(wrong, correct)
        yaml.write(out)

def clean_build_file(package, no_windows=False):
    """
    Cleans build.sh file created by `conda skeleton cran` to be compatible with
    conda-forge.

    Parameters
    ----------
    package : str
        Must be sanitized "r-pkgname" package name.

    no_windows : bool
        Included for consistency with other `clean_*` functions; does not have
        any effect for this function.
    """

    path = os.path.join(package, 'build.sh')
    with open(path, 'r') as build:
        lines = list(build.readlines())

        # Remove lines with mv commands
        lines = filter_lines_regex(lines, r'^mv\s.*$', '')

        # Remove lines with grep commands
        lines = filter_lines_regex(lines, r'^grep\s.*$', '')

        # Removes the lines consisting of only comments
        lines = filter_lines_regex(lines, r'^\s*#.*$', '')

        lines = remove_empty_lines(lines)

    with open(path, 'w') as build:
        build.write("".join(lines))

def clean_bld_file(package, no_windows):
    """
    Cleans bld.bat file created by `conda skeleton cran` to be compatible with
    conda-forge.

    Parameters
    ----------
    package : str
        Must be sanitized "r-pkgname" package name.

    no_windows : bool
        Included for consistency with other `clean_*` functions; does not have
        any effect for this function.
    """
    path = os.path.join(package, 'bld.bat')
    if not os.path.exists(path):
        return
    with open(path, 'r') as bld:
        lines = list(bld.readlines())

        # Removes the lines that start with @
        lines = filter_lines_regex(lines, r'^@.*$', '')
        lines = remove_empty_lines(lines)

    with open(path, 'w') as bld:
        bld.write("".join(lines))

def filter_lines_regex(lines, regex, substitute):
    """
    Substitutes `substitute` for every match to `regex` in each line of
    `lines`.

    Parameters
    ----------

    lines : iterable of strings

    regex, substitute : str
    """
    return [re.sub(regex, substitute, line) for line in lines]

def remove_empty_lines(lines):
    """
    Removes consecutive empty lines in `lines`.

    Parameters
    ----------

    lines: iterable of strings
    """
    cleaned_lines = []
    for line, next_line in zip_longest(lines, lines[1:]):
        if (
            (line.isspace() and next_line is None) or
            (line.isspace() and next_line.isspace())
        ):
            pass
        else:
            cleaned_lines.append(line)

    if cleaned_lines[0].isspace():
        cleaned_lines = cleaned_lines[1:]
    return cleaned_lines

def add_maintainers(lines):
    """
    Append the contents of "maintainers.yaml" to the end of a YAML file.
    """
    HERE = os.path.abspath(os.path.dirname(__file__))
    maintainers_yaml = os.path.join(HERE, 'maintainers.yaml')
    with open(maintainers_yaml, 'r') as yaml:
        extra_lines = list(yaml.readlines())
        lines.extend(extra_lines)

def main():
    """ Adding support for arguments here """
    parser = argparse.ArgumentParser()
    parser.add_argument('package', help='name of the cran package')
    parser.add_argument('output_dir', help='output directory for the recipe')
    parser.add_argument('--no-win', default=False, action="store_true",
                        help='runs the skeleton and removes windows specific information')

    args = parser.parse_args()
    write_recipe(args.package, args.output_dir, no_windows=args.no_win)

if __name__ == '__main__':
    main()
<commit_msg>add force arg to cran_skeleton.write_recipe; cleanup other kwargs<commit_after>"""
This module cleans up conda CRAN skeletons to make it compliant with
conda-forge requirements.
"""

import subprocess as sp
import os
import logging
import re
from itertools import zip_longest
import argparse
from conda_build.api import skeletonize
from .utils import run, setup_logger

logger = setup_logger(__name__, 'debug')

# Some dependencies are listed in CRAN that are actually in Bioconductor. Use
# this dict to map these to bioconductor package names.
INVALID_NAME_MAP = {
    'r-edger': 'bioconductor-edger',
}

# Raw strings needed to support the awkward backslashes needed when adding the
# command to yaml
gpl2_short = r"  license_family: GPL2"
gpl2_long = (
    "  license_family: GPL2\n  license_file: '{{ environ[\"PREFIX\"] }}"
    "\/lib\/R\/share\/licenses\/GPL-2'  # [unix]\n  "
    "license_file: '{{ environ[\"PREFIX\"] }}"
    "\\\R\\\share\\\licenses\\\GPL-2'  # [win]"
)

gpl3_short = r"  license_family: GPL3"
gpl3_long = (
    "  license_family: GPL3\n  license_file: '{{ environ[\"PREFIX\"] }}"
    "\/lib\/R\/share\/licenses\/GPL-3'  # [unix]\n  "
    "license_file: '{{ environ[\"PREFIX\"] }}"
    "\\\R\\\share\\\licenses\\\GPL-3'  # [win]"
)
win32_string = 'number: 0\n  skip: true  # [win32]'

def write_recipe(package, recipe_dir='.', recursive=False, force=False,
                 **kwargs):
        """
        Call out to to `conda skeleton cran`.

        Kwargs are accepted for uniformity with
        `bioconductor_skeleton.write_recipe`; the only one handled here is
        `recursive`.

        Parameters
        ----------

        package : str
            Package name. Can be case-sensitive CRAN name, or sanitized
            "r-pkgname" conda package name.

        recipe_dir : str
            Recipe will be created as a subdirectory in `recipe_dir`

        recursive : bool
            Add the `--recursive` argument to `conda skeleton cran` to
            recursively build CRAN recipes.

        force : bool
            If True, then remove the directory `<recipe_dir>/<pkgname>`, where
            `<pkgname>` the sanitized conda version of the package name,
            regardless of which format was provided as `package`.
        """
        logger.debug('Building skeleton for %s', package)
        conda_version = package.startswith('r-')
        if not conda_version:
            outdir = os.path.join(
                recipe_dir, 'r-' + package.lower())
        else:
            outdir = os.path.join(
                recipe_dir, package)
        if os.path.exists(outdir):
            if force:
                logger.warning('Removing %s', outdir)
                run(['rm', '-r', outdir])
            else:
                logger.warning('%s exists, skipping', outdir)
                return

        try:
            skeletonize(package, repo='cran', output_dir=recipe_dir, version=None, recursive=recursive)
        except NotImplementedError as e:
            logger.error('%s had dependencies that specified versions: skipping.', package)

def clean_skeleton_files(package, no_windows=True):
    """
    Cleans output files created by `conda skeleton cran` to make them
    conda-forge compatible.

    Parameters
    ----------
    package : str
        Package name. Can be case-sensitive CRAN name, or sanitized
        "r-pkgname" conda package name.

    no_windows : bool
        If True, no bld.bat will be created and no `[win]` preprocess selectors
        will be added to the yaml
    """
    clean_yaml_file(package, no_windows)
    clean_build_file(package, no_windows)
    clean_bld_file(package, no_windows)

def clean_yaml_file(package, no_windows):
    """
    Cleans the YAML file output by `conda skeleton cran` to make it conda-forge
    compatible.

    Parameters
    ----------
    package : str
        Must be sanitized "r-pkgname" package name.

    no_windows : bool
        If True, then adds a "build: skip: True # [win32]" line to skip Windows
        builds.
    """
    path = os.path.join(package, 'meta.yaml')
    with open(path, 'r') as yaml:
        lines = list(yaml.readlines())

        # Remove lines consisting only of comments
        lines = filter_lines_regex(lines, r'^\s*#.*$', '')
        lines = remove_empty_lines(lines)

        # Remove file license
        lines = filter_lines_regex(lines, r' [+|] file LICEN[SC]E', '')

        # Replace GPL2 or GPL3 string created by conda skeleton cran with long
        # format
        lines = filter_lines_regex(lines, gpl2_short, gpl2_long)
        lines = filter_lines_regex(lines, gpl3_short, gpl3_long)

        if no_windows:
            # Inserts `skip: true # [win32]` after `number: 0` to skip windows
            # builds
            lines = filter_lines_regex(lines, r'number: 0', win32_string)

        # Add contents of maintainers file to the end of the recipe
        add_maintainers(lines)

    with open(path, 'w') as yaml:
        out = "".join(lines)
        out = out.replace('{indent}', '\n    - ')

        # Edit INVALID_NAME_MAP if additional fixes needed
        for wrong, correct in INVALID_NAME_MAP.items():
            out = out.replace(wrong, correct)
        yaml.write(out)

def clean_build_file(package, no_windows=False):
    """
    Cleans build.sh file created by `conda skeleton cran` to be compatible with
    conda-forge.

    Parameters
    ----------
    package : str
        Must be sanitized "r-pkgname" package name.

    no_windows : bool
        Included for consistency with other `clean_*` functions; does not have
        any effect for this function.
    """

    path = os.path.join(package, 'build.sh')
    with open(path, 'r') as build:
        lines = list(build.readlines())

        # Remove lines with mv commands
        lines = filter_lines_regex(lines, r'^mv\s.*$', '')

        # Remove lines with grep commands
        lines = filter_lines_regex(lines, r'^grep\s.*$', '')

        # Removes the lines consisting of only comments
        lines = filter_lines_regex(lines, r'^\s*#.*$', '')

        lines = remove_empty_lines(lines)

    with open(path, 'w') as build:
        build.write("".join(lines))

def clean_bld_file(package, no_windows):
    """
    Cleans bld.bat file created by `conda skeleton cran` to be compatible with
    conda-forge.

    Parameters
    ----------
    package : str
        Must be sanitized "r-pkgname" package name.

    no_windows : bool
        Included for consistency with other `clean_*` functions; does not have
        any effect for this function.
    """
    path = os.path.join(package, 'bld.bat')
    if not os.path.exists(path):
        return
    with open(path, 'r') as bld:
        lines = list(bld.readlines())

        # Removes the lines that start with @
        lines = filter_lines_regex(lines, r'^@.*$', '')
        lines = remove_empty_lines(lines)

    with open(path, 'w') as bld:
        bld.write("".join(lines))

def filter_lines_regex(lines, regex, substitute):
    """
    Substitutes `substitute` for every match to `regex` in each line of
    `lines`.

    Parameters
    ----------

    lines : iterable of strings

    regex, substitute : str
    """
    return [re.sub(regex, substitute, line) for line in lines]

def remove_empty_lines(lines):
    """
    Removes consecutive empty lines in `lines`.

    Parameters
    ----------

    lines: iterable of strings
    """
    cleaned_lines = []
    for line, next_line in zip_longest(lines, lines[1:]):
        if (
            (line.isspace() and next_line is None) or
            (line.isspace() and next_line.isspace())
        ):
            pass
        else:
            cleaned_lines.append(line)

    if cleaned_lines[0].isspace():
        cleaned_lines = cleaned_lines[1:]
    return cleaned_lines

def add_maintainers(lines):
    """
    Append the contents of "maintainers.yaml" to the end of a YAML file.
    """
    HERE = os.path.abspath(os.path.dirname(__file__))
    maintainers_yaml = os.path.join(HERE, 'maintainers.yaml')
    with open(maintainers_yaml, 'r') as yaml:
        extra_lines = list(yaml.readlines())
        lines.extend(extra_lines)

def main():
    """ Adding support for arguments here """
    parser = argparse.ArgumentParser()
    parser.add_argument('package', help='name of the cran package')
    parser.add_argument('output_dir', help='output directory for the recipe')
    parser.add_argument('--no-win', action="store_true",
                        help='runs the skeleton and removes windows specific information')
    parser.add_argument('--force', action='store_true',
                        help='If a directory exists for any recipe, overwrite it')

    args = parser.parse_args()
    write_recipe(args.package, args.output_dir, no_windows=args.no_win,
                 force=args.force)

if __name__ == '__main__':
    main()
<|endoftext|>


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

"""SchoolCMS-handler-init.

route.
"""

from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals

import functools
import os

import tornado.web
from tornado.escape import json_encode

from schoolcms.db import Session, User, GroupList
from webassets import Environment, Bundle
from schoolcms.util  import webassets_react

class BaseHandler(tornado.web.RequestHandler):
    def initialize(self):
        self.assets = Environment(
                os.path.join(os.path.dirname(__file__), '../static'),'/static')
        jsx = Bundle('schoolcms/init.jsx','schoolcms/import/*.jsx',filters=('react','jsmin'),output='js/jsx.js')
        all_js = Bundle(
                'js/jquery-2.1.3.min.js',
                'bootstrap-3.3.4-dist/js/bootstrap.min.js',
                'react-0.13.2/react-with-addons.js',
                'react-0.13.2/JSXTransformer.js',
                'js/react-bootstrap.min.js',
                'js/react-mini-router.min.js',
                'js/marked.min.js',
                'bootstrap-material/js/material.min.js',
                output='js/plugin.js')
        self.assets.register('js_all', all_js)
        self.assets.register('jsx', jsx)

    def prepare(self):
        """This method is executed at the beginning of each request.

        """
        self.sql_session = Session()

    def on_finish(self):
        """Finish this response, ending the HTTP request
        and properly close the database.
        """
        self.sql_session.close()

    def get_current_user(self):
        """Gets the current user logged in from the cookies
        If a valid cookie is retrieved, return a User object.
        Otherwise, return None.
        """
        uid = self.get_secure_cookie('uid')
        if not uid:
            return None
        return User.by_key(uid, self.sql_session).scalar()

    def get_template_namespace(self):
        _ = super(BaseHandler, self).get_template_namespace()
        _['xsrf'] = self.xsrf_token
        _['js_urls'] = self.assets['js_all'].urls()
        _['jsx_urls'] = self.assets['jsx'].urls()
        return _

    @property
    def HTTPError(self):
        return tornado.web.HTTPError

    def write_error(self, error, **kargs):
        self.write('
Geez! %d!
' % error)

    @staticmethod
    def authenticated(method):
        return tornado.web.authenticated(method)

    @staticmethod
    def check_is_admin_user(method):
        def wrapper(self, *args, **kwargs):
            if not self.current_user or not self.current_user.admin:
                raise self.HTTPError(403)
            return method(self, *args, **kwargs)
        return wrapper

    @staticmethod
    def check_is_group_user(group_id):
        def decorator(method):
            def wrapper(self, *args, **kwargs):
                if not self.is_group_user(group_id):
                    raise self.HTTPError(403)
                return method(self, *args, **kwargs)
            return wrapper
        return decorator

    def is_group_user(self, group_id):
        if not self.current_user:
            return False
        if self.current_user.admin:
            return True
        group = GroupList.check(self.current_user.key,
                                group_id, self.sql_session)
        return bool(group)

class AppHandler(BaseHandler):
    def get(self,  *a, **kwargs):
        self.render('app.html')

from .indexhandler import IndexHandler
from .announcehandler import AnnounceHandler, EditAnnHandler
from .userhandler import LoginHandler, LogoutHandler, AddUserHandler
from .defaulthandler import DefaultHandler
from .filehandler import FileHandler, TempUploadHandler
from .grouphandler import GroupHandler, UserListHandler
from .recordhandler import RecordHandler

print(os.path.join(os.path.dirname(__file__), '../../file'))

route = [
    (r'/', AppHandler),
    (r'/login/?', AppHandler),
    (r'/logout/?', AppHandler),
    (r'/admin/adduser/?', AddUserHandler),
    (r'/announce(?:/([0-9]+))?/?', AppHandler),
    (r'/announce/edit(?:/([0-9]+))?/?', AppHandler),
    (r'/file/(.*)', FileHandler, {"path": os.path.join(os.path.dirname(__file__), '../../file')}),
    (r'/fileupload(?:/([a-zA-Z0-9]+))?/?', TempUploadHandler),
    (r'/group/?', GroupHandler),
    (r'/userlist/?', UserListHandler),
    # API
    (r'/api/?', IndexHandler),
    (r'/api/login/?', LoginHandler),
    (r'/api/logout/?', LogoutHandler),
    (r'/api/announce(?:/([0-9]+))?/?', AnnounceHandler),
    (r'/api/announce/edit(?:/([0-9]+))?/?', EditAnnHandler),
    (r'/api/record/?', RecordHandler),
]
<commit_msg>change api path<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""SchoolCMS-handler-init.

route.
"""

from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals

import functools
import os

import tornado.web
from tornado.escape import json_encode

from schoolcms.db import Session, User, GroupList
from webassets import Environment, Bundle
from schoolcms.util  import webassets_react

class BaseHandler(tornado.web.RequestHandler):
    def initialize(self):
        self.assets = Environment(
                os.path.join(os.path.dirname(__file__), '../static'),'/static')
        jsx = Bundle('schoolcms/init.jsx','schoolcms/import/*.jsx',filters=('react','jsmin'),output='js/jsx.js')
        all_js = Bundle(
                'js/jquery-2.1.3.min.js',
                'bootstrap-3.3.4-dist/js/bootstrap.min.js',
                'react-0.13.2/react-with-addons.js',
                'react-0.13.2/JSXTransformer.js',
                'js/react-bootstrap.min.js',
                'js/react-mini-router.min.js',
                'js/marked.min.js',
                'bootstrap-material/js/material.min.js',
                output='js/plugin.js')
        self.assets.register('js_all', all_js)
        self.assets.register('jsx', jsx)

    def prepare(self):
        """This method is executed at the beginning of each request.

        """
        self.sql_session = Session()

    def on_finish(self):
        """Finish this response, ending the HTTP request
        and properly close the database.
        """
        self.sql_session.close()

    def get_current_user(self):
        """Gets the current user logged in from the cookies
        If a valid cookie is retrieved, return a User object.
        Otherwise, return None.
        """
        uid = self.get_secure_cookie('uid')
        if not uid:
            return None
        return User.by_key(uid, self.sql_session).scalar()

    def get_template_namespace(self):
        _ = super(BaseHandler, self).get_template_namespace()
        _['xsrf'] = self.xsrf_token
        _['js_urls'] = self.assets['js_all'].urls()
        _['jsx_urls'] = self.assets['jsx'].urls()
        return _

    @property
    def HTTPError(self):
        return tornado.web.HTTPError

    def write_error(self, error, **kargs):
        self.write('
Geez! %d!
' % error)

    @staticmethod
    def authenticated(method):
        return tornado.web.authenticated(method)

    @staticmethod
    def check_is_admin_user(method):
        def wrapper(self, *args, **kwargs):
            if not self.current_user or not self.current_user.admin:
                raise self.HTTPError(403)
            return method(self, *args, **kwargs)
        return wrapper

    @staticmethod
    def check_is_group_user(group_id):
        def decorator(method):
            def wrapper(self, *args, **kwargs):
                if not self.is_group_user(group_id):
                    raise self.HTTPError(403)
                return method(self, *args, **kwargs)
            return wrapper
        return decorator

    def is_group_user(self, group_id):
        if not self.current_user:
            return False
        if self.current_user.admin:
            return True
        group = GroupList.check(self.current_user.key,
                                group_id, self.sql_session)
        return bool(group)

class AppHandler(BaseHandler):
    def get(self,  *a, **kwargs):
        self.render('app.html')

from .indexhandler import IndexHandler
from .announcehandler import AnnounceHandler, EditAnnHandler
from .userhandler import LoginHandler, LogoutHandler, AddUserHandler
from .defaulthandler import DefaultHandler
from .filehandler import FileHandler, TempUploadHandler
from .grouphandler import GroupHandler, UserListHandler
from .recordhandler import RecordHandler

print(os.path.join(os.path.dirname(__file__), '../../file'))

route = [
    (r'/', AppHandler),
    (r'/login/?', AppHandler),
    (r'/logout/?', AppHandler),
    (r'/admin/adduser/?', AddUserHandler),
    (r'/announce(?:/([0-9]+))?/?', AppHandler),
    (r'/announce/edit(?:/([0-9]+))?/?', AppHandler),
    (r'/file/(.*)', FileHandler, {"path": os.path.join(os.path.dirname(__file__), '../../file')}),
    (r'/fileupload(?:/([a-zA-Z0-9]+))?/?', TempUploadHandler),
    (r'/group/?', GroupHandler),
    (r'/userlist/?', UserListHandler),
    # API
    (r'/api/?', IndexHandler),
    (r'/api/login/?', LoginHandler),
    (r'/api/logout/?', LogoutHandler),
    (r'/api/announce(?:/([0-9]+))?/?', AnnounceHandler),
    (r'/api/announce/edit(?:/([0-9]+))?/?', EditAnnHandler),
    (r'/api/announce/record/?', RecordHandler),
]
<|endoftext|>