hinet_translator.py :  » Math » Modular-toolkit-for-Data-Processing » MDP-2.6 » mdp » hinet » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Math » Modular toolkit for Data Processing 
Modular toolkit for Data Processing » MDP 2.6 » mdp » hinet » hinet_translator.py
"""
Module to translate HiNet structures into other representations, like HTML.

This module contains the HTML node extension.
"""

import tempfile
import os
import webbrowser
import cStringIO as StringIO

import mdp

import switchboard


class HiNetTranslator(object):
    """Generic translation class for HiNet flow.
    
    The dummy implementation in this base class turns the HiNet structure
    into nested lists of the basic nodes.
    """
    
    def __init__(self):
        """Initialize the internal variables."""
        super(HiNetTranslator, self).__init__()

    def _translate_flow(self, flow):
        """Translate the flow and return the translation."""
        flow_translation = []
        for node in flow:
            flow_translation.append(self._translate_node(node))
        return flow_translation
            
    def _translate_node(self, node):
        """Translate a node and return the translation.
        
        Depending on the type of the node this can be delegated to more
        specific methods.
        """
        if hasattr(node, "flow"):
            return self._translate_flownode(node)
        elif isinstance(node, mdp.hinet.CloneLayer):
            return self._translate_clonelayer(node)
        elif isinstance(node, mdp.hinet.SameInputLayer):
            return self._translate_sameinputlayer(node)
        elif isinstance(node, mdp.hinet.Layer):
            return self._translate_layer(node)
        else:
            return self._translate_standard_node(node)
        
    def _translate_flownode(self, flownode):
        """Translate a node containing a flow and return the translation.
        
        The internal nodes are translated recursively.
        
        Note that this method is used for translation whenever the node has
        a flow attribute. This flow attribute is then used for the iteration,
        so the node itself does not have to be an iterable.
        """
        flownode_translation = []
        for node in flownode.flow:
            flownode_translation.append(self._translate_node(node))
        return flownode_translation
    
    def _translate_layer(self, layer):
        """Translate a layer and return the translation.
        
        All the nodes in the layer are translated.
        """
        layer_translation = []
        for node in layer:
            layer_translation.append(self._translate_node(node))
        return layer_translation
    
    def _translate_clonelayer(self, layer):
        """Translate a CloneLayer and return the translation."""
        translated_node = self._translate_node(layer.node)
        return [translated_node] * len(layer)
    
    def _translate_sameinputlayer(self, layer):
        """Translate a SameInputLayer and return the translation."""
        return self._translate_layer(layer)

    def _translate_standard_node(self, node):
        """Translate a node and return the translation.
        
        This method is used when no specialized translation (like for FlowNodes
        or Layers) is required.
        """
        return node


## Specialized HTML Translator ##

# load CSS from style file
_css_filename = os.path.join(os.path.split(__file__)[0], "hinet.css")
_css_file = open(_css_filename, 'r')
HINET_STYLE = _css_file.read()
_css_file.close()


class  HTMLExtensionNode(mdp.ExtensionNode, mdp.Node):
    """Extension node for HTML representations of individual nodes."""
    
    extension_name = "html"
    
    def html_representation(self):
        """Return an HTML representation of the node."""
        html_repr = self._html_representation()
        if type(html_repr) is str:
            return html_repr
        else:
            return " <br>\n".join(html_repr)
            
    def _html_representation(self):
        """Return either the final HTML code or a list of HTML lines."""
        return ""
    
    
@mdp.extension_method("html", switchboard.Rectangular2dSwitchboard,
                      "_html_representation")
def _rect2d_switchoard_html(self):
    lines = ['rec. field size (in channels): %d x %d = %d' % 
                (self.x_field_channels, self.y_field_channels,
                 self.x_field_channels * self.y_field_channels),
             '# of rec. fields (out channels): %d x %d = %d' %
                (self.x_out_channels, self.y_out_channels,
                 self.output_channels),
             'rec. field distances (in channels): (%d x %d)' %
                (self.x_field_spacing, self.y_field_spacing),
             'channel width: %d' % self.in_channel_dim]
    if self.x_unused_channels or self.y_unused_channels:
        lines.append('unused channels: (%d, %d)' %
                     (self.x_unused_channels, self.y_unused_channels))
    return lines

@mdp.extension_method("html", switchboard.DoubleRect2dSwitchboard,
                      "_html_representation")
def _double_rect2d_switchoard_html(self):
    lines = ['rec. field size (in channels): %d x %d = %d' % 
                (self.x_field_channels, self.y_field_channels,
                 self.x_field_channels * self.y_field_channels),
             '# of long row rec. fields (out channels): %d, %d' %
                (self.x_long_out_channels, self.y_long_out_channels),
             'total number of receptive fields: %d' % 
                self.output_channels,
             'channel width: %d' % self.in_channel_dim]
    if self.x_unused_channels or self.y_unused_channels:
        lines.append('unused channels: (%d, %d)' %
                     (self.x_unused_channels, self.y_unused_channels))
    return lines

@mdp.extension_method("html", switchboard.DoubleRhomb2dSwitchboard,
                      "_html_representation")
def _double_rhomb2d_switchoard_html(self):
    lines = ['rec. field size: %d' % self.diag_field_channels,
             '# of rec. fields (out channels): %d x %d = %d' %
                (self.x_out_channels, self.y_out_channels,
                 self.output_channels),
             'channel width: %d' % self.in_channel_dim]
    return lines

@mdp.extension_method("html", mdp.nodes.SFA2Node, "_html_representation")
def _sfa_html(self):
    return 'expansion dim: ' + str(self._expnode.output_dim)

@mdp.extension_method("html", mdp.nodes.NormalNoiseNode,
                      "_html_representation")   
def _noise_html(self):
    return ['noise level: ' + str(self.noise_args[1]),
            'noise offset: ' + str(self.noise_args[0])]

@mdp.extension_method("html", mdp.nodes.CutoffNode, "_html_representation") 
def _cutoff_html(self):
    return ['lower bound: ' + str(self.lower_bound),
            'upper bound: ' + str(self.upper_bound)]

@mdp.extension_method("html", mdp.nodes.HistogramNode, "_html_representation")   
def _hist_html(self):
    return 'history data fraction: ' + str(self.hist_fraction)

@mdp.extension_method("html", mdp.nodes.AdaptiveCutoffNode,
                      "_html_representation")
def _adap_html(self):
    return ['lower cutoff fraction: ' + str(self.lower_cutoff_fraction), 
            'upper cutoff fraction: ' + str(self.upper_cutoff_fraction), 
            'history data fraction: ' + str(self.hist_fraction)]
    

class NewlineWriteFile(object):
    """Decorator for file-like object.
    
    Adds a newline character to each line written with write().
    """
    
    def __init__(self, file_obj):
        """Wrap the given file-like object."""
        self.file_obj = file_obj
    
    def write(self, str_obj):
        """Write a string to the file object and append a newline character."""
        self.file_obj.write(str_obj + "\n")
        
    def __getattr__(self, attr):
        return getattr(self.file_obj, attr)
    
    
class HiNetHTMLTranslator(HiNetTranslator):
    """Specialized translator for HTML.
    
    Instead of relying on the return values the HTML lines are directly
    written to a provided file.
    """
    
    def __init__(self, show_size=False):
        """Initialize the HMTL translator.
        
        show_size -- Show the approximate memory footprint of all nodes.
        """
        self.show_size = show_size
        self._html_file = None
        
    def write_flow_to_file(self, flow, html_file):
        """Write the HTML translation of the flow into the provided file.
        
        Note that html_file file can be any file-like object with a write
        method.
        """
        self._html_file = NewlineWriteFile(html_file)
        self._translate_flow(flow)
        self._html_file = None
    
    # overwrite private methods
    
    @mdp.with_extension("html")
    def _translate_flow(self, flow):
        """Translate the flow into HTML and write it into the internal file.
        
        Use write_flow_to_file instead of calling this method.
        """
        f = self._html_file
        self._open_node_env(flow, "flow")
        for node in flow:
            f.write('<tr><td>')
            self._translate_node(node)
            f.write('</td></tr>')
        self._close_node_env(flow, "flow")
        
    def _translate_flownode(self, flownode):
        f = self._html_file
        self._open_node_env(flownode, "flownode")
        for node in flownode.flow:
            f.write('<tr><td>')
            self._translate_node(node)
            f.write('</td></tr>')
        self._close_node_env(flownode, "flownode")
     
    def _translate_layer(self, layer):
        f = self._html_file
        self._open_node_env(layer, "layer")
        f.write('<tr>')
        for node in layer:
            f.write('<td>')
            self._translate_node(node)
            f.write('</td>')
        f.write('</tr>')
        self._close_node_env(layer)
        
    def _translate_clonelayer(self, layer):
        f = self._html_file
        self._open_node_env(layer, "layer")
        f.write('<tr><td class="nodename">')
        f.write(str(layer) + '<br><br>')
        f.write('%d repetitions' % len(layer))
        f.write('</td>')
        f.write('<td>')
        self._translate_node(layer.node)
        f.write('</td></tr>')
        self._close_node_env(layer)
        
    def _translate_sameinputlayer(self, layer):
        f = self._html_file
        self._open_node_env(layer, "layer")
        f.write('<tr><td colspan="%d" class="nodename">%s</td></tr>' %
                (len(layer), str(layer)))
        f.write('<tr>')
        for node in layer:
            f.write('<td>')
            self._translate_node(node)
            f.write('</td>')
        f.write('</tr>')
        self._close_node_env(layer)

    def _translate_standard_node(self, node):
        f = self._html_file
        self._open_node_env(node)
        f.write('<tr><td class="nodename">')
        f.write(str(node))
        f.write('</td></tr>')
        f.write('<tr><td class="nodeparams">')
        f.write(node.html_representation())
        f.write('</td></tr>')
        self._close_node_env(node)
        
    # helper methods for decoration
    
    def _open_node_env(self, node, type_id="node"):
        """Open the HTML environment for the node internals.
        
        node -- The node itself.
        type_id -- The id string as used in the CSS.
        """
        self._html_file.write('<table class="%s">' % type_id)
        self._write_node_header(node, type_id)
        
    def _write_node_header(self, node, type_id="node"):
        """Write the header content for the node into the HTML file."""
        f = self._html_file
        if not (type_id=="flow" or type_id=="flownode"):
            f.write('<tr><td class="dim">in-dim: %s</td></tr>' % 
                    str(node.input_dim))
        f.write('<tr><td>')
        f.write('<table class="nodestruct">')
    
    def _close_node_env(self, node, type_id="node"):
        """Close the HTML environment for the node internals.
        
        node -- The node itself.
        type_id -- The id string as used in the CSS.
        """
        f = self._html_file
        f.write('</table>')
        f.write('</td></tr>')
        if not (type_id=="flow" or type_id=="flownode"):
            f.write('<tr><td class="dim">out-dim: %s' % str(node.output_dim))
            if self.show_size:
                f.write('&nbsp;&nbsp;<span class="memorycolor">size: %s</span>' 
                        % mdp.utils.get_node_size_str(node))
            f.write('</td></tr>')
        f.write('</table>')
        

class HiNetXHTMLTranslator(HiNetHTMLTranslator):
    """Modified translator to create valid XHTML."""
    
    def write_flow_to_file(self, flow, xhtml_file):
        """Write the XHTML translation of the flow into the provided file.
        
        This method will produce valid XHTML.
        
        Note that xhtml_file file can be any file-like object with a write
        method.
        """
        # first write the normal HTML into a buffer
        html_file = StringIO.StringIO()
        self._html_file = NewlineWriteFile(html_file)
        self._translate_flow(flow)
        self._html_file = None
        # now translate it to XHTML and then write it to the file
        html_code = html_file.getvalue()
        html_code = html_code.replace('<br>', '<br />')
        html_code = html_code.replace('&nbsp;', '&#160;')
        xhtml_file.write(html_code)
       

## Helper functions ##

def show_flow(flow, filename=None, title="MDP flow display",
              show_size=False, browser_open=True):
    """Write a flow into a HTML file, open it in the browser and
    return the file name.

    flow -- The flow to be shown.
    filename -- Filename for the HTML file to be created. If None
                a temporary file is created.
    title -- Title for the HTML file.
    show_size -- Show the approximate memory footprint of all nodes.
    browser_open -- If True (default value) then the slideshow file is
        automatically opened in a webbrowser.
    """
    if filename is None:
        (fd, filename) = tempfile.mkstemp(suffix=".html", prefix="MDP_")
        html_file = os.fdopen(fd, 'w')
    else:
        html_file = open(filename, 'w')
    html_file.write('<html>\n<head>\n<title>%s</title>\n' % title)
    html_file.write('<style type="text/css" media="screen">')
    html_file.write(mdp.utils.BASIC_STYLE)
    html_file.write(HINET_STYLE)
    hinet_translator = mdp.hinet.HiNetHTMLTranslator(show_size=show_size)
    html_file.write('</style>\n</head>\n<body>\n')
    html_file.write('<h3>%s</h3>\n' % title)
    explanation = '(data flows from top to bottom)'
    html_file.write('<par class="explanation">%s</par>\n' % explanation)
    html_file.write('<br><br><br>\n')
    hinet_translator.write_flow_to_file(flow=flow, html_file=html_file)
    html_file.write('</body>\n</html>')
    html_file.close()
    if browser_open:
        webbrowser.open(os.path.abspath(filename))
    return filename
    
        
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.