Skip to content

Commit

Permalink
Merge pull request #22 from blevic/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
blevic authored Jul 25, 2022
2 parents b4d7e35 + 520e43a commit c60579e
Show file tree
Hide file tree
Showing 8 changed files with 218 additions and 11 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ pip install nrarfcn

>>> nr.get_frequency_range('n100', direction='dl')
(919.4, 925)

>>> nr.get_frequency_by_gscn(2156)
862.85

>>> nr.get_gscn_by_frequency(4405.440)
8475

>>> nr.get_gscn_range('n92')
(3584, 3787)
```

### Contributing
Expand Down
9 changes: 9 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ Usage
>>> nr.get_frequency_range('n100', direction='dl')
(919.4, 925)
>>> nr.get_frequency_by_gscn(2156)
862.85
>>> nr.get_gscn_by_frequency(4405.440)
8475
>>> nr.get_gscn_range('n92')
(3584, 3787)
Documentation
~~~~~~~~~~~~~

Expand Down
4 changes: 2 additions & 2 deletions nrarfcn/api/get_frequency.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ def get_frequency(nrarfcn: int) -> float:
n_offset = table.get_cell(row, 'n_ref_offs')
freq_khz = f_offset + delta_f * (nrarfcn - n_offset)
freq_mhz = freq_khz / 1000
return freq_mhz
return round(freq_mhz, 3)

raise ValueError('NR-ARFCN is not valid.')
raise ValueError('NR-ARFCN is not valid.')
6 changes: 4 additions & 2 deletions nrarfcn/api/get_frequency_by_gscn.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ def get_frequency_by_gscn(gscn: int) -> float:
if table.get_cell(row, 'gscn_min') <= gscn <= table.get_cell(row, 'gscn_max'):
if table.get_cell(row, 'm_set') == {}:
n = gscn - table.get_cell(row, 'g_offs')
return table.get_cell(row, 'f_offs') + table.get_cell(row, 'n_coeff') * n
freq = table.get_cell(row, 'f_offs') + table.get_cell(row, 'n_coeff') * n
return round(freq, 3)
else:
if gscn % 3 == 0:
n = gscn // table.get_cell(row, 'g_n_coeff')
Expand All @@ -37,6 +38,7 @@ def get_frequency_by_gscn(gscn: int) -> float:
n = (gscn + 1) // table.get_cell(row, 'g_n_coeff')
m = 1

return table.get_cell(row, 'f_offs') + table.get_cell(row, 'n_coeff') * n + table.get_cell(row, 'm_coeff') * m
freq = table.get_cell(row, 'f_offs') + table.get_cell(row, 'n_coeff') * n + table.get_cell(row, 'm_coeff') * m
return round(freq, 3)

raise ValueError("Expected to have found a GSCN in the table, but didn't")
31 changes: 30 additions & 1 deletion nrarfcn/api/get_gscn_by_frequency.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,34 @@


def get_gscn_by_frequency(freq: float) -> int:
"""Gets the GSCN (Global Synchronization Channel Number) of a given frequency in MHz.
Args:
freq: The frequency to get the GSCN of.
Returns:
The GSCN of the given frequency, in MHz, or the closest GSCN to the given frequency.
Raises:
ValueError: If the given frequency is invalid
"""
if not isinstance(freq, float) and not isinstance(freq, int):
raise ValueError("Frequency must be a float or an integer")

if freq < 0 or freq > 100_000:
raise ValueError("Frequency must be between 0 and 100,000 (MHz)")

table = table_gscn_parameters()
return 0

for row in table.data:
if table.get_cell(row, 'f_min') <= freq <= table.get_cell(row, 'f_max'):
if table.get_cell(row, 'm_set') == {}:
n = round((freq - table.get_cell(row, 'f_offs'))/table.get_cell(row, 'n_coeff'))
return int(table.get_cell(row, 'g_offs') + n)
else:
n_round_gap = table.get_cell(row, 'm_coeff') * sum(table.get_cell(row, 'm_set'))/len(table.get_cell(row, 'm_set'))
n = round((freq - n_round_gap) / table.get_cell(row, 'n_coeff'))
m = min((abs(freq - (n * table.get_cell(row, 'n_coeff') + m_candidate * table.get_cell(row, 'm_coeff'))), m_candidate) for m_candidate in table.get_cell(row, 'm_set'))[1]
return int(table.get_cell(row, 'g_offs') + n * table.get_cell(row, 'g_n_coeff') + m * table.get_cell(row, 'g_m_coeff'))

raise ValueError("Expected to have found a frequency in the table, but didn't")
42 changes: 41 additions & 1 deletion nrarfcn/api/get_gscn_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,47 @@


def get_gscn_range(band: Union[str, int]) -> tuple:
"""Gets the GSCN range for a given band.
Args:
band: The band to get the range for, e.g. 'n12' or 12.
Returns:
A tuple with the min GSCN and max GSCN for the given band.
Raises:
ValueError: If the given band is not a valid band.
"""
table_fr1 = table_applicable_ss_raster_fr1()
table_fr2 = table_applicable_ss_raster_fr2()

return 0, 0
valid_bands = table_fr1.get_column('band') + table_fr2.get_column('band')

if isinstance(band, int):
band = 'n' + str(band)

if not isinstance(band, str) or not band or band[0] != 'n':
raise ValueError("The band must be an integer or a string starting with 'n': 12, 'n12', 101, 'n101', etc.")

if band not in valid_bands:
raise ValueError(f'Invalid band: {band}.')

tables = [table_fr1, table_fr2]
band_rows = []

for table in tables:
for row in table.data:
if table.get_cell(row, 'band') == band:
gscn_first = table.get_cell(row, 'gscn_first')
gscn_last = table.get_cell(row, 'gscn_last')

if gscn_first == 0 or gscn_last == 0:
gscn_first = min(table.get_cell(row, 'note'))
gscn_last = max(table.get_cell(row, 'note'))

band_rows.append((gscn_first, gscn_last))

min_gscn = min(band_rows, key=lambda x: x[0])[0]
max_gscn = max(band_rows, key=lambda x: x[1])[1]

return min_gscn, max_gscn
58 changes: 55 additions & 3 deletions tests/test_get_gscn_by_frequency.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,62 @@

class TestGetGscnByFrequency(unittest.TestCase):
def test_valid_freqs(self):
pass
gscn_freq_map = {
2: 1.250,
3: 1.350,
4: 1.450,
5: 2.450,
6: 2.550,
7: 2.650,
500: 200.450,
1000: 399.850,
5000: 2000.450,
7498: 2999.050,
7499: 3000.000,
10000: 6601.440,
15000: 13801.440,
20000: 21001.440,
22255: 24248.640,
22256: 24250.080,
23000: 37106.400,
25000: 71666.400,
26639: 99988.320
}

for gscn, freq in gscn_freq_map.items():
self.assertEqual(get_gscn_by_frequency(freq), gscn)

def test_different_freqs(self):
pass
different_freqs = [
(1.250, 1.350),
(1.280, 1.320),
(1.299, 1.301),
(1.450, 2.450),
(1.550, 2.350),
(1.650, 2.250),
(1.750, 2.150),
(1.850, 2.050),
(1.910, 1.990),
(1.940, 1.960),
(2997.850, 2998.850),
(2998.050, 2998.650),
(2998.250, 2998.450),
(2998.349, 2998.351),
(3000.000, 3001.440),
(3000.500, 3000.940),
(3000.700, 3000.740),
(3000.719, 3000.721),
(24250.080, 24267.360),
(24258.080, 24259.360),
(24258.719, 24258.721),
]

for freq1, freq2 in different_freqs:
self.assertNotEqual(get_gscn_by_frequency(freq1), get_gscn_by_frequency(freq2))

def test_invalid_freqs(self):
pass
invalid_freqs = [-1.0, -1, -0.01, 100000.01, 100001, 100001.0, None, '', '60000']

for freq in invalid_freqs:
with self.assertRaises(ValueError):
get_gscn_by_frequency(freq)
70 changes: 68 additions & 2 deletions tests/test_get_gscn_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,73 @@

class TestGetGscnRange(unittest.TestCase):
def test_valid_bands(self):
pass
band_range_map = {
'n1': (5279, 5419),
'n2': (4829, 4969),
'n3': (4517, 4693),
'n5': (2177, 2230),
'n7': (6554, 6718),
'n8': (2318, 2395),
'n12': (1828, 1858),
'n13': (1871, 1885),
'n14': (1901, 1915),
'n18': (2156, 2182),
'n20': (1982, 2047),
'n24': (3818, 3892),
'n25': (4829, 4981),
'n26': (2153, 2230),
'n28': (1901, 2002),
'n29': (1798, 1813),
'n30': (5879, 5893),
'n34': (5032, 5054),
'n38': (6432, 6543),
'n39': (4707, 4793),
'n40': (5762, 5989),
'n41': (6246, 6717),
'n46': (8993, 9530),
'n48': (7884, 7982),
'n50': (3590, 3781),
'n51': (3572, 3574),
'n53': (6215, 6232),
'n65': (5279, 5494),
'n66': (5279, 5494),
'n67': (1850, 1888),
'n70': (4993, 5044),
'n71': (1547, 1624),
'n74': (3692, 3790),
'n75': (3584, 3787),
'n76': (3572, 3574),
'n77': (7711, 8329),
'n78': (7711, 8051),
'n79': (8475, 8884),
'n85': (1826, 1858),
'n90': (6245, 6718),
'n91': (3572, 3574),
'n92': (3584, 3787),
'n93': (3572, 3574),
'n94': (3584, 3787),
'n96': (9531, 10363),
'n100': (2303, 2307),
'n101': (4754, 4768),
'n102': (9531, 9877),
'n104': (9882, 10358),
'n257': (22388, 22558),
'n258': (22257, 22443),
'n259': (23140, 23369),
'n260': (22995, 23166),
'n261': (22446, 22492),
'n262': (23586, 23641),
'n263': (24156, 24957)
}

for band, (min_gscn, max_gscn) in band_range_map.items():
self.assertEqual(get_gscn_range(band), (min_gscn, max_gscn))
int_band = int(band[1:])
self.assertEqual(get_gscn_range(int_band), (min_gscn, max_gscn))

def test_invalid_bands(self):
pass
invalid_bands = ['n4', 4, 'n6', 6, 0, 1.0, -1, 'n0', 64, 256, 'n', '']

for band in invalid_bands:
with self.assertRaises(ValueError):
get_gscn_range(band)

0 comments on commit c60579e

Please sign in to comment.