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

# CAUTION: Please use SI in the project.

from __future__ import absolute_import, division

import numpy as np
from scipy.optimize import brentq

import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot as plt

import isentropic_flow as ise_flow
import normal_shock_wave as nsw
from constants import EPSILON, R

class WindTunnelNotBuild(Exception):
    pass

class InvalidCall(Exception):
    pass

class Model(object):
    pass

class View(object):
    pass

class Controller(object):

    def __init__(self, model, view):
        self._model = model
        self._view = view

class WindTunnel(Model):

    def __init__(self,
                 design_mach,
                 test_section_area,
                 in_pressure,   # NOTE: This is not reservoir pressure.
                 in_temperature,    # NOTE: This is not reservoir temperature.
                 in_area,
                 con_len,
                 div_len,
                 z_len,
                 back_pressure):
        Model.__init__(self)

        # Properties specified by the designer of the wind tunnel
        self._design_mach = design_mach
        self._test_section_area = test_section_area
        self._in_pressure = in_pressure
        self._in_temperature = in_temperature
        self._in_area = in_area
        self._con_len = con_len
        self._div_len = div_len
        self._z_len = z_len
        self._back_pressure = back_pressure

        self._working_condition = None

    ##########################################################################
    # Properties decided by designer.

    @property
    def design_mach(self):
        return self._design_mach

    @property
    def md(self):
        return self._design_mach

    @property
    def test_section_area(self):
        return self._test_section_area

    @property
    def ats(self):
        return self._test_section_area

    @property
    def con_len(self):
        return self._con_len

    @property
    def div_len(self):
        return self._div_len

    @property
    def t_len(self):
        return self.con_len + self.div_len

    @property
    def z_len(self):
        return self._z_len

    @property
    def atsat(self):
        return ise_flow.m2a(self.md)

    @property
    def throat_area(self):
        return self.ats / self.atsat

    @property
    def at(self):
        return self.throat_area

    @property
    def in_area(self):
        return self._in_area

    @property
    def ain(self):
        return self._in_area

    @property
    def ainat(self):
        return self.ain / self.at

    @property
    def ymax(self):
        return max(self.x2y(0), self.x2y(self.t_len))

    @property
    def amax(self):
        return max(self.x2a(0), self.x2a(self.t_len))

    ##########################################################################
    # Properties can be adjusted after the wind tunnel is built.

    @property
    def back_pressure(self):
        return self._back_pressure

    @property
    def pb(self):
        return self._back_pressure

    @property
    def inlet_pressure(self):
        return self._in_pressure

    @property
    def pin(self):
        return self._in_pressure

    ##########################################################################
    # Methods to change working condition.

    def change_back_pressure(self, p):
        self._back_pressure = p
        self._working_condition = self.get_working_condition()

    def change_inlet_pressure(self, p):
        self._in_pressure = p
        self._working_condition = self.get_working_condition()

    def change_inlet_temperature(self, t):
        self._in_temperature = t
        self._working_condition = self.get_working_condition()

    ##########################################################################
    # Methods to calculate flow properties at given x.

    def x2a(self, x):
        if x <= self.con_len:
            area = (self.ain*self.con_len-self.ain*x+self.at*x) / self.con_len
        elif self.con_len < x <= self.con_len + self.div_len:
            area = (self.ats-self.at)*(x-self.con_len)/self.div_len + self.at
        return area

    def x2y(self, x):
        return self.x2a(x) / self.z_len / 2

    @property
    def mts_34(self):
        return ise_flow.ap2m(self.ap_34)

    @property
    def p02_34(self):
        return self.pb / ise_flow.m2p(self.mts_34)

    @property
    def p02pin(self):
        return self.p02_34 / self.pin

    @property
    def a2star_34(self):
        return (self.ap_34/(self.pb/self.p02_34)/self.ats) ** -1

    @property
    def m1_34(self):
        return nsw.p02m(self.p02pin)

    @property
    def ap_34(self):
        return self.atsat * self.pb / self.pin

    @property
    def xns_34(self):
        area = ise_flow.m2a(self.m1_34) * self.at
        return self.a2x(area, 0)

    def x2m(self, x):
        if self.wc in (1, 2):
            aastar = self.x2a(x) / self.get_astar_if_subsonic()
            m = ise_flow.a2m(aastar, supersonic=0)

        elif self.wc in (3, 4):
            if 0 <= x <= self.con_len:
                m = ise_flow.a2m(self.x2a(x)/self.at, supersonic=0)
            elif self.con_len <= x <= self.xns_34:
                m = ise_flow.a2m(self.x2a(x)/self.at, supersonic=1)
            elif self.xns_34 < x <= self.t_len:
                m = ise_flow.a2m(self.x2a(x)/self.a2star_34, supersonic=0)

        elif self.wc in (5, 6, 7):
            if 0 <= x <= self.con_len:
                m = ise_flow.a2m(self.x2a(x)/self.at, 0)
            elif self.con_len <= x <= self.t_len:
                m = ise_flow.a2m(self.x2a(x)/self.at, 1)
        return m

    def x2p(self, x):
        if self.wc in (1, 2, 5, 6, 7):
            p = ise_flow.m2p(self.x2m(x))
        elif self.wc in (3, 4):
            if 0 <= x <= self.xns_34:
                p = ise_flow.m2p(self.x2m(x))
            elif self.xns_34 < x <= self.t_len:
                p = ise_flow.m2p(self.x2m(x)) * self.p02_34 / self.pin
        return p

    def x2rho(self, x):
        return self.x2p(x) / self.x2t(x)

    def x2t(self, x):
        return ise_flow.m2t(self.x2m(x))

    def a2x(self, a, front=1):
        if front:
            return brentq(lambda x: self.x2a(x)-a, 0, self.con_len)
        else:
            return brentq(lambda x: self.x2a(x)-a, self.con_len, self.t_len)

    def get_wall_shape(self):
        yin = self.x2y(0)
        yt = self.x2y(self.con_len)
        yts = self.x2y(self.t_len)
        return np.array([
            [0, yin],
            [self.con_len, yt],
            [self.t_len, yts],
            [self.t_len, -yts],
            [self.con_len, -yt],
            [0, -yin],
        ])

    @property
    def wc(self):
        if self._working_condition is None:
            self._working_condition = self.get_working_condition()
        return self._working_condition

    def get_working_condition(self):
        # Mach number for the limiting case.
        ml = ise_flow.a2m(self.atsat, 0)
        # Mach number for the design case.
        md = self.md

        pl = ise_flow.m2p(ml)
        pd = ise_flow.m2p(md)
        pns = ise_flow.m2p(md) * nsw.m2p(md)

        ratio = self.pb / self.pin
        if ratio > pl:
            wc = 1
        elif abs(ratio-pl) < EPSILON:
            wc = 2
        elif pns < ratio < pl:
            wc = 3
        elif abs(ratio-pns) < EPSILON:
            wc = 4
        elif pd < ratio < pns:
            wc = 5
        elif abs(ratio-pd) < EPSILON:
            wc = 6
        elif ratio < pd:
            wc = 7
        return wc

    def get_in_mach(self):
        case = self.get_working_condition()
        if case == 1 or case == 2:
            astar = self.get_astar_if_subsonic()
            in_mach = ise_flow.a2m(self.ain/astar, supersonic=0)
        elif case == 3:
            in_mach = ise_flow.a2m(self.ainat, supersonic=1)
        return in_mach

    def get_astar_if_subsonic(self):
        case = self.get_working_condition()
        if not case == 1 or case == 2:
            raise InvalidCall

        return self.ats / ise_flow.m2a(ise_flow.p2m(self.pb/self.pin))

class Report(object):

    def __init__(self):
        pass

    def get_shape(self):
        points = self.wt.get_wall_shape()
        steps = len(points)
        points = np.vstack([points, points[0]])
        fig = plt.figure()

        for i in xrange(steps):
            sub = fig.add_subplot(111)
            x = [points[i, 0], points[i+1, 0]]
            y = [points[i, 1], points[i+1, 1]]
            sub.plot(x, y, 'b')

        t_len = self.wt.t_len
        max_y = self.wt.ymax

        h_margin = t_len * 0.1 / 2
        v_margin = max_y * 0.1
        plt.axis([-h_margin, t_len+h_margin,
                  -max_y-v_margin, max_y+v_margin])
        return fig

    def get_fig(self, type_, steps=1000):
        xs = np.linspace(0, self.wt.t_len, steps)
        ys = np.zeros(steps)
        for i in xrange(steps):
            if type_ == 'a':
                ys[i] = self.wt.x2a(xs[i])
            elif type_ == 'm':
                ys[i] = self.wt.x2m(xs[i])
            elif type_ == 'p':
                ys[i] = self.wt.x2p(xs[i])
            elif type_ == 'rho':
                ys[i] = self.wt.x2rho(xs[i])
            elif type_ == 't':
                ys[i] = self.wt.x2t(xs[i])

        fig = plt.figure()
        sub = fig.add_subplot(111)
        sub.plot(xs, ys, 'b')
        return fig

    @property
    def all_plot_type(self):
        return ['a', 'm', 'p', 'rho', 't']

class WindTunnelReportCreator(Controller):

    def __init__(self, wind_tunnel, report):
        self._wind_tunnel = wind_tunnel
        self._report = report

    def save_plot(self, filename, plot_type):
        if plot_type == 's':
            fig = self.get_shape()
        elif plot_type in ('a', 'm', 'p', 'rho', 't'):
            fig = self.get_fig(plot_type)
        fig.savefig(filename)

    def generate(self):
        for t in self.all_plot_type:
            self.save_plot('%s.png' % t, t)

if __name__ == '__main__':
    t = WindTunnel(2.4, 1, 10e6, 300, 10, 5, 20, 1, 0.5*10E6)
    r = Report()
    r.build(t)
    r.generate()<commit_msg>Finish Task I Step 1<commit_after>#!/usr/bin/env python

# CAUTION: Please use SI in the project.

from __future__ import absolute_import, division

import numpy as np
from scipy.optimize import brentq

import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot as plt

import isentropic_flow as ise_flow
import normal_shock_wave as nsw
from constants import EPSILON, R

class WindTunnelNotBuild(Exception):
    pass

class InvalidCall(Exception):
    pass

class Model(object):
    pass

class View(object):
    pass

class Controller(object):

    def __init__(self, model, view):
        self._model = model
        self._view = view

class WindTunnel(Model):

    def __init__(self,
                 design_mach,
                 test_section_area,
                 in_pressure,   # NOTE: This is not reservoir pressure.
                 in_temperature,    # NOTE: This is not reservoir temperature.
                 in_area,
                 con_len,
                 div_len,
                 z_len,
                 back_pressure):
        Model.__init__(self)

        # Properties specified by the designer of the wind tunnel
        self._design_mach = design_mach
        self._test_section_area = test_section_area
        self._in_pressure = in_pressure
        self._in_temperature = in_temperature
        self._in_area = in_area
        self._con_len = con_len
        self._div_len = div_len
        self._z_len = z_len
        self._back_pressure = back_pressure

        self._working_condition = None

    ##########################################################################
    # Properties decided by designer.

    @property
    def design_mach(self):
        return self._design_mach

    @property
    def md(self):
        return self._design_mach

    @property
    def test_section_area(self):
        return self._test_section_area

    @property
    def ats(self):
        return self._test_section_area

    @property
    def con_len(self):
        return self._con_len

    @property
    def div_len(self):
        return self._div_len

    @property
    def t_len(self):
        return self.con_len + self.div_len

    @property
    def z_len(self):
        return self._z_len

    @property
    def atsat(self):
        return ise_flow.m2a(self.md)

    @property
    def throat_area(self):
        return self.ats / self.atsat

    @property
    def at(self):
        return self.throat_area

    @property
    def in_area(self):
        return self._in_area

    @property
    def ain(self):
        return self._in_area

    @property
    def ainat(self):
        return self.ain / self.at

    @property
    def ymax(self):
        return max(self.x2y(0), self.x2y(self.t_len))

    @property
    def amax(self):
        return max(self.x2a(0), self.x2a(self.t_len))

    ##########################################################################
    # Properties can be adjusted after the wind tunnel is built.

    @property
    def back_pressure(self):
        return self._back_pressure

    @property
    def pb(self):
        return self._back_pressure

    @property
    def inlet_pressure(self):
        return self._in_pressure

    @property
    def pin(self):
        return self._in_pressure

    ##########################################################################
    # Methods to change working condition.

    def change_back_pressure(self, p):
        self._back_pressure = p
        self._working_condition = self.get_working_condition()

    def change_inlet_pressure(self, p):
        self._in_pressure = p
        self._working_condition = self.get_working_condition()

    def change_inlet_temperature(self, t):
        self._in_temperature = t
        self._working_condition = self.get_working_condition()

    ##########################################################################
    # Methods to calculate flow properties at given x.

    def x2a(self, x):
        if x <= self.con_len:
            area = (self.ain*self.con_len-self.ain*x+self.at*x) / self.con_len
        elif self.con_len < x <= self.con_len + self.div_len:
            area = (self.ats-self.at)*(x-self.con_len)/self.div_len + self.at
        return area

    def x2y(self, x):
        return self.x2a(x) / self.z_len / 2

    @property
    def mts_34(self):
        return ise_flow.ap2m(self.ap_34)

    @property
    def p02_34(self):
        return self.pb / ise_flow.m2p(self.mts_34)

    @property
    def p02pin(self):
        return self.p02_34 / self.pin

    @property
    def a2star_34(self):
        return (self.ap_34/(self.pb/self.p02_34)/self.ats) ** -1

    @property
    def m1_34(self):
        return nsw.p02m(self.p02pin)

    @property
    def ap_34(self):
        return self.atsat * self.pb / self.pin

    @property
    def xns_34(self):
        area = ise_flow.m2a(self.m1_34) * self.at
        return self.a2x(area, 0)

    def x2m(self, x):
        if self.wc in (1, 2):
            aastar = self.x2a(x) / self.get_astar_if_subsonic()
            m = ise_flow.a2m(aastar, supersonic=0)

        elif self.wc in (3, 4):
            if 0 <= x <= self.con_len:
                m = ise_flow.a2m(self.x2a(x)/self.at, supersonic=0)
            elif self.con_len <= x <= self.xns_34:
                m = ise_flow.a2m(self.x2a(x)/self.at, supersonic=1)
            elif self.xns_34 < x <= self.t_len:
                m = ise_flow.a2m(self.x2a(x)/self.a2star_34, supersonic=0)

        elif self.wc in (5, 6, 7):
            if 0 <= x <= self.con_len:
                m = ise_flow.a2m(self.x2a(x)/self.at, 0)
            elif self.con_len <= x <= self.t_len:
                m = ise_flow.a2m(self.x2a(x)/self.at, 1)
        return m

    def x2p(self, x):
        if self.wc in (1, 2, 5, 6, 7):
            p = ise_flow.m2p(self.x2m(x))
        elif self.wc in (3, 4):
            if 0 <= x <= self.xns_34:
                p = ise_flow.m2p(self.x2m(x))
            elif self.xns_34 < x <= self.t_len:
                p = ise_flow.m2p(self.x2m(x)) * self.p02_34 / self.pin
        return p

    def x2rho(self, x):
        return self.x2p(x) / self.x2t(x)

    def x2t(self, x):
        return ise_flow.m2t(self.x2m(x))

    def a2x(self, a, front=1):
        if front:
            return brentq(lambda x: self.x2a(x)-a, 0, self.con_len)
        else:
            return brentq(lambda x: self.x2a(x)-a, self.con_len, self.t_len)

    def get_wall_shape(self):
        yin = self.x2y(0)
        yt = self.x2y(self.con_len)
        yts = self.x2y(self.t_len)
        return np.array([
            [0, yin],
            [self.con_len, yt],
            [self.t_len, yts],
            [self.t_len, -yts],
            [self.con_len, -yt],
            [0, -yin],
        ])

    @property
    def wc(self):
        if self._working_condition is None:
            self._working_condition = self.get_working_condition()
        return self._working_condition

    def get_working_condition(self):
        # Mach number for the limiting case.
        ml = ise_flow.a2m(self.atsat, 0)
        # Mach number for the design case.
        md = self.md

        pl = ise_flow.m2p(ml)
        pd = ise_flow.m2p(md)
        pns = ise_flow.m2p(md) * nsw.m2p(md)

        ratio = self.pb / self.pin
        if ratio > pl:
            wc = 1
        elif abs(ratio-pl) < EPSILON:
            wc = 2
        elif pns < ratio < pl:
            wc = 3
        elif abs(ratio-pns) < EPSILON:
            wc = 4
        elif pd < ratio < pns:
            wc = 5
        elif abs(ratio-pd) < EPSILON:
            wc = 6
        elif ratio < pd:
            wc = 7
        return wc

    def get_in_mach(self):
        case = self.get_working_condition()
        if case == 1 or case == 2:
            astar = self.get_astar_if_subsonic()
            in_mach = ise_flow.a2m(self.ain/astar, supersonic=0)
        elif case == 3:
            in_mach = ise_flow.a2m(self.ainat, supersonic=1)
        return in_mach

    def get_astar_if_subsonic(self):
        case = self.get_working_condition()
        if not case == 1 or case == 2:
            raise InvalidCall

        return self.ats / ise_flow.m2a(ise_flow.p2m(self.pb/self.pin))

class Report(object):

    def __init__(self):
        pass

    def shape(self, points):
        steps = len(points)
        points = np.vstack([points, points[0]])
        fig = plt.figure()

        for i in xrange(steps):
            sub = fig.add_subplot(111)
            x = [points[i, 0], points[i+1, 0]]
            y = [points[i, 1], points[i+1, 1]]
            sub.plot(x, y, 'b')

        #t_len = self.wt.t_len
        #max_y = self.wt.ymax

        #h_margin = t_len * 0.1 / 2
        #v_margin = max_y * 0.1
        #plt.axis([-h_margin, t_len+h_margin,
        #          -max_y-v_margin, max_y+v_margin])
        return fig

    def graph(self, x, profile):
        graph = plt.figure()
        sub = graph.add_subplot(111)
        sub.plot(x, profile, 'b')
        return graph

class WindTunnelReportCreator(Controller):

    def __init__(self, model, view):
        Controller.__init__(self, model, view)

    @property
    def plot_types(self):
        return ['s', 'a', 'm', 'p', 'rho', 't']

    def save_plot(self, filename, plot_type, steps=1000):
        if plot_type == 's':
            points = self._model.get_wall_shape()
            fig = self._view.shape(points)
            fig.savefig(filename)
        else:
            xs = np.linspace(0, self._model.t_len, steps)
            profile = np.zeros(steps)

            if plot_type == 'a':
                for i in xrange(steps):
                    profile[i] = self._model.x2a(xs[i])
            elif plot_type == 'm':
                for i in xrange(steps):
                    profile[i] = self._model.x2m(xs[i])
            elif plot_type == 'p':
                for i in xrange(steps):
                    profile[i] = self._model.x2p(xs[i])
            elif plot_type == 'rho':
                for i in xrange(steps):
                    profile[i] = self._model.x2rho(xs[i])
            elif plot_type == 't':
                for i in xrange(steps):
                    profile[i] = self._model.x2t(xs[i])

            graph = self._view.graph(xs, profile)
            graph.savefig(filename)

    def generate(self):
        for t in self.plot_types:
            self.save_plot('%s.png' % t, t)

if __name__ == '__main__':
    t = WindTunnel(2.4, 1, 10e6, 300, 10, 5, 20, 1, 0.5*10E6)
    r = Report()
    c = WindTunnelReportCreator(t, r)
    c.generate()<|endoftext|>


<commit_before>import errno
import glob
import os
from rhcephcompose import Build, Comps, Variants
from rhcephcompose.log import log
from shutil import copy
import subprocess
import textwrap
import time

COMPOSE_TYPE_MAP = {
    'production': '',
    'nightly': '.n',
    'test': '.t',
    'ci': '.ci',
}

class Compose(object):
    """
    A "compose" is a particular "spin" or "release" . It is a collection
    of repositories.
    """

    def __init__(self, conf):
        """ This constructor simply stores all our settings; it takes no
        actions. See run() for that. """
        # Build lists are normally in the Errata Tool or a Brew tag. There's
        # no support for Ubuntu builds in Brew or the Errata Tool today, so I
        # just list each build in text files. The "builds" dict here contains
        # a text file for each distro.
        self.builds = conf['builds']
        # In Pungi terminology, assume gather_source "comps" (see also
        # Pungi's "comps_file".)
        self.comps = conf['comps']
        # Variants file copied directly from what we use with Distill on
        # RHEL.
        self.variants_file = conf['variants_file']
        # In Pungi terminology, assume pkgset_source "chacra" (instead
        # of "koji").
        self.chacra_url = conf['chacra_url']
        self.chacra_ssl_verify = conf.get('chacra_ssl_verify', True)
        # Lookaside cache location.
        # See freedesktop.org spec for XDG_CACHE_HOME
        try:
            xdg_cache_home = os.environ['XDG_CACHE_HOME']
        except KeyError:
            xdg_cache_home = os.path.expanduser('~/.cache')
        self.cache_path = os.path.join(xdg_cache_home, 'rhcephcompose')
        # Output target directory
        self.target = conf['target']
        # Product version, eg "1.3"
        self.product_version = conf['product_version']
        # Extra files to put at the root of the compose
        self.extra_files = conf['extra_files']
        # Whether sources composition should be skipped
        self.include_sources = conf.get('include_sources', True)
        # Compose type for output directory name
        self.compose_type = conf.get('compose_type', 'test')

    @property
    def output_dir(self):
        """
        Use the same logic that pungi/compose.py uses in order come up with
        the name for the output directory. The name should be something
        like "Ceph-1.3-Ubuntu-20160922.t.0-x86_64" to match what
        distill/pungi creates.
        """
        if getattr(self, '_output_directory', None):
            return self._output_directory
        compose_date = time.strftime('%Y%m%d')
        compose_name = 'Ceph-{product_version}-{oslabel}-{arch}-{compose_date}{compose_type}.{compose_respin}'  # NOQA
        compose_type = COMPOSE_TYPE_MAP[self.compose_type]
        compose_respin = 0
        while 1:
            output_dir = os.path.join(self.target, compose_name.format(
                product_version=self.product_version,
                oslabel='Ubuntu',
                compose_date=compose_date,
                arch='x86_64',
                compose_type=compose_type,
                compose_respin=compose_respin
            ))
            if os.path.isdir(output_dir):
                log.info('Found prior compose dir: %s' % output_dir)
                compose_respin += 1
                continue
            log.info('Using new compose dir: %s' % output_dir)
            self._output_directory = output_dir
            return output_dir

    def run(self):
        """ High-level function to execute a compose. """
        if not os.path.isdir(self.cache_path):
            os.makedirs(self.cache_path)

        if not os.path.isdir(self.target):
            os.makedirs(self.target)

        # Make top-level output directory for this compose.
        os.mkdir(self.output_dir)

        # Top-level "sources" directory, parallel to our output_dir.
        if self.include_sources:
            sources_dir = self.output_dir + '-sources'
            os.mkdir(sources_dir)

        # Run the steps for each distro.
        for distro in self.builds.keys():
            # (We assume that all keys in self.builds also exist in
            # self.comps.)
            if distro not in self.comps.keys():
                msg = ('Loading builds for "{0}", and the comps '
                       'configuration is missing a "{0}" key. Please add a '
                       'comps XML file for this distro.').format(distro)
                raise SystemExit(msg)
            self.run_distro(distro)

        # Copy any extra files to the root of the compose.
        for extra_file in self.extra_files:
            # For "glob" type extra files, glob the compose's output_dir, and
            # copy the results to the root.
            if 'glob' in extra_file:
                glob_path = os.path.join(self.output_dir, extra_file['glob'])
                for f in glob.glob(glob_path):
                    copy(f, self.output_dir)
            # For "file" type extra files, copy the file from the user's cwd.
            if 'file' in extra_file:
                copy(os.path.join('extra_files', extra_file['file']),
                     self.output_dir)

        # create "latest" symlink
        self.symlink_latest()

    def symlink_latest(self):
        """ Create the "latest" symlink for this output_dir. """
        latest_tmpl = 'Ceph-{product_version}-{oslabel}-{arch}-latest'
        latest_path = os.path.join(self.target, latest_tmpl.format(
            product_version=self.product_version,
            oslabel='Ubuntu',
            arch='x86_64',
        ))
        try:
            os.unlink(latest_path)
        except OSError as e:
            if e.errno != errno.ENOENT:
                log.error('Problem deleting "latest" symlink')
                raise SystemExit(e)
        os.symlink(os.path.relpath(self.output_dir, start=self.target),
                   latest_path)

    def run_distro(self, distro):
        """ Execute a compose for a distro. """

        # Read the "builds_path" text file for this distro. Create a list of
        # each line of this file.
        builds_path = self.builds[distro]
        builds = [line.rstrip('\n') for line in open(builds_path)]

        log.info('Found %d build ids in "%s"' % (len(builds), builds_path))

        # Read pkg mappings from Distill-style comps XML.
        # (Assembles a master list of package names that we will need.)
        comps_file = self.comps[distro]
        comps = Comps()
        comps.parse_file(comps_file)

        # Copy the builds' files to the correct directories, according to
        # comps.xml + variants.xml.

        for build_id in builds:
            build = Build(build_id, ssl_verify=self.chacra_ssl_verify)
            # Find all the (whitelisted) binaries for this build.
            build.find_artifacts_from_chacra(chacra=self.chacra_url,
                                             whitelist=comps.all_packages)
            # Assign each binary to its respective comps group(s).
            for binary in build.binaries:
                comps.assign_binary_to_groups(binary)
            # Download all the source artifacts for this build and put them in
            # the "sources" directory.
            if self.include_sources:
                # Top-level "sources" directory, parallel to our output_dir.
                sources_dir = self.output_dir + '-sources'
                for source in build.sources:
                    source.download(cache_dir=self.cache_path,
                                    dest_dir=sources_dir)

        variants = Variants()
        variants.parse_file(self.variants_file)

        for variant_id, variant_groups in variants.items():
            # Top-level directory for this repository:
            variant_dir = os.path.join(self.output_dir, variant_id)
            if not os.path.isdir(variant_dir):
                os.mkdir(variant_dir)

            # Set up the reprepro configuration:
            log.info('Creating reprepro configuration for %s' % variant_id)
            conf_dir = os.path.join(variant_dir, 'conf')
            if not os.path.isdir(conf_dir):
                os.mkdir(conf_dir)
            distributions_path = os.path.join(conf_dir, 'distributions')
            dist_template = textwrap.dedent('''\
                Codename: {codename}
                Suite: stable
                Components: main
                Architectures: amd64 i386
                Origin: Red Hat, Inc.
                Description: Ceph distributed file system
                DebIndices: Packages Release . .gz .bz2
                DscIndices: Sources Release .gz .bz2
                Contents: .gz .bz2

            ''')
            with open(distributions_path, 'a') as dist_conf_file:
                dist_conf_file.write(dist_template.format(codename=distro))

            # Loop through all the comps groups in this variant. (in Ceph we
            # only have one group per variant, so far!)
            for group_id in variant_groups:
                # Loop through all the binaries in this comps group
                binaries = comps.groups[group_id].binaries
                msg = 'Comps group ID "%s" contains %d binaries %s'
                msg_binaries = list(map(lambda x: x.filename, binaries))
                log.info(msg % (group_id, len(binaries), msg_binaries))
                for binary in binaries:
                    # Add this binary to our variant's repo/directory:
                    self.add_binary_to_repo(binary=binary,
                                            repo_path=variant_dir,
                                            distro=distro)

    def add_binary_to_repo(self, binary, repo_path, distro):
        """ Add a binary (.deb) to a Debian repository. """
        binary.download(cache_dir=self.cache_path)
        msg = 'Running reprepro to add %s to %s distro in %s'
        log.info(msg % (binary.name, distro, repo_path))
        binary_path = os.path.join(self.cache_path, binary.filename)
        command = [
            'reprepro',
            '--ask-passphrase',
            '-b', repo_path,
            '-C', 'main',
            '--ignore=wrongdistribution',
            '--ignore=wrongversion',
            '--ignore=undefinedtarget',
            'includedeb', distro, binary_path
        ]
        log.info('running command: %s' % ' '.join(command))
        proc = subprocess.Popen(
            command,
            stdout=subprocess.PIPE
        )
        out, err = proc.communicate()
        exit_code = proc.wait()
        if err:
            for i in err:
                log.error(i)
        if exit_code != 0:
            msg = 'command failed with status code: %s'
            raise RuntimeError(msg % exit_code)
<commit_msg>compose: better description for include_sources<commit_after>import errno
import glob
import os
from rhcephcompose import Build, Comps, Variants
from rhcephcompose.log import log
from shutil import copy
import subprocess
import textwrap
import time

COMPOSE_TYPE_MAP = {
    'production': '',
    'nightly': '.n',
    'test': '.t',
    'ci': '.ci',
}

class Compose(object):
    """
    A "compose" is a particular "spin" or "release" . It is a collection
    of repositories.
    """

    def __init__(self, conf):
        """ This constructor simply stores all our settings; it takes no
        actions. See run() for that. """
        # Build lists are normally in the Errata Tool or a Brew tag. There's
        # no support for Ubuntu builds in Brew or the Errata Tool today, so I
        # just list each build in text files. The "builds" dict here contains
        # a text file for each distro.
        self.builds = conf['builds']
        # In Pungi terminology, assume gather_source "comps" (see also
        # Pungi's "comps_file".)
        self.comps = conf['comps']
        # Variants file copied directly from what we use with Distill on
        # RHEL.
        self.variants_file = conf['variants_file']
        # In Pungi terminology, assume pkgset_source "chacra" (instead
        # of "koji").
        self.chacra_url = conf['chacra_url']
        self.chacra_ssl_verify = conf.get('chacra_ssl_verify', True)
        # Lookaside cache location.
        # See freedesktop.org spec for XDG_CACHE_HOME
        try:
            xdg_cache_home = os.environ['XDG_CACHE_HOME']
        except KeyError:
            xdg_cache_home = os.path.expanduser('~/.cache')
        self.cache_path = os.path.join(xdg_cache_home, 'rhcephcompose')
        # Output target directory
        self.target = conf['target']
        # Product version, eg "1.3"
        self.product_version = conf['product_version']
        # Extra files to put at the root of the compose
        self.extra_files = conf['extra_files']
        # Whether sources composition should be included or skipped
        self.include_sources = conf.get('include_sources', True)
        # Compose type for output directory name
        self.compose_type = conf.get('compose_type', 'test')

    @property
    def output_dir(self):
        """
        Use the same logic that pungi/compose.py uses in order come up with
        the name for the output directory. The name should be something
        like "Ceph-1.3-Ubuntu-20160922.t.0-x86_64" to match what
        distill/pungi creates.
        """
        if getattr(self, '_output_directory', None):
            return self._output_directory
        compose_date = time.strftime('%Y%m%d')
        compose_name = 'Ceph-{product_version}-{oslabel}-{arch}-{compose_date}{compose_type}.{compose_respin}'  # NOQA
        compose_type = COMPOSE_TYPE_MAP[self.compose_type]
        compose_respin = 0
        while 1:
            output_dir = os.path.join(self.target, compose_name.format(
                product_version=self.product_version,
                oslabel='Ubuntu',
                compose_date=compose_date,
                arch='x86_64',
                compose_type=compose_type,
                compose_respin=compose_respin
            ))
            if os.path.isdir(output_dir):
                log.info('Found prior compose dir: %s' % output_dir)
                compose_respin += 1
                continue
            log.info('Using new compose dir: %s' % output_dir)
            self._output_directory = output_dir
            return output_dir

    def run(self):
        """ High-level function to execute a compose. """
        if not os.path.isdir(self.cache_path):
            os.makedirs(self.cache_path)

        if not os.path.isdir(self.target):
            os.makedirs(self.target)

        # Make top-level output directory for this compose.
        os.mkdir(self.output_dir)

        # Top-level "sources" directory, parallel to our output_dir.
        if self.include_sources:
            sources_dir = self.output_dir + '-sources'
            os.mkdir(sources_dir)

        # Run the steps for each distro.
        for distro in self.builds.keys():
            # (We assume that all keys in self.builds also exist in
            # self.comps.)
            if distro not in self.comps.keys():
                msg = ('Loading builds for "{0}", and the comps '
                       'configuration is missing a "{0}" key. Please add a '
                       'comps XML file for this distro.').format(distro)
                raise SystemExit(msg)
            self.run_distro(distro)

        # Copy any extra files to the root of the compose.
        for extra_file in self.extra_files:
            # For "glob" type extra files, glob the compose's output_dir, and
            # copy the results to the root.
            if 'glob' in extra_file:
                glob_path = os.path.join(self.output_dir, extra_file['glob'])
                for f in glob.glob(glob_path):
                    copy(f, self.output_dir)
            # For "file" type extra files, copy the file from the user's cwd.
            if 'file' in extra_file:
                copy(os.path.join('extra_files', extra_file['file']),
                     self.output_dir)

        # create "latest" symlink
        self.symlink_latest()

    def symlink_latest(self):
        """ Create the "latest" symlink for this output_dir. """
        latest_tmpl = 'Ceph-{product_version}-{oslabel}-{arch}-latest'
        latest_path = os.path.join(self.target, latest_tmpl.format(
            product_version=self.product_version,
            oslabel='Ubuntu',
            arch='x86_64',
        ))
        try:
            os.unlink(latest_path)
        except OSError as e:
            if e.errno != errno.ENOENT:
                log.error('Problem deleting "latest" symlink')
                raise SystemExit(e)
        os.symlink(os.path.relpath(self.output_dir, start=self.target),
                   latest_path)

    def run_distro(self, distro):
        """ Execute a compose for a distro. """

        # Read the "builds_path" text file for this distro. Create a list of
        # each line of this file.
        builds_path = self.builds[distro]
        builds = [line.rstrip('\n') for line in open(builds_path)]

        log.info('Found %d build ids in "%s"' % (len(builds), builds_path))

        # Read pkg mappings from Distill-style comps XML.
        # (Assembles a master list of package names that we will need.)
        comps_file = self.comps[distro]
        comps = Comps()
        comps.parse_file(comps_file)

        # Copy the builds' files to the correct directories, according to
        # comps.xml + variants.xml.

        for build_id in builds:
            build = Build(build_id, ssl_verify=self.chacra_ssl_verify)
            # Find all the (whitelisted) binaries for this build.
            build.find_artifacts_from_chacra(chacra=self.chacra_url,
                                             whitelist=comps.all_packages)
            # Assign each binary to its respective comps group(s).
            for binary in build.binaries:
                comps.assign_binary_to_groups(binary)
            # Download all the source artifacts for this build and put them in
            # the "sources" directory.
            if self.include_sources:
                # Top-level "sources" directory, parallel to our output_dir.
                sources_dir = self.output_dir + '-sources'
                for source in build.sources:
                    source.download(cache_dir=self.cache_path,
                                    dest_dir=sources_dir)

        variants = Variants()
        variants.parse_file(self.variants_file)

        for variant_id, variant_groups in variants.items():
            # Top-level directory for this repository:
            variant_dir = os.path.join(self.output_dir, variant_id)
            if not os.path.isdir(variant_dir):
                os.mkdir(variant_dir)

            # Set up the reprepro configuration:
            log.info('Creating reprepro configuration for %s' % variant_id)
            conf_dir = os.path.join(variant_dir, 'conf')
            if not os.path.isdir(conf_dir):
                os.mkdir(conf_dir)
            distributions_path = os.path.join(conf_dir, 'distributions')
            dist_template = textwrap.dedent('''\
                Codename: {codename}
                Suite: stable
                Components: main
                Architectures: amd64 i386
                Origin: Red Hat, Inc.
                Description: Ceph distributed file system
                DebIndices: Packages Release . .gz .bz2
                DscIndices: Sources Release .gz .bz2
                Contents: .gz .bz2

            ''')
            with open(distributions_path, 'a') as dist_conf_file:
                dist_conf_file.write(dist_template.format(codename=distro))

            # Loop through all the comps groups in this variant. (in Ceph we
            # only have one group per variant, so far!)
            for group_id in variant_groups:
                # Loop through all the binaries in this comps group
                binaries = comps.groups[group_id].binaries
                msg = 'Comps group ID "%s" contains %d binaries %s'
                msg_binaries = list(map(lambda x: x.filename, binaries))
                log.info(msg % (group_id, len(binaries), msg_binaries))
                for binary in binaries:
                    # Add this binary to our variant's repo/directory:
                    self.add_binary_to_repo(binary=binary,
                                            repo_path=variant_dir,
                                            distro=distro)

    def add_binary_to_repo(self, binary, repo_path, distro):
        """ Add a binary (.deb) to a Debian repository. """
        binary.download(cache_dir=self.cache_path)
        msg = 'Running reprepro to add %s to %s distro in %s'
        log.info(msg % (binary.name, distro, repo_path))
        binary_path = os.path.join(self.cache_path, binary.filename)
        command = [
            'reprepro',
            '--ask-passphrase',
            '-b', repo_path,
            '-C', 'main',
            '--ignore=wrongdistribution',
            '--ignore=wrongversion',
            '--ignore=undefinedtarget',
            'includedeb', distro, binary_path
        ]
        log.info('running command: %s' % ' '.join(command))
        proc = subprocess.Popen(
            command,
            stdout=subprocess.PIPE
        )
        out, err = proc.communicate()
        exit_code = proc.wait()
        if err:
            for i in err:
                log.error(i)
        if exit_code != 0:
            msg = 'command failed with status code: %s'
            raise RuntimeError(msg % exit_code)
<|endoftext|>


<commit_before>
class Decisions:
    def __init__(self, decision_policy, stimulus_memory_n_timesteps):
        # we take plume as input for the gradient ascent. however, this is inelegant. FIXME
        self.decision_policy = decision_policy

        self.stimulus_memory_n_timesteps = stimulus_memory_n_timesteps
        self.plume_sighted_ago = 10000000  # a long time ago
        self.last_plume_side_exited = None

    def make_decision(self, in_plume, crosswind_velocity):
        if 'cast' in self.decision_policy:
            decision = self._boolean_decisions(in_plume, crosswind_velocity)
        elif 'surge' in self.decision_policy:
            decision = self._boolean_decisions(in_plume, crosswind_velocity)
        elif 'gradient' in self.decision_policy:
            decision = self._gradient_decisions()
        elif 'ignore' in self.decision_policy:
            decision = 'ignore'
        else:
            raise ValueError('unk decision policy {}'.format(self.decision_policy))

        return decision

    def _boolean_decisions(self, in_plume, crosswind_velocity):
        if in_plume == True:  # use == instead of "is" because we're using type np.bool
            self.plume_sighted_ago = 0
            plume_signal = 'in'
            if 'surge' in self.decision_policy:
                current_decision = 'surge'
            else:
                current_decision = 'search'
        elif in_plume == False:
            self.plume_sighted_ago += 1
            if self.plume_sighted_ago == 1:  # we just exited the plume
                # if our y velocity is negative, we just exited to the left. otherwise, to the right.
                if crosswind_velocity < 0:
                    plume_signal = 'exit_l'
                    self.last_plume_side_exited = 'l'
                    current_decision = 'cast_r'
                else:
                    plume_signal = 'exit_r'
                    self.last_plume_side_exited = 'r'
                    current_decision = 'cast_l'
            else:  # been outside plume at least a couple timesteps
                plume_signal = 'out'
                if 'cast' in self.decision_policy:
                    if self.plume_sighted_ago <= self.stimulus_memory_n_timesteps:  # we were in the plume recently
                        if self.last_plume_side_exited == 'l':
                            current_decision = 'cast_r'
                        else:  # 'r'
                            current_decision = 'cast_l'
                    else:  # haven't seen the plume in a while
                        current_decision = 'search'
                else:
                    current_decision = 'search'

        return current_decision, plume_signal

    def _gradient_decisions(self):
        """
        Returns
        -------
        current_decision
            we are always following the gradient in this model
        plume_signal
            tell upstream code to look up plume signal
        """
        plume_signal = 'X'  # magic code to look up gradient
        current_decision = 'ga'

        return current_decision, plume_signal
<commit_msg>fixing tuple error<commit_after>
class Decisions:
    def __init__(self, decision_policy, stimulus_memory_n_timesteps):
        # we take plume as input for the gradient ascent. however, this is inelegant. FIXME
        self.decision_policy = decision_policy

        self.stimulus_memory_n_timesteps = stimulus_memory_n_timesteps
        self.plume_sighted_ago = 10000000  # a long time ago
        self.last_plume_side_exited = None

    def make_decision(self, in_plume, crosswind_velocity):
        if 'cast' in self.decision_policy:
            current_decision, plume_signal = self._boolean_decisions(in_plume, crosswind_velocity)
        elif 'surge' in self.decision_policy:
            current_decision, plume_signal = self._boolean_decisions(in_plume, crosswind_velocity)
        elif 'gradient' in self.decision_policy:
            current_decision, plume_signal = self._gradient_decisions()
        elif 'ignore' in self.decision_policy:
            current_decision, plume_signal = 'ignore', 0
        else:
            raise ValueError('unk decision policy {}'.format(self.decision_policy))

        return current_decision, plume_signal

    def _boolean_decisions(self, in_plume, crosswind_velocity):
        if in_plume == True:  # use == instead of "is" because we're using type np.bool
            self.plume_sighted_ago = 0
            plume_signal = 'in'
            if 'surge' in self.decision_policy:
                current_decision = 'surge'
            else:
                current_decision = 'search'
        elif in_plume == False:
            self.plume_sighted_ago += 1
            if self.plume_sighted_ago == 1:  # we just exited the plume
                # if our y velocity is negative, we just exited to the left. otherwise, to the right.
                if crosswind_velocity < 0:
                    plume_signal = 'exit_l'
                    self.last_plume_side_exited = 'l'
                    current_decision = 'cast_r'
                else:
                    plume_signal = 'exit_r'
                    self.last_plume_side_exited = 'r'
                    current_decision = 'cast_l'
            else:  # been outside plume at least a couple timesteps
                plume_signal = 'out'
                if 'cast' in self.decision_policy:
                    if self.plume_sighted_ago <= self.stimulus_memory_n_timesteps:  # we were in the plume recently
                        if self.last_plume_side_exited == 'l':
                            current_decision = 'cast_r'
                        else:  # 'r'
                            current_decision = 'cast_l'
                    else:  # haven't seen the plume in a while
                        current_decision = 'search'
                else:
                    current_decision = 'search'

        return current_decision, plume_signal

    def _gradient_decisions(self):
        """
        Returns
        -------
        current_decision
            we are always following the gradient in this model
        plume_signal
            tell upstream code to look up plume signal
        """
        plume_signal = 'X'  # magic code to look up gradient
        current_decision = 'ga'

        return current_decision, plume_signal
<|endoftext|>


<commit_before>from django.db import models

from uuid import UUID

class UUIDField(models.BinaryField, metaclass=models.SubfieldBase):
    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = 16
        super().__init__(*args, **kwargs)

    def deconstruct(self):
        name, path, args, kwargs = super().deconstruct()
        del kwargs['max_length']
        return name, path, args, kwargs

    def to_python(self, value):
        if not value or isinstance(value, UUID):
            return value
        return UUID(bytes=value)

    def get_prep_value(self, value):
        return super().get_prep_value(value.bytes)
<commit_msg>Adding bytes() in UUIDField<commit_after>from django.db import models

from uuid import UUID

class UUIDField(models.BinaryField, metaclass=models.SubfieldBase):
    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = 16
        super().__init__(*args, **kwargs)

    def deconstruct(self):
        name, path, args, kwargs = super().deconstruct()
        del kwargs['max_length']
        return name, path, args, kwargs

    def to_python(self, value):
        if not value or isinstance(value, UUID):
            return value
        return UUID(bytes=bytes(value))

    def get_prep_value(self, value):
        return super().get_prep_value(value.bytes)
<|endoftext|>


<commit_before>from roglick.lib import libtcod

class Color(object):
    def __init__(self, r, g, b):
        self._rgb = (r,g,b)
        self._libtcod = None

    @property
    def libtcod(self):
        if self._libtcod is None:
            self._libtcod = libtcod.Color(*self._rgb)

        return self._libtcod

class RGBBlendedColor(Color):
    def __init__(self, color1, color2, blend=0.50):
        # Get the RGB components of our base colors
        r1,g1,b1 = color1._rgb
        r2,g2,b2 = color2._rgb

        # Easy-peasy: linearly interpolate each component...
        r = r1 + (r2 - r1) * blend
        g = g1 + (g2 - g1) * blend
        b = b1 + (b2 - b1) * blend

        # ...and put them all back together into our new color
        super().__init__(r,g,b)

class HSVBlendedColor(Color):
    def __init__(self, color1, color2, blend=0.50):
        # Convert our base colors to HSV
        h1,s1,v1 = RGBtoHSV(*color1._rgb)
        h2,s2,v2 = RGBtoHSV(*color2._rgb)

        # Linearly interpolate s and v
        s = s1 + (s2 - s1) * blend
        v = v1 + (v2 - v1) * blend

        # h gets tricky because it's the angle around a circle...
        # Logic here is taken from:
        # http://www.stuartdenman.com/improved-color-blending/
        hmin = min(h1, h2)
        hmax = max(h1, h2)
        d = hmax - hmin
        if hmax == h1:
            blend = 1 - blend
        if d > 180:
            hmin = hmin + 360
            h = (hmin + blend * (hmax-hmin)) % 360
        else:
            h = hmin + blend * d

        # Now convert back to RGB and create the Color
        super().__init__(*HSVtoRGB(h,s,v))

def RGBtoHSV(r, g, b):
    """Convert RGB values to HSV

    Algorithm is taken from https://www.cs.rit.edu/~ncs/color/t_convert.html
    """
    # If we were given black, return black
    if r == 0 and g == 0 and b == 0:
        return 0,0,0

    # We need RGB from 0-1, not 0-255
    r /= 255
    g /= 255
    b /= 255

    min_rgb = min(r, g, b)
    max_rgb = max(r, g, b)
    delta = max_rgb - min_rgb

    v = max_rgb
    s = delta / max_rgb

    if delta == 0:
        return 0,s,v
    elif r == max_rgb:
        # Between yellow and magenta
        h = (g - b) / delta
    elif g == max_rgb:
        # Between cyan and yellow
        h = 2 + (b - r) / delta
    else:
        # Between magenta and cyan
        h = 4 + (r - g) / delta

    h *= 60 # Degrees
    if h < 0:
        h += 360

    return h,s,v

def HSVtoRGB(h, s, v):
    """Convert HSV values to RGB

    Algorithm is taken from https://www.cs.rit.edu/~ncs/color/t_convert.html
    """
    if s == 0:
        # Achromatic, i.e. gray
        gray = v * 255
        return gray,gray,gray

    # Calculate our "sectors"
    h /= 60
    i = int(h)
    # A few intermediate values we may need
    f = h - i
    p = v * (1 - s)
    q = v * (1 - s * f)
    t = v * (1 - s * (1 - f))

    # Figure out which "sector" of the HSV cylinder we're in and assign RGB
    if i == 0:
        r = v
        g = t
        b = p
    elif i == 1:
        r = q
        g = v
        b = p
    elif i == 2:
        r = p
        g = v
        b = t
    elif i == 3:
        r = p
        g = q
        b = v
    elif i == 4:
        r = t
        g = p
        b = v
    else:
        r = v
        g = p
        b = q

    r *= 255
    g *= 255
    b *= 255

    return r,g,b

# This color palette is taken from the "DB32" palette
# http://pixeljoint.com/forum/forum_posts.asp?TID=16247
black = Color(0,0,0)
valhalla = Color(34,32,52)
loulou = Color(69,40,60)
oiled_cedar = Color(102,57,49)
rope = Color(143,86,59)
orange = Color(223,113,38)
twine = Color(217,160,102)
pancho = Color(238,195,154)
gold = Color(251,242,54)
atlantis = Color(153,229,80)
christi = Color(106,190,48)
elf_green = Color(55,148,110)
dell = Color(75,105,47)
verdigris = Color(82,75,36)
opal = Color(50,60,57)
deep_koamaru = Color(63,63,116)
venice_blue = Color(48,96,130)
royal_blue = Color(91,110,225)
cornflower = Color(99,155,255)
viking = Color(95,205,228)
light_steel_blue = Color(203,219,252)
white = Color(255,255,255)
heather = Color(155,173,183)
topaz = Color(132,126,135)
dim_gray = Color(105,106,106)
smokey_ash = Color(89,86,82)
clairvoyant = Color(118,66,138)
red = Color(172,50,50)
mandy = Color(217,87,99)
plum = Color(215,123,186)
rain_forest = Color(143,151,74)
stinger = Color(138,111,48)

<commit_msg>Drop redundant Color class<commit_after>from roglick.lib import libtcod

class RGBBlendedColor(libtcod.Color):
    def __init__(self, color1, color2, blend=0.50):
        # Get the RGB components of our base colors
        r1,g1,b1 = color1.r,color1.g,color1.b
        r2,g2,b2 = color2.r,color2.g,color2.b

        # Easy-peasy: linearly interpolate each component...
        r = r1 + (r2 - r1) * blend
        g = g1 + (g2 - g1) * blend
        b = b1 + (b2 - b1) * blend

        # ...and put them all back together into our new color
        super().__init__(int(r),int(g),int(b))

class HSVBlendedColor(libtcod.Color):
    def __init__(self, color1, color2, blend=0.50):
        # Get the HSV components of our base colors
        h1,s1,v1 = RGBtoHSV(color1.r,color1.g,color1.b)
        h2,s2,v2 = RGBtoHSV(color2.r,color2.g,color2.b)

        # Linearly interpolate s and v
        s = s1 + (s2 - s1) * blend
        v = v1 + (v2 - v1) * blend

        # h gets tricky because it's the angle around a circle...
        # Logic here is taken from:
        # http://www.stuartdenman.com/improved-color-blending/
        hmin = min(h1, h2)
        hmax = max(h1, h2)
        d = hmax - hmin
        if hmax == h1:
            blend = 1 - blend
        if d > 180:
            hmin = hmin + 360
            h = (hmin + blend * (hmax-hmin)) % 360
        else:
            h = hmin + blend * d

        # Now convert back to RGB and create the Color
        r,g,b = HSVtoRGB(h,s,v)
        super().__init__(int(r),int(g),int(b))

def RGBtoHSV(r, g, b):
    """Convert RGB values to HSV

    Algorithm is taken from https://www.cs.rit.edu/~ncs/color/t_convert.html
    """
    # If we were given black, return black
    if r == 0 and g == 0 and b == 0:
        return 0,0,0

    # We need RGB from 0-1, not 0-255
    r /= 255
    g /= 255
    b /= 255

    min_rgb = min(r, g, b)
    max_rgb = max(r, g, b)
    delta = max_rgb - min_rgb

    v = max_rgb
    s = delta / max_rgb

    if delta == 0:
        return 0,s,v
    elif r == max_rgb:
        # Between yellow and magenta
        h = (g - b) / delta
    elif g == max_rgb:
        # Between cyan and yellow
        h = 2 + (b - r) / delta
    else:
        # Between magenta and cyan
        h = 4 + (r - g) / delta

    h *= 60 # Degrees
    if h < 0:
        h += 360

    return h,s,v

def HSVtoRGB(h, s, v):
    """Convert HSV values to RGB

    Algorithm is taken from https://www.cs.rit.edu/~ncs/color/t_convert.html
    """
    if s == 0:
        # Achromatic, i.e. gray
        gray = v * 255
        return gray,gray,gray

    # Calculate our "sectors"
    h /= 60
    i = int(h)
    # A few intermediate values we may need
    f = h - i
    p = v * (1 - s)
    q = v * (1 - s * f)
    t = v * (1 - s * (1 - f))

    # Figure out which "sector" of the HSV cylinder we're in and assign RGB
    if i == 0:
        r = v
        g = t
        b = p
    elif i == 1:
        r = q
        g = v
        b = p
    elif i == 2:
        r = p
        g = v
        b = t
    elif i == 3:
        r = p
        g = q
        b = v
    elif i == 4:
        r = t
        g = p
        b = v
    else:
        r = v
        g = p
        b = q

    r *= 255
    g *= 255
    b *= 255

    return r,g,b

# This color palette is taken from the "DB32" palette
# http://pixeljoint.com/forum/forum_posts.asp?TID=16247
black = libtcod.Color(0,0,0)
valhalla = libtcod.Color(34,32,52)
loulou = libtcod.Color(69,40,60)
oiled_cedar = libtcod.Color(102,57,49)
rope = libtcod.Color(143,86,59)
orange = libtcod.Color(223,113,38)
twine = libtcod.Color(217,160,102)
pancho = libtcod.Color(238,195,154)
gold = libtcod.Color(251,242,54)
atlantis = libtcod.Color(153,229,80)
christi = libtcod.Color(106,190,48)
elf_green = libtcod.Color(55,148,110)
dell = libtcod.Color(75,105,47)
verdigris = libtcod.Color(82,75,36)
opal = libtcod.Color(50,60,57)
deep_koamaru = libtcod.Color(63,63,116)
venice_blue = libtcod.Color(48,96,130)
royal_blue = libtcod.Color(91,110,225)
cornflower = libtcod.Color(99,155,255)
viking = libtcod.Color(95,205,228)
light_steel_blue = libtcod.Color(203,219,252)
white = libtcod.Color(255,255,255)
heather = libtcod.Color(155,173,183)
topaz = libtcod.Color(132,126,135)
dim_gray = libtcod.Color(105,106,106)
smokey_ash = libtcod.Color(89,86,82)
clairvoyant = libtcod.Color(118,66,138)
red = libtcod.Color(172,50,50)
mandy = libtcod.Color(217,87,99)
plum = libtcod.Color(215,123,186)
rain_forest = libtcod.Color(143,151,74)
stinger = libtcod.Color(138,111,48)

<|endoftext|>


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

# First you need to create an svg file.
# After that it`s simple to merge two svg files.
# http://neuroscience.telenczuk.pl/?p=331
import svgutils.transform as st

template = st.fromfile('template/4x6-index-card-portrait.svg')
im_b = st.fromfile('second.svg')

template.append(im_b)
template.save('merged.svg')
<commit_msg>merging figures on svg<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

# First you need to create an svg file.
# After that it`s simple to merge two svg files.
# http://neuroscience.telenczuk.pl/?p=331
import svgutils.transform as st
import svgwrite

def merge(model, mus):
    """
    model: svg file, containing Music Box paper sheet
    mus: extracted from Lilypond
    """
    for compass in mus:
        # Program here setup of coordinates to create figures
        dwg = svgwrite.Drawing('compass.svg')
        for note in compass: # note is a pair of x,y coordinates
            dwg.add(dwg.circle((note), r=5, fill='blue'))
            #square = dwg.add(dwg.rect((20,20),(80,80), fill='blue'))
        dwg.saveas('music.svg')

    template = st.fromfile('template/4x6-index-card-portrait.svg')

    music = st.fromfile('music.svg')

    template.append(music)
    template.save('rollingnotes.svg')

<|endoftext|>


<commit_before>import yaml

import esx_snmp
import synology_snmp
import ups_snmp
import misc_ipmi

import time
import datetime
import math

# starttime=time.time()

SECONDS = 30.0

def roundTimeToSeconds(unixTime,secondsToRound):
	return int(round(unixTime / secondsToRound) * secondsToRound)

with open("config.yaml", 'r') as stream:
	try:
		config = yaml.load(stream)
	except yaml.YAMLError as exc:
		print(exc)

while True:
	print("Gathering statistics every "+str(SECONDS)+" seconds")
	# timeTest = int(round(time.time() / SECONDS) * SECONDS)
	# timeTest = (math.ceil(time.time() / SECONDS))*SECONDS
	# timeTest = (math.ceil(time.time() / SECONDS))*SECONDS
	timeStamp = roundTimeToSeconds(time.time(),SECONDS)

	print("Actual Time:",datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S'))
	print("Timestamp:",datetime.datetime.fromtimestamp(timeStamp).strftime('%Y-%m-%d %H:%M:%S'))

	INFLUXDB_CONFIG = config["influxdb"]
	ESXI_HOSTS = config["esxi_hosts"]
	IPMI_HOSTS = config["ipmi_hosts"]
	SYNOLOGY_HOSTS = config["synology_hosts"]
	UPS_HOSTS = config["ups_hosts"]

	for hostData in ESXI_HOSTS:
		esx_snmp.procLoad(INFLUXDB_CONFIG,hostData,timeStamp)
		esx_snmp.VMList(INFLUXDB_CONFIG,hostData,timeStamp)

	for hostData in IPMI_HOSTS:
		misc_ipmi.fanTempMeasure(INFLUXDB_CONFIG,hostData,timeStamp)

	for hostData in SYNOLOGY_HOSTS:
		synology_snmp.diskUsage(INFLUXDB_CONFIG,hostData,timeStamp)
		synology_snmp.diskTemp(INFLUXDB_CONFIG,hostData,timeStamp)

	for hostData in UPS_HOSTS:
		ups_snmp.upsPower(INFLUXDB_CONFIG,hostData,timeStamp)

	timeToSleep = SECONDS - ((time.time() - timeStamp) % SECONDS)
	print("Statistics gathered, sleeping for "+str(timeToSleep)+" seconds")
	time.sleep(timeToSleep)
	pass<commit_msg>Fixed Config file path<commit_after>import yaml

import esx_snmp
import synology_snmp
import ups_snmp
import misc_ipmi

import time
import datetime
import math

# starttime=time.time()

SECONDS = 30.0

def roundTimeToSeconds(unixTime,secondsToRound):
	return int(round(unixTime / secondsToRound) * secondsToRound)

with open("../config/config.yaml", 'r') as stream:
	try:
		config = yaml.load(stream)
	except yaml.YAMLError as exc:
		print(exc)

while True:
	print("Gathering statistics every "+str(SECONDS)+" seconds")
	# timeTest = int(round(time.time() / SECONDS) * SECONDS)
	# timeTest = (math.ceil(time.time() / SECONDS))*SECONDS
	# timeTest = (math.ceil(time.time() / SECONDS))*SECONDS
	timeStamp = roundTimeToSeconds(time.time(),SECONDS)

	print("Actual Time:",datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S'))
	print("Timestamp:",datetime.datetime.fromtimestamp(timeStamp).strftime('%Y-%m-%d %H:%M:%S'))

	INFLUXDB_CONFIG = config["influxdb"]
	ESXI_HOSTS = config["esxi_hosts"]
	IPMI_HOSTS = config["ipmi_hosts"]
	SYNOLOGY_HOSTS = config["synology_hosts"]
	UPS_HOSTS = config["ups_hosts"]

	for hostData in ESXI_HOSTS:
		esx_snmp.procLoad(INFLUXDB_CONFIG,hostData,timeStamp)
		esx_snmp.VMList(INFLUXDB_CONFIG,hostData,timeStamp)

	for hostData in IPMI_HOSTS:
		misc_ipmi.fanTempMeasure(INFLUXDB_CONFIG,hostData,timeStamp)

	for hostData in SYNOLOGY_HOSTS:
		synology_snmp.diskUsage(INFLUXDB_CONFIG,hostData,timeStamp)
		synology_snmp.diskTemp(INFLUXDB_CONFIG,hostData,timeStamp)

	for hostData in UPS_HOSTS:
		ups_snmp.upsPower(INFLUXDB_CONFIG,hostData,timeStamp)

	timeToSleep = SECONDS - ((time.time() - timeStamp) % SECONDS)
	print("Statistics gathered, sleeping for "+str(timeToSleep)+" seconds")
	time.sleep(timeToSleep)
	pass<|endoftext|>


<commit_before>from abc import ABCMeta
from io import BytesIO
from PIL import Image

import numpy
from six import PY3, add_metaclass

from ._image import window_batch_bchw
from . import ExpectsAxisLabels, SourcewiseTransformer
from .. import config

@add_metaclass(ABCMeta)
class ImagesFromBytes(SourcewiseTransformer):
    """Load from a stream of image-formatted data represented as bytes.

    Parameters
    ----------
    data_stream : instance of :class:`AbstractDataStream`
        The wrapped data stream.
    which_sources : tuple of str
        Which sources to apply the mapping to.
    color_mode : str, optional
        Mode to pass to PIL for color space conversion. Default is RGB.
        If `None`, no coercion is performed.

    Notes
    -----
    Images are returned as NumPy arrays converted from PIL objects.
    If `color_mode` is RGB, then the array is transposed from the
    `(height, width, channel)` dimension layout native to PIL to the
    `(channel, height, width)` layout that is pervasive in the world of
    convolutional networks.

    This SourcewiseTransformer supports streams returning single examples as
    `bytes` objects (`str` on Python 2.x) as well as streams that
    return iterables containing such objects. In the case of an
    iterable, a list of loaded images is returned.

    """
    def __init__(self, data_stream, which_sources, color_mode='RGB'):
        super(ImagesFromBytes, self).__init__(data_stream, which_sources)
        self.color_mode = color_mode

    def transform_source_example(self, example):
        if PY3:
            bytes_type = bytes
        else:
            bytes_type = str
        if not isinstance(example, bytes_type):
            raise TypeError("expected {} object".format(bytes_type.__name__))
        pil_image = Image.open(BytesIO(example))
        if self.color_mode is not None:
            pil_image = pil_image.convert(self.color_mode)
        image = numpy.array(pil_image)
        if self.color_mode == 'RGB':
            # Transpose to `(channels, height, width)` layout.
            return image.transpose(2, 0, 1)
        else:
            return image

    def transform_source_batch(self, batch):
        return [self.transform_source_example(im) for im in batch]

@add_metaclass(ABCMeta)
class MinimumImageDimensions(SourcewiseTransformer, ExpectsAxisLabels):
    """Resize (lists of) images to minimum dimensions.

    Parameters
    ----------
    data_stream : instance of :class:`AbstractDataStream`
        The data stream to wrap.
    minimum_shape : 2-tuple
        The minimum `(height, width)` dimensions every image must have.
        Images whose height and width are larger than these dimensions
        are passed through as-is.
    resample : str, optional
        Resampling filter for PIL to use to upsample any images requiring
        it. Options include 'nearest' (default), 'bilinear', and 'bicubic'.
        See the PIL documentation for more detailed information.

    Notes
    -----
    This transformer expects stream sources returning individual images,
    represented as 2- or 3-dimensional arrays, or lists of the same.
    The format of the stream is unaltered.

    """
    def __init__(self, data_stream, minimum_shape, resample='nearest',
                 **kwargs):
        self.minimum_shape = minimum_shape
        try:
            self.resample = getattr(Image, resample.upper())
        except AttributeError:
            raise ValueError("unknown resampling filter '{}'".format(resample))
        super(MinimumImageDimensions, self).__init__(data_stream, **kwargs)

    def transform_source_batch(self, batch):
        self.verify_axis_labels(('batch', 'channel', 'height', 'width'),
                                self.data_stream.axis_labels)
        return [self.transform_source_example(im) for im in batch]

    def transform_source_example(self, example):
        self.verify_axis_labels(('channel', 'height', 'width'),
                                self.data_stream.axis_labels)
        if example.ndim > 3 or example.ndim < 2:
            raise NotImplementedError
        min_height, min_width = self.min_shape
        original_height, original_width = example.shape[-2:]
        if original_height < min_height or original_width < min_width:
            dt = example.dtype
            # If we're dealing with a colour image, swap around the axes
            # to be in the format that PIL needs.
            if example.ndim == 3:
                im = example.tranpose(2, 0, 1)
            else:
                im = example
            im = Image.fromarray(im)
            width, height = im.size
            # Based on the current width and height, generate
            # dimensions that respect the minimum constraints but also
            # match the old aspect ratio.
            aspect = float(width) / height
            if width < min_width:
                width = min_width
                height = int(width / aspect)
            # N.B.: not elif. Aspect-ratio corrected height may be less
            # than minimum requested height.
            if height < min_height:
                height = min_height
                width = int(height * aspect)
            im = numpy.array(im.resize((width, height))).astype(dt)
            # If necessary, undo the axis swap from earlier.
            if im.ndim == 3:
                example = im.transpose(2, 0, 1)
            else:
                example = im
        return example

@add_metaclass(ABCMeta)
class RandomFixedSizeCrop(SourcewiseTransformer, ExpectsAxisLabels):
    """Randomly crop images to a fixed window size.

    Parameters
    ----------
    data_stream : :class:`AbstractDataStream`
        The data stream to wrap.
    window_shape : tuple
        The `(height, width)` tuple representing the size of the output
        window.

    Notes
    -----
    This transformer expects to act on stream sources which provide one of

     * Single images represented as 3-dimensional ndarrays, with layout
       `(n_channels, height, width)`.
     * Batches of images represented as lists of 3-dimensional ndarrays,
       possibly of different shapes (i.e. images of differing
       heights/widths).
     * Batches of images represented as 4-dimensional ndarrays, with
       layout `(batch, n_channels, height, width)`.

    The format of the stream will be un-altered, i.e. if lists are
    yielded by `data_stream` then lists will be yielded by this
    transformer.

    """
    def __init__(self, data_stream, window_shape, **kwargs):
        self.window_shape = window_shape
        self.rng = kwargs.pop('rng', None)
        self.warned_axis_labels = False
        if self.rng is None:
            self.rng = numpy.random.RandomState(config.default_seed)
        kwargs.setdefault('axis_labels', data_stream.axis_labels)
        super(RandomFixedSizeCrop, self).__init__(data_stream, **kwargs)

    def transform_source_batch(self, source):
        self.verify_axis_labels(('batch', 'channel', 'height', 'width'),
                                self.data_stream.axis_labels)
        windowed_height, windowed_width = self.window_shape
        if isinstance(source, list):
            return [self.transform_source_example(im) for im in source]
        elif isinstance(source, numpy.ndarray) and source.ndim == 4:
            # Hardcoded assumption of (batch, channels, height, width).
            # This is what the fast Cython code supports.
            out = numpy.empty(source.shape[:2] + self.window_shape,
                              dtype=source.dtype)
            batch_size = source.shape[0]
            image_height, image_width = source.shape[2:]
            max_h_off = image_height - windowed_height
            max_w_off = image_width - windowed_width
            if max_h_off < 0 or max_w_off < 0:
                raise ValueError("Got ndarray batch with image dimensions {} "
                                 "but requested window shape of {}".format(
                                     source.shape[2:], self.window_shape))
            offsets_w = self.rng.random_integers(0, max_w_off, size=batch_size)
            offsets_h = self.rng.random_integers(0, max_h_off, size=batch_size)
            window_batch_bchw(source, offsets_h, offsets_w, out)
            return out
        else:
            raise ValueError("uninterpretable batch format; expected a list "
                             "of arrays with ndim = 3, or an array with "
                             "ndim = 4")

    def transform_source_example(self, example):
        self.verify_axis_labels(('channel', 'height', 'width'),
                                self.data_stream.axis_labels)
        windowed_height, windowed_width = self.window_shape
        if not isinstance(example, numpy.ndarray) or example.ndim != 3:
            raise ValueError("uninterpretable example format; expected "
                             "ndarray with ndim = 3")
        image_height, image_width = example.shape[1:]
        assert image_height >= windowed_height
        assert image_width >= windowed_width
        if image_height - windowed_height > 0:
            off_h = self.rng.random_integers(image_height - windowed_height)
        else:
            off_h = 0
        if image_width - windowed_width > 0:
            off_w = self.rng.random_integers(image_width - windowed_width)
        else:
            off_w = 0
        return example[off_h:off_h + windowed_height,
                       off_w:off_w + windowed_width]
<commit_msg>Docstring fix.<commit_after>from abc import ABCMeta
from io import BytesIO
from PIL import Image

import numpy
from six import PY3, add_metaclass

from ._image import window_batch_bchw
from . import ExpectsAxisLabels, SourcewiseTransformer
from .. import config

@add_metaclass(ABCMeta)
class ImagesFromBytes(SourcewiseTransformer):
    """Load from a stream of image-formatted data represented as bytes.

    Parameters
    ----------
    data_stream : instance of :class:`AbstractDataStream`
        The wrapped data stream.
    which_sources : tuple of str
        Which sources to apply the mapping to.
    color_mode : str, optional
        Mode to pass to PIL for color space conversion. Default is RGB.
        If `None`, no coercion is performed.

    Notes
    -----
    Images are returned as NumPy arrays converted from PIL objects.
    If `color_mode` is RGB, then the array is transposed from the
    `(height, width, channel)` dimension layout native to PIL to the
    `(channel, height, width)` layout that is pervasive in the world of
    convolutional networks.

    This SourcewiseTransformer supports streams returning single examples
    as `bytes` objects (`str` on Python 2.x) as well as streams that
    return iterables containing such objects. In the case of an
    iterable, a list of loaded images is returned.

    """
    def __init__(self, data_stream, which_sources, color_mode='RGB'):
        super(ImagesFromBytes, self).__init__(data_stream, which_sources)
        self.color_mode = color_mode

    def transform_source_example(self, example):
        if PY3:
            bytes_type = bytes
        else:
            bytes_type = str
        if not isinstance(example, bytes_type):
            raise TypeError("expected {} object".format(bytes_type.__name__))
        pil_image = Image.open(BytesIO(example))
        if self.color_mode is not None:
            pil_image = pil_image.convert(self.color_mode)
        image = numpy.array(pil_image)
        if self.color_mode == 'RGB':
            # Transpose to `(channels, height, width)` layout.
            return image.transpose(2, 0, 1)
        else:
            return image

    def transform_source_batch(self, batch):
        return [self.transform_source_example(im) for im in batch]

@add_metaclass(ABCMeta)
class MinimumImageDimensions(SourcewiseTransformer, ExpectsAxisLabels):
    """Resize (lists of) images to minimum dimensions.

    Parameters
    ----------
    data_stream : instance of :class:`AbstractDataStream`
        The data stream to wrap.
    minimum_shape : 2-tuple
        The minimum `(height, width)` dimensions every image must have.
        Images whose height and width are larger than these dimensions
        are passed through as-is.
    resample : str, optional
        Resampling filter for PIL to use to upsample any images requiring
        it. Options include 'nearest' (default), 'bilinear', and 'bicubic'.
        See the PIL documentation for more detailed information.

    Notes
    -----
    This transformer expects stream sources returning individual images,
    represented as 2- or 3-dimensional arrays, or lists of the same.
    The format of the stream is unaltered.

    """
    def __init__(self, data_stream, minimum_shape, resample='nearest',
                 **kwargs):
        self.minimum_shape = minimum_shape
        try:
            self.resample = getattr(Image, resample.upper())
        except AttributeError:
            raise ValueError("unknown resampling filter '{}'".format(resample))
        super(MinimumImageDimensions, self).__init__(data_stream, **kwargs)

    def transform_source_batch(self, batch):
        self.verify_axis_labels(('batch', 'channel', 'height', 'width'),
                                self.data_stream.axis_labels)
        return [self.transform_source_example(im) for im in batch]

    def transform_source_example(self, example):
        self.verify_axis_labels(('channel', 'height', 'width'),
                                self.data_stream.axis_labels)
        if example.ndim > 3 or example.ndim < 2:
            raise NotImplementedError
        min_height, min_width = self.min_shape
        original_height, original_width = example.shape[-2:]
        if original_height < min_height or original_width < min_width:
            dt = example.dtype
            # If we're dealing with a colour image, swap around the axes
            # to be in the format that PIL needs.
            if example.ndim == 3:
                im = example.tranpose(2, 0, 1)
            else:
                im = example
            im = Image.fromarray(im)
            width, height = im.size
            # Based on the current width and height, generate
            # dimensions that respect the minimum constraints but also
            # match the old aspect ratio.
            aspect = float(width) / height
            if width < min_width:
                width = min_width
                height = int(width / aspect)
            # N.B.: not elif. Aspect-ratio corrected height may be less
            # than minimum requested height.
            if height < min_height:
                height = min_height
                width = int(height * aspect)
            im = numpy.array(im.resize((width, height))).astype(dt)
            # If necessary, undo the axis swap from earlier.
            if im.ndim == 3:
                example = im.transpose(2, 0, 1)
            else:
                example = im
        return example

@add_metaclass(ABCMeta)
class RandomFixedSizeCrop(SourcewiseTransformer, ExpectsAxisLabels):
    """Randomly crop images to a fixed window size.

    Parameters
    ----------
    data_stream : :class:`AbstractDataStream`
        The data stream to wrap.
    window_shape : tuple
        The `(height, width)` tuple representing the size of the output
        window.

    Notes
    -----
    This transformer expects to act on stream sources which provide one of

     * Single images represented as 3-dimensional ndarrays, with layout
       `(n_channels, height, width)`.
     * Batches of images represented as lists of 3-dimensional ndarrays,
       possibly of different shapes (i.e. images of differing
       heights/widths).
     * Batches of images represented as 4-dimensional ndarrays, with
       layout `(batch, n_channels, height, width)`.

    The format of the stream will be un-altered, i.e. if lists are
    yielded by `data_stream` then lists will be yielded by this
    transformer.

    """
    def __init__(self, data_stream, window_shape, **kwargs):
        self.window_shape = window_shape
        self.rng = kwargs.pop('rng', None)
        self.warned_axis_labels = False
        if self.rng is None:
            self.rng = numpy.random.RandomState(config.default_seed)
        kwargs.setdefault('axis_labels', data_stream.axis_labels)
        super(RandomFixedSizeCrop, self).__init__(data_stream, **kwargs)

    def transform_source_batch(self, source):
        self.verify_axis_labels(('batch', 'channel', 'height', 'width'),
                                self.data_stream.axis_labels)
        windowed_height, windowed_width = self.window_shape
        if isinstance(source, list):
            return [self.transform_source_example(im) for im in source]
        elif isinstance(source, numpy.ndarray) and source.ndim == 4:
            # Hardcoded assumption of (batch, channels, height, width).
            # This is what the fast Cython code supports.
            out = numpy.empty(source.shape[:2] + self.window_shape,
                              dtype=source.dtype)
            batch_size = source.shape[0]
            image_height, image_width = source.shape[2:]
            max_h_off = image_height - windowed_height
            max_w_off = image_width - windowed_width
            if max_h_off < 0 or max_w_off < 0:
                raise ValueError("Got ndarray batch with image dimensions {} "
                                 "but requested window shape of {}".format(
                                     source.shape[2:], self.window_shape))
            offsets_w = self.rng.random_integers(0, max_w_off, size=batch_size)
            offsets_h = self.rng.random_integers(0, max_h_off, size=batch_size)
            window_batch_bchw(source, offsets_h, offsets_w, out)
            return out
        else:
            raise ValueError("uninterpretable batch format; expected a list "
                             "of arrays with ndim = 3, or an array with "
                             "ndim = 4")

    def transform_source_example(self, example):
        self.verify_axis_labels(('channel', 'height', 'width'),
                                self.data_stream.axis_labels)
        windowed_height, windowed_width = self.window_shape
        if not isinstance(example, numpy.ndarray) or example.ndim != 3:
            raise ValueError("uninterpretable example format; expected "
                             "ndarray with ndim = 3")
        image_height, image_width = example.shape[1:]
        assert image_height >= windowed_height
        assert image_width >= windowed_width
        if image_height - windowed_height > 0:
            off_h = self.rng.random_integers(image_height - windowed_height)
        else:
            off_h = 0
        if image_width - windowed_width > 0:
            off_w = self.rng.random_integers(image_width - windowed_width)
        else:
            off_w = 0
        return example[off_h:off_h + windowed_height,
                       off_w:off_w + windowed_width]
<|endoftext|>