Создадим истинную электронную плотность

In [28]:
%run scripts/compile-func.py -g 8,3,2+6,3,3.4+8,3,4.6+1,3,10+16,3,11.5+1,3,13 -o func.txt
File func.txt created

А теперь будем долго и упорно с ней эксперементировать

Для начала посмотрим самый простой случай: по всем имеющимся гармоникам Фурье без всякого шума воссоздали исходную функцию. Неинтересно...

In [29]:
%run scripts/func2fourier.py -i func.txt -o full.txt
%run scripts/fourier2func.py -f func.txt -i full.txt -o full_2func.txt
..Done
File full_2func.txt with function and its recovering is created

Создадим функцию, которая бы создавала гармоники с шумом, отбирала только некоторые из них и преобразовывалаих в экспериментальную функию. А также зададим функцию подсчёта разрешения.

In [30]:
from itertools import chain


def count_resolution(select, min_cover=0.9, T=30):
    groups = select.split(',')
    ranges = []
    for group in groups:
        if '-' not in group:
            group = group+'-'+group
        a, b = list(map(int, group.split('-')))
        b += 1
        ranges.append(range(a, b))
    horms = sorted(list(chain(*ranges)))
    full_horms = list(range(0, horms[-1]+1))

    resolutions = list()
    coverages = list()
    for i, horm in enumerate(horms):
        count = i+1
        full_count = full_horms.index(horm) + 1
        coverage = count/full_count
        coverages.append(coverage)
        if horm != 0:
            resolution = T / horm
        else:
            resolution = T
        resolutions.append(resolution)
    resolutions = resolutions[::-1]
    coverages = coverages[::-1]
    for i, coverage in enumerate(coverages):
        if coverage >= min_cover:
            return resolutions[i], coverage

    return resolutions[0], coverages[0]


def experiment(func_file, select=None, amp_noise=0, phase_noise=0):
    amp_noise = str(amp_noise)
    phase_noise = str(phase_noise)

    full_file_name = "full_" + amp_noise + "_" + phase_noise + ".txt"

    args = "".join(["-i ", func_file, ' -o ', full_file_name,
                    ' -F ', amp_noise, ' -P ', phase_noise])

    %run scripts/func2fourier.py $args
    if select != None:
        sel_file_name = "sel_" + \
            select.replace(',', '_') + "_" + amp_noise + \
            "_" + phase_noise + ".txt"
        args = "".join(["-i ", full_file_name, " -r ",
                        select, " -o ", sel_file_name])
        %run scripts/fourier-filter.py $args
    else:
        sel_file_name = full_file_name
    res_file_name = sel_file_name[:-4] + "_2func.txt"

    args = "".join(["-f ", func_file, " -i ",
                    sel_file_name, " -o ", res_file_name])

    %run scripts/fourier2func.py $args
    print(select.replace(',', ', ') if select != None else "All", count_resolution(select),
          amp_noise + '%', phase_noise + '%', sep="\t")
    return (select.replace(',', ', ') if select != None else "All", count_resolution(select)[0],
            str(round(count_resolution(select)[1]*100, 2))+"%", amp_noise + '%', phase_noise + '%')

def summarise(results):
    print("Summary")
    print("Harmonics\tResolution\tCoverage\tAmp Noise\tPhi Noise")
    for res in results:
        print(*res, sep="\t")
In [31]:
count_resolution("10-30")
Out[31]:
(1.0, 0.6774193548387096)

Часть 1. Число гармоник в полном наборе

In [32]:
selects = []
for i in [0,1,3,4,10,20,25,30,40,50]:
    selects.append("0-"+str(i))
    
results = []
for select in selects:
    results.append(experiment("func.txt", select, 0, 0))
summarise(results)
..Done
..Done
File sel_0-0_0_0_2func.txt with function and its recovering is created
0-0	(30, 1.0)	0%	0%
..Done
..Done
File sel_0-1_0_0_2func.txt with function and its recovering is created
0-1	(30.0, 1.0)	0%	0%
..Done
..Done
File sel_0-3_0_0_2func.txt with function and its recovering is created
0-3	(10.0, 1.0)	0%	0%
..Done
..Done
File sel_0-4_0_0_2func.txt with function and its recovering is created
0-4	(7.5, 1.0)	0%	0%
..Done
..Done
File sel_0-10_0_0_2func.txt with function and its recovering is created
0-10	(3.0, 1.0)	0%	0%
..Done
..Done
File sel_0-20_0_0_2func.txt with function and its recovering is created
0-20	(1.5, 1.0)	0%	0%
..Done
..Done
File sel_0-25_0_0_2func.txt with function and its recovering is created
0-25	(1.2, 1.0)	0%	0%
..Done
..Done
File sel_0-30_0_0_2func.txt with function and its recovering is created
0-30	(1.0, 1.0)	0%	0%
..Done
..Done
File sel_0-40_0_0_2func.txt with function and its recovering is created
0-40	(0.75, 1.0)	0%	0%
..Done
..Done
File sel_0-50_0_0_2func.txt with function and its recovering is created
0-50	(0.6, 1.0)	0%	0%
Summary
Harmonics	Resolution	Coverage	Amp Noise	Phi Noise
0-0	30	100.0%	0%	0%
0-1	30.0	100.0%	0%	0%
0-3	10.0	100.0%	0%	0%
0-4	7.5	100.0%	0%	0%
0-10	3.0	100.0%	0%	0%
0-20	1.5	100.0%	0%	0%
0-25	1.2	100.0%	0%	0%
0-30	1.0	100.0%	0%	0%
0-40	0.75	100.0%	0%	0%
0-50	0.6	100.0%	0%	0%

Часть 2. Влияние шума на качество синтеза Фурье

Для гармоник 0-25

In [33]:
select = "0-25"
amp_noises = [5,10,20,30]

results = []
for noise in amp_noises:
    results.append(experiment("func.txt", select, noise, 0))
summarise(results)
..Done
..Done
File sel_0-25_5_0_2func.txt with function and its recovering is created
0-25	(1.2, 1.0)	5%	0%
..Done
..Done
File sel_0-25_10_0_2func.txt with function and its recovering is created
0-25	(1.2, 1.0)	10%	0%
..Done
..Done
File sel_0-25_20_0_2func.txt with function and its recovering is created
0-25	(1.2, 1.0)	20%	0%
..Done
..Done
File sel_0-25_30_0_2func.txt with function and its recovering is created
0-25	(1.2, 1.0)	30%	0%
Summary
Harmonics	Resolution	Coverage	Amp Noise	Phi Noise
0-25	1.2	100.0%	5%	0%
0-25	1.2	100.0%	10%	0%
0-25	1.2	100.0%	20%	0%
0-25	1.2	100.0%	30%	0%
In [34]:
select = "0-25"
phi_noises = [5,10,20,30]
results = []
for noise in phi_noises:
    results.append(experiment("func.txt", select, 0, noise))
summarise(results)
..Done
..Done
File sel_0-25_0_5_2func.txt with function and its recovering is created
0-25	(1.2, 1.0)	0%	5%
..Done
..Done
File sel_0-25_0_10_2func.txt with function and its recovering is created
0-25	(1.2, 1.0)	0%	10%
..Done
..Done
File sel_0-25_0_20_2func.txt with function and its recovering is created
0-25	(1.2, 1.0)	0%	20%
..Done
..Done
File sel_0-25_0_30_2func.txt with function and its recovering is created
0-25	(1.2, 1.0)	0%	30%
Summary
Harmonics	Resolution	Coverage	Amp Noise	Phi Noise
0-25	1.2	100.0%	0%	5%
0-25	1.2	100.0%	0%	10%
0-25	1.2	100.0%	0%	20%
0-25	1.2	100.0%	0%	30%
In [35]:
select = "0-25"
comb_noise = [5,10,20,30]
results = []
for noise in comb_noise:
    results.append(experiment("func.txt", select, noise, noise))
summarise(results)
..Done
..Done
File sel_0-25_5_5_2func.txt with function and its recovering is created
0-25	(1.2, 1.0)	5%	5%
..Done
..Done
File sel_0-25_10_10_2func.txt with function and its recovering is created
0-25	(1.2, 1.0)	10%	10%
..Done
..Done
File sel_0-25_20_20_2func.txt with function and its recovering is created
0-25	(1.2, 1.0)	20%	20%
..Done
..Done
File sel_0-25_30_30_2func.txt with function and its recovering is created
0-25	(1.2, 1.0)	30%	30%
Summary
Harmonics	Resolution	Coverage	Amp Noise	Phi Noise
0-25	1.2	100.0%	5%	5%
0-25	1.2	100.0%	10%	10%
0-25	1.2	100.0%	20%	20%
0-25	1.2	100.0%	30%	30%

Для гармоник 0-30

In [36]:
select = "0-30"
amp_noises = [5,10,20,30]
results = []
for noise in amp_noises:
    results.append(experiment("func.txt", select, noise, 0))
summarise(results)
..Done
..Done
File sel_0-30_5_0_2func.txt with function and its recovering is created
0-30	(1.0, 1.0)	5%	0%
..Done
..Done
File sel_0-30_10_0_2func.txt with function and its recovering is created
0-30	(1.0, 1.0)	10%	0%
..Done
..Done
File sel_0-30_20_0_2func.txt with function and its recovering is created
0-30	(1.0, 1.0)	20%	0%
..Done
..Done
File sel_0-30_30_0_2func.txt with function and its recovering is created
0-30	(1.0, 1.0)	30%	0%
Summary
Harmonics	Resolution	Coverage	Amp Noise	Phi Noise
0-30	1.0	100.0%	5%	0%
0-30	1.0	100.0%	10%	0%
0-30	1.0	100.0%	20%	0%
0-30	1.0	100.0%	30%	0%
In [37]:
select = "0-30"
phi_noises = [5,10,20,30]
results = []
for noise in phi_noises:
    results.append(experiment("func.txt", select, 0, noise))
summarise(results)
..Done
..Done
File sel_0-30_0_5_2func.txt with function and its recovering is created
0-30	(1.0, 1.0)	0%	5%
..Done
..Done
File sel_0-30_0_10_2func.txt with function and its recovering is created
0-30	(1.0, 1.0)	0%	10%
..Done
..Done
File sel_0-30_0_20_2func.txt with function and its recovering is created
0-30	(1.0, 1.0)	0%	20%
..Done
..Done
File sel_0-30_0_30_2func.txt with function and its recovering is created
0-30	(1.0, 1.0)	0%	30%
Summary
Harmonics	Resolution	Coverage	Amp Noise	Phi Noise
0-30	1.0	100.0%	0%	5%
0-30	1.0	100.0%	0%	10%
0-30	1.0	100.0%	0%	20%
0-30	1.0	100.0%	0%	30%
In [38]:
select = "0-30"
comb_noise = [5,10,20,30]
results = []
for noise in comb_noise:
    results.append(experiment("func.txt", select, noise, noise))
summarise(results)
..Done
..Done
File sel_0-30_5_5_2func.txt with function and its recovering is created
0-30	(1.0, 1.0)	5%	5%
..Done
..Done
File sel_0-30_10_10_2func.txt with function and its recovering is created
0-30	(1.0, 1.0)	10%	10%
..Done
..Done
File sel_0-30_20_20_2func.txt with function and its recovering is created
0-30	(1.0, 1.0)	20%	20%
..Done
..Done
File sel_0-30_30_30_2func.txt with function and its recovering is created
0-30	(1.0, 1.0)	30%	30%
Summary
Harmonics	Resolution	Coverage	Amp Noise	Phi Noise
0-30	1.0	100.0%	5%	5%
0-30	1.0	100.0%	10%	10%
0-30	1.0	100.0%	20%	20%
0-30	1.0	100.0%	30%	30%

Часть 3. Неполный набор гармоник

In [39]:
selects = ["1-30","2-30","5-30","0-3,5-30","0-14,16-30","0-27,29-30", "0-10,20-30", "0-8,10-19,21-25,27-30"]
results = []
for select in selects:
    results.append(experiment("func.txt", select, 0, 0))
summarise(results)
..Done
..Done
File sel_1-30_0_0_2func.txt with function and its recovering is created
1-30	(1.0, 0.967741935483871)	0%	0%
..Done
..Done
File sel_2-30_0_0_2func.txt with function and its recovering is created
2-30	(1.0, 0.9354838709677419)	0%	0%
..Done
..Done
File sel_5-30_0_0_2func.txt with function and its recovering is created
5-30	(1.0, 0.8387096774193549)	0%	0%
..Done
..Done
File sel_0-3_5-30_0_0_2func.txt with function and its recovering is created
0-3, 5-30	(1.0, 0.967741935483871)	0%	0%
..Done
..Done
File sel_0-14_16-30_0_0_2func.txt with function and its recovering is created
0-14, 16-30	(1.0, 0.967741935483871)	0%	0%
..Done
..Done
File sel_0-27_29-30_0_0_2func.txt with function and its recovering is created
0-27, 29-30	(1.0, 0.967741935483871)	0%	0%
..Done
..Done
File sel_0-10_20-30_0_0_2func.txt with function and its recovering is created
0-10, 20-30	(3.0, 1.0)	0%	0%
..Done
..Done
File sel_0-8_10-19_21-25_27-30_0_0_2func.txt with function and its recovering is created
0-8, 10-19, 21-25, 27-30	(1.0, 0.9032258064516129)	0%	0%
Summary
Harmonics	Resolution	Coverage	Amp Noise	Phi Noise
1-30	1.0	96.77%	0%	0%
2-30	1.0	93.55%	0%	0%
5-30	1.0	83.87%	0%	0%
0-3, 5-30	1.0	96.77%	0%	0%
0-14, 16-30	1.0	96.77%	0%	0%
0-27, 29-30	1.0	96.77%	0%	0%
0-10, 20-30	3.0	100.0%	0%	0%
0-8, 10-19, 21-25, 27-30	1.0	90.32%	0%	0%

Добавим шум к некоторым неполным наборам гармоник

In [40]:
selects = ["0-8,10-19,21-25,27-30"]
noises = [5,20]
results = []
for select in selects:
    for noise in noises:
        results.append(experiment("func.txt", select, noise, noise))
summarise(results)
..Done
..Done
File sel_0-8_10-19_21-25_27-30_5_5_2func.txt with function and its recovering is created
0-8, 10-19, 21-25, 27-30	(1.0, 0.9032258064516129)	5%	5%
..Done
..Done
File sel_0-8_10-19_21-25_27-30_20_20_2func.txt with function and its recovering is created
0-8, 10-19, 21-25, 27-30	(1.0, 0.9032258064516129)	20%	20%
Summary
Harmonics	Resolution	Coverage	Amp Noise	Phi Noise
0-8, 10-19, 21-25, 27-30	1.0	90.32%	5%	5%
0-8, 10-19, 21-25, 27-30	1.0	90.32%	20%	20%