Updated to ACES 1.0.1
[OpenColorIO-Configs.git] / aces_1.0.1 / python / aces_ocio / utilities.py
diff --git a/aces_1.0.1/python/aces_ocio/utilities.py b/aces_1.0.1/python/aces_ocio/utilities.py
new file mode 100644 (file)
index 0000000..947bf93
--- /dev/null
@@ -0,0 +1,306 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Defines various package utilities objects.
+"""
+
+from __future__ import division
+
+import itertools
+import os
+import re
+from collections import OrderedDict
+
+import PyOpenColorIO as ocio
+
+__author__ = 'ACES Developers'
+__copyright__ = 'Copyright (C) 2014 - 2015 - ACES Developers'
+__license__ = ''
+__maintainer__ = 'ACES Developers'
+__email__ = 'aces@oscars.org'
+__status__ = 'Production'
+
+__all__ = ['ColorSpace',
+           'mat44_from_mat33',
+           'filter_words',
+           'files_walker',
+           'replace',
+           'sanitize',
+           'compact',
+           'colorspace_prefixed_name',
+           'unpack_default']
+
+
+class ColorSpace(object):
+    """
+    A container for data needed to define an *OCIO* *ColorSpace*.
+    """
+
+    def __init__(self,
+                 name,
+                 aliases=None,
+                 description=None,
+                 bit_depth=ocio.Constants.BIT_DEPTH_F32,
+                 equality_group='',
+                 family=None,
+                 is_data=False,
+                 to_reference_transforms=None,
+                 from_reference_transforms=None,
+                 allocation_type=ocio.Constants.ALLOCATION_UNIFORM,
+                 allocation_vars=None,
+                 aces_transform_id=None):
+        """
+        Constructor for ColorSpace container class
+
+        Parameters
+        ----------
+        name : str or unicode
+            Name of the colorspace
+        All other arguments are optional
+
+        Returns
+        -------
+        None
+        """
+
+        if aliases is None:
+            aliases = []
+
+        if to_reference_transforms is None:
+            to_reference_transforms = []
+
+        if from_reference_transforms is None:
+            from_reference_transforms = []
+
+        if allocation_vars is None:
+            allocation_vars = [0, 1]
+
+        self.name = name
+        self.aliases = aliases
+        self.bit_depth = bit_depth
+        self.description = description
+        self.equality_group = equality_group
+        self.family = family
+        self.is_data = is_data
+        self.to_reference_transforms = to_reference_transforms
+        self.from_reference_transforms = from_reference_transforms
+        self.allocation_type = allocation_type
+        self.allocation_vars = allocation_vars
+        self.aces_transform_id = aces_transform_id
+
+
+def mat44_from_mat33(mat33):
+    """
+    Creates a 4x4 matrix from given 3x3 matrix.
+
+    Parameters
+    ----------
+    mat33 : array of float
+        A 3x3 matrix
+
+    Returns
+    -------
+    array of float
+         A 4x4 matrix
+    """
+
+    return [mat33[0], mat33[1], mat33[2], 0,
+            mat33[3], mat33[4], mat33[5], 0,
+            mat33[6], mat33[7], mat33[8], 0,
+            0, 0, 0, 1]
+
+
+def filter_words(words, filters_in=None, filters_out=None, flags=0):
+    """
+    A function to filter strings in an array
+
+    Parameters
+    ----------
+    words : array of str or unicode
+        Array of strings
+    filters_in : array of str or unicode, optional
+        Words to match
+    filters_out : array of str or unicode, optional
+        Words to NOT match
+    flags : int, optional
+        Flags for re.search
+
+    Returns
+    -------
+    array of str or unicode
+         An array of matched or unmatched strings
+    """
+
+    filtered_words = []
+    for word in words:
+        if filters_in:
+            filter_matched = False
+            for filter in filters_in:
+                if re.search(filter, word, flags):
+                    filter_matched = True
+                    break
+            if not filter_matched:
+                continue
+
+        if filters_out:
+            filter_matched = False
+            for filter in filters_out:
+                if re.search(filter, word, flags):
+                    filter_matched = True
+                    break
+            if filter_matched:
+                continue
+        filtered_words.append(word)
+    return filtered_words
+
+
+def files_walker(directory, filters_in=None, filters_out=None, flags=0):
+    """
+    A function to walk a directory hierarchy, only returning items that do or
+    do not match the specified filters
+
+    Parameters
+    ----------
+    directory : str or unicode
+        The starting point for directory walking
+    filters_in : array of str or unicode, optional
+        File or directory names to match
+    filters_out : array of str or unicode, optional
+        File or directory names to NOT match
+    flags : int, optional
+        Flags for re.search
+
+    Returns
+    -------
+    iterable
+         The next matching file or directory name
+    """
+
+    for parent_directory, directories, files in os.walk(
+            directory, topdown=False, followlinks=True):
+        for file in files:
+            path = os.path.join(parent_directory, file)
+            if os.path.isfile(path):
+                if not filter_words((path,), filters_in, filters_out, flags):
+                    continue
+
+                yield path
+
+
+def replace(string, data):
+    """
+    Replaces the data occurrences in the string.
+
+    Parameters
+    ----------
+    string : str or unicode
+        String to manipulate.
+    data : dict
+        Replacement occurrences.
+
+    Returns
+    -------
+    unicode
+        Manipulated string.
+
+    Examples
+    --------
+    >>> patterns = {'John' : 'Luke',
+    ...             'Jane' : 'Anakin',
+    ...             'Doe' : 'Skywalker',
+    ...             'Z6PO' : 'R2D2'}
+    >>> data = 'Users are: John Doe, Jane Doe, Z6PO.'
+    >>> replace(data,patterns )
+    u'Users are: Luke Skywalker, Anakin Skywalker, R2D2.'
+    """
+
+    for old, new in data.iteritems():
+        string = string.replace(old, new)
+    return string
+
+
+def sanitize(path):
+    """
+    Replaces occurrences of ' ', '(', or ')' in the string with an underscore.
+
+    Parameters
+    ----------
+    path : str or unicode
+        Path string to manipulate.
+
+    Returns
+    -------
+    unicode
+        Manipulated string.
+    """
+
+    return replace(path, {' ': '_', ')': '_', '(': '_'})
+
+
+def compact(string):
+    """
+    Removes blanks, underscores, dashes and parentheses.
+
+    Parameters
+    ----------
+    string : str or unicode
+        String to compact.
+
+    Returns
+    -------
+    str or unicode
+         A compact version of that string.
+    """
+
+    return replace(string.lower(),
+                   OrderedDict(((' ', '_'),
+                                ('(', '_'),
+                                (')', '_'),
+                                ('.', '_'),
+                                ('-', '_'),
+                                ('___', '_'),
+                                ('__', '_'),
+                                ('_', ''))))
+
+
+def colorspace_prefixed_name(colorspace):
+    """
+    Returns given *OCIO* colorspace prefixed name with its family name.
+
+    Parameters
+    ----------
+    colorspace : Colorspace
+        Colorspace to prefix.
+
+    Returns
+    -------
+    str or unicode
+         Family prefixed *OCIO* colorspace name.
+    """
+    prefix = colorspace.family.replace('/', ' - ')
+
+    return '%s - %s' % (prefix, colorspace.name)
+
+
+def unpack_default(iterable, length=3, default=None):
+    """
+    Unpacks given iterable maintaining given length and filling missing
+    entries with given default.
+
+    Parameters
+    ----------
+    iterable : object
+        Iterable.
+    length : int
+        Iterable length.
+    default : object
+        Filling default object.
+
+    Returns
+    -------
+    iterable
+    """
+
+    return itertools.islice(
+        itertools.chain(iter(iterable), itertools.repeat(default)), length)