<commit_before>'''
DatetimePicker
=============

:class:`DatetimePicker` is a roulette based datetime selector like in iOS
and android.

Dependencies
------------

The only immediate dependency is the garden package ``kivy.garden.roulette``.
However, if you have never installed garden packages before, and start with
only a default kivy python distribution, then the following is needed.

1. garden packages. Use ``garden install`` to install them.

    a. ``kivy.garden.tickline``
    b. ``kivy.garden.roulette``
    c. ``kivy.garden.roulettescroll``

'''

from calendar import monthrange
from datetime import datetime, timedelta
from functools import partial
from kivy.clock import Clock
from kivy.effects.scroll import ScrollEffect
from kivy.factory import Factory
from kivy.garden.roulette import TimeFormatCyclicRoulette, Roulette, \
    CyclicRoulette
from kivy.lang import Builder
from kivy.metrics import dp
from kivy.properties import ObjectProperty, NumericProperty, AliasProperty, \
    BooleanProperty
from kivy.uix.boxlayout import BoxLayout

Builder.load_string('''
<Symbol@Label>:
    size_hint_x: None
    width: '20dp'
    text: ''
    font_size: '30sp'
<Colon@Symbol>:
    text: ':'
<Dash@Symbol>:
    text: '-'
''')

Symbol = Factory.Symbol
Dash = Factory.Dash
Colon = Factory.Colon

Builder.load_string('''
<DatetimePicker>:
    canvas.after:
        Color:
            rgba: 0, 0, 1, .3
        Rectangle:
            pos: self.x, self.center_y - self.shield_width
            size: self.width, 2 * self.shield_width
        Line:
            points: self.x, self.center_y - self.shield_width + self._shade_width, \
            self.x + self.width, self.center_y - self.shield_width + self._shade_width
            width: self._shade_width
            cap: 'none'
    size_hint: None, 1
    padding: [dp(10), 0, dp(10), 0]
''')

class DatetimePicker(BoxLayout):
    '''a simple roulette datetime selector for *timezone-naive* datetime.'''

    _shade_width = NumericProperty('1.5dp')
    shield_width = NumericProperty('25dp')
    '''setting for graphics. May be changed or obsoleted in the future.'''

    year = ObjectProperty(None)
    month = ObjectProperty(None)
    day = ObjectProperty(None)
    hour = ObjectProperty(None)
    minute = ObjectProperty(None)
    second = ObjectProperty(None)

    selected_datetime = ObjectProperty(None)
    '''tracks the datetime selection.'''

    in_motion = BooleanProperty(False)
    '''indicates whether any of the member roulettes are in motion.'''

    datetime_fields = ('year', 'month', 'day', 'hour', 'minute', 'second')
    month_size = NumericProperty(None, allownone=True)

    def __init__(self, **kw):
        super(DatetimePicker, self).__init__(**kw)
        self.init_roulettes()
    def init_roulettes(self):
        self._calibrate_month_size_trigger = t = \
                    Clock.create_trigger(self.calibrate_month_size)
        self._adjust_day_cycle_trigger = \
                    Clock.create_trigger(self._adjust_day_cycle, -1)
        now = datetime.now()
        self.second = second = TimeFormatCyclicRoulette(cycle=60)
        second.select_and_center(now.second)
        self.minute = minute = TimeFormatCyclicRoulette(cycle=60)
        minute.select_and_center(now.minute)
        self.hour = hour = TimeFormatCyclicRoulette(cycle=24)
        hour.select_and_center(now.hour)
        self.year = year = Roulette()
        year.select_and_center(now.year)
        self.month = month = CyclicRoulette(cycle=12, zero_indexed=False)
        month.select_and_center(now.month)

        month_size = monthrange(now.year, now.month)[1]
        self.day = day = CyclicRoulette(cycle=month_size, zero_indexed=False,
                                        on_centered=self._adjust_day_cycle_trigger)
        day.select_and_center(now.day)

        self.month.bind(selected_value=t)
        self.year.bind(selected_value=t)

        self.set_selected_datetime()
        self._bind_updates()

        children = [
                    year, Dash(), month, Dash(), day, Symbol(),
                    hour, Colon(), minute, Colon(), second,
                    ]
        add = self.add_widget
        width = dp(20)
        for c in children:
            add(c)
            width += c.width
        self.width = width
    def update_width(self, *args):
        width = sum(c.width for c in self.children)
        self.width = width
    def get_datetime(self, *args):
        try:
            d = {field: getattr(self, field).selected_value
                 for field in self.datetime_fields}
            return datetime(**d)
        except:
            return None
    def _update_in_motion(self, *args):
        for field in self.datetime_fields:
            if getattr(self, field).in_motion:
                self.in_motion = True
                return
        self.in_motion = False
        return
    def set_datetime(self, val, *args, **kw):
        '''animatedly set the roulette's datetime to ``val``.
        The keyword argument ``largest_delta`` can be set to True to specify
        that only the largest granularity of time that differs from
        ``val`` to the time shown on the roulettes is to be changed.

        For example, if ``val = datetime(2013, 1, 2, 5, 55, 23)`` and
        current time shown is ``datetime(2013, 1, 2, 6, 02, 33)``, and
        ``largest_delta=True``, then only the hour roulette will be updated
        to center on ``5``, and no other changes are introduced.

        This option is useful for reducing graphical load when linking
        this roulette to changing values of time.'''
        largest_delta = kw.get('largest_delta')
        for field in self.datetime_fields:
            changed = getattr(self, field).select_and_center(getattr(val, field))
            if changed and largest_delta:
                return
    def set_selected_datetime(self, *args):
        new_dt = self.get_datetime()
        if new_dt:
            self.selected_datetime = new_dt
    def _bind_updates(self, *args):
        for field in self.datetime_fields:
            getattr(self, field).bind(selected_value=self.set_selected_datetime,
                                      in_motion=self._update_in_motion)

    def calibrate_month_size(self, *args):
        selected_year = self.year.selected_value
        selected_month = self.month.selected_value
        self.month_size = month_size = monthrange(selected_year,
                                                  selected_month)[1]
        day = self.day
        if day.cycle == month_size:
            return
        if day.selected_value > month_size:
            day.select_and_center(month_size)
        else:
            self._adjust_day_cycle()
    def _adjust_day_cycle(self, *args, **kw):
        new_cycle = kw.get('new_cycle', self.month_size)
        if new_cycle is None or self.day.cycle == new_cycle:
            return
        current_day = self.day.selected_value
        self.day.cycle = new_cycle
        # unless month_size gets set again, guards against erroneous adjustment
        # and infinite loop
        self.month_size = None

        self.day.select_and_center(current_day, animate=False)

if __name__ == '__main__':
    from kivy.base import runTouchApp
    runTouchApp(DatetimePicker())<commit_msg>added section encouraging graphics mod<commit_after>'''
DatetimePicker
==============

:class:`DatetimePicker` is a roulette based datetime selector like in iOS
and android.

Dependencies
------------

The only immediate dependency is the garden package ``kivy.garden.roulette``.
However, if you have never installed garden packages before, and start with
only a default kivy python distribution, then the following garden packages
are needed. Use ``garden install`` to install them.

a. ``kivy.garden.tickline``
b. ``kivy.garden.roulette``
c. ``kivy.garden.roulettescroll``

Usage
-----

Just instantiate ``DatetimePicker()``::

    if __name__ == '__main__':
        from kivy.base import runTouchApp
        runTouchApp(DatetimePicker())

This will give you 6 vertical roulettes
that respectively represent year, month, day, hour, minute, and second.

:attr:`DatetimePicker.selected_value` records the selection from the user.

:attr:`DatetimePicker.density` controls how many values are shown at a time.

NICER GRAPHICS!
---------------

I didn't focus much on the graphics, or to closely simulate the iOS or android
experience. You are encourage to contribute to improve the default appearance
of the datetimepicker!

'''

from calendar import monthrange
from datetime import datetime, timedelta
from functools import partial
from kivy.clock import Clock
from kivy.effects.scroll import ScrollEffect
from kivy.factory import Factory
from kivy.garden.roulette import TimeFormatCyclicRoulette, Roulette, \
    CyclicRoulette
from kivy.lang import Builder
from kivy.metrics import dp
from kivy.properties import ObjectProperty, NumericProperty, AliasProperty, \
    BooleanProperty
from kivy.uix.boxlayout import BoxLayout

Builder.load_string('''
<Symbol@Label>:
    size_hint_x: None
    width: '20dp'
    text: ''
    font_size: '30sp'
<Colon@Symbol>:
    text: ':'
<Dash@Symbol>:
    text: '-'
''')

Symbol = Factory.Symbol
Dash = Factory.Dash
Colon = Factory.Colon

Builder.load_string('''
<DatetimePicker>:
    canvas.after:
        Color:
            rgba: 0, 0, 1, .3
        Rectangle:
            pos: self.x, self.center_y - self.shield_width
            size: self.width, 2 * self.shield_width
        Line:
            points:
                self.x, \
                self.center_y - self.shield_width + self._shade_width, \
                self.x + self.width, \
                self.center_y - self.shield_width + self._shade_width
            width: self._shade_width
            cap: 'none'
    size_hint: None, 1
    padding: [dp(10), 0, dp(10), 0]
''')

class DatetimePicker(BoxLayout):
    '''a simple roulette datetime selector for *timezone-naive* datetime.'''

    _shade_width = NumericProperty('1.5dp')
    shield_width = NumericProperty('25dp')
    '''setting for graphics. May be changed or obsoleted in the future.'''

    year = ObjectProperty(None)
    month = ObjectProperty(None)
    day = ObjectProperty(None)
    hour = ObjectProperty(None)
    minute = ObjectProperty(None)
    second = ObjectProperty(None)

    density = NumericProperty(4.2)
    '''determines how many values are shown at a time on each roulette.'''

    selected_datetime = ObjectProperty(None)
    '''tracks the datetime selection.'''

    in_motion = BooleanProperty(False)
    '''indicates whether any of the member roulettes are in motion.'''

    datetime_fields = ('year', 'month', 'day', 'hour', 'minute', 'second')
    month_size = NumericProperty(None, allownone=True)

    def __init__(self, **kw):
        super(DatetimePicker, self).__init__(**kw)
        self.init_roulettes()
    def init_roulettes(self):
        self._calibrate_month_size_trigger = t = \
                    Clock.create_trigger(self.calibrate_month_size)
        self._adjust_day_cycle_trigger = \
                    Clock.create_trigger(self._adjust_day_cycle, -1)
        now = datetime.now()
        kw = {'density': self.density}
        self.second = second = TimeFormatCyclicRoulette(cycle=60, **kw)
        second.select_and_center(now.second)
        self.minute = minute = TimeFormatCyclicRoulette(cycle=60, **kw)
        minute.select_and_center(now.minute)
        self.hour = hour = TimeFormatCyclicRoulette(cycle=24, **kw)
        hour.select_and_center(now.hour)
        self.year = year = Roulette(**kw)
        year.select_and_center(now.year)
        self.month = month = CyclicRoulette(cycle=12, zero_indexed=False, **kw)
        month.select_and_center(now.month)

        month_size = monthrange(now.year, now.month)[1]
        self.day = day = CyclicRoulette(cycle=month_size, zero_indexed=False,
                                        on_centered=self._adjust_day_cycle_trigger,
                                        **kw)
        day.select_and_center(now.day)

        self.month.bind(selected_value=t)
        self.year.bind(selected_value=t)

        self.set_selected_datetime()
        self._bind_updates()

        children = [
                    year, Dash(), month, Dash(), day, Symbol(),
                    hour, Colon(), minute, Colon(), second,
                    ]
        add = self.add_widget
        width = dp(20)
        for c in children:
            add(c)
            width += c.width
        self.width = width
    def update_width(self, *args):
        width = sum(c.width for c in self.children)
        self.width = width
    def get_datetime(self, *args):
        try:
            d = {field: getattr(self, field).selected_value
                 for field in self.datetime_fields}
            return datetime(**d)
        except:
            return None
    def _update_in_motion(self, *args):
        for field in self.datetime_fields:
            if getattr(self, field).in_motion:
                self.in_motion = True
                return
        self.in_motion = False
        return
    def set_datetime(self, val, *args, **kw):
        '''animatedly set the roulette's datetime to ``val``.
        The keyword argument ``largest_delta`` can be set to True to specify
        that only the largest granularity of time that differs from
        ``val`` to the time shown on the roulettes is to be changed.

        For example, if ``val = datetime(2013, 1, 2, 5, 55, 23)`` and
        current time shown is ``datetime(2013, 1, 2, 6, 02, 33)``, and
        ``largest_delta=True``, then only the hour roulette will be updated
        to center on ``5``, and no other changes are introduced.

        This option is useful for reducing graphical load when linking
        this roulette to changing values of time.'''
        largest_delta = kw.get('largest_delta')
        for field in self.datetime_fields:
            changed = getattr(self, field).select_and_center(getattr(val, field))
            if changed and largest_delta:
                return
    def set_selected_datetime(self, *args):
        new_dt = self.get_datetime()
        if new_dt:
            self.selected_datetime = new_dt
    def _bind_updates(self, *args):
        for field in self.datetime_fields:
            getattr(self, field).bind(selected_value=self.set_selected_datetime,
                                      in_motion=self._update_in_motion)

    def calibrate_month_size(self, *args):
        selected_year = self.year.selected_value
        selected_month = self.month.selected_value
        self.month_size = month_size = monthrange(selected_year,
                                                  selected_month)[1]
        day = self.day
        if day.cycle == month_size:
            return
        if day.selected_value > month_size:
            day.select_and_center(month_size)
        else:
            self._adjust_day_cycle()
    def _adjust_day_cycle(self, *args, **kw):
        new_cycle = kw.get('new_cycle', self.month_size)
        if new_cycle is None or self.day.cycle == new_cycle:
            return
        current_day = self.day.selected_value
        self.day.cycle = new_cycle
        # unless month_size gets set again, guards against erroneous adjustment
        # and infinite loop
        self.month_size = None

        self.day.select_and_center(current_day, animate=False)

if __name__ == '__main__':
    from kivy.base import runTouchApp
    runTouchApp(DatetimePicker())<|endoftext|>


<commit_before># Copyright (c) 2013 Che-Liang Chiou

from SCons.Script import Dir, Environment

from scons_package.builder_maker_builder import BuilderMakerBuilder
from scons_package.builder_maker_registry import BuilderMakerRegistry
from scons_package.label import PackageName
from scons_package.utils import glob

__all__ = ['package_environment',
           'library',
           'program',
           'make_builders',
           'make_variant_builders',
           'glob']

def package_environment(env, package_str=None):
    assert isinstance(env, Environment)
    assert package_str is None or isinstance(package_str, str)
    bmreg = BuilderMakerRegistry.get_instance()
    if package_str is None and Dir('.') == Dir('#'):
        bmreg.set_default_env(env)
    else:
        package_name = PackageName.make_package_name(package_str)
        bmreg.set_package_env(package_name, env)

def program(name, srcs, deps=(), variant=None, env=None):
    assert variant is None or isinstance(variant, str)
    assert env is None or isinstance(env, Environment)
    bmb = BuilderMakerBuilder()
    bmb.set_builder_type('Program')
    bmb.set_name_srcs_deps(name, srcs, deps)
    if variant is not None:
        bmb.set_variant(variant)
    if env is not None:
        bmb.set_env(env)
    bmb.build(BuilderMakerRegistry.get_instance())

def library(name, srcs, deps=(), variant=None, env=None, export_env=None):
    assert variant is None or isinstance(variant, str)
    assert env is None or isinstance(env, Environment)
    assert export_env is None or callable(export_env)
    bmb = BuilderMakerBuilder()
    bmb.set_builder_type('StaticLibrary')
    bmb.set_name_srcs_deps(name, srcs, deps)
    if variant is not None:
        bmb.set_variant(variant)
    if env is not None:
        bmb.set_env(env)
    if export_env is not None:
        bmb.set_export_env(export_env)
    bmb.build(BuilderMakerRegistry.get_instance())

def make_builders(sconscript, build_root, variants, duplicate=1):
    bmreg = BuilderMakerRegistry.get_instance()
    bmreg.make_builders(sconscript, build_root, variants, duplicate)

def make_variant_builders(variant):
    BuilderMakerRegistry.get_instance().make_variant_builders(variant)
<commit_msg>Rename package_str to package in public API<commit_after># Copyright (c) 2013 Che-Liang Chiou

from SCons.Script import Dir, Environment

from scons_package.builder_maker_builder import BuilderMakerBuilder
from scons_package.builder_maker_registry import BuilderMakerRegistry
from scons_package.label import PackageName
from scons_package.utils import glob

__all__ = ['package_environment',
           'library',
           'program',
           'make_builders',
           'make_variant_builders',
           'glob']

def package_environment(env, package=None):
    assert isinstance(env, Environment)
    assert package is None or isinstance(package, str)
    bmreg = BuilderMakerRegistry.get_instance()
    if package is None and Dir('.') == Dir('#'):
        bmreg.set_default_env(env)
    else:
        package_name = PackageName.make_package_name(package)
        bmreg.set_package_env(package_name, env)

def program(name, srcs, deps=(), variant=None, env=None):
    assert variant is None or isinstance(variant, str)
    assert env is None or isinstance(env, Environment)
    bmb = BuilderMakerBuilder()
    bmb.set_builder_type('Program')
    bmb.set_name_srcs_deps(name, srcs, deps)
    if variant is not None:
        bmb.set_variant(variant)
    if env is not None:
        bmb.set_env(env)
    bmb.build(BuilderMakerRegistry.get_instance())

def library(name, srcs, deps=(), variant=None, env=None, export_env=None):
    assert variant is None or isinstance(variant, str)
    assert env is None or isinstance(env, Environment)
    assert export_env is None or callable(export_env)
    bmb = BuilderMakerBuilder()
    bmb.set_builder_type('StaticLibrary')
    bmb.set_name_srcs_deps(name, srcs, deps)
    if variant is not None:
        bmb.set_variant(variant)
    if env is not None:
        bmb.set_env(env)
    if export_env is not None:
        bmb.set_export_env(export_env)
    bmb.build(BuilderMakerRegistry.get_instance())

def make_builders(sconscript, build_root, variants, duplicate=1):
    bmreg = BuilderMakerRegistry.get_instance()
    bmreg.make_builders(sconscript, build_root, variants, duplicate)

def make_variant_builders(variant):
    BuilderMakerRegistry.get_instance().make_variant_builders(variant)
<|endoftext|>


<commit_before>"""The SCons AsciiDoc tool

This is an SCons tool for compiling AsciiDoc documents to various formats using
the `asciidoc` and `a2x` programs using two builders, `AsciiDoc` and `A2X`, to
the construction environment.
"""

# support Python 2.5
from __future__ import with_statement

# TODO: write tests
# TODO: try out docbook, htmlhelp and manpage formats
# FIXME: 'manpage' and 'epub' formats produce xsltproc failures
# TODO: complete implicit dependency handling
#
# NOTE: AsciiDoc does not seem to output extra targets.  In the case where JS
# and CSS is linked to the HTML file, it must be manually copied to the
# appropriate location.  In this case, the files would be part of the source
# code repository anyway, and the dependencies of the target file on them should
# not matter.  Furthermore, they are irrelevant to the produced HTML, and even
# when they are embedded, they reside in a central asciidoc configuration
# directory in $HOME, /etc/ or /usr/local/etc/ (see
# http://www.methods.co.nz/asciidoc/userguide.html#X27).  I believe that is
# *outside* the scope of this AsciiDoc tool.
#
# Actual potential candidates for implicit dependencies:
# - image directories when the data-uri option is set:
#     - iconsdir
#     - imagesdir
# - files referenced in sys::[] macros; basically: expand the glob, split() it
# and check if any of the substrings are files (or directories)
# - find other implicit files used, i.e., from --theme and --filter (asciidoc)
# and from --icons-dir, --stylesheet, and --xsl-file (a2x); see the respective
# man pages
#
# (again, see http://www.methods.co.nz/asciidoc/userguide.html#X27 for more)
#
# Also, see if it is possible to deal with ifdef:[].

#######################################################
# functions used to help generate the build signature #
#######################################################

def _gen_ad_conf_str(target, source, env, for_signature):
    return ' '.join('-f ' + c for c in env['AD_CONFFILES'])

def _gen_ad_attr_str(target, source, env, for_signature):
    return ' '.join('-a "'+a+'"' for a in env['AD_ATTRIBUTES'])

def _gen_a2x_conf_str(target, source, env, for_signature):
    if env['A2X_CONFFILE']:
        return "--conf-file=" + env['A2X_CONFFILE']
    return ''

def _gen_a2x_attr_str(target, source, env, for_signature):
    return ' '.join('-a "'+a+'"' for a in env['A2X_ATTRIBUTES'])

def _gen_a2x_res_str(target, source, env, for_signature):
    return ' '.join('-r "'+r+'"' for r in env['A2X_RESOURCES'])

def _gen_a2x_resman_str(target, source, env, for_signature):
    if env['A2X_RESOURCEMANIFEST']:
        return '-m ' + env['A2X_RESOURCEMANIFEST']
    else:
        return ''

##########################
# generate() and friends #
##########################

def _get_prog_path(env, key, name):
    """Try to find the executable 'name' and store its location in env[key]."""

    # check if the user already specified the location
    try:
        return env[key]
    except KeyError:
        pass

    # asciidoc and a2x may be installed with a '.py' suffix
    prog_path = env.WhereIs(name) or env.WhereIs(name+'.py')

    # Explicitly do not raise an error here. If asciidoc is not installed, then
    # the build system using this tool should be able to deal with it.
    return prog_path

def generate(env):

    import subprocess as subp
    import pseudo_builders

    # put the builders in the environment
    env['BUILDERS']['AsciiDoc'] = pseudo_builders.asciidoc_builder
    env['BUILDERS']['A2X']      = pseudo_builders.a2x_builder

    # try to find the asciidoc and a2x executables
    ad_asciidoc = _get_prog_path(env, 'AD_ASCIIDOC', 'asciidoc')
    a2x_a2x     = _get_prog_path(env, 'A2X_A2X', 'a2x')

    # get the asciidoc version
    try:
        ad_proc = subp.Popen([ad_asciidoc, '--version'], stdout=subp.PIPE)
        ad_ver  = ad_proc.communicate()[0].split()[-1]
    except:
        ad_ver = ''

    # get the a2x version
    try:
        a2x_proc = subp.Popen([a2x_a2x, '--version'], stdout=subp.PIPE)
        a2x_ver = a2x_proc.communicate()[0].split()[-1]
    except:
        a2x_ver = ''

    # set asciidoc defaults; should match the asciidoc(1) defaults
    env['AD_ASCIIDOC']    = ad_asciidoc
    env['AD_VERSION']     = ad_ver
    env['AD_BACKEND']     = 'html'
    env['AD_DOCTYPE']     = 'article'
    env['AD_CONFFILES']   = []
    env['AD_ATTRIBUTES']  = []

    # set a2x defaults; should match the a2x(1) defaults
    env['A2X_A2X']        = a2x_a2x
    env['A2X_VERSION']    = a2x_ver
    env['A2X_FORMAT']     = 'pdf'
    env['A2X_DOCTYPE']    = 'article'
    env['A2X_CONFFILE']   = ''
    env['A2X_ATTRIBUTES'] = []
    env['A2X_RESOURCES']  = []
    env['A2X_RESOURCEMANIFEST'] = ''
    env['A2X_KEEPARTIFACTS']    = True

    # variables used to generate the build signature
    env['AD_GET_CONF']    = _gen_ad_conf_str
    env['AD_GET_ATTR']    = _gen_ad_attr_str
    env['A2X_GET_CONF']   = _gen_a2x_conf_str
    env['A2X_GET_ATTR']   = _gen_a2x_attr_str
    env['A2X_GET_RES']    = _gen_a2x_res_str
    env['A2X_GET_RESMAN'] = _gen_a2x_resman_str

def exists(env):
    # expect a2x to be there if asciidoc is
    return _get_prog_path(env, 'AD_ASCIIDOC', 'asciidoc')
<commit_msg>Improve handling of construction variable defaults.<commit_after>"""The SCons AsciiDoc tool

This is an SCons tool for compiling AsciiDoc documents to various formats using
the `asciidoc` and `a2x` programs using two builders, `AsciiDoc` and `A2X`, to
the construction environment.
"""

# support Python 2.5
from __future__ import with_statement
import SCons.Util

# TODO: write tests
# TODO: try out docbook, htmlhelp and manpage formats
# FIXME: 'manpage' and 'epub' formats produce xsltproc failures
# TODO: complete implicit dependency handling
#
# NOTE: AsciiDoc does not seem to output extra targets.  In the case where JS
# and CSS is linked to the HTML file, it must be manually copied to the
# appropriate location.  In this case, the files would be part of the source
# code repository anyway, and the dependencies of the target file on them should
# not matter.  Furthermore, they are irrelevant to the produced HTML, and even
# when they are embedded, they reside in a central asciidoc configuration
# directory in $HOME, /etc/ or /usr/local/etc/ (see
# http://www.methods.co.nz/asciidoc/userguide.html#X27).  I believe that is
# *outside* the scope of this AsciiDoc tool.
#
# Actual potential candidates for implicit dependencies:
# - image directories when the data-uri option is set:
#     - iconsdir
#     - imagesdir
# - files referenced in sys::[] macros; basically: expand the glob, split() it
# and check if any of the substrings are files (or directories)
# - find other implicit files used, i.e., from --theme and --filter (asciidoc)
# and from --icons-dir, --stylesheet, and --xsl-file (a2x); see the respective
# man pages
#
# (again, see http://www.methods.co.nz/asciidoc/userguide.html#X27 for more)
#
# Also, see if it is possible to deal with ifdef:[].

#######################################################
# functions used to help generate the build signature #
#######################################################

def _gen_ad_conf_str(target, source, env, for_signature):
    return ' '.join('-f ' + c for c in env['AD_CONFFILES'])

def _gen_ad_attr_str(target, source, env, for_signature):
    return ' '.join('-a "'+a+'"' for a in env['AD_ATTRIBUTES'])

def _gen_a2x_conf_str(target, source, env, for_signature):
    if env['A2X_CONFFILE']:
        return "--conf-file=" + env['A2X_CONFFILE']
    return ''

def _gen_a2x_attr_str(target, source, env, for_signature):
    return ' '.join('-a "'+a+'"' for a in env['A2X_ATTRIBUTES'])

def _gen_a2x_res_str(target, source, env, for_signature):
    return ' '.join('-r "'+r+'"' for r in env['A2X_RESOURCES'])

def _gen_a2x_resman_str(target, source, env, for_signature):
    if env['A2X_RESOURCEMANIFEST']:
        return '-m ' + env['A2X_RESOURCEMANIFEST']
    else:
        return ''

##########################
# generate() and friends #
##########################

def _get_prog_path(env, key, name):
    """Try to find the executable 'name' and store its location in env[key]."""

    # check if the user already specified the location
    try:
        return env[key]
    except KeyError:
        pass

    # asciidoc and a2x may be installed with a '.py' suffix
    prog_path = env.WhereIs(name) or env.WhereIs(name+'.py')

    # Explicitly do not raise an error here. If asciidoc is not installed, then
    # the build system using this tool should be able to deal with it.
    return prog_path

def generate(env):

    import subprocess as subp
    import pseudo_builders

    # put the builders in the environment
    env['BUILDERS']['AsciiDoc'] = pseudo_builders.asciidoc_builder
    env['BUILDERS']['A2X']      = pseudo_builders.a2x_builder

    # try to find the asciidoc and a2x executables
    ad_asciidoc = _get_prog_path(env, 'AD_ASCIIDOC', 'asciidoc')
    a2x_a2x     = _get_prog_path(env, 'A2X_A2X', 'a2x')

    # get the asciidoc version
    try:
        ad_proc = subp.Popen([ad_asciidoc, '--version'], stdout=subp.PIPE)
        ad_ver  = ad_proc.communicate()[0].split()[-1]
    except:
        ad_ver = ''

    # get the a2x version
    try:
        a2x_proc = subp.Popen([a2x_a2x, '--version'], stdout=subp.PIPE)
        a2x_ver = a2x_proc.communicate()[0].split()[-1]
    except:
        a2x_ver = ''

    env.SetDefault(
        # set asciidoc defaults; should match the asciidoc(1) defaults
        AD_ASCIIDOC    = ad_asciidoc,
        AD_VERSION     = ad_ver,
        AD_BACKEND     = 'html',
        AD_DOCTYPE     = 'article',
        AD_CONFFILES   = SCons.Util.CLVar(''),
        AD_ATTRIBUTES  = SCons.Util.CLVar(''),
        AD_FLAGS       = SCons.Util.CLVar(''),

        # set a2x defaults; should match the a2x(1) defaults
        A2X_A2X        = a2x_a2x,
        A2X_VERSION    = a2x_ver,
        A2X_FORMAT     = 'pdf',
        A2X_DOCTYPE    = 'article',
        A2X_CONFFILE   = '',
        A2X_ATTRIBUTES = SCons.Util.CLVar(''),
        A2X_RESOURCES  = SCons.Util.CLVar(''),
        A2X_RESOURCEMANIFEST = '',
        A2X_KEEPARTIFACTS    = True,
        A2X_FLAGS      = SCons.Util.CLVar(''),

        # variables used to generate the build signature
        AD_GET_CONF    = _gen_ad_conf_str,
        AD_GET_ATTR    = _gen_ad_attr_str,
        A2X_GET_CONF   = _gen_a2x_conf_str,
        A2X_GET_ATTR   = _gen_a2x_attr_str,
        A2X_GET_RES    = _gen_a2x_res_str,
        A2X_GET_RESMAN = _gen_a2x_resman_str,
    )

def exists(env):
    # expect a2x to be there if asciidoc is
    return _get_prog_path(env, 'AD_ASCIIDOC', 'asciidoc')
<|endoftext|>


<commit_before>#/usr/bin/python2

'''
time mpiexec -n 8 python batch.py movie_filename
'''

import numpy as np
import scipy as sp
from scipy import misc
from scipy import stats
import mpi4py.MPI as mpi
import pylab as plt
from matplotlib.ticker import MultipleLocator, FormatStrFormatter
import datetime as dt
import os
import sys
import cv2
import glob
import time
#import ipdb

class Video_class(object):

    def __init__(self, video_path):
        self.comm = mpi.COMM_WORLD
        self.size = self.comm.Get_size()
        self.rank = self.comm.Get_rank()
        #video info
        self.video_path = video_path
        self.cap = cv2.VideoCapture(video_path)
        self.f_rate = int(self.cap.get(cv2.cv.CV_CAP_PROP_FPS))
        self.frames = int(self.cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT))
        self.f_sec = 1 / self.f_rate
        self.width = int(self.cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH))
        self.height = int(self.cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT))

    def _get_inital_master(self, samples):
        '''samples randomly from the video to get a inital master frame'''
        # Get empty frame
        self.cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, 0)
        _, inital_frame = self.cap.read()
        inital_frame = np.float32(inital_frame *0)
        # get random samples
        sam_array = np.sort(np.random.randint(0, self.frames, samples))
        count = 0.
        for frame_no in sam_array:
            self.cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, frame_no)
            # get frame
            sucess, frame = self.cap.read()
            if not sucess:
                continue
            count += 1
            inital_frame += frame
        inital_frame /= count
        return inital_frame

    def parallel_moving_ave(self, frame_array):
        '''Does same as moving_ave_chi but in parrallel'''
        # Check for master image
        if not 'moving_ave_frame' in vars(self):
            self.moving_ave_frame = self._get_inital_master(120)

        self.frame_no = frame_array
        self.frame_chi = []
        self.frame_time = []
        # start chi square
        x,y,z = self.moving_ave_frame.shape
        ddof = float(x * y)
        for frame_no in frame_array:
            self.cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, frame_no)
            success, frame = self.cap.read()
            if not success:
                # remove frame_no
                self.frame_no.pop(self.frame_no.index(frame_no))
                continue
            self.frame_time.append(self.cap.get(cv2.cv.CV_CAP_PROP_POS_MSEC))
            # Cal chi
            self.frame_chi.append(chisquare(frame, self.moving_ave_frame).sum()/ddof)
            # Cal new ave frame
            cv2.accumulateWeighted(frame, self.moving_ave_frame, 0.020)

        return self.frame_no, self.frame_time, self.frame_chi

    def moving_ave_chi(self, max_frames=-1, fps=1, plot=False):
        '''Uses moving average for master frame and calculates fps frames per second'''
        if max_frames < 1:
            max_frames = self.frames
        # set number of steps to skip
        stride = int(round(self.f_rate / float(fps)))
        # get inital aveage frame
        self.moving_ave_frame = self._get_inital_master(120)

        # out puts
        self.frame_no = []
        self.frame_chi = []
        self.frame_time = []
        # start chi square
        x,y,z = self.moving_ave_frame.shape
        ddof = float(x * y)
        for frame_no in xrange(0, max_frames, stride):
            # Get chi square
            self.cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, frame_no)
            success, frame = self.cap.read()
            if not success:
                continue
            self.frame_no.append(frame_no)
            self.frame_time.append(self.cap.get(cv2.cv.CV_CAP_PROP_POS_MSEC))
            # Cal chi
            self.frame_chi.append(chisquare(frame, self.moving_ave_frame).sum()/ddof)
            # Cal new ave frame
            cv2.accumulateWeighted(frame, self.moving_ave_frame, 0.020)
            # Show moving Ave Frame and chi plot
            if plot:
                cv2.imshow('Ave Frame',self.moving_ave_frame)
                #cv2.waitKey(100)

    def _msec2min(self, msec):
        '''Converts miliseconds to min'''
        return msec * 1.6666666666666667e-05

    def _msec2sec(self, msec):
        '''Converts mili-sec to sec'''
        return msec * 10**-3

    def make_master_im(self, max_frames=-1, step=-1):
        '''makes master in memory'''
        if max_frames < 1 and step < 1:
            max_frames = self.frames
            step = self.f_rate
        elif max_frames < 1 and step >= 1:
            max_frames = self.frames
        elif max_frames >= 1 and step < 1:
            step = self.local_i / (max_frames / self.size)

        print step, max_frames

        #print self.local_i, step, max_frames / self.size
        #initalize master image

        _, self.master_image = self.cap.read()
        sample = np.unravel_index(np.random.randint(0, len(self.master_image.ravel())),self.master_image.shape)
        self.master_image = np.asarray(self.master_image, dtype=float)
        #for image_no in xrange(1, max_frames):
        for image_no in xrange(self.local_startframe, self.local_endframe, step):
            self.cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, image_no)
            print image_no, step, self.local_startframe, self.local_endframe, self.frames
            _, temp_image = self.cap.read()
            out.append(temp_image)
            temp_image = np.asarray(temp_image, dtype=float)
            self.master_image += temp_image
        self.master_image /= float(max_frames)

    def image_chi(self, max_frames=-1, step=-1):
        '''
        Calculate chi squared on the images
        '''
        if max_frames < 1 and step < 1:
            max_frames = self.frames
            step = self.f_rate
        elif max_frames < 1 and step >= 1:
            max_frames = self.frames
        elif max_frames >= 1 and step < 1:
            step = self.local_i / (max_frames / self.size)

        self.frame_no = []
        self.frame_chi = []
        print "About to start doing Chi-squared"
        x, y, z = self.master_image.shape
        ddof = x*y
        #for i_base in xrange(0, max_frames):
        for i_base in xrange(self.local_startframe, self.local_endframe, step):
            self.cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, i_base)
            print i_base, step, self.local_startframe, self.local_endframe, self.frames
            _, images = self.cap.read()
            # Scale images so there are non nans or inf from chi squared test
            chi = chisquare(np.float32(images)+1, self.master_image+1)
            reduced = np.sum(chi) / ( ddof )
            self.frame_no.append(float(i_base))
            self.frame_chi.append(float(reduced))

        self.frame_no = np.asarray(self.frame_no)
        self.frame_chi = np.asarray(self.frame_chi)
        self.comm.Barrier()

        print "About to start zipping..."
        with open(self.video_path + '.dat', 'a') as outfile:
            print "About to start zipping... I am rank ", self.rank
            time.sleep(0.1*self.rank)
            zipped = zip(self.frame_no, self.frame_chi)
            np.savetxt(outfile, zipped)
        self.comm.Barrier()
    #THIS FILE OUTPUT WILL BE USED FOR POSTPROCESSING IF NEEDS BE

    def plot(self, individual=True):
        print "I am about to start drawing those amazing figures you really want to see!"
        majorLocator   = MultipleLocator(5)
        majorFormatter = FormatStrFormatter('%d')
        minorLocator   = MultipleLocator(1)

        frame_no, frame_chi = self.frame_no, self.frame_chi
        # in mili seconds
        frameTime = np.asarray(self.frame_time)
        redChi = frame_chi

        self.dpi = 600
        # time in min
        #ipdb.set_trace()
        minTime, maxTime = self._msec2min(min(frameTime)), self._msec2min(max(frameTime))
        minChi, maxChi = min(redChi), max(redChi)
        averageChi = float(sum(redChi) / len(redChi))

        #plt.axhline(y=3*minChi)

        ax = plt.subplot(1, 1, 1)
        #plt.figure()
        ax.xaxis.set_major_locator(majorLocator)
        ax.xaxis.set_major_formatter(majorFormatter)
        ax.xaxis.set_minor_locator(minorLocator)

        plt.tick_params(axis='both', which='major', length=10)
        plt.tick_params(axis='both', which='minor', length=5)

        plt.ylim([minChi, maxChi])
        plt.xlim([minTime, maxTime])
        plt.xlabel("Time (min)")
        plt.ylabel("Reduced Chi-squared")

        plt.gca().set_yscale('log')

        xpos, ypos = float(minTime), float(maxChi/1.5)
        plt.text(xpos, ypos, self.video_path)

        if not individual:
            if self.rank == 1:
                plt.plot(self._msec2min(frameTime),redChi, 'r-')
                plt.savefig(self.video_path + ".jpg", dpi=self.dpi)
                plt.clf()
        else:
            for i in xrange(len(frameTime)):
                pos = float(i)
                plt.axvline(x=pos)
            plt.plot(self._msec2min(frameTime), redChi, 'k-')
            plt.savefig(self.video_path + ".jpg", dpi=self.dpi)
            plt.show()
            plt.clf()
        #plt.savefig(temp_folder + "reduced.eps")
        #plt.savefig(rootfile + ".eps")
        #ipdb.set_trace()
        #plt.show()
        '''
        for i in xrange(len(frameTime)):
            output = (temp_folder + "image%.7d.jpg" % i)

            ax = plt.subplot(1, 1, 1)

            plt.axhline(y=3*minChi)

            #plt.figure()
            ax.xaxis.set_major_locator(majorLocator)
            ax.xaxis.set_major_formatter(majorFormatter)
            ax.xaxis.set_minor_locator(minorLocator)

            plt.tick_params(axis='both', which='major', length=10)
            plt.tick_params(axis='both', which='minor', length=5)

            plt.ylim([minChi, maxChi])
            plt.xlim([minTime, maxTime])
            plt.xlabel("Time (min)")
            plt.ylabel("Reduced Chi-squared")

            plt.gca().set_yscale('log')

            xpos, ypos = float(minTime), float(maxChi/1.5)
            plt.text(xpos, ypos, rootfile)

            pos = float(i / 60.)
            #print output, pos
            plt.axvline(x=pos)
            plt.plot(frameTime, redChi, 'k-')
            plt.savefig(output)
            plt.clf()
            '''
    def make_movie(self):
        '''
    TO CREATE MOVIE
    http://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_gui/py_video_display/py_video_display.html
    '''

        # Define the codec and create VideoWriter object
        fourcc = cv2.cv.CV_FOURCC(*'XVID')
        out = cv2.VideoWriter(self.video_path + '.avi',fourcc, 1, (self.width,self.height))
        if self.rank == 0:
            print "Making a movie"
            x_offset=y_offset= 0
            for i in xrange(0, len(self.frame_no), 1):
                #if self.frame_chi[i] > self.minChi:
                print self.frame_chi[i]
                    #images = cv2.imread(files[i])
                    #s_img = cv2.imread(output[i])
                    #s_img = cv2.resize(s_img, (0,0), fx=0.5, fy=0.5)
                    #images[y_offset:y_offset+s_img.shape[0], x_offset:x_offset+s_img.shape[1]] = s_img
                    #out.write()

    def finialize(self):
        '''Closes everything'''
        self.cap.release()
        cv2.destroyAllWindows()
        out.release()

    def mpi_work_split(self, max_frames=-1, size=None, fps=1, start=0):
        '''Splits work up from worker size'''
        if not size is None and size > 1:
            self.size = size
        if max_frames < 1:
            max_frames = self.frames

        stride = int(round(self.f_rate / float(fps)))
        # Make split array
        split = np.linspace(start, max_frames, self.size+1).round()
        frame_min, frame_max = int(split[self.rank]),int(split[self.rank + 1])
        return range(frame_min, frame_max, stride)

    def aggrigate_to_root(self, frame_no, frame_time, frame_chi):
        '''Send and organizes data at root'''
        if self.rank == 0:
            reciv =[(frame_no, frame_time, frame_chi)]
            for source in xrange(1,self.size):
                reciv.append(self.comm.recv(source=source))
                print 'Recived from process %i'%source
            self.frame_no, self.frame_time, self.frame_chi = np.hstack(reciv)

        else:
            self.comm.send((frame_no, frame_time, frame_chi), dest=0)

def chisquare(f_obs, f_exp, axis=0):
    '''calculates chi squared test correctly for 3D arrays'''
    return (f_obs - f_exp)**2 / f_exp

if __name__ == '__main__':

    # Test multiprocessing
    #frames = 10000
    video = Video_class('00016.MTS')
    # Single process
    if video.rank == 0:
        t_single = mpi.Wtime()
        video.moving_ave_chi()
        t_single -= mpi.Wtime()
        del video.moving_ave_frame
    video.comm.barrier()
    # Multiprocess
    t_multi = mpi.Wtime()
    work_array = video.mpi_work_split()
    frame_no, frame_time, frame_chi = video.parallel_moving_ave(work_array)
    video.aggrigate_to_root(frame_no, frame_time, frame_chi)
    video.comm.barrier()
    t_multi -= mpi.Wtime()
    if video.rank == 0:
        print 'Single time is %2.0f and Multi time is %2.0f for speed up of %2.1f times'%(abs(t_single),abs(t_multi), t_multi/t_single)
    #plt.hist(freq, 5)
    #plt.show()
    #video.image_chi()
    video.plot()
    #video.make_movie()
<commit_msg>Change how I sample for moving Average<commit_after>#/usr/bin/python2

'''
time mpiexec -n 8 python batch.py movie_filename
'''

import numpy as np
import scipy as sp
from scipy import misc
from scipy import stats
import mpi4py.MPI as mpi
import pylab as plt
from matplotlib.ticker import MultipleLocator, FormatStrFormatter
import datetime as dt
import os
import sys
import cv2
import glob
import time
#import ipdb

class Video_class(object):

    def __init__(self, video_path):
        self.comm = mpi.COMM_WORLD
        self.size = self.comm.Get_size()
        self.rank = self.comm.Get_rank()
        #video info
        self.video_path = video_path
        self.cap = cv2.VideoCapture(video_path)
        self.f_rate = int(self.cap.get(cv2.cv.CV_CAP_PROP_FPS))
        self.frames = int(self.cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT))
        self.f_sec = 1 / self.f_rate
        self.width = int(self.cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH))
        self.height = int(self.cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT))

    def _get_inital_master(self, start, samples):
        '''samples previous frames from the video to get a inital master frame
        Start is the frame number to start, and samples is how many frames to
        sample'''
        # Get empty frame
        self.cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, start)
        sucess, inital_frame = self.cap.read()
        while not sucess:
            sucess, inital_frame = self.cap.read()
        inital_frame = np.float32(inital_frame)
        # get random samples
        sam_array = np.arange(start, start+samples)
        count = 0.
        for frame_no in sam_array:
            #self.cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, frame_no)
            # get frame
            sucess, frame = self.cap.read()
            if not sucess:
                continue
            cv2.accumulateWeighted(np.float32(frame), inital_frame, 0.020)
            count += 1

        return inital_frame

    def parallel_moving_ave(self, frame_array, n_sample=120):
        '''Does same as moving_ave_chi but in parrallel'''
        # Check for master image
        if not 'moving_ave_frame' in vars(self):
            # Check if at zero
            if np.min(frame_array) - n_sample < 0:
                start = 0
            else:
                start = np.min(frame_array) - n_sample
            self.moving_ave_frame = self._get_inital_master(start, n_sample)

        self.frame_no = frame_array
        self.frame_chi = []
        self.frame_time = []
        # start chi square
        x,y,z = self.moving_ave_frame.shape
        ddof = float(x * y)
        for frame_no in frame_array:
            self.cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, frame_no)
            success, frame = self.cap.read()
            if not success:
                # remove frame_no
                self.frame_no.pop(self.frame_no.index(frame_no))
                continue
            self.frame_time.append(self.cap.get(cv2.cv.CV_CAP_PROP_POS_MSEC))
            # Cal chi
            frame = np.float32(frame)
            # add 1 so chi square can't be nan or inf
            self.frame_chi.append(chisquare(frame+1,
                                            self.moving_ave_frame+1).sum()
                                                                     / ddof)
            # Cal new ave frame
            cv2.accumulateWeighted(frame, self.moving_ave_frame, 0.020)

        return self.frame_no, self.frame_time, self.frame_chi

    def moving_ave_chi(self, max_frames=-1, fps=1, plot=False):
        '''Uses moving average for master frame and calculates fps frames per second'''
        if max_frames < 1:
            max_frames = self.frames
        # set number of steps to skip
        stride = int(round(self.f_rate / float(fps)))
        # get inital aveage frame
        self.moving_ave_frame = self._get_inital_master(0, 120)

        # out puts
        self.frame_no = []
        self.frame_chi = []
        self.frame_time = []
        # start chi square
        x,y,z = self.moving_ave_frame.shape
        ddof = float(x * y)
        for frame_no in xrange(0, max_frames, stride):
            # Get chi square
            self.cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, frame_no)
            success, frame = self.cap.read()
            if not success:
                continue
            self.frame_no.append(frame_no)
            self.frame_time.append(self.cap.get(cv2.cv.CV_CAP_PROP_POS_MSEC))
            # Cal chi
            self.frame_chi.append(chisquare(frame, self.moving_ave_frame).sum()/ddof)
            # Cal new ave frame
            cv2.accumulateWeighted(frame, self.moving_ave_frame, 0.020)
            # Show moving Ave Frame and chi plot
            if plot:
                cv2.imshow('Ave Frame',self.moving_ave_frame)
                #cv2.waitKey(100)

    def _msec2min(self, msec):
        '''Converts miliseconds to min'''
        return msec * 1.6666666666666667e-05

    def _msec2sec(self, msec):
        '''Converts mili-sec to sec'''
        return msec * 10**-3

    def plot(self, individual=True):
        print "I am about to start drawing those amazing figures you really want to see!"
        majorLocator   = MultipleLocator(5)
        majorFormatter = FormatStrFormatter('%d')
        minorLocator   = MultipleLocator(1)

        frame_no, frame_chi = self.frame_no, self.frame_chi
        # in mili seconds
        frameTime = np.asarray(self.frame_time)
        redChi = frame_chi

        self.dpi = 600
        # time in min
        #ipdb.set_trace()
        minTime, maxTime = self._msec2min(min(frameTime)), self._msec2min(max(frameTime))
        minChi, maxChi = min(redChi), max(redChi)
        averageChi = float(sum(redChi) / len(redChi))

        #plt.axhline(y=3*minChi)

        ax = plt.subplot(1, 1, 1)
        #plt.figure()
        ax.xaxis.set_major_locator(majorLocator)
        ax.xaxis.set_major_formatter(majorFormatter)
        ax.xaxis.set_minor_locator(minorLocator)

        plt.tick_params(axis='both', which='major', length=10)
        plt.tick_params(axis='both', which='minor', length=5)

        plt.ylim([minChi, maxChi])
        plt.xlim([minTime, maxTime])
        plt.xlabel("Time (min)")
        plt.ylabel("Reduced Chi-squared")

        plt.gca().set_yscale('log')

        xpos, ypos = float(minTime), float(maxChi/1.5)
        plt.text(xpos, ypos, self.video_path)

        if not individual:
            if self.rank == 1:
                plt.plot(self._msec2min(frameTime),redChi, 'r-')
                plt.savefig(self.video_path + ".jpg", dpi=self.dpi)
                plt.clf()
        else:
            for i in xrange(len(frameTime)):
                pos = float(i)
                plt.axvline(x=pos)
            plt.plot(self._msec2min(frameTime), redChi, 'k-')
            plt.savefig(self.video_path + ".jpg", dpi=self.dpi)
            plt.show()
            plt.clf()
        #plt.savefig(temp_folder + "reduced.eps")
        #plt.savefig(rootfile + ".eps")
        #ipdb.set_trace()
        #plt.show()
        '''
        for i in xrange(len(frameTime)):
            output = (temp_folder + "image%.7d.jpg" % i)

            ax = plt.subplot(1, 1, 1)

            plt.axhline(y=3*minChi)

            #plt.figure()
            ax.xaxis.set_major_locator(majorLocator)
            ax.xaxis.set_major_formatter(majorFormatter)
            ax.xaxis.set_minor_locator(minorLocator)

            plt.tick_params(axis='both', which='major', length=10)
            plt.tick_params(axis='both', which='minor', length=5)

            plt.ylim([minChi, maxChi])
            plt.xlim([minTime, maxTime])
            plt.xlabel("Time (min)")
            plt.ylabel("Reduced Chi-squared")

            plt.gca().set_yscale('log')

            xpos, ypos = float(minTime), float(maxChi/1.5)
            plt.text(xpos, ypos, rootfile)

            pos = float(i / 60.)
            #print output, pos
            plt.axvline(x=pos)
            plt.plot(frameTime, redChi, 'k-')
            plt.savefig(output)
            plt.clf()
            '''
    def make_movie(self):
        '''
    TO CREATE MOVIE
    http://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_gui/py_video_display/py_video_display.html
    '''

        # Define the codec and create VideoWriter object
        fourcc = cv2.cv.CV_FOURCC(*'XVID')
        out = cv2.VideoWriter(self.video_path + '.avi',fourcc, 1, (self.width,self.height))
        if self.rank == 0:
            print "Making a movie"
            x_offset=y_offset= 0
            for i in xrange(0, len(self.frame_no), 1):
                #if self.frame_chi[i] > self.minChi:
                print self.frame_chi[i]
                    #images = cv2.imread(files[i])
                    #s_img = cv2.imread(output[i])
                    #s_img = cv2.resize(s_img, (0,0), fx=0.5, fy=0.5)
                    #images[y_offset:y_offset+s_img.shape[0], x_offset:x_offset+s_img.shape[1]] = s_img
                    #out.write()

    def finialize(self):
        '''Closes everything'''
        self.cap.release()
        cv2.destroyAllWindows()
        out.release()

    def mpi_work_split(self, max_frames=-1, size=None, fps=1, start=0):
        '''Splits work up from worker size'''
        if not size is None and size > 1:
            self.size = size
        if max_frames < 1:
            max_frames = self.frames

        stride = int(round(self.f_rate / float(fps)))
        # Make split array
        split = np.linspace(start, max_frames, self.size+1).round()
        frame_min, frame_max = int(split[self.rank]),int(split[self.rank + 1])
        return range(frame_min, frame_max, stride)

    def aggrigate_to_root(self, frame_no, frame_time, frame_chi):
        '''Send and organizes data at root'''
        if self.rank == 0:
            reciv =[(frame_no, frame_time, frame_chi)]
            for source in xrange(1,self.size):
                reciv.append(self.comm.recv(source=source))
                print 'Recived from process %i'%source
            self.frame_no, self.frame_time, self.frame_chi = np.hstack(reciv)

        else:
            self.comm.send((frame_no, frame_time, frame_chi), dest=0)

def chisquare(f_obs, f_exp, axis=0):
    '''calculates chi squared test correctly for 3D arrays'''
    return (f_obs - f_exp)**2 / f_exp

if __name__ == '__main__':
    import cPickle as pik
    # Test multiprocessing
    #frames = 10000
    video = Video_class('00016.MTS')
    # Single process
    '''if video.rank == 0:
        t_single = mpi.Wtime()
        video.moving_ave_chi()
        t_single -= mpi.Wtime()
        del video.moving_ave_frame'''
    video.comm.barrier()
    # Multiprocess
    t_multi = mpi.Wtime()
    work_array = video.mpi_work_split()
    frame_no, frame_time, frame_chi = video.parallel_moving_ave(work_array)
    video.aggrigate_to_root(frame_no, frame_time, frame_chi)
    video.comm.barrier()
    t_multi -= mpi.Wtime()
    if video.rank == 0:
        # Save
        pik.dump((video.frame_no, video.frame_time, video.frame_chi),open('t','w'),2)
        #print 'Single time is %2.0f and Multi time is %2.0f for speed up of %2.1f times'%(abs(t_single),abs(t_multi), t_multi/t_single)
        video.plot()
        #video.make_movie()
<|endoftext|>


<commit_before>"""EcoData Retriever Wizard

Running this module directly will launch the download wizard, allowing the user
to choose from all scripts.

The main() function can be used for bootstrapping.

"""
from __future__ import print_function
from __future__ import absolute_import
from builtins import str
from imp import reload
import os
import platform
import sys
# sys removes the setdefaultencoding method at startup; reload to get it back
reload(sys)
if hasattr(sys, 'setdefaultencoding'):
    # set default encoding to utf-8 to decode source text
    sys.setdefaultencoding('utf-8')
from retriever import VERSION, MASTER, SCRIPT_LIST, sample_script, current_platform
from retriever.engines import engine_list
from retriever.lib.repository import check_for_updates
from retriever.lib.lists import Category, get_lists
from retriever.lib.tools import choose_engine, name_matches, reset_retriever
from retriever.lib.get_opts import parser

def main():
    """This function launches the EcoData Retriever."""
    if len(sys.argv) == 1:
        # if no command line args are passed, show the help options
        parser.parse_args(['-h'])

    else:
        # otherwise, parse them

        script_list = SCRIPT_LIST()

        args = parser.parse_args()
        if args.quiet:
            sys.stdout = open(os.devnull, 'w')

        if args.command == 'help':
            parser.parse_args(['-h'])

        if hasattr(args, 'compile') and args.compile:
            script_list = SCRIPT_LIST(force_compile=True)

        if args.command == 'update':
            check_for_updates()
            script_list = SCRIPT_LIST()
            return

        elif args.command == 'citation':
            if args.dataset is None:
                citation_path = os.path.join(os.path.split(__file__)[0], '../CITATION')
                print("\nCitation for retriever:\n")
                with open(citation_path) as citation_file:
                    print(citation_file.read())
            else:
                scripts = name_matches(script_list, args.dataset)
                for dataset in scripts:
                    print("\nDataset:  {}".format(dataset.name))
                    print("Citation:   {}".format(dataset.citation))
                    print("Description:   {}\n".format(dataset.description))

            return

        elif args.command == 'new':
            f = open(args.filename, 'w')
            f.write(sample_script)
            f.close()

            return

        elif args.command == 'reset':
            reset_retriever(args.scope)
            return

        if args.command == 'ls' or args.dataset is None:

            # If scripts have never been downloaded there is nothing to list
            if not script_list:
                print("No scripts are currently available. Updating scripts now...")
                check_for_updates()
                print("\n\nScripts downloaded.\n")
                script_list = SCRIPT_LIST()

            all_scripts = []

            for script in script_list:
                if script.name:
                    if args.l!=None:
                        script_name = script.name + "\nShortname: " + script.shortname+"\n"
                        if script.tags:
                            script_name += "Tags: "+str([tag for tag in script.tags])+"\n"
                        not_found = 0
                        for term in args.l:
                            if script_name.lower().find(term.lower()) == -1:
                                not_found = 1
                                break
                        if not_found == 0:
                            all_scripts.append(script_name)
                    else:
                        script_name = script.shortname
                        all_scripts.append(script_name)

            all_scripts = sorted(all_scripts, key=lambda s: s.lower())

            print("Available datasets : {}\n".format(len(all_scripts)))

            if args.l==None:
                from retriever import lscolumns
                lscolumns.printls(sorted(all_scripts, key=lambda s: s.lower()))
            else:
                count = 1
                for script in all_scripts:
                    print ("%d. %s"%(count, script))
                    count += 1
            return

        engine = choose_engine(args.__dict__)

        if hasattr(args, 'debug') and args.debug:
            debug = True
        else:
            debug = False

        scripts = name_matches(script_list, args.dataset)
        if scripts:
            for dataset in scripts:
                print("=> Installing", dataset.name)
                try:
                    dataset.download(engine, debug=debug)
                    dataset.engine.final_cleanup()
                except KeyboardInterrupt:
                    pass
                except Exception as e:
                    print(e)
                    if debug: raise
            print("Done!")
        else:
            print("The dataset {} isn't currently available in the Retriever".format(args.dataset))
            print("Run 'retriever ls to see a list of currently available datasets")

if __name__ == "__main__":
    main()
<commit_msg>Set default encoding to 'latin-1'<commit_after>"""EcoData Retriever Wizard

Running this module directly will launch the download wizard, allowing the user
to choose from all scripts.

The main() function can be used for bootstrapping.

"""
from __future__ import print_function
from __future__ import absolute_import
from builtins import str
from imp import reload
import os
import platform
import sys
# sys removes the setdefaultencoding method at startup; reload to get it back
reload(sys)
if hasattr(sys, 'setdefaultencoding'):
    # set default encoding to utf-8 to decode source text
    sys.setdefaultencoding('latin-1')
from retriever import VERSION, MASTER, SCRIPT_LIST, sample_script, current_platform
from retriever.engines import engine_list
from retriever.lib.repository import check_for_updates
from retriever.lib.lists import Category, get_lists
from retriever.lib.tools import choose_engine, name_matches, reset_retriever
from retriever.lib.get_opts import parser

def main():
    """This function launches the EcoData Retriever."""
    if len(sys.argv) == 1:
        # if no command line args are passed, show the help options
        parser.parse_args(['-h'])

    else:
        # otherwise, parse them

        script_list = SCRIPT_LIST()

        args = parser.parse_args()
        if args.quiet:
            sys.stdout = open(os.devnull, 'w')

        if args.command == 'help':
            parser.parse_args(['-h'])

        if hasattr(args, 'compile') and args.compile:
            script_list = SCRIPT_LIST(force_compile=True)

        if args.command == 'update':
            check_for_updates()
            script_list = SCRIPT_LIST()
            return

        elif args.command == 'citation':
            if args.dataset is None:
                citation_path = os.path.join(os.path.split(__file__)[0], '../CITATION')
                print("\nCitation for retriever:\n")
                with open(citation_path) as citation_file:
                    print(citation_file.read())
            else:
                scripts = name_matches(script_list, args.dataset)
                for dataset in scripts:
                    print("\nDataset:  {}".format(dataset.name))
                    print("Citation:   {}".format(dataset.citation))
                    print("Description:   {}\n".format(dataset.description))

            return

        elif args.command == 'new':
            f = open(args.filename, 'w')
            f.write(sample_script)
            f.close()

            return

        elif args.command == 'reset':
            reset_retriever(args.scope)
            return

        if args.command == 'ls' or args.dataset is None:

            # If scripts have never been downloaded there is nothing to list
            if not script_list:
                print("No scripts are currently available. Updating scripts now...")
                check_for_updates()
                print("\n\nScripts downloaded.\n")
                script_list = SCRIPT_LIST()

            all_scripts = []

            for script in script_list:
                if script.name:
                    if args.l!=None:
                        script_name = script.name + "\nShortname: " + script.shortname+"\n"
                        if script.tags:
                            script_name += "Tags: "+str([tag for tag in script.tags])+"\n"
                        not_found = 0
                        for term in args.l:
                            if script_name.lower().find(term.lower()) == -1:
                                not_found = 1
                                break
                        if not_found == 0:
                            all_scripts.append(script_name)
                    else:
                        script_name = script.shortname
                        all_scripts.append(script_name)

            all_scripts = sorted(all_scripts, key=lambda s: s.lower())

            print("Available datasets : {}\n".format(len(all_scripts)))

            if args.l==None:
                from retriever import lscolumns
                lscolumns.printls(sorted(all_scripts, key=lambda s: s.lower()))
            else:
                count = 1
                for script in all_scripts:
                    print ("%d. %s"%(count, script))
                    count += 1
            return

        engine = choose_engine(args.__dict__)

        if hasattr(args, 'debug') and args.debug:
            debug = True
        else:
            debug = False

        scripts = name_matches(script_list, args.dataset)
        if scripts:
            for dataset in scripts:
                print("=> Installing", dataset.name)
                try:
                    dataset.download(engine, debug=debug)
                    dataset.engine.final_cleanup()
                except KeyboardInterrupt:
                    pass
                except Exception as e:
                    print(e)
                    if debug: raise
            print("Done!")
        else:
            print("The dataset {} isn't currently available in the Retriever".format(args.dataset))
            print("Run 'retriever ls to see a list of currently available datasets")

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


<commit_before>import argparse
import json
import logging

from PIL import Image
from numpy import array

from src import MFM, Model, ModelInput, View, Face
from src.fitter import FittersChain
from data import get_datafile_path

def parse_command_line_arguments():
    LOGGER_LEVELS_COUNT = 6
    LOGGER_LEVELS_STEP = 10
    LOGGER_LEVELS = [logging.getLevelName(i*LOGGER_LEVELS_STEP)
                     for i in range(LOGGER_LEVELS_COUNT)]

    parser = argparse.ArgumentParser(
        description='Morphable Face Model fitting application')
    parser.add_argument(
        '--config', metavar='config', type=str, required=False,
        help='specify configuration file for fitting procedure')
    parser.add_argument('-l', '--log', help='set logger level', type=str.upper,
                        default='WARNING', choices=LOGGER_LEVELS)

    return parser.parse_args()

def setup_logging(level):
    logging.basicConfig(
        level=getattr(logging, level),
        format=' '.join(['[%(asctime)s]', '[%(levelname)8s]',
                         '[%(module)s:%(funcName)s]', '%(message)s']))

def construct_chain(configuration_filename, model):
    fitting_settings = None
    with open(configuration_filename) as config:
        fitting_settings = json.load(config)

    fitters = fitting_settings['fitters']

    face_parameters = fitting_settings['input'].get('initial_face', {})

    coefficients = face_parameters.get('coefficients', [])
    directed_light = face_parameters.get('directed_light', (0., 0., 0.))
    ambient_light = face_parameters.get('ambient_light', 0.)
    initial_face = Face(coefficients=coefficients,
                        directed_light=directed_light,
                        ambient_light=ambient_light)

    face_filename = get_datafile_path(fitting_settings['input']['input_image'])
    image = Image.open(face_filename).convert('L')
    original_data = array(image.getdata()).astype('f') / 255
    image_data = original_data.reshape(image.size)[::-1, :].flatten()
    image.close()

    return FittersChain(fitters, image_data, model, initial_face=initial_face)

def setup_application(configuration_filename=None):
    MFM.init()
    view = View((500, 500))
    model = Model(view)
    ModelInput(model)

    if configuration_filename is None:
        model.start()
    else:
        model.start(construct_chain(configuration_filename, model))

if __name__ == '__main__':
    arguments = parse_command_line_arguments()
    setup_logging(arguments.log)
    setup_application(arguments.config)
<commit_msg>Refactored __main__ module<commit_after>import argparse
import json
import logging

from PIL import Image
from numpy import array

from src import MFM, Model, ModelInput, View, Face
from src.fitter import FittersChain
from data import get_datafile_path

def parse_command_line_arguments():
    LOGGER_LEVELS_COUNT = 6
    LOGGER_LEVELS_STEP = 10
    LOGGER_LEVELS = [logging.getLevelName(i*LOGGER_LEVELS_STEP)
                     for i in range(LOGGER_LEVELS_COUNT)]

    parser = argparse.ArgumentParser(
        description='Morphable Face Model fitting application')
    parser.add_argument(
        '--config', metavar='config', type=str, required=False,
        help='specify configuration file for fitting procedure')
    parser.add_argument('-l', '--log', help='set logger level', type=str.upper,
                        default='WARNING', choices=LOGGER_LEVELS)

    return parser.parse_args()

def setup_logging(level):
    logging.basicConfig(
        level=getattr(logging, level),
        format=' '.join(['[%(asctime)s]', '[%(levelname)8s]',
                         '[%(module)s:%(funcName)s]', '%(message)s']))

def construct_chain(configuration_filename, model):
    fitting_settings = None
    with open(configuration_filename) as config:
        fitting_settings = json.load(config)

    fitters = fitting_settings['fitters']

    face_parameters = fitting_settings['input'].get('initial_face', {})

    coefficients = face_parameters.get('coefficients', [])
    directed_light = face_parameters.get('directed_light', (0., 0., 0.))
    ambient_light = face_parameters.get('ambient_light', 0.)
    initial_face = Face(coefficients=coefficients,
                        directed_light=directed_light,
                        ambient_light=ambient_light)

    face_filename = get_datafile_path(fitting_settings['input']['input_image'])
    image = Image.open(face_filename).convert('L')
    original_data = array(image.getdata()).astype('f') / 255
    image_data = original_data.reshape(image.size)[::-1, :].flatten()
    image.close()

    return FittersChain(fitters, image_data, model, initial_face=initial_face)

def setup_application(configuration_filename=None):
    MFM.init()
    view = View((500, 500))
    model = Model(view)
    ModelInput(model)

    if configuration_filename is None:
        model.start()
    else:
        model.start(construct_chain(configuration_filename, model))

if __name__ == '__main__':
    arguments = parse_command_line_arguments()
    setup_logging(arguments.log)
    setup_application(arguments.config)
<|endoftext|>