#!/usr/bin/python3
# -*- coding: utf-8 -*-

import sys
import utsusemi.SAS.ana.Reduction.TransBaseCommands as TBC
import Manyo as mm
import Manyo.SAS as ms

# reserved words for return value in this.
DAT = None
ecs = None
EC = None
ret = None
PyObj = None
Iq = None
Tr = None

#########################################
def TransmittanceCorrection(dat=DAT, params=PyObj, calcError=False, useAngDep=False):
    """
    Transmittance correction using the function which indicated by params.
    @param dat      (ElementContainerMatrix)
    @param params   (PyObject) Function parameters and their errors
    @param calcError    (bool) True: Calculate an error w/ errors of parameters.
                            False: Calculate it w/o errors of parameters.
    @param useAngDep (bool) True: use angle dependence of calculation for transmittance correction
    @retval None
    """
    fit_type=""
    if type(params[-1])==tuple:
        fit_type=params[0][-1]
    else:
        fit_type=params[-1]
    trans = ms.TransmittanceCorrection()
    if fit_type == trans.TRANSMIT_TYPE_EXP:
        TBC.TransmittanceCorrectionExp(dat, params, calcError, useAngDep)
    elif fit_type == trans.TRANSMIT_TYPE_POLY3:
        TBC.TransmittanceCorrectionPoly3(dat, params, calcError, useAngDep)
    elif fit_type == trans.TRANSMIT_TYPE_POLYAPPROX:
        TBC.TransmittanceCorrPolyApproximation(dat, params, calcError)
    else:
        raise UserWarning("Unknown fitting function {}".format(fit_type))

#########################################
def TransmittanceCorrectionExp(dat=DAT,params=PyObj,calcError=False):
    """
    Transmittance correction by an exponential function, which is p0*exp(-p1*lambda)+p2.
    @param dat      (ElementContainerMatrix)
    @param params   (PyObject) Function parameters and their errors
    @param calcError    (bool) True: Calculate an error w/ errors of parameters.
                            False: Calculate it w/o errors of parameters.
    """
    fit_type=""
    if type(params[-1])==list:
        fit_type=params[0][-1]
    else:
        fit_type=params[-1]
    if fit_type == "exp":
        TBC.TransmittanceCorrectionExp(dat,params,calcError)
    elif fit_type == "poly3":
        raise UserWarning("The choosed funtion dose not match.")
    else:
        raise UserWarning("Unknown fitting function")

#########################################
def TransmittanceCorrectionPoly3(dat=DAT,params=PyObj,calcError=False):
    """
    Transmittance correction by a degree 3 polynomial function, which is p0+p1*lamb+p2*lamb^2+p3*lamb^3.
    @param dat      (ElementContainerMatrix)
    @param params   (PyObject) Function parameters and their errors
    @param calcError    (bool) True: Calculate an error w/ errors of parameters.
                            False: Calculate it w/o errors of parameters.
    """
    fit_type=""
    if type(params[-1])==list:
        fit_type=params[0][-1]
    else:
        fit_type=params[-1]
    if fit_type == "exp":
        raise UserWarning("The choosed funtion dose not match.")
    elif fit_type == "poly3":
        TBC.TransmittanceCorrectionPoly3(dat,params,calcError)
    else:
        raise UserWarning("Unknown fitting function")

#########################################
def TransmittanceCorrectionPolyApprox(dat=DAT,params=PyObj,calcError=False):
    """
    Transmittance correction by a degree 3 polynomial function, which is p0+p1*lamb+p2*lamb^2+p3*lamb^3.
    @param dat      (ElementContainerMatrix)
    @param params   (PyObject) Function parameters and their errors
    @param calcError    (bool) True: Calculate an error w/ errors of parameters.
                            False: Calculate it w/o errors of parameters.
    """
    fit_type=""
    if type(params[-1])==list:
        fit_type=params[0][-1]
    else:
        fit_type=params[-1]
    trans = ms.TransmittanceCorrection()
    if fit_type == trans.TRANSMIT_TYPE_POLYAPPROX:
        TBC.TransmittanceCorrPolyApproximation(dat, params, calcError)
    elif fit_type == "exp" or fit_type == "poly3":
        raise UserWarning("The choosed funtion dose not match.")
    else:
        raise UserWarning("Unknown fitting function")

#########################################
def FitExponentialWoBase(dat=Tr,iniVals="1.0 0.01" ):
    """
    An exponential fitting. The fitting function is p0*exp(-p1*lambda).
    @params dat         (ElementContainer)
    @params iniVals     (str) initial parameters separated with space
    @retval PyObj
    """
    return TBC.FitExponentialWoBase(dat,iniVals,False)

#########################################
def FitExponential(dat=Tr,iniVals="1.0 0.01 0.0001" ):
    """
    An exponential fitting. The fitting function is p0*exp(-p1*lambda)+p2.
    @params dat         (ElementContainer)
    @params iniVals     (str) initial parameters separated with space
    @retval PyObj
    """
    return TBC.FitExponential(dat,iniVals,False)

#########################################
def FitPolynomial3(dat=Tr,iniVals="0.3 -0.05 0.004 -0.0001" ):
    """
    A degree 3 polynomial fitting. The fitting function is p0+p1*lamb+p2*lamb^2+p3*lamb^3.
    @params dat         (ElementContainer)
    @params iniVals     (str) initial parameters separated with space
    @retval PyObj
    """
    return TBC.FitPolynomial3(dat,iniVals, False)

#########################################
def FitPolyApproximation(dat=Tr, thick=1.0, iniVals="0.0001 0.0001 0.0001 0.0001", weighted=True):
    """
    An exponential fitting. The fitting function is
      exp(-(P1 + P2 * Lambda + P3 * Lambda^2 + P4 * Lambda^3) * T)
    @params dat         (ElementContainer) or list of ElementContainer
    @params thick       (float) thickness of sample [cm]
    @params iniVals     (str) initial parameters separated with space
    @params weighted    (bool) using weighted least squares
    @retval PyObj
    """
    return TBC.FitPolyApproximation(dat, thick, iniVals, weighted)

#########################################
def GetTransNormByMonCounts(SmplRunNo=104000, DrctRunNo=104000, AxType="lambda", XRange="0.7 7.6 0.1", frameBoundary=0.0, CalibEffi=True ):
    """
    Monitor histogram of sample and direct followed by a transmittance calculation.
    @param SmplRunNo     (int)    Sample measurement run number
    @param DrctRunNo     (int)    Direct beam measurement run number
    @param AxType        (string)  Type must be "tof', "lambda" or "lamda2"
    @param XRange        (string) "startX endX widthX" separated with space (not comma)
    @param frameBoundary (float)
    @param CalibEffi     (bool)    Monitor-detector efficiency calibration
    @retval Tr
    """
    return TBC.GetTransNormByMonCounts(SmplRunNo, DrctRunNo, AxType, XRange, frameBoundary, CalibEffi)

#########################################
def GetTransNormByMonCountsTS(SmplRunNo=104000, DrctRunNo=104000, AxType="lambda", XRange="0.7 7.6 0.1", frameBoundary=0.0, CalibEffi=True, SmplTSlice="-1 -1", DrctTSlice="-1 -1"):
    """
    Monitor histogram of sample and direct followed by a transmittance calculation.
    @param SmplRunNo     (int)    Sample measurement run number
    @param DrctRunNo     (int)    Direct beam measurement run number
    @param AxType        (string)  Type must be "tof', "lambda" or "lamda2"
    @param XRange        (string) "startX endX widthX" separated with space (not comma)
    @param frameBoundary (float)
    @param CalibEffi     (bool)    Monitor-detector efficiency calibration
    @param SmplTSlice    (string) Time Slice parameters for Sample run
    @param DrctTSlice    (string) Time Slice parameters for Directrun
    @retval Tr
    """
    return TBC.GetTransNormByMonCountsTS(SmplRunNo, DrctRunNo, AxType, XRange, frameBoundary, CalibEffi, SmplTSlice, DrctTSlice )

#########################################
def GetTransNormByMon(SmplRunNo=104000, DrctRunNo=104000, Xrange="0.7 7.6 0.1 dL", frameBoundary="0.0", CalibEffi=True, useMon="MON1" ):
    """
    Monitor histogram of sample and direct followed by a transmittance calculation.
    @param SmplRunNo     (int)    Sample measurement run number
    @param DrctRunNo     (int)    Direct beam measurement run number
    @param Xrange        (string)  "startX endX widthX type" separated with space (not comma) : type=[dL, dL/L, tof]
    @param frameBoundary (float)
    @param CalibEffi     (bool)    Monitor-detector efficiency calibration
    @param useMon        (strng)  Upstream Monitor (MON1 or MON3)
    @retval Tr
    """
    return TBC.GetTransNormByMon(SmplRunNo, DrctRunNo, Xrange, frameBoundary, CalibEffi, useMon )

#########################################
def GetTransNormByMonTS(SmplRunNo=104000, DrctRunNo=104000, Xrange="0.7 7.6 0.1 dL", frameBoundary="0.0", CalibEffi=True, SmplTSlice="-1 -1", DrctTSlice="-1 -1", useMon="MON1", paramFiles="- -"):
    """
    Monitor histogram of sample and direct followed by a transmittance calculation.
    @param SmplRunNo     (int)    Sample measurement run number
    @param DrctRunNo     (int)    Direct beam measurement run number
    @param Xrange        (string)  "startX endX widthX type" separated with space (not comma) : type=[dL, dL/L, tof]
    @param frameBoundary (float)
    @param CalibEffi     (bool)    Monitor-detector efficiency calibration
    @param SmplTSlice    (string) Time Slice parameters for Sample run
    @param DrctTSlice    (string) Time Slice parameters for Directrun
    @param useMon        (strng)  Upstream Monitor (MON1 or MON3)
    @param paramFiles    (string) "<wiringInfo> <detectorInfo>[ <caseInfo>]
    @retval Tr
    """
    return TBC.GetTransNormByMonTS(SmplRunNo, DrctRunNo, Xrange, frameBoundary, CalibEffi, SmplTSlice, DrctTSlice, useMon, paramFiles)

#########################################
def GetCalcTransmittance(dat=Tr):
    """
    Get trnasmittance data using a fitting result
    @param dat      (ElementContainer) Observed transmittance which was used by fitting facades
    @retval Tr_calc
    """
    return TBC.GetCalcTransmittance(dat)

#########################################
def CreateCoefficientSet(coeff="1.0 0.01 0.0001", err="0.1 0.001 0.00001", funcType="exp"):
    """
    Create a coefficient set
    @param coeff    (str) coefficient separated with space
    @param err      (str) error separated with space
    @param funcType (str) function type. "exp" or "poly3"
    @retval PyObj
    """
    return TBC.CreateCoefficientSet(coeff, err, funcType)

########################################
def SetCoeffToTransmittance(dat=Tr, params=PyObj):
    """
    Set a coefficient set to transmittance data container.
    @param dat      (ElementContainer) Observed transmittance
    @param params   (PyObj) Coefficient set
    @retval None
    """
    TBC.SetCoeffToTransmittance(dat, params)

########################################
def GetTransRPMTNormByMon(SmplRunNo=104000, DrctRunNo=104000, PixelRange="134 131 158 155", AxType="lambda", XRange="0.7 7.6 0.1", frameBoundary=0.0, CalibEffi=True ):
    """
    Monitor histogram of sample and direct followed by a transmittance calculation.
    @param SmplRunNo     (int)    Sample measurement run number
    @param DrctRunNo     (int)    Direct beam measurement run number
    @param PixelRange    (string) "x0 y0 x1 y1"
    @param AxType        (string)  Type must be "tof', "lambda" or "lamda2"
    @param XRange        (string) "startX endX widthX" separated with space (not comma)
    @param frameBoundary (float)
    @param CalibEffi     (bool)    Monitor-detector efficiency calibration
    @retval Tr
    """
    return TBC.GetTransRPMTNormByMon(SmplRunNo, DrctRunNo, PixelRange, AxType, XRange, frameBoundary, CalibEffi )

# Dictionary for entry the name of functions
_functions = {
            "TransmittanceCorrection":TransmittanceCorrection,
            "TransmittanceCorrectionExp":TransmittanceCorrectionExp,
            "TransmittanceCorrectionPoly3":TransmittanceCorrectionPoly3,
            "TransmittanceCorrectionPolyApprox":TransmittanceCorrectionPolyApprox,
            "FitPolyApproximation":FitPolyApproximation,
            "FitExponentialWoBase":FitExponentialWoBase,
            "FitExponential":FitExponential,
            "FitPolynomial3":FitPolynomial3,
            "GetTransNormByMonCounts":GetTransNormByMonCounts,
            "GetTransNormByMonCountsTS":GetTransNormByMonCountsTS,
            "GetTransNormByMon":GetTransNormByMon,
            "GetTransNormByMonTS":GetTransNormByMonTS,
            "GetTransRPMTNormByMon":GetTransRPMTNormByMon,
            "GetCalcTransmittance":GetCalcTransmittance,
            "CreateCoefficientSet":CreateCoefficientSet,
            "SetCoeffToTransmittance":SetCoeffToTransmittance
            }
