# -*- coding: utf-8 -*-
import sys
import re
import pdb
import sqlite3

def to_numbers(ch):
    n_dict = {"一":1,\
              "二":2,\
              "三":3,\
              "四":4,\
              "五":5,\
              "六":6,\
              "七":7,\
              "八":8,\
              "九":9,\
              "十":10}
    return n_dict[ch]

def main(args):
    #pdb.set_trace()
    #rid = "testrid"
    rid = args[1].decode("gb18030");
    #lines = "|||                 小校场    三清殿    小校场    |||                        ＼   ｜   ／|||                 小校场---武当广场---小校场    |||                      ／   ↑   ＼|||                 小校场    凌霄宫    小校场    ||||||武当广场 - [门派]||||||    这是一个由大石板铺成的广场，是武当弟子学习武功和互|||相切磋的地点。周围种满了梧桐树，一到秋天就是满地的落叶。|||一个年纪轻轻的道童正在打扫。北边是灵霄宫三清殿。|||  「深秋」: 东方的天空渐渐的发白了，又一个万物初醒的早上！。||||||    这里明显的出口是 north、east、southeast、northeast、west、southdown、southwest|||、northwest 和 eastdown。||||||    二位武当派小道士 道童(Daotong)|||    武当派真人 冲虚道长(Chongxu daozhang)|||>".split("|||")

    lines = args[2].decode("gb18030").encode("utf8").split("|||")
    p = re.compile(r"^\s*((一|二|三|四|五|六|七|八|九|十)(位|只))?(.*?)\((.*?)\)( <(.*?)>)?$")
    conn = sqlite3.connect('./tintin/myscripts/pkuxkx/gps/xkxmap.sqlite')
    cursor = conn.cursor()
    cursor.execute('delete from room_npc where rid=?',(rid,))
    for line in lines:
        if p.match(line):
            s = p.match(line)
            npc_num = 1
            if s.group(2) is not None:
                npc_num = to_numbers(s.group(2))
            ps = re.compile(r" |「|」")
            mylist = ps.split(s.group(4).strip(" "))
            npc_title1=""
            npc_title2=""
            npc_title3=""
            npc_cname=""
            ts = []
            for t in mylist:
                if t=="":
                    continue
                ts.append(t)
            if len(ts) == 4:
                npc_title1 = ts[0]
                npc_title2 = ts[1]
                npc_title3 = ts[2]
                npc_cname = ts[3]
            if len(ts) == 3:
                npc_title1 = ts[0]
                npc_title2 = ts[1]
                npc_cname = ts[2]
            if len(ts) == 2:
                npc_title1 = ts[0]
                npc_cname = ts[1]
            if len(ts) == 1:
                npc_cname = ts[0]

            npc_ename = s.group(5)
            npc_status = s.group(7)
            if npc_status is None:
                npc_status = "normal"
#            print(npc_num)
#            print(npc_title1.decode("utf8").encode("gb18030"))
#            print(npc_title2.decode("utf8").encode("gb18030"))
#            print(npc_title3.decode("utf8").encode("gb18030"))
#            print(npc_cname.decode("utf8").encode("gb18030"))
#            print(npc_ename.decode("utf8").encode("gb18030"))
#            print(npc_status.decode("utf8").encode("gb18030"))
            cursor.execute('insert into room_npc (rid,npc_num,npc_title1,npc_title2,npc_title3,npc_cname,npc_ename) values (?,?,?,?,?,?,?)',(rid,npc_num,npc_title1.decode("utf8"),npc_title2.decode("utf8"),npc_title3.decode("utf8"),npc_cname.decode("utf8"),npc_ename.decode("utf8")));
            conn.commit()
    conn.close()

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


# coding: utf-8

"""
    Refinery Calc API Documentation

    Integrate the powerful Refinery Calc Engine into your process using this API.  # noqa: E501

    OpenAPI spec version: 1.0
    Contact: support@refinerycalc.com.com
    Generated by: https://github.com/swagger-api/swagger-codegen.git
"""

import pprint
import re  # noqa: F401

import six

class OutputTypes(object):
    """NOTE: This class is auto generated by the swagger code generator program.

    Do not edit the class manually.
    """
    """
    Attributes:
      swagger_types (dict): The key is attribute name
                            and the value is attribute type.
      attribute_map (dict): The key is attribute name
                            and the value is json key in definition.
    """
    swagger_types = {
        'balance': 'list[OutputDetails]',
        'complexity': 'list[OutputDetails]',
        'constraints': 'list[OutputDetails]',
        'crude_names': 'list[OutputDetails]',
        'crude_percent': 'list[OutputDetails]',
        'crude_pricing': 'list[OutputDetails]',
        'crude_quality': 'list[OutputDetails]',
        'crudes_and_feeds': 'list[OutputDetails]',
        'delete_category': 'list[OutputDetails]',
        'economics': 'list[OutputDetails]',
        'end_points_f': 'list[OutputDetails]',
        'expense_factors': 'list[OutputDetails]',
        'fcc_hydrk_conv': 'list[OutputDetails]',
        'feeds_pricing': 'list[OutputDetails]',
        'gasoline_blending': 'list[OutputDetails]',
        'general': 'list[OutputDetails]',
        'hydrogen': 'list[OutputDetails]',
        'product_pricing': 'list[OutputDetails]',
        'products': 'list[OutputDetails]',
        'refinery_layout_svg': 'list[OutputDetails]',
        'sustainability': 'list[OutputDetails]',
        'unit_balance': 'list[OutputDetails]'
    }

    attribute_map = {
        'balance': 'balance',
        'complexity': 'complexity',
        'constraints': 'constraints',
        'crude_names': 'crudeNames',
        'crude_percent': 'crudePercent',
        'crude_pricing': 'crudePricing',
        'crude_quality': 'crudeQuality',
        'crudes_and_feeds': 'crudesAndFeeds',
        'delete_category': 'deleteCategory',
        'economics': 'economics',
        'end_points_f': 'endPointsF',
        'expense_factors': 'expenseFactors',
        'fcc_hydrk_conv': 'fccHydrkConv',
        'feeds_pricing': 'feedsPricing',
        'gasoline_blending': 'gasolineBlending',
        'general': 'general',
        'hydrogen': 'hydrogen',
        'product_pricing': 'productPricing',
        'products': 'products',
        'refinery_layout_svg': 'refineryLayoutSVG',
        'sustainability': 'sustainability',
        'unit_balance': 'unitBalance'
    }

    def __init__(self, balance=None, complexity=None, constraints=None, crude_names=None, crude_percent=None, crude_pricing=None, crude_quality=None, crudes_and_feeds=None, delete_category=None, economics=None, end_points_f=None, expense_factors=None, fcc_hydrk_conv=None, feeds_pricing=None, gasoline_blending=None, general=None, hydrogen=None, product_pricing=None, products=None, refinery_layout_svg=None, sustainability=None, unit_balance=None):  # noqa: E501
        """OutputTypes - a model defined in Swagger"""  # noqa: E501
        self._balance = None
        self._complexity = None
        self._constraints = None
        self._crude_names = None
        self._crude_percent = None
        self._crude_pricing = None
        self._crude_quality = None
        self._crudes_and_feeds = None
        self._delete_category = None
        self._economics = None
        self._end_points_f = None
        self._expense_factors = None
        self._fcc_hydrk_conv = None
        self._feeds_pricing = None
        self._gasoline_blending = None
        self._general = None
        self._hydrogen = None
        self._product_pricing = None
        self._products = None
        self._refinery_layout_svg = None
        self._sustainability = None
        self._unit_balance = None
        self.discriminator = None
        if balance is not None:
            self.balance = balance
        if complexity is not None:
            self.complexity = complexity
        if constraints is not None:
            self.constraints = constraints
        if crude_names is not None:
            self.crude_names = crude_names
        if crude_percent is not None:
            self.crude_percent = crude_percent
        if crude_pricing is not None:
            self.crude_pricing = crude_pricing
        if crude_quality is not None:
            self.crude_quality = crude_quality
        if crudes_and_feeds is not None:
            self.crudes_and_feeds = crudes_and_feeds
        if delete_category is not None:
            self.delete_category = delete_category
        if economics is not None:
            self.economics = economics
        if end_points_f is not None:
            self.end_points_f = end_points_f
        if expense_factors is not None:
            self.expense_factors = expense_factors
        if fcc_hydrk_conv is not None:
            self.fcc_hydrk_conv = fcc_hydrk_conv
        if feeds_pricing is not None:
            self.feeds_pricing = feeds_pricing
        if gasoline_blending is not None:
            self.gasoline_blending = gasoline_blending
        if general is not None:
            self.general = general
        if hydrogen is not None:
            self.hydrogen = hydrogen
        if product_pricing is not None:
            self.product_pricing = product_pricing
        if products is not None:
            self.products = products
        if refinery_layout_svg is not None:
            self.refinery_layout_svg = refinery_layout_svg
        if sustainability is not None:
            self.sustainability = sustainability
        if unit_balance is not None:
            self.unit_balance = unit_balance

    @property
    def balance(self):
        """Gets the balance of this OutputTypes.  # noqa: E501

        :return: The balance of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._balance

    @balance.setter
    def balance(self, balance):
        """Sets the balance of this OutputTypes.

        :param balance: The balance of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._balance = balance

    @property
    def complexity(self):
        """Gets the complexity of this OutputTypes.  # noqa: E501

        :return: The complexity of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._complexity

    @complexity.setter
    def complexity(self, complexity):
        """Sets the complexity of this OutputTypes.

        :param complexity: The complexity of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._complexity = complexity

    @property
    def constraints(self):
        """Gets the constraints of this OutputTypes.  # noqa: E501

        :return: The constraints of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._constraints

    @constraints.setter
    def constraints(self, constraints):
        """Sets the constraints of this OutputTypes.

        :param constraints: The constraints of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._constraints = constraints

    @property
    def crude_names(self):
        """Gets the crude_names of this OutputTypes.  # noqa: E501

        :return: The crude_names of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._crude_names

    @crude_names.setter
    def crude_names(self, crude_names):
        """Sets the crude_names of this OutputTypes.

        :param crude_names: The crude_names of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._crude_names = crude_names

    @property
    def crude_percent(self):
        """Gets the crude_percent of this OutputTypes.  # noqa: E501

        :return: The crude_percent of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._crude_percent

    @crude_percent.setter
    def crude_percent(self, crude_percent):
        """Sets the crude_percent of this OutputTypes.

        :param crude_percent: The crude_percent of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._crude_percent = crude_percent

    @property
    def crude_pricing(self):
        """Gets the crude_pricing of this OutputTypes.  # noqa: E501

        :return: The crude_pricing of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._crude_pricing

    @crude_pricing.setter
    def crude_pricing(self, crude_pricing):
        """Sets the crude_pricing of this OutputTypes.

        :param crude_pricing: The crude_pricing of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._crude_pricing = crude_pricing

    @property
    def crude_quality(self):
        """Gets the crude_quality of this OutputTypes.  # noqa: E501

        :return: The crude_quality of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._crude_quality

    @crude_quality.setter
    def crude_quality(self, crude_quality):
        """Sets the crude_quality of this OutputTypes.

        :param crude_quality: The crude_quality of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._crude_quality = crude_quality

    @property
    def crudes_and_feeds(self):
        """Gets the crudes_and_feeds of this OutputTypes.  # noqa: E501

        :return: The crudes_and_feeds of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._crudes_and_feeds

    @crudes_and_feeds.setter
    def crudes_and_feeds(self, crudes_and_feeds):
        """Sets the crudes_and_feeds of this OutputTypes.

        :param crudes_and_feeds: The crudes_and_feeds of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._crudes_and_feeds = crudes_and_feeds

    @property
    def delete_category(self):
        """Gets the delete_category of this OutputTypes.  # noqa: E501

        :return: The delete_category of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._delete_category

    @delete_category.setter
    def delete_category(self, delete_category):
        """Sets the delete_category of this OutputTypes.

        :param delete_category: The delete_category of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._delete_category = delete_category

    @property
    def economics(self):
        """Gets the economics of this OutputTypes.  # noqa: E501

        :return: The economics of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._economics

    @economics.setter
    def economics(self, economics):
        """Sets the economics of this OutputTypes.

        :param economics: The economics of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._economics = economics

    @property
    def end_points_f(self):
        """Gets the end_points_f of this OutputTypes.  # noqa: E501

        :return: The end_points_f of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._end_points_f

    @end_points_f.setter
    def end_points_f(self, end_points_f):
        """Sets the end_points_f of this OutputTypes.

        :param end_points_f: The end_points_f of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._end_points_f = end_points_f

    @property
    def expense_factors(self):
        """Gets the expense_factors of this OutputTypes.  # noqa: E501

        :return: The expense_factors of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._expense_factors

    @expense_factors.setter
    def expense_factors(self, expense_factors):
        """Sets the expense_factors of this OutputTypes.

        :param expense_factors: The expense_factors of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._expense_factors = expense_factors

    @property
    def fcc_hydrk_conv(self):
        """Gets the fcc_hydrk_conv of this OutputTypes.  # noqa: E501

        :return: The fcc_hydrk_conv of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._fcc_hydrk_conv

    @fcc_hydrk_conv.setter
    def fcc_hydrk_conv(self, fcc_hydrk_conv):
        """Sets the fcc_hydrk_conv of this OutputTypes.

        :param fcc_hydrk_conv: The fcc_hydrk_conv of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._fcc_hydrk_conv = fcc_hydrk_conv

    @property
    def feeds_pricing(self):
        """Gets the feeds_pricing of this OutputTypes.  # noqa: E501

        :return: The feeds_pricing of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._feeds_pricing

    @feeds_pricing.setter
    def feeds_pricing(self, feeds_pricing):
        """Sets the feeds_pricing of this OutputTypes.

        :param feeds_pricing: The feeds_pricing of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._feeds_pricing = feeds_pricing

    @property
    def gasoline_blending(self):
        """Gets the gasoline_blending of this OutputTypes.  # noqa: E501

        :return: The gasoline_blending of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._gasoline_blending

    @gasoline_blending.setter
    def gasoline_blending(self, gasoline_blending):
        """Sets the gasoline_blending of this OutputTypes.

        :param gasoline_blending: The gasoline_blending of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._gasoline_blending = gasoline_blending

    @property
    def general(self):
        """Gets the general of this OutputTypes.  # noqa: E501

        :return: The general of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._general

    @general.setter
    def general(self, general):
        """Sets the general of this OutputTypes.

        :param general: The general of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._general = general

    @property
    def hydrogen(self):
        """Gets the hydrogen of this OutputTypes.  # noqa: E501

        :return: The hydrogen of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._hydrogen

    @hydrogen.setter
    def hydrogen(self, hydrogen):
        """Sets the hydrogen of this OutputTypes.

        :param hydrogen: The hydrogen of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._hydrogen = hydrogen

    @property
    def product_pricing(self):
        """Gets the product_pricing of this OutputTypes.  # noqa: E501

        :return: The product_pricing of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._product_pricing

    @product_pricing.setter
    def product_pricing(self, product_pricing):
        """Sets the product_pricing of this OutputTypes.

        :param product_pricing: The product_pricing of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._product_pricing = product_pricing

    @property
    def products(self):
        """Gets the products of this OutputTypes.  # noqa: E501

        :return: The products of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._products

    @products.setter
    def products(self, products):
        """Sets the products of this OutputTypes.

        :param products: The products of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._products = products

    @property
    def refinery_layout_svg(self):
        """Gets the refinery_layout_svg of this OutputTypes.  # noqa: E501

        :return: The refinery_layout_svg of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._refinery_layout_svg

    @refinery_layout_svg.setter
    def refinery_layout_svg(self, refinery_layout_svg):
        """Sets the refinery_layout_svg of this OutputTypes.

        :param refinery_layout_svg: The refinery_layout_svg of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._refinery_layout_svg = refinery_layout_svg

    @property
    def sustainability(self):
        """Gets the sustainability of this OutputTypes.  # noqa: E501

        :return: The sustainability of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._sustainability

    @sustainability.setter
    def sustainability(self, sustainability):
        """Sets the sustainability of this OutputTypes.

        :param sustainability: The sustainability of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._sustainability = sustainability

    @property
    def unit_balance(self):
        """Gets the unit_balance of this OutputTypes.  # noqa: E501

        :return: The unit_balance of this OutputTypes.  # noqa: E501
        :rtype: list[OutputDetails]
        """
        return self._unit_balance

    @unit_balance.setter
    def unit_balance(self, unit_balance):
        """Sets the unit_balance of this OutputTypes.

        :param unit_balance: The unit_balance of this OutputTypes.  # noqa: E501
        :type: list[OutputDetails]
        """

        self._unit_balance = unit_balance

    def to_dict(self):
        """Returns the model properties as a dict"""
        result = {}

        for attr, _ in six.iteritems(self.swagger_types):
            value = getattr(self, attr)
            if isinstance(value, list):
                result[attr] = list(map(
                    lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
                    value
                ))
            elif hasattr(value, "to_dict"):
                result[attr] = value.to_dict()
            elif isinstance(value, dict):
                result[attr] = dict(map(
                    lambda item: (item[0], item[1].to_dict())
                    if hasattr(item[1], "to_dict") else item,
                    value.items()
                ))
            else:
                result[attr] = value
        if issubclass(OutputTypes, dict):
            for key, value in self.items():
                result[key] = value

        return result

    def to_str(self):
        """Returns the string representation of the model"""
        return pprint.pformat(self.to_dict())

    def __repr__(self):
        """For `print` and `pprint`"""
        return self.to_str()

    def __eq__(self, other):
        """Returns true if both objects are equal"""
        if not isinstance(other, OutputTypes):
            return False

        return self.__dict__ == other.__dict__

    def __ne__(self, other):
        """Returns true if both objects are not equal"""
        return not self == other


import threading

import wikipedia
from kivy.clock import mainthread
from kivymd.app import MDApp

class MainApp(MDApp):
    url = ""

    def build(self):
        self.title = "Wikipedia-App"

    @mainthread
    def search(self, text):
        t1 = threading.Thread(target=self.get_wiki, args=(text,), daemon=True)
        t1.start()

    def get_wiki(self, text):
        self.root.ids.rc_spin.active = True
        self.root.ids.summary.text = ""
        self.root.ids.title.text = ""

        wikipedia.set_lang("en")
        try:
            summary = wikipedia.page(text.strip())
            self.root.ids.title.text = summary.title
            self.root.ids.summary.text = f"\n{summary.summary}"
        except Exception as e:
            print(e)
            self.root.ids.title.text = (
                "[color=#EE4B2B]"
                + "Sorry unable to find "
                + self.root.ids.fld.text
                + "[/color]"
            )
        self.root.ids.rc_spin.active = False

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


# encoding: utf-8
"""
@author:  liaoxingyu
@contact: sherlockliao01@gmail.com
"""

import logging
import math
from collections import OrderedDict

import torch
from torch import nn
import torch.nn.functional as F
from torch.autograd.variable import Variable
from fastreid.modeling.ops import MetaConv2d, MetaLinear, MetaBNNorm, MetaINNorm, MetaIBNNorm, MetaGate

from fastreid.layers import (
    IBN,
    SELayer,
    Non_local,
    get_norm,
)
from fastreid.utils.checkpoint import get_missing_parameters_message, get_unexpected_parameters_message
from .build import BACKBONE_REGISTRY
from fastreid.utils import comm

K = 4
logger = logging.getLogger(__name__)
model_urls = {
    '18x': 'https://download.pytorch.org/models/resnet18-5c106cde.pth',
    '34x': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth',
    '50x': 'https://download.pytorch.org/models/resnet50-19c8e357.pth',
    '101x': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth',
    'ibn_18x': 'https://github.com/XingangPan/IBN-Net/releases/download/v1.0/resnet18_ibn_a-2f571257.pth',
    'ibn_34x': 'https://github.com/XingangPan/IBN-Net/releases/download/v1.0/resnet34_ibn_a-94bc1577.pth',
    'ibn_50x': 'https://github.com/XingangPan/IBN-Net/releases/download/v1.0/resnet50_ibn_a-d9d0bb7b.pth',
    'ibn_101x': 'https://github.com/XingangPan/IBN-Net/releases/download/v1.0/resnet101_ibn_a-59ea0ac6.pth',
    'se_ibn_101x': 'https://github.com/XingangPan/IBN-Net/releases/download/v1.0/se_resnet101_ibn_a-fabed4e2.pth',
}

def repackage_hidden(h):
    if type(h) == Variable:
        return Variable(h.data)
    else:
        return tuple(repackage_hidden(v) for v in h)

class Sequential_ext(nn.Module):
    """A Sequential container extended to also propagate the gating information
    that is needed in the target rate loss.
    """

    def __init__(self, *args):
        super(Sequential_ext, self).__init__()
        if len(args) == 1 and isinstance(args[0], OrderedDict):
            for key, module in args[0].items():
                self.add_module(key, module)
        else:
            for idx, module in enumerate(args):
                self.add_module(str(idx), module)

    def __getitem__(self, idx):
        if not (-len(self) <= idx < len(self)):
            raise IndexError('index {} is out of range'.format(idx))
        if idx < 0:
            idx += len(self)
        it = iter(self._modules.values())
        for i in range(idx):
            next(it)
        return next(it)

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

    def forward(self, input, opt=None):
        for i, module in enumerate(self._modules.values()):
            input = module(input, opt)
        return input

class BasicBlock(nn.Module):
    expansion = 1

    def __init__(self, inplanes, planes, bn_norm, with_ibn=False, with_se=False,
                 stride=1, downsample=None, reduction=16):
        super(BasicBlock, self).__init__()
        self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
        if with_ibn:
            self.bn1 = IBN(planes, bn_norm)
        else:
            self.bn1 = get_norm(bn_norm, planes)
        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn2 = get_norm(bn_norm, planes)
        self.relu = nn.ReLU(inplace=True)
        if with_se:
            self.se = SELayer(planes, reduction)
        else:
            self.se = nn.Identity()
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        identity = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)
        out = self.se(out)

        if self.downsample is not None:
            identity = self.downsample(x)

        out += identity
        out = self.relu(out)

        return out

class MetaSELayer(nn.Module):
    def __init__(self, channel, reduction=16):
        super(MetaSELayer, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.fc1 = MetaLinear(channel, int(channel / reduction), bias=False)
        self.relu = nn.ReLU()
        self.fc2 = MetaLinear(int(channel / reduction), channel, bias=False)
        self.sigmoid = nn.Sigmoid()

    def forward(self, x, opt=None):
        b, c, _, _ = x.size()
        y = self.avg_pool(x).view(b, c)
        y = self.relu(self.fc1(y, opt))
        y = self.sigmoid(self.fc2(y, opt)).view(b, c, 1, 1)

        return x * y.expand_as(x)

class Bottleneck2(nn.Module):
    expansion = 4*K

    def __init__(self, inplanes, planes, bn_norm, with_ibn=False, with_se=False,
                 stride=1, downsample=None, reduction=16):
        super(Bottleneck2, self).__init__()
        self.conv1 = MetaConv2d(inplanes * K, planes, kernel_size=1, bias=False, groups=K)
        if with_ibn:
            self.bn1 = MetaIBNNorm(planes)
        else:
            self.bn1 = MetaBNNorm(planes)
        self.conv2 = MetaConv2d(planes, planes, kernel_size=3, stride=stride,
                            padding=1, bias=False, groups=K)
        self.bn2 = MetaBNNorm(planes)
        self.conv3 = MetaConv2d(planes, planes * self.expansion, kernel_size=1, bias=False, groups=K)
        self.bn3 = MetaBNNorm(planes * self.expansion)

        self.relu = nn.ReLU(inplace=True)
        if with_se:
            self.se = SELayer(planes * self.expansion, reduction)
        else:
            self.se = nn.Identity()
        self.downsample = downsample
        self.stride = stride

    def forward(self, x, opt=None):

        residual = x

        out = self.conv1(x, opt)
        out = self.bn1(out, opt)
        out = self.relu(out)

        out = self.conv2(out, opt)
        out = self.bn2(out, opt)
        out = self.relu(out)

        out = self.conv3(out, opt)
        out = self.bn3(out, opt)
        out = self.se(out)

        if self.downsample is not None:
            residual = self.downsample(x, opt)

        out += residual
        out = self.relu(out)

        return out

class Bottleneck(nn.Module):
    expansion = 4

    def __init__(self, inplanes, planes, bn_norm, with_ibn=False, with_se=False,
                 stride=1, downsample=None, reduction=16):
        super(Bottleneck, self).__init__()
        if bn_norm == 'IN':
            norm = MetaINNorm
        else:
            norm = MetaBNNorm
        self.conv1 = MetaConv2d(inplanes, planes, kernel_size=1, bias=False)
        if with_ibn:
            self.bn1 = MetaIBNNorm(planes)
        else:
            self.bn1 = norm(planes)
        self.conv2 = MetaConv2d(planes, planes, kernel_size=3, stride=stride,
                            padding=1, bias=False)
        self.bn2 = norm(planes)
        self.conv3 = MetaConv2d(planes, planes * self.expansion, kernel_size=1, bias=False)
        self.bn3 = norm(planes * self.expansion)
        self.relu = nn.ReLU(inplace=True)
        if with_se:
            self.se = SELayer(planes * self.expansion, reduction)
        else:
            self.se = nn.Identity()
        self.downsample = downsample
        self.stride = stride

    def forward(self, x, opt=None):
        residual = x

        out = self.conv1(x, opt)
        out = self.bn1(out, opt)
        out = self.relu(out)

        out = self.conv2(out, opt)
        out = self.bn2(out, opt)
        out = self.relu(out)

        out = self.conv3(out, opt)
        out = self.bn3(out, opt)
        out = self.se(out)

        if self.downsample is not None:
            residual = self.downsample(x, opt)

        out += residual
        out = self.relu(out)

        return out

class Identity(nn.Module):
    def __init__(self):
        super(Identity, self).__init__()

    def forward(self, x):
        return x, None

class HyperRouter(nn.Module):
    def __init__(self, planes):
        super().__init__()
        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
        self.planes = planes
        self.fc1 = MetaLinear(planes, planes//16)
        self.fc2 = MetaLinear(planes//16, planes*K)
        self.fc_classifier = MetaLinear(planes*K, 3)
        self.relu = nn.ReLU()
        self.softmax = nn.Softmax(-1)

    def forward(self, x, opt=None):

        x = self.avgpool(x).squeeze(-1).squeeze(-1)

        weight = self.relu(F.normalize(self.fc1(x, opt), 2, -1))
        weight = self.fc2(weight, opt).reshape(-1, self.planes, K)
        domain_cls_logits = self.fc_classifier(weight.reshape(-1, self.planes*K), opt)
        x = self.softmax(torch.einsum('bi,bil->bl', x, weight))

        return x, domain_cls_logits

class ResNet(nn.Module):
    def __init__(self, last_stride, bn_norm, with_ibn, with_se, with_nl, block, layers, non_layers):
        self.inplanes = 64
        super().__init__()
        self.conv1 = MetaConv2d(3, 64, kernel_size=7, stride=2, padding=3,
                               bias=False)
        self.bn1 = MetaBNNorm(64)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True)
        self.layer1 = self._make_layer(block, 64, layers[0]-1, 1, bn_norm, with_ibn, with_se)

        self.adaptor1_base = block(256, 64, 'IN', False, with_se)
        self.adaptor1_sub = Bottleneck2(256, 64, bn_norm, with_ibn, with_se)
        self.router1 = HyperRouter(256)
        self.invariant_norm1 = MetaBNNorm(256)
        self.specific_norm1 = MetaBNNorm(256)
        self.meta_fuse1 = MetaGate(256)
        self.meta_se1 = MetaSELayer(256)
        self.map1 = MetaBNNorm(256, bias_freeze=True)

        self.layer2 = self._make_layer(block, 128, layers[1]-1, 2, bn_norm, with_ibn, with_se)

        self.adaptor2_base = block(512, 128, 'IN', False, with_se)
        self.adaptor2_sub = Bottleneck2(512, 128, bn_norm, with_ibn, with_se)
        self.router2 = HyperRouter(512)
        self.invariant_norm2 = MetaBNNorm(512)
        self.specific_norm2 = MetaBNNorm(512)
        self.meta_fuse2 = MetaGate(512)
        self.meta_se2 = MetaSELayer(512)
        self.map2 = MetaBNNorm(512, bias_freeze=True)

        self.layer3 = self._make_layer(block, 256, layers[2]-1, 2, bn_norm, with_ibn, with_se)

        self.adaptor3_base = block(1024, 256, 'IN', False, with_se)
        self.adaptor3_sub = Bottleneck2(1024, 256, bn_norm, with_ibn, with_se)
        self.router3 = HyperRouter(1024)
        self.invariant_norm3 = MetaBNNorm(1024)
        self.specific_norm3 = MetaBNNorm(1024)
        self.meta_fuse3 = MetaGate(1024)
        self.meta_se3 = MetaSELayer(1024)
        self.map3 = MetaBNNorm(1024, bias_freeze=True)

        self.layer4 = self._make_layer(block, 512, layers[3]-1, last_stride, bn_norm, with_se=with_se)

        self.adaptor4_base = block(2048, 512, 'IN', False, with_se)
        self.adaptor4_sub = Bottleneck2(2048, 512, bn_norm, with_ibn, with_se)
        self.router4 = HyperRouter(2048)
        self.invariant_norm4 = MetaBNNorm(2048)
        self.specific_norm4 = MetaBNNorm(2048)
        self.meta_fuse4 = MetaGate(2048)
        self.meta_se4 = MetaSELayer(2048)
        self.map4 = MetaBNNorm(2048, bias_freeze=True)

        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))

        # Standard Params
        self.softmax = nn.Softmax(1)
        self.sigmoid = nn.Sigmoid()
        self.relu = nn.ReLU()

        self.random_init()

        # fmt: off
        if with_nl: self._build_nonlocal(layers, non_layers, bn_norm)
        else:       self.NL_1_idx = self.NL_2_idx = self.NL_3_idx = self.NL_4_idx = []
        # fmt: on

    def _make_layer(self, block, planes, blocks, stride=1, bn_norm="BN", with_ibn=False, with_se=False):
        downsample = None
        if stride != 1 or self.inplanes != planes * block.expansion:
            downsample = Sequential_ext(
                MetaConv2d(self.inplanes, planes * block.expansion,
                          kernel_size=1, stride=stride, bias=False),
                MetaBNNorm(planes * block.expansion),
            )

        layers = []
        layers.append(block(self.inplanes, planes, bn_norm, with_ibn, with_se, stride, downsample))
        self.inplanes = planes * block.expansion
        for i in range(1, blocks):
            layers.append(block(self.inplanes, planes, bn_norm, with_ibn, with_se))

        return nn.Sequential(*layers)

    def _build_nonlocal(self, layers, non_layers, bn_norm):
        self.NL_1 = nn.ModuleList(
            [Non_local(256, bn_norm) for _ in range(non_layers[0])])
        self.NL_1_idx = sorted([layers[0] - (i + 1) for i in range(non_layers[0])])
        self.NL_2 = nn.ModuleList(
            [Non_local(512, bn_norm) for _ in range(non_layers[1])])
        self.NL_2_idx = sorted([layers[1] - (i + 1) for i in range(non_layers[1])])
        self.NL_3 = nn.ModuleList(
            [Non_local(1024, bn_norm) for _ in range(non_layers[2])])
        self.NL_3_idx = sorted([layers[2] - (i + 1) for i in range(non_layers[2])])
        self.NL_4 = nn.ModuleList(
            [Non_local(2048, bn_norm) for _ in range(non_layers[3])])
        self.NL_4_idx = sorted([layers[3] - (i + 1) for i in range(non_layers[3])])

    def get_all_conv_layers(self, module):
        for m in module:
            if isinstance(m, Bottleneck):
                for _m in m.modules():
                    if isinstance(_m, nn.Conv2d):
                        yield _m

    def forward(self, x, epoch, opt=None):

        x = self.conv1(x, opt)
        x = self.bn1(x, opt)
        x = self.relu(x)
        x = self.maxpool(x)

        weights = []
        out_features = []

        # layer 1
        NL1_counter = 0
        if len(self.NL_1_idx) == 0:
            self.NL_1_idx = [-1]
        for i in range(len(self.layer1)):
            x = self.layer1[i](x, opt)
            if i == self.NL_1_idx[NL1_counter]:
                _, C, H, W = x.shape
                x = self.NL_1[NL1_counter](x)
                NL1_counter += 1

        x_invariant = self.adaptor1_base(x, opt)
        N, C, H, W = x_invariant.shape
        x_specific = self.adaptor1_sub(x.repeat(1, K, 1, 1), opt).reshape(N, K, C, H, W)
        weight, domain_cls_logit = self.router1(x, opt)
        weights.append(weight)
        x_specific = (x_specific * weight.reshape(-1, K, 1, 1, 1)).sum(1)
        x_invariant = self.invariant_norm1(x_invariant, opt)
        x_specific = self.specific_norm1(x_specific, opt)
        x = self.meta_fuse1(x_invariant, x_specific, opt)
        x = self.meta_se1(x, opt)
        temp = self.map1(self.avgpool(x), opt)
        out_features.append(F.normalize(temp, 2, 1)[..., 0, 0])

        # layer 2
        NL2_counter = 0
        if len(self.NL_2_idx) == 0:
            self.NL_2_idx = [-1]
        for i in range(len(self.layer2)):
            x = self.layer2[i](x, opt)
            if i == self.NL_2_idx[NL2_counter]:
                _, C, H, W = x.shape
                x = self.NL_2[NL2_counter](x)
                NL2_counter += 1

        x_invariant = self.adaptor2_base(x, opt)
        N, C, H, W = x_invariant.shape
        x_specific = self.adaptor2_sub(x.repeat(1, K, 1, 1), opt).reshape(N, K, C, H, W)
        weight, domain_cls_logit = self.router2(x, opt)
        weights.append(weight)
        x_specific = (x_specific * weight.reshape(-1, K, 1, 1, 1)).sum(1)
        x_invariant = self.invariant_norm2(x_invariant, opt)
        x_specific = self.specific_norm2(x_specific, opt)
        x = self.meta_fuse2(x_invariant, x_specific, opt)
        x = self.meta_se2(x, opt)
        temp = self.map2(self.avgpool(x), opt)
        out_features.append(F.normalize(temp, 2, 1)[..., 0, 0])

        # layer 3
        NL3_counter = 0
        if len(self.NL_3_idx) == 0:
            self.NL_3_idx = [-1]
        for i in range(len(self.layer3)):
            x = self.layer3[i](x, opt)
            if i == self.NL_3_idx[NL3_counter]:
                _, C, H, W = x.shape
                x = self.NL_3[NL3_counter](x)
                NL3_counter += 1

        x_invariant = self.adaptor3_base(x, opt)
        N, C, H, W = x_invariant.shape
        x_specific = self.adaptor3_sub(x.repeat(1, K, 1, 1), opt).reshape(N, K, C, H, W)
        weight, domain_cls_logit = self.router3(x, opt)
        weights.append(weight)
        x_specific = (x_specific * weight.reshape(-1, K, 1, 1, 1)).sum(1)
        x_invariant = self.invariant_norm3(x_invariant, opt)
        x_specific = self.specific_norm3(x_specific, opt)
        x = self.meta_fuse3(x_invariant, x_specific, opt)
        x = self.meta_se3(x, opt)
        temp = self.map3(self.avgpool(x), opt)
        out_features.append(F.normalize(temp, 2, 1)[..., 0, 0])

        # layer 4
        NL4_counter = 0
        if len(self.NL_4_idx) == 0:
            self.NL_4_idx = [-1]
        for i in range(len(self.layer4)):
            x = self.layer4[i](x, opt)
            if i == self.NL_4_idx[NL4_counter]:
                _, C, H, W = x.shape
                x = self.NL_4[NL4_counter](x)
                NL4_counter += 1

        x_invariant = self.adaptor4_base(x, opt)
        N, C, H, W = x_invariant.shape
        x_specific = self.adaptor4_sub(x.repeat(1, K, 1, 1), opt).reshape(N, K, C, H, W)
        weight, domain_cls_logit = self.router4(x, opt)
        weights.append(weight)
        x_specific = (x_specific * weight.reshape(-1, K, 1, 1, 1)).sum(1)
        x_invariant = self.invariant_norm4(x_invariant, opt)
        x_specific = self.specific_norm4(x_specific, opt)
        x = self.meta_fuse4(x_invariant, x_specific, opt)
        x = self.meta_se4(x, opt)
        temp = self.map4(self.avgpool(x), opt)
        out_features.append(F.normalize(temp, 2, 1)[..., 0, 0])

        weights = torch.cat(weights, -1)

        return x, weights, out_features

    def random_init(self):
        for name, m in self.named_modules():
            if isinstance(m, MetaConv2d):
                n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
                nn.init.normal_(m.weight, 0, math.sqrt(2. / n))
            elif isinstance(m, nn.BatchNorm2d):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)

def init_pretrained_weights(key):
    """Initializes model with pretrained weights.

    Layers that don't match with pretrained layers in name or size are kept unchanged.
    """
    import os
    import errno
    import gdown

    def _get_torch_home():
        ENV_TORCH_HOME = 'TORCH_HOME'
        ENV_XDG_CACHE_HOME = 'XDG_CACHE_HOME'
        DEFAULT_CACHE_DIR = '~/.cache'
        torch_home = os.path.expanduser(
            os.getenv(
                ENV_TORCH_HOME,
                os.path.join(
                    os.getenv(ENV_XDG_CACHE_HOME, DEFAULT_CACHE_DIR), 'torch'
                )
            )
        )
        return torch_home

    torch_home = _get_torch_home()
    model_dir = os.path.join(torch_home, 'checkpoints')
    try:
        os.makedirs(model_dir)
    except OSError as e:
        if e.errno == errno.EEXIST:
            # Directory already exists, ignore.
            pass
        else:
            # Unexpected OSError, re-raise.
            raise

    filename = model_urls[key].split('/')[-1]

    cached_file = os.path.join(model_dir, filename)

    if not os.path.exists(cached_file):
        logger.info(f"Pretrain model don't exist, downloading from {model_urls[key]}")
        if comm.is_main_process():
            gdown.download(model_urls[key], cached_file, quiet=False)

    comm.synchronize()

    logger.info(f"Loading pretrained model from {cached_file}")
    state_dict = torch.load(cached_file, map_location=torch.device('cpu'))
    #CHANGE Reduction Version
    state_dict = torch.load('/home/pengyi/.cache/torch/checkpoints/resnet50_ibn_a-d9d0bb7b.pth', map_location=torch.device('cpu'))

    return state_dict

@BACKBONE_REGISTRY.register()
def build_meta_dynamic_router_resnet_backbone(cfg):
    """
    Create a ResNet instance from config.
    Returns:
        ResNet: a :class:`ResNet` instance.
    """

    # fmt: off
    pretrain      = cfg.MODEL.BACKBONE.PRETRAIN
    pretrain_path = cfg.MODEL.BACKBONE.PRETRAIN_PATH
    last_stride   = cfg.MODEL.BACKBONE.LAST_STRIDE
    bn_norm       = cfg.MODEL.BACKBONE.NORM
    with_ibn      = cfg.MODEL.BACKBONE.WITH_IBN
    with_se       = cfg.MODEL.BACKBONE.WITH_SE
    with_nl       = cfg.MODEL.BACKBONE.WITH_NL
    depth         = cfg.MODEL.BACKBONE.DEPTH
    # fmt: on

    num_blocks_per_stage = {
        '18x': [2, 2, 2, 2],
        '34x': [3, 4, 6, 3],
        '50x': [3, 4, 6, 3],
        '101x': [3, 4, 23, 3],
    }[depth]

    nl_layers_per_stage = {
        '18x': [0, 0, 0, 0],
        '34x': [0, 0, 0, 0],
        '50x': [0, 2, 3, 0],
        '101x': [0, 2, 9, 0]
    }[depth]

    block = {
        '18x': BasicBlock,
        '34x': BasicBlock,
        '50x': Bottleneck,
        '101x': Bottleneck
    }[depth]

    model = ResNet(last_stride, bn_norm, with_ibn, with_se, with_nl, block,
                   num_blocks_per_stage, nl_layers_per_stage)
    if pretrain:
        # Load pretrain path if specifically
        if pretrain_path:
            try:
                state_dict = torch.load(pretrain_path, map_location=torch.device('cpu'))
                logger.info(f"Loading pretrained model from {pretrain_path}")
            except FileNotFoundError as e:
                logger.info(f'{pretrain_path} is not found! Please check this path.')
                raise e
            except KeyError as e:
                logger.info("State dict keys error! Please check the state dict.")
                raise e
        else:
            key = depth
            if with_ibn: key = 'ibn_' + key
            # if with_se:  key = 'se_' + key

            state_dict = init_pretrained_weights(key)

        model_dict = model.state_dict()

        for k in model_dict.keys():
            if k in state_dict:
                v = state_dict[k]
                if model_dict[k].shape == v.shape:
                    model_dict[k] = v
                else:
                    if len(v.shape) == 1:
                        model_dict[k] = v[:model_dict[k].shape[0]]
                    elif len(v.shape) == 2:
                        model_dict[k] = v[:model_dict[k].shape[0], :model_dict[k].shape[1]]
                    elif len(v.shape) == 3:
                        model_dict[k] = v[:model_dict[k].shape[0], :model_dict[k].shape[1], :model_dict[k].shape[2]]
                    elif len(v.shape) == 4:
                        model_dict[k] = v[:model_dict[k].shape[0], :model_dict[k].shape[1], :model_dict[k].shape[2], :model_dict[k].shape[3]]
                    elif len(v.shape) == 5:
                        model_dict[k] = v[:model_dict[k].shape[0], :model_dict[k].shape[1], :model_dict[k].shape[2], :model_dict[k].shape[3], :model_dict[k].shape[4]]
                    else:
                        raise Exception
            else:
                try:
                    if 'adaptor1_base' in k:
                        if model_dict[k].shape == state_dict['layer1.2'+k[13:]].shape:
                            model_dict[k] = state_dict['layer1.2'+k[13:]]
                            print('Done, adaptor', k)
                        else:
                            print('Skip, adaptor', k)
                    elif 'adaptor1_sub' in k:
                        if 'conv3' in k:
                            v = state_dict['layer1.2'+k[12:]]
                            Cout, Cin, H, W = v.shape
                            model_dict[k] = F.avg_pool1d(v.permute(0, 2, 3, 1).reshape(Cout, H*W, Cin), kernel_size=K).reshape(Cout, H, W, -1).permute(0, 3, 1, 2).repeat(K, 1, 1, 1)
                        elif 'bn3' in k:
                            v = state_dict['layer1.2'+k[12:]]
                            model_dict[k] = v.repeat(K)
                        elif model_dict[k].shape == state_dict['layer1.2'+k[12:]].shape:
                            model_dict[k] = state_dict['layer1.2'+k[12:]]
                        else:
                            v = state_dict['layer1.2'+k[12:]]
                            Cout, Cin, H, W = v.shape
                            model_dict[k] = F.avg_pool1d(v.permute(0, 2, 3, 1).reshape(Cout, H*W, Cin), kernel_size=K).reshape(Cout, H, W, -1).permute(0, 3, 1, 2)
                        print('Done, adaptor', k)
                    elif 'adaptor2_base' in k:
                        if model_dict[k].shape == state_dict['layer2.3'+k[13:]].shape:
                            model_dict[k] = state_dict['layer2.3'+k[13:]]
                            print('Done, adaptor', k)
                        else:
                            print('Skip, adaptor', k)
                    elif 'adaptor2_sub' in k:
                        if 'conv3' in k:
                            v = state_dict['layer2.3'+k[12:]]
                            Cout, Cin, H, W = v.shape
                            model_dict[k] = F.avg_pool1d(v.permute(0, 2, 3, 1).reshape(Cout, H*W, Cin), kernel_size=K).reshape(Cout, H, W, -1).permute(0, 3, 1, 2).repeat(K, 1, 1, 1)
                        elif 'bn3' in k:
                            v = state_dict['layer2.3'+k[12:]]
                            model_dict[k] = v.repeat(K)
                        elif model_dict[k].shape == state_dict['layer2.3'+k[12:]].shape:
                            model_dict[k] = state_dict['layer2.3'+k[12:]]
                        else:
                            v = state_dict['layer2.3'+k[12:]]
                            Cout, Cin, H, W = v.shape
                            model_dict[k] = F.avg_pool1d(v.permute(0, 2, 3, 1).reshape(Cout, H*W, Cin), kernel_size=K).reshape(Cout, H, W, -1).permute(0, 3, 1, 2)
                        print('Done, adaptor', k)

                    elif 'adaptor3_base' in k:
                        if model_dict[k].shape == state_dict['layer3.5'+k[13:]].shape:
                            model_dict[k] = state_dict['layer3.5'+k[13:]]
                            print('Done, adaptor', k)
                        else:
                            print('Skip, adaptor', k)
                    elif 'adaptor3_sub' in k:
                        if 'conv3' in k:
                            v = state_dict['layer3.5'+k[12:]]
                            Cout, Cin, H, W = v.shape
                            model_dict[k] = F.avg_pool1d(v.permute(0, 2, 3, 1).reshape(Cout, H*W, Cin), kernel_size=K).reshape(Cout, H, W, -1).permute(0, 3, 1, 2).repeat(K, 1, 1, 1)
                        elif 'bn3' in k:
                            v = state_dict['layer3.5'+k[12:]]
                            model_dict[k] = v.repeat(K)
                        elif model_dict[k].shape == state_dict['layer3.5'+k[12:]].shape:
                            model_dict[k] = state_dict['layer3.5'+k[12:]]
                        else:
                            v = state_dict['layer3.5'+k[12:]]
                            Cout, Cin, H, W = v.shape
                            model_dict[k] = F.avg_pool1d(v.permute(0, 2, 3, 1).reshape(Cout, H*W, Cin), kernel_size=K).reshape(Cout, H, W, -1).permute(0, 3, 1, 2)
                        print('Done, adaptor', k)

                    elif 'adaptor4_base' in k:
                        if model_dict[k].shape == state_dict['layer4.2'+k[13:]].shape:
                            model_dict[k] = state_dict['layer4.2'+k[13:]]
                            print('Done, adaptor', k)
                        else:
                            print('Skip, adaptor', k)
                    elif 'adaptor4_sub' in k:
                        if 'conv3' in k:
                            v = state_dict['layer4.2'+k[12:]]
                            Cout, Cin, H, W = v.shape
                            model_dict[k] = F.avg_pool1d(v.permute(0, 2, 3, 1).reshape(Cout, H*W, Cin), kernel_size=K).reshape(Cout, H, W, -1).permute(0, 3, 1, 2).repeat(K, 1, 1, 1)
                        elif 'bn3' in k:
                            v = state_dict['layer4.2'+k[12:]]
                            model_dict[k] = v.repeat(K)
                        elif 'bn1' in k:
                            if 'IN' in k:
                                model_dict[k] = state_dict['layer4.2.bn1.'+k.split('.')[-1]][:256]
                            else:
                                model_dict[k] = state_dict['layer4.2.bn1.'+k.split('.')[-1]][256:]
                        elif model_dict[k].shape == state_dict['layer4.2'+k[12:]].shape:
                            model_dict[k] = state_dict['layer4.2'+k[12:]]
                        else:
                            v = state_dict['layer4.2'+k[12:]]
                            Cout, Cin, H, W = v.shape
                            model_dict[k] = F.avg_pool1d(v.permute(0, 2, 3, 1).reshape(Cout, H*W, Cin), kernel_size=K).reshape(Cout, H, W, -1).permute(0, 3, 1, 2)
                        print('Done, adaptor', k)

                except Exception:
                    pass
        incompatible = model.load_state_dict(model_dict, strict=False)
        if incompatible.missing_keys:
            logger.info(
                get_missing_parameters_message(incompatible.missing_keys)
            )
        if incompatible.unexpected_keys:
            logger.info(
                get_unexpected_parameters_message(incompatible.unexpected_keys)
            )

    return model


import h5py
import os
from torch.utils.data import Dataset
from DVS_dataload.my_transforms import *
from PIL import Image
import torch
import numpy as np

class DVSGestureDataset(Dataset):
    def __init__(self, root, train=True, transform=None):
        super(DVSGestureDataset, self).__init__()
        self.n = 0
        self.root = root
        self.train = train
        self.transform = transform

        if train:
            root_train = os.path.join(self.root, 'DvsGesture_train_40step_downsample')
            for _, _, self.files_train in os.walk(root_train):
                pass
            self.n = len(self.files_train)
        else:
            root_test = os.path.join(self.root, 'DvsGesture_test_40step_downsample')
            for _, _, self.files_test in os.walk(root_test):
                pass
            self.n = len(self.files_test)

    def __len__(self):
        return self.n

    def __getitem__(self, idx):
        if self.train:
            root_test = os.path.join(self.root, 'DvsGesture_train_40step_downsample')

            with h5py.File(root_test + os.sep + self.files_train[idx], 'r', swmr=True, libver="latest") as f:
                target = f['label'][()]
                data = f['data'][()]
            if self.transform is not None:
                data = self.transform(data)

            return data, target
        else:
            root_test = os.path.join(self.root, 'DvsGesture_test_40step_downsample')

            with h5py.File(root_test + os.sep + self.files_test[idx], 'r', swmr=True, libver="latest") as f:
                target = f['label'][()]
                data = f['data'][()]
            if self.transform is not None:
                data = self.transform(data)

            return data, target


import os
import cv2
import shutil

source_path = 'test_copy_image'
des_path = 'train_image_label'

def get_all_label_file_to_image_file():
    list_file = os.listdir(source_path)
    list_label = [file for file in list_file if file.endswith('.txt')]
    return list_label

def copy_image_according_to_label():
    label_name = get_all_label_file_to_image_file()
    print('There are {} label files'.format(len(label_name)))
    print(label_name)

    # copy files
    for name in label_name:
        # copy text file
        orig_label = os.path.join(source_path, name)
        des_label = os.path.join(des_path, name)
        print(des_label)
        shutil.copy(orig_label, des_label)

        # copy image file
        img_name = name.split('.')[0] + '.jpg'
        orig_img = os.path.join(source_path, img_name)
        #print(origin)
        des_img = os.path.join(des_path, img_name)
        #print(des)
        img = cv2.imread(orig_img)
        cv2.imwrite(des_img, img)

copy_image_according_to_label()


#!/usr/bin/env python3
"""
Cache class. In the __init__ method, store an instance of the Redis }
client as a private variable named _redis (using redis.Redis()) and
flush the instance using flushdb.

"""

import redis
from typing import Union, Optional, Callable
from uuid import uuid4
from functools import wraps

def count_calls(method: Callable) -> Callable:
    """
    count how many times the function was called
    """

    key = method.__qualname__

    @wraps(method)
    def wrapper(self, *args, **kwargs):
        """ Wrapper for decorator functionality """
        self._redis.incr(key)
        return method(self, *args, **kwargs)

    return wrapper

def call_history(method: Callable) -> Callable:
    """
        store the history of inputs and outputs for a particular function.
    """

    inputs = '{}:inputs'.format(method.__qualname__)
    outputs = '{}:outputs'.format(method.__qualname__)

    @wraps(method)
    def wrapper(self, *args, **kwds):
        """wrapper function"""

        self._redis.rpush(inputs, str(args))
        output = method(self, *args, **kwds)
        self._redis.rpush(outputs, output)
        return output
    return wrapper

def replay(methodName: Callable) -> None:
    """
    Display the history of calls of a function
    """

    _redis = redis.Redis()
    try:
        calls = _redis.get(methodName.__qualname__).decode('utf-8')
    except Exception:
        calls = 0

    print(f'{methodName.__qualname__} was called {calls} times:')

    inputs = _redis.lrange(methodName.__qualname__ + ':inputs', 0, -1)
    outputs = _redis.lrange(methodName.__qualname__ + ':outputs', 0, -1)

    for input, output in zip(inputs, outputs):
        print('{}(*{}) -> {}'.format(methodName.__qualname__,
                                     input.decode('utf-8'),
                                     output.decode('utf-8')))

class Cache():
    """
    Main class for cache
    """
    def __init__(self):
        """ CONSTRUCTOR"""
        self._redis = redis.Redis()
        self._redis.flushdb()

    @call_history
    @count_calls
    def store(self, data: Union[str, bytes, int, float]) -> str:
        """
        Takes a data as argumen a store in a REDIS db
        Remember that data can be a str, bytes, int or float.

        Returns: A key in string format
        """
        _randomkey = uuid4().__str__()
        self._redis.set(_randomkey, data)
        return _randomkey

    def get(self, key: str,
            fn: Optional[Callable] = None) -> Union[str, bytes, int, float]:
        """  Get the values as specific func"""
        data = self._redis.get(key)
        if fn:
            return fn(data)
        return data

    def get_int(self, data: int) -> int:
        """  Get the values as int" """
        try:
            int(data)
            return data
        except Exception:
            return 0

    def get_str(self, data: str) -> str:
        """  Get the values as str"""
        return self._redis.get(data).decode('utf_8')


#!/usr/bin/env python3

__requires__ = '''
plover>=4.0.0.dev2
setuptools>=30.3.0
'''

from setuptools import setup

from plover_build_utils.setup import BuildPy, BuildUi

BuildPy.build_dependencies.append('build_ui')
BuildUi.hooks = ['plover_build_utils.pyqt:fix_icons']
cmdclass = {
    'build_py': BuildPy,
    'build_ui': BuildUi,
}

setup(cmdclass=cmdclass)


# -*- coding: utf-8 -*-
"""
# @file name  : target.py
# @author     : chenzhanpeng https://github.com/chenzpstar
# @date       : 2022-01-09
# @brief      : FCOS训练目标类
"""

import torch
import torch.nn as nn

from models.config import FCOSConfig
from models.utils import coords2centers, coords2offsets, decode_coords, reshape_feat

class FCOSTarget(nn.Module):
    def __init__(self, cfg=None):
        super(FCOSTarget, self).__init__()
        if cfg is None:
            self.cfg = FCOSConfig
        else:
            self.cfg = cfg

        self.strides = self.cfg.strides
        self.ranges = self.cfg.ranges
        assert len(self.strides) == len(self.ranges)

    def forward(self, feats, labels, boxes):
        stages_num = len(self.strides)
        assert len(feats) == stages_num

        cls_targets = []
        reg_targets = []
        ctr_targets = []

        for i in range(stages_num):
            stage_targets = self._gen_stage_targets(
                feats[i],
                labels,
                boxes,
                self.strides[i],
                self.ranges[i],
            )
            cls_targets.append(stage_targets[0])
            reg_targets.append(stage_targets[1])
            ctr_targets.append(stage_targets[2])

        return cls_targets, reg_targets, ctr_targets

    def _gen_stage_targets(self,
                           feat,
                           labels,
                           boxes,
                           stride,
                           range,
                           sample_radio=1.5):
        coords = decode_coords(feat, stride).to(device=boxes.device)
        feat = reshape_feat(feat)  # bchw -> b(hw)c

        batch_size, hw = feat.shape[:2]  # b(hw)c
        boxes_num = boxes.shape[1]  # bnc

        # 1.计算每个坐标到所有标注框四边的偏移量
        offsets = coords2offsets(coords, boxes)
        assert offsets.shape == (batch_size, hw, boxes_num, 4)

        offsets_min = offsets.min(dim=-1)[0]
        offsets_max = offsets.max(dim=-1)[0]
        boxes_mask = offsets_min > 0
        stage_mask = (offsets_max > range[0]) & (offsets_max <= range[1])

        # 2.计算每个坐标到所有标注框中心的偏移量
        ctr_offsets = coords2centers(coords, boxes)
        assert ctr_offsets.shape == (batch_size, hw, boxes_num, 4)

        radius = sample_radio * stride
        ctr_offsets_max = ctr_offsets.max(dim=-1)[0]
        ctr_mask = ctr_offsets_max <= radius

        pos_mask = boxes_mask & stage_mask & ctr_mask
        assert pos_mask.shape == (batch_size, hw, boxes_num)

        # 3.计算所有标注框面积
        areas = (offsets[..., 0] + offsets[..., 2]) * (offsets[..., 1] +
                                                       offsets[..., 3])
        areas[~pos_mask] = 999999  # neg_areas
        areas_min_idx = areas.min(dim=-1)[1].unsqueeze(dim=-1)
        areas_min_mask = torch.zeros_like(areas, dtype=torch.bool).scatter(
            -1, areas_min_idx, 1)
        assert areas_min_mask.shape == (batch_size, hw, boxes_num)

        # 4.计算分类目标
        labels = torch.broadcast_tensors(
            labels[:, None, :], areas.long())[0]  # [b,1,n] -> [b,h*w,n]
        cls_targets = labels[areas_min_mask].reshape((batch_size, -1, 1))
        assert cls_targets.shape == (batch_size, hw, 1)

        # 5.计算回归目标
        offsets = offsets / stride
        reg_targets = offsets[areas_min_mask].reshape((batch_size, -1, 4))
        assert reg_targets.shape == (batch_size, hw, 4)

        # 6.计算中心度目标
        lr_min = torch.min(reg_targets[..., 0], reg_targets[..., 2])
        lr_max = torch.max(reg_targets[..., 0], reg_targets[..., 2])
        tb_min = torch.min(reg_targets[..., 1], reg_targets[..., 3])
        tb_max = torch.max(reg_targets[..., 1], reg_targets[..., 3])
        ctr_targets = ((lr_min * tb_min) /
                       (lr_max * tb_max).clamp(min=1e-10)).sqrt().unsqueeze(
                           dim=-1)
        assert ctr_targets.shape == (batch_size, hw, 1)

        # 7.处理负样本
        pos_mask = pos_mask.long().sum(dim=-1)
        pos_mask = pos_mask >= 1
        assert pos_mask.shape == (batch_size, hw)

        cls_targets[~pos_mask] = 0
        reg_targets[~pos_mask] = -1
        ctr_targets[~pos_mask] = -1

        return cls_targets, reg_targets, ctr_targets

if __name__ == "__main__":

    import torch
    torch.manual_seed(0)

    model = FCOSTarget()

    preds = (
        [torch.rand(2, 3, 2, 2)] * 5,
        [torch.rand(2, 4, 2, 2)] * 5,
        [torch.rand(2, 1, 2, 2)] * 5,
    )
    labels = torch.rand(2, 3)
    boxes = torch.rand(2, 3, 4)

    out = model(preds[0], labels, boxes)
    [print(stage_out.shape) for branch_out in out for stage_out in branch_out]


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Oct 31 11:56:58 2019

@author: saransh
"""

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans,AgglomerativeClustering,DBSCAN
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
from sklearn import metrics
from scipy.optimize import linear_sum_assignment

def purity_score(y_true, y_pred):
    contingency_matrix = metrics.cluster.contingency_matrix(y_true, y_pred)
    row_ind, col_ind = linear_sum_assignment(-contingency_matrix)
    return contingency_matrix[row_ind, col_ind].sum() / np.sum(contingency_matrix)

csv = pd.read_csv("Iris.csv")
datay = csv["Species"]
data = csv.drop(columns = ["Species"],axis = 1)
#pca = PCA(n_components=2).fit(data)
data = PCA(n_components=2).fit_transform(data)
data=pd.DataFrame(data)
print("_________________")
print(" ")
print("2D-Points After Reducing Dimensions ")
print("_________________")
plt.scatter(data.iloc[:,0],data.iloc[:,1],color="blue")
plt.show()

Kmean = KMeans(n_clusters=3)
labels = Kmean.fit_predict(data)
#labels = Kmean.predict(data)
print("_________________")
print(" ")
print("KMeans Clustering")
print("_________________")
plt.scatter(data.iloc[:,0],data.iloc[:,1],c=Kmean.labels_,cmap='viridis')
centers=Kmean.cluster_centers_
plt.scatter(centers[:,0],centers[:,1],s=100,c='black')
plt.show()
print("purity score for KMeans Clustering is -")
print(purity_score(pd.DataFrame(datay),pd.DataFrame(labels)))
print("_________________")

print(" ")
print(" ")
print(" ")

print("_________________")
print(" ")
print("Agglomerative Clustering")
print("_________________")
cluster = AgglomerativeClustering(n_clusters=3, affinity='euclidean', linkage='average')
labelag=cluster.fit_predict(data)
plt.scatter(data.iloc[:,0],data.iloc[:,1], c=cluster.labels_, cmap='rainbow')
plt.show()
'''
Kmean.fit(data)
labels = Kmean.predict(data)
print("_________________")
print(" ")
print("KMeans Clustering")
print("_________________")
plt.scatter(data.iloc[:,0],data.iloc[:,1],c=labels,cmap='viridis')
centers=Kmean.cluster_centers_
plt.scatter(centers[:,0],centers[:,1],s=100,c='black')
plt.show()
print("purity score for KMeans Clustering is -")
print(purity_score(pd.DataFrame(datay),pd.DataFrame(labels)))
print("_________________")

plt.show()
'''
print("purity score for Agglomerative Clustering is -")
print(purity_score(pd.DataFrame(datay),pd.DataFrame(labelag)))
print("_________________")

print(" ")

print(" ")

print("_________________")
print(" ")
print("DBSCAN")
print("_________________")

epsp=[0.05,0.5,0.95]
min_samplesp=[1,5,10,20]
ps=[]
arr = []
for i in epsp:
    for j in min_samplesp:
        db = DBSCAN(eps = i, min_samples = j)
        arr.append([i,j])
        labels1 = db.fit_predict(data)
        ps.append([purity_score(pd.DataFrame(datay),pd.DataFrame(labels1)),i,j])
psmax=max(ps)
ind = ps.index(psmax)
print('for eps = 0.05 and minpts = 1')
db = DBSCAN(eps = 0.05, min_samples = 1).fit(data)
labels1 = db.labels_
plt.scatter(data.iloc[:,0],data.iloc[:,1], c=db.labels_)
plt.show()

db = DBSCAN(eps = arr[ind][0], min_samples = arr[ind][1]).fit(data)
labels1 = db.labels_
plt.scatter(data.iloc[:,0],data.iloc[:,1], c=db.labels_, cmap='rainbow')
plt.show()

print("purity score for DBSAN is -")
print(purity_score(pd.DataFrame(datay),pd.DataFrame(labels1)))
print("_________________")


from PyQt4.QtGui import QApplication, QFrame, QPalette, QLabel, QPixmap
from PyQt4.QtCore import Qt, QRect, QCoreApplication

class BareFrame(QFrame):

    def __init__(self, parent=None):
        super(BareFrame, self).__init__(parent)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setFrameShadow(QFrame.Plain)
        self.setFrameShape(QFrame.Box)
        self.setLineWidth(1)

    def setBGColor(self, color):
        pal = QCoreApplication.instance().palette()
        pal.setColor(QPalette.Window, color)
        self.setPalette(pal)

class CloseMark(QLabel):

    WIDTH  = 31
    HEIGHT = 31
    MARGIN = 10

    def __init__(self, pixmap, parent=None):
        super(CloseMark, self).__init__(parent)
        self.setPixmap(pixmap)
        self.toParentTopRight()

    def mousePressEvent(self, event):
        self.parent().close()

    def toParentTopRight(self):
        parent = self.parent()
        x = parent.width() - CloseMark.MARGIN - CloseMark.WIDTH
        y = CloseMark.MARGIN
        w = CloseMark.WIDTH
        h = CloseMark.HEIGHT
        self.setGeometry(QRect(x, y, w, h))

class Dashboard(BareFrame):

    SCALE  = .85

    def __init__(self, parent=None):
        from camelot.view.controls.busy_widget import BusyWidget
        from camelot.view.model_thread import get_model_thread
        super(Dashboard, self).__init__(parent)
        desktop = QCoreApplication.instance().desktop()
        self.resize(desktop.width() * Dashboard.SCALE, desktop.height() * Dashboard.SCALE)
        self.closemark = CloseMark(QPixmap('close-mark.png'), self)
        self.setBGColor(Qt.white)
        busy_widget = BusyWidget(self)
        busy_widget.setMinimumSize( desktop.width() * Dashboard.SCALE, desktop.height() * Dashboard.SCALE )
        #self.addPermanentWidget(busy_widget, 0)
        mt = get_model_thread()
        mt.thread_busy_signal.connect( busy_widget.set_busy )
        busy_widget.set_busy(mt.busy())

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    board = Dashboard()
    board.show()
    sys.exit(app.exec_())


import fcntl
import logging
import socket
import struct
import urllib.request
from urllib.parse import urlparse
from xml.dom import minidom
from functools import wraps
import urllib.error
import xml

SIOCGIFINDEX = 0x8933  # Get interface index
logger = logging.getLogger(__name__)

class NotRetrievedError(Exception):
    """Custom exception for objects that have not been retrieved

    Custom object not retrieved exception class. Raised whenever a certain
    property for a device or service was not retrieved.

    """
    pass

class NotAvailableError(Exception):
    """Custom exception for when a certain URL could not be retrieved

    Custom element not retrieved exception class. Raised whenever a value
    needed to be accessed could not be retrieved from the URL.

    """
    pass

def parse_http_header(header, header_key):
    """Parse HTTP header value

    Parse the value of a specific header from a RAW HTTP response.

    :param header: String containing the RAW HTTP response and headers
    :type header: str
    :param header_key: The header name of which to extract a value from
    :type header_key: str
    :return: The value of the header
    :rtype: str

    """
    split_headers = header.split('\r\n')

    for entry in split_headers:
        header = entry.strip().split(':', 1)

        if header[0].strip().lower() == header_key.strip().lower():
            return ''.join(header[1::]).split()[0]

def make_http_request(url, data=None, headers=None):
    """Helper function for making HTTP requests

    Helper function for making HTTP requests using urllib.

    :param url: The URL to which a request should be made
    :type url: str
    :param data: Provide data for the request. Request method will be set to
                 POST if data is provided
    :type data: str
    :param headers: Provide headers to send with the request
    :type headers: dict
    :return: A urllib.Request.urlopen object
    :rtype: urllib.Request.urlopen

    """
    if not headers:
        headers = {}

    # If data is provided the request method will automatically be set to POST
    # by urllib
    request = urllib.request.Request(url, data=data, headers=headers)
    return urllib.request.urlopen(request)

def _device_description_required(func):
    """Decorator for checking whether the device description is available on a
    device.

    """

    @wraps(func)
    def wrapper(device, *args, **kwargs):
        if device.description is None:
            raise NotRetrievedError(
                'No device description retrieved for this device.')
        elif device.description == NotAvailableError:
            return
        return func(device, *args, **kwargs)

    return wrapper

def _get_if_index(ifname, fd):
    """Get the index corresponding to interface ifname used by socket fd"""
    ifreq = struct.pack('16si', ifname.encode(), 0)
    res = fcntl.ioctl(fd, SIOCGIFINDEX, ifreq)
    return int(struct.unpack('16si', res)[1])

class SSDPDevice:
    """Represents an SSDP device

    Object for representing an SSDP device.

    :param address: SSDP device address
    :type address: tuple
    :param response: Device discovery response data
    :type response: str

    """

    def __init__(self, address, response):
        self.address = address
        self.host = address[0]
        self.port = address[1]
        self.response = response
        self.description = None
        self.friendly_name = None
        self.type_ = None
        self.base_url = None

        self._get_description_request(parse_http_header(response, 'Location'))
        self._get_friendly_name_request()
        self._get_type_request()
        self._get_base_url_request()

    def get_friendly_name(self):
        """Get the friendly name for the device

        Gets the device's friendly name

        :return: Friendly name of the device
        :rtype: str

        """
        return self.friendly_name

    def _get_description_request(self, url):
        try:
            device_description = make_http_request(url).read()
            self.description = device_description
            return device_description.decode()

        except (urllib.error.HTTPError, urllib.error.URLError):
            self.description = NotAvailableError
            return None

    @_device_description_required
    def _get_friendly_name_request(self):
        root = minidom.parseString(self.description)
        device_friendly_name = root.getElementsByTagName(
            'friendlyName')[0].firstChild.nodeValue
        self.friendly_name = device_friendly_name
        return self.friendly_name

    @_device_description_required
    def _get_type_request(self):
        root = minidom.parseString(self.description)
        device_type = root.getElementsByTagName(
            'deviceType')[0].firstChild.nodeValue
        self.type_ = device_type
        return self.type_

    @_device_description_required
    def _get_base_url_request(self):
        location_header_value = parse_http_header(self.response, 'Location')
        header_url = urlparse(location_header_value)
        root = minidom.parseString(self.description)
        try:
            parsed_url = urlparse(
                root.getElementsByTagName('URLBase')[0].firstChild.nodeValue)

            if parsed_url.port is not None:
                base_url = '{}://{}'.format(parsed_url.scheme,
                                            parsed_url.netloc)
            else:
                base_url = '{}://{}:{}'.format(parsed_url.scheme,
                                               parsed_url.netloc,
                                               header_url.port)
        except (IndexError, AttributeError):
            base_url = '{}://{}'.format(header_url.scheme, header_url.netloc)

        self.base_url = base_url
        return base_url

class SSDPHeader:

    def __init__(self, **headers):
        """
        Example M-SEARCH header:
        ------------------------------------------------------------------------
        M-SEARCH * HTTP/1.1          SSDP method for search requests
        HOST: 239.255.255.250:1900   SSDP multicast address and port (REQUIRED)
        MAN: "ssdp:discover"         HTTP Extension Framework scope (REQUIRED)
        MX: 2                        Maximum wait time in seconds (REQUIRED)
        ST: upnp:rootdevice          Search target (REQUIRED)
        ------------------------------------------------------------------------
        """
        self.headers = {}
        self.set_headers(**headers)

        self._available_methods = ['M-SEARCH']

        self.method = None
        self.host = self.headers.get('HOST')
        self.man = self.headers.get('MAN')
        self.mx = self.headers.get('MX')
        self.st = self.headers.get('ST')

    def _check_method_required_params(self):
        if self.method == 'M-SEARCH':
            # M-SEARCH required parameters: HOST, MAN, MX, ST
            if None in [self.host, self.man, self.mx, self.st]:
                raise ValueError(
                    'M-SEARCH method requires HOST, MAN, MX and ST headers '
                    'to be set.')

    def set_method(self, method):
        method = method.upper()
        if method in self._available_methods:
            self.method = method.upper()
        else:
            raise ValueError('Method must be either' +
                             ' or '.join(self._available_methods))

    def set_header(self, name, value):
        self.headers[name.upper()] = value

    def set_headers(self, **headers):
        for key, value in headers.items():
            self.set_header(key.upper(), value)

class SSDPRequest(SSDPHeader):
    """Create and perform an SSDP request

    :param method: SSDP request method [M-SEARCH]

    """

    def __init__(self,
                 ssdp_mcast_addr='239.255.255.250',
                 ssdp_port=1900,
                 src_port=None,
                 interface=None,
                 **headers):
        super().__init__(**headers)

        self.SSDP_MCAST_ADDR = ssdp_mcast_addr
        self.SSDP_PORT = ssdp_port

        self.set_header('HOST', "{}:{}".format(self.SSDP_MCAST_ADDR,
                                               self.SSDP_PORT))

        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

        if (src_port is not None):
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.socket.bind(('', src_port))

        if (interface is not None):
            try:
                ifindex = _get_if_index(interface, self.socket.fileno())
            except OSError:
                logger.error(
                    "Could not find interface \"{}\"".format(interface))
                return
            except ValueError:
                logger.error(
                    "Failed to parse the index of interface \"{}\"".format(
                        interface))
                return
            ip_mreqn = struct.pack(
                '4s4si',
                socket.inet_aton(ssdp_mcast_addr),
                socket.inet_aton('0.0.0.0'),  # INADDR_ANY
                ifindex)
            self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF,
                                   ip_mreqn)

    def __del__(self):
        self.socket.close()

    def m_search(self, discover_delay=2, st='ssdp:all', **headers):
        """Perform an M-SEARCH SSDP request

        Send an SSDP M-SEARCH request for finding UPnP devices on the network.

        :param discover_delay: Device discovery delay in seconds
        :type discover_delay: int
        :param st: Specify device Search Target
        :type st: str
        :param headers: Specify M-SEARCH specific headers
        :type headers: str
        :return: List of device that replied
        :rtype: list

        """
        self.set_method('M-SEARCH')

        self.set_header('MAN', '"ssdp:discover"')
        self.set_header('MX', discover_delay)
        self.set_header('ST', st)
        self.set_headers(**headers)

        self.socket.settimeout(discover_delay)

        devices = self._send_request(self._get_raw_request())

        for device in devices:
            yield device

    def _get_raw_request(self):
        """Get raw request data to send to server"""

        final_request_data = ''

        if self.method is not None:
            ssdp_start_line = '{} * HTTP/1.1'.format(self.method)
        else:
            ssdp_start_line = 'HTTP/1.1 200 OK'

        final_request_data += '{}\r\n'.format(ssdp_start_line)

        for header, value in self.headers.items():
            final_request_data += '{}: {}\r\n'.format(header, value)

        final_request_data += '\r\n'

        return final_request_data

    def _send_request(self, message):
        self.socket.sendto(message.encode(),
                           (self.SSDP_MCAST_ADDR, self.SSDP_PORT))

        devices = []

        try:
            while True:

                # UDP packet data limit is 65507 imposed by IPv4
                # https://en.wikipedia.org/wiki/User_Datagram_Protocol#Packet_structure

                response, addr = self.socket.recvfrom(65507)
                try:
                    device = SSDPDevice(addr, response.decode())
                except xml.parsers.expat.ExpatError:
                    continue
                devices.append(device)
        except socket.timeout:
            pass

        return devices

class UPnP:
    """UPnP object

    A UPnP object used for device discovery

    """

    def __init__(self, src_port=None, interface=None):
        self.ssdp = SSDPRequest(src_port=src_port, interface=interface)
        self.discovered_devices = []

    def discover(self, delay=2, **headers):
        """Find UPnP devices on the network

        Find available UPnP devices on the network by sending an M-SEARCH
        request.

        :param delay: Discovery delay, amount of time in seconds to wait for a
                      reply from devices
        :type delay: int
        :param headers: Optional headers for the request
        :return: List of discovered devices
        :rtype: list

        """

        discovered_devices = []
        for device in self.ssdp.m_search(discover_delay=delay,
                                         st='upnp:rootdevice',
                                         **headers):
            discovered_devices.append(device)

        self.discovered_devices = discovered_devices
        return self.discovered_devices


import numpy as np
import time
import os
import sys
from scipy.stats import poisson, binom
from scipy.special import erf as erf
from admin import make_glob_array
import multiprocessing
# from Sim_show import Sim_fit
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
import matplotlib.colors as mcolors
from make_3D import make_3D

pmts=np.array([0,1,4,6,7,3,10,13,15,17,18,5,11,12,14])

path='/home/gerak/Desktop/DireXeno/011220/'
data=np.load(path+'h.npz')
Angs=data['Angs']
Angs10=data['Angs10']
Angsbins=data['Angsbins']
H=data['H']
G=data['G']
Spectrum=data['spectrum']
Sbins=data['Sbins']
Spectra=np.transpose(data['spectra'], (2,0,1))
sbins=data['sbins']
FSbins=data['FSbins']
FullSpectrum=data['Fullspectrum']
w=data['W']
Wbins=data['Wbins']
Wbands=data['Wbands']
Sbands=data['Sbands']
W20_40=data['W20_40']
W20_40bins=data['W20_40bins']

data=np.loadtxt(path+'NRel.txt')
NDep=[]
NSpec=[]
for i in range(len(data)):
    NDep.append(data[i][0])
    NSpec.append(data[i][1])
NSpec=NSpec/np.sum(NSpec)

N=10
data=np.load('Q.npz')
ls=data['ls']
Sspectrum=data['Ravel_Spectrum'].reshape((N, 1, np.shape(Spectrum)[0]))[:,0]
Sspectra=data['Ravel_Spectra'].reshape((N, 1, np.shape(Spectra)[0], np.shape(Spectra)[1], np.shape(Spectra)[2]))[:,0]
SG=data['Ravel_G'].reshape((N, 1, np.shape(G)[0], np.shape(G)[1], np.shape(G)[2]))[:,0]
SH=data['Ravel_H'].reshape((N, 1, np.shape(H)[0], np.shape(H)[1], np.shape(H)[2], np.shape(H)[3]))[:,0]
SAngs=data['Ravel_Angs'].reshape((N, 1, np.shape(Angs)[0], np.shape(Angs)[1]))[:,0]
SFullspectrum=data['Ravel_Fullspectrum'].reshape((N, 1, np.shape(FullSpectrum)[1]))[:,0]
SW=data['Ravel_W'].reshape((N, 1, np.shape(w)[0]))[:,0]
keVbins=data['keVbins']
PEbins=data['PEbins']
keVPE=data['Ravel_KeVPE'].reshape((N, len(keVbins)-1, len(PEbins)-1))
y=np.arange(0, 600)
y1=data['adn']*y+data['bdn']
y2=data['aup']*y+data['bup']

plt.figure()
plt.title('Energy spectrum')
plt.step(NDep, NSpec, where='mid')
# plt.yscale('log')

plt.figure(figsize=(20,10))
X, Y= np.meshgrid(0.5*(keVbins[1:]+keVbins[:-1]), 0.5*(PEbins[1:]+PEbins[:-1]))
plt.pcolor(Y, X, np.mean(keVPE, axis=0), norm=mcolors.PowerNorm(0.3))
plt.plot(y, y1, 'k--', label='{}x+{}'.format(np.round(data['adn'],decimals=2), np.round(data['bdn'],decimals=2)), linewidth=5)
plt.plot(y, y2, 'k--', label='{}x+{}'.format(np.round(data['aup'],decimals=2), np.round(data['bup'],decimals=2)), linewidth=5)
plt.xlabel('PEs', fontsize=25)
plt.ylabel('keV', fontsize=25)
plt.tick_params(axis='both', which='major', labelsize=20)
cbar=plt.colorbar()
cbar.ax.tick_params(labelsize=25)
plt.legend(fontsize=35, loc='upper right')
plt.xlim(0, np.amax(PEbins))
plt.ylim(0, np.amax(keVbins))

plt.figure()
plt.title('W')
plt.bar(0.5*(Wbins[1:]+Wbins[:-1]), w, width=Wbins[1:]-Wbins[:-1], color='r', alpha=0.5)
plt.errorbar(0.5*(Wbins[1:]+Wbins[:-1]), np.mean(SW, axis=0), np.std(SW, axis=0), fmt='.')
for i in range(len(Wbands)):
    plt.axvline(Wbands[i], 0, 1)
plt.yscale('log')
#
plt.figure()
plt.title('Full Spectrum')
plt.step(0.5*(FSbins[1:]+FSbins[:-1]), np.sum(FullSpectrum, axis=0), where='mid')
for i in range(len(Wbands)-1):
    plt.bar(0.5*(FSbins[1:]+FSbins[:-1]), FullSpectrum[i], width=FSbins[1:]-FSbins[:-1], label='spectrum', alpha=0.5)
plt.errorbar(0.5*(FSbins[1:]+FSbins[:-1]), np.mean(SFullspectrum, axis=0), np.std(SFullspectrum, axis=0), fmt='.', label='A')
plt.yscale('log')
plt.legend()

plt.figure()
plt.title('Global Spectrum')
plt.bar(0.5*(Sbins[1:]+Sbins[:-1]), Spectrum, width=Sbins[1:]-Sbins[:-1], label='spectrum', color='r', alpha=0.5)
plt.errorbar(0.5*(Sbins[1:]+Sbins[:-1]), np.mean(Sspectrum, axis=0), np.std(Sspectrum, axis=0), fmt='.', label='A')
plt.legend()
plt.yscale('log')

t=np.arange(100)
fig, ax=plt.subplots(2,3)
for k in range(len(Sbands)-1):
    #plt.title('The temporal structure in different energy ranges (NRs) {}-{}'.format(Sbands[k], Sbands[k+1]), fontsize=35)
    data=np.ravel(G[k])
    model=np.ravel(np.mean(SG[:,k], axis=0))
    N=np.sum(np.sum(G[k].T*np.arange(np.shape(G)[1]), axis=1)/np.sum(G[k], axis=0))
    np.ravel(ax)[k].step(t, (np.sum(G[k].T*np.arange(np.shape(G)[1]), axis=1)/np.sum(G[k], axis=0))/N, where='mid', label='PEs: {}-{}'.format(Sbands[k], Sbands[k+1]), linewidth=3)
    np.ravel(ax)[k].errorbar(t, np.mean(np.sum(np.transpose(SG[:,k], (0,2,1))*np.arange(np.shape(G)[1]), axis=-1)/np.sum(SG[:,k], axis=1), axis=0)/N,
                np.std(np.sum(np.transpose(SG[:,k], (0,2,1))*np.arange(np.shape(G)[1]), axis=-1)/np.sum(SG[:,k], axis=1), axis=0)/N, fmt='.', label='{}'.format(-np.sum(data*np.log((model+1e-10)/(data+1e-10))+data-model)))
    np.ravel(ax)[k].legend(fontsize=10)
    np.ravel(ax)[k].set_yscale('log')
    # plt.xlabel('Time [ns]', fontsize=35)
    # plt.ylabel('The probability to resolve a PE /\naveage number of PEs at\n the energy range', fontsize=35)
    # plt.ylabel('The average number of\nPEs resolved (normalized)', fontsize=35)
    # plt.tick_params(axis='both', which='major', labelsize=20)
# plt.show()

# for k in range(len(Sbands)-1):
#     fig, ax=plt.subplots(4,4)
#     fig.suptitle('PMT spectra ({}-{})'.format(Sbands[k], Sbands[k+1]))
#     for i in range(15):
#         np.ravel(ax)[i].step(0.5*(sbins[1:]+sbins[:-1]), Spectra[k,:,i], where='mid', label='A')
#         np.ravel(ax)[i].errorbar(0.5*(sbins[1:]+sbins[:-1]), np.mean(Sspectra[:,k,:,i], axis=0), np.std(Sspectra[:,k,:,i], axis=0), fmt='.', label='A')
#         np.ravel(ax)[i].legend()
#         np.ravel(ax)[i].set_yscale('log')

# for k in range(len(Sbands)-1):
for k in range(1):
    fig, ax=plt.subplots(4,4)
    fig.suptitle('PMT temporal ({}-{})'.format(Sbands[k], Sbands[k+1]))
    for i in range(15):
        np.ravel(ax)[i].step(t, np.sum(H[k, :,:,i].T*np.arange(np.shape(H)[1]), axis=1)/np.sum(H[k, :,:,i], axis=0), where='mid', label='PMT{}'.format(pmts[i]))
        # np.ravel(ax)[i].errorbar(t, np.mean(np.sum(np.transpose(SH[k,:,:,:,i], (0,2,1))*np.arange(np.shape(H)[1]), axis=-1)/np.sum(SH[k,:,:,:,i], axis=1), axis=0),
        #             np.std(np.sum(np.transpose(SH[k,:,:,:,i], (0,2,1))*np.arange(np.shape(H)[1]), axis=-1)/np.sum(SH[k,:,:,:,i], axis=1), axis=0), fmt='.')
        np.ravel(ax)[i].set_yscale('log')
        np.ravel(ax)[i].legend()
plt.show()