__author__ = 'Wojto'
import socket
import random
import pymysql
from settings import *
import re
#settings located in settings file

if debug == True:
    channel = '#sram'
    host = "irc.freenode.net"
else:
    channel = '#kx'
    host = "irc.quakenet.org"

#guwner
random.seed()
podmiot = open('podmiot.txt', 'r')
okolicznik = open('okolicznik.txt', 'r')
orzeczenie = open('orzeczenie.txt', 'r')
dopelnienie = open('dopelnienie.txt', 'r')
przydawka = open('przydawka.txt', 'r')
def cytat(): #fetching quote from db
    connection = pymysql.connect(**connection_settings)
    kursor = connection.cursor()
    kursor.execute('SELECT * FROM Quote ORDER BY RAND() LIMIT 1')
    for row in kursor.fetchall():
                 print("PRIVMSG " + channel + " : " + "Quote nr:" + str(row[0]) + "  " + str(row[1]), file=soclog)
    kursor.close()
    connection.close()
def dodaj(): #adding quote to db
    connection = pymysql.connect(**connection_settings)
    kursor = connection.cursor()
    qwithline = 'INSERT INTO Quote (Quote) VALUES ("%s")' % quotemsg
    kursor.execute(qwithline)
    kursor.close()
    connection.close()
    print (qwithline)
def zguwnij():
    linep = random.choice(open('podmiot.txt').readlines())
    lineok = random.choice(open('okolicznik.txt').readlines())
    lineorz = random.choice(open('orzeczenie.txt').readlines())
    linedop = random.choice(open('dopelnienie.txt').readlines())
    lineprz = random.choice(open('przydawka.txt').readlines())

    zz1 = linep.rstrip()
    zz5 = lineok.rstrip()
    zz2 = lineorz.rstrip()
    zz3 = lineprz.rstrip()
    zz4 = linedop.rstrip()
    #print("PRIVMSG " + channel + " : " + zz1 + " " + zz2 + " " + zz3  + " " + zz4  + " " + zz5, file=soclog)
    msg = 'PRIVMSG {} : {}'.format(channel, ' '.join([zz1, zz2, zz3, zz4, zz5]))
    print(msg, file=soclog)
#Connect
soc = socket.socket()
soc.connect((host, port))

print ("Connecting to %s" % (host))

soclog = soc.makefile(mode='rw', buffering=1, encoding='utf-8', newline='\r\n')
def logIn(): #log in function
    print("NICK", bnick, file=soclog)
    print("USER", bnick, bnick, bnick, ':'+bnick, file=soclog)
logIn() #calling the log in function
FirstPing = False

for line in soclog:
    line = line.strip()
    print(line)
    if 'PRIVMSG' in line:
        msg = ":".join(line.split (':')[2:])
        nick = line.split('!')[ 0 ].replace(':','')
    if 'PING' in line:
        print("PONG :" + line.split(":")[1], file=soclog)
        if not FirstPing:
            print("JOIN :" +channel, file=soclog)
            FirstPing = True;
    if 'zguwnij' in line:
        zguwnij()
    if 'join' in line:
        print("JOIN :" + channel, file=soclog)
    if '!cyt' in line:
        cytat()
    if '!test' in line:
        quotemsg = msg.replace("!test ","",1)
        dodaj()


# https://leetcode.com/problems/shuffle-an-array/
import random
from typing import List

# One solution: Knuth shuffle https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
# The solution presented in leetcode: https://leetcode.com/problems/shuffle-an-array/discuss/86006/simple-java-solution
# Workaround solution: Python hack using lambda functions
class Solution:
    def __init__(self, nums: List[int]):
        self.reset = lambda: nums
        self.shuffle = lambda: random.sample(nums, len(nums))

    def reset(self) -> List[int]:
        """
        Resets the array to its original configuration and return it.
        """
        return self.reset()

    def shuffle(self) -> List[int]:
        """
        Returns a random shuffling of the array.
        """
        return self.shuffle()

# Your Solution object will be instantiated and called as such:
# obj = Solution(nums)
# param_1 = obj.reset()
# param_2 = obj.shuffle()
if __name__ == "__main__":
    sol = Solution([1, 2, 3])
    print(sol.reset())
    print(sol.shuffle())
    print(sol.shuffle())
    print(sol.reset())


__author__ = 'Const'

import numpy as np

from scipy.linalg import lu

# An alternative to MATLAB '/' matrix operation
def rmatdiv(B, A):
    assert A.shape[1] == B.shape[1]
    z = np.linalg.lstsq(A.T, B.T)[0].T
    return z

def maxvol(A, max_iters=100, eps=5e-2):
    n, r = A.shape
    if n <= r:
        return np.array(xrange(n))

    perm, _, _ = lu(A)
    permutation_vector = perm.T.nonzero()[1].copy()
    ind = permutation_vector[:r]
    B = A[permutation_vector, :]
    submatrix = A[ind, :]
    z = rmatdiv(B[r:, :], submatrix)

    iter = 0
    while iter <= max_iters:
        max_indices = np.argmax(abs(z), axis=1)
        max_values = abs(z)[range(z.shape[0]), max_indices]
        max_arg = np.argmax(max_values)
        max_val = max_values[max_arg]
        if max_val <= 1 + eps:
            ind = np.sort(ind)
            return ind
        i_row = max_arg
        j_row = max_indices[i_row]
        permutation_vector[i_row + r], permutation_vector[j_row] =  \
                permutation_vector[j_row], permutation_vector[i_row + r]
        bb = z[:, j_row]
        bb[i_row] += 1
        cc = z[i_row, :]
        cc[j_row] -= 1
        #print z.shape, bb.shape, cc.shape
        z -= np.outer(bb, cc) / z[i_row, j_row]
        iter += 1
        ind = permutation_vector[:r]
        ind = np.sort(ind)
    return ind


import logging
import os
import tempfile
import uuid
from base64 import b64decode, b64encode
from copy import deepcopy

import pytest

from edusign_webapp import run
from edusign_webapp.doc_store import DocStore
from edusign_webapp.document.metadata.redis_client import RedisMD
from edusign_webapp.document.metadata.sqlite import SqliteMD
from edusign_webapp.document.storage.local import LocalStorage
from edusign_webapp.tests.sample_pdfs import pdf_form_1, pdf_form_2, pdf_simple_1, pdf_simple_2

here = os.path.abspath(os.path.dirname(__file__))

config_dev = {
    'TESTING': True,
    'ENVIRONMENT': 'development',
    'SCOPE_WHITELIST': 'example.org',
    'USER_BLACKLIST': 'blacklisted@example.org',
    'USER_WHITELIST': 'whitelisted@example.org',
    'MAIL_BACKEND': 'dummy',
    'BABEL_DEFAULT_LOCALE': 'en',
    'DOC_LOCK_TIMEOUT': 300,
}

config_pro = {
    'TESTING': True,
    'ENVIRONMENT': 'production',
    'SCOPE_WHITELIST': 'example.org',
    'USER_BLACKLIST': 'blacklisted@example.org',
    'USER_WHITELIST': 'whitelisted@example.org',
    'MAIL_BACKEND': 'dummy',
    'BABEL_DEFAULT_LOCALE': 'en',
    'DOC_LOCK_TIMEOUT': 300,
}

_environ_base = {
    "HTTP_MD_ORGANIZATIONNAME": 'Test Org',
    "HTTP_EDUPERSONPRINCIPALNAME": 'dummy-eppn@example.org',
    "HTTP_DISPLAYNAME": b64encode('<Attribute>Tëster Kid</Attribute>'.encode("utf-8")),
    "HTTP_MAIL": b64encode(b'<Attribute>tester@example.org</Attribute>'),
    "HTTP_SHIB_IDENTITY_PROVIDER": 'https://idp',
    "HTTP_SHIB_AUTHENTICATION_METHOD": 'dummy',
    "HTTP_SHIB_AUTHNCONTEXT_CLASS": 'dummy',
}

_environ_base_2 = {
    "HTTP_MD_ORGANIZATIONNAME": 'Test Org',
    "HTTP_EDUPERSONPRINCIPALNAME": 'dummy-eppn-2@example.org',
    "HTTP_DISPLAYNAME": b64encode('<Attribute>Invited Kid</Attribute>'.encode("utf-8")),
    "HTTP_MAIL": b64encode(b'<Attribute>invited0@example.org</Attribute>'),
    "HTTP_SHIB_IDENTITY_PROVIDER": 'https://idp',
    "HTTP_SHIB_AUTHENTICATION_METHOD": 'dummy',
    "HTTP_SHIB_AUTHNCONTEXT_CLASS": 'dummy',
}

@pytest.fixture
def environ_base():
    yield _environ_base

@pytest.fixture
def environ_base_2():
    yield _environ_base_2

@pytest.fixture(params=[config_dev, config_pro])
def client(request):
    app = run.edusign_init_app('testing', request.param)
    app.config.update(request.param)
    app.api_client.api_base_url = 'https://dummy.edusign.api'

    with app.test_client() as client:
        client.environ_base.update(_environ_base)

        yield client

@pytest.fixture(params=[config_dev, config_pro])
def client_non_whitelisted(request):
    app = run.edusign_init_app('testing')
    app.config.update(request.param)
    app.api_client.api_base_url = 'https://dummy.edusign.api'

    with app.test_client() as client:
        environ = deepcopy(_environ_base)
        environ['HTTP_EDUPERSONPRINCIPALNAME'] = b'tester@example.com'
        client.environ_base.update(environ)

        yield client

def _get_test_app(config):
    tempdir = tempfile.TemporaryDirectory()
    db_path = os.path.join(tempdir.name, 'test.db')
    more_config = {'LOCAL_STORAGE_BASE_DIR': tempdir.name, 'SQLITE_MD_DB_PATH': db_path}
    more_config.update(config)
    app = run.edusign_init_app('testing', more_config)
    app.api_client.api_base_url = 'https://dummy.edusign.api'
    return tempdir, app

@pytest.fixture(params=[config_dev, config_pro])
def app(request):

    yield _get_test_app(request.param)

def _get_test_s3_app(config):
    more_config = {'STORAGE_CLASS_PATH': 'edusign_webapp.document.storage.s3.S3Storage', 'AWS_REGION_NAME': 'us-east-1'}
    more_config.update(config)
    app = run.edusign_init_app('testing', more_config)
    app.api_client.api_base_url = 'https://dummy.edusign.api'
    return app

@pytest.fixture(params=[config_dev, config_pro])
def s3_app(request):

    yield _get_test_s3_app(request.param)

@pytest.fixture
def local_storage():
    tempdir = tempfile.TemporaryDirectory()
    config = {'LOCAL_STORAGE_BASE_DIR': tempdir.name}
    config.update(config_dev)
    # return tempdir, since once it goes out of scope, it is removed
    yield tempdir, LocalStorage(config, logging.getLogger(__name__))

@pytest.fixture
def sqlite_md():
    tempdir = tempfile.TemporaryDirectory()
    db_path = os.path.join(tempdir.name, 'test.db')
    config = {'SQLITE_MD_DB_PATH': db_path}
    config.update(config_dev)
    app = run.edusign_init_app('testing', config)
    # return tempdir, since once it goes out of scope, it is removed
    yield tempdir, SqliteMD(app)

@pytest.fixture
def redis_md():
    tempdir = tempfile.TemporaryDirectory()
    db_path = os.path.join(tempdir.name, 'test.db')
    config = {'SQLITE_MD_DB_PATH': db_path}
    config.update(config_dev)
    app = run.edusign_init_app('testing', config)
    # return tempdir, since once it goes out of scope, it is removed
    yield tempdir, RedisMD(app)

@pytest.fixture
def doc_store_local_sqlite():
    tempdir = tempfile.TemporaryDirectory()
    db_path = os.path.join(tempdir.name, 'test.db')
    config = {
        'STORAGE_CLASS_PATH': 'edusign_webapp.document.storage.local.LocalStorage',
        'DOC_METADATA_CLASS_PATH': 'edusign_webapp.document.metadata.sqlite.SqliteMD',
        'LOCAL_STORAGE_BASE_DIR': tempdir.name,
        'SQLITE_MD_DB_PATH': db_path,
    }
    config.update(config_dev)
    app = run.edusign_init_app('testing', config)
    # return tempdir, since once it goes out of scope, it is removed
    yield tempdir, DocStore(app)

@pytest.fixture
def doc_store_local_redis():
    tempdir = tempfile.TemporaryDirectory()
    config = {
        'STORAGE_CLASS_PATH': 'edusign_webapp.document.storage.local.LocalStorage',
        'DOC_METADATA_CLASS_PATH': 'edusign_webapp.document.metadata.redis_client.RedisMD',
        'LOCAL_STORAGE_BASE_DIR': tempdir.name,
    }
    config.update(config_dev)
    app = run.edusign_init_app('testing', config)
    # return tempdir, since once it goes out of scope, it is removed
    yield tempdir, DocStore(app)

@pytest.fixture
def sample_pdf_data():
    yield pdf_simple_1

@pytest.fixture
def sample_binary_pdf_data():
    yield b64decode(pdf_simple_1.encode('utf8'))

@pytest.fixture
def sample_metadata_1():
    yield _sample_metadata_1

@pytest.fixture
def sample_new_doc_1():
    doc = {'blob': pdf_simple_1}
    doc.update(_sample_metadata_1)
    del doc['key']
    yield doc

@pytest.fixture
def sample_owned_doc_1():
    doc = {'blob': pdf_simple_1}
    doc.update(_sample_metadata_1)
    yield doc

@pytest.fixture
def sample_doc_1():
    doc = {'blob': pdf_simple_1}
    doc.update(_sample_metadata_1)
    yield doc

@pytest.fixture
def sample_pdf_data_2():
    yield pdf_simple_2

@pytest.fixture
def sample_metadata_2():
    yield _sample_metadata_2

@pytest.fixture
def sample_doc_2():
    doc = {'blob': pdf_simple_2}
    doc.update(_sample_metadata_2)
    yield doc

@pytest.fixture
def sample_invites_1():
    yield [{'name': 'invite0', 'email': 'invite0@example.org'}, {'name': 'invite1', 'email': 'invite1@example.org'}]

@pytest.fixture
def sample_invites_2():
    yield [{'name': 'invite0', 'email': 'invite0@example.org'}, {'name': 'invite2', 'email': 'invite2@example.org'}]

@pytest.fixture
def sample_owner_1():
    yield {'name': 'owner', 'email': 'owner@example.org', 'eppn': 'owner-eppn@example.org'}

@pytest.fixture
def sample_owner_2():
    yield {'name': 'owner2', 'email': 'owner2@example.org', 'eppn': 'owner2-eppn@example.org'}

_sample_metadata_1 = {'name': 'test1.pdf', 'size': 1500000, 'type': 'application/pdf', 'key': str(uuid.uuid4())}

_sample_metadata_2 = {'name': 'test2.pdf', 'size': 1500000, 'type': 'application/pdf', 'key': str(uuid.uuid4())}

_form_1_schema = [
    {'type': 'Text', 'value': '', 'label': 'First name', 'name': 'Given Name Text Box', 'choices': None},
    {'type': 'Text', 'value': '', 'label': 'Last name', 'name': 'Family Name Text Box', 'choices': None},
    {'type': 'Text', 'value': '', 'label': '', 'name': 'Address 1 Text Box', 'choices': None},
    {'type': 'Text', 'value': '', 'label': 'House and floor', 'name': 'House nr Text Box', 'choices': None},
    {'type': 'Text', 'value': '', 'label': '', 'name': 'Address 2 Text Box', 'choices': None},
    {'type': 'Text', 'value': '', 'label': '', 'name': 'Postcode Text Box', 'choices': None},
    {'type': 'Text', 'value': '', 'label': '', 'name': 'City Text Box', 'choices': None},
    {
        'type': 'ComboBox',
        'value': '',
        'label': 'Use selection or write country name',
        'name': 'Country Combo Box',
        'choices': [
            'Austria',
            'Belgium',
            'Britain',
            'Bulgaria',
            'Croatia',
            'Cyprus',
            'Czech-Republic',
            'Denmark',
            'Estonia',
            'Finland',
            'France',
            'Germany',
            'Greece',
            'Hungary',
            'Ireland',
            'Italy',
            'Latvia',
            'Lithuania',
            'Luxembourg',
            'Malta',
            'Netherlands',
            'Poland',
            'Portugal',
            'Romania',
            'Slovakia',
            'Slovenia',
            'Spain',
            'Sweden',
        ],
    },
    {
        'type': 'ComboBox',
        'value': 'Man',
        'label': 'Select from list',
        'name': 'Gender List Box',
        'choices': ['Man', 'Woman'],
    },
    {
        'type': 'Text',
        'value': '150',
        'label': 'Value from 40 to 250 cm',
        'name': 'Height Formatted Field',
        'choices': None,
    },
    {
        'type': 'CheckBox',
        'value': 'Off',
        'label': 'Car driving license',
        'name': 'Driving License Check Box',
        'choices': None,
    },
    {'type': 'CheckBox', 'value': 'Off', 'label': '', 'name': 'Language 1 Check Box', 'choices': None},
    {'type': 'CheckBox', 'value': 'Yes', 'label': '', 'name': 'Language 2 Check Box', 'choices': None},
    {'type': 'CheckBox', 'value': 'Off', 'label': '', 'name': 'Language 3 Check Box', 'choices': None},
    {'type': 'CheckBox', 'value': 'Off', 'label': '', 'name': 'Language 4 Check Box', 'choices': None},
    {'type': 'CheckBox', 'value': 'Off', 'label': '', 'name': 'Language 5 Check Box', 'choices': None},
    {
        'type': 'ComboBox',
        'value': 'Red',
        'label': 'Select from colour spectrum',
        'name': 'Favourite Colour List Box',
        'choices': ['Black', 'Brown', 'Red', 'Orange', 'Yellow', 'Green', 'Blue', 'Violet', 'Grey', 'White'],
    },
]

_form_2_schema = [
    {'type': 'Text', 'value': '', 'label': 'Name', 'name': 'Name', 'choices': None},
    {'type': 'Text', 'value': '', 'label': 'Surname', 'name': 'Surname', 'choices': None},
    {'type': 'Text', 'value': '', 'label': 'e-Mail Address (required)', 'name': 'email', 'choices': None},
    {'type': 'Text', 'value': '', 'label': 'Phone Number', 'name': 'phone', 'choices': None},
    {'type': 'Text', 'value': '', 'label': 'Mobile Number', 'name': 'Mobile', 'choices': None},
    {'type': 'Text', 'value': '', 'label': 'Street', 'name': 'Street', 'choices': None},
    {'type': 'Text', 'value': '', 'label': 'House Name', 'name': 'House', 'choices': None},
    {'type': 'Text', 'value': '', 'label': 'Town Name', 'name': 'Town', 'choices': None},
    {'type': 'Text', 'value': '', 'label': 'Postcode', 'name': 'Postcode', 'choices': None},
    {'type': 'Text', 'value': '', 'label': 'Country', 'name': 'Country', 'choices': None},
    {'type': 'TextArea', 'value': '', 'label': 'Comments', 'name': 'Comments', 'choices': None},
    {'type': 'Button', 'value': '', 'label': '', 'name': 'AloahaFormSaveButton', 'choices': None},
    {'type': 'Button', 'value': '', 'label': '', 'name': 'AloahaFormSubmitButton', 'choices': None},
]

@pytest.fixture
def sample_form_1():
    yield {
        'pdf': pdf_form_1,
        'schema': _form_1_schema,
    }

@pytest.fixture
def sample_form_2():
    yield {
        'pdf': pdf_form_2,
        'schema': _form_2_schema,
    }


import os
import numpy as np
import matplotlib.pylab as plt

def get_grad_norm_from_file(fp):
    if not os.path.exists(fp):
        return -1

    with open(fp, "r") as f:
        grad_norms = []
        for line in f.readlines():
            line = line.strip()
            if 'grad_norm' in line:
                grad_norm = line.split('|')[-2]
                grad_norm = float(grad_norm)

                grad_norms.append(grad_norm)
    try:
        return sum(grad_norms) / len(grad_norms)
    except ZeroDivisionError:
        return -1

def parse_exp_dir(dir):
    sub_dirs = os.listdir(dir)
    sub_dirs = [int(x) for x in sub_dirs]
    sub_dirs.sort()
    sub_dirs = [f"{x:06d}" for x in sub_dirs]
    print(sub_dirs)

    # different iters
    grad_norm_at_iters = []
    for _sub_dir in sub_dirs:
        # from-to dir

        # different timesteps for each iter
        grad_norm_at_steps = []
        for i in range(100):
            _from = 10 * i
            _to = 10 * (i + 1) - 1

            _fp = f"{dir}/{_sub_dir}/from-to-{_from}-{_to}/log.txt"
            grad_norm = get_grad_norm_from_file(_fp)
            # print(grad_norm)
            if grad_norm > 0:
                grad_norm_at_steps.append(grad_norm)

        grad_norm_at_iters.append(grad_norm_at_steps)

    return grad_norm_at_iters

def main():
    # x = get_grad_norm_from_file("/home/v-tiahang/code_base/others/analyze_gradnorm/data/28/nov11_imnet_beit_base_layer12_lr1e-4_099_099_img64_pred_x0_loss-eps_fp16_bs8x64/070000/from-to-150-159/log.txt")
    # print(x)

    exp_list = [
        "nov3_imnet_beit_base_layer12_lr1e-4_099_099_img64_pred_noise_fp16_bs8x64",
        "nov11_imnet_beit_base_layer12_lr1e-4_099_099_img64_pred_x0_loss-eps_fp16_bs8x64",
        "nov15_imnet_beit_base_layer12_lr1e-4_099_099_img64_pred_x0__min_snr_1__fp16_bs8x64",
        "nov15_imnet_beit_base_layer12_lr1e-4_099_099_img64_pred_x0__min_snr_5__fp16_bs8x64",
        "nov23_imnet_beit_base_layer12_lr1e-4_099_099_img64_pred_noise__min_snr_1__fp16_bs8x64",
        "nov23_imnet_beit_base_layer12_lr1e-4_099_099_img64_pred_noise__min_snr_5__fp16_bs8x64",
    ]

    for exp in exp_list:
        result = parse_exp_dir(f"data/28/{exp}")
        # import pdb; pdb.set_trace()

        for iter, norms_at_iter in enumerate(result):
            plt.plot(norms_at_iter, label=f"{(iter + 1)*10000}")

        plt.legend()
        plt.savefig(f"{exp}.png")

        plt.close(); plt.clf()
        # import pdb; pdb.set_trace()

if __name__ == '__main__':
    main()


#!/usr/bin/env python
# coding: utf-8

import os
import argparse

import numpy as np
import tensorflow as tf

from keras.utils import to_categorical
from keras import Sequential
from keras.layers import Conv2D, MaxPooling2D, Dense, Flatten

from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split

from PIL import Image

import matplotlib.pyplot as plt
from matplotlib import image

tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)

IMAGE_PATH = os.getcwd() + '/images'
SPECIES_MODE = True

parser = argparse.ArgumentParser()
parser.add_argument('-g', '--genus', action='store_true')
if parser.parse_args().genus:
    SPECIES_MODE = False

#CROP_X =
#960x320+62+0

images = []
labels = []

# subfolders of images should be genus names
genera = [folder for folder in os.listdir(IMAGE_PATH)
          if os.path.isdir(os.path.join(IMAGE_PATH, folder))]

if not genera:
    print("Need to download genera first.")
    quit()

for genus in genera:
    new_image_path = os.path.join(IMAGE_PATH, genus)
    for img_file in os.listdir(new_image_path):
        img = Image.open(os.path.join(new_image_path, img_file)).convert('L')
        # crop away the part that all images share
        #img = img.crop((960,320,62,0))

        # shape: (height, width)
        img_array = np.asarray(img)
        img_array = img_array.reshape(img_array.shape[0], img_array.shape[1], 1)

        #plt.imshow(img_array, cmap='gray', vmin=0, vmax=255)
        #plt.show()

        images.append(img_array)

        # parse label from file
        if SPECIES_MODE:
            labels.append(img_file.split(".")[0].split("-")[1])
        else:
            labels.append(genus)

#for img in images:
    #print(img)

# one hot encoding on labels
encoder = LabelBinarizer()
one_hot_labels = encoder.fit_transform(labels)

print(one_hot_labels.shape)

X_train, X_val, y_train, y_val = train_test_split(images, one_hot_labels, test_size=0.2, random_state=31)
X_train = np.array(X_train)
X_val = np.array(X_val)

#X_train_shaped = X_train.reshape(X_train.shape[0], X_train.shape[1], X_train.shape[2], 1)
#X_val_shaped = X_val.reshape(X_val.shape[0], X_val.shape[1], X_val.shape[2], 1)

model = Sequential()

model.add(Conv2D(filters=32, input_shape=(X_train.shape[1], X_train.shape[2], 1), data_format="channels_last", kernel_size=2,
                 strides=2, activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(one_hot_labels.shape[1], activation='sigmoid'))
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

model.summary()

model.fit(X_train, y_train, validation_data=(X_val, y_val), epochs=10)

#model.predict(test_X_shaped[:4])


from itertools import combinations

from Architecture.factor_models.pair_spread_factor import PairSpreadFactor

class AlphaModel:
    """
    Emit trading signals to Portfolio Model. Under the Alpha Model is a collection
    of factor models (strategies) which receive preprocessed data, calculate
    indicators and generate signals based off the indicators.
    """
    def __init__(self):
        # internal data structures
        self.factor_universes_and_models = {}

        # data structures received from data model
        self.securities_and_latest_quote = {}
        self.securities_and_latest_trade = {}
        self.securities_and_latest_bar = {}
        self.securities_and_latest_usd_price = {}
        self.current_time = None

        # data structures received from universe model
        self.securities_and_ids = {}
        self.security_clusters = {}

        # data structures to pass to portfolio model
        self.alpha_signals = {}

    def update_factors_with_latest_data(self):
        """ Updates each factor model with latest data for factor model to function
        """
        # Loop through each factor model, and the subset of securities traded by the factor
        for factor_universe, factor_model in self.factor_universes_and_models.items():
            # Loops through each security in the factor universe to update factor model
            for security in factor_universe:
                self.update_specific_factor_model(security, factor_model)

    def update_specific_factor_model(self, security, factor_model):
        """
        Updates a factor model by feeding it latest data for one of the securities
        that is in the factor model's universe.

        Args:
             security (str): symbol code for the security
             factor_model (FactorModel): an instance of a factor model
        """
        factor_model.receive_data({"security": security,
                                   "latest_bar": self.securities_and_latest_bar[security],
                                   "latest_trade": self.securities_and_latest_trade[security],
                                   "latest_quote": self.securities_and_latest_quote[security],
                                   "latest_usd_price": self.securities_and_latest_usd_price[security]})

    def aggregate_signals_from_strategies(self):
        """ Calls each factor model to generate signals, and aggregates signals across factors
        """
        # Initialise aggregated alpha signals
        alpha_signals = {security: 0 for security in self.securities_and_ids}

        # Loop through each factor model, and the subset of securities traded by the factor
        for factor_universe, factor_model in self.factor_universes_and_models.items():
            signals = factor_model.generate_signals()
            for security in factor_universe:
                alpha_signals[security] += signals[security]

        self.alpha_signals = alpha_signals

    def emit_alpha_signal(self):
        """
        Emits aggregated alpha signals to Portfolio model

        Returns:
            self.alpha_signals (dict{security (str): position (int)})
        """
        return self.alpha_signals

    def receive_trading_universe(self, trading_universe):
        """
        Receives securities to trade from universe model.

        Args:
            trading_universe (dict): securities and currencies to trade
        """
        self.securities_and_ids = trading_universe['securities_and_ids']
        self.security_clusters = trading_universe['security_clusters']

    def receive_latest_data(self, latest_data):
        """
        Receives latest data from data model.

        Args:
            latest_data (dict)
        """
        self.securities_and_latest_quote = latest_data['securities_and_latest_quote']
        self.securities_and_latest_trade = latest_data['securities_and_latest_trade']
        self.securities_and_latest_bar = latest_data['securities_and_latest_bar']
        self.securities_and_latest_usd_price = latest_data['securities_and_latest_usd_price']
        self.current_time = latest_data['current_time']

    def initialise_factor_models(self):
        """
        Initialises factor models for alpha model to function. Each factor models focus on a
        subset of the trading universe, creating signals based on indicators calculated from
        preprocessed data.

        As an example, we will create factors for each pair of securities in the trading
        universe. Such factors focus on pair-trading; a common strategy used by traders to
        take long-short positions in a pair of highly correlated securities.
        """
        # Create pairs of securities from clusters
        pairs_of_securities = []

        for cluster in self.security_clusters.values():
            pairs_of_securities.extend(list(combinations(cluster, 2)))

        for pair in pairs_of_securities:
            self.factor_universes_and_models[pair] = PairSpreadFactor(pair)


import feedparser
from lxml.html import fromstring
from config.config import get_software_list, save_threat_db, save_vuln
from config.config import check_saved_threats, check_saved_vulns

class CISAVulnerability:
    def __init__(self, vendor_product, description, published, cvss, cve_info):
        self.vendor_product = vendor_product
        self.description = description
        self.published = published
        self.cvss = cvss
        self.cve_info = cve_info

    def show_vulnerability_info(self):
        print("[*] Vulnerability found!")
        print("\t[-] Vendor-product: "+self.vendor_product)
        print("\t[-] Description: "+self.description)
        print("\t[-] Published: "+self.published)
        print("\t[-] Scoring: "+self.cvss)
        print("\t[-] CVE: " + self.cve_info)

class CISAICSThreat:
    def __init__(self, title, summary, published, link):
        self.title = title
        self.summary = summary
        self.published = published
        self.link = link

    def show_threat_info(self):
        print("[*] Threat found!")
        print("\t[-] Title: "+self.title)
        print("\t[-] Summary: "+self.summary)
        print("\t[-] Published: "+self.published)
        print("\t[-] Link: "+self.link)

def check_vuln_products(vulnerabibility_list):
    product_list = get_software_list()
    vuln_alert = []
    for v in vulnerabibility_list:
        for p in product_list:
            if p in v.description:
                vuln_alert.append(v)
    return vuln_alert

def check_ics_threats(threat_list):
    threats= get_software_list()
    threat_alert = []
    for t in threat_list:
        for p in threats:
            if p in t.summary:
                threat_alert.append(t)
    return threat_alert

def feed_vulnerability_reports():
    vulnerability_list = []
    rss = 'https://us-cert.cisa.gov/ncas/bulletins.xml'
    feed = feedparser.parse(rss)
    for key in feed["entries"]:
        title = key['title']
        url = key['links'][0]['href']
        published = key['published']
        summary = key['summary']
        already_stored = check_saved_vulns(url)
        if already_stored is False:
            save_vuln(url, title, published)
            doc = fromstring(summary)
            tr_elements = doc.xpath('//tr')
            for j in range(1, len(tr_elements)):
                items = tr_elements[j]
                if len(items) != 5:
                    break
                count = 0
                for t in items.iterchildren():
                    data = t.text_content().strip()
                    if count == 0:
                        vendor = data
                    elif count == 1:
                        description = data
                    elif count == 2:
                        published = data
                    elif count == 3:
                        cvss = data
                    elif count == 4:
                        info = data
                        cisa = CISAVulnerability(vendor, description, published, cvss, info)
                        vulnerability_list.append(cisa)
                    count = count + 1
    return vulnerability_list

def feed_ics_threats():
    cisa_threats = []
    rss="https://us-cert.cisa.gov/ics/advisories/advisories.xml"
    feed = feedparser.parse(rss)
    for key in feed["entries"]:
        title = key['title']
        summary = key['summary'].replace("<p>","").replace("<p>","")
        published = key['published']
        link = key['link']
        already_stored = check_saved_threats(link)
        if already_stored is False:
            save_threat_db(link, title, published)
            threat = CISAICSThreat(title, summary, published, link)
            cisa_threats.append(threat)
    return cisa_threats

def get_vulnerability_reports():
    products_wt_vulns = []
    vulnerability_list = feed_vulnerability_reports()
    if vulnerability_list is not None:
        products_wt_vulns = check_vuln_products(vulnerability_list)
        for p in products_wt_vulns:
            p.show_vulnerability_info()
    return products_wt_vulns
    return vulnerability_list

def get_ics_threats():
    threats = feed_ics_threats()
    if threats is not None:
        filtered_threats = check_ics_threats(threats)
        for t in filtered_threats:
            t.show_threat_info()
    return filtered_threats
    return threats


#Program to convert a color image to grayscale image

from skimage import color, io

#Read an image from a file
img = io.imread('image.png')

#Convert the image tp grayscale
hsv_image = color.rgb2hsv(img)

io.imshow(hsv_image)
io.show()


import collections, copy
Card = collections.namedtuple('Card',['rank','suit'])

class Deck(object):

	def __int__(self):

		''' Initializes a deck of cards.'''

		ranks = [str(n) for n in range(2,11)] + list('JQKA')
		suits = 'spades diamonds clubs hearts'.split()

		self._cards = [Card(rank,suit) for rank in ranks for suit in suits]

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

	def __getitem__(self, key):
		return self._cards[key]

	def flipBackSequence(self, deck = None):

		''' returns the sequence of cards, in order, if you drew the top card, put the next card at the back of the deck,
		and then repeated until only one card remained (in which case it would be returned.)'''

		if deck == None:
			deck = copy.deepcopy(self)

		if len(deck) == 1: # only one item left in the deck:
			return [deck[0]]

		else:
			topCard, secondCard = deck[0:2]

			deck = deck[1:]

			deck.insert(len(deck) + 1, secondCard)

			return [topCard] + flipBackSequence(self, deck)


def imrotate(img_path:str, degree:np.float32, interpolation='nearest'):

    if interpolation not in ['nearest','bilinear']:
        print("Unknown Interpolation. Plese Choose either 'nearest' or 'bilinear'")
        import sys
        sys.exit(1)

    import skimage.io
    import math as ma
    # check for no. of channels
    img_data = skimage.io.imread(img_path.as_posix(), as_gray=True)

    rads = degree * 22/(7*180)
    h, w = img_data.shape[0], img_data.shape[1]

    # New size of image
    newW = int(np.ceil(abs(w*np.cos(rads)) + abs(h*np.sin(rads))) + 1)
    newH = int(np.ceil(abs(w*np.sin(rads)) + abs(h*np.cos(rads))) + 1)

    x0, y0 = h/2, w/2

    def linear_interpolation(pt1, pt2, unknown):
        temp1 = pt1[1]*((pt2[0]-unknown[0])/(pt2[0]-pt1[0]))
        temp2 = pt2[1]*((unknown[0]-pt1[0])/(pt2[0]-pt1[0]))
        return temp1 + temp2

    def bilinear_interpolation(pt1, pt2, pt3, pt4, unknown):
        if pt1[0] == pt3[0]:
            return linear_interpolation((pt1[1], pt1[2]), (pt2[1], pt2[2]), (unknown[1], unknown[2]))
        if pt1[1] == pt2[1]:
            return linear_interpolation((pt1[0], pt1[2]), (pt3[0], pt3[2]), (unknown[0], unknown[2]))

        R1 = linear_interpolation((pt1[0], pt1[2]), (pt3[0], pt3[2]), (unknown[0], unknown[2]))
        R2 = linear_interpolation((pt2[0], pt2[2]), (pt4[0], pt4[2]), (unknown[0], unknown[2]))
        P = linear_interpolation((pt1[1], R1), (pt2[1], R2), (unknown[1], unknown[2]))
        return P

    # New image initialisation
    newImg = np.zeros([newH, newW])

    for i in tqdm.tqdm(range(newH)):
        for j in range(newW):

            # shifting the origin
            x = (newH/2 - i)
            y = (j - newW/2)

            # calculating new x and y co-ordinates after rotating
            xx = (x*np.cos(rads) - y*np.sin(rads))
            yy = (x*np.sin(rads) + y*np.cos(rads))

            xx = (h/2 - xx)
            yy = (yy + w/2)

            if interpolation=='bilinear':
                x, y = xx, yy
                if (x<0 or x>=h or y<0 or y>=w):
                    newImg[i][j] = 255
                else:
                    x1, x2 = ma.floor(x), ma.ceil(x)
                    y1, y2 = ma.floor(y), ma.ceil(y)

                    x1 = x1-1 if x1==h else x1
                    x2 = x2-1 if x2==h else x2
                    y1 = y1-1 if y1==w else y1
                    y2 = y2-1 if y2==w else y2

                    pt1, pt2 = (x1, y1, img_data[x1, y1]), (x1, y2, img_data[x1, y2])
                    pt3, pt4 = (x2, y1, img_data[x2, y1]), (x2, y2, img_data[x2, y2])
                    unknown = (x, y, 0)

                    if pt1[0] == pt3[0] and pt1[2] == pt2[2]:
                        newImg[i, j] = img_data[int(x), int(y)]
                    else:
                        newImg[i,j] = bilinear_interpolation(pt1, pt2, pt3, pt4, unknown)

            elif interpolation=='nearest':
                xx, yy = int(xx), int(yy)

                # checking if any of the following conditions satisfy then assigning it 255

                if (xx<0 or xx>=h or yy<0 or yy>=w):
                    newImg[i][j] = 255
                else:
                    newImg[i][j] = img_data[xx][yy]

    #plt.imshow(newImg, cmap='gray')
    return  newImg


from flask import Flask
#from werkzeug.datastructures import T #架站軟體 做route回應
app = Flask(__name__) # route 設定
from flask import request,abort #request接收訊息
from linebot import LineBotApi,WebhookHandler # LINEBOTAPI接收訊息 # handle 識別碼
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent,TextMessage,TextSendMessage
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing import image
from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
import numpy as np
from linebot.models import *
import tempfile
import os
## 授權
line_bot_api = LineBotApi("r7Zq64defLm6ZXPBwUUT8AS+/5Rbau+jUnOY+lcDWTx+p/b0pX94AdeSbiPrGuxMDDkDfy6m0GQcJcLNc7Y5Ie49HQh+dl8nmJytkntT52AA3XAgO83kqGrntlNFOoaInPOJD0QAqbd/E6jZFoPFtQdB04t89/1O/w1cDnyilFU=")
## channel secert
handler = WebhookHandler("cfc2857f38799f624e02148130e0706c")
static_tmp_path = os.path.join(os.path.dirname(__file__), 'static', 'tmp')
# @app.route("/",methods=["POST"]) # 接收資料 不傳密碼
# def callback(): #回覆函數
#     signature = request.headers["X-Line-Signature"] #查詢簽名
#     body = request.get_data(as_text = True) # get
#     try:
#         handler.handle(body,signature)
#     except InvalidSignatureError:
#         abort(500)
#     return "OK"

# @handler.add(MessageEvent,message= TextMessage)  # handler become router cope with textmessage
# def handle_message(event):
#     line_bot_api.reply_message(event.reply_token,TextSendMessage(text=event.message.text))
# 回覆訊息 event連接 text event所送過來的文字
# event.replt_token識別跟誰對話
# TextSendMessage(text=event.message.text)) event的message
dic = {0 : '三杯雞', 1 : '什錦炒麵',2:"咖哩雞",3:"塔香海茸",4:"大陸妹",5:"客家小炒",6:"小番茄",7:"有機小松菜",8:"有機青松菜",9:"木瓜",
        10:"柳丁",11:"棗子",12:"橘子",13:"沙茶肉片",14:"油菜",15:"洋蔥炒蛋",16:"滷蛋",17:"滷雞腿",18:"玉米炒蛋",19:"瓜仔肉",
        20:"番茄炒蛋",21:"白米飯",22:"白菜滷",23:"福山萵苣",24:"空心菜",25:"糖醋雞丁",26:"紅蘿蔔炒蛋",27:"義大利麵",28:"芥藍菜",29:"菠菜",
        30:"葡萄",31:"蒜泥白肉",32:"蒸蛋",33:"蓮霧",34:"螞蟻上樹",35:"西瓜",36:"豆芽菜",37:"關東煮",38:"青江菜",39:"香蕉",40:"香酥魚排",
        41:"馬鈴薯燉肉",42:"高麗菜",43:"鳳梨'",44:"鵝白菜",45:"鹽酥雞",46:"麥克雞塊",47:"麻婆豆腐",48:"麻油雞",49:"黑胡椒豬柳"}
model = load_model('model.h5')
def predict_label(img_path):
    i = image.load_img(img_path, target_size=(224,224))
    #i = image.img_to_array(i)/255.0
	#i = i.reshape(None,224,224,3)
    #i = np.expand_dims(i,axis=0)
    i  = np.expand_dims( i , axis = 0)
    p = model.predict(i)[0]
    top = p.argsort()[::-1][:5]
    return dic[top[0]]
@app.route("/", methods=['POST'])
def callback():
    signature = request.headers['X-Line-Signature']
    body = request.get_data(as_text=True)
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)
    return 'OK'
@handler.add(MessageEvent,message= TextMessage)  # handler become router cope with textmessage
def handle_message(event):
    message = TextSendMessage(text='哈囉你好，第一道謎題，請問某水果以屏東黑珍珠著稱，請回傳圖片解題！')
    line_bot_api.reply_message(event.reply_token,TextSendMessage(text='哈囉你好，第一道謎題，請問某水果以屏東黑珍珠著稱，請回傳圖片解題！'))
@handler.add(MessageEvent, message=ImageMessage)
def handle_message(event):

    #line_bot_api.reply_message(event.reply_token, message)
    if isinstance(event.message,ImageMessage):
        ext = "jpg"
        #line_bot_api.reply_message(event.reply_token, message)
        message_content = line_bot_api.get_message_content(event.message.id)
        with tempfile.NamedTemporaryFile(dir=static_tmp_path, prefix=ext + '-', delete=False) as tf:
            for chunk in message_content.iter_content():
                tf.write(chunk)
            tempfile_path = tf.name
        dist_path = tempfile_path + '.' + ext
        dist_name = os.path.basename(dist_path)
        os.rename(tempfile_path, dist_path)
        res = predict_label(dist_path)
        if(res=="蓮霧"):
            message =TextSendMessage(text="答對了，是蓮霧")
        else:
            message = TextSendMessage(text="答錯了，你給的是{}".format(res))
        line_bot_api.reply_message(event.reply_token, message)
    #print('-----------------')
    # if event.message.type=="image":
    #     #line_bot_api.reply_message(event.reply_token,message)
    #     res = predict_label(event.message)
    #     line_bot_api.reply_message(event.reply_token,res)
    #line_bot_api.reply_message(event.reply_token,TextSendMessage(text=event.message.text))

# @handler.add(MessageEvent, message=(ImageMessage, VideoMessage, AudioMessage))
# def handle_content_message(event):
#     if event.message.type=="image":
#         line_bot_api.reply_message(event.reply_token,"ff")

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


#!/usr/bin/env python
"""
Data classes defining Variants with added functionality for manipulating them.
"""

from typing import Optional
from pysam import VariantFile
from pysam.libcbcf import VariantRecord
from var_annot.ensembl import get_vep_data

class Variants:
    """Data class managing many Variant classes as well as functions to manipulate them."""

    def __init__(self, infile_path: str):
        """
        Initializes the Variants from a VCF data file.

        :param infile_path: Path to VCF input file
        :return: None
        """
        self.data = {}
        self.variants_order = []
        self.load_vcf(infile_path=infile_path)

    def load_vcf(self, infile_path: str):
        """
        Loads VCF data from file.

        :param infile_path: Path to VCF input file
        :return: None
        """
        vcf_in = VariantFile(infile_path)  # auto-detect input format
        for record in vcf_in.fetch():
            # Process multiple alt alleles for sample
            for alt_index in range(len(record.alts)):
                var = Variant(record=record, alt_index=alt_index)
                self.data[var.vep_hgvs] = var
                self.variants_order.append(var.vep_hgvs)

    def add_vep_info(
        self,
        hgvs_infile: Optional[str] = None,
        hgvs_outfile: Optional[str] = None,
        ids_infile: Optional[str] = None,
        ids_outfile: Optional[str] = None,
    ):
        """
        Adds VEP information to the Variants.

        Calls VEP APIs to obtain the information. If infiles are provided this function
        will load the data from the infiles. If outfiles are provided it will save the
        data to outfile paths.

        :param hgvs_infile: Loads HGVS data from this JSON file.
        :param hgvs_outfile: Writes HGVS data to this JSON file path.
        :param ids_infile: Loads Variant ID data from this JSON file.
        :param ids_outfile: Writes Variant ID data to this JSON file path.
        :return: None
        """
        vep_data = get_vep_data(
            hgvs_list=list(self.data.keys()),
            hgvs_infile=hgvs_infile,
            hgvs_outfile=hgvs_outfile,
            ids_infile=ids_infile,
            ids_outfile=ids_outfile,
        )
        for vep_key in vep_data.keys():
            self.data[vep_key].vep_content = vep_data[vep_key]

            # Processes the gene name data
            genes = set()
            self.data[vep_key].variant_effect = vep_data[vep_key]["most_severe_consequence"]
            if "transcript_consequences" in vep_data[vep_key]:
                for tc in vep_data[vep_key]["transcript_consequences"]:
                    ignored_genes = [
                        "Clone_based_vega_gene",
                        "Clone_based_ensembl_gene",
                        "Uniprot_gn",
                    ]
                    if (
                        self.data[vep_key].variant_effect in tc["consequence_terms"]
                        and tc["gene_symbol_source"] not in ignored_genes
                    ):
                        genes.add(tc["gene_symbol_source"])
                self.data[vep_key].gene_name = ",".join(genes)

            # Processes the id, variant_type, and MAF data
            if vep_data[vep_key]["vep_id_data"]:
                self.data[vep_key].vep_id = vep_data[vep_key]["vep_id"]
                self.data[vep_key].variant_type = vep_data[vep_key]["vep_id_data"]["var_class"]
                self.data[vep_key].maf = vep_data[vep_key]["vep_id_data"]["MAF"]

    def write(self, out_file: str):
        """
        Writes relevant data to output TSV file.

        :param out_file: Path to output file.
        :return: None
        """
        header_list = [
            "chrom",
            "pos",
            "id",
            "ref",
            "alt",
            "total_depth",
            "variant_depth",
            "variant_percentage",
            "gene",
            "variation_type",
            "variation_effect",
            "MAF",
        ]
        with open(out_file, "w") as out_fh:
            out_line = "\t".join(header_list) + "\n"
            out_fh.write(out_line)
            for vep_hgvs in self.variants_order:
                var = self.data[vep_hgvs]
                variant_id = "."
                if var.vep_id:
                    variant_id = var.vep_id
                line_list = [
                    var.chrom,
                    var.pos,
                    variant_id,
                    var.ref,
                    var.alt,
                    var.depth,
                    var.var_depth,
                    var.var_percentage,
                    var.gene_name,
                    var.variant_type,
                    var.variant_effect,
                    var.maf,
                ]
                # clean up output list
                clean_line_list = []
                for item in line_list:
                    if item:
                        clean_line_list.append(str(item))
                    else:
                        clean_line_list.append("N/A")
                out_line = "\t".join(clean_line_list) + "\n"
                out_fh.write(out_line)

class Variant:
    """Data class containing relelant information at the Variant level."""

    def __init__(self, record: VariantRecord, alt_index=0):
        self.chrom = record.contig
        self.pos = record.pos
        self.ref = record.ref
        self.alt = record.alts[alt_index]
        self.vep_hgvs = f"{self.chrom}:g.{self.pos}{self.ref}>{self.alt}"  # ex: "1:g.1158631A>G"
        self.depth = record.samples[0]["NR"][alt_index]  # total depth
        self.var_depth = record.samples[0]["NV"][alt_index]  # Variant depth
        # Percentage of reads supporting the variant versus those supporting reference reads.
        self.var_percentage = 100 * (self.var_depth / self.depth)
        # Values defined by VEP HGVS annotation. Initialized to None until VEP is queried.
        self.vep_id = None
        self.vep_content = None
        self.gene_name = None
        self.variant_type = None
        self.variant_effect = None
        self.maf = None  # The minor allele frequency of the variant if available.
        # Any additional annotations that you feel might be relevant.
        self.record = record  # vcf record, not printed to outfile but could easily be if you want.


import torch
import torch.nn as nn
from timm.models.layers import DropPath
from model.gcn_lib.torch_edge import DenseDilatedKnnGraph
from model.gcn_lib.torch_vertex import GraphConv2d
from model.gcn_lib.torch_nn import get_act_layer
from torch.nn import Sequential as Seq
from data import ClipFramesLen

class FFN(nn.Module):
    def __init__(self, in_features, hidden_features=None, out_features=None, act='relu', drop_path=0.0):
        super().__init__()
        out_features = out_features or in_features
        hidden_features = hidden_features or in_features
        self.fc1 = nn.Sequential(
            nn.Conv2d(in_features, hidden_features, 1, stride=1, padding=0),
            nn.BatchNorm2d(hidden_features),
        )
        self.act = get_act_layer(act)
        self.fc2 = nn.Sequential(
            nn.Conv2d(hidden_features, out_features, 1, stride=1, padding=0),
            nn.BatchNorm2d(out_features),
        )
        self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()

    def forward(self, x):
        # shortcut = x
        x = self.fc1(x)
        x = self.act(x)
        x = self.fc2(x)
        x = self.drop_path(x)
        # x = self.drop_path(x) + shortcut
        return x

class SignalGraphConv2d(GraphConv2d):
    """
    Dynamic graph convolution layer
    """

    def __init__(self, in_channels, out_channels, kernel_size=9, dilation=1, conv='edge', act='relu',
                 norm=None, bias=True, stochastic=False, epsilon=0.0):
        super(SignalGraphConv2d, self).__init__(in_channels, out_channels, conv, act, norm, bias)
        self.dilated_knn_graph = DenseDilatedKnnGraph(kernel_size, dilation, stochastic, epsilon)

    def forward(self, x, relative_pos=None, **kwargs):
        tmp = x
        y = None
        edge_index = self.dilated_knn_graph(x, y, relative_pos)
        x = super(SignalGraphConv2d, self).forward(x, edge_index, y)
        return tmp + x

class DenoiseGraph(torch.nn.Module):
    def __init__(self, opt):
        super(DenoiseGraph, self).__init__()
        k = opt.wave_gnn_k
        act = opt.wave_gnn_act
        norm = opt.wave_gnn_norm
        bias = opt.wave_gnn_bias
        epsilon = opt.wave_gnn_epsilon
        stochastic = opt.wave_gnn_use_stochastic
        conv = opt.wave_gnn_conv
        drop_path = opt.wave_gnn_drop_path
        blocks = opt.wave_gnn_blocks
        channels = opt.wave_channels
        self.last_dim = opt.wave_last_dim

        self.n_blocks = sum(blocks)
        dpr = [x.item() for x in torch.linspace(0, drop_path, self.n_blocks)]  # stochastic depth decay rule
        num_knn = [int(x.item()) for x in torch.linspace(k, k, self.n_blocks)]  # number of knn's k
        max_dilation = max(1, 49 // max(num_knn))

        idx = 0
        self.graph_backbone = nn.ModuleList([])
        start_dim = channels[0]
        self.change_dim_layout = None
        if start_dim != self.last_dim:
            self.change_dim_layout = nn.Linear(self.last_dim, start_dim, bias=True)
        for i in range(len(blocks)):
            for j in range(blocks[i]):
                self.graph_backbone += [
                    Seq(SignalGraphConv2d(ClipFramesLen, ClipFramesLen, num_knn[idx], min(idx // 4 + 1, max_dilation),
                                          conv, act, norm, bias, stochastic, epsilon),
                        FFN(ClipFramesLen, ClipFramesLen, act=act, drop_path=dpr[idx]))]
                idx += 1

        dim = channels[0]
        self.graph_backbone = Seq(*self.graph_backbone)
        self.backbone = nn.ModuleList([])
        for id in range(1, len(channels)):
            self.backbone += [Seq(nn.Conv1d(dim, channels[id], 1, stride=1, padding=0), get_act_layer(act))]
            dim = channels[id]

        self.backbone = Seq(*self.backbone)

        self.model_init()

    def model_init(self):
        for m in self.modules():
            if isinstance(m, torch.nn.Conv2d):
                torch.nn.init.kaiming_normal_(m.weight)
                m.weight.requires_grad = True
                if m.bias is not None:
                    m.bias.data.zero_()
                    m.bias.requires_grad = True

    def forward(self, x):
        batch_size = x.shape[0]
        features_last = x.permute(0, 2, 1, 3, 4)
        features_last = features_last.reshape(batch_size, 160, self.last_dim)  # x [B, 160, self.last_dim]
        if self.change_dim_layout is not None:
            features_last = self.change_dim_layout(features_last)
        ecg = features_last.unsqueeze(3)  # [B, 160, start_dim, 1]

        for i in range(len(self.graph_backbone)):
            ecg = self.graph_backbone[i](ecg)

        ecg = ecg.squeeze(3).permute(0, 2, 1)  # x [B, start_dim, 160]
        for i in range(len(self.backbone)):
            ecg = self.backbone[i](ecg)
        # [B, 1, 160]

        ecg = ecg.squeeze(1)  # x [B, 160]
        return ecg

def denoise_graph(opt):
    model = DenoiseGraph(opt)
    return model


from functools import cache
from matplotlib import pyplot as plt
from itertools import combinations
from joblib import Parallel, delayed

import json
import random
import os
import math
import numpy as np

# imports for Isaac's code
from filtered_constraints import filtered_constraints as fc, make_correct_rows as crows

auxdirpath = "/home/ikmarti/Desktop/ising-clustering/constraint-reduction/aux_arrays/"

def uniquify(path):
    filename, extension = os.path.splitext(path)
    counter = 1

    while os.path.exists(path):
        path = filename + " (" + str(counter) + ")" + extension
        counter += 1

    return path

def read_auxfile(filename):
    auxes = []
    with open(filename) as file:
        for line in file:
            auxes.append(json.loads(line)[0])

    return auxes

def sample_auxfile(filename, samples):
    auxes = []
    with open(filename) as file:
        for line in file:
            auxes.append(json.loads(line))

    return random.sample(auxes, k=samples)

def save_auxfile(auxes, filename):
    path = uniquify(auxdirpath + filename)
    with open(path, "w") as file:
        for aux in auxes:
            file.write(str(aux.tolist()) + "\n")

correct_rows_no_aux = {}

def pairs_to_and(N1, N2, pairs):
    try:
        correct = correct_rows_no_aux[(N1, N2)]
    except KeyError:
        correct_rows_no_aux[(N1, N2)] = crows(N1, N2, None)
        correct = correct_rows_no_aux[(N1, N2)]

    aux_vecs = np.concatenate(
        [np.expand_dims(np.prod(correct[..., key], axis=-1), axis=0) for key in pairs]
    ).astype(np.int8)
    return aux_vecs

def and_aux_generator(N1, N2, A, numsamples=10000):
    filename = f"IMul{N1}x{N2}x{A}_AND_AUX.dat"
    N = N1 + N2
    correct = crows(N1, N2, None)
    correct = correct.numpy()

    tups = set(
        {
            tuple(random.sample(list(combinations(list(range(N)), r=2)), k=A))
            for _ in range(numsamples)
        }
    )
    auxes = []
    for tup in tups:
        aux_vecs = np.concatenate(
            [np.expand_dims(np.prod(correct[..., key], axis=-1), axis=0) for key in tup]
        ).astype(np.int8)
        auxes.append(aux_vecs)

    save_auxfile(auxes, filename)

if __name__ == "__main__":
    N1 = 4
    N2 = 3
    M = N1 + N2
    G = N1 + N2 + M
    maxA = 20
    for A in range(1, maxA + 1):
        numsamples = min(math.comb(math.comb(G, 2), A), 100000)
        and_aux_generator(N1, N2, A, numsamples)
        print(f"Finished IMul{N1}x{N2}x{A}")


import logging
from pathlib import Path
import pytest

from flit_core import config

samples_dir = Path(__file__).parent / 'samples'

def test_flatten_entrypoints():
    r = config.flatten_entrypoints({'a': {'b': {'c': 'd'}, 'e': {'f': {'g': 'h'}}, 'i': 'j'}})
    assert r == {'a': {'i': 'j'}, 'a.b': {'c': 'd'}, 'a.e.f': {'g': 'h'}}

def test_load_toml():
    inf = config.read_flit_config(samples_dir / 'module1-pkg.toml')
    assert inf.module == 'module1'
    assert inf.metadata['home_page'] == 'http://github.com/sirrobin/module1'

def test_load_toml_ns():
    inf = config.read_flit_config(samples_dir / 'ns1-pkg' / 'pyproject.toml')
    assert inf.module == 'ns1.pkg'
    assert inf.metadata['home_page'] == 'http://github.com/sirrobin/module1'

def test_load_normalization():
    inf = config.read_flit_config(samples_dir / 'normalization' / 'pyproject.toml')
    assert inf.module == 'my_python_module'
    assert inf.metadata['name'] == 'my-python-module'

def test_load_pep621():
    inf = config.read_flit_config(samples_dir / 'pep621' / 'pyproject.toml')
    assert inf.module == 'module1a'
    assert inf.metadata['name'] == 'module1'
    assert inf.metadata['description_content_type'] == 'text/x-rst'
    # Remove all whitespace from requirements so we don't check exact format:
    assert {r.replace(' ', '') for r in inf.metadata['requires_dist']} == {
        'docutils',
        'requests>=2.18',
        'pytest;extra=="test"',  # from [project.optional-dependencies]
        'mock;extra=="test"and(python_version<\'3.6\')',
    }
    assert inf.metadata['author_email'] == "Sir Röbin <robin@camelot.uk>"
    assert inf.entrypoints['flit_test_example']['foo'] == 'module1:main'
    assert set(inf.dynamic_metadata) == {'version', 'description'}

def test_load_pep621_nodynamic():
    inf = config.read_flit_config(samples_dir / 'pep621_nodynamic' / 'pyproject.toml')
    assert inf.module == 'module1'
    assert inf.metadata['name'] == 'module1'
    assert inf.metadata['version'] == '0.3'
    assert inf.metadata['summary'] == 'Statically specified description'
    assert set(inf.dynamic_metadata) == set()

    # Filling reqs_by_extra when dependencies were specified but no optional
    # dependencies was a bug.
    assert inf.reqs_by_extra == {'.none':  ['requests >= 2.18', 'docutils']}

def test_misspelled_key():
    with pytest.raises(config.ConfigError) as e_info:
        config.read_flit_config(samples_dir / 'misspelled-key.toml')

    assert 'description-file' in str(e_info.value)

def test_description_file():
    info = config.read_flit_config(samples_dir / 'package1.toml')
    assert info.metadata['description'] == \
        "Sample description for test.\n"
    assert info.metadata['description_content_type'] == 'text/x-rst'

def test_missing_description_file():
    with pytest.raises(config.ConfigError, match=r"Description file .* does not exist"):
        config.read_flit_config(samples_dir / 'missing-description-file.toml')

def test_bad_description_extension(caplog):
    info = config.read_flit_config(samples_dir / 'bad-description-ext.toml')
    assert info.metadata['description_content_type'] is None
    assert any((r.levelno == logging.WARN and "Unknown extension" in r.msg)
                for r in caplog.records)

def test_extras():
    info = config.read_flit_config(samples_dir / 'extras.toml')
    requires_dist = set(info.metadata['requires_dist'])
    assert requires_dist == {
        'toml',
        'pytest ; extra == "test"',
        'requests ; extra == "custom"',
    }
    assert set(info.metadata['provides_extra']) == {'test', 'custom'}

def test_extras_dev_conflict():
    with pytest.raises(config.ConfigError, match=r'dev-requires'):
        config.read_flit_config(samples_dir / 'extras-dev-conflict.toml')

def test_extras_dev_warning(caplog):
    info = config.read_flit_config(samples_dir / 'requires-dev.toml')
    assert '"dev-requires = ..." is obsolete' in caplog.text
    assert set(info.metadata['requires_dist']) == {'apackage ; extra == "dev"'}

def test_requires_extra_env_marker():
    info = config.read_flit_config(samples_dir / 'requires-extra-envmark.toml')
    assert info.metadata['requires_dist'][0].startswith('pathlib2 ;')

@pytest.mark.parametrize(('erroneous', 'match'), [
    ({'requires-extra': None}, r'Expected a dict for requires-extra field'),
    ({'requires-extra': dict(dev=None)}, r'Expected a dict of lists for requires-extra field'),
    ({'requires-extra': dict(dev=[1])}, r'Expected a string list for requires-extra'),
])
def test_faulty_requires_extra(erroneous, match):
    metadata = {'module': 'mymod', 'author': '', 'author-email': ''}
    with pytest.raises(config.ConfigError, match=match):
        config._prep_metadata(dict(metadata, **erroneous), None)

@pytest.mark.parametrize(('path', 'err_match'), [
    ('../bar', 'out of the directory'),
    ('foo/../../bar', 'out of the directory'),
    ('/home', 'absolute path'),
    ('foo:bar', 'bad character'),
])
def test_bad_include_paths(path, err_match):
    toml_cfg = {'tool': {'flit': {
        'metadata': {'module': 'xyz', 'author': 'nobody'},
        'sdist': {'include': [path]}
    }}}

    with pytest.raises(config.ConfigError, match=err_match):
        config.prep_toml_config(toml_cfg, None)

@pytest.mark.parametrize(('proj_bad', 'err_match'), [
    ({'version': 1}, r'\bstr\b'),
    ({'license': {'fromage': 2}}, '[Uu]nrecognised'),
    ({'license': {'file': 'LICENSE', 'text': 'xyz'}}, 'both'),
    ({'license': {}}, 'required'),
    ({'keywords': 'foo'}, 'list'),
    ({'keywords': ['foo', 7]}, 'strings'),
    ({'entry-points': {'foo': 'module1:main'}}, 'entry-point.*tables'),
    ({'entry-points': {'group': {'foo': 7}}}, 'entry-point.*string'),
    ({'entry-points': {'gui_scripts': {'foo': 'a:b'}}}, r'\[project\.gui-scripts\]'),
    ({'scripts': {'foo': 7}}, 'scripts.*string'),
    ({'gui-scripts': {'foo': 7}}, 'gui-scripts.*string'),
    ({'optional-dependencies': {'test': 'requests'}}, 'list.*optional-dep'),
    ({'optional-dependencies': {'test': [7]}}, 'string.*optional-dep'),
    ({'dynamic': ['classifiers']}, 'dynamic'),
    ({'dynamic': ['version']}, r'dynamic.*\[project\]'),
    ({'authors': ['thomas']}, r'author.*\bdict'),
    ({'maintainers': [{'title': 'Dr'}]}, r'maintainer.*title'),
])
def test_bad_pep621_info(proj_bad, err_match):
    proj = {'name': 'module1', 'version': '1.0', 'description': 'x'}
    proj.update(proj_bad)
    with pytest.raises(config.ConfigError, match=err_match):
        config.read_pep621_metadata(proj, samples_dir / 'pep621')

@pytest.mark.parametrize(('readme', 'err_match'), [
    ({'file': 'README.rst'}, 'required'),
    ({'file': 'README.rst', 'content-type': 'text/x-python'}, 'content-type'),
    ('/opt/README.rst', 'relative'),
    ({'file': 'README.rst', 'text': '', 'content-type': 'text/x-rst'}, 'both'),
    ({'content-type': 'text/x-rst'}, 'required'),
    ({'file': 'README.rst', 'content-type': 'text/x-rst', 'a': 'b'}, '[Uu]nrecognised'),
    (5, r'readme.*string'),
])
def test_bad_pep621_readme(readme, err_match):
    proj = {
        'name': 'module1', 'version': '1.0', 'description': 'x', 'readme': readme
    }
    with pytest.raises(config.ConfigError, match=err_match):
        config.read_pep621_metadata(proj, samples_dir / 'pep621')


import controller
import time
from hardpotato import *
import numpy as np
import matplotlib.pyplot as plt
import softpotato as sp
from scipy.optimize import curve_fit
import os
from scipy.stats import linregress
import shutil
import serial
import time
import dill
from pathlib import Path

import datetime

number_runs = 5

start_time = time.time()

###make parent folder
experiment_name = "expt1"
parent_dir1 = "C:/Data Path"
# Path
path = os.path.join(parent_dir1, experiment_name)
os.mkdir(path)
print("Directory '% s' created" % experiment_name)
parent_folder = str(path)
######################### GENERATE DUPLICATE CODE ################
# generate filename with timestring
copied_script_name = time.strftime("%Y-%m-%d_%H%M") + "_" + os.path.basename(__file__)
# copy script
shutil.copy(__file__, parent_folder + os.sep + copied_script_name)
##################################################################

############################ setup control board and MUX###############################

####define com ports for controller and MUX + baudrate (keep at 115200 for both)
controllerPort = "COM5"
muxPort = "COM4"
baud_rate = 115200
###setup mux
mux = serial.Serial(port=muxPort, baudrate=baud_rate, timeout=0.1)
###setup controller
setup = controller.Setup(controllerPort, baud_rate)
setup.connect()

#### This section of the code just cycles a couple of states in the multiplexer, it can be deleted (but may cause issues if not present)
mux.write(bytes(str(1), "utf-8"))
msg = mux.readline()
print(msg.decode("utf-8"))
time.sleep(5)
mux.write(bytes(str(3), "utf-8"))
msg = mux.readline()
print(msg.decode("utf-8"))
time.sleep(5)
mux.write(bytes(str(5), "utf-8"))
msg = mux.readline()
print(msg.decode("utf-8"))
time.sleep(5)

###setup serial commands for the macro electrode chip
serialNum = [11, 12, 13, 14, 15, 16, 17, 18]

##########setup pstat ##################3
##### Setup
# Select the potentiostat model to use:
# emstatpico, chi1205b, chi760e
#### Potentiostat setup #####
model = "chi760e"  # Model to use
path_exe = (
    "C:/Potentiostat Path/chi760e.exe"  # Path to the chi760e.exe
)
potentiostat.Setup(model, path_exe, parent_folder)  # Setup

#################### Fluidics parameters ###########################
wait = 10
move = controller.Motor()
power = controller.MainPower()

# Parameters related to peristaltic pumps
p1_new = [
    13.712609063042798,
    0.977763871750637,
    4.104248850640944e-05,
    -4.143399187088928e-08,
]
p1_default = [
    19.801938114061617,
    0.964367848880719,
    1.167139063529185e-05,
    -2.873709837738213e-09,
]
p2_default = [
    11.765533598083050,
    0.994151183002726,
    -2.200584843815698e-05,
    5.268389857671134e-09,
]
p_linear = [0, 1, 0, 0]

disp1_cutoff = 600
disp2_cutoff = 600

########### start of script! #################################################

# Main Power ON
print("\n----MAIN POWER ON----")
power.state("ON")
time.sleep(2)

# Homming
print("\n----NOZZLES HOMING----")
message_home2 = bytes("<homeDisp,0,0>", "UTF-8")
move.send(message_home2)
time.sleep(wait + 15)

print("\n----GANTRY HOMING----")
message_home1 = bytes("<homeGantry,0,0>", "UTF-8")
move.send(message_home1)
time.sleep(wait + 5)

######## Dispense in the dummy cell  + cleaning ######################################################
# Move to the dummy cell
print("\n----Moving to cell 4 (dummy)----")
pos = controller.Position_in_cell(4)
pos.run()
time.sleep(wait + 5)

# Dummy dispensing to remove trapped air bubbles in tubes
print("\n----Dispense in cell 4 (dummy) from Nozzle 1 & 2----")
dispense_1d = controller.Dispense(
    nozzle=1,
    volume=200,
    speed=8000,
    wait_time=[0, 3, 26.4, 3, 0],
    motor_values=[-9000, 20, -2755, 20, 9000],
    p=p_linear,
)
dispense_1d.run()
time.sleep(7)

dispense_2d = controller.Dispense(
    nozzle=2,
    volume=200,
    speed=8000,
    wait_time=[0, 3, 26.4, 3, 0],
    motor_values=[-9000, 20, -2755, 20, 9000],
    p=p_linear,
)
dispense_2d.run()
time.sleep(7)

# Dummy cell suction
suction_only = controller.Rinse_dummy(loop=1, wait_time=[16, 12, 0, 0, 16])
suction_only.run()
time.sleep(5)

######## Move to actual cell  ##########################################################

# Move to the cell
print("\n----Moving to cell 3----")
pos = controller.Position_in_cell(3)
pos.run()
time.sleep(15)

for a in range(number_runs):
    ### dispense 1 mL of Electrolyte first ##############################################
    dispense_2d = controller.Dispense(
        nozzle=2,
        volume=1000,
        speed=8000,
        wait_time=[0, 3, 26.4, 3, 0],
        motor_values=[-9000, 20, -2755, 20, 9000],
        p=p_linear,
    )
    print(f"From nozzle 2, dispensing \033[33m{1000} \033[0muL  \n")
    dispense_2d.run()
    time.sleep(wait)

    ### Argon bubbling #################################################################
    print("\n----\033[31mN2 bubbling\033[0m----")
    n2_bubbling = controller.N2(loop=1, nozzle=2, wait_time=[12, 3, 12], mode="dual")
    n2_bubbling.run()
    time.sleep(7)

    ### Main Power OFF #################################################################
    print("\n----MAIN POWER OFF----")
    power.state("OFF")
    time.sleep(15)

    ########### echem with just electrolyte ######################################################
    ##### Experimental parameters:
    Ei = -0.2  # V, initial potential
    Eh = 0.3  # V, first vertex potential
    El = -0.2  # V, second vertex potential
    nSweeps = 2  # number of sweeps
    sens = 1e-7  # A/V, current sensitivity                              ### CHANGE THIS IF NEEDED
    header = "CV"  # header for data file
    ##### Experiment:
    sr = np.array([0.1, 0.15, 0.2, 0.25, 0.3])  # V/s, scan rate
    for y in serialNum:
        mux.write(bytes(str(y), "utf-8"))
        msg = mux.readline()
        print(msg.decode("utf-8"))
        time.sleep(5)
        for x in range(sr.size):
            # initialize experiment:
            fileName_CV = f"0mM_Electrode{y-10}_{int(sr[x]*1000)}mVs_CV_{a+1}"  # base file name for data file
            cv = potentiostat.CV(
                Eini=Ei,
                Ev1=Eh,
                Ev2=El,
                Efin=Ei,
                sr=sr[x],
                sens=sens,
                dE=0.001,
                nSweeps=2,
                qt=2,
                fileName=fileName_CV,
            )
            # Run experiment:
            cv.run()
            data = load_data.CV(fileName_CV + ".txt", parent_folder, model)
            # load data to do the data analysis later

    ####################################### cleaning ##############################################
    ### Main Power ON #############################################################################
    print("\n----MAIN POWER ON----")
    power.state("ON")
    time.sleep(5)

    ### Initial Electrode Rinsing #################################################################
    ## "wait_time" in Rinse function (0 will skip the step, and below is the sequence)
    ## (1) Down / [LOOP start [ (2) suction / (3) flush / (4) suction] LOOP end] / (5) Up
    ## = [16, 12, 15, 12, 16]
    rinse = controller.Rinse(
        loop=3, wait_time=[16, 12, 15, 12, 16]
    )  # change the number of loops if needed
    rinse.run()
    time.sleep(5)

    ### Electrode strong rinsing / bubbling / drying (SR) ###############################################
    # (SR1) Filling reservoir with solvent
    print("\n----\033[31m Filling reservoir with solvent \033[0m----")
    filling_only = controller.Rinse(loop=1, wait_time=[16, 0, 15, 0, 16])
    filling_only.run()

    # (SR2) Argon bubbling
    print("\n----\033[31mN2 bubbling\033[0m----")
    n2_bubbling = controller.N2(loop=1, nozzle=2, wait_time=[12, 3, 12], mode="dual")
    n2_bubbling.run()
    time.sleep(7)

    # (SR3) Suction only
    suction_only = controller.Rinse(loop=1, wait_time=[16, 12, 0, 0, 16])
    suction_only.run()
    time.sleep(7)

    # (SR4) Argon drying
    print("\n----\033[31mN2 drying\033[0m----")
    n2_drying = controller.N2(loop=1, nozzle=1, wait_time=[12, 3, 12], mode="single")
    n2_drying.run()
    time.sleep(10)

    ### dispense 1 mL of FcMeOh ########################################################################
    dispense_1d = controller.Dispense(
        nozzle=1,
        volume=1000,
        speed=8000,
        wait_time=[0, 3, 26.4, 3, 0],
        motor_values=[-9000, 20, -2755, 20, 9000],
        p=p_linear,
    )
    print(f"From nozzle 1, dispensing \033[33m{1000} \033[0muL  \n")
    dispense_1d.run()
    time.sleep(wait)

    ### Argon bubbling #################################################################################
    print("\n----\033[31mN2 bubbling\033[0m----")
    n2_bubbling = controller.N2(loop=1, nozzle=2, wait_time=[12, 3, 12], mode="dual")
    n2_bubbling.run()
    time.sleep(7)

    ### Main Power OFF ##################################################################################
    print("\n----MAIN POWER OFF----")
    power.state("OFF")
    time.sleep(15)

    ########### echem with fcmeoh #######################################################################
    ##### Experimental parameters:
    Ei = -0.2  # V, initial potential
    Eh = 0.3  # V, first vertex potential
    El = -0.2  # V, second vertex potential
    nSweeps = 2  # number of sweeps
    sens = 1e-7  # A/V, current sensitivity                              ### (2) CHANGE THIS !!!!
    header = "CV"  # header for data file
    ##### Experiment:
    sr = np.array([0.1, 0.15, 0.2, 0.25, 0.3])  # V/s, scan rate
    for y in serialNum:
        mux.write(bytes(str(y), "utf-8"))
        msg = mux.readline()
        print(msg.decode("utf-8"))
        time.sleep(5)
        for x in range(sr.size):
            # initialize experiment:
            fileName_CV = f"1mM_Electrode{y-10}_{int(sr[x]*1000)}mVs_CV_{a+1}"  # base file name for data file
            cv = potentiostat.CV(
                Eini=Ei,
                Ev1=Eh,
                Ev2=El,
                Efin=Ei,
                sr=sr[x],
                sens=sens,
                dE=0.001,
                nSweeps=2,
                qt=2,
                fileName=fileName_CV,
            )
            # Run experiment:
            cv.run()
            data = load_data.CV(fileName_CV + ".txt", parent_folder, model)
            # load data to do the data analysis later

    ####################################### cleaning ##############################################
    # Main Power ON
    print("\n----MAIN POWER ON----")
    power.state("ON")
    time.sleep(5)

    ### Initial Electrode Rinsing #################################################################
    ## "wait_time" in Rinse function (0 will skip the step, and below is the sequence)
    ## (1) Down / [LOOP start [ (2) suction / (3) flush / (4) suction] LOOP end] / (5) Up
    ## = [16, 12, 15, 12, 16]

    rinse = controller.Rinse(
        loop=3, wait_time=[16, 12, 15, 12, 16]
    )  # change the number of loops if needed
    rinse.run()
    time.sleep(5)

    ### Electrode strong rinsing / bubbling / drying (SR) ###############################################
    # (SR1) Filling reservoir with solvent
    print("\n----\033[31m Filling reservoir with solvent \033[0m----")
    filling_only = controller.Rinse(loop=1, wait_time=[16, 0, 15, 0, 16])
    filling_only.run()

    # (SR2) Argon bubbling
    print("\n----\033[31mN2 bubbling\033[0m----")
    n2_bubbling = controller.N2(loop=1, nozzle=2, wait_time=[12, 3, 12], mode="dual")
    n2_bubbling.run()
    time.sleep(7)

    # (SR3) Suction only
    suction_only = controller.Rinse(loop=1, wait_time=[16, 12, 0, 0, 16])
    suction_only.run()
    time.sleep(7)

    # (SR4) Argon drying
    print("\n----\033[31mN2 drying\033[0m----")
    n2_drying = controller.N2(loop=1, nozzle=1, wait_time=[12, 3, 12], mode="single")
    n2_drying.run()
    time.sleep(10)

########## Main Power OFF ##################################################################################
print("\n----MAIN POWER OFF----")
power.state("OFF")
time.sleep(10)

print("Finished")
setup.disconnect()

print("\n----\033[31m Print the total time duration \033[0m----")
end_time = time.time()
total_time = end_time - start_time
total_time_list = str(datetime.timedelta(seconds=total_time)).split(".")
print(total_time_list[0])  # Hrs:Mins:Secs format


from django import forms
from django.contrib.admin import register, ModelAdmin
from django.urls import path, reverse
from django.utils.html import format_html
from django_mptt_admin.admin import DjangoMpttAdmin
from leaflet.admin import LeafletGeoAdmin
import logging
from reversion.admin import VersionAdmin
from threading import Thread
import time

from .models import DepartmentUser, Location, OrgUnit, CostCentre
from .views import DepartmentUserExport, DepartmentUserDiscrepancyReport

LOGGER = logging.getLogger('sync_tasks')

def delayed_save(obj):
    """Wait one second, then call save() for the passed-in object.
    """
    time.sleep(1)
    obj.save()

class DepartmentUserForm(forms.ModelForm):

    class Meta:
        model = DepartmentUser
        exclude = []

    def clean_ad_guid(self):
        return self.cleaned_data['ad_guid'] or None

    def clean_employee_id(self):
        if self.cleaned_data['employee_id'] == '':
            return None
        else:
            return self.cleaned_data['employee_id']

@register(DepartmentUser)
class DepartmentUserAdmin(VersionAdmin):
    # Override the default reversion/change_list.html template:
    change_list_template = 'admin/organisation/departmentuser/change_list.html'
    form = DepartmentUserForm
    list_display = [
        'email', 'title', 'employee_id', 'username', 'active', 'vip', 'executive',
        'cost_centre', 'account_type', 'o365_licence']
    list_filter = [
        'account_type', 'active', 'vip', 'executive', 'shared_account',
        'o365_licence']
    search_fields = ['name', 'email', 'username', 'employee_id', 'preferred_name']
    raw_id_fields = ['parent', 'cost_centre', 'org_unit']
    filter_horizontal = ['secondary_locations']
    readonly_fields = [
        'username', 'org_data_pretty', 'ad_data_pretty',
        'active', 'in_sync', 'ad_deleted', 'date_ad_updated',
        'alesco_data_pretty', 'o365_licence', 'shared_account', 'date_hr_term']
    fieldsets = (
        ('Email/username', {
            'fields': ('email', 'username'),
        }),
        ('Name and organisational fields', {
            'description': '''
Do not edit information in this section
            without written permission from People Services or the cost centre manager
            (forms are required).
''',
            'fields': (
                'given_name', 'surname', 'name', 'employee_id', 'cost_centre',
                'org_unit', 'location', 'parent', 'security_clearance', 'name_update_reference'),
        }),
        ('Account fields', {
            'fields': ('account_type', 'expiry_date', 'date_hr_term', 'hr_auto_expiry', 'contractor', 'notes'),
        }),
        ('Other details', {
            'fields': (
                'vip', 'executive', 'populate_primary_group',
                'preferred_name', 'photo', 'title', 'position_type',
                'telephone', 'mobile_phone', 'extension', 'other_phone',
                'secondary_locations', 'working_hours', 'extra_data',
            )
        }),
        ('AD sync and HR data', {
            'fields': (
                'ad_guid',
                'ad_dn',
                'azure_guid',
                'active', 'in_sync', 'ad_deleted', 'date_ad_updated',
                'o365_licence', 'shared_account',
                'org_data_pretty', 'ad_data_pretty', 'alesco_data_pretty',
            )
        })
    )

    def save_model(self, request, obj, form, change):
        """Override save_model in order to log any changes to some fields:
        'given_name', 'surname', 'employee_id', 'cost_centre', 'name', 'org_unit', 'photo'
        """
        l = 'DepartmentUser: {}, field: {}, original_value: {} new_value: {}, changed_by: {}, reference: {}'
        if obj._DepartmentUser__original_given_name != obj.given_name:
            LOGGER.info(l.format(
                obj.email, 'given_name', obj._DepartmentUser__original_given_name, obj.given_name,
                request.user.username, obj.name_update_reference
            ))
        if obj._DepartmentUser__original_surname != obj.surname:
            LOGGER.info(l.format(
                obj.email, 'surname', obj._DepartmentUser__original_surname, obj.surname,
                request.user.username, obj.name_update_reference
            ))
        if obj._DepartmentUser__original_employee_id != obj.employee_id:
            LOGGER.info(l.format(
                obj.email, 'employee_id', obj._DepartmentUser__original_employee_id,
                obj.employee_id, request.user.username, obj.name_update_reference
            ))
        if obj._DepartmentUser__original_cost_centre_id != obj.cost_centre_id:
            LOGGER.info(l.format(
                obj.email, 'cost_centre', CostCentre.objects.filter(id=obj._DepartmentUser__original_cost_centre_id).first(),
                obj.cost_centre, request.user.username, obj.name_update_reference
            ))
        if obj._DepartmentUser__original_name != obj.name:
            LOGGER.info(l.format(
                obj.email, 'name', obj._DepartmentUser__original_name, obj.name,
                request.user.username, obj.name_update_reference
            ))
        if obj._DepartmentUser__original_org_unit_id != obj.org_unit_id:
            LOGGER.info(l.format(
                obj.email, 'org_unit', OrgUnit.objects.filter(id=obj._DepartmentUser__original_org_unit_id).first(), obj.org_unit,
                request.user.username, obj.name_update_reference
            ))
        if obj._DepartmentUser__original_expiry_date != obj.expiry_date:
            LOGGER.info(l.format(
                obj.email, 'expiry_date', obj._DepartmentUser__original_expiry_date, obj.expiry_date,
                request.user.username, obj.name_update_reference
            ))
        # Shrink photo for AD, if it changed.
        if obj._DepartmentUser__original_photo != obj.photo:
            LOGGER.info(l.format(
                obj.email, 'photo', obj._DepartmentUser__original_photo, obj.photo,
                request.user.username, obj.name_update_reference
            ))
            obj.update_photo_ad()

        obj.save()

        # NOTE: following a change to a DepartmentUser object, we need to call
        # save a second time so that the org_data field is correct. The lines
        # below will do so in a separate thread.
        t = Thread(target=delayed_save, args=(obj,))
        t.start()

    def get_urls(self):
        urls = super(DepartmentUserAdmin, self).get_urls()
        urls = [
            path('export/', DepartmentUserExport.as_view(), name='departmentuser_export'),
            path('departmentuser-discrepancy-report/', DepartmentUserDiscrepancyReport.as_view(), name='departmentuser_discrepancy_report'),
        ] + urls
        return urls

@register(Location)
class LocationAdmin(LeafletGeoAdmin):
    list_display = ('name', 'address', 'phone', 'fax', 'email', 'manager')
    list_filter = ('active',)
    raw_id_fields = ('manager',)
    search_fields = ('name', 'address', 'phone', 'fax', 'email', 'manager__email')
    settings_overrides = {
        'DEFAULT_CENTER': (-31.0, 115.0),
        'DEFAULT_ZOOM': 5
    }

@register(OrgUnit)
class OrgUnitAdmin(DjangoMpttAdmin):
    tree_auto_open = True
    tree_load_on_demand = False
    list_display = (
        'name', 'unit_type', 'users', 'members', 'it_systems', 'cc', 'acronym',
        'manager')
    search_fields = ('name', 'acronym', 'manager__name', 'location__name')
    raw_id_fields = ('manager', 'parent', 'location')
    list_filter = ('unit_type', 'active')

    def users(self, obj):
        from organisation.models import DepartmentUser
        dusers = obj.departmentuser_set.filter(**DepartmentUser.ACTIVE_FILTER)
        return format_html(
            '{}',
            reverse('admin:organisation_departmentuser_changelist'),
            obj.pk, dusers.count())

    def members(self, obj):
        return format_html(
            '{}',
            reverse('admin:organisation_departmentuser_changelist'),
            ','.join([str(o.pk)
                      for o in obj.get_descendants(include_self=True)]),
            obj.members().count()
        )

    def it_systems(self, obj):
        return format_html(
            '{}',
            reverse('admin:registers_itsystem_changelist'),
            obj.pk, obj.itsystem_set.count())

@register(CostCentre)
class CostCentreAdmin(ModelAdmin):
    list_display = (
        'name', 'code', 'chart_acct_name', 'org_position', 'division', 'users', 'manager',
        'business_manager', 'admin', 'tech_contact', 'active')
    search_fields = (
        'name', 'code', 'chart_acct_name', 'org_position__name', 'division__name',
        'org_position__acronym', 'division__acronym')
    list_filter = ('active', 'chart_acct_name')
    raw_id_fields = (
        'org_position', 'manager', 'business_manager', 'admin', 'tech_contact')

    def users(self, obj):
        return format_html(
            '{}',
            reverse('admin:organisation_departmentuser_changelist'),
            obj.pk, obj.departmentuser_set.count())


import argparse
import cv2

ap=argparse.ArgumentParser()
ap.add_argument("-i", "--image", required = True, help='Path to the image')
args=vars(ap.parse_args())

image=cv2.imread(args["image"])
print("width: %d pixels" % (image.shape[1])) #goruntunun boyutlarini inceler
print("height: %d pixels" % (image.shape[0]))#bu incelemeyi shape ile yapar
print("channels: %d" % (image.shape[2]))

cv2.imshow("image",image)
cv2.waitKey(0)
cv2.imwrite("newimage.jpg",image)


import requests

# Make a GET request to the API endpoint
response = requests.get('https://api.adzuna.com/v1/api/jobs/us/search/1?app_id=cc3c6bd4&app_key=3fe3e17eff25c1091b93ff10a8f6a8f3&results_per_page=6')

# Parse the JSON response
data = response.json()

# Extract the information from each job
jobs = data['results']
for job in jobs:
    # Extract category information
    category_label = job['category']['label']

    # Extract company information
    company_display_name = job['company']['display_name']
    #company_contract_time = job['contract_time']
    company_created = job['created']
    company_description = job['description']

    # Extract location information
    location_area = job['location']['area']

    # Extract salary information
    salary_max = job['salary_max']

    title = job['title']

    # Print the extracted information
    print('Category:', category_label)
    print('Company Display Name:', company_display_name)
    print('Title:', title)
    print('Company Created:', company_created)
    print('Company Description:', company_description)
    print('Location Area:', location_area)
    print('Salary Max:', salary_max)
    print('\n')


#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# @Description:
# @PreInstall:
# @Author : claer
# @File : time_util.py
# @Version: 1.0.0
# @Time : 2019/9/25 18:49
# @Project: scripts_python
# @Package:
# @Software: PyCharm
import datetime
import time

def get_every_day(begin_date, end_date):
    """
    获取两个日期间的所有日期
    :param begin_date:
    :param end_date:
    :return:
    """
    date_list = []
    begin_date = datetime.datetime.strptime(begin_date, "%Y-%m-%d")
    end_date = datetime.datetime.strptime(end_date, "%Y-%m-%d")
    while begin_date <= end_date:
        date_str = begin_date.strftime("%Y-%m-%d")
        date_list.append(date_str)
        begin_date += datetime.timedelta(days=1)
    return date_list

def date_compare_to(begin_date, end_date):
    """
    比较两个日期大小
    :param begin_date:
    :param end_date:
    :return: 返回0为相等，1为begin比end大，-1为begin比end小
    """
    begin_date = datetime.datetime.strptime(begin_date, "%Y-%m-%d")
    end_date = datetime.datetime.strptime(end_date, "%Y-%m-%d")
    if begin_date == end_date:
        return 0
    elif begin_date < end_date:
        return -1
    else:
        return 1

def time_compare_to(begin_time, end_time):
    """
    比较两个时间大小
    :param begin_time:
    :param end_time:
    :return: 返回0为相等，1为begin比end大，-1为begin比end小
    """
    begin_time = time.strftime("%Y-%m-%d-%H_%M_%S", begin_time)
    end_time = time.strftime("%Y-%m-%d-%H_%M_%S", end_time)
    if begin_time == end_time:
        return 0
    elif begin_time < end_time:
        return -1
    else:
        return 1


import cv2
import time
import sys
import traceback
import numpy as np
from .utils import EasyDict

from rich import print
import slideflow as sf
from slideflow.util import model_backend

if sf.util.tf_available:
    import tensorflow as tf
    import slideflow.io.tensorflow
    gpus = tf.config.experimental.list_physical_devices('GPU')
    for gpu in gpus:
        try:
            tf.config.experimental.set_memory_growth(gpu, True)
        except RuntimeError:
            pass
if sf.util.torch_available:
    import torch
    import torchvision
    import slideflow.io.torch

#----------------------------------------------------------------------------

class CapturedException(Exception):
    def __init__(self, msg=None):
        if msg is None:
            _type, value, _traceback = sys.exc_info()
            assert value is not None
            if isinstance(value, CapturedException):
                msg = str(value)
            else:
                msg = traceback.format_exc()
        assert isinstance(msg, str)
        super().__init__(msg)

#----------------------------------------------------------------------------

class CaptureSuccess(Exception):
    def __init__(self, out):
        super().__init__()
        self.out = out

#----------------------------------------------------------------------------

def _reduce_dropout_preds_torch(yp_drop, num_outcomes, stack=True):
    if num_outcomes > 1:
        if stack:
            yp_drop = [torch.stack(yp_drop[n], dim=0) for n in range(num_outcomes)]
        else:
            yp_drop = [yp_drop[0] for n in range(num_outcomes)]
        yp_mean = [torch.mean(yp_drop[n], dim=0) for n in range(num_outcomes)]
        yp_std = [torch.std(yp_drop[n], dim=0) for n in range(num_outcomes)]
    else:
        if stack:
            yp_drop = torch.stack(yp_drop[0], dim=0)  # type: ignore
        else:
            yp_drop = yp_drop[0]
        yp_mean = torch.mean(yp_drop, dim=0)  # type: ignore
        yp_std = torch.std(yp_drop, dim=0)  # type: ignore
    return yp_mean, yp_std

def _reduce_dropout_preds_tf(yp_drop, num_outcomes, stack=True):
    if num_outcomes > 1:
        if stack:
            yp_drop = [tf.stack(yp_drop[n], axis=0) for n in range(num_outcomes)]
        else:
            yp_drop = [yp_drop[0] for n in range(num_outcomes)]
        yp_mean = [tf.math.reduce_mean(yp_drop[n], axis=0).numpy() for n in range(num_outcomes)]
        yp_std = [tf.math.reduce_std(yp_drop[n], axis=0).numpy() for n in range(num_outcomes)]
    else:
        if stack:
            yp_drop = tf.stack(yp_drop[0], axis=0)
        else:
            yp_drop = yp_drop[0]
        yp_mean = tf.math.reduce_mean(yp_drop, axis=0).numpy()
        yp_std = tf.math.reduce_std(yp_drop, axis=0).numpy()
    return yp_mean, yp_std

def _decode_jpeg(img, _model_type):
    if _model_type in ('tensorflow', 'tflite'):
        return tf.image.decode_jpeg(img, channels=3)
    else:
        np_data = torch.from_numpy(np.fromstring(img, dtype=np.uint8))
        return torchvision.io.decode_image(np_data)

def _umap_normalize(vector, clip_min, clip_max, norm_min, norm_max):
    vector = np.clip(vector, clip_min, clip_max)
    vector -= norm_min
    vector /= (norm_max - norm_min)
    return vector

#----------------------------------------------------------------------------

class Renderer:
    def __init__(self, device=None, buffer=None, extract_px=None, tile_px=None):
        #self._device            = torch.device('cuda')
        self._pkl_data          = dict()    # {pkl: dict | CapturedException, ...}
        self._pinned_bufs       = dict()    # {(shape, dtype): torch.Tensor, ...}
        self._cmaps             = dict()    # {name: torch.Tensor, ...}
        self._is_timing         = False
        #self._start_event       = torch.cuda.Event(enable_timing=True)
        #self._end_event         = torch.cuda.Event(enable_timing=True)
        self._net_layers        = dict()
        self._uq_thread         = None
        self._model             = None
        self._saliency          = None
        self._buffer            = buffer
        self.extract_px         = extract_px
        self.tile_px            = tile_px
        self.device             = device
        self._umap_encoders     = None
        self._addl_renderers    = []

    @property
    def model_type(self):
        if self._model is None:
            return None
        else:
            return model_backend(self._model)

    def process_tf_preds(self, preds):
        if isinstance(preds, list):
            return [self.to_numpy(p[0]) for p in preds]
        else:
            return self.to_numpy(preds[0])

    def to_numpy(self, x):
        if self.model_type in ('tensorflow', 'tflite'):
            return x.numpy()
        else:
            return x.cpu().detach().numpy()

    def add_renderer(self, renderer):
        self._addl_renderers += [renderer]

    def render(self, **args):
        self._is_timing = True
        #self._start_event.record(torch.cuda.current_stream(self._device))
        self._start_time = time.time()
        res = EasyDict()
        try:
            self._render_impl(res, **args)
        except:
            res.error = CapturedException()
        #self._end_event.record(torch.cuda.current_stream(self._device))
        if 'error' in res:
            res.error = str(res.error)
        if self._is_timing:
            #self._end_event.synchronize()
            res.render_time = time.time() - self._start_time #self._start_event.elapsed_time(self._end_event) * 1e-3
            self._is_timing = False
        return res

    def _ignore_timing(self):
        self._is_timing = False

    def _calc_preds_and_uncertainty(self, img, uq_n=30):

        if self.model_type in ('tensorflow', 'tflite'):
            yp = self._model(tf.repeat(img, repeats=uq_n, axis=0), training=False)
            reduce_fn = _reduce_dropout_preds_tf
        else:
            yp = self._model(torch.repeat(img, repeats=uq_n, dim=0), training=False)
            reduce_fn = _reduce_dropout_preds_torch

        num_outcomes = 1 if not isinstance(yp, list) else len(yp)
        yp_drop = {n: [] for n in range(num_outcomes)}
        if num_outcomes > 1:
            for o in range(num_outcomes):
                yp_drop[o] = yp[o]
        else:
            yp_drop[0] = yp
        yp_mean, yp_std = reduce_fn(yp_drop, num_outcomes, stack=False)
        if num_outcomes > 1:
            uncertainty = [np.mean(s) for s in yp_std]
        else:
            uncertainty = np.mean(yp_std)
        predictions = yp_mean
        return predictions, uncertainty

    def _classify_img(self, img, use_uncertainty=False):
        """Classify an image, returning predictions and uncertainty.

        Args:
            img (_type_): _description_

        Returns:
            Predictions, Uncertainty
        """
        if self.model_type in ('tensorflow', 'tflite'):
            img = tf.expand_dims(img, axis=0)
        elif self.model_type == 'torch':
            img = torch.unsqueeze(img, dim=0)

        if use_uncertainty:
            return self._calc_preds_and_uncertainty(img)
        elif self.model_type == 'tflite':
            sig_name = list(self._model._inputs.keys())[0]
            preds = self._model(**{sig_name: img})['output']
            if isinstance(preds, list):
                preds = [p[0] for p in preds]
            else:
                preds = preds[0]
        else:
            preds = self._model(img)
            preds = self.process_tf_preds(preds)
        return preds, None

    def _render_impl(self, res,
        x                   = 0,
        y                   = 0,
        saliency_overlay    = False,
        saliency_method     = 0,
        img_format          = None,
        use_model           = False,
        use_uncertainty     = False,
        use_saliency        = False,
        normalizer          = None,
        viewer              = None,
        tile_px             = None,
        tile_um             = None,
        full_image          = None,
        use_umap_encoders   = False,
        **kwargs
    ):
        args = locals()
        del args['kwargs']
        del args['self']
        args.update(kwargs)
        args['use_model'] = False
        for renderer in self._addl_renderers:
            renderer._render_impl(**args)
        if (x is None or y is None) and 'image' not in res:
            return
        if full_image is not None:
            img = cv2.resize(full_image, (tile_px, tile_px))
            res.image = img
        elif viewer is not None:

            if not self._model:
                res.message = "Model not loaded"
                print(res.message)
                return

            res.predictions = None
            res.uncertainty = None

            if self.model_type in ('tensorflow', 'tflite'):
                dtype = tf.uint8
            elif self.model_type == 'torch':
                dtype = torch.uint8

            use_jpeg = use_model and img_format is not None and img_format.lower() in ('jpg', 'jpeg')
            img = viewer.read_tile(x, y, img_format='jpg' if use_jpeg else None, allow_errors=True)
            if img is None:
                res.message = "Invalid tile location."
                print(res.message)
                return
            if use_jpeg:
                img = _decode_jpeg(img, self.model_type)
                if self.model_type == 'torch':
                    res.image = sf.io.torch.cwh_to_whc(img).numpy()
                res.image = img.numpy()
                img = sf.io.convert_dtype(img, dtype)
            else:
                res.image = img
        elif 'image' in res and use_model:
            # Image was generated by one of the additional renderers.
            # Check if any additional pre-processing needs to be done.
            img = res.image
            for renderer in self._addl_renderers:
                if hasattr(renderer, 'preprocess'):
                    img = renderer.preprocess(img, tile_px=tile_px, tile_um=tile_um)

        if use_model:
            if self.model_type in ('tensorflow', 'tflite') and isinstance(img, np.ndarray):
                proc_img = tf.convert_to_tensor(img)
            elif isinstance(img, np.ndarray):
                proc_img = sf.io.torch.whc_to_cwh(torch.from_numpy(img)).to(self.device)
            else:
                proc_img = img

            # Pre-process image.
            if normalizer:
                _norm_start = time.time()
                proc_img = normalizer.transform(proc_img)
                if not isinstance(proc_img, np.ndarray):
                    if self.model_type == 'torch':
                        res.normalized = sf.io.torch.cwh_to_whc(proc_img).numpy().astype(np.uint8)
                    else:
                        res.normalized = proc_img.numpy().astype(np.uint8)
                else:
                    res.normalized = proc_img.astype(np.uint8)
                res.norm_time = time.time() - _norm_start
            if self.model_type in ('tensorflow', 'tflite'):
                proc_img = sf.io.tensorflow.preprocess_uint8(proc_img, standardize=True)['tile_image']
            elif self.model_type == 'torch':
                proc_img = sf.io.torch.preprocess_uint8(proc_img, standardize=True)
                if self.device is not None:
                    proc_img = proc_img.to(self.device)

            # Saliency.
            if use_saliency:
                mask = self._saliency.get(self.to_numpy(proc_img), method=saliency_method)
                if saliency_overlay:
                    res.image = sf.grad.plot_utils.overlay(res.image, mask)
                else:
                    res.image = sf.grad.plot_utils.inferno(mask)
                if res.image.shape[-1] == 4:
                    res.image = res.image[:, :, 0:3]

            # Show predictions.
            _inference_start = time.time()
            if use_umap_encoders:
                u = self._umap_encoders
                encoder_out = u.encoder(tf.expand_dims(proc_img, axis=0))
                res.umap_coords = {}
                for i, layer in enumerate(u.layers):
                    res.umap_coords[layer] = _umap_normalize(
                        encoder_out[i],
                        clip_min=u.clip[layer][0],
                        clip_max=u.clip[layer][1],
                        norm_min=u.range[layer][0],
                        norm_max=u.range[layer][1]
                    )[0]
                res.predictions = self.process_tf_preds(encoder_out[-1])
                res.uncertainty = None
            else:
                res.predictions, res.uncertainty = self._classify_img(proc_img, use_uncertainty=use_uncertainty)
            res.inference_time = time.time() - _inference_start

#----------------------------------------------------------------------------