#!/usr/bin/env python

#
#  Copyright (C) 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2023
#                Smithsonian Astrophysical Observatory
#
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License along
#  with this program; if not, write to the Free Software Foundation, Inc.,
#  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#

"""
Script:
  deflare

  Choose lc_clean or lc_sigma_clip
  to filter light curves.

  This script is run from the Unix command line, within the CIAO environment.

Example syntax:
unix% ciao
ciao% deflare clean lc.fits gti.fits
ciao% deflare method=clean infile=lc.fits outfile=gti.fits

"""

import os
import sys

import matplotlib
if 'DISPLAY' in os.environ and os.environ['DISPLAY'] != "":
    matplotlib.interactive(True)
else:
    matplotlib.use('Agg')

import paramio

from lightcurves import lc_clean, lc_sigma_clip, lc_sigma_uclip

from ciao_contrib.logger_wrapper import initialize_logger, \
    make_verbose_level, set_verbosity, handle_ciao_errors
from ciao_contrib.param_wrapper import open_param_file


toolname = "deflare"
__revision__ = "28 March 2023"

initialize_logger(toolname)

v1 = make_verbose_level(toolname, 1)


def get_par(args):
    """Get parameters from parameter file """

    pinfo = open_param_file(args, toolname=toolname)
    pfile = pinfo["fp"]

    # Common parameters:
    params = {}

    params["infile"] = paramio.pgetstr(pfile, "infile")
    params["outfile"] = paramio.pgetstr(pfile, "outfile")
    params["method"] = paramio.pgetstr(pfile, "method")
    params["nsigma"] = paramio.pgetd(pfile, "nsigma")
    plot_stat = params["plot"] = paramio.pgetb(pfile, "plot") == 1
    params["save"] = paramio.pgetstr(pfile, "save")
    params["rateaxis"] = paramio.pgetstr(pfile, "rateaxis")
    params["pattern"] = paramio.pgetstr(pfile, "pattern")
    params["good_color"] = paramio.pgetstr(pfile, "good_color")
    params["exclude_color"] = paramio.pgetstr(pfile, "exclude_color")
    params["verbose"] = paramio.pgeti(pfile, "verbose")

    if params["save"].strip() == "":
        params["save"] = None

    # # Assume that if the user has selected save then they must also
    # # want a plot, even if plot is False.
    #
    if not params["plot"] and params["save"] is not None:
        params["plot"] = True

    if params["outfile"] == "" or params["outfile"].lower() == 'none':
        params["outfile"] = None

    # Convert from tool verbose range 0 to 5 to that used by the
    # routines
    verbose = params['verbose']
    if verbose > 0:
        params["verbose"] = verbose if verbose <= 5 else 5

    if params["method"] in ['sigma', 'usigma']:
        # lc_sigma_clip/uclip parameters:
        params["minlength"] = paramio.pgetd(pfile, "minlength")

    elif params["method"] == 'clean':
        # lc_clean parameters:
        params["mean"] = paramio.pgetd(pfile, "mean")
        params["stddev"] = paramio.pgetd(pfile, "stddev")
        params["scale"] = paramio.pgetd(pfile, "scale")
        params["minfrac"] = paramio.pgetd(pfile, "minfrac")

    else:
        # The parameter interface enforces this restriction
        # so this is not really needed
        raise ValueError("Invalid method parameter: expected clean,sigma,usigma sent '{0}'".format(params["method"]))

    paramio.paramclose(pfile)
    return params, plot_stat


def pause():
    input("Press ENTER to close the plot window and exit:")


def wrapup(params, plot_stat):
    "Let the user know what has happened."
    from ciao_contrib.runtool import add_tool_history
    add_tool_history(params["outfile"], toolname, params,
                     toolversion=__revision__)

    labels = {"clean": "lc_clean", "sigma": "lc_sigma_clip",
              "usigma": "lc_sigma_uclip"}
    label = labels[params["method"]]

    v1("Light curve cleaned using the {0} routine.".format(label))

    if params["save"] is not None:
        import matplotlib.pyplot as plt

        oplot = params["save"]

        if oplot.lower().endswith(".pdf"):
            format = "pdf"
        elif oplot.lower().endswith(".ps"):
            format = "ps"
        elif oplot.lower().endswith(".eps"):
            format = "eps"
        elif oplot.lower().endswith(".png"):
            format = "png"
        elif oplot.lower().endswith(".svg"):
            format = "svg"
        else:
            oplot += ".pdf"
            format = "pdf"

        plt.savefig(oplot, format=format)

        v1("Created: {0}".format(oplot))

    if plot_stat:
        pause()


# Note that at present (July 2014) the uclip version isn't
# selectable since the parameter file does not support it.
#
@handle_ciao_errors(toolname, __revision__)
def deflare(arglist):
    "Do the work"

    params, plot_stat = get_par(arglist)
    set_verbosity(params["verbose"])

    # Set up the common arguments
    #
    args = [params["infile"]]
    kwargs = {"outfile": params["outfile"],
              "plot": params["plot"],
              "rateaxis": params["rateaxis"],
              "pattern": params["pattern"],
              "gcol": params["good_color"],
              "pcol": params["exclude_color"],
              "verbose": params["verbose"]}

    if params["method"] == 'clean':

        if params["stddev"] > 0.0:
            sigmac = params["stddev"]
        else:
            sigmac = None

        if params["mean"] > 0.0:
            meanc = params["mean"]
            v1("Warning: the mean value should be set very carefully (approx. the mean count-rate of the input light curve).")
        else:
            meanc = None

        kwargs["mean"] = meanc
        kwargs["sigma"] = sigmac
        kwargs["clip"] = params["nsigma"]
        kwargs["scale"] = params["scale"]
        kwargs["minfrac"] = params["minfrac"]
        func = lc_clean

    else:
        kwargs["sigma"] = params["nsigma"]
        kwargs["minlength"] = params["minlength"]
        if params['method'] == "usigma":
            func = lc_sigma_uclip
        else:
            func = lc_sigma_clip

    # if plot_stat:
    #     matplotlib.use("TkAgg")
    #     matplotlib.interactive(True)

    # else:
    #     matplotlib.use("PS")
    #     matplotlib.interactive(True)

    func(*args, **kwargs)
    wrapup(params, plot_stat)


if __name__ == "__main__":
    deflare(sys.argv)

# End
