#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
可視化処理制御モジュール
[160401] add VisContM_macosx xrc file for running on MacOS
[150903] add "Direct" or "Inverted" flag for VisualCalcSqe
[150602] add isSliceAverageMode flag
[150601] add Load QxQyQz Text function
[150526][150527] add 3 axes rotation function
[150316] add auto filling for each axis
[1307xx] add diagonal folding
[130624] bugfix making MAP data to be sent to D2Vis
[130617] improve foldings functions (required Manyo-Utsusemi rev69 or later)
[121228] change code for Manyo Release
[120709] remove the panel to operate data on tabs
"""

import vis.D2Vis as D2Vis
import vis.UtilPlot as UtilPlot
import time
import sys

import threading
import wx
import os
from wx import xrc

#from exp.DeffCommonCHOP import *

from numpy import *

try:
    import Manyo as mm
    import Manyo.Utsusemi as mu ##[inamura 121228]
except:
    pass

import vis.VisContMParams as VCP ## [inamura 110206]

SpectTypeDic = {
    "SIK":"Direct",
    "DNA":"Inverted",
    "HRC":"Direct",
    "AMR":"Direct"
}#[inamura 150903]

#######################################
#  Setting Dialog
#######################################
class SettingDialog( wx.Dialog ):
    """
    Dialog class for Setting
    [inamura 150602]
    """
    #########################################################
    def __init__(self, parent):
        """
        """
        self.parent = parent
        self.res = parent.res
        self.dialog = self.parent.res.GetDialog( parent.frame, "SettingDialog" )
        
        self.ckSliceAveMode = self.res.GetCtrl(self.dialog, 'ckSliceAverageMode')
        self.ckSliceAveMode.Bind(wx.EVT_CHECKBOX, self.OnCheckSliceAveMode, self.ckSliceAveMode)
        
        
        self.dialog.Bind(wx.EVT_CLOSE, self.OnClose)
        
        # Show this dialog
        self.dialog.Show()
        
        
    ##############################################        
    def OnCheckSliceAveMode(self, evt):
        """
        チェックボックスのイベントハンドラ
        @param  evt 　イベント
        @retval 無し
        """ 
        print "--OnCheckSliceAveMode"
        if evt.IsChecked():
            self.parent.isSliceAverageMode = True
            print "---- isSliceAverageMode is True"
        else:
            self.parent.isSliceAverageMode = False
            print "---- isSliceAverageMode is False"

    ##########################################################
    def OnClose(self, evt):
        """
        Function driven by Close event (just destroy)
        @param  evt  event info
        @retval None
        """ 
        self.dialog.Destroy()
        

        
#######################################
#  DataOperatorDialog [inamura 120709]
#######################################
class DataOperatorDialog( wx.Dialog ):
    """
    Dialog class for data operation
    """
    #########################################################
    def __init__(self, parent):
        """
        """
        
        self.parent = parent
        self.res = parent.res
        # Get resource
        #self.res = UtilPlot.ResourceFile("VisContM")
        self.dialog = self.parent.res.GetDialog( parent.frame, "DataOperationDialog" )
        
        # Get control 
        # チェックボックスのイベントハンドラ登録
        self.ckPr = self.res.GetCtrl(self.dialog, 'ckPr')
        self.ckPr.Bind(wx.EVT_CHECKBOX, self.OnCheck, self.ckPr)
        
        # コンボボックスのイベントハンドラ登録
        cbop = self.res.GetCtrl(self.dialog, 'cbOP')
        cbop.Bind(wx.EVT_COMBOBOX, self.OnComboOP, cbop)
        
        self.dialog.Bind(wx.EVT_BUTTON, self.OnCalc, id=self.res.GetId('btCalc'))
        self.dialog.Bind(wx.EVT_BUTTON, self.OnClose, id=self.res.GetId('btClose'))
        
        # Show this dialog
        self.dialog.Show()
        
        
    ##########################################################
    def OnClose(self, evt):
        """
        Function driven by Close event (just destroy)
        @param  evt  event info
        @retval None
        """ 
        self.dialog.Destroy()
        
    ##############################################        
    def OnCheck(self, evt):
        """
        チェックボックスのイベントハンドラ
        @param  evt 　イベント        @retval 無し        """ 
        # 演算式のコントロールを取得
        panel = self.dialog
        cb0 = self.res.GetCtrl(panel, 'cb0')
        eq = self.res.GetCtrl(panel, 'stEQ')
        butbn = self.res.GetCtrl(panel, 'btCalc')
        
        print "OnCheck: "
        # スライスデータ間の演算であれば
        if evt.IsChecked():
            # 演算結果を入れるタブの指定を消す
            cb0.Hide()
            eq.Hide()
            # ボタンのラベルを変更
            butbn.SetLabel("Show")
        else:
            cb0.Show()
            eq.Show()
            butbn.SetLabel("Calculate")

    ##############################################        
    def OnComboOP(self, evt):
        """
        演算子コンボボックスのイベントハンドラ
        @param  evt 　イベント
        @retval 無し
        """ 
        #panel = self.res.GetCtrl(self.dialog, 'DataOperationPanel')
        panel = self.dialog
        # 演算子無しか
        if evt.GetSelection() == 2:
            self.res.GetCtrl(panel, 'm2').Hide()
            self.res.GetCtrl(panel, 'asta').Hide()
            self.res.GetCtrl(panel, 'cb2').Hide()
        # 減算または加算    
        else:
            self.res.GetCtrl(panel, 'm2').Show()
            self.res.GetCtrl(panel, 'asta').Show()
            self.res.GetCtrl(panel, 'cb2').Show()
            
    ##############################################        
    def OnCalc(self, evt):
        """
        Calcurateボタンのイベントハンドラ
        @param  evt 　イベント
        @retval 無し
        """ 
        panel = self.res.GetCtrl(self.dialog, 'DataOperationPanel')
        try:
            try:
                # 係数をテキストボックスから取得
                sm1 = self.res.GetCtrl(panel, 'm1').GetValue()
                m1 = float(sm1)
                sm2 = self.res.GetCtrl(panel, 'm2').GetValue()
                m2 = float(sm2)
            except:
                raise UtilPlot.PlotException('Common', 'C027', ("Coefficient",))
            
            
            # 各コンボボックスのコントロールを取得
            c0 = self.res.GetCtrl(panel, 'cb0').GetSelection()
            c1 = self.res.GetCtrl(panel, 'cb1').GetSelection()
            c2 = self.res.GetCtrl(panel, 'cb2').GetSelection()
            c3 = self.res.GetCtrl(panel, 'cbOP').GetSelection()
            
            # サンプルタイトル文字列を作る
            strSamp = self._MakeSampName(c1, c2, c3, sm1,sm2)
            # スライスデータ間の演算か
            if self.ckPr.IsChecked():
                self._OperateSlicedData(c1, c2, c3, m1,m2, strSamp)
            else:
            # 生データ間の演算(あれば射影後のデータも)
                self._OperateRawData(c0, c1, c2, c3, m1,m2, strSamp)
                     
        except UtilPlot.PlotException, ex:
            UtilPlot.PlotMessage(self.dialog, ex)
            return      

    #########################################
    def _MakeSampName(self, i1, i2, op, sm1, sm2):
        """
        スライスデータを演算し、2D マップ表示
        @param　 i1　タブ1 のインデックス
        @param　 i2　タブ2 のインデックス
        @param　 op　0: 減算、1: 加算
        @param　 sm1　タブ1 のデータに乗ずる係数(文字列)
        @param　 sm2　タブ2 のデータに乗ずる係数(文字列)
        @retval 無し
        """
        t1 = self.parent.tabs[i1]
        if t1.ECM == None:
            raise UtilPlot.PlotException('VisCont', 'V006', (self.parent.tname[i1],))
        h1 = t1.ECM.PutHeaderPointer()
        if h1.CheckKey("SampleName")==1:
            s1 = h1.PutString("SampleName")
            if '*' in s1:
                s1 = '( %s )' % s1
        else:
            s1 = self.parent.tname[i1]
        
        if op == 2:
            return "%s * %s" % (sm1,s1)
 
        t2 = self.parent.tabs[i2]
        if t2.ECM == None:
            raise UtilPlot.PlotException('VisCont', 'V006', (self.parent.tname[i2],))
        h2 = t2.ECM.PutHeaderPointer()
        if h1.CheckKey("SampleName")==1:
            s2 = h2.PutString("SampleName")
        else:
            s2 = self.parent.tname[i2]
        
        if h1.PutDouble("Ei")!=h2.PutDouble("Ei"):
            raise UtilPlot.PlotException('VisCont', 'V007', ())
        
        if '*' in s2:
            s2 = "( %s )" % s2

        # 演算子を作る
        if op == 0:
            opc = '-'
        else:
            opc = '+'
        
        # 演算内容を示す文字列を作る
        return "%s * %s %s %s * %s" % (sm1, s1, opc, sm2, s2)
        
    #########################################
    def _OperateSlicedData(self, i1, i2, op, m1, m2, samp):
        """
        スライスデータを演算し、2D マップ表示
        @param　 i1　タブ1 のインデックス
        @param　 i2　タブ2 のインデックス
        @param　 op　0: 減算、1: 加算
        @param　 m1　タブ1 のデータに乗ずる係数
        @param　 m2　タブ2 のデータに乗ずる係数
        @param　 samp　演算過程を示すサンプル名
        @retval 無し
        """
        t1 = self.parent.tabs[i1]

        # タブ1にスライスデータがあるか
        if t1.map == None:
            raise UtilPlot.PlotException('VisCont', 'V004', (self.parent.tname[i1],))
        
        # 演算するデータを取得
        mt1 = t1.map[0]
        et1 = t1.map[1]
        param1 = t1.GetTabParam()
                
        # タブ間の演算か
        if op != 2:
            t2 = self.parent.tabs[i2]
            # タブ2にスライスデータがあるか
            if t2.map == None:
                raise UtilPlot.PlotException('VisCont', 'V004', (self.parent.tname[i2],))
        
            # タブ間のパラメータを比較
            param2 = t2.GetTabParam()
            for i in range(len(param1)):
                # パラメータにアンマッチがあるか
                if param1[i] != param2[i]:
                    raise UtilPlot.PlotException('VisCont', 'V005', (self.parent.tname[i1],self.parent.tname[i2]))

            # 演算するデータを取得
            mt2 = t2.map[0]
            et2 = t2.map[1]
        
            # 縦・横のデータ数が等しいか
            if len(mt1) != len(mt2) or len(mt1[0]) != len(mt2[0]):
                raise UtilPlot.PlotException('VisCont', 'V009', ())
        
        # 減算か
        if op == 0:
            dd = m1*mt1 - m2*mt2
            ee = m1*m1*et1*et1 + m2*m2*et2*et2
        # 加算か
        elif op == 1:
            dd = m1*mt1 + m2*mt2
            ee = m1*m1*et1*et1 + m2*m2*et2*et2
        else:
            dd = m1*mt1
            ee = m1*m1*et1*et1
            
        ee = sqrt(ee)
        
        # マスク値処理
        for i in range(len(mt1)):
            for j in range(len(mt1[0])):
                if mt1[i,j] == UtilPlot.MASKVALUE:
                    dd[i,j] = UtilPlot.MASKVALUE
                    ee[i,j] = 0.0
        
        map = (dd, ee, t1.map[2], t1.map[3])    
        
        if self.parent.pmap == None:
            self.parent.pmap = Plot2DMap(0, "0", self.parent.frame)
        # 2D マップ表示
        self.parent.pmap.PlotMap(t1, map)
       

    #########################################
    def _OperateRawData(self,i0, i1, i2, op, m1, m2, samp):
        """
        スライスデータを演算し、2D マップ表示
        @param　 i0　演算結果を入れるタブ のインデックス
        @param　 i1　タブ1 のインデックス
        @param　 i2　タブ2 のインデックス
        @param　 op　0: 減算、1: 加算
        @param　 m1　タブ1 のデータに乗ずる係数
        @param　 m2　タブ2 のデータに乗ずる係数
        @param　 samp　演算過程を示すサンプル名
        @retval 無し
        """
        # タブのインスタンスを取得
        t0 = self.parent.tabs[i0]
        t1 = self.parent.tabs[i1]
        t2 = self.parent.tabs[i2]
        # タブ1のパラメータを取得
        param1 = t1.GetTabParam()
        # データを取得   
        ecm1 = t1.ECM
        
        # タブ間の加減算であれば
        if op != 2:
            # タブ2のパラメータを取得
            param2 = t2.GetTabParam()
            # タブ間のサンプル情報を比較
            for i in range(13):
                # パラメータにアンマッチがあるか
                if param1[i] != param2[i]:
                    raise UtilPlot.PlotException('VisCont', 'V005', (self.parent.tname[i1],self.parent.tname[i2]))
            ecm2 = t2.ECM
            # データ数のチェック
            if ecm1.PutTableSize() != ecm2.PutTableSize():
                raise UtilPlot.PlotException('VisCont', 'V009', ())
            if ecm1(0).PutTableSize() != ecm1(0).PutTableSize():
                raise UtilPlot.PlotException('VisCont', 'V009', ())
            ec1=ecm1(0,0).PutX()
            ec2=ecm2(0,0).PutX()
            if ec1.size()!=ec2.size():
                raise UtilPlot.PlotException('VisCont', 'V009', ())
        
        # データをロードするタブを選択状態とする
        self.parent.note.SetSelection(i0)
        
        # 減算か
        if op == 0:
            ecm3 = ecm1.Mul(m1) - ecm2.Mul(m2)

        # 加算か
        elif op == 1:
            ecm3 = ecm1.Mul(m1) + ecm2.Mul(m2)

        else:
            ecm3 = ecm1.Mul(m1)
            
        ecm3.InputHeader( ecm1.PutHeader() )
        t0.SetDataToTab( ecm3 )

        
#######################################
#  VisConMtFrame
####################################### 
class VisContMFrame(wx.Frame):
    """
    可視化制御画面クラス
    """
    tabs = [None, None, None, None, None, None, None, None, None, None]
    tname = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
    tdict = {"A":0,"B":1,"C":2,"D":3,"E":4,"F":5,"G":6,"H":7,"I":8,"J":9}
    
    #########################################################
    def __init__(self, m0=None, m1=None, m2=None, m3=None, m4=None, m5=None, m6=None, m7=None, m8=None, m9=None):
        """
        コンストラクタ
        @param  m0～m4  ElementContainerMatrix
        @retval 無し
        """ 
        #print "VisualContM_2nd_version"
        self.pmap = None
        #[inamura 100127]-->
        #[inamura 160401]-->
        if sys.platform=='darwin':
            self.res = UtilPlot.ResourceFile("VisContM_macosx")
        else:
            self.res = UtilPlot.ResourceFile("VisContM")
        #<--[inamura 160401]
        #self.res = UtilPlot.ResourceFile("/home/yinamura/dev/ManyoRelease2/VisualContM/150525/VisContM")
        #<--[inamura 100127]
        self.frame = self.res.GetFrame(None, 'mainframe')
        # リソースからフレームが取得できなかった
        if self.frame == None:
            print "Cannot read VisCont.xrc"
            return

        # アイコンの設定
        self.frame.SetIcon(UtilPlot.Images().GetMainIcon())
        # メニューバーを作る
        menuBar= self.res.GetMenuBar('MainMenuBar')
        self.frame.SetMenuBar(menuBar)
        # Set Event Handlers for menue items
        #self.frame.Bind(wx.EVT_MENU, self.OnOpen, id=xrc.XRCID('menu_load'))
        self.frame.Bind(wx.EVT_MENU, self.OnLoadLegacy, id=xrc.XRCID('menu_legacy'))
        #self.frame.Bind(wx.EVT_MENU, self.OnSaveAs, id=xrc.XRCID('menu_saveas'))
        self.frame.Bind(wx.EVT_MENU, self.OnLoadQxQyQzText, id=xrc.XRCID('menu_load_qxqyqz_text')) ##[inamura 150601]
        self.frame.Bind(wx.EVT_MENU, self.OnSettings, id=xrc.XRCID('menu_settings')) ##[inamura 150602]
        self.frame.Bind(wx.EVT_MENU, self.OnClose, id=xrc.XRCID('menu_exit'))
        
        self.note = self.res.GetCtrl(self.frame, 'note')

        # ボタンのイベントハンドラ設定
        self.frame.Bind(wx.EVT_BUTTON, self.OnApply, id=self.res.GetId('btApply'))
        self.frame.Bind(wx.EVT_BUTTON, self.OnOpperate, id=self.res.GetId('btOpperate'))
        # logo panel
        #logo_path = os.path.join( os.environ['UTSUSEMI_BASE_DIR'],'vis','LOGO_utsusemi3_s.png' )
        logo_path = os.path.join( os.environ['UTSUSEMI_BASE_DIR'],'vis','LOGO_utsusemi_3_c_long_small.png' )
        if os.path.exists( logo_path ):
            logo_panel = self.res.GetCtrl(self.frame, 'logoPanel' )
            logo_bmp = wx.Image(logo_path).ConvertToBitmap()
            #wx.StaticBitmap(logo_panel, -1, logo_bmp, (0,0),(200,40))
            wx.StaticBitmap(logo_panel, -1, logo_bmp, (5,0),(205,40))
        else:
            print "log path=", logo_path
        #クローズイベント登録
        self.frame.Bind(wx.EVT_CLOSE, self.OnClose)

        # 画面を表示
        self.frame.Show(True)
        # 各タブのインスタンスを取得し保存、データをセット
        self.SetTab(m0, 0)
        self.SetTab(m1, 1)
        self.SetTab(m2, 2)
        self.SetTab(m3, 3)
        self.SetTab(m4, 4)
        self.SetTab(m5, 5)
        self.SetTab(m6, 6)
        self.SetTab(m7, 7)
        self.SetTab(m8, 8)
        self.SetTab(m9, 9)

        # Slice Mode Setting [inamura 150602]
        self.isSliceAverageMode = True
        
    ##############################################        
    def SetTab(self, mm, num):
        """
        タブインスタンスを生成し、データをセット
        @param  mm 　エレメントコンテナマトリックス
        @param  num  データを追加するタブのNO.
        @retval 無し
        """
        # タブインスタンスを生成
        self.tabs[num] = OperationTab(self, num)
        
        # データが指定されていれば
        if mm != None:
            self.AddMatrix(mm, num)
            
    ##############################################        
    def OnApply(self, evt):
        """
        開いているタブのパラメータを他のタブ画面にコピーする
        @param  evt 　イベント
        @retval 無し
        """ 
        # 開いているタブのパラメータを取得する
        num = self.note.GetSelection()
        param = self.tabs[num].GetTabParam() 
        
        # 他のタブにパラメータを設定する
        for i in range(len(self.tabs)):
            if i != num:
                self.tabs[i].SetTabParam(param) 

    ##############################################        
    def OnOpperate(self, evt):
        """
        ##[inamura 120709]
        """
        ## show dialog
        dlg = DataOperatorDialog( self )
        
    ##############################################        
    def AddMatrix(self, matrix , num = -1):
        """
        マトリックスデータの追加
        @param  matrix 　エレメントコンテナマトリックス
        @param  num  データを追加するタブのNO.  -1 は指定無し
        @retval 無し
        """
        # タブが指定されていなければ
        if num < 0:
            # 空のタブをさがす、なければ置き換え
            num = self.GetTabNum()
            # キャンセルか
            if num == None:
                return
        # マトリックスクラスでデータ読み込み
        if isinstance( matrix, mm.ElementContainerMatrix ):
            self.tabs[num].SetDataToTab(matrix) 
        
            
    ##############################################        
    def OnLoadLegacy(self, *args):
        """
        デテクタマップ画面クローズ
        @param  evt 　イベント
        @retval 無し
        """
        """
        # 空のタブをさがす、なければ置き換え
        num = self.GetTabNum()
        # キャンセルか
        if num == None:
            return
        
        # データをロードするタブを選択状態とする
        self.note.SetSelection(num)

        # SPE ファイルオープンダイアログ
        dlg = wx.FileDialog(self.frame, 'SPE File Open ...', os.getcwd(), style=wx.OPEN, wildcard='SPE(*.SPE)|*.SPE')

        # キャンセルか
        if dlg.ShowModal() != wx.ID_OK:
            return
        
        spefile = dlg.GetPath()
        dir = os.path.dirname(spefile)
        
        # PHX ファイルオープンダイアログ
        dlg = wx.FileDialog(self.frame, 'PHX File Open ...', dir, style=wx.OPEN, wildcard='PHX(*.PHX)|*.PHX')

        # キャンセルか
        if dlg.ShowModal() != wx.ID_OK:
            return
        
        phxfile = dlg.GetPath()
        
        # Ei 指定、正常に入力されるまで繰り返す
        while True:
            dlg = wx.TextEntryDialog(self.frame, "Main Ei (mev):",
                                  "Input Ei", style=wx.OK|wx.CANCEL)
            # キャンセルか
            if dlg.ShowModal() != wx.ID_OK:
                return
            try:
                try:
                    ei = float(dlg.GetValue()) 
                except:
                    raise UtilPlot.PlotException('Common', 'C027', ("Ei",))
                else:
                    if ei > 0.0:
                        break
                    raise UtilPlot.PlotException('Common', 'C009', ("Ei","0.0"))
            except UtilPlot.PlotException, ex:
                UtilPlot.PlotMessage(self.frame, ex)

        # レガシィファイルの読み込みクラスのインスタンス取得
        spe = LegacyFile()
        # SPE ファイルの読み込み
        try:
            spe.ReadFiles(spefile, phxfile, ei)
        except UtilPlot.PlotException, ex:
                UtilPlot.PlotMessage(self.frame, ex)
        else:
            self.tabs[num].ECM = spe
        """
        print "---- OnLoadLegacy"
        return

    ##############################################
    def OnLoadQxQyQzText(self,evt):
        """
        ##[inamura 150601]
        """
        dlg = wx.FileDialog(self.frame, 'QxQyQx Text File Open ...', os.getcwd(), style=wx.OPEN, wildcard='Text(*.txt)|*.txt')
        ## Cancel ?
        if dlg.ShowModal() != wx.ID_OK:
            return
        
        filename = dlg.GetPath()
        fo = open( filename, "r" )
        qx = mm.MakeDoubleVector()
        qy = mm.MakeDoubleVector()
        qz = mm.MakeDoubleVector()
        hw = mm.MakeDoubleVector()
        ii = mm.MakeDoubleVector()
        ee = mm.MakeDoubleVector()
        Ei = 0.0
        TAB = "A"
        while(True):
            a_line = fo.readline()
            if a_line=="":
                break
            if a_line.find('##Ei=')==0:
                sep_line = a_line.split("=")
                ei_str = sep_line[1].split(" ")
                Ei = float( ei_str[0].strip() )
            if a_line.find('##TAB=')==0:
                sep_line = a_line.split("=")
                TAB = sep_line[1].strip()
            elif a_line.find("#")!=0:
                sep_line = a_line.split(" ")
                if len(sep_line)<6:
                    fo.close()
                    msg = "QxQyQx file is invalid."
                    print msg
                    raise UserWarning,msg
                else:
                    qx.append( float( sep_line[0].strip() ) )
                    qy.append( float( sep_line[1].strip() ) )
                    qz.append( float( sep_line[2].strip() ) )
                    hw.append( float( sep_line[3].strip() ) )
                    ii.append( float( sep_line[4].strip() ) )
                    ee.append( float( sep_line[5].strip() ) )
            else:
                pass
                
        ec = mm.ElementContainer()
        ec.Add("Qx",qx)
        ec.Add("Qy",qy)
        ec.Add("Qz",qz)
        ec.Add("hw",hw)
        ec.Add("Intensity",ii)
        ec.Add("Error",ee)
        ec.SetKeys("hw","Intensity","Error")
        hh_ec = ec.PutHeaderPointer()
        hh_ec.Add("MASKED", 0)
        
        eca = mm.ElementContainerArray()
        eca.Add(ec)
        hh_eca =eca.PutHeaderPointer()
        hh_eca.Add("MASKED", 0)
        del ec
        
        ecm = mm.ElementContainerMatrix()
        ecm.Add(eca)
        del eca
        
        hh_ecm = ecm.PutHeaderPointer()
        hh_ecm.Add("Ei",Ei)
        hh_ecm.Add("QxQyQzTextFile",str(filename) )
        hh_ecm.Add("MASKED", 0)
        hh_ecm.Add("isHistogram", 0 )
        

        self.SetTab( ecm, self.tdict[TAB] )
        
    ##############################################
    def OnSettings(self,evt):
        """
        ##[inamura 150602]
        """
        dlg = SettingDialog( self )
        
    ##############################################        
    def GetTabNum(self):
        """
        データを読み込むタブを探す
        @param  無し
        @retval 空タブのインデックス
        """
        num = None
        # 空のタブを探す
        for i in range(5):
            if self.tabs[i].smpDat == None:
                num = i
                break
        # 空のタブがあればタブNo.を返す
        if num != None:
            return num
            
        # 空のタブが無い場合は置き換えるタブを指定    
        while True:
            dlg = wx.TextEntryDialog(self.frame, "Tab to replace (A, B, C, D or E):",
                                  "Tab to Replace", style=wx.OK|wx.CANCEL)
        
            if dlg.ShowModal() != wx.ID_OK:
                return None
            try:
                code = dlg.GetValue().strip()
                code.capitalize()
                if code == 'A' or code == 'a':
                    return 0
                elif code == 'B' or code == 'b':
                    return 1
                elif code == 'C' or code == 'c':
                    return 2
                elif code == 'D' or code == 'd':
                    return 3
                elif code == 'E' or code == 'e':
                    return 4
                else:
                    raise UtilPlot.PlotException('Common', 'C013', ("A, B, C, D or E",))
            except UtilPlot.PlotException, ex:
                UtilPlot.PlotMessage(self.frame, ex)

    ##############################################        
    def OnClose(self, *args):
        """
        デテクタマップ画面クローズ
        @param  evt 　イベント
        @retval 無し
        """
        # ---> 2008/04/27 Minakawa add
        # 2Dプロッタのクローズ要求を出す
        if self.pmap != None:
            self.pmap.Request2DClose()
        # 全タブに2Dプロッタのクローズ要求を出す
        for tab in self.tabs:
            if tab.pmap != None:
                tab.pmap.Request2DClose()
        # <--- 2008/04/27 Minakawa add
        
        for tab in self.tabs:
            ##[inamura 120503]-->
            try:
                if tab.ECM!=None:
                    del tab.ECM
            except:
                print "#####*******  Tab has no ECM!!!"

            #if tab.ECM!=None:
            #    del tab.ECM
            ##<--[inamura 120503]
            del tab
        
        # 画面のクローズ       
        self.frame.Destroy() 

#######################################
#  OperationTab
####################################### 
class OperationTab(object):
    """
    可視化制御画面クラス
    """
    
    #########################################################
    def __init__(self, parent, num):
        """
        コンストラクタ
        @param  parent  親クラスのインスタンス
        @param  num  タブNo.
        @retval 無し
        """ 
        self.parent = parent
        self.note = parent.note
        self.frame = parent.frame
        self.num = num      # タブ No.
        #self.smpDat = None  # データクラス
        #self.smpInfo = None # サンプル情報クラス
        self.map = None     # スライス後の2次元マップデータ
        self.ECM = None
        
        #[inamura 150903]-->
        spect_type="Direct"
        if os.environ.has_key("UTSUSEMI_SYS_NAME"):
            sys_name=os.environ["UTSUSEMI_SYS_NAME"]
            if SpectTypeDic.has_key(sys_name):
                spect_type=SpectTypeDic[sys_name]
        self.VisualCalcSqe = mu.UtsusemiSqeCalc(spect_type) #[inamura 121228]
        #<--[inamura 150903]
        
        # タブオブジェクトを取得
        self.tab = self.note.GetPage(num)

        self.frame = parent.frame
        self.res = parent.res

        self.pmap = None
        #self.dat = OperateMatrix()
        
        # ハンドル取得とイベントハンドラの設定
        self.HandleTB()

        # スライス履歴リストを初期化
        self.hist = []
        self.histI = 0
       
        # ボタンを選択不可
        self.SetStatus(False)
        
    #########################################################
    def HandleTB(self):
        """
        テキストボックス読み込み用のハンドル取得
        @param  無し
        @retval 無し
        """
        ##[inamrua 110206]-->
        panel0 = self.res.GetCtrl(self.tab, 'panel0')
        self.tab.Bind(wx.EVT_BUTTON, self.OnLoad, id=self.res.GetId('btLoad'))
        self.tab.Bind(wx.EVT_BUTTON, self.OnSave, id=self.res.GetId('btSave'))
        ##<--[inamrua 110206]
        
        panel1 = self.res.GetCtrl(self.tab, 'panel1')

        # プログレスバーのコントロール取得
        self.gauge = self.res.GetCtrl(self.tab, 'gauge')

        # プログレスバー表示用のタイマーを準備
        self.timer = wx.Timer(panel1)
        panel1.Bind(wx.EVT_TIMER, self.TimerHandler)
        # サンプル情報テキストボックスのコントロールを取得
        self.sinfo = []
        for i in range(15): ##[inamura 150526]
            ii = i+1
            txt = "txt%d" % ii
            self.sinfo.append(self.res.GetCtrl(panel1, txt)) 
        ##[inamura 150526]-->
        self.chrotax1 = self.res.GetCtrl(panel1, 'chRotateAxis1st') 
        self.chrotax2 = self.res.GetCtrl(panel1, 'chRotateAxis2nd')
        self.chrotax3 = self.res.GetCtrl(panel1, 'chRotateAxis3rd')            
        ##<--[inamura 150526]
        
        # UVベクトルテキストボックスのコントロールを取得
        panel2 = self.res.GetCtrl(self.tab, 'panel2')
        self.uv = []
        #[inamura 100127]-->
        #for i in range(3):
        for i in range(4):
        #<--[inamura 100127]
            uv0 = []
            for j in range(5):
               ii = i*5+j+1
               txt = "txt%d" % ii
               uv0.append(self.res.GetCtrl(panel2, txt)) 
            self.uv.append(uv0)

        #[inamura 100130]-->
        #self.rbox = self.res.GetCtrl(panel2, 'rbQ') 

        # ラジオボックスイベントハンドラ登録
        #self.rbox.Bind(wx.EVT_RADIOBOX, self.OnRadioBox, self.rbox)
        #<--[inamura 100130]
        
        # スライス情報テキストボックスのコントロールを取得
        panel3 = self.res.GetCtrl(self.tab, 'panel3')
        
        self.slice = []
        #[inamura 100127]-->
        #for i in range(9):
        for i in range(12):
        #<--[inamura 100127]
            ii = i+1
            txt = "txt%d" % ii
            self.slice.append(self.res.GetCtrl(panel3, txt))

        # リソースよりコントロールを取得
        self.v1txt = self.res.GetCtrl(panel3, 'v1txt')
        self.v2txt = self.res.GetCtrl(panel3, 'v2txt')
        ##[inamura 150526]-->
        self.chv1 = self.res.GetCtrl(panel3, 'v1ch')
        self.chv2 = self.res.GetCtrl(panel3, 'v2ch')
        self.chv3 = self.res.GetCtrl(panel3, 'v3ch')
        self.chv4 = self.res.GetCtrl(panel3, 'v4ch')
        ##<--[inamura 150526]
        self.cbdiagfold = self.res.GetCtrl(panel3, 'cbDiagFoldType') #[inamura 1307xx]
        
        #[inamura 130617]-->
        self.FoldTxtList=[]
        self.FoldTxtList.append( self.res.GetCtrl(panel3, 'txtFold1') )
        self.FoldTxtList.append( self.res.GetCtrl(panel3, 'txtFold2') )
        self.FoldTxtList.append( self.res.GetCtrl(panel3, 'txtFold3') )
        self.FoldTxtList.append( self.res.GetCtrl(panel3, 'txtFold4') )
        #[inamura 1307xx]-->
        self.DiagFoldAxesList=[]
        self.DiagFoldAxesList.append( self.res.GetCtrl(panel3, 'ckbUseAx1Fold') )
        self.DiagFoldAxesList.append( self.res.GetCtrl(panel3, 'ckbUseAx2Fold') )
        self.DiagFoldAxesList.append( self.res.GetCtrl(panel3, 'ckbUseAx3Fold') )
        self.DiagFoldAxesList.append( self.res.GetCtrl(panel3, 'ckbUseAx4Fold') )
        #<--[inamura 1307xx]
        
        self.ckbSaveMem = self.res.GetCtrl(panel3, 'ckbSaveMem') #[inamura 110419]
        
        btProj = self.res.GetCtrl(panel2, 'btProj')
        self.btAutoFill = self.res.GetCtrl(panel3, 'btAutoFill' ) #[inamura 100930]
        #[inamura 160401]-->
        if sys.platform=='darwin':
            btSlice = self.res.GetCtrl(self.tab, 'btSlice')
            self.btBack = self.res.GetCtrl(self.tab, 'btBack')
            self.btForward = self.res.GetCtrl(self.tab, 'btForward')
            btSliceOutTxt = self.res.GetCtrl(self.tab, 'btOutTxt' ) #[inamura 100615]
            btSliceOutBin = self.res.GetCtrl(self.tab, 'btOutBin' ) #[inamura 110223]
        else:
            btSlice = self.res.GetCtrl(panel3, 'btSlice')
            self.btBack = self.res.GetCtrl(panel3, 'btBack')
            self.btForward = self.res.GetCtrl(panel3, 'btForward')
            btSliceOutTxt = self.res.GetCtrl(panel3, 'btOutTxt' ) #[inamura 100615]
            btSliceOutBin = self.res.GetCtrl(panel3, 'btOutBin' ) #[inamura 110223]
        #<--[inamura 160401]
        
        #[inamura 150316]-->
        self.btAutoFillBtnList=[None,None,None,None,None]
        self.btAutoFillBtnList[0] = self.res.GetCtrl(panel3, 'btAutoFillAx1' )
        self.btAutoFillBtnList[1] = self.res.GetCtrl(panel3, 'btAutoFillAx2' )
        self.btAutoFillBtnList[2] = self.res.GetCtrl(panel3, 'btAutoFillAx3' )
        self.btAutoFillBtnList[3] = self.res.GetCtrl(panel3, 'btAutoFillAx4' )
        self.btAutoFillBtnList[4] = self.btAutoFill
        #<--[inamura 150316]
        
        # CHOICEイベントハンドラ登録
        ##[inamura 150526]-->
        self.chrotax1.Bind(wx.EVT_CHOICE, self.OnChoiceRotateAxes, self.chrotax1) 
        self.chrotax2.Bind(wx.EVT_CHOICE, self.OnChoiceRotateAxes, self.chrotax2) 
        self.chrotax3.Bind(wx.EVT_CHOICE, self.OnChoiceRotateAxes, self.chrotax3) 
        self.chRotationSteps = [self.chrotax1,self.chrotax2,self.chrotax3]
        self.chv1.Bind(wx.EVT_CHOICE, self.OnChoicePlotAxes, self.chv1)
        self.chv2.Bind(wx.EVT_CHOICE, self.OnChoicePlotAxes, self.chv2)
        self.chv3.Bind(wx.EVT_CHOICE, self.OnChoicePlotAxes, self.chv3)
        self.chv4.Bind(wx.EVT_CHOICE, self.OnChoicePlotAxes, self.chv4)
        ##<--[inamura 150526]
        self.cbdiagfold.Bind(wx.EVT_CHOICE, self.OnComboDiagFold, self.cbdiagfold) #[inamura 1307xx]
        
        # ボタンのイベントハンドラ設定
        self.tab.Bind(wx.EVT_BUTTON, self.OnProj, id=self.res.GetId('btProj'))
        self.tab.Bind(wx.EVT_BUTTON, self.OnSlice, id=self.res.GetId('btSlice'))
        
        self.tab.Bind(wx.EVT_BUTTON, self.OnBack, id=self.res.GetId('btBack'))
        self.tab.Bind(wx.EVT_BUTTON, self.OnForward, id=self.res.GetId('btForward'))
        
        self.tab.Bind(wx.EVT_BUTTON, self.OnProjClea, id=self.res.GetId('btClr'))#[inamura 100130]
        self.tab.Bind(wx.EVT_BUTTON, self.OnSliceOutTxt, id=self.res.GetId('btOutTxt')) #[inamura 100615]
        self.tab.Bind(wx.EVT_BUTTON, self.OnAutoFill, id=self.res.GetId('btAutoFill')) #[inamura 100930]
        self.tab.Bind(wx.EVT_BUTTON, self.OnSliceOutBin, id=self.res.GetId('btOutBin')) #[inamura 110223]
        
        #[inamura 150316]-->
        self.tab.Bind(wx.EVT_BUTTON, self.OnAutoFillAxes, id=self.res.GetId('btAutoFillAx1'))
        self.tab.Bind(wx.EVT_BUTTON, self.OnAutoFillAxes, id=self.res.GetId('btAutoFillAx2'))
        self.tab.Bind(wx.EVT_BUTTON, self.OnAutoFillAxes, id=self.res.GetId('btAutoFillAx3'))
        self.tab.Bind(wx.EVT_BUTTON, self.OnAutoFillAxes, id=self.res.GetId('btAutoFillAx4'))
        #<--[inamura 150316]
        
        # ボタンコントロールリスト
        #self.lstbt = [btProj, btSlice, self.btBack, self.btForward]
        #self.lstbt = [btProj, btSlice, btSliceOutTxt, self.btBack, self.btForward] #[inamura 100615]
        #self.lstbt = [btProj, btSlice, btSliceOutTxt,btSliceOutBin, self.btBack, self.btForward] ##[inamura 110223]
        #self.lstbt = [btProj, btSlice, self.btAutoFill,btSliceOutTxt,btSliceOutBin, self.btBack, self.btForward] ##[inamura 120216]
        self.lstbt = [btProj, btSlice, self.btAutoFillBtnList,btSliceOutTxt,btSliceOutBin, self.btBack, self.btForward]
        
    #############################################
    def TimerHandler(self, evt):
        """
        タイマー監視ルーチン
        プログレスバーの表示
        @param  evt イベント情報
        @retval 無し
        """ 
        #num, max = self.spe.GetProgress()
        num, max = (1,1)
        # 読み込みが開始されたか
        if num > 0:
            # 読み込み中か
            if num < max-1:
                pb = num * 20 / max
                self.gauge.SetValue(pb)
            # 読み込み終了
            else:
                # プログレスバーを消す
                self.gauge.Hide()
                # タイマー停止 
                self.timer.Stop()
                # タブにデータを表示
                self._SetData()
                

    #########################################
    def SetDataToTab(self, ecm):
        """
        タブにデータを設定
        @param ecm ElementContainerMatrix
        @retval 無し
        """

        if self.ECM!=None:
            del self.ECM
        
        self.ECM = mm.ElementContainerMatrix( ecm )
        
        self._SetData()

    #########################################
    def _SetData(self):
        """
        タブにデータを設定
        @param  無し
        @retval 無し
        """
        
        ## サンプル情報クラスの生成
        #self.smpInfo = SampleInfo(self.smpDat.sample)
        #self.smpInfo.SetInfoFromHeader(self.smpDat.ECMHeader) #[inamura 101001]
        # スライス履歴を初期化
        self._InitSlice()
        # サンプル名をタブに表示
        panel0 = self.res.GetCtrl(self.tab, 'Panel0')
        smp = self.res.GetCtrl(panel0, 'sample')
        ecm_h = self.ECM.PutHeader()
        if (ecm_h.CheckKey("SampleName")==1):
            smp.SetLabel(ecm_h.PutString("SampleName"))
            
        # Ei値をタブに表示
        strEi = "%.2f" % ecm_h.PutDouble("Ei")
        self.res.GetCtrl(panel0, 'stei').SetLabel(strEi)
        # サンプル情報表示
        self._DispSampleInfo()
       
        # 射影ボタンを選択可、スライスボタンを選択不可とする
        self.SetStatus(False) ##[inamura 120214]
        self.SetStatus(True, 1)
        code = self.note.GetPageText(self.num)
        # タブにデータロード済みマークをつける
        self.note.SetPageText(self.num, code[0]+"*")
        
    #########################################################
    def _DispSampleInfo(self):
        """
        サンプル情報を表示
        @param  無し
        @retval 無し
        """  
        panel1 = self.res.GetCtrl(self.tab, 'panel1')

        ecm_h = self.ECM.PutHeader()
        if (ecm_h.CheckKey("SimpleLatticeConsts")==1):
            lcs = ecm_h.PutDoubleVector("SimpleLatticeConsts")
            self.res.GetCtrl(panel1, 'txt1').SetValue("%.3f"%lcs[0])
            self.res.GetCtrl(panel1, 'txt2').SetValue("%.3f"%lcs[1])
            self.res.GetCtrl(panel1, 'txt3').SetValue("%.3f"%lcs[2])
            self.res.GetCtrl(panel1, 'txt4').SetValue("%.1f"%lcs[3])
            self.res.GetCtrl(panel1, 'txt5').SetValue("%.1f"%lcs[4])
            self.res.GetCtrl(panel1, 'txt6').SetValue("%.1f"%lcs[5])
        if (ecm_h.CheckKey("SampleUvec")==1):
            suv = ecm_h.PutDoubleVector("SampleUvec")
            self.res.GetCtrl(panel1, 'txt7').SetValue("%.1f"%suv[0])
            self.res.GetCtrl(panel1, 'txt8').SetValue("%.1f"%suv[1])
            self.res.GetCtrl(panel1, 'txt9').SetValue("%.1f"%suv[2])
        if (ecm_h.CheckKey("SampleVvec")==1):
            svv = ecm_h.PutDoubleVector("SampleVvec")
            self.res.GetCtrl(panel1, 'txt10').SetValue("%.1f"%svv[0])
            self.res.GetCtrl(panel1, 'txt11').SetValue("%.1f"%svv[1])
            self.res.GetCtrl(panel1, 'txt12').SetValue("%.1f"%svv[2])
        if (ecm_h.CheckKey("SampleRotatePhi")==1):
            phi = ecm_h.PutDouble("SampleRotatePhi")
            self.res.GetCtrl(panel1, 'txt13').SetValue("%.1f"%phi)


    #########################################################
    def GetTabParam(self):
        """
        タブのもつパラメータ(テキストボックスの値他)を返す
        @param  無し
        @retval パラメータの一覧(リスト)
        """ 
        param = []
        # サンプル情報を取得
        for ss in self.sinfo:
            param.append(ss.GetValue())
            
        # 射影情報を取得
        ##[inamura 100201]-->
        #for i in range(3):
        for i in range(4):    ##<--[inamura 100201]
            for j in range(5):
                param.append(self.uv[i][j].GetValue())
        ##[inamura 100201]-->
        ## 縮約軸の情報を取得        
        #param.append(self.rbox.GetSelection())
        ##<--[inamura100201]
        # スライス情報を取得
        for sl in self.slice:
            param.append(sl.GetValue())
        # 軸情報を取得
        param.append(self.chv1.GetSelection()) ##[inamura 150526]
        param.append(self.chv2.GetSelection()) ##[inamura 150526]
        param.append(self.chv3.GetSelection()) ##[inamura 150526]
        param.append(self.chv4.GetSelection()) ##[inamura 150526]
        
        return param
    
    #########################################################
    def SetTabParam(self, param):
        """
        タブのもつパラメータ(テキストボックスの値他)に値を設定
        @param  param パラメータの一覧(リスト)
        @retval 無し
        """ 
        k = 0
        # サンプル情報を設定
        for ss in self.sinfo:
            ss.SetValue(param[k])
            k += 1
            
        # 射影情報を設定
        ##[inamura100201]-->
        for i in range(4):  ##<--[inamura100201]
            for j in range(5):
                self.uv[i][j].SetValue(param[k])
                k += 1

        ##[inamura100201]
        ## 縮約軸の情報を設定        
        #self.rbox.SetSelection(param[k])
        #k += 1
        ##<--[inamura100201]
        
        # スライス情報を設定
        for sl in self.slice:
            sl.SetValue(param[k])
            k += 1
            
        # 軸情報を設定
        self.chv1.SetSelection(param[k])
        self.chv2.SetSelection(param[k+1])
        self.chv3.SetSelection(param[k+2])
        self.chv4.SetSelection(param[k+3])  ##[inamura 150526]
        # ステップテキストボックスの選択可/不可を設定
        self.SetStepEnable()
        
        # スライス履歴を初期化
        self._InitSlice()
        

    #########################################
    def OnRadioBox(self, evt):
        """
        ラジオボタンボックスイベント処理
        @param evt　　イベント
        @retval 無し
        """
        ax = evt.GetSelection()
        # 表示を初期化
        #[inamura 100127]-->
        val = [["1","0","0","0"],["0","1","0","0"],["0","0","1","0"],["0","0","0","1"]]
        for i in range(4):
            for j in range(4):
                self.uv[i][j].SetValue(val[i][j])

        self.uv[0][4].SetValue("Qa (rlu)")
        self.uv[1][4].SetValue("Qb (rlu)")
        self.uv[2][4].SetValue("Qc (rlu)")
        self.uv[3][4].SetValue("Energy (meV)")
        
        #<--[inamura 100127]
    #########################################
    def OnChoiceRotateAxes(self, evt):
        """
        CHOICE Event
        ##[inamura 150526]
        @param evt    Event
        @retval None
        """
        bt = evt.GetEventObject()
        if bt==self.chrotax1:
            if self.chrotax1.GetCurrentSelection()==0:
                self.sinfo[12].Enable(False)
                self.chrotax2.Enable(False)
                self.sinfo[13].Enable(False)
                self.chrotax3.Enable(False)
                self.sinfo[14].Enable(False)
            else:
                self.sinfo[12].Enable(True)
                self.chrotax2.Enable(True)
                if self.chrotax2.GetCurrentSelection()==0:
                    self.sinfo[13].Enable(False)
                    self.chrotax3.Enable(False)
                    self.sinfo[14].Enable(False)
                else:
                    self.sinfo[13].Enable(True)
                    self.chrotax3.Enable(True)
                    if self.chrotax3.GetCurrentSelection()==0:
                        self.sinfo[14].Enable(False)
                    else:
                        self.sinfo[14].Enable(True)
                        
        elif bt==self.chrotax2:
            if self.chrotax1.GetCurrentSelection()==0:
                self.sinfo[13].Enable(False)
                self.chrotax3.Enable(True)
                self.sinfo[14].Enable(False)
            else:
                if bt.GetCurrentSelection()==0:
                    self.sinfo[13].Enable(False)
                    self.chrotax3.Enable(False)
                    self.sinfo[14].Enable(False)
                else:
                    self.chrotax3.Enable(True)
                    self.sinfo[13].Enable(True)
                    if self.chrotax3.GetCurrentSelection()==0:
                        self.sinfo[14].Enable(False)
                    else:
                        self.sinfo[14].Enable(True)
                        
        else:
            if (self.chrotax1.GetCurrentSelection()==0) or (self.chrotax2.GetCurrentSelection()==0) or (bt.GetCurrentSelection()==0):
                self.sinfo[14].Enable(False)
            else:
                self.sinfo[14].Enable(True)
        
            
    #########################################
    def OnChoicePlotAxes(self, evt):
        """
        コンボボックスイベント処理
        @param evt　　イベント
        @retval 無し
        """
        bt = evt.GetEventObject()
        # ステップテキストボックスを取得
        ##[inamura 150526]-->
        if bt == self.chv1:
            step = self.slice[2]
        elif bt == self.chv2:
            step = self.slice[5]
        elif bt == self.chv3:
            step = self.slice[8]
        else:
            step = self.slice[11]
        # 暑さ指定ならステップは選択不可    
        if bt.GetCurrentSelection() == 2: # 0..X-Axis, 1..Y-Axis, 2..Thickness
            step.Enable(False)
        else:
            step.Enable(True)
        ##<--[inamura 150526]

    ######################################### [inamura 1307xx]->
    def OnComboDiagFold(self, evt):
        """
        """
        index = 0
        if isinstance( evt, int ):
            index = evt
        else:
            bt = evt.GetEventObject()
            index = bt.GetSelection()
        
        if index==0:
            for obj in self.DiagFoldAxesList:
                obj.SetValue(False)
                obj.Enable(False)
        else:
            for obj in self.DiagFoldAxesList:
                obj.Enable(True)
        
    #########################################
    def OnProj(self, *args):
        """
        Exec Projection ボタン押下イベント処理
        射影処理を実行
        @param evt　　イベント
        @retval 無し
        """
        # サンプル情報テキストボックスの値を取得 
        sample = []
        try:
            # サンプル情報をテキストボックスから取得
            for cont in self.sinfo:
                anum = cont.GetValue().strip()
                try:
                    num = float(anum)
                except:
                    raise UtilPlot.PlotException('Common', 'C027', ("Sample Info",))
                sample.append(num)
                
            ##[inamura 150526]-->
            if not self.sinfo[12].IsEnabled():
                sample[12] = 0.0
            if not self.sinfo[13].IsEnabled():
                sample[13] = 0.0
            if not self.sinfo[14].IsEnabled():
                sample[14] = 0.0
            ##<--[inamura 150526]
            
            # サンプル情報クラスに詰め替え
            ecm_h = self.ECM.PutHeaderPointer()
            
            lcv = mm.MakeDoubleVector()
            for i in range(6):
                lcv.append( sample[i] )
            if ecm_h.CheckKey("SimpleLatticeConsts")==1:
                ecm_h.OverWrite("SimpleLatticeConsts",lcv)
            else:
                ecm_h.Add("SimpleLatticeConsts",lcv)

            uv = mm.MakeDoubleVector()
            vv = mm.MakeDoubleVector()
            for i in range(3):
                uv.append( sample[6+i] )
                vv.append( sample[9+i] )
            if ecm_h.CheckKey("SampleUvec")==1:
                ecm_h.OverWrite("SampleUvec",uv)
            else:
                ecm_h.Add("SampleUvec",uv)
            if ecm_h.CheckKey("SampleVvec")==1:
                ecm_h.OverWrite("SampleVvec",vv)
            else:
                ecm_h.Add("SampleVvec",vv)

            if ecm_h.CheckKey("SampleRotatePhi")==1:
                ecm_h.OverWrite("SampleRotatePhi", float(sample[12]))
            else:
                ecm_h.Add("SampleRotatePhi", float(sample[12]))
                
            ##[inamura 150526]-->
            rotSteps = mm.MakeDoubleVector()
            ## self.chRotationSteps is [self.chrotax1,self.chrotax2,self.chrotax3]
            for i in range(3):
                if self.sinfo[12+i].IsEnabled():
                    axis_num = -1.0
                    if self.chRotationSteps[i].GetCurrentSelection()==1:   # if Y-axis
                        axis_num = 1.0                             # 1 means Y-axis in VisualCalcSqe
                    elif self.chRotationSteps[i].GetCurrentSelection()==2: # if Z-axis
                        axis_num = 2.0                             # 2 means Z-axis in VisualCalcSqe
                    elif self.chRotationSteps[i].GetCurrentSelection()==3: # if X-axis
                        axis_num = 0.0                             # 0 means X-axis in VisualCalcSqe
                    else:
                        break
                    if axis_num > -1.0:
                        rotSteps.append( axis_num )                # axis number
                        rotSteps.append( float( sample[12+i] ) )   # angle
                else:
                    break
                    
            if ecm_h.CheckKey("SampleRotateSteps")==1:
                ecm_h.OverWrite("SampleRotateSteps", rotSteps )
            else:
                ecm_h.Add("SampleRotateSteps", rotSteps )
            ##<--[inamura 150526]
                    
            # U1, U2, U3 ベクトルをテキストボックスから取得
            viewAxis = zeros([4,4], float64)
            for i in range(4):
            #<-- [inamura 100127]
                for j in range(4): 
                    anum = self.uv[i][j].GetValue()
                    try:
                        num = float(anum)
                    except:
                        raise UtilPlot.PlotException('Common', 'C027', ("U Vector",))
                    
                    viewAxis[i][j]=num
                # U1, U2, U3, ベクトルが直交しているかどうかを確認
                sp0 = dot(viewAxis[0], viewAxis[1])
                sp1 = dot(viewAxis[1], viewAxis[2])
                sp2 = dot(viewAxis[0], viewAxis[2])
                
                # 内積誤差の範囲で0でなかったら
                if abs(sp0) > 0.01 or abs(sp1) > 0.01 or abs(sp2) > 0.01:
                    raise UtilPlot.PlotException('VisCont', 'V000', ())
                    
        except UtilPlot.PlotException, ex:
            UtilPlot.PlotMessage(self.frame, ex)
            return
        
        # 射影処理を実行
        self.SetStatus(False)
        self.VisualCalcSqe.SetTarget( self.ECM )
        viewAxis_in = mm.MakeDoubleVector()
        for i in range(4):
            for j in range(4):
                viewAxis_in.append( viewAxis[i][j] )
        ##[inamura 150601]-->
        #all_u = self.VisualCalcSqe.Projection(viewAxis_in)
        hh_ECM = self.ECM.PutHeaderPointer()
        if hh_ECM.CheckKey("QxQyQzTextFile")==1:
            all_u = self.VisualCalcSqe.Projection_QxQyQz(viewAxis_in)
        else:
            all_u = self.VisualCalcSqe.Projection(viewAxis_in)
        ##<--[inamura 150601]
        
        # スライスボタンを選択可とする
        #self.SetStatus(True,  4)
        self.SetStatus(True,  5) ##[inamura 120216]
        
        code = self.note.GetPageText(self.num)
        # タブに射影済みマークをつける
        self.note.SetPageText(self.num, code[0] + "**")
        
        # スライス履歴を初期化
        self._InitSlice()

        # [inamura 100615]-->
        #print "On Proj, min and max Vx=",self.dat.Vx.min(),self.dat.Vx.max()
        #print "On Proj, min and max Vy=",self.dat.Vy.min(),self.dat.Vy.max()
        #print "On Proj, min and max Vz=",self.dat.Vz.min(),self.dat.Vz.max()
        #print "On Proj, min and max Vw=",self.dat.Vw.min(),self.dat.Vw.max()
        # [inamura 100930]
        #self.slice[0].SetValue( "%g" % round( (self.dat.Vx.min()-0.1),1) )
        #self.slice[1].SetValue( "%g" % round( (self.dat.Vx.max()+0.1),1) )
        #self.slice[3].SetValue( "%g" % round( (self.dat.Vy.min()-0.1),1) )
        #self.slice[4].SetValue( "%g" % round( (self.dat.Vy.max()+0.1),1) )
        #self.slice[6].SetValue( "%g" % round( (self.dat.Vz.min()-0.1),1) )
        #self.slice[7].SetValue( "%g" % round( (self.dat.Vz.max()+0.1),1) )
        #self.slice[9].SetValue( "%g" % round( (self.dat.Vw.min()-0.1),1) )
        #self.slice[10].SetValue( "%g" % round( (self.dat.Vw.max()+0.1),1) )
        #<--[inamura 100930]<--[inamura 100616]
        
    ##[inamura 100130]-->
    #########################################
    def OnProjClea(self,*args):
        # 表示を初期化
        val = [["1","0","0","0"],["0","1","0","0"],["0","0","1","0"],["0","0","0","1"]]
        for i in range(4):
            for j in range(4):
                self.uv[i][j].SetValue(val[i][j])

        self.uv[0][4].SetValue("Qa (rlu)")
        self.uv[1][4].SetValue("Qb (rlu)")
        self.uv[2][4].SetValue("Qc (rlu)")
        self.uv[3][4].SetValue("Energy (meV)")
        
        # スライスボタンを選択不可とする
        if self.lstbt[0].IsEnabled():
            self.SetStatus(False)
            self.SetStatus(True, 1)
        else:
            self.SetStatus(False)        

    ##<--[inamura 100130]
    ##[inamura 100930]-->
    #########################################
    def OnAutoFill(self,*args):
        try:
            qrv = self.VisualCalcSqe.PutQRange()
            self.slice[0].SetValue( "%g" % round( (qrv[0]-0.1),1) )
            self.slice[1].SetValue( "%g" % round( (qrv[1]+0.1),1) )
            self.slice[3].SetValue( "%g" % round( (qrv[2]-0.1),1) )
            self.slice[4].SetValue( "%g" % round( (qrv[3]+0.1),1) )
            self.slice[6].SetValue( "%g" % round( (qrv[4]-0.1),1) )
            self.slice[7].SetValue( "%g" % round( (qrv[5]+0.1),1) )
            self.slice[9].SetValue( "%g" % round( (qrv[6]-0.1),1) )
            self.slice[10].SetValue( "%g" % round( (qrv[7]+0.1),1) )
        except:
            print "Do the projection first."

    #<--[inamura 100930]
    ##[inamura 150316]-->
    #########################################
    def OnAutoFillAxes(self,*args):
        try:
            btn_name = args[0].GetEventObject().GetName()
            qrv = self.VisualCalcSqe.PutQRange()
            if btn_name == "btAutoFillAx1":
                self.slice[0].SetValue( "%g" % round( (qrv[0]-0.1),1) )
                self.slice[1].SetValue( "%g" % round( (qrv[1]+0.1),1) )
            elif btn_name == "btAutoFillAx2":
                self.slice[3].SetValue( "%g" % round( (qrv[2]-0.1),1) )
                self.slice[4].SetValue( "%g" % round( (qrv[3]+0.1),1) )
            elif btn_name == "btAutoFillAx3":
                self.slice[6].SetValue( "%g" % round( (qrv[4]-0.1),1) )
                self.slice[7].SetValue( "%g" % round( (qrv[5]+0.1),1) )
            elif btn_name == "btAutoFillAx4":
                self.slice[9].SetValue( "%g" % round( (qrv[6]-0.1),1) )
                self.slice[10].SetValue( "%g" % round( (qrv[7]+0.1),1) )
            else:
                pass
        except:
            print "Do the projection first"
        
    #<--[inamura 150316]
    #########################################
    def _InitSlice(self):
        """
        スライス履歴を初期化
        @param  無し
        @retval 無し
        """        
        # スライス履歴リストを初期化
        self.hist = []
        self.histI = 0
        
    #########################################
    def OnSlice(self, *args):
        """
        Slice ボタン押下イベント処理
        2D マップにスライス結果を表示
        @param evt　　イベント
        @retval 無し
        """

        avs = []
        avs.append( self.chv1.GetCurrentSelection() )
        avs.append( self.chv2.GetCurrentSelection() )
        avs.append( self.chv3.GetCurrentSelection() )
        avs.append( self.chv4.GetCurrentSelection() )
        AxType = mm.MakeStringVector()
        
        n1=[]
        n2=[]
        n3=[]
        for i in range(4):
            if avs[i] == 0:
                n1.append(i)
                AxType.append("X")
            elif avs[i] == 1:
                n2.append(i)
                AxType.append("Y")
            else:
                n3.append(i)
                AxType.append("T")
                if len(n3)>1:
                    avs[i]=3
                    
        if len(n1)!=1 or len(n2)!=1 or len(n3)!=2:
            raise UtilPlot.PlotException('VisCont', 'V001', ())

        #[inamura 1307xx]-->
        foldings = mm.MakeDoubleVector()
        for i in range(7):
            foldings.append(-1.0)
            
        for i in range(len(self.FoldTxtList)):
            tmp_f = float(self.FoldTxtList[i].GetValue())
            if tmp_f<0.0:
                tmp_f = -1.0
            foldings[i] = tmp_f
        
        DiagCond = self.cbdiagfold.GetSelection()
        #print "### DiagCond = ",DiagCond
        if DiagCond==wx.NOT_FOUND:
            print "Not Secected"
        elif (DiagCond==1) or (DiagCond==2) or (DiagCond==3):
            foldings[4] = float( DiagCond )
            ax_fold = []
            for i in range(len(self.DiagFoldAxesList)):
                if self.DiagFoldAxesList[i].GetValue():
                    ax_fold.append(i)
            if len(ax_fold)!=2:
                print "the number of Checked must be 2"
                return
            else:
                foldings[5]=float( ax_fold[0] )
                foldings[6]=float( ax_fold[1] )
        else:
            foldings[4] = -1.0
            foldings[5] = 0.0
            foldings[6] = 0.0
        #if self.ckbf1.GetValue(): # diagonal line Y=X
        #    foldings[4] = 1.0
        #if self.ckbf2.GetValue(): # diagonal line Y=-X
        #    foldings[5] = 1.0
        #print "Foldings=",foldings[0],foldings[1],foldings[2],foldings[3],foldings[4],foldings[5],foldings[6]
        #<--[inamura 1307xx]
        
        A1range = mm.MakeDoubleVector()
        A2range = mm.MakeDoubleVector()
        A3range = mm.MakeDoubleVector()
        A4range = mm.MakeDoubleVector()

        for i in range(3):
            A1range.append( float( self.slice[0+i].GetValue() ) )
            A2range.append( float( self.slice[3+i].GetValue() ) )
            A3range.append( float( self.slice[6+i].GetValue() ) )
            A4range.append( float( self.slice[9+i].GetValue() ) )
        
        #ret = self.VisualCalcSqe.Slice( A1range,A2range,A3range,A4range,AxType,foldings )
        ret = self.VisualCalcSqe.Slice( A1range,A2range,A3range,A4range,AxType,foldings, self.parent.isSliceAverageMode ) ##[inamura 150602]
        
        xv = self.VisualCalcSqe.PutXArray()
        yv = self.VisualCalcSqe.PutYArray()
        II = self.VisualCalcSqe.PutDArray()
        EE = self.VisualCalcSqe.PutEArray()
        #print "size=",xv.size(),yv.size(),II.size(),EE.size()
        
        h = []
        v = []
        for i in range(xv.size()):
            h.append(xv[i])
        for i in range(yv.size()):
            v.append(yv[i])
        
        h = array(h)
        v = array(v)

        H, V = meshgrid(h, v)

        numx = xv.size()-1
        numy = yv.size()-1
        #print "numx,numy=",numx,numy
        
        data =zeros((numy,numx), float64)
        err =zeros((numy,numx), float64)
        
        for j in range(numx):
            for k in range(numy):
                data[k,j] = II[ j*numy + k ]
                err[k,j] = EE[ j*numy + k ]

        #self.map = ( data, err, H, V, 1 )
        self.map = ( data, err, H, V, 0 ) ##[inamura 130624]
        
        #self.SetStatus(True, 4)
        self.SetStatus(True, 5) ##[inamura 120216]
                
        # タブラベルを取得
        code = self.note.GetPageText(self.num)
        
        if self.pmap == None:
            self.pmap = Plot2DMap(self.num, code[0], self.frame)
        # 2D マップ表示
        self.pmap.PlotMap(self, self.map)
        
        # 履歴を記録
        self.PutHistory()
        # タブラベルにスライスデータ有りのマークをつける
        self.note.SetPageText(self.num, code[0] + "***")


    ##[inamura 110206]-->
    #########################################
    def _devideBinAsZeroCenter(self,r_min,r_step):
        """
        calculate min of binning to satisfy that zero becomes center of a bin
        @param r_min (float) min value
        @param r_step (float) step value
        @return r_min (float) calculated min value
        """
        
        if r_min<0.0:
            p = -r_step/2.0
            while(p>r_min):
                p -= r_step
            r_min = p
        else:
            p = r_step/2.0
            while(p<r_min):
                p += r_step
            r_min = p - r_step

        return r_min
    ##<--[inamura 110206]
        
    #########################################
    def PutHistory(self):
        """
        スライス履歴を保存
        @param 無し
        @retval 無し
        """
        sd = SlicedData(ver=2) #[inamura 100930]

        # 軸条件を取得
        #[inamura 100127]-->
        #sd.axis = (self.chv1.GetSelection(),self.chv2.GetSelection(), self.chv3.GetSelection())  ##[inamura 150526]
        #
        # スライス条件テキストボックスの文字列を保存
        #for i in range(9):
        
        sd.axis = (self.chv1.GetSelection(),self.chv2.GetSelection(), self.chv3.GetSelection(), self.chv4.GetSelection()) ##[inamura 150526]
        for i in range(12):
        #<--[inamura 100127]
            sd.txts[i]=self.slice[i].GetValue()

        sd.map = self.map
        # 履歴を保存
        self.hist.append(sd)
        self.histI = len(self.hist)-1
        # 前にデータがあれば
        if self.histI > 0: 
            # バックボタンを選択可とする
            self.btBack.Enable(True)

    #########################################
    def OnBack(self, *args):
        """
        バック ボタン押下イベント処理
        前のパラメータを表示し、2Dマップ画像を戻す
        @param evt　　イベント
        @retval 無し
        """
        
        self.histI = self.histI-1
        # 履歴データを表示
        self.DispHistory()
        # フォワードボタンを選択可とする
        self.btForward.Enable(True)
        # 前にデータが無ければ
        if self.histI == 0:
            # バックボタンを選択不可とする
            self.btBack.Enable(False)

    #########################################
    def OnForward(self, *args):
        """
        前へ ボタン押下イベント処理
        元のパラメータを表示し、2Dマップ画像を戻す
        @param evt　　イベント
        @retval 無し
        """
        self.histI += 1
        # 履歴データを表示
        self.DispHistory()
        # バックボタンを選択可とする
        self.btBack.Enable(True)
        # 後にデータが無ければ
        if self.histI == len(self.hist)-1:
            # バックボタンを選択不可とする
            self.btForward.Enable(False)

    #########################################
    def DispHistory(self):
        """
        スライス履歴表示、パラメータを設定し
        マップを表示
        @param 無し
        @retval 無し
        """
        sd = self.hist[self.histI]
        # 軸条件を設定
        self.chv1.SetSelection(sd.axis[0])
        self.chv2.SetSelection(sd.axis[1])
        self.chv3.SetSelection(sd.axis[2])
        self.chv4.SetSelection(sd.axis[3])
        # スライス条件テキストボックスに保存文字列を設定
        #[inamura 100127]-->
        #for i in range(9):
        for i in range(12):
        #<--[inamura 100127]
            self.slice[i].SetValue(sd.txts[i])
        
        self.SetStepEnable()
        # 2次元マップを表示
        self.pmap.PlotMap(self, sd.map)

    #########################################
    def SetStepEnable(self):
        """
        ステップテキストボックスの選択可・不可を設定
        @param 無し
        @retval 無し
        """
        if self.chv1.GetSelection() == 2:
            self.slice[2].Enable(False)
        else:
            self.slice[2].Enable(True)
            
        if self.chv2.GetSelection() == 2:
            self.slice[5].Enable(False)
        else:
            self.slice[5].Enable(True)
            
        if self.chv3.GetSelection() == 2:
            self.slice[8].Enable(False)
        else:
            self.slice[8].Enable(True)        

        ##[inamura 101020]-->
        if self.chv4.GetSelection() == 2:
            self.slice[11].Enable(False)
        else:
            self.slice[11].Enable(True)
        ##<--[inamura 101020]

    #########################################
    # [inamura 100615]-->
    #def SetStatus(self, flag, num = 4):
    #def SetStatus(self, flag, num = 5): # <--[inamura 100615]
    #def SetStatus(self, flag, num = 6): # <--[inamura 110223]
    def SetStatus(self, flag, num = 7): # <--[inamura 120215]
        """
        状態表示とボタン制御
        @param flag   ボタンの選択可・不可フラグ
        @param num　　　ボタンの数
        @retval 無し
        """
        # ボタンの選択可・不可
        for i in range(num):
            if type(self.lstbt[i])==list:
                for a_btn in self.lstbt[i]:
                    a_btn.Enable(flag)
            else:
                self.lstbt[i].Enable(flag)

    # [inamura 110419]-->
    #########################################
    def _SliceForOutput(self, isText=True):
        """
        """
        if isText:
            dlg = wx.FileDialog(self.frame, 'Save Output Text File  ...', os.getcwd(), style=wx.SAVE, wildcard='Text(*.txt)|*.txt')
        else:
            dlg = wx.FileDialog(self.frame, 'Save Output Binary File  ...', os.getcwd(), style=wx.SAVE, wildcard='Bin(*.vbin)|*.vbin')
            
        # Cancel?
        if dlg.ShowModal() != wx.ID_OK:
            return

        try:

            # Get Slicing parameter from text box on the panel
            param = zeros([12],float64)

            ## get type of axis X, Y or T
            avs = []
            avs.append( self.chv1.GetSelection() )
            avs.append( self.chv2.GetSelection() )
            avs.append( self.chv3.GetSelection() )
            avs.append( self.chv4.GetSelection() )

            # Set axis range using type of axis
            for i in range(4):
                r_min = float(self.slice[i*3].GetValue())
                r_max = float(self.slice[i*3+1].GetValue())
                # if X or Y
                if avs[i]<2:
                    r_step = float(self.slice[i*3+2].GetValue())
                    r_min = self._devideBinAsZeroCenter( r_min, r_step )
                # if T 
                else:
                    r_step = r_max - r_min
                    
                param[i*3] = r_min
                param[i*3+1] = r_max
                param[i*3+2] = r_step

            print param
            ax1 = mm.MakeDoubleVector()
            ax2 = mm.MakeDoubleVector()
            ax3 = mm.MakeDoubleVector()
            ax4 = mm.MakeDoubleVector()
            
            for i in range(3):
                ax1.append( param[0+i] )
                ax2.append( param[3+i] )
                ax3.append( param[6+i] )
                ax4.append( param[9+i] )
            
            # Get folding flag
            #[inamura 130617]-->
            #fld = mm.MakeInt4Vector()
            #for i in range(4):
            #    fld.append(0)
            # 
            #if self.cks1.GetValue():
            #    fld[0]=1
            #if self.cks2.GetValue():
            #    fld[1]=1
            #if self.cks3.GetValue():
            #    fld[2]=1
            #if self.cks4.GetValue():
            #    fld[3]=1
            fld = mm.MakeDoubleVector()
            for i in range(4):
                fld.append(0)
            for i in range(len(self.FoldTxtList)):
                tmp = float( self.FoldTxtList[i].GetValue() )
                if tmp<0.0:
                    fld[i]=0.0
                else:
                    fld[i]=1.0
            #<--[inamura 130617]
            print "Foldings=",fld[0],fld[1],fld[2],fld[3]            
            self.SetStatus(False)
            
            # Execute slicing for output
            savefile = dlg.GetPath()
            #convD4Mat = Manyo.ConvertEcmToD4Matrix()
            #convD4Mat.SetTarget( self.ECM )
            """
            if not self.ckbSaveMem.GetValue():
                print "Mapping with much memory."
                convD4Mat.Mapping(ax1,ax2,ax3,ax4,fld)
            else:
                print "Mapping with low memory"
                ff = os.path.join(os.getcwd(),"temp_execslice.bin")
                convD4Mat.MakeTempMapFile( ff, ax1, ax2, ax3, ax4, fld )
                print "Finished make map file"
                convD4Mat.TempMapping()
            
            ret = convD4Mat.SaveSlicedDataToFile( str(savefile) )
            """
            ##convD4Mat.SaveSimpleSlicedDataToFile( str(savefile) )
            ##convD4Mat.PartialMapping( str(savefile),ax1,ax2,ax3,ax4,fld )
            #self.VisualCalcSqe.ConvertToD4Mat( str(savefile),ax1,ax2,ax3,ax4,fld )
            self.VisualCalcSqe.ConvertToD4Mat( str(savefile),ax1,ax2,ax3,ax4,fld, self.parent.isSliceAverageMode ) ##[inamura 150602]
            #self.SetStatus(True, 4)
            self.SetStatus(True, 5) ##[inamura 120216]
                    
        except UtilPlot.PlotException, ex:
            UtilPlot.PlotMessage(self.frame, ex)
            return

    #########################################
    def OnSliceOutTxt(self, evt):
        """
        """
        print "On Slice OutTxt"
        
        self._SliceForOutput(isText=True)
        
    
    #########################################
    def OnSliceOutBin(self, evt):
        """
        """
        print "On Slice Out bin file"
        
        self._SliceForOutput(isText=False)

    ##<--[inamura 110419]
    ##[inamrua 110206]-->
    #########################################
    def OnLoad(self, evt):
        """
        Load parameters of VisualCont control from xml file
        @param evt
        @return None
        """
        
        # open dialog
        dlg = wx.FileDialog(self.frame, 'Open Parameter File for VisualCont2 ...', os.getcwd(), style=wx.OPEN, wildcard='xml(*.xml)|*.xml')

        # is Cancel?
        if dlg.ShowModal() != wx.ID_OK:
            return

        # get file path
        xml_file = dlg.GetPath()
        dir = os.path.dirname(xml_file)

        # make instance and load file and analysis XML parameter
        vcp=VCP.VisContMParams(xml_file)
        #print vcp.Header
        #self.smpInfo = vcp.smpInfo
        lc = vcp.Header["SimpleLatticeConsts"]
        uv = vcp.Header["SampleUvec"]
        vv = vcp.Header["SampleVvec"]
        #phi = vcp.Header["SampleRotatePhi"]
        try:
            ro_list = vcp.Header["SampleRotateSteps"]
        except:
            try:
                phi = vcp.Header["SampleRotatePhi"]
                ro_list = [("Y",phi)] 
            except:
                print "Sample Rotation Info or Phi is not found."
                phi = 0.0

        # Set text box on the panel from obtained parameters
        ## sample info, U-vector, V-vector and fai
        self.sinfo[0].SetValue( "%6.4f" % float(lc[0]) )
        self.sinfo[1].SetValue( "%6.4f" % float(lc[1]) )
        self.sinfo[2].SetValue( "%6.4f" % float(lc[2]) )
        self.sinfo[3].SetValue( "%6.4f" % float(lc[3]) )
        self.sinfo[4].SetValue( "%6.4f" % float(lc[4]) )
        self.sinfo[5].SetValue( "%6.4f" % float(lc[5]) )
        self.sinfo[6].SetValue( "%6.4f" % float(uv[0]) )
        self.sinfo[7].SetValue( "%6.4f" % float(uv[1]) )
        self.sinfo[8].SetValue( "%6.4f" % float(uv[2]) )
        self.sinfo[9].SetValue( "%6.4f" % float(vv[0]) )
        self.sinfo[10].SetValue( "%6.4f" % float(vv[1]) )
        self.sinfo[11].SetValue( "%6.4f" % float(vv[2]) )
        ##[inamura 150527]-->
        #self.sinfo[12].SetValue( "%6.4f" % float(phi) )
        ro_axis_dic={ "Y":1,"Z":2,"X":3 }
        for i,a_rot in enumerate(ro_list):
            ax_num=0
            try:
                ax_num = ro_axis_dic[ a_rot[0] ]
            except:
                pass
            self.chRotationSteps[i].Enable(True)
            self.chRotationSteps[i].SetSelection( ax_num )
            self.sinfo[12+i].SetValue( "%6.4f" % float(a_rot[1]) )
            self.sinfo[12+i].Enable(True)
            if (i+1)<len(self.chRotationSteps):
                self.chRotationSteps[i+1].Enable(True)
            
        ##<--[inamura 150527]
                    
        ## Projection infor
        for id in range(4):
            for col in range(4):
                self.uv[id][col].SetValue( "%g" % (vcp.proj_axes[str(id)][col]) )
            self.uv[id][4].SetValue( vcp.proj_axes[str(id)][4] )

        ## Slicing ranges and steps
        for id in range(4):
            type = vcp.paxis_info[str(id)][0]
            if type in ["x","y","p","t"]:
                range_axis = vcp.paxis_info[str(id)][1]
                self.slice[3*id + 0].SetValue( "%g" % ( range_axis[0] ) )
                self.slice[3*id + 1].SetValue( "%g" % ( range_axis[1] ) )
                self.slice[3*id + 2].SetValue( "%g" % ( range_axis[2] ) )
            else:
                print "type in xml file is invalid!!"
                raise
        ## axis type for slicing
        dic = {"x":0,"y":1,"p":2,"t":2 }
        self.chv1.SetSelection( dic[ vcp.paxis_info["0"][0] ] )
        self.chv2.SetSelection( dic[ vcp.paxis_info["1"][0] ] )
        self.chv3.SetSelection( dic[ vcp.paxis_info["2"][0] ] )
        self.chv4.SetSelection( dic[ vcp.paxis_info["3"][0] ] )  ##[inamura 150527]

        ## folding
        #[inamura 130617]-->
        for i in range(4):
            self.FoldTxtList[i].SetValue( str(vcp.paxis_info[str("%1d"%(i))][2]) )
        #<--[inamura 130617]
        #[inamura 1307xx]-->        
        if vcp.diag_folding[0] in [0,1,2]:
            self.cbdiagfold.SetSelection(vcp.diag_folding[0])
            if vcp.diag_folding[0]==0:
                self.OnComboDiagFold(0)
            else:
                self.OnComboDiagFold(1)
                for obj in self.DiagFoldAxesList:
                    obj.SetValue(False)
                if vcp.diag_folding[1]!=0:
                    self.DiagFoldAxesList[vcp.diag_folding[1]-1].SetValue(True)
                if vcp.diag_folding[2]!=0:
                    self.DiagFoldAxesList[vcp.diag_folding[2]-1].SetValue(True)
            
        
        # Update panel display 
        self.SetStepEnable()
        
    
    #########################################
    def OnSave(self, evt):
        """
        Save parameters to xml file from information on the panel
        @param evt
        @return None
        """
        sample=[]
        #for i in range(12):
        for i in range(len(self.sinfo)):  #[inamura 161104]
            anum = self.sinfo[i].GetValue().strip()
            try:
                num = float(anum)
            except:
                raise UtilPlot.PlotException('Common', 'C027', ("Sample Info",))
            sample.append(num)
        
        Header = {}
        Header['SimpleLatticeConsts']=sample[:6]
        Header['SampleUvec']=sample[6:9]
        Header['SampleVvec']=sample[9:12]
        ##[inamura 150527]-->
        #Header['SampleRotatePhi']=sample[12]
        rotationSteps=[]
        for i,rax in zip([0,1,2],self.chRotationSteps):
            if rax.IsEnabled():
                ax_num = rax.GetCurrentSelection()
                if ax_num == 1:
                    rotationSteps.append( ["Y", sample[12+i] ] )
                elif ax_num == 2:
                    rotationSteps.append( ["Z", sample[12+i] ] )
                elif ax_num == 3:
                    rotationSteps.append( ["X", sample[12+i] ] )
                else:
                    break
        Header['SampleRotateSteps']=rotationSteps
        ##<--[inamura 150527]
        
        # Make parameters to give to VisContParams
        ## axisInfo
        axisInfo = []
        for id in range(4):
            a_list = []
            for col in range(4):
                a_list.append( float( self.uv[id][col].GetValue() ) )
            a_list.append( self.uv[id][4].GetValue() )
            axisInfo.append(a_list)

        ## sliceInfo
        dic = {0:"x",1:"y",2:"t"}
        type_list = []
        type_list.append( dic[ self.chv1.GetSelection() ] )
        type_list.append( dic[ self.chv2.GetSelection() ] )
        type_list.append( dic[ self.chv3.GetSelection() ] )
        type_list.append( dic[ self.chv4.GetSelection() ] ) ##[inamura 150527]

        dic = { False:0, True:1 }
        fold_list = []
        #[inamura 130617]-->
        #fold_list.append( dic[ self.cks1.GetValue() ] )
        #fold_list.append( dic[ self.cks2.GetValue() ] )
        #fold_list.append( dic[ self.cks3.GetValue() ] )
        #fold_list.append( dic[ self.cks4.GetValue() ] )
        for i in range(4):
            fold_list.append( float( self.FoldTxtList[i].GetValue() ) )
        #<--[inamura 130617]
        
        #[inamura 1307xx]-->
        sliceInfo = []
        for id in range(4):
            a_list = [type_list[id]]
            for i in range(3):
                a_list.append( float( self.slice[3*id + i].GetValue() ) )
            a_list.append( fold_list[id] )
            sliceInfo.append( a_list )
        
        diagFoldInfo = [self.cbdiagfold.GetSelection()]
        for id in range( len(self.DiagFoldAxesList) ):
            if self.DiagFoldAxesList[id].GetValue():
                diagFoldInfo.append(id+1)
        if len(diagFoldInfo)>3:
            diagFoldInfo = diagFoldInfo[:3]
        #<--[inamura 1307xx]
        
        # make instance
        vcp=VCP.VisContMParams()

        # set parameters
        #vcp.SetAllInfo( Header, axisInfo, sliceInfo )
        vcp.SetAllInfo( Header, axisInfo, sliceInfo, diagFoldInfo ) #[inamura 1307xx]

        # open dialog
        dlg = wx.FileDialog(self.frame, 'Save Parameter File  ...', os.getcwd(), style=wx.SAVE, wildcard='XML(*.xml)|*.xml')

        # if cancel?
        if dlg.ShowModal() != wx.ID_OK:
            return

        # get file path
        savefile = dlg.GetPath()
        dir = os.path.dirname(savefile)

        # show parameters to be checked
        #vcp.ShowParams()

        # save to XML file
        vcp.SaveXML( savefile )
        

    ##<--[inamrua 110206]
#######################################
#  Plot2DMap
####################################### 
class Plot2DMap(object):
    """
    2次元マップ表示クラス
    """ 
    #########################################################
    def __init__(self, num, code, frame):
        """
        コンストラクタ
        @param  num  タブ No.
        @param  code  マップ画面タイトルに付する記号
        @param  frame  親フレーム
        @retval 無し
        """ 
        self.frame = frame
        self.code = code
        self.d2 = None
        if num == 0:
            self.ifi = UtilPlot.IFEvtProp(0)
            self.pno = 0  
        else:
            self.pno = (num+1) * 10  
            self.ifi = UtilPlot.IFEvtProp(self.pno) 

    #########################################
    def PlotMap(self, tab, map):
        """
        2D マップ表示
        @param tab タブのインスタンス
        @param map　2D データ
        @retval 無し
        """
        # D2 プロッタが表示されているか
        if self.d2 == None:
            # 2Dプロッタフレームクローズイベントのリスナー登録
            self.ifi.AddListner('2dclosed',  self.OnNotify2DClose)
            self.d2 = D2Vis.MapD2Frame(self.frame , map, self.pno, self.code) 
        else:
            # データ変更
            self.ifi.NotifyEvent(self, "changedata", map) 
        
        labels = ["","",""]
        labels[tab.chv1.GetCurrentSelection()]=tab.uv[0][4].GetValue()
        labels[tab.chv2.GetCurrentSelection()]=tab.uv[1][4].GetValue()
        labels[tab.chv3.GetCurrentSelection()]=tab.uv[2][4].GetValue()
        labels[tab.chv4.GetCurrentSelection()]=tab.uv[3][4].GetValue() ##[inamura 150527]
        
        # メインタイトル作成
        #di = tab.smpDat
        ecm_h = tab.ECM.PutHeader()
        if ecm_h.CheckKey("SampleName")==1:
            #sample = ecm_h.PutString("SampleName")
            sample = "Sample: %s " % ecm_h.PutString("SampleName")
        else:
            sample = ""
            if ecm_h.CheckKey("INSTRUMENT")==1:
                sample += "%s" % ecm_h.PutString("INSTRUMENT")
            if ecm_h.CheckKey("RUNNUMBER")==1:
                #sample += "%06d" % ( int( ecm_h.PutString("RUNNUMBER") ) ) ##[inamura 161121]
                sample += "%s" % ( ecm_h.PutString("RUNNUMBER") )
            else:
                sample = "---"
        if ecm_h.CheckKey("Ei")==1:
            Ei = ecm_h.PutDouble("Ei")

        #main = "Sample: %s  ( Ei = %.1f (meV) )" % ( sample , Ei )
        main = "%s ( Ei= %.1f (meV) )" % ( sample, Ei )
        # サブタイトル作成
        #str0 = "Ei (meV): %.1f\n" % di.ei
        str1 = "U=[%g, %g, %g]\n" % (float(tab.sinfo[6].GetValue()),float(tab.sinfo[7].GetValue()),float(tab.sinfo[8].GetValue()))
        str2 = "V=[%g, %g, %g]\n" % (float(tab.sinfo[9].GetValue()),float(tab.sinfo[10].GetValue()),float(tab.sinfo[11].GetValue()))
        str3 = "Psi=%s\n" % tab.sinfo[12].GetValue()
        
        
        str4 = "ax1=[%s, %s, %s,%s]\n" % (tab.uv[0][0].GetValue(),tab.uv[0][1].GetValue(),tab.uv[0][2].GetValue(), tab.uv[0][3].GetValue())
        str5 = "ax2=[%s, %s, %s,%s]\n" % (tab.uv[1][0].GetValue(),tab.uv[1][1].GetValue(),tab.uv[1][2].GetValue(), tab.uv[1][3].GetValue())
        str6 = "ax3=[%s, %s, %s,%s]\n" % (tab.uv[2][0].GetValue(),tab.uv[2][1].GetValue(),tab.uv[2][2].GetValue(), tab.uv[2][3].GetValue())
        #str7 = "ax4=[%s, %s, %s,%s]\n" % (tab.uv[3][0].GetValue(),tab.uv[3][1].GetValue(),tab.uv[3][2].GetValue(), tab.uv[3][3].GetValue())

        ii = []
        nn = []
        if tab.chv1.GetSelection() == 2:
            ii.append(0)
            nn.append("ax1")
        if tab.chv2.GetSelection() == 2:
            ii.append(1)
            nn.append("ax2")
        if tab.chv3.GetSelection() == 2:
            ii.append(2)
            nn.append("ax3")
        if tab.chv4.GetSelection() == 2:
            ii.append(3)
            nn.append("ax4")
        
        # Thickness 取得
        th11 = tab.slice[ii[0]*3].GetValue()
        th12 = tab.slice[ii[0]*3+1].GetValue()
        th21 = tab.slice[ii[1]*3].GetValue()
        th22 = tab.slice[ii[1]*3+1].GetValue()
        str8 = "Thick=[%s:%s - %s]\nThick=[%s:%s - %s]" % (nn[0],th11,th12,nn[1],th21,th22 )
        str9 = "Fold:"
        cnt_fld = 0
        for i in range(4):            
            if float(tab.FoldTxtList[i].GetValue())!=-1.0:
                if cnt_fld>1:
                    str9 += "\n      Ax%d[%s]"%(i+1,tab.FoldTxtList[i].GetValue())
                else:
                    str9 += " Ax%d[%s]"%(i+1,tab.FoldTxtList[i].GetValue())
                cnt_fld+=1
        if str9=="Fold:":
            str9=""
        else:
            str9 = ";\n"+str9
        
        #sub = str1+str2+str3+str4+str5+str6+str7+str8 ##[inamura 120211]
        #sub = str1+str2+str3+";"+str4+str5+str6+str7+";"+str8
        sub = str1+str2+str3+";"+str4+str5+str6+";"+str8+str9
        
        # タイトル設定コマンド送信
        self.ifi.NotifyEvent(self, "title", (main, sub))


        # スケールラベル設定コマンド送信
        self.ifi.NotifyEvent(self, "scalelabel", (labels[0], labels[1],"Neutrons")) 
        
        # 表示中のデータを保存
        self.plotNow = (map, labels[0], labels[1])  
 
                
    #########################################
    def OnNotify2DClose(self, *args):
        """
        2Dプロッタクローズイベント受信処理
        @param evt　　イベント
        @retval 無し
        """
        self.plotNow = None
        self.d2 = None

    #########################################
    def Request2DClose(self):
        """
        2Dプロッタクローズ要求処理
        @param  無し
        @retval 無し
        """
         # 2Dプロッタが開いているなら
        if self.d2 != None:
             # 2Dプロッタのクローズ要求を出す　
            self.ifi.NotifyEvent(self, "close")

#######################################
#  VisCont
#######################################  
class VisCont(object):
    """
    Application Class 
    """
    #########################################
    def __init__(self, m0=None, m1=None, m2=None, m3=None, m4=None, m5=None, m6=None, m7=None, m8=None, m9=None):
        """
        アプリケーションスタート
        @param  m0,m1,m2,m3,m4  エレメントコンテナマトリックス
        @retval 無し
        """ 
        app = wx.App()
        VisContMFrame(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9)
        app.MainLoop()


#######################################
#  SlicedData
#######################################
class SlicedData(object):
    """
     スライスデータクラス
     [inamura 100930]
    """
    #########################################
    def __init__(self,ver=1):
        """
        コンストラクタ
        @param  ver (int) indicates VisualCont or VisualCont2
        @retval 無し
        """
        if ver==1:
            # 選択されている軸
            self.axes = (0,1,2)
            # テキストボックスの設定値
            self.txts= ["1","2","3","4","5","6","7","8","9"]
            
        elif ver==2:
            self.axes = (0,1,2,2)
            self.txts= ["1","2","3","4","5","6","7","8","9","10","11","12"]
            
        # マップデータ
        self.map = None

        
if __name__ == '__main__':

     vc=VisCont()


