#!/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

SASBankDic={"SD":0,"SU":1,"SM16":2,"SM14":3,"SC":4,"MD":5,"MU":6,"ML":7,"MR":8,"HD":9,"HU":10,"HL":11,"BW":13}
########################################
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 ConvertQSpaceWithGravity( dat=DAT, params="188.19 0.1562 208.5" ):
    """
    Convert Data to Q space EventData to produce histogram with gravity effect
    ConvertQSpaceWithGravity(dat=DAT, params="188.19 0.1562 208.5")
    py = a+b*(lambda)^2
    
    params = "188.19 0.1562 208.5" <- a, b, px
    params = "0.1562 1.0 208.5 188.35" <- b, lambda, px, py@lambda
    
    @param  dat    (ElementContainerMatrix)
    @param  params (string) "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" ):
    """
    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"
    @retval ECA   (ElementContainerArray)
    """
    return QBC.QzProjection( dat, QxRange, QyRange, QzRange, LambdaRange )

########################################
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" ):
    """
    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)
    @retval IQLam    (ElementContainerArray)
    """
    return QBC.MakeRegionOfSectAve( dat, Bank, Qrange, LamRange, AzimAng, PolAng, ErrTh, OutFile )

########################################
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,
            "ConvertQSpaceWithGravity":ConvertQSpaceWithGravity,
            "QzProjection":QzProjection,
            "SectorAverageByAngles":SectorAverageByAngles,
            "MakeRegionOfSectAve":MakeRegionOfSectAve,
            "GetAzimuthProfile":GetAzimuthProfile,
            "GetAzimuthProfileMulti":GetAzimuthProfileMulti,
            }

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