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

"""Simulated region to VTC------Figure 2b"""
###############################################################################
###############################################################################
import os
import cv2
import copy
import csv
from tqdm import tqdm
import numpy as np
from skimage import transform
from scipy.stats import zscore
import pandas as pd
import scipy.signal as signal
import scipy.stats as stats
import PIL.Image as Image
import torchvision
import torchvision.transforms as transforms
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import nibabel as nib
from dipy.align.imwarp import SymmetricDiffeomorphicRegistration
from dipy.align.metrics import SSDMetric
from dipy.viz import regtools
import BrainSOM

data_transforms = {
    'train': transforms.Compose([
        transforms.RandomResizedCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize(mean = [0.485, 0.456, 0.406],
                             std = [0.229, 0.224, 0.225])]),
    'val': transforms.Compose([
        transforms.Resize(256),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize(mean = [0.485, 0.456, 0.406],
                             std = [0.229, 0.224, 0.225])])
    }
alexnet = torchvision.models.alexnet(pretrained=True)
alexnet.eval()

threshold_cohend = 0.5
HCP_data = nib.load('./HCP_S1200_997_tfMRI_ALLTASKS_level2_cohensd_hp200_s4_MSMAll.dscalar.nii')
mask = nib.load('./MMP_mpmLR32k.dlabel.nii').dataobj[0][:]
vtc_mask = np.where((mask==7)|(mask==18)|(mask==22)|(mask==127)|(mask==136)|(mask==138)|(mask==154)|(mask==163)|(mask==7+180)|(mask==18+180)|(mask==22+180)|(mask==127+180)|(mask==136+180)|(mask==138+180)|(mask==154+180)|(mask==163+180))[0]
hcp_vtc = np.zeros(91282)
hcp_vtc[vtc_mask] = 1
R_vtc_mask = np.where((mask==7)|(mask==18)|(mask==22)|(mask==127)|(mask==136)|(mask==138)|(mask==154)|(mask==163))[0]
R_hcp_vtc = np.zeros(91282)
R_hcp_vtc[R_vtc_mask] = 1
L_vtc_mask = np.where((mask==7+180)|(mask==18+180)|(mask==22+180)|(mask==127+180)|(mask==136+180)|(mask==138+180)|(mask==154+180)|(mask==163+180))[0]
L_hcp_vtc = np.zeros(91282)
L_hcp_vtc[L_vtc_mask] = 1

"""Symmetric Diffeomorphic Registration"""
###############################################################################
###############################################################################
# make dict
list_of_block = list(HCP_data.header.get_index_map(1).brain_models)
CORTEX_Left = list_of_block[0]
Dict_hcp_to_32kL = dict()
for vertex in range(CORTEX_Left.index_count):
    Dict_hcp_to_32kL[vertex] = CORTEX_Left.vertex_indices[vertex]
Dict_32kL_to_hcp = {v:k for k,v in Dict_hcp_to_32kL.items()}

list_of_block = list(HCP_data.header.get_index_map(1).brain_models)
CORTEX_Right = list_of_block[1]
Dict_hcp_to_32kR = dict()
for vertex in range(CORTEX_Right.index_count):
    Dict_hcp_to_32kR[vertex] = CORTEX_Right.vertex_indices[vertex]
Dict_32kR_to_hcp = {v:k for k,v in Dict_hcp_to_32kR.items()}

def get_Lvtc_position(plot=False):
    # geometry information
    geometry = nib.load('./S1200.L.flat.32k_fs_LR.surf.gii').darrays[0].data
    # data
    mask = nib.load('./MMP_mpmLR32k.dlabel.nii').dataobj[0][:]
    L_vtc_mask = np.where((mask==7+180)|(mask==18+180)|(mask==22+180)|(mask==127+180)|(mask==136+180)|(mask==138+180)|(mask==154+180)|(mask==163+180))[0]
    L_hcp_vtc = np.zeros(91282)
    L_hcp_vtc[L_vtc_mask] = 1
    # hcp mapping to 32K
    vtc_32K = []
    for i in np.where(L_hcp_vtc[:CORTEX_Left.index_count]==1)[0]:
        vtc_32K.append(Dict_hcp_to_32kL[i])
    position = geometry[vtc_32K][:,[0,1]]
    if plot==False:
        pass
    if plot==True:
        plt.figure()
        plt.scatter(geometry[:,0], geometry[:,1], marker='.')
        plt.scatter(position[:,0], position[:,1], marker='s')
    return position

def get_Rvtc_position(plot=False):
    # geometry information
    geometry = nib.load('./S1200.R.flat.32k_fs_LR.surf.gii').darrays[0].data
    # data
    mask = nib.load('./MMP_mpmLR32k.dlabel.nii').dataobj[0][:]
    R_vtc_mask = np.where((mask==7)|(mask==18)|(mask==22)|(mask==127)|(mask==136)|(mask==138)|(mask==154)|(mask==163))[0]
    R_hcp_vtc = np.zeros(91282)
    R_hcp_vtc[R_vtc_mask] = 1
    # hcp mapping to 32K
    vtc_32K = []
    for i in np.where(R_hcp_vtc[29696:CORTEX_Right.index_count+29696]==1)[0]:
        vtc_32K.append(Dict_hcp_to_32kR[i])
    position = geometry[vtc_32K][:,[0,1]]
    if plot==False:
        pass
    if plot==True:
        plt.figure()
        plt.scatter(geometry[:,0], geometry[:,1], marker='.')
        plt.scatter(position[:,0], position[:,1], marker='s')
    return position

def get_L_hcp_space_mask(hcp_index, threshold, plot=False):
    # geometry information
    geometry = nib.load('./S1200.L.flat.32k_fs_LR.surf.gii').darrays[0].data
    # data
    hcp_data = HCP_data.dataobj[hcp_index,:]
    hcp_data = hcp_data * L_hcp_vtc
    hcp_data = np.where(hcp_data>=threshold, 1, 0)
    # hcp mapping to 32K
    vtc_32K = []
    hcp_32K = []
    for i in np.where(L_hcp_vtc[:CORTEX_Left.index_count]==1)[0]:
        vtc_32K.append(Dict_hcp_to_32kL[i])
        hcp_32K.append(hcp_data[i])
    if plot==False:
        pass
    if plot==True:
        # plot
        plt.figure()
        plt.scatter(geometry[:,0], geometry[:,1], marker='.')
        plt.scatter(geometry[vtc_32K][:,0], geometry[vtc_32K][:,1], marker='.',
                    c=hcp_32K, cmap=plt.cm.jet)
    class_index = np.where(np.array(hcp_32K)==1)[0].tolist()
    position = []
    for i in class_index:
        position.append(geometry[vtc_32K[i]][[0,1]].tolist())
    position = np.array(position)
    value = hcp_32K
    return position, value

def get_R_hcp_space_mask(hcp_index, threshold, plot=False):
    # geometry information
    geometry = nib.load('./S1200.R.flat.32k_fs_LR.surf.gii').darrays[0].data
    # data
    hcp_data = HCP_data.dataobj[hcp_index,:]
    hcp_data = hcp_data * R_hcp_vtc
    hcp_data = np.where(hcp_data>=threshold, 1, 0)
    # hcp mapping to 32K
    vtc_32K = []
    hcp_32K = []
    for i in np.where(R_hcp_vtc[29696:CORTEX_Right.index_count+29696]==1)[0]:
        vtc_32K.append(Dict_hcp_to_32kR[i])
        hcp_32K.append(hcp_data[i+29696])
    if plot==False:
        pass
    if plot==True:
        # plot
        plt.figure()
        plt.scatter(geometry[:,0], geometry[:,1], marker='.')
        plt.scatter(geometry[vtc_32K][:,0], geometry[vtc_32K][:,1], marker='.',
                    c=hcp_32K, cmap=plt.cm.jet)
    class_index = np.where(np.array(hcp_32K)==1)[0].tolist()
    position = []
    for i in class_index:
        position.append(geometry[vtc_32K[i]][[0,1]].tolist())
    position = np.array(position)
    value = hcp_32K
    return position, value

def fill_hcp_map(position):
    round_position = []
    for v in range(position.shape[0]):
        round_position.append([np.floor(position[v,:][0]), np.floor(position[v,:][1])])
        round_position.append([np.floor(position[v,:][0]), np.ceil(position[v,:][1])])
        round_position.append([np.ceil(position[v,:][0]), np.floor(position[v,:][1])])
        round_position.append([np.ceil(position[v,:][0]), np.ceil(position[v,:][1])])
    round_position = np.array(round_position)
    return round_position

def make_moving_map(position, shift, rotation_theta, hemisphere):
    '''
    shift is a list, like [70,90]
    hemisphere is 'left' or 'right'
    '''
    round_position = fill_hcp_map(position)
    if hemisphere=='left':
        vtc_round_position = fill_hcp_map(get_Lvtc_position(plot=False))
    if hemisphere=='right':
        vtc_round_position = fill_hcp_map(get_Rvtc_position(plot=False))
    round_position[:,0] -= vtc_round_position[:,0].min()-170
    round_position[:,1] -= vtc_round_position[:,1].min()-160
    round_position = np.int0(round_position)
    moving = np.zeros((340,340))
    for pos in round_position:
        moving[pos[0],pos[1]] = 1
    moving_copy = copy.deepcopy(moving)
    it = np.nditer(moving, flags=['multi_index'])
    while not it.finished:
        for ii in range(it.multi_index[0]-1, it.multi_index[0]+2):
            for jj in range(it.multi_index[1]-1, it.multi_index[1]+2):
                if moving_copy[it.multi_index]==1:
                    moving[ii,jj] = 1
        it.iternext()
    moving = transform.rotate(moving, rotation_theta)
    pos = np.where(moving==1)
    move = np.zeros((340,340))
    move[pos[0]+shift[0], pos[1]+shift[1]] = 1
    return move

def Make_mapping_vtc2sheet(position, shift, rotation_theta, hemisphere):
    moving = make_moving_map(position, shift, rotation_theta, hemisphere)
    static = np.zeros((340,340))
    static[70:270,70:270] = 1
    dim = static.ndim
    metric = SSDMetric(dim)
    level_iters = [500, 200, 100, 50, 10]
    sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)
    mapping = sdr.optimize(static, moving)
    warped_moving = mapping.transform(moving, 'linear')
    return mapping

def Mapping_area2sheet(mapping, area_position, shift, rotation_theta, hemisphere):
    moving = make_moving_map(area_position, shift, rotation_theta, hemisphere)
    static = np.zeros((340,340))
    static[70:270,70:270] = 1
    warped_moving = mapping.transform(moving, 'linear')
    warped_moving = warped_moving[70:270,70:270]
    return warped_moving

def Mapping_som_area_2_vtc(mapping, som_area):
    '''som_area: array (200x200)'''
    moving = np.zeros((340,340))
    moving[70:270,70:270] = som_area
    vtc_area = mapping.transform_inverse(moving)
    return vtc_area

def save_warped_area_as_gii(units_in_hcp, out_dir):
    """"out_dir: .dtseries.nii"""
    data_nii = nib.load('D:\TDCNN\HCP\seg1_1_Atlas.dtseries.nii')
    img = np.tile(units_in_hcp, (245,1))
    IMG = nib.cifti2.cifti2.Cifti2Image(img, header=data_nii.header)
    nib.save(IMG, out_dir)

def Mapping_som_units_2_vtc_units(mapping, som, sigma, shift, rotation_theta, hemisphere, units):
    ''''units: [100:102,100:102]'''
    if hemisphere=='left':
        vtc = make_moving_map(get_Lvtc_position(plot=False), shift, rotation_theta, hemisphere)
    if hemisphere=='right':
        vtc = make_moving_map(get_Rvtc_position(plot=False), shift, rotation_theta, hemisphere)
    som_units = np.zeros((200,200))
    som_units[units] = 1
    moving = np.zeros((250,250))
    moving[20:220,20:220] = som_units
    vtc_units = mapping.transform_inverse(moving)
    plt.figure(figsize=(12,12))
    plt.imshow(som_units);plt.axis('off')
    plt.figure(figsize=(12,12))
    plt.imshow(vtc, alpha=1);plt.axis('off')
    plt.imshow(vtc_units, alpha=0.5, cmap='jet');plt.axis('off')
    return som_units, vtc_units

def Mapping_som_structure_constrain_2_vtc_map(mapping, som, sigma, shift, rotation_theta, hemisphere, plot_number):
    if hemisphere=='left':
        vtc = make_moving_map(get_Lvtc_position(plot=False), shift, rotation_theta, hemisphere)
    if hemisphere=='right':
        vtc = make_moving_map(get_Rvtc_position(plot=False), shift, rotation_theta, hemisphere)
    x = np.random.choice(np.arange(0,200,1), plot_number)
    y = np.random.choice(np.arange(0,200,1), plot_number)
    point_pair = zip(x,y)
    som_structure = np.zeros((200,200))
    vtc_structure_constrain = np.zeros((340,340))
    for point in point_pair:
        som_structure_constrain = som._gaussian(point,sigma)
        som_structure += som_structure_constrain
        moving = np.zeros((340,340))
        moving[70:270,70:270] = som_structure_constrain
        vtc_structure_constrain += mapping.transform_inverse(moving)
    plt.figure(figsize=(12,12))
    plt.imshow(som_structure);plt.axis('off')
    plt.figure(figsize=(12,12))
    plt.imshow(vtc, alpha=1);plt.axis('off')
    plt.imshow(vtc_structure_constrain, alpha=0.5, cmap='jet');plt.axis('off')
    fig = plt.figure(figsize=(10,8))
    ax = plt.axes(projection='3d')
    xx = np.arange(0,340,1)
    yy = -np.arange(-340,0,1)
    X, Y = np.meshgrid(xx, yy)
    surf = ax.plot_surface(X,Y,vtc_structure_constrain, cmap='jet')
    ax.set_zlim3d(0)
    fig.colorbar(surf)
    return som_structure, vtc_structure_constrain

def plot_vertex_distance(vertex_dir, hemisphere):
    if hemisphere=='left':
        geometry = nib.load('./S1200.L.flat.32k_fs_LR.surf.gii').darrays[0].data
    if hemisphere=='right':
        geometry = nib.load('./S1200.R.flat.32k_fs_LR.surf.gii').darrays[0].data
    hcp_data = nib.load(vertex_dir).darrays[0].data
    hcp_data = np.where(hcp_data>0)[0]
    plt.figure()
    plt.scatter(geometry[:,0], geometry[:,1], marker='.')
    plt.scatter(geometry[hcp_data][:,0], geometry[hcp_data][:,1], marker='.', cmap=plt.cm.jet)

def cohen_d(x1, x2):
    s1 = x1.std()
    return (x1.mean()-x2)/s1

def Functional_map_pca(som, pca, pca_index):
    class_name = ['face', 'place', 'body', 'object']
    f1 = os.listdir(".\HCP_WM\\" + 'face')
    if '.DS_Store' in f1:
        f1.remove('.DS_Store')
    f2 = os.listdir(".\HCP_WM\\" + 'place')
    if '.DS_Store' in f2:
        f2.remove('.DS_Store')
    f3 = os.listdir(".\HCP_WM\\" + 'body')
    if '.DS_Store' in f3:
        f3.remove('.DS_Store')
    f4 = os.listdir(".\HCP_WM\\" + 'object')
    if '.DS_Store' in f4:
        f4.remove('.DS_Store')
    Response = []
    for index,f in enumerate([f1,f2,f3,f4]):
        for pic in f:
            img = Image.open(".\HCP_WM\\"+class_name[index]+"\\"+pic).convert('RGB')
            picimg = data_transforms['val'](img).unsqueeze(0)
            output = alexnet(picimg).data.numpy()
            Response.append(output[0])
    Response = np.array(Response)
    Response = zscore(Response, axis=0)
    Response_som = []
    for response in Response:
        Response_som.append(1/som.activate(pca.transform(response.reshape(1,-1))[0,pca_index]))
    Response_som = np.array(Response_som)
    return Response_som[:111,:,:],Response_som[111:172,:,:],Response_som[172:250,:,:],Response_som[250:,:,:]

def som_mask(som, Response, Contrast_respense, contrast_index, threshold_cohend):
    t_map, p_map = stats.ttest_1samp(Response, Contrast_respense[contrast_index])
    mask = np.zeros((som._weights.shape[0],som._weights.shape[1]))
    Cohend_mask = np.zeros((som._weights.shape[0],som._weights.shape[1]))
    for i in range(som._weights.shape[0]):
        for j in range(som._weights.shape[1]):
            cohend = cohen_d(Response[:,i,j], Contrast_respense[contrast_index][i,j])
            if (p_map[i,j] < 0.05/40000) and (cohend>threshold_cohend):
                Cohend_mask[i,j] = cohend
                mask[i,j] = 1
    return Cohend_mask, mask

Data = np.load('.\\Data.npy')
Data = zscore(Data, axis=0)
pca = PCA()
pca.fit(Data)

som = BrainSOM.VTCSOM(200, 200, 4, sigma=6.2, learning_rate=1, neighborhood_function='gaussian')
som._weights = np.load('./som_sigma_6.2.npy')
Response_face,Response_place,Response_body,Response_object = Functional_map_pca(som, pca, pca_index=[0,1,2,3])
Contrast_respense = [np.vstack((Response_place,Response_body,Response_object)).mean(axis=0),
                     np.vstack((Response_face,Response_body,Response_object)).mean(axis=0),
                     np.vstack((Response_face,Response_place,Response_object)).mean(axis=0),
                     np.vstack((Response_face,Response_place,Response_body)).mean(axis=0)]
face_mask = som_mask(som, Response_face, Contrast_respense, 0, 0.5)
place_mask = som_mask(som, Response_place, Contrast_respense, 1, 0.5)
limb_mask = som_mask(som, Response_body, Contrast_respense, 2, 0.5)
object_mask = som_mask(som, Response_object, Contrast_respense, 3, 0.5)

shift = [70,90]
rotation_theta = 215
mapping_Left = Make_mapping_vtc2sheet(get_Lvtc_position(plot=False), shift, rotation_theta, hemisphere='left')
warped_face = Mapping_som_area_2_vtc(mapping_Left, face_mask[1])
warped_place = Mapping_som_area_2_vtc(mapping_Left, place_mask[1])
warped_limb = Mapping_som_area_2_vtc(mapping_Left, limb_mask[1])
warped_object = Mapping_som_area_2_vtc(mapping_Left, object_mask[1])

plt.figure()
plt.imshow(warped_face);plt.axis('off')
plt.figure()
plt.imshow(warped_place);plt.axis('off')
plt.figure()
plt.imshow(warped_limb);plt.axis('off')
plt.figure()
plt.imshow(warped_object);plt.axis('off')


if __name__ == '__main__':
    import sys
    from xlat import Config

    # 注意下不同文件这个路径可能不同
    Config.root = __file__ + "\\..\\..\\.."
    sys.path.append(Config.root)
    print(sys.path)

import unittest
import time

from xlat import Driver
from common.login import Login
from xlat import Log
from xlat import screenshot

#这个类是测试头像区展示及各跳转页面
class TestDriver(unittest.TestCase):

    def setUp(self):
        self.d = Driver.get_driver()

    def tearDown(self):
        pass
        # self.d.stop_server()

    def vip_account(main_func):  #装饰器，检查是否登录了会员，没有则登录
        def out(self,*args,**kwargs):
            if Login.is_logined():
                #如果已经登录，检查是否未白金会员。通过用户名检查
                account = self.d.find_element(ID="nickname.text").text()
                #print("++++++++++++++%s" %account)
                time.sleep(1)
                if account != "app51_bj...":
                    #print("++++++++++++++++account!=555555+++++++++++++++++++")
                    Login.logout()
                    Login.login("5123000073","123456")
            else:
                Login.login("5123000073","123456")
            main_func(self,*args,**kwargs)
            pass
        return out

    def ordinary_account(main_func):  #装饰器，检查是否登录普通账号，没有则登录
        def out(self,*args,**kwargs):
            if Login.is_logined():
                #如果已经登录，检查是否为普通账户。通过用户名检查
                account = self.d.find_element(ID="nickname.text").text()
                time.sleep(1)
                if account != "555555":
                    Login.logout()
                    Login.login("5123000430","123456")
            else:
                Login.login("5123000430","123456")
            main_func(self,*args,**kwargs)
            pass
        return out

    def supervip_account(main_func):  #装饰器，检查是否登录超级会员账号，没有则登录
        def out(self,*args,**kwargs):
            if Login.is_logined():
                #如果已经登录，检查是否为超级会员账户。通过用户名检查
                account = self.d.find_element(ID="nickname.text").text()
                time.sleep(1)
                if account != "哈哈`1":
                    Login.logout()
                    Login.login("paycenter029","xl123456")
            else:
                Login.login("paycenter029","xl123456")
            main_func(self,*args,**kwargs)
            pass
        return out

    def moble_account(main_func):  #装饰器，检查是否登录了绑定过手机的账号，没有则登录
        def out(self,*args,**kwargs):
            if Login.is_logined():
                #如果已经登录，检查是否为普通账户。通过用户名检查
                account = self.d.find_element(ID="nickname.text").text()
                time.sleep(1)
                if account != "手机用户158*...":
                    Login.logout()
                    Login.login("15815589318","yu111111")
            else:
                Login.login("15815589318","yu111111")
            main_func(self,*args,**kwargs)
            pass
        return out

    def closeTab(self):
        # 当在标签栏能找到关闭按钮，就点击关闭
        #for i in range(2,20):
         #   idstr = "XLBrowserApp.Tab.Header"+str(i)
          #  if self.d.find_element(ID=idstr):
           #     self.d.find_element(ID="TabHeader.Container").find_element(ID="Close.Btn").click()
        Log.info("关闭标签页中的其他标签")
        i= 20
        while self.d.find_element(ID="TabHeader.Container").find_element(ID="Close.Btn") and i:
            self.d.find_element(ID="TabHeader.Container").find_element(ID="Close.Btn").click()
            i-=1

    def display_area_layer(self):
        flag = False
        self.d.find_element(ID="normal.header.img").hover()
        if self.d.wait(ResId="bitmap.userinfopanel.bkg"):
            flag = True
        return flag

    @vip_account  #1、先检测是否登录了会员，如果没有登录则登录；2、鼠标悬浮在头像区域，会显示头像浮层
    def test_suspendInAvatar(self):
        Log.info("会员时，鼠标悬浮在头像区域")
        self.d.find_element(ID="normal.header.img").hover()
        #time.sleep(1)
        self.assertTrue(self.d.wait(ResId="bitmap.userinfopanel.bkg"))
        Log.info("鼠标悬浮后成功展示头像区浮层")
        #screenshot("鼠标悬浮后成功展示头像区浮层.png")

    @vip_account   #鼠标悬浮在昵称区域，会显示头像浮层
    def test_suspendInNickname(self):
        Log.info("会员时，鼠标悬浮在昵称区域")
        self.d.find_element(ID="online.panel").find_element(ID="nickname.text").hover()
        #time.sleep(1)
        self.assertTrue(self.d.wait(ResId="bitmap.userinfopanel.bkg"))
        Log.info("鼠标悬浮后成功展示头像区浮层")
        #screenshot("鼠标悬浮后成功展示头像区浮层.png")

    @vip_account   #鼠标悬浮在VIP按钮上，会显示头像浮层
    def test_suspendInVIPbt(self):
        Log.info("会员时，鼠标悬浮在VIP按钮区域")
        self.d.find_element(ID="online.panel").find_element(ID="viplevel.img").hover()
        #time.sleep(1)
        self.assertTrue(self.d.wait(ResId="bitmap.userinfopanel.bkg"))
        Log.info("鼠标悬浮后成功展示头像区浮层")
        #screenshot("鼠标悬浮后成功展示头像区浮层.png")

    @vip_account   #没有绑定手机的用户会展示手机图标
    def test_displayPhoneLogo(self):
        Log.info("用户没有绑定手机，会展示手机图标")
        self.d.find_element(ID="normal.header.img").hover()
        self.assertTrue(self.d.wait(ID="phone.icon.new"))
        Log.info("成功展示手机图标")
        #screenshot("鼠标悬浮后成功展示头像区浮层.png")

    @vip_account   #点击手机图标弹出绑定手机弹窗
    def test_clickPhoneLogo(self):
        Log.info("点击手机图标，展示绑定手机浮层")
        self.d.find_element(ID="normal.header.img").hover()
        time.sleep(1)
        self.d.find_element(ID="phone.icon.new").click()
        self.assertTrue(self.d.wait(Text="绑定手机"))
        Log.info("点击手机图标成功展示绑定手机浮层")
        #screenshot("成功展示绑定手机浮层.png")

    @moble_account   #已经绑定手机的用户不展示手机图标
    def test_noDisplayMobleLogo(self):
        Log.info("用户已经绑定手机，不展示手机图标")
        self.d.find_element(ID="normal.header.img").hover()
        self.assertFalse(self.d.wait(ID="phone.icon.new"))
        Log.info("没有找到手机图标")
        #screenshot("鼠标悬浮后成功展示头像区浮层.png")

    @vip_account    #点击头像浮层内头像，弹出基本资料窗口
    def test_clickAvatar(self):
        Log.info("点击浮层内头像，弹出基本资料窗口")
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        self.d.find_element(ID="xlue_tips_object_autoinstance").find_element(ID="header.img").click()
        self.assertTrue(self.d.wait(Text="基本资料"))
        Log.info("找到基本资料窗口")
        # screenshot("点击头像弹出基本资料成功.png")
        self.d.find_element(ID="item.bkg.image").click()

    @vip_account       #昵称较长时显示不全，鼠标悬浮会提示全名
    def test_nicknameTip(self):
        Log.info("鼠标悬浮在浮层内昵称，提示昵称全名")
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        self.d.find_element(ID="xlue_tips_object_autoinstance").find_element(ID="nickname.text").hover()
        self.assertTrue(self.d.wait(ID="tip.context"))
        Log.info("找到昵称全名提示")
        # screenshot("成功找到昵称全名提示.png")

    @vip_account        #会员用户昵称显示为红色
    def test_vipNicknameColor(self):
        Log.info("会员昵称显示为红色，色号为color.userpanel.nickname.vip")
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        nicknameColor =self.d.find_element(ID="xlue_tips_object_autoinstance").find_element(ID="nickname.text").get_TextColorResID()
        self.assertTrue(nicknameColor=="color.userpanel.nickname.vip")
        Log.info("会员昵称显示为红色，True")
        # screenshot("会员昵称为红色.png")

    @ordinary_account    #非会员用户昵称显示为白色
    def test_nicknameColor(self):
        Log.info("非会员昵称显示为白色，色号为color.userpanel.nickname.ex.nonvip")
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        nicknameColor = self.d.find_element(ID="xlue_tips_object_autoinstance").find_element(
            ID="nickname.text").get_TextColorResID()
        self.assertTrue(nicknameColor == "color.userpanel.nickname.ex.nonvip")
        Log.info("非会员昵称显示为白色，True")
        # screenshot("非会员昵称为白色.png")

    @vip_account    #点击头像浮层内昵称，弹出基本资料窗口
    def test_clickNickname(self):
        Log.info("点击浮层内昵称，弹出基本资料窗口")
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        self.d.find_element(ID="xlue_tips_object_autoinstance").find_element(ID="nickname.text").click()
        self.assertTrue(self.d.wait(Text="基本资料"))
        Log.info("找到基本资料窗口")
        # screenshot("点击昵称弹出基本资料成功.png")
        self.d.find_element(ID="item.bkg.image").click()

    @vip_account    #会员用户点击VIP按钮，链接到会员信息页面
    def test_clickVIPbt(self):
        Log.info("点击浮层内VIP按钮，拉起内嵌浏览器链接到会有信息页面")
        #当在标签栏能找到关闭按钮，就点击关闭
        self.closeTab()
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        #点击头像浮层内VIP按钮
        self.d.find_element(ID="xlue_tips_object_autoinstance").find_element(ID="viplevel.img").click()
        #在标签栏查找有没有迅雷会员会员信息的标签，找到则测试通过
        self.assertTrue(self.d.find_element(ID="TabHeader.Container").wait(Text="迅雷会员 会员信息"))
        Log.info("找到了会员信息标签")
        #screenshot("成功打开会员信息页面.png")
        self.closeTab()

    @ordinary_account   # 非会员用户点击置灰的VIP按钮，链接到迅雷支付页面
    def test_clickGrayVIPbt(self):
        Log.info("点击浮层内VIP按钮，拉起内嵌浏览器链接到会有信息页面")
        #当在标签栏能找到关闭按钮，就点击关闭
        self.closeTab()
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        #点击头像浮层内置灰的VIP按钮
        self.d.find_element(ID="xlue_tips_object_autoinstance").find_element(ID="viplevel.img").click()
        #在标签栏查找有没有迅雷支付中心的标签，找到则测试通过
        self.assertTrue(self.d.find_element(ID="TabHeader.Container").wait(Text="迅雷支付中心"))
        Log.info("找到了迅雷支付中心标签")
        #screenshot("成功打开迅雷支付中心页面.png")
        self.closeTab()

    @vip_account    #会员用户点击年会员按钮，链接到年费乐园页面
    def test_clickYearbt(self):
        Log.info("点击浮层内年会员按钮，拉起内嵌浏览器链接到年费乐园页面")
        #当在标签栏能找到关闭按钮，就点击关闭
        self.closeTab()
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        # 点击头像浮层内VIP按钮
        self.d.find_element(ID="xlue_tips_object_autoinstance").find_element(ID="year").click()
        # 在标签栏查找有没有迅雷会员会员信息的标签，找到则测试通过
        self.assertTrue(self.d.find_element(ID="TabHeader.Container").wait(Text="年费乐园"))
        Log.info("找到了年费乐园标签")
        # screenshot("成功打开年费乐园页面.png")
        self.closeTab()

    @ordinary_account    #非会员用户点击置灰的年会员按钮，链接到年费乐园页面
    def test_clickYearnovipbt(self):
        Log.info("点击浮层内置灰的年会员按钮，拉起内嵌浏览器链接到年费乐园页面")
        #当在标签栏能找到关闭按钮，就点击关闭
        self.closeTab()
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        # 点击头像浮层内VIP按钮
        self.d.find_element(ID="xlue_tips_object_autoinstance").find_element(ID="yearnovip").click()
        # 在标签栏查找有没有迅雷会员会员信息的标签，找到则测试通过
        self.assertTrue(self.d.find_element(ID="TabHeader.Container").wait(Text="年费乐园"))
        Log.info("找到了年费乐园标签")
        # screenshot("成功打开年费乐园页面.png")
        self.closeTab()

    @vip_account       #鼠标悬浮在浮层内等级图标上，提示等级和经验值
    def test_userLevelTip(self):
        Log.info("鼠标悬浮在浮层内等级图标上，提示等级和经验值")
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        self.d.find_element(ID="xlue_tips_object_autoinstance").find_element(ID="user.level").hover()
        self.assertTrue(self.d.find_element(ID="xlue_tips_object_autoinstance").wait(ID="tip.context"))
        Log.info("找到等级和经验值提示")
        # screenshot("成功找到等级和经验值提示.png")

    @vip_account    #点击会员等级图标，链接到迅雷个人中心_帮助中心
    def test_clickUserLevel(self):
        Log.info("点击会员等级图标，链接到迅雷个人中心_帮助中心")
        #当在标签栏能找到关闭按钮，就点击关闭
        self.closeTab()
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        # 点击头像浮层内等级图标
        self.d.find_element(ID="xlue_tips_object_autoinstance").find_element(ID="user.level").click()
        # 在标签栏查找有没有迅雷个人中心_帮助中心的标签，找到则测试通过
        self.assertTrue(self.d.find_element(ID="TabHeader.Container").wait(Text="迅雷个人中心_帮助中心"))
        Log.info("找到了迅雷个人中心_帮助中心标签")
        # screenshot("成功打开迅雷个人中心_帮助中心页面.png")
        self.closeTab()

    @vip_account       #鼠标悬浮在浮层内升级剩余活跃天数图标上，提示等升级剩余活跃天数
    def test_userUpLevelTip(self):
        Log.info("鼠标悬浮在浮层内升级剩余活跃天数图标上，提示等升级剩余活跃天数")
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        self.d.find_element(ID="xlue_tips_object_autoinstance").find_element(ID="user.uplevel").hover()
        self.assertTrue(self.d.find_element(ID="xlue_tips_object_autoinstance").wait(ID="tip.context"))
        Log.info("找到等级和经验值提示")
        # screenshot("成功找到等级和经验值提示.png")

    @vip_account    #点击升级剩余活跃天数图标，链接到迅雷个人中心_帮助中心
    def test_clickUserUpLevel(self):
        Log.info("点击升级剩余活跃天数图标，链接到迅雷个人中心_帮助中心")
        #当在标签栏能找到关闭按钮，就点击关闭
        self.closeTab()
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        # 点击头像浮层内剩余活跃天数图标
        self.d.find_element(ID="xlue_tips_object_autoinstance").find_element(ID="user.uplevel").click()
        # 在标签栏查找有没有迅雷个人中心_帮助中心的标签，找到则测试通过
        self.assertTrue(self.d.find_element(ID="TabHeader.Container").wait(Text="迅雷个人中心_帮助中心"))
        Log.info("找到了迅雷个人中心_帮助中心标签")
        # screenshot("成功打开迅雷个人中心_帮助中心页面.png")
        self.closeTab()

    @vip_account       #鼠标悬浮在全球排名上
    def test_userGlobalRankTip(self):
        Log.info("鼠标悬浮在全球排名上，提示全球排名")
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        self.d.find_element(ID="xlue_tips_object_autoinstance").find_element(ID="globalRank.num").hover()
        self.assertTrue(self.d.find_element(ID="xlue_tips_object_autoinstance").wait(ID="tip.context"))
        Log.info("找到全球排名提示")
        # screenshot("成功找到全球排名提示.png")

    @vip_account    #点击全球排名
    def test_clickUserGlobalRank(self):
        Log.info("点击全球排名图标，链接到迅雷个人中心")
        #当在标签栏能找到关闭按钮，就点击关闭
        self.closeTab()
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        # 点击头像浮层内全球排名图标
        self.d.find_element(ID="xlue_tips_object_autoinstance").find_element(ID="globalRank.num").click()
        # 在标签栏查找有没有迅雷个人中心的标签，找到则测试通过
        self.assertTrue(self.d.find_element(ID="TabHeader.Container").wait(Text="迅雷个人中心"))
        Log.info("找到了迅雷个人中心标签")
        # screenshot("成功打开迅雷个人中心页面.png")
        self.closeTab()

    @vip_account    #点击优惠券
    def test_clickCoupon(self):
        Log.info("点击优惠券图标，链接到迅雷会员-我的代金券")
        #当在标签栏能找到关闭按钮，就点击关闭
        self.closeTab()
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        # 点击头像浮层内优惠券图标
        self.d.find_element(ID="xlue_tips_object_autoinstance").find_element(ID="activity.none.btn").click()
        # 在标签栏查找有没有迅雷会员-我的代金券的标签，找到则测试通过
        self.assertTrue(self.d.find_element(ID="TabHeader.Container").wait(Text="迅雷会员-我的代金券"))
        Log.info("找到了迅雷会员-我的代金券标签")
        # screenshot("成功打开迅雷会员-我的代金券页面.png")
        self.closeTab()

    @ordinary_account    #非会员时的会员信息
    def test_novipinfoText(self):
        Log.info("非会员提示'开通会员享下载加速等32项特权'")
        #没有找到头像浮层则失败
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        # 查看头像浮层内的会员信息
        self.assertTrue(self.d.find_element(ID="xlue_tips_object_autoinstance").wait(Text="开通会员享下载加速等32项特权"))
        Log.info("找到了会员信息'开通会员享下载加速等32项特权'")
        # screenshot("成功找到非会员时的信息.png")

    @vip_account    #会员时提示到期时间
    def test_vipinfoText(self):
        Log.info("会员提示到期时间")
        #没有找到头像浮层则失败
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        # 查看头像浮层内的会员信息
        self.assertTrue(self.d.find_element(ID="xlue_tips_object_autoinstance").wait(Text="2019-03-24到期"))
        Log.info("找到了会员信息'2019-03-24到期'")
        # screenshot("成功找到会员.png")

    @ordinary_account    #非会员显示开通超级会员
    def test_supervip1(self):
        Log.info("非会员显示开通超级会员")
        #没有找到头像浮层则失败
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        # 头像浮层内找'开通超级会员'的按钮
        self.assertTrue(self.d.find_element(ID="xlue_tips_object_autoinstance").wait(Text="开通超级会员"))
        Log.info("找到了开通超级会员文案")
        # screenshot("成功找到开通超级会员按钮.png")

    @vip_account    #会员显示升级超级会员
    def test_supervip2(self):
        Log.info("会员显示升级超级会员")
        #没有找到头像浮层则失败
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        # 头像浮层内找'升级超级会员'的按钮
        self.assertTrue(self.d.find_element(ID="xlue_tips_object_autoinstance").wait(Text="升级超级会员"))
        Log.info("找到了升级超级会员按钮")
        # screenshot("成功找到开通超级会员按钮.png")

    @supervip_account    #超级会员显示续费超级会员
    def test_supervip3(self):
        Log.info("超级会员显示续费超级会员")
        #没有找到头像浮层则失败
        if not self.display_area_layer():
            Log.error("没有找到头像浮层")
            self.assertTrue(False)
            return
        # 头像浮层内找'续费超级会员'的按钮
        self.assertTrue(self.d.find_element(ID="xlue_tips_object_autoinstance").wait(Text="续费超级会员"))
        Log.info("找到了续费超级会员按钮")
        # screenshot("成功找到续费超级会员按钮.png")

    @ordinary_account   #点击左上角头像，打开会员中心页面
    def test_click_onlinepanel_avatar(self):
        Log.info("点击左上角头像，打开会员中心页面")
        #先关闭标签
        self.closeTab()
        #点击头像
        time.sleep(1)
        self.d.find_element(ID="online.panel").find_element(ID="normal.header.img").click()
        self.assertTrue(self.d.find_element(ID="TabHeader.Container").wait(Text="会员中心"))
        Log.info("找到会员中心页面")
        #screenshot("点击左上角头像打开会员中心页面.png")
        self.closeTab()

    @ordinary_account   #点击左上角昵称，打开会员中心页面
    def test_click_onlinepanel_nickname(self):
        Log.info("点击左上角昵称，打开会员中心页面")
        #先关闭标签
        self.closeTab()
        #点击头像
        time.sleep(1)
        self.d.find_element(ID="online.panel").find_element(ID="nickname.text").click()
        self.assertTrue(self.d.find_element(ID="TabHeader.Container").wait(Text="会员中心"))
        Log.info("找到会员中心页面")
        #screenshot("点击左上角昵称打开会员中心页面.png")
        self.closeTab()

    @ordinary_account   #点击会员开通按钮
    def test_click_onlinepanel_renewvip(self):
        Log.info("点击会员开通按钮")
        #先关闭标签
        self.closeTab()
        #点击头像
        time.sleep(1)
        self.d.find_element(ID="online.panel").find_element(ID="renewvip.seqimg").click()
        self.assertTrue(self.d.find_element(ID="TabHeader.Container").wait(Text="迅雷支付中心"))
        Log.info("找到迅雷支付中心页面")
        #screenshot("点击会员开通按钮打开迅雷支付中心页面.png")
        self.closeTab()

    @ordinary_account   #悬浮会员开通按钮，会提示"开通会员，老司机带你提速，请立即开通"，点击立即开通打开迅雷支付中心
    def test_click_onlinepanel_joinvip(self):
        Log.info("悬浮会员开通按钮，会提示'开通会员，老司机带你提速，请立即开通'，点击立即开通打开迅雷支付中心")
        #先关闭标签
        self.closeTab()
        #点击头像
        time.sleep(1)
        self.d.find_element(ID="online.panel").find_element(ID="renewvip.seqimg").hover()
        time.sleep(1)
        self.d.find_element(ID="online.panel").find_element(ID="joinvip.textlink").click()
        self.assertTrue(self.d.find_element(ID="TabHeader.Container").wait(Text="迅雷支付中心"))
        Log.info("找到迅雷支付中心页面")
        #screenshot("点击立即开通按钮打开迅雷支付中心页面.png")
        self.closeTab()

    @vip_account   #点击左上角vip按钮
    def test_click_onlinepanel_viplevel(self):
        Log.info("点击左上角vip按钮")
        #先关闭标签
        self.closeTab()
        #点击头像
        time.sleep(1)
        self.d.find_element(ID="online.panel").find_element(ID="viplevel.img").click()
        self.assertTrue(self.d.find_element(ID="TabHeader.Container").wait(Text="迅雷会员 会员信息"))
        Log.info("找到迅雷会员 会员信息页面")
        #screenshot("点击左上角vip按钮打开会员信息页面.png")
        self.closeTab()

    @vip_account       #鼠标悬浮在年会员按钮上
    def test_suspendyearbt(self):
        Log.info("鼠标悬浮在左上角年会员按钮上")
        self.d.find_element(ID="online.panel").find_element(ID="yearpay.img").hover()
        self.assertTrue(self.d.find_element(ID="online.panel").wait(text="迅雷年费会员"))
        Log.info("找到迅雷年费会员的提示")
        #screenshot("找到迅雷年会员提示.png")

    @vip_account   #点击左上角年会员按钮
    def test_click_onlinepanel_yearbt(self):
        Log.info("点击左上角年会员按钮")
        #先关闭标签
        self.closeTab()
        #点击头像
        time.sleep(1)
        self.d.find_element(ID="online.panel").find_element(ID="yearpay.img").click()
        self.assertTrue(self.d.find_element(ID="TabHeader.Container").wait(Text="年费乐园"))
        Log.info("找到年费乐园页面")
        #screenshot("点击左上角年会员按钮找到年费乐园页面.png")
        self.closeTab()

    @vip_account       #鼠标悬浮在小火箭上提示'升级超级会员，特权活力全开，请立即升级'，点击打开迅雷支付页面
    def test_suspendrocketbt(self):
        Log.info("鼠标悬浮在小火箭上提示'升级超级会员，特权活力全开，请立即升级'，点击打开迅雷支付页面")
        #先关闭标签页
        self.closeTab()
        time.sleep(1)
        self.d.find_element(ID="online.panel").find_element(ID="renewvip.seqimg").hover()
        time.sleep(1)
        self.d.find_element(ID="online.panel").find_element(ID="joinvip.textlink").click()
        self.assertTrue(self.d.find_element(ID="TabHeader.Container").wait(text="迅雷支付中心"))
        Log.info("找到迅雷支付中心页面")
        #screenshot("点击立即升级打开迅雷支付中心页面.png")

    @vip_account   #点击左上角小火箭按钮
    def test_click_onlinepanel_rocketbt(self):
        Log.info("点击左上角小火箭")
        #先关闭标签
        self.closeTab()
        #点击头像
        time.sleep(1)
        self.d.find_element(ID="online.panel").find_element(ID="renewvip.seqimg").click()
        self.assertTrue(self.d.find_element(ID="TabHeader.Container").wait(Text="迅雷支付中心"))
        Log.info("找到迅雷支付中心页面")
        #screenshot("点击左上角小火箭找到迅雷支付中心页面.png")
        self.closeTab()

if __name__ == '__main__':
    # unittest.main()
    # 构造测试集
    suite = unittest.TestSuite()
    #suite.addTest(TestDriver("test_suspendInAvatar"))
    #suite.addTest(TestDriver("test_suspendInNickname"))
    #suite.addTest(TestDriver("test_suspendInVIPbt"))
    #suite.addTest(TestDriver("test_displayPhoneLogo"))
    #suite.addTest(TestDriver("test_clickPhoneLogo"))
    #suite.addTest(TestDriver("test_noDisplayMobleLogo"))
    #suite.addTest(TestDriver("test_clickAvatar"))
    #suite.addTest(TestDriver("test_nicknameTip"))
    #suite.addTest(TestDriver("test_vipNicknameColor"))
    #suite.addTest(TestDriver("test_nicknameColor"))
    #suite.addTest(TestDriver("test_clickNickname"))
    #suite.addTest(TestDriver("test_clickVIPbt"))
    #suite.addTest(TestDriver("test_clickGrayVIPbt"))
    #suite.addTest(TestDriver("test_clickYearbt"))
    #suite.addTest(TestDriver("test_clickYearnovipbt"))
    #suite.addTest(TestDriver("test_userLevelTip"))   #没有调通
    #suite.addTest(TestDriver("test_clickUserLevel"))
    #suite.addTest(TestDriver("test_userUpLevelTip"))   #没有调通
    #suite.addTest(TestDriver("test_clickUserUpLevel"))
    #suite.addTest(TestDriver("test_userGlobalRankTip"))  #没有调通
    #suite.addTest(TestDriver("test_clickUserGlobalRank"))
    #suite.addTest(TestDriver("test_clickCoupon"))
    #suite.addTest(TestDriver("test_novipinfoText"))
    #suite.addTest(TestDriver("test_vipinfoText"))
    #suite.addTest(TestDriver("test_supervip1"))
    #suite.addTest(TestDriver("test_supervip2"))
    #suite.addTest(TestDriver("test_supervip3"))
    #suite.addTest(TestDriver("test_click_onlinepanel_avatar"))
    #suite.addTest(TestDriver("test_click_onlinepanel_nickname"))
    #suite.addTest(TestDriver("test_click_onlinepanel_renewvip"))
    #suite.addTest(TestDriver("test_click_onlinepanel_joinvip"))
    #suite.addTest(TestDriver("test_click_onlinepanel_viplevel"))
    #suite.addTest(TestDriver("test_suspendyearbt"))
    #suite.addTest(TestDriver("test_click_onlinepanel_yearbt"))
    suite.addTest(TestDriver("test_suspendrocketbt"))
    #suite.addTest(TestDriver("test_click_onlinepanel_rocketbt"))

    # 执行测试
    runner = unittest.TextTestRunner()
    runner.run(suite)

    # 生成HTML报告
    #from xlat.html_test_runner import HTMLTestRunner,TestRunner
    #runner=TestRunner()
    #runner.run(suite)


import serial
import json
import time
import numpy as np
import math
import re

from threading import Lock

class generic_driver_py_serial(object):

    def __init__(self, spec):
        """This driver expects to receive information on:
        port, baud rate, parity, stop bits, timeout, read/write terms"""
        self.spec = spec
        self.operations = spec.get('operations', {})
        port = spec["port"]  # Port is required and can't be generalised.
        baud = spec.get("baudrate", 9600)
        par = spec.get("parity", "NONE")
        stop_B = spec.get("stopbits", 1)
        time_out = spec.get("timeout", 0)
        self.w_term = spec.get("write_termination", '\r')
        self.r_term = spec.get("read_termination", '\r')

        self.store = {}
        self.timeout = spec.get("store_timeout", 2)

        # self.instrument = serial.Serial('COM6',
        #                                 19200,
        #                                 parity=serial.PARITY_NONE,
        #                                 stopbits=serial.STOPBITS_ONE,
        #                                 timeout=3)

        self.instrument = serial.Serial(port,
                                        baud,
                                        timeout=time_out)

        if par == "odd":
            self.instrument.parity = serial.PARITY_ODD
        elif par == "even":
            self.instrument.parity = serial.PARITY_EVEN
        elif par == "mark":
            self.instrument.parity = serial.PARITY_MARK
        elif par == "space":
            self.instrument.parity = serial.PARITY_SPACE
        else:
            self.instrument.parity = serial.PARITY_NONE

        if stop_B == "2":
            self.instrument.stopbits = serial.STOPBITS_TWO
        elif stop_B == "1.5":
            self.instrument.stopbits = serial.STOPBITS_ONE_POINT_FIVE
        else:
            self.instrument.stopbits = serial.STOPBITS_ONE

        self.lock = Lock()

    def read_instrument(self, operation_id):
        """
        read instrument
        """
        try:
            operation = self.operations[operation_id]
        except KeyError:
            print("Invalid operation")
            return float("NaN"), float("NaN")
        # datatype = operation['data_type']
        dtype = operation.get('type', "read_single")
        echo = self.spec.get('echo', False)

        stored = self.store.get(operation_id, (None, time.time() - (self.timeout + 1))) #what is this?

        if time.time() - stored[1] < self.timeout:
            data, data_trans = stored[0]
        else:
            if dtype == 'read_single':
                with self.lock:
                    # print("locK")
                    cmd_e = (operation.get('command', "")).encode("ascii") + self.w_term.encode("ascii")
                    self.instrument.write(cmd_e)
                    data = self.instrument.read_until(self.r_term)
                    floats_data = re.findall(r"([-+]?\d+(\.\d*))([eE][-+]?\d+)?", str(data))
                    try:
                        data = float(floats_data[0][0] + floats_data[0][2])
                    except IndexError:
                        data = float("NaN")

                    data_trans = self.transform(data, operation)
                # print('unlocK')
            else:
                with self.lock:
                    # print("lock")
                    print(operation.get('command', ""))
                    cmd_e = (operation.get('command', "")).encode("ascii") + self.w_term.encode("ascii")
                    self.instrument.write(cmd_e)
                    data = str(self.instrument.read_until(self.r_term))
                    print(data)
                    data = float("NaN")
                    data_trans = float("NaN")
                # print('unlock')
            self.store[operation_id] = ((data, data_trans), time.time())

        return data, data_trans

    def write_instrument(self, operation_id, values):
        with self.lock:
            """
            write instrument
            """
            # todo: check valid values for sending to instrument
            try:
                op = self.operations[operation_id]
            except KeyError:
                print("Invalid operation")
                return float("NaN"), float("NaN")
            command = op.get("command", "")
            command = command.format(*values)

            # response = self.instrument.query(command)
            cmd_e = command.encode("ascii")+self.w_term.encode("ascii")
            self.instrument.write(cmd_e)

            response = str(self.instrument.read_until(self.r_term))

            if response != "":
                print(response)
            else:
                print("No response")
            return response

    def transform(self, data, operation):
        x = data
        eq = operation.get("transform_eq", ['V', 0, 1, 0, 0])
        if self.isfloat(data):  # Check that the data can be transformed
            if eq[0] == 'T':  # Callendar-Van Dusen equation
                if np.isnan(eq[1:4]).any() or np.isinf(eq[1:4]).any() or np.isnan(x) or np.isinf(x):
                    print(f"{x} with transform {eq} is out of range.")
                    transformed = float("NaN")
                else:
                    if x < eq[4]:
                        fulltransformed = np.roots([eq[3], -100 * eq[3], eq[2], eq[1], (1 - (x / eq[4]))])
                    else:
                        fulltransformed = np.roots([eq[2], eq[1], (1 - (x / eq[4]))])
                    transformed = float("inf")  # Create a maximum value
                    for j in fulltransformed:
                        if np.imag(j) == 0:  # Remove imaginary roots
                            if abs(j) < abs(transformed):
                                transformed = np.real(j)  # Find most reasonable real root
                            elif abs(j) == transformed and j > transformed:
                                transformed = np.real(j)  # If the roots are same magnitude, give positive root
                    if math.isinf(transformed):
                        print("Invalid Callendar–Van Dusen equation: No real solutions for")
                        print(f"R = {x}, R0 = {eq[4]}, A = {eq[1]}, B = {eq[2]}, C = {eq[3]}")
                        transformed = float("NaN")
            elif eq[0] == 'V' or eq[0] == 'P':
                transformed = eq[1] + eq[2] * x + eq[3] * x ** 2 + eq[
                    4] * x ** 3  # V and P both use cubic equations. P is
                # listed purely for record keeping purposes
            else:
                print(f"Transform form not recognised: {eq[0]}")
                transformed = float("NaN")
        else:
            print(f"{x} can't be transformed.")
            transformed = float("NaN")  # The data can't be transformed
        # c = operation.get("transform_coeff", None)
        # transformed = eval(eq)
        return transformed

    def convert_to(self, data, datatype):
        if datatype == 'int':
            return int(data)
        elif datatype == 'float':
            return float(data)
        else:
            return data

    def isfloat(self, data):
        try:
            float(data)  # Checks if the string can be made into a float.
            return True
        except ValueError:
            return False
# testing
def main():
    instr = generic_driver_py_serial(json.load(open('../instruments/PC200_serial.json')))
    #print(instr.read_instrument('read_Tm'))
    print(instr.write_instrument('SS', 5))

if __name__ == '__main__':
    main()


# -*- encoding: utf-8 -*-
from parsedatetime.pdt_locales import pdtLocale_base

__all__ = [
    'pdtLocale_ptBR',
]

class pdtLocale_ptBR(pdtLocale_base):
    """
    pt_BR Locale

    """
    def __init__(self):
        super( pdtLocale_ptBR, self ).__init__()

        self.localeID     = 'pt_BR'   # don't use a unicode string
        self.dateSep      = [ '/' ]
        self.usesMeridian = False
        self.uses24       = True
        self.decimal_mark = ','

        self.Weekdays      = [ 'segunda-feira', 'ter\xe7a-feira', 'quarta-feira',
                               'quinta-feira', 'sexta-feira', 's\xe1bado', 'domingo',
                             ]
        self.shortWeekdays = [ 'seg', 'ter', 'qua',
                               'qui', 'sex', 's\xe1b', 'dom',
                             ]
        self.Months        = [ 'janeiro', 'fevereiro', 'mar\xe7o',
                               'abril', 'maio', 'junho',
                               'julho', 'agosto', 'setembro',
                               'outubro', 'novembro', 'dezembro'
                             ]
        self.shortMonths   = [ 'jan', 'fev', 'mar',
                               'abr', 'mai', 'jun',
                               'jul', 'ago', 'set',
                               'out', 'nov', 'dez'
                             ]
        self.dateFormats['full']   = "EEEE, d' de 'MMMM' de 'yyyy"
        self.dateFormats['long']   = "d' de 'MMMM' de 'yyyy"
        self.dateFormats['medium'] = "dd-MM-yy"
        self.dateFormats['short']  = "dd/MM/yyyy"

        self.timeFormats['full']   = "HH'H'mm' 'ss z"
        self.timeFormats['long']   = "HH:mm:ss z"
        self.timeFormats['medium'] = "HH:mm:ss"
        self.timeFormats['short']  = "HH:mm"

        self.dp_order = [ 'd', 'm', 'y' ]

        self.units['seconds'] = [ 'segundo', 'seg', 's']
        self.units['minutes'] = [ 'minuto', 'min',  'm']
        self.units['days']    = [ 'dia',  'dias',   'd']
        self.units['months']  = [ 'm\xeas',     'meses']