<commit_before>"""
MakeMKV Auto Ripper

Uses MakeMKV to watch for movies inserted into DVD/BD Drives
Looks up movie title on IMDb for saving into seperate directory

Automaticly checks for existing directory/movie and will NOT overwrite existing
files or folders
Checks minimum length of video to ensure movie is ripped not previews or other
junk that happens to be on the DVD

This script can be run with a simple cron, every 5 minutes or so

DVD goes in > MakeMKV checks IMDb and gets a proper DVD name > MakeMKV Rips
DVD does not get ejected, maybe it will get added to later versions

Released under the MIT license
Copyright (c) 2012, Jason Millward

@category   misc
@version    $Id: 1.4, 2013-04-03 09:41:53 CST $;
@author     Jason Millward <jason@jcode.me>
@license    http://opensource.org/licenses/MIT

Enough with these comments, on to the code
"""

import os
import sys
import ConfigParser
from makemkv import makeMKV
from timer import Timer

DIR = os.path.dirname(os.path.realpath(__file__))
CONFIG_FILE = "%s/../settings.cfg" % DIR

"""
    read_value temp doc
"""
def read_value(key):
    config = ConfigParser.RawConfigParser()
    config.read(CONFIG_FILE)
    to_return = config.get('MAKEMKV', key)
    config = None
    return to_return

"""
    rip temp doc string
"""
def rip():
    mkv_save_path = read_value('save_path')
    mkv_min_length = read_value('min_length')
    mkv_cache_size = read_value('cache_MB')
    mkv_tmp_output = read_value('temp_output')
    use_handbrake = read_value('handbrake')

    mkv_api = makeMKV()

    if (mkv_api.findDisc(mkv_tmp_output)):
        movie_title = mkv_api.getTitle()

        print movie_title
        sys.exit()

        if not os.path.exists('%s/%s' % (mkv_save_path, movie_title)):
            os.makedirs('%s/%s' % (mkv_save_path, movie_title))

            stopwatch = Timer()

            if mkv_api.ripDisc(path=mkv_save_path,
                    length=mkv_min_length,
                    cache=mkv_cache_size,
                    queue=use_handbrake,
                    output=mkv_tmp_output):

                stopwatch.stop()

                print ("It took %s minutes to complete the ripping of %s"
                    %
                    (stopwatch.getTime(), movie_title))

            else:
                stopwatch.stop()
                print "MakeMKV did not did not complete successfully"

        else:
            print "Movie folder already exists, will not overwrite."

    else:
        print "Could not find valid DVD in drive list"

if __name__ == '__main__':
    rip()
<commit_msg>Refactor to comply with pep8 and pylint<commit_after>"""
MakeMKV Auto Ripper

Uses MakeMKV to watch for movies inserted into DVD/BD Drives
Looks up movie title on IMDb for saving into seperate directory

Automaticly checks for existing directory/movie and will NOT overwrite existing
files or folders
Checks minimum length of video to ensure movie is ripped not previews or other
junk that happens to be on the DVD

This script can be run with a simple cron, every 5 minutes or so

DVD goes in > MakeMKV checks IMDb and gets a proper DVD name > MakeMKV Rips
DVD does not get ejected, maybe it will get added to later versions

Released under the MIT license
Copyright (c) 2012, Jason Millward

@category   misc
@version    $Id: 1.4, 2013-04-03 09:41:53 CST $;
@author     Jason Millward <jason@jcode.me>
@license    http://opensource.org/licenses/MIT

Enough with these comments, on to the code
"""

import os
import sys
import ConfigParser
from makemkv import makeMKV
from timer import Timer

DIR = os.path.dirname(os.path.realpath(__file__))
CONFIG_FILE = "%s/../settings.cfg" % DIR

def read_value(key):
    """
    read_value temp docstring
    """
    config = ConfigParser.RawConfigParser()
    config.read(CONFIG_FILE)
    to_return = config.get('MAKEMKV', key)
    config = None
    return to_return

def rip():
    """
    rip temp docstring
    """
    mkv_save_path = read_value('save_path')
    mkv_min_length = read_value('min_length')
    mkv_cache_size = read_value('cache_MB')
    mkv_tmp_output = read_value('temp_output')
    use_handbrake = read_value('handbrake')

    mkv_api = makeMKV()

    if (mkv_api.findDisc(mkv_tmp_output)):
        movie_title = mkv_api.getTitle()

        print movie_title
        sys.exit()

        if not os.path.exists('%s/%s' % (mkv_save_path, movie_title)):
            os.makedirs('%s/%s' % (mkv_save_path, movie_title))

            stopwatch = Timer()

            if mkv_api.ripDisc(path=mkv_save_path,
                    length=mkv_min_length,
                    cache=mkv_cache_size,
                    queue=use_handbrake,
                    output=mkv_tmp_output):

                stopwatch.stop()

                print ("It took %s minutes to complete the ripping of %s"
                    %
                    (stopwatch.getTime(), movie_title))

            else:
                stopwatch.stop()
                print "MakeMKV did not did not complete successfully"

        else:
            print "Movie folder already exists, will not overwrite."

    else:
        print "Could not find valid DVD in drive list"

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


<commit_before>__version__ = "0.8.1"
<commit_msg>up minor version<commit_after>__version__ = "0.8.2"
<|endoftext|>


<commit_before>import random
import pygame
from gameobj import GameObj
from collision_aabb import CollisionAABB

# TODO add a CollisionAABB to the row. And, for that matter to the ball

class Row(GameObj):
    # Define some static vars that we'll use to initialize the collision geoms - types should be non-zero, because the CollisionAABB class initializes to 0
    COLLISION_TYPE_NONE = 0
    COLLISION_TYPE_ROW = 1
    COLLISION_TYPE_GAP = 2
    ''' A row of blocks.
    '''
    def __init__(self, numBlocks = 16, yPosition = 32, gap = -1, updateDelay = 1):
        super(Row, self).__init__()

        self._numBlocks = numBlocks # Prefer this number to be a factor of 64
        self._position[1] = yPosition # We really only care about the row's y position on the grid (x defaults to 0)
        self._drawRects = [None, None]
        self._collGeoms = [None, None, None] # geom[0] is the gap (used for scorekeeping), geom[1] is row block 1, geom[2] is row block 2 (if applicable)
        self._blockWidth = 64 / self._numBlocks # block width in terms of grid cells
        self._blockHeight = 2

        self.setGap(gap)

        self._updateDelay = 0.0
        self.setUpdateDelay(updateDelay) # Update delay in seconds

        self.setSize(64 / self._numBlocks, 2) # NOTE: Size here is PER BLOCK, in terms of grid cells. (TODO: You can probably delete blockWidth and blockHeight

    def draw(self, screen, cell_size):
        for rect in self._drawRects:
            if rect:
                pygame.draw.rect(screen, (128, 128, 128), rect)

        # DEBUG draw the collision geometry
        for geom in self._collGeoms:
            if geom:
                geom.draw(screen, cell_size)

    def _getRandomGap(self):
        return random.randint(0, self._numBlocks - 1)

    def setGap(self, gap):
        self._gap = self._getRandomGap() if gap == -1 else gap

    def getGap(self):
        return self._gap

    def setUpdateDelay(self, delay_s):
        self._updateDelay = delay_s

    def reInit(self, yPosition = 32, gap = -1):
        self._position[1] = yPosition # We really only care about the row's y position on the grid (x defaults to 0)
        # NOTE here, we simply set position; recomputation of render geometry and collision geometry is handled during the update step
        self.setGap(gap)

    def update(self, dt_s, cell_size):
        self._accumulator_s[1] += dt_s # NOTE _accumulator_s is part of the gameObj class.. Perhaps break it out to the ball? Because the ball needs a [x,y] accumulator; the rows only need a single value

        if self._accumulator_s[1] >= self._updateDelay:
            self._accumulator_s[1] -= self._updateDelay
            self._position[1] -= 1

            # Upon movement, recompute render and collision geometry
            # TODO: Fix - you're creating a totally new collision geom on every update.. That's wasteful. Instead, create the collision geom at the same time as the row is created
            self._computeRenderGeometry(cell_size)
            self._computeCollisionGeometry(cell_size)

    def _computeRenderGeometry(self, cell_size):
        if self._gap == 0:
            # Draw 1 row section
            sPt = [ (self._gap + 1) * self._size[0] * cell_size[0], self._position[1] * cell_size[1] ]
            ePt = [ sPt[0] + 63 * cell_size[0], sPt[1] + self._size[1] * cell_size[1] ]

            self._drawRects[0] = (sPt[0], sPt[1], ePt[0] - sPt[0], ePt[1] - sPt[1]) # Rects are defined as (left, top, width, height)

        elif self._gap == self._numBlocks - 1:
            # Draw 1 row section
            sPt = [ 0, self._position[1] * cell_size[1] ]
            ePt = [ sPt[0] + self._gap * self._size[0] * cell_size[0], sPt[1] + self._size[1] * cell_size[1] ]

            self._drawRects[0] = (sPt[0], sPt[1], ePt[0] - sPt[0], ePt[1] - sPt[1]) # Rects are defined as (left, top, width, height)
        else:
            # Draw 2 row sections
            sPt = [ 0, self._position[1] * cell_size[1] ]
            ePt = [ sPt[0] + self._gap * self._size[0] * cell_size[0], sPt[1] + self._size[1] * cell_size[1] ]
            self._drawRects[0] = (sPt[0], sPt[1], ePt[0] - sPt[0], ePt[1] - sPt[1]) # Rects are defined as (left, top, width, height)

            sPt = [ (self._gap + 1) * self._size[0] * cell_size[0], self._position[1] * cell_size[1] ]
            ePt = [ sPt[0] + (64 - (self._gap + 1) * self._size[0]) * cell_size[0], sPt[1] + self._size[1] * cell_size[1] ]
            self._drawRects[1] = (sPt[0], sPt[1], ePt[0] - sPt[0], ePt[1] - sPt[1]) # Rects are defined as (left, top, width, height)

    def _computeCollisionGeometry(self, cell_size):
        # NOTE: In this game, the AABB geometry is the same as the rendering geometry

        # NOTE: We make sure to put the gap in slot 0, so we can test for collisions with the ball against the gap 1st, before the row geoms

        # TODO Don't create new CollisionAABB's at every recomputation.. That stresses the garbage collector. Just reinitialize existing geoms. For geom[2], which may or may not be active, set to COLLISION_TYPE_NONE to tell game not to use it for anything

        # Also Note: You could have computed the collision geom based on the render geometry, but multiplying things is more fun
        self._collGeoms[0] = CollisionAABB()
        self._collGeoms[0]._type = Row.COLLISION_TYPE_GAP
        offset = 2 # Grid offset to put collision 'zone' for score keeping
        self._collGeoms[0]._minPt = [ (self._gap * self._size[0] * cell_size[0]) + cell_size[0], (self._position[1] + self._size[1] + offset) * cell_size[1] ]
        self._collGeoms[0]._maxPt = [ (self._gap * self._size[0] * cell_size[0]) + (self._size[0] - 1) * cell_size[0], (self._position[1] + self._size[1] + offset + 1) * cell_size[1] ]
        self._collGeoms[0].setPosition(self._getGridCoordFromScreenCoord(self._collGeoms[0]._minPt[0], cell_size), self._position[1] + self._size[1] + offset)
        self._collGeoms[0].setSize((self._collGeoms[0]._maxPt[0] - self._collGeoms[0]._minPt[0]) / cell_size[0], 1)
        #print "Gap: type:{} minPt:{} maxPt:{} pos:{} size:{}".format(self._collGeoms[0]._type, self._collGeoms[0]._minPt, self._collGeoms[0]._maxPt, self._collGeoms[0]._position, self._collGeoms[0]._size)

        if self._gap == 0 or self._gap == self._numBlocks - 1:
            self._collGeoms[1] = CollisionAABB()
            self._collGeoms[2] = None
            #self._collGeoms[0].setPosition(self._position[0], self._position[1])

            # NOTE: Here, we're totally cheating and computing the AABB based on the render geometry.
            # Note rect[0] = left; rect[1] = top; rect[2] = width; rect[3] = height
            self._collGeoms[1]._type = Row.COLLISION_TYPE_ROW
            self._collGeoms[1]._minPt = [ self._drawRects[0][0], self._drawRects[0][1] ]
            self._collGeoms[1]._maxPt = [ self._drawRects[0][0] + self._drawRects[0][2], self._drawRects[0][1] + self._drawRects[0][3] ]
            self._collGeoms[1].setPosition(self._getGridCoordFromScreenCoord(self._collGeoms[1]._minPt[0], cell_size), self._position[1])
            self._collGeoms[1].setSize(self._drawRects[0][2] / cell_size[0], self._size[1])
            #print "Row: type:{} minPt:{} maxPt:{} pos:{} size:{}".format(self._collGeoms[1]._type, self._collGeoms[1]._minPt, self._collGeoms[1]._maxPt, self._collGeoms[1]._position, self._collGeoms[1]._size)

        else:
            # Note: You ALWAYS will have at least 2 collision geom, so the if/else conditions could be different. But whatever.. :-D
            self._collGeoms[1] = CollisionAABB()
            self._collGeoms[2] = CollisionAABB()

            self._collGeoms[1]._type = Row.COLLISION_TYPE_ROW
            self._collGeoms[1]._minPt = [ self._drawRects[0][0], self._drawRects[0][1] ]
            self._collGeoms[1]._maxPt = [ self._drawRects[0][0] + self._drawRects[0][2], self._drawRects[0][1] + self._drawRects[0][3] ]
            self._collGeoms[1].setPosition(self._getGridCoordFromScreenCoord(self._collGeoms[1]._minPt[0], cell_size), self._position[1])
            self._collGeoms[1].setSize(self._drawRects[0][2] / cell_size[0], self._size[1])
            #print "Row: type:{} minPt:{} maxPt:{} pos:{} size:{}".format(self._collGeoms[1]._type, self._collGeoms[1]._minPt, self._collGeoms[1]._maxPt, self._collGeoms[1]._position, self._collGeoms[1]._size)

            self._collGeoms[2]._type = Row.COLLISION_TYPE_ROW
            self._collGeoms[2]._minPt = [ self._drawRects[1][0], self._drawRects[1][1] ]
            self._collGeoms[2]._maxPt = [ self._drawRects[1][0] + self._drawRects[1][2], self._drawRects[1][1] + self._drawRects[1][3] ]
            self._collGeoms[2].setPosition(self._getGridCoordFromScreenCoord(self._collGeoms[2]._minPt[0], cell_size), self._position[1])
            self._collGeoms[2].setSize(self._drawRects[1][2] / cell_size[0], self._size[1])
            #print "Row: type:{} minPt:{} maxPt:{} pos:{} size:{}".format(self._collGeoms[2]._type, self._collGeoms[2]._minPt, self._collGeoms[2]._maxPt, self._collGeoms[2]._position, self._collGeoms[2]._size)

        #print

    def _getGridCoordFromScreenCoord(self, coord, cell_size):
        return coord / cell_size[0] # Cells are square, so it doesn't matter which cell_size coordinate we use
<commit_msg>Changed gap collision geometry to be at the same y-level as the rest of the row. The current structure is what I thought I should have been able to do earlier in development. Fixing logic problems has made it possible to structure the row/gap collision geoms on the same y-level. Jyeaw. Now it's time to actually make a game out of all this code<commit_after>import random
import pygame
from gameobj import GameObj
from collision_aabb import CollisionAABB

# TODO add a CollisionAABB to the row. And, for that matter to the ball

class Row(GameObj):
    # Define some static vars that we'll use to initialize the collision geoms - types should be non-zero, because the CollisionAABB class initializes to 0
    COLLISION_TYPE_NONE = 0
    COLLISION_TYPE_ROW = 1
    COLLISION_TYPE_GAP = 2
    ''' A row of blocks.
    '''
    def __init__(self, numBlocks = 16, yPosition = 32, gap = -1, updateDelay = 1):
        super(Row, self).__init__()

        self._numBlocks = numBlocks # Prefer this number to be a factor of 64
        self._position[1] = yPosition # We really only care about the row's y position on the grid (x defaults to 0)
        self._drawRects = [None, None]
        self._collGeoms = [None, None, None] # geom[0] is the gap (used for scorekeeping), geom[1] is row block 1, geom[2] is row block 2 (if applicable)
        self._blockWidth = 64 / self._numBlocks # block width in terms of grid cells
        self._blockHeight = 2

        self.setGap(gap)

        self._updateDelay = 0.0
        self.setUpdateDelay(updateDelay) # Update delay in seconds

        self.setSize(64 / self._numBlocks, 2) # NOTE: Size here is PER BLOCK, in terms of grid cells. (TODO: You can probably delete blockWidth and blockHeight

    def draw(self, screen, cell_size):
        for rect in self._drawRects:
            if rect:
                pygame.draw.rect(screen, (128, 128, 128), rect)

        # DEBUG draw the collision geometry
        for geom in self._collGeoms:
            if geom:
                geom.draw(screen, cell_size)

    def _getRandomGap(self):
        return random.randint(0, self._numBlocks - 1)

    def setGap(self, gap):
        self._gap = self._getRandomGap() if gap == -1 else gap

    def getGap(self):
        return self._gap

    def setUpdateDelay(self, delay_s):
        self._updateDelay = delay_s

    def reInit(self, yPosition = 32, gap = -1):
        self._position[1] = yPosition # We really only care about the row's y position on the grid (x defaults to 0)
        # NOTE here, we simply set position; recomputation of render geometry and collision geometry is handled during the update step
        self.setGap(gap)

    def update(self, dt_s, cell_size):
        self._accumulator_s[1] += dt_s # NOTE _accumulator_s is part of the gameObj class.. Perhaps break it out to the ball? Because the ball needs a [x,y] accumulator; the rows only need a single value

        if self._accumulator_s[1] >= self._updateDelay:
            self._accumulator_s[1] -= self._updateDelay
            self._position[1] -= 1

            # Upon movement, recompute render and collision geometry
            # TODO: Fix - you're creating a totally new collision geom on every update.. That's wasteful. Instead, create the collision geom at the same time as the row is created
            self._computeRenderGeometry(cell_size)
            self._computeCollisionGeometry(cell_size)

    def _computeRenderGeometry(self, cell_size):
        if self._gap == 0:
            # Draw 1 row section
            sPt = [ (self._gap + 1) * self._size[0] * cell_size[0], self._position[1] * cell_size[1] ]
            ePt = [ sPt[0] + 63 * cell_size[0], sPt[1] + self._size[1] * cell_size[1] ]

            self._drawRects[0] = (sPt[0], sPt[1], ePt[0] - sPt[0], ePt[1] - sPt[1]) # Rects are defined as (left, top, width, height)

        elif self._gap == self._numBlocks - 1:
            # Draw 1 row section
            sPt = [ 0, self._position[1] * cell_size[1] ]
            ePt = [ sPt[0] + self._gap * self._size[0] * cell_size[0], sPt[1] + self._size[1] * cell_size[1] ]

            self._drawRects[0] = (sPt[0], sPt[1], ePt[0] - sPt[0], ePt[1] - sPt[1]) # Rects are defined as (left, top, width, height)
        else:
            # Draw 2 row sections
            sPt = [ 0, self._position[1] * cell_size[1] ]
            ePt = [ sPt[0] + self._gap * self._size[0] * cell_size[0], sPt[1] + self._size[1] * cell_size[1] ]
            self._drawRects[0] = (sPt[0], sPt[1], ePt[0] - sPt[0], ePt[1] - sPt[1]) # Rects are defined as (left, top, width, height)

            sPt = [ (self._gap + 1) * self._size[0] * cell_size[0], self._position[1] * cell_size[1] ]
            ePt = [ sPt[0] + (64 - (self._gap + 1) * self._size[0]) * cell_size[0], sPt[1] + self._size[1] * cell_size[1] ]
            self._drawRects[1] = (sPt[0], sPt[1], ePt[0] - sPt[0], ePt[1] - sPt[1]) # Rects are defined as (left, top, width, height)

    def _computeCollisionGeometry(self, cell_size):
        # NOTE: In this game, the AABB geometry is the same as the rendering geometry

        # NOTE: We make sure to put the gap in slot 0, so we can test for collisions with the ball against the gap 1st, before the row geoms

        # TODO Don't create new CollisionAABB's at every recomputation.. That stresses the garbage collector. Just reinitialize existing geoms. For geom[2], which may or may not be active, set to COLLISION_TYPE_NONE to tell game not to use it for anything

        # Also Note: You could have computed the collision geom based on the render geometry, but multiplying things is more fun
        self._collGeoms[0] = CollisionAABB()
        self._collGeoms[0]._type = Row.COLLISION_TYPE_GAP
        offset = 0 # Grid offset to put collision 'zone' for score keeping
        self._collGeoms[0]._minPt = [ (self._gap * self._size[0] * cell_size[0]) + cell_size[0], (self._position[1]) * cell_size[1] ]
        self._collGeoms[0]._maxPt = [ (self._gap * self._size[0] * cell_size[0]) + (self._size[0] - 1) * cell_size[0], (self._position[1] + self._size[1] + offset) * cell_size[1] ]
        self._collGeoms[0].setPosition(self._getGridCoordFromScreenCoord(self._collGeoms[0]._minPt[0], cell_size), self._position[1] + self._size[1] + offset)
        self._collGeoms[0].setSize((self._collGeoms[0]._maxPt[0] - self._collGeoms[0]._minPt[0]) / cell_size[0], 1)
        #print "Gap: type:{} minPt:{} maxPt:{} pos:{} size:{}".format(self._collGeoms[0]._type, self._collGeoms[0]._minPt, self._collGeoms[0]._maxPt, self._collGeoms[0]._position, self._collGeoms[0]._size)

        if self._gap == 0 or self._gap == self._numBlocks - 1:
            self._collGeoms[1] = CollisionAABB()
            self._collGeoms[2] = None
            #self._collGeoms[0].setPosition(self._position[0], self._position[1])

            # NOTE: Here, we're totally cheating and computing the AABB based on the render geometry.
            # Note rect[0] = left; rect[1] = top; rect[2] = width; rect[3] = height
            self._collGeoms[1]._type = Row.COLLISION_TYPE_ROW
            self._collGeoms[1]._minPt = [ self._drawRects[0][0], self._drawRects[0][1] ]
            self._collGeoms[1]._maxPt = [ self._drawRects[0][0] + self._drawRects[0][2], self._drawRects[0][1] + self._drawRects[0][3] ]
            self._collGeoms[1].setPosition(self._getGridCoordFromScreenCoord(self._collGeoms[1]._minPt[0], cell_size), self._position[1])
            self._collGeoms[1].setSize(self._drawRects[0][2] / cell_size[0], self._size[1])
            #print "Row: type:{} minPt:{} maxPt:{} pos:{} size:{}".format(self._collGeoms[1]._type, self._collGeoms[1]._minPt, self._collGeoms[1]._maxPt, self._collGeoms[1]._position, self._collGeoms[1]._size)

        else:
            # Note: You ALWAYS will have at least 2 collision geom, so the if/else conditions could be different. But whatever.. :-D
            self._collGeoms[1] = CollisionAABB()
            self._collGeoms[2] = CollisionAABB()

            self._collGeoms[1]._type = Row.COLLISION_TYPE_ROW
            self._collGeoms[1]._minPt = [ self._drawRects[0][0], self._drawRects[0][1] ]
            self._collGeoms[1]._maxPt = [ self._drawRects[0][0] + self._drawRects[0][2], self._drawRects[0][1] + self._drawRects[0][3] ]
            self._collGeoms[1].setPosition(self._getGridCoordFromScreenCoord(self._collGeoms[1]._minPt[0], cell_size), self._position[1])
            self._collGeoms[1].setSize(self._drawRects[0][2] / cell_size[0], self._size[1])
            #print "Row: type:{} minPt:{} maxPt:{} pos:{} size:{}".format(self._collGeoms[1]._type, self._collGeoms[1]._minPt, self._collGeoms[1]._maxPt, self._collGeoms[1]._position, self._collGeoms[1]._size)

            self._collGeoms[2]._type = Row.COLLISION_TYPE_ROW
            self._collGeoms[2]._minPt = [ self._drawRects[1][0], self._drawRects[1][1] ]
            self._collGeoms[2]._maxPt = [ self._drawRects[1][0] + self._drawRects[1][2], self._drawRects[1][1] + self._drawRects[1][3] ]
            self._collGeoms[2].setPosition(self._getGridCoordFromScreenCoord(self._collGeoms[2]._minPt[0], cell_size), self._position[1])
            self._collGeoms[2].setSize(self._drawRects[1][2] / cell_size[0], self._size[1])
            #print "Row: type:{} minPt:{} maxPt:{} pos:{} size:{}".format(self._collGeoms[2]._type, self._collGeoms[2]._minPt, self._collGeoms[2]._maxPt, self._collGeoms[2]._position, self._collGeoms[2]._size)

        #print

    def _getGridCoordFromScreenCoord(self, coord, cell_size):
        return coord / cell_size[0] # Cells are square, so it doesn't matter which cell_size coordinate we use
<|endoftext|>


<commit_before># coding: utf-8
"""Main stb-tester python module. Intended to be used with `stbt run`.

See `man stbt` and http://stb-tester.com for documentation.

Copyright 2012-2013 YouView TV Ltd and contributors.
Copyright 2013-2015 stb-tester.com Ltd.
License: LGPL v2.1 or (at your option) any later version (see
https://github.com/stb-tester/stb-tester/blob/master/LICENSE for details).
"""

from __future__ import absolute_import

import _stbt.core
from _stbt.core import \
    as_precondition, \
    debug, \
    get_config, \
    ConfigurationError, \
    MatchParameters, \
    MatchResult, \
    MatchTimeout, \
    MotionResult, \
    MotionTimeout, \
    NoVideo, \
    OcrMode, \
    Position, \
    PreconditionError, \
    Region, \
    save_frame, \
    TextMatchResult, \
    UITestError, \
    UITestFailure, \
    wait_until

__all__ = [
    "as_precondition",
    "ConfigurationError",
    "debug",
    "detect_match",
    "detect_motion",
    "draw_text",
    "frames",
    "get_config",
    "get_frame",
    "is_screen_black",
    "match",
    "match_text",
    "MatchParameters",
    "MatchResult",
    "MatchTimeout",
    "MotionResult",
    "MotionTimeout",
    "NoVideo",
    "ocr",
    "OcrMode",
    "Position",
    "PreconditionError",
    "press",
    "press_until_match",
    "Region",
    "save_frame",
    "TextMatchResult",
    "UITestError",
    "UITestFailure",
    "wait_for_match",
    "wait_for_motion",
    "wait_until",
]

_dut = _stbt.core.DeviceUnderTest()

# Functions available to stbt scripts
# ===========================================================================

def press(key, interpress_delay_secs=None):
    """Send the specified key-press to the system under test.

    :param str key:
        The name of the key/button (as specified in your remote-control
        configuration file).

    :type interpress_delay_secs: int or float
    :param interpress_delay_secs:
        The minimum time to wait after a previous key-press, in order to
        accommodate the responsiveness of the device-under-test.

        This defaults to 0.3. You can override the global default value by
        setting ``interpress_delay_secs`` in the ``[press]`` section of
        stbt.conf.
    """
    return _dut.press(key, interpress_delay_secs)

def draw_text(text, duration_secs=3):
    """Write the specified text to the output video.

    :param str text: The text to write.

    :param duration_secs: The number of seconds to display the text.
    :type duration_secs: int or float
    """
    return _dut.draw_text(text, duration_secs)

def match(image, frame=None, match_parameters=None, region=Region.ALL):
    """
    Search for an image in a single video frame.

    :type image: string or numpy.ndarray
    :param image:
      The image to search for. It can be the filename of a png file on disk, or
      a numpy array containing the pixel data in 8-bit BGR format.

      8-bit BGR numpy arrays are the same format that OpenCV uses for images.
      This allows generating templates on the fly (possibly using OpenCV) or
      searching for images captured from the system-under-test earlier in the
      test script.

    :param numpy.ndarray frame:
      If this is specified it is used as the video frame to search in;
      otherwise a new frame is grabbed from the system-under-test. This is an
      image in OpenCV format (for example as returned by `frames` and
      `get_frame`).

    :param match_parameters:
      Customise the image matching algorithm. See `MatchParameters` for details.
    :type match_parameters: `MatchParameters`

    :param region:
      Only search within the specified region of the video frame.
    :type region: `Region`

    :returns:
      A `MatchResult`, which will evaluate to true if a match was found,
      false otherwise.
    """
    return _dut.match(image, frame, match_parameters, region)

def detect_match(image, timeout_secs=10, match_parameters=None):
    """Generator that yields a sequence of one `MatchResult` for each frame
    processed from the system-under-test's video stream.

    `image` is the image used as the template during matching.  See `stbt.match`
    for more information.

    Returns after `timeout_secs` seconds. (Note that the caller can also choose
    to stop iterating over this function's results at any time.)

    Specify `match_parameters` to customise the image matching algorithm. See
    the documentation for `MatchParameters` for details.
    """
    return _dut.detect_match(image, timeout_secs, match_parameters)

def detect_motion(timeout_secs=10, noise_threshold=None, mask=None):
    """Generator that yields a sequence of one `MotionResult` for each frame
    processed from the system-under-test's video stream.

    The `MotionResult` indicates whether any motion was detected -- that is,
    any difference between two consecutive frames.

    :type timeout_secs: int or float or None
    :param timeout_secs:
        A timeout in seconds. After this timeout the iterator will be exhausted.
        Thas is, a ``for`` loop like ``for m in detect_motion(timeout_secs=10)``
        will terminate after 10 seconds. If ``timeout_secs`` is ``None`` then
        the iterator will yield frames forever. Note that you can stop
        iterating (for example with ``break``) at any time.

    :param float noise_threshold:
        The amount of noise to ignore. This is only useful with noisy analogue
        video sources. Valid values range from 0 (all differences are
        considered noise; a value of 0 will never report motion) to 1.0 (any
        difference is considered motion).

        This defaults to 0.84. You can override the global default value by
        setting ``noise_threshold`` in the ``[motion]`` section of stbt.conf.

    :param str mask:
        The filename of a black & white image that specifies which part of the
        image to search for motion. White pixels select the area to search;
        black pixels select the area to ignore.
    """
    return _dut.detect_motion(timeout_secs, noise_threshold, mask)

def wait_for_match(image, timeout_secs=10, consecutive_matches=1,
                   match_parameters=None):
    """Search for an image in the system-under-test's video stream.

    :param image: The image to search for. See `match`.

    :type timeout_secs: int or float or None
    :param timeout_secs:
        A timeout in seconds. This function will raise `MatchTimeout` if no
        match is found within this time.

    :param int consecutive_matches:
        Forces this function to wait for several consecutive frames with a
        match found at the same x,y position. Increase ``consecutive_matches``
        to avoid false positives due to noise, or to wait for a moving
        selection to stop moving.

    :param match_parameters: See `match`.

    :returns: `MatchResult` when the image is found.
    :raises: `MatchTimeout` if no match is found after ``timeout_secs`` seconds.
    """
    return _dut.wait_for_match(
        image, timeout_secs, consecutive_matches, match_parameters)

def press_until_match(
        key,
        image,
        interval_secs=None,
        max_presses=None,
        match_parameters=None):
    """Call `press` as many times as necessary to find the specified image.

    :param key: See `press`.

    :param image: See `match`.

    :type interval_secs: int or float
    :param interval_secs:
        The number of seconds to wait for a match before pressing again.
        Defaults to 3.

        You can override the global default value by setting ``interval_secs``
        in the ``[press_until_match]`` section of stbt.conf.

    :param int max_presses:
        The number of times to try pressing the key and looking for the image
        before giving up and raising `MatchTimeout`. Defaults to 10.

        You can override the global default value by setting ``max_presses``
        in the ``[press_until_match]`` section of stbt.conf.

    :param match_parameters: See `match`.

    :returns: `MatchResult` when the image is found.
    :raises: `MatchTimeout` if no match is found after ``timeout_secs`` seconds.
    """
    return _dut.press_until_match(
        key, image, interval_secs, max_presses, match_parameters)

def wait_for_motion(
        timeout_secs=10, consecutive_frames=None,
        noise_threshold=None, mask=None):
    """Search for motion in the system-under-test's video stream.

    "Motion" is difference in pixel values between two consecutive frames.

    :type timeout_secs: int or float or None
    :param timeout_secs:
        A timeout in seconds. This function will raise `MotionTimeout` if no
        motion is detected within this time.

    :type consecutive_frames: int or str
    :param consecutive_frames:
        Considers the video stream to have motion if there were differences
        between the specified number of consecutive frames. This can be:

        * a positive integer value, or
        * a string in the form "x/y", where "x" is the number of frames with
          motion detected out of a sliding window of "y" frames.

        This defaults to "10/20". You can override the global default value by
        setting ``consecutive_frames`` in the ``[motion]`` section of stbt.conf.

    :param float noise_threshold: See `detect_motion`.

    :param str mask: See `detect_motion`.

    :returns: `MotionResult` when motion is detected.
    :raises: `MotionTimeout` if no motion is detected after ``timeout_secs``
        seconds.
    """
    return _dut.wait_for_motion(
        timeout_secs, consecutive_frames, noise_threshold, mask)

def ocr(frame=None, region=Region.ALL,
        mode=OcrMode.PAGE_SEGMENTATION_WITHOUT_OSD,
        lang="eng", tesseract_config=None, tesseract_user_words=None,
        tesseract_user_patterns=None):
    r"""Return the text present in the video frame as a Unicode string.

    Perform OCR (Optical Character Recognition) using the "Tesseract"
    open-source OCR engine.

    :param frame:
        The video frame to process. If not specified, take a frame from the
        system-under-test.

    :param region: Only search within the specified region of the video frame.
    :type region: `Region`

    :param mode: Tesseract's layout analysis mode.
    :type mode: `OcrMode`

    :param str lang:
        The three-letter
        `ISO-639-3 <http://www.loc.gov/standards/iso639-2/php/code_list.php>`_
        language code of the language you are attempting to read; for example
        "eng" for English or "deu" for German. More than one language can be
        specified by joining with '+'; for example "eng+deu" means that the
        text to be read may be in a mixture of English and German. Defaults to
        English.

    :param dict tesseract_config:
        Allows passing configuration down to the underlying OCR engine.
        See the `tesseract documentation
        <https://code.google.com/p/tesseract-ocr/wiki/ControlParams>`_
        for details.

    :type tesseract_user_words: list of unicode strings
    :param tesseract_user_words:
        List of words to be added to the tesseract dictionary. To replace the
        tesseract system dictionary altogether, also set
        ``tesseract_config={'load_system_dawg': False, 'load_freq_dawg':
        False}``.

    :type tesseract_user_patterns: list of unicode strings
    :param tesseract_user_patterns:
        List of patterns to add to the tesseract dictionary. The tesseract
        pattern language corresponds roughly to the following regular
        expressions::

            tesseract  regex
            =========  ===========
            \c         [a-zA-Z]
            \d         [0-9]
            \n         [a-zA-Z0-9]
            \p         [:punct:]
            \a         [a-z]
            \A         [A-Z]
            \*         *

    """
    return _dut.ocr(frame, region, mode, lang, tesseract_config,
                    tesseract_user_words, tesseract_user_patterns)

def match_text(text, frame=None, region=Region.ALL,
               mode=OcrMode.PAGE_SEGMENTATION_WITHOUT_OSD, lang="eng",
               tesseract_config=None):
    """Search for the specified text in a single video frame.

    This can be used as an alternative to `match`, searching for text instead
    of an image.

    :param unicode text: The text to search for.
    :param frame: See `ocr`.
    :param region: See `ocr`.
    :param mode: See `ocr`.
    :param lang: See `ocr`.
    :param tesseract_config: See `ocr`.

    :returns:
      A `TextMatchResult`, which will evaluate to True if the text was found,
      false otherwise.

    For example, to select a button in a vertical menu by name (in this case
    "TV Guide")::

        m = stbt.match_text("TV Guide")
        assert m.match
        while not stbt.match('selected-button.png').region.contains(m.region):
            stbt.press('KEY_DOWN')

    """
    return _dut.match_text(
        text, frame, region, mode, lang, tesseract_config)

def frames(timeout_secs=None):
    """Generator that yields video frames captured from the system-under-test.

    :type timeout_secs: int or float or None
    :param timeout_secs:
      A timeout in seconds. After this timeout the iterator will be exhausted.
      That is, a ``for`` loop like ``for f, t in frames(timeout_secs=10)`` will
      terminate after 10 seconds. If ``timeout_secs`` is ``None`` (the default)
      then the iterator will yield frames forever. Note that you can stop
      iterating (for example with ``break``) at any time.

    :returns:
      An ``(image, timestamp)`` tuple for each video frame, where ``image`` is
      a `numpy.ndarray` object (that is, an OpenCV image).
    """
    return _dut.frames(timeout_secs)

def get_frame():
    """:returns: The latest video frame in OpenCV format (`numpy.ndarray`)."""
    return _dut.get_frame()

def is_screen_black(frame=None, mask=None, threshold=None):
    """Check for the presence of a black screen in a video frame.

    :param numpy.ndarray frame:
      If this is specified it is used as the video frame to check; otherwise a
      new frame is grabbed from the system-under-test. This is an image in
      OpenCV format (for example as returned by `frames` and `get_frame`).

    :param str mask:
      The filename of a black & white image mask. It must have white pixels for
      parts of the frame to check and black pixels for any parts to ignore.

    :param int threshold:
      Even when a video frame appears to be black, the intensity of its pixels
      is not always 0. To differentiate almost-black from non-black pixels, a
      binary threshold is applied to the frame. The `threshold` value is in the
      range 0 (black) to 255 (white). The global default can be changed by
      setting `threshold` in the `[is_screen_black]` section of stbt.conf.
    """
    return _dut.is_screen_black(frame, mask, threshold)

def init_run(
        gst_source_pipeline, gst_sink_pipeline, control_uri, save_video=False,
        restart_source=False, transformation_pipeline='identity'):
    global _dut
    _dut = _stbt.core.new_device_under_test_from_config(
        gst_source_pipeline, gst_sink_pipeline, control_uri, save_video,
        restart_source, transformation_pipeline)
    _dut.__enter__()

def teardown_run():
    _dut.__exit__(None, None, None)
<commit_msg>stbt.init_run(): Don't leave _dut in inconsistent state on error<commit_after># coding: utf-8
"""Main stb-tester python module. Intended to be used with `stbt run`.

See `man stbt` and http://stb-tester.com for documentation.

Copyright 2012-2013 YouView TV Ltd and contributors.
Copyright 2013-2015 stb-tester.com Ltd.
License: LGPL v2.1 or (at your option) any later version (see
https://github.com/stb-tester/stb-tester/blob/master/LICENSE for details).
"""

from __future__ import absolute_import

import _stbt.core
from _stbt.core import \
    as_precondition, \
    debug, \
    get_config, \
    ConfigurationError, \
    MatchParameters, \
    MatchResult, \
    MatchTimeout, \
    MotionResult, \
    MotionTimeout, \
    NoVideo, \
    OcrMode, \
    Position, \
    PreconditionError, \
    Region, \
    save_frame, \
    TextMatchResult, \
    UITestError, \
    UITestFailure, \
    wait_until

__all__ = [
    "as_precondition",
    "ConfigurationError",
    "debug",
    "detect_match",
    "detect_motion",
    "draw_text",
    "frames",
    "get_config",
    "get_frame",
    "is_screen_black",
    "match",
    "match_text",
    "MatchParameters",
    "MatchResult",
    "MatchTimeout",
    "MotionResult",
    "MotionTimeout",
    "NoVideo",
    "ocr",
    "OcrMode",
    "Position",
    "PreconditionError",
    "press",
    "press_until_match",
    "Region",
    "save_frame",
    "TextMatchResult",
    "UITestError",
    "UITestFailure",
    "wait_for_match",
    "wait_for_motion",
    "wait_until",
]

_dut = _stbt.core.DeviceUnderTest()

# Functions available to stbt scripts
# ===========================================================================

def press(key, interpress_delay_secs=None):
    """Send the specified key-press to the system under test.

    :param str key:
        The name of the key/button (as specified in your remote-control
        configuration file).

    :type interpress_delay_secs: int or float
    :param interpress_delay_secs:
        The minimum time to wait after a previous key-press, in order to
        accommodate the responsiveness of the device-under-test.

        This defaults to 0.3. You can override the global default value by
        setting ``interpress_delay_secs`` in the ``[press]`` section of
        stbt.conf.
    """
    return _dut.press(key, interpress_delay_secs)

def draw_text(text, duration_secs=3):
    """Write the specified text to the output video.

    :param str text: The text to write.

    :param duration_secs: The number of seconds to display the text.
    :type duration_secs: int or float
    """
    return _dut.draw_text(text, duration_secs)

def match(image, frame=None, match_parameters=None, region=Region.ALL):
    """
    Search for an image in a single video frame.

    :type image: string or numpy.ndarray
    :param image:
      The image to search for. It can be the filename of a png file on disk, or
      a numpy array containing the pixel data in 8-bit BGR format.

      8-bit BGR numpy arrays are the same format that OpenCV uses for images.
      This allows generating templates on the fly (possibly using OpenCV) or
      searching for images captured from the system-under-test earlier in the
      test script.

    :param numpy.ndarray frame:
      If this is specified it is used as the video frame to search in;
      otherwise a new frame is grabbed from the system-under-test. This is an
      image in OpenCV format (for example as returned by `frames` and
      `get_frame`).

    :param match_parameters:
      Customise the image matching algorithm. See `MatchParameters` for details.
    :type match_parameters: `MatchParameters`

    :param region:
      Only search within the specified region of the video frame.
    :type region: `Region`

    :returns:
      A `MatchResult`, which will evaluate to true if a match was found,
      false otherwise.
    """
    return _dut.match(image, frame, match_parameters, region)

def detect_match(image, timeout_secs=10, match_parameters=None):
    """Generator that yields a sequence of one `MatchResult` for each frame
    processed from the system-under-test's video stream.

    `image` is the image used as the template during matching.  See `stbt.match`
    for more information.

    Returns after `timeout_secs` seconds. (Note that the caller can also choose
    to stop iterating over this function's results at any time.)

    Specify `match_parameters` to customise the image matching algorithm. See
    the documentation for `MatchParameters` for details.
    """
    return _dut.detect_match(image, timeout_secs, match_parameters)

def detect_motion(timeout_secs=10, noise_threshold=None, mask=None):
    """Generator that yields a sequence of one `MotionResult` for each frame
    processed from the system-under-test's video stream.

    The `MotionResult` indicates whether any motion was detected -- that is,
    any difference between two consecutive frames.

    :type timeout_secs: int or float or None
    :param timeout_secs:
        A timeout in seconds. After this timeout the iterator will be exhausted.
        Thas is, a ``for`` loop like ``for m in detect_motion(timeout_secs=10)``
        will terminate after 10 seconds. If ``timeout_secs`` is ``None`` then
        the iterator will yield frames forever. Note that you can stop
        iterating (for example with ``break``) at any time.

    :param float noise_threshold:
        The amount of noise to ignore. This is only useful with noisy analogue
        video sources. Valid values range from 0 (all differences are
        considered noise; a value of 0 will never report motion) to 1.0 (any
        difference is considered motion).

        This defaults to 0.84. You can override the global default value by
        setting ``noise_threshold`` in the ``[motion]`` section of stbt.conf.

    :param str mask:
        The filename of a black & white image that specifies which part of the
        image to search for motion. White pixels select the area to search;
        black pixels select the area to ignore.
    """
    return _dut.detect_motion(timeout_secs, noise_threshold, mask)

def wait_for_match(image, timeout_secs=10, consecutive_matches=1,
                   match_parameters=None):
    """Search for an image in the system-under-test's video stream.

    :param image: The image to search for. See `match`.

    :type timeout_secs: int or float or None
    :param timeout_secs:
        A timeout in seconds. This function will raise `MatchTimeout` if no
        match is found within this time.

    :param int consecutive_matches:
        Forces this function to wait for several consecutive frames with a
        match found at the same x,y position. Increase ``consecutive_matches``
        to avoid false positives due to noise, or to wait for a moving
        selection to stop moving.

    :param match_parameters: See `match`.

    :returns: `MatchResult` when the image is found.
    :raises: `MatchTimeout` if no match is found after ``timeout_secs`` seconds.
    """
    return _dut.wait_for_match(
        image, timeout_secs, consecutive_matches, match_parameters)

def press_until_match(
        key,
        image,
        interval_secs=None,
        max_presses=None,
        match_parameters=None):
    """Call `press` as many times as necessary to find the specified image.

    :param key: See `press`.

    :param image: See `match`.

    :type interval_secs: int or float
    :param interval_secs:
        The number of seconds to wait for a match before pressing again.
        Defaults to 3.

        You can override the global default value by setting ``interval_secs``
        in the ``[press_until_match]`` section of stbt.conf.

    :param int max_presses:
        The number of times to try pressing the key and looking for the image
        before giving up and raising `MatchTimeout`. Defaults to 10.

        You can override the global default value by setting ``max_presses``
        in the ``[press_until_match]`` section of stbt.conf.

    :param match_parameters: See `match`.

    :returns: `MatchResult` when the image is found.
    :raises: `MatchTimeout` if no match is found after ``timeout_secs`` seconds.
    """
    return _dut.press_until_match(
        key, image, interval_secs, max_presses, match_parameters)

def wait_for_motion(
        timeout_secs=10, consecutive_frames=None,
        noise_threshold=None, mask=None):
    """Search for motion in the system-under-test's video stream.

    "Motion" is difference in pixel values between two consecutive frames.

    :type timeout_secs: int or float or None
    :param timeout_secs:
        A timeout in seconds. This function will raise `MotionTimeout` if no
        motion is detected within this time.

    :type consecutive_frames: int or str
    :param consecutive_frames:
        Considers the video stream to have motion if there were differences
        between the specified number of consecutive frames. This can be:

        * a positive integer value, or
        * a string in the form "x/y", where "x" is the number of frames with
          motion detected out of a sliding window of "y" frames.

        This defaults to "10/20". You can override the global default value by
        setting ``consecutive_frames`` in the ``[motion]`` section of stbt.conf.

    :param float noise_threshold: See `detect_motion`.

    :param str mask: See `detect_motion`.

    :returns: `MotionResult` when motion is detected.
    :raises: `MotionTimeout` if no motion is detected after ``timeout_secs``
        seconds.
    """
    return _dut.wait_for_motion(
        timeout_secs, consecutive_frames, noise_threshold, mask)

def ocr(frame=None, region=Region.ALL,
        mode=OcrMode.PAGE_SEGMENTATION_WITHOUT_OSD,
        lang="eng", tesseract_config=None, tesseract_user_words=None,
        tesseract_user_patterns=None):
    r"""Return the text present in the video frame as a Unicode string.

    Perform OCR (Optical Character Recognition) using the "Tesseract"
    open-source OCR engine.

    :param frame:
        The video frame to process. If not specified, take a frame from the
        system-under-test.

    :param region: Only search within the specified region of the video frame.
    :type region: `Region`

    :param mode: Tesseract's layout analysis mode.
    :type mode: `OcrMode`

    :param str lang:
        The three-letter
        `ISO-639-3 <http://www.loc.gov/standards/iso639-2/php/code_list.php>`_
        language code of the language you are attempting to read; for example
        "eng" for English or "deu" for German. More than one language can be
        specified by joining with '+'; for example "eng+deu" means that the
        text to be read may be in a mixture of English and German. Defaults to
        English.

    :param dict tesseract_config:
        Allows passing configuration down to the underlying OCR engine.
        See the `tesseract documentation
        <https://code.google.com/p/tesseract-ocr/wiki/ControlParams>`_
        for details.

    :type tesseract_user_words: list of unicode strings
    :param tesseract_user_words:
        List of words to be added to the tesseract dictionary. To replace the
        tesseract system dictionary altogether, also set
        ``tesseract_config={'load_system_dawg': False, 'load_freq_dawg':
        False}``.

    :type tesseract_user_patterns: list of unicode strings
    :param tesseract_user_patterns:
        List of patterns to add to the tesseract dictionary. The tesseract
        pattern language corresponds roughly to the following regular
        expressions::

            tesseract  regex
            =========  ===========
            \c         [a-zA-Z]
            \d         [0-9]
            \n         [a-zA-Z0-9]
            \p         [:punct:]
            \a         [a-z]
            \A         [A-Z]
            \*         *

    """
    return _dut.ocr(frame, region, mode, lang, tesseract_config,
                    tesseract_user_words, tesseract_user_patterns)

def match_text(text, frame=None, region=Region.ALL,
               mode=OcrMode.PAGE_SEGMENTATION_WITHOUT_OSD, lang="eng",
               tesseract_config=None):
    """Search for the specified text in a single video frame.

    This can be used as an alternative to `match`, searching for text instead
    of an image.

    :param unicode text: The text to search for.
    :param frame: See `ocr`.
    :param region: See `ocr`.
    :param mode: See `ocr`.
    :param lang: See `ocr`.
    :param tesseract_config: See `ocr`.

    :returns:
      A `TextMatchResult`, which will evaluate to True if the text was found,
      false otherwise.

    For example, to select a button in a vertical menu by name (in this case
    "TV Guide")::

        m = stbt.match_text("TV Guide")
        assert m.match
        while not stbt.match('selected-button.png').region.contains(m.region):
            stbt.press('KEY_DOWN')

    """
    return _dut.match_text(
        text, frame, region, mode, lang, tesseract_config)

def frames(timeout_secs=None):
    """Generator that yields video frames captured from the system-under-test.

    :type timeout_secs: int or float or None
    :param timeout_secs:
      A timeout in seconds. After this timeout the iterator will be exhausted.
      That is, a ``for`` loop like ``for f, t in frames(timeout_secs=10)`` will
      terminate after 10 seconds. If ``timeout_secs`` is ``None`` (the default)
      then the iterator will yield frames forever. Note that you can stop
      iterating (for example with ``break``) at any time.

    :returns:
      An ``(image, timestamp)`` tuple for each video frame, where ``image`` is
      a `numpy.ndarray` object (that is, an OpenCV image).
    """
    return _dut.frames(timeout_secs)

def get_frame():
    """:returns: The latest video frame in OpenCV format (`numpy.ndarray`)."""
    return _dut.get_frame()

def is_screen_black(frame=None, mask=None, threshold=None):
    """Check for the presence of a black screen in a video frame.

    :param numpy.ndarray frame:
      If this is specified it is used as the video frame to check; otherwise a
      new frame is grabbed from the system-under-test. This is an image in
      OpenCV format (for example as returned by `frames` and `get_frame`).

    :param str mask:
      The filename of a black & white image mask. It must have white pixels for
      parts of the frame to check and black pixels for any parts to ignore.

    :param int threshold:
      Even when a video frame appears to be black, the intensity of its pixels
      is not always 0. To differentiate almost-black from non-black pixels, a
      binary threshold is applied to the frame. The `threshold` value is in the
      range 0 (black) to 255 (white). The global default can be changed by
      setting `threshold` in the `[is_screen_black]` section of stbt.conf.
    """
    return _dut.is_screen_black(frame, mask, threshold)

def init_run(
        gst_source_pipeline, gst_sink_pipeline, control_uri, save_video=False,
        restart_source=False, transformation_pipeline='identity'):
    global _dut
    dut = _stbt.core.new_device_under_test_from_config(
        gst_source_pipeline, gst_sink_pipeline, control_uri, save_video,
        restart_source, transformation_pipeline)
    dut.__enter__()
    _dut = dut

def teardown_run():
    _dut.__exit__(None, None, None)
<|endoftext|>


<commit_before>import numpy as np
import matplotlib.pyplot as plt
import wget
import h5py
from K2pgram import K2pgram
import fitsio

def sigma_clipping(x, y, low, high):
    # running median with 100 points
    N = 100
    nsections = len(x)/N + 1
    inds = range(0, nsections*100, 100)

    # middle bit
    meds = []
    for i, ind0 in enumerate(inds):
        ind1 = ind0 + N
        sx, sy = x[ind0:ind1], y[ind0:ind1]
        med, std = np.median(sy[np.isfinite(sy)]), np.std(sy[np.isfinite(sy)])
        m = (med - std*low < sy) * (sy < med + std*high)
        x[ind0:ind1][~m] = np.nan
        y[ind0:ind1][~m] = np.nan
        meds.append(med)

    # end bit
    sx, sy = x[inds[-1]:], y[inds[-1]:]
    med, std = np.median(sy[np.isfinite(sy)]), np.std(sy[np.isfinite(sy)])
    m = (sy < med - std*low) * (med + std*high < sy)
    x[inds[-1]:][~m] = np.nan
    y[inds[-1]:][~m] = np.nan

    # get rid of initial dip
    clip = 170
    y[:clip], x[:clip] = np.ones(clip)*np.nan, np.ones(clip)*np.nan

    return x, y

def load_data(id):
        print "loading data"
        fname = "ktwo%s-c01_lpd-lc.fits" % id
        data = fitsio.read(fname)
        aps = fitsio.read(fname, 2)
        y = data["flux"][:, np.argmin(aps["cdpp6"])]
        x = data["time"]
        q = data["quality"]

        # sigma clip
#         x, y = sigma_clipping(x, y, 4, 4)
        l = np.isfinite(y) * np.isfinite(x) * (q==0)
        y, x = y[l], x[l]

        MAD = np.median(y - np.median(y))
        x *= 24*3600

        print "load basis"
        with h5py.File("../data/c1.h5", "r") as f:
            basis = f["basis"][:150, l]

        return x, y, basis

def list_SIP(epids):
    for id in epids:
        print id

        x, y, basis = load_data(id)
        med = np.median(y)
        y = y/med - 1

        plt.clf()
        plt.plot(x, y, "k.")
        plt.savefig("%s_lc" % id)

        print "computing SIP..."
        fs = np.arange(10, 280, 4e-2) * 1e-6
        amps2, s2n, w = K2pgram(x, y, basis, fs)

        data = np.vstack((fs, amps2**.5*1e6)).T

        print "saving SIP"
        np.savetxt("%s_ns.txt" % id, data)

def plot_results(epids):
    for id in epids:
        fs, amp2s = np.genfromtxt("%s_ns.txt" % id).T
        print "plotting %s..." % id
        plt.clf()
        plt.plot(fs, amp2s, "k")
        plt.xlabel("$\\nu\mathrm{~(}\mu\mathrm{Hz)}$")
        plt.ylabel("$\mathrm{Relative~(S/N)}^2$")
        plt.title("$\mathrm{EPIC~%s}$" % str(int(id)))
        plt.subplots_adjust(bottom=.15, left=.2)
        plt.savefig("%s_ns" % str(int(id)))

if __name__ == "__main__":
#     epids = np.genfromtxt("ktwo_c1_APO-RGs_llc.dat.epic.list", dtype=str).T
    epids = np.genfromtxt("K2Campaign1-ObservedTargets_K2GAP.txt",
                          skip_header=1, dtype=str).T  # 8000 targets

    list_SIP(epids)
<commit_msg>running on bbq<commit_after>import numpy as np
import matplotlib.pyplot as plt
import wget
import h5py
from K2pgram import K2pgram
import fitsio
import pyfits
import subprocess
import sys

def sigma_clipping(x, y, low, high):
    # running median with 100 points
    N = 100
    nsections = len(x)/N + 1
    inds = range(0, nsections*100, 100)

    # middle bit
    meds = []
    for i, ind0 in enumerate(inds):
        ind1 = ind0 + N
        sx, sy = x[ind0:ind1], y[ind0:ind1]
        med, std = np.median(sy[np.isfinite(sy)]), np.std(sy[np.isfinite(sy)])
        m = (med - std*low < sy) * (sy < med + std*high)
        x[ind0:ind1][~m] = np.nan
        y[ind0:ind1][~m] = np.nan
        meds.append(med)

    # end bit
    sx, sy = x[inds[-1]:], y[inds[-1]:]
    med, std = np.median(sy[np.isfinite(sy)]), np.std(sy[np.isfinite(sy)])
    m = (sy < med - std*low) * (med + std*high < sy)
    x[inds[-1]:][~m] = np.nan
    y[inds[-1]:][~m] = np.nan

    # get rid of initial dip
    clip = 170
    y[:clip], x[:clip] = np.ones(clip)*np.nan, np.ones(clip)*np.nan

    return x, y

def load_data(id):
        print "loading data"
        fname = "ktwo%s-c01_lpd-lc.fits" % id
        data = fitsio.read(fname)
        aps = fitsio.read(fname, 2)
        y = data["flux"][:, np.argmin(aps["cdpp6"])]
        x = data["time"]
        q = data["quality"]

        # sigma clip
#         x, y = sigma_clipping(x, y, 4, 4)
        l = np.isfinite(y) * np.isfinite(x) * (q==0)
        y, x = y[l], x[l]

        MAD = np.median(y - np.median(y))
        x *= 24*3600

        print "load basis"
        with h5py.File("../data/c1.h5", "r") as f:
            basis = f["basis"][:150, l]

        return x, y, basis

def list_SIP(epids, plot=False):
    for i, id in enumerate(epids):
        print id, i, "of", len(epids)

        print "downloading lightcurve..."
        a = "ktwo%s-c01_lpd-lc.fits" % id
        url = "http://bbq.dfm.io/ketu/lightcurves/c1/%s00000/%s000/%s" \
                % (id[:4], id[4:6], a)
        wget.download(url)

        x, y, basis = load_data(id)
        med = np.median(y)
        y = y/med - 1

        print "deleting lightcurve"
        subprocess.call("rm ktwo%s-c01_lpd-lc.fits" % id, shell=True)

        if plot:
            plt.clf()
            plt.plot(x, y, "k.")
            plt.savefig("plots/%s_lc" % id)

        print "computing SIP..."
        fs = np.arange(10, 280, 4e-2) * 1e-6
        amps2, s2n, w = K2pgram(x, y, basis, fs)

        data = np.vstack((fs, amps2**.5*1e6)).T

        print "saving SIP"
        np.savetxt("SIPs/%s.txt" % id, data)

def plot_results(epids, tex=False):
    for id in epids:
        fs, amp2s = np.genfromtxt("%s.txt" % id).T
        print "plotting %s..." % id
        plt.clf()
        plt.plot(fs, amp2s, "k")
        if tex:
            plt.xlabel("$\\nu\mathrm{~(}\mu\mathrm{Hz)}$")
            plt.ylabel("$\mathrm{Relative~(S/N)}^2$")
            plt.title("$\mathrm{EPIC~%s}$" % str(int(id)))
        else:
            plt.xlabel("Frequency (Hz)")
            plt.ylabel("Relative (S/N)^2")
            plt.title("EPIC %s" % str(int(id)))
        plt.subplots_adjust(bottom=.15, left=.2)
        plt.savefig("plots/%s" % str(int(id)))

if __name__ == "__main__":
#     epids = np.genfromtxt("ktwo_c1_APO-RGs_llc.dat.epic.list", dtype=str).T
    epids = np.genfromtxt("K2Campaign1-ObservedTargets_K2GAP.txt",
                          skip_header=1, dtype=str).T  # 8000 targets

    start, stop = int(sys.argv[1]), int(sys.argv[2])
    if stop > len(epids): list_SIP(epids[start:])
    else: list_SIP(epids[start:stop])
<|endoftext|>


<commit_before>from fasta import *
from dna import *
from itertools import izip, imap, dropwhile
from optparse import *
from multiprocessing import Pool
import os
import sys
from time import time

def main():
    ''' Spaghetti & Meatballs '''
    parser = OptionParser(
        description="""Stitch - Tool for creating contigs from overlapping
paried-end illumina reads.""",
        usage='-i <fastq file 1> -j <fastq file 2> -o <output prefix>')
    parser.add_option('-i', '--first', dest='filea',
        help='first fastq file')
    parser.add_option('-j', '--second', dest='fileb',
        help='second fastq file')
    parser.add_option('-o', '--output', dest='prefix',
        help='output prefix (omit to print to stdout)')
    parser.add_option('-t', '--threads', dest='threads', default=None,
        type=int, help='number of threads (default = all available)')
    parser.add_option('-p', '--pretty_output', dest='pretty', default=False,
        action='store_true',
        help='displays overlapping contigs in a nice way.')
    parser.add_option('-s', '--score', dest='score', default=0.6,
        help='minimum percent identity (default = 25)', type=float)

    (options, args) = parser.parse_args()

    if not (options.filea and options.fileb):
        print >> sys.stderr, 'Usage: %s %s' % \
            (parser.get_prog_name(), parser.usage)
        sys.exit()
    if not (options.prefix):
        print >> sys.stderr, 'Warning: no outputfile'
        dudsa, dudsb, outfile = sys.stdout, sys.stdout, sys.stdout
    else:
        dudsa = open('%s-nh-s1.fastq' % options.prefix, 'w')
        dudsb = open('%s-nh-s2.fastq' % options.prefix, 'w')
        outfile = open('%s-contigs.fastq' % options.prefix , 'w')

    seqsa = open(options.filea, 'r')
    seqsb = open(options.fileb, 'r')

    numcontigs, numtotes = 0, 0

    #p = Pool(options.threads)

    starttime = time()
    overlaps = 0

    for i in imap(doStitch, izip(Fasta(seqsa), Fasta(seqsb))):
        numtotes += 1
        if i.score > options.score:
            numcontigs += 1
            overlaps += i.overlap

            if options.prefix:
                print >> outfile, '%s' % i.record

            if options.pretty:
                print >> sys.stdout, '>%s (%.3f)' % (i.reca.header, i.score)
                print >> sys.stdout, i.pretty
        else:
            reca, recb = i.originals

            if options.prefix:
                print >> dudsa, reca,
                print >> dudsb, recb,

    duration = time() - starttime

    print >> sys.stderr, \
        'Made %s contigs out of %s reads in %.2f seconds (%.2f per sec)' % \
        (numcontigs, numtotes, duration, numtotes/duration)
    try:
        print >> sys.stderr, \
            'Average overlap was %.2f' % (float(overlaps)/numcontigs)
    except ZeroDivisionError:
        print >> sys.stderr, 'no contigs :('

class Stitch:
    ''' Stitches together two overlapping Illumina reads using Doubleblast '''
    def __init__(self, reca, recb):
        self.reca = reca
        self.recb = recb
        self.record = False
        self.overlap = 0
        self.pretty = ''
        self.score = 0.0

        self.find_overlaps()

    @property
    def originals(self):
        return (self.reca, self.recb)

    def find_overlaps(self):
        ''' Alignment algorithm, returns new DNA object of contig '''
        seqa, seqb = self.reca.seq, self.recb.revcomp
        seqb = self.recb.revcomp
        length = min([len(i) for i in (seqa, seqb)])
        scores, hits = [], {}

        # Find overlap
        for i in range(len(seqa)):
            score = 0
            for na, nb in zip(seqa[i-1:], seqb[:-i+1]):
                if (na == nb) and ('N' not in (na, nb)):
                    score += 1
            hits[score] = i

        score = max(hits.keys())
        i = hits[score]

        self.overlap = len(seqa) - i
        self.score = float(score)/(len(seqa)-i)

        beg = seqa[0:i-1]
        end = seqb[-i+1:]
        qbeg = self.reca.qual[0:i-1]
        qend = self.recb.qual[-i+1:][::-1]
        smida = seqa[i-1:]
        smidb = seqb[0:len(seqb)-i+1]
        qmida = self.reca.qual[i-1:]
        qmidb = self.recb.qual[0:len(seqb)-i+1][::-1]
        mid, midq = [], []

        for (na, qa), (nb, qb) in \
                                zip(zip(smida, qmida), zip(smidb, qmidb)):
            if qa>qb:
                mid+=na
                midq+=qa
            elif qa<qb:
                mid+=nb
                midq+=qb
            else:
                if qa==qb:
                    mid+=na
                    midq+=qa
                else:
                    mid+='N'
                    midq+=qa

        newseq = beg + ''.join(mid) + end
        newqual = qbeg + ''.join(midq) + qend

        self.pretty = '1:%s\n2:%s\nC:%s\n' % \
                        (seqa + '-'*(i-1),
                        '-'*(i-1) + seqb, newseq)

        self.record = Dna(self.reca.header, newseq, newqual)

def doStitch(recs):
    ''' Used by Pool.imap to create stitch jobs '''
    try:
        reca, recb = recs
        return Stitch(reca, recb)
    except KeyboardInterrupt:
        print 'Ouch!'
        quit()

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print >> sys.stderr, 'Ouch!'
        quit()<commit_msg>forgot to run on pool<commit_after>from fasta import *
from dna import *
from itertools import izip, imap, dropwhile
from optparse import *
from multiprocessing import Pool
import os
import sys
from time import time

def main():
    ''' Spaghetti & Meatballs '''
    parser = OptionParser(
        description="""Stitch - Tool for creating contigs from overlapping
paried-end illumina reads.""",
        usage='-i <fastq file 1> -j <fastq file 2> -o <output prefix>')
    parser.add_option('-i', '--first', dest='filea',
        help='first fastq file')
    parser.add_option('-j', '--second', dest='fileb',
        help='second fastq file')
    parser.add_option('-o', '--output', dest='prefix',
        help='output prefix (omit to print to stdout)')
    parser.add_option('-t', '--threads', dest='threads', default=None,
        type=int, help='number of threads (default = all available)')
    parser.add_option('-p', '--pretty_output', dest='pretty', default=False,
        action='store_true',
        help='displays overlapping contigs in a nice way.')
    parser.add_option('-s', '--score', dest='score', default=0.6,
        help='minimum percent identity (default = 25)', type=float)

    (options, args) = parser.parse_args()

    if not (options.filea and options.fileb):
        print >> sys.stderr, 'Usage: %s %s' % \
            (parser.get_prog_name(), parser.usage)
        sys.exit()
    if not (options.prefix):
        print >> sys.stderr, 'Warning: no outputfile'
        dudsa, dudsb, outfile = sys.stdout, sys.stdout, sys.stdout
    else:
        dudsa = open('%s-nh-s1.fastq' % options.prefix, 'w')
        dudsb = open('%s-nh-s2.fastq' % options.prefix, 'w')
        outfile = open('%s-contigs.fastq' % options.prefix , 'w')

    seqsa = open(options.filea, 'r')
    seqsb = open(options.fileb, 'r')

    numcontigs, numtotes = 0, 0

    p = Pool(options.threads)

    starttime = time()
    overlaps = 0

    for i in p.imap(doStitch, izip(Fasta(seqsa), Fasta(seqsb))):
        numtotes += 1
        if i.score > options.score:
            numcontigs += 1
            overlaps += i.overlap

            if options.prefix:
                print >> outfile, '%s' % i.record

            if options.pretty:
                print >> sys.stdout, '>%s (%.3f)' % (i.reca.header, i.score)
                print >> sys.stdout, i.pretty
        else:
            reca, recb = i.originals

            if options.prefix:
                print >> dudsa, reca,
                print >> dudsb, recb,

    duration = time() - starttime

    print >> sys.stderr, \
        'Made %s contigs out of %s reads in %.2f seconds (%.2f per sec)' % \
        (numcontigs, numtotes, duration, numtotes/duration)
    try:
        print >> sys.stderr, \
            'Average overlap was %.2f' % (float(overlaps)/numcontigs)
    except ZeroDivisionError:
        print >> sys.stderr, 'no contigs :('

class Stitch:
    ''' Stitches together two overlapping Illumina reads using Doubleblast '''
    def __init__(self, reca, recb):
        self.reca = reca
        self.recb = recb
        self.record = False
        self.overlap = 0
        self.pretty = ''
        self.score = 0.0

        self.find_overlaps()

    @property
    def originals(self):
        return (self.reca, self.recb)

    def find_overlaps(self):
        ''' Alignment algorithm, returns new DNA object of contig '''
        seqa, seqb = self.reca.seq, self.recb.revcomp
        seqb = self.recb.revcomp
        length = min([len(i) for i in (seqa, seqb)])
        scores, hits = [], {}

        # Find overlap
        for i in range(len(seqa)):
            score = 0
            for na, nb in zip(seqa[i-1:], seqb[:-i+1]):
                if (na == nb) and ('N' not in (na, nb)):
                    score += 1
            hits[score] = i

        score = max(hits.keys())
        i = hits[score]

        self.overlap = len(seqa) - i
        self.score = float(score)/(len(seqa)-i)

        beg = seqa[0:i-1]
        end = seqb[-i+1:]
        qbeg = self.reca.qual[0:i-1]
        qend = self.recb.qual[-i+1:][::-1]
        smida = seqa[i-1:]
        smidb = seqb[0:len(seqb)-i+1]
        qmida = self.reca.qual[i-1:]
        qmidb = self.recb.qual[0:len(seqb)-i+1][::-1]
        mid, midq = [], []

        for (na, qa), (nb, qb) in \
                                zip(zip(smida, qmida), zip(smidb, qmidb)):
            if qa>qb:
                mid+=na
                midq+=qa
            elif qa<qb:
                mid+=nb
                midq+=qb
            else:
                if qa==qb:
                    mid+=na
                    midq+=qa
                else:
                    mid+='N'
                    midq+=qa

        newseq = beg + ''.join(mid) + end
        newqual = qbeg + ''.join(midq) + qend

        self.pretty = '1:%s\n2:%s\nC:%s\n' % \
                        (seqa + '-'*(i-1),
                        '-'*(i-1) + seqb, newseq)

        self.record = Dna(self.reca.header, newseq, newqual)

def doStitch(recs):
    ''' Used by Pool.imap to create stitch jobs '''
    try:
        reca, recb = recs
        return Stitch(reca, recb)
    except KeyboardInterrupt:
        print 'Ouch!'
        quit()

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print >> sys.stderr, 'Ouch!'
        quit()<|endoftext|>


<commit_before># Author:  Lisandro Dalcin
# Contact: dalcinl@gmail.com
"""
Run Python code (scripts, modules, zip files) using the ``runpy``
module. In case of an unhandled exception, abort execution of the MPI
program by calling ``MPI.COMM_WORLD.Abort()``.
"""
from __future__ import print_function

def main():
    """
    Entry-point for ``python -m mpi4py.run ...``
    """
    # pylint: disable=missing-docstring
    import sys
    from runpy import run_module
    try:
        from runpy import run_path
    except ImportError:  # Python 2.6  # pragma: no cover
        def run_path(path_name, init_globals=None, run_name=None):
            from pkgutil import read_code
            from runpy import _run_module_code
            with open(path_name, 'rb') as fobj:  # compiled file
                code = read_code(fobj)
            if code is None:
                with open(path_name, 'rU') as fobj:  # normal source code
                    code = compile(fobj.read(), path_name, 'exec')
            return _run_module_code(code, init_globals, run_name, path_name)

    def run_string(string, init_globals=None, run_name=None, argv0='-c'):
        from runpy import _run_module_code
        karg = 'script_name' if sys.version_info >= (3, 4) else 'mod_fname'
        code = compile(string, '<string>', 'exec')
        return _run_module_code(code, init_globals, run_name, **{karg: argv0})

    def version():
        from . import __version__
        print(__package__, __version__, file=sys.stdout)
        sys.exit(0)

    def usage(errmess=None):
        from textwrap import dedent
        if __name__ == '__main__':
            prog_name = __package__ + '.run'
        else:
            prog_name = __package__
        subs = dict(prog=prog_name, python='python'+sys.version[0])

        cmdline = dedent("""
        usage: {python} -m {prog} [options] <pyfile> [arg] ...
           or: {python} -m {prog} [options] -m <module> [arg] ...
           or: {python} -m {prog} [options] -c <string> [arg] ...
        """).strip().format(**subs)

        helptip = dedent("""
        Try `{python} -m {prog} -h` for more information.
        """).strip().format(**subs)

        options = dedent("""
        options:
          --version            show version number and exit
          -h|--help            show this help message and exit
          -rc <key=value,...>  set 'mpi4py.rc.key=value'
          -p|--profile <pmpi>  use <pmpi> for profiling
          --mpe                profile with MPE
          --vt                 profile with VampirTrace
        """).strip()

        if errmess:
            print(errmess, file=sys.stderr)
            print(cmdline, file=sys.stderr)
            print(helptip, file=sys.stderr)
            sys.exit(1)
        else:
            print(cmdline, file=sys.stdout)
            print(options, file=sys.stdout)
            sys.exit(0)

    def parse_command_line(args=None):
        # pylint: disable=too-many-branches
        class Options(object):  # pylint: disable=too-few-public-methods
            rc_args = {}
            profile = None

        def poparg(args):
            if len(args) < 2 or not args[1] or args[1].startswith('-'):
                usage('Argument expected for option: ' + args[0])
            return args.pop(1)

        options = Options()
        args = sys.argv[1:] if args is None else args[:]
        while args and args[0].startswith('-'):
            if args[0] in ('-m', '-c'):
                break  # Stop processing options
            if args[0] in ('-h', '-help', '--help'):
                usage()  # Print help and exit
            if args[0] in ('-version', '--version'):
                version()  # Print version and exit
            try:
                arg0 = args[0]
                if arg0.startswith('--'):
                    if '=' in arg0:
                        i = arg0.index('=')
                        opt, arg = arg0[1:i], arg0[i+1:]
                        if opt in ('-rc', '-profile'):
                            arg0, args[1:1] = opt, [arg]
                    else:
                        arg0 = arg0[1:]
                if arg0 == '-rc':
                    for entry in poparg(args).split(','):
                        i = entry.index('=')
                        key = entry[:i].strip()
                        val = entry[i+1:].strip()
                        if not key or not val:
                            raise ValueError(entry)
                        try:
                            # pylint: disable=eval-used
                            options.rc_args[key] = eval(val, {})
                        except NameError:
                            options.rc_args[key] = val
                elif arg0 in ('-p', '-profile'):
                    options.profile = poparg(args) or None
                elif arg0 in ('-mpe', '-vt'):
                    options.profile = arg0[1:]
                else:
                    usage('Unknown option: ' + args[0])
                del args[0]
            except Exception:  # pylint: disable=broad-except
                # Bad option, print usage and exit with error
                usage('Cannot parse option: ' + args[0])
        # Final check and return to caller
        if len(args) < 1:
            usage("No path specified for execution")
        elif args[0] in ('-m', '-c') and len(args) < 2:
            usage('Argument expected for option: ' + args[0])
        return options, args

    def bootstrap(options):
        if options.rc_args:  # Set mpi4py.rc parameters
            from . import rc
            rc(**options.rc_args)
        if options.profile:  # Load profiling library
            from . import profile
            profile(options.profile)

    def set_abort_status(status):
        if status is None:
            status = 0
        if not isinstance(status, int):
            status = 1
        mpi = sys.modules.get(__package__ + '.MPI')
        if mpi is not None:
            # pylint: disable=protected-access
            mpi._set_abort_status(status)

    # Parse and process command line options
    options, sys.argv[:] = parse_command_line()
    bootstrap(options)

    # Run user code (scripts, modules, zip files) using the 'runpy'
    # module. In case of an unhandled exception, abort execution of
    # the MPI program by calling 'MPI_Abort()'.
    try:

        if sys.argv[0] == '-c':
            run_string(sys.argv[1], run_name='__main__')
        elif sys.argv[0] == '-m':
            del sys.argv[0]  # Remove "-m" from argument list
            run_module(sys.argv[0], run_name='__main__', alter_sys=True)
        else:
            from os.path import realpath, dirname
            sys.path[0] = realpath(dirname(sys.argv[0]))  # Fix sys.path
            run_path(sys.argv[0], run_name='__main__')

    except SystemExit as exc:
        set_abort_status(exc.code)
        raise
    except:
        set_abort_status(1)
        raise

if __name__ == '__main__':
    main()
<commit_msg>Fix call to compile() to not inherit __future__ statements<commit_after># Author:  Lisandro Dalcin
# Contact: dalcinl@gmail.com
"""
Run Python code (scripts, modules, zip files) using the ``runpy``
module. In case of an unhandled exception, abort execution of the MPI
program by calling ``MPI.COMM_WORLD.Abort()``.
"""
from __future__ import print_function

def main():
    """
    Entry-point for ``python -m mpi4py.run ...``
    """
    # pylint: disable=missing-docstring
    import sys
    from runpy import run_module
    try:
        from runpy import run_path
    except ImportError:  # Python 2.6  # pragma: no cover
        def run_path(path_name, init_globals=None, run_name=None):
            from pkgutil import read_code
            from runpy import _run_module_code
            with open(path_name, 'rb') as fobj:  # compiled file
                code = read_code(fobj)
            if code is None:
                with open(path_name, 'rU') as fobj:  # normal source code
                    code = compile(fobj.read(), path_name, 'exec')
            return _run_module_code(code, init_globals, run_name, path_name)

    def run_string(string, init_globals=None, run_name=None, argv0='-c'):
        from runpy import _run_module_code
        karg = 'script_name' if sys.version_info >= (3, 4) else 'mod_fname'
        code = compile(string, '<string>', 'exec', 0, 1)
        return _run_module_code(code, init_globals, run_name, **{karg: argv0})

    def version():
        from . import __version__
        print(__package__, __version__, file=sys.stdout)
        sys.exit(0)

    def usage(errmess=None):
        from textwrap import dedent
        if __name__ == '__main__':
            prog_name = __package__ + '.run'
        else:
            prog_name = __package__
        subs = dict(prog=prog_name, python='python'+sys.version[0])

        cmdline = dedent("""
        usage: {python} -m {prog} [options] <pyfile> [arg] ...
           or: {python} -m {prog} [options] -m <module> [arg] ...
           or: {python} -m {prog} [options] -c <string> [arg] ...
        """).strip().format(**subs)

        helptip = dedent("""
        Try `{python} -m {prog} -h` for more information.
        """).strip().format(**subs)

        options = dedent("""
        options:
          --version            show version number and exit
          -h|--help            show this help message and exit
          -rc <key=value,...>  set 'mpi4py.rc.key=value'
          -p|--profile <pmpi>  use <pmpi> for profiling
          --mpe                profile with MPE
          --vt                 profile with VampirTrace
        """).strip()

        if errmess:
            print(errmess, file=sys.stderr)
            print(cmdline, file=sys.stderr)
            print(helptip, file=sys.stderr)
            sys.exit(1)
        else:
            print(cmdline, file=sys.stdout)
            print(options, file=sys.stdout)
            sys.exit(0)

    def parse_command_line(args=None):
        # pylint: disable=too-many-branches
        class Options(object):  # pylint: disable=too-few-public-methods
            rc_args = {}
            profile = None

        def poparg(args):
            if len(args) < 2 or not args[1] or args[1].startswith('-'):
                usage('Argument expected for option: ' + args[0])
            return args.pop(1)

        options = Options()
        args = sys.argv[1:] if args is None else args[:]
        while args and args[0].startswith('-'):
            if args[0] in ('-m', '-c'):
                break  # Stop processing options
            if args[0] in ('-h', '-help', '--help'):
                usage()  # Print help and exit
            if args[0] in ('-version', '--version'):
                version()  # Print version and exit
            try:
                arg0 = args[0]
                if arg0.startswith('--'):
                    if '=' in arg0:
                        i = arg0.index('=')
                        opt, arg = arg0[1:i], arg0[i+1:]
                        if opt in ('-rc', '-profile'):
                            arg0, args[1:1] = opt, [arg]
                    else:
                        arg0 = arg0[1:]
                if arg0 == '-rc':
                    for entry in poparg(args).split(','):
                        i = entry.index('=')
                        key = entry[:i].strip()
                        val = entry[i+1:].strip()
                        if not key or not val:
                            raise ValueError(entry)
                        try:
                            # pylint: disable=eval-used
                            options.rc_args[key] = eval(val, {})
                        except NameError:
                            options.rc_args[key] = val
                elif arg0 in ('-p', '-profile'):
                    options.profile = poparg(args) or None
                elif arg0 in ('-mpe', '-vt'):
                    options.profile = arg0[1:]
                else:
                    usage('Unknown option: ' + args[0])
                del args[0]
            except Exception:  # pylint: disable=broad-except
                # Bad option, print usage and exit with error
                usage('Cannot parse option: ' + args[0])
        # Final check and return to caller
        if len(args) < 1:
            usage("No path specified for execution")
        elif args[0] in ('-m', '-c') and len(args) < 2:
            usage('Argument expected for option: ' + args[0])
        return options, args

    def bootstrap(options):
        if options.rc_args:  # Set mpi4py.rc parameters
            from . import rc
            rc(**options.rc_args)
        if options.profile:  # Load profiling library
            from . import profile
            profile(options.profile)

    def set_abort_status(status):
        if status is None:
            status = 0
        if not isinstance(status, int):
            status = 1
        mpi = sys.modules.get(__package__ + '.MPI')
        if mpi is not None:
            # pylint: disable=protected-access
            mpi._set_abort_status(status)

    # Parse and process command line options
    options, sys.argv[:] = parse_command_line()
    bootstrap(options)

    # Run user code (scripts, modules, zip files) using the 'runpy'
    # module. In case of an unhandled exception, abort execution of
    # the MPI program by calling 'MPI_Abort()'.
    try:

        if sys.argv[0] == '-c':
            run_string(sys.argv[1], run_name='__main__')
        elif sys.argv[0] == '-m':
            del sys.argv[0]  # Remove "-m" from argument list
            run_module(sys.argv[0], run_name='__main__', alter_sys=True)
        else:
            from os.path import realpath, dirname
            sys.path[0] = realpath(dirname(sys.argv[0]))  # Fix sys.path
            run_path(sys.argv[0], run_name='__main__')

    except SystemExit as exc:
        set_abort_status(exc.code)
        raise
    except:
        set_abort_status(1)
        raise

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


<commit_before>import argparse

from ._logical import build_logical_parser
from ._physical import build_physical_parser

def build_list_parser(parser):
    """
    Generate the parser appropriate for displaying information.

    :param ArgumentParser parser: a parser
    :returns: a completed parser for listing pools
    :rtype: ArgumentParser
    """
    return parser

def build_create_parser(parser):
    """
    Generates the parser appropriate for creating a pool.

    :param ArgumentParser parser: a parser
    :returns: a completed parser for creating a pool
    :rtype: ArgumentParser
    """
    parser.add_argument(
       'name',
       action='store',
       help='name to assign to pool'
    )
    parser.add_argument(
       'device',
       help='make device D a member of this pool',
       metavar='D',
       nargs='+'
    )
    parser.add_argument(
       '--force',
       action="store_true",
       default=False,
       help="overwrite all existing data and metadata on selected devices"
    )
    parser.add_argument(
       '--redundancy',
       action='store',
       choices=['single'],
       default='single',
       help="redundancy selection for this pool"
    )
    return parser

def gen_parser():
    """
    Make the parser.

    :returns: a fully constructed parser for command-line arguments
    :rtype: ArgumentParser
    """
    parser = argparse.ArgumentParser(description="Stratis Storage Manager")

    subparsers = \
       parser.add_subparsers(dest='subparser_name', title='subcommands')

    subparser_names = ('cache', 'create', 'dev', 'list', 'vol')

    subparser_table = dict()

    subparser_table['create'] = \
       subparsers.add_parser('create', description="Create New Stratis Pool")
    build_create_parser(subparser_table['create'])

    subparser_table['list'] = \
       subparsers.add_parser('list', description="List Stratis Pools")
    build_list_parser(subparser_table['list'])

    subparser_table['logical'] = \
       subparsers.add_parser(
          'logical',
          description="Administer Logical Aspects of Specified Pool"
       )
    build_logical_parser(subparser_table['logical'])

    subparser_table['physical'] = \
       subparsers.add_parser(
          'physical',
          description="Administer Physical Aspects of Specified Pool"
       )
    build_physical_parser(subparser_table['physical'])

    return parser
<commit_msg>Add a destroy command for pools.<commit_after>import argparse

from ._logical import build_logical_parser
from ._physical import build_physical_parser

def build_list_parser(parser):
    """
    Generate the parser appropriate for displaying information.

    :param ArgumentParser parser: a parser
    :returns: a completed parser for listing pools
    :rtype: ArgumentParser
    """
    return parser

def build_create_parser(parser):
    """
    Generates the parser appropriate for creating a pool.

    :param ArgumentParser parser: a parser
    :returns: a completed parser for creating a pool
    :rtype: ArgumentParser
    """
    parser.add_argument(
       'name',
       action='store',
       help='name to assign to pool'
    )
    parser.add_argument(
       'device',
       help='make device D a member of this pool',
       metavar='D',
       nargs='+'
    )
    parser.add_argument(
       '--force',
       action="store_true",
       default=False,
       help="overwrite all existing data and metadata on selected devices"
    )
    parser.add_argument(
       '--redundancy',
       action='store',
       choices=['single'],
       default='single',
       help="redundancy selection for this pool"
    )
    return parser

def build_destroy_parser(parser):
    """
    Generates the parser appropriate for destroying a pool.

    :param ArgumentParser parser: a parser
    :returns: a completed parser for destroying a pool
    :rtype: ArgumentParser
    """
    parser.add_argument(
       'name',
       action='store',
       help='name of pool'
    )
    parser.add_argument(
       '--force',
       action="store_true",
       default=False,
       help="disregard the presence of any data or metadata"
    )
    return parser

def gen_parser():
    """
    Make the parser.

    :returns: a fully constructed parser for command-line arguments
    :rtype: ArgumentParser
    """
    parser = argparse.ArgumentParser(description="Stratis Storage Manager")

    subparsers = \
       parser.add_subparsers(dest='subparser_name', title='subcommands')

    subparser_names = ('cache', 'create', 'dev', 'list', 'vol')

    subparser_table = dict()

    subparser_table['create'] = \
       subparsers.add_parser('create', description="Create New Stratis Pool")
    build_create_parser(subparser_table['create'])

    subparser_table['destroy'] = \
       subparsers.add_parser(
          'destroy',
          description="Destroy Existing Stratis Pool"
    )
    build_destroy_parser(subparser_table['destroy'])

    subparser_table['list'] = \
       subparsers.add_parser('list', description="List Stratis Pools")
    build_list_parser(subparser_table['list'])

    subparser_table['logical'] = \
       subparsers.add_parser(
          'logical',
          description="Administer Logical Aspects of Specified Pool"
       )
    build_logical_parser(subparser_table['logical'])

    subparser_table['physical'] = \
       subparsers.add_parser(
          'physical',
          description="Administer Physical Aspects of Specified Pool"
       )
    build_physical_parser(subparser_table['physical'])

    return parser
<|endoftext|>


<commit_before>"""
mbed SDK
Copyright (c) 2016 ARM Limited

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 os import getenv
from os.path import join, abspath, dirname, exists
import logging

ROOT = abspath(join(dirname(__file__), ".."))

##############################################################################
# Toolchains and Build System Settings
##############################################################################
BUILD_DIR = abspath(join(ROOT, ".build"))

# ARM Compiler 5
ARM_PATH = "C:/Keil_v5/ARM/ARMCC"

# GCC ARM
GCC_ARM_PATH = ""

# GCC CodeRed
GCC_CR_PATH = "C:/code_red/RedSuite_4.2.0_349/redsuite/Tools/bin"

# IAR
IAR_PATH = "C:/Program Files (x86)/IAR Systems/Embedded Workbench 7.3/arm"

# Goanna static analyser. Please overload it in mbed_settings.py
GOANNA_PATH = "c:/Program Files (x86)/RedLizards/Goanna Central 3.2.3/bin"

# cppcheck path (command) and output message format
CPPCHECK_CMD = ["cppcheck", "--enable=all"]
CPPCHECK_MSG_FORMAT = ["--template=[{severity}] {file}@{line}: {id}:{message}"]

BUILD_OPTIONS = []

# mbed.org username
MBED_ORG_USER = ""

##############################################################################
# User Settings (file)
##############################################################################
try:
    # Allow to overwrite the default settings without the need to edit the
    # settings file stored in the repository
    from mbed_settings import *
except ImportError:
    pass

##############################################################################
# User Settings (env vars)
##############################################################################
_ENV_PATHS = ['ARM_PATH', 'GCC_ARM_PATH', 'GCC_CR_PATH', 'IAR_PATH']

for _n in _ENV_PATHS:
    if getenv('MBED_'+_n):
        if exists(getenv('MBED_'+_n)):
            globals()[_n] = getenv('MBED_'+_n)
        else:
            print "WARNING: MBED_%s set as environment variable but doesn't exist" % _n

##############################################################################
# ARM Compiler Paths
##############################################################################

ARM_BIN = join(ARM_PATH, "bin")
ARM_INC = join(ARM_PATH, "include")
ARM_LIB = join(ARM_PATH, "lib")
ARM_CPPLIB = join(ARM_LIB, "cpplib")
MY_ARM_CLIB = join(ARM_LIB, "lib", "microlib")

##############################################################################
# Test System Settings
##############################################################################
SERVER_PORT = 59432
SERVER_ADDRESS = "10.2.200.94"
LOCALHOST = "10.2.200.94"

MUTs = {
    "1" : {"mcu": "LPC1768",
        "port":"COM41", "disk":'E:\\',
        "peripherals": ["TMP102", "digital_loop", "port_loop", "analog_loop", "SD"]
    },
    "2": {"mcu": "LPC11U24",
        "port":"COM42", "disk":'F:\\',
        "peripherals":  ["TMP102", "digital_loop", "port_loop", "SD"]
    },
    "3" : {"mcu": "KL25Z",
        "port":"COM43", "disk":'G:\\',
        "peripherals":  ["TMP102", "digital_loop", "port_loop", "analog_loop", "SD"]
    },
}
<commit_msg>Add a setting for colorization map so that it may be overwritten by the user<commit_after>"""
mbed SDK
Copyright (c) 2016 ARM Limited

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 os import getenv
from os.path import join, abspath, dirname, exists
import logging

ROOT = abspath(join(dirname(__file__), ".."))

##############################################################################
# Toolchains and Build System Settings
##############################################################################
BUILD_DIR = abspath(join(ROOT, ".build"))

# ARM Compiler 5
ARM_PATH = "C:/Keil_v5/ARM/ARMCC"

# GCC ARM
GCC_ARM_PATH = ""

# GCC CodeRed
GCC_CR_PATH = "C:/code_red/RedSuite_4.2.0_349/redsuite/Tools/bin"

# IAR
IAR_PATH = "C:/Program Files (x86)/IAR Systems/Embedded Workbench 7.3/arm"

# Goanna static analyser. Please overload it in mbed_settings.py
GOANNA_PATH = "c:/Program Files (x86)/RedLizards/Goanna Central 3.2.3/bin"

# cppcheck path (command) and output message format
CPPCHECK_CMD = ["cppcheck", "--enable=all"]
CPPCHECK_MSG_FORMAT = ["--template=[{severity}] {file}@{line}: {id}:{message}"]

BUILD_OPTIONS = []

# mbed.org username
MBED_ORG_USER = ""

CLI_COLOR_MAP = {
    "warning": "yellow",
    "error"  : "red"
}

##############################################################################
# User Settings (file)
##############################################################################
try:
    # Allow to overwrite the default settings without the need to edit the
    # settings file stored in the repository
    from mbed_settings import *
except ImportError:
    pass

##############################################################################
# User Settings (env vars)
##############################################################################
_ENV_PATHS = ['ARM_PATH', 'GCC_ARM_PATH', 'GCC_CR_PATH', 'IAR_PATH']

for _n in _ENV_PATHS:
    if getenv('MBED_'+_n):
        if exists(getenv('MBED_'+_n)):
            globals()[_n] = getenv('MBED_'+_n)
        else:
            print "WARNING: MBED_%s set as environment variable but doesn't exist" % _n

##############################################################################
# ARM Compiler Paths
##############################################################################

ARM_BIN = join(ARM_PATH, "bin")
ARM_INC = join(ARM_PATH, "include")
ARM_LIB = join(ARM_PATH, "lib")
ARM_CPPLIB = join(ARM_LIB, "cpplib")
MY_ARM_CLIB = join(ARM_LIB, "lib", "microlib")

##############################################################################
# Test System Settings
##############################################################################
SERVER_PORT = 59432
SERVER_ADDRESS = "10.2.200.94"
LOCALHOST = "10.2.200.94"

MUTs = {
    "1" : {"mcu": "LPC1768",
        "port":"COM41", "disk":'E:\\',
        "peripherals": ["TMP102", "digital_loop", "port_loop", "analog_loop", "SD"]
    },
    "2": {"mcu": "LPC11U24",
        "port":"COM42", "disk":'F:\\',
        "peripherals":  ["TMP102", "digital_loop", "port_loop", "SD"]
    },
    "3" : {"mcu": "KL25Z",
        "port":"COM43", "disk":'G:\\',
        "peripherals":  ["TMP102", "digital_loop", "port_loop", "analog_loop", "SD"]
    },
}
<|endoftext|>