<commit_before>import urllib2

from django.utils.http import urlencode
from mezzanine.conf import settings

from cartridge.shop.checkout import CheckoutError

AUTH_NET_LIVE = 'https://secure.authorize.net/gateway/transact.dll'
AUTH_NET_TEST = 'https://test.authorize.net/gateway/transact.dll'
# replace this with your authroize.net login
AUTH_NET_LOGIN = settings.AUTH_NET_LIVE
# replace with your transaction key
AUTH_NET_TRANS_KEY = settings.AUTH_NET_TRANS_KEY

def process(request, order_form, order):
    """
    Raise cartridge.shop.checkout.CheckoutError("error message") if
    payment is unsuccessful.
    """

    trans = {}
    amount = order.total
    trans['amount'] = amount
    if settings.DEBUG:
        trans['connection'] = AUTH_NET_TEST
    else:
        trans['connection'] = AUTH_NET_LIVE
    trans['authorize_only'] = False
    trans['configuration'] = {
        'x_login': AUTH_NET_LOGIN,
        'x_tran_key': AUTH_NET_TRANS_KEY,
        'x_version': '3.1',
        'x_relay_response': 'FALSE',
        'x_test_request': 'FALSE',
        'x_delim_data': 'TRUE',
        'x_delim_char': '|',
        # could be set to AUTH_ONLY to only authorize but not capture payment
        'x_type': 'AUTH_CAPTURE',
        'x_method': 'CC',
    }
    data = order_form.cleaned_data
    trans['custBillData'] = {
        'x_first_name': data['billing_detail_first_name'],
        'x_last_name': data['billing_detail_last_name'],
        'x_address': data['billing_detail_street'],
        'x_city': data['billing_detail_city'],
        'x_state': data['billing_detail_state'],
        'x_zip': data['billing_detail_postcode'],
        'x_country': data['billing_detail_country'],
        'x_phone': data['billing_detail_phone'],
        'x_email': data['billing_detail_email'],
    }

    trans['custShipData'] = {
        'x_ship_to_first_name': data['shipping_detail_first_name'],
        'x_ship_to_last_name': data['shipping_detail_last_name'],
        'x_ship_to_address': data['shipping_detail_street'],
        'x_ship_to_city': data['shipping_detail_city'],
        'x_ship_to_state': data['shipping_detail_state'],
        'x_ship_to_zip': data['shipping_detail_postcode'],
        'x_ship_to_country': data['shipping_detail_country'],
    }
    trans['transactionData'] = {
        'x_amount': amount,
        'x_card_num': data['card_number'],
        'x_exp_date': (data['card_expiry_month'] + "/" +
                       data['card_expiry_year']),
        'x_card_code': data['card_ccv'],
        'x_invoice_num': str(order.id)
    }

    part1 = urlencode(trans['configuration']) + "&"
    part2 = "&" + urlencode(trans['custBillData'])
    part3 = "&" + urlencode(trans['custShipData'])
    trans['postString'] = (part1 + urlencode(trans['transactionData']) +
                           part2 + part3)

    conn = urllib2.Request(url=trans['connection'], data=trans['postString'])
    # useful for debugging transactions
    #print trans['postString']
    try:
        f = urllib2.urlopen(conn)
        all_results = f.read()
    except urllib2.URLError:
        raise CheckoutError("Could not talk to authorize.net payment gateway")

    parsed_results = all_results.split(trans['configuration']['x_delim_char'])
    # response and response_reason_codes with their meaning here:
    # http://www.authorize.net/support/merchant/Transaction_Response/
    # Response_Reason_Codes_and_Response_Reason_Text.htm
    # not exactly sure what the reason code is
    response_code = parsed_results[0]
    #reason_code = parsed_results[1]
    #response_reason_code = parsed_results[2]
    #response_text = parsed_results[3]
    #transaction_id = parsed_results[6]
    success = response_code == '1'
    if not success:
        raise CheckoutError("Transaction declined: " + parsed_results[2])
    return parsed_results[6]
<commit_msg>Fixed settings names in cartridge.shop.payment.authorizenet and added a clearer error when they're not defined.<commit_after>import urllib2

from django.core.exceptions import ImproperlyConfigured
from django.utils.http import urlencode
from mezzanine.conf import settings

from cartridge.shop.checkout import CheckoutError

AUTH_NET_LIVE = 'https://secure.authorize.net/gateway/transact.dll'
AUTH_NET_TEST = 'https://test.authorize.net/gateway/transact.dll'
try:
    AUTH_NET_LOGIN = settings.AUTH_NET_LOGIN
    AUTH_NET_TRANS_KEY = settings.AUTH_NET_TRANS_KEY
except AttributeError:
    raise ImproperlyConfigured("You need to define AUTH_NET_LOGIN and "
                               "AUTH_NET_TRANS_KEY in your settings module "
                               "to use the authorizenet payment processor.")

def process(request, order_form, order):
    """
    Raise cartridge.shop.checkout.CheckoutError("error message") if
    payment is unsuccessful.
    """

    trans = {}
    amount = order.total
    trans['amount'] = amount
    if settings.DEBUG:
        trans['connection'] = AUTH_NET_TEST
    else:
        trans['connection'] = AUTH_NET_LIVE
    trans['authorize_only'] = False
    trans['configuration'] = {
        'x_login': AUTH_NET_LOGIN,
        'x_tran_key': AUTH_NET_TRANS_KEY,
        'x_version': '3.1',
        'x_relay_response': 'FALSE',
        'x_test_request': 'FALSE',
        'x_delim_data': 'TRUE',
        'x_delim_char': '|',
        # could be set to AUTH_ONLY to only authorize but not capture payment
        'x_type': 'AUTH_CAPTURE',
        'x_method': 'CC',
    }
    data = order_form.cleaned_data
    trans['custBillData'] = {
        'x_first_name': data['billing_detail_first_name'],
        'x_last_name': data['billing_detail_last_name'],
        'x_address': data['billing_detail_street'],
        'x_city': data['billing_detail_city'],
        'x_state': data['billing_detail_state'],
        'x_zip': data['billing_detail_postcode'],
        'x_country': data['billing_detail_country'],
        'x_phone': data['billing_detail_phone'],
        'x_email': data['billing_detail_email'],
    }

    trans['custShipData'] = {
        'x_ship_to_first_name': data['shipping_detail_first_name'],
        'x_ship_to_last_name': data['shipping_detail_last_name'],
        'x_ship_to_address': data['shipping_detail_street'],
        'x_ship_to_city': data['shipping_detail_city'],
        'x_ship_to_state': data['shipping_detail_state'],
        'x_ship_to_zip': data['shipping_detail_postcode'],
        'x_ship_to_country': data['shipping_detail_country'],
    }
    trans['transactionData'] = {
        'x_amount': amount,
        'x_card_num': data['card_number'],
        'x_exp_date': (data['card_expiry_month'] + "/" +
                       data['card_expiry_year']),
        'x_card_code': data['card_ccv'],
        'x_invoice_num': str(order.id)
    }

    part1 = urlencode(trans['configuration']) + "&"
    part2 = "&" + urlencode(trans['custBillData'])
    part3 = "&" + urlencode(trans['custShipData'])
    trans['postString'] = (part1 + urlencode(trans['transactionData']) +
                           part2 + part3)

    conn = urllib2.Request(url=trans['connection'], data=trans['postString'])
    # useful for debugging transactions
    #print trans['postString']
    try:
        f = urllib2.urlopen(conn)
        all_results = f.read()
    except urllib2.URLError:
        raise CheckoutError("Could not talk to authorize.net payment gateway")

    parsed_results = all_results.split(trans['configuration']['x_delim_char'])
    # response and response_reason_codes with their meaning here:
    # http://www.authorize.net/support/merchant/Transaction_Response/
    # Response_Reason_Codes_and_Response_Reason_Text.htm
    # not exactly sure what the reason code is
    response_code = parsed_results[0]
    #reason_code = parsed_results[1]
    #response_reason_code = parsed_results[2]
    #response_text = parsed_results[3]
    #transaction_id = parsed_results[6]
    success = response_code == '1'
    if not success:
        raise CheckoutError("Transaction declined: " + parsed_results[2])
    return parsed_results[6]
<|endoftext|>


<commit_before># Copyright 2017 The Bazel Authors. 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.

"""Rules for executing programs in the nodejs runtime.
"""
load(":common/module_mappings.bzl", "module_mappings_runtime_aspect")

def _sources_aspect_impl(target, ctx):
  result = depset()
  if hasattr(ctx.rule.attr, "deps"):
    for dep in ctx.rule.attr.deps:
      if hasattr(dep, "node_sources"):
        result += dep.node_sources
  # Note layering: until we have JS interop providers, this needs to know how to
  # get TypeScript outputs.
  if hasattr(target, "typescript"):
    result += target.typescript.es5_sources
  elif hasattr(target, "files"):
    result += target.files
  return struct(node_sources = result)

sources_aspect = aspect(
    _sources_aspect_impl,
    attr_aspects = ["deps"],
)

def _write_loader_script(ctx):
  # Generates the JavaScript snippet of module roots mappings, with each entry
  # in the form:
  #   {module_name: /^mod_name\b/, module_root: 'path/to/mod_name'}
  module_mappings = []
  for d in ctx.attr.data:
    if hasattr(d, "runfiles_module_mappings"):
      for [mn, mr] in d.runfiles_module_mappings.items():
        escaped = mn.replace("/", r"\/").replace(".", r"\.")
        mapping = r"{module_name: /^%s\b/, module_root: '%s'}" % (escaped, mr)
        module_mappings.append(mapping)
  ctx.template_action(
      template=ctx.file._loader_template,
      output=ctx.outputs.loader,
      substitutions={
          "TEMPLATED_module_roots": "\n  " + ",\n  ".join(module_mappings),
          "TEMPLATED_entry_point": ctx.attr.entry_point,
          "TEMPLATED_label_package": ctx.attr.node_modules.label.package,
          "TEMPLATED_workspace_name": (
              ctx.label.workspace_root.split("/")[1]
              if ctx.label.workspace_root
              else ctx.workspace_name),
      },
      executable=True,
  )

def expand_location_into_runfiles(ctx, input):
  """Given a string that might contain $(location) label expansions,
   provide the path to the file in runfiles.
   See https://docs.bazel.build/versions/master/skylark/lib/ctx.html#expand_location
  """
  targets = ctx.attr.data if hasattr(ctx.attr, "data") else []
  expanded = ctx.expand_location(input, targets)
  if expanded.startswith(ctx.bin_dir.path):
    expanded = expanded[len(ctx.bin_dir.path + "/"):]
  if expanded.startswith(ctx.genfiles_dir.path):
    expanded = expanded[len(ctx.genfiles_dir.path + "/"):]
  return ctx.workspace_name + "/" + expanded

def _nodejs_binary_impl(ctx):
    node = ctx.file._node
    node_modules = ctx.files.node_modules
    sources = depset()
    for d in ctx.attr.data:
      if hasattr(d, "node_sources"):
        sources += d.node_sources

    _write_loader_script(ctx)

    # Avoid writing non-normalized paths (workspace/../other_workspace/path)
    if ctx.outputs.loader.short_path.startswith("../"):
      script_path = ctx.outputs.loader.short_path[len("../"):]
    else:
      script_path = "/".join([
          ctx.workspace_name,
          ctx.outputs.loader.short_path,
      ])
    substitutions = {
        "TEMPLATED_node": ctx.workspace_name + "/" + node.path,
        "TEMPLATED_args": " ".join([
            expand_location_into_runfiles(ctx, a)
            for a in ctx.attr.templated_args]),
        "TEMPLATED_script_path": script_path,
    }
    # Write the output twice.
    # In order to have the name "nodejs_test", the rule must be declared
    # with test = True, which means we must write an output called "executable".
    # However, in order to wrap with a sh_test for Windows, we must be able to
    # get a single output file with a ".sh" extension.
    ctx.template_action(
        template=ctx.file._launcher_template,
        output=ctx.outputs.executable,
        substitutions=substitutions,
        executable=True,
    )
    ctx.template_action(
        template=ctx.file._launcher_template,
        output=ctx.outputs.script,
        substitutions=substitutions,
        executable=True,
    )

    runfiles = depset(sources)
    runfiles += [node]
    runfiles += [ctx.outputs.loader]
    runfiles += node_modules

    return struct(
        runfiles = ctx.runfiles(
            transitive_files = runfiles,
            files = [node, ctx.outputs.loader] + node_modules + sources.to_list(),
            collect_data = True,
        ),
    )

_NODEJS_EXECUTABLE_ATTRS = {
    "entry_point": attr.string(mandatory = True),
    "data": attr.label_list(
        allow_files = True,
        cfg = "data",
        aspects=[sources_aspect, module_mappings_runtime_aspect]),
    "templated_args": attr.string_list(),
    "_node": attr.label(
        default = Label("@nodejs//:node"),
        allow_files = True,
        single_file = True),
    "node_modules": attr.label(
        default = Label("@//:node_modules")),
    "_launcher_template": attr.label(
        default = Label("//internal:node_launcher.sh"),
        allow_files = True,
        single_file = True),
    "_loader_template": attr.label(
        default = Label("//internal:node_loader.js"),
        allow_files = True,
        single_file = True),
}

_NODEJS_EXECUTABLE_OUTPUTS = {
    "loader": "%{name}_loader.js",
    "script": "%{name}.sh",
}

# The name of the declared rule appears in
# bazel query --output=label_kind
# So we make these match what the user types in their BUILD file
# and duplicate the definitions to give two distinct symbols.
nodejs_binary = rule(
    implementation = _nodejs_binary_impl,
    attrs = _NODEJS_EXECUTABLE_ATTRS,
    executable = True,
    outputs = _NODEJS_EXECUTABLE_OUTPUTS,
)
nodejs_test = rule(
    implementation = _nodejs_binary_impl,
    attrs = _NODEJS_EXECUTABLE_ATTRS,
    test = True,
    outputs = _NODEJS_EXECUTABLE_OUTPUTS,
)

# Wrap in an sh_binary for windows .exe wrapper.
def nodejs_binary_macro(name, args=[], visibility=None, **kwargs):
  nodejs_binary(
      name = "%s_bin" % name,
      **kwargs
  )

  native.sh_binary(
      name = name,
      args = args,
      srcs = [":%s_bin.sh" % name],
      data = [":%s_bin" % name],
      visibility = visibility,
  )

# Wrap in an sh_test for windows .exe wrapper.
def nodejs_test_macro(name, args=[], visibility=None, **kwargs):
  nodejs_test(
      name = "%s_bin" % name,
      testonly = 1,
      **kwargs
  )

  native.sh_test(
      name = name,
      args = args,
      visibility = visibility,
      srcs = [":%s_bin.sh" % name],
      data = [":%s_bin" % name],
  )
<commit_msg>fix for templated args that are not paths<commit_after># Copyright 2017 The Bazel Authors. 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.

"""Rules for executing programs in the nodejs runtime.
"""
load(":common/module_mappings.bzl", "module_mappings_runtime_aspect")

def _sources_aspect_impl(target, ctx):
  result = depset()
  if hasattr(ctx.rule.attr, "deps"):
    for dep in ctx.rule.attr.deps:
      if hasattr(dep, "node_sources"):
        result += dep.node_sources
  # Note layering: until we have JS interop providers, this needs to know how to
  # get TypeScript outputs.
  if hasattr(target, "typescript"):
    result += target.typescript.es5_sources
  elif hasattr(target, "files"):
    result += target.files
  return struct(node_sources = result)

sources_aspect = aspect(
    _sources_aspect_impl,
    attr_aspects = ["deps"],
)

def _write_loader_script(ctx):
  # Generates the JavaScript snippet of module roots mappings, with each entry
  # in the form:
  #   {module_name: /^mod_name\b/, module_root: 'path/to/mod_name'}
  module_mappings = []
  for d in ctx.attr.data:
    if hasattr(d, "runfiles_module_mappings"):
      for [mn, mr] in d.runfiles_module_mappings.items():
        escaped = mn.replace("/", r"\/").replace(".", r"\.")
        mapping = r"{module_name: /^%s\b/, module_root: '%s'}" % (escaped, mr)
        module_mappings.append(mapping)
  ctx.template_action(
      template=ctx.file._loader_template,
      output=ctx.outputs.loader,
      substitutions={
          "TEMPLATED_module_roots": "\n  " + ",\n  ".join(module_mappings),
          "TEMPLATED_entry_point": ctx.attr.entry_point,
          "TEMPLATED_label_package": ctx.attr.node_modules.label.package,
          "TEMPLATED_workspace_name": (
              ctx.label.workspace_root.split("/")[1]
              if ctx.label.workspace_root
              else ctx.workspace_name),
      },
      executable=True,
  )

def expand_location_into_runfiles(ctx, input):
  """Given a string that might contain $(location) label expansions,
   provide the path to the file in runfiles.
   See https://docs.bazel.build/versions/master/skylark/lib/ctx.html#expand_location
  """
  targets = ctx.attr.data if hasattr(ctx.attr, "data") else []
  expanded = ctx.expand_location(input, targets)
  if input == expanded:
    return input

  if expanded.startswith(ctx.bin_dir.path):
    expanded = expanded[len(ctx.bin_dir.path + "/"):]
  if expanded.startswith(ctx.genfiles_dir.path):
    expanded = expanded[len(ctx.genfiles_dir.path + "/"):]
  return ctx.workspace_name + "/" + expanded

def _nodejs_binary_impl(ctx):
    node = ctx.file._node
    node_modules = ctx.files.node_modules
    sources = depset()
    for d in ctx.attr.data:
      if hasattr(d, "node_sources"):
        sources += d.node_sources

    _write_loader_script(ctx)

    # Avoid writing non-normalized paths (workspace/../other_workspace/path)
    if ctx.outputs.loader.short_path.startswith("../"):
      script_path = ctx.outputs.loader.short_path[len("../"):]
    else:
      script_path = "/".join([
          ctx.workspace_name,
          ctx.outputs.loader.short_path,
      ])
    substitutions = {
        "TEMPLATED_node": ctx.workspace_name + "/" + node.path,
        "TEMPLATED_args": " ".join([
            expand_location_into_runfiles(ctx, a)
            for a in ctx.attr.templated_args]),
        "TEMPLATED_script_path": script_path,
    }
    # Write the output twice.
    # In order to have the name "nodejs_test", the rule must be declared
    # with test = True, which means we must write an output called "executable".
    # However, in order to wrap with a sh_test for Windows, we must be able to
    # get a single output file with a ".sh" extension.
    ctx.template_action(
        template=ctx.file._launcher_template,
        output=ctx.outputs.executable,
        substitutions=substitutions,
        executable=True,
    )
    ctx.template_action(
        template=ctx.file._launcher_template,
        output=ctx.outputs.script,
        substitutions=substitutions,
        executable=True,
    )

    runfiles = depset(sources)
    runfiles += [node]
    runfiles += [ctx.outputs.loader]
    runfiles += node_modules

    return struct(
        runfiles = ctx.runfiles(
            transitive_files = runfiles,
            files = [node, ctx.outputs.loader] + node_modules + sources.to_list(),
            collect_data = True,
        ),
    )

_NODEJS_EXECUTABLE_ATTRS = {
    "entry_point": attr.string(mandatory = True),
    "data": attr.label_list(
        allow_files = True,
        cfg = "data",
        aspects=[sources_aspect, module_mappings_runtime_aspect]),
    "templated_args": attr.string_list(),
    "_node": attr.label(
        default = Label("@nodejs//:node"),
        allow_files = True,
        single_file = True),
    "node_modules": attr.label(
        default = Label("@//:node_modules")),
    "_launcher_template": attr.label(
        default = Label("//internal:node_launcher.sh"),
        allow_files = True,
        single_file = True),
    "_loader_template": attr.label(
        default = Label("//internal:node_loader.js"),
        allow_files = True,
        single_file = True),
}

_NODEJS_EXECUTABLE_OUTPUTS = {
    "loader": "%{name}_loader.js",
    "script": "%{name}.sh",
}

# The name of the declared rule appears in
# bazel query --output=label_kind
# So we make these match what the user types in their BUILD file
# and duplicate the definitions to give two distinct symbols.
nodejs_binary = rule(
    implementation = _nodejs_binary_impl,
    attrs = _NODEJS_EXECUTABLE_ATTRS,
    executable = True,
    outputs = _NODEJS_EXECUTABLE_OUTPUTS,
)
nodejs_test = rule(
    implementation = _nodejs_binary_impl,
    attrs = _NODEJS_EXECUTABLE_ATTRS,
    test = True,
    outputs = _NODEJS_EXECUTABLE_OUTPUTS,
)

# Wrap in an sh_binary for windows .exe wrapper.
def nodejs_binary_macro(name, args=[], visibility=None, **kwargs):
  nodejs_binary(
      name = "%s_bin" % name,
      **kwargs
  )

  native.sh_binary(
      name = name,
      args = args,
      srcs = [":%s_bin.sh" % name],
      data = [":%s_bin" % name],
      visibility = visibility,
  )

# Wrap in an sh_test for windows .exe wrapper.
def nodejs_test_macro(name, args=[], visibility=None, **kwargs):
  nodejs_test(
      name = "%s_bin" % name,
      testonly = 1,
      **kwargs
  )

  native.sh_test(
      name = name,
      args = args,
      visibility = visibility,
      srcs = [":%s_bin.sh" % name],
      data = [":%s_bin" % name],
  )
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
===============================================================================
Atom class for crystal structure basis (:mod:`sknano.core.atoms._basis_atom`)
===============================================================================

An `Atom` sub-class for a crystal structure basis atom.

.. currentmodule:: sknano.core.atoms._basis_atom

"""
from __future__ import absolute_import, division, print_function
from __future__ import unicode_literals
__docformat__ = 'restructuredtext en'

from functools import total_ordering
import copy
import numbers
import numpy as np

from sknano.core.math import Vector
from ._xyz_atom import XYZAtom

__all__ = ['BasisAtom']

@total_ordering
class BasisAtom(XYZAtom):
    """An abstract object representation of a crystal structure basis atom.

    Parameters
    ----------
    lattice : :class:`~sknano.core.crystallography.Crystal3DLattice`
    xs, ys, zs : float
    """

    def __init__(self, *args, lattice=None, xs=None, ys=None, zs=None,
                 **kwargs):

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

        # if None in (xs, ys, zs) and lattice is not None:
        #     xs, ys, zs = lattice.cartesian_to_fractional

        self.lattice = lattice
        try:
            self.rs = Vector([xs, ys, zs])
            # print(self.rs)
            # print(self.r)
        except AttributeError:
            pass
        self.fmtstr = super().fmtstr + \
            ", lattice={lattice!r}, xs={xs:.6f}, ys={ys:.6f}, zs={zs:.6f}"

    def __eq__(self, other):
        return self.rs == other.rs and super().__eq__(other)

    def __lt__(self, other):
        """Test if `self` is *less than* `other`."""
        return (self.rs < other.rs and super().__le__(other)) or \
            (self.rs <= other.rs and super().__lt__(other))

    def __dir__(self):
        attrs = super().__dir__()
        attrs.extend(['lattice', 'xs', 'ys', 'zs'])
        return attrs

    @property
    def xs(self):
        """:math:`x`-coordinate in units of **Angstroms**.

        Returns
        -------
        float
            :math:`x`-coordinate in units of **Angstroms**.

        """
        return self.rs.x

    @xs.setter
    def xs(self, value):
        """Set `Atom` :math:`x`-coordinate in units of **Angstroms**.

        Parameters
        ----------
        value : float
            :math:`x`-coordinate in units of **Angstroms**.

        """
        if not isinstance(value, numbers.Number):
            raise TypeError('Expected a number')
        rs = self.rs
        rs.x = value
        self._update_cartesian_coordinate(rs)

    @property
    def ys(self):
        """:math:`y`-coordinate in units of **Angstroms**.

        Returns
        -------
        float
            :math:`y`-coordinate in units of **Angstroms**.

        """
        return self.rs.y

    @ys.setter
    def ys(self, value):
        """Set `Atom` :math:`y`-coordinate in units of **Angstroms**.

        Parameters
        ----------
        value : float
            :math:`y`-coordinate in units of **Angstroms**.

        """
        if not isinstance(value, numbers.Number):
            raise TypeError('Expected a number')
        rs = self.rs
        rs.y = value
        self._update_cartesian_coordinate(rs)

    @property
    def zs(self):
        """:math:`z`-coordinate in units of **Angstroms**.

        Returns
        -------
        float
            :math:`z`-coordinate in units of **Angstroms**.

        """
        return self.rs.z

    @zs.setter
    def zs(self, value):
        """Set `Atom` :math:`z`-coordinate in units of **Angstroms**.

        Parameters
        ----------
        value : float
            :math:`z`-coordinate in units of **Angstroms**.

        """
        if not isinstance(value, numbers.Number):
            raise TypeError('Expected a number')
        rs = self.rs
        rs.z = value
        self._update_cartesian_coordinate(rs)

    @property
    def rs(self):
        """:math:`x, y, z` components of `Atom` position vector.

        Returns
        -------
        ndarray
            3-element ndarray of [:math:`x, y, z`] coordinates of `Atom`.

        """
        try:
            return Vector(self.lattice.cartesian_to_fractional(self.r))
        except AttributeError:
            return Vector()

    @rs.setter
    def rs(self, value):
        """Set :math:`x, y, z` components of `Atom` position vector.

        Parameters
        ----------
        value : array_like
            :math:`x, y, z` coordinates of `Atom` position vector relative to
            the origin.

        """
        if not isinstance(value, (list, np.ndarray)):
            raise TypeError('Expected an array_like object')
        rs = Vector(value, nd=3)
        self._update_cartesian_coordinate(rs)

    def _update_cartesian_coordinate(self, rs):
        self.r = Vector(self.lattice.fractional_to_cartesian(rs))

    @property
    def lattice(self):
        """:class:`~sknano.core.crystallography.Crystal3DLattice`."""
        return self._lattice

    @lattice.setter
    def lattice(self, value):
        self._lattice = copy.copy(value)

    def rotate(self, **kwargs):
        """Rotate `Atom` position vector.

        Parameters
        ----------
        angle : float
        axis : :class:`~sknano.core.math.Vector`, optional
        anchor_point : :class:`~sknano.core.math.Point`, optional
        rot_point : :class:`~sknano.core.math.Point`, optional
        from_vector, to_vector : :class:`~sknano.core.math.Vector`, optional
        degrees : bool, optional
        transform_matrix : :class:`~numpy:numpy.ndarray`

        """
        self.lattice.rotate(**kwargs)
        super().rotate(**kwargs)

    def translate(self, t, fix_anchor_point=True):
        """Translate `Atom` position vector by :class:`Vector` `t`.

        Parameters
        ----------
        t : :class:`Vector`
        fix_anchor_point : bool, optional

        """
        # TODO compare timing benchmarks for translation of position vector.
        self.lattice.translate(t, fix_anchor_point=fix_anchor_point)
        super().translate(t, fix_anchor_point=fix_anchor_point)

    def todict(self):
        super_dict = super().todict()
        super_dict.update(dict(lattice=self.lattice, xs=self.xs, ys=self.ys,
                               zs=self.zs))
        return super_dict
<commit_msg>tidying up code<commit_after># -*- coding: utf-8 -*-
"""
===============================================================================
Atom class for crystal structure basis (:mod:`sknano.core.atoms._basis_atom`)
===============================================================================

An `Atom` sub-class for a crystal structure basis atom.

.. currentmodule:: sknano.core.atoms._basis_atom

"""
from __future__ import absolute_import, division, print_function
from __future__ import unicode_literals
__docformat__ = 'restructuredtext en'

from functools import total_ordering
import copy
import numbers
import numpy as np

from sknano.core.math import Vector
from ._xyz_atom import XYZAtom

__all__ = ['BasisAtom']

@total_ordering
class BasisAtom(XYZAtom):
    """An abstract object representation of a crystal structure basis atom.

    Parameters
    ----------
    lattice : :class:`~sknano.core.crystallography.Crystal3DLattice`
    xs, ys, zs : float
    """

    def __init__(self, *args, lattice=None, xs=None, ys=None, zs=None,
                 **kwargs):

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

        self.lattice = lattice
        try:
            self.rs = Vector([xs, ys, zs])
        except AttributeError:
            pass

        self.fmtstr = super().fmtstr + \
            ", lattice={lattice!r}, xs={xs:.6f}, ys={ys:.6f}, zs={zs:.6f}"

    def __eq__(self, other):
        return self.rs == other.rs and super().__eq__(other)

    def __lt__(self, other):
        """Test if `self` is *less than* `other`."""
        return (self.rs < other.rs and super().__le__(other)) or \
            (self.rs <= other.rs and super().__lt__(other))

    def __dir__(self):
        attrs = super().__dir__()
        attrs.extend(['lattice', 'xs', 'ys', 'zs'])
        return attrs

    @property
    def xs(self):
        """:math:`x`-coordinate in units of **Angstroms**.

        Returns
        -------
        float
            :math:`x`-coordinate in units of **Angstroms**.

        """
        return self.rs.x

    @xs.setter
    def xs(self, value):
        """Set `Atom` :math:`x`-coordinate in units of **Angstroms**.

        Parameters
        ----------
        value : float
            :math:`x`-coordinate in units of **Angstroms**.

        """
        if not isinstance(value, numbers.Number):
            raise TypeError('Expected a number')
        rs = self.rs
        rs.x = value
        self._update_cartesian_coordinate(rs)

    @property
    def ys(self):
        """:math:`y`-coordinate in units of **Angstroms**.

        Returns
        -------
        float
            :math:`y`-coordinate in units of **Angstroms**.

        """
        return self.rs.y

    @ys.setter
    def ys(self, value):
        """Set `Atom` :math:`y`-coordinate in units of **Angstroms**.

        Parameters
        ----------
        value : float
            :math:`y`-coordinate in units of **Angstroms**.

        """
        if not isinstance(value, numbers.Number):
            raise TypeError('Expected a number')
        rs = self.rs
        rs.y = value
        self._update_cartesian_coordinate(rs)

    @property
    def zs(self):
        """:math:`z`-coordinate in units of **Angstroms**.

        Returns
        -------
        float
            :math:`z`-coordinate in units of **Angstroms**.

        """
        return self.rs.z

    @zs.setter
    def zs(self, value):
        """Set `Atom` :math:`z`-coordinate in units of **Angstroms**.

        Parameters
        ----------
        value : float
            :math:`z`-coordinate in units of **Angstroms**.

        """
        if not isinstance(value, numbers.Number):
            raise TypeError('Expected a number')
        rs = self.rs
        rs.z = value
        self._update_cartesian_coordinate(rs)

    @property
    def rs(self):
        """:math:`x, y, z` components of `Atom` position vector.

        Returns
        -------
        ndarray
            3-element ndarray of [:math:`x, y, z`] coordinates of `Atom`.

        """
        try:
            return Vector(self.lattice.cartesian_to_fractional(self.r))
        except AttributeError:
            return Vector()

    @rs.setter
    def rs(self, value):
        """Set :math:`x, y, z` components of `Atom` position vector.

        Parameters
        ----------
        value : array_like
            :math:`x, y, z` coordinates of `Atom` position vector relative to
            the origin.

        """
        if not isinstance(value, (list, np.ndarray)):
            raise TypeError('Expected an array_like object')
        rs = Vector(value, nd=3)
        self._update_cartesian_coordinate(rs)

    def _update_cartesian_coordinate(self, rs):
        self.r = Vector(self.lattice.fractional_to_cartesian(rs))

    @property
    def lattice(self):
        """:class:`~sknano.core.crystallography.Crystal3DLattice`."""
        return self._lattice

    @lattice.setter
    def lattice(self, value):
        self._lattice = copy.copy(value)

    def rotate(self, **kwargs):
        """Rotate `Atom` position vector.

        Parameters
        ----------
        angle : float
        axis : :class:`~sknano.core.math.Vector`, optional
        anchor_point : :class:`~sknano.core.math.Point`, optional
        rot_point : :class:`~sknano.core.math.Point`, optional
        from_vector, to_vector : :class:`~sknano.core.math.Vector`, optional
        degrees : bool, optional
        transform_matrix : :class:`~numpy:numpy.ndarray`

        """
        self.lattice.rotate(**kwargs)
        super().rotate(**kwargs)

    def translate(self, t, fix_anchor_point=True):
        """Translate `Atom` position vector by :class:`Vector` `t`.

        Parameters
        ----------
        t : :class:`Vector`
        fix_anchor_point : bool, optional

        """
        # TODO compare timing benchmarks for translation of position vector.
        self.lattice.translate(t, fix_anchor_point=fix_anchor_point)
        super().translate(t, fix_anchor_point=fix_anchor_point)

    def todict(self):
        super_dict = super().todict()
        super_dict.update(dict(lattice=self.lattice, xs=self.xs, ys=self.ys,
                               zs=self.zs))
        return super_dict
<|endoftext|>


<commit_before># Copyright 2014 Open Source Robotics Foundation, Inc.
#
# 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.

from __future__ import print_function

try:
    raw_input
except NameError:
    raw_input = input

import os
import shutil
import sys

from catkin_pkg.packages import find_packages

from catkin_tools.argument_parsing import add_context_args

from catkin_tools.context import Context

from catkin_tools.common import log
from catkin_tools.common import wide_log

import catkin_tools.execution.job_server as job_server

from catkin_tools.metadata import get_paths as get_metadata_paths
from catkin_tools.metadata import get_profile_names
from catkin_tools.metadata import update_metadata
from catkin_tools.metadata import METADATA_DIR_NAME

from catkin_tools.terminal_color import ColorMapper

from .clean import clean_packages

color_mapper = ColorMapper()
clr = color_mapper.clr

# Exempt build directories
# See https://github.com/catkin/catkin_tools/issues/82
exempt_build_files = ['.catkin_tools.yaml', 'catkin_tools_prebuild']

setup_files = ['.catkin', 'env.sh', 'setup.bash', 'setup.sh', 'setup.zsh', '_setup_util.py']

def yes_no_loop(question):
    while True:
        resp = str(raw_input(question + " [yN]: "))
        if resp.lower() in ['n', 'no'] or len(resp) == 0:
            return False
        elif resp.lower() in ['y', 'yes']:
            return True
        log(clr("[clean] Please answer either \"yes\" or \"no\"."))

def safe_rmtree(path, workspace_root, force):
    """Safely remove a path outside of the workspace root."""

    # Check if the path is inside the workspace
    path_in_workspace = path.find(workspace_root) == 0

    yes = True
    if not path_in_workspace and not force:
        log(clr("[clean] Warning: `{}` is outside of the workspace root. (Use"
                " --force to skip this check)".format(path)))
        yes = yes_no_loop("Are you sure you want to entirely remove `{}`?".format(path))

    if yes:
        shutil.rmtree(path)
    else:
        log("[clean] Not removing `{}`".format(path))

def prepare_arguments(parser):
    # Workspace / profile args
    add_context_args(parser)

    add = parser.add_argument
    add('--dry-run', '-n', action='store_true', default=False,
        help='Show the effects of the clean action without modifying the workspace.')
    add('--verbose', '-v', action='store_true', default=False,
        help='Verbose status output.')
    add('--yes', '-y', action='store_true', default=False,
        help='Assume "yes" to all interactive checks.')
    add('--force', '-f', action='store_true', default=False,
        help='Allow cleaning files outside of the workspace root.')
    add('--all-profiles', action='store_true', default=False,
        help='Apply the specified clean operation for all profiles in this workspace.')

    full_group = parser.add_argument_group(
        'Full',
        'Remove everything except the source space.')
    add = full_group.add_argument
    add('--deinit', action='store_true', default=False,
        help='De-initialize the workspace, delete all build profiles and'
        ' configuration. This will also clean subdirectories for all profiles in'
        ' the workspace.')

    # Basic group
    basic_group = parser.add_argument_group(
        'Spaces',
        'Clean workspace subdirectories for the selected profile.')
    add = basic_group.add_argument
    add('-l', '--logs', action='store_true', default=False,
        help='Remove the entire log space.')
    add('-b', '--build', action='store_true', default=False,
        help='Remove the entire build space.')
    add('-d', '--devel', action='store_true', default=False,
        help='Remove the entire devel space.')
    add('-i', '--install', action='store_true', default=False,
        help='Remove the entire install space.')

    # Packages group
    packages_group = parser.add_argument_group(
        'Packages',
        "Clean products from specific packages in the workspace. Note that"
        " these options are only available in a `linked` devel space layout."
        " These options will also automatically enable the --force-cmake"
        " option for the next build invocation.")
    add = packages_group.add_argument
    add('packages', metavar='PKGNAME', nargs='*',
        help='Explicilty specify a list of specific packages to clean from the build, devel, and install space.')
    add('--dependents', '--deps', action='store_true', default=False,
        help='Clean the packages which depend on the packages to be cleaned.')
    add('--orphans', action='store_true', default=False,
        help='Remove products from packages are no longer in the source space. '
        'Note that this also removes packages which are '
        'blacklisted or which contain `CATKIN_INGORE` marker files.')

    # Advanced group
    advanced_group = parser.add_argument_group(
        'Advanced',
        "Clean other specific parts of the workspace.")
    add = advanced_group.add_argument
    add('--setup-files', action='store_true', default=False,
        help='Clear the catkin-generated setup files from the devel and install spaces.')

    return parser

def clean_profile(opts, profile):
    # Load the context
    ctx = Context.load(opts.workspace, profile, opts, strict=True, load_env=False)

    if not ctx:
        if not opts.workspace:
            log(
                "[clean] Error: The current or desired workspace could not be "
                "determined. Please run `catkin clean` from within a catkin "
                "workspace or specify the workspace explicitly with the "
                "`--workspace` option.")
        else:
            log(
                "[clean] Error: Could not clean workspace \"%s\" because it "
                "either does not exist or it has no catkin_tools metadata." %
                opts.workspace)
        return False

    profile = ctx.profile

    # Check if the user wants to do something explicit
    actions = [
        'build', 'devel', 'install', 'logs',
        'packages', 'orphans',
        'deinit',  'setup_files']

    logs_exists = os.path.exists(ctx.log_space_abs)
    build_exists = os.path.exists(ctx.build_space_abs)
    devel_exists = os.path.exists(ctx.devel_space_abs)

    install_path = (
        os.path.join(ctx.destdir, ctx.install_space_abs.lstrip(os.sep))
        if ctx.destdir
        else ctx.install_space_abs)
    install_exists = os.path.exists(install_path)

    # Default is to clean all products for this profile
    no_specific_action = not any([
        v for (k, v) in vars(opts).items()
        if k in actions])
    clean_all = opts.deinit or no_specific_action

    # Initialize action options
    if clean_all:
        opts.logs = opts.build = opts.devel = opts.install = True

    # Make sure the user intends to clena everything
    spaces_to_clean_msgs = []

    if not (opts.yes or opts.dry_run):
        if opts.logs and logs_exists:
            spaces_to_clean_msgs.append(clr("[clean] Log Space:     @{yf}{}").format(ctx.log_space_abs))
        if opts.build and build_exists:
            spaces_to_clean_msgs.append(clr("[clean] Build Space:   @{yf}{}").format(ctx.build_space_abs))
        if opts.devel and devel_exists:
            spaces_to_clean_msgs.append(clr("[clean] Devel Space:   @{yf}{}").format(ctx.devel_space_abs))
        if opts.install and install_exists:
            spaces_to_clean_msgs.append(clr("[clean] Install Space: @{yf}{}").format(install_path))

        if len(spaces_to_clean_msgs) == 0 and not opts.deinit:
            log("[clean] Nothing to be cleaned for profile:  `{}`".format(profile))
            return True

    if len(spaces_to_clean_msgs) > 0:
        log("")
        log(clr("[clean] @!@{yf}Warning:@| This will completely remove the "
                "following directories. (Use `--yes` to skip this check)"))
        for msg in spaces_to_clean_msgs:
            log(msg)
        try:
            yes = yes_no_loop(
                "\n[clean] Are you sure you want to completely remove the directories listed above?")
            if not yes:
                log(clr("[clean] Not removing any workspace directories for"
                        " this profile."))
                return True
        except KeyboardInterrupt:
            log("\n[clean] No actions performed.")
            sys.exit(0)

    # Initialize flag to be used on the next invocation
    needs_force = False

    try:
        # Remove all installspace files
        if opts.install and install_exists:
            log("[clean] Removing installspace: %s" % install_path)
            if not opts.dry_run:
                safe_rmtree(install_path, ctx.workspace, opts.force)

        # Remove all develspace files
        if opts.devel:
            if devel_exists:
                log("[clean] Removing develspace: %s" % ctx.devel_space_abs)
                if not opts.dry_run:
                    safe_rmtree(ctx.devel_space_abs, ctx.workspace, opts.force)
            # Clear the cached metadata from the last build run
            _, build_metadata_file = get_metadata_paths(ctx.workspace, profile, 'build')
            if os.path.exists(build_metadata_file):
                os.unlink(build_metadata_file)
            # Clear the cached packages data, if it exists
            packages_metadata_path = ctx.package_metadata_path()
            if os.path.exists(packages_metadata_path):
                safe_rmtree(packages_metadata_path, ctx.workspace, opts.force)

        # Remove all buildspace files
        if opts.build and build_exists:
            log("[clean] Removing buildspace: %s" % ctx.build_space_abs)
            if not opts.dry_run:
                safe_rmtree(ctx.build_space_abs, ctx.workspace, opts.force)

        # Setup file removal
        if opts.setup_files:
            if devel_exists:
                log("[clean] Removing setup files from develspace: %s" % ctx.devel_space_abs)
                opts.packages.append('catkin')
                opts.packages.append('catkin_tools_prebuild')
            else:
                log("[clean] No develspace exists, no setup files to clean.")

        # Clean log files
        if opts.logs and logs_exists:
            log("[clean] Removing log space: {}".format(ctx.log_space_abs))
            if not opts.dry_run:
                safe_rmtree(ctx.log_space_abs, ctx.workspace, opts.force)

        # Find orphaned packages
        if ctx.link_devel and not any([opts.build, opts.devel]):
            if opts.orphans:
                if os.path.exists(ctx.build_space_abs):
                    log("[clean] Determining orphaned packages...")

                    # Get all existing packages in source space and the
                    # Suppress warnings since this is looking for packages which no longer exist
                    found_source_packages = [
                        pkg.name for (path, pkg) in
                        find_packages(ctx.source_space_abs, warnings=[]).items()]
                    built_packages = [
                        pkg.name for (path, pkg) in
                        find_packages(ctx.package_metadata_path(), warnings=[]).items()]

                    # Look for orphaned products in the build space
                    orphans = [p for p in built_packages
                               if (p not in found_source_packages and p !=
                                   'catkin_tools_prebuild')]

                    if len(orphans) > 0:
                        opts.packages.extend(list(orphans))
                    else:
                        log("[clean] No orphans in the workspace.")
                else:
                    log("[clean] No buildspace exists, no potential for orphans.")

            # Remove specific packages
            if len(opts.packages) > 0:

                try:
                    # Clean the packages
                    needs_force = clean_packages(
                        ctx,
                        opts.packages,
                        opts.dependents,
                        opts.verbose,
                        opts.dry_run)
                except KeyboardInterrupt:
                    wide_log("[build] User interrupted!")
                    return False

        elif opts.orphans or len(opts.packages) > 0:
            log("[clean] Error: Individual packages can only be cleaned from "
                "workspaces with symbolically-linked develspaces (`catkin "
                "config --link-devel`).")

    except:
        log("[clean] Failed to clean profile `{}`".format(profile))
        needs_force = True
        raise

    finally:
        if needs_force:
            log(clr(
                "[clean] @/@!Note:@| @/Parts of the workspace have been cleaned which will "
                "necessitate re-configuring CMake on the next build.@|"))
            update_metadata(ctx.workspace, ctx.profile, 'build', {'needs_force': True})

    return True

def main(opts):
    # Check for exclusivity
    full_options = opts.deinit
    space_options = opts.logs or opts.build or opts.devel or opts.install
    package_options = len(opts.packages) > 0 or opts.orphans
    advanced_options = opts.setup_files

    if full_options:
        if space_options or package_options or advanced_options:
            log("[clean] Error: Using `--deinit` will remove all spaces, so"
                " additional partial cleaning options will be ignored.")
    elif space_options:
        if package_options:
            log("[clean] Error: Package arguments are not allowed with space"
                " arguments (--build, --devel, --install, --logs). See usage.")
        elif advanced_options:
            log("[clean] Error: Advanced arguments are not allowed with space"
                " arguments (--build, --devel, --install, --logs). See usage.")

    # Check for all profiles option
    if opts.all_profiles:
        profiles = get_profile_names(opts.workspace or os.getcwd())
    else:
        profiles = [opts.profile]

    # Initialize job server
    job_server.initialize(
        max_jobs=1,
        max_load=None,
        gnu_make_enabled=False)

    # Clean the requested profiles
    retcode = 0
    for profile in profiles:
        if not clean_profile(opts, profile):
            retcode = 1

    # Warn before nuking .catkin_tools
    if retcode == 0:
        if opts.deinit and not opts.yes:
            log("")
            log(clr("[clean] @!@{yf}Warning:@| If you deinitialize this workspace"
                    " you will lose all profiles and all saved build"
                    " configuration. (Use `--yes` to skip this check)"))
            try:
                opts.deinit = yes_no_loop("\n[clean] Are you sure you want to deinitialize this workspace?")
                if not opts.deinit:
                    log(clr("[clean] Not deinitializing workspace."))
            except KeyboardInterrupt:
                log("\n[clean] No actions performed.")
                sys.exit(0)

        # Nuke .catkin_tools
        if opts.deinit:
            ctx = Context.load(opts.workspace, profile, opts, strict=True, load_env=False)
            metadata_dir = os.path.join(ctx.workspace, METADATA_DIR_NAME)
            log("[clean] Deinitializing workspace by removing catkin_tools config: %s" % metadata_dir)
            if not opts.dry_run:
                safe_rmtree(metadata_dir, ctx.workspace, opts.force)

    return retcode
<commit_msg>clean: Fixing non-space cleaning warning<commit_after># Copyright 2014 Open Source Robotics Foundation, Inc.
#
# 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.

from __future__ import print_function

try:
    raw_input
except NameError:
    raw_input = input

import os
import shutil
import sys

from catkin_pkg.packages import find_packages

from catkin_tools.argument_parsing import add_context_args

from catkin_tools.context import Context

from catkin_tools.common import log
from catkin_tools.common import wide_log

import catkin_tools.execution.job_server as job_server

from catkin_tools.metadata import get_paths as get_metadata_paths
from catkin_tools.metadata import get_profile_names
from catkin_tools.metadata import update_metadata
from catkin_tools.metadata import METADATA_DIR_NAME

from catkin_tools.terminal_color import ColorMapper

from .clean import clean_packages

color_mapper = ColorMapper()
clr = color_mapper.clr

# Exempt build directories
# See https://github.com/catkin/catkin_tools/issues/82
exempt_build_files = ['.catkin_tools.yaml', 'catkin_tools_prebuild']

setup_files = ['.catkin', 'env.sh', 'setup.bash', 'setup.sh', 'setup.zsh', '_setup_util.py']

def yes_no_loop(question):
    while True:
        resp = str(raw_input(question + " [yN]: "))
        if resp.lower() in ['n', 'no'] or len(resp) == 0:
            return False
        elif resp.lower() in ['y', 'yes']:
            return True
        log(clr("[clean] Please answer either \"yes\" or \"no\"."))

def safe_rmtree(path, workspace_root, force):
    """Safely remove a path outside of the workspace root."""

    # Check if the path is inside the workspace
    path_in_workspace = path.find(workspace_root) == 0

    yes = True
    if not path_in_workspace and not force:
        log(clr("[clean] Warning: `{}` is outside of the workspace root. (Use"
                " --force to skip this check)".format(path)))
        yes = yes_no_loop("Are you sure you want to entirely remove `{}`?".format(path))

    if yes:
        shutil.rmtree(path)
    else:
        log("[clean] Not removing `{}`".format(path))

def prepare_arguments(parser):
    # Workspace / profile args
    add_context_args(parser)

    add = parser.add_argument
    add('--dry-run', '-n', action='store_true', default=False,
        help='Show the effects of the clean action without modifying the workspace.')
    add('--verbose', '-v', action='store_true', default=False,
        help='Verbose status output.')
    add('--yes', '-y', action='store_true', default=False,
        help='Assume "yes" to all interactive checks.')
    add('--force', '-f', action='store_true', default=False,
        help='Allow cleaning files outside of the workspace root.')
    add('--all-profiles', action='store_true', default=False,
        help='Apply the specified clean operation for all profiles in this workspace.')

    full_group = parser.add_argument_group(
        'Full',
        'Remove everything except the source space.')
    add = full_group.add_argument
    add('--deinit', action='store_true', default=False,
        help='De-initialize the workspace, delete all build profiles and'
        ' configuration. This will also clean subdirectories for all profiles in'
        ' the workspace.')

    # Basic group
    basic_group = parser.add_argument_group(
        'Spaces',
        'Clean workspace subdirectories for the selected profile.')
    add = basic_group.add_argument
    add('-l', '--logs', action='store_true', default=False,
        help='Remove the entire log space.')
    add('-b', '--build', action='store_true', default=False,
        help='Remove the entire build space.')
    add('-d', '--devel', action='store_true', default=False,
        help='Remove the entire devel space.')
    add('-i', '--install', action='store_true', default=False,
        help='Remove the entire install space.')

    # Packages group
    packages_group = parser.add_argument_group(
        'Packages',
        "Clean products from specific packages in the workspace. Note that"
        " these options are only available in a `linked` devel space layout."
        " These options will also automatically enable the --force-cmake"
        " option for the next build invocation.")
    add = packages_group.add_argument
    add('packages', metavar='PKGNAME', nargs='*',
        help='Explicilty specify a list of specific packages to clean from the build, devel, and install space.')
    add('--dependents', '--deps', action='store_true', default=False,
        help='Clean the packages which depend on the packages to be cleaned.')
    add('--orphans', action='store_true', default=False,
        help='Remove products from packages are no longer in the source space. '
        'Note that this also removes packages which are '
        'blacklisted or which contain `CATKIN_INGORE` marker files.')

    # Advanced group
    advanced_group = parser.add_argument_group(
        'Advanced',
        "Clean other specific parts of the workspace.")
    add = advanced_group.add_argument
    add('--setup-files', action='store_true', default=False,
        help='Clear the catkin-generated setup files from the devel and install spaces.')

    return parser

def clean_profile(opts, profile):
    # Load the context
    ctx = Context.load(opts.workspace, profile, opts, strict=True, load_env=False)

    if not ctx:
        if not opts.workspace:
            log(
                "[clean] Error: The current or desired workspace could not be "
                "determined. Please run `catkin clean` from within a catkin "
                "workspace or specify the workspace explicitly with the "
                "`--workspace` option.")
        else:
            log(
                "[clean] Error: Could not clean workspace \"%s\" because it "
                "either does not exist or it has no catkin_tools metadata." %
                opts.workspace)
        return False

    profile = ctx.profile

    # Check if the user wants to do something explicit
    actions = [
        'build', 'devel', 'install', 'logs',
        'packages', 'orphans',
        'deinit',  'setup_files']

    logs_exists = os.path.exists(ctx.log_space_abs)
    build_exists = os.path.exists(ctx.build_space_abs)
    devel_exists = os.path.exists(ctx.devel_space_abs)

    install_path = (
        os.path.join(ctx.destdir, ctx.install_space_abs.lstrip(os.sep))
        if ctx.destdir
        else ctx.install_space_abs)
    install_exists = os.path.exists(install_path)

    # Default is to clean all products for this profile
    no_specific_action = not any([
        v for (k, v) in vars(opts).items()
        if k in actions])
    clean_all = opts.deinit or no_specific_action

    # Initialize action options
    if clean_all:
        opts.logs = opts.build = opts.devel = opts.install = True

    # Make sure the user intends to clena everything
    spaces_to_clean = (opts.logs or opts.build or opts.devel or opts.install)
    spaces_to_clean_msgs = []

    if spaces_to_clean and not (opts.yes or opts.dry_run):
        if opts.logs and logs_exists:
            spaces_to_clean_msgs.append(clr("[clean] Log Space:     @{yf}{}").format(ctx.log_space_abs))
        if opts.build and build_exists:
            spaces_to_clean_msgs.append(clr("[clean] Build Space:   @{yf}{}").format(ctx.build_space_abs))
        if opts.devel and devel_exists:
            spaces_to_clean_msgs.append(clr("[clean] Devel Space:   @{yf}{}").format(ctx.devel_space_abs))
        if opts.install and install_exists:
            spaces_to_clean_msgs.append(clr("[clean] Install Space: @{yf}{}").format(install_path))

        if len(spaces_to_clean_msgs) == 0 and not opts.deinit:
            log("[clean] Nothing to be cleaned for profile:  `{}`".format(profile))
            return True

    if len(spaces_to_clean_msgs) > 0:
        log("")
        log(clr("[clean] @!@{yf}Warning:@| This will completely remove the "
                "following directories. (Use `--yes` to skip this check)"))
        for msg in spaces_to_clean_msgs:
            log(msg)
        try:
            yes = yes_no_loop(
                "\n[clean] Are you sure you want to completely remove the directories listed above?")
            if not yes:
                log(clr("[clean] Not removing any workspace directories for"
                        " this profile."))
                return True
        except KeyboardInterrupt:
            log("\n[clean] No actions performed.")
            sys.exit(0)

    # Initialize flag to be used on the next invocation
    needs_force = False

    try:
        # Remove all installspace files
        if opts.install and install_exists:
            log("[clean] Removing installspace: %s" % install_path)
            if not opts.dry_run:
                safe_rmtree(install_path, ctx.workspace, opts.force)

        # Remove all develspace files
        if opts.devel:
            if devel_exists:
                log("[clean] Removing develspace: %s" % ctx.devel_space_abs)
                if not opts.dry_run:
                    safe_rmtree(ctx.devel_space_abs, ctx.workspace, opts.force)
            # Clear the cached metadata from the last build run
            _, build_metadata_file = get_metadata_paths(ctx.workspace, profile, 'build')
            if os.path.exists(build_metadata_file):
                os.unlink(build_metadata_file)
            # Clear the cached packages data, if it exists
            packages_metadata_path = ctx.package_metadata_path()
            if os.path.exists(packages_metadata_path):
                safe_rmtree(packages_metadata_path, ctx.workspace, opts.force)

        # Remove all buildspace files
        if opts.build and build_exists:
            log("[clean] Removing buildspace: %s" % ctx.build_space_abs)
            if not opts.dry_run:
                safe_rmtree(ctx.build_space_abs, ctx.workspace, opts.force)

        # Setup file removal
        if opts.setup_files:
            if devel_exists:
                log("[clean] Removing setup files from develspace: %s" % ctx.devel_space_abs)
                opts.packages.append('catkin')
                opts.packages.append('catkin_tools_prebuild')
            else:
                log("[clean] No develspace exists, no setup files to clean.")

        # Clean log files
        if opts.logs and logs_exists:
            log("[clean] Removing log space: {}".format(ctx.log_space_abs))
            if not opts.dry_run:
                safe_rmtree(ctx.log_space_abs, ctx.workspace, opts.force)

        # Find orphaned packages
        if ctx.link_devel and not any([opts.build, opts.devel]):
            if opts.orphans:
                if os.path.exists(ctx.build_space_abs):
                    log("[clean] Determining orphaned packages...")

                    # Get all existing packages in source space and the
                    # Suppress warnings since this is looking for packages which no longer exist
                    found_source_packages = [
                        pkg.name for (path, pkg) in
                        find_packages(ctx.source_space_abs, warnings=[]).items()]
                    built_packages = [
                        pkg.name for (path, pkg) in
                        find_packages(ctx.package_metadata_path(), warnings=[]).items()]

                    # Look for orphaned products in the build space
                    orphans = [p for p in built_packages
                               if (p not in found_source_packages and p !=
                                   'catkin_tools_prebuild')]

                    if len(orphans) > 0:
                        opts.packages.extend(list(orphans))
                    else:
                        log("[clean] No orphans in the workspace.")
                else:
                    log("[clean] No buildspace exists, no potential for orphans.")

            # Remove specific packages
            if len(opts.packages) > 0:

                try:
                    # Clean the packages
                    needs_force = clean_packages(
                        ctx,
                        opts.packages,
                        opts.dependents,
                        opts.verbose,
                        opts.dry_run)
                except KeyboardInterrupt:
                    wide_log("[build] User interrupted!")
                    return False

        elif opts.orphans or len(opts.packages) > 0:
            log("[clean] Error: Individual packages can only be cleaned from "
                "workspaces with symbolically-linked develspaces (`catkin "
                "config --link-devel`).")

    except:
        log("[clean] Failed to clean profile `{}`".format(profile))
        needs_force = True
        raise

    finally:
        if needs_force:
            log(clr(
                "[clean] @/@!Note:@| @/Parts of the workspace have been cleaned which will "
                "necessitate re-configuring CMake on the next build.@|"))
            update_metadata(ctx.workspace, ctx.profile, 'build', {'needs_force': True})

    return True

def main(opts):
    # Check for exclusivity
    full_options = opts.deinit
    space_options = opts.logs or opts.build or opts.devel or opts.install
    package_options = len(opts.packages) > 0 or opts.orphans
    advanced_options = opts.setup_files

    if full_options:
        if space_options or package_options or advanced_options:
            log("[clean] Error: Using `--deinit` will remove all spaces, so"
                " additional partial cleaning options will be ignored.")
    elif space_options:
        if package_options:
            log("[clean] Error: Package arguments are not allowed with space"
                " arguments (--build, --devel, --install, --logs). See usage.")
        elif advanced_options:
            log("[clean] Error: Advanced arguments are not allowed with space"
                " arguments (--build, --devel, --install, --logs). See usage.")

    # Check for all profiles option
    if opts.all_profiles:
        profiles = get_profile_names(opts.workspace or os.getcwd())
    else:
        profiles = [opts.profile]

    # Initialize job server
    job_server.initialize(
        max_jobs=1,
        max_load=None,
        gnu_make_enabled=False)

    # Clean the requested profiles
    retcode = 0
    for profile in profiles:
        if not clean_profile(opts, profile):
            retcode = 1

    # Warn before nuking .catkin_tools
    if retcode == 0:
        if opts.deinit and not opts.yes:
            log("")
            log(clr("[clean] @!@{yf}Warning:@| If you deinitialize this workspace"
                    " you will lose all profiles and all saved build"
                    " configuration. (Use `--yes` to skip this check)"))
            try:
                opts.deinit = yes_no_loop("\n[clean] Are you sure you want to deinitialize this workspace?")
                if not opts.deinit:
                    log(clr("[clean] Not deinitializing workspace."))
            except KeyboardInterrupt:
                log("\n[clean] No actions performed.")
                sys.exit(0)

        # Nuke .catkin_tools
        if opts.deinit:
            ctx = Context.load(opts.workspace, profile, opts, strict=True, load_env=False)
            metadata_dir = os.path.join(ctx.workspace, METADATA_DIR_NAME)
            log("[clean] Deinitializing workspace by removing catkin_tools config: %s" % metadata_dir)
            if not opts.dry_run:
                safe_rmtree(metadata_dir, ctx.workspace, opts.force)

    return retcode
<|endoftext|>


<commit_before>import unittest
import skrf
import numpy as np
import tempfile
import os

class VectorFittingTestCase(unittest.TestCase):

    def test_vectorfitting_ring_slot(self):
        # expected fitting parameters for skrf.data.ring_slot with 2 initial real poles
        expected_poles = np.array([-7.80605445e+10+5.32645184e+11j])
        expected_zeros = np.array([[7.01837934e+10+1.14737278e+10j],
                                   [7.93470695e+10-4.54467471e+09j],
                                   [7.93470695e+10-4.54467471e+09j],
                                   [8.19724835e+10-2.11876421e+10j]])
        expected_props = np.array([-2.06451610e-15,
                                   -2.45016478e-14,
                                   -2.45016478e-14,
                                   7.79744644e-13])
        expected_const = np.array([-0.9871906,
                                   -0.06043898,
                                   -0.06043898,
                                   -0.99401152])

        # perform the fit
        vf = skrf.vectorFitting.VectorFitting(skrf.data.ring_slot)
        vf.vector_fit(n_poles_real=2, n_poles_cmplx=0, fit_constant=True, fit_proportional=True)

        # relax relative and absolute tolerances, as results from Python 2.7 are slightly different from Python 3.x
        # basically, this disables the absolute tolerance criterion
        rtol = 0.01
        atol = rtol * np.amax(np.abs(expected_poles))

        # compare both sets of parameters
        self.assertTrue(np.allclose(vf.poles, expected_poles, rtol=rtol, atol=atol))
        self.assertTrue(np.allclose(vf.zeros, expected_zeros, rtol=rtol, atol=atol))
        self.assertTrue(np.allclose(vf.proportional_coeff, expected_props, rtol=rtol, atol=atol))
        self.assertTrue(np.allclose(vf.constant_coeff, expected_const, rtol=rtol, atol=atol))

    def test_model_response(self):
        # fit ring slot example network
        nw = skrf.data.ring_slot
        vf = skrf.vectorFitting.VectorFitting(nw)
        vf.vector_fit(n_poles_real=4, n_poles_cmplx=0, fit_constant=True, fit_proportional=True)

        # compare fitted model responses to original network responses (should match with less than 1% error)
        # s11
        nw_s11 = nw.s[:, 0, 0]
        fit_s11 = vf.get_model_response(0, 0, freqs=nw.f)
        delta_s11_maxabs = np.amax(np.abs((fit_s11 - nw_s11) / nw_s11))
        self.assertLess(delta_s11_maxabs, 0.05)

        # s12
        nw_s12 = nw.s[:, 0, 1]
        fit_s12 = vf.get_model_response(0, 1, freqs=nw.f)
        delta_s12_maxabs = np.amax(np.abs((fit_s12 - nw_s12) / nw_s12))
        self.assertLess(delta_s12_maxabs, 0.05)

        # s21
        nw_s21 = nw.s[:, 1, 0]
        fit_s21 = vf.get_model_response(1, 0, freqs=nw.f)
        delta_s21_maxabs = np.amax(np.abs((fit_s21 - nw_s21) / nw_s21))
        self.assertLess(delta_s21_maxabs, 0.05)

        # s22
        nw_s22 = nw.s[:, 1, 1]
        fit_s22 = vf.get_model_response(1, 1, freqs=nw.f)
        delta_s22_maxabs = np.amax(np.abs((fit_s22 - nw_s22) / nw_s22))
        print(delta_s22_maxabs)
        self.assertLess(delta_s22_maxabs, 0.05)

    def test_spice_subcircuit(self):
        # fit ring slot example network
        nw = skrf.data.ring_slot
        vf = skrf.vectorFitting.VectorFitting(nw)
        vf.vector_fit(n_poles_real=4, n_poles_cmplx=0, fit_constant=True, fit_proportional=True)

        # write equivalent SPICE subcircuit to tmp file
        tmp_file = tempfile.NamedTemporaryFile(suffix='.sp')
        vf.write_spice_subcircuit_s(tmp_file.name)

        # written tmp file should contain 69 lines
        n_lines = len(open(tmp_file.name, 'r').readlines())
        self.assertEqual(n_lines, 69)

    def test_read_write_npz(self):
        # fit ring slot example network
        nw = skrf.data.ring_slot
        vf = skrf.vectorFitting.VectorFitting(nw)
        vf.vector_fit(n_poles_real=2, n_poles_cmplx=0, fit_constant=True, fit_proportional=True)

        # export (write) fitted parameters to .npz file in tmp directory
        tmp_dir = tempfile.TemporaryDirectory()
        vf.write_npz(tmp_dir.name)

        # create a new vector fitting instance and import (read) those fitted parameters
        vf2 = skrf.vectorFitting.VectorFitting(nw)
        vf2.read_npz(os.path.join(tmp_dir.name, 'coefficients_{}.npz'.format(nw.name)))

        # compare both sets of parameters
        self.assertTrue(np.allclose(vf.poles, vf2.poles))
        self.assertTrue(np.allclose(vf.zeros, vf2.zeros))
        self.assertTrue(np.allclose(vf.proportional_coeff, vf2.proportional_coeff))
        self.assertTrue(np.allclose(vf.constant_coeff, vf2.constant_coeff))

    def test_matplotlib_missing(self):
        vf = skrf.vectorFitting.VectorFitting(skrf.data.ring_slot)
        skrf.vectorFitting.mplt = None
        with self.assertRaises(RuntimeError):
            vf.plot_convergence()

suite = unittest.TestLoader().loadTestsFromTestCase(VectorFittingTestCase)
unittest.TextTestRunner(verbosity=2).run(suite)
<commit_msg>Adapted and extended testcases.<commit_after>import unittest
import skrf
import numpy as np
import tempfile
import os

class VectorFittingTestCase(unittest.TestCase):

    def test_ringslot_with_proportional(self):
        # perform the fit
        vf = skrf.vectorFitting.VectorFitting(skrf.data.ring_slot)
        vf.vector_fit(n_poles_real=2, n_poles_cmplx=0, fit_proportional=True, fit_constant=True)

        # expected fitting parameters for skrf.data.ring_slot with 2 initial real poles
        expected_poles = np.array([-7.82570461e+10+5.32874416e+11j])
        expected_zeros = np.array([[7.04342166e+10+1.12221242e+10j],
                                   [7.95530409e+10-4.87232072e+09j],
                                   [7.95530409e+10-4.87232072e+09j],
                                   [8.21087613e+10-2.15675492e+10j]])
        expected_props = np.array([9.71465239e-16,
                                   -2.10871364e-14,
                                   -2.10871364e-14,
                                   7.83239517e-13])
        expected_const = np.array([-0.98831027,
                                   -0.06128905,
                                   -0.06128905,
                                   -0.99446547])

        # relax relative and absolute tolerances, as results from Python 2.7 are slightly different from Python 3.x
        # basically, this disables the absolute tolerance criterion
        rtol = 0.01
        atol = rtol * np.amax(np.abs(expected_poles))

        # compare both sets of parameters
        self.assertTrue(np.allclose(vf.poles, expected_poles, rtol=rtol, atol=atol))
        self.assertTrue(np.allclose(vf.zeros, expected_zeros, rtol=rtol, atol=atol))
        self.assertTrue(np.allclose(vf.proportional_coeff, expected_props, rtol=rtol, atol=atol))
        self.assertTrue(np.allclose(vf.constant_coeff, expected_const, rtol=rtol, atol=atol))

    def test_ringslot_default_log(self):
        # perform the fit without proportional term
        vf = skrf.vectorFitting.VectorFitting(skrf.data.ring_slot)
        vf.vector_fit(n_poles_real=4, n_poles_cmplx=0, init_pole_spacing='log')

        # expected parameters:
        expected_poles = np.array([-8.93571544e+11+1.84502286e+12j, -7.96637282e+10+5.33065163e+11j])
        expected_zeros = np.array([[4.71811349e+09+2.20844260e+10j, 7.22130093e+10+1.10150314e+10j],
                                   [-8.10130339e+10+2.69553730e+10j, 8.12743265e+10-5.28434213e+09j],
                                   [-8.10130339e+10+2.69553730e+10j, 8.12743265e+10-5.28434213e+09j],
                                   [1.50741990e+12+1.03733308e+12j, 8.72835493e+10-2.51863622e+10j]])
        expected_props = np.array([0.0, 0.0, 0.0, 0.0])
        expected_const = np.array([-0.97995369, -0.00434421, -0.00434421, -0.86793172])

        # relax relative and absolute tolerances, as results from Python 2.7 are slightly different from Python 3.x
        # basically, this disables the absolute tolerance criterion
        rtol = 0.01
        atol = rtol * np.amax(np.abs(expected_poles))

        # compare both sets of parameters
        self.assertTrue(np.allclose(vf.poles, expected_poles, rtol=rtol, atol=atol))
        self.assertTrue(np.allclose(vf.zeros, expected_zeros, rtol=rtol, atol=atol))
        self.assertTrue(np.allclose(vf.proportional_coeff, expected_props, rtol=rtol, atol=atol))
        self.assertTrue(np.allclose(vf.constant_coeff, expected_const, rtol=rtol, atol=atol))

    def test_ringslot_without_prop_const(self):
        # perform the fit without proportional term
        vf = skrf.vectorFitting.VectorFitting(skrf.data.ring_slot)
        vf.vector_fit(n_poles_real=4, n_poles_cmplx=0, fit_proportional=False, fit_constant=False)

        # expected parameters:
        expected_poles = np.array([-2.68320606e+13+0.0j, -2.39725722e+12+0.0j, -7.94998061e+10+5.33460725e+11j])
        expected_zeros = np.array([[-2.85512308e+13+0.0j, 1.72810467e+11+0.0j, 7.19396489e+10+1.06616739e+10j],
                                   [-2.51468427e+12+0.0j, 6.44668782e+10+0.0j, 8.10600423e+10-5.87840573e+09j],
                                   [-2.51468427e+12+0.0j, 6.44668782e+10+0.0j, 8.10600423e+10-5.87840573e+09j],
                                   [3.10896516e+13+0.0j, -5.51444142e+12+0.0j, 8.57614332e+10-2.64489550e+10j]])
        expected_props = np.array([0.0, 0.0, 0.0, 0.0])
        expected_const = np.array([0.0, 0.0, 0.0, 0.0])

        # relax relative and absolute tolerances, as results from Python 2.7 are slightly different from Python 3.x
        # basically, this disables the absolute tolerance criterion
        rtol = 0.01
        atol = rtol * np.amax(np.abs(expected_poles))

        # compare both sets of parameters
        self.assertTrue(np.allclose(vf.poles, expected_poles, rtol=rtol, atol=atol))
        self.assertTrue(np.allclose(vf.zeros, expected_zeros, rtol=rtol, atol=atol))
        self.assertTrue(np.allclose(vf.proportional_coeff, expected_props, rtol=rtol, atol=atol))
        self.assertTrue(np.allclose(vf.constant_coeff, expected_const, rtol=rtol, atol=atol))

    def test_190ghz_measured(self):
        # perform the fit without proportional term
        nw = skrf.network.Network('./doc/source/examples/vectorfitting/190ghz_tx_measured.S2P')
        vf = skrf.vectorFitting.VectorFitting(nw)
        vf.vector_fit(n_poles_real=4, n_poles_cmplx=4, fit_proportional=False, fit_constant=True)

        # expected parameters:
        expected_poles = np.array([-1.57475745e+14+0.0j,
                                   -1.18834516e+11+9.09437100e+11j,
                                   -9.31737428e+10+1.28087682e+12j,
                                   -8.62928730e+10+1.17731581e+12j,
                                   -8.40722337e+10+1.06025397e+12j,
                                   -6.78498212e+10+1.40989041e+12j,
                                   -2.14689157e+10+0.0j])
        expected_zeros = np.array([[-2.65287319e+15+0.0j,
                                    -1.93216730e+10-5.07224595e+10j,
                                    -2.21817763e+10-4.06200216e+10j,
                                    1.36015316e+10-1.17553256e+10j,
                                    5.56282943e+09+2.05636021e+10j,
                                    1.67186787e+10+8.76036057e+09j,
                                    -1.45040972e+11+0.0j],
                                   [7.58775308e+14+0.0j,
                                    -2.38135317e+09+7.47127977e+08j,
                                    -4.86143241e+09+1.80283555e+09j,
                                    -6.10784454e+08+1.03682367e+09j,
                                    -7.16135706e+08+6.77740453e+08j,
                                    -3.33102819e+09-7.59790686e+08j,
                                    -3.30724201e+10+0.0j],
                                   [-1.15809727e+15+0.0j,
                                    -1.22716214e+11-9.54130617e+09j,
                                    -9.21636351e+10+1.24415054e+11j,
                                    3.58950981e+11+2.00228548e+11j,
                                    4.99726589e+10-3.38515501e+11j,
                                    -5.72387494e+10+3.80171040e+10j,
                                    4.08499919e+10+0.0j],
                                   [-4.20227295e+15+0.0j,
                                    2.71669215e+10+1.16365804e+10j,
                                    -1.26160359e+10+3.15388544e+09j,
                                    -3.02169283e+10-3.65666828e+10j,
                                    4.32209635e+09-2.19063498e+10j,
                                    2.41311866e+10-3.75303886e+10j,
                                    -2.67088753e+11+0.0j]])
        expected_props = np.array([0.0, 0.0, 0.0, 0.0])
        expected_const = np.array([16.86700896, -4.77902696, 7.19034104, 26.87203581])

        # relax relative and absolute tolerances, as results from Python 2.7 are slightly different from Python 3.x
        # basically, this disables the absolute tolerance criterion
        rtol = 0.01
        atol = rtol * np.amax(np.abs(expected_poles))

        # compare both sets of parameters
        self.assertTrue(np.allclose(vf.poles, expected_poles, rtol=rtol, atol=atol))
        self.assertTrue(np.allclose(vf.zeros, expected_zeros, rtol=rtol, atol=atol))
        self.assertTrue(np.allclose(vf.proportional_coeff, expected_props, rtol=rtol, atol=atol))
        self.assertTrue(np.allclose(vf.constant_coeff, expected_const, rtol=rtol, atol=atol))

    def test_model_response(self):
        # fit ring slot example network
        nw = skrf.data.ring_slot
        vf = skrf.vectorFitting.VectorFitting(nw)
        vf.vector_fit(n_poles_real=4, n_poles_cmplx=0)

        # compare fitted model responses to original network responses (should match with less than 1% error)
        # s11
        nw_s11 = nw.s[:, 0, 0]
        fit_s11 = vf.get_model_response(0, 0, freqs=nw.f)
        delta_s11_maxabs = np.amax(np.abs((fit_s11 - nw_s11) / nw_s11))
        self.assertLess(delta_s11_maxabs, 0.01)

        # s12
        nw_s12 = nw.s[:, 0, 1]
        fit_s12 = vf.get_model_response(0, 1, freqs=nw.f)
        delta_s12_maxabs = np.amax(np.abs((fit_s12 - nw_s12) / nw_s12))
        self.assertLess(delta_s12_maxabs, 0.01)

        # s21
        nw_s21 = nw.s[:, 1, 0]
        fit_s21 = vf.get_model_response(1, 0, freqs=nw.f)
        delta_s21_maxabs = np.amax(np.abs((fit_s21 - nw_s21) / nw_s21))
        self.assertLess(delta_s21_maxabs, 0.01)

        # s22
        nw_s22 = nw.s[:, 1, 1]
        fit_s22 = vf.get_model_response(1, 1, freqs=nw.f)
        delta_s22_maxabs = np.amax(np.abs((fit_s22 - nw_s22) / nw_s22))
        print(delta_s22_maxabs)
        self.assertLess(delta_s22_maxabs, 0.01)

    def test_spice_subcircuit(self):
        # fit ring slot example network
        nw = skrf.data.ring_slot
        vf = skrf.vectorFitting.VectorFitting(nw)
        vf.vector_fit(n_poles_real=4, n_poles_cmplx=0, fit_constant=True, fit_proportional=True)

        # write equivalent SPICE subcircuit to tmp file
        tmp_file = tempfile.NamedTemporaryFile(suffix='.sp')
        vf.write_spice_subcircuit_s(tmp_file.name)

        # written tmp file should contain 69 lines
        n_lines = len(open(tmp_file.name, 'r').readlines())
        self.assertEqual(n_lines, 69)

    def test_read_write_npz(self):
        # fit ring slot example network
        nw = skrf.data.ring_slot
        vf = skrf.vectorFitting.VectorFitting(nw)
        vf.vector_fit(n_poles_real=3, n_poles_cmplx=0)

        # export (write) fitted parameters to .npz file in tmp directory
        tmp_dir = tempfile.TemporaryDirectory()
        vf.write_npz(tmp_dir.name)

        # create a new vector fitting instance and import (read) those fitted parameters
        vf2 = skrf.vectorFitting.VectorFitting(nw)
        vf2.read_npz(os.path.join(tmp_dir.name, 'coefficients_{}.npz'.format(nw.name)))

        # compare both sets of parameters
        self.assertTrue(np.allclose(vf.poles, vf2.poles))
        self.assertTrue(np.allclose(vf.zeros, vf2.zeros))
        self.assertTrue(np.allclose(vf.proportional_coeff, vf2.proportional_coeff))
        self.assertTrue(np.allclose(vf.constant_coeff, vf2.constant_coeff))

    def test_matplotlib_missing(self):
        vf = skrf.vectorFitting.VectorFitting(skrf.data.ring_slot)
        skrf.vectorFitting.mplt = None
        with self.assertRaises(RuntimeError):
            vf.plot_convergence()

suite = unittest.TestLoader().loadTestsFromTestCase(VectorFittingTestCase)
unittest.TextTestRunner(verbosity=2).run(suite)
<|endoftext|>


<commit_before>"""Tests for Jurisdiction class and other functionality related
   to jurisdictions."""

import cc.license
from cc.license import CCLicenseError
import nose.tools

# TODO: additional tests exercising the output
def test_jurisdictions():
    jurisdictions = cc.license.jurisdictions.list()
    for j in jurisdictions:
        assert type(j) == cc.license.Jurisdiction

def test_jurisdiction_codes():
    codes = cc.license.jurisdictions.list_codes()
    # scotland is in there, and it's the only one that isn't 2 letters
    assert 'scotland' in codes
    codes.remove('scotland')
    # excepting the empty string (default jurisdiction) of course
    assert '' in codes
    codes.remove('')
    # they are all strings of length 2
    for c in codes:
        assert type(c) == str
        assert len(c) == 2
    # test a few big jurisdictions
    for k in ('us', 'uk', 'fr', 'de', 'jp', 'ca'):
        assert k in codes

def test_commutativity():
    codes = cc.license.jurisdictions.list_codes()
    for uri in cc.license.jurisdictions.list_uris():
        assert cc.license.jurisdictions.uri2code(uri) in codes

def test_code_constructor():
    for k in ('us', 'uk', 'fr', 'de', 'jp', 'ca'):
        j = cc.license.jurisdictions.by_code(k)
        assert type(j) == cc.license.Jurisdiction

def test_unported():
    j = cc.license.jurisdictions.by_code('')
    assert j == cc.license.Jurisdiction('')
    assert j.title() == 'Unported'

def test_equality():
    codes = ('', 'jp', 'us')
    one, two, three = ( cc.license.jurisdictions.by_code(c) for c in codes )
    four, five, six = ( cc.license.jurisdictions.by_code(c) for c in codes )
    assert one == one
    assert not (one != one)
    assert one == four
    assert not (one != four)
    assert one != two
    assert two == five
    assert three != four
    assert three == six
    assert not (two == three)
    assert not (five == six)

def test_uri2code():
    for c in ('us', 'uk', 'fr', 'de', 'jp', 'ca'):
        j = cc.license.jurisdictions.by_code(c)
        assert cc.license.jurisdictions.uri2code(j.id) == c

def test_uri2code_trivial():
    assert cc.license.jurisdictions.uri2code('') == ''

def test_uri2code_fails():
    nose.tools.assert_raises(CCLicenseError, cc.license.jurisdictions.uri2code,
                             'roflcopter')

def test_cache():
    tmp = cc.license.jurisdictions.list()
    assert tmp is not cc.license.jurisdictions.list()
    tmp = cc.license.jurisdictions.list_codes()
    assert tmp is not cc.license.jurisdictions.list_codes()
    tmp = cc.license.jurisdictions.list_uris()
    assert tmp is not cc.license.jurisdictions.list_uris()

def test_default_language():
    canada_juris = cc.license.Jurisdiction(
        'http://creativecommons.org/international/ca/')
    assert canada_juris.default_language == 'en-ca'

    finland_juris = cc.license.Jurisdiction(
        'http://creativecommons.org/international/fi/')
    assert finland_juris.default_language == 'fi'

class TestJurisdictions:

    def __init__(self):
        self.langs = ('fr', 'ja', 'de', 'en')
        self.mx = cc.license.Jurisdiction(
                     'http://creativecommons.org/international/mx/')

    def test_jurisdiction(self):
        assert 'creativecommons.org.mx' in self.mx.local_url
        assert self.mx.code == 'mx'
        assert self.mx.launched
        assert self.mx.id.endswith('mx/')

    def test_unported(self):
        j = cc.license.Jurisdiction('')
        assert j.code == ''
        assert j.id == ''
        assert j.local_url == '' #XXX check me!
        assert j.launched

    def test_titles(self):
        for t in self.langs:
            title = self.mx.title(t)
            assert type(title) == unicode
            assert len(title) != 0

    def test_title_default(self):
        assert self.mx.title() == self.mx.title('en')

    def test_constructor_fails(self):
        nose.tools.assert_raises(CCLicenseError,
                             cc.license.Jurisdiction, 'lollerskates')

class TestPublicApi:

    def __init__(self):
        self.dir = dir(cc.license.jurisdictions)

    def test_functions(self):
        for f in ('list_uris', 'list_codes', 'list', 'by_code', 'uri2code'):
            assert f in self.dir

class TestCustomization:

    def __init__(self):
        self.jurisdictions = []
        for code in ('mx', 'jp', 'tw', 'de', 'us', 'uk'):
            self.jurisdictions.append(cc.license.jurisdictions.by_code(code))
        self.unported = cc.license.jurisdictions.by_code('')

    def test_repr(self):
        for j in self.jurisdictions:
            r = repr(j)
            assert j.id in r
            assert j.title() in r
            assert 'Jurisdiction' in r
            assert r.startswith('<')
            assert r.endswith('>')

    def test_repr_unported(self):
        r = repr(self.unported)
        assert self.unported.title() in r
        assert 'Jurisdiction' in r
        assert r.startswith('<')
        assert r.endswith('>')

    def test_str(self):
        for j in self.jurisdictions:
            s = str(j)
            assert j.title() in s
            assert j.code in s

    def test_str_unported(self):
        s = str(self.unported)
        assert self.unported.title() in s

def test_default_language():
    juris = cc.license.Jurisdiction(
        'http://creativecommons.org/international/be/')
    assert juris.default_language == 'fr'

<commit_msg>fix test to allow igo as a 3-letter jurisdiction code<commit_after>"""Tests for Jurisdiction class and other functionality related
   to jurisdictions."""

import cc.license
from cc.license import CCLicenseError
import nose.tools

# TODO: additional tests exercising the output
def test_jurisdictions():
    jurisdictions = cc.license.jurisdictions.list()
    for j in jurisdictions:
        assert type(j) == cc.license.Jurisdiction

def test_jurisdiction_codes():
    codes = cc.license.jurisdictions.list_codes()
    # scotland and igo are the only ones that aren't 2 letters
    assert 'scotland' in codes
    codes.remove('scotland')
    assert 'igo' in codes
    codes.remove('igo')
    # excepting the empty string (default jurisdiction) of course
    assert '' in codes
    codes.remove('')
    # they are all strings of length 2
    for c in codes:
        assert type(c) == str
        assert len(c) == 2
    # test a few big jurisdictions
    for k in ('us', 'uk', 'fr', 'de', 'jp', 'ca'):
        assert k in codes

def test_commutativity():
    codes = cc.license.jurisdictions.list_codes()
    for uri in cc.license.jurisdictions.list_uris():
        assert cc.license.jurisdictions.uri2code(uri) in codes

def test_code_constructor():
    for k in ('us', 'uk', 'fr', 'de', 'jp', 'ca'):
        j = cc.license.jurisdictions.by_code(k)
        assert type(j) == cc.license.Jurisdiction

def test_unported():
    j = cc.license.jurisdictions.by_code('')
    assert j == cc.license.Jurisdiction('')
    assert j.title() == 'Unported'

def test_equality():
    codes = ('', 'jp', 'us')
    one, two, three = ( cc.license.jurisdictions.by_code(c) for c in codes )
    four, five, six = ( cc.license.jurisdictions.by_code(c) for c in codes )
    assert one == one
    assert not (one != one)
    assert one == four
    assert not (one != four)
    assert one != two
    assert two == five
    assert three != four
    assert three == six
    assert not (two == three)
    assert not (five == six)

def test_uri2code():
    for c in ('us', 'uk', 'fr', 'de', 'jp', 'ca'):
        j = cc.license.jurisdictions.by_code(c)
        assert cc.license.jurisdictions.uri2code(j.id) == c

def test_uri2code_trivial():
    assert cc.license.jurisdictions.uri2code('') == ''

def test_uri2code_fails():
    nose.tools.assert_raises(CCLicenseError, cc.license.jurisdictions.uri2code,
                             'roflcopter')

def test_cache():
    tmp = cc.license.jurisdictions.list()
    assert tmp is not cc.license.jurisdictions.list()
    tmp = cc.license.jurisdictions.list_codes()
    assert tmp is not cc.license.jurisdictions.list_codes()
    tmp = cc.license.jurisdictions.list_uris()
    assert tmp is not cc.license.jurisdictions.list_uris()

def test_default_language():
    canada_juris = cc.license.Jurisdiction(
        'http://creativecommons.org/international/ca/')
    assert canada_juris.default_language == 'en-ca'

    finland_juris = cc.license.Jurisdiction(
        'http://creativecommons.org/international/fi/')
    assert finland_juris.default_language == 'fi'

class TestJurisdictions:

    def __init__(self):
        self.langs = ('fr', 'ja', 'de', 'en')
        self.mx = cc.license.Jurisdiction(
                     'http://creativecommons.org/international/mx/')

    def test_jurisdiction(self):
        assert 'creativecommons.org.mx' in self.mx.local_url
        assert self.mx.code == 'mx'
        assert self.mx.launched
        assert self.mx.id.endswith('mx/')

    def test_unported(self):
        j = cc.license.Jurisdiction('')
        assert j.code == ''
        assert j.id == ''
        assert j.local_url == '' #XXX check me!
        assert j.launched

    def test_titles(self):
        for t in self.langs:
            title = self.mx.title(t)
            assert type(title) == unicode
            assert len(title) != 0

    def test_title_default(self):
        assert self.mx.title() == self.mx.title('en')

    def test_constructor_fails(self):
        nose.tools.assert_raises(CCLicenseError,
                             cc.license.Jurisdiction, 'lollerskates')

class TestPublicApi:

    def __init__(self):
        self.dir = dir(cc.license.jurisdictions)

    def test_functions(self):
        for f in ('list_uris', 'list_codes', 'list', 'by_code', 'uri2code'):
            assert f in self.dir

class TestCustomization:

    def __init__(self):
        self.jurisdictions = []
        for code in ('mx', 'jp', 'tw', 'de', 'us', 'uk'):
            self.jurisdictions.append(cc.license.jurisdictions.by_code(code))
        self.unported = cc.license.jurisdictions.by_code('')

    def test_repr(self):
        for j in self.jurisdictions:
            r = repr(j)
            assert j.id in r
            assert j.title() in r
            assert 'Jurisdiction' in r
            assert r.startswith('<')
            assert r.endswith('>')

    def test_repr_unported(self):
        r = repr(self.unported)
        assert self.unported.title() in r
        assert 'Jurisdiction' in r
        assert r.startswith('<')
        assert r.endswith('>')

    def test_str(self):
        for j in self.jurisdictions:
            s = str(j)
            assert j.title() in s
            assert j.code in s

    def test_str_unported(self):
        s = str(self.unported)
        assert self.unported.title() in s

def test_default_language():
    juris = cc.license.Jurisdiction(
        'http://creativecommons.org/international/be/')
    assert juris.default_language == 'fr'

<|endoftext|>