import pickle
import sys
import psutil

import torch
import numpy as np

import index

from pympler import muppy, summary
import gc

def print_mem():
    all_objects = muppy.get_objects()
    sum1 = summary.summarize(all_objects)
    summary.print_(sum1)
    print(psutil.Process().memory_full_info().rss / 1e9)

prefix = index.get_index_prefix(
    index_base_path = "../index",
    full_model_path = "models/en_multibert_empty_l2_dev=94.94.pt",
    nn_prefix = "nl2-multi",
)
span_index = index.FaissIndex(num_labels = 112, metric="l2")
span_index.load(prefix)

shape = span_index.keys.shape

print("initialized index")
print_mem()
span_index.to(1)
print("to gpu")
print_mem()

span_index.reset()
print("reset index")
print_mem()

print("collecting garbage")
gc.collect()
print_mem()

new_keys = np.random.randn(*shape)
print("made new keys")
print_mem()

import pdb; pdb.set_trace()


import os
from pyBedGraph import BedGraph
import numpy as np

PEAK_DATA_DIR = '/media/hirwo/extra/jax/data/chia_pet/peaks'
LOOP_DATA_DIR = '/media/hirwo/extra/jax/data/chia_pet/loops'
BEDGRAPH_DIR = '/media/hirwo/extra/jax/data/chia_pet/bedgraphs'

MY_PEAK_DATA_DIR = '/media/hirwo/extra/jax/data/chia_pet/my_full_peaks'
MY_LOOP_DATA_DIR = '/media/hirwo/extra/jax/data/chia_pet/my_loops'

HUMAN_CHROM_SIZE_FILE = \
    '/media/hirwo/extra/jax/data/chia_pet/chrom_sizes/hg38.chrom.sizes'
MOUSE_CHROM_SIZE_FILE = \
    '/media/hirwo/extra/jax/data/chia_pet/chrom_sizes/mm10.chrom.sizes'

hg_sample_names = []
mm_sample_names = []

def get_file_path(sample_name, data_dir):
    for file_name in os.listdir(data_dir):
        if sample_name in file_name:
            return os.path.join(data_dir, file_name)

def read_peak_file(peak_file_path, is_narrow):
    peak_dict = {}
    max_value = -1
    with open(peak_file_path) as peak_file:
        for line in peak_file:
            line = line.split()
            chrom_name = line[0]

            try:
                peak_start = int(line[1])
                peak_end = int(line[2])
                if is_narrow:  # peak value is q-value
                    peak_value = float(line[8])
                else:
                    peak_value = float(line[6])
            except ValueError:
                print(line)
                continue

            if chrom_name not in peak_dict:
                peak_dict[chrom_name] = {
                    'start_list': [],
                    'end_list': [],
                    'value_list': []
                }
            if peak_start > max_value:
                max_value = peak_start
            if peak_end > max_value:
                max_value = peak_end

            peak_dict[chrom_name]['start_list'].append(peak_start)
            peak_dict[chrom_name]['end_list'].append(peak_end)
            peak_dict[chrom_name]['value_list'].append(peak_value)

    return peak_dict

def read_bedgraph(sample_name, chrom_file):
    bedgraph_file_path = get_file_path(sample_name, BEDGRAPH_DIR)

    if bedgraph_file_path is None:
        print(f"No bedgraph file for {sample_name}")
        return None

    print(f"Reading in {bedgraph_file_path}")
    # return BedGraph(chrom_file, bedgraph_file_path, ignore_missing_bp=False, chrom_wanted='chr1')
    return BedGraph(chrom_file, bedgraph_file_path, ignore_missing_bp=False)

def main():
    with open('/media/hirwo/extra/jax/data/chia_pet/hg_libraries.txt') as f:
        for line in f:
            hg_sample_names.append(line.strip())

    with open('/media/hirwo/extra/jax/data/chia_pet/mm_libraries.txt') as f:
        for line in f:
            mm_sample_names.append(line.strip())

    for peak_file_name in os.listdir(PEAK_DATA_DIR):
        if 'peak' not in peak_file_name.lower():
            continue

        is_narrow = False
        if 'narrowpeak' in peak_file_name.lower():
            is_narrow = True

        sample_name = peak_file_name.split('.')[0]

        if os.path.isfile(f'{MY_PEAK_DATA_DIR}/{sample_name}.mypeak'):
            continue

        loop_file_path = LOOP_DATA_DIR + f'/{sample_name}.e500.clusters.cis.BE3'

        chrom_file = None
        if sample_name in hg_sample_names:
            chrom_file = HUMAN_CHROM_SIZE_FILE
        if sample_name in mm_sample_names:
            if chrom_file:
                print(sample_name)
                print("ERROR")
            chrom_file = MOUSE_CHROM_SIZE_FILE

        if not chrom_file:
            print(f"{sample_name} is not a mouse or a human. Skipping")
            continue

        print(f"Finding peaks for {sample_name}")
        peak_file_path = os.path.join(PEAK_DATA_DIR, peak_file_name)
        peak_dict = read_peak_file(peak_file_path, is_narrow)

        b = read_bedgraph(sample_name, chrom_file)
        if b is None:
            continue

        temp_array = np.zeros(1000000, dtype=np.int8)
        for chrom_name, peaks in peak_dict.items():
            '''if chrom_name != 'chr1':
                peaks['max_values'] = temp_array
                peaks['mean_values'] = temp_array
                continue'''
            b.load_chrom_data(chrom_name)
            try:
                peaks['max_values'] = b.stats(start_list=peaks['start_list'],
                                              end_list=peaks['end_list'],
                                              stat='max', chrom_name=chrom_name)

                peaks['mean_values'] = b.stats(start_list=peaks['start_list'],
                                               end_list=peaks['end_list'],
                                               stat='mean', chrom_name=chrom_name)
            except IndexError:
                max_value = -1
                print(chrom_name)
                for i in range(len(peaks['start_list'])):
                    assert peaks['start_list'][i] < peaks['end_list'][i]

                    if peaks['end_list'][i] > max_value:
                        max_value = peaks['end_list'][i]
                print(max_value)
            b.free_chrom_data(chrom_name)

        with open(f'{MY_PEAK_DATA_DIR}/{sample_name}.mypeak', 'w+') as out_file:
            for chrom_name, peaks in peak_dict.items():
                for i in range(len(peaks['end_list'])):
                    out_file.write(f'{chrom_name}\t{peaks["start_list"][i]}\t'
                                   f'{peaks["end_list"][i]}\t'
                                   f'{peaks["value_list"][i]}\t'
                                   f'{peaks["max_values"][i]}\t'
                                   f'{peaks["mean_values"][i]}\n')

if __name__ == "__main__":
    main()


import argparse
import asyncio
import logging
import math

import cv2
import numpy
from av import VideoFrame

from aiortc import (
    RTCIceCandidate,
    RTCPeerConnection,
    RTCSessionDescription,
    VideoStreamTrack,
)
from aiortc.contrib.media import MediaBlackhole, MediaPlayer, MediaRecorder
from aiortc.contrib.signaling import BYE, add_signaling_arguments, create_signaling

class FlagVideoStreamTrack(VideoStreamTrack):
    """
    A video track that returns an animated flag.
    """

    def __init__(self):
        super().__init__()  # don't forget this!
        self.counter = 0
        height, width = 480, 640

        # generate flag
        data_bgr = numpy.hstack(
            [
                self._create_rectangle(
                    width=213, height=480, color=(255, 0, 0)
                ),  # blue
                self._create_rectangle(
                    width=214, height=480, color=(255, 255, 255)
                ),  # white
                self._create_rectangle(width=213, height=480, color=(0, 0, 255)),  # red
            ]
        )

        # shrink and center it
        M = numpy.float32([[0.5, 0, width / 4], [0, 0.5, height / 4]])
        data_bgr = cv2.warpAffine(data_bgr, M, (width, height))

        # compute animation
        omega = 2 * math.pi / height
        id_x = numpy.tile(numpy.array(range(width), dtype=numpy.float32), (height, 1))
        id_y = numpy.tile(
            numpy.array(range(height), dtype=numpy.float32), (width, 1)
        ).transpose()

        self.frames = []
        for k in range(30):
            phase = 2 * k * math.pi / 30
            map_x = id_x + 10 * numpy.cos(omega * id_x + phase)
            map_y = id_y + 10 * numpy.sin(omega * id_x + phase)
            self.frames.append(
                VideoFrame.from_ndarray(
                    cv2.remap(data_bgr, map_x, map_y, cv2.INTER_LINEAR), format="bgr24"
                )
            )

    async def recv(self):
        pts, time_base = await self.next_timestamp()

        frame = self.frames[self.counter % 30]
        frame.pts = pts
        frame.time_base = time_base
        self.counter += 1
        return frame

    def _create_rectangle(self, width, height, color):
        data_bgr = numpy.zeros((height, width, 3), numpy.uint8)
        data_bgr[:, :] = color
        return data_bgr

async def run(pc, player, recorder, signaling, role):
    def add_tracks():
        if player and player.audio:
            pc.addTrack(player.audio)

        if player and player.video:
            pc.addTrack(player.video)
        else:
            pc.addTrack(FlagVideoStreamTrack())

    @pc.on("track")
    def on_track(track):
        print("Receiving %s" % track.kind)
        recorder.addTrack(track)

    # connect signaling
    await signaling.connect()

    if role == "offer":
        # send offer
        add_tracks()
        await pc.setLocalDescription(await pc.createOffer())
        await signaling.send(pc.localDescription)

    # consume signaling
    while True:
        obj = await signaling.receive()

        if isinstance(obj, RTCSessionDescription):
            await pc.setRemoteDescription(obj)
            await recorder.start()

            if obj.type == "offer":
                # send answer
                add_tracks()
                await pc.setLocalDescription(await pc.createAnswer())
                await signaling.send(pc.localDescription)
        elif isinstance(obj, RTCIceCandidate):
            await pc.addIceCandidate(obj)
        elif obj is BYE:
            print("Exiting")
            break

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Video stream from the command line")
    parser.add_argument("role", choices=["offer", "answer"])
    parser.add_argument("--play-from", help="Read the media from a file and sent it."),
    parser.add_argument("--record-to", help="Write received media to a file."),
    parser.add_argument("--verbose", "-v", action="count")
    add_signaling_arguments(parser)
    args = parser.parse_args()

    if args.verbose:
        logging.basicConfig(level=logging.DEBUG)

    # create signaling and peer connection
    signaling = create_signaling(args)
    pc = RTCPeerConnection()

    # create media source
    if args.play_from:
        player = MediaPlayer(args.play_from)
    else:
        player = None

    # create media sink
    if args.record_to:
        recorder = MediaRecorder(args.record_to)
    else:
        recorder = MediaBlackhole()

    # run event loop
    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(
            run(
                pc=pc,
                player=player,
                recorder=recorder,
                signaling=signaling,
                role=args.role,
            )
        )
    except KeyboardInterrupt:
        pass
    finally:
        # cleanup
        loop.run_until_complete(recorder.stop())
        loop.run_until_complete(signaling.close())
        loop.run_until_complete(pc.close())


import numpy as np
import random
import copy
from collections import namedtuple, deque

from actor_critic_DNN import Actor, Critic

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

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

class OUNoise:
    """Ornstein-Uhlenbeck process."""

    def __init__(self, size, seed, mu=0., theta=0.15, sigma=0.05):
        """
        Initialize parameters and noise process.
        """
        self.mu = mu * np.ones(size)
        self.theta = theta
        self.sigma = sigma
        random.seed(seed)
        self.reset()

    def reset(self):
        """Reset the internal state (= noise) to mean (mu)."""
        self.state = copy.copy(self.mu)

    def sample(self):
        """Update internal state and return it as a noise sample."""
        x = self.state
        dx = self.theta * (self.mu - x) + self.sigma * np.array([random.random() for i in range(len(x))])
        self.state = x + dx
        return self.state

class ReplayBuffer:
    """
    Fixed-size Buffer for the experience tuples
    """

    def __init__(self, buffer_size, batch_size, seed):
        """Initialize a ReplayBuffer object.
        Params
        ======
            buffer_size (int): maximum size of buffer
            batch_size (int): size of each training batch
            random_seed (int): random seed
        """

        self.rb = deque(maxlen=buffer_size)  # internal memory (deque)
        self.batch_size = batch_size
        self.experience = namedtuple("Experience", field_names=["state", "action", "reward", "next_state", "done"])
        random.seed(seed)

    def add(self,state,action,reward,next_state,done):
        """Add a new experience tuple to the ring buffer"""
        single_expi = self.experience(state,action,reward,next_state,done)
        self.rb.append(single_expi)

    def sample(self):
        """Randomly sample a batch of experiences from memory."""
        experiences = random.sample(self.rb, k=self.batch_size)

        states = torch.from_numpy(np.vstack([e.state for e in experiences if e is not None])).float().to(device)
        actions = torch.from_numpy(np.vstack([e.action for e in experiences if e is not None])).float().to(device)
        rewards = torch.from_numpy(np.vstack([e.reward for e in experiences if e is not None])).float().to(device)
        next_states = torch.from_numpy(np.vstack([e.next_state for e in experiences if e is not None])).float().to(device)
        dones = torch.from_numpy(np.vstack([e.done for e in experiences if e is not None]).astype(np.uint8)).float().to(device)
        #torch_done = torch.from_numpy(np.vstack([1 if e.done == True else 0 for e in experience if e is not None])).float().to(device)

        return (states, actions, rewards, next_states, dones)

    def __len__(self):
        """Return the current size of internal memory."""
        return len(self.rb)

class Agent():
    """
    The Agent interacts with the environment and learns from the interactions and the environment
    """
    def __init__(self, state_size, action_size, buffer_size, batch_size, gamma, tau, lr_actor, lr_critic, \
        weight_decay, epsilon_decay, update_every, update_times, random_seed = 23, epsilon = 1.0):
        """
        Parameters
        ==========
            state_size (in): dimension of each state
            action_size (int): dimension of each action
            random_seed (int): random seed
            epsilon (int): start value of epsilon, default 1.0
            buffer_size (int): size of the memorybuffer
            batch_size (int): size of the batch
            gamma (float): discounted value, must be between 0 and 1
            tau (float): blend parameter for the soft update, has to be between 0 and 1
            lr_actor (float): learning rate for the actor dnn
            lr_critic (float): learning rate for the critic dnn
            weight_decay (float): L2 penalty
            epsilon_decay (float): factor to reduce epsilon frequently
            update_every (int): update frequence
            update_times (int): how many times the weights should be updated at one update step

        """
        self.state_size = state_size
        self.action_size = action_size
        self.seed = random.seed(random_seed)
        self.random_seed = random_seed
        self.epsilon = epsilon
        self.buffer_size = buffer_size
        self.batch_size = batch_size
        self.gamma = gamma
        self.tau = tau
        self.lr_actor = lr_actor
        self.lr_critic = lr_critic
        self.weight_decay = weight_decay
        self.epsilon_decay = epsilon_decay
        self.update_every = update_every
        self.update_times = update_times

        self.update_every_x = 0

        # The Actor
        ###########
        self.actor_local  = Actor(self.state_size, self.action_size, self.random_seed).to(device)
        self.actor_target = Actor(self.state_size, self.action_size, self.random_seed).to(device)
        self.actor_optimizer = optim.Adam(self.actor_local.parameters(), lr = self.lr_actor)

        # The Critic
        ############
        self.critic_local = Critic(self.state_size, self.action_size, self.random_seed).to(device)
        self.critic_target = Critic(self.state_size, self.action_size, self.random_seed).to(device)
        self.critic_optimizer = optim.Adam(self.critic_local.parameters(), lr = self.lr_critic, weight_decay = self.weight_decay)

        # for target_param, param in zip(self.actor_target.parameters(), self.actor_local.parameters()):
        #     target_param.data.copy_(param.data)
        # for target_param, param in zip(self.critic_target.parameters(), self.critic_local.parameters()):
        #     target_param.data.copy_(param.data)

        # The Replay Buffer
        ###################
        self.RepMem = ReplayBuffer(self.buffer_size, self.batch_size, self.random_seed)

        # The "Ornstein-Uhlenbeck-Noise"
        ################################
        self.noise = OUNoise(self.action_size, self.random_seed)

    def step(self, state, action, reward, next_state, done):
        """
        add info to the ringbuffer, if enough entries are available --> learn
        """
        self.RepMem.add(state, action, reward, next_state, done)
        #print("Length buffer: " + str(len(self.RepMem)))
        self.update_every_x = (self.update_every_x+1) % self.update_every
        if self.update_every_x == 0:
            # start learning when buffer is half-full
            if len(self.RepMem) > int(self.buffer_size/2):
                for _ in range(int(self.update_times)):
                    sample_batch = self.RepMem.sample()
                    #print (sample_batch)
                    #print("----------")
                    self.learn(sample_batch)
                    #print ("Learned")
                    #print ("++++++++++")

    def act(self, state, add_noise = True):
        """
        choose an action due to the given state and policy
        Parameters:
        ===========
        state: the current state
        add_noise (bool): True: adds a noise for exploration

        return: the estimate action
        """
        ### adapt state and send it to device
        state = torch.from_numpy(state).float().to(device)
        self.actor_local.eval()
        with torch.no_grad():
            action = self.actor_local(state).cpu().data.numpy()
        self.actor_local.train()
        if add_noise:
            noise_ = self.noise.sample()
            #print (action)
            action += self.epsilon * noise_
            #print (action)
            #print ("------------------------------------------")
        ### be shure that with the noise the action is still between -1 and 1
        return np.clip(action, -1.0, 1.0)

    def get_epsilon(self):
        """
        getter function: used to monitor epsilon
        """
        return self.epsilon

    def learn(self, experiences):
        """
        update the DNNs
        Parameters:
        ==========
        experiences: batch sample
        """
        states, actions, rewards, next_states, dones = experiences

        # ---------------------------- update critic ---------------------------- #
        # Get predicted next-state actions and Q values from target models
        actions_next = self.actor_target(next_states)
        Q_targets_next = self.critic_target(next_states, actions_next)
        # Compute Q targets for current states (y_i)
        Q_targets = rewards + (self.gamma * Q_targets_next * (1 - dones))
        # Compute critic loss
        Q_expected = self.critic_local(states, actions)
        critic_loss = F.mse_loss(Q_expected, Q_targets)
        # Minimize the loss
        self.critic_optimizer.zero_grad()
        critic_loss.backward()
        self.critic_optimizer.step()

        # ---------------------------- update actor ---------------------------- #
        # Compute actor loss
        actions_pred = self.actor_local(states)
        actor_loss = -self.critic_local(states, actions_pred).mean()
        # Minimize the loss
        self.actor_optimizer.zero_grad()
        actor_loss.backward()
        self.actor_optimizer.step()

        # ----------------------- update target networks ----------------------- #
        self.soft_update(self.critic_local, self.critic_target, self.tau)
        self.soft_update(self.actor_local, self.actor_target, self.tau)

        self.epsilon = max(0.001, self.epsilon * self.epsilon_decay)
        self.noise.reset()

    def soft_update(self, local_model, target_model, tau):
        """
        θ_target = τ*θ_local + (1 - τ)*θ_target
        Parameters
        ==========
        local_model (Actor or Critic object): from that model the parameters are used
        target_model (Actor or Critic object): to that model the parameters are updated
        tau (float): blend parameter, has to be between 0 and 1
        """
        for target_param, local_param in zip(target_model.parameters(), local_model.parameters()):
            target_param.data.copy_(tau*local_param.data + (1.0-tau)*target_param.data)

    def reset(self):
        self.noise.reset()

if __name__ == "__main__":
    test = Agent(3,4,5)
    test.reset()


"""
This helps control motors in pybullet physics simulator.
https://github.com/Einsbon
https://blog.naver.com/einsbon
"""

import numpy as np
import time
from time import sleep
import pybullet as p

class MotorController:
    def __init__(self, robot, physicsClientId, timeStep, kp, kd, torque, max_velocity):
        self._robot = robot
        self._physicsClientId = physicsClientId
        jointNameToId = {}
        joint_id_list = []
        joint_pos_list = []
        self._joint_number = 0
        for i in range(p.getNumJoints(self._robot, physicsClientId=self._physicsClientId)):
            jointInfo = p.getJointInfo(self._robot, i, physicsClientId=self._physicsClientId)
            if jointInfo[2] == 0:
                joint_id_list.append(jointInfo[0])
                joint_pos_list.append(p.getJointState(
                    self._robot, jointInfo[0], physicsClientId=self._physicsClientId)[0])
                jointNameToId[jointInfo[1].decode('UTF-8')] = jointInfo[0]
                self._joint_number += 1
        self._joint_id = np.array(joint_id_list, dtype=np.int32)
        self._joint_targetPos = np.array(joint_pos_list, dtype=np.float)
        self._joint_currentPos = np.array(joint_pos_list, dtype=np.float)

        self._jointNameToId = jointNameToId
        self._kp = kp
        self._kd = kd
        self._torque = torque
        self._max_velocity = max_velocity
        self._timeStep = timeStep
        # print(self._joint_id)
        # print(self._joint_targetPos)
        # print(self._jointNameToId)

    def setRobot(self, robot, physicsClientId=None):
        self._robot = robot
        if physicsClientId != None:
            self._physicsClientId = physicsClientId

        joint_id_list = []
        joint_pos_list = []
        self._joint_number = 0
        for i in range(p.getNumJoints(robot)):
            jointInfo = p.getJointInfo(robot, i)
            if jointInfo[2] == 0:
                joint_id_list.append(jointInfo[0])
                joint_pos_list.append(p.getJointState(robot, jointInfo[0])[0])
                self._joint_number += 1
        print(self._joint_number)
        self._joint_id = np.array(joint_id_list, dtype=np.int32)
        self._joint_targetPos = np.array(joint_pos_list, dtype=np.float)
        self._joint_currentPos = np.array(joint_pos_list, dtype=np.float)

    def setMotorParameters(self, kp=None, kd=None, torque=None, maxVelocity=None, timeStep=None):
        if kp != None:
            self._kp = kp
        if kd != None:
            self._kd = kd
        if torque != None:
            self._torque = torque
        if maxVelocity != None:
            self._max_velocity = maxVelocity
        if timeStep != None:
            self._timeStep = timeStep

    def getRevoluteJoint_nameToId(self):
        return self._jointNameToId

    def getMotorAngle(self):
        for i in range(self._joint_number):
            self._joint_currentPos[i] = p.getJointState(
                self._robot, self._joint_id[i], physicsClientId=self._physicsClientId)[0]
        return self._joint_currentPos

    def setMotorAngle(self, motorTargetAngles):
        for i in range(self._joint_number):
            self._joint_targetPos[i] = motorTargetAngles[i]
            p.setJointMotorControl2(bodyIndex=self._robot, jointIndex=self._joint_id[i], controlMode=p.POSITION_CONTROL,
                                    targetPosition=self._joint_targetPos[i],
                                    positionGain=self._kp, velocityGain=self._kd, force=self._torque, maxVelocity=self._max_velocity, physicsClientId=self._physicsClientId)

    def setMotorsAngleInRealTimestep(self, motorTargetAngles, motorTargetTime, delayTime):
        if(motorTargetTime == 0):
            self._joint_targetPos = np.array(motorTargetAngles)
            for i in range(self._joint_number):
                p.setJointMotorControl2(bodyIndex=self._robot, jointIndex=self._joint_id[i], controlMode=p.POSITION_CONTROL,
                                        targetPosition=self._joint_targetPos[i],
                                        positionGain=self._kp, velocityGain=self._kd, force=self._torque, maxVelocity=self._max_velocity, physicsClientId=self._physicsClientId)
            time.sleep(delayTime)
        else:
            self._joint_currentPos = self._joint_targetPos
            self._joint_targetPos = np.array(motorTargetAngles)
            for i in range(self._joint_number):
                dydt = (self._joint_targetPos-self._joint_currentPos)/motorTargetTime
            internalTime = 0.0
            reft = time.time()
            while internalTime < motorTargetTime:
                internalTime = time.time() - reft
                for i in range(self._joint_number):
                    p.setJointMotorControl2(bodyIndex=self._robot, jointIndex=self._joint_id[i], controlMode=p.POSITION_CONTROL,
                                            targetPosition=self._joint_currentPos[i] + dydt[i] * internalTime,
                                            positionGain=self._kp, velocityGain=self._kd, force=self._torque, maxVelocity=self._max_velocity, physicsClientId=self._physicsClientId)

    def setMotorsAngleInFixedTimestep(self, motorTargetAngles, motorTargetTime, delayTime):
        if(motorTargetTime == 0):
            self._joint_targetPos = np.array(motorTargetAngles)
            for i in range(self._joint_number):
                p.setJointMotorControl2(bodyIndex=self._robot, jointIndex=self._joint_id[i], controlMode=p.POSITION_CONTROL,
                                        targetPosition=self._joint_targetPos[i],
                                        positionGain=self._kp, velocityGain=self._kd, force=self._torque, maxVelocity=self._max_velocity, physicsClientId=self._physicsClientId)
                p.stepSimulation(physicsClientId=self._physicsClientId)
                time.sleep(self._timeStep, physicsClientId=self._physicsClientId)
        else:
            self._joint_currentPos = self._joint_targetPos
            self._joint_targetPos = np.array(motorTargetAngles)
            for i in range(self._joint_number):
                dydt = (self._joint_targetPos-self._joint_currentPos)/motorTargetTime
            internalTime = 0.0
            while internalTime < motorTargetTime:
                internalTime += self._timeStep
                for i in range(self._joint_number):
                    p.setJointMotorControl2(bodyIndex=self._robot, jointIndex=self._joint_id[i], controlMode=p.POSITION_CONTROL,
                                            targetPosition=self._joint_currentPos[i] + dydt[i] * internalTime,
                                            positionGain=self._kp, velocityGain=self._kd, force=self._torque, maxVelocity=self._max_velocity, physicsClientId=self._physicsClientId)
                p.stepSimulation(physicsClientId=self._physicsClientId)

            if delayTime != 0:
                for _ in range(int(delayTime/self._timeStep)):
                    p.stepSimulation(physicsClientId=self._physicsClientId)


# -*- coding: utf-8 -*-
"""
Created on Thu Dec  2 13:35:41 2021

@author: Mc Zie
"""

import datetime
import time
import board
import busio
i2c = busio.I2C(board.SCL, board.SDA)
import csv
import adafruit_ads1x15.ads1015 as ADS
#import adafruit_ads1x15.ads1115 as ADS
from w1thermsensor import W1ThermSensor
from adafruit_ads1x15.analog_in import AnalogIn
import RPi.GPIO as GPIO

ds18b20 = W1ThermSensor()

ads = ADS.ADS1015(i2c)
ads.gain = 1

interval = 5 #How long we want to wait between loops (seconds)
waterTick = 0 #Used to count the number of times the flow input is triggered

import pandas as pd
from sklearn.preprocessing import LabelEncoder,OneHotEncoder
from sklearn.model_selection import train_test_split
import pandas as pd
from sklearn import model_selection
import sklearn as read_csv
import numpy as np
from sklearn.metrics import classification_report,accuracy_score,confusion_matrix
from matplotlib import pyplot as plt
from sklearn import svm
from sklearn import metrics
from sklearn.svm import SVC
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import label_binarize
from sklearn.multiclass import OneVsRestClassifier
from scipy import interp
from sklearn.preprocessing import LabelEncoder
from sklearn import preprocessing
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from sklearn.neural_network import MLPClassifier
import numpy as np
from random import shuffle
from operator import itemgetter
import pandas as pd
from sklearn.model_selection import train_test_split
import pandas as pd
from sklearn import model_selection
import sklearn as read_csv
import numpy as np
from sklearn.metrics import classification_report,accuracy_score,confusion_matrix
from matplotlib import pyplot as plt
from sklearn import svm
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import label_binarize
from sklearn.multiclass import OneVsRestClassifier
from scipy import interp
from sklearn.preprocessing import LabelEncoder
from sklearn import preprocessing
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from sklearn.neural_network import MLPClassifier
import numpy as np
from random import shuffle
from operator import itemgetter
from sklearn import preprocessing
from gplearn.genetic import SymbolicRegressor
from sklearn.utils.random import check_random_state
import numpy as np
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import BaggingClassifier
from sklearn.model_selection import cross_val_score, train_test_split
from mlxtend.plotting import plot_learning_curves
from mlxtend.plotting import plot_decision_regions
import itertools
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split, GridSearchCV
import numpy as np
import xgboost as xgb
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from mlxtend.classifier import StackingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV
from matplotlib import pyplot
#We choose 5 cross validation for our machine learning model
n_folds = KFold(n_splits =5,shuffle= False )
from sklearn.model_selection import RandomizedSearchCV
from sklearn.metrics import jaccard_score
from keras.models import Sequential
from keras.layers.core import Dense,Activation
from keras.utils import np_utils
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
import xgboost as xgb
from sklearn.metrics import accuracy_score
from numpy import mean
from numpy import std
from sklearn.model_selection import RepeatedStratifiedKFold # evaluate a given model using cross-validation

# import packages for hyperparameters tuning
from hyperopt import STATUS_OK, Trials, fmin, hp, tpe

import keras
import keras.utils
from keras import utils as np_utils
from tensorflow.keras.utils import to_categorical
from keras.layers import Dropout
# Example of Dropout on the Sonar Dataset: Hidden Layer
from pandas import read_csv
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.wrappers.scikit_learn import KerasClassifier
from keras.constraints import maxnorm
from keras.optimizers import SGD
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
import os
import pickle
import random

slope = 1.48; #slope from linear fit
intercept = -1.56 # intercept from linear fit

ads = ADS.ADS1015(i2c)

chan = AnalogIn(ads, ADS.P0)
#voltage=chan.voltage

while True:
    try:
        voltage = round((chan.voltage),2)
        print( 'voltage:')
        print(f'{chan.voltage} Volt')

        vol_water_cont = ((1.0/chan.voltage)*slope)+intercept #calc of theta_v (vol. water content)
        vol_water_cont= round((vol_water_cont),2)
        print(" V, Theta_v: ")
        print(f'{vol_water_cont} cm^3/cm^3')

        if vol_water_cont>-0.40:
            print('wet')
        else:

            print('dry')

        def get_voltage():

            voltage = round((chan.voltage),2)

            voltage = str(voltage)

            return(voltage)

        def get_humidity():

            humidity = vol_water_cont
            humidity= round((humidity),2)

            humidity = str(humidity)

            return(humidity)

        def date_now():
           today = datetime.datetime.now().strftime("%Y-%m-%d")
           today = str(today)
           return(today)

        def time_now():

            now = datetime.datetime.now().strftime("%H:%M:%S")
            now = str(now)
            return(now)

        def get_humidity_binary():

            if vol_water_cont>-0.40:

                return str('wet')
            else:
                return str('dry')

        def write_to_csv():

            #the a is for append, if w for write is used then it overwrites the file
            with open('/home/pi/sensor_readings.csv', mode='a') as sensor_readings:

                sensor_write = csv.writer(sensor_readings, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
                write_to_log = sensor_write.writerow([date_now(),time_now(),get_voltage(), get_humidity(),get_humidity_binary()])
                return(write_to_log)

        print( write_to_csv())

  ############## ARTIFICIAL INTELLIGENCE APPLY IN SOLEINOID VALVE ############################
        from numpy import loadtxt
        from keras.models import load_model

        # load model Neural network
        model = load_model('model_rwet_dry.h5')

        colnames=['date','time','voltage','humidity','target']

        df1=pd.read_csv('/home/pi/sensor_readings.csv',names=colnames, header=None)

        encoded=df1[['date','time','target']].apply(LabelEncoder().fit_transform)
        remain=df1[['voltage','humidity']]

        # Adding both the dataframes encoded and remaining (without encoding)
        data =pd.concat([remain,encoded], axis=1)

        X=data[['voltage', 'humidity', 'date', 'time']]
        y=data['target']

        result = model.predict(X)

        #Convert result predict in binary
        from sklearn.preprocessing import binarize

        predict = np.ravel(binarize(result.reshape(-1,1), 0.5))

        if predict[0]>0.5:
            print("The soil is wet")
        else:

            print("The soil is dry")
         ### SOLEINOID DATA AND READER ######################################

        ds18b20 = W1ThermSensor()

        ads = ADS.ADS1015(i2c)
        ads.gain = 1

        interval = 1 #How long we want to wait between loops (seconds)
        waterTick = 0 #Used to count the number of times the flow input is triggered

#Assign channels to variables to keep track of them easier (these BCM pin numbers were listed in part 1 of the tutorial)
        s1 = 13
        s2 = 16
        s3 = 19
        s4 = 20
        s5 = 26
        s6 = 21

#Set GPIO pins to use BCM pin numbers
        GPIO.setmode(GPIO.BCM)

#Set digital pin 24 to an input
        GPIO.setup(24, GPIO.IN)

#Set solenoid driver pins to outputs:
        GPIO.setup(s1, GPIO.OUT) #set Solenoid 1 output
        GPIO.setup(s2, GPIO.OUT) #set Solenoid 2 output
        GPIO.setup(s3, GPIO.OUT) #set Solenoid 3 output
        GPIO.setup(s4, GPIO.OUT) #set Solenoid 4 output
        GPIO.setup(s5, GPIO.OUT) #set Solenoid 5 output
        GPIO.setup(s6, GPIO.OUT) #set Solenoid 6 output

#Event to detect flow (1 tick per revolution)
        GPIO.add_event_detect(24, GPIO.FALLING)
        def flowtrig(self):

            global waterTick

            waterTick += 1

        GPIO.add_event_callback(24, flowtrig)

        while True:

            time.sleep(interval)

#Pull Temperature from DS18B20
            #temperature = ds18b20.get_temperature()

#Measure Analog Input 0
        chan = AnalogIn(ads, ADS.P0) #ADS.P1 , P2, P3 for channels 1, 2, 3
            #val = chan.value #Pull the raw ADC data from Channel 0

        waterFlow = waterTick * 2.25
        waterTick = 0

#Test Solenoids by turning each on for a 1 second
        GPIO.output(s1, GPIO.HIGH) #turn solenoid 1 on
        time.sleep(1) #Wait for a half second
        GPIO.output(s1, GPIO.LOW) #turn solenoid 1 off
        time.sleep(1)

        def soleinoi_off_on():

            if predict[0]>0.5:

                return  GPIO.output(s1, GPIO.LOW) #turn solenoid 1 off

                time.sleep(1)
            else:
                return  GPIO.output(s1, GPIO.HIGH) #turn solenoid 1 on

                time.sleep(1)

                print(soleinoi_off_on())

    #if we need to extend the irrigation,
    #we will change the value of time.sleep () for example for one hour,
    #we will have 3600 seconds so time.sleep (3600)
    # the sensor value will read each one hour
    #For industrial we will use temporisator to extend the watering

        def soleinoi_off_on_extension():

            if predict[0]>0.5:

                return  GPIO.output(s1, GPIO.LOW) #turn solenoid 1 off

                time.sleep(3600)
            else:
                return  GPIO.output(s1, GPIO.HIGH) #turn solenoid 1 on

                time.sleep(3600)

                print(soleinoi_off_on_extension())

            """
            GPIO.output(s2, GPIO.HIGH) #turn solenoid 2 on
            time.sleep(0.5) #Wait for a half second
            GPIO.output(s2, GPIO.LOW) #turn solenoid 2 off
            time.sleep(0.5)

            GPIO.output(s3, GPIO.HIGH) #turn solenoid 3 on
            time.sleep(0.5) #Wait for a half second
            GPIO.output(s3, GPIO.LOW) #turn solenoid 3 off
            time.sleep(0.5)

            GPIO.output(s4, GPIO.HIGH) #turn solenoid 4 on
            time.sleep(0.5) #Wait for a half second
            GPIO.output(s4, GPIO.LOW) #turn solenoid 4 off
            time.sleep(0.5)

            GPIO.output(s5, GPIO.HIGH) #turn solenoid 5 on
            time.sleep(0.5) #Wait for a half second
            GPIO.output(s5, GPIO.LOW) #turn solenoid 5 off
            time.sleep(0.5)

            GPIO.output(s6, GPIO.HIGH) #turn solenoid 6 on
            time.sleep(0.5) #Wait for a half second
            GPIO.output(s6, GPIO.LOW) #turn solenoid 6 off
            time.sleep(0.5)

#Print the results

            print( 'Soil Moisture:' , val)
            print( 'Flow Rate:' , waterFlow)
            print( " ")

            """

        time.sleep(1)

    except KeyboardInterrupt:
        break
    except IOError:
        print ("Error")


import numpy as np
import imutils
import time
import cv2

def detect(frame, net, CLASSES, COLORS, conf=0.2, display=False):
    """Detect objects in frame using pre-trained model"""

    # grab the frame dimensions and convert it to a blob
    #(h, w) = frame.shape[:2]
    blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)),
        0.007843, (300, 300), 127.5)

    # pass the blob through the network and obtain the detections and
    # predictions
    net.setInput(blob)
    detections = net.forward()

    pred = []
    score = []

    # loop over the detections
    for i in np.arange(0, detections.shape[2]):
        # extract the confidence (i.e., probability) associated with
        # the prediction
        confidence = detections[0, 0, i, 2]

        # filter out weak detections by ensuring the `confidence` is
        # greater than the minimum confidence
        if confidence > conf:
            # Extract label
            idx = int(detections[0, 0, i, 1])
            # Store results
            pred.append(CLASSES[idx])
            score.append(confidence)

            ##TODO: for display only
            if display:
                # extract the index of the class label from the
                # `detections`, then compute the (x, y)-coordinates of
                # the bounding box for the object

                box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
                label = "{}: {:.2f}%".format(CLASSES[idx],
                    confidence * 100)
                (startX, startY, endX, endY) = box.astype("int")
                cv2.rectangle(frame, (startX, startY), (endX, endY),
                    COLORS[idx], 2)
                y = startY - 15 if startY - 15 > 15 else startY + 15
                cv2.putText(frame, label, (startX, y),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, COLORS[idx], 2)

    if display:
        # show the output frame
        cv2.imshow("Frame", frame)
        time.sleep(5)
        # # do a bit of cleanup
        cv2.destroyAllWindows()

    return frame, pred, score


"""
    Code for Matching Model from:
    Diversifying Reply Suggestions using a Matching-Conditional Variational Autoencoder: https://arxiv.org/abs/1903.10630
    Copyright: Microsoft Search, Assistance and Intelligence Team, 2020
    @author: Budhaditya Deb
"""
# coding=utf-8
import importlib
import pdb
import numpy as np
import random
import torch

from retrieval_rs.models.matching.model_params import ModelParams
from retrieval_rs.models.common.utils import get_path_to_pretrained_model
from retrieval_rs.models.common_model_lib.text_encoders import TextEncoder
from retrieval_rs.models.common_model_lib.sr_module import SRModule
from retrieval_rs.models.common_model_lib.model_factory import get_module_class_from_factory

# dummy comment to pop it into the PR

class MatchingModule(SRModule):
    """
        Matching Model as described in:
            Diversifying Reply Suggestions using a Matching-Conditional Variational Autoencoder: https://arxiv.org/abs/1903.10630
        Model with two independent encoders for Msg and Rsp, trained to minimize the dot product distance between the two encoding outputs
        This is defined to generalize the models defined in retrieval_rs/models/matching for MCVAE.
        MCVAE always requires two independent encoders for msg and rsp side.
        Thus original MAtching model with BiLSTM encoders cannot be used at it has a shared embedding layer.
        Args to set:
            --txt_encoder_type
            --pretrained_model_path
            --recon_loss_type
            --train_rsp_encoder
    """
    def __init__(self, params):
        super().__init__(params)
        # ------------ create and initialize the base encoders from pretrained model ------------
        self.create_base_encoders()
        module = importlib.import_module("retrieval_rs.models.common_model_lib.losses")
        self.recon_loss = getattr(module, self.params.recon_loss_type)(self.params)

    def create_base_encoders(self):
        """
            Creates the base encoders (BERT, BiLSTM etc.)
            Loads these from a pretrained Matching model if available (need to pass --load_from parameter)
            Loading from pretrained is usually when loading from a model which was trained with a different class structure
            E.g. BERT, TNLR Matching Models (since these had different class structures)
        """
        print("SystemLog: Creating Base encoders for Matching model")
        self.msg_encoder = TextEncoder(self.params, encoder_side='msg')
        self.rsp_encoder = TextEncoder(self.params, encoder_side='rsp')

        if self.params.load_from == "tnlr": # assume that BERT like model was trained as a matching
            """
                This condition assumes the Matching Model was trained using Class definitions in
                /models/matching/bert_matching_model.py
                Since this does not use the TextEncoder wrapper so it needs to be created.
            """
            if self.params.txt_encoder_type == "BertTNLR":
                matching_model_inst = get_module_class_from_factory('bert_matching_model')
                matching_model = matching_model_inst(self.params)

            if self.params.pretrained_model_path:
                path_to_model = get_path_to_pretrained_model(self.params)
                print("SystemLog: Loading Matching Model (%s, %s) from %s" %(self.params.load_from, self.params.txt_encoder_type, path_to_model))
                matching_model.load_state_dict(torch.load(path_to_model, map_location=torch.device('cpu')))
                self.msg_encoder = TextEncoder(self.params, encoder_inst=matching_model.msg_encoder)
                self.rsp_encoder = TextEncoder(self.params, encoder_inst=matching_model.rsp_encoder)

        self.msg_enc_out_dim = self.msg_encoder.enc_out_dim
        self.rsp_enc_out_dim = self.rsp_encoder.enc_out_dim

    def train_valid_forward(self, input_batch):
        """
            For pretrained txt encoders like BertModel have not been pretrained for matching we should
            train the msg_encoder but dont neccesaruly need to train the response encoder.
            Args:
                input_batch: as a list of dicts: batch_size[{'msg_batch_tuple', 'rsp_batch_tuple', 'batch_messages', 'batch_replies', 'batch_rsp_labels'}]
            Returns:
                X: Input encoding of size [batch_size, self.msg_enc_out_dim]
                Y: Input encoding of size [batch_size, self.rsp_enc_out_dim]
        """
        X = self.msg_encoder(input_batch['msg_batch_tuple'])
        if self.params.train_rsp_encoder is False: # usually with BERT
            with torch.no_grad():
                Y = self.rsp_encoder(input_batch['rsp_batch_tuple'])
        else:
            Y = self.rsp_encoder(input_batch['rsp_batch_tuple'])
        return (X, Y)

    def eval_forward(self, input_batch):
        """ Used for inference model
            Need to make sure that the infernce graph has been initialized to latest model
            For matching we can do constrained sampling by first getting the topk and then doing the CVAE samples using only the topk.
            The sampling this works with batch size of 1. To do larger batch sizes we encode the messages in batch mode,
            but do the sampling with batch sizes of 1.
            Args:
                input_batch: msg_batch_tuple, batch_messages
            Returns:
                scores_with_lm_pen: [batch_size, top_k]
                scores_with_lm_pen_topk_inds: [batch_size, top_k]
                msg_enc_final: [batch_size, output_encoding_size]
        """
        with torch.no_grad():
            if self.run_mode == 'eval':
                msg_enc_final = self.msg_encoder(input_batch['msg_batch_tuple'], self.enforce_sorted)
            if self.run_mode == 'export_onnx':
                # -------- input_batch is inputed as a tuple for consistency with QAS --------
                msg_enc_final = self.msg_encoder(input_batch, self.enforce_sorted)

            scores = torch.matmul(msg_enc_final, torch.transpose(self.rsp_encodings, 0, 1))
            penalized_lm_scores = self.lm_alpha * self.lm_scores
            scores_with_lm_pen_all = torch.add(scores, penalized_lm_scores)
            scores_with_lm_pen, scores_with_lm_pen_topk_inds = torch.topk(scores_with_lm_pen_all, self.top_k, dim=1)

        return scores_with_lm_pen, scores_with_lm_pen_topk_inds, msg_enc_final

    def loss(self, output):
        """
            SMLoss and SySMLoss returns loss for each item in batch. Here we just compute the mean across the batch
            Args:
                output from forward (X, Y)
                X: Input encoding of size [batch_size, self.msg_enc_out_dim]
                Y: Input encoding of size [batch_size, self.rsp_enc_out_dim]
            Returns:
                loss_dict: {loss, precision}
        """
        loss_dict = self.recon_loss(output)
        recon_loss = loss_dict['loss']
        recon_loss = torch.mean(recon_loss)
        loss_dict['loss'] = recon_loss
        return loss_dict

    def initialize_inference_graph(self, params, enforce_sorted=False):
        self.top_k = int(params.top_k)
        self.lm_alpha = params.lm_alpha
        self.msg_encoder.to(params.device)
        self.rsp_encoder.to(params.device)
        self.rsp_encodings, self.rsp_token_ids = self.encode_responses()
        self.enforce_sorted = enforce_sorted


import numpy as np
import cv2 as cv
import paho.mqtt.client as mqtt
import socket
import sys
import cv2 as cv
import pickle
import numpy as np
import struct
import zlib
import multiprocessing
from multiprocessing import Queue
import queue
import math
import time

######################## DEFINICIONES PARA MQTT ####################

host = "192.168.1.11"
topic = "Control/orden"
puerto = 1883

distancia = Queue(10)

def on_connect(client, userdata, flags, rc):

    if rc == 0:

        print("Connected to broker")
        client.subscribe("Control/distancia")
    else:

        print("Connection failed")

def on_message(client, userdata, msg):
    m = str(msg.payload.decode("utf-8"))
    if userdata.full():
        pass
    else:
        userdata.put(m)
        #print('%s %s' % (msg.topic, msg.payload))

def on_publish(client, userdata, result):
    #print("Orden Enviada")
    pass

def cliente(cola_distancia, cola_objetivo, cola_base):
    client = mqtt.Client()
    client.on_connect = on_connect
    client.on_message = on_message
    client.on_publish = on_publish
    client.user_data_set(cola_distancia)

    client.connect(host, puerto)
    client.loop_start()

    objetivo = ""
    base = ""
    adquirido = False
    contador = 10
    contadorREV = 10
    rotar = False
    rotarREV = False
    distancia = 0
    while True:

        if cola_objetivo.empty():
            objetivo = "NA"
        else:
            objetivo = cola_objetivo.get()

        if cola_base.empty():
            base = "NA"
        else:
            base = cola_base.get()

        if cola_distancia.empty():
            distancia = 0
        else:
            distancia = cola_distancia.get()
            if distancia == '':
                distancia = 0
            else:
                distancia = int(distancia)

        if distancia == 0:
            pass
        elif distancia == 100:
            client.publish(topic, "on")
        else:
            if not adquirido:
                # Busqueda de pieza
                if objetivo == "NA":
                    # NO ENCUENTRA PIEZA
                    #### Busqueda de pieza
                    #Objeto delante
                    if distancia < 30:
                        if not rotarREV:
                            orden = "REVE"
                            client.publish(topic, orden)
                            contadorREV -= 1
                            if contadorREV == 0:
                                rotarREV = True
                                contadorREV = 10
                        else:
                            orden = "DERE"
                            client.publish(topic, orden)
                            contadorREV -= 1
                            if contadorREV == 0:
                                rotarREV = False
                                contadorREV = 10

                    else:
                        if not rotar:
                            orden = "STOP"
                            client.publish(topic, orden)
                            contador = contador-1
                            if contador == 0:
                                contador = 10
                                rotar = True
                        else:
                            orden = "STOP"
                            client.publish(topic, orden)
                            contador = contador-1
                            if contador == 0:
                                contador = 10
                                rotar = False

                else:
                    # Hay objetivo
                    x = objetivo[1]
                    centro = 300
                    margen = 80
                    area = objetivo[3]
                    distanciamin = 9000
                    if x < (centro - margen):
                        # Obejetivo a la derecha
                        orden = "IZQU"
                        client.publish(topic, orden)
                    elif x > (centro + margen):
                        # Objetivo a la izquierda
                        orden = "DERE"
                        client.publish(topic, orden)
                    else:
                        # Objetivo centrado
                        if area < distanciamin:
                            orden = "AVAN"
                            client.publish(topic, orden)
                        else:
                            orden = "STOP"
                            client.publish(topic, orden)

            else:
                # Cubo en las pinzas moviendose a la base
                if base == "NA":
                    # No encuentra la base
                    if distancia < 20:
                        if not rotarREV:
                            orden = "REVE"
                            client.publish(topic, orden)
                            contadorREV -= 1
                            if contadorREV == 0:
                                rotarREV = True
                                contadorREV = 10
                        else:
                            orden = "DERE"
                            client.publish(topic, orden)
                            contadorREV -= 1
                            if contadorREV == 0:
                                rotarREV = False
                                contadorREV = 10

                    else:
                        if not rotar:
                            orden = "StOP"
                            client.publish(topic, orden)
                            contador = contador-1
                            if contador == 0:
                                contador = 10
                                rotar = True
                        else:
                            orden = "STOP"
                            client.publish(topic, orden)
                            contador = contador-1
                            if contador == 0:
                                contador = 10
                                rotar = False
                else:
                   # Hay objetivo
                    x = objetivo[1]
                    centro = 300
                    margen = 50
                    area = objetivo[3]
                    distanciamin = 9500
                    if x < (centro - margen):
                        # Obejetivo a la derecha
                        orden = "IZQU"
                        client.publish(topic, orden)
                    elif x > (centro + margen):
                        # Objetivo a la izquierda
                        orden = "DERE"
                        client.publish(topic, orden)
                    else:
                        # Objetivo centrado
                        if area < distanciamin:
                            orden = "AVAN"
                            client.publish(topic, orden)
                        else:
                            orden = "STOP"
                            client.publish(topic, orden)

        time.sleep(0.05)

#################### SOCKET RECEPCION VIDEO #############
con = False

def videoRec(cola_framesR, cola_framesG, cola_framesB, cola_framesF):
    HOST = ''
    PORT = 8485

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print('Socket de video creado')

    s.bind((HOST, PORT))
    print('Socket de video bind completado')
    s.listen(10)
    print('Socket de video en espera')

    conn, addr = s.accept()

    print("Conexion de video establecida con %s:%s" % (addr[0], addr[1]))

    data = b""
    payload_size = struct.calcsize(">L")
    print("payload_size: {}".format(payload_size))

    while True:

        while len(data) < payload_size:
            # print("Recv: {}".format(len(data)))
            data += conn.recv(4096)

        # print("Done Recv: {}".format(len(data)))
        packed_msg_size = data[:payload_size]
        data = data[payload_size:]
        msg_size = struct.unpack(">L", packed_msg_size)[0]
        # print("msg_size: {}".format(msg_size))
        while len(data) < msg_size:
            data += conn.recv(4096)
        frame_data = data[:msg_size]
        data = data[msg_size:]

        frame = pickle.loads(frame_data, fix_imports=True, encoding="bytes")
        frame = cv.imdecode(frame, cv.IMREAD_COLOR)

        frame = cv.flip(frame, 0)
        frame = cv.flip(frame, 1)

        cola_framesR.put(frame)
        cola_framesG.put(frame)
        cola_framesB.put(frame)
        cola_framesF.put(frame)

####################  OPENCV ####################
def nothing(x):
    pass

font = cv.FONT_HERSHEY_COMPLEX_SMALL

def buscador(cola_frames, val_ini, color, cola_obj):
    cv.namedWindow("Barras " + color)

    cv.createTrackbar('L-H', "Barras " + color, val_ini.l_h, 180, nothing)
    cv.createTrackbar('U-H', "Barras " + color, val_ini.u_h, 180, nothing)

    cv.createTrackbar('L-S', "Barras " + color, val_ini.l_s, 255, nothing)
    cv.createTrackbar('U-S', "Barras " + color, val_ini.u_s, 255, nothing)

    cv.createTrackbar('L-V', "Barras " + color, val_ini.l_v, 255, nothing)
    cv.createTrackbar('U-V', "Barras " + color, val_ini.u_v, 255, nothing)

    while True:
        if(cola_frames.empty()):
            nothing(1)
        else:
            frame = cola_frames.get()

            hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)

            l_h = cv.getTrackbarPos('L-H',  "Barras " + color)
            l_s = cv.getTrackbarPos('L-S',  "Barras " + color)
            l_v = cv.getTrackbarPos('L-V',  "Barras " + color)
            u_h = cv.getTrackbarPos('U-H',  "Barras " + color)
            u_s = cv.getTrackbarPos('U-S',  "Barras " + color)
            u_v = cv.getTrackbarPos('U-V',  "Barras " + color)

            color_min = np.array([l_h, l_s, l_v])
            color_max = np.array([u_h, u_s, u_v])

            mask = cv.inRange(hsv, color_min, color_max)
            kernel = np.ones((5, 5), np.uint8)

            mask = cv.erode(mask, kernel)

            contours, _ = cv.findContours(
                mask, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

            if(len(contours) < 1):
                if cola_obj.full():
                    pass
                else:
                    cola_obj.put([color, "NA"])
            else:
                areamax = 0
                for contour in contours:
                    area = cv.contourArea(contour)

                    approx = cv.approxPolyDP(
                        contour, 0.02*cv.arcLength(contour, True), True)

                    x = approx.ravel()[0]
                    y = approx.ravel()[1]

                    if(area > 400):
                        momentos = cv.moments(contour)
                        cx = int(momentos['m10']/momentos['m00'])
                        cy = int(momentos['m01']/momentos['m00'])
                        if len(approx) == 3:
                            cv.drawContours(
                                frame, [approx], 0, (val_ini.B, val_ini.G, val_ini.R), 2)
                            cv.circle(frame, (cx, cy), 3,
                                      (val_ini.B, val_ini.G, val_ini.R), -1)
                            if cola_obj.full():
                                pass
                            else:
                                cola_obj.put([color, area, "T", cx, cy])

                            cv.putText(frame, "Base", (x, y),
                                       font, 1, (255, 255, 255))
                        elif len(approx) >= 4 and len(approx) <= 8:
                            if area > areamax:
                                areamax = area
                                cv.drawContours(
                                    frame, [approx], 0, (val_ini.B, val_ini.G, val_ini.R), 2)
                                cv.circle(frame, (cx, cy), 3,
                                          (val_ini.B, val_ini.G, val_ini.R), -1)
                                if cola_obj.full():
                                    pass
                                else:
                                    cola_obj.put([color, area, "C", cx, cy])

                                cv.putText(frame, "Objetivo", (x, y),
                                           font, 1, (255, 255, 255))

            cv.imshow("Mask " + color, mask)
            cv.imshow("Siguiendo " + color, frame)

        if cv.waitKey(1) == ord('q'):
            break

        cv.waitKey(1)

class valores_ini:
    l_h = 0
    l_s = 0
    l_v = 0
    u_h = 0
    u_s = 0
    u_v = 0
    R = 0
    G = 0
    B = 0

"""val_R = valores_ini()

val_R.l_h = 0
val_R.l_s = 0
val_R.l_v = 0
val_R.u_h = 0
val_R.u_s = 0
val_R.u_v = 0
val_R.R = 0"""

val_R = valores_ini()

val_R.l_h = 140
val_R.l_s = 55
val_R.l_v = 0
val_R.u_h = 180
val_R.u_s = 229
val_R.u_v = 255
val_R.R = 255

"""val_G = valores_ini()

val_G.l_h = 45
val_G.l_s = 100
val_G.l_v = 40
val_G.u_h = 70
val_G.u_s = 255
val_G.u_v = 255
val_G.G = 255"""

val_G = valores_ini()

val_G.l_h = 0
val_G.l_s = 0
val_G.l_v = 0
val_G.u_h = 0
val_G.u_s = 0
val_G.u_v = 0
val_G.G = 0

"""val_B = valores_ini()

val_B.l_h = 80
val_B.l_s = 80
val_B.l_v = 40
val_B.u_h = 100
val_B.u_s = 255
val_B.u_v = 255
val_B.B = 255"""

val_B = valores_ini()

val_B.l_h = 0
val_B.l_s = 0
val_B.l_v = 0
val_B.u_h = 0
val_B.u_s = 0
val_B.u_v = 0
val_B.B = 0

########### CONTROL PRINCIPAL ################

class objets:
    color = ""
    tipo = ""
    area = 0
    x = 0
    y = 0

def control(cola_frames, cola_objR, cola_objG, cola_objB, cola_objetivo, cola_base):

    mas_cercano = objets()
    cuboR = objets()
    cuboG = objets()
    cuboB = objets()
    baseR = objets()
    baseG = objets()
    baseB = objets()
    objetivo = ""

    while True:

        recR = []
        recG = []
        recB = []
        try:
            recR = cola_objR.get()
            recG = cola_objG.get()
            recB = cola_objB.get()
        except:
            recR[1] = "NA"
            recG[1] = "NA"
            recB[1] = "NA"

        if recR[1] == "NA":
            cuboR = objets()
            baseR = objets()
        else:
            if recR[2] == "T":
                baseR.area = recR[1]
                baseR.x = recR[3]
                baseR.y = recR[4]
            else:
                cuboR.area = recR[1]
                cuboR.x = recR[3]
                cuboR.y = recR[4]

        if recG[1] == "NA":
            cuboG = objets()
            baseG = objets()
        else:
            if recG[2] == "T":
                baseG.area = recG[1]
                baseG.x = recG[3]
                baseG.y = recG[4]
            else:
                cuboG.area = recG[1]
                cuboG.x = recG[3]
                cuboG.y = recG[4]

        if recB[1] == "NA":
            cuboB = objets()
            baseB = objets()
        else:
            if recB[2] == "T":
                baseB.area = recB[1]
                baseB.x = recB[3]
                baseB.y = recB[4]
            else:
                cuboB.area = recB[1]
                cuboB.x = recB[3]
                cuboB.y = recB[4]

        if cuboR.area > cuboG.area and cuboR.area > cuboB.area and cuboR.area > 0:

            # print("Area: " + str(cuboR.area) + " X: " +
            # str(cuboR.x) + " Y: " + str(cuboR.y))
            objetivo = "R"
            if cola_objetivo.full():
                pass
            else:
                cola_objetivo.put([objetivo, cuboR.x, cuboR.y, cuboR.area])

        elif cuboG.area > cuboB.area and cuboG.area > 0:

            # print("Area: " + str(cuboG.area) + " X: " +
            #      str(cuboG.x) + " Y: " + str(cuboG.y))
            objetivo = "G"
            if cola_objetivo.full():
                pass
            else:
                cola_objetivo.put([objetivo, cuboG.x, cuboG.y, cuboG.area])
        elif cuboB.area > 0:

            # print("Area: " + str(cuboB.area) + " X: " +
            #      str(cuboB.x) + " Y: " + str(cuboB.y))
            objetivo = "B"
            if cola_objetivo.full():
                pass
            else:
                cola_objetivo.put([objetivo, cuboB.x, cuboB.y, cuboB.area])
        else:
            objetivo = ""

        if baseR.area > 0 and objetivo == "R":

            # print("Base R x: " + str(baseR.x) + " y: " +
            #      str(baseR.y) + " area: " + str(baseR.area))
            if cola_base.full():
                pass
            else:
                cola_base.put([objetivo, baseR.x, baseR.y, baseR.area])
        elif baseG.area > 0 and objetivo == "G":

            # print("Base G x: " + str(baseG.x) + " y: " +
            #      str(baseG.y) + " area: " + str(baseG.area))
            if cola_base.full():
                pass
            else:
                cola_base.put([objetivo, baseG.x, baseG.y, baseG.area])
        elif baseB.area > 0 and objetivo == "B":

            # print("Base B x: " + str(baseB.x) + " y: " +
            #      str(baseB.y) + " area: " + str(baseB.area))
            if cola_base.full():
                pass
            else:
                cola_base.put([objetivo, baseB.x, baseB.y, baseB.area])

########### MAIN ######################
if __name__ == '__main__':
    framesR = Queue()
    framesG = Queue()
    framesB = Queue()
    framesF = Queue()
    objetosR = Queue(10)
    objetosG = Queue(10)
    objetosB = Queue(10)
    objetivo = Queue(10)
    base = Queue(10)

    cliente_thread = multiprocessing.Process(
        target=cliente, args=(distancia, objetivo, base))

    videoRec_thread = multiprocessing.Process(
        target=videoRec, args=(framesR, framesG, framesB, framesF))

    R_thread = multiprocessing.Process(
        target=buscador, args=(framesR, val_R, "R", objetosR))

    G_thread = multiprocessing.Process(
        target=buscador, args=(framesG, val_G, "G", objetosG))

    B_thread = multiprocessing.Process(
        target=buscador, args=(framesB, val_B, "B", objetosB))

    control_thread = multiprocessing.Process(
        target=control, args=(framesF, objetosR, objetosG, objetosB, objetivo, base))

    cliente_thread.start()
    videoRec_thread.start()
    R_thread.start()
    G_thread.start()
    B_thread.start()
    control_thread.start()

    cliente_thread.join()
    videoRec_thread.join()
    R_thread.join()
    G_thread.join()
    B_thread.join()
    control_thread.join()

    exit()


def selection_13():

    # Library import
    import numpy
    import matplotlib
    import matplotlib.pyplot   as plt
    import matplotlib.gridspec as gridspec

    # Library version
    matplotlib_version = matplotlib.__version__
    numpy_version      = numpy.__version__

    # Histo binning
    xBinning = numpy.linspace(0.0,1000.0,201,endpoint=True)

    # Creating data sequence: middle of each bin
    xData = numpy.array([2.5,7.5,12.5,17.5,22.5,27.5,32.5,37.5,42.5,47.5,52.5,57.5,62.5,67.5,72.5,77.5,82.5,87.5,92.5,97.5,102.5,107.5,112.5,117.5,122.5,127.5,132.5,137.5,142.5,147.5,152.5,157.5,162.5,167.5,172.5,177.5,182.5,187.5,192.5,197.5,202.5,207.5,212.5,217.5,222.5,227.5,232.5,237.5,242.5,247.5,252.5,257.5,262.5,267.5,272.5,277.5,282.5,287.5,292.5,297.5,302.5,307.5,312.5,317.5,322.5,327.5,332.5,337.5,342.5,347.5,352.5,357.5,362.5,367.5,372.5,377.5,382.5,387.5,392.5,397.5,402.5,407.5,412.5,417.5,422.5,427.5,432.5,437.5,442.5,447.5,452.5,457.5,462.5,467.5,472.5,477.5,482.5,487.5,492.5,497.5,502.5,507.5,512.5,517.5,522.5,527.5,532.5,537.5,542.5,547.5,552.5,557.5,562.5,567.5,572.5,577.5,582.5,587.5,592.5,597.5,602.5,607.5,612.5,617.5,622.5,627.5,632.5,637.5,642.5,647.5,652.5,657.5,662.5,667.5,672.5,677.5,682.5,687.5,692.5,697.5,702.5,707.5,712.5,717.5,722.5,727.5,732.5,737.5,742.5,747.5,752.5,757.5,762.5,767.5,772.5,777.5,782.5,787.5,792.5,797.5,802.5,807.5,812.5,817.5,822.5,827.5,832.5,837.5,842.5,847.5,852.5,857.5,862.5,867.5,872.5,877.5,882.5,887.5,892.5,897.5,902.5,907.5,912.5,917.5,922.5,927.5,932.5,937.5,942.5,947.5,952.5,957.5,962.5,967.5,972.5,977.5,982.5,987.5,992.5,997.5])

    # Creating weights for histo: y14_MET_0
    y14_MET_0_weights = numpy.array([87.8712184224,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_1
    y14_MET_1_weights = numpy.array([52.866729024,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_2
    y14_MET_2_weights = numpy.array([34.1474106704,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_3
    y14_MET_3_weights = numpy.array([23.2791433376,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_4
    y14_MET_4_weights = numpy.array([0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_5
    y14_MET_5_weights = numpy.array([3.15970038462,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_6
    y14_MET_6_weights = numpy.array([25.7975673846,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_7
    y14_MET_7_weights = numpy.array([34.8076353462,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_8
    y14_MET_8_weights = numpy.array([18.8331344136,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_9
    y14_MET_9_weights = numpy.array([11.438338975,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_10
    y14_MET_10_weights = numpy.array([1.92080170268,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_11
    y14_MET_11_weights = numpy.array([0.492029039423,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_12
    y14_MET_12_weights = numpy.array([0.048601296,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_13
    y14_MET_13_weights = numpy.array([1.16464979258,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_14
    y14_MET_14_weights = numpy.array([6.68294011675,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_15
    y14_MET_15_weights = numpy.array([7.0934749248,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_16
    y14_MET_16_weights = numpy.array([3.66041069784,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_17
    y14_MET_17_weights = numpy.array([2.15301866735,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_18
    y14_MET_18_weights = numpy.array([0.384965608101,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating weights for histo: y14_MET_19
    y14_MET_19_weights = numpy.array([0.0982300333891,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])

    # Creating a new Canvas
    fig   = plt.figure(figsize=(12,6),dpi=80)
    frame = gridspec.GridSpec(1,1,right=0.7)
    pad   = fig.add_subplot(frame[0])

    # Creating a new Stack
    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights+y14_MET_4_weights+y14_MET_5_weights+y14_MET_6_weights+y14_MET_7_weights+y14_MET_8_weights+y14_MET_9_weights+y14_MET_10_weights+y14_MET_11_weights+y14_MET_12_weights+y14_MET_13_weights+y14_MET_14_weights+y14_MET_15_weights+y14_MET_16_weights+y14_MET_17_weights+y14_MET_18_weights+y14_MET_19_weights,\
             label="$bg\_vbf\_1600\_inf$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#ccc6aa", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights+y14_MET_4_weights+y14_MET_5_weights+y14_MET_6_weights+y14_MET_7_weights+y14_MET_8_weights+y14_MET_9_weights+y14_MET_10_weights+y14_MET_11_weights+y14_MET_12_weights+y14_MET_13_weights+y14_MET_14_weights+y14_MET_15_weights+y14_MET_16_weights+y14_MET_17_weights+y14_MET_18_weights,\
             label="$bg\_vbf\_1200\_1600$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#c1bfa8", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights+y14_MET_4_weights+y14_MET_5_weights+y14_MET_6_weights+y14_MET_7_weights+y14_MET_8_weights+y14_MET_9_weights+y14_MET_10_weights+y14_MET_11_weights+y14_MET_12_weights+y14_MET_13_weights+y14_MET_14_weights+y14_MET_15_weights+y14_MET_16_weights+y14_MET_17_weights,\
             label="$bg\_vbf\_800\_1200$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#bab5a3", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights+y14_MET_4_weights+y14_MET_5_weights+y14_MET_6_weights+y14_MET_7_weights+y14_MET_8_weights+y14_MET_9_weights+y14_MET_10_weights+y14_MET_11_weights+y14_MET_12_weights+y14_MET_13_weights+y14_MET_14_weights+y14_MET_15_weights+y14_MET_16_weights,\
             label="$bg\_vbf\_600\_800$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#b2a596", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights+y14_MET_4_weights+y14_MET_5_weights+y14_MET_6_weights+y14_MET_7_weights+y14_MET_8_weights+y14_MET_9_weights+y14_MET_10_weights+y14_MET_11_weights+y14_MET_12_weights+y14_MET_13_weights+y14_MET_14_weights+y14_MET_15_weights,\
             label="$bg\_vbf\_400\_600$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#b7a39b", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights+y14_MET_4_weights+y14_MET_5_weights+y14_MET_6_weights+y14_MET_7_weights+y14_MET_8_weights+y14_MET_9_weights+y14_MET_10_weights+y14_MET_11_weights+y14_MET_12_weights+y14_MET_13_weights+y14_MET_14_weights,\
             label="$bg\_vbf\_200\_400$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#ad998c", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights+y14_MET_4_weights+y14_MET_5_weights+y14_MET_6_weights+y14_MET_7_weights+y14_MET_8_weights+y14_MET_9_weights+y14_MET_10_weights+y14_MET_11_weights+y14_MET_12_weights+y14_MET_13_weights,\
             label="$bg\_vbf\_100\_200$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#9b8e82", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights+y14_MET_4_weights+y14_MET_5_weights+y14_MET_6_weights+y14_MET_7_weights+y14_MET_8_weights+y14_MET_9_weights+y14_MET_10_weights+y14_MET_11_weights+y14_MET_12_weights,\
             label="$bg\_vbf\_0\_100$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#876656", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights+y14_MET_4_weights+y14_MET_5_weights+y14_MET_6_weights+y14_MET_7_weights+y14_MET_8_weights+y14_MET_9_weights+y14_MET_10_weights+y14_MET_11_weights,\
             label="$bg\_dip\_1600\_inf$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#afcec6", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights+y14_MET_4_weights+y14_MET_5_weights+y14_MET_6_weights+y14_MET_7_weights+y14_MET_8_weights+y14_MET_9_weights+y14_MET_10_weights,\
             label="$bg\_dip\_1200\_1600$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#84c1a3", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights+y14_MET_4_weights+y14_MET_5_weights+y14_MET_6_weights+y14_MET_7_weights+y14_MET_8_weights+y14_MET_9_weights,\
             label="$bg\_dip\_800\_1200$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#89a8a0", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights+y14_MET_4_weights+y14_MET_5_weights+y14_MET_6_weights+y14_MET_7_weights+y14_MET_8_weights,\
             label="$bg\_dip\_600\_800$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#829e8c", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights+y14_MET_4_weights+y14_MET_5_weights+y14_MET_6_weights+y14_MET_7_weights,\
             label="$bg\_dip\_400\_600$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#adbcc6", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights+y14_MET_4_weights+y14_MET_5_weights+y14_MET_6_weights,\
             label="$bg\_dip\_200\_400$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#7a8e99", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights+y14_MET_4_weights+y14_MET_5_weights,\
             label="$bg\_dip\_100\_200$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#758991", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights+y14_MET_4_weights,\
             label="$bg\_dip\_0\_100$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#688296", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights,\
             label="$signal\_2pt4TeVL$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#6d7a84", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights,\
             label="$signal\_2pt2TeVL$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#7c99d1", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights+y14_MET_1_weights,\
             label="$signal\_2TeVL$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#7f7f9b", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    pad.hist(x=xData, bins=xBinning, weights=y14_MET_0_weights,\
             label="$signal\_1pt8TeVL$", histtype="step", rwidth=1.0,\
             color=None, edgecolor="#aaa5bf", linewidth=1, linestyle="solid",\
             bottom=None, cumulative=False, normed=False, align="mid", orientation="vertical")

    # Axis
    plt.rc('text',usetex=False)
    plt.xlabel(r"MET",\
               fontsize=16,color="black")
    plt.ylabel(r"$\mathrm{Events}$ $(\mathcal{L}_{\mathrm{int}} = 40.0\ \mathrm{fb}^{-1})$ ",\
               fontsize=16,color="black")

    # Boundary of y-axis
    ymax=(y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights+y14_MET_4_weights+y14_MET_5_weights+y14_MET_6_weights+y14_MET_7_weights+y14_MET_8_weights+y14_MET_9_weights+y14_MET_10_weights+y14_MET_11_weights+y14_MET_12_weights+y14_MET_13_weights+y14_MET_14_weights+y14_MET_15_weights+y14_MET_16_weights+y14_MET_17_weights+y14_MET_18_weights+y14_MET_19_weights).max()*1.1
    ymin=0 # linear scale
    #ymin=min([x for x in (y14_MET_0_weights+y14_MET_1_weights+y14_MET_2_weights+y14_MET_3_weights+y14_MET_4_weights+y14_MET_5_weights+y14_MET_6_weights+y14_MET_7_weights+y14_MET_8_weights+y14_MET_9_weights+y14_MET_10_weights+y14_MET_11_weights+y14_MET_12_weights+y14_MET_13_weights+y14_MET_14_weights+y14_MET_15_weights+y14_MET_16_weights+y14_MET_17_weights+y14_MET_18_weights+y14_MET_19_weights) if x])/100. # log scale
    plt.gca().set_ylim(ymin,ymax)

    # Log/Linear scale for X-axis
    plt.gca().set_xscale("linear")
    #plt.gca().set_xscale("log",nonposx="clip")

    # Log/Linear scale for Y-axis
    plt.gca().set_yscale("linear")
    #plt.gca().set_yscale("log",nonposy="clip")

    # Legend
    plt.legend(bbox_to_anchor=(1.05,1), loc=2, borderaxespad=0.)

    # Saving the image
    plt.savefig('../../HTML/MadAnalysis5job_0/selection_13.png')
    plt.savefig('../../PDF/MadAnalysis5job_0/selection_13.png')
    plt.savefig('../../DVI/MadAnalysis5job_0/selection_13.eps')

# Running!
if __name__ == '__main__':
    selection_13()