Gauss-Fit Problems

48 Views Asked by At

I have this .txt file and I need to fit a Gauss Curve to every peak to get a spectrum. But I do not know why my code is not working. Any help?

I tried to fit a Gauss Curve to my data sets by defining it and using the data from the .txt file. Sadly that did not work.

2

There are 2 best solutions below

1
ArrowRise On

Maybe you want to get this plot : enter image description here

You can try this simple code :

import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv("data.txt", sep="\t", names=["first_col", "sec_col"], header=None,)
df = df.iloc[:700]

ax = df.plot(x='first_col', y='sec_col')
plt.savefig('plot.png', format='png')

With "data.txt" the file you linked.

I croped the data to 700 because after that it's only zeros.

0
AstroKnop On

In the end it is supposed to look like this: Example fit

My current code looks like this:

import numpy as np 
import matplotlib.pyplot as plt 
from scipy.optimize import curve_fit 
from scipy.stats import poisson

# Gaußsche Funktion für die Anpassung

# Updated Gauss function
def gauss(x, *params):
    a, x0, sigma = params
    return a * np.exp(-(x - x0)**2 / (2 * sigma**2))


# Poisson-Verteilungsfunktion
def poisson_distribution(k, mu, scale):
    return poisson.pmf(k, mu) * scale

# Funktion zum Einlesen der Daten aus einer Textdatei
def readData(filename):
    data = np.loadtxt(filename, delimiter='\t', skiprows=1)  # Die erste Zeile wird übersprungen
    x_data = data[:, 0]
    y_data = data[:, 1]
    return x_data, y_data

# Dateiname für die Datendatei
filename = '4.3-56V.txt'  # Hier Dateinamen anpassen

# Daten aus der Datei lesen
x_data, y_data = readData(filename)

# Anzahl der Peaks (angepasst an deine Daten)
num_peaks = 7

# Schätzungen für die Anfangsparameter der Gauß-Funktionen
initial_guesses = []

# Angenommen, du kennst die X-Positionen der sieben Peaks
peak_positions = [0, 100, 200, 300, 400, 500, 600]  # Beispielwerte, ersetze sie durch deine Daten

# Breite des Peaks (kann je nach Peak variieren)
peak_width = 50  # Beispielwert, anpassen an die tatsächliche Breite der Peaks

# Definiere x_min und x_max für jeden Peak
x_min = [pos - peak_width for pos in peak_positions]
x_max = [pos + peak_width for pos in peak_positions]



for i in range(num_peaks):
    # Schätzung der Amplitude (maximale Höhe) für jeden Peak
    a_guess = np.max(y_data[(x_data >= x_min[i]) & (x_data <= x_max[i])])

    # Schätzung des Mittelwerts (Mittelwert) für jeden Peak
    x0_guess = x_data[np.argmax(y_data[(x_data >= x_min[i]) & (x_data <= x_max[i])])]

    # Schätzung der Standardabweichung für jeden Peak (kann konstant oder variabel sein)
    sigma_guess = 0.2  # Beispielwert, anpassen an die Breite der Peaks

    # Anfangsschätzungen in die Parameterliste aufnehmen
    initial_guesses.extend([a_guess, x0_guess, sigma_guess])

# initial_guesses ist jetzt eine Liste von Schätzungen für alle sieben Peaks


# Anpassung der Gauß-Funktionen an die Daten
fit_params, _ = curve_fit(gauss, x_data, y_data, p0=initial_guesses)

# Anpassung der Poisson-Verteilung an die Höhen der Peaks
poisson_params, _ = curve_fit(poisson_distribution, np.arange(num_peaks), y_data)

# Plot der Daten und der angepassten Gauß-Funktionen
plt.figure(figsize=(8, 6))
plt.scatter(x_data, y_data, label='Daten', marker='o', color='b')

for i in range(num_peaks):
    start_idx = i * 3
    end_idx = (i + 1) * 3
    params = fit_params[start_idx:end_idx]
    plt.plot(x_data, gauss(x_data, *params), label=f'Peak {i+1}')

# Plot der Poisson-Verteilung für die Höhen der Peaks
poisson_x = np.arange(num_peaks)
poisson_y = poisson_distribution(poisson_x, *poisson_params)
plt.bar(poisson_x, poisson_y, alpha=0.5, width=0.4, label='Poisson Verteilung', color='r')

plt.xlabel('X-Achse')
plt.ylabel('Y-Achse')
plt.legend()
plt.show()