from mantid.simpleapi import *
import time
import redis
import datetime
import jsonArray
import multiprocessing
from multiprocessing import Process, Manager
import json
import numpy
#import shutil
import path
class reduction(multiprocessing.Process):
    def __init__(self, neonRedis, refreshtime, myDict, logger):
        super(reduction, self).__init__()
        self.logger=logger
        self.refreshtime=refreshtime
        self.neonRedis_write=neonRedis
        self.neonRedis_read=neonRedis
        self.myDict=myDict
        self.groupList1=['module131', 'module132', 'module133', 'module231', 'module232', 'module233']
        self.groupList2=['module322', 'module331', 'module332', 'module333', 'module341', 'module342', 'module343', 'module422', 'module431', 'module432', 'module433', 'module441', 'module442', 'module443']
        self.groupList3=['module521', 'module522', 'module523', 'module531', 'module532', 'module533', 'module541', 'module542', 'module543', 'module621', 'module622', 'module623', 'module631', 'module632', 'module633', 'module641', 'module642', 'module643']

    def get1Ddata(self, path):
        data=[]
        _json=self.neonRedis_read.get(path)
        while _json is None:
            self.logger.warning("no 1D data in data reduction"+path)
            time.sleep(5)
            _json=self.neonRedis_read.get(path)
        data=jsonArray.jsonDecoder(_json)
        #print data
        return data
    
    def getProtonCharge(self):
        data=[]
        path="/GPPD/drone/proton_charge"
        _json=self.neonRedis_read.get(path)
        if _json is None:
            return 1
        else:
            data=jsonArray.jsonDecoder(_json)
            #print data
            val=data[1][-1]
            if(type(val)==int):
                return val
            else:
                return 1
            #if val==0:
            #    return 1

 
    def mergeData(self,groupList, path):
        # merge raw I-d I-tof
        tmp1=[]
        tmp2=[]
        value1=[]
        value2=[]
        num=0
        print "start merge data in: " ,path
        for i in range(len(groupList)):
            data1=[]
            print path+"/"+groupList[i]+"/counts"
            data1=self.get1Ddata(path+"/"+groupList[i]+"/counts")
            num1=len(data1)
            print "num: ", num1
            tmp1.append(data1)
            data2=[]
            data2=self.get1Ddata(path+"/"+groupList[i]+"/intensity")
            print "num data2: ", len(data2)
            num2=len(data2)
            tmp2.append(data2)
            print groupList[i]
        for j in range(num1):
            ans1=0
            for k in range(len(groupList)):
                if not numpy.isnan(tmp1[k][j]) and numpy.isfinite(tmp1[k][j]):
                    ans1=ans1+tmp1[k][j]
                    #print "ans1: ",ans1
                else:
                    pass
            #print "ans: ",ans1," ",j
            value1.append(ans1)
        for j in range(num2):
            ans2=0
            for k in range(len(groupList)):
                if not numpy.isnan(tmp2[k][j]) and numpy.isfinite(tmp2[k][j]):
                    ans2=ans2+tmp2[k][j]
                else:
                    pass
            value2.append(ans2)
            #print "ans2: ",ans2," ",j
        print len(value1), len(value2)
        return value1, value2
        
    def setGroupData(self, groupList, groupName):
        # set raw data
        value1,value2=self.mergeData(groupList, "/GPPD/workspace/MantidData")
        print "hello1"
        x1=self.neonRedis_read.get("/GPPD/workspace/MantidData/"+groupList[0]+"/tof")
        #print jsonArray.jsonDecoder(x1)
        self.neonRedis_write.set("/GPPD/workspace/MantidData/"+groupName+"/raw/tof", x1)
        self.neonRedis_write.set("/GPPD/workspace/MantidData/"+groupName+"/reduction/PC/tof", x1)
        self.neonRedis_write.set("/GPPD/workspace/MantidData/"+groupName+"/raw/counts", jsonArray.jsonEncoder(value1))
        x2=self.neonRedis_read.get("/GPPD/workspace/MantidData/"+groupList[0]+"/d")
        self.neonRedis_write.set("/GPPD/workspace/MantidData/"+groupName+"/raw/d", x2)
        self.neonRedis_write.set("/GPPD/workspace/MantidData/"+groupName+"/reduction/PC/d", x2)
        self.neonRedis_write.set("/GPPD/workspace/MantidData/"+groupName+"/raw/intensity", jsonArray.jsonEncoder(value2))
        #print "hello3"
        #set nor data by PC
        for i in range(len(value1)):
            value1[i]=value1[i]/float(self.proton)
        self.neonRedis_write.set("/GPPD/workspace/MantidData/"+groupName+"/reduction/PC/counts", jsonArray.jsonEncoder(value1))
        for i in range(len(value2)):
            value2[i]=value2[i]/self.proton
        self.neonRedis_write.set("/GPPD/workspace/MantidData/"+groupName+"/reduction/PC/intensity", jsonArray.jsonEncoder(value2))
        print "hello4"
        #set nor data by monitor
        #value11,value22=self.mergeData(groupList, "/GPPD/workspace/MantidData/reduction")
        #x11= self.neonRedis_read.get("/GPPD/workspace/MantidData/reduction/"+groupList[0]+"/tof")
        #self.neonRedis_write.set("/GPPD/workspace/MantidData/"+groupName+"/reduction/monitor/tof", x11)
        #self.neonRedis_write.set("/GPPD/workspace/MantidData/"+groupName+"/reduction/monitor/counts", jsonArray.jsonEncoder(value11))
        
        #x22= self.neonRedis_read.get("/GPPD/workspace/MantidData/reduction/"+groupList[0]+"/d")
        #self.neonRedis_write.set("/GPPD/workspace/MantidData/"+groupName+"/reduction/monitor/d", x22)
        #self.neonRedis_write.set("/GPPD/workspace/MantidData/"+groupName+"/reduction/monitor/intensity", jsonArray.jsonEncoder(value22))
        

    def setNeutronCounts(self):
        num=0
        for name in self.groupList1:
            num+=int(json.loads(self.neonRedis_read.get("/GPPD/workspace/MantidData/"+name+"/neutroncounts")))
        for name in self.groupList2:
            num+=int(json.loads(self.neonRedis_read.get("/GPPD/workspace/MantidData/"+name+"/neutroncounts")))
        for name in self.groupList3:
            num+=int(json.loads(self.neonRedis_read.get("/GPPD/workspace/MantidData/"+name+"/neutroncounts")))
               
        self.neonRedis_write.set("/GPPD/workspace/MantidData/neutroncounts", json.dumps(num))

    def process(self):
        if self.myDict['configure']:
            self.proton=self.getProtonCharge()
            if float(self.proton) == 0.0:
                self.proton = 1
            #path.clearRedis(self.neonRedis_write)
            #pass
        else:
            pass
        
        if self.myDict['running']:
            #try:
            self.logger.debug('start running processing')
            self.setNeutronCounts()
            #print 1111
            self.setGroupData(self.groupList1,"group01")
            #print 2222
            self.setGroupData(self.groupList2,"group02")
            self.setGroupData(self.groupList3,"group03")
            self.logger.debug("finish data focussing for 3 group!")
            #except:
            #    self.myDict['error']=True
            #    self.myDict['running']=False
            #    self.myDict['configure']=False
        else:
            pass

    def run(self):
        while True:
            time.sleep(self.refreshtime)
            self.process()
    
