<commit_before>from UM.Signal import Signal, SignalEmitter
from . import PrinterConnection
from UM.Application import Application
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Scene.SceneNode import SceneNode
from UM.Resources import Resources
import threading
import platform
import glob
import time
import os
import sys
from UM.Extension import Extension

from PyQt5.QtQuick import QQuickView
from PyQt5.QtCore import QUrl, QObject,pyqtSlot , pyqtProperty,pyqtSignal

from UM.i18n import i18nCatalog

i18n_catalog = i18nCatalog('plugins')

class USBPrinterManager(QObject, SignalEmitter, Extension):
    def __init__(self, parent = None):
        super().__init__(parent)
        self._serial_port_list = []
        self._printer_connections = []
        self._check_ports_thread = threading.Thread(target=self._updateConnectionList)
        self._check_ports_thread.daemon = True
        self._check_ports_thread.start()

        self._progress = 0

        self.view = None
        self._extruder_temp = 0
        self._bed_temp = 0
        self._error_message = ""

        self.addMenuItem(i18n_catalog.i18n("Update firmware"), self.updateAllFirmware)

        #time.sleep(1)
        #self.connectAllConnections()
        #time.sleep(5)
        #f = open("Orb.gcode")
        #lines = f.readlines()
        #print(len(lines))
        #print(len(self._printer_connections))
        #self.sendGCodeToAllActive(lines)
        #print("sending heat " , self.sendCommandToAllActive("M104 S190"))

    def spawnInterface(self,serial_port):
        if self.view is None:
            self.view = QQuickView()
            self.view.engine().rootContext().setContextProperty('manager',self)
            self.view.setSource(QUrl("plugins/USBPrinting/ControlWindow.qml"))
            self.view.show()

    processingProgress = pyqtSignal(float, arguments = ['amount'])
    @pyqtProperty(float,notify = processingProgress)
    def progress(self):
        return self._progress

    pyqtExtruderTemperature = pyqtSignal(float, arguments = ['amount'])
    @pyqtProperty(float,notify = pyqtExtruderTemperature)
    def extruderTemperature(self):
        return self._extruder_temp

    pyqtBedTemperature = pyqtSignal(float, arguments = ['amount'])
    @pyqtProperty(float,notify = pyqtBedTemperature)
    def bedTemperature(self):
        return self._bed_temp

    pyqtError = pyqtSignal(str, arguments = ['amount'])
    @pyqtProperty(str,notify = pyqtError)
    def error(self):
        return self._error_message

    ##  Check all serial ports and create a PrinterConnection object for them.
    #   Note that this does not validate if the serial ports are actually usable!
    #   This (the validation) is only done when the connect function is called.
    def _updateConnectionList(self):
        while True:
            temp_serial_port_list = self.getSerialPortList(only_list_usb = True)
            if temp_serial_port_list != self._serial_port_list: # Something changed about the list since we last changed something.
                disconnected_ports = [port for port in self._serial_port_list if port not in temp_serial_port_list ]
                self._serial_port_list = temp_serial_port_list
                for serial_port in self._serial_port_list:
                    if self.getConnectionByPort(serial_port) is None: #If it doesn't already exist, add it
                        if not os.path.islink(serial_port): #Only add the connection if it's a non symbolic link
                            connection = PrinterConnection.PrinterConnection(serial_port)
                            connection.connect()
                            connection.connectionStateChanged.connect(self.serialConectionStateCallback)
                            connection.progressChanged.connect(self.onProgress)
                            connection.onExtruderTemperatureChange.connect(self.onExtruderTemperature)
                            connection.onBedTemperatureChange.connect(self.onBedTemperature)
                            connection.onError.connect(self.onError)
                            self._printer_connections.append(connection)

                for serial_port in disconnected_ports: # Close connections and remove them from list.
                    connection = self.getConnectionByPort(serial_port)
                    if connection != None:
                        self._printer_connections.remove(connection)
                        connection.close()
            time.sleep(5) #Throttle, as we don't need this information to be updated every single second.

    def onExtruderTemperature(self, serial_port, index,temperature):
        #print("ExtruderTemperature " , serial_port, " " , index, " " , temperature)
        self._extruder_temp = temperature
        self.pyqtExtruderTemperature.emit(temperature)

        pass

    def updateAllFirmware(self):
        for printer_connection in self._printer_connections:
            printer_connection.updateFirmware(Resources.getPath(Resources.FirmwareLocation, self._getDefaultFirmwareName()))

    def updateFirmwareBySerial(self, serial_port):
        printer_connection = self.getConnectionByPort(serial_port)
        if printer_connection is not None:
            printer_connection.updateFirmware(Resources.getPath(Resources.FirmwareLocation, self._getDefaultFirmwareName()))

    def _getDefaultFirmwareName(self):
        machine_type = Application.getInstance().getActiveMachine().getTypeID()
        firmware_name = ""
        baudrate = 250000
        if sys.platform.startswith('linux'):
                baudrate = 115200
        if machine_type == "ultimaker_original":
            firmware_name = 'MarlinUltimaker'
            firmware_name += '-%d' % (baudrate)
        elif machine_type == "ultimaker_original_plus":
            firmware_name = 'MarlinUltimaker-UMOP-%d' % (baudrate)
        elif machine_type == "Witbox":
            return "MarlinWitbox.hex"
        elif machine_type == "ultimaker2go":
            return "MarlinUltimaker2go.hex"
        elif machine_type == "ultimaker2extended":
            return "MarlinUltimaker2extended.hex"
        elif machine_type == "ultimaker2":
            return "MarlinUltimaker2.hex"

        ##TODO: Add check for multiple extruders

        if firmware_name != "":
            firmware_name += ".hex"
        return firmware_name

    def onBedTemperature(self, serial_port,temperature):
        self._bed_temperature = temperature
        self.pyqtBedTemperature.emit(temperature)
        #print("bedTemperature " , serial_port, " "  , temperature)
        pass

    def onError(self, error):
        self._error_message = error
        self.pyqtError.emit(error)
        pass

    def onProgress(self, progress, serial_port):
        self._progress = progress
        self.processingProgress.emit(progress)
        pass

    ##  Attempt to connect with all possible connections.
    def connectAllConnections(self):
        for connection in self._printer_connections:
            connection.connect()

    ##  send gcode to printer and start printing
    def sendGCodeByPort(self, serial_port, gcode_list):
        printer_connection = self.getConnectionByPort(serial_port)
        if printer_connection is not None:
            printer_connection.printGCode(gcode_list)
            return True
        return False

    @pyqtSlot()
    def cancelPrint(self):
        for printer_connection in self.getActiveConnections():
            printer_connection.cancelPrint()

    ##  Send gcode to all active printers.
    #   \return True if there was at least one active connection.
    def sendGCodeToAllActive(self, gcode_list):
        for printer_connection in self.getActiveConnections():
            printer_connection.printGCode(gcode_list)
        if len(self.getActiveConnections()):
            return True
        else:
            return False

    ##  Send a command to a printer indentified by port
    #   \param serial port String indentifieing the port
    #   \param command String with the g-code command to send.
    #   \return True if connection was found, false otherwise
    def sendCommandByPort(self, serial_port, command):
        printer_connection = self.getConnectionByPort(serial_port)
        if printer_connection is not None:
            printer_connection.sendCommand(command)
            return True
        return False

    ##  Send a command to all active (eg; connected) printers
    #   \param command String with the g-code command to send.
    #   \return True if at least one connection was found, false otherwise
    def sendCommandToAllActive(self, command):
        for printer_connection in self.getActiveConnections():
            printer_connection.sendCommand(command)
        if len(self.getActiveConnections()):
            return True
        else:
            return False

    def serialConectionStateCallback(self,serial_port):
        connection = self.getConnectionByPort(serial_port)
        if connection.isConnected():
            Application.getInstance().addOutputDevice(serial_port, {
                'id': serial_port,
                'function': self.spawnInterface,
                'description': 'Write to USB {0}'.format(serial_port),
                'icon': 'print_usb',
                'priority': 1
            })
        else:
            Application.getInstance().removeOutputDevice(serial_port)

    '''def _writeToSerial(self, serial_port):
        gcode_list = getattr(Application.getInstance().getController().getScene(), 'gcode_list', None)
        if gcode_list:
            final_list = []
            for gcode in gcode_list:
                final_list += gcode.split('\n')
            self.sendGCodeByPort(serial_port, gcode_list)'''
    @pyqtSlot()
    def startPrint(self):
        gcode_list = getattr(Application.getInstance().getController().getScene(), 'gcode_list', None)
        if gcode_list:
            final_list = []
            for gcode in gcode_list:
                final_list += gcode.split('\n')
            self.sendGCodeToAllActive(gcode_list)

    ## Get a list of printer connection objects that are connected.
    def getActiveConnections(self):
        return [connection for connection in self._printer_connections if connection.isConnected()]

    ##  get a printer connection object by serial port
    def getConnectionByPort(self, serial_port):
        for printer_connection in self._printer_connections:
            if serial_port == printer_connection.getSerialPort():
                return printer_connection
        return None

    ##  Create a list of serial ports on the system.
    #   \param only_list_usb If true, only usb ports are listed
    def getSerialPortList(self,only_list_usb=False):
        base_list=[]
        if platform.system() == "Windows":
            try:
                key=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,"HARDWARE\\DEVICEMAP\\SERIALCOMM")
                i=0
                while True:
                    values = _winreg.EnumValue(key, i)
                    if not base_list or 'USBSER' in values[0]:
                        base_list+=[values[1]]
                    i+=1
            except:
                pass

        if base_list:
            base_list = base_list + glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*') + glob.glob("/dev/cu.usb*")
            base_list = filter(lambda s: not 'Bluetooth' in s, base_list) #Filter because mac sometimes puts them in the list
            #prev = profile.getMachineSetting('serial_port_auto')
            #if prev in base_list:
            #    base_list.remove(prev)
            #    base_list.insert(0, prev)
        else:
            base_list = base_list + glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*') + glob.glob("/dev/cu.*") + glob.glob("/dev/tty.usb*") + glob.glob("/dev/rfcomm*") + glob.glob('/dev/serial/by-id/*')
        #if version.isDevVersion() and not base_list:
            #base_list.append('VIRTUAL')
        return base_list<commit_msg>Add missing import.<commit_after>from UM.Signal import Signal, SignalEmitter
from . import PrinterConnection
from UM.Application import Application
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Scene.SceneNode import SceneNode
from UM.Resources import Resources
import threading
import platform
import glob
import time
import os
import sys
from UM.Extension import Extension

from PyQt5.QtQuick import QQuickView
from PyQt5.QtCore import QUrl, QObject,pyqtSlot , pyqtProperty,pyqtSignal

from UM.i18n import i18nCatalog

i18n_catalog = i18nCatalog('plugins')

class USBPrinterManager(QObject, SignalEmitter, Extension):
    def __init__(self, parent = None):
        super().__init__(parent)
        self._serial_port_list = []
        self._printer_connections = []
        self._check_ports_thread = threading.Thread(target=self._updateConnectionList)
        self._check_ports_thread.daemon = True
        self._check_ports_thread.start()

        self._progress = 0

        self.view = None
        self._extruder_temp = 0
        self._bed_temp = 0
        self._error_message = ""

        self.addMenuItem(i18n_catalog.i18n("Update firmware"), self.updateAllFirmware)

        #time.sleep(1)
        #self.connectAllConnections()
        #time.sleep(5)
        #f = open("Orb.gcode")
        #lines = f.readlines()
        #print(len(lines))
        #print(len(self._printer_connections))
        #self.sendGCodeToAllActive(lines)
        #print("sending heat " , self.sendCommandToAllActive("M104 S190"))

    def spawnInterface(self,serial_port):
        if self.view is None:
            self.view = QQuickView()
            self.view.engine().rootContext().setContextProperty('manager',self)
            self.view.setSource(QUrl("plugins/USBPrinting/ControlWindow.qml"))
            self.view.show()

    processingProgress = pyqtSignal(float, arguments = ['amount'])
    @pyqtProperty(float,notify = processingProgress)
    def progress(self):
        return self._progress

    pyqtExtruderTemperature = pyqtSignal(float, arguments = ['amount'])
    @pyqtProperty(float,notify = pyqtExtruderTemperature)
    def extruderTemperature(self):
        return self._extruder_temp

    pyqtBedTemperature = pyqtSignal(float, arguments = ['amount'])
    @pyqtProperty(float,notify = pyqtBedTemperature)
    def bedTemperature(self):
        return self._bed_temp

    pyqtError = pyqtSignal(str, arguments = ['amount'])
    @pyqtProperty(str,notify = pyqtError)
    def error(self):
        return self._error_message

    ##  Check all serial ports and create a PrinterConnection object for them.
    #   Note that this does not validate if the serial ports are actually usable!
    #   This (the validation) is only done when the connect function is called.
    def _updateConnectionList(self):
        while True:
            temp_serial_port_list = self.getSerialPortList(only_list_usb = True)
            if temp_serial_port_list != self._serial_port_list: # Something changed about the list since we last changed something.
                disconnected_ports = [port for port in self._serial_port_list if port not in temp_serial_port_list ]
                self._serial_port_list = temp_serial_port_list
                for serial_port in self._serial_port_list:
                    if self.getConnectionByPort(serial_port) is None: #If it doesn't already exist, add it
                        if not os.path.islink(serial_port): #Only add the connection if it's a non symbolic link
                            connection = PrinterConnection.PrinterConnection(serial_port)
                            connection.connect()
                            connection.connectionStateChanged.connect(self.serialConectionStateCallback)
                            connection.progressChanged.connect(self.onProgress)
                            connection.onExtruderTemperatureChange.connect(self.onExtruderTemperature)
                            connection.onBedTemperatureChange.connect(self.onBedTemperature)
                            connection.onError.connect(self.onError)
                            self._printer_connections.append(connection)

                for serial_port in disconnected_ports: # Close connections and remove them from list.
                    connection = self.getConnectionByPort(serial_port)
                    if connection != None:
                        self._printer_connections.remove(connection)
                        connection.close()
            time.sleep(5) #Throttle, as we don't need this information to be updated every single second.

    def onExtruderTemperature(self, serial_port, index,temperature):
        #print("ExtruderTemperature " , serial_port, " " , index, " " , temperature)
        self._extruder_temp = temperature
        self.pyqtExtruderTemperature.emit(temperature)

        pass

    def updateAllFirmware(self):
        for printer_connection in self._printer_connections:
            printer_connection.updateFirmware(Resources.getPath(Resources.FirmwareLocation, self._getDefaultFirmwareName()))

    def updateFirmwareBySerial(self, serial_port):
        printer_connection = self.getConnectionByPort(serial_port)
        if printer_connection is not None:
            printer_connection.updateFirmware(Resources.getPath(Resources.FirmwareLocation, self._getDefaultFirmwareName()))

    def _getDefaultFirmwareName(self):
        machine_type = Application.getInstance().getActiveMachine().getTypeID()
        firmware_name = ""
        baudrate = 250000
        if sys.platform.startswith('linux'):
                baudrate = 115200
        if machine_type == "ultimaker_original":
            firmware_name = 'MarlinUltimaker'
            firmware_name += '-%d' % (baudrate)
        elif machine_type == "ultimaker_original_plus":
            firmware_name = 'MarlinUltimaker-UMOP-%d' % (baudrate)
        elif machine_type == "Witbox":
            return "MarlinWitbox.hex"
        elif machine_type == "ultimaker2go":
            return "MarlinUltimaker2go.hex"
        elif machine_type == "ultimaker2extended":
            return "MarlinUltimaker2extended.hex"
        elif machine_type == "ultimaker2":
            return "MarlinUltimaker2.hex"

        ##TODO: Add check for multiple extruders

        if firmware_name != "":
            firmware_name += ".hex"
        return firmware_name

    def onBedTemperature(self, serial_port,temperature):
        self._bed_temperature = temperature
        self.pyqtBedTemperature.emit(temperature)
        #print("bedTemperature " , serial_port, " "  , temperature)
        pass

    def onError(self, error):
        self._error_message = error
        self.pyqtError.emit(error)
        pass

    def onProgress(self, progress, serial_port):
        self._progress = progress
        self.processingProgress.emit(progress)
        pass

    ##  Attempt to connect with all possible connections.
    def connectAllConnections(self):
        for connection in self._printer_connections:
            connection.connect()

    ##  send gcode to printer and start printing
    def sendGCodeByPort(self, serial_port, gcode_list):
        printer_connection = self.getConnectionByPort(serial_port)
        if printer_connection is not None:
            printer_connection.printGCode(gcode_list)
            return True
        return False

    @pyqtSlot()
    def cancelPrint(self):
        for printer_connection in self.getActiveConnections():
            printer_connection.cancelPrint()

    ##  Send gcode to all active printers.
    #   \return True if there was at least one active connection.
    def sendGCodeToAllActive(self, gcode_list):
        for printer_connection in self.getActiveConnections():
            printer_connection.printGCode(gcode_list)
        if len(self.getActiveConnections()):
            return True
        else:
            return False

    ##  Send a command to a printer indentified by port
    #   \param serial port String indentifieing the port
    #   \param command String with the g-code command to send.
    #   \return True if connection was found, false otherwise
    def sendCommandByPort(self, serial_port, command):
        printer_connection = self.getConnectionByPort(serial_port)
        if printer_connection is not None:
            printer_connection.sendCommand(command)
            return True
        return False

    ##  Send a command to all active (eg; connected) printers
    #   \param command String with the g-code command to send.
    #   \return True if at least one connection was found, false otherwise
    def sendCommandToAllActive(self, command):
        for printer_connection in self.getActiveConnections():
            printer_connection.sendCommand(command)
        if len(self.getActiveConnections()):
            return True
        else:
            return False

    def serialConectionStateCallback(self,serial_port):
        connection = self.getConnectionByPort(serial_port)
        if connection.isConnected():
            Application.getInstance().addOutputDevice(serial_port, {
                'id': serial_port,
                'function': self.spawnInterface,
                'description': 'Write to USB {0}'.format(serial_port),
                'icon': 'print_usb',
                'priority': 1
            })
        else:
            Application.getInstance().removeOutputDevice(serial_port)

    '''def _writeToSerial(self, serial_port):
        gcode_list = getattr(Application.getInstance().getController().getScene(), 'gcode_list', None)
        if gcode_list:
            final_list = []
            for gcode in gcode_list:
                final_list += gcode.split('\n')
            self.sendGCodeByPort(serial_port, gcode_list)'''
    @pyqtSlot()
    def startPrint(self):
        gcode_list = getattr(Application.getInstance().getController().getScene(), 'gcode_list', None)
        if gcode_list:
            final_list = []
            for gcode in gcode_list:
                final_list += gcode.split('\n')
            self.sendGCodeToAllActive(gcode_list)

    ## Get a list of printer connection objects that are connected.
    def getActiveConnections(self):
        return [connection for connection in self._printer_connections if connection.isConnected()]

    ##  get a printer connection object by serial port
    def getConnectionByPort(self, serial_port):
        for printer_connection in self._printer_connections:
            if serial_port == printer_connection.getSerialPort():
                return printer_connection
        return None

    ##  Create a list of serial ports on the system.
    #   \param only_list_usb If true, only usb ports are listed
    def getSerialPortList(self,only_list_usb=False):
        base_list=[]
        if platform.system() == "Windows":
            import _winreg
            try:
                key=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,"HARDWARE\\DEVICEMAP\\SERIALCOMM")
                i=0
                while True:
                    values = _winreg.EnumValue(key, i)
                    if not base_list or 'USBSER' in values[0]:
                        base_list+=[values[1]]
                    i+=1
            except:
                pass

        if base_list:
            base_list = base_list + glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*') + glob.glob("/dev/cu.usb*")
            base_list = filter(lambda s: not 'Bluetooth' in s, base_list) #Filter because mac sometimes puts them in the list
            #prev = profile.getMachineSetting('serial_port_auto')
            #if prev in base_list:
            #    base_list.remove(prev)
            #    base_list.insert(0, prev)
        else:
            base_list = base_list + glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*') + glob.glob("/dev/cu.*") + glob.glob("/dev/tty.usb*") + glob.glob("/dev/rfcomm*") + glob.glob('/dev/serial/by-id/*')
        #if version.isDevVersion() and not base_list:
            #base_list.append('VIRTUAL')
        return base_list<|endoftext|>


<commit_before>#!/usr/bin/env python
# test_TaxPlot.py

from __future__ import division
from unittest import TestCase, main
import random
from numpy import ones, ndarray, power, array, round as nround
from numpy.testing import (assert_almost_equal,
                           assert_allclose)
from scipy.stats import kruskal
from skbio.stats.power_analysis import (confidence_bound,
                                        calculate_power,
                                        compare_distributions,
                                        calculate_power_curve,
                                        bootstrap_power_curve)

random.seed(5)

class PowerAnalysisTest(TestCase):
    def setUp(self):
        """Initializes data for each test instance"""
        # Sets up the distributions of data for use
        self.s1 = arange(0, 10, 1)
        # Sets up two distributions which will never be equal by a rank-sum
        # test.
        self.samps = [ones((10))/10., ones((10))]
        self.pop = [arange(0, 10, 0.1), arange(0, 20, 0.2)]
        # Sets up a vector of alpha values
        self.alpha = power(10, array([-1, -1.301, -2, -3])).round(3)
        # Sets up a vector of samples
        self.num_samps = arange(10, 100, 10)
        # Sets up the test function, a rank-sum test
        self.f = lambda x: kruskal(*x)[1]

    def test_confidence_bound_default(self):
        """Checks confidence_bound correctly determines an interval"""
        # Sets the know confidence bound
        known = 2.1658506
        test = confidence_bound(self.s1)
        assert_almost_equal(known, test, 5)

    def test_confidence_bound_df(self):
        """Checks a custom df for confidence_bound"""
        known = 2.0407076
        test = confidence_bound(self.s1, df=15)
        assert_almost_equal(known, test, 5)

    def test_confidence_bound_alpha(self):
        """Checks a custom df for confidence_bound"""
        known = 3.111481
        test = confidence_bound(self.s1, alpha=0.01)
        assert_almost_equal(known, test, 5)

    def test_calculate_power(self):
        """Tests calculate_power is sane"""
        # Sets up the values to test
        crit = 0.025
        # Sets the known value
        known = 0.5
        # Calculates the test value
        test = calculate_power(self.alpha, crit)
        # Checks the test value
        assert_almost_equal(known, test)

    def test_compare_distributions(self):
        """Checks compare_distributions is sane"""
        known = ones((100))*0.0026998
        test = compare_distributions(self.f, self.samps, num_iter=100)
        assert_allclose(known, test, 5)

    def test_calculate_power_curve_ratio_error(self):
        """Checks the function errors correctly for a non-sane ratio argument

        the ratio argument must be a none-type (flat distribution), or an array
        with the same shape as population.

        """
        self.assertRaises(ValueError, calculate_power_curve, self.f,
                          self.pop, self.num_samps,
                          ratio=array([0.1, 0.2, 0.3]))

    def test_calculate_power_curve_default(self):
        """Checks the power array is within a sane range for default values"""
        # Sets the know output
        known = array([0.509, 0.822, 0.962, 0.997, 1.000, 1.000, 1.000,
                       1.000,  1.000])

        # Generates the test values.
        test = calculate_power_curve(self.f,
                                     self.pop,
                                     self.num_samps,
                                     num_iter=100)
        # Checks the samples returned sanely
        assert_allclose(test, known, rtol=0.1, atol=0.1)

    def test_calculate_power_curve_alpha(self):
        """Checks the power array is in a sane range when alpha is varied"""
        # Sets the know output
        known = array([0.182, 0.568, 0.842, 0.954, 0.995, 1.000, 1.000, 1.000,
                       1.000])

         # Generates the test values
        test = calculate_power_curve(self.f,
                                     self.pop,
                                     self.num_samps,
                                     alpha=0.01,
                                     num_iter=100)

        # Checks the samples returned sanely
        assert_allclose(test, known, rtol=0.1, atol=0.1)

    def test_calculate_power_curve_ratio(self):
        """Checks the power array is in a sane range when ratio is varied"""
        # Sets the know output
        known = array([0.096, 0.333, 0.493, 0.743, 0.824, 0.937, 0.969,
                       0.996, 0.998])

         # Generates the test values
        test = calculate_power_curve(self.f,
                                     self.pop,
                                     self.num_samps,
                                     ratio=array([0.25, 0.75]),
                                     num_iter=100)

        # Checks the samples returned sanely
        assert_allclose(test, known, rtol=0.1, atol=0.1)

    def test_bootstrap_power_curve(self):
        """Checks the power estimate is handled in a sane way"""
        # Sets the known values
        known_mean = array([0.500, 0.82, 0.965, 0.995, 1.000, 1.000,
                            1.000, 1.000,  1.000])
        known_bound = array([0.03, 0.03, 0.02, 0.005, 0.00, 0.00, 0.00, 0.00,
                             0.00])
        # Generates the test values
        test_mean, test_bound = bootstrap_power_curve(self.f,
                                                      self.pop,
                                                      self.num_samps,
                                                      num_iter=100)
        # Checks the function returned sanely
        assert_allclose(test_mean, known_mean, rtol=0.05, atol=0.05)
        assert_allclose(test_bound, known_bound, rtol=0.05, atol=0.01)

if __name__ == '__main__':
    main()
<commit_msg>Fixes more imports because pep8<commit_after>#!/usr/bin/env python
# test_TaxPlot.py

from __future__ import division
from unittest import TestCase, main
import random
from numpy import ones, ndarray, power, array, round as nround, arange
from numpy.testing import (assert_almost_equal,
                           assert_allclose)
from scipy.stats import kruskal
from skbio.stats.power_analysis import (confidence_bound,
                                        calculate_power,
                                        compare_distributions,
                                        calculate_power_curve,
                                        bootstrap_power_curve)

random.seed(5)

class PowerAnalysisTest(TestCase):
    def setUp(self):
        """Initializes data for each test instance"""
        # Sets up the distributions of data for use
        self.s1 = arange(0, 10, 1)
        # Sets up two distributions which will never be equal by a rank-sum
        # test.
        self.samps = [ones((10))/10., ones((10))]
        self.pop = [arange(0, 10, 0.1), arange(0, 20, 0.2)]
        # Sets up a vector of alpha values
        self.alpha = power(10, array([-1, -1.301, -2, -3])).round(3)
        # Sets up a vector of samples
        self.num_samps = arange(10, 100, 10)
        # Sets up the test function, a rank-sum test
        self.f = lambda x: kruskal(*x)[1]

    def test_confidence_bound_default(self):
        """Checks confidence_bound correctly determines an interval"""
        # Sets the know confidence bound
        known = 2.1658506
        test = confidence_bound(self.s1)
        assert_almost_equal(known, test, 5)

    def test_confidence_bound_df(self):
        """Checks a custom df for confidence_bound"""
        known = 2.0407076
        test = confidence_bound(self.s1, df=15)
        assert_almost_equal(known, test, 5)

    def test_confidence_bound_alpha(self):
        """Checks a custom df for confidence_bound"""
        known = 3.111481
        test = confidence_bound(self.s1, alpha=0.01)
        assert_almost_equal(known, test, 5)

    def test_calculate_power(self):
        """Tests calculate_power is sane"""
        # Sets up the values to test
        crit = 0.025
        # Sets the known value
        known = 0.5
        # Calculates the test value
        test = calculate_power(self.alpha, crit)
        # Checks the test value
        assert_almost_equal(known, test)

    def test_compare_distributions(self):
        """Checks compare_distributions is sane"""
        known = ones((100))*0.0026998
        test = compare_distributions(self.f, self.samps, num_iter=100)
        assert_allclose(known, test, 5)

    def test_calculate_power_curve_ratio_error(self):
        """Checks the function errors correctly for a non-sane ratio argument

        the ratio argument must be a none-type (flat distribution), or an array
        with the same shape as population.

        """
        self.assertRaises(ValueError, calculate_power_curve, self.f,
                          self.pop, self.num_samps,
                          ratio=array([0.1, 0.2, 0.3]))

    def test_calculate_power_curve_default(self):
        """Checks the power array is within a sane range for default values"""
        # Sets the know output
        known = array([0.509, 0.822, 0.962, 0.997, 1.000, 1.000, 1.000,
                       1.000,  1.000])

        # Generates the test values.
        test = calculate_power_curve(self.f,
                                     self.pop,
                                     self.num_samps,
                                     num_iter=100)
        # Checks the samples returned sanely
        assert_allclose(test, known, rtol=0.1, atol=0.1)

    def test_calculate_power_curve_alpha(self):
        """Checks the power array is in a sane range when alpha is varied"""
        # Sets the know output
        known = array([0.182, 0.568, 0.842, 0.954, 0.995, 1.000, 1.000, 1.000,
                       1.000])

         # Generates the test values
        test = calculate_power_curve(self.f,
                                     self.pop,
                                     self.num_samps,
                                     alpha=0.01,
                                     num_iter=100)

        # Checks the samples returned sanely
        assert_allclose(test, known, rtol=0.1, atol=0.1)

    def test_calculate_power_curve_ratio(self):
        """Checks the power array is in a sane range when ratio is varied"""
        # Sets the know output
        known = array([0.096, 0.333, 0.493, 0.743, 0.824, 0.937, 0.969,
                       0.996, 0.998])

         # Generates the test values
        test = calculate_power_curve(self.f,
                                     self.pop,
                                     self.num_samps,
                                     ratio=array([0.25, 0.75]),
                                     num_iter=100)

        # Checks the samples returned sanely
        assert_allclose(test, known, rtol=0.1, atol=0.1)

    def test_bootstrap_power_curve(self):
        """Checks the power estimate is handled in a sane way"""
        # Sets the known values
        known_mean = array([0.500, 0.82, 0.965, 0.995, 1.000, 1.000,
                            1.000, 1.000,  1.000])
        known_bound = array([0.03, 0.03, 0.02, 0.005, 0.00, 0.00, 0.00, 0.00,
                             0.00])
        # Generates the test values
        test_mean, test_bound = bootstrap_power_curve(self.f,
                                                      self.pop,
                                                      self.num_samps,
                                                      num_iter=100)
        # Checks the function returned sanely
        assert_allclose(test_mean, known_mean, rtol=0.05, atol=0.05)
        assert_allclose(test_bound, known_bound, rtol=0.05, atol=0.01)

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


<commit_before>import cno
import signal
import asyncio
import weakref
import itertools
import contextlib

from .c import ffi
from .c.lib import *

@ffi.def_extern('webm_on_write', -1)
def _(handle, data, size, force):
    queue = ffi.from_handle(handle)
    if not force and queue.qsize() > 0:
        return -1
    queue.put_nowait(ffi.buffer(data, size)[:])
    return 0

class Broadcast (asyncio.Event):
    def __init__(self, *a, **k):
        super().__init__(*a, **k)
        self.obj = webm_broadcast_start()

    def __del__(self):
        webm_broadcast_stop(self.obj)

    def stop(self):
        self.set()

    def send(self, chunk):
        s = ffi.new('uint8_t[]', chunk)
        if webm_broadcast_send(self.obj, s, len(chunk)):
            raise ValueError('bad data')

    @contextlib.contextmanager
    def connect(self, queue, skip_headers=False):
        handle = ffi.new_handle(queue)
        slot = webm_slot_connect(self.obj, webm_on_write, handle, skip_headers)
        try:
            yield self
        finally:
            webm_slot_disconnect(self.obj, slot)

async def handle(req, streams = weakref.WeakValueDictionary()):
    if req.path.endswith('.webm'):
        stream_id = req.path.lstrip('/')[:-5]

        if req.method == 'POST':
            if stream_id in streams:
                return (await req.respond(403, [], b'stream id already taken'))

            streams[stream_id] = stream = Broadcast(loop=req.conn.loop)
            try:
                while True:
                    chunk = await req.payload.read(16384)
                    if chunk == b'':
                        break
                    stream.send(chunk)
            finally:
                stream.stop()
            return (await req.respond(204, [], b''))

        try:
            stream = streams[stream_id]
        except KeyError:
            return (await req.respond(404, [], b'this stream is offline'))

        queue = cno.Channel(loop=req.conn.loop)

        async def writer():
            try:
                # XXX we can switch streams in the middle of the video
                #     by disconnecting the queue and reconnecting it
                #     with skip_headers=True. (that would make the server
                #     start a new webm segment) this might be useful
                #     for adaptive streaming.
                with stream.connect(queue):
                    await stream.wait()
            finally:
                queue.close()

        writer = asyncio.ensure_future(writer(), loop=req.conn.loop)
        try:
            return (await req.respond(200, [('content-type', 'video/webm')], queue))
        finally:
            writer.cancel()

    if req.method != 'GET':
        return (await req.respond(405, [], b'/stream_name**.webm**'))

    stream_id = req.path.strip('/')

    if stream_id not in streams:
        return (await req.respond(404, [], b'this stream is offline'))

    await req.respond(200, [('content-type', 'text/html')],
        '''<!doctype html>
            <html>
                <head>
                    <meta charset='utf-8' />
                    <title>asd</title>
                </head>
                <body>
                    <video autoplay preload='none'>
                        <source src='/{}.webm' type='video/webm' />
                    </video>
            </html>
        '''.format(stream_id).encode('utf-8')
    )

async def main(loop):
    http = await loop.create_server(lambda: cno.Server(loop, handle), '', 8000)
    try:
        print('http://127.0.0.1:8000/')
        await asyncio.Future(loop=loop)
    finally:
        http.close()

loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))
<commit_msg>http-webm: keep streams alive for 10 seconds after a disconnect.<commit_after>import cno
import signal
import asyncio
import weakref
import itertools
import contextlib

from .c import ffi
from .c.lib import *

@ffi.def_extern('webm_on_write', -1)
def _(handle, data, size, force):
    queue = ffi.from_handle(handle)
    if not force and queue.qsize() > 0:
        return -1
    queue.put_nowait(ffi.buffer(data, size)[:])
    return 0

class Broadcast (asyncio.Event):
    def __init__(self, *a, **k):
        super().__init__(*a, **k)
        self.obj = webm_broadcast_start()

    def __del__(self):
        webm_broadcast_stop(self.obj)

    def stop(self):
        self.set()

    def send(self, chunk):
        s = ffi.new('uint8_t[]', chunk)
        if webm_broadcast_send(self.obj, s, len(chunk)):
            raise ValueError('bad data')

    @contextlib.contextmanager
    def connect(self, queue, skip_headers=False):
        handle = ffi.new_handle(queue)
        slot = webm_slot_connect(self.obj, webm_on_write, handle, skip_headers)
        try:
            yield self
        finally:
            webm_slot_disconnect(self.obj, slot)

async def handle(req, streams = weakref.WeakValueDictionary(),
                      collectors = {}):
    if req.path.endswith('.webm'):
        stream_id = req.path.lstrip('/')[:-5]

        if req.method == 'POST':
            if stream_id in streams:
                try:
                    collectors.pop(stream_id).cancel()
                except KeyError:
                    return (await req.respond(403, [], b'stream id already taken'))
                stream = streams[stream_id]
            else:
                streams[stream_id] = stream = Broadcast(loop=req.conn.loop)
            try:
                while True:
                    chunk = await req.payload.read(16384)
                    if chunk == b'':
                        break
                    stream.send(chunk)
            finally:
                async def collect():
                    await asyncio.sleep(10, loop=req.conn.loop)
                    stream.stop()
                collectors[stream_id] = asyncio.ensure_future(collect(), loop=req.conn.loop)
            return (await req.respond(204, [], b''))

        try:
            stream = streams[stream_id]
        except KeyError:
            return (await req.respond(404, [], b'this stream is offline'))

        queue = cno.Channel(loop=req.conn.loop)

        async def writer():
            try:
                # XXX we can switch streams in the middle of the video
                #     by disconnecting the queue and reconnecting it
                #     with skip_headers=True. (that would make the server
                #     start a new webm segment) this might be useful
                #     for adaptive streaming.
                with stream.connect(queue):
                    await stream.wait()
            finally:
                queue.close()

        writer = asyncio.ensure_future(writer(), loop=req.conn.loop)
        try:
            return (await req.respond(200, [('content-type', 'video/webm')], queue))
        finally:
            writer.cancel()

    if req.method != 'GET':
        return (await req.respond(405, [], b'/stream_name**.webm**'))

    stream_id = req.path.strip('/')

    if stream_id not in streams:
        return (await req.respond(404, [], b'this stream is offline'))

    await req.respond(200, [('content-type', 'text/html')],
        '''<!doctype html>
            <html>
                <head>
                    <meta charset='utf-8' />
                    <title>asd</title>
                </head>
                <body>
                    <video autoplay preload='none'>
                        <source src='/{}.webm' type='video/webm' />
                    </video>
            </html>
        '''.format(stream_id).encode('utf-8')
    )

async def main(loop):
    http = await loop.create_server(lambda: cno.Server(loop, handle), '', 8000)
    try:
        print('http://127.0.0.1:8000/')
        await asyncio.Future(loop=loop)
    finally:
        http.close()

loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))
<|endoftext|>


<commit_before>"""
designed to easily configure logging.logger,
and consist the performance of tornado's loggers.
"""
import logging
import os

def get_logger(class_name, debug=False):
    """
    configure logger before return if it has no handler.configure.
    consist the performance of tornado's loggers.
    """
    logger = logging.getLogger(class_name)

    if len(logger.handlers) != 0:
        return logger

    formatter = logging.Formatter(
        '%(asctime)s - %(name)s.%(funcName)s %(levelname)-5s : %(message)s',
        '%m-%d %H:%M'
    )

    log_dir = "logs"
    log_file = 'http_api_exporter.log'

    log_file = os.path.join(log_dir, log_file)

    if not os.path.exists(log_dir):
        os.mkdir(log_dir)

    if not os.path.exists(log_file):
        open(log_file, 'w').close()

    hdlr = logging.handlers.TimedRotatingFileHandler(
        log_file,
        when="D",
        interval=1,
        backupCount=7
    )
    hdlr.setLevel(logging.DEBUG)
    hdlr.setFormatter(formatter)

    console = logging.StreamHandler()
    if debug:
        console.setLevel(logging.DEBUG)
    else:
        console.setLevel(logging.INFO)
    console.setFormatter(formatter)

    logger.addHandler(hdlr)
    logger.addHandler(console)

    tornado_access_logger = logging.getLogger("tornado.access")
    tornado_application_logger = logging.getLogger("tornado.application")
    tornado_general_logger = logging.getLogger("tornado.general")

    tornado_access_logger.handlers = []
    tornado_application_logger.handlers = []
    tornado_general_logger.handlers = []

    tornado_access_logger.addHandler(hdlr)
    tornado_access_logger.addHandler(console)
    tornado_access_logger.setLevel(logging.DEBUG)

    tornado_application_logger.addHandler(hdlr)
    tornado_application_logger.addHandler(console)
    tornado_application_logger.setLevel(logging.DEBUG)

    tornado_general_logger.addHandler(hdlr)
    tornado_general_logger.addHandler(console)
    tornado_general_logger.setLevel(logging.DEBUG)

    logger.setLevel(logging.DEBUG)

    return logger
<commit_msg>modify logger for test purpose<commit_after>"""
designed to easily configure logging.logger,
and consist the performance of tornado's loggers.
"""
import logging
import os

def get_logger(class_name, debug=False):
    """
    Configure logger before return if it has no handlers.
    Consist the performance of tornado's loggers.
    """
    logger = logging.getLogger(class_name)

    if not logging.getLogger().isEnabledFor(logging.CRITICAL) or not logger.handlers:
        return logger

    formatter = logging.Formatter(
        '%(asctime)s - %(name)s.%(funcName)s %(levelname)-5s : %(message)s',
        '%m-%d %H:%M'
    )

    log_dir = "logs"
    log_file = 'http_api_exporter.log'

    log_file = os.path.join(log_dir, log_file)

    if not os.path.exists(log_dir):
        os.mkdir(log_dir)

    if not os.path.exists(log_file):
        open(log_file, 'w').close()

    hdlr = logging.handlers.TimedRotatingFileHandler(
        log_file,
        when="D",
        interval=1,
        backupCount=7
    )
    hdlr.setLevel(logging.DEBUG)
    hdlr.setFormatter(formatter)

    console = logging.StreamHandler()
    if debug:
        console.setLevel(logging.DEBUG)
    else:
        console.setLevel(logging.INFO)
    console.setFormatter(formatter)

    logger.addHandler(hdlr)
    logger.addHandler(console)

    tornado_access_logger = logging.getLogger("tornado.access")
    tornado_application_logger = logging.getLogger("tornado.application")
    tornado_general_logger = logging.getLogger("tornado.general")

    tornado_access_logger.handlers = []
    tornado_application_logger.handlers = []
    tornado_general_logger.handlers = []

    tornado_access_logger.addHandler(hdlr)
    tornado_access_logger.addHandler(console)
    tornado_access_logger.setLevel(logging.DEBUG)

    tornado_application_logger.addHandler(hdlr)
    tornado_application_logger.addHandler(console)
    tornado_application_logger.setLevel(logging.DEBUG)

    tornado_general_logger.addHandler(hdlr)
    tornado_general_logger.addHandler(console)
    tornado_general_logger.setLevel(logging.DEBUG)

    logger.setLevel(logging.DEBUG)

    return logger
<|endoftext|>


<commit_before>import numpy as np
from scipy import ndimage as nd
from ..morphology import dilation, erosion, square
from ..util import img_as_float, view_as_windows, pad
from ..color import gray2rgb

def _find_boundaries_subpixel(label_img):
    """See ``find_boundaries(..., mode='subpixel')``.

    Notes
    -----
    This function puts in an empty row and column between each *actual*
    row and column of the image, for a corresponding shape of $2s - 1$
    for every image dimension of size $s$. These "interstitial" rows
    and columns are filled as ``True`` if they separate two labels in
    `label_img`, ``False`` otherwise.

    I used ``view_as_windows`` to get the neighborhood of each pixel.
    Then I check whether there are two labels or more in that
    neighborhood.
    """
    ndim = label_img.ndim
    max_label = np.iinfo(label_img.dtype).max

    label_img_expanded = np.zeros([(2 * s - 1) for s in label_img.shape],
                                  label_img.dtype)
    pixels = [slice(None, None, 2)] * ndim
    label_img_expanded[pixels] = label_img

    edges = np.ones(label_img_expanded.shape, dtype=bool)
    edges[pixels] = False
    label_img_expanded[edges] = max_label
    windows = view_as_windows(pad(label_img_expanded, 1,
                                  mode='constant', constant_values=0),
                              (3,) * ndim)

    boundaries = np.zeros_like(edges)
    for index in np.ndindex(label_img_expanded.shape):
        if edges[index]:
            values = np.unique(windows[index].ravel())
            if len(values) > 2: # single value and max_label
                boundaries[index] = True
    return boundaries

def find_boundaries(label_img, connectivity=1, mode='thick', background=0):
    """Return bool array where boundaries between labeled regions are True.

    Parameters
    ----------
    label_img : array of int
        An array in which different regions are labeled with different
        integers.
    connectivity: int in {1, ..., `label_img.ndim`}, optional
        A pixel is considered a boundary pixel if any of its neighbors
        has a different label. `connectivity` controls which pixels are
        considered neighbors. A connectivity of 1 (default) means
        pixels sharing an edge (in 2D) or a face (in 3D) will be
        considered neighbors. A connectivity of `label_img.ndim` means
        pixels sharing a corner will be considered neighbors.
    mode: string in {'thick', 'inner', 'outer', 'subpixel'}
        How to mark the boundaries:

        - thick: any pixel not completely surrounded by pixels of the
        same label (defined by `connectivity`) is marked as a boundary.
        This results in boundaries that are 2 pixels thick.
        - inner: outline the pixels *just inside* of objects, leaving
        background pixels untouched.
        - outer: outline pixels in the background around object
        boundaries. When two objects touch, their boundary is also
        marked.
        - subpixel: return a doubled image, with pixels *between* the
        original pixels marked as boundary where appropriate.
    background: int, optional
        For modes 'inner' and 'outer', a definition of a background
        label is required. See `mode` for descriptions of these two.

    Returns
    -------
    boundaries : array of bool, same shape as `label_img`
        A bool image where ``True`` represents a boundary pixel. For
        `mode` equal to 'subpixel', ``boundaries.shape[i]`` is equal
        to ``2 * label_img.shape[i] - 1`` for all ``i`` (a pixel is
        inserted in between all other pairs of pixels).

    Examples
    --------
    >>> labels = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    ...                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    ...                    [0, 0, 0, 0, 0, 5, 5, 5, 0, 0],
    ...                    [0, 0, 1, 1, 1, 5, 5, 5, 0, 0],
    ...                    [0, 0, 1, 1, 1, 5, 5, 5, 0, 0],
    ...                    [0, 0, 1, 1, 1, 5, 5, 5, 0, 0],
    ...                    [0, 0, 0, 0, 0, 5, 5, 5, 0, 0],
    ...                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    ...                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=np.uint8)
    >>> find_boundaries(labels).astype(np.uint8) # display 1/0, not True/False
    array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
           [0, 0, 1, 1, 1, 1, 1, 1, 1, 0],
           [0, 1, 1, 1, 1, 1, 0, 1, 1, 0],
           [0, 1, 1, 0, 1, 1, 0, 1, 1, 0],
           [0, 1, 1, 1, 1, 1, 0, 1, 1, 0],
           [0, 0, 1, 1, 1, 1, 1, 1, 1, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
    >>> find_boundaries(labels, mode='inner').astype(np.uint8)
    array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
           [0, 0, 1, 1, 1, 1, 0, 1, 0, 0],
           [0, 0, 1, 0, 1, 1, 0, 1, 0, 0],
           [0, 0, 1, 1, 1, 1, 0, 1, 0, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
    >>> find_boundaries(labels, mode='outer').astype(np.uint8)
    array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
           [0, 0, 1, 1, 1, 1, 0, 0, 1, 0],
           [0, 1, 0, 0, 1, 1, 0, 0, 1, 0],
           [0, 1, 0, 0, 1, 1, 0, 0, 1, 0],
           [0, 1, 0, 0, 1, 1, 0, 0, 1, 0],
           [0, 0, 1, 1, 1, 1, 0, 0, 1, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
    >>> labels_small = labels[::2, ::3]
    >>> labels_small
    array([[0, 0, 0, 0],
           [0, 0, 5, 0],
           [0, 1, 5, 0],
           [0, 0, 5, 0],
           [0, 0, 0, 0]], dtype=uint8)
    >>> find_boundaries(labels_small, mode='subpixel').astype(np.uint8)
    array([[0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 1, 1, 1, 0],
           [0, 0, 0, 1, 0, 1, 0],
           [0, 1, 1, 1, 0, 1, 0],
           [0, 1, 0, 1, 0, 1, 0],
           [0, 1, 1, 1, 0, 1, 0],
           [0, 0, 0, 1, 0, 1, 0],
           [0, 0, 0, 1, 1, 1, 0],
           [0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
    """
    ndim = label_img.ndim
    selem = nd.generate_binary_structure(ndim, connectivity)
    if mode != 'subpixel':
        boundaries = dilation(label_img, selem) != erosion(label_img, selem)
        if mode == 'inner':
            foreground_image = (label_img != background)
            boundaries &= foreground_image
        elif mode == 'outer':
            max_label = np.iinfo(label_img.dtype).max
            background_image = (label_img == background)
            selem = nd.generate_binary_structure(ndim, ndim)
            inverted_background = np.array(label_img, copy=True)
            inverted_background[background_image] = max_label
            adjacent_objects = ((dilation(label_img, selem) !=
                                 erosion(inverted_background, selem)) &
                                ~background_image)
            boundaries &= (background_image | adjacent_objects)
        return boundaries
    else:
        boundaries = _find_boundaries_subpixel(label_img)
        return boundaries

def mark_boundaries(image, label_img, color=(1, 1, 0),
                    outline_color=(0, 0, 0)):
    """Return image with boundaries between labeled regions highlighted.

    Parameters
    ----------
    image : (M, N[, 3]) array
        Grayscale or RGB image.
    label_img : (M, N) array
        Label array where regions are marked by different integer values.
    color : length-3 sequence
        RGB color of boundaries in the output image.
    outline_color : length-3 sequence
        RGB color surrounding boundaries in the output image. If None, no
        outline is drawn.
    """
    if image.ndim == 2:
        image = gray2rgb(image)
    image = img_as_float(image, force_copy=True)

    boundaries = find_boundaries(label_img)
    if outline_color is not None:
        outer_boundaries = dilation(boundaries.astype(np.uint8), square(3))
        image[outer_boundaries != 0, :] = np.array(outline_color)
    image[boundaries, :] = np.array(color)
    return image
<commit_msg>Allow different modes in mark_boundaries<commit_after>from __future__ import division

import numpy as np
from scipy import ndimage as nd
from ..morphology import dilation, erosion, square
from ..util import img_as_float, view_as_windows, pad
from ..color import gray2rgb

def _find_boundaries_subpixel(label_img):
    """See ``find_boundaries(..., mode='subpixel')``.

    Notes
    -----
    This function puts in an empty row and column between each *actual*
    row and column of the image, for a corresponding shape of $2s - 1$
    for every image dimension of size $s$. These "interstitial" rows
    and columns are filled as ``True`` if they separate two labels in
    `label_img`, ``False`` otherwise.

    I used ``view_as_windows`` to get the neighborhood of each pixel.
    Then I check whether there are two labels or more in that
    neighborhood.
    """
    ndim = label_img.ndim
    max_label = np.iinfo(label_img.dtype).max

    label_img_expanded = np.zeros([(2 * s - 1) for s in label_img.shape],
                                  label_img.dtype)
    pixels = [slice(None, None, 2)] * ndim
    label_img_expanded[pixels] = label_img

    edges = np.ones(label_img_expanded.shape, dtype=bool)
    edges[pixels] = False
    label_img_expanded[edges] = max_label
    windows = view_as_windows(pad(label_img_expanded, 1,
                                  mode='constant', constant_values=0),
                              (3,) * ndim)

    boundaries = np.zeros_like(edges)
    for index in np.ndindex(label_img_expanded.shape):
        if edges[index]:
            values = np.unique(windows[index].ravel())
            if len(values) > 2: # single value and max_label
                boundaries[index] = True
    return boundaries

def find_boundaries(label_img, connectivity=1, mode='thick', background=0):
    """Return bool array where boundaries between labeled regions are True.

    Parameters
    ----------
    label_img : array of int
        An array in which different regions are labeled with different
        integers.
    connectivity: int in {1, ..., `label_img.ndim`}, optional
        A pixel is considered a boundary pixel if any of its neighbors
        has a different label. `connectivity` controls which pixels are
        considered neighbors. A connectivity of 1 (default) means
        pixels sharing an edge (in 2D) or a face (in 3D) will be
        considered neighbors. A connectivity of `label_img.ndim` means
        pixels sharing a corner will be considered neighbors.
    mode: string in {'thick', 'inner', 'outer', 'subpixel'}
        How to mark the boundaries:

        - thick: any pixel not completely surrounded by pixels of the
        same label (defined by `connectivity`) is marked as a boundary.
        This results in boundaries that are 2 pixels thick.
        - inner: outline the pixels *just inside* of objects, leaving
        background pixels untouched.
        - outer: outline pixels in the background around object
        boundaries. When two objects touch, their boundary is also
        marked.
        - subpixel: return a doubled image, with pixels *between* the
        original pixels marked as boundary where appropriate.
    background: int, optional
        For modes 'inner' and 'outer', a definition of a background
        label is required. See `mode` for descriptions of these two.

    Returns
    -------
    boundaries : array of bool, same shape as `label_img`
        A bool image where ``True`` represents a boundary pixel. For
        `mode` equal to 'subpixel', ``boundaries.shape[i]`` is equal
        to ``2 * label_img.shape[i] - 1`` for all ``i`` (a pixel is
        inserted in between all other pairs of pixels).

    Examples
    --------
    >>> labels = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    ...                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    ...                    [0, 0, 0, 0, 0, 5, 5, 5, 0, 0],
    ...                    [0, 0, 1, 1, 1, 5, 5, 5, 0, 0],
    ...                    [0, 0, 1, 1, 1, 5, 5, 5, 0, 0],
    ...                    [0, 0, 1, 1, 1, 5, 5, 5, 0, 0],
    ...                    [0, 0, 0, 0, 0, 5, 5, 5, 0, 0],
    ...                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    ...                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=np.uint8)
    >>> find_boundaries(labels, mode='thick').astype(np.uint8)
    array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
           [0, 0, 1, 1, 1, 1, 1, 1, 1, 0],
           [0, 1, 1, 1, 1, 1, 0, 1, 1, 0],
           [0, 1, 1, 0, 1, 1, 0, 1, 1, 0],
           [0, 1, 1, 1, 1, 1, 0, 1, 1, 0],
           [0, 0, 1, 1, 1, 1, 1, 1, 1, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
    >>> find_boundaries(labels, mode='inner').astype(np.uint8)
    array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
           [0, 0, 1, 1, 1, 1, 0, 1, 0, 0],
           [0, 0, 1, 0, 1, 1, 0, 1, 0, 0],
           [0, 0, 1, 1, 1, 1, 0, 1, 0, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
    >>> find_boundaries(labels, mode='outer').astype(np.uint8)
    array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
           [0, 0, 1, 1, 1, 1, 0, 0, 1, 0],
           [0, 1, 0, 0, 1, 1, 0, 0, 1, 0],
           [0, 1, 0, 0, 1, 1, 0, 0, 1, 0],
           [0, 1, 0, 0, 1, 1, 0, 0, 1, 0],
           [0, 0, 1, 1, 1, 1, 0, 0, 1, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
    >>> labels_small = labels[::2, ::3]
    >>> labels_small
    array([[0, 0, 0, 0],
           [0, 0, 5, 0],
           [0, 1, 5, 0],
           [0, 0, 5, 0],
           [0, 0, 0, 0]], dtype=uint8)
    >>> find_boundaries(labels_small, mode='subpixel').astype(np.uint8)
    array([[0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 1, 1, 1, 0],
           [0, 0, 0, 1, 0, 1, 0],
           [0, 1, 1, 1, 0, 1, 0],
           [0, 1, 0, 1, 0, 1, 0],
           [0, 1, 1, 1, 0, 1, 0],
           [0, 0, 0, 1, 0, 1, 0],
           [0, 0, 0, 1, 1, 1, 0],
           [0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
    """
    ndim = label_img.ndim
    selem = nd.generate_binary_structure(ndim, connectivity)
    if mode != 'subpixel':
        boundaries = dilation(label_img, selem) != erosion(label_img, selem)
        if mode == 'inner':
            foreground_image = (label_img != background)
            boundaries &= foreground_image
        elif mode == 'outer':
            max_label = np.iinfo(label_img.dtype).max
            background_image = (label_img == background)
            selem = nd.generate_binary_structure(ndim, ndim)
            inverted_background = np.array(label_img, copy=True)
            inverted_background[background_image] = max_label
            adjacent_objects = ((dilation(label_img, selem) !=
                                 erosion(inverted_background, selem)) &
                                ~background_image)
            boundaries &= (background_image | adjacent_objects)
        return boundaries
    else:
        boundaries = _find_boundaries_subpixel(label_img)
        return boundaries

def mark_boundaries(image, label_img, color=(1, 1, 0),
                    outline_color=(0, 0, 0), mode='outer'):
    """Return image with boundaries between labeled regions highlighted.

    Parameters
    ----------
    image : (M, N[, 3]) array
        Grayscale or RGB image.
    label_img : (M, N) array of int
        Label array where regions are marked by different integer values.
    color : length-3 sequence, optional
        RGB color of boundaries in the output image.
    outline_color : length-3 sequence, optional
        RGB color surrounding boundaries in the output image. If None, no
        outline is drawn.
    mode : string in {'thick', 'inner', 'outer', 'subpixel'}, optional
        The mode for finding boundaries.

    Returns
    -------
    marked : (M, N, 3) array of float
        An image in which the boundaries between labels are
        superimposed on the original image.

    See Also
    --------
    ``find_boundaries``.
    """
    if image.ndim == 2:
        image = gray2rgb(image)
    marked = img_as_float(image, force_copy=True)
    if mode == 'subpixel':
        marked = nd.zoom(marked, [2 - 1/s for s in marked.shape[:-1]] + [1],
                         mode='reflect')
    boundaries = find_boundaries(label_img, mode=mode)
    if outline_color is not None:
        outer_boundaries = dilation(boundaries.astype(np.uint8), square(3))
        marked[outer_boundaries != 0, :] = np.array(outline_color)
    marked[boundaries, :] = np.array(color)
    return marked
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
Created on Thu Aug 30 14:00:54 2012

@author: Richard
"""

import numpy as np
#import Splines
from Splines import spline1d
from scipy.interpolate import interp1d

def fit_history_spline(age_array, offset_array):

    return interp1d(age_array, offset_array)

def sample_slip_history(age_array, offset_array, time_array,
                        extend_time=False):

    history_spline = fit_history_spline(age_array, offset_array)

    if extend_time == False:
        time_array = time_array[time_array <= np.max(age_array)]
    elif extend_time == True:
        raise Exception('extrapolating not supported yet')

    return history_spline(time_array)

def inverse_transform_sample(vals, probs, n_samps, n_interp=1000, seed=False,
                            seed_val=69):
    pdf_range, pdf_vals = make_pdf(vals, probs, n_interp)
    cdf_range, cdf_vals = make_cdf(pdf_range, pdf_vals)

    cdf_interp = interp1d(cdf_vals, cdf_range)

    if seed == True:
        np.random.seed(seed_val)

    samps = np.random.rand(n_samps)

    return cdf_interp(samps)

def make_pdf(vals, probs, n_interp=1000):
    val_min = np.min(vals)
    val_max = np.max(vals)

    pdf_range = np.linspace(val_min, val_max, n_interp)

    pmf = interp1d(vals, probs)
    pmf_samples = pmf(pdf_range)
    pdf_vals = pmf_samples / np.sum(pmf_samples)

    return pdf_range, pdf_vals

def make_cdf(pdf_range, pdf_vals):
    return (pdf_range, np.cumsum(pdf_vals))

class OffsetMarker:
    """Represents an offset geologic marker.

    Attributes:
        offsets: list of possible offset distances for the given marker.
            If offset_type = normal, offsets = [mean, sd]
        offset_probs: list of probabilities of corresponding offset distances
        offset_dist_type: offset prob. distribution (normal, uniform, arbitrary)
        ages: list of possible ages for the given marker
        age_probs: list of probabilities of corresponding ages
        age_dist_type: age prob. distribution (normal, uniform, arbitrary)
        source: Source for information (e.g., what article, field campaign)

    """
    def __init__(self, offsets=np.array([]), offset_probs=None,
                 offset_vals=None, offset_mean=None, offset_median=None,
                 offset_sd=None, offset_mad=None,
                 offset_min=None, offset_max=None,
                 offset_seed=None,
                 offset_dist_type='unspecified', ages=np.array([]),
                 age_probs=None, age_vals=None,
                 age_mean=None, age_median=None, age_sd=None, age_mad=None,
                 age_min=None, age_max=None,
                 age_seed=None,
                 age_dist_type='unspecified',
                 source='None'):

            self.offsets = offsets
            self.offset_probs = offset_probs
            self.offset_vals = offset_vals
            self.offset_mean = offset_mean
            self.offset_median = offset_median
            self.offset_sd = offset_sd
            self.offset_mad = offset_mad
            self.offset_min = offset_min
            self.offset_max = offset_max

            if offset_dist_type != 'unspecified':
                self.offset_dist_type = offset_dist_type
            elif offset_dist_type == 'unspecified':
                if offset_mean is not None and offset_sd is not None:
                    self.offset_dist_type = 'normal'
                elif (offset_min is not None and offset_max is not None
                      and offset_sd == None):
                    self.offset_dist_type = 'uniform'
                elif offset_probs is not None and offset_vals is not None:
                    self.offset_dist_type = 'arbitrary'

            self.ages = ages
            self.age_probs = age_probs
            self.age_vals = age_vals
            self.age_mean = age_mean
            self.age_median = age_median
            self.age_sd = age_sd
            self.age_mad = age_mad
            self.age_min = age_min
            self.age_max = age_max

            if age_dist_type != 'unspecified':
                self.age_dist_type = age_dist_type
            elif age_dist_type == 'unspecified':
                if age_mean is not None and age_sd is not None:
                    self.age_dist_type = 'normal'
                elif (age_min is not None and age_max is not None
                      and age_sd == None):
                    self.age_dist_type = 'uniform'
                elif age_probs is not None and age_vals is not None:
                    self.age_dist_type == 'arbitrary'

            self.source = source

    def sample_offset_from_normal(self, n):
        """Generates n-length sample from normal distribution of offsets"""

        return sample_from_bounded_normal(self.offset_mean, self.offset_sd, n,
                                          self.offset_min, self.offset_max)

    def sample_offset_from_uniform(self, n):
        """Generates n-length sample from uniform distribution of ages"""

        return np.random.uniform(self.offset_min, self.offset_max, n)

    def sample_offset_from_arbitrary(self, n):
        """not supported yet"""
        offset_sample = inverse_transform_sample(self.offset_vals,
                                                 self.offset_probs, n)
        return offset_sample

    def sample_offset(self, n):
        """Generates n-length array of samples from distribution"""
        if self.offset_dist_type == 'normal':
            offset_sample = self.sample_offset_from_normal(n)

        elif self.offset_dist_type == 'uniform':
            offset_sample = self.sample_offset_from_uniform(n)

        elif self.offset_dist_type == 'arbitrary':
            offset_sample = self.sample_offset_from_arbitrary(n)

        else:
            print('What is the offset distribution type?')

        return offset_sample

    def sample_age_from_normal(self, n):
        """Generates n-length sample from normal distribution of ages"""
        if self.age_min:
            age_min = self.age_min
        else:
            age_min = 0.

        age_sample = sample_bounded_normal(self.age_mean, self.age_sd, n,
                                           age_min, self.age_max)

        return age_sample

    def sample_age_from_uniform(self, n):
        """Generates n-length sample from uniform distribution of ages"""
        age_sample = (np.random.rand(n) * 2 -1) * self.age_err + self.age_mean
        #TODO: change mean, err to min, max

        return age_sample

    def sample_age_from_arbitrary(self, n):
        """not supported yet"""
        age_sample = inverse_transform_sample(self.age_vals, self.age_probs, n)

        return age_sample

    def sample_age(self, n):
        """Generates n-length array of samples from distribution"""
        if self.age_dist_type == 'normal':
            age_sample = self.sample_age_from_normal(n)

        elif self.age_dist_type == 'uniform':
            age_sample = self.sample_age_from_uniform(n)

        elif self.age_dist_type == 'arbitrary':
            pass

        else:
            print('What is the age distribution type?')

        return age_sample

    def sample(self, n):
        age_sample = self.sample_age(n)
        offset_sample = self.sample_offset(n)

        asl = len(age_sample)
        osl = len(offset_sample)

        if asl > osl:
            age_sample = age_sample[0:osl]
        elif osl > asl:
            offset_sample = offset_sample[0:asl]

        return age_sample, offset_sample

def sample_bounded_normal(mean, sd, n, sample_min=None, sample_max=None):

    sample = np.random.normal(mean, sd, n)
    sample = trim_distribution(sample, sample_min=sample_min,
                                       sample_max=sample_max)

    while len(sample) < n:
        next_sample = np.random.normal(mean, sd, n)
        next_sample = trim_distribution(next_sample, sample_min, sample_max)
        sample = np.hstack([sample, next_sample])

    return sample[:n]

def trim_distribution(sample, sample_min=None, sample_max=None):

    if sample_min is not None and sample_max is not None:
        if sample_min >= sample_max:
            raise Exception('min must be less than max!')

    if sample_min is not None:
        sample = sample[sample >= sample_min]

    if sample_max is not None:
        sample = sample[sample <= sample_max]

    return sample

def check_increasing(in_array):
    """Checks to see if array is monotonically increasing, returns bool value
    """

    dx = np.diff(in_array)

    return np.all(dx >= 0)

def get_log_pts(p_min, p_max, n_pts=50, base=np.e):
    """Generates n_pts length array of logarithmically spaced points"""
    if p_min == 0:
        pts_array = np.hstack([0, np.logspace(np.log(1e-5), np.log(p_max),
                                                num=n_pts-1, base=base)])
    else:
        pts_array = np.logspace(p_min, p_max, num=n_pts, base=base)
    return pts_array

def tspline_interpolate():
    pass

def calc_stats():
    pass
<commit_msg>added linear + piecewise linear fitting and BIC discrimination to slip_rate_tools.py<commit_after># -*- coding: utf-8 -*-
"""
Created on Thu Aug 30 14:00:54 2012

@author: Richard
"""

import numpy as np
#import Splines
from Splines import spline1d
from scipy.interpolate import interp1d
from scipy.optimize import minimize

def fit_history_spline(age_array, offset_array):

    return interp1d(age_array, offset_array)

def sample_slip_history(age_array, offset_array, time_array,
                        extend_time=False):

    history_spline = fit_history_spline(age_array, offset_array)

    if extend_time == False:
        time_array = time_array[time_array <= np.max(age_array)]
    elif extend_time == True:
        raise Exception('extrapolating not supported yet')

    return history_spline(time_array)

def inverse_transform_sample(vals, probs, n_samps, n_interp=1000, seed=False,
                            seed_val=69):
    pdf_range, pdf_vals = make_pdf(vals, probs, n_interp)
    cdf_range, cdf_vals = make_cdf(pdf_range, pdf_vals)

    cdf_interp = interp1d(cdf_vals, cdf_range)

    if seed == True:
        np.random.seed(seed_val)

    samps = np.random.rand(n_samps)

    return cdf_interp(samps)

def make_pdf(vals, probs, n_interp=1000):
    val_min = np.min(vals)
    val_max = np.max(vals)

    pdf_range = np.linspace(val_min, val_max, n_interp)

    pmf = interp1d(vals, probs)
    pmf_samples = pmf(pdf_range)
    pdf_vals = pmf_samples / np.sum(pmf_samples)

    return pdf_range, pdf_vals

def make_cdf(pdf_range, pdf_vals):
    return (pdf_range, np.cumsum(pdf_vals))

class OffsetMarker:
    """Represents an offset geologic marker.

    Attributes:
        offsets: list of possible offset distances for the given marker.
            If offset_type = normal, offsets = [mean, sd]
        offset_probs: list of probabilities of corresponding offset distances
        offset_dist_type: offset prob. distribution (normal, uniform, arbitrary)
        ages: list of possible ages for the given marker
        age_probs: list of probabilities of corresponding ages
        age_dist_type: age prob. distribution (normal, uniform, arbitrary)
        source: Source for information (e.g., what article, field campaign)

    """
    def __init__(self, offsets=np.array([]), offset_probs=None,
                 offset_vals=None, offset_mean=None, offset_median=None,
                 offset_sd=None, offset_mad=None,
                 offset_min=None, offset_max=None,
                 offset_seed=None,
                 offset_dist_type='unspecified', ages=np.array([]),
                 age_probs=None, age_vals=None,
                 age_mean=None, age_median=None, age_sd=None, age_mad=None,
                 age_min=None, age_max=None,
                 age_seed=None,
                 age_dist_type='unspecified',
                 source='None'):

            self.offsets = offsets
            self.offset_probs = offset_probs
            self.offset_vals = offset_vals
            self.offset_mean = offset_mean
            self.offset_median = offset_median
            self.offset_sd = offset_sd
            self.offset_mad = offset_mad
            self.offset_min = offset_min
            self.offset_max = offset_max

            if offset_dist_type != 'unspecified':
                self.offset_dist_type = offset_dist_type
            elif offset_dist_type == 'unspecified':
                if offset_mean is not None and offset_sd is not None:
                    self.offset_dist_type = 'normal'
                elif (offset_min is not None and offset_max is not None
                      and offset_sd == None):
                    self.offset_dist_type = 'uniform'
                elif offset_probs is not None and offset_vals is not None:
                    self.offset_dist_type = 'arbitrary'

            self.ages = ages
            self.age_probs = age_probs
            self.age_vals = age_vals
            self.age_mean = age_mean
            self.age_median = age_median
            self.age_sd = age_sd
            self.age_mad = age_mad
            self.age_min = age_min
            self.age_max = age_max

            if age_dist_type != 'unspecified':
                self.age_dist_type = age_dist_type
            elif age_dist_type == 'unspecified':
                if age_mean is not None and age_sd is not None:
                    self.age_dist_type = 'normal'
                elif (age_min is not None and age_max is not None
                      and age_sd == None):
                    self.age_dist_type = 'uniform'
                elif age_probs is not None and age_vals is not None:
                    self.age_dist_type == 'arbitrary'

            self.source = source

    def sample_offset_from_normal(self, n):
        """Generates n-length sample from normal distribution of offsets"""

        return sample_from_bounded_normal(self.offset_mean, self.offset_sd, n,
                                          self.offset_min, self.offset_max)

    def sample_offset_from_uniform(self, n):
        """Generates n-length sample from uniform distribution of ages"""

        return np.random.uniform(self.offset_min, self.offset_max, n)

    def sample_offset_from_arbitrary(self, n):
        """not supported yet"""
        offset_sample = inverse_transform_sample(self.offset_vals,
                                                 self.offset_probs, n)
        return offset_sample

    def sample_offset(self, n):
        """Generates n-length array of samples from distribution"""
        if self.offset_dist_type == 'normal':
            offset_sample = self.sample_offset_from_normal(n)

        elif self.offset_dist_type == 'uniform':
            offset_sample = self.sample_offset_from_uniform(n)

        elif self.offset_dist_type == 'arbitrary':
            offset_sample = self.sample_offset_from_arbitrary(n)

        else:
            print('What is the offset distribution type?')

        return offset_sample

    def sample_age_from_normal(self, n):
        """Generates n-length sample from normal distribution of ages"""
        if self.age_min:
            age_min = self.age_min
        else:
            age_min = 0.

        age_sample = sample_bounded_normal(self.age_mean, self.age_sd, n,
                                           age_min, self.age_max)

        return age_sample

    def sample_age_from_uniform(self, n):
        """Generates n-length sample from uniform distribution of ages"""
        age_sample = (np.random.rand(n) * 2 -1) * self.age_err + self.age_mean
        #TODO: change mean, err to min, max

        return age_sample

    def sample_age_from_arbitrary(self, n):
        """not supported yet"""
        age_sample = inverse_transform_sample(self.age_vals, self.age_probs, n)

        return age_sample

    def sample_age(self, n):
        """Generates n-length array of samples from distribution"""
        if self.age_dist_type == 'normal':
            age_sample = self.sample_age_from_normal(n)

        elif self.age_dist_type == 'uniform':
            age_sample = self.sample_age_from_uniform(n)

        elif self.age_dist_type == 'arbitrary':
            pass

        else:
            print('What is the age distribution type?')

        return age_sample

    def sample(self, n):
        age_sample = self.sample_age(n)
        offset_sample = self.sample_offset(n)

        asl = len(age_sample)
        osl = len(offset_sample)

        if asl > osl:
            age_sample = age_sample[0:osl]
        elif osl > asl:
            offset_sample = offset_sample[0:asl]

        return age_sample, offset_sample

def sample_bounded_normal(mean, sd, n, sample_min=None, sample_max=None):

    sample = np.random.normal(mean, sd, n)
    sample = trim_distribution(sample, sample_min=sample_min,
                                       sample_max=sample_max)

    while len(sample) < n:
        next_sample = np.random.normal(mean, sd, n)
        next_sample = trim_distribution(next_sample, sample_min, sample_max)
        sample = np.hstack([sample, next_sample])

    return sample[:n]

def trim_distribution(sample, sample_min=None, sample_max=None):

    if sample_min is not None and sample_max is not None:
        if sample_min >= sample_max:
            raise Exception('min must be less than max!')

    if sample_min is not None:
        sample = sample[sample >= sample_min]

    if sample_max is not None:
        sample = sample[sample <= sample_max]

    return sample

def check_increasing(in_array):
    """Checks to see if array is monotonically increasing, returns bool value
    """

    dx = np.diff(in_array)

    return np.all(dx >= 0)

def get_log_pts(p_min, p_max, n_pts=50, base=np.e):
    """Generates n_pts length array of logarithmically spaced points"""
    if p_min == 0:
        pts_array = np.hstack([0, np.logspace(np.log(1e-5), np.log(p_max),
                                                num=n_pts-1, base=base)])
    else:
        pts_array = np.logspace(p_min, p_max, num=n_pts, base=base)

    return pts_array

def tspline_interpolate():
    pass

def make_age_offset_arrays(offset_list, n, check_increasing=False,
                           zero_offset_age=0.):

    #TODO: use random seeding

    age_array = np.zeros((n, len(offset_list)+1))
    off_array = np.zeros((n, len(offset_list)+1))

    age_array[:,0] = zero_offset_age

    for i, off_mark in enumerate(offset_list):
        col = i+1
        age_array[:,col], off_array[:,col] = off_mark.sample(n)

    if check_increasing == True:

        def make_inc_bool(age_array, off_array, n):

            inc_bool = np.ones((age_array.shape[0]), dtype=int)
            for row in range(n):
                age_inc = check_increasing(age_array[row,:])
                off_inc = check_increasing(off_array[row,:])

                if not (age_inc and off_inc):
                    inc_bool[row] = 0

            inc_bool = np.array(inc_bool, dtype=bool)

            return inc_bool

        inc_bool = make_inc_bool(age_array, off_array, n)

        age_array = age_array[inc_bool, :]
        off_array = off_array[inc_bool, :]

        while age_array.shape[0] < n:

            next_age_array, next_off_array = make_age_offset_arrays(
                                                offset_list, n,
                                                check_increasing=False,
                                                zero_offset_age=zero_offset_age)

            next_inc_bool = make_inc_bool(next_age_array, next_off_array, n)

            next_age_array = next_age_array[next_inc_bool, :]
            next_off_array = next_off_array[next_inc_bool, :]

            off_array = np.vstack([off_array, next_off_array])
            age_array = np.vstack([age_array, next_age_array])

    return age_array[:n,:], off_array[:n,:]

def piece_lin_objective(params, x_data, y_data):
    '''docs

    Modified from a function by Andreas Hillboll on the StatsModels
    mailing list.
    '''
    y1 = 0.
    y2, y3, x2 = params
    x1, x3 = x_data[0], x_data[-1]
    Xbefore = y1 + (x_data - x1) * (y2 - y1) / (x2 - x1)
    Xafter = y2 + (x_data - x2) * (y3 - y2) / (x3 - x2)
    Xbreak = np.where(x_data <= x2, Xbefore, Xafter)
    return (ma.masked_invalid(Xbreak - y_data)**2).sum()

def piece_lin_opt(x_data, y_data):

    init_guesses = (np.mean(y_data), np.mean(y_data), np.mean(x_data))
    bounds = ((0, np.max(y_data)), (0., np.max(y_data)), (0., np.max(y_data)))

    res = minimize(piece_lin_objective, init_guesses, (x_data, y_data),
                   method="L-BFGS-B", bounds=bounds)

    sum_sq_err = piece_lin_objective(res.x, x_data, y_data)

    y2, y3, x2 = res.x

    slope1 = y2 / x2
    slope2 = ((y3 - y2) / (np.max(x_data) - x2))
    breakpoint = x2

    return slope1, slope2, breakpoint, sum_sq_err

def lin_fit(x_data, y_data):
    x = x_data[:,np.newaxis]
    m, _, _, _ = np.linalg.lstsq(x, y_data)
    m = m[0]

    sum_sq_err = ((y_data - (m * x_data))**2).sum()

    return m, sum_sq_erri

def log_like(sum_sq, n):

    return -n / 2 * np.log(sum_sq)

def BIC(log_like, n, p):

    return log_like - ( 0.5 * p * np.log(n / 2 * np.pi))
<|endoftext|>


<commit_before>version = "0.0.4"
<commit_msg>bumping version number<commit_after>version = "0.0.5"
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
#    Copyright 2015 Mirantis, Inc.
#
#    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.

from solar.core.log import log
from solar import errors

from solar.core.handlers.base import TempFileHandler

class Shell(TempFileHandler):
    def action(self, resource, action_name):
        action_file = self._compile_action_file(resource, action_name)
        log.debug('action_file: %s', action_file)

        action_file_name = '/tmp/{}.sh'.format(resource.name)
        self.prepare_templates_and_scripts(resource, action_name, '')
        self.transport_sync.copy(resource, action_file, action_file_name)
        self.transport_sync.sync_all()
        cmd = self.transport_run.run(
            resource,
            'bash', action_file_name,
            use_sudo=True,
            warn_only=True
        )

        if cmd.return_code:
            raise errors.SolarError(
                'Bash execution for {} failed with {}'.format(
                    resource.name, cmd.return_code))
        return cmd
<commit_msg>Sync in temp dirs<commit_after># -*- coding: utf-8 -*-
#    Copyright 2015 Mirantis, Inc.
#
#    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.

from solar.core.log import log
from solar import errors
import os

from solar.core.handlers.base import TempFileHandler

class Shell(TempFileHandler):
    def action(self, resource, action_name):
        action_file = self._compile_action_file(resource, action_name)
        log.debug('action_file: %s', action_file)

        action_file_name = os.path.join(self.dirs[resource.name], action_file)
        self._copy_templates_and_scripts(resource, action_name)

        self.transport_sync.copy(resource, self.dst, '/tmp')
        self.transport_sync.sync_all()

        cmd = self.transport_run.run(
            resource,
            'bash', action_file_name,
            use_sudo=True,
            warn_only=True
        )

        if cmd.return_code:
            raise errors.SolarError(
                'Bash execution for {} failed with {}'.format(
                    resource.name, cmd.return_code))
        return cmd
<|endoftext|>