<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

from cobra import Reaction
from ..optim.utils import symbol_sum

from pytfa.optim.variables import ReactionVariable, BinaryVariable, get_binary_type
from pytfa.optim.constraints import ReactionConstraint

from numpy import sum

CPLEX = 'optlang-cplex'
GUROBI = 'optlang-gurobi'
GLPK = 'optlang-glpk'

class MyVariableClass(ReactionVariable, BinaryVariable):
    prefix = 'VC_'

    def __init__(self, reaction, **kwargs):
        ReactionVariable.__init__(self, reaction,
                                  type=get_binary_type(),
                                  **kwargs)

# Define a new constraint type:
class MyConstraintClass(ReactionConstraint):
    prefix = 'CC_'

class LumpGEM:
    """
    A class encapsulating the LumpGEM algorithm
    """
    def __init__(self, tfa_model, biomass_rxns, core_subsystems, carbon_uptake, growth_rate):
        """
        : param tfa_model: The GEM (associated with the thermodynamics constraints) that lumpGEM must work on
        : type GEM: pytfa model

        : param biomass_rxns: list of biomass reactions
        : type biomass_rxns: [GEM.biomass_rxn.id]

        : param core_subsystems: list of Core subsystems names
        : type core_subsystems: [string]

        : param carbon_intake: the amount of carbon atoms the cell intakes from its surrounding
        : type carbon_intake: float

        : param growth_rate: theoretical maximum specific growth rate in 1/hr units
        : type growth_rate: float
        """

        self._tfa_model = tfa_model

        # Set containing every BBB reaction
        self._rBBB = []
        # Set containing every core reaction
        self._rcore = []
        # Set containing every core metabolite
        self._mcore = []
        # Set containing every non-core reaction
        self._rncore = []

        # For each reaction
        for rxn in self._tfa_model.reactions:
            # If it's a BBB reaction
            if rxn.id in biomass_rxns:
                self._rBBB.append(rxn)
            # If it's a core reaction
            elif rxn.subsystem in core_subsystems:
                self._rcore.append(rxn)
                for met in rxn.metabolites:
                    self._mcore.append(met)
            # If it's neither BBB nor core, then it's non-core
            else:
                self._rncore.append(rxn)

        # Carbon uptake
        self._C_uptake = carbon_uptake
        # Growth rate
        self._growth_rate = growth_rate

        # TODO : solver choice
        # TODO default : solver du modele
        self._solver = 'optlang-cplex'

        # lumpgen binary variables to deactivate non-core reactions. The reaction is deactivated when the value of
        # the variable is 1
        self._activation_vars = {rxn: self._tfa_model.add_variable(kind=MyVariableClass,
                                                                   hook=rxn,
                                                                   lb=0,
                                                                   ub=1,
                                                                   queue=False)
                                 for rxn in self._rncore}

        self._generate_carbon_constraints()
        self._generate_objective()
        self._sinks = self._prepare_sinks()

    def _generate_carbon_constraints(self):
        """
        Generate carbon intake related constraints for each non-core reaction
        For each reaction rxn : rxn.forward_variable + rxn.reverse_variable + activation_var * C_uptake < C_uptake
        """
        for rxn in self._rncore:
            activation_var = self._activation_vars[rxn]

            # variable that should be bounded by carbon_uptake
            reac_var = rxn.forward_variable + rxn.reverse_variable + activation_var * self._C_uptake
            # adding the constraint to the model
            self._tfa_model.add_constraint(kind=MyConstraintClass,
                                           hook=rxn,
                                           expr=reac_var,
                                           ub=self._C_uptake,
                                           queue=True)

        # push constraints in one bulk (faster)
        self._tfa_model._push_queue()
        # refresh constraint fields
        self._tfa_model.repair()

    def _prepare_sinks(self):
        """
        For each BBB (reactant of the biomass reactions), generate a sink, i.e an unbalanced reaction BBB ->
        of which purpose is to enable the BBB to be output of the GEM
        :return: the dict {BBB: sink} containing every BBB (keys) and their associated sinks
        """
        all_sinks = {}
        print("Preparing sinks...")

        for bio_rxn in self._rBBB:
            print(bio_rxn.id)
            for met, stoech_coeff in bio_rxn.metabolites.items():

                # stoech_coeff < 0 indicates that the metabolite is a reactant
                if (stoech_coeff < 0) and (met not in all_sinks.keys()):
                    print("   " + met.id)
                    sink = Reaction("Sink_" + bio_rxn.id + "_" + met.id)
                    sink.name = "Sink_" + bio_rxn.name + "_" + met.name
                    # Subsystem specific to BBB sinks
                    sink.subsystem = "Demand"

                    # A sink is simply a reaction which consumes the BBB
                    sink.add_metabolites({met: -1})
                    # The sinks will be activated later (cf compute_lumps), one at a time
                    sink.knock_out()

                    # The stoechiometric coefficients will be used to define the lower bound of the sink,
                    # thus it must be stored
                    all_sinks[met] = (sink.id, -stoech_coeff)
                    self._tfa_model.add_reactions([sink])

                # reactant already seen
                elif stoech_coeff < 0:
                    # The BBB has already been associated to a sink, so we simply increase the bound of the sink
                    all_sinks[met][1] -= stoech_coeff
                    # Equivalent to this, but there is a knockout :
                    #self._tfa_model.reactions.get_by_id(sinks[met]).lower_bound += self._growth_rate * stoech_coeff

        self._tfa_model.prepare()
        for ncrxn in self._rncore:
            ncrxn.thermo['computed'] = False

        return all_sinks

    def _generate_objective(self):
        """
        Generate and add the maximization objective : set as many activation variables as possible to 1
        When an activation variable is set to 1, the corresponding non-core reaction is deactivated
        """
        # Sum of binary variables to be maximized
        objective_sum = symbol_sum(list(self._activation_vars.values()))
        # Set the sum as the objective function
        self._tfa_model.objective = self._tfa_model.problem.Objective(objective_sum, direction='max')

    def compute_lumps(self):
        """
        For each BBB (reactant of the biomass reaction), add the corresponding sink to the model, then optimize and
        lump the result into one lumped reaction
        :return: The dict {BBB: lump} containing every lumped reactions, associated to their BBBs
        """

        # Must be called before optimization
        self._tfa_model.convert()

        # dict: {metabolite: lumped_reaction}
        lumps = {}

        for met_BBB, (sink_id, stoech_coeff) in self._sinks.items():
            print("Considering :" + met_BBB.id)

            # Activate reaction by setting its lower bound
            self._tfa_model.reactions.get_by_id(sink_id).lower_bound = self._growth_rate * stoech_coeff

            # TODO timeout
            tfa_solution = self._tfa_model.optimize()

            # TODO maybe use sympy.add
            lumped_core_reactions  = sum([rxn * tfa_solution.fluxes.get(rxn.id) for rxn in self._rcore])
            lumped_ncore_reactions = sum([rxn * tfa_solution.fluxes.get(rxn.id) * self._activation_vars[rxn].variable.primal for rxn in self._rncore])
            lumped_BBB_reactions   = sum([rxn * tfa_solution.fluxes.get(rxn.id) for rxn in self._rBBB])

            lumped_reaction = sum([lumped_core_reactions, lumped_ncore_reactions, lumped_BBB_reactions])

            lumps[met_BBB] = lumped_reaction

            # Deactivating reaction by setting both bounds to 0
            self._tfa_model.reactions.get_by_id(sink_id).knock_out()

        return lumps

<commit_msg>FIX : removed mcore list, was useless<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

from cobra import Reaction
from ..optim.utils import symbol_sum

from pytfa.optim.variables import ReactionVariable, BinaryVariable, get_binary_type
from pytfa.optim.constraints import ReactionConstraint

from numpy import sum

CPLEX = 'optlang-cplex'
GUROBI = 'optlang-gurobi'
GLPK = 'optlang-glpk'

class MyVariableClass(ReactionVariable, BinaryVariable):
    prefix = 'VC_'

    def __init__(self, reaction, **kwargs):
        ReactionVariable.__init__(self, reaction,
                                  type=get_binary_type(),
                                  **kwargs)

# Define a new constraint type:
class MyConstraintClass(ReactionConstraint):
    prefix = 'CC_'

class LumpGEM:
    """
    A class encapsulating the LumpGEM algorithm
    """
    def __init__(self, tfa_model, biomass_rxns, core_subsystems, carbon_uptake, growth_rate):
        """
        : param tfa_model: The GEM (associated with the thermodynamics constraints) that lumpGEM must work on
        : type GEM: pytfa model

        : param biomass_rxns: list of biomass reactions
        : type biomass_rxns: [GEM.biomass_rxn.id]

        : param core_subsystems: list of Core subsystems names
        : type core_subsystems: [string]

        : param carbon_intake: the amount of carbon atoms the cell intakes from its surrounding
        : type carbon_intake: float

        : param growth_rate: theoretical maximum specific growth rate in 1/hr units
        : type growth_rate: float
        """

        self._tfa_model = tfa_model

        # Set containing every BBB reaction
        self._rBBB = []
        # Set containing every core reaction
        self._rcore = []
        # Set containing every non-core reaction
        self._rncore = []

        # For each reaction
        for rxn in self._tfa_model.reactions:
            # If it's a BBB reaction
            if rxn.id in biomass_rxns:
                self._rBBB.append(rxn)
            # If it's a core reaction
            elif rxn.subsystem in core_subsystems:
                self._rcore.append(rxn)
            # If it's neither BBB nor core, then it's non-core
            else:
                self._rncore.append(rxn)

        # Carbon uptake
        self._C_uptake = carbon_uptake
        # Growth rate
        self._growth_rate = growth_rate

        # TODO : solver choice
        # TODO default : solver du modele
        self._solver = 'optlang-cplex'

        # lumpgen binary variables to deactivate non-core reactions. The reaction is deactivated when the value of
        # the variable is 1
        self._activation_vars = {rxn: self._tfa_model.add_variable(kind=MyVariableClass,
                                                                   hook=rxn,
                                                                   lb=0,
                                                                   ub=1,
                                                                   queue=False)
                                 for rxn in self._rncore}

        self._generate_carbon_constraints()
        self._generate_objective()
        self._sinks = self._prepare_sinks()

    def _generate_carbon_constraints(self):
        """
        Generate carbon intake related constraints for each non-core reaction
        For each reaction rxn : rxn.forward_variable + rxn.reverse_variable + activation_var * C_uptake < C_uptake
        """
        for rxn in self._rncore:
            activation_var = self._activation_vars[rxn]

            # variable that should be bounded by carbon_uptake
            reac_var = rxn.forward_variable + rxn.reverse_variable + activation_var * self._C_uptake
            # adding the constraint to the model
            self._tfa_model.add_constraint(kind=MyConstraintClass,
                                           hook=rxn,
                                           expr=reac_var,
                                           ub=self._C_uptake,
                                           queue=True)

        # push constraints in one bulk (faster)
        self._tfa_model._push_queue()
        # refresh constraint fields
        self._tfa_model.repair()

    def _prepare_sinks(self):
        """
        For each BBB (reactant of the biomass reactions), generate a sink, i.e an unbalanced reaction BBB ->
        of which purpose is to enable the BBB to be output of the GEM
        :return: the dict {BBB: sink} containing every BBB (keys) and their associated sinks
        """
        all_sinks = {}
        print("Preparing sinks...")

        for bio_rxn in self._rBBB:
            print(bio_rxn.id)
            for met, stoech_coeff in bio_rxn.metabolites.items():

                # stoech_coeff < 0 indicates that the metabolite is a reactant
                if (stoech_coeff < 0) and (met not in all_sinks.keys()):
                    print("   " + met.id)
                    sink = Reaction("Sink_" + bio_rxn.id + "_" + met.id)
                    sink.name = "Sink_" + bio_rxn.name + "_" + met.name
                    # Subsystem specific to BBB sinks
                    sink.subsystem = "Demand"

                    # A sink is simply a reaction which consumes the BBB
                    sink.add_metabolites({met: -1})
                    # The sinks will be activated later (cf compute_lumps), one at a time
                    sink.knock_out()

                    # The stoechiometric coefficients will be used to define the lower bound of the sink,
                    # thus it must be stored
                    all_sinks[met] = (sink.id, -stoech_coeff)
                    self._tfa_model.add_reactions([sink])

                # reactant already seen
                elif stoech_coeff < 0:
                    # The BBB has already been associated to a sink, so we simply increase the bound of the sink
                    all_sinks[met][1] -= stoech_coeff

        # Must be called before changing the reaction.thermo['computed'] values
        self._tfa_model.prepare()
        for ncrxn in self._rncore:
            ncrxn.thermo['computed'] = False

        return all_sinks

    def _generate_objective(self):
        """
        Generate and add the maximization objective : set as many activation variables as possible to 1
        When an activation variable is set to 1, the corresponding non-core reaction is deactivated
        """
        # Sum of binary variables to be maximized
        objective_sum = symbol_sum(list(self._activation_vars.values()))
        # Set the sum as the objective function
        self._tfa_model.objective = self._tfa_model.problem.Objective(objective_sum, direction='max')

    def compute_lumps(self):
        """
        For each BBB (reactant of the biomass reaction), add the corresponding sink to the model, then optimize and
        lump the result into one lumped reaction
        :return: The dict {BBB: lump} containing every lumped reactions, associated to their BBBs
        """

        # Must be called before optimization
        self._tfa_model.convert()

        # dict: {metabolite: lumped_reaction}
        lumps = {}

        for met_BBB, (sink_id, stoech_coeff) in self._sinks.items():
            print("Considering :" + met_BBB.id)

            # Activate reaction by setting its lower bound
            self._tfa_model.reactions.get_by_id(sink_id).lower_bound = self._growth_rate * stoech_coeff

            # TODO timeout
            tfa_solution = self._tfa_model.optimize()

            # TODO maybe use sympy.add
            lumped_core_reactions  = sum([rxn * tfa_solution.fluxes.get(rxn.id) for rxn in self._rcore])
            lumped_ncore_reactions = sum([rxn * tfa_solution.fluxes.get(rxn.id) * self._activation_vars[rxn].variable.primal for rxn in self._rncore])
            lumped_BBB_reactions   = sum([rxn * tfa_solution.fluxes.get(rxn.id) for rxn in self._rBBB])

            lumped_reaction = sum([lumped_core_reactions, lumped_ncore_reactions, lumped_BBB_reactions])

            lumps[met_BBB] = lumped_reaction

            # Deactivating reaction by setting both bounds to 0
            self._tfa_model.reactions.get_by_id(sink_id).knock_out()

        return lumps

<|endoftext|>


<commit_before>"""
homeassistant.components.device_tracker.nmap
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Device tracker platform that supports scanning a network with nmap.

Configuration:

To use the nmap tracker you will need to add something like the following
to your configuration.yaml file.

device_tracker:
  platform: nmap_tracker
  hosts: 192.168.1.1/24

Variables:

hosts
*Required
The IP addresses to scan in the network-prefix notation (192.168.1.1/24) or
the range notation (192.168.1.1-255).

home_interval
*Optional
Number of minutes it will not scan devices that it found in previous results.
This is to save battery.
"""
import logging
from datetime import timedelta
from collections import namedtuple
import subprocess
import re

import homeassistant.util.dt as dt_util
from homeassistant.const import CONF_HOSTS
from homeassistant.helpers import validate_config
from homeassistant.util import Throttle, convert
from homeassistant.components.device_tracker import DOMAIN

# Return cached results if last scan was less then this time ago
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=5)

_LOGGER = logging.getLogger(__name__)

# interval in minutes to exclude devices from a scan while they are home
CONF_HOME_INTERVAL = "home_interval"

REQUIREMENTS = ['python-nmap==0.4.3']

def get_scanner(hass, config):
    """ Validates config and returns a Nmap scanner. """
    if not validate_config(config, {DOMAIN: [CONF_HOSTS]},
                           _LOGGER):
        return None

    scanner = NmapDeviceScanner(config[DOMAIN])

    return scanner if scanner.success_init else None

Device = namedtuple("Device", ["mac", "name", "ip", "last_update"])

def _arp(ip_address):
    """ Get the MAC address for a given IP. """
    cmd = ['arp', '-n', ip_address]
    arp = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    out, _ = arp.communicate()
    match = re.search(r'(([0-9A-Fa-f]{1,2}\:){5}[0-9A-Fa-f]{1,2})', str(out))
    if match:
        return match.group(0)
    _LOGGER.info("No MAC address found for %s", ip_address)
    return None

class NmapDeviceScanner(object):
    """ This class scans for devices using nmap. """

    def __init__(self, config):
        self.last_results = []

        self.hosts = config[CONF_HOSTS]
        minutes = convert(config.get(CONF_HOME_INTERVAL), int, 0)
        self.home_interval = timedelta(minutes=minutes)

        self.success_init = self._update_info()
        _LOGGER.info("nmap scanner initialized")

    def scan_devices(self):
        """
        Scans for new devices and return a list containing found device ids.
        """

        self._update_info()

        return [device.mac for device in self.last_results]

    def get_device_name(self, mac):
        """ Returns the name of the given device or None if we don't know. """

        filter_named = [device.name for device in self.last_results
                        if device.mac == mac]

        if filter_named:
            return filter_named[0]
        else:
            return None

    @Throttle(MIN_TIME_BETWEEN_SCANS)
    def _update_info(self):
        """
        Scans the network for devices.
        Returns boolean if scanning successful.
        """
        _LOGGER.info("Scanning")

        from nmap import PortScanner, PortScannerError
        scanner = PortScanner()

        options = "-F --host-timeout 5"
        exclude_targets = set()
        if self.home_interval:
            now = dt_util.now()
            for host in self.last_results:
                if host.last_update + self.home_interval > now:
                    exclude_targets.add(host)
            if len(exclude_targets) > 0:
                target_list = [t.ip for t in exclude_targets]
                options += " --exclude {}".format(",".join(target_list))

        try:
            result = scanner.scan(hosts=self.hosts, arguments=options)
        except PortScannerError:
            return False

        now = dt_util.now()
        self.last_results = []
        for ipv4, info in result['scan'].items():
            if info['status']['state'] != 'up':
                continue
            name = info['hostnames'][0] if info['hostnames'] else ipv4
            # Mac address only returned if nmap ran as root
            mac = info['addresses'].get('mac') or _arp(ipv4)
            if mac is None:
                continue
            device = Device(mac.upper(), name, ipv4, now)
            self.last_results.append(device)
        self.last_results.extend(exclude_targets)

        _LOGGER.info("nmap scan successful")
        return True
<commit_msg>NMap: fix hostname resolver<commit_after>"""
homeassistant.components.device_tracker.nmap
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Device tracker platform that supports scanning a network with nmap.

Configuration:

To use the nmap tracker you will need to add something like the following
to your configuration.yaml file.

device_tracker:
  platform: nmap_tracker
  hosts: 192.168.1.1/24

Variables:

hosts
*Required
The IP addresses to scan in the network-prefix notation (192.168.1.1/24) or
the range notation (192.168.1.1-255).

home_interval
*Optional
Number of minutes it will not scan devices that it found in previous results.
This is to save battery.
"""
import logging
from datetime import timedelta
from collections import namedtuple
import subprocess
import re

import homeassistant.util.dt as dt_util
from homeassistant.const import CONF_HOSTS
from homeassistant.helpers import validate_config
from homeassistant.util import Throttle, convert
from homeassistant.components.device_tracker import DOMAIN

# Return cached results if last scan was less then this time ago
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=5)

_LOGGER = logging.getLogger(__name__)

# interval in minutes to exclude devices from a scan while they are home
CONF_HOME_INTERVAL = "home_interval"

REQUIREMENTS = ['python-nmap==0.4.3']

def get_scanner(hass, config):
    """ Validates config and returns a Nmap scanner. """
    if not validate_config(config, {DOMAIN: [CONF_HOSTS]},
                           _LOGGER):
        return None

    scanner = NmapDeviceScanner(config[DOMAIN])

    return scanner if scanner.success_init else None

Device = namedtuple("Device", ["mac", "name", "ip", "last_update"])

def _arp(ip_address):
    """ Get the MAC address for a given IP. """
    cmd = ['arp', '-n', ip_address]
    arp = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    out, _ = arp.communicate()
    match = re.search(r'(([0-9A-Fa-f]{1,2}\:){5}[0-9A-Fa-f]{1,2})', str(out))
    if match:
        return match.group(0)
    _LOGGER.info("No MAC address found for %s", ip_address)
    return None

class NmapDeviceScanner(object):
    """ This class scans for devices using nmap. """

    def __init__(self, config):
        self.last_results = []

        self.hosts = config[CONF_HOSTS]
        minutes = convert(config.get(CONF_HOME_INTERVAL), int, 0)
        self.home_interval = timedelta(minutes=minutes)

        self.success_init = self._update_info()
        _LOGGER.info("nmap scanner initialized")

    def scan_devices(self):
        """
        Scans for new devices and return a list containing found device ids.
        """

        self._update_info()

        return [device.mac for device in self.last_results]

    def get_device_name(self, mac):
        """ Returns the name of the given device or None if we don't know. """

        filter_named = [device.name for device in self.last_results
                        if device.mac == mac]

        if filter_named:
            return filter_named[0]
        else:
            return None

    @Throttle(MIN_TIME_BETWEEN_SCANS)
    def _update_info(self):
        """
        Scans the network for devices.
        Returns boolean if scanning successful.
        """
        _LOGGER.info("Scanning")

        from nmap import PortScanner, PortScannerError
        scanner = PortScanner()

        options = "-F --host-timeout 5"
        exclude_targets = set()
        if self.home_interval:
            now = dt_util.now()
            for host in self.last_results:
                if host.last_update + self.home_interval > now:
                    exclude_targets.add(host)
            if exclude_targets:
                options += " --exclude {}".format(",".join(t.ip for t
                                                           in exclude_targets))

        try:
            result = scanner.scan(hosts=self.hosts, arguments=options)
        except PortScannerError:
            return False

        now = dt_util.now()
        self.last_results = []
        for ipv4, info in result['scan'].items():
            if info['status']['state'] != 'up':
                continue
            name = info['hostnames'][0]['name'] if info['hostnames'] else ipv4
            # Mac address only returned if nmap ran as root
            mac = info['addresses'].get('mac') or _arp(ipv4)
            if mac is None:
                continue
            device = Device(mac.upper(), name, ipv4, now)
            self.last_results.append(device)
        self.last_results.extend(exclude_targets)

        _LOGGER.info("nmap scan successful")
        return True
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
Created on Tue Nov  3 21:14:25 2015

@author: Suhas Somnath, Chris Smith
"""

# cannot import unicode_literals since it is not compatible with h5py just yet
from __future__ import division, print_function, absolute_import
from multiprocessing import cpu_count
from time import strftime
from psutil import virtual_memory as vm

import h5py
import numpy as np

__all__ = ['getAvailableMem', 'getTimeStamp', 'uiGetFile', 'transformToTargetType', 'transformToReal',
           'complex_to_float', 'compound_to_scalar', 'realToComplex', 'realToCompound', 'check_dtype',
           'recommendCores']

def getTimeStamp():
    """
    Teturns the current date and time as a string formatted as:
    Year_Month_Dat-Hour_Minute_Second

    Parameters
    ----------
    None

    Returns
    -------
    String
    """
    return strftime('%Y_%m_%d-%H_%M_%S')

def getAvailableMem():
    """
    Returns the available memory

    Chris Smith -- csmith55@utk.edu

    Parameters
    ----------
    None

    Returns
    -------
    mem : unsigned int
        Memory in bytes
    """
    import sys
    mem = vm().available

    if sys.maxsize <= 2**32:
        mem = min([mem, sys.maxsize])

    return mem

def recommendCores(num_jobs, requested_cores=None, lengthy_computation=False):
    """
    Decides the number of cores to use for parallel computing

    Parameters
    ----------
    num_jobs : unsigned int
        Number of times a parallel operation needs to be performed
    requested_cores : unsigned int (Optional. Default = None)
        Number of logical cores to use for computation
    lengthy_computation : Boolean (Optional. Default = False)
        Whether or not each computation takes a long time. If each computation is quick, it may not make sense to take
        a hit in terms of starting and using a larger number of cores, so use fewer cores instead.
        Eg- BE SHO fitting is fast (<1 sec) so set this value to False,
        Eg- Bayesian Inference is very slow (~ 10-20 sec)so set this to True

    Returns
    -------
    requested_cores : unsigned int
        Number of logical cores to use for computation
    """

    max_cores = max(1, cpu_count() - 2)

    if requested_cores is None:
        # conservative allocation
        requested_cores = max_cores
    else:
        # Respecting the explicit request
        requested_cores = min(int(abs(requested_cores)), cpu_count())

    recom_chunks = int(num_jobs / requested_cores)

    if not lengthy_computation:
        if requested_cores > 1 and recom_chunks < 10:
            recom_chunks = 20
            # intelligently set the cores now.
            requested_cores = min(requested_cores, int(num_jobs / recom_chunks))
            # print('Not enough jobs per core. Reducing cores to {}'.format(recom_cores))

    return requested_cores

def complex_to_float(ds_main):
    """
    Function to convert a complex ND numpy array or HDF5 dataset into a scalar dataset

    Parameters
    ----------
    ds_main : complex ND numpy array or ND HDF5 dataset
        Dataset of interest

    Returns
    -------
    retval : ND real numpy array
    """
    return np.hstack([np.real(ds_main), np.imag(ds_main)])

def compound_to_scalar(ds_main):
    """
    Converts a compound ND numpy array or HDF5 dataset into a real scalar dataset

    Parameters
    ----------
    ds_main : ND numpy array or ND HDF5 dataset object of compound datatype
        Dataset of interest

    Returns
    -------
    retval : ND real numpy array

    """
    if isinstance(ds_main, h5py.Dataset):
        return np.hstack([np.float32(ds_main[name]) for name in ds_main.dtype.names])
    elif isinstance(ds_main, np.ndarray):
        return np.hstack([ds_main[name] for name in ds_main.dtype.names])
    else:
        raise TypeError('Datatype {} not supported in compound_to_scalar'.format(type(ds_main)))

def check_dtype(ds_main):
    """
    Checks the datatype of the input dataset and provides the appropriate
    function calls to convert it to a float

    Parameters
    ----------
    ds_main : HDF5 Dataset
        Dataset of interest

    Returns
    -------
    func : function
        function that will convert the dataset to a float
    is_complex : Boolean
        is the input dataset complex?
    is_compound : Boolean
        is the input dataset compound?
    n_features : Unsigned integer, the length of the 2nd dimension of
        the data after func is called on it
    n_samples : Unsigned integer
        the length of the 1st dimension of the data
    type_mult : Unsigned integer
        multiplier that converts from the typesize of the input dtype to the
        typesize of the data after func is run on it
    """
    is_complex = False
    is_compound = False
    in_dtype = ds_main.dtype
    new_dtype = ds_main.dtype
    n_samples, n_features = ds_main.shape
    if ds_main.dtype in [np.complex64, np.complex128, np.complex]:
        is_complex = True
        new_dtype = np.real(ds_main[0, 0]).dtype
        type_mult = new_dtype.itemsize * 2
        func = complex_to_float
        n_features *= 2
    elif len(ds_main.dtype) > 0:
        """
        Some form of compound datatype is in use
        We only support real scalars for the component types at the current time
        """
        is_compound = True
        new_dtype = np.float32
        type_mult = len(in_dtype) * new_dtype(0).itemsize
        func = compound_to_scalar
        n_features *= len(in_dtype)
    else:
        if ds_main.dtype not in [np.float32, np.float64]:
            new_dtype = np.float32
        else:
            new_dtype = ds_main.dtype.type

        type_mult = new_dtype(0).itemsize

        func = new_dtype

    return func, is_complex, is_compound, n_features, n_samples, type_mult

def realToComplex(ds_real):
    """
    Puts the real and imaginary sections together to make complex dataset

    Parameters
    ------------
    ds_real : 2D real numpy array or HDF5 dataset
        Data arranged as [instance, 2 x features]
        where the first half of the features are the real component and the
        second half contains the imaginary components

    Returns
    ----------
    ds_compound : 2D complex numpy array
        Data arranged as [sample, features]
    """
    return ds_real[:, :int(0.5 * ds_real.shape[1])] + 1j * ds_real[:, int(0.5 * ds_real.shape[1]):]

def realToCompound(ds_real, compound_type):
    """
    Converts a real dataset to a compound dataset of the provided compound d-type

    Parameters
    ------------
    ds_real : 2D real numpy array or HDF5 dataset
        Data arranged as [instance, features]
    compound_type : dtype
        Target complex datatype

    Returns
    ----------
    ds_compound : 2D complex numpy array
        Data arranged as [sample, features]
    """
    new_spec_length = ds_real.shape[1]/len(compound_type)
    if new_spec_length % 1:
        raise TypeError('Provided compound type was not compatible by numbr of elements')

    new_spec_length = int(new_spec_length)
    ds_compound = np.empty([ds_real.shape[0], new_spec_length], dtype=compound_type)
    for iname, name in enumerate(compound_type.names):
        istart = iname * ds_compound.shape[1]
        iend = (iname + 1) * ds_compound.shape[1]
        ds_compound[name] = ds_real[:, istart:iend]

    return np.squeeze(ds_compound)

def transformToTargetType(ds_real, new_dtype):
    """
    Transforms real data into the target dtype

    Parameters
    ----------
    ds_real : nD real numpy array or HDF5 dataset
        Source dataset
    new_dtype : dtype
        Target data type

    Returns
    ----------
    ret_val : nD numpy array
        Data of the target data type
    """
    if new_dtype in [np.complex64, np.complex128, np.complex]:
        return realToComplex(ds_real)
    elif len(new_dtype) > 0:
        return realToCompound(ds_real, new_dtype)
    else:
        return new_dtype.type(ds_real)

def transformToReal(ds_main):
    """
    Transforms real data into the target dtype

    Parameters
    ----------
    ds_main : nD compound, complex or real numpy array or HDF5 dataset
        Data that could be compound, complex or real

    Returns
    ----------
    ds_main : nD numpy array
        Data raveled to a float data type
    """
    if ds_main.dtype in [np.complex64, np.complex128, np.complex]:
        return complex_to_float(ds_main)
    elif len(ds_main.dtype) > 0:
        return compound_to_scalar(ds_main)
    else:
        return ds_main<commit_msg>removed uitGetfile from __all__ in io_utils. Now possible to install pycroscopy<commit_after># -*- coding: utf-8 -*-
"""
Created on Tue Nov  3 21:14:25 2015

@author: Suhas Somnath, Chris Smith
"""

# cannot import unicode_literals since it is not compatible with h5py just yet
from __future__ import division, print_function, absolute_import
from multiprocessing import cpu_count
from time import strftime
from psutil import virtual_memory as vm
import h5py
import numpy as np

__all__ = ['getAvailableMem', 'getTimeStamp', 'transformToTargetType', 'transformToReal',
           'complex_to_float', 'compound_to_scalar', 'realToComplex', 'realToCompound', 'check_dtype',
           'recommendCores']

def getTimeStamp():
    """
    Teturns the current date and time as a string formatted as:
    Year_Month_Dat-Hour_Minute_Second

    Parameters
    ----------
    None

    Returns
    -------
    String
    """
    return strftime('%Y_%m_%d-%H_%M_%S')

def getAvailableMem():
    """
    Returns the available memory

    Chris Smith -- csmith55@utk.edu

    Parameters
    ----------
    None

    Returns
    -------
    mem : unsigned int
        Memory in bytes
    """
    import sys
    mem = vm().available

    if sys.maxsize <= 2**32:
        mem = min([mem, sys.maxsize])

    return mem

def recommendCores(num_jobs, requested_cores=None, lengthy_computation=False):
    """
    Decides the number of cores to use for parallel computing

    Parameters
    ----------
    num_jobs : unsigned int
        Number of times a parallel operation needs to be performed
    requested_cores : unsigned int (Optional. Default = None)
        Number of logical cores to use for computation
    lengthy_computation : Boolean (Optional. Default = False)
        Whether or not each computation takes a long time. If each computation is quick, it may not make sense to take
        a hit in terms of starting and using a larger number of cores, so use fewer cores instead.
        Eg- BE SHO fitting is fast (<1 sec) so set this value to False,
        Eg- Bayesian Inference is very slow (~ 10-20 sec)so set this to True

    Returns
    -------
    requested_cores : unsigned int
        Number of logical cores to use for computation
    """

    max_cores = max(1, cpu_count() - 2)

    if requested_cores is None:
        # conservative allocation
        requested_cores = max_cores
    else:
        # Respecting the explicit request
        requested_cores = min(int(abs(requested_cores)), cpu_count())

    recom_chunks = int(num_jobs / requested_cores)

    if not lengthy_computation:
        if requested_cores > 1 and recom_chunks < 10:
            recom_chunks = 20
            # intelligently set the cores now.
            requested_cores = min(requested_cores, int(num_jobs / recom_chunks))
            # print('Not enough jobs per core. Reducing cores to {}'.format(recom_cores))

    return requested_cores

def complex_to_float(ds_main):
    """
    Function to convert a complex ND numpy array or HDF5 dataset into a scalar dataset

    Parameters
    ----------
    ds_main : complex ND numpy array or ND HDF5 dataset
        Dataset of interest

    Returns
    -------
    retval : ND real numpy array
    """
    return np.hstack([np.real(ds_main), np.imag(ds_main)])

def compound_to_scalar(ds_main):
    """
    Converts a compound ND numpy array or HDF5 dataset into a real scalar dataset

    Parameters
    ----------
    ds_main : ND numpy array or ND HDF5 dataset object of compound datatype
        Dataset of interest

    Returns
    -------
    retval : ND real numpy array

    """
    if isinstance(ds_main, h5py.Dataset):
        return np.hstack([np.float32(ds_main[name]) for name in ds_main.dtype.names])
    elif isinstance(ds_main, np.ndarray):
        return np.hstack([ds_main[name] for name in ds_main.dtype.names])
    else:
        raise TypeError('Datatype {} not supported in compound_to_scalar'.format(type(ds_main)))

def check_dtype(ds_main):
    """
    Checks the datatype of the input dataset and provides the appropriate
    function calls to convert it to a float

    Parameters
    ----------
    ds_main : HDF5 Dataset
        Dataset of interest

    Returns
    -------
    func : function
        function that will convert the dataset to a float
    is_complex : Boolean
        is the input dataset complex?
    is_compound : Boolean
        is the input dataset compound?
    n_features : Unsigned integer, the length of the 2nd dimension of
        the data after func is called on it
    n_samples : Unsigned integer
        the length of the 1st dimension of the data
    type_mult : Unsigned integer
        multiplier that converts from the typesize of the input dtype to the
        typesize of the data after func is run on it
    """
    is_complex = False
    is_compound = False
    in_dtype = ds_main.dtype
    new_dtype = ds_main.dtype
    n_samples, n_features = ds_main.shape
    if ds_main.dtype in [np.complex64, np.complex128, np.complex]:
        is_complex = True
        new_dtype = np.real(ds_main[0, 0]).dtype
        type_mult = new_dtype.itemsize * 2
        func = complex_to_float
        n_features *= 2
    elif len(ds_main.dtype) > 0:
        """
        Some form of compound datatype is in use
        We only support real scalars for the component types at the current time
        """
        is_compound = True
        new_dtype = np.float32
        type_mult = len(in_dtype) * new_dtype(0).itemsize
        func = compound_to_scalar
        n_features *= len(in_dtype)
    else:
        if ds_main.dtype not in [np.float32, np.float64]:
            new_dtype = np.float32
        else:
            new_dtype = ds_main.dtype.type

        type_mult = new_dtype(0).itemsize

        func = new_dtype

    return func, is_complex, is_compound, n_features, n_samples, type_mult

def realToComplex(ds_real):
    """
    Puts the real and imaginary sections together to make complex dataset

    Parameters
    ------------
    ds_real : 2D real numpy array or HDF5 dataset
        Data arranged as [instance, 2 x features]
        where the first half of the features are the real component and the
        second half contains the imaginary components

    Returns
    ----------
    ds_compound : 2D complex numpy array
        Data arranged as [sample, features]
    """
    return ds_real[:, :int(0.5 * ds_real.shape[1])] + 1j * ds_real[:, int(0.5 * ds_real.shape[1]):]

def realToCompound(ds_real, compound_type):
    """
    Converts a real dataset to a compound dataset of the provided compound d-type

    Parameters
    ------------
    ds_real : 2D real numpy array or HDF5 dataset
        Data arranged as [instance, features]
    compound_type : dtype
        Target complex datatype

    Returns
    ----------
    ds_compound : 2D complex numpy array
        Data arranged as [sample, features]
    """
    new_spec_length = ds_real.shape[1]/len(compound_type)
    if new_spec_length % 1:
        raise TypeError('Provided compound type was not compatible by numbr of elements')

    new_spec_length = int(new_spec_length)
    ds_compound = np.empty([ds_real.shape[0], new_spec_length], dtype=compound_type)
    for iname, name in enumerate(compound_type.names):
        istart = iname * ds_compound.shape[1]
        iend = (iname + 1) * ds_compound.shape[1]
        ds_compound[name] = ds_real[:, istart:iend]

    return np.squeeze(ds_compound)

def transformToTargetType(ds_real, new_dtype):
    """
    Transforms real data into the target dtype

    Parameters
    ----------
    ds_real : nD real numpy array or HDF5 dataset
        Source dataset
    new_dtype : dtype
        Target data type

    Returns
    ----------
    ret_val : nD numpy array
        Data of the target data type
    """
    if new_dtype in [np.complex64, np.complex128, np.complex]:
        return realToComplex(ds_real)
    elif len(new_dtype) > 0:
        return realToCompound(ds_real, new_dtype)
    else:
        return new_dtype.type(ds_real)

def transformToReal(ds_main):
    """
    Transforms real data into the target dtype

    Parameters
    ----------
    ds_main : nD compound, complex or real numpy array or HDF5 dataset
        Data that could be compound, complex or real

    Returns
    ----------
    ds_main : nD numpy array
        Data raveled to a float data type
    """
    if ds_main.dtype in [np.complex64, np.complex128, np.complex]:
        return complex_to_float(ds_main)
    elif len(ds_main.dtype) > 0:
        return compound_to_scalar(ds_main)
    else:
        return ds_main<|endoftext|>


<commit_before>##########################################################################
#
#  Copyright (c) 2013, Image Engine Design Inc. All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions are
#  met:
#
#      * Redistributions of source code must retain the above
#        copyright notice, this list of conditions and the following
#        disclaimer.
#
#      * Redistributions in binary form must reproduce the above
#        copyright notice, this list of conditions and the following
#        disclaimer in the documentation and/or other materials provided with
#        the distribution.
#
#      * Neither the name of John Haddon nor the names of
#        any other contributors to this software may be used to endorse or
#        promote products derived from this software without specific prior
#        written permission.
#
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
#  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
#  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
#  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
#  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
#  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
#  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
#  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
#  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
##########################################################################

import re
import os

import IECore

import Gaffer
import GafferUI

## A command suitable for use with NodeMenu.append(), to add a menu
# item for the creation of a Box from the current selection. We don't
# actually append it automatically, but instead let the startup files
# for particular applications append it if it suits their purposes.
def nodeMenuCreateCommand( menu ) :

	nodeGraph = menu.ancestor( GafferUI.NodeGraph )
	assert( nodeGraph is not None )

	script = nodeGraph.scriptNode()
	graphGadget = nodeGraph.graphGadgetWidget().getViewportGadget().getChild()

	return Gaffer.Box.create( graphGadget.getRoot(), script.selection() )

## A callback suitable for use with NodeGraph.nodeContextMenuSignal - it provides
# menu options specific to Boxes. We don't actually register it automatically,
# but instead let the startup files for particular applications register
# it if it suits their purposes.
def appendNodeContextMenuDefinitions( nodeGraph, node, menuDefinition ) :

	if not isinstance( node, Gaffer.Box ) :
		return

	menuDefinition.append( "/BoxDivider", { "divider" : True } )
	menuDefinition.append( "/Show Contents...", { "command" : IECore.curry( __showContents, nodeGraph, node ) } )

def __showContents( nodeGraph, box ) :

	GafferUI.NodeGraph.acquire( box )

# NodeUI
##########################################################################

class BoxNodeUI( GafferUI.StandardNodeUI ) :

	def __init__( self, node, displayMode = None, **kw ) :

		GafferUI.StandardNodeUI.__init__( self, node, displayMode, **kw )

		## \todo Maybe this should become a customisable part of the StandardNodeUI - if so then
		# perhaps we need to integrate it with the existing presets menu in ParameterisedHolderNodeUI.
		toolButton = GafferUI.MenuButton( image = "gear.png", hasFrame=False )
		toolButton.setMenu( GafferUI.Menu( Gaffer.WeakMethod( self._toolMenuDefinition ) ) )

		self._tabbedContainer().setCornerWidget( toolButton )

	def _toolMenuDefinition( self ) :

		result = IECore.MenuDefinition()
		result.append( "/Export for referencing...", { "command" : Gaffer.WeakMethod( self.__exportForReferencing ) } )

		return result

	def __exportForReferencing( self ) :

		path = Gaffer.FileSystemPath( os.getcwd() )

		path.setFilter( Gaffer.FileSystemPath.createStandardFilter( [ "grf" ] ) )

		dialogue = GafferUI.PathChooserDialogue( path, title="Export for referencing", confirmLabel="Export" )
		path = dialogue.waitForPath( parentWindow = self.ancestor( GafferUI.Window ) )

		if not path :
			return

		path = str( path )
		if not path.endswith( ".grf" ) :
			path += ".grf"

		self.node().exportForReference( path )

GafferUI.NodeUI.registerNodeUI( Gaffer.Box.staticTypeId(), BoxNodeUI )

# PlugValueWidget registrations
##########################################################################

GafferUI.PlugValueWidget.registerCreator( Gaffer.Box.staticTypeId(), re.compile( "in[0-9]*" ), None )
GafferUI.PlugValueWidget.registerCreator( Gaffer.Box.staticTypeId(), re.compile( "out[0-9]*" ), None )

# Plug promotion
##########################################################################

def __promoteToBox( box, plug ) :

	with Gaffer.UndoContext( box.ancestor( Gaffer.ScriptNode.staticTypeId() ) ) :
		box.promotePlug( plug )

def __plugPopupMenu( menuDefinition, plugValueWidget ) :

	plug = plugValueWidget.getPlug()
	node = plug.node()
	if node is None :
		return

	box = node.ancestor( Gaffer.Box.staticTypeId() )
	if box is None :
		return

	if not box.canPromotePlug( plug ) :
		return

	menuDefinition.append( "/BoxDivider", { "divider" : True } )
	menuDefinition.append( "/Promote to %s" % box.getName(), { "command" : IECore.curry( __promoteToBox, box, plug ) } )

__plugPopupMenuConnection = GafferUI.PlugValueWidget.popupMenuSignal().connect( __plugPopupMenu )
<commit_msg>Added "Unpromote from Box" item to plug popup menu.<commit_after>##########################################################################
#
#  Copyright (c) 2013, Image Engine Design Inc. All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions are
#  met:
#
#      * Redistributions of source code must retain the above
#        copyright notice, this list of conditions and the following
#        disclaimer.
#
#      * Redistributions in binary form must reproduce the above
#        copyright notice, this list of conditions and the following
#        disclaimer in the documentation and/or other materials provided with
#        the distribution.
#
#      * Neither the name of John Haddon nor the names of
#        any other contributors to this software may be used to endorse or
#        promote products derived from this software without specific prior
#        written permission.
#
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
#  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
#  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
#  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
#  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
#  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
#  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
#  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
#  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
##########################################################################

import re
import os

import IECore

import Gaffer
import GafferUI

## A command suitable for use with NodeMenu.append(), to add a menu
# item for the creation of a Box from the current selection. We don't
# actually append it automatically, but instead let the startup files
# for particular applications append it if it suits their purposes.
def nodeMenuCreateCommand( menu ) :

	nodeGraph = menu.ancestor( GafferUI.NodeGraph )
	assert( nodeGraph is not None )

	script = nodeGraph.scriptNode()
	graphGadget = nodeGraph.graphGadgetWidget().getViewportGadget().getChild()

	return Gaffer.Box.create( graphGadget.getRoot(), script.selection() )

## A callback suitable for use with NodeGraph.nodeContextMenuSignal - it provides
# menu options specific to Boxes. We don't actually register it automatically,
# but instead let the startup files for particular applications register
# it if it suits their purposes.
def appendNodeContextMenuDefinitions( nodeGraph, node, menuDefinition ) :

	if not isinstance( node, Gaffer.Box ) :
		return

	menuDefinition.append( "/BoxDivider", { "divider" : True } )
	menuDefinition.append( "/Show Contents...", { "command" : IECore.curry( __showContents, nodeGraph, node ) } )

def __showContents( nodeGraph, box ) :

	GafferUI.NodeGraph.acquire( box )

# NodeUI
##########################################################################

class BoxNodeUI( GafferUI.StandardNodeUI ) :

	def __init__( self, node, displayMode = None, **kw ) :

		GafferUI.StandardNodeUI.__init__( self, node, displayMode, **kw )

		## \todo Maybe this should become a customisable part of the StandardNodeUI - if so then
		# perhaps we need to integrate it with the existing presets menu in ParameterisedHolderNodeUI.
		toolButton = GafferUI.MenuButton( image = "gear.png", hasFrame=False )
		toolButton.setMenu( GafferUI.Menu( Gaffer.WeakMethod( self._toolMenuDefinition ) ) )

		self._tabbedContainer().setCornerWidget( toolButton )

	def _toolMenuDefinition( self ) :

		result = IECore.MenuDefinition()
		result.append( "/Export for referencing...", { "command" : Gaffer.WeakMethod( self.__exportForReferencing ) } )

		return result

	def __exportForReferencing( self ) :

		path = Gaffer.FileSystemPath( os.getcwd() )

		path.setFilter( Gaffer.FileSystemPath.createStandardFilter( [ "grf" ] ) )

		dialogue = GafferUI.PathChooserDialogue( path, title="Export for referencing", confirmLabel="Export" )
		path = dialogue.waitForPath( parentWindow = self.ancestor( GafferUI.Window ) )

		if not path :
			return

		path = str( path )
		if not path.endswith( ".grf" ) :
			path += ".grf"

		self.node().exportForReference( path )

GafferUI.NodeUI.registerNodeUI( Gaffer.Box.staticTypeId(), BoxNodeUI )

# PlugValueWidget registrations
##########################################################################

GafferUI.PlugValueWidget.registerCreator( Gaffer.Box.staticTypeId(), re.compile( "in[0-9]*" ), None )
GafferUI.PlugValueWidget.registerCreator( Gaffer.Box.staticTypeId(), re.compile( "out[0-9]*" ), None )

# Plug promotion
##########################################################################

def __promoteToBox( box, plug ) :

	with Gaffer.UndoContext( box.ancestor( Gaffer.ScriptNode.staticTypeId() ) ) :
		box.promotePlug( plug )

def __unpromoteFromBox( box, plug ) :

	with Gaffer.UndoContext( box.ancestor( Gaffer.ScriptNode.staticTypeId() ) ) :
		box.unpromotePlug( plug )

def __plugPopupMenu( menuDefinition, plugValueWidget ) :

	plug = plugValueWidget.getPlug()
	node = plug.node()
	if node is None :
		return

	box = node.ancestor( Gaffer.Box.staticTypeId() )
	if box is None :
		return

	if box.canPromotePlug( plug ) :

		menuDefinition.append( "/BoxDivider", { "divider" : True } )
		menuDefinition.append( "/Promote to %s" % box.getName(), { "command" : IECore.curry( __promoteToBox, box, plug ) } )

	elif box.plugIsPromoted( plug ) :

		# Add a menu item to unpromote the plug, replacing the "Remove input" menu item if it exists

		with IECore.IgnoredExceptions( Exception ) :
			menuDefinition.remove( "/Remove input" )

		menuDefinition.append( "/BoxDivider", { "divider" : True } )
		menuDefinition.append( "/Unpromote from %s" % box.getName(), { "command" : IECore.curry( __unpromoteFromBox, box, plug ) } )

__plugPopupMenuConnection = GafferUI.PlugValueWidget.popupMenuSignal().connect( __plugPopupMenu )
<|endoftext|>


<commit_before>## account.py
# Account system support.
from pydle.features import rfc1459

class AccountSupport(rfc1459.RFC1459Support):

    ## Internal.

    def _create_user(self, nickname):
        super()._create_user(nickname)
        self.users[nickname].update({
            'account': None,
            'identified': False
        })

    def _rename_user(self, user, new):
        super()._rename_user(user, new)
        # Unset account info.
        self._sync_user(new, { 'account': None, 'identified': False })

    ## IRC API.

    def whois(self, nickname):
        r = super().whois(nickname)

        # Add own info.
        if nickname in self._whois_info:
            self._whois_info[nickname].setdefault('account', None)
            self._whois_info[nickname].setdefault('identified', False)

        return r

    ## Message handlers.

    def on_raw_307(self, message):
        """ WHOIS: User has identified for this nickname. (Anope) """
        target, nickname = message.params[:2]
        info = {
            'identified': True
        }

        if nickname in self.users:
            self._sync_user(nickname, info)
        if nickname in self._requests['whois']:
            self._whois_info[nickname].update(info)

    def on_raw_330(self, message):
        """ WHOIS account name (Atheme). """
        target, nickname, account = message.params[:3]
        info = {
            'account': account,
            'identified': True
        }

        if nickname in self.users:
            self._sync_user(nickname, info)
        if nickname in self._requests['whois']:
            self._whois_info[nickname].update(info)
<commit_msg>Fix variable naming in features.account.<commit_after>## account.py
# Account system support.
from pydle.features import rfc1459

class AccountSupport(rfc1459.RFC1459Support):

    ## Internal.

    def _create_user(self, nickname):
        super()._create_user(nickname)
        self.users[nickname].update({
            'account': None,
            'identified': False
        })

    def _rename_user(self, user, new):
        super()._rename_user(user, new)
        # Unset account info.
        self._sync_user(new, { 'account': None, 'identified': False })

    ## IRC API.

    def whois(self, nickname):
        future = super().whois(nickname)

        # Add own info.
        if nickname in self._whois_info:
            self._whois_info[nickname].setdefault('account', None)
            self._whois_info[nickname].setdefault('identified', False)

        return future

    ## Message handlers.

    def on_raw_307(self, message):
        """ WHOIS: User has identified for this nickname. (Anope) """
        target, nickname = message.params[:2]
        info = {
            'identified': True
        }

        if nickname in self.users:
            self._sync_user(nickname, info)
        if nickname in self._requests['whois']:
            self._whois_info[nickname].update(info)

    def on_raw_330(self, message):
        """ WHOIS account name (Atheme). """
        target, nickname, account = message.params[:3]
        info = {
            'account': account,
            'identified': True
        }

        if nickname in self.users:
            self._sync_user(nickname, info)
        if nickname in self._requests['whois']:
            self._whois_info[nickname].update(info)
<|endoftext|>


<commit_before>#////////////////////////////////////////////////////////////////
#//                                                            //
#//  Python modules                                            //
#//                                                            //
#// ---------------------------------------------------------- //
#//                                                            //
#//  AUTHOR: Miguel Ramos Pernas                               //
#//  e-mail: miguel.ramos.pernas@cern.ch                       //
#//                                                            //
#//  Last update: 11/12/2015                                   //
#//                                                            //
#// ---------------------------------------------------------- //
#//                                                            //
#//  Description:                                              //
#//                                                            //
#//  This module implements different tools to generate plots  //
#//  using Root objects.                                       //
#//                                                            //
#// ---------------------------------------------------------- //
#////////////////////////////////////////////////////////////////

from ROOT import ( TCanvas, TLegend, TPaveText, gStyle,
                   TGraph, TGraphErrors,
                   TH1F, TH1D, TH1I,
                   TH2F, TH2D, TH2I,
                   kBlue, kRed, kOrange, kGreen, kMagenta, kCyan )
from array import array
from math import sqrt
import sys
from Isis.MathExt import IsSquare, GreaterComDiv

#_______________________________________________________________________________
# This class allows to generate a color list to iter over. The colors are given
# by < __getitem__ > method or in an iteration process. The number of times the
# given index is greater than the number of colors in the list, corresponds to
# the number that is added to the remainder that araises from the division.
class ColorList:

    def __init__( self, *args ):
        ''' A set of colors can be specified in the constructor as < args > '''
        self.Iter = 0
        if args: self.Colors = args
        else:    self.Colors = [ kBlue, kRed, kOrange, kGreen, kMagenta, kCyan ]

    def __getitem__( self, idx ):
        ''' Gets the color for the given index '''
        return self.Colors[ idx % len( self.Colors ) ] + idx/len( self.Colors )

    def __iter__( self ):
        ''' Definition of the iterator '''
        self.Iter = 0
        return self

    def next( self ):
        ''' Sets the new value for the iteration. In order to use this class in an
        iterative mode, another iterable object has to be the one that raises the
        exception to stop the iteration. '''
        nloop = self.Iter / len( self.Colors )
        niter = self.Iter % len( self.Colors )
        self.Iter += 1
        return self.Colors[ niter ] + nloop

#_______________________________________________________________________________
# This function imports different plot modules from Root
def ImportPlotModules():
    glob = sys._getframe( 1 ).f_globals
    loc  = sys._getframe( 1 ).f_locals
    modlist = [ "gROOT", "TBrowser",
                "TDirectory", "TDirectoryFile", "gDirectory", "TFile",
                "TTree", "TBranch", "TLeaf",
                "TCanvas", "TPave", "TPaveText", "TLegend",
                "TH1D", "TH1F", "TH1I",
                "TH2D", "TH2F", "TH2I",
                "TGraph", "TGraphErrors",
                "TF1", "TF2", "TLine",
                "TColor",
                "kBlue", "kViolet", "kMagenta", "kPink",
                "kRed", "kOrange", "kYellow",
                "kSpring", "kGreen", "kTeal", "kCyan", "kAzure",
                "kWhite", "kBlack", "kGray" ]
    glob[ "ROOT" ] = __import__( "ROOT" )
    for el in modlist:
        glob[ el ] = __import__( "ROOT." + el, glob, loc, [ '*' ] )

#_______________________________________________________________________________
# Function to generate a Root histogram given a list. By default no ytitle is drawn, but it
# can be set with the < ytitle > option
def MakeHistogram( var, wvar = False, **kwargs ):
    if "name" in kwargs: name = kwargs[ "name" ]
    else: name = "hist"
    if "title" in kwargs: title = kwargs[ "title" ]
    else: title = "hist"
    if "nbins" in kwargs: nbins = kwargs[ "nbins" ]
    else: nbins = 100
    if "xtitle" in kwargs: xtitle = kwargs[ "xtitle" ]
    else: xtitle = name
    if "vmax" in kwargs: vmax = kwargs[ "vmax" ]
    else: vmax = max( var )
    if "vmin" in kwargs: vmin = kwargs[ "vmin" ]
    else: vmin = min( var )
    if "vtype" in kwargs: tp = kwargs[ "vtype" ]
    else: tp = "double"
    if tp == "float":
        hist = TH1F( name, title, nbins, vmin, vmax )
    elif tp == "double":
        hist = TH1D( name, title, nbins, vmin, vmax )
    elif tp == "int":
        hist = TH1I( name, title, nbins, vmin, vmax )
    else:
        print "Histogram type", tp, "not known"
        return
    if wvar:
        for el, w in zip( var, wvar ):
            hist.Fill( el, w )
    else:
        for el in var:
            hist.Fill( el )
    hist.GetXaxis().SetTitle( xtitle )
    if "ytitle" in kwargs:
        hist.GetYaxis().SetTitle( kwargs[ "ytitle" ] )
    return hist

#_______________________________________________________________________________
# Creates a 2-dimensional histogram given two lists
def MakeHistogram2D( xvar, yvar, wvar = False, **kwargs ):
    if "name" in kwargs: name = kwargs[ "name" ]
    else: name = "hist"
    if "title" in kwargs: title = kwargs[ "title" ]
    else: title = "hist"
    if "xbins" in kwargs: xbins = kwargs[ "xbins" ]
    else: xbins = 100
    if "ybins" in kwargs: ybins = kwargs[ "ybins" ]
    else: ybins = 100
    if "xtitle" in kwargs: xtitle = kwargs[ "xtitle" ]
    else: xtitle = "X"
    if "ytitle" in kwargs: ytitle = kwargs[ "ytitle" ]
    else: ytitle = "Y"
    if "xmax" in kwargs: xmax = kwargs[ "xmax" ]
    else: xmax = min( xvar )
    if "ymax" in kwargs: ymax = kwargs[ "ymax" ]
    else: ymax = min( yvar )
    if "xmin" in kwargs: xmin = kwargs[ "xmin" ]
    else: xmin = min( xvar )
    if "ymin" in kwargs: ymin = kwargs[ "ymin" ]
    else: ymin = min( yvar )
    if "vtype" in kwargs: tp = kwargs[ "vtype" ]
    else: tp = "double"
    if tp == "float":
        hist = TH2F( name, title, xbins, xmin, xmax, ybins, ymin, ymax )
    elif tp == "double":
        hist = TH2D( name, title, xbins, xmin, xmax, ybins, ymin, ymax )
    elif tp == "int":
        hist = TH2I( name, title, xbins, xmin, xmax, ybins, ymin, ymax )
    else:
        print "Histogram type", tp, "not known"
        return
    if wvar:
        for x, y, w in zip( xvar, yvar, wvar ):
            hist.Fill( x, y, w )
    else:
        for x, y in zip( xvar, yvar ):
            hist.Fill( x, y )
    hist.GetXaxis().SetTitle( xtitle )
    hist.GetYaxis().SetTitle( ytitle )
    return hist

#_______________________________________________________________________________
# Generates a scatter plot given two lists of data
def MakeScatterPlot( xvar, yvar, xerr = False, yerr = False, **kwargs ):
    if "name" in kwargs: name = kwargs[ "name" ]
    else: name = False
    if "title" in kwargs: title = kwargs[ "title" ]
    else: title = False
    if "xtitle" in kwargs: xtitle = kwargs[ "xtitle" ]
    else: xtitle = "X"
    if "ytitle" in kwargs: ytitle = kwargs[ "ytitle" ]
    else: ytitle = "Y"
    npoints = len( xvar )
    xvar    = array( 'd', xvar )
    yvar    = array( 'd', yvar )
    if xerr or yerr:
        if   not xerr:
            xerr = array( 'd', npoints*[ 0 ] )
            yerr = array( 'd', yerr )
        elif not yerr:
            xerr = array( 'd', yerr )
            yerr = array( 'd', npoints*[ 0 ] )
        else:
            xerr = array( 'd', xerr )
            yerr = array( 'd', yerr )
        graph = TGraphErrors( npoints, xvar, yvar, xerr, yerr )
    else:
        graph = TGraph( npoints, xvar, yvar )
    if name:
        graph.SetName( name )
    if title:
        graph.SetTitle( title )
    graph.GetXaxis().SetTitle( xtitle )
    graph.GetYaxis().SetTitle( ytitle )
    return graph

#_______________________________________________________________________________
# This function plots in the same canvas the distributions of the given
# variables from different DataManager classes. Different options can
# also been provided to modify the canvas and the information displayed.
def MultiPlot( mngrs, variables, **kwargs):
    if "colors" in kwargs: colors = ColorList( kwargs[ "colors" ] )
    else: colors = ColorList()
    if "cuts" in kwargs: cuts = kwargs[ "cuts" ]
    else: cuts = False
    if "legend" in kwargs: legend = kwargs[ "legend" ]
    else: legend = True
    if "name" in kwargs: name = kwargs[ "name" ]
    else: name = "canvas"
    if "title" in kwargs: title = kwargs[ "title" ]
    else: title = "canvas"
    if "nbins" in kwargs: nbins = kwargs[ "nbins" ]
    else: nbins = 100
    if "norm" in kwargs: norm = kwargs[ "norm" ]
    else: norm = 1

    nvars   = len( variables ) + 1
    results = {}
    if all( var in mngr.Variables for mngr in mngrs for var in variables ):
        ''' Checks if the number of variables is a square number '''
        if IsSquare( nvars ):
            nyvars = int( round( sqrt( nvars ) ) )
            nxvars = nyvars
        else:
            nyvars = GreaterComDiv( nvars )
            nxvars = nvars/nyvars

        ''' Generates and divides the canvas '''
        canvas = TCanvas( name, title )
        canvas.Divide( nxvars, nyvars )

        nmngrs = len( mngrs )
        ''' If cuts are specified it calculates the true managers '''
        if cuts:
            for i in xrange( nmngrs ):
                mngrs[ i ], mngrs[ i ].Name = mngrs[ i ].CutSample( cuts ), mngrs[ i ].Name

        ''' Disables the stat box of the histograms '''
        gStyle.SetOptStat( 0 )

        ''' Constructs the legend and the information panel if specified '''
        if legend:
            rlegend = TLegend( 0.1, 0.8 - nmngrs*0.05, 0.9, 0.9 )
            rlegend.SetHeader( "#bf{-- Legend --}" )
            rlegend.SetTextAlign( 22 )
            rlegend.SetFillColor( 17 )
            rtxtinf = TPaveText( 0.1, 0.8 - nmngrs*0.05, 0.9, 0.9 )
            rtxtinf.AddText( "-- Number of entries --" )
            rtxtinf.SetFillColor( 42 )
            rtxtinf.SetShadowColor( 0 )

        ''' Generates and draws the histograms '''
        for iv, var in enumerate( variables ):
            canvas.cd( iv + 1 )
            totlst = [ el for mngr in mngrs for el in mngr[ var ]  ]
            vmin, vmax, hists = min( totlst ), max( totlst ), []
            for im, mngr in enumerate( mngrs ):
                hname = mngr.Name + "_" + var
                hists.append( mngr.MakeHistogram( var,
                                                  name  = hname,
                                                  title = var,
                                                  nbins = nbins,
                                                  vmin  = vmin,
                                                  vmax  = vmax,
                                                  cuts  = cuts ) )
                h = hists[ -1 ]
                if norm:
                    h.Scale( float( norm )/h.GetEntries() )
                h.SetLineColor( colors[ im ] )
                if legend and iv == 0:
                    ''' In the first iteration adds the entries to the legend '''
                    rlegend.AddEntry( h, "#bf{" + mngr.Name + "}", "L" )
                    rtxtinf.AddText( mngr.Name + ": %i" % h.GetEntries() )
                results[ hname ] = h
            ''' The maximum of the y-axis in the pad is set to the 110% of the maximum
            value for all the histograms to be drawn '''
            hists[ 0 ].SetMaximum( 1.1*max( h.GetMaximum() for h in hists ) )
            for h in hists: h.Draw( "SAME" )
        if legend:
            pad = canvas.cd( nvars )
            pad.Divide( 2, 1 )
            pad.cd( 1 ); rlegend.Draw()
            pad.cd( 2 ); rtxtinf.Draw()
            results[ "legend" ] = rlegend
            results[ "info" ]   = rtxtinf
        canvas.Update()
        results[ name ] = canvas
        return results
    else:
        print "Any of the managers does not have access to some of the variables"
        return
<commit_msg>Modified MultiPlot function in PlotTools.py so now it manages better the number of input variables. If it is a prime number, the canvas will be divided as if it was one unit greater. The option to draw errors has also been added.<commit_after>#////////////////////////////////////////////////////////////////
#//                                                            //
#//  Python modules                                            //
#//                                                            //
#// ---------------------------------------------------------- //
#//                                                            //
#//  AUTHOR: Miguel Ramos Pernas                               //
#//  e-mail: miguel.ramos.pernas@cern.ch                       //
#//                                                            //
#//  Last update: 13/12/2015                                   //
#//                                                            //
#// ---------------------------------------------------------- //
#//                                                            //
#//  Description:                                              //
#//                                                            //
#//  This module implements different tools to generate plots  //
#//  using Root objects.                                       //
#//                                                            //
#// ---------------------------------------------------------- //
#////////////////////////////////////////////////////////////////

from ROOT import ( TCanvas, TLegend, TPaveText, gStyle,
                   TGraph, TGraphErrors,
                   TH1F, TH1D, TH1I,
                   TH2F, TH2D, TH2I,
                   kBlue, kRed, kOrange, kGreen, kMagenta, kCyan )
from array import array
from math import sqrt
import sys
from Isis.MathExt import Decompose, GreaterComDiv, IsPrime, IsSquare

#_______________________________________________________________________________
# This class allows to generate a color list to iter over. The colors are given
# by < __getitem__ > method or in an iteration process. The number of times the
# given index is greater than the number of colors in the list, corresponds to
# the number that is added to the remainder that araises from the division.
class ColorList:

    def __init__( self, *args ):
        ''' A set of colors can be specified in the constructor as < args > '''
        self.Iter = 0
        if args: self.Colors = args
        else:    self.Colors = [ kBlue, kRed, kOrange, kGreen, kMagenta, kCyan ]

    def __getitem__( self, idx ):
        ''' Gets the color for the given index '''
        return self.Colors[ idx % len( self.Colors ) ] + idx/len( self.Colors )

    def __iter__( self ):
        ''' Definition of the iterator '''
        self.Iter = 0
        return self

    def next( self ):
        ''' Sets the new value for the iteration. In order to use this class in an
        iterative mode, another iterable object has to be the one that raises the
        exception to stop the iteration. '''
        nloop = self.Iter / len( self.Colors )
        niter = self.Iter % len( self.Colors )
        self.Iter += 1
        return self.Colors[ niter ] + nloop

#_______________________________________________________________________________
# This function imports different plot modules from Root
def ImportPlotModules():
    glob = sys._getframe( 1 ).f_globals
    loc  = sys._getframe( 1 ).f_locals
    modlist = [ "gROOT", "TBrowser",
                "TDirectory", "TDirectoryFile", "gDirectory", "TFile",
                "TTree", "TBranch", "TLeaf",
                "TCanvas", "TPave", "TPaveText", "TLegend",
                "TH1D", "TH1F", "TH1I",
                "TH2D", "TH2F", "TH2I",
                "TGraph", "TGraphErrors",
                "TF1", "TF2", "TLine",
                "TColor",
                "kBlue", "kViolet", "kMagenta", "kPink",
                "kRed", "kOrange", "kYellow",
                "kSpring", "kGreen", "kTeal", "kCyan", "kAzure",
                "kWhite", "kBlack", "kGray" ]
    glob[ "ROOT" ] = __import__( "ROOT" )
    for el in modlist:
        glob[ el ] = __import__( "ROOT." + el, glob, loc, [ '*' ] )

#_______________________________________________________________________________
# Function to generate a Root histogram given a list. By default no ytitle is drawn, but it
# can be set with the < ytitle > option
def MakeHistogram( var, wvar = False, **kwargs ):
    if "name" in kwargs: name = kwargs[ "name" ]
    else: name = "hist"
    if "title" in kwargs: title = kwargs[ "title" ]
    else: title = "hist"
    if "nbins" in kwargs: nbins = kwargs[ "nbins" ]
    else: nbins = 100
    if "xtitle" in kwargs: xtitle = kwargs[ "xtitle" ]
    else: xtitle = name
    if "vmax" in kwargs: vmax = kwargs[ "vmax" ]
    else: vmax = max( var )
    if "vmin" in kwargs: vmin = kwargs[ "vmin" ]
    else: vmin = min( var )
    if "vtype" in kwargs: tp = kwargs[ "vtype" ]
    else: tp = "double"
    if tp == "float":
        hist = TH1F( name, title, nbins, vmin, vmax )
    elif tp == "double":
        hist = TH1D( name, title, nbins, vmin, vmax )
    elif tp == "int":
        hist = TH1I( name, title, nbins, vmin, vmax )
    else:
        print "Histogram type", tp, "not known"
        return
    if wvar:
        for el, w in zip( var, wvar ):
            hist.Fill( el, w )
    else:
        for el in var:
            hist.Fill( el )
    hist.GetXaxis().SetTitle( xtitle )
    if "ytitle" in kwargs:
        hist.GetYaxis().SetTitle( kwargs[ "ytitle" ] )
    return hist

#_______________________________________________________________________________
# Creates a 2-dimensional histogram given two lists
def MakeHistogram2D( xvar, yvar, wvar = False, **kwargs ):
    if "name" in kwargs: name = kwargs[ "name" ]
    else: name = "hist"
    if "title" in kwargs: title = kwargs[ "title" ]
    else: title = "hist"
    if "xbins" in kwargs: xbins = kwargs[ "xbins" ]
    else: xbins = 100
    if "ybins" in kwargs: ybins = kwargs[ "ybins" ]
    else: ybins = 100
    if "xtitle" in kwargs: xtitle = kwargs[ "xtitle" ]
    else: xtitle = "X"
    if "ytitle" in kwargs: ytitle = kwargs[ "ytitle" ]
    else: ytitle = "Y"
    if "xmax" in kwargs: xmax = kwargs[ "xmax" ]
    else: xmax = min( xvar )
    if "ymax" in kwargs: ymax = kwargs[ "ymax" ]
    else: ymax = min( yvar )
    if "xmin" in kwargs: xmin = kwargs[ "xmin" ]
    else: xmin = min( xvar )
    if "ymin" in kwargs: ymin = kwargs[ "ymin" ]
    else: ymin = min( yvar )
    if "vtype" in kwargs: tp = kwargs[ "vtype" ]
    else: tp = "double"
    if tp == "float":
        hist = TH2F( name, title, xbins, xmin, xmax, ybins, ymin, ymax )
    elif tp == "double":
        hist = TH2D( name, title, xbins, xmin, xmax, ybins, ymin, ymax )
    elif tp == "int":
        hist = TH2I( name, title, xbins, xmin, xmax, ybins, ymin, ymax )
    else:
        print "Histogram type", tp, "not known"
        return
    if wvar:
        for x, y, w in zip( xvar, yvar, wvar ):
            hist.Fill( x, y, w )
    else:
        for x, y in zip( xvar, yvar ):
            hist.Fill( x, y )
    hist.GetXaxis().SetTitle( xtitle )
    hist.GetYaxis().SetTitle( ytitle )
    return hist

#_______________________________________________________________________________
# Generates a scatter plot given two lists of data
def MakeScatterPlot( xvar, yvar, xerr = False, yerr = False, **kwargs ):
    if "name" in kwargs: name = kwargs[ "name" ]
    else: name = False
    if "title" in kwargs: title = kwargs[ "title" ]
    else: title = False
    if "xtitle" in kwargs: xtitle = kwargs[ "xtitle" ]
    else: xtitle = "X"
    if "ytitle" in kwargs: ytitle = kwargs[ "ytitle" ]
    else: ytitle = "Y"
    npoints = len( xvar )
    xvar    = array( 'd', xvar )
    yvar    = array( 'd', yvar )
    if xerr or yerr:
        if   not xerr:
            xerr = array( 'd', npoints*[ 0 ] )
            yerr = array( 'd', yerr )
        elif not yerr:
            xerr = array( 'd', yerr )
            yerr = array( 'd', npoints*[ 0 ] )
        else:
            xerr = array( 'd', xerr )
            yerr = array( 'd', yerr )
        graph = TGraphErrors( npoints, xvar, yvar, xerr, yerr )
    else:
        graph = TGraph( npoints, xvar, yvar )
    if name:
        graph.SetName( name )
    if title:
        graph.SetTitle( title )
    graph.GetXaxis().SetTitle( xtitle )
    graph.GetYaxis().SetTitle( ytitle )
    return graph

#_______________________________________________________________________________
# This function plots in the same canvas the distributions of the given
# variables from different DataManager classes. Different options can
# also been provided to modify the canvas and the information displayed.
def MultiPlot( mngrs, variables, **kwargs):
    if "colors" in kwargs: colors = ColorList( kwargs[ "colors" ] )
    else: colors = ColorList()
    if "cuts" in kwargs: cuts = kwargs[ "cuts" ]
    else: cuts = False
    if "errors" in kwargs: errors = kwargs[ "errors" ]
    else: errors = False
    if "legend" in kwargs: legend = kwargs[ "legend" ]
    else: legend = True
    if "name" in kwargs: name = kwargs[ "name" ]
    else: name = "canvas"
    if "title" in kwargs: title = kwargs[ "title" ]
    else: title = "canvas"
    if "nbins" in kwargs: nbins = kwargs[ "nbins" ]
    else: nbins = 100
    if "norm" in kwargs: norm = kwargs[ "norm" ]
    else: norm = 1

    nvars   = len( variables ) + 1
    results = {}
    if all( var in mngr.Variables for mngr in mngrs for var in variables ):
        ''' Checks if the number of variables is a square number '''
        if IsSquare( nvars ):
            nxvars = int( round( sqrt( nvars ) ) )
            nyvars = nxvars
        else:
            nxvars, nyvars = 1, 1
            if IsPrime( nvars ): decvars = Decompose( nvars + 1 )
            else:                decvars = Decompose( nvars )
            for i in xrange( len( decvars ) ):
                if i % 2: nxvars *= decvars[ i ]
                else:     nyvars *= decvars[ i ]

        ''' Generates and divides the canvas '''
        canvas = TCanvas( name, title, 300*nyvars, 300*nxvars )
        canvas.Divide( nyvars, nxvars )

        nmngrs = len( mngrs )
        ''' If cuts are specified it calculates the true managers '''
        if cuts:
            for i in xrange( nmngrs ):
                mngrs[ i ], mngrs[ i ].Name = mngrs[ i ].CutSample( cuts ), mngrs[ i ].Name

        ''' Disables the stat box of the histograms '''
        gStyle.SetOptStat( 0 )

        ''' Constructs the legend and the information panel if specified '''
        if legend:
            rlegend = TLegend( 0.1, 0.8 - nmngrs*0.05, 0.9, 0.9 )
            rlegend.SetHeader( "#bf{-- Legend --}" )
            rlegend.SetTextAlign( 22 )
            rlegend.SetTextSize( 0.075 )
            rlegend.SetFillColor( 17 )
            rtxtinf = TPaveText( 0.1, 0.8 - nmngrs*0.05, 0.9, 0.9 )
            rtxtinf.AddText( "-- Number of entries --" )
            rtxtinf.SetTextSize( 0.075 )
            rtxtinf.SetFillColor( 42 )
            rtxtinf.SetShadowColor( 0 )

        ''' Generates and draws the histograms '''
        for iv, var in enumerate( variables ):
            canvas.cd( iv + 1 )
            totlst = [ el for mngr in mngrs for el in mngr[ var ]  ]
            vmin, vmax, hists = min( totlst ), max( totlst ), []
            for im, mngr in enumerate( mngrs ):
                hname = mngr.Name + "_" + var
                hists.append( mngr.MakeHistogram( var,
                                                  name  = hname,
                                                  title = var,
                                                  nbins = nbins,
                                                  vmin  = vmin,
                                                  vmax  = vmax,
                                                  cuts  = cuts ) )
                h = hists[ -1 ]
                if norm:
                    h.Scale( float( norm )/h.GetEntries() )
                h.SetLineColor( colors[ im ] )
                h.SetMarkerColor( colors[ im ] )
                if legend and iv == 0:
                    ''' In the first iteration adds the entries to the legend '''
                    rlegend.AddEntry( h, "#bf{" + mngr.Name + "}", "L" )
                    rtxtinf.AddText( mngr.Name + ": %i" % h.GetEntries() )
                results[ hname ] = h
            ''' The maximum of the y-axis in the pad is set to the 110% of the maximum
            value for all the histograms to be drawn '''
            hists[ 0 ].SetMaximum( 1.1*max( h.GetMaximum() for h in hists ) )
            for h in hists:
                if errors: h.Draw( "SAMEE" )
                else:      h.Draw( "SAME"  )
        if legend:
            pad = canvas.cd( nvars )
            pad.Divide( 2, 1 )
            pad.cd( 1 ); rlegend.Draw()
            pad.cd( 2 ); rtxtinf.Draw()
            results[ "legend" ] = rlegend
            results[ "info" ]   = rtxtinf
        canvas.Update()
        results[ name ] = canvas
        return results
    else:
        print "Any of the managers does not have access to some of the variables"
        return
<|endoftext|>


<commit_before>#!/usr/bin/env python
# coding=utf-8

from pyecharts.chart import Chart
from pyecharts.option import get_all_options

class Polar(Chart):
    """
    <<< 极坐标系 >>>

    可以用于散点图和折线图。
    """
    def __init__(self, title="", subtitle="", **kwargs):
        super(Polar, self).__init__(title, subtitle, **kwargs)

    def add(self, *args, **kwargs):
        self.__add(*args, **kwargs)

    def __add(self, name, data,
              angle_data=None,
              radius_data=None,
              type='line',
              symbol_size=4,
              start_angle=90,
              rotate_step=0,
              boundary_gap=True,
              is_clockwise=True,
              is_stack=False,
              axis_range=None,
              is_angleaxis_show=True,
              is_radiusaxis_show=True,
              **kwargs):
        """

        :param name:
            系列名称，用于 tooltip 的显示，legend 的图例筛选。
        :param data:
            数据项 [极径，极角 [数据值]]。
        :param angle_data:
            角度类目数据。
        :param radius_data:
            半径类目数据。
        :param type:
            图例类型，有'line', 'scatter', 'effectScatter', 'barAngle', 'barRadius'
            可选。默认为 'line'。
        :param symbol_size:
            标记图形大小，默认为 4。
        :param start_angle:
            起始刻度的角度，默认为 90 度，即圆心的正上方。0 度为圆心的正右方。
        :param rotate_step:
            刻度标签旋转的角度，在类目轴的类目标签显示不下的时候可以通过旋转防止标签之间重叠
            旋转的角度从 -90 度到 90 度。默认为 0
        :param boundary_gap:
            坐标轴两边留白策略
            默认为 True，这时候刻度只是作为分隔线，标签和数据点都会在两个刻度之间的带(band)中间。
        :param is_clockwise:
            刻度增长是否按顺时针，默认 True
        :param is_stack:
            数据堆叠，同个类目轴上系列配置相同的 stack 值可以堆叠放置。
        :param axis_range:
            坐标轴刻度范围。默认值为 [None, None]。
        :param is_angleaxis_show:
            是否显示极坐标系的角度轴，默认为 True。
        :param is_radiusaxis_show:
            是否显示极坐标系的径向轴，默认为 True。
        :param kwargs:
        """
        chart = get_all_options(**kwargs)
        polar_type = 'value' if type == "line" else "category"
        is_stack = "stack" if is_stack else ""
        self._option.get('legend')[0].get('data').append(name)

        _amin, _amax = None, None
        if axis_range:
            if len(axis_range) == 2:
                _amin, _amax = axis_range

        _area_style = {"normal": chart['area_style']}
        if kwargs.get('area_color', None) is None:
            _area_style = None

        if type in ("scatter", "line"):
            self._option.get('series').append({
                "type": type,
                "name": name,
                "coordinateSystem": 'polar',
                "symbol": chart['symbol'],
                "symbolSize": symbol_size,
                "data": data,
                "label": chart['label'],
                "areaStyle": _area_style
            })

        elif type == "effectScatter":
            self._option.get('series').append({
                "type": type,
                "name": name,
                "coordinateSystem": 'polar',
                "showEffectOn": "render",
                "rippleEffect": chart['effect'],
                "symbol": chart['symbol'],
                "symbolSize": symbol_size,
                "data": data,
                "label": chart['label'],
            })

        elif type == "barRadius":
            self._option.get('series').append({
                "type": "bar",
                "stack": is_stack,
                "name": name,
                "coordinateSystem": 'polar',
                "data": data,
            })
            self._option.update(angleAxis={})
            self._option.update(
                radiusAxis={
                    "type": polar_type,
                    "data": radius_data,
                    "z": 50,
                })

        elif type == "barAngle":
            self._option.get('series').append({
                "type": "bar",
                "stack": is_stack,
                "name": name,
                "coordinateSystem": 'polar',
                "data": data,
            })
            self._option.update(radiusAxis={})
            self._option.update(
                angleAxis={
                    "type": polar_type,
                    "data": radius_data,
                    "z": 50
                })

        if type not in ("barAngle", "barRadius"):
            self._option.update(
                angleAxis={
                    "show":is_angleaxis_show,
                    "type": polar_type,
                    "data": angle_data,
                    "clockwise": is_clockwise,
                    "startAngle": start_angle,
                    "boundaryGap": boundary_gap,
                    "splitLine": chart['split_line'],
                    "axisLine": chart['axis_line']
                }
            )
            self._option.update(
                radiusAxis={
                    "show": is_radiusaxis_show,
                    "type": polar_type,
                    "data": radius_data,
                    "min": _amin,
                    "max": _amax,
                    "axisLine": chart['axis_line'],
                    "axisLabel": {"rotate": rotate_step}
                }
            )
        self._option.update(polar={})
        self._config_components(**kwargs)
<commit_msg>帮同事提交修复 Issues #234<commit_after>#!/usr/bin/env python
# coding=utf-8

from pyecharts.chart import Chart
from pyecharts.option import get_all_options

class Polar(Chart):
    """
    <<< 极坐标系 >>>

    可以用于散点图和折线图。
    """
    def __init__(self, title="", subtitle="", **kwargs):
        super(Polar, self).__init__(title, subtitle, **kwargs)

    def add(self, *args, **kwargs):
        self.__add(*args, **kwargs)

    def __add(self, name, data,
              angle_data=None,
              radius_data=None,
              type='line',
              symbol_size=4,
              start_angle=90,
              rotate_step=0,
              boundary_gap=True,
              is_clockwise=True,
              is_stack=False,
              axis_range=None,
              is_angleaxis_show=True,
              is_radiusaxis_show=True,
              **kwargs):
        """

        :param name:
            系列名称，用于 tooltip 的显示，legend 的图例筛选。
        :param data:
            数据项 [极径，极角 [数据值]]。
        :param angle_data:
            角度类目数据。
        :param radius_data:
            半径类目数据。
        :param type:
            图例类型，有'line', 'scatter', 'effectScatter', 'barAngle', 'barRadius'
            可选。默认为 'line'。
        :param symbol_size:
            标记图形大小，默认为 4。
        :param start_angle:
            起始刻度的角度，默认为 90 度，即圆心的正上方。0 度为圆心的正右方。
        :param rotate_step:
            刻度标签旋转的角度，在类目轴的类目标签显示不下的时候可以通过旋转防止标签之间重叠
            旋转的角度从 -90 度到 90 度。默认为 0
        :param boundary_gap:
            坐标轴两边留白策略
            默认为 True，这时候刻度只是作为分隔线，标签和数据点都会在两个刻度之间的带(band)中间。
        :param is_clockwise:
            刻度增长是否按顺时针，默认 True
        :param is_stack:
            数据堆叠，同个类目轴上系列配置相同的 stack 值可以堆叠放置。
        :param axis_range:
            坐标轴刻度范围。默认值为 [None, None]。
        :param is_angleaxis_show:
            是否显示极坐标系的角度轴，默认为 True。
        :param is_radiusaxis_show:
            是否显示极坐标系的径向轴，默认为 True。
        :param kwargs:
        """
        chart = get_all_options(**kwargs)
        polar_type = 'value' if type == "line" else "category"
        is_stack = "stack" if is_stack else ""
        self._option.get('legend')[0].get('data').append(name)

        _amin, _amax = None, None
        if axis_range:
            if len(axis_range) == 2:
                _amin, _amax = axis_range

        _area_style = {"normal": chart['area_style']}
        if kwargs.get('area_color', None) is None:
            _area_style = None

        if type in ("scatter", "line"):
            self._option.get('series').append({
                "type": type,
                "name": name,
                "coordinateSystem": 'polar',
                "symbol": chart['symbol'],
                "symbolSize": symbol_size,
                "data": data,
                "label": chart['label'],
                "areaStyle": _area_style
            })

        elif type == "effectScatter":
            self._option.get('series').append({
                "type": type,
                "name": name,
                "coordinateSystem": 'polar',
                "showEffectOn": "render",
                "rippleEffect": chart['effect'],
                "symbol": chart['symbol'],
                "symbolSize": symbol_size,
                "data": data,
                "label": chart['label'],
            })

        elif type == "barRadius":
            self._option.get('series').append({
                "type": "bar",
                "stack": is_stack,
                "name": name,
                "coordinateSystem": 'polar',
                "data": data,
            })
            self._option.update(angleAxis={})
            self._option.update(
                radiusAxis={
                    "type": polar_type,
                    "data": radius_data,
                    "z": 50,
                })

        elif type == "barAngle":
            self._option.get('series').append({
                "type": "bar",
                "stack": is_stack,
                "name": name,
                "coordinateSystem": 'polar',
                "data": data,
            })
            self._option.update(radiusAxis={
                "show": is_radiusaxis_show,
            })
            self._option.update(
                angleAxis={
                    "show": is_angleaxis_show,
                    "type": polar_type,
                    "data": radius_data,
                    "z": 50,
                    "startAngle": start_angle,
                    "splitLine": chart['split_line']
                })

        if type not in ("barAngle", "barRadius"):
            self._option.update(
                angleAxis={
                    "show":is_angleaxis_show,
                    "type": polar_type,
                    "data": angle_data,
                    "clockwise": is_clockwise,
                    "startAngle": start_angle,
                    "boundaryGap": boundary_gap,
                    "splitLine": chart['split_line'],
                    "axisLine": chart['axis_line']
                }
            )
            self._option.update(
                radiusAxis={
                    "show": is_radiusaxis_show,
                    "type": polar_type,
                    "data": radius_data,
                    "min": _amin,
                    "max": _amax,
                    "axisLine": chart['axis_line'],
                    "axisLabel": {"rotate": rotate_step}
                }
            )
        self._option.update(polar={})
        self._config_components(**kwargs)
<|endoftext|>


<commit_before>#!/usr/bin/env python3

from fusion_engine_client.analysis.analyzer import main

if __name__ == "__main__":
    main()
<commit_msg>Fixed import path for p1_display.py wrapper utility.<commit_after>#!/usr/bin/env python3

import os
import sys

root_dir = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
sys.path.append(root_dir)

from fusion_engine_client.analysis.analyzer import main

if __name__ == "__main__":
    main()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
    pygments.lexers.cypher
    ~~~~~~~~~~~~~~~~~~~~~~

    A Lexer for the cypher graph query language use in the neo4j graph database.

    `CypherLexer`

    the ``tests/examplefiles`` contains file "test.cyp" which has valid
    cypher queries that execute against the example database shipped with Neo4J

    :copyright: Copyright 2006-2013 by the Pygments team, see AUTHORS.
    :license: BSD, see LICENSE for details.
"""

import re

from pygments.lexer import RegexLexer, include, bygroups
from pygments.token import Punctuation, Text, Comment, Operator, Name, \
String, Number, Generic

__all__ = ['CypherLexer']

class CypherLexer(RegexLexer):
    """
    For Cypher Query Language
    http://docs.neo4j.org/chunked/milestone/cypher-query-lang.html
    For the Cypher version in Neo4J 2.0
    """
    name = 'Cypher'
    aliases = ['cypher']
    filenames = ['*.cyp','*.cypher']

    tokens = {
        'root': [
            include('comment'),
            include('keywords'),
            include('clauses'),
            include('relations')
            ],
        'comment': [(r'^.*//.*\n', Comment.Single)],
        'keywords': [(
            r''
        )],
        'clauses': [],
        'relations': []
        }

<commit_msg>a crude, barely functional lexer. Now to improve it.<commit_after># -*- coding: utf-8 -*-
"""
    pygments.lexers.cypher
    ~~~~~~~~~~~~~~~~~~~~~~

    A Lexer for the cypher graph query language use in the neo4j graph database.

    `CypherLexer`

    the ``tests/examplefiles`` contains file "test.cyp" which has valid
    cypher queries that execute against the example database shipped with Neo4J

    :copyright: Copyright 2006-2013 by the Pygments team, see AUTHORS.
    :license: BSD, see LICENSE for details.
"""

import re

from pygments.lexer import RegexLexer, include, bygroups
from pygments.token import Keyword, Punctuation, Text, Comment, Operator, Name,\
String, Number, Generic

__all__ = ['CypherLexer']

class CypherLexer(RegexLexer):
    """
    For Cypher Query Language
    http://docs.neo4j.org/chunked/milestone/cypher-query-lang.html
    For the Cypher version in Neo4J 2.0
    """
    name = 'Cypher'
    aliases = ['cypher']
    filenames = ['*.cyp','*.cypher']

    tokens = {
        'root': [
            include('comment'),
            include('keywords'),
            include('clauses'),
            include('relations')
            ],
        'comment': [(r'^.*//.*\n', Comment.Single)],
        'keywords': [
            (r'CREATE|ORDER|MATCH|LIMIT|SET|SKIP|START|RETURN|WITH|WHERE|DELETE'
             r'|FOREACH|NOT|BY|AS', Keyword)],
        'clauses': [(r' all | any | as | asc |create|create unique|delete|'
                     r'desc |distinct|foreach| in |is null|limit|match|none|'
                     r'order by|return|set|skip|single|start|union|where|with',
                     Keyword)],
        'relations': [(r'-->|-\[.*\]->|<-\[.*\]-|<--', Punctuation),
                      (r'<|>|<>|=|<=|=>', Operator)]
        }

<|endoftext|>