#!/usr/bin/env python
from __future__ import print_function
import time
import glob
import numpy
import os
import array
import struct
import getVNRConst #[inamura 180326]

_tagStrLength=16
detectorIDS={"MWPC" :{"daqID":"01","detID":"001"},
             "WLSF1":{"daqID":"01","detID":"001"},
             "WLSF2":{"daqID":"01","detID":"001"},
             "WLSF3":{"daqID":"01","detID":"001"},
             "WLSF4":{"daqID":"01","detID":"001"},
             "RPMT" :{"daqID":"01","detID":"001"},
             "TrigNET":{"daqID":"00","detID":"040"},
             "He":{"daqID":"00","detID":"000"},
             "N2":{"daqID":"00","detID":"002"},
             "0D"   :{"daqID":"00","detID":"254"},
             }
##detectorIDS={"MWPC" :{"daqID":"01","detID":"001"},
##             "WLSF1":{"daqID":"01","detID":"001"},
##             "WLSF2":{"daqID":"01","detID":"001"},
##             "WLSF3":{"daqID":"01","detID":"001"},
##             "WLSF4":{"daqID":"01","detID":"001"},
##             "RPMT" :{"daqID":"01","detID":"001"},
##             "TrigNET":{"daqID":"00","detID":"040"},
##             "0D"   :{"daqID":"00","detID":"254"},
##             }

DIOS=([[16,16]], # DIOS[0]
# unused
# 00010000 mask
# 00010000 available
# mp,pp,mm,pm
[[21,31],[22,31],[25,31],[26,31]],
#[[26,31],[22,31],[25,31],[21,31]], # DIOS[1]
# SF1/SF2
# 00011111 mask
# 00011010 on/on
# 00010110 on/off
# 00011001 off/on
# 00010101 off/off
# mp,pp,mm,pm
[[49,115],[50,115],[81,115],[82,115]],
#[[50,115],[82,115],[49,115],[81,115]])
#[[34,99],[66,99],[33,99],[65,99]]) # DIOS[2]
# SF1/SF3
# 01110011 mask
# 00110010 on/on pp
# 01010010 on/off pm
# 00110001 off/on mp
# 01010001 off/off mm
# swing add 20160401
[[5,31],[6,31],[9,31],[10,31]],
[[33,115],[34,115],[65,115],[66,115]])

offsetPID = 2
XXX="VNR"
#-------------------------------------------------------------------------------
class timeMeasurement:
    def __init__(self,tag=""):
        self.startTime=0
        self.endTime  =0
        self.tag      =tag.ljust(_tagStrLength)
    def start(self):
        self.startTime=time.time()
        if self.tag!="":print(self.tag+">> start")
    def end(self):
        self.endTime  =time.time()
        if self.tag!="":print(self.tag+">> end")
    def show(self):
        if self.tag=="":
            print(str(self.endTime-self.startTime))
        else:
            print(self.tag+">>  %0.4f sec"%(self.endTime-self.startTime))
#-------------------------------------------------------------------------------
def getFilePath(runNo,detector):
#   tm=timeMeasurement("search data path")
#   tm.start()
    runNo_format='%06d' % runNo
    #[inamura 180826]-->
    #if os.name == 'posix' :
    if os.name == 'posix' or os.name == 'nt':
        basepath = getVNRConst.GetDataDir(True)
        #<--[inamura 180826]
        searchName = os.path.join(basepath,XXX+runNo_format+"_????????")
        result=glob.glob(searchName)
        if len(result)>0:
            dname=result[0]
        else:
            print(searchName+" not found!")
            return ""
    else:
        dname=os.path.join(os.getcwd())


    if detector in ["MWPC","WLSF1","WLSF2","RPMT","0D","He","N2","TrigNET"]:
        daqId=detectorIDS[detector]["daqID"]
        detId=detectorIDS[detector]["detID"]
    else:
        print("Wrong detector name!")
        return ""

    fname=XXX+runNo_format+"_"+daqId+"_"+detId+"_???.edb"
    datapath=os.path.join(dname,fname)

    result=glob.glob(datapath)
    if len(result)>0:
        # dname=result[0]
        datapath = os.path.join(dname,result[0])
    else:
        print(datapath+" not found!")
        return ""

#   print "data file path".ljust(_tagStrLength)+">> "+datapath
#   tm.end()
#   tm.show()
    return datapath

def getFilePathNew(runNo,detector):
    """
    New in 1610 ver. (AS)
    getFilePath returns list of files matching the format.
    used in new getEventDataArray
    """
    tm=timeMeasurement("search data path")
    tm.start()
    runNo_format='%06d' % runNo
    #[inamura 180826]-->
    #if os.name == 'posix':
    if os.name == 'posix' or os.name == 'nt':
        basepath = getVNRConst.GetDataDir(True)
        #<--[inamura 180826]
        searchName = os.path.join(basepath,XXX+runNo_format+"_????????")
        result=glob.glob(searchName)
        if len(result)>0:
            dname=result[0]
        else:
            print(searchName+" not found!")
            return ""
    else:
        dname=os.path.join(os.getcwd())

    if detector in ["MWPC","WLSF1","WLSF2","RPMT","0D","He","N2","TrigNET"]:
        daqId=detectorIDS[detector]["daqID"]
        detId=detectorIDS[detector]["detID"]
    else:
        print("Wrong detector name!")
        return ""

    fname=XXX+runNo_format+"_"+daqId+"_"+detId+"_???.edb"
    datapath=os.path.join(dname,fname)

    result=sorted(glob.glob(datapath))
    if len(result)>0:
        dname=result
    else:
        print(datapath+" not found!")
        return ""

    datapath = []
    for d in result:
        print("data file path".ljust(_tagStrLength)+" >> "+d)
    tm.end()
    tm.show()
    return result

def decode_VNR_MWPC(a): # READOUT
    """
    Modified in 1610 ver. (AS)
    used struct.unpack for faster decoding.
    """
    if len(a) < 8:
	 header = '0x0'
         return header, -999
    decode = struct.unpack('8B', a)
    header = hex(decode[0])

    if header == '0xb7': # T0 data (0xb7 = 0x5b<<1|0x01)
        readout = decode[2]
        t0count = (decode[7]<<23) | (decode[6]<<15) | (decode[5]<<7) | ((decode[4]&0xFE)>>1)
        return header, readout, t0count

    elif header == '0xb5': # Neutron data (0xB5 = 0x5a<<1|0x01)
        if decode[7]^0x3f:
	    header = '0x0'
            return header, -999
        tof = (decode[3]<<16) | (decode[2]<<8) | decode[1]  #{[1,2,3]8:15}
        x  = ((decode[5] & 0x0F)<<4) | ((decode[4] & 0xF0)>>4)   #{[4,5]36:47} expired upper 4bit
        ana = (decode[7] & 0x30)>>4 #{[7]60:61}
        err = (decode[7] & 0xC0)>>6 #{[7]62:63}

        return header, tof, 255-decode[6], x, ana, err

    else:
        return header, -999

#-------------------------------------------------------------------------------
def decode_VNR_RPMT(a): # READOUT
    header = hex(ord(a[0])) #{[0]0:7}

    decode = struct.unpack('8B', a)
    header = hex(decode[0])

    if header == '0xb7': # T0 data (0xb7 = 0x5b<<1|0x01)
        readout = decode[2]
        t0count = (decode[7]<<23) | (decode[6]<<15) | (decode[5]<<7) | ((decode[4]&0xFE)>>1)
        return header, readout, t0count

    elif header == '0xb5': # Neutron data (0xB5 = 0x5a<<1|0x01)
        #print '%  ', (" ".join([hex(ord(aa)) for aa in a]))
        if (decode[7] & 0xf0)^0x30:
	    header = '0x0'
            return header, -999

        tof = (decode[3]<<16) | (decode[2]<<8) | decode[1]  #{[1,2,3]8:15}
	x =  (((decode[5] & 0xff) << 1) | (decode[4] >> 7)) #{[4,5]36:47} expired upper 4bit
        y  = (((decode[7] & 0x0f) << 5) | (decode[6] >> 3))  #{[6,7]48:60} expired upper 4bit
        ana = (decode[7] & 0x30)>>4 #{[7]60:61}
        err = (decode[7] & 0xC0)>>6 #{[7]62:63}
	if ( x > 383):
	    x = 383
	if ( y > 383):
	    y = 383
        return header, tof, x - 128, y - 128, ana, err

    else:
        return header, -999

#-------------------------------------------------------------------------------
def decode_VNR_WLSF1(a): # READOUT
    header = hex(ord(a[0])) #{[0]0:7}

    if header == '0xb7': # T0 data (0xb7 = 0x5b<<1|0x01)
        #print '&  ', (" ".join([hex(ord(aa)) for aa in a]))
        readout = long(0xFF & ord(a[2]) ) #{[2]16:23
        t0count = long(0x7FFFFFFF & (ord(a[7])<<23) | (ord(a[6])<<15) | (ord(a[5])<<7) |((ord(a[4])&0xFE)>>1)   )
        #print '&& ',readout, t0count
        return header, readout, t0count

    elif header == '0xb5': # Neutron data (0xB5 = 0x5a<<1|0x01)
        #print '%  ', (" ".join([hex(ord(aa)) for aa in a]))
        tof = long(0xFFFFFF & (ord(a[3])<<16) | (ord(a[2])<<8) | (ord(a[1])) ) #{[1,2,3]8:15}
        x   = long(0xFF & ((ord(a[5])&0x0F)<<4) | ((ord(a[4])&0xF0)>>4) )  #{[4,5]36:47} expired upper 4bit
        y   = long(0xFF & ((ord(a[6]))) ) #{[6,7]48:60} expired upper 4bit
        ana = long(0xF & ((ord(a[7])&0x30)>>4) )#{[7]60:61}
        err = long(0xF & ((ord(a[7])&0xC0)>>6) )#{[7]62:63}
        #print '%% ',tof, x, y, ana, err

        #Area1:0x00, Area2:0x40, Area3:0x80, Area4:0xC0
        if (x&0xC0)==0x00 and (y&0xC0)==0x00:
            return header, tof, long(x&0x3F), long(y&0x3F), ana, err
        else:
            return header, -999

    else:
        return header, -999
#-------------------------------------------------------------------------------
def decode_VNR_WLSF2(a): # READOUT
    header = hex(ord(a[0])) #{[0]0:7}

    if header == '0xb7': # T0 data (0xb7 = 0x5b<<1|0x01)
        #print '&  ', (" ".join([hex(ord(aa)) for aa in a]))
        readout = long(0xFF & ord(a[2]) ) #{[2]16:23
        t0count = long(0x7FFFFFFF & (ord(a[7])<<23) | (ord(a[6])<<15) | (ord(a[5])<<7) |((ord(a[4])&0xFE)>>1)   )
        #print '&& ',readout, t0count
        return header, readout, t0count

    elif header == '0xb5': # Neutron data (0xB5 = 0x5a<<1|0x01)
        #print '%  ', (" ".join([hex(ord(aa)) for aa in a]))
        tof = long(0xFFFFFF & (ord(a[3])<<16) | (ord(a[2])<<8) | (ord(a[1])) ) #{[1,2,3]8:15}
        x   = long(0xFF & ((ord(a[5])&0x0F)<<4) | ((ord(a[4])&0xF0)>>4) )  #{[4,5]36:47} expired upper 4bit
        y   = long(0xFF & ((ord(a[6]))) ) #{[6,7]48:60} expired upper 4bit
        ana = long(0xF & ((ord(a[7])&0x30)>>4) )#{[7]60:61}
        err = long(0xF & ((ord(a[7])&0xC0)>>6) )#{[7]62:63}
        #print '%% ',tof, x, y, ana, err

        #Area1:0x00, Area2:0x40, Area3:0x80, Area4:0xC0
        if (x&0xC0)==0x40 and (y&0xC0)==0x40:
            return header, tof, long(x&0x3F), long(y&0x3F), ana, err
        else:
            return header, -999

    else:
        return header, -999
#-------------------------------------------------------------------------------
def decode_VNR_WLSF3(a): # READOUT
    header = hex(ord(a[0])) #{[0]0:7}

    if header == '0xb7': # T0 data (0xb7 = 0x5b<<1|0x01)
        #print '&  ', (" ".join([hex(ord(aa)) for aa in a]))
        readout = long(0xFF & ord(a[2]) ) #{[2]16:23
        t0count = long(0x7FFFFFFF & (ord(a[7])<<23) | (ord(a[6])<<15) | (ord(a[5])<<7) |((ord(a[4])&0xFE)>>1)   )
        #print '&& ',readout, t0count
        return header, readout, t0count

    elif header == '0xb5': # Neutron data (0xB5 = 0x5a<<1|0x01)
        #print '%  ', (" ".join([hex(ord(aa)) for aa in a]))
        tof = long(0xFFFFFF & (ord(a[3])<<16) | (ord(a[2])<<8) | (ord(a[1])) ) #{[1,2,3]8:15}
        x   = long(0xFF & ((ord(a[5])&0x0F)<<4) | ((ord(a[4])&0xF0)>>4) )  #{[4,5]36:47} expired upper 4bit
        y   = long(0xFF & ((ord(a[6]))) ) #{[6,7]48:60} expired upper 4bit
        ana = long(0xF & ((ord(a[7])&0x30)>>4) )#{[7]60:61}
        err = long(0xF & ((ord(a[7])&0xC0)>>6) )#{[7]62:63}
        #print '%% ',tof, x, y, ana, err

        #Area1:0x00, Area2:0x40, Area3:0x80, Area4:0xC0
        if (x&0xC0)==0x80 and (y&0xC0)==0x80:
            return header, tof, long(x&0x3F), long(y&0x3F), ana, err
        else:
            return header, -999

    else:
        return header, -999
#-------------------------------------------------------------------------------
def decode_VNR_WLSF4(a): # READOUT
    header = hex(ord(a[0])) #{[0]0:7}

    if header == '0xb7': # T0 data (0xb7 = 0x5b<<1|0x01)
        #print '&  ', (" ".join([hex(ord(aa)) for aa in a]))
        readout = long(0xFF & ord(a[2]) ) #{[2]16:23
        t0count = long(0x7FFFFFFF & (ord(a[7])<<23) | (ord(a[6])<<15) | (ord(a[5])<<7) |((ord(a[4])&0xFE)>>1)   )
        #print '&& ',readout, t0count
        return header, readout, t0count

    elif header == '0xb5': # Neutron data (0xB5 = 0x5a<<1|0x01)
        #print '%  ', (" ".join([hex(ord(aa)) for aa in a]))
        tof = long(0xFFFFFF & (ord(a[3])<<16) | (ord(a[2])<<8) | (ord(a[1])) ) #{[1,2,3]8:15}
        x   = long(0xFF & ((ord(a[5])&0x0F)<<4) | ((ord(a[4])&0xF0)>>4) )  #{[4,5]36:47} expired upper 4bit
        y   = long(0xFF & ((ord(a[6]))) ) #{[6,7]48:60} expired upper 4bit
        ana = long(0xF & ((ord(a[7])&0x30)>>4) )#{[7]60:61}
        err = long(0xF & ((ord(a[7])&0xC0)>>6) )#{[7]62:63}
        #print '%% ',tof, x, y, ana, err

        #Area1:0x00, Area2:0x40, Area3:0x80, Area4:0xC0
        if (x&0xC0)==0xC0 and (y&0xC0)==0xC0:
            return header, tof, long(x&0x3F), long(y&0x3F), ana, err
        else:
            return header, -999

    else:
        return header, -999


#-------------------------------------------------------------------------------
def decode_VNR_TrigNET(a):
    header = hex(ord(a[0])) #{[0]0:7}
    #print header

    if header == '0x54': # Digital data
        #print '1% ', (" ".join([hex(ord(aa)) for aa in a]))
        tof = long(0xFFFFFF & (ord(a[3])<<16) | (ord(a[2])<<8) | (ord(a[1])) )#/40000000. #{[1,2,3]8:15}
        sid = long(0xFF & (ord(a[4])) )
        dio = long(0xFF & (ord(a[7])) )
        #print '2% ', tof, sid, dio
        return header, tof, sid, dio

    elif  header == '0x5b': # T0
        #print '1&  ', (" ".join([hex(ord(aa)) for aa in a]))
        crate = long(0x00 & (ord(a[1])) ) #{[1]8:15
        module = long(0x00 & (ord(a[2])) ) #{[2]16:23
        #t0count = long(0xFFFFFFFFFF & (ord(a[7])<<36) | (ord(a[6])<<24) | (ord(a[5])<<16) | (ord(a[4])<<8) | (ord(a[3])) )
        t0count = long(0xFFFFFFFFFF & (ord(a[3])<<36) | (ord(a[4])<<24) | (ord(a[5])<<16) | (ord(a[6])<<8) | (ord(a[7])) )
        #print '2& ',crate,module, t0count
        return header, crate,module, t0count

    elif  header == '0x5c': # Instrument clock
        #print '1#  ', (" ".join([hex(ord(aa)) for aa in a]))
        sec = long(0x3FFFFFFF & (ord(a[1])<<22) | (ord(a[2])<<14) | (ord(a[3])<<6) | (ord(a[4])&0x3F) ) #{[1]8:15
        subsec = long(0x7FFF & ((ord(a[4])&0xC0)>>6<<13) | (ord(a[5])<<5) | (ord(a[6])&0x1F) ) #{[2]16:23
        submsec = long(0x07FF & ((ord(a[6])&0xF8)>>5<<8) | (ord(a[7])) )
        #print '2# ', sec, subsec, submsec
        return header , sec, subsec, submsec

#-------------------------------------------------------------------------------
def processTrigNet(inputParam, dioSortingList, dio):
    """
    New in 1610 ver. (AS)
    Extracted from getEventDataArray(old)
    """

    if isinstance(inputParam,int):
        filename=getFilePath(inputParam,'TrigNET')
        print(filename)

        firstPID = -1 # local
        beginPID = -1 # local
        endPID = -1 # local

        DIO = -1 # local

        currDIO = -1 # local
        indexDIO = -1 #local

        iDIO = -1 # local
        nDIO = -1 # local
    

        #--------------------------
        f = open(filename, "rb")
        while 1:
            a=f.read(8)
            if len(a)==0:
                break
        #--------------------------
            b=decode_VNR_TrigNET(a)
            #print b

            if b[1]==-999:
                continue

            if b[0]=='0x5b':

                PID = long(b[3])
                if firstPID == -1:
                    firstPID = PID

                if DIO != -1 and (beginPID == -1 or endPID != -1) and nDIO != 0:
                    beginPID = -1
                    endPID = -1
                    nDIO = 0
                    currDIO = -1
                    indexDIO = -1
                elif DIO != -1 and (beginPID == -1 or endPID != -1) and nDIO == 0:
                    beginPID = PID
                    endPID = -1
                    nDIO = 0
                    currDIO = DIO
                    indexDIO = iDIO
                    #print '**********  Relally Begin PID: ', beginPID, endPID, currDIO, indexDIO

                elif beginPID!=-1 and  nDIO != 0:
                    endPID = PID-1
                    if endPID-beginPID-offsetPID>=0:
                        dioSortingList.append((indexDIO, beginPID-firstPID+offsetPID ,beginPID+offsetPID, endPID-beginPID-offsetPID, DIOS[dio][indexDIO][0],DIOS[dio][indexDIO][1] ))
                        #print '*** Begin-End PID:   ', beginPID,'-' ,endPID, indexDIO, currDIO, DIOS[dio][indexDIO]

            if b[0]=='0x54':
                index =0
                for dio1 in DIOS[dio]:
                    if (b[3]&dio1[1])==dio1[0]:
                        DIO=dio1[0]
                        if DIO != currDIO:
                            nDIO += 1
                            iDIO = index
                    index+=1
                    #print '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ', indexDIO, firstPID, beginPID, endPID, PID


        if beginPID != -1:
            if PID-beginPID-offsetPID>=0:
                dioSortingList.append((indexDIO, beginPID-firstPID+offsetPID ,beginPID+offsetPID, PID-beginPID-offsetPID, DIOS[dio][indexDIO][0],DIOS[dio][indexDIO][1] ))
        #--------------------------
        f.close()
        #--------------------------
    return dioSortingList

def createT0Count (dio, dioSortingList, T0Count):
    if dio == 0:
        c0=0
        for aaa in dioSortingList:
            c0+=aaa[3]+1
        T0Count.append(c0)
    elif dio != -1:
        c0=0
        c1=0
        c2=0
        c3=0
        for aaa in dioSortingList:
            if aaa[0]==0: c0+=aaa[3]+1
            if aaa[0]==1: c1+=aaa[3]+1
            if aaa[0]==2: c2+=aaa[3]+1
            if aaa[0]==3: c3+=aaa[3]+1

        T0Count.append(c0)
        T0Count.append(c1)
        T0Count.append(c2)
        T0Count.append(c3)
    return T0Count

def getEventDataArray(inputParam,detector="MWPC",pixels=(256,256),dio=-1, nT0start=0, nT0end=-1):
    """
    Modified in 1610 ver. (AS)
    used array.array to conserve memory
    """
    if nT0end == -1:
        nT0end = 2 ** 32  # nT0 end set to very large number
    tm=timeMeasurement("data read")
    tm.start()

    print("dio in getEventDataArray", dio)

    dioSortingList=[]
    if dio != -1:
        dioSortingList = processTrigNet(inputParam, dioSortingList, dio)

    T0Count = []
    T0Count = createT0Count(dio, dioSortingList, T0Count)

    if isinstance(inputParam,int):
        filelist=getFilePathNew(inputParam,detector)
    elif isinstance(inputParam,str) or isinstance(inputParam,unicode):
        filelist=glob.glob(inputParam)
    
    PX=pixels[0]
    PY=pixels[1]

    if dio == -1 or dio == 0:

        data=[[[array.array('l') for i in xrange(PX)] for j in xrange(PY)]]
    else:
        data=[[[array.array('l') for i in xrange(PX)] for j in xrange(PY)],
              [[array.array('l') for i in xrange(PX)] for j in xrange(PY)],
              [[array.array('l') for i in xrange(PX)] for j in xrange(PY)],
              [[array.array('l') for i in xrange(PX)] for j in xrange(PY)]]

    indexDIO=0
    iDIO = 0 # flag
    nDIO = 0 # count bet. each periods
    fDIO = 0 # flag for increasing an index
    nT0 = 0 # for dio=-1
    nT0Range = 0 # for T0 range

    func_name = "".join(['decode_',XXX,'_',detector])
    func = globals()[func_name]

    nT0_in_range = False # Flag if nT0 is in parameters set by option
    for filename in filelist:
        with open(filename, "rb") as f:
            #i1=0
            #i2=0

            while 1:
                a=f.read(8)
                if len(a) < 8:
                    break
                b = func(a)
                if b[1]==-999:
                    #AS Start 20160125 4 byte back for many bad data reduction.
                    f.seek(-4,1)
                    #AS End
                    continue

                if b[0]=='0xb7':
		    # nT0 range check (1610 AS)
                    nT0Range+=1
                    if nT0Range > nT0end:
                        break
                    elif nT0Range >= nT0start:
                        nT0_in_range = True
		    # nT0 range check end
                    if dio == -1:
                        nT0+=1
                    else:
                        if len(dioSortingList)==0:
                            break

                        if fDIO==1:
                            indexDIO+=1
                            nDIO = 0
                            fDIO = 0
                            if indexDIO >= len(dioSortingList):
                                break

                        PID = long(b[2])
                        #print '################### ', indexDIO, len(dioSortingList)
                        if dioSortingList[indexDIO][1]>PID:
                        #print 'before PID ', PID
                            iDIO = 0
                            nDIO = 0

                        elif dioSortingList[indexDIO][1]+dioSortingList[indexDIO][3]>=PID:
                            iDIO = 1
                            #print '*** ', PID, dioSortingList[indexDIO]

                        if dioSortingList[indexDIO][1]+dioSortingList[indexDIO][3]==PID:
                            fDIO = 1

                elif b[0] == '0xb5' and nT0_in_range: # nT0 flag check added (1610 AS)
                    if b[2]<PX and b[3]<PY:
                        if dio == -1:
                            data[0][b[3]][b[2]].append(b[1])
                        elif dio == 0:
                            if iDIO == 1:
                                nDIO+=1
                                data[0][b[3]][b[2]].append(b[1])
                        else:
                            if iDIO == 1:
                                nDIO+=1
                                data[dioSortingList[indexDIO][0]][b[3]][b[2]].append(b[1])


    if dio == -1:
        T0Count.append(nT0)

    datalist=[]

    if dio == -1 or dio == 0:
        dl = []
        dl=[[numpy.array(data[0][j][i]) for i in xrange(PX)] for j in xrange(PY)]

        datalist.append(dl)
    else:
        for k in [0,1,2,3]:
            dl = []
            dl=[[numpy.array(data[k][j][i]) for i in xrange(PX)] for j in xrange(PY)]

            datalist.append(dl)

    tm.end()
    tm.show()

    print(T0Count)
    return datalist, T0Count
#-------------------------------------------------------------------------------
def getDim2Tofs(inputParam,bininfo=(0.0,40000.0,100.0),positionRegion=None,
                detector="MWPC",pixels=(256,256)):
    if isinstance(inputParam,int):
        data = getEventDataArray(inputParam,detector,pixels)
    elif isinstance(inputParam,str) or isinstance(inputParam,unicode):
        data = getEventDataArray(inputParam,detector,pixels)
    elif isinstance(inputParam,list) or isinstance(inputParam,tuple)\
               or isinstance(inputParam,numpy.ndarray):
        data = inputParam
    else:
        return []

    tm=timeMeasurement("create histogram")
    tm.start()

    bin_ini=bininfo[0]
    bin_end=bininfo[1]
    bin_wid=bininfo[2]
    bin_num=int((bininfo[1]-bininfo[0])/bininfo[2])

    PX=pixels[0]
    PY=pixels[1]
    if positionRegion==None:
        retData=[[[] for i in xrange(PX)] for j in xrange(PY)]
        for i in xrange(PY):
            for j in xrange(PX):
                histDatas=numpy.histogram(data[i][j],
                                          bins=bin_num,
                                          normed=False,
                                          range=(bin_ini,bin_end))
                if i==0 and j==0:
                    histDataX= (histDatas[1][1:]+histDatas[1][:-1])*0.5
                histDataY= histDatas[0]
                retData[i][j]=[histDataX,histDataY]
        tm.end()
        tm.show()
        return retData
    else:
        if len(positionRegion)==2:
            roi=_getPositionList(positionRegion)
        elif len(positionRegion)>2:
            roi=positionRegion

        histDataX=numpy.zeros(bin_num)
        histDataY=numpy.zeros(bin_num)
        for (pos0,pos1) in roi:
            if 0 <= pos0 < PX and 0 <= pos1 < PY:
                histDatas=numpy.histogram(data[pos1][pos0],
                                          bins=bin_num,
                                          normed=False,
                                          range=(bin_ini,bin_end))
                histDataX =(histDatas[1][1:]+histDatas[1][:-1])*0.5
                histDataY+=histDatas[0]
            else:
                print("position parameter is invalid")

        tm.end()
        tm.show()
        return histDataX,histDataY
#-------------------------------------------------------------------------------
def getDim2Integral(inputParam,
                         timeRegion=[-numpy.inf,numpy.inf],
                         positionRegion=None,detector="MWPC"):
    if isinstance(inputParam,int):
        filename=getFilePath(inputParam,detector)
        data = getDim2Tofs(filename)
    elif isinstance(inputParam,str) or isinstance(inputParam,unicode):
        data = getDim2Tofs(inputParam)
    elif isinstance(inputParam,list) or isinstance(inputParam,tuple) \
                    or isinstance(inputParam,numpy.ndarray):
        data = inputParam
    else:
        return []

    tm=timeMeasurement("create 2d-histogram")
    tm.start()

    if positionRegion!=None:
        if len(positionRegion)==2:
            roi=_getPositionList(positionRegion)
        elif len(positionRegion)>2:
            roi=positionRegion

    tdata = data[0][0][0]
    region_min,region_max = _getIndexRegion(tdata,timeRegion[0],timeRegion[1])
    PY=len(data)
    PX=len(data[0])

    retData=[[0 for i in xrange(PX)] for j in xrange(PY)]
    if positionRegion==None:
        for i in xrange(PY):
            for j in xrange(PX):
                idata=data[i][j][1][region_min:region_max]
                retData[i][j]=numpy.sum(idata)
    else:
        for (pos0,pos1) in roi:
            if 0 <= pos0 < PX and 0 <= pos1 < PY:
                idata=data[pos1][pos0][1][region_min:region_max]
                retData[pos1][pos0]=numpy.sum(idata)

    tm.end()
    tm.show()

    return numpy.array(retData)
#-------------------------------------------------------------------------------
def getProjection(inputParam,direction="x",
                           timeRegion=[-numpy.inf,numpy.inf],
                           positionRegion=None,detector="MWPC"):
    if isinstance(inputParam,int):
        data = getDim2Integral(inputParam,timeRegion,positionRegion,detector)
    elif isinstance(inputParam,str) or isinstance(inputParam,unicode):
        data = getDim2Integral(inputParam,timeRegion,positionRegion,detector)
    elif isinstance(inputParam,list) or isinstance(inputParam,tuple)\
            or isinstance(inputParam,numpy.ndarray):
        data = inputParam
    else:
        return []

    PY=len(data)
    PX=len(data[0])

    if direction=="x" or direction=="X":
        histY=[]
        histX=numpy.arange(PX)
        for j in xrange(PX):
            val=0
            for i in xrange(PY):
                val+=data[i][j]
            histY.append(val)
        histY=numpy.array(histY)
    elif direction=="y" or direction=="Y":
        histY=[]
        histX=numpy.arange(PY)
        for i in xrange(PY):
            val=0
            for j in xrange(PX):
                val+=data[i][j]
            histY.append(val)
        histY=numpy.array(histY)

    return histX,histY
#-------------------------------------------------------------------------------
def _getPositionList(position):
    if isinstance(position[0],list) or isinstance(position[0],tuple):
        x=range(position[0][0],position[0][1]+1)
    elif isinstance(position[0],int):
        x=[position[0]]
    else:
        x=0

    if isinstance(position[1],list) or isinstance(position[1],tuple):
        y=range(position[1][0],position[1][1]+1)
    elif isinstance(position[1],int):
        y=[position[1]]
    else:
        y=0

    roi = [(i,j) for i in x for j in y]
    return roi
#-------------------------------------------------------------------------------
def _getIndexRegion(tdata,region1,region2):

    region1,region2=_swap(region1,region2)
    maxSize=len(tdata)
    region_min=maxSize-1
    for i in xrange(maxSize):
        if tdata[i]>region1:
            region_min=i
            break

    region_max=0
    for i in xrange(maxSize):
        if tdata[maxSize-i-1]<region2:
            region_max=maxSize-i-1
            break
    return region_min,region_max
#-------------------------------------------------------------------------------
def _swap(x1,x2):
    if x1>x2:
        tmp=x1
        x1=x2
        x2=tmp
    return x1,x2
#-------------------------------------------------------------------------------
def getEventDataArray0D(inputParam):
    tm=timeMeasurement("data read")
    tm.start()

    if isinstance(inputParam,int):
        filename=getFilePath(inputParam,"0D")
    elif isinstance(inputParam,str) or isinstance(inputParam,unicode):
        filename=inputParam

    f=open(filename,"rb")
    s=f.read()
    f.close()
    data=[]
    print("This data has "+str(len(s)) +" Blocks")

    initial = 0
    final   = len(s)
    for i in xrange(initial,final,8):
        if 0x5a==ord(s[i]): # neutron
            tof=long(ord(s[i+1])<<16)+(long(ord(s[i+2])<<8))+(long(ord(s[i+3])))
            data.append(tof)
    data=numpy.array(data)
    tm.end()
    tm.show()
    return data
#-------------------------------------------------------------------------------
def getDim0Tof(inputParam,bininfo=(0.0,40000.0,100.0)):
    if isinstance(inputParam,int):
        data = getEventDataArray0D(inputParam)
    elif isinstance(inputParam,str) or isinstance(inputParam,unicode):
        data = getEventDataArray0D(inputParam)
    elif isinstance(inputParam,list) or isinstance(inputParam,tuple) \
               or isinstance(inputParam,numpy.ndarray):
        data = inputParam
    else:
        return []

    tm=timeMeasurement("create histogram")
    tm.start()

    bin_ini=bininfo[0]*40.0
    bin_end=bininfo[1]*40.0
    bin_wid=bininfo[2]*40.0
    bin_num=int((bininfo[1]-bininfo[0])/bininfo[2])

    histDatas=numpy.histogram(data,
                              bins=bin_num,
                              normed=False,
                              range=(bin_ini,bin_end))

    histDataX= (histDatas[1][1:]+histDatas[1][:-1])*0.0125
    histDataY= histDatas[0]

    tm.end()
    tm.show()
    return histDataX,histDataY

if __name__ == '__main__':
    import sys

    if 3 == len(sys.argv):
        aa =getEventDataArray(int(sys.argv[1]),dio=int(sys.argv[2]))
#        aa =getEventDataArray(int(sys.argv[1]),dio=int(sys.argv[2]), nT0start=100000, nT0end=150000)
        print(aa[1])

#    aa =getEventDataArray(sys.argv[1], dio=-1, nT0end=10000)
#    print aa[1]

