Created
January 4, 2022 12:06
-
-
Save astropenguin/baed5da866788525b9c7211cbe5005c5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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