From a14cb8afb8fe340812c28a1eddbba57d6dafac9e Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Wed, 28 Mar 2018 15:57:09 +0200 Subject: Add some TII testing scripts --- tii/tii.py | 219 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100755 tii/tii.py (limited to 'tii/tii.py') diff --git a/tii/tii.py b/tii/tii.py new file mode 100755 index 0000000..0ec9429 --- /dev/null +++ b/tii/tii.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Does some TII pattern calculations +# +# http://www.opendigitalradio.org +# Licence: The MIT License, see notice at the end of this file + +import sys +import argparse +import time + +TII_PATTERN = [ # {{{ + [0,0,0,0,1,1,1,1], + [0,0,0,1,0,1,1,1], + [0,0,0,1,1,0,1,1], + [0,0,0,1,1,1,0,1], + [0,0,0,1,1,1,1,0], + [0,0,1,0,0,1,1,1], + [0,0,1,0,1,0,1,1], + [0,0,1,0,1,1,0,1], + [0,0,1,0,1,1,1,0], + [0,0,1,1,0,0,1,1], + [0,0,1,1,0,1,0,1], + [0,0,1,1,0,1,1,0], + [0,0,1,1,1,0,0,1], + [0,0,1,1,1,0,1,0], + [0,0,1,1,1,1,0,0], + [0,1,0,0,0,1,1,1], + [0,1,0,0,1,0,1,1], + [0,1,0,0,1,1,0,1], + [0,1,0,0,1,1,1,0], + [0,1,0,1,0,0,1,1], + [0,1,0,1,0,1,0,1], + [0,1,0,1,0,1,1,0], + [0,1,0,1,1,0,0,1], + [0,1,0,1,1,0,1,0], + [0,1,0,1,1,1,0,0], + [0,1,1,0,0,0,1,1], + [0,1,1,0,0,1,0,1], + [0,1,1,0,0,1,1,0], + [0,1,1,0,1,0,0,1], + [0,1,1,0,1,0,1,0], + [0,1,1,0,1,1,0,0], + [0,1,1,1,0,0,0,1], + [0,1,1,1,0,0,1,0], + [0,1,1,1,0,1,0,0], + [0,1,1,1,1,0,0,0], + [1,0,0,0,0,1,1,1], + [1,0,0,0,1,0,1,1], + [1,0,0,0,1,1,0,1], + [1,0,0,0,1,1,1,0], + [1,0,0,1,0,0,1,1], + [1,0,0,1,0,1,0,1], + [1,0,0,1,0,1,1,0], + [1,0,0,1,1,0,0,1], + [1,0,0,1,1,0,1,0], + [1,0,0,1,1,1,0,0], + [1,0,1,0,0,0,1,1], + [1,0,1,0,0,1,0,1], + [1,0,1,0,0,1,1,0], + [1,0,1,0,1,0,0,1], + [1,0,1,0,1,0,1,0], + [1,0,1,0,1,1,0,0], + [1,0,1,1,0,0,0,1], + [1,0,1,1,0,0,1,0], + [1,0,1,1,0,1,0,0], + [1,0,1,1,1,0,0,0], + [1,1,0,0,0,0,1,1], + [1,1,0,0,0,1,0,1], + [1,1,0,0,0,1,1,0], + [1,1,0,0,1,0,0,1], + [1,1,0,0,1,0,1,0], + [1,1,0,0,1,1,0,0], + [1,1,0,1,0,0,0,1], + [1,1,0,1,0,0,1,0], + [1,1,0,1,0,1,0,0], + [1,1,0,1,1,0,0,0], + [1,1,1,0,0,0,0,1], + [1,1,1,0,0,0,1,0], + [1,1,1,0,0,1,0,0], + [1,1,1,0,1,0,0,0], + [1,1,1,1,0,0,0,0] ] # }}} + +def calculate_A_c_p(c, p, k): + """ETSI EN 300 401 14.8.1""" + r = 0 + + if k == 0 or k == -769: + return 0 + elif -768 <= k and k < -384: + for b in range(8): + if k == -768 + 2*c + 48*b and TII_PATTERN[p][b]: + r += 1 + elif -384 <= k and k < 0: + for b in range(8): + if k == -384 + 2*c + 48*b and TII_PATTERN[p][b]: + r += 1 + elif 0 < k and k <= 384: + for b in range(8): + if k == 1 + 2*c + 48*b and TII_PATTERN[p][b]: + r += 1 + elif 384 < k and k <= 768: + for b in range(8): + if k == 385 + 2*c + 48*b and TII_PATTERN[p][b]: + r += 1 + else: + raise ValueError("Invalid k={}".format(k)) + + # I'm expecting that r means "enable or disable", nothing else + assert(r < 2); + return r + +def calculate_reduced_carrier_indices(c, p): + carriers = [] + for k in range(384): + for b in range(8): + if k == 1 + 2*c + 48*b and TII_PATTERN[p][b]: + carriers.append(k) + return carriers + +def calculate_carrier_indices(c, p): + carriers = calculate_reduced_carrier_indices(c, p) + + # because of z_m,0,k, we enable carrier k if A_c,p(k) or A_c,p(k-1) are + # true + carriers += [k + 1 for k in carriers] + carriers += [k - 769 for k in carriers] + \ + [k - 385 for k in carriers] + \ + [k + 384 for k in carriers] + carriers.sort() + return carriers + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Calculate TII") + parser.add_argument('--all', action='store_const', const=True, + help='Calulate all carrier indices', required=False) + parser.add_argument('--check-zero', action='store_const', const=True, + help='Check if any pattern sets zero freq', required=False) + parser.add_argument('--test1', action='store_const', const=True, + help='Do equivalence test 1', required=False) + cli_args = parser.parse_args() + + + if cli_args.all: + for c in range(24): + for p in range(70): + carriers = calculate_carrier_indices(c, p) + print(c, p, carriers, len(carriers)) + + elif cli_args.check_zero: + for c in range(24): + for p in range(70): + carriers = calculate_carrier_indices(c, p) + if 0 in carriers: + print("Found 0 in") + elif 1 in carriers: + print("Found 1 in") + elif -1 in carriers: + print("Found -1 in") + else: + continue + print("Car: ", c, p, carriers, len(carriers)) + + elif cli_args.test1: + print("Running compare test table") + duration1 = 0 + duration2 = 0 + for c in range(24): + for p in range(70): + start1 = time.time() + carriers0 = [k + for k in range(-768, 769) + if calculate_A_c_p(c, p, k) or calculate_A_c_p(c, p, k-1)] + carriers0.sort() + duration1 += (time.time() - start1) + + start2 = time.time() + carriers1 = calculate_carrier_indices(c, p) + duration2 += (time.time() - start2) + + if carriers0 != carriers1: + print("0: {}".format(carriers0)) + print("1: {}".format(carriers1)) + sys.exit(1) + print("Comparison successful: {} vs {}".format(duration1, duration2)) + + else: + print("Example given in standard:") + c = 1 + p = 11 + acps = [k + for k in range(-768, 769) + if calculate_A_c_p(c, p, k)] + print("ACP: ", c, p, acps, len(acps)) + carriers = calculate_carrier_indices(c, p) + print("Car: ", c, p, carriers, len(carriers)) + +# The MIT License (MIT) +# +# Copyright (c) 2018 Matthias P. Braendli +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. -- cgit v1.2.3