"""
A registry class to handle Format classes and provide lists of them when
this is useful for i.e. identifying the best tool to read a given range
of image formats.
"""
from __future__ import annotations

import importlib.metadata
import os
import typing
from typing import Callable

from dxtbx.util import get_url_scheme

if typing.TYPE_CHECKING:
    from dxtbx.format.Format import Format

def get_format_class_for(format_class_name: str) -> type[Format]:
    """Return the named format class
    :param format_class_name: Name of the format class
    :return: The (uninstantiated) class object
    """
    return get_format_class_index()[format_class_name][0]()

def get_format_class_index() -> dict[str, tuple[Callable[[], type[Format]], list[str]]]:
    """Return a dictionary of all known format classes.
    :return: A dictionary containing entries
             {format_class_name: (format_class_factory_function, [base_class_names])}
             The factory function takes no arguments and returns an
             uninstantiated format class. This avoids importing all
             format classes.
    """
    if not hasattr(get_format_class_index, "cache"):
        class_index = {}
        for e in importlib.metadata.entry_points()["dxtbx.format"]:
            if ":" in e.name:
                format_name, base_classes_str = e.name.split(":", 1)
                base_classes = tuple(base_classes_str.split(","))
            else:
                format_name, base_classes = e.name, ()
            class_index[format_name] = (e.load, base_classes)
        setattr(get_format_class_index, "cache", class_index)
    register = get_format_class_index.cache.copy()  # type: ignore
    return register

def get_format_class_dag() -> dict[str, list[str]]:
    """Return a directed acyclical graph of the format classes.
    :return: A dictionary with entries
             {format class name: [subformat class names]}
    """
    if not hasattr(get_format_class_dag, "cache"):
        index = {
            name: class_info[1] for name, class_info in get_format_class_index().items()
        }
        dag: dict[str, list[str]] = {}
        for name in index:
            for parent in index[name]:
                dag.setdefault(parent, []).append(name)
        for key in dag:
            dag[key].sort()
        setattr(get_format_class_dag, "cache", dag)
    dag = get_format_class_dag.cache.copy()  # type: ignore
    return dag

_format_dag: dict[str, list[str]] = get_format_class_dag()

def get_format_class_for_file(
    image_file: str | bytes | os.PathLike, format_hint: str | None = None
) -> type[Format] | None:
    """Find the best format handler in the registry for given image file
    :param image_file: A string containing the file path to an image
    :param format_hint: An optional string of a format class name that should
                        be checked first
    :return: An uninstantiated format class, if a matching one was found,
             otherwise None
    """

    # Grab the scheme from this URI
    scheme = get_url_scheme(image_file)

    image_file_str = os.fspath(image_file)

    # If a format hint was given then find all paths through the DAG leading
    # to this format class. Create a set containing all format class names
    # on those paths (priority_formats), and use the information whether a
    # format name is in the set to prioritise it during the format search.
    priority_formats = set()
    if format_hint:
        priority_candidates = {format_hint}
        dagset = {f: set(subf) for f, subf in _format_dag.items()}
        while priority_candidates:
            priority_formats.update(priority_candidates)
            priority_candidates = {
                f
                for f, subf in dagset.items()
                if priority_candidates.intersection(subf)
            }

    def format_sort(format_name):
        return (0 if format_name in priority_formats else 1, format_name)

    def recurse(format_name, image_file):
        # Recursively check whether any of the children understand image_file,
        # in which case they are preferred over the parent format.
        for child in sorted(_format_dag.get(format_name, []), key=format_sort):
            format_class = get_format_class_for(child)
            if scheme in format_class.schemes and format_class.understand(image_file):
                return recurse(child, image_file)
        return get_format_class_for(format_name)

    # Starting at "Format" and using any potential prioritisation information
    # look for any path through the DAG of formats, stopping at the first
    # accepting leaf node
    for format in sorted(_format_dag["Format"], key=format_sort):
        format_class = get_format_class_for(format)
        if scheme in format_class.schemes and format_class.understand(image_file_str):
            return recurse(format, image_file_str)

    return None


import pymqi as pymqi
from mqtools import smqpcf as SMQPCF
from mqtools import mqpcfget as mqpcfget
from mqtools import mqpcfset as mqpcfset
from sys import stderr
# import string

def eprint(*args, **kwargs):
    print(*args, file=stderr, **kwargs)

"""
q090210_.htm

MQIA_* (Integer Attribute Selectors)
MQIACF_* (Command format Integer Parameter Types)
MQIACH_* (Command format Integer Channel Types)
MQIAMO_* (Command format Integer Monitoring Parameter Types)
MQIAMO64_* (Command format 64-bit Integer Monitoring Parameter Types)

selectTypeS= {
  "ACCOUNTING_TOKEN": ("MQBACF",7010),
  "ALTERNATE_SECURITYID": ("MQBACF",7019),
  "CF_LEID": ("MQBACF",7014),

sLookupToI = {

,("MQACTP","FORWARD"): 1
,("MQACTP","NEW"): 0
,("MQCA","APPL_DESC"): 3174  # strictly it is MQCACF_APPL_DESC
                             # but this assumes you know it is for a Command

sLookupTypes ={
  20:"MQQT"
, 134:"MQMON"
, 123:"MQMON"
, 128:"MQMON"
, 4:"MQOO"
, 57:"MQIT"
, 9:"MQQA_IG"

sMQLOOKUP = {
,("MQBT",1): "OTMA"
,("MQCA",3134): "ACTIVITY_DESC"
,("MQCA",3172): "ADMIN_TOPIC_NAMES
,("MQCMD",9): "CLEAR_Q"
,("MQCMD",184): "CLEAR_TOPIC_STRING"
,("MQCMD",99): "COMMAND_EVENT"
,("MQRC",2386): "AUTH_INFO_TYPE_ERROR"
,("MQRC",2003): "BACKED_OUT"
,("MQRC",2362): "BACKOUT_THRESHOLD_REACHED"
,("MQRC",2303): "BAG_CONVERSION_ERROR"
,("MQRC",2326): "BAG_WRONG_TYPE"

"""

class mqpcf(object):

    """PCF()
    Process IBM MQ PCF objects.  Create messages with commands and parse data

    MQPCFSET  is used to create the PCF message
    MQPCFGET is used to parse a passed in message in PCF format

    """

    def __init__(self,debug = 0):
        self.pcfset = mqpcfset.mqpcfset(debug=debug)
        self.pcfget = mqpcfget.mqpcfget()

    def create_request(self,request,*args):
        """ Call the MQPCFSET to do the work"""
        ret= self.pcfset.create_request(request, *args)
        return ret

    def parse_data(self, buffer='', strip="no", debug= 0):
        """ Call the MQPCFGET to do the work"""
        ret = self.pcfget._parse_data(buffer, strip, debug)
        return ret

    def getAllData(self):
        """
        return the all the parsed data
        """
        return self.all_data

    def get_h_admin_queue(self,qmgr=None,queue=b'SYSTEM.ADMIN.COMMAND.QUEUE'):
        admin = pymqi.OD()
        #   print("getAdminQueue",type(qmgr),type(queue))
        if not isinstance(queue,bytes):
            queue = queue.encode()
        if qmgr is None:
            raise ValueError("QMGR name must be specified")
        admin.ObjectName = queue
        hAdmin = pymqi.Queue(qmgr, admin, pymqi.CMQC.MQOO_OUTPUT)
        return hAdmin
        #
        # get replyqueue - by default create a dynamic queue
        #
    def get_h_reply_queue(self,qmgr=None,queue=None):
        """ create a queue object using passed, or default queue name"""
        if (queue is None):
            queue=b'SYSTEM.MQSC.REPLY.QUEUE'
        hReply = pymqi.Queue(qmgr,queue,pymqi.CMQC.MQOO_INPUT_SHARED|
                             pymqi.CMQC.MQOO_INQUIRE)
        return hReply

        #def getAdminMD(self):
        #    """
        #    Create an MQMD for reply to queue
        #    """
        #    md = pymqi.MD()
        #    md.ReplyToQ = b'CP0000'
        #    md.MsgType = pymqi.CMQC.MQMT_REQUEST
        #    md.Feedback = pymqi.CMQC.MQFB_NONE
        #    md.Format = pymqi.CMQC.MQFMT_ADMIN
        #   return md

    def create_admin_MD_CMD(self,replyToQ=None):
        """
        Create an MQ for reply to queue, and fillin the replyto queue
        """

        md = pymqi.MD() # create an MD
        if replyToQ is None:
            raise ValueError("You must specify the replyToQ")

        # and fill in the fields
        md.ReplyToQ = replyToQ
        md.MsgType = pymqi.CMQC.MQMT_REQUEST
        md.Feedback = pymqi.CMQC.MQFB_NONE
        md.Format = pymqi.CMQC.MQFMT_STRING
        return md

    def create_admin_MD(self,hReplyToQ=None):
        """
        Create an MQ for reply to queue, and fillin the replyto queue
        """

        md = pymqi.MD() # create an MD
        if hReplyToQ is None:
            raise ValueError("You must specify the hReplOD in getAdminMD, to provide the reply to queue")
        qname = hReplyToQ.inquire(pymqi.CMQC.MQCA_Q_NAME)
        # and fill in the fields
        md.ReplyToQ = qname
        md.MsgType = pymqi.CMQC.MQMT_REQUEST
        md.Feedback = pymqi.CMQC.MQFB_NONE
        md.Format = pymqi.CMQC.MQFMT_ADMIN
        return md

    def resetMD(self,md=None):
        """
        Clear the msgid and correlid fields in the MD
        """
        if md is None:
            raise ValueError("You must specify the MD to reset")
        md.MsgId = b''
        md.Correlid = b''
        md.MsgType = pymqi.CMQC.MQMT_REQUEST
        md.Feedback = pymqi.CMQC.MQFB_NONE
        md.Format = pymqi.CMQC.MQFMT_ADMIN
        return md

def lookup_reason(reason):
    """ Lookup reason code from number of string """
    return  SMQPCF.sMQLOOKUP.get(("MQRCCF", reason), reason)
# in case this is executed on its own
if (__name__ == '__main__'):
    pass


#!/usr/bin/env python3

# std import
import os
import csv
import sys
import argparse
import subprocess

from jinja2 import FileSystemLoader
from jinja2 import Environment

from Bio import SeqIO

def main(args=None):

    if args is None:
        args = sys.argv[1:]

    parser = argparse.ArgumentParser(prog="knot.analysis.generate_report")

    parser.add_argument("-i", "--input_prefix", type=str, help="prefix of knot output", required=True)
    parser.add_argument("-o", "--output", type=argparse.FileType('wb'), help="path where report was write", required=True)

    parser.add_argument("-c", "--classification", help="Add path classification in report", action="store_true")
    parser.add_argument("-p", "--hamilton-path", help="Add hamilton path in report", action="store_true")

    args = vars(parser.parse_args(args))

    template_path = os.path.dirname(__file__) + os.sep + "template" + os.sep
    env = Environment(loader=FileSystemLoader(template_path))
    template = env.get_template('report.jinja2.html')

    param = dict()

    contig_info(param, open(args["input_prefix"] + "_knot/contigs.fasta"))

    if args["classification"]:
        run_classification(args["input_prefix"] + "_AAG.csv", args["input_prefix"])
        classification_info(param, open(args["input_prefix"]+"_knot" + os.sep + "classification.csv"))

    if args["hamilton_path"]:
        run_hamilton(args["input_prefix"] + "_AAG.csv", args["input_prefix"])
        hamilton_info(param, open(args["input_prefix"]+"_knot" + os.sep + "hamilton_path.csv"))

    full_aag_info(param, open(args["input_prefix"]+"_AAG.csv"))

    build_AAG_representation(param, open(args["input_prefix"]+"_AAG.csv"))

    if args["classification"]:
        build_clean_AAG(param, open(args["input_prefix"]+"_AAG.csv"), open(args["input_prefix"] + "_knot" + os.sep + "classification.csv"))

    args["output"].write(template.render(param).encode("utf-8"))

def contig_info(param, contig_file):

    tig2len = dict()
    for record in SeqIO.parse(contig_file, "fasta"):
        tig2len[record.id] = len(record.seq)

    param["tig_info"] = tig2len

def run_classification(aag_path, prefix_output):
    subprocess.run(["knot.analysis.classifications", "-i", aag_path, "-o", prefix_output + "_knot" + os.sep + "classification.csv"])

def __classification_info(classification_file):
    ext2type = dict()
    for row in csv.DictReader(classification_file):
        ext2type[(row["ext1"], row["ext2"])] = row["type"]

    return ext2type

def classification_info(param, classification_file):
    param["classification_info"] = __classification_info(classification_file)

def run_hamilton(aag_path, prefix_output):
    subprocess.run(["knot.analysis.hamilton_path", "-i", aag_path, "-o", prefix_output + "_knot" + os.sep + "hamilton_path.csv"])

def hamilton_info(param, hamilton_file):

    hamilton_path = list()
    for row in csv.reader(hamilton_file, delimiter=";"):
        hamilton_path.append((list(row[0].split(",")), row[1]))

    param["hamilton_info"] = hamilton_path

def full_aag_info(param, aag_file):

    aag_record = list()
    for row in csv.DictReader(aag_file):
        aag_record.append((row["tig1"], row["tig2"], row["nb_base"], row["nb_read"], row["nbread_contig"].split(";"), row["read1"], row["read2"]))

    param["full_aag_info"] = aag_record

def get_aag_graph(aag_file):

    edges_dict = dict()
    tig_set = set()
    for row in csv.DictReader(aag_file):
        tig_set.add(row["tig1"].split("_")[0])
        tig_set.add(row["tig2"].split("_")[0])

        key = frozenset((row["tig1"], row["tig2"]))

        if row["paths"] == "not_found":
            continue

        if key in edges_dict and edges_dict[key] < int(row["nb_base"]):
            continue

        edges_dict[frozenset((row["tig1"], row["tig2"]))] = int(row["nb_base"])

    return edges_dict, tig_set

def __construct_tig(tig_set):
    nodes = ""
    edges = ""

    for tig in tig_set:
        nodes += "{{ id: '{}_begin', label: 'begin' }},\n".format(tig, tig)
        nodes += "{{ id: '{}_end', label: 'end' }},\n".format(tig, tig)

    for tig in tig_set:
        e1 = tig + "_begin"
        e2 = tig + "_end"
        edges += "{{from: '{}', to: '{}', label: '{}', width: 10, length: 1}},\n".format(e1, e2, tig)

    return nodes, edges

def build_AAG_representation(param, aag_file):
    edges_dict, tig_set = get_aag_graph(aag_file)

    nodes, edges = __construct_tig(tig_set)

    for (tig1, tig2), length in edges_dict.items():
        if length <= 0:
            length = "overlap"
        edges += "{{ from: '{}', to: '{}', label: '{}', id: '{}' }},\n".format(tig1, tig2, length, tig1+"-"+tig2)

    param["aag_nodes"] = nodes
    param["aag_edges"] = edges

def build_clean_AAG(param, aag, classification):
    edges_dict, tig_set = get_aag_graph(aag)
    classification = __classification_info(classification)
    nodes, edges = __construct_tig(tig_set)

    for (tig1, tig2), value in classification.items():
        if not value.endswith("adjacency"):
            continue

        key = frozenset((tig1, tig2))
        length = edges_dict[key]

        if length <= 0:
            length = "overlap"
        edges += "{{ from: '{}', to: '{}', label: '{}', id: '{}' }},\n".format(tig1, tig2, length, tig1+"-"+tig2)

    param["aag_clean_nodes"] = nodes
    param["aag_clean_edges"] = edges

if __name__ == "__main__":
    main()


import json
def VMPFC(si,a,m,p,e): #si:Stimulus, a:Hidonic, m:Magnitude, p:Probability, e:salience
    r = []
    mayor = []
    action = DLPPFC()# take the disponible actions from DLPFC function
    experience = VLPFC(si) #Use the historial associacions from VLPFC fuction

    k=0.4 #volatil variable
    c =0.3 #volatil variable
    Pv = (k*(a*m*p))+(c*e)/(k+c) #Utility stabelized
    print("Pv:",Pv)
    labelo = [Valorations(a),Valorations(m),Valorations(p),Valorations(e),Valorations(Pv)] #Label of status string
    #rule
    if(experience !=0):
        if (Pv >= experience["Utility"]): #compare only the stimulus selected
            #labelo.append(Valorations(Pv)) #add the label to labels array
            r = [si,action,Pv] #crate tuple stimulus, action, Utility
        else:
            all=VLPFC(1) #incert "1" to obtain all the historial
            for i in all:
                mayor.append(i["Utility"])
                aa=max(mayor) #obtain the biggest utility from the historial
            for i in all:
                if aa == i["Utility"]: #look for the associasion corresponding with the biggest ulility
                    si = str(i["if"])
            r=[si, action,aa]    #append the new biggest associasion

    return labelo, r

def VLPFC(si):#Assosiations historial
    historial = ""
    memory_association = ({"Id":0,"if":"A" ,"then":1,"Utility":0.64},{"Id":1,"if":"B" ,"then":1,"Utility":0.23},
    {"Id":2,"if":"C" ,"then":1,"Utility":0.54},{"Id":3,"if":"D" ,"then":1,"Utility":0.70})
    a = json.dumps(memory_association)
    memory_association = json.loads(a)
    for i in memory_association:
        if(i["if"] == si):
            historial = i
            print(historial)
    if(si == 1):
        historial = memory_association
    return historial

def DLPPFC():#disponible actions
    act = "selecto"
    return act

def Valorations(num): #Label Hidonic states
    val = []
    layer = ""
    if num >= 0.87:
        layer = "Excelente"
    elif num < 0.87 and num >= 0.55:
        layer = "Very_good"
    elif num < 0.55 and num >= 0.35:
        layer = "Good"
    elif num < 0.35 and num >= 0.15:
        layer = "More_less_good"
    elif num < 0.15 and num >= 0.01:
        layer = "Few_good"
    elif num == 0:
        layer = "Neutral"
    elif num > -0.15 and num <= -0.01:
        layer = "Few_bad"
    elif num > -0.35 and num <= -0.15:
        layer = "More_less_bad"
    elif num > -0.55 and num <= -0.35:
        layer = "Bad"
    elif num > -0.87 and num <= -0.55:
        layer = "Very_bad"
    elif num <= -0.87:
        layer = "Horrible"
    val.append(layer)

    return val

print(VMPFC("A", -0.53,0.57,1,-0.87)) #incert (stimulus, hidonic-value, reward-magnitude, reward-probability, incentive-salience)


import warnings

import torch
import torch.multiprocessing as mp

import pyro
from pyro.infer.mcmc.hmc import HMC
from pyro.infer.mcmc.nuts import NUTS
from pyro.infer.mcmc.util import diagnostics, initialize_model, print_summary
from pyro.infer.mcmc.api import _UnarySampler, _MultiSampler
import pyro.poutine as poutine

from FrequencyModulatedKernelBO.pyro_cbo.infer.mcmc.slice import Slice

class MCMC(object):
    """
    Wrapper class for Markov Chain Monte Carlo algorithms. Specific MCMC algorithms
    are TraceKernel instances and need to be supplied as a ``kernel`` argument
    to the constructor.
    .. note:: The case of `num_chains > 1` uses python multiprocessing to
        run parallel chains in multiple processes. This goes with the usual
        caveats around multiprocessing in python, e.g. the model used to
        initialize the ``kernel`` must be serializable via `pickle`, and the
        performance / constraints will be platform dependent (e.g. only
        the "spawn" context is available in Windows). This has also not
        been extensively tested on the Windows platform.
    :param kernel: An instance of the ``TraceKernel`` class, which when
        given an execution trace returns another sample trace from the target
        (posterior) distribution.
    :param int num_samples: The number of samples that need to be generated,
        excluding the samples discarded during the warmup phase.
    :param int warmup_steps: Number of warmup iterations. The samples generated
        during the warmup phase are discarded. If not provided, default is
        half of `num_samples`.
    :param int num_chains: Number of MCMC chains to run in parallel. Depending on
        whether `num_chains` is 1 or more than 1, this class internally dispatches
        to either `_UnarySampler` or `_MultiSampler`.
    :param dict initial_params: dict containing initial tensors in unconstrained
        space to initiate the markov chain. The leading dimension's size must match
        that of `num_chains`. If not specified, parameter values will be sampled from
        the prior.
    :param hook_fn: Python callable that takes in `(kernel, samples, stage, i)`
        as arguments. stage is either `sample` or `warmup` and i refers to the
        i'th sample for the given stage. This can be used to implement additional
        logging, or more generally, run arbitrary code per generated sample.
    :param str mp_context: Multiprocessing context to use when `num_chains > 1`.
        Only applicable for Python 3.5 and above. Use `mp_context="spawn"` for
        CUDA.
    :param bool disable_progbar: Disable progress bar and diagnostics update.
    :param bool disable_validation: Disables distribution validation check. This is
        disabled by default, since divergent transitions will lead to exceptions.
        Switch to `True` for debugging purposes.
    :param dict transforms: dictionary that specifies a transform for a sample site
        with constrained support to unconstrained space.
    """
    def __init__(self, kernel, num_samples, warmup_steps=None, initial_params=None,
                 num_chains=1, hook_fn=None, mp_context=None, disable_progbar=False,
                 disable_validation=True, transforms=None):
        self.warmup_steps = num_samples if warmup_steps is None else warmup_steps  # Stan
        self.num_samples = num_samples
        self.kernel = kernel
        self.transforms = transforms
        self.disable_validation = disable_validation
        self._samples = None
        self._args = None
        self._kwargs = None
        if isinstance(self.kernel, (HMC, NUTS)) and self.kernel.potential_fn is not None:
            if initial_params is None:
                raise ValueError("Must provide valid initial parameters to begin sampling"
                                 " when using `potential_fn` in HMC/NUTS kernel.")
        parallel = False
        if num_chains > 1:
            # check that initial_params is different for each chain
            if initial_params:
                for v in initial_params.values():
                    if v.shape[0] != num_chains:
                        raise ValueError("The leading dimension of tensors in `initial_params` "
                                         "must match the number of chains.")
                # FIXME: probably we want to use "spawn" method by default to avoid the error
                # CUDA initialization error https://github.com/pytorch/pytorch/issues/2517
                # even that we run MCMC in CPU.
                if mp_context is None:
                    # change multiprocessing context to 'spawn' for CUDA tensors.
                    if list(initial_params.values())[0].is_cuda:
                        mp_context = "spawn"

            # verify num_chains is compatible with available CPU.
            available_cpu = max(mp.cpu_count() - 1, 1)  # reserving 1 for the main process.
            if num_chains <= available_cpu:
                parallel = True
            else:
                warnings.warn("num_chains={} is more than available_cpu={}. "
                              "Chains will be drawn sequentially."
                              .format(num_chains, available_cpu))
        else:
            if initial_params:
                initial_params = {k: v.unsqueeze(0) for k, v in initial_params.items()}

        self.num_chains = num_chains
        self._diagnostics = [None] * num_chains

        if parallel:
            self.sampler = _MultiSampler(kernel, num_samples, self.warmup_steps, num_chains, mp_context,
                                         disable_progbar, initial_params=initial_params, hook=hook_fn)
        else:
            self.sampler = _UnarySampler(kernel, num_samples, self.warmup_steps, num_chains, disable_progbar,
                                         initial_params=initial_params, hook=hook_fn)

    @poutine.block
    def run(self, *args, **kwargs):
        self._args, self._kwargs = args, kwargs
        num_samples = [0] * self.num_chains
        z_flat_acc = [[] for _ in range(self.num_chains)]
        with pyro.validation_enabled(not self.disable_validation):
            for x, chain_id in self.sampler.run(*args, **kwargs):
                if num_samples[chain_id] == 0:
                    num_samples[chain_id] += 1
                    z_structure = x
                elif num_samples[chain_id] == self.num_samples + 1:
                    self._diagnostics[chain_id] = x
                else:
                    num_samples[chain_id] += 1
                    if self.num_chains > 1:
                        x_cloned = x.clone()
                        del x
                    else:
                        x_cloned = x
                    z_flat_acc[chain_id].append(x_cloned)

        z_flat_acc = torch.stack([torch.stack(l) for l in z_flat_acc])

        # unpack latent
        pos = 0
        z_acc = z_structure.copy()
        for k in sorted(z_structure):
            shape = z_structure[k]
            next_pos = pos + shape.numel()
            z_acc[k] = z_flat_acc[:, :, pos:next_pos].reshape(
                (self.num_chains, self.num_samples) + shape)
            pos = next_pos
        assert pos == z_flat_acc.shape[-1]

        # If transforms is not explicitly provided, infer automatically using
        # model args, kwargs.
        if self.transforms is None and isinstance(self.kernel, (HMC, NUTS, Slice)):# only modification from the orginal one
            if self.kernel.transforms is not None:
                self.transforms = self.kernel.transforms
            elif self.kernel.model:
                _, _, self.transforms, _ = initialize_model(self.kernel.model,
                                                            model_args=args,
                                                            model_kwargs=kwargs)
            else:
                self.transforms = {}

        # transform samples back to constrained space
        for name, transform in self.transforms.items():
            z_acc[name] = transform.inv(z_acc[name])
        self._samples = z_acc

        # terminate the sampler (shut down worker processes)
        self.sampler.terminate(True)

    def get_samples(self, num_samples=None, group_by_chain=False):
        """
        Get samples from the MCMC run, potentially resampling with replacement.
        :param int num_samples: Number of samples to return. If `None`, all the samples
            from an MCMC chain are returned in their original ordering.
        :param bool group_by_chain: Whether to preserve the chain dimension. If True,
            all samples will have num_chains as the size of their leading dimension.
        :return: dictionary of samples keyed by site name.
        """
        samples = self._samples
        if num_samples is None:
            # reshape to collapse chain dim when group_by_chain=False
            if not group_by_chain:
                samples = {k: v.reshape((-1,) + v.shape[2:]) for k, v in samples.items()}
        else:
            if not samples:
                raise ValueError("No samples found from MCMC run.")
            if group_by_chain:
                batch_dim = 1
            else:
                samples = {k: v.reshape((-1,) + v.shape[2:]) for k, v in samples.items()}
                batch_dim = 0
            sample_tensor = list(samples.values())[0]
            batch_size, device = sample_tensor.shape[batch_dim], sample_tensor.device
            idxs = torch.randint(0, batch_size, size=(num_samples,), device=device)
            samples = {k: v.index_select(batch_dim, idxs) for k, v in samples.items()}
        return samples

    def diagnostics(self):
        """
        Gets some diagnostics statistics such as effective sample size, split
        Gelman-Rubin, or divergent transitions from the sampler.
        """
        diag = diagnostics(self._samples)
        for diag_name in self._diagnostics[0]:
            diag[diag_name] = {'chain {}'.format(i): self._diagnostics[i][diag_name]
                               for i in range(self.num_chains)}
        return diag

    def summary(self, prob=0.9):
        """
        Prints a summary table displaying diagnostics of samples obtained from
        posterior. The diagnostics displayed are mean, standard deviation, median,
        the 90% Credibility Interval, :func:`~pyro.ops.stats.effective_sample_size`,
        :func:`~pyro.ops.stats.split_gelman_rubin`.
        :param float prob: the probability mass of samples within the credibility interval.
        """
        print_summary(self._samples, prob=prob)
        if 'divergences' in self._diagnostics[0]:
            print("Number of divergences: {}".format(
                sum([len(self._diagnostics[i]['divergences']) for i in range(self.num_chains)])))


from django.shortcuts import render, redirect
from django.views.generic import TemplateView
from django.contrib.auth.views import LoginView, LogoutView
from django.contrib.auth.mixins import LoginRequiredMixin
from  .forms import LoginForm
from .models import Member, Method, BigCategory, SmallCategory, Payment
import datetime

class Login(LoginView):
    form_class = LoginForm
    template_name = 'app/login.html'

class Logout(LogoutView):
    template_name = 'app/login.html'

class TopView(LoginRequiredMixin, TemplateView):
    template_name = "top.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["members"] = Member.objects.filter(user=self.request.user)
        return context

    def post(self, request, *args, **kwargs):
        print(request.POST.get("name"))
        Member.objects.create(name=request.POST.get("name"), user=self.request.user)
        return redirect("home")

def calendar(request):
    return render(request, 'calendar.html')

class MoneyView(LoginRequiredMixin, TemplateView):
    template_name = "money.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["today"] = datetime.datetime.now().strftime('%Y-%m-%d')
        context["methods"] = Method.objects.filter(user=self.request.user)
        context["small_categories"] =  SmallCategory.objects.filter(user=self.request.user)
        context["members"] = Member.objects.filter(user=self.request.user)

        return context

    def post(self, request, *args, **kwargs):
        print(request.POST.get("method"))
        method = Method.objects.get(name=request.POST.get("method"), user=self.request.user)
        small_category = SmallCategory.objects.get(name=request.POST.get("small_category"), user=self.request.user)
        members = request.POST.getlist("member")

        payment = Payment.objects.create(
            balance = request.POST.get("balance"),
            price = request.POST.get("price"),
            date = request.POST.get("date"),
            method = method,
            small_category = small_category,
            memo = request.POST.get("memo"),
        )
        for member_id in members:
            payment.member.add(Member.objects.get(id=member_id))

        return redirect("money")

class AddCategoryView(LoginRequiredMixin, TemplateView):
    template_name = "add_category.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["payments"] = Method.objects.filter(balance=False,user=self.request.user)
        context["incomes"] = Method.objects.filter(balance=True,user=self.request.user)
        context["big_categories"] = {}
        big_categories = BigCategory.objects.filter(user=self.request.user)
        for big_category in big_categories:
            context["big_categories"][big_category] = SmallCategory.objects.filter(big_category=big_category, user=self.request.user)

        return context

    def post(self, request, *args, **kwargs):
        if request.POST.get("payment"):
            Method.objects.create(
                balance = False,
                name = request.POST.get("payment"),
                user = self.request.user
            )

        if request.POST.get("income"):
            Method.objects.create(
                balance = True,
                name = request.POST.get("income"),
                user = self.request.user
            )

        if request.POST.get("big_category"):
            BigCategory.objects.create(
                name = request.POST.get("big_category"),
                user = self.request.user
            )

        if request.POST.get("small_category"):
            big_category = BigCategory.objects.get(name=request.POST.get("small_category_base"),user=self.request.user)
            SmallCategory.objects.create(
                name = request.POST.get("small_category"),
                big_category = big_category,
                user = self.request.user
            )

        return redirect("add_category")


# YOLOv5 YOLO-specific modules
# with binary
import argparse
import logging
import sys
from copy import deepcopy
import scipy.io as sio
from torch import mode

sys.path.append('./')  # to run '$ python *.py' files in subdirectories
logger = logging.getLogger(__name__)

from .common import *
# from models.swin_transformer import *
from .experimental import *
from .image_encoder import *
# from models.edsr import EDSR
from ..utils.autoanchor import check_anchor_order
from ..utils.general_samDet import make_divisible, check_file, set_logging, xywh2xyxy
from ..utils.torch_utils import time_synchronized, fuse_conv_and_bn, model_info, scale_img, initialize_weights, \
    select_device, copy_attr
#from codes.meta_SAM.segment_anything.segment_anything.build_sam import sam_model_registry
#from codes.meta_SAM.segment_anything.segment_anything.automatic_mask_generator import SamAutomaticMaskGenerator
import torchvision.ops as ops
import scipy.io as sio
import numpy
from torch.nn.utils.rnn import pad_sequence
# from models import build_model
try:
    import thop  # for FLOPS computation
except ImportError:
    thop = None
import torch.nn.functional as F

class Detect(nn.Module):
    stride = None  # strides computed during build
    export = False  # onnx export

    def __init__(self, nc=80, in_channels= 4610, representation_size=1024, anchors=(), ch=()):  # detection layer
        super(Detect, self).__init__()
        self.nc = nc  # number of classes
        self.no = nc + 5  # number of outputs per anchor
        # self.conv1 = Conv(256, 256)
        # self.c31 = C3(256, 128, 3)
        # self.conv2 = Conv(128, 64)
        # self.c32 = C3(64, 32, 3)

        #for samDet
        self.fc6 = nn.Linear(in_channels, representation_size)
        self.fc7 = nn.Linear(representation_size, representation_size)
            #prediction head
        self.cls_score = nn.Linear(representation_size, nc + 1)  # +1 should be added for background
        self.bbox_pred = nn.Linear(representation_size, 4) #num_classes * 4

    def forward(self, x, propos):
        # x = x.copy()  # for profiling
        z = []  # inference output

        self.training |= self.export

        #for samDet
        # x = self.conv1(x)
        # x = self.c31(x)
        # x = self.conv2(x)
        # x= self.c32(x)
        #x = x.flatten(start_dim=1)

        x = F.relu(self.fc6(x))
        x = F.relu(self.fc7(x))

        x = x.flatten(start_dim=1)
        scores = self.cls_score(x)
        bbox_deltas = self.bbox_pred(x)
        z.append(bbox_deltas)
        z.append(scores)
        x = torch.cat(z, 1)
        bs, _ = x.shape
        if not self.training:
                x[:,[0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12]] = x[:,[0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12]].sigmoid()
                y = x
                #y = y.view(propos.shape[0], -1, self.no)
                propos = propos.to(y.device)
                #y[..., 0:2] = y[..., 0:2] * 2. * 512. + propos[..., 0:2]#* 2. - 0.5 + self.grid[i]) * self.stride[i]  # xy
                #y[..., 2:4] = ((y[..., 2:4] * 2) ** 2) * 512. + propos[..., 2:4]#* 2) ** 2 * self.anchor_grid[i]

                y[..., 0] = (y[..., 0]  * (propos[..., 2] + 1e-6)) + propos[..., 0] * 1024
                y[..., 1] = ((y[..., 1] * (propos[..., 3] + 1e-6)) + propos[..., 1]) * 1024
                y[..., 2] = torch.exp(y[..., 2]) * (propos[..., 2] + 1e-6) *1024#*16#* 64
                y[..., 3] = torch.exp(y[..., 3]) * (propos[..., 3] + 1e-6) *1024#*16#* 64
                # x = x.view(propos.shape[0], -1, self.no)
                # x = x.unsqueeze(0)
                #y = y.unsqueeze(0)

        #x=  x.view(propos.shape[0], -1, self.no)
        # propos = propos.to(x.device)

        x = x.unsqueeze(0)
        return x if self.training else (y, x) #(torch.cat(z, 1), x)

    @staticmethod
    def _make_grid(nx=20, ny=20):
        yv, xv = torch.meshgrid([torch.arange(ny), torch.arange(nx)])
        return torch.stack((xv, yv), 2).view((1, 1, ny, nx, 2)).float()

class Model(nn.Module):
    export = False  # onnx export
    def __init__(self, cfg='yolov5s.yaml',input_mode='RGB',ch_steam=3, ch=3, nc=None, anchors=None,config=None,sr=False,factor=2):  #att=False,sr_att=False model, input channels, number of classes
        super(Model, self).__init__()
        if isinstance(cfg, dict):
            self.yaml = cfg  # model dict
        else:  # is *.yaml
            import yaml  # for torch hub
            self.yaml_file = Path(cfg).name
            with open(cfg) as f:
                self.yaml = yaml.load(f, Loader=yaml.SafeLoader)  # model dict
        self.sr = sr
        ch = self.yaml['ch'] = self.yaml.get('ch', ch)  # input channels
        if nc and nc != self.yaml['nc']:
            logger.info(f"Overriding model.yaml nc={self.yaml['nc']} with nc={nc}")
            self.yaml['nc'] = nc  # override yaml value
        if anchors:
            logger.info(f'Overriding model.yaml anchors with anchors={anchors}')
            self.yaml['anchors'] = round(anchors)  # override yaml value
        # self.input_mode = input_mode
        if input_mode == 'RGB+IR+fusion':
            self.steam, _ = parse_model(deepcopy(self.yaml),'steam', ch=[ch_steam],config=config)  # zjq model, savelist
        #self.model, self.save = parse_model(deepcopy(self.yaml),'backbone+head', ch=[ch],config=config)  # model, savelist   #* changed removed
        '''following part was for preparing the dataset
        model = "vit_b"
        weights_filepath = "/home/bbahaduri/sryolo/weights/sam_vit_b_01ec64.pth"
        model = sam_model_registry[model](checkpoint=weights_filepath)
        self.sam = model
        self.mask_generator = SamAutomaticMaskGenerator(
            model=self.sam,
            points_per_side=64,
            points_per_batch= 640,
            pred_iou_thresh=0.86,
            stability_score_thresh=0.92,
            crop_n_layers=0,
            crop_n_points_downscale_factor=1,
            #min_mask_region_area=100,  # Requires open-cv to run post-processing
            )
        '''
        self.conv1 = Conv(256, 256)
        self.c31 = C3(256, 128, 3)
        self.conv2 = Conv(128, 64)
        self.c32 = C3(64, 32, 3)
        self.pooler = ops.RoIPool((12, 12), 1.0)

        self.detect = Detect(nc=8)

        # self.f1=self.yaml['f1']  #蒸馏特征层层数
        # self.f2=self.yaml['f2']
        # self.f3=self.yaml['f3']

        # Build strides, anchors
         # only run once
        # m = self.model[-2]  # Detect()
        # if isinstance(m, Detect):
        #     s = 256  # 2x min stride
        #     #m.stride = torch.tensor([s / x.shape[-2] for x in self.forward(torch.zeros(1, ch_steam, s, s),torch.zeros(1, ch_steam, s, s),input_mode)[0]])  # forward
        #     m.stride = torch.tensor([s / x.shape[-2] for x in self.forward(torch.zeros(1, ch_steam, s, s),torch.zeros(1, ch_steam, s, s),input_mode)[0]])  # forward
        #     m.anchors /= m.stride.view(-1, 1, 1)
        #     check_anchor_order(m)
        #     self.stride = m.stride
        #     self._initialize_biases()  # only run once
        # Init weights, biases
        initialize_weights(self)
        self.info()
        logger.info('')

    def forward(self, x, ir=torch.randn(1,3,512,512), propos=None, input_mode='RGB+IR', augment=False, profile=False):

        # input_mode = 'RGB+IR' #IRRGB
        if input_mode=='RGB':
            ir=x
        if augment:
            img_size = x.shape[-2:]  # height, width
            s = [1, 0.83, 0.67]  # scales
            f = [None, 3, None]  # flips (2-ud, 3-lr)
            y = []  # outputs
            for si, fi in zip(s, f):
                xi = scale_img(x.flip(fi) if fi else x, si, gs=int(self.stride.max()))
                iri = scale_img(ir.flip(fi) if fi else ir, si, gs=int(self.stride.max()))
                if input_mode =='RGB+IR+fusion':
                    steam1 = self.forward_once(x,'steam',profile)
                    steam2 = self.forward_once(ir,'steam',profile)
                    steam = torch.cat([steam1,steam2],1)
                if input_mode == 'RGB+IR':
                    steam = torch.cat([xi,iri[:,0:1,:,:]],1)
                if input_mode == 'RGB':
                    steam = xi
                if input_mode == 'IR':
                    steam = iri#steam = iri[:,0:1,:,:]
                if input_mode == 'RGB+IR+MF':
                    steam = [x,ir[:,0:1,:,:]] #[:,0:1,:,:]
                yi = self.forward_once(steam, propos, 'yolo')[0]  # forward
                # yi = self.forward_once(xi)[0]  # forward
                # cv2.imwrite('img%g.jpg' % s, 255 * xi[0].numpy().transpose((1, 2, 0))[:, :, ::-1])  # save
                yi[..., :4] /= si  # de-scale
                if fi == 2:
                    yi[..., 1] = img_size[0] - yi[..., 1]  # de-flip ud
                elif fi == 3:
                    yi[..., 0] = img_size[1] - yi[..., 0]  # de-flip lr
                y.append(yi)
            return torch.cat(y, 1), None  # augmented inference, train
        else:
            if input_mode =='RGB+IR+fusion':
                steam1 = self.forward_once(x,'steam',profile)
                steam2 = self.forward_once(ir,'steam',profile)
                steam = torch.cat([steam1,steam2],1)
                # sio.savemat('features/output.mat', mdict={'data':steam.cpu().numpy()})
            if input_mode == 'RGB+IR':
                steam = torch.cat([x,ir[:,0:1,:,:]],1)
            if input_mode == 'RGB':
                steam = x
            if input_mode == 'IR':
                steam = ir#steam = ir[:,0:1,:,:]
            if input_mode == 'RGB+IR+MF':
                steam = [x,ir[:,0:1,:,:]] #[:,0:1,:,:]

            self.training |= self.export
            if self.training==True:
                if self.sr:
                    y,output_sr,features = self.forward_once(steam,'yolo', profile) #zjq
                    return y,output_sr,features
                else:
                    y,features = self.forward_once(steam, propos, 'yolo', profile) #zjq
                    return y,features
            else:
                y,features = self.forward_once(steam, propos, 'yolo', profile) #zjq

                return y,features[0], features[1]  #y[0],y[1]

    def forward_once(self, x, propos, string, profile=False):
        y, dt = [], []  # outputs
        if string == 'steam':
            for m in self.steam:
                if m.f != -1:  # if not from previous layer
                    x = y[m.f] if isinstance(m.f, int) else [x if j == -1 else y[j] for j in m.f]  # from earlier layers

                if profile:
                    o = thop.profile(m, inputs=(x,), verbose=False)[0] / 1E9 * 2 if thop else 0  # FLOPS
                    t = time_synchronized()
                    for _ in range(10):
                        _ = m(x)
                    dt.append((time_synchronized() - t) * 100)
                    print('%10.1f%10.0f%10.1fms %-40s' % (o, m.np, dt[-1], m.type))

                x = m(x)  # run
                #y.append(x if m.i in self.save_steam else None)  # save output
            return x
        elif string == 'yolo':
            # for samDet
            #TO DO SAM should be modified so it output image embedding as well
            # breakpoint()
            # feature_maps = self.sam.image_encoder(x)
            # breakpoint()
            # point_grids = build_all_layer_point_grids(64, 0, 1)
            '''
            *** for preparing dataset:
            _outputs, feature_maps = self.mask_generator.generate(x)
            '''
            _outputs = propos
            #feature_maps = x

            x = self.conv1(x)
            x = self.c31(x)
            x = self.conv2(x)
            x= self.c32(x)

            rois, proposals, batch_lenghts = prepare(_outputs, x.device)
            # rois_pool = deepcopy(rois)
            # for i, roi_pool in enumerate(rois_pool):

            #     roi_pool = torch.ceil(roi_pool[:, 0:4])
            #     rois_pool[i] = roi_pool.detach()
            #rois = rois.detach()
            x = self.pooler(x, rois)

            x = x.flatten(start_dim=1)
            proposals = proposals.detach()
            wh = deepcopy(proposals[:, -2:])
            wh_d = wh.detach()
            x = torch.cat([x, wh_d], dim=1)
            # rois_pool, rois, zero_mask, proposals = prepare(_outputs)
            # rois_pool = rois_pool.to(x.device)
            # zero_mask = zero_mask.to(x.device)colorstr(f'{task}: ')
            # rois = rois.to(x.device)
            # output_size = (12, 12)

            # rois_pool = rois_pool.type(torch.float32)
            # pooled_features = ops.roi_pool(x, rois_pool, output_size)

            # pooled_features = pooled_features.type(torch.float32)
            # zero_mask = zero_mask[:, None, None, None]
            # pooled_features = pooled_features * (~zero_mask).int()
            #proposals[:, 0:4] = proposals[:, 0:4] * 64
            y = self.detect(x, proposals)

            #feature_maps = feature_maps.squeeze(0)
            self.training |= self.export
            if self.training==True:
                if self.sr:
                    output_sr = self.model_up(y[self.l1],y[self.l2]) #在超分上加attention
                    return x,output_sr,y#(y[self.f1],y[self.f2],y[self.f3])#(y[4],y[8],y[18],y[21],y[24])#(y[7],y[15],y[-2])
                else:
                    return rois,y   #(y[self.f1],y[self.f2],y[self.f3])#(y[4],y[8],y[18],y[21],y[24])#(y[7],y[15],y[-2])
            else:
                y = list(y)
                y[0] = torch.split(y[0], batch_lenghts)
                y[0] = pad_sequence(y[0], batch_first=True, padding_value=0)
                y = tuple(y)

                return rois,y#(y[17],y[20],y[23])#(y[4],y[8],y[18],y[21],y[24])#(y[7],y[15],y[-2])(y[-4],y[-3],y[-2])

    def _initialize_biases(self, cf=None):  # initialize biases into Detect(), cf is class frequency
        # https://arxiv.org/abs/1708.02002 section 3.3
        # cf = torch.bincount(torch.tensor(np.concatenate(dataset.labels, 0)[:, 0]).long(), minlength=nc) + 1.
        m = self.detect     #[-1]  # Detect() module   #*changed self.model[-1] to self.detect

        b_reg = m.bbox_pred.bias.view(1, -1)
        b_reg.data[:, :4] += math.log(0.1)  #adjusting the foreground/background prior

        b_cls = m.cls_score.bias.view(1, -1)  #1 is because we have 1 anchor and not 3 anchors
        b_cls.data += math.log((1 - 0.01) / 0.01)

        m.bboc_pred.bias = torch.nn.Parameter(b_reg.view(-1), requires_grad=True)
        m.cls_score.bias = torch.nn.Parameter(b_cls.view(-1), requires_grad=True)

    def _print_biases(self):
        m = self.model[-1]  # Detect() module
        for mi in m.m:  # from
            b = mi.bias.detach().view(m.na, -1).T  # conv.bias(255) to (3,85)
            print(('%6g Conv2d.bias:' + '%10.3g' * 6) % (mi.weight.shape[1], *b[:5].mean(1).tolist(), b[5:].mean()))

    # def _print_weights(self):
    #     for m in self.model.modules():
    #         if type(m) is Bottleneck:
    #             print('%10.3g' % (m.w.detach().sigmoid() * 2))  # shortcut weights

    def fuse(self):  # fuse model Conv2d() + BatchNorm2d() layers
        print('Fusing layers... ')
        for m in self.modules():   ##self.model  to self.modules
            if (type(m) is Conv) and hasattr(m, 'bn'):
                m.conv = fuse_conv_and_bn(m.conv, m.bn)  # update conv
                delattr(m, 'bn')  # remove batchnorm
                m.forward = m.fuseforward  # update forward
        self.info()
        return self

    def nms(self, mode=True):  # add or remove NMS module
        present = type(self.model[-1]) is NMS  # last layer is NMS
        if mode and not present:
            print('Adding NMS... ')
            m = NMS()  # module
            m.f = -1  # from
            m.i = self.model[-1].i + 1  # index
            self.model.add_module(name='%s' % m.i, module=m)  # add
            self.eval()
        elif not mode and present:
            print('Removing NMS... ')
            self.model = self.model[:-1]  # remove
        return self

    def autoshape(self):  # add autoShape module
        print('Adding autoShape... ')
        m = autoShape(self)  # wrap model
        copy_attr(m, self, include=('yaml', 'nc', 'hyp', 'names', 'stride'), exclude=())  # copy attributes
        return m

    def info(self, verbose=False, img_size=640):  # print model information
        model_info(self, verbose, img_size)

def parse_model(d, string, ch,config):  # model_dict, input_channels(3)
    logger.info('\n%3s%18s%3s%10s  %-40s%-30s' % ('', 'from', 'n', 'params', 'module', 'arguments'))
    anchors, nc, gd, gw = d['anchors'], d['nc'], d['depth_multiple'], d['width_multiple']
    na = (len(anchors[0]) // 2) if isinstance(anchors, list) else anchors  # number of anchors
    no = na * (nc + 5)  # number of outputs = anchors * (classes + 5)

    layers, save, c2 = [], [], ch[-1]  # layers, savelist, ch out
    i_shoud_add = 0

    stri = string.split('+')
    if len(stri)==2:
        string_1 = stri[0]
        string_2 = stri[1]
        d_ = d[string_1] + d[string_2]
        save.extend([2,4,5,6,8,9]) #save some layer of backbone
    else:
        d_ = d[stri[-1]]
    if string == 'head':
        ch.append(256)
    for i, (f, n, m, args) in enumerate(d_):  # from, number, module, args
        m = eval(m) if isinstance(m, str) else m  # eval strings
        for j, a in enumerate(args):
            try:
                args[j] = eval(a) if isinstance(a, str) else a  # eval strings
            except:
                pass

        n = max(round(n * gd), 1) if n > 1 else n  # depth gain
        if m in [Conv, ACmix, Bottleneck, SPP, DWConv, MixConv2d, Focus, CrossConv, BottleneckCSP, BottleneckCSP2, SPPCSP, C3, AttentionModel]:
            c1, c2 = ch[f], args[0]

            # Normal
            # if i > 0 and args[0] != no:  # channel expansion factor
            #     ex = 1.75  # exponential (default 2.0)
            #     e = math.log(c2 / ch[1]) / math.log(2)
            #     c2 = int(ch[1] * ex ** e)
            # if m != Focus:

            c2 = make_divisible(c2 * gw, 8) if c2 != no else c2

            # Experimental
            # if i > 0 and args[0] != no:  # channel expansion factor
            #     ex = 1 + gw  # exponential (default 2.0)
            #     ch1 = 32  # ch[1]
            #     e = math.log(c2 / ch1) / math.log(2)  # level 1-n
            #     c2 = int(ch1 * ex ** e)
            # if m != Focus:
            #     c2 = make_divisible(c2, 8) if c2 != no else c2

            args = [c1, c2, *args[1:]]
            if m in [BottleneckCSP, C3,BottleneckCSP2, SPPCSP]:
                args.insert(2, n)
                n = 1
        elif m is nn.BatchNorm2d:
            args = [ch[f]]
        elif m is Concat:# or m is SAM:
            c2 = sum([ch[x if x < 0 else x + 1] for x in f])
        elif m is Detect:
            args.append([ch[x + 1] for x in f])   #*changed removed + 1
            if isinstance(args[1], int):  # number of anchors
                args[1] = [list(range(args[1] * 2))] * len(f)
            print(*args)

        elif m is Contract:
            c2 = ch[f if f < 0 else f + 1] * args[0] ** 2
        elif m is Expand:
            c2 = ch[f if f < 0 else f + 1] // args[0] ** 2
        else:
            c2 = ch[f if f < 0 else f + 1]

        if string == 'backbone':
            m_ = m(img_size = args[0], patch_size=args[1], in_chans= args[2], out_chans=args[3], window_size= args[4], depth= 24, num_heads= 16, embed_dim= 1024,global_attn_indexes= [5, 11, 17, 23],)
        else:
            m_ = nn.Sequential(*[m(*args) for _ in range(n)]) if n > 1 else m(*args)  # module
        t = str(m)[8:-2].replace('__main__.', '')  # module type
        np = sum([x.numel() for x in m_.parameters()])  # number params
        m_.i, m_.f, m_.type, m_.np = i+i_shoud_add, f, t, np  # attach index, 'from' index, type, number params
        logger.info('%3s%18s%3s%10.0f  %-40s%-30s' % (i+i_shoud_add, f, n, np, t, args))  # print
        save.extend(x % (i+i_shoud_add+0.00001) for x in ([f] if isinstance(f, int) else f) if x != -1)  # append to savelist
        layers.append(m_)
        ch.append(c2)
    if string == 'backbone':
        return layers[0], sorted(save) #*changed  nn.Sequential(*layers) to layers[0]
    return nn.Sequential(*layers), sorted(save)

# if __name__ == '__main__':
#     parser = argparse.ArgumentParser()
#     #parser = argparse.ArgumentParser('Set transformer detector', add_help=False)    #newly added
#     parser.add_argument('--temp', default = 'something', type = str, help='it is nothing')
#     parser.add_argument('--cfg', default='yolov5s.yaml', type=str, help='model.yaml')
#     parser.add_argument('--device', default='cuda', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
#     #opt = parser.parse_args()
#     opt, _ = parser.parse_known_args()
#     opt.cfg = check_file(opt.cfg)  # check file
#     set_logging()
#     device = select_device(opt.device)

#     # Create model
#     model = Model(opt.cfg).to(device)
#     model.train()

    # Profile
    # img = torch.rand(8 if torch.cuda.is_available() else 1, 3, 640, 640).to(device)
    # y = model(img, profile=True)

    # Tensorboard
    # from torch.utils.tensorboard import SummaryWriter
    # tb_writer = SummaryWriter()
    # print("Run 'tensorboard --logdir=models/runs' to view tensorboard at http://localhost:6006/")
    # tb_writer.add_graph(model.model, img)  # add model to tensorboard
    # tb_writer.add_image('test', img[0], dataformats='CWH')  # add model to tensorboard

def prepare(_outputs, device):
    max_num_boxes = 400
    if isinstance(_outputs, tuple):
        _outputs = list(_outputs)

    #new here
    proposals = deepcopy(_outputs)

    for i, rois in enumerate(_outputs):
        rois = rois * 64.0                         #changing from a base of 1 to base of 64 to match the feature maps
        rois[:, 0] = rois[:, 0] - rois[:, 2] / 2
        rois[:, 1] = rois[:, 1] - rois[:, 3] / 2
        rois[:, 2] = rois[:, 0] + rois[:, 2]
        rois[:, 3] = rois[:, 1] + rois[:, 3]
        rois = rois.to(device)
        _outputs[i] = rois

    for i, propos in enumerate(proposals):
        propos = propos.to(device)
        proposals[i] = propos

    batch_lenghts = [propos.shape[0] for propos in proposals]
    proposals = torch.cat(proposals)
    # for i  in range(len(_outputs)):

    #     if len(_outputs[i]) < 400:
    #         add_tensor = torch.zeros(max_num_boxes - len(_outputs[i]), 4)
    #         _outputs[i] = torch.cat((_outputs[i], add_tensor), dim=0)

#   proposals = torch.stack(_outputs)

#     rois = deepcopy(proposals)
#     rois = rois * 64.0                         #changing from a base of 1 to base of 64 to match the feature maps
#     rois[:, :, 0] = rois[:, :, 0] - rois[:, :, 2] / 2
#     rois[:, :, 1] = rois[:, :, 1] - rois[:, :, 3] / 2
#     rois[:, :, 2] = rois[:, :, 0] + rois[:, :, 2]
#     rois[:, :, 3] = rois[:, :, 1] + rois[:, :, 3]

    # batch_size = rois.shape[0]
    # batch_indices = torch.arange(rois.shape[0]).unsqueeze(1).unsqueeze(2).expand(rois.shape[0], 400, 1)

    # rois = torch.cat((batch_indices, rois), dim=2)

    # rois_pool = deepcopy(rois)
    # rois_pool = rois_pool.view(-1, 5)
    # output_size = (12, 12)

    # zero_mask = torch.all(rois_pool[:, 1:5] == 0, dim=1)
    # rois_pool[:, 1:5] = torch.ceil(rois_pool[:, 1:5])
    # return rois_pool, rois, zero_mask, proposals

    return _outputs, proposals, batch_lenghts


from datetime import datetime
import pytz
import requests
import logging
import json
import random
import re
from utils import logerrors, botcmd
from random import randint
from modules.MessageResponse import MessageResponse

log = logging.getLogger(__name__)

class SweetieLookup(object):

    id_dic = {"": ""}

    def __init__(self, bot):
        self.bot = bot
        self.bot.load_commands_from(self)

    def get_sender_username(self, mess):
        return self.bot.get_sender_username(mess)

    def chat(self, message):
        self.bot.send_groupchat_message(message)

    def ross(self):
        return random.choice(
            [
                "In painting, you have unlimited power. You have the ability to move mountains. You can bend rivers. But when I get home, the only thing I have power over is the garbage",
                "You need the dark in order to show the light.",
                "Look around. Look at what we have. Beauty is everywhere - you only have to look to see it.",
                "Just go out and talk to a tree. Make friends with it.",
                "There's nothing wrong with having a tree as a friend.",
                "Trees cover up a multitude of sins.",
                "They say everything looks better with odd numbers of things. But sometimes I put even numbers - just to upset the critics.",
                "I remember when my Dad told me as a kid, 'If you want to catch a rabbit, stand behind a tree and make a noise like a carrot. Then when the rabbit comes by you grab him.' Works pretty good until you try to figure out what kind of noise a carrot makes...",
                "The secret to doing anything is believing that you can do it. Anything that you believe you can do strong enough, you can do. Anything. As long as you believe.",
                "Water's like me. It's laaazy ... Boy, it always looks for the easiest way to do things",
                "We artists are a different breed of people. We're a happy bunch.",
                "We don't make mistakes. We just have happy accidents.",
                "Talent is a pursued interest. Anything that you're willing to practice, you can do.",
                "I guess I'm a little weird. I like to talk to trees and animals. That's okay though; I have more fun than most people.",
                "I can't think of anything more rewarding than being able to express yourself to others through painting. Exercising the imagination, experimenting with talents, being creative; these things, to me, are truly the windows to your soul.",
                "Lets build a happy little cloud. Lets build some happy little trees.",
                "Believe that you can do it, 'cause you can do it.",
            ]
        )

    @botcmd
    @logerrors
    def argue(self, message):
        """Get angry"""
        return self.ross()

    @botcmd
    @logerrors
    def rant(self, message):
        """Rage at the dying of the light"""
        return self.ross()

    class Bunch:
        def __init__(self, **kw): setattr(self, "__dict__", kw)
        def __getattr__(self, name): return None

    def dice_error(self, message, *args):
        return SweetieLookup.Bunch(error=message.format(*args))

    def parse_dice(self, dice_spec):
        # scrap whitespace
        dice_spec = re.sub(r"\s+", "", dice_spec, re.UNICODE)

        # search for the d
        split = dice_spec.split("d", 1)
        if len(split) != 2:
            return self.dice_error(
                "Dice need to be specified in the form 2d20 [>x] [<x] [!] [=] [+n]"
            )
        dice_count = split[0]
        dice_type = split[1]

        try:
            # assume we only want one die if dice count is missing
            dice = 1 if dice_count == "" else int(dice_count)
        except Exception:
            return self.dice_error(
                "Sorry, don't know how to roll '{}' dice", dice_count
            )

        try:
            split_modifiers = re.split(r"(\d+|=|>|<|!|%|\+|\-)", dice_type)
            split_modifiers = list(filter(len, split_modifiers))

            current_modifier = None
            threshold = None
            lt_threshold = None
            show_sum = False
            explode = False
            bonus = 0
            # iterate over dice spec, remembering what the last modifier was
            # in order to interpret the different numbers
            for modifier in split_modifiers:
                if modifier.isdigit():
                    modifier_value = int(modifier)

                    if current_modifier == ">":
                        threshold = modifier_value
                    elif current_modifier == "<":
                        lt_threshold = modifier_value
                    elif current_modifier == "+":
                        bonus += modifier_value
                    elif current_modifier == "-":
                        bonus -= modifier_value
                    else:
                        assert current_modifier is None
                        sides = int(modifier)
                    current_modifier = None

                elif modifier == "%":
                    sides = 100
                elif modifier in [">", "<", "+", "-"]:
                    current_modifier = modifier
                elif modifier == "=":
                    show_sum = True
                elif modifier == "!":
                    explode = True
                else:
                    raise "unknown modifier"

            return SweetieLookup.Bunch(
                dice=dice,
                sides=sides,
                bonus=bonus,
                threshold=threshold,
                lt_threshold=lt_threshold,
                show_sum=show_sum,
                explode=explode,
            )
        except Exception:
            return self.dice_error("Sorry, don't know how to roll '{}'", dice_type)
        return SweetieLookup.Bunch(dice=dice, sides=sides)

    @botcmd
    def roll(self, message):
        """[eg 5d20] Roll some dice"""
        try:
            dice_spec = self.parse_dice(message.args)
            if dice_spec.error:
                return dice_spec.error
            dice = dice_spec.dice
            sides = dice_spec.sides
        except Exception:
            log.exception("bad dice")
            return "Error parsing input"
        if dice > 25:
            return "Too many variables in possibility space, abort!"
        if sides > 20000000:
            return "Sides of dice too small, can't see what face is upright!"
        if sides == 1:
            return "Oh look, they all came up ones. Are you surprised? I'm surprised."
        if sides < 1:
            return "How do you make a dice with less than two sides?"
        if dice < 1:
            return "You want me to roll...less than one dice?"

        if (
            dice_spec.threshold
            and dice_spec.lt_threshold
            and dice_spec.threshold > dice_spec.lt_threshold
        ):
            return "Requirements unsatisfactory: thresholds conflict. Try again."

        rolls = self.get_rolls(dice, sides)
        rolls = list(map(lambda x: x + dice_spec.bonus, rolls))

        if dice_spec.explode:
            rolls = self.explode_dice(rolls, sides)

        log.debug("roll result: {}".format(rolls))
        roll_list = ", ".join(map(str, rolls))
        if dice_spec.threshold or dice_spec.lt_threshold:
            gt = dice_spec.threshold
            lt = dice_spec.lt_threshold

            if not lt:
                success_count = len(list(filter(lambda x: x >= gt, rolls)))
            elif not gt:
                success_count = len(list(filter(lambda x: x <= lt, rolls)))
            else:
                success_count = len(
                    list(filter(lambda x: (x <= lt and x >= gt), rolls))
                )

            roll_list += " ({} successes)".format(success_count)
        if dice_spec.show_sum:
            dice_sum = sum(rolls)
            roll_list += " (sum {})".format(dice_sum)
        return roll_list

    class ExplodingDice:
        def __init__(self, initialValue):
            self.rolls = [int(initialValue)]

        def last_roll(self):
            return self.rolls[-1]

        def add_roll(self, roll):
            self.rolls.append(int(roll))
            return self

        def sum(self):
            return sum(self.rolls)

    def explode_dice(self, rolls, sides):
        sides = int(sides)
        rolls = list(map(SweetieLookup.ExplodingDice, rolls))
        def should_explode(r): return r.last_roll() == sides
        def add_roll(r, n): return r.add_roll(n)
        unexploded_rolls = list(rolls)
        while any(unexploded_rolls):
            unexploded_rolls = list(filter(should_explode, unexploded_rolls))
            rerolls = self.get_rolls(len(unexploded_rolls), sides)
            unexploded_rolls = list(map(add_roll, unexploded_rolls, rerolls))

        return list(map(lambda x: x.sum(), rolls))

    def get_rolls(self, dice=1, sides=6):
        try:
            return [randint(1, sides) for i in range(dice)]
        except Exception:
            return []

    @botcmd
    def date(self, message):
        """Returns the current datetime in a bunch of timezones"""
        now = datetime.now(pytz.utc)
        usptz = pytz.timezone("US/Pacific")
        usetz = pytz.timezone("US/Eastern")
        evetz = pytz.timezone("UTC")
        uktz = pytz.timezone("Europe/London")
        eutz = pytz.timezone("Europe/Brussels")
        nztz = pytz.timezone("Pacific/Auckland")

        format = "%Y-%m-%d %H:%M %Z"
        dates = [now.astimezone(tz) for tz in [usptz, usetz, evetz, uktz, eutz, nztz]]
        dates = [date.strftime(format) for date in dates]
        return ("\n" + "\n".join(dates)).replace("UTC", "EVE")

    @logerrors
    def random_reddit_link(self, subreddit, domain_filter=None):
        luna_data = self.get(
            "http://www.reddit.com/r/{}/new.json?limit=100".format(subreddit)
        )
        if luna_data is None:
            raise Exception("failed to call reddit api")
        link_data = self.get_children_of_type(json.loads(luna_data), "t3")
        if domain_filter:
            link_data = list(
                filter(lambda x: x["data"]["domain"] in domain_filter, link_data)
            )
        log.info("choosing one of {} links".format(len(link_data)))
        choice = random.choice(link_data)
        link = choice["data"]["url"]
        text = choice["data"]["title"]
        html = '{}'.format(link, text)
        plain = "{} [ {} ]".format(text, link)
        return MessageResponse(plain, None, html=html)

    @botcmd
    @logerrors
    def ferret(self, message):
        """Ferret!"""
        return self.random_reddit_link(
            "ferret", ("imgur.com", "i.imgur.com", "youtu.be", "i.redd.it")
        )

    @botcmd
    @logerrors
    def woon(self, message):
        """loona woona"""
        luna_data = self.get("http://www.reddit.com/r/princessluna/new.json?limit=100")
        if luna_data is None:
            raise Exception("failed to call reddit api")
        link_data = self.get_children_of_type(json.loads(luna_data), "t3")

        kyuu_data = self.get("http://www.reddit.com/user/kyuuketsuki.json?limit=100")
        if kyuu_data is None:
            raise Exception("failed to call reddit api")
        link_title_data = self.get_children_of_type(json.loads(kyuu_data), "t1")

        log.info("choosing one of {} links".format(len(link_data)))
        log.info("choosing one of {} comments".format(len(link_title_data)))
        link = random.choice(link_data)["data"]["url"]
        text = random.choice(link_title_data)["data"]["body"]
        text = re.split(r"\.|!|\?", text)[0]
        html = '{}'.format(link, text)
        plain = "{} [ {} ]".format(text, link)
        return MessageResponse(plain, None, html=html)

    def get_children_of_type(self, reddit_data, kind):
        if type(reddit_data) is dict:
            return self.get_children_from_listing(reddit_data, kind)

        result = []
        for listing in reddit_data:
            for child in self.get_children_from_listing(listing, kind):
                result.append(child)
        return result

    def get_children_from_listing(self, listing_data, kind):
        result = []
        for child in listing_data["data"]["children"]:
            if child["kind"] == kind:
                result.append(child)
        return result

    def get(self, url, extra_headers={}):
        try:
            headers = {"user-agent": "sweetiebot", "cache-control": "no-cache"}
            headers.update(extra_headers)
            log.debug("requesting {} with headers {}".format(url, str(headers)))
            res = requests.get(url, timeout=10, headers=headers)
            return res.text
        except Exception as e:
            log.warning("error fetching url " + url + " : " + str(e))
            return None


from densecID.models import dendrites
import cv2
import numpy as np
from PIL import Image
import imagehash

# from django.core.files import default_storage

class Operations:

    def encode_img(self,image):
        # reduce size of image before storing
        image_str = cv2.imencode(".jpg",image)[1].tostring()
        return image_str

    def decode_img(self,image):

        image = np.frombuffer(image,np.uint8)
        image = cv2.imdecode(image,cv2.IMREAD_COLOR)
        return image

        # image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)

    def hash_function(self,image):
        img_pil = Image.fromarray(image)
        im_hash = imagehash.whash(img_pil)
        return str(im_hash)

    def orb_Sim(self,imgA , imgB):
        orb = cv2.ORB_create()
        kpA, dsA = orb.detectAndCompute(imgA, None)
        kpB, dsB = orb.detectAndCompute(imgB, None)

        bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
        matches = bf.match(dsA,dsB)
        similar = [i for i in matches if i.distance<45]
        if len(matches) == 0:
            return 0
        return len(similar)/len(matches)*100

    def select_images(self,i):

        images = dendrites.objects.values_list("dendPic", flat=True)[i:i+20]
        hash = dendrites.objects.values_list("dendID",flat=True)[i:i+20]

        images = [self.decode_img(a) for a in images]
        return images,hash

    def image_Compare(self,image):
        scan = image
        den_images=[]
        den_sim=[]
        last = dendrites.objects.all().count()
        for i in range(0,last,20):
            images, hashes = self.select_images(i)
            # print(hashes)
            sim=[]

            if not images:
                # print("No match")
                return "No Match"

            else:
                # print(len(images))
                # print("Something")

                for j in range(len(images)):
                    # print(j)
                    # cv2.imshow(" ",images[j])
                    # cv2.waitKey(0)
                    sim.append(self.orb_Sim(scan,images[j]))

                best_ind = sim.index(max(sim))
                den_images.append((images[best_ind],hashes[best_ind]))
                den_sim.append(sim[best_ind])
        if not den_sim:
            return "No Match"
        else:
            match = den_sim.index(max(den_sim))
            # print(den_sim)
            if (max(den_sim)<50):
                # print("similarity<50")
                return "No Match"
            else:
                # print("Hash",den_images[match][1])
                return den_images[match]

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

    def insert_row(self,task):

        ins = dendrites(dendID = task[0],
                        dendPic = task[1],
                        prod_name = task[2],
                        prod_disc = task[3],
                        prod_category = task[4],
                        mfg_date = task[5],
                        exp_date = task[6] )
        ins.save()

    def select_match(self,hash):

        match = dendrites.objects.filter(dendID = str(hash)).values()
        match = match[0]

        data=[match['dendID'],match['prod_name'],match['prod_disc'],match['prod_category'],match['mfg_date'],match['exp_date']]
        return data

    def update_info(self,task):

        dendrites.objects.filter(dendID = str(task[0])).update(prod_name = str(task[1]),
                                                               prod_disc = str(task[2]),
                                                               prod_category = str(task[3]),
                                                               mfg_date = str(task[4]),
                                                               exp_date = str(task[5]))


"""
A Python script for testing the battery life of an IMU by running a test and updating the GUI until the IMU dies, at
which point the GUI will stop updating. When the test is stopped the details of the test are stored in the
DrainTests.txt file.
"""
from datetime import datetime as dt
from pathlib import Path

import PySimpleGUI as Psg
import witmotion as wm
from matplotlib.figure import Figure

# Custom constants used in the program.
import constants as c
# Custom styling.
import styling as st
import utils as ut
# Used to get the available COM ports.
from classes import IMU

# Location of refresh icon, stored for main program.
refresh_icon = str(Path().absolute().parent) + '\\icons\\refresh_icon.png'

class ImuBatterLifeTest:
    def __init__(self):
        # COM ports available on the system.
        self.com_ports = IMU.available_com_ports()
        # Number of messages received from the IMU device during a test.
        self.imu_counter = 0
        # File for saving IMU data of recording.
        self.save_file = None
        # IMU object and associated variables.
        self.imu = None
        self.imu_com_port = 'COM3'
        self.imu_baud_rate = c.COMMON_BAUD_RATES[6]
        self.quaternion = None
        self.acceleration = None
        self.angle = None
        self.rotate_imu_xy = False
        # Connection state of the IMU.
        self.imu_connected = False
        # Plotting variables: axis, points, lines, fig_agg, and bg set to None until initialised.
        self.ax = None
        self.point_data = None
        self.line_data = None
        self.fig_agg = None
        self.bg = None
        # Is a test currently running.
        self.testing = False
        self.test_start = dt.now().timestamp()
        self.test_last = dt.now().timestamp()
        self.test_elapsed = self.test_last - self.test_start
        # Create BatteryTests directory.
        self.battery_tests_path = ut.create_battery_test_directory()

        # Layout creation.
        self.layout = self.create_layout()
        # Create main window for display.
        self.window = Psg.Window('IMU Battery Tester', self.layout, finalize=True)

        self.create_orientation_plot(c.AZIMUTH)

        # Display loop.
        while True:
            self.update_imu_values()
            self.update_orientation_plot()
            event, values = self.window.read(0)
            if event in [Psg.WIN_CLOSED, 'None']:  # On window close clicked.
                break
            # Refresh available COM ports.
            if event == '-B-COM-REFRESH-':
                self.refresh_com_ports()
            # Combo of available COM ports.
            if event == '-COMBO-COM-PORT-':
                self.imu_com_port = values['-COMBO-COM-PORT-']
            # Combo of available baud rates.
            if event == '-COMBO-BAUD-RATE-':
                self.imu_baud_rate = int(values['-COMBO-BAUD-RATE-'])
            # Toggle IMU connection.
            if event == '-B-IMU-CONNECT-':
                self.toggle_imu_connect()
            # Set azimuth.
            if event == '-SLD-AZIMUTH-':
                self.set_azimuth(int(values['-SLD-AZIMUTH-']))
            # Set the return rate of the IMU.
            if event == '-COMBO-RETURN-RATE-':
                self.imu.set_update_rate(float(values['-COMBO-RETURN-RATE-'][:-2]))
            # Calibrate IMU acceleration.
            if event == '-B-IMU-CALIBRATE-':
                self.imu.send_config_command(wm.protocol.ConfigCommand(register=wm.protocol.Register.calsw, data=0x01))
            # Start a timed test.
            if event == '-B-TEST-START-':
                self.toggle_test()
            # Stop a timed test.
            if event == '-B-TEST-STOP-':
                self.toggle_test()

        # Close IMU connections manually.
        print('Program closing down...')

        if self.imu_connected:
            self.imu.ser.close()
            self.imu.close()

    def create_layout(self):
        """
        Create the layout for the program.

        Returns:
            layout (list): 2D list used by PySimpleGUI as the layout format.
        """
        # IMU controls.
        imu_layout = [
            [Psg.T('IMU Controls', s=(40, 1), justification='c', font=st.FONT_HEADING, p=((0, 0), (0, 20)))],
            [Psg.B(k='-B-COM-REFRESH-', button_text='', image_source=refresh_icon, image_subsample=4, border_width=3),
             Psg.Combo(k='-COMBO-COM-PORT-', default_value=self.imu_com_port, values=self.com_ports, s=7,
                       font=st.FONT_COMBO, enable_events=True, readonly=True),
             Psg.T('Baud Rate:', justification='r', font=st.FONT_DESCR, p=((20, 0), (0, 0))),
             Psg.Combo(k='-COMBO-BAUD-RATE-', default_value=self.imu_baud_rate, values=c.COMMON_BAUD_RATES, s=7,
                       font=st.FONT_COMBO, enable_events=True, readonly=True)],
            [Psg.B(k='-B-IMU-CONNECT-', button_text='Connect IMU', s=(15, 1), font=st.FONT_BTN, border_width=3,
                   p=((0, 0), (20, 20)))],
            [Psg.T('Return Rate:', justification='r', font=st.FONT_DESCR, p=((20, 0), (0, 0))),
             Psg.Combo(k='-COMBO-RETURN-RATE-', values=c.IMU_RATE_OPTIONS, s=7, font=st.FONT_COMBO, enable_events=True,
                       readonly=True, disabled=True),
             Psg.B(k='-B-IMU-CALIBRATE-', button_text='Calibrate Acc', s=(15, 1), font=st.FONT_BTN, border_width=3,
                   p=((40, 0), (0, 0)), disabled=True)]
        ]
        # Orientation plot.
        imu_plot_layout = [
            [Psg.T('IMU Orientation Plot', s=(40, 1), justification='c', font=st.FONT_HEADING)],
            [Psg.Canvas(k='-CANVAS-PLOT-', s=(500, 500))],
            [Psg.T('Select Azimuth', font=st.FONT_DESCR, p=((0, 0), (5, 0)))],
            [Psg.Sl(k='-SLD-AZIMUTH-', range=(0, 360), default_value=c.AZIMUTH, s=(40, 10),
                    orientation='h', enable_events=True)]
        ]
        # IMU values from callback.
        imu_values_layout = [
            [Psg.T('IMU Values (Raw)', s=(40, 1), justification='c', font=st.FONT_HEADING)],
            [Psg.T('Acceleration (m/s^2): ', justification='l', font=st.FONT_DESCR, s=(20, 1)),
             Psg.T(k='-TEXT-ACCELERATION-', text='', justification='r', font=st.FONT_DESCR, s=(30, 1))],
            [Psg.T('Quaternion: ', justification='l', font=st.FONT_DESCR, s=(20, 1)),
             Psg.T(k='-TEXT-QUATERNION-', text='', justification='r', font=st.FONT_DESCR, s=(30, 1))],
            [Psg.T('Euler Angles (deg): ', justification='l', font=st.FONT_DESCR, s=(20, 1)),
             Psg.T(k='-TEXT-ANGLE-', text='', justification='r', font=st.FONT_DESCR, s=(30, 1))]
        ]

        # Test start column.
        test_start_layout = [
            [Psg.T(text='Start Time', font=st.FONT_DESCR + ' underline', s=(15, 1))],
            [Psg.T(k='-TEXT-TEST-START-', font=st.FONT_DESCR, s=(15, 1))]
        ]

        # Test last message received column.
        test_last_layout = [
            [Psg.T(text='Last Message\nReceived At', font=st.FONT_DESCR + ' underline', s=(15, 1))],
            [Psg.T(k='-TEXT-TEST-LAST-', font=st.FONT_DESCR, s=(15, 1))]
        ]
        # Test elapsed time column.
        test_elapsed_layout = [
            [Psg.T(text='Elapsed Time', font=st.FONT_DESCR + ' underline', s=(15, 1))],
            [Psg.T(k='-TEXT-TEST-ELAPSED-', font=st.FONT_DESCR, s=(15, 1))]
        ]
        # Test counter layout
        test_counter_layout = [
            [Psg.T(text='Total Messages', font=st.FONT_DESCR + ' underline', s=(15, 1))],
            [Psg.T(k='-TEXT-TEST-COUNTER-', font=st.FONT_DESCR, s=(15, 1))]
        ]
        # Test control layout.
        test_control_layout = [
            [Psg.B(k='-B-TEST-START-', button_text='Start', font=st.FONT_BTN, border_width=3,
                   p=((0, 10), (20, 20)), disabled=True, button_color='#33ff77'),
             Psg.Col(test_start_layout, element_justification='c', vertical_alignment='t'),
             Psg.Col(test_last_layout, element_justification='c', vertical_alignment='t'),
             Psg.Col(test_elapsed_layout, element_justification='c', vertical_alignment='t'),
             Psg.Col(test_counter_layout, element_justification='c', vertical_alignment='t'),
             Psg.B(k='-B-TEST-STOP-', button_text='Stop', font=st.FONT_BTN, border_width=3,
                   p=((0, 10), (20, 20)), disabled=True, button_color='#ff2121')],
            [Psg.T('Test Name', font=st.FONT_DESCR, justification='l'),
             Psg.I(k='-INP-TEST-NAME-', justification='l', default_text='Drain Test')]
        ]
        # Total layout.
        layout = [
            [Psg.Col(imu_layout, element_justification='c', vertical_alignment='t', justification='c')],
            [Psg.HSep(p=((0, 10), (10, 20)))],
            [Psg.Col(imu_plot_layout, element_justification='c', vertical_alignment='t'),
             Psg.Col(imu_values_layout, element_justification='c', vertical_alignment='t')],
            [Psg.HSep(p=((0, 10), (10, 20)))],
            [Psg.Col(test_control_layout, element_justification='c', vertical_alignment='t',
                     justification='c')]
        ]

        return layout

    def toggle_test(self):
        """
        Toggle the testing state of the program. If true, reset imuTestCounter and instantiate testStartTime, else save
        test data to file.
        """
        self.testing = not self.testing
        print(f'Start a test: {self.testing}')

        if self.testing:
            self.imu_counter = 0
            self.test_start = dt.now().timestamp()
        else:
            self.save_to_file()

        # Set element states.
        self.window['-B-TEST-START-'].update(disabled=True if self.testing else False)
        self.window['-B-TEST-STOP-'].update(disabled=True if not self.testing else False)
        self.window['-TEXT-TEST-START-'].update(
            f"{dt.fromtimestamp(self.test_start).strftime('%H:%M:%S.%f')[:-3]}s" if self.testing else "")
        self.window['-TEXT-TEST-LAST-'].update('' if self.testing else "No Test Running")
        self.window['-TEXT-TEST-ELAPSED-'].update('')
        self.window['-B-IMU-CONNECT-'].update(disabled=True if self.testing else False)

    def refresh_com_ports(self):
        """
        Refresh the available COM ports. The list of available COM ports is updated as well as the related Combo box.
        """
        self.com_ports = IMU.available_com_ports()
        self.window['-COMBO-COM-PORT-'].update(values=self.com_ports)

    def toggle_imu_connect(self):
        """
        Toggles the connection state of the IMU. If the IMU is connected, it will be disconnected, else it will
        be connected using the values set in the Combo boxes.
        """

        # If imu is not connected it must be connected, else disconnected.
        if not self.imu_connected:
            print(f'Attempting to connect to {self.imu_com_port} at {self.imu_baud_rate}...')
            try:
                self.imu = wm.IMU(self.imu_com_port, self.imu_baud_rate)
                self.imu.subscribe(self.imu_callback)
                self.imu_connected = True
            except Exception as e:
                print(f'Error connecting to IMU: {e}.')
                self.imu_connected = False
        else:
            print(f'Disconnecting from {self.imu_com_port} as {self.imu_baud_rate}...')
            self.imu.close()
            self.imu.ser.close()
            self.imu_connected = False
        # Set element states
        self.window['-COMBO-COM-PORT-'].update(disabled=True if self.imu_connected else False)
        self.window['-COMBO-BAUD-RATE-'].update(disabled=True if self.imu_connected else False)
        self.window['-B-IMU-CONNECT-'].update(
            button_color='#ff2121' if self.imu_connected else Psg.DEFAULT_BUTTON_COLOR,
            text='Disconnect IMU' if self.imu_connected else 'Connect IMU'
        )
        self.window['-COMBO-RETURN-RATE-'].update(disabled=True if not self.imu_connected else False)
        self.window['-B-IMU-CALIBRATE-'].update(disabled=True if not self.imu_connected else False)
        self.window['-B-TEST-START-'].update(disabled=True if not self.imu_connected else False)

    def create_orientation_plot(self, azimuth):
        """
        Instantiate the initial plotting variables: The Figure and the axis, and the 2 plot parameters that store the
        line and point data. This is also called when changing the azimuth of the plot as the entire canvas needs to
        be redrawn.

        Args:
            azimuth (int): Azimuth angle in degrees.
        """
        fig = Figure(figsize=(4, 4), dpi=100)
        self.ax = fig.add_subplot(111, projection='3d')
        fig.patch.set_facecolor(Psg.DEFAULT_BACKGROUND_COLOR)
        self.ax.set_position((0, 0, 1, 1))

        self.ax = ut.initialise_axis(self.ax, azimuth)
        self.ax.disable_mouse_rotation()

        self.fig_agg = ut.draw_figure(fig, self.window['-CANVAS-PLOT-'].TKCanvas)

        self.bg = self.fig_agg.copy_from_bbox(self.ax.bbox)

        self.point_data = self.ax.plot([], [], [], color="red", linestyle="none", marker="o", animated=True)[0]
        self.line_data = self.ax.plot([], [], [], color="red", animated=True)[0]

    def update_orientation_plot(self):
        """
        Update the plot to show orientation of the IMU unit. Restores the axis region that does not need to be
        recreated (bg), then adds the points to the axis. Blit is used to increase plot speed substantially. This
        currently limits the plot to lines and points, surfaces are not used.
        """
        # Only plot if the IMU is connected, and a quaternion value is available.
        if self.imu_connected and self.quaternion:
            self.fig_agg.restore_region(self.bg)

            self.ax = ut.plot_orientation_on_axis(self.ax, self.quaternion, self.point_data, self.line_data)

            self.fig_agg.blit(self.ax.bbox)
            self.fig_agg.flush_events()

    def set_azimuth(self, azimuth):
        """
        Set the azimuth of the plot to the slider value. This allows for aligning the plot to the user's orientation
        since the IMU orientation is based on magnetic north. The axis needs to be cleared first, then reinitialised
        to ensure a clean plot is saved for blit purposes.

        Args:
            azimuth (int): Azimuth to set the displayed plot to.
        """
        # Clear axis.
        self.ax.cla()
        # Reinitialise axis.
        self.ax = ut.initialise_axis(self.ax, azimuth)
        # Redraw new axis.
        self.fig_agg.draw()
        # Re-save background for blit.
        self.bg = self.fig_agg.copy_from_bbox(self.ax.bbox)

    def imu_callback(self, msg):
        """
        Callback subscribed to the IMU object. Called whenever a new dataset is available. This callback is
        activated for every value sent by the IMU (Acceleration, Quaternion, Angle, ..etc) and not just for each
        serial packet. The counter only increments when a quaternion message is read.

        This callback is handled off the main thread, and as such no GUI updates should take place from functions
        originating here.

        Args:
            msg (String): The type of dataset that is newly available.
        """
        msg_type = type(msg)

        if msg_type is wm.protocol.AccelerationMessage:
            self.acceleration = self.imu.get_acceleration()
        elif msg_type is wm.protocol.AngleMessage:
            self.angle = self.imu.get_angle()
        elif msg_type is wm.protocol.QuaternionMessage:
            self.quaternion = self.imu.get_quaternion()
            self.test_last = dt.now().timestamp()
            self.imu_counter += 1

    def update_imu_values(self):
        """
        Update the shown IMU and test values if they are available.
        """
        if self.imu_connected:
            if self.acceleration:
                self.window['-TEXT-ACCELERATION-'].update(
                    f'[{self.acceleration[0]:.4f}, {self.acceleration[1]:.4f}, {self.acceleration[2]:.4f}]')
            if self.quaternion:
                self.window['-TEXT-QUATERNION-'].update(
                    f'[{self.quaternion[0]:.4f}, {self.quaternion[1]:.4f}, {self.quaternion[2]:.4f}, '
                    f'{self.quaternion[3]:.4f}]')
            if self.angle and self.angle[0]:
                self.window['-TEXT-ANGLE-'].update(f'[{self.angle[0]:.4f}, {self.angle[1]:.4f}, {self.angle[2]:.4f}]')

            if self.testing:
                self.window['-TEXT-TEST-LAST-'].update(
                    f"{dt.fromtimestamp(self.test_last).strftime('%H:%M:%S.%f')[:-3]}s")
                self.window['-TEXT-TEST-ELAPSED-'].update(
                    f"{dt.fromtimestamp(max(self.test_last - self.test_start, 0)).strftime('%H:%M:%S')}s")
                self.window['-TEXT-TEST-COUNTER-'].update(
                    f'{self.imu_counter}'
                )

    def save_to_file(self):
        """
        Save details of the test to the DrainTests.txt file.

        Future note: Calling save_to_file from the IMU callback was causing threading issues as updating GUI from
        a non-main thread is a problem.
        """

        self.save_file = open(
            Path(self.battery_tests_path, 'DrainTests.txt'), 'a')

        self.save_file.write(
            f"{self.window['-INP-TEST-NAME-'].get()} "
            f"Started: {dt.fromtimestamp(self.test_start).strftime('%d %m %Y - %H:%M:%S')}, "
            f"Test Completed: {dt.fromtimestamp(dt.now().timestamp()).strftime('%d %m %Y - %H:%M:%S')}, "
            f"Last Message: {dt.fromtimestamp(self.test_last).strftime('%d %m %Y - %H:%M:%S')}, "
            f"Run Time: {dt.fromtimestamp(self.test_last - self.test_start).strftime('%H:%M:%S')}, "
            f"Total Messages received: {self.imu_counter}\n")

        self.save_file.close()

ImuBatterLifeTest()


from flask import Flask, render_template, url_for
app = Flask(__name__)

posts = [
    {
        'author': 'risqull',
        'title': 'blog post content',
        'content': 'testing'
    },
    {
        'author': 'random',
        'title': 'about',
        'content': 'tesss'
    }
]

@app.route('/')
def hello_world():
    return render_template('index.html', posts=posts)

@app.route('/about')
def aboutpage():
    return render_template('about.html', title='About')

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


from . import models
from django import forms
from django.forms.models import inlineformset_factory

class RecipeIngredientsForm(forms.ModelForm):

    class Meta:
        model = models.RecipeIngredients
        exclude = ()

RecipeIngredientsFormSet = inlineformset_factory(
    models.Recipe, models.RecipeIngredients, form=RecipeIngredientsForm,
    fields=['name', 'amount'], extra=1, can_delete=True)

class RecipeForm(forms.ModelForm):
    class Meta:
        model = models.Recipe
        fields = ['category', 'title', 'image', 'instructions', 'about']

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)
        if user is not None:
            self.fields['category'].queryset = (
                models.Category.objects.filter(
                    pk__in=user.category.values_list('category__pk')
                )
            )


import boto3
import pandas as pd
from sagemaker import get_execution_role

role = get_execution_role()

# Specify the S3 bucket
bucket_name = 'llminfo'

# Instantiate a s3 client
s3 = boto3.client('s3', region_name='us-west-2')

# List all the objects in the bucket
objects_in_bucket = s3.list_objects(Bucket=bucket_name)

# Suppose you have a CSV file you want to read into a pandas dataframe
file_to_read = 'FaCov_dataset (3).csv' # replace with your file name

# Check if the file exists in the bucket
if any(obj['Key'] == file_to_read for obj in objects_in_bucket['Contents']):

    # Get the file object
    file_obj = s3.get_object(Bucket=bucket_name, Key=file_to_read)

    # Read the file object into a pandas dataframe
    data = pd.read_csv(file_obj['Body'])
    # print(df.head())
    # print(df.columns)
    # print(df['content'][0])
    # print(df['raw_label'][0])
    # print(df.raw_label.unique())
    selected_values = ['mostly true', 'half true', 'true', 'partly true', 'Partly True']
    sub_df = data[data['raw_label'].isin(selected_values)]
    print(sub_df.head())
    length = len(sub_df)
    print("Length of the subdataframe:", length)
    print(sub_df.columns)
    print(sub_df['content'].tolist()[0])
    print('********')
    content_string = '\n'.join(sub_df['content'].astype(str))

print(content_string)


# -*- coding: utf-8 -*-
import scrapy
from scrapy.spiders import XMLFeedSpider
import json
import time
from filtering.items import FilteringItem

class HackNewsSpider(XMLFeedSpider):
    name = 'martinfowler'
    alias = 'martinfowler'
    group = '海外'

    start_urls = ['https://martinfowler.com/feed.atom']
    itertag = 'entry'

    def parse_node(self, response, selector):
        print('111111111111')
        item = FilteringItem()
        item['title'] = selector.css("title::text").extract_first()
        item['url'] = selector.css("link::href").get()
        t = time.mktime(
            time.strptime(selector.css("updated::text").extract_first(),
            "%Y-%m-%dT%H:%M:%S-04:00")
        )
        item['time'] = int(t)
        item['site'] = self.alias
        item['group'] = self.group
        print(item)


#!/usr/bin/env python

#run these in bash before script
#1. $srun --account=bgmp --partition=bgmp --nodes=1 --ntasks-per-node=1 --time=2:00:00 --cpus-per-task=1 --pty bash
#2. $dir="/projects/bgmp/shared/2017_sequencing"

import numpy as np
import bioinfo
import matplotlib.pyplot as plt
import gzip
import argparse

def get_args():
    parser = argparse.ArgumentParser(description = "client input program")
    parser.add_argument("-f", "--filename", help = "specify filename", type=str, required = True)
    parser.add_argument("-r", "--readlength", help = "specify readlength", type=int, required = True)
    parser.add_argument("-o", help = "specify outfile name", type=str, required = True)

    return parser.parse_args()

#make arg input name easier to type
clinput = get_args()
f = clinput.filename
r = clinput.readlength
o = clinput.o

#create a numpy array that we will fill with mean values
fa_array = np.zeros(r,dtype=np.int64) #should the end length by length of file? (wc -l)/4?

numrecord = 0
with gzip.open(f,"rt") as fh: #open file
        i = 0

        for line in fh: #iterate through input file
            i+=1
            line = line.strip('\n') #strip new line characters

            if i%4 == 0: #grab every 4th line (q score line)
                numrecord = int(i/4) -1
                if numrecord % 100000 == 0 :
                    print(f"Current Record Is {numrecord}")
                for c,s in enumerate(line): #populates list using c for counter and s for conver_phred. Lets us do two different calculations at the same spot
                    score = bioinfo.convert_phred(s)
                    # fa_array[c,l] = score
                    fa_array[c] += score

#create empty array and call it 'mean'
mean = np.zeros(r, dtype=float)

#populate array w/ np.mean function
# for i in range(r):
#     mean[i] = fa_array[i]/numrecord

# another way of coding the above
mean = fa_array/numrecord

#np.mean(fa_array[i])

plt.bar(range(r), mean)
plt.xlabel("Sequence Postition")
plt.ylabel("Mean Quality Score")
plt.title("Mean Quality Scores by Position for FastQ File")
plt.savefig(o+'.png')


import sys
from collections import defaultdict
data = [[i.strip() for i in line.split("-")] for line in sys.stdin]
paths = defaultdict(lambda: set())
uniq_paths = set()
for a, b in data:
    paths[a].add(b)
    paths[b].add(a)

def dfs(seen, node):
    count = 0
    if node == "end":
        return 1
    if node in seen:
        return 0
    if node.islower():
        seen.add(node)
    for n in paths[node]:
        count += dfs(seen.copy(), n)
    return count

def dfs2(seen, node, twice, path):
    path.append(node)
    if node == "end":
        uniq_paths.add(",".join(path))
        return 1
    if node in seen:
        return 0
    if node.islower():
        seen.add(node)
    for n in paths[node]:
        dfs2(seen.copy(), n, twice, path.copy())
        if not twice and node != "start" and node.islower():
            seen2 = seen.copy()
            seen2.remove(node)
            dfs2(seen2.copy(), n, True, path.copy())
    return

if __name__ == "__main__":
    print(dfs(set(), "start"))
    dfs2(set(), "start", False, list())
    print(len(uniq_paths))