Skip to content

Instantly share code, notes, and snippets.

@astropenguin
Created January 4, 2022 12:06
Show Gist options
  • Save astropenguin/baed5da866788525b9c7211cbe5005c5 to your computer and use it in GitHub Desktop.
Save astropenguin/baed5da866788525b9c7211cbe5005c5 to your computer and use it in GitHub Desktop.
# coding: utf-8
'''
makefmp.py - make frequency modulation pattern (FMP) file
+ developer: Akio Taniguchi (IoA, UTokyo)
+ contact: taniguchi_at_ioa.s.u-tokyo.ac.jp
'''
import sys
import argparse
from fractions import gcd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
def makefmp(fmstep, fmwidth, fmcycle, df, uniform=False):
'''Make a frequency modulation pattern (FMP) array.
Args:
- fmstep (int): FM step per sampling (ch).
- fmwidth (int): FM total width (ch).
- fmcycle (int): number of FMP cycle.
- df (float): requency resolution per channel (Hz).
- uniform (bool): FMP are uniformly distributed.
Returns:
- fmpfq (array): FMP in unit of Hz.
'''
if fmstep % 2:
raise ValueError('fmstep must be an even integer')
if fmwidth % fmstep:
raise ValueError('fmwidth must be devisible by fmstep')
fmpup = np.arange(-fmwidth//2, +fmwidth//2, +fmstep)
fmpdown = np.arange(+fmwidth//2, -fmwidth//2, -fmstep)
innercycle = gcd(fmstep//2, fmcycle)
outercycle = fmcycle // innercycle
print('innercycle={}'.format(innercycle))
print('outercycle={}'.format(outercycle))
fmoffset = fmstep//innercycle//2 if uniform else 0
fmpch = []
for i in range(outercycle):
for j in range(innercycle):
fmpch.append(fmpup + j*fmoffset)
fmpch.append(fmpdown - (innercycle-j)*fmoffset)
fmpch = np.roll(np.hstack(fmpch), -fmwidth//fmstep//2)
fmpfq = fmpch * df
return fmpfq
def savefmp(fmpfq, fmpfile):
'''Save a frequency modulation pattern (FMP) file.
Args:
- fmpfq (array): FMP in unit of Hz.
- fmpfile (str): name of output FMP file (*.fmp)
Returns:
- None (NoneType): this function returns nothing
'''
with open(fmpfile, 'w') as f:
for i in range(len(fmpfq)):
f.write('{:0>5} {:+.15e}\n'.format(i+1, fmpfq[i]))
if __name__ == '__main__':
# argument parser
p = argparse.ArgumentParser(
description='make frequency modulation pattern (FMP) file')
p.add_argument(
'fmstep', metavar='fmstep', type=int,
help='int: FM step per sampling (ch)')
p.add_argument(
'fmwidth', metavar='fmwidth', type=int,
help='int: FM total width (ch)')
p.add_argument(
'fmcycle', metavar='fmcycle', type=int,
help='int: number of FMP cycle')
p.add_argument(
'df', metavar='df', type=float, default=1.0,
help='float: frequency resolution per channel (Hz)')
p.add_argument(
'fmpfile', metavar='fmpfile', type=str,
help='str: name of output FMP file (*.fmp)')
p.add_argument(
'-u', '--uniform', action='store_true', default=False,
help='FMP are uniformly distributed')
p.add_argument('-p', '--plot', action='store_true', default=False,
help='plot FMP instead of saving FMP file')
# parsed args
a = p.parse_args()
# FMP in unit of Hz
fmpfq = makefmp(a.fmstep, a.fmwidth, a.fmcycle, a.df, a.uniform)
# plot FMP
if a.plot:
plt.plot(np.arange(1,len(fmpfq)+1), fmpfq, '.-')
plt.xlim([1,len(fmpfq)])
plt.xlabel('Sample')
plt.ylabel('Frequency modulation (Hz)')
plt.show()
sys.exit()
# save FMP file
message = 'save FMP to {}? [Y/n] '.format(a.fmpfile)
if input(message) == 'Y':
savefmp(fmpfq, a.fmpfile)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment