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

import utsusemi.SAS.ana.Reduction.QSpaceBaseCommands as QBC

# special reserved word for commands history
HISTORY = None

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

########################################
def ConvertQSpace( dat=DAT, InVec="0.0 0.0 1.0" ):
    """
    Convert Data to Q space EventData to produce histogram
    ConvertQSpace(dat=DAT, InVec="0.0 0.0 1.0")

    @param  dat    (ElementContainerMatrix)
    @param  InVec  (string) vector of the incident beam
    @retval None
    """
    QBC.ConvertQSpace( dat, InVec )

########################################
def ConvertQSpaceRPMTCenterShift(dat=DAT, DET=151, PIX=151):
    """
    Convert Data to Qspace on RPMT using shifted center position.
    The center position is at center point of the pixel given by DET and PIX.
    If DET or PIX is minus, for example -1, then this function calculates with the original position.

    ConvertQSpaceRPMTCenterShift(dat, DET, PIX)

    @param dat (ElementContainerMatrix) Target Data
    @param DET (int) Detect ID, or minus value (-1) to use original position
    @param PIX (int) Pixel No, or minus value (-1) to use original position
    @retval None
    """
    QBC.ConvertQSpaceRPMTCenterShift(dat, DET, PIX)

########################################
def ConvertQSpaceWithGravity( dat=DAT, params="default" ):
    """
    Convert Data to Q space EventData to produce histogram with gravity effect
    ConvertQSpaceWithGravity(dat=DAT, params="0.0")
    py = a+b*(lambda)^2

    params = "default" <- default : Using DetectorInfo/sas/rpmt parameters
    params = "150.093 -0.14218 136.9" <- a, b, px
    params = "0.1562 1.0 208.5 188.35" <- b, lambda, px, py@lambda

    @param  dat    (ElementContainerMatrix)
    @param  params (string) "default" or "<a> <b> <px>" or "<b> <lambda> <px> <py>"
    @retval None
    """
    QBC.ConvertQSpaceWithGravity( dat, params )

########################################
def QzProjection( dat=DAT, QxRange="-1.0 1.0 0.005", QyRange="-1.0 1.0 0.005", QzRange="-0.5 0.0", LambdaRange="0.7 7.6", Bank="All" ):
    """
    Makes Qx-Qy map data integrated in a Qz range.
    QzProjection( dat=DAT, QxRange="-1.0 1.0 0.005", QyRange="-1.0 1.0 0.005", QzRange="-0.5 0.0" )

    @param  dat   (ElementContainerMatrix) Data after ConvertToQSpace
    @param  QxRange   (string)  "Qx_min Qx_max Qx_bin"
    @param  QyRange   (string)  "Qy_min Qy_max Qy_bin"
    @param  QzRange   (string)  "Qz_max Qz_bin"
    @param LambdaRange(string)  "Lambda_min, Lambda_max"
    @param  Bank      (string)  "All" or "<BankName> <BankName> ..."
    @retval ECA   (ElementContainerArray)
    """
    return QBC.QzProjection( dat, QxRange, QyRange, QzRange, LambdaRange, Bank )

########################################
def SectorAverageByAngles( dat=DAT, Banks="SM16-SM14-SD-SU", Qrange="0.01 2.0 0.001 dQ/Q", LamRange="0.7 0.8", AzimAng="0.0 0.0", PolAng="0.0 0.0", QLamFile="None/QLambdaRange" ):
    """
    Convert Data to Q space EventData to produce histogram
    SectorAverageByAngles( dat=DAT, Banks="SM16-SM14-SD-SU", Qrange="0.01 2.0 0.001 dq/Q", LamRange="0.7 0.8", AzimAng="0.0 0.0", PolAng="0.0 0.0" )

    @param  dat  (ElementContainerMatrix)
    @param  Banks    (string)  "SM16-SD-SU" means these banks are unified in one Iq, "SM SD SU" means separated Iq
    @param  Qrange   (string)  Q range and type of Qbin "Qmin Qmax deltaQ type" type must be dQ/Q or dQ
    @param  LamRange (string)  Lambda range "Lambda_min Lambda_max"
    @param  AzimAng  (string)  "-20.0 20 170 -170"
    @param  PolAng   (string)  "0 90 0 40"
    @param  QLamFile (string)  filename of Q-Lambda range info. If None, no use. (read QLambdaRange_SM.txt for SM bank)
    @retval Iq       (list of ElementContainer)
    """
    return QBC.SectorAverageByAngles( dat, Banks, Qrange, LamRange, AzimAng, PolAng, QLamFile )

########################################
def MakeRegionOfSectAve( dat=DAT, Bank="SM", Qrange="0.01 2.0 0.001 dQ/Q", LamRange="0.7 7.6 0.1", AzimAng="0.0 0.0", PolAng="0.0 0.0", ErrTh="-1.0 e", OutFile="QLambdaRange", TwoThetaRange="0.0-180.0" ):
    """
    Makes Lamda slice SectorAverage
    MakeRegionOfSectAve( dat=DAT, Bank="SM", Qrange="0.01 2.0 0.001 dQ/Q", LamRange="0.7 7.6 0.1", AzimAng="0.0 0.0", PolAng="0.0 0.0", ErrTh=1.0, OutFile="QLambdaRange" )

    @param  dat  (ElementContainerMatrix)
    @param  Bank     (string)  Target bank. Only one bank can be accepted.
    @param  Qrange   (string)  Q range and type of Qbin "Qmin Qmax deltaQ type" type must be dQ/Q or dQ
    @param  LamRange (string)  Lambda range "Lambda_min Lambda_max"
    @param  AzimAng  (string)  "-20.0 20 170 -170"
    @param  PolAng   (string)  "0 90 0 40"
    @param  ErrTh    (string)   "sh type" sh : threshold of error bar to decide useless region (ErrTh<=0.0 means no decision), type="e" or "ie"
    @param  OutFile  (string)  output file name for Q-Lambda range for target bunk (filename = QLambdaRange_SM.xml)
    @param  TwoThetaRange (string)
    @retval IQLam    (ElementContainerArray)
    """
    return QBC.MakeRegionOfSectAve( dat, Bank, Qrange, LamRange, AzimAng, PolAng, ErrTh, OutFile, TwoThetaRange )

########################################
def GetAzimuthProfile(dat=DAT, Qcenter=0.036, dQ=0.002, azim_bin=1.0, azim_range="0.0 360.0", lambda_range="0 0"):
    """
    Calculates Azimuth Profile from DataReduction

    @param dat          (ElementContainerMatrix)
    @param Qcenter      (float)
    @param dQ           (float)
    @param azim_bin     (float)
    @param azim_range   (string)
    @param lambda_range (string)
    @retval Iap
    """
    return QBC.GetAzimuthProfile(dat, Qcenter, dQ, azim_bin, azim_range, lambda_range)

########################################
def GetAzimuthProfileMulti(dat_list=DATList, Qcenter=0.036, dQ=0.002, azim_bin=1.0, azim_range="0.0 360.0", lambda_range="0 0"):
    """
    Calculates Azimuth Profile from DataReduction

    @param dat_list     (list)
    @param Qcenter      (float)
    @param dQ           (float)
    @param azim_bin     (float)
    @param azim_range   (string)
    @param lambda_range (string)
    @retval IapList
    """
    return QBC.GetAzimuthProfileMulti(dat_list, Qcenter, dQ, azim_bin, azim_range, lambda_range)

# Dictionary for entry the name of functions
_functions = {
            "ConvertQSpace":ConvertQSpace,
            "ConvertQSpaceRPMTCenterShift":ConvertQSpaceRPMTCenterShift,
            "ConvertQSpaceWithGravity":ConvertQSpaceWithGravity,
            "QzProjection":QzProjection,
            "SectorAverageByAngles":SectorAverageByAngles,
            "MakeRegionOfSectAve":MakeRegionOfSectAve,
            "GetAzimuthProfile":GetAzimuthProfile,
            "GetAzimuthProfileMulti":GetAzimuthProfileMulti,
            }

_functionsOrder = [
    "ConvertQSpace",
    "ConvertQSpaceWithGravity",
    "ConvertQSpaceRPMTCenterShift",
    "QzProjection",
    "SectorAverageByAngles",
    "MakeRegionOfSectAve",
    "GetAzimuthProfile",
    "GetAzimuthProfileMulti"
]
