#!/usr/bin/env python
#
# Copyright 2009,2012 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#

from gnuradio import gr
from gnuradio import filter
import sys, time

try:
    import scipy
    from scipy import fftpack
except ImportError:
    print "Error: Program requires scipy (see: www.scipy.org)."
    sys.exit(1)

try:
    import pylab
    from pylab import mlab
except ImportError:
    print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)."
    sys.exit(1)

class pfb_top_block(gr.top_block):
    def __init__(self):
        gr.top_block.__init__(self)

        self._N = 100000        # number of samples to use
        self._fs = 2000         # initial sampling rate
        self._interp = 5        # Interpolation rate for PFB interpolator
        self._ainterp = 5.5       # Resampling rate for the PFB arbitrary resampler

        # Frequencies of the signals we construct
        freq1 = 100
        freq2 = 200

        # Create a set of taps for the PFB interpolator
        # This is based on the post-interpolation sample rate
        self._taps = filter.firdes.low_pass_2(self._interp,
                                              self._interp*self._fs,
                                              freq2+50, 50,
                                              attenuation_dB=120,
                                              window=filter.firdes.WIN_BLACKMAN_hARRIS)

        # Create a set of taps for the PFB arbitrary resampler
        # The filter size is the number of filters in the filterbank; 32 will give very low side-lobes,
        # and larger numbers will reduce these even farther
        # The taps in this filter are based on a sampling rate of the filter size since it acts
        # internally as an interpolator.
        flt_size = 32
        self._taps2 = filter.firdes.low_pass_2(flt_size,
                                               flt_size*self._fs,
                                               freq2+50, 150,
                                               attenuation_dB=120,
                                               window=filter.firdes.WIN_BLACKMAN_hARRIS)

        # Calculate the number of taps per channel for our own information
        tpc = scipy.ceil(float(len(self._taps)) /  float(self._interp))
        print "Number of taps:     ", len(self._taps)
        print "Number of filters:  ", self._interp
        print "Taps per channel:   ", tpc

        # Create a couple of signals at different frequencies
        self.signal1 = gr.sig_source_c(self._fs, gr.GR_SIN_WAVE, freq1, 0.5)
        self.signal2 = gr.sig_source_c(self._fs, gr.GR_SIN_WAVE, freq2, 0.5)
        self.signal = gr.add_cc()

        self.head = gr.head(gr.sizeof_gr_complex, self._N)

        # Construct the PFB interpolator filter
        self.pfb = filter.pfb.interpolator_ccf(self._interp, self._taps)

        # Construct the PFB arbitrary resampler filter
        self.pfb_ar = filter.pfb.arb_resampler_ccf(self._ainterp, self._taps2, flt_size)
        self.snk_i = gr.vector_sink_c()

        #self.pfb_ar.pfb.print_taps()
        #self.pfb.pfb.print_taps()

        # Connect the blocks
        self.connect(self.signal1, self.head, (self.signal,0))
        self.connect(self.signal2, (self.signal,1))
        self.connect(self.signal, self.pfb)
        self.connect(self.signal, self.pfb_ar)
        self.connect(self.signal, self.snk_i)

        # Create the sink for the interpolated signals
        self.snk1 = gr.vector_sink_c()
        self.snk2 = gr.vector_sink_c()
        self.connect(self.pfb, self.snk1)
        self.connect(self.pfb_ar, self.snk2)

def main():
    tb = pfb_top_block()

    tstart = time.time()
    tb.run()
    tend = time.time()
    print "Run time: %f" % (tend - tstart)

    if 1:
        fig1 = pylab.figure(1, figsize=(12,10), facecolor="w")
        fig2 = pylab.figure(2, figsize=(12,10), facecolor="w")
        fig3 = pylab.figure(3, figsize=(12,10), facecolor="w")

        Ns = 10000
        Ne = 10000

        fftlen = 8192
        winfunc = scipy.blackman

        # Plot input signal
        fs = tb._fs

        d = tb.snk_i.data()[Ns:Ns+Ne]
        sp1_f = fig1.add_subplot(2, 1, 1)

        X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
                          window = lambda d: d*winfunc(fftlen),
                          scale_by_freq=True)
        X_in = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
        f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
        p1_f = sp1_f.plot(f_in, X_in, "b")
        sp1_f.set_xlim([min(f_in), max(f_in)+1])
        sp1_f.set_ylim([-200.0, 50.0])

        sp1_f.set_title("Input Signal", weight="bold")
        sp1_f.set_xlabel("Frequency (Hz)")
        sp1_f.set_ylabel("Power (dBW)")

        Ts = 1.0/fs
        Tmax = len(d)*Ts

        t_in = scipy.arange(0, Tmax, Ts)
        x_in = scipy.array(d)
        sp1_t = fig1.add_subplot(2, 1, 2)
        p1_t = sp1_t.plot(t_in, x_in.real, "b-o")
        #p1_t = sp1_t.plot(t_in, x_in.imag, "r-o")
        sp1_t.set_ylim([-2.5, 2.5])

        sp1_t.set_title("Input Signal", weight="bold")
        sp1_t.set_xlabel("Time (s)")
        sp1_t.set_ylabel("Amplitude")

        # Plot output of PFB interpolator
        fs_int = tb._fs*tb._interp

        sp2_f = fig2.add_subplot(2, 1, 1)
        d = tb.snk1.data()[Ns:Ns+(tb._interp*Ne)]
        X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
                          window = lambda d: d*winfunc(fftlen),
                          scale_by_freq=True)
        X_o = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
        f_o = scipy.arange(-fs_int/2.0, fs_int/2.0, fs_int/float(X_o.size))
        p2_f = sp2_f.plot(f_o, X_o, "b")
        sp2_f.set_xlim([min(f_o), max(f_o)+1])
        sp2_f.set_ylim([-200.0, 50.0])

        sp2_f.set_title("Output Signal from PFB Interpolator", weight="bold")
        sp2_f.set_xlabel("Frequency (Hz)")
        sp2_f.set_ylabel("Power (dBW)")

        Ts_int = 1.0/fs_int
        Tmax = len(d)*Ts_int

        t_o = scipy.arange(0, Tmax, Ts_int)
        x_o1 = scipy.array(d)
        sp2_t = fig2.add_subplot(2, 1, 2)
        p2_t = sp2_t.plot(t_o, x_o1.real, "b-o")
        #p2_t = sp2_t.plot(t_o, x_o.imag, "r-o")
        sp2_t.set_ylim([-2.5, 2.5])

        sp2_t.set_title("Output Signal from PFB Interpolator", weight="bold")
        sp2_t.set_xlabel("Time (s)")
        sp2_t.set_ylabel("Amplitude")

        # Plot output of PFB arbitrary resampler
        fs_aint = tb._fs * tb._ainterp

        sp3_f = fig3.add_subplot(2, 1, 1)
        d = tb.snk2.data()[Ns:Ns+(tb._interp*Ne)]
        X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
                          window = lambda d: d*winfunc(fftlen),
                          scale_by_freq=True)
        X_o = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
        f_o = scipy.arange(-fs_aint/2.0, fs_aint/2.0, fs_aint/float(X_o.size))
        p3_f = sp3_f.plot(f_o, X_o, "b")
        sp3_f.set_xlim([min(f_o), max(f_o)+1])
        sp3_f.set_ylim([-200.0, 50.0])

        sp3_f.set_title("Output Signal from PFB Arbitrary Resampler", weight="bold")
        sp3_f.set_xlabel("Frequency (Hz)")
        sp3_f.set_ylabel("Power (dBW)")

        Ts_aint = 1.0/fs_aint
        Tmax = len(d)*Ts_aint

        t_o = scipy.arange(0, Tmax, Ts_aint)
        x_o2 = scipy.array(d)
        sp3_f = fig3.add_subplot(2, 1, 2)
        p3_f = sp3_f.plot(t_o, x_o2.real, "b-o")
        p3_f = sp3_f.plot(t_o, x_o1.real, "m-o")
        #p3_f = sp3_f.plot(t_o, x_o2.imag, "r-o")
        sp3_f.set_ylim([-2.5, 2.5])

        sp3_f.set_title("Output Signal from PFB Arbitrary Resampler", weight="bold")
        sp3_f.set_xlabel("Time (s)")
        sp3_f.set_ylabel("Amplitude")

        pylab.show()

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        pass


##############################################################################
# Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
# This file is part of Spack.
# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
# LLNL-CODE-647188
#
# For details, see https://github.com/llnl/spack
# Please also see the NOTICE and LICENSE files for our notice and the LGPL.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License (as
# published by the Free Software Foundation) version 2.1, February 1999.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
# conditions of the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
from spack import *

class PyIminuit(PythonPackage):
    """Interactive IPython-Friendly Minimizer based on SEAL Minuit2."""

    homepage = "https://pypi.python.org/pypi/iminuit"
    url      = "https://pypi.io/packages/source/i/iminuit/iminuit-1.2.tar.gz"

    version('1.2', '4701ec472cae42015e26251703e6e984')

    # Required dependencies
    depends_on('py-setuptools', type='build')

    # Optional dependencies
    depends_on('py-numpy', type=('build', 'run'))
    depends_on('py-matplotlib', type=('build', 'run'))
    depends_on('py-cython', type='build')


import numpy as np
import pandas as pd
from sklearn.base import TransformerMixin

class MonthlySubquotaLimitClassifier(TransformerMixin):
    """
    Monthly Subquota Limit classifier.

    Dataset
    -------
    issue_date : datetime column
        Date when the expense was made.

    month : int column
        The quota month matching the expense request.

    net_value : float column
        The value of the expense.

    subquota_number : category column
        A number to classify a category of expenses.

    year : int column
        The quota year matching the expense request.
    """

    KEYS = ['applicant_id', 'month', 'year']
    COLS = ['applicant_id',
            'issue_date',
            'month',
            'net_value',
            'subquota_number',
            'year']

    def fit(self, X):
        self.X = X
        self._X = self.X[self.COLS].copy()
        self.__create_columns()
        return self

    def transform(self, X=None):
        self.limits = [
            {
                # Automotive vehicle renting or charter (From 12/2013 to 03/2015)
                'data': self._X.query('(subquota_number == "120") & '
                                      '(reimbursement_month >= datetime(2013, 12, 1)) & '
                                      '(reimbursement_month <= datetime(2015, 3, 1))'),
                'monthly_limit': 1000000,
            },
            {
                # Automotive vehicle renting or charter (From 04/2015 to 04/2017)
                'data': self._X.query('(subquota_number == "120") & '
                                      '(reimbursement_month >= datetime(2015, 4, 1)) & '
                                      '(reimbursement_month <= datetime(2017, 4, 1))'),
                'monthly_limit': 1090000,
            },
            {
                # Automotive vehicle renting or charter (From 05/2017)
                'data': self._X.query('(subquota_number == "120") & '
                                      '(reimbursement_month >= datetime(2017, 5, 1))'),
                'monthly_limit': 1271300,
            },
            {
                # Taxi, toll and parking (From 12/2013 to 03/2015)
                'data': self._X.query('(subquota_number == "122") & '
                                      '(reimbursement_month >= datetime(2013, 12, 1)) & '
                                      '(reimbursement_month <= datetime(2015, 3, 1))'),
                'monthly_limit': 250000,
            },
            {
                # Taxi, toll and parking (From 04/2015)
                'data': self._X.query('(subquota_number == "122") & '
                                      '(reimbursement_month >= datetime(2015, 4, 1))'),
                'monthly_limit': 270000,
            },
            {
                # Fuels and lubricants (From 07/2009 to 03/2015)
                'data': self._X.query('(subquota_number == "3") & '
                                      '(reimbursement_month >= datetime(2009, 7, 1)) & '
                                      '(reimbursement_month <= datetime(2015, 3, 1))'),
                'monthly_limit': 450000,
            },
            {
                # Fuels and lubricants (From 04/2015 to 08/2015)
                'data': self._X.query('(subquota_number == "3") & '
                                      '(reimbursement_month >= datetime(2015, 4, 1)) & '
                                      '(reimbursement_month <= datetime(2015, 8, 1))'),
                'monthly_limit': 490000,
            },
            {
                # Fuels and lubricants (From 9/2015)
                'data': self._X.query('(subquota_number == "3") & '
                                      '(reimbursement_month >= datetime(2015, 9, 1))'),
                'monthly_limit': 600000,
            },
            {
                # Security service provided by specialized company (From 07/2009 to 4/2014)
                'data': self._X.query('(subquota_number == "8") & '
                                      '(reimbursement_month >= datetime(2009, 7, 1)) & '
                                      '(reimbursement_month <= datetime(2014, 4, 1))'),
                'monthly_limit': 450000,
            },
            {
                # Security service provided by specialized company (From 05/2014 to 3/2015)
                'data': self._X.query('(subquota_number == "8") & '
                                      '(reimbursement_month >= datetime(2014, 5, 1)) & '
                                      '(reimbursement_month <= datetime(2015, 3, 1))'),
                'monthly_limit': 800000,
            },
            {
                # Security service provided by specialized company (From 04/2015)
                'data': self._X.query('(subquota_number == "8") & '
                                      '(reimbursement_month >= datetime(2015, 4, 1))'),
                'monthly_limit': 870000,
            },
            {
                # Participation in course, talk or similar event (From 10/2015)
                'data': self._X.query('(subquota_number == "137") & '
                                      '(reimbursement_month >= datetime(2015, 10, 1))'),
                'monthly_limit': 769716,
            },
        ]
        return self

    def predict(self, X=None):
        self._X['is_over_monthly_subquota_limit'] = False
        for metadata in self.limits:
            data, monthly_limit = metadata['data'], metadata['monthly_limit']
            if len(data):
                surplus_reimbursements = self.__find_surplus_reimbursements(data, monthly_limit)
                self._X.loc[surplus_reimbursements.index,
                            'is_over_monthly_subquota_limit'] = True
        results = self._X.loc[self.X.index, 'is_over_monthly_subquota_limit']
        return np.r_[results]

    def predict_proba(self, X=None):
        return 1.

    def __create_columns(self):
        self._X['net_value_int'] = (self._X['net_value'] * 100).apply(int)

        self._X['coerced_issue_date'] = \
            pd.to_datetime(self._X['issue_date'], errors='coerce')
        self._X.sort_values('coerced_issue_date', kind='mergesort', inplace=True)

        reimbursement_month = self._X[['year', 'month']].copy()
        reimbursement_month['day'] = 1
        self._X['reimbursement_month'] = pd.to_datetime(reimbursement_month)

    def __find_surplus_reimbursements(self, data, monthly_limit):
        grouped = data.groupby(self.KEYS).apply(self.__create_cumsum_cols)
        return grouped[grouped['cumsum_net_value'] > monthly_limit]

    def __create_cumsum_cols(self, subset):
        subset['cumsum_net_value'] = subset['net_value_int'].cumsum()
        return subset


# -*- coding: UTF-8 -*-

import numpy as np
import matplotlib.pyplot as plt #for figures
#from mpl_toolkits.basemap import Basemap #to render maps
import math

from GrowYourIC import tracers, positions, geodyn, geodyn_trg, geodyn_static, plot_data, data, geodyn_analytical_flows

#plt.rcParams['figure.figsize'] = (8.0, 3.0) #size of figures
cm = plt.cm.get_cmap('viridis_r')

#V = 0.2 # translation velocity
#S2 = 1/5.

#Yoshida = geodyn_analytical_flows.Yoshida96(V, S=S2)
#file = "Fig/Yoshida_{}_S2_{}".format(V, S2)
#print(file)

V = [0.2, 0.4]
S2 = [1/5., 4/5., 2.]

for vitesse in V:
    for value_S in S2:
        Yoshida = geodyn_analytical_flows.Yoshida96(vitesse, S=value_S)
        file = "Fig/Yoshida_{}_S2_{}".format(vitesse, value_S)
        print(file)

        npoints = 50 #number of points in the x direction for the data set.
        data_set = data.PerfectSamplingCut(npoints, rICB = 1.)
        data_set.method = "bt_point"

        # Age plot with velocity field
        proxy = geodyn.evaluate_proxy(data_set, Yoshida, proxy_type="age", verbose = False)
        data_set.plot_c_vec(Yoshida, proxy=proxy, nameproxy="age")
        plt.savefig(file+"_age.pdf")

# accumulated deformation
#proxy = geodyn.evaluate_proxy(data_set, Yoshida, proxy_type="vMises_acc", verbose = False)
#data_set.plot_c_vec(Yoshida, proxy=proxy, cm=cm, nameproxy="vMises_acc")
#plt.savefig(file+"_vM_acc.pdf")
#data_set.plot_c_vec(Yoshida, proxy=np.log10(proxy), cm=cm, nameproxy="log_vMises_acc")
#plt.savefig(file+"_log_vM_acc.pdf")

# tracers with age
#tracers.Swarm(5, Yoshida, Yoshida.tau_ic/400, "ici", plane="meridional")

#data_set = data.PerfectSamplingCut(20, rICB = 1.)
#data_set.method = "bt_point"
#proxy = geodyn.evaluate_proxy(data_set, Yoshida, proxy_type="age", verbose = False)
#data_set.plot_c_vec(Yoshida, proxy=proxy, nameproxy="age")

#plt.show()

#proxy = geodyn.evaluate_proxy(data_set, Yoshida, proxy_type="vMises_tau_ic", verbose = False)
#data_set.plot_c_vec(Yoshida, proxy=proxy, cm=cm, nameproxy="vMises_tau_ic")
#proxy = geodyn.evaluate_proxy(data_set, Yoshida, proxy_type="vMises_acc", verbose = False)
#data_set.plot_c_vec(Yoshida, proxy=proxy, cm=cm, nameproxy="vMises_acc")

#Karato = geodyn_analytical_flows.Model_LorentzForce()
#proxy = geodyn.evaluate_proxy(data_set, Karato, proxy_type="vMises_tau_ic", verbose = False)
#data_set.plot_c_vec(Karato, proxy=proxy, cm=cm, nameproxy="vMises_tau_ic")

#Karato.P = 1e-4
#proxy = geodyn.evaluate_proxy(data_set, Karato, proxy_type="vMises_tau_ic", verbose = False)
#data_set.plot_c_vec(Karato, proxy=proxy, cm=cm, nameproxy="vMises_tau_ic")

#proxy = geodyn.evaluate_proxy(data_set, Karato, proxy_type="age", verbose = False)
#data_set.plot_c_vec(Karato, proxy=proxy, cm=cm, nameproxy="age")

#proxy = geodyn.evaluate_proxy(data_set, Yoshida, proxy_type="age", verbose = False)
#data_set.plot_c_vec(Yoshida, proxy=proxy, cm=cm, nameproxy="age")
#plt.savefig(file+"_tage.pdf")

#proxy = geodyn.evaluate_proxy(data_set, Yoshida, proxy_type="vMises_tau_ic", verbose = False)
#data_set.plot_c_vec(Yoshida, proxy=proxy, cm=cm, nameproxy="vMises_tau_ic")
#plt.savefig(file+"_t_vM.pdf")

#proxy = geodyn.evaluate_proxy(data_set, Yoshida, proxy_type="vMises_cart", verbose = False)
#data_set.plot_c_vec(Yoshida, proxy=proxy, cm=cm, nameproxy="vMises_cart")
#plt.savefig("Yoshida_vM.pdf")

#Karato.P = 1e4
#proxy_1 = geodyn.evaluate_proxy(data_set, Karato, proxy_type="vMises_tau_ic", verbose = False)
#data_set.plot_c_vec(Karato, proxy=proxy_1, cm=cm, nameproxy="vMises_tau_ic")

#npoints = 50 #number of points in the x direction for the data set.
#data_set = data.PerfectSamplingCut(npoints, rICB = 1.)
#data_set.method = "bt_point"
#proxy_2 = geodyn.evaluate_proxy(data_set, Karato, proxy_type="age", verbose = False)
#data_set.plot_c_vec(Karato, proxy=proxy_2, cm=cm, nameproxy="age")

#npoints = 100 #number of points in the x direction for the data set.
#data_set = data.PerfectSamplingCut(npoints, rICB = 1.)
#data_set.method = "bt_point"
#proxy = geodyn.evaluate_proxy(data_set, Yoshida, proxy_type="vMises_acc", verbose = False)
#data_set.plot_c_vec(Yoshida, proxy=proxy, cm=cm, nameproxy="vMises_acc")

plt.show()


# OpenFace training tests.
#
# Copyright 2015-2016 Carnegie Mellon University
#
# 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.

import os
import shutil
import sys

import numpy as np
np.set_printoptions(precision=2)
import pandas as pd
import tempfile

from subprocess import Popen, PIPE

openfaceDir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
modelDir = os.path.join(openfaceDir, 'models')

exampleImages = os.path.join(openfaceDir, 'images', 'examples')
lfwSubset = os.path.join(openfaceDir, 'data', 'lfw-subset')

def test_dnn_training():
    assert os.path.isdir(
        lfwSubset), "Get lfw-subset by running ./data/download-lfw-subset.sh"

    imgWorkDir = tempfile.mkdtemp(prefix='OpenFaceTrainingTest-Img-')
    cmd = [sys.executable, os.path.join(openfaceDir, 'util', 'align-dlib.py'),
           os.path.join(lfwSubset, 'raw'), 'align', 'outerEyesAndNose',
           os.path.join(imgWorkDir, 'aligned')]
    p = Popen(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True)
    (out, err) = p.communicate()
    print(out)
    print(err)
    assert p.returncode == 0

    cmd = [sys.executable, os.path.join(openfaceDir, 'util', 'align-dlib.py'),
           os.path.join(lfwSubset, 'raw'), 'align', 'outerEyesAndNose',
           os.path.join(imgWorkDir, 'aligned')]
    p = Popen(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True)
    (out, err) = p.communicate()
    print(out)
    print(err)
    assert p.returncode == 0

    netWorkDir = tempfile.mkdtemp(prefix='OpenFaceTrainingTest-Net-')
    saveDir = os.path.join(netWorkDir, '1')
    cmd = ['th', './main.lua',
           '-data', os.path.join(imgWorkDir, 'aligned'),
           '-modelDef', '../models/openface/nn4.def.lua',
           '-peoplePerBatch', '3',
           '-imagesPerPerson', '10',
           '-nEpochs', '10',
           '-epochSize', '1',
           '-cache', netWorkDir,
           '-save', saveDir,
           '-cuda', '-cudnn', '-testing',
           '-nDonkeys', '-1']
    p = Popen(cmd, stdout=PIPE, stderr=PIPE,
              cwd=os.path.join(openfaceDir, 'training'), universal_newlines=True)
    (out, err) = p.communicate()
    print(out)
    print(err)
    assert p.returncode == 0

    # Training won't make much progress on lfw-subset, but as a sanity check,
    # make sure the training code runs and doesn't get worse than 0.2.
    trainLoss = pd.read_csv(os.path.join(saveDir, 'train.log'),
                            sep='\t').as_matrix()[:, 0]
    assert np.mean(trainLoss) < 0.3

    shutil.rmtree(imgWorkDir)
    shutil.rmtree(netWorkDir)


import unittest
import copy
import sys

from nose.tools import assert_true
import numpy as np
from numpy.testing import (assert_array_equal, assert_array_almost_equal,
                           assert_raises)
from scipy import stats
from sklearn import mixture
from sklearn.datasets.samples_generator import make_spd_matrix
from sklearn.utils.testing import assert_greater
from sklearn.utils.testing import assert_raise_message
from sklearn.metrics.cluster import adjusted_rand_score
from sklearn.externals.six.moves import cStringIO as StringIO

rng = np.random.RandomState(0)

def test_sample_gaussian():
    # Test sample generation from mixture.sample_gaussian where covariance
    # is diagonal, spherical and full

    n_features, n_samples = 2, 300
    axis = 1
    mu = rng.randint(10) * rng.rand(n_features)
    cv = (rng.rand(n_features) + 1.0) ** 2

    samples = mixture.sample_gaussian(
        mu, cv, covariance_type='diag', n_samples=n_samples)

    assert_true(np.allclose(samples.mean(axis), mu, atol=1.3))
    assert_true(np.allclose(samples.var(axis), cv, atol=1.5))

    # the same for spherical covariances
    cv = (rng.rand() + 1.0) ** 2
    samples = mixture.sample_gaussian(
        mu, cv, covariance_type='spherical', n_samples=n_samples)

    assert_true(np.allclose(samples.mean(axis), mu, atol=1.5))
    assert_true(np.allclose(
        samples.var(axis), np.repeat(cv, n_features), atol=1.5))

    # and for full covariances
    A = rng.randn(n_features, n_features)
    cv = np.dot(A.T, A) + np.eye(n_features)
    samples = mixture.sample_gaussian(
        mu, cv, covariance_type='full', n_samples=n_samples)
    assert_true(np.allclose(samples.mean(axis), mu, atol=1.3))
    assert_true(np.allclose(np.cov(samples), cv, atol=2.5))

    # Numerical stability check: in SciPy 0.12.0 at least, eigh may return
    # tiny negative values in its second return value.
    from sklearn.mixture import sample_gaussian
    x = sample_gaussian([0, 0], [[4, 3], [1, .1]],
                        covariance_type='full', random_state=42)
    print(x)
    assert_true(np.isfinite(x).all())

def _naive_lmvnpdf_diag(X, mu, cv):
    # slow and naive implementation of lmvnpdf
    ref = np.empty((len(X), len(mu)))
    stds = np.sqrt(cv)
    for i, (m, std) in enumerate(zip(mu, stds)):
        ref[:, i] = np.log(stats.norm.pdf(X, m, std)).sum(axis=1)
    return ref

def test_lmvnpdf_diag():
    # test a slow and naive implementation of lmvnpdf and
    # compare it to the vectorized version (mixture.lmvnpdf) to test
    # for correctness
    n_features, n_components, n_samples = 2, 3, 10
    mu = rng.randint(10) * rng.rand(n_components, n_features)
    cv = (rng.rand(n_components, n_features) + 1.0) ** 2
    X = rng.randint(10) * rng.rand(n_samples, n_features)

    ref = _naive_lmvnpdf_diag(X, mu, cv)
    lpr = mixture.log_multivariate_normal_density(X, mu, cv, 'diag')
    assert_array_almost_equal(lpr, ref)

def test_lmvnpdf_spherical():
    n_features, n_components, n_samples = 2, 3, 10

    mu = rng.randint(10) * rng.rand(n_components, n_features)
    spherecv = rng.rand(n_components, 1) ** 2 + 1
    X = rng.randint(10) * rng.rand(n_samples, n_features)

    cv = np.tile(spherecv, (n_features, 1))
    reference = _naive_lmvnpdf_diag(X, mu, cv)
    lpr = mixture.log_multivariate_normal_density(X, mu, spherecv,
                                                  'spherical')
    assert_array_almost_equal(lpr, reference)

def test_lmvnpdf_full():
    n_features, n_components, n_samples = 2, 3, 10

    mu = rng.randint(10) * rng.rand(n_components, n_features)
    cv = (rng.rand(n_components, n_features) + 1.0) ** 2
    X = rng.randint(10) * rng.rand(n_samples, n_features)

    fullcv = np.array([np.diag(x) for x in cv])

    reference = _naive_lmvnpdf_diag(X, mu, cv)
    lpr = mixture.log_multivariate_normal_density(X, mu, fullcv, 'full')
    assert_array_almost_equal(lpr, reference)

def test_lvmpdf_full_cv_non_positive_definite():
    n_features, n_samples = 2, 10
    rng = np.random.RandomState(0)
    X = rng.randint(10) * rng.rand(n_samples, n_features)
    mu = np.mean(X, 0)
    cv = np.array([[[-1, 0], [0, 1]]])
    expected_message = "'covars' must be symmetric, positive-definite"
    assert_raise_message(ValueError, expected_message,
                         mixture.log_multivariate_normal_density,
                         X, mu, cv, 'full')

def test_GMM_attributes():
    n_components, n_features = 10, 4
    covariance_type = 'diag'
    g = mixture.GMM(n_components, covariance_type, random_state=rng)
    weights = rng.rand(n_components)
    weights = weights / weights.sum()
    means = rng.randint(-20, 20, (n_components, n_features))

    assert_true(g.n_components == n_components)
    assert_true(g.covariance_type == covariance_type)

    g.weights_ = weights
    assert_array_almost_equal(g.weights_, weights)
    g.means_ = means
    assert_array_almost_equal(g.means_, means)

    covars = (0.1 + 2 * rng.rand(n_components, n_features)) ** 2
    g.covars_ = covars
    assert_array_almost_equal(g.covars_, covars)
    assert_raises(ValueError, g._set_covars, [])
    assert_raises(ValueError, g._set_covars,
                  np.zeros((n_components - 2, n_features)))

    assert_raises(ValueError, mixture.GMM, n_components=20,
                  covariance_type='badcovariance_type')

class GMMTester():
    do_test_eval = True

    def _setUp(self):
        self.n_components = 10
        self.n_features = 4
        self.weights = rng.rand(self.n_components)
        self.weights = self.weights / self.weights.sum()
        self.means = rng.randint(-20, 20, (self.n_components, self.n_features))
        self.threshold = -0.5
        self.I = np.eye(self.n_features)
        self.covars = {
            'spherical': (0.1 + 2 * rng.rand(self.n_components,
                                             self.n_features)) ** 2,
            'tied': (make_spd_matrix(self.n_features, random_state=0)
                     + 5 * self.I),
            'diag': (0.1 + 2 * rng.rand(self.n_components,
                                        self.n_features)) ** 2,
            'full': np.array([make_spd_matrix(self.n_features, random_state=0)
                              + 5 * self.I for x in range(self.n_components)])}

    def test_eval(self):
        if not self.do_test_eval:
            return  # DPGMM does not support setting the means and
        # covariances before fitting There is no way of fixing this
        # due to the variational parameters being more expressive than
        # covariance matrices
        g = self.model(n_components=self.n_components,
                       covariance_type=self.covariance_type, random_state=rng)
        # Make sure the means are far apart so responsibilities.argmax()
        # picks the actual component used to generate the observations.
        g.means_ = 20 * self.means
        g.covars_ = self.covars[self.covariance_type]
        g.weights_ = self.weights

        gaussidx = np.repeat(np.arange(self.n_components), 5)
        n_samples = len(gaussidx)
        X = rng.randn(n_samples, self.n_features) + g.means_[gaussidx]

        ll, responsibilities = g.score_samples(X)

        self.assertEqual(len(ll), n_samples)
        self.assertEqual(responsibilities.shape,
                         (n_samples, self.n_components))
        assert_array_almost_equal(responsibilities.sum(axis=1),
                                  np.ones(n_samples))
        assert_array_equal(responsibilities.argmax(axis=1), gaussidx)

    def test_sample(self, n=100):
        g = self.model(n_components=self.n_components,
                       covariance_type=self.covariance_type, random_state=rng)
        # Make sure the means are far apart so responsibilities.argmax()
        # picks the actual component used to generate the observations.
        g.means_ = 20 * self.means
        g.covars_ = np.maximum(self.covars[self.covariance_type], 0.1)
        g.weights_ = self.weights

        samples = g.sample(n)
        self.assertEqual(samples.shape, (n, self.n_features))

    def test_train(self, params='wmc'):
        g = mixture.GMM(n_components=self.n_components,
                        covariance_type=self.covariance_type)
        g.weights_ = self.weights
        g.means_ = self.means
        g.covars_ = 20 * self.covars[self.covariance_type]

        # Create a training set by sampling from the predefined distribution.
        X = g.sample(n_samples=100)
        g = self.model(n_components=self.n_components,
                       covariance_type=self.covariance_type,
                       random_state=rng, min_covar=1e-1,
                       n_iter=1, init_params=params)
        g.fit(X)

        # Do one training iteration at a time so we can keep track of
        # the log likelihood to make sure that it increases after each
        # iteration.
        trainll = []
        for _ in range(5):
            g.params = params
            g.init_params = ''
            g.fit(X)
            trainll.append(self.score(g, X))
        g.n_iter = 10
        g.init_params = ''
        g.params = params
        g.fit(X)  # finish fitting

        # Note that the log likelihood will sometimes decrease by a
        # very small amount after it has more or less converged due to
        # the addition of min_covar to the covariance (to prevent
        # underflow).  This is why the threshold is set to -0.5
        # instead of 0.
        delta_min = np.diff(trainll).min()
        self.assertTrue(
            delta_min > self.threshold,
            "The min nll increase is %f which is lower than the admissible"
            " threshold of %f, for model %s. The likelihoods are %s."
            % (delta_min, self.threshold, self.covariance_type, trainll))

    def test_train_degenerate(self, params='wmc'):
        # Train on degenerate data with 0 in some dimensions
        # Create a training set by sampling from the predefined distribution.
        X = rng.randn(100, self.n_features)
        X.T[1:] = 0
        g = self.model(n_components=2, covariance_type=self.covariance_type,
                       random_state=rng, min_covar=1e-3, n_iter=5,
                       init_params=params)
        g.fit(X)
        trainll = g.score(X)
        self.assertTrue(np.sum(np.abs(trainll / 100 / X.shape[1])) < 5)

    def test_train_1d(self, params='wmc'):
        # Train on 1-D data
        # Create a training set by sampling from the predefined distribution.
        X = rng.randn(100, 1)
        # X.T[1:] = 0
        g = self.model(n_components=2, covariance_type=self.covariance_type,
                       random_state=rng, min_covar=1e-7, n_iter=5,
                       init_params=params)
        g.fit(X)
        trainll = g.score(X)
        if isinstance(g, mixture.DPGMM):
            self.assertTrue(np.sum(np.abs(trainll / 100)) < 5)
        else:
            self.assertTrue(np.sum(np.abs(trainll / 100)) < 2)

    def score(self, g, X):
        return g.score(X).sum()

class TestGMMWithSphericalCovars(unittest.TestCase, GMMTester):
    covariance_type = 'spherical'
    model = mixture.GMM
    setUp = GMMTester._setUp

class TestGMMWithDiagonalCovars(unittest.TestCase, GMMTester):
    covariance_type = 'diag'
    model = mixture.GMM
    setUp = GMMTester._setUp

class TestGMMWithTiedCovars(unittest.TestCase, GMMTester):
    covariance_type = 'tied'
    model = mixture.GMM
    setUp = GMMTester._setUp

class TestGMMWithFullCovars(unittest.TestCase, GMMTester):
    covariance_type = 'full'
    model = mixture.GMM
    setUp = GMMTester._setUp

def test_multiple_init():
    # Test that multiple inits does not much worse than a single one
    X = rng.randn(30, 5)
    X[:10] += 2
    g = mixture.GMM(n_components=2, covariance_type='spherical',
                    random_state=rng, min_covar=1e-7, n_iter=5)
    train1 = g.fit(X).score(X).sum()
    g.n_init = 5
    train2 = g.fit(X).score(X).sum()
    assert_true(train2 >= train1 - 1.e-2)

def test_n_parameters():
    # Test that the right number of parameters is estimated
    n_samples, n_dim, n_components = 7, 5, 2
    X = rng.randn(n_samples, n_dim)
    n_params = {'spherical': 13, 'diag': 21, 'tied': 26, 'full': 41}
    for cv_type in ['full', 'tied', 'diag', 'spherical']:
        g = mixture.GMM(n_components=n_components, covariance_type=cv_type,
                        random_state=rng, min_covar=1e-7, n_iter=1)
        g.fit(X)
        assert_true(g._n_parameters() == n_params[cv_type])

def test_1d_1component():
    # Test all of the covariance_types return the same BIC score for
    # 1-dimensional, 1 component fits.
    n_samples, n_dim, n_components = 100, 1, 1
    X = rng.randn(n_samples, n_dim)
    g_full = mixture.GMM(n_components=n_components, covariance_type='full',
                         random_state=rng, min_covar=1e-7, n_iter=1)
    g_full.fit(X)
    g_full_bic = g_full.bic(X)
    for cv_type in ['tied', 'diag', 'spherical']:
        g = mixture.GMM(n_components=n_components, covariance_type=cv_type,
                        random_state=rng, min_covar=1e-7, n_iter=1)
        g.fit(X)
        assert_array_almost_equal(g.bic(X), g_full_bic)

def assert_fit_predict_correct(model, X):
    model2 = copy.deepcopy(model)

    predictions_1 = model.fit(X).predict(X)
    predictions_2 = model2.fit_predict(X)

    assert adjusted_rand_score(predictions_1, predictions_2) == 1.0

def test_fit_predict():
    """
    test that gmm.fit_predict is equivalent to gmm.fit + gmm.predict
    """
    lrng = np.random.RandomState(101)

    n_samples, n_dim, n_comps = 100, 2, 2
    mu = np.array([[8, 8]])
    component_0 = lrng.randn(n_samples, n_dim)
    component_1 = lrng.randn(n_samples, n_dim) + mu
    X = np.vstack((component_0, component_1))

    for m_constructor in (mixture.GMM, mixture.VBGMM, mixture.DPGMM):
        model = m_constructor(n_components=n_comps, covariance_type='full',
                              min_covar=1e-7, n_iter=5,
                              random_state=np.random.RandomState(0))
        assert_fit_predict_correct(model, X)

    model = mixture.GMM(n_components=n_comps, n_iter=0)
    z = model.fit_predict(X)
    assert np.all(z == 0), "Quick Initialization Failed!"

def test_aic():
    # Test the aic and bic criteria
    n_samples, n_dim, n_components = 50, 3, 2
    X = rng.randn(n_samples, n_dim)
    SGH = 0.5 * (X.var() + np.log(2 * np.pi))  # standard gaussian entropy

    for cv_type in ['full', 'tied', 'diag', 'spherical']:
        g = mixture.GMM(n_components=n_components, covariance_type=cv_type,
                        random_state=rng, min_covar=1e-7)
        g.fit(X)
        aic = 2 * n_samples * SGH * n_dim + 2 * g._n_parameters()
        bic = (2 * n_samples * SGH * n_dim +
               np.log(n_samples) * g._n_parameters())
        bound = n_dim * 3. / np.sqrt(n_samples)
        assert_true(np.abs(g.aic(X) - aic) / n_samples < bound)
        assert_true(np.abs(g.bic(X) - bic) / n_samples < bound)

def check_positive_definite_covars(covariance_type):
    r"""Test that covariance matrices do not become non positive definite

    Due to the accumulation of round-off errors, the computation of the
    covariance  matrices during the learning phase could lead to non-positive
    definite covariance matrices. Namely the use of the formula:

    .. math:: C = (\sum_i w_i  x_i x_i^T) - \mu \mu^T

    instead of:

    .. math:: C = \sum_i w_i (x_i - \mu)(x_i - \mu)^T

    while mathematically equivalent, was observed a ``LinAlgError`` exception,
    when computing a ``GMM`` with full covariance matrices and fixed mean.

    This function ensures that some later optimization will not introduce the
    problem again.
    """
    rng = np.random.RandomState(1)
    # we build a dataset with 2 2d component. The components are unbalanced
    # (respective weights 0.9 and 0.1)
    X = rng.randn(100, 2)
    X[-10:] += (3, 3)  # Shift the 10 last points

    gmm = mixture.GMM(2, params="wc", covariance_type=covariance_type,
                      min_covar=1e-3)

    # This is a non-regression test for issue #2640. The following call used
    # to trigger:
    # numpy.linalg.linalg.LinAlgError: 2-th leading minor not positive definite
    gmm.fit(X)

    if covariance_type == "diag" or covariance_type == "spherical":
        assert_greater(gmm.covars_.min(), 0)
    else:
        if covariance_type == "tied":
            covs = [gmm.covars_]
        else:
            covs = gmm.covars_

        for c in covs:
            assert_greater(np.linalg.det(c), 0)

def test_positive_definite_covars():
    # Check positive definiteness for all covariance types
    for covariance_type in ["full", "tied", "diag", "spherical"]:
        yield check_positive_definite_covars, covariance_type

def test_verbose_first_level():
    # Create sample data
    X = rng.randn(30, 5)
    X[:10] += 2
    g = mixture.GMM(n_components=2, n_init=2, verbose=1)

    old_stdout = sys.stdout
    sys.stdout = StringIO()
    try:
        g.fit(X)
    finally:
        sys.stdout = old_stdout

def test_verbose_second_level():
    # Create sample data
    X = rng.randn(30, 5)
    X[:10] += 2
    g = mixture.GMM(n_components=2, n_init=2, verbose=2)

    old_stdout = sys.stdout
    sys.stdout = StringIO()
    try:
        g.fit(X)
    finally:
        sys.stdout = old_stdout


"""Gaussian processes regression. """

# Authors: Jan Hendrik Metzen <jhm@informatik.uni-bremen.de>
#
# License: BSD 3 clause

import warnings
from operator import itemgetter

import numpy as np
from scipy.linalg import cholesky, cho_solve, solve_triangular
from scipy.optimize import fmin_l_bfgs_b

from sklearn.base import BaseEstimator, RegressorMixin, clone
from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C
from sklearn.utils import check_random_state
from sklearn.utils.validation import check_X_y, check_array

class GaussianProcessRegressor(BaseEstimator, RegressorMixin):
    """Gaussian process regression (GPR).

    The implementation is based on Algorithm 2.1 of Gaussian Processes
    for Machine Learning (GPML) by Rasmussen and Williams.

    In addition to standard scikit-learn estimator API,
    GaussianProcessRegressor:

       * allows prediction without prior fitting (based on the GP prior)
       * provides an additional method sample_y(X), which evaluates samples
         drawn from the GPR (prior or posterior) at given inputs
       * exposes a method log_marginal_likelihood(theta), which can be used
         externally for other ways of selecting hyperparameters, e.g., via
         Markov chain Monte Carlo.

    Read more in the :ref:`User Guide <gaussian_process>`.

    Parameters
    ----------
    kernel : kernel object
        The kernel specifying the covariance function of the GP. If None is
        passed, the kernel "1.0 * RBF(1.0)" is used as default. Note that
        the kernel's hyperparameters are optimized during fitting.

    alpha : float or array-like, optional (default: 1e-10)
        Value added to the diagonal of the kernel matrix during fitting.
        Larger values correspond to increased noise level in the observations
        and reduce potential numerical issue during fitting. If an array is
        passed, it must have the same number of entries as the data used for
        fitting and is used as datapoint-dependent noise level. Note that this
        is equivalent to adding a WhiteKernel with c=alpha. Allowing to specify
        the noise level directly as a parameter is mainly for convenience and
        for consistency with Ridge.

    optimizer : string or callable, optional (default: "fmin_l_bfgs_b")
        Can either be one of the internally supported optimizers for optimizing
        the kernel's parameters, specified by a string, or an externally
        defined optimizer passed as a callable. If a callable is passed, it
        must have the signature::

            def optimizer(obj_func, initial_theta, bounds):
                # * 'obj_func' is the objective function to be maximized, which
                #   takes the hyperparameters theta as parameter and an
                #   optional flag eval_gradient, which determines if the
                #   gradient is returned additionally to the function value
                # * 'initial_theta': the initial value for theta, which can be
                #   used by local optimizers
                # * 'bounds': the bounds on the values of theta
                ....
                # Returned are the best found hyperparameters theta and
                # the corresponding value of the target function.
                return theta_opt, func_min

        Per default, the 'fmin_l_bfgs_b' algorithm from scipy.optimize
        is used. If None is passed, the kernel's parameters are kept fixed.
        Available internal optimizers are::

            'fmin_l_bfgs_b'

    n_restarts_optimizer: int, optional (default: 0)
        The number of restarts of the optimizer for finding the kernel's
        parameters which maximize the log-marginal likelihood. The first run
        of the optimizer is performed from the kernel's initial parameters,
        the remaining ones (if any) from thetas sampled log-uniform randomly
        from the space of allowed theta-values. If greater than 0, all bounds
        must be finite. Note that n_restarts_optimizer == 0 implies that one
        run is performed.

    normalize_y: boolean, optional (default: False)
        Whether the target values y are normalized, i.e., the mean of the
        observed target values become zero. This parameter should be set to
        True if the target values' mean is expected to differ considerable from
        zero. When enabled, the normalization effectively modifies the GP's
        prior based on the data, which contradicts the likelihood principle;
        normalization is thus disabled per default.

    copy_X_train : bool, optional (default: True)
        If True, a persistent copy of the training data is stored in the
        object. Otherwise, just a reference to the training data is stored,
        which might cause predictions to change if the data is modified
        externally.

    random_state : integer or numpy.RandomState, optional
        The generator used to initialize the centers. If an integer is
        given, it fixes the seed. Defaults to the global numpy random
        number generator.

    Attributes
    ----------
    X_train_ : array-like, shape = (n_samples, n_features)
        Feature values in training data (also required for prediction)

    y_train_: array-like, shape = (n_samples, [n_output_dims])
        Target values in training data (also required for prediction)

    kernel_: kernel object
        The kernel used for prediction. The structure of the kernel is the
        same as the one passed as parameter but with optimized hyperparameters

    L_: array-like, shape = (n_samples, n_samples)
        Lower-triangular Cholesky decomposition of the kernel in ``X_train_``

    alpha_: array-like, shape = (n_samples,)
        Dual coefficients of training data points in kernel space

    log_marginal_likelihood_value_: float
        The log-marginal-likelihood of ``self.kernel_.theta``
    """
    def __init__(self, kernel=None, alpha=1e-10,
                 optimizer="fmin_l_bfgs_b", n_restarts_optimizer=0,
                 normalize_y=False, copy_X_train=True, random_state=None):
        self.kernel = kernel
        self.alpha = alpha
        self.optimizer = optimizer
        self.n_restarts_optimizer = n_restarts_optimizer
        self.normalize_y = normalize_y
        self.copy_X_train = copy_X_train
        self.random_state = random_state

    def fit(self, X, y):
        """Fit Gaussian process regression model

        Parameters
        ----------
        X : array-like, shape = (n_samples, n_features)
            Training data

        y : array-like, shape = (n_samples, [n_output_dims])
            Target values

        Returns
        -------
        self : returns an instance of self.
        """
        if self.kernel is None:  # Use an RBF kernel as default
            self.kernel_ = C(1.0, constant_value_bounds="fixed") \
                * RBF(1.0, length_scale_bounds="fixed")
        else:
            self.kernel_ = clone(self.kernel)

        self.rng = check_random_state(self.random_state)

        X, y = check_X_y(X, y, multi_output=True, y_numeric=True)

        # Normalize target value
        if self.normalize_y:
            self.y_train_mean = np.mean(y, axis=0)
            # demean y
            y = y - self.y_train_mean
        else:
            self.y_train_mean = np.zeros(1)

        if np.iterable(self.alpha) \
           and self.alpha.shape[0] != y.shape[0]:
            if self.alpha.shape[0] == 1:
                self.alpha = self.alpha[0]
            else:
                raise ValueError("alpha must be a scalar or an array"
                                 " with same number of entries as y.(%d != %d)"
                                 % (self.alpha.shape[0], y.shape[0]))

        self.X_train_ = np.copy(X) if self.copy_X_train else X
        self.y_train_ = np.copy(y) if self.copy_X_train else y

        if self.optimizer is not None and self.kernel_.n_dims > 0:
            # Choose hyperparameters based on maximizing the log-marginal
            # likelihood (potentially starting from several initial values)
            def obj_func(theta, eval_gradient=True):
                if eval_gradient:
                    lml, grad = self.log_marginal_likelihood(
                        theta, eval_gradient=True)
                    return -lml, -grad
                else:
                    return -self.log_marginal_likelihood(theta)

            # First optimize starting from theta specified in kernel
            optima = [(self._constrained_optimization(obj_func,
                                                      self.kernel_.theta,
                                                      self.kernel_.bounds))]

            # Additional runs are performed from log-uniform chosen initial
            # theta
            if self.n_restarts_optimizer > 0:
                if not np.isfinite(self.kernel_.bounds).all():
                    raise ValueError(
                        "Multiple optimizer restarts (n_restarts_optimizer>0) "
                        "requires that all bounds are finite.")
                bounds = self.kernel_.bounds
                for iteration in range(self.n_restarts_optimizer):
                    theta_initial = \
                        self.rng.uniform(bounds[:, 0], bounds[:, 1])
                    optima.append(
                        self._constrained_optimization(obj_func, theta_initial,
                                                       bounds))
            # Select result from run with minimal (negative) log-marginal
            # likelihood
            lml_values = list(map(itemgetter(1), optima))
            self.kernel_.theta = optima[np.argmin(lml_values)][0]
            self.log_marginal_likelihood_value_ = -np.min(lml_values)
        else:
            self.log_marginal_likelihood_value_ = \
                self.log_marginal_likelihood(self.kernel_.theta)

        # Precompute quantities required for predictions which are independent
        # of actual query points
        K = self.kernel_(self.X_train_)
        K[np.diag_indices_from(K)] += self.alpha
        self.L_ = cholesky(K, lower=True)  # Line 2
        self.alpha_ = cho_solve((self.L_, True), self.y_train_)  # Line 3

        return self

    def predict(self, X, return_std=False, return_cov=False):
        """Predict using the Gaussian process regression model

        We can also predict based on an unfitted model by using the GP prior.
        In addition to the mean of the predictive distribution, also its
        standard deviation (return_std=True) or covariance (return_cov=True).
        Note that at most one of the two can be requested.

        Parameters
        ----------
        X : array-like, shape = (n_samples, n_features)
            Query points where the GP is evaluated

        return_std : bool, default: False
            If True, the standard-deviation of the predictive distribution at
            the query points is returned along with the mean.

        return_cov : bool, default: False
            If True, the covariance of the joint predictive distribution at
            the query points is returned along with the mean

        Returns
        -------
        y_mean : array, shape = (n_samples, [n_output_dims])
            Mean of predictive distribution a query points

        y_std : array, shape = (n_samples,), optional
            Standard deviation of predictive distribution at query points.
            Only returned when return_std is True.

        y_cov : array, shape = (n_samples, n_samples), optional
            Covariance of joint predictive distribution a query points.
            Only returned when return_cov is True.
        """
        if return_std and return_cov:
            raise RuntimeError(
                "Not returning standard deviation of predictions when "
                "returning full covariance.")

        X = check_array(X)

        if not hasattr(self, "X_train_"):  # Unfitted;predict based on GP prior
            y_mean = np.zeros(X.shape[0])
            if return_cov:
                y_cov = self.kernel(X)
                return y_mean, y_cov
            elif return_std:
                y_var = self.kernel.diag(X)
                return y_mean, np.sqrt(y_var)
            else:
                return y_mean
        else:  # Predict based on GP posterior
            K_trans = self.kernel_(X, self.X_train_)
            y_mean = K_trans.dot(self.alpha_)  # Line 4 (y_mean = f_star)
            y_mean = self.y_train_mean + y_mean  # undo normal.
            if return_cov:
                v = cho_solve((self.L_, True), K_trans.T)  # Line 5
                y_cov = self.kernel_(X) - K_trans.dot(v)  # Line 6
                return y_mean, y_cov
            elif return_std:
                # compute inverse K_inv of K based on its Cholesky
                # decomposition L and its inverse L_inv
                L_inv = solve_triangular(self.L_.T, np.eye(self.L_.shape[0]))
                K_inv = L_inv.dot(L_inv.T)
                # Compute variance of predictive distribution
                y_var = self.kernel_.diag(X)
                y_var -= np.einsum("ki,kj,ij->k", K_trans, K_trans, K_inv)

                # Check if any of the variances is negative because of
                # numerical issues. If yes: set the variance to 0.
                y_var_negative = y_var < 0
                if np.any(y_var_negative):
                    warnings.warn("Predicted variances smaller than 0. "
                                  "Setting those variances to 0.")
                    y_var[y_var_negative] = 0.0
                return y_mean, np.sqrt(y_var)
            else:
                return y_mean

    def sample_y(self, X, n_samples=1, random_state=0):
        """Draw samples from Gaussian process and evaluate at X.

        Parameters
        ----------
        X : array-like, shape = (n_samples_X, n_features)
            Query points where the GP samples are evaluated

        n_samples : int, default: 1
            The number of samples drawn from the Gaussian process

        random_state: RandomState or an int seed (0 by default)
            A random number generator instance

        Returns
        -------
        y_samples : array, shape = (n_samples_X, [n_output_dims], n_samples)
            Values of n_samples samples drawn from Gaussian process and
            evaluated at query points.
        """
        rng = check_random_state(random_state)

        y_mean, y_cov = self.predict(X, return_cov=True)
        if y_mean.ndim == 1:
            y_samples = rng.multivariate_normal(y_mean, y_cov, n_samples).T
        else:
            y_samples = \
                [rng.multivariate_normal(y_mean[:, i], y_cov,
                                         n_samples).T[:, np.newaxis]
                 for i in range(y_mean.shape[1])]
            y_samples = np.hstack(y_samples)
        return y_samples

    def log_marginal_likelihood(self, theta=None, eval_gradient=False):
        """Returns log-marginal likelihood of theta for training data.

        Parameters
        ----------
        theta : array-like, shape = (n_kernel_params,) or None
            Kernel hyperparameters for which the log-marginal likelihood is
            evaluated. If None, the precomputed log_marginal_likelihood
            of ``self.kernel_.theta`` is returned.

        eval_gradient : bool, default: False
            If True, the gradient of the log-marginal likelihood with respect
            to the kernel hyperparameters at position theta is returned
            additionally. If True, theta must not be None.

        Returns
        -------
        log_likelihood : float
            Log-marginal likelihood of theta for training data.

        log_likelihood_gradient : array, shape = (n_kernel_params,), optional
            Gradient of the log-marginal likelihood with respect to the kernel
            hyperparameters at position theta.
            Only returned when eval_gradient is True.
        """
        if theta is None:
            if eval_gradient:
                raise ValueError(
                    "Gradient can only be evaluated for theta!=None")
            return self.log_marginal_likelihood_value_

        kernel = self.kernel_.clone_with_theta(theta)

        if eval_gradient:
            K, K_gradient = kernel(self.X_train_, eval_gradient=True)
        else:
            K = kernel(self.X_train_)

        K[np.diag_indices_from(K)] += self.alpha
        try:
            L = cholesky(K, lower=True)  # Line 2
        except np.linalg.LinAlgError:
            return (-np.inf, np.zeros_like(theta)) \
                if eval_gradient else -np.inf

        # Support multi-dimensional output of self.y_train_
        y_train = self.y_train_
        if y_train.ndim == 1:
            y_train = y_train[:, np.newaxis]

        alpha = cho_solve((L, True), y_train)  # Line 3

        # Compute log-likelihood (compare line 7)
        log_likelihood_dims = -0.5 * np.einsum("ik,ik->k", y_train, alpha)
        log_likelihood_dims -= np.log(np.diag(L)).sum()
        log_likelihood_dims -= K.shape[0] / 2 * np.log(2 * np.pi)
        log_likelihood = log_likelihood_dims.sum(-1)  # sum over dimensions

        if eval_gradient:  # compare Equation 5.9 from GPML
            tmp = np.einsum("ik,jk->ijk", alpha, alpha)  # k: output-dimension
            tmp -= cho_solve((L, True), np.eye(K.shape[0]))[:, :, np.newaxis]
            # Compute "0.5 * trace(tmp.dot(K_gradient))" without
            # constructing the full matrix tmp.dot(K_gradient) since only
            # its diagonal is required
            log_likelihood_gradient_dims = \
                0.5 * np.einsum("ijl,ijk->kl", tmp, K_gradient)
            log_likelihood_gradient = log_likelihood_gradient_dims.sum(-1)

        if eval_gradient:
            return log_likelihood, log_likelihood_gradient
        else:
            return log_likelihood

    def _constrained_optimization(self, obj_func, initial_theta, bounds):
        if self.optimizer == "fmin_l_bfgs_b":
            theta_opt, func_min, convergence_dict = \
                fmin_l_bfgs_b(obj_func, initial_theta, bounds=bounds)
            if convergence_dict["warnflag"] != 0:
                warnings.warn("fmin_l_bfgs_b terminated abnormally with the "
                              " state: %s" % convergence_dict)
        elif callable(self.optimizer):
            theta_opt, func_min = \
                self.optimizer(obj_func, initial_theta, bounds=bounds)
        else:
            raise ValueError("Unknown optimizer %s." % self.optimizer)

        return theta_opt, func_min


"""
Ideas about fractional calculus defined on C^2
J^b f(x, a) = f(x, a + b)
"""

import numpy
from matplotlib import pyplot
from scipy import special

def monomial(x, a, x_0, a_0):
    return (x - x_0)**(a - a_0)/special.gamma(a - a_0 + 1)

def exp(x, a, b):
    return b**(-a)*numpy.exp(b*x)

def projx(f, x, a):
    n = numpy.searchsorted(numpy.real(a), 0.0)
    pyplot.plot(x, f[-n, :])
    pyplot.show()

def proja(f, x, a):
    n = numpy.searchsorted(numpy.real(x), 0.0)
    pyplot.plot(a, f[:, -n])
    pyplot.show()

def plotR(f, vmin=-10, vmax=10):
    _plot_C3(numpy.real(f), vmin=vmin, vmax=vmax)

def plotI(f, vmin=-10, vmax=10):
    _plot_C3(numpy.imag(f), vmin=vmin, vmax=vmax)

def plotM(f, vmax=10):
    _plot_C3(numpy.abs(f), vmax=vmax)

def plotMl(f):
    _plot_C3(numpy.log(numpy.abs(f)))

def _plot_C3(f, vmin=None, vmax=None):
    pyplot.imshow(f, extent = [x_0, x_1, a_0, a_1], vmin=vmin, vmax=vmax)
    pyplot.show()

x_0, x_1, Nx = -5, 5, 1000
a_0, a_1, Na = -5, 5,  1000
X = numpy.linspace(x_0, x_1, Nx, dtype=numpy.complex)
dx = (x_1 - x_0)/(Nx - 1)
da = (a_1 - a_0)/(Na - 1)
A = numpy.linspace(a_0, a_1, Na, dtype=numpy.complex)

domain_x, domain_a = numpy.meshgrid(X, A[::-1])

F = monomial(domain_x, domain_a, 0, -1)
G = monomial(domain_x, domain_a, 1, -1) + monomial(domain_x, domain_a, 1, 0)
G = -monomial(domain_x, domain_a, 1, -1) + 0.5*monomial(domain_x, domain_a, 0, -3)
G = (exp(domain_x, domain_a, 1.0j) + exp(domain_x, domain_a, -1.0j))/2.0
#G = (exp(domain_x, domain_a, 2.0j) - exp(domain_x, domain_a, -2.0j))/2.0
#G = F
Gp = numpy.gradient(G)
#G = Gp[1]

projx(G, X, A)
proja(G, X, A)
plotR(G)
plotI(G)
plotM(G)
plotMl(G)


#!/usr/bin/env python
# encoding: utf-8

"""
This code implemented review texts classication by using Support Vector Machine, Support Vector Regression,
Decision Tree and Random Forest, the evaluation function has been implemented as well.
"""

from time import gmtime, strftime

from sklearn import ensemble, svm
import Scikit_Classification as sc

features = []
labels = []

def main():
    starttime = strftime("%Y-%m-%d %H:%M:%S",gmtime())

    config = {}
    execfile("params.conf", config)
    inputfile = config["histogram_dataset"]
    trainingSamples = config["trainingSamples"]
    testingSamples = config["testingSamples"]

    numberOfSamples = trainingSamples + testingSamples

    rf_selectedFeatures = "all"
    svm_selectedFeatures = [20, 21, 22, 23, 24]

    rf_features, rf_labels = sc.Data_Preparation(inputfile, rf_selectedFeatures)
    svm_features, svm_labels = sc.Data_Preparation(inputfile, svm_selectedFeatures)

    Scikit_RandomForest_Model = ensemble.RandomForestClassifier(n_estimators=510, criterion='gini', max_depth=7,
                                                                 min_samples_split=2, min_samples_leaf=1, max_features='sqrt',
                                                                 bootstrap=True, oob_score=False, n_jobs=-1, random_state=None, verbose=0,
                                                                 min_density=None, compute_importances=None)

    Scikit_SVM_Model = svm.SVC(C=1.0, kernel='rbf', degree=3, gamma=0.0, coef0=0.0, shrinking=True, probability=True, tol=0.001, cache_size=200, class_weight=None, verbose=False, max_iter=-1, random_state=None)

    accuracy, testing_Labels, predict_Labels =  sc.Classification_Blending(Scikit_RandomForest_Model, rf_features, rf_labels, Scikit_SVM_Model, svm_features, svm_labels, trainingSamples, testingSamples)

    sc.Result_Evaluation('data/evaluation_result/evaluation_Blending.txt', accuracy, testing_Labels, predict_Labels)

    endtime = strftime("%Y-%m-%d %H:%M:%S",gmtime())
    print(starttime)
    print(endtime)

if __name__  == "__main__":
    main()


import predict as pd
import copy
import os
import numpy as np
import util
import shutil
import pickle
import pylab as plt
import pandas
import local_multiprocessing
import load_data
import features.featurization as feat

def check_feature_set_dims(feature_sets):
    F2 = None
    for set in feature_sets.keys():
        F = feature_sets[set].shape[0]
        if F2 is None: F = F2
        assert F == F2, "not same # individuals for feature %s" % set

    assert feature_sets !={}, "features are empty, check learn_options"

def set_target(learn_options, classification):
    assert 'target_name' not in learn_options.keys() or learn_options['target_name'] is not None, "changed it to be automatically set here"
    if not classification:
        learn_options["target_name"] = learn_options['rank-transformed target name']
        learn_options["training_metric"] = 'spearmanr'
        learn_options['ground_truth_label'] = learn_options['target_name']
    else:
        learn_options["target_name"] = learn_options['binary target name']
        learn_options["training_metric"] = 'AUC'
        learn_options['ground_truth_label'] = learn_options['binary target name']

    if learn_options["V"]==3:
        assert learn_options['target_name']=='score_drug_gene_rank' or learn_options['target_name']=='score_drug_gene_threshold', "cannot use raw scores when mergind data"
        assert learn_options["ground_truth_label"]=='score_drug_gene_rank' or learn_options["ground_truth_label"]=='score_drug_gene_threshold', "cannot use raw scores when mergind data"

    return learn_options

def GP_setup(learn_options, likelihood='gaussian', degree=3, set_target_fn=set_target):
    learn_options["method"] = "GPy"
    learn_options['kernel degree'] = degree

    if likelihood == 'warped':
        learn_options['warpedGP'] = True
    else:
        learn_options['warpedGP'] = False
    learn_options = set_target_fn(learn_options, classification=False)

    return learn_options

def SVC_setup(learn_options, likelihood='gaussian', degree=3,  set_target_fn=set_target):
    learn_options["method"] = "SVC"
    learn_options = set_target_fn(learn_options, classification=True)

    return learn_options

def L1_setup(learn_options, set_target_fn=set_target):
    learn_options = set_target_fn(learn_options, classification=False)
    learn_options["method"] = "linreg"
    learn_options["penalty"] = "L1"
    learn_options["feature_select"] = False
    if "alpha" not in learn_options.keys():
        learn_options["alpha"] = np.array([1e-6*pow(1.3,x) for x in range(0,100)])
    learn_options["loss"] = "squared"

    return learn_options

def L2_setup(learn_options, set_target_fn=set_target):
    learn_options = set_target_fn(learn_options, classification=False)
    learn_options["method"] = "linreg"
    learn_options["penalty"] = "L2"
    learn_options["feature_select"] = False
    if "alpha" not in learn_options.keys():
        learn_options["alpha"] = np.array([1e-6*pow(1.3,x) for x in range(0,100)])
    learn_options["loss"] = "squared"

    return learn_options

def mean_setup(learn_options, set_target_fn=set_target):
    learn_options = set_target_fn(learn_options, classification=False)
    learn_options['method'] = 'mean'
    return learn_options

def random_setup(learn_options, set_target_fn=set_target):
    learn_options = set_target_fn(learn_options, classification=False)
    learn_options['method'] = 'random'
    return learn_options

def elasticnet_setup(learn_options, set_target_fn=set_target):
    learn_options = set_target_fn(learn_options, classification=False)
    learn_options["method"] = "linreg"
    learn_options["penalty"] = "EN"
    learn_options["feature_select"] = False
    learn_options["loss"] = "squared"
    if "alpha" not in learn_options.keys():
        learn_options["alpha"] = np.array([1e-5*pow(2,x) for x in range(0,30)])
    return learn_options

def DNN_setup(learn_options, set_target_fn=set_target):
    learn_options = set_target_fn(learn_options, classification=False)
    learn_options['method'] = 'DNN'
    learn_options['DNN target variable'] = 'score'#'score_drug_gene_quantized'
    # learn_options['DNN architecture'] = (119, 10, 10, 10, 2)
    return learn_options

def RF_setup(learn_options, set_target_fn=set_target):
    learn_options = set_target_fn(learn_options, classification=False)
    learn_options['method'] = 'RandomForestRegressor'
    return learn_options

def doench_setup(learn_options, set_target_fn=set_target):
    learn_options = set_target_fn(learn_options, classification=True)
    learn_options['method'] = 'doench'
    return learn_options

def sgrna_from_doench_setup(learn_options, set_target_fn=set_target):
    learn_options = set_target_fn(learn_options, classification=False)
    learn_options['method'] = 'sgrna_from_doench'
    return learn_options

def linreg_setup(learn_options, set_target_fn=set_target):
    learn_options["method"] = "linreg"
    learn_options["penalty"] = "L1"
    learn_options["feature_select"] = False
    if "alpha" not in learn_options.keys():
        learn_options["alpha"] = np.array([0.0])
    learn_options["loss"] = "squared"
    learn_options = set_target_fn(learn_options, classification=False)

    return learn_options

def logregL1_setup(learn_options, set_target_fn=set_target):
    learn_options = set_target_fn(learn_options, classification=True)
    learn_options["method"] = "logregL1"
    learn_options["penalty"] = "L1"
    learn_options["feature_select"] = False
    if "alpha" not in learn_options.keys():
        learn_options["alpha"] = np.array([1e-6*pow(1.3,x) for x in range(0,100)])
    return learn_options

def LASSOs_ensemble_setup(learn_options, set_target_fn=set_target):
    learn_options = set_target_fn(learn_options, classification=False)
    learn_options["method"] = "lasso_ensemble"
    learn_options["penalty"] = "L1"
    learn_options["feature_select"] = False
    if "alpha" not in learn_options.keys():
        learn_options["alpha"] = np.array([1e-6*pow(1.3,x) for x in range(0,100)])
    learn_options["loss"] = "squared"

    return learn_options

def xu_et_al_setup(learn_options, set_target_fn=set_target):
    learn_options = set_target_fn(learn_options, classification=True)
    learn_options["method"] = "xu_et_al"

    return learn_options

def adaboost_setup(learn_options, num_estimators=100, max_depth=3, learning_rate=0.1, set_target_fn=set_target, model="AdaBoost"):
    """
    """
    learn_options = set_target_fn(learn_options, classification=False)
    if model=="AdaBoost":
        learn_options['method'] = "AdaBoostRegressor"
    elif model=="AdaBoostClassifier":
        learn_options['method'] = "AdaBoostClassifier"
    else:
        raise Exception("model must be either AdaBoost or AdaBoost Classifier")
    learn_options['adaboost_version'] = 'python' # "R" or "python"

    if 'adaboost_loss' not in learn_options.keys() and model=="AdaBoostRegressor":
        learn_options['adaboost_loss'] = 'ls' # alternatives: "lad", "huber", "quantile", see scikit docs for details
    if 'adaboost_alpha' not in learn_options.keys():
        learn_options['adaboost_alpha'] = 0.5 # this parameter is only used by the huber and quantile loss functions.

    if not learn_options['adaboost_CV']:
        learn_options['adaboost_learning_rate'] = learning_rate
        learn_options['adaboost_n_estimators'] = num_estimators
        learn_options['adaboost_max_depth'] = max_depth
    else:
        learn_options['adaboost_n_estimators'] = num_estimators

    return learn_options

def shared_setup(learn_options, order, test):
    if 'num_proc' not in learn_options.keys():
        learn_options['num_proc'] = None
    if 'num_thread_per_proc' not in learn_options.keys():
        learn_options['num_thread_per_proc'] = None

    num_proc = local_multiprocessing.configure(TEST=test, num_proc=learn_options["num_proc"],
                                                num_thread_per_proc=learn_options["num_thread_per_proc"])
    learn_options["num_proc"] = num_proc

    learn_options["order"] = order  # gets used many places in code, not just here

    if "cv" not in learn_options.keys():
        # if no CV preference is specified, use leave-one-gene-out
        learn_options["cv"] = "gene"

    if "normalize_features" not in learn_options.keys():
        # if no CV preference is specified, use leave-one-gene-out
        learn_options["normalize_features"] = True

    if "weighted" not in learn_options.keys():
        learn_options['weighted'] = None

    if "all pairs" not in learn_options.keys():
        learn_options["all pairs"] = False

    if "include_known_pairs" not in learn_options.keys():
        learn_options["include_known_pairs"] = False

    if "include_gene_guide_feature" not in learn_options.keys():
        learn_options["include_gene_guide_feature"] = 0 #used as window size, so 0 is none

    #these should default to true to match experiments before they were options:
    if "gc_features" not in learn_options.keys():
        learn_options["gc_features"] = True
    if "nuc_features" not in learn_options.keys():
        learn_options["nuc_features"] = True

    if 'train_genes' not in learn_options.keys():
        learn_options["train_genes"] = None
    if 'test_genes' not in learn_options.keys():
        learn_options["test_genes"] = None

    if "num_proc" not in learn_options:
        learn_options["num_proc"] = None
    if "num_thread_per_proc" not in learn_options:
        learn_options["num_thread_per_proc"] = None

    if 'seed' not in learn_options:
        learn_options['seed'] = 1

    if "flipV1target" not in learn_options:
        learn_options["flipV1target"] = False

    if 'num_genes_remove_train' not in learn_options:
        learn_options['num_genes_remove_train'] = None

    if "include_microhomology" not in learn_options:
        learn_options["include_microhomology"] = False

    if "algorithm_hyperparam_search" not in learn_options:
        learn_options["algorithm_hyperparam_search"] = "grid" # other options is bo for bayesian optimization

    return num_proc

def setup(test=False, order=1, learn_options=None, data_file=None, pam_audit=True, length_audit=True):

    num_proc = shared_setup(learn_options, order, test)

    assert "testing_non_binary_target_name" in learn_options.keys(), "need this in order to get metrics, though used to be not needed, so you may newly see this error"
    if learn_options["testing_non_binary_target_name"] not in ['ranks', 'raw', 'thrs']:
        raise Exception('learn_otions["testing_non_binary_target_name"] must be in ["ranks", "raw", "thrs"]')

    Xdf, Y, gene_position, target_genes = load_data.from_file(data_file, learn_options)
    learn_options['all_genes'] = target_genes

    if test:
        learn_options["order"] = 1

    if 'convert_30mer_to_31mer' in learn_options and learn_options['convert_30mer_to_31mer'] is True:
        print "WARNING!!! converting 30 mer to 31 mer (and then cutting off first nucleotide to go back to 30mer with a right shift)"
        for i in range(Xdf.shape[0]):
            Xdf['30mer'].iloc[i] = util.convert_to_thirty_one(Xdf.iloc[i]["30mer"], Xdf.index.values[i][1], Xdf.iloc[i]["Strand"])
        # to_keep = Xdf['30mer'].isnull() == False
        # Xdf = Xdf[to_keep]
        # gene_position = gene_position[to_keep]
        # Y = Y[to_keep]
        Xdf["30mer"] = Xdf["30mer"].apply(lambda x: x[1:]) # chop the first nucleotide

    if learn_options.has_key('left_right_guide_ind') and learn_options['left_right_guide_ind'] is not None:
        seq_start, seq_end, expected_length = learn_options['left_right_guide_ind']
        Xdf['30mer'] = Xdf['30mer'].apply(lambda seq: seq[seq_start:seq_end])

    feature_sets = feat.featurize_data(Xdf, learn_options, Y, gene_position, pam_audit=pam_audit, length_audit=length_audit)
    np.random.seed(learn_options['seed'])

    return Y, feature_sets, target_genes, learn_options, num_proc

def run_models(models, orders, GP_likelihoods=['gaussian', 'warped'], WD_kernel_degrees=[3],
               adaboost_learning_rates=[0.1], adaboost_num_estimators=[100], adaboost_max_depths=[3],
               learn_options_set=None, test=False, CV=True, setup_function=setup, set_target_fn=set_target, pam_audit=True, length_audit=True):

    '''
    CV is set to false if want to train a final model and not cross-validate, but it goes in to what
    looks like cv code
    '''

    results = {}
    assert learn_options_set is not None, "need to specify learn_options_set"
    all_learn_options = {}

    #shorten so easier to display on graphs
    feat_models_short = {'L1':"L1", 'L2':"L2", 'elasticnet':"EN", 'linreg':"LR",
                         'RandomForest': "RF",
                         'AdaBoost':"AB", 'AdaBoostClassifier':"ABClass", 'doench': 'doench',
                         "logregL1": "logregL1", "sgrna_from_doench":"sgrna_from_doench", 'SVC': 'SVC', 'xu_et_al': 'xu_et_al'}

    if not CV:
        print "Received option CV=False, so I'm training using all of the data"
        assert len(learn_options_set.keys()) == 1, "when CV is False, only 1 set of learn options is allowed"
        assert len(models) == 1, "when CV is False, only 1 model is allowed"

    for learn_options_str in learn_options_set.keys():
        # these options get augmented in setup
        partial_learn_opt = learn_options_set[learn_options_str]
        # if the model requires encoded features
        for model in models:
            # models requiring explicit featurization
            if model in feat_models_short.keys():
                for order in orders:
                    print "running %s, order %d for %s" % (model, order, learn_options_str)

                    Y, feature_sets, target_genes, learn_options, num_proc = setup_function(test=test, order=order, learn_options=partial_learn_opt, pam_audit=pam_audit, length_audit=length_audit) # TODO precompute features for all orders, as this is repated for each model

                    if model == 'L1':
                        learn_options_model = L1_setup(copy.deepcopy(learn_options), set_target_fn=set_target_fn)
                    elif model == 'L2':
                        learn_options_model = L2_setup(copy.deepcopy(learn_options), set_target_fn=set_target_fn)
                    elif model == 'elasticnet':
                        learn_options_model = elasticnet_setup(copy.deepcopy(learn_options), set_target_fn=set_target_fn)
                    elif model == 'linreg':
                        learn_options_model = linreg_setup(copy.deepcopy(learn_options), set_target_fn=set_target_fn)
                    elif model == "logregL1":
                        learn_options_model = logregL1_setup(copy.deepcopy(learn_options), set_target_fn=set_target_fn)
                    elif model == 'RandomForest':
                        learn_options_model = RF_setup(copy.deepcopy(learn_options), set_target_fn=set_target_fn)
                    elif model == 'SVC':
                        learn_options_model = SVC_setup(copy.deepcopy(learn_options), set_target_fn=set_target_fn)
                    elif model == 'doench':
                        learn_options_model = doench_setup(copy.deepcopy(learn_options), set_target_fn=set_target_fn)
                    elif model == 'sgrna_from_doench':
                        learn_options_model = sgrna_from_doench_setup(copy.deepcopy(learn_options), set_target_fn=set_target_fn)
                    elif model == 'xu_et_al':
                        learn_options_model = xu_et_al_setup(copy.deepcopy(learn_options), set_target_fn=set_target_fn)
                    elif model == 'AdaBoost' or 'AdaBoostClassifier':
                        for learning_rate in adaboost_learning_rates:
                            for num_estimators in adaboost_num_estimators:
                                for max_depth in adaboost_max_depths:
                                    learn_options_model = adaboost_setup(copy.deepcopy(learn_options), learning_rate=learning_rate, num_estimators=num_estimators, max_depth=max_depth, set_target_fn=set_target_fn, model=model)
                        model_string = feat_models_short[model] + '_or%d_md%d_lr%.2f_n%d_%s' % (learn_options_set[learn_options_str]["order"], max_depth, learning_rate, num_estimators, learn_options_str)
                    if model != 'AdaBoost':
                        model_string = feat_models_short[model] + '_ord%d_%s' % (learn_options_set[learn_options_str]["order"], learn_options_str)

                    results[model_string] = pd.cross_validate(Y, feature_sets, learn_options=learn_options_model, TEST=test, CV=CV)

                    all_learn_options[model_string] = learn_options_model
            # if the model doesn't require explicit featurization
            else:
                assert setup_fn==setup, "not yet modified to handle this"
                print "running %s for %s" % (model, learn_options_str)
                Y, feature_sets, target_genes, learn_options, num_proc = setup(test=test, order=1, learn_options=partial_learn_opt, pam_audit=pam_audit, length_audit=length_audit)
                if model == 'mean':
                    learn_options_model = mean_setup(copy.deepcopy(learn_options))
                elif model == 'random':
                    learn_options_model = random_setup(copy.deepcopy(learn_options))
                elif model == 'DNN':
                    learn_options_model = DNN_setup(copy.deepcopy(learn_options))
                elif model == 'GP':
                    for likelihood in GP_likelihoods:
                        for degree in WD_kernel_degrees:
                            learn_options_model = GP_setup(copy.deepcopy(learn_options), likelihood=likelihood, degree=degree)
                            model_string = '%s_%s_degree%d_%s' % (model, likelihood, degree, learn_options_str)
                            results[model_string] = pd.cross_validate(Y, feature_sets, learn_options=learn_options_model,TEST=test, CV=CV)

                else:
                    raise NotImplementedError("model %s not supported" % model)

                # "GP" already calls pd.cross_validate() and has its own model_string, so skip this.
                if model != "GP":
                    model_string = model + '_%s' % learn_options_str
                    results[model_string] = pd.cross_validate(Y, feature_sets, learn_options=learn_options_model, TEST=test, CV=CV)

            all_learn_options[model_string] = learn_options_model

    return results, all_learn_options

def pickle_runner_results(exp_name, results, all_learn_options, relpath="/../" + "results"):
    abspath = os.path.abspath(__file__)
    dname = os.path.dirname(abspath) + relpath
    if not os.path.exists(dname):
        os.makedirs(dname)
        print "Created directory: %s" % str(dname)
    if exp_name is None:
        exp_name = results.keys()[0]
    myfile = dname+'/'+ exp_name + '.pickle'
    with open(myfile, 'wb') as f:
        print "writing results to %s" % myfile
        pickle.dump((results, all_learn_options), f, -1)

def runner(models, learn_options, GP_likelihoods=None, orders=None, WD_kernel_degrees=None, where='local', cluster_user='fusi', cluster='RR1-N13-09-H44', test=False, exp_name = None, **kwargs):

    if where == 'local':
        results, all_learn_options = run_models(models, orders=orders, GP_likelihoods=GP_likelihoods, learn_options_set=learn_options, WD_kernel_degrees=WD_kernel_degrees, test=test, **kwargs)
        all_metrics, gene_names = util.get_all_metrics(results, learn_options)
        util.plot_all_metrics(all_metrics, gene_names, all_learn_options, save=True)

        # for non-local (i.e. cluster), the comparable code is in cli_run_model.py
        pickle_runner_results(exp_name, results, all_learn_options)

        return results, all_learn_options, all_metrics, gene_names

    elif where == 'cluster':
        import cluster_job

        # create random cluster directory, dump learn options, and create cluster file
        tempdir, user, clust_filename = cluster_job.create(cluster_user, models, orders, WD_kernel_degrees, GP_likelihoods, exp_name=exp_name, learn_options=learn_options, **kwargs)

        # raw_input("Submit job to HPC and press any key when it's finished: ")
        # util.plot_cluster_results(directory=tempdir)

        #stdout = tempdir + r"/stdout"
        #stderr = tempdir + r"/stderr"
        #if not os.path.exists(stdout): os.makedirs(stdout)
        #if not os.path.exists(stderr): os.makedirs(stderr)

        return tempdir, clust_filename, user#, stdout, stderr

def save_final_model_V3(filename=None, include_position=True, learn_options=None, short_name='final', pam_audit=True, length_audit=True):
    '''
    run_models(produce_final_model=True) is what saves the model
    '''
    test = False
    assert filename is not None, "need to provide filename to save final model"

    if learn_options is None:
        if include_position:
            learn_options = {"V": 3,
                        'train_genes': load_data.get_V3_genes(),
                        'test_genes': load_data.get_V3_genes(),
                        "testing_non_binary_target_name": 'ranks',
                        'include_pi_nuc_feat': True,
                        "gc_features": True,
                        "pam_features": True,
                        "repeat_features": None,
                        "nuc_features": True,
                        "include_gene_position": True,
                        "include_NGGX_interaction": True,
                        "include_NGGXX_interaction": None,
                        "include_Tm": True,
                        "include_strand": False,
                        "include_gene_feature": False,
                        "include_gene_guide_feature": 0,
                        "extra pairs": False,
                        "weighted": None,
                        "training_metric": 'spearmanr',
                        "NDGC_k": 10,
                        "cv": "gene",
                        "include_gene_effect": False,
                        "include_drug": False,
                        "include_sgRNAscore": False,
                        'adaboost_loss' : 'ls', # main "ls", alternatives: "lad", "huber", "quantile", see scikit docs for details
                        'adaboost_alpha': 0.5, # this parameter is only used by the huber and quantile loss functions.
                        'normalize_features': False,
                        'adaboost_CV' : False
                        }
        else:
            learn_options = {"V": 3,
                'train_genes': load_data.get_V3_genes(),
                'test_genes': load_data.get_V3_genes(),
                "testing_non_binary_target_name": 'ranks',
                'include_pi_nuc_feat': True,
                "gc_features": True,
                "pam_features": True,
                "repeat_features": None,
                "nuc_features": True,
                "include_gene_position": False,
                "include_NGGX_interaction": True,
                "include_NGGXX_interaction": None,
                "include_Tm": True,
                "include_strand": False,
                "include_gene_feature": False,
                "include_gene_guide_feature": 0,
                "extra pairs": False,
                "weighted": None,
                "training_metric": 'spearmanr',
                "NDGC_k": 10,
                "cv": "gene",
                "include_gene_effect": False,
                "include_drug": False,
                "include_sgRNAscore": False,
                'adaboost_loss' : 'ls', # main "ls", alternatives: "lad", "huber", "quantile", see scikit docs for details
                'adaboost_alpha': 0.5, # this parameter is only used by the huber and quantile loss functions.
                'normalize_features': False,
                 'adaboost_CV' : False
                }

    learn_options_set = {short_name: learn_options}
    results, all_learn_options = run_models(["AdaBoost"], orders=[2], adaboost_learning_rates=[0.1],
                                            adaboost_max_depths=[3], adaboost_num_estimators=[100],
                                            learn_options_set=learn_options_set,
                                            test=test, CV=False, pam_audit=length_audit, length_audit=length_audit)
    model = results.values()[0][3][0]

    with open(filename, 'wb') as f:
        pickle.dump((model, learn_options), f, -1)

    return model

def predict(seq, aa_cut=-1, percent_peptide=-1, model=None, model_file=None, pam_audit=True, length_audit=False, learn_options_override=None):
    """
    if pam_audit==False, then it will not check for GG in the expected position
    this is useful if predicting on PAM mismatches, such as with off-target
    """
    print "predict function running"
    # assert not (model is None and model_file is None), "you have to specify either a model or a model_file"
    assert isinstance(seq, (np.ndarray)), "Please ensure seq is a numpy array"
    assert len(seq[0]) > 0, "Make sure that seq is not empty"
    assert isinstance(seq[0], str), "Please ensure input sequences are in string format, i.e. 'AGAG' rather than ['A' 'G' 'A' 'G'] or alternate representations"

    if aa_cut is not None:
        assert len(aa_cut) > 0, "Make sure that aa_cut is not empty"
        assert isinstance(aa_cut, (np.ndarray)), "Please ensure aa_cut is a numpy array"
        assert np.all(np.isreal(aa_cut)), "amino-acid cut position needs to be a real number"

    if percent_peptide is not None:
        assert len(percent_peptide) > 0, "Make sure that percent_peptide is not empty"
        assert isinstance(percent_peptide, (np.ndarray)), "Please ensure percent_peptide is a numpy array"
        assert np.all(np.isreal(percent_peptide)), "percent_peptide needs to be a real number"

    if model_file is None:
        azimuth_saved_model_dir = os.path.join(os.path.dirname(__file__), 'saved_models')
        if np.any(percent_peptide == -1) or (percent_peptide is None and aa_cut is None):
            print("No model file specified, using V3_model_nopos")
            model_name = 'V3_model_nopos.pickle'
        else:
            print("No model file specified, using V3_model_full")
            model_name = 'V3_model_full.pickle'

        model_file = os.path.join(azimuth_saved_model_dir, model_name)

    if model is None:
        with open(model_file, 'rb') as f:
            model, learn_options = pickle.load(f)
        print model_file
        print learn_options
    else:
        model, learn_options = model

    learn_options["V"] = 2

    learn_options = override_learn_options(learn_options_override, learn_options)

    # Y, feature_sets, target_genes, learn_options, num_proc = setup(test=False, order=2, learn_options=learn_options, data_file=test_filename)
    # inputs, dim, dimsum, feature_names = pd.concatenate_feature_sets(feature_sets)

    Xdf = pandas.DataFrame(columns=[u'30mer', u'Strand'], data=zip(seq, ['NA' for x in range(len(seq))]))

    if np.all(percent_peptide != -1) and (percent_peptide is not None and aa_cut is not None):
        gene_position = pandas.DataFrame(columns=[u'Percent Peptide', u'Amino Acid Cut position'], data=zip(percent_peptide, aa_cut))
    else:
        gene_position = pandas.DataFrame(columns=[u'Percent Peptide', u'Amino Acid Cut position'], data=zip(np.ones(seq.shape[0])*-1, np.ones(seq.shape[0])*-1))

    feature_sets = feat.featurize_data(Xdf, learn_options, pandas.DataFrame(), gene_position, pam_audit=pam_audit, length_audit=length_audit)
    inputs, dim, dimsum, feature_names = util.concatenate_feature_sets(feature_sets)

    # call to scikit-learn, returns a vector of predicted values
    preds = model.predict(inputs)

    # also check that predictions are not 0/1 from a classifier.predict() (instead of predict_proba() or decision_function())
    unique_preds = np.unique(preds)
    ok = False
    for pr in preds:
        if pr not in [0,1]:
            ok = True
    assert ok, "model returned only 0s and 1s"
    return preds

def override_learn_options(learn_options_override, learn_options):
    """
    override all keys seen in learn_options_override to alter learn_options
    """
    if learn_options_override is not None:
        for k in learn_options_override.keys():
            learn_options[k] = learn_options_override[k]
    return learn_options

def fill_learn_options(learn_options_fill, learn_options):
    """
    only fill in keys that are missing form learn_options from learn_options_fill
    """
    if learn_options_fill is not None:
        for k in learn_options_fill.keys():
            if not learn_options.has_key(k):
                learn_options[k] = learn_options_fill[k]
    return learn_options

def write_results(predictions, file_to_predict):
    newfile = file_to_predict.replace(".csv", ".pred.csv")
    data = pandas.read_csv(file_to_predict)
    data['predictions'] = predictions
    data.to_csv(newfile)
    print "wrote results to %s" % newfile
    return data, newfile

if __name__ == '__main__':
    #save_final_model_V3(filename='azimuth/azure_models/V3_model_full.pickle', include_position=True)

    save_final_model_V3(filename='saved_models/model_8_nopos.pickle', include_position=False)
    save_final_model_V3(filename='saved_models/model_8.pickle', include_position=True)

    # predict('GGGCCGCTGTTGCAGGTGGCGGGTAGGATC', 'sense', 1200, 30.3, model_file='../saved_models/final_model_nicolo.pickle')

    learn_options = {"V": 3,
                "train_genes": load_data.get_V3_genes(),
                "test_genes": load_data.get_V3_genes(),
                "target_name": 'score_drug_gene_rank',
                "testing_non_binary_target_name": 'ranks',
                'include_pi_nuc_feat': True,
                "gc_features": True,
                "pam_features": True,
                "repeat_features": True,
                "nuc_features": True,
                "include_gene_position": True,
                "include_NGGX_interaction": None,
                "include_NGGXX_interaction": True,
                "include_Tm": True,
                "include_strand": False,
                "include_gene_feature": False,
                "include_gene_guide_feature": 0,
                "extra pairs": False,
                "weighted": None,
                "training_metric": 'spearmanr',
                "NDGC_k": 10,
                "cv": "gene",
                "adaboost_loss" : 'ls',
                "include_gene_effect": False,
                "include_drug": False,
                "include_sgRNAscore": False,
                'adaboost_loss' : 'ls', # main "ls", alternatives: "lad", "huber", "quantile", see scikit docs for details
                'adaboost_alpha': 0.5, # this parameter is only used by the huber and quantile loss functions.
                'adaboost_CV' : False
                }

    learn_options_set = {"post bug fix":learn_options}

    #runner(['AdaBoost'], learn_options_set, orders=[2], where='local', adaboost_learning_rates=[0.1],  adaboost_max_depths=[3], adaboost_num_estimators=[100], exp_name='post-index-fix')
# #util.feature_importances(results)


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

# Saving and Loading
# ============================
#
# Setup
# -----------------------------

# Let's first make sure we have the latest version of PHOEBE 2.1 installed. (You can comment out this line if you don't use pip for your installation or don't want to update to the latest release).

# In[ ]:

get_ipython().system('pip install -I "phoebe>=2.1,<2.2"')

# As always, let's do imports and initialize a logger and a new bundle.  See [Building a System](building_a_system.ipynb) for more details.

# In[1]:

import phoebe
from phoebe import u # units
import numpy as np
import matplotlib.pyplot as plt

logger = phoebe.logger(clevel='INFO')

b = phoebe.default_binary()

# Saving a Bundle
# -----------------------
#
#

# In[2]:

b['incl@orbit'] = 56.789

# To save the Bundle to a file, we can call the [save](../api/phoebe.parameters.ParameterSet.save.md) method of the Bundle and pass a filename.

# In[3]:

print b.save('test.phoebe')

# We can now inspect the contents of the created file.
#
# This file is in the JSON-format and is simply a list of dictionaries - where each dictionary represents the attributes of a single Parameter.
#
# You could edit this file in a text-editor - but do be careful if changing any of the tags.  For example: if you want to change the component tag of one of your stars, make sure to change ALL instances of the component tag to match (as well as the hierarchy Parameter).

# In[4]:

get_ipython().system('head -n 30 test.phoebe')

# Loading a Bundle
# ----------------------

# To open an existing Bundle from the file we just created, call [Bundle.open](../api/phoebe.frontend.bundle.Bundle.open.md) and pass the filename.

# In[5]:

b2 = phoebe.Bundle.open('test.phoebe')

# Just to prove this worked, we can check to make sure we retained the changed value of inclination.

# In[6]:

print b2.get_value('incl@orbit')

# Support for Other Codes
# ------------------------------
#
# ### Legacy
#
# Importing from a PHOEBE Legacy file is as simple as passing the filename to [from_legacy](../api/phoebe.frontend.bundle.Bundle.from_legacy.md):

# In[7]:

b = phoebe.Bundle.from_legacy('legacy.phoebe')

# Exporting to a PHOEBE Legacy file is also possible (although note that some parameters don't translate exactly or are not supported in PHOEBE Legacy), via [b.export_legacy](../api/phoebe.frontend.bundle.Bundle.export_legacy.md).

# In[8]:

b.export_legacy('legacy_export.phoebe')

# For the parameters that could not be directly translated, you should see a warning message (if you have warning messages enabled in your logger).
#
# We can now look at the beginning of the saved file and see that it matches the PHOEBE Legacy file-format.

# In[9]:

get_ipython().system('head -n 30 legacy_export.phoebe')

# Next
# ---------
#
# Next up: let's learn all about [constraints](constraints.ipynb)


#!/usr/bin/env python
"""
=====================
Lasso path using LARS
=====================

Computes Lasso Path along the regularization parameter using the LARS
algorithm on the diabetes dataset. Each color represents a different
feature of the coefficient vector, and this is displayed as a function
of the regularization parameter.

"""
print(__doc__)

# Author: Fabian Pedregosa <fabian.pedregosa@inria.fr>
#         Alexandre Gramfort <alexandre.gramfort@inria.fr>
# License: BSD 3 clause

import numpy as np
import matplotlib.pyplot as plt

from sklearn import linear_model
from sklearn import datasets

diabetes = datasets.load_diabetes()
X = diabetes.data
y = diabetes.target

print("Computing regularization path using the LARS ...")
alphas, _, coefs = linear_model.lars_path(X, y, method='lasso', verbose=True)

xx = np.sum(np.abs(coefs.T), axis=1)
xx /= xx[-1]

plt.plot(xx, coefs.T)
ymin, ymax = plt.ylim()
plt.vlines(xx, ymin, ymax, linestyle='dashed')
plt.xlabel('|coef| / max|coef|')
plt.ylabel('Coefficients')
plt.title('LASSO Path')
plt.axis('tight')
plt.show()