##### Python to plot multiple plots at the same time in a panel
# L. Fita, LMD September 2016
## e.g. #  multi_plot.py -f multi_plot.dat -o multi_plot -d True -s True
import os
import subprocess as sub
import numpy as np
from netCDF4 import Dataset as NetCDFFile
import matplotlib.pyplot as plt
import nc_var_tools as ncvar
import drawing_tools as drw
import generic_tools as gen
import drawing as DrW
import matplotlib as mpl
from optparse import OptionParser

main='multi_plot.py'

errormsg='ERROR -- error -- ERROR -- error'
warnmsg='WARNING -- warning -- WARNING -- warning'

class values_figure(object):
    """ Class with the values to plot a figure
      self.files= list with the files to use
      self.vals= values to use for the plot
      self.vars= list with the variables to use
    """

    def __init__(self,files,vals,varns):
        self.files = files
        self.vals = vals
        self.vars = varns

####### ###### ##### #### ### ## #
fix_multiplot_conf = ['title','kind','panel']

parser = OptionParser()
parser.add_option("-d", "--debug", dest="debug", 
  help="debug ('true'/'false')", metavar="VALUE")
parser.add_option("-f", "--file_configuration", dest="fileconf", help="configuration file to use", 
  metavar="FILE")
parser.add_option("-o", "--output_name", dest="oname", 
  help="name of the output figure (without extension)", metavar="LABEL")
parser.add_option("-s", "--seeFigure", dest="seefig", 
  help="see resultan figure ('true'/'false')", metavar="VALUE")

(opts, args) = parser.parse_args()

#######    #######
## MAIN
    #######

if opts.debug is None:
    print warnmsg
    print '  ' + main + ": no debug provided!!"
    print "    give a value for the option '-d/--debug'"
    print "       debug ('true'/'false')"
    print " Assuming 'false'"
    dbg=False
else:
    dbg=gen.Str_Bool(opts.debug)

if opts.fileconf is None:
    print errormsg
    print '  ' + main + ": no configuration file provided!!"
    print "    give a value for the option '-f/--file_configuration'"
    print "      configuration file to use"
    quit(-1)

if not os.path.isfile(opts.fileconf):
    print errormsg
    print '  '+main+": configuration file '" + opts.fileconf + "' does not exist!!"
    quit(-1)

if opts.oname is None:
    print warnmsg
    print '  ' + main + ": no output figure name provided!!"
    print "    give a value for the option '-o/--output_name'"
    print "       name of the output figure (without extension)"
    print " Assuming 'multi_plot'"
    oname='multi_plot'
else:
    oname=opts.oname

if opts.seefig is None:
    print warnmsg
    print '  ' + main + ": no seeing figure provided!!"
    print "    give a value for the option '-s/--seeFigure'"
    print "      see resultan figure ('true'/'false')"
    print " Assuming 'false'"
    seefig=False
else:
    seefig=gen.Str_Bool(opts.seefig)


# Reading configuration file
# File strcture must be as follows
#    fig_title: Title of the figure ('!') for spaces  (None for no title)
#    fig_panel: [Ncol],[Nrow] panel of figures with Ncolumns and Nrows
#    fig_kind: kind of the output figure (None, png)
#    kind: [graphic_label] (from drawing.py)
#    file: [file1],[file2],...,[fileN] (',' list of files if required)
#    values: Specific values for this graphic (in same format as in [graphic_label]
#    variables: [var1],[var2],....,[varN] (',' list of variables if required)
# Figures will be draw consecutively as they appear in the file

# Dictionary with the figures to plot and their values kepts in a class
figures = {}

# List of the names of the figures as they appear in the file
figns = []

# List of the names of the variables as they appear in the file
varns = []

# Dictionary with the number of times that a given graphic appears in the panel
Nfigs = {}

oconf = open(opts.fileconf)
kindn = None
kindnow = None
variables = None
for line in oconf:
    if line[0:1] != '#' and len(line) > 1 and line.find(':') != -1:
        label = line.split(':')[0].replace(' ','')
        vals = line.split(':')[1].replace('\n','')
        if label == 'fig_title': figures['title'] = vals
        elif label == 'fig_panel': 
            vals0 = vals.replace(' ','').split(',')
            figures['panel']=[int(vals0[0]), int(vals0[1])]
        elif label == 'fig_kind': 
            if vals == 'None': figures['kind'] = png
            else: figures['kind'] = vals.replace(' ','')
        elif label == 'kind': kindn = vals.replace(' ','') + '@0'
        elif label == 'file': files = gen.str_list(vals.replace(' ',''),',')
        elif label == 'values': 
            Lvalues = len('values:')
            Lline = len(line)
            values = line[Lvalues:Lline - Lvalues + 1]
        elif label == 'variables': variables = gen.str_list(vals.replace(' ',''),',')
        else:
            print errormsg
            print '  ' + main + ": configuration label '" + label + "' not ready !!"
            quit(-1)

        if kindn is not None and kindn != kindnow and variables is not None:
            if kindnow is None: 
                kindnow = kindn.split('@')[0]
            else:
                kindnow = kindnow.split('@')[0]

            if dbg:
                print '    ' + main + ": adding in panel: '" + kindnow + "'... "
                print '      files:', files
                print '      values:', values
                print '      variables:', variables

            varns.append(':'.join(values))
            if Nfigs.has_key(kindnow):
                N = Nfigs[kindnow]
                Nfigs[kindnow] = N + 1
            else:
                Nfigs[kindnow] = 1

            labf = kindnow + '@' + str(Nfigs[kindnow])
            figns.append(labf)
            if dbg:
                print "    added as '" + labf + "'"

            figures[labf] = values_figure(files,values,variables)
                
            kindnow = kindn+'@-1'
            variables = None

oconf.close()

if dbg:
    print '  ' + main + " General figure configuration _______"
    for ff in fix_multiplot_conf:
        print '    ' + ff + ': ', figures[ff]

    for ff in figns:
        if not gen.searchInlist(fix_multiplot_conf,ff):
            print "    '" + ff + "' _______"
            gen.printing_class(figures[ff])

panelval = figures['panel']
if np.prod(panelval) != len(figns):
    print errormsg
    print '  ' + main + ': then number of plots=',len(figns),'not suits the panel=', \
      figures['panel']
    print '    figures to plot:',figns
    quit(-1)

#
## Plotting
#
plt.rc('text', usetex=True)

fig, axes = plt.subplots(panelval[0],panelval[1])

ifig = 1
for ff in figns:
    isubplot = gen.index_flatten_mat(ifig,list(panelval))
    isubplot = isubplot + 1
    if dbg:
        print '  ' + main + " adding in graph '" + ff + "' in ", isubplot, "..."
    graphinf = figures[ff]
    graphlab = ff.split('@')[0]
    plt.subplot(panelval[0],panelval[1],ifig)

    if graphlab == 'draw_2D_shad':
        Files = graphinf.files[0]
        Vals = graphinf.vals+':False'
        Vars = graphinf.vars[0]

        DrW.draw_2D_shad(Files,Vals,Vars)

    elif graphlab == 'direc_draw_2D_shad':
        Files = graphinf.files[0]
        if not os.path.isfile(Files):
            print errormsg
            print '  '+main+": netcdf file with data '" + Files + "' does not exist!!"
            quit(-1)

        Vals = graphinf.vals.split(':')

        ncf = NetCDFFile(Files,'r')
        ovar = ncf.variables[graphinf.vars[0]]

        dictslice = {}
        for dmn in Vals[1].split(','):
            dn = dmn.split('|')[0]
            dv = int(dmn.split('|')[1])
            dictslice[dn] = dv

        slicevar, slicedims = ncvar.SliceVarDict(ovar,dictslice)

        Vars = ovar[tuple(slicevar)]
        ncf.close()

        CFname = Vals[0].replace(' ','')
        dimxn = Vals[2]
        dimyn = Vals[3]
        colorbar = Vals[4]
        minv = np.float(Vals[5].split(',')[0])
        maxv = np.float(Vals[5].split(',')[1])
        titgraph = Vals[6].replace('|',' ')

        varvu = gen.variables_values(CFname)[5]
        dimxu = gen.variables_values(dimxn)[5]
        dimyu = gen.variables_values(dimyn)[5]

        # Plot itself
        plt.rc('text', usetex=True)
        plt.pcolormesh(Vars, cmap=plt.get_cmap(colorbar), vmin=minv, vmax=maxv)
        cbar = plt.colorbar()
        cbar.set_label(CFname + ' (' + drw.units_lunits(varvu) + ')')
        plt.title(titgraph)
        plt.xlabel(dimxn + ' (' + drw.units_lunits(dimxu) + ')')
        plt.ylabel(dimyn + ' (' + drw.units_lunits(dimyu) + ')')

    else:
        print errormsg
        print '  ' + main + ": kind of figure '" + graphlab + "' not ready !!"
    ifig = ifig+1

fig.suptitle(figures['title'].replace('!',' '))

figname = opts.oname + '.' + figures['kind']
sub.call('rm ' + figname + ' >& /dev/null', shell=True)
plt.savefig(figname)
print main + " succesfull drawing of figure '" + figname + "' !!"
if seefig:
    if figures['kind'] == 'pdf':
        sub.call('evince ' + figname + ' &', shell=True)
    else:
        sub.call('display ' + figname + ' &', shell=True)

