# spectroscopy.py spectroscopy measurement class for use with a vector network analyzer
# JB/MP/AS@KIT 04/2015, 08/2015, 01/2016

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

import logging
from time import time

import numpy as np

import qkit

if qkit.module_available("matplotlib"):
    import matplotlib.pylab as plt
if qkit.module_available("scipy"):
    from scipy.optimize import curve_fit
    from scipy.interpolate import interp1d, UnivariateSpline
from qkit.analysis.resonator import Resonator as resonator
from qkit.gui.notebook.Progress_Bar import Progress_Bar
from qkit.measure.measurement_base import MeasureBase

##################################################################

class spectrum(MeasureBase):
    """
    Class for spectroscopy measurements with a VNA
    usage:
    m = spectrum(vna=vna1, sample=yoursample)

    m.set_x_parameters(arange(-0.05,0.05,0.01),'flux_coil_current',coil.set_current, unit = 'mA')  outer scan in 3D
    m.set_y_parameters(arange(4e9,7e9,10e6),'excitation_frequency',mw_src1.set_frequency, unit = 'Hz')

    m.landscape.generate_fit_function_xy(...) for 3D scan, can be called several times and appends the current landscape
    m.landscape.generate_fit_function_xz(...) for 2D or 3D scan, adjusts the vna freqs with respect to x

    m.measure_XX()
    """

    def __init__(self, vna, sample=None):
        super(spectrum, self).__init__(sample)

        self.vna = vna
        self.averaging_start_ready = "start_measurement" in self.vna.get_function_names() and "ready" in self.vna.get_function_names()
        if not self.averaging_start_ready: logging.warning(
                __name__ + ': With your VNA instrument driver (' + self.vna.get_type() + '), I can not see when a measurement is complete. So I only wait for a specific time and hope the VNA has finished. Please consider implemeting the necessary functions into your driver.')

        self.landscape = Landscape(vna=vna, spec=self)
        self._fit_resonator = False
        self._measurement_object.measurement_type = 'SpectroscopyMeasurement'
        self._views = []
        self._scan_time = False
        self._segments = [] # bool([]) == False

    def set_x_parameters(self, vec, coordname, set_obj, unit, dt=None):
        """
        Sets x-parameters for 2D and 3D scan.
        In a 3D measurement, the x-parameters will be the "outer" sweep meaning for every x value all y values are swept and for each (x,y) value the bias is swept according to the set sweep parameters.

        Parameters
        ----------
        vec: array_likes
            An N-dimensional array that contains the sweep values.
        coordname: string
            The coordinate name to be created as data series in the .h5 file.
        set_obj: obj
            An callable object to execute with vec-values.
        unit: string
            The unit name to be used in data series in the .h5 file.
        dt: float, optional
            The sleep time between x-iterations.

        Returns
        -------
        None
        """
        super(spectrum, self).set_x_parameters(vec, coordname, set_obj, unit, dt)
        if self.landscape.xylandscapes:
            self.landscape.delete_landscape_function_xy()
            logging.warning('xy landscape has been deleted')
        if self.landscape.xzlandscape_func:
            self.landscape.delete_landscape_function_xz()
            logging.warning('xz landscape has been deleted')

    def set_y_parameters(self, vec, coordname, set_obj, unit, dt=None):
        """
        Sets y-parameters for 2D and 3D scan.
        In a 3D measurement, the y-parameters will be the "inner" sweep meaning for every x value all y values are swept

        Parameters
        ----------
        vec: array_likes
            An N-dimensional array that contains the sweep values.
        coordname: string
            The coordinate name to be created as data series in the .h5 file.
        set_obj: obj
            An callable object to execute with vec-values.
        unit: string
            The unit name to be used in data series in the .h5 file.
        dt: float, optional
            The sleep time between y-iterations.

        Returns
        -------
        None
        """
        super(spectrum, self).set_y_parameters(vec, coordname, set_obj, unit, dt)
        if self.landscape.xylandscapes:
            self.landscape.delete_landscape_function_xy()
            logging.warning('xy landscape has been deleted')
        if self.landscape.xzlandscape_func:
            self.landscape.delete_landscape_function_xz()
            logging.warning('xz landscape has been deleted. You can switch this off if you whish.')

    def _prepare_measurement_devices(self):
        """
        all the relevant settings from the vna are updated and called
        """
        self.vna.get_all()
        self._nop = self.vna.get_nop()
        self._sweeptime_averages = self.vna.get_sweeptime_averages()
        try:
            self._segments = self.vna.get_segments()
        except AttributeError:
            self._segments = []
        if self._dim == 1 or not self.landscape.xzlandscape_func:  # normal scan
            self._freqpoints = self.vna.get_freqpoints()
        else:
            self._freqpoints = self.landscape.get_freqpoints_xz()
        if self.averaging_start_ready:
            self.vna.pre_measurement()

    # def _prepare_measurement_file_(self):
    #
    #     if not self._scan_time:
    #         self._data_freq = self._data_file.add_coordinate('frequency', unit='Hz')
    #         self._data_freq.add(self._freqpoints)
    #
    #     if self._scan_2D:
    #         if self._nop < 10:
    #             """creates view: plot middle point vs x-parameter, for qubit measurements"""
    #             self._views = [self._data_file.add_view("amplitude_midpoint", x=self._data_x, y=self._data_amp,
    #                                                     view_params=dict(transpose=True, default_trace=self._nop // 2, linecolors=[(200, 200, 100)])),
    #                            self._data_file.add_view("phase_midpoint", x=self._data_x, y=self._data_pha,
    #                                                     view_params=dict(transpose=True, default_trace=self._nop // 2, linecolors=[(200, 200, 100)]))]
    #
    #     if self._scan_time:
    #         self._data_x = self._data_file.add_coordinate('trace_number', unit='')
    #         self._data_x.add(np.arange(0, self.number_of_timetraces, 1))
    #
    #         self._data_amp = self._data_file.add_value_matrix('amplitude', x=self._data_x, y=self._data_time, unit='lin. mag.', save_timestamp=False)
    #         self._data_pha = self._data_file.add_value_matrix('phase', x=self._data_x, y=self._data_time, unit='rad.', save_timestamp=False)

    def measure_1D(self, rescan=True):
        """
        measure method to record a single (averaged) VNA trace, S11 or S21 according to the setting on the VNA
        rescan: If True (default), the averages on the VNA are cleared and a new measurement is started.
                If False, it will directly take the data from the VNA without waiting.
        """
        self._dim =1
        self._measurement_object.measurement_func = 'measure_1D'

        self._prepare_measurement_devices()
        if self._segments:
            f =  [self.Coordinate('frequency_%i' % i, unit='Hz', values=self._freqpoints[0 if i == 0 else self._segments[i - 1]:self._segments[i]]) for i in range(len(self._segments))]
            self._prepare_measurement_file(
                    [self.Data(P[0] % i, [f[i]], P[1], save_timestamp=P[2] and not i)
                     for i in range(len(self._segments)) for P in [["amplitude_%i","arb. unit",True],["phase_%i","rad",False],["real_%i","",False],["imag_%i","",False]]])
        else:
            f = self.Coordinate('frequency', unit='Hz', values=self._freqpoints)

            self._prepare_measurement_file([self.Data("real", [f], ""), self.Data("imag", [f], ""), self.Data("amplitude", [f], "arb. unit", save_timestamp=True),
                self.Data("phase", [f], "rad")])

        self._open_qviewkit(datasets=[] if len(self._segments)>4 else None)

        qkit.flow.start()
        if rescan:
            self._pb = Progress_Bar(self.vna.get_averages(), self.measurement_name, self.vna.get_sweeptime(), dummy=not self.progress_bar)
            if self.averaging_start_ready:
                self.vna.start_measurement()
                ti = time()
                qkit.flow.sleep(.2)
                while not self.vna.ready():
                    if time() - ti > self.vna.get_sweeptime(query=False):
                        self._pb.iterate()
                        ti = time()
                    qkit.flow.sleep(.2)
                while self._pb.progr < self._pb.max_it:
                    self._pb.iterate()
            else:
                self.vna.avg_clear()
                if self.vna.get_averages() == 1 or self.vna.get_Average() == False:  # no averaging
                    qkit.flow.sleep(self.vna.get_sweeptime())  # wait single sweep
                    self._pb.iterate()
                else:  # with averaging
                    if "avg_status" in self.vna.get_function_names():
                        for a in range(self.vna.get_averages()):
                            while self.vna.avg_status() <= a:
                                qkit.flow.sleep(.2)  # maybe one would like to adjust this at a later point
                            self._pb.iterate()
                    else:  # old style
                        for a in range(self.vna.get_averages()):
                            qkit.flow.sleep(self.vna.get_sweeptime())  # wait single sweep time
                            self._pb.iterate()

        data_amp, data_pha = self.vna.get_tracedata()
        data_real, data_imag = self.vna.get_tracedata('RealImag')

        self._append(data_amp,data_pha,data_real,data_imag)
        if self._fit_resonator:
            self._do_fit_resonator()
        self._end_measurement()

    def measure_2D(self):
        """
        measure method to record a (averaged) VNA trace, S11 or S21 according to the setting on the VNA
        for all parameters x_vec in x_obj
        """

        if self.landscape.xzlandscape_func:  # The vna limits need to be adjusted, happens in the frequency wrapper
            self._x_parameter.set_function = self.landscape.vna_frequency_wrapper(self._x_parameter.set_function)

        self._dim = 2
        self._measurement_object.measurement_func = 'measure_2D'

        self._prepare_measurement_devices()
        if self._segments:
            f =  [self.Coordinate('frequency_%i' % i, unit='Hz', values=self._freqpoints[0 if i == 0 else self._segments[i - 1]:self._segments[i]]) for i in range(len(self._segments))]
            self._prepare_measurement_file(
                    [self.Data(P[0] % i, [self._x_parameter,f[i]], P[1], save_timestamp=P[2] and not i)
                     for i in range(len(self._segments)) for P in [["amplitude_%i","arb. unit",True],["phase_%i","rad",False],["real_%i","",False],["imag_%i","",False]]])
        else:
            f = self.Coordinate('frequency', unit='Hz', values=self._freqpoints)

            self._prepare_measurement_file(
                    [self.Data("amplitude", [self._x_parameter, f], "arb. unit", save_timestamp=True), self.Data("phase", [self._x_parameter, f], "rad")])

        self._pb = Progress_Bar(len(self._x_parameter.values), '2D VNA sweep ' + self.measurement_name, self.vna.get_sweeptime_averages(),
                                dummy=not self.progress_bar)

        if self._nop < 10:
            # creates view: plot middle point vs x-parameter, for qubit measurements
            self._views = [self._data_file.add_view("amplitude_midpoint", x=self._x_parameter.hdf_dataset, y=self._datasets['amplitude'],
                                                    view_params=dict(transpose=True, default_trace=self._nop // 2, linecolors=[(200, 200, 100)])),
                self._data_file.add_view("phase_midpoint", x=self._x_parameter.hdf_dataset, y=self._datasets['phase'],
                                         view_params=dict(transpose=True, default_trace=self._nop // 2, linecolors=[(200, 200, 100)]))]
            self._open_qviewkit(['views/amplitude_midpoint', 'views/phase_midpoint'])
        else:
            self._views = []
            self._open_qviewkit(datasets=[] if len(self._segments)>4 else None)

        if self._fit_resonator:
            self._resonator = resonator(self._data_file.get_filepath())
        self._measure()

    def measure_3D(self):
        """
        measure full window of vna while sweeping x_set_obj and y_set_obj with parameters x_vec/y_vec. sweep over y_set_obj is the inner loop, for every value x_vec[i] all values y_vec are measured.

        optional: measure method to perform the measurement according to landscape, if set
        self.span is the range (in units of the vertical plot axis) data is taken around the specified funtion(s)
        note: make sure to have properly set x,y vectors before generating traces
        """
        if self.landscape.xzlandscape_func:  # The vna limits need to be adjusted, happens in the frequency wrapper
            self._x_parameter.set_function = self.landscape.vna_frequency_wrapper(self._x_parameter.set_function)

        self._dim = 3
        self._measurement_object.measurement_func = 'measure_3D'

        self._prepare_measurement_devices()
        if self._segments:
            f =  [self.Coordinate('frequency_%i' % i, unit='Hz', values=self._freqpoints[0 if i == 0 else self._segments[i - 1]:self._segments[i]]) for i in range(len(self._segments))]
            self._prepare_measurement_file(
                    [self.Data(P[0] % i, [self._x_parameter, self._y_parameter,f[i]], P[1], save_timestamp=P[2] and not i)
                     for i in range(len(self._segments)) for P in [["amplitude_%i","arb. unit",True],["phase_%i","rad",False],["real_%i","",False],["imag_%i","",False]]])
        else:
            f = self.Coordinate('frequency', unit='Hz', values=self._freqpoints)
            self._prepare_measurement_file([self.Data("amplitude", [self._x_parameter, self._y_parameter, f], "arb. unit", save_timestamp=True),
                self.Data("phase", [self._x_parameter, self._y_parameter, f], "rad")])

        self._open_qviewkit(datasets=[] if len(self._segments)>4 else None)

        if self._fit_resonator:
            self._resonator = resonator(self._data_file.get_filepath())

        if self.progress_bar:
            if self.landscape.xylandscapes:  # ToDo: This part could be part of the Landscape class
                truth = np.full((len(self._y_parameter.values), len(self._x_parameter.values)), False)  # first, nothing is selected:
                for e in self.landscape.xylandscapes:
                    if not e['blacklist']:
                        truth = np.logical_or(truth, (np.abs(self._y_parameter.values[:, np.newaxis] - e['center_points']) <= e['y_span'] / 2) *  # check y span
                                              (e['x_range'][0] <= self._x_parameter.values) * (self._x_parameter.values <= e['x_range'][1]))  # check x range

                for e in self.landscape.xylandscapes:
                    if e['blacklist']:  # exclude blacklisted areas
                        truth = np.logical_and(truth, np.logical_not(
                                (np.abs(self._y_parameter.values[:, np.newaxis] - e['center_points']) <= e['y_span'] / 2) * (
                                    e['x_range'][0] <= self._x_parameter.values) * (self._x_parameter.values <= e['x_range'][1])))
                points = np.sum(truth)
            else:
                points = len(self._x_parameter.values) * len(self._y_parameter.values)
            self._pb = Progress_Bar(points, '3D VNA sweep ' + self.measurement_name, self.vna.get_sweeptime_averages())
        else:
            self._pb = Progress_Bar(1, dummy=True)

        self._measure()

    def measure_timetrace(self):
        """
        measure method to record a single VNA timetrace, this only makes sense when span is set to 0 Hz!,
        tested only with KEYSIGHT E5071C ENA and its corresponding qkit driver
        LGruenhaupt 11/2016
        """
        #ToDo: move this to regular sweeps
        if self.vna.get_span() > 0:
            raise ValueError(__name__ + ': For timetrace scans, VNA span needs to be 0 Hz')
        if self.vna.get_Average():
            raise ValueError(__name__ + ': For timetrace scans, Averaging needs to be turned off.')
        self.vna.get_centerfreq()
        self._scan_time = True

        self._measurement_object.measurement_func = 'measure_timetrace'

        self._prepare_measurement_devices()

        t = self.Coordinate('time', unit='s', values=np.arange(0, self._nop, 1) * self.vna.get_sweeptime() / (self._nop - 1))
        f = self.Coordinate('frequency', unit='Hz', values=[self.vna.get_centerfreq()])
        iteration = self.Coordinate("trace_number", unit="", values=np.arange(0, self.number_of_timetraces, 1))

        self._prepare_measurement_file([self.Data("amplitude", [iteration, t], "arb. unit", save_timestamp=True), self.Data("phase", [iteration, t], "rad")],
                coords=f)

        self._pb = Progress_Bar(self.number_of_timetraces, 'VNA timetrace ' + self.measurement_name, self.vna.get_sweeptime_averages(),
                                dummy=not self.progress_bar)

        qkit.flow.start()
        try:
            """
            loop: x_obj with parameters from x_vec
            """

            for i, x in enumerate(self._x_parameter.values):
                self._x_parameter.set_function(x)
                qkit.flow.sleep(self._x_parameter.wait_time)

                self._acquire_log_functions()

                data_amp, data_pha = self._acquire_vna_data()
                self._datasets['amplitude'].append(data_amp)
                self._datasets['phase'].append(data_pha)
                qkit.flow.sleep()
                self._pb.iterate()
        finally:
            self._end_measurement()
            self._scan_time = False

    def _acquire_vna_data(self):
        if self.averaging_start_ready:
            self.vna.start_measurement()
            if self._scan_time:
                qkit.flow.sleep(self.vna.get_sweeptime(query=False))  # to prevent timeouts in time scan
            elif self.vna.ready():
                logging.debug("VNA STILL ready... Adding delay")
                qkit.flow.sleep(.2)  # just to make sure, the ready command does not *still* show ready

            while not self.vna.ready():
                qkit.flow.sleep(min(self.vna.get_sweeptime_averages(query=False) / 11., .2))
        else:
            self.vna.avg_clear()
            qkit.flow.sleep(self._sweeptime_averages)

        """ measurement """
        return self.vna.get_tracedata()

    def _append(self,amplitude,phase,real=None,imag=None):
        if self._segments:
            for i in range(len(self._segments)):
                self._datasets['amplitude_%i' % i].append(amplitude[0 if i == 0 else self._segments[i - 1]:self._segments[i]])
                self._datasets['phase_%i' % i].append(phase[0 if i == 0 else self._segments[i - 1]:self._segments[i]])
                if real is not None and imag is not None:
                    self._datasets['real_%i' % i].append(real[0 if i == 0 else self._segments[i - 1]:self._segments[i]])
                    self._datasets['imag_%i' % i].append(imag[0 if i == 0 else self._segments[i - 1]:self._segments[i]])
        else:
            self._datasets['amplitude'].append(amplitude)
            self._datasets['phase'].append(phase)
            if real is not None and imag is not None:
                self._datasets['real'].append(real)
                self._datasets['imag'].append(imag)

    def _measure(self):
        """
        measures and plots the data depending on the measurement type.
        the measurement loops feature the setting of the objects and saving the data in the .h5 file.
        """
        qkit.flow.start()
        try:
            """
            loop: x_obj with parameters from x_vec
            """
            for ix, x in enumerate(self._x_parameter.values):
                self._x_parameter.set_function(x)
                qkit.flow.sleep(self._x_parameter.wait_time)

                self._acquire_log_functions()

                if self._dim == 3:
                    for y in self._y_parameter.values:
                        # loop: y_obj with parameters from y_vec (only 3D measurement)
                        if self.landscape.xylandscapes and not self.landscape.perform_measurement_at_point(x, y, ix):
                            # if point is not of interest (not close to one of the functions)
                            data_amp = np.full(int(self._nop), np.NaN, dtype=np.float16)
                            data_pha = np.full(int(self._nop), np.NaN, dtype=np.float16)  # fill with NaNs
                        else:
                            self._y_parameter.set_function(y)
                            qkit.flow.sleep(self._y_parameter.wait_time)
                            if not self.landscape.xzlandscape_func:  # normal scan
                                data_amp, data_pha = self._acquire_vna_data()
                            else:
                                data_amp, data_pha = self.landscape.get_tracedata_xz(x)
                            self._pb.iterate()
                        self._append(data_amp,data_pha)
                        if self._fit_resonator:
                            self._do_fit_resonator()
                        qkit.flow.sleep()
                    """
                    filling of value-box is done here.
                    after every y-loop the data is stored the next 2d structure
                    """
                    [d.next_matrix() for d in self._datasets.values()]

                if self._dim == 2:
                    data_amp, data_pha = self._acquire_vna_data()
                    self._append(data_amp, data_pha)

                    if self._fit_resonator:
                        self._do_fit_resonator()
                    self._pb.iterate()
                    qkit.flow.sleep()
        finally:
            self._end_measurement()

    def _end_measurement(self):
        super(spectrum, self)._end_measurement()
        if self.averaging_start_ready: self.vna.post_measurement()

    def set_resonator_fit(self, fit_resonator=True, fit_function='', f_min=None, f_max=None):
        """
        sets fit parameter for resonator

        fit_resonator (bool): True or False, default: True (optional)
        fit_function (string): function which will be fitted to the data (optional)
        f_min (float): lower frequency boundary for the fitting function, default: None (optional)
        f_max (float): upper frequency boundary for the fitting function, default: None (optional)
        fit types: 'lorentzian','skewed_lorentzian','circle_fit_reflection', 'circle_fit_notch','fano'
        """
        if not fit_resonator:
            self._fit_resonator = False
            return
        self._functions = {'lorentzian': 0, 'skewed_lorentzian': 1, 'circle_fit_reflection': 2, 'circle_fit_notch': 3, 'fano': 5, 'all_fits': 5}
        try:
            self._fit_function = self._functions[fit_function]
        except KeyError:
            logging.error(
                    'Fit function not properly set. Must be either \'lorentzian\', \'skewed_lorentzian\', \'circle_fit_reflection\', \'circle_fit_notch\', \'fano\', or \'all_fits\'.')
        else:
            self._fit_resonator = True
            self._f_min = f_min
            self._f_max = f_max

    def _do_fit_resonator(self):
        """
        calls fit function in resonator class
        fit function is specified in self.set_fit, with boundaries f_mim and f_max
        only the last 'slice' of data is fitted, since we fit live while measuring.
        """

        if self._fit_function == 0:  # lorentzian
            self._resonator.fit_lorentzian(f_min=self._f_min, f_max=self._f_max)
        if self._fit_function == 1:  # skewed_lorentzian
            self._resonator.fit_skewed_lorentzian(f_min=self._f_min, f_max=self._f_max)
        if self._fit_function == 2:  # circle_reflection
            self._resonator.fit_circle(reflection=True, f_min=self._f_min, f_max=self._f_max)
        if self._fit_function == 3:  # circle_notch
            self._resonator.fit_circle(notch=True, f_min=self._f_min, f_max=self._f_max)
        if self._fit_function == 4:  # fano
            self._resonator.fit_fano(f_min=self._f_min, f_max=self._f_max)
            # if self._fit_function == 5: #all fits
            # self._resonator.fit_all_fits(f_min=self._f_min, f_max = self._f_max)

    def set_plot_comment(self, comment):
        """
        Small comment to add at the end of plot pics for more information i.e. good for wiki entries.
        """
        self._plot_comment = comment

    def gen_fit_function(self, curve_f, curve_p, x_range=None, span=None, p0=[-1, 0.1, 7], units=''):
        """
        Generates an xy landscape fit for 3D scan. Function is deprecated and calls landscape.generate_fit_function
        curve_f: 'spline', '2pt' 'lin, 'parab', 'hyp', specifies the fit function to be employed
        curve_p: set of points that are the basis for the fit in the format [[x1,x2,x3,...],[y1,y2,y3,...]], frequencies in Hz
        span: specify span for the generated fit_function, if not given default of self.span is used
        x_range: specify x_range for the function in the format [x_min, x_max]
        p0 (optional): start parameters for the fit, must be an 1D array of length 3 ([a,b,c,d]),
           where for the parabula p0[3] will be ignored
        units: set this to 'Hz' in order to avoid large values that cause the fit routine to diverge
        The parabolic function takes the form  y = a*(x-b)**2 + c , where (a,b,c) = p0
        The hyperbolic function takes the form y = sqrt[ a*(x-b)**2 + c ], where (a,b,c) = p0

        adds a trace to landscape
        """
        logging.warning("This function is deprecated. Better to use landscape.generate_fit_function_xy")
        self.landscape.generate_fit_function_xy(curve_f=curve_f, curve_p=curve_p, x_range=x_range, y_span=span, p0=p0, units=units)

    def delete_fit_function(self, n=None):
        """
        legacy support for delete_xy_landscape_function. Please use the other function in the future
        delete single fit function n (with 0 being the first one generated) or the complete landscape for n not specified
        :param n: index of single fit function to be deleted
        :return:
        """
        logging.warning('This function is deprecated for clarity purposes.'
                        ' Please use delete_xy_landscape_function in the future')
        self.landscape.delete_landscape_function_xy(n=n)

    def plot_fit_function(self):
        """
        legeacy support for landscape.plot_fit_function_xy. Please use the other function in the future.
        Plots the landscape
        :return:
        """
        self.landscape.plot_xy_landscape()

class Landscape:
    """
    Class for landscape scans in combination with spectroscopy. spectrum gnerates an instance of Landscape in __init__
    Use this instance to generate your fit_functions/landscape for your measurement.
    Instance stores the landscape(functions), lets you plot them, checks if points are to be measured and adjusts
    the vna frequencies.
    """

    def __init__(self, vna, spec):
        self.vna = vna
        self.spec = spec  # The spectroscopy object
        self.xylandscapes = []  # List containing dicts
        self.xzlandscape_func = None
        self.xz_freqpoints = None
        self.y_span_default = 200e6  # this is for the xy landscape scan, i.e., span of your y_parameter, e.g, mw_frequency
        self.z_span = self.vna.get_span()  # This is for the xz landscape scan i.e. span of vna is adjusted w/ resp to x

    def generate_fit_function_xy(self, curve_f, curve_p, x_range=None, y_span=None, blacklist=False, p0=[-1, 0.1, 7], units=''):
        """
        Use this function if you keep your vna span fixed but want to add a landscape to your x and y parameter.
        I.e., for given x parameter not all y parameters are swept but only those that lie within the specified y-span
        around the fit function.
        Adds a trace to landscape
        curve_f: 'spline', 'lin_spline' 'lin, 'parab', 'hyp', 'transmon' specifies the fit function to be employed
        curve_p: set of points that are the basis for the fit in the format [[x1,x2,x3,...],[y1,y2,y3,...]], frequencies in Hz
        x_range: specify x_range for the function in the format [x_min, x_max]
        y_span: specify the span of your y_axis for the generated fit_function,
                if not given default of self.span is used, if negative the span will be excluded from the measurement
                interesting for overlaping regions
        blacklist: Use this parameter to explicitly exclude a section from the measurement (previously done by negative span)
        p0 (optional): start parameters for the fit, must be an 1D array of length 3 ([a,b,c,d]),
           where for the parabula p0[3] will be ignored
        units: set this to 'Hz' in order to avoid large values that cause the fit routine to diverge

        The parabolic function takes the form  y = a*(x-b)**2 + c , where (a,b,c) = p0
        The hyperbolic function takes the form y = sqrt[ a*(x-b)**2 + c ], where (a,b,c) = p0

        """
        if not qkit.module_available("scipy"):
            raise ImportError('scipy not available.')

        if units == 'Hz':
            multiplier = 1e9
        else:
            multiplier = 1
        x_fit = np.array(curve_p[0])
        y_fit = np.array(curve_p[1])
        if x_range is None:
            x_range = [self.spec.x_vec[0], self.spec.x_vec[-1]]
        if y_span is None:
            y_span = self.y_span_default
        if y_span < 0:
            y_span = -y_span
            blacklist = True
            logging.warning('Using a negative span in generate_fit_function_xy is deprecated. Please use blacklist = True instead for more clarity.')

        try:
            if curve_f == 'lin_spline':
                f = interp1d(x_fit, y_fit)
                center_points = f(self.spec.x_vec)
            elif curve_f == 'spline':
                center_points = UnivariateSpline(x_fit, y_fit)(self.spec.x_vec)
            else:  # curve_fit procedure differs from splines
                if curve_f == 'parab':
                    fit_fct = self.f_parab
                elif curve_f == 'hyp':
                    fit_fct = self.f_hyp
                elif curve_f == 'lin':
                    fit_fct = self.f_lin
                    p0 = p0[:2]
                elif curve_f == 'transmon':
                    fit_fct = self.f_transmon
                else:
                    raise ValueError('function type not known...aborting')
                popt, pcov = curve_fit(fit_fct, x_fit, y_fit / multiplier, p0=p0)
                center_points = multiplier * fit_fct(self.spec.x_vec, *popt)
        except Exception as message:
            print('fit not successful:', message)
        else:
            self.xylandscapes.append({'center_points': center_points, 'y_span': y_span, 'x_range': [np.min(x_range), np.max(x_range)], 'blacklist': blacklist})

    def generate_fit_function_xz(self, curve_f, curve_p, z_span=None, p0=[-1, 0.1, 7]):
        """
        Use this function if you want to adjust your vna span with respect to your x-values, useful if you want to
        track your fresonator, e.g., shifting resonance due qubit resonator coupling or fmr measurements. It works
        in a 2d and 3d scan.
        :param curve_f: fit_function (str) such as 'lin_spline', 'spline', 'parab', 'hyp', 'lin'
        :param curve_p: Valeus to fit in the form [[x0,x1,..xn],[z0,z1,..zn]]
        :param z_span: If None, span from VNA is used. If specified, vna span will be updated.
        :param p0: intial fit parameters
        :return:
        """
        if not qkit.module_available("scipy"):
            raise ImportError('scipy not available.')

        if curve_p[1][-1] > 1e6:  # test if z_values are given in Hz or GHz
            multiplier = 1e9
        else:
            multiplier = 1
        if z_span is not None:
            self.z_span = z_span
            self.vna.set_span(z_span)
        else:
            self.z_span = self.vna.get_span()
        x_fit = np.array(curve_p[0])
        z_fit = np.array(curve_p[1])
        try:
            if curve_f == 'lin_spline':
                self.xzlandscape_func = interp1d(x_fit, z_fit)
            elif curve_f == 'spline':
                self.xzlandscape_func = UnivariateSpline(x_fit, z_fit)
            else:  # curve_fit procedure differs from splines
                if curve_f == 'parab':
                    fit_fct = self.f_parab
                elif curve_f == 'hyp':
                    fit_fct = self.f_hyp
                elif curve_f == 'lin':
                    fit_fct = self.f_lin
                    p0 = p0[:2]
                else:
                    raise ValueError('function type not known...aborting')
                popt, pcov = curve_fit(fit_fct, x_fit, z_fit / multiplier, p0=p0)
                self.xzlandscape_func = lambda x: multiplier * fit_fct(x, *popt)

            self.xz_freqpoints = np.arange(self.xzlandscape_func(self.spec.x_vec[0]) - self.z_span / 2,
                                           self.xzlandscape_func(self.spec.x_vec[-1]) + self.z_span / 2, self.vna.get_span() / self.vna.get_nop())
        except Exception as message:
            print('fit not successful:', message)

    def delete_landscape_function_xy(self, n=None):
        """
        delete single xy landscape function n (with 0 being the first one generated)
        or the complete landscape for n not specified
        """
        if n is not None:
            del self.xylandscapes[n]
        else:
            self.xylandscapes = []

    def delete_landscape_function_xz(self):
        """
        delets the xz_landscape_function incl. the xz_freqpoints
        :return: None
        """
        self.xzlandscape_func = None
        self.xz_freqpoints = None
        print('xz_landscape deleted')

    def plot_xy_landscape(self):
        """
        Plots the xy landscape(s) (for 3D scan, z-axis (vna) is not plotted
        :return:
        """
        if not qkit.module_available("matplotlib"):
            raise ImportError("matplotlib not found.")

        if self.xylandscapes:
            for i in self.xylandscapes:
                try:
                    arg = np.where((i['x_range'][0] <= self.spec.x_vec) & (self.spec.x_vec <= i['x_range'][1]))
                    x = self.spec.x_vec[arg]
                    t = i['center_points'][arg]
                    plt.plot(x, t, color='C1')
                    if i['blacklist']:
                        plt.fill_between(x, t + i['y_span'] / 2., t - i['y_span'] / 2., color='C3', alpha=0.5)
                    else:
                        plt.fill_between(x, t + i['y_span'] / 2., t - i['y_span'] / 2., color='C0', alpha=0.5)
                except Exception as e:
                    print(e)
                    print('invalid trace...skip')
            plt.axhspan(np.min(self.spec.y_vec), np.max(self.spec.y_vec), facecolor='0.5', alpha=0.5)
            plt.xlim(np.min(self.spec.x_vec), np.max(self.spec.x_vec))
            plt.show()
        else:
            print('No trace generated. Use landscape.generate_xy_function')

    def plot_xz_landscape(self):
        """
        plots the xz landscape, i.e., how your vna frequency span changes with respect to the x vector
        :return: None
        """
        if not qkit.module_available("matplotlib"):
            raise ImportError("matplotlib not found.")

        if self.xzlandscape_func:
            y_values = self.xzlandscape_func(self.spec.x_vec)
            plt.plot(self.spec.x_vec, y_values, 'C1')
            plt.fill_between(self.spec.x_vec, y_values + self.z_span / 2., y_values - self.z_span / 2., color='C0', alpha=0.5)
            plt.xlim((self.spec.x_vec[0], self.spec.x_vec[-1]))
            plt.ylim((self.xz_freqpoints[0], self.xz_freqpoints[-1]))
            plt.show()
        else:
            print('No xz funcion generated. Use landscape.generate_xz_function')

    def set_y_span(self, y_span, n=None):
        if not self.xylandscapes:
            self.y_span_default = y_span
        else:
            if n is not None:
                self.xylandscapes[n]['y_span'] = y_span
            else:
                for e in self.xylandscapes:
                    e['y_span'] = y_span

    def get_y_span(self):
        return self.y_span_default

    def get_y_span_list(self):
        return [e['y_span'] for e in self.xylandscapes]

    def vna_frequency_wrapper(self, x_set_obj):
        """
        Function wraps the x_set_obj function for a landscape_xy scan such that the vna frequencies are automatically
        adjusted
        :param x_set_obj: as given by the user
        :return: the wrapped function
        """

        def vna_wrapper(x):
            start_freq = self.xz_freqpoints[np.argmin(np.abs(self.xz_freqpoints - (self.xzlandscape_func(x) - self.z_span / 2)))]
            self.vna.set_startfreq(start_freq)
            self.vna.set_stopfreq(start_freq + self.z_span)
            x_set_obj(x)

        return vna_wrapper

    def perform_measurement_at_point(self, x, y, ix):
        """
        Looks if the point is of interest and returns True or False
        :param x: point in the x-vector
        :param y: point in the y-vector
        :param ix: index of x-vector
        :return: measure_bool, whether or not the point should be measured
        """
        # looks strange but works
        measure = False
        for e in self.xylandscapes:
            if np.abs(e['center_points'][ix] - y) <= e['y_span'] / 2 and e['x_range'][0] <= x <= e['x_range'][1]:  # The point is covered by this span
                if e['blacklist']:
                    return False  # if the point is blacklisted anywhere, we don't need to look further
                else:
                    measure = True
        return measure

    def get_tracedata_xz(self, x):
        """
        Function to fill the tracedata with NaNs outside the scan region
        :param x: x_value where we perform the scan
        :return:
        """
        amp = np.full_like(self.xz_freqpoints, np.NaN, dtype=np.float16)
        pha = np.full_like(self.xz_freqpoints, np.NaN, dtype=np.float16)
        startarg = np.argmin(np.abs(self.xz_freqpoints - (self.xzlandscape_func(x) - self.z_span / 2)))
        stoparg = startarg + self.vna.get_nop()
        a, p = self.spec._acquire_vna_data()
        amp[startarg:stoparg] = a
        pha[startarg:stoparg] = p
        return amp, pha

    def get_freqpoints_xz(self):
        return self.xz_freqpoints

    def f_parab(self, x, a, b, c):
        return a * (x - b) ** 2 + c

    def f_hyp(self, x, a, b, c):
        """hyperbolic function with the form y = sqrt[ a*(x-b)**2 + c ]"""
        return np.sqrt(a * (x - b) ** 2 + c)

    def f_lin(self, x, a, b):
        return a * x + b

    def f_transmon(self, x, w_max, L, I_ext, djj):
        """
        Dispersion of a tunable transmon qubit with junction asymmetry.

        Args:
            x:     x-value
            w_max:    Maximum qubit frequency without detuning.
            L:     Oscillation period in current/x-value.
            I_ext: Offset current/x offset.
            djj:   Josephson junction asymmetry (Ic1 - Ic2)/(Ic1 + Ic2)

        Returns:
            Primal transition frequency of a transmon qubit.
        """
        return w_max * (np.abs(np.cos(np.pi / L * (x - I_ext))) * (1 + djj ** 2 * np.tan(np.pi / L * (x - I_ext)) ** 2) ** .5) ** 0.5


# -*- coding: utf-8 -*-
"""
Created on Thu Feb 28 10:16:47 2019

Script to convert text from an xml to geometries
and put the output into a postgres DB table

@author: crosic
"""

import pandas as pd
import xml.etree.cElementTree as et
import psycopg2
import configparser
import pandas.io.sql as psql

# Part 1
# read xml into pandas dataframe

def getvalueofnode(node):
    """ return node text or None """
    return node.text if node is not None else None

parsedXML = et.parse(r"C:\Users\crosic\Downloads\traffic-and-parking-by-law-schedules-data-march-2019\Ch_950_Sch_35_SpeedLimitOnPublicHighways.xml")
dfcols = ['ID', 'Chapter', 'Schedule', 'ScheduleName', 'Highway', 'Between', 'Speed_Limit_km_per_hr']
df_xml = pd.DataFrame(columns=dfcols)
for node in parsedXML.getroot():
    ID = node.find('ID')
    Chapter = node.find('Chapter')
    Schedule = node.find('Schedule')
    ScheduleName = node.find('ScheduleName')
    Highway = node.find('Highway')
    Between = node.find('Between')
    Speed_Limit_km_per_hr = node.find('Speed_Limit_km_per_hr')

    df_xml = df_xml.append(
            pd.Series([getvalueofnode(ID), getvalueofnode(Chapter), getvalueofnode(Schedule),
                       getvalueofnode(ScheduleName), getvalueofnode(Highway),
                       getvalueofnode(Between),  getvalueofnode(Speed_Limit_km_per_hr)],
                       index=dfcols),
            ignore_index=True)

# 6554 rows
print(df_xml.shape[0])

repealed = df_xml[df_xml.Between.isnull()]
# 1521
print(repealed.shape[0])

active_bylaws = df_xml[df_xml.Between.notnull()]
# 5033
print(active_bylaws.shape[0])

# Part 2
# match bylaws to geometry

CONFIG = configparser.ConfigParser()
CONFIG.read('db.cfg')
dbset = CONFIG['DBSETTINGS']
con = psycopg2.connect(**dbset)

from sqlalchemy import create_engine

engine = create_engine('postgresql://' + dbset['user'] + ':' + dbset['password'] + '@' + dbset['host'] + '/' + dbset['database'])

# get one row at a time
def text_to_centreline(highway, between):
   try:
      df = psql.read_sql("SELECT centreline_segments AS geom,  con AS confidence, notice, line_geom, oid1_geom, oid2_geom, street_name_arr, ratio FROM crosic.text_to_centreline('{}', '{}', {})".format(highway.replace("'", ""), between.replace("'", ""), 'NULL'), con)
   except Exception as e:
        print("------------------------")
        print("street: " + highway)
        print(" from: " + between)
        print("ERROR " + str(e))
        print("------------------------")
        raise Exception("Error in text_to_centreline: " + str(e))
        return  [highway, between, "Error", df['geom'].item(), df['notice'].item(), df['line_geom'].item(), df['oid1_geom'].item(), df['oid2_geom'].item(), df['street_name_arr'].item(), df['ratio'].item()]

   return [highway, between, df['confidence'].item(),  df['geom'].item(), df['notice'].item(), df['line_geom'].item(), df['oid1_geom'].item(), df['oid2_geom'].item(), df['street_name_arr'].item(), df['ratio'].item()]

def call_text_to_centreline_on_every_row(bylaws):
    rows = []
    total_rows = bylaws.shape[0]
    for index, row in bylaws.iterrows():

        # print messages to tell user where you are in process
        if index%100 == 0:
          print("Calling SQL function on index " + str(index))
        if index == total_rows-1:
          print("Processing last row with index value of " + str(index))

        # call text_to_centreline function
        try:
          row_with_wkt = text_to_centreline(row[4], row[5])
          # add ID and speed limit value to each row
          rows.append([row[0]] +  row_with_wkt + row[6])
        except Exception as e:
          rows.append([row[0], row[1], row[2], "No Match - ERROR", None, str(e), None, None, None, None, None, row[6]])
          continue

    return pd.DataFrame(data=rows, columns=['id','street_name', 'extents',  'confidence', 'geom', 'notice', 'line_geom', 'oid1_geom', 'oid2_geom', 'street_name_arr', 'ratio', 'speed_limit_km_per_hr'])  #gpd.GeoDataFrame(data=rows)

# convert list of rows to sql table
geom_data = call_text_to_centreline_on_every_row(active_bylaws)
geom_data.to_sql('posted_speed_limit_xml_open_data', engine)

con.close()


from copy import deepcopy
from torch import nn
from models.layer.residual_connection_layer import ResidualConnectionLayer

class DecoderBlock(nn.Module):
    def __init__(self, self_attention, cross_attention, position_ff, norm, dropout=0) -> None:
        super().__init__()
        self.self_attention = self_attention
        self.cross_attention = cross_attention
        self.position_ff = position_ff
        self.residuals = [ResidualConnectionLayer(deepcopy(norm), dropout) for _ in range(3)]

    def forward(self, tgt, encoder_out, tgt_mask, src_tgt_mask):
        out = tgt
        out = self.residuals[0](out, lambda out: self.self_attention(query=out, key=out, value=out, mask=tgt_mask))
        out = self.residuals[1](out, lambda out: self.self_attention(query=out, key=encoder_out, value=encoder_out, mask=src_tgt_mask))
        out = self.residuals[2](out, self.position_ff)
        return out


from django.contrib import admin
from .models import Profile

# Register your models here.
class ProfileAdmin(admin.ModelAdmin):
    list_display = [
        'pk',
        'user',
        'phone',
        'country',
        'city',
        'аddress_1',
        'postcode',
        'other',]

admin.site.register(Profile, ProfileAdmin)


import pandas as pd
from sklearn.model_selection import train_test_split
import librosa
import numpy as np
from scipy import signal
from tqdm import tqdm
import h5py
import sys
import argparse

parser = argparse.ArgumentParser(description='Preparing data.')

parser.add_argument('--run', help='Use this flag to run the prepare loop.', action="store_true")
parser.add_argument('--sample_rate', type=int, help='Desired sample rate.', default=220500)
parser.add_argument('--n_fft', type=int, help='Desired number of fft.', default=512)
parser.add_argument('--filename', help='Desired filename to write to.', default="prepared_signal.h5")

args, unknown = parser.parse_known_args()

sample_rate = args.sample_rate      # recordings are in 96 kHz, 24 bit depth, 1:10 TE (mic sr 960 kHz)
n_fft = args.n_fft                  # 23 ms * 22050 Hz ~ 512

# Smaller values improve the temporal resolution of the STFT at the expense of frequency resolution
# Shape: (1+nfft/2, n_frames = len/(n_fft/4))

# 1th order butterworth high-pass filter with cut-off frequency of 15,000 kHz
b, a = signal.butter(10, 15000 / 120000, 'highpass')

print(sample_rate)
def prepareData(y):
    filtered = signal.lfilter(b, a, y)                      # filter
    return filtered

def mergeClass(name):
    signals = []
    for filename in tqdm(classes[name]):
        y, _ = librosa.load("./data/" + filename, sr=sample_rate)
        sig = prepareData(y)
        signals.append(sig)

    if len(signals) >= 7:
        X_train, X_test, _, _ = train_test_split(signals, np.zeros(len(signals)), test_size=0.25, random_state=42)
        X_train, X_val, _, _ = train_test_split(X_train, np.zeros(len(X_train)), test_size=0.2, random_state=42)
        train = np.concatenate(X_train)
        test = np.concatenate(X_test)
        val = np.concatenate(X_val)
        train_set.create_dataset(name, data=train)
        test_set.create_dataset(name, data=test)
        val_set.create_dataset(name, data=val)

if args.run:
    df = pd.read_csv('./meta_n.csv', delimiter=';')
    hf = h5py.File(args.filename, 'a')  # will be ~13GB
    train_set = hf.require_group("train")
    test_set = hf.require_group("test")
    val_set = hf.require_group("val")

    classes = {}

    for index, row in df.iterrows():
        spec = row["MANUAL ID"]
        if spec not in classes:
            classes[spec] = []
        classes[spec].append(row["IN FILE"])

    print("sorted!")
    print(classes.keys())

    for classname in list(classes):
        if not classname in train_set or not classname in test_set or not classname in val_set:
            mergeClass(classname)
            print(classname + " prepared!")

    hf.close()


with open("NAPISY_2014.TXT", "r", encoding="UTF-8") as plik:
    napisy = []

    for line in plik:
        napisy.append(line.strip())

# print(napisy)

napisy_rosnace = []
#ABCD -> 4 -> ROSNĄCY
#BCDA  -> 4 -> NIEROSNĄCY
for napis in napisy:
    for i in range(1, len(napis)):
        if ord(napis[i]) <= ord(napis[i - 1]):
            # napisy_rosnace.append(napis)
            break
        if i == len(napis) - 1:
            napisy_rosnace.append(napis)

# print(napisy_rosnace)

for napis in napisy_rosnace:
    print(napis)

with open("ZADANIE5.TXT", "a", encoding="UTF-8") as plik:
    plik.write(f'b) Napisy rosnące: \n')
    for napis in napisy_rosnace:
        plik.write(f'{napis}\n')
    plik.write("\n")


import sys, heapq
sys.stdin = open('input.txt')

def dijkstra(start):
    dist = [sys.maxsize] * (n+1)
    dist[start] = 0
    que = []
    heapq.heappush(que, (0, start))
    while que:
        d, now = heapq.heappop(que)
        if dist[now] < d:
            continue
        for b, c in g[now]:
            if dist[b] > d + c:
                dist[b] = d + c
                heapq.heappush(que, (dist[b], b))
    return dist

input = sys.stdin.readline

n, m, x = map(int, input().split())
g = [[] for _ in range(n+1)]
for _ in range(m):
    a, b, c = map(int, input().split())
    g[a].append((b, c))
ans = 0
# x에서 돌아가는 거리 구해놓기
back = dijkstra(x)
for i in range(1, n+1):
    go = dijkstra(i)
    temp = go[x] + back[i]
    ans = max(ans, temp)
print(ans)


# 4 Pillars of OOP
# -1 - Encapsulation = Create Classes (blueprint)
# -2 - Inheritance
# -3 - Polymorphism  = many forms
# -4 - Abstraction = Hide Complexity

class Human:

    # Constructor
    def __init__(self,name):
        self.name = name
        self.health = 100
        self.strength = 10
        self.power = 10
        self.defense = 5
        self.weapon = None

    def attack(self,target):
        print(f"[ATTACK] {self.name} is attacking {target.name}")
        target.defend(self.power) #! Abstraction
        # target.health -= self.power

    def defend(self, damage):
        damage -= self.defense
        self.health -= damage
        print(f"[DEFEND] {self.name} takes {damage} and now has {self.health} HP")

# ! Inheritance

class Barbarian(Human):
    def __init__(self, name):
        super().__init__(name)
        self.strength += 20 #! Polymorphism (modify the parent attribute)
        self.rage = 35  #! Polymorphism (add a new attribute that belongs only to the child class(Barbarian))

class Knight(Human):
    def __init__(self, name):
        super().__init__(name) # call my Parent(Human)
        # self.name = name
        self.health += 10
        self.defense += 50

    def heal(self): #! Polymorphism (add a new method that belongs only to the child class(Knight))
        self.health += self.defense/4
        print(f"[knight] {self.name} heals for {self.defense/4} and now has {self.health} HP")

class Seer :
    def __init__(self):
        self.magic = 50
        self.hidden_type = Barbarian("No Name") #! Abstraction

alex = Human("Alex")
john = Human("John")
conan = Barbarian("Conan")
# print("Conan Health",conan.health)
alex.attack(john)
# conan.attack(john)
# print(type(alex))
# print(type(conan))
# print(isinstance(conan, Human))
# print("Conan Power",conan.power)

sam = Seer()
print("Conan Health",conan.health)
sam.hidden_type.attack(conan)
print("Conan Health",conan.health)
print("***********",sam.hidden_type,"**********")

arthur = Knight("Arthur")
print(f"Arthur health before healing : {arthur.health}")
arthur.heal()
print(f"Arthur health after healing : {arthur.health}")


import os
from lib import Utils
from lib import Settings
from lib import SetupLogger

# ConfigurationFile class, contains parsed information of the configuration file
class ConfigFIle:

    def __init__(self, config_file_path):

        self.config_file_path = config_file_path
        self.alerts_dir = None
        self.documentation_dir = None
        self.upload_documentation = None
        self.documentation_plugin = None
        self.operations_dir = None
        self.upload_operations = None
        self.operations_plugin = None
        self.config_yml = None

        self.read_config_file()

    # Get alert dir variable from configuration file
    def read_config_file(self):

        # Read configuration file
        config_file = Utils.read_yml_file(self.config_file_path)

        # Check if the configuration file exist
        if config_file is None:
            print("[error] Configuration file not found: {}, exiting ...".format(self.config_file_path))
            exit(1)

        self.config_yml = config_file.get('config')

        # Validate if the value exist if don't use default
        if not self.config_yml.get('alerts_dir', False):
            self.alerts_dir = Settings.CONFIGURATION_FOLDERS["alerts"].get('folder')
            SetupLogger.logger.debug("Variable alerts_dir not defined, using default value: {}".format(self.alerts_dir))
        else:
            self.alerts_dir = self.config_yml.get('alerts_dir')
            SetupLogger.logger.debug("Variable alerts_dir defined, using value: {}".format(self.alerts_dir))
        # Validate if the dir is valid
        if not os.path.isdir(self.alerts_dir):
            SetupLogger.logger.fatal("Alerts directory is not valid, exiting ...")
            exit(1)

        # Validate if the value exist if don't use default
        if not self.config_yml.get('documentation_dir', False):
            self.documentation_dir = Settings.CONFIGURATION_FOLDERS["documentation"].get('folder')
            SetupLogger.logger.debug(
                "Variable documentation_dir not defined, using default value: {}".format(self.documentation_dir))
        else:
            self.documentation_dir = self.config_yml.get('documentation_dir')
            SetupLogger.logger.debug("documentation_dir defined, using value: {}".format(self.documentation_dir))
        # Validate if the dir is valid
        if not os.path.isdir(self.documentation_dir):
            print("[error] Documentation directory is not valid, exiting ...")
            exit(1)

        # Validate if the value exist if don't use default
        if not self.config_yml.get('operations_dir', False):
            self.operations_dir = Settings.CONFIGURATION_FOLDERS["operations"].get('folder')
            SetupLogger.logger.debug(
                "Variable operations_dir not defined, using default value: {}".format(self.operations_dir))
        else:
            self.operations_dir = self.config_yml.get('operations_dir')
            SetupLogger.logger.debug("operations_dir defined, using value: {}".format(self.operations_dir))
        # Validate if the dir is valid
        if not os.path.isdir(self.operations_dir):
            print("[error] Operations directory is not valid, exiting ...")
            exit(1)

        # Check if upload_documentation variable is available
        self.upload_documentation = self.config_yml.get('upload_documentation', False)

        # Check if documentation_plugin variable is available
        self.documentation_plugin = self.config_yml.get('documentation_plugin', Settings.DEFAULT_DOCUMENTATION_PLUGIN)

        # Check if upload_operations variable is available
        self.upload_operations = self.config_yml.get('upload_operations', False)

        # Check if operations_plugin variable is available
        self.operations_plugin = self.config_yml.get('operations_plugin', Settings.DEFAULT_OPERATIONS_PLUGIN)


import base64
import datetime
import io
import plotly.graph_objs as go
import cufflinks as cf
import plotly.express as px

import dash
from dash.dependencies import Input, Output, State
# import dash_core_components as dcc
# import dash_html_components as html
# import dash_table

from dash import dcc
from dash import dash_table
from dash import html

import pandas as pd

external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
server = app.server

colors = {"graphBackground": "#F5F5F5", "background": "#ffffff", "text": "#000000"}

app.layout = html.Div(
    [
        dcc.Upload(
            id="upload-data",
            children=html.Div(["Drag and Drop or ", html.A("Select Files")]),
            style={
                "width": "100%",
                "height": "60px",
                "lineHeight": "60px",
                "borderWidth": "1px",
                "borderStyle": "dashed",
                "borderRadius": "5px",
                "textAlign": "center",
                "margin": "10px",
            },
            # Allow multiple files to be uploaded
            multiple=True,
        ),
        dcc.Dropdown(id='x-axis', placeholder="X-Axis"),
        # html.Button('Add X-Axis Columns', id='add_x_axis_columns', n_clicks=0),
        dcc.Dropdown(id='y-axis', placeholder="Y-Axis"),
        # html.Button('Add Y-Axis Columns', id='add_y_axis_columns', n_clicks=0),
        dcc.Dropdown(id='color', placeholder="Color"),
        dcc.Graph(id="Mygraph"),
        html.Div(id="output-data-upload"),
    ]
)

# @app.callback(
#     Output('x-axis', 'options'),
#     columns)
# def update(n_clicks, existing_options):
#     print("Flag Updated")
#     return []

# @app.callback(
#     Output('x-axis', 'options'),
#     [Input('add_x_axis_columns', 'n_clicks')],
#     [State('x-axis', 'options')])
# def update_options(n_clicks, existing_options):
#     new_options = []
#     for choice in columns:
#         new_options.append({'label': choice, 'value': choice})
#     return new_options

# @app.callback(
#     Output('y-axis', 'options'),
#     [Input('add_y_axis_columns', 'n_clicks')],
#     [State('y-axis', 'options')])
# def update_options(n_clicks, existing_options):
#     new_options = []
#     for choice in columns:
#         new_options.append({'label': choice, 'value': choice})
#     return new_options

@app.callback(
    Output('y-axis', 'options'),
    [Input("upload-data", "contents"),
    Input("upload-data", "filename")],
    [State('y-axis', 'options')])
def update_y_columns(contents, filename, exsting_options):
    new_options = []
    if contents:
        contents = contents[0]
        filename = filename[0]
        df = parse_data(contents, filename)
        arr = df.columns
        for choice in arr:
            new_options.append({'label': choice, 'value': choice})
    return new_options

@app.callback(
    Output('color', 'options'),
    [Input("upload-data", "contents"),
    Input("upload-data", "filename")],
    [State('color', 'options')])
def update_y_columns(contents, filename, exsting_options):
    new_options = []
    if contents:
        contents = contents[0]
        filename = filename[0]
        df = parse_data(contents, filename)
        arr = df.columns
        for choice in arr:
            new_options.append({'label': choice, 'value': choice})
    return new_options

@app.callback(
    Output('x-axis', 'options'),
    [Input("upload-data", "contents"),
    Input("upload-data", "filename")],
    [State('x-axis', 'options')])
def update_x_columns(contents, filename, exsting_options):
    new_options = []
    if contents:
        contents = contents[0]
        filename = filename[0]
        df = parse_data(contents, filename)
        arr = df.columns
        for choice in arr:
            new_options.append({'label': choice, 'value': choice})
    return new_options

@app.callback(
    Output("Mygraph", "figure"),
    [Input("upload-data", "contents"),
    Input("upload-data", "filename"),
    dash.dependencies.Input('y-axis', 'value'),
    dash.dependencies.Input('x-axis', 'value'),
    dash.dependencies.Input('color', 'value')],
)
def update_graph(contents, filename, xaxis, yaxis, color):
    fig = {
        "layout": go.Layout(
            plot_bgcolor=colors["graphBackground"],
            paper_bgcolor=colors["graphBackground"],
        )
    }
    if contents:
        contents = contents[0]
        filename = filename[0]
        df = parse_data(contents, filename)

        # print("Called" + " X-axis: " + str(xaxis) + "Y-Axis: " + str(yaxis))
        if xaxis != None and yaxis != None:
            if color != None:
                fig = px.scatter(df, x=xaxis, y=yaxis, color=color)
            else:
                fig = px.scatter(df, x=xaxis, y=yaxis)
    return fig

    # if contents:
    #     contents = contents[0]
    #     filename = filename[0]
    #     df = parse_data(contents, filename)
    #     df = df.set_index(df.columns[0])
    #     fig["data"] = df.iplot(
    #         asFigure=True, kind="scatter", mode="lines+markers", size=1
    #     )

    # return fig

def parse_data(contents, filename):
    content_type, content_string = contents.split(",")

    decoded = base64.b64decode(content_string)
    try:
        if "csv" in filename:
            # Assume that the user uploaded a CSV or TXT file
            df = pd.read_csv(io.StringIO(decoded.decode("utf-8")))
        elif "xls" in filename:
            # Assume that the user uploaded an excel file
            df = pd.read_excel(io.BytesIO(decoded))
        elif "txt" or "tsv" in filename:
            # Assume that the user upl, delimiter = r'\s+'oaded an excel file
            df = pd.read_csv(io.StringIO(decoded.decode("utf-8")), delimiter=r"\s+")
    except Exception as e:
        print(e)
        return html.Div(["There was an error processing this file."])

    return df

@app.callback(
    Output("output-data-upload", "children"),
    [Input("upload-data", "contents"), Input("upload-data", "filename")],
)
def update_table(contents, filename):
    table = html.Div()

    if contents:
        contents = contents[0]
        filename = filename[0]
        df = parse_data(contents, filename)

        table = html.Div(
            [
                html.H5(filename),
                dash_table.DataTable(
                    data=df.to_dict("rows"),
                    columns=[{"name": i, "id": i} for i in df.columns],
                ),
                html.Hr(),
                html.Div("Raw Content"),
                html.Pre(
                    contents[0:200] + "...",
                    style={"whiteSpace": "pre-wrap", "wordBreak": "break-all"},
                ),
            ]
        )

    return table

if __name__ == "__main__":
    app.run_server(debug=True)


import os
import time

from flask import Flask, request, render_template

from TravSHACL.core.GraphTraversal import GraphTraversal
from TravSHACL.core.ShapeSchema import ShapeSchema
from TravSHACL.sparql.SPARQLEndpoint import SPARQLEndpoint

app = Flask(__name__)
app.config['SCHEMA_PATH'] = os.environ.get('SCHEMA_PATH', '/path/to/your/shacl')
app.config['ENDPOINT'] = os.environ.get('ENDPOINT', 'https://example.org/sparql')

HEURISTICS = {
    'target': True,
    'degree': 'in',
    'properties': 'big'
}

@app.route('/validate', methods=['GET', 'POST'])
def validation():
    if request.method == 'GET':
        return render_template('validate.jinja2', schema_path=app.config['SCHEMA_PATH'], endpoint=app.config['ENDPOINT'])
    SPARQLEndpoint.instance = None  # Needs to be reset since it is a singleton and won't change otherwise
    schema_path = request.form.get('schemaDir', None)
    endpoint = request.form.get('external_endpoint', None)

    shape_schema = ShapeSchema(
        schema_dir=schema_path,
        schema_format='SHACL',
        endpoint=endpoint,
        graph_traversal=GraphTraversal.DFS,
        heuristics=HEURISTICS,
        use_selective_queries=True,
        max_split_size=256,
        output_dir=None,
        order_by_in_queries=False,
        save_outputs=False
    )

    start = time.time()
    result = shape_schema.validate()
    stop = time.time()
    result_html = travshacl_to_html_table(result, stop - start)
    return render_template("result.jinja2", html=result_html)

def travshacl_to_html_table(trav_result, time_used):
    parsed_result = []

    for shape, validation_dict in trav_result.items():
        for validation_result, instances in validation_dict.items():
            for instance in instances:
                finished_at = shape
                if finished_at[0] == '<':
                    finished_at = finished_at[1:]
                if finished_at[-1] == '>':
                    finished_at = finished_at[:-1]

                shape_ = instance[0]
                if shape_[0] == '<':
                    shape_ = shape_[1:]
                if shape_[-1] == '>':
                    shape_ = shape_[:-1]
                parsed_result.append({'shape': shape_, 'finished@shape': finished_at, 'validation result': validation_result.replace('_instances',''), 'instance': instance[1]})

    html = '
Trav-SHACL returned ' + str(len(parsed_result)) + ' validation results in ' + str(time_used) + ' seconds.

'

    order = []
    html += '
'
    for item in ['instance', 'shape', 'validation result', 'finished@shape']:
        order.append(item)
        html += '' + item + '	'
    html += '
'

    for res in parsed_result:
        html += '
'
        for item in order:
            if res[item]:
                if item == 'validation result':
                    if res[item] == 'valid':
                        html += '' + str(res[item]) + '	'
                    else:
                        html += '' + str(res[item]) + '	'
                else:
                    html += '' + str(res[item]) + '	'
        html += '
'

    html += '

'
    return html

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)


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

import pickle
from sklearn.preprocessing import StandardScaler
import numpy as np

svm = pickle.load(open("..\\Algorithm Evaluation\\Models\\svm.sav", 'rb'))
rf = pickle.load(open("..\\Algorithm Evaluation\\Models\\random_forest.sav", 'rb'))
mlp = pickle.load(open("..\\Algorithm Evaluation\\Models\\mlp.sav", 'rb'))

new_register=[[50000, 40, 5000]]
new_register = np.asarray(new_register)
new_register = new_register.reshape(-1,1)

scaler = StandardScaler()
new_register = scaler.fit_transform(new_register)
new_register = new_register.reshape(-1,3)

response_svm = svm.predict(new_register)
response_random = rf.predict(new_register)
response_mlp = mlp.predict(new_register)

pay = 0
not_pay = 0

if response_svm == 1:
    pay += 1
else:
    not_pay += 1

if response_random == 1:
    pay += 1
else:
    not_pay += 1

if response_mlp == 1:
    pay += 1
else:
    not_pay += 1

# Estrategy: Plurality (Most Votes)
if pay >= not_pay:
    print("Client pays")
else:
    print("Client doesn't pay")


from __future__ import annotations

from typing import Any, Dict, List, Type, TypeVar, Union, cast

import attr

from binarylane.models.network import Network
from binarylane.types import UNSET, Unset

T = TypeVar("T", bound="Networks")

@attr.s(auto_attribs=True)
class Networks:
    """
    Attributes:
        v4 (List[Network]): A list of the IPv4 networks for this server.
        v6 (List[Network]): A list of the IPv6 networks for this server.
        port_blocking (bool): Whether the default port blocking is enabled for this server.
        recent_ddos (bool): If this is true this server has been the target of a recent DDOS attack. An email will have
            been sent to your email address when the DDOS was detected (and if it has ended, when it ended) with more
            details.
        separate_private_network_interface (Union[Unset, None, bool]): Whether a separate private network interface is
            provided for the server's VPC traffic.
        source_and_destination_check (Union[Unset, None, bool]): If enabled, this server is only able to send and
            receive data packets directly addressed to an IP address assigned to this server.
        ipv6_reverse_nameservers (Union[Unset, None, List[str]]): Any configured IPv6 reverse nameservers for this
            server. Please see our documentation for how this interacts with IPv6 nameserver settings at the account level.
    """

    v4: List[Network]
    v6: List[Network]
    port_blocking: bool
    recent_ddos: bool
    separate_private_network_interface: Union[Unset, None, bool] = UNSET
    source_and_destination_check: Union[Unset, None, bool] = UNSET
    ipv6_reverse_nameservers: Union[Unset, None, List[str]] = UNSET
    additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict)

    def to_dict(self) -> Dict[str, Any]:
        v4 = []
        for v4_item_data in self.v4:
            v4_item = v4_item_data.to_dict()

            v4.append(v4_item)

        v6 = []
        for v6_item_data in self.v6:
            v6_item = v6_item_data.to_dict()

            v6.append(v6_item)

        port_blocking = self.port_blocking
        recent_ddos = self.recent_ddos
        separate_private_network_interface = self.separate_private_network_interface
        source_and_destination_check = self.source_and_destination_check
        ipv6_reverse_nameservers: Union[Unset, None, List[str]] = UNSET
        if not isinstance(self.ipv6_reverse_nameservers, Unset):
            if self.ipv6_reverse_nameservers is None:
                ipv6_reverse_nameservers = None
            else:
                ipv6_reverse_nameservers = self.ipv6_reverse_nameservers

        field_dict: Dict[str, Any] = {}
        field_dict.update(self.additional_properties)
        field_dict.update(
            {
                "v4": v4,
                "v6": v6,
                "port_blocking": port_blocking,
                "recent_ddos": recent_ddos,
            }
        )
        if separate_private_network_interface is not UNSET:
            field_dict["separate_private_network_interface"] = separate_private_network_interface
        if source_and_destination_check is not UNSET:
            field_dict["source_and_destination_check"] = source_and_destination_check
        if ipv6_reverse_nameservers is not UNSET:
            field_dict["ipv6_reverse_nameservers"] = ipv6_reverse_nameservers

        return field_dict

    @classmethod
    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
        d = src_dict.copy()
        v4 = []
        _v4 = d.pop("v4")
        for v4_item_data in _v4:
            v4_item = Network.from_dict(v4_item_data)

            v4.append(v4_item)

        v6 = []
        _v6 = d.pop("v6")
        for v6_item_data in _v6:
            v6_item = Network.from_dict(v6_item_data)

            v6.append(v6_item)

        port_blocking = d.pop("port_blocking")

        recent_ddos = d.pop("recent_ddos")

        separate_private_network_interface = d.pop("separate_private_network_interface", UNSET)

        source_and_destination_check = d.pop("source_and_destination_check", UNSET)

        ipv6_reverse_nameservers = cast(List[str], d.pop("ipv6_reverse_nameservers", UNSET))

        networks = cls(
            v4=v4,
            v6=v6,
            port_blocking=port_blocking,
            recent_ddos=recent_ddos,
            separate_private_network_interface=separate_private_network_interface,
            source_and_destination_check=source_and_destination_check,
            ipv6_reverse_nameservers=ipv6_reverse_nameservers,
        )

        networks.additional_properties = d
        return networks

    @property
    def additional_keys(self) -> List[str]:
        return list(self.additional_properties.keys())

    def __getitem__(self, key: str) -> Any:
        return self.additional_properties[key]

    def __setitem__(self, key: str, value: Any) -> None:
        self.additional_properties[key] = value

    def __delitem__(self, key: str) -> None:
        del self.additional_properties[key]

    def __contains__(self, key: str) -> bool:
        return key in self.additional_properties


from roboaugen.data.dataset import ProjectedMeshDataset
from roboaugen.core.config import Config
from roboaugen.model.models import HigherResolutionNetwork, MobileNetV2
from roboaugen.model.silco import Silco
from roboaugen.train.trainer import Trainer

import cv2
import sys
import math
import os
import random

import torch
import torch.nn as nn
import torch.nn.functional as F

import numpy as np
import click

class Inferencer():

  def __init__(self, distort=False, keep_dimensions=False, use_cache=False, \
      mode='silco', max_background_objects=1, max_foreground_objects=1, object_type=None):
    self.config = Config()
    self.distort = distort
    self.keep_dimensions = keep_dimensions
    self.use_cache = use_cache
    self.mode = mode
    self.max_background_objects = max_background_objects
    self.max_foreground_objects = max_foreground_objects
    self.object_type = object_type
    self.dataset = ProjectedMeshDataset(self.config.input_height, self.config.input_width, self.config.num_vertices,
      self.max_background_objects, self.max_foreground_objects, distort=self.distort,
      keep_dimensions=self.keep_dimensions, use_cache=self.use_cache, forced_object_type=object_type)
    self.higher_resolution = self.config.load_higher_resolution_model().cuda()
    self.silco = self.config.load_silco_model().cuda()
    self.backbone = self.config.load_mobilenet_model().cuda()

  @staticmethod
  def to_numpy_image(tensor):
    return tensor.transpose(0,2).transpose(0,1).numpy()

  def display_heatmap(self, label, input_images, predicted_heatmaps, threshold):
    colored_predictions = torch.zeros(predicted_heatmaps.size()[0], predicted_heatmaps.size()[1], 3, input_images.size()[2], input_images.size()[3])
    hues = torch.arange(start=0,end=179., step = 179 / (self.config.num_vertices + 1) )  # H: 0-179, S: 0-255, V: 0-255.
    colored_predictions[:, :, 1, : ,:] = 128
    predicted_heatmaps[:, :, : , :] = (predicted_heatmaps[:, :, : , :] > threshold)
    for sample in range(predicted_heatmaps.size()[0]):
      predictions_in_sample = np.zeros((input_images.size()[2], input_images.size()[3], 3))
      for vertex in range(predicted_heatmaps.size()[1]):
        colored_predictions[sample, vertex, 0, : , :] = int(hues[vertex])
        colored_predictions[sample, vertex, 2, : , :] = (predicted_heatmaps[sample, vertex, : , :] * 255.).byte()
        current_prediction = colored_predictions[sample, vertex, :, : , :].transpose(0,2).transpose(0,1).numpy()
        current_prediction = cv2.cvtColor(current_prediction, cv2.COLOR_HSV2BGR)
        predictions_in_sample += current_prediction
      predictions_in_sample = predictions_in_sample
      predictions_in_sample_mask = predictions_in_sample.sum(2)
      predictions_in_sample_mask = (predictions_in_sample_mask == 0).astype(np.float32)
      predictions_in_sample_mask = np.expand_dims(predictions_in_sample_mask, 2)
      input_image = Inferencer.to_numpy_image(input_images[sample])
      new_input_image = (predictions_in_sample_mask * input_image[:, :, :] * 255) + ((1.- predictions_in_sample_mask) * predictions_in_sample)
      new_input_image = (new_input_image).astype(np.uint8)
      #cv2.imshow(f'Input_Heatmap_{label}_{sample}', new_input_image)
      #if self.heatmap:
      #  predictions_in_sample = predictions_in_sample.astype(np.uint8)
        #cv2.imshow(f'Heatmap_{label}_{sample}', predictions_in_sample)
      return new_input_image

  def get_supports_and_query(self, sampleid, file, supports_path):
    target_heatmaps = None
    spatial_penalty = None
    supports = None
    if file is None or file == '':
      query, supports, target, spatial_penalty, _, _ = self.dataset.__getitem__(sampleid)
      if self.mode == 'keypoints':
        supports = None
      else:
        supports = supports.unsqueeze(0)
      query = torch.cat([query.unsqueeze(0)], dim=0)
      target_heatmaps = torch.cat([target.unsqueeze(0)], dim=0)
      spatial_penalty = torch.cat([spatial_penalty.unsqueeze(0)], dim=0)
    else:
      if self.mode != 'keypoints':
        if supports_path is not None and supports_path != '':
          supports = self.get_supports_from_folder(supports_path)
        else:
          supports = self.dataset.get_supports(sampleid, self.dataset.forced_object_type).unsqueeze(0)
      query = self.get_queries_from_opencv_images([cv2.imread(file)])
    return supports, query, target_heatmaps, spatial_penalty

  def get_supports_from_folder(self, supports_folder):
    support_ids = os.listdir(f'{supports_folder}')
    support_ids = random.choices(support_ids, k=5)
    supports = [self.dataset.image_to_torch(cv2.imread(f'{supports_folder}/{support_id}')).unsqueeze(0).unsqueeze(1) for support_id in support_ids]
    supports = torch.cat(supports, 1)
    return supports

  def get_queries_from_opencv_images(self, query_images):
    queries = [self.dataset.image_to_torch(image).unsqueeze(0) for image in query_images]
    queries = torch.cat(queries, dim=0)
    return queries

  def get_model_inference(self, supports, query):
    w = query.size()[2]
    h = query.size()[3]
    if supports is not None:
      supports = supports[:, :, :, :w, :h]
    query_features, support_features = Silco.backbone_features(self.backbone, query, supports)
    if self.mode != 'keypoints':
      query_features, spatial_classifier, feature_classifier, spatial_supports = self.silco(query_features, support_features)
    predicted_heatmaps = self.higher_resolution(query_features)
    return predicted_heatmaps

  def display_results(self, label, visualize_query, visualize_suports, predicted_heatmaps, threshold, target_heatmap=None, spatial_penalty=None):
    visual_targets, visual_predictions, visual_suports = None, None, None

    predicted_heatmaps = F.interpolate(predicted_heatmaps, size=(visualize_query.size()[2], visualize_query.size()[3]), mode='bilinear')
    predicted_heatmaps = predicted_heatmaps.detach().cpu()
    visual_predictions = self.display_heatmap('Predictions', visualize_query, predicted_heatmaps, threshold)
    if target_heatmap is not None:
      targets = self.display_heatmap('Targets', visualize_query, target_heatmap, threshold)
      spatial_penalty = self.display_heatmap('Spatial Penalty', visualize_query, spatial_penalty, threshold)
      images = np.hstack((targets, spatial_penalty, visual_predictions))
      visual_targets = images
    if visualize_suports is not None:
      visual_suports = visualize_suports.squeeze(0)
      visual_suports = [Inferencer.to_numpy_image(visual_suports[sample_idx]) for sample_idx in range(visual_suports.size()[0])]
      visual_suports = np.hstack(visual_suports)

    return visual_targets, visual_predictions, visual_suports

@click.command()
@click.option("--sampleid", default=1, help="Sample ID.")
@click.option("--distort", default=False, help="Distort sample image.")
@click.option("--keep_dimensions", default=True, help="Keep original image dimensions.")
@click.option("--use_cache", default=False, help="Use image cache.")
@click.option("--file", default='', help="Path to image file.")
@click.option("--threshold", default=0.1, help="Positive threshold.")
@click.option("--supports_path", default='', help="Path to support images.")
@click.option("--heatmap", default=False, help="Display heatmap without image.")
@click.option("--mode", default='keypoints', help="Training mode: keypoints, silco.")
@click.option("--max_background_objects", default=1, help="Maximum number of background objects not in target for keypoints")
@click.option("--max_foreground_objects", default=1, help="Maximum number of foreground objects not in target for keypoints.")
@click.option("--object_type", default='', help="Supports object type.")
def inference(sampleid, distort, keep_dimensions, use_cache, file, threshold, supports_path, heatmap, mode, max_background_objects, max_foreground_objects, object_type):
  object_type = None if object_type == '' else object_type
  inferencer = Inferencer(distort, keep_dimensions, use_cache, \
      mode, max_background_objects, max_foreground_objects, object_type)
  supports, query, target_heatmaps, spatial_penalty = inferencer.get_supports_and_query(sampleid, file, supports_path)
  if distort:
    query = inferencer.dataset.distort_image(query)
  #if distort:
  #  supports = torch.cat([inferencer.dataset.distort_image(supports[0, support_idx]).unsqueeze(0) for support_idx in range(supports.size()[1])], 0).unsqueeze(0)
  visualize_query = query.clone()

  visualize_suports = None
  if mode != 'keypoints':
    visualize_suports = supports.clone()
    supports = supports.cuda()
  query = query.cuda()
  predicted_heatmaps = inferencer.get_model_inference(supports, query)
  visual_targets, visual_predictions, visual_suports = inferencer.display_results(sampleid, visualize_query, visualize_suports, predicted_heatmaps, threshold, target_heatmaps, spatial_penalty)
  if visual_targets is not None:
    cv2.imshow(f'{sampleid} - Targets - Spatial Penalty - Predictions', visual_targets)
  #cv2.imshow(f'{sampleid} - Targets - Spatial Penalty - Predictions', visualize_query)
  #cv2.imshow(f'{sampleid} Supports', visual_suports)
  cv2.imshow(f'{sampleid} Predictions', visual_predictions)
  cv2.waitKey(0)

if __name__ == '__main__':
  inference()


#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division
"""
Computing GC Content
"""
__author__ = 'caixia tian'
__date__= '2019/08/08'

import os
import argparse
import sys
import re

parser = argparse.ArgumentParser(description="input  parameters")
parser.add_argument('-i', '--fa',required=True, help=' a fasta file ')
parser.add_argument('-o', '--out',required=True, help='ouput file name')
args = parser.parse_args()

def gc_content( s ):
    seq = s.upper()
    total = len(seq)
    count = {}
    for base in seq:
        count.setdefault(base, 0) # 方法调用确保了键存在于 count 字典中(默认值是 0)
        count[base] = count[base] + 1
    gcnum = count['G'] + count['C']
    result = "%.2f%%" %(gcnum/total * 100)
    return result

with open(args.fa) as inp:
    stat={}
    for line in inp:
        if line.startswith('>'):
            seqid=line.replace('>','').split()[0]
            stat[seqid]=''
            #print(seqid)
            #break
        else:
            stat[seqid]+=line.replace('\n','').strip()

idlist=[]
gclist=[]
for name in stat:
    #print name,'\n',stat[name],'\n',gc_content(stat[name]),'\n'
    #break
    idlist.append(name)
    gclist.append(gc_content(stat[name]))

maxgc=max(gclist)
maxindex=gclist.index(maxgc)
output=idlist[maxindex] + '\n' + maxgc + '\n'
with open(args.out,"w") as oup:
    oup.write (output)

#########################################################
"""
Input fasta
>Rosalind_6404
CCTGCGGAAGATCGGCACTAGAATAGCCAGAACCGTTTCTCTGAGGCTTCCGGCCTTCCC
TCCCACTAATAATTCTGAGG
>Rosalind_5959
CCATCGGTAGCGCATCCTTAGTCCAATTAAGTCCCTATCCAGGCGCTCCGCCGAAGGTCT
ATATCCATTTGTCAGCAGACACGC
>Rosalind_0808
CCACCCTCGTGGTATGGCTAGGCATTCAGGAACCGGAGAACGCTTCAGACCAGCCCGGAC
TGGGAACCTGCGGGCAGTAGGTGGAAT

Output result
Rosalind_0808
60.92%
"""


from __future__ import absolute_import, division, print_function
import os
import hashlib
import zipfile
from six.moves import urllib

def readlines(filename):
    """Read all the lines in a text file and return as a list
    """
    with open(filename, 'r') as f:
        lines = f.read().splitlines()
    return lines

def normalize_image(x):
    """Rescale image pixels to span range [0, 1]
    """
    ma = float(x.max().cpu().data)
    mi = float(x.min().cpu().data)
    d = ma - mi if ma != mi else 1e5
    return (x - mi) / d

def sec_to_hm(t):
    """Convert time in seconds to time in hours, minutes and seconds
    e.g. 10239 -> (2, 50, 39)
    """
    t = int(t)
    s = t % 60
    t //= 60
    m = t % 60
    t //= 60
    return t, m, s

def sec_to_hm_str(t):
    """Convert time in seconds to a nice string
    e.g. 10239 -> '02h50m39s'
    """
    h, m, s = sec_to_hm(t)
    return "{:02d}h{:02d}m{:02d}s".format(h, m, s)

def download_model_if_doesnt_exist(model_name):
    """If pretrained kitti model doesn't exist, download and unzip it
    """
    # values are tuples of (<google cloud URL>, <md5 checksum>)
    download_paths = {
        "mono_640x192":
            ("https://storage.googleapis.com/niantic-lon-static/research/monodepth2/mono_640x192.zip",
             "a964b8356e08a02d009609d9e3928f7c"),
        "stereo_640x192":
            ("https://storage.googleapis.com/niantic-lon-static/research/monodepth2/stereo_640x192.zip",
             "3dfb76bcff0786e4ec07ac00f658dd07"),
        "mono+stereo_640x192":
            ("https://storage.googleapis.com/niantic-lon-static/research/monodepth2/mono%2Bstereo_640x192.zip",
             "c024d69012485ed05d7eaa9617a96b81"),
        "mono_no_pt_640x192":
            ("https://storage.googleapis.com/niantic-lon-static/research/monodepth2/mono_no_pt_640x192.zip",
             "9c2f071e35027c895a4728358ffc913a"),
        "stereo_no_pt_640x192":
            ("https://storage.googleapis.com/niantic-lon-static/research/monodepth2/stereo_no_pt_640x192.zip",
             "41ec2de112905f85541ac33a854742d1"),
        "mono+stereo_no_pt_640x192":
            ("https://storage.googleapis.com/niantic-lon-static/research/monodepth2/mono%2Bstereo_no_pt_640x192.zip",
             "46c3b824f541d143a45c37df65fbab0a"),
        "mono_1024x320":
            ("https://storage.googleapis.com/niantic-lon-static/research/monodepth2/mono_1024x320.zip",
             "0ab0766efdfeea89a0d9ea8ba90e1e63"),
        "stereo_1024x320":
            ("https://storage.googleapis.com/niantic-lon-static/research/monodepth2/stereo_1024x320.zip",
             "afc2f2126d70cf3fdf26b550898b501a"),
        "mono+stereo_1024x320":
            ("https://storage.googleapis.com/niantic-lon-static/research/monodepth2/mono%2Bstereo_1024x320.zip",
             "cdc5fc9b23513c07d5b19235d9ef08f7"),
        }

    if not os.path.exists("models"):
        os.makedirs("models")

    model_path = os.path.join("models", model_name)

    def check_file_matches_md5(checksum, fpath):
        if not os.path.exists(fpath):
            return False
        with open(fpath, 'rb') as f:
            current_md5checksum = hashlib.md5(f.read()).hexdigest()
        return current_md5checksum == checksum

    # see if we have the model already downloaded...
    if not os.path.exists(os.path.join(model_path, "encoder.pth")):

        model_url, required_md5checksum = download_paths[model_name]

        if not check_file_matches_md5(required_md5checksum, model_path + ".zip"):
            print("-> Downloading pretrained model to {}".format(model_path + ".zip"))
            urllib.request.urlretrieve(model_url, model_path + ".zip")

        if not check_file_matches_md5(required_md5checksum, model_path + ".zip"):
            print("   Failed to download a file which matches the checksum - quitting")
            quit()

        print("   Unzipping model...")
        with zipfile.ZipFile(model_path + ".zip", 'r') as f:
            f.extractall(model_path)

        print("   Model unzipped to {}".format(model_path))

def get_filenames(dataset, data_path, split):
    train_filenames = []
    val_filenames = []
    thermal = False
    if dataset == 'FLIR':
        train_files = os.listdir(os.path.join(data_path, 'train/PreviewData/'))
        train_files.sort()
        train_filenames.extend(os.path.join(data_path, 'train/PreviewData/') +
                               file for file in train_files[1:-1])

        video_files = os.listdir(os.path.join(data_path, 'video/PreviewData/'))
        video_files.sort()
        train_filenames.extend(os.path.join(data_path, 'video/PreviewData/') +
                               file for file in video_files[1:-1])

        val_files = os.listdir(os.path.join(data_path, 'valid/PreviewData/'))
        val_files.sort()
        val_filenames.extend(os.path.join(data_path, 'valid/PreviewData/') +
                             file for file in val_files[1:-1])
        thermal = True
    elif dataset == 'KAIST':
        train_files = os.path.join(data_path, 'training/')

        campus_train = os.listdir(os.path.join(train_files, 'Campus/THERMAL/'))
        campus_train.sort()
        residential_train = os.listdir(os.path.join(train_files, 'Residential/THERMAL/'))
        residential_train.sort()
        urban_train = os.listdir(os.path.join(train_files, 'Urban/THERMAL/'))
        urban_train.sort()

        train_filenames.extend(os.path.join(train_files, 'Campus/THERMAL/') +
                               file for file in campus_train[1:-1])
        train_filenames.extend(os.path.join(train_files, 'Residential/THERMAL/') +
                               file for file in residential_train[1:-1])
        train_filenames.extend(os.path.join(train_files, 'Urban/THERMAL/') +
                               file for file in urban_train[1:-1])

        val_files = os.path.join(data_path, 'testing/')

        campus_val = os.listdir(os.path.join(val_files, 'Campus/THERMAL/'))
        campus_val.sort()
        residential_val = os.listdir(os.path.join(val_files, 'Residential/THERMAL/'))
        residential_val.sort()
        urban_val = os.listdir(os.path.join(val_files, 'Urban/THERMAL/'))
        urban_val.sort()

        val_filenames.extend(os.path.join(val_files, 'Campus/THERMAL/') +
                             file for file in campus_val[1:-1])
        val_filenames.extend(os.path.join(val_files, 'Residential/THERMAL/') +
                             file for file in residential_val[1:-1])
        val_filenames.extend(os.path.join(val_files, 'Urban/THERMAL/') +
                             file for file in urban_val[1:-1])
        thermal = True
    elif dataset == 'CREOL':
        train_path = os.path.join(data_path, 'training/')
        train_sequences = os.listdir(train_path)

        for sequence in train_sequences:
            sequence_files = os.listdir(os.path.join(train_path, sequence))
            sequence_files.sort()
            train_filenames.extend(os.path.join(train_path, sequence, file) for file in sequence_files[1:-1])

        val_path = os.path.join(data_path, 'testing/')
        val_sequences = os.listdir(val_path)

        for sequence in val_sequences:
            sequence_files  = os.listdir(os.path.join(val_path, sequence))
            sequence_files.sort()
            val_filenames.extend(os.path.join(val_path, sequence, file) for file in sequence_files[1:-1])

        thermal = True

    else:
        fpath = os.path.join(os.path.dirname(__file__), "splits", split, "{}_files.txt")
        train_filenames = readlines(fpath.format("train"))
        val_filenames = readlines(fpath.format("val"))

    return train_filenames, val_filenames, thermal


from datetime import datetime

class Guest(object):
    def __init__(
        self,
        first_name,
        last_name,
        phone_number,
        email_address,
        total_number_of_guests_attending,
        not_attending,
    ):
        self.first_name: str or None = first_name
        self.first_name_lower: str or None = first_name.lower()
        self.last_name: str or None = last_name
        self.last_name_lower: str or None = last_name.lower()
        self.phone_number: str or None = phone_number
        self.email_address: str or None = email_address
        self.total_number_of_guests_attending: int = total_number_of_guests_attending
        self.last_updated: datetime = datetime.now()
        self.not_attending: bool = not_attending