import os
import sys
import numpy as np
import pydicom
from tqdm import tqdm
# Import Mask RCNN
from mrcnn.config import Config
from mrcnn import utils
import mrcnn.model as modellib
from utilities import get_dicom_fps, parse_dataset, DetectorDataset, find_lastest_model_and_save_config_class
ROOT_DIR = '.'
DATA_DIR = '../Input' # to be modified
sys.path.append(os.path.join(ROOT_DIR, 'Mask_RCNN'))  # To find local version of the library
test_dicom_dir = os.path.join(DATA_DIR, 'stage_2_test_images')
# Directory to save logs and trained model
ROOT_DIR = '.'
ORIG_SIZE = 1024

# os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID"
# # The GPU id to use, usually either "0" or "1"
# os.environ["CUDA_VISIBLE_DEVICES"]="3"

#*************retreive mask RCNN******************
# retreive path to model and config class
model_path = 'pneumonia20181020T2012_0165/mask_rcnn_pneumonia_0032.h5'  # find_lastest_model(ROOT_DIR)
# ap_model_path = 'pneumonia20181021T0631_0165_AP/mask_rcnn_pneumonia_0032.h5'
# pa_model_path = 'pneumonia20181021T1543_0165_PA/mask_rcnn_pneumonia_0032.h5'
# retrieve DetectorConfig from pickle file

######################################################################
#model parameter setting for testing data
######################################################################
class InferenceConfig(Config):
    NAME = 'pneumonia'
    GPU_COUNT = 1
    IMAGES_PER_GPU = 1
    BACKBONE = 'resnet50'
    NUM_CLASSES = 2  # background + 1 pneumonia classes
    IMAGE_MIN_DIM = 256  # 512
    IMAGE_MAX_DIM = 256  # 512
    # MEAN_PIXEL = np.array([0, 0, 0])#np.array([124.9, 124.9, 124.9])
    RPN_ANCHOR_SCALES = (32, 64, 128, 256)
    TRAIN_ROIS_PER_IMAGE = 32
    MAX_GT_INSTANCES = 4
    DETECTION_MAX_INSTANCES = 3
    DETECTION_MIN_CONFIDENCE = 0.78
    DETECTION_NMS_THRESHOLD = 0.01
    # DETECTION_MIN_CONFIDENCE = 0.9

inference_config = InferenceConfig()

model = modellib.MaskRCNN(mode='inference',
                              config=inference_config,
                              model_dir=ROOT_DIR)
#
# Load trained weights (fill in path to trained weights here)
print('Retrieving mask RCNN...')
assert model_path != "", "Provide path to trained weights for mask RCNN"
print("Loading weights from ", model_path)
model.load_weights(model_path, by_name=True)

# ap_model = modellib.MaskRCNN(mode='inference',
#                               config=inference_config,
#                               model_dir=ROOT_DIR)

# Load trained weights (fill in path to trained weights here)
# print('Retrieving AP mask RCNN...')
# assert ap_model_path != "", "Provide path to trained weights for mask RCNN"
# print("Loading weights from ", ap_model_path)
# ap_model.load_weights(ap_model_path, by_name=True)
#
# pa_model = modellib.MaskRCNN(mode='inference',
#                               config=inference_config,
#                               model_dir=ROOT_DIR)

# Load trained weights (fill in path to trained weights here)
# print('Retrieving PA mask RCNN...')
# assert pa_model_path != "", "Provide path to trained weights for mask RCNN"
# print("Loading weights from ", pa_model_path)
# pa_model.load_weights(pa_model_path, by_name=True)
# *************retreive image classifier******************
DROPOUT = 0.2
DENSE_COUNT = 128
image_classifier_path = 'classifier/ResNet50/384_384_lr_1e-4_balanced_orig_data_prtrained_imagenet_20epoch_all_layers/RESNET50_full_model.h5'
#LEARN_RATE = 1e-4
SHAPE = 2  # t_y.shape[1] in lung_opacity_classifier.py
print('Retrieving classifier...')
assert image_classifier_path != "", "Provide path to trained weights for classifier"
from keras.applications.resnet50 import ResNet50 as PTModel, preprocess_input as Resnet50_preprocess
base_pretrained_model = PTModel(input_shape=(384, 384, 3),
                                include_top=False)

from keras.layers import GlobalAveragePooling2D, Dense, Dropout, Flatten, Input, Conv2D, multiply, \
    LocallyConnected2D, Lambda, AvgPool2D
from keras.models import Model
from keras.optimizers import Adam
# catch the output as feature from picked pre-trained model
pt_features = Input(base_pretrained_model.get_output_shape_at(0)[1:], name='feature_input')
pt_depth = base_pretrained_model.get_output_shape_at(0)[-1]
# Normalize the activations of the previous layer at each batch,
# i.e. applies a transformation that maintains the mean activation close to 0 and the activation standard deviation close to 1.
from keras.layers import BatchNormalization
bn_features = BatchNormalization()(pt_features)
# Global average pooling operation for spatial data
gap = GlobalAveragePooling2D()(bn_features)
# Dropout layer
gap_dr = Dropout(DROPOUT)(gap)
# Another Dropout after a fully connected network after first dropout layer
dr_steps = Dropout(DROPOUT)(Dense(DENSE_COUNT, activation='elu')(gap_dr))
out_layer = Dense(SHAPE, activation='softmax')(dr_steps)
attn_model = Model(inputs=[pt_features],
                   outputs=[out_layer], name='trained_model')
from keras.models import Sequential
image_classifier = Sequential(name='combined_model')
image_classifier.add(base_pretrained_model)
image_classifier.add(attn_model)
#load pre-trained weights
print("Loading weights from ", image_classifier_path)
image_classifier.load_weights(image_classifier_path)

# *************retreive bbox classifier******************
DROPOUT = 0.2
DENSE_COUNT = 256
bbox_classifier_path = 'bbox_classifier/Xception_200_200_lr1e-4_256dense/Xception_full_model.h5'
#LEARN_RATE = 1e-4
SHAPE = 2  # t_y.shape[1] in lung_opacity_classifier.py
print('Retrieving classifier...')
assert bbox_classifier_path != "", "Provide path to trained weights for classifier"
from keras.applications.xception import Xception as PTModel, preprocess_input as Xception_preprocess
base_pretrained_model = PTModel(input_shape=(200, 200, 3),
                                include_top=False)

from keras.layers import GlobalAveragePooling2D, Dense, Dropout, Flatten, Input, Conv2D, multiply, \
    LocallyConnected2D, Lambda, AvgPool2D
from keras.models import Model
from keras.optimizers import Adam
# catch the output as feature from picked pre-trained model
pt_features = Input(base_pretrained_model.get_output_shape_at(0)[1:], name='feature_input')
pt_depth = base_pretrained_model.get_output_shape_at(0)[-1]
# Normalize the activations of the previous layer at each batch,
# i.e. applies a transformation that maintains the mean activation close to 0 and the activation standard deviation close to 1.
from keras.layers import BatchNormalization
bn_features = BatchNormalization()(pt_features)
# Global average pooling operation for spatial data
gap = GlobalAveragePooling2D()(bn_features)
# Dropout layer
gap_dr = Dropout(DROPOUT)(gap)
# Another Dropout after a fully connected network after first dropout layer
dr_steps = Dropout(DROPOUT)(Dense(DENSE_COUNT, activation='elu')(gap_dr))
out_layer = Dense(SHAPE, activation='softmax')(dr_steps)
attn_model = Model(inputs=[pt_features],
                   outputs=[out_layer], name='trained_model')
from keras.models import Sequential
bbox_classifier = Sequential(name='combined_model')
bbox_classifier.add(base_pretrained_model)
bbox_classifier.add(attn_model)
#load pre-trained weights
print("Loading weights from ", bbox_classifier_path)
bbox_classifier.load_weights(bbox_classifier_path)

# Get filenames of test dataset DICOM images
test_image_fps = get_dicom_fps(test_dicom_dir)

from scipy import misc
######################################################################
# Predict the result on testing data and output to submission.csv
######################################################################
# Make predictions on test images, write out sample submission
from keras.preprocessing import image as img
def predict(image_fps, filepath='submission.csv', min_conf=0.95):
    # assume square image
    resize_factor = ORIG_SIZE / inference_config.IMAGE_SHAPE[0]
    with open(filepath, 'w') as file:
        file.write("patientId,predictionString\n") #header
        for image_id in tqdm(image_fps):
            ds = pydicom.read_file(image_id)
            #view_position = ds.ViewPosition
            original_image = ds.pixel_array
            # If grayscale. Convert to RGB for consistency.
            if len(original_image.shape) != 3 or original_image.shape[2] != 3:
                original_image = np.stack((original_image,) * 3, -1)

            image_for_maskRCNN, window, scale, padding, crop = utils.resize_image(
                original_image,
                min_dim=inference_config.IMAGE_MIN_DIM,
                min_scale=inference_config.IMAGE_MIN_SCALE,
                max_dim=inference_config.IMAGE_MAX_DIM,
                mode=inference_config.IMAGE_RESIZE_MODE)

            image_for_classifier, window2, scale2, padding2, crop2 = utils.resize_image(
                original_image,
                min_dim=384,
                min_scale=0,
                max_dim=384,
                mode=inference_config.IMAGE_RESIZE_MODE)
            image_for_classifier = np.expand_dims(image_for_classifier.astype(np.float32), axis=0)
            image_for_classifier = Resnet50_preprocess(image_for_classifier)
            image_pred = image_classifier.predict(image_for_classifier) # [no opacity, opacity]

            patient_id = os.path.splitext(os.path.basename(image_id))[0]

            results = model.detect([image_for_maskRCNN])
            r = results[0]

            out_str = ""
            out_str += patient_id
            out_str += ","
            assert (len(r['rois']) == len(r['class_ids']) == len(r['scores']))
            if len(r['rois']) == 0:# no bbox detected
                pass
            else:
                if False: #pred[0][0] > 0.99: #classified as no opacity with high prob
                    pass
                else:
                    num_instances = len(r['rois'])
                    for i in range(num_instances):
                        if r['scores'][i] > min_conf:#threshold and view_position != 'PA':
                            #prediction on bbox
                            x = r['rois'][i][1]
                            y = r['rois'][i][0]
                            width = r['rois'][i][3] - x
                            height = r['rois'][i][2] - y

                            x1 = int(x * resize_factor)
                            y1 = int(y * resize_factor)
                            width1 = int((r['rois'][i][3] - x) * resize_factor)
                            height1 = int((r['rois'][i][2] - y) * resize_factor)

                            masked = np.array(original_image[y1:y1 + height1, x1:x1 + width1, :], dtype=np.int32)
                            resized_patch = misc.imresize(masked, (200, 200), 'nearest')
                            image = np.expand_dims(resized_patch.astype(np.float32), axis=0)
                            image = Xception_preprocess(image)
                            pred = bbox_classifier.predict(image)
                            # prob of false positive on bbox, confidence of bbox, prob of false positive on whole image
                            #if pred[0][0] > 0.95 and r['scores'][i] < 0.98 and image_pred[0][0] > 0.95: 0.13
                            #if pred[0][0] > 0.9 and r['scores'][i] < 0.97 and image_pred[0][0] > 0.9: 0132
                            if pred[0][0] > 0.9 and r['scores'][i] < 0.97 and image_pred[0][0] > 0.9:
                                continue
                            out_str += ' '
                            out_str += str(round(r['scores'][i], 2))
                            out_str += ' '
                            # x1, y1, width, height
                            bboxes_str = "{} {} {} {}".format(x * resize_factor, y * resize_factor, width * resize_factor, height * resize_factor)
                            #bboxes_str = "{} {} {} {}".format(x1, y1, width, height)
                            out_str += bboxes_str

            file.write(out_str + "\n")

#tag = model_path.split('/')[1]
submission_fp = os.path.join(ROOT_DIR, 'submission.csv')
#print(submission_fp)
predict(test_image_fps, filepath=submission_fp, min_conf=0.965)


"""
Give an efficient algorithm that computes and prints, for every position p
of a tree T, the element of p followed by the height of p’s subtree.
"""

from EulerTour import EulerTour
from LinkedBinaryTree import LinkedBinaryTree
from other import parenthesize

class xd:
    def travel_tree(self, tree, p, height):

        best = height
        for child in tree.children(p):
            new_size = self.travel_tree(tree, child, 0)
            best = max(best, new_size)
        if not tree.is_leaf(p):
            best += 1
        print("Node {} have height {}".format(p._node._element, best))
        return best

t = LinkedBinaryTree()
root = t._add_root(0)
a = t._add_left(root, 1)
b = t._add_right(root, 2)
c = t._add_left(a, 3)
d = t._add_right(a, 4)
e = t._add_left(d, 5)
"""
     0
  1     2
3  4
    5

"""
parenthesize(t, t.root())
print()
xd = xd()
x = xd.travel_tree(t, t.root(), 0)

print()


#ask for age
age = input("How old are you? ")

if age:
    age = int(age)
    if age >= 18 and age < 21:
        print("You can enter, but can't drink.")
    elif age >= 21:
        print("You can enter.")
    else:
        print("You can't come in, you're to young.")
else:
    print("Please enter an age.")
# 18 -21 wristband
#21+ drink, normal entry
#too young, sorry


import pygame
import random
import os
import time

pygame.font.init()

#Variables
WIDTH, HEIGHT = 1000 , 750
p1_score = 0
p2_score = 0
#main_font = pygame.font.SysFont('')
#scene

WIN = pygame.display.set_mode([WIDTH,HEIGHT])

#Objects

class Ball():
    RADIUS = 15
    def __init__(self,x,y,vel_x,vel_y):
        self.x = x
        self.y = y
        self.vel_x = vel_x
        self.vel_y = vel_y

    def show(self,window):

        pygame.draw.circle(window,FG,(self.x,self.y),self.RADIUS)

    #def move(self):

#Game runner
def pongv2():
    running = True
    FPS = 60
    clock = pygame.time.Clock()

    def refresh():

        pygame.display.flip()
        Ball.show(WIN)

    while running :
        clock.tick(FPS)
        refresh()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

                key = pygame.key.get_pressed()
                #if event.type == pygame.KEYDOWN:

                    #if key[pygame.K_UP]:

                    #if key[pygame.K_DOWN]:

                    #if key[pygame.K_w]:

                    #if key[pygame.K_s]:

    pygame.quit()


import baostock as bs
import pandas as pd
import time

def get_new_data(bs, stockid):
    rs = bs.query_history_k_data_plus(stockid,
                                      "date,code,open,high,low,close,preclose,volume,amount,adjustflag,turn,tradestatus,pctChg,peTTM,pbMRQ,psTTM,pcfNcfTTM,isST",
                                      start_date='2021-08-01', end_date='2021-08-31',
                                      frequency="d", adjustflag="1")  # frequency="d"取日k线，adjustflag="3"默认不复权, 1后复权，2前复权

    #### 打印结果集 ####
    data_list = []
    while (rs.error_code == '0') & rs.next():
        # 获取一条记录，将记录合并在一起
        data_list.append(rs.get_row_data())
    result = pd.DataFrame(data_list, columns=rs.fields)
    return result

if __name__ == '__main__':
    #### 登陆系统 ####
    lg = bs.login()
    his_data = pd.read_csv('.\\result\\close.csv').drop(columns=['Unnamed: 0'])
    his_data.set_index('date', inplace=True)
    stock_list = list(his_data.columns)
    all_df = pd.DataFrame()
    for stockid in stock_list:
        print(stockid)
        df = get_new_data(bs, stockid)
        all_df = all_df.append(df)
        time.sleep(0.2)

        all_df.to_csv('stock_new.csv')
    #### 登出系统 ####
    bs.logout()


# coding: utf-8

import os
import requests
import time
import logging

from logging.handlers import QueueHandler
from multiprocessing import Process
from multiprocessing.shared_memory import SharedMemory
from queue import Empty

from legendary.models.chunk import Chunk
from legendary.models.downloading import DownloaderTaskResult, WriterTaskResult

class DLWorker(Process):
    def __init__(self, name, queue, out_queue, shm, max_retries=5,
                 logging_queue=None, dl_timeout=10):
        super().__init__(name=name)
        self.q = queue
        self.o_q = out_queue
        self.session = requests.session()
        self.session.headers.update({
            'User-Agent': 'EpicGamesLauncher/11.0.1-14907503+++Portal+Release-Live Windows/10.0.19041.1.256.64bit'
        })
        self.max_retries = max_retries
        self.shm = SharedMemory(name=shm)
        self.log_level = logging.getLogger().level
        self.logging_queue = logging_queue
        self.dl_timeout = float(dl_timeout) if dl_timeout else 10.0

    def run(self):
        # we have to fix up the logger before we can start
        _root = logging.getLogger()
        _root.handlers = []
        _root.addHandler(QueueHandler(self.logging_queue))

        logger = logging.getLogger(self.name)
        logger.setLevel(self.log_level)
        logger.debug(f'Download worker reporting for duty!')

        empty = False
        while True:
            try:
                job = self.q.get(timeout=10.0)
                empty = False
            except Empty:
                if not empty:
                    logger.debug(f'Queue Empty, waiting for more...')
                empty = True
                continue

            if job.kill:  # let worker die
                logger.debug(f'Worker received kill signal, shutting down...')
                break

            tries = 0
            dl_start = dl_end = 0
            compressed = 0
            chunk = None

            try:
                while tries < self.max_retries:
                    # print('Downloading', job.url)
                    logger.debug(f'Downloading {job.url}')
                    dl_start = time.time()

                    try:
                        r = self.session.get(job.url, timeout=self.dl_timeout)
                        r.raise_for_status()
                    except Exception as e:
                        logger.warning(f'Chunk download for {job.guid} failed: ({e!r}), retrying...')
                        continue

                    dl_end = time.time()
                    if r.status_code != 200:
                        logger.warning(f'Chunk download for {job.guid} failed: status {r.status_code}, retrying...')
                        continue
                    else:
                        compressed = len(r.content)
                        chunk = Chunk.read_buffer(r.content)
                        break
                else:
                    raise TimeoutError('Max retries reached')
            except Exception as e:
                logger.error(f'Job for {job.guid} failed with: {e!r}, fetching next one...')
                # add failed job to result queue to be requeued
                self.o_q.put(DownloaderTaskResult(success=False, chunk_guid=job.guid, shm=job.shm, url=job.url))
            except KeyboardInterrupt:
                logger.warning('Immediate exit requested, quitting...')
                break

            if not chunk:
                logger.warning(f'Chunk somehow None?')
                self.o_q.put(DownloaderTaskResult(success=False, chunk_guid=job.guid, shm=job.shm, url=job.url))
                continue

            # decompress stuff
            try:
                size = len(chunk.data)
                if size > job.shm.size:
                    logger.fatal(f'Downloaded chunk is longer than SharedMemorySegment!')

                self.shm.buf[job.shm.offset:job.shm.offset + size] = bytes(chunk.data)
                del chunk
                self.o_q.put(DownloaderTaskResult(success=True, chunk_guid=job.guid, shm=job.shm,
                                                  url=job.url, size=size, compressed_size=compressed,
                                                  time_delta=dl_end - dl_start))
            except Exception as e:
                logger.warning(f'Job for {job.guid} failed with: {e!r}, fetching next one...')
                self.o_q.put(DownloaderTaskResult(success=False, chunk_guid=job.guid, shm=job.shm, url=job.url))
                continue
            except KeyboardInterrupt:
                logger.warning('Immediate exit requested, quitting...')
                break

        self.shm.close()

class FileWorker(Process):
    def __init__(self, queue, out_queue, base_path, shm, cache_path=None, logging_queue=None):
        super().__init__(name='FileWorker')
        self.q = queue
        self.o_q = out_queue
        self.base_path = base_path
        self.cache_path = cache_path if cache_path else os.path.join(base_path, '.cache')
        self.shm = SharedMemory(name=shm)
        self.log_level = logging.getLogger().level
        self.logging_queue = logging_queue

    def run(self):
        # we have to fix up the logger before we can start
        _root = logging.getLogger()
        _root.handlers = []
        _root.addHandler(QueueHandler(self.logging_queue))

        logger = logging.getLogger(self.name)
        logger.setLevel(self.log_level)
        logger.debug(f'Download worker reporting for duty!')

        last_filename = ''
        current_file = None

        while True:
            try:
                try:
                    j = self.q.get(timeout=10.0)
                except Empty:
                    logger.warning('Writer queue empty!')
                    continue

                if j.kill:
                    if current_file:
                        current_file.close()
                    self.o_q.put(WriterTaskResult(success=True, kill=True))
                    break

                # make directories if required
                path = os.path.split(j.filename)[0]
                if not os.path.exists(os.path.join(self.base_path, path)):
                    os.makedirs(os.path.join(self.base_path, path))

                full_path = os.path.join(self.base_path, j.filename)

                if j.empty:  # just create an empty file
                    open(full_path, 'a').close()
                    self.o_q.put(WriterTaskResult(success=True, filename=j.filename))
                    continue
                elif j.open:
                    if current_file:
                        logger.warning(f'Opening new file {j.filename} without closing previous! {last_filename}')
                        current_file.close()

                    current_file = open(full_path, 'wb')
                    last_filename = j.filename

                    self.o_q.put(WriterTaskResult(success=True, filename=j.filename))
                    continue
                elif j.close:
                    if current_file:
                        current_file.close()
                        current_file = None
                    else:
                        logger.warning(f'Asking to close file that is not open: {j.filename}')

                    self.o_q.put(WriterTaskResult(success=True, filename=j.filename, closed=True))
                    continue
                elif j.rename:
                    if current_file:
                        logger.warning('Trying to rename file without closing first!')
                        current_file.close()
                        current_file = None
                    if j.delete:
                        try:
                            os.remove(full_path)
                        except OSError as e:
                            logger.error(f'Removing file failed: {e!r}')
                            self.o_q.put(WriterTaskResult(success=False, filename=j.filename))
                            continue

                    try:
                        os.rename(os.path.join(self.base_path, j.old_filename), full_path)
                    except OSError as e:
                        logger.error(f'Renaming file failed: {e!r}')
                        self.o_q.put(WriterTaskResult(success=False, filename=j.filename))
                        continue

                    self.o_q.put(WriterTaskResult(success=True, filename=j.filename))
                    continue
                elif j.delete:
                    if current_file:
                        logger.warning('Trying to delete file without closing first!')
                        current_file.close()
                        current_file = None

                    try:
                        os.remove(full_path)
                    except OSError as e:
                        if not j.silent:
                            logger.error(f'Removing file failed: {e!r}')

                    self.o_q.put(WriterTaskResult(success=True, filename=j.filename))
                    continue

                pre_write = post_write = 0

                try:
                    if j.shm:
                        pre_write = time.time()
                        shm_offset = j.shm.offset + j.chunk_offset
                        shm_end = shm_offset + j.chunk_size
                        current_file.write(self.shm.buf[shm_offset:shm_end].tobytes())
                        post_write = time.time()
                    elif j.cache_file:
                        pre_write = time.time()
                        with open(os.path.join(self.cache_path, j.cache_file), 'rb') as f:
                            if j.chunk_offset:
                                f.seek(j.chunk_offset)
                            current_file.write(f.read(j.chunk_size))
                        post_write = time.time()
                    elif j.old_file:
                        pre_write = time.time()
                        with open(os.path.join(self.base_path, j.old_file), 'rb') as f:
                            if j.chunk_offset:
                                f.seek(j.chunk_offset)
                            current_file.write(f.read(j.chunk_size))
                        post_write = time.time()
                except Exception as e:
                    logger.warning(f'Something in writing a file failed: {e!r}')
                    self.o_q.put(WriterTaskResult(success=False, filename=j.filename,
                                                  chunk_guid=j.chunk_guid,
                                                  release_memory=j.release_memory,
                                                  shm=j.shm, size=j.chunk_size,
                                                  time_delta=post_write-pre_write))
                else:
                    self.o_q.put(WriterTaskResult(success=True, filename=j.filename,
                                                  chunk_guid=j.chunk_guid,
                                                  release_memory=j.release_memory,
                                                  shm=j.shm, size=j.chunk_size,
                                                  time_delta=post_write-pre_write))
            except Exception as e:
                logger.warning(f'Job {j.filename} failed with: {e!r}, fetching next one...')
                self.o_q.put(WriterTaskResult(success=False, filename=j.filename, chunk_guid=j.chunk_guid))

                try:
                    if current_file:
                        current_file.close()
                        current_file = None
                except Exception as e:
                    logger.error(f'Closing file after error failed: {e!r}')
            except KeyboardInterrupt:
                logger.warning('Immediate exit requested, quitting...')
                if current_file:
                    current_file.close()
                return


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date    : 2019-06-02 21:22:24
# @Author  : Mengji Zhang (zmj_xy@sjtu.edu.cn)
import torch
from torch import nn
import numpy as np
from scipy import linalg as sla
class UNet2D_4Lanes_LSF(nn.Module):
	def __init__(self,feature_extractor,device):
		super(UNet2D_4Lanes_LSF,self).__init__()
		self.feature_extractor=feature_extractor
		self.map_weights=nn.Sequential(
			nn.Conv2d(32,4,1,padding=0),
			nn.Sigmoid())

		self.device=device
	def forward(self,x,masks):
		## masks: B,C,H,W
		features=self.feature_extractor(x)
		weights=self.map_weights(features)
		B,C,H,W=weights.shape
		betas=[]
		for b in range(B):
			tmp_betas=[]
			for c in range(C):
				xv,yv=self.generate_coordinates(W,H,weights[b,c],masks[b,c])
				if xv.shape[0]==0:
					tmp_betas.append(-1)
					continue
				beta=self.compute_beta_cuda(xv,yv)
				tmp_betas.append(beta)
			betas.append(tmp_betas)
		betas=torch.FloatTensor(betas).to(self.device)

		return weights,betas
	def generate_coordinates(self,size_w,size_h,w,label):
		xv,yv=torch.meshgrid([torch.arange(0,size_h),torch.arange(0,size_w)])
		xv=xv.type(torch.FloatTensor);yv=yv.type(torch.FloatTensor)
		xv=xv.to(self.device);yv=yv.to(self.device)

		xv,yv=torch.mul(xv,w),torch.mul(yv,w)
		xv,yv=torch.mul(xv,label),torch.mul(yv,label)
		nonzeros=torch.nonzero(xv)
		return xv[nonzeros[:,0],nonzeros[:,1]].unsqueeze(1),yv[nonzeros[:,0],nonzeros[:,1]].unsqueeze(1)

	def compute_beta_cuda(self,X,Y):
		XtX,XtY=X.permute(1,0).mm(X),X.permute(1,0).mm(Y)
		beta_cholesky,_=torch.gesv(XtY,XtX)
		return beta_cholesky
if __name__=="__main__":
	model=UNet2D_4Lanes_LSF(None)
	x_map,y_map=generate_xy_coordinates(10,10,4)
	x_map=np.stack([x_map for i in range(2)])
	y_map=np.stack([y_map for i in range(2)])
	x_map=torch.FloatTensor(x_map).to("cuda")
	y_map=torch.FloatTensor(y_map).to("cuda")
	model.forward(None,x_map,y_map)


import warnings

import numba
from numba import types
from numba.core.errors import NumbaPendingDeprecationWarning
from numba.experimental import jitclass

# Disable warning that comes when pure python list is passed to functions below.
# We use a specific version of numba that is still compatible with pure python lists.
warnings.simplefilter('ignore', category=NumbaPendingDeprecationWarning)

RANS64_L = 2 ** 30
MIN_PROB = 8
prob_bits = 14
prob_scale = 1 << prob_bits

@numba.jit(nopython=True)
def argmax(values):
    if not values:
        return -1  # Empty list has no argmax

    current_max = values[0]
    current_max_index = 0
    for i in range(1, len(values)):
        if values[i] > current_max:
            current_max = values[i]
            current_max_index = i

    return current_max_index

@numba.jit(nopython=True)
def float_to_int_probs(float_probs):
    pdf = []
    cdf = [0]

    for prob in float_probs:
        next_prob = round(prob * prob_scale)
        if prob > 0 and next_prob < MIN_PROB:
            next_prob = MIN_PROB

        pdf.append(next_prob)
        cdf.append(cdf[-1] + next_prob)

    # Account for possible rounding error
    # Remove the correction from the largest element
    to_correct = prob_scale - cdf[-1]

    largest_index = argmax(pdf)
    pdf[largest_index] += to_correct
    for i in range(largest_index + 1, len(cdf)):
        cdf[i] += to_correct

    return pdf, cdf

@numba.jit(nopython=True)
def find_in_int_dist(cdf, to_find):
    for i in range(len(cdf) - 1):
        if cdf[i] <= to_find and cdf[i + 1] > to_find:
            return i

    print("Error: Could not find symbol in integer-dist")

spec = [
    ('state', numba.uint64),
    ('encoded_data', types.ListType(types.uint32)),
]

@jitclass(spec=spec)
class Encoder:
    def __init__(self):
        self.state = RANS64_L
        self.encoded_data = numba.typed.List.empty_list(types.uint32)

    def encode_symbol(self, freqs, symbol):
        (pdf, cdf) = float_to_int_probs(freqs)
        freq = pdf[symbol]
        start = cdf[symbol]

        if freq == 0:
            print("Error: Can't encode symbol with frequency 0!")
            return

        x = self.state

        x_max = ((RANS64_L >> prob_bits) << 32) * freq
        if x >= x_max:
            self.encoded_data.append(types.uint32(x & 0xffffffff))
            x >>= 32

        self.state = ((x // freq) << prob_bits) + (x % freq) + start

    def get_encoded(self):
        self.encoded_data.append(types.uint32(self.state & 0xffffffff))
        self.state >>= 32
        self.encoded_data.append(types.uint32(self.state & 0xffffffff))
        return self.encoded_data

spec = [
    ('state', numba.uint64),
    ('encoded_data', types.ListType(types.uint32)),
]

@jitclass(spec=spec)
class Decoder:
    def __init__(self, encoded_data):
        self.state = (encoded_data.pop() << 32) | encoded_data.pop()
        self.encoded_data = encoded_data

    def decode_symbol(self, freqs):
        (pdf, cdf) = float_to_int_probs(freqs)

        # Extract symbol
        to_find = self.state & (prob_scale - 1)
        symbol = find_in_int_dist(cdf, to_find)

        # Symbol related variables.
        start = cdf[symbol]
        freq = pdf[symbol]

        mask = prob_scale - 1

        # Move state foward one step
        x = self.state
        x = freq * (x >> prob_bits) + (x & mask) - start

        # Enough of state has been read that we now need to get more out of encoded_data.
        if x < RANS64_L:
            x = (x << 32) | self.encoded_data.pop()

        self.state = x

        return symbol


from django.urls import path, include

from authentication.views import login_page, registration, logout, login_user

app_name = 'authentication'

urlpatterns = [
    path('login/', login_page, name="login"),
    path('signup/', registration, name="signup_page"),
    path('logout/', logout, name="logout")
]


import os

def get_folders_names_from_path(path="."):
    d = path
    root_folders_names = [
        os.path.join(d, o)
        for o in os.listdir(d)
        if os.path.isdir(os.path.join(d, o))
    ]

    return root_folders_names

def create_folders_if_not_exists(folder_names = [], path=""):
    for folder_name in folder_names:
        folder_name = folder_name.split("/")[1]
        folder_path = os.path.join(path, folder_name)

        if not os.path.exists(folder_path):
            os.makedirs(folder_path)


# Advent of Code 2016
#
# From https://adventofcode.com/2016/day/19
from collections import deque

data = 3001330

def find_elf1(data):
    elves = {x: x + 1 for x in range(data)}
    elves[data - 1] = 0
    elf = 0
    while len(elves) > 1:
        to_del = elves[elf]
        elves[elf] = elves[elves[elf]]
        elf = elves[elf]
        del elves[to_del]
    return list(elves.values())[0] + 1

def find_elf2(data):
    q = deque()
    q.extend(range(1, data + 1))
    while len(q) > 1:
        x = len(q) // 2
        q.rotate(-x)
        q.popleft()
        q.rotate(x - 1)
    return q.pop()

print(f"AoC 2016 Day 19 Part 1 answer is: {find_elf1(data)}")
print(f"AoC 2016 Day 19 Part 2 answer is: {find_elf2(data)}")


"""
This file contains a module to calculate operating costs for airplanes in the general turboprop / Part 23 range. It does not consider crew
costs, so mission optimization routines will tend to favor slower, longer-time routes than they  probably should (could fix in future).
"""

from openmdao.api import ExplicitComponent

class TurbopropOperatingCost(ExplicitComponent):
    def initialize(self):
        self.options.declare(
            "n_components",
            default=1,
            desc='Number of propulsion components, e.g. engines, motors, generators. Inputs will be numbered "component_1" thru n ',
        )
        self.options.declare(
            "n_batteries",
            default=None,
            desc='Number of batteries. These should NOT be counted as components as they are not to be subtracted from OEW. Numbered "battery_1" through n',
        )
        self.options.declare(
            "airframe_cost_per_kg",
            default=266.0,
            desc="Cost of each kg of airplane empty weight MINUS ENGINES/MOTORS/GEN/BATTERIES",
        )
        self.options.declare(
            "fuel_cost_per_kg", default=2.5 / 3.08, desc="Cost of each KG of fuel; divide USD/gal by 3.08kg/gal"
        )
        self.options.declare(
            "electricity_cost_per_MJ", default=0.01, desc="Electricity cost per MJ. Divide MWh cost by 3600 MJ/MWh"
        )
        self.options.declare("aircraft_life_years", default=15, desc="Useful aircraft life in years")
        self.options.declare("aircraft_daily_cycles", default=5, desc="Number of mission cycles per day (average).")
        self.options.declare(
            "battery_replacement_cycles", default=1500, desc="Number of battery cycles until replacement"
        )
        self.options.declare(
            "OEM_premium",
            default=1.1,
            desc="Multiplier on the airframe cost as profit margin for the OEM. 10% margin = 1.1",
        )

    def setup(self):
        n_components = self.options["n_components"]
        n_batteries = self.options["n_batteries"]
        battery_replacement_cycles = self.options["battery_replacement_cycles"]
        af_cost_kg = self.options["airframe_cost_per_kg"]
        aircraft_daily_cycles = self.options["aircraft_daily_cycles"]
        aircraft_life_years = self.options["aircraft_life_years"]
        fuel_cost_per_kg = self.options["fuel_cost_per_kg"]
        electricity_cost_per_MJ = self.options["electricity_cost_per_MJ"]
        OEM_premium = self.options["OEM_premium"]

        for i in range(n_components):
            self.add_input("component_" + str(i + 1) + "_weight", units="kg", desc="Component weight")
            self.add_input("component_" + str(i + 1) + "_NR_cost", units="USD", desc="Component cost")
            self.declare_partials(
                ["airframe_NR_cost", "total_NR_cost"],
                ["component_" + str(i + 1) + "_weight"],
                val=-af_cost_kg * OEM_premium,
            )
            self.declare_partials(
                ["trip_direct_operating_cost"],
                ["component_" + str(i + 1) + "_weight"],
                val=-af_cost_kg * OEM_premium / aircraft_daily_cycles / 365 / aircraft_life_years,
            )
            self.declare_partials(["total_NR_cost"], ["component_" + str(i + 1) + "_NR_cost"], val=OEM_premium)
            self.declare_partials(
                ["trip_direct_operating_cost"],
                ["component_" + str(i + 1) + "_NR_cost"],
                val=OEM_premium / aircraft_daily_cycles / 365 / aircraft_life_years,
            )

        if n_batteries is not None:
            self.add_output("trip_battery_cost", units="USD")
            self.add_output("electricity_cost", units="USD")
            for i in range(n_batteries):
                self.add_input("battery_" + str(i + 1) + "_NR_cost", units="USD", desc="Battery purchase cost")
                self.add_input(
                    "battery_" + str(i + 1) + "_energy_used", units="MJ", desc="Battery energy used for mission"
                )
                self.declare_partials(
                    ["electricity_cost", "trip_energy_cost", "trip_direct_operating_cost"],
                    ["battery_" + str(i + 1) + "_energy_used"],
                    val=electricity_cost_per_MJ,
                )
                self.declare_partials(
                    ["trip_battery_cost", "trip_direct_operating_cost"],
                    ["battery_" + str(i + 1) + "_NR_cost"],
                    val=1 / battery_replacement_cycles,
                )

        self.add_input("fuel_burn", units="kg", desc="Fuel used for mission")
        self.add_input("OEW", units="kg", desc="Operating empty weight")

        self.add_output("fuel_cost", units="USD")
        self.add_output("airframe_NR_cost", units="USD")
        self.add_output("total_NR_cost", units="USD")
        self.add_output("trip_energy_cost", units="USD")
        self.add_output("trip_direct_operating_cost", units="USD")

        self.declare_partials(["airframe_NR_cost", "total_NR_cost"], ["OEW"], val=af_cost_kg * OEM_premium)
        self.declare_partials(
            ["trip_direct_operating_cost"],
            ["OEW"],
            val=af_cost_kg * OEM_premium / aircraft_daily_cycles / 365 / aircraft_life_years,
        )
        self.declare_partials(
            ["fuel_cost", "trip_energy_cost", "trip_direct_operating_cost"], ["fuel_burn"], val=fuel_cost_per_kg
        )

    def compute(self, inputs, outputs):
        # compute empty weight less the number of propulsion components
        # OEW - w_component for n components
        n_components = self.options["n_components"]
        n_batteries = self.options["n_batteries"]
        battery_replacement_cycles = self.options["battery_replacement_cycles"]
        af_cost_kg = self.options["airframe_cost_per_kg"]
        aircraft_daily_cycles = self.options["aircraft_daily_cycles"]
        aircraft_life_years = self.options["aircraft_life_years"]
        fuel_cost_per_kg = self.options["fuel_cost_per_kg"]
        electricity_cost_per_MJ = self.options["electricity_cost_per_MJ"]
        OEM_premium = self.options["OEM_premium"]

        adj_OEW = inputs["OEW"]
        components_NR_cost = 0

        for i in range(n_components):
            adj_OEW = adj_OEW - inputs["component_" + str(i + 1) + "_weight"]
            components_NR_cost = components_NR_cost + inputs["component_" + str(i + 1) + "_NR_cost"]

        outputs["airframe_NR_cost"] = adj_OEW * af_cost_kg * OEM_premium
        outputs["total_NR_cost"] = outputs["airframe_NR_cost"] + components_NR_cost * OEM_premium

        NR_contrib_trip_cost = outputs["total_NR_cost"] / aircraft_daily_cycles / 365 / aircraft_life_years

        outputs["fuel_cost"] = inputs["fuel_burn"] * fuel_cost_per_kg

        total_elec = 0
        total_batt_cost = 0
        if n_batteries is not None:
            for i in range(n_batteries):
                total_elec = total_elec + inputs["battery_" + str(i + 1) + "_energy_used"]
                total_batt_cost = total_batt_cost + inputs["battery_" + str(i + 1) + "_NR_cost"]
            outputs["electricity_cost"] = total_elec * electricity_cost_per_MJ
            outputs["trip_battery_cost"] = total_batt_cost / battery_replacement_cycles
            outputs["trip_energy_cost"] = outputs["electricity_cost"] + outputs["fuel_cost"]
            outputs["trip_direct_operating_cost"] = (
                outputs["trip_energy_cost"] + NR_contrib_trip_cost + outputs["trip_battery_cost"]
            )
        else:
            outputs["trip_energy_cost"] = outputs["fuel_cost"]
            outputs["trip_direct_operating_cost"] = outputs["trip_energy_cost"] + NR_contrib_trip_cost

    # def compute_partials(self, inputs, J):
    #     n_components = self.options['n_components']
    #     n_batteries = self.options['n_batteries']
    #     battery_replacement_cycles = self.options['battery_replacement_cycles']
    #     af_cost_kg = self.options['airframe_cost_per_kg']
    #     aircraft_daily_cycles = self.options['aircraft_daily_cycles']
    #     aircraft_life_years = self.options['aircraft_life_years']
    #     fuel_cost_per_kg = self.options['fuel_cost_per_kg']
    #     electricity_cost_per_MJ = self.options['electricity_cost_per_MJ']
    #     OEM_premium = self.options['OEM_premium']

    #     J['airframe_NR_cost','OEW'] = af_cost_kg * OEM_premium
    #     J['total_NR_cost','OEW'] = J['airframe_NR_cost','OEW']
    #     J['trip_direct_operating_cost','OEW'] = J['total_NR_cost','OEW'] / aircraft_daily_cycles / 365 / aircraft_life_years

    #     for i in range(n_components):
    #         J['airframe_NR_cost','component_'+str(i+1)+'_weight'] = - af_cost_kg * OEM_premium
    #         J['total_NR_cost','component_'+str(i+1)+'_weight'] = J['airframe_NR_cost','component_'+str(i+1)+'_weight']
    #         J['total_NR_cost','component_'+str(i+1)+'_NR_cost'] = OEM_premium
    #         J['trip_direct_operating_cost','component_'+str(i+1)+'_weight'] = J['total_NR_cost','component_'+str(i+1)+'_weight'] / aircraft_daily_cycles / 365 / aircraft_life_years
    #         J['trip_direct_operating_cost','component_'+str(i+1)+'_NR_cost'] = J['total_NR_cost','component_'+str(i+1)+'_NR_cost'] / aircraft_daily_cycles / 365 / aircraft_life_years

    #     J['fuel_cost','fuel_burn'] = fuel_cost_per_kg
    #     J['trip_energy_cost','fuel_burn'] = fuel_cost_per_kg
    #     J['trip_direct_operating_cost','fuel_burn'] = fuel_cost_per_kg

    #     if n_batteries is not None:
    #         for i in range(n_batteries):
    #             J['electricity_cost','battery_'+str(i+1)+'_energy_used'] = electricity_cost_per_MJ
    #             J['trip_energy_cost','battery_'+str(i+1)+'_energy_used'] = electricity_cost_per_MJ
    #             J['trip_direct_operating_cost','battery_'+str(i+1)+'_energy_used'] = electricity_cost_per_MJ

    #             J['trip_battery_cost','battery_'+str(i+1)+'_NR_cost'] = 1 / battery_replacement_cycles
    #             J['trip_direct_operating_cost','battery_'+str(i+1)+'_NR_cost'] = 1 / battery_replacement_cycles


exec(compile(open("Log_data/log_state.py", "rb").read(), "Log_data/log_state.py", 'exec'))
log_state(1)

dynamics.dyn_manager_init.mode = trick.DynManagerInit.EphemerisMode_SinglePlanet
dynamics.dyn_manager_init.central_point_name = "Sun"

rk_integrator = trick.RK4IntegratorConstructor()
dynamics.dyn_manager_init.integ_constructor = rk_integrator

vehicle.dyn_body.set_name("vehicle")
vehicle.dyn_body.integ_frame_name = "Sun.inertial"
vehicle.dyn_body.translational_dynamics = False
vehicle.dyn_body.rotational_dynamics = False

vehicle.array.set_name("array")

exec(compile(open("Modified_data/vehicle_mass_props.py", "rb").read(), "Modified_data/vehicle_mass_props.py", 'exec'))
exec(compile(open("Modified_data/vehicle_state.py", "rb").read(), "Modified_data/vehicle_state.py", 'exec'))
exec(compile(open("Modified_data/surface.py", "rb").read(), "Modified_data/surface.py", 'exec'))
exec(compile(open("Modified_data/attach.py", "rb").read(), "Modified_data/attach.py", 'exec'))

vehicle.facet_pos = [0,0,0]
vehicle.T_for_rotation = [[1,0,0],[0,1,0],[0,0,1]]

trick.exec_set_terminate_time(1000)


from aima.core.search.adversarial import MinMaxSearch, SuccessorFunction, AlphaBetaSearch

__author__ = 'proger'

import unittest

class TestSuccessorFunction(SuccessorFunction):
    def __init__(self):
        successors = {}
        successors['A'] = [('B', 'a1', 1), ('C', 'a2', 1), ('D', 'a3', 1)]
        successors['B'] = [('E', 'b1', 1), ('F', 'b2', 1), ('G', 'b3', 1)]
        successors['C'] = [('H', 'c1', 1), ('I', 'c2', 1), ('J', 'c3', 1)]
        successors['D'] = [('K', 'd1', 1), ('L', 'd2', 1), ('M', 'd3', 1)]

        self.successors = successors

    def get_successor_states(self, state):
        return self.successors[state]

class TestUtilityFunction():
    def __init__(self):
        utility = {}
        utility['E'] = 3
        utility['F'] = 12
        utility['G'] = 8

        utility['H'] = 2
        utility['I'] = 4
        utility['J'] = 6

        utility['K'] = 14
        utility['L'] = 5
        utility['M'] = 2

        self.utility = utility

    def __call__(self, state):
        return self.utility[state]

class TestTerminalFunction():
    def __init__(self):
        self.terminal_states = {'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M'}

    def __call__(self, state):
        return state in self.terminal_states

class MinMaxSearchTest(unittest.TestCase):
    def test_get_action(self):
        mms = MinMaxSearch(TestSuccessorFunction(), TestSuccessorFunction(), TestUtilityFunction(), TestTerminalFunction())
        action = mms.get_action('A')

        self.assertEquals('a1', action)

class MinMaxSearchTest(unittest.TestCase):
    def test_get_action(self):
        mms = AlphaBetaSearch(TestSuccessorFunction(), TestSuccessorFunction(), TestUtilityFunction(), TestTerminalFunction())
        action = mms.get_action('A')

        self.assertEquals('a1', action)

if __name__ == '__main__':
    unittest.main()


"""
Primary class of the EventStore component. Supports writing to the
canonical database for the History Atlas.
"""

import asyncio
import logging
import signal

from abstract_domain_model.transform import to_dict
from eventstore.database import Database
from eventstore.broker import Broker
from tha_config import Config

logging.basicConfig(level="DEBUG")
log = logging.getLogger(__name__)

class EventStore:
    def __init__(self):
        self.config = Config()
        self.db = Database(self.config)
        self.broker = Broker(self.config, self.process_event)

    async def start_broker(self):
        await self.broker.start()

    async def shutdown(self, signal):
        if signal:
            log.info(f"Received shutdown signal: {signal}")
        await self.broker.cancel()

    async def process_event(self, event, pub_func):
        """accepts an event and submits it to the datastore for storage.
        Returns a json string representation of the persisted event."""
        log.debug(f"processing event {event}")
        persisted_events = self.db.commit_event(event)
        for event in persisted_events:
            await pub_func(to_dict(event))
        log.info("Finished processing event")

if __name__ == "__main__":
    store = EventStore()
    loop = asyncio.get_event_loop()
    loop.create_task(store.start_broker())
    signals = (signal.SIGHUP, signal.SIGTERM, signal.SIGINT)
    for s in signals:
        loop.add_signal_handler(s, lambda s=s: asyncio.create_task(store.shutdown(s)))
    try:
        log.info("Asyncio loop now running")
        loop.run_forever()
    finally:
        loop.close()
        log.info("EventStore shut down successfully.")


from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import ExecuteProcess

# Retrieving path information
from ament_index_python.packages import get_package_share_directory
from pathlib import Path

# Utilizing launch files from other packages
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource

# Working with environment variables
from launch.actions import SetEnvironmentVariable

# Simulation event handling
from launch.actions import RegisterEventHandler, EmitEvent
from launch.event_handlers import OnProcessExit
from launch.events import Shutdown

# Path Variables
ignition_ros_package_path = get_package_share_directory("ros_gz_sim")
udemy_ros2_pkg_path = get_package_share_directory("sim_tut")
simulation_world_file_path = Path(udemy_ros2_pkg_path, "worlds/Wheeled_model_world.sdf").as_posix()
simulation_models_path = Path(udemy_ros2_pkg_path, "models").as_posix()

def generate_launch_description():
    ld =LaunchDescription()

    set_path= SetEnvironmentVariable(
        name="GZ_SIM_RESOURCE_PATH",
        value=simulation_models_path
    )

    simulation = ExecuteProcess(
        cmd=['gz', 'sim', '-r', simulation_world_file_path],
        output='screen'
    )

    bridge_vel=Node(
        package="ros_gz_bridge",
        executable="parameter_bridge",
        arguments=["/model/wheeled_model/cmd_vel@geometry_msgs/msg/Twist@ignition.msgs.Twist"],
        remappings=[("/model/wheeled_model/cmd_vel", "/cmd_vel")], # Remapping topic in launch file
        output="screen"
    )

    Res=RegisterEventHandler(
        event_handler=OnProcessExit(
        target_action=simulation,
        on_exit=[EmitEvent(event=Shutdown())])
    )

    ld.add_action(set_path)
    ld.add_action(simulation)
    ld.add_action(bridge_vel)
    ld.add_action(Res)

    return ld


a = int(input())

for i in range(1, a + 1):
    str_a = str(i)
    cnt = 0
    for x in str_a:
        if (x == '3') or (x == '6') or (x == '9'):
            cnt += 1
    if cnt == 0:
        print(i, end=' ')
    else:
        print(cnt * 'ьзЭ', end=' ')


#!pip install streamlit
from keras_vggface.utils import preprocess_input
from keras_vggface.vggface import VGGFace
import pickle as pk
from sklearn.metrics.pairwise import cosine_similarity
import streamlit as st
from PIL import Image
import os
import cv2
import heapq
from facenet_pytorch import MTCNN
import numpy as np

face_detector = MTCNN()
model = VGGFace(model='resnet50',include_top=False,input_shape=(224,224,3),pooling='avg')
celeb_feature_list = np.array(pk.load(open('embedding.pkl', 'rb')))
celeb_and_file_names = pk.load(open('celeb_and_file_names.pkl', 'rb'))

def save_uploaded_image(uploaded_image):
    """
    Saves an uploaded image to the 'uploads' directory.

    Parameters:
        uploaded_image (FileStorage): The uploaded image file.

    Returns:
        bool: True if the image is successfully saved, False otherwise.
                                                                            """
    try:
        uploads_dir = 'uploads'

        # Create the 'uploads' directory if it doesn't exist
        if not os.path.exists(uploads_dir):
            os.makedirs(uploads_dir)

        with open(os.path.join(uploads_dir, uploaded_image.name), 'wb') as f:
            f.write(uploaded_image.getbuffer())

        return True
    except:
        return False

def extract_features(person_image_path, model, face_detector):

    """
        Extracts facial features from an input image using a pre-trained model.
        It first detects the face from  the image using a face_detector model,
        then extracts its features using a model

        Params:
            person_image_path (str): The file path to the input image.
            model (tf.keras.Model): The pre-trained model for feature extraction.
            face_detector: The face detection model

        Returns:
            numpy.ndarray: The extracted facial features as a 1D numpy array.
            Node: if face can not be cropped using the model
                                                                                """

    sample_img = cv2.imread(person_image_path)
    boxes, _ = face_detector.detect(sample_img)

    if boxes is not None and len(boxes) > 0:
        bounding_box = boxes[0].astype(int)  # Convert float values to integers
        x_low, y_low, x_high, y_high = bounding_box

        # Crop the face region from the image
        cropped_face = sample_img[y_low:y_high, x_low:x_high]

    else:
        return None

    image = Image.fromarray(cropped_face)
    image = image.resize((224, 224))

    face_array = np.asarray(image)
    face_array = face_array.astype('float32')

    expanded_img = np.expand_dims(face_array, axis=0)
    preprocessed_img = preprocess_input(expanded_img)
    face_features = model.predict(preprocessed_img).flatten()

    return face_features

# Function to find the celebrity a person looks like
def find_celebrity(celeb_feature_list ,face_features):
    """
        Finds the celebrity that a person looks like based on facial similarity scores.

    Parameters:
        celeb_feature_list (list): A list of celebrity feature vectors.
        face_features (numpy.ndarray): The feature vector of the person's face.

    Returns:
        tuple: A tuple containing the name of the matched celebrity and the image path of the matched celebrity.
    """

    similarities = []

    # Find the cosine similarity of current image with all of the 13000 image_features
    for celeb_feature in celeb_feature_list:
        similarity = cosine_similarity(face_features.reshape(1, -1), celeb_feature.reshape(1, -1))[0][0]
        similarities.append(similarity)

    # Get the indices of the top 5 similarity scores
    top_indices = heapq.nlargest(5, range(len(similarities)), similarities.__getitem__)

    # Dictionary to store the weighted similarity scores for each celebrity
    weighted_similarity_scores = {}
    # Dict to store the celebrity name and corresponding image path
    celeb_name2path = {}

    # Iterate over the top 5 indices
    for i in top_indices:
        # Get the similarity score and celebrity name
        similarity_score = similarities[i]
        celebrity_name = celeb_and_file_names[i][0]
        img_path = celeb_and_file_names[i][1]

        # Add the img path to the corresponding celebrity name
        if celebrity_name not in celeb_name2path:
            celeb_name2path[celebrity_name] = img_path

        # Add the similarity score to the corresponding celebrity's weighted similarity score
        if celebrity_name in weighted_similarity_scores:
            weighted_similarity_scores[celebrity_name] += similarity_score
        else:
            weighted_similarity_scores[celebrity_name] = similarity_score

    # Get the celebrity with the highest weighted similarity score
    matched_celebrity = max(weighted_similarity_scores, key=weighted_similarity_scores.get)
    matched_image_path = celeb_name2path[matched_celebrity]

    return matched_celebrity,  matched_image_path

# The APP layout
st.title('Which bollywood celebrity are you?')

uploaded_image = st.file_uploader('Choose an image')

if uploaded_image is not None:
    # save the image in a directory
    if save_uploaded_image(uploaded_image):
        # load the image
        display_image = Image.open(uploaded_image)

        # extract the features
        features = extract_features(os.path.join('uploads', uploaded_image.name),model, face_detector)
        if features is not None:
            # recommend
            matched_celebrity, matched_imagepath = find_celebrity(celeb_feature_list, features)
            # display
            col1, col2 = st.columns(2)

            with col1:
                st.header('Your uploaded image')
                st.image(display_image)
            with col2:
                st.header("Looks like " + matched_celebrity)
                st.image(matched_imagepath, width=250)

        else:
            st.write("No Face could be detected. \n Possible reasons are \n- Image is too small or of low quality for face detection. \n- Image does not contain recognizable faces")

    else:
        st.subheader("Error! File could not be saved ")

else:
    st.subheader("Please Upload an image file.")


from __future__ import print_function

def readData(filename):
    # read input file, build memory array
    xmem = []
    f = open(filename,"r")
    data = f.readline()
    while len(data) > 0:
        line = data.split(",")
        for item in line:
            xmem.append(int(item))
        data = f.readline()
    f.close()
    return xmem

def initExec(mem, debug = False):
    # execute memory array program
    # 1 for add, 2 for multiply, 99 to stop
    # 1 a b c is [c] = [a] + [b]
    # 2 d e f is [d] = [e] * [f]
    # 99 is stop
    pc = 0
    op = mem[pc]
    while op in (1,2):
        if op == 1:
            fi = mem[pc+1]
            se = mem[pc+2]
            ne = mem[pc+3]
            if debug: print("%d: [%d] = [%d] + [%d]" % (pc,ne,fi,se))
            result = mem[fi] + mem[se]
            if debug: print("    %d = %d + %d" % (result,mem[fi],mem[se]))
            mem[ne] = result
            pc += 4
        elif op == 2:
            fi = mem[pc+1]
            se = mem[pc+2]
            ne = mem[pc+3]
            if debug: print("%d: [%d] = [%d] * [%d]" % (op,ne,fi,se))
            result = mem[fi] * mem[se]
            if debug: print("    %d = %d * %d" % (result,mem[fi],mem[se]))
            mem[ne] = result
            pc += 4
        else:
            print("instruction error at",pc)
            break
        op = mem[pc]

xmem = readData("day2-1.txt")
m1 = 0
m2 = 0
search = True
while search:
    mem = xmem[:]
    mem[1] = m1
    mem[2] = m2
    initExec(mem)
    if mem[0] != 19690720:
        m2 += 1
        if m2 > 100:
            m2 = 0
            m1 += 1
            if m1 > 100:
                print("did not find it")
                search = False
    else:
        search = False
print("finish",m1,m2)


import unittest
from dodge.constants import EventType, EventParam
from dodge.components.death.retaliatory import RetaliatoryDeath
from dodge.event import Event
from unittests.utils import EventStackStub

class TestRetaliatoryDeath(unittest.TestCase):
    def setUp(self):
        self.stack = EventStackStub()
        self.retaliatory = RetaliatoryDeath(self.stack)

    def test_handles_death(self):
        death = Event(EventType.DEATH, {EventParam.HANDLER: "alice",
                                        EventParam.KILLER: "bob"})
        self.assertTrue(self.retaliatory.handle_event(death))
        prepare_attack = self.stack.pop()
        self.assertTrue(self.stack.is_empty())
        self.assertEqual("alice", prepare_attack[EventParam.HANDLER])
        self.assertEqual("bob", prepare_attack[EventParam.TARGET])
        self.assertEqual(0, prepare_attack[EventParam.QUANTITY])

    def test_handles_death_no_killer(self):
        death = Event(EventType.DEATH, {EventParam.HANDLER: "alice"})
        self.assertEqual(death, self.retaliatory.handle_event(death))
        self.assertTrue(self.stack.is_empty())

    def test_handles_death_None_killer(self):
        death = Event(EventType.DEATH, {EventParam.HANDLER: "alice", EventParam.KILLER: None})
        self.assertEqual(death, self.retaliatory.handle_event(death))
        self.assertTrue(self.stack.is_empty())


"""
    testing.py - en este fichero python se encuentra el código fuente dedicado a los testings de
    cada Base de Datos(ck,jaffe,fer2013) con cada modelo hecho a partir de dichas Bases de datos:
    fer2013-pre(fer2013), modelkdef(kdef), modeljaffe.h5(jaffe) y modelck.h5(ck)

    Para hacer un test a una base de datos con un modelo pre-entrenado, se ejecuta este fichero
    agregando  la base ded atos elegida y el modelo con el que se va a probar el acierto.
        python  testing.py --db kdef --m fer2013
    El comando anterior prueba el modelo de fer2013 en las imagenes de kdef y devuelve como
    resultado el porcentaje de aciertos que ha obtenido respecto al total de imagenes de cada
    expresión. Con el comando anterior se obtendría por consola lo siguiente:

            ENFADO Id 0: 64.29 % | correct : 18  fail: 10
            REPUGNANCIA Id 1: 0.00 % | correct : 0  fail: 28
            MIEDO Id 2: 7.14 % | correct : 2  fail: 26
            FELICIDAD  Id 3: 100.00 % | correct : 28  fail: 0
            NEUTRAL Id 4: 96.43 number % | correct : 27  fail: 1
            TRISTEZA Id 5: 7.14 % | correct : 2  fail: 26
            SORPRESA Id 6: 10.71 % | correct : 3  fail: 25

            PRECISION TOTAL DE BD: 40.82 %
"""

import os
import cv2
import glob
import argparse
import numpy as np
from decimal import Decimal
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Flatten
from tensorflow.keras.layers import Conv2D
from tensorflow.keras.layers import MaxPooling2D

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

# ---------------------------parser de argumentos --db database --m model---------------------------

parser = argparse.ArgumentParser()
parser.add_argument("--db", help="ck/fer2013/jaffe/kdef/hibrido1/hibrido2/hibrido3/hibrido4/final")
parser.add_argument("--m", help="ck/fer2013/jaffe/kdef/hibrido1/hibrido2/hibrido3/hibrido4/final")
db = parser.parse_args().db
dbmodel = parser.parse_args().m

# dependiendo de la BD que se utilice para el testing tendremos ciertas expresiones. Usaremos una
# lista de las expresiones que maneja la BD y un diccionario que traduzca el indice de la expresión
# del modelo de la BD por el id de la expresión

if db == 'ck':
    emotions = ["anger", "disgust", "fear", "happy", "sad", "surprise"]  # Emotion list CK DB
    dict_db = {0: 0, 1: 1, 2: 2, 3: 3, 4: 5, 5: 6}
else:
    emotions = ["anger", "disgust", "fear", "happy", "neutral", "sad", "surprise"]  # GENERAL list
    dict_db = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6}
    # emotions = ["anger", "disgust", "fear", "happy", "neutral", "sad", "surprise"]  # Emotion list
    # fer2013 DB
    # dict_db = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6}

# guardamos el nombre del modelo y un diccionario que traduzca el índice de la expresión del modelo
# de la BD por el id de la expresión
dict_m = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6}
num_emotions = 7
if dbmodel == 'ck':
    name_m = 'models/modelck.h5'
    dict_m = {0: 0, 1: 1, 2: 2, 3: 3, 4: 5, 5: 6}
    num_emotions = 6
elif dbmodel == 'jaffe':
    name_m = 'models/modeljaffe.h5'
elif dbmodel == 'kdef':
    name_m = 'models/modelkdef.h5'
elif dbmodel == 'fer2013':
    name_m = 'models/fer2013-pre.h5'
elif dbmodel == 'hibrido1':
    name_m = 'models/modelhibrid1.h5'
elif dbmodel == 'hibrido2':
    name_m = 'models/modelhibrid2.h5'
elif dbmodel == 'hibrido3':
    name_m = 'models/modelhibrid3.h5'
elif dbmodel == 'hibrido4':
    name_m = 'models/modelhibrid4.h5'
    # dict_m = {0: 0, 1: 1, 2: 3, 3: 4, 4: 5, 5: 6}
elif dbmodel == 'final':
    name_m = 'models/modelfinal2.h5'
    dict_m = {0: 0, 1: 1, 2: 3, 3: 4, 4: 5, 5: 6}
    num_emotions = 6

# ----------------------FIN de parser de argumentos --db database --m model-------------------------

dict_orig = {0: "Angry", 1: "Disgusted", 2: "Fearful", 3: "Happy", 4: "Neutral", 5: "Sad",
             6: "Surprised"}
# dict_orig = {0: "Angry", 1: "Disgusted", 2: "Happy", 3: "Neutral", 4: "Sad", 5: "Surprised"}

"""
     Función auxiliar make_sets() para crear 2 listas:
     -testing_data: lista de todas las imágenes de todas las expresiones a testear
     -testing_labels: lista de las etiquetas de estas imágenes guardadas en el mismo orden, la
     etiqueta será el id identificativo de cada expresion en el modelo
"""

def make_sets():
    testing_data = []
    testing_labels = []
    # se recorren todas las expresiones
    for emotion in emotions:
        expression_data = glob.glob(db + "//test//%s//*" % emotion)
        for item in expression_data:  # repeat above process for prediction set
            image = cv2.imread(item)
            gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
            # cada imágen se cambia de espacio de color y se guarda en testing_data
            testing_data.append(gray)
            # se añade a la lista de etiquetas el índice de la expresión de la imágen
            testing_labels.append(emotions.index(emotion))

    return testing_data, testing_labels

"""
    Función auxiliar run_recognizer() para crear 2 listas y un porcentaje de aciertos general:
    -hit: aciertos de cada expresión
    -fail: fallos de cada expresión
"""

def run_recognizer():
    #lista de imagenes testing y sus etiquetas
    testing_data, testing_labels = make_sets()
    #estructuras para almacenar los aciertos y fallos para cada expresión
    hit = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0}
    fail = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0}
    cnt = 0
    correct = 0
    incorrect = 0

    for image in testing_data:
        # almacenado en prediction, de ese vector
        im = np.array(image)
        # ajustamos las dimensiones de la imágen hecha array
        im_array = np.expand_dims(np.expand_dims(im, -1), 0)
        # vector de estimación
        prediction = model.predict(im_array)
        # nos quedamos con el dato más alto cuyo indice de posición corresponde al íd identificativo
        # de la expresión
        pred = int(np.argmax(prediction))

        # si el id de la expresión es el mismo que el id de la expresión predecida se guarda el
        # acierto sino se guarda el fallo
        # print(pred)
        # print(pred in dict_m.keys())
        # print(dict_m[pred])
        # print(dict_db[testing_labels[cnt]])
        #print("%s lo predice como : %s"% (dict_orig[dict_db[testing_labels[cnt]]],
        #                                  dict_orig[dict_m[pred]]))

        if dict_m[pred] == dict_db[testing_labels[cnt]]:
            correct += 1
            hit[dict_m[pred]] = hit[dict_m[pred]] + 1
            cnt += 1
        else:
            incorrect += 1
            fail[dict_db[testing_labels[cnt]]] = fail[dict_db[testing_labels[cnt]]] + 1
            cnt += 1

    return ((100 * correct) / (correct + incorrect)), hit, fail

# --------------------- INICIO: Cargar modelo de Red Neuronal Convolucional ------------------------
model = Sequential()
"""
# capa 1 convolucional 32 filtros
# capa 2 convolucional 64 filtros
# capa 1 MaxPooling
# capa 3 convolucional 128 filtros
# capa 2 MaxPooling
# capa 3 convolucional 128 filtros
# capa 3 MaxPooling
# aplanamos el volumen resultante
# red neuronal con 1024 neuronas
# salida de 7 categorías
"""
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(48, 48, 1)))
model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_emotions, activation='softmax')) # CAMBIAR a 6 o 7

# cargar el modelo
model.load_weights(name_m)
# --------------------- FIN: Cargar modelo de Red Neuronal Convolucional ---------------------------

#metascore = 0
percentages_exp = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0}

perc, number_hits, number_fails = run_recognizer()
number_exp = 0

# print(number_hits)
# print(number_fails)

# recorremos las expresiones para sacaar la precisión de acierto
for j in range(0, 7):
    try:
        res = (number_hits[j] * 100) / (number_hits[j] + number_fails[j])
    except ZeroDivisionError:
        res = 0
    percentages_exp[j] = res

print("Resultados Testing modelo %s con BD %s" % (dbmodel, db))
print("\nENFADO Id 0: %.2f %% | correct : %d  fail: %d" % (Decimal(np.mean(percentages_exp[0])),
                                                           number_hits[0], number_fails[0] ))
print("REPUGNANCIA Id 1: %.2f %% | correct : %d  fail: %d" % (Decimal(np.mean(percentages_exp[1])),
                                                              number_hits[1], number_fails[1]))
print("MIEDO Id 2: %.2f %% | correct : %d  fail: %d" % (Decimal(np.mean(percentages_exp[2])),
                                                        number_hits[2], number_fails[2]))
print("FELICIDAD  Id 3: %.2f %% | correct : %d  fail: %d " % (Decimal(np.mean(percentages_exp[3])),
                                                              number_hits[3], number_fails[3]))
print("NEUTRAL Id 4: %.2f number %% | correct : %d  fail: %d" % (Decimal(np.mean(
    percentages_exp[4])), number_hits[4], number_fails[4]))
print("TRISTEZA Id 5: %.2f %% | correct : %d  fail: %d" % (Decimal(np.mean(percentages_exp[5])),
                                                           number_hits[5], number_fails[5]))
print("SORPRESA Id 6: %.2f %% | correct : %d  fail: %d" % (Decimal(np.mean(percentages_exp[6])),
                                                           number_hits[6], number_fails[6]))
print("\nPRECISION TOTAL DE BD: %.2f %%" % perc)


"""function used to recognise text in images"""

import pytesseract
from PIL import Image

def crop(input_path, coordinates, output_path=None):
    """
    @param input_path: The path to the image to edit
    @param coordinates: A tuple of x/y coordinates (x1, y1, x2, y2)
    @param output_path: Path to save the cropped image
    """
    image_obj = Image.open(input_path)
    cropped_image = image_obj.crop(coordinates)

    if output_path is not None:
        cropped_image.save(output_path)
    else:
        return cropped_image

def perform_ocr(input_path, coordinates):
    """
    @param input_path: The path to the image to edit
    @param coordinates: A tuple of x/y coordinates (x1, y1, x2, y2)
    """
    text_list = []
    config = '-l deu --oem 1 --psm 3'
    for coords in coordinates:
        cropped_image = crop(input_path=input_path, coordinates=coords)
        recognized_text = pytesseract.image_to_string(cropped_image, config=config)
        text_list.append(recognized_text)

    return text_list


__author__ = 'ub'

_ = float("inf")

def dijkstra(graph, n):
    dist = [0]*n
    pre = [0]*n
    flag = [False]*n
    flag[0] = True
    k = 0
    for i in range(n):
        dist[i] = graph[k][i]
    for j in range(n-1):
        min = _
        for i in range(n):
            if dist[i] < min and not flag[i]:
                min = dist[i]
                k = i
        if k == 0:
            return
        flag[k] = True
        for i in range(n):
            if dist[i] > dist[k] + graph[k][i]:
                dist[i] = dist[k] + graph[k][i]
                pre[i] = k
    return dist, pre

if __name__ == "__main__":
    n = 6
    graph = [
            [0,6,3,_,_,_],
            [6,0,2,5,_,_],
            [3,2,0,3,4,_],
            [_,5,3,0,2,3],
            [_,_,4,2,0,5],
            [_,_,_,3,5,0],
            ]
    dis, pre = dijkstra(graph, n)
    print(dis)
    print(pre)


"""Alpaca real time news streaming."""
# %% codecell
import json
from pathlib import Path
import asyncio
import websockets
from io import BytesIO
import pandas as pd

try:
    from scripts.dev.multiuse.help_class import baseDir, getDate, write_to_parquet
    from scripts.dev.data_collect.alpaca.api_calls.apca_auth import ApcaAuth
except ModuleNotFoundError:
    from multiuse.help_class import baseDir, getDate, write_to_parquet
    from data_collect.alpaca.api_calls.apca_auth import ApcaAuth

# %% codecell

class ApcaNewsStream(ApcaAuth):
    """Apca real-time news stream with websockets."""

    # Url for websocket streaming
    uri = 'wss://stream.data.alpaca.markets/v1beta1/news'
    # All stock and crypto symbols
    subscribe_all = {"action": "subscribe", "news": ["*"]}
    # Unsubscribe
    unsubscribe_all = {"action": "unsubscribe", "news": ["*"]}

    def __init__(self, **kwargs):
        ApcaAuth.__init__(self, **kwargs)
        self.auth = self._create_auth_msg(self, **kwargs)
        self.fpath = self._create_fpath(self, **kwargs)
        self._start_news_streaming(self)

    @classmethod
    def _create_auth_msg(cls, self, **kwargs):
        """Create auth message."""
        auth = ({"action": "auth",
                 "key": self.headers['APCA-API-KEY-ID'],
                 "secret": self.headers['APCA-API-SECRET-KEY']})

        auth = json.dumps(auth)
        return auth

    @classmethod
    def _create_fpath(cls, self, **kwargs):
        """Construct and return fpath."""
        bpath = Path(baseDir().path, 'alpaca', 'news', 'real_time')
        dt = getDate.query('iex_eod')
        f_path = bpath.joinpath(f"_{str(dt.year)}.parquet")
        return f_path

    @classmethod
    def _start_news_streaming(cls, self):
        """instantiate news streaming function."""
        try:
            loop = asyncio.get_running_loop()
            if loop and loop.is_running():
                print('Loop is running')
                tsk = loop.create_task(self._news_streaming(self))
        except RuntimeError:
            asyncio.run(self._news_streaming(self))

    @classmethod
    async def _news_streaming(cls, self):
        """Asyncio news streaming."""
        async for ws in websockets.connect(self.uri):
            try:
                a = await ws.send(self.auth)
                print(str(await ws.recv()))
                sa = await ws.send(json.dumps(self.subscribe_all))
                print(str(await ws.recv()))

                msg = await self._process_message(self, ws)
            except websockets.ConnectionClosed:
                continue

    @classmethod
    async def _process_message(cls, self, ws):
        """Process message and write to dataframe."""
        while True:
            data = await ws.recv()
            try:
                data = json.loads(data)[0]
                if 'headline' in data.keys():
                    df = pd.json_normalize(data)
                    kwargs = {'cols_to_drop': 'id'}
                    write_to_parquet(df, self.fpath, combine=True, **kwargs)
            except AttributeError as ae:
                print(str(ae))
                print(str(data))

                try:
                    df = pd.DataFrame(json.load(BytesIO(data)))
                    kwargs = {'cols_to_drop': 'id'}
                    write_to_parquet(df, self.fpath, combine=True, **kwargs)
                except Exception as e:
                    print(f"{str(e)} {type(e)}")
                continue


import numpy as np
import pandas as pd

df = pd.read_csv('233x_sequences_degdata_081120.csv')

print(df.keys())

df['RT_PCR_length'] = df['RT_PCR_end_pos']-df['RT_PCR_start_pos']

df['k_deg_normalize'] = df['k_deg_per_hour']/df['RT_PCR_length']
df['k_deg_err_normalize'] = df['k_deg_err_per_hour']/df['RT_PCR_length']

df['length'] = [len(x) for x in df['RNA_sequence']]

df['SUP DegScore2.1 FULL'] = np.nansum(np.loadtxt('formatted_predictions/Degscore_2.1_flat_FULL_233x.csv',delimiter=','),axis=1)
df['SUP DegScore2.1 PCR'] = np.nansum(np.loadtxt('formatted_predictions/Degscore_2.1_flat_PCR_233x.csv',delimiter=','),axis=1)

df['SUP Vienna FULL'] = np.nansum(np.loadtxt('formatted_predictions/P_UNP_vienna_flat_FULL_233x.csv',delimiter=','),axis=1)
df['SUP Vienna PCR'] = np.nansum(np.loadtxt('formatted_predictions/P_UNP_vienna_flat_PCR_233x.csv',delimiter=','),axis=1)

df['SUP EternaFold FULL'] = np.nansum(np.loadtxt('formatted_predictions/P_UNP_eternafold_flat_FULL_233x.csv',delimiter=','),axis=1)
df['SUP EternaFold PCR'] = np.nansum(np.loadtxt('formatted_predictions/P_UNP_eternafold_flat_PCR_233x.csv',delimiter=','),axis=1)

df['SUP nullrecurrent FULL'] = np.nansum(np.loadtxt('formatted_predictions/nullrecurrent_posthoc_hkws_FULL_233x.csv',delimiter=','),axis=1)
df['SUP nullrecurrent PCR'] = np.nansum(np.loadtxt('formatted_predictions/nullrecurrent_posthoc_hkws_PCR_233x.csv',delimiter=','),axis=1)

df['SUP kazuki2 FULL'] = np.nansum(np.loadtxt('formatted_predictions/kazuki2_deg_Mg_pH10_flat_FULL_233x.csv',delimiter=','),axis=1)
df['SUP kazuki2 PCR'] = np.nansum( np.loadtxt('formatted_predictions/kazuki2_deg_Mg_pH10_flat_PCR_233x.csv',delimiter=','),axis=1)

df['SUP Degscore-XGB FULL'] = np.nansum(np.loadtxt('formatted_predictions/Degscore-XGB_FULL_233x.csv',delimiter=','),axis=1)
df['SUP Degscore-XGB PCR'] = np.nansum(np.loadtxt('formatted_predictions/Degscore-XGB_PCR_233x.csv',delimiter=','),axis=1)

df['SUP nr_k2_ensembled FULL'] = df.apply(lambda row: 0.5*(row['SUP nullrecurrent FULL']+row['SUP kazuki2 FULL']), axis=1)
df['SUP nr_k2_ensembled PCR'] = df.apply(lambda row: 0.5*(row['SUP nullrecurrent PCR']+row['SUP kazuki2 PCR']), axis=1)

predictor_list = ['Vienna', 'EternaFold', 'DegScore2.1', 'Degscore-XGB','nullrecurrent','kazuki2', 'nr_k2_ensembled']

for pred in predictor_list:
	df['AUP %s PCR'% pred] = df['SUP %s PCR'%pred]/df['RT_PCR_length']
	df['AUP %s FULL'%pred] = df['SUP %s FULL'%pred]/df['length']

df = df.loc[df['single_exp_fit_ok']==1]
df = df.loc[df['k_deg_per_hour']>0]

for typ in ['SUP','AUP']:
	for typ2 in ['FULL','PCR']:
		lst = ['k_deg_per_hour', 'k_deg_normalize']
		for pred in predictor_list:
			lst.append("%s %s %s" % (typ, pred, typ2))
		print(df[lst].corr())
		#print(df[lst+['Expt type']].groupby('Expt type').corr())

df.to_csv('collated_predictions_all_models_233x.csv',index=False)


"""empty message

Revision ID: d91e0e2fb7a3
Revises: 9e6583e6f8a6
Create Date: 2023-10-29 04:12:30.717424

"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql

# revision identifiers, used by Alembic.
revision = 'd91e0e2fb7a3'
down_revision = '9e6583e6f8a6'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table('board', schema=None) as batch_op:
        batch_op.alter_column('member_name',
               existing_type=mysql.INTEGER(),
               type_=sa.String(length=30),
               nullable=False)
        batch_op.create_foreign_key(None, 'users', ['member_name'], ['member_name'], ondelete='CASCADE')

    with op.batch_alter_table('comment', schema=None) as batch_op:
        batch_op.add_column(sa.Column('member_name', sa.String(length=30), nullable=False))
        batch_op.create_foreign_key(None, 'users', ['member_name'], ['member_name'], ondelete='CASCADE')

    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table('comment', schema=None) as batch_op:
        batch_op.drop_constraint(None, type_='foreignkey')
        batch_op.drop_column('member_name')

    with op.batch_alter_table('board', schema=None) as batch_op:
        batch_op.drop_constraint(None, type_='foreignkey')
        batch_op.alter_column('member_name',
               existing_type=sa.String(length=30),
               type_=mysql.INTEGER(),
               nullable=True)

    # ### end Alembic commands ###


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Sep 18 17:10:33 2019

@author: rj299
"""

import numpy as np
import os
import scipy.io as spio
import pandas as pd

#%%
data_behav_root = '/home/rj299/scratch60/mdm_analysis/data_behav'
out_root = '/home/rj299/scratch60/mdm_analysis/output'
# data_behav_root = 'D:\Ruonan\Projects in the lab\MDM Project\Medical Decision Making Imaging\MDM_imaging\Behavioral Analysis\PTB Behavior Log'

# subjects for imaging analysis
sub_num = [2073, 2550, 2582, 2583, 2584, 2585, 2588, 2592, 2593, 2594, 2596, 2597, 2598, 2599, 2600, 2624,
           2650, 2651, 2652, 2653, 2654, 2655, 2656, 2657, 2658, 2659, 2660, 2661, 2662, 2663, 2664, 2665, 2666]
#sub_nums = [2599, 2661]

#%% read parameters to calculate SV
par = pd.read_csv(os.path.join(data_behav_root, 'par_09300219.csv'))

#%% calculate SV
def ambig_utility(sub_id, par, p, a, obj_val, domain, model):
    '''
    Calcualte subjective value based on model
    For a list of trials

    Input:
        sub_id: subject id
        par: panda data frame of all subjects' parameter fits
        p: probability of lotteries, vector
        a: ambiguity of lotteries, vector
        obj_val: objective value of lottery pary-offs, vector
        domain_idx: domian indes, 1-medical, 0-monetary
        model: named of the subjective value model

    Output:
        sv: subjective values of lotteries, vector
    '''

    if domain == 'Med':
        domain_idx = 1
    elif domain == 'Mon':
        domain_idx = 0

    par_sub = par[(par.id == sub_id) & (par.is_med == domain_idx)]

    beta = par_sub.iloc[0]['beta']
    val1 = par_sub.iloc[0]['val1']
    val2 = par_sub.iloc[0]['val2']
    val3 = par_sub.iloc[0]['val3']
    val4 = par_sub.iloc[0]['val4']

    val = np.zeros(obj_val.shape)
    val[obj_val == 5] = val1
    val[obj_val == 8] = val2
    val[obj_val == 12] = val3
    val[obj_val == 25] = val4

    if model == 'ambigSVPar':
        sv = (p - beta * a/2) * val

    ref_sv = np.ones(obj_val.shape) * val1

    return sv, ref_sv

#%%
def _todict(matobj):
    '''
    Author: Or

    A recursive function which constructs from matobjects nested dictionaries
    '''
    dict = {}
    for strg in matobj._fieldnames:
        elem = matobj.__dict__[strg]
        if isinstance(elem, spio.matlab.mio5_params.mat_struct):
            dict[strg] = _todict(elem)
        else:
            dict[strg] = elem
    return dict

def _check_keys(dict):
    '''
    Author: Or

    checks if entries in dictionary are mat-objects. If yes todict is called to change them to nested dictionaries
    '''
    for key in dict:
        if isinstance(dict[key], spio.matlab.mio5_params.mat_struct):
            dict[key] = _todict(dict[key])
    return dict

def loadmat(filename):
    '''
    Author: Or

    this function should be called instead of direct spio.loadmat
    as it cures the problem of not properly recovering python dictionaries
    from mat files. It calls the function check keys to cure all entries
    which are still mat-objects

    from: `StackOverflow <http://stackoverflow.com/questions/7008608/scipy-io-loadmat-nested-structures-i-e-dictionaries>`_
    '''
    data = spio.loadmat(filename, struct_as_record=False, squeeze_me=True)
    return _check_keys(data)

#%%
def readConditions(subNum, domain, matFile, x): # takes name of file and when to begin (i.e. first block is zero. second is 21 etc.)
    """ read condition onset and duration
    Author: Or

    Parameters
    -------------
    subNum: subject id
    domain: domain name, 'Med' or 'Mon'
    matFile: filename
    x: trial index at the begining of each block

    Return
    -------------
    events
    """

    metaData = loadmat(matFile)
    # get the key names for the data, as half is 'Datamed', half is 'Datamon'
    data_keyname = list(metaData.keys())[3]
    # trial number per block
    trial_num = 21

    timeStamp = []
    condition = []
    events = []
    resultsArray = []
    duration = []
    resp_array =[]
    resp_onset = []

    ambigs = metaData[data_keyname]['ambigs']
    probs = metaData[data_keyname]['probs']
    vals = metaData[data_keyname]['vals']
    svs, ref_svs = ambig_utility(subNum, par, probs, ambigs, vals, domain, 'ambigSVPar')
    choice = metaData[data_keyname]['choice']
    refside = metaData[data_keyname]['refSide']

    # calculate response from choice and refside
    resp = np.ones(choice.shape) # 1-choose lottery
    resp[choice == refside] = 0 # 0-choose reference
    resp[choice == 0] = 2 # 2-no respone

    # x= 0 # where to start
    for i in range(x, x+trial_num):
        #a= metaData['Data']['trialTime'][i]
        #b = vars(a)

        # trial onset
        resultsArray = vars(metaData[data_keyname]['trialTime'][i])['trialStartTime'] - vars(metaData[data_keyname]['trialTime'][x])['trialStartTime']
        timeStamp.append(int(round((3600*resultsArray[3] + 60*resultsArray[4] + resultsArray[5])))) # using int and round to round to the close integer.

        # response onset
        resp_array = vars(metaData[data_keyname]['trialTime'][i])['feedbackStartTime'] - vars(metaData[data_keyname]['trialTime'][x])['trialStartTime']
        resp_onset.append(int(round((3600*resp_array[3] + 60*resp_array[4] + resp_array[5])))) # using int and round to round to the close integer.

        duration.append(6)

        if ambigs[i] == 0:
            condition.append('risk')
        else:
            condition.append('amb')

    events= pd.DataFrame({'trial_type':condition, 'onset':timeStamp, 'duration':duration,
                          'probs': probs[range(x, x+trial_num)], 'ambigs': ambigs[range(x, x+trial_num)], 'vals': vals[range(x, x+trial_num)],
                          'svs': np.round(svs[range(x, x+trial_num)], 3), 'ref_svs': np.round(ref_svs[range(x, x+trial_num)], 3),
                          'resp': resp[range(x, x+trial_num)],
                          'resp_onset': resp_onset})[1:] # building data frame from what we took. Removing first row because its not used.
    return events

def organizeBlocks(subNum):
    # Read both mat files (first timestamp)
    # check first block of each day.
    # check thrird of each day
    # sort
    trial_num = 21

    orderArray = []

    mat_med_name = os.path.join(data_behav_root, 'subj%s' %subNum, 'MDM_MED_%s.mat' %subNum)
    mat_mon_name = os.path.join(data_behav_root, 'subj%s' %subNum, 'MDM_MON_%s.mat' %subNum)

#     matFileLoss = '/media/Drobo/Levy_Lab/Projects/R_A_PTSD_Imaging/Data/Behavior data/Behavior_fitpar/Behavior data fitpar_091318/RA_LOSS_%s_fitpar.mat'%subNum
#     matFileGain = '/media/Drobo/Levy_Lab/Projects/R_A_PTSD_Imaging/Data/Behavior data/Behavior_fitpar/Behavior data fitpar_091318/RA_GAINS_%s_fitpar.mat'%subNum
    metaDataMed = loadmat(mat_med_name)
    data_med_keyname = list(metaDataMed.keys())[3]
    metaDataMon = loadmat(mat_mon_name)
    data_mon_keyname = list(metaDataMon.keys())[3]

    # trial start time of the 1st and the 3rd block in each domain
    a= {'1stMed':list(vars(metaDataMed[data_med_keyname]['trialTime'][0])['trialStartTime']), '3rdMed':list(vars(metaDataMed[data_med_keyname]['trialTime'][trial_num*2])['trialStartTime']), '1stMon':list(vars(metaDataMon[data_mon_keyname]['trialTime'][0])['trialStartTime']), '3rdMon':list(vars(metaDataMon[data_mon_keyname]['trialTime'][trial_num*2])['trialStartTime'])}
    # sort by trial start time
    s = [(k, a[k]) for k in sorted(a, key=a.get, reverse=False)]
    for k, v in s:
        print (k, v)
        orderArray.append(k)

    totalEvent = []
    for n in orderArray:
        print (n)
        if n=='1stMed':
            # run Med mat file on readConcitions function on first two blocks (i.e. 0, 21)
            print (n)
            for x in [0,trial_num]:
                event = readConditions(subNum, 'Med', mat_med_name, x)
                event['condition'] = 'Med'
                totalEvent.append(event)
        elif n=='1stMon':
            # run Mon mat file on readCondition function
            print (n)
            for x in [0,trial_num]:
                event = readConditions(subNum, 'Mon', mat_mon_name, x)
                event['condition'] = 'Mon'
                totalEvent.append(event)
        elif n=='3rdMed':
            print (n)
            for x in [trial_num*2, trial_num*3]:
                event = readConditions(subNum, 'Med', mat_med_name, x)
                event['condition'] = 'Med'
                totalEvent.append(event)
        elif n=='3rdMon':
            # run Mon from 3rd block
            print (n)
            for x in [trial_num*2, trial_num*3]:
                event = readConditions(subNum, 'Mon', mat_mon_name, x)
                event['condition'] = 'Mon'
                totalEvent.append(event)
        else:
            print ('The condition ' + n + ' is not clear.')

        # the end result is an array of data sets per each run (i.e. block) - called totalEvent
    return totalEvent

#%% test
sub_id = 2588
mat_med_name = os.path.join(data_behav_root, 'subj%s' %sub_id, 'MDM_MED_%s.mat' %sub_id)

mat_med_name
behav_med = loadmat(mat_med_name)
list(behav_med.keys())[3]
behav_med['Datamed'].keys()

sub_id = behav_med['Datamed']['observer']
probs = behav_med['Datamed']['probs']
ambigs = behav_med['Datamed']['ambigs']
vals = behav_med['Datamed']['vals']
trialTime = behav_med['Datamed']['trialTime']

choice = behav_med['Datamed']['choice']
print(choice)
print(choice.shape)

behav_med['Datamed']['trialTime'][0]._fieldnames
behav_med['Datamed']['trialTime'][0].__dict__['trialStartTime']
vars(behav_med['Datamed']['trialTime'][0])
list(range(0, 21))

#%%
totalEvent_sub = organizeBlocks(2588)
totalEvent_sub[0]

#%%
# read conditions and write into csv files

for sub_id in sub_num:
    totalEvent_sub = organizeBlocks(sub_id)
    # write into csv

    for task_id in range(8):
        pd.DataFrame(totalEvent_sub[task_id]).to_csv(os.path.join(out_root, 'event_files', 'sub-' + str(sub_id)+ '_task-' +str(task_id+1) + '_cond_v3.csv'),
                          index = False, sep = '\t')


"""
    Implementation of bagged models
"""
import multiprocessing
import numpy as np
from joblib import Parallel, delayed

class BaggedModel:
    """
        Implements a bagged model.

        Used methods:
        * fit, get_rank_cell
    """

    def __init__(self, n_sample, card_sample, model_instantiator):
        self.n_sample = n_sample
        self.card_sample = card_sample
        self.parallel = True
        # private
        self._model_instantiator = model_instantiator
        self._fitted_models = list()

    def fit(self, X, y):
        """Fits several trees."""
        samples = [self._get_random_sample(X, y)
                   for _ in range(self.n_sample)]

        if self.parallel:
            pool = Parallel(n_jobs=multiprocessing.cpu_count()-10)
            self._fitted_models = pool(
                delayed(self._get_fitted_model)(X_samp, y_samp)
                for X_samp, y_samp in samples
            )
        else:
            self._fitted_models = [
                self._get_fitted_model(X_samp, y_samp)
                for X_samp, y_samp in samples
            ]

    def median_rank(self, X):
        """
        Returns the median of the rank of the cells of the X's.

        Which with that notation just means that lots of cells
        will have the same rank.
        """
        rank_values = list()

        if self.parallel:
            pool = Parallel(n_jobs=multiprocessing.cpu_count()//2)
            rank_values = pool(delayed(lambda x: x.get_rank_cell(X))(model)
                               for model in self._fitted_models)
        else:
            for model in self._fitted_models:
                rank_values.append(model.get_rank_cell(X))
        rank_array = np.array(rank_values).transpose()
        return np.mean(rank_array, axis=1)
        # return np.median(rank_array, axis=1)

    def score(self, X):
        """A score, derived from the median rank."""
        return - self.median_rank(X)

    def _get_random_sample(self, X, y):
        ind_sample = np.random.randint(0, X.shape[0], self.card_sample)
        return X[ind_sample], y[ind_sample]

    def _get_fitted_model(self, X_resampled, y_resampled):
        cur_model = self._model_instantiator()
        cur_model.fit(X_resampled, y_resampled)
        return cur_model


import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets, linear_model
from sklearn.metrics import mean_squared_error, r2_score
from GSKpy.BasicGSK import  BasicGSK
# Load the diabetes dataset
diabetes_X, diabetes_y = datasets.load_diabetes(return_X_y=True)

# Use only one feature
#diabetes_X = diabetes_X[:, np0]
print('Train data shape:',diabetes_X.shape)
diabetes_X_train = diabetes_X[:-20]
diabetes_X_test = diabetes_X[-20:]

# Split the targets into training/testing sets
diabetes_y_train = diabetes_y[:-20]
diabetes_y_test = diabetes_y[-20:]

regr = linear_model.LinearRegression()
regr.fit(diabetes_X_train, diabetes_y_train)
diabetes_y_pred = regr.predict(diabetes_X_test)
print('MSE=',mean_squared_error(diabetes_y_test, diabetes_y_pred))
dim = len(regr.coef_)
def evaluateFun(coef,func_args=None):
    fitness_val = []
    for co in coef:
        regr.coef_ = co
        diabetes_y_pred = regr.predict(diabetes_X_train)
        #print(mean_squared_error(diabetes_y_train, diabetes_y_pred))
        fitness_val.append(mean_squared_error(diabetes_y_train, diabetes_y_pred))
    return np.array(fitness_val)

for i in range(30):
    solver = BasicGSK(evaluateFun, dim, 200, [-1000]*dim,[1000]*dim,LPSR=True,kr=0.1,max_nfes=100000)
    g, best , best_fit, loss = solver.run(optimum=0)
    regr.coef_ = best
    diabetes_y_pred = regr.predict(diabetes_X_test)
    print()
    print('MSE=',mean_squared_error(diabetes_y_test, diabetes_y_pred))


from telemetry.web_perf import timeline_based_measurement
from telemetry.timeline import chrome_trace_config

_JS_FLAGS_SWITCH = '--js-flags='

def AppendJSFlags(options, js_flags):
  existing_js_flags = ''
  # There should be only one occurence of --js-flags in the browser flags. When
  # there are multiple flags, only one of them would be used. Append any
  # additional js_flags to the existing flags (if present).
  for extra_arg in options.extra_browser_args:
    if extra_arg.startswith(_JS_FLAGS_SWITCH):
      # Find and remove the set of existing js_flags.
      existing_js_flags = extra_arg[len(_JS_FLAGS_SWITCH):]
      options.extra_browser_args.remove(extra_arg)
      break

  options.AppendExtraBrowserArgs([
      # Add a new --js-flags which includes previous flags.
      '%s%s %s' %  (_JS_FLAGS_SWITCH, js_flags, existing_js_flags)
  ])

def AugmentOptionsForV8Metrics(options, enable_runtime_call_stats=True):
  categories = [
      # Disable all categories by default.
      '-*',
      # Memory categories.
      'disabled-by-default-memory-infra',
      'toplevel',
      # V8 categories.
      'cppgc',
      'disabled-by-default-cppgc',
      'disabled-by-default-v8.gc',
      'v8',
      'v8.wasm',
      'v8.console',
      'webkit.console',
      # Blink categories.
      'blink_gc',
      'partition_alloc',
      # Needed for the metric reported by page.
      'blink.user_timing'
  ]

  options.ExtendTraceCategoryFilter(categories)
  if enable_runtime_call_stats:
    options.AddTraceCategoryFilter('disabled-by-default-v8.runtime_stats')

  options.config.enable_android_graphics_memtrack = True
  # Trigger periodic light memory dumps every 1000 ms.
  memory_dump_config = chrome_trace_config.MemoryDumpConfig()
  memory_dump_config.AddTrigger('light', 1000)
  options.config.chrome_trace_config.SetMemoryDumpConfig(memory_dump_config)

  options.config.chrome_trace_config.SetTraceBufferSizeInKb(400 * 1024)

  metrics = [
      'blinkGcMetric',
      'consoleErrorMetric',
      'expectedQueueingTimeMetric',
      'gcMetric',
      'memoryMetric',
      'pcscanMetric',
      'reportedByPageMetric',
      'wasmMetric',
  ]
  options.ExtendTimelineBasedMetric(metrics)
  if enable_runtime_call_stats:
    options.AddTimelineBasedMetric('runtimeStatsTotalMetric')
  return options

class V8PerfMixin(object):
  """Base class for V8 benchmarks that measure RuntimeStats,
  eqt, gc and memory metrics.
  """

  def CreateCoreTimelineBasedMeasurementOptions(self):
    options = timeline_based_measurement.Options()
    AugmentOptionsForV8Metrics(options)
    return options

  def SetExtraBrowserOptions(self, options):
    options.AppendExtraBrowserArgs(
        '--enable-blink-features=BlinkRuntimeCallStats')
    options.AppendExtraBrowserArgs(['--disable-popup-blocking'])


import matplotlib.pyplot as plt
import fileMethod as file
import aStar
import BFS
import DFS
import Draw
import CheckPoints as cp

if __name__ == "__main__":
    # doc file lay thong tin ban do
    map = input("Choose map (1, 2, 3, 4): ")
    mapData = file.readFileData("map" + map + ".txt")
    mode = int(input("Choose Algorithm: \n1: A*\n2: BFS\n3: DFS\n4: Check Points\nYour choice: "))
    path = []
    cost = 0
    method = aStar.aStarMethod(mapData.obstacles)

    # A star
    if mode == 1:
        path, cost = aStar.aStartAlgorithm(mapData, method)
        if path == None and cost == None:
            print("A* failed in find a path to end point")
        file.writeFile(mapData, path, cost)

    # BFS
    elif mode == 2:
        path, cost = BFS.BFSFunc(mapData)
        if path == None and cost == None:
            print("BFS failed in find a path to end point")
        file.writeFile(mapData, path, cost)

    # DFS
    elif mode == 3:
        path, cost = DFS.DFSFunc(mapData)
        if path == None and cost == None:
            print("DFS failed in find a path to end point")
        else:
            file.writeFile(mapData, path, cost)

    # A* checkpoints
    elif mode == 4:
        path, cost = cp.findPathPriority(mapData, method)
        if path == None and cost == None:
            print("A* failed in find a path from start to check points and end point")
        file.writeFile(mapData, path, cost)
    # in cost ra man hinh
    print("cost: ", cost)
    # goi ham ve
    Draw.drawGraph(mapData, path)