# 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__ = ['PolarParams', 'PolarParamsDialog']

# *****************************************************************************
class PolarParams(ParamsCollection):
    """Parameters for aerosol backscatter and depolarization retrieval
    algorithm utilizing polarized lidar signals."""

    # ---- Class attributes ---------------------------------------------------
    parameterList = [
        # ---- Weighting coefficients ----
        ParameterHeader('Weighting_coefficients', 'Lidar signals:'),
        ParameterInfo('Weighting_coefficients', 'k<sub>0</sub> =',
            'weighting0', float, 5e-6, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', 'k<sub>3</sub> =',
            'weighting3',float, 5e-6, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', 'k<sub>2,0</sub> =',
            'weighting20', float, 5e-6, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', 'k<sub>2,3</sub> =',
            'weighting23', float, 5e-6, minValue = 0.0),

        ParameterHeader('Weighting_coefficients', 'Backscatter smoothness:'),
        ParameterInfo('Weighting_coefficients', u'\u03bd<sub>2</sub> =',
            'weightSmooth2', float, 1.0, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', u'\u03bd<sub>d</sub> =',
            'weightSmooth3', float, 1.0, minValue = 0.0),

        # ---- Calibration coefficients -----
        ParameterHeader('Cross_channel_calibration',
            'Initial approximations:'),
        ParameterInfo('Cross_channel_calibration', 'Q<sub>0</sub> =',
            'lidarCalibration0', float, 1.0, minValue = 0.0,
            isMinStrict = True),
        ParameterInfo('Cross_channel_calibration', 'Q<sub>3</sub> =',
            'lidarCalibration3', float, 1.0, minValue = 0.0,
            isMinStrict = True),
        ParameterHeader('Cross_channel_calibration',
            'Calibration tolerances:'),
        ParameterInfo('Cross_channel_calibration', 'g<sub>0</sub> =',
            'calibrationTolerance0', float, 0.1, minValue = 0.0),
        ParameterInfo('Cross_channel_calibration', 'g<sub>3</sub> =',
            'calibrationTolerance3', float, 0.1, minValue = 0.0),

        # ---- Aerosol parameters ----
        ParameterHeader('Aerosol_parameters', 'Initial backscatter ratios:'),
        ParameterInfo('Aerosol_parameters', 'R<sub>0</sub> =',
            'aerBackscatterRatioRef0', float, 1.1, minValue = 1.0,
            isMinStrict = True),
        ParameterInfo('Aerosol_parameters', 'R<sub>3</sub> =',
            'aerBackscatterRatioRef3', float, 1.1, minValue = 1.0,
            isMinStrict = True),
        ParameterHeader('Aerosol_parameters', 'Backscatter ratio tolerances:'),
        ParameterInfo('Aerosol_parameters', 'v<sub>0</sub> =',
            'aerBackscatterTolerance0', float, 0.1, minValue = 0.0),
        ParameterInfo('Aerosol_parameters', 'v<sub>3</sub> =',
            'aerBackscatterTolerance3', float, 0.1, minValue = 0.0),
        ParameterHeader('Aerosol_parameters', 'Lidar ratio:'),
        ParameterInfo('Aerosol_parameters', u'\u03b3<sub>a</sub> =',
            'lidarRatio', float, 50.0, minValue = 0.0),

        # ---- Polarization parameters ----
        ParameterHeader('Polarization_parameters',
            'Molecular depolarization:'),
        ParameterInfo('Polarization_parameters', u'\u03c7 =',
            'molDepolarization', float, 0.014, minValue = 0.0),
        ParameterHeader('Polarization_parameters', 'Parallel leakage:'),
        ParameterInfo('Polarization_parameters', u'\u03bc =',
            'parallelLeakage', float, 0.0, 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/PolarParams.ini'

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

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

        return [
            ParameterGroupInfo('Weighting_coefficients',
                '&Weighting coefficients'),
            ParameterGroupInfo('Aerosol_parameters',
                '&Aerosol parameters'),

            ParameterGroupInfo('Cross_channel_calibration',
                '&Cross channel calibration', True),
            ParameterGroupInfo('Polarization_parameters',
                '&Polarization parameters'),
            ParameterGroupInfo('Optimization_options',
                '&Optimization options')
        ]

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