# Copyright (c) 2011-2014, B.I.Stepanov Institute of Physics, National Academy
# of Sciences of Belarus.
#
# 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 2 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.

from PyQt4.QtCore import *
from PyQt4.QtGui import *

from common.ParamsCollection import *
from common.ParamsDialog import *

__all__ = ['RamanParams', 'RamanParamsDialog']

# *****************************************************************************
class RamanParams(ParamsCollection):
    """Parameters for aerosol backscatter and lidar ratio retrieval algorithm
    utilizing Raman lidar signals."""

    # ---- Class attributes ---------------------------------------------------
    parameterList = [
        # ---- Weighting coefficients ----
        ParameterHeader('Weighting_coefficients', 'Lidar signals:'),
        ParameterInfo('Weighting_coefficients', 'k<sub>355</sub> =',
            'weighting355', float, 5e-6, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', 'k<sub>387</sub> =',
            'weighting387',float, 5e-6, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', 'k<sub>532</sub> =',
            'weighting532', float, 5e-6, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', 'k<sub>607</sub> =',
            'weighting607', float, 5e-6, minValue = 0.0),

        ParameterHeader('Weighting_coefficients',
            'Backscatter ratio smoothness:'),
        ParameterInfo('Weighting_coefficients', u'd2<sub>\u03b8, 355</sub> =',
            'weightSmoothBackscatter355', float, 1.0, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', u'd2<sub>\u03b8, 532</sub> =',
            'weightSmoothBackscatter532', float, 1.0, minValue = 0.0),

        ParameterHeader('Weighting_coefficients', 'Lidar ratio smoothness:'),
        ParameterInfo('Weighting_coefficients', u'd1<sub>\u03b3, 355</sub> =',
            'weightSmoothLidar355', float, 1.0, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', u'd1<sub>\u03b3, 532</sub> =',
            'weightSmoothLidar532', float, 1.0, minValue = 0.0),

        ParameterHeader('Weighting_coefficients', 'Lidar ratio deviation:'),
        ParameterInfo('Weighting_coefficients', u'd0<sub>\u03b3, 355</sub> =',
            'weightDeviateLidar355', float, 1.0, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', u'd0<sub>\u03b3, 532</sub> =',
            'weightDeviateLidar532', float, 1.0, minValue = 0.0),

        # ---- Raman parameters ----
        ParameterHeader('Raman_parameters', 'Raman attenuation ratios:'),
        ParameterInfo('Raman_parameters', u'\u03b7<sub>387/355</sub> =',
            'attenuationRatio355', float, 1.0, minValue = 0.0),
        ParameterInfo('Raman_parameters', u'\u03b7<sub>607/532</sub> =',
            'attenuationRatio532', float, 1.0, minValue = 0.0),

        # ---- Polarization parameters ----
        ParameterHeader('Polarization_parameters',
            'Molecular depolarization:'),
        ParameterInfo('Polarization_parameters', u'\u03c7 =',
            'molDepolarization', float, 0.014, minValue = 0.0),

        # ---- Reference point parameters -----
        ParameterHeader('Reference_point_parameters',
            'Lidar correction coefficients:'),
        ParameterInfo('Reference_point_parameters', 'R<sub>1</sub> =',
            'ratioSource', float, 1.0, minValue = 0.0),
        ParameterInfo('Reference_point_parameters', 'q<sub>2</sub> =',
            'ratioRaman', float, 1.0, minValue = 0.0),
        ParameterHeader('Reference_point_parameters',
            'Correction limits:'),
        ParameterInfo('Reference_point_parameters', u'\u03b1<sub>1</sub> =',
            'ratioSourceLimit', float, 0.1, minValue = 0.0),
        ParameterInfo('Reference_point_parameters', u'\u03b1<sub>2</sub> =',
            'ratioRamanLimit', float, 0.1, minValue = 0.0),

        # ---- Optimization options ----
        ParameterHeader('Optimization_options', 'Function tolerance:'),
        ParameterInfo('Optimization_options', 'Tol<sub>Fun</sub> =',
            'tolFun', float, 1.0e-7, minValue = 0.0),
        ParameterHeader('Optimization_options', 'Parameter tolerance:'),
        ParameterInfo('Optimization_options', 'Tol<sub>X</sub> =',
            'tolX', float, 1.0e-7, minValue = 0.0)
    ]

    # ---- Public overridden methods ------------------------------------------
    @classmethod
    def getParameterList(cls):
        return cls.parameterList

    @classmethod
    def getSettingsFilePath(cls):
        return 'settings/RamanParams.ini'

# *****************************************************************************
class RamanParamsDialog(ParamsDialog):
    """Dialog for interactive modification of a 'RamanParams' instance."""

    # ---- Private overridden methods -----------------------------------------
    @classmethod
    def getGroupInfoList(cls):

        return [
            ParameterGroupInfo('Weighting_coefficients',
                '&Weighting coefficients'),

            ParameterGroupInfo('Raman_parameters',
                '&Raman parameters', True),
            ParameterGroupInfo('Polarization_parameters',
                '&Polarization parameters'),
            ParameterGroupInfo('Reference_point_parameters',
                'R&eference point parameters'),
            ParameterGroupInfo('Optimization_options',
                '&Optimization options')
        ]

    @classmethod
    def getWindowTitle(cls):
        return 'Raman retrieval parameters'
