import os

import pandas as pd
import numpy as np

import sqlalchemy
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import Session
from sqlalchemy import create_engine, func
from sqlalchemy import inspect
from sqlalchemy import MetaData
from sqlalchemy import Table

from flask import Flask, jsonify, render_template, redirect
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

#################################################
# Database Setup
#################################################

app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///db/World_Happiness_Life_Expectancy_db.sqlite"
db = SQLAlchemy(app)

engine2 = db.engine

@app.route("/")
def index():
    """Return the homepage."""

    return render_template("index.html")

@app.route("/visualization")
def index2():
    """Visualization Page."""

    return render_template("index2.html")

@app.route("/tensorflow")
def tensorflow():
    """Image Classification Page."""

    return render_template("image_test.html")

@app.route("/flaskcode")
def flaskcode():
    """Flask Code Page."""

    return render_template("flask.html")

@app.route("/pandas")
def index_pandas():
    """Data Cleaning and Wrangling Page."""

    return redirect("https://xliu510.github.io/Happiness_JN/")

@app.route("/httpcats")
def index_HttpCats():
    """Http Cats Page."""

    return redirect("https://xliu510.github.io/Happiness/cats_index.html")

@app.route("/tableau")
def tableau_link():
    """Tableau Page."""

    return redirect("https://public.tableau.com/profile/xing7154#!/vizhome/Happiness_15525426932400/CountryMap")

@app.route("/sandy_graph")
def index_sandyGraph():
    """Http Sandy's Graph Page."""

    return render_template("graph.html")

@app.route("/index_jessie")
def map_visual():
   """Bubble Plot"""
   return render_template("index_jessie.html")

@app.route("/happiness_score")
def map_score():
   """Happiness Score Map"""
   return render_template("plot_happiness_score.html")

@app.route("/happiness_rank")
def map_rank():
   """Happiness Rank Map"""
   return render_template("plot_happiness_rank.html")

@app.route("/happiness_kmeans")
def map_kmeans():
   """Happiness Kmeans Map"""
   return render_template("plot_happiness_kmeans_clustering.html")

@app.route("/region/happiness")
def happiness_region():

    #select query

    avg_happiness_region_select = ('SELECT region_2015, avg(happiness_score_2015) as avg_happiness_2015 '
                               ', avg(life_expectancy) as avg_life_2015 '
                               ', avg(hw.value) as avg_whr_2015 '
                              'FROM World_Happiness_Life_Expectancy_tb hl'
                               ' JOIN weekly_hours_avg_worked_job_df_2015_2017_tb hw ON hl.country = hw.country '
                              'GROUP BY region_2015')

    #read query into dataframe
    avg_happiness_region_df = pd.read_sql(avg_happiness_region_select, engine2.connect())

    #convert dataframe to list
    happiness_region = avg_happiness_region_df["Region_2015"].values.tolist()
    happiness_score = avg_happiness_region_df["avg_happiness_2015"].values.tolist()
    happiness_life = avg_happiness_region_df["avg_life_2015"].values.tolist()
    happiness_work = avg_happiness_region_df["avg_whr_2015"].values.tolist()

    #create happiness object
    happiness = {
        "region": happiness_region,
        "happiness": happiness_score,
        "life": happiness_life,
        "work": happiness_work
        }

    #return as json object
    return jsonify(happiness)

@app.route("/barplot/<feature>")
def graph_barplot(feature):

    selected_feature = None

    if feature == 'adultmortality':
        selected_feature = 'adult_mortality'
    elif feature == 'lifeexpectancy':
        selected_feature = 'life_expectancy'
    elif feature == 'gdp':
        selected_feature = 'gdp_per_capita_2015'
    elif feature == 'family':
        selected_feature = 'family_2015'
    elif feature == 'health':
        selected_feature = 'health_2015'
    elif feature == 'freedom':
        selected_feature = 'freedom_2015'
    elif feature == 'income':
        selected_feature = 'income'

    #select query
    happiness_region_select = ('SELECT country, happiness_score_2015 '
                           f', {selected_feature} as Second_Feature '
                            'FROM World_Happiness_Life_Expectancy_tb '
                            'ORDER BY happiness_score_2015 DESC LIMIT 50')

    #read query into dataframe
    happiness_region_df = pd.read_sql(happiness_region_select, engine2.connect())

    #convert dataframe to dictionary
    happiness_region_dict = happiness_region_df.to_dict('records')

    #return as json object
    return jsonify(happiness_region_dict)

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


"""
Actually using the feature extractor!!
dump tuple: name, author, avg_sent_len, num_unique_terms, adv_adj_pct
"""
import statistics

import os
from feature_extractor import Extractor
import pickle
from textblob import TextBlob

def remove_negatives(list):
    out = []
    for i in list:
        if i >= 0.0:
            out.append(i)
    return out
def normalize_row(slist):
    #removes negatives from consideration
    #negatives are the result of an error or non-english text
    f_list = remove_negatives(slist)

    mean = statistics.mean(f_list)
    standard_deviation = statistics.stdev(f_list)
    if standard_deviation == 0.0:
        standard_deviation = 1.0
    out = []
    for i in slist:
        out.append((i-mean)/standard_deviation)
    return out

def processTexts(path):
    folders = ["a1896/", "a861/", "a507/", "a481/", "a326/", "a314/", "a125/", "a111/", "a93/", "a69/"]
    try:
        stat_dict = {}
        """This code gets ALL files
        for folder in os.listdir(path):
            print("Opening", folder)
            for filename in os.listdir(path+folder):
        """
        stats = ("","","")
        stats_list = [[],[],[]]
        for folder in folders:
            count = 0
            for filename in os.listdir(path+folder):
                print("\topening", filename)
                f = open(path+folder+"/"+filename, "r")
                print("\topened")
                tb = TextBlob(f.read(900)[100:]) #look at characters 100-900
                if len(tb.words) > 0 and tb.detect_language() != "en":
                    print(filename +" is not an english text. skipping to next document")
                    f.close()
                    stats = (-1,-1,-1)

                else:
                    text = f.read()
                    f.close()
                    #get author/title later. use gutenberg IDs now

                    ex = Extractor(text)
                    try:
                        stats = ex.dump(False)
                        if stats[0] == 0:
                            raise ZeroDivisionError

                        #for a smaller dataset
                        count += 1
                    except ZeroDivisionError:
                        print("Empty file.")
                        stats = (-1,-1,-1)
                for i in range(len(stats)):
                    stats_list[i].append(stats[i])

                if folder not in stat_dict.keys():
                    stat_dict[folder] = {filename:stats}
                else:
                    stat_dict[folder][filename] = stats
                #for a smaller dataset, continued
                if count >= 15:
                    break
        pickle.dump(stat_dict, open("sd_nonnormalized.p", "wb"))
        pickle.dump(stats_list, open("sl_nonnormalized.p", "wb"))

        print("Pickle of NON-NORMALIZED stats dumped.")

        return stat_dict, stats_list

    except OSError:
        print("File(s) not found.")
        return None

def normalize(stat_dict, stats_list):
    folders = ["a1896/", "a861/", "a507/", "a481/", "a326/", "a314/", "a125/", "a111/", "a93/", "a69/"]
    path = "text/"
    i = 0 #to loop through statlists
    #stats_list is a list of three lists (word count, avg sent len, % adv/adj) with a stat for each doc. it is terrible to read. our apologies.
    for i in range(len(stats_list)):
        stats_list[i] = normalize_row(stats_list[i])
    print(str(len(stats_list[2])))
    i = 0
    for folder in folders:
        for filename in os.listdir(path+folder):
            #skip over negative values, aka, texts that have been marked as non english or errors

            print(folder+" "+filename)
            if stats_list[0][i] >= 0:
                stat_dict[folder][filename] = (stats_list[0][i], stats_list[1][i], stats_list[2][i])
            i+=1

    print("Pickling...")
    pickle.dump(stat_dict, open("sd_NORMAL.p", "wb"))
    print("Pickle dumped.")

def main():
    try:
        sd = pickle.load(open("sd_nonnormalized.p", "rb"))
        sl = pickle.load(open("sl_nonnormalized.p", "rb"))
    except FileNotFoundError:
        sd, sl = processTexts("text/")
    try:
        normalize(sd, sl)
    except (OSError, FileNotFoundError):
        print("yer files done goofed")

main()


#!/usr/bin/env python
"""
This contains some of what is common to all of the peak finding algorithms.

Hazen 03/17
"""
import numpy
import os
import tifffile

import storm_analysis.sa_library.daxwriter as daxwriter
import storm_analysis.sa_library.i3dtype as i3dtype
import storm_analysis.sa_library.ia_utilities_c as utilC
import storm_analysis.sa_library.matched_filter_c as matchedFilterC
import storm_analysis.sa_library.parameters as params
import storm_analysis.sa_library.readinsight3 as readinsight3

import storm_analysis.simulator.draw_gaussians_c as dg

#
# Functions.
#
def gaussianPSF(shape, sigma):
    """
    Return a normalized 2D Gaussian, usually used for creating MatchedFilter objects.
    """
    psf = dg.drawGaussiansXY(shape,
                             numpy.array([0.5*shape[0]]),
                             numpy.array([0.5*shape[1]]),
                             sigma = sigma)
    return psf/numpy.sum(psf)

def getPeakLocations(peak_filename, margin, pixel_size, sigma):
    """
    This is for if you already know where your want fitting to happen, as
    for example in a bead calibration movie and you just want to use the
    approximate locations as inputs for fitting.

    There are two choices for peak_locations file format:

    1. A text file with the peak x, y, height and background values as
       white spaced columns (x and y positions are in pixels as determined
       using visualizer).

       1.0 2.0 1000.0 100.0
       10.0 5.0 2000.0 200.0
       ...

    2. An Insight3 format localization file. In this case only the localizations
       in the first frame will be used.
    """
    if os.path.exists(peak_filename):
        print("Using peak starting locations specified in", peak_filename)
    elif os.path.exists(os.path.basename(peak_filename)):
        peak_filename = os.path.basename(peak_filename)
        print("Using peak starting locations specified in", peak_filename)

    # Try to read file as if it was an Insight3 binary file.
    #
    # FIXME: This won't work properly for analysis with the 'inverted' parameter
    #        set to True.
    #
    if readinsight3.checkStatus(peak_filename):
        is_text = False

        frame_number = 1
        with readinsight3.I3Reader(peak_filename) as i3r:
            i3_locs = i3r.getMoleculesInFrame(frame_number)

        peak_locations = i3dtype.convertToMultiFit(i3_locs, 1, 1, frame_number, pixel_size)

    else:
        is_text = True

        # Load peak x,y locations.
        peak_locs = numpy.loadtxt(peak_filename, ndmin = 2)

        # Create peak array.
        peak_locations = numpy.zeros((peak_locs.shape[0],
                                      utilC.getNPeakPar()))
        peak_locations[:,utilC.getXCenterIndex()] = peak_locs[:,1] - 1.0
        peak_locations[:,utilC.getYCenterIndex()] = peak_locs[:,0] - 1.0
        peak_locations[:,utilC.getHeightIndex()] = peak_locs[:,2]
        peak_locations[:,utilC.getBackgroundIndex()] = peak_locs[:,3]

        peak_locations[:,utilC.getXWidthIndex()] = numpy.ones(peak_locs.shape[0]) * sigma
        peak_locations[:,utilC.getYWidthIndex()] = numpy.ones(peak_locs.shape[0]) * sigma

    # Adjust positions for finding/fitting margin.
    peak_locations[:,utilC.getXCenterIndex()] += margin
    peak_locations[:,utilC.getYCenterIndex()] += margin

    print("Loaded", peak_locations.shape[0], "peak locations")
    #
    # We return is_text as the caller might want to do different things if
    # the file is text, like initialize the Z value.
    #
    return [peak_locations, is_text]

def padArray(ori_array, pad_size):
    """
    Pads out an array to a large size.

    ori_array - A 2D numpy array.
    pad_size - The number of elements to add to each of the "sides" of the array.

    The padded 2D numpy array.
    """
    if (pad_size > 0):
        [x_size, y_size] = ori_array.shape
        lg_array = numpy.ones((x_size+2*pad_size,y_size+2*pad_size))
        lg_array[pad_size:(x_size+pad_size),pad_size:(y_size+pad_size)] = ori_array.astype(numpy.float64)
        lg_array[0:pad_size,:] = numpy.flipud(lg_array[pad_size:2*pad_size,:])
        lg_array[(x_size+pad_size):(x_size+2*pad_size),:] = numpy.flipud(lg_array[x_size:(x_size+pad_size),:])
        lg_array[:,0:pad_size] = numpy.fliplr(lg_array[:,pad_size:2*pad_size])
        lg_array[:,(y_size+pad_size):(y_size+2*pad_size)] = numpy.fliplr(lg_array[:,y_size:(y_size+pad_size)])
        return lg_array

    else:
        return ori_array

#
# Classes.
#
def FittingException(Exception):
    pass

class PeakFinder(object):
    """
    Base class for peak finding. This handles identification of peaks in an image.

    If you want to modify this with a custom peak finder or an alternative
    way to estimate the background, the recommended approach is to sub-class this
    class and then modify backgroundEstimator(), newImage() and peakFinder().
    """
    # Hard-wired defaults.
    unconverged_dist = 5.0  # Distance between peaks for marking as unconverged (this is multiplied by parameters.sigma)
    new_peak_dist = 1.0     # Minimum allowed distance between new peaks and current peaks.

    def __init__(self, parameters = None, **kwds):
        """
        This is called once at the start of analysis to initialize the
        parameters that will be used for peak fitting.

        parameters - A parameters object.
        """
        super(PeakFinder, self).__init__(**kwds)

        # Initialized from parameters.
        self.find_max_radius = parameters.getAttr("find_max_radius")     # Radius (in pixels) over which the maxima is maximal.
        self.iterations = parameters.getAttr("iterations")               # Maximum number of cycles of peak finding, fitting and subtraction to perform.
        self.sigma = parameters.getAttr("sigma")                         # Peak sigma (in pixels).
        self.threshold = parameters.getAttr("threshold")                 # Peak minimum threshold in units of sigma (as in "3 sigma effect").

        # Other member variables.
        self.background = None                                           # Current estimate of the image background.
        self.bg_filter = None                                            # Background MatchedFilter object.
        self.camera_variance = None                                      # Camera variance, only relevant for a sCMOS camera.
        self.check_mode = False                                          # Run in diagnostic mode. Only useful for debugging.
        self.image = None                                                # The original image.
        self.margin = PeakFinderFitter.margin                            # Size of the unanalyzed "edge" around the image.
        self.neighborhood = PeakFinder.unconverged_dist * self.sigma     # Radius for marking neighbors as unconverged.
        self.new_peak_radius = PeakFinder.new_peak_dist                  # Minimum allowed distance between new peaks and current peaks.
        self.parameters = parameters                                     # Keep access to the parameters object.
        self.peak_locations = None                                       # Initial peak locations, as explained below.
        self.peak_mask = None                                            # Mask for limiting peak identification to a particular AOI.

        # Print warning about check mode
        if self.check_mode:
            print("Warning! Running in check mode!")

        # Only do one cycle of peak finding as we'll always return the same locations.
        if parameters.hasAttr("peak_locations"):
            if (self.iterations != 1):
                print("WARNING: setting number of iterations to 1!")
                self.iterations = 1

    def backgroundEstimator(self, image):
        """
        This method does the actual background estimation. It is just a simple
        low pass filter.

        Override this if you want to change how the background is estimated.

        FIXME: Convolution should be weighted by the camera variance if it is
               not uniform?
        """
        return self.bg_filter.convolve(image)

    def cleanUp(self):
        pass

    def findPeaks(self, fit_peaks_image, peaks):
        """
        Finds the peaks in an image & adds to the current list of peaks.

        fit_peaks_image - The current fit image.
        peaks - The current list of peaks.

        return - [True/False if new peaks were added to the current list, the new peaks]
        """

        # Use pre-specified peak locations if available, e.g. bead calibration.
        if self.peak_locations is not None:
            new_peaks = self.peak_locations

        # Otherwise, identify local maxima in the image and initialize fitting parameters.
        else:
            new_peaks = self.peakFinder(fit_peaks_image)

        # Update new peak identification threshold (if necessary).
        # Also, while threshold is greater than min_threshold we
        # are automatically not done.
        found_new_peaks = False
        if (self.cur_threshold > self.threshold):
            self.cur_threshold -= 1.0
            found_new_peaks = True

        # If we did not find any new peaks then we may be done.
        if (new_peaks.shape[0] == 0):
            return [found_new_peaks, peaks]

        # Add new peaks to the current list of peaks if it exists,
        # otherwise these peaks become the current list.
        if isinstance(peaks, numpy.ndarray):
            merged_peaks = self.mergeNewPeaks(peaks, new_peaks)

            # If none of the new peaks are valid then we may be done.
            if (merged_peaks.shape[0] == peaks.shape[0]):
                return [found_new_peaks, merged_peaks]
            else:
                return [True, merged_peaks]
        else:
            return [True, new_peaks]

    def mergeNewPeaks(self, peaks, new_peaks):
        """
        Merge new peaks into the current list of peaks.
        """
        return utilC.mergeNewPeaks(peaks,
                                   new_peaks,
                                   self.new_peak_radius,
                                   self.neighborhood)

    def newImage(self, new_image):
        """
        This is called once at the start of the analysis of a new image.

        new_image - A 2D numpy array.
        """
        # Make a copy of the starting image.
        self.image = numpy.copy(new_image)

        # Initialize new peak minimum threshold. If we are doing more
        # than one iteration we start a bit higher and come down to
        # the specified threshold.
        if(self.iterations>4):
            self.cur_threshold = self.threshold + 4.0
        else:
            self.cur_threshold = self.threshold + float(self.iterations)

        # Create mask to limit peak finding to a user defined sub-region of the image.
        if self.peak_mask is None:
            self.peak_mask = numpy.ones(new_image.shape)
            if self.parameters.hasAttr("x_start"):
                self.peak_mask[0:self.parameters.getAttr("x_start")+self.margin,:] = 0.0
            if self.parameters.hasAttr("x_stop"):
                self.peak_mask[self.parameters.getAttr("x_stop")+self.margin:-1,:] = 0.0
            if self.parameters.hasAttr("y_start"):
                self.peak_mask[:,0:self.parameters.getAttr("y_start")+self.margin] = 0.0
            if self.parameters.hasAttr("y_stop"):
                self.peak_mask[:,self.parameters.getAttr("y_stop")+self.margin:-1] = 0.0

        # Create filter objects if necessary.
        if self.bg_filter is None:

            # Create matched filter for background.
            bg_psf = gaussianPSF(new_image.shape, self.parameters.getAttr("background_sigma"))
            self.bg_filter = matchedFilterC.MatchedFilter(bg_psf)

            #
            # Create matched filter for foreground as well as a matched filter
            # for calculating the expected variance of the background if it was
            # smoothed on the same scale as the foeground.
            #
            if self.parameters.hasAttr("foreground_sigma"):
                if (self.parameters.getAttr("foreground_sigma") > 0.0):
                    fg_psf = gaussianPSF(new_image.shape, self.parameters.getAttr("foreground_sigma"))
                    self.fg_mfilter = matchedFilterC.MatchedFilter(fg_psf)
                    self.fg_vfilter = matchedFilterC.MatchedFilter(fg_psf * fg_psf)

    def setVariance(self, camera_variance):
        """
        Set the camera variance, usually used in sCMOS analysis.
        """
        self.camera_variance = padArray(camera_variance, self.margin)
        return self.camera_variance

    def subtractBackground(self, image, bg_estimate):
        """
        Estimate the background for the image.

        Note: image is the residual image after the found / fit
              localizations have been subtracted out.

        image - The image to estimate the background of.
        bg_estimate - An estimate of the background.
        """

        # If we are provided with an estimate of the background
        # then just use it.
        if bg_estimate is not None:
            self.background = bg_estimate

        # Otherwise make our own estimate.
        else:
            self.background = self.backgroundEstimator(image)

        if self.check_mode:
            with tifffile.TiffWriter("bg_estimate.tif") as tf:
                tf.save(numpy.transpose(self.background.astype(numpy.float32)))

class PeakFinderGaussian(PeakFinder):
    """
    This is the peak finder for 3D-DAOSTORM and sCMOS, it handles Gaussian shaped
    peaks.
    """
    def __init__(self, parameters = None, **kwds):
        """
        This is called once at the start of analysis to initialize the
        parameters that will be used for peak fitting.

        parameters - A parameters object.
        """
        kwds["parameters"] = parameters
        super(PeakFinderGaussian, self).__init__(**kwds)

        # Initialized from parameters.
        self.z_value = self.parameters.getAttr("z_value", 0.0)           # The starting z value to use for peak fitting.

        # Other member variables.
        self.fg_mfilter = None                                           # Foreground MatchedFilter object (may be None).
        self.fg_vfilter = None                                           # Foreground variance MatchedFilter object, will be none if self.fg_mfilter is None.
        self.taken = None                                                # Spots in the image where a peak has already been added.

        # Load peak locations if specified.
        #
        # FIXME: The starting z value is always 0.0. Not sure why we don't use
        #        self.z_value for this. Though I guess it would only really be
        #        relevant for the 'Z' fitting model.
        #
        if parameters.hasAttr("peak_locations"):
            [self.peak_locations, is_text] = getPeakLocations(parameters.getAttr("peak_locations"),
                                                              self.margin,
                                                              parameters.getAttr("pixel_size"),
                                                              self.sigma)

    def newImage(self, new_image):
        """
        This is called once at the start of the analysis of a new image.

        new_image - A 2D numpy array.
        """
        super(PeakFinderGaussian, self).newImage(new_image)

        # Reset taken mask.
        self.taken = numpy.zeros(new_image.shape, dtype=numpy.int32)

    def peakFinder(self, fit_peaks_image):
        """
        This method does the actual peak finding.

        Override this if you want to change the peak finding behaviour.
        """
        # Calculate background variance.
        #
        # Note the assumption here that we are working in units of photo-electrons
        # so Poisson statistics applies, variance = mean.
        #
        bg_var = self.background + fit_peaks_image

        # Add camera variance if set.
        if self.camera_variance is not None:
            bg_var += self.camera_variance

        # Calculate weighted variance if the image is being smoothed.
        if self.fg_vfilter is not None:
            bg_var = self.fg_vfilter.convolve(bg_var)

        if self.check_mode:
            with tifffile.TiffWriter("variances.tif") as tf:
                tf.save(numpy.transpose(bg_var.astype(numpy.float32)))

        # Check for problematic values.
        #
        # Note: numpy will also complain when we try to take the sqrt of a negative number.
        #
        if self.check_mode:
            mask = (bg_var <= 0.0)
            if (numpy.sum(mask) > 0):
                print("Warning! zero and/or negative values detected in background variance!")

        # Convert to standard deviation.
        bg_std = numpy.sqrt(bg_var)

        # Calculate foreground.
        foreground = self.image - self.background - fit_peaks_image

        # Calculate smoothed image if we have a foreground filter.
        if self.fg_mfilter is not None:
            foreground = self.fg_mfilter.convolve(foreground)

        if self.check_mode:
            with tifffile.TiffWriter("foreground.tif") as tf:
                tf.save(numpy.transpose(foreground.astype(numpy.float32)))

        # Calculate foreground in units of signal to noise.
        foreground = foreground/bg_std

        if self.check_mode:
            with tifffile.TiffWriter("fg_bg_ratio.tif") as tf:
                tf.save(numpy.transpose(foreground.astype(numpy.float32)))

        # Mask the image so that peaks are only found in the AOI.
        masked_image = foreground * self.peak_mask

        # Identify local maxima in the masked image.
        [new_peaks, self.taken] = utilC.findLocalMaxima(masked_image,
                                                        self.taken,
                                                        self.cur_threshold,
                                                        self.find_max_radius,
                                                        self.margin)

        # Fill in initial values for peak height, background and sigma.
        new_peaks = utilC.initializePeaks(new_peaks,         # The new peaks.
                                          self.image,        # The original image.
                                          self.background,   # The current estimate of the background.
                                          self.sigma,        # The starting sigma value.
                                          self.z_value)      # The starting z value.

        return new_peaks

class PeakFinderArbitraryPSF(PeakFinder):
    """
    This is the base class for Spliner and Pupilfn, it handles arbitrary
    PSF shapes possibly with multiple z values.
    """
    def __init__(self, parameters = None, psf_object = None, **kwds):
        kwds["parameters"] = parameters
        super(PeakFinderArbitraryPSF, self).__init__(**kwds)

        self.height_rescale = []
        self.fg_mfilter = []
        self.fg_mfilter_zval = []
        self.fg_vfilter = []
        self.psf_object = psf_object
        self.taken = []
        self.z_values = []

        #
        # Note: self.z_values is the Z position in 'internal' units, i.e. the units
        #       that the PSF generation library uses. For splines for example this
        #       is the spline size in Z.
        #
        #       self.fg_mfilter_zval is the Z position in nanometers.
        #
        self.margin = psf_object.getMargin()

        self.fg_mfilter_zval = parameters.getAttr("z_value", [0.0])
        for zval in self.fg_mfilter_zval:
            self.z_values.append(self.psf_object.getScaledZ(zval))

        if parameters.hasAttr("peak_locations"):
            [self.peak_locations, is_text] = getPeakLocations(parameters.getAttr("peak_locations"),
                                                              self.margin,
                                                              parameters.getAttr("pixel_size"),
                                                              self.sigma)

            zc_index = utilC.getZCenterIndex()
            # Set initial z value (for text files).
            if is_text:
                self.peak_locations[:,zc_index] = self.z_value[0]

            # Convert z value to PSF FFT units (Insight3 localization files).
            else:
                for i in range(self.peak_locations.shape[0]):
                    self.peak_locations[i,zc_index] = self.psf_object.getScaledZ(self.peak_locations[i,zc_index])

    def newImage(self, new_image):
        """
        This is called once at the start of the analysis of a new image.

        new_image - A 2D numpy array.
        """
        super(PeakFinderArbitraryPSF, self).newImage(new_image)

        #
        # If does not already exist, create filter objects from
        # the PSF at different z values.
        #
        # As not all PSFs will be maximal in the center we can't just
        # use the image intensity at the center as the starting
        # height value. Instead we will use the intensity at the
        # peak center of the convolved image, then adjust this
        # value by the height_rescale parameter.
        #
        if (len(self.fg_mfilter) == 0):
            for zval in self.fg_mfilter_zval:
                psf = self.psf_object.getPSF(zval,
                                             shape = new_image.shape,
                                             normalize = False)
                psf_norm = psf/numpy.sum(psf)
                self.fg_mfilter.append(matchedFilterC.MatchedFilter(psf_norm))
                self.fg_vfilter.append(matchedFilterC.MatchedFilter(psf_norm * psf_norm))

                #
                # This is used to convert the height measured in the
                # convolved image to the correct height in the original
                # image, as this is the height unit that is used in
                # fitting.
                #
                # If you convolved a localization with itself the final
                # height would be sum(loc * loc). Here we are convolving
                # the localizations with a unit sum PSF, so the following
                # should give us the correct initial height under the
                # assumption that the shape of the localization is
                # pretty close to the shape of the PSF.
                #
                self.height_rescale.append(1.0/numpy.sum(psf * psf_norm))

                # Save a picture of the PSF for debugging purposes.
                if self.check_mode:
                    print("psf max", numpy.max(psf))
                    filename = "psf_{0:.3f}.tif".format(zval)
                    tifffile.imsave(filename, psf.astype(numpy.float32))

        self.taken = []
        for i in range(len(self.fg_mfilter)):
            self.taken.append(numpy.zeros(new_image.shape, dtype=numpy.int32))

    def peakFinder(self, fit_peaks_image):
        """
        This method does the actual peak finding.
        """
        all_new_peaks = None

        if self.check_mode:
            tifffile.imsave("fit_peaks.tif", numpy.transpose(fit_peaks_image.astype(numpy.float32)))

        # Calculate background variance.
        #
        # Notes:
        #
        # 1. The assumption here is that we are working in units of photo-electrons
        #    so Poisson statistics applies, variance = mean.
        #
        # 2. We use the absolute value of fit_peaks_image as some fitters (such as
        #    Spliner) will sometimes return this array with negative values. This is
        #    still probably not the correct way to handle this.
        #
        bg_var = self.background + numpy.abs(fit_peaks_image)

        # Add camera variance if set.
        if self.camera_variance is not None:
            bg_var += self.camera_variance

        #
        # Find peaks in image convolved with the PSF at different z values.
        #
        if self.check_mode:
            bg_tif = tifffile.TiffWriter("background.tif")
            fg_tif = tifffile.TiffWriter("foreground.tif")
            fg_bg_ratio_tif = tifffile.TiffWriter("fg_bg_ratio.tif")

        for i in range(len(self.fg_mfilter)):

            # Estimate background variance at this particular z value.
            background = self.fg_vfilter[i].convolve(bg_var)

            # Check for problematic values.
            #
            # Note: numpy will also complain when we try to take the sqrt of a negative number.
            #
            if self.check_mode:
                mask = (background <= 0.0)
                if (numpy.sum(mask) > 0):
                    print("Warning! zero and/or negative values detected in background variance!")

            # Convert to standard deviation.
            bg_std = numpy.sqrt(background)

            # Calculate foreground.
            foreground = self.image - self.background - fit_peaks_image
            foreground = self.fg_mfilter[i].convolve(foreground)

            # Calculate foreground in units of signal to noise.
            fg_bg_ratio = foreground/bg_std

            if self.check_mode:
                bg_tif.save(numpy.transpose(background.astype(numpy.float32)))
                fg_tif.save(numpy.transpose(foreground.astype(numpy.float32)))
                fg_bg_ratio_tif.save(numpy.transpose(fg_bg_ratio.astype(numpy.float32)))

            # Mask the image so that peaks are only found in the AOI.
            masked_image = fg_bg_ratio * self.peak_mask

            # Identify local maxima in the masked ratio image.
            [new_peaks, taken] = utilC.findLocalMaxima(masked_image,
                                                       self.taken[i],
                                                       self.cur_threshold,
                                                       self.find_max_radius,
                                                       self.margin)

            # Fill in initial values for peak height, background and sigma.
            new_peaks = utilC.initializePeaks(new_peaks,                    # The new peaks.
                                              foreground + self.background, # Convolved image + background.
                                              self.background,              # The current estimate of the background.
                                              self.sigma,                   # The starting sigma value.
                                              self.z_values[i])             # The starting z value.

            # Correct initial peak heights, self.height_rescale is an estimate
            # of the effect of PSF convolution on the height of the original
            # localization.
            h_index = utilC.getHeightIndex()
            new_peaks[:,h_index] = new_peaks[:,h_index] * self.height_rescale[i]

            if all_new_peaks is None:
                all_new_peaks = new_peaks
            else:
                all_new_peaks = numpy.append(all_new_peaks, new_peaks, axis = 0)

        if self.check_mode:
            fg_tif.close()
            fg_bg_ratio_tif.close()

        #
        # Remove the dimmer of two peaks with similar x,y values but different z values.
        #
        if (len(self.fg_mfilter) > 1):

            if self.check_mode:
                print("Before peak removal", all_new_peaks.shape)
                if False:
                    for i in range(all_new_peaks.shape[0]):
                        print(all_new_peaks[i,:])
                print("")

            all_new_peaks = utilC.removeClosePeaks(all_new_peaks,
                                                   self.find_max_radius,
                                                   self.find_max_radius)

            if self.check_mode:
                print("After peak removal", all_new_peaks.shape)
                if False:
                    for i in range(all_new_peaks.shape[0]):
                        print(all_new_peaks[i,:])
                print("")

        return all_new_peaks

class PeakFitter(object):
    """
    Base class for peak fitting. This handles refinement of the
    parameters of the peaks that were identified with PeakFinder.

    The actual fitting is done by an the self.mfitter object, this
    is primarily just a wrapper for the self.mfitter object.
    """

    def __init__(self, mfitter = None, parameters = None, **kwds):
        """
        parameters - A (fitting) parameters object.
        """
        super(PeakFitter, self).__init__(**kwds)

        self.image = None      # The image for peak fitting.
        self.mfitter = mfitter # An instance of a sub-class of the MultiFitter class.

        self.sigma = parameters.getAttr("sigma")                   # Peak sigma (in pixels).
        self.neighborhood = self.sigma*PeakFinder.unconverged_dist # Radius for marking neighbors as unconverged.

    def cleanUp(self):
        self.mfitter.cleanup()

    def fitPeaks(self, peaks):
        """
        Performs a single iteration of peak fitting.

        peaks - A numpy array of peaks to fit.

        return - [updated peaks, fit peaks image]
        """
        # Fit to update peak locations.
        [fit_peaks, fit_peaks_image] = self.peakFitter(peaks)
        fit_peaks = self.mfitter.getGoodPeaks(fit_peaks,
                                              0.5*self.sigma)

        # Remove peaks that are too close to each other & refit.
        fit_peaks = utilC.removeClosePeaks(fit_peaks, self.sigma, self.neighborhood)
        [fit_peaks, fit_peaks_image] = self.peakFitter(fit_peaks)

        fit_peaks = self.mfitter.getGoodPeaks(fit_peaks,
                                              0.5 * self.sigma)

        return [fit_peaks, fit_peaks_image]

    def newImage(self, new_image):
        """
        new_image - A new image (2D numpy array).
        """
        self.mfitter.newImage(new_image)

    def peakFitter(self, peaks):
        """
        This method does the actual peak fitting.
        """
        fit_peaks = self.mfitter.doFit(peaks)
        fit_peaks_image = self.mfitter.getFitImage()
        return [fit_peaks, fit_peaks_image]

class PeakFitterArbitraryPSF(PeakFitter):
    """
    Class for arbitrary PSF based peak fitting.
    """
    def __init__(self, **kwds):
        super(PeakFitterArbitraryPSF, self).__init__(**kwds)

        # Update refitting neighborhood parameter.
        self.neighborhood = int(0.5 * self.mfitter.getSize()) + 1

    def rescaleZ(self, peaks):
        """
        Convert from fitting z units to microns.
        """
        return self.mfitter.rescaleZ(peaks)

class PeakFinderFitter(object):
    """
    Base class to encapsulate peak finding and fitting.

    To get an idea of how all the pieces are supposed to go together, please see:
      3d_daostorm/find_peaks.py
      sCMOS/find_peaks.py
    """

    margin = 10   # Size of the unanalyzed edge around the image. This is also
                  #  a constant in the C libraries, so if you change this you
                  #  also need to change that.

    def __init__(self, peak_finder = None, peak_fitter = None, **kwds):
        """
        peak_finder - A PeakFinder object.
        peak_fitter - A PeakFitter object.
        """
        super(PeakFinderFitter, self).__init__(**kwds)

        self.peak_finder = peak_finder
        self.peak_fitter = peak_fitter

        #
        # Update margin. Normally this is 10 as specified above for the
        # class variable, but the fitters that use splines may change this.
        #
        self.margin = self.peak_finder.margin

    def analyzeImage(self, movie_reader, save_residual = False, verbose = False):
        """
        movie_reader - analysis_io.MovieReader object.
        save_residual - (Optional) Save the residual image after peak fitting, default is False.

        return - [Found peaks, Image residual]
        """
        # Load image (in photo-electrons).
        [image, fit_peaks_image] = self.loadImage(movie_reader)

        # Load background estimate (in photo-electrons).
        bg_estimate = self.loadBackgroundEstimate(movie_reader)

        self.peak_finder.newImage(image)
        self.peak_fitter.newImage(image)

        if save_residual:
            resid_tif = tifffile.TiffWriter("residual.tif")

        peaks = False
        for i in range(self.peak_finder.iterations):
            if save_residual:
                resid_tif.save(numpy.transpose((image - fit_peaks_image).astype(numpy.float32)))

            # Update background estimate.
            self.peak_finder.subtractBackground(image - fit_peaks_image, bg_estimate)

            # Find new peaks.
            [found_new_peaks, peaks] = self.peak_finder.findPeaks(fit_peaks_image, peaks)

            # Fit new peaks.
            if isinstance(peaks, numpy.ndarray):
                [peaks, fit_peaks_image] = self.peak_fitter.fitPeaks(peaks)

            if verbose:
                if isinstance(peaks, numpy.ndarray):
                    print(" peaks:", i, found_new_peaks, peaks.shape[0])
                else:
                    print(" peaks:", i, found_new_peaks, "NA")

            if not found_new_peaks:
                break

        if save_residual:
            resid_tif.save(numpy.transpose((image - fit_peaks_image).astype(numpy.float32)))
            resid_tif.close()

        if isinstance(peaks, numpy.ndarray):
            peaks[:,utilC.getXCenterIndex()] -= float(self.margin)
            peaks[:,utilC.getYCenterIndex()] -= float(self.margin)

        return [peaks, fit_peaks_image]

    def cleanUp(self):
        self.peak_finder.cleanUp()
        self.peak_fitter.cleanUp()

    def getConvergedPeaks(self, peaks, verbose = False):
        """
        peaks - A 1D numpy array containing the peaks.

        return - A 1D numpy array containing only the converged peaks.
        """
        if (peaks.shape[0] > 0):
            status_index = utilC.getStatusIndex()
            mask = (peaks[:,status_index] == 1.0)  # 0.0 = running, 1.0 = converged.
            if verbose:
                print(" ", numpy.sum(mask), "converged out of", peaks.shape[0])
            return peaks[mask,:]
        else:
            return peaks

    def loadBackgroundEstimate(self, movie_reader):
        bg_estimate = movie_reader.getBackground()
        if bg_estimate is not None:
            bg_estimate = padArray(bg_estimate, self.margin)

        return bg_estimate

    def loadImage(self, movie_reader):
        image = padArray(movie_reader.getFrame(), self.margin)
        fit_peaks_image = numpy.zeros(image.shape)
        return [image, fit_peaks_image]

class PeakFinderFitterArbitraryPSF(PeakFinderFitter):
    """
    Class for arbitrary PSF based peak finding and fitting.
    """
    def getConvergedPeaks(self, peaks):
        converged_peaks = super(PeakFinderFitterArbitraryPSF, self).getConvergedPeaks(peaks)
        return self.peak_fitter.rescaleZ(converged_peaks)

class PSFFunction(object):
    """
    This is the base class for handling the PSF for fitters that use
    arbitrary PSFs such as PSFFFT, PupilFN and Spliner. In theory it
    handles all of the details of the PSF, such as how many pixels
    it covers, how much margin to add to the image, how to convert
    Z values, etc..
    """
    def getCPointer(self):
        """
        Returns a pointer to the C library structure that is
        used to describe the PSF.

        pupilData in pupilfn/pupil_function.h for example.
        """
        assert False

    def getMargin(self):
        """
        Return the margin to add to the image for finding/fitting.
        """
        assert False

    def getPSF(self, z_value, shape = None, normalize = False):
        """
        Return an image of the PSF at z_value, centered in an
        array of size shape.
        """
        assert False

    def getScaledZ(self, z_value):
        """
        This expects z_value to be in nanometers.
        """
        return z_value

    def getSize(self):
        """
        Return the X/Y size in pixels (all the fitters expect the
        PSF to be square).
        """
        assert False

    def getZMax(self):
        """
        Return maximum z position for the PSF in nanometers.
        """
        return self.zmax

    def getZMin(self):
        """
        Return the minimum z position for the PSF in nanometers.
        """
        return self.zmin

    def rescaleZ(self, z_value):
        """
        Convert from fitting units back to *microns* (not nanometers).
        """
        return z_value

#
# The MIT License
#
# Copyright (c) 2014 Zhuang Lab, Harvard University
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#


from collections import Counter

class InvalidScoresheetException(Exception):
    pass

class Scorer:
    EXPECTED_TOKEN_COUNTS = {
        'A': 4,
        'B': 4,
        'C': 1,
    }

    def __init__(self, teams_data, arena_data):
        self._teams_data = teams_data
        self._arena_data = arena_data

    def calculate_scores(self):
        scores = {}
        for tla, info in self._teams_data.items():
            zone = info['zone']
            tokens = self._arena_data[zone]['tokens']

            # 1 point per token
            points = len(tokens)

            counts = Counter(tokens)

            if 'A' in counts and 'B' in counts:
                # 1 further point per B token if there's an A token
                points += counts['B']

                # 2 further points per C token if there are both A and B tokens
                points += 2 * counts.get('C', 0)

            scores[tla] = points

        return scores

    def validate(self, extra):
        all_tokens = ''.join(
            d['tokens']
            for d in self._arena_data.values()
        ).replace(' ', '')

        counts = Counter(all_tokens)

        if counts != self.EXPECTED_TOKEN_COUNTS:
            msg = "Found invalid token counts {0!r} (expecting: {1!r})".format(
                dict(counts),
                self.EXPECTED_TOKEN_COUNTS,
            )
            raise InvalidScoresheetException(msg)

if __name__ == '__main__':
    import libproton
    libproton.main(Scorer)


import logging
import random
import numpy as np
import torch

def set_logger():
    logging.basicConfig(
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        level=logging.INFO
    )

def set_seed(seed):
    """for reproducibility

    :param seed:
    :return:
    """
    np.random.seed(seed)
    random.seed(seed)

    torch.manual_seed(seed)
    if torch.cuda.is_available():
        torch.cuda.manual_seed(seed)
        torch.cuda.manual_seed_all(seed)
    torch.backends.cudnn.enabled = False
    torch.backends.cudnn.benchmark = False
    torch.backends.cudnn.deterministic = True

def get_device(no_cuda=False, gpus='0'):
    return torch.device("cuda:" + gpus if torch.cuda.is_available() and not no_cuda else "cpu")

def detach_to_numpy(tensor):
    return tensor.detach().cpu().numpy()


# Lint as: python3
#
# Copyright 2020 The XLS Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for xls.dslx.interpreter.parse_and_interpret."""

import io

import unittest.mock as mock
from pyfakefs import fake_filesystem_unittest as ffu

from xls.dslx.interpreter import parse_and_interpret
from absl.testing import absltest

class ParseAndInterpretTest(absltest.TestCase):

  def test_assertion_failure_prints_positionally(self):
    program = """
    #![test]
    fn foo_test() {
      assert_eq(false, true)
    }
    """
    mock_stderr = io.StringIO()
    filename = 'test_filename.x'
    with ffu.Patcher() as patcher:
      patcher.fs.CreateFile(filename, contents=program)
      with mock.patch('sys.stderr', mock_stderr):
        parse_and_interpret.parse_and_test(
            program, 'test_program', filename=filename, raise_on_error=False)
    self.assertIn('* 0004:       assert_eq(false, true)',
                  mock_stderr.getvalue())
    self.assertIn(
        '        ~~~~~~~~~~~~~~~^-----------^ The program being interpreted failed!',
        mock_stderr.getvalue())

if __name__ == '__main__':
  absltest.main()


import unittest
from unittest.mock import Mock

from pyats.topology import Device
from pyats.topology import loader
from genie.metaparser.util.exceptions import SchemaEmptyParserError
from genie.libs.parser.junos.show_lacp import ShowLacpInterfacesInterface

""" TestCase for:
        * show lacp interfaces {interface}
"""
class TestShowLacpInterfacesInterface(unittest.TestCase):

    device = Device(name="aDevice")

    maxDiff = None

    empty_output = {"execute.return_value": ""}

    golden_output = {
        "execute.return_value": """
        show lacp interfaces ae4
        Aggregated interface: ae4
            LACP state:       Role   Exp   Def  Dist  Col  Syn  Aggr  Timeout  Activity
            xe-3/0/1       Actor    No    No   Yes  Yes  Yes   Yes     Fast    Active
            xe-3/0/1     Partner    No    No   Yes  Yes  Yes   Yes     Fast    Active
            LACP protocol:        Receive State  Transmit State          Mux State
            xe-3/0/1                  Current   Fast periodic Collecting distributing
    """
    }

    golden_parsed_output = {
        "lacp-interface-information-list": {
            "lacp-interface-information": {
                "lag-lacp-header": {"aggregate-name": "ae4"},
                "lag-lacp-protocol": [
                    {
                        "lacp-mux-state": "Collecting distributing",
                        "lacp-receive-state": "Current",
                        "lacp-transmit-state": "Fast periodic",
                        "name": "xe-3/0/1",
                    }
                ],
                "lag-lacp-state": [
                    {
                        "lacp-activity": "Active",
                        "lacp-aggregation": "Yes",
                        "lacp-collecting": "Yes",
                        "lacp-defaulted": "No",
                        "lacp-distributing": "Yes",
                        "lacp-expired": "No",
                        "lacp-role": "Actor",
                        "lacp-synchronization": "Yes",
                        "lacp-timeout": "Fast",
                        "name": "xe-3/0/1",
                    },
                    {
                        "lacp-activity": "Active",
                        "lacp-aggregation": "Yes",
                        "lacp-collecting": "Yes",
                        "lacp-defaulted": "No",
                        "lacp-distributing": "Yes",
                        "lacp-expired": "No",
                        "lacp-role": "Partner",
                        "lacp-synchronization": "Yes",
                        "lacp-timeout": "Fast",
                        "name": "xe-3/0/1",
                    },
                ],
            }
        }
    }

    def test_empty(self):
        self.device = Mock(**self.empty_output)
        obj = ShowLacpInterfacesInterface(device=self.device)
        with self.assertRaises(SchemaEmptyParserError):
            obj.parse()

    def test_golden_instance(self):
        self.device = Mock(**self.golden_output)
        obj = ShowLacpInterfacesInterface(device=self.device)
        parsed_output = obj.parse(interface="ae4")
        self.assertEqual(parsed_output, self.golden_parsed_output)

if __name__ == '__main__':
    unittest.main()


from django import forms
from .models import Poll , Choice
from django.forms import formset_factory

class PollCreateForm(forms.ModelForm):

	class Meta:

		model = Poll
		fields = ['name' , 'question' , 'image' , 'vote_limit']

		labels = {

			'name': "Name",
			'question': "Enter your poll's main question",
			'image': "you can upload an image for your poll" ,
			'vote_limit': "How many votes the the voters can take place in your poll?"
		}

	def __init__(self , *args , **kwargs):

		super(PollCreateForm,self).__init__(*args , **kwargs)

		name = self.fields['name']
		question = self.fields['question']
		image = self.fields['image']
		vote_limit = self.fields['vote_limit']

		name.widget.attrs.update({'class':'name-field'})
		question.widget.attrs.update({'class':'question-field'})
		image.widget.attrs.update({'class':'image-field'})
		vote_limit.widget.attrs.update({'class':'vote-field'})

class ChoiceForm(forms.ModelForm):

	class Meta:

		model = Choice
		fields = ['field']

		labels = {

			'field':'Enter your choice'
		}

	def __init__(self , *args , **kwargs):

		super(ChoiceForm,self).__init__(*args , **kwargs)

		field = self.fields['field']

		field.widget.attrs.update({'class' : 'field'})

ChoiceFormset = formset_factory(ChoiceForm , extra=5)


# Image smoothing operations

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('logo.png')

# 5x5 averaging filter F (times 1/25)
'''
kernel = np.ones((5,5),np.float32)/25
dst = cv2.filter2D(img,-1,kernel)

plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(dst),plt.title('Averaging')
plt.xticks([]), plt.yticks([])
plt.show()
#'''

#img = cv2.imread('logo_noise.png')

# 4x4 averaging filter
#blur = cv2.blur(img,(5,5))

# Gaussian filter
#blur = cv2.GaussianBlur(img,(5,5),0)

# Median filter
#median = cv2.medianBlur(img, 5)

# Bilateral filtering (preserves edges)
blur = cv2.bilateralFilter(img,9,75,75)

plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur),plt.title('Blurred')
#plt.subplot(122),plt.imshow(median),plt.title('Median')
plt.xticks([]), plt.yticks([])
plt.show()
#'''


# -*- coding: utf-8 -*-
import os, sys

from fake_useragent import UserAgent
from requests_html import HTMLSession
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
import re

cred = credentials.Certificate('/./root/Classmate/ServiceAccount.json')
firebase_admin.initialize_app(cred)
db = firestore.client()

ua = UserAgent()
uarandom = {'User-Agent': ua.random}
schulhauslinks = ('https://display.edubs.ch/bfsa', 'https://display.edubs.ch/bfsb', 'https://display.edubs.ch/bfsc',
                  'https://display.edubs.ch/bfsd', 'https://display.edubs.ch/dr1', 'https://display.edubs.ch/fzg1',
                  'https://display.edubs.ch/fms1', 'https://display.edubs.ch/gm1', 'https://display.edubs.ch/gb1',
                  'https://display.edubs.ch/gkg1', 'https://display.edubs.ch/gl1', 'https://display.edubs.ch/ii1',
                  'https://display.edubs.ch/kh1', 'https://display.edubs.ch/bibliothek',
                  'https://display.edubs.ch/medialab1', 'https://display.edubs.ch/sb1', 'https://display.edubs.ch/dw1',
                  'https://display.edubs.ch/dli1', 'https://display.edubs.ch/hb1', 'https://display.edubs.ch/sleo',
                  'https://display.edubs.ch/sand1', 'https://display.edubs.ch/alb1', 'https://display.edubs.ch/tb',
                  'https://display.edubs.ch/vog1', 'https://display.edubs.ch/wr1', 'https://display.edubs.ch/joh1',
                  'https://display.edubs.ch/dli2', 'https://display.edubs.ch/ts1', 'https://display.edubs.ch/wg1',
                  'https://display.edubs.ch/zbag1', 'https://display.edubs.ch/zbal1')
schulhauslinksTest = (
    'https://display.edubs.ch/gm1',
)

for haupturl in schulhauslinks:  # TODO: Test entfernen

    a = "1"
    b = "2"
# ======

    # Hier wird die Schule ausgelesen.
    session = HTMLSession()
    r = session.get(haupturl, headers=uarandom)
    schulehtml = r.html.find('body > div > h1', first=True)
    schule = schulehtml.text

    # Fromatiere schule fuer Target
    schuleTarget2 = re.sub('r"|\s|"', '', schule)
    schuleTarget = re.sub('[äöü]', '', schuleTarget2)

 # ======
    anzahlausfaelle1 = r.html.text
    anzahlausfaelle1split = anzahlausfaelle1.split('\n')
    del (anzahlausfaelle1split)[0:4]

    try:
        ersterausfalltaghtml = r.html.find('body > div > h3', first=True)
        ersterausfalltag = ersterausfalltaghtml.text
        ersterausfalltag1 = a + ersterausfalltag
        keinausfalltag = False

    except:  # keine Stellvertretungen
        keinausfalltag = True
        ersterausfalltaghtml = r.html.find(
            'body > div > div > div > strong')[0]
        ersterausfalltag = ersterausfalltaghtml.text
        ersterausfalltag1 = a + ersterausfalltag

    try:
        zweiteausfalltaghtml = r.html.find('body > div > h3')[1]
        zweiteausfalltag = zweiteausfalltaghtml.text
        zweiteausfalltag1 = b + zweiteausfalltag
        zweiterausfall = True

    except:  # kein zweiter Tag
        zweiterausfall = False
        zweiteausfalltaghtml = r.html.find('body > div > h2')[1]
        zweiteausfalltag = zweiteausfalltaghtml.text
        zweiteausfalltag1 = b + zweiteausfalltag

 # ======
    # Gruppiert alle informationen in 3ergruppen = 1 ausfall ->
    # wenn zweiter ausfall true = zwei listen(zb. montag und dienstag) mit den jeweiligen ausfaellen
    alleAusfaelleUnsortiert = anzahlausfaelle1split
    if zweiterausfall:
        # splittet alle ausfaelle in 2 listen bei zweitem tag
        splitIndex = alleAusfaelleUnsortiert.index(zweiteausfalltag)
        ersterTagListe, zweiterTagListeDirty = alleAusfaelleUnsortiert[
            :splitIndex], alleAusfaelleUnsortiert[splitIndex+1:]

        # splittet zweiten tag bei anlaesse
        anlaesseSplit = zweiterTagListeDirty.index('Anlässe')
        zweiterTagListe = zweiterTagListeDirty[:anlaesseSplit]

        # in 3er gruppen sortieren
        N = 3
        alleAusfaelleListe1Tag = [ersterTagListe[n:n+N]
                                 for n in range(0, len(ersterTagListe), N)]

        alleAusfaelleListe2Tag = [zweiterTagListe[n:n+N]
                                 for n in range(0, len(zweiterTagListe), N)]
    else:
        N = 3
        alleAusfaelleListe1Tag = [alleAusfaelleUnsortiert[n:n+N]
                                 for n in range(0, len(alleAusfaelleUnsortiert), N)]
# ======
    # Zaehlt ausfaelle des 1. Tags
    anzahlerstertag = 0
    for position in anzahlausfaelle1split:
        if position == zweiteausfalltag:
            break
        else:
            anzahlerstertag = anzahlerstertag + 1

    anzahlerstertagganz = anzahlerstertag + 5

    anzahlx = anzahlerstertag / 3

    if anzahlx < 1:
        anzahl1 = 0
    else:
        anzahl1 = anzahlx
# ======
    # Zaehlt ausfaelle des 2. Tags
    if zweiterausfall:
        anzahlzweitertag = 0
        anzahlT2 = len(zweiterTagListe) / 3
    else:
        anzahlT2 = 0
# ======
    # =========================================
    # ERSTER TAG
    # =========================================
    x = 0

    # Liest klasse aus HTML
    while x < anzahl1:
        try:
            # ----- INFOS -----# (benoetigt wird: Ausfall(alle Infos), Betroffene klassen, Tag des Ausfalls)

            # SCHULHAUS das bearbeitet wird
            # print(schule)

            # AUSFALL der bearbeitet wird (alle infos)

            auktellerAufall = alleAusfaelleListe1Tag[x]

            # TAG des Ausfalls
            # print(ersterausfalltag1)
            # print(zweiteausfalltag1)

            # klasse in html suchen
            klasse = r.html.find('body > div > div > div > strong')[x]
            klassetext = klasse.text

            # splittet den klassentext in einen array ( splittet bei komma und lehrzeichen )
            klassetextsplit = re.split(',| ', klassetext)

            klassentextlen = len(klassetextsplit)

            anz = 0  # setzt while loop unten zurueck
 # ======    # Liest verschindene Klassen aus und unterteilt sie in eine Liste
            while anz < klassentextlen:
                try:
                    klass = klassetextsplit[anz]
                    klasseSauber = klass.replace(':', '')

                    klasslen = len(klasseSauber)
                    klassenstufe = klass[0]

                    if klassenstufe.isdigit():

                        zeichen = 1  # setzt while loop unten zurueck
# ======                 # Liest zusammengesetzte Klassen aus. (Bsp. 1ac, 2BD, 3abc)
                        while zeichen <= klasslen:

                            try:
                                # TODO: check if 2. oder 3. stelle ein Buchstabe und nicht eine Zahl ist
                                # 2. oder 3. stelle nicht weiter!s
                                if klasseSauber[zeichen].isalpha():
                                    klassExtracted = klassenstufe + \
                                        klasseSauber[zeichen]
                                    # TODO: final goal is here bring here the ausfaelle!

                                    zeichen = zeichen + 1
                                    klassFinal = klassExtracted.upper()

                                    if klassetext == "Keine Anlässe":
                                        break
                                    if klassetext == "Keine Stellvertretungen":
                                        break
                                    else:
                                        if klassetext == "Keine Neuigkeiten":
                                            break
                                        else:
                                            num1 = x - 1 + zeichen
                                            num = str(num1)
                                            individualDoc = auktellerAufall[0] + \
                                                ' - '+num

                                            # fuegt 'am' hinzu bei allen wochentagen
                                            if ersterausfalltag == 'Heute:':
                                                tag1 = 'Ausfall '+ersterausfalltag
                                            else:
                                                tag1 = 'Ausfall am '+ersterausfalltag
                                            try:
                                                db.collection(u'Nachrichten').document(u'Schulen').collection(
                                                    schuleTarget2).document(individualDoc).set({

                                                        u'tag': tag1,
                                                        u'target': schuleTarget+'-'+klassFinal,
                                                        u'klasse': auktellerAufall[0],
                                                        u'grund': auktellerAufall[1],
                                                        u'raum': auktellerAufall[2],

                                                    })
                                            except:
                                                e = sys.exc_info()[0]

                                else:
                                    break

                            except:
                                break
                        anz = anz + 1
                    else:

                        anz = anz + 1

                except:

                    break
            x = x + 1
        except:
            break
# ======
    # =========================================
    # ZWEITER TAG
    # =========================================
    y = 0

    # Liest klasse aus HTML

    while y < anzahlT2:
        try:
            # ----- INFOS -----# (benoetigt wird: Ausfall(alle Infos), Betroffene klassen, Tag des Ausfalls)

            # SCHULHAUS das bearbeitet wird
            # print(schule)

            # AUSFALL der bearbeitet wird (alle infos)

            auktellerAufall = alleAusfaelleListe2Tag[y]

            # TAG des Ausfalls
            # print(ersterausfalltag1)
            # print(zweiteausfalltag1)

            # klasse in html suchen
            klasse = r.html.find('body > div > div > div > strong')[x+y]
            klassetext = klasse.text

            # splittet den klassentext in einen array ( splittet bei komma und lehrzeichen )
            klassetextsplit = re.split(',| ', klassetext)

            klassentextlen = len(klassetextsplit)

            anz = 0  # setzt while loop unten zurueck
# ======     # Liest verschindene Klassen aus und unterteilt sie in eine Liste
            while anz < klassentextlen:
                try:
                    klass = klassetextsplit[anz]
                    klasseSauber = klass.replace(':', '')

                    klasslen = len(klasseSauber)
                    klassenstufe = klass[0]

                    if klassenstufe.isdigit():

                        zeichen = 1  # setzt while loop unten zurueck
# ======                 # Liest zusammengesetzte Klassen aus. (Bsp. 1ac, 2BD, 3abc)
                        while zeichen <= klasslen:

                            try:

                                if klasseSauber[zeichen].isalpha():
                                    klassExtracted = klassenstufe + \
                                        klasseSauber[zeichen]

                                    zeichen = zeichen + 1
                                    klassFinal = klassExtracted.upper()

                                    if klassetext == "Keine Anlässe":
                                        break
                                    if klassetext == "Keine Stellvertretungen":
                                        break
                                    else:
                                        if klassetext == "Keine Neuigkeiten":
                                            break
                                        else:
                                            num1 = x + y - 1 + zeichen
                                            num = str(num1)
                                            individualDoc = auktellerAufall[0] + \
                                                ' - '+num
                                            # TODO:

                                            # fuegt 'am' hinzu bei allen wochentagen
                                            if zweiteausfalltag == 'Morgen:':
                                                tag2 = 'Ausfall '+zweiteausfalltag
                                            else:
                                                tag2 = 'Ausfall am '+zweiteausfalltag
                                            try:
                                                db.collection(u'Nachrichten').document(u'Schulen').collection(
                                                    schuleTarget2).document(individualDoc).set({
                                                        u'tag': tag2,
                                                        u'target': schuleTarget+'-'+klassFinal,
                                                        u'klasse': auktellerAufall[0],
                                                        u'grund': auktellerAufall[1],
                                                        u'raum': auktellerAufall[2],

                                                    })

                                            except:
                                                e = sys.exc_info()[0]

                                else:
                                    break
                            except:
                                break
                        anz = anz + 1
                    else:

                        anz = anz + 1

                except:

                    break
            y = y + 1
        except:
            break


#!/usr/bin/env python
import os
import string
import random
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
import glob

import numpy as np

def iterate_lines_over_file(filename):
    with open(filename) as file:
        print(filename)
        for line in file:
            line = line.strip()
            if len(line) < 2:
                continue
            yield line

def iterate_lines(root):
    filenames = [root]
    if os.path.isdir(root):
        filenames = glob.glob(os.path.join(root, '**/*'), recursive=True)

    for filename in filenames:
        for val in iterate_lines_over_file(filename):
            yield val

if __name__ == '__main__':
    parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
    parser.add_argument('dev_dir')
    parser.add_argument('out_dir')
    parser.add_argument('--num', default=-1, type=int)

    args = parser.parse_args()
    random.seed(0)

    count = sum(1 for _ in iterate_lines(args.dev_dir))
    allowed = None
    if args.num > 0 and args.num < count:
        allowed = set(np.random.choice(count, args.num, replace=False))

    with open(os.path.join(args.out_dir, 'input.txt'), 'w+') as input_file, \
            open(os.path.join(args.out_dir, 'answer.txt'), 'w+') as ans_file:
        for i, line in enumerate(iterate_lines(args.dev_dir)):
            if allowed is not None and i not in allowed:
                continue
            keep = random.randint(2, len(line))
            line = line[:keep]
            input_file.write(line[:-1] + '\n')
            ans_file.write(line[-1] + '\n')


import mock
import os
import shutil
import tempfile
import unittest

from ngi_pipeline.engines.sarek.database import CharonConnector
from ngi_pipeline.engines.sarek.exceptions import BestPracticeAnalysisNotRecognized, SampleNotValidForAnalysisError
from ngi_pipeline.engines.sarek.models.sample import SarekAnalysisSample
from ngi_pipeline.engines.sarek.models.sarek import SarekAnalysis, SarekGermlineAnalysis
from ngi_pipeline.engines.sarek.parsers import ParserIntegrator
from ngi_pipeline.log.loggers import minimal_logger
from ngi_pipeline.tests.engines.sarek.test_launchers import TestLaunchers

@mock.patch("ngi_pipeline.engines.sarek.models.sarek.ReferenceGenome", autospec=True)
@mock.patch("ngi_pipeline.engines.sarek.database.CharonConnector", autospec=True)
class TestSarekAnalysis(unittest.TestCase):

    CONFIG = {}

    def setUp(self):
        self.log = minimal_logger(__name__, to_file=False, debug=True)
        self.config = TestSarekAnalysis.CONFIG
        self.analysis_obj = TestLaunchers.get_NGIAnalysis(log=self.log)

    def test_get_analysis_instance_for_project_germline(self, charon_connector_mock, reference_genome_mock):
        reference_genome_mock.get_instance.return_value = "this-is-a-reference-genome"
        charon_connector = charon_connector_mock.return_value
        charon_connector.best_practice_analysis.return_value = "something_germline_something"
        expected_analysis_class = SarekGermlineAnalysis
        observed_analysis_instance = SarekAnalysis.get_analysis_instance_for_project(
            "this-is-a-project-id",
            self.config,
            self.log,
            charon_connector=charon_connector)
        self.assertIsInstance(observed_analysis_instance, expected_analysis_class)

    def test_get_analysis_instance_for_project_somatic(self, charon_connector_mock, reference_genome_mock):
        reference_genome_mock.get_instance.return_value = "this-is-a-reference-genome"
        charon_connector = charon_connector_mock.return_value
        charon_connector.best_practice_analysis.return_value = "something_somatic_something"
        with self.assertRaises(NotImplementedError):
            SarekAnalysis.get_analysis_instance_for_project(
                "this-is-a-project-id",
                self.config,
                self.log,
                charon_connector=charon_connector)

    def test_get_analysis_instance_for_project_unknown(self, charon_connector_mock, reference_genome_mock):
        reference_genome_mock.get_instance.return_value = "this-is-a-reference-genome"
        charon_connector = charon_connector_mock.return_value
        charon_connector.best_practice_analysis.return_value = "something_unknown_something"
        with self.assertRaises(BestPracticeAnalysisNotRecognized):
            SarekAnalysis.get_analysis_instance_for_project(
                "this-is-a-project-id",
                self.config,
                self.log,
                charon_connector=charon_connector)

    def test_status_should_be_started(self, charon_connector_mock, reference_genome_mock):

        def _analysis_status_wrapper(status, *args):
            return CharonConnector(
                self.config, self.log, charon_session="charon-session").analysis_status_from_process_status(status)

        def _alignment_status_wrapper(status, *args):
            return CharonConnector(
                self.config, self.log, charon_session="charon-session").alignment_status_from_analysis_status(status)

        charon_connector = charon_connector_mock.return_value
        charon_connector.analysis_status_from_process_status.side_effect = _analysis_status_wrapper
        charon_connector.alignment_status_from_analysis_status.side_effect = _alignment_status_wrapper
        sarek_analysis = SarekAnalysis(
            reference_genome_mock.return_value, self.config, self.log, charon_connector=charon_connector)

        for restart_mode in True, False:
            self.assertEqual(
                restart_mode,
                sarek_analysis.status_should_be_started(
                    "FAILED",
                    restart_failed_jobs=restart_mode))

        for restart_mode in True, False:
            self.assertEqual(
                restart_mode,
                sarek_analysis.status_should_be_started(
                    "ANALYZED",
                    restart_finished_jobs=restart_mode))

        for restart_mode in True, False:
            self.assertEqual(
                restart_mode,
                sarek_analysis.status_should_be_started(
                    "UNDER_ANALYSIS",
                    restart_running_jobs=restart_mode))

        self.assertTrue(
            sarek_analysis.status_should_be_started("TO_BE_ANALYZED"))

    def test_configure_analysis(self, charon_connector_mock, reference_genome_mock):
        config = {
            "profile": "this-is-a-profile",
            "tools": ["tool-A", "tool-B"]}

        sarek_analysis = SarekAnalysis(
            reference_genome_mock.return_value,
            {"sarek": config},
            self.log,
            charon_connector=charon_connector_mock.return_value)

        for key in config.keys():
            self.assertEqual(config[key], sarek_analysis.sarek_config[key])
        self.assertEqual(SarekAnalysis.DEFAULT_CONFIG["nf_path"], sarek_analysis.sarek_config["nf_path"])
        self.assertEqual(SarekAnalysis.DEFAULT_CONFIG["sarek_path"], sarek_analysis.sarek_config["sarek_path"])

        config = {
            "config": "this-is-a-site-specific-config-file",
            "profile": "this-is-another-profile",
            "nf_path": "this-is-the-path-to-nextflow",
            "sarek_path": "this-is-the-path-to-sarek"}
        sarek_config = sarek_analysis.configure_analysis(config={"sarek": config})
        for key in config.keys():
            self.assertEqual(config[key], sarek_config[key])
        self.assertEqual(SarekAnalysis.DEFAULT_CONFIG["tools"], sarek_config["tools"])

    def test_command_line(self, charon_connector_mock, reference_genome_mock):

        sarek_analysis = SarekAnalysis(
            reference_genome_mock.return_value,
            self.config,
            self.log,
            charon_connector=charon_connector_mock.return_value)

        with self.assertRaises(NotImplementedError):
            sarek_analysis.command_line(None)

    def test_generate_tsv_file_contents(self, charon_connector_mock, reference_genome_mock):

        sarek_analysis = SarekAnalysis(
            reference_genome_mock.return_value,
            self.config,
            self.log,
            charon_connector=charon_connector_mock.return_value)

        with self.assertRaises(NotImplementedError):
            sarek_analysis.generate_tsv_file_contents(None)

    def test_create_tsv_file(self, charon_connector_mock, reference_genome_mock):
        sarek_analysis = SarekAnalysis(
            reference_genome_mock.return_value,
            self.config,
            self.log,
            charon_connector=charon_connector_mock.return_value)
        sample_obj = self.analysis_obj.project.samples.values()[0]
        analysis_sample = SarekAnalysisSample(self.analysis_obj.project, sample_obj, sarek_analysis)
        with mock.patch.object(sarek_analysis, "generate_tsv_file_contents") as tsv_mock, \
                mock.patch.object(analysis_sample, "sample_analysis_tsv_file") as tsv_path_mock:
            tsv_mock.return_value = []
            with self.assertRaises(SampleNotValidForAnalysisError) as e:
                sarek_analysis.create_tsv_file(analysis_sample)
            tsv_mock.return_value = [["this", "is"], ["some", "content"]]
            tempdir = tempfile.mkdtemp(prefix="test_create_tsv_file_")
            tsv_path_mock.return_value = os.path.join(tempdir, "tsv_parent_folder", "tsv_file.tsv")
            sarek_analysis.create_tsv_file(analysis_sample)
            self.assertTrue(os.path.exists(tsv_path_mock.return_value))
            shutil.rmtree(tempdir)

@mock.patch("ngi_pipeline.engines.sarek.models.resources.ReferenceGenome", autospec=True)
@mock.patch("ngi_pipeline.engines.sarek.database.CharonConnector", autospec=True)
@mock.patch("ngi_pipeline.engines.sarek.database.TrackingConnector", autospec=True)
@mock.patch("ngi_pipeline.engines.sarek.process.ProcessConnector", autospec=True)
class TestSarekGermlineAnalysis(unittest.TestCase):

    CONFIG = {
        "profile": "this-is-a-profile",
        "tools": ["haplotypecaller", "manta"],
        "nf_path": os.path.join("/this", "is", "the", "nextflow", "path"),
        "sarek_path": os.path.join("/this", "is", "the", "path", "to", "sarek"),
        "genome": "this-is-the-genome"}

    def setUp(self):
        self.log = minimal_logger(__name__, to_file=False, debug=True)
        self.config = TestSarekGermlineAnalysis.CONFIG
        self.analysis_obj = TestLaunchers.get_NGIAnalysis(log=self.log)

    def get_instance(
            self, process_connector_mock, tracking_connector_mock, charon_connector_mock, reference_genome_mock):
        reference_genome = reference_genome_mock.return_value
        reference_genome.__str__.return_value = self.config["genome"]
        return SarekGermlineAnalysis(
            reference_genome,
            {"sarek": self.config},
            self.log,
            charon_connector=charon_connector_mock,
            tracking_connector=tracking_connector_mock,
            process_connector=process_connector_mock)

    def test_cleanup(self, *mocks):
        sarek_analysis = self.get_instance(*mocks)
        with mock.patch("ngi_pipeline.engines.sarek.models.sample.SarekAnalysisSample", autospec=True) as sample_mock:
            expected_work_dir = "path/to/work/dir"
            sample_mock.sample_analysis_work_dir.return_value = expected_work_dir
            sarek_analysis.cleanup(sample_mock)
            sarek_analysis.process_connector.cleanup.assert_called_once_with(expected_work_dir)

    def test_command_line(
            self, process_connector_mock, tracking_connector_mock, charon_connector_mock, reference_genome_mock):
        sarek_analysis = self.get_instance(
            process_connector_mock, tracking_connector_mock, charon_connector_mock, reference_genome_mock)
        sample_obj = self.analysis_obj.project.samples.values()[0]
        analysis_sample = SarekAnalysisSample(self.analysis_obj.project, sample_obj, sarek_analysis)
        self.config["outDir"] = analysis_sample.sample_analysis_path()
        self.config["sample"] = analysis_sample.sample_analysis_tsv_file()
        observed_cmd = sarek_analysis.command_line(analysis_sample)

        self.assertIn("-profile {}".format(self.config["profile"]), observed_cmd)
        self.assertIn("--tools {}".format(",".join(self.config["tools"])), observed_cmd)
        self.assertTrue(observed_cmd.startswith("{} run {}".format(self.config["nf_path"], self.config["sarek_path"])))
        for key in filter(lambda k: k not in ["profile", "nf_path", "sarek_path", "tools"], self.config.keys()):
            self.assertIn("--{} {}".format(key, self.config[key]), observed_cmd)

    def test_generate_tsv_file_contents(
            self, process_connector_mock, tracking_connector_mock, charon_connector_mock, reference_genome_mock):
        sarek_analysis = self.get_instance(
            process_connector_mock, tracking_connector_mock, charon_connector_mock, reference_genome_mock)
        sample_obj = self.analysis_obj.project.samples.values()[0]
        analysis_sample = SarekAnalysisSample(self.analysis_obj.project, sample_obj, sarek_analysis)
        sample_data_path = analysis_sample.sample_data_path()
        with mock.patch.object(
                sarek_analysis, "libprep_should_be_started") as libprep_mock, \
                mock.patch.object(
                    sarek_analysis, "seqrun_should_be_started") as seqrun_mock:
            for start_mode in True, False:
                libprep_mock.return_value = start_mode
                seqrun_mock.return_value = not start_mode
                self.assertListEqual(
                    [],
                    sarek_analysis.generate_tsv_file_contents(analysis_sample))
            libprep_mock.return_value = True
            seqrun_mock.return_value = True
            expected_tsv = []
            for libprepid in map(lambda lp: '{}-{}'.format(sample_obj.name, lp), ['libprep1', 'libprep2']):
                for sample_index in ['1', '2']:
                    tsv_row = [sample_obj.name, 'ZZ', 0, sample_obj.name, 'ABC00{0}CXY.1.S{0}'.format(sample_index)]
                    tsv_row.extend([
                        os.path.join(
                            sample_data_path,
                            libprepid,
                            '180411_ST-0123_001{0}_AABC00{0}CXY'.format(sample_index),
                            '{}_S{}_L001_R{}_001.fastq.gz'.format(
                                libprepid, sample_index, read_num)) for read_num in ['1', '2']])
                    expected_tsv.append(tsv_row)
            observed_tsv = sarek_analysis.generate_tsv_file_contents(analysis_sample)
            self.assertListEqual(sorted(expected_tsv), sorted(observed_tsv))

    def test_analyze_sample(
            self, process_connector_mock, tracking_connector_mock, charon_connector_mock, reference_genome_mock):
        sarek_analysis = self.get_instance(
            process_connector_mock, tracking_connector_mock, charon_connector_mock, reference_genome_mock)
        with mock.patch.object(
                sarek_analysis, "create_tsv_file", return_value=os.path.join("/path", "to", "tsv", "file")) as tsv_mock:
            for sample_obj in self.analysis_obj.project:
                sarek_analysis.analyze_sample(sample_obj, self.analysis_obj)

    def test_runid_and_fastq_files_from_tsv_file(self, *args):
        fh, fake_tsv_file = tempfile.mkstemp(prefix="test_fastq_files_from_tsv_")
        with mock.patch("ngi_pipeline.engines.sarek.models.sarek.csv.reader", autospec=True) as csv_mock:
            expected_fastq_files = []
            for row in range(3):
                expected_fastq_files.append(
                    ["id.for.row.{}".format(row)] + [
                        os.path.join("/path", "to", "fastq", "file_{}-R{}.fastq.gz".format(row, i)) for i in [1, 2]])
            for row in range(2):
                expected_fastq_files.append(
                    ["id.for.row.{}".format(row+3)] +
                    [os.path.join("/path", "to", "fastq", "file_{}-R1.fastq.gz".format(row))])
            mocked_tsv_data = (
                ["col1", "col2", "col3", "col4"] +
                runid_and_fastq_files for runid_and_fastq_files in expected_fastq_files)
            csv_mock.return_value = mocked_tsv_data
            observed_fastq_files = list(SarekGermlineAnalysis.runid_and_fastq_files_from_tsv_file(fake_tsv_file))
            self.assertListEqual(sorted(expected_fastq_files), sorted(observed_fastq_files))
        os.unlink(fake_tsv_file)

    def test_collect_analysis_metrics(
            self, process_connector_mock, tracking_connector_mock, charon_connector_mock, reference_genome_mock):
        sarek_analysis = self.get_instance(
            process_connector_mock, tracking_connector_mock, charon_connector_mock, reference_genome_mock)
        expected_metrics = {
            "percent_duplication": [25.3],
            "autosomal_coverage": [35.8],
            "total_reads": [123456789]
        }

        def _serve_metric(metric):
            return expected_metrics[metric[4:]]

        with mock.patch.object(
                sarek_analysis, "processing_steps") as processing_steps, \
                mock.patch(
                    "ngi_pipeline.engines.sarek.models.sarek.ParserIntegrator", autospec=ParserIntegrator) as \
                        parser_mock:
            processing_steps.return_value = []
            parser_instance = parser_mock.return_value
            query_mock = parser_instance.query_parsers
            query_mock.side_effect = _serve_metric
            observed_metrics = sarek_analysis.collect_analysis_metrics("this-is-a-sample-analysis")
            self.assertDictEqual({metric: value[0] for metric, value in expected_metrics.items()}, observed_metrics)


from ...Types.PrimitiveTypes.Node import Node
import logging
import xxhash

class Operation(Node):
    allowed_parent_label = ['Expression', 'Instruction']
    logger = logging.getLogger(__name__)

    def __init__(self, bn_object, self_uuid, parent_uuid, parent_node_label, parent_node_hash):
        self.bn_operation_object = bn_object

        if parent_node_label in self.allowed_parent_label:
            super().__init__(self.get_hash(), self_uuid, parent_uuid, parent_node_label, 'Operation',
                             parent_node_hash, {})
        else:
            self.logger.error(f'parent_node_label not allowed: {parent_node_label}')
        self.set_node_attributes()

    def get_hash(self):
        hash_digest = xxhash.xxh64()
        hash_digest.update(self.bn_operation_object.operation.name)
        return hash_digest.hexdigest()

    def set_node_attributes(self):
        node_attributes_dict = dict()
        node_attributes_dict.update({'Operation': self.bn_operation_object.operation})

        self.add_node_attributes(node_attributes_dict)

    def __str__(self):
        return super().__str__()


from ClaseVehiculo import Vehiculo
import datetime

class Usado(Vehiculo):
    __marca=""
    __patente=""
    __año=""
    __kilometraje=0

    def __init__(self, modelo, puertas, color, preciobase,marca,patente,año,kilometraje):
        super().__init__(modelo, puertas, color, preciobase)
        self.__marca=marca
        self.__patente=patente
        self.__año=año
        self.__kilometraje=kilometraje
    def getPatente(self):
        return self.__patente

    def getPuertas(self):
        return super().getPuertas()
    def getPrecioBase(self):
        return super().getPrecioBase()
    def getModelo(self):
        return super().getModelo()
    def getColor(self):
        return super().getColor()

    def toJson(self):
        d=dict(
            __class__=self.__class__.__name__,
            __atributos__=dict(
                modelo=self.getModelo(),
                puertas=self.getPuertas(),
                color=self.getColor(),
                preciobase=self.getPrecioBase(),
                marca=self.__marca,
                patente=self.__patente,
                año=self.__año,
                kilometraje=self.__kilometraje
            )
        )
        return d

    def CalcPrecioVenta(self):
        km=0
        antig=int(datetime.date.today().year) - int(self.__año)
        porc=float((super().getPrecioBase() * 1)/100)
        if(int(self.__kilometraje)>100000):
            km=float((super().getPrecioBase() * 2)/100)
        total=float(super().getPrecioBase())-porc-antig-km
        return total
    def __str__(self):
        super().__str__()
        print('Marca: {}'.format(self.__marca))
        print('Patente: {}'.format(self.__patente))
        print('Año: {}'.format(self.__año))
        print('Kilometros: {}'.format(self.__kilometraje))
        return ""


# cmt
from cmt.rig.meshretarget import *
import cmt.shortcuts as shortcuts

# maya
import pymel.core as pm
import maya.api.OpenMaya as OpenMaya
import maya.cmds as cmds

# numpy
import numpy as np

# scipy
from scipy.spatial.distance import cdist

#
import math
import time

guides = ("body_C0_root",
"shoulder_L0_root",
"shoulder_R0_root",
"shoulder_L0_tip",
"shoulder_R0_tip",
"arm_L0_elbow",
"arm_R0_elbow",
"arm_L0_wrist",
"arm_R0_wrist",
"arm_L0_eff",
"arm_R0_eff",
"meta_L0_root",
"meta_R0_root",
"meta_L0_0_loc",
"meta_R0_0_loc",
"meta_L0_1_loc",
"meta_R0_1_loc",
"meta_L0_2_loc",
"meta_R0_2_loc",
"thumbRoll_L0_root",
"thumbRoll_R0_root",
"thumb_L0_0_loc",
"thumb_R0_0_loc",
"thumb_L0_1_loc",
"thumb_R0_1_loc",
"thumb_L0_2_loc",
"thumb_R0_2_loc",
"finger_L0_root",
"finger_R0_root",
"finger_L0_0_loc",
"finger_R0_0_loc",
"finger_L0_1_loc",
"finger_R0_1_loc",
"finger_L0_2_loc",
"finger_R0_2_loc",
"finger_L1_root",
"finger_R1_root",
"finger_L1_0_loc",
"finger_R1_0_loc",
"finger_L1_1_loc",
"finger_R1_1_loc",
"finger_L1_2_loc",
"finger_R1_2_loc",
"finger_L2_root",
"finger_R2_root",
"finger_L2_0_loc",
"finger_L2_0_loc",
"finger_L2_1_loc",
"finger_L2_1_loc",
"finger_L2_2_loc",
"finger_L2_2_loc",
"finger_L3_root",
"finger_L3_0_loc",
"finger_L3_0_loc",
"finger_L3_1_loc",
"finger_L3_1_loc",
"finger_L3_2_loc",
"finger_L3_2_loc",
"leg_L0_root",
"leg_R0_root",
"leg_L0_knee",
"leg_R0_knee",
"leg_L0_ankle",
"leg_R0_ankle",
"foot_L0_heel",
"foot_R0_heel",
"foot_L0_inpivot",
"foot_R0_inpivot",
"foot_L0_outpivot",
"foot_R0_outpivot",
"foot_L0_0_loc",
"foot_R0_0_loc",
"leg_L0_eff",
"leg_R0_eff",
"foot_L0_1_loc",
"foot_R0_1_loc",)

def retarget(source, target, rbf=None, radius=0.5, stride=1):
    """Run the mesh retarget.
    :param source: Source mesh
    :param target: Modified source mesh
    :param shapes: List of meshes to retarget
    :param rbf: One of the RBF functions. See class RBF
    :param radius: Smoothing parameter for the rbf
    :param stride: Vertex stride to sample on the source mesh.  Increase to speed up
    the calculation but less accurate.
    """
    start_time = time.time()
    source_points = points_to_np_array(source, stride)
    target_points = points_to_np_array(target, stride)

    if rbf is None:
        rbf = RBF.linear
    weights = get_weight_matrix(source_points, target_points, rbf, radius)

    points = get_guide_points()
    n_points = points.shape[0]
    dist = get_distance_matrix(points, source_points, rbf, radius)
    identity = np.ones((n_points, 1))
    h = np.bmat([[dist, identity, points]])
    deformed = np.asarray(np.dot(h, weights))
    points = [OpenMaya.MPoint(*p) for p in deformed]
    set_guide_points(points)

    end_time = time.time()
    print("Transferred in {} seconds".format(end_time - start_time))

def get_guide_points(stride=1):
    points = [ pm.xform(guide, query=True, translation=True, worldSpace=True) for guide in guides]
    sparse_points = [OpenMaya.MPoint(p) for p in points][::stride]
    np_points = np.array([[p.x, p.y, p.z] for p in sparse_points])
    return np_points

def set_guide_points(points):
    for index, point in enumerate(points):
        pm.xform(guides[index], translation=point, worldSpace=True)

retarget(pm.ls(sl=1)[0], pm.ls(sl=1)[1])


from nose.tools import assert_true
import os
import mock
import jsonbender
from validate.miflowcyt_validate import FlowRepoClient

map_file = os.path.join(os.path.dirname(__file__),
                        "../tests/data/MiFlowCyt/experiment_mapping.json")
base_schema = "experiment_schema.json"
range_limit = 1

class TestFlowRepoClient(object):

    @classmethod
    def setup_class(cls):
        cls.client = FlowRepoClient(map_file, base_schema, "this is a fake ID")
        cls.mock_request_patcher = mock.patch('validate.miflowcyt_validate.requests.request')
        cls.mock_request = cls.mock_request_patcher.start()

        cls.mock_xmljson_patcher = mock.patch('validate.miflowcyt_validate.xmljson.parker.data')
        cls.mock_xmljson = cls.mock_xmljson_patcher.start()

        cls.mock_etree_patcher = mock.patch('validate.miflowcyt_validate.elemTree.fromstring')
        cls.mock_etree = cls.mock_etree_patcher.start()

    @classmethod
    def teardown_class(cls):
        cls.mock_request_patcher.stop()
        cls.mock_xmljson_patcher.stop()
        cls.mock_etree_patcher.stop()

    def test_get_mapping(self):
        mapping = self.client.get_mapping(map_file)
        assert_true(isinstance(mapping['date'], jsonbender.selectors.OptionalS))
        assert_true(isinstance(mapping['keywords'], jsonbender.selectors.OptionalS))
        assert_true(isinstance(mapping['other'], jsonbender.selectors.OptionalS))
        assert_true(isinstance(mapping['primaryContact'], jsonbender.selectors.S))
        assert_true(isinstance(mapping['organization'], jsonbender.selectors.F))
        assert_true(isinstance(mapping['purpose'], jsonbender.selectors.OptionalS))
        assert_true(isinstance(mapping['qualityControlMeasures'], jsonbender.selectors.OptionalS))
        assert_true(isinstance(mapping['conclusions'], jsonbender.selectors.K))
        assert_true(isinstance(mapping['experimentVariables'], jsonbender.selectors.OptionalS))

        map_file_error = os.path.join(os.path.dirname(__file__),
                                      "../tests/data/MiFlowCyt/_mapping.json")
        error = self.client.get_mapping(map_file_error)
        assert_true(isinstance(error, Exception))

    def test_grab_user_content(self):
        self.mock_request.return_value.status_code = 200
        response = self.client.grab_user_content(self.client.clientID)
        assert_true(response.status_code == 200)

    def test_get_user_content_id(self):
        self.mock_request.return_value.status_code = 200
        self.mock_xmljson.return_value = {
            "public-experiments": {
                "experiment": [
                    {"id": "123"},
                    {"id": "456"}
                ]
            }
        }
        ids = self.client.get_user_content_id(self.client.clientID)
        assert_true('123' in ids)
        assert_true('456' in ids)

    def test_grab_experiment_from_api(self):
        self.mock_request.return_value.status_code = 200
        item_metadata = self.client.grab_experiment_from_api(self.client.clientID, "123")
        assert_true(item_metadata.status_code == 200)

        self.mock_request.return_value.status_code = 404
        item_metadata = self.client.grab_experiment_from_api(self.client.clientID, "123")
        assert_true(item_metadata.status_code == 404)

    def test_validate_instance_from_file(self):
        validation = self.client.validate_instance_from_file({"test": "test"}, "test",
                                                             "test.test")
        assert_true(isinstance(validation, Exception))

    def test_make_validation(self):
        self.mock_request.return_value.status_code = 401
        validation = self.client.make_validation(1)
        assert_true(isinstance(validation, Exception))