# 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__ = ['ManualParams', 'ManualParamsDialog']

# *****************************************************************************
class ManualParams(ParamsCollection):
    """Generic algorithm parameters for the manual version of aerosol profile
    retrieval algorithm.

    Attributes:
      - 'weighting355', 'weighting532', 'weighting1064', 'weighting532C':
        weighting coefficients for lidar signals.
      - 'weightingFine', 'weightingSpherical', 'weightingSpheroid',
        'weightingCoarse': weighting coefficients for aerosol fraction
        concentrations retrieved with Sun photometer.
      - 'weightSmoothFine', 'weightSmoothSpherical', 'weightSmoothSpheroid',
        'weightSmoothCoarse': weighting coefficients for aerosol profile
        smoothness terms.

      - 'molDepolarization532': depolarization ratio of the molecular
        atmosphere (currently, single value is used for all the wavelenghts).
      - 'parallelLeakage532': portion of the parallel-polarized lidar signal
        that actually penetrates the cross-polarized receiver channel.

      - 'tolFun': 'Function tolerance' criterion to be used by the Matlab's
        optimization function (maximum value of the function change between
        successive iterations, or alternatively maximum value of its first
        derivative, that should trigger termination of the optimization
        process).
      - 'tolX': 'Parameter tolerance' criterion to be used by the Matlab's
        optimization function (maximum value of the parameters change between
        successive iterations that should trigger termination of the
        optimization process).

      - 'photometerDisplacement': altitude of the photometer station relative
        to the lidar measurement point (positive value means that photometer is
        above the lidar). This value should normally be zero. It might be
        calculated based on the values stored in "aeronet locations" data file
        and in the lidar databases, but is instead placed here, to make it more
        explicit and hence avoid confusion."""

    # ---- Class attributes ---------------------------------------------------
    parameterList = [

        # ---- Weighting coefficients ----
        ParameterHeader('Weighting_coefficients', 'Lidar signals:'),
        ParameterInfo('Weighting_coefficients', 'k<sub>355</sub> =',
            'weighting355', float, 2.5e-6, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', 'k<sub>532</sub> =',
            'weighting532', float, 5e-6, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', 'k<sub>1064</sub> =',
            'weighting1064', float, 2.5e-6, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', u'k<sub>532,\u22a5</sub> =',
            'weighting532C', float, 7.5e-6, minValue = 0.0),

        ParameterHeader('Weighting_coefficients', 'Total concentrations:'),
        ParameterInfo('Weighting_coefficients', 'f<sub>fine</sub> =',
            'weightingFine', float, 0.2, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', 'f<sub>spherical</sub> =',
            'weightingSpherical', float, 0.2, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', 'f<sub>spheroid</sub> =',
            'weightingSpheroid', float, 0.2, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', 'f<sub>coarse</sub> =',
            'weightingCoarse', float, 0.2, minValue = 0.0),

        ParameterHeader('Weighting_coefficients',
            'Concentration smoothnesses:'),
        ParameterInfo('Weighting_coefficients', 'd<sub>fine</sub> =',
            'weightSmoothFine', float, 1.0, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', 'd<sub>spherical</sub> =',
            'weightSmoothSpherical', float, 1.0, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', 'd<sub>spheroid</sub> =',
            'weightSmoothSpheroid', float, 1.0, minValue = 0.0),
        ParameterInfo('Weighting_coefficients', 'd<sub>coarse</sub> =',
            'weightSmoothCoarse', float, 1.0, minValue = 0.0),

        # ---- Polarization parameters ----
        ParameterHeader('Polarization_parameters',
            'Molecular depolarization:'),
        ParameterInfo('Polarization_parameters', u'\u03c7<sub>532</sub> =',
            'molDepolarization532', float, 0.014, minValue = 0.0),
        ParameterHeader('Polarization_parameters', 'Parallel leakage:'),
        ParameterInfo('Polarization_parameters', u'\u03bc<sub>532</sub> =',
            'parallelLeakage532', 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),

        ParameterHeader('Photometer_parameters', 'Altitude displacement (m):'),
        ParameterInfo('Photometer_parameters', u'\u0394h<sub>photo</sub> =',
            'photometerDisplacement', float, 0.0),
    ]

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

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

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

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

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

            ParameterGroupInfo('Polarization_parameters',
                '&Polarization parameters', True),
            ParameterGroupInfo('Optimization_options',
                '&Optimization options'),
            ParameterGroupInfo('Photometer_parameters',
                'P&hotometer parameters'),
        ]

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