Source code for irfpy.vels.mode

''' ELS mode related module.

Constants are defined:

    - :attr:`MODE_E128`
    - :attr:`MODE_E32`
    - :attr:`MODE_UNKNOWN`
'''
import logging

import numpy

from irfpy.vels.bible import energy as bible_energy

class __ElsMode:
    ''' ELS mode class. It is a base class.
    '''
    def __init__(self):
        pass

class __ModeE128(__ElsMode):
    ''' ELS mode energy 128.
    '''
    def __init__(self):
        pass

    def __str__(self):
        return "<VE128>"

MODE_E128 = __ModeE128()
''' E128 mode constant.
'''

class __ModeE32(__ElsMode):
    ''' ELS mode energy 32.
    '''
    def __init__(self):
        pass

    def __str__(self):
        return "<VE032>"

MODE_E32 = __ModeE32()
''' E32 mode constant.
'''

class __ModeUnknown(__ElsMode):
    ''' ELS mode but unknown
    '''
    def __init__(self):
        pass

    def __str__(self):
        return "<VE???>"

MODE_UNKNOWN = __ModeUnknown()
''' Unknown mode constant.
'''

[docs]def guess_mode_from_level(tm_level): ''' Return the mode instance. :param tm_level: An array of TM level. :type tm_level: ``numpy.array`` with (128,) shape. High energy first. :returns: :attr:`MODE_E128`, :attr:`MODE_E32` or :attr:`MODE_UNKNOWN`. Algorithm used is as follows. Take a difference between the monitor level and reference level for E128 and E32x4 mode. Take the 64 steps with smallest difference out of 128 steps for each mode, and calculate squared sum. The values can be proxies for *resembleness* of monitor level to E128 and E32x4 respectively. Smaller one (20% margin) is returned as the mode applied. ''' logger = logging.getLogger('guess_mode_from_level') # logger.setLevel(logging.DEBUG) # Two levels. According to bible energy table order # reversing operation [::-1] is added. level128 = abs(bible_energy.EnergyTable128().tmidx())[::-1] level32 = abs(bible_energy.EnergyTable32().tmidx())[::-1] level32 = numpy.concatenate([level32, level32, level32, level32]) logger.debug('Shape = %s' % str(tm_level.shape)) diff128 = (level128 - tm_level) diff32 = (level32 - tm_level) # Compare 64 best channels least square between 128 and 32. sum128 = sum(sorted(((level128 - tm_level)**2))[0:64]) sum32 = sum(sorted(((level32 - tm_level)**2))[0:64]) ratio_128_or_32 = 1. * sum128 / sum32 unknown_boundary = 0.2 # if within 20% difference, unknown is returned. logger.debug('Comparison: L128=%d L32=%d ratio=%f' % (sum128, sum32, ratio_128_or_32)) if ratio_128_or_32 > (1 + unknown_boundary): logger.debug('Guess E32') elsmode = MODE_E32 elif ratio_128_or_32 < 1 / (1 + unknown_boundary): logger.debug('Guess E128') elsmode = MODE_E128 else: logger.debug('Guess Failed, Unknown.') elsmode = MODE_UNKNOWN # logger.setLevel(logging.WARN) return elsmode