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

from __future__ import print_function
from __future__ import division

from pyomo.core.base import Var, Objective, minimize, Set, Constraint, Expression, Param, Suffix, maximize
from pyomo.core.base import ConstraintList
from pyomo.opt import SolverFactory, ProblemFormat, SolverStatus, TerminationCondition
from pyomo.core.base import value
import numpy as np
import sys, time, re
from pyutilib.common._exceptions import ApplicationError

__author__ = "David M Thierry @dthierry"

class DynGen(object):
    def __init__(self, **kwargs):
        # Values for the suffixes of input files
        self.int_file_mhe_suf = int()
        self.res_file_mhe_suf = str()

        self.int_file_nmpc_suf = int()
        self.res_file_nmpc_suf = str()

        self.res_file_suf = str(int(time.time()))

        self.d_mod = kwargs.pop('d_mod', None)

        self.nfe_t = kwargs.pop('nfe_t', 5)
        self.ncp_t = kwargs.pop('ncp_t', 3)

        self._t = kwargs.pop('_t', 100)
        self.states = kwargs.pop('states', [])
        self.u = kwargs.pop('u', [])  #: The inputs (controls)

        self.hi_t = self._t/self.nfe_t
        self.ss = self.d_mod(1, 1, steady=True)
        self.ss2 = object
        self.d1 = self.d_mod(1, self.ncp_t, _t=self.hi_t)
        self.d2 = object()
        self.ss.name = "ss"
        self.d1.name = "d1"

        self.ipopt = SolverFactory("ipopt")
        self.asl_ipopt = SolverFactory("asl:ipopt")
        self.k_aug = SolverFactory("k_aug",
                                   executable="/home/dav0/k2/KKT_matrix/src/kmatrix/k_aug")
        self.k_aug_sens = SolverFactory("k_aug",
                                        executable="/home/dav0/k2/KKT_matrix/src/kmatrix/k_aug")
        self.dot_driver = SolverFactory("dot_driver",
                                        executable="/home/dav0/k2/KKT_matrix/src/kmatrix/dot_driver/dot_driver")

        # self.k_aug.options["eig_rh"] = ""
        self.asl_ipopt.options["halt_on_ampl_error"] = "yes"

        # self.ipopt.options["print_user_options"] = "yes"
        # self.k_aug.options["deb_kkt"] = ""

        self.ss.ofun = Objective(expr=1, sense=minimize)
        self.dyn = object()
        self.l_state = []
        self.l_vals = []
        self._c_it = 0
        self.ccl = []
        self.iput = []
        self.sp = []

        self._kt_list = []
        self._dt_list = []
        self._ipt_list = []

        self._k_timing = ["0", "0", "0"]
        self._dot_timing = "0"
        self.ip_time = 0

        self._stall_iter = 0
        self._window_keep = self.nfe_t + 2

        self._u_plant = {}  #: key: (ui, time)
        for i in self.u:
            u = getattr(self.d1, i)
            for t in range(0, self._window_keep):
                self._u_plant[(i, t)] = value(u[1])
        self.curr_u = dict.fromkeys(self.u, 0.0)

        self.state_vars = {}
        self.curr_estate = {}  #: Current estimated state (for the olnmpc)
        self.curr_rstate = {}  #: Current real state (for the olnmpc)

        self.curr_state_offset = {}  #: Current offset of measurement
        self.curr_pstate = {}  #: Current offset of measurement
        self.curr_state_noise = {}  #: Current noise of the state

        self.curr_state_target = {}  #: Current target state
        self.curr_u_target = {}  #: Current control state

        self.xp_l = []
        self.xp_key = {}

        with open("ipopt.opt", "w") as f:
            f.close()

    def load_iguess_ss(self):
        """"Call the method for loading initial guess from steady-state"""
        self.ss.init_steady_ref()

    def solve_ss(self):
        """Solves steady state model
        Args:
            None
        Return:
            None"""
        # self.k_aug.solve(self.ss, tee=True, symbolic_solver_labels=True)
        with open("ipopt.opt", "w") as f:
            f.write("max_iter 100\n")
            f.write("mu_init 1e-08\n")
            f.write("bound_push 1e-08\n")
            f.write("print_info_string yes\n")
            f.close()
        ip = SolverFactory("ipopt")
        # ip.options["halt_on_ampl_error"] = "yes"
        ip.options["print_user_options"] = "yes"
        ip.options["linear_solver"] = "ma57"
        results = ip.solve(self.ss, tee=True, symbolic_solver_labels=True, report_timing=True)
        self.ss.solutions.load_from(results)
        for x in self.states:
            self.state_vars[x] = []
            try:
                xv = getattr(self.ss, x)
            except AttributeError:  # delete this
                continue
            for j in xv.keys():
                if xv[j].stale:
                    continue
                if type(j[2:]) == tuple:
                    self.state_vars[x].append(j[2:])
                else:
                    self.state_vars[x].append((j[2:],))

        for x in self.states:
            try:
                xvar = getattr(self.ss, x)
            except AttributeError:  # delete this
                continue
            for j in self.state_vars[x]:
                self.curr_state_offset[(x, j)] = 0.0
                self.curr_state_noise[(x, j)] = 0.0
                self.curr_estate[(x, j)] = value(xvar[1, 1, j])
                self.curr_rstate[(x, j)] = value(xvar[1, 1, j])
                self.curr_state_target[(x, j)] = value(xvar[1, 1, j])
        for u in self.u:
            uvar = getattr(self.ss, u)
            self.curr_u_target[u] = value(uvar[1])
            self.curr_u[u] = value(uvar[1])

    # self.ss.write(filename="ss.nl",format=ProblemFormat.nl, io_options={"symbolic_solver_labels":True})

    def load_d_s(self, dmod):
        """Loads the solution of the steady state model into the dynamic
        Args:
            dmod (pyomo.core.base.PyomoModel.ConcreteModel): Target model
        Return:
            None"""
        s = self.ss
        d = dmod
        for vs in s.component_objects(Var, active=True):
            vd = getattr(d, vs.getname())
            if vs.is_indexed():
                if len(vs.keys()) > 1:
                    # print(vs.getname())
                    for ks in vs.keys():
                        kj = ks[2:]
                        # for i in range(1, self.nfe_t + 1):
                        for j in range(1, self.ncp_t + 1):
                            vd[(1, j) + kj].set_value(value(vs[ks]))
                else:
                    for ks in vs.keys():
                        for kd in vd.keys():
                            vd[kd].set_value(value(vs[ks]))
        for x in self.states:
            try:
                dv = getattr(dmod, "d" + x + "_dt")
            except AttributeError:  # delete this
                continue
            for i in dv.itervalues():
                i.set_value(0.0)
        for i in self.states:
            pn = i + "_ic"
            p = getattr(d, pn)
            vs = getattr(s, i)
            vd0 = getattr(d, i)
            for ks in p.keys():
                p[ks].value = value(vs[(1, 1)+(ks,)])
                vd0[(1, 0)+(ks,)].set_value(value(vs[(1, 1)+(ks,)]))

    def solve_d(self, mod, **kwargs):
        """Solves dynamic model
        Args:
            mod (pyomo.core.base.PyomoModel.ConcreteModel): Target model
        Return:
            int: 0 if success 1 otw"""
        d = mod
        mu_init = 0.1
        iter_max = 3000
        max_cpu_time = 1e+06
        linear_solver = "ma57"
        ma57_pre_alloc = 1.05
        ma57_automatic_scaling = "no"
        ma57_small_pivot_flag = 0

        # o_tee = True
        stop_if_nopt = False
        want_stime = False  #: Updates internal time variable
        rep_timing = False

        if kwargs.get("stop_if_nopt"):
            stop_if_nopt = kwargs["stop_if_nopt"]
        if kwargs.get("want_stime"):
            want_stime = kwargs["want_stime"]
        if kwargs.get("rep_timing"):
            rep_timing = kwargs["rep_timing"]
        if kwargs.get("stop_if_nopt"):
            stop_if_nopt = kwargs["stop_if_nopt"]
        if kwargs.get("iter_max"):
            iter_max = kwargs["iter_max"]

        if kwargs.get("linear_solver"):
            linear_solver = kwargs["linear_solver"]
        if kwargs.get("ma57_pre_alloc"):
            ma57_pre_alloc = kwargs["ma57_pre_alloc"]
        if kwargs.get("ma57_automatic_scaling"):
            ma57_automatic_scaling = kwargs["ma57_automatic_scaling"]
        if kwargs.get("ma57_small_pivot_flag"):
            ma57_small_pivot_flag = kwargs["ma57_small_pivot_flag"]

        max_cpu_time = kwargs.pop("max_cpu_time", 1e+06)

        o_tee = kwargs.pop("o_tee", True)
        skip_mult_update = kwargs.pop("skip_update", True)
        halt_on_ampl_error = kwargs.pop("halt_on_ampl_error", False)
        warm_start = kwargs.pop("warm_start", False)
        tol = kwargs.pop("tol", None)
        mu_init = kwargs.pop("mu_init", None)
        out_file = kwargs.pop("output_file", None)
        linear_scaling_on_demand = kwargs.pop("linear_scaling_on_demand", None)
        mu_strategy = kwargs.pop("mu_strategy", None)
        perturb_always_cd = kwargs.pop("perturb_always_cd", None)
        mu_target = kwargs.pop("mu_target", None)
        print_level = kwargs.pop("print_level", None)
        print_user_options = kwargs.pop("print_user_options", True)

        if out_file:
            if type(out_file) != str:
                self.journalizer("E", self._c_it, "solve_d", "incorrect_output")
                print("output_file is not str", file=sys.stderr)
                sys.exit()
        jacRegVal = kwargs.pop("jacobian_regularization_value", None)
        jacRegExp = kwargs.pop("jacobian_regularization_exponent", None)
        if jacRegVal:
            if type(jacRegVal) != float:
                self.journalizer("E", self._c_it, "solve_d", "incorrect_output")
                print("jacobian_regularization_value is not float", file=sys.stderr)

                sys.exit()
        if jacRegExp:
            if type(jacRegExp) != float:
                self.journalizer("E", self._c_it, "solve_d", "incorrect_output")
                print("jacobian_regularization_exponent is not float", file=sys.stderr)
                sys.exit()
        if mu_strategy:
            if mu_strategy != "monotone" and mu_strategy != "adaptive":
                self.journalizer("E", self._c_it, "solve_d", "incorrect_output(mu_strategy)")
                print(mu_strategy)
                sys.exit()
        if mu_target:
            if type(mu_target) != float:
                self.journalizer("E", self._c_it, "solve_d", "incorrect_output")
                print("mu_target is not float", file=sys.stderr)
                sys.exit()
        if print_level:
            if type(print_level) != int:
                self.journalizer("E", self._c_it, "solve_d", "incorrect_output")
                print("print_level is not int", file=sys.stderr)
                sys.exit()

        name = mod.name

        self.journalizer("I", self._c_it, "Solving with IPOPT\t", name)

        with open("ipopt.opt", "w") as f:
            f.write("print_info_string\tyes\n")
            f.write("max_iter\t" + str(iter_max) + "\n")

            f.write("max_cpu_time\t" + str(max_cpu_time) + "\n")
            f.write("linear_solver\t" + linear_solver + "\n")
            f.write("ma57_pre_alloc\t" + str(ma57_pre_alloc) + "\n")
            f.write("ma57_automatic_scaling\t" + ma57_automatic_scaling + "\n")
            f.write("ma57_small_pivot_flag\t" + str(ma57_small_pivot_flag) + "\n")
            if warm_start:
                f.write("warm_start_init_point\t" + "yes" + "\n")
                f.write("warm_start_bound_push\t" + "1e-06" + "\n")
                f.write("mu_init\t" + "0.001" + "\n")
            if tol:
                f.write("tol\t" + str(tol) + "\n")
            if mu_init:
                f.write("mu_init\t" + str(mu_init) + "\n")
            if out_file:
                f.write("output_file\t" + out_file + "\n")
            if linear_scaling_on_demand:
                f.write("linear_scaling_on_demand\tyes\n")
            if jacRegVal:
                f.write("jacobian_regularization_value\t" + str(jacRegVal) + "\n")
            if jacRegExp:
                f.write("jacobian_regularization_exponent\t" + str(jacRegExp) + "\n")
            if mu_strategy:
                f.write("mu_strategy\t" + mu_strategy + "\n")
            if perturb_always_cd:
                f.write("perturb_always_cd\t" + "yes" + "\n")
            if mu_target:
                f.write("mu_target\t" + str(mu_target) + "\n")
            if print_level:
                f.write("print_level\t" + str(print_level) + "\n")
            if print_user_options:
                f.write("print_user_options\t" + "yes" + "\n")

            # f.write("\ncheck_derivatives_for_naninf yes\n")
            f.close()
            if halt_on_ampl_error:
                solver_ip = self.asl_ipopt
            else:
                solver_ip = self.ipopt
        results = solver_ip.solve(d, tee=o_tee, symbolic_solver_labels=True, report_timing=rep_timing)
        if (results.solver.status == SolverStatus.ok) and \
                (results.solver.termination_condition == TerminationCondition.optimal):
            self.journalizer("I", self._c_it, "solve_d", " Model solved to optimality")
            d.solutions.load_from(results)
            self._stall_iter = 0
            if want_stime and rep_timing:
                self.ip_time = self.ipopt._solver_time_x
            if not skip_mult_update:
                mod.ipopt_zL_in.update(mod.ipopt_zL_out)
                mod.ipopt_zU_in.update(mod.ipopt_zU_out)

            return 0
        else:
            if stop_if_nopt:
                self.journalizer("E", self._c_it, "solve_d", "Not-optimal. Stoping")
                sys.exit()
            self.journalizer("W", self._c_it, "solve_d", "Not-optimal.")
            return 1

    def cycle_ics(self, plant_step=False):
        """Patches the initial conditions with the last result from the simulation
        Args:
            None
        Return
            None"""
        print("-" * 120)
        print("I[[cycle_ics]] Cycling initial state.")
        print("-" * 120)
        for x in self.states:
            x_ic = getattr(self.d1, x + "_ic")
            v_tgt = getattr(self.d1, x)
            for ks in x_ic.keys():
                if type(ks) != tuple:
                    ks = (ks,)
                x_ic[ks].value = value(v_tgt[(1, self.ncp_t) + ks])
                v_tgt[(1, 0) + ks].set_value(value(v_tgt[(1, self.ncp_t) + ks]))
        if plant_step:
            self._c_it += 1

    def load_d_d(self, src, d_mod, fe, fe_src='d'):
        """Loads the solution of the src state model into the d_mod, i.e. src-->d_mod
        Args:
            src (pyomo.core.base.PyomoModel.ConcreteModel): Model with source values
            d_mod (pyomo.core.base.PyomoModel.ConcreteModel): Model whose values are to be assigned
            fe (int): The d_mod's finite element
            fe_src (str):
        Return:
            None"""
        for vs in src.component_objects(Var, active=True):
            if vs.getname()[-7:] == "_pnoisy":
                continue
            vd = getattr(d_mod, vs.getname())
            # there are two cases: 1 key 1 elem, several keys 1 element
            vskeys = vs.keys()  #: keys of the source model
            if len(vskeys) == 1:
                #: One key
                for ks in vskeys:
                    for v in vd.keys():
                        vd[v].set_value(value(vs[ks]))
            else:
                k = 0
                for ks in vskeys:
                    if k == 0:  #: Do this only once per variable
                        if type(ks) != tuple:
                            #: Several keys of 1 element each!!
                            if fe_src == "d":
                                for ks1 in vskeys:
                                    vd[ks1].set_value(value(vs[ks1]))  #: This has got to be true
                                break
                            elif fe_src == "s":
                                for ks1 in vd.keys():
                                    try:
                                        vd[ks1].set_value(value(vs[fe]))  #: This has got to be true
                                    except AttributeError:
                                        vd[ks1].value = value(vs[fe])  #: This has got to be true
                                break
                        k += 1
                    ki = ks[:2]
                    kj = ks[2:]
                    if fe_src == 'd':
                        if vs.getname() in self.states:  #: States start at 0
                            for j in range(0, self.ncp_t + 1):
                                vd[(fe, j) + kj].set_value(value(vs[ks]))
                        else:
                            for j in range(1, self.ncp_t + 1):
                                vd[(fe, j) + kj].set_value(value(vs[ks]))
                    elif fe_src == 's':
                        if vs.getname() in self.states:  #: States start at 0
                            for j in range(0, self.ncp_t + 1):
                                if ki == (fe, j):
                                    vd[(1, j) + kj].set_value(value(vs[ks]))
                                else:
                                    continue
                        else:
                            for j in range(1, self.ncp_t + 1):
                                if ki == (fe, j):
                                    vd[(1, j) + kj].set_value(value(vs[ks]))
                                else:
                                    continue

    def create_dyn(self, initialize=True):
        print("-" * 120)
        print("I[[create_dyn]] Dynamic (full) model created.")
        print("-" * 120)
        self.dyn = self.d_mod(self.nfe_t, self.ncp_t, _t=self._t)
        self.dyn.name = "full_dyn"
        self.load_d_s(self.dyn)
        if initialize:
            self.load_d_s(self.d1)
            for i in range(1, self.nfe_t + 1):
                self.solve_d(self.d1, mu_init=1e-08, iter_max=10)
                self.cycle_ics()
                self.load_d_d(self.d1, self.dyn, i)
            print("I[[create_dyn]] Dynamic (full) model initialized.")

    @staticmethod
    def journalizer(flag, iter, phase, message):
        """Method that writes a little message
        Args:
            flag (str): The flag
            iter (int): The current iteration
            phase (str): The phase
            message (str): The text message to display
        Returns:
            None"""
        iter = str(iter)
        print("-" * 120)
        if flag == 'W':
            print(flag + iter + "[[" + phase + "]]" + message + ".", file=sys.stderr)
            # print to file warning
        elif flag == 'E':
            print(flag + iter + "[[" + phase + "]]" + message + ".", file=sys.stderr)
        else:
            print(flag + iter + "[[" + phase + "]]" + message + "." + "-" * 20)
            # print to file error
        #print("-" * 120)

    # NMPC or just dyn?
    def cycle_ics_noisy(self, sigma_bar=0.0001):
        """Patches the initial conditions with the last result from the simulation with noise.
        Args:
            sigma_bar (float): The variance.
        Return
            None"""
        print("-" * 120)
        print("I[[cycle_ics]] Cycling initial state -- NOISY.")
        print("-" * 120)
        s = np.random.normal(0, sigma_bar)
        for x in self.states:
            x_ic = getattr(self.d1, x + "_ic")
            v_tgt = getattr(self.d1, x)
            for ks in x_ic.keys():
                if type(ks) != tuple:
                    ks = (ks,)
                x_ic[ks].value = value(v_tgt[(1, self.ncp_t) + ks])
                sigma = value(v_tgt[(1, self.ncp_t) + ks]) * s

                self.curr_state_noise[(x, ks)] = sigma
                tst_val = value(v_tgt[(1, self.ncp_t) + ks]) + sigma
                if tst_val < 0:
                    print("error", tst_val, x, ks)
                x_ic[ks].value = value(v_tgt[(1, self.ncp_t) + ks]) + sigma
        self._c_it += 1

    def create_predictor(self):
        self.d2 = self.d_mod(1, self.ncp_t, _t=self.hi_t)
        self.d2.name = "Dynamic Predictor"

    def predictor_step(self, ref, state_dict, **kwargs):
        """Predicted-state computation by forward simulation.
        Args:
            ref (pyomo.core.base.PyomoModel.ConcreteModel): Reference model (mostly for initialization)
            state_dict (str): Source of state. For nmpc = real, mhe = estimated

        It always loads the input from the input dictionary"""

        fe = kwargs.pop("fe", 1)
        if fe > 1:
            fe_src = "s"
        else:
            fe_src = "d"
        self.journalizer("I", self._c_it, "predictor_step", "Predictor step")
        self.load_d_d(ref, self.d2, fe, fe_src=fe_src)  #: Load the initial guess
        self.load_init_state_gen(self.d2, src_kind="dict", state_dict=state_dict)  #: Load the initial state
        self.plant_input_gen(self.d2, src_kind="dict")  #: Load the current control
        self.solve_d(self.d2, stop_if_nopt=True)
        self.journalizer("I", self._c_it, "predictor_step", "Predictor step - Success")
        sinopt = False
    def plant_input_gen(self, d_mod, src_kind, nsteps=5, **kwargs):
        """Attempt to solve the dynamic model with some source model input
        Args:
            d_mod (pyomo.core.base.PyomoModel.ConcreteModel): Model to be updated
            src_kind (str): Kind of update (default=dict)
            nsteps (int): The number of continuation steps (default=5)
        Keyword Args:
            src (pyomo.core.base.PyomoModel.ConcreteModel): Source model
            src_fe (int): Finite element from the source model"""

        self.journalizer("I", self._c_it, "plant_input", "Continuation_plant, src_kind=" + src_kind)
        #: Inputs
        target = {}
        current = {}
        ncont_steps = nsteps
        sinopt = False
        if src_kind == "mod":
            src = kwargs.pop("src", None)
            if src:
                src_fe = kwargs.pop("src_fe", 1)
                for u in self.u:
                    src_var = getattr(src, u)
                    plant_var = getattr(d_mod, u)
                    target[u] = value(src_var[src_fe])
                    current[u] = value(plant_var[1])
                    self.journalizer("I", self._c_it,
                                     "plant_input",
                                     "Target {:f}, Current {:f}, n_steps {:d}".format(target[u], current[u],
                                                                                ncont_steps))
            else:
                pass  #error
        else:
            for u in self.u:
                plant_var = getattr(d_mod, u)
                target[u] = self.curr_u[u]
                current[u] = value(plant_var[1])
                self.journalizer("I", self._c_it,
                                 "plant_input",
                                 "Target {:f}, Current {:f}, n_steps {:d}".format(target[u], current[u],
                                                                                ncont_steps))
        for i in range(0, ncont_steps):
            for u in self.u:
                plant_var = getattr(d_mod, u)
                plant_var[1].value += (target[u]-current[u])/ncont_steps
                print("Continuation :Current {:s}\t{:f}".format(u, value(plant_var[1])))
            if i == ncont_steps:
                sinopt = True
                tstv = self.solve_d(d_mod, o_tee=True, stop_if_nopt=False, print_level=2, max_cpu_time=600, print_user_options=False)
            else:
                tstv = self.solve_d(d_mod, o_tee=True, stop_if_nopt=False, print_level=2, max_cpu_time=600, print_user_options=False)
                if tstv != 0:
                    try:
                        self.solve_d(d_mod, o_tee=True,
                                     max_cpu_time = 600,
                                     halt_on_ampl_error = True,
                                     mu_strategy = "adaptive",
                                     perturb_always_cd = True,
                                     tol = 1e-03,
                                     ma57_automatic_scaling = "yes",
                                     output_file = "failed_homotopy_d1.txt",
                                     stop_if_nopt=sinopt)
                    except ApplicationError:
                        print("Ipopt FAIL", file=sys.stderr)
                        self.d1.write_nl()
                        self.d1.snap_shot(filename="baddie.py")
                        self.d1.report_zL(filename="bad_bounds")
                        sys.exit()

    def update_u(self, src, **kwargs):
        """Update the current control(input) vector
        Args:
            **kwargs: Arbitrary keyword arguments.
        Returns:
            None
        Keyword Args:
            mod (pyomo.core.base.PyomoModel.ConcreteModel): The reference model (default d1)
            fe (int): The required finite element """
        fe = kwargs.pop("fe", 1)
        for u in self.u:
            uvar = getattr(src, u)
            self.curr_u[u] = value(uvar[fe])

    def update_state_real(self):
        for x in self.states:
            xvar = getattr(self.d1, x)
            for j in self.state_vars[x]:
                self.curr_rstate[(x, j)] = value(xvar[1, self.ncp_t, j])

    def update_state_predicted(self):
        """For the olnmpc"""
        for x in self.states:
            xvar = getattr(self.d2, x)
            for j in self.state_vars[x]:
                self.curr_pstate[(x, j)] = value(xvar[1, self.ncp_t, j])

    def load_init_state_gen(self, dmod, src_kind="mod", **kwargs):
        """Loads ref state for a forward simulation.
        Args:
            **kwargs: Arbitrary keyword arguments.
        Returns:
            None
        Keyword Args:
            src_kind (str) : if == mod use reference model, otw use the internal dictionary
            ref (pyomo.core.base.PyomoModel.ConcreteModel): The reference model (default d1)
            fe (int): The required finite element
            cp (int): The required collocation point
        """
        # src_kind = kwargs.pop("src_kind", "mod")
        self.journalizer("I", self._c_it, "load_init_state_gen", "Load State to nmpc src_kind=" + src_kind)
        ref = kwargs.pop("ref", None)
        fe = kwargs.pop("fe", self.nfe_t)
        cp = kwargs.pop("cp", self.ncp_t)
        if src_kind == "mod":
            if not ref:
                self.journalizer("W", self._c_it, "load_init_state_gen", "No model was given")
                self.journalizer("W", self._c_it, "load_init_state_gen", "No update on state performed")
                return
            for x in self.states:
                xic = getattr(dmod, x + "_ic")
                xvar = getattr(dmod, x)
                xsrc = getattr(ref, x)
                for j in self.state_vars[x]:
                    val_src = value(xsrc[(fe, cp) + j])
                    xic[j].value = val_src
                    xvar[(1, 0) + j].set_value(val_src)
        else:
            state_dict = kwargs.pop("state_dict", None)
            if state_dict == "real":  #: Load from the real state dict
                for x in self.states:
                    xic = getattr(dmod, x + "_ic")
                    xvar = getattr(dmod, x)
                    for j in self.state_vars[x]:
                        xic[j].value = self.curr_rstate[(x, j)]
                        xvar[(1, 0) + j].set_value(self.curr_rstate[(x, j)])
            elif state_dict == "estimated":  #: Load from the estimated state dict
                for x in self.states:
                    xic = getattr(dmod, x + "_ic")
                    xvar = getattr(dmod, x)
                    for j in self.state_vars[x]:
                        xic[j].value = self.curr_estate[(x, j)]
                        xvar[(1, 0) + j].set_value(self.curr_estate[(x, j)])
            elif state_dict == "predicted":  #: Load from the estimated state dict
                for x in self.states:
                    xic = getattr(dmod, x + "_ic")
                    xvar = getattr(dmod, x)
                    for j in self.state_vars[x]:
                        xic[j].value = self.curr_pstate[(x, j)]
                        xvar[(1, 0) + j].set_value(self.curr_pstate[(x, j)])
            else:
                self.journalizer("W", self._c_it, "load_init_state_gen", "No dict w/state was specified")
                self.journalizer("W", self._c_it, "load_init_state_gen", "No update on state performed")
                return

    def make_noisy(self, cov_dict, conf_level=2):
        self.d1.name = "Noisy plant (d1)"
        k = 0
        for x in self.states:
            s = getattr(self.d1, x)  #: state
            xicc = getattr(self.d1, x + "_icc")
            xicc.deactivate()
            for j in self.state_vars[x]:
                self.xp_l.append(s[(1, 0) + j])
                self.xp_key[(x, j)] = k
                k += 1

        self.d1.xS_pnoisy = Set(initialize=[i for i in range(0, len(self.xp_l))])  #: Create set of noisy_states
        self.d1.w_pnoisy = Var(self.d1.xS_pnoisy, initialize=0.0)  #: Model disturbance
        self.d1.Q_pnoisy = Param(self.d1.xS_pnoisy, initialize=1, mutable=True)
        self.d1.obj_fun_noisy = Objective(sense=maximize,
                                          expr=0.5 *
                                              sum(self.d1.Q_pnoisy[k] * self.d1.w_pnoisy[k]**2 for k in self.d1.xS_pnoisy)
                                          )
        self.d1.ics_noisy = ConstraintList()

        k = 0
        for x in self.states:
            s = getattr(self.d1, x)  #: state
            xic = getattr(self.d1, x + "_ic")
            for j in self.state_vars[x]:
                expr = s[(1, 1) + j] == xic[j] + self.d1.w_pnoisy[k]
                self.d1.ics_noisy.add(expr)
                k += 1

        for key in cov_dict:
            vni = key
            v_i = self.xp_key[vni]
            self.d1.Q_pnoisy[v_i].value = cov_dict[vni]
            self.d1.w_pnoisy[v_i].setlb(-conf_level * cov_dict[vni])
            self.d1.w_pnoisy[v_i].setub(conf_level * cov_dict[vni])

        with open("debug.txt", "w") as f:
            self.d1.Q_pnoisy.display(ostream=f)
            self.d1.obj_fun_noisy.pprint(ostream=f)
            self.d1.ics_noisy.pprint(ostream=f)
            self.d1.w_pnoisy.display(ostream=f)

    def randomize_noize(self, cov_dict):
        conf_level = np.random.randint(1, high=4)
        print("Confidence level", conf_level)
        for key in cov_dict:
            vni = key
            v_i = self.xp_key[vni]
            self.d1.w_pnoisy[v_i].setlb(-conf_level * cov_dict[vni])
            self.d1.w_pnoisy[v_i].setub(conf_level * cov_dict[vni])

    def deb_alg_sys_dyn(self, ddt=False):
        """Debugging the algebraic system"""
        # Fix differential states
        # Deactivate ODEs de_
        # Deactivate FE cont cp_
        # Deactivate IC _icc
        # Deactivate coll dvar_t_

        # Deactivate hyk
        for i in self.states:
            if ddt:
                x = getattr(self.d1, "d" + i + "_dt")
            else:
                x = getattr(self.d1, i)
            x.fix()
            # cp_con = getattr(self.d1, "cp_" + i)
            # cp_con.deactivate()
            de_con = getattr(self.d1, "de_" + i)
            de_con.deactivate()
            icc_con = getattr(self.d1, i + "_icc")
            icc_con.deactivate()
            dvar_con = getattr(self.d1, "dvar_t_" + i)
            dvar_con.deactivate()

        # self.lsmhe.pprint(filename="algeb_mod.txt")

    def GradientsTool(self):
        self.journalizer("E", self._c_it, "GradientsTool", "Begin")
        src = self.d1
        src.dum_objfun = Objective(expr=1, sense=minimize)
        self.d1.var_order = Suffix(direction=Suffix.EXPORT)
        self.d1.con_order = Suffix(direction=Suffix.EXPORT)

        src.pprint(filename="first.txt")
        #: Fix/Deactivate irrelevant stuff
        for var in src.component_objects(Var, active=True):
            if not var.is_indexed():
                var.fix()
            for index in var.keys():
                if type(index) != tuple:
                    var.fix()
                    continue
                try:
                    if index[1] == self.ncp_t:
                        continue
                    var[index].fix()
                except IndexError:
                    var.fix()
                    print("Variable not indexed by time", var.name, file=sys.stderr)
        for con in src.component_objects(Constraint, active=True):
            if not con.is_indexed():
                con.deactivate()
            for index in con.keys():
                if type(index) != tuple:
                    con.deactivate()
                    continue
                try:
                    if index[1] == self.ncp_t:
                        continue
                    con[index].deactivate()
                except IndexError:
                    con.deactivate()
                    print("Constraint not indexed by time", con.name, file=sys.stderr)

        for i in self.states:  #: deactivate collocation related equations
            # con = getattr(src, "cp_" + i)  #: continuation
            # con.deactivate()
            con = getattr(src, "dvar_t_" + i)  #: derivative vars
            con.deactivate()
            con = getattr(src, i + "_icc")  #: initial-conditions
            con.deactivate()
            var = getattr(src, "d" + i + "_dt")
            var.fix()
            var = getattr(src, i)
            var.fix()  #: left with the av
            con = getattr(src, "de_" + i)  #: initial-conditions
            con.deactivate()
        # colcount = 0
        # for i in src.component_data_objects(Var, active=True):
        #     if i.is_fixed():
        #         continue
        #     print(i)
        #     colcount += 1
        #     i.set_suffix_value(src.var_order, colcount)
        # print(colcount)

        self.d1.write_nl(name="dgy.nl")
        sfxdict = dict()
        self.parse_rc("dgy.row", sfxdict)
        colcount = 1
        for ob in sfxdict.keys():
            con = getattr(src, sfxdict[ob][0])
            con[sfxdict[ob][1]].set_suffix_value(src.con_order, colcount)
            colcount += 1

        sfxdict = dict()
        self.parse_rc("dgy.col", sfxdict)
        colcount = 1
        for ob in sfxdict.keys():
            var = getattr(src, sfxdict[ob][0])
            var[sfxdict[ob][1]].set_suffix_value(src.var_order, colcount)
            colcount += 1
        print("Colcount\t",str(colcount), file=sys.stderr)
        src.write_nl(name="dgy.nl")
        #: Now dgx
        for var in src.component_objects(Var):
            var.fix()  #: Fix everything
        for i in self.states:
            var = getattr(src, i)
            for index in var.keys():
                try:
                    if index[1] == self.ncp_t:
                        var[index].unfix()
                except IndexError:
                    print("Something whent wrong :(\t", var.name, file=sys.stderr)

        self.d1.write_nl(name="dgx.nl")

        sfxdict = dict()
        self.parse_rc("dgx.col", sfxdict)
        colcount = 1
        for ob in sfxdict.keys():
            var = getattr(src, sfxdict[ob][0])
            var[sfxdict[ob][1]].set_suffix_value(src.var_order, colcount)
            colcount += 1
        src.write_nl(name="dgx.nl")

        #: Now dfy
        for var in src.component_objects(Var):
            var.unfix()
        for var in src.component_objects(Var):
            if not var.is_indexed():
                var.fix()
            for index in var.keys():
                if type(index) != tuple:
                    var.fix()
                    continue
                try:
                    if index[1] == self.ncp_t:
                        continue
                    var[index].fix()
                except IndexError:
                    var.fix()
                    print("Variable not indexed by time", var.name, file=sys.stderr)

        for con in src.component_objects(Constraint):
            con.deactivate()  #: deactivate everything

        for i in self.states:  #: deactivate collocation related terms
            var = getattr(src, "d" + i + "_dt")
            var.fix()
            var = getattr(src, i)
            var.fix()  #: left with the av
            con = getattr(src, "de_" + i)
            for index in con.keys():
                if index[1] == self.ncp_t:
                    con[index].activate()
        self.d1.reconstruct()
        # self.d1.write_nl(name="dfy.nl")

        sfxdict = dict()
        self.parse_rc("dgx.col", sfxdict)
        colcount = 1
        for ob in sfxdict.keys():
            col = getattr(src, "de_" + sfxdict[ob][0])
            col[sfxdict[ob][1]].set_suffix_value(src.con_order, colcount)
            colcount += 1
        src.write_nl(name="dfy.nl")

        #: Now dfx
        for var in src.component_objects(Var):
            var.fix()  #: Fix everything

        for i in self.states:
            var = getattr(src, i)
            for index in var.keys():
                try:
                    if index[1] == self.ncp_t:
                        var[index].unfix()
                except IndexError:
                    print("Something whent wrong :(\t", var.name, file=sys.stderr)
            # var.pprint()
        self.d1.reconstruct()
        src.pprint(filename="second.txt")
        self.d1.write_nl(name="dfx.nl")

    @staticmethod
    def parse_rc(file, dsfx):

        f = open(file, "r")
        lines = f.readlines()
        for l in lines:
            i = re.split('\[|\]', l.strip())
            index = list()
            if len(i) < 2:
                continue
            for k in i[1].split(','):
                try:
                    k = int(k)
                except ValueError:
                    pass
                index.append(k)
            index = tuple(index)
            dsfx[l] = [i[0], index]
        f.close()

max_stars_repo_name: kuanhanl/cappresse

max_issues_repo_name: kuanhanl/cappresse

max_forks_repo_name: kuanhanl/cappresse

reason: import numpy,from pyomo


text:
import numpy as np
import sys
import os
sys.path.append('utils/')
from config import *
from utils import *
sys.path.append(pycaffe_dir)
import time
import pdb
import random
import pickle as pkl
import caffe
from multiprocessing import Pool
from threading import Thread
import random
import h5py
import itertools
import math
import re

glove_dim = 300
glove_path = 'data/glove.6B.%dd.txt' %glove_dim
#glove_path = 'data/glove_debug_path.txt' #for debugging

if glove_path == 'data/glove_debug_path.txt':
    print "continue?"
    pdb.set_trace()

possible_segments = [(0,0), (1,1), (2,2), (3,3), (4,4), (5,5)]
for i in itertools.combinations(range(6), 2):
    possible_segments.append(i)

length_prep_word = 40
length_prep_character = 250

vocab_file = 'data/vocab_glove_complete.txt'

def word_tokenize(s):
  sent = s.lower()
  sent = re.sub('[^A-Za-z0-9\s]+',' ', sent)
  return sent.split()

def sentences_to_words(sentences):
  words = []
  for s in sentences:
    words.extend(word_tokenize(str(s.lower())))
  return words

class glove_embedding(object):

  ''' Creates glove embedding object
  '''

  def __init__(self, glove_file=glove_path):
    glove_txt = open(glove_file).readlines()
    glove_txt = [g.strip() for g in glove_txt]
    glove_vector = [g.split(' ') for g in glove_txt]
    glove_words = [g[0] for g in glove_vector]
    glove_vecs = [g[1:] for g in glove_vector]
    glove_array = np.zeros((glove_dim, len(glove_words)))
    glove_dict = {}
    for i, w in enumerate(glove_words):  glove_dict[w] = i
    for i, vec in enumerate(glove_vecs):
      glove_array[:,i] = np.array(vec)
    self.glove_array = glove_array
    self.glove_dict = glove_dict
    self.glove_words = glove_words

class zero_language_vector(object):

  def __init__(self, data):
    self.dim = glove_dim

  def get_vector_dim(self):
    return self.dim

  def get_vocab_size(self):
    return 0

  def preprocess(self, data):
    embedding = np.zeros((self.get_vector_dim(),))
    for d in data:
      d['language_input'] = embedding
      d['gt'] = (d['gt'][0], d['gt'][1])
    return data

class recurrent_language(object):

  def get_vocab_size(self):
    return len(self.vocab_dict.keys())

  def preprocess_sentence(self, words):
    vector_dim = self.get_vector_dim()
    sentence_mat = np.zeros((len(words), vector_dim))
    count_words = 0
    for i, w in enumerate(words):
      try:
        sentence_mat[count_words,:] = self.vocab_dict[w]
        count_words += 1
      except:
        if '<unk>' in self.vocab_dict.keys():
          sentence_mat[count_words,:] = self.vocab_dict['<unk>']
          count_words += 1
        else:
          pass
    sentence_mat = sentence_mat[:count_words]
    return sentence_mat

  def preprocess(self, data):

    for d in data:
      words = sentences_to_words([d['description']])
      d['language_input'] = self.preprocess(words)
    return data

class recurrent_word(recurrent_language):

  def __init__(self, data):

    self.data = data
    vocab = open(vocab_file).readlines()
    vocab = [v.strip() for v in vocab]
    if '<unk>' not in vocab:
      vocab.append('<unk>')

    vocab_dict = {}
    for i, word in enumerate(vocab):
      vocab_dict[word] = i
    self.vocab_dict = vocab_dict

  def get_vector_dim(self):
    return 1

class recurrent_embedding(recurrent_language):

  def read_embedding(self):
    print "Reading glove embedding"
    embedding = glove_embedding(glove_path)
    self.embedding = embedding

  def get_vector_dim(self):
    return glove_dim

  def __init__(self, data):

    self.read_embedding()
    embedding = self.embedding
    vector_dim = self.get_vector_dim()
    self.data = data

    self.data = data
    vocab = open(vocab_file).readlines()
    vocab = [v.strip() for v in vocab]
    if '<unk>' in vocab:
      vocab.remove('<unk>') #don't have an <unk> vector.  Alternatively, could map to random vector...
    vocab_dict = {}

    for i, word in enumerate(vocab):
      try:
        vocab_dict[word] = embedding.glove_array[:,embedding.glove_dict[word]]
      except:
        print "%s not in glove embedding" %word
    self.vocab_dict = vocab_dict

  def preprocess(self, data):

    vector_dim = self.get_vector_dim()

    for d in data:
      d['language_input'] = sentences_to_words([d['description']])

    return data

  def get_vocab_dict(self):
    return self.vocab_dict

#Methods for extracting visual features

def feature_process_base(start, end, features):
  return np.mean(features[start:end+1,:], axis = 0)

def feature_process_norm(start, end, features):
  base_feature = np.mean(features[start:end+1,:], axis = 0)
  return base_feature/(np.linalg.norm(base_feature) + 0.00001)

def feature_process_context(start, end, features):
  feature_dim = features.shape[1]
  full_feature = np.zeros((feature_dim*2,))
  if np.sum(features[5,:]) > 0:
    full_feature[:feature_dim] = feature_process_norm(0,6, features)
  else:
    full_feature[:feature_dim] = feature_process_norm(0,5, features)
  full_feature[feature_dim:feature_dim*2] = feature_process_norm(start, end, features)

  return full_feature

feature_process_dict = {'feature_process_base': feature_process_base,
                        'feature_process_norm': feature_process_norm,
                        'feature_process_context': feature_process_context,
                        }

class extractData(object):
  """ General class to extract data.
  """

  def increment(self):
  #uses iteration, batch_size, data_list, and num_data to extract next batch identifiers
    next_batch = [None]*self.batch_size
    if self.iteration + self.batch_size >= self.num_data:
      next_batch[:self.num_data-self.iteration] = self.data_list[self.iteration:]
      next_batch[self.num_data-self.iteration:] = self.data_list[:self.batch_size -(self.num_data-self.iteration)]
      random.shuffle(self.data_list)
      self.iteration = self.num_data - self.iteration
    else:
      next_batch = self.data_list[self.iteration:self.iteration+self.batch_size]
      self.iteration += self.batch_size
    assert self.iteration > -1
    assert len(next_batch) == self.batch_size
    return next_batch

class extractLanguageFeatures(extractData):

  def __init__(self, dataset, params, result=None):
    self.data_list = range(len(dataset))
    self.num_data = len(self.data_list)
    self.dataset = dataset
    self.iteration = 0

    self.vocab_dict = params['vocab_dict']
    self.batch_size = params['batch_size']
    self.num_glove_centroids = self.vocab_dict.values()[0].shape[0]
    self.T = params['sentence_length']

    if isinstance(result, dict):
        self.result = result
        self.query_key = params['query_key']
        self.cont_key = params['cont_key']

        self.top_keys = [self.query_key, self.cont_key]
        self.top_shapes = [(self.T, self.batch_size, self.num_glove_centroids),
                           (self.T, self.batch_size)]
    else:
        print "Will only be able to run in test mode"

  def get_features(self, query):

    feature = np.zeros((self.T, self.num_glove_centroids))
    cont = np.zeros((self.T,))

    len_query = min(len(query), self.T)
    if len_query < len(query):
      query = query[:len_query]
    for count_word, word in enumerate(query):
      try:
        feature[-(len_query)+count_word,:] = self.vocab_dict[word]
      except:
        feature[-(len_query)+count_word,:] = np.zeros((glove_dim,))
    cont[-(len_query-1):] = 1
    assert np.sum(feature[:-len_query,:]) == 0

    return feature, cont

  def get_data_test(self, data):
    query = data['language_input']
    return self.get_features(query)

  def get_data(self, next_batch):

    data = self.dataset
    query_mat = np.zeros((self.T, self.batch_size, self.num_glove_centroids))
    cont = np.zeros((self.T, self.batch_size))

    for i, nb in enumerate(next_batch):
      query = data[nb]['language_input']
      query_mat[:,i,:], cont[:,i] = self.get_features(query)

    self.result[self.query_key] = query_mat
    self.result[self.cont_key] = cont

class extractVisualFeatures(extractData):

  def __init__(self, dataset, params, result):
    self.data_list = range(len(dataset))
    self.feature_process_algo = params['feature_process']
    self.loc_feature = params['loc_feature']
    self.num_data = len(self.data_list)
    self.dataset = dataset
    self.iteration = 0
    self.loc = params['loc_feature']
    loss_type = params['loss_type']
    assert loss_type in ['triplet', 'inter', 'intra']

    self.inter = False
    self.intra = False
    if loss_type in ['triplet', 'inter']:
      self.inter = True
    if loss_type in ['triplet', 'intra']:
      self.intra = True

    self.batch_size = params['batch_size']
    self.num_glove_centroids = params['num_glove_centroids']

    features_h5py = h5py.File(params['features'])
    features = {}
    for key in features_h5py.keys():
      features[key] = np.array(features_h5py[key])
    features_h5py.close()
    self.features = features

    assert self.feature_process_algo in feature_process_dict.keys()
    self.feature_process = feature_process_dict[self.feature_process_algo]

    self.feature_dim = self.feature_process(0,0,self.features[self.dataset[0]['video']]).shape[-1]
    self.result = result

    self.feature_key_p = params['feature_key_p']
    self.feature_time_stamp_p = params['feature_time_stamp_p']
    self.feature_time_stamp_n = params['feature_time_stamp_n']

    self.top_keys = [self.feature_key_p, self.feature_time_stamp_p, self.feature_time_stamp_n]
    self.top_shapes = [(self.batch_size, self.feature_dim),
                     (self.batch_size, 2),
                     (self.batch_size,2)]

    if self.inter:
      self.feature_key_inter = 'features_inter'
      self.top_keys.append(self.feature_key_inter)
      self.top_shapes.append((self.batch_size, self.feature_dim))
    if self.intra:
      self.feature_key_intra = 'features_intra'
      self.top_keys.append(self.feature_key_intra)
      self.top_shapes.append((self.batch_size, self.feature_dim))

    self.possible_annotations = possible_segments

  def get_data_test(self, d):
      video_feats = self.features[d['video']]
      features = np.zeros((len(self.possible_annotations), self.feature_dim))
      loc_feats = np.zeros((len(self.possible_annotations), 2))
      for i, p in enumerate(self.possible_annotations):
          features[i,:] = self.feature_process(p[0], p[1], video_feats)
          loc_feats[i,:] = [p[0]/6., p[1]/6.]

      return features, loc_feats

  def get_data(self, next_batch):

    feature_process = self.feature_process
    data = self.dataset
    features_p = np.zeros((self.batch_size, self.feature_dim))
    if self.inter: features_inter = np.zeros((self.batch_size, self.feature_dim))
    if self.intra: features_intra = np.zeros((self.batch_size, self.feature_dim))

    features_time_stamp_p = np.zeros((self.batch_size, 2))
    features_time_stamp_n = np.zeros((self.batch_size, 2))

    for i, nb in enumerate(next_batch):
        rint = random.randint(0,len(data[nb]['times'])-1)
        gt_s = data[nb]['times'][rint][0]
        gt_e = data[nb]['times'][rint][1]
        possible_n = list(set(self.possible_annotations) - set(((gt_s,gt_e),)))
        random.shuffle(possible_n)
        n = possible_n[0]
        assert n != (gt_s, gt_e)

        video = data[nb]['video']
        feats = self.features[video]

        if self.inter:
          other_video = data[nb]['video']
          while (other_video == video):
            other_video_index = int(random.random()*len(data))
            other_video = data[other_video_index]['video']
          feats_inter = self.features[other_video]

        features_p[i,:] = feature_process(gt_s, gt_e, feats)
        if self.intra:
          features_intra[i,:] = feature_process(n[0], n[1], feats)
        if self.inter:
          try:
            features_inter[i,:] = feature_process(gt_s, gt_e, feats_inter)
          except:
            pdb.set_trace()

        if self.loc:
          features_time_stamp_p[i,0] = gt_s/6.
          features_time_stamp_p[i,1] = gt_e/6.
          features_time_stamp_n[i,0] = n[0]/6.
          features_time_stamp_n[i,1] = n[1]/6.
        else:
          features_time_stamp_p[i,0] = 0
          features_time_stamp_p[i,1] = 0
          features_time_stamp_n[i,0] = 0
          features_time_stamp_n[i,1] = 0

        assert not math.isnan(np.mean(self.features[data[nb]['video']][n[0]:n[1]+1,:]))
        assert not math.isnan(np.mean(self.features[data[nb]['video']][gt_s:gt_e+1,:]))

    self.result[self.feature_key_p] = features_p
    self.result[self.feature_time_stamp_p] = features_time_stamp_p
    self.result[self.feature_time_stamp_n] = features_time_stamp_n
    if self.inter:
      self.result[self.feature_key_inter] = features_inter
    if self.intra:
      self.result[self.feature_key_intra] = features_intra

class batchAdvancer(object):

  def __init__(self, extractors):
    self.extractors = extractors
    self.increment_extractor = extractors[0]

  def __call__(self):
    #The batch advancer just calls each extractor
    next_batch = self.increment_extractor.increment()
    for e in self.extractors:
      e.get_data(next_batch)

class python_data_layer(caffe.Layer):
  """ General class to extract data.
  """

  def setup(self, bottom, top):
    random.seed(10)
    self.params = eval(self.param_str)
    params = self.params

    assert 'top_names' in params.keys()

    #set up prefetching
    self.thread_result = {}
    self.thread = None

    self.setup_extractors()

    self.batch_advancer = batchAdvancer(self.data_extractors)
    shape_dict = {}
    self.top_names = []
    for de in self.data_extractors:
      for top_name, top_shape in zip(de.top_keys, de.top_shapes):
        shape_dict[top_name] = top_shape
        self.top_names.append((params['top_names'].index(top_name), top_name))

    self.dispatch_worker()

    self.top_shapes = [shape_dict[tn[1]] for tn in self.top_names]

    print 'Outputs:', self.top_names
    if len(top) != len(self.top_names):
      raise Exception('Incorrect number of outputs (expected %d, got %d)' %
                      (len(self.top_names), len(top)))
    self.join_worker()
    #for top_index, name in enumerate(self.top_names.keys()):

    top_count = 0
    for top_index, name in self.top_names:
      shape = self.top_shapes[top_count]
      print 'Top name %s has shape %s.' %(name, shape)
      top[top_index].reshape(*shape)
      top_count += 1

  def reshape(self, bottom, top):
    pass

  def forward(self, bottom, top):
    if self.thread is not None:
      self.join_worker()

    for top_index, name in self.top_names:
      top[top_index].data[...] = self.thread_result[name]

    self.dispatch_worker()

  def dispatch_worker(self):
    assert self.thread is None
    self.thread = Thread(target=self.batch_advancer)
    self.thread.start()

  def join_worker(self):
    assert self.thread is not None
    self.thread.join()
    self.thread = None

  def backward(self, top, propoagate_down, bottom):
    pass

feature_process_dict = {'feature_process_base': feature_process_base,
                        'feature_process_norm': feature_process_norm,
                        'feature_process_context': feature_process_context,
                        }

language_feature_process_dict = {'zero_language': zero_language_vector,
                                 'recurrent_embedding': recurrent_embedding}

class dataLayer_ExtractPairedLanguageVision(python_data_layer):

  def setup_extractors(self):
    assert 'top_names' in self.params.keys()
    assert 'descriptions' in self.params.keys()
    assert 'features' in self.params.keys()
    if 'batch_size' not in self.params.keys(): self.params['batch_size'] = 120

    self.params['query_key'] = 'query'
    self.params['feature_key_n'] = 'features_n'
    self.params['feature_key_p'] = 'features_p'
    self.params['feature_key_t'] = 'features_t'
    self.params['feature_time_stamp_p'] = 'features_time_stamp_p'
    self.params['feature_time_stamp_n'] = 'features_time_stamp_n'
    self.params['cont_key'] = 'cont'

    language_extractor_fcn = extractLanguageFeatures
    visual_extractor_fcn = extractVisualFeatures
    language_process = recurrent_embedding

    data_orig = read_json(self.params['descriptions'])
    random.shuffle(data_orig)
    language_processor = language_process(data_orig)
    data = language_processor.preprocess(data_orig)
    self.params['vocab_dict'] = language_processor.vocab_dict
    num_glove_centroids = language_processor.get_vector_dim()
    self.params['num_glove_centroids'] = num_glove_centroids
    visual_feature_extractor = visual_extractor_fcn(data, self.params, self.thread_result)
    textual_feature_extractor = language_extractor_fcn(data, self.params, self.thread_result)
    self.data_extractors = [visual_feature_extractor, textual_feature_extractor]

ext: py

max_stars_repo_name: LisaAnne/LocalizingMoments

max_issues_repo_name: Naman-Bhalla/LocalizingMoments

max_forks_repo_name: Naman-Bhalla/LocalizingMoments

reason: import numpy


text:
import chainer
import chainer.functions as F
import chainer.links as L

import onnx
import onnx.helper as oh
from onnx import numpy_helper
from onnx import TensorProto
from onnx import ModelProto

from chainer_compiler.elichika.parser import core
from chainer_compiler.elichika.parser import graphs
from chainer_compiler.elichika.parser import values
from chainer_compiler.elichika.parser import nodes
from chainer_compiler.elichika.parser import functions
from chainer_compiler.elichika.parser import functions_builtin
from chainer_compiler.elichika.parser import utils

import numpy as np
import collections

from chainer_compiler.elichika import onnx_converters as oc

def _pair(x):
    if isinstance(x, collections.Iterable):
        return x
    return (x, x)

def _list(v) -> 'List[int]':
    if isinstance(v, collections.Iterable):
        return list(x for x in v)
    return [v]

def get_onnx_dtype(dtype):
    a = np.zeros((), dtype=dtype)
    dt = onnx.mapping.NP_TYPE_TO_TENSOR_TYPE[a.dtype]
    return dt

class BaseConverter(object):
    def __init__(self):
        self.expected_args = ()

    def parse_args(self, onnx_graph, node):
        assert hasattr(self, 'expected_args'), 'BaseConverter subclass must have `expected_args`'
        parser =  oc.NodeParse()
        for arg_def in self.expected_args:
            parser.add_def(*arg_def)
        parser.parse(onnx_graph, node)
        return parser

    def __call__(self, onnx_graph, node):
        raise NotImplementedError

class ConverterRelu(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),)

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            'Relu',
            [parser.get('x')],
            node.outputs,
            name=str(node.lineprop))

class ConverterElu(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('alpha', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            'Elu',
            [parser.get('x')],
            node.outputs,
            name=str(node.lineprop),
            alpha=parser.get('alpha'))

class ConverterLeakyRelu(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('slope', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            'LeakyRelu',
            [parser.get('x')],
            node.outputs,
            name=str(node.lineprop),
            alpha=parser.get('slope'))

class ConverterChainerMathMisc(BaseConverter):
    def __init__(self, operator):
        self.expected_args = (
            ('x', oc.ParseType.In),)
        self.operator = operator

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            self.operator,
            [parser.get('x')],
            node.outputs,
            name=str(node.lineprop))

class ConverterSigmoid(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),)

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            'Sigmoid',
            [parser.get('x')],
            node.outputs,
            name=str(node.lineprop))

def convert_argminmax(onnx_graph, node, parser, tensor, operator, dtype):
    axis = parser.get('axis')

    if axis is None:
        (reshaped,) = onnx_graph.add_node(
        'Reshape',
        [parser.get(tensor), oc.ONNXValue(onnx_graph, np.array([-1], dtype=np.int64), [node, '/Minus1'])],
        [None],
        str(node.lineprop))

        (minmax,) = onnx_graph.add_node(
            operator,
            [reshaped],
            [None],
            str(node.lineprop),
            axis=0)

        (squeesed,) = onnx_graph.add_node(
            'Squeeze',
            [minmax],
            [None],
            str(node.lineprop))

        onnx_graph.add_node(
            "Cast",
            [squeesed],
            node.outputs,
            str(node.lineprop),
            to=get_onnx_dtype(dtype))

    else:
        (minmax,) = onnx_graph.add_node(
            operator,
            [parser.get(tensor)],
            [None],
            str(node.lineprop),
            keepdims=False,
            axis=axis)

        onnx_graph.add_node(
            "Cast",
            [minmax],
            node.outputs,
            str(node.lineprop),
            to=get_onnx_dtype(dtype))

class ConverterChainerArgMax(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('axis', oc.ParseType.Att),
            )

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)
        convert_argminmax(onnx_graph, node, parser, 'x', 'ArgMax', np.int32)

class ConverterArgMax(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('a', oc.ParseType.In),
            ('axis', oc.ParseType.Att),
            ('out', oc.ParseType.Att, None),
            )

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)
        convert_argminmax(onnx_graph, node, parser, 'a', 'ArgMax', np.int64)

class ConverterChainerArgMin(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('axis', oc.ParseType.Att),
            )

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)
        convert_argminmax(onnx_graph, node, parser, 'x', 'ArgMin', np.int32)

class ConverterArgMin(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('a', oc.ParseType.In),
            ('axis', oc.ParseType.Att),
            ('out', oc.ParseType.Att, None),
            )

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)
        convert_argminmax(onnx_graph, node, parser, 'a', 'ArgMin', np.int64)

class ConverterChainerMaximum(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x1', oc.ParseType.In),
            ('x2', oc.ParseType.In),
            )

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)
        onnx_graph.add_node(
            "Max",
            [parser.get('x1'), parser.get('x2')],
            node.outputs,
            str(node.lineprop))

class ConverterMaximum(ConverterChainerMaximum):
    def __init__(self):
        super().__init__()
        self.expected_args += (
            ('out', oc.ParseType.Att, None),
            ('where', oc.ParseType.Att, True),
            ('casting', oc.ParseType.Att, 'same_kind'),
            ('order', oc.ParseType.Att, 'K'),
            ('dtype', oc.ParseType.Att, None),
            ('subok', oc.ParseType.Att, True),
            )

class ConverterChainerMinimum(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x1', oc.ParseType.In),
            ('x2', oc.ParseType.In),
            )

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)
        onnx_graph.add_node(
            "Min",
            [parser.get('x1'), parser.get('x2')],
            node.outputs,
            str(node.lineprop))

class ConverterMinimum(ConverterChainerMinimum):
    def __init__(self):
        super().__init__()
        self.expected_args += (
            ('out', oc.ParseType.Att, None),
            ('where', oc.ParseType.Att, True),
            ('casting', oc.ParseType.Att, 'same_kind'),
            ('order', oc.ParseType.Att, 'K'),
            ('dtype', oc.ParseType.Att, None),
            ('subok', oc.ParseType.Att, True),
            )

class ConverterSum(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('axis', oc.ParseType.Att),
            ('keepdims', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        kwargs = {}
        axis = parser.get('axis')

        if isinstance(axis, int):
            kwargs['axes'] = [axis]
        elif axis is not None:
            kwargs['axes'] = list(axis)

        onnx_graph.add_node(
            "ReduceSum",
            [parser.get('x')],
            node.outputs,
            str(node.lineprop),
            keepdims=parser.get('keepdims'),
            **kwargs)

class ConverterAverage(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('axis', oc.ParseType.Att),
            ('weights', oc.ParseType.Att, None),
            ('keepdims', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        kwargs = {}
        axis = parser.get('axis')

        if isinstance(axis, int):
            kwargs['axes'] = [axis]
        elif axis is not None:
            kwargs['axes'] = list(axis)

        onnx_graph.add_node(
            "ReduceMean",
            [parser.get('x')],
            node.outputs,
            str(node.lineprop),
            keepdims=parser.get('keepdims'),
            **kwargs)

class ConverterSoftmax(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('axis', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            'Softmax',
            [parser.get('x')],
            node.outputs,
            name=str(node.lineprop),
            axis=parser.get('axis'),
            chainer_is_onnx_semantics=False)

class ConverterPadSequence(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('xs', oc.ParseType.In),
            ('length', oc.ParseType.Att),
            ('padding', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        kwargs = {}
        if parser.get('length') is not None:
            kwargs['length'] = parser.get('length')
        if parser.get('padding') is not None:
            kwargs['value'] = float(parser.get('padding'))

        onnx_graph.add_node(
            'ChainerSequencePad',
            [parser.get('xs')],
            node.outputs,
            name=str(node.lineprop),
            **kwargs)

class ConverterDropout(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('ratio', oc.ParseType.Att),
            ('kwargs', oc.ParseType.Ignore))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            "Dropout",
            [parser.get('x')],
            node.outputs,
            name=str(node.lineprop),
            ratio=parser.get('ratio'))

class ConverterMatMul(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('a', oc.ParseType.In),
            ('b', oc.ParseType.In),
            ('transa', oc.ParseType.Att, False),
            ('transb', oc.ParseType.Att, False))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        assert(parser.get('transa') == False) # TODO(hamaji): Not supported yet.
        assert(parser.get('transb') == False) # TODO(hamaji): Not supported yet.

        onnx_graph.add_node(
            "MatMul",
            [parser.get('a').create_tensor(node.lineprop), parser.get('b').create_tensor(node.lineprop)],
            node.outputs,
            name=str(node.lineprop))

class ConverterConcat(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('xs', oc.ParseType.In),
            ('axis', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            "ChainerSequenceConcat",
            [parser.get('xs').create_sequence()],
            node.outputs,
            str(node.lineprop),
            axis=parser.get('axis'))

class ConverterSoftmaxCrossEntropy(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('t', oc.ParseType.In),
            ('normalize', oc.ParseType.Att),
            ('cache_score', oc.ParseType.Att),
            ('class_weight', oc.ParseType.Att),
            ('ignore_label', oc.ParseType.Att),
            ('reduce', oc.ParseType.Att),
            ('enable_double_backprop', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        kwargs = {}
        assert parser.get('normalize')  # TODO(hamaji): Not supported yet.
        assert parser.get('cache_score')  # TODO(hamaji): Not supported yet.
        assert parser.get('class_weight') is None  # TODO(hamaji): Not supported yet.
        assert parser.get('ignore_label') == -1  # TODO(hamaji): Not supported yet.
        assert parser.get('reduce') == 'mean'  # TODO(hamaji): Not supported yet.
        assert not parser.get('enable_double_backprop')  # TODO(hamaji): Not supported yet.

        onnx_graph.add_node(
            "ChainerSoftmaxCrossEntropy",
            [parser.get('x'), parser.get('t')],
            node.outputs,
            str(node.lineprop),
            **kwargs)

class ConverterMaxPooling2D(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('ksize', oc.ParseType.AttPad),
            ('stride', oc.ParseType.AttPad),
            ('pad', oc.ParseType.AttPad),
            ('cover_all', oc.ParseType.Att),
            ('return_indices', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        assert not parser.get('return_indices')  # TODO(hamaji): Not implemented yet.

        kwargs = {}
        kwargs['kernel_shape'] = parser.get('ksize')
        if parser.get('stride') is not None:
            kwargs['strides'] = parser.get('stride')
        else:
            kwargs['strides'] = parser.get('ksize')

        if parser.get('pad') is not None:
            kwargs['pads'] = parser.get('pad') *2
        else:
            kwargs['pads'] = _pair(0)

        onnx_graph.add_node(
            "MaxPool",
            [parser.get('x')],
            node.outputs,
            name=str(node.lineprop),
            chainer_cover_all=parser.get('cover_all'),
            **kwargs)

class ConverterAveragePool2D(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('ksize', oc.ParseType.AttPad),
            ('stride', oc.ParseType.AttPad),
            ('pad', oc.ParseType.AttPad))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        kwargs = {}
        kwargs['kernel_shape'] = parser.get('ksize')
        if parser.get('stride') is not None:
            kwargs['strides'] = parser.get('stride')
        else:
            kwargs['strides'] = parser.get('ksize')

        if parser.get('pad') is not None:
            kwargs['pads'] = parser.get('pad') *2
        else:
            kwargs['pads'] = _pair(0)

        kwargs['count_include_pad'] = 1

        onnx_graph.add_node(
            "AveragePool",
            [parser.get('x')],
            node.outputs,
            name=str(node.lineprop),
            **kwargs)

class ConverterUnpooling2D(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('ksize', oc.ParseType.Att),
            ('stride', oc.ParseType.Att),
            ('pad', oc.ParseType.Att),
            ('outsize', oc.ParseType.Att),
            ('cover_all', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        kwargs = {}
        assert(parser.get('stride') is None) # TODO(hamaji): Not supported yet.
        assert(parser.get('pad') == 0) # TODO(hamaji): Not supported yet.
        assert(parser.get('outsize') is None) # TODO(hamaji): Not supported yet.
        assert(parser.get('cover_all') is False) # TODO(hamaji): Not supported yet.

        scales = np.array([1, 1] + list(_pair(parser.get('ksize'))), dtype=np.float32)
        scales_ = oc.ONNXValue(onnx_graph, scales, [node, '/Scale'], is_constant = True)
        onnx_graph.add_node(
            "Upsample",
            [parser.get('x'), scales_],
            node.outputs,
            name=str(node.lineprop),
            **kwargs)

class ConverterResizeImages(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('output_shape', oc.ParseType.Att),
            ('mode', oc.ParseType.Att),
            ('align_corners', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        assert(parser.get('mode') == 'bilinear')  # TODO(hamaji): Not supported yet.
        assert(parser.get('align_corners') == True)  # TODO(hamaji): Not supported yet.

        onnx_graph.add_node(
            "ChainerResizeImages",
            [parser.get('x')],
            node.outputs,
            name=str(node.lineprop),
            output_shape=parser.get('output_shape'))

class ConverterVstack(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('xs', oc.ParseType.In),)

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            "ChainerSequenceConcat",
            [parser.get('xs').create_sequence()],
            node.outputs,
            name=str(node.lineprop),
            axis=0)

class ConverterHstack(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('xs', oc.ParseType.In),)

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            "ChainerSequenceConcat",
            [parser.get('xs').create_sequence()],
            node.outputs,
            name=str(node.lineprop),
            axis=1)

class ConverterStack(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('xs', oc.ParseType.In),
            ('axis', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            "ChainerSequenceStack",
            [parser.get('xs').create_sequence()],
            node.outputs,
            name=str(node.lineprop),
            axis=parser.get('axis'))

class ConverterSeparate(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('axis', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            "ChainerSequenceSeparate",
            [parser.get('x').create_tensor(node.lineprop)],
            node.outputs,
            name=str(node.lineprop),
            axis=parser.get('axis'))

class ConverterSqueeze(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('axis', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        kwargs = {}
        if parser.get('axis') is not None:
            kwargs['axes'] = _list(parser.get('axis'))

        onnx_graph.add_node(
            "Squeeze",
            [parser.get('x').create_tensor(node.lineprop)],
            node.outputs,
            name=str(node.lineprop),
            **kwargs)

class ConverterReshape(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('shape', oc.ParseType.In))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            "Reshape",
            [parser.get('x'), parser.get('shape').create_tensor(node.lineprop)],
            node.outputs,
            name=str(node.lineprop))

class ConverterSplitAxis(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('indices_or_sections', oc.ParseType.In),
            ('axis', oc.ParseType.Att),
            ('force_tuple', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        kwargs = {}
        assert(parser.get('force_tuple') is True) # TODO(hamaji): Not supported yet.

        onnx_graph.add_node(
            "ChainerSequenceSplitAxis",
            [parser.get('x'), parser.get('indices_or_sections').create_tensor(node.lineprop)],
            node.outputs,
            name=str(node.lineprop),
            axis=parser.get('axis'),
            **kwargs)

class ConverterSwapaxes(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('axis1', oc.ParseType.Att),
            ('axis2', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        axis1 = parser.get('axis1')
        axis2 = parser.get('axis2')
        pe = list(range(max(axis1, axis2)+1))
        pe[axis1] = axis2
        pe[axis2] = axis1

        onnx_graph.add_node(
            "Transpose",
            [parser.get('x')],
            node.outputs,
            name=str(node.lineprop),
            perm=pe)

class ConverterRoiMaxPooling2D(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('rois', oc.ParseType.In),
            ('roi_indices', oc.ParseType.In),
            ('outsize', oc.ParseType.AttPad),
            ('spatial_scale', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            "ChainerROIMaxPool2D",
            [parser.get('x').create_tensor(node.lineprop), parser.get('rois').create_tensor(node.lineprop), parser.get('roi_indices').create_tensor(node.lineprop)],
            node.outputs,
            str(node.lineprop),
            output_shape=parser.get('outsize'),
            spatial_scale=parser.get('spatial_scale'))

class ConverterRoiAveragePooling2D(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('rois', oc.ParseType.In),
            ('roi_indices', oc.ParseType.In),
            ('outsize', oc.ParseType.AttPad),
            ('spatial_scale', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            "ChainerROIAveragePool2D",
            [parser.get('x').create_tensor(node.lineprop), parser.get('rois').create_tensor(node.lineprop), parser.get('roi_indices').create_tensor(node.lineprop)],
            node.outputs,
            str(node.lineprop),
            output_shape=parser.get('outsize'),
            spatial_scale=parser.get('spatial_scale'))

class ConverterRoiMaxAlign2D(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('rois', oc.ParseType.In),
            ('roi_indices', oc.ParseType.In),
            ('outsize', oc.ParseType.AttPad),
            ('spatial_scale', oc.ParseType.Att),
            ('sampling_ratio', oc.ParseType.AttPad))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            "ChainerROIMaxAlign2D",
            [parser.get('x').create_tensor(node.lineprop), parser.get('rois').create_tensor(node.lineprop), parser.get('roi_indices').create_tensor(node.lineprop)],
            node.outputs,
            str(node.lineprop),
            output_shape=parser.get('outsize'),
            spatial_scale=parser.get('spatial_scale'),
            sampling_ratio=parser.get('sampling_ratio'))

class ConverterRoiAverageAlign2D(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('rois', oc.ParseType.In),
            ('roi_indices', oc.ParseType.In),
            ('outsize', oc.ParseType.AttPad),
            ('spatial_scale', oc.ParseType.Att),
            ('sampling_ratio', oc.ParseType.AttPad))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            "ChainerROIAverageAlign2D",
            [parser.get('x').create_tensor(node.lineprop), parser.get('rois').create_tensor(node.lineprop), parser.get('roi_indices').create_tensor(node.lineprop)],
            node.outputs,
            str(node.lineprop),
            output_shape=parser.get('outsize'),
            spatial_scale=parser.get('spatial_scale'),
            sampling_ratio=parser.get('sampling_ratio'))

class ConverterBroadcastTo(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('shape', oc.ParseType.In))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            "Expand",
            [parser.get('x'), parser.get('shape').create_tensor(node.lineprop)],
            node.outputs,
            name=str(node.lineprop))

class ConverterExpandDims(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('axis', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        onnx_graph.add_node(
            "Unsqueeze",
            [parser.get('x')],
            node.outputs,
            name=str(node.lineprop),
            axes=[int(parser.get('axis'))])

class ConverterResponseNormalization(BaseConverter):
    def __init__(self):
        self.expected_args = (
            ('x', oc.ParseType.In),
            ('n', oc.ParseType.Att),
            ('k', oc.ParseType.Att),
            ('alpha', oc.ParseType.Att),
            ('beta', oc.ParseType.Att))

    def __call__(self, onnx_graph, node):
        parser = self.parse_args(onnx_graph, node)

        kwargs = {}
        kwargs['size'] = parser.get('n')
        kwargs['bias'] = float(parser.get('k'))
        kwargs['alpha'] = float(parser.get('alpha') * kwargs['size'])
        kwargs['beta'] = float(parser.get('beta'))

        onnx_graph.add_node(
            "LRN",
            [parser.get('x')],
            node.outputs,
            name=str(node.lineprop),
            **kwargs)

max_stars_repo_name: okdshin/chainer-compiler

max_issues_repo_name: okdshin/chainer-compiler

max_forks_repo_name: okdshin/chainer-compiler


text:
import spectral as sp
import os
import test_algorithm as ta
import numpy as np
import pandas as pd
import math
from glob import glob

bands_init = []
bands_end = []
#define switch
testOxi = 1

#check the data. And got acc txt file.

def dataProcess_alg_pass(SP):
    return SP

# useless, rewriten in test_algorithm
def check(SP_ref_oxido, SP_ref_sulfuro, check_all = 0, dataProcess_alg = dataProcess_alg_pass):
    if check_all == 1:
        filePath = 'data/'
        files_list_oxi = glob(filePath + 'oxidos/'+"*.hdr")
        files_list_sul = glob(filePath + 'sulfuros/'+'*.hdr')
        num_oxi = len(files_list_oxi)
        num_sul = len(files_list_sul)

        #accuracy dict, the index is testing files' name and values is a list [single_SP, all_SP]
        acc_dict_oxi = {}
        acc_dict_sul = {}

        #switch
        global testOxi
        #check all the oxidos.
        for i in range(num_oxi):
            if testOxi == 0:
                break
            index0 = files_list_oxi[i].split('Esc')[-1].split('Ox')[-1][0:2]
            # u could also achieve this by :
            #
                # if i < 10:
                    # i = str('0' + str(i))
                # else:
                    # i = str(i)
            img_testing = ta.input_testing_data(index = index0, type = 'oxido', check_all = check_all)

            #core alg of check
            # ////////SP_ref_oxido, SP_ref_sulfuro = input_training_data(use_multi_SP_as_reference = 1)
            res, accurarcy = ta.Tranversing(SP_ref_oxido, SP_ref_sulfuro, img_testing, testingType = 'oxido', dataProcess_alg = dataProcess_alg)
            acc_dict_oxi.setdefault(str(img_testing).split('/')[2].split('_')[0] + '_res.bmp',[])
            acc_dict_oxi[str(img_testing).split('/')[2].split('_')[0] + '_res.bmp'].append(accurarcy)

            #showing the progress

            acc_key = str(img_testing).split('/')[2].split('_')[0] + '_res.bmp'
            print('%s   %f   \n' % (acc_key, acc_dict_oxi[acc_key][0] ))

        #check all the sulfuros
        for i in range(num_sul):

            index0 = files_list_sul[i].split('Esc')[-1].split('Sulf')[-1][0:2] # after split('Esc'), u got a list containing only one element.... x[0] == x[-1]
            img_testing = ta.input_testing_data(index = index0, type = 'sulfuro', check_all = check_all)

            #core alg of check
            # /////SP_ref_oxido, SP_ref_sulfuro = input_training_data(use_multi_SP_as_reference = 0)
            res, accurarcy = ta.Tranversing(SP_ref_oxido, SP_ref_sulfuro, img_testing,  testingType = 'sulfuro', dataProcess_alg = dataProcess_alg)
            acc_dict_sul.setdefault(str(img_testing).split('/')[2].split('_')[0] + '_res.bmp',[])
            acc_dict_sul[str(img_testing).split('/')[2].split('_')[0] + '_res.bmp'].append(accurarcy)

            #showing the progress
            acc_key = str(img_testing).split('/')[2].split('_')[0] + '_res.bmp'
            print('%s   %f   \n' % (acc_key, acc_dict_sul[acc_key][0] ))

        #write the results into txt
        file_res = open(filePath + '3paras_accuracy_non_normalized.txt', 'w')
        file_res.write('fileName \t \t Accuracy\n')
        for i in acc_dict_oxi.keys():
            file_res.write("%s \t %f\n" % (i,acc_dict_oxi[i][0]))
        for i in acc_dict_sul.keys():
            file_res.write("%s \t %f\n" % (i,acc_dict_sul[i][0]))
    elif check_all == 0:

        #input testing data
        img_testing = input_testing_data()

        # tranversing the img and cal spectral angle between testImg and refImg.
        #Input: testing img and reference img.
        if 'Sulf' in str(img_testing):
            res, accurarcy = Tranversing(SP_ref_oxido,SP_ref_sulfuro, img_testing, 2)

        else:
            res, accurarcy = Tranversing(SP_ref_oxido,SP_ref_sulfuro, img_testing, 1)

        width, height, deepth = img_testing.shape

        resName = str(img_testing).split('/')[2].split('_')[0] + '_res.bmp'
        filePath = 'data/'
        show_res(res,accurarcy, width, height, filePath, resName, showImg = 0)

#convert the dictionary to dataFrame.
def dict_to_dataFrame(para_dict, support_now = 0):
    if len(para_dict) > 1:
        print('did not support multiple wavelength input now, auto calculate the first band you input.')
        for key in sorted(para_dict.keys()):
            return para_dict[key]
    else:
        for key in sorted(para_dict.keys()):
            return para_dict[key]
    if support_now == 1:
        df = pd.DataFrame(para_dict)
        df = df.transpose()
        return df
# input an para dict, return a list containing all its data. para_dict['band1']['AA'] = ...
#para_list = [1,2,3,0.1.....]
def dict_to_list(para_dict):

    para_list = []
    for i in para_dict.keys() :
        for j in para_dict[i].keys():
            para_list.append(para_dict[i][j])

    return para_list

#input three arrays and normalize them, return three normalized arrays.
def normalize(arr1,arr2, arr3):

    arr_length = len(arr1)
    assert len(arr1) == len(arr2) and len(arr2) == len(arr3), 'length of your three arrays to be normalized is not equal! \n'
    for i in range(arr_length):
        value_list = [arr1[i], arr2[i], arr3[i]]
        max_value = max(value_list)
        min_value = min(value_list)
        if max_value == min_value:
            arr1[i] = 1
            arr2[i] = 1
            arr3[i] = 1
            continue
        arr1[i] = ( arr1[i] - min_value ) / (max_value - min_value)
        arr2[i] = ( arr2[i] - min_value ) / (max_value - min_value)
        arr3[i] = ( arr3[i] - min_value ) / (max_value - min_value)

    return [arr1, arr2, arr3]

#load average sulfuros data, return a spectrum array.
def load_training_SP(type = 'sulfuro'):
    filePath = 'data/'
    # fileName = 'sulfuros/'

    fileNameList =  os.listdir(filePath + type +'s/') #  glob(filePath + 'sulfuros/' + '*.hdr')

    fileName_aver = 'spectrum_average.txt'
    if fileName_aver in fileNameList :
        file_temp = open(filePath + type + 's/' + fileName_aver)
        sp_average = file_temp.read()
        sp_average = sp_average.replace('[', '')
        sp_average = sp_average.replace(']', '')
        sp_average = sp_average.split()
        file_temp.close()
        return np.array(sp_average ,dtype = np.float)
    else:
        file_temp = sp.open_image(filePath + type + 's/' + fileNameList[1])
        file_temp.close()
        pass
    sp.open_image(filePath + fileName)

def rectify(sp_ABP_band, minRef_index):
    sp_rec = []
    initial_left = 0
    initial_right = len(sp_ABP_band)
    maxRef_left = max(sp_ABP_band[:minRef_index])
    maxRef_right = max(sp_ABP_band[minRef_index:])

    for i in range(len(sp_ABP_band)):
        if sp_ABP_band[i] == maxRef_left and i < minRef_index:
            initial_left = i
        if sp_ABP_band[i] == maxRef_right and i > minRef_index:
            initial_right = i

    sp_rec = sp_ABP_band[initial_left:initial_right+1]

    return sp_rec

# input auto_set, default 1 and set the ABPs (absorption bands) are set mannually
# type controls the ABP bands' difference between sulf and oxi. (tho no differences now.)
# sp is a spectrum.
def choose_ABP_bands(sp, auto_set = 1, type = 'sulfuro', choose_band = [1,1,1], wavelength = None):

    global bands_init
    global bands_end
    sp_reso = 256
    sp_range = (928.08,2530.1500)
    sp_index_reso = (sp_range[1] - sp_range[0])/ sp_reso

    if wavelength != None:
        ABP_bands = []
        for band in wavelength:
            waveInit = band[0] - sp_range[0]
            waveEnd = band[1] - sp_range[0]
            indexInit = int(waveInit/sp_index_reso)
            indexEnd = int(waveEnd/sp_index_reso)
            bands_init.append(indexInit)
            bands_end.append(indexEnd)
            ABP_bands.append(sp[indexInit:indexEnd])
        return ABP_bands
    #sp's sampling interval is around 6.3 um, not continuous. 928.08 - 2530.1500
    #attention, need to set the bands automatically.
    ABP_bands_sulf = []
    ABP_bands_oxi = []
    for i in range(len(choose_band)):
        if choose_band[i] == 1 and i==0:
            ABP_bands_sulf.append(sp[51:91])  # see at band excel, starting from 1;   52-92  1250um-1500um
            ABP_bands_oxi.append(sp[51:91])
            continue
        if choose_band[i] == 1 and i==1:
            ABP_bands_sulf.append(sp[138:171])  # 1800:2000 ,139-172
            ABP_bands_oxi.append(sp[138:171])
            continue
        if choose_band[i] == 1 and i==2:
            ABP_bands_sulf.append(sp[186:211])  # 2100:2250 , 187-212
            ABP_bands_oxi.append(sp[186:211])
            continue

        if type == 'sulfuro':
            return ABP_bands_sulf
        if type == 'oxido':
            return ABP_bands_oxi

#input absorption bands(some specific area) of a spectrum, and return these bands' paras
def cal_SP_paras(ABP_bands_SP):

    global bands_init, bands_end

    #the key of band_index is 0-255, value is wavelength
    band_index = {}

    step = int ((2530.15-928.08)/ 256)
    for i in range(256):
        band_index.setdefault(i, 928.08 + i* step)

    #para_dict is a dict containing absorption info of a spectrum. para_dict[band1][AD] = xxxx,  para_dict[band2][SAI]
    para_dict = {}
    for i in range(len(ABP_bands_SP)):
        # key_temp = 'band' + str(ABP_bands_SP[i][0]) + '-' str(ABP_bands_SP[i][1])  this is band1250-1500
        key_temp = 'band' + str(i+1) # this is band1, band2

        para_dict.setdefault(key_temp, {})
        # set initial value to para_dict
        para_dict[key_temp].setdefault('AP', 0)
        para_dict[key_temp].setdefault('AD', 0)
        para_dict[key_temp].setdefault('AW', 0)
        para_dict[key_temp].setdefault('AA', 0)
        para_dict[key_temp].setdefault('AS', 0)
        para_dict[key_temp].setdefault('SAI', 0)

        ####################################cal paras of ABP bands.###########################################

        #cal AP, ABP position.
        minRef = min(ABP_bands_SP[i])
        maxRef = max(ABP_bands_SP[i])
        minRef_index = -1
        for j in range(len(ABP_bands_SP[i])):
            if ABP_bands_SP[i][j] == minRef:
                minRef_index = j
        AP = band_index[  j + bands_init[i]   ]

        #cal AD, ABP deepth
        AD = maxRef - minRef

        #cal AW, ABP width
        right_half_point = 0
        left_half_point = 0

        for j in range(len(ABP_bands_SP[i])-1):
            midRef = (minRef + maxRef) / 2
            if ABP_bands_SP[i][j] >= midRef and ABP_bands_SP[i][j+1] < midRef:
                left_half_point = j
            if ABP_bands_SP[i][j] <= midRef and ABP_bands_SP[i][j+1] > midRef :
                right_half_point = j
        AW = abs(right_half_point - left_half_point) * step

        # before compute AA, SAI, AS, u should rectify ABP bands, let correct and precise shoulder be the left and right initial.
        ABP_bands_SP[i] = rectify(ABP_bands_SP[i], minRef_index)

        #cal AA
        AA = 0.0
        for j in range(len(ABP_bands_SP[i])):
            AA += 1 - ABP_bands_SP[i][j]

        #cal AS
        leftArea = 0.0
        rightArea = 0.0
        for j in range(len(ABP_bands_SP[i])):
            if j < minRef_index:
                leftArea += 1 - ABP_bands_SP[i][j]
            else:
                rightArea += 1 - ABP_bands_SP[i][j]
        if leftArea == 0:
            AS = 0
        else:
            AS = math.log1p(rightArea/ leftArea )

        #cal SAI
        d = (AP - band_index[bands_init[i]])/(band_index[bands_end[i]] - band_index[bands_init[i]])
        upside = ( d * ABP_bands_SP[i][-1] )+  ( (1-d) * ABP_bands_SP[i][0] )
        downside = minRef
        SAI = upside / downside
        #########################################################################################################

        para_dict[key_temp]['AP'] = AP
        para_dict[key_temp]['AD'] = AD
        para_dict[key_temp]['AW'] = AW
        para_dict[key_temp]['AA'] = AA
        para_dict[key_temp]['AS'] = AS
        para_dict[key_temp]['SAI'] = SAI
        # for end.

    return para_dict

def SP_paras(SP_array, type = 'sulfuro', choose_band = [1,1,1], wavelength = None):

    ABP_bands = choose_ABP_bands(SP_array, type = type, choose_band = choose_band, wavelength = wavelength)
    para_dict = cal_SP_paras(ABP_bands)
    return para_dict

if __name__ == '__main__':

    # 1. load sp data from img.
    sp_average_sul = load_training_SP(type = 'sulfuro')
    # 2. choose interesting area (absorption bands) in a spectrum
    sul_ABP_bands = choose_ABP_bands(sp_average_sul)
    # 3. Cal SP paras of this areas, and got the set of features.
    para_dict = cal_SP_paras(sul_ABP_bands)
    print("end\n")