yay, band detection seems to work ok

This commit is contained in:
Valentin Boettcher 2023-03-20 19:30:56 -04:00
parent 90ed980f12
commit 65f4fc56cc

View file

@ -6,6 +6,7 @@ from scipy import signal
from skimage.transform import resize from skimage.transform import resize
from skimage.filters import hessian from skimage.filters import hessian
from skimage.morphology import skeletonize from skimage.morphology import skeletonize
from itertools import chain
def load_data(data_file: str) -> np.ndarray: def load_data(data_file: str) -> np.ndarray:
@ -92,6 +93,9 @@ def optimize():
d = load_data("../data/t_t_0.5_c_2.0_d_0.0_pc_1.0_pd_1.0.txt") d = load_data("../data/t_t_0.5_c_2.0_d_0.0_pc_1.0_pd_1.0.txt")
d = load_data("../data/t_t_1.0_c_0.75_d_0.2_pc_1.0_pd_1.0.txt") d = load_data("../data/t_t_1.0_c_0.75_d_0.2_pc_1.0_pd_1.0.txt")
plt.plot()
return
def target(x): def target(x):
a, c, dd = x a, c, dd = x
test = smear_band( test = smear_band(
@ -151,3 +155,84 @@ def get_weight(data, radius, k, e, weight, depth):
weight += get_weight(data, radius, k + 1, next_e, weight, depth - 1) weight += get_weight(data, radius, k + 1, next_e, weight, depth - 1)
return weight return weight
def lorentzian(x, x0, γ):
return γ**2 / ((x - x0) ** 2 + γ**2)
def double_lorentzian(x, x0_1, x0_2, γ, r=1):
return lorentzian(x, x0_1, γ) + r * lorentzian(x, x0_2, γ)
def refine_band_fit(k, e0, data):
pass
def detect_bands_fixed_k(k, data, γ, last_separation=0, min_height=0.5):
col = data[:, k].copy()
col -= col.min()
col /= col.max()
e_axis = np.arange(col.size)
guesses = np.array(sc.signal.find_peaks(col, distance=2, height=min_height)[0])
means = guesses[:, None] + guesses[None, :]
guess_i_1, guess_i_2 = np.unravel_index(
np.argmin(abs(means - col.size)), means.shape
)
guess_1, guess_2 = np.sort((guesses[guess_i_1], guesses[guess_i_2]))
if last_separation > 0 and abs(guess_2 - guess_1) < last_separation / 4:
guess_2 = col.size - guess_1
col /= col[guess_1]
(e_1, e_2, γ, _), cov = sc.optimize.curve_fit(
double_lorentzian,
e_axis,
col,
(guess_1, guess_2, γ, 1),
bounds=(
(max(guess_1 - γ, 0), max(guess_2 - γ, 0), 0.5, 0.3),
(min(guess_1 + γ, col.size), min(guess_2 + γ, col.size), col.size, 1 / 0.3),
),
)
e_1, e_2 = np.sort((e_1, e_2))
# es = np.linspace(0, col.size, 1000)
# plt.plot(col)
# plt.plot(es, double_lorentzian(es, e_1, e_2, γ, _))
σ_1, σ_2, _, _ = np.sqrt(np.diag(cov))
return e_1, e_2, σ_1, σ_2
def detect_bands(data, γ=20, min_height=0.5):
bands = []
e_1, e_2 = 0, 0
for k in range(data.shape[1]):
e_1, e_2, *σ = detect_bands_fixed_k(
k, data, γ, last_separation=abs(e_2 - e_1), min_height=min_height
)
bands.append((e_1, e_2, *σ))
return np.array(bands)
def plot_data_with_bands(data, bands):
plt.matshow(data)
ks = np.arange(data.shape[1])
plt.errorbar(ks, bands[:, 0], yerr=bands[:, 2])
plt.errorbar(ks, bands[:, 1], yerr=bands[:, 3])
# return sc.optimize.curve_fit(double_lorentzian, e_axis, col, (0, 10, 0, 3))
def fit_to_bands(bands):