include peak detection in scheludko

This commit is contained in:
François Boulogne 2025-05-21 14:43:20 +02:00
parent 56aac01151
commit ccd1f2c1f0
7 changed files with 100 additions and 82 deletions

View file

@ -14,6 +14,7 @@ import matplotlib.pyplot as plt
from optifik.analysis import * from optifik.analysis import *
from optifik.auto import auto from optifik.auto import auto
from optifik import io
plt.rc('text', usetex=True) plt.rc('text', usetex=True)
plt.rcParams.update({ plt.rcParams.update({
@ -25,6 +26,36 @@ plt.rcParams.update({
def play():
##### Chemin du dossier contenant le spectre #####
DATA_FOLDER = os.path.abspath(os.path.join(os.path.curdir, 'tests', 'basic'))
#SAVE_FOLDER = DATA_FOLDER
# FILE_NAME = '003582.xy' #FFT Exemple -> FFT 3524.51
# FILE_NAME = '000004310.xy' #OOspectro Exemple -> minmax 1338.35
# FILE_NAME = '000005253.xy'#Scheludko 4 pics Exemple -> scheludko ²
# FILE_NAME = '000006544.xy'#Scheludko 2 pics Exemple -> ombre ## Diviser prominence FFT par 2
# FILE_NAME = '000018918.xy' #Scheludko 1 pic max Exemple -> ombre ## Diviser prominence FFT par 2
FILE_NAME = '000004310.xy' #TEST#
spectrum_file = os.path.join(DATA_FOLDER, FILE_NAME)
lambdas, intensities = io.load_spectrum(spectrum_file)
plot_spectrum(lambdas, intensities, title='Raw')
lambdas, intensities = io.load_spectrum(spectrum_file, lambda_min=450)
plot_spectrum(lambdas, intensities, title='Raw, cropped')
smoothed_intensities = smooth_intensities(intensities)
plot_spectrum(lambdas, smoothed_intensities, title='Smoothed')
prominence = 0.02
total_extrema, peaks_min, peaks_max = finds_peak(lambdas, smoothed_intensities,
min_peak_prominence=prominence,
plot=True)
def check_basic(): def check_basic():
##### Chemin du dossier contenant le spectre ##### ##### Chemin du dossier contenant le spectre #####
@ -41,7 +72,8 @@ def check_basic():
FILE_NAME = '000004310.xy' #TEST# FILE_NAME = '000004310.xy' #TEST#
auto(DATA_FOLDER, FILE_NAME, plot=False) spectrum_file = os.path.join(DATA_FOLDER, FILE_NAME)
auto(spectrum_file, plot=False)
def check_SV1(): def check_SV1():
@ -80,8 +112,9 @@ def check_SV1():
##### Find Peak ##### ##### Find Peak #####
total_extrema, smoothed_intensities, raw_intensities, lambdas, peaks_min, peaks_max = finds_peak(spectre_file, total_extrema, peaks_min, peaks_max = finds_peak(lambdas, smoothed_intensities,
min_peak_prominence=prominence) min_peak_prominence=prominence,
plot=False)
thickness_minmax = thickness_from_minmax(lambdas, thickness_minmax = thickness_from_minmax(lambdas,
smoothed_intensities, smoothed_intensities,
@ -99,5 +132,6 @@ def check_SV1():
if __name__ == '__main__': if __name__ == '__main__':
check_basic() #check_basic()
check_SV1() #check_SV1()
play()

View file

@ -15,13 +15,23 @@ plt.rcParams.update({
from .io import load_spectrum from .io import load_spectrum
from .fft import * from .fft import *
from .scheludko import *
from .minmax import * from .minmax import *
def plot_spectrum(lambdas, intensities, title=''):
plt.figure(figsize=(10, 6),dpi =600)
plt.plot(lambdas, intensities, 'o-', markersize=2)
plt.xlabel(r'$\lambda$ (nm)')
plt.ylabel(r'$I^*$')
plt.title(title)
plt.tight_layout()
plt.show()
def plot_xy(file_path, plot=True): def plot_xy(file_path, plot=True):
try: try:
@ -62,40 +72,26 @@ def finds_peak(lambdas, intensities, min_peak_prominence, min_peak_distance=10,
Distance minimale entre les pics. Distance minimale entre les pics.
""" """
smoothed_intensities = intensities
peaks_max, _ = find_peaks(intensities, prominence=min_peak_prominence, distance=min_peak_distance)
peaks_min, _ = find_peaks(-intensities, prominence=min_peak_prominence, distance=min_peak_distance)
# Trouver les maxima et minima sur le signal lissé
peaks_max, _ = find_peaks(smoothed_intensities, prominence=min_peak_prominence, distance=min_peak_distance)
peaks_min, _ = find_peaks(-smoothed_intensities, prominence=min_peak_prominence, distance=min_peak_distance)
if plot: if plot:
plt.figure(figsize=(10, 6),dpi =600) plt.figure(figsize=(10, 6),dpi =600)
plt.plot(lambdas, smoothed_intensities, 'o-', markersize=2, label="Smoothed data") plt.plot(lambdas, intensities, 'o-', markersize=2, label="Smoothed data")
plt.plot(lambdas[peaks_max], smoothed_intensities[peaks_max], 'ro') plt.plot(lambdas[peaks_max], intensities[peaks_max], 'ro')
plt.plot(lambdas[peaks_min], smoothed_intensities[peaks_min], 'ro') plt.plot(lambdas[peaks_min], intensities[peaks_min], 'ro')
plt.xlabel(r'$\lambda$ (nm)') plt.xlabel(r'$\lambda$ (nm)')
plt.ylabel(r'$I^*$') plt.ylabel(r'$I^*$')
plt.legend() plt.legend()
plt.tight_layout() plt.tight_layout()
plt.show() plt.show()
# Nombre total dextremums
total_extrema = len(peaks_max) + len(peaks_min)
if total_extrema >= 15:
print('Number of extrema', total_extrema,'.')
print('FFT method')
if total_extrema <= 15 and total_extrema > 4:
print('Number of extrema', total_extrema,'.')
print('OOSpectro method')
if total_extrema <= 4:
print('Number of extrema', total_extrema,'.')
print('Scheludko method')
return total_extrema, peaks_min, peaks_max
return peaks_min, peaks_max

View file

@ -3,10 +3,10 @@ import os.path
from .analysis import * from .analysis import *
from .io import load_spectrum from .io import load_spectrum
def auto(DATA_FOLDER, FILE_NAME, plot=None): def auto(spectrum_file, plot=None):
spectre_file = os.path.join(DATA_FOLDER, FILE_NAME) spectre_file = spectrum_file
##### Affichage du spectre brut et récupération des Intesités brutes##### ##### Affichage du spectre brut et récupération des Intesités brutes#####
@ -32,17 +32,20 @@ def auto(DATA_FOLDER, FILE_NAME, plot=None):
prominence = 0.03 prominence = 0.03
##### Find Peak ##### ##### Find Peak #####
total_extrema, peaks_min, peaks_max = finds_peak(lambdas, smoothed_intensities, peaks_min, peaks_max = finds_peak(lambdas, smoothed_intensities,
min_peak_prominence=prominence, min_peak_prominence=prominence,
plot=plot) plot=False)
##### Epaisseur selon la methode ##### ##### Epaisseur selon la methode #####
#thickness_FFT = thickness_from_fft(lambdas,smoothed_intensities,refractive_index=1.33) #thickness_FFT = thickness_from_fft(lambdas,smoothed_intensities,refractive_index=1.33)
total_extrema = len(peaks_max) + len(peaks_min)
if total_extrema > 15 and total_extrema > 4: if total_extrema > 15 and total_extrema > 4:
print('Apply method FFT') print('Apply method FFT')
thickness_FFT = thickness_from_fft(lambdas,smoothed_intensities, thickness_FFT = thickness_from_fft(lambdas, smoothed_intensities,
refractive_index=indice, refractive_index=indice,
plot=plot) plot=plot)
thickness = thickness_FFT.thickness thickness = thickness_FFT.thickness
@ -51,7 +54,7 @@ def auto(DATA_FOLDER, FILE_NAME, plot=None):
if total_extrema <= 15 and total_extrema > 4: if total_extrema <= 15 and total_extrema > 4:
print('Apply method minmax') print('Apply method minmax')
thickness_minmax = thickness_from_minmax(lambdas,smoothed_intensities, thickness_minmax = thickness_from_minmax(lambdas, smoothed_intensities,
refractive_index=indice, refractive_index=indice,
min_peak_prominence=prominence, min_peak_prominence=prominence,
plot=plot) plot=plot)
@ -61,8 +64,8 @@ def auto(DATA_FOLDER, FILE_NAME, plot=None):
if total_extrema <= 4 and total_extrema >= 2: #& 2peak minimum: if total_extrema <= 4 and total_extrema >= 2: #& 2peak minimum:
print('Apply method Scheludko') print('Apply method Scheludko')
thickness = thickness_from_scheludko(lambdas, smoothed_intensities, thickness = thickness_from_scheludko(lambdas, smoothed_intensities,
peaks_min, peaks_max,
refractive_index=indice, refractive_index=indice,
min_peak_prominence=prominence,
plot=plot) plot=plot)
print(f'thickness: {thickness:.2f} nm') print(f'thickness: {thickness:.2f} nm')
@ -70,8 +73,8 @@ def auto(DATA_FOLDER, FILE_NAME, plot=None):
print('Apply method ordre0') print('Apply method ordre0')
thickness = thickness_for_order0(lambdas, smoothed_intensities, thickness = thickness_for_order0(lambdas, smoothed_intensities,
peaks_min, peaks_max,
refractive_index=indice, refractive_index=indice,
min_peak_prominence=prominence,
plot=plot) plot=plot)
print(f'thickness: {thickness:.2f} nm') print(f'thickness: {thickness:.2f} nm')

View file

@ -1,6 +1,6 @@
import numpy as np import numpy as np
from .io import load_spectrum
from scipy.optimize import curve_fit from scipy.optimize import curve_fit
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
@ -12,8 +12,9 @@ plt.rcParams.update({
'legend.fontsize': 23, 'legend.fontsize': 23,
}) })
from .io import load_spectrum
from .utils import OptimizeResult from .utils import OptimizeResult
from .analysis import finds_peak
def thickness_scheludko_at_order(wavelengths, def thickness_scheludko_at_order(wavelengths,
intensity, intensity,
@ -114,9 +115,8 @@ def Delta_fit(xdata, thickness, interference_order):
def thickness_from_scheludko(lambdas, def thickness_from_scheludko(lambdas,
smoothed_intensities, smoothed_intensities,
peaks_min,
peaks_max,
refractive_index, refractive_index,
min_peak_prominence,
plot=None): plot=None):
""" """
@ -129,10 +129,6 @@ def thickness_from_scheludko(lambdas,
DESCRIPTION. DESCRIPTION.
smoothed_intensities : TYPE smoothed_intensities : TYPE
DESCRIPTION. DESCRIPTION.
peaks_min : TYPE
DESCRIPTION.
peaks_max : TYPE
DESCRIPTION.
refractive_index : TYPE refractive_index : TYPE
DESCRIPTION. DESCRIPTION.
plot : TYPE, optional plot : TYPE, optional
@ -144,9 +140,13 @@ def thickness_from_scheludko(lambdas,
DESCRIPTION. DESCRIPTION.
""" """
max_tested_order = 12
r_index = refractive_index r_index = refractive_index
peaks_min, peaks_max = finds_peak(lambdas, smoothed_intensities,
min_peak_prominence=min_peak_prominence,
plot=False)
lambda_min = lambdas[peaks_min[-1]] lambda_min = lambdas[peaks_min[-1]]
lambda_max = lambdas[peaks_max[-1]] lambda_max = lambdas[peaks_max[-1]]
@ -169,11 +169,12 @@ def thickness_from_scheludko(lambdas,
plt.ylabel(r'$h$ ($\mathrm{{nm}}$)') plt.ylabel(r'$h$ ($\mathrm{{nm}}$)')
plt.xlabel(r'$\lambda$ ($ \mathrm{nm} $)') plt.xlabel(r'$\lambda$ ($ \mathrm{nm} $)')
for m in range(0, 9):
for m in range(0, max_tested_order+1):
h_values = thickness_scheludko_at_order(lambdas_masked, intensities_masked, m, r_index_masked) h_values = thickness_scheludko_at_order(lambdas_masked, intensities_masked, m, r_index_masked)
if plot: if plot:
plt.plot(lambdas_masked, h_values,'.', markersize =3, label=f"Épaisseur du film (Scheludko, m={m})") plt.plot(lambdas_masked, h_values,'.', markersize=3, label=f"Épaisseur du film (Scheludko, m={m})")
ecart = np.max(h_values)-np.min(h_values) ecart = np.max(h_values)-np.min(h_values)
print(f"Écart pour m={m} : {ecart:.3f} nm") print(f"Écart pour m={m} : {ecart:.3f} nm")
@ -213,15 +214,20 @@ def thickness_from_scheludko(lambdas,
def thickness_for_order0(lambdas, def thickness_for_order0(lambdas,
smoothed_intensities, smoothed_intensities,
peaks_min,
peaks_max,
refractive_index, refractive_index,
min_peak_prominence,
plot=None): plot=None):
File_I_min = 'tests/spectre_trou/000043641.xy' File_I_min = 'tests/spectre_trou/000043641.xy'
r_index = refractive_index r_index = refractive_index
peaks_min, peaks_max = finds_peak(lambdas, smoothed_intensities,
min_peak_prominence=min_peak_prominence,
plot=False)
lambdas_I_min, intensities_I_min = load_spectrum(File_I_min, lambda_min=450) lambdas_I_min, intensities_I_min = load_spectrum(File_I_min, lambda_min=450)

View file

@ -29,10 +29,6 @@ def test_minmax(spectrum_path, expected):
indice = 1.324188 + 3102.060378 / (lambdas**2) indice = 1.324188 + 3102.060378 / (lambdas**2)
prominence = 0.02 prominence = 0.02
total_extrema, peaks_min, peaks_max = finds_peak(lambdas, smoothed_intensities,
min_peak_prominence=prominence,
plot=False)
thickness_minmax = thickness_from_minmax(lambdas, thickness_minmax = thickness_from_minmax(lambdas,
smoothed_intensities, smoothed_intensities,
refractive_index=indice, refractive_index=indice,

View file

@ -6,7 +6,6 @@ import pytest
from optifik.scheludko import thickness_from_scheludko from optifik.scheludko import thickness_from_scheludko
from optifik.io import load_spectrum from optifik.io import load_spectrum
from optifik.analysis import smooth_intensities from optifik.analysis import smooth_intensities
from optifik.analysis import finds_peak
import yaml import yaml
@ -22,22 +21,18 @@ def load():
@pytest.mark.parametrize("spectrum_path, expected", load()) @pytest.mark.parametrize("spectrum_path, expected", load())
def test_minmax(spectrum_path, expected): def test_SV2o5(spectrum_path, expected):
lambdas, raw_intensities = load_spectrum(spectrum_path, lambda_min=450) lambdas, raw_intensities = load_spectrum(spectrum_path, lambda_min=450)
smoothed_intensities = smooth_intensities(raw_intensities) smoothed_intensities = smooth_intensities(raw_intensities)
refractive_index = 1.324188 + 3102.060378 / (lambdas**2) refractive_index = 1.324188 + 3102.060378 / (lambdas**2)
prominence = 0.02 prominence = 0.02
total_extrema, peaks_min, peaks_max = finds_peak(lambdas, smoothed_intensities,
thickness_scheludko = thickness_from_scheludko(lambdas, smoothed_intensities,
refractive_index=refractive_index,
min_peak_prominence=prominence, min_peak_prominence=prominence,
plot=False) plot=False)
thickness_scheludko = thickness_from_scheludko(lambdas,
smoothed_intensities,
peaks_min,
peaks_max,
refractive_index)
result = thickness_scheludko.thickness result = thickness_scheludko.thickness
assert_allclose(result, expected, rtol=1e-1) assert_allclose(result, expected, rtol=1e-1)

View file

@ -3,13 +3,12 @@ import numpy as np
from numpy.testing import assert_allclose from numpy.testing import assert_allclose
import pytest import pytest
from optifik.analysis import thickness_from_fft from optifik.fft import thickness_from_fft
from optifik.analysis import thickness_from_minmax from optifik.minmax import thickness_from_minmax
from optifik.analysis import thickness_from_scheludko from optifik.scheludko import thickness_from_scheludko
from optifik.analysis import thickness_for_order0 from optifik.scheludko import thickness_for_order0
from optifik.analysis import smooth_intensities from optifik.analysis import smooth_intensities
from optifik.analysis import Prominence_from_fft from optifik.analysis import Prominence_from_fft
from optifik.analysis import finds_peak
from optifik.io import load_spectrum from optifik.io import load_spectrum
@ -69,14 +68,10 @@ def test_scheludko_4peaks():
prominence = Prominence_from_fft(lambdas=lambdas, intensities=smoothed_intensities, refractive_index=indice, plot=False) prominence = Prominence_from_fft(lambdas=lambdas, intensities=smoothed_intensities, refractive_index=indice, plot=False)
total_extrema, peaks_min, peaks_max = finds_peak(lambdas, smoothed_intensities,
min_peak_prominence=prominence,
plot=False)
result = thickness_from_scheludko(lambdas, smoothed_intensities, result = thickness_from_scheludko(lambdas, smoothed_intensities,
peaks_min, peaks_max,
refractive_index=indice, refractive_index=indice,
min_peak_prominence=prominence,
plot=False) plot=False)
assert_allclose(result.thickness, expected, rtol=1e-1) assert_allclose(result.thickness, expected, rtol=1e-1)
@ -95,13 +90,9 @@ def test_scheludko_2peaks():
prominence = 0.03 prominence = 0.03
total_extrema, peaks_min, peaks_max = finds_peak(lambdas, smoothed_intensities,
min_peak_prominence=prominence,
plot=False)
result = thickness_from_scheludko(lambdas, smoothed_intensities, result = thickness_from_scheludko(lambdas, smoothed_intensities,
peaks_min, peaks_max,
refractive_index=indice, refractive_index=indice,
min_peak_prominence=prominence,
plot=False) plot=False)
assert_allclose(result.thickness, expected, rtol=1e-1) assert_allclose(result.thickness, expected, rtol=1e-1)
@ -122,13 +113,10 @@ def test_order0():
prominence = 0.03 prominence = 0.03
total_extrema, peaks_min, peaks_max = finds_peak(lambdas, smoothed_intensities,
min_peak_prominence=prominence,
plot=False)
result = thickness_for_order0(lambdas, smoothed_intensities, result = thickness_for_order0(lambdas, smoothed_intensities,
peaks_min, peaks_max,
refractive_index=indice, refractive_index=indice,
min_peak_prominence=prominence,
plot=False) plot=False)
assert_allclose(result.thickness, expected, rtol=1e-1) assert_allclose(result.thickness, expected, rtol=1e-1)