<commit_before>import numpy as np
from pure_data import Data_parse

def argument_gpec(func):
    def box(*arg):
        try:
            if 1 <= arg[0] <= 3 and 0 <= arg[1] <= 3: return func(*arg)
        except ValueError:
            return ValueError("NMODEL = 1,2,3 and ICALC = 0,1,2,3")
        else:
            return func(3, 2)
    return box

@argument_gpec
def gpec2pyther_argument(NMODEL, ICALC):

    if ICALC == 0: ICALC = "constants_eps"
    elif ICALC == 1: ICALC = "parameters_eps"
    elif ICALC == 2: ICALC = "rk_param"
    elif ICALC == 3: ICALC = "density"

    if NMODEL == 1: NMODEL = "SRK"
    elif NMODEL == 2: NMODEL = "PR"
    elif NMODEL == 3: NMODEL = "RKPR"

    return NMODEL, ICALC

class Control_arguments(object):

    def __init__(self, NMODEL, ICALC):
        self.NMODEL = NMODEL
        self.ICALC = ICALC

    @property
    def NMODEL(self):
        print ("NMODEL is valid ...")
        return self._NMODEL

    @property
    def ICALC(self):
        print("ICALC is valid ...")
        return self._ICALC

    @NMODEL.setter
    def NMODEL(self, NMODEL):
        if NMODEL not in ["SRK", "PR", "RKPR"]:
            raise AttributeError("’NMODEL’ not in ['SRK', 'PR', 'RKPR']")
        self._NMODEL = NMODEL

    @ICALC.setter
    def ICALC(self, ICALC):
        if ICALC not in ["constants_eps", "parameters_eps", "rk_param", "density"]:
            raise AttributeError("'ICALC' not in ['constants_eps', 'parameters_eps', 'rk_param', 'density']")
        self._ICALC = ICALC

nm = Control_arguments("PR", "constants_eps")
print ("NMODEL: {0} and ICALC: {1}".format(nm.NMODEL, nm.ICALC))

def main():
    dppr_file = "PureFull.xls"
    component = 'METHANE'
    #component = "ETHANE"

    component_eos = Data_parse()
    properties_component = component_eos.selec_component(dppr_file, component)

    print ('acentric_factor = {0}'.format(properties_component[1]['Omega']))
    print ('critical_Temperature = {0} K'.format(properties_component[1]['Tc']))
    print ('critical_Pressure = {0} Bar'.format(properties_component[1]['Pc']))
    print ('critical_Volume = {0} cm3/mol'.format(properties_component[1]['Vc']))
    print ('compressibility_factor_Zz = {0}'.format(properties_component[1]['Zc']))
    NMODEL = 1
    ICALC = -3

    if type(NMODEL) == int or type(ICALC) == int:
        NMODEL, ICALC = gpec2pyther_argument(NMODEL, ICALC)

    print('NMODEL = {0} and ICALC = {1}'.format(NMODEL, ICALC))

if __name__ == "__main__":
    main()
<commit_msg>NMODEL and ICALC convert<commit_after>import numpy as np
from pure_data import Data_parse

def argument_gpec(func):
    def box(*arg):
        try:
            if 1 <= arg[0] <= 3 and 0 <= arg[1] <= 3: return func(*arg)
        except AttributeError:
            return AttributeError("NMODEL = 1,2,3 and ICALC = 0,1,2,3")
        else:
            return func(3, 2)
    return box

@argument_gpec
def gpec2pyther_argument(NMODEL, ICALC):

    if ICALC == 0: ICALC = "constants_eps"
    elif ICALC == 1: ICALC = "parameters_eps"
    elif ICALC == 2: ICALC = "rk_param"
    elif ICALC == 3: ICALC = "density"

    if NMODEL == 1: NMODEL = "SRK"
    elif NMODEL == 2: NMODEL = "PR"
    elif NMODEL == 3: NMODEL = "RKPR"

    return NMODEL, ICALC

class Control_arguments(object):

    def __init__(self, NMODEL, ICALC):
        self.NMODEL = NMODEL
        self.ICALC = ICALC

    @property
    def NMODEL(self):
        print ("NMODEL is valid ...")
        return self._NMODEL

    @property
    def ICALC(self):
        print("ICALC is valid ...")
        return self._ICALC

    @NMODEL.setter
    def NMODEL(self, NMODEL):
        if NMODEL not in ["SRK", "PR", "RKPR"]:
            raise AttributeError("’NMODEL’ not in ['SRK', 'PR', 'RKPR']")
        self._NMODEL = NMODEL

    @ICALC.setter
    def ICALC(self, ICALC):
        if ICALC not in ["constants_eps", "parameters_eps", "rk_param", "density"]:
            raise AttributeError("'ICALC' not in ['constants_eps', 'parameters_eps', 'rk_param', 'density']")
        self._ICALC = ICALC

def control_arguments_gpec(gpec_data):

    if gpec_data:
        NMODEL, ICALC = gpec2pyther_argument(NMODEL, ICALC)
    else:
        nm = Control_arguments("PR", "constants_eps")

def main():
    dppr_file = "PureFull.xls"
    component = 'METHANE'
    #component = "ETHANE"

    component_eos = Data_parse()
    properties_component = component_eos.selec_component(dppr_file, component)

    print ('acentric_factor = {0}'.format(properties_component[1]['Omega']))
    print ('critical_Temperature = {0} K'.format(properties_component[1]['Tc']))
    print ('critical_Pressure = {0} Bar'.format(properties_component[1]['Pc']))
    print ('critical_Volume = {0} cm3/mol'.format(properties_component[1]['Vc']))
    print ('compressibility_factor_Zz = {0}'.format(properties_component[1]['Zc']))

    nm = Control_arguments("PR", "constants_eps")
    print ("NMODEL: {0} and ICALC: {1}".format(nm.NMODEL, nm.ICALC))

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


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from osv import osv,fields
from osv.orm import except_orm
import pickle
from tools.translate import _

EXCLUDED_FIELDS = set((
    'report_sxw_content', 'report_rml_content', 'report_sxw', 'report_rml',
    'report_sxw_content_data', 'report_rml_content_data', 'search_view', ))

class ir_values(osv.osv):
    _name = 'ir.values'

    def _value_unpickle(self, cursor, user, ids, name, arg, context=None):
        res = {}
        for report in self.browse(cursor, user, ids, context=context):
            value = report[name[:-9]]
            if not report.object and value:
                try:
                    value = str(pickle.loads(value))
                except:
                    pass
            res[report.id] = value
        return res

    def _value_pickle(self, cursor, user, id, name, value, arg, context=None):
        if context is None:
            context = {}
        ctx = context.copy()
        if self.CONCURRENCY_CHECK_FIELD in ctx:
            del ctx[self.CONCURRENCY_CHECK_FIELD]
        if not self.browse(cursor, user, id, context=context).object:
            value = pickle.dumps(value)
        self.write(cursor, user, id, {name[:-9]: value}, context=ctx)

    def onchange_object_id(self, cr, uid, ids, object_id, context={}):
        if not object_id: return {}
        act = self.pool.get('ir.model').browse(cr, uid, object_id, context=context)
        return {
                'value': {'model': act.model}
        }

    def onchange_action_id(self, cr, uid, ids, action_id, context={}):
        if not action_id: return {}
        act = self.pool.get('ir.actions.actions').browse(cr, uid, action_id, context=context)
        return {
                'value': {'value_unpickle': act.type+','+str(act.id)}
        }

    _columns = {
        'name': fields.char('Name', size=128),
        'model_id': fields.many2one('ir.model', 'Object', size=128,
            help="This field is not used, it only helps you to select a good model."),
        'model': fields.char('Object Name', size=128, select=True),
        'action_id': fields.many2one('ir.actions.actions', 'Action',
            help="This field is not used, it only helps you to select the right action."),
        'value': fields.text('Value'),
        'value_unpickle': fields.function(_value_unpickle, fnct_inv=_value_pickle,
            method=True, type='text', string='Value'),
        'object': fields.boolean('Is Object'),
        'key': fields.selection([('action','Action'),('default','Default')], 'Type', size=128, select=True),
        'key2' : fields.char('Event Type',help="The kind of action or button in the client side that will trigger the action.", size=128, select=True),
        'meta': fields.text('Meta Datas'),
        'meta_unpickle': fields.function(_value_unpickle, fnct_inv=_value_pickle,
            method=True, type='text', string='Metadata'),
        'res_id': fields.integer('Object ID', help="Keep 0 if the action must appear on all resources.", select=True),
        'user_id': fields.many2one('res.users', 'User', ondelete='cascade', select=True),
        'company_id': fields.many2one('res.company', 'Company', select=True)
    }
    _defaults = {
        'key': lambda *a: 'action',
        'key2': lambda *a: 'tree_but_open',
        'company_id': lambda *a: False
    }

    def _auto_init(self, cr, context=None):
        super(ir_values, self)._auto_init(cr, context)
        cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = \'ir_values_key_model_key2_res_id_user_id_idx\'')
        if not cr.fetchone():
            cr.execute('CREATE INDEX ir_values_key_model_key2_res_id_user_id_idx ON ir_values (key, model, key2, res_id, user_id)')

    def set(self, cr, uid, key, key2, name, models, value, replace=True, isobject=False, meta=False, preserve_user=False, company=False):
        if isinstance(value, unicode):
            value = value.encode('utf8')
        if not isobject:
            value = pickle.dumps(value)
        if meta:
            meta = pickle.dumps(meta)
        ids_res = []
        for model in models:
            if isinstance(model, (list, tuple)):
                model,res_id = model
            else:
                res_id=False
            if replace:
                search_criteria = [
                    ('key', '=', key),
                    ('key2', '=', key2),
                    ('model', '=', model),
                    ('res_id', '=', res_id),
                    ('user_id', '=', preserve_user and uid)
                ]
                if key in ('meta', 'default'):
                    search_criteria.append(('name', '=', name))
                else:
                    search_criteria.append(('value', '=', value))

                self.unlink(cr, uid, self.search(cr, uid, search_criteria))
            vals = {
                'name': name,
                'value': value,
                'model': model,
                'object': isobject,
                'key': key,
                'key2': key2 and key2[:200],
                'meta': meta,
                'user_id': preserve_user and uid,
            }
            if company:
                cid = self.pool.get('res.users').browse(cr, uid, uid, context={}).company_id.id
                vals['company_id']=cid
            if res_id:
                vals['res_id']= res_id
            ids_res.append(self.create(cr, uid, vals))
        return ids_res

    def get(self, cr, uid, key, key2, models, meta=False, context={}, res_id_req=False, without_user=True, key2_req=True):
        result = []
        for m in models:
            if isinstance(m, (list, tuple)):
                m, res_id = m
            else:
                res_id=False

            where = ['key=%s','model=%s']
            params = [key, str(m)]
            if key2:
                where.append('key2=%s')
                params.append(key2[:200])
            elif key2_req and not meta:
                where.append('key2 is null')
            if res_id_req and (models[-1][0]==m):
                if res_id:
                    where.append('res_id=%s')
                    params.append(res_id)
                else:
                    where.append('(res_id is NULL)')
            elif res_id:
                if (models[-1][0]==m):
                    where.append('(res_id=%s or (res_id is null))')
                    params.append(res_id)
                else:
                    where.append('res_id=%s')
                    params.append(res_id)

            where.append('(user_id=%s or (user_id IS NULL)) order by id')
            params.append(uid)
            clause = ' and '.join(where)
            cr.execute('select id,name,value,object,meta, key from ir_values where ' + clause, params)
            result = cr.fetchall()
            if result:
                break

        if not result:
            return []

        def _result_get(x, keys):
            if x[1] in keys:
                return False
            keys.append(x[1])
            if x[3]:
                model,id = x[2].split(',')
                # FIXME: It might be a good idea to opt-in that kind of stuff
                # FIXME: instead of arbitrarily removing random fields
                fields = [
                    field
                    for field in self.pool.get(model).fields_get_keys(cr, uid)
                    if field not in EXCLUDED_FIELDS]

                try:
                    datas = self.pool.get(model).read(cr, uid, [int(id)], fields, context)
                except except_orm, e:
                    return False
                datas = datas and datas[0]
                if not datas:
                    return False
            else:
                datas = pickle.loads(x[2].encode('utf-8'))
            if meta:
                return (x[0], x[1], datas, pickle.loads(x[4]))
            return (x[0], x[1], datas)
        keys = []
        res = filter(None, map(lambda x: _result_get(x, keys), result))
        res2 = res[:]
        for r in res:
            if isinstance(r[2], dict) and r[2].get('type') in ('ir.actions.report.xml','ir.actions.act_window','ir.actions.wizard'):
                groups = r[2].get('groups_id')
                if groups:
                    cr.execute('SELECT COUNT(1) FROM res_groups_users_rel WHERE gid IN %s AND uid=%s',(tuple(groups), uid))
                    cnt = cr.fetchone()[0]
                    if not cnt:
                        res2.remove(r)
                    if r[1] == 'Menuitem' and not res2:
                        raise osv.except_osv('Error !','You do not have the permission to perform this operation !!!')
        return res2
ir_values()
<commit_msg>[Fix] Set default value for current login user<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from osv import osv,fields
from osv.orm import except_orm
import pickle
from tools.translate import _

EXCLUDED_FIELDS = set((
    'report_sxw_content', 'report_rml_content', 'report_sxw', 'report_rml',
    'report_sxw_content_data', 'report_rml_content_data', 'search_view', ))

class ir_values(osv.osv):
    _name = 'ir.values'

    def _value_unpickle(self, cursor, user, ids, name, arg, context=None):
        res = {}
        for report in self.browse(cursor, user, ids, context=context):
            value = report[name[:-9]]
            if not report.object and value:
                try:
                    value = str(pickle.loads(value))
                except:
                    pass
            res[report.id] = value
        return res

    def _value_pickle(self, cursor, user, id, name, value, arg, context=None):
        if context is None:
            context = {}
        ctx = context.copy()
        if self.CONCURRENCY_CHECK_FIELD in ctx:
            del ctx[self.CONCURRENCY_CHECK_FIELD]
        if not self.browse(cursor, user, id, context=context).object:
            value = pickle.dumps(value)
        self.write(cursor, user, id, {name[:-9]: value}, context=ctx)

    def onchange_object_id(self, cr, uid, ids, object_id, context={}):
        if not object_id: return {}
        act = self.pool.get('ir.model').browse(cr, uid, object_id, context=context)
        return {
                'value': {'model': act.model}
        }

    def onchange_action_id(self, cr, uid, ids, action_id, context={}):
        if not action_id: return {}
        act = self.pool.get('ir.actions.actions').browse(cr, uid, action_id, context=context)
        return {
                'value': {'value_unpickle': act.type+','+str(act.id)}
        }

    _columns = {
        'name': fields.char('Name', size=128),
        'model_id': fields.many2one('ir.model', 'Object', size=128,
            help="This field is not used, it only helps you to select a good model."),
        'model': fields.char('Object Name', size=128, select=True),
        'action_id': fields.many2one('ir.actions.actions', 'Action',
            help="This field is not used, it only helps you to select the right action."),
        'value': fields.text('Value'),
        'value_unpickle': fields.function(_value_unpickle, fnct_inv=_value_pickle,
            method=True, type='text', string='Value'),
        'object': fields.boolean('Is Object'),
        'key': fields.selection([('action','Action'),('default','Default')], 'Type', size=128, select=True),
        'key2' : fields.char('Event Type',help="The kind of action or button in the client side that will trigger the action.", size=128, select=True),
        'meta': fields.text('Meta Datas'),
        'meta_unpickle': fields.function(_value_unpickle, fnct_inv=_value_pickle,
            method=True, type='text', string='Metadata'),
        'res_id': fields.integer('Object ID', help="Keep 0 if the action must appear on all resources.", select=True),
        'user_id': fields.many2one('res.users', 'User', ondelete='cascade', select=True),
        'company_id': fields.many2one('res.company', 'Company', select=True)
    }
    _defaults = {
        'key': lambda *a: 'action',
        'key2': lambda *a: 'tree_but_open',
        'company_id': lambda *a: False
    }

    def _auto_init(self, cr, context=None):
        super(ir_values, self)._auto_init(cr, context)
        cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = \'ir_values_key_model_key2_res_id_user_id_idx\'')
        if not cr.fetchone():
            cr.execute('CREATE INDEX ir_values_key_model_key2_res_id_user_id_idx ON ir_values (key, model, key2, res_id, user_id)')

    def set(self, cr, uid, key, key2, name, models, value, replace=True, isobject=False, meta=False, preserve_user=False, company=False):
        if isinstance(value, unicode):
            value = value.encode('utf8')
        if not isobject:
            value = pickle.dumps(value)
        if meta:
            meta = pickle.dumps(meta)
        ids_res = []
        for model in models:
            if isinstance(model, (list, tuple)):
                model,res_id = model
            else:
                res_id=False
            if replace:
                search_criteria = [
                    ('key', '=', key),
                    ('key2', '=', key2),
                    ('model', '=', model),
                    ('res_id', '=', res_id),
                    ('user_id', '=', preserve_user and uid)
                ]
                if key in ('meta', 'default'):
                    search_criteria.append(('name', '=', name))
                else:
                    search_criteria.append(('value', '=', value))

                self.unlink(cr, uid, self.search(cr, uid, search_criteria))
            vals = {
                'name': name,
                'value': value,
                'model': model,
                'object': isobject,
                'key': key,
                'key2': key2 and key2[:200],
                'meta': meta,
                'user_id': preserve_user and uid,
            }
            if company:
                cid = self.pool.get('res.users').browse(cr, uid, uid, context={}).company_id.id
                vals['company_id']=cid
            if res_id:
                vals['res_id']= res_id
            ids_res.append(self.create(cr, uid, vals))
        return ids_res

    def get(self, cr, uid, key, key2, models, meta=False, context={}, res_id_req=False, without_user=True, key2_req=True):
        result = []
        for m in models:
            if isinstance(m, (list, tuple)):
                m, res_id = m
            else:
                res_id=False

            where = ['key=%s','model=%s']
            params = [key, str(m)]
            if key2:
                where.append('key2=%s')
                params.append(key2[:200])
            elif key2_req and not meta:
                where.append('key2 is null')
            if res_id_req and (models[-1][0]==m):
                if res_id:
                    where.append('res_id=%s')
                    params.append(res_id)
                else:
                    where.append('(res_id is NULL)')
            elif res_id:
                if (models[-1][0]==m):
                    where.append('(res_id=%s or (res_id is null))')
                    params.append(res_id)
                else:
                    where.append('res_id=%s')
                    params.append(res_id)
            order = 'id'
            if key == 'default':
                order = 'user_id'
            where.append('(user_id=%s or (user_id IS NULL)) order by '+ order)
            params.append(uid)
            clause = ' and '.join(where)
            cr.execute('select id,name,value,object,meta, key from ir_values where ' + clause, params)
            result = cr.fetchall()
            if result:
                break

        if not result:
            return []

        def _result_get(x, keys):
            if x[1] in keys:
                return False
            keys.append(x[1])
            if x[3]:
                model,id = x[2].split(',')
                # FIXME: It might be a good idea to opt-in that kind of stuff
                # FIXME: instead of arbitrarily removing random fields
                fields = [
                    field
                    for field in self.pool.get(model).fields_get_keys(cr, uid)
                    if field not in EXCLUDED_FIELDS]

                try:
                    datas = self.pool.get(model).read(cr, uid, [int(id)], fields, context)
                except except_orm, e:
                    return False
                datas = datas and datas[0]
                if not datas:
                    return False
            else:
                datas = pickle.loads(x[2].encode('utf-8'))
            if meta:
                return (x[0], x[1], datas, pickle.loads(x[4]))
            return (x[0], x[1], datas)
        keys = []
        res = filter(None, map(lambda x: _result_get(x, keys), result))
        res2 = res[:]
        for r in res:
            if isinstance(r[2], dict) and r[2].get('type') in ('ir.actions.report.xml','ir.actions.act_window','ir.actions.wizard'):
                groups = r[2].get('groups_id')
                if groups:
                    cr.execute('SELECT COUNT(1) FROM res_groups_users_rel WHERE gid IN %s AND uid=%s',(tuple(groups), uid))
                    cnt = cr.fetchone()[0]
                    if not cnt:
                        res2.remove(r)
                    if r[1] == 'Menuitem' and not res2:
                        raise osv.except_osv('Error !','You do not have the permission to perform this operation !!!')
        return res2
ir_values()
<|endoftext|>


<commit_before># ----------------------------------------------------------------------------
# Copyright (c) 2016--, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
# ----------------------------------------------------------------------------

import re
import pathlib

from qiime.core import transform
from .base import FormatBase

class PathMakerDescriptor:
    def __init__(self, file):
        self.file = file

    def __get__(self, obj, cls=None):
        if obj is None:
            raise Exception()
        return getattr(obj, self.file.name).path_maker

class File:
    def __init__(self, pathspec, *, format=None):
        if format is None:
            raise TypeError("Must provide a format.")
        self.pathspec = pathspec
        self.format = format

    def __get__(self, obj, cls=None):
        if obj is None:
            return self
        return BoundFile(self.name, self.pathspec, self.format, obj)

class FileCollection(File):
    def __init__(self, pathspec, *, format=None):
        super().__init__(pathspec, format=format)
        self._path_maker = None

    def set_path_maker(self, function):
        self._path_maker = function
        return PathMakerDescriptor(self)

    def __get__(self, obj, cls=None):
        if obj is None:
            return self

        if self._path_maker is None:
            raise NotImplementedError()

        return BoundFileCollection(self.name, self.pathspec, self.format,
                                   obj, path_maker=self._path_maker)

class BoundFile:
    @property
    def mode(self):
        return self._directory_format._mode

    def __init__(self, name, pathspec, format, directory_format):
        self.name = name
        self.pathspec = pathspec
        self.format = format
        self._directory_format = directory_format
        self._path_maker = lambda s: pathspec

    def view(self, view_type):
        from_type = transform.ModelType.from_view_type(self.format)
        to_type = transform.ModelType.from_view_type(view_type)

        transformation = from_type.make_transformation(to_type)
        return transformation(self.path_maker())

    def write_data(self, view, view_type, **kwargs):
        # TODO: make `view_type` optional like in `Artifact.import_data`
        if self.mode != 'w':
            raise TypeError("Cannot use `set`/`add` when mode=%r" % self.mode)
        from_type = transform.ModelType.from_view_type(view_type)
        to_type = transform.ModelType.from_view_type(self.format)

        transformation = from_type.make_transformation(to_type)
        result = transformation(view)
        result.path._move_or_copy(self.path_maker(**kwargs))

    def _validate_members(self, collected_paths):
        found_members = False
        root = pathlib.Path(self._directory_format.path)
        for path in collected_paths:
            if re.match(self.pathspec, str(path.relative_to(root))):
                if collected_paths[path]:
                    raise ValueError("%r was already validated by another"
                                     " field, the pathspecs (regexes) must"
                                     " overlap." % path)
                collected_paths[path] = True
                found_members = True
                self.format(path, mode='r').validate()
        if not found_members:
            raise ValueError("Missing one or more files for %s: %r"
                             % (self._directory_format.__class__.__name__,
                                self.pathspec))

    @property
    def path_maker(self):
        def bound_path_maker(**kwargs):
            # Must wrap in a naive Path, otherwise an OutPath would be summoned
            # into this world, and would destroy everything in its path.
            path = (pathlib.Path(self._directory_format.path) /
                    self._path_maker(self._directory_format, **kwargs))
            # NOTE: path makers are bound to the directory format, so must be
            # provided as the first argument which will look like `self` to
            # the plugin-dev.
            path.parent.mkdir(parents=True, exist_ok=True)
            return path
        return bound_path_maker

class BoundFileCollection(BoundFile):
    def __init__(self, name, pathspec, format, directory_format, path_maker):
        super().__init__(name, pathspec, format, directory_format)
        self._path_maker = path_maker

    def view(self, view_type):
        raise NotImplementedError("Use `iter_views` instead.")

    def iter_views(self, view_type):
        # Don't want an OutPath, just a Path
        root = pathlib.Path(self._directory_format.path)
        paths = [fp for fp in sorted(root.glob('**/*'))
                 if re.match(self.pathspec, str(fp.relative_to(root)))]
        from_type = transform.ModelType.from_view_type(self.format)
        to_type = transform.ModelType.from_view_type(view_type)

        transformation = from_type.make_transformation(to_type)
        for fp in paths:
            # TODO: include capture?
            yield fp.relative_to(root), transformation(fp)

class _DirectoryMeta(type):
    def __init__(self, name, bases, dct):
        super().__init__(name, bases, dct)
        if hasattr(self, '_fields'):
            fields = self._fields.copy()
        else:
            fields = []
        for key, value in dct.items():
            if isinstance(value, File):
                # TODO: validate that the paths described by `value` are unique
                # within a DirectoryFormat
                value.name = key
                fields.append(key)

        self._fields = fields

class DirectoryFormat(FormatBase, metaclass=_DirectoryMeta):
    def validate(self):
        if not self.path.is_dir():
            raise ValueError("%r is not a directory." % self.path)
        collected_paths = {p: None for p in self.path.glob('**/*')
                           if p.is_file()}
        for field in self._fields:
            getattr(self, field)._validate_members(collected_paths)

        for path, value in collected_paths.items():
            if value:
                continue
            if value is None:
                raise ValueError("Unrecognized file (%r) for %r."
                                 % (path, self.__class__.__name__))

class SingleFileDirectoryFormatBase(DirectoryFormat):
    pass

def SingleFileDirectoryFormat(name, pathspec, format):
    # TODO: do the same hack namedtuple does so we don't mangle globals
    # (arguably the code is going to be broken if defined dynamically anyways,
    # but better to find that out later than writing in the module namespace
    # even if it isn't called module-level [which is must be!])
    df = globals()[name] = type(name, (SingleFileDirectoryFormatBase,),
                                {'file': File(pathspec, format=format)})
    return df
<commit_msg>FIX: Directory Formats fail to validate from globbed hidden files (#174)<commit_after># ----------------------------------------------------------------------------
# Copyright (c) 2016--, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
# ----------------------------------------------------------------------------

import re
import pathlib

from qiime.core import transform
from .base import FormatBase

class PathMakerDescriptor:
    def __init__(self, file):
        self.file = file

    def __get__(self, obj, cls=None):
        if obj is None:
            raise Exception()
        return getattr(obj, self.file.name).path_maker

class File:
    def __init__(self, pathspec, *, format=None):
        if format is None:
            raise TypeError("Must provide a format.")
        self.pathspec = pathspec
        self.format = format

    def __get__(self, obj, cls=None):
        if obj is None:
            return self
        return BoundFile(self.name, self.pathspec, self.format, obj)

class FileCollection(File):
    def __init__(self, pathspec, *, format=None):
        super().__init__(pathspec, format=format)
        self._path_maker = None

    def set_path_maker(self, function):
        self._path_maker = function
        return PathMakerDescriptor(self)

    def __get__(self, obj, cls=None):
        if obj is None:
            return self

        if self._path_maker is None:
            raise NotImplementedError()

        return BoundFileCollection(self.name, self.pathspec, self.format,
                                   obj, path_maker=self._path_maker)

class BoundFile:
    @property
    def mode(self):
        return self._directory_format._mode

    def __init__(self, name, pathspec, format, directory_format):
        self.name = name
        self.pathspec = pathspec
        self.format = format
        self._directory_format = directory_format
        self._path_maker = lambda s: pathspec

    def view(self, view_type):
        from_type = transform.ModelType.from_view_type(self.format)
        to_type = transform.ModelType.from_view_type(view_type)

        transformation = from_type.make_transformation(to_type)
        return transformation(self.path_maker())

    def write_data(self, view, view_type, **kwargs):
        # TODO: make `view_type` optional like in `Artifact.import_data`
        if self.mode != 'w':
            raise TypeError("Cannot use `set`/`add` when mode=%r" % self.mode)
        from_type = transform.ModelType.from_view_type(view_type)
        to_type = transform.ModelType.from_view_type(self.format)

        transformation = from_type.make_transformation(to_type)
        result = transformation(view)
        result.path._move_or_copy(self.path_maker(**kwargs))

    def _validate_members(self, collected_paths):
        found_members = False
        root = pathlib.Path(self._directory_format.path)
        for path in collected_paths:
            if re.match(self.pathspec, str(path.relative_to(root))):
                if collected_paths[path]:
                    raise ValueError("%r was already validated by another"
                                     " field, the pathspecs (regexes) must"
                                     " overlap." % path)
                collected_paths[path] = True
                found_members = True
                self.format(path, mode='r').validate()
        if not found_members:
            raise ValueError("Missing one or more files for %s: %r"
                             % (self._directory_format.__class__.__name__,
                                self.pathspec))

    @property
    def path_maker(self):
        def bound_path_maker(**kwargs):
            # Must wrap in a naive Path, otherwise an OutPath would be summoned
            # into this world, and would destroy everything in its path.
            path = (pathlib.Path(self._directory_format.path) /
                    self._path_maker(self._directory_format, **kwargs))
            # NOTE: path makers are bound to the directory format, so must be
            # provided as the first argument which will look like `self` to
            # the plugin-dev.
            path.parent.mkdir(parents=True, exist_ok=True)
            return path
        return bound_path_maker

class BoundFileCollection(BoundFile):
    def __init__(self, name, pathspec, format, directory_format, path_maker):
        super().__init__(name, pathspec, format, directory_format)
        self._path_maker = path_maker

    def view(self, view_type):
        raise NotImplementedError("Use `iter_views` instead.")

    def iter_views(self, view_type):
        # Don't want an OutPath, just a Path
        root = pathlib.Path(self._directory_format.path)
        paths = [fp for fp in sorted(root.glob('**/*'))
                 if re.match(self.pathspec, str(fp.relative_to(root)))]
        from_type = transform.ModelType.from_view_type(self.format)
        to_type = transform.ModelType.from_view_type(view_type)

        transformation = from_type.make_transformation(to_type)
        for fp in paths:
            # TODO: include capture?
            yield fp.relative_to(root), transformation(fp)

class _DirectoryMeta(type):
    def __init__(self, name, bases, dct):
        super().__init__(name, bases, dct)
        if hasattr(self, '_fields'):
            fields = self._fields.copy()
        else:
            fields = []
        for key, value in dct.items():
            if isinstance(value, File):
                # TODO: validate that the paths described by `value` are unique
                # within a DirectoryFormat
                value.name = key
                fields.append(key)

        self._fields = fields

class DirectoryFormat(FormatBase, metaclass=_DirectoryMeta):
    def validate(self):
        if not self.path.is_dir():
            raise ValueError("%r is not a directory." % self.path)
        collected_paths = {p: None for p in self.path.glob('**/*')
                           if not p.name.startswith('.') and
                           p.is_file()}
        for field in self._fields:
            getattr(self, field)._validate_members(collected_paths)

        for path, value in collected_paths.items():
            if value:
                continue
            if value is None:
                raise ValueError("Unrecognized file (%r) for %r."
                                 % (path, self.__class__.__name__))

class SingleFileDirectoryFormatBase(DirectoryFormat):
    pass

def SingleFileDirectoryFormat(name, pathspec, format):
    # TODO: do the same hack namedtuple does so we don't mangle globals
    # (arguably the code is going to be broken if defined dynamically anyways,
    # but better to find that out later than writing in the module namespace
    # even if it isn't called module-level [which is must be!])
    df = globals()[name] = type(name, (SingleFileDirectoryFormatBase,),
                                {'file': File(pathspec, format=format)})
    return df
<|endoftext|>


<commit_before>r"""

**openpnm.models.geometry**

----

This submodule contains pore-scale models that calculate geometrical properties

"""

from . import pore_size
from . import pore_seed
from . import pore_volume
from . import pore_surface_area
from . import pore_cross_sectional_area
from . import throat_endpoints
from . import throat_cross_sectional_area
from . import throat_seed
from . import throat_size
from . import throat_length
from . import throat_perimeter
from . import throat_surface_area
from . import throat_volume
from . import throat_capillary_shape_factor
from . import throat_centroid
from . import throat_vector
from . import hydraulic_size_factors
from . import diffusive_size_factors
from . import conduit_lengths
<commit_msg>Added pore_area and throat_area as temporary aliases for cross_sectional_area, until deprecated<commit_after>r"""

**openpnm.models.geometry**

----

This submodule contains pore-scale models that calculate geometrical properties

"""

from . import pore_size
from . import pore_seed
from . import pore_volume
from . import pore_surface_area
from . import pore_cross_sectional_area
from . import throat_endpoints
from . import throat_cross_sectional_area
from . import throat_seed
from . import throat_size
from . import throat_length
from . import throat_perimeter
from . import throat_surface_area
from . import throat_volume
from . import throat_capillary_shape_factor
from . import throat_centroid
from . import throat_vector
from . import hydraulic_size_factors
from . import diffusive_size_factors
from . import conduit_lengths

# Up for deprecation
pore_area = pore_cross_sectional_area
throat_area = throat_cross_sectional_area
<|endoftext|>


<commit_before># This code is part of Qiskit.
#
# (C) Copyright IBM 2017.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
"""
Quantum information measures, metrics, and related functions for states.
"""

import numpy as np
import scipy.linalg as la
from qiskit.exceptions import QiskitError
from qiskit.quantum_info.states.densitymatrix import DensityMatrix, Statevector
from qiskit.quantum_info.states.utils import (partial_trace, shannon_entropy,
                                              _format_state, _funm_svd)

def state_fidelity(state1, state2, validate=True):
    r"""Return the state fidelity between two quantum states.

    The state fidelity :math:`F` for density matrix input states
    :math:`\rho_1, \rho_2` is given by

    .. math::
        F(\rho_1, \rho_2) = Tr[\sqrt{\sqrt{\rho_1}\rho_2\sqrt{\rho_1}}]^2.

    If one of the states is a pure state this simplies to
    :math:`F(\rho_1, \rho_2) = \langle\psi_1|\rho_2|\psi_1\rangle`, where
    :math:`\rho_1 = |\psi_1\rangle\!\langle\psi_1|`.

    Args:
        state1 (Statevector or DensityMatrix): the first quantum state.
        state2 (Statevector or DensityMatrix): the second quantum state.
        validate (bool): check if the inputs are valid quantum states
                         [Default: True]

    Returns:
        float: The state fidelity :math:`F(\rho_1, \rho_2)`.

    Raises:
        QiskitError: if ``validate=True`` and the inputs are invalid quantum states.
    """
    # convert input to numpy arrays
    state1 = _format_state(state1, validate=validate)
    state2 = _format_state(state2, validate=validate)

    # Get underlying numpy arrays
    arr1 = state1.data
    arr2 = state2.data
    if isinstance(state1, Statevector):
        if isinstance(state2, Statevector):
            # Fidelity of two Statevectors
            fid = np.abs(arr2.conj().dot(arr1))**2
        else:
            # Fidelity of Statevector(1) and DensityMatrix(2)
            fid = arr1.conj().dot(arr2).dot(arr1)
    elif isinstance(state2, Statevector):
        # Fidelity of Statevector(2) and DensityMatrix(1)
        fid = arr2.conj().dot(arr1).dot(arr2)
    else:
        # Fidelity of two DensityMatrices
        s1sq = _funm_svd(arr1, np.sqrt)
        s2sq = _funm_svd(arr2, np.sqrt)
        fid = np.linalg.norm(s1sq.dot(s2sq), ord='nuc')**2
    # Convert to py float rather than return np.float
    return float(np.real(fid))

def purity(state, validate=True):
    r"""Calculate the purity of a quantum state.

    The purity of a density matrix :math:`\rho` is

    .. math::

        \text{Purity}(\rho) = Tr[\rho^2]

    Args:
        state (Statevector or DensityMatrix): a quantum state.
        validate (bool): check if input state is valid [Default: True]

    Returns:
        float: the purity :math:`Tr[\rho^2]`.

    Raises:
        QiskitError: if the input isn't a valid quantum state.
    """
    state = _format_state(state, validate=validate)
    return state.purity()

def entropy(state, base=2):
    r"""Calculate the von-Neumann entropy of a quantum state.

    The entropy :math:`S` is given by

    .. math::

        S(\rho) = - Tr[\rho \log(\rho)]

    Args:
        state (Statevector or DensityMatrix): a quantum state.
        base (int): the base of the logarithm [Default: 2].

    Returns:
        float: The von-Neumann entropy S(rho).

    Raises:
        QiskitError: if the input state is not a valid QuantumState.
    """
    # pylint: disable=assignment-from-no-return
    state = _format_state(state, validate=True)
    if isinstance(state, Statevector):
        return 0
    # Density matrix case
    evals = np.maximum(np.real(la.eigvals(state.data)), 0.)
    return shannon_entropy(evals, base=base)

def mutual_information(state, base=2):
    r"""Calculate the mutual information of a bipartite state.

    The mutual information :math:`I` is given by:

    .. math::

        I(\rho_{AB}) = S(\rho_A) + S(\rho_B) - S(\rho_{AB})

    where :math:`\rho_A=Tr_B[\rho_{AB}], \rho_B=Tr_A[\rho_{AB}]`, are the
    reduced density matrices of the bipartite state :math:`\rho_{AB}`.

    Args:
        state (Statevector or DensityMatrix): a bipartite state.
        base (int): the base of the logarithm [Default: 2].

    Returns:
        float: The mutual information :math:`I(\rho_{AB})`.

    Raises:
        QiskitError: if the input state is not a valid QuantumState.
        QiskitError: if input is not a bipartite QuantumState.
    """
    state = _format_state(state, validate=True)
    if len(state.dims()) != 2:
        raise QiskitError('Input must be a bipartite quantum state.')
    rho_a = partial_trace(state, [1])
    rho_b = partial_trace(state, [0])
    return entropy(rho_a, base=base) + entropy(
        rho_b, base=base) - entropy(state, base=base)

def concurrence(state):
    r"""Calculate the concurrence of a quantum state.

    The concurrence of a bipartite
    :class:`~qiskit.quantum_info.Statevector` :math:`|\psi\rangle` is
    given by

    .. math::

        C(|\psi\rangle) = \sqrt{2(1 - Tr[\rho_0^2])}

    where :math:`\rho_0 = Tr_1[|\psi\rangle\!\langle\psi|]` is the
    reduced state from by taking the
    :math:`~qiskit.quantum_info.partial_trace` of the input state.

    For density matrices the concurrence is only defined for
    2-qubit states, it is given by:

    .. math::

        C(\rho) = \max(0, \lambda_1 - \lambda_2 - \lamda_3 - \lambda_4)

    where  :math:`\lambda _1 \ge \lambda _2 \ge \lambda _3 \ge \lambda _4`
    are the ordered eigenvalues of the matrix
    :math:`R=\sqrt{\sqrt{\rho }(Y\otimes Y)\overline{\rho}(Y\otimes Y)\sqrt{\rho}}`.

    Args:
        state (Statevector or DensityMatrix): a 2-qubit quantum state.

    Returns:
        float: The concurrence.

    Raises:
        QiskitError: if the input state is not a valid QuantumState.
        QiskitError: if input is not a bipartite QuantumState.
        QiskitError: if density matrix input is not a 2-qubit state.
    """
    # Concurrence computation requires the state to be valid
    state = _format_state(state, validate=True)
    if isinstance(state, Statevector):
        # Pure state concurrence
        dims = state.dims()
        if len(dims) != 2:
            raise QiskitError('Input is not a bipartite quantum state.')
        qargs = [0] if dims[0] > dims[1] else [1]
        rho = partial_trace(state, qargs)
        return float(np.sqrt(2 * (1 - np.real(purity(rho)))))
    # If input is a density matrix it must be a 2-qubit state
    if state.dim != 4:
        raise QiskitError('Input density matrix must be a 2-qubit state.')
    rho = DensityMatrix(state).data
    yy_mat = np.fliplr(np.diag([-1, 1, 1, -1]))
    sigma = rho.dot(yy_mat).dot(rho.conj()).dot(yy_mat)
    w = np.sort(np.real(la.eigvals(sigma)))
    w = np.sqrt(np.maximum(w, 0.))
    return max(0.0, w[-1] - np.sum(w[0:-1]))

def entanglement_of_formation(state):
    """Calculate the entanglement of formation of quantum state.

    The input quantum state must be either a bipartite state vector, or a
    2-qubit density matrix.

    Args:
        state (Statevector or DensityMatrix): a 2-qubit quantum state.

    Returns:
        float: The entanglement of formation.

    Raises:
        QiskitError: if the input state is not a valid QuantumState.
        QiskitError: if input is not a bipartite QuantumState.
        QiskitError: if density matrix input is not a 2-qubit state.
    """
    state = _format_state(state, validate=True)
    if isinstance(state, Statevector):
        # The entanglement of formation is given by the reduced state
        # entropy
        dims = state.dims()
        if len(dims) != 2:
            raise QiskitError('Input is not a bipartite quantum state.')
        qargs = [0] if dims[0] > dims[1] else [1]
        return entropy(partial_trace(state, qargs), base=2)

    # If input is a density matrix it must be a 2-qubit state
    if state.dim != 4:
        raise QiskitError('Input density matrix must be a 2-qubit state.')
    conc = concurrence(state)
    val = (1 + np.sqrt(1 - (conc ** 2))) / 2
    return shannon_entropy([val, 1 - val])
<commit_msg>Fix docstring typos in qiskit.quantum_info.concurrence. (#5386)<commit_after># This code is part of Qiskit.
#
# (C) Copyright IBM 2017.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
"""
Quantum information measures, metrics, and related functions for states.
"""

import numpy as np
import scipy.linalg as la
from qiskit.exceptions import QiskitError
from qiskit.quantum_info.states.densitymatrix import DensityMatrix, Statevector
from qiskit.quantum_info.states.utils import (partial_trace, shannon_entropy,
                                              _format_state, _funm_svd)

def state_fidelity(state1, state2, validate=True):
    r"""Return the state fidelity between two quantum states.

    The state fidelity :math:`F` for density matrix input states
    :math:`\rho_1, \rho_2` is given by

    .. math::
        F(\rho_1, \rho_2) = Tr[\sqrt{\sqrt{\rho_1}\rho_2\sqrt{\rho_1}}]^2.

    If one of the states is a pure state this simplies to
    :math:`F(\rho_1, \rho_2) = \langle\psi_1|\rho_2|\psi_1\rangle`, where
    :math:`\rho_1 = |\psi_1\rangle\!\langle\psi_1|`.

    Args:
        state1 (Statevector or DensityMatrix): the first quantum state.
        state2 (Statevector or DensityMatrix): the second quantum state.
        validate (bool): check if the inputs are valid quantum states
                         [Default: True]

    Returns:
        float: The state fidelity :math:`F(\rho_1, \rho_2)`.

    Raises:
        QiskitError: if ``validate=True`` and the inputs are invalid quantum states.
    """
    # convert input to numpy arrays
    state1 = _format_state(state1, validate=validate)
    state2 = _format_state(state2, validate=validate)

    # Get underlying numpy arrays
    arr1 = state1.data
    arr2 = state2.data
    if isinstance(state1, Statevector):
        if isinstance(state2, Statevector):
            # Fidelity of two Statevectors
            fid = np.abs(arr2.conj().dot(arr1))**2
        else:
            # Fidelity of Statevector(1) and DensityMatrix(2)
            fid = arr1.conj().dot(arr2).dot(arr1)
    elif isinstance(state2, Statevector):
        # Fidelity of Statevector(2) and DensityMatrix(1)
        fid = arr2.conj().dot(arr1).dot(arr2)
    else:
        # Fidelity of two DensityMatrices
        s1sq = _funm_svd(arr1, np.sqrt)
        s2sq = _funm_svd(arr2, np.sqrt)
        fid = np.linalg.norm(s1sq.dot(s2sq), ord='nuc')**2
    # Convert to py float rather than return np.float
    return float(np.real(fid))

def purity(state, validate=True):
    r"""Calculate the purity of a quantum state.

    The purity of a density matrix :math:`\rho` is

    .. math::

        \text{Purity}(\rho) = Tr[\rho^2]

    Args:
        state (Statevector or DensityMatrix): a quantum state.
        validate (bool): check if input state is valid [Default: True]

    Returns:
        float: the purity :math:`Tr[\rho^2]`.

    Raises:
        QiskitError: if the input isn't a valid quantum state.
    """
    state = _format_state(state, validate=validate)
    return state.purity()

def entropy(state, base=2):
    r"""Calculate the von-Neumann entropy of a quantum state.

    The entropy :math:`S` is given by

    .. math::

        S(\rho) = - Tr[\rho \log(\rho)]

    Args:
        state (Statevector or DensityMatrix): a quantum state.
        base (int): the base of the logarithm [Default: 2].

    Returns:
        float: The von-Neumann entropy S(rho).

    Raises:
        QiskitError: if the input state is not a valid QuantumState.
    """
    # pylint: disable=assignment-from-no-return
    state = _format_state(state, validate=True)
    if isinstance(state, Statevector):
        return 0
    # Density matrix case
    evals = np.maximum(np.real(la.eigvals(state.data)), 0.)
    return shannon_entropy(evals, base=base)

def mutual_information(state, base=2):
    r"""Calculate the mutual information of a bipartite state.

    The mutual information :math:`I` is given by:

    .. math::

        I(\rho_{AB}) = S(\rho_A) + S(\rho_B) - S(\rho_{AB})

    where :math:`\rho_A=Tr_B[\rho_{AB}], \rho_B=Tr_A[\rho_{AB}]`, are the
    reduced density matrices of the bipartite state :math:`\rho_{AB}`.

    Args:
        state (Statevector or DensityMatrix): a bipartite state.
        base (int): the base of the logarithm [Default: 2].

    Returns:
        float: The mutual information :math:`I(\rho_{AB})`.

    Raises:
        QiskitError: if the input state is not a valid QuantumState.
        QiskitError: if input is not a bipartite QuantumState.
    """
    state = _format_state(state, validate=True)
    if len(state.dims()) != 2:
        raise QiskitError('Input must be a bipartite quantum state.')
    rho_a = partial_trace(state, [1])
    rho_b = partial_trace(state, [0])
    return entropy(rho_a, base=base) + entropy(
        rho_b, base=base) - entropy(state, base=base)

def concurrence(state):
    r"""Calculate the concurrence of a quantum state.

    The concurrence of a bipartite
    :class:`~qiskit.quantum_info.Statevector` :math:`|\psi\rangle` is
    given by

    .. math::

        C(|\psi\rangle) = \sqrt{2(1 - Tr[\rho_0^2])}

    where :math:`\rho_0 = Tr_1[|\psi\rangle\!\langle\psi|]` is the
    reduced state from by taking the
    :func:`~qiskit.quantum_info.partial_trace` of the input state.

    For density matrices the concurrence is only defined for
    2-qubit states, it is given by:

    .. math::

        C(\rho) = \max(0, \lambda_1 - \lambda_2 - \lambda_3 - \lambda_4)

    where  :math:`\lambda _1 \ge \lambda _2 \ge \lambda _3 \ge \lambda _4`
    are the ordered eigenvalues of the matrix
    :math:`R=\sqrt{\sqrt{\rho }(Y\otimes Y)\overline{\rho}(Y\otimes Y)\sqrt{\rho}}`.

    Args:
        state (Statevector or DensityMatrix): a 2-qubit quantum state.

    Returns:
        float: The concurrence.

    Raises:
        QiskitError: if the input state is not a valid QuantumState.
        QiskitError: if input is not a bipartite QuantumState.
        QiskitError: if density matrix input is not a 2-qubit state.
    """
    # Concurrence computation requires the state to be valid
    state = _format_state(state, validate=True)
    if isinstance(state, Statevector):
        # Pure state concurrence
        dims = state.dims()
        if len(dims) != 2:
            raise QiskitError('Input is not a bipartite quantum state.')
        qargs = [0] if dims[0] > dims[1] else [1]
        rho = partial_trace(state, qargs)
        return float(np.sqrt(2 * (1 - np.real(purity(rho)))))
    # If input is a density matrix it must be a 2-qubit state
    if state.dim != 4:
        raise QiskitError('Input density matrix must be a 2-qubit state.')
    rho = DensityMatrix(state).data
    yy_mat = np.fliplr(np.diag([-1, 1, 1, -1]))
    sigma = rho.dot(yy_mat).dot(rho.conj()).dot(yy_mat)
    w = np.sort(np.real(la.eigvals(sigma)))
    w = np.sqrt(np.maximum(w, 0.))
    return max(0.0, w[-1] - np.sum(w[0:-1]))

def entanglement_of_formation(state):
    """Calculate the entanglement of formation of quantum state.

    The input quantum state must be either a bipartite state vector, or a
    2-qubit density matrix.

    Args:
        state (Statevector or DensityMatrix): a 2-qubit quantum state.

    Returns:
        float: The entanglement of formation.

    Raises:
        QiskitError: if the input state is not a valid QuantumState.
        QiskitError: if input is not a bipartite QuantumState.
        QiskitError: if density matrix input is not a 2-qubit state.
    """
    state = _format_state(state, validate=True)
    if isinstance(state, Statevector):
        # The entanglement of formation is given by the reduced state
        # entropy
        dims = state.dims()
        if len(dims) != 2:
            raise QiskitError('Input is not a bipartite quantum state.')
        qargs = [0] if dims[0] > dims[1] else [1]
        return entropy(partial_trace(state, qargs), base=2)

    # If input is a density matrix it must be a 2-qubit state
    if state.dim != 4:
        raise QiskitError('Input density matrix must be a 2-qubit state.')
    conc = concurrence(state)
    val = (1 + np.sqrt(1 - (conc ** 2))) / 2
    return shannon_entropy([val, 1 - val])
<|endoftext|>


<commit_before>import tornado.auth
import tornado.escape
import tornado.web

import zmq
import pymongo
import bson.json_util as json_util

import sockjs.tornado

from panoptes.utils import logger, database

@logger.has_logger
class MessagingConnection(sockjs.tornado.SockJSConnection):

    """ Handler for the messaging connection.

    This is the connection between the administrative web interface and
    the running `Panoptes` instance.

    Implemented with sockjs for websockets or long polling.
    """

    def __init__(self, session):
        """ """
        self.session = session

        self.logger.info('Setting up websocket mount control')

        # Get or create a socket
        self.logger.info("Getting socket connection")
        try:
            self.socket = self.user_settings['socket']
        except:
            self.context = zmq.Context()
            self.socket = self.context.socket(zmq.REQ)
        finally:
            self.logger.info("Socket created, connecting")
            self.socket.connect("tcp://localhost:5559")

        # Get or create a mongo connection
        self.logger.info("Getting connection to mongo db")
        try:
            self.db = self.user_settings['db']
        except:
            self.db = database.PanMongo()

        self._mount_connected = False

    def on_open(self, info):
        """ Action to be performed when a client first connects

        Create periodic callbacks for the admin. Callbacks include:

            * _send_environment_stats:
            * _send_mount_status:

        Note:
            Delay times for the callbacks should not be hardcoded
        """
        self.logger.info('New connection to mount established')

        self.logger.info('Creating periodic callback for sensor stats')
        self.stats_loop = tornado.ioloop.PeriodicCallback(self._send_environment_stats, 1000)
        self.stats_loop.start()

        self.logger.info('Creating periodic callback for mount stats')
        self.mount_status_loop = tornado.ioloop.PeriodicCallback(self._send_mount_status, 2000)
        self.mount_status_loop.start()

    def on_message(self, message):
        """ A message received from the client

        The client will be passing commands to our `Panoptes` instance, which
        are captured here and processed. Uses the REQ socket to communicate
        with Observatory broker

        Args:
            message(str):       Message received from client (web). This is
                command that is then passed on to the broker, which is a
                `Panoptes` instance.
        """

        self.logger.info("Message Received: {}".format(message))

        # Send message to Mount
        self.socket.send_string(message)

        # Get response
        raw_response = self.socket.recv().decode('ascii')

        response = json_util.dumps({
            'type': 'mount',
            'message': raw_response,
        })

        # Send the response back to the web socket
        self.send(response)

    def on_close(self):
        """ Actions to be performed when web admin client leaves """
        self.stats_loop.stop()
        self.mount_status_loop.stop()

    def _send_environment_stats(self):
        """ Sends the current environment stats to the web admin client

        Called periodically from the `on_open` method, this simply grabs the
        current stats from the mongo db, serializes them to json, and then sends
        to the client.
        """
        data_raw = self.db.sensors.find_one({'status': 'current', 'type': 'environment'})
        data = json_util.dumps({
            'type': 'environment',
            'message': data_raw.get('data'),
        })
        self.send(data)

    def _send_mount_status(self):
        """ Gets the status read off of the mount ands sends to admin

        """
        # Send message to Mount
        self.socket.send_string('get_status')

        # Get response - NOTE: just gets the status code,
        # which is the second character [1]. See the iOptron manual
        status_response = self.socket.recv().decode('ascii')

        if status_response == "Mount not connected":
            # Stop the mount loop since we don't have a connection
            self.mount_status_loop.stop()

            response = json_util.dumps({
                'type': 'mount_status',
                'message': status_response,
            })
        else:

            # Send message to Mount
            self.socket.send_string('current_coords')

            # Get response - NOTE: just gets the status code,
            # which is the second character [1]. See the iOptron manual
            coords_response = self.socket.recv().decode('ascii')

            # Send message to Mount
            self.socket.send_string('get_coordinates_altaz')

            # Get response - NOTE: just gets the status code,
            # which is the second character [1]. See the iOptron manual
            coords_altaz_response = self.socket.recv().decode('ascii')

            status_map = {
                '0': 'Stopped - Not at zero position',
                '1': 'Tracking (PEC Disabled)',
                '2': 'Slewing',
                '3': 'Guiding',
                '4': 'Meridian Flipping',
                '5': 'Tracking',
                '6': 'Parked',
                '7': 'Home',
            }

            response = json_util.dumps({
                'type': 'mount_status',
                'message': status_map.get(status_response[1], 'No response from mount'),
                'code': status_response,
                'coords': coords_response,
                'coords_altaz': coords_altaz_response,
            })

        # Send the response back to the web admins
        self.send(response)
<commit_msg>Do not get moutn stats<commit_after>import tornado.auth
import tornado.escape
import tornado.web

import zmq
import pymongo
import bson.json_util as json_util

import sockjs.tornado

from panoptes.utils import logger, database

@logger.has_logger
class MessagingConnection(sockjs.tornado.SockJSConnection):

    """ Handler for the messaging connection.

    This is the connection between the administrative web interface and
    the running `Panoptes` instance.

    Implemented with sockjs for websockets or long polling.
    """

    def __init__(self, session):
        """ """
        self.session = session

        self.logger.info('Setting up websocket mount control')

        # Get or create a socket
        self.logger.info("Getting socket connection")
        try:
            self.socket = self.user_settings['socket']
        except:
            self.context = zmq.Context()
            self.socket = self.context.socket(zmq.REQ)
        finally:
            self.logger.info("Socket created, connecting")
            self.socket.connect("tcp://localhost:5559")

        # Get or create a mongo connection
        self.logger.info("Getting connection to mongo db")
        try:
            self.db = self.user_settings['db']
        except:
            self.db = database.PanMongo()

        self._mount_connected = False

    def on_open(self, info):
        """ Action to be performed when a client first connects

        Create periodic callbacks for the admin. Callbacks include:

            * _send_environment_stats:
            * _send_mount_status:

        Note:
            Delay times for the callbacks should not be hardcoded
        """
        self.logger.info('New connection to mount established')

        self.logger.info('Creating periodic callback for sensor stats')
        self.stats_loop = tornado.ioloop.PeriodicCallback(self._send_environment_stats, 1000)
        self.stats_loop.start()

        self.logger.info('Creating periodic callback for mount stats')
        self.mount_status_loop = tornado.ioloop.PeriodicCallback(self._send_mount_status, 2000)
        # self.mount_status_loop.start()

    def on_message(self, message):
        """ A message received from the client

        The client will be passing commands to our `Panoptes` instance, which
        are captured here and processed. Uses the REQ socket to communicate
        with Observatory broker

        Args:
            message(str):       Message received from client (web). This is
                command that is then passed on to the broker, which is a
                `Panoptes` instance.
        """

        self.logger.info("Message Received: {}".format(message))

        # Send message to Mount
        self.socket.send_string(message)

        # Get response
        raw_response = self.socket.recv().decode('ascii')

        response = json_util.dumps({
            'type': 'mount',
            'message': raw_response,
        })

        # Send the response back to the web socket
        self.send(response)

    def on_close(self):
        """ Actions to be performed when web admin client leaves """
        self.stats_loop.stop()
        self.mount_status_loop.stop()

    def _send_environment_stats(self):
        """ Sends the current environment stats to the web admin client

        Called periodically from the `on_open` method, this simply grabs the
        current stats from the mongo db, serializes them to json, and then sends
        to the client.
        """
        data_raw = self.db.sensors.find_one({'status': 'current', 'type': 'environment'})
        data = json_util.dumps({
            'type': 'environment',
            'message': data_raw.get('data'),
        })
        self.send(data)

    def _send_mount_status(self):
        """ Gets the status read off of the mount ands sends to admin

        """
        # Send message to Mount
        self.socket.send_string('get_status')

        # Get response - NOTE: just gets the status code,
        # which is the second character [1]. See the iOptron manual
        status_response = self.socket.recv().decode('ascii')

        if status_response == "Mount not connected":
            # Stop the mount loop since we don't have a connection
            self.mount_status_loop.stop()

            response = json_util.dumps({
                'type': 'mount_status',
                'message': status_response,
            })
        else:

            # Send message to Mount
            self.socket.send_string('current_coords')

            # Get response - NOTE: just gets the status code,
            # which is the second character [1]. See the iOptron manual
            coords_response = self.socket.recv().decode('ascii')

            # Send message to Mount
            self.socket.send_string('get_coordinates_altaz')

            # Get response - NOTE: just gets the status code,
            # which is the second character [1]. See the iOptron manual
            coords_altaz_response = self.socket.recv().decode('ascii')

            status_map = {
                '0': 'Stopped - Not at zero position',
                '1': 'Tracking (PEC Disabled)',
                '2': 'Slewing',
                '3': 'Guiding',
                '4': 'Meridian Flipping',
                '5': 'Tracking',
                '6': 'Parked',
                '7': 'Home',
            }

            response = json_util.dumps({
                'type': 'mount_status',
                'message': status_map.get(status_response[1], 'No response from mount'),
                'code': status_response,
                'coords': coords_response,
                'coords_altaz': coords_altaz_response,
            })

        # Send the response back to the web admins
        self.send(response)
<|endoftext|>


<commit_before># vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright (C) 2012 Midokura Japan K.K.
# Copyright (C) 2013 Midokura PTE LTD
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
#
# @author: Tomoe Sugihara, Midokura Japan KK
# @author: Ryu Ishimoto, Midokura Japan KK

from quantum.openstack.common import log as logging

LOG = logging.getLogger(__name__)

PREFIX = 'OS_SG_'
SUFFIX_IN = '_IN'
SUFFIX_OUT = '_OUT'
OS_ROUTER_IN_CHAIN_NAME_FORMAT = 'OS_ROUTER_IN_%s'
OS_ROUTER_OUT_CHAIN_NAME_FORMAT = 'OS_ROUTER_OUT_%s'
NAME_IDENTIFIABLE_PREFIX_LEN = len(PREFIX) + 36  # 36 = length of uuid

def sg_label(sg_id, sg_name):
    """Construct the security group ID used as chain identifier in MidoNet."""
    return PREFIX + str(sg_id) + '_' + sg_name

port_group_name = sg_label

def chain_names(sg_id, sg_name):
    """Get inbound and outbound chain names."""
    prefix = sg_label(sg_id, sg_name)
    in_chain_name = prefix + SUFFIX_IN
    out_chain_name = prefix + SUFFIX_OUT
    return {'in': in_chain_name, 'out': out_chain_name}

class ChainManager:

    def __init__(self, mido_api):
        self.mido_api = mido_api

    def create_for_sg(self, tenant_id, sg_id, sg_name):
        """Create a new chain for security group.

        Creating a security group creates a pair of chains in MidoNet, one for
        inbound and the other for outbound.
        """
        LOG.debug(_("ChainManager.create_for_sg called: "
                    "tenant_id=%(tenant_id)s sg_id=%(sg_id)s "
                    "sg_name=%(sg_name)s "),
                  {'tenant_id': tenant_id, 'sg_id': sg_id, 'sg_name': sg_name})

        cnames = chain_names(sg_id, sg_name)
        self.mido_api.add_chain().tenant_id(tenant_id).name(
            cnames['in']).create()
        self.mido_api.add_chain().tenant_id(tenant_id).name(
            cnames['out']).create()

    def delete_for_sg(self, tenant_id, sg_id, sg_name):
        """Delete a chain mapped to a security group.

        Delete a SG means deleting all the chains (inbound and outbound)
        associated with the SG in MidoNet.
        """
        LOG.debug(_("ChainManager.delete_for_sg called: "
                    "tenant_id=%(tenant_id)s sg_id=%(sg_id)s "
                    "sg_name=%(sg_name)s "),
                  {'tenant_id': tenant_id, 'sg_id': sg_id, 'sg_name': sg_name})

        cnames = chain_names(sg_id, sg_name)
        chains = self.mido_api.get_chains({'tenant_id': tenant_id})
        for c in chains:
            if c.get_name() == cnames['in'] or c.get_name() == cnames['out']:
                LOG.debug(_('ChainManager.delete_for_sg: deleting chain=%r'),
                          c)
                c.delete()

    def get_router_chains(self, tenant_id, router_id):
        """Get router chains.

        Returns a dictionary that has in/out chain resources key'ed with 'in'
        and 'out' respectively, given the tenant_id and the router_id passed
        in in the arguments.
        """
        LOG.debug(_("ChainManager.get_router_chains called: "
                    "tenant_id=%(tenant_id)s router_id=%(router_id)s"),
                  {'tenant_id': tenant_id, 'router_id': router_id})

        router_chain_names = self._get_router_chain_names(router_id)
        chains = {}
        for c in self.mido_api.get_chains({'tenant_id': tenant_id}):
            if c.get_name() == router_chain_names['in']:
                chains['in'] = c
            elif c.get_name() == router_chain_names['out']:
                chains['out'] = c
        return chains

    def create_router_chains(self, tenant_id, router_id):
        """Create a new chain on a router.

        Creates chains for the router and returns the same dictionary as
        get_router_chains() returns.
        """
        LOG.debug(_("ChainManager.create_router_chains called: "
                    "tenant_id=%(tenant_id)s router_id=%(router_id)s"),
                  {'tenant_id': tenant_id, 'router_id': router_id})

        chains = {}
        router_chain_names = self._get_router_chain_names(router_id)
        chains['in'] = self.mido_api.add_chain().tenant_id(tenant_id).name(
            router_chain_names['in']).create()

        chains['out'] = self.mido_api.add_chain().tenant_id(tenant_id).name(
            router_chain_names['out']).create()
        return chains

    def get_sg_chains(self, tenant_id, sg_id):
        """Get a list of chains mapped to a security group."""
        LOG.debug(_("ChainManager.get_sg_chains called: "
                    "tenant_id=%(tenant_id)s sg_id=%(sg_id)s"),
                  {'tenant_id': tenant_id, 'sg_id': sg_id})

        cnames = chain_names(sg_id, sg_name='')
        chain_name_prefix_for_id = cnames['in'][:NAME_IDENTIFIABLE_PREFIX_LEN]
        chains = {}

        for c in self.mido_api.get_chains({'tenant_id': tenant_id}):
            if c.get_name().startswith(chain_name_prefix_for_id):
                if c.get_name().endswith(SUFFIX_IN):
                    chains['in'] = c
                if c.get_name().endswith(SUFFIX_OUT):
                    chains['out'] = c
        assert 'in' in chains
        assert 'out' in chains
        return chains

    def _get_router_chain_names(self, router_id):
        LOG.debug(_("ChainManager.get_router_chain_names called: "
                    "router_id=%(router_id)s"), {'router_id': router_id})

        in_name = OS_ROUTER_IN_CHAIN_NAME_FORMAT % router_id
        out_name = OS_ROUTER_OUT_CHAIN_NAME_FORMAT % router_id
        router_chain_names = {'in': in_name, 'out': out_name}
        return router_chain_names

class PortGroupManager:

    def __init__(self, mido_api):
        self.mido_api = mido_api

    def create(self, tenant_id, sg_id, sg_name):
        LOG.debug(_("PortGroupManager.create called: "
                    "tenant_id=%(tenant_id)s sg_id=%(sg_id)s "
                    "sg_name=%(sg_name)s"),
                  {'tenant_id': tenant_id, 'sg_id': sg_id, 'sg_name': sg_name})
        pg_name = port_group_name(sg_id, sg_name)
        self.mido_api.add_port_group().tenant_id(tenant_id).name(
            pg_name).create()

    def delete(self, tenant_id, sg_id, sg_name):
        LOG.debug(_("PortGroupManager.delete called: "
                    "tenant_id=%(tenant_id)s sg_id=%(sg_id)s "
                    "sg_name=%(sg_name)s"),
                  {'tenant_id': tenant_id, 'sg_id': sg_id, 'sg_name': sg_name})
        pg_name = port_group_name(sg_id, sg_name)
        pgs = self.mido_api.get_port_groups({'tenant_id': tenant_id})
        for pg in pgs:
            if pg.get_name() == pg_name:
                LOG.debug(_("PortGroupManager.delete: deleting pg=%r"), pg)
                pg.delete()

    def get_for_sg(self, tenant_id, sg_id):
        LOG.debug(_("PortGroupManager.get_for_sg called: "
                    "tenant_id=%(tenant_id)s sg_id=%(sg_id)s"),
                  {'tenant_id': tenant_id, 'sg_id': sg_id})

        pg_name_prefix = port_group_name(
            sg_id, sg_name='')[:NAME_IDENTIFIABLE_PREFIX_LEN]
        port_groups = self.mido_api.get_port_groups({'tenant_id': tenant_id})
        for pg in port_groups:
            if pg.get_name().startswith(pg_name_prefix):
                LOG.debug(_("PortGroupManager.get_for_sg exiting: pg=%r"), pg)
                return pg
        return None

class RuleManager:

    OS_SG_KEY = 'os_sg_rule_id'

    def __init__(self, mido_api):
        self.mido_api = mido_api
        self.chain_manager = ChainManager(mido_api)
        self.pg_manager = PortGroupManager(mido_api)

    def _properties(self, os_sg_rule_id):
        return {self.OS_SG_KEY: str(os_sg_rule_id)}

    def create_for_sg_rule(self, rule):
        LOG.debug(_("RuleManager.create_for_sg_rule called: rule=%r"), rule)

        direction = rule['direction']
        protocol = rule['protocol']
        port_range_max = rule['port_range_max']
        rule_id = rule['id']
        security_group_id = rule['security_group_id']
        remote_group_id = rule['remote_group_id']
        remote_ip_prefix = rule['remote_ip_prefix']  # watch out. not validated
        tenant_id = rule['tenant_id']
        port_range_min = rule['port_range_min']

        # construct a corresponding rule
        tp_src_start = tp_src_end = None
        tp_dst_start = tp_dst_end = None
        nw_src_address = None
        nw_src_length = None
        port_group_id = None

        # handle source
        if not remote_ip_prefix is None:
            nw_src_address, nw_src_length = remote_ip_prefix.split('/')
        elif not remote_group_id is None:  # security group as a srouce
            source_pg = self.pg_manager.get_for_sg(tenant_id, remote_group_id)
            port_group_id = source_pg.get_id()
        else:
            raise Exception(_("Don't know what to do with rule=%r"), rule)

        # dst ports
        tp_dst_start, tp_dst_end = port_range_min, port_range_max

        # protocol
        if protocol == 'tcp':
            nw_proto = 6
        elif protocol == 'udp':
            nw_proto = 17
        elif protocol == 'icmp':
            nw_proto = 1
            # extract type and code from reporposed fields
            icmp_type = rule['from_port']
            icmp_code = rule['to_port']

            # translate -1(wildcard in OS) to midonet wildcard
            if icmp_type == -1:
                icmp_type = None
            if icmp_code == -1:
                icmp_code = None

            # set data for midonet rule
            tp_src_start = tp_src_end = icmp_type
            tp_dst_start = tp_dst_end = icmp_code

        chains = self.chain_manager.get_sg_chains(tenant_id, security_group_id)
        chain = None
        if direction == 'egress':
            chain = chains['in']
        elif direction == 'ingress':
            chain = chains['out']
        else:
            raise Exception(_("Don't know what to do with rule=%r"), rule)

        # create an accept rule
        properties = self._properties(rule_id)
        LOG.debug(_("RuleManager.create_for_sg_rule: adding accept rule "
                    "%(rule_id) in portgroup %(port_group_id)s"),
                  {'rule_id': rule_id, 'port_group_id': port_group_id})
        chain.add_rule().port_group(port_group_id).type('accept').nw_proto(
            nw_proto).nw_src_address(nw_src_address).nw_src_length(
                nw_src_length).tp_src_start(tp_src_start).tp_src_end(
                    tp_src_end).tp_dst_start(tp_dst_start).tp_dst_end(
                        tp_dst_end).properties(properties).create()

    def delete_for_sg_rule(self, rule):
        LOG.debug(_("RuleManager.delete_for_sg_rule called: rule=%r"), rule)

        tenant_id = rule['tenant_id']
        security_group_id = rule['security_group_id']
        rule_id = rule['id']

        properties = self._properties(rule_id)
        # search for the chains to find the rule to delete
        chains = self.chain_manager.get_sg_chains(tenant_id, security_group_id)
        for c in chains['in'], chains['out']:
            rules = c.get_rules()
            for r in rules:
                if r.get_properties() == properties:
                    LOG.debug(_("RuleManager.delete_for_sg_rule: deleting "
                                "rule %r"), r)
                    r.delete()
<commit_msg>Added conversion specifier for proper log<commit_after># vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright (C) 2012 Midokura Japan K.K.
# Copyright (C) 2013 Midokura PTE LTD
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
#
# @author: Tomoe Sugihara, Midokura Japan KK
# @author: Ryu Ishimoto, Midokura Japan KK

from quantum.openstack.common import log as logging

LOG = logging.getLogger(__name__)

PREFIX = 'OS_SG_'
SUFFIX_IN = '_IN'
SUFFIX_OUT = '_OUT'
OS_ROUTER_IN_CHAIN_NAME_FORMAT = 'OS_ROUTER_IN_%s'
OS_ROUTER_OUT_CHAIN_NAME_FORMAT = 'OS_ROUTER_OUT_%s'
NAME_IDENTIFIABLE_PREFIX_LEN = len(PREFIX) + 36  # 36 = length of uuid

def sg_label(sg_id, sg_name):
    """Construct the security group ID used as chain identifier in MidoNet."""
    return PREFIX + str(sg_id) + '_' + sg_name

port_group_name = sg_label

def chain_names(sg_id, sg_name):
    """Get inbound and outbound chain names."""
    prefix = sg_label(sg_id, sg_name)
    in_chain_name = prefix + SUFFIX_IN
    out_chain_name = prefix + SUFFIX_OUT
    return {'in': in_chain_name, 'out': out_chain_name}

class ChainManager:

    def __init__(self, mido_api):
        self.mido_api = mido_api

    def create_for_sg(self, tenant_id, sg_id, sg_name):
        """Create a new chain for security group.

        Creating a security group creates a pair of chains in MidoNet, one for
        inbound and the other for outbound.
        """
        LOG.debug(_("ChainManager.create_for_sg called: "
                    "tenant_id=%(tenant_id)s sg_id=%(sg_id)s "
                    "sg_name=%(sg_name)s "),
                  {'tenant_id': tenant_id, 'sg_id': sg_id, 'sg_name': sg_name})

        cnames = chain_names(sg_id, sg_name)
        self.mido_api.add_chain().tenant_id(tenant_id).name(
            cnames['in']).create()
        self.mido_api.add_chain().tenant_id(tenant_id).name(
            cnames['out']).create()

    def delete_for_sg(self, tenant_id, sg_id, sg_name):
        """Delete a chain mapped to a security group.

        Delete a SG means deleting all the chains (inbound and outbound)
        associated with the SG in MidoNet.
        """
        LOG.debug(_("ChainManager.delete_for_sg called: "
                    "tenant_id=%(tenant_id)s sg_id=%(sg_id)s "
                    "sg_name=%(sg_name)s "),
                  {'tenant_id': tenant_id, 'sg_id': sg_id, 'sg_name': sg_name})

        cnames = chain_names(sg_id, sg_name)
        chains = self.mido_api.get_chains({'tenant_id': tenant_id})
        for c in chains:
            if c.get_name() == cnames['in'] or c.get_name() == cnames['out']:
                LOG.debug(_('ChainManager.delete_for_sg: deleting chain=%r'),
                          c)
                c.delete()

    def get_router_chains(self, tenant_id, router_id):
        """Get router chains.

        Returns a dictionary that has in/out chain resources key'ed with 'in'
        and 'out' respectively, given the tenant_id and the router_id passed
        in in the arguments.
        """
        LOG.debug(_("ChainManager.get_router_chains called: "
                    "tenant_id=%(tenant_id)s router_id=%(router_id)s"),
                  {'tenant_id': tenant_id, 'router_id': router_id})

        router_chain_names = self._get_router_chain_names(router_id)
        chains = {}
        for c in self.mido_api.get_chains({'tenant_id': tenant_id}):
            if c.get_name() == router_chain_names['in']:
                chains['in'] = c
            elif c.get_name() == router_chain_names['out']:
                chains['out'] = c
        return chains

    def create_router_chains(self, tenant_id, router_id):
        """Create a new chain on a router.

        Creates chains for the router and returns the same dictionary as
        get_router_chains() returns.
        """
        LOG.debug(_("ChainManager.create_router_chains called: "
                    "tenant_id=%(tenant_id)s router_id=%(router_id)s"),
                  {'tenant_id': tenant_id, 'router_id': router_id})

        chains = {}
        router_chain_names = self._get_router_chain_names(router_id)
        chains['in'] = self.mido_api.add_chain().tenant_id(tenant_id).name(
            router_chain_names['in']).create()

        chains['out'] = self.mido_api.add_chain().tenant_id(tenant_id).name(
            router_chain_names['out']).create()
        return chains

    def get_sg_chains(self, tenant_id, sg_id):
        """Get a list of chains mapped to a security group."""
        LOG.debug(_("ChainManager.get_sg_chains called: "
                    "tenant_id=%(tenant_id)s sg_id=%(sg_id)s"),
                  {'tenant_id': tenant_id, 'sg_id': sg_id})

        cnames = chain_names(sg_id, sg_name='')
        chain_name_prefix_for_id = cnames['in'][:NAME_IDENTIFIABLE_PREFIX_LEN]
        chains = {}

        for c in self.mido_api.get_chains({'tenant_id': tenant_id}):
            if c.get_name().startswith(chain_name_prefix_for_id):
                if c.get_name().endswith(SUFFIX_IN):
                    chains['in'] = c
                if c.get_name().endswith(SUFFIX_OUT):
                    chains['out'] = c
        assert 'in' in chains
        assert 'out' in chains
        return chains

    def _get_router_chain_names(self, router_id):
        LOG.debug(_("ChainManager.get_router_chain_names called: "
                    "router_id=%(router_id)s"), {'router_id': router_id})

        in_name = OS_ROUTER_IN_CHAIN_NAME_FORMAT % router_id
        out_name = OS_ROUTER_OUT_CHAIN_NAME_FORMAT % router_id
        router_chain_names = {'in': in_name, 'out': out_name}
        return router_chain_names

class PortGroupManager:

    def __init__(self, mido_api):
        self.mido_api = mido_api

    def create(self, tenant_id, sg_id, sg_name):
        LOG.debug(_("PortGroupManager.create called: "
                    "tenant_id=%(tenant_id)s sg_id=%(sg_id)s "
                    "sg_name=%(sg_name)s"),
                  {'tenant_id': tenant_id, 'sg_id': sg_id, 'sg_name': sg_name})
        pg_name = port_group_name(sg_id, sg_name)
        self.mido_api.add_port_group().tenant_id(tenant_id).name(
            pg_name).create()

    def delete(self, tenant_id, sg_id, sg_name):
        LOG.debug(_("PortGroupManager.delete called: "
                    "tenant_id=%(tenant_id)s sg_id=%(sg_id)s "
                    "sg_name=%(sg_name)s"),
                  {'tenant_id': tenant_id, 'sg_id': sg_id, 'sg_name': sg_name})
        pg_name = port_group_name(sg_id, sg_name)
        pgs = self.mido_api.get_port_groups({'tenant_id': tenant_id})
        for pg in pgs:
            if pg.get_name() == pg_name:
                LOG.debug(_("PortGroupManager.delete: deleting pg=%r"), pg)
                pg.delete()

    def get_for_sg(self, tenant_id, sg_id):
        LOG.debug(_("PortGroupManager.get_for_sg called: "
                    "tenant_id=%(tenant_id)s sg_id=%(sg_id)s"),
                  {'tenant_id': tenant_id, 'sg_id': sg_id})

        pg_name_prefix = port_group_name(
            sg_id, sg_name='')[:NAME_IDENTIFIABLE_PREFIX_LEN]
        port_groups = self.mido_api.get_port_groups({'tenant_id': tenant_id})
        for pg in port_groups:
            if pg.get_name().startswith(pg_name_prefix):
                LOG.debug(_("PortGroupManager.get_for_sg exiting: pg=%r"), pg)
                return pg
        return None

class RuleManager:

    OS_SG_KEY = 'os_sg_rule_id'

    def __init__(self, mido_api):
        self.mido_api = mido_api
        self.chain_manager = ChainManager(mido_api)
        self.pg_manager = PortGroupManager(mido_api)

    def _properties(self, os_sg_rule_id):
        return {self.OS_SG_KEY: str(os_sg_rule_id)}

    def create_for_sg_rule(self, rule):
        LOG.debug(_("RuleManager.create_for_sg_rule called: rule=%r"), rule)

        direction = rule['direction']
        protocol = rule['protocol']
        port_range_max = rule['port_range_max']
        rule_id = rule['id']
        security_group_id = rule['security_group_id']
        remote_group_id = rule['remote_group_id']
        remote_ip_prefix = rule['remote_ip_prefix']  # watch out. not validated
        tenant_id = rule['tenant_id']
        port_range_min = rule['port_range_min']

        # construct a corresponding rule
        tp_src_start = tp_src_end = None
        tp_dst_start = tp_dst_end = None
        nw_src_address = None
        nw_src_length = None
        port_group_id = None

        # handle source
        if not remote_ip_prefix is None:
            nw_src_address, nw_src_length = remote_ip_prefix.split('/')
        elif not remote_group_id is None:  # security group as a srouce
            source_pg = self.pg_manager.get_for_sg(tenant_id, remote_group_id)
            port_group_id = source_pg.get_id()
        else:
            raise Exception(_("Don't know what to do with rule=%r"), rule)

        # dst ports
        tp_dst_start, tp_dst_end = port_range_min, port_range_max

        # protocol
        if protocol == 'tcp':
            nw_proto = 6
        elif protocol == 'udp':
            nw_proto = 17
        elif protocol == 'icmp':
            nw_proto = 1
            # extract type and code from reporposed fields
            icmp_type = rule['from_port']
            icmp_code = rule['to_port']

            # translate -1(wildcard in OS) to midonet wildcard
            if icmp_type == -1:
                icmp_type = None
            if icmp_code == -1:
                icmp_code = None

            # set data for midonet rule
            tp_src_start = tp_src_end = icmp_type
            tp_dst_start = tp_dst_end = icmp_code

        chains = self.chain_manager.get_sg_chains(tenant_id, security_group_id)
        chain = None
        if direction == 'egress':
            chain = chains['in']
        elif direction == 'ingress':
            chain = chains['out']
        else:
            raise Exception(_("Don't know what to do with rule=%r"), rule)

        # create an accept rule
        properties = self._properties(rule_id)
        LOG.debug(_("RuleManager.create_for_sg_rule: adding accept rule "
                    "%(rule_id)s in portgroup %(port_group_id)s"),
                  {'rule_id': rule_id, 'port_group_id': port_group_id})
        chain.add_rule().port_group(port_group_id).type('accept').nw_proto(
            nw_proto).nw_src_address(nw_src_address).nw_src_length(
                nw_src_length).tp_src_start(tp_src_start).tp_src_end(
                    tp_src_end).tp_dst_start(tp_dst_start).tp_dst_end(
                        tp_dst_end).properties(properties).create()

    def delete_for_sg_rule(self, rule):
        LOG.debug(_("RuleManager.delete_for_sg_rule called: rule=%r"), rule)

        tenant_id = rule['tenant_id']
        security_group_id = rule['security_group_id']
        rule_id = rule['id']

        properties = self._properties(rule_id)
        # search for the chains to find the rule to delete
        chains = self.chain_manager.get_sg_chains(tenant_id, security_group_id)
        for c in chains['in'], chains['out']:
            rules = c.get_rules()
            for r in rules:
                if r.get_properties() == properties:
                    LOG.debug(_("RuleManager.delete_for_sg_rule: deleting "
                                "rule %r"), r)
                    r.delete()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright (C) 2014-2017 GEM Foundation
#
# OpenQuake is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenQuake is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with OpenQuake. If not, see <http://www.gnu.org/licenses/>.

import logging
import numpy

from openquake.commonlib import calc
from openquake.calculators import base, event_based_risk as ebr

U16 = numpy.uint16
F32 = numpy.float32
U64 = numpy.uint64
F64 = numpy.float64  # higher precision to avoid task order dependency
stat_dt = numpy.dtype([('mean', F32), ('stddev', F32)])

@base.calculators.add('gmf_ebrisk')
class GmfEbRiskCalculator(base.RiskCalculator):
    """
    Run an event based risk calculation starting from precomputed GMFs
    """
    core_task = ebr.event_based_risk
    pre_calculator = None
    is_stochastic = True

    def pre_execute(self):
        logging.warn('%s is still experimental', self.__class__.__name__)
        base.RiskCalculator.pre_execute(self)
        oq = self.oqparam
        self.L = len(self.riskmodel.lti)
        self.T = len(self.assetcol.tags())
        self.A = len(self.assetcol)
        self.E = oq.number_of_ground_motion_fields
        self.I = oq.insured_losses + 1
        if oq.ignore_covs:
            eps = numpy.zeros((self.A, self.E), numpy.float32)
        else:
            logging.info('Building the epsilons')
            eps = self.make_eps(self.E)
        eids, gmfs = base.get_gmfs(self)  # shape (R, N, E, I)
        self.R = len(gmfs)
        self.riskinputs = self.build_riskinputs('gmf', eps, eids)
        self.param['assetcol'] = self.assetcol
        self.param['insured_losses'] = oq.insured_losses
        self.param['avg_losses'] = oq.avg_losses
        self.param['ses_ratio'] = oq.ses_ratio
        self.param['asset_loss_table'] = oq.asset_loss_table
        self.param['elt_dt'] = numpy.dtype(
            [('eid', U64), ('rlzi', U16), ('loss', (F32, (self.L * self.I,)))])
        self.taskno = 0
        self.start = 0
        self.datastore.create_dset('losses_by_tag-rlzs', F32,
                                   (self.T, self.R, self.L * self.I))

        avg_losses = self.oqparam.avg_losses
        if avg_losses:
            self.dset = self.datastore.create_dset(
                'avg_losses-rlzs', F32, (self.A, self.R, self.L * self.I))

        events = numpy.zeros(oq.number_of_ground_motion_fields,
                             calc.stored_event_dt)
        events['eid'] = eids
        self.datastore['events'] = events

    def post_execute(self, result):
        pass

    def combine(self, dummy, res):
        """
        :param dummy: unused parameter
        :param res: a result dictionary
        """
        ebr.EbriskCalculator.__dict__['save_losses'](self, res, self.taskno)
<commit_msg>Fixed another import [skip hazardlib]<commit_after># -*- coding: utf-8 -*-
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright (C) 2014-2017 GEM Foundation
#
# OpenQuake is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenQuake is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with OpenQuake. If not, see <http://www.gnu.org/licenses/>.

import logging
import numpy

from openquake.commonlib import readinput
from openquake.calculators import base, event_based_risk as ebr

U16 = numpy.uint16
F32 = numpy.float32
U64 = numpy.uint64
F64 = numpy.float64  # higher precision to avoid task order dependency
stat_dt = numpy.dtype([('mean', F32), ('stddev', F32)])

@base.calculators.add('gmf_ebrisk')
class GmfEbRiskCalculator(base.RiskCalculator):
    """
    Run an event based risk calculation starting from precomputed GMFs
    """
    core_task = ebr.event_based_risk
    pre_calculator = None
    is_stochastic = True

    def pre_execute(self):
        logging.warn('%s is still experimental', self.__class__.__name__)
        base.RiskCalculator.pre_execute(self)
        oq = self.oqparam
        self.L = len(self.riskmodel.lti)
        self.T = len(self.assetcol.tags())
        self.A = len(self.assetcol)
        self.E = oq.number_of_ground_motion_fields
        self.I = oq.insured_losses + 1
        if oq.ignore_covs:
            eps = numpy.zeros((self.A, self.E), numpy.float32)
        else:
            logging.info('Building the epsilons')
            eps = self.make_eps(self.E)
        eids, gmfs = base.get_gmfs(self)  # shape (R, N, E, I)
        self.R = len(gmfs)
        self.riskinputs = self.build_riskinputs('gmf', eps, eids)
        self.param['assetcol'] = self.assetcol
        self.param['insured_losses'] = oq.insured_losses
        self.param['avg_losses'] = oq.avg_losses
        self.param['ses_ratio'] = oq.ses_ratio
        self.param['asset_loss_table'] = oq.asset_loss_table
        self.param['elt_dt'] = numpy.dtype(
            [('eid', U64), ('rlzi', U16), ('loss', (F32, (self.L * self.I,)))])
        self.taskno = 0
        self.start = 0
        self.datastore.create_dset('losses_by_tag-rlzs', F32,
                                   (self.T, self.R, self.L * self.I))

        avg_losses = self.oqparam.avg_losses
        if avg_losses:
            self.dset = self.datastore.create_dset(
                'avg_losses-rlzs', F32, (self.A, self.R, self.L * self.I))

        events = numpy.zeros(oq.number_of_ground_motion_fields,
                             readinput.stored_event_dt)
        events['eid'] = eids
        self.datastore['events'] = events

    def post_execute(self, result):
        pass

    def combine(self, dummy, res):
        """
        :param dummy: unused parameter
        :param res: a result dictionary
        """
        ebr.EbriskCalculator.__dict__['save_losses'](self, res, self.taskno)
<|endoftext|>