Merge pull request #1 from colour-science/code_style
authorhpd <hpd1@duikerresearch.com>
Fri, 16 Jan 2015 20:35:15 +0000 (12:35 -0800)
committerhpd <hpd1@duikerresearch.com>
Fri, 16 Jan 2015 20:35:15 +0000 (12:35 -0800)
PR: Implement basic unit tests and apply PEP8 code formatting.

20 files changed:
.gitignore [new file with mode: 0644]
aces_1.0.0/python/aces_ocio/__init__.py [new file with mode: 0644]
aces_1.0.0/python/aces_ocio/create_aces_config.py [new file with mode: 0755]
aces_1.0.0/python/aces_ocio/create_arri_colorspaces.py [new file with mode: 0644]
aces_1.0.0/python/aces_ocio/create_canon_colorspaces.py [new file with mode: 0644]
aces_1.0.0/python/aces_ocio/create_red_colorspaces.py [new file with mode: 0644]
aces_1.0.0/python/aces_ocio/create_sony_colorspaces.py [new file with mode: 0644]
aces_1.0.0/python/aces_ocio/generate_lut.py [new file with mode: 0644]
aces_1.0.0/python/aces_ocio/process.py [new file with mode: 0755]
aces_1.0.0/python/aces_ocio/tests/__init__.py [new file with mode: 0644]
aces_1.0.0/python/aces_ocio/tests/tests_aces_config.py [new file with mode: 0644]
aces_1.0.0/python/aces_ocio/utilities.py [new file with mode: 0644]
aces_1.0.0/python/createARRIColorSpaces.py [deleted file]
aces_1.0.0/python/createCanonColorSpaces.py [deleted file]
aces_1.0.0/python/createREDColorSpaces.py [deleted file]
aces_1.0.0/python/createSonyColorSpaces.py [deleted file]
aces_1.0.0/python/create_aces_config.py [deleted file]
aces_1.0.0/python/generateLUT.py [deleted file]
aces_1.0.0/python/process.py [deleted file]
aces_1.0.0/python/util.py [deleted file]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..c10666e
--- /dev/null
@@ -0,0 +1,2 @@
+.idea
+*.pyc
diff --git a/aces_1.0.0/python/aces_ocio/__init__.py b/aces_1.0.0/python/aces_ocio/__init__.py
new file mode 100644 (file)
index 0000000..55576c9
--- /dev/null
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+ACES OCIO
+=========
+
+Usage
+-----
+
+Python
+******
+
+>>> import sys
+>>> sys.path.append("/path/to/script")
+>>> import create_aces_config as cac
+>>> acesReleaseCTLDir = "/path/to/github/checkout/releases/v0.7.1/transforms/ctl"
+>>> configDir = "/path/to/config/dir"
+>>> cac.createACESConfig(acesReleaseCTLDir, configDir, 1024, 33, True)
+
+Command Line
+************
+
+From the directory with 'create_aces_config.py':
+
+$ python create_aces_config.py -a "/path/to/github/checkout/releases/v0.7.1/transforms/ctl" -c "/path/to/config/dir" --lut_resolution_1d 1024 --lut_resolution_3d 33 --keepTempImages
+
+Build
+-----
+
+Mac OS X - Required packages
+****************************
+
+OpenColorIO
+___________
+
+$ brew install -vd opencolorio --with-python
+
+OpenImageIO
+___________
+
+$ brew tap homebrew/science
+
+Optional Dependencies
+_____________________
+
+$ brew install -vd libRaw
+$ brew install -vd OpenCV
+$ brew install -vd openimageio --with-python
+
+CTL
+___
+
+$ brew install -vd CTL
+
+OpenColorIO
+___________
+
+*ociolutimage* will build with *openimageio* installed.
+
+$ brew uninstall -vd opencolorio
+$ brew install -vd opencolorio --with-python
+"""
+
+__author__ = 'ACES Developers'
+__copyright__ = 'Copyright (C) 2014 - 2015 - ACES Developers'
+__license__ = ''
+__maintainer__ = 'ACES Developers'
+__email__ = 'aces@oscars.org'
+__status__ = 'Production'
+
+__major_version__ = '1'
+__minor_version__ = '0'
+__change_version__ = '0'
+__version__ = '.'.join((__major_version__,
+                        __minor_version__,
+                        __change_version__))
\ No newline at end of file
diff --git a/aces_1.0.0/python/aces_ocio/create_aces_config.py b/aces_1.0.0/python/aces_ocio/create_aces_config.py
new file mode 100755 (executable)
index 0000000..a18ba48
--- /dev/null
@@ -0,0 +1,1845 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Defines objects creating the *ACES* configuration.
+"""
+
+import math
+import numpy
+import os
+import pprint
+import shutil
+import string
+import sys
+
+# TODO: This restores the capability of running the script without having
+# added the package to PYTHONPATH, this is ugly and should ideally replaced by
+# dedicated executable in a /bin directory.
+sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+
+import PyOpenColorIO as OCIO
+
+import aces_ocio.create_arri_colorspaces as arri
+import aces_ocio.create_canon_colorspaces as canon
+import aces_ocio.create_red_colorspaces as red
+import aces_ocio.create_sony_colorspaces as sony
+from aces_ocio.generate_lut import (
+    generate_1d_LUT_from_CTL,
+    generate_3d_LUT_from_CTL,
+    write_SPI_1d)
+from aces_ocio.process import Process
+from aces_ocio.utilities import ColorSpace, mat44_from_mat33
+
+__author__ = 'ACES Developers'
+__copyright__ = 'Copyright (C) 2014 - 2015 - ACES Developers'
+__license__ = ''
+__maintainer__ = 'ACES Developers'
+__email__ = 'aces@oscars.org'
+__status__ = 'Production'
+
+__all__ = ['ACES_OCIO_CTL_DIRECTORY_ENVIRON',
+           'ACES_OCIO_CONFIGURATION_DIRECTORY_ENVIRON',
+           'set_config_default_roles',
+           'write_config',
+           'generate_OCIO_transform',
+           'create_config',
+           'generate_LUTs',
+           'generate_baked_LUTs',
+           'create_config_dir',
+           'get_transform_info',
+           'get_ODT_info',
+           'get_LMT_info',
+           'create_ACES_config',
+           'main']
+
+ACES_OCIO_CTL_DIRECTORY_ENVIRON = 'ACES_OCIO_CTL_DIRECTORY'
+ACES_OCIO_CONFIGURATION_DIRECTORY_ENVIRON = 'ACES_OCIO_CONFIGURATION_DIRECTORY'
+
+
+def set_config_default_roles(config,
+                             color_picking="",
+                             color_timing="",
+                             compositing_log="",
+                             data="",
+                             default="",
+                             matte_paint="",
+                             reference="",
+                             scene_linear="",
+                             texture_paint=""):
+    """
+    Sets given *OCIO* configuration default roles.
+
+    Parameters
+    ----------
+    config : config
+        *OCIO* configuration.
+    color_picking : str or unicode
+        Color picking role title.
+    color_timing : str or unicode
+        Color timing role title.
+    compositing_log : str or unicode
+        Compositing log role title.
+    data : str or unicode
+        Data role title.
+    default : str or unicode
+        Default role title.
+    matte_paint : str or unicode
+        Matte painting role title.
+    reference : str or unicode
+        Reference role title.
+    scene_linear : str or unicode
+        Scene linear role title.
+    texture_paint : str or unicode
+        Texture painting role title.
+
+    Returns
+    -------
+    bool
+         Definition success.
+    """
+
+    if color_picking:
+        config.setRole(OCIO.Constants.ROLE_COLOR_PICKING, color_picking)
+    if color_timing:
+        config.setRole(OCIO.Constants.ROLE_COLOR_TIMING, color_timing)
+    if compositing_log:
+        config.setRole(OCIO.Constants.ROLE_COMPOSITING_LOG, compositing_log)
+    if data:
+        config.setRole(OCIO.Constants.ROLE_DATA, data)
+    if default:
+        config.setRole(OCIO.Constants.ROLE_DEFAULT, default)
+    if matte_paint:
+        config.setRole(OCIO.Constants.ROLE_MATTE_PAINT, matte_paint)
+    if reference:
+        config.setRole(OCIO.Constants.ROLE_REFERENCE, reference)
+    if scene_linear:
+        config.setRole(OCIO.Constants.ROLE_SCENE_LINEAR, scene_linear)
+    if texture_paint:
+        config.setRole(OCIO.Constants.ROLE_TEXTURE_PAINT, texture_paint)
+
+    return True
+
+
+def write_config(config, config_path, sanity_check=True):
+    """
+    Writes the configuration to given path.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    if sanity_check:
+        try:
+            config.sanityCheck()
+        except Exception, e:
+            print e
+            print "Configuration was not written due to a failed Sanity Check"
+            return
+            # sys.exit()
+
+    file_handle = open(config_path, mode='w')
+    file_handle.write(config.serialize())
+    file_handle.close()
+
+
+def generate_OCIO_transform(transforms):
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    # print("Generating transforms")
+
+    interpolation_options = {
+        'linear': OCIO.Constants.INTERP_LINEAR,
+        'nearest': OCIO.Constants.INTERP_NEAREST,
+        'tetrahedral': OCIO.Constants.INTERP_TETRAHEDRAL
+    }
+    direction_options = {
+        'forward': OCIO.Constants.TRANSFORM_DIR_FORWARD,
+        'inverse': OCIO.Constants.TRANSFORM_DIR_INVERSE
+    }
+
+    ocio_transforms = []
+
+    for transform in transforms:
+        if transform['type'] == 'lutFile':
+            ocio_transform = OCIO.FileTransform(
+                src=transform['path'],
+                interpolation=interpolation_options[
+                    transform['interpolation']],
+                direction=direction_options[transform['direction']])
+            ocio_transforms.append(ocio_transform)
+        elif transform['type'] == 'matrix':
+            ocio_transform = OCIO.MatrixTransform()
+            # MatrixTransform member variables can't be initialized directly.
+            # Each must be set individually.
+            ocio_transform.setMatrix(transform['matrix'])
+
+            if 'offset' in transform:
+                ocio_transform.setOffset(transform['offset'])
+
+            if 'direction' in transform:
+                ocio_transform.setDirection(
+                    direction_options[transform['direction']])
+
+            ocio_transforms.append(ocio_transform)
+        elif transform['type'] == 'exponent':
+            ocio_transform = OCIO.ExponentTransform()
+            ocio_transform.setValue(transform['value'])
+            ocio_transforms.append(ocio_transform)
+        elif transform['type'] == 'log':
+            ocio_transform = OCIO.LogTransform(
+                base=transform['base'],
+                direction=direction_options[transform['direction']])
+
+            ocio_transforms.append(ocio_transform)
+        else:
+            print("Ignoring unknown transform type : %s" % transform['type'])
+
+    # Build a group transform if necessary
+    if len(ocio_transforms) > 1:
+        transform_G = OCIO.GroupTransform()
+        for transform in ocio_transforms:
+            transform_G.push_back(transform)
+        transform = transform_G
+
+    # Or take the first transform from the list
+    else:
+        transform = ocio_transforms[0]
+
+    return transform
+
+
+def create_config(config_data, nuke=False):
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    # Create the config
+    config = OCIO.Config()
+
+    #
+    # Set config wide values
+    #
+    config.setDescription("An ACES config generated from python")
+    config.setSearchPath("luts")
+
+    #
+    # Define the reference color space
+    #
+    reference_data = config_data['referenceColorSpace']
+    print("Adding the reference color space : %s" % reference_data.name)
+
+    # Create a color space
+    reference = OCIO.ColorSpace(
+        name=reference_data.name,
+        bitDepth=reference_data.bit_depth,
+        description=reference_data.description,
+        equalityGroup=reference_data.equality_group,
+        family=reference_data.family,
+        isData=reference_data.is_data,
+        allocation=reference_data.allocation_type,
+        allocationVars=reference_data.allocation_vars)
+
+    # Add to config
+    config.addColorSpace(reference)
+
+    #
+    # Create the rest of the color spaces
+    #
+    for colorspace in sorted(config_data['colorSpaces']):
+        print("Creating new color space : %s" % colorspace.name)
+
+        ocio_colorspace = OCIO.ColorSpace(
+            name=colorspace.name,
+            bitDepth=colorspace.bit_depth,
+            description=colorspace.description,
+            equalityGroup=colorspace.equality_group,
+            family=colorspace.family,
+            isData=colorspace.is_data,
+            allocation=colorspace.allocation_type,
+            allocationVars=colorspace.allocation_vars)
+
+        if colorspace.to_reference_transforms != []:
+            print("Generating To-Reference transforms")
+            ocio_transform = generate_OCIO_transform(
+                colorspace.to_reference_transforms)
+            ocio_colorspace.setTransform(
+                ocio_transform,
+                OCIO.Constants.COLORSPACE_DIR_TO_REFERENCE)
+
+        if colorspace.from_reference_transforms != []:
+            print("Generating From-Reference transforms")
+            ocio_transform = generate_OCIO_transform(
+                colorspace.from_reference_transforms)
+            ocio_colorspace.setTransform(
+                ocio_transform,
+                OCIO.Constants.COLORSPACE_DIR_FROM_REFERENCE)
+
+        config.addColorSpace(ocio_colorspace)
+
+        print("")
+
+    #
+    # Define the views and displays
+    #
+    displays = []
+    views = []
+
+    # Generic display and view setup
+    if not nuke:
+        for display, view_list in config_data['displays'].iteritems():
+            for view_name, colorspace in view_list.iteritems():
+                config.addDisplay(display, view_name, colorspace.name)
+                if not (view_name in views):
+                    views.append(view_name)
+            displays.append(display)
+    # A Nuke specific set of views and displays
+    #
+    # XXX
+    # A few names: Output Transform, ACES, ACEScc, are hard-coded here.
+    # Would be better to automate.
+    #
+    else:
+        for display, view_list in config_data['displays'].iteritems():
+            for view_name, colorspace in view_list.iteritems():
+                if (view_name == 'Output Transform'):
+                    view_name = 'View'
+                    config.addDisplay(display, view_name, colorspace.name)
+                    if not (view_name in views):
+                        views.append(view_name)
+            displays.append(display)
+
+        config.addDisplay('linear', 'View', 'ACES2065-1')
+        displays.append('linear')
+        config.addDisplay('log', 'View', 'ACEScc')
+        displays.append('log')
+
+    # Set active displays and views
+    config.setActiveDisplays(','.join(sorted(displays)))
+    config.setActiveViews(','.join(views))
+
+    #
+    # Need to generalize this at some point
+    #
+
+    # Add Default Roles
+    set_config_default_roles(
+        config,
+        color_picking=reference.getName(),
+        color_timing=reference.getName(),
+        compositing_log=reference.getName(),
+        data=reference.getName(),
+        default=reference.getName(),
+        matte_paint=reference.getName(),
+        reference=reference.getName(),
+        scene_linear=reference.getName(),
+        texture_paint=reference.getName())
+
+    # Check to make sure we didn't screw something up
+    config.sanityCheck()
+
+    return config
+
+
+def generate_LUTs(odt_info,
+                  lmt_info,
+                  shaper_name,
+                  aces_CTL_directory,
+                  lut_directory,
+                  lut_resolution_1d=4096,
+                  lut_resolution_3d=64,
+                  cleanup=True):
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    dict
+         Colorspaces and transforms converting between those colorspaces and
+         the reference colorspace, *ACES*.
+    """
+
+    print("generateLUTs - begin")
+    config_data = {}
+
+    #
+    # Define the reference color space
+    #
+    ACES = ColorSpace('ACES2065-1')
+    ACES.description = (
+        'The Academy Color Encoding System reference color space')
+    ACES.equality_group = ''
+    ACES.family = 'ACES'
+    ACES.is_data = False
+    ACES.allocation_type = OCIO.Constants.ALLOCATION_LG2
+    ACES.allocation_vars = [-15, 6]
+
+    config_data['referenceColorSpace'] = ACES
+
+    #
+    # Define the displays
+    #
+    config_data['displays'] = {}
+
+    #
+    # Define the other color spaces
+    #
+    config_data['colorSpaces'] = []
+
+    # Matrix converting ACES AP1 primaries to AP0
+    ACES_AP1_to_AP0 = [0.6954522414, 0.1406786965, 0.1638690622,
+                       0.0447945634, 0.8596711185, 0.0955343182,
+                       -0.0055258826, 0.0040252103, 1.0015006723]
+
+    # Matrix converting ACES AP0 primaries to XYZ
+    ACES_AP0_to_XYZ = [0.9525523959, 0.0000000000, 0.0000936786,
+                       0.3439664498, 0.7281660966, -0.0721325464,
+                       0.0000000000, 0.0000000000, 1.0088251844]
+
+    #
+    # ACEScc
+    #
+    def create_ACEScc(name='ACEScc',
+                      min_value=0.0,
+                      max_value=1.0,
+                      input_scale=1.0):
+        cs = ColorSpace(name)
+        cs.description = "The %s color space" % name
+        cs.equality_group = ''
+        cs.family = 'ACES'
+        cs.is_data = False
+
+        ctls = [
+            '%s/ACEScc/ACEScsc.ACEScc_to_ACES.a1.0.0.ctl' % aces_CTL_directory,
+            # This transform gets back to the AP1 primaries
+            # Useful as the 1d LUT is only covering the transfer function
+            # The primaries switch is covered by the matrix below
+            '%s/ACEScg/ACEScsc.ACES_to_ACEScg.a1.0.0.ctl' % aces_CTL_directory
+        ]
+        lut = "%s_to_ACES.spi1d" % name
+
+        # Remove spaces and parentheses
+        lut = lut.replace(' ', '_').replace(')', '_').replace('(', '_')
+
+        generate_1d_LUT_from_CTL(
+            lut_directory + "/" + lut,
+            ctls,
+            lut_resolution_1d,
+            'float',
+            input_scale,
+            1.0,
+            {},
+            cleanup,
+            aces_CTL_directory,
+            min_value,
+            max_value)
+
+        cs.to_reference_transforms = []
+        cs.to_reference_transforms.append({
+            'type': 'lutFile',
+            'path': lut,
+            'interpolation': 'linear',
+            'direction': 'forward'
+        })
+
+        # AP1 primaries to AP0 primaries
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': mat44_from_mat33(ACES_AP1_to_AP0),
+            'direction': 'forward'
+        })
+
+        cs.from_reference_transforms = []
+        return cs
+
+    ACEScc = create_ACEScc()
+    config_data['colorSpaces'].append(ACEScc)
+
+    #
+    # ACESproxy
+    #
+    def create_ACESproxy(name='ACESproxy'):
+        cs = ColorSpace(name)
+        cs.description = "The %s color space" % name
+        cs.equality_group = ''
+        cs.family = 'ACES'
+        cs.is_data = False
+
+        ctls = [
+            '%s/ACESproxy/ACEScsc.ACESproxy10i_to_ACES.a1.0.0.ctl' % (
+                aces_CTL_directory),
+            # This transform gets back to the AP1 primaries
+            # Useful as the 1d LUT is only covering the transfer function
+            # The primaries switch is covered by the matrix below
+            '%s/ACEScg/ACEScsc.ACES_to_ACEScg.a1.0.0.ctl' % aces_CTL_directory
+        ]
+        lut = "%s_to_aces.spi1d" % name
+
+        # Remove spaces and parentheses
+        lut = lut.replace(' ', '_').replace(')', '_').replace('(', '_')
+
+        generate_1d_LUT_from_CTL(
+            lut_directory + "/" + lut,
+            ctls,
+            lut_resolution_1d,
+            'uint16',
+            64.0,
+            1.0,
+            {},
+            cleanup,
+            aces_CTL_directory)
+
+        cs.to_reference_transforms = []
+        cs.to_reference_transforms.append({
+            'type': 'lutFile',
+            'path': lut,
+            'interpolation': 'linear',
+            'direction': 'forward'
+        })
+
+        # AP1 primaries to AP0 primaries
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': mat44_from_mat33(ACES_AP1_to_AP0),
+            'direction': 'forward'
+        })
+
+        cs.from_reference_transforms = []
+        return cs
+
+    ACESproxy = create_ACESproxy()
+    config_data['colorSpaces'].append(ACESproxy)
+
+    #
+    # ACEScg
+    #
+    def create_ACEScg(name='ACEScg'):
+        cs = ColorSpace(name)
+        cs.description = "The %s color space" % name
+        cs.equality_group = ''
+        cs.family = 'ACES'
+        cs.is_data = False
+
+        cs.to_reference_transforms = []
+
+        # AP1 primaries to AP0 primaries
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': mat44_from_mat33(ACES_AP1_to_AP0),
+            'direction': 'forward'
+        })
+
+        cs.from_reference_transforms = []
+        return cs
+
+    ACEScg = create_ACEScg()
+    config_data['colorSpaces'].append(ACEScg)
+
+    #
+    # ADX
+    #
+    def create_ADX(bit_depth=10, name='ADX'):
+        name = "%s%s" % (name, bit_depth)
+        cs = ColorSpace(name)
+        cs.description = "%s color space - used for film scans" % name
+        cs.equality_group = ''
+        cs.family = 'ADX'
+        cs.is_data = False
+
+        if bit_depth == 10:
+            cs.bit_depth = bit_depth = OCIO.Constants.BIT_DEPTH_UINT10
+            adx_to_cdd = [1023.0 / 500.0, 0.0, 0.0, 0.0,
+                          0.0, 1023.0 / 500.0, 0.0, 0.0,
+                          0.0, 0.0, 1023.0 / 500.0, 0.0,
+                          0.0, 0.0, 0.0, 1.0]
+            offset = [-95.0 / 500.0, -95.0 / 500.0, -95.0 / 500.0, 0.0]
+        elif bit_depth == 16:
+            cs.bit_depth = bit_depth = OCIO.Constants.BIT_DEPTH_UINT16
+            adx_to_cdd = [65535.0 / 8000.0, 0.0, 0.0, 0.0,
+                          0.0, 65535.0 / 8000.0, 0.0, 0.0,
+                          0.0, 0.0, 65535.0 / 8000.0, 0.0,
+                          0.0, 0.0, 0.0, 1.0]
+            offset = [-1520.0 / 8000.0, -1520.0 / 8000.0, -1520.0 / 8000.0,
+                      0.0]
+
+        cs.to_reference_transforms = []
+
+        # Convert from ADX to Channel-Dependent Density
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': adx_to_cdd,
+            'offset': offset,
+            'direction': 'forward'
+        })
+
+        # Convert from Channel-Dependent Density to Channel-Independent Density
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': [0.75573, 0.22197, 0.02230, 0,
+                       0.05901, 0.96928, -0.02829, 0,
+                       0.16134, 0.07406, 0.76460, 0,
+                       0.0, 0.0, 0.0, 1.0],
+            'direction': 'forward'
+        })
+
+        # Copied from Alex Fry's adx_cid_to_rle.py
+        def create_CID_to_RLE_LUT():
+            def interpolate_1D(x, xp, fp):
+                return numpy.interp(x, xp, fp)
+
+            LUT_1D_xp = [-0.190000000000000,
+                         0.010000000000000,
+                         0.028000000000000,
+                         0.054000000000000,
+                         0.095000000000000,
+                         0.145000000000000,
+                         0.220000000000000,
+                         0.300000000000000,
+                         0.400000000000000,
+                         0.500000000000000,
+                         0.600000000000000]
+
+            LUT_1D_fp = [-6.000000000000000,
+                         -2.721718645000000,
+                         -2.521718645000000,
+                         -2.321718645000000,
+                         -2.121718645000000,
+                         -1.921718645000000,
+                         -1.721718645000000,
+                         -1.521718645000000,
+                         -1.321718645000000,
+                         -1.121718645000000,
+                         -0.926545676714876]
+
+            REF_PT = ((7120.0 - 1520.0) / 8000.0 * (100.0 / 55.0) -
+                      math.log(0.18, 10.0))
+
+            def cid_to_rle(x):
+                if x <= 0.6:
+                    return interpolate_1D(x, LUT_1D_xp, LUT_1D_fp)
+                return (100.0 / 55.0) * x - REF_PT
+
+            def fit(value, from_min, from_max, to_min, to_max):
+                if from_min == from_max:
+                    raise ValueError("from_min == from_max")
+                return (value - from_min) / (from_max - from_min) * (
+                    to_max - to_min) + to_min
+
+            NUM_SAMPLES = 2 ** 12
+            RANGE = (-0.19, 3.0)
+            data = []
+            for i in xrange(NUM_SAMPLES):
+                x = i / (NUM_SAMPLES - 1.0)
+                x = fit(x, 0.0, 1.0, RANGE[0], RANGE[1])
+                data.append(cid_to_rle(x))
+
+            lut = 'ADX_CID_to_RLE.spi1d'
+            write_SPI_1d(lut_directory + "/" + lut, RANGE[0], RANGE[1],
+                         data,
+                         NUM_SAMPLES, 1)
+
+            return lut
+
+        # Convert Channel Independent Density values to Relative Log Exposure
+        # values.
+        lut = create_CID_to_RLE_LUT()
+        cs.to_reference_transforms.append({
+            'type': 'lutFile',
+            'path': lut,
+            'interpolation': 'linear',
+            'direction': 'forward'
+        })
+
+        # Convert Relative Log Exposure values to Relative Exposure values
+        cs.to_reference_transforms.append({
+            'type': 'log',
+            'base': 10,
+            'direction': 'inverse'
+        })
+
+        # Convert Relative Exposure values to ACES values
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': [0.72286, 0.12630, 0.15084, 0,
+                       0.11923, 0.76418, 0.11659, 0,
+                       0.01427, 0.08213, 0.90359, 0,
+                       0.0, 0.0, 0.0, 1.0],
+            'direction': 'forward'
+        })
+
+        cs.from_reference_transforms = []
+        return cs
+
+    ADX10 = create_ADX(bit_depth=10)
+    config_data['colorSpaces'].append(ADX10)
+
+    ADX16 = create_ADX(bit_depth=16)
+    config_data['colorSpaces'].append(ADX16)
+
+    #
+    # Camera Input Transforms
+    #
+
+    # RED color spaces to ACES
+    red_colorspaces = red.create_colorspaces(lut_directory, lut_resolution_1d)
+    for cs in red_colorspaces:
+        config_data['colorSpaces'].append(cs)
+
+    # Canon-Log to ACES
+    canon_colorspaces = canon.create_colorspaces(lut_directory,
+                                                 lut_resolution_1d)
+    for cs in canon_colorspaces:
+        config_data['colorSpaces'].append(cs)
+
+    # S-Log to ACES
+    sony_colorSpaces = sony.create_colorspaces(lut_directory,
+                                               lut_resolution_1d)
+    for cs in sony_colorSpaces:
+        config_data['colorSpaces'].append(cs)
+
+    # Log-C to ACES
+    arri_colorSpaces = arri.create_colorspaces(lut_directory,
+                                               lut_resolution_1d)
+    for cs in arri_colorSpaces:
+        config_data['colorSpaces'].append(cs)
+
+    #
+    # Generic log transform
+    #
+    def create_generic_log(name='log',
+                           min_value=0.0,
+                           max_value=1.0,
+                           input_scale=1.0,
+                           middle_grey=0.18,
+                           min_exposure=-6.0,
+                           max_exposure=6.5,
+                           lut_resolution_1d=lut_resolution_1d):
+        cs = ColorSpace(name)
+        cs.description = "The %s color space" % name
+        cs.equality_group = name
+        cs.family = 'Utility'
+        cs.is_data = False
+
+        ctls = [
+            '%s/utilities/ACESlib.OCIO_shaper_log2_to_lin_param.a1.0.0.ctl' % (
+                aces_CTL_directory)]
+        lut = "%s_to_aces.spi1d" % name
+
+        # Remove spaces and parentheses
+        lut = lut.replace(' ', '_').replace(')', '_').replace('(', '_')
+
+        generate_1d_LUT_from_CTL(
+            lut_directory + "/" + lut,
+            ctls,
+            lut_resolution_1d,
+            'float',
+            input_scale,
+            1.0,
+            {
+                'middleGrey': middle_grey,
+                'minExposure': min_exposure,
+                'maxExposure': max_exposure
+            },
+            cleanup,
+            aces_CTL_directory,
+            min_value,
+            max_value)
+
+        cs.to_reference_transforms = []
+        cs.to_reference_transforms.append({
+            'type': 'lutFile',
+            'path': lut,
+            'interpolation': 'linear',
+            'direction': 'forward'
+        })
+
+        cs.from_reference_transforms = []
+        return cs
+
+    #
+    # ACES LMTs
+    #
+    def create_ACES_LMT(lmt_name,
+                        lmt_values,
+                        shaper_info,
+                        lut_resolution_1d=1024,
+                        lut_resolution_3d=64,
+                        cleanup=True):
+        cs = ColorSpace("%s" % lmt_name)
+        cs.description = "The ACES Look Transform: %s" % lmt_name
+        cs.equality_group = ''
+        cs.family = 'Look'
+        cs.is_data = False
+
+        pprint.pprint(lmt_values)
+
+        #
+        # Generate the shaper transform
+        #
+        (shaper_name,
+         shaper_to_ACES_CTL,
+         shaper_from_ACES_CTL,
+         shaper_input_scale,
+         shaper_params) = shaper_info
+
+        shaper_lut = "%s_to_aces.spi1d" % shaper_name
+        if (not os.path.exists(lut_directory + "/" + shaper_lut)):
+            ctls = [shaper_to_ACES_CTL % aces_CTL_directory]
+
+            # Remove spaces and parentheses
+            shaper_lut = shaper_lut.replace(
+                ' ', '_').replace(')', '_').replace('(', '_')
+
+            generate_1d_LUT_from_CTL(
+                lut_directory + "/" + shaper_lut,
+                ctls,
+                lut_resolution_1d,
+                'float',
+                1.0 / shaper_input_scale,
+                1.0,
+                shaper_params,
+                cleanup,
+                aces_CTL_directory)
+
+        shaper_OCIO_transform = {
+            'type': 'lutFile',
+            'path': shaper_lut,
+            'interpolation': 'linear',
+            'direction': 'inverse'
+        }
+
+        #
+        # Generate the forward transform
+        #
+        cs.from_reference_transforms = []
+
+        if 'transformCTL' in lmt_values:
+            ctls = [
+                shaper_to_ACES_CTL % aces_CTL_directory,
+                '%s/%s' % (aces_CTL_directory, lmt_values['transformCTL'])
+            ]
+            lut = "%s.%s.spi3d" % (shaper_name, lmt_name)
+
+            # Remove spaces and parentheses
+            lut = lut.replace(' ', '_').replace(')', '_').replace('(', '_')
+
+            generate_3d_LUT_from_CTL(
+                lut_directory + "/" + lut,
+                ctls,
+                lut_resolution_3d,
+                'float',
+                1.0 / shaper_input_scale,
+                1.0,
+                shaper_params,
+                cleanup,
+                aces_CTL_directory)
+
+            cs.from_reference_transforms.append(shaper_OCIO_transform)
+            cs.from_reference_transforms.append({
+                'type': 'lutFile',
+                'path': lut,
+                'interpolation': 'tetrahedral',
+                'direction': 'forward'
+            })
+
+        #
+        # Generate the inverse transform
+        #
+        cs.to_reference_transforms = []
+
+        if 'transformCTLInverse' in lmt_values:
+            ctls = [
+                '%s/%s' % (
+                    aces_CTL_directory, odt_values['transformCTLInverse']),
+                shaper_from_ACES_CTL % aces_CTL_directory
+            ]
+            lut = "Inverse.%s.%s.spi3d" % (odt_name, shaper_name)
+
+            # Remove spaces and parentheses
+            lut = lut.replace(' ', '_').replace(')', '_').replace('(', '_')
+
+            generate_3d_LUT_from_CTL(
+                lut_directory + "/" + lut,
+                ctls,
+                lut_resolution_3d,
+                'half',
+                1.0,
+                shaper_input_scale,
+                shaper_params,
+                cleanup,
+                aces_CTL_directory)
+
+            cs.to_reference_transforms.append({
+                'type': 'lutFile',
+                'path': lut,
+                'interpolation': 'tetrahedral',
+                'direction': 'forward'
+            })
+
+            shaper_inverse = shaper_OCIO_transform.copy()
+            shaper_inverse['direction'] = 'forward'
+            cs.to_reference_transforms.append(shaper_inverse)
+
+        return cs
+
+    #
+    # LMT Shaper
+    #
+
+    lmt_lut_resolution_1d = max(4096, lut_resolution_1d)
+    lmt_lut_resolution_3d = max(65, lut_resolution_3d)
+
+    # Log 2 shaper
+    lmt_shaper_name = 'LMT Shaper'
+    lmt_params = {
+        'middleGrey': 0.18,
+        'minExposure': -10.0,
+        'maxExposure': 6.5
+    }
+    lmt_shaper = create_generic_log(name=lmt_shaper_name,
+                                    middle_grey=lmt_params['middleGrey'],
+                                    min_exposure=lmt_params['minExposure'],
+                                    max_exposure=lmt_params['maxExposure'],
+                                    lut_resolution_1d=lmt_lut_resolution_1d)
+    config_data['colorSpaces'].append(lmt_shaper)
+
+    shaper_input_scale_generic_log2 = 1.0
+
+    # Log 2 shaper name and CTL transforms bundled up
+    lmt_shaper_data = [
+        lmt_shaper_name,
+        '%s/utilities/ACESlib.OCIO_shaper_log2_to_lin_param.a1.0.0.ctl',
+        '%s/utilities/ACESlib.OCIO_shaper_lin_to_log2_param.a1.0.0.ctl',
+        shaper_input_scale_generic_log2,
+        lmt_params
+    ]
+
+    sorted_LMTs = sorted(lmt_info.iteritems(), key=lambda x: x[1])
+    print(sorted_LMTs)
+    for lmt in sorted_LMTs:
+        (lmt_name, lmt_values) = lmt
+        cs = create_ACES_LMT(
+            lmt_values['transformUserName'],
+            lmt_values,
+            lmt_shaper_data,
+            lmt_lut_resolution_1d,
+            lmt_lut_resolution_3d,
+            cleanup)
+        config_data['colorSpaces'].append(cs)
+
+    #
+    # ACES RRT with the supplied ODT
+    #
+    def create_ACES_RRT_plus_ODT(odt_name,
+                                 odt_values,
+                                 shaper_info,
+                                 lut_resolution_1d=1024,
+                                 lut_resolution_3d=64,
+                                 cleanup=True):
+        cs = ColorSpace("%s" % odt_name)
+        cs.description = "%s - %s Output Transform" % (
+            odt_values['transformUserNamePrefix'], odt_name)
+        cs.equality_group = ''
+        cs.family = 'Output'
+        cs.is_data = False
+
+        pprint.pprint(odt_values)
+
+        #
+        # Generate the shaper transform
+        #
+        # if 'shaperCTL' in odtValues:
+        (shaper_name,
+         shaper_to_ACES_CTL,
+         shaper_from_ACES_CTL,
+         shaper_input_scale,
+         shaper_params) = shaper_info
+
+        if 'legalRange' in odt_values:
+            shaper_params['legalRange'] = odt_values['legalRange']
+        else:
+            shaper_params['legalRange'] = 0
+
+        shaper_lut = "%s_to_aces.spi1d" % shaper_name
+        if (not os.path.exists(lut_directory + "/" + shaper_lut)):
+            ctls = [shaper_to_ACES_CTL % aces_CTL_directory]
+
+            # Remove spaces and parentheses
+            shaper_lut = shaper_lut.replace(
+                ' ', '_').replace(')', '_').replace('(', '_')
+
+            generate_1d_LUT_from_CTL(
+                lut_directory + "/" + shaper_lut,
+                ctls,
+                lut_resolution_1d,
+                'float',
+                1.0 / shaper_input_scale,
+                1.0,
+                shaper_params,
+                cleanup,
+                aces_CTL_directory)
+
+        shaper_OCIO_transform = {
+            'type': 'lutFile',
+            'path': shaper_lut,
+            'interpolation': 'linear',
+            'direction': 'inverse'
+        }
+
+        #
+        # Generate the forward transform
+        #
+        cs.from_reference_transforms = []
+
+        if 'transformLUT' in odt_values:
+            # Copy into the lut dir
+            transform_LUT_file_name = os.path.basename(
+                odt_values['transformLUT'])
+            lut = lut_directory + "/" + transform_LUT_file_name
+            shutil.copy(odt_values['transformLUT'], lut)
+
+            cs.from_reference_transforms.append(shaper_OCIO_transform)
+            cs.from_reference_transforms.append({
+                'type': 'lutFile',
+                'path': transform_LUT_file_name,
+                'interpolation': 'tetrahedral',
+                'direction': 'forward'
+            })
+        elif 'transformCTL' in odt_values:
+            # shaperLut
+
+            ctls = [
+                shaper_to_ACES_CTL % aces_CTL_directory,
+                '%s/rrt/RRT.a1.0.0.ctl' % aces_CTL_directory,
+                '%s/odt/%s' % (aces_CTL_directory, odt_values['transformCTL'])
+            ]
+            lut = "%s.RRT.a1.0.0.%s.spi3d" % (shaper_name, odt_name)
+
+            # Remove spaces and parentheses
+            lut = lut.replace(' ', '_').replace(')', '_').replace('(', '_')
+
+            generate_3d_LUT_from_CTL(lut_directory + "/" + lut,
+                                     # shaperLUT,
+                                     ctls,
+                                     lut_resolution_3d,
+                                     'float',
+                                     1.0 / shaper_input_scale,
+                                     1.0,
+                                     shaper_params,
+                                     cleanup,
+                                     aces_CTL_directory)
+
+            cs.from_reference_transforms.append(shaper_OCIO_transform)
+            cs.from_reference_transforms.append({
+                'type': 'lutFile',
+                'path': lut,
+                'interpolation': 'tetrahedral',
+                'direction': 'forward'
+            })
+
+        #
+        # Generate the inverse transform
+        #
+        cs.to_reference_transforms = []
+
+        if 'transformLUTInverse' in odt_values:
+            # Copy into the lut dir
+            transform_LUT_inverse_file_name = os.path.basename(
+                odt_values['transformLUTInverse'])
+            lut = lut_directory + "/" + transform_LUT_inverse_file_name
+            shutil.copy(odt_values['transformLUTInverse'], lut)
+
+            cs.to_reference_transforms.append({
+                'type': 'lutFile',
+                'path': transform_LUT_inverse_file_name,
+                'interpolation': 'tetrahedral',
+                'direction': 'forward'
+            })
+
+            shaper_inverse = shaper_OCIO_transform.copy()
+            shaper_inverse['direction'] = 'forward'
+            cs.to_reference_transforms.append(shaper_inverse)
+        elif 'transformCTLInverse' in odt_values:
+            ctls = [
+                '%s/odt/%s' % (
+                    aces_CTL_directory, odt_values['transformCTLInverse']),
+                '%s/rrt/InvRRT.a1.0.0.ctl' % aces_CTL_directory,
+                shaper_from_ACES_CTL % aces_CTL_directory
+            ]
+            lut = "InvRRT.a1.0.0.%s.%s.spi3d" % (odt_name, shaper_name)
+
+            # Remove spaces and parentheses
+            lut = lut.replace(' ', '_').replace(')', '_').replace('(', '_')
+
+            generate_3d_LUT_from_CTL(
+                lut_directory + "/" + lut,
+                # None,
+                ctls,
+                lut_resolution_3d,
+                'half',
+                1.0,
+                shaper_input_scale,
+                shaper_params,
+                cleanup,
+                aces_CTL_directory)
+
+            cs.to_reference_transforms.append({
+                'type': 'lutFile',
+                'path': lut,
+                'interpolation': 'tetrahedral',
+                'direction': 'forward'
+            })
+
+            shaper_inverse = shaper_OCIO_transform.copy()
+            shaper_inverse['direction'] = 'forward'
+            cs.to_reference_transforms.append(shaper_inverse)
+
+        return cs
+
+    #
+    # RRT/ODT shaper options
+    #
+    shaper_data = {}
+
+    # Log 2 shaper
+    log2_shaper_name = shaper_name
+    log2_params = {
+        'middleGrey': 0.18,
+        'minExposure': -6.0,
+        'maxExposure': 6.5
+    }
+    log2_shaper = create_generic_log(
+        name=log2_shaper_name,
+        middle_grey=log2_params['middleGrey'],
+        min_exposure=log2_params['minExposure'],
+        max_exposure=log2_params['maxExposure'])
+    config_data['colorSpaces'].append(log2_shaper)
+
+    shaper_input_scale_generic_log2 = 1.0
+
+    # Log 2 shaper name and CTL transforms bundled up
+    log2_shaper_data = [
+        log2_shaper_name,
+        '%s/utilities/ACESlib.OCIO_shaper_log2_to_lin_param.a1.0.0.ctl',
+        '%s/utilities/ACESlib.OCIO_shaper_lin_to_log2_param.a1.0.0.ctl',
+        shaper_input_scale_generic_log2,
+        log2_params
+    ]
+
+    shaper_data[log2_shaper_name] = log2_shaper_data
+
+    #
+    # Shaper that also includes the AP1 primaries
+    # - Needed for some LUT baking steps
+    #
+    log2_shaper_AP1 = create_generic_log(
+        name=log2_shaper_name,
+        middle_grey=log2_params['middleGrey'],
+        min_exposure=log2_params['minExposure'],
+        max_exposure=log2_params['maxExposure'])
+    log2_shaper_AP1.name = "%s - AP1" % log2_shaper_AP1.name
+    # AP1 primaries to AP0 primaries
+    log2_shaper_AP1.to_reference_transforms.append({
+        'type': 'matrix',
+        'matrix': mat44_from_mat33(ACES_AP1_to_AP0),
+        'direction': 'forward'
+    })
+    config_data['colorSpaces'].append(log2_shaper_AP1)
+
+    #
+    # Choose your shaper
+    #
+    rrt_shaper_name = log2_shaper_name
+    rrt_shaper = log2_shaper_data
+
+    #
+    # RRT + ODT Combinations
+    #
+    sorted_odts = sorted(odt_info.iteritems(), key=lambda x: x[1])
+    print(sorted_odts)
+    for odt in sorted_odts:
+        (odt_name, odt_values) = odt
+
+        # Have to handle ODTs that can generate either legal or full output
+        if odt_name in ['Academy.Rec2020_100nits_dim.a1.0.0',
+                        'Academy.Rec709_100nits_dim.a1.0.0',
+                        'Academy.Rec709_D60sim_100nits_dim.a1.0.0']:
+            odt_name_legal = '%s - Legal' % odt_values['transformUserName']
+        else:
+            odt_name_legal = odt_values['transformUserName']
+
+        odt_legal = odt_values.copy()
+        odt_legal['legalRange'] = 1
+
+        cs = create_ACES_RRT_plus_ODT(
+            odt_name_legal,
+            odt_legal,
+            rrt_shaper,
+            lut_resolution_1d,
+            lut_resolution_3d,
+            cleanup)
+        config_data['colorSpaces'].append(cs)
+
+        # Create a display entry using this color space
+        config_data['displays'][odt_name_legal] = {
+            'Linear': ACES,
+            'Log': ACEScc,
+            'Output Transform': cs}
+
+        if odt_name in ['Academy.Rec2020_100nits_dim.a1.0.0',
+                        'Academy.Rec709_100nits_dim.a1.0.0',
+                        'Academy.Rec709_D60sim_100nits_dim.a1.0.0']:
+            print("Generating full range ODT for %s" % odt_name)
+
+            odt_name_full = "%s - Full" % odt_values['transformUserName']
+            odt_full = odt_values.copy()
+            odt_full['legalRange'] = 0
+
+            cs_full = create_ACES_RRT_plus_ODT(
+                odt_name_full,
+                odt_full,
+                rrt_shaper,
+                lut_resolution_1d,
+                lut_resolution_3d,
+                cleanup)
+            config_data['colorSpaces'].append(cs_full)
+
+            # Create a display entry using this color space
+            config_data['displays'][odt_name_full] = {
+                'Linear': ACES,
+                'Log': ACEScc,
+                'Output Transform': cs_full}
+
+    #
+    # Generic Matrix transform
+    #
+    def create_generic_matrix(name='matrix',
+                              from_reference_values=[],
+                              to_reference_values=[]):
+        cs = ColorSpace(name)
+        cs.description = "The %s color space" % name
+        cs.equality_group = name
+        cs.family = 'Utility'
+        cs.is_data = False
+
+        cs.to_reference_transforms = []
+        if to_reference_values != []:
+            for matrix in to_reference_values:
+                cs.to_reference_transforms.append({
+                    'type': 'matrix',
+                    'matrix': mat44_from_mat33(matrix),
+                    'direction': 'forward'
+                })
+
+        cs.from_reference_transforms = []
+        if from_reference_values != []:
+            for matrix in from_reference_values:
+                cs.from_reference_transforms.append({
+                    'type': 'matrix',
+                    'matrix': mat44_from_mat33(matrix),
+                    'direction': 'forward'
+                })
+
+        return cs
+
+    cs = create_generic_matrix('XYZ', from_reference_values=[ACES_AP0_to_XYZ])
+    config_data['colorSpaces'].append(cs)
+
+    cs = create_generic_matrix(
+        'Linear - AP1', to_reference_values=[ACES_AP1_to_AP0])
+    config_data['colorSpaces'].append(cs)
+
+    # ACES to Linear, P3D60 primaries
+    XYZ_to_P3D60 = [2.4027414142, -0.8974841639, -0.3880533700,
+                    -0.8325796487, 1.7692317536, 0.0237127115,
+                    0.0388233815, -0.0824996856, 1.0363685997]
+
+    cs = create_generic_matrix(
+        'Linear - P3-D60',
+        from_reference_values=[ACES_AP0_to_XYZ, XYZ_to_P3D60])
+    config_data['colorSpaces'].append(cs)
+
+    # ACES to Linear, P3D60 primaries
+    XYZ_to_P3DCI = [2.7253940305, -1.0180030062, -0.4401631952,
+                    -0.7951680258, 1.6897320548, 0.0226471906,
+                    0.0412418914, -0.0876390192, 1.1009293786]
+
+    cs = create_generic_matrix(
+        'Linear - P3-DCI',
+        from_reference_values=[ACES_AP0_to_XYZ, XYZ_to_P3DCI])
+    config_data['colorSpaces'].append(cs)
+
+    # ACES to Linear, Rec 709 primaries
+    XYZ_to_Rec709 = [3.2409699419, -1.5373831776, -0.4986107603,
+                     -0.9692436363, 1.8759675015, 0.0415550574,
+                     0.0556300797, -0.2039769589, 1.0569715142]
+
+    cs = create_generic_matrix(
+        'Linear - Rec.709',
+        from_reference_values=[ACES_AP0_to_XYZ, XYZ_to_Rec709])
+    config_data['colorSpaces'].append(cs)
+
+    # ACES to Linear, Rec 2020 primaries
+    XYZ_to_Rec2020 = [1.7166511880, -0.3556707838, -0.2533662814,
+                      -0.6666843518, 1.6164812366, 0.0157685458,
+                      0.0176398574, -0.0427706133, 0.9421031212]
+
+    cs = create_generic_matrix(
+        'Linear - Rec.2020',
+        from_reference_values=[ACES_AP0_to_XYZ, XYZ_to_Rec2020])
+    config_data['colorSpaces'].append(cs)
+
+    print("generateLUTs - end")
+    return config_data
+
+
+def generate_baked_LUTs(odt_info,
+                        shaper_name,
+                        baked_directory,
+                        config_path,
+                        lut_resolution_1d,
+                        lut_resolution_3d,
+                        lut_resolution_shaper=1024):
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    # Add the legal and full variations into this list
+    odt_info_C = dict(odt_info)
+    for odt_CTL_name, odt_values in odt_info.iteritems():
+        if odt_CTL_name in ['Academy.Rec2020_100nits_dim.a1.0.0',
+                            'Academy.Rec709_100nits_dim.a1.0.0',
+                            'Academy.Rec709_D60sim_100nits_dim.a1.0.0']:
+            odt_name = odt_values["transformUserName"]
+
+            odt_values_legal = dict(odt_values)
+            odt_values_legal["transformUserName"] = "%s - Legal" % odt_name
+            odt_info_C["%s - Legal" % odt_CTL_name] = odt_values_legal
+
+            odt_values_full = dict(odt_values)
+            odt_values_full["transformUserName"] = "%s - Full" % odt_name
+            odt_info_C["%s - Full" % odt_CTL_name] = odt_values_full
+
+            del (odt_info_C[odt_CTL_name])
+
+    for odt_CTL_name, odt_values in odt_info_C.iteritems():
+        odt_prefix = odt_values["transformUserNamePrefix"]
+        odt_name = odt_values["transformUserName"]
+
+        # For Photoshop
+        for input_space in ["ACEScc", "ACESproxy"]:
+            args = ["--iconfig", config_path,
+                    "-v",
+                    "--inputspace", input_space]
+            args += ["--outputspace", "%s" % odt_name]
+            args += ["--description",
+                     "%s - %s for %s data" % (odt_prefix,
+                                              odt_name,
+                                              input_space)]
+            args += ["--shaperspace", shaper_name,
+                     "--shapersize", str(lut_resolution_shaper)]
+            args += ["--cubesize", str(lut_resolution_3d)]
+            args += ["--format",
+                     "icc",
+                     "%s/photoshop/%s for %s.icc" % (baked_directory,
+                                                     odt_name,
+                                                     input_space)]
+
+            bake_LUT = Process(description="bake a LUT",
+                               cmd="ociobakelut",
+                               args=args)
+            bake_LUT.execute()
+
+        # For Flame, Lustre
+        for input_space in ["ACEScc", "ACESproxy"]:
+            args = ["--iconfig", config_path,
+                    "-v",
+                    "--inputspace", input_space]
+            args += ["--outputspace", "%s" % odt_name]
+            args += ["--description",
+                     "%s - %s for %s data" % (
+                         odt_prefix, odt_name, input_space)]
+            args += ["--shaperspace", shaper_name,
+                     "--shapersize", str(lut_resolution_shaper)]
+            args += ["--cubesize", str(lut_resolution_3d)]
+
+            fargs = ["--format", "flame", "%s/flame/%s for %s Flame.3dl" % (
+                baked_directory, odt_name, input_space)]
+            bake_LUT = Process(description="bake a LUT",
+                               cmd="ociobakelut",
+                               args=(args + fargs))
+            bake_LUT.execute()
+
+            largs = ["--format", "lustre", "%s/lustre/%s for %s Lustre.3dl" % (
+                baked_directory, odt_name, input_space)]
+            bake_LUT = Process(description="bake a LUT",
+                               cmd="ociobakelut",
+                               args=(args + largs))
+            bake_LUT.execute()
+
+        # For Maya, Houdini
+        for input_space in ["ACEScg", "ACES2065-1"]:
+            args = ["--iconfig", config_path,
+                    "-v",
+                    "--inputspace", input_space]
+            args += ["--outputspace", "%s" % odt_name]
+            args += ["--description",
+                     "%s - %s for %s data" % (
+                         odt_prefix, odt_name, input_space)]
+            if input_space == 'ACEScg':
+                lin_shaper_name = "%s - AP1" % shaper_name
+            else:
+                lin_shaper_name = shaper_name
+            args += ["--shaperspace", lin_shaper_name,
+                     "--shapersize", str(lut_resolution_shaper)]
+
+            args += ["--cubesize", str(lut_resolution_3d)]
+
+            margs = ["--format", "cinespace", "%s/maya/%s for %s Maya.csp" % (
+                baked_directory, odt_name, input_space)]
+            bake_LUT = Process(description="bake a LUT",
+                               cmd="ociobakelut",
+                               args=(args + margs))
+            bake_LUT.execute()
+
+            hargs = ["--format", "houdini",
+                     "%s/houdini/%s for %s Houdini.lut" % (
+                         baked_directory, odt_name, input_space)]
+            bake_LUT = Process(description="bake a LUT",
+                               cmd="ociobakelut",
+                               args=(args + hargs))
+            bake_LUT.execute()
+
+
+def create_config_dir(config_directory, bake_secondary_LUTs):
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    dirs = [config_directory, "%s/luts" % config_directory]
+    if bake_secondary_LUTs:
+        dirs.extend(["%s/baked" % config_directory,
+                     "%s/baked/flame" % config_directory,
+                     "%s/baked/photoshop" % config_directory,
+                     "%s/baked/houdini" % config_directory,
+                     "%s/baked/lustre" % config_directory,
+                     "%s/baked/maya" % config_directory])
+
+    for d in dirs:
+        not os.path.exists(d) and os.mkdir(d)
+
+
+def get_transform_info(ctl_transform):
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    # TODO: Use *with* statement.
+    fp = open(ctl_transform, 'rb')
+
+    # Read lines
+    lines = fp.readlines()
+
+    # Grab transform ID and User Name
+    transform_ID = lines[1][3:].split('<')[1].split('>')[1].strip()
+    # print(transformID)
+    transform_user_name = '-'.join(
+        lines[2][3:].split('<')[1].split('>')[1].split('-')[1:]).strip()
+    transform_user_name_prefix = (
+        lines[2][3:].split('<')[1].split('>')[1].split('-')[0].strip())
+    # print(transformUserName)
+    fp.close()
+
+    return transform_ID, transform_user_name, transform_user_name_prefix
+
+
+def get_ODT_info(aces_CTL_directory):
+    """
+    Object description.
+
+    For versions after WGR9.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    # TODO: Investigate usage of *files_walker* definition here.
+    # Credit to Alex Fry for the original approach here
+    odt_dir = os.path.join(aces_CTL_directory, "odt")
+    all_odt = []
+    for dir_name, subdir_list, file_list in os.walk(odt_dir):
+        for fname in file_list:
+            all_odt.append((os.path.join(dir_name, fname)))
+
+    odt_CTLs = [x for x in all_odt if
+                ("InvODT" not in x) and (os.path.split(x)[-1][0] != '.')]
+
+    # print odtCTLs
+
+    odts = {}
+
+    for odt_CTL in odt_CTLs:
+        odt_tokens = os.path.split(odt_CTL)
+        # print(odtTokens)
+
+        # Handle nested directories
+        odt_path_tokens = os.path.split(odt_tokens[-2])
+        odt_dir = odt_path_tokens[-1]
+        while odt_path_tokens[-2][-3:] != 'odt':
+            odt_path_tokens = os.path.split(odt_path_tokens[-2])
+            odt_dir = os.path.join(odt_path_tokens[-1], odt_dir)
+
+        # Build full name
+        # print("odtDir : %s" % odtDir)
+        transform_CTL = odt_tokens[-1]
+        # print(transformCTL)
+        odt_name = string.join(transform_CTL.split('.')[1:-1], '.')
+        # print(odtName)
+
+        # Find id, user name and user name prefix
+        (transform_ID,
+         transform_user_name,
+         transform_user_name_prefix) = get_transform_info(
+            "%s/odt/%s/%s" % (aces_CTL_directory, odt_dir, transform_CTL))
+
+        # Find inverse
+        transform_CTL_inverse = "InvODT.%s.ctl" % odt_name
+        if not os.path.exists(
+                os.path.join(odt_tokens[-2], transform_CTL_inverse)):
+            transform_CTL_inverse = None
+        # print(transformCTLInverse)
+
+        # Add to list of ODTs
+        odts[odt_name] = {}
+        odts[odt_name]['transformCTL'] = os.path.join(odt_dir, transform_CTL)
+        if transform_CTL_inverse != None:
+            odts[odt_name]['transformCTLInverse'] = os.path.join(
+                odt_dir, transform_CTL_inverse)
+
+        odts[odt_name]['transformID'] = transform_ID
+        odts[odt_name]['transformUserNamePrefix'] = transform_user_name_prefix
+        odts[odt_name]['transformUserName'] = transform_user_name
+
+        print("ODT : %s" % odt_name)
+        print("\tTransform ID               : %s" % transform_ID)
+        print("\tTransform User Name Prefix : %s" % transform_user_name_prefix)
+        print("\tTransform User Name        : %s" % transform_user_name)
+        print("\tForward ctl                : %s" % (
+            odts[odt_name]['transformCTL']))
+        if 'transformCTLInverse' in odts[odt_name]:
+            print("\tInverse ctl                : %s" % (
+                odts[odt_name]['transformCTLInverse']))
+        else:
+            print("\tInverse ctl                : %s" % "None")
+
+    print("\n")
+
+    return odts
+
+
+def get_LMT_info(aces_CTL_directory):
+    """
+    Object description.
+
+    For versions after WGR9.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    # TODO: Investigate refactoring with previous definition.
+
+    # Credit to Alex Fry for the original approach here
+    lmt_dir = os.path.join(aces_CTL_directory, "lmt")
+    all_lmt = []
+    for dir_name, subdir_list, file_list in os.walk(lmt_dir):
+        for fname in file_list:
+            all_lmt.append((os.path.join(dir_name, fname)))
+
+    lmt_CTLs = [x for x in all_lmt if
+                ("InvLMT" not in x) and ("README" not in x) and (
+                    os.path.split(x)[-1][0] != '.')]
+
+    # print lmtCTLs
+
+    lmts = {}
+
+    for lmt_CTL in lmt_CTLs:
+        lmt_tokens = os.path.split(lmt_CTL)
+        # print(lmtTokens)
+
+        # Handle nested directories
+        lmt_path_tokens = os.path.split(lmt_tokens[-2])
+        lmt_dir = lmt_path_tokens[-1]
+        while lmt_path_tokens[-2][-3:] != 'ctl':
+            lmt_path_tokens = os.path.split(lmt_path_tokens[-2])
+            lmt_dir = os.path.join(lmt_path_tokens[-1], lmt_dir)
+
+        # Build full name
+        # print("lmtDir : %s" % lmtDir)
+        transform_CTL = lmt_tokens[-1]
+        # print(transformCTL)
+        lmt_name = string.join(transform_CTL.split('.')[1:-1], '.')
+        # print(lmtName)
+
+        # Find id, user name and user name prefix
+        (transform_ID,
+         transform_user_name,
+         transform_user_name_prefix) = get_transform_info(
+            "%s/%s/%s" % (aces_CTL_directory, lmt_dir, transform_CTL))
+
+        # Find inverse
+        transform_CTL_inverse = "InvLMT.%s.ctl" % lmt_name
+        if not os.path.exists(
+                os.path.join(lmt_tokens[-2], transform_CTL_inverse)):
+            transform_CTL_inverse = None
+        # print(transformCTLInverse)
+
+        # Add to list of LMTs
+        lmts[lmt_name] = {}
+        lmts[lmt_name]['transformCTL'] = os.path.join(lmt_dir, transform_CTL)
+        if transform_CTL_inverse != None:
+            # TODO: Check unresolved *odt_name* referemce.
+            lmts[odt_name]['transformCTLInverse'] = os.path.join(
+                lmt_dir, transform_CTL_inverse)
+
+        lmts[lmt_name]['transformID'] = transform_ID
+        lmts[lmt_name]['transformUserNamePrefix'] = transform_user_name_prefix
+        lmts[lmt_name]['transformUserName'] = transform_user_name
+
+        print("LMT : %s" % lmt_name)
+        print("\tTransform ID               : %s" % transform_ID)
+        print("\tTransform User Name Prefix : %s" % transform_user_name_prefix)
+        print("\tTransform User Name        : %s" % transform_user_name)
+        print("\t Forward ctl : %s" % lmts[lmt_name]['transformCTL'])
+        if 'transformCTLInverse' in lmts[lmt_name]:
+            print("\t Inverse ctl : %s" % (
+                lmts[lmt_name]['transformCTLInverse']))
+        else:
+            print("\t Inverse ctl : %s" % "None")
+
+    print("\n")
+
+    return lmts
+
+
+def create_ACES_config(aces_CTL_directory,
+                       config_directory,
+                       lut_resolution_1d=4096,
+                       lut_resolution_3d=64,
+                       bake_secondary_LUTs=True,
+                       cleanup=True):
+    """
+    Creates the ACES configuration.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    # Get ODT names and CTL paths
+    odt_info = get_ODT_info(aces_CTL_directory)
+
+    # Get ODT names and CTL paths
+    lmt_info = get_LMT_info(aces_CTL_directory)
+
+    # Create config dir
+    create_config_dir(config_directory, bake_secondary_LUTs)
+
+    # Generate config data and LUTs for different transforms
+    lut_directory = "%s/luts" % config_directory
+    shaper_name = 'Output Shaper'
+    config_data = generate_LUTs(odt_info,
+                                lmt_info,
+                                shaper_name,
+                                aces_CTL_directory,
+                                lut_directory,
+                                lut_resolution_1d,
+                                lut_resolution_3d,
+                                cleanup)
+
+    # Create the config using the generated LUTs
+    print("Creating generic config")
+    config = create_config(config_data)
+    print("\n\n\n")
+
+    # Write the config to disk
+    write_config(config, "%s/config.ocio" % config_directory)
+
+    # Create a config that will work well with Nuke using the previously
+    # generated LUTs.
+    print("Creating Nuke-specific config")
+    nuke_config = create_config(config_data, nuke=True)
+    print("\n\n\n")
+
+    # Write the config to disk
+    write_config(nuke_config, "%s/nuke_config.ocio" % config_directory)
+
+    # Bake secondary LUTs using the config
+    if bake_secondary_LUTs:
+        generate_baked_LUTs(odt_info,
+                            shaper_name,
+                            "%s/baked" % config_directory,
+                            "%s/config.ocio" % config_directory,
+                            lut_resolution_1d,
+                            lut_resolution_3d,
+                            lut_resolution_1d)
+
+    return True
+
+
+def main():
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    import optparse
+
+    p = optparse.OptionParser(description='An OCIO config generation script',
+                              prog='createACESConfig',
+                              version='createACESConfig 0.1',
+                              usage='%prog [options]')
+    p.add_option('--acesCTLDir', '-a', default=os.environ.get(
+        'ACES_OCIO_CTL_DIRECTORY', None))
+    p.add_option('--configDir', '-c', default=os.environ.get(
+        'ACES_OCIO_CONFIGURATION_DIRECTORY', None))
+    p.add_option('--lutResolution1d', default=4096)
+    p.add_option('--lutResolution3d', default=64)
+    p.add_option('--dontBakeSecondaryLUTs', action="store_true")
+    p.add_option('--keepTempImages', action="store_true")
+
+    options, arguments = p.parse_args()
+
+    #
+    # Get options
+    #
+    aces_CTL_directory = options.acesCTLDir
+    config_directory = options.configDir
+    lut_resolution_1d = int(options.lutResolution1d)
+    lut_resolution_3d = int(options.lutResolution3d)
+    bake_secondary_LUTs = not (options.dontBakeSecondaryLUTs)
+    cleanup_temp_images = not (options.keepTempImages)
+
+    try:
+        args_start = sys.argv.index('--') + 1
+        args = sys.argv[args_start:]
+    except:
+        args_start = len(sys.argv) + 1
+        args = []
+
+    print("command line : \n%s\n" % " ".join(sys.argv))
+
+    # TODO: Use assertion and mention environment variables.
+    if not aces_CTL_directory:
+        print("process: No ACES CTL directory specified")
+        return
+    if not config_directory:
+        print("process: No configuration directory specified")
+        return
+    #
+    # Generate the configuration
+    #
+    return create_ACES_config(aces_CTL_directory,
+                              config_directory,
+                              lut_resolution_1d,
+                              lut_resolution_3d,
+                              bake_secondary_LUTs,
+                              cleanup_temp_images)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/aces_1.0.0/python/aces_ocio/create_arri_colorspaces.py b/aces_1.0.0/python/aces_ocio/create_arri_colorspaces.py
new file mode 100644 (file)
index 0000000..be56c9d
--- /dev/null
@@ -0,0 +1,219 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Implements support for *ARRI* colorspaces conversions and transfer functions.
+"""
+
+import array
+import math
+
+import aces_ocio.generate_lut as genlut
+from aces_ocio.utilities import ColorSpace, mat44_from_mat33
+
+
+__author__ = 'ACES Developers'
+__copyright__ = 'Copyright (C) 2014 - 2015 - ACES Developers'
+__license__ = ''
+__maintainer__ = 'ACES Developers'
+__email__ = 'aces@oscars.org'
+__status__ = 'Production'
+
+__all__ = ['create_log_c',
+           'create_colorspaces']
+
+
+def create_log_c(gamut,
+                 transfer_function,
+                 exposure_index,
+                 name,
+                 lut_directory,
+                 lut_resolution_1d):
+    """
+    Object description.
+
+    LogC to ACES.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    name = "%s (EI%s) - %s" % (transfer_function, exposure_index, gamut)
+    if transfer_function == "":
+        name = "Linear - %s" % gamut
+    if gamut == "":
+        name = "%s (EI%s)" % (transfer_function, exposure_index)
+
+    cs = ColorSpace(name)
+    cs.description = name
+    cs.equality_group = ''
+    cs.family = 'ARRI'
+    cs.is_data = False
+
+    # Globals
+    IDT_maker_version = "0.08"
+
+    nominal_EI = 400.0
+    black_signal = 0.003907
+    mid_gray_signal = 0.01
+    encoding_gain = 0.256598
+    encoding_offset = 0.391007
+
+    def gain_for_EI(EI):
+        return (math.log(EI / nominal_EI) / math.log(2) * (
+            0.89 - 1) / 3 + 1) * encoding_gain
+
+    def log_c_inverse_parameters_for_EI(EI):
+        cut = 1.0 / 9.0
+        slope = 1.0 / (cut * math.log(10))
+        offset = math.log10(cut) - slope * cut
+        gain = EI / nominal_EI
+        gray = mid_gray_signal / gain
+        # The higher the EI, the lower the gamma
+        enc_gain = gain_for_EI(EI)
+        enc_offset = encoding_offset
+        for i in range(0, 3):
+            nz = ((95.0 / 1023.0 - enc_offset) / enc_gain - offset) / slope
+            enc_offset = encoding_offset - math.log10(1 + nz) * enc_gain
+        # Calculate some intermediate values
+        a = 1.0 / gray
+        b = nz - black_signal / gray
+        e = slope * a * enc_gain
+        f = enc_gain * (slope * b + offset) + enc_offset
+        # Manipulations so we can return relative exposure
+        s = 4 / (0.18 * EI)
+        t = black_signal
+        b += a * t
+        a *= s
+        f += e * t
+        e *= s
+
+        return {'a': a,
+                'b': b,
+                'cut': (cut - b) / a,
+                'c': enc_gain,
+                'd': enc_offset,
+                'e': e,
+                'f': f}
+
+    def log_c_to_linear(code_value, exposure_index):
+        p = log_c_inverse_parameters_for_EI(exposure_index)
+        breakpoint = p['e'] * p['cut'] + p['f']
+        if (code_value > breakpoint):
+            linear = ((pow(10, (code_value / 1023.0 - p['d']) / p['c']) -
+                       p['b']) / p['a'])
+        else:
+            linear = (code_value / 1023.0 - p['f']) / p['e']
+
+        # print(codeValue, linear)
+        return linear
+
+
+    cs.to_reference_transforms = []
+
+    if transfer_function == "V3 LogC":
+        data = array.array('f', "\0" * lut_resolution_1d * 4)
+        for c in range(lut_resolution_1d):
+            data[c] = log_c_to_linear(1023.0 * c / (lut_resolution_1d - 1),
+                                      int(exposure_index))
+
+        lut = "%s_to_linear.spi1d" % (
+            "%s_%s" % (transfer_function, exposure_index))
+
+        # Remove spaces and parentheses
+        lut = lut.replace(' ', '_').replace(')', '_').replace('(', '_')
+
+        genlut.write_SPI_1d(lut_directory + "/" + lut,
+                            0.0,
+                            1.0,
+                            data,
+                            lut_resolution_1d,
+                            1)
+
+        # print("Writing %s" % lut)
+        cs.to_reference_transforms.append({
+            'type': 'lutFile',
+            'path': lut,
+            'interpolation': 'linear',
+            'direction': 'forward'
+        })
+
+    if gamut == 'Wide Gamut':
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': mat44_from_mat33([0.680206, 0.236137, 0.083658,
+                                      0.085415, 1.017471, -0.102886,
+                                      0.002057, -0.062563, 1.060506]),
+            'direction': 'forward'
+        })
+
+    cs.from_reference_transforms = []
+    return cs
+
+
+def create_colorspaces(lut_directory, lut_resolution_1d):
+    """
+    Generates the colorspace conversions.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    colorspaces = []
+
+    transfer_function = "V3 LogC"
+    gamut = "Wide Gamut"
+
+    # EIs = [160.0, 200.0, 250.0, 320.0, 400.0, 500.0, 640.0, 800.0,
+    # 1000.0, 1280.0, 1600.0, 2000.0, 2560.0, 3200.0]
+    EIs = [160, 200, 250, 320, 400, 500, 640, 800,
+           1000, 1280, 1600, 2000, 2560, 3200]
+    default_EI = 800
+
+    # Full conversion
+    for EI in EIs:
+        log_c_EI_full = create_log_c(
+            gamut,
+            transfer_function,
+            EI,
+            "LogC",
+            lut_directory,
+            lut_resolution_1d)
+        colorspaces.append(log_c_EI_full)
+
+    # Linearization only
+    for EI in [800]:
+        log_c_EI_linearization = create_log_c(
+            "",
+            transfer_function,
+            EI,
+            "LogC",
+            lut_directory,
+            lut_resolution_1d)
+        colorspaces.append(log_c_EI_linearization)
+
+    # Primaries
+    log_c_EI_primaries = create_log_c(
+        gamut,
+        "",
+        default_EI,
+        "LogC",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(log_c_EI_primaries)
+
+    return colorspaces
diff --git a/aces_1.0.0/python/aces_ocio/create_canon_colorspaces.py b/aces_1.0.0/python/aces_ocio/create_canon_colorspaces.py
new file mode 100644 (file)
index 0000000..5ac15b3
--- /dev/null
@@ -0,0 +1,270 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Implements support for *Canon* colorspaces conversions and transfer functions.
+"""
+
+import array
+
+import aces_ocio.generate_lut as genlut
+from aces_ocio.utilities import ColorSpace
+
+__author__ = 'ACES Developers'
+__copyright__ = 'Copyright (C) 2014 - 2015 - ACES Developers'
+__license__ = ''
+__maintainer__ = 'ACES Developers'
+__email__ = 'aces@oscars.org'
+__status__ = 'Production'
+
+__all__ = ['create_c_log',
+           'create_colorspaces']
+
+
+def create_c_log(gamut,
+                 transfer_function,
+                 name,
+                 lut_directory,
+                 lut_resolution_1d):
+    """
+    Object description.
+
+    Canon-Log to ACES.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    name = "%s - %s" % (transfer_function, gamut)
+    if transfer_function == "":
+        name = "Linear - %s" % gamut
+    if gamut == "":
+        name = "%s" % transfer_function
+
+    cs = ColorSpace(name)
+    cs.description = name
+    cs.equality_group = ''
+    cs.family = 'Canon'
+    cs.is_data = False
+
+    def legal_to_full(codeValue):
+        return (codeValue - 64.0) / (940.0 - 64.0)
+
+    def c_log_to_linear(codeValue):
+        # log = fullToLegal(c1 * log10(c2*linear + 1) + c3)
+        # linear = (pow(10, (legalToFul(log) - c3)/c1) - 1)/c2
+        c1 = 0.529136
+        c2 = 10.1596
+        c3 = 0.0730597
+
+        linear = (pow(10.0, (legal_to_full(codeValue) - c3) / c1) - 1.0) / c2
+        linear *= 0.9
+        # print(codeValue, linear)
+        return linear
+
+    cs.to_reference_transforms = []
+
+    if transfer_function == "Canon-Log":
+        data = array.array('f', "\0" * lut_resolution_1d * 4)
+        for c in range(lut_resolution_1d):
+            data[c] = c_log_to_linear(1023.0 * c / (lut_resolution_1d - 1))
+
+        lut = "%s_to_linear.spi1d" % transfer_function
+        genlut.write_SPI_1d(lut_directory + "/" + lut,
+                            0.0,
+                            1.0,
+                            data,
+                            lut_resolution_1d,
+                            1)
+
+        cs.to_reference_transforms.append({
+            'type': 'lutFile',
+            'path': lut,
+            'interpolation': 'linear',
+            'direction': 'forward'})
+
+    if gamut == 'Rec. 709 Daylight':
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': [0.561538969, 0.402060105, 0.036400926, 0.0,
+                       0.092739623, 0.924121198, -0.016860821, 0.0,
+                       0.084812961, 0.006373835, 0.908813204, 0.0,
+                       0, 0, 0, 1.0],
+            'direction': 'forward'})
+    elif gamut == 'Rec. 709 Tungsten':
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': [0.566996399, 0.365079418, 0.067924183, 0.0,
+                       0.070901044, 0.880331008, 0.048767948, 0.0,
+                       0.073013542, -0.066540862, 0.99352732, 0.0,
+                       0, 0, 0, 1.0],
+            'direction': 'forward'})
+    elif gamut == 'DCI-P3 Daylight':
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': [0.607160575, 0.299507286, 0.093332140, 0.0,
+                       0.004968120, 1.050982224, -0.055950343, 0.0,
+                       -0.007839939, 0.000809127, 1.007030813, 0.0,
+                       0, 0, 0, 1.0],
+            'direction': 'forward'})
+    elif gamut == 'DCI-P3 Tungsten':
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': [0.650279125, 0.253880169, 0.095840706, 0.0,
+                       -0.026137986, 1.017900530, 0.008237456, 0.0,
+                       0.007757558, -0.063081669, 1.055324110, 0.0,
+                       0, 0, 0, 1.0],
+            'direction': 'forward'})
+    elif gamut == 'Cinema Gamut Daylight':
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': [0.763064455, 0.149021161, 0.087914384, 0.0,
+                       0.003657457, 1.10696038, -0.110617837, 0.0,
+                       -0.009407794, -0.218383305, 1.227791099, 0.0,
+                       0, 0, 0, 1.0],
+            'direction': 'forward'})
+    elif gamut == 'Cinema Gamut Tungsten':
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': [0.817416293, 0.090755698, 0.091828009, 0.0,
+                       -0.035361374, 1.065690585, -0.030329211, 0.0,
+                       0.010390366, -0.299271107, 1.288880741, 0.0,
+                       0, 0, 0, 1.0],
+            'direction': 'forward'})
+
+    cs.from_reference_transforms = []
+    return cs
+
+
+def create_colorspaces(lut_directory, lut_resolution_1d):
+    """
+    Generates the colorspace conversions.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    colorspaces = []
+
+    # Full conversion
+    c_log_1 = create_c_log(
+        "Rec. 709 Daylight",
+        "Canon-Log",
+        "Canon-Log",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(c_log_1)
+
+    c_log_2 = create_c_log(
+        "Rec. 709 Tungsten",
+        "Canon-Log",
+        "Canon-Log",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(c_log_2)
+
+    c_log_3 = create_c_log(
+        "DCI-P3 Daylight",
+        "Canon-Log",
+        "Canon-Log",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(c_log_3)
+
+    c_log_4 = create_c_log(
+        "DCI-P3 Tungsten",
+        "Canon-Log",
+        "Canon-Log",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(c_log_4)
+
+    c_log_5 = create_c_log(
+        "Cinema Gamut Daylight",
+        "Canon-Log",
+        "Canon-Log",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(c_log_5)
+
+    c_log_6 = create_c_log(
+        "Cinema Gamut Tungsten",
+        "Canon-Log",
+        "Canon-Log",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(c_log_6)
+
+    # Linearization only
+    c_log_7 = create_c_log(
+        '',
+        "Canon-Log",
+        "Canon-Log",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(c_log_7)
+
+    # Primaries only
+    c_log_8 = create_c_log(
+        "Rec. 709 Daylight",
+        "",
+        "Canon-Log",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(c_log_8)
+
+    c_log_9 = create_c_log(
+        "Rec. 709 Tungsten",
+        "",
+        "Canon-Log",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(c_log_9)
+
+    c_log_10 = create_c_log(
+        "DCI-P3 Daylight",
+        "",
+        "Canon-Log",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(c_log_10)
+
+    c_log_11 = create_c_log(
+        "DCI-P3 Tungsten",
+        "",
+        "Canon-Log",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(c_log_11)
+
+    c_log_12 = create_c_log(
+        "Cinema Gamut Daylight",
+        "",
+        "Canon-Log",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(c_log_12)
+
+    c_log_13 = create_c_log(
+        "Cinema Gamut Tungsten",
+        "",
+        "Canon-Log",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(c_log_13)
+
+    return colorspaces
diff --git a/aces_1.0.0/python/aces_ocio/create_red_colorspaces.py b/aces_1.0.0/python/aces_ocio/create_red_colorspaces.py
new file mode 100644 (file)
index 0000000..4c09151
--- /dev/null
@@ -0,0 +1,239 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Implements support for *RED* colorspaces conversions and transfer functions.
+"""
+
+import array
+
+import aces_ocio.generate_lut as genlut
+from aces_ocio.utilities import ColorSpace, mat44_from_mat33
+
+__author__ = 'ACES Developers'
+__copyright__ = 'Copyright (C) 2014 - 2015 - ACES Developers'
+__license__ = ''
+__maintainer__ = 'ACES Developers'
+__email__ = 'aces@oscars.org'
+__status__ = 'Production'
+
+__all__ = ['create_RED_log_film',
+           'create_colorspaces']
+
+
+def create_RED_log_film(gamut,
+                        transfer_function,
+                        name,
+                        lut_directory,
+                        lut_resolution_1d):
+    """
+    Object description.
+
+    RED colorspaces to ACES.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    name = "%s - %s" % (transfer_function, gamut)
+    if transfer_function == "":
+        name = "Linear - %s" % gamut
+    if gamut == "":
+        name = "%s" % transfer_function
+
+    cs = ColorSpace(name)
+    cs.description = name
+    cs.equality_group = ''
+    cs.family = 'RED'
+    cs.is_data = False
+
+    def cineon_to_linear(code_value):
+        n_gamma = 0.6
+        black_point = 95.0
+        white_point = 685.0
+        code_value_to_density = 0.002
+
+        black_linear = pow(10.0, (black_point - white_point) * (
+            code_value_to_density / n_gamma))
+        code_linear = pow(10.0, (code_value - white_point) * (
+            code_value_to_density / n_gamma))
+
+        return (code_linear - black_linear) / (1.0 - black_linear)
+
+    cs.to_reference_transforms = []
+
+    if transfer_function == 'REDlogFilm':
+        data = array.array('f', "\0" * lut_resolution_1d * 4)
+        for c in range(lut_resolution_1d):
+            data[c] = cineon_to_linear(1023.0 * c / (lut_resolution_1d - 1))
+
+        lut = "CineonLog_to_linear.spi1d"
+        genlut.write_SPI_1d(lut_directory + "/" + lut,
+                            0.0,
+                            1.0,
+                            data,
+                            lut_resolution_1d,
+                            1)
+
+        cs.to_reference_transforms.append({
+            'type': 'lutFile',
+            'path': lut,
+            'interpolation': 'linear',
+            'direction': 'forward'})
+
+    if gamut == 'DRAGONcolor':
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': mat44_from_mat33([0.532279, 0.376648, 0.091073,
+                                      0.046344, 0.974513, -0.020860,
+                                      -0.053976, -0.000320, 1.054267]),
+            'direction': 'forward'})
+    elif gamut == 'DRAGONcolor2':
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': mat44_from_mat33([0.468452, 0.331484, 0.200064,
+                                      0.040787, 0.857658, 0.101553,
+                                      -0.047504, -0.000282, 1.047756]),
+            'direction': 'forward'})
+    elif gamut == 'REDcolor2':
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': mat44_from_mat33([0.480997, 0.402289, 0.116714,
+                                      -0.004938, 1.000154, 0.004781,
+                                      -0.105257, 0.025320, 1.079907]),
+            'direction': 'forward'})
+    elif gamut == 'REDcolor3':
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': mat44_from_mat33([0.512136, 0.360370, 0.127494,
+                                      0.070377, 0.903884, 0.025737,
+                                      -0.020824, 0.017671, 1.003123]),
+            'direction': 'forward'})
+    elif gamut == 'REDcolor4':
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': mat44_from_mat33([0.474202, 0.333677, 0.192121,
+                                      0.065164, 0.836932, 0.097901,
+                                      -0.019281, 0.016362, 1.002889]),
+            'direction': 'forward'})
+
+    cs.from_reference_transforms = []
+    return cs
+
+
+def create_colorspaces(lut_directory, lut_resolution_1d):
+    """
+    Generates the colorspace conversions.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    colorspaces = []
+
+    # Full conversion
+    RED_log_film_dragon = create_RED_log_film(
+        "DRAGONcolor",
+        "REDlogFilm",
+        "REDlogFilm",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(RED_log_film_dragon)
+
+    RED_log_film_dragon2 = create_RED_log_film(
+        "DRAGONcolor2",
+        "REDlogFilm",
+        "REDlogFilm",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(RED_log_film_dragon2)
+
+    RED_log_film_color2 = create_RED_log_film(
+        "REDcolor2",
+        "REDlogFilm",
+        "REDlogFilm",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(RED_log_film_color2)
+
+    RED_log_film_color3 = create_RED_log_film(
+        "REDcolor3",
+        "REDlogFilm",
+        "REDlogFilm",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(RED_log_film_color3)
+
+    RED_log_film_color4 = create_RED_log_film(
+        "REDcolor4",
+        "REDlogFilm",
+        "REDlogFilm",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(RED_log_film_color4)
+
+    # Linearization only
+    RED_log_film_dragon = create_RED_log_film(
+        "",
+        "REDlogFilm",
+        "REDlogFilm",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(RED_log_film_dragon)
+
+    # Primaries only
+    RED_log_film_dragon = create_RED_log_film(
+        "DRAGONcolor",
+        "",
+        "REDlogFilm",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(RED_log_film_dragon)
+
+    RED_log_film_dragon2 = create_RED_log_film(
+        "DRAGONcolor2",
+        "",
+        "REDlogFilm",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(RED_log_film_dragon2)
+
+    RED_log_film_color2 = create_RED_log_film(
+        "REDcolor2",
+        "",
+        "REDlogFilm",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(RED_log_film_color2)
+
+    RED_log_film_color3 = create_RED_log_film(
+        "REDcolor3",
+        "",
+        "REDlogFilm",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(RED_log_film_color3)
+
+    RED_log_film_color4 = create_RED_log_film(
+        "REDcolor4",
+        "",
+        "REDlogFilm",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(RED_log_film_color4)
+
+    return colorspaces
diff --git a/aces_1.0.0/python/aces_ocio/create_sony_colorspaces.py b/aces_1.0.0/python/aces_ocio/create_sony_colorspaces.py
new file mode 100644 (file)
index 0000000..3867e87
--- /dev/null
@@ -0,0 +1,342 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Implements support for *Sony* colorspaces conversions and transfer functions.
+"""
+
+import array
+
+import aces_ocio.generate_lut as genlut
+from aces_ocio.utilities import ColorSpace, mat44_from_mat33
+
+__author__ = 'ACES Developers'
+__copyright__ = 'Copyright (C) 2014 - 2015 - ACES Developers'
+__license__ = ''
+__maintainer__ = 'ACES Developers'
+__email__ = 'aces@oscars.org'
+__status__ = 'Production'
+
+__all__ = ['create_s_log',
+           'create_colorspaces']
+
+
+def create_s_log(gamut,
+                 transfer_function,
+                 name,
+                 lut_directory,
+                 lut_resolution_1d):
+    """
+    Object description.
+
+    SLog to ACES.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    name = "%s - %s" % (transfer_function, gamut)
+    if transfer_function == "":
+        name = "Linear - %s" % gamut
+    if gamut == "":
+        name = "%s" % transfer_function
+
+    cs = ColorSpace(name)
+    cs.description = name
+    cs.equality_group = ''
+    cs.family = 'Sony'
+    cs.is_data = False
+
+    def s_log1_to_linear(s_log):
+        b = 64.
+        ab = 90.
+        w = 940.
+
+        if (s_log >= ab):
+            linear = ((pow(10.,
+                           ( ((s_log - b) /
+                              (w - b) - 0.616596 - 0.03) / 0.432699)) -
+                       0.037584) * 0.9)
+        else:
+            linear = (
+                         ((s_log - b) / (
+                             w - b) - 0.030001222851889303) / 5.) * 0.9
+        return linear
+
+    def s_log2_to_linear(s_log):
+        b = 64.
+        ab = 90.
+        w = 940.
+
+        if (s_log >= ab):
+            linear = ((219. * (pow(10.,
+                                   (((s_log - b) /
+                                     (w - b) - 0.616596 - 0.03) / 0.432699)) -
+                               0.037584) / 155.) * 0.9)
+        else:
+            linear = (((s_log - b) / (
+                w - b) - 0.030001222851889303) / 3.53881278538813) * 0.9
+        return linear
+
+    def s_log3_to_linear(code_value):
+        if code_value >= (171.2102946929):
+            linear = (pow(10.0, ((code_value - 420.0) / 261.5)) *
+                      (0.18 + 0.01) - 0.01)
+        else:
+            linear = (code_value - 95.0) * 0.01125000 / (171.2102946929 - 95.0)
+        # print(codeValue, linear)
+        return linear
+
+    cs.to_reference_transforms = []
+
+    if transfer_function == "S-Log1":
+        data = array.array('f', "\0" * lut_resolution_1d * 4)
+        for c in range(lut_resolution_1d):
+            data[c] = s_log1_to_linear(1023.0 * c / (lut_resolution_1d - 1))
+
+        lut = "%s_to_linear.spi1d" % transfer_function
+        genlut.write_SPI_1d(lut_directory + "/" + lut,
+                            0.0,
+                            1.0,
+                            data,
+                            lut_resolution_1d,
+                            1)
+
+        # print("Writing %s" % lut)
+
+        cs.to_reference_transforms.append({
+            'type': 'lutFile',
+            'path': lut,
+            'interpolation': 'linear',
+            'direction': 'forward'
+        })
+    elif transfer_function == "S-Log2":
+        data = array.array('f', "\0" * lut_resolution_1d * 4)
+        for c in range(lut_resolution_1d):
+            data[c] = s_log2_to_linear(1023.0 * c / (lut_resolution_1d - 1))
+
+        lut = "%s_to_linear.spi1d" % transfer_function
+        genlut.write_SPI_1d(lut_directory + "/" + lut,
+                            0.0,
+                            1.0,
+                            data,
+                            lut_resolution_1d,
+                            1)
+
+        # print("Writing %s" % lut)
+
+        cs.to_reference_transforms.append({
+            'type': 'lutFile',
+            'path': lut,
+            'interpolation': 'linear',
+            'direction': 'forward'
+        })
+    elif transfer_function == "S-Log3":
+        data = array.array('f', "\0" * lut_resolution_1d * 4)
+        for c in range(lut_resolution_1d):
+            data[c] = s_log3_to_linear(1023.0 * c / (lut_resolution_1d - 1))
+
+        lut = "%s_to_linear.spi1d" % transfer_function
+        genlut.write_SPI_1d(lut_directory + "/" + lut,
+                            0.0,
+                            1.0,
+                            data,
+                            lut_resolution_1d,
+                            1)
+
+        # print("Writing %s" % lut)
+
+        cs.to_reference_transforms.append({
+            'type': 'lutFile',
+            'path': lut,
+            'interpolation': 'linear',
+            'direction': 'forward'
+        })
+
+    if gamut == 'S-Gamut':
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': mat44_from_mat33(
+                [0.754338638, 0.133697046, 0.111968437,
+                 0.021198141, 1.005410934, -0.026610548,
+                 -0.009756991, 0.004508563, 1.005253201]),
+            'direction': 'forward'})
+    elif gamut == 'S-Gamut Daylight':
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': mat44_from_mat33(
+                [0.8764457030, 0.0145411681, 0.1090131290,
+                 0.0774075345, 0.9529571767, -0.0303647111,
+                 0.0573564351, -0.1151066335, 1.0577501984]),
+            'direction': 'forward'})
+    elif gamut == 'S-Gamut Tungsten':
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': mat44_from_mat33(
+                [1.0110238740, -0.1362526051, 0.1252287310,
+                 0.1011994504, 0.9562196265, -0.0574190769,
+                 0.0600766530, -0.1010185315, 1.0409418785]),
+            'direction': 'forward'})
+    elif gamut == 'S-Gamut3.Cine':
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': mat44_from_mat33(
+                [0.6387886672, 0.2723514337, 0.0888598992,
+                 -0.0039159061, 1.0880732308, -0.0841573249,
+                 -0.0299072021, -0.0264325799, 1.0563397820]),
+            'direction': 'forward'})
+    elif gamut == 'S-Gamut3':
+        cs.to_reference_transforms.append({
+            'type': 'matrix',
+            'matrix': mat44_from_mat33(
+                [0.7529825954, 0.1433702162, 0.1036471884,
+                 0.0217076974, 1.0153188355, -0.0370265329,
+                 -0.0094160528, 0.0033704179, 1.0060456349]),
+            'direction': 'forward'})
+
+    cs.from_reference_transforms = []
+    return cs
+
+
+def create_colorspaces(lut_directory, lut_resolution_1d):
+    """
+    Generates the colorspace conversions.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    colorspaces = []
+
+    # S-Log1
+    s_log1_s_gamut = create_s_log(
+        "S-Gamut",
+        "S-Log1",
+        "S-Log",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(s_log1_s_gamut)
+
+    # S-Log2
+    s_log2_s_gamut = create_s_log(
+        "S-Gamut",
+        "S-Log2",
+        "S-Log2",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(s_log2_s_gamut)
+
+    s_log2_s_gamut_daylight = create_s_log(
+        "S-Gamut Daylight",
+        "S-Log2",
+        "S-Log2",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(s_log2_s_gamut_daylight)
+
+    s_log2_s_gamut_tungsten = create_s_log(
+        "S-Gamut Tungsten",
+        "S-Log2",
+        "S-Log2",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(s_log2_s_gamut_tungsten)
+
+    # S-Log3
+    s_log3_s_gamut3Cine = create_s_log(
+        "S-Gamut3.Cine",
+        "S-Log3",
+        "S-Log3",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(s_log3_s_gamut3Cine)
+
+    s_log3_s_gamut3 = create_s_log(
+        "S-Gamut3",
+        "S-Log3",
+        "S-Log3",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(s_log3_s_gamut3)
+
+    # Linearization only
+    s_log1 = create_s_log(
+        "",
+        "S-Log1",
+        "S-Log",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(s_log1)
+
+    s_log2 = create_s_log(
+        "",
+        "S-Log2",
+        "S-Log2",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(s_log2)
+
+    s_log3 = create_s_log(
+        "",
+        "S-Log3",
+        "S-Log3",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(s_log3)
+
+    # Primaries only
+    s_gamut = create_s_log(
+        "S-Gamut",
+        "",
+        "S-Log",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(s_gamut)
+
+    s_gamut_daylight = create_s_log(
+        "S-Gamut Daylight",
+        "",
+        "S-Log2",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(s_gamut_daylight)
+
+    s_gamut_tungsten = create_s_log(
+        "S-Gamut Tungsten",
+        "",
+        "S-Log2",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(s_gamut_tungsten)
+
+    s_gamut3Cine = create_s_log(
+        "S-Gamut3.Cine",
+        "",
+        "S-Log3",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(s_gamut3Cine)
+
+    s_gamut3 = create_s_log(
+        "S-Gamut3",
+        "",
+        "S-Log3",
+        lut_directory,
+        lut_resolution_1d)
+    colorspaces.append(s_gamut3)
+
+    return colorspaces
diff --git a/aces_1.0.0/python/aces_ocio/generate_lut.py b/aces_1.0.0/python/aces_ocio/generate_lut.py
new file mode 100644 (file)
index 0000000..e0d4dfa
--- /dev/null
@@ -0,0 +1,638 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Defines objects to generate various kind of 1d, 2d and 3d LUTs in various file
+formats.
+"""
+
+import array
+import os
+import sys
+
+import OpenImageIO as oiio
+
+from aces_ocio.process import Process
+
+__author__ = 'ACES Developers'
+__copyright__ = 'Copyright (C) 2014 - 2015 - ACES Developers'
+__license__ = ''
+__maintainer__ = 'ACES Developers'
+__email__ = 'aces@oscars.org'
+__status__ = 'Production'
+
+__all__ = ['generate_1d_LUT_image',
+           'write_SPI_1d',
+           'generate_1d_LUT_from_image',
+           'generate_3d_LUT_image',
+           'generate_3d_LUT_from_image',
+           'apply_CTL_to_image',
+           'convert_bit_depth',
+           'generate_1d_LUT_from_CTL',
+           'correct_LUT_image',
+           'generate_3d_LUT_from_CTL',
+           'main']
+
+
+def generate_1d_LUT_image(ramp_1d_path,
+                          resolution=1024,
+                          min_value=0.0,
+                          max_value=1.0):
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    # print("Generate 1d LUT image - %s" % ramp1dPath)
+
+    # open image
+    format = os.path.splitext(ramp_1d_path)[1]
+    ramp = oiio.ImageOutput.create(ramp_1d_path)
+
+    # set image specs
+    spec = oiio.ImageSpec()
+    spec.set_format(oiio.FLOAT)
+    # spec.format.basetype = oiio.FLOAT
+    spec.width = resolution
+    spec.height = 1
+    spec.nchannels = 3
+
+    ramp.open(ramp_1d_path, spec, oiio.Create)
+
+    data = array.array("f",
+                       "\0" * spec.width * spec.height * spec.nchannels * 4)
+    for i in range(resolution):
+        value = float(i) / (resolution - 1) * (
+            max_value - min_value) + min_value
+        data[i * spec.nchannels + 0] = value
+        data[i * spec.nchannels + 1] = value
+        data[i * spec.nchannels + 2] = value
+
+    ramp.write_image(spec.format, data)
+    ramp.close()
+
+
+def write_SPI_1d(filename, from_min, from_max, data, entries, channels):
+    """
+    Object description.
+
+    Credit to *Alex Fry* for the original single channel version of the spi1d
+    writer.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    f = file(filename, 'w')
+    f.write("Version 1\n")
+    f.write("From %f %f\n" % (from_min, from_max))
+    f.write("Length %d\n" % entries)
+    f.write("Components %d\n" % (min(3, channels)))
+    f.write("{\n")
+    for i in range(0, entries):
+        entry = ""
+        for j in range(0, min(3, channels)):
+            entry = "%s %s" % (entry, data[i * channels + j])
+        f.write("        %s\n" % entry)
+    f.write("}\n")
+    f.close()
+
+
+def generate_1d_LUT_from_image(ramp_1d_path,
+                               output_path=None,
+                               min_value=0.0,
+                               max_value=1.0):
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    if output_path is None:
+        output_path = ramp_1d_path + ".spi1d"
+
+    # open image
+    ramp = oiio.ImageInput.open(ramp_1d_path)
+
+    # get image specs
+    spec = ramp.spec()
+    type = spec.format.basetype
+    width = spec.width
+    height = spec.height
+    channels = spec.nchannels
+
+    # get data
+    # Force data to be read as float. The Python API doesn't handle
+    # half-floats well yet.
+    type = oiio.FLOAT
+    data = ramp.read_image(type)
+
+    write_SPI_1d(output_path, min_value, max_value, data, width, channels)
+
+
+def generate_3d_LUT_image(ramp_3d_path, resolution=32):
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    args = ["--generate",
+            "--cubesize",
+            str(resolution),
+            "--maxwidth",
+            str(resolution * resolution),
+            "--output",
+            ramp_3d_path]
+    lut_extract = Process(description="generate a 3d LUT image",
+                          cmd="ociolutimage",
+                          args=args)
+    lut_extract.execute()
+
+
+def generate_3d_LUT_from_image(ramp_3d_path, output_path=None, resolution=32):
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    if output_path is None:
+        output_path = ramp_3d_path + ".spi3d"
+
+    args = ["--extract",
+            "--cubesize",
+            str(resolution),
+            "--maxwidth",
+            str(resolution * resolution),
+            "--input",
+            ramp_3d_path,
+            "--output",
+            output_path]
+    lut_extract = Process(description="extract a 3d LUT",
+                          cmd="ociolutimage",
+                          args=args)
+    lut_extract.execute()
+
+
+def apply_CTL_to_image(input_image,
+                       output_image,
+                       ctl_paths=[],
+                       input_scale=1.0,
+                       output_scale=1.0,
+                       global_params={},
+                       aces_CTL_directory=None):
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    if len(ctl_paths) > 0:
+        ctlenv = os.environ
+        if aces_CTL_directory != None:
+            if os.path.split(aces_CTL_directory)[1] != "utilities":
+                ctl_module_path = "%s/utilities" % aces_CTL_directory
+            else:
+                ctl_module_path = aces_CTL_directory
+            ctlenv['CTL_MODULE_PATH'] = ctl_module_path
+
+        args = []
+        for ctl in ctl_paths:
+            args += ['-ctl', ctl]
+        args += ["-force"]
+        # args += ["-verbose"]
+        args += ["-input_scale", str(input_scale)]
+        args += ["-output_scale", str(output_scale)]
+        args += ["-global_param1", "aIn", "1.0"]
+        for key, value in global_params.iteritems():
+            args += ["-global_param1", key, str(value)]
+        args += [input_image]
+        args += [output_image]
+
+        # print("args : %s" % args)
+
+        ctlp = Process(description="a ctlrender process",
+                       cmd="ctlrender",
+                       args=args, env=ctlenv)
+
+        ctlp.execute()
+
+
+def convert_bit_depth(input_image, output_image, depth):
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    args = [input_image,
+            "-d",
+            depth,
+            "-o",
+            output_image]
+    convert = Process(description="convert image bit depth",
+                      cmd="oiiotool",
+                      args=args)
+    convert.execute()
+
+
+def generate_1d_LUT_from_CTL(lut_path,
+                             ctl_paths,
+                             lut_resolution=1024,
+                             identity_LUT_bit_depth='half',
+                             input_scale=1.0,
+                             output_scale=1.0,
+                             global_params={},
+                             cleanup=True,
+                             aces_CTL_directory=None,
+                             min_value=0.0,
+                             max_value=1.0):
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    # print(lutPath)
+    # print(ctlPaths)
+
+    lut_path_base = os.path.splitext(lut_path)[0]
+
+    identity_LUT_image_float = lut_path_base + ".float.tiff"
+    generate_1d_LUT_image(identity_LUT_image_float,
+                          lut_resolution,
+                          min_value,
+                          max_value)
+
+    if identity_LUT_bit_depth != 'half':
+        identity_LUT_image = lut_path_base + ".uint16.tiff"
+        convert_bit_depth(identity_LUT_image_float,
+                          identity_LUT_image,
+                          identity_LUT_bit_depth)
+    else:
+        identity_LUT_image = identity_LUT_image_float
+
+    transformed_LUT_image = lut_path_base + ".transformed.exr"
+    apply_CTL_to_image(identity_LUT_image,
+                       transformed_LUT_image,
+                       ctl_paths,
+                       input_scale,
+                       output_scale,
+                       global_params,
+                       aces_CTL_directory)
+
+    generate_1d_LUT_from_image(transformed_LUT_image,
+                               lut_path,
+                               min_value,
+                               max_value)
+
+    if cleanup:
+        os.remove(identity_LUT_image)
+        if identity_LUT_image != identity_LUT_image_float:
+            os.remove(identity_LUT_image_float)
+        os.remove(transformed_LUT_image)
+
+
+def correct_LUT_image(transformed_LUT_image,
+                      corrected_LUT_image,
+                      lut_resolution):
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    # open image
+    transformed = oiio.ImageInput.open(transformed_LUT_image)
+
+    # get image specs
+    transformed_spec = transformed.spec()
+    type = transformed_spec.format.basetype
+    width = transformed_spec.width
+    height = transformed_spec.height
+    channels = transformed_spec.nchannels
+
+    # rotate or not
+    if width != lut_resolution * lut_resolution or height != lut_resolution:
+        print(("Correcting image as resolution is off. "
+               "Found %d x %d. Expected %d x %d") % (
+                  width,
+                  height,
+                  lut_resolution * lut_resolution,
+                  lut_resolution))
+        print("Generating %s" % corrected_LUT_image)
+
+        #
+        # We're going to generate a new correct image
+        #
+
+        # Get the source data
+        # Force data to be read as float. The Python API doesn't handle
+        # half-floats well yet.
+        type = oiio.FLOAT
+        source_data = transformed.read_image(type)
+
+        format = os.path.splitext(corrected_LUT_image)[1]
+        correct = oiio.ImageOutput.create(corrected_LUT_image)
+
+        # set image specs
+        correct_spec = oiio.ImageSpec()
+        correct_spec.set_format(oiio.FLOAT)
+        correct_spec.width = height
+        correct_spec.height = width
+        correct_spec.nchannels = channels
+
+        correct.open(corrected_LUT_image, correct_spec, oiio.Create)
+
+        dest_data = array.array("f",
+                                ("\0" * correct_spec.width *
+                                 correct_spec.height *
+                                 correct_spec.nchannels * 4))
+        for j in range(0, correct_spec.height):
+            for i in range(0, correct_spec.width):
+                for c in range(0, correct_spec.nchannels):
+                    # print(i, j, c)
+                    dest_data[(correct_spec.nchannels *
+                               correct_spec.width * j +
+                               correct_spec.nchannels * i + c)] = (
+                        source_data[correct_spec.nchannels *
+                                    correct_spec.width * j +
+                                    correct_spec.nchannels * i + c])
+
+        correct.write_image(correct_spec.format, dest_data)
+        correct.close()
+    else:
+        # shutil.copy(transformedLUTImage, correctedLUTImage)
+        corrected_LUT_image = transformed_LUT_image
+
+    transformed.close()
+
+    return corrected_LUT_image
+
+
+def generate_3d_LUT_from_CTL(lut_path,
+                             ctl_paths,
+                             lut_resolution=64,
+                             identity_LUT_bit_depth='half',
+                             input_scale=1.0,
+                             output_scale=1.0,
+                             global_params={},
+                             cleanup=True,
+                             aces_CTL_directory=None):
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    # print(lutPath)
+    # print(ctlPaths)
+
+    lut_path_base = os.path.splitext(lut_path)[0]
+
+    identity_LUT_image_float = lut_path_base + ".float.tiff"
+    generate_3d_LUT_image(identity_LUT_image_float, lut_resolution)
+
+    if identity_LUT_bit_depth != 'half':
+        identity_LUT_image = (lut_path_base +
+                              "." +
+                              identity_LUT_bit_depth +
+                              ".tiff")
+        convert_bit_depth(identity_LUT_image_float,
+                          identity_LUT_image,
+                          identity_LUT_bit_depth)
+    else:
+        identity_LUT_image = identity_LUT_image_float
+
+    transformed_LUT_image = lut_path_base + ".transformed.exr"
+    apply_CTL_to_image(identity_LUT_image,
+                       transformed_LUT_image,
+                       ctl_paths,
+                       input_scale,
+                       output_scale,
+                       global_params,
+                       aces_CTL_directory)
+
+    corrected_LUT_image = lut_path_base + ".correct.exr"
+    corrected_LUT_image = correct_LUT_image(transformed_LUT_image,
+                                            corrected_LUT_image,
+                                            lut_resolution)
+
+    generate_3d_LUT_from_image(corrected_LUT_image, lut_path, lut_resolution)
+
+    if cleanup:
+        os.remove(identity_LUT_image)
+        if identity_LUT_image != identity_LUT_image_float:
+            os.remove(identity_LUT_image_float)
+        os.remove(transformed_LUT_image)
+        if corrected_LUT_image != transformed_LUT_image:
+            os.remove(corrected_LUT_image)
+            # os.remove(correctedLUTImage)
+
+
+def main():
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    import optparse
+
+    p = optparse.OptionParser(
+        description='A utility to generate LUTs from CTL',
+        prog='generateLUT',
+        version='0.01',
+        usage='%prog [options]')
+
+    p.add_option('--lut', '-l', type="string", default="")
+    p.add_option('--ctl', '-c', type="string", action="append")
+    p.add_option('--lut_resolution_1d', '', type="int", default=1024)
+    p.add_option('--lut_resolution_3d', '', type="int", default=33)
+    p.add_option('--ctlReleasePath', '-r', type="string", default="")
+    p.add_option('--bitDepth', '-b', type="string", default="float")
+    p.add_option('--keepTempImages', '', action="store_true")
+    p.add_option('--minValue', '', type="float", default=0.0)
+    p.add_option('--maxValue', '', type="float", default=1.0)
+    p.add_option('--inputScale', '', type="float", default=1.0)
+    p.add_option('--outputScale', '', type="float", default=1.0)
+    p.add_option('--ctlRenderParam', '-p', type="string", nargs=2,
+                 action="append")
+
+    p.add_option('--generate1d', '', action="store_true")
+    p.add_option('--generate3d', '', action="store_true")
+
+    options, arguments = p.parse_args()
+
+    #
+    # Get options
+    # 
+    lut = options.lut
+    ctls = options.ctl
+    lut_resolution_1d = options.lut_resolution_1d
+    lut_resolution_3d = options.lut_resolution_3d
+    min_value = options.minValue
+    max_value = options.maxValue
+    input_scale = options.inputScale
+    output_scale = options.outputScale
+    ctl_release_path = options.ctlReleasePath
+    generate_1d = options.generate1d is True
+    generate_3d = options.generate3d is True
+    bitdepth = options.bitDepth
+    cleanup = not options.keepTempImages
+
+    params = {}
+    if options.ctlRenderParam != None:
+        for param in options.ctlRenderParam:
+            params[param[0]] = float(param[1])
+
+    try:
+        args_start = sys.argv.index('--') + 1
+        args = sys.argv[args_start:]
+    except:
+        args_start = len(sys.argv) + 1
+        args = []
+
+    # print("command line : \n%s\n" % " ".join(sys.argv))
+
+    #
+    # Generate LUTs
+    #
+    if generate_1d:
+        print("1D LUT generation options")
+    else:
+        print("3D LUT generation options")
+
+    print("lut                 : %s" % lut)
+    print("ctls                : %s" % ctls)
+    print("lut res 1d          : %s" % lut_resolution_1d)
+    print("lut res 3d          : %s" % lut_resolution_3d)
+    print("min value           : %s" % min_value)
+    print("max value           : %s" % max_value)
+    print("input scale         : %s" % input_scale)
+    print("output scale        : %s" % output_scale)
+    print("ctl render params   : %s" % params)
+    print("ctl release path    : %s" % ctl_release_path)
+    print("bit depth of input  : %s" % bitdepth)
+    print("cleanup temp images : %s" % cleanup)
+
+    if generate_1d:
+        generate_1d_LUT_from_CTL(lut,
+                                 ctls,
+                                 lut_resolution_1d,
+                                 bitdepth,
+                                 input_scale,
+                                 output_scale,
+                                 params,
+                                 cleanup,
+                                 ctl_release_path,
+                                 min_value,
+                                 max_value)
+
+    elif generate_3d:
+        generate_3d_LUT_from_CTL(lut,
+                                 ctls,
+                                 lut_resolution_3d,
+                                 bitdepth,
+                                 input_scale,
+                                 output_scale,
+                                 params,
+                                 cleanup,
+                                 ctl_release_path)
+    else:
+        print(("\n\nNo LUT generated. "
+               "You must choose either 1D or 3D LUT generation\n\n"))
+
+
+if __name__ == '__main__':
+    main()
+
diff --git a/aces_1.0.0/python/aces_ocio/process.py b/aces_1.0.0/python/aces_ocio/process.py
new file mode 100755 (executable)
index 0000000..6445b46
--- /dev/null
@@ -0,0 +1,757 @@
+#!/usr/bin/env python\r
+# -*- coding: utf-8 -*-\r
+\r
+"""\r
+A process wrapper class that maintains the text output and execution status of\r
+a process or a list of other process wrappers which carry such data.\r
+"""\r
+\r
+import os\r
+import sys\r
+import traceback\r
+\r
+__author__ = 'ACES Developers'\r
+__copyright__ = 'Copyright (C) 2014 - 2015 - ACES Developers'\r
+__license__ = ''\r
+__maintainer__ = 'ACES Developers'\r
+__email__ = 'aces@oscars.org'\r
+__status__ = 'Production'\r
+\r
+__all__ = ['read_text',\r
+           'write_text',\r
+           'Process',\r
+           'ProcessList',\r
+           'main']\r
+\r
+\r
+def read_text(text_file):\r
+    """\r
+    Object description.\r
+\r
+    Parameters\r
+    ----------\r
+    parameter : type\r
+        Parameter description.\r
+\r
+    Returns\r
+    -------\r
+    type\r
+         Return value description.\r
+    """\r
+\r
+    if (text_file != ""):\r
+        fp = open(text_file, 'rb')\r
+        # Create a text/plain message\r
+        text = (fp.read())\r
+        fp.close()\r
+    return text\r
+\r
+\r
+def write_text(text, text_file):\r
+    """\r
+    Object description.\r
+\r
+    Parameters\r
+    ----------\r
+    parameter : type\r
+        Parameter description.\r
+\r
+    Returns\r
+    -------\r
+    type\r
+         Return value description.\r
+    """\r
+\r
+    if (text_file != ""):\r
+        fp = open(text_file, 'wb')\r
+        # Create a text/plain message\r
+        fp.write(text)\r
+        fp.close()\r
+    return text\r
+\r
+\r
+class Process:\r
+    """\r
+    A process with logged output.\r
+    """\r
+\r
+    def __init__(self,\r
+                 description=None,\r
+                 cmd=None,\r
+                 args=[],\r
+                 cwd=None,\r
+                 env=None,\r
+                 batch_wrapper=False):\r
+        """\r
+        Initialize the standard class variables.\r
+\r
+        Parameters\r
+        ----------\r
+        parameter : type\r
+            Parameter description.\r
+\r
+        Returns\r
+        -------\r
+        type\r
+             Return value description.\r
+        """\r
+\r
+        self.cmd = cmd\r
+        if not description:\r
+            self.description = cmd\r
+        else:\r
+            self.description = description\r
+        self.status = None\r
+        self.args = args\r
+        self.start = None\r
+        self.end = None\r
+        self.log = []\r
+        self.echo = True\r
+        self.cwd = cwd\r
+        self.env = env\r
+        self.batch_wrapper = batch_wrapper\r
+        self.process_keys = []\r
+\r
+    def get_elapsed_seconds(self):\r
+        """\r
+        Object description.\r
+\r
+        Parameters\r
+        ----------\r
+        parameter : type\r
+            Parameter description.\r
+\r
+        Returns\r
+        -------\r
+        type\r
+             Return value description.\r
+        """\r
+\r
+        import math\r
+\r
+        if self.end and self.start:\r
+            delta = (self.end - self.start)\r
+            formatted = "%s.%s" % (delta.days * 86400 + delta.seconds,\r
+                                   int(math.floor(delta.microseconds / 1e3)))\r
+        else:\r
+            formatted = None\r
+        return formatted\r
+\r
+    def write_key(self, write_dict, key=None, value=None, start_stop=None):\r
+        """\r
+        Writes a key / value pair in a supported format.\r
+\r
+        Parameters\r
+        ----------\r
+        parameter : type\r
+            Parameter description.\r
+\r
+        Returns\r
+        -------\r
+        type\r
+             Return value description.\r
+        """\r
+\r
+        if key != None and (value != None or start_stop != None):\r
+            indent = '\t' * write_dict['indentationLevel']\r
+            if write_dict['format'] == 'xml':\r
+                if start_stop == 'start':\r
+                    write_dict['logHandle'].write("%s<%s>\n" % (indent, key))\r
+                elif start_stop == 'stop':\r
+                    write_dict['logHandle'].write("%s</%s>\n" % (indent, key))\r
+                else:\r
+                    write_dict['logHandle'].write(\r
+                        "%s<%s>%s</%s>\n" % (indent, key, value, key))\r
+            else:  # writeDict['format'] == 'txt':\r
+                write_dict['logHandle'].write(\r
+                    "%s%40s : %s\n" % (indent, key, value))\r
+\r
+    def write_log_header(self, write_dict):\r
+        """\r
+        Object description.\r
+\r
+        Parameters\r
+        ----------\r
+        parameter : type\r
+            Parameter description.\r
+\r
+        Returns\r
+        -------\r
+        type\r
+             Return value description.\r
+        """\r
+\r
+        import platform\r
+\r
+        # Retrieve operating environment information\r
+        user = None\r
+        try:\r
+            user = os.getlogin()\r
+        except:\r
+            try:\r
+                user = os.getenv("USERNAME")\r
+                if user is None:\r
+                    user = os.getenv("USER")\r
+            except:\r
+                user = "unknown_user"\r
+        try:\r
+            (sysname, nodename, release, version, machine,\r
+             processor) = platform.uname()\r
+        except:\r
+            (sysname, nodename, release, version, machine, processor) = (\r
+                "unknown_sysname", "unknown_nodename", "unknown_release",\r
+                "unknown_version", "unknown_machine", "unknown_processor")\r
+        try:\r
+            hostname = platform.node()\r
+        except:\r
+            hostname = "unknown_hostname"\r
+\r
+        self.write_key(write_dict, 'process', None, 'start')\r
+        write_dict['indentationLevel'] += 1\r
+\r
+        self.write_key(write_dict, 'description', self.description)\r
+        self.write_key(write_dict, 'cmd', self.cmd)\r
+        if self.args:\r
+            self.write_key(write_dict, 'args', ' '.join(self.args))\r
+        self.write_key(write_dict, 'start', self.start)\r
+        self.write_key(write_dict, 'end', self.end)\r
+        self.write_key(write_dict, 'elapsed', self.get_elapsed_seconds())\r
+\r
+        self.write_key(write_dict, 'user', user)\r
+        self.write_key(write_dict, 'sysname', sysname)\r
+        self.write_key(write_dict, 'nodename', nodename)\r
+        self.write_key(write_dict, 'release', release)\r
+        self.write_key(write_dict, 'version', version)\r
+        self.write_key(write_dict, 'machine', machine)\r
+        self.write_key(write_dict, 'processor', processor)\r
+\r
+        if len(self.process_keys) > 0:\r
+            self.write_key(write_dict, 'processKeys', None, 'start')\r
+            for pair in self.process_keys:\r
+                (key, value) = pair\r
+                write_dict['indentationLevel'] += 1\r
+                self.write_key(write_dict, key, value)\r
+                write_dict['indentationLevel'] -= 1\r
+            self.write_key(write_dict, 'processKeys', None, 'stop')\r
+\r
+        self.write_key(write_dict, 'status', self.status)\r
+\r
+    def write_log_footer(self, write_dict):\r
+        """\r
+        Object description.\r
+\r
+        Parameters\r
+        ----------\r
+        parameter : type\r
+            Parameter description.\r
+\r
+        Returns\r
+        -------\r
+        type\r
+             Return value description.\r
+        """\r
+\r
+        write_dict['indentationLevel'] -= 1\r
+        self.write_key(write_dict, 'process', None, 'stop')\r
+\r
+    def write_log(self,\r
+                  log_handle=sys.stdout,\r
+                  indentation_level=0,\r
+                  format='xml'):\r
+        """\r
+        Writes logging information to the specified handle.\r
+\r
+        Parameters\r
+        ----------\r
+        parameter : type\r
+            Parameter description.\r
+\r
+        Returns\r
+        -------\r
+        type\r
+             Return value description.\r
+        """\r
+\r
+        write_dict = {}\r
+        write_dict['logHandle'] = log_handle\r
+        write_dict['indentationLevel'] = indentation_level\r
+        write_dict['format'] = format\r
+\r
+        if log_handle:\r
+            self.write_log_header(write_dict)\r
+\r
+            if self.log:\r
+                self.write_key(write_dict, 'output', None, 'start')\r
+                if format == 'xml':\r
+                    log_handle.write("<![CDATA[\n")\r
+                for line in self.log:\r
+                    log_handle.write('%s%s\n' % ("", line))\r
+                if format == 'xml':\r
+                    log_handle.write("]]>\n")\r
+                self.write_key(write_dict, 'output', None, 'stop')\r
+\r
+            self.write_log_footer(write_dict)\r
+\r
+    def write_log_to_disk(self, log_filename=None, format='xml', header=None):\r
+        """\r
+        Object description.\r
+\r
+        Parameters\r
+        ----------\r
+        parameter : type\r
+            Parameter description.\r
+\r
+        Returns\r
+        -------\r
+        type\r
+             Return value description.\r
+        """\r
+\r
+        if log_filename:\r
+            try:\r
+                # This also doesn't seem like the best structure...\r
+                # 3.1\r
+                try:\r
+                    log_handle = open(log_filename,\r
+                                      mode='wt',\r
+                                      encoding="utf-8")\r
+                # 2.6\r
+                except:\r
+                    log_handle = open(log_filename,\r
+                                      mode='wt')\r
+            except:\r
+                print("Couldn't open log : %s" % log_filename)\r
+                log_handle = None\r
+\r
+        if log_handle:\r
+            if header:\r
+                if format == 'xml':\r
+                    log_handle.write("<![CDATA[\n")\r
+                log_handle.write(header)\r
+                if format == 'xml':\r
+                    log_handle.write("]]>\n")\r
+            self.write_log(log_handle)\r
+            log_handle.close()\r
+\r
+    def log_line(self, line):\r
+        """\r
+        Adds a line of text to the log.\r
+\r
+        Parameters\r
+        ----------\r
+        parameter : type\r
+            Parameter description.\r
+\r
+        Returns\r
+        -------\r
+        type\r
+             Return value description.\r
+        """\r
+\r
+        self.log.append(line.rstrip())\r
+        if self.echo:\r
+            print("%s" % line.rstrip())\r
+\r
+    def execute(self):\r
+        """\r
+        Executes the current process.\r
+\r
+        Parameters\r
+        ----------\r
+        parameter : type\r
+            Parameter description.\r
+\r
+        Returns\r
+        -------\r
+        type\r
+             Return value description.\r
+        """\r
+\r
+        import datetime\r
+        import traceback\r
+\r
+        try:\r
+            import subprocess as sp\r
+        except:\r
+            sp = None\r
+\r
+        self.start = datetime.datetime.now()\r
+\r
+        cmdargs = [self.cmd]\r
+        cmdargs.extend(self.args)\r
+\r
+        if self.echo:\r
+            if sp:\r
+                print(\r
+                    "\n%s : %s\n" % (self.__class__, sp.list2cmdline(cmdargs)))\r
+            else:\r
+                print("\n%s : %s\n" % (self.__class__, " ".join(cmdargs)))\r
+\r
+        # intialize a few variables that may or may not be set later\r
+        process = None\r
+        tmp_wrapper = None\r
+        stdout = None\r
+        stdin = None\r
+        parentenv = os.environ\r
+        parentcwd = os.getcwd()\r
+\r
+        try:\r
+            # Using subprocess\r
+            if sp:\r
+                if self.batch_wrapper:\r
+                    cmd = " ".join(cmdargs)\r
+                    tmp_wrapper = os.path.join(self.cwd, "process.bat")\r
+                    write_text(cmd, tmp_wrapper)\r
+                    print("%s : Running process through wrapper %s\n" % (\r
+                        self.__class__, tmp_wrapper))\r
+                    process = sp.Popen([tmp_wrapper], stdout=sp.PIPE,\r
+                                       stderr=sp.STDOUT,\r
+                                       cwd=self.cwd, env=self.env)\r
+                else:\r
+                    process = sp.Popen(cmdargs, stdout=sp.PIPE,\r
+                                       stderr=sp.STDOUT,\r
+                                       cwd=self.cwd, env=self.env)\r
+\r
+            # using os.popen4\r
+            else:\r
+                if self.env:\r
+                    os.environ = self.env\r
+                if self.cwd:\r
+                    os.chdir(self.cwd)\r
+\r
+                stdin, stdout = os.popen4(cmdargs, 'r')\r
+        except:\r
+            print("Couldn't execute command : %s" % cmdargs[0])\r
+            traceback.print_exc()\r
+\r
+        # Using subprocess\r
+        if sp:\r
+            if process != None:\r
+                # pid = process.pid\r
+                # log.logLine("process id %s\n" % pid)\r
+\r
+                try:\r
+                    # This is more proper python, and resolves some issues with\r
+                    # a process ending before all of its output has been\r
+                    # processed, but it also seems to stall when the read\r
+                    # buffer is near or over it's limit. this happens\r
+                    # relatively frequently with processes that generate lots\r
+                    # of print statements.\r
+                    for line in process.stdout:\r
+                        self.log_line(line)\r
+                    #\r
+                    # So we go with the, um, uglier  option below\r
+\r
+                    # This is now used to ensure that the process has finished\r
+                    line = ""\r
+                    while line != None and process.poll() is None:\r
+                        try:\r
+                            line = process.stdout.readline()\r
+                        except:\r
+                            break\r
+                        # 3.1\r
+                        try:\r
+                            self.log_line(str(line, encoding="utf-8"))\r
+                        # 2.6\r
+                        except:\r
+                            self.log_line(line)\r
+                except:\r
+                    self.log_line("Logging error : %s" % sys.exc_info()[0])\r
+\r
+                self.status = process.returncode\r
+\r
+                if self.batch_wrapper and tmp_wrapper:\r
+                    try:\r
+                        os.remove(tmp_wrapper)\r
+                    except:\r
+                        print(\r
+                            "Couldn't remove temp wrapper : %s" % tmp_wrapper)\r
+                        traceback.print_exc()\r
+\r
+        # Using os.popen4\r
+        else:\r
+            exit_code = -1\r
+            try:\r
+                # print("reading stdout lines")\r
+                stdout_lines = stdout.readlines()\r
+                exit_code = stdout.close()\r
+\r
+                stdout.close()\r
+                stdin.close()\r
+\r
+                if self.env:\r
+                    os.environ = parentenv\r
+                if self.cwd:\r
+                    os.chdir(parentcwd)\r
+\r
+                if len(stdout_lines) > 0:\r
+                    for line in stdout_lines:\r
+                        self.log_line(line)\r
+\r
+                if not exit_code:\r
+                    exit_code = 0\r
+            except:\r
+                self.log_line("Logging error : %s" % sys.exc_info()[0])\r
+\r
+            self.status = exit_code\r
+\r
+        self.end = datetime.datetime.now()\r
+\r
+\r
+class ProcessList(Process):\r
+    """\r
+    A list of processes with logged output.\r
+    """\r
+\r
+    def __init__(self, description, blocking=True, cwd=None, env=None):\r
+        """\r
+        Object description.\r
+\r
+        Parameters\r
+        ----------\r
+        parameter : type\r
+            Parameter description.\r
+\r
+        Returns\r
+        -------\r
+        type\r
+             Return value description.\r
+        """\r
+\r
+        Process.__init__(self, description, None, None, cwd, env)\r
+        "Initialize the standard class variables"\r
+        self.processes = []\r
+        self.blocking = blocking\r
+\r
+    def generate_report(self, write_dict):\r
+        """\r
+        Generates a log based on the success of the child processes.\r
+\r
+        Parameters\r
+        ----------\r
+        parameter : type\r
+            Parameter description.\r
+\r
+        Returns\r
+        -------\r
+        type\r
+             Return value description.\r
+        """\r
+\r
+        if self.processes:\r
+            _status = True\r
+            indent = '\t' * (write_dict['indentationLevel'] + 1)\r
+\r
+            self.log = []\r
+\r
+            for child in self.processes:\r
+                if isinstance(child, ProcessList):\r
+                    child.generate_report(write_dict)\r
+\r
+                child_result = ""\r
+                key = child.description\r
+                value = child.status\r
+                if write_dict['format'] == 'xml':\r
+                    child_result = (\r
+                        "%s<result description=\"%s\">%s</result>" % (\r
+                            indent, key, value))\r
+                else:  # writeDict['format'] == 'txt':\r
+                    child_result = ("%s%40s : %s" % (indent, key, value))\r
+                self.log.append(child_result)\r
+\r
+                if child.status != 0:\r
+                    _status = False\r
+            if not _status:\r
+                self.status = -1\r
+            else:\r
+                self.status = 0\r
+        else:\r
+            self.log = ["No child processes available to generate a report"]\r
+            self.status = -1\r
+\r
+    def write_log_header(self, write_dict):\r
+        """\r
+        Object description.\r
+\r
+        Parameters\r
+        ----------\r
+        parameter : type\r
+            Parameter description.\r
+\r
+        Returns\r
+        -------\r
+        type\r
+             Return value description.\r
+        """\r
+\r
+        self.write_key(write_dict, 'processList', None, 'start')\r
+        write_dict['indentationLevel'] += 1\r
+\r
+        self.write_key(write_dict, 'description', self.description)\r
+        self.write_key(write_dict, 'start', self.start)\r
+        self.write_key(write_dict, 'end', self.end)\r
+        self.write_key(write_dict, 'elapsed', self.get_elapsed_seconds())\r
+\r
+        self.generate_report(write_dict)\r
+\r
+        self.write_key(write_dict, 'status', self.status)\r
+\r
+    def write_log_footer(self, write_dict):\r
+        """\r
+        Object description.\r
+\r
+        Parameters\r
+        ----------\r
+        parameter : type\r
+            Parameter description.\r
+\r
+        Returns\r
+        -------\r
+        type\r
+             Return value description.\r
+        """\r
+\r
+        write_dict['indentationLevel'] -= 1\r
+        self.write_key(write_dict, 'processList', None, 'stop')\r
+\r
+    def write_log(self,\r
+                  log_handle=sys.stdout,\r
+                  indentation_level=0,\r
+                  format='xml'):\r
+        """\r
+        Writes logging information to the specified handle.\r
+\r
+        Parameters\r
+        ----------\r
+        parameter : type\r
+            Parameter description.\r
+\r
+        Returns\r
+        -------\r
+        type\r
+             Return value description.\r
+        """\r
+\r
+        write_dict = {}\r
+        write_dict['logHandle'] = log_handle\r
+        write_dict['indentationLevel'] = indentation_level\r
+        write_dict['format'] = format\r
+\r
+        if log_handle:\r
+            self.write_log_header(write_dict)\r
+\r
+            if self.log:\r
+                self.write_key(write_dict, 'output', None, 'start')\r
+                for line in self.log:\r
+                    log_handle.write('%s%s\n' % ("", line))\r
+                self.write_key(write_dict, 'output', None, 'stop')\r
+\r
+            if self.processes:\r
+                self.write_key(write_dict, 'processes', None, 'start')\r
+                for child in self.processes:\r
+                    child.write_log(log_handle, indentation_level + 1, format)\r
+                self.write_key(write_dict, 'processes', None, 'stop')\r
+\r
+            self.write_log_footer(write_dict)\r
+\r
+    def execute(self):\r
+        """\r
+        Executes the list of processes.\r
+\r
+        Parameters\r
+        ----------\r
+        parameter : type\r
+            Parameter description.\r
+\r
+        Returns\r
+        -------\r
+        type\r
+             Return value description.\r
+        """\r
+\r
+        import datetime\r
+\r
+        self.start = datetime.datetime.now()\r
+\r
+        self.status = 0\r
+        if self.processes:\r
+            for child in self.processes:\r
+                if child:\r
+                    try:\r
+                        child.execute()\r
+                    except:\r
+                        print("%s : caught exception in child class %s" % (\r
+                            self.__class__, child.__class__))\r
+                        traceback.print_exc()\r
+                        child.status = -1\r
+\r
+                    if self.blocking and child.status != 0:\r
+                        print("%s : child class %s finished with an error" % (\r
+                            self.__class__, child.__class__))\r
+                        self.status = -1\r
+                        break\r
+\r
+        self.end = datetime.datetime.now()\r
+\r
+\r
+def main():\r
+    """\r
+    Object description.\r
+\r
+    Parameters\r
+    ----------\r
+    parameter : type\r
+        Parameter description.\r
+\r
+    Returns\r
+    -------\r
+    type\r
+         Return value description.\r
+    """\r
+\r
+    import optparse\r
+\r
+    p = optparse.OptionParser(description='A process logging script',\r
+                              prog='process',\r
+                              version='process 0.1',\r
+                              usage=('%prog [options] '\r
+                                     '[options for the logged process]'))\r
+    p.add_option('--cmd', '-c', default=None)\r
+    p.add_option('--log', '-l', default=None)\r
+\r
+    options, arguments = p.parse_args()\r
+\r
+    #\r
+    # Get options\r
+    # \r
+    cmd = options.cmd\r
+    log_filename = options.log\r
+\r
+    try:\r
+        args_start = sys.argv.index('--') + 1\r
+        args = sys.argv[args_start:]\r
+    except:\r
+        args_start = len(sys.argv) + 1\r
+        args = []\r
+\r
+    if cmd is None:\r
+        print("process: No command specified")\r
+\r
+    #\r
+    # Test regular logging\r
+    #\r
+    process = Process(description="a process", cmd=cmd, args=args)\r
+\r
+    #\r
+    # Test report generation and writing a log\r
+    #\r
+    process_list = ProcessList("a process list")\r
+    process_list.processes.append(process)\r
+    process_list.echo = True\r
+    process_list.execute()\r
+\r
+    process_list.write_log_to_disk(log_filename)\r
+\r
+\r
+if __name__ == '__main__':\r
+    main()\r
diff --git a/aces_1.0.0/python/aces_ocio/tests/__init__.py b/aces_1.0.0/python/aces_ocio/tests/__init__.py
new file mode 100644 (file)
index 0000000..a5682fb
--- /dev/null
@@ -0,0 +1,2 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
\ No newline at end of file
diff --git a/aces_1.0.0/python/aces_ocio/tests/tests_aces_config.py b/aces_1.0.0/python/aces_ocio/tests/tests_aces_config.py
new file mode 100644 (file)
index 0000000..61acfa5
--- /dev/null
@@ -0,0 +1,143 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Defines unit tests for *ACES* configuration.
+"""
+
+import hashlib
+import os
+import re
+import shutil
+import sys
+
+# TODO: Temporary ugly thing to be discussed, ideally the package should be
+# in PYTHONPATH.
+sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
+
+import tempfile
+import unittest
+
+from aces_ocio.utilities import files_walker
+from aces_ocio.create_aces_config import (
+    ACES_OCIO_CTL_DIRECTORY_ENVIRON,
+    create_ACES_config)
+
+__author__ = 'ACES Developers'
+__copyright__ = 'Copyright (C) 2014 - 2015 - ACES Developers'
+__license__ = ''
+__maintainer__ = 'ACES Developers'
+__email__ = 'aces@oscars.org'
+__status__ = 'Production'
+
+__all__ = ['REFERENCE_CONFIG_ROOT_DIRECTORY',
+           'HASH_TEST_PATTERNS',
+           'UNHASHABLE_TEST_PATTERNS',
+           'TestACESConfig']
+
+
+# TODO: Investigate how the current config has been generated to use it for
+# tests.
+# REFERENCE_CONFIG_ROOT_DIRECTORY = os.path.abspath(
+#     os.path.join(os.path.dirname(__file__), '..', '..', '..'))
+REFERENCE_CONFIG_ROOT_DIRECTORY = '/colour-science/colour-ramblings/ocio/aces'
+
+HASH_TEST_PATTERNS = ('\.3dl', '\.lut', '\.csp')
+UNHASHABLE_TEST_PATTERNS = ('\.icc', '\.ocio')
+
+
+class TestACESConfig(unittest.TestCase):
+    """
+    Performs tests on the *ACES* configuration.
+    """
+
+    def setUp(self):
+        """
+        Initialises common tests attributes.
+        """
+
+        self.__aces_ocio_ctl_directory = os.environ.get(
+            ACES_OCIO_CTL_DIRECTORY_ENVIRON, None)
+
+        assert self.__aces_ocio_ctl_directory is not None, (
+            'Undefined "{0}" environment variable!'.format(
+                ACES_OCIO_CTL_DIRECTORY_ENVIRON))
+
+        assert os.path.exists(self.__aces_ocio_ctl_directory) is True, (
+            '"{0}" directory does not exists!'.format(
+                self.__aces_ocio_ctl_directory))
+
+        self.maxDiff = None
+        self.__temporary_directory = tempfile.mkdtemp()
+
+    def tearDown(self):
+        """
+        Post tests actions.
+        """
+
+        shutil.rmtree(self.__temporary_directory)
+
+    @staticmethod
+    def directory_hashes(directory,
+                         filters_in=None,
+                         filters_out=None,
+                         flags=0):
+        """
+        Recursively computes the hashes from the file within given directory.
+
+        Parameters
+        ----------
+        directory : str or unicode
+            Directory to compute the file hashes.
+        filters_in : array_like
+            Included patterns.
+        filters_out : array_like
+            Excluded patterns.
+        flags : int
+            Regex flags.
+
+        Returns
+        -------
+        dict
+             Directory file hashes.
+        """
+
+        hashes = {}
+        for path in files_walker(directory,
+                                 filters_in=filters_in,
+                                 filters_out=filters_out):
+            with open(path) as file:
+                hash = hashlib.md5(
+                    re.sub('\s', '', file.read())).hexdigest()
+            hashes[path.replace(directory, '')] = hash
+        return hashes
+
+    def test_ACES_config(self):
+        """
+        Performs tests on the *ACES* configuration by computing hashes on the
+        generated configuration and comparing them to the existing one.
+        """
+
+        self.assertTrue(create_ACES_config(self.__aces_ocio_ctl_directory,
+                                           self.__temporary_directory))
+
+        reference_hashes = self.directory_hashes(
+            REFERENCE_CONFIG_ROOT_DIRECTORY,
+            HASH_TEST_PATTERNS)
+        test_hashes = self.directory_hashes(
+            self.__temporary_directory,
+            HASH_TEST_PATTERNS)
+
+        self.assertDictEqual(reference_hashes, test_hashes)
+
+        # Checking that unashable files ('.icc', '.ocio') are generated.
+        unashable = lambda x: (
+            sorted([file.replace(x, '') for file in
+                    files_walker(x, UNHASHABLE_TEST_PATTERNS)]))
+
+        self.assertListEqual(unashable(REFERENCE_CONFIG_ROOT_DIRECTORY),
+                             unashable(self.__temporary_directory))
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/aces_1.0.0/python/aces_ocio/utilities.py b/aces_1.0.0/python/aces_ocio/utilities.py
new file mode 100644 (file)
index 0000000..00804e3
--- /dev/null
@@ -0,0 +1,154 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Defines various package utilities objects.
+"""
+
+import os
+import re
+
+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']
+
+#
+# Utility classes and functions
+#
+
+class ColorSpace(object):
+    """
+    A container for data needed to define an *OCIO* *ColorSpace*.
+    """
+
+    def __init__(self,
+                 name,
+                 description=None,
+                 bit_depth=OCIO.Constants.BIT_DEPTH_F32,
+                 equality_group=None,
+                 family=None,
+                 is_data=False,
+                 to_reference_transforms=[],
+                 from_reference_transforms=[],
+                 allocation_type=OCIO.Constants.ALLOCATION_UNIFORM,
+                 allocation_vars=[0.0, 1.0]):
+        """
+        Object description.
+
+        Parameters
+        ----------
+        parameter : type
+            Parameter description.
+
+        Returns
+        -------
+        type
+             Return value description.
+        """
+
+        self.name = name
+        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
+
+
+def mat44_from_mat33(mat33):
+    """
+    Creates a 4x4 matrix from given 3x3 matrix.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    return [mat33[0], mat33[1], mat33[2], 0.0,
+            mat33[3], mat33[4], mat33[5], 0.0,
+            mat33[6], mat33[7], mat33[8], 0.0,
+            0, 0, 0, 1.0]
+
+
+def filter_words(words, filters_in=None, filters_out=None, flags=0):
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    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):
+    """
+    Object description.
+
+    Parameters
+    ----------
+    parameter : type
+        Parameter description.
+
+    Returns
+    -------
+    type
+         Return value description.
+    """
+
+    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
diff --git a/aces_1.0.0/python/createARRIColorSpaces.py b/aces_1.0.0/python/createARRIColorSpaces.py
deleted file mode 100644 (file)
index 73e175b..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-import math
-import array
-
-from util import *
-import generateLUT as genlut
-
-
-#
-# LogC to ACES
-#
-def createLogC(gamut, transferFunction, exposureIndex, name, lutDir, lutResolution1d):
-    name = "%s (EI%s) - %s" % (transferFunction, exposureIndex, gamut)
-    if transferFunction == "":
-        name = "Linear - %s" % gamut
-    if gamut == "":
-        name = "%s (EI%s)" % (transferFunction, exposureIndex)
-
-    cs = ColorSpace(name)
-    cs.description = name
-    cs.equalityGroup = ''
-    cs.family = 'ARRI'
-    cs.isData=False
-
-    # Globals
-    IDT_maker_version = "0.08"
-
-    nominalEI = 400.0
-    blackSignal = 0.003907
-    midGraySignal = 0.01
-    encodingGain = 0.256598
-    encodingOffset = 0.391007
-
-    def gainForEI(EI) :
-        return (math.log(EI/nominalEI)/math.log(2) * (0.89 - 1) / 3 + 1) * encodingGain
-
-    def LogCInverseParametersForEI(EI) :
-        cut = 1.0 / 9.0
-        slope = 1.0 / (cut * math.log(10))
-        offset = math.log10(cut) - slope * cut
-        gain = EI / nominalEI
-        gray = midGraySignal / gain
-        # The higher the EI, the lower the gamma
-        encGain = gainForEI(EI)
-        encOffset = encodingOffset
-        for i in range(0,3) :
-            nz = ((95.0 / 1023.0 - encOffset) / encGain - offset) / slope
-            encOffset = encodingOffset - math.log10(1 + nz) * encGain
-        # Calculate some intermediate values
-        a = 1.0 / gray
-        b = nz - blackSignal / gray
-        e = slope * a * encGain
-        f = encGain * (slope * b + offset) + encOffset
-        # Manipulations so we can return relative exposure
-        s = 4 / (0.18 * EI)
-        t = blackSignal
-        b = b + a * t
-        a = a * s
-        f = f + e * t
-        e = e * s
-        return { 'a' : a,
-                 'b' : b,
-                 'cut' : (cut - b) / a,
-                 'c' : encGain,
-                 'd' : encOffset,
-                 'e' : e,
-                 'f' : f }
-
-    def logCtoLinear(codeValue, exposureIndex):
-        p = LogCInverseParametersForEI(exposureIndex)
-        breakpoint = p['e'] * p['cut'] + p['f']
-        if (codeValue > breakpoint):
-            linear = (pow(10,(codeValue/1023.0 - p['d']) / p['c']) - p['b']) / p['a']
-        else:
-            linear = (codeValue/1023.0 - p['f']) / p['e']
-
-        #print( codeValue, linear )
-        return linear
-
-
-    cs.toReferenceTransforms = []
-
-    if transferFunction == "V3 LogC":
-        data = array.array('f', "\0" * lutResolution1d * 4)
-        for c in range(lutResolution1d):
-            data[c] = logCtoLinear(1023.0*c/(lutResolution1d-1), int(exposureIndex))
-
-        lut = "%s_to_linear.spi1d" % ("%s_%s" % (transferFunction, exposureIndex))
-
-        # Remove spaces and parentheses
-        lut = lut.replace(' ', '_').replace(')', '_').replace('(', '_')
-
-        genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
-
-        #print( "Writing %s" % lut)
-        cs.toReferenceTransforms.append( {
-            'type':'lutFile', 
-            'path':lut, 
-            'interpolation':'linear', 
-            'direction':'forward'
-        } )
-
-    if gamut == 'Wide Gamut':
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':mat44FromMat33([0.680206, 0.236137, 0.083658, 
-                        0.085415, 1.017471, -0.102886, 
-                        0.002057, -0.062563, 1.060506]),
-            'direction':'forward'
-        })
-
-    cs.fromReferenceTransforms = []
-    return cs
-
-def createColorSpaces(lutDir, lutResolution1d):
-    colorspaces = []
-
-    transferFunction = "V3 LogC"
-    gamut = "Wide Gamut"
-    #EIs = [160.0, 200.0, 250.0, 320.0, 400.0, 500.0, 640.0, 800.0, 1000.0, 1280.0, 1600.0, 2000.0, 2560.0, 3200.0]
-    EIs = [160, 200, 250, 320, 400, 500, 640, 800, 1000, 1280, 1600, 2000, 2560, 3200]
-    defaultEI = 800
-
-    # Full conversion
-    for EI in EIs:
-        LogCEIfull = createLogC(gamut, transferFunction, EI, "LogC", lutDir, lutResolution1d)
-        colorspaces.append(LogCEIfull)
-
-    # Linearization only
-    for EI in [800]:
-        LogCEIlinearization = createLogC("", transferFunction, EI, "LogC", lutDir, lutResolution1d)
-        colorspaces.append(LogCEIlinearization)
-
-    # Primaries
-    LogCEIprimaries = createLogC(gamut, "", defaultEI, "LogC", lutDir, lutResolution1d)
-    colorspaces.append(LogCEIprimaries)
-
-    return colorspaces
diff --git a/aces_1.0.0/python/createCanonColorSpaces.py b/aces_1.0.0/python/createCanonColorSpaces.py
deleted file mode 100644 (file)
index 194cc2e..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-import array
-
-from util import *
-import generateLUT as genlut
-
-#
-# Canon-Log to ACES
-#
-def createCanonLog(gamut, transferFunction, name, lutDir, lutResolution1d):
-    name = "%s - %s" % (transferFunction, gamut)
-    if transferFunction == "":
-        name = "Linear - %s" % gamut
-    if gamut == "":
-        name = "%s" % transferFunction
-
-    cs = ColorSpace(name)
-    cs.description = name
-    cs.equalityGroup = ''
-    cs.family = 'Canon'
-    cs.isData=False
-
-    def legalToFull(codeValue):
-        return (codeValue - 64.0)/(940.0 - 64.0)
-
-    def canonLogToLinear(codeValue):
-        # log = fullToLegal(c1 * log10(c2*linear + 1) + c3)
-        # linear = (pow(10, (legalToFul(log) - c3)/c1) - 1)/c2
-        c1 = 0.529136
-        c2 = 10.1596
-        c3 = 0.0730597
-
-        linear = (pow(10.0, (legalToFull(codeValue) - c3)/c1) -1.0)/c2
-        linear = 0.9 * linear
-        #print( codeValue, linear )
-        return linear
-
-    cs.toReferenceTransforms = []
-
-    if transferFunction == "Canon-Log":
-        data = array.array('f', "\0" * lutResolution1d * 4)
-        for c in range(lutResolution1d):
-            data[c] = canonLogToLinear(1023.0*c/(lutResolution1d-1))
-
-        lut = "%s_to_linear.spi1d" % transferFunction
-        genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
-
-        cs.toReferenceTransforms.append( {
-            'type':'lutFile', 
-            'path':lut, 
-            'interpolation':'linear', 
-            'direction':'forward'
-        } )
-
-    if gamut == 'Rec. 709 Daylight':
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':[0.561538969, 0.402060105, 0.036400926, 0.0, 
-                        0.092739623, 0.924121198, -0.016860821, 0.0, 
-                        0.084812961, 0.006373835, 0.908813204, 0.0, 
-                        0,0,0,1.0],
-            'direction':'forward'
-        })
-    elif gamut == 'Rec. 709 Tungsten':
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':[0.566996399, 0.365079418, 0.067924183, 0.0, 
-                        0.070901044, 0.880331008, 0.048767948, 0.0, 
-                        0.073013542, -0.066540862, 0.99352732, 0.0, 
-                        0,0,0,1.0],
-            'direction':'forward'
-        })
-    elif gamut == 'DCI-P3 Daylight':
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':[0.607160575, 0.299507286, 0.093332140, 0.0, 
-                        0.004968120, 1.050982224, -0.055950343, 0.0, 
-                        -0.007839939, 0.000809127, 1.007030813, 0.0, 
-                        0,0,0,1.0],
-            'direction':'forward'
-        })
-    elif gamut == 'DCI-P3 Tungsten':
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':[0.650279125, 0.253880169, 0.095840706, 0.0, 
-                        -0.026137986, 1.017900530, 0.008237456, 0.0, 
-                        0.007757558, -0.063081669, 1.055324110, 0.0, 
-                        0,0,0,1.0],
-            'direction':'forward'
-        })
-    elif gamut == 'Cinema Gamut Daylight':
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':[0.763064455, 0.149021161, 0.087914384, 0.0, 
-                        0.003657457, 1.10696038, -0.110617837, 0.0, 
-                        -0.009407794,-0.218383305, 1.227791099, 0.0, 
-                        0,0,0,1.0],
-            'direction':'forward'
-        })
-    elif gamut == 'Cinema Gamut Tungsten':
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':[0.817416293, 0.090755698, 0.091828009, 0.0, 
-                        -0.035361374, 1.065690585, -0.030329211, 0.0, 
-                        0.010390366, -0.299271107, 1.288880741, 0.0, 
-                        0,0,0,1.0],
-            'direction':'forward'
-        })
-
-    cs.fromReferenceTransforms = []
-    return cs
-
-# Generate all color spaces conversion
-def createColorSpaces(lutDir, lutResolution1d):
-    colorspaces = []
-
-    # Full conversion
-    CanonLog1 = createCanonLog("Rec. 709 Daylight", "Canon-Log", "Canon-Log", lutDir, lutResolution1d)
-    colorspaces.append(CanonLog1)
-
-    CanonLog2 = createCanonLog("Rec. 709 Tungsten", "Canon-Log", "Canon-Log", lutDir, lutResolution1d)
-    colorspaces.append(CanonLog2)
-
-    CanonLog3 = createCanonLog("DCI-P3 Daylight", "Canon-Log", "Canon-Log", lutDir, lutResolution1d)
-    colorspaces.append(CanonLog3)
-
-    CanonLog4 = createCanonLog("DCI-P3 Tungsten", "Canon-Log", "Canon-Log", lutDir, lutResolution1d)
-    colorspaces.append(CanonLog4)
-
-    CanonLog5 = createCanonLog("Cinema Gamut Daylight", "Canon-Log", "Canon-Log", lutDir, lutResolution1d)
-    colorspaces.append(CanonLog5)
-
-    CanonLog6 = createCanonLog("Cinema Gamut Tungsten", "Canon-Log", "Canon-Log", lutDir, lutResolution1d)
-    colorspaces.append(CanonLog6)
-
-    # Linearization only
-    CanonLog7 = createCanonLog('', "Canon-Log", "Canon-Log", lutDir, lutResolution1d)
-    colorspaces.append(CanonLog7)
-
-    # Primaries only
-    CanonLog8 = createCanonLog("Rec. 709 Daylight", "", "Canon-Log", lutDir, lutResolution1d)
-    colorspaces.append(CanonLog8)
-
-    CanonLog9 = createCanonLog("Rec. 709 Tungsten", "", "Canon-Log", lutDir, lutResolution1d)
-    colorspaces.append(CanonLog9)
-
-    CanonLog10 = createCanonLog("DCI-P3 Daylight", "", "Canon-Log", lutDir, lutResolution1d)
-    colorspaces.append(CanonLog10)
-
-    CanonLog11 = createCanonLog("DCI-P3 Tungsten", "", "Canon-Log", lutDir, lutResolution1d)
-    colorspaces.append(CanonLog11)
-
-    CanonLog12 = createCanonLog("Cinema Gamut Daylight", "", "Canon-Log", lutDir, lutResolution1d)
-    colorspaces.append(CanonLog12)
-
-    CanonLog13 = createCanonLog("Cinema Gamut Tungsten", "", "Canon-Log", lutDir, lutResolution1d)
-    colorspaces.append(CanonLog13)
-
-    return colorspaces
diff --git a/aces_1.0.0/python/createREDColorSpaces.py b/aces_1.0.0/python/createREDColorSpaces.py
deleted file mode 100644 (file)
index 0e3823d..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-import array
-
-from util import *
-import generateLUT as genlut
-
-#
-# RED color spaces to ACES
-#
-def createREDlogFilm(gamut, transferFunction, name, lutDir, lutResolution1d):
-    name = "%s - %s" % (transferFunction, gamut)
-    if transferFunction == "":
-        name = "Linear - %s" % gamut
-    if gamut == "":
-        name = "%s" % transferFunction
-
-    cs = ColorSpace(name)
-    cs.description = name
-    cs.equalityGroup = ''
-    cs.family = 'RED'
-    cs.isData=False
-
-    def cineonToLinear(codeValue):
-        nGamma = 0.6
-        blackPoint = 95.0
-        whitePoint = 685.0
-        codeValueToDensity = 0.002
-
-        blackLinear = pow(10.0, (blackPoint - whitePoint) * (codeValueToDensity / nGamma))
-        codeLinear = pow(10.0, (codeValue - whitePoint) * (codeValueToDensity / nGamma))
-
-        return (codeLinear - blackLinear)/(1.0 - blackLinear)
-
-    cs.toReferenceTransforms = []
-
-    if transferFunction == 'REDlogFilm':
-        data = array.array('f', "\0" * lutResolution1d * 4)
-        for c in range(lutResolution1d):
-            data[c] = cineonToLinear(1023.0*c/(lutResolution1d-1))
-
-        lut = "CineonLog_to_linear.spi1d"
-        genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
-
-        cs.toReferenceTransforms.append( {
-            'type':'lutFile', 
-            'path':lut, 
-            'interpolation':'linear', 
-            'direction':'forward'
-        } )
-
-    if gamut == 'DRAGONcolor':
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':mat44FromMat33([0.532279,  0.376648,  0.091073, 
-                                     0.046344,  0.974513, -0.020860, 
-                                    -0.053976, -0.000320, 1.054267]),
-            'direction':'forward'
-        })
-    elif gamut == 'DRAGONcolor2':
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':mat44FromMat33([0.468452,  0.331484,  0.200064, 
-                                     0.040787,  0.857658,  0.101553, 
-                                    -0.047504, -0.000282, 1.047756]),
-            'direction':'forward'
-        })
-    elif gamut == 'REDcolor2':
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':mat44FromMat33([0.480997, 0.402289, 0.116714, 
-                                    -0.004938, 1.000154, 0.004781, 
-                                    -0.105257, 0.025320, 1.079907]),
-            'direction':'forward'
-        })
-    elif gamut == 'REDcolor3':
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':mat44FromMat33([0.512136, 0.360370, 0.127494, 
-                                     0.070377, 0.903884, 0.025737, 
-                                    -0.020824, 0.017671, 1.003123]),
-            'direction':'forward'
-        })
-    elif gamut == 'REDcolor4':
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':mat44FromMat33([0.474202, 0.333677, 0.192121, 
-                                     0.065164, 0.836932, 0.097901, 
-                                    -0.019281, 0.016362, 1.002889]),
-            'direction':'forward'
-        })
-
-    cs.fromReferenceTransforms = []
-    return cs
-
-# Generate all color spaces conversion
-def createColorSpaces(lutDir, lutResolution1d):
-    colorspaces = []
-
-    # Full conversion
-    REDlogFilmDRAGON = createREDlogFilm("DRAGONcolor", "REDlogFilm", "REDlogFilm", lutDir, lutResolution1d)
-    colorspaces.append(REDlogFilmDRAGON)
-
-    REDlogFilmDRAGON2 = createREDlogFilm("DRAGONcolor2", "REDlogFilm", "REDlogFilm", lutDir, lutResolution1d)
-    colorspaces.append(REDlogFilmDRAGON2)
-
-    REDlogFilmREDcolor2 = createREDlogFilm("REDcolor2", "REDlogFilm", "REDlogFilm", lutDir, lutResolution1d)
-    colorspaces.append(REDlogFilmREDcolor2)
-
-    REDlogFilmREDcolor3 = createREDlogFilm("REDcolor3", "REDlogFilm", "REDlogFilm", lutDir, lutResolution1d)
-    colorspaces.append(REDlogFilmREDcolor3)
-
-    REDlogFilmREDcolor4 = createREDlogFilm("REDcolor4", "REDlogFilm", "REDlogFilm", lutDir, lutResolution1d)
-    colorspaces.append(REDlogFilmREDcolor4)
-
-    # Linearization only
-    REDlogFilmDRAGON = createREDlogFilm("", "REDlogFilm", "REDlogFilm", lutDir, lutResolution1d)
-    colorspaces.append(REDlogFilmDRAGON)
-
-    # Primaries only
-    REDlogFilmDRAGON = createREDlogFilm("DRAGONcolor", "", "REDlogFilm", lutDir, lutResolution1d)
-    colorspaces.append(REDlogFilmDRAGON)
-
-    REDlogFilmDRAGON2 = createREDlogFilm("DRAGONcolor2", "", "REDlogFilm", lutDir, lutResolution1d)
-    colorspaces.append(REDlogFilmDRAGON2)
-
-    REDlogFilmREDcolor2 = createREDlogFilm("REDcolor2", "", "REDlogFilm", lutDir, lutResolution1d)
-    colorspaces.append(REDlogFilmREDcolor2)
-
-    REDlogFilmREDcolor3 = createREDlogFilm("REDcolor3", "", "REDlogFilm", lutDir, lutResolution1d)
-    colorspaces.append(REDlogFilmREDcolor3)
-
-    REDlogFilmREDcolor4 = createREDlogFilm("REDcolor4", "", "REDlogFilm", lutDir, lutResolution1d)
-    colorspaces.append(REDlogFilmREDcolor4)
-
-    return colorspaces
diff --git a/aces_1.0.0/python/createSonyColorSpaces.py b/aces_1.0.0/python/createSonyColorSpaces.py
deleted file mode 100644 (file)
index dcfbb43..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-import array
-
-from util import *
-import generateLUT as genlut
-
-#
-# SLog to ACES
-#
-def createSlog(gamut, transferFunction, name, lutDir, lutResolution1d):
-    name = "%s - %s" % (transferFunction, gamut)
-    if transferFunction == "":
-        name = "Linear - %s" % gamut
-    if gamut == "":
-        name = "%s" % transferFunction
-
-    cs = ColorSpace(name)
-    cs.description = name
-    cs.equalityGroup = ''
-    cs.family = 'Sony'
-    cs.isData=False
-
-    def sLog1ToLinear(SLog):
-        b = 64.
-        ab = 90.
-        w = 940.
-
-        if (SLog >= ab):
-            lin = ( pow(10., ( ( ( SLog - b) / ( w - b) - 0.616596 - 0.03) / 0.432699)) - 0.037584) * 0.9
-        else:
-            lin = ( ( ( SLog - b) / ( w - b) - 0.030001222851889303) / 5.) * 0.9 
-        return lin
-
-    def sLog2ToLinear(SLog):
-        b = 64.
-        ab = 90.
-        w = 940.
-
-        if (SLog >= ab):
-            lin = ( 219. * ( pow(10., ( ( ( SLog - b) / ( w - b) - 0.616596 - 0.03) / 0.432699)) - 0.037584) / 155.) * 0.9
-        else:
-            lin = ( ( ( SLog - b) / ( w - b) - 0.030001222851889303) / 3.53881278538813) * 0.9
-        return lin
-
-    def sLog3ToLinear(codeValue):
-        if codeValue >= (171.2102946929):
-            linear = pow(10.0, ((codeValue - 420.0) / 261.5)) * (0.18 + 0.01) - 0.01
-        else:
-            linear = (codeValue - 95.0)*0.01125000/(171.2102946929 - 95.0)
-        #print( codeValue, linear )
-        return linear
-
-    cs.toReferenceTransforms = []
-
-    if transferFunction == "S-Log1":
-        data = array.array('f', "\0" * lutResolution1d * 4)
-        for c in range(lutResolution1d):
-            data[c] = sLog1ToLinear(1023.0*c/(lutResolution1d-1))
-
-        lut = "%s_to_linear.spi1d" % transferFunction
-        genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
-
-        #print( "Writing %s" % lut)
-
-        cs.toReferenceTransforms.append( {
-            'type':'lutFile', 
-            'path':lut, 
-            'interpolation':'linear', 
-            'direction':'forward'
-        } )
-    elif transferFunction == "S-Log2":
-        data = array.array('f', "\0" * lutResolution1d * 4)
-        for c in range(lutResolution1d):
-            data[c] = sLog2ToLinear(1023.0*c/(lutResolution1d-1))
-
-        lut = "%s_to_linear.spi1d" % transferFunction
-        genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
-
-        #print( "Writing %s" % lut)
-
-        cs.toReferenceTransforms.append( {
-            'type':'lutFile', 
-            'path':lut, 
-            'interpolation':'linear', 
-            'direction':'forward'
-        } )
-    elif transferFunction == "S-Log3":
-        data = array.array('f', "\0" * lutResolution1d * 4)
-        for c in range(lutResolution1d):
-            data[c] = sLog3ToLinear(1023.0*c/(lutResolution1d-1))
-
-        lut = "%s_to_linear.spi1d" % transferFunction
-        genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
-
-        #print( "Writing %s" % lut)
-
-        cs.toReferenceTransforms.append( {
-            'type':'lutFile', 
-            'path':lut, 
-            'interpolation':'linear', 
-            'direction':'forward'
-        } )
-
-    if gamut == 'S-Gamut':
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':mat44FromMat33([0.754338638, 0.133697046, 0.111968437,
-                                    0.021198141, 1.005410934, -0.026610548, 
-                                    -0.009756991, 0.004508563, 1.005253201]),
-            'direction':'forward'
-        })
-    elif gamut == 'S-Gamut Daylight':
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':mat44FromMat33([0.8764457030, 0.0145411681, 0.1090131290,
-                                    0.0774075345, 0.9529571767, -0.0303647111, 
-                                    0.0573564351, -0.1151066335, 1.0577501984]),
-            'direction':'forward'
-        })
-    elif gamut == 'S-Gamut Tungsten':
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':mat44FromMat33([1.0110238740, -0.1362526051, 0.1252287310, 
-                        0.1011994504, 0.9562196265, -0.0574190769,
-                        0.0600766530, -0.1010185315, 1.0409418785]),
-            'direction':'forward'
-        })
-    elif gamut == 'S-Gamut3.Cine':
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':mat44FromMat33([0.6387886672, 0.2723514337, 0.0888598992, 
-                                    -0.0039159061, 1.0880732308, -0.0841573249, 
-                                    -0.0299072021, -0.0264325799, 1.0563397820]),
-            'direction':'forward'
-        })
-    elif gamut == 'S-Gamut3':
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':mat44FromMat33([0.7529825954, 0.1433702162, 0.1036471884, 
-                        0.0217076974, 1.0153188355, -0.0370265329, 
-                        -0.0094160528, 0.0033704179, 1.0060456349]),
-            'direction':'forward'
-        })
-
-    cs.fromReferenceTransforms = []
-    return cs
-
-def createColorSpaces(lutDir, lutResolution1d):
-    colorspaces = []
-
-    # SLog1
-    SLog1SGamut = createSlog("S-Gamut", "S-Log1", "S-Log", lutDir, lutResolution1d)
-    colorspaces.append(SLog1SGamut)
-
-    # SLog2
-    SLog2SGamut = createSlog("S-Gamut", "S-Log2", "S-Log2", lutDir, lutResolution1d)
-    colorspaces.append(SLog2SGamut)
-
-    SLog2SGamutDaylight = createSlog("S-Gamut Daylight", "S-Log2", "S-Log2", lutDir, lutResolution1d)
-    colorspaces.append(SLog2SGamutDaylight)
-
-    SLog2SGamutTungsten = createSlog("S-Gamut Tungsten", "S-Log2", "S-Log2", lutDir, lutResolution1d)
-    colorspaces.append(SLog2SGamutTungsten)
-
-    # SLog3
-    SLog3SGamut3Cine = createSlog("S-Gamut3.Cine", "S-Log3", "S-Log3", lutDir, lutResolution1d)
-    colorspaces.append(SLog3SGamut3Cine)
-
-    SLog3SGamut3 = createSlog("S-Gamut3", "S-Log3", "S-Log3", lutDir, lutResolution1d)
-    colorspaces.append(SLog3SGamut3)
-
-    # Linearization only
-    SLog1 = createSlog("", "S-Log1", "S-Log", lutDir, lutResolution1d)
-    colorspaces.append(SLog1)
-
-    SLog2 = createSlog("", "S-Log2", "S-Log2", lutDir, lutResolution1d)
-    colorspaces.append(SLog2)
-
-    SLog3 = createSlog("", "S-Log3", "S-Log3", lutDir, lutResolution1d)
-    colorspaces.append(SLog3)
-
-    # Primaries only
-    SGamut = createSlog("S-Gamut", "", "S-Log", lutDir, lutResolution1d)
-    colorspaces.append(SGamut)
-
-    SGamutDaylight = createSlog("S-Gamut Daylight", "", "S-Log2", lutDir, lutResolution1d)
-    colorspaces.append(SGamutDaylight)
-
-    SGamutTungsten = createSlog("S-Gamut Tungsten", "", "S-Log2", lutDir, lutResolution1d)
-    colorspaces.append(SGamutTungsten)
-
-    SGamut3Cine = createSlog("S-Gamut3.Cine", "", "S-Log3", lutDir, lutResolution1d)
-    colorspaces.append(SGamut3Cine)
-
-    SGamut3 = createSlog("S-Gamut3", "", "S-Log3", lutDir, lutResolution1d)
-    colorspaces.append(SGamut3)
-
-    return colorspaces
-
diff --git a/aces_1.0.0/python/create_aces_config.py b/aces_1.0.0/python/create_aces_config.py
deleted file mode 100755 (executable)
index 2ff8b85..0000000
+++ /dev/null
@@ -1,1505 +0,0 @@
-'''
-usage from python
-
-import sys
-sys.path.append( "/path/to/script" )
-import create_aces_config as cac
-acesReleaseCTLDir = "/path/to/github/checkout/releases/v0.7.1/transforms/ctl"
-configDir = "/path/to/config/dir"
-cac.createACESConfig(acesReleaseCTLDir, configDir, 1024, 33, True)
-
-usage from command line, from the directory with 'create_aces_config.py'
-python create_aces_config.py -a "/path/to/github/checkout/releases/v0.7.1/transforms/ctl" -c "/path/to/config/dir" --lutResolution1d 1024 --lutResolution3d 33 --keepTempImages
-
-
-
-build instructions for osx for needed packages.
-
-#opencolorio
-brew install -vd opencolorio --with-python
-
-#openimageio
-brew tap homebrew/science
-
-# optional installs
-brew install -vd libRaw
-brew install -vd OpenCV
-
-brew install -vd openimageio --with-python
-
-#ctl
-brew install -vd CTL
-
-#opencolorio - again.
-# this time, 'ociolutimage' will build because openimageio is installed
-brew uninstall -vd opencolorio
-brew install -vd opencolorio --with-python
-'''
-
-import sys
-import os
-import array
-import shutil
-import string
-import pprint
-import math
-import numpy
-
-import OpenImageIO as oiio
-import PyOpenColorIO as OCIO
-
-import process
-from util import *
-
-import generateLUT as genlut
-import createREDColorSpaces as red
-import createCanonColorSpaces as canon
-import createSonyColorSpaces as sony
-import createARRIColorSpaces as arri
-
-#
-# Utility functions
-#
-def setConfigDefaultRoles( config, 
-    color_picking="",
-    color_timing="",
-    compositing_log="",
-    data="",
-    default="",
-    matte_paint="",
-    reference="",
-    scene_linear="",
-    texture_paint=""):
-    
-    # Add Roles
-    if color_picking: config.setRole( OCIO.Constants.ROLE_COLOR_PICKING, color_picking )
-    if color_timing: config.setRole( OCIO.Constants.ROLE_COLOR_TIMING, color_timing )
-    if compositing_log: config.setRole( OCIO.Constants.ROLE_COMPOSITING_LOG, compositing_log )
-    if data: config.setRole( OCIO.Constants.ROLE_DATA, data )
-    if default: config.setRole( OCIO.Constants.ROLE_DEFAULT, default )
-    if matte_paint: config.setRole( OCIO.Constants.ROLE_MATTE_PAINT, matte_paint )
-    if reference: config.setRole( OCIO.Constants.ROLE_REFERENCE, reference )
-    if scene_linear: config.setRole( OCIO.Constants.ROLE_SCENE_LINEAR, scene_linear )
-    if texture_paint: config.setRole( OCIO.Constants.ROLE_TEXTURE_PAINT, texture_paint )
-
-# Write config to disk
-def writeConfig( config, configPath, sanityCheck=True ):
-    if sanityCheck:
-        try:
-            config.sanityCheck()
-        except Exception,e:
-            print e
-            print "Configuration was not written due to a failed Sanity Check"
-            return
-            #sys.exit()
-
-    fileHandle = open( configPath, mode='w' )
-    fileHandle.write( config.serialize() )
-    fileHandle.close()
-
-def generateOCIOTransform(transforms):
-    #print( "Generating transforms")
-
-    interpolationOptions = { 
-        'linear':OCIO.Constants.INTERP_LINEAR,
-        'nearest':OCIO.Constants.INTERP_NEAREST, 
-        'tetrahedral':OCIO.Constants.INTERP_TETRAHEDRAL 
-    }
-    directionOptions = { 
-        'forward':OCIO.Constants.TRANSFORM_DIR_FORWARD,
-        'inverse':OCIO.Constants.TRANSFORM_DIR_INVERSE 
-    }
-
-    ocioTransforms = []
-
-    for transform in transforms:
-        if transform['type'] == 'lutFile':
-
-            ocioTransform = OCIO.FileTransform( src=transform['path'],
-                interpolation=interpolationOptions[transform['interpolation']],
-                direction=directionOptions[transform['direction']] )
-
-            ocioTransforms.append(ocioTransform)
-        elif transform['type'] == 'matrix':
-            ocioTransform = OCIO.MatrixTransform()
-            # MatrixTransform member variables can't be initialized directly. Each must be set individually
-            ocioTransform.setMatrix( transform['matrix'] )
-
-            if 'offset' in transform:
-                ocioTransform.setOffset( transform['offset'] )
-            if 'direction' in transform:
-                ocioTransform.setDirection( directionOptions[transform['direction']] )
-
-            ocioTransforms.append(ocioTransform)
-        elif transform['type'] == 'exponent':
-            ocioTransform = OCIO.ExponentTransform()
-            ocioTransform.setValue( transform['value'] )
-
-            ocioTransforms.append(ocioTransform)
-        elif transform['type'] == 'log':
-            ocioTransform = OCIO.LogTransform(base=transform['base'],
-                direction=directionOptions[transform['direction']])
-
-            ocioTransforms.append(ocioTransform)
-        else:
-            print( "Ignoring unknown transform type : %s" % transform['type'] )
-
-    # Build a group transform if necessary
-    if len(ocioTransforms) > 1:
-        transformG = OCIO.GroupTransform()
-        for transform in ocioTransforms:
-            transformG.push_back( transform )
-        transform = transformG
-
-    # Or take the first transform from the list
-    else:
-        transform = ocioTransforms[0]
-
-    return transform
-
-def createConfig(configData, nuke=False):
-    # Create the config
-    config = OCIO.Config()
-    
-    #
-    # Set config wide values
-    #
-    config.setDescription( "An ACES config generated from python" )
-    config.setSearchPath( "luts" )
-    
-    #
-    # Define the reference color space
-    #
-    referenceData = configData['referenceColorSpace']
-    print( "Adding the reference color space : %s" % referenceData.name)
-
-    # Create a color space
-    reference = OCIO.ColorSpace( name=referenceData.name, 
-        bitDepth=referenceData.bitDepth, 
-        description=referenceData.description, 
-        equalityGroup=referenceData.equalityGroup, 
-        family=referenceData.family, 
-        isData=referenceData.isData, 
-        allocation=referenceData.allocationType, 
-        allocationVars=referenceData.allocationVars ) 
-
-    # Add to config
-    config.addColorSpace( reference )
-
-    #
-    # Create the rest of the color spaces
-    #
-    for colorspace in sorted(configData['colorSpaces']):
-        print( "Creating new color space : %s" % colorspace.name)
-
-        ocioColorspace = OCIO.ColorSpace( name=colorspace.name, 
-            bitDepth=colorspace.bitDepth, 
-            description=colorspace.description, 
-            equalityGroup=colorspace.equalityGroup, 
-            family=colorspace.family, 
-            isData=colorspace.isData,
-            allocation=colorspace.allocationType, 
-            allocationVars=colorspace.allocationVars ) 
-
-        if colorspace.toReferenceTransforms != []:
-            print( "Generating To-Reference transforms")
-            ocioTransform = generateOCIOTransform(colorspace.toReferenceTransforms)
-            ocioColorspace.setTransform( ocioTransform, OCIO.Constants.COLORSPACE_DIR_TO_REFERENCE )
-
-        if colorspace.fromReferenceTransforms != []:
-            print( "Generating From-Reference transforms")
-            ocioTransform = generateOCIOTransform(colorspace.fromReferenceTransforms)
-            ocioColorspace.setTransform( ocioTransform, OCIO.Constants.COLORSPACE_DIR_FROM_REFERENCE )
-
-        config.addColorSpace(ocioColorspace)
-
-        print( "" )
-
-    #
-    # Define the views and displays
-    #
-    displays = []
-    views = []
-
-    # Generic display and view setup
-    if not nuke:
-        for display, viewList in configData['displays'].iteritems():
-            for viewName, colorspace in viewList.iteritems():
-                config.addDisplay( display, viewName, colorspace.name )
-                if not (viewName in views):
-                    views.append(viewName)
-            displays.append(display)
-    # A Nuke specific set of views and displays
-    #
-    # XXX
-    # A few names: Output Transform, ACES, ACEScc, are hard-coded here. Would be better to automate
-    #
-    else:
-        for display, viewList in configData['displays'].iteritems():
-            for viewName, colorspace in viewList.iteritems():
-                if( viewName == 'Output Transform'):
-                    viewName = 'View'
-                    config.addDisplay( display, viewName, colorspace.name )
-                    if not (viewName in views):
-                        views.append(viewName)
-            displays.append(display)
-
-        config.addDisplay( 'linear', 'View', 'ACES2065-1' )
-        displays.append('linear')
-        config.addDisplay( 'log', 'View', 'ACEScc' )
-        displays.append('log')
-
-    # Set active displays and views
-    config.setActiveDisplays( ','.join(sorted(displays)) )
-    config.setActiveViews( ','.join(views) )
-
-    #
-    # Need to generalize this at some point
-    #
-
-    # Add Default Roles
-    setConfigDefaultRoles( config, 
-        color_picking=reference.getName(),
-        color_timing=reference.getName(),
-        compositing_log=reference.getName(),
-        data=reference.getName(),
-        default=reference.getName(),
-        matte_paint=reference.getName(),
-        reference=reference.getName(),
-        scene_linear=reference.getName(),
-        texture_paint=reference.getName() )
-
-    # Check to make sure we didn't screw something up
-    config.sanityCheck()
-
-    return config
-
-#
-# Functions to generate color space definitions and LUTs for transforms for a specific ACES release
-#
-
-# Output is a list of colorspaces and transforms that convert between those
-# colorspaces and reference color space, ACES
-def generateLUTs(odtInfo, lmtInfo, shaperName, acesCTLReleaseDir, lutDir, lutResolution1d=4096, lutResolution3d=64, cleanup=True):
-    print( "generateLUTs - begin" )
-    configData = {}
-
-    #
-    # Define the reference color space
-    #
-    ACES = ColorSpace('ACES2065-1')
-    ACES.description = "The Academy Color Encoding System reference color space"
-    ACES.equalityGroup = ''
-    ACES.family = 'ACES'
-    ACES.isData=False
-    ACES.allocationType=OCIO.Constants.ALLOCATION_LG2
-    ACES.allocationVars=[-15, 6]
-
-    configData['referenceColorSpace'] = ACES
-
-    #
-    # Define the displays
-    #
-    configData['displays'] = {}
-
-    #
-    # Define the other color spaces
-    #
-    configData['colorSpaces'] = []
-
-    # Matrix converting ACES AP1 primaries to AP0
-    acesAP1toAP0 = [ 0.6954522414, 0.1406786965, 0.1638690622,
-                     0.0447945634, 0.8596711185, 0.0955343182,
-                    -0.0055258826, 0.0040252103, 1.0015006723]
-
-    # Matrix converting ACES AP0 primaries to XYZ
-    acesAP0toXYZ = [0.9525523959,  0.0000000000,  0.0000936786,
-                    0.3439664498,  0.7281660966, -0.0721325464,
-                    0.0000000000,  0.0000000000,  1.0088251844]
-
-    #
-    # ACEScc
-    #
-    def createACEScc(name='ACEScc', minValue=0.0, maxValue=1.0, inputScale=1.0):
-        cs = ColorSpace(name)
-        cs.description = "The %s color space" % name
-        cs.equalityGroup = ''
-        cs.family = 'ACES'
-        cs.isData=False
-
-        ctls = [
-            '%s/ACEScc/ACEScsc.ACEScc_to_ACES.a1.0.0.ctl' % acesCTLReleaseDir,
-            # This transform gets back to the AP1 primaries
-            # Useful as the 1d LUT is only covering the transfer function
-            # The primaries switch is covered by the matrix below
-            '%s/ACEScg/ACEScsc.ACES_to_ACEScg.a1.0.0.ctl' % acesCTLReleaseDir
-        ]
-        lut = "%s_to_ACES.spi1d" % name
-
-        # Remove spaces and parentheses
-        lut = lut.replace(' ', '_').replace(')', '_').replace('(', '_')
-
-        genlut.generate1dLUTFromCTL( lutDir + "/" + lut, 
-            ctls, 
-            lutResolution1d, 
-            'float', 
-            inputScale,
-            1.0, 
-            {},
-            cleanup, 
-            acesCTLReleaseDir,
-            minValue,
-            maxValue)
-
-        cs.toReferenceTransforms = []
-        cs.toReferenceTransforms.append( {
-            'type':'lutFile', 
-            'path':lut, 
-            'interpolation':'linear', 
-            'direction':'forward'
-        } )
-
-        # AP1 primaries to AP0 primaries
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':mat44FromMat33(acesAP1toAP0),
-            'direction':'forward'
-        })
-
-        cs.fromReferenceTransforms = []
-        return cs
-
-    ACEScc = createACEScc()
-    configData['colorSpaces'].append(ACEScc)
-
-    #
-    # ACESproxy
-    #
-    def createACESProxy(name='ACESproxy'):
-        cs = ColorSpace(name)
-        cs.description = "The %s color space" % name
-        cs.equalityGroup = ''
-        cs.family = 'ACES'
-        cs.isData=False
-
-        ctls = [
-            '%s/ACESproxy/ACEScsc.ACESproxy10i_to_ACES.a1.0.0.ctl' % acesCTLReleaseDir,
-            # This transform gets back to the AP1 primaries
-            # Useful as the 1d LUT is only covering the transfer function
-            # The primaries switch is covered by the matrix below
-            '%s/ACEScg/ACEScsc.ACES_to_ACEScg.a1.0.0.ctl' % acesCTLReleaseDir
-        ]
-        lut = "%s_to_aces.spi1d" % name
-
-        # Remove spaces and parentheses
-        lut = lut.replace(' ', '_').replace(')', '_').replace('(', '_')
-
-        genlut.generate1dLUTFromCTL( lutDir + "/" + lut, 
-            ctls, 
-            lutResolution1d, 
-            'uint16', 
-            64.0,
-            1.0, 
-            {},
-            cleanup, 
-            acesCTLReleaseDir )
-
-        cs.toReferenceTransforms = []
-        cs.toReferenceTransforms.append( {
-            'type':'lutFile', 
-            'path':lut, 
-            'interpolation':'linear', 
-            'direction':'forward'
-        } )
-
-        # AP1 primaries to AP0 primaries
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':mat44FromMat33(acesAP1toAP0),
-            'direction':'forward'
-        })
-
-
-        cs.fromReferenceTransforms = []
-        return cs
-
-    ACESproxy = createACESProxy()
-    configData['colorSpaces'].append(ACESproxy)
-
-    #
-    # ACEScg
-    #
-    def createACEScg(name='ACEScg'):
-        cs = ColorSpace(name)
-        cs.description = "The %s color space" % name
-        cs.equalityGroup = ''
-        cs.family = 'ACES'
-        cs.isData=False
-
-        cs.toReferenceTransforms = []
-
-        # AP1 primaries to AP0 primaries
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':mat44FromMat33(acesAP1toAP0),
-            'direction':'forward'
-        })
-
-        cs.fromReferenceTransforms = []
-        return cs
-
-    ACEScg = createACEScg()
-    configData['colorSpaces'].append(ACEScg)
-
-    #
-    # ADX
-    #
-    def createADX(bitdepth=10, name='ADX'):
-        name = "%s%s" % (name, bitdepth)
-        cs = ColorSpace(name)
-        cs.description = "%s color space - used for film scans" % name
-        cs.equalityGroup = ''
-        cs.family = 'ADX'
-        cs.isData=False
-
-        if bitdepth == 10:
-            cs.bitDepth = bitDepth=OCIO.Constants.BIT_DEPTH_UINT10
-            adx_to_cdd = [1023.0/500.0, 0.0, 0.0, 0.0,
-                        0.0, 1023.0/500.0, 0.0, 0.0,
-                        0.0, 0.0, 1023.0/500.0, 0.0,
-                        0.0, 0.0, 0.0, 1.0]
-            offset = [-95.0/500.0, -95.0/500.0, -95.0/500.0, 0.0]
-        elif bitdepth == 16:
-            cs.bitDepth = bitDepth=OCIO.Constants.BIT_DEPTH_UINT16
-            adx_to_cdd = [65535.0/8000.0, 0.0, 0.0, 0.0,
-                        0.0, 65535.0/8000.0, 0.0, 0.0,
-                        0.0, 0.0, 65535.0/8000.0, 0.0,
-                        0.0, 0.0, 0.0, 1.0]
-            offset = [-1520.0/8000.0, -1520.0/8000.0, -1520.0/8000.0, 0.0]
-
-        cs.toReferenceTransforms = []
-
-        # Convert from ADX to Channel-Dependent Density
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':adx_to_cdd,
-            'offset':offset,
-            'direction':'forward'
-        })
-
-        # Convert from Channel-Dependent Density to Channel-Independent Density
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':[0.75573, 0.22197, 0.02230, 0,
-                        0.05901, 0.96928, -0.02829, 0,
-                        0.16134, 0.07406, 0.76460, 0,
-                        0.0, 0.0, 0.0, 1.0],
-            'direction':'forward'
-        })
-
-        # Copied from Alex Fry's adx_cid_to_rle.py
-        def createCIDtoRLELUT():
-            def interpolate1D(x, xp, fp):
-                return numpy.interp(x, xp, fp)
-
-            LUT_1D_xp = [-0.190000000000000, 
-                          0.010000000000000,
-                          0.028000000000000,
-                          0.054000000000000,
-                          0.095000000000000,
-                          0.145000000000000,
-                          0.220000000000000,
-                          0.300000000000000,
-                          0.400000000000000,
-                          0.500000000000000,
-                          0.600000000000000]
-
-            LUT_1D_fp = [-6.000000000000000, 
-                         -2.721718645000000,
-                         -2.521718645000000,
-                         -2.321718645000000,
-                         -2.121718645000000,
-                         -1.921718645000000,
-                         -1.721718645000000,
-                         -1.521718645000000,
-                         -1.321718645000000,
-                         -1.121718645000000,
-                         -0.926545676714876]
-
-            REF_PT = (7120.0 - 1520.0) / 8000.0 * (100.0 / 55.0) - math.log(0.18, 10.0)
-
-            def cid_to_rle(x):
-                if x <= 0.6:
-                    return interpolate1D(x, LUT_1D_xp, LUT_1D_fp)
-                return (100.0 / 55.0) * x - REF_PT
-
-            def Fit(value, fromMin, fromMax, toMin, toMax):
-                if fromMin == fromMax:
-                    raise ValueError("fromMin == fromMax")
-                return (value - fromMin) / (fromMax - fromMin) * (toMax - toMin) + toMin
-
-            NUM_SAMPLES = 2**12
-            RANGE = (-0.19, 3.0)
-            data = []
-            for i in xrange(NUM_SAMPLES):
-                x = i/(NUM_SAMPLES-1.0)
-                x = Fit(x, 0.0, 1.0, RANGE[0], RANGE[1])
-                data.append(cid_to_rle(x))
-
-            lut = 'ADX_CID_to_RLE.spi1d'
-            genlut.writeSPI1D(lutDir + "/" + lut, RANGE[0], RANGE[1], data, NUM_SAMPLES, 1)
-
-            return lut
-
-        # Convert Channel Independent Density values to Relative Log Exposure values
-        lut = createCIDtoRLELUT()
-        cs.toReferenceTransforms.append( {
-            'type':'lutFile', 
-            'path':lut, 
-            'interpolation':'linear', 
-            'direction':'forward'
-        })
-
-        # Convert Relative Log Exposure values to Relative Exposure values
-        cs.toReferenceTransforms.append( {
-            'type':'log', 
-            'base':10, 
-            'direction':'inverse'
-        })
-
-        # Convert Relative Exposure values to ACES values
-        cs.toReferenceTransforms.append( {
-            'type':'matrix',
-            'matrix':[0.72286, 0.12630, 0.15084, 0,
-                        0.11923, 0.76418, 0.11659, 0,
-                        0.01427, 0.08213, 0.90359, 0,
-                        0.0, 0.0, 0.0, 1.0],
-            'direction':'forward'
-        })
-
-        cs.fromReferenceTransforms = []
-        return cs
-
-    ADX10 = createADX(bitdepth=10)
-    configData['colorSpaces'].append(ADX10)
-
-    ADX16 = createADX(bitdepth=16)
-    configData['colorSpaces'].append(ADX16)
-
-    #
-    # Camera Input Transforms
-    #
-
-    # RED color spaces to ACES
-    redColorSpaces = red.createColorSpaces(lutDir, lutResolution1d)
-    for cs in redColorSpaces:
-        configData['colorSpaces'].append(cs)
-
-    # Canon-Log to ACES
-    canonColorSpaces = canon.createColorSpaces(lutDir, lutResolution1d)
-    for cs in canonColorSpaces:
-        configData['colorSpaces'].append(cs)
-
-    # SLog to ACES
-    sonyColorSpaces = sony.createColorSpaces(lutDir, lutResolution1d)
-    for cs in sonyColorSpaces:
-        configData['colorSpaces'].append(cs)
-
-    # LogC to ACES
-    arriColorSpaces = arri.createColorSpaces(lutDir, lutResolution1d)
-    for cs in arriColorSpaces:
-        configData['colorSpaces'].append(cs)
-
-    #
-    # Generic log transform
-    #
-    def createGenericLog(name='log', 
-        minValue=0.0, 
-        maxValue=1.0, 
-        inputScale=1.0,
-        middleGrey=0.18,
-        minExposure=-6.0,
-        maxExposure=6.5,
-        lutResolution1d=lutResolution1d):
-        cs = ColorSpace(name)
-        cs.description = "The %s color space" % name
-        cs.equalityGroup = name
-        cs.family = 'Utility'
-        cs.isData=False
-
-        ctls = [
-            '%s/utilities/ACESlib.OCIO_shaper_log2_to_lin_param.a1.0.0.ctl' % acesCTLReleaseDir
-        ]
-        lut = "%s_to_aces.spi1d" % name
-
-        # Remove spaces and parentheses
-        lut = lut.replace(' ', '_').replace(')', '_').replace('(', '_')
-
-        genlut.generate1dLUTFromCTL( lutDir + "/" + lut, 
-            ctls, 
-            lutResolution1d, 
-            'float', 
-            inputScale,
-            1.0, 
-            {
-                'middleGrey'  : middleGrey,
-                'minExposure' : minExposure,
-                'maxExposure' : maxExposure
-            },
-            cleanup, 
-            acesCTLReleaseDir,
-            minValue,
-            maxValue)
-
-        cs.toReferenceTransforms = []
-        cs.toReferenceTransforms.append( {
-            'type':'lutFile', 
-            'path':lut, 
-            'interpolation':'linear', 
-            'direction':'forward'
-        } )
-
-        cs.fromReferenceTransforms = []
-        return cs
-
-    #
-    # ACES LMTs
-    #
-    def createACESLMT(lmtName, 
-        lmtValues,
-        shaperInfo,
-        lutResolution1d=1024, 
-        lutResolution3d=64, 
-        cleanup=True):
-        cs = ColorSpace("%s" % lmtName)
-        cs.description = "The ACES Look Transform: %s" % lmtName
-        cs.equalityGroup = ''
-        cs.family = 'Look'
-        cs.isData=False
-
-        import pprint
-        pprint.pprint( lmtValues )
-
-        #
-        # Generate the shaper transform
-        #
-        (shaperName, shaperToACESCTL, shaperFromACESCTL, shaperInputScale, shaperParams) = shaperInfo
-
-        shaperLut = "%s_to_aces.spi1d" % shaperName
-        if( not os.path.exists( lutDir + "/" + shaperLut ) ):
-            ctls = [
-                shaperToACESCTL % acesCTLReleaseDir
-            ]
-            
-            # Remove spaces and parentheses
-            shaperLut = shaperLut.replace(' ', '_').replace(')', '_').replace('(', '_')
-
-            genlut.generate1dLUTFromCTL( lutDir + "/" + shaperLut, 
-                ctls, 
-                lutResolution1d, 
-                'float', 
-                1.0/shaperInputScale,
-                1.0, 
-                shaperParams,
-                cleanup, 
-                acesCTLReleaseDir)
-
-        shaperOCIOTransform = {
-            'type':'lutFile', 
-            'path':shaperLut, 
-            'interpolation':'linear', 
-            'direction':'inverse'
-        }
-
-        #
-        # Generate the forward transform
-        #
-        cs.fromReferenceTransforms = []
-
-        if 'transformCTL' in lmtValues:
-            ctls = [
-                shaperToACESCTL % acesCTLReleaseDir, 
-                '%s/%s' % (acesCTLReleaseDir, lmtValues['transformCTL'])
-            ]
-            lut = "%s.%s.spi3d" % (shaperName, lmtName)
-
-            # Remove spaces and parentheses
-            lut = lut.replace(' ', '_').replace(')', '_').replace('(', '_')
-
-            genlut.generate3dLUTFromCTL( lutDir + "/" + lut, 
-                ctls, 
-                lutResolution3d, 
-                'float', 
-                1.0/shaperInputScale,
-                1.0, 
-                shaperParams,
-                cleanup, 
-                acesCTLReleaseDir )
-
-            cs.fromReferenceTransforms.append( shaperOCIOTransform )
-            cs.fromReferenceTransforms.append( {
-                'type':'lutFile', 
-                'path':lut, 
-                'interpolation':'tetrahedral', 
-                'direction':'forward'
-            } )
-
-        #
-        # Generate the inverse transform
-        #
-        cs.toReferenceTransforms = []
-
-        if 'transformCTLInverse' in lmtValues:
-            ctls = [
-                '%s/%s' % (acesCTLReleaseDir, odtValues['transformCTLInverse']),
-                shaperFromACESCTL % acesCTLReleaseDir
-            ]
-            lut = "Inverse.%s.%s.spi3d" % (odtName, shaperName)
-
-            # Remove spaces and parentheses
-            lut = lut.replace(' ', '_').replace(')', '_').replace('(', '_')
-
-            genlut.generate3dLUTFromCTL( lutDir + "/" + lut, 
-                ctls, 
-                lutResolution3d, 
-                'half', 
-                1.0,
-                shaperInputScale, 
-                shaperParams,
-                cleanup, 
-                acesCTLReleaseDir )
-
-            cs.toReferenceTransforms.append( {
-                'type':'lutFile', 
-                'path':lut, 
-                'interpolation':'tetrahedral', 
-                'direction':'forward'
-            } )
-
-            shaperInverse = shaperOCIOTransform.copy()
-            shaperInverse['direction'] = 'forward'
-            cs.toReferenceTransforms.append( shaperInverse )
-
-        return cs
-
-    #
-    # LMT Shaper
-    #
-
-    lmtLutResolution1d = max(4096, lutResolution1d)
-    lmtLutResolution3d = max(65, lutResolution3d)
-
-    # Log 2 shaper
-    lmtShaperName = 'LMT Shaper'
-    lmtParams = {
-        'middleGrey'  : 0.18,
-        'minExposure' : -10.0,
-        'maxExposure' : 6.5
-    }
-    lmtShaper = createGenericLog(name=lmtShaperName, 
-        middleGrey=lmtParams['middleGrey'], 
-        minExposure=lmtParams['minExposure'], 
-        maxExposure=lmtParams['maxExposure'],
-        lutResolution1d=lmtLutResolution1d)
-    configData['colorSpaces'].append(lmtShaper)
-
-    shaperInputScale_genericLog2 = 1.0
-
-    # Log 2 shaper name and CTL transforms bundled up
-    lmtShaperData = [
-        lmtShaperName, 
-        '%s/utilities/ACESlib.OCIO_shaper_log2_to_lin_param.a1.0.0.ctl',
-        '%s/utilities/ACESlib.OCIO_shaper_lin_to_log2_param.a1.0.0.ctl',
-        shaperInputScale_genericLog2,
-        lmtParams
-    ]
-
-    sortedLMTs = sorted(lmtInfo.iteritems(), key=lambda x: x[1])
-    print( sortedLMTs )
-    for lmt in sortedLMTs:
-        (lmtName, lmtValues) = lmt
-        cs = createACESLMT(
-            lmtValues['transformUserName'], 
-            lmtValues,
-            lmtShaperData,
-            lmtLutResolution1d,
-            lmtLutResolution3d,
-            cleanup)
-        configData['colorSpaces'].append(cs)
-
-    #
-    # ACES RRT with the supplied ODT
-    #
-    def createACESRRTplusODT(odtName, 
-        odtValues,
-        shaperInfo,
-        lutResolution1d=1024, 
-        lutResolution3d=64, 
-        cleanup=True):
-        cs = ColorSpace("%s" % odtName)
-        cs.description = "%s - %s Output Transform" % (odtValues['transformUserNamePrefix'], odtName)
-        cs.equalityGroup = ''
-        cs.family = 'Output'
-        cs.isData=False
-
-        import pprint
-        pprint.pprint( odtValues )
-
-        #
-        # Generate the shaper transform
-        #
-        #if 'shaperCTL' in odtValues:
-        (shaperName, shaperToACESCTL, shaperFromACESCTL, shaperInputScale, shaperParams) = shaperInfo
-
-        if 'legalRange' in odtValues:
-            shaperParams['legalRange'] = odtValues['legalRange']
-        else:
-            shaperParams['legalRange'] = 0
-
-        shaperLut = "%s_to_aces.spi1d" % shaperName
-        if( not os.path.exists( lutDir + "/" + shaperLut ) ):
-            ctls = [
-                shaperToACESCTL % acesCTLReleaseDir
-            ]
-
-            # Remove spaces and parentheses
-            shaperLut = shaperLut.replace(' ', '_').replace(')', '_').replace('(', '_')
-
-            genlut.generate1dLUTFromCTL( lutDir + "/" + shaperLut, 
-                ctls, 
-                lutResolution1d, 
-                'float', 
-                1.0/shaperInputScale,
-                1.0, 
-                shaperParams,
-                cleanup, 
-                acesCTLReleaseDir)
-
-        shaperOCIOTransform = {
-            'type':'lutFile', 
-            'path':shaperLut, 
-            'interpolation':'linear', 
-            'direction':'inverse'
-        }
-
-        #
-        # Generate the forward transform
-        #
-        cs.fromReferenceTransforms = []
-
-        if 'transformLUT' in odtValues:
-            # Copy into the lut dir
-            transformLUTFileName = os.path.basename(odtValues['transformLUT'])
-            lut = lutDir + "/" + transformLUTFileName
-            shutil.copy(odtValues['transformLUT'], lut)
-
-            cs.fromReferenceTransforms.append( shaperOCIOTransform )
-            cs.fromReferenceTransforms.append( {
-                'type':'lutFile', 
-                'path': transformLUTFileName, 
-                'interpolation':'tetrahedral', 
-                'direction':'forward'
-            } )
-        elif 'transformCTL' in odtValues:
-            #shaperLut
-
-            ctls = [
-                shaperToACESCTL % acesCTLReleaseDir, 
-                '%s/rrt/RRT.a1.0.0.ctl' % acesCTLReleaseDir, 
-                '%s/odt/%s' % (acesCTLReleaseDir, odtValues['transformCTL'])
-            ]
-            lut = "%s.RRT.a1.0.0.%s.spi3d" % (shaperName, odtName)
-
-            # Remove spaces and parentheses
-            lut = lut.replace(' ', '_').replace(')', '_').replace('(', '_')
-
-            genlut.generate3dLUTFromCTL( lutDir + "/" + lut, 
-                #shaperLUT,
-                ctls, 
-                lutResolution3d, 
-                'float', 
-                1.0/shaperInputScale,
-                1.0, 
-                shaperParams,
-                cleanup, 
-                acesCTLReleaseDir )
-
-            cs.fromReferenceTransforms.append( shaperOCIOTransform )
-            cs.fromReferenceTransforms.append( {
-                'type':'lutFile', 
-                'path':lut, 
-                'interpolation':'tetrahedral', 
-                'direction':'forward'
-            } )
-
-        #
-        # Generate the inverse transform
-        #
-        cs.toReferenceTransforms = []
-
-        if 'transformLUTInverse' in odtValues:
-            # Copy into the lut dir
-            transformLUTInverseFileName = os.path.basename(odtValues['transformLUTInverse'])
-            lut = lutDir + "/" + transformLUTInverseFileName
-            shutil.copy(odtValues['transformLUTInverse'], lut)
-
-            cs.toReferenceTransforms.append( {
-                'type':'lutFile', 
-                'path': transformLUTInverseFileName, 
-                'interpolation':'tetrahedral', 
-                'direction':'forward'
-            } )
-
-            shaperInverse = shaperOCIOTransform.copy()
-            shaperInverse['direction'] = 'forward'
-            cs.toReferenceTransforms.append( shaperInverse )
-        elif 'transformCTLInverse' in odtValues:
-            ctls = [
-                '%s/odt/%s' % (acesCTLReleaseDir, odtValues['transformCTLInverse']),
-                '%s/rrt/InvRRT.a1.0.0.ctl' % acesCTLReleaseDir,
-                shaperFromACESCTL % acesCTLReleaseDir
-            ]
-            lut = "InvRRT.a1.0.0.%s.%s.spi3d" % (odtName, shaperName)
-
-            # Remove spaces and parentheses
-            lut = lut.replace(' ', '_').replace(')', '_').replace('(', '_')
-
-            genlut.generate3dLUTFromCTL( lutDir + "/" + lut, 
-                #None,
-                ctls, 
-                lutResolution3d, 
-                'half', 
-                1.0,
-                shaperInputScale, 
-                shaperParams,
-                cleanup, 
-                acesCTLReleaseDir )
-
-            cs.toReferenceTransforms.append( {
-                'type':'lutFile', 
-                'path':lut, 
-                'interpolation':'tetrahedral', 
-                'direction':'forward'
-            } )
-
-            shaperInverse = shaperOCIOTransform.copy()
-            shaperInverse['direction'] = 'forward'
-            cs.toReferenceTransforms.append( shaperInverse )
-
-        return cs
-
-    #
-    # RRT/ODT shaper options
-    #
-    shaperData = {}
-
-    # Log 2 shaper
-    log2ShaperName = shaperName
-    log2Params = {
-        'middleGrey'  : 0.18,
-        'minExposure' : -6.0,
-        'maxExposure' : 6.5
-    }
-    log2Shaper = createGenericLog(name=log2ShaperName, 
-        middleGrey=log2Params['middleGrey'], 
-        minExposure=log2Params['minExposure'], 
-        maxExposure=log2Params['maxExposure'])
-    configData['colorSpaces'].append(log2Shaper)
-
-    shaperInputScale_genericLog2 = 1.0
-
-    # Log 2 shaper name and CTL transforms bundled up
-    log2ShaperData = [
-        log2ShaperName, 
-        '%s/utilities/ACESlib.OCIO_shaper_log2_to_lin_param.a1.0.0.ctl',
-        '%s/utilities/ACESlib.OCIO_shaper_lin_to_log2_param.a1.0.0.ctl',
-        shaperInputScale_genericLog2,
-        log2Params
-    ]
-
-    shaperData[log2ShaperName] = log2ShaperData
-
-    #
-    # Shaper that also includes the AP1 primaries
-    # - Needed for some LUT baking steps
-    #
-    log2ShaperAP1 = createGenericLog(name=log2ShaperName, 
-        middleGrey=log2Params['middleGrey'], 
-        minExposure=log2Params['minExposure'], 
-        maxExposure=log2Params['maxExposure'])
-    log2ShaperAP1.name = "%s - AP1" % log2ShaperAP1.name
-    # AP1 primaries to AP0 primaries
-    log2ShaperAP1.toReferenceTransforms.append( {
-        'type':'matrix',
-        'matrix':mat44FromMat33(acesAP1toAP0),
-        'direction':'forward'
-    })
-    configData['colorSpaces'].append(log2ShaperAP1)
-
-    #
-    # Choose your shaper
-    #
-    rrtShaperName = log2ShaperName
-    rrtShaper = log2ShaperData
-
-    #
-    # RRT + ODT Combinations
-    #
-    sortedOdts = sorted(odtInfo.iteritems(), key=lambda x: x[1])
-    print( sortedOdts )
-    for odt in sortedOdts:
-        (odtName, odtValues) = odt
-
-        # Have to handle ODTs that can generate either legal or full output
-        if odtName in ['Academy.Rec2020_100nits_dim.a1.0.0', 
-                'Academy.Rec709_100nits_dim.a1.0.0',
-                'Academy.Rec709_D60sim_100nits_dim.a1.0.0']:
-            odtNameLegal = '%s - Legal' % odtValues['transformUserName']
-        else:
-            odtNameLegal = odtValues['transformUserName']
-
-        odtLegal = odtValues.copy()
-        odtLegal['legalRange'] = 1
-
-        cs = createACESRRTplusODT(
-            odtNameLegal, 
-            odtLegal,
-            rrtShaper,
-            lutResolution1d,
-            lutResolution3d,
-            cleanup)
-        configData['colorSpaces'].append(cs)
-
-        # Create a display entry using this color space
-        configData['displays'][odtNameLegal] = { 
-            'Linear':ACES, 
-            'Log':ACEScc, 
-            'Output Transform':cs }
-
-        if odtName in ['Academy.Rec2020_100nits_dim.a1.0.0', 
-                'Academy.Rec709_100nits_dim.a1.0.0', 
-                'Academy.Rec709_D60sim_100nits_dim.a1.0.0']:
-
-            print( "Generating full range ODT for %s" % odtName)
-
-            odtNameFull = "%s - Full" % odtValues['transformUserName']
-            odtFull = odtValues.copy()
-            odtFull['legalRange'] = 0
-
-            csFull = createACESRRTplusODT(
-                odtNameFull, 
-                odtFull,
-                rrtShaper,
-                lutResolution1d,
-                lutResolution3d,
-                cleanup)
-            configData['colorSpaces'].append(csFull)
-
-            # Create a display entry using this color space
-            configData['displays'][odtNameFull] = { 
-                'Linear':ACES, 
-                'Log':ACEScc, 
-                'Output Transform':csFull }
-
-    #
-    # Generic Matrix transform
-    #
-    def createGenericMatrix(name='matrix', 
-        fromReferenceValues=[],
-        toReferenceValues=[]):
-        cs = ColorSpace(name)
-        cs.description = "The %s color space" % name
-        cs.equalityGroup = name
-        cs.family = 'Utility'
-        cs.isData=False
-
-        cs.toReferenceTransforms = []
-        if toReferenceValues != []:
-            for matrix in toReferenceValues:
-                cs.toReferenceTransforms.append( {
-                    'type':'matrix',
-                    'matrix':mat44FromMat33(matrix),
-                    'direction':'forward'
-                })
-
-        cs.fromReferenceTransforms = []
-        if fromReferenceValues != []:
-            for matrix in fromReferenceValues:
-                cs.fromReferenceTransforms.append( {
-                    'type':'matrix',
-                    'matrix':mat44FromMat33(matrix),
-                    'direction':'forward'
-                })
-
-        return cs
-
-    cs = createGenericMatrix('XYZ', fromReferenceValues=[acesAP0toXYZ])
-    configData['colorSpaces'].append(cs)   
-
-    cs = createGenericMatrix('Linear - AP1', toReferenceValues=[acesAP1toAP0])
-    configData['colorSpaces'].append(cs)   
-
-    # ACES to Linear, P3D60 primaries
-    xyzToP3D60 = [ 2.4027414142, -0.8974841639, -0.3880533700,
-                  -0.8325796487,  1.7692317536,  0.0237127115,
-                   0.0388233815, -0.0824996856,  1.0363685997]
-
-    cs = createGenericMatrix('Linear - P3-D60', fromReferenceValues=[acesAP0toXYZ, xyzToP3D60])
-    configData['colorSpaces'].append(cs)   
-
-    # ACES to Linear, P3D60 primaries
-    xyzToP3DCI = [ 2.7253940305, -1.0180030062, -0.4401631952,
-                  -0.7951680258,  1.6897320548,  0.0226471906,
-                   0.0412418914, -0.0876390192,  1.1009293786]
-
-    cs = createGenericMatrix('Linear - P3-DCI', fromReferenceValues=[acesAP0toXYZ, xyzToP3DCI])
-    configData['colorSpaces'].append(cs)   
-
-    # ACES to Linear, Rec 709 primaries
-    xyzToRec709 = [ 3.2409699419, -1.5373831776, -0.4986107603,
-                   -0.9692436363,  1.8759675015,  0.0415550574,
-                    0.0556300797, -0.2039769589,  1.0569715142]
-
-    cs = createGenericMatrix('Linear - Rec.709', fromReferenceValues=[acesAP0toXYZ, xyzToRec709])
-    configData['colorSpaces'].append(cs)   
-
-    # ACES to Linear, Rec 2020 primaries
-    xyzToRec2020 = [ 1.7166511880, -0.3556707838, -0.2533662814,
-                    -0.6666843518,  1.6164812366,  0.0157685458,
-                     0.0176398574, -0.0427706133,  0.9421031212]
-
-    cs = createGenericMatrix('Linear - Rec.2020', fromReferenceValues=[acesAP0toXYZ, xyzToRec2020])
-    configData['colorSpaces'].append(cs)   
-
-    print( "generateLUTs - end" )
-    return configData
-
-def generateBakedLUTs(odtInfo, shaperName, bakedDir, configPath, lutResolution1d, lutResolution3d, lutResolutionShaper=1024):
-    # Add the legal and full variations into this list
-    odtInfoC = dict(odtInfo)
-    for odtCTLName, odtValues in odtInfo.iteritems():
-        if odtCTLName in ['Academy.Rec2020_100nits_dim.a1.0.0', 
-            'Academy.Rec709_100nits_dim.a1.0.0',
-            'Academy.Rec709_D60sim_100nits_dim.a1.0.0']:
-                odtName = odtValues["transformUserName"]
-
-                odtValuesLegal = dict(odtValues)
-                odtValuesLegal["transformUserName"] = "%s - Legal" % odtName
-                odtInfoC["%s - Legal" % odtCTLName] = odtValuesLegal
-
-                odtValuesFull = dict(odtValues)
-                odtValuesFull["transformUserName"] = "%s - Full" % odtName
-                odtInfoC["%s - Full" % odtCTLName] = odtValuesFull
-                
-                del( odtInfoC[odtCTLName] )
-
-    for odtCTLName, odtValues in odtInfoC.iteritems():
-        odtPrefix = odtValues["transformUserNamePrefix"]
-        odtName = odtValues["transformUserName"]
-
-        # For Photoshop
-        for inputspace in ["ACEScc", "ACESproxy"]:
-            args =  ["--iconfig", configPath, "-v", "--inputspace", inputspace ]
-            args += ["--outputspace", "%s" % odtName ]
-            args += ["--description", "%s - %s for %s data" % (odtPrefix, odtName, inputspace) ]
-            args += ["--shaperspace", shaperName, "--shapersize", str(lutResolutionShaper) ] 
-            args += ["--cubesize", str(lutResolution3d) ]
-            args += ["--format", "icc", "%s/photoshop/%s for %s.icc" % (bakedDir, odtName, inputspace) ]
-
-            bakeLUT = process.Process(description="bake a LUT", cmd="ociobakelut", args=args)
-            bakeLUT.execute()    
-
-        # For Flame, Lustre
-        for inputspace in ["ACEScc", "ACESproxy"]:
-            args =  ["--iconfig", configPath, "-v", "--inputspace", inputspace ]
-            args += ["--outputspace", "%s" % odtName ]
-            args += ["--description", "%s - %s for %s data" % (odtPrefix, odtName, inputspace) ]
-            args += ["--shaperspace", shaperName, "--shapersize", str(lutResolutionShaper) ] 
-            args += ["--cubesize", str(lutResolution3d) ]
-
-            fargs = ["--format", "flame", "%s/flame/%s for %s Flame.3dl" % (bakedDir, odtName, inputspace) ]
-            bakeLUT = process.Process(description="bake a LUT", cmd="ociobakelut", args=(args + fargs))
-            bakeLUT.execute()    
-
-            largs = ["--format", "lustre", "%s/lustre/%s for %s Lustre.3dl" % (bakedDir, odtName, inputspace) ]
-            bakeLUT = process.Process(description="bake a LUT", cmd="ociobakelut", args=(args + largs))
-            bakeLUT.execute()
-
-        # For Maya, Houdini
-        for inputspace in ["ACEScg", "ACES2065-1"]:
-            args =  ["--iconfig", configPath, "-v", "--inputspace", inputspace ]
-            args += ["--outputspace", "%s" % odtName ]
-            args += ["--description", "%s - %s for %s data" % (odtPrefix, odtName, inputspace) ]
-            if inputspace == 'ACEScg':
-                linShaperName = "%s - AP1" % shaperName 
-            else:
-                linShaperName = shaperName
-            args += ["--shaperspace", linShaperName, "--shapersize", str(lutResolutionShaper) ] 
-            
-            args += ["--cubesize", str(lutResolution3d) ]
-
-            margs = ["--format", "cinespace", "%s/maya/%s for %s Maya.csp" % (bakedDir, odtName, inputspace) ]
-            bakeLUT = process.Process(description="bake a LUT", cmd="ociobakelut", args=(args + margs))
-            bakeLUT.execute()    
-
-            hargs = ["--format", "houdini", "%s/houdini/%s for %s Houdini.lut" % (bakedDir, odtName, inputspace) ]
-            bakeLUT = process.Process(description="bake a LUT", cmd="ociobakelut", args=(args + hargs))
-            bakeLUT.execute()    
-
-
-def createConfigDir(configDir, bakeSecondaryLUTs):
-    dirs = [configDir, "%s/luts" % configDir]
-    if bakeSecondaryLUTs:
-        dirs.extend(["%s/baked" % configDir, 
-            "%s/baked/flame" % configDir, "%s/baked/photoshop" % configDir,
-            "%s/baked/houdini" % configDir, "%s/baked/lustre" % configDir,
-            "%s/baked/maya" % configDir])
-
-    for d in dirs:
-        if not os.path.exists(d):
-            os.mkdir(d)
-
-def getTransformInfo(ctlTransform):
-    fp = open(ctlTransform, 'rb')
-
-    # Read lines
-    lines = fp.readlines()
-
-    # Grab transform ID and User Name
-    transformID = lines[1][3:].split('<')[1].split('>')[1].lstrip().rstrip()
-    #print( transformID )
-    transformUserName = '-'.join(lines[2][3:].split('<')[1].split('>')[1].split('-')[1:]).lstrip().rstrip()
-    transformUserNamePrefix = lines[2][3:].split('<')[1].split('>')[1].split('-')[0].lstrip().rstrip()
-    #print( transformUserName )
-    fp.close()
-
-    return (transformID, transformUserName, transformUserNamePrefix)
-
-# For versions after WGR9
-def getODTInfo(acesCTLReleaseDir):
-    # Credit to Alex Fry for the original approach here
-    odtDir = os.path.join(acesCTLReleaseDir, "odt")
-    allodt = []
-    for dirName, subdirList, fileList in os.walk(odtDir):
-        for fname in fileList:
-            allodt.append((os.path.join(dirName,fname)))
-
-    odtCTLs = [x for x in allodt if ("InvODT" not in x) and (os.path.split(x)[-1][0] != '.')]
-
-    #print odtCTLs
-
-    odts = {}
-
-    for odtCTL in odtCTLs:
-        odtTokens = os.path.split(odtCTL)
-        #print( odtTokens )
-
-        # Handle nested directories
-        odtPathTokens = os.path.split(odtTokens[-2])
-        odtDir = odtPathTokens[-1]
-        while odtPathTokens[-2][-3:] != 'odt':
-            odtPathTokens = os.path.split(odtPathTokens[-2])
-            odtDir = os.path.join(odtPathTokens[-1], odtDir)
-
-        # Build full name
-        #print( "odtDir : %s" % odtDir )
-        transformCTL = odtTokens[-1]
-        #print( transformCTL )
-        odtName = string.join(transformCTL.split('.')[1:-1], '.')
-        #print( odtName )
-
-        # Find id, user name and user name prefix
-        (transformID, transformUserName, transformUserNamePrefix) = getTransformInfo(
-            "%s/odt/%s/%s" % (acesCTLReleaseDir, odtDir, transformCTL) )
-
-        # Find inverse
-        transformCTLInverse = "InvODT.%s.ctl" % odtName
-        if not os.path.exists(os.path.join(odtTokens[-2], transformCTLInverse)):
-            transformCTLInverse = None
-        #print( transformCTLInverse )
-
-        # Add to list of ODTs
-        odts[odtName] = {}
-        odts[odtName]['transformCTL'] = os.path.join(odtDir, transformCTL)
-        if transformCTLInverse != None:
-            odts[odtName]['transformCTLInverse'] = os.path.join(odtDir, transformCTLInverse)
-
-        odts[odtName]['transformID'] = transformID
-        odts[odtName]['transformUserNamePrefix'] = transformUserNamePrefix
-        odts[odtName]['transformUserName'] = transformUserName
-
-        print( "ODT : %s" % odtName )
-        print( "\tTransform ID               : %s" % transformID )
-        print( "\tTransform User Name Prefix : %s" % transformUserNamePrefix )
-        print( "\tTransform User Name        : %s" % transformUserName )
-        print( "\tForward ctl                : %s" % odts[odtName]['transformCTL'])
-        if 'transformCTLInverse' in odts[odtName]:
-            print( "\tInverse ctl                : %s" % odts[odtName]['transformCTLInverse'])
-        else:
-            print( "\tInverse ctl                : %s" % "None" )
-
-    print( "\n" )
-
-    return odts
-
-# For versions after WGR9
-def getLMTInfo(acesCTLReleaseDir):
-    # Credit to Alex Fry for the original approach here
-    lmtDir = os.path.join(acesCTLReleaseDir, "lmt")
-    alllmt = []
-    for dirName, subdirList, fileList in os.walk(lmtDir):
-        for fname in fileList:
-            alllmt.append((os.path.join(dirName,fname)))
-
-    lmtCTLs = [x for x in alllmt if ("InvLMT" not in x) and ("README" not in x) and (os.path.split(x)[-1][0] != '.')]
-
-    #print lmtCTLs
-
-    lmts = {}
-
-    for lmtCTL in lmtCTLs:
-        lmtTokens = os.path.split(lmtCTL)
-        #print( lmtTokens )
-
-        # Handle nested directories
-        lmtPathTokens = os.path.split(lmtTokens[-2])
-        lmtDir = lmtPathTokens[-1]
-        while lmtPathTokens[-2][-3:] != 'ctl':
-            lmtPathTokens = os.path.split(lmtPathTokens[-2])
-            lmtDir = os.path.join(lmtPathTokens[-1], lmtDir)
-
-        # Build full name
-        #print( "lmtDir : %s" % lmtDir )
-        transformCTL = lmtTokens[-1]
-        #print( transformCTL )
-        lmtName = string.join(transformCTL.split('.')[1:-1], '.')
-        #print( lmtName )
-
-        # Find id, user name and user name prefix
-        (transformID, transformUserName, transformUserNamePrefix) = getTransformInfo(
-            "%s/%s/%s" % (acesCTLReleaseDir, lmtDir, transformCTL) )
-
-        # Find inverse
-        transformCTLInverse = "InvLMT.%s.ctl" % lmtName
-        if not os.path.exists(os.path.join(lmtTokens[-2], transformCTLInverse)):
-            transformCTLInverse = None
-        #print( transformCTLInverse )
-
-        # Add to list of LMTs
-        lmts[lmtName] = {}
-        lmts[lmtName]['transformCTL'] = os.path.join(lmtDir, transformCTL)
-        if transformCTLInverse != None:
-            lmts[odtName]['transformCTLInverse'] = os.path.join(lmtDir, transformCTLInverse)
-
-        lmts[lmtName]['transformID'] = transformID
-        lmts[lmtName]['transformUserNamePrefix'] = transformUserNamePrefix
-        lmts[lmtName]['transformUserName'] = transformUserName
-
-        print( "LMT : %s" % lmtName )
-        print( "\tTransform ID               : %s" % transformID )
-        print( "\tTransform User Name Prefix : %s" % transformUserNamePrefix )
-        print( "\tTransform User Name        : %s" % transformUserName )
-        print( "\t Forward ctl : %s" % lmts[lmtName]['transformCTL'])
-        if 'transformCTLInverse' in lmts[lmtName]:
-            print( "\t Inverse ctl : %s" % lmts[lmtName]['transformCTLInverse'])
-        else:
-            print( "\t Inverse ctl : %s" % "None" )
-
-    print( "\n" )
-
-    return lmts
-
-#
-# Create the ACES config
-#
-def createACESConfig(acesCTLReleaseDir, 
-    configDir, 
-    lutResolution1d=4096, 
-    lutResolution3d=64, 
-    bakeSecondaryLUTs=True,
-    cleanup=True):
-
-    # Get ODT names and CTL paths
-    odtInfo = getODTInfo(acesCTLReleaseDir)
-
-    # Get ODT names and CTL paths
-    lmtInfo = getLMTInfo(acesCTLReleaseDir)
-
-    # Create config dir
-    createConfigDir(configDir, bakeSecondaryLUTs)
-
-    # Generate config data and LUTs for different transforms
-    lutDir = "%s/luts" % configDir
-    shaperName = 'Output Shaper'
-    configData = generateLUTs(odtInfo, lmtInfo, shaperName, acesCTLReleaseDir, lutDir, lutResolution1d, lutResolution3d, cleanup)
-    
-    # Create the config using the generated LUTs
-    print( "Creating generic config")
-    config = createConfig(configData)
-    print( "\n\n\n" )
-
-    # Write the config to disk
-    writeConfig(config, "%s/config.ocio" % configDir )
-
-    # Create a config that will work well with Nuke using the previously generated LUTs
-    print( "Creating Nuke-specific config")
-    nuke_config = createConfig(configData, nuke=True)
-    print( "\n\n\n" )
-
-    # Write the config to disk
-    writeConfig(nuke_config, "%s/nuke_config.ocio" % configDir )
-
-    # Bake secondary LUTs using the config
-    if bakeSecondaryLUTs:
-        generateBakedLUTs(odtInfo, shaperName, "%s/baked" % configDir, "%s/config.ocio" % configDir, lutResolution1d, lutResolution3d, lutResolution1d)
-
-#
-# Main
-#
-def main():
-    import optparse
-
-    p = optparse.OptionParser(description='An OCIO config generation script',
-                                prog='createACESConfig',
-                                version='createACESConfig 0.1',
-                                usage='%prog [options]')
-    p.add_option('--acesCTLDir', '-a', default=None)
-    p.add_option('--configDir', '-c', default=None)
-    p.add_option('--lutResolution1d', default=4096)
-    p.add_option('--lutResolution3d', default=64)
-    p.add_option('--dontBakeSecondaryLUTs', action="store_true")
-    p.add_option('--keepTempImages', action="store_true")
-
-    options, arguments = p.parse_args()
-
-    #
-    # Get options
-    # 
-    acesCTLDir = options.acesCTLDir
-    configDir  = options.configDir
-    lutResolution1d  = int(options.lutResolution1d)
-    lutResolution3d  = int(options.lutResolution3d)
-    bakeSecondaryLUTs  = not(options.dontBakeSecondaryLUTs)
-    cleanupTempImages  = not(options.keepTempImages)
-
-    try:
-        argsStart = sys.argv.index('--') + 1
-        args = sys.argv[argsStart:]
-    except:
-        argsStart = len(sys.argv)+1
-        args = []
-
-    print( "command line : \n%s\n" % " ".join(sys.argv) )
-
-    if configDir == None:
-        print( "process: No ACES CTL directory specified" )
-        return
-    #
-    # Generate the configuration
-    #
-    createACESConfig(acesCTLDir, configDir, lutResolution1d, lutResolution3d, bakeSecondaryLUTs, cleanupTempImages)
-# main
-
-if __name__ == '__main__':
-    main()
diff --git a/aces_1.0.0/python/generateLUT.py b/aces_1.0.0/python/generateLUT.py
deleted file mode 100644 (file)
index 874157b..0000000
+++ /dev/null
@@ -1,391 +0,0 @@
-'''
-build instructions for osx for needed packages.
-
-#opencolorio
-brew install -vd opencolorio --with-python
-
-#openimageio
-brew tap homebrew/science
-
-# optional installs
-brew install -vd libRaw
-brew install -vd OpenCV
-
-brew install -vd openimageio --with-python
-
-#ctl
-brew install -vd CTL
-
-#opencolorio - again.
-# this time, 'ociolutimage' will build because openimageio is installed
-brew uninstall -vd opencolorio
-brew install -vd opencolorio --with-python
-'''
-
-import sys
-import os
-import array
-
-import OpenImageIO as oiio
-
-import process
-
-#
-# Functions used to generate LUTs using CTL transforms
-#
-def generate1dLUTImage(ramp1dPath, resolution=1024, minValue=0.0, maxValue=1.0):
-    #print( "Generate 1d LUT image - %s" % ramp1dPath)
-
-    # open image
-    format = os.path.splitext(ramp1dPath)[1]
-    ramp = oiio.ImageOutput.create(ramp1dPath)
-
-    # set image specs
-    spec = oiio.ImageSpec()
-    spec.set_format( oiio.FLOAT )
-    #spec.format.basetype = oiio.FLOAT
-    spec.width = resolution
-    spec.height = 1
-    spec.nchannels = 3
-
-    ramp.open (ramp1dPath, spec, oiio.Create)
-
-    data = array.array("f", "\0" * spec.width * spec.height * spec.nchannels * 4)
-    for i in range(resolution):
-        value = float(i)/(resolution-1) * (maxValue - minValue) + minValue
-        data[i*spec.nchannels +0] = value
-        data[i*spec.nchannels +1] = value
-        data[i*spec.nchannels +2] = value
-
-    ramp.write_image(spec.format, data)
-    ramp.close()
-
-# Credit to Alex Fry for the original single channel version of the spi1d writer
-def writeSPI1D(filename, fromMin, fromMax, data, entries, channels):
-    f = file(filename,'w')
-    f.write("Version 1\n")
-    f.write("From %f %f\n" % (fromMin, fromMax))
-    f.write("Length %d\n" % entries)
-    f.write("Components %d\n" % (min(3, channels)) )
-    f.write("{\n")
-    for i in range(0, entries):
-        entry = ""
-        for j in range(0, min(3, channels)):
-            entry = "%s %s" % (entry, data[i*channels + j])
-        f.write("        %s\n" % entry)
-    f.write("}\n")
-    f.close()
-
-def generate1dLUTFromImage(ramp1dPath, outputPath=None, minValue=0.0, maxValue=1.0):
-    if outputPath == None:
-        outputPath = ramp1dPath + ".spi1d"
-
-    # open image
-    ramp = oiio.ImageInput.open( ramp1dPath )
-
-    # get image specs
-    spec = ramp.spec()
-    type = spec.format.basetype
-    width = spec.width
-    height = spec.height
-    channels = spec.nchannels
-
-    # get data
-    # Force data to be read as float. The Python API doesn't handle half-floats well yet.
-    type = oiio.FLOAT
-    data = ramp.read_image(type)
-
-    writeSPI1D(outputPath, minValue, maxValue, data, width, channels)
-
-def generate3dLUTImage(ramp3dPath, resolution=32):
-    args = ["--generate", "--cubesize", str(resolution), "--maxwidth", str(resolution*resolution), "--output", ramp3dPath]
-    lutExtract = process.Process(description="generate a 3d LUT image", cmd="ociolutimage", args=args)
-    lutExtract.execute()    
-
-def generate3dLUTFromImage(ramp3dPath, outputPath=None, resolution=32):
-    if outputPath == None:
-        outputPath = ramp3dPath + ".spi3d"
-
-    args = ["--extract", "--cubesize", str(resolution), "--maxwidth", str(resolution*resolution), "--input", ramp3dPath, "--output", outputPath]
-    lutExtract = process.Process(description="extract a 3d LUT", cmd="ociolutimage", args=args)
-    lutExtract.execute()    
-
-def applyCTLToImage(inputImage, 
-    outputImage, 
-    ctlPaths=[], 
-    inputScale=1.0, 
-    outputScale=1.0, 
-    globalParams={},
-    acesCTLReleaseDir=None):
-    if len(ctlPaths) > 0:
-        ctlenv = os.environ
-        if acesCTLReleaseDir != None:
-            if os.path.split(acesCTLReleaseDir)[1] != "utilities":
-                ctlModulePath = "%s/utilities" % acesCTLReleaseDir
-            else:
-                ctlModulePath = acesCTLReleaseDir
-            ctlenv['CTL_MODULE_PATH'] = ctlModulePath
-
-        args = []
-        for ctl in ctlPaths:
-            args += ['-ctl', ctl]
-        args += ["-force"]
-        #args += ["-verbose"]
-        args += ["-input_scale", str(inputScale)]
-        args += ["-output_scale", str(outputScale)]
-        args += ["-global_param1", "aIn", "1.0"]
-        for key, value in globalParams.iteritems():
-            args += ["-global_param1", key, str(value)]
-        args += [inputImage]
-        args += [outputImage]
-
-        #print( "args : %s" % args )
-
-        ctlp = process.Process(description="a ctlrender process", cmd="ctlrender", args=args, env=ctlenv )
-
-        ctlp.execute()
-
-def convertBitDepth(inputImage, outputImage, depth):
-    args = [inputImage, "-d", depth, "-o", outputImage]
-    convert = process.Process(description="convert image bit depth", cmd="oiiotool", args=args)
-    convert.execute()    
-
-def generate1dLUTFromCTL(lutPath, 
-    ctlPaths, 
-    lutResolution=1024, 
-    identityLutBitDepth='half', 
-    inputScale=1.0, 
-    outputScale=1.0,
-    globalParams={},
-    cleanup=True,
-    acesCTLReleaseDir=None,
-    minValue=0.0,
-    maxValue=1.0):
-    #print( lutPath )
-    #print( ctlPaths )
-
-    lutPathBase = os.path.splitext(lutPath)[0]
-
-    identityLUTImageFloat = lutPathBase + ".float.tiff"
-    generate1dLUTImage(identityLUTImageFloat, lutResolution, minValue, maxValue)
-
-    if identityLutBitDepth != 'half':
-        identityLUTImage = lutPathBase + ".uint16.tiff"
-        convertBitDepth(identityLUTImageFloat, identityLUTImage, identityLutBitDepth)
-    else:
-        identityLUTImage = identityLUTImageFloat
-
-    transformedLUTImage = lutPathBase + ".transformed.exr"
-    applyCTLToImage(identityLUTImage, transformedLUTImage, ctlPaths, inputScale, outputScale, globalParams, acesCTLReleaseDir)
-
-    generate1dLUTFromImage(transformedLUTImage, lutPath, minValue, maxValue)
-
-    if cleanup:
-        os.remove(identityLUTImage)
-        if identityLUTImage != identityLUTImageFloat:
-            os.remove(identityLUTImageFloat)
-        os.remove(transformedLUTImage)
-
-def correctLUTImage(transformedLUTImage, correctedLUTImage, lutResolution):
-    # open image
-    transformed = oiio.ImageInput.open( transformedLUTImage )
-
-    # get image specs
-    transformedSpec = transformed.spec()
-    type = transformedSpec.format.basetype
-    width = transformedSpec.width
-    height = transformedSpec.height
-    channels = transformedSpec.nchannels
-
-    # rotate or not
-    if width != lutResolution * lutResolution or height != lutResolution:
-        print( "Correcting image as resolution is off. Found %d x %d. Expected %d x %d" % (width, height, lutResolution * lutResolution, lutResolution) )
-        print( "Generating %s" % correctedLUTImage)
-
-        #
-        # We're going to generate a new correct image
-        #
-
-        # Get the source data
-        # Force data to be read as float. The Python API doesn't handle half-floats well yet.
-        type = oiio.FLOAT
-        sourceData = transformed.read_image(type)
-
-        format = os.path.splitext(correctedLUTImage)[1]
-        correct = oiio.ImageOutput.create(correctedLUTImage)
-
-        # set image specs
-        correctSpec = oiio.ImageSpec()
-        correctSpec.set_format( oiio.FLOAT )
-        correctSpec.width = height
-        correctSpec.height = width
-        correctSpec.nchannels = channels
-
-        correct.open (correctedLUTImage, correctSpec, oiio.Create)
-
-        destData = array.array("f", "\0" * correctSpec.width * correctSpec.height * correctSpec.nchannels * 4)
-        for j in range(0, correctSpec.height):
-            for i in range(0, correctSpec.width):
-                for c in range(0, correctSpec.nchannels):
-                    #print( i, j, c )
-                    destData[correctSpec.nchannels*correctSpec.width*j + correctSpec.nchannels*i + c] = sourceData[correctSpec.nchannels*correctSpec.width*j + correctSpec.nchannels*i + c]
-
-        correct.write_image(correctSpec.format, destData)
-        correct.close()
-    else:
-        #shutil.copy(transformedLUTImage, correctedLUTImage)
-        correctedLUTImage = transformedLUTImage
-
-    transformed.close()
-
-    return correctedLUTImage
-
-def generate3dLUTFromCTL(lutPath, 
-    ctlPaths, 
-    lutResolution=64, 
-    identityLutBitDepth='half', 
-    inputScale=1.0,
-    outputScale=1.0, 
-    globalParams={},
-    cleanup=True,
-    acesCTLReleaseDir=None):
-    #print( lutPath )
-    #print( ctlPaths )
-
-    lutPathBase = os.path.splitext(lutPath)[0]
-
-    identityLUTImageFloat = lutPathBase + ".float.tiff"
-    generate3dLUTImage(identityLUTImageFloat, lutResolution)
-
-
-    if identityLutBitDepth != 'half':
-        identityLUTImage = lutPathBase + "." + identityLutBitDepth + ".tiff"
-        convertBitDepth(identityLUTImageFloat, identityLUTImage, identityLutBitDepth)
-    else:
-        identityLUTImage = identityLUTImageFloat
-
-    transformedLUTImage = lutPathBase + ".transformed.exr"
-    applyCTLToImage(identityLUTImage, transformedLUTImage, ctlPaths, inputScale, outputScale, globalParams, acesCTLReleaseDir)
-
-    correctedLUTImage = lutPathBase + ".correct.exr"
-    correctedLUTImage = correctLUTImage(transformedLUTImage, correctedLUTImage, lutResolution)    
-
-    generate3dLUTFromImage(correctedLUTImage, lutPath, lutResolution)
-
-    if cleanup:
-        os.remove(identityLUTImage)
-        if identityLUTImage != identityLUTImageFloat:
-            os.remove(identityLUTImageFloat)
-        os.remove(transformedLUTImage)
-        if correctedLUTImage != transformedLUTImage:
-            os.remove(correctedLUTImage)
-        #os.remove(correctedLUTImage)
-
-def main():
-    import optparse
-
-    p = optparse.OptionParser(description='A utility to generate LUTs from CTL',
-                                prog='generateLUT',
-                                version='0.01',
-                                usage='%prog [options]')
-
-    p.add_option('--lut', '-l', type="string", default="")
-    p.add_option('--ctl', '-c', type="string", action="append")
-    p.add_option('--lutResolution1d', '', type="int", default=1024)
-    p.add_option('--lutResolution3d', '', type="int", default=33)
-    p.add_option('--ctlReleasePath', '-r', type="string", default="")
-    p.add_option('--bitDepth', '-b', type="string", default="float")
-    p.add_option('--keepTempImages', '', action="store_true")
-    p.add_option('--minValue', '', type="float", default=0.0)
-    p.add_option('--maxValue', '', type="float", default=1.0)
-    p.add_option('--inputScale', '', type="float", default=1.0)
-    p.add_option('--outputScale', '', type="float", default=1.0)
-    p.add_option('--ctlRenderParam', '-p', type="string", nargs=2, action="append")
-
-    p.add_option('--generate1d', '', action="store_true")
-    p.add_option('--generate3d', '', action="store_true")
-
-    options, arguments = p.parse_args()
-
-    #
-    # Get options
-    # 
-    lut = options.lut
-    ctls = options.ctl
-    lutResolution1d = options.lutResolution1d
-    lutResolution3d = options.lutResolution3d
-    minValue = options.minValue
-    maxValue = options.maxValue
-    inputScale = options.inputScale
-    outputScale = options.outputScale
-    ctlReleasePath = options.ctlReleasePath
-    generate1d = options.generate1d == True
-    generate3d = options.generate3d == True
-    bitDepth = options.bitDepth
-    cleanup = not options.keepTempImages
-
-    params = {}
-    if options.ctlRenderParam != None:
-        for param in options.ctlRenderParam:
-            params[param[0]] = float(param[1])
-
-    try:
-        argsStart = sys.argv.index('--') + 1
-        args = sys.argv[argsStart:]
-    except:
-        argsStart = len(sys.argv)+1
-        args = []
-
-    #print( "command line : \n%s\n" % " ".join(sys.argv) )
-
-    #
-    # Generate LUTs
-    #
-    if generate1d:
-        print( "1D LUT generation options")
-    else:
-        print( "3D LUT generation options")
-
-    print( "lut                 : %s" % lut )
-    print( "ctls                : %s" % ctls )
-    print( "lut res 1d          : %s" % lutResolution1d )
-    print( "lut res 3d          : %s" % lutResolution3d )
-    print( "min value           : %s" % minValue )
-    print( "max value           : %s" % maxValue )
-    print( "input scale         : %s" % inputScale )
-    print( "output scale        : %s" % outputScale )
-    print( "ctl render params   : %s" % params )
-    print( "ctl release path    : %s" % ctlReleasePath )
-    print( "bit depth of input  : %s" % bitDepth )
-    print( "cleanup temp images : %s" % cleanup)
-
-    if generate1d:
-        generate1dLUTFromCTL( lut, 
-            ctls, 
-            lutResolution1d, 
-            bitDepth, 
-            inputScale,
-            outputScale, 
-            params,
-            cleanup, 
-            ctlReleasePath,
-            minValue,
-            maxValue)
-
-    elif generate3d:
-        generate3dLUTFromCTL( lut, 
-            ctls, 
-            lutResolution3d, 
-            bitDepth, 
-            inputScale,
-            outputScale, 
-            params,
-            cleanup, 
-            ctlReleasePath)
-    else:
-        print( "\n\nNo LUT generated. You must choose either 1D or 3D LUT generation\n\n")
-# main
-
-if __name__ == '__main__':
-    main()
-
diff --git a/aces_1.0.0/python/process.py b/aces_1.0.0/python/process.py
deleted file mode 100755 (executable)
index 17347ee..0000000
+++ /dev/null
@@ -1,474 +0,0 @@
-#!/usr/bin/python2.6\r
-\r
-'''A process wrapper class that maintains the text output and execution status of a process\r
-or a list of other process wrappers which carry such data.'''\r
-\r
-import os\r
-import sys\r
-import traceback\r
-\r
-def readText(textFile):\r
-    if( textFile != "" ):\r
-        fp = open(textFile, 'rb')\r
-        # Create a text/plain message\r
-        text = (fp.read())\r
-        fp.close()\r
-    return text\r
-# readText\r
-\r
-def writeText(text, textFile):\r
-    if( textFile != "" ):\r
-        fp = open(textFile, 'wb')\r
-        # Create a text/plain message\r
-        fp.write(text)\r
-        fp.close()\r
-    return text\r
-# readText\r
-\r
-class Process:\r
-    "A process with logged output"\r
-\r
-    def __init__(self, description=None, cmd=None, args=[], cwd=None, env=None, batchWrapper=False):\r
-        "Initialize the standard class variables"\r
-        self.cmd = cmd\r
-        if not description:\r
-            self.description = cmd\r
-        else:\r
-            self.description = description\r
-        self.status = None\r
-        self.args = args\r
-        self.start = None\r
-        self.end = None\r
-        self.log = []\r
-        self.echo = True\r
-        self.cwd = cwd\r
-        self.env = env\r
-        self.batchWrapper = batchWrapper\r
-        self.processKeys = []\r
-    # __init__\r
-\r
-    def getElapsedSeconds(self):\r
-        import math\r
-        if self.end and self.start:\r
-            delta = (self.end - self.start)\r
-            formatted = "%s.%s" % (delta.days * 86400 + delta.seconds, int(math.floor(delta.microseconds/1e3)))\r
-        else:\r
-            formatted = None\r
-        return formatted\r
-    # getElapsedtime\r
-\r
-    def writeKey(self, writeDict, key=None, value=None, startStop=None):\r
-        "Write a key, value pair in a supported format"\r
-        if key != None and (value != None or startStop != None):\r
-            indent = '\t'*writeDict['indentationLevel']\r
-            if writeDict['format'] == 'xml':\r
-                if startStop == 'start':\r
-                    writeDict['logHandle'].write( "%s<%s>\n" % (indent, key) )\r
-                elif startStop == 'stop':\r
-                    writeDict['logHandle'].write( "%s</%s>\n" % (indent, key) )\r
-                else:\r
-                    writeDict['logHandle'].write( "%s<%s>%s</%s>\n" % (indent, key, value, key) )\r
-            else: # writeDict['format'] == 'txt':\r
-                writeDict['logHandle'].write( "%s%40s : %s\n" % (indent, key, value) )\r
-\r
-    def writeLogHeader(self, writeDict):\r
-        import platform\r
-\r
-        # Retrieve operating environment information\r
-        user = None\r
-        try:\r
-            user = os.getlogin()\r
-        except:\r
-            try:\r
-                user = os.getenv("USERNAME")\r
-                if user == None:\r
-                    user = os.getenv("USER")\r
-            except:\r
-                user = "unknown_user"\r
-        try:\r
-            (sysname, nodename, release, version, machine, processor) = platform.uname()\r
-        except:\r
-            (sysname, nodename, release, version, machine, processor) = ("unknown_sysname", "unknown_nodename", "unknown_release", "unknown_version", "unknown_machine", "unknown_processor")\r
-        try:\r
-            hostname = platform.node()\r
-        except:\r
-            hostname = "unknown_hostname"\r
-\r
-        self.writeKey(writeDict, 'process', None, 'start' )\r
-        writeDict['indentationLevel'] += 1\r
-\r
-        self.writeKey(writeDict, 'description', self.description )\r
-        self.writeKey(writeDict, 'cmd', self.cmd )\r
-        if self.args: self.writeKey(writeDict, 'args', ' '.join(self.args) )\r
-        self.writeKey(writeDict, 'start', self.start )\r
-        self.writeKey(writeDict, 'end', self.end )\r
-        self.writeKey(writeDict, 'elapsed', self.getElapsedSeconds() )\r
-\r
-        self.writeKey(writeDict, 'user', user )\r
-        self.writeKey(writeDict, 'sysname', sysname )\r
-        self.writeKey(writeDict, 'nodename', nodename )\r
-        self.writeKey(writeDict, 'release', release )\r
-        self.writeKey(writeDict, 'version', version )\r
-        self.writeKey(writeDict, 'machine', machine )\r
-        self.writeKey(writeDict, 'processor', processor )\r
-\r
-        if len(self.processKeys) > 0:\r
-            self.writeKey(writeDict, 'processKeys', None, 'start' )\r
-            for pair in self.processKeys:\r
-                (key, value) = pair\r
-                writeDict['indentationLevel'] += 1\r
-                self.writeKey(writeDict, key, value )\r
-                writeDict['indentationLevel'] -= 1\r
-            self.writeKey(writeDict, 'processKeys', None, 'stop' )\r
-\r
-        self.writeKey(writeDict, 'status', self.status )\r
-    # writeLogHeader\r
-\r
-    def writeLogFooter(self, writeDict):\r
-        writeDict['indentationLevel'] -= 1\r
-        self.writeKey(writeDict, 'process', None, 'stop' )\r
-    # writeLogFooter\r
-\r
-    def writeLog(self, logHandle=sys.stdout, indentationLevel=0,format='xml'):\r
-        "Write logging information to the specified handle"\r
-        \r
-        writeDict = {}\r
-        writeDict['logHandle'] = logHandle\r
-        writeDict['indentationLevel'] = indentationLevel\r
-        writeDict['format'] = format\r
-        \r
-        if logHandle:\r
-            self.writeLogHeader(writeDict)\r
-            \r
-            if self.log:\r
-                self.writeKey(writeDict, 'output', None, 'start' )\r
-                if format == 'xml':\r
-                    logHandle.write( "<![CDATA[\n" )\r
-                for line in self.log:\r
-                    logHandle.write( '%s%s\n' % ("", line) )\r
-                if format == 'xml':\r
-                    logHandle.write( "]]>\n" )\r
-                self.writeKey(writeDict, 'output', None, 'stop' )\r
-\r
-            self.writeLogFooter(writeDict)\r
-    # writeLog\r
-\r
-    def writeLogToDisk(self, logFilename=None, format='xml', header=None):\r
-        if logFilename: \r
-            try:\r
-                # This also doesn't seem like the best structure...\r
-                # 3.1\r
-                try:\r
-                    logHandle = open( logFilename, mode='wt', encoding="utf-8")\r
-                # 2.6\r
-                except:\r
-                    logHandle = open( logFilename, mode='wt')\r
-            except:\r
-                print( "Couldn't open log : %s" % logFilename )\r
-                logHandle = None\r
-\r
-        if logHandle:\r
-            if header:\r
-                if format == 'xml':\r
-                    logHandle.write( "<![CDATA[\n" )\r
-                logHandle.write( header )\r
-                if format == 'xml':\r
-                    logHandle.write( "]]>\n" )\r
-            self.writeLog(logHandle)\r
-            logHandle.close()\r
-    # writeLogToDisk\r
-\r
-    def logLine(self, line):\r
-        "Add a line of text to the log"\r
-        self.log.append( line.rstrip() )\r
-        if self.echo:\r
-            print( "%s" % line.rstrip() )\r
-    # logLine\r
-\r
-    def execute(self):\r
-        "Execute this process"\r
-        import re\r
-        import datetime\r
-        import traceback\r
-        \r
-        try:\r
-            import subprocess as sp\r
-        except:\r
-            sp = None\r
-\r
-        self.start = datetime.datetime.now()\r
-\r
-        cmdargs = [self.cmd]\r
-        cmdargs.extend(self.args)\r
-        \r
-        if self.echo:\r
-            if sp:\r
-                print( "\n%s : %s\n" % (self.__class__, sp.list2cmdline(cmdargs)) )\r
-            else:\r
-                print( "\n%s : %s\n" % (self.__class__, " ".join(cmdargs)) )\r
-\r
-        # intialize a few variables that may or may not be set later\r
-        process = None\r
-        tmpWrapper = None\r
-        stdout = None\r
-        stdin = None\r
-        parentenv = os.environ\r
-        parentcwd = os.getcwd()\r
-\r
-        try:\r
-            # Using subprocess\r
-            if sp:\r
-                if self.batchWrapper:\r
-                    cmd = " ".join(cmdargs)\r
-                    tmpWrapper = os.path.join(self.cwd, "process.bat")\r
-                    writeText(cmd, tmpWrapper)\r
-                    print( "%s : Running process through wrapper %s\n" % (self.__class__, tmpWrapper) )\r
-                    process = sp.Popen([tmpWrapper], stdout=sp.PIPE, stderr=sp.STDOUT, \r
-                        cwd=self.cwd, env=self.env)\r
-                else:\r
-                    process = sp.Popen(cmdargs, stdout=sp.PIPE, stderr=sp.STDOUT, \r
-                        cwd=self.cwd, env=self.env)\r
-\r
-            # using os.popen4\r
-            else:\r
-                if self.env:\r
-                    os.environ = self.env\r
-                if self.cwd:\r
-                    os.chdir( self.cwd )\r
-                \r
-                stdin, stdout = os.popen4( cmdargs, 'r')\r
-        except:\r
-            print( "Couldn't execute command : %s" % cmdargs[0] )\r
-            traceback.print_exc()\r
-\r
-        # Using subprocess\r
-        if sp:\r
-            if process != None:\r
-                #pid = process.pid\r
-                #log.logLine( "process id %s\n" % pid )\r
-\r
-                try:\r
-                    # This is more proper python, and resolves some issues with a process ending before all\r
-                    #  of its output has been processed, but it also seems to stall when the read buffer\r
-                    #  is near or over it's limit. this happens relatively frequently with processes\r
-                    #  that generate lots of print statements.\r
-                    #\r
-                    for line in process.stdout:\r
-                        self.logLine(line)\r
-                    #\r
-                    # So we go with the, um, uglier  option below\r
-\r
-                    # This is now used to ensure that the process has finished\r
-                    line = ""\r
-                    while line != None and process.poll() == None:\r
-                        try:\r
-                            line = process.stdout.readline()\r
-                        except:\r
-                            break\r
-                        # 3.1\r
-                        try:\r
-                            self.logLine( str(line, encoding="utf-8") )\r
-                        # 2.6\r
-                        except:\r
-                            self.logLine( line )\r
-                except:\r
-                    self.logLine( "Logging error : %s" % sys.exc_info()[0] )\r
-\r
-                self.status = process.returncode\r
-                \r
-                if self.batchWrapper and tmpWrapper:\r
-                    try:\r
-                        os.remove(tmpWrapper)\r
-                    except:\r
-                        print( "Couldn't remove temp wrapper : %s" % tmpWrapper )\r
-                        traceback.print_exc()\r
-\r
-        # Using os.popen4\r
-        else:\r
-            exitCode = -1\r
-            try:\r
-                #print( "reading stdout lines" )\r
-                stdoutLines = stdout.readlines()\r
-                exitCode = stdout.close()\r
-\r
-                stdout.close()\r
-                stdin.close()\r
-\r
-                if self.env:\r
-                    os.environ = parentenv\r
-                if self.cwd:\r
-                    os.chdir( parentcwd )\r
-                \r
-                if len( stdoutLines ) > 0:\r
-                    for line in stdoutLines:\r
-                        self.logLine(line)\r
-\r
-                if not exitCode:\r
-                    exitCode = 0\r
-            except:\r
-                self.logLine( "Logging error : %s" % sys.exc_info()[0] )\r
-\r
-            self.status = exitCode\r
-            \r
-        self.end = datetime.datetime.now()\r
-    #execute\r
-# Process\r
-\r
-class ProcessList(Process):\r
-    "A list of processes with logged output"\r
-\r
-    def __init__(self, description, blocking=True, cwd=None, env=None):\r
-        Process.__init__(self, description, None, None, cwd, env)\r
-        "Initialize the standard class variables"\r
-        self.processes = []\r
-        self.blocking = blocking\r
-    # __init__\r
-\r
-    def generateReport(self, writeDict):\r
-        "Generate a log based on the success of the child processes"\r
-        if self.processes:\r
-            _status = True\r
-            indent = '\t'*(writeDict['indentationLevel']+1)\r
-            \r
-            self.log = []\r
-            \r
-            for child in self.processes:\r
-                if isinstance(child, ProcessList):\r
-                    child.generateReport(writeDict)\r
-                \r
-                childResult = ""\r
-                key = child.description\r
-                value = child.status\r
-                if writeDict['format'] == 'xml':\r
-                    childResult = ( "%s<result description=\"%s\">%s</result>" % (indent, key, value) )\r
-                else: # writeDict['format'] == 'txt':\r
-                    childResult = ( "%s%40s : %s" % (indent, key, value) )\r
-                self.log.append( childResult )\r
-                \r
-                if child.status != 0:\r
-                    _status = False\r
-            if not _status:\r
-                self.status = -1\r
-            else:\r
-                self.status = 0\r
-        else:\r
-            self.log = ["No child processes available to generate a report"]\r
-            self.status = -1\r
-\r
-    def writeLogHeader(self, writeDict):\r
-        self.writeKey(writeDict, 'processList', None, 'start' )\r
-        writeDict['indentationLevel'] += 1\r
-\r
-        self.writeKey(writeDict, 'description', self.description )\r
-        self.writeKey(writeDict, 'start', self.start )\r
-        self.writeKey(writeDict, 'end', self.end )\r
-        self.writeKey(writeDict, 'elapsed', self.getElapsedSeconds() )\r
-\r
-        self.generateReport(writeDict)\r
-\r
-        self.writeKey(writeDict, 'status', self.status )\r
-    # writeLogHeader\r
-\r
-    def writeLogFooter(self, writeDict):\r
-        writeDict['indentationLevel'] -= 1\r
-        self.writeKey(writeDict, 'processList', None, 'stop' )\r
-    # writeLogFooter\r
-\r
-    def writeLog(self, logHandle=sys.stdout, indentationLevel=0,format='xml'):\r
-        "Write logging information to the specified handle"\r
-        \r
-        writeDict = {}\r
-        writeDict['logHandle'] = logHandle\r
-        writeDict['indentationLevel'] = indentationLevel\r
-        writeDict['format'] = format\r
-        \r
-        if logHandle:\r
-            self.writeLogHeader(writeDict)\r
-            \r
-            if self.log:\r
-                self.writeKey(writeDict, 'output', None, 'start' )\r
-                for line in self.log:\r
-                    logHandle.write( '%s%s\n' % ("", line) )\r
-                self.writeKey(writeDict, 'output', None, 'stop' )\r
-\r
-            if self.processes:\r
-                self.writeKey(writeDict, 'processes', None, 'start' )\r
-                for child in self.processes:\r
-                    child.writeLog( logHandle, indentationLevel + 1, format )\r
-                self.writeKey(writeDict, 'processes', None, 'stop' )\r
-\r
-            self.writeLogFooter(writeDict)\r
-    # writeLog\r
-\r
-    def execute(self):\r
-        "Execute this list of processes"\r
-        import datetime\r
-\r
-        self.start = datetime.datetime.now()\r
-\r
-        self.status = 0\r
-        if self.processes:\r
-            for child in self.processes:\r
-                if child:\r
-                    try:\r
-                        child.execute()\r
-                    except:\r
-                        print( "%s : caught exception in child class %s" % (self.__class__, child.__class__) )\r
-                        traceback.print_exc()\r
-                        child.status = -1\r
-\r
-                    if self.blocking and child.status != 0:\r
-                        print( "%s : child class %s finished with an error" % (self.__class__, child.__class__) )\r
-                        self.status = -1\r
-                        break\r
-\r
-        self.end = datetime.datetime.now()\r
-    # execute\r
-# ProcessList\r
-\r
-def main():\r
-    import optparse\r
-\r
-    p = optparse.OptionParser(description='A process logging script',\r
-                                prog='process',\r
-                                version='process 0.1',\r
-                                usage='%prog [options] [options for the logged process]')\r
-    p.add_option('--cmd', '-c', default=None)\r
-    p.add_option('--log', '-l', default=None)\r
-\r
-    options, arguments = p.parse_args()\r
-\r
-    #\r
-    # Get options\r
-    # \r
-    cmd = options.cmd\r
-    logFilename = options.log\r
-\r
-    try:\r
-        argsStart = sys.argv.index('--') + 1\r
-        args = sys.argv[argsStart:]\r
-    except:\r
-        argsStart = len(sys.argv)+1\r
-        args = []\r
-\r
-    if cmd == None:\r
-        print( "process: No command specified" )\r
\r
-    #\r
-    # Test regular logging\r
-    #\r
-    process = Process(description="a process",cmd=cmd, args=args)\r
-\r
-    #\r
-    # Test report generation and writing a log\r
-    #\r
-    processList = ProcessList("a process list")\r
-    processList.processes.append( process )\r
-    processList.echo = True\r
-    processList.execute()\r
-    \r
-    processList.writeLogToDisk(logFilename)\r
-# main\r
-\r
-if __name__ == '__main__':\r
-    main()\r
diff --git a/aces_1.0.0/python/util.py b/aces_1.0.0/python/util.py
deleted file mode 100644 (file)
index aa891d3..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-import PyOpenColorIO as OCIO
-
-#
-# Utility classes and functions
-#
-class ColorSpace:
-    "A container for data needed to define an OCIO 'Color Space' "
-
-    def __init__(self, 
-        name, 
-        description=None, 
-        bitDepth=OCIO.Constants.BIT_DEPTH_F32,
-        equalityGroup=None,
-        family=None,
-        isData=False,
-        toReferenceTransforms=[],
-        fromReferenceTransforms=[],
-        allocationType=OCIO.Constants.ALLOCATION_UNIFORM,
-        allocationVars=[0.0, 1.0]):
-        "Initialize the standard class variables"
-        self.name = name
-        self.bitDepth=bitDepth
-        self.description = description
-        self.equalityGroup=equalityGroup
-        self.family=family 
-        self.isData=isData
-        self.toReferenceTransforms=toReferenceTransforms
-        self.fromReferenceTransforms=fromReferenceTransforms
-        self.allocationType=allocationType
-        self.allocationVars=allocationVars
-
-# Create a 4x4 matrix (list) based on a 3x3 matrix (list) input
-def mat44FromMat33(mat33):
-    return [mat33[0], mat33[1], mat33[2], 0.0, 
-            mat33[3], mat33[4], mat33[5], 0.0, 
-            mat33[6], mat33[7], mat33[8], 0.0, 
-            0,0,0,1.0]
\ No newline at end of file