[Python] Modelling a large dataset using a Lorentzian function

Discussão em 'Python' iniciado por Stack, Fevereiro 21, 2025.

  1. Stack

    Stack Membro Participativo

    I'm trying to model a large dataset using the Lorentzian function

    [​IMG]

    So far, I've been unable to do so, the dataset I have, when seen on a basic pyplot, has multiple maxima and minima. To fit them on a Lorentzian, I'm not sure if I need to be plotting them by splicing the data around each minima or if I need to be entering the data as a whole. Regardless I've posted the code here below and the output underneath it. I don't have a lot of experience in programming, so the code is definitely poorly structured.

    A bit of info, the data I had needed to be scaled up by a factor found in my experiment, and I used a Savitzky-Golay filter to smoothen the data. I am essentially only working with minimas.

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    from scipy.optimize import curve_fit
    from scipy.signal import savgol_filter, find_peaks

    #Lorentzian
    def lorentzian(x, u, T, A):
    return (A/np.pi) * ( (T/2) / ((x -u) **2 + (T/2)**2) )

    ## Load data
    file_path = "Franck-Hertz/Mercury/VaDecreasing.csv"
    data = pd.read_csv(file_path)

    #parameters
    x_data = data.Pot1
    y_data = data.Pot2

    # Filter
    pot1Smooth = savgol_filter(x_data, window_length = 21, polyorder =2)
    pot2Smooth = savgol_filter(y_data, window_length=21, polyorder=2)
    pot2Smooth_invert = -pot2Smooth
    peaks, properties = find_peaks(pot2Smooth_invert, prominence=0.05, distance = 10)

    x_minima = []
    for i in peaks:
    x_minima.append(x_data)


    #Scaling
    x = [57.2, 51.4, 46.5, 41.0, 36.3, 31.2, 26.2, 21.0, 16.20, 11.30, 6.8]
    x.sort()
    Ratio = np.mean(x)/ np.mean(x_minima)
    newPot1 = Ratio * pot1Smooth

    #new Minima
    minimax = newPot1[peaks]
    minimax.sort()
    minimayb = pot2Smooth[peaks]
    minimayb.sort()
    minimay = np.delete(minimayb, [5,13])
    minima = np.delete(minimax,[5,13])
    print(minima)

    #temp fit
    plt.plot(newPot1, pot2Smooth)
    plt.scatter(minima,minimay)
    #curve fitting
    uGuess = []
    TGuess = 2.0
    AGuess = 1.0
    for i in range(len(minima)):
    uGuess = minima
    pGuess = [ uGuess, TGuess, AGuess ]
    popt, pcov = curve_fit(lorentzian, newPot1, pot2Smooth, p0 =pGuess)
    u, T = popt[0], popt[1]
    print(u, T)


    Out
    [​IMG]

    Continue reading...

Compartilhe esta Página