from __future__ import print_function

import os.path
import sys

from Bio._py3k import range

VERSIONS = ["4_1", "4_3", "4_4", "4_4c", "4_5", "4_6", "4_7", "4_8", "4_9a"]

def codeml(vers=None, verbose=False):
    from Bio.Phylo.PAML import codeml
    if vers is not None:
        versions = [vers]
    else:
        versions = VERSIONS
    tests = [("aa_model0", "aa_alignment.phylip", "species.tree"),
             ("aa_pairwise", "aa_alignment.phylip", "species.tree"),
             ("all_NSsites", "alignment.phylip", "species.tree"),
             ("branchsiteA", "alignment.phylip", "species.tree"),
             ("clademodelC", "alignment.phylip", "species.tree"),
             ("freeratio", "alignment.phylip", "species.tree"),
             ("ngene2_mgene02", "lysinYangSwanson2002.nuc", "lysin.trees"),
             ("ngene2_mgene34", "lysinYangSwanson2002.nuc", "lysin.trees"),
             ("pairwise", "alignment.phylip", "species.tree"),
             ("SE", "alignment.phylip", "species.tree"),
             ("m2a_rel", "alignment.phylip", "species.tree")]

    for test in tests:
        print(test[0])
        cml = codeml.Codeml()
        cml.working_dir = "temp"
        ctl_file = os.path.join("Control_files",
                                "codeml",
                                '.'.join([test[0], "ctl"]))
        alignment = os.path.join("Alignments", test[1])
        tree = os.path.join("Trees", test[2])
        cml.read_ctl_file(ctl_file)
        cml.alignment = alignment
        cml.tree = tree
        for version in versions:
            # M2a_rel (NSsites 22) was introduced in PAML 4.6
            if test[0] == "m2a_rel" and int(version.split("_")[1][0]) < 6:
                continue
            print("\t{0}".format(version.replace('_', '.')))
            if test[0] in ["ngene2_mgene02", "ngene2_mgene34"] and \
               version == "4_6":
                cml.tree = ".".join([cml.tree, "4.6"])
            out_file = '.'.join(['-'.join([test[0], version]), "out"])
            cml.out_file = os.path.join("Results", "codeml", test[0], out_file)
            bin = ''.join(["codeml", version])
            cml.run(command=bin, verbose=verbose)

def baseml(vers=None, verbose=False):
    from Bio.Phylo.PAML import baseml
    if vers is not None:
        versions = [vers]
    else:
        versions = VERSIONS
    tests = [("model", list(range(0, 9))), ("nhomo", [1, 3, 4]),
             ("nparK", list(range(1, 5))), ("alpha1rho1", None), ("SE", None)]
    alignment = os.path.join("Alignments", "alignment.phylip")
    tree = os.path.join("Trees", "species.tree")
    for test in tests:
        print(test[0])
        bml = baseml.Baseml()
        for version in versions:
            print("\t{0}".format(version.replace('_', '.')))
            if test[1] is not None:
                for n in test[1]:
                    if (version in ["4_3", "4_4", "4_4c", "4_5"] and
                            test[0] == "nparK" and n in [3, 4]):
                        continue
                    print("\t\tn = {0}".format(n))
                    ctl_file = (os.path.join("Control_files", "baseml",
                                "{0}{1}.ctl".format(test[0], n)))
                    bml.read_ctl_file(ctl_file)
                    bml.alignment = alignment
                    bml.tree = tree
                    out_file = "{0}{1}-{2}.out".format(test[0], n, version)
                    bml.out_file = (os.path.join("Results", "baseml", test[0],
                                    out_file))
                    bin = "baseml{0}".format(version)
                    bml.run(command=bin, verbose=verbose)
            else:
                if (version in ["4_3", "4_4", "4_4c", "4_5"] and
                        test[0] == "alpha1rho1"):
                    continue
                ctl_file = (os.path.join("Control_files", "baseml",
                            "{0}.ctl".format(test[0])))
                bml.read_ctl_file(ctl_file)
                bml.alignment = alignment
                bml.tree = tree
                out_file = "{0}-{1}.out".format(test[0], version)
                bml.out_file = (os.path.join("Results", "baseml", test[0],
                                out_file))
                bin = "baseml{0}".format(version)
                bml.run(command=bin, verbose=verbose)

def yn00(vers=None, verbose=False):
    from Bio.Phylo.PAML import yn00
    if vers is not None:
        versions = [vers]
    else:
        versions = VERSIONS
    tests = ["yn00", "yn00_long"]
    for test in tests:
        print(test[0])
        yn = yn00.Yn00()
        for version in versions:
            print("\t{0}".format(version.replace('_', '.')))
            ctl_file = (os.path.join("Control_files", "yn00",
                        "{0}.ctl".format(test)))
            yn.read_ctl_file(ctl_file)
            out_file = "{0}-{1}.out".format(test, version)
            yn.out_file = os.path.join("Results", 'yn00', out_file)
            bin = "yn00{0}".format(version)
            yn.run(command=bin, verbose=verbose)

def print_usage():
    versions = ", ".join(vers.replace("_", ".") for vers in VERSIONS)
    usage = """Usage: gen_results.py [-v] PROGRAM [VERSION]

Generate result files to be used in Bio.Phylo.PAML unit tests.

  -v         Use verbose output
  PROGRAM    codeml, baseml or yn00
  VERSION    %s

To use this, the PAML programs must be in your executable path and
they must be named programX_Y, where X and Y are the version numbers
(i.e. baseml4_5 or codeml4_4c). If VERSION is not specified, test
results will be generated for all versions listed above.
""" % (versions)
    sys.exit(usage)

if __name__ == "__main__":
    programs = ["codeml", "baseml", "yn00"]
    prog = None
    verbose = False
    vers = None
    if len(sys.argv) < 2:
        print_usage()
    for arg in sys.argv[1:]:
        if arg == "-v":
            verbose = True
        elif arg in programs:
            if prog is not None:
                print("Only one program at a time, please.")
                print_usage()
            prog = arg
        elif arg.replace(".", "_") in VERSIONS:
            if vers is not None:
                print("Only one version at a time, sorry.")
            vers = arg.replace(".", "_")
        else:
            print("Unrecognized argument")
            print_usage()
    if prog is None:
        print("No program specified")
        print_usage()
    if prog == "codeml":
        codeml(vers, verbose)
    elif prog == "baseml":
        baseml(vers, verbose)
    elif prog == "yn00":
        yn00(vers, verbose)


import logging
from itertools import chain
from typing import Tuple
from bdo_coupon_scanner.scanners.site_scanner import OfficialSiteScanner
from bdo_coupon_scanner.scanners.twitter_scanner import TwitterScanner
from time import perf_counter
from ..db import DatabaseTransaction
from ..db.coupons import Coupon

def remove_duplicates_by_key(selector, items):
    history = []
    for x in items:
        key = selector(x)
        seen = False
        for old_key in history:
            if key != old_key:
                continue
            seen = True
        if seen:
            continue
        history.append(key)
        yield x

async def get_new_codes(save_to_db: bool) -> Tuple[list[Coupon], float]:
    log = logging.getLogger(__name__)
    start_t = perf_counter()

    codes = []
    try:
        site_codes = OfficialSiteScanner().get_codes()
        codes = chain(codes, site_codes)
        log.debug(f"Site codes: {site_codes}")
    except Exception:
        log.error("Could not get site codes!")

    try:
        log.debug(f"Code chain before 2 scan: {codes}")
        twitter_codes = TwitterScanner().get_codes()
        codes = chain(codes, twitter_codes)
        log.debug(f"Twitter codes: {twitter_codes}")
    except Exception:
        log.error("Could not get twitter codes!")

    codes = remove_duplicates_by_key(lambda x: x.code, codes)

    delta_codes = []
    with DatabaseTransaction() as db:
        existing_codes = list(
            db.coupons.get_all()
        )  # Must be a list as an iterator would get exhausted on first pass.
        for new_code in codes:
            exists = False
            for old_code in existing_codes:
                if new_code.code != old_code.code:
                    continue
                exists = True
                break
            if not exists:
                if save_to_db:
                    db.coupons.add(new_code)
                delta_codes.append(new_code)
    end_t = perf_counter()
    elapsed_s = round(end_t - start_t, 2)
    return delta_codes, elapsed_s


import argparse
from dataclasses import dataclass

from azureml.core import Datastore, Workspace

@dataclass
class Args:
    config: str

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("-c", "--config", help="path to config json", default="config.json")

    args = parser.parse_args()
    return Args(
        config=args.config,
    )

def main():
    args = parse_args()
    ws = Workspace.from_config(_file_name=args.config)
    for x in ws.datastores:
        # ds: Union[Datastore, None] = ws.datastores.get(x)
        ds = Datastore.get(ws, x)
        if ds is not None:
            print(ds.name)

if __name__ == '__main__':
    main()


import os
import json
import numpy as np

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *

from core.laserMarker import JCZLaserMarker, Pen, Hatch
from core.constants import JCZError

from ui.UiLaser import Ui_Laser

class RedLightThread(QThread):
    def __init__(self, laser, name="", showContour=True) -> None:
        super().__init__()
        self.name = name
        self.laser = laser
        self.showContour = showContour

        self._isRunning = False

    def start(self, priority=QThread.InheritPriority) -> None:
        self._isRunning = True
        super().start(priority)

    def quit(self) -> None:
        self._isRunning = False

    def run(self) -> None:
        while self._isRunning:
            self.laser.redLightMarkByEnt(self.name, self.showContour)
            self.msleep(1)

        self.quit()

class Window(Ui_Laser, QWidget):
    def __init__(self) -> None:
        super().__init__()
        self.setupUi(self)
        self.setWindowTitle("LaserDemo")

        QDir.setCurrent("./bin/")
        self.laser = JCZLaserMarker(os.path.abspath( "./MarkEzd.dll" ))
        self.laser.loadDLL()
        self.laser.sigError.connect(self.onError)

        self.isOpen = False
        self.startTimer(500)
        self.redThread = RedLightThread(self.laser)

        # bind signal
        self.bnOpen.clicked.connect(self.onOpen)
        self.bnSave.clicked.connect(self.onSave)
        self.bnInit.clicked.connect(self.onInit)
        self.bnClose.clicked.connect(self.onClose)
        self.bnSetting.clicked.connect(self.onDevConfig)

        self.bnMirrorMove.clicked.connect(self.onMirrorMove)

        self.bnEntMark.clicked.connect(self.onMark)
        self.bnEntRedLight.clicked.connect(self.onRedLight)
        self.bnEntChangeText.clicked.connect(self.onChangeText)
        self.bnEntMove.clicked.connect(self.onMove)
        self.bnEntMoveSet.clicked.connect(self.onMoveSet)
        self.bnEntGetHatch.clicked.connect(self.onGetHatch)
        self.bnEntSetHatch.clicked.connect(self.onSetHatch)
        self.bnEntSetPen.clicked.connect(self.onSetPen)
        self.bnEntGetPen.clicked.connect(self.onGetPen)

            # comboBox
        self.cbEnt.textActivated.connect(self.onCombo)

    def onError(self, methodName, e: JCZError):
        print("OnError:", [methodName, e.code, e.desc, e.solution])

    def onCombo(self, name):
        rect,z = self.laser.getEntSize(name)
        self.lbEntRect.setText(f"{rect}")

    def onOpen(self):
        if not self.isOpen: return
        file, _ = QFileDialog.getOpenFileName(filter="Ezd File (*.ezd)")
        if file:
            self.laser.loadEzdFile(file)

            n = self.laser.getEntityCount()
            for i in range(n):
                name = self.laser.getEntName(i)
                self.cbEnt.addItem(name)

    def onSave(self):
        self.laser.saveEzdFile(self.laser.ezdFile)

    def onInit(self):
        self.isOpen = self.laser.initial(False)

    def onClose(self):
        self.isOpen = False
        self.laser.close()

    def onDevConfig(self):
        self.laser.setDeviceConfig()

    def onMirrorMove(self):
        x, y = self.leMirrorX.text(), self.leMirrorY.text()
        self.laser.gotoPos(float(x), float(y))

    def onMark(self):
        name = self.cbEnt.currentText()
        self.laser.markEntity(name)

    def onRedLight(self):
        name = self.cbEnt.currentText()
        self.redThread.name = name
        if self.redThread.isRunning():
            self.redThread.quit()
        else:
            self.redThread.start()

    def onChangeText(self):
        name = self.cbEnt.currentText()
        newText = self.leEntText.text()
        self.laser.changeTextByName(name, newText)

    def onMove(self):
        name = self.cbEnt.currentText()
        x, y = self.leEntX.text(), self.leEntY.text()
        self.laser.moveEnt(name, float(x), float(y))

    def onMoveSet(self):
        name = self.cbEnt.currentText()
        x, y = self.leEntX.text(), self.leEntY.text()
        w, h = self.leEntW.text(), self.leEntH.text()
        self.laser.setSizeAndMove(name, float(x), float(y), float(w), float(h))

    def onGetHatch(self):
        name = self.cbEnt.currentText()
        hatch = self.laser.getHatchEntParam2(Hatch(name))
        self.tePara.setText(json.dumps(hatch.asDict(), indent=4))

    def onGetPen(self):
        name = self.cbEnt.currentText()
        n = self.laser.getPenNumberFromEnt(name)
        pen = self.laser.getPenParam(Pen(n))
        self.tePara.setText(json.dumps(pen.asDict(), indent=4))

    def onSetHatch(self):
        hatchDict = json.loads(self.tePara.toPlainText())
        self.laser.setHatchEntParam2(Hatch.fromDict(hatchDict))

    def onSetPen(self):
        penDict = json.loads(self.tePara.toPlainText())
        self.laser.setPenParam(Pen.fromDict(penDict))

    def timerEvent(self, e: 'QTimerEvent') -> None:
        if self.isOpen == False : return

        ## img
        s = self.gvPreview.sceneRect().size()
        img = self.laser.getPrevBitmap(s.width(), s.height())
        img = self.gvPreview.scene().addPixmap(img)
        img.setPos(-200, -200)

        ## pos
        x, y = self.laser.getCurCoor()
        self.lbPos.setText(f"({x},{y})")

        ## is marking
        v = self.laser.isMarking()
        self.lsMarking.setText(str(v))

        ## speed
        v = self.laser.getFlySpeed()
        self.lbSpeed.setText(f"{v}")

        ## ent count
        v = self.laser.getEntityCount()
        self.lbCount.setText(f"{v}")

        # ent Rect
        name = self.cbEnt.currentText()
        rect,z = self.laser.getEntSize(name)
        self.lbEntRect.setText(f"{rect}")

        # last markTime
        hour, min, sec, miliSec = self.laser.getLastMarkTime()
        self.lbMarkTime.setText(f"{hour}:{min}:{sec}.{miliSec}")

app = QApplication([])
win  = Window()
win.show()
app.exec()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Oct 17 15:09:54 2019

@author: burakgur
"""
import numpy as np
from numpy.fft import fft, fftfreq
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
#import sima # Commented out by seb
import copy
import scipy
from warnings import warn
from scipy import signal
from roipoly import RoiPoly
from scipy.optimize import curve_fit
from scipy.stats import linregress
from skimage import filters
from scipy.stats.stats import pearsonr
from scipy import fft
from scipy.signal import blackman
import course_functions.post_analysis_core as pac
import course_functions.process_mov_core_reduced_msc_course as pmc
class ROI_bg:
    """A region of interest from an image sequence """

    def __init__(self,Mask = None, experiment_info = None,imaging_info = None):
        """
        Initialized with a mask and optionally with experiment and imaging
        information
        """
        if (Mask is None):
            raise TypeError('ROI_bg: ROI must be initialized with a mask (numpy array)')
        if (experiment_info is not None):
            self.experiment_info = experiment_info
        if (imaging_info is not None):
            self.imaging_info = imaging_info

        self.mask = Mask
        self.uniq_id = id(self) # Generate a unique ID everytime

    def __str__(self):
        return '<ROI:{_id}>'.format(_id = self.uniq_id)

    def __repr__(self):
        return '<ROI:{_id}>'.format(_id = self.uniq_id)

    def setCategory(self,Category):
        self.category = Category

    def set_z_depth(self,depth):
        self.z_depth = depth

    def setSourceImage(self, Source_image):

        if np.shape(Source_image) == np.shape(self.mask):
            self.source_image = Source_image
        else:
            raise TypeError('ROI_bg: source image dimensions has to match with\
                            ROI mask.')

    def set_extraction_type(self,extraction_type):
        self.extraction_type = extraction_type

    def showRoiMask(self, cmap = 'Pastel2',source_image = None):

        if (source_image is None):
            source_image = self.source_image
        curr_mask = np.array(copy.deepcopy(self.mask),dtype=float)
        curr_mask[curr_mask==0] = np.nan
        sns.heatmap(source_image,alpha=0.8,cmap = 'gray',cbar=False)
        sns.heatmap(curr_mask, alpha=0.6,cmap = cmap,cbar=False)
        plt.axis('off')
        plt.title(self)

    def calculateDf(self,method='mean',moving_avg = False, bins = 3):
        try:
            self.raw_trace
        except NameError:
            raise NameError('ROI_bg: for deltaF calculations, a raw trace \
                            needs to be provided: a.raw_trace')

        if method=='mean':
            df_trace = (self.raw_trace-self.raw_trace.mean(axis=0))/(self.raw_trace.mean(axis=0))
            self.baseline_method = method

        if moving_avg:
            self.df_trace = movingaverage(df_trace, bins)
        else:
            self.df_trace = df_trace

        return self.df_trace

    def plotDF(self, line_w = 1, adder = 0,color=plt.cm.Dark2(0)):

        plt.plot(self.df_trace+adder, lw=line_w, alpha=.8,color=color)

        try:
            self.stim_info['output_data']
            stim_frames = self.stim_info['output_data'][:,7]  # Frame information
            stim_vals = self.stim_info['output_data'][:,3] # Stimulus value
            uniq_frame_id = np.unique(stim_frames,return_index=True)[1]
            stim_vals = stim_vals[uniq_frame_id]
            # Make normalized values of stimulus values for plotting

            stim_vals = (stim_vals/np.max(np.unique(stim_vals))) \
                *np.max(self.df_trace+adder)
            plt.plot(stim_vals,'--', lw=1, alpha=.6,color='k')
        except KeyError:
            print('No raw stimulus information found')

    def appendTrace(self, trace, epoch_num, trace_type = 'whole'):

        if trace_type == 'whole':
            try:
                self.whole_trace_all_epochs
            except AttributeError:
                self.whole_trace_all_epochs = {}

            self.whole_trace_all_epochs[epoch_num] = trace

        elif trace_type == 'response':
            try:
                self.resp_trace_all_epochs
            except AttributeError:
                self.resp_trace_all_epochs = {}

            self.resp_trace_all_epochs[epoch_num] = trace

    def appendStimInfo(self, Stim_info ,raw_stim_info = None):

        self.stim_info = Stim_info
        self.stim_name = Stim_info['stim_name']

        if (raw_stim_info is not None):
            # This part is now stored in the stim_info already but keeping it
            # for backward compatibility.
            self.raw_stim_info = raw_stim_info

    def findMaxResponse_all_epochs(self):
        try:
            self.resp_trace_all_epochs
        except AttributeError:
            raise AttributeError('ROI_bg: for finding maximum responses \
                            "resp_trace_all_epochs" has to be appended by \
                            appendTrace() method ')

        self.max_resp_all_epochs = \
            np.empty(shape=(int(self.stim_info['EPOCHS']),1)) #Seb: epochs_number --> EPOCHS

        self.max_resp_all_epochs[:] = np.nan

        for epoch_idx in self.resp_trace_all_epochs:
            self.max_resp_all_epochs[epoch_idx] = np.nanmax(self.resp_trace_all_epochs[epoch_idx])

        self.max_response = np.nanmax(self.max_resp_all_epochs)
        self.max_resp_idx = np.nanargmax(self.max_resp_all_epochs)

    def calculate_DSI_PD(self,method='PDND'):
        '''Calcuates DSI and PD of an ROI '''

        try:
            self.max_resp_all_epochs
            self.max_resp_idx
            self.stim_info
            self.max_response
        except AttributeError:
            raise TypeError('ROI_bg: for finding DSI an ROI needs\
                                 max_resp_all_epochs and stim_info')
        def find_opp_epoch(self, current_dir, current_freq, current_epoch_type):
            required_epoch_array = \
                    (self.stim_info['epoch_dir'] == ((current_dir+180) % 360)) & \
                    (self.stim_info['epoch_frequency'] == current_freq) & \
                    (self.stim_info['stimtype'] == current_epoch_type)

            return np.where(required_epoch_array)[0]

        if method == 'PDND':
            # Finding the maximum response epoch properties
            current_dir = self.stim_info['epoch_dir'][self.max_resp_idx]
            current_freq = self.stim_info['epoch_frequency'][self.max_resp_idx]
            current_epoch_type = self.stim_info['stimtype'][self.max_resp_idx]

            if current_freq == 0:
                warn('ROI %s -- max response is not in a moving epoch...' % self.uniq_id)
                moving_epochs = np.where(self.stim_info['epoch_frequency']>0)[0]
                # Find the moving epoch with max response
                idx = np.nanargmax(self.max_resp_all_epochs[moving_epochs])
                max_epoch = moving_epochs[idx]
                max_resp = self.max_resp_all_epochs[max_epoch]

            else:

                max_epoch = self.max_resp_idx
                max_resp = self.max_response
            # Calculating the DSI

            opposite_dir_epoch = find_opp_epoch(self,current_dir, current_freq,
                                                current_epoch_type)
            DSI = (max_resp - self.max_resp_all_epochs[opposite_dir_epoch])/\
                (max_resp + self.max_resp_all_epochs[opposite_dir_epoch])
            self.DSI = DSI[0][0]

            self.PD = current_dir

        elif method =='vector':
            dirs = self.stim_info['epoch_dir'][self.stim_info['baseline_epoch']+1:]
            resps = self.max_resp_all_epochs[self.stim_info['baseline_epoch']+1:]

            # Functions work with radians so convert
            xs= np.transpose(resps)*np.cos(np.radians(dirs))
            ys = np.transpose(resps)*np.sin(np.radians(dirs))
            x = (xs).sum()
            y = (ys).sum()
            DSI_vector = [x, y]
            cosine_angle = np.dot(DSI_vector, [1,0]) / (np.linalg.norm(DSI_vector) * np.linalg.norm([1,0]))

            # origin = [0], [0] # origin point
            # for idx,direction in enumerate(dirs):
            #     plt.quiver(origin[0],origin[1], xs[0][idx],ys[0][idx],
            #                color=plt.cm.Dark2(idx),
            #                label=str(direction),scale=2)
            # plt.quiver(origin[0],origin[1], x, y, color='r',scale=6)
            # plt.legend()

            angle = np.degrees(np.arccos(cosine_angle))
            if y<0:
                angle = 360 - angle
            self.DSI  = np.linalg.norm(DSI_vector)/np.max(resps)
            self.PD = angle

    def calculate_CSI(self, frameRate = None):

        try:
            self.resp_trace_all_epochs
            self.stim_info

        except AttributeError:
            raise TypeError('ROI_bg: for finding CSI an ROI needs\
                                 resp_trace_all_epochs and stim_info')
        # Find edge epochs
        edge_epochs = np.where(self.stim_info['stimtype']==50)[0]
        epochDur= self.stim_info['epochs_duration']

        self.edge_response = np.max(self.max_resp_all_epochs[edge_epochs])
        # Find the edge epoch with max response
        idx = np.nanargmax(self.max_resp_all_epochs[edge_epochs])
        max_edge_epoch = edge_epochs[idx]

        raw_trace = self.resp_trace_all_epochs[max_edge_epoch]
        trace = raw_trace
        # Filtering to decrease noise in max detection
#        b, a = signal.butter(3, 0.3, 'low')
#        trace = signal.filtfilt(b, a, raw_trace)

        half_dur_frames = int((round(self.imaging_info['frame_rate'] * epochDur[max_edge_epoch]))/2)
        OFF_resp = np.nanmax(trace[:half_dur_frames])
        ON_resp = np.nanmax(trace[half_dur_frames:])
        CSI = (ON_resp-OFF_resp)/(ON_resp+OFF_resp)

        self.CSI = np.abs(CSI)
        if CSI >0:
            self.CS = 'ON'
        else:
            self.CS = 'OFF'

    def calculateTFtuning_BF(self):

        grating_epochs = np.where(((self.stim_info['stimtype'] == 61) | \
                                   (self.stim_info['stimtype'] == 46)) &\
                                   (self.stim_info['epoch_frequency'] > 0))[0]

        # If there are no grating epochs
        if grating_epochs.size==0:
            raise ValueError('ROI_bg: No grating epoch (stim type: 61 or 46 \
                                                        exists.')

        max_grating_epoch=np.nanargmax(self.max_resp_all_epochs[grating_epochs])
        max_grating_epoch=grating_epochs[max_grating_epoch]

        current_dir = self.stim_info['epoch_dir'][max_grating_epoch]
        current_epoch_type = self.stim_info['stimtype'][max_grating_epoch]

        # Finding all same direction moving grating epochs
        required_epoch_array = \
                (self.stim_info['epoch_dir'] == current_dir) & \
                (self.stim_info['stimtype'] == current_epoch_type)& \
                (self.stim_info['epoch_frequency'] > 0)
        opposite_epoch_array = \
                (self.stim_info['epoch_dir'] == ((current_dir+180) % 360)) & \
                (self.stim_info['stimtype'] == current_epoch_type)& \
                (self.stim_info['epoch_frequency'] > 0)

        self.TF_curve_stim = self.stim_info['epoch_frequency'][required_epoch_array]

        self.ND_TF_curve_stim = self.stim_info['epoch_frequency'][opposite_epoch_array]
        # Get it as integer indices
        req_epochs_PD = np.where(required_epoch_array)[0]
        self.TF_curve_resp = self.max_resp_all_epochs[req_epochs_PD]

        req_epochs_ND = np.where(opposite_epoch_array)[0]
        self.ND_TF_curve_resp = self.max_resp_all_epochs[req_epochs_ND]

        self.BF = self.stim_info['epoch_frequency'][max_grating_epoch]

#%% The Class ROI_bg ends here and some other functions relating with ROIs will follow

def movingaverage(interval, window_size):
    window = np.ones(int(window_size))/float(window_size)
    return np.convolve(interval, window, 'same')

def interpolate_signal(signal, sampling_rate, int_rate):
    """
    """

     #juan: corrected interpolation
    period=1/sampling_rate
    timeV=  np.linspace(period,(len(signal)+1)*period,num=len(signal))
    # Create an interpolated time vector in the desired interpolation rate
    timeVI=np.linspace(0.1,10,100) #logic (period already interpolated,duration of trace(S),period*duration(s)) #careful if you change int_rate. Hardcoded line for 10hz interpolation of a 10sec stimulus
    return np.interp(timeVI, timeV, signal)

def find_inverted(rois,stim_type = None):
    """
    Calculate pearson's correlation between responses and stimulus.

    """
    for roi in rois:
        if stim_type == '1Hz_gratings':
            fr = roi.imaging_info['frame_rate']
            baseline_frames_total = roi.stim_info['baseline_duration'] * fr
            baseline_frames_needed = int(baseline_frames_total-(roi.stim_info['baseline_duration']/2.0 * fr))

            baseline_m = roi.whole_trace_all_epochs[1][baseline_frames_needed:int(baseline_frames_total)].mean()

            response_m = roi.resp_trace_all_epochs[1].mean()

            diff = response_m - baseline_m
            if diff>0:
                roi.inverted = 0
            else:
                roi.inverted = 1

        else:
            raise NameError('Stimulus type not found.')

    return rois

def generate_ROI_instances(roi_masks, category_masks, category_names, source_im,
                           experiment_info = None, imaging_info =None):
    """ Generates ROI_bg instances and adds the category information.

    Parameters
    ==========
    roi_masks : list
        A list of ROI masks in the form of numpy arrays.

    category_masks: list
        A list of category masks in the form of numpy arrays.

    category_names: list
        A list of category names.

    source_im : numpy array
        An array containing a representation of the source image where the
        ROIs are found.

    Returns
    =======

    rois : list
        A list containing instances of ROI_bg
    """
    # Seb: coommented this
    # if type(roi_masks) == sima.ROI.ROIList:
    #     roi_masks = list(map(lambda roi : np.array(roi)[0,:,:], roi_masks))

    # Generate instances of ROI_bg from the masks
    rois = list(map(lambda mask : ROI_bg(mask, experiment_info = experiment_info,
                                    imaging_info=imaging_info), roi_masks))

    def assign_region(roi, category_masks, category_names):
        """ Finds which layer the current mask is in"""
        for iLayer, category_mask in enumerate(category_masks):
            if np.sum(roi.mask*category_mask):
                roi.setCategory(category_names[iLayer])

    # Add information
    for roi in rois:
        assign_region(roi, category_masks, category_names)
        roi.setSourceImage(source_im)

    return rois

#%%
def data_to_list(rois, data_name_list):
    """ Generates a dictionary with desired variables from ROIs.

    Parameters
    ==========
    rois : list
        A list of ROI_bg instances.

    data_name_list: list
        A list of strings with desired variable names. The variables should be
        written as defined in the ROI_bg class.

    Returns
    =======

    roi_data_dict : dictionary
        A dictionary with keys as desired data variable names and values as
        list of data.
    """
    class my_dictionary(dict):

        # __init__ function
        def __init__(self):
            self = dict()

        # Function to add key:value
        def add(self, key, value):
            self[key] = value

    roi_data_dict = my_dictionary()

    # Generate an empty dictionary
    for key in data_name_list:
        roi_data_dict.add(key, [])

    # Loop through ROIs and get the desired data
    for iROI, roi in enumerate(rois):
        for key, value in roi_data_dict.items():
            if key in roi.__dict__.keys():
                value.append(roi.__dict__[key])
            else:
                value.append(np.nan)
    return roi_data_dict

def threshold_ROIs(rois, threshold_dict):
    """ Thresholds given ROIs and returns the ones passing the threshold.

    Parameters
    ==========
    rois : list
        A list of ROI_bg instances.

    threshold_dict: dict
        A dictionary with desired ROI_bg property names that will be
        thresholded as keys and the corresponding threshold values as values.

    Returns
    =======

    thresholded_rois : list
        A list containing instances of ROI_bg which pass the thresholding step.
    """
    # If there is no threshold
    if threshold_dict is None:
        print('No threshold used.')
        return rois
    vars_to_threshold = threshold_dict.keys()

    roi_data_dict = data_to_list(rois, vars_to_threshold)

    pass_bool = np.ones((1,len(rois)))

    for key, value in threshold_dict.items():

        if type(value) == tuple:
            if value[0] == 'b':
                pass_bool = \
                    pass_bool * (np.array(roi_data_dict[key]).flatten() > value[1])

            elif value[0] == 's':
                pass_bool = \
                    pass_bool * (np.array(roi_data_dict[key]).flatten() < value[1])
            else:
                raise TypeError("Tuple first value not understood: should be 'b' for bigger than or 's' for smaller than")

        else:
            pass_bool = pass_bool * (np.array(roi_data_dict[key]).flatten() > value)

    pass_indices = np.where(pass_bool)[1]

    thresholded_rois = []
    for idx in pass_indices:
        thresholded_rois.append(rois[idx])

    return thresholded_rois

#%%
def get_masks_image(rois):
    """ Generates an image of masks.

    Parameters
    ==========
    rois : list
        A list of ROI_bg instances.

    Returns
    =======

    roi_data_dict : np array
        A numpy array with masks depicted in different integers
    """
    roi_masks_image = np.array(list(map(lambda idx_roi_pair : \
                             idx_roi_pair[1].mask.astype(float) * (idx_roi_pair[0]+1),
                             list(enumerate(rois))))).sum(axis=0)

    roi_masks_image[roi_masks_image==0] = np.nan

    return roi_masks_image

#%%
def generate_colorMasks_properties(rois, prop = 'BF'):
    """ Generates images of masks depending on DSI CSI Rel and BF

    TODO: Is it possible to generate something independent?
    Parameters
    ==========
    rois : list
        A list of ROI_bg instances.

    Returns
    =======

    roi_data_dict : np array
        A numpy array with masks depicted in different integers
    """
    if prop == 'BF':
        BF_image = np.zeros(np.shape(rois[0].mask))

        for roi in rois:
            curr_mask = roi.mask.astype(int)
            BF_image = BF_image + (curr_mask * roi.BF)
        BF_image[BF_image==0] = np.nan

        return BF_image
    elif prop == 'CS':
        CSI_image = np.zeros(np.shape(rois[0].mask))
        for roi in rois:
            curr_CS = roi.CS
            if curr_CS == 'OFF':
                curr_CSI = roi.CSI * -1
            else:
                curr_CSI = roi.CSI
            curr_mask = roi.mask.astype(int)
            CSI_image = CSI_image + (curr_mask * curr_CSI)
        CSI_image[CSI_image==0] = np.nan
        return CSI_image
    elif prop =='DSI':
        DSI_image  = np.zeros(np.shape(rois[0].mask))
        for roi in rois:
            curr_DSI = roi.DSI

            curr_mask = roi.mask.astype(int)
            DSI_image = DSI_image + (curr_mask * curr_DSI)
        DSI_image[DSI_image==0] = np.nan
        return DSI_image
    elif prop =='PD':
        PD_image  = np.full(np.shape(rois[0].mask),np.nan)
        alpha_image  = np.full(np.shape(rois[0].mask),np.nan)
        for roi in rois:
            PD_image[roi.mask] = roi.PD
            alpha_image[roi.mask] = roi.DSI

        return PD_image

    elif prop == 'reliability':
        Corr_image = np.zeros(np.shape(rois[0].mask))
        for roi in rois:
            curr_mask = roi.mask.astype(int)
            Corr_image = Corr_image + (curr_mask * roi.reliability)

        Corr_image[Corr_image==0] = np.nan
        return Corr_image

    elif prop == 'SNR':
        snr_image = np.zeros(np.shape(rois[0].mask))
        for roi in rois:
            curr_mask = roi.mask.astype(int)
            snr_image = snr_image + (curr_mask * roi.SNR)

        snr_image[snr_image==0] = np.nan
        return snr_image
    elif prop == 'corr_fff':
        Corr_image = np.zeros(np.shape(rois[0].mask))
        for roi in rois:
            curr_mask = roi.mask.astype(int)
            Corr_image = Corr_image + (curr_mask * roi.corr_fff)

        Corr_image[Corr_image==0] = np.nan
        return Corr_image
    elif prop == 'max_response':
        max_image = np.zeros(np.shape(rois[0].mask))
        for roi in rois:
            curr_mask = roi.mask.astype(int)
            max_image = max_image + (curr_mask * roi.max_response)

        max_image[max_image==0] = np.nan
        return max_image
    elif prop == 'slope':

        slope_im = np.zeros(np.shape(rois[0].mask))
        for roi in rois:
            curr_mask = roi.mask.astype(int)
            slope_im = slope_im + (curr_mask * roi.slope)

        slope_im[slope_im==0] = np.nan
        return slope_im

    else:
        raise TypeError('Property %s not available for color mask generation' % prop)
        return 0

#%%
def analyze_gratings_general(rois):
    # IMPORTANT INFO
    # Seb: function name was changed from: analyze_luminance_gratings >>> analyze_gratings_general
    # The idea is to make one singl function handling all type of grating stimulation

    # Seb: if this variable does NOT exist in the stim file, made it 0 (= one single direction)
    if 'epoch_dir' in rois[0].stim_info:
        epoch_dirs = rois[0].stim_info['epoch_dir']
    else:
        epoch_dirs = np.ndarray.tolist(np.zeros(rois[0].stim_info['EPOCHS']))

    epoch_dirs_no_base= \
        np.delete(epoch_dirs,rois[0].stim_info['baseline_epoch'])
    epoch_types = rois[0].stim_info['stimtype']

    epoch_luminances= np.array(rois[0].stim_info['input_data']['lum'],float)
    epoch_velocity = np.array(rois[0].stim_info['input_data']['velocity'],float)
    epoch_sWavelength = np.array(rois[0].stim_info['input_data']['sWavelength'],float)
    epoch_TF= epoch_velocity/epoch_sWavelength

    if epoch_types[1] == 'noisygrating':
        epoch_SNR= np.array(rois[0].stim_info['input_data']['SNR'],float)

    for roi in rois:
        roi_dict = {}

        req_epochs = [e == rois[0].stim_info['stimtype'][-1] for e in epoch_types] # Seb: selecting epochs of interest based on the name of the last epoch in the stimulus input file
        if int(rois[0].stim_info['random']) == 1:
            req_epochs[0] = False # Seb: first epoch is for the baseline, not for analyzing any response
        #if rois[0].stim_info['stimtype'][0] != rois[0].stim_info['stimtype'][1]:
        #    req_epochs[0] = False
        #if rois[0].stim_info['stimtype'][0] == 'circle':
        #    req_epochs[0] = False #JC:4 times doing the same thing? commented it out

        roi_dict['luminance'] = epoch_luminances[req_epochs]
        roi_dict['deltaF'] = np.array(map(float,roi.max_resp_all_epochs[req_epochs]))
        roi_dict['TF'] = epoch_TF[req_epochs]
        # Specific variable based on the typ of stimulation for buiding a future heat map between this variable and TF
        if epoch_types[1] == 'lumgrating':
            variable_name = 'lum'

        elif epoch_types[1] == 'noisygrating':
            roi_dict['SNR'] = epoch_SNR[req_epochs]
            variable_name = 'SNR'

        elif epoch_types[1] == 'TFgrating':
            variable_name = 'TF'

        #Seb: fft analysis
        #epochs_roi_data= roi.whole_trace_all_epochs # try also just with roi.resp_trace_all_epochs
        epochs_roi_data = roi.resp_trace_all_epochs

        amp_fft = []
        for idx, epoch in enumerate(epochs_roi_data):
            curr_trace = epochs_roi_data[epoch]
            N = len(curr_trace) # frames or total number of points (aka sample rate)

            # FFT and power spectra calculations
            period = 1.0 / roi.imaging_info['frame_rate']
            yf = fft.fft(curr_trace) #JC: added fft. because the module changed and now
                                    #we need it to get the function
            xf = np.linspace(0.0, 1.0/(2.0*period), N//2)
            # mitigate spectral leakage
            w = np.blackman(N)
            ywf = fft.fft((curr_trace-curr_trace.mean())*w)

            # "X" Hz sinusoidal as reference
            Lx = N/roi.imaging_info['frame_rate'] # Duration in seconds
            X_Hz = round(roi_dict['TF'][idx],2)
            f = X_Hz * np.rint(Lx) # X_hz
            amp = 0.5 # desired amplitude
            x = np.arange(N)
            y = amp * np.sin(2 * np.pi * f * x / N)
            yf_ref = fft.fft(y) #fft values ref
            # yf_theo_ref = 2.0*np.abs(fft_values_ref/N)
            # mitigate spectral leakage
            w = np.blackman(N)
            ywf_ref = fft.fft((y-y.mean())*w)

            # Locating max peak of the reference frequency
            ref_trace_power = 2.0/N * np.abs(ywf_ref[1:N//2])
            m = max(ref_trace_power)
            max_idx = [i for i in range(len(ref_trace_power)) if ref_trace_power[i] == m][0]

            # Locating amplitude of the desired frequency in the response trace
            response_trace_power = 2.0/N * np.abs(ywf[1:N//2])
            temp_respose_amp = response_trace_power[max_idx]
            amp_fft.append(temp_respose_amp)

            # # plotting the spectrum
            # x_freqs = xf[1:N//2]

            # plt.close()
            # plt.plot(y)
            # plt.show()
            # plt.close()
            # plt.plot(x_freqs, response_trace_power, label='fft values')
            # plt.plot(x_freqs, ref_trace_power)
            # plt.plot(x_freqs[max_idx],temp_respose_amp, 'ro')
            # plt.title("Stimulated frequency (Hz): {}".format(X_Hz))
            # plt.show()
            # plt.close()

        # Saving the amplitude of the "X" hz component
        roi.fft_X_hz_amp = amp_fft

        # Seb: if this variable does NOT exist in the stim file, create it from others
        if 'epoch_TF' in rois[0].stim_info:
            roi_dict['TF'] = roi.stim_info['epoch_TF'][req_epochs]

        else:
            temp_TF_list = []
            for i, value in enumerate(roi.stim_info['velocity']):
                #Seb: if statement to take care of non-grating epoch
                if value == 0.0 and roi.stim_info['sWavelength'][i] == 0.0:
                    temp_TF = 0.0
                    temp_TF_list.append(temp_TF)
                    continue
                temp_TF = value/roi.stim_info['sWavelength'][i]
                temp_TF_list.append(temp_TF)

            temp_TF_list = np.array(temp_TF_list)
            roi.stim_info['epoch_TF'] = temp_TF_list
            roi_dict['TF'] = temp_TF_list[req_epochs]

        # Creating a pandas dataframe for future heat map
        df_roi = pd.DataFrame.from_dict(roi_dict)
        if epoch_types[1] == 'lumgrating':
            tfl_map = df_roi.pivot(index='TF',columns='luminance')
        elif epoch_types[1] == 'noisygrating':
            tfl_map = df_roi.pivot(index='TF',columns='SNR')
        elif epoch_types[1] == 'TFgrating':
            tfl_map = df_roi.pivot(index='TF',columns='luminance')

        roi.tfl_map= tfl_map
        roi.tfl_map_norm=(tfl_map-tfl_map.mean())/tfl_map.std()
        roi.BF = roi.stim_info['epoch_TF'][roi.max_resp_idx]

        conc_trace = []
        for epoch in np.argwhere((roi.stim_info['epoch_TF'] == 1))[1:]:

            conc_trace=np.append(conc_trace,
                                 roi.whole_trace_all_epochs[float(epoch)],axis=0)
        roi.oneHz_conc_resp = conc_trace

    return rois

def analyze_gratings_1Hz(rois,int_rate = 10):  # Previous name: analyze_luminance_gratings_1Hz

    # Seb: if this variable does NOT exist in the stim file, made it 0 (= one single direction)
    if 'epoch_dir' in rois[0].stim_info:
        epoch_dirs = rois[0].stim_info['epoch_dir']
    else:
        epoch_dirs = np.ndarray.tolist(np.zeros(rois[0].stim_info['EPOCHS']))

    epoch_dirs_no_base= \
        np.delete(epoch_dirs,rois[0].stim_info['baseline_epoch'])
    epoch_types = rois[0].stim_info['stimtype']

    if epoch_types[-1] == 'lumgrating':
        epoch_luminances= np.array(rois[0].stim_info['input_data']['lum'],float)
    elif epoch_types[-1] == 'noisygrating':
        epoch_luminances= np.array(rois[0].stim_info['input_data']['SNR'],float)

    for roi in rois:

        # Seb: commented this out
        # if not('1D' in roi.stim_name):
        #     curr_pref_dir = \
        #         np.unique(epoch_dirs_no_base)[np.argmin(np.abs(np.unique(epoch_dirs_no_base)-roi.PD))]
        #     req_epochs = (epoch_dirs==curr_pref_dir) & (epoch_types != 11)
        # else:
        #     req_epochs = (epoch_types != 11)

        req_epochs = [e == rois[0].stim_info['stimtype'][-1] for e in epoch_types] # Seb: selecting epochs of interest based on the name of the last epoch in the stimulus input file
        if rois[0].stim_info['stimtype'][0] == rois[0].stim_info['stimtype'][1]:
            req_epochs[0] = False

        roi.luminances = epoch_luminances[req_epochs]
        conc_trace = []
        roi.power_at_hz = np.zeros_like(roi.luminances)
        roi.base_power = np.zeros_like(roi.luminances)
        roi.baselines = np.zeros_like(roi.luminances)
        fr = roi.imaging_info['frame_rate']

        min_len = np.array(list(map(len, roi.resp_trace_all_epochs.values()))).min()
        traces = np.zeros((np.sum(req_epochs),min_len))

        ex_trace = roi.resp_trace_all_epochs[np.where(req_epochs)[0][0]][:min_len]
        int_len = len(interpolate_signal(ex_trace,
                                     roi.imaging_info['frame_rate'],int_rate))
        int_traces =np.zeros((np.sum(req_epochs),int_len))

        min_len_wholeT = np.array(list(map(len, roi.whole_trace_all_epochs.values()))).min()
        traces_wholeT = np.zeros((np.sum(req_epochs),min_len_wholeT))

        ex_trace_wholeT = roi.whole_trace_all_epochs[np.where(req_epochs)[0][0]][:min_len_wholeT]
        int_len_wholeT = len(interpolate_signal(ex_trace_wholeT,
                                     roi.imaging_info['frame_rate'],int_rate))
        int_traces_wholeT =np.zeros((np.sum(req_epochs),int_len_wholeT))
        mat_idx = 0
        for idx,epoch in enumerate(np.where(req_epochs)[0]):
            try:
                curr_freq = roi.stim_info['epoch_frequency'][epoch]
            except:
                curr_freq = roi.stim_info['epoch_TF'][epoch]
            curr_resp = roi.resp_trace_all_epochs[epoch]

            two_sec = int(2 * roi.imaging_info['frame_rate'])
            curr_whole = roi.whole_trace_all_epochs[epoch][two_sec:-1-two_sec]
            bg_resp = roi.whole_trace_all_epochs[epoch][two_sec:-two_sec+int(roi.imaging_info['frame_rate'])]
            bg_resp_mean = bg_resp.mean()
            roi.baselines[idx] = curr_resp[int(fr):].mean()-bg_resp_mean

            # Fourier analysis of baseline responses
            N = len(curr_whole)
            period = 1.0 / roi.imaging_info['frame_rate']
            x = np.linspace(0.0, N*period, N)
            yf = fft.fft(curr_whole)

            xf = np.linspace(0.0, 1.0/(2.0*period), N//2)
            # mitigate spectral leakage
            w = blackman(N)
            ywf = fft.fft((curr_whole-curr_whole.mean())*w)
            # plt.plot(xf[1:N//2], 2.0/N * np.abs(ywf[1:N//2]),
            #               label = '{l}'.format(l=roi.luminances[idx]))
            # plt.legend()
            base_p = 2.0/N * np.abs(ywf[1:N//2])
            req_idx = np.argmin(np.abs(xf-(1.0/6)))
            roi.base_power[idx] = base_p[req_idx]

            # Fourier analysis of sinusodial responses
            N = len(curr_resp)
            period = 1.0 / roi.imaging_info['frame_rate']
            x = np.linspace(0.0, N*period, N)
            yf = fft.fft(curr_resp)

            xf = np.linspace(0.0, 1.0/(2.0*period), N//2)
            # mitigate spectral leakage
            w = blackman(N)
            ywf = fft.fft((curr_resp-curr_resp.mean())*w)
            # plt.plot(xf[1:N//2], 2.0/N * np.abs(ywf[1:N//2]),
            #               label = '{l}'.format(l=roi.luminances[idx]))
            # plt.legend()
            power = 2.0/N * np.abs(ywf[1:N//2])
            req_idx = np.argmin(np.abs(xf-curr_freq))
            roi.power_at_hz[idx] = power[req_idx]

            # Concatenate trace
            conc_trace=np.append(conc_trace,
                                 roi.whole_trace_all_epochs[float(epoch)][two_sec:],axis=0)

            # Interpolation
            curr_trace = roi.resp_trace_all_epochs[epoch][:min_len]
            traces[mat_idx,:] = curr_trace
            int_traces[mat_idx,:] = interpolate_signal(curr_trace,
                                 roi.imaging_info['frame_rate'],int_rate)

            curr_trace_wt = roi.whole_trace_all_epochs[epoch][:min_len_wholeT]
            traces_wholeT[mat_idx,:] = curr_trace_wt
            int_traces_wholeT[mat_idx,:] = interpolate_signal(curr_trace_wt,
                                 roi.imaging_info['frame_rate'],int_rate)

            mat_idx +=1

        roi.int_rate = int_rate
        roi.grating_resp_traces = traces
        roi.grating_resp_traces_interpolated = int_traces

        roi.grating_whole_traces = traces_wholeT
        roi.grating_whole_traces_interpolated = int_traces_wholeT

        # plt.legend()
        # plt.title(roi.experiment_info['Genotype'])
        # plt.xlabel('Hz')
        # plt.ylabel('Signal')
        # plt.waitforbuttonpress()
        # plt.close('all')
        roi.conc_resp = conc_trace

        X = roi.luminances
        Y = roi.power_at_hz
        Z = roi.base_power

        roi.slope = linregress(X, np.transpose(Y))[0]
        roi.basePower_slope = linregress(X, np.transpose(Z))[0]
        roi.base_slope = linregress(X, np.transpose(roi.baselines))[0]

    return rois


import hashlib
import math
import multiprocessing as mp
import time
from math import pi, sqrt

import cython
import numpy as np
import numpy.typing as npt
from scipy.special import erf, expi

from .mesh import Element
from .quadrature import (DuffyScheme2D, ProductScheme2D,
                         gauss_quadrature_scheme, log_quadrature_scheme)
from .single_layer_exact import (spacetime_evaluated_1,
                                 spacetime_integrated_kernel)

FPI_INV = cython.declare(cython.double)
FPI_INV = (4 * pi)**-1
PI_SQRT = cython.declare(cython.double)
PI_SQRT = math.sqrt(pi)

def kernel(t, x):
    assert isinstance(t, float) and isinstance(x, float)
    if (t <= 0): return 0
    else: return FPI_INV * 1. / t * np.exp(-x**2 / (4 * t))

def alpha(z):
    """ Returns lambda a_z(x) """
    return lambda x: np.sum(x**2, axis=0) / (4 * z)

def noop(x):
    return 0

def g(a, b):
    """ Returns g_z for z = a - b. """
    if a <= b:
        return noop
    z = a - b
    return lambda x: FPI_INV * expi(-np.sum(x**2, axis=0) / (4 * z))

def f(a, b):
    """ Returns f_z for z = a - b"""
    if a <= b:
        return noop
    z = a - b

    def f_z(x_sqr):
        a_z = x_sqr / (4 * z)
        return FPI_INV * (z * np.exp(-a_z) + z * (1 + a_z) * expi(-a_z))

    return f_z

def time_integrated_kernel(t, a, b):
    """ Returns heat kernel G(t-s,x) integrated over s in [a,b]. """
    assert a < b
    g_ta = g(t, a)
    g_tb = g(t, b)
    return lambda x: g_tb(x) - g_ta(x)

def double_time_integrated_kernel(a, b, c, d):
    """ Returns kernel integrated in time over [a,b] x [c, d], """
    assert a < b and c < d

    def G(x):
        x_sqr = np.sum(x**2, axis=0) / 4
        result = 0
        if b > d:
            z = b - d
            result += FPI_INV * (z * np.exp(-x_sqr / z) +
                                 (x_sqr + z) * expi(-x_sqr / z))
        if b > c:
            z = b - c
            result -= FPI_INV * (z * np.exp(-x_sqr / z) +
                                 (x_sqr + z) * expi(-x_sqr / z))
        if a > c:
            z = a - c
            result += FPI_INV * (z * np.exp(-x_sqr / z) +
                                 (x_sqr + z) * expi(-x_sqr / z))
        if a > d:
            z = a - d
            result -= FPI_INV * (z * np.exp(-x_sqr / z) +
                                 (x_sqr + z) * expi(-x_sqr / z))

        return result

    return G

def MP_SL_matrix_col(j: int) -> npt.ArrayLike:
    """ Function to evaluate SL in parallel using the multiprocessing library. """
    global __SL, __elems_test, __elems_trial
    elem_trial = __elems_trial[j]
    col = np.zeros(len(__elems_test))
    for i, elem_test in enumerate(__elems_test):
        if elem_test.time_interval[1] <= elem_trial.time_interval[0]:
            continue
        col[i] = __SL.bilform(elem_trial, elem_test)
    return col

class SingleLayerOperator:
    def __init__(self, mesh, quad_order=12, pw_exact=False, cache_dir=None):
        self.pw_exact = pw_exact
        self.gauss_scheme = gauss_quadrature_scheme(23)
        self.gauss_2d = ProductScheme2D(self.gauss_scheme)
        self.log_scheme = log_quadrature_scheme(quad_order, quad_order)
        self.log_scheme_m = self.log_scheme.mirror()
        self.log_log = ProductScheme2D(self.log_scheme, self.log_scheme)
        self.duff_log_log = DuffyScheme2D(self.log_log, symmetric=False)
        self.mesh = mesh
        self.gamma_len = self.mesh.gamma_space.gamma_length
        self.glue_space = self.mesh.glue_space
        self.cache_dir = cache_dir
        self._init_elems(self.mesh.leaf_elements)

    def _init_elems(self, elems):
        # For all elements in the mesh, register the log scheme.
        for elem in elems:
            a, b = elem.space_interval
            elem.__log_scheme_y = elem.gamma_space(a + (b - a) *
                                                   self.log_scheme.points)
            elem.__log_scheme_m_y = elem.gamma_space(a + (b - a) *
                                                     self.log_scheme_m.points)

    @cython.locals(h_x=cython.double, h_y=cython.double)
    def __integrate(self, f: object, a: float, b: float, c: float,
                    d: float) -> float:
        """ Integrates a symmetric singular f over the square [a,b]x[c,d]. """
        h_x = b - a
        h_y = d - c
        assert h_x > 1e-8 and h_y > 1e-8
        assert (a < b and c < d)
        assert (a, b) <= (c, d)

        # If are the same panel.
        if a == c and b == d:
            return self.duff_log_log.integrate(f, a, b, c, d)

        # If the panels touch in the middle, split into even parts.
        if b == c:
            if abs(h_x - h_y) < 1e-10:
                return self.duff_log_log.mirror_x().integrate(f, a, b, c, d)
            elif h_x > h_y:
                return self.duff_log_log.mirror_x().integrate(
                    f, b - h_y, b, c, d) + self.__integrate(
                        f, a, b - h_y, c, d)
            else:
                return self.duff_log_log.mirror_x().integrate(
                    f, a, b, c, c + h_x) + self.__integrate(
                        f, a, b, c + h_x, d)
        assert not math.isclose(b, c)

        # If the panels touch through in the glued boundary, split into even parts.
        if a == 0 and d == self.gamma_len and self.glue_space:
            assert b < c
            if abs(h_x - h_y) < 1e-10:
                return self.duff_log_log.mirror_y().integrate(f, a, b, c, d)
            elif h_x > h_y:
                return self.duff_log_log.mirror_y().integrate(
                    f, a, a + h_y, c, d) + self.__integrate(
                        f, a + h_y, b, c, d)
            else:
                return self.__integrate(
                    f, a, b, c,
                    d - h_x) + self.duff_log_log.mirror_y().integrate(
                        f, a, b, d - h_x, d)

        # If we are disjoint.  TODO: Do more singular stuff if close?
        # TODO: Gauss 2d for disjoint..
        if b < c:
            #return self.gauss_2d.integrate(f, a, b, c, d)
            if c - b < self.gamma_len - d + a or not self.glue_space:
                return self.log_log.mirror_x().integrate(f, a, b, c, d)
            else:
                return self.log_log.mirror_y().integrate(f, a, b, c, d)

        # If the first panel is longer than the second panel.
        if d < b:
            # TODO: Is this correct?
            return self.__integrate(
                f, a, d, c, d) + self.duff_log_log.mirror_y().integrate(
                    f, d, b, c, d)

        # First panel is contained in second one.
        if a == c:
            assert b < d
            return self.__integrate(f, a, b, c, b) + self.__integrate(
                f, a, b, b, d)
        assert not math.isclose(a, c)

        # We have overlap, split this in two parts.
        assert a < c
        return self.__integrate(f, a, c, c, d) + self.__integrate(
            f, c, b, c, d)

    @cython.locals(a=cython.double,
                   b=cython.double,
                   c=cython.double,
                   d=cython.double)
    def bilform(self, elem_trial: Element, elem_test: Element) -> float:
        """ Evaluates <V 1_trial, 1_test>. """
        # If the test element lies below the trial element, we are done.
        if elem_test.time_interval[1] <= elem_trial.time_interval[0]:
            return 0

        if self.pw_exact and elem_test.gamma_space is elem_trial.gamma_space:
            return spacetime_integrated_kernel(*elem_test.time_interval,
                                               *elem_trial.time_interval,
                                               *elem_test.space_interval,
                                               *elem_trial.space_interval)

        a, b = elem_test.time_interval
        c, d = elem_trial.time_interval

        # Calculate the time integrated kernel.
        G_time = double_time_integrated_kernel(a, b, c, d)

        gamma_test = elem_test.gamma_space
        gamma_trial = elem_trial.gamma_space

        if elem_test.space_interval <= elem_trial.space_interval:
            G_time_parametrized = lambda x: G_time(
                gamma_test(x[0]) - gamma_trial(x[1]))

            return self.__integrate(G_time_parametrized,
                                    *elem_test.space_interval,
                                    *elem_trial.space_interval)
        else:
            # Swap x,y coordinates.
            G_time_parametrized = lambda x: G_time(
                gamma_test(x[1]) - gamma_trial(x[0]))

            return self.__integrate(G_time_parametrized,
                                    *elem_trial.space_interval,
                                    *elem_test.space_interval)

    def bilform_matrix(self, elems_test=None, elems_trial=None, use_mp=False):
        """ Returns the dense matrix <V 1_trial, 1_test>. """
        if elems_test is None:
            elems_test = list(self.mesh.leaf_elements)
        if elems_trial is None:
            elems_trial = elems_test

        N = len(elems_test)
        M = len(elems_trial)

        # For small N, M, simply construct matrix inline and return.
        if N * M < 100:
            mat = np.zeros((N, M))
            for i, elem_test in enumerate(elems_test):
                for j, elem_trial in enumerate(elems_trial):
                    mat[i, j] = self.bilform(elem_trial, elem_test)
            return mat

        if self.cache_dir is not None:
            md5 = hashlib.md5((str(self.mesh.gamma_space) + str(elems_test) +
                               str(elems_trial)).encode()).hexdigest()
            cache_fn = "{}/SL_{}_{}x{}_{}.npy".format(self.cache_dir,
                                                      self.mesh.gamma_space, N,
                                                      M, md5)
            try:
                mat = np.load(cache_fn)
                print("Loaded Single Layer from file {}".format(cache_fn))
                return mat
            except:
                pass

        time_mat_begin = time.time()

        mat = np.zeros((N, M))
        if not use_mp:
            for i, elem_test in enumerate(elems_test):
                for j, elem_trial in enumerate(elems_trial):
                    mat[i, j] = self.bilform(elem_trial, elem_test)
        else:
            # Set up global variables for parallelizing.
            globals()['__elems_test'] = elems_test
            globals()['__elems_trial'] = elems_trial
            globals()['__SL'] = self
            cpu = mp.cpu_count()
            for j, col in enumerate(
                    mp.Pool(mp.cpu_count()).imap(MP_SL_matrix_col, range(M),
                                                 M // (16 * cpu) + 1)):
                mat[:, j] = col

        if self.cache_dir is not None:
            try:
                np.save(cache_fn, mat)
                print("Stored Single Layer to {}".format(cache_fn))
            except:
                pass

        print('Calculating SL matrix took {}s'.format(time.time() -
                                                      time_mat_begin))
        return mat

    def potential(self, elem_trial, t, x):
        """ Evaluates (V 1_trial)(t,x) for t,x not on the bdr. """
        assert x.shape == (2, 1)
        if t <= elem_trial.time_interval[0]: return 0

        # Calculate the time integrated kernel.
        G_time = time_integrated_kernel(t, *elem_trial.time_interval)
        G_time_parametrized = lambda y: G_time(x - elem_trial.gamma_space(y))
        return self.gauss_scheme.integrate(G_time_parametrized,
                                           *elem_trial.space_interval)

    def potential_vector(self, t, x):
        """ Returns the vector (V 1_elem)(t, x) for all elements in mesh. """
        elems = list(self.mesh.leaf_elements)
        N = len(elems)
        vec = np.zeros(shape=N)
        for j, elem_trial in enumerate(elems):
            vec[j] = self.potential(elem_trial, t, x)
        return vec

    @cython.locals(x_a=cython.double,
                   x_b=cython.double,
                   d_a=cython.double,
                   d_b=cython.double,
                   t_a=cython.double,
                   t_b=cython.double)
    def evaluate(self, elem_trial: Element, t: float, x_hat: float,
                 x: npt.ArrayLike) -> float:
        """ Evaluates (V 1_trial)(t, gamma(x_hat)) for t, x_hat in the param domain. """
        if t <= elem_trial.time_interval[0]: return 0
        #if x is None: x = self.mesh.gamma_space.eval(x_hat)
        x_a = elem_trial.space_interval[0]
        x_b = elem_trial.space_interval[1]
        t_a = elem_trial.time_interval[0]
        t_b = elem_trial.time_interval[1]

        # Check if singularity lies in this element.
        if x_a * (1 + 1e-10) <= x_hat <= x_b * (1 - 1e-10):
            # Calculate the time integrated kernel.
            def G_time_parametrized(y_hat: npt.ArrayLike):
                xy = (x - elem_trial.gamma_space(y_hat))**2
                xy = xy[0] + xy[1]
                a, b = elem_trial.time_interval
                if t <= b:
                    return -FPI_INV * expi(-xy / (4 * (t - a)))
                else:
                    return FPI_INV * (expi(-xy / (4 *
                                                  (t - b))) - expi(-xy /
                                                                   (4 *
                                                                    (t - a))))

            return self.log_scheme_m.integrate(
                G_time_parametrized, x_a, x_hat) + self.log_scheme.integrate(
                    G_time_parametrized, x_hat, x_b)

        # Calculate distance of x_hat to both endpoints.
        if self.glue_space:
            d_a = min(abs(x_hat - x_a), abs(self.gamma_len - x_hat + x_a))
            d_b = min(abs(x_hat - x_b), abs(self.gamma_len - x_b + x_hat))
        else:
            d_a = abs(x_hat - x_a)
            d_b = abs(x_hat - x_b)

        # Calculate |x - gamma(yhat)|^2 for the quadrature rule.
        if d_a <= d_b:
            xy_sqr = (x - elem_trial.__log_scheme_y)**2
        else:
            xy_sqr = (x - elem_trial.__log_scheme_m_y)**2
        xy = xy_sqr[0] + xy_sqr[1]

        # Evaluate the time integrated kernel for the above points.
        if t <= t_b:
            vec = -FPI_INV * expi(-xy / (4 * (t - t_a)))
        else:
            vec = FPI_INV * (expi(-xy / (4 * (t - t_b))) - expi(-xy /
                                                                (4 *
                                                                 (t - t_a))))
        # Return the quadrature result.
        return (x_b - x_a) * np.dot(self.log_scheme.weights, vec)

    def evaluate_exact(self, elem_trial: Element, t: float, x: float) -> float:
        """ Evaluates (V 1_trial)(t, x) for elem_trial lying on the
            same pane as x. """
        if t <= elem_trial.time_interval[0]: return 0
        a, b = elem_trial.space_interval
        if x < a or x > b:
            h = min(abs(a - x), abs(b - x))
            k = max(abs(a - x), abs(b - x))
            a, b = elem_trial.time_interval
            if t <= b:
                return -FPI_INV * (PI_SQRT * (2 * sqrt(
                    (t - a))) * (erf(h / (2 * sqrt(
                        (t - a)))) - erf(k / (2 * sqrt(
                            (t - a))))) - h * expi(-(h**2 / (4 * (t - a)))) +
                                   k * expi(-(k**2 / (4 * (t - a)))))
            else:
                return FPI_INV * (
                    2 * PI_SQRT *
                    (sqrt(t - a) *
                     (-erf(h / (2 * sqrt(t - a))) + erf(k /
                                                        (2 * sqrt(t - a)))) +
                     sqrt(t - b) *
                     (erf(h / (2 * sqrt(t - b))) - erf(k /
                                                       (2 * sqrt(t - b))))) +
                    h * expi(h**2 / (4 * (a - t))) - k * expi(k**2 /
                                                              (4 * (a - t))) -
                    h * expi(h**2 / (4 * (b - t))) + k * expi(k**2 /
                                                              (4 * (b - t))))
        elif a < x < b:
            return spacetime_evaluated_1(
                t, *elem_trial.time_interval, x - a) + spacetime_evaluated_1(
                    t, *elem_trial.time_interval, b - x)
        elif x == a or x == b:
            return spacetime_evaluated_1(t, *elem_trial.time_interval, b - a)

    def evaluate_vector(self, t, x_hat):
        """ Returns the vector (V 1_elem)(t, gamma(x_hat)) for all elements in mesh. """
        elems = list(self.mesh.leaf_elements)
        N = len(elems)
        vec = np.zeros(shape=N)
        x = self.mesh.gamma_space.eval(x_hat)
        for j, elem_trial in enumerate(elems):
            vec[j] = self.evaluate(elem_trial, t, x_hat, x)
        return vec

    def rhs_vector(self, f, gauss_order=23):
        """ Returns the vector f(1_elem) for all elements in the mesh. """
        gauss_scheme = gauss_quadrature_scheme(gauss_order)
        gauss_2d = ProductScheme2D(gauss_scheme, gauss_scheme)
        elems = list(self.mesh.leaf_elements)
        N = len(elems)
        vec = np.zeros(shape=N)
        for i, elem_test in enumerate(elems):
            f_param = lambda tx: f(tx[0], elem_test.gamma_space(tx[1]))
            vec[i] = gauss_2d.integrate(f_param, *elem_test.time_interval,
                                        *elem_test.space_interval)
        return vec


from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponseRedirect
from django.views.generic import TemplateView, ListView

from foundation.models import SiteUser
from friends.models import Subscription

class FriendsListView(LoginRequiredMixin, TemplateView):
    template_name = 'friends/friends_list.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        subscribers_s = Subscription.objects.filter(subscriptor_id=self.request.user.id)
        subscribers = []
        for sub in subscribers_s:
            subscribers.append(sub.subscriber)
        subscriptions_s = Subscription.objects.filter(subscriber_id=self.request.user.id)
        subscriptions = []
        for sub in subscriptions_s:
            subscriptions.append(sub.subscriptor)
        friends = []
        for u in SiteUser.objects.exclude(id=self.request.user.id):
            if subscriptions_s.filter(subscriptor_id=u.id).exists() & subscribers_s.filter(subscriber_id=u.id).exists():
                friends.append(u)
        context['friends'] = friends
        context['subscribers'] = list(set(subscribers) - set(friends))
        context['subscriptions'] = list(set(subscriptions) - set(friends))
        return context

@login_required
def subscribe(request, pk):
    Subscription.objects.create(subscriber=request.user, subscriptor_id=pk)
    next_page = request.POST.get('next', '/')
    return HttpResponseRedirect(next_page)

@login_required
def unsubscribe(request, pk):
    Subscription.objects.get(subscriber=request.user, subscriptor_id=pk).delete()
    next_page = request.POST.get('next', '/')
    return HttpResponseRedirect(next_page)


import streamlit as st
import numpy as np
from PIL import Image
from detection.object_detection import detect_object
import cv2

def main():
    st.title("Employee Working or Not Working")

    img_array = upload_image_ui()
    # st.write(img_array.shape)
    # st.write(img_array.shape)

    # rgbImage = cv2.cvtColor(img_array, cv2.COLOR_RGBA2RGB)
    # img_array = rgbImage

    if isinstance(img_array, np.ndarray):
        image = detect_object(img_array)

        st.image(image, width = 412)
#         st.write(f"Person is {label}")

def upload_image_ui():
    uploaded_image = st.file_uploader("Please upload an image file", type=["png", "jpg", "jpeg"])

    if uploaded_image is not None:
        try:
            image = Image.open(uploaded_image)

        except Exception:
            st.error("Error: Invalid image")
        else:
            img_array = np.array(image)
            img_array = cv2.cvtColor(img_array, cv2.COLOR_RGBA2RGB)
            return img_array

if __name__ == '__main__':
    main()


import copy
import logging
from bz2 import BZ2Compressor
from typing import Union, Iterable

import cv2
import gym
import numpy as np
# noinspection PyUnresolvedReferences
import pybullet_envs  # Needs to be imported to register PyBullet environments
from gym import Wrapper
from gym.spaces import Box
from gym.wrappers.atari_preprocessing import AtariPreprocessing

# noinspection PyUnresolvedReferences
import gym_memory_environments  # Needs to be imported to register our custom memory environments
from tools.ae_wrapper import AEWrapper
from tools.configurations import (EpisodeRunnerCfg, ReacherMemoryEnvAttributesCfg, AtariEnvAttributesCfg,
                                  ProcGenEnvAttributesCfg)

class EnvHandler:
    """This class creates and modifies OpenAI-Gym environments."""

    def __init__(self, config: EpisodeRunnerCfg):
        self.config = config

    def make_env(self, env_id: str, render: bool = False, record: str = None, record_force: bool = False):
        if env_id == "ReacherMemory-v0" or env_id == "ReacherMemoryDynamic-v0":
            assert isinstance(self.config.environment_attributes, ReacherMemoryEnvAttributesCfg), \
                "For the environment 'ReacherMemory-v0' one must provide the ReacherMemoryEnvAttributesCfg" \
                " (config.environment_attributes)"

            env = gym.make(
                env_id,
                observation_frames=self.config.environment_attributes.observation_frames,
                memory_frames=self.config.environment_attributes.memory_frames,
                action_frames=self.config.environment_attributes.action_frames)
        elif env_id.startswith("procgen"):
            logging.debug("initiating procgen with memory")

            assert isinstance(self.config.environment_attributes, ProcGenEnvAttributesCfg), \
                "For procgen environment one must provide the ProcGenEnvAttributesCfg" \
                " (config.environment_attributes)"
            env = ProcEnvHandler(env_id, render, self.config.environment_attributes)
        elif env_id == 'QbertHard-v0':
            logging.debug("wrapping QbertNoFrameskip-v4 in QbertGlitchlessWrapper")
            env = QbertGlitchlessWrapper(gym.make('QbertNoFrameskip-v4'))
        elif env_id == 'ReverseShaped-v0':
            env = gym.make('Reverse-v0')
            # these options are specific to reverse-v0 and aren't important enough to be part of the
            # global configuration file.
            env.env.last = 15
            env.env.min_length = 7
            logging.debug("creating env with min_length " + str(
                env.env.min_length) + " and also comparing results over the last " + str(env.env.last) + " runs.")

            logging.debug("wrapping env in ReverseWrapper")
            env = ReverseWrapper(env)
        else:
            env = gym.make(env_id)

        if self.config.use_autoencoder:
            logging.debug("wrapping env in AEWrapper")
            env = AEWrapper(env)
        else:
            if env.spec.id.endswith("NoFrameskip-v4"):
                logging.debug("wrapping env in AtariPreprocessing")

                assert isinstance(self.config.environment_attributes, AtariEnvAttributesCfg), \
                    "For atari environment one must provide the AtariEnvAttributesCfg" \
                    " (config.environment_attributes)"

                # terminal_on_life_loss behaves different than EpisodicLifeEnv
                # terminal_on_life_loss resets the env when the first life is loss so the next agent will start fresh
                # EpisodicLifeEnv does not reset the env, so the next agent will continue where the last one died.
                # env = AtariPreprocessing(env, screen_size=32, scale_obs=True, terminal_on_life_loss=False)
                # env = EpisodicLifeEnv(env)
                env = AtariPreprocessing(env,
                                         screen_size=self.config.environment_attributes.screen_size,
                                         scale_obs=self.config.environment_attributes.scale_obs,
                                         terminal_on_life_loss=self.config.environment_attributes.terminal_on_life_loss,
                                         grayscale_obs=self.config.environment_attributes.grayscale_obs)

        if str(env_id).startswith("BipedalWalker"):
            logging.debug("wrapping env in Box2DWalkerWrapper")
            # remove spurious warning "WARN: Box bound precision lowered by casting to float32" during creation
            gym.logger.MIN_LEVEL = gym.logger.ERROR
            env = Box2DWalkerWrapper(env)
            # gym.logger.MIN_LEVEL = level

        if self.config.novelty:
            if self.config.novelty.behavior_source in ['observation', 'action', 'state']:
                logging.debug("wrapping env in BehaviorWrapper")
                env = BehaviorWrapper(env, self.config.novelty.behavior_source,
                                      self.config.novelty.behavioral_interval,
                                      self.config.novelty.behavioral_max_length)

        if self.config.max_steps_per_run:
            logging.debug("wrapping env in MaxStepWrapper")
            env = MaxStepWrapper(env, max_steps=self.config.max_steps_per_run, penalty=self.config.max_steps_penalty)

        if record is not None:
            env = gym.wrappers.Monitor(env, record, force=record_force)

        return env

class ProcEnvHandler(gym.Env):
    """
    This Wrapper scales to observation to values between 0 and 1.
    Additionally it implements a seed method because for reasons unknown it not implemented upstream
    """

    def __init__(self, env_id: str, render: bool, conf: ProcGenEnvAttributesCfg):
        # todo: maybe add env specific configuration, but only after issue #20 has been implemented
        self.env_id = env_id
        self.render_mode = None
        self.conf = conf
        if render:
            self.render_mode = "rgb_array"
        super().__init__()
        self._env = self._make_inner_env(start_level=0)
        self.spec = copy.deepcopy(self._env.spec)  # deep copy to avoid references to inner gym
        self.action_space = self._env.action_space  # use reference, so action_space.seed() works as expected
        self.obs_dtype = np.float16
        self.input_high = 255
        self.current_level = 0
        assert self.input_high == self._env.observation_space.high.min(), "unexpected bounds for input space"
        assert self.input_high == self._env.observation_space.high.max(), "unexpected bounds for input space"
        assert 0 == self._env.observation_space.low.min(), "unexpected bounds for input space"
        assert 0 == self._env.observation_space.low.max(), "unexpected bounds for input space"
        self.observation_space = Box(low=0, high=1,
                                     shape=(self.conf.screen_size, self.conf.screen_size, 3),
                                     dtype=self.obs_dtype)

    def _make_inner_env(self, start_level):
        self.current_level = start_level
        env = gym.make(self.env_id,
                       distribution_mode=self.conf.distribution_mode,
                       use_monochrome_assets=self.conf.use_monochrome_assets,
                       restrict_themes=self.conf.restrict_themes,
                       use_backgrounds=self.conf.use_backgrounds,
                       num_levels=1,
                       start_level=self.current_level,
                       render_mode=self.render_mode
                       )
        return env

    def _transform_ob(self, ob):
        obs = cv2.resize(ob, (self.conf.screen_size, self.conf.screen_size), interpolation=cv2.INTER_AREA)
        return np.asarray(obs, dtype=self.obs_dtype) / 255.0

    def render(self, mode="human", **kwargs):
        frame = self._env.render(mode=self.render_mode, **kwargs)
        cv2.imshow("ProcGen Agent", frame)
        cv2.waitKey(1)

    def step(self, action):
        ob, rew, done, info = self._env.step(action)
        return self._transform_ob(ob), rew, done, info

    def reset(self):
        del self._env
        self._env = self._make_inner_env(start_level=self.current_level + 1)
        return self._transform_ob(self._env.reset())

    def seed(self, seed=0):
        # explicitly delete old env to avoid memory leak
        del self._env
        self._env = self._make_inner_env(start_level=seed)

class MaxStepWrapper(Wrapper):
    def __init__(self, env, max_steps, penalty):
        super().__init__(env)
        self.steps = 0
        self.max_steps = max_steps
        self.penalty = penalty

    def reset(self, **kwargs):
        self.steps = 0
        return super(MaxStepWrapper, self).reset(**kwargs)

    def step(self, action: Union[int, Iterable[int]]):
        self.steps += 1
        ob, rew, done, info = super(MaxStepWrapper, self).step(action)
        if self.steps > self.max_steps:
            logging.debug("step limit reached")
            done = True
            rew += self.penalty
        return ob, rew, done, info

class QbertGlitchlessWrapper(Wrapper):
    def step(self, action: Union[int, Iterable[int]]):
        ob, rew, done, info = super(QbertGlitchlessWrapper, self).step(action)
        if rew == 500 or rew == 525:
            logging.debug("remove reward to avoid luring enemy into abyss")
            rew = 0
        if rew == 300 or rew == 325:
            logging.debug("removed reward from fruit to avoid repetitive behavior")
            rew = 0
        return ob, rew, done, info

class BehaviorWrapper(Wrapper):
    def __init__(self, env, behavior_source, behavioral_interval, behavioral_max_length):
        super().__init__(env)
        self.behavior_source = behavior_source
        self.behavioral_interval = behavioral_interval
        self.behavioral_max_length = behavioral_max_length
        self._reset_compressor()

    def _reset_compressor(self):
        self.compressed_behavior = b''
        self.compressor = BZ2Compressor(2)
        self.step_count = 0
        self.aggregate = None

    def reset(self, **kwargs):
        return super(BehaviorWrapper, self).reset(**kwargs)

    def _aggregate2compressor(self):
        if self.aggregate is not None:
            data_bytes = np.array(self.aggregate).astype(np.float16).tobytes()
            self.compressed_behavior += self.compressor.compress(data_bytes)
            self.aggregate.fill(0)

    def _record(self, data):
        if self.behavioral_interval < 0:
            # in this case  the actual recording is handled by get_compressed_behavior
            self.aggregate = np.array(data)
            return

        if self.aggregate is None:
            self.aggregate = np.array(data, dtype=np.float32)
            self.aggregate.fill(0)

        if self.behavioral_interval > 0:
            self.aggregate += np.array(data) / self.behavioral_interval

        if self.step_count * self.behavioral_interval < self.behavioral_max_length:
            if self.step_count % self.behavioral_interval == 0:
                self._aggregate2compressor()

    def step(self, action: Union[int, Iterable[int]]):
        ob, rew, done, info = super(BehaviorWrapper, self).step(action)
        if self.behavior_source == "observation":
            self._record(ob)
        elif self.behavior_source == "action":
            self._record(action)
        elif self.behavior_source == "state":
            if hasattr(self.env.unwrapped, "model") and "PyMjModel" in str(type(self.env.unwrapped.model)):
                # since float16.max is only around 65500, we need to make it a little smaller
                data = np.array(self.env.unwrapped.sim.data.qpos.flat) * 10e-3
                self._record(data)
            elif self.env.spec.id.endswith("NoFrameskip-v4"):
                # this is an atari env
                # noinspection PyProtectedMember
                self._record(self.env.unwrapped._get_ram())
            else:
                raise RuntimeError('behavior_source=="state" is unsupported for this environment')
        return ob, rew, done, info

    def get_compressed_behavior(self):
        if self.behavioral_interval < 0:
            # special case, where just the last value is used as BC
            self._aggregate2compressor()
        data = self.compressed_behavior + self.compressor.flush()
        self._reset_compressor()
        return data

class Box2DWalkerWrapper(Wrapper):
    """ simple speedup for bad agents, because some agents just stand still indefinitely and waste simulation time"""

    def __init__(self, *narg, **kwargs):
        super(Box2DWalkerWrapper, self).__init__(*narg, **kwargs)
        self.consecutive_non_movement = 0

    def reset(self, **kwargs):
        self.consecutive_non_movement = 0
        return super(Box2DWalkerWrapper, self).reset(**kwargs)

    def step(self, action):
        ob, rew, done, info = super(Box2DWalkerWrapper, self).step(action)

        if ob[2] < 0.0001:
            self.consecutive_non_movement = self.consecutive_non_movement + 1
            if self.consecutive_non_movement > 50:
                done = True
                rew = rew - 100
        else:
            self.consecutive_non_movement = 0

        return ob, rew, done, info

class ReverseWrapper(Wrapper):
    """In reverse-v0 the readhead should be at a specific position when deciding which symbol to write next.
    This Wrapper adds a penalty when the head was in a wrong position, when a symbol was written"""

    def step(self, action):
        ob, rew, done, info = self.env.step(action)

        if done:
            if rew < 0:
                inp_act, out_act, pred = action
                dist = abs(len(self.unwrapped.target)
                           - self.unwrapped.read_head_position
                           - self.unwrapped.write_head_position)
                if dist > 0:
                    rew -= 1. * dist
                if self.unwrapped.MOVEMENTS[inp_act] != "left":
                    rew -= 1

        return ob, rew, done, info


# -*- coding: utf-8 -*-

if __name__ == '__main__':

    import argparse
    import os
    import unittest
    import sys

    import system_tests

    parser = argparse.ArgumentParser(description="The system test suite")

    parser.add_argument(
        "--config_file",
        type=str,
        nargs=1,
        help="Path to the suite's configuration file",
        default=['suite.conf']
    )
    parser.add_argument(
        "--verbose", "-v",
        action='count',
        help="verbosity level",
        default=1
    )
    parser.add_argument(
        "--debug",
        help="enable debugging output",
        action='store_true'
    )

    parser.add_argument(
        "dir",
        help="directory where the test are searched for (defaults to the config"
        "file's location)",
        default=None,
        type=str,
        nargs='?'
    )

    args = parser.parse_args()
    conf_file = args.config_file[0]
    discovery_root = os.path.dirname(conf_file if args.dir is None else args.dir)
    system_tests.set_debug_mode(args.debug)

    system_tests.configure_suite(conf_file)

    discovered_tests = unittest.TestLoader().discover(discovery_root)
    test_res = unittest.runner.TextTestRunner(verbosity=args.verbose)\
                              .run(discovered_tests)

    sys.exit(0 if len(test_res.failures) + len(test_res.errors) == 0 else 1)


import scipy.misc
import numpy as np
import SimpleITK as sitk
from prepare.utility import get_segmented_lungs, get_augmented_cube
from configs import RESOURCES_PATH, OUTPUT_PATH
from glob import glob
from skimage.measure import regionprops

class CTScan(object):
    def __init__(self, seriesuid, centers, radii, clazz):
        self._seriesuid = seriesuid
        self._centers = centers
        paths = glob(f'''{RESOURCES_PATH}/*/{self._seriesuid}.mhd''')
        path = paths[0]
        self._ds = sitk.ReadImage(path)
        self._spacing = np.array(list(reversed(self._ds.GetSpacing())))
        self._origin = np.array(list(reversed(self._ds.GetOrigin())))
        self._image = sitk.GetArrayFromImage(self._ds)
        self._radii = radii
        self._clazz = clazz
        self._mask = None

    def preprocess(self):
        self._resample()
        self._segment_lung_from_ct_scan()
        self._normalize()
        self._zero_center()
        self._change_coords()

    def save_preprocessed_image(self):
        subdir = 'negatives' if self._clazz == 0 else 'positives'
        file_path = f'''preprocessed/{subdir}/{self._seriesuid}.npy'''
        np.save(f'{OUTPUT_PATH}/{file_path}', self._image)

    def get_info_dict(self):
        (min_z, min_y, min_x, max_z, max_y, max_x) = (None, None, None, None, None, None)
        for region in regionprops(self._mask):
            min_z, min_y, min_x, max_z, max_y, max_x = region.bbox
        assert (min_z, min_y, min_x, max_z, max_y, max_x) != (None, None, None, None, None, None)
        min_point = (min_z, min_y, min_x)
        max_point = (max_z, max_y, max_x)
        return {'seriesuid': self._seriesuid, 'radii': self._radii, 'centers': self._centers,
                'spacing': list(self._spacing), 'lungs_bounding_box': [min_point, max_point], 'class': self._clazz}

    def _resample(self):
        spacing = np.array(self._spacing, dtype=np.float32)
        new_spacing = [1, 1, 1]
        imgs = self._image
        new_shape = np.round(imgs.shape * spacing / new_spacing)
        true_spacing = spacing * imgs.shape / new_shape
        resize_factor = new_shape / imgs.shape
        imgs = scipy.ndimage.interpolation.zoom(imgs, resize_factor, mode='nearest')
        self._image = imgs
        self._spacing = true_spacing

    def _segment_lung_from_ct_scan(self):
        result_img = []
        result_mask = []
        for slicee in self._image:
            rimg, rmsk = get_segmented_lungs(slicee)
            result_img.append(rimg)
            result_mask.append(rmsk)
        self._image = np.asarray(result_img)
        self._mask = np.asarray(result_mask, dtype=int)

    def _world_to_voxel(self, worldCoord):
        stretchedVoxelCoord = np.absolute(np.array(worldCoord) - np.array(self._origin))
        voxelCoord = stretchedVoxelCoord / np.array(self._spacing)
        return voxelCoord.astype(int)

    def _get_world_to_voxel_coords(self, idx):
        return tuple(self._world_to_voxel(self._centers[idx]))

    def _get_voxel_coords(self):
        voxel_coords = [self._get_world_to_voxel_coords(j) for j in range(len(self._centers))]
        return voxel_coords

    def _change_coords(self):
        new_coords = self._get_voxel_coords()
        self._centers = new_coords

    def _normalize(self):
        MIN_BOUND = -1200
        MAX_BOUND = 600.
        self._image = (self._image - MIN_BOUND) / (MAX_BOUND - MIN_BOUND)
        self._image[self._image > 1] = 1.
        self._image[self._image < 0] = 0.
        self._image *= 255.

    def _zero_center(self):
        PIXEL_MEAN = 0.25 * 256
        self._image = self._image - PIXEL_MEAN

class PatchMaker(object):
    def __init__(self, seriesuid: str, coords: list, radii: list, spacing: list, lungs_bounding_box: list,
                 file_path: str,
                 clazz: int):
        self._seriesuid = seriesuid
        self._coords = coords
        self._spacing = spacing
        self._radii = radii
        self._image = np.load(file=f'{file_path}')
        self._clazz = clazz
        self._lungs_bounding_box = lungs_bounding_box

    def _get_augmented_patch(self, idx, rot_id=None):
        return get_augmented_cube(img=self._image, radii=self._radii, centers=self._coords,
                                  spacing=tuple(self._spacing), rot_id=rot_id, main_nodule_idx=idx,
                                  lungs_bounding_box=self._lungs_bounding_box)

    def get_augmented_patches(self):
        radii = self._radii
        list_of_dicts = []
        for i in range(len(self._coords)):
            times_to_sample = 1
            if radii[i] > 15.:
                times_to_sample = 2
            elif radii[i] > 20.:
                times_to_sample = 6
            for j in range(times_to_sample):
                rot_id = int((j / times_to_sample) * 24 + np.random.randint(0, int(24 / times_to_sample)))
                img, radii2, centers, lungs_bounding_box, spacing, existing_nodules_in_patch = \
                    self._get_augmented_patch(idx=i, rot_id=rot_id)
                existing_radii = [radii2[i] for i in existing_nodules_in_patch]
                existing_centers = [centers[i] for i in existing_nodules_in_patch]
                subdir = 'negatives' if self._clazz == 0 else 'positives'
                file_path = f'''augmented/{subdir}/{self._seriesuid}_{i}_{j}.npy'''
                list_of_dicts.append(
                    {'seriesuid': self._seriesuid, 'centers': existing_centers, 'sub_index': f'{i}_{j}',
                     'lungs_bounding_box': lungs_bounding_box, 'radii': existing_radii, 'class': self._clazz})
                np.save(f'{OUTPUT_PATH}/{file_path}', img)
        return list_of_dicts


'''
二叉树的前序遍历
给你二叉树的根节点 root ，返回它节点值的 前序 遍历。
'''

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
from typing import List, Optional

class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        '''递归写法'''
        # def preorder(root:TreeNode):
        #     if root==None:
        #         return
        #     res.append(root.val) # 根节点在前
        #     preorder(root.left)
        #     preorder(root.right)
        # res=[]
        # preorder(root)
        # return res

        '''迭代写法
        也可以用迭代的方式实现方法一的递归函数，两种方式是等价的，
        区别在于递归的时候隐式地维护了一个栈，而我们在迭代的时候需要显式地将这个栈模拟出来，
        其余的实现与细节都相同'''
        ans=[]
        stack=[]
        stack.append(root)
        while stack:
            node=stack.pop()
            if node==None:
                continue
            ans.append(node.val)
            stack.append(node.right)
            stack.append(node.left)
        return ans

code/数据结构/二叉树/树的遍历/2022-04-05_1-二叉树的前序遍历.py


# -*- coding: utf-8 -*-
"""
Created on Wed Mar 27 12:57:16 2019

@author: 123456
"""
import numpy as np

from sklearn.metrics.pairwise import cosine_similarity

def file2matrix(filename):
    f = open(filename) # 打开文件
    dataSet = f.readlines() # 读取文件的全部内容
    numberOfLines = len(dataSet) # 获得数据集的行数
    data = np.zeros((numberOfLines, 3)) # 创建一个初始值为0，
                                             # 大小为 numberOfLines x 3 的数组
    label = [] # 用于保存没个数据的类别标签
    index = 0
    for line in dataSet: # 处理每一行数据
        line = line.strip() # 去掉行首尾的空白字符,(包括'\n', '\r', '\t', ' ')
        listFromLine = line.split() # 分割每行数据，保存到一个列表中
        data[index, :] = listFromLine[0:3] # 将列表中的特征保存到reurnMat中
        label.append(int(listFromLine[-1])) # 保存分类标签
        index += 1
    label = np.array(label)
    return data, label

data, label = file2matrix('dating/datingTestSet2.txt')

sims = cosine_similarity(data)

sorted_sims = np.argsort(-sims)  #np.sort(-sims)
print(sorted_sims)


import pytest
import pytest_mock
import requests_mock
from mock import MagicMock
import os
from visualize_data import graphics, x_axis_coordinates, y_axis_coordinates
import numpy as np
import bokeh
import requests

mock = MagicMock()

xaxis = mock.__iter__.return_value = range(100)
yaxis = mock.__iter__.return_value = range(100)

my_graphics = graphics.line(
                            xaxis,
                            yaxis,
                            color = 'red',
                            legend_label = 'test_label'
                            )

def test_output_file_has_been_created():
    assert os.path.isfile('data.html')

def test_graphiccs_xaxis_label_must_be_date():
    assert graphics.xaxis.axis_label == 'Date'

def test_graphics_yaxis_label_must_be_price_usd():
    assert graphics.yaxis.axis_label == 'Price (in USD)'

def test_any_element_in_x_axis_coordinates_is_type_datetime64():
    assert type(x_axis_coordinates[0]) == np.datetime64
    assert type(x_axis_coordinates[5]) == np.datetime64
    assert type(x_axis_coordinates[13]) == np.datetime64
    assert type(x_axis_coordinates[25]) == np.datetime64

def test_any_element_in_x_axis_coordinates_is_type_date():
    assert type(y_axis_coordinates[0]) == float
    assert type(y_axis_coordinates[5]) == float
    assert type(y_axis_coordinates[13]) == float
    assert type(y_axis_coordinates[25]) == float

def test_type_generated_graphics_instance():
    assert type(my_graphics) == bokeh.models.renderers.GlyphRenderer

def test_legend_location():
    assert graphics.legend.location == 'top_left'

def test_correct_HTML_response(requests_mock):
    requests_mock.get("http://your/custom/file/path", text="data")
    response = requests.get("http://your/custom/file/path")

    assert response.text == "data"


import requests
import json
import sys
from elasticsearch import Elasticsearch

#Loop to check which node in cluster is the current master
ESMaster=''
masterIndex=0
while ESMaster == '' and masterIndex <= 2:
   ESMasterResponse=requests.get('http://prod-hq-logging-es-master20{}:9200/_cat/master?pretty&h=node'.format(masterIndex))
   ESMaster = ESMasterResponse.text.replace("\n","")
   masterIndex += 1
   print("Master is {}".format(ESMaster))

#Establish connection to ES master node
es = Elasticsearch("http://{}:9200".format(ESMaster))

#Search cluster for indices with non-null values for read-only block
openIndices_request=requests.get('http://{}:9200/_all/_settings/index.blocks.read_only_allow_delete*'.format(ESMaster))
openIndices_json=json.loads(openIndices_request.text)

#If any found with read-only block, list them
trueRoIndices = [x for x in openIndices_json if openIndices_json[x]['settings']['index']['blocks']['read_only_allow_delete'] == 'true']
falseRoIndices = [x for x in openIndices_json if openIndices_json[x]['settings']['index']['blocks']['read_only_allow_delete'] == 'false']

#If none found, report that and end
if len(trueRoIndices) == 0 and len (falseRoIndices) == 0:
   print("No indices detected with non-null values for read-only setting.")

#If one or more found, fix them and report
else:
   if len(trueRoIndices) > 0:
      print("{} read-only indices detected:".format(len(trueRoIndices)))
      print(trueRoIndices)
      for roIndex in trueRoIndices:
         es.indices.put_settings(index=roIndex, body={
         "index.blocks.read_only_allow_delete": None
         })
         print("Removing true read-only flag from {}".format(roIndex))

   if len(falseRoIndices) > 0:
      print("{} indices detected with read-only flag set to false instead of null:".format(len(falseRoIndices)))
      print(falseRoIndices)
      for roIndex in falseRoIndices:
         es.indices.put_settings(index=roIndex, body={
         "index.blocks.read_only_allow_delete": None
         })
         print("Removing false read-only flag from {}".format(roIndex))


"""동영상을 프레임 단위로 쪼개주는 코드"""
import cv2

vidcap = cv2.VideoCapture(r'C:\Users\kcjer\OneDrive\바탕 화면\1.mp4')

count = 6000

while (vidcap.isOpened()):
    ret, image = vidcap.read()

    if (int(vidcap.get(1)) % 6000 == 0):
        resized_image = cv2.resize(image, (192, 192))
        cv2.imwrite(f"C:/imgcollect/{count}.jpg", resized_image)
        print(count)
        count += 1

vidcap.release()


from enum import IntEnum
from functools import reduce
from common import io

def run():
    print("Part 1 result:", part1())
    print("Part 2 result:", part2())

def part1():
    return [x for x in follow_instructions(parse_input("day10/input.txt"))
        if x[1] and x[1][0][0] == 17 and x[1][1][0] == 61][0][0]

def part2():
    outputs = ([x for x in follow_instructions(parse_input("day10/input.txt"))][-1])[2]
    return reduce(lambda acc, x: (acc * x[0]), outputs[:3], 1)

def follow_instructions(instr):
    # Perform all one-time initialisation before the generator cycle
    bot_count = max([x[i] for i in [2, 4] if x[i+1] == DestType.Bot] for x in instr if x[0] == InstructionType.Give)[0] + 1
    out_count = max([x[i] for i in [2, 4] if x[i+1] == DestType.Output] for x in instr if x[0] == InstructionType.Give)[0] + 1

    bots = [[] for _ in range(bot_count)]
    outputs = [[] for _ in range(out_count)]
    dist = {x[1]: ((x[2], x[3]), (x[4], x[5])) for x in instr if x[0] == InstructionType.Give}

    for x in instr:
        if x[0] == InstructionType.Init:
            bots[x[1]].append(x[2])

    # Evaluation cycle
    eval = [i for (i, x) in enumerate(bots) if len(x) == 2]
    while eval:
        i = eval.pop()
        vals = sorted(bots[i])
        assign = dist[i]

        yield((i, [(vals[ix], assign[ix]) for ix in range(2)], outputs))  # Yield { bot, [(val0, tgt0), (val1, tgt1)], output }

        bots[i] = []
        for (i, x) in enumerate(assign):
            [bots, outputs][x[1] == DestType.Output][x[0]].append(vals[i])

        eval.extend([x[0] for x in assign if x[1] == DestType.Bot and len(bots[x[0]]) == 2])

    yield((None, None, outputs))

def parse_input(path):
    rows = [x.split() for x in io.read_file(path).splitlines(False)]
    return [
        (InstructionType.Init, int(x[5]), int(x[1])) if x[2] == 'goes'      # { bot, init-value }
        else (InstructionType.Give, int(x[1]),                              # { bot, give-low, type-low, give-high, type-high }
              int(x[6]), DestType.Output if x[5] == 'output' else DestType.Bot,
              int(x[11]), DestType.Output if x[10] == 'output' else DestType.Bot) if x[2] == 'gives'

        else "ERROR"
    for x in rows]

class InstructionType(IntEnum):
    Init = 0
    Give = 1

class DestType(IntEnum):
    Bot = 0
    Output = 1