# coding:utf8

import sys

import cv2
import numpy as np
import math
import pytesseract
import os
from PIL import Image
from pytesseract import Output
import pytesseract
import argparse
import cv2
import imutils
import numpy as np
import easyocr

def findTextRegion(img):
    region = []

    contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    print(len(contours))
    for i in range(len(contours)):
        cnt = contours[i]
        area = cv2.contourArea(cnt)
        print(area)
        if area < 100:
            continue
        rect = cv2.minAreaRect(cnt)
        box = cv2.boxPoints(rect)
        box = np.int0(box)
        region.append(box)

    return region

def avaDir(im):
    dir_name = 'output/' + str(im)
    if not os.path.isdir(dir_name):
        os.makedirs(dir_name)
    return dir_name

# test
def cropImage(gray):
    threshold = 30
    nrowW = gray.shape[0]
    ncolH = gray.shape[1]

    row = gray[:, int(1 / 2 * nrowW)]
    col = gray[int(1 / 2 * ncolH), :]

    r_flag = np.argwhere(row > threshold)
    c_flag = np.argwhere(col > threshold)

    left, bottom, right, top = r_flag[0, 0], c_flag[-1, 0], r_flag[-1, 0], c_flag[0, 0]
    img = gray[left:right, top:bottom]
    cv2.imwrite('pro2.png', img)
    return img

def pyocr(image):
    # image = cv2.imread("test/181.png")
    h, w = image.shape[:2]
    newImg = np.ones((h, w, 3), dtype=np.uint8) * 255
    print(newImg.shape)
    print(image.shape)

    results = pytesseract.image_to_data(image, output_type=Output.DICT, lang='eng')
    print(results)

    for i in range(0, len(results["text"])):
        # extract the bounding box coordinates of the text region from the current result
        tmp_tl_x = results["left"][i]
        tmp_tl_y = results["top"][i]
        tmp_br_x = tmp_tl_x + results["width"][i]
        tmp_br_y = tmp_tl_y + results["height"][i]
        tmp_level = results["level"][i]
        conf = float(results["conf"][i])
        # print(type(conf))
        text = results["text"][i]
        if float(results["height"][i]) > float(results["width"][i]) * 2:
            continue
        if tmp_level == 4 or tmp_level == 5:
            cv2.rectangle(image, (tmp_tl_x, tmp_tl_y), (tmp_br_x, tmp_br_y - 5), (0, 0, 0), 2)
            cv2.rectangle(newImg, (tmp_tl_x, tmp_tl_y), (tmp_br_x, tmp_br_y - 5), (0, 0, 0), -1)

    # image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    cv2.imwrite("image.png", newImg)
    cv2.imwrite("imageo.png", image)
    return newImg

def resizeShape(img):
    rn = 1000
    # image height and width
    H, W = img.shape[:2]
    # Aspect ratio of the image
    ratio = float(H / W)
    # If any value is less than 1000, then image enlargement is performed
    print(ratio)
    print(W < rn)
    if min(H, W) < rn:
        if ratio >= 1:
            H1 = int(ratio * rn)
            img = cv2.resize(img, (rn, H1))
        else:
            W1 = int(rn / ratio)
            img = cv2.resize(img, (W1, rn))

    print('new img:', img.shape)
    return img

# NMS 方法（Non Maximum Suppression，非极大值抑制）
def nms(boxes, overlapThresh):
    if len(boxes) == 0:
        return []
    if boxes.dtype.kind == "i":
        boxes = boxes.astype("float")
    pick = []
    x1 = boxes[:, 0]
    y1 = boxes[:, 1]
    x2 = boxes[:, 2]
    y2 = boxes[:, 3]
    area = (x2 - x1 + 1) * (y2 - y1 + 1)
    idxs = np.argsort(y2)
    while len(idxs) > 0:
        last = len(idxs) - 1
        i = idxs[last]
        pick.append(i)
        xx1 = np.maximum(x1[i], x1[idxs[:last]])
        yy1 = np.maximum(y1[i], y1[idxs[:last]])
        xx2 = np.minimum(x2[i], x2[idxs[:last]])
        yy2 = np.minimum(y2[i], y2[idxs[:last]])
        w = np.maximum(0, xx2 - xx1 + 1)
        h = np.maximum(0, yy2 - yy1 + 1)
        overlap = (w * h) / area[idxs[:last]]
        idxs = np.delete(idxs, np.concatenate(([last], np.where(overlap > overlapThresh)[0])))
    return boxes[pick].astype("int")

def grouper(iterable, interval=2):
    prev = None
    group = []
    for item in iterable:
        if not prev or (abs(item[3] - prev[3]) <= interval):
            group.append(item)
        else:
            yield group
            group = [item]
        prev = item
    if group:
        yield group

def divideRecByAngle(rect_all):
    list = []
    list_0 = []
    list_45 = []
    list_90 = []
    for rect in rect_all:
        if (0 <= rect[2] < 10) or(90 >= rect[2] >= 80):
            list_0.append(rect)
            continue
        if 10 < rect[2] < 50:
            list_45.append(rect)
            continue
        if 50 < rect[2] < 80:
            list_90.append(rect)
            continue
    list.append(list_0)
    list.append(list_45)
    list.append(list_90)
    return list

def divideThreeImg():

    img_0 = cv2.imread('img_test_0.png')
    img_1 = cv2.imread('img_test_1.png')
    img_2 = cv2.imread('img_test_2.png')
    img_3 = cv2.imread('img_test_3.png')
    h, w = img.shape[:2]
    img_angle_all = np.ones((h, w, 3), dtype=np.uint8) * 255

    #img_0
    img_final_gray = cv2.cvtColor(img_0, cv2.COLOR_BGR2GRAY)
    ret, binary_final = cv2.threshold(img_final_gray, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV)
    contours, hierarchy = cv2.findContours(binary_final, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    bboxes_list = []
    heights = []
    for i in range(len(contours)):
        x, y, w, h = cv2.boundingRect(contours[i])
        cv2.rectangle(img_final, (x, y), (x + w, y + h), (0, 0, 0), -1)
        bboxes_list.append([x, y, x + w,
                            y + h])  # Create list of bounding boxes, with each bbox containing the left-top and right-bottom coordinates
        heights.append(h)

    cv2.imwrite('img_rec_final.png', img_final)
    # print(rect_all_final)

    heights = sorted(heights)  # Sort heights
    median_height = heights[len(heights) // 2] / 2  # Find half of the median height
    bboxes_list = sorted(bboxes_list, key=lambda k: k[3])
    combined_bboxes = grouper(bboxes_list, median_height)
    for group in combined_bboxes:
        x_min = min(group, key=lambda k: k[0])[0]  # Find min of x1
        x_max = max(group, key=lambda k: k[2])[2]  # Find max of x2
        y_min = min(group, key=lambda k: k[1])[1]  # Find min of y1
        y_max = max(group, key=lambda k: k[3])[3]  # Find max of y2
        cv2.rectangle(img_0, (x_min, y_min), (x_max, y_max), (0, 0, 0), -1)
        cv2.rectangle(img_angle_all, (x_min, y_min), (x_max, y_max), (0, 0, 0), -1)

    cv2.imwrite('img_angle_all.png', img_angle_all)

    #img_1
    img_gray2 = cv2.cvtColor(img_1, cv2.COLOR_BGR2GRAY)
    cv2.imwrite('img_gray_1.png', img_gray2)
    ret, binary_rec = cv2.threshold(img_gray2, 127, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV)
    img_1_element = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 3))
    img_1_dilate = cv2.morphologyEx(binary_rec, cv2.MORPH_DILATE, img_1_element, iterations=1)
    img_1_dilate = cv2.morphologyEx(img_1_dilate, cv2.MORPH_CLOSE, img_1_element, iterations=2)

    img_1_region = findTextRegion(img_1_dilate)
    print(img_1_region)
    for box in img_1_region:
        print(box)
        cv2.drawContours(img_1, [box], 0, (127, 0, 0), thickness=-1)
        cv2.drawContours(img_angle_all, [box], 0, (0, 0, 0), thickness=-1)

    cv2.imwrite('img_angle_all.png', img_angle_all)
    #img_2
    img_gray3 = cv2.cvtColor(img_2, cv2.COLOR_BGR2GRAY)
    cv2.imwrite('img_gray_1.png', img_gray3)
    ret, binary_rec = cv2.threshold(img_gray3, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV)
    img_2_element = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 3))
    img_2_dilate = cv2.morphologyEx(binary_rec, cv2.MORPH_DILATE, img_2_element, iterations=1)
    img_2_1 = cv2.morphologyEx(img_2_dilate, cv2.MORPH_CLOSE, img_2_element, iterations=2)
    img_2_region = findTextRegion(img_2_1)
    print(img_2_region)
    for box in img_2_region:
        print(box)
        cv2.drawContours(img_2, [box], 0, (0, 127, 70), thickness=-1)
        cv2.drawContours(img_angle_all, [box], 0, (0, 0, 0), thickness=-1)
    cv2.imwrite('img_angle_all.png', img_angle_all)
    return img_angle_all

if __name__ == '__main__':
    # img = cropImage(img)

    # im_list = ['167', 168, 169, 170, 174, 176, 180, 181, 182, 183, 184, 185, 186,187,188]
    im = '167.png'
    imagePath = 'test/' + im
    img = cv2.imread(imagePath)
    img = resizeShape(img)
    # Batch reading and generation of text line images
    dir_name = avaDir(im)
    print('img name：', im)
    print("image size：", img.shape)
    img09 = img.copy()
    img_rec = img.copy()
    # 图像预处理
    # Converting images to grayscale and removing noise using the medianBlur() method
    gray_imag = cv2.cvtColor(img09, cv2.COLOR_BGR2GRAY)

    cv2.imwrite('gray.png', gray_imag)
    cv2.imwrite('crop_image.png', img)

    # mser
    img7 = img.copy()
    mser = cv2.MSER_create()
    regions, bboxs = mser.detectRegions(gray_imag)
    hulls = [cv2.convexHull(p.reshape(-1, 1, 2)) for p in regions]
    cv2.polylines(img09, hulls, 1, (127, 0, 0))
    keep = []
    for box in bboxs:
        x, y, w, h = box
        keep.append([x, y, x + w, y + h])
        cv2.rectangle(img7,(x,y),(x+w,y+h), (127, 0, 0), 1)
    cv2.imwrite('final_mser.png', img09)
    keep2 = np.array(keep)
    cv2.imwrite('img7.png',img7)
    h, w = img.shape[:2]
    img_rec_1 = np.ones((h, w, 3), dtype=np.uint8) * 255
    for h in hulls:
        rect = cv2.minAreaRect(h)
        box = cv2.boxPoints(rect)
        box = np.int0(box)
        cv2.drawContours(img_rec, [box], 0, (127, 0, 255), 1)
        cv2.drawContours(img_rec_1, [box], 0, (0, 0, 0), -1)
    cv2.imwrite('img_rec.png', img_rec)
    cv2.imwrite('img_rec_1.png', img_rec_1)
    rect_all = []
    img_rec_gray = cv2.cvtColor(img_rec_1, cv2.COLOR_BGR2GRAY)
    ret, binary_rec = cv2.threshold(img_rec_gray, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV)
    element3 = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 1))
    element2 = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 1))

    img_rec_dilate = cv2.morphologyEx(binary_rec, cv2.MORPH_DILATE, element2, iterations=1)
    # img_rec_dilate = cv2.morphologyEx(binary_rec, cv2.MORPH_CLOSE, element3, iterations=1)
    img_rec_dilate = cv2.morphologyEx(img_rec_dilate, cv2.MORPH_ERODE, element2, iterations=1)
    img_rec_dilate = cv2.morphologyEx(img_rec_dilate, cv2.MORPH_OPEN, element3, iterations=2)

    cv2.imwrite('img_rec_dilate.png', binary_rec)
    cv2.imwrite('img_rec_dilate.png', img_rec_dilate)
    img_rec_region = findTextRegion(img_rec_dilate)
    #
    for rec in img_rec_region:
        rect = cv2.minAreaRect(rec)
        rect_all.append(rect)
        box = cv2.boxPoints(rect)
        box = np.int0(box)
        cv2.drawContours(img_rec_dilate, [box], 0, (127, 0, 255), 1)
    cv2.imwrite('img_rec_dilate_up.png', img_rec_dilate)

    img_NMS_original = img.copy()
    # final image
    h, w = img.shape[:2]
    img_NMS = np.ones((h, w, 3), dtype=np.uint8) * 255
    box_final = nms(keep2, 0.3)
    for (x, y, x1, y1) in box_final:
        # draw edges on image_NMS_original and draw and Full rectangle of the final output image_NMS
        cv2.rectangle(img_NMS_original, (x, y), (x1, y1), (255, 0, 0), 2)
        cv2.rectangle(img_NMS, (x, y), (x1, y1), (0, 0, 0), 2)
    cv2.imwrite('img_NMS_original.png', img_NMS_original)
    cv2.imwrite('img_NMS.png', img_NMS)

    q = divideRecByAngle(rect_all)
    for i in range(len(q)):
        print(q[i])

    h, w = img.shape[:2]
    img_text = np.ones((h, w, 3), dtype=np.uint8) * 255
    for i in range(len(q)):
        list = q[i]

        img_text1 = np.ones((h, w, 3), dtype=np.uint8) * 255

        print('rectangle number:', len(list))
        for l in list:
            box = cv2.boxPoints(l)
            box = np.int0(box)
            cv2.drawContours(img_text1, [box], 0, (0, 0, 0), -1)
            cv2.drawContours(img_text, [box], 0, (0, 0, 0), -1)
        # Save images in each direction
        cv2.imwrite('img_test_' + str(i) + '.png', img_text1)

        cv2.imwrite('img_test_all' + '.png', img_text)
    h, w = img.shape[:2]
    vis = np.ones((h, w, 3), dtype=np.uint8) * 255

    bboxes_list = []
    heights = []
    # 由于 输入文本主要呈现水平矩形的方式，在经过开闭操作后，如若外接矩阵的角度变化不大，可看作矩阵的书写方式呈水平，于是，可以利用同行上纵坐标的相等去分类矩形。
    # 找到现在的外接矩形
    img_final_gray = cv2.cvtColor(img_text, cv2.COLOR_BGR2GRAY)
    ret, binary_final = cv2.threshold(img_final_gray, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV)
    contours, hierarchy = cv2.findContours(binary_final, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    img_final = np.ones((h, w, 3), dtype=np.uint8) * 255
    for i in range(len(contours)):
        x, y, w, h = cv2.boundingRect(contours[i])
        cv2.rectangle(img_final, (x, y), (x + w, y + h), (0, 0, 0), -1)
        bboxes_list.append([x, y, x + w,
                            y + h])  # Create list of bounding boxes, with each bbox containing the left-top and right-bottom coordinates
        heights.append(h)

    cv2.imwrite('img_rec_final.png', img_final)
    if abs(len(rect_all)) - abs(len(q[0])) < abs(len(rect_all) // 5):
        heights = sorted(heights)  # Sort heights
        median_height = heights[len(heights) // 2] / 2  # Find half of the median height
        bboxes_list = sorted(bboxes_list, key=lambda k: k[3])
        combined_bboxes = grouper(bboxes_list, median_height)
        for group in combined_bboxes:
            x_min = min(group, key=lambda k: k[0])[0]  # Find min of x1
            x_max = max(group, key=lambda k: k[2])[2]  # Find max of x2
            y_min = min(group, key=lambda k: k[1])[1]  # Find min of y1
            y_max = max(group, key=lambda k: k[3])[3]  # Find max of y2
            cv2.rectangle(vis, (x_min, y_min), (x_max, y_max), (0, 0, 0), -1)
            cv2.rectangle(img, (x_min, y_min), (x_max, y_max), (127,0 , 0), 3)
        cv2.imwrite('vis1.png', vis)
        cv2.imwrite('img_rec1.png', img)

    else :
        img_all_angle = divideThreeImg()
        cv2.imwrite('vis1.png', img_all_angle)
        cv2.imshow('visi',img_all_angle)
        cv2.waitKey(0)
        cv2.destroyAllWindows()


import re

from datetime import tzinfo

PLACEHOLDER_PATTERN = '\{(?P<kw>[a-zA-Z]*)(?::(?P<fmt>[^}]*))?\}'

def get_dump_filename(config, database, now):
    def repl(matches):
        kw = matches.group('kw')
        if kw == 'name':
            return config['name']
        elif kw == 'hostname':
            return config['hostname']
        elif kw == 'username':
            return config['username']
        elif kw == 'database':
            return database
        elif kw == 'now':
            date = now
        elif kw == 'utcnow':
            date = now.astimezone(tzinfo('UTC'))
        else:
            raise Exception('Invalid placeholder ' + kw +
                            ' in filename pattern')

        fmt = matches.group('fmt')
        if fmt is None:
            return fmt.isoformat()
        return date.strftime(fmt)

    filename = re.sub(PLACEHOLDER_PATTERN, repl, config['filename'])
    return config['directory'] + filename

def get_dump_glob(config):
    def repl(matches):
        kw = matches.group('kw')
        if kw == 'name':
            return config['name']
        elif kw == 'hostname':
            return config['hostname']
        elif kw == 'username':
            return config['username']
        elif kw == 'database':
            return '*'
        elif kw == 'now':
            return '*'
        elif kw == 'utcnow':
            return '*'
        else:
            raise Exception('Invalid placeholder ' + kw +
                            ' in filename pattern')
    filename = re.sub(PLACEHOLDER_PATTERN, repl, config['filename'])
    return config['directory'] + filename

def get_dump_matcher(config):
    def repl(matches):
        kw = matches.group('kw')
        if kw == 'name':
            return config['name']
        elif kw == 'hostname':
            return config['hostname']
        elif kw == 'username':
            return config['username']
        elif kw == 'database':
            if repl.db_kw_present:
                return '[a-zA-Z0-9_]+'
            else:
                repl.db_kw_present = True
                return '(?P<database>[a-zA-Z0-9_]+)'
        elif kw == 'now':
            return '[^/]+'
        elif kw == 'utcnow':
            return '[^/]+'
        else:
            raise Exception('Invalid placeholder ' + kw +
                            ' in filename pattern')
    repl.db_kw_present = False
    pattern = re.sub(PLACEHOLDER_PATTERN, repl, config['filename'])
    if not repl.db_kw_present:
        raise Exception('Database name must be present in filename pattern '
                        'to allow prune')
    return re.compile(config['directory'] + pattern)


import torch
from torchvision.transforms import Normalize

# CIFAR10 dataset unnormalize as it comes out of the iter
def unnormalize_cifar10(normed):

    mean = torch.tensor([0.4914, 0.4822, 0.4465])
    std = torch.tensor([0.2023, 0.1994, 0.201])

    unnormalize = Normalize((-mean / std).tolist(), (1.0 / std).tolist())
    a = unnormalize(normed)
    a = a.transpose(0,1)
    a = a.transpose(1,2)
    a = a * 255
    b = a.clone().detach().requires_grad_(True).type(torch.uint8)

    return b

def unnormalize_femnist(normed):
    mean = torch.tensor([0.1307])
    std = torch.tensor([0.3081])

    unnormalize = Normalize((-mean / std).tolist(), (1.0 / std).tolist())
    a = unnormalize(normed)
    b = a.clone().detach().requires_grad_(True)
    return b


import pandas as pd
import numpy as np
import torch
import os
import logging, sys
from torch.utils.data import Dataset, DataLoader

from stock_language import ts_to_string, BPE, tokenize

logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)

# Dataset of ALL stocks from a particular index (ex: NASDAQ)
class StockDataset(Dataset):
    def __init__(self, data_dir, close_only=True, as_tensor=True):
        self.data_dir = data_dir
        self.paths = os.listdir(self.data_dir)
        self.close_only = close_only
        self.as_tensor = as_tensor

    def __len__(self):
        return len(self.paths)

    def __getitem__(self, idx):
        ticker_path = os.path.join(self.data_dir, self.paths[idx])
        data = pd.read_csv(ticker_path)
        if self.close_only:
            data = data.loc[:,'Close']
        if self.as_tensor:
            data = torch.tensor(data)
        else:
            data = data.to_numpy()
        return self.paths[idx].split('.')[0], data

class StockLanguageDataset(Dataset):
    def __init__(self, data_dir, preprocess=True, close_only=True, as_language=True, mini_test=False):
        self.data_dir = data_dir
        self.paths = os.listdir(self.data_dir)
        self.close_only = close_only
        self.as_language = as_language

        if mini_test:
            self.paths = self.paths[:min(5, len(self.paths))]

        if as_language:
            self.SL_strings = []
            for path in self.paths:
                ##
                logging.info(f'Processing path {path}')
                ##
                path = os.path.join(self.data_dir, path)
                data = pd.read_csv(path)

                if preprocess:
                    data = data.dropna()

                if self.close_only:
                    data = data.loc[:,'Close']
                else:
                    # operation not yet supported
                    ...

                data = ts_to_string(data)
                self.SL_strings.append(data)
        else:
            self.SL_strings = []

    def __len__(self):
        return len(self.SL_strings)

    def __getitem__(self, idx):
        return self.SL_strings[idx]

def basicSLDatasetDemo():
    nasdaq = './stock_market_data/nasdaq/csv'
    nasdaq_dataset = StockLanguageDataset(nasdaq, mini_test=True)
    nasdaq_dataloader = DataLoader(nasdaq_dataset, batch_size=1, shuffle=False)

    # need to unbatch
    SL_strings = [SL_string[0] for SL_string in nasdaq_dataloader]
    tokenizer = BPE(SL_strings, n=500)
    print(tokenizer)

def main():
    basicSLDatasetDemo()

if __name__ == '__main__':
    main()


import plotly.graph_objects as _go
from scipy import stats as _stats
import pandas as _pd
import plotly.express as _px

def _get(inputDataFrame, plotConfigData):
    fig = _go.Figure()

    x = plotConfigData["params"]["x"]
    del plotConfigData["params"]["x"]

    showFit = False
    if "trendline" in plotConfigData["params"] and plotConfigData["params"]["trendline"] == "ols":
        showFit = True
        del plotConfigData["params"]["trendline"]

    groupParams = []
    # add color and facet entries to possible data groupings
    if "color" in plotConfigData["params"]:
        groupParams.append(plotConfigData["params"]["color"])
    if "facet_row" in plotConfigData["params"]:
        groupParams.append(
            plotConfigData["params"]["facet_row"])
    if "facet_col" in plotConfigData["params"]:
        groupParams.append(
            plotConfigData["params"]["facet_col"])
    groupParams = list(set(filter(None, groupParams)))

    def getProbPlot(groupData, grouped=True):
        res = _stats.probplot(groupData[x])
        if grouped:
            return _pd.Series({"Theoretical quantiles": res[0][0], "Percent": _stats.norm.cdf(res[0][0])*100.0, x: res[0][1], "Fit": res[0][0]*res[1][0] + res[1][1]})
        else:
            return _pd.DataFrame({"Theoretical quantiles": res[0][0], "Percent": _stats.norm.cdf(res[0][0])*100.0, x: res[0][1], "Fit": res[0][0]*res[1][0] + res[1][1]})

    if len(groupParams) > 0:
        plotData = inputDataFrame.groupby(groupParams).apply(
            lambda x: getProbPlot(x)).apply(_pd.Series.explode).reset_index()
    else:
        plotData = getProbPlot(inputDataFrame, False)

    # create the output plot

    plotConfigData["params"]["hover_data"] = ["Percent"]

    scatterPlot = _px.scatter(
        plotData, y="Theoretical quantiles", x=x,  **plotConfigData["params"])
    for d in scatterPlot.data:
        fig.add_trace(d)
    if showFit:
        for d in _px.line(plotData, y="Theoretical quantiles", x="Fit", **plotConfigData["params"]).data:
            d.showlegend = False
            fig.add_trace(d)
    fig.update_layout(scatterPlot.layout)
    fig.update_yaxes(
            tickmode='array',
            tickvals=[-3.090232306, -2.326347874, -1.281551566, -0.841621234, -0.524400513, -0.253347103,
                        0, 0.253347103, 0.524400513, 0.841621234, 1.281551566, 1.644853627, 2.326347874, 3.090232306],
            ticktext=["0.1%", "1%", "10%", "20%", "30%", "40%", "50%",
                        "60%", "70%", "80%", "90%", "95%", "99%", "99.9%"]
    )

    return fig


import time
import urllib
import spotipy
from spotipy.oauth2 import SpotifyOAuth
import credetials

#Configs
SPOTIPY_CLIENT_ID = credetials.SPOTIPY_CLIENT_ID
SPOTIPY_CLIENT_SECRET = credetials.SPOTIPY_CLIENT_SECRET
SPOTIPY_REDIRECT_URI = credetials.SPOTIPY_REDIRECT_URI
SCOPE = credetials.SCOPE
DEVICE_ID = credetials.DEVICE_ID
PLY_URI = credetials.PLY_URI

#Spotify definition of authentication
spfy = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=SPOTIPY_CLIENT_ID,
                     client_secret=SPOTIPY_CLIENT_SECRET, redirect_uri=SPOTIPY_REDIRECT_URI, scope=SCOPE))

def internet_on():
    try:
        urllib.request.urlopen('http://google.com')
        return True
    except:
        return False

start_time = '09:00:00'
end_time = '20:00:00'
start_time = time.strptime(start_time, '%H:%M:%S')
end_time = time.strptime(end_time, '%H:%M:%S')

# main loop
while True:
    if not internet_on():
        print("No connection")
    else:
        now = time.localtime()
        playing = spfy.current_user_playing_track()
        if playing is None or (playing.get('is_playing') == False and playing != None):
            spfy.start_playback(device_id=DEVICE_ID, context_uri=PLY_URI)
            print("Started to play")
        if start_time <= now <= end_time:
            spfy.volume(100, device_id=DEVICE_ID)
        else:
            spfy.volume(0, device_id=DEVICE_ID)
    time.sleep(300)


import math
from multiprocessing import Pool

import numpy as np
from numpy import inf

from src.cluster.chromosome import Chromosome
from src.cluster.dm_chromosome import DMChromosome
from src.cluster.dm_population import DMPopulation
from src.cluster.population import Population
from src.common.fp import find_frequent_patterns
from src.common.utils import make_cluster_from_medoids

class ClusterSolver:
    def __init__(self, distances, Z=10, P=20, ng_arr=None, Pc=0.65, Pm=0.2, Pmb=0.05, k=None,
                 dm_size=4, dm_ng=5):
        self._distances = distances

        # Find k number based on number of customers K and
        # acceptable TSPTW subproblem size Z
        if k is None:
            K = len(distances)
            self._k = math.ceil(K / Z)
        else:
            self._k = k

        self._P = P

        if ng_arr is None:
            self._ng_arr = [25, ]
        else:
            self._ng_arr = ng_arr

        self._Pc = Pc
        self._Pm = Pm
        self._Pmb = Pmb

        self._numpy_rand = np.random.RandomState(42)

        self._dm_size = dm_size
        self._dm_ng = dm_ng
        self._dm_cur_priority_list = []

        self._dm_sup_threshold = 3
        self._dm_min_pattern_length = 3

        self._DM_MAX_PATTERNS_SEARCH = 2
        self._DM_MAX_PRIORITY_LIST_SIZE = self._k

    # параллелизм здесь внутри будет для режима data_mining
    def solve_cluster_core_data_mining(self):
        function_values = []

        # Заданное число итераций для dm режима
        global_best_res = None
        global_best_fitness = inf
        global_best_chrom = DMChromosome(self._k, self._distances, self._dm_cur_priority_list)
        for i in range(self._dm_ng):
            print("DM iteration: {}. Best fitness: {}".format(i, global_best_fitness))

            patterns = {}
            patterns_search_i = 0

            cur_best_res = None
            cur_best_fitness = None
            cur_best_chrom = None
            while patterns_search_i < self._DM_MAX_PATTERNS_SEARCH and len(patterns) == 0:
                print("DM. dm: {}, patterns_search_i: {}.".format(i, patterns_search_i))

                # Получаем список с кластерами для каждого запуска
                res, cur_best_res, cur_best_fitness, cur_best_chrom, cur_best_hist = self._make_multistart_genetic(i,
                                                                                global_best_chrom)

                function_values.extend(cur_best_hist)

                # Помещаем все кластеры из разных потоков в один глобальный список
                flatten_res = res.reshape(self._dm_size * self._k, res[0][0].shape[0])

                # запуск fp-growth для поиска лучшей хромосомы из набора res
                patterns = find_frequent_patterns(flatten_res.tolist(), self._dm_sup_threshold)
                # patterns, _ = FPGrowth.fpgrowth(flatten_res.tolist(), self._dm_sup_threshold)
                filtered_patterns = []

                for key in patterns:
                    if all(-1 != el and 0 != el for el in key):
                        filtered_patterns.append([patterns[key], list(key)])
                patterns = filtered_patterns

                # if patterns is not None:
                #     for sup, pattern in patterns:
                #         if all(-1 != el and 0 != el for el in pattern) and len(pattern) >= self._dm_min_pattern_length:
                #             filtered_patterns.append([sup, pattern])
                # patterns = filtered_patterns
                patterns.sort(key=lambda x: (x[0], len(x[1])), reverse=True)

                patterns_search_i += 1

            if len(patterns) != 0:
                for sup, pattern in patterns:
                    ind_to_replace = -1
                    for ind, item in enumerate(self._dm_cur_priority_list):
                        if pattern in item[1] and len(pattern) > len(item[1]):
                            ind_to_replace = ind
                            break

                    if ind_to_replace != -1:
                        self._dm_cur_priority_list[ind_to_replace] = pattern
                    else:
                        if len(self._dm_cur_priority_list) == self._DM_MAX_PRIORITY_LIST_SIZE:
                            self._dm_cur_priority_list[-1] = [sup, pattern]
                        else:
                            self._dm_cur_priority_list.append([sup, pattern])
                        self._dm_cur_priority_list.sort(key=lambda x: (x[0], len(x[1])), reverse=True)
            else:
                print("DM. Patterns not found.")

            if cur_best_fitness < global_best_fitness:
                global_best_res = cur_best_res
                global_best_fitness = cur_best_fitness
                global_best_chrom = cur_best_chrom

        return global_best_res, function_values

    def _make_multistart_genetic(self, dm_iter_ind, elite_chromosome):
        # Мультистарт
        rand_arr = self._numpy_rand.rand(self._dm_size, 1)
        np_rand_arr = [np.random.RandomState(int(100 * i)) for i in rand_arr]

        args = []
        for np_rand in np_rand_arr:
            dm_population = DMPopulation(self._P, self._k, self._distances, self._dm_cur_priority_list)
            current_best_chromosome, population = self._init(
                dm_population,
                elite_chromosome,
                np_rand
            )
            dm_population.chromosomes[0] = current_best_chromosome
            args.append((population, current_best_chromosome, np_rand, self._ng_arr[dm_iter_ind]))

        res = []
        cur_best_hist = []
        with Pool(self._dm_size) as p:
            result = p.starmap(self._solve, args)

            best_res = None
            best_chromosome = None
            cur_best_fitness = inf
            histories = []
            for chrom, history in result:
                clusters, _ = make_cluster_from_medoids(self._distances, self._dm_cur_priority_list, chrom.genes)
                res.append(clusters)

                if best_res is None:
                    best_res = clusters

                if chrom.fitness < cur_best_fitness:
                    cur_best_fitness = chrom.fitness
                    best_res = clusters
                    best_chromosome = chrom

                histories.append(history)

            histories = np.array(histories)
            cur_best_hist = [min([el.fitness for el in histories[:, i].tolist()]) for i in range(histories[0].size)]

        return np.array(res), best_res, cur_best_fitness, best_chromosome, cur_best_hist

    def solve(self):
        current_best_chromosome, population = self._init(Population(self._P, self._k, self._distances),
                                                         Chromosome(self._k, self._distances), self._numpy_rand)
        res_chromosome = self._solve(population, current_best_chromosome, self._numpy_rand, self._ng_arr[0])
        clusters, _ = make_cluster_from_medoids(self._distances, self._dm_cur_priority_list, res_chromosome.genes)
        return clusters

    def _solve(self, population, cur_best_chromosome, np_rand, ng):
        history = []

        self._print_current_iteration_info(0, cur_best_chromosome, population)
        history.append(cur_best_chromosome)
        for i in range(1, ng):
            population = population.selection(np_rand)
            population.crossover(self._Pc, self._Pmb, np_rand)
            population.mutate(self._Pm, np_rand)

            population.calculate_fitness()
            cur_best_chromosome = self._get_new_best_chromosome(cur_best_chromosome, population)

            self._print_current_iteration_info(i, cur_best_chromosome, population)
            history.append(cur_best_chromosome)

        return cur_best_chromosome, history

    def _init(self, population, chromosome, numpy_rand):
        population.generate_random_population(numpy_rand)
        population.calculate_fitness()
        current_best_chromosome = self._get_new_best_chromosome(chromosome, population)
        return current_best_chromosome, population

    def _print_current_iteration_info(self, i, current_best_chromosome, current_population):
        if i % 10 == 0:
            print("---------")
            print("Iteration: {}".format(i))
            print("Best chromosome fitness: {}".format(current_best_chromosome.fitness))
            # print("All chromosomes genes: {}".format(
            #     [chromosome.genes.tolist() for chromosome in current_population.chromosomes]))
            print("Best genes: {}".format(current_best_chromosome.genes))
            print("---------")

    def _get_new_best_chromosome(self, current_best_chromosome, population):
        best_chromosome_ind = population.find_best_chromosome_ind()
        best_chromosome = population.chromosomes[best_chromosome_ind]
        # print("cur fitness: {}".format(best_chromosome.fitness))
        if best_chromosome.fitness < current_best_chromosome.fitness:
            return best_chromosome
        return current_best_chromosome


import os
import cv2
import subprocess
import sys
import numpy

dirLeft  = "/Volumes/MySanDisk/mysdk/bvt_model/HumanSeg_mobile_v2_unet_8_hhl_2023-11-16_put_BackGround_before_crop"
dirMid   = "/Volumes/MySanDisk/mysdk/bvt_model/HumanSeg_mobile_v2_unet_8_hhl_2023-11-06"
dirRight = "/Volumes/MySanDisk/mysdk/bvt_model/HumanSeg_u2net_small_16_sigmoid_2023-10-09_DataClean1_Pass"
dirGT    = "/Volumes/MySanDisk/mysdk/bvt_model/val_3_mask_clip"

OUTPUT_NAME = "L_Low_Clean_2---M_Low_Clean_1---R_High_Pass"
OUTPUT_VIDEO_PATH = f"/Volumes/MySanDisk/mysdk/bvt_model/compare/{OUTPUT_NAME}_temp.mp4"
OUTPUT_VIDEO_PATH_RESIZE = f"/Volumes/MySanDisk/mysdk/bvt_model/compare/{OUTPUT_NAME}.mp4"
#OUTPUT_VIDEO_PATH = None

# if OUTPUT_VIDEO_PATH is not None and os.path.exists(OUTPUT_VIDEO_PATH):
#     raise Exception(f"{OUTPUT_VIDEO_PATH} exists")

video_file_list = [
    # "VID_1_out.mp4",
    # "VID_2_out.mp4",
    # "VID_3_out.mp4",
    # "VID_4_out.mp4",
    # "VID_5_out.mp4",
    # "back_chain_on_head_out.mp4",
    # "right_side_black_chain_out.mp4",
    # "long_hair_out.mp4",
    # "show_hand_out.mp4",
    # #"turn_around_out.mp4"

    "Chuang_out.mp4",
    "KeTing_out.mp4",
    "Office_Road_out.mp4",
    "Office_Seat_Angle_out.mp4",
    "Office_Seat_HalfBody_out.mp4",
    "Office_Seat_Postion_out.mp4",
    "YangTai_out.mp4",
]

def metric_mse(pred, true):
    #print(f"{pred.shape}, {true.shape}")  # 已经是 (1280, 720), (1280, 720)
    return ((pred - true) ** 2).mean() * 1e3

def iou_pytorch_numpy(preds, target):

    pred_cls   = preds > 0.5
    target_cls = target > 0.5

    intersection = numpy.sum(pred_cls & target_cls)
    union = numpy.sum(pred_cls | target_cls)

    iou = numpy.sum((intersection + 1e-6) / (union + 1e-6))

    return iou

def meaning(data):
    return sum(data) / len(data)

def put_text(np_img, text, postion):
    text = text
    org = postion
    fontFace = cv2.FONT_HERSHEY_SIMPLEX
    fontScale = 1
    color = (0, 255, 255)
    thickness = 2
    lineType = cv2.LINE_AA
    cv2.putText(np_img, text, org, fontFace, fontScale, color, thickness, lineType)

NUMBER_VIDEOS = len(video_file_list)
QUIT_KEY = ord('q') # 113
LEFT_KEY  = 2
RIGHT_KEY = 3
SPACE_KEY = 32

# current_index = 0
# end_flag = False
# output_video_writer = None

# while (not end_flag):

#     video_file = video_file_list[current_index]

#     # 打开源视频
#     left_video   = cv2.VideoCapture(os.path.join(dirLeft,  video_file) )
#     middle_video = cv2.VideoCapture(os.path.join(dirMid,   video_file) )
#     right_video  = cv2.VideoCapture(os.path.join(dirRight, video_file) )

#     # 获取视频帧的宽度和高度
#     frame_width  = int(left_video.get(cv2.CAP_PROP_FRAME_WIDTH))
#     frame_height = int(left_video.get(cv2.CAP_PROP_FRAME_HEIGHT))
#     frame_num    = int(left_video.get(cv2.CAP_PROP_FRAME_COUNT))

#     frame_width_m  = int(middle_video.get(cv2.CAP_PROP_FRAME_WIDTH))
#     frame_height_m = int(middle_video.get(cv2.CAP_PROP_FRAME_HEIGHT))
#     frame_num_m    = int(middle_video.get(cv2.CAP_PROP_FRAME_COUNT))

#     frame_width_r  = int(right_video.get(cv2.CAP_PROP_FRAME_WIDTH))
#     frame_height_r = int(right_video.get(cv2.CAP_PROP_FRAME_HEIGHT))
#     frame_num_r    = int(right_video.get(cv2.CAP_PROP_FRAME_COUNT))
#     print(f"file {video_file} ")
#     print(f"left_video    frame width:{frame_width}   height:{frame_height}     frame_num:{frame_num}")
#     print(f"middle_video  frame width:{frame_width_m}   height:{frame_height_m}   frame_num:{frame_num_m}")
#     print(f"right_video   frame width:{frame_width_r}   height:{frame_height_r}   frame_num:{frame_num_r}")

#     # 每个视频都清空重新计算
#     iou_list_l = []
#     mse_list_l = []
#     iou_list_m = []
#     mse_list_m = []
#     iou_list_r = []
#     mse_list_r = []

#     gt_mask_video    = None  # GT
#     left_mask_video  = None  # 左mask
#     mid_mask_video   = None  # 中mask
#     right_mask_video = None  # 右mask
#     gt_mask_name   = video_file.replace('_out', '' , 1)
#     if dirGT is not None and os.path.exists(os.path.join(dirGT, gt_mask_name)):
#         gt_mask_path = os.path.join(dirGT, gt_mask_name)
#         print(f"gt_mask_path: {gt_mask_path}")

#         mask_name = video_file.replace('_out', '_mask' , 1)
#         left_mask_path  = os.path.join(dirLeft,  mask_name)
#         mid_mask_path   = os.path.join(dirMid,   mask_name)
#         right_mask_path = os.path.join(dirRight, mask_name)
#         #print(f"left_mask_path: {left_mask_path}")

#         all_flag = True
#         all_flag = all_flag and os.path.exists(gt_mask_path)
#         all_flag = all_flag and os.path.exists(left_mask_path)
#         all_flag = all_flag and os.path.exists(mid_mask_path)
#         all_flag = all_flag and os.path.exists(right_mask_path)

#         if all_flag :
#             gt_mask_video    = cv2.VideoCapture(gt_mask_path)
#             left_mask_video  = cv2.VideoCapture(left_mask_path)
#             mid_mask_video   = cv2.VideoCapture(mid_mask_path)
#             right_mask_video = cv2.VideoCapture(right_mask_path)

#     while (True):
#         ret,  img  = left_video.read()
#         ret1, img1 = middle_video.read()
#         ret2, img2 = right_video.read()

#         # 读取mask(如果存在)
#         gt_mask    = None
#         left_mask  = None
#         mid_mask   = None
#         right_mask = None
#         ret_mask   = True
#         if gt_mask_video is not None:
#             mask_ret1, gt_mask = gt_mask_video.read()
#             mask_ret2, left_mask = left_mask_video.read()
#             mask_ret3, mid_mask = mid_mask_video.read()
#             mask_ret4, right_mask = right_mask_video.read()
#             ret_mask = mask_ret1 and mask_ret2 and mask_ret3 and  mask_ret4
#             if ret_mask:
#                 gt_mask    = gt_mask[:, :, 2] / 255.0
#                 left_mask  = left_mask[:, :, 2] / 255.0
#                 mid_mask   = mid_mask[:, :, 2] / 255.0
#                 right_mask = right_mask[:, :, 2] / 255.0 # 归一化 iou是计算>0.5 并且 训练代码计算mse的mask是在0~1

#         if not ret or not ret2 or not ret1 or not ret_mask:
#             print(f"end of video read ret={ret} ret1={ret1} ret2={ret2}")
#             # 下一个视频
#             current_index = current_index + 1
#             if (current_index >= NUMBER_VIDEOS):
#                 current_index = 0
#                 # 如果是保存到视频文件 全部文件遍历完就退出
#                 if OUTPUT_VIDEO_PATH is not None:
#                     end_flag = True
#             break

#         merged_img = cv2.hconcat([img, img1, img2])

#         if gt_mask_video is not None: # 计算每帧的mse iou和目前的平均 mse iou, 只判断一个通道
#             iou_l = iou_pytorch_numpy(gt_mask, left_mask)
#             iou_m = iou_pytorch_numpy(gt_mask, mid_mask)
#             iou_r = iou_pytorch_numpy(gt_mask, right_mask)
#             mse_l = metric_mse(gt_mask, left_mask)
#             mse_m = metric_mse(gt_mask, mid_mask)
#             mse_r = metric_mse(gt_mask, right_mask)
#             iou_list_l.append(iou_l)
#             iou_list_m.append(iou_m)
#             iou_list_r.append(iou_r)
#             mse_list_l.append(mse_l)
#             mse_list_m.append(mse_m)
#             mse_list_r.append(mse_r)
#             #print(f"iou:{iou_l:.2f},{iou_m:.2f},{iou_r:.2f};  mse:{mse_l:.2f},{mse_m:.2f},{mse_r:.2f}")
#             #print(f"mean iou:{meaning(iou_list_l):.2f},{meaning(iou_list_m):.2f},{meaning(iou_list_r):.2f}")
#             #print(f"mean mse:{meaning(mse_list_l):.2f},{meaning(mse_list_m):.2f},{meaning(mse_list_r):.2f}")
#             put_text(merged_img, f"cur   iou:{iou_l:.2f}, mse:{mse_l:.2f}",(0 , 50))
#             put_text(merged_img, f"mean iou:{meaning(iou_list_l):.2f}, mse:{meaning(mse_list_l):.2f}",(0 , 100)) # y轴需要偏移100
#             put_text(merged_img, f"cur   iou:{iou_m:.2f}, mse:{mse_m:.2f}",(img.shape[1] , 50))
#             put_text(merged_img, f"mean iou:{meaning(iou_list_m):.2f}, mse:{meaning(mse_list_m):.2f}",(img.shape[1] , 100))
#             put_text(merged_img, f"cur   iou:{iou_r:.2f}, mse:{mse_r:.2f}",(img.shape[1] * 2 , 50))
#             put_text(merged_img, f"mean iou:{meaning(iou_list_r):.2f}, mse:{meaning(mse_list_r):.2f}",(img.shape[1] * 2 , 100))
#             put_text(merged_img, f"{gt_mask_name}", (0 , 150))

#         if OUTPUT_VIDEO_PATH is not None:
#             if output_video_writer is None:
#                 fourcc = cv2.VideoWriter_fourcc(*'mp4v')
#                 print(f"out file size w:{merged_img.shape[1]} h:{merged_img.shape[0]}")
#                 output_video_writer = cv2.VideoWriter(OUTPUT_VIDEO_PATH, fourcc, 30.0, (merged_img.shape[1], merged_img.shape[0]))
#             output_video_writer.write(merged_img)
#         else:
#             cv2.imshow(OUTPUT_NAME, merged_img)
#             ######## key process begin ########
#             key = cv2.waitKey(1) & 0xFF
#             if (key != 255):
#                 print(f" key = {key}")

#             if (key == SPACE_KEY):
#                 while True:
#                     key = cv2.waitKey(1000) & 0xFF
#                     if (key == SPACE_KEY):
#                         break
#                     elif (key == QUIT_KEY):
#                         end_flag = True
#                         break
#             elif (key == QUIT_KEY):
#                 end_flag = True
#                 break
#             elif (key == LEFT_KEY):
#                 # 上一个视频
#                 current_index = current_index - 1
#                 if (current_index < 0):
#                     current_index = NUMBER_VIDEOS - 1
#                 break
#             elif (key == RIGHT_KEY):
#                 # 下一个视频
#                 current_index = current_index + 1
#                 if (current_index >= NUMBER_VIDEOS):
#                     current_index = 0
#                 break
#             ######## key process begin ########

#         # end 视频
#     left_video.release()
#     middle_video.release()
#     right_video.release()
#     # next 视频

# cv2.destroyAllWindows()

# if output_video_writer is not None: # 必须关闭文件 否则后面转换会出错 moov atom not found
#     output_video_writer.release()
# else:
#     sys.exit()

# 降低码率 视频文件大小

# 定义ffmpeg命令
command = ['ffmpeg', '-i', OUTPUT_VIDEO_PATH, '-b:v', '6M' , OUTPUT_VIDEO_PATH_RESIZE]
print(f"reduce video: {' '.join(command)}")

# 执行命令
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

# 输出结果
print(f"stdout = {result.stdout.decode()}" )
print(f"stderr = {result.stderr.decode()}" )

# 执行成功, 删除大的视频文件
if result.returncode == 0:
    print(f"reduce ok")
    #os.remove(OUTPUT_VIDEO_PATH)
else:
    print(f"[ERROR] reduce fail")

print(f"reduce done")


from typing import Dict

import pandas as pd
from tqdm import tqdm

from python import DOCUMENT_ID, SENTENCE_IDX, TOKEN_IDX, PUBLISH_DATE, TOKEN, MENTION_ID, TOKEN_IDX_FROM, TOKEN_IDX_TO, \
    MENTION_TYPE, TIMEX_CORENLP_TO_OURS
from python.common_components import CORENLP
from python.common_components.corenlp import CoreNlp
from python.handwritten_baseline import POS, MENTION_TEXT, LEMMA, TIMEX_NORMALIZED
from python.handwritten_baseline.pipeline.data.base import BaselineDataProcessorStage, MODE_EXTEND, \
    MODE_INTERSECT, MODE_REPLACE
from python.handwritten_baseline.pipeline.data.base import Dataset
from python.handwritten_baseline.pipeline.data.processing import left_join_predictions, outer_join_predictions

class CoreNlpPosNerProcessorStage(BaselineDataProcessorStage):

    def __init__(self, pos, config, config_global, logger):
        super(CoreNlpPosNerProcessorStage, self).__init__(pos, config, config_global, logger)

        if self.mode == MODE_REPLACE:
            raise ValueError(f"Mode '{MODE_REPLACE}' is not supported.")

    @staticmethod
    def _parse_document(corenlp: CoreNlp,
                        doc_tokens: pd.DataFrame,
                        publish_date: pd.datetime):
        assert doc_tokens.index.names == [DOCUMENT_ID, SENTENCE_IDX, TOKEN_IDX]
        doc_id = doc_tokens.index.get_level_values(DOCUMENT_ID).unique()[0]

        tokens = []
        time_entities = []

        is_pretokenized = True

        # if present, pass the document publish date
        doc_date = None
        if pd.notna(publish_date):
            doc_date = publish_date.strftime("%Y-%m-%dT%H:%M:%S")

        for sent_idx, sent_tokens in doc_tokens.groupby(SENTENCE_IDX):
            properties = {}

            # The correct property to pass for the document date is "date", see https://stackoverflow.com/a/46290254.
            # When using any of the ner.docdate.xxx options, the CoreNLP server restarts for every request, which is terribly slow.
            if doc_date is not None:
                properties["date"] = doc_date
            if is_pretokenized:
                properties["tokenize.whitespace"] = True
                properties["tokenize.options"] = "ptb3Escaping=false"
                properties["ssplit.eolonly"] = True

            sentence_pretokenized = sent_tokens[TOKEN].str.cat(sep=" ")
            annotations = corenlp.parse_sentence(sentence_pretokenized, properties=properties)

            # if no "sentence" was recognized, keep the span as it was
            sentences = annotations.sentence
            if not sentences:
                raise ValueError

            # CoreNLP might tell us there is more than 1 sentence in the given string. We ignore that and trust our own
            # previously applied sentence tokenization. Therefore, tokens are counted across the corenlp sentence boundaries
            # here.
            sent_tokens = []
            token_idx = 0
            mentions = []
            sent_temporal_mentions = []

            for sentence in sentences:
                for token in sentence.token:
                    word, pos, lemma = token.word, token.pos, token.lemma
                    sent_tokens.append({TOKEN_IDX: token_idx, TOKEN: word, POS: pos, LEMMA: lemma})
                    token_idx += 1
                for mention in sentence.mentions:
                    _type, text = mention.entityType, mention.entityMentionText

                    row = {MENTION_TYPE: _type,
                           MENTION_TEXT: text,
                           TOKEN_IDX_FROM: int(mention.tokenStartInSentenceInclusive),
                           TOKEN_IDX_TO: int(mention.tokenEndInSentenceExclusive)}

                    # specific handling for temporal mentions
                    if _type in TIMEX_CORENLP_TO_OURS.keys():
                        # skip any non-timex mentions
                        if not mention.HasField("timex"):
                            continue

                        # update mention type and keep normalized TIMEX if we can get it
                        row[MENTION_TYPE] = TIMEX_CORENLP_TO_OURS[mention.timex.type]
                        if mention.HasField("normalizedNER"):
                            row[TIMEX_NORMALIZED] = mention.normalizedNER
                        sent_temporal_mentions.append(row)
                    else:
                        mentions.append(row)

            # add document id and sentence idx to each row
            for row in sent_tokens:
                row[DOCUMENT_ID] = doc_id
                row[SENTENCE_IDX] = sent_idx
            tokens += sent_tokens

            for row in sent_temporal_mentions:
                row[DOCUMENT_ID] = doc_id
                row[SENTENCE_IDX] = sent_idx
            time_entities += sent_temporal_mentions

        # combine tokens and mention info into new dataframes
        tokens = pd.DataFrame(tokens).set_index([DOCUMENT_ID, SENTENCE_IDX, TOKEN_IDX]).sort_index()

        # turn the index into [DOCUMENT_ID, MENTION_ID]
        if time_entities:
            time_entities_reindexed = []
            for doc_id, df in pd.DataFrame(time_entities).groupby(DOCUMENT_ID):
                temp = df.reset_index(drop=True).reset_index().rename(columns={"index": MENTION_ID})
                time_entities_reindexed.append(temp)
            time_entities = pd.concat(time_entities_reindexed).set_index([DOCUMENT_ID, MENTION_ID]).sort_index()
        else:
            time_entities = None

        return tokens, time_entities

    def _process_dataset(self,
                         dataset: Dataset,
                         live_objects: Dict) -> Dataset:
        corenlp = live_objects[CORENLP]

        # data is pre-tokenized, but run in through CoreNLP one more time for POS and named entities
        self.logger.info("Performing POS-tagging and NER")
        tokens = []
        time_entities = []

        for doc_id, doc_tokens in tqdm(dataset.tokens.groupby(level=[DOCUMENT_ID]),
                                                               desc="Parsing documents",
                                                               total=len(dataset.documents),
                                                               mininterval=10):
            # if present, pass the document publish date
            publish_date = pd.NaT
            if PUBLISH_DATE in dataset.documents.columns:
                publish_date = dataset.documents.loc[dataset.documents[DOCUMENT_ID] == doc_id, PUBLISH_DATE].item()

            doc_tokens, doc_time_entities = self._parse_document(corenlp, doc_tokens, publish_date)
            tokens.append(doc_tokens)
            if doc_time_entities is not None:
                time_entities.append(doc_time_entities)

        tokens = pd.concat(tokens).sort_index()
        time_entities = pd.concat(time_entities).sort_index()
        time_entities = time_entities.loc[time_entities[TIMEX_NORMALIZED].notna()]

        # add pos and lemma to each token in the dataset
        dataset.tokens = dataset.tokens.merge(tokens[[POS, LEMMA]], left_index=True, right_index=True)

        if dataset.mentions_time is None:
            dataset.mentions_time = time_entities
        else:
            # Common task for MODE_EXTEND and MODE_INTERSECT: perform left-join: keep all gold entity annotations,
            # but add information from CoreNLP output
            columns_keep_system = time_entities.columns.drop([TOKEN_IDX_FROM, TOKEN_IDX_TO, SENTENCE_IDX, MENTION_TYPE])
            dataset.mentions_time = left_join_predictions(dataset.mentions_time, time_entities, dataset.mentions_time.columns, columns_keep_system)

            if self.mode == MODE_INTERSECT:
                self.logger.info("Intersected new annotations with dataset from previous pipeline stages.")
            elif self.mode == MODE_EXTEND:
                self.logger.info("Extending set of temporal expressions in dataset with the ones found by CoreNLP")

                mentions_time_to_add = outer_join_predictions(time_entities, dataset).copy()
                dataset.mentions_time = pd.concat([dataset.mentions_time, mentions_time_to_add]).sort_index()

        # add mention text for later
        def get_mention_text_from_mention(row: pd.Series) -> str:
            return " ".join(dataset.tokens.loc[(row.name[0], row[SENTENCE_IDX], slice(row[TOKEN_IDX_FROM], row[TOKEN_IDX_TO] - 1)), TOKEN].values)
        dataset.mentions_time[MENTION_TEXT] = dataset.mentions_time.apply(get_mention_text_from_mention, axis=1)
        return dataset

component = CoreNlpPosNerProcessorStage


import discord
from discord.ext import commands
import requests

_carbon_url = "https://carbonnowsh.herokuapp.com/"

def code_to_url(code: str) -> str:
    return f"{_carbon_url}?&code={trim_url(encode_url(code))}"

class Carbon(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.command()
    async def carbonate(self, ctx, *, code):

        carbon_url = code_to_url(code)
        r = requests.get(carbon_url)

        b = BytesIO(r.content)
        await ctx.send(file=discord.File(fp=b, filename="code.png"))

async def setup(bot):
    await bot.add_cog(Carbon(bot))


from django.shortcuts import render
from common.models import Navbar, Info, Motto, Friends, Images, Categories, Valine
from .models import Articles
from django.utils.html import escape
from django.shortcuts import get_object_or_404
import random, markdown
import commonmark

# Create your views here.

def articles(request, id):

    # 初始化变量
    pre_flag = 0
    pre_article = 0
    next_article = 0
    context = {}

    navbar =  Navbar.objects.all()
    info = Info.objects.first()
    all_articles = Articles.objects.all().order_by('-id')
    article = get_object_or_404(Articles, id=id)

    # 当前文章访问量
    article.total_views += 1
    article.save(update_fields=['total_views'])

    # 获得上下篇文章
    for i in all_articles:
        if pre_flag == 0 and i.id < id:
            pre_article = get_object_or_404(Articles, id=i.id)
            pre_flag += 1
        if i.id > id:
            next_article = get_object_or_404(Articles, id=i.id)

    # markdown渲染
    md = markdown.Markdown(
        extensions=[
            'markdown.extensions.extra',
            'markdown.extensions.toc',
        ]
    )
    SS = md.convert(article.content)
    article.content = commonmark.commonmark(article.content)
    context['Navbar'] = navbar
    context['Info'] = info
    context['article'] = article
    context['tob'] = md.toc
    context['next_article'] = next_article
    context['pre_article'] = pre_article
    context['Valine'] = Valine.objects.first()

    return render(request, 'article.html',context)

def category(request,id):

    context = {}
    navbar = Navbar.objects.all()
    info = Info.objects.first()
    categories = Categories.objects.all()
    images = Images.objects.all()
    category = get_object_or_404(Categories,id=id)
    articles = category.articles_set.all().order_by("-created_time")
    if images:
        num = random.randint(0, len(images) - 1)
        context['header_img'] = images[num]

    context['Navbar'] = navbar
    context['Info'] = info
    context['categories'] = categories
    context['articles'] = articles
    context['category_name'] = category.name

    return render(request, 'category.html', context)

def categories(request):
    context = {}
    navbar = Navbar.objects.all()
    info = Info.objects.first()
    categories = Categories.objects.all()
    images = Images.objects.all()
    if images:
        num = random.randint(0, len(images) - 1)
        context['header_img'] = images[num]

    context['Navbar'] = navbar
    context['Info'] = info
    context['categories'] = categories

    return render(request, 'classify.html', context)


#!/usr/bin/env python3

import re
import time
import argparse
import subprocess

from collections import namedtuple

import boto3
import arrow
import dateparser

from marshmallow import Schema, fields, post_load

class ObjectSchema(Schema):
    @post_load
    def make_obj(self, data):
        return namedtuple(
            re.sub(r'Schema$', '', self.__class__.__name__),
            data.keys()
        )(**data)

class EventSchema(ObjectSchema):
    timestamp = fields.Function(deserialize=lambda x: int(x/1000))
    message = fields.String()
    eventId = fields.String()

class FilterResponseSchema(ObjectSchema):
    events = fields.List(fields.Nested(EventSchema))

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--log-group', required=True)
    parser.add_argument('--profile', default="default")
    parser.add_argument('--start-time', default="now")
    parser.add_argument('--poll-freq', type=int, default=5)

    args = parser.parse_args()

    aws_session = boto3.Session(profile_name=args.profile)
    logs = aws_session.client('logs')

    start_time = int(dateparser.parse(args.start_time).timestamp())

    seen = set()
    while True:
        resp = logs.filter_log_events(
            logGroupName=args.log_group,
            startTime=start_time * 1000,
        )

        schema = FilterResponseSchema()
        resp = schema.load(resp).data
        for event in resp.events:
            if event.eventId in seen:
                continue
            seen.add(event.eventId)
            msg = event.message
            while msg.endswith('\n'):
                msg = msg[:-1]
            print(
                arrow.get(event.timestamp).to('local').isoformat(),
                msg,
            )
            if event.timestamp > start_time:
                start_time = event.timestamp

        start_time -= 1
        time.sleep(args.poll_freq)

if __name__ == "__main__":
    main()


import numpy as np
import matplotlib.pyplot as plt
import pickle

def load_agent_data(dir):
    return pickle.load(open(f"{dir}/sess_data.p", 'rb'))

agent_data = load_agent_data('/home/tzhang/Dropbox/Caltech/VisionLab/RL/Neuro/RL_Neuro/data/analysis/experiment_50/sess_0')

import pdb; pdb.set_trace()
state_action_log = agent_data.state_act_history_trials

def analyze_agent_novel_states_visited(state_action_log, truncate = 2000):
    all_agents_sameconfig = []
    for trial_data in state_action_log:
        one_agent_novel_states = []
        visited_states = set()
        for bout in trial_data: # each episode is one bout
            for state, _, _, in bout:
                visited_states.add(state)
                one_agent_novel_states.append(len(visited_states))
            # +1 at end because terminal state not counted
            one_agent_novel_states.append(one_agent_novel_states[-1])
        all_agents_sameconfig.append(one_agent_novel_states)

    if any(np.array([len(states) for states in all_agents_sameconfig]) < truncate):
        print(f'* Issue: at least one agent does not have enough data (<{truncate} nodes)')
        import pdb; pdb.set_trace()
    else:
        # trim each trial, and find variance / SD
        data_for_averaging = []
        for agent_data in all_agents_sameconfig:
            data_for_averaging.append(agent_data[:truncate])
        # compute variance
        var = np.std(data_for_averaging, axis = 0)
        avg = np.average(data_for_averaging, axis = 0)
        plt.figure()
        x = [i for i in range(truncate)]
        color = 'C0'
        plt.fill_between(x, avg - var, avg + var, facecolor = color, alpha = 0.3)
        plt.plot(avg, color = color)
        plt.savefig('/media/tzhang/Tony_WD_4TB_2/5_maze_v4/B_animals_reward/analysis/test2.png',
                    bbox_inches = 'tight', )

analyze_agent_novel_states_visited(state_action_log)


from . import views
from django.urls import path
app_name = 'User'

urlpatterns = [
    path('register/',views.index,name='register'),
    path('login/',views.login1,name='login'),
    path('logout/',views.logout1,name='logout'),
    path('reply/',views.reply,name='reply')
]


#/////////////////////////#
#   import dependencies   #
#/////////////////////////#

import numpy as np
import pandas as pd
from datetime import datetime
import pandas_datareader as dr
import pandas_datareader.data as web
from matplotlib import pyplot as plt
import seaborn as sns

import plotly.graph_objects as go
import plotly.express as px

import tensorflow as tf

import IPython
import IPython.display

#/////////////////////////#
#        Formatting       #
#/////////////////////////#

sns.set(style='darkgrid', context='paper', palette='Dark2')
sns.despine()

#/////////////////////////#
#        Timestamps       #
#/////////////////////////#

start_date = datetime(2017,10,8)
end_date = datetime(2020,10,8)

months = ["August","September","October"]
months_timestamp = [datetime(2020,i,1)for i in range(8,11)]

#/////////////////////////#
#    select tickers       #
#/////////////////////////#

# Market symbols for our stocks
tickers = ["MSFT","INTC","AMZN","AAPL","GOOG","TSLA","NFLX","PBW","ZM","LVGO","PLUG","NVDA"]

num_symbols = len(tickers)

#/////////////////////////#
#        load data        #
#/////////////////////////#

# GET data using pandas datareader via yahoo finance API
stock_data = web.DataReader([symbol for symbol in tickers], 'yahoo', start_date, end_date)

# stock_data.to_csv('stock_dat.csv')

# stock_data = pd.read_csv('stock_dat.csv')

#//////////////////////////#
#        preprocess        #
#//////////////////////////#

# Drop extra index
stock_data = stock_data.droplevel(level = 'Symbols',axis = 1)

# Drop Adjusted Close and Dates(keep the dates in a seperate Series)
# reindex
stock_data.reset_index(inplace = True)
# pop dates
dates = stock_data.pop('Date')
# drop Adj Close
stock_data.drop(columns=['Adj Close','Volume'],inplace = True)
plot_col = 'Open:MSFT'
metrics = ['Close','High','Low','Open']

cols = []

for metric in metrics:
    for ticker in tickers:
        cols.append("{}:{}".format(metric,ticker))

stock_data.columns = cols
print(stock_data.head())

# get stats
print(stock_data.describe())

corr = stock_data.corr()

#///////////////////////////////#
#        train test split       #
#///////////////////////////////#

column_indices = {name: i for i, name in enumerate(stock_data.columns)}

n = len(stock_data)
train_df = stock_data[0:int(n*0.7)]
val_df = stock_data[int(n*0.7):int(n*0.9)]
test_df= stock_data[int(n*0.9):]

num_features = stock_data.shape[1]
print(num_features)

# Normalise data

train_mean = train_df.mean()
train_std = train_df.std()

train_df = (train_df - train_mean) / train_std
val_df = (val_df - train_mean) / train_std
test_df = (test_df - train_mean) / train_std

df_std = (stock_data - train_mean) / train_std
df_std = df_std.melt(var_name='Column', value_name='Normalized')
plt.figure(figsize=(12, 6))
ax = sns.violinplot(x='Column', y='Normalized', data=df_std)
_ = ax.set_xticklabels(stock_data.keys(), rotation=90)

plt.show()
print(df_std)

#///////////////////////////////#
#      Data Windowing Class     #
#///////////////////////////////#

class WindowGenerator():
    def __init__(self, input_width, label_width, shift,
               train_df=train_df, val_df=val_df, test_df=test_df,
               label_columns=None):
    # Store the raw data.
        self.train_df = train_df
        self.val_df = val_df
        self.test_df = test_df

        # Work out the label column indices.
        self.label_columns = label_columns
        if label_columns is not None:
            self.label_columns_indices = {name: i for i, name in
                                        enumerate(label_columns)}
        self.column_indices = {name: i for i, name in
                            enumerate(train_df.columns)}

        # Work out the window parameters.
        self.input_width = input_width
        self.label_width = label_width
        self.shift = shift

        self.total_window_size = input_width + shift

        self.input_slice = slice(0, input_width)
        self.input_indices = np.arange(self.total_window_size)[self.input_slice]

        self.label_start = self.total_window_size - self.label_width
        self.labels_slice = slice(self.label_start, None)
        self.label_indices = np.arange(self.total_window_size)[self.labels_slice]

    def __repr__(self):
        return '\n'.join([
            f'Total window size: {self.total_window_size}',
            f'Input indices: {self.input_indices}',
            f'Label indices: {self.label_indices}',
            f'Label column name(s): {self.label_columns}'])

    #//////////////////#
    #      METHODS     #
    #//////////////////#

    # ___________________________________________________________
    # Getter Methods
    # -----------------------------------------------------------
    @property
    def train(self):
        return self.make_dataset(self.train_df)

    @property
    def val(self):
        return self.make_dataset(self.val_df)

    @property
    def test(self):
        return self.make_dataset(self.test_df)

    @property
    def example(self):
        """Get and cache an example batch of `inputs, labels` for plotting."""
        result = getattr(self, '_example', None)
        if result is None:
            # No example batch was found, so get one from the `.train` dataset
            result = next(iter(self.train))
            # And cache it for next time
            self._example = result
        return result

    #////////////////////////#
    #      CLASS METHODS     #
    #////////////////////////#

    # ___________________________________________________________
    # Split window into inputs and labels
    # -----------------------------------------------------------

    def split_window(self, features):
        inputs = features[:, self.input_slice, :]
        labels = features[:, self.labels_slice, :]
        if self.label_columns is not None:
            labels = tf.stack(
                [labels[:, :, self.column_indices[name]] for name in self.label_columns],
                axis=-1)

        # Slicing doesn't preserve static shape information, so set the shapes
        # manually. This way the `tf.data.Datasets` are easier to inspect.
        inputs.set_shape([None, self.input_width, None])
        labels.set_shape([None, self.label_width, None])

        return inputs, labels

    # ___________________________________________________________
    # Make Datasets
    # -----------------------------------------------------------
    def make_dataset(self, data):
        data = np.array(data, dtype=np.float32)
        ds = tf.keras.preprocessing.timeseries_dataset_from_array(
            data=data,
            targets=None,
            sequence_length=self.total_window_size,
            sequence_stride=1,
            shuffle=True,
            batch_size=32,)

        ds = ds.map(self.split_window)

        return ds

    # ___________________________________________________________
    # Plot
    # -----------------------------------------------------------

    def plot(self, model=None, plot_col=plot_col, max_subplots=3):
        inputs, labels = self.example
        plt.figure(figsize=(12, 8))
        plot_col_index = self.column_indices[plot_col]
        max_n = min(max_subplots, len(inputs))
        for n in range(max_n):
            plt.subplot(3, 1, n+1)
            plt.ylabel(f'{plot_col} [normed]')
            plt.plot(self.input_indices, inputs[n, :, plot_col_index],
                    label='Inputs', marker='.', zorder=-10)

            if self.label_columns:
                label_col_index = self.label_columns_indices.get(plot_col, None)
            else:
                label_col_index = plot_col_index

            if label_col_index is None:
                continue

            plt.scatter(self.label_indices, labels[n, :, label_col_index],
                        edgecolors='k', label='Labels', c='#2ca02c', s=64)
            if model is not None:
                predictions = model(inputs)
                plt.scatter(self.label_indices, predictions[n, :, label_col_index],
                        marker='X', edgecolors='k', label='Predictions',
                        c='#ff7f0e', s=64)

            if n == 0:
                plt.legend()
            if model:
                plt.title(model.id)
            plt.xlabel('Time [h]')

        plt.title(plot_col)
        plt.show()

# ___________________________________________________________
# ___________________________________________________________
# WINDOWS
# -----------------------------------------------------------
# -----------------------------------------------------------

# single
single_step_window = WindowGenerator(
    input_width=1, label_width=1, shift=1,
    label_columns=[plot_col])
print(single_step_window)

# wide (1 month)
wide_window = WindowGenerator(
    input_width=21, label_width=21, shift=1,
    label_columns=[plot_col])

print(wide_window)

# ___________________________________________________________
# ___________________________________________________________
# MODELS
# -----------------------------------------------------------
# -----------------------------------------------------------

#////////////////////////#
#         Baseline       #
#////////////////////////#

# Baseline Class Predicts no change
class Baseline(tf.keras.Model):
  def __init__(self, label_index=None,ID = 'Model'):
    super().__init__()
    self.label_index = label_index
    self.id = ID

  def call(self, inputs):
    if self.label_index is None:
      return inputs
    result = inputs[:, :, self.label_index]
    return result[:, :, tf.newaxis]

#////////////////////////#
#         Sequential        #
#////////////////////////#

# sequential custom class
class Sequential(tf.keras.Sequential):

    def __init__(self, layers=None, name=None,ID = 'Model'):
        super().__init__(layers=layers, name=name)
        self.id = ID

    def compile_and_fit(self, window, patience=4,MAX_EPOCHS = 200,baseline = None):
        early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss',
                                                            patience=patience,
                                                            mode='min',
                                                            restore_best_weights = True,
                                                            baseline = baseline)

        self.compile(loss=tf.losses.MeanSquaredError(),
                        optimizer=tf.optimizers.Adam(),
                        metrics=[tf.metrics.MeanAbsoluteError()])

        history = self.fit(window.train, epochs=MAX_EPOCHS,
                            validation_data=window.val,
                            callbacks=[early_stopping])
        return history

def compile_and_fit(model,window, patience=4,MAX_EPOCHS = 200,baseline = None):
        early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss',
                                                            patience=patience,
                                                            mode='min',
                                                            restore_best_weights = True,
                                                            baseline = baseline)

        model.compile(loss=tf.losses.MeanSquaredError(),
                        optimizer=tf.optimizers.Adam(),
                        metrics=[tf.metrics.MeanAbsoluteError()])

        history = model.fit(window.train, epochs=MAX_EPOCHS,
                            validation_data=window.val,
                            callbacks=[early_stopping])
        return history

# ___________________________________________________________
# ___________________________________________________________
# EXECTUTION (SINGLE STEP)
# -----------------------------------------------------------
# -----------------------------------------------------------

#////////////////////////#
#         Baseline       #
#////////////////////////#

baseline = Baseline(label_index=column_indices[plot_col])

baseline.compile(loss=tf.losses.MeanSquaredError(),
                 metrics=[tf.metrics.MeanAbsoluteError()])

val_performance = {}
performance = {}
val_performance['Baseline'] = baseline.evaluate(single_step_window.val)
performance['Baseline'] = baseline.evaluate(single_step_window.test, verbose=0)

wide_window.plot(baseline)

#////////////////////////#
#         linear         #
#////////////////////////#

linear = Sequential([
    tf.keras.layers.Dense(units=1)
])

history = linear.compile_and_fit( single_step_window)

val_performance['Linear'] = linear.evaluate(single_step_window.val)
performance['Linear'] = linear.evaluate(single_step_window.test, verbose=0)

wide_window.plot(linear)
plt.show()

plt.bar(x = range(len(train_df.columns)),
        height=linear.layers[0].kernel[:,0].numpy())
axis = plt.gca()
axis.set_xticks(range(len(train_df.columns)))
_ = axis.set_xticklabels(train_df.columns, rotation=90)
plt.show()

#////////////////////////#
#         multidense     #
#////////////////////////#

dense = Sequential([
    tf.keras.layers.Dense(units=64, activation='relu'),
    tf.keras.layers.Dense(units=64, activation='relu'),
    tf.keras.layers.Dense(units=1)
])

history = dense.compile_and_fit( single_step_window)

val_performance['Dense'] = dense.evaluate(single_step_window.val)
performance['Dense'] = dense.evaluate(single_step_window.test, verbose=0)

plt.bar(x = range(len(train_df.columns)),
        height=dense.layers[0].kernel[:,0].numpy())
axis = plt.gca()
axis.set_xticks(range(len(train_df.columns)))
_ = axis.set_xticklabels(train_df.columns, rotation=90)
plt.show()

#////////////////////////#
#          RNN           #
#////////////////////////#

lstm_model = Sequential([
    # Shape [batch, time, features] => [batch, time, lstm_units]
    tf.keras.layers.LSTM(32, return_sequences=True,dropout=0.2),
    # Shape => [batch, time, features]
    tf.keras.layers.Dense(units=1)
],ID='LSTM')

history = lstm_model.compile_and_fit( wide_window,MAX_EPOCHS=30)

IPython.display.clear_output()
val_performance['LSTM'] = lstm_model.evaluate(wide_window.val)
performance['LSTM'] = lstm_model.evaluate(wide_window.test, verbose=0)

wide_window.plot(lstm_model)

# ///////////////////
# conv
# //////////////////

CONV_WIDTH = 3
LABEL_WIDTH = 23
INPUT_WIDTH = LABEL_WIDTH + (CONV_WIDTH - 1)
conv_window = WindowGenerator(
    input_width=INPUT_WIDTH,
    label_width=LABEL_WIDTH,
    shift=1,
    label_columns=[plot_col])

conv_model = Sequential([
    tf.keras.layers.Conv1D(filters=32,
                           kernel_size=(CONV_WIDTH,),
                           activation='relu'),
    tf.keras.layers.Dense(units=32, activation='relu'),
    tf.keras.layers.Dense(units=1),
],ID = 'Conv')

print("Conv model on `conv_window`")
print('Input shape:', conv_window.example[0].shape)
print('Labels shape:', conv_window.example[1].shape)
print('Output shape:', conv_model(conv_window.example[0]).shape)
print(conv_window)

history = conv_model.compile_and_fit(conv_window)

IPython.display.clear_output()
val_performance['Conv'] = conv_model.evaluate(conv_window.val)
performance['Conv'] = conv_model.evaluate(conv_window.test, verbose=0)

conv_window.plot(conv_model)

# ///////////////////
# residual RNN
# //////////////////

class ResidualWrapper(tf.keras.Model):
    def __init__(self, model,ID = 'RESNET'):
        super().__init__()
        self.model = model
        self.id = ID

    def call(self, inputs, *args, **kwargs):
        delta = self.model(inputs, *args, **kwargs)

        # The prediction for each timestep is the input
        # from the previous time step plus the delta
        # calculated by the model.
        return inputs + delta

    def compile_and_fit(self, window, patience=2,MAX_EPOCHS = 100):
        early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss',
                                                            patience=patience,
                                                            mode='min')

        self.compile(loss=tf.losses.MeanSquaredError(),
                        optimizer=tf.optimizers.Adam(),
                        metrics=[tf.metrics.MeanAbsoluteError()])

        history = self.fit(window.train, epochs=MAX_EPOCHS,
                            validation_data=window.val,
                            callbacks=[early_stopping])
        return history

residual_lstm = ResidualWrapper(
    Sequential([
    tf.keras.layers.LSTM(32, return_sequences=True,dropout=0.2),
    tf.keras.layers.Dense(
        num_features,
        # The predicted deltas should start small
        # So initialize the output layer with zeros
        kernel_initializer=tf.initializers.zeros)
],ID = 'RES'))

history = compile_and_fit(residual_lstm, wide_window)

IPython.display.clear_output()
val_performance['Residual LSTM'] = residual_lstm.evaluate(wide_window.val)
performance['Residual LSTM'] = residual_lstm.evaluate(wide_window.test, verbose=0)
print()

# //////////////
# PERFORMANCE
#///////////////

x = np.arange(len(performance))
width = 0.3
metric_name = 'mean_absolute_error'
metric_index = lstm_model.metrics_names.index('mean_absolute_error')
val_mae = [v[metric_index] for v in val_performance.values()]
test_mae = [v[metric_index] for v in performance.values()]

plt.ylabel('mean_absolute_error [{}], normalized]'.format(plot_col))
plt.bar(x - 0.17, val_mae, width, label='Validation')
plt.bar(x + 0.17, test_mae, width, label='Test')
plt.xticks(ticks=x, labels=performance.keys(),
           rotation=45)
_ = plt.legend()
plt.show()

for name, value in performance.items():
  print(f'{name:12s}: {value[1]:0.4f}')

# ___________________________________________________________
# ___________________________________________________________
# MULTI (single shot)
# -----------------------------------------------------------
# -----------------------------------------------------------

OUT_STEPS = 24
multi_window = WindowGenerator(input_width=24,
                               label_width=OUT_STEPS,
                               shift=OUT_STEPS)

multi_window.plot()
print(multi_window)

# //////////////
# BASELINE
#///////////////

class MultiStepLastBaseline(tf.keras.Model):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.id = 'Baseline'
    def call(self, inputs):
        return tf.tile(inputs[:, -1:, :], [1, OUT_STEPS, 1])

last_baseline = MultiStepLastBaseline()
last_baseline.compile(loss=tf.losses.MeanSquaredError(),
                      metrics=[tf.metrics.MeanAbsoluteError()])

multi_val_performance = {}
multi_performance = {}

multi_val_performance['BENCHMARK'] = last_baseline.evaluate(multi_window.val)
multi_performance['BENCHMARK'] = last_baseline.evaluate(multi_window.test, verbose=0)
multi_window.plot(last_baseline)

print(multi_performance['BENCHMARK'])

# //////////////
# DENSE(Multi)
#///////////////

multi_linear_model = Sequential([
    # Take the last time-step.
    # Shape [batch, time, features] => [batch, 1, features]
    tf.keras.layers.Lambda(lambda x: x[:, -1:, :]),
    # Shape => [batch, 1, out_steps*features]
    tf.keras.layers.Dense(OUT_STEPS*num_features,
                          kernel_initializer=tf.initializers.zeros),
    # Shape => [batch, out_steps, features]
    tf.keras.layers.Reshape([OUT_STEPS, num_features])
],ID = 'Dense(multi)')

history = multi_linear_model.compile_and_fit( multi_window)

IPython.display.clear_output()
multi_val_performance['Linear'] = multi_linear_model.evaluate(multi_window.val)
multi_performance['Linear'] = multi_linear_model.evaluate(multi_window.test, verbose=0)
multi_window.plot(multi_linear_model)

# //////////////
# DENSE(Multi) (RES)
#///////////////

multi_linear_model_RES =ResidualWrapper( Sequential([
    # Take the last time-step.
    # Shape [batch, time, features] => [batch, 1, features]
    tf.keras.layers.Lambda(lambda x: x[:, -1:, :]),
    # Shape => [batch, 1, out_steps*features]
    tf.keras.layers.Dense(OUT_STEPS*num_features,
                          kernel_initializer=tf.initializers.zeros),
    # Shape => [batch, out_steps, features]
    tf.keras.layers.Reshape([OUT_STEPS, num_features])
],ID = 'Dense(multi)'),ID = "Dense(multi_RES)")

history = multi_linear_model_RES.compile_and_fit( multi_window)

IPython.display.clear_output()
multi_val_performance['Linear'] = multi_linear_model_RES.evaluate(multi_window.val)
multi_performance['Linear'] = multi_linear_model_RES.evaluate(multi_window.test, verbose=0)
multi_window.plot(multi_linear_model_RES)
# //////////////
# CONV(Multi)
#///////////////

CONV_WIDTH = 3
multi_conv_model = Sequential([
    # Shape [batch, time, features] => [batch, CONV_WIDTH, features]
    tf.keras.layers.Lambda(lambda x: x[:, -CONV_WIDTH:, :]),
    # Shape => [batch, 1, conv_units]
    tf.keras.layers.Conv1D(256, activation='relu', kernel_size=(CONV_WIDTH)),
    # Shape => [batch, 1,  out_steps*features]
    tf.keras.layers.Dense(OUT_STEPS*num_features,
                          kernel_initializer=tf.initializers.zeros),
    # Shape => [batch, out_steps, features]
    tf.keras.layers.Reshape([OUT_STEPS, num_features])
],ID='conv')

history = multi_conv_model.compile_and_fit( multi_window)

IPython.display.clear_output()

multi_val_performance['Conv'] = multi_conv_model.evaluate(multi_window.val)
multi_performance['Conv'] = multi_conv_model.evaluate(multi_window.test, verbose=0)
multi_window.plot(multi_conv_model)

# //////////////
# CONV(Multi) with RES
#///////////////

CONV_WIDTH = 3
multi_conv_model_res = ResidualWrapper(Sequential([
    # Shape [batch, time, features] => [batch, CONV_WIDTH, features]
    tf.keras.layers.Lambda(lambda x: x[:, -CONV_WIDTH:, :]),
    # Shape => [batch, 1, conv_units]
    tf.keras.layers.Conv1D(256, activation='relu', kernel_size=(CONV_WIDTH)),
    # Shape => [batch, 1,  out_steps*features]
    tf.keras.layers.Dense(OUT_STEPS*num_features,
                          kernel_initializer=tf.initializers.zeros),
    # Shape => [batch, out_steps, features]
    tf.keras.layers.Reshape([OUT_STEPS, num_features])
],ID='conv_RES'),ID = 'conv_RES')

history = multi_conv_model_res.compile_and_fit( multi_window)

IPython.display.clear_output()

multi_val_performance['Conv_RES'] = multi_conv_model_res.evaluate(multi_window.val)
multi_performance['Conv_RES'] = multi_conv_model_res.evaluate(multi_window.test, verbose=0)
multi_window.plot(multi_conv_model_res)

# //////////////
# LSTM(Multi)
#///////////////

multi_lstm_model = Sequential([
    # Shape [batch, time, features] => [batch, lstm_units]
    # Adding more `lstm_units` just overfits more quickly.
    tf.keras.layers.LSTM(32, return_sequences=False,dropout=0.2),
    # Shape => [batch, out_steps*features]
    tf.keras.layers.Dense(OUT_STEPS*num_features,
                          kernel_initializer=tf.initializers.zeros),
    # Shape => [batch, out_steps, features]
    tf.keras.layers.Reshape([OUT_STEPS, num_features])
],ID = 'LSTM')

history = compile_and_fit(multi_lstm_model, multi_window)

IPython.display.clear_output()

multi_val_performance['LSTM'] = multi_lstm_model.evaluate(multi_window.val)
multi_performance['LSTM'] = multi_lstm_model.evaluate(multi_window.test, verbose=0)
multi_window.plot(multi_lstm_model)

# //////////////
# LSTM(residual)
#///////////////

class FeedBack(tf.keras.Model):
    def __init__(self, units, out_steps):
        super().__init__()
        self.out_steps = out_steps
        self.units = units
        self.lstm_cell = tf.keras.layers.LSTMCell(units,dropout = 0.1)
        # Also wrap the LSTMCell in an RNN to simplify the `warmup` method.
        self.lstm_rnn = tf.keras.layers.RNN(self.lstm_cell, return_state=True)
        self.dense = tf.keras.layers.Dense(num_features)
        self.id = 'AUTOREG'

    def warmup(self, inputs):
        # inputs.shape => (batch, time, features)
        # x.shape => (batch, lstm_units)
        x, *state = self.lstm_rnn(inputs)

        # predictions.shape => (batch, features)
        prediction = self.dense(x)
        return prediction, state
    def call(self, inputs, training=None):
        # Use a TensorArray to capture dynamically unrolled outputs.
        predictions = []
        # Initialize the lstm state
        prediction, state = self.warmup(inputs)

        # Insert the first prediction
        predictions.append(prediction)

        # Run the rest of the prediction steps
        for n in range(1, self.out_steps):
            # Use the last prediction as input.
            x = prediction
            # Execute one lstm step.
            x, state = self.lstm_cell(x, states=state,
                                    training=training)
            # Convert the lstm output to a prediction.
            prediction = self.dense(x)
            # Add the prediction to the output
            predictions.append(prediction)

        # predictions.shape => (time, batch, features)
        predictions = tf.stack(predictions)
        # predictions.shape => (batch, time, features)
        predictions = tf.transpose(predictions, [1, 0, 2])
        return predictions

feedback_model =  ResidualWrapper(
    FeedBack(units=32, out_steps=OUT_STEPS),
    ID = "FEEBACK RES")

history = compile_and_fit(feedback_model, multi_window)

IPython.display.clear_output()

multi_val_performance['AR RES LSTM'] = feedback_model.evaluate(multi_window.val)
multi_performance['AR RES LSTM'] = feedback_model.evaluate(multi_window.test, verbose=0)
print(feedback_model.evaluate(multi_window.test, verbose=0))

# //////////////
# PERFORMANCE
#///////////////

for name, value in multi_performance.items():
  print(f'{name}: {value[1]}')

x = np.arange(len(multi_performance))
width = 0.3

metric_name = 'mean_absolute_error'
metric_index = lstm_model.metrics_names.index('mean_absolute_error')
val_mae = [v[metric_index] for v in multi_val_performance.values()]
test_mae = [v[metric_index] for v in multi_performance.values()]

plt.bar(x - 0.17, val_mae, width, label='Validation')
plt.bar(x + 0.17, test_mae, width, label='Test')
plt.xticks(ticks=x, labels=multi_performance.keys(),
           rotation=45)
plt.ylabel(f'MAE (average over all times and outputs)')
_ = plt.legend()
plt.show()


import pyrender
import numpy as np
import trimesh
from numba import jit, cuda
import cv2
import time
import matplotlib.pyplot as plt

from PIL import Image
#from RealismEmbedding.Harmonization import Harmonization
from Communication.python.client import Client
from HumanPose.demo import PoseEstimator
import pickle

@jit(nopython=True)
def compute_mask(rows, cols, im_color, im_depth, obj_depth, mask_, result_):
    for ro in range(rows):
        for co in range(cols):
            if obj_depth[ro][co] != 0:
                if obj_depth[ro][co] > im_depth[ro][co]:
                    result_[ro][co] = im_color[ro][co]
                    mask_[ro][co] = 0.0

                else:
                    result_[ro][co] = color[ro][co]
                    mask_[ro][co] = 255.0
    return result_, mask_
def is_inside_sphere(point,center, radius):
    diff = point-center
    return diff.T@diff < radius*radius

if __name__ == "__main__":
    client = Client("10.152.42.93", 5002)

    client.send("WP3")

    fuze_trimesh = trimesh.load('data/plane/textured.obj')

    scale = trimesh.transformations.scale_matrix(0.5)
    window_size = (640, 480)
    harmonize = Harmonization()
    estimator = PoseEstimator()
    last_hit = 0
    points = 0
    fourcc = cv2.VideoWriter_fourcc(*'MP4V')
    out = cv2.VideoWriter('output.mp4', fourcc, 5, (640, 480))
    while 1:
        # Receive data and unserialize
        start_time = time.time()
        serializedData = client.receive(decode=False)
        data = pickle.loads(serializedData)

        img_depth = data["depthMap"]
        img_depth = img_depth.astype(np.float32)
        img_depth = img_depth / 1000
        # img_depth = ((img_depth * 3.96) / 4.0) + 0.04

        img_color = data["rgbFrame"]
        #Render the Points achieved, can be done later or some other way, but I think this works fine
        cv2.putText(img_color, "Points: {}".format(points),(0,50), cv2.FONT_HERSHEY_TRIPLEX, 2, (255, 0, 0))
        #Estimate Human Poses
        human_poses = estimator.process_frame(img_color)
        # Get coordinate of right_wrist  == Keypoint 4
        wrist_coord = human_poses[0].keypoints[4]
        # Take a 3 x 3 Patch around that coordinate in the depth map
        hand_patch = img_depth[wrist_coord[0]-1:wrist_coord[0]+2, wrist_coord[1]-1:wrist_coord[1]+2]
        mean_depth = np.mean(hand_patch)
        wrist_coord_3d = np.array([wrist_coord[0], wrist_coord[1], mean_depth])

        camera_pose = np.eye(4)
        intrinsics = data["depthIntrincics"]

        object_pose = data["objectPose"]
        ## "Game" Logic
        if is_inside_sphere(wrist_coord_3d, object_pose[:3, 3], 0.1):
            if time.monotonic()- last_hit > 1:
                last_hit = time.monotonic()
                points += 1
        print(object_pose)
        camera = pyrender.camera.IntrinsicsCamera(intrinsics[0][0], intrinsics[1][1], intrinsics[0][2],
                                                  intrinsics[1][2],
                                                  znear=0.04, zfar=4.0, name=None)

        r = pyrender.OffscreenRenderer(window_size[0], window_size[1])
        scene = pyrender.Scene(bg_color=[0, 0, 0], ambient_light=[1.0, 1.0, 1.0])
        mesh = pyrender.Mesh.from_trimesh(fuze_trimesh, poses=object_pose)
        scene.add(mesh)

        scene.add(camera, pose=camera_pose)
        color, depth = r.render(scene)
        dim = depth.shape
        row = dim[0]
        col = dim[1]
        mask = np.zeros_like(depth)
        result = np.copy(img_color)

        indexes = depth > img_depth
        result[indexes] = img_color[indexes]
        mask[indexes] = 0.0
        result[~indexes] = color[~indexes]
        mask[~indexes] = 255.0
        z_indexes = depth == 0
        result[z_indexes] = img_color[z_indexes]

        # uncomment below line to enable harmonization
        # frame = harmonize.compute(Image.fromarray(mask), Image.fromarray(result))
        # comment below line to enable harmonization
        frame = result
        frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
        cv2.namedWindow('RS_DepthMap', cv2.WINDOW_AUTOSIZE)
        cv2.imshow('RS_DepthMap', frame)
        out.write(frame)

        key = cv2.waitKey(1)


#Monument Labs - Assignment 2 ~ Shaan Barkat

import subprocess
from collections import defaultdict
import datetime

commands = ['sleep 3', 'ls -1 /', 'find /', 'sleep 4', 'find /usr', 'date', 'sleep 5', 'uptime']

times = defaultdict(list)

for cmd in commands:
    for i in range(1,10):
    #Used to find an accurate average time.
        #Check the running time - gives initial state.
        start_time = datetime.datetime.now()
        x = subprocess.Popen(cmd)
        end_time = datetime.datetime.now()
        #Gives end state, through 10 runs to justify average, min, and max.

        #Wait till the process terminates.
        while x.poll() is None:
            time.sleep(0.5)

        runtime = end_time - start_time
        cmd_times[cmd].append(runtime)

for cmd in commands:
    print(min(cmd_times[cmd]))#Min execution time.
    print(max(cmd_times[cmd]))#Max execution time.
    print((sum(cmd_times[cmd]))/(len(cmd_times[cmd])))#Average execution time.


import numpy as np
from .Physics import *

import torch
from .Global import *
torch.set_default_tensor_type(torchPrecision)
device = torchdevice

class snell_refraction_vector_physics():
    """snell_refraction_vector_physics.
    """

    def __init__(self):
        """__init__.
        """
        pass

    def calculate(self, s1_norm, Nsurf_norm, n1, n2, empty1, empty2, empty3, empty4, Secuen):

        return calculate2(s1_norm, Nsurf_norm, n1, n2, empty1, empty2, empty3, empty4, Secuen)

# @jit(nopython=True)
def calculate2(s1_norm, Nsurf_norm, n1, n2, empty1, empty2, empty3, empty4, Secuen):
    """calculate.

    Parameters
    ----------
    s1_norm :
        s1_norm
    Nsurf_norm :
        Nsurf_norm
    n1 :
        n1
    n2 :
        n2
    empty1 :
        empty1
    empty2 :
        empty2
    empty3 :
        empty3
    empty4 :
        empty4
    Secuen :
        Secuen
r = rayo
r'=reflejado
S=normal superficie
    """

    Nv = Nsurf_norm
    Iv = s1_norm

    """ checking if the normal to the surface is in the
    direction of space where the ray is coming from and
    not where it is going """

    cos=torch.dot(Nv, Iv)

    if (cos < (- 1.0)):
        ang = 180.0
    else:
        ang = torch.rad2deg(torch.arccos(cos))

    if (ang <= 90.0):
        Nv = - Nv

    """----------------------------------------------"""

    Nsurf_Cros_s1 = torch.cross(Nv, Iv)
    SIGN = 1.0

    if (n2 == - 1.0):
        n2 = - n1
        SIGN = -1.0

    NN = (n1 / n2)
    d22=torch.dot(Nsurf_Cros_s1, Nsurf_Cros_s1)
    R = (NN * NN) * d22

    if (Secuen == 1.0):
        R = 2.0

    if (R > 1.0):
        n2 = - n1
        NN = n1 / n2
        # R = (NN * NN) * d22
        SIGN = - 1.0

    c1 = torch.dot(Nv,Iv)
    if c1 < 0.0 :
        c1 = torch.dot(-Nv,Iv)
    IP = ((NN**2)*(1-(c1**2.0)))

    c2 = torch.sqrt(1.0-IP)
    T = NN * Iv + ((( NN * c1 ) - c2)) * Nv

    return T, np.abs(n2), SIGN

# @jit(nopython=True)
# def calculate2(s1_norm, Nsurf_norm, n1, n2, empty1, empty2, empty3, empty4, Secuen):
#     """calculate.

#     Parameters
#     ----------
#     s1_norm :
#         s1_norm
#     Nsurf_norm :
#         Nsurf_norm
#     n1 :
#         n1
#     n2 :
#         n2
#     empty1 :
#         empty1
#     empty2 :
#         empty2
#     empty3 :
#         empty3
#     empty4 :
#         empty4
#     Secuen :
#         Secuen
#     """

#     # Nsurf_norm = 1. * np.asarray(Nsurf_norm1)
#     # s1_norm = 1. * np.asarray(s1_norm1)

#     N1 = [Nsurf_norm[0], Nsurf_norm[1], Nsurf_norm[2]]
#     S1 = [s1_norm[0], s1_norm[1], s1_norm[2]]

#     cos=(N1[0]*S1[0]) + (N1[1]*S1[1]) + (N1[2]*S1[2])

#     # cos = np.dot(N1, S1)

#     if (cos < (- 1.0)):
#         ang = 180.0
#     else:
#         ang = np.rad2deg(np.arccos(cos))

#     if (ang <= 90.0):
#         Nsurf_norm = (- Nsurf_norm)

#     Nsurf_Cros_s1 = np.cross(Nsurf_norm, s1_norm)
#     SIGN = 1.0

#     if (n2 == (- 1.0)):
#         n2 = (- n1)
#         SIGN = (- 1.0)

#     NN = (n1 / n2)
#     d22=np.dot(Nsurf_Cros_s1, Nsurf_Cros_s1)
#     R = ((NN * NN) * d22)

#     if (Secuen == 1.0):
#         R = 2.0

#     if (R > 1.0):
#         n2 = (- n1)
#         NN = (n1 / n2)
#         R = ((NN * NN) * d22)
#         SIGN = (- 1.0)

#     s2 = ((NN * np.cross(Nsurf_norm, np.cross((- Nsurf_norm), s1_norm))) - (Nsurf_norm * np.sqrt((1.0 - ((NN * NN) * d22)))))

#     # cos = np.dot([0.0, 0.0, 1.0], [s2[0], s2[1], s2[2]])
#     # cos = s2[2]

#     # ang = np.rad2deg(np.arccos(cos))

#     return s2, np.abs(n2), SIGN

class paraxial_exact_physics():
    """paraxial_exact_physics.
    """

    def __init__(self):
        """__init__.
        """
        pass

    def calculate(self, s1_norm, Nsurf_norm, n1, n2, empty1, empty2, empty3, empty4, empty5):
        """calculate.

        Parameters
        ----------
        s1_norm :
            s1_norm
        Nsurf_norm :
            Nsurf_norm
        n1 :
            n1
        n2 :
            n2
        empty1 :
            empty1
        empty2 :
            empty2
        empty3 :
            empty3
        empty4 :
            empty4
        empty5 :
            empty5
        """
        return (Nsurf_norm, 1, 1)

class diffraction_grating_physics():
    """diffraction_grating_physics.
    """

    def __init__(self):
        """__init__.
        """
        pass

    def calculate(self, S, R, N, Np, P, Ord, d, W, Secuent):
        Ang=np.rad2deg(np.arccos( np.dot(R,S)))
        # print(S, R, Ord, Ang)

        if np.abs(Ang) < 90:
            R = -R

        """calculate.

        Parameters
        ----------
        S :
            S
        R :
            R
        N :
            N
        Np :
            Np
        D :
            D
        Ord :
            Ord
        d :
            d
        W :
            W
        Secuent :
            Secuent
        """

        D = np.cross(R, P)

        lamb = W
        RefRef = ((- 1.) * np.sign(Np))
        SIGN = 1.

        # print(RefRef, Np)
        if (Np == (- 1.)):
            Np = np.abs(N)

##########################################
        mu = (N / Np)
        T = ((Ord * lamb) / (Np * d))
##########################################

        V = (mu * np.dot(R,S))
        W = ((((mu ** 2.0) - 1.) + (T ** 2.0)) - (((2.0 * mu) * T) * np.dot(D,S)))

        Q1 = ( np.sqrt((V**2 - W))) - V
        Q2 = (-np.sqrt((V**2 - W))) - V

        if RefRef == 1:
            if Q1 > Q2:
                Q = Q1
            else:
                Q = Q2

        if RefRef == -1:
            if Q1 < Q2:
                Q = Q1
            else:
                Q = Q2

        S = np.asarray(S)
        Sp = (((mu * S) - (T * D)) + (Q * R))

        SIGN = SIGN*-1*RefRef
        return (Sp, np.abs(Np), SIGN)