"""
File saving routines for plots.
Typically called using save_plotgroup in commands/analysis.py, but these
objects can also be instantiated explicitly, to save a series of plots.
"""
import Image
import numpy
import param
from param import normalize_path
import topo
# Consider using PIL's ImageFont module
[docs]class PlotGroupSaver(param.Parameterized):
    """
    Allows a PlotGroup to be saved as a set of bitmap files on disk.
    """
    file_format = param.String(default="png",doc="""
        Bitmap image file format to use.""")
    filename_prefix = param.String(default="",doc="""
        Optional prefix that can be used in the filename_format command
        to disambiguate different simulations or conditions.""")
    filename_suffix = param.String(default="",doc="""
        Optional suffix that can be used in the filename_format command
        to disambiguate different simulations or conditions.""")
    filename_format = param.String(default=
        "%(filename_prefix)s%(basename)s_%(plot_label)s%(filename_suffix)s.%(file_format)s",doc="""
        Format string to use for generating filenames for plots.  This
        string will be evaluated in the context of a dictionary that
        defines various items commonly used when generating filenames,
        including::
          basename:    the default sim.basename(), usually name+time()
          time:        the current simulation time (topo.sim.time())
          sim_name:    the name of the current simulation (topo.sim.name)
          plot_label:  the label specfied in the PlotGroup for this plot
          file_format: the bitmap image file format for this type of plot
          plotgroup_name: the name of this PlotGroup
      """)
    # Should move this out of plotfilesaver to get the same filenames in the GUI.
    # Should also allow each template in topo/command/analysis.py to have a nice
    # short filename format, perhaps as an option.
    def __init__(self,plotgroup,**params):
        super(PlotGroupSaver,self).__init__(**params)
        self.plotgroup = plotgroup
[docs]    def strip(self,filename):
        """Strip inappropriate characters from a filename."""
        return filename\
            
.replace('\n','_')\
            
.replace('\t','_')\
            
.replace(' ','_')\
            
.replace('&','And')
 
[docs]    def filename(self,label,**params):
        """Calculate a specific filename from the filename_format."""
        varmap = dict(self.get_param_values())
        varmap.update(self.__dict__)
        varmap['basename']= topo.sim.basename()
        varmap['sim_name']= topo.sim.name
        varmap['time']=topo.sim.time()
        varmap['plot_label']=label
        varmap['plotgroup_name']=self.plotgroup.name
        varmap.update(params)
        return self.strip(self.filename_format % varmap)
 
    def save_to_disk(self,**params):
        for p,l in zip(self.plotgroup.plots,self.plotgroup.labels):
            p.bitmap.image.save(normalize_path(self.filename(l,**params)))
# Could move this elsewhere if it will be useful.
#
# Adapted from:
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/412982 
[docs]class CFProjectionPlotGroupSaver(PlotGroupSaver):
    """
    Allows a CFProjectionPlotGroup to be saved as a bitmap file,
    concatenating all the CF plots into a single image.
    """
    def save_to_disk(self,**params):
        imgs = numpy.array([p.bitmap.image
                            for p in self.plotgroup.plots],
                           dtype=object).reshape(
            self.plotgroup.proj_plotting_shape)
        img = make_contact_sheet(imgs, (3,3,3,3), 3)
        img.save(normalize_path(self.filename(
            self.plotgroup.sheet.name+"_"+
            self.plotgroup.projection.name,**params)))