def plotMiddle(self): """Function to plot the graph on the Middle Canvas""" self.ui.factorPlot.canvas.ax.cla() self.ui.factorPlot.canvas.ax.grid(True) self.elementList = Utility.molToElemList(self.molecule) self.elementParameters = Utility.read_parameters( self.elementList, "./elementParameters.txt") if self.ui.formFactorCheck.isChecked(): # print("test fe check") self.Q, self.I_Q, self.Qbkg, self.Ibkg_Q = UtilityAnalysis.check_data_length( self.Q, self.I_Q, self.Qbkg, self.Ibkg_Q, self.ui.minQ.value(), self.ui.maxQ.value()) self.fe_Q, self.Ztot = MainFunctions.calc_eeff( self.elementList, self.Q, self.elementParameters) self.ui.factorPlot.canvas.ax.plot(self.Q, self.fe_Q, label=r"$f_e(Q)$") self.ui.factorPlot.canvas.ax.legend() self.ui.factorPlot.canvas.draw() # else: # # print("test unchecked") # self.ui.factorPlot.canvas.ax.lines.pop(0) # self.ui.factorPlot.canvas.draw() if self.ui.SQCheck.isChecked(): S_Q = self.SQ() self.ui.factorPlot.canvas.ax.plot(self.Q, S_Q, label=r"$S(Q)$") self.ui.factorPlot.canvas.ax.legend() self.ui.factorPlot.canvas.draw() if self.ui.incohCheck.isChecked(): self.Iincoh_Q = MainFunctions.calc_Iincoh(self.elementList, self.Q, self.elementParameters) self.ui.factorPlot.canvas.ax.plot(self.Q, self.Iincoh_Q, label=r"$I_{incoh}(Q)$") self.ui.factorPlot.canvas.ax.legend() self.ui.factorPlot.canvas.draw() if self.ui.QiQCheck.isChecked(): self.Sinf = MainFunctions.calc_Sinf(self.elementList, self.fe_Q, self.Q, self.Ztot, self.elementParameters) self.i_Q = MainFunctions.calc_iQ(S_Q, self.Sinf) # self.r = MainFunctions.calc_r(self.Q) Qi_Q = self.Q * self.i_Q self.ui.factorPlot.canvas.ax.plot(self.Q, Qi_Q, label=r"$Qi(Q)$") self.ui.factorPlot.canvas.ax.legend() self.ui.factorPlot.canvas.draw()
def calc_intraComponentFZ(Q, fe_Q, Ztot, QmaxIntegrate, maxQ, elementList, element, \ x, y, z, elementParameters, damping_factor, aff_mean_squared): """Function to calculate the intra-molecular components. Parameters ---------- Q : numpy array momentum transfer (nm^-1) fe_Q : numpy array effective electric form factor Ztot : int total Z number QmaxIntegrate : float maximum Q value for the intagrations maxQ : float maximum Q value elementList : dictionary("element": multiplicity) chemical elements of the sample with their multiplicity element : string chemical element multiplicity : int chemical element multiplicity element : string array array with the elements in the xyz_file x, y, z : float array atomic coordinate in the xyz_file (nm) elementParameters : dictionary("element": parameters) chemical elements of the sample with their parameters element : string chemical element parameters : list list of the parameters (Z, a1, b1, a2, b2, a3, b3, a4, b4, c, M, K, L) damping_factor : float damp factor Returns ------- r : numpy array atomic distance (nm) Fintra_r : numpy array intramolecular contribution of F(r) """ iintra_Q = calc_iintraFZ(Q, QmaxIntegrate, maxQ, elementList, element, x, y, z, elementParameters, aff_mean_squared) iintradamp_Q = UtilityAnalysis.calc_iintradamp(iintra_Q, Q, QmaxIntegrate, damping_factor) r = MainFunctions.calc_r(Q) Fintra_r = MainFunctions.calc_Fr(r, Q[Q <= QmaxIntegrate], iintradamp_Q[Q <= QmaxIntegrate]) return (r, iintradamp_Q, Fintra_r)
def Fr(self): """Function to calculte and plot F(r)""" self.i_Q = MainFunctions.calc_iQ(self.SsmoothDamp_Q, self.Sinf) # self.r = MainFunctions.calc_r(self.Q) Qi_Q = self.Q * self.i_Q self.r, self.F_r = MainFunctions.calc_Fr( self.Q[self.Q <= self.ui.QmaxIntegrate.value()], Qi_Q[self.Q <= self.ui.QmaxIntegrate.value()]) # self.ui.distfuncPlot.canvas.ax.plot(self.r, self.F_r, "b", label=r"$F(r)$") # self.ui.distfuncPlot.canvas.ax.legend() # self.ui.distfuncPlot.canvas.draw() return (self.r, self.F_r)
def S_QCalculation(Q, I_Q, Ibkg_Q, scaleFactor, J_Q, Sinf, fe_Q, Ztot, density, Iincoh_Q, minQ, QmaxIntegrate, maxQ, smoothFactor, dampFactor): """Function for the S(Q) calculation. """ Isample_Q = MainFunctions.calc_IsampleQ(I_Q, scaleFactor, Ibkg_Q) alpha = MainFunctions.calc_alpha(J_Q[Q <= QmaxIntegrate], Sinf, Q[Q <= QmaxIntegrate], Isample_Q[Q <= QmaxIntegrate], fe_Q[Q <= QmaxIntegrate], Ztot, density) Icoh_Q = MainFunctions.calc_Icoh(alpha, Isample_Q, Iincoh_Q) S_Q = MainFunctions.calc_SQ(Icoh_Q, Ztot, fe_Q, Sinf, Q, minQ, QmaxIntegrate, maxQ) Ssmooth_Q = UtilityAnalysis.calc_SQsmoothing(Q, S_Q, Sinf, smoothFactor, minQ, QmaxIntegrate, maxQ) SsmoothDamp_Q = UtilityAnalysis.calc_SQdamp(Ssmooth_Q, Q, Sinf, QmaxIntegrate, dampFactor) return SsmoothDamp_Q
def FitRemoveGofRPeaks(Q, SsmoothDamp_Q, Sinf, QmaxIntegrate, Fintra_r, iterations, rmin, density, J_Q, Ztot): """Equivalent of Igor function """ Qi_Q = Q*MainFunctions.calc_iQ(SsmoothDamp_Q, Sinf) r, GR = calc_FFT_QiQ(Q, Qi_Q, QmaxIntegrate) # _, Fintra_r = UtilityAnalysis.rebinning(rintra, Fintra_r, np.amin(Fintra_r), # np.amax(Fintra_r), len(GR)) # QiQ1 = np.zeros(len(SsmoothDamp_Q)) # idx, _ = UtilityAnalysis.find_nearest(Qi_Q, QmaxIntegrate) # QiQ1[Q<QmaxIntegrate] = Qi_Q[Q<QmaxIntegrate] # QiQ1[0] = 0.0 QiQ[Q>=QmaxIntegrate] = 0.0 QiQ[0] = 0.0 # GR1 = GR DelG = np.zeros(len(GR)) Rnn = rmin DelG[r<Rnn] = GR[r<Rnn]-(Fintra_r[r<Rnn]-4*np.pi*r[r<Rnn]*density) GRIdealSmallR = Fintra_r-4*np.pi*r*density for i in range(iterations): Q1, QiQCorr = calc_IFFT_Fr(r, DelG) mask = np.where((Q1>0.0) & (Q1<QmaxIntegrate)) QiQ[mask] = QiQ[mask] - (QiQ[mask] / (Q1[mask] *(Sinf + J_Q[:len(Q1[mask])]/Ztot**2)) + 1) * QiQCorr[mask] r, GR = calc_FFT_QiQ(Q1, QiQ, QmaxIntegrate) DelG = np.zeros(len(GR)) DelG[r<Rnn] = GR[r<Rnn]-GRIdealSmallR[r<Rnn] _, rmin = UtilityAnalysis.find_nearest(r, 0.95*Rnn) Rnn = 0.99*r[np.where(GR==np.amin(GR[r>=rmin]))[0][0]] # DTemp = DelG # DTemp = DTemp**2 # chi2 = np.mean(DTemp) DelG = DelG**2 chi2 = np.mean(DelG) return chi2
def calc_optimize_FrFZ(iteration, F_r, Fintra_r, rho0, i_Q, Q, Iincoh_Q, r, rmin): """Function to calculate the F(r) optimization (eq 47, 48, 49). Parameters ---------- iteration : int number of iterations F_r : numpy array F(r) rho0 : float atomic density i_Q : numpy array i(Q) Q : numpy array momentum transfer (nm^-1) Sinf : float value of S(Q) for Q->inf J_Q : numpy array J(Q) r : numpy array atomic distance (nm) rmin : float r cut-off value (nm) plot_iter : string flag to plot the F(r) iterations Returns ------- F_r : numpy array optimazed F(r) deltaF_r : numpy array difference between the last F(r) and its theoretical value """ for i in range(iteration): deltaF_r = Optimization.calc_deltaFr(F_r, Fintra_r, r, rho0) i_Q = calc_iQiFZ(i_Q, Q, Iincoh_Q, deltaF_r, r, rmin) i_Q[0] = 0.0 F_r = MainFunctions.calc_Fr(r, Q, i_Q) return (F_r, deltaF_r)
def calc_aff_mean_squared(numAtoms, elementList, Q, elementParameters): """Function to calculate the mean squared effective electron Form Factor, <f>^2 (eq. FZ-5). Parameters ---------- numAtoms : int number of atoms in the molecule elementList : dictionary("element": multiplicity) chemical elements of the sample with their multiplicity element : string chemical element multiplicity : int chemical element multiplicity Q : numpy array momentum transfer (nm^-1) elementParameters : dictionary("element": parameters) chemical elements of the sample with their parameters element : string chemical element parameters : list list of the parameters (Z, a1, b1, a2, b2, a3, b3, a4, b4, c, M, K, L) Returns ------- aff_mean_squared : numpy array squared of the mean form factor: <f>^2 """ aff_mean_squared = np.zeros(Q.size) for element, multiplicity in elementList.items(): aff_mean_squared += multiplicity * MainFunctions.calc_aff( element, Q, elementParameters) aff_mean_squared /= numAtoms aff_mean_squared = aff_mean_squared**2 return aff_mean_squared
def calc_FFT_QiQ(Q, Qi_Q, QmaxIntegrate): """Function to calculate the FFT following the Igor Pro procedure. I do not agree with this procedure, but I follow it to compare my results with Igor Pro's ones. Parameters ---------- Q : numpy array momentum transfer (nm^-1) Qi_Q : numpy array Q*i(Q) QmaxIntegrate : float maximum Q value for the integrations Returns ------- r : numpy array atomic distance (nm) F_r : numpy array F(r) """ pMax, elem = UtilityAnalysis.find_nearest(Q, QmaxIntegrate) NumPoints = 2*2*2**math.ceil(math.log(5*(pMax+1))/math.log(2)) DelR = 2*np.pi/(np.mean(np.diff(Q))*NumPoints) Qi_Q = Utility.resize_zero(Qi_Q[Q<=QmaxIntegrate], NumPoints) Qi_Q[pMax+1:] = 0.0 Q = np.arange(np.amin(Q), np.amin(Q)+np.mean(np.diff(Q))*NumPoints, np.mean(np.diff(Q))) r = MainFunctions.calc_r(Q) F_r = fftpack.fft(Qi_Q) F_r = F_r[np.where(r>=0.0)] F_r = -np.imag(F_r)*np.mean(np.diff(Q))*2/np.pi r = np.arange(0.0, 0.0+DelR*len(F_r), DelR) return (r, F_r)
def calc_optimize_Fr(iterations, F_r, Fintra_r, density, i_Q, Q, Sinf, J_Q, r, rmin, plot_iter): """Function to calculate the F(r) optimization (eq 47, 48, 49). Parameters ---------- iterations : int number of iterations F_r : numpy array F(r) density : float atomic density i_Q : numpy array i(Q) Q : numpy array momentum transfer (nm^-1) Sinf : float value of S(Q) for Q->inf J_Q : numpy array J(Q) r : numpy array atomic distance (nm) rmin : float r cut-off value (nm) plot_iter : string flag to plot the F(r) iterations Returns ------- F_r : numpy array optimazed F(r) deltaF_r : numpy array difference between the last F(r) and its theoretical value """ # if plot_iter.lower() == "y": # plt.ion() # plt.figure("F_rIt") # plt.plot(r, F_r, label="F(r)") # plt.xlabel("r (nm)") # plt.ylabel("F(r)") # plt.legend() # plt.grid(True) for i in range(iterations): deltaF_r = calc_deltaFr(F_r, Fintra_r, r, density) i_Q[0] = 0.0 i_Q[1:] = calc_iQi(i_Q[1:], Q[1:], Sinf, J_Q[1:], deltaF_r, r, rmin) r, F_r = MainFunctions.calc_Fr(Q, Q * i_Q) # if plot_iter.lower() == "y": # j = i+1 # plt.figure("F_rIt") # plt.plot(r, F_r, label="%s iteration F(r)" %j) # plt.legend() # plt.draw() # time.sleep(1.0) # if plot_iter.lower() == "y": # plt.ioff() return (F_r, deltaF_r)
def OptimizeScale(Q, I_Q, Ibkg_Q, J_Q, Iincoh_Q, fe_Q, minQ, QmaxIntegrate, maxQ, Ztot, density, scaleFactor, Sinf, smoothingFactor, rmin, dampingFunction, Fintra_r, iterations, scaleStep, sth, s0th, mccFlag, thickness_sampling, phi_matrix): """Function for the scale factor optimization. Q : numpy array momentum transfer (nm^-1) I_Q : numpy array measured scattering intensity Ibkg_Q : numpy array background scattering intensity J_Q : numpy array J(Q) Iincoh_Q : numpy array incoherent scattering intensity fe_Q : numpy array effective electric form factor minQ : float minimum Q value QmaxIntegrate : float maximum Q value for the intagrations maxQ : float maximum Q value Ztot : int total Z number density : float average atomic density scaleFactor : float scale factor Sinf : float value of S(Q) for Q->inf smoothingFactor : float smoothing factor rmin : float r cut-off value (nm) dampingFunction : numpy array damping function Fintra_r : numpy array intramolecular contribution of F(r) iterations : int number of iterations scaleStep sth s0th MCC_flag """ numSample = 23 if mccFlag.lower() == "y": T_MCC_sth, T_MCC_corr_factor_bkg = Geometry.MCC_correction( sth, s0th, thickness_sampling, phi_matrix) # print(thickness_sampling) # plt.contour(phi_matrix) # plt.show() # x = np.linspace(0, len(T_MCC_sth), len(T_MCC_sth), endpoint=True) # _, T_MCC_sth = UtilityAnalysis.rebinning(x, T_MCC_sth, np.amin(T_MCC_sth), # np.amax(T_MCC_sth), len(I_Q)) # plt.plot(T_MCC_sth) # plt.show() I_Q = I_Q / T_MCC_sth Ibkg_Q = Ibkg_Q * T_MCC_corr_factor_bkg / (T_MCC_sth) flag = 0 # Loop for the range shifting while 1: # print(type(scaleFactor)) # print(type(scaleStep)) scaleArray = UtilityAnalysis.makeArrayLoop(scaleFactor, scaleStep) chi2Array = np.zeros(numSample) flag += 1 print("iter flag ", flag) for i in range(numSample): print("sample ", i, scaleArray[i]) # ------------------Kaplow method for scale-------------------- Isample_Q = MainFunctions.calc_IsampleQ(I_Q, scaleArray[i], Ibkg_Q) alpha = MainFunctions.calc_alpha(J_Q[Q <= QmaxIntegrate], Sinf, Q[Q <= QmaxIntegrate], Isample_Q[Q <= QmaxIntegrate], fe_Q[Q <= QmaxIntegrate], Ztot, density) Icoh_Q = MainFunctions.calc_Icoh(alpha, Isample_Q, Iincoh_Q) S_Q = MainFunctions.calc_SQ(Icoh_Q, Ztot, fe_Q, Sinf, Q, minQ, QmaxIntegrate, maxQ) Ssmooth_Q = UtilityAnalysis.calc_SQsmoothing( Q, S_Q, Sinf, smoothingFactor, minQ, QmaxIntegrate, maxQ) SsmoothDamp_Q = UtilityAnalysis.calc_SQdamp( Ssmooth_Q, Sinf, dampingFunction) i_Q = MainFunctions.calc_iQ(SsmoothDamp_Q, Sinf) Qi_Q = Q * i_Q r, F_r = MainFunctions.calc_Fr(Q[Q <= QmaxIntegrate], Qi_Q[Q <= QmaxIntegrate]) Fopt_r, deltaFopt_r = Optimization.calc_optimize_Fr( iterations, F_r, Fintra_r, density, i_Q[Q <= QmaxIntegrate], Q[Q <= QmaxIntegrate], Sinf, J_Q[Q <= QmaxIntegrate], r, rmin, "n") deltaFopt_r[np.where(r >= rmin)] = 0.0 # Igor version chi2Array[i] = np.mean(deltaFopt_r**2) # Igor version # Fth_r = Fintra_r - 4*np.pi*r*density # plt.plot(r, Fth_r) # plt.show() # print(Fth_r) # print(Fintra_r) # chi2Array[i] = simps(deltaFopt_r[np.where((r>0)&(r<rmin))]**2) # --------------------Range shifting selection -------------------- plt.scatter(scaleArray, chi2Array) plt.grid(True) plt.show() maxLimit = 10**5 if np.amax(chi2Array) >= maxLimit: scaleArray = scaleArray[0:np.argmax(chi2Array >= maxLimit)] chi2Array = chi2Array[0:np.argmax(chi2Array >= maxLimit)] if np.argmin(chi2Array) < 6: scaleFactor -= scaleStep * 10 if np.argmin(chi2Array) > 16: scaleFactor += scaleStep * 10 if (np.argmin(chi2Array) >= 6 and np.argmin(chi2Array) <= 16): break else: continue # ------------------------chi2 curve fit for scale------------------------- # plt.ioff() xFit, yFit, scaleFactor, chi2 = IgorFunctions.chi2Fit( scaleFactor, scaleArray, chi2Array) print("final scale factor", scaleFactor) plt.scatter(scaleArray, chi2Array) plt.plot(xFit, yFit) plt.grid(True) plt.show() return scaleFactor
def calc_iintraFZ(Q, QmaxIntegrate, maxQ, elementList, element, x, y, z, elementParameters, aff_mean_squared): """Function to calculate the intramolecular contribution of i(Q) (eq. 41). Parameters ---------- Q : numpy array momentum transfer (nm^-1) fe_Q : numpy array effective electric form factor Ztot : int total Z number QmaxIntegrate : float maximum Q value for the intagrations maxQ : float maximum Q value elementList : dictionary("element": multiplicity) chemical elements of the sample with their multiplicity element : string chemical element multiplicity : int chemical element multiplicity element : string array array with the elements in the xyz_file x, y, z : float array atomic coordinate in the xyz_file (nm) elementParameters : dictionary("element": parameters) chemical elements of the sample with their parameters element : string chemical element parameters : list list of the parameters (Z, a1, b1, a2, b2, a3, b3, a4, b4, c, M, K, L) Returns ------- iintra_Q : numpy array intramolecular contribution of i(Q) """ iintra_Q = np.zeros(Q.size) sinpq = np.zeros(Q.size) for ielem in range(len(element)): for jelem in range(len(element)): if ielem != jelem: # print(ielem, jelem) # print(type(element[ielem])) # print(element[ielem], elementList[element[ielem]], element[jelem], elementList[element[jelem]]) f_Qi = MainFunctions.calc_aff(element[ielem], Q, elementParameters) f_Qj = MainFunctions.calc_aff(element[jelem], Q, elementParameters) f_i = np.mean(elementList[element[ielem]] * f_Qi / 3) f_j = np.mean(elementList[element[jelem]] * f_Qj / 3) # f_i = np.mean(f_Qi) # f_j = np.mean(f_Qj) ff = f_i * f_j d = Utility.calc_distMol(x[ielem], y[ielem], z[ielem], x[jelem], y[jelem], z[jelem]) if d != 0.0: iintra_Q += ff * np.sin(d * Q) / (d * Q) iintra_Q[Q == 0.0] = ff iintra_Q[(Q > QmaxIntegrate) & (Q <= maxQ)] = 0.0 iintra_Q /= np.mean(aff_mean_squared) # iintra_Q /= 3 return iintra_Q
def Kaplow_method(Q, I_Q, Ibkg_Q, J_Q, fe_Q, Iincoh_Q, Sinf, Ztot, scaleFactor, density, Fintra_r, r, minQ, QmaxIntegrate, maxQ, smoothFactor, dampFactor, iteration, rmin): """Function to apply the Kaplow method. Parameters ---------- variables : module input variables setted by the user Q : numpy array momentum transfer (nm^-1) I_Q : numpy array measured scattering intensity Ibkg_Q : numpy array background scattering intensity J_Q : numpy array J(Q) fe_Q : numpy array effective electric form factor Iincoh_Q : numpy array incoherent scattering intensity Sinf : float value of S(Q) for Q->inf Ztot : int total Z number scaleFactor : float scale factor density : float average atomic density Fintra_r : numpy array intramolecular contribution of F(r) r : numpy array atomic distance (nm) Returns ------- chi2 : float chi2 value SsmoothDamp_Q : numpy array smoothed and damped structure factor Fopt_r : numpy array optimized F(r) """ Isample_Q = MainFunctions.calc_IsampleQ(I_Q, scaleFactor, Ibkg_Q) alpha = MainFunctions.calc_alpha(J_Q[Q <= QmaxIntegrate], Sinf, Q[Q <= QmaxIntegrate], Isample_Q[Q <= QmaxIntegrate], fe_Q[Q <= QmaxIntegrate], Ztot, density) Icoh_Q = MainFunctions.calc_Icoh(alpha, Isample_Q, Iincoh_Q) S_Q = MainFunctions.calc_SQ(Icoh_Q, Ztot, fe_Q, Sinf, Q, minQ, QmaxIntegrate, maxQ) Ssmooth_Q = UtilityAnalysis.calc_SQsmoothing(Q, S_Q, Sinf, smoothFactor, minQ, QmaxIntegrate, maxQ) SsmoothDamp_Q = UtilityAnalysis.calc_SQdamp(Ssmooth_Q, Q, Sinf, QmaxIntegrate, dampFactor) i_Q = MainFunctions.calc_iQ(SsmoothDamp_Q, Sinf) F_r = MainFunctions.calc_Fr(r, Q[Q <= QmaxIntegrate], i_Q[Q <= QmaxIntegrate]) Fopt_r, deltaFopt_r = Optimization.calc_optimize_Fr( iteration, F_r, Fintra_r, density, i_Q[Q <= QmaxIntegrate], Q[Q <= QmaxIntegrate], Sinf, J_Q[Q <= QmaxIntegrate], r, rmin, "n") chi2 = simps(deltaFopt_r[r < rmin]**2, r[r < rmin]) return (chi2, SsmoothDamp_Q, F_r, Fopt_r)
def Kaplow_methodFZ(numAtoms, variables, Q, I_Q, Ibkg_Q, aff_squared_mean, aff_mean_squared, Iincoh_Q, sf, rho0, Fintra_r, r): """Function to apply the Kaplow method with Waseda FZ formalism. Parameters ---------- numAtoms : int number of atoms in the molecule variables : module input variables setted by the user Q : numpy array momentum transfer (nm^-1) I_Q : numpy array measured scattering intensity Ibkg_Q : numpy array background scattering intensity aff_squared_mean : numpy array mean of the squared form factor: <f^2> aff_mean_squared : numpy array squared of the mean form factor: <f>^2 Iincoh_Q : numpy array incoherent scattering intensity sf : float scale factor rho0 : float average atomic density Fintra_r : numpy array intramolecular contribution of F(r) r : numpy array atomic distance (nm) Returns ------- chi2 : float chi2 value """ Isample_Q = MainFunctions.calc_IsampleQ(I_Q, sf, Ibkg_Q) alpha = Formalism.calc_alphaFZ(Q, Isample_Q, Iincoh_Q, rho0, aff_squared_mean, aff_mean_squared) Icoh_Q = MainFunctions.calc_Icoh(alpha, Isample_Q, Iincoh_Q) S_Q = Formalism.calc_SFZ_Q(Q, Icoh_Q, aff_squared_mean, aff_mean_squared, variables.minQ, \ variables.QmaxIntegrate, variables.maxQ) S_Qsmoothed = UtilityAnalysis.calc_SQsmoothing(Q, S_Q, 1, variables.smooth_factor, \ variables.minQ, variables.QmaxIntegrate, variables.maxQ) S_QsmoothedDamp = UtilityAnalysis.calc_SQdamp(S_Qsmoothed, Q, 1, \ variables.QmaxIntegrate, variables.damping_factor) i_Q = MainFunctions.calc_iQ(S_QsmoothedDamp, 1) F_r = MainFunctions.calc_Fr(r, Q[Q<=variables.QmaxIntegrate], \ i_Q[Q<=variables.QmaxIntegrate]) # J_Q = Iincoh_Q/aff_mean_squared F_rIt, deltaF_rIt = Formalism.calc_optimize_FrFZ(variables.iteration, F_r, \ Fintra_r, rho0, i_Q[Q<=variables.QmaxIntegrate], Q[Q<=variables.QmaxIntegrate], \ Iincoh_Q[Q<=variables.QmaxIntegrate], r, variables.rmin) chi2 = simps(deltaF_rIt[r < variables.rmin]**2, r[r < variables.rmin]) return (chi2, S_QsmoothedDamp, F_rIt)
def OptimizeThicknessRef(Q, I_Q, Ibkg_Q, J_Q, Iincoh_Q, fe_Q, maxQ, minQ, QmaxIntegrate, Ztot, density, scaleFactor, sth, s0th, Sinf, smoothingFactor, rmin, dampingFunction, Fintra_r, iterations, s0thStep, ws1, ws2, r1, r2, d, phi_matrix_flag): """Function for the thickness optimization. """ Flag = 0 NoPeak = 0 s0th = max(s0th - s0thStep * 11, 0.0) s0thStepEnd = 0.0006 numSample = 23 # Loop for the range shifting while 1: s0thArray = IgorFunctions.makeArrayLoop(s0th, s0thStep) chi2Array = np.zeros(numSample) for i in range(numSample): # ------------------Kaplow method for scale-------------------- T_MCC_sth, T_MCC_corr_factor_bkg = Geometry.MCCCorrection( sth, s0thArray[i], thickness_sampling, phi_matrix) I_Q = I_Q / T_MCC_sth Ibkg_Q = Ibkg_Q * T_MCC_corr_factor_bkg / (T_MCC_sth) Isample_Q = MainFunctions.calc_IsampleQ(I_Q, scaleFactor, Ibkg_Q) alpha = MainFunctions.calc_alpha(J_Q[Q <= QmaxIntegrate], Sinf, Q[Q <= QmaxIntegrate], Isample_Q[Q <= QmaxIntegrate], fe_Q[Q <= QmaxIntegrate], Ztot, density) Icoh_Q = MainFunctions.calc_Icoh(alpha, Isample_Q, Iincoh_Q) S_Q = MainFunctions.calc_SQ(Icoh_Q, Ztot, fe_Q, Sinf, Q, minQ, QmaxIntegrate, maxQ) Ssmooth_Q = UtilityAnalysis.calc_SQsmoothing( Q, S_Q, Sinf, smoothingFactor, minQ, QmaxIntegrate, maxQ) SsmoothDamp_Q = UtilityAnalysis.calc_SQdamp( Ssmooth_Q, Sinf, dampingFunction) i_Q = MainFunctions.calc_iQ(SsmoothDamp_Q, Sinf) Qi_Q = Q * i_Q r, F_r = MainFunctions.calc_Fr(Q[Q <= QmaxIntegrate], Qi_Q[Q <= QmaxIntegrate]) Fopt_r, deltaFopt_r = Optimization.calc_optimize_Fr( iterations, F_r, Fintra_r, density, i_Q[Q <= QmaxIntegrate], Q[Q <= QmaxIntegrate], Sinf, J_Q[Q <= QmaxIntegrate], r, rmin, "n") deltaFopt_r[np.where(r >= rmin)] = 0.0 chi2Array[i] = np.mean(deltaFopt_r**2) # --------------------Range shifting selection -------------------- if np.amax(chi2Array) > 10**8: s0thIdx = np.argmin(chi2Array[0:np.argmax(chi2Array)]) else: s0thIdx = np.argmin(chi2Array) s0th = s0thArray[s0thIdx] - s0thStep * 1.1 nearIdx, nearEl = UtilityAnalysis.find_nearest(s0thArray, s0th) if nearIdx == 0: print("out1") s0th -= s0thStep * 10 s0thStep *= 10 NoPeak += 1 if nearIdx >= numSample - 2: print("out2") s0th += s0thStep * 10 s0thStep *= 10 NoPeak += 1 s0thStep /= 10 Flag += 1 if ((10 * s0thStep > s0thStepEnd) and (NoPeak < 5)): continue else: break # ------------------------chi2 curve fit for scale------------------------- xFit, yFit, sth, chi2 = IgorFunctions.chi2Fit(s0th, s0thArray, chi2Array) print("final sample thickness ref", s0th) return s0th
elementList = Utility.molToelemList(variables.molecule) elementParameters = Utility.read_parameters(elementList, variables.element_params_path) path = Utility.path_xyz_file(variables.molecule) numAtoms, element, x, y, z = Utility.read_xyz_file(path) Q, I_Q = Utility.read_file(variables.data_file) Qbkg, Ibkg_Q = Utility.read_file(variables.bkg_file) #--------------------Preliminary calculation------------------------------- # Q, I_Q, Qbkg, Ibkg_Q = UtilityAnalysis.check_data_length(Q, I_Q, Qbkg, Ibkg_Q, \ # variables.minQ, variables.maxQ) fe_Q, Ztot = MainFunctions.calc_eeff(elementList, Q, elementParameters) Iincoh_Q = MainFunctions.calc_Iincoh(elementList, Q, elementParameters) J_Q = IgorFunctions.calc_JQ(Iincoh_Q, fe_Q) Sinf = MainFunctions.calc_Sinf(elementList, fe_Q, Q, Ztot, elementParameters) dampingFunction = UtilityAnalysis.calc_dampingFunction(Q, variables.dampingFactor, variables.QmaxIntegrate, variables.typeFunction) #-------------------Intra-molecular components----------------------------- iintra_Q = Optimization.calc_iintra(Q, fe_Q, Ztot, variables.QmaxIntegrate, variables.maxQ, elementList, element, x, y, z, elementParameters) iintradamp_Q = UtilityAnalysis.calc_iintradamp(iintra_Q, Q, variables.QmaxIntegrate, dampingFunction) rintra, Fintra_r = IgorFunctions.calc_FFT_QiQ(Q, Q*iintradamp_Q, variables.QmaxIntegrate)
# plt.show #--------------------Preliminary calculation------------------------------- Q, I_Q = UtilityAnalysis.data_interpolation(Q, I_Q, inputVariables["minQ"], inputVariables["maxQ"], inputVariables["numPoints"]) Qbkg, Ibkg_Q = UtilityAnalysis.data_interpolation( Qbkg, Ibkg_Q, inputVariables["minQ"], inputVariables["maxQ"], inputVariables["numPoints"]) # plt.plot(Q, I_Q) # plt.plot(Qbkg, Ibkg_Q) # plt.show fe_Q, Ztot = MainFunctions.calc_eeff(elementList, Q, elementParameters) Iincoh_Q = MainFunctions.calc_Iincoh(elementList, Q, elementParameters) J_Q = MainFunctions.calc_JQ(Iincoh_Q, Ztot, fe_Q) Sinf = MainFunctions.calc_Sinf(elementList, fe_Q, Q, Ztot, elementParameters) dampingFunction = UtilityAnalysis.calc_dampingFunction( Q, inputVariables["dampingFactor"], inputVariables["QmaxIntegrate"], inputVariables["typeFunction"]) #-------------------Intra-molecular components----------------------------- iintra_Q = Optimization.calc_iintra( Q, fe_Q, Ztot, inputVariables["QmaxIntegrate"], inputVariables["maxQ"], elementList, elementPosition["element"], elementPosition["x"], elementPosition["y"], elementPosition["z"], elementParameters) iintradamp_Q = UtilityAnalysis.calc_iintradamp(iintra_Q, dampingFunction)
variables = Utility.read_inputFile("./inputFile.txt") elementList = Utility.molToelemList(variables.molecule) elementParameters = Utility.read_parameters(elementList, variables.element_params_path) path = Utility.path_xyz_file(variables.molecule) numAtoms, element, x, y, z = Utility.read_xyz_file(path) Q, I_Q = Utility.read_file(variables.data_file) Qbkg, Ibkg_Q = Utility.read_file(variables.bkg_file) # -------------------Preliminary calculation------------------------------- fe_Q, Ztot = MainFunctions.calc_eeff(elementList, Q, elementParameters) Iincoh_Q = MainFunctions.calc_Iincoh(elementList, Q, elementParameters) J_Q = MainFunctions.calc_JQ(Iincoh_Q, Ztot, fe_Q) Sinf = MainFunctions.calc_Sinf(elementList, fe_Q, Q, Ztot, elementParameters) dampingFunction = UtilityAnalysis.calc_dampingFunction( Q, variables.dampingFactor, variables.QmaxIntegrate, variables.typeFunction) # ------------------Intra-molecular components----------------------------- iintra_Q = Optimization.calc_iintra(Q, fe_Q, Ztot, variables.QmaxIntegrate, variables.maxQ, elementList, element, x, y, z, elementParameters) iintradamp_Q = UtilityAnalysis.calc_iintradamp(iintra_Q, dampingFunction)
def SQ(self): """Function to calculate and plot the structure factor S(Q)""" self.elementList = Utility.molToElemList(self.molecule) # self.elementList = Utility.molToElemList("Ar") self.elementParameters = Utility.read_parameters( self.elementList, "./elementParameters.txt") # print(elementList) # print(elementParameters) self.Q, self.I_Q, self.Qbkg, self.Ibkg_Q = UtilityAnalysis.check_data_length( self.Q, self.I_Q, self.Qbkg, self.Ibkg_Q, self.ui.minQ.value(), self.ui.maxQ.value()) two_theta = UtilityAnalysis.Qto2theta(self.Q) absCorrFactor = Geometry.calcAbsCorrection( self.ui.absLength.value(), two_theta, self.ui.dacThickness.value(), self.ui.dacAngle.value()) self.I_Q = self.I_Q / absCorrFactor self.Ibkg_Q = self.Ibkg_Q / absCorrFactor self.fe_Q, self.Ztot = MainFunctions.calc_eeff(self.elementList, self.Q, self.elementParameters) self.Iincoh_Q = MainFunctions.calc_Iincoh(self.elementList, self.Q, self.elementParameters) self.J_Q = MainFunctions.calc_JQ(self.Iincoh_Q, self.Ztot, self.fe_Q) self.Sinf = MainFunctions.calc_Sinf(self.elementList, self.fe_Q, self.Q, self.Ztot, self.elementParameters) self.dampingFunct = UtilityAnalysis.calc_dampingFunction( self.Q, self.ui.dampingFactor.value(), self.ui.QmaxIntegrate.value(), self.ui.dampingFunction.currentText()) Isample_Q = MainFunctions.calc_IsampleQ( self.I_Q, self.ui.scaleFactorValue.value(), self.Ibkg_Q) alpha = MainFunctions.calc_alpha( self.J_Q[self.Q <= self.ui.QmaxIntegrate.value()], self.Sinf, self.Q[self.Q <= self.ui.QmaxIntegrate.value()], Isample_Q[self.Q <= self.ui.QmaxIntegrate.value()], self.fe_Q[self.Q <= self.ui.QmaxIntegrate.value()], self.Ztot, self.ui.densityValue.value()) Icoh_Q = MainFunctions.calc_Icoh(alpha, Isample_Q, self.Iincoh_Q) S_Q = MainFunctions.calc_SQ(Icoh_Q, self.Ztot, self.fe_Q, self.Sinf, self.Q, self.ui.minQ.value(), self.ui.QmaxIntegrate.value(), self.ui.maxQ.value()) Ssmooth_Q = UtilityAnalysis.calc_SQsmoothing( self.Q, S_Q, self.Sinf, self.ui.smoothingFactor.value(), self.ui.minQ.value(), self.ui.QmaxIntegrate.value(), self.ui.maxQ.value()) self.SsmoothDamp_Q = UtilityAnalysis.calc_SQdamp( Ssmooth_Q, self.Sinf, self.dampingFunct) # self.ui.factorPlot.canvas.ax.plot(self.Q, self.SsmoothDamp_Q, "b", label=r"$S(Q)$") # self.ui.factorPlot.canvas.ax.legend() # self.ui.factorPlot.canvas.draw() return self.SsmoothDamp_Q
def calc_iintra(Q, fe_Q, Ztot, QmaxIntegrate, maxQ, elementList, element, x, y, z, elementParameters): """Function to calculate the intramolecular contribution of i(Q) (eq. 41). Parameters ---------- Q : numpy array momentum transfer (nm^-1) fe_Q : numpy array effective electric form factor Ztot : int total Z number QmaxIntegrate : float maximum Q value for the intagrations maxQ : float maximum Q value elementList : dictionary("element": multiplicity) chemical elements of the sample with their multiplicity element : string chemical element multiplicity : int chemical element multiplicity element : string array array with the elements in the xyz_file x, y, z : float array atomic coordinate in the xyz_file (nm) elementParameters : dictionary("element": parameters) chemical elements of the sample with their parameters element : string chemical element parameters : list list of the parameters (Z, a1, b1, a2, b2, a3, b3, a4, b4, c, M, K, L) Returns ------- iintra_Q : numpy array intramolecular contribution of i(Q) """ iintra_Q = np.zeros(Q.size) sinpq = np.zeros(Q.size) for ielem in range(len(element)): for jelem in range(len(element)): if ielem != jelem: Kpi = MainFunctions.calc_Kp(fe_Q, element[ielem], Q, elementParameters) Kpj = MainFunctions.calc_Kp(fe_Q, element[jelem], Q, elementParameters) KK = Kpi * Kpj d = Utility.calc_distMol(x[ielem], y[ielem], z[ielem], x[jelem], y[jelem], z[jelem]) if d != 0.0: iintra_Q += KK * np.sin(d * Q) / (d * Q) iintra_Q[Q == 0.0] = KK iintra_Q[(Q > QmaxIntegrate) & (Q <= maxQ)] = 0.0 iintra_Q /= Ztot**2 # iintra_Q /= 3 return iintra_Q
def Optimization(self): """Function to optimize and plot F(r)""" #-------------------Intra-molecular components----------------------------- # numAtoms, element, x, y, z = Utility.read_xyz_file(self.XYZFilePath) numAtoms, element, x, y, z = Utility.read_xyz_file( "/Users/ciccio/work/ID27/LASDiA/xyzFiles/Ar.xyz") iintra_Q = Optimization.calc_iintra(self.Q, self.fe_Q, self.Ztot, self.ui.QmaxIntegrate.value(), self.ui.maxQ.value(), self.elementList, element, x, y, z, self.elementParameters) iintradamp_Q = UtilityAnalysis.calc_iintradamp(iintra_Q, self.dampingFunct) Qiintradamp_Q = self.Q * iintradamp_Q rintra, Fintra_r = MainFunctions.calc_Fr( self.Q[self.Q <= self.ui.QmaxIntegrate.value()], Qiintradamp_Q[self.Q <= self.ui.QmaxIntegrate.value()]) scaleFactor = self.ui.scaleFactorValue.value() density0 = self.ui.densityValue.value() # ----------------------First scale minimization--------------------------- scaleStep = 0.05 # sth = 0.008 # s0th = 0.006 sth = 0.0 s0th = 0.0 phi_matrix = 0.0 thickness_sampling = 0.0 scaleFactor = Minimization.OptimizeScale( self.Q, self.I_Q, self.Ibkg_Q, self.J_Q, self.Iincoh_Q, self.fe_Q, self.ui.maxQ.value(), self.ui.minQ.value(), self.ui.QmaxIntegrate.value(), self.Ztot, density0, scaleFactor, self.Sinf, self.ui.smoothingFactor.value(), self.ui.rmin.value(), self.dampingFunct, Fintra_r, self.ui.iterations.value(), scaleStep, sth, s0th, thickness_sampling, phi_matrix, "n") # ----------------------First density minimization------------------------- densityStep = density0 / 50 densityStepEnd = density0 / 250 density = Minimization.OptimizeDensity( self.Q, self.I_Q, self.Ibkg_Q, self.J_Q, self.Iincoh_Q, self.fe_Q, self.ui.maxQ.value(), self.ui.minQ.value(), self.ui.QmaxIntegrate.value(), self.Ztot, density0, scaleFactor, self.Sinf, self.ui.smoothingFactor.value(), self.ui.rmin.value(), self.dampingFunct, Fintra_r, self.ui.iterations.value(), densityStep, densityStepEnd, sth, s0th, thickness_sampling, phi_matrix, "n") # print("density0, density", density0, density) numLoopIteration = 0 while 1: if np.abs(density - density0) > density / 25: # print("First") scaleStep = 0.006 densityStep = density / 10 WSamplestep = 0.0008 WRefstep = 0.0008 elif np.abs(density - density0) > density / 75: # print("Second") scaleStep = 0.0006 densityStep = density / 100 WSamplestep = 0.0002 WRefstep = 0.0002 else: # print("Third") scaleStep = 0.00006 densityStep = density / 1000 WSamplestep = 0.0001 WRefstep = 0.0001 scaleFactor = Minimization.OptimizeScale( self.Q, self.I_Q, self.Ibkg_Q, self.J_Q, self.Iincoh_Q, self.fe_Q, self.ui.maxQ.value(), self.ui.minQ.value(), self.ui.QmaxIntegrate.value(), self.Ztot, density, scaleFactor, self.Sinf, self.ui.smoothingFactor.value(), self.ui.rmin.value(), self.dampingFunct, Fintra_r, self.ui.iterations.value(), scaleStep, sth, s0th, thickness_sampling, phi_matrix, "n") density0 = density density = Minimization.OptimizeDensity( self.Q, self.I_Q, self.Ibkg_Q, self.J_Q, self.Iincoh_Q, self.fe_Q, self.ui.maxQ.value(), self.ui.minQ.value(), self.ui.QmaxIntegrate.value(), self.Ztot, density0, scaleFactor, self.Sinf, self.ui.smoothingFactor.value(), self.ui.rmin.value(), self.dampingFunct, Fintra_r, self.ui.iterations.value(), densityStep, density / 250, sth, s0th, thickness_sampling, phi_matrix, "n") numLoopIteration += 1 # print("numLoopIteration", numLoopIteration, scaleFactor, density) if (np.abs(density - density0) > np.abs( density / 2500)) and (numLoopIteration <= 30): continue else: break # print("final scale", scaleFactor, "final density", density) self.ui.scaleFactorValue.setValue(scaleFactor) self.ui.densityValue.setValue(density) Isample_Q = MainFunctions.calc_IsampleQ(self.I_Q, scaleFactor, self.Ibkg_Q) alpha = MainFunctions.calc_alpha( self.J_Q[self.Q <= self.ui.QmaxIntegrate.value()], self.Sinf, self.Q[self.Q <= self.ui.QmaxIntegrate.value()], Isample_Q[self.Q <= self.ui.QmaxIntegrate.value()], self.fe_Q[self.Q <= self.ui.QmaxIntegrate.value()], self.Ztot, density) Icoh_Q = MainFunctions.calc_Icoh(alpha, Isample_Q, self.Iincoh_Q) S_Q = MainFunctions.calc_SQ(Icoh_Q, self.Ztot, self.fe_Q, self.Sinf, self.Q, self.ui.minQ.value(), self.ui.QmaxIntegrate.value(), self.ui.maxQ.value()) Ssmooth_Q = UtilityAnalysis.calc_SQsmoothing( self.Q, S_Q, self.Sinf, self.ui.smoothingFactor.value(), self.ui.minQ.value(), self.ui.QmaxIntegrate.value(), self.ui.maxQ.value()) SsmoothDamp_Q = UtilityAnalysis.calc_SQdamp(Ssmooth_Q, self.Sinf, self.dampingFunct) i_Q = MainFunctions.calc_iQ(SsmoothDamp_Q, self.Sinf) Qi_Q = self.Q * i_Q r, F_r = MainFunctions.calc_Fr( self.Q[self.Q <= self.ui.QmaxIntegrate.value()], Qi_Q[self.Q <= self.ui.QmaxIntegrate.value()]) Fopt_r, deltaFopt_r = Optimization.calc_optimize_Fr( self.ui.iterations.value(), F_r, Fintra_r, density, i_Q[self.Q <= self.ui.QmaxIntegrate.value()], self.Q[self.Q <= self.ui.QmaxIntegrate.value()], self.Sinf, self.J_Q[self.Q <= self.ui.QmaxIntegrate.value()], r, self.ui.rmin.value(), "n") Scorr_Q = MainFunctions.calc_SQCorr(Fopt_r, r, self.Q, self.Sinf) self.ui.distfuncPlot.canvas.ax.plot(r, Fopt_r, "g", label=r"$F_{opt}(r)$") self.ui.distfuncPlot.canvas.ax.legend() self.ui.distfuncPlot.canvas.draw() self.ui.factorPlot.canvas.ax.plot(self.Q, Scorr_Q, "g", label=r"$S_{opt}(Q)$") self.ui.factorPlot.canvas.ax.legend() self.ui.factorPlot.canvas.draw()
def OptimizeDensity(Q, I_Q, Ibkg_Q, J_Q, Iincoh_Q, fe_Q, minQ, QmaxIntegrate, maxQ, Ztot, density, scaleFactor, Sinf, smoothingFactor, rmin, dampingFunction, Fintra_r, iterations, densityStep, sth, s0th, mccFlag, thickness_sampling, phi_matrix): """Function for the density optimization. Q : numpy array momentum transfer (nm^-1) I_Q : numpy array measured scattering intensity Ibkg_Q : numpy array background scattering intensity J_Q : numpy array J(Q) Iincoh_Q : numpy array incoherent scattering intensity fe_Q : numpy array effective electric form factor minQ : float minimum Q value QmaxIntegrate : float maximum Q value for the intagrations maxQ : float maximum Q value Ztot : int total Z number density : float average atomic density scaleFactor : float scale factor Sinf : float value of S(Q) for Q->inf smoothingFactor : float smoothing factor rmin : float r cut-off value (nm) dampingFunction : numpy array damping function Fintra_r : numpy array intramolecular contribution of F(r) iterations : int number of iterations scaleStep sth s0th thickness_sampling : float phi_matrix MCC_flag """ numSample = 23 if mccFlag.lower() == "y": T_MCC_sth, T_MCC_corr_factor_bkg = Geometry.MCC_correction( sth, s0th, thickness_sampling, phi_matrix) I_Q = I_Q / T_MCC_sth Ibkg_Q = Ibkg_Q * T_MCC_corr_factor_bkg / (T_MCC_sth) flag = 0 # Loop for the range shifting while 1: flag += 1 print("iter flag ", flag) densityArray = UtilityAnalysis.makeArrayLoop(density, densityStep) chi2Array = np.zeros(numSample) for i in range(numSample): print("sample ", i, densityArray[i]) # ------------------Kaplow method for scale-------------------- Isample_Q = MainFunctions.calc_IsampleQ(I_Q, scaleFactor, Ibkg_Q) alpha = MainFunctions.calc_alpha(J_Q[Q <= QmaxIntegrate], Sinf, Q[Q <= QmaxIntegrate], Isample_Q[Q <= QmaxIntegrate], fe_Q[Q <= QmaxIntegrate], Ztot, densityArray[i]) Icoh_Q = MainFunctions.calc_Icoh(alpha, Isample_Q, Iincoh_Q) S_Q = MainFunctions.calc_SQ(Icoh_Q, Ztot, fe_Q, Sinf, Q, minQ, QmaxIntegrate, maxQ) Ssmooth_Q = UtilityAnalysis.calc_SQsmoothing( Q, S_Q, Sinf, smoothingFactor, minQ, QmaxIntegrate, maxQ) SsmoothDamp_Q = UtilityAnalysis.calc_SQdamp( Ssmooth_Q, Sinf, dampingFunction) i_Q = MainFunctions.calc_iQ(SsmoothDamp_Q, Sinf) Qi_Q = Q * i_Q r, F_r = MainFunctions.calc_Fr(Q[Q <= QmaxIntegrate], Qi_Q[Q <= QmaxIntegrate]) # r, F_r = MainFunctions.calc_Fr(Q[Q<=QmaxIntegrate], # Qi_Q[Q<=QmaxIntegrate]) Fopt_r, deltaFopt_r = Optimization.calc_optimize_Fr( iterations, F_r, Fintra_r, densityArray[i], i_Q[Q <= QmaxIntegrate], Q[Q <= QmaxIntegrate], Sinf, J_Q[Q <= QmaxIntegrate], r, rmin, "n") deltaFopt_r[np.where(r >= rmin)] = 0.0 chi2Array[i] = np.mean(deltaFopt_r**2) # --------------------Range shifting selection -------------------- # densityIdx = np.argmin(chi2Array) # density = densityArray[densityIdx] - densityStep*1.1 # nearIdx, nearEl = UtilityAnalysis.find_nearest(densityArray, density) plt.scatter(densityArray, chi2Array) plt.grid(True) plt.show() maxLimit = 10**5 if np.amax(chi2Array) >= maxLimit: densityArray = densityArray[0:np.argmax(chi2Array >= maxLimit)] chi2Array = chi2Array[0:np.argmax(chi2Array >= maxLimit)] # print(np.argmin(chi2Array)) if np.argmin(chi2Array) < 6: # print("bug") density -= densityStep * 10 if np.argmin(chi2Array) > 16: density += densityStep * 10 if (np.argmin(chi2Array) >= 6 and np.argmin(chi2Array) <= 16): break else: continue # ------------------------chi2 curve fit for scale------------------------- #xFit, yFit, density, chi2Min = chi2Fit(densityArray, chi2Array) xFit, yFit, density, chi2 = IgorFunctions.chi2Fit(density, densityArray, chi2Array) print("final density", density) plt.scatter(densityArray, chi2Array) plt.plot(xFit, yFit) plt.grid(True) plt.show() return density