<commit_before>import types, os

from neuroimaging import traits
import numpy as N

from neuroimaging import flatten
from neuroimaging.data_io import DataSource
from neuroimaging.data_io.formats import getformats, Format
from neuroimaging.core.reference.grid import SamplingGrid

class BaseImage(object):
    """
    This class define a minimal interface which different types of images
    should implement. This interface is used by the Image class, which is
    the class which should be used by applications.
    """

    def __init__(self, data, grid, sctype):
        assert(data.shape == grid.shape)
        self.grid = grid
        self.data = data
        self.sctype = sctype

    def __getitem__(self, item):
        return self.data[item]

    def __setitem__(self, item, value):
        self[item] = value

class ArrayImage (BaseImage):
    """A simple class to mimic an image file from an array."""
    def __init__(self, data, grid=None):
        """
        Create an ArrayImage instance from an array,
        by default assumed to be 3d.

        >>> from numpy import *
        >>> from neuroimaging.core.image import Image
        >>> z = Image.ArrayImage(zeros((10,20,20)))
        >>> print z.ndim
        3
        """
        grid = grid and grid or SamplingGrid.identity(self.shape)
        sctype = data.dtype.type
        BaseImage.__init__(self, data, grid, sctype)

class Image(object):

    @staticmethod
    def fromurl(url, datasource=DataSource(), format=None, grid=None, mode="r", clobber=False,
      **keywords):
        zipexts = (".gz",".bz2")
        base, ext = os.path.splitext(url.strip())
        if ext in zipexts: url = base
        if not format: valid = getformats(url)
        else: valid = [format]
        for format in valid:
            try:
                return format(filename=url,
                               datasource=datasource, mode=mode, clobber=clobber, grid=grid, **keywords)
            except Exception, e:
                pass

        raise NotImplementedError, 'no valid reader found for URL %s' % url

    def __init__(self, image, datasource=DataSource(), grid=None, **keywords):
        '''
        Create a Image (volumetric image) object from either a file, an
        existing Image object, or an array.
        '''

        # from existing Image
        if isinstance(image, Image):
            self._source = image._source

        # from existing Format instance
        elif isinstance(image, Format):
            self._source = image

        # from array
        elif isinstance(image, N.ndarray) or isinstance(image, N.core.memmap):
            self._source = ArrayImage(image, grid=grid)

        # from filename or url
        elif type(image) == types.StringType:
            self._source = self.fromurl(image, datasource, grid=grid, **keywords)

        else:
            raise ValueError(
          "Image input must be a string, array, or another image.")
        # Find spatial grid -- this is the one that will be used generally
        self.grid = self._source.grid
        self.shape = list(self.grid.shape)
        self.ndim = len(self.shape)

        # When possible, attach memory-mapped array or array as buffer attr
        if hasattr(self._source, 'memmap'):
            self.buffer = self._source.memmap
        else:
            self.buffer = self._source.data

        self.postread = lambda x:x
        self.fill = 0.0

    def __getitem__(self, slice): return self._source[slice]
    def __setitem__(self, slice, data): self._source[slice] = data

    def __iter__(self):
        "Create an iterator over an image based on its grid's iterator."
        iter(self.grid)
        if self.grid.get_iter_param("itertype") in ["parcel", "slice/parcel"]:
            self.buffer.shape = N.product(self.buffer.shape)
        return self

    def compress(self, where, axis=0):
        if hasattr(self, 'buffer'):
            return self.buffer.compress(where, axis=axis)
        else: raise ValueError, 'no buffer: compress not supported'

    def put(self, data, indices):
        if hasattr(self, 'buffer'):
            return self.buffer.put(data, indices)
        else: raise ValueError, 'no buffer: put not supported'

    def next(self, value=None, data=None):
        """
        The value argument here is used when, for instance one wants to
        iterate over one image with a ParcelIterator and write out data
        to this image without explicitly setting this image's grid to
        the original image's grid, i.e. to just take the value the
        original image's iterator returns and use it here.
        """
        if value is None:
            self.itervalue = value = self.grid.next()
        itertype = self.grid.get_iter_param("itertype")

        if data is None:
            if itertype is 'slice':
                result = N.squeeze(self[value.slice])
                #result = self[value.slice]
            elif itertype is 'parcel':
                flatten(value.where)
                self.label = value.label
                result = self.compress(value.where, axis=0)
            elif itertype == 'slice/parcel':
                result = self[value.slice].compress(value.where)
            return self.postread(result)
        else:
            if itertype is 'slice':
                self[value.slice] = data
            elif itertype in ('parcel', "slice/parcel"):
                self.put(data, N.nonzero(value.where.flatten()))

    def getvoxel(self, voxel):
        if len(voxel) != self.ndim:
            raise ValueError, 'expecting a voxel coordinate'
        return self[voxel]

    def toarray(self, clean=True, **keywords):
        """
        Return a Image instance that has an ArrayPipe as its image attribute.

        >>> from numpy import *
        >>> from BrainSTAT import *
        >>> test = Image(testfile('anat+orig.HEAD'))
        >>> _test = test.toarray()
        >>> print _test.source.data.shape
        (124, 256, 256)
        >>> test = Image(testfile('test_fmri.img'))
        >>> _test = test.toarray(slice=(2,), grid=test.grid)
        >>> print _test.shape
        (13, 128, 128)
        """
        data = self.readall()
        if clean and data.dtype.type in N.sctypes['float'] + N.sctypes['complex']:
            data = N.nan_to_num(data)

        return Image(self.postread(data), grid=self.grid, **keywords)

    def tofile(self, filename, array=True, clobber=False,
               sctype=None, **keywords):
        sctype = sctype or self._source.sctype
        outimage = Image(filename, mode='w', grid=self.grid,
                         clobber=clobber,
                         sctype=sctype,
                         **keywords)
        if array:
            tmp = self.toarray(**keywords)
            outimage._source[:] = tmp._source.data
        else:
            tmp = iter(self)
            outimage = iter(outimage)
            # make sure that "self" is driving iteration
            # over image, i.e. when self is an fMRIImage and
            # outimage is an Image
            for dataslice in tmp:
                outimage.next(data=dataslice, value=tmp.itervalue)
        if hasattr(outimage, "close"):
            outimage.close()
        return outimage

    def readall(self, clean=False):
        """
        Read an entire Image object, returning a numpy, not another instance of
        Image. By default, it does not read 4d images. Missing values are
        filled in with the value of fill (default=self.fill=0.0).
        """
        value = self._source[self.grid.allslice()]
        if clean:
            value = Image(N.nan_to_num(value, fill=self.fill))
        return value

    def check_grid(self, test):
        return self.grid == test.grid

class ImageSequenceIterator(object):
    """
    Take a sequence of images, and an optional grid (which defaults to
    imgs[0].grid) and create an iterator whose next method returns array with
    shapes (len(imgs),) + self.imgs[0].next().shape Very useful for voxel-based
    methods, i.e. regression, one-sample t.
    """
    def __init__(self, imgs, grid=None):
        self.imgs = imgs
        if grid is None: self.grid = iter(self.imgs[0].grid)
        else: self.grid = iter(grid)

    def __iter__(self):
        return self

    def next(self, value=None):
        if value is None: value = self.grid.next()
        v = [img.next(value=value) for img in self.imgs]
        return N.array(v, N.float64)

<commit_msg>add docstring<commit_after>"""
The Image class provides the interface which should be used
by users at the application level. It is build onto of a
BaseImage object (self._source) which handles the actual
representation of the data. A base image provides a grid,
a data type and the data itself, while the main Image class
builds on top of these.

A BaseImage object can be created from an ndarray (ArrayImage)
or from a file (Formats).

TODO: The Formats class does not currently subclass from BaseImage,
or even provide the correct interface, so this needs to be fixed
to fall in line with the class structure shown here.

  Application Level
----------------------
        Image
          |
          o
          |
      BaseImage
          |
          |
      ------------
      |          |
   Formats   ArrayImage
      |
   Binary
      |
  ------------------
  |        |       |
Nifti   Analyze  ECAT
"""

import types, os

from neuroimaging import traits
import numpy as N

from neuroimaging import flatten
from neuroimaging.data_io import DataSource
from neuroimaging.data_io.formats import getformats, Format
from neuroimaging.core.reference.grid import SamplingGrid

class BaseImage(object):
    """
    This class define a minimal interface which different types of images
    should implement. This interface is used by the Image class, which is
    the class which should be used by applications.
    """

    def __init__(self, data, grid, sctype):
        assert(data.shape == grid.shape)
        self.grid = grid
        self.data = data
        self.sctype = sctype

    def __getitem__(self, item):
        return self.data[item]

    def __setitem__(self, item, value):
        self[item] = value

class ArrayImage (BaseImage):
    """A simple class to mimic an image file from an array."""
    def __init__(self, data, grid=None):
        """
        Create an ArrayImage instance from an array,
        by default assumed to be 3d.

        >>> from numpy import *
        >>> from neuroimaging.core.image import Image
        >>> z = Image.ArrayImage(zeros((10,20,20)))
        >>> print z.ndim
        3
        """
        grid = grid and grid or SamplingGrid.identity(self.shape)
        sctype = data.dtype.type
        BaseImage.__init__(self, data, grid, sctype)

class Image(object):

    @staticmethod
    def fromurl(url, datasource=DataSource(), format=None, grid=None, mode="r", clobber=False,
      **keywords):
        zipexts = (".gz",".bz2")
        base, ext = os.path.splitext(url.strip())
        if ext in zipexts: url = base
        if not format: valid = getformats(url)
        else: valid = [format]
        for format in valid:
            try:
                return format(filename=url,
                               datasource=datasource, mode=mode, clobber=clobber, grid=grid, **keywords)
            except Exception, e:
                pass

        raise NotImplementedError, 'no valid reader found for URL %s' % url

    def __init__(self, image, datasource=DataSource(), grid=None, **keywords):
        '''
        Create a Image (volumetric image) object from either a file, an
        existing Image object, or an array.
        '''

        # from existing Image
        if isinstance(image, Image):
            self._source = image._source

        # from existing Format instance
        elif isinstance(image, Format):
            self._source = image

        # from array
        elif isinstance(image, N.ndarray) or isinstance(image, N.core.memmap):
            self._source = ArrayImage(image, grid=grid)

        # from filename or url
        elif type(image) == types.StringType:
            self._source = self.fromurl(image, datasource, grid=grid, **keywords)

        else:
            raise ValueError(
          "Image input must be a string, array, or another image.")
        # Find spatial grid -- this is the one that will be used generally
        self.grid = self._source.grid
        self.shape = list(self.grid.shape)
        self.ndim = len(self.shape)

        # When possible, attach memory-mapped array or array as buffer attr
        if hasattr(self._source, 'memmap'):
            self.buffer = self._source.memmap
        else:
            self.buffer = self._source.data

        self.postread = lambda x:x
        self.fill = 0.0

    def __getitem__(self, slice): return self._source[slice]
    def __setitem__(self, slice, data): self._source[slice] = data

    def __iter__(self):
        "Create an iterator over an image based on its grid's iterator."
        iter(self.grid)
        if self.grid.get_iter_param("itertype") in ["parcel", "slice/parcel"]:
            self.buffer.shape = N.product(self.buffer.shape)
        return self

    def compress(self, where, axis=0):
        if hasattr(self, 'buffer'):
            return self.buffer.compress(where, axis=axis)
        else: raise ValueError, 'no buffer: compress not supported'

    def put(self, data, indices):
        if hasattr(self, 'buffer'):
            return self.buffer.put(data, indices)
        else: raise ValueError, 'no buffer: put not supported'

    def next(self, value=None, data=None):
        """
        The value argument here is used when, for instance one wants to
        iterate over one image with a ParcelIterator and write out data
        to this image without explicitly setting this image's grid to
        the original image's grid, i.e. to just take the value the
        original image's iterator returns and use it here.
        """
        if value is None:
            self.itervalue = value = self.grid.next()
        itertype = self.grid.get_iter_param("itertype")

        if data is None:
            if itertype is 'slice':
                result = N.squeeze(self[value.slice])
                #result = self[value.slice]
            elif itertype is 'parcel':
                flatten(value.where)
                self.label = value.label
                result = self.compress(value.where, axis=0)
            elif itertype == 'slice/parcel':
                result = self[value.slice].compress(value.where)
            return self.postread(result)
        else:
            if itertype is 'slice':
                self[value.slice] = data
            elif itertype in ('parcel', "slice/parcel"):
                self.put(data, N.nonzero(value.where.flatten()))

    def getvoxel(self, voxel):
        if len(voxel) != self.ndim:
            raise ValueError, 'expecting a voxel coordinate'
        return self[voxel]

    def toarray(self, clean=True, **keywords):
        """
        Return a Image instance that has an ArrayPipe as its image attribute.

        >>> from numpy import *
        >>> from BrainSTAT import *
        >>> test = Image(testfile('anat+orig.HEAD'))
        >>> _test = test.toarray()
        >>> print _test.source.data.shape
        (124, 256, 256)
        >>> test = Image(testfile('test_fmri.img'))
        >>> _test = test.toarray(slice=(2,), grid=test.grid)
        >>> print _test.shape
        (13, 128, 128)
        """
        data = self.readall()
        if clean and data.dtype.type in N.sctypes['float'] + N.sctypes['complex']:
            data = N.nan_to_num(data)

        return Image(self.postread(data), grid=self.grid, **keywords)

    def tofile(self, filename, array=True, clobber=False,
               sctype=None, **keywords):
        sctype = sctype or self._source.sctype
        outimage = Image(filename, mode='w', grid=self.grid,
                         clobber=clobber,
                         sctype=sctype,
                         **keywords)
        if array:
            tmp = self.toarray(**keywords)
            outimage._source[:] = tmp._source.data
        else:
            tmp = iter(self)
            outimage = iter(outimage)
            # make sure that "self" is driving iteration
            # over image, i.e. when self is an fMRIImage and
            # outimage is an Image
            for dataslice in tmp:
                outimage.next(data=dataslice, value=tmp.itervalue)
        if hasattr(outimage, "close"):
            outimage.close()
        return outimage

    def readall(self, clean=False):
        """
        Read an entire Image object, returning a numpy, not another instance of
        Image. By default, it does not read 4d images. Missing values are
        filled in with the value of fill (default=self.fill=0.0).
        """
        value = self._source[self.grid.allslice()]
        if clean:
            value = Image(N.nan_to_num(value, fill=self.fill))
        return value

    def check_grid(self, test):
        return self.grid == test.grid

class ImageSequenceIterator(object):
    """
    Take a sequence of images, and an optional grid (which defaults to
    imgs[0].grid) and create an iterator whose next method returns array with
    shapes (len(imgs),) + self.imgs[0].next().shape Very useful for voxel-based
    methods, i.e. regression, one-sample t.
    """
    def __init__(self, imgs, grid=None):
        self.imgs = imgs
        if grid is None: self.grid = iter(self.imgs[0].grid)
        else: self.grid = iter(grid)

    def __iter__(self):
        return self

    def next(self, value=None):
        if value is None: value = self.grid.next()
        v = [img.next(value=value) for img in self.imgs]
        return N.array(v, N.float64)

<|endoftext|>


<commit_before>from django.conf.urls import patterns, url
from niqati import views
from niqati.models import COUPON, SHORT_LINK

urlpatterns = patterns('',
    url(r'^$', views.index, name='index'),
    url(r'^submit/$', views.redeem, name='submit'),
    url(r'^submit/claim/$', views.claim_code, name='claim_code'),
    url(r'^submit/(?P<code>[\w\d]+)/$', views.redeem, name='submit_prefilled'),
    url(r'^report/$', views.student_report, name='student_report'),
    url(r'^report/(?P<username>[\w\d]+)/$', views.student_report, name='student_report_with_username'),
    url(r'^collections/(?P<pk>\d+)/download/coupons/$', views.download_collection,
        {"download_type": COUPON}, name="download_coupons"),
    url(r'^collections/(?P<pk>\d+)/download/links/$', views.download_collection,
        {"download_type": SHORT_LINK}, name="download_links"),
    url(r'^orders/(?P<pk>\d+)/$', views.download_collection, name='view_collec'),
    url(r'^review/$', views.review_order, name='review_order'),
    url(r'^short_url/$', views.get_short_url, name='get_short_url'),
    url(r'^approve/$', views.list_pending_orders, name='list_pending_orders'),
    url(r'^generalreport/$', views.general_report, name='general_report'),
    url(r'^generalreport/(?P<city>\w+)/$', views.general_report, name='general_report_for_city'),
)
<commit_msg>Some usernames include dashes.<commit_after>from django.conf.urls import patterns, url
from niqati import views
from niqati.models import COUPON, SHORT_LINK

urlpatterns = patterns('',
    url(r'^$', views.index, name='index'),
    url(r'^submit/$', views.redeem, name='submit'),
    url(r'^submit/claim/$', views.claim_code, name='claim_code'),
    url(r'^submit/(?P<code>[\w\d]+)/$', views.redeem, name='submit_prefilled'),
    url(r'^report/$', views.student_report, name='student_report'),
    url(r'^report/(?P<username>[\w\d\-]+)/$', views.student_report, name='student_report_with_username'),
    url(r'^collections/(?P<pk>\d+)/download/coupons/$', views.download_collection,
        {"download_type": COUPON}, name="download_coupons"),
    url(r'^collections/(?P<pk>\d+)/download/links/$', views.download_collection,
        {"download_type": SHORT_LINK}, name="download_links"),
    url(r'^orders/(?P<pk>\d+)/$', views.download_collection, name='view_collec'),
    url(r'^review/$', views.review_order, name='review_order'),
    url(r'^short_url/$', views.get_short_url, name='get_short_url'),
    url(r'^approve/$', views.list_pending_orders, name='list_pending_orders'),
    url(r'^generalreport/$', views.general_report, name='general_report'),
    url(r'^generalreport/(?P<city>\w+)/$', views.general_report, name='general_report_for_city'),
)
<|endoftext|>


<commit_before>import dbconnection
import main
import sqlbuilder

__all__ = ['SelectResults']

class SelectResults(object):
    IterationClass = dbconnection.Iteration

    def __init__(self, sourceClass, clause, clauseTables=None,
                 **ops):
        self.sourceClass = sourceClass
        if clause is None or isinstance(clause, str) and clause == 'all':
            clause = sqlbuilder.SQLTrueClause
        if not isinstance(clause, sqlbuilder.SQLExpression):
            clause = sqlbuilder.SQLConstant(clause)
        self.clause = clause
        self.ops = ops
        if ops.get('orderBy', sqlbuilder.NoDefault) is sqlbuilder.NoDefault:
            ops['orderBy'] = sourceClass.sqlmeta.defaultOrder
        orderBy = ops['orderBy']
        if isinstance(orderBy, (tuple, list)):
            orderBy = map(self._mungeOrderBy, orderBy)
        else:
            orderBy = self._mungeOrderBy(orderBy)
        ops['dbOrderBy'] = orderBy
        if 'connection' in ops and ops['connection'] is None:
            del ops['connection']
        if ops.get('limit', None):
            assert not ops.get('start', None) and not ops.get('end', None), \
               "'limit' cannot be used with 'start' or 'end'"
            ops["start"] = 0
            ops["end"] = ops.pop("limit")

        tablesSet = sqlbuilder.tablesUsedSet(self.clause,
                                             self._getConnection().dbName)
        if clauseTables:
            for table in clauseTables:
                tablesSet.add(table)
        self.clauseTables = clauseTables
        # Explicitly post-adding-in sqlmeta.table,
        # sqlbuilder.Select will handle sqlrepr'ing and dupes.
        self.tables = list(tablesSet) + [sourceClass.sqlmeta.table]

    def queryForSelect(self):
        columns = [self.sourceClass.q.id] + \
            [getattr(self.sourceClass.q, x.name)
             for x in self.sourceClass.sqlmeta.columnList]
        query = sqlbuilder.Select(columns,
                                  where=self.clause,
                                  join=self.ops.get(
                                      'join', sqlbuilder.NoDefault),
                                  distinct=self.ops.get('distinct', False),
                                  lazyColumns=self.ops.get(
                                      'lazyColumns', False),
                                  start=self.ops.get('start', 0),
                                  end=self.ops.get('end', None),
                                  orderBy=self.ops.get(
                                      'dbOrderBy', sqlbuilder.NoDefault),
                                  reversed=self.ops.get('reversed', False),
                                  staticTables=self.tables,
                                  forUpdate=self.ops.get('forUpdate', False))
        return query

    def __repr__(self):
        return "<%s at %x>" % (self.__class__.__name__, id(self))

    def _getConnection(self):
        return self.ops.get('connection') or self.sourceClass._connection

    def __str__(self):
        conn = self._getConnection()
        return conn.queryForSelect(self)

    def _mungeOrderBy(self, orderBy):
        if isinstance(orderBy, basestring) and orderBy.startswith('-'):
            orderBy = orderBy[1:]
            desc = True
        else:
            desc = False
        if isinstance(orderBy, basestring):
            if orderBy in self.sourceClass.sqlmeta.columns:
                val = getattr(self.sourceClass.q,
                              self.sourceClass.sqlmeta.columns[orderBy].name)
                if desc:
                    return sqlbuilder.DESC(val)
                else:
                    return val
            else:
                orderBy = sqlbuilder.SQLConstant(orderBy)
                if desc:
                    return sqlbuilder.DESC(orderBy)
                else:
                    return orderBy
        else:
            return orderBy

    def clone(self, **newOps):
        ops = self.ops.copy()
        ops.update(newOps)
        return self.__class__(self.sourceClass, self.clause,
                              self.clauseTables, **ops)

    def orderBy(self, orderBy):
        return self.clone(orderBy=orderBy)

    def connection(self, conn):
        return self.clone(connection=conn)

    def limit(self, limit):
        return self[:limit]

    def lazyColumns(self, value):
        return self.clone(lazyColumns=value)

    def reversed(self):
        return self.clone(reversed=not self.ops.get('reversed', False))

    def distinct(self):
        return self.clone(distinct=True)

    def newClause(self, new_clause):
        return self.__class__(self.sourceClass, new_clause,
                              self.clauseTables, **self.ops)

    def filter(self, filter_clause):
        if filter_clause is None:
            # None doesn't filter anything, it's just a no-op:
            return self
        clause = self.clause
        if isinstance(clause, basestring):
            clause = sqlbuilder.SQLConstant('(%s)' % clause)
        return self.newClause(sqlbuilder.AND(clause, filter_clause))

    def __getitem__(self, value):
        if isinstance(value, slice):
            assert not value.step, "Slices do not support steps"
            if not value.start and not value.stop:
                # No need to copy, I'm immutable
                return self

            # Negative indexes aren't handled (and everything we
            # don't handle ourselves we just create a list to
            # handle)
            if (value.start and value.start < 0) \
               or (value.stop and value.stop < 0):
                if value.start:
                    if value.stop:
                        return list(self)[value.start:value.stop]
                    return list(self)[value.start:]
                return list(self)[:value.stop]

            if value.start:
                assert value.start >= 0
                start = self.ops.get('start', 0) + value.start
                if value.stop is not None:
                    assert value.stop >= 0
                    if value.stop < value.start:
                        # an empty result:
                        end = start
                    else:
                        end = value.stop + self.ops.get('start', 0)
                        if self.ops.get('end', None) is not None and \
                                self.ops['end'] < end:
                            # truncated by previous slice:
                            end = self.ops['end']
                else:
                    end = self.ops.get('end', None)
            else:
                start = self.ops.get('start', 0)
                end = value.stop + start
                if self.ops.get('end', None) is not None \
                   and self.ops['end'] < end:
                    end = self.ops['end']
            return self.clone(start=start, end=end)
        else:
            if value < 0:
                return list(iter(self))[value]
            else:
                start = self.ops.get('start', 0) + value
                return list(self.clone(start=start, end=start+1))[0]

    def __iter__(self):
        # @@: This could be optimized, using a simpler algorithm
        # since we don't have to worry about garbage collection,
        # etc., like we do with .lazyIter()
        return iter(list(self.lazyIter()))

    def lazyIter(self):
        """
        Returns an iterator that will lazily pull rows out of the
        database and return SQLObject instances
        """
        conn = self._getConnection()
        return conn.iterSelect(self)

    def accumulate(self, *expressions):
        """ Use accumulate expression(s) to select result
            using another SQL select through current
            connection.
            Return the accumulate result
        """
        conn = self._getConnection()
        exprs = []
        for expr in expressions:
            if not isinstance(expr, sqlbuilder.SQLExpression):
                expr = sqlbuilder.SQLConstant(expr)
            exprs.append(expr)
        return conn.accumulateSelect(self, *exprs)

    def count(self):
        """ Counting elements of current select results """
        assert not self.ops.get('start') and not self.ops.get('end'), \
            "start/end/limit have no meaning with 'count'"
        assert not (self.ops.get('distinct') and (self.ops.get('start')
                                                  or self.ops.get('end'))), \
            "distinct-counting of sliced objects is not supported"
        if self.ops.get('distinct'):
            # Column must be specified, so we are using unique ID column.
            # COUNT(DISTINCT column) is supported by MySQL and PostgreSQL,
            # but not by SQLite. Perhaps more portable would be subquery:
            #  SELECT COUNT(*) FROM (SELECT DISTINCT id FROM table)
            count = self.accumulate(
                'COUNT(DISTINCT %s)' % self._getConnection().sqlrepr(
                    self.sourceClass.q.id))
        else:
            count = self.accumulate('COUNT(*)')
        if self.ops.get('start'):
            count -= self.ops['start']
        if self.ops.get('end'):
            count = min(self.ops['end'] - self.ops.get('start', 0), count)
        return count

    def accumulateMany(self, *attributes):
        """ Making the expressions for count/sum/min/max/avg
            of a given select result attributes.
            `attributes` must be a list/tuple of pairs (func_name, attribute);
            `attribute` can be a column name (like 'a_column')
            or a dot-q attribute (like Table.q.aColumn)
        """
        expressions = []
        conn = self._getConnection()
        if self.ops.get('distinct'):
            distinct = 'DISTINCT '
        else:
            distinct = ''
        for func_name, attribute in attributes:
            if not isinstance(attribute, str):
                attribute = conn.sqlrepr(attribute)
            expression = '%s(%s%s)' % (func_name, distinct, attribute)
            expressions.append(expression)
        return self.accumulate(*expressions)

    def accumulateOne(self, func_name, attribute):
        """ Making the sum/min/max/avg of a given select result attribute.
            `attribute` can be a column name (like 'a_column')
            or a dot-q attribute (like Table.q.aColumn)
        """
        return self.accumulateMany((func_name, attribute))

    def sum(self, attribute):
        return self.accumulateOne("SUM", attribute)

    def min(self, attribute):
        return self.accumulateOne("MIN", attribute)

    def avg(self, attribute):
        return self.accumulateOne("AVG", attribute)

    def max(self, attribute):
        return self.accumulateOne("MAX", attribute)

    def getOne(self, default=sqlbuilder.NoDefault):
        """
        If a query is expected to only return a single value,
        using ``.getOne()`` will return just that value.

        If not results are found, ``SQLObjectNotFound`` will be
        raised, unless you pass in a default value (like
        ``.getOne(None)``).

        If more than one result is returned,
        ``SQLObjectIntegrityError`` will be raised.
        """
        results = list(self)
        if not results:
            if default is sqlbuilder.NoDefault:
                raise main.SQLObjectNotFound(
                    "No results matched the query for %s"
                    % self.sourceClass.__name__)
            return default
        if len(results) > 1:
            raise main.SQLObjectIntegrityError(
                "More than one result returned from query: %s"
                % results)
        return results[0]

    def throughTo(self):
        class _throughTo_getter(object):
            def __init__(self, inst):
                self.sresult = inst

            def __getattr__(self, attr):
                return self.sresult._throughTo(attr)
        return _throughTo_getter(self)
    throughTo = property(throughTo)

    def _throughTo(self, attr):
        otherClass = None
        orderBy = sqlbuilder.NoDefault

        ref = self.sourceClass.sqlmeta.columns.get(
            attr.endswith('ID') and attr or attr+'ID', None)
        if ref and ref.foreignKey:
            otherClass, clause = self._throughToFK(ref)
        else:
            join = [x for x in self.sourceClass.sqlmeta.joins
                    if x.joinMethodName == attr]
            if join:
                join = join[0]
                orderBy = join.orderBy
                if hasattr(join, 'otherColumn'):
                    otherClass, clause = self._throughToRelatedJoin(join)
                else:
                    otherClass, clause = self._throughToMultipleJoin(join)

        if not otherClass:
            raise AttributeError(
                "throughTo argument (got %s) should be "
                "name of foreignKey or SQL*Join in %s" % (attr,
                                                          self.sourceClass))

        return otherClass.select(clause,
                                 orderBy=orderBy,
                                 connection=self._getConnection())

    def _throughToFK(self, col):
        otherClass = getattr(self.sourceClass, "_SO_class_"+col.foreignKey)
        colName = col.name
        query = self.queryForSelect().newItems([
            sqlbuilder.ColumnAS(getattr(self.sourceClass.q, colName), colName)
            ]).orderBy(None).distinct()
        query = sqlbuilder.Alias(query,
                                 "%s_%s" % (self.sourceClass.__name__,
                                            col.name))
        return otherClass, otherClass.q.id == getattr(query.q, colName)

    def _throughToMultipleJoin(self, join):
        otherClass = join.otherClass
        colName = join.soClass.sqlmeta.style.\
            dbColumnToPythonAttr(join.joinColumn)
        query = self.queryForSelect().newItems(
            [sqlbuilder.ColumnAS(self.sourceClass.q.id, 'id')]).\
            orderBy(None).distinct()
        query = sqlbuilder.Alias(query,
                                 "%s_%s" % (self.sourceClass.__name__,
                                            join.joinMethodName))
        joinColumn = getattr(otherClass.q, colName)
        return otherClass, joinColumn == query.q.id

    def _throughToRelatedJoin(self, join):
        otherClass = join.otherClass
        intTable = sqlbuilder.Table(join.intermediateTable)
        colName = join.joinColumn
        query = self.queryForSelect().newItems(
            [sqlbuilder.ColumnAS(self.sourceClass.q.id, 'id')]).\
            orderBy(None).distinct()
        query = sqlbuilder.Alias(query,
                                 "%s_%s" % (self.sourceClass.__name__,
                                            join.joinMethodName))
        clause = sqlbuilder.AND(
            otherClass.q.id == getattr(intTable, join.otherColumn),
            getattr(intTable, colName) == query.q.id)
        return otherClass, clause
<commit_msg>Change to relative imports<commit_after>from . import dbconnection
import main
from . import sqlbuilder

__all__ = ['SelectResults']

class SelectResults(object):
    IterationClass = dbconnection.Iteration

    def __init__(self, sourceClass, clause, clauseTables=None,
                 **ops):
        self.sourceClass = sourceClass
        if clause is None or isinstance(clause, str) and clause == 'all':
            clause = sqlbuilder.SQLTrueClause
        if not isinstance(clause, sqlbuilder.SQLExpression):
            clause = sqlbuilder.SQLConstant(clause)
        self.clause = clause
        self.ops = ops
        if ops.get('orderBy', sqlbuilder.NoDefault) is sqlbuilder.NoDefault:
            ops['orderBy'] = sourceClass.sqlmeta.defaultOrder
        orderBy = ops['orderBy']
        if isinstance(orderBy, (tuple, list)):
            orderBy = map(self._mungeOrderBy, orderBy)
        else:
            orderBy = self._mungeOrderBy(orderBy)
        ops['dbOrderBy'] = orderBy
        if 'connection' in ops and ops['connection'] is None:
            del ops['connection']
        if ops.get('limit', None):
            assert not ops.get('start', None) and not ops.get('end', None), \
               "'limit' cannot be used with 'start' or 'end'"
            ops["start"] = 0
            ops["end"] = ops.pop("limit")

        tablesSet = sqlbuilder.tablesUsedSet(self.clause,
                                             self._getConnection().dbName)
        if clauseTables:
            for table in clauseTables:
                tablesSet.add(table)
        self.clauseTables = clauseTables
        # Explicitly post-adding-in sqlmeta.table,
        # sqlbuilder.Select will handle sqlrepr'ing and dupes.
        self.tables = list(tablesSet) + [sourceClass.sqlmeta.table]

    def queryForSelect(self):
        columns = [self.sourceClass.q.id] + \
            [getattr(self.sourceClass.q, x.name)
             for x in self.sourceClass.sqlmeta.columnList]
        query = sqlbuilder.Select(columns,
                                  where=self.clause,
                                  join=self.ops.get(
                                      'join', sqlbuilder.NoDefault),
                                  distinct=self.ops.get('distinct', False),
                                  lazyColumns=self.ops.get(
                                      'lazyColumns', False),
                                  start=self.ops.get('start', 0),
                                  end=self.ops.get('end', None),
                                  orderBy=self.ops.get(
                                      'dbOrderBy', sqlbuilder.NoDefault),
                                  reversed=self.ops.get('reversed', False),
                                  staticTables=self.tables,
                                  forUpdate=self.ops.get('forUpdate', False))
        return query

    def __repr__(self):
        return "<%s at %x>" % (self.__class__.__name__, id(self))

    def _getConnection(self):
        return self.ops.get('connection') or self.sourceClass._connection

    def __str__(self):
        conn = self._getConnection()
        return conn.queryForSelect(self)

    def _mungeOrderBy(self, orderBy):
        if isinstance(orderBy, basestring) and orderBy.startswith('-'):
            orderBy = orderBy[1:]
            desc = True
        else:
            desc = False
        if isinstance(orderBy, basestring):
            if orderBy in self.sourceClass.sqlmeta.columns:
                val = getattr(self.sourceClass.q,
                              self.sourceClass.sqlmeta.columns[orderBy].name)
                if desc:
                    return sqlbuilder.DESC(val)
                else:
                    return val
            else:
                orderBy = sqlbuilder.SQLConstant(orderBy)
                if desc:
                    return sqlbuilder.DESC(orderBy)
                else:
                    return orderBy
        else:
            return orderBy

    def clone(self, **newOps):
        ops = self.ops.copy()
        ops.update(newOps)
        return self.__class__(self.sourceClass, self.clause,
                              self.clauseTables, **ops)

    def orderBy(self, orderBy):
        return self.clone(orderBy=orderBy)

    def connection(self, conn):
        return self.clone(connection=conn)

    def limit(self, limit):
        return self[:limit]

    def lazyColumns(self, value):
        return self.clone(lazyColumns=value)

    def reversed(self):
        return self.clone(reversed=not self.ops.get('reversed', False))

    def distinct(self):
        return self.clone(distinct=True)

    def newClause(self, new_clause):
        return self.__class__(self.sourceClass, new_clause,
                              self.clauseTables, **self.ops)

    def filter(self, filter_clause):
        if filter_clause is None:
            # None doesn't filter anything, it's just a no-op:
            return self
        clause = self.clause
        if isinstance(clause, basestring):
            clause = sqlbuilder.SQLConstant('(%s)' % clause)
        return self.newClause(sqlbuilder.AND(clause, filter_clause))

    def __getitem__(self, value):
        if isinstance(value, slice):
            assert not value.step, "Slices do not support steps"
            if not value.start and not value.stop:
                # No need to copy, I'm immutable
                return self

            # Negative indexes aren't handled (and everything we
            # don't handle ourselves we just create a list to
            # handle)
            if (value.start and value.start < 0) \
               or (value.stop and value.stop < 0):
                if value.start:
                    if value.stop:
                        return list(self)[value.start:value.stop]
                    return list(self)[value.start:]
                return list(self)[:value.stop]

            if value.start:
                assert value.start >= 0
                start = self.ops.get('start', 0) + value.start
                if value.stop is not None:
                    assert value.stop >= 0
                    if value.stop < value.start:
                        # an empty result:
                        end = start
                    else:
                        end = value.stop + self.ops.get('start', 0)
                        if self.ops.get('end', None) is not None and \
                                self.ops['end'] < end:
                            # truncated by previous slice:
                            end = self.ops['end']
                else:
                    end = self.ops.get('end', None)
            else:
                start = self.ops.get('start', 0)
                end = value.stop + start
                if self.ops.get('end', None) is not None \
                   and self.ops['end'] < end:
                    end = self.ops['end']
            return self.clone(start=start, end=end)
        else:
            if value < 0:
                return list(iter(self))[value]
            else:
                start = self.ops.get('start', 0) + value
                return list(self.clone(start=start, end=start+1))[0]

    def __iter__(self):
        # @@: This could be optimized, using a simpler algorithm
        # since we don't have to worry about garbage collection,
        # etc., like we do with .lazyIter()
        return iter(list(self.lazyIter()))

    def lazyIter(self):
        """
        Returns an iterator that will lazily pull rows out of the
        database and return SQLObject instances
        """
        conn = self._getConnection()
        return conn.iterSelect(self)

    def accumulate(self, *expressions):
        """ Use accumulate expression(s) to select result
            using another SQL select through current
            connection.
            Return the accumulate result
        """
        conn = self._getConnection()
        exprs = []
        for expr in expressions:
            if not isinstance(expr, sqlbuilder.SQLExpression):
                expr = sqlbuilder.SQLConstant(expr)
            exprs.append(expr)
        return conn.accumulateSelect(self, *exprs)

    def count(self):
        """ Counting elements of current select results """
        assert not self.ops.get('start') and not self.ops.get('end'), \
            "start/end/limit have no meaning with 'count'"
        assert not (self.ops.get('distinct') and (self.ops.get('start')
                                                  or self.ops.get('end'))), \
            "distinct-counting of sliced objects is not supported"
        if self.ops.get('distinct'):
            # Column must be specified, so we are using unique ID column.
            # COUNT(DISTINCT column) is supported by MySQL and PostgreSQL,
            # but not by SQLite. Perhaps more portable would be subquery:
            #  SELECT COUNT(*) FROM (SELECT DISTINCT id FROM table)
            count = self.accumulate(
                'COUNT(DISTINCT %s)' % self._getConnection().sqlrepr(
                    self.sourceClass.q.id))
        else:
            count = self.accumulate('COUNT(*)')
        if self.ops.get('start'):
            count -= self.ops['start']
        if self.ops.get('end'):
            count = min(self.ops['end'] - self.ops.get('start', 0), count)
        return count

    def accumulateMany(self, *attributes):
        """ Making the expressions for count/sum/min/max/avg
            of a given select result attributes.
            `attributes` must be a list/tuple of pairs (func_name, attribute);
            `attribute` can be a column name (like 'a_column')
            or a dot-q attribute (like Table.q.aColumn)
        """
        expressions = []
        conn = self._getConnection()
        if self.ops.get('distinct'):
            distinct = 'DISTINCT '
        else:
            distinct = ''
        for func_name, attribute in attributes:
            if not isinstance(attribute, str):
                attribute = conn.sqlrepr(attribute)
            expression = '%s(%s%s)' % (func_name, distinct, attribute)
            expressions.append(expression)
        return self.accumulate(*expressions)

    def accumulateOne(self, func_name, attribute):
        """ Making the sum/min/max/avg of a given select result attribute.
            `attribute` can be a column name (like 'a_column')
            or a dot-q attribute (like Table.q.aColumn)
        """
        return self.accumulateMany((func_name, attribute))

    def sum(self, attribute):
        return self.accumulateOne("SUM", attribute)

    def min(self, attribute):
        return self.accumulateOne("MIN", attribute)

    def avg(self, attribute):
        return self.accumulateOne("AVG", attribute)

    def max(self, attribute):
        return self.accumulateOne("MAX", attribute)

    def getOne(self, default=sqlbuilder.NoDefault):
        """
        If a query is expected to only return a single value,
        using ``.getOne()`` will return just that value.

        If not results are found, ``SQLObjectNotFound`` will be
        raised, unless you pass in a default value (like
        ``.getOne(None)``).

        If more than one result is returned,
        ``SQLObjectIntegrityError`` will be raised.
        """
        results = list(self)
        if not results:
            if default is sqlbuilder.NoDefault:
                raise main.SQLObjectNotFound(
                    "No results matched the query for %s"
                    % self.sourceClass.__name__)
            return default
        if len(results) > 1:
            raise main.SQLObjectIntegrityError(
                "More than one result returned from query: %s"
                % results)
        return results[0]

    def throughTo(self):
        class _throughTo_getter(object):
            def __init__(self, inst):
                self.sresult = inst

            def __getattr__(self, attr):
                return self.sresult._throughTo(attr)
        return _throughTo_getter(self)
    throughTo = property(throughTo)

    def _throughTo(self, attr):
        otherClass = None
        orderBy = sqlbuilder.NoDefault

        ref = self.sourceClass.sqlmeta.columns.get(
            attr.endswith('ID') and attr or attr+'ID', None)
        if ref and ref.foreignKey:
            otherClass, clause = self._throughToFK(ref)
        else:
            join = [x for x in self.sourceClass.sqlmeta.joins
                    if x.joinMethodName == attr]
            if join:
                join = join[0]
                orderBy = join.orderBy
                if hasattr(join, 'otherColumn'):
                    otherClass, clause = self._throughToRelatedJoin(join)
                else:
                    otherClass, clause = self._throughToMultipleJoin(join)

        if not otherClass:
            raise AttributeError(
                "throughTo argument (got %s) should be "
                "name of foreignKey or SQL*Join in %s" % (attr,
                                                          self.sourceClass))

        return otherClass.select(clause,
                                 orderBy=orderBy,
                                 connection=self._getConnection())

    def _throughToFK(self, col):
        otherClass = getattr(self.sourceClass, "_SO_class_"+col.foreignKey)
        colName = col.name
        query = self.queryForSelect().newItems([
            sqlbuilder.ColumnAS(getattr(self.sourceClass.q, colName), colName)
            ]).orderBy(None).distinct()
        query = sqlbuilder.Alias(query,
                                 "%s_%s" % (self.sourceClass.__name__,
                                            col.name))
        return otherClass, otherClass.q.id == getattr(query.q, colName)

    def _throughToMultipleJoin(self, join):
        otherClass = join.otherClass
        colName = join.soClass.sqlmeta.style.\
            dbColumnToPythonAttr(join.joinColumn)
        query = self.queryForSelect().newItems(
            [sqlbuilder.ColumnAS(self.sourceClass.q.id, 'id')]).\
            orderBy(None).distinct()
        query = sqlbuilder.Alias(query,
                                 "%s_%s" % (self.sourceClass.__name__,
                                            join.joinMethodName))
        joinColumn = getattr(otherClass.q, colName)
        return otherClass, joinColumn == query.q.id

    def _throughToRelatedJoin(self, join):
        otherClass = join.otherClass
        intTable = sqlbuilder.Table(join.intermediateTable)
        colName = join.joinColumn
        query = self.queryForSelect().newItems(
            [sqlbuilder.ColumnAS(self.sourceClass.q.id, 'id')]).\
            orderBy(None).distinct()
        query = sqlbuilder.Alias(query,
                                 "%s_%s" % (self.sourceClass.__name__,
                                            join.joinMethodName))
        clause = sqlbuilder.AND(
            otherClass.q.id == getattr(intTable, join.otherColumn),
            getattr(intTable, colName) == query.q.id)
        return otherClass, clause
<|endoftext|>


<commit_before>from rest_framework import status
from rest_framework.exceptions import APIException

class RequiredParameterMissingException(APIException):
    status_code = status.HTTP_400_BAD_REQUEST
    pass

class DateParseException(APIException):
    status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
    pass

class DateTimeParseException(APIException):
    status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
    pass

class NumberParseException(APIException):
    status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
    pass

class ValidationFailedException(APIException):
    status_code = status.HTTP_403_FORBIDDEN
    pass

class ChartNotFoundException(APIException):
    status_code = status.HTTP_400_BAD_REQUEST
    pass

class MalformedChartDataException(APIException):
    status_code = status.HTTP_400_BAD_REQUEST
    pass

class TransformationException(APIException):
    status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
    pass

class DatabaseWriteException(APIException):
    status_code = status.HTTP_400_BAD_REQUEST
    pass

class InvalidDateRangeException(APIException):
    status_code = status.HTTP_400_BAD_REQUEST
    pass

class DuplicateUrlException(APIException):
    status_code = status.HTTP_400_BAD_REQUEST
    pass<commit_msg>HIR-494 Added a new exception for emails<commit_after>from rest_framework import status
from rest_framework.exceptions import APIException

class RequiredParameterMissingException(APIException):
    status_code = status.HTTP_400_BAD_REQUEST
    pass

class DateParseException(APIException):
    status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
    pass

class DateTimeParseException(APIException):
    status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
    pass

class NumberParseException(APIException):
    status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
    pass

class ValidationFailedException(APIException):
    status_code = status.HTTP_403_FORBIDDEN
    pass

class ChartNotFoundException(APIException):
    status_code = status.HTTP_400_BAD_REQUEST
    pass

class MalformedChartDataException(APIException):
    status_code = status.HTTP_400_BAD_REQUEST
    pass

class TransformationException(APIException):
    status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
    pass

class DatabaseWriteException(APIException):
    status_code = status.HTTP_400_BAD_REQUEST
    pass

class InvalidDateRangeException(APIException):
    status_code = status.HTTP_400_BAD_REQUEST
    pass

class DuplicateUrlException(APIException):
    status_code = status.HTTP_400_BAD_REQUEST
    pass

class EmailException(APIException):
    status_code = status.HTTP_400_BAD_REQUEST
    pass<|endoftext|>


<commit_before># SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2015, ARM Limited and contributors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import re
import os

from android import Screen, Workload, System
from time import sleep

import logging

class YouTube(Workload):
    """
    Android YouTube workload
    """

    # Package required by this workload
    package = 'com.google.android.youtube'
    action = 'android.intent.action.VIEW'

    # Setup logger
    logger = logging.getLogger('YouTube')
    logger.setLevel(logging.INFO)

    def __init__(self, test_env):
        super(YouTube, self).__init__(test_env)
        self.logger.debug('%14s - Workload created', 'YouTube')

    def run(self, exp_dir, video_url, video_duration_s, collect=''):

        # Initialize energy meter results
        nrg_report = None

        # Unlock device screen (assume no password required)
        System.menu(self.target)
        # Press Back button to be sure we run the video from the start
        System.back(self.target)

        # Use the monkey tool to start YouTube without playing any video.
        # This allows to subsequently set the screen orientation to LANDSCAPE
        # and to reset the frame statistics.
        System.monkey(self.target, self.package)

        # Force screen in LANDSCAPE mode
        Screen.set_orientation(self.target, portrait=False)

        System.gfxinfo_reset(self.target, self.package)
        sleep(1)

        # Start YouTube video on the target device
        System.start_action(self.target, self.action, video_url)
        # Allow the activity to start
        sleep(1)

        # Start energy collection
        if 'energy' in collect and self.te.emeter:
            self.te.emeter.reset()

        # Wait until the end of the video
        self.logger.info("Play video for %d [s]", video_duration_s)
        sleep(video_duration_s)

        # Stop energy collection
        if 'energy' in collect and self.te.emeter:
            nrg_report = self.te.emeter.report(exp_dir)

        # Get frame stats
        db_file = os.path.join(exp_dir, "framestats.txt")
        System.gfxinfo_get(self.target, self.package, db_file)

        System.force_stop(self.target, self.package, clear=True)

        System.home(self.target)

        # Switch back to screen auto rotation
        Screen.set_orientation(self.target, auto=True)

        return db_file, nrg_report

# vim :set tabstop=4 shiftwidth=4 expandtab
<commit_msg>android/workloads: do not clean the YouTube data folder<commit_after># SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2015, ARM Limited and contributors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import re
import os

from android import Screen, Workload, System
from time import sleep

import logging

class YouTube(Workload):
    """
    Android YouTube workload
    """

    # Package required by this workload
    package = 'com.google.android.youtube'
    action = 'android.intent.action.VIEW'

    # Setup logger
    logger = logging.getLogger('YouTube')
    logger.setLevel(logging.INFO)

    def __init__(self, test_env):
        super(YouTube, self).__init__(test_env)
        self.logger.debug('%14s - Workload created', 'YouTube')

    def run(self, exp_dir, video_url, video_duration_s, collect=''):

        # Initialize energy meter results
        nrg_report = None

        # Unlock device screen (assume no password required)
        System.menu(self.target)
        # Press Back button to be sure we run the video from the start
        System.back(self.target)

        # Use the monkey tool to start YouTube without playing any video.
        # This allows to subsequently set the screen orientation to LANDSCAPE
        # and to reset the frame statistics.
        System.monkey(self.target, self.package)

        # Force screen in LANDSCAPE mode
        Screen.set_orientation(self.target, portrait=False)

        System.gfxinfo_reset(self.target, self.package)
        sleep(1)

        # Start YouTube video on the target device
        System.start_action(self.target, self.action, video_url)
        # Allow the activity to start
        sleep(1)

        # Start energy collection
        if 'energy' in collect and self.te.emeter:
            self.te.emeter.reset()

        # Wait until the end of the video
        self.logger.info("Play video for %d [s]", video_duration_s)
        sleep(video_duration_s)

        # Stop energy collection
        if 'energy' in collect and self.te.emeter:
            nrg_report = self.te.emeter.report(exp_dir)

        # Get frame stats
        db_file = os.path.join(exp_dir, "framestats.txt")
        System.gfxinfo_get(self.target, self.package, db_file)

        # Close the app without clearing the local data to
        # avoid the dialog to select the account at next start
        System.force_stop(self.target, self.package, clear=False)

        # Go back to home screen
        System.home(self.target)

        # Switch back to screen auto rotation
        Screen.set_orientation(self.target, auto=True)

        return db_file, nrg_report

# vim :set tabstop=4 shiftwidth=4 expandtab
<|endoftext|>


<commit_before># -*- coding: UTF-8 -*-
## Copyright 2012 Luc Saffre
## This file is part of the Lino project.
## Lino is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
## Lino is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
## You should have received a copy of the GNU General Public License
## along with Lino; if not, see <http://www.gnu.org/licenses/>.

import os
import sys
import cgi
import datetime

from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.db import IntegrityError
from django.utils.encoding import force_unicode

from lino import tools
from lino import dd
#~ from lino.utils.babel import default_language
#~ from lino import reports
#~ from lino import layouts
from lino.core.perms import UserProfiles
from lino.utils.restify import restify
#~ from lino.utils import printable
from lino.utils.choosers import chooser
from lino.utils import babel
from lino import mixins
from django.conf import settings
#~ from lino import choices_method, simple_choices_method
#~ from lino.modlib.contacts import models as contacts
from lino.modlib.users import models as users
from lino.modlib.cal.utils import DurationUnits

#~ from lino_welfare.models import Person
#~ from lino_welfare.modlib.pcsw import models as welfare
from lino_welfare.modlib.pcsw import models as pcsw

def amonthago():
    return DurationUnits.months.add_duration(datetime.date.today(),-1)

class Broker(dd.Model):
    """
    A Broker (Vermittler) is an external institution
    who suggests newcomers.
    """
    class Meta:
        verbose_name = _("Broker")
        verbose_name_plural = _("Brokers")

    name = models.CharField(max_length=200)

    def __unicode__(self):
        return self.name

class Brokers(dd.Table):
    """
    List of Brokers on this site.
    """
    required=dict(user_groups=['newcomers'],user_level='manager')
    #~ required_user_level = UserLevels.manager
    model = Broker
    column_names = 'name *'
    order_by = ["name"]

class Faculty(babel.BabelNamed):
    """
    A Faculty (Fachbereich) is a conceptual (not organizational)
    department of this PCSW.
    Each Newcomer will be assigned to one and only one Faculty,
    based on his/her needs.

    """
    class Meta:
        verbose_name = _("Faculty")
        verbose_name_plural = _("Faculties")
    #~ body = babel.BabelTextField(_("Body"),blank=True,format='html')

class Faculties(dd.Table):
    required=dict(user_groups=['newcomers'],user_level='manager')
    #~ required_user_groups = ['newcomers']
    #~ required_user_level = UserLevels.manager
    model = Faculty
    column_names = 'name *'
    order_by = ["name"]
    detail_template = """
    id name
    CompetencesByFaculty
    NewcomersByFaculty
    """

class Competence(mixins.AutoUser,mixins.Sequenced):
    """
    Deserves more documentation.
    """
    class Meta:
        #~ abstract = True
        verbose_name = _("Competence")
        verbose_name_plural = _("Competences")

    faculty = models.ForeignKey(Faculty)

    def __unicode__(self):
        return u'%s #%s' % (self._meta.verbose_name,self.pk)

class Competences(dd.Table):
    required = dict(user_groups=['newcomers'],user_level='manager')
    #~ required_user_groups = ['newcomers']
    #~ required_user_level = UserLevels.manager
    model = Competence
    column_names = 'id *'
    order_by = ["id"]

class CompetencesByUser(Competences):
    #~ required = dict(user_groups=['newcomers'])
    required = dict()
    #~ required_user_level = None
    master_key = 'user'
    column_names = 'seqno faculty *'
    order_by = ["seqno"]

class CompetencesByFaculty(Competences):
    master_key = 'faculty'
    column_names = 'user *'
    order_by = ["user"]

class MyCompetences(mixins.ByUser,CompetencesByUser):
    pass

class Newcomers(pcsw.Clients):
    """
    Clients who have the "Newcomer" checkbox on.
    """
    required = dict(user_groups=['newcomers'])
    #~ required_user_groups = ['newcomers']

    #~ filter = dict(newcomer=True)
    #~ known_values = dict(newcomer=True)
    known_values = dict(client_state=pcsw.ClientStates.newcomer)
    #~ use_as_default_table = False
    column_names = "name_column broker faculty address_column *"

    #~ @classmethod
    #~ def get_actor_label(self):
        #~ return _("Newcomers")
    label = _("Newcomers")

class NewcomersByFaculty(Newcomers):
    master_key = 'faculty'
    column_names = "name_column broker address_column *"

class NewClients(pcsw.Clients):
    required=dict(user_groups=['newcomers'])
    #~ required_user_groups = ['newcomers']
    label = _("New Clients")
    use_as_default_table = False

    parameters = dict(
        coached_by = models.ForeignKey(users.User,verbose_name=_("Coached by"),blank=True),
        since = models.DateField(_("Since"),blank=True,default=amonthago),
        **pcsw.Clients.parameters
    )
    params_template = "coached_by since " + pcsw.Clients.params_template

    column_names = "name_column:20 coached_from coached_until national_id:10 gsm:10 address_column age:10 email phone:10 id bank_account1 aid_type coach1 language:10 *"

    @classmethod
    def get_request_queryset(self,ar):
        """
        We only want the Clients who actually have at least one client.
        We store the corresponding request in the user object
        under the name `my_persons`.
        """
        #~ qs = Person.objects.all()
        qs = super(NewClients,self).get_request_queryset(ar)

        if ar.param_values.coached_by:
            qs = pcsw.only_coached_by(qs,ar.param_values.coached_by)

        if ar.param_values.since:
            qs = pcsw.only_coached_since(qs,ar.param_values.since)
        return qs

#~ class UsersByNewcomer(dd.VirtualTable):
#~ class UsersByNewcomer(dd.Table):
class UsersByNewcomer(users.Users):
    """
    A list of the Users that are susceptible to become responsible for a Newcomer.
    """
    use_as_default_table = False

    required = dict(user_groups=['newcomers'])
    #~ required_user_groups = ['newcomers']
    #~ model = users.User
    editable = False # even root should not edit here
    #~ filter = models.Q(profile__in=[p for p in UserProfiles.items() if p.integ_level])
    label = _("Users by Newcomer")
    column_names = 'name_column primary_clients active_clients new_clients newcomer_quota newcomer_score'
    parameters = dict(
        for_client = models.ForeignKey('contacts.Person',
            verbose_name=_("Show suggested agents for"),
            blank=True),
        since = models.DateField(_("Count Newcomers since"),
            blank=True,default=amonthago),
    )
    params_template = "for_client since"

    @chooser()
    def for_client_choices(cls):
        return Newcomers.request().data_iterator

    @classmethod
    def get_request_queryset(self,ar):
        profiles = [p for p in UserProfiles.items() if p.integ_level]
        return super(UsersByNewcomer,self,ar).filter(models.Q(profile__in=profiles))

    #~ @classmethod
    #~ def get_permission(self,action,user):
        #~ return isinstance(p.actors.ReadPermission)
        #~ return True

    @classmethod
    def get_data_rows(self,ar):
        """
        We only want the users who actually have at least one client.
        We store the corresponding request in the user object
        under the name `my_persons`.
        """
        qs = super(UsersByNewcomer,self).get_request_queryset(ar)

        Q = models.Q
        #~ for user in users.User.objects.filter(
        for user in qs:
            if ar.param_values.for_client:
                r = Competence.objects.filter(user=user,faculty=ar.param_values.for_client.faculty)
                if r.count() == 0:
                    continue
            user.new_clients = NewClients.request(
              ar.ui,param_values=dict(
                coached_by=user,
                since=ar.param_values.since))
            yield user

    #~ @dd.virtualfield('contacts.Person.coach1')
    #~ def user(self,obj,ar):
        #~ return obj

    @dd.requestfield(_("Primary clients"))
    def primary_clients(self,obj,ar):
        return pcsw.ClientsByCoach1.request(ar.ui,master_instance=obj)

    @dd.requestfield(_("Active clients"))
    def active_clients(self,obj,ar):
        return pcsw.MyActiveClients.request(ar.ui,subst_user=obj)

    @dd.requestfield(_("New Clients"))
    def new_clients(self,obj,ar):
        return obj.new_clients

    @dd.virtualfield(models.IntegerField(_("Score")))
    def newcomer_score(self,obj,ar):
        if obj.new_clients.get_total_count():
            return 100 * obj.newcomer_quota / obj.new_clients.get_total_count()
        else:
            return None

MODULE_LABEL = _("Newcomers")

#~ settings.LINO.add_user_field('newcomers_level',UserLevels.field(MODULE_LABEL))
#~ settings.LINO.add_user_group('newcomers',MODULE_LABEL)
settings.LINO.add_user_field('newcomer_quota',models.IntegerField(
          _("Newcomers Quota"),
          default=0,
          help_text="""Relative number expressing
          how many Newcomer requests this User is able to treat."""
        ))

dd.inject_field(pcsw.Client,
    'broker',
    models.ForeignKey(Broker,
        blank=True,null=True),
    """The Broker who sent this Newcomer.
    """)
dd.inject_field(pcsw.Client,
    'faculty',
    models.ForeignKey(Faculty,
        blank=True,null=True),
    """The Faculty this client has been attributed to.
    """)

def site_setup(site):
    site.modules.users.Users.add_detail_tab('newcomers.CompetencesByUser')

def setup_main_menu(site,ui,user,m):
    #~ if user.profile.newcomers_level < UserLevels.user:
        #~ return
    m  = m.add_menu("newcomers",MODULE_LABEL)
    m.add_action(Newcomers)
    m.add_action(UsersByNewcomer)
    m.add_action(NewClients)

def setup_master_menu(site,ui,user,m): pass

def setup_my_menu(site,ui,user,m):
    pass

def setup_config_menu(site,ui,user,m):
    #~ if user.profile.newcomers_level < UserLevels.manager:
        #~ return
    m  = m.add_menu("newcomers",MODULE_LABEL)
    m.add_action(Brokers)
    m.add_action(Faculties)

def setup_explorer_menu(site,ui,user,m):
    #~ if user.profile.newcomers_level < UserLevels.manager:
        #~ return
    m.add_action(Competences)

dd.add_user_group('newcomers',MODULE_LABEL)
  <commit_msg>http://code.google.com/p/lino-welfare/source/browse/docs/en/blog/2012/0913.rst<commit_after># -*- coding: UTF-8 -*-
## Copyright 2012 Luc Saffre
## This file is part of the Lino project.
## Lino is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
## Lino is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
## You should have received a copy of the GNU General Public License
## along with Lino; if not, see <http://www.gnu.org/licenses/>.

import os
import sys
import cgi
import datetime

from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.db import IntegrityError
from django.utils.encoding import force_unicode

from lino import tools
from lino import dd
#~ from lino.utils.babel import default_language
#~ from lino import reports
#~ from lino import layouts
from lino.core.perms import UserProfiles
from lino.utils.restify import restify
#~ from lino.utils import printable
from lino.utils.choosers import chooser
from lino.utils import babel
from lino import mixins
from django.conf import settings
#~ from lino import choices_method, simple_choices_method
#~ from lino.modlib.contacts import models as contacts
from lino.modlib.users import models as users
from lino.modlib.cal.utils import DurationUnits

#~ from lino_welfare.models import Person
#~ from lino_welfare.modlib.pcsw import models as welfare
from lino_welfare.modlib.pcsw import models as pcsw

def amonthago():
    return DurationUnits.months.add_duration(datetime.date.today(),-1)

class Broker(dd.Model):
    """
    A Broker (Vermittler) is an external institution
    who suggests newcomers.
    """
    class Meta:
        verbose_name = _("Broker")
        verbose_name_plural = _("Brokers")

    name = models.CharField(max_length=200)

    def __unicode__(self):
        return self.name

class Brokers(dd.Table):
    """
    List of Brokers on this site.
    """
    required=dict(user_groups=['newcomers'],user_level='manager')
    #~ required_user_level = UserLevels.manager
    model = Broker
    column_names = 'name *'
    order_by = ["name"]

class Faculty(babel.BabelNamed):
    """
    A Faculty (Fachbereich) is a conceptual (not organizational)
    department of this PCSW.
    Each Newcomer will be assigned to one and only one Faculty,
    based on his/her needs.

    """
    class Meta:
        verbose_name = _("Faculty")
        verbose_name_plural = _("Faculties")
    #~ body = babel.BabelTextField(_("Body"),blank=True,format='html')

class Faculties(dd.Table):
    required=dict(user_groups=['newcomers'],user_level='manager')
    #~ required_user_groups = ['newcomers']
    #~ required_user_level = UserLevels.manager
    model = Faculty
    column_names = 'name *'
    order_by = ["name"]
    detail_template = """
    id name
    CompetencesByFaculty
    NewcomersByFaculty
    """

class Competence(mixins.AutoUser,mixins.Sequenced):
    """
    Deserves more documentation.
    """
    class Meta:
        #~ abstract = True
        verbose_name = _("Competence")
        verbose_name_plural = _("Competences")

    faculty = models.ForeignKey(Faculty)

    def __unicode__(self):
        return u'%s #%s' % (self._meta.verbose_name,self.pk)

class Competences(dd.Table):
    required = dict(user_groups=['newcomers'],user_level='manager')
    #~ required_user_groups = ['newcomers']
    #~ required_user_level = UserLevels.manager
    model = Competence
    column_names = 'id *'
    order_by = ["id"]

class CompetencesByUser(Competences):
    #~ required = dict(user_groups=['newcomers'])
    required = dict()
    #~ required_user_level = None
    master_key = 'user'
    column_names = 'seqno faculty *'
    order_by = ["seqno"]

class CompetencesByFaculty(Competences):
    master_key = 'faculty'
    column_names = 'user *'
    order_by = ["user"]

class MyCompetences(mixins.ByUser,CompetencesByUser):
    pass

class Newcomers(pcsw.Clients):
    """
    Clients who have the "Newcomer" checkbox on.
    """
    required = dict(user_groups=['newcomers'])
    #~ required_user_groups = ['newcomers']

    #~ filter = dict(newcomer=True)
    #~ known_values = dict(newcomer=True)
    known_values = dict(client_state=pcsw.ClientStates.newcomer)
    #~ use_as_default_table = False
    column_names = "name_column broker faculty address_column *"

    #~ @classmethod
    #~ def get_actor_label(self):
        #~ return _("Newcomers")
    label = _("Newcomers")

class NewcomersByFaculty(Newcomers):
    master_key = 'faculty'
    column_names = "name_column broker address_column *"

class NewClients(pcsw.Clients):
    required=dict(user_groups=['newcomers'])
    #~ required_user_groups = ['newcomers']
    label = _("New Clients")
    use_as_default_table = False

    parameters = dict(
        coached_by = models.ForeignKey(users.User,verbose_name=_("Coached by"),blank=True),
        since = models.DateField(_("Since"),blank=True,default=amonthago),
        **pcsw.Clients.parameters
    )
    params_layout = "coached_by since " + pcsw.Clients.params_layout

    column_names = "name_column:20 coached_from coached_until national_id:10 gsm:10 address_column age:10 email phone:10 id bank_account1 aid_type coach1 language:10 *"

    @classmethod
    def get_request_queryset(self,ar):
        """
        We only want the Clients who actually have at least one client.
        We store the corresponding request in the user object
        under the name `my_persons`.
        """
        #~ qs = Person.objects.all()
        qs = super(NewClients,self).get_request_queryset(ar)

        if ar.param_values.coached_by:
            qs = pcsw.only_coached_by(qs,ar.param_values.coached_by)

        if ar.param_values.since:
            qs = pcsw.only_coached_since(qs,ar.param_values.since)
        return qs

#~ class UsersByNewcomer(dd.VirtualTable):
#~ class UsersByNewcomer(dd.Table):
class UsersByNewcomer(users.Users):
    """
    A list of the Users that are susceptible to become responsible for a Newcomer.
    """
    use_as_default_table = False

    required = dict(user_groups=['newcomers'])
    #~ required_user_groups = ['newcomers']
    #~ model = users.User
    editable = False # even root should not edit here
    #~ filter = models.Q(profile__in=[p for p in UserProfiles.items() if p.integ_level])
    label = _("Users by Newcomer")
    column_names = 'name_column primary_clients active_clients new_clients newcomer_quota newcomer_score'
    parameters = dict(
        for_client = models.ForeignKey('contacts.Person',
            verbose_name=_("Show suggested agents for"),
            blank=True),
        since = models.DateField(_("Count Newcomers since"),
            blank=True,default=amonthago),
    )
    params_template = "for_client since"

    @chooser()
    def for_client_choices(cls):
        return Newcomers.request().data_iterator

    @classmethod
    def get_request_queryset(self,ar):
        profiles = [p for p in UserProfiles.items() if p.integ_level]
        return super(UsersByNewcomer,self,ar).filter(models.Q(profile__in=profiles))

    #~ @classmethod
    #~ def get_permission(self,action,user):
        #~ return isinstance(p.actors.ReadPermission)
        #~ return True

    @classmethod
    def get_data_rows(self,ar):
        """
        We only want the users who actually have at least one client.
        We store the corresponding request in the user object
        under the name `my_persons`.
        """
        qs = super(UsersByNewcomer,self).get_request_queryset(ar)

        Q = models.Q
        #~ for user in users.User.objects.filter(
        for user in qs:
            if ar.param_values.for_client:
                r = Competence.objects.filter(user=user,faculty=ar.param_values.for_client.faculty)
                if r.count() == 0:
                    continue
            user.new_clients = NewClients.request(
              ar.ui,param_values=dict(
                coached_by=user,
                since=ar.param_values.since))
            yield user

    #~ @dd.virtualfield('contacts.Person.coach1')
    #~ def user(self,obj,ar):
        #~ return obj

    @dd.requestfield(_("Primary clients"))
    def primary_clients(self,obj,ar):
        return pcsw.ClientsByCoach1.request(ar.ui,master_instance=obj)

    @dd.requestfield(_("Active clients"))
    def active_clients(self,obj,ar):
        return pcsw.MyActiveClients.request(ar.ui,subst_user=obj)

    @dd.requestfield(_("New Clients"))
    def new_clients(self,obj,ar):
        return obj.new_clients

    @dd.virtualfield(models.IntegerField(_("Score")))
    def newcomer_score(self,obj,ar):
        if obj.new_clients.get_total_count():
            return 100 * obj.newcomer_quota / obj.new_clients.get_total_count()
        else:
            return None

MODULE_LABEL = _("Newcomers")

#~ settings.LINO.add_user_field('newcomers_level',UserLevels.field(MODULE_LABEL))
#~ settings.LINO.add_user_group('newcomers',MODULE_LABEL)
settings.LINO.add_user_field('newcomer_quota',models.IntegerField(
          _("Newcomers Quota"),
          default=0,
          help_text="""Relative number expressing
          how many Newcomer requests this User is able to treat."""
        ))

dd.inject_field(pcsw.Client,
    'broker',
    models.ForeignKey(Broker,
        blank=True,null=True),
    """The Broker who sent this Newcomer.
    """)
dd.inject_field(pcsw.Client,
    'faculty',
    models.ForeignKey(Faculty,
        blank=True,null=True),
    """The Faculty this client has been attributed to.
    """)

def site_setup(site):
    site.modules.users.Users.add_detail_tab('newcomers.CompetencesByUser')

def setup_main_menu(site,ui,user,m):
    #~ if user.profile.newcomers_level < UserLevels.user:
        #~ return
    m  = m.add_menu("newcomers",MODULE_LABEL)
    m.add_action(Newcomers)
    m.add_action(UsersByNewcomer)
    m.add_action(NewClients)

def setup_master_menu(site,ui,user,m): pass

def setup_my_menu(site,ui,user,m):
    pass

def setup_config_menu(site,ui,user,m):
    #~ if user.profile.newcomers_level < UserLevels.manager:
        #~ return
    m  = m.add_menu("newcomers",MODULE_LABEL)
    m.add_action(Brokers)
    m.add_action(Faculties)

def setup_explorer_menu(site,ui,user,m):
    #~ if user.profile.newcomers_level < UserLevels.manager:
        #~ return
    m.add_action(Competences)

dd.add_user_group('newcomers',MODULE_LABEL)
  <|endoftext|>


<commit_before># -*- coding: utf-8 -*-

"""
Copyright [2009-2018] EMBL-European Bioinformatics Institute
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

import os

import luigi

from tasks.config import db
from tasks.config import export
from tasks.genome_mapping.genome_mapping_tasks import get_mapped_assemblies
from rnacentral.export.ftp import bed

class ChromSizes(luigi.Task):
    assembly_ucsc = luigi.Parameter(default='hg38')

    def output(self):
        filename = '%s.chrom.sizes' % self.assembly_ucsc
        return luigi.LocalTarget(export().bed(filename))

    def run(self):
        bed.get_chrom_sizes(db(), assembly_ucsc=self.assembly_ucsc, output=self.output().path)

class BedDataDump(luigi.Task):
    assembly_id = luigi.Parameter(default='GRCh38')
    species = luigi.Parameter(default='homo_sapiens')
    taxid = luigi.IntParameter(default=9606)

    def output(self):
        filename = '{species}.{assembly_id}.tsv'.format(assembly_id=self.assembly_id, species=self.species.capitalize())
        return luigi.LocalTarget(export().bed(filename))

    def run(self):
        with self.output().open('w') as raw:
            bed.export_blat_coordinates(db(), raw, taxid=self.taxid)
            bed.export_ensembl_coordinates(db(), raw, taxid=self.taxid)

class BedFile(luigi.Task):
    assembly_id = luigi.Parameter(default='GRCh38')
    species = luigi.Parameter(default='homo_sapiens')
    taxid = luigi.IntParameter(default=9606)

    def requires(self):
        return BedDataDump(taxid=self.taxid, assembly_id=self.assembly_id, species=self.species)

    def output(self):
        filename = '{species}.{assembly_id}.bed'.format(assembly_id=self.assembly_id, species=self.species.capitalize())
        return luigi.LocalTarget(export().bed(filename))

    def run(self):
        with self.input().open('r') as raw, self.output().open('w') as out:
            bed.make_bed_file(raw, out)
        bed.sort_bed_file(self.output().path)

class BedToBigBed(luigi.Task):
    assembly_ucsc = luigi.Parameter(default='hg38')
    assembly_id = luigi.Parameter(default='GRCh38')
    species = luigi.Parameter(default='homo_sapiens')
    taxid = luigi.IntParameter(default=9606)

    def requires(self):
        return {
            'bed': BedFile(taxid=self.taxid, assembly_id=self.assembly_id, species=self.species),
            'chromsizes': ChromSizes(assembly_ucsc=self.assembly_ucsc),
        }

    def output(self):
        filename = '{assembly_ucsc}.bigBed'.format(assembly_ucsc=self.assembly_ucsc)
        return luigi.LocalTarget(export().bed(filename))

    def run(self):
        bed.convert_to_bigbed(self.input()['bed'].path,
                              self.input()['chromsizes'].path,
                              self.output().path)

class BigBedWrapper(luigi.WrapperTask):
    def requires(self):
        for assembly in get_mapped_assemblies():
            if assembly['assembly_ucsc']:
                yield BedToBigBed(taxid=assembly['taxid'],
                                  assembly_id=assembly['assembly_id'],
                                  assembly_ucsc=assembly['assembly_ucsc'],
                                  species=assembly['species'])

class BedWrapper(luigi.WrapperTask):
    def requires(self):
        for assembly in get_mapped_assemblies():
            yield BedFile(taxid=assembly['taxid'],
                          assembly_id=assembly['assembly_id'],
                          species=assembly['species'])

class BedAndBigBedWrapper(luigi.WrapperTask):
    def requires(self):
        yield BigBedWrapper()
        yield BedWrapper()
<commit_msg>Minor refactoring<commit_after># -*- coding: utf-8 -*-

"""
Copyright [2009-2018] EMBL-European Bioinformatics Institute
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

import os

import luigi

from tasks.config import db
from tasks.config import export
from tasks.genome_mapping.genome_mapping_tasks import get_mapped_assemblies
from rnacentral.export.ftp import bed

class ChromSizes(luigi.Task):
    assembly_ucsc = luigi.Parameter(default='hg38')

    def output(self):
        filename = '{}.chrom.sizes'.format(self.assembly_ucsc)
        return luigi.LocalTarget(export().bed(filename))

    def run(self):
        bed.get_chrom_sizes(db(), assembly_ucsc=self.assembly_ucsc, output=self.output().path)

class BedDataDump(luigi.Task):
    assembly_id = luigi.Parameter(default='GRCh38')
    species = luigi.Parameter(default='homo_sapiens')
    taxid = luigi.IntParameter(default=9606)

    def output(self):
        filename = '{}.{}.tsv'.format(self.species.capitalize(), self.assembly_id)
        return luigi.LocalTarget(export().bed(filename))

    def run(self):
        with self.output().open('w') as raw:
            bed.export_blat_coordinates(db(), raw, taxid=self.taxid)
            bed.export_ensembl_coordinates(db(), raw, taxid=self.taxid)

class BedFile(luigi.Task):
    assembly_id = luigi.Parameter(default='GRCh38')
    species = luigi.Parameter(default='homo_sapiens')
    taxid = luigi.IntParameter(default=9606)

    def requires(self):
        return BedDataDump(taxid=self.taxid,
                           assembly_id=self.assembly_id,
                           species=self.species)

    def output(self):
        filename = '{}.{}.bed'.format(self.species.capitalize(), self.assembly_id)
        return luigi.LocalTarget(export().bed(filename))

    def run(self):
        with self.input().open('r') as raw, self.output().open('w') as out:
            bed.make_bed_file(raw, out)
        bed.sort_bed_file(self.output().path)

class BedToBigBed(luigi.Task):
    assembly_ucsc = luigi.Parameter(default='hg38')
    assembly_id = luigi.Parameter(default='GRCh38')
    species = luigi.Parameter(default='homo_sapiens')
    taxid = luigi.IntParameter(default=9606)

    def requires(self):
        return {
            'bed': BedFile(taxid=self.taxid,
                           assembly_id=self.assembly_id,
                           species=self.species),
            'chromsizes': ChromSizes(assembly_ucsc=self.assembly_ucsc),
        }

    def output(self):
        filename = '{}.bigBed'.format(self.assembly_ucsc)
        return luigi.LocalTarget(export().bed(filename))

    def run(self):
        bed.convert_to_bigbed(self.input()['bed'].path,
                              self.input()['chromsizes'].path,
                              self.output().path)

class BigBedWrapper(luigi.WrapperTask):
    def requires(self):
        for assembly in get_mapped_assemblies():
            if assembly['assembly_ucsc']:
                yield BedToBigBed(taxid=assembly['taxid'],
                                  assembly_id=assembly['assembly_id'],
                                  assembly_ucsc=assembly['assembly_ucsc'],
                                  species=assembly['species'])

class BedWrapper(luigi.WrapperTask):
    def requires(self):
        for assembly in get_mapped_assemblies():
            yield BedFile(taxid=assembly['taxid'],
                          assembly_id=assembly['assembly_id'],
                          species=assembly['species'])

class BedAndBigBedWrapper(luigi.WrapperTask):
    def requires(self):
        yield BigBedWrapper()
        yield BedWrapper()
<|endoftext|>