from utm import utmconv
from math import pi, cos, sin, sqrt, asin, acos

def getLattitudeConvertionError(lattitude, longitude, lattitude_difference):
    earthRadius = 6378137.0

    (hemisphere, zone, letter, e, n) = uc.geodetic_to_utm(lattitude, longitude)
    e_new = e + lattitude_difference
    n_new = n

    # convert back from UTM to geodetic
    (lattitude_new, longitude_new) = uc.utm_to_geodetic(
        hemisphere, zone, e_new, n_new)
    print("Coordinates: ", lattitude, ",", longitude)

    print("New Coordinates: ", lattitude_new, ",", longitude_new)
    # calculate the error using Great Circle Distance Formula
    calc_distance = 2*asin(sqrt((sin((lattitude*(pi/180)-lattitude_new*(pi/180))/2))**2+cos(
        lattitude*(pi/180))*cos(lattitude_new*(pi/180))*(sin((longitude*(pi/180)-longitude_new*(pi/180))/2))**2))
    # Great circle distance can be likewise be expressed in radians by defining the distance to be the angle subtended by the
    # arc at the center of the earth. Since by definition, one nautical mile subtends one minute (=1/60 degree) of arc, we have:
    calc_distance = calc_distance*((180*60)/pi)
    calc_distance = calc_distance*1852
    error = lattitude_difference - calc_distance

    print('Distance: ', lattitude_difference,
          ' Calculated distance: ', calc_distance, 'Error: ',  error)
    return error

def getLongitudeConvertionError(lattitude, longitude, longitude_difference):
    earthRadius = 6378137.0
    # Convert from geodetic to UTM and add distance
    (hemisphere, zone, letter, e, n) = uc.geodetic_to_utm(lattitude, longitude)
    e_new = e
    n_new = n + longitude_difference

    # convert back from UTM to geodetic
    (lattitude_new, longitude_new) = uc.utm_to_geodetic(
        hemisphere, zone, e_new, n_new)
    print("Coordinates: ", lattitude, ",", longitude)
    print("New Coordinates: ", lattitude_new, ",", longitude_new)

    # calculate the error using Great Circle Distance Formula
    calc_distance = 2*asin(sqrt((sin((lattitude*(pi/180)-lattitude_new*(pi/180))/2))**2+cos(
        lattitude*(pi/180))*cos(lattitude_new*(pi/180))*(sin((longitude*(pi/180)-longitude_new*(pi/180))/2))**2))
    calc_distance = ((180*60)/pi)*calc_distance  # radians to degrees*seconds
    calc_distance = calc_distance*1852  # Nautic mile to km
    error = longitude_difference - calc_distance

    print('Distance: ', longitude_difference,
          ' Calculated distance: ', calc_distance, 'Error: ',  error)
    return error

def exercise_4_1():
    # Drone center
    lat1 = 55.47
    lon1 = 10.33
    print("Error @ the Drone Center")
    getLattitudeConvertionError(lat1, lon1, 100.)

    # Iceland
    lat1 = 55.47
    lon1 = 12.33
    print("Error @ Iceland")
    getLattitudeConvertionError(lat1, lon1, 1000.)

    # Greenland
    lat1 = 55.47
    lon1 = 20.33
    print("Error @ Greenland")

    getLattitudeConvertionError(lat1, lon1, 1000.)

    # Longitude test
    lat1 = 55.47
    lon1 = 50.33
    print("Error Longitude Test")
    getLongitudeConvertionError(lat1, lon1, 1000.)

# instantiate utmconv class
uc = utmconv()

# exercise_4_1()

# lat1 = 55.12518
# lon1 = 10.25419
# print("Error @ the Drone Center")
# getLattitudeConvertionError(lat1, lon1, 1000.)


import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-3,3,100)
y = np.sin(x)

fig = plt.figure()
ax = fig.add_subplot(111)

plt.plot(x,y)
plt.plot(y,x)
plt.xlim(-3,3)
plt.ylim(-3,3)

ax.set_aspect('equal', adjustable='box')

plt.xlabel("x")
plt.ylabel("sinx")

plt.show()


import cv2
import glob
import numpy as np

image_true_paths = [
    "testdata/gMH/restrueimages/*.png",
]

image_train_paths =[
    "testdata/gMH/resimages/*.png",
]

video_paths = [
    "videos/truevalidation_gMH_compare.mp4",
]

for i in range(0, 1):
    # print(image_paths[i])
    trueimages = sorted(glob.glob(image_true_paths[i]))
    trainimages = sorted(glob.glob(image_train_paths[i]))
    #(images)
    cap = cv2.VideoCapture()

    # Define the codec and create VideoWriter object.The output is stored in 'outpy.avi' file.
    out = cv2.VideoWriter(video_paths[i], cv2.VideoWriter_fourcc('m','p','4','v'), 60, (3840,1080))
    for j in range(len(trueimages)):
        trueimage=cv2.imread(trueimages[j])
        trainimage=cv2.imread(trainimages[j])
        frame=cv2.hconcat([trueimage,trainimage])
        # print(image)
        #frame = cv2.imread(image)
        # Write the frame into the file 'output.avi'
        out.write(frame)

    # When everything done, release the video capture and video write objects
    out.release()


# Copyright (c) 2014, Adam J. Rossi. All rights reserved. See README for licensing details.
import sys, uuid, string, os
import Chain, Analyze

class StageBase:

    MAX_INPUT_STAGES = sys.maxint

    def __init__(self, inputStages=None, stageDoc="", parameterDoc=None):
        self.__stageDoc = stageDoc
        if (parameterDoc==None): self.__parameterDoc = {}
        else:                    self.__parameterDoc = parameterDoc
        self._properties = {}
        self.__inputStages = []
        self.__outputStages = []
        self.__outputCache = None
        self.__prepared = False
        self._uid = uuid.uuid1()
        if (inputStages!=None):
            self.AddInputStage(inputStages)
        import StageRegistry
        if ("registry" in dir(StageRegistry) and
            StageRegistry.registry.IsInitialized()):
            StageRegistry.registry.AddInstance(self)

    def AddInputStage(self, stages):
        self.__prepared = False
        if (isinstance(stages, list)):
            self.__inputStages += stages
            for stage in stages: stage.AddOutputStage(self)
        else:
            self.__inputStages.append(stages)
            stages.AddOutputStage(self)

    def AddOutputStage(self, stages):
        if (isinstance(stages, list)):  self.__outputStages += stages
        else:                           self.__outputStages.append(stages)

    def RemoveConnections(self):
        for outputStage in self.__outputStages:
            outputStage.__inputStages.remove(self)
        for inputStage in self.__inputStages:
            inputStage.__outputStages.remove(self)

    def GetInputStages(self):
        return self.__inputStages

    def GetOutputStages(self):
        return self.__outputStages

    def NumInputStages(self):
        return len(self.__inputStages)

    def GetPropertyMap(self):
        d = {}
        for n in self._properties:
            d[n] = type(self._properties[n])
        return d

    def GetPackageName(self):
        return str(self.__class__).split(".")[0]

    def GetStageName(self):
        return self.__class__.__name__

    def GetStageDescription(self):
        return self.__stageDoc

    def GetPropertyDescription(self, name):
        if (name in self.__parameterDoc.keys()):
            return self.__parameterDoc[name]
        else:
            raise Exception("Property does not exist: " + name)

    def SetPropertyDescription(self, name, desc):
        self.__parameterDoc[name] = desc

    def GetProperty(self, name):
        if (name in self._properties.keys()):
            return self._properties[name]
        else:
            raise Exception("Property does not exist: " + name)

    def SetProperty(self, name, val):
        if (name in self._properties.keys()):
            self._properties[name] = val
        else:
            raise Exception("Property does not exist: " + name)

    def __GetInputStagesInterfaces(self):
        # return list of dictionaries that represent the input stages' interface
        return [stage.GetOutputInterface() for stage in self.__inputStages]

    def Reset(self):
        self.__prepared = False
        for stage in self.GetInputStages(): stage.Reset()

    def Prepare(self):
        # check:
        #   - parameters
        #   - inputs' outputs
        #   - max number of input stages

        # depth-first prepare
        for stage in self.GetInputStages(): stage.Prepare()
        if (self.__prepared): return

        # clear cache
        self.__outputCache = None

#        # validate interface names/types
#        myInputInterface = self.GetInputInterface()
#        for stage in self.__inputStages:
#            inputStageInterface = stage.GetOutputInterface()
#            for inputKey in myInputInterface.keys():
#                if (not inputStageInterface.has_key(inputKey)):
#                    raise Exception("[%s:Prepare] Input (%s) interface does not include: %s:%s" % (self.__class__.__name__,stage.__class__.__name__,inputKey,myInputInterface[inputKey]))
#                if (inputStageInterface[inputKey] != myInputInterface[inputKey]):
#                    raise Exception("[%s:Prepare] Invalid input (%s) interface type: expected %s, received %s" % (self.__class__.__name__,inputStageInterface[inputKey].__class__.__name__,inputStageInterface[inputKey],myInputInterface[inputKey]))

        # ensure input interface is consistent with input stage's output interface

        myInputInterface = self.GetInputInterface()
        if (myInputInterface != None):
            for kv in myInputInterface.items():

                try:
                    inputName,(inputIndex,inputType) = kv
                except:
                    raise Exception("[%s:Prepare] Input interface definition error" % (self.__class__.__name__))

                if (isinstance(inputIndex,tuple)):
                    for iIndex in range(inputIndex[0], inputIndex[0]+inputIndex[1]):
                        if (iIndex < self.NumInputStages()):  # check only valid input stage indices
                            if (not self.__inputStages[iIndex].GetOutputInterface().has_key(inputName)):
                                raise Exception("[%s:Prepare] Input stage %d does not include %s:%s" % \
                                                (self.__class__.__name__,iIndex,inputName,inputType))

                            if (not issubclass(self.__inputStages[iIndex].GetOutputInterface()[inputName],inputType)):
                                raise Exception("[%s:Prepare] Input stage %d's output parameter (%s) type is %s, type should be %s" % \
                                                (self.__class__.__name__,
                                                 iIndex,
                                                 inputName,
                                                 self.__inputStages[iIndex].GetOutputInterface()[inputName],
                                                 inputType))
                else:
                    if (inputIndex >= self.NumInputStages()):
                        raise Exception("[%s:Prepare] Expected input stage at index %d" % \
                                        (self.__class__.__name__,inputIndex))

                    if (not self.__inputStages[inputIndex].GetOutputInterface().has_key(inputName)):
                        raise Exception("[%s:Prepare] Input stage %d does not include %s:%s" % \
                                        (self.__class__.__name__,inputIndex,inputName,inputType))

                    if (not issubclass(self.__inputStages[inputIndex].GetOutputInterface()[inputName], inputType) and
                        not issubclass(inputType, self.__inputStages[inputIndex].GetOutputInterface()[inputName])):
                        raise Exception("[%s:Prepare] Input stage %d's output parameter (%s) type is %s, type should be %s" % \
                                        (self.__class__.__name__,
                                         inputIndex,
                                         inputName,
                                         self.__inputStages[inputIndex].GetOutputInterface()[inputName],
                                         inputType))

        # successfully prepared stage
        self.__prepared = True

    def __InitializeOutputCache(self):
        self.__outputCache = {}
        if (self.GetOutputInterface()!=None):
            for k in self.GetOutputInterface().keys():
                self.__outputCache[k] = None

    def __ValidateCompleteOutputCache(self):
        for k,v in self.__outputCache.items():
            if (v==None):
                raise Exception("[%s::__ValidateCompleteOutputCache] Developer error, output parameter (%s) not filled" % \
                                (self.__class__.__name__,k))

            if (str(type(v)) == "<type 'instance'>" or
                str(type(v)).startswith("<class '")):
                if (issubclass(v.__class__, self.GetOutputInterface()[k])):
                    pass
                elif (str(self.GetOutputInterface()[k]) not in [v.__class__.__name__, "%s.%s" % (v.__module__, v.__class__.__name__)]):
                    raise Exception("[%s::__ValidateCompleteOutputCache] Developer error, output parameter (%s) type is %s, type should be %s" % \
                                    (self.__class__.__name__,k,v.__class__.__name__,self.GetOutputInterface()[k]))
            else:
                if (self.GetOutputInterface()[k] != type(v)):
                    raise Exception("[%s::__ValidateCompleteOutputCache] Developer error, output parameter (%s) type is %s, type should be %s" % \
                                    (self.__class__.__name__,k,type(v),self.GetOutputInterface()[k]))

    def GetOutput(self):
        # this method is called by the next stage
        # the outputs of this stage are cached within this class by ensuring Execute is only called when necessary
        self.Prepare()

        if (self.__outputCache==None):
            self.__InitializeOutputCache()
            self.Execute()
            self.__ValidateCompleteOutputCache()

        return self.__outputCache

    def GetOutputByKey(self, key):

        if (not self.__outputCache.has_key(key)):
            raise Exception("[%s:GetOutputByKey] Invalid output key: %s" % \
                            (self.__class__.__name__,key))

        return self.__outputCache[key]

    def GetInputStageValue(self, index, key):
        if (index >= self.NumInputStages()):
            raise Exception("[%s:GetInputStageValue] Invalid input stage index: %d" % \
                            (self.__class__.__name__,index))

        outputs = self.GetInputStages()[index].GetOutput()

        if (not outputs.has_key(key)):
            raise Exception("[%s:GetInputStageValue] Invalid input stage (%s) key: %s" % \
                            (self.__class__.__name__,self.GetInputStages()[index].__class__.__name__,key))

        return outputs[key]

    def SetOutputValue(self, key, value):
        if (not self.__outputCache.has_key(key)):
            raise Exception("[%s:SetOutputValue] Unknown output parameters: %s" % \
                            (self.__class__.__name__,key))

        # TODO: validate value's type
        self.__outputCache[key] = value

    def StartProcess(self):
        name = self.__class__.__name__
        if (len(self._properties)>0):
            sargs = ["%s = %s" %(str(x),self._properties[x]) for x in sorted(self._properties.keys())]
            name = "%s [%s]" % (name, string.join(sargs,", "))
        Analyze.StartProcess(name)

    def RunCommand(self, exe, args="", cwd=None, shell=True, captureCout=False):
        import Common

        # find executable for given platform
        exe = Common.Utility.GetExePath(sys.modules[self.__class__.__module__].__file__, exe)
        cmd = "\"%s\" %s" % (exe, args)
        return Common.Utility.RunCommand(cmd, cwd=cwd, shell=shell, captureCout=captureCout)

    # pure virtual methods...
    def GetInputInterface(self):
        # return dictionary of input types, keyed by name (name->type)
        raise Exception("Derived class (%s) must implement GetInputInterface" % self.__class__.__name__)

    def GetOutputInterface(self):
        # return dictionary of output types, keyed by name (name->type)
        raise Exception("Derived class (%s) must implement GetOutputInterface" % self.__class__.__name__)

    def Execute(self):
        # carry out execution
        # note, this is called by GetOutputs
        # return dictionary of results keyed by name (name->object)
        raise Exception("Derived class (%s) must implement Execute" % self.__class__.__name__)


from django.urls import path
from . import views

app_name = 'community'

urlpatterns = [
    path('', views.index, name='index'),
    path('notice/', views.notice, name='notice'),
    path('help/', views.help, name='help'),
    path('info/', views.info, name='info'),
    path('marvel/', views.marvel, name='marvel'),
    path('korean/', views.korean, name='korean'),
    path('nolan/', views.nolan, name='nolan'),
    path('tarantino/', views.tarantino, name='tarantino'),
    path('create/', views.create, name='create'),
    path('<int:article_pk>/', views.detail, name='detail'),
    path('<int:article_pk>/comments/', views.create_comment, name='create_comment'),
    path('<int:article_pk>/like/', views.like, name='like'),
]


import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import numpy as np

FILE_NAME = 'record.txt'
SMOOTH_EPISODE = 1000

if __name__ == '__main__':
    plt.clf()
    plt.xlabel('eposide')
    plt.ylabel('score')
    plt.xlim(-1000, 11000)
    plt.ylim(-100, 2000)
    plt.grid(True)
    with open(FILE_NAME, 'r') as f:
        content = f.readlines()

    x = []
    y = []
    means = []
    tmp_value = []
    mean_idx = 0
    idx = 0
    for c in content:
        if idx > 10000:
            break
        idx += 1
        c_list = c.split(' ')
        x.append(c_list[0])
        yvalue = int(c_list[1].split('\n')[0])
        y.append(yvalue)

        tmp_value.append(yvalue)
        mean_idx += 1

        if (mean_idx % SMOOTH_EPISODE == 0 and mean_idx != 0) or mean_idx == (len(content) - 1):
            means.append(np.mean(tmp_value))
            tmp_value = []

    mean_x_idx = [_ * SMOOTH_EPISODE for _ in range(1, len(means) + 1)]
    plt.plot(mean_x_idx, means, c='#F39019', linewidth='3')
    plt.scatter(x, y, c='#51A7F9', marker='o', s=15, alpha=0.9)
    plt.savefig(FILE_NAME.split('.')[0] + '.pdf', format='pdf', bbox_inches='tight')

    plt.show()
    plt.close()


#usr/bin/env/python
'''
Author  : Bhekimpilo Ndhlela
Author  : 18998712
module  : TW244 Applied Mathematics
task    : Assignment 01 problem2
since   : Saturday-28-07-2018
'''

from numpy import (linspace, array, zeros)
import matplotlib.pyplot as plt
from sys import exit

def plot_functions():

    X = linspace(0, 2.5, 100)
    y = array([ p**3 - 4*(p**2) +4*p for p in X])
    plt.subplot(211)
    plt.title('Plot of function f\'(x)')
    plt.xlabel('x = linspace(0, 2.5, 1000)')
    plt.ylabel('f(x)')
    plt.plot(X, y, '-r', linewidth=4)

    plt.subplot(212)
    X = linspace(0, 2.5, 100)
    y = array([ p*(p-2)**3 * (3*p - 2) for p in X])
    plt.title('Plot of function f\'\'(x)')
    plt.xlabel('x = linspace(0, 2.5, 1000)')
    plt.ylabel('f(x)')
    plt.plot(X, zeros(len(X)), '-k', linewidth=2)
    plt.plot(X, y, '-r', linewidth=4)
    plt.show()

plot_functions()


import discord
from discord.ext import commands
from discord.utils import get
import argparse
from collections import deque

from concurrent.futures import ThreadPoolExecutor
import asyncio

import os
from dotenv import load_dotenv
import sys

# Import custom functions from the oogabooga library
from oogabooga import init_llm, generate_llm
from speech2text import init_whisper, generate_whisper
from text2speech import init_bark, generate_bark, init_tortoise, generate_tortoise, audio_combine, init_emotion, get_emotion
from udp_server import init_udp_server, udp_server

import tempfile
from tortoise.utils.text import split_and_recombine_text

parser = argparse.ArgumentParser()
parser.add_argument("--reboot", action="store", help="Helper for rebooting the bot (message_id) (don't use this except you are a bot)")
parser.add_argument("--channel", action="store", help="Helper for rebooting the bot (channel_id)(don't use this except you are a bot)")

# Load environment variables from a .env file
load_dotenv()
model_url = os.environ.get("MODEL_URL")
llm_debug = eval(os.environ.get("LLM_DEBUG", "False"))

use_whisper = os.environ.get("USE_WHISPER", "1")
whisper_model = os.environ.get("WHISPER_MODEL", "base")

use_bark = os.environ.get("USE_BARK", "0")
bark_use_small_model = os.environ.get("BARK_USE_SMALL_MODEL", "1")
bark_speaker = os.environ.get("BARK_SPEAKER", "v2/en_speaker_7")

use_tortoise = os.environ.get("USE_TORTOISE", "1")
tortoise_voice = os.environ.get("TORTOISE_VOICE", "angie")
tortoise_diffusion_iterations = int(os.environ.get("TORTOISE_DIFFUSION_ITERATIONS", "50"))
tortoise_num_autoregressive_samples = int(os.environ.get("TORTOISE_NUM_AUTOREGRESSIVE_SAMPLES", "2"))
tortoise_temperature = float(os.environ.get("TORTOISE_TEMPERATURE", "0.2"))
tortoise_use_deepspeed = eval(os.environ.get("TORTOISE_USE_DEEPSPEED", "False"))
tortoise_kv_cache = eval(os.environ.get("TORTOISE_KV_CACHE", "True"))
tortoise_half = eval(os.environ.get("TORTOISE_HALF", "True"))

use_emotion = os.environ.get("USE_EMOTION", "1")

use_unity = os.environ.get("USE_UNITY", "0")

discord_token = os.environ.get("DISCORD_TOKEN")

with open("discord_info.txt", "r") as file:
    discord_info = file.read()

# Set up Discord intents
intents = discord.Intents.default()
intents.message_content = True
intents.voice_states = True
intents.members = True

# Initialize the modeles
llm_chain = init_llm(model_url, llm_debug)

if use_tortoise == "1" and use_bark == "1":
    print("Tortoise and Bark cannot be used at the same time")
    sys.exit()

if use_whisper == "1":
    whisper_model = init_whisper(whisper_model)

if use_bark == "1":
    init_bark(bark_use_small_model)

if use_tortoise == "1":
    tortoise_tts = init_tortoise(tortoise_use_deepspeed, tortoise_kv_cache, tortoise_half, tortoise_num_autoregressive_samples)

if use_emotion == "1":
    if use_tortoise == "1" or use_bark == "1":
        text2emotion = init_emotion()
    else:
        print("Tortoise or Bark must be enabled because emotion detection is used for them exclusively exept in generate_emotion_test")
        sys.exit()

if use_unity == "1":
    init_udp_server()

bot = discord.Bot(intents=intents)
connectet_voice_channel = None

@bot.event
async def on_ready():
    # This method is called when the bot successfully logs in to Discord
    print("Login successful")
    if parser.parse_args().reboot and parser.parse_args().channel:
        channel_id = int(parser.parse_args().channel)
        message_id = int(parser.parse_args().reboot)

        response_msg = await bot.get_channel(channel_id).fetch_message(message_id)
        await response_msg.edit(content="Reboot successful")

@bot.command(description="Join a voice channel")
async def join(ctx, channel: discord.VoiceChannel = None):
    global connectet_voice_channel
    if channel is None:
        if ctx.author.voice is None:
            await ctx.respond("Not connected to a voice channel, pls specify a channel or join one")
            return
        channel = ctx.author.voice.channel
    connectet_voice_channel = await channel.connect()
    await ctx.respond("Connected to voice channel")

@bot.command(description="Leave a voice channel")
async def leave(ctx):
    if ctx.voice_client is None:
        await ctx.respond("Not connected to a voice channel")
        return
    global connectet_voice_channel
    connectet_voice_channel = None
    await ctx.voice_client.disconnect()
    await ctx.respond("Disconnected from voice channel")

@bot.event
async def on_message(message):
    # This method is called whenever a message is sent in any channel (also direct messages) the bot can access

    # Ignore messages sent by the bot itself to avoid potential infinite loops
    if message.author == bot.user:
        return

    if (message.content == None or message.content == "") and message.attachments == None:
        return

    print("Nachricht von " + str(message.author) + " enthält " + message.content)

    # Acknowledge receipt of the command by replying to the original message
    response_msg = await message.reply("Processing your request...")

    # If the message contains an audio file, transcribe it and use the transcription as input
    if message.attachments:
        if 'audio' in message.attachments[0].content_type:
            if use_whisper == "1":
                message.content = generate_whisper(whisper_model, message.attachments[0].url)
            else:
                await response_msg.edit(content="Whisper is disabled")
                return

    # Start the time-consuming task asynchronously
    result = await generate_llm_thread(llm_chain, message.content)

    # Edit the "Processing your request..." message with the final response
    await response_msg.edit(content=result)

    if use_tortoise == "1" or use_bark == "1":
        audio_file = await generate_tts(result)
        await response_msg.edit(file=discord.File(audio_file))

@bot.command(description="Show all commands and other information")
async def info(ctx):
    await ctx.respond(discord_info)

@bot.command(description="Show help")
async def help(ctx):
    await ctx.send("Commands: /join, /leave, /info, /delete_short_mem, /reboot, /help, /generate_bark_test, /generate_tortoise_test, /generate_whisper_test")

#Function that deltets the files located in the shortmem directory
@bot.command(description="Delete shortmem located files")
@commands.has_permissions(manage_channels=True)
async def delete_short_mem(ctx):
    if os.path.exists("shortmem"):
        for item in os.listdir("shortmem"):
            if os.path.isfile(os.path.join("shortmem", item)):
                os.remove(os.path.join("shortmem", item))
        await ctx.respond("shortterm memory deleted, restarting bot")
        response = await ctx.send("pls wait")
        os.execl(sys.executable, sys.executable, *sys.argv, '--reboot', str(response.id), '--channel', str(ctx.channel.id))
    else:
        await ctx.respond("shortterm memory is not existed")

@bot.command(description="Reboot the bot")
@commands.has_permissions(manage_channels=True)
async def reboot(ctx):
    if ctx.voice_client != None:
        await ctx.voice_client.disconnect()

    await ctx.respond("rebooting bot")
    response = await ctx.send("pls wait")
    os.execl(sys.executable, sys.executable, *sys.argv, '--reboot', str(response.id), '--channel', str(ctx.channel.id))

@bot.command(description="Generate audio from text")
async def generate_bark_test(ctx, text: str=None):
    if use_bark == "1":
        response = await ctx.respond(f"Generating audio from text")
        if text is None:
            text = "Hello this is a bark generation test."
        file = await generate_tts(text)
        await response.edit_original_response(file=discord.File(file))
    else:
        await ctx.respond("Bark generation is disabled")

@bot.command(description="Generate text from audio")
async def generate_whisper_test(ctx, file: discord.Attachment):
    if use_whisper == "1":
        if 'audio' in file.content_type:
            response = await ctx.respond(f"Generating text from audio")
            await response.followup.send(generate_whisper(whisper_model, file.url))
        else:
            await ctx.respond("Please send an audio file")
    else:
        await ctx.respond("Whisper is disabled")

@bot.command(description="Generate audio from text")
async def generate_tortoise_test(ctx, text: str=None):
    if use_tortoise == "1":
        response = await ctx.respond(f"Generating audio from text")
        if text is None:
            text = "Hello this is a tortoise generation test."
        file = await generate_tts(text)
        await response.edit_original_response(file=discord.File(file))
    else:
        await ctx.respond("Tortoise is disabled")

@bot.command(description="Generate emotion from text")
async def generate_emotion_test(ctx, text: str=None):
    if use_emotion == "1":
        response = await ctx.respond(f"Generating emotion from text")
        if text is None:
            text = "Hello this is a emotion generation test."
        emotion = get_emotion(text, text2emotion)
        await response.followup.send(str(emotion))
    else:
        await ctx.respond("Emotion is disabled")

semaphore_llm = asyncio.Semaphore(1)

async def generate_llm_thread(llm_chain, content):
    global semaphore_llm

    # Use a semaphore to ensure that only one thread is running this function at a time and to maintain the order of requests
    async with semaphore_llm:
        # Use ThreadPoolExecutor to run the synchronous function in a separate thread
        # This prevents the event loop from being blocked during the time-consuming task
        with ThreadPoolExecutor() as executor:
            result = await bot.loop.run_in_executor(executor, generate_llm, llm_chain, content)

    return result

semaphore_tts = asyncio.Semaphore(1)

async def generate_tts(text):
    global semaphore_tts

    # Use a semaphore to ensure that only one thread is running this function at a time and to maintain the order of requests
    async with semaphore_tts:

        emotion = None

        if use_emotion == "1":
            emotion = get_emotion(text, text2emotion)
            emotion_tts = f"[{emotion}] "
            len_emotion = len(emotion_tts)

        # Use ThreadPoolExecutor to run the synchronous function in a separate thread
        # This prevents the event loop from being blocked during the time-consuming task
        with ThreadPoolExecutor() as executor:
            if use_tortoise == "1":
                max_length = 300
                desired_length = 200
                if use_emotion == "1":
                    desired_length = desired_length - len_emotion
                    max_length = max_length - len_emotion
                texts = split_and_recombine_text(text, desired_length=desired_length, max_length=max_length)
                audio_parts = []
                for text in texts:
                    if use_emotion == "1":
                        text = emotion_tts + text
                    result = await bot.loop.run_in_executor(executor, generate_tortoise, text, tortoise_tts, tortoise_diffusion_iterations, tortoise_num_autoregressive_samples, tortoise_temperature, tortoise_voice)
                    await play_audio(result, emotion)
                    audio_parts.append(result)

                result = audio_combine(audio_parts)

            if use_bark == "1":
                if use_emotion == "1":
                    text = emotion_tts + text
                result = await bot.loop.run_in_executor(executor, generate_bark, text, bark_speaker)
                await play_audio(result, emotion)

    return result

audio_queue = deque()

async def play_audio(audio_file, emotion=None):
    global connectet_voice_channel
    global audio_queue

    if connectet_voice_channel is not None:

        if audio_file:  # Check if both audio_file and emotion are provided
            # Add the audio file to the queue
            audio_queue.append((audio_file, emotion))

        if not connectet_voice_channel.is_playing() and audio_queue:
            # If the voice channel is not currently playing audio and the queue is not empty, start playback
            audio_file, emotion = audio_queue.popleft()
            if use_unity == "1" and emotion:
                udp_server(emotion)
            connectet_voice_channel.play(discord.FFmpegPCMAudio(audio_file), after=on_audio_complete)

def on_audio_complete(_):
    # This function is called when audio playback is complete
    asyncio.run(play_audio("", ""))  # Continue playing the next audio, pass appropriate audio file and emotion

bot.run(discord_token)


import subprocess
import time
import pymongo

SMALL_SAMPLE_PATH = "./tests/utils/small_sample.mind.gz"

def run_subprocess(command):
    command = [x for x in command.split(" ")]
    process = subprocess.Popen(command,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE,
                               close_fds=True)
    return process

def test_end_to_end():
    # Clearing the db:
    client = pymongo.MongoClient('mongodb://localhost:27017')
    client.drop_database('db')

    # Starting to run services:
    saver_process = run_subprocess("python -m brain_freeze.saver run-saver "
                                   "mongodb://127.0.0.1:27017 "
                                   "rabbitmq://127.0.0.1:5672/")
    time.sleep(1)
    pose_process = run_subprocess("python -m brain_freeze.parsers run-parser "
                                  "pose rabbitmq://127.0.0.1:5672/")
    time.sleep(1)
    feelings_process = run_subprocess("python -m brain_freeze.parsers "
                                      "run-parser feelings "
                                      "rabbitmq://127.0.0.1:5672/")
    time.sleep(1)
    color_process = run_subprocess("python -m brain_freeze.parsers run-parser "
                                   "color_image rabbitmq://127.0.0.1:5672/")
    time.sleep(1)
    server_process = run_subprocess("python -m brain_freeze.server run-server"
                                    " rabbitmq://127.0.0.1:5672/")
    time.sleep(5)
    # Running the client:
    client_process = run_subprocess("python -m brain_freeze.client "
                                    "upload_sample " + SMALL_SAMPLE_PATH)
    time.sleep(350)

    # Running the api and cli:
    api_process = run_subprocess("python -m brain_freeze.api run-server")
    time.sleep(5)
    cli_users_process = run_subprocess("python -m brain_freeze.cli get-users")
    time.sleep(5)
    cli_user_process = run_subprocess("python -m brain_freeze.cli get-user 42")
    time.sleep(5)
    cli_snapshots_process = run_subprocess("python -m brain_freeze.cli "
                                           "get-snapshots 42")
    time.sleep(5)
    cli_snapshot_process = run_subprocess("python -m brain_freeze.cli "
                                          "get-snapshot 42 1575446887339")
    time.sleep(5)
    cli_pose_result_process = run_subprocess("python -m brain_freeze.cli "
                                             "get-result 42 1575446887339 "
                                             "pose")
    time.sleep(5)
    cli_feelings_result_process = run_subprocess("python -m brain_freeze.cli "
                                                 "get-result 42 1575446887339 "
                                                 "feelings")
    time.sleep(5)
    cli_color_result_process = run_subprocess("python -m brain_freeze.cli "
                                              "get-result 42 1575446887339 "
                                              "color_image")
    time.sleep(5)

    # Checking the results:
    client_process.terminate()
    saver_process.terminate()
    pose_process.terminate()
    feelings_process.terminate()
    color_process.terminate()
    server_process.terminate()
    api_process.terminate()
    out, err = client_process.communicate()
    print("client out: " + out.decode())
    print("client err: " + err.decode())
    assert client_process.returncode == 0

    out, err = server_process.communicate()
    print("server out: " + out.decode())
    print("server err: " + err.decode())

    out, err = color_process.communicate()
    print("color out: " + out.decode())
    print("color err: " + err.decode())

    out, err = pose_process.communicate()
    print("pose out: " + out.decode())
    print("pose err: " + err.decode())

    out, err = feelings_process.communicate()
    print("feelings out: " + out.decode())
    print("feelings err: " + err.decode())

    out, err = saver_process.communicate()
    print("saver out: " + out.decode())
    print("saver err: " + err.decode())

    out, err = api_process.communicate()
    print("api out: " + out.decode())
    print("api err: " + err.decode())

    out, err = cli_users_process.communicate()
    print("cli_users out: " + out.decode())
    print("cli_users err: " + err.decode())
    assert b'Dan Gittik' in out

    out, err = cli_user_process.communicate()
    print("cli_user out: " + out.decode())
    print("cli_user err: " + err.decode())
    assert b'Dan Gittik' in out

    out, err = cli_snapshots_process.communicate()
    print("cli_snapshots_process out: " + out.decode())
    print("cli_snapshots_process err: " + err.decode())
    assert b'1575446887339' in out

    out, err = cli_snapshot_process.communicate()
    print("cli_snapshot_process out: " + out.decode())
    print("cli_snapshot_process err: " + err.decode())
    assert b'pose' in out
    assert b'feelings' in out

    out, err = cli_pose_result_process.communicate()
    print("cli_pose_result_process out: " + out.decode())
    print("cli_pose_result_process err: " + err.decode())
    assert b'0.4873843491077423' in out

    out, err = cli_feelings_result_process.communicate()
    print("cli_feelings_result_process out: " + out.decode())
    print("cli_feelings_result_process err: " + err.decode())
    assert b'0.0' in out

    out, err = cli_color_result_process.communicate()
    print("cli_color_result_process out: " + out.decode())
    print("cli_color_result_process err: " + err.decode())
    assert b'color_image.jpg' in out


from collections import Counter
from urlextract import URLExtract
from wordcloud import WordCloud
import emoji
import pandas as pd
import emoji_data_python as emoji_data
import re

extract=URLExtract()
def fetch_stats(selected_user,df):
    if selected_user!="Overall":
        df=df[df['user']==selected_user]
    num_messages=df.shape[0]

    words=[]
    for m in df['message']:
        words.extend(m.split())
    media=df[df['message']=='<Media omitted>\n'].shape[0]

    link=[]
    for message in df['message']:
        link.extend(extract.find_urls(message))

    return num_messages,len(words),media,len(link)

def most_active_user(df):
    x=df['user'].value_counts().head()
    df=round((df['user'].value_counts()/df.shape[0])*100,2).reset_index().rename(columns={'index':'name','user':'percent'})
    return x,df

def create_wordcloud(selected_user,df):
    if selected_user!="Overall":
        df=df[df['user']==selected_user]
    wc=WordCloud(width=500,height=300,min_font_size=10,background_color='white')
    df_wc=wc.generate(df['message'].str.cat(sep=" "))
    return df_wc

def emoji(selected_user,df):
    if selected_user!="Overall":
        df=df[df['user']==selected_user]

    emojis = []
    emoji_pattern = r'[\U0001F300-\U0001F64F\U0001F680-\U0001F6FF\u2600-\u26FF\u2700-\u27BF]'
    for message in df['message']:
    # Extract emojis from the message using the regular expression pattern
        extracted_emojis = re.findall(emoji_pattern, message)
        emojis.extend(extracted_emojis)
    emoji_df = pd.DataFrame(Counter(emojis).most_common(), columns=['Emoji', 'Count'])
    return emoji_df

def montly_timeline(selected_user,df):
    if selected_user!="Overall":
        df=df[df['user']==selected_user]
    timeline=df.groupby(['year','month_num','month']).count()['message'].reset_index()
    time=[]
    for i in range(timeline.shape[0]):
        time.append(timeline['month'][i]+"-"+str(timeline['year'][i]))
    timeline['time']=time
    return timeline

def daily_timeline(selected_user,df):
    if selected_user!="Overall":
        df=df[df['user']==selected_user]
    daily_timeline=df.groupby('only_date').count()['message'].reset_index()
    return daily_timeline

def week_activity_map(selected_user,df):
    if selected_user!="Overall":
        df=df[df['user']==selected_user]
    return df['day_name'].value_counts()

def month_activity_map(selected_user,df):
    if selected_user!="Overall":
        df=df[df['user']==selected_user]
    return df['month'].value_counts()


#!/usr/bin/env python
# Script: Script reads BPM parameters from FG screen
# Author: M.Fedurin, T.Morris 06/24/2022

# Version: 0.0
# Last Update: 2022/07/11 (M.Fedurin, Lines:198,207,209,252 "tol" changed to 1e+1)

# Notes:

import time
#import atf_db  #for ATF database operations
import atf_db_py3x as atf_db
import datetime
import pandas as pd
import numpy as np

#import pyvisa
#import numpy as np

host_name = '172.16.82.101'
port_name = 1505

atf_db.host_connect(host_name,port_name)  # Generate socket

print("version of Mon 27 Jun 2022 03:47:41 PM EDT ")

def ReadLaserEnergy():

    LaserEnergy = atf_db.get_real(atf_db.get_channel_index("RT_DATABASE::JOULE;RLE;LASER_ENERGY"))
    return LaserEnergy

def WriteLaserEnergy(a):
    stra = str(a)
    atf_db.put_real(atf_db.get_channel_index("NEWPORT_DB::YAG_INTENSITY;DESIRED_MOVEMENT_NATIVE_UNITS"), a)
#    atf_db.put_real(AtfDB.getchix("NEWPORT_DB::YAG_INTENSITY;DESIRED_MOVEMENT_NATIVE_UNITS"), '+5')
#do i need time in between here?
    atf_db.put_binary(atf_db.get_channel_index("NEWPORT_DB::YAG_INTENSITY;START_STOP_MOTION_CTRL"),"START")
    time.sleep(3)

LaserEnergyRead = ReadLaserEnergy()

print(" ")
print("Laser Energy = ", LaserEnergyRead)
print(" ")

fgN=3

def CameraSwitchFG3(POPN):
	atf_db.put_integer(atf_db.get_channel_index("RT_DATABASE::VID_SWITCH;CMM;VID_MON_03_MUX"),POPN)
	time.sleep(1)

def MovePOPIN(POPN,Direction):
	atf_db.put_binary(atf_db.get_channel_index("RT_DATABASE::POPCTL" + POPN + ";CPU;CTL_REQ_POP_UP_CKT_"+ POPN),Direction)

def GetPOPIN(POPN):
	return atf_db.get_binary(atf_db.get_channel_index("RT_DATABASE::POPCTL" + POPN + ";RPU;RDBK_REQ_POP_UP_CKT_"+ POPN))

# POPINLIST = [POPIN_NAME, POIPIN_#, POPIN_CAM_#],[]]
POPINLIST = [['LTR','21','6'],['LPOP1','11','2'],['HPOP1','18','4'],['HPOP2','14','75'],['CHIC_UP','36','54'],['CHIC_DOWN','36','55'],['HPOP3','13','24'],['HPOP4','12','5'],['HPOP5','38','76'],['HPOP6','39','77']]

pop_in_dict = {}

for name, n_pop, n_cam in POPINLIST:

	pop_in_dict[name] = {}
	pop_in_dict[name]['n_pop'] = n_pop
	pop_in_dict[name]['n_cam'] = n_cam

def pop_and_switch(name):

	MovePOPIN(pop_in_dict[name]['n_pop'], 'INSERT')
	CameraSwitchFG3(pop_in_dict[name]['n_cam'])

	for _name, d in pop_in_dict.items():

		if _name == name: continue

		if GetPOPIN(d['n_pop']) == "'INSERT'":

			print(f'retracting {_name}...')
			MovePOPIN(d['n_pop'], 'RETRACT')

	print(f'inserting {name}...')
	time.sleep(1)

def ReadFG(fgN):
   fgname = "FRAME" + str(fgN) + "_DB::FGR" + str(fgN) + ";"
   xpos = atf_db.get_real(atf_db.get_channel_index(fgname+"RCX;CENTROID_X"))
   ypos = atf_db.get_real(atf_db.get_channel_index(fgname+"RCY;CENTROID_Y"))
   xsig = atf_db.get_real(atf_db.get_channel_index(fgname+"RSX;SIGMA_X"))
   ysig = atf_db.get_real(atf_db.get_channel_index(fgname+"RSY;SIGMA_Y"))
#   pixsum = atf_db.get_real(atf_db.get_channel_index(fgname +"RM00;SUM_PIXELS"))
   return [xpos,ypos,xsig,ysig]

def StopFGSavePicRunFG(fgN,FullPathFileName):
   fgname = "FRAME" + str(fgN) + "_DB::FGR" + str(fgN) + ";"
   ReadButtonStatus = atf_db.get_binary(atf_db.get_channel_index(fgname+"RRS;RUN_STOP_READBACK"))
   print('FG'+str(fgN)+' is at: '+str(ReadButtonStatus))
   time.sleep(1)
   PushButton = atf_db.put_binary(atf_db.get_channel_index(fgname+"CRS;RUN_STOP_CONTROL"),"STOP")
   time.sleep(1)
   ReadButtonStatus = atf_db.get_binary(atf_db.get_channel_index(fgname+"RRS;RUN_STOP_READBACK"))
   print('FG'+str(fgN)+' is now : '+str(ReadButtonStatus))
   FileNameLog = atf_db.put_string(atf_db.get_channel_index(fgname+"CIFN;IMAGE_FILE_NAME"),FullPathFileName)
   time.sleep(1)
   PushButtonSave = atf_db.put_binary(atf_db.get_channel_index(fgname+"CSIF;SAVE_IMAGE_FILE_CTRL"),'SAVING')
   time.sleep(3)
   PushButton = atf_db.put_binary(atf_db.get_channel_index(fgname+"CRS;RUN_STOP_CONTROL"),"RUN")
   time.sleep(1)

# *~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~* VaryCurrent PART START *~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*

def PSCurrentReadSet(ChannelName,db=''):

	return atf_db.get_real(atf_db.get_channel_index(f'{db}::' + str(ChannelName) + ";CDS;SET_CURRENT_SETPT"))

def PSCurrentSet(ChannelName,CurrentSet,db=''):

	atf_db.put_real(atf_db.get_channel_index(f'{db}::' + str(ChannelName) + ";CDS;SET_CURRENT_SETPT"),CurrentSet)

def PSCurrentRead(ChannelName,db='abc'):

    return atf_db.get_real(atf_db.get_channel_index(f"{db}::" + str(ChannelName) + ";RAS;RB_CURRENT_SETPT"))

# *~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~* VaryCurrent PART START *~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*

channel_names_full_Hline = { 'HPOP1' : { "LT1HX" : "CAEN3",
	         	     "LT1VX" : "CAEN2",
	         	     "LT2HX" : "CAEN1",
	         		"LT2VX" : "CAEN4",
		 		 "TK1H" : "CAEN13",
	          	   	 "TK1V" : "CAEN14",
	         		 "TK2H" : "CAEN15",
	          		 "TK2V" : "CAEN16",
 		  		 "TK3H" : "CAEN17",
	          		 "TK3V" : "CAEN18"},

		 'HPOP2' : { "HT1HX" : "DARL1",
	        	     "HT1VX" : "DARL2",
	       			 "HT2HX" : "DARL3",
	       			 "HT2VX" : "DARL4",
				  "HQ1" : "DARL149",
		                  "HQ2" : "DARL150",
				  "HQ3" : "DARL151"},

		 'HPOP3' : {},

		 'HPOP4' : { "HT3HX" : "DARL9",
	        		 "HT3VX" : "DARL10",
	         		"HT4HX" : "DARL27",
	         		"HT4VX" : "DARL28",
		  		 "HQ4" : "DARL152",
		  		 "HQ5" : "DARL153",
		  		 "HQ6" : "DARL154"},
		  'HPOP5' : {},
		  'HPOP6' : {  "HT3HX" : "DARL29",
	        		 "HT3VX" : "DARL30",
	         		"HT4HX" : "DARL31",
	         		"HT4VX" : "DARL32",
		  		 "HQ4" : "DARL155",
		  		 "HQ5" : "DARL156",
		  		 "HQ6" : "DARL157"}

	        }

channel_names = { 'HPOP2' : { "HT1HX" : "DARL1",
	        	      "HT1VX" : "DARL2",
	       			 "HT2HX" : "DARL3",
	       			 "HT2VX" : "DARL4",
				  "HQ1" : "DARL149",
		                  "HQ2" : "DARL150",
				  "HQ3" : "DARL151"},

		 'HPOP3' : {},

		 'HPOP4' : { "HT3HX" : "DARL9",
	        		 "HT3VX" : "DARL10",
	         		"HT4HX" : "DARL27",
	         		"HT4VX" : "DARL28",
		  		 "HQ4" : "DARL152",
		  		 "HQ5" : "DARL153",
		  		 "HQ6" : "DARL154"},
		  'HPOP5' : {},
		  'HPOP6' : {  "HT3HX" : "DARL29",
	        		 "HT3VX" : "DARL30",
	         		"HT4HX" : "DARL31",
	         		"HT4VX" : "DARL32",
		  		 "HQ4" : "DARL155",
		  		 "HQ5" : "DARL156",
		  		 "HQ6" : "DARL157"}

	        }

POP_list = ['HPOP1', 'HPOP2', 'HPOP3', 'HPOP4', 'HPOP5', 'HPOP6']

channel_dict = {}

dp_max  = 0.2
dp_step = 0.05

for pop, channels in channel_names.items():

	n_pop = int(pop[-1])

	for tag, name in channels.items():

		channel_dict[tag] = {}
		channel_dict[tag]['name']  = name
		channel_dict[tag]['n_pop'] = n_pop
		channel_dict[tag]['tol']   = 1e+1

		if name[:4] == 'CAEN':
			channel_dict[tag]['db'] = 'CAEN_DB'

		else:
			channel_dict[tag]['db'] = 'RT_DATABASE'

		if name[:4] == 'PTEN':
			channel_dict[tag]['tol'] = 1e+1
		if name[:4] == 'DARL':
			channel_dict[tag]['tol'] = 1e+1

		channel_dict[tag]['orig'] = PSCurrentReadSet(name, channel_dict[tag]['db']) #changed "PSCurrentRead" to "PSCurrentReadSet" ; M.Fedurin

		channel_dict[tag]['p_list'] = channel_dict[tag]['orig'] + np.arange(-dp_max, dp_max + 1e-6, dp_step)

		#print(channel_dict[tag])
		print(tag, name)

FileName = "C:/Images/AE124/20220711/2022071542_HPOP1_"

fgN=3
#

print(channel_dict)

timestamp = int(time.time())

ps_columns = list(channel_dict.keys())

Files = 'SavedFileName'

POP_cols = ['xpos', 'ypos', 'xsig', 'ysig', 'file']

metadata = pd.DataFrame(columns=['timestamp', *ps_columns, *[f'{POP}_{col}' for POP in POP_list for col in POP_cols]])

print(metadata.columns)

ps_tol = 1e-1

min_wait_time = 1e-1
max_wait_time = 2e0

def put_complete(ps, set_point, verbose=True):

	name, db = ps['name'], ps['db']

	abs_tol = np.abs(ps['tol'] * (PSCurrentReadSet(name, db) - set_point)) #changed "PSCurrentRead" to "PSCurrentReadSet" ; M.Fedurin

	PSCurrentSet(name, set_point, db)
	t0 = time.time()
	while True:
		elapsed = time.time() - t0
		if elapsed > max_wait_time: break
		if elapsed > min_wait_time:
			if np.abs(PSCurrentReadSet(name, db) - set_point) < abs_tol: #changed "PSCurrentRead" to "PSCurrentReadSet" ; M.Fedurin
				break
			#print(PSCurrentReadSet(name, db), set_point, db)
		time.sleep(1e-1)
	t1 = time.time()
	if verbose: print(f'set {name} to {set_point:.03e} +/- {abs_tol:.01e} ({PSCurrentRead(name, db):.03e}) in {1e3*(t1-t0):.00f}ms')

from datetime import datetime

now = datetime.now()

print(metadata.columns)

dirname = f"C:/Images/AE124/{now.year}{now.month:>02}{now.day:>02}/"

POP_metadata = {}

for POP in POP_list:

	n_pop = int(POP[-1])

	pop_and_switch(POP)

	#POP_metadata[POP] = metadata.copy()

	#scan_id = 0

	for tag, ps in channel_dict.items():

		if not ps['n_pop'] == n_pop: continue

		for p in ps['p_list']:

			scan_id = len(metadata)

			put_complete(ps, p)

			filetimestamp = int(time.time())

			filename = f'{filetimestamp}_{POP}.asc'

			StopFGSavePicRunFG(3, dirname + filename)

			if len(metadata) <= scan_id: metadata.loc[scan_id] = np.nan
			metadata.loc[scan_id, ['timestamp', *ps_columns]] = time.time(),*[PSCurrentReadSet(ps['name'], ps['db']) for ps in channel_dict.values()] #changed "PSCurrentRead" to "PSCurrentReadSet" ; M.Fedurin
			metadata.loc[scan_id, [f'{POP}_{col}' for col in POP_cols]] = *ReadFG(fgN), filename
			put_complete(ps, ps['orig'])
			#scan_id += 1

metadata.to_csv(f'{timestamp}.csv')

for tag, ps in channel_dict.items():

	orig = ps['orig']
	print(f'returned {tag}:{name} to {orig}')
	put_complete(ps, orig, verbose=False)

atf_db.host_disconnect()  # Close socket

print(metadata)


from fmpy import supported_platforms

from fmpy.util import remove_source_code, download_test_file, download_file

def test_remove_source_code():

    filename = download_file('https://github.com/modelica/fmi-cross-check/raw/master/fmus/2.0/cs/win64/Dymola/2019FD01/BooleanNetwork1/BooleanNetwork1.fmu')

    assert 'c-code' in supported_platforms(filename)

    remove_source_code(filename)

    assert 'c-code' not in supported_platforms(filename)


import csv

from scipy.stats import pearsonr
from numpy import var

def get_row_from_input(file_path):
    with open(file_path, "r") as f:
        reader = csv.reader(f)
        headers = next(reader)
        return headers, list(reader)

class GenesFilter(object):
    def __init__(self, genes_input_path):
        self.genes_input_path = genes_input_path
        self.filters = [(self.should_filter_avg_cs_score, self.get_avg_cs_score_threshold),
                        (self.should_filter_second_lowest_cs_score, None),
                        (self.should_filter_pearson, None),
                        (self.should_filter_variance, self.get_variance_threshold)]

    @staticmethod
    def get_parsed_cs_scores(row):
        return list(map(float, row[1:]))

    def get_variance_threshold(self, rows):
        list_of_variances = self.get_list_of_variances(rows)
        return [self.get_top_2000_variance_threshold(list_of_variances)]

    @staticmethod
    def get_list_of_variances(rows):
        list_of_variances = list()
        for row in rows:
            cs_scores = GenesFilter.get_parsed_cs_scores(row)
            list_of_variances.append(var(cs_scores))
        return list_of_variances

    @staticmethod
    def get_top_2000_variance_threshold(list_of_variances):
        list_of_variances = sorted(list_of_variances)
        return list_of_variances[-2000]

    def get_avg_cs_score_threshold(self, rows):
        avg_cs_list = self.get_list_of_avg_cs_scores(rows)
        return [self.get_15_percent_cs_score_threshold(avg_cs_list)]

    @staticmethod
    def get_list_of_avg_cs_scores(rows):
        avg_cs_list = list()
        for row in rows:
            cs_scores = GenesFilter.get_parsed_cs_scores(row)
            avg_cs_list.append(sum(cs_scores) / len(cs_scores))
        return avg_cs_list

    @staticmethod
    def get_15_percent_cs_score_threshold(avg_cs_list):
        avg_cs_list = sorted(avg_cs_list)
        return avg_cs_list[int((15/100.0) * len(avg_cs_list))]

    def filter_genes(self, output_file_path):
        headers, rows = get_row_from_input(self.genes_input_path)
        for filter_method, pre_process_method in self.filters:
            data = []
            if pre_process_method:
                data = pre_process_method(rows)
            filtered_rows = list()
            for row in rows:
                if filter_method(row, *data):
                    continue
                filtered_rows.append(row)
            rows = filtered_rows
        with open(output_file_path, "w") as output_file:
            writer = csv.writer(output_file)
            writer.writerow(headers)
            writer.writerows(rows)

    def should_filter_avg_cs_score(self, row, avg_cs_score_threshold):
        cs_scores = self.get_parsed_cs_scores(row)
        if sum(cs_scores) / len(cs_scores) < avg_cs_score_threshold:
            return True

    @staticmethod
    def should_filter_second_lowest_cs_score(row):
        cs_scores = GenesFilter.get_parsed_cs_scores(row)
        cs_scores = sorted(cs_scores)
        if cs_scores[1] < -1:
            return True

    @staticmethod
    def should_filter_pearson(row):
        cs_scores = GenesFilter.get_parsed_cs_scores(row)
        for i in range(len(cs_scores)):
            identity_vector = [0] * len(cs_scores)
            identity_vector[i] = 1
            if abs(pearsonr(cs_scores, identity_vector)[0]) > 0.8:
                return True

    @staticmethod
    def should_filter_variance(row, variance_threshold):
        cs_scores = GenesFilter.get_parsed_cs_scores(row)
        if var(cs_scores) < variance_threshold:
            return True

def main(genes_input_file_path):
    genes_filter = GenesFilter(genes_input_file_path)
    genes_filter.filter_genes("../model/2000_genes_input.csv")

if __name__ == '__main__':
    main("../model/genes_input.csv")


"""
Killing KILL_REQUIREMENT other players in under TIME_REQUIREMENT seconds
sends you into a rampage lasting RAMPAGE_DURATION seconds.
The rampage refills and drastically increases your weapons' rate of fire.

By default this means 3 kills in under 8 seconds to activate. For reference,
lines disappear from the killfeed 10 seconds after they appear.

Intended for use in frantic last team standing or free for all matches.

.. codeauthor:: hompy
"""

from collections import deque
from twisted.internet.reactor import callLater, seconds
from twisted.internet.task import LoopingCall
from pyspades import contained as loaders
from pyspades.common import make_color
from pyspades.constants import (
    GRENADE_KILL, RIFLE_WEAPON, SMG_WEAPON, SHOTGUN_WEAPON)

KILL_REQUIREMENT = 3
TIME_REQUIREMENT = 8.0
GRENADE_KILLS_COUNT = True
RAMPAGE_REFILLS = True
RAMPAGE_RELOADS = True
RAMPAGE_DURATION = 20.0
RAPID_INTERVALS = {
    RIFLE_WEAPON: 0.16,
    SMG_WEAPON: 0.08,
    SHOTGUN_WEAPON: 0.18
}
RAMPAGE_FOG_COLOR = (255, 0, 0)

def RAMPAGE_FOG_FUNC():
    return RAMPAGE_FOG_COLOR

ANNOUNCE_RAMPAGE = True
S_RAMPAGE_START = '{player} IS ON A RAMPAGE!!'
S_RAMPAGE_KILLED = "{victim}'s rampage was ended by {killer}"

def resend_tool(player):
    set_tool = loaders.SetTool()
    set_tool.player_id = player.player_id
    set_tool.value = player.tool
    if player.weapon_object.shoot:
        player.protocol.broadcast_contained(set_tool)
    else:
        player.send_contained(set_tool)

def rapid_cycle(player):
    resend_tool(player)
    if not player.weapon_object.shoot:
        player.rampage_rapid_loop.stop()

def send_fog(player, color):
    fog_color = loaders.FogColor()
    fog_color.color = make_color(*color)
    player.send_contained(fog_color)

def fog_switch(player, colorgetter_a, colorgetter_b):
    if player.rampage:
        send_fog(player, colorgetter_a())
        player.rampage_warning_call = callLater(0.5, fog_switch, player,
                                                colorgetter_b, colorgetter_a)

def apply_script(protocol, connection, config):
    class RampageConnection(connection):
        rampage = False
        rampage_rapid_loop = None
        rampage_call = None
        rampage_warning_call = None
        rampage_kills = None
        rampage_reenable_rapid_hack_detect = None

        def start_rampage(self):
            self.rampage = True
            self.rampage_kills.clear()
            self.rampage_reenable_rapid_hack_detect = self.rapid_hack_detect
            self.rapid_hack_detect = False
            self.rampage_call = callLater(RAMPAGE_DURATION, self.end_rampage)
            if RAMPAGE_DURATION > 4.0:
                self.rampage_warning_call = callLater(
                    RAMPAGE_DURATION - 3.0,
                    fog_switch,
                    self,
                    self.protocol.get_fog_color,
                    RAMPAGE_FOG_FUNC)
            if RAMPAGE_REFILLS:
                self.refill()
            if RAMPAGE_RELOADS:
                weapon = self.weapon_object
                was_shooting = weapon.shoot
                weapon.reset()
                weapon_reload = loaders.WeaponReload()
                weapon_reload.player_id = self.player_id
                weapon_reload.clip_ammo = weapon.current_ammo
                weapon_reload.reserve_ammo = weapon.current_stock
                weapon.set_shoot(was_shooting)
                self.send_contained(weapon_reload)
            send_fog(self, RAMPAGE_FOG_COLOR)
            if ANNOUNCE_RAMPAGE:
                message = S_RAMPAGE_START.format(player=self.name)
                self.protocol.broadcast_chat(message, global_message=None)

        def end_rampage(self):
            self.rampage = False
            self.rapid_hack_detect = self.rampage_reenable_rapid_hack_detect
            if self.rampage_call and self.rampage_call.active():
                self.rampage_call.cancel()
            self.rampage_call = None
            if (self.rampage_warning_call and
                    self.rampage_warning_call.active()):
                self.rampage_warning_call.cancel()
            self.rampage_warning_call = None
            if self.rampage_rapid_loop and self.rampage_rapid_loop.running:
                self.rampage_rapid_loop.stop()
            send_fog(self, self.protocol.fog_color)

        def on_connect(self):
            self.rampage_rapid_loop = LoopingCall(rapid_cycle, self)
            self.rampage_kills = deque(maxlen=KILL_REQUIREMENT)
            connection.on_connect(self)

        def on_disconnect(self):
            if self.rampage:
                self.end_rampage()
            self.rampage_rapid_loop = None
            connection.on_disconnect(self)

        def on_reset(self):
            if self.rampage:
                self.end_rampage()
            connection.on_reset(self)

        def on_kill(self, killer, type, grenade):
            was_rampaging = self.rampage
            if self.rampage:
                self.end_rampage()
            if killer is not None and killer is not self:
                if was_rampaging and ANNOUNCE_RAMPAGE:
                    message = S_RAMPAGE_KILLED.format(victim=self.name,
                                                      killer=killer.name)
                    self.protocol.broadcast_chat(message, global_message=None)
                if (not killer.rampage and killer.hp and
                    killer.team is not self.team and
                        (GRENADE_KILLS_COUNT or type != GRENADE_KILL)):
                    now = seconds()
                    killer.rampage_kills.append(now)
                    if (len(killer.rampage_kills) == KILL_REQUIREMENT and
                            killer.rampage_kills[0] >= now - TIME_REQUIREMENT):
                        killer.start_rampage()
            return connection.on_kill(self, killer, type, grenade)

        def on_grenade_thrown(self, grenade):
            if self.rampage:
                resend_tool(self)
            connection.on_grenade_thrown(self, grenade)

        def on_shoot_set(self, fire):
            if (self.rampage and fire and
                self.rampage_rapid_loop and
                    not self.rampage_rapid_loop.running):
                interval = RAPID_INTERVALS[self.weapon]
                self.rampage_rapid_loop.start(interval, now=False)
            connection.on_shoot_set(self, fire)

    def send_fog_rule(player):
        return not player.rampage

    class RampageProtocol(protocol):

        def set_fog_color(self, color):
            self.fog_color = color
            fog_color = loaders.FogColor()
            fog_color.color = make_color(*color)
            self.broadcast_contained(fog_color, save=True, rule=send_fog_rule)

    return RampageProtocol, RampageConnection


#! venv/bin/python
import sys
import os
from flask import Flask
from flask import send_from_directory
import markdown
import pystache
import codecs

_MD_PATH = 'assets/md/'
_TEMPLATE_PATH = 'assets/templates/'
app = Flask(__name__)

@app.route('/')
def root():
    return send_from_directory('.', 'index.html')

@app.route('/<path:path>')
def send_static(path):

    return send_from_directory('.', path)

def render_site():
    md_files = os.listdir(_MD_PATH)
    template_str = ""
    with open(_TEMPLATE_PATH+"template.mustache") as template:
        template_str = template.read()

    #only compile files with .md extension
    for name in md_files:
        if name[-3:] == ".md":
            file_path = _MD_PATH+name

            with codecs.open(file_path, encoding="utf-8") as md_file:
                md_str = markdown.markdown(md_file.read())+"\n

\n

\n

"
                output = pystache.render(template_str, {"content": md_str})
                out_file = codecs.open(name.split('.')[0]+'.html','w', encoding="utf-8")
                out_file.write(output, )
    print("rendered pages: " + str(md_files))

if __name__ == "__main__":

    render_site()

    if len(sys.argv) > 1:
        runServer = sys.argv[1].strip("-")
        if runServer == "true":
            app.run(host='127.0.0.1', threaded=True)


import random
import math
import copy

import numpy as np

import utils

class flavorText:

    std = '...'

    # assuming 3x3 player grid
    trans = {
        (0, 0): 'corner',
        (0, 1): 'wall',
        (0, 2): 'corner',

        (1, 0): 'wall',
        (1, 1): 'center',
        (1, 2): 'wall',

        (2, 0): 'corner',
        (2, 1): 'wall',
        (2, 2): 'corner',
    }

    rim = {
        'corner': ['a snowdrift is piled up in the corner'],
        'center': ['starlight streams in from above'],
        'wall': ['a crooked panel reveals numerous decrepit cables'],
    }

    locs = {
        'rim': rim,
    }

    @classmethod
    def flavor(self, location, pos):
        if random.random() < 0.1:
            return random.choice(self.locs[location][self.trans[pos]])
        else:
            return self.std

tiles = {
    'unlit': ' ',
    'lit': '•',
    'opaque': '█',
    'opaque_up': '▀',
    'opaque_down': '▄',
    'water': '~'
    # 'corpse': '×', this would be a dynamic element, not a baked room element
}

# flatgen = {}
# keys = list(tiles.keys())
#
# for i in range(len(keys)):
#     for j in range(len(keys)):

flat = {
    (0, 0): 'unlit',
    (2, 1): 'opaque_up',
    (1, 2): 'opaque_down',
    (1, 1): 'lit',

    (2, 0): 'opaque_up',
    (0, 2): 'opaque_down',
    (2, 2): 'opaque',
}

# NOTE for map data --
# 0 = unlit tile
# 1 = lit
# 2 = opaque

doorTemplate = {
    'type': 'normal',
    'position': (0, 0),
    'postr': 'left',
    'state': 'open',
}

def newDoor(type, pos, postr, state):
    return {'type': type, 'pos': pos, 'postr': postr, 'state': state}

roomTemplate = {
    'type': 'room',
    'name': 'room',
    'width' : -1,
    'height': -1,
    'playerw': 3,
    'playerh': 3,
    'draww': -1,
    'drawh': -1,
    'ptog': {},
    'flav': {},
    'map': [],
    'things': [],
    'doors': [],
    'special': None,
    'dist': 0,
}

sqRoom = {
    'type': 'room',
    'name': 'square',
    'width': 5,
    'height': 5,
    'playerw': 3,
    'playerh': 3,
    'map': [
        2, 2, 2, 2, 2,
        2, 0, 0, 0, 2,
        2, 0, 0, 0, 2,
        2, 0, 0, 0, 2,
        2, 2, 2, 2, 2,
    ],
    'things': [],
}

def formatRoom(roomdict):
    w = roomdict['draww']
    h = roomdict['drawh']
    # for final discord use:
    # output = '```'
    output = ''
    mapp = roomdict['map']
    # print(math.ceil(h/2))
    for y in range(math.ceil(h/2)):
        for x in range(w):
            pos1 = utils.od(x, y*2, w)
            pos2 = utils.od(x, y*2 + 1, w)
            # print(pos1, pos2)
            try:
                output += tiles[flat[(mapp[pos1], mapp[pos2])]]
            except IndexError:
                # print(flat[(mapp[pos1]), mapp[pos1]])
                output += tiles[flat[(mapp[pos1], 0)]]
            except KeyError:
                print('Error: room {} is poorly formatted!'.format(roomdict['name']))
                exit(1)
        output += '\n'
    # for final discord use:
    # output += '```'
    return output

doorList = [
    'up',
    'down',
    'left',
    'right'
]

doorTrans = {
    (0, 1): 'left',
    (2, 1): 'right',
    (1, 0): 'up',
    (1, 2): 'down'
}

wallTile = 2
litTile = 1

def genRect(dict, tempmap, width, height, fill, location, doors):
    # smallest size for a rect is 5x5
    for y in range(height):
        for x in range(width):
            if y == 0:
                tempmap[utils.od(x, y, width)] = wallTile
            elif y == height - 1:
                tempmap[utils.od(x, y, width)] = wallTile
            if x == 0:
                tempmap[utils.od(x, y, width)] = wallTile
            elif x == width - 1:
                tempmap[utils.od(x, y, width)] = wallTile

            if fill:
                if x > 1 and x < width - 2 and y > 1 and y < height - 2:
                    if (x + 1) % 3 == 0:
                        tempmap[utils.od(x, y, width)] = litTile
    # if width
    # dict['playerw']
    # TODO -- this should be in terms of playerw and playerh
    for y in range(3):
        for x in range(3):
            dict['ptog'][(x, y)] = (x*((dict['width'] - 1)//2),
                                   y*((dict['height'] - 1)//2))
            dict['flav'][(x, y)] = flavorText.flavor(location, (x, y))

            if (x, y) in doorTrans and doorTrans[(x, y)] in doors:
                dict['doors'].append(newDoor('normal', (x, y), doorTrans[(x, y)], 'open'))
            elif (x, y) in doorTrans and doorTrans[(x, y)] + '_k' in doors:
                dict['doors'].append(newDoor('key', (x, y), doorTrans[(x, y)], 'open'))

    # doors (hardcoded 2 pixels)
    unlit = 0
    if height % 2 == 0:
        if 'left' in doors:
            tempmap[utils.od(0, height/2 - 1, width)] = unlit
            tempmap[utils.od(0, height/2, width)] = unlit

        if 'right' in doors:
            tempmap[utils.od(width - 1, height/2 - 1, width)] = unlit
            tempmap[utils.od(width - 1, height/2, width)] = unlit
    else:
        if 'left' in doors:
            tempmap[utils.od(0, math.floor(height/2), width)] = unlit
        if 'right' in doors:
            tempmap[utils.od(width - 1, math.floor(height/2), width)] = unlit

    if width % 2 == 0:
        if 'up' in doors:
            tempmap[utils.od(width/2 - 1, 0, width)] = unlit
            tempmap[utils.od(width/2, 0, width)] = unlit

        if 'down' in doors:
            tempmap[utils.od(width/2 - 1, height - 1, width)] = unlit
            tempmap[utils.od(width/2, height - 1, width)] = unlit
    else:
        if 'up' in doors:
            tempmap[utils.od(width/2, 0, width)] = unlit
        if 'down' in doors:
            tempmap[utils.od(width/2, height - 1, width)] = unlit

def genCircle(tempmap, width, height, fill, location):
    # smallest size for a rect is 5x5
    for y in range(height):
        for x in range(width):
            if y == 0:
                tempmap[utils.od(x, y, width)] = wallTile
            elif y == height - 1:
                tempmap[utils.od(x, y, width)] = wallTile
            if x == 0:
                tempmap[utils.od(x, y, width)] = wallTile
            elif x == width - 1:
                tempmap[utils.od(x, y, width)] = wallTile

            if fill:
                if x > 1 and x < width - 2 and y > 1 and y < height - 2:
                    if (x + 1) % 3 == 0:
                        tempmap[utils.od(x, y, width)] = litTile
    # if width
    # dict['playerw']
    # TODO -- this should be in terms of playerw and playerh
    for y in range(3):
        for x in range(3):
            dict['ptog'][(x, y)] = (x*((dict['width'] - 1)//2),
                                   y*((dict['height'] - 1)//2))
            dict['flav'][(x, y)] = flavorText.flavor(location, (x, y))

    # doors (hardcoded 2 pixels)
    unlit = 0
    if height % 2 == 0:
        tempmap[utils.od(0, height/2 - 1, width)] = unlit
        tempmap[utils.od(0, height/2, width)] = unlit
        tempmap[utils.od(width - 1, height/2 - 1, width)] = unlit
        tempmap[utils.od(width - 1, height/2, width)] = unlit
    else:
        tempmap[utils.od(0, math.floor(height/2), width)] = unlit
        tempmap[utils.od(width - 1, math.floor(height/2), width)] = unlit

    if width % 2 == 0:
        tempmap[utils.od(width/2 - 1, 0, width)] = unlit
        tempmap[utils.od(width/2, 0, width)] = unlit
        tempmap[utils.od(width/2 - 1, height - 1, width)] = unlit
        tempmap[utils.od(width/2, height - 1, width)] = unlit
    else:
        tempmap[utils.od(width/2, 0, width)] = unlit
        tempmap[utils.od(width/2, height - 1, width)] = unlit

def genRoom(name, width, height, shape, doors=doorList, fill=True, location='rim', special=None, dist=0):
    dict = copy.deepcopy(roomTemplate)
    dict['name'] = name
    dict['width'] = width
    dict['height'] = height
    width = width*3 + 2
    height = height*2 + 4
    dict['draww'] = width
    dict['drawh'] = height
    dict['special'] = special
    dict['dist'] = dist
    tempmap = np.zeros((width*height,), dtype='u1')

    # note -- this will cause errors if the height is less than four
    if shape == 'rect':
        genRect(dict, tempmap, width, height, fill, location, doors)
    elif shape == 'circle':
        genCircle(tempmap, width, height, fill, location)

    dict['map'] = tempmap
    return dict

# bigg = genRoom('sq', 18, 9, 'rect')

def printRoom(roomdict):
    for y in range(roomdict['drawh']):
        string = ''
        for x in range(roomdict['draww']):
            string += str(roomdict['map'][utils.od(x, y, roomdict['draww'])])
        print(string)

# printRoom(bigg)

arenaStr = '\n'.join([
'   ░░░░░░░░░░░░░░░░░░░░░░░░   ',
'   ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒   ',
'   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓   ',
'  /...............{6}.{3}..\\  ',
' /••{0}••••••••••••{4}•{1}••\\ ',
'/●●●●●●●●●●●●●●●●●●●{5}●{2}●●\\'
])

replacement = [
    '•••',
    '●●●',
    '...',
    '•••',
    '●●●',
    '...'
]

barStr = '\n'.join([
' {} ',
'│{}│',
'│{}│',
'│{}│',
'│{}│',
'│{}│',
])

barFill = [
    ' ',
    '▁',
    '▂',
    '▃',
    '▄',
    '▅',
    '▆',
    '▇',
    '█',
]

def drawBar(char, total, current):
    numsegs = 5
    totalRange = numsegs * 8 # as determined by box characters
    # this assumes a start of zero
    barval = utils.clamp(int(utils.remap(current, 0, total, 0, totalRange)), 0, totalRange)
    numFull = barval // 8
    partial = barval % 8
    barlist = [barFill[-1] for x in range(numFull)]
    if partial != 0:
        barlist += [barFill[partial]]
    barlist += [' ' for x in range(numsegs - len(barlist))]
    return barStr.format(char, *barlist[::-1])

def drawArena(player):
    enemyList = [x.dict['char'] for x in player.dict['enemies']]
    enemyList += replacement[len(enemyList):]
    arena = arenaStr.format(player.dict['char'], *enemyList)
    bar = drawBar('H', player.dict['stats']['hp'], player.dict['status']['hp'])
    merge1 = utils.mergeStrings(arena, bar, 3, 0)
    return merge1

rectTemplate = genRoom('chamber', 7, 5, 'rect')

class Room:
    def __init__(self, initdict=rectTemplate, name=None, width=None, height=None, shape=None, dist=None):
        self.dict = copy.deepcopy(initdict)

        self.dict['name'] = name if name is not None else self.dict['name']
        self.dict['width'] = width if width is not None else self.dict['width']
        self.dict['height'] = height if height is not None else self.dict['height']
        self.dict['shape'] = shape if shape is not None else ''

    def draw(self, player):
        if player.dict['state']['state'] == 'exploration':
            tempbuff = formatRoom(self.dict)
            for thing in self.dict['things']:
                tempbuff = self.add(tempbuff, thing)
            tempbuff = self.addPlayer(tempbuff, player)
        elif player.dict['state']['state'] == 'combat':
            tempbuff = drawArena(player)
        return tempbuff

    def add(self, buff, thing):
        pos = self.buff2coord(thing.dict['x'], thing.dict['y'])
        offset = len(thing.dict['char'])//2
        return buff[:pos - offset] + thing.dict['char'] + buff[pos + 1 + offset:]

    def addPlayer(self, buff, player):
        temppos = self.getPlayerPos(player)
        pos = self.buff2coord(temppos[0], temppos[1])
        offset = len(player.dict['char'])//2
        # print(playerpos, temppos, pos)
        return buff[:pos - offset] + player.dict['char'] + buff[pos + 1 + offset:]

    def buff2coord(self, x, y):
        # + 1 because of newline
        return (x*3 + 2) + (y + 1)*(self.dict['draww'] + 1)

    def getPlayerPos(self, player):
        playerpos = (player.dict['x'], player.dict['y'])
        return self.dict['ptog'][playerpos]

    def insert(self, thing):
        self.dict['things'].append(thing)

    def save(self):
        for i in range(len(self.dict['things'])):
            self.dict['things'][i] = self.dict['things'][i].save()
        return self.dict

    def animate(self, player):
        for thing in self.dict['things']:
            thing.animate(player)
        for thing in self.dict['things']:
            if thing.dict['type'] == 'enemy':
                thing.resolveCollision(player)
        for thing in self.dict['things']:
            if utils.distance((thing.dict['x'], thing.dict['y']), self.getPlayerPos(player)) < 2:
                thing.onTouch(player)

    def validPosition(self, pos):
        if pos[0] < 0 or pos[0] > self.dict['width'] - 1:
            return False
        if pos[1] < 0 or pos[1] > self.dict['height'] - 1:
            return False
        return True


import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader
import torchvision.transforms as transforms
from torchvision.datasets import ImageFolder
from PIL import Image
from torch.utils.data.sampler import WeightedRandomSampler
from torchvision.datasets import DatasetFolder
import torchvision
from tqdm.notebook import tqdm as tqdm
from torchsampler import ImbalancedDatasetSampler
from sklearn.metrics import plot_confusion_matrix
from sklearn.metrics import confusion_matrix
from torch.utils.data.sampler import SubsetRandomSampler

class VGG16(nn.Module):

    def __init__(self):
        super(VGG16, self).__init__()

        # calculate same padding:
        # (w - k + 2*p)/s + 1 = o
        # => p = (s(o-1) - w + k)/2

        self.block_1 = nn.Sequential(
            nn.Conv2d(in_channels=3,
                      out_channels=64,
                      kernel_size=(3, 3),
                      stride=(1, 1),
                      # (1(32-1)- 32 + 3)/2 = 1
                      padding=1),
            nn.BatchNorm2d(64),
            nn.ReLU(),
            nn.Conv2d(in_channels=64,
                      out_channels=64,
                      kernel_size=(3, 3),
                      stride=(1, 1),
                      padding=1),
            nn.BatchNorm2d(64),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=(2, 2),
                         stride=(2, 2))
        )

        self.block_2 = nn.Sequential(
            nn.Conv2d(in_channels=64,
                      out_channels=128,
                      kernel_size=(3, 3),
                      stride=(1, 1),
                      padding=1),
            nn.BatchNorm2d(128),
            nn.ReLU(),
            nn.Conv2d(in_channels=128,
                      out_channels=128,
                      kernel_size=(3, 3),
                      stride=(1, 1),
                      padding=1),
            nn.BatchNorm2d(128),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=(2, 2),
                         stride=(2, 2))
        )

        self.block_3 = nn.Sequential(
            nn.Conv2d(in_channels=128,
                      out_channels=256,
                      kernel_size=(3, 3),
                      stride=(1, 1),
                      padding=1),
            nn.BatchNorm2d(256),
            nn.ReLU(),
            nn.Conv2d(in_channels=256,
                      out_channels=256,
                      kernel_size=(3, 3),
                      stride=(1, 1),
                      padding=1),
            nn.BatchNorm2d(256),
            nn.ReLU(),
            nn.Conv2d(in_channels=256,
                      out_channels=256,
                      kernel_size=(3, 3),
                      stride=(1, 1),
                      padding=1),
            nn.BatchNorm2d(256),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=(2, 2),
                         stride=(2, 2))
        )

        self.block_4 = nn.Sequential(
            nn.Conv2d(in_channels=256,
                      out_channels=512,
                      kernel_size=(3, 3),
                      stride=(1, 1),
                      padding=1),
            nn.BatchNorm2d(512),
            nn.ReLU(),
            nn.Conv2d(in_channels=512,
                      out_channels=512,
                      kernel_size=(3, 3),
                      stride=(1, 1),
                      padding=1),
            nn.BatchNorm2d(512),
            nn.ReLU(),
            nn.Conv2d(in_channels=512,
                      out_channels=512,
                      kernel_size=(3, 3),
                      stride=(1, 1),
                      padding=1),
            nn.BatchNorm2d(512),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=(2, 2),
                         stride=(2, 2))
        )

        self.block_5 = nn.Sequential(
            nn.Conv2d(in_channels=512,
                      out_channels=512,
                      kernel_size=(3, 3),
                      stride=(1, 1),
                      padding=1),
            nn.BatchNorm2d(512),
            nn.ReLU(),
            nn.Conv2d(in_channels=512,
                      out_channels=512,
                      kernel_size=(3, 3),
                      stride=(1, 1),
                      padding=1),
            nn.BatchNorm2d(512),
            nn.ReLU(),
            nn.Conv2d(in_channels=512,
                      out_channels=512,
                      kernel_size=(3, 3),
                      stride=(1, 1),
                      padding=1),
            nn.BatchNorm2d(512),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=(2, 2),
                         stride=(2, 2))
        )

        self.classifier = nn.Sequential(
            nn.Linear(512, 4096),
            nn.ReLU(True),
            nn.Dropout(p=0.65),
            nn.Linear(4096, 4096),
            nn.ReLU(True),
            nn.Dropout(p=0.65),
            nn.Linear(4096, 3),
        )

    def forward(self, x):

        x = self.block_1(x)
        x = self.block_2(x)
        x = self.block_3(x)
        x = self.block_4(x)
        x = self.block_5(x)
        x = x.view(x.size(0), -1)
        logits = self.classifier(x)
        return logits

def train():
    train_on_gpu = torch.cuda.is_available()
    if not train_on_gpu:
        print('CUDA is not available.')
    else:
        print('CUDA is available!')
    device = "cuda" if train_on_gpu else "cpu"

    train_image_path = "/home/chisc/workspace/wuzhenrong/galaxy/three_final/train/"
    val_image_path = "/home/chisc/workspace/wuzhenrong/galaxy/three_final/validation/"
    test_image_path = "/home/chisc/workspace/wuzhenrong/galaxy/three_final/test/"

    batch_size = 32
    # torch.manual_seed(0) # random seed

    # transforms.GaussianBlur(7,3)
    # transforms.ColorJitter(brightness=0.5, contrast=0.5, saturation=0.5, hue=0.5)
    # class0 = 212
    # class1 = 158
    # class2 = 2209
    # class_weights = [class0/2209, class1/2209, class2/2209]

    # train_set_size = int(len(train_data) * 0.9)
    # valid_set_size = len(train_data) - train_set_size
    # train_set, val_set = torch.utils.data.random_split(train_data, [train_set_size, valid_set_size])
    # print(train_data)

    # class0 = 351
    # class1 = 265
    # class2 = 1839
    # class_weights = [class0/2455, class1/2455, class2/2455]
    # target = torch.cat((torch.zeros(class0), torch.ones(class1), torch.ones(class2)*2)).long()
    # weights = 1. / torch.tensor(class_weights, dtype=torch.float)
    # # weights = weights.double()
    # # print(weights)
    # target = target[torch.randperm(len(target))]# shuffle
    # sampler_weights = weights[target]
    # class_sampler = WeightedRandomSampler(weights=sampler_weights, num_samples=2000, replacement=True)

    # E type :212
    # I type :158
    # S type :1839
    # All :2209
    ### new
    # E type :351
    # I type :265
    # S type :1839
    # All :2455

    ### latest
    # E type :732
    # I type :270
    # S type :1466
    ## All :2468
    train_trans = transforms.Compose([
                                    transforms.RandomHorizontalFlip(),
                                    transforms.RandomRotation((-30, 30)),
                                    transforms.Resize((255, 255)),
    #                                   transforms.CenterCrop(210),
    #                                   transforms.Resize((255, 255)),
    #                                   transforms.GaussianBlur(7,3),
    #                                   transforms.ColorJitter(brightness=0.5, contrast=0.5, saturation=0.5, hue=0.5),
                                    transforms.RandomCrop(size=(255, 255)),
                                    transforms.ToTensor()])

    train_data = ImageFolder(train_image_path, transform = train_trans)
    train_loader = DataLoader(train_data, pin_memory = True, batch_size = batch_size, sampler=ImbalancedDatasetSampler(train_data))

    val_trans = transforms.Compose([transforms.Resize((255, 255)),transforms.ToTensor()])
    val_data = ImageFolder(val_image_path, transform = val_trans)
    val_loader = DataLoader(val_data, shuffle = True)

    test_trans = transforms.Compose([transforms.Resize((255, 255)),transforms.ToTensor()])
    test_data = ImageFolder(test_image_path, transform = test_trans)
    test_loader = DataLoader(test_data, shuffle = True)

    print('Train:', len(train_data))
    print('Valid:', len(val_data))
    print('Test:', len(test_data))

    # for i, j in train_loader:
    #     break
    images, labels = next(iter(train_loader))
    print(labels)
    for i in np.arange(3):
        print(labels[i])
        plt.figure(i)
        plt.imshow(images[i].permute(1, 2, 0))
        plt.show()

    # model = Galaxy()
    model = torchvision.models.vgg16(pretrained=False)
    # model = VGG16() # the other way of vgg16
    # model = torchvision.models.resnet18(pretrained=False)
    model = model.to(device)
    print(model)

    optimizer = torch.optim.Adam(model.parameters(), lr=0.0001, weight_decay=0.005)
    # optimizer = torch.optim.SGD(model.parameters(), lr=0.0005, momentum=0.9, weight_decay=0.01)
    loss_func = nn.CrossEntropyLoss()
    # # reg = JacobianReg() # Jacobian regularization
    # lambda_JR = 0.01 # hyperparameter
    # l1_crit = nn.L1Loss(size_average=False)
    factor = 0.03
    n_epochs = 30
    train_loss_record = []
    train_acc_record = []
    val_loss_record = []
    val_acc_record = []
    min_loss = 2000.
    for epoch in range(n_epochs):
        train_loss = 0.0
        val_loss = 0.0
        train_acc = 0.0
        val_acc = 0.0
        model.train()
        for x, y in tqdm(train_loader):
            x, y = x.to(device), y.to(device)
            optimizer.zero_grad()
            prediction = model(x)
    #         reg_loss = 0
    #         reg_loss = l1_crit(prediction.argmax(dim = 1), y)

            loss = loss_func(prediction, y)

    #         loss = super_loss + factor*reg_loss

            loss.backward()
            optimizer.step()

            acc = ((prediction.argmax(dim = 1) == y).float().mean())
            train_acc += acc/len(train_loader)
            train_loss += loss/len(train_loader)
        print(f"[ Train | {epoch+1}/{n_epochs} ] loss = {train_loss:.5f}, acc = {train_acc:.5f}")
        train_loss_record.append(train_loss)
        train_acc_record.append(train_acc)

        model.eval()
        for x, y in tqdm(val_loader):
            x, y = x.to(device), y.to(device)
            prediction = model(x)
    #         reg_loss = 0

    #         reg_loss = l1_crit(prediction.argmax(dim = 1), y)

            loss = loss_func(prediction, y)

    #         loss = super_loss + factor*reg_loss

            loss.backward()
            acc = ((prediction.argmax(dim = 1) == y).float().mean())
            val_acc += acc/len(val_loader)
            val_loss += loss/len(val_loader)
            if loss < min_loss:
                min_loss = loss
                torch.save(model, 'E_I_S_new.pkl')
        print(f"[ Validation | {epoch+1}/{n_epochs} ] loss = {val_loss:.5f}, acc = {val_acc:.5f}")
        val_loss_record.append(val_loss)
        val_acc_record.append(val_acc)
    # torch.save(model, 'E_I_Sc.pkl')

    actu = []
    ai_pred = []
    model.eval()
    test_acc = 0.0
    test_loss = 0.0
    for x, y in test_loader:
        x, y = x.to(device), y.to(device)
        prediction = model(x)
        actu.append(y.to('cpu').numpy()[0])
        ai_pred.append(prediction.argmax().to('cpu').numpy().tolist())
        loss = loss_func(prediction, y)
        loss.backward()
        acc = ((prediction.argmax(dim = 1) == y).float().mean())
        test_acc += acc/len(test_loader)
        test_loss += loss/len(test_loader)
    print(f"[ Test ] loss = {test_loss:.5f}, acc = {test_acc:.5f}")

    model = torch.load('E_I_S_new.pkl')
    loss_func = nn.CrossEntropyLoss()
    i = 0
    for x, y in test_loader:
        i += 1
        if train_on_gpu:
            x, y = x.cuda(), y.cuda()
        output = model(x)
        out = output.argmax(dim = 1)
        out = out.to('cpu').numpy()
        if y[0] == 0:
            ans = 'E'
        elif y[0] == 1:
            ans = 'I'
        else:
            ans = 'S'
        if i % 10 == 0:
            plt.figure(i)
            if out[0] == 0:
                plt.title(f'Predict: E, Answer: {ans}')
            elif out[0] == 1:
                plt.title(f'Predict: I, Answer: {ans}')
            else:
                plt.title(f'Predict: S, Answer: {ans}')
            x = x.squeeze()
            x = x.to('cpu')
            plt.imshow(x.permute(1, 2, 0))
            plt.show()

    plt.figure(1)
    plt.title('Training and Validation Loss')
    train_l, = plt.plot(train_loss_record, color = 'red')
    val_l, = plt.plot(val_loss_record, color = 'blue')
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.legend(handles = [train_l, val_l], labels = ['Training', 'Validation'], loc = 'best')
    plt.show()

    plt.figure(2)
    plt.title('Training and Validation Accuracy')
    train_a, = plt.plot(train_acc_record, color = 'red')
    val_a, = plt.plot(val_acc_record, color = 'blue')
    plt.xlabel('Epochs')
    plt.ylabel('Accuracy')
    plt.legend(handles = [train_a, val_a], labels = ['Training', 'Validation'], loc = 'best')
    plt.show()

    answer = pd.Series(actu, name='Actual')
    pred = pd.Series(ai_pred, name='Predicted', dtype = 'int64')
    df_confusion = pd.crosstab(answer, pred, rownames=['True'], colnames=['Predicted'], margins=True)

    def plot_confusion_matrixs(df_confusion, title='Confusion matrix', cmap=plt.cm.hot):
        plt.matshow(df_confusion, cmap=cmap) # imshow
        plt.title(title)
        plt.colorbar()
        tick_marks = np.arange(len(df_confusion.columns))
    #     plt.xticks(tick_marks, df_confusion.columns, rotation=45)
    #     plt.yticks(tick_marks, df_confusion.index)
        plt.xticks([0, 1, 2, 3],['E', 'I', 'S', 'All'])
        plt.yticks([0, 1, 2, 3],['E', 'I', 'S', 'All'])
        plt.tight_layout()
        plt.ylabel(df_confusion.index.name)
        plt.xlabel(df_confusion.columns.name)

    plot_confusion_matrixs(df_confusion)

    confmat = confusion_matrix(y_true=actu, y_pred=ai_pred)

    fig, ax = plt.subplots(figsize=(5, 5))
    ax.matshow(confmat, cmap=plt.cm.Blues, alpha=0.3)
    for i in range(confmat.shape[0]):
        for j in range(confmat.shape[1]):
            ax.text(x=j, y=i, s=confmat[i,j], va='center', ha='center')
    plt.xlabel('predicted label')
    plt.ylabel('true label')
    plt.xticks([0, 1, 2],['E', 'I', 'S'])
    plt.yticks([0, 1, 2],['E', 'I', 'S'])
    plt.show()

if __name__ == '__main__':
    train()


import numpy as np
import cv2

cap = cv2.VideoCapture(0)

# Define the codec and create VideoWriter object
#fourcc = cv2.cv.CV_FOURCC(*'DIVX')
#out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))
# out = cv2.VideoWriter('output.avi', -1, 20.0, (640,480))

from threading import Thread
import threading
import time

bRecordVideo = True
bDetected = True

from datetime import datetime

def VideoWriting():
    global frame
    global bWriteVideo
    bFirstTime = True
    bWriteVideo = False
    out = cv2.VideoWriter()
    fourcc = cv2.VideoWriter_fourcc('M','J','P','G') #cv2.VideoWriter_fourcc(*'XVID')

    while bRecordVideo:
        if(True == bFirstTime and True == bDetected and True == bWriteVideo):
            fileName = datetime.now().strftime("%Y_%m_%d-%H_%M_%S") + '.avi'
            out = cv2.VideoWriter(fileName, fourcc, 20.0, (int(cap.get(3)), int(cap.get(4))))
            #cv2.VideoWriter('output.avi',fourcc, 20.0, (frame.shape[0],frame.shape[1]) )
            print(out.getBackendName())
            bFirstTime = False
        if(True == bWriteVideo):
            out.write(frame)
            bWriteVideo = False
        if(False == bDetected):
            bFirstTime = True
            out.release()

    if(out.isOpened() ):
        out.release()

recordingVideoThread = Thread(target=VideoWriting)

recordingVideoThread.daemon = True
recordingVideoThread.start()

ret = False
while(cap.isOpened()):
    try:
        ret, frame = cap.read()
    except KeyboardInterrupt:
        break

    if ret==True:
        bWriteVideo = True
        cv2.imshow('frame',frame)
        key = cv2.waitKey(1)
        if key & 0xFF == ord('q'):
            break
        elif key & 0xFF == ord('s'):
            bDetected = not bDetected
    else:
        break

# Release everything if job is finished
cap.release()
cv2.destroyAllWindows()

bRecordVideo = False

recordingVideoThread.join()