# -*- coding: utf-8 -*-
#
# Copyright (c) 2016 Barcelona Supercomputing Center
# @license: https://www.gnu.org/licenses/gpl-3.0.html
# @author: see AUTHORS file


import matplotlib as mpl
#mpl.use('Agg')

import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from matplotlib.cbook import delete_masked_points
import numpy as np
from datetime import datetime
#from datetime import timedelta
#import time
import os.path
import commands
import subprocess
#import sys
from collections import Iterable
from PIL import Image
#from mapgenerator.plotting.mapgenerator import MapCross
#from mapgenerator.plotting.mapgenerator import MapDrawOptions
#from mapgenerator.plotting.mapgenerator import MapDataHandler
from mapgenerator import MapCross
from mapgenerator import MapDrawOptions
from mapgenerator import MapDataHandler
from mapgenerator import CsvDataHandler
from mapgenerator import strictly_increasing
from mapgenerator import do_interpolation


class PlotMap(MapCross, MapDrawOptions):
    """ """

    def __init__(self, **kwargs):
        """ Initialize class with attributes """
        MapCross.__init__(self, **kwargs)
        MapDrawOptions.__init__(self, **kwargs)
        self.nocontourf = False
        self.maxdata = False
        self.maxtitle = None
        self.nomap = False
        self.background = False
        self.extend = 'neither'
        self.kml = False
        self.kmz = False
        self.norm = None
        self.cmap = None
        self.formats = None
        self.map = None   #Map
        #self.first_image = True # Is is the first image of the batch?
        self.mapName = None # name of the figure to map animation colors
        self.drawopts = {'coastlines':
                            {'linewidth': 0.5, 'color': 'grey', },
                         'countries':
                            {'linewidth': 0.3, 'color': 'grey', },
                        }

    def setResolution(self):
        """ 'c','l','i','h','f' """
        # lats = 36, 72, 108, 144, 180
        # lons = 72, 144, 216, 288, 360
        minlat, maxlat = self.lat[0], self.lat[1]
        minlon, maxlon = self.lon[0], self.lon[1]
        lats = maxlat + abs(minlat)
        lons = maxlon + abs(minlon)
        if not self.resolution:
            if lats > 130 and lons > 260:
                self.resolution = 'c'
            elif lats > 100 and lons > 200:
                self.resolution = 'l'
            elif lats > 60 and lons > 120:
                self.resolution = 'i'
            elif lats > 30 and lons > 60:
                self.resolution = 'h'
            elif lats <= 30 and lons <= 60:
                self.resolution = 'f'
            else:
                self.resolution = 'c' # default

    def setColorMap(self):
        """ Create color map """
        if not isinstance(self.colors, str) and isinstance(self.colors, Iterable):
            # adjust number of colors to number of bounds
            if self.bounds:
                if self.extend in ('min','max'):
                    if len(self.bounds) < len(self.colors):
                        self.colors = self.colors[:len(self.bounds)]
                elif self.extend == 'both':
                    if len(self.bounds)+1 < len(self.colors):
                        self.colors = self.colors[:len(self.bounds)+1]
            if self.extend == 'max':
                self.cmap = mpl.colors.ListedColormap(self.colors[:-1])
                self.cmap.set_over(self.colors[-1])
            elif self.extend == 'min':
                self.cmap = mpl.colors.ListedColormap(self.colors[1:])
                self.cmap.set_under(self.colors[0])
            elif self.extend == 'both':
                self.cmap = mpl.colors.ListedColormap(self.colors[1:-1])
                self.cmap.set_over(self.colors[-1])
                self.cmap.set_under(self.colors[0])
            else:
                self.cmap = mpl.colors.ListedColormap(self.colors)
            custom_cmap = True
        else:
            try:
                self.cmap = mpl.cm.get_cmap(self.colors)
            except:
                self.cmap = mpl.cm.get_cmap('jet')
            custom_cmap = False

        if self.bad:
            self.cmap.set_bad(self.bad)

        if self.background or self.kml or self.kmz:
            try:
                self.cmap.colors[-1] = (0,0,0,0)
            except:
                self.cmap.set_under(color=(0,0,0,0))

        # normalize colormap
        if self.bounds and not self.nointerp and not custom_cmap:
            if self.extend == 'min':
                self.norm = mpl.colors.BoundaryNorm([-np.inf]+self.bounds, self.cmap.N+1)
            elif self.extend == 'max':
                self.norm = mpl.colors.BoundaryNorm(self.bounds+[np.inf], self.cmap.N+1)
            elif self.extend == 'both':
                self.norm = mpl.colors.BoundaryNorm([-np.inf]+self.bounds+[np.inf], self.cmap.N+2)
            else:
                self.norm = mpl.colors.BoundaryNorm(self.bounds, self.cmap.N)
        elif self.bounds:
            self.norm = mpl.colors.BoundaryNorm(self.bounds, self.cmap.N)

    def setColorBar(self, mco, location='left', drawedges=False, cax=None):
        """ Create color bar """
#        xs = self.xsize
#        nap = .8-((1-xs)*0.4)
#        a = plt.axes([nap, 0, .14, 1])#, frameon=False)
#        plt.axis('off')
        mpl.rcParams['axes.linewidth'] = 0.1
        if self.map:
            cb = self.map.colorbar(mco, ticks=self.bounds, format=self.formats, pad="2%", size="3%", extend=self.extend, drawedges=drawedges)
        else:
            cb = plt.colorbar(mco, ticks=self.bounds, format=self.formats, pad=.06, extend=self.extend, drawedges=drawedges)
        if self.bounds:
            cb.set_ticklabels(self.bounds)
        else:
            try:
                cb.set_ticklabels(mco.levels)
            except:
                pass
        cb.ax.tick_params(labelsize=self.coords_fontsize)
        for lin in cb.ax.yaxis.get_ticklines():
            lin.set_visible(False)
        #self.printTime("colorbar")

        ## If required, draw arrow pointing to the specified limits
        if self.hasLimits():
            # The following two values are absolute
            shrink = 0.75
            upper = 0.863 - 0.45 * (0.8 - shrink) # formula seems to work ok
            lower = 0.137 + 0.45 * (0.8 - shrink)
            span  = upper - lower
            arrows = self.limits

            if self.bounds:
                ticks = self.bounds
            else:
                ticks = mco.levels

            f = span/float(len(ticks) - 1)
            for i in arrows:
                for j in range(0, len(ticks) - 1):
                    if (i >= ticks[j] and i <= ticks[j+1]):
                        if (i == ticks[j+1]):
                            p = j+1
                            add = 0
                        else:
                            p = j
                            add = (float(i - ticks[j])/float(ticks[j+1] - ticks[j]))*f
                        pos = f*p + lower
                        plt.arrow(0.88, pos + add, 0.10, 0, length_includes_head=True, head_length=0.10, head_width=0.025, fill=True, color='k')
        #plt.colorbar(drawedges=drawedges, cax=cax, ticks=self.bounds)

    def setTitle(self, title, sdate, cdate, step, stime):
        """ Set the title of the current image to the one provided, substituting the
            patterns """

        titleDic = {
            'syear':  sdate.strftime("%Y"),
            'smonth': sdate.strftime("%m"),
            'sMONTH': sdate.strftime("%b"),
            'sday':   sdate.strftime("%d"),
            'shour':  sdate.strftime("%H"),
            'year':   cdate.strftime("%Y"),
            'month':  cdate.strftime("%m"),
            'MONTH':  cdate.strftime("%b"),
            'day':    cdate.strftime("%d"),
            'hour':   cdate.strftime("%H"),
            'step':   step,
            'simday': "%d" % (int(stime)/24),
            'simhh':  stime,
            #'simhh':  "%02d" % (int(stime)%24)
        }

        try:
            pTitle = unicode(title.decode('utf-8')) % titleDic #("%sh" % sTime, valid)
        except Exception, e:
            print("Title error: %s", str(e))
            pTitle = title % titleDic #("%sh" % sTime, valid)

        return pTitle

    def printTime(self, msg=None):
        # initial time
        if 'start_t' not in globals():
            global start_t, last_t
            print("Creating start_t")
            start_t = datetime.now()
            last_t = start_t

        now_t = datetime.now()
        diff_t = now_t - last_t
        if (msg != None):
            print 'TIME:', msg, ' done in ', diff_t.seconds, ' s'
        last_t = now_t

    def runCommand(self, commStr, fatal=True):
        print(commStr)
        p = subprocess.Popen(commStr.split(), stderr=subprocess.PIPE)
        output, err = p.communicate()
        print(output,'-----',err)
#        st, out = commands.getstatusoutput(commStr)
#        if st != 0:
#            print "Error: %s" % str(out)
#            if (fatal == True):
#                sys.exit(1)

    def genAnim(self, indir, inpattern, outdir, outfile):
        ''' Generate an animation starting from a set of
            images, specified by the inpattern parameter '''
        print "Animation: ", indir, inpattern, outdir, outfile
        # Create animation
        #self.runCommand("convert -delay 75 -loop 0 -crop 800x600+0+0 -layers Optimize %s/%s %s/%s" % (indir, inpattern, outdir, outfile))
        self.runCommand("/usr/bin/convert -delay %s -loop 0 -layers Optimize %s/%s %s/%s" % (self.anim_delay, indir, inpattern, outdir, outfile))
        # Remove intermediate files
        #self.runCommand("rm %s/%s %s" % (indir, inpattern, self.mapName), False)

    def initMap(self, grid):
        """ Initialize a Basemap map. Initialization should be performed only once
        the beginning of a serie of images """
        glon, glat = grid
        if not self.lat or len(self.lat) not in (2,3):
            self.lat = (round(glat.min(), 1),
                        round(glat.max(), 1),
                        round((glat.max()-glon.min())/10, 1))
        elif self.lat and len(self.lat) == 2:
            self.lat = (self.lat[0],
                        self.lat[1],
                        round((self.lat[1]-self.lat[0])/10, 1))

        if not self.lon or len(self.lon) not in (2,3):
            self.lon = (round(glon.min(), 1),
                        round(glon.max(), 1),
                        round((glon.max()-glon.min())/10, 1))
        elif self.lon and len(self.lon) == 2:
            self.lon = (self.lon[0],
                        self.lon[1],
                        round((self.lon[1]-self.lon[0])/10, 1))

        #self.printTime("Start: ")

        #self.printTime("Initialization of Basemap:")

        # Fix the printout of tick values to avoid .0 decimals in integers
        strs = []
        if self.bounds:
            for b in self.bounds:
                if (b == int(b)):
                    strs.append("%d" % b)
                else:
                    strs.append(str(b))

            self.formats = mpl.ticker.FixedFormatter(strs)

        #self.first_image = True

        # Set the colormap
        self.setColorMap()
        self.setResolution()


    def genImageMap(self, figName, grid, data,  imgTitle, scatter_data, **kwargs):
        """ Generate image map """
        mapData = data.getMapData()

        plt.clf()
#        params = {
#             'font.size': 14,
#             'text.fontsize': 28,
#             'axes.titlesize': 11,
#             'savefig.dpi': self.dpi
#        }
#
#        mpl.rcParams.update(params)

        if not self.nomap:
            if self.projection != 'cyl':
                lon_0 = (self.lon[1]-abs(self.lon[0]))/2
                lat_0 = (self.lat[1]-abs(self.lat[0]))/2
                #print("-----------", lon_0, lat_0, "-----------")
            else:
                lon_0, lat_0 = None, None
            self.map = Basemap(
                projection=self.projection, resolution=self.resolution,
                llcrnrlon=self.lon[0], llcrnrlat=self.lat[0],
                urcrnrlon=self.lon[1], urcrnrlat=self.lat[1],
                lon_0=lon_0, lat_0=lat_0,
                fix_aspect=self.keep_aspect,
                area_thresh=self.area_thresh
            )

        glon, glat = grid
        if len(glon.shape)==1 and len(glat.shape)==1:
            glon, glat = np.meshgrid(glon, glat)

        #print(glon, glat)
        # if curvilinear grid do interpolation, return already gridded coords
        if not strictly_increasing(glon[0]) or not strictly_increasing(glat[:,0]):
            mapData[0], glon, glat = do_interpolation(mapData[0], glon, glat)

        if not self.nomap:
            x, y = self.map(*(glon, glat))
        else:
            x, y = glon, glat
#        print "X", x.shape
#        print "Y", y.shape
#        print "mapData", mapData[0].shape

        #self.printTime("meshgrid")

        # overwrite option
        if os.path.exists(figName + ".png") and not self.overwrite:
            print figName, " already exists."
            plt.clf()
            return figName

#        # nomap option
#        if self.nomap and os.path.exists("%s-%s/%s.png" % (runDate, varName, figName)) and not self.overwrite:
#            print figName, " already exists."
#            plt.clf()
#            return figName

        if self.nomap:
            self.mgplot.frameon = False

        # Draw filled contour
        if not self.keep_aspect:
            print "Not keeping original aspect"
            ysize_norm = self.ysize*0.8
            xsize_norm = self.xsize*0.8

            rows = imgTitle.count("\n")
            blines = max(rows - 2, 0)
            param = float(self.fontsize)/400
            ystart_base_norm = 0.1 - param*(blines)#imgTitle
            xstart_base_norm = 0.1
            ystart_norm = (0.8 - ysize_norm) / 2 + ystart_base_norm
            xstart_norm = (0.8 - xsize_norm) / 2 + xstart_base_norm
            #ax_map = self.mgaxis.axes([xstart_norm, ystart_norm, xsize_norm, ysize_norm])
            self.mgplot.add_axes([xstart_norm, ystart_norm, xsize_norm, ysize_norm])
            #print "Switching AXES for MAP:", ax_map

        if not self.nocontourf and not self.nomap and not self.nointerp:
            mco = self.map.contourf(x, y, mapData[0], cmap=self.cmap, norm=self.norm, levels=self.bounds, extend=self.extend, horizontalalignment='center')

        elif not self.nocontourf and not self.nomap and self.nointerp:
            mco = self.map.pcolormesh(x, y, mapData[0], cmap=self.cmap, norm=self.norm)

        elif not self.nocontourf and self.nomap and not self.nointerp:
            mco = plt.contourf(x, y, mapData[0], cmap=self.cmap, norm=self.norm, levels=self.bounds, extend=self.extend, horizontalalignment='center')
            plt.axis([self.lon[0], self.lon[1], self.lat[0], self.lat[1]])

        elif not self.nocontourf and self.nomap and self.nointerp:
            mco = plt.pcolormesh(x, y, mapData[0], cmap=self.cmap, norm=self.norm)
            plt.axis([self.lon[0], self.lon[1], self.lat[0], self.lat[1]])

        # Draw shape files
        if self.hasShapeFiles():
            line_w = self.shapef_width_init
            for shapef in self.shapefiles:
                print "Processing shape file:", shapef, " with line width:", line_w
                self.map.readshapefile(shapef, "%s" % os.path.basename(shapef), linewidth=line_w)
                line_w = max(self.shapef_width_step, line_w - self.shapef_width_step)
        #self.printTime("contourf")

        ## FIXME Modify to use scatter inside DATA
        ## if DATA.hasScatterData()... etc...
        if (scatter_data != None):
            print "Plotting scatter data", scatter_data[0], scatter_data[1]
            self.map.scatter(scatter_data[0], scatter_data[1], s=scatter_data[2], c=scatter_data[3], marker='o', linewidth=0.5)

        if data.hasWindData():
            winds = data.getWindData()
            X,Y,U,V = delete_masked_points(x.ravel(), y.ravel(), winds['u'].ravel(), winds['v'].ravel())
            print "Wind scale is", self.wind_units, self.wind_scale
            if winds.has_key('barbs'):
                self.map.barbs(X, Y, U, V, #units=self.wind_units,
                    #headlength=self.wind_head_length,
                    #headwidth=self.wind_head_width,
                    #width=self.wind_width,
                    #minshaft=self.wind_minshaft,
                    #scale=self.wind_scale,
                    color='k')
                #self.printTime("barbs")
            else:
                Q = self.map.quiver(X, Y, U, V, units=self.wind_units,
                        headlength=self.wind_head_length,
                        headwidth=self.wind_head_width,
                        width=self.wind_width,
                        minshaft=self.wind_minshaft,
                        scale=self.wind_scale,
                        color='gray')
                # Draw the key
                plt.quiverkey(Q,
                    self.wind_label_xpos,
                    self.wind_label_ypos,
                    self.wind_label_scale,
                    label='%s m/s' % self.wind_label_scale,
                    coordinates='axes',
                    labelpos='S', labelsep=0.05)
                #self.printTime("quivers")

        if data.hasContourData():
            interval = self.contours_int
            exclude = self.contours_exclude_vals
            cLowBound = -99999
            cUppBound = 99999
            cdata = data.getContourData()
            try:
                cMin = min(filter (lambda a: a > cLowBound, cdata.data.ravel()))
                adjcMin = int(cMin - (cMin % interval) - interval * 2)
            except ValueError:
                cMin =0
            try:
                cMax = max(filter (lambda a: a < cUppBound, cdata.data.ravel()))
                adjcMax = int(cMax - (cMax % interval) + interval * 2)
            except ValueError:
                cMax = 0
            lvls = np.arange(adjcMin, adjcMax, interval)
            for ex in exclude:
                lvls = filter (lambda ex: ex != 0, lvls)
            if(len(lvls) > 0):
                mco = self.map.contourf(x, y, mapData[0], cmap=self.cmap, norm=self.norm, levels=self.bounds, extend=self.extend, horizontalalignment='center')

            print "-----------------", mapData, cdata, "--------------------"
            if (mapData[0] == cdata).all():
                print ":::::::::::::::::::::::: SAME !!! :::::::::::::::::::"
                CS = plt.contour(x, y, cdata, levels=self.bounds,
                        colors=self.contours_color,
                        linewidths=self.contours_linewidth)
            else:
                print ":::::::::::::::::::::::: DIFFERENT !!! :::::::::::::::::::"
                print "MIN:", cMin, "MAX:", cMax
                CS = plt.contour(x, y, cdata, levels=lvls,
                        colors=self.contours_color,
                        linewidths=self.contours_linewidth)

            if self.contours_label:
                self.mgplot.clabel(CS, inline=1,
                        fontsize=self.contours_lbl_fontsize,
                        #backgroundcolor='r',
                        fmt=self.contours_lbl_format)
#            else:
#                print "Not drawing contours since levels has ", len(lvls), " elements"

        #coords normalization
        lat_offset = abs(self.lat[0]) % self.lat[2]
        lon_offset = abs(self.lon[0]) % self.lon[2]

        if not self.nomap and not self.kml and not self.kmz:
            self.map.drawparallels(np.arange(self.lat[0]+lat_offset, self.lat[1], self.lat[2]),labels=[1,0,0,0],linewidth=self.coords_linewidth, fontsize=self.coords_fontsize)
            self.map.drawmeridians(np.arange(self.lon[0]+lon_offset, self.lon[1], self.lon[2]),labels=[0,0,0,1],linewidth=self.coords_linewidth, fontsize=self.coords_fontsize)
            #self.printTime("coords")

            drawopts = self.drawopts
            if drawopts:
                # Drawing countries
                if 'countries' in drawopts:
                    self.map.drawcountries(**drawopts['countries'])
                    #self.printTime("countries")
                # Drawing coastlines (land/sea, lakes, etc...)
                if 'coastlines' in drawopts:
                    self.map.drawcoastlines(**drawopts['coastlines'])
                    #self.printTime("coastlines")
                # Drawing states (FIXME does it work outside the U.S.?)
                if 'states' in drawopts:
                    self.map.drawstates(**drawopts['states'])
                    #self.printTime("states")

        # Change axes for colorbar
        if self.draw_colorbar and not self.kml and not self.kmz and not self.nocontourf:
            self.setColorBar(mco)

        #m.bluemarble()
        if self.background == 'shadedrelief':
            self.map.shadedrelief()
        if self.background == 'bluemarble':
            self.map.bluemarble()
        if self.background == 'etopo':
            self.map.etopo()

        #logo
        if self.logo:
            im = Image.open(self.logo[0])
#            height = im.size[1]
#            width  = im.size[0]

            # We need a float array between 0-1, rather than
            # a uint8 array between 0-255
            nim = np.array(im).astype(np.float) / 255

            # With newer (1.0) versions of matplotlib, you can
            # use the "zorder" kwarg to make the image overlay
            # the plot, rather than hide behind it... (e.g. zorder=10)
            self.mgplot.figimage(nim, self.logo[1], self.logo[2], zorder=10)

        # SAVEFIG
        print "printing ", figName, " ..."
        if self.kml or self.kmz:
            #self.mgplot.axes(frameon=0)
            self.mgplot.savefig("%s.%s" % (figName, self.filefmt),
                                bbox_inches='tight',
                                frameon=0,
                                pad_inches=0, dpi=self.dpi, transparent=True)
        else:
            #a = plt.axes([0.0, 0.0, 1.0, 1.0])
            #plt.axis('off')
            plt.setp(plt.gca().spines.values(), linewidth=.1)
            self.mgplot.text(
                0.5,
                0.98,
                imgTitle,
                horizontalalignment='center',
                verticalalignment='top',
                fontsize=self.fontsize
                )
            self.mgplot.savefig("%s.%s" % (figName, self.filefmt),
                                bbox_inches='tight', pad_inches=.2, dpi=self.dpi)

        #plt.tight_layout()
        #self.printTime("saving")

#        if(self.first_image):
#            #if first image of the batch, produce a image "color map"
#            print "First image of the batch: creating image color map"
#            self.mapName = "%s.map.png" % figName
#            # Get the colorbar to generate the image color map
#            self.runCommand("convert -crop 70x600+730+0 -colors 160 %s.png %s" % (figName, self.mapName))
#            self.first_image = False

        #convert from png to gif
        #print "printing ", figName
#        self.runCommand("convert -quality 80 +dither -remap %s %s.png %s.anim.png" % (self.mapName, figName, figName))
#        self.runCommand("convert +dither %s.png %s.gif" % (figName, figName))
#        self.runCommand("rm %s.png" % figName)

        #plt.clf()
        #self.printTime("convert")
        return figName


    def compareMaps(self, mapNames, outdir, date, steps, tpl=''):
        """ Generate maps comparison """

        os.chdir(outdir)

        #print "MAPNAMES", mapNames
        #for mapName in mapNames:
#        newMapNames = mapNames[0]
#        items = {} #[i[0] for i in mapNames]
#        for i in range(0, len(mapNames)-1):
#            items, newMapNames, newMapNameTpl = self.twoMapsCompare([newMapNames, mapNames[i+1]], items)

        mn = np.array(mapNames)
        ks = mn.T

        idx = 0
        for item in ks:
#            if idx >= len(newMapNames):
#                continue
            imgs = ' '.join([str(i) + '.gif' for i in item])
            if tpl:
                newimg = tpl % {'date':date, 'step':steps[idx]}
            else:
                newimg = steps[idx]
            #comm = "montage %s -tile 2x -geometry 800x600+1+1 %s.gif" % (imgs, newMapNames[idx])
            comm = "montage %s -tile 2x -geometry +1+1 %s.gif" % (imgs, newimg)
            #print "COMPARE COMMAND:", comm
            st, out = commands.getstatusoutput(comm)
            idx += 1

        #montage <infiles> -tile 2x -geometry 800x600+1+1 <outfile>

        #rename from 00-06-... to 00-01 ...
#        st, out = commands.getstatusoutput("ls %s*" % newMapNameTpl)
#        if st != 0:
#            print "Error: %s" % str(out)
#        else:
#            names = out.split('\n')
#            #print names
#            for num in range(0, len(names)):
#                snum = "%02d" % num
#                #print "mv %s %s.gif" % (names[num], newMapNameTpl.replace("??", snum))
#                st2, out2 = commands.getstatusoutput("mv -f %s %s.gif" % (names[num], newMapNameTpl.replace("??", snum)))
#                if st2 != 0:
#                    print "Error: %s" % str(out2)

#        newMapNameTpl2 = newMapNameTpl.replace("??", "loop")
        nimg0 = "??"
        nimg1 = "loop"
        if tpl:
            nimg0 = tpl % {'date':date, 'step':nimg0}
            nimg1 = tpl % {'date':date, 'step':nimg1}
        st, out = commands.getstatusoutput("convert -delay 75 -loop 0 %s.gif %s.gif" % (nimg0, nimg1))
        if st != 0:
            print "Error: %s" % str(out)


    def genKML(self, figNames, srcvars, dims, online):
        """ """
        from lxml import etree
#        from pykml.parser import Schema
        from pykml.factory import KML_ElementMaker as KML
#        from datetime import datetime, timedelta
        import zipfile

        lon = self.lon
        lat = self.lat

        kmlName = '-'.join(os.path.basename(figNames[0]).split('-')[:-1])
        varName = srcvars[0] #figNames[0].split('-')[-2]
        runDate0 = datetime.strptime(dims[0], "%HZ%d%b%Y") #.strftime("%Y%m%d%H")
        runDate1 = datetime.strptime(dims[1], "%HZ%d%b%Y") #.strftime("%Y%m%d%H")
        begindate = runDate0.strftime("%Y%m%d%H")
        dirName = os.path.join(self.outdir, begindate + '-' + varName).replace('./','')
        interval = runDate1 - runDate0
        datefmt = "%Y-%m-%dT%H:00:00Z"

        doc = KML.kml(
            KML.Folder(
                KML.name(kmlName),
                KML.LookAt(
                    KML.longitude((lon[1]+lon[0])/2),
                    KML.latitude((lat[1]+lat[0])/2),
                    KML.range(8500000.0),
                    KML.tilt(0),
                    KML.heading(0),
                ),
                KML.ScreenOverlay(
                    KML.name("Legend"),
                    KML.open(1),
                    KML.Icon(
                        KML.href("%s/%s-colorbar.png" % (dirName, begindate)),
                    ),
                    KML.overlayXY(x="0",y="1",xunits="fraction",yunits="fraction"),
                    KML.screenXY(x=".01",y="0.75",xunits="fraction",yunits="fraction"),
                    KML.rotationXY(x="0",y="0",xunits="fraction",yunits="fraction"),
                    KML.size(x="0",y="0.5",xunits="fraction",yunits="fraction"),
                    id="%s-ScreenOverlay" %(begindate),
                ),
            )
        )

        try:
            os.mkdir(dirName)
        except:
            pass

        if not online:
            zf = zipfile.ZipFile("%s.kmz" % kmlName, 'w')

        for figName, dat in zip(figNames, sorted(dims.keys())):
            dt = dims[dat]
            figName = figName + ".png"
            figPath = os.path.join(dirName,os.path.basename(figName))
            startdate = datetime.strptime(dt, "%HZ%d%b%Y")
            begdate = startdate.strftime(datefmt)
            enddate = (startdate + interval).strftime(datefmt)
            starth = startdate.hour
            doc.Folder.append(KML.GroundOverlay(
                KML.name("%02d:00:00Z" % starth),
                KML.TimeSpan(
                    KML.begin(begdate),
                    KML.end(enddate),
                ),
                KML.Icon(
                    KML.href(figPath),
                    KML.viewBoundScale(1.0),
                ),
                KML.altitude(0.0),
                KML.altitudeMode("relativeToGround"),
                KML.LatLonBox(
                    KML.south(lat[0]),
                    KML.north(lat[1]),
                    KML.west(lon[0]),
                    KML.east(lon[1]),
                    KML.rotation(0.0),
                ),
            ))

            if os.path.exists(figName):
                os.rename(figName, figPath)
                zf.write(figPath)

        outf = file("%s.kml" % kmlName, 'w')
        outf.write('<?xml version="1.0" encoding="UTF-8"?>\n')
        outf.write(etree.tostring(doc, pretty_print=True))
        outf.close()

        if not online:
            zf.write("%s.kml" % kmlName)
            zf.write("%s/%s-colorbar.png" % (dirName, begindate))
            zf.close()

            for img in os.listdir(dirName):
                os.remove("%s/%s" % (dirName, img))
            os.rmdir(dirName)
            os.remove("%s.kml" % kmlName)


    def plot(self, srcfiles, srcvars, **kwargs):
        """ Plot one or more maps """

#        global run
#        global run_tmp

        if isinstance(srcvars, str):
            srcvars = [srcvars]
        elif not isinstance(srcvars, list):
            print('Error')

        if isinstance(srcfiles, str):
            srcfiles = [srcfiles]
        elif not isinstance(srcfiles, list):
            print('Error')

        #run = ''
        run_tmp = ''
        mapNames = []

#        curdir = os.getcwd()

        nc_handler = None
        csv_handler = None

        # store options to be restored at the end
        localvars = vars(self).copy()
        vars(self).update(kwargs)
        # arguments are only local

        if (self.windopts and (len(self.windopts) == 4)):
            self.wind_scale = int(self.windopts[3]);

        if (self.scatter != None):
            csv_handler = CsvDataHandler("%s/%s" % (self.indir, self.scatter))

#        if (shapefiles != None):
#            for s in shapefiles:
#               shapefiles.append("%s/%s" % (indir, s))

        nc_handler = MapDataHandler(
                                    srcfiles,
                                    srcvars,
                                    self.indir,
                                    self.srcgaps,
                                    self.wind,
                                    self.windopts,
                                    self.lat,
                                    self.lon,
                                    self.transf,
                                    self.subsetting,
                                    winds={'src': self.wind,
                                           'opts': self.windopts},
                                    contours={'var': self.contours},
                                    varconds=self.varconds,
                                   )

        figNames = []
        pltNames = []

        dims = nc_handler.getDims()
        run_tmp = dims[0] #12:30Z30NOV2010
        if run_tmp[:-10] == "01:30": run_tmp = run_tmp.replace("01:30", "00")
        #run = "%sh %s %s %s" % (run_tmp[:-10], run_tmp[-9:-7], run_tmp[-7:-4], run_tmp[-4:])

        # return grid
        grid = nc_handler.grid

        #if not NOMAP:
        self.initMap(grid)

        sDate = datetime.strptime("%s %s %s %s" % (run_tmp[-4:], run_tmp[-7:-4], run_tmp[-9:-7], run_tmp[0:2]), "%Y %b %d %H" )

        ssDate = sDate.strftime("%Y%m%d")
        steps = []

        if self.timesteps == 'all':
            self.timesteps = np.array(sorted(dims.keys()))
        else:
            self.timesteps = np.array(self.timesteps)

        START = self.timesteps[0]

        print "START AT ", START, ' sDate:', sDate, ' run_tmp', run_tmp

        if START is None:
            START = 0

        for nTime in self.timesteps: #range(START,int(TOTAL),INTERVAL):

            plt.clf()

#            self.mgplot = plt.figure()
#            self.mgaxis = plt.gca()
            self.mgplot, self.mgaxis = plt.subplots()

            scatter_data = None

            valid_tmp = dims[nTime]
            currDate = datetime.strptime("%s %s %s %s" % (valid_tmp[-4:], valid_tmp[-7:-4], valid_tmp[-9:-7], valid_tmp[0:2]), "%Y %b %d %H" )

            sTime = "%02d" % nTime
            steps.append(sTime)

            pTime = (currDate - sDate).total_seconds()/3600
            sTime24 = "%02d" % (pTime%24)
            #sTime3d = "%03d" % pTime # Currently unused, only for Valentina who has more than 99 img in a set

            if self.img_template:
                fName = self.img_template % {'date': ssDate, 'step': sTime}
                figName = "%s/%s" % (self.outdir, fName)
                loopName = self.img_template % {'date': ssDate, 'step': 'loop'}
            else:
                fName = '.'.join(srcfiles[0].split('.')[:-1])
                figName = "%s/%s_%s" % (self.outdir, fName, sTime)
                loopName = "%s_loop" % (fName)

            #valid = "%02dUTC %s" % (pTime % 24, currDate.strftime("%d %b %Y"))

            #stime = "%02d" % (int(run_tmp.split('Z')[0])+pTime)
            stime = "%02d" % (pTime)
            pTitle = self.setTitle(self.title, sDate, currDate, sTime, stime)

            # plot scatter data
            if(csv_handler != None):
                ccc = []
                ccc.append(self.under)
                ccc.extend(self.colors)
                ccc.append(self.over)
                print "Filtering scatter data for date/hour: ", currDate.strftime("%Y%m%d"), sTime24
                csv_lat, csv_lon, csv_con = csv_handler.filter(currDate.strftime("%Y%m%d"), sTime24)
                csv_col = self.dataTransform.setColorsFromBuckets(ccc, self.bounds, csv_con)
                if(len(csv_lat) > 0):
                    scatter_data = [csv_lon, csv_lat, 40, csv_col]
                    print "**************** SCATTER_DATA", scatter_data
                    print "Filtered %d records for scatterplot" % len(scatter_data)

            fn = self.genImageMap(
                                  figName,
                                  grid,
                                  nc_handler.getDataForTstep(nTime),
                                  pTitle,
                                  scatter_data=scatter_data
                                 )

            figNames.append(fn)
            pltNames.append((self.mgplot, self.mgaxis))

            # Create Max at required intervals
            if self.maxdata and nTime in self.maxdata:
                if (self.maxtitle != None):
                    figName = "%s/%s_%s" % (self.outdir, fName, 'MAXD%d' % (nTime/24))
                    pTitle = self.setTitle(self.maxtitle, sDate, currDate, sTime)
                    self.genImageMap(
                                    figName,
                                    grid,
                                    nc_handler.getCurrentMaxData(),
                                    pTitle
                                    )
                else:
                    print "Missing MAXTITLE, thus not generating MAX images!"

        if self.kml or self.kmz:
            plt.clf()

            runDate = sDate.strftime("%Y%m%d%H")
            #separate colorbar
            mpl.rcParams['axes.linewidth'] = 0.1
            fig = plt.figure(figsize=(.1,12))
            ax = fig.add_axes([0.05, 0.80, 0.9, 0.15], axisbg=(1,1,1,0))
            cb = mpl.colorbar.ColorbarBase(
                                           ax,
                                           cmap=self.cmap,
                                           norm=self.norm,
                                           ticks=self.bounds,
                                           extend=self.extend,
                                           drawedges=False)
            plt.setp(plt.getp(ax, 'yticklabels'), color='w')
            plt.setp(plt.getp(ax, 'yticklabels'), fontsize=6)
            for lin in cb.ax.yaxis.get_ticklines():
                lin.set_visible(False)

            tit = unicode(pTitle.decode('utf-8'))
            idx1 = tit.find('(')
            idx2 = tit.find(')')
            varUnit = tit[idx1:idx2+1]
            if varUnit.find("%s") >= 0:
                varUnit = ''
            plt.xlabel(
                "%s\n%s" % (srcvars[0], varUnit),
                horizontalalignment='left',
                color='w',
                fontsize=6,
            )
            ax.xaxis.set_label_coords(-0.025,-0.025)

            try:
                os.mkdir("%s-%s" % (runDate, srcvars[0]))
            except:
                pass

            fig.savefig(
                        "%s-%s/%s-colorbar.png" % (runDate, srcvars[0], runDate),
                        bbox_inches='tight',
                        pad_inches=0, dpi=self.dpi,
                        transparent=True
                       )

            #generate KMZ - Offline
            if self.kmz:
                print "Generating KMZ ..."
                self.genKML(figNames, srcvars, dims, online=False)

            #generate KML - Online
            if self.kml:
                print "Generating KML ..."
                self.genKML(figNames, srcvars, dims)

        #generate animation.
        if self.anim:
            fulloutdir = os.path.join(self.outdir, os.path.dirname(self.img_template))
            loopName = os.path.basename(loopName)
            self.genAnim(
                         fulloutdir,
                         "%s.%s" % (loopName.replace('loop','*'), self.filefmt),
                         fulloutdir,
                         "%s.gif" % loopName
                        )

        mapNames.append(figNames)

        # restore options without local function parameters
        vars(self).update(localvars)

        #print "Returning ", pltNames
        #return pltNames

#    num = len(mapNames)
#    if num > 1:
#        mg.compareMaps(mapNames, OUTDIR, ssDate, steps, JOINT_TEMPLATE )


    def loadConf(self, section=None, fpath=None):
        """ Load existing configurations from file. """

        from config import readConf

        if fpath == None:
            fpath = os.path.join(self.config_dir, self.config_file)

        if not os.path.isabs(fpath):
            fpath = os.path.join(self.indir, fpath)

        if not os.path.isfile(fpath):
            print("Error %s" % fpath)
            return

        opts = readConf(section, fpath)
        if section == None:
            return opts

        vars(self).update(opts)


    def writeConf(self, section, fpath=None):
        """ Write configurations on file. """

        from config import writeConf

        if fpath == None:
            fpath = os.path.join(self.config_dir, self.config_file)

        if not os.path.isabs(fpath):
            fpath = os.path.join(self.indir, fpath)

        # create new dir if doesn't exist
        dirname = os.path.dirname(fpath)
        if not os.path.exists(dirname):
            os.makedirs(dirname)

        writeConf(section, fpath, vars(self))


    def resetConf(self):
        """ Back to the initial conditions. """

        self.__init__()

#def run():
#    """ """
#
#    import sys
#    import string
#    import os
#    import os.path
#
#    parser = parseOpts()
#
#    (options, args) = parser.parse_args()
#
#    #print options
#    #print args
#
#    if len(args) < 1:
#        parser.error("wrong number of arguments")
#
#    global run
#    global run_tmp
#
#    clf()
#
#    run = ''
#    run_tmp = ''
#    mapNames = []
#
#    cFile = options.configfile
#    #section name(s)
#    fNames = args
#
#    curdir = os.getcwd()
#
#    mg = MapGenerator()
#
#    for fName in fNames:
#        #os.chdir(curdir)
#
#        #print '@@@@@', fName, '; ', cFile
#        OPTS = readConf(fName, cFile)
#        #print OPTS
#
#        if not OPTS:
#            print "Section '", fName, "' doesn't exist."
#            continue
#
#        INDIR = options.indir or OPTS['indir']
#        OUTDIR = options.outdir or OPTS['outdir']
#        SOURCES = options.srcfile or OPTS['srcfile']
#        SRCVAR = options.var or OPTS['var']
#        SRCGAP = options.gap or OPTS['gap']
#        BOUNDS = options.bounds or OPTS['bounds']
#        BOUNDARIES = options.boundaries or OPTS['boundaries']
#        COLORS = options.colors or OPTS['colors']
#        TOTAL = options.total or OPTS['total']
#        INTERVAL = options.interval or OPTS['interval']
#        FREQ = options.freq or OPTS['freq']
#        TITLE = options.title or OPTS['title']
#        MAXTITLE = options.maxtitle or OPTS['maxtitle']
#        LAT = options.lat or OPTS['lat']
#        LON = options.lon or OPTS['lon']
#        OVER = options.over or OPTS['over']
#        UNDER = options.under or OPTS['under']
#        LIMITS = options.limits or OPTS['limits']
#        WIND = options.wind or OPTS['wind']
#        WINDOPTS = options.windopts or OPTS['windopts']
#        RESOLUTION = options.resolution or OPTS['resolution']
#        SHAPES = options.shapes or OPTS['shapes']
#        ASPECT = options.aspect or OPTS['aspect']
#        MAX = options.max or OPTS['max']
#        DRAWOPTS = options.drawopts or OPTS['drawopts']
#        AREA_THRESH = options.area_thresh or OPTS['area_thresh']
#        SCATTER = options.scatter or OPTS['scatter']
#        DPI = options.dpi or OPTS['dpi']
#        IMG_TEMPLATE = options.dpi or OPTS['img_template']
#        JOINT_TEMPLATE = options.joint_template or OPTS['joint_template']
#        XSIZE = options.xsize or OPTS['xsize']
#        YSIZE = options.ysize or OPTS['ysize']
#        ANIM = options.anim or OPTS['anim']
#        TRANSF = options.transf or OPTS['transf']
#        CONTOURS = options.contours or OPTS['contours']
#        CONTOURS_COLOR = options.contours_color or OPTS['contours_color']
#        CONTOURS_LABEL = options.contours_label or OPTS['contours_label']
#        CONTOURS_INTERVAL = options.contours_interval or OPTS['contours_interval']
#        NOCONTOURF = options.nocontourf or OPTS['nocontourf']
#        NOMAP = options.nomap or OPTS['nomap']
#        NOINTERP = options.nointerp or OPTS['nointerp']
#        START = options.start or OPTS['start']
#        COLORBAR = options.colorbar or OPTS['colorbar']
#        TSTEPS = options.tsteps or OPTS['tsteps']
#        VARCONDS = options.varconds or OPTS['varconds']
#        KML = options.kml or OPTS['kml'],
#        KMZ = options.kmz or OPTS['kmz'],
#        NODRAW = options.nodraw or OPTS['nodraw'],
#        OVERWRITE = options.overwrite or OPTS['overwrite'],
#        BACKGROUND = options.background or OPTS['background'],
#        LOGO = options.logo or OPTS['logo'],
#        NORUNTIME = options.noruntime or OPTS['noruntime'],
#
#
#        print "OPTIONS:", """
#        INDIR = %s
#        OUTDIR = %s
#        SOURCES = %s
#        SRCVAR = %s
#        SRCGAP = %s
#        BOUNDS = %s
#        BOUNDARIES = %s
#        COLORS = %s
#        TOTAL = %s
#        INTERVAL = %s
#        FREQ = %s
#        TITLE = %s
#        MAXTITLE = %s
#        LAT = %s
#        LON = %s
#        OVER = %s
#        UNDER = %s
#        LIMITS = %s
#        WIND = %s
#        WINDOPTS = %s
#        RESOLUTION = %s
#        SHAPES = %s
#        ASPECT = %s
#        MAX = %s
#        DRAWOPTS = %s
#        AREA THRESHOLD = %s
#        SCATTER = %s
#        DPI = %s
#        XSIZE = %s
#        YSIZE = %s
#        ANIM = %s
#        TRANSF = %s
#        CONTOURS = %s
#        CONTOURS_COLOR = %s
#        CONTOURS_LABEL = %s
#        KML = %s
#        KMZ = %s
#        OVERWRITE = %s
#        BACKGROUND = %s
#        LOGO = %s
#        NORUNTIME = %s
#        TOGIF = %s
#""" % (INDIR, OUTDIR, SOURCES, SRCVAR, SRCGAP, BOUNDS, BOUNDARIES, COLORS, TOTAL, INTERVAL, FREQ, TITLE, MAXTITLE, LAT, LON, OVER, UNDER, LIMITS, WIND, WINDOPTS, RESOLUTION, SHAPES, ASPECT, MAX, DRAWOPTS, AREA_THRESH, SCATTER, DPI, XSIZE, YSIZE, ANIM, TRANSF, NOINTERP, CONTOURS, CONTOURS_COLOR, CONTOURS_LABEL, KML, KMZ, OVERWRITE, BACKGROUND, LOGO, NORUNTIME)
#
#        galab_handler = None
#        csv_handler = None
#
#        # PROCESS DRAWING OPTIONS
#        DRAW_OPTS = MapDrawOptions()
#
#        if(LIMITS != None):
#            aq_limits = LIMITS
#
#        if(RESOLUTION != None):
#            resolution = RESOLUTION
#
#        if(ASPECT != None):
#            keep_aspect = ASPECT
#
#        if(COLORBAR != None):
#            draw_colorbar = COLORBAR
#
#        if(CONTOURS_LABEL != None):
#            contours_label = CONTOURS_LABEL
#
#        if(CONTOURS_INTERVAL != None):
#            contours_interval = int(CONTOURS_INTERVAL)
#
#        if(XSIZE != None):
#            xsize = float(XSIZE)
#
#        if(YSIZE != None):
#            ysize = float(YSIZE)
#
#        if(DPI != None):
#            dpi = int(DPI)
#
#        if(HIDDEN_TSTEPS == None):
#            HIDDEN_TSTEPS = []
#
##        if(VARCONDS != None):
##            varconds = eval(VARCONDS)
##        else:
##            varconds = VARCONDS
#
#        if (WINDOPTS and (len(WINDOPTS) == 4)):
#            wind_scale = int(WINDOPTS[3]);
#
#        if (options.contours_interval or OPTS['contours_interval']):
#            contours_interval = options.contours_interval or OPTS['contours_interval']
#            print "CONTOUR INTERVAL:", contours_interval
#
#        if (options.contours_color or OPTS['contours_color']):
#            contours_color = options.contours_color or OPTS['contours_color']
#            print "CONTOUR COLOR:", contours_color
#
#        if (options.contours_label or OPTS['contours_label']):
#            contours_label = options.contours_label or OPTS['contours_label']
#            print "CONTOUR LABEL:", contours_label
#
#        if (options.nocontourf or OPTS['nocontourf']):
#            nocontourf = options.nocontourf or OPTS['nocontourf']
#            print "NOCONTOURF:", nocontourf
#
#        if (options.nomap or OPTS['nomap']):
#            nomap = options.nomap or OPTS['nomap']
#            print "NOMAP:", nomap
#
#        if (options.nointerp or OPTS['nointerp']):
#            nointerp = options.nointerp or OPTS['nointerp']
#            print "NOINTERP:", nointerp
#
#        gaLab_handler = MapDataHandler(INDIR, SOURCES, SRCVAR, SRCGAP, WIND, WINDOPTS, LAT, LON, TRANSF, winds={'src': WIND, 'opts': WINDOPTS}, contours={'var': CONTOURS}, varconds=VARCONDS)
#
#        if (SCATTER != None):
#            csv_handler = CsvDataHandler("%s/%s" % (INDIR, SCATTER))
#
#        if(SHAPES != None):
#            for s in SHAPES:
#               shapefiles.append("%s/%s" % (INDIR, s))
#
#        figNames = []
#
#        dims = gaLab_handler.getDims()
#        run_tmp = dims.time[0] #12:30Z30NOV2010
#        if run_tmp[:-10] == "01:30": run_tmp = run_tmp.replace("01:30", "00")
#        run = "%sh %s %s %s" % (run_tmp[:-10], run_tmp[-9:-7], run_tmp[-7:-4], run_tmp[-4:])
#
#        valid_tmp = dims.time[1]
#
#        #if not NOMAP:
#        mg.initMap(DRAW_OPTS, LAT, LON, BOUNDS, BOUNDARIES, COLORS, OVER, UNDER,
#            area_thresh=int(AREA_THRESH))
#
#        sDate = datetime.strptime("%s %s %s %s" % (run_tmp[-4:], run_tmp[-7:-4], run_tmp[-9:-7], run_tmp[0:2]), "%Y %b %d %H" )
#        aDate = datetime.strptime("%s %s %s %s" % (valid_tmp[-4:], valid_tmp[-7:-4], valid_tmp[-9:-7], valid_tmp[0:2]), "%Y %b %d %H" )
#
#        ssDate = sDate.strftime("%Y%m%d")
#        steps = []
#        print "START AT ", START, ' sDate:', sDate, ' aDate:', aDate, ' run_tmp', run_tmp, 'valid_tmp ', valid_tmp
#
#        if START is None:
#            START = 0
#
#        for nTime in range(START,int(TOTAL),INTERVAL):
#
#            if nTime in HIDDEN_TSTEPS:
#                continue
#
#            scatter_data = None
#
#            pTime = nTime*FREQ
#            sTime = "%02d" % pTime
#            steps.append(sTime)
#            sTime24 = "%02d" % (pTime%24)
#            sTime3d = "%03d" % pTime # Currently unused, only for Valentina who has more than 99 img in a set
#            if IMG_TEMPLATE:
#                fName = IMG_TEMPLATE % {'date': ssDate, 'step': sTime}
#                figName = "%s/%s" % (OUTDIR, fName)
#                loopName = IMG_TEMPLATE % {'date': ssDate, 'step': 'loop'}
#            else:
#                figName = "%s/%s_%s" % (OUTDIR, fName, sTime)
#                loopName = "%s_loop" % (fName)
#
#            aDelta = timedelta(hours = pTime)
#            currDate = aDate + aDelta
#            valid = "%02dUTC %s" % (pTime % 24, currDate.strftime("%d %b %Y"))
#
#            if(csv_handler != None):
#                ccc = []
#                ccc.append(UNDER)
#                ccc.extend(COLORS)
#                ccc.append(OVER)
#                print "Filtering scatter data for date/hour: ", currDate.strftime("%Y%m%d"), sTime24
#                csv_lat, csv_lon, csv_con = csv_handler.filter(currDate.strftime("%Y%m%d"), sTime24)
#                csv_col = dataTransform.setColorsFromBuckets(ccc, BOUNDS, csv_con)
#                if(len(csv_lat) > 0):
#                    scatter_data = [csv_lon, csv_lat, 40, csv_col]
#                    print "**************** SCATTER_DATA", scatter_data
#                    print "Filtered %d records for scatterplot" % len(scatter_data)
#
#            stime = "%02d" % (int(run_tmp.split('Z')[0])+pTime)
#            pTitle = mg.setTitle(TITLE, sDate, currDate, sTime, stime)
#
#            figNames.append(mg.genImageMap(figName, valid, gaLab_handler.getDataForTstep(nTime), pTitle,
#                limits=LIMITS, drawopts=DRAWOPTS, scatter=scatter_data))
#
#            # Create Max at required intervals
#            if MAX and nTime in MAX:
#                if (MAXTITLE != None):
#                    figName = "%s/%s_%s" % (OUTDIR, fName, 'MAXD%d' % (nTime/24))
#                    pTitle = mg.setTitle(MAXTITLE, sDate, currDate, sTime)
#                    mg.genImageMap(figName, valid, gaLab_handler.getCurrentMaxData(), pTitle, drawopts=DRAWOPTS)
#                else:
#                    print "Missing MAXTITLE, thus not generating MAX images!"
#
#        #generate animation.
#        if ANIM and (ANIM == True):
#            mg.genAnim(OUTDIR, "%s.gif" % loopName.replace('loop','*'), OUTDIR, "%s.gif" % loopName)
#            #mg.genAnim(OUTDIR, "%s_[0-9][0-9].anim.png" % fName, OUTDIR, "%s_ANIM.gif" % fName)
#
#        mapNames.append(figNames)
#
#    num = len(mapNames)
#    if num > 1:
#        mg.compareMaps(mapNames, OUTDIR, ssDate, steps, JOINT_TEMPLATE )


#if __name__ == "__main__":
#    run()
