import pandas as pd
from pandas.api.types import is_numeric_dtype
import plotly.graph_objects as go
import plotly.express as px
import numpy as np
import datetime
import statsmodels.api as sm
from Barracuda_Styles import STYLES
#######################################################################################################################

# Primary Plotting Functions
#######################################################################################################################
def default_chart(message="Click drag on the map to select counties"):
    fig = go.Figure(
        data=[],
        layout=dict(
            title=message,
            paper_bgcolor=STYLES["chart_background"],
            plot_bgcolor=STYLES["chart_background"],
            font=dict(color=STYLES["font"]),
            margin=STYLES['margins'],
        )
    )
    return fig

# Creates a simple line plot.
def plot_line(df, time_val, y_val, label):
    fig = go.Figure()

    fig.add_trace(go.Scatter(
        x=df[time_val],
        y=df[y_val],
        mode='lines+markers',
        line={'color': STYLES['line_colors'][0]},
        showlegend=False
    ))

    fig_layout = style_figure(fig['layout'], label, "line")

    return fig

def plot_bar(df, x_val, y_val, label, summary):

    df["time"] = ["Present", "Predicted"]
    fig = px.bar(data_frame = df, y = x_val, x = y_val)

    fig_layout = style_figure(fig['layout'], label, "bar")
    fig.update_traces(marker_color='#1c4966')

    return fig

def plot_hist(df, x_val, label, summary):

    # get summary data
    if summary == "mean":
        sum_out = np.mean(df[x_val])
    if summary == "max":
        sum_out = np.max(df[x_val])
    if summary == "min":
        sum_out = np.min(df[x_val])
    if summary == "median":
        sum_out = np.median(df[x_val])

    mx = np.max(df[x_val])
    freq = np.unique(df[x_val], return_counts=True)

    fig = px.histogram(data_frame = df,
                 x = x_val
                 )

    fig.add_vline(x=sum_out, line_dash = 'dash', line_color = 'firebrick', line_width = 4)

    fig.add_annotation(
        x=sum_out,
        y=np.max(freq[1]),
        xref="x",
        yref="y",
        text=summary + " " + "value",
        font=dict(
            size=25,
            color="#ffffff"
            ),
        align="center",
        arrowhead=2,
        arrowsize=1,
        arrowwidth=4,
        arrowcolor="#636363",
        bordercolor="#c7c7c7",
        borderwidth=2,
        borderpad=4,
        ax=mx/10,
        ay=-mx/10,
        bgcolor="#808080",
        opacity=0.8
        )

    fig_layout = style_figure(fig['layout'], label, "hist")
    fig.update_traces(marker_color='#1c4966')

    return fig

# Creates a control chart plotly figure based on the input DataFrame and parameters
def plot_control(dataframe, segments, y_col, time_key, label, show_all, flags):

    fig = go.Figure()

    # Base line trace for the markers to sit on top of
    fig.add_trace(go.Scatter(x=dataframe[time_key],
                             y=dataframe[y_col],
                             mode='lines',
                             line_color=flags["base"][0],
                             showlegend=False))

    print_trend = True

    # loop to generate a trace for each flag
    for d in flags:
        if flags[d][1] == 1:
            if (d == 'trending up' or d == 'trending down') and print_trend:
                fig = plot_trends(fig, dataframe, segments, y_col, time_key, show_all, flags)
                print_trend = False

            # For all non-trend data, we use scatter plot markers.
            elif d not in ['trending up', 'trending down']:
                d_filter = d + ' mask'
                df = dataframe.loc[dataframe[d_filter] == 1]
                fig.add_trace(go.Scatter(x=df[time_key],
                                         y=df[y_col],
                                         mode='markers',
                                         name=d,
                                         marker_color=flags[d][0],
                                         showlegend=False if d == 'base' else True))

    # Line indicating average value of the dataset
    fig.add_shape(type="line",
                  line_color='blue',
                  line_width=2,
                  line_dash='dot',
                  x0=0,
                  x1=1,
                  xref='paper',
                  y0=np.average(dataframe[y_col]),
                  y1=np.average(dataframe[y_col]),
                  yref='y'
                  )

    fig_layout = style_figure(fig['layout'], label, "line")

    return fig

# Create statespace figure
def plot_statespace(df, time_val, lat_val, lon_val, label):
    fig = go.Figure()

    fig.add_trace(go.Scatter(
        x=df[time_val],
        y=df[lat_val],
        mode='lines',
        name="Latitude",
    ))
    fig.add_trace(go.Scatter(
        x=df[time_val],
        y=df[lon_val],
        mode='lines',
        name="Longitude",
    ))

    fig_layout = style_figure(fig['layout'], label)

    return fig

# Creates Choropleth figure
def plot_choropleth(dataframe, dataframe_label, data_label, data_json, years, counties, address, zips_df):

    if data_json[dataframe_label]['space_type'] == 'latlong':

        lat = 43
        lon = -74
        zoom = 4.5

        if ',' in address:
            addressSplit = address.split(",") # split address by comma

            # get row of data frame based on city and state
            coords = zips_df[(zips_df['city'] == addressSplit[0]) & (zips_df['state_id'] == addressSplit[1].strip())].head(1)
            lat = float(coords["lat"]) # get coords
            lon = float(coords["lon"]) # get coords
            zoom = 9

        dataframe['timeChar'] = dataframe[data_json[dataframe_label]['temporal_key']].astype('str')
        max_val = np.nanmax(dataframe[data_label])

        fig = px.scatter_mapbox(dataframe, lat=data_json[dataframe_label]['space_keys'][0],
                                lon=data_json[dataframe_label]['space_keys'][1],
                                color=data_label,
                                animation_frame='timeChar',
                                range_color=(0, max_val),
                                color_continuous_scale="Viridis",
                                opacity=0.6,
                                )

        # Choropleth Layout
        fig.update_layout(mapbox_style="carto-darkmatter", mapbox_zoom=zoom, mapbox_center={"lat": lat, "lon": lon}, )
        fig.update_layout(margin={"r": 0, "t": 0, "l": 20, "b": 0},
                          plot_bgcolor=STYLES["chart_background"],
                          paper_bgcolor=STYLES["chart_background"],
                          font=dict(color=STYLES["font"]),
                          # dragmode="lasso",
                          )

        unique_times = len(pd.unique(dataframe['timeChar']))

        fig.layout.height = 600
        fig.layout.coloraxis.showscale = True

        if unique_times > 1:
            fig.layout.updatemenus[0].buttons[0].args[1]["frame"]["duration"] = 200
            fig.layout.updatemenus[0].buttons[0].args[1]["transition"]["duration"] = 200
            fig.layout.sliders[0].pad.t = 10
            fig.layout.updatemenus[0].pad.t = 10

    else:

        lat = 34.640033
        lon = -95.981758
        zoom = 2.9

        if ',' in address:
            addressSplit = address.split(",") # split address by comma

            # get row of data frame based on city and state
            coords = zips_df[(zips_df['city'] == addressSplit[0]) & (zips_df['state_id'] == addressSplit[1].strip())].head(1)
            lat = float(coords["lat"]) # get coords
            lon = float(coords["lon"]) # get coords
            zoom = 9

        # Find max value for heat map bar
        max_val = max(dataframe[data_label])

        if data_json[dataframe_label]['dataset_label'] != 'Annual Weather Data':

            dataframe['timeChar'] = dataframe[data_json[dataframe_label]['temporal_key']].astype('str')

            fig = px.choropleth_mapbox(dataframe, geojson=counties, locations='fips', color=data_label,
                               color_continuous_scale="Viridis",
                               range_color=(0, max_val),
                               animation_frame='timeChar',
                               mapbox_style="carto-darkmatter",
                               zoom=zoom, center={"lat": lat, "lon": lon},
                               opacity=0.9,
                               labels={data_label: ' ', 'time': 'Time', 'Counties': 'County Code'}
                               )
        else:
            # filter by year
            dataframe = dataframe[(dataframe[data_json[dataframe_label]['temporal_key']] == years)]
            fig = px.choropleth_mapbox(dataframe, geojson=counties, locations='fips', color=data_label,
                           color_continuous_scale="Viridis",
                           range_color=(0, max_val),
                           mapbox_style="carto-darkmatter",
                           zoom=zoom, center={"lat": lat, "lon": lon},
                           opacity=0.9,
                           labels={data_label: ' ', 'time': 'Time', 'Counties': 'County Code'}
                           )

        fig.update_layout(margin={"r": 0, "t": 0, "l": 20, "b": 0},
                          geo_scope='usa',
                          plot_bgcolor=STYLES["chart_background"],
                          paper_bgcolor=STYLES["chart_background"],
                          font=dict(color=STYLES["font"]),
                          height=600,
                          )

    return fig
#######################################################################################################################

# Helper Functions
#######################################################################################################################
# Add trend lines to figure, plots trend lines of imported segments for the dataset.
def plot_trends(fig, df_plot, segments, y_col, time_key, show_all, flags):

    for start_idx, end_idx in zip(segments[:-1], segments[1:]):
        segment = df_plot.iloc[start_idx:end_idx + 1, :].copy()

        # Serialize the temporal column if it isn't already numeric
        if not is_numeric_dtype(segment[time_key]):
            segment['serial_time'] = [(d - datetime.datetime(1970, 1, 1)).days for d in segment[time_key]]
        else:
            segment['serial_time'] = segment[time_key]

        x = sm.add_constant(segment['serial_time'])
        model = sm.OLS(segment[y_col], x).fit()
        segment['fitted_values'] = model.fittedvalues

        fit_color = flags['trending up'][0] if model.params['serial_time'] > 0 \
            else flags['trending down'][0]

        trend_name = "Trending Up" if model.params['serial_time'] > 0 else "Trending Down"

        # Determine whether the current segment should be printed or not.
        print_trend = False

        if show_all:
            if (flags['trending up'][1] == 1 and model.params['serial_time'] > 0) \
                    or (flags['trending down'][1] == 1 and model.params['serial_time'] <= 0):
                print_trend = True
            else:
                pass
        else:
            if model.f_pvalue < 0.05:
                if (flags['trending up'][1] == 1 and model.params['serial_time'] > 0) \
                        or (flags['trending down'][1] == 1 and model.params['serial_time'] <= 0):
                    print_trend = True
                else:
                    pass
            else:
                pass

        if print_trend:
            fig.add_trace(go.Scatter(
                x=segment[time_key],
                y=segment['fitted_values'],
                mode='lines',
                line=dict(color=fit_color),
                name=trend_name,
            ))

    # Ensure duplicate legend items get removed
    legend_names = set()
    fig.for_each_trace(
        lambda trace:
        trace.update(showlegend=False) if (trace.name in legend_names) else legend_names.add(trace.name)
    )

    return fig

# Figure Style Information
def style_figure(layout, title, type):
    fig_layout = layout

    if type == "hist":
        fig_layout["yaxis"]["title"] = "Count"
        fig_layout["xaxis"]["title"] = title
    if type == "line":
        fig_layout["yaxis"]["title"] = title
        fig_layout["xaxis"]["title"] = "Time"
    if type == "bar":
        fig_layout["yaxis"]["title"] = title
        fig_layout["xaxis"]["title"] = "Projection"

    fig_layout["yaxis"]["fixedrange"] = True
    fig_layout["xaxis"]["fixedrange"] = False
    fig_layout["hovermode"] = "closest"
    fig_layout["legend"] = dict(orientation="v")
    fig_layout["autosize"] = False
    fig_layout["paper_bgcolor"] = STYLES["chart_background"]
    fig_layout["plot_bgcolor"] = STYLES["chart_background"]
    fig_layout["font"]["color"] = STYLES["font"]
    fig_layout["font"]["size"] = 16
    fig_layout["xaxis"]["tickfont"]["color"] = STYLES["tick_font"]
    fig_layout["yaxis"]["tickfont"]["color"] = STYLES["tick_font"]
    fig_layout["xaxis"]["gridcolor"] = STYLES["chart_grid"]
    fig_layout["yaxis"]["gridcolor"] = STYLES["chart_grid"]
    fig_layout["margin"] = STYLES['margins']

    return fig_layout
#######################################################################################################################


# coding: utf-8
import numpy as np
import matplotlib.pyplot as plt
from collections import OrderedDict
from utils import img_show, load_mnist
from two_layer_net import TwoLayerNet

from optimizer import *

(x_train, y_train), (x_test, y_test) = load_mnist(normalize=True, one_hot_label=True)

optimizers = OrderedDict()
optimizers["SGD"] = SGD()
optimizers["Momentum"] = Momentum()
optimizers["AdaGrad"] = AdaGrad()
optimizers["Adam"] = Adam()

inters_num = 2000
train_size = x_train.shape[0]
batch_size = 100

markers = {"SGD": "o", "Momentum": "x", "AdaGrad": "s", "Adam": "D"}
train_loss_list = {}

for key in optimizers:
  net = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)
  optimizer = optimizers[key]
  train_loss_list[key] = []
  for i in range(inters_num):
      batch_mask = np.random.choice(train_size, batch_size)
      x_batch = x_train[batch_mask]
      y_batch = y_train[batch_mask]

      grads = net.gradient(x_batch, y_batch)
      optimizer.update(net.params, grads)

      loss = net.loss(x_batch, y_batch)
      train_loss_list[key].append(loss)

  x = np.arange(inters_num)
  plt.plot(x, train_loss_list[key], marker=markers[key], markevery=100, label=key)

plt.xlabel("iterations")
plt.ylabel("loss")
#plt.ylim(0, 5)
plt.legend()
plt.show()


""" asd a"""
from osgeo import ogr, gdal
import os
import numpy
from skimage.graph import route_through_array
import cookbook

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

def get_array_from_dataset(dataset):
    band = dataset.GetRasterBand(1)
    array = band.ReadAsArray()
    #_display_array(array)
    return array

def get_dataset_from_filepath(filepath):
    """Imports dataset using gdal library."""
    dataset = gdal.Open(
        filepath,
        gdal.GA_ReadOnly
    )
    return dataset

def convert_Tiff_raster_to_array(user_input_path):
    raster = gdal.Open(user_input_path)
    band = raster.GetRasterBand(1)
    array = band.ReadAsArray()
    return array

def get_path_from_cost_surface(cost_dataset, start_point, dest_point):
    CostSurfacefn = "C:\\Users\\Diego\\Desktop\\python_workspace\\10x10_bsp.tif"
    # coordinates to array index
    startCoordX = start_point.x
    startCoordY = start_point.y
    startIndexX, startIndexY = cookbook.coord2pixelOffset(
        CostSurfacefn,
        startCoordX,
        startCoordY
    )

    stopCoordX = dest_point.x
    stopCoordY = dest_point.y
    stopIndexX, stopIndexY = cookbook.coord2pixelOffset(
        CostSurfacefn,
        stopCoordX,
        stopCoordY
    )

    costSurfaceArray = convert_Tiff_raster_to_array(CostSurfacefn)
    _display_array(costSurfaceArray)
    print("##############")
    # create path
    indices, weight = route_through_array(
        costSurfaceArray,
        (startIndexY, startIndexX),
        (stopIndexY, stopIndexX),
        geometric=True,
        fully_connected=True
    )
    indices = numpy.array(indices).T
    path = numpy.zeros_like(costSurfaceArray)
    path[indices[0], indices[1]] = 1
    _display_array(path)
    return path

def convert_array_to_Tiff_raster(array, output_path):
    driver = gdal.GetDriverByName('GTiff')
    cols = array.shape[1]
    rows = array.shape[0]
    outRaster = driver.Create(output_path, cols, rows, 1, gdal.GDT_Byte)
    return outRaster

def _display_array(array):
    for row in array:
        for pixel in row:
            print(pixel, end="")
        print()

def main():

    user_input_path = "C:\\Users\\Diego\\Desktop\\python_workspace\\10x10_bsp.tif"

    data_raster = get_dataset_from_filepath("C:\\Users\\Diego\\Desktop\\python_workspace\\10x10_bsp.tif")

    data_array = convert_Tiff_raster_to_array(user_input_path)

    path_dataset = get_path_from_cost_surface(data_array, Point(0, 0), Point(9, 9))

    output_path = "C:\\Users\\Diego\\Desktop\\python_workspace\\path_raster.tif"
    path_raster = convert_array_to_Tiff_raster(path_dataset, output_path)

if __name__ == '__main__':
    main()


from style import StyleContainer, StyleAccessor

# Anything that can by styled
class Element:
    # classes: a list of object classes. If nothing is passed, an empty list
    # will be used.
    def __init__(self, parent, style_descriptors, classes = None, id_ = None):
        self._parent = parent

        if parent:
            parent_style_container = parent.style_container
        else:
            parent_style_container = None

        self.style_container = StyleContainer(style_descriptors, parent_style_container)
        self.style = StyleAccessor(self.style_container)

        self.classes = classes or []
        self.id_ = id_

    # Must be implemented to return a list of all children; all instances of
    # Element subclasses, but can be different ones.
    def children(self):
        raise NotImplementedError()

    def get_parent(self):
        return self._parent


import unittest
from xml_to_json import XMLToJSON
import json

class TestXMLToJSON(unittest.TestCase):

  def test_convert_to_json_object(self):
    """test xml to json conversion on the specification files"""
    xml_to_json = XMLToJSON()
    test_cases = (
        ('lines.json', 'lines.xml'),
        ('words.json', 'words.xml')
    )

    for test_case in test_cases:

      with open('./tests/'+test_case[1]) as xml_file:
        xml_string = xml_file.read()
      with open('./tests/'+test_case[0]) as json_file:
        json_object = json.load(json_file)

      self.assertEqual(xml_to_json.convert_from_string(xml_string), json_object)

  def test_convert_to_int_list(self):
    """test the conversion of a coords string to an int list"""
    xml_to_json = XMLToJSON()
    test_case = ([13, 277, 313, 19], '13,277,313,19')
    self.assertEqual(xml_to_json._convert_to_int_list(test_case[1]), test_case[0])


import glob
import os
import shutil
import subprocess
import sys
import unittest

import torch
from testpath.tempdir import TemporaryDirectory

from neuropod.packagers import create_pytorch_neuropod
from neuropod.tests.utils import get_addition_model_spec, requires_frameworks
from neuropod.utils.hash_utils import sha256sum

ADDITION_MODEL_SOURCE = """
import torch
import torch.nn as nn
import addition_op

class AdditionModel(nn.Module):
    def forward(self, x, y):
        return {
            "out": addition_op.forward(torch.from_numpy(x), torch.from_numpy(y)).numpy()
        }

def get_model(_):
    return AdditionModel()
"""

def build_op(workdir):
    subprocess.check_call([sys.executable, "setup.py", "build"], cwd=workdir)
    return glob.glob(os.path.join(workdir, "build", "lib*", "addition_op.so"))[0]

@requires_frameworks("python")
@unittest.skipIf(
    not torch.__version__.startswith("1.4.0"),
    "Skipping custom op test for torch != 1.4.0",
)
class TestPytorchPackaging(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        # Build the custom op
        current_dir = os.path.dirname(os.path.abspath(__file__))

        cls.custom_op_path = build_op(os.path.join(current_dir, "addition_op_1"))

        # For testing loading of a custom op multiple times
        cls.second_custom_op = os.path.join(current_dir, "addition_op_copy.so")
        shutil.copyfile(cls.custom_op_path, cls.second_custom_op)

        # This op is named the same thing as the above op, but has a different
        # implementation
        cls.other_op_path = build_op(os.path.join(current_dir, "addition_op_2"))

    def package_simple_addition_model(self, test_dir, custom_ops, do_fail=False):
        neuropod_path = os.path.join(test_dir, "test_neuropod")
        model_code_dir = os.path.join(test_dir, "model_code")
        os.makedirs(model_code_dir)

        with open(os.path.join(model_code_dir, "addition_model.py"), "w") as f:
            f.write(ADDITION_MODEL_SOURCE)

        # `create_pytorch_neuropod` runs inference with the test data immediately
        # after creating the neuropod. Raises a ValueError if the model output
        # does not match the expected output.
        create_pytorch_neuropod(
            neuropod_path=neuropod_path,
            model_name="addition_model",
            data_paths=[],
            code_path_spec=[
                {
                    "python_root": model_code_dir,
                    "dirs_to_package": [""],  # Package everything in the python_root
                }
            ],
            entrypoint_package="addition_model",
            entrypoint="get_model",
            custom_ops=custom_ops,
            requirements="""
            torch==1.4.0
            """,
            # Get the input/output spec along with test data
            **get_addition_model_spec(do_fail=do_fail)
        )

        return neuropod_path

    def test_simple_addition_model(self):
        # Tests a case where packaging works correctly and
        # the model output matches the expected output
        with TemporaryDirectory() as test_dir:
            self.package_simple_addition_model(
                test_dir, custom_ops=[self.custom_op_path, self.second_custom_op]
            )

    def test_simple_addition_model_failure(self):
        # Tests a case where the output does not match the expected output
        with TemporaryDirectory() as test_dir:
            with self.assertRaises(ValueError):
                self.package_simple_addition_model(
                    test_dir, do_fail=True, custom_ops=[self.custom_op_path]
                )

    def test_consistent_hash(self):
        # Packages the same model twice and ensures it has the same hash
        shas = []
        for i in range(2):
            with TemporaryDirectory() as test_dir:
                self.package_simple_addition_model(
                    test_dir, custom_ops=[self.custom_op_path, self.second_custom_op]
                )

                neuropod_path = os.path.join(test_dir, "test_neuropod")
                shas.append(sha256sum(neuropod_path))

        self.assertEqual(shas[0], shas[1])

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


"""
Tools for animating simulation data.
"""

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib import animation
from matplotlib.patches import Circle
import discretisedfield as df
import re
from MicromagneticAnalysisTools import Read
from MicromagneticAnalysisTools import Plot
from MicromagneticAnalysisTools import Calculate
plt.rcdefaults()  # Reset stylesheet imported by discretisedfield

def oneDQuantity(quantityArray, timeArray, yLabel, quantityTextValue, quantityTextFormat="{:.2f}", out_name="Movie.mp4", initialMinValue=0, initialMaxValue=0, fps=25):
    """ Outputs an animation of a generic quantity (e.g. Nsk, energy, current) over time. The input arrays are to be given as file names, e.g. Nsk.npy, Time.npy. """

    t = timeArray * 1e9

    fig, ax = plt.subplots()

    thePlot, = ax.plot(t[0], quantityArray[0], animated=True)

    plt.xlim(0, 0)
    plt.xlabel(r"$t$ (ns)")
    plt.ylabel(yLabel)

    minValue = initialMinValue
    maxValue = initialMaxValue

    quantityText = ax.text(0, maxValue, "")
    timeText = ax.text(0.05 * t[0], maxValue, "")

    def init():
        pass

    def updateAnim(i):

        print("Animating value", i, "of", len(quantityArray), end='\r')

        nonlocal maxValue
        nonlocal minValue

        try:
            if np.min(quantityArray[:i]) < minValue:
                minValue = np.min(quantityArray[:i])
            if np.max(quantityArray[:i]) > maxValue:
                maxValue = np.max(quantityArray[:i])

            quantityText.set_text(
                quantityTextValue + " = " + quantityTextFormat.format(quantityArray[i]))

            if maxValue == 0:  # Stop the texts being placed on top of one another if the energy is zero
                quantity_text_y = 0.02
                time_text_y = 0.03

            else:
                quantity_text_y = 0.3 * maxValue
                time_text_y = 0.5 * maxValue

            text_x = 0.05 * t[i]

            quantityText.set_position((text_x, quantity_text_y))
            timeText.set_position((text_x, time_text_y))

            timeText.set_text('t = ' + '{:.2f}'.format(t[i]) + ' ns')

        except ValueError:
            pass

        ax.set_xlim(t[0], t[i])
        ax.set_ylim(minValue, 1.1*maxValue)
        thePlot.set_data(t[:i+1], quantityArray[:i+1])
        ax.get_xaxis().set_major_formatter(
            mpl.ticker.FuncFormatter(lambda x, p: '{:.1f}'.format(x)))

    dataIterator = iter(range(len(quantityArray)))

    print("Producing animation", out_name)

    anim = animation.FuncAnimation(fig, updateAnim, dataIterator, init_func=init,
                                   blit=False, save_count=len(quantityArray))
    plt.tight_layout()

    anim.save(out_name, fps=fps, writer='ffmpeg')

def NskAnimation(NskArray, timeArray):
    oneDQuantity(NskArray, timeArray, r"$N_{\mathrm{sk}}$", r"$N_{\mathrm{sk}}$",
                 out_name="Nsk.mp4", initialMinValue=-1.1, initialMaxValue=1.1)

def currentAnimation(currentArray, timeArray, component):
    oneDQuantity(currentArray, timeArray, "$j_" + component + "$ (A m$^{-2}$)", "$j_" + component + "$",
                 quantityTextFormat="{:.2e}", out_name="Current" + component + ".mp4", initialMinValue=0, initialMaxValue=1)

def energyAnimation(energyArray, timeArray):
    oneDQuantity(energyArray, timeArray, "$E$ (J)", "$E$ (J)",
                 quantityTextFormat="{:.2e}", out_name="Energy.mp4", initialMinValue=energyArray[0], initialMaxValue=0.9 * energyArray[0])

class MagnetizationAnimator:

    def __init__(self,
    plot_type,
    directory,
    fig=None,
    ax=None,
    z_index=0,
    com_array_file=None,
    component=None,
    plot_quiver=False,
    show_time=False,
    time_units=None,
    plot_impurity=None,
    plot_pinning=None,
    show_component=False,
    interpolation=None,
    limits=None,
    length_units=None,
    step=1,
    start_file = None,
    end_file = None,
    rectangle_fracs = None,
    out_name = None,
    quiver_colour = [1., 1., 1.],
    quiver_scale = 1.,
    quiver_headwidth = 6,
    quiver_headlength = 10,
    quiver_headaxislength = 10,
    quiver_linewidth = 5):
        self.plot_type = plot_type
        self.directory = directory
        self.fig = fig
        self.ax = ax
        self.z_index = z_index
        self.com_array_file = com_array_file
        self.component = component
        self.plot_quiver = plot_quiver
        self.show_time = show_time
        self.time_units = time_units
        self.plot_impurity = plot_impurity
        self.plot_pinning = plot_pinning
        self.show_component = show_component
        self.interpolation = interpolation
        self.limits = limits
        self.length_units  = length_units
        self.step = step
        self.start_file = start_file
        self.end_file = end_file
        self.rectangle_fracs = rectangle_fracs
        self.out_name = out_name
        self.quiver_colour = quiver_colour
        self.quiver_scale = quiver_scale
        self.quiver_headwidth = quiver_headwidth
        self.quiver_headlength = quiver_headlength
        self.quiver_headaxislength = quiver_headaxislength
        self.quiver_linewidth = quiver_linewidth

        self.files_to_scan = Read.getFilesToScan(self.directory, self.start_file, self.end_file)
        assert len(self.files_to_scan) != 0

        self.Lx, self.Ly = Read.sampleExtent(self.directory)
        self.m_array = df.Field.fromfile(self.directory + '/' + self.files_to_scan[0]).array
        if self.limits == None: self.limits = [0., self.Lx, 0., self.Ly]
        self.limits_indices = self._get_limits_indices()

        # Offset the centre of mass array index if we do not start the animation at the beginning of the simulation
        self.corrected_idx = int(re.findall(r'\d+', start_file)[0]) if self.start_file else 0

        if fig == None:
            if ax == None:
                self.fig, self.ax = plt.subplots()
            else:
                raise ValueError('If supplying an axis, also need to supply a figure.')

        # Ensure the centre of mass marker colour is easily visible with the colour scheme
        self.marker_colour = 'green' if 'magnetization' in self.plot_type else 'red'

        if plot_type == 'quiveronly': self.plot_quiver = True

        self.plotter = Plot.MagnetizationPlotter(self.plot_type, self.directory, self.files_to_scan[0],
        ax=self.ax, z_index=self.z_index, component=self.component, plot_quiver=self.plot_quiver,
        plot_impurity=self.plot_impurity, plot_pinning=self.plot_pinning, show_component=self.show_component,
        interpolation=self.interpolation, limits=self.limits, length_units=self.length_units, step=self.step,
        quiver_colour=self.quiver_colour, quiver_scale=self.quiver_scale, quiver_headwidth=self.quiver_headwidth,
        quiver_headlength=self.quiver_headlength, quiver_headaxislength=quiver_headaxislength,
        quiver_linewidth=self.quiver_linewidth)

        if self.plot_quiver:
            if plot_type == 'quiveronly':
                self.quiver_plot = self.plotter.plot()
            else:
                self.colour_plot, self.quiver_plot = self.plotter.plot()

        else:
            self.colour_plot = self.plotter.plot()

        if self.com_array_file:
            self.com_array = np.load(self.com_array_file)
            self.com_marker = Circle(
                (self.com_array[0, 0], self.com_array[0, 1]), 10, color=self.marker_colour, alpha=0.8)
            self.ax.add_patch(self.com_marker)

        if self.show_time:

            file_text_x = 0.5 * (self.limits[1] - self.limits[0]) + self.limits[0]
            file_text_y = 1.1 * (self.limits[3] - self.limits[2]) + self.limits[2]
            time_text_x = self.limits[0]
            time_text_y = 1.1 * (self.limits[3] - self.limits[2]) + self.limits[2]

            if length_units:
                file_text_x /= 1e9*length_units
                file_text_y /= 1e9*length_units
                time_text_x /= 1e9*length_units
                time_text_y /= 1e9*length_units

            self.file_text = self.ax.text(file_text_x, file_text_y, "")
            self.time_text = self.ax.text(time_text_x, time_text_y, "")

    def _get_limits_indices(self):

        try:
            start_x_idx = int(np.round((self.limits[0] / self.Lx) * self.m_array.shape[0]))
            end_x_idx = int(np.round((self.limits[1] / self.Lx) * self.m_array.shape[0]))
            start_y_idx = int(np.round((self.limits[2] / self.Ly) * self.m_array.shape[1]))
            end_y_idx  = int(np.round((self.limits[3] / self.Ly) * self.m_array.shape[1]))

        except TypeError:
            start_x_idx = 0
            end_x_idx = self.m_array.shape[0]
            start_y_idx = 0
            end_y_idx = self.m_array.shape[1]

        return [start_x_idx, end_x_idx, start_y_idx, end_y_idx]

    def _get_limits_indices(self):

        try:
            start_x_idx = int(np.round((self.limits[0] / self.Lx) * self.m_array.shape[0]))
            end_x_idx = int(np.round((self.limits[1] / self.Lx) * self.m_array.shape[0]))
            start_y_idx = int(np.round((self.limits[2] / self.Ly) * self.m_array.shape[1]))
            end_y_idx  = int(np.round((self.limits[3] / self.Ly) * self.m_array.shape[1]))

        except TypeError:
            start_x_idx = 0
            end_x_idx = self.m_array.shape[0]
            start_y_idx = 0
            end_y_idx = self.m_array.shape[1]

        return [start_x_idx, end_x_idx, start_y_idx, end_y_idx]

    def _update_magnetization_array(self, full_file):

        magnetization_array = df.Field.fromfile(full_file).array[:, :, self.z_index, :]

        magnetization_array = magnetization_array[self.limits_indices[0]: self.limits_indices[1],
            self.limits_indices[2]: self.limits_indices[3]]

        plot_array = Plot.vecToRGB(magnetization_array).transpose(1, 0, 2)
        self.colour_plot.set_array(plot_array)

    def _update_magnetization_single_component_array(self, full_file):

        magnetization_array = df.Field.fromfile(full_file).array

        magnetization_array = magnetization_array[self.limits_indices[0]: self.limits_indices[1],
            self.limits_indices[2]: self.limits_indices[3]]

        if self.component == 'x':
            new_plot_array = magnetization_array[:, :, self.z_index, 0]

        elif self.component == 'y':
            new_plot_array = magnetization_array[:, :, self.z_index, 1]

        elif self.component == 'z':
            new_plot_array = magnetization_array[:, :, self.z_index, 2]

        self.colour_plot.set_array(new_plot_array.T)

    def _update_skyrmion_density_array(self, full_file):

        magnetization_array = df.Field.fromfile(full_file).array[:, :, self.z_index]

        magnetization_array = magnetization_array[self.limits_indices[0]: self.limits_indices[1],
            self.limits_indices[2]: self.limits_indices[3]]

        magnetization_array = magnetization_array.reshape(magnetization_array.shape[0],
            magnetization_array.shape[1], 3)

        dx, dy = Read.sampleDiscretisation(self.directory)[:2]
        skyrmion_density_array = Calculate.skyrmionNumberDensity(magnetization_array, dx, dy, self.length_units).T
        self.colour_plot.set_array(skyrmion_density_array)

    def _update_quiver_array(self, full_file):

        # Load magnetization array and cut depending on user-defined limits
        magnetization_array = df.Field.fromfile(full_file).array[:, :, self.z_index, :]
        magnetization_array = magnetization_array[self.limits_indices[0]: self.limits_indices[1],
            self.limits_indices[2]: self.limits_indices[3]]

        # Remove the z-axis as only plotting in 2D plane
        magnetization_array = magnetization_array.reshape(
                magnetization_array.shape[0], magnetization_array.shape[1], 3)

        # Skip points specified by the step parameter
        magnetization_array = magnetization_array[::self.step, ::self.step, :]

        # Get in-plane magnetization value to normalise arrows
        in_plane_magnitude = np.sqrt(magnetization_array[:, :, 0]**2 + magnetization_array[:, :, 1]**2).T

        # Update arrow directions
        self.quiver_plot.set_UVC(magnetization_array[:, :, 0].T / in_plane_magnitude, magnetization_array[:, :, 1].T / in_plane_magnitude)

        # Update arrow colours
        colour_array = self.plotter._get_quiver_colour_array(magnetization_array)
        self.quiver_plot.set_facecolors(colour_array)

    def _update_marker_position(self, i):

        com_idx = i + self.corrected_idx
        marker_x, marker_y = self.com_array[com_idx]

        # For when the skrymion goes over the bounary with PBCs
        while marker_x >= self.Lx:
            marker_x -= self.Lx

        while marker_x < 0:
            marker_x += self.Lx

        while marker_y >= self.Ly:
            marker_y -= self.Ly

        while marker_y < 0:
            marker_y += self.Ly

        self.com_marker.center = [marker_x, marker_y]

    def animate(self):

        def update_anim(i):

            print("Producing animation frame", i, "of", len(self.files_to_scan), end='\r')

            full_file = self.directory + '/' + self.files_to_scan[i]

            if self.show_time:
                self.file_text.set_text('File: ' + self.files_to_scan[i])
                self.time_text.set_text('$t$ = ' + "{:.2f}".format(Read.fileTime(full_file) * 1e9) + " ns" if not self.time_units else
                                        '$t$ = ' "{:.2f}".format(Read.fileTime(full_file) / self.time_units))

            if self.plot_quiver:
                self._update_quiver_array(full_file)

            if self.plot_type == 'magnetization':
                self._update_magnetization_array(full_file)

            elif self.plot_type == 'magnetization_single_component':
                self._update_magnetization_single_component_array(full_file)

            elif self.plot_type == 'skyrmion_density':
                self._update_skyrmion_density_array(full_file)

            if self.com_array_file: self._update_marker_position(i)

        anim = animation.FuncAnimation(
                self.fig, update_anim, iter(range(len(self.files_to_scan))), blit=False, save_count=len(self.files_to_scan))

        if self.out_name is None:

            if self.plot_type == 'magnetization':
                if self.start_file or self.limits:
                    # After so much time generating the animation for the full simulation, don't want to overwrite it when looking at part of the simulation
                    self.out_name = 'mag_part.mp4'

                else:
                    self.out_name = 'mag.mp4'

            elif self.plot_type == 'magnetization_single_component':
                if self.start_file or self.limits:
                    # After so much time generating the animation for the full simulation, don't want to overwrite it when looking at part of the simulation
                    self.out_name = 'm' + self.component + '_part' + '.mp4'

                else:
                    self.out_name = 'm' + self.component + '.mp4'

            elif self.plot_type == 'skyrmion_density':
                if self.start_file or self.limits:
                    # After so much time generating the animation for the full simulation, don't want to overwrite it when looking at part of the simulation
                    self.out_name = 'SkDensityPart.mp4'

                else:
                    self.out_name = 'SkDensity.mp4'

            elif self.plot_type == 'quiveronly':
                if self.start_file or self.limits:
                    # After so much time generating the animation for the full simulation, don't want to overwrite it when looking at part of the simulation
                    self.out_name = 'QuiverPart.mp4'

                else:
                    self.out_name = 'Quiver.mp4'

        anim.save(self.out_name, fps=25, writer='ffmpeg')


import numpy as np
import pandas as pd
import dash_bootstrap_components as dbc
import dash

from dash import html, dcc, callback, Input, Output, State, ALL

from tools.utils import board_cast_2, create_df

dash.register_page(
    __name__,
    path='/',
    title='home', name='home'
    )

# -------------------------------
'''
Initial input:
- quantity of piles
- pile size
- footing dimension
- column size
'''
label_1 = ('Quantity of pile :', 'Pile size, cm :')
pile_id = ('pile-no', 'pile-size')
placeholder_1 = ('', 'sq:width, circle:diameter, cm')

label_2 = ('Footing dimensions, cm :' , 'Column size, cm :')
width_id = ('footing-width', 'column-width')
length_id = ('footing-length', 'column-depth')
placeholder_2 = ('footing-width',  'column-width', 'footing-length', 'column-depth')

definition = html.Div([
    dbc.Row([
        dbc.Col([html.H5('Pile type :')], width=3),
        dbc.Col([
            dcc.RadioItems(id='radio1', options={
                        'sqr': 'Square pile',
                        'cir': 'Circle'},
                        value='sqr',  inline=True),
        ], width=3),
    ]),
    html.Div([
        dbc.Row([
            dbc.Col([
                html.H5(label_1[i]),
            ], width=3, className='mt-2'),
            dbc.Col([
                dbc.Input(id=pile_id[i], type='number', placeholder=placeholder_1[i])], width=3, className='mt-2')
        ])for i in range(2)

    ]),
    html.Div([
        dbc.Row([
            dbc.Col([
                html.H5(label_2[i]),
            ], width=3, className='mt-2'),
            dbc.Col([
                dbc.Input(id=width_id[i], type='number', placeholder=placeholder_2[i])], width=3, className='mt-2'),
            dbc.Col([
                dbc.Input(id=length_id[i], type='number', placeholder=placeholder_2[i+2])], width=3, className='mt-2')
        ])
        for i in range(2)
    ]),
    dbc.Button('Submit', id='button-1', n_clicks=0, className='btn1 mt-4'),
    html.Hr()
    # TODO button cannot click if all input not full-fill
])

layout = dbc.Container(id='content', children=[
    definition,
    html.Form(id='xy-vector', children=[]),
    dbc.Button('Submit', id='button-2', n_clicks=0, className='btn2 mt-4'),
])

# -------------------------------
'''
Construct input for coordinate:
- X-Y coordinate
- error vector for each pile
'''
label3 = ('x', 'y', 'ex', 'ey')
@callback(
    Output('xy-vector', 'children'),
    Input('button-1', 'n_clicks'),
    State('pile-no', 'value'),
    prevent_initial_call=True,
)
def render_xy_input(n, n_pile):
    if n_pile != None:
        return html.Div([
            html.Div([
                dbc.Row([
                    dbc.Col(['Difine X-Y vector for each pile'], width=6),
                    dbc.Col(['Difine error vector for each pile'], width=6)
                ]),
            ]),
            html.Div([
                dbc.Row([
                    dbc.Col([dbc.Input(type='number', id={'type':'x-coor', 'id':f'x-{i+1}'}, placeholder=f'x-{i+1}', className='mt-2')]),
                    dbc.Col([dbc.Input(type='number', id={'type':'y-coor', 'id':f'y-{i+1}'}, placeholder=f'y-{i+1}', className='mt-2')]),
                    dbc.Col([dbc.Input(type='number', id={'type':'x-err', 'id':f'ex-{i+1}'}, placeholder=f'ex-{i+1}', className='mt-2')]),
                    dbc.Col([dbc.Input(type='number', id={'type':'y-err', 'id':f'ey-{i+1}'}, placeholder=f'ey-{i+1}', className='mt-2')]),
                ])for i in range(n_pile)
            ]),
            html.Div([
                dbc.Row([
                    dbc.Col([
                        dcc.Graph(id='graph', className='pb-4', figure={}),
                        dbc.Card(id='result', className='ml-2',
                            style={
                                    'width':'50%'
                                    })
                    ]),
                ])
            ]),
            html.Hr()
    ])
    # TODO button cannot click if all input not full-fill

# -------------------------------
# get X-Y coordinate
@callback(
    Output('graph', 'figure'),
    Output('result', 'children'),
    Input('button-2', 'n_clicks'),
    State('radio1', 'value'),
    State({'type':'x-coor', 'id':ALL}, 'value'),
    State({'type':'y-coor', 'id':ALL}, 'value'),
    State({'type':'x-err', 'id':ALL}, 'value'),
    State({'type':'y-err', 'id':ALL}, 'value'),
    State('footing-width', 'value'),
    State('footing-length', 'value'),
    State('column-width', 'value'),
    State('column-depth', 'value'),
    State('pile-size', 'value'),
    prevent_initial_call=True
)
def coor_text(n, type, x, y, ex, ey, B, L, w, d, p):
    if n > 0:
        X = np.array(x)
        Y = np.array(y)

        ex = np.array(ex)
        ey = np.array(ey)

        X_new = X + ex
        Y_new = Y + ey

        rx = X_new.sum()
        ry = Y_new.sum()
        unit_vector = np.array([rx, ry])
        unit_vector = unit_vector.T
        unit_vector = pd.DataFrame({
            'x' : [0, unit_vector[0]],
            'y' : [0, unit_vector[1]]
        })
        R = np.linalg.norm(unit_vector)

        # coordinate of column and footing
        column_x = np.array([w/2, -w/2, -w/2, w/2, w/2]) #[x1, x2, x3, ..., x1] x-coordinate
        column_y = np.array([d/2, d/2, -d/2, -d/2, d/2])
        footing_x = np.array([B/2, -B/2, -B/2, B/2, B/2])
        footing_y = np.array([L/2, L/2, -L/2, -L/2, L/2])

        # square pile
        if type == 'sqr' :
            # coordinate of local pile section
            px_vector = np.array([p/2, -p/2, -p/2, p/2, p/2]) #[p1, p2, p3, ..., p1] local x-coordinate
            py_vector = np.array([p/2, p/2, -p/2, -p/2, p/2])

            # coordinate of all piles and create df for plot
            piles = create_df(X, Y, px_vector, py_vector)
            piles_err = create_df(X_new, Y_new, px_vector, py_vector)

        # circle pile
        else:
            # https://plotly.com/python/shapes/
            # only need diagonal point to add circle
            px_vector = np.array([-p/2, p/2,])
            py_vector = np.array([-p/2, p/2,])

            PX = board_cast_2(X, px_vector)
            PY = board_cast_2(Y, py_vector)
            PX_NEW = board_cast_2(X_new, px_vector)
            PY_NEW = board_cast_2(Y_new, py_vector)
            print(PX)
            print(PY)
            print(PX_NEW)
            print(PY_NEW)

        footing = pd.DataFrame({
            'x' : footing_x,
            'y' : footing_y
        })

        column = pd.DataFrame({
            'x' : column_x,
            'y' : column_y
        })

    # plot
        # multi fig
        # https://stackoverflow.com/questions/69096931/how-do-i-combine-two-plots-into-one-figure-using-plotly
        import plotly.graph_objects as go
        fig = go.Figure()

        # plot footing
        fig.add_trace(go.Scatter(
            x=footing['x'], y=footing['y'], name='footing',
            mode='lines+markers'))

        # plot column
        fig.add_trace(go.Scatter(
            x=column['x'], y=column['y'], name='column',
             mode='lines+markers'))

        # plot piles
        if type == 'sqr':
            fig.add_trace(go.Scatter(
                x=piles['x'], y=piles['y'], name='drawing',
                mode='lines+markers',
                line=dict(color='#31fc03', width=2 )))

            fig.add_trace(go.Scatter(
                x=piles_err['x'], y=piles_err['y'], name='onsite',
                mode='lines+markers',
                line=dict(color='firebrick', width=2, dash='dash')))
        else:
            # Add circles
            # https://plotly.com/python/shapes/
            for i in range(len(X)):
                fig.add_shape(type="circle",
                    xref="x", yref="y",
                    x0=PX[2*i], y0=PY[2*i], x1=PX[2*i+1], y1=PY[2*i+1], # only need diagonal point to add circle
                    line_color="LightSeaGreen",)

            for i in range(len(X)):
                fig.add_shape(type="circle",
                    xref="x", yref="y",
                    x0=PX_NEW[2*i], y0=PY_NEW[2*i], x1=PX_NEW[2*i+1], y1=PY_NEW[2*i+1],
                    line=dict(color='orange', width=2, dash='dash'))

        # plot CG
        fig.add_trace(go.Scatter(
            x=unit_vector['x'], y=unit_vector['y'], name='C.G.',
            mode='markers', marker_symbol='cross'))

        fig.update_layout(
            autosize = False,
            width = B*4,
            height = L*4
        )

        return fig, dbc.CardBody([
                                html.H4(f"New CG : x = {rx}, y = {ry}, norm = {R:.2f} cm."),
                                ])


#all the imports
import os
import sqlite3

from flask import Flask, request, session, g, redirect, url_for, abort,render_template, flash

app = Flask(__name__)
app.config['DATABASE'] = '/www/db/storydb'
# 连接数据库
def connect_db():
    """Connects to the speciffic database."""
    # app.logger.warning(app.config['DATABASE'])
    rv = sqlite3.connect("/www/db/storydb.db")
    # rv = sqlite3.connect(app.config['DATABASE'])
    rv.row_factory = sqlite3.Row
    return rv

#获取数据库连接句柄
def get_db():
    """Opens a new database connection if there is none yet for the current application ocntext"""
    if not hasattr(g, 'sqlite_db'):
        g.sqlite_db = connect_db()
    return g.sqlite_db

#断开数据库
def close_db(error):
    """Closes the databse again at the end of the request"""
    if hasattr(g, 'sqlite_db'):
        g.sqlite_db.close()

# 执行数据库model
def ini_db():
    with app.app_context():
        db = get_db()
        with app.open_resource('schema.sql', mode='r') as f:
            db.cursor().executescript(f.read())
            db.commit()

if __name__ == '__main__':
    app.run()


from django.shortcuts import render
from django.http import HttpResponseRedirect
from .models import TodoItem
from django.forms.models import model_to_dict
from django.utils import timezone
import pytz
# Create your views here.

class item:
    def __init__(self, date, content, id_):
        self.date = convert_to_localtime(date)
        self.utc_time = date
        self.content = content
        self.id = id_

def convert_to_localtime(utctime):
    tm = "%B %d,%Y %I:%M %p"
    utc = utctime.replace(tzinfo=pytz.UTC)
    localtz = utc.astimezone(pytz.timezone('America/Los_Angeles'))
    return localtz.strftime(tm).lstrip("0").replace(" 0", " ")

def todoView(request):
    all_todo_items = TodoItem.objects.all()
    items = []
    for i in all_todo_items:
        items.append(item(i.date, i.text, i.id))
    items.sort(key=lambda x: x.id)
    return render(request, 'todo.html',
                  {'all_items': all_todo_items, 'items': items, 'auth': request.user.is_authenticated})

def addTodo(request):
    if not request.user.is_authenticated:
        return render(request, '404.html')
    new_item = TodoItem(text=request.POST['text'])
    new_item.save()
    return HttpResponseRedirect('/todo/')

def deleteTodo(request, todo_id):
    if not request.user.is_authenticated:
        return render(request, '404.html')
    delete_item = TodoItem.objects.get(id=todo_id)
    delete_item.delete()
    return HttpResponseRedirect('/todo/')


#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Mon Mar 12 13:14:12 2018

@author: icasdb
"""

import SimpleITK as sitk
import glob
import numpy as np
import dicom
import math

def dicom_sorter_thickness_splitter(dcm_unsorted_list):
    thickness_list=[]
    slicelocation_list=[]
    unique_sorted_thickness_list=[]
    sorted_slicelocation_list=[]
    dcm_sorted_list=[]
    dcm_sorted_thickness_list=[]
    dcm_lists=[]
    for i in range(len(dcm_unsorted_list)):
        x=dicom.read_file(dcm_unsorted_list[i])
        thickness_list.append(float(x.SliceThickness))
        slicelocation_list.append(float(x.SliceLocation))

    unique_sorted_thickness_list=sorted(set(thickness_list))
    sorted_slicelocation_list=sorted(slicelocation_list)

    for i in range(len(sorted_slicelocation_list)):
        for j in range(len(slicelocation_list)):
            if slicelocation_list[j]==sorted_slicelocation_list[i]:
                dcm_sorted_list.append(dcm_unsorted_list[j])
#        if i>0:
#            print sorted_slicelocation_list[i]-sorted_slicelocation_list[i-1]

    for i in range(len(unique_sorted_thickness_list)):
        for j in range(len(dcm_sorted_list)):
            x1=dicom.read_file(dcm_sorted_list[j])
            if float(x1.SliceThickness)==unique_sorted_thickness_list[i]:
                dcm_sorted_thickness_list.append(dcm_sorted_list[j])

        dcm_lists.append(dcm_sorted_thickness_list)
        dcm_sorted_thickness_list=[]

    return dcm_sorted_list, dcm_lists,unique_sorted_thickness_list

if __name__=="__main__":
    cid=101
    input_folder='/Users/icasdb/Desktop/'+str(cid)+'/'
    output_folder='/Users/icasdb/Desktop/'+str(cid)+'/'

    x1=sitk.ReadImage(input_folder+'NCCT_FIX_tiltcorrected.nii')
    y1=sitk.ReadImage(input_folder+'NCCT_TOPOK_tiltcorrected.nii')
    x1arr=sitk.GetArrayFromImage(x1)
    x1arr[x1arr<0]=0
    x1new=sitk.GetImageFromArray(x1arr)
    x1new.CopyInformation(x1)
    y1arr=sitk.GetArrayFromImage(y1)
    y1arr[y1arr<0]=0
    y1new=sitk.GetImageFromArray(y1arr)
    y1new.CopyInformation(y1)

    y1new.SetDirection(x1new.GetDirection())
    SimpleElastix=sitk.ElastixImageFilter()
    parameterMap = SimpleElastix.ReadParameterFile('/Users/icasdb/Desktop/DWINCCT/CODE/rigid_D3.txt')

    SimpleElastix.SetFixedImage(x1new)
    SimpleElastix.SetMovingImage(y1new)
    SimpleElastix.SetParameterMap(parameterMap)
    RI=SimpleElastix.Execute()
    transformParameterMap =SimpleElastix.GetTransformParameterMap()
    sitk.WriteParameterFile(transformParameterMap[0],output_folder+'tranform_param.xfm.txt')
    sitk.WriteImage(RI,output_folder+'image2_registeredto_image1.nii')
    RIarr=sitk.GetArrayFromImage(RI)

    x1arr[RIarr>0]=RIarr[RIarr>0]

    FIimage=sitk.GetImageFromArray(x1arr)
    FIimage.CopyInformation(x1new)
    sitk.WriteImage(FIimage,output_folder+'corrected_noncon.nii')


# Get the Mobile Country Codes (MCC) and Mobile Network Codes (MNC) table
# from mcc-mnc.com and output it in XML format.

import re
import urllib.request
import xml.etree.ElementTree as element_tree
import xml.dom.minidom as minidom

td_re = re.compile('([^<]*)	'*6)

with urllib.request.urlopen('http://mcc-mnc.com/') as f:
    html = f.read().decode('utf-8')

    tbody_start = False

    mcc_mnc_list = []

    for line in html.split('\n'):
        if '
' in line:
            tbody_start = True
        elif '
' in line:
            break
        elif tbody_start:
            td_search = td_re.search(line)
            current_item = {}
            td_search = td_re.split(line)

            current_item['mcc'] = td_search[1]
            current_item['mnc'] = td_search[2]
            current_item['iso'] = td_search[3]
            current_item['country'] = td_search[4]
            current_item['country_code'] = td_search[5]
            current_item['network'] = td_search[6][0:-1]

            mcc_mnc_list.append(current_item)

    root_element = element_tree.Element('carriers')

    for carrier in mcc_mnc_list:
        sub_element = element_tree.Element('carrier')

        for key, value in carrier.items():
            child_element = element_tree.Element(key)
            child_element.text = value
            sub_element.append(child_element)

        root_element.append(sub_element)

    print(minidom.parseString(element_tree.tostring(root_element)).toprettyxml(indent = '    '))


import argparse
import os

import shutil
import subprocess
import zipfile
import datetime
import pandas as pd
from DataCollector.Miners import miners_list

def compress_folder(folder_path, output_path):
    """Compresses all the files in a folder into a zip archive"""
    # Create a ZipFile object
    with zipfile.ZipFile(output_path, 'w') as zip_obj:
        # Iterate through all the files in the folder
        for root, dirs, files in os.walk(folder_path):
            for file in files:
                file_path = os.path.join(root, file)
                zip_obj.write(file_path, os.path.relpath(file_path, folder_path))

tmp_data_path = "./tmp_data"
backup_data_path = "./backup_data"
data_path = "DataVisualizer/data"

parser = argparse.ArgumentParser(description='Collect information on a topic from leading scientific publishers and visualize it ')
group = parser.add_mutually_exclusive_group()
group.add_argument('-c', '--collect', nargs=3, metavar=('term', 'start_year', 'end_year'),
                   type=str, help='Collect term information from start_year to end_year:  scientific_analyzer.py -c "blockchain" 2013 2022')
group.add_argument('-v', '--visualizer', action='store_true', help='Open a shiny app with the latest data collected')
group.add_argument('-l', '--load', action='store_true', help='Transfer the data you recently gathered in \'./tmp_data\' to the parser')
args = parser.parse_args()

if args.collect:
    term = args.collect[0]
    start_year = int(args.collect[1])
    end_year = int(args.collect[2])
    print("Option A chosen with arguments:", args.collect)
    print("term: {}  \nSyear: {} \nEdata: {}".format(term, start_year, end_year))

    # Clean tmp_data
    # Delete all csv files in the destination folder
    files = [f for f in os.listdir(tmp_data_path) if f.endswith(".csv")]
    for f in files:
        os.remove(os.path.join(tmp_data_path, f))

    # Save search term on .csv
    with open(tmp_data_path + "/term.csv", "w") as f:
        f.write(term)

    # Save search term on .csv
    with open(tmp_data_path + "/time.csv", "w") as f:
        f.write(datetime.datetime.now().strftime("%Y-%m-%d"))

    for MinerClass in miners_list:
        miner = MinerClass(term, start_year, end_year, tmp_data_path)
        miner.run()

    print()
    print()
    print()
    print("__________________________")
    print("Please execute the \'scientific_analyzer.py -l\' command to transfer the data you recently gathered in './tmp_data' to the parser.")
    print("__________________________")
    print()
    print()
    print()

elif args.visualizer:
    #print("Option B chosen with no additional arguments")
    res = subprocess.call('R -e "shiny::runApp(\'./DataVisualizer\')"', shell=True)
    res
    #os.system('R -e "shiny::runApp(\'~/DataVisualizer\')"')
    #
elif args.load:
    print("LOADING...")

    # OLD DATA BACKUP
    # Get the current date in the format YYYY-MM-DD
    current_date = datetime.datetime.now()
    # Define the name of the output archive
    output_path = backup_data_path+"/old_data_{}.zip".format(current_date)
    # Compress the folder
    compress_folder(data_path, output_path)

    # Delete all csv files in the destination folder
    files = [f for f in os.listdir(data_path) if f.endswith(".csv")]
    for f in files:
        os.remove(os.path.join(data_path, f))

    all_files = [f for f in os.listdir(tmp_data_path) if f.endswith("_data.csv")]

    df_list = []
    for file in all_files:
        df = pd.read_csv(os.path.join(tmp_data_path, file), dtype={'year': int, 'title': str, 'citations': int, 'authors': str, 'editorial': str})
        df_list.append(df)
    merged_df = pd.concat(df_list)
    merged_df.to_csv(os.path.join(data_path, "all.csv"), index=False)

    shutil.copy(tmp_data_path + "/time.csv", data_path + "/time.csv")
    shutil.copy(tmp_data_path + "/term.csv", data_path + "/term.csv")
    print("LOADED")
else:
    print()
    print()
    print("Run scientific_analyzer.py -h")
    print()
    print()


#!/usr/bin/env python
import sys
sys.path.append('core')
import os
import time, glob
import numpy as np
import torch
import cv2
from PIL import Image
import argparse
import rospy
from sensor_msgs.msg import CompressedImage

libs_path = os.path.join(os.path.dirname(__file__), "RAFT/")
sys.path.append(libs_path)
libs_path = os.path.join(os.path.dirname(__file__), "RAFT/core")
sys.path.append(libs_path)

from raft import RAFT
from utils import flow_viz
from utils.utils import InputPadder

DEVICE = 'cuda'
prev_img = None

def callback(ros_data):
    global pub, model, count, ts_start, prev_img
    start_time = time.time()
    np_arr = np.fromstring(ros_data.data, np.uint8)
    image_np = cv2.imdecode(np_arr, cv2.IMREAD_COLOR)
    img = cv2.cvtColor(image_np, cv2.COLOR_BGR2RGB)
    # img = cv2.resize(img, (368, 176))
    # img = cv2.resize(img, (336, 184))
    # img = cv2.resize(img, (336, 188))

    # zed camera size
    # img = cv2.resize(img, (672, 376))

    # unity size
    # img = cv2.resize(img, (180, 84))
    img = cv2.resize(img, (360, 168))
    # img = cv2.resize(img, (360, 168))
    # img = cv2.resize(img, (720, 336))

    image2 = torch.from_numpy(img).permute(2, 0, 1).float()
    image2 = image2[None].to(DEVICE)
    if prev_img == None:
        prev_img = image2
        return

    padder = InputPadder(prev_img.shape)
    image1, image2 = padder.pad(prev_img, image2)
    prev_img = image2
    flow_low, flow_up = model(image1, image2, iters=3, test_mode=True)
    flo = flow_up[0].permute(1,2,0).cpu().detach().numpy()
    # flo = flow_viz.flow_to_image(flo)

    # print('inference time:', time.time() - start_time)
    # print('header stamp:', ros_data.header.stamp)
    # print('my delay:', round((rospy.Time.now() - ros_data.header.stamp).to_sec(), 2))

    msg = CompressedImage()
    msg.header.stamp = ros_data.header.stamp
    msg.format = "jpeg"
    '''
    flo = cv2.imencode('.jpg', flo)[1]
    img = cv2.imencode('.jpg', img)[1]
    data_to_send = np.concatenate((img, flo), 0)
    s = str(img.shape[0]).rjust(16, '0')
    b = bytes(s, 'ascii')
    msg.data = data_to_send.tostring() + b
    '''
    msg.data = flo.tobytes()

    # Publish new image
    pub.publish(msg)

    count += 1
    delta = time.perf_counter() - ts_start
    # Log
    print("Sent", count, "images in",
        round(delta), "seconds with",
        round(count / delta, 2), "FPS and Latency",
        round((rospy.Time.now() - ros_data.header.stamp).to_sec(), 2), "seconds")

def main(args):
    global pub, model, count, ts_start
    print("Torch version", torch.__version__)

    parser = argparse.ArgumentParser()
    parser.add_argument('--model', help="restore checkpoint")
    parser.add_argument('--path', help="dataset for evaluation")
    parser.add_argument('--small', action='store_true', help='use small model', default=True)
    parser.add_argument('--mixed_precision', action='store_true', help='use mixed precision')
    parser.add_argument('--alternate_corr', action='store_true', help='use efficent correlation implementation')
    args = parser.parse_args()

    model = torch.nn.DataParallel(RAFT(args))
    # model.load_state_dict(torch.load("./RAFT/models/raft-kitti.pth"))
    # model.load_state_dict(torch.load("./RAFT/models/raft-things.pth"))
    model.load_state_dict(torch.load("./RAFT/models/raft-small.pth"))
    model = model.module
    model.to(DEVICE)
    model.eval()

    # Init ROS node
    rospy.init_node('flow_preprocessor', anonymous=True)
    pub = rospy.Publisher("/processed/flow_all_raw/compressed",
        CompressedImage, queue_size=1)
    sub = rospy.Subscriber("/camera/image_raw/compressed",
        CompressedImage, callback, queue_size = 1, buff_size=2*800*800*3*8*100)
    count = 0
    ts_start = time.perf_counter()
    # Begin main loop
    try:
        rospy.spin()
    except KeyboardInterrupt:
        print("Shutting down ROS Zed Segmentation module")

if __name__ == '__main__':
    main(sys.argv)


from typing import List, Tuple, Dict
from collections import defaultdict

from sqlalchemy.sql import text as sql

from ..common.story_key import StoryId
from ..common.story_data import StoryData
from .postgres_client import PostgresClient
from .postgres_sharding import sharding_for

_KEY = Tuple[int, int]

class PostgresStoryStorage:

    def __init__(self, client: PostgresClient):
        self._client = client

    def get_content(self, feed_id: int, offset: int) -> str:
        r = self.batch_get_content([(feed_id, offset)])
        if not r:
            return None
        _, content = r[0]
        return content

    def delete_content(self, feed_id: int, offset: int) -> None:
        self.batch_delete_content([(feed_id, offset)])

    def save_content(self, feed_id: int, offset: int, content: str) -> None:
        self.batch_save_content([((feed_id, offset), content)])

    @classmethod
    def _split_by(cls, items: list, by: callable) -> dict:
        groups = defaultdict(list)
        for item in items:
            groups[by(item)].append(item)
        return groups

    @classmethod
    def _split_keys(cls, keys: List[_KEY]) -> Dict[int, List[_KEY]]:
        return cls._split_by(keys, lambda x: sharding_for(x[0]))

    @classmethod
    def _split_items(cls, items: List[Tuple[_KEY, str]]) -> Dict[int, List[Tuple[_KEY, str]]]:
        return cls._split_by(items, lambda x: sharding_for(x[0][0]))

    @staticmethod
    def _to_id_tuple(keys: List[_KEY]) -> tuple:
        return tuple(StoryId.encode(feed_id, offset) for feed_id, offset in keys)

    def batch_get_content(self, keys: List[_KEY]) -> List[Tuple[_KEY, str]]:
        result = []
        if not keys:
            return result
        groups = self._split_keys(keys)
        for volume, group_keys in groups.items():
            result.extend(self._batch_get_content(volume, group_keys))
        return result

    def _batch_get_content(self, volume: int, keys: List[_KEY]) -> List[Tuple[_KEY, str]]:
        q = sql("""
        SELECT id, content FROM {table} WHERE id IN :id_tuple
        """.format(table=self._client.get_table(volume)))
        id_tuple = self._to_id_tuple(keys)
        with self._client.get_engine(volume).connect() as conn:
            rows = list(conn.execute(q, id_tuple=id_tuple).fetchall())
        result = []
        for story_id, content_data in rows:
            key = StoryId.decode(story_id)
            if content_data:
                content = StoryData.decode_text(content_data)
            else:
                content = None
            result.append((key, content))
        return result

    def batch_delete_content(self, keys: List[_KEY]) -> None:
        if not keys:
            return
        groups = self._split_keys(keys)
        for volume, group_keys in groups.items():
            self._batch_delete_content(volume, group_keys)

    def _batch_delete_content(self, volume: int, keys: List[_KEY]) -> None:
        q = sql("""
        DELETE FROM {table} WHERE id IN :id_tuple
        """.format(table=self._client.get_table(volume)))
        id_tuple = self._to_id_tuple(keys)
        with self._client.get_engine(volume).connect() as conn:
            with conn.begin():
                conn.execute(q, id_tuple=id_tuple)

    def batch_save_content(self, items: List[Tuple[_KEY, str]]) -> None:
        if not items:
            return
        groups = self._split_items(items)
        for volume, group_items in groups.items():
            self._batch_save_content(volume, group_items)

    def _batch_save_content(self, volume: int, items: List[Tuple[_KEY, str]]) -> None:
        q = sql("""
        INSERT INTO {table} (id, content) VALUES (:id, :content)
        ON CONFLICT (id) DO UPDATE SET content = EXCLUDED.content
        """.format(table=self._client.get_table(volume)))
        params = []
        for (feed_id, offset), content in items:
            story_id = StoryId.encode(feed_id, offset)
            if content:
                content_data = StoryData.encode_text(content)
            else:
                content_data = b''
            params.append({'id': story_id, 'content': content_data})
        with self._client.get_engine(volume).connect() as conn:
            with conn.begin():
                conn.execute(q, params)


import random
import discord
from discord.ext import commands

import datetime, traceback, asyncio

from services import PerkService, SurvivorService, KillerService

import formatter as formatter
from formatter import perk_imager as pi
from PIL import Image
from io import BytesIO
import requests
import os

# OpenCV
import cv2
import numpy as np
import matplotlib.pyplot as plt

class PerksCog(commands.Cog):

    def __init__(self, bot: commands.Bot):
        """

        """
        self.bot = bot
        self.perkService = PerkService()
        self.survivorService = SurvivorService()
        self.killerService = KillerService()

    def __randomCombo(self, ctx, isSurv : int, isKiller : int, number : input):

        return self.perkService.random_combo(isSurv, isKiller, number)

    def __getRandBoonPerk(self, isSurv : int, isKiller : int):

            # access the method to get a random perk
            # Params: True True bc we want to get a random perk from the survivors and killers
            perk, owner = self.perkService.randomBoon_perk(isSurv, isKiller)
            # print(perk)
            # print(owner)

            perk_name = perk[0]
            perk_description = perk[1]
            perk_image = perk[2]
            # Owner: another query

            # We return the name, description and image of the perk
            return perk_name, perk_description, perk_image, owner

    def __getRandHexPerk(self, isSurv : int, isKiller : int):

            # access the method to get a random perk
            # Params: True True bc we want to get a random perk from the survivors and killers
            perk, owner = self.perkService.randomHex_perk(isSurv, isKiller)
            # print(perk)
            # print(owner)

            perk_name = perk[0]
            perk_description = perk[1]
            perk_image = perk[2]
            # Owner: another query

            # We return the name, description and image of the perk
            return perk_name, perk_description, perk_image, owner

    def __getRandPerk(self, isSurv : int, isKiller : int):

        # access the method to get a random perk
        # Params: True True bc we want to get a random perk from the survivors and killers
        perk, owner = self.perkService.random_perk(isSurv, isKiller)
        # print(perk)
        # print(owner)

        perk_name = perk[0]
        perk_description = perk[1]
        perk_image = perk[2]
        # Owner: another query

        # We return the name, description and image of the perk
        return perk_name, perk_description, perk_image, owner

    # ---> comando: !dbd perk <perkName>
    def __getPerkInfo(self, perkName):

        # Future update: Can be easily put the same function as the random perk with a flag and dont repeat code :)
        perk, owner = self.perkService.perk_info(perkName)

        if perk == None:
            return None, None, None, None

        perk_name = perk[0]
        perk_description = perk[1]
        perk_image = perk[2]

        return perk_name, perk_description, perk_image, owner

    def __getPerksOf(self,survivorName=None, killerName=None):

        if survivorName != None:
            perks = self.survivorService.get_survivor_perks(survivorName)
        elif killerName != None:
            perks = self.killerService.get_killer_perks(killerName)
        else:
            return None

        return perks

    async def __randomBoon_perk(self, ctx, isSurv : int, isKiller : int):
        # Just inline the image of the perk and the name of the perk in the same line
        perk_name, perk_image, _, _ = self.__getRandBoonPerk(isSurv, isKiller)

        # Show an embed with the name of the perk and the image
        embed = discord.Embed(
            color=0xff0000,
            timestamp=datetime.datetime.now(datetime.timezone.utc))

        # Title of the embed bold and centered
        embed.add_field(name="Perk:",
                        value=f"**{perk_name}**",
                        inline=False)

        embed.set_image(url=perk_image)

        # We will send the embed
        await ctx.send(embed=embed)

    async def __randomHex_perk(self, ctx, isSurv : int, isKiller : int):
        # Just inline the image of the perk and the name of the perk in the same line
        perk_name, perk_image, _, _ = self.__getRandHexPerk(isSurv, isKiller)

        # Show an embed with the name of the perk and the image
        embed = discord.Embed(
            color=0xff0000,
            timestamp=datetime.datetime.now(datetime.timezone.utc))

        # Title of the embed bold and centered
        embed.add_field(name="Perk:",
                        value=f"**{perk_name}**",
                        inline=False)

        embed.set_image(url=perk_image)

        # We will send the embed
        await ctx.send(embed=embed)

    async def __random_perk(self, ctx, isSurv : int, isKiller : int):
        # Just inline the image of the perk and the name of the perk in the same line
        perk_name, perk_image, _, _ = self.__getRandPerk(isSurv, isKiller)

        # Show an embed with the name of the perk and the image
        embed = discord.Embed(
            color=0xff0000,
            timestamp=datetime.datetime.now(datetime.timezone.utc))

        # Title of the embed bold and centered
        embed.add_field(name="Perk:",
                        value=f"**{perk_name}**",
                        inline=False)

        embed.set_image(url=perk_image)

        # We will send the embed
        await ctx.send(embed=embed)

    async def __perks_group(self, ctx, perkN):
        """
        Simple random perk, or detailed perk given an argument.
        """
        try:
            if perkN is None:
                await self.__random_perk(ctx, 1, 1)

            else:
                # Detailed perk, name is arg1

                # We will call the function to get the perk
                perk_name, perk_image, perk_description, owner = self.__getPerkInfo(perkN)

                if perk_name == None:
                    # Send an image with the perk not found
                    embed = discord.Embed(
                        # Perk _<perkName>_ not found
                        title=f"Perk _{perkN}_ not found",
                        description="Check the name of the perk and try again, or check if it's a Hex. In that case use hex: first.",
                        color=0xff0000,
                        timestamp=datetime.datetime.now(datetime.timezone.utc))

                    embed.set_thumbnail(url="https://static.wikia.nocookie.net/deadbydaylight_gamepedia_en/images/5/56/Atl_Loadout_Icon_Cruelty.png/revision/latest?cb=20210604022641")

                    embed.set_footer(
                        text="Use !dbd perks for more info",

                    )
                    # We will send the embed
                    await ctx.send(embed=embed)

                    return

                if owner == None:
                    owner = ("No pertenece a nadie (:",
                            "https://i.imgur.com/Od372kM_d.webp?maxwidth=760&fidelity=grand")

                # We will create the embed
                # timestamp utc + 2
                embed = discord.Embed(
                    title=perk_name,
                    description=perk_description,
                    color=0x00fff0,
                    timestamp=datetime.datetime.now(datetime.timezone.utc))

                # embed.set_footer(
                #     text=f"Owner: {owner[0]}",
                #     icon_url=owner[-1],
                # )
                # Try author instead of footer
                embed.set_author(
                    name=f"Owner: {owner[0]}",
                    icon_url=owner[-1],
                )

                embed.set_thumbnail(url=perk_image)

                # We will send the embed
                await ctx.send(embed=embed)

        except Exception as e:
            await ctx.send(f'```{traceback.format_exception(e)}```')

    async def __perks_survivor(self, ctx):
        try:
            await self.__random_perk(ctx, 1, 0)
        except Exception as e:
            await ctx.send(f'```{traceback.format_exception(e)}```')

    async def __perks_killer(self, ctx):
        try:
            await self.__random_perk(ctx, 0, 1)
        except Exception as e:
            await ctx.send(f'```{traceback.format_exception(e)}```')

    async def __perks_of(self, ctx, ownerName : str):
        try:

            # Check if is a killer or a survivor
            isSurv = self.survivorService.checkName(ownerName.lower())

            fullInfo = None

            if isSurv:
                fullInfo = self.survivorService.get_survivor(ownerName, True)
                # Get the perks of the survivor
                perks = self.__getPerksOf(ownerName,None)

            else:
                fullInfo = self.killerService.get_killer(ownerName, True)

                if fullInfo is None:
                    # error
                    err_embed = discord.Embed(
                        color=0xf0f000,
                        timestamp=datetime.datetime.now(datetime.timezone.utc),
                        title="Whoops!",
                        description="Can't find the survivor/killer. Are you sure you spelled it right?")

                    err_embed.set_thumbnail(url="https://static.wikia.nocookie.net/deadbydaylight_gamepedia_en/images/9/9e/IconStatusEffects_exposed.png/revision/latest?cb=20170620155518")

                    await ctx.send(embed=err_embed)

                    return
                else:
                    # Get the perks of the killer
                    perks = self.__getPerksOf(None,fullInfo[0])

            # Parse the perks
            # Its an array of tuples
            # Format the tuple to a string
            perk_names = [f"{perk[0]}" for perk in perks]

            image_index = 0

            title_vars = perk_names.copy()
            title_vars[image_index] = f"**{title_vars[image_index]}**"

            # Join with a comma
            names = ", ".join(title_vars)

            # Show an embed with the name of the survivor and the image
            embed = discord.Embed(
                color=0xff0000,
                timestamp=datetime.datetime.now(datetime.timezone.utc),
                description=names)

            # Title of the embed bold and centered

            # # Add the images
            # # Get the images
            images = [perk[-1] for perk in perks]

            total_images = len(images)
            current_image = images[image_index]
            embed.set_image(url=current_image)
            embed.set_footer(text=f'Perk: {perk_names[image_index]}')
            embed.set_author(
                name=f"Perks of {fullInfo[0]}",
                icon_url=fullInfo[-1]
            )

            msg = await ctx.send(embed=embed)
            await msg.add_reaction('⬅')
            await msg.add_reaction('➡')

            def check(reaction, user):
                return user == ctx.author and str(reaction.emoji) in ['⬅', '➡']

            while True:
                try:
                    reaction, user = await self.bot.wait_for('reaction_add', timeout=60.0, check=check)

                    if str(reaction.emoji) == '⬅':
                        image_index -= 1
                        if image_index < 0:
                            image_index = total_images - 1
                    elif str(reaction.emoji) == '➡':
                        image_index += 1
                        if image_index >= total_images:
                            image_index = 0

                    title_vars = perk_names.copy()
                    title_vars[image_index] = f"**{title_vars[image_index]}**"
                    names = ", ".join(title_vars)

                    embed = discord.Embed(
                        color=0xff0000,
                        timestamp=datetime.datetime.now(datetime.timezone.utc),
                        description=names)
                    embed.set_footer(text=f'Perk: {perk_names[image_index]}')
                    embed.set_author(
                        name=f"Perks of {fullInfo[0]}",
                        icon_url=fullInfo[-1]
                    )
                    current_image = images[image_index]
                    embed.set_image(url=current_image)

                    await msg.edit(embed=embed)
                    await msg.remove_reaction(reaction, user)
                except asyncio.TimeoutError:
                    break

        except Exception as e:
            await ctx.send(f'```{traceback.format_exception(e)}```')

    async def __perks_hex(self, ctx, perkN):
        # Just add the hex to the perkN
        if perkN is None:
            # print("No perkN")
            await self.__randomHex_perk(ctx, 0, 1)
        else:
            perkN = f"Hex: {perkN.lower()}"
            # Call perk group
            await self.__perks_group(ctx, perkN)

    async def __perks_boon(self, ctx, perkN):
        # Just add the hex to the perkN
        if perkN is None:
            # print("No perkN")
            await self.__randomBoon_perk(ctx, 1,0)
        else:
            perkN = f"Boon: {perkN.lower()}"
            # Call perk group
            await self.__perks_group(ctx, perkN)

    async def __perkCombo_group(self,ctx, character, number):

        # Loading embed
        loading_embed = discord.Embed(
            color=0xf0f000,
            timestamp=datetime.datetime.now(datetime.timezone.utc),
            title="Loading...",
            description="Wait fellas!, Your perk combo is baking ʕ••ʔ")

        msg = await ctx.send(embed=loading_embed)

        if character is not None:
            character = character.lower()

        # If the character is killer
        if character is None:
            # Just a randomCombo
            randInteger = random.randint(0,1)
            if randInteger == 0:
                perks = self.__randomCombo(ctx,0,1, number)
                character = "killer"
            else:
                perks = self.__randomCombo(ctx,1,0, number)
                character = "survivor"

        if character == "killer":
            perks = self.__randomCombo(ctx,0,1, number)
        elif character == "survivor":
            perks = self.__randomCombo(ctx,1,0, number)
        # else:
        #     embed = discord.Embed(
        #         color=0xf0f000,
        #         timestamp=datetime.datetime.now(datetime.timezone.utc),
        #         title="Whoops!",
        #         description="Invalid command. Just !dbd perkcombo killer/survivor")

        #     embed.set_thumbnail(url="https://static.wikia.nocookie.net/deadbydaylight_gamepedia_en/images/f/f0/IconHelp_exitGates.png/revision/latest?cb=20170907140953")

        #     await ctx.send(embed=embed)

        # Parse the perks
        # Make an embed

        # print("PERKS: ", perks)

        ps = [f"{perk[0]}" for perk in perks]
        # Get the first 4
        ps = ps[:4]

        # Join with comma the first 4
        names = ", ".join(ps)

        embed = discord.Embed(
            title=f"Your perk combo is ready!",
            color=0xf0f000,
            timestamp=datetime.datetime.now(datetime.timezone.utc),
            description=names)

        embed.set_footer(text="Perk Combo")
        # print("PERKS: ", perks)

        perksImages = [perk[1] for perk in perks]

        if len(perksImages) < 4:
            while(len(perksImages) < 4):
                perksImages.append(None)

        # Print formatted string
        # print("PERKS IMAGES: ", perksImages)

        image_perk = []
        for perk in perksImages:
            if perk is not None:
                image_perk.append(Image.open(BytesIO(requests.get(perk).content)))
            else:
                image_perk.append(None)

        if character == "killer":
            embed.set_thumbnail(url="https://static.wikia.nocookie.net/deadbydaylight_gamepedia_en/images/0/06/IconHelpLoading_killer.png/revision/latest?cb=20220324212743")
        elif character == "survivor":
            embed.set_thumbnail(url="https://static.wikia.nocookie.net/deadbydaylight_gamepedia_en/images/b/b3/IconHelpLoading_survivor.png/revision/latest?cb=20220324212914")

        # Create a perk display object
        # 4 arguments passed as
        pdisp = pi.perk_display(
            up=image_perk[0],
            left=image_perk[1],
            right=image_perk[2],
            down=image_perk[3],
            size=(512, 512)
        )

        bytes_img = BytesIO()
        pdisp.save(bytes_img, format="PNG")
        bytes_img.seek(0)
        dfile = discord.File(bytes_img, filename="image.png")

        embed.set_image(url="attachment://image.png")

        # Delete the loading message
        await msg.delete()

        # Substitution for the message
        await ctx.send(embed=embed, file=dfile)

    @commands.group(description="Command group for Perks", invoke_without_command=True, pass_context=True)
    async def perks(self, ctx, *, arg1 = None):
        await self.__perks_group(ctx, arg1)

    @perks.command(description="Subcommand for getting random survivor perk")
    async def survivor(self, ctx):
        await self.__perks_survivor(ctx)

    @perks.command(description="Subcommand for getting random killer perk")
    async def killer(self, ctx):
        await self.__perks_killer(ctx)

    @perks.command(name="of", description="Subcommand for getting random killer perk")
    async def perks_of(self, ctx, *, arg1):
        await self.__perks_of(ctx, arg1)

    @perks.command(name="hex", description="(QoL)Subcommand for getting random hex perk or a specific one")
    async def perks_hex(self, ctx, *, arg1 = None):
        await self.__perks_hex(ctx, arg1)

    @perks.command(name="boon", description="(QoL)Subcommand for getting random boon perk or a specific one")
    async def perks_boon(self, ctx, *, arg1 = None):
        await self.__perks_boon(ctx, arg1)

    # New group for getting a list of perks
    @commands.group(description="Command group for Perks", invoke_without_command=True, pass_context=True)
    async def perkcombo(self, ctx, arg1 = None, arg2 = None):
        # arg1 could be survivor or killer
        if arg1 is None:
            await self.__perkCombo_group(ctx, character=None, number=4)
        elif arg1.isnumeric():
            await self.__perkCombo_group(ctx, character=None, number=int(arg1))
        else:
            if arg2 is None:
                await self.__perkCombo_group(ctx, character=arg1, number=4)
            elif arg2.isnumeric():
                await self.__perkCombo_group(ctx, character=arg1, number=int(arg2))
            else:
                await ctx.send("Invalid command. Just !dbd perkcombo killer/survivor <number>")

    # Same, survivor,killer ...

    # @perks.command(name="list", description="Subcommand for getting a list of perks")

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


import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
import pandas as pd
from datetime import datetime
import numpy as np

def create_multi_df(ddf,country_val,measure,dayfilter=True):
    dftotal = None

    for country in country_val:
        dfc = ddf[country]
        if dayfilter:
            dfc = dfc[last28days:]

        dfc = dfc[[measure]]
        dfc.columns = [measure+"_"+country]

        if dftotal is None:
            dftotal = dfc
        else:
            dftotal = dftotal.join(dfc,how="outer",rsuffix="_"+country)

    return dftotal

def generate_data(df,countries,measure,kind="bar"):
    return [ dict(x = df.index, y= [xx for xx in df[measure+"_"+c].values.tolist()], type=kind,name=c) for c in countries]

todaydate = datetime.today().strftime('%Y-%m-%d')
last14days = pd.to_datetime(todaydate, format="%Y-%m-%d") - pd.DateOffset(days=14)
last28days = pd.to_datetime(todaydate, format="%Y-%m-%d") - pd.DateOffset(days=28)

colors = {
    'background': '#111111',
    'text': '#7FDBFF'
}

df1 = pd.read_csv("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv")

dfus = pd.read_csv("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_US.csv")

d = df1.drop(["Province/State","Lat","Long"],axis=1)

dworld = d.copy()
dworld = dworld.drop(["Country/Region"],axis=1).sum()
dworld = pd.DataFrame(dworld)
dworld.columns = [ "World" ]
dworld.index = pd.to_datetime(dworld.index)

d = d.groupby(["Country/Region"]).sum().T.reset_index()
d = d.set_index(pd.to_datetime(d["index"]))
d = d.drop(["index"],axis=1)

dfus = dfus.drop(["UID","iso2","iso3","code3","FIPS","Admin2","Lat","Long_","Combined_Key"],axis=1)
dfus = dfus.groupby(["Country_Region"]).sum().T.reset_index()
dfus = dfus.set_index(pd.to_datetime(dfus["index"]))
dfus = dfus.drop(["index"],axis=1)

#d = d.join(dfus,how="outer")

dd = {}

for country in d.columns:
    c2 = "United States" if country == "US" else country
    dd[c2] = pd.DataFrame(d[country])
    dd[c2].columns = ["Infections"]

dd["World"] = dworld
dd["World"].columns = ["Infections"]

df1 = pd.read_csv("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_deaths_global.csv")

dfus = pd.read_csv("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_deaths_US.csv")

d = df1.drop(["Province/State","Lat","Long"],axis=1)

dworld = d.copy()
dworld = dworld.drop(["Country/Region"],axis=1).sum()
dworld = pd.DataFrame(dworld)
dworld.columns = [ "World" ]
dworld.index = pd.to_datetime(dworld.index)

d = d.groupby(["Country/Region"]).sum().T.reset_index()
d = d.set_index(pd.to_datetime(d["index"]))
d = d.drop(["index"],axis=1)

#dfus = dfus.drop(["UID","iso2","iso3","code3","FIPS","Admin2","Lat","Long_","Combined_Key","Population","Province/State"],axis=1)
#dfus = dfus.groupby(["Country/Region"]).sum().T.reset_index()
#dfus = dfus.set_index(pd.to_datetime(dfus["index"]))
#dfus = dfus.drop(["index"],axis=1)

#d = d.join(dfus,how="outer")

for c in d.columns:
    #current data frame = dataframe[country]
    cdf = pd.DataFrame(d[c])
    cdf.columns = ["Deaths"]
    c2 = "United States" if c == "US" else c
    dd[c2] = dd[c2].join(cdf,how="outer")

dworld.columns = ["Deaths"]
dd["World"] = dd["World"].join(dworld,how="outer")

df1 =  pd.read_csv("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_recovered_global.csv")

d = df1.drop(["Province/State","Lat","Long"],axis=1)

dworld = d.copy()
dworld = dworld.drop(["Country/Region"],axis=1).sum()
dworld = pd.DataFrame(dworld)
dworld.columns = [ "World" ]
dworld.index = pd.to_datetime(dworld.index)

d = d.groupby(["Country/Region"]).sum().T.reset_index()
d = d.set_index(pd.to_datetime(d["index"]))
d = d.drop(["index"],axis=1)

for c in d.columns:
    #current data frame = dataframe[country]
    cdf = pd.DataFrame(d[c])
    cdf.columns = ["Recovery"]
    c2 = "United States" if c == "US" else c
    dd[c2] = dd[c2].join(cdf,how="outer")

dworld.columns = ["Recovery"]
dd["World"] = dd["World"].join(dworld,how="outer")

for key in dd:
    cdf = dd[key]
    cdf["Infections diff abs"] = cdf["Infections"].diff()
    cdf["Infections diff %"] = cdf["Infections"].pct_change()*100
    cdf["Infections diff %"] = cdf["Infections diff %"].round(2)

    cdf["Deaths diff abs"] = cdf["Deaths"].diff()
    cdf["Deaths diff %"] = cdf["Deaths"].pct_change()*100
    cdf["Deaths diff %"] = cdf["Deaths diff %"].round(2)

    cdf["Current Infections"] = cdf["Infections"] - cdf["Recovery"]

    cdf["Current Infections diff abs"] = cdf["Current Infections"].diff()
    cdf["Current Infections diff %"] = cdf["Current Infections"].pct_change()*100
    cdf["Current Infections diff %"] = cdf["Current Infections diff %"].round(2)

    cdf = cdf[["Infections","Infections diff abs","Infections diff %","Deaths","Deaths diff abs","Deaths diff %","Recovery","Current Infections","Current Infections diff abs","Current Infections diff %"]]

    dd[key] = cdf

#external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
external_stylesheets=[dbc.themes.BOOTSTRAP]

def style_callback(colname):
    if colname == "index":
        return { 'border-right':'2px solid black','width':'9%' }
    elif "Recovery" in colname or "%" in colname:
        return { 'border-right':'2px solid black' }

def generate_table(dataframe, max_rows=10000):
    dataframe = dataframe.sort_index(ascending=False)
    dataframe = dataframe.reset_index()
    dataframe["index"] = dataframe["index"].astype(str).str[:10]

    return html.Table([
        html.Thead(
            html.Tr([html.Th(col,style= style_callback(col) ) for col in dataframe.columns])
        ),
        html.Tbody([
            html.Tr([
                html.Td(dataframe.iloc[i][col], style= {'border-right':'2px solid black'} if "%" in col or "Recovery" in col or "index" in col else {}) for col in dataframe.columns
            ]) for i in range(min(len(dataframe), max_rows))
        ])
    ],className='table')

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
server = app.server
app.title = "COVID 19 Custom Dashboard"

tabs_styles = {
    'height': '44px'
}
tab_style = {
    'borderBottom': '1px solid #d6d6d6',
    'padding': '6px',
    'fontWeight': 'bold'
}

tab_selected_style = {
    'borderTop': '1px solid #d6d6d6',
    'borderBottom': '1px solid #d6d6d6',
    'backgroundColor': '#119DFF',
    'color': 'white',
    'padding': '6px'
}

app.layout = html.Div(className='container',children=[

    html.H2(children='COVID19 - Custom Dashboard'),

    #html.Div(children='''
    #    Dash: A web application framework for Python!
    #'''),

    html.Div([
        html.Span('Choose Country',style={'font-weight':'bold'}),
        dcc.Dropdown(
            id='drop-countries',
            options=[{'label':i, 'value': i} for i in dd.keys()],
            value="World",
            multi=True,
        ),
    ],style={'width': '20%', 'margin': 'auto','margin-bottom':'20px'}),

    html.Div([
        html.Span('Measures',style={'font-weight':'bold'}),
        dcc.Dropdown(
            id='val-slider',
            options=[{'label':i, 'value': i} for i in ['Infections','Deaths', 'Recovery', 'Current Infections']],
            value="Infections",
            style={'margin-bottom':'20px'},
        ),
        html.Span('Y-Axis Scale',style={'font-weight':'bold'}),
        dcc.RadioItems(
            id='yaxis-type',
            options=[{'label': i, 'value': i} for i in ['Linear', 'Log']],
            value='Linear',
            labelStyle={'display': 'block'}
        ),

    ],style={'width': '20%', 'display': 'inline-block'}),
    #],style={'width': '20%'}),

    html.Div([
        dcc.Graph(id='timeseries'),
    #],style={'width': '60%','margin':'auto'}),
    ],className="container"),

    html.Div([
        html.Span('Scale',style={'font-weight':'bold'}),
        dcc.RadioItems(
            id='diffscale',
            options=[{'label': i, 'value': i} for i in ['absolute', 'percentage']],
            value='absolute',
            labelStyle={'display': 'block'}
        )
    #],style={'width': '48%', 'display': 'inline-block'}),
    ],className="container",style={'width':'20%'}),

    html.Div([
        dcc.Graph(id='diffdata'),
    ],className="container"),

    html.Div(dcc.Tabs(id="tabs", value='tab-1'
        ,style = tabs_styles
    ),id='tabelle',className='table-responsive'),

    html.Div([
        html.A("Data Source: https://github.com/CSSEGISandData/COVID-19",href="https://github.com/CSSEGISandData/COVID-19")
    ],className="container",style={ 'margin-bottom':'20px'}),

],style={'margin': 'auto','text-align':'center'})

@app.callback(
    Output('timeseries','figure'),
    [Input('val-slider','value'),
     Input('yaxis-type','value'),
     Input('drop-countries','value')])
def update_figure(selected_value, yaxis_type, country_val):

    if not isinstance(country_val, list):
        country_val = [ country_val ]

    df_ger = create_multi_df(dd,country_val,selected_value,False)
    return {
        'data': generate_data(df_ger,country_val,selected_value,"scatter"),
        'layout': {
            #'plot_bgcolor': colors['background'],
            #'paper_bgcolor': colors['background'],
            #'font': {
            #    'color': colors['text']
            #},
            'yaxis': {
                'type': 'linear' if yaxis_type == 'Linear' else 'log',
                'tickformat':'>-,d',
                #'separators':', '
            },
            'title': {
                'text': 'Timeline '+selected_value+' of '+ (",".join(country_val)),
            },
            'hoverformat':'>-,d',
        }
    }

@app.callback(
    Output('diffdata','figure'),
    [Input('diffscale','value'),
     Input('drop-countries','value'),
     Input('val-slider','value')])
def update_diffs(vala,country_val,selected_value):

    measure = selected_value+" diff " + ("abs" if vala == "absolute" else "%")
    if selected_value == "Recovery":
        measure = "Infections diff " + ("abs" if vala == "absolute" else "%")

    if not isinstance(country_val, list):
        country_val = [ country_val ]

    dftotal = create_multi_df(dd,country_val,measure)

    df_ger = dftotal
    df2 = df_ger
    df2 = df2[last28days:]

    return {
        'data': generate_data(df2, country_val, measure),
        #'data': [
        #    { 'x': df2.index, 'y': [x[0] for x in df2.values.tolist()], 'type':'bar','name':'pad'},
        #],
        'layout': {
            'title': {
                'text': selected_value+' difference to prior day in '+ (",".join(country_val)),
            },
            'yaxis': {
                'tickformat':'>-,d' if vala=="absolute" else '>-,2f',
            }
        }
    }

#@app.callback(
#    Output('tabelle','children'),
#    [Input('drop-countries','value')])
#def update_table(country_val):
#
#    if not isinstance(country_val,list):
#        country_val = [ country_val ]
#
#
#    df_ger = dd[country_val[0]]
#    return generate_table(df_ger[last14days:]),

@app.callback(
    Output('tabs','children'),
    [Input('drop-countries','value')])
def update_tabs(country_val):

    if not isinstance(country_val,list):
        country_val = [ country_val ]

    return [ dcc.Tab(label=c,children=generate_table(dd[c][last14days:]), style=tab_style, selected_style=tab_selected_style) for c in country_val ]

if __name__ == '__main__':
    app.run_server(debug=True)


from multiprocessing import Process,Pipe
import os,time

#创建管道
fd1,fd2 = Pipe(False)

def fun(name):
    time.sleep(3)
    #向管道写入内容
    fd2.send("hello" + str(name))

jobs = []
for i in range(5):
    p = Process(target = fun,args = (i,))
    jobs.append(p)
    p.start()

while True:
    #从管道读取内容
    data = fd1.recv()
    print(data)

for i in jobs:
    i.join()