Source code for pycraf.protection.cispr

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

from __future__ import (
    absolute_import, unicode_literals, division, print_function
    )

from functools import partial  # , update_wrapper
import numpy as np
from astropy import units as apu
from astropy.units import Quantity, UnitsError
from .. import conversions as cnv
from .. import utils


__all__ = ['cispr11_limits', 'cispr22_limits']


def _cispr_limits(
        params, freq, detector_type='RMS', detector_dist=30.
        ):
    '''
    The params dictionary must have the following content:
    'lims' - list of tuples (low freq, high freq, limit in dB_uV_m)
    'dist' - distance detector <-> source for which the limits are valid
    'meas_bw' - measurement bandwidth
    '''

    assert params is not None
    assert detector_type in ['QP', 'RMS']

    freq = np.atleast_1d(freq)
    Elim = np.ones(freq.shape, dtype=np.float64)

    for lof, hif, lim in params['lims']:

        mask = (freq >= lof) & (freq < hif)
        Elim[mask] = lim

    # 20, because area of sphere is proportional to radius ** 2
    Elim += 20 * np.log10(params['dist'] / detector_dist)

    # According to Hasenpusch (BNetzA, priv. comm.) the CISPR standard
    # detector is a quasi-peak detector with a bandwidth of 120 kHz. To
    # convert to an RMS detector (which is more suitable to the RA.769) one
    # has to subtract 5.5 dB.
    if detector_type == 'RMS':
        Elim -= 5.5

    return Elim, params['meas_bw']


[docs]@utils.ranged_quantity_input( freq=(0, None, apu.MHz), detector_dist=(0.001, None, apu.m), strip_input_units=True, output_unit=(cnv.dB_uV_m, apu.kHz) ) def cispr11_limits(freq, detector_type='RMS', detector_dist=30. * apu.m): ''' Industrial-device limits for given frequency and distance from device according to `CISPR-11 (EN 55011) <http://rfemcdevelopment.eu/index.php/en/emc-emi-standards/en-55011-2009>`_. Parameters ---------- freq : `~astropy.units.Quantity` Frequency or frequency vector [Hz] detector_type : str, optional Detector type: 'QP' (quasi-peak), 'RMS' (default: 'RMS) detector_dist : `~astropy.units.Quantity`, optional Distance between source and detector [m], (default: 30 m) Returns ------- efield_limit : `~astropy.units.Quantity` Electric-field limit permitted by CISPR-11 at given distance. [dB(uV^2 / m^2)] meas_bw : `~astropy.units.Quantity` Measure bandwidth (of detector) [kHz] ''' cispr11_params = { 'lims': [ (0, 230, 30), (230, 1e20, 37) ], 'dist': 30, 'meas_bw': 120, } return _cispr_limits( cispr11_params, freq, detector_type=detector_type, detector_dist=detector_dist )
[docs]@utils.ranged_quantity_input( freq=(0, None, apu.MHz), detector_dist=(0.001, None, apu.m), strip_input_units=True, output_unit=(cnv.dB_uV_m, apu.kHz) ) def cispr22_limits(freq, detector_type='RMS', detector_dist=30. * apu.m): ''' Industrial-device limits for given frequency and distance from device according to `CISPR-22 (EN 55022) <http://www.rfemcdevelopment.eu/en/en-55022-2010>`_. Parameters ---------- freq : `~astropy.units.Quantity` Frequency or frequency vector [MHz] detector_type : str, optional Detector type: 'QP' (quasi-peak), 'RMS' (default: 'RMS) detector_dist : `~astropy.units.Quantity`, optional Distance between source and detector [m], (default: 30 m) Returns ------- efield_limit : `~astropy.units.Quantity` Electric-field limit permitted by CISPR-22 at given distance. [dB(uV^2 / m^2)] meas_bw : `~astropy.units.Quantity` Measure bandwidth (of detector) [kHz] ''' cispr22_params = { 'lims': [ (0, 230, 40), (230, 1000, 47), (1000, 3000, 56), (3000, 1e20, 60) ], 'dist': 30, 'meas_bw': 120, # is this correct? } return _cispr_limits( cispr22_params, freq, detector_type=detector_type, detector_dist=detector_dist )