# -*- coding: utf-8 -*-

"""
ElementContainerArrayの中のContainerごとの総和（積分ではない）
ElementContainerMatrix中のArrayを指定して取り出し、
そのArray中の各ContainerのKyeY成分の和を計算し
そのContainerのindexをKeyX、総和をKeyYとする
新しいElementContainerを作り出す。
"""
from __future__ import print_function
import Manyo as mm
import math

##############################


class PutSum(object):
    ##############################
    def __init__(self, dat=None):
        """
        コンストラクタ

        @param  dat(ElementContainerMatrix)
        """
        if dat is not None:
            # if type(dat)!=type(mm.ElementContainerMatrix()):
            if not isinstance(dat, mm.ElementContainerMatrix):
                return
        self.KeyY = "Intensity"
        self.dat = dat

    ##############################
    def PutSumEC(self, psd, tmin=0.0, tmax=39500.0):
        """
        KeyYの和を算出
        与えられたElementContainerMatrixから指定されたindexのArrayを取り出し、
        指定したTOF領域で和を行った結果をElementContainerへ出力する。
        @param  psd(UInt4/ElementContainerArray)  index of Array
        @param  tmin(Double) minimum TOF of range for summation.
        @param  tmax(Double) maximum TOF of range for summation.
        @retval EC(ElementContainer)
        """
        if isinstance(psd, int):
            if self.dat is None:
                print("You should input ElementContainer Array!!")
                return
            if psd >= self.dat.PutTableSize():
                print("PSD number is to high!")
                return

            a_psd = self.dat.Put(psd)
        # elif type(psd)==type(mm.ElementContainerArray()):
        elif isinstance(psd, mm.ElementContainerArray):
            a_psd = psd
        else:
            print("You should input ElemnetContainer Array!!")
            return

        num_pixel = a_psd.PutTableSize()

        pixel_list = []
        pixel_sums = []
        pixel_errs = []

        tof_vec = a_psd.PutPointer(0).PutX()
        tof = []
        for t in range(tof_vec.size() - 1):
            tof.append((tof_vec[t] + tof_vec[t + 1]) / 2.0)

        index_min = -1
        index_max = -1
        for t in range(len(tof)):

            if (index_min == -1) and (tmin < tof[t]):
                index_min = t

            if (index_max == -1) and (tmax < tof[t]):
                index_max = t

        if index_min == -1:
            index_min = 0
        if index_max == -1:
            index_max = len(tof) - 1

        print("index min, max = {}".format(index_min, index_max))

        for i in range(num_pixel):
            pixel_list.append(i - 0.5)
            a_sum, a_err = self._SumEC(a_psd.Put(i), index_min, index_max)
            pixel_sums.append(a_sum)
            pixel_errs.append(a_err)

        pixel_list.append(num_pixel + 0.5)

        head_psd = a_psd.PutHeader()
        head_EC = mm.HeaderBase()
        if head_psd.CheckKey("PSDID") != 0:
            head_EC.Add("PSDID", head_psd.PutInt4("PSDID"))
        else:
            if isinstance(psd, int):
                head_EC.Add("PSDID", psd)
            else:
                head_EC.Add("PSDID", 0)
        EC = mm.ElementContainer(head_EC)
        EC.Add("PSD", pixel_list)
        EC.Add("Intensity", pixel_sums)
        EC.Add("Error", pixel_errs)
        EC.SetKeys("PSD", "Intensity", "Error")

        return EC

    ##############################
    def _SumEC(self, a_pixel, index_min, index_max):
        """
        ElementContainerのKeyYの和
        index_minからindex_maxまでのKeyYの総和を返す
        @param a_pixel(ElementContainer) 対象となるElementContainer
        @param index_min(UInt4) 和をとる領域の最小index
        @param index_max(UInt4) 和をとる領域の最大index
        @retval tupple of sum and err (Double) 総和 and error
        """
        intensity = a_pixel.PutY()
        error = a_pixel.PutE()
        a_sum = 0.0
        a_err = 0.0
        for t in range(index_min, index_max):
            a_sum = a_sum + intensity[t]
            a_err = a_err + error[t] * error[t]

        return (a_sum, math.sqrt(a_err))

    ##############################
    def PutSumText(self, psd, tmin=0.0, tmax=39500.0, filename="PutSum.txt"):
        """
        KeyYの和をTEXTファイルに出力
        与えられたElementContainerMatrixから指定されたindexのArrayを取り出し、
        指定したTOF領域で和を行った結果をTEXTファイルに出力。戻り値にはそのElementCotainer。
        @param   psd(UInt4)  index of Array
        @param  tmin(Double) minimum TOF of range for summation.
        @param  tmax(Double) maximum TOF of range for summation.
        @param  filename(String) File name of output
        @retval EC(ElementContainer)
        """
        EC2txt = self.PutSumEC(psd, tmin, tmax)

        wf = open(filename, "w")

        pixel_list = EC2txt.PutX()
        pixel_sums = EC2txt.PutY()
        xx = []
        for i in range(len(pixel_list) - 1):
            xx.append((pixel_list[i] + pixel_list[i + 1]) / 2)

        for i in range(len(pixel_sums)):
            st = "%d,%f\n" % (int(xx[i]), pixel_sums[i])
            wf.write(st)

        wf.close()

        return EC2txt
