def geometry_correction(Q, I_Q, Qbkg, Ibkg_Q, variables, phi_matrix_flag): """Function to calcultate all intensity geometrical corrections. Parameters ---------- Q : numpy array momentum transfer (nm^-1) I_Q : numpy array measured scattering intensity Qbkg : numpy array background momentum transfer (nm^-1) Ibkg_Q : numpy array background scattering intensity variables : module input variables setted by the user phi_matrix_flag : string flag for the phi matrix calculation: "y": calculate phi matrix and save on file "n": read the phi matrix from file Returns ------- I_Q : numpy array corrected measured sample intensity Ibkg_Q : numpy array corrected background intensity """ two_theta = UtilityAnalysis.Qto2theta(Q) abs_corr_factor = calcAbsCorrection(variables.abs_length, \ two_theta, variables.dac_thickness, 0) num_point = 1000 phi_matrix_path = "./phi_matrix_" + variables.molecule if phi_matrix_flag.lower() == "y": ws1, ws2, r1, r2, d = Utility.read_MCC_file(variables.MCC_path, variables.MCC_type) thickness_sampling, phi_matrix = calc_phi_matrix(variables.phi_matrix_thickness, \ two_theta, ws1, ws2, r1, r2, d, num_point) np.save(phi_matrix_path, phi_matrix) else: thickness_sampling = np.linspace(0, variables.phi_matrix_thickness, num=num_point) phi_matrix = np.load(phi_matrix_path + ".npy") T_MCC_sample3, T_MCC_DAC3, T_MCC_ALL3 = calc_T_MCC(0.003, thickness_sampling, \ phi_matrix, "y") T_MCC_sample4, T_MCC_DAC4, T_MCC_ALL4 = calc_T_MCC(0.004, thickness_sampling, \ phi_matrix, "y") T_MCC_corr_factor_bkg = calc_T_DAC_MCC_bkg_corr(T_MCC_DAC4, T_MCC_DAC3) I_Q = I_Q / (abs_corr_factor * T_MCC_sample4) Ibkg_Q = Ibkg_Q * T_MCC_corr_factor_bkg / (abs_corr_factor * T_MCC_sample4) return (I_Q, Ibkg_Q)
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 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 interpolation(self): """Function to interpolate data""" self.Q, self.I_Q = UtilityAnalysis.data_interpolation( self.orgQ, self.orgI_Q, self.ui.minQ.value(), self.ui.maxQ.value(), self.ui.interpolationPoints.value()) self.Qbkg, self.Ibkg_Q = UtilityAnalysis.data_interpolation( self.orgQbkg, self.orgIbkg_Q, self.ui.minQ.value(), self.ui.maxQ.value(), self.ui.interpolationPoints.value()) self.ui.rawDataPlot.canvas.ax.lines.pop(0) self.ui.rawDataPlot.canvas.ax.lines.pop(0) self.ui.rawDataPlot.canvas.ax.plot(self.Q, self.I_Q, "b", label="Data") self.ui.rawDataPlot.canvas.ax.legend() self.ui.rawDataPlot.canvas.draw() self.ui.rawDataPlot.canvas.ax.plot(self.Qbkg, self.Ibkg_Q, "g--", label="Bkg") self.ui.rawDataPlot.canvas.ax.legend() self.ui.rawDataPlot.canvas.draw()
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_abs_correction(Q, abs_length, thickness, angle): """Function to calculate the absorption correction. This function can be used to calculate the absorption correction for the diamond or for any other object between the sample and the detector. The characteristics for some diamonds can be found here: http://www.almax-easylab.com/DiamondSelectionPage.aspx Parameters ---------- Q : numpy array momentum transfer (nm^-1) abs_length : float absorption length (cm), @33keV 1.208cm thickness : float object thickness (cm) angle : float object rotation angle respect the XRay beam (deg) Returns ------- corr_factor : numpy array correction factor """ # for now... # wavelenght : float # XRay beam wavelenght (nm), @ESRF ID27 0.03738nm # wavelenght = 0.03738 # nm # two_theta = Qto2theta(Q) # rad two_theta = UtilityAnalysis.Qto2theta(Q) mu_l = 1 / abs_length angle = np.radians(angle) path_lenght = thickness / np.cos(two_theta - angle) corr_factor = np.exp(-mu_l * path_lenght) # I_Qeff = I_Q / corr_factor return corr_factor
def check_phi_matrix(Q, ws1, ws2, r1, r2, d, phiMatrixCalcFlag, phiMatrixPath): """Function to make or read from file the phi matrix. Parameters ---------- Q : numpy array momentum transfer (nm^-1) ws1 : float distance between the slits of first set (cm) ws2 : float distance between the slits of second set (cm) r1 : float first radius r2 : float second radius d : float dimension of slit phiMatrixCalcFlag : string flag for the phi matrix calculation phiMatrixPath : string phi matrix path Returns ------- phi_matrix : 2D numpy array dispersion angle matrix for sample+DAC (rad) """ two_theta = UtilityAnalysis.Qto2theta(Q) if phiMatrixCalcFlag.lower() == "y": phi_matrix = calc_phi_matrix(two_theta, ws1, ws2, r1, r2, d) np.save(phiMatrixPath, phi_matrix) else: phi_matrix = np.load(phiMatrixPath) thickness_sampling = np.linspace(0, 0.17, num=1000) return (thickness_sampling, phi_matrix)
def calc_IFFT_Fr(r, F_r): """Function to calculate the FFT following the IGOR procedure. I do not agree with this procedure, but I follow it to compare my results with Igor Pro's ones. Parameters ---------- r : numpy array atomic distance (nm) F_r : numpy array F(r) Returns ------- Q : numpy array momentum transfer (nm^-1) Qi_Q : numpy array Qi(Q) """ NumPoints = 2**math.ceil(math.log(len(F_r)-1)/math.log(2)) F_r = Utility.resize_zero(F_r, NumPoints) Q = np.linspace(0.0, 109, 550) DelQ = 2*np.pi/(np.mean(np.diff(r))*NumPoints) meanDeltar = np.mean(np.diff(r)) Q1 = fftpack.fftfreq(r.size, meanDeltar) Qi_Q = fftpack.fft(F_r) Qi_Q = Qi_Q[np.where(Q1>=0.0)] Qi_Q = -np.imag(Qi_Q)*meanDeltar Q1 = np.arange(0.0, 0.0+DelQ*len(Qi_Q), DelQ) idxArray = np.zeros(550, dtype=np.int) for i in range(len(Q)): idxArray[i], _ = UtilityAnalysis.find_nearest(Q1, Q[i]) Qi_Q = Qi_Q[idxArray] return (Q, Qi_Q)
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 OptimizeScaleGofRCorr(Q, I_Q, Ibkg_Q, J_Q, fe_Q, maxQ, minQ, QmaxIntegrate, Ztot, density, scaleFactor, Sinf, smoothingFactor, rmin, NumPoints, dampingFunction, Fintra_r, iterations, scaleStep): """Function for the scale factor optimization. """ Flag = 0 NoPeak = 0 # scaleStep = 0.05 scaleStepEnd = 0.00006 numSample = 23 scaleFactor = scaleFactor-scaleStep*11 Qorg = Q # Loop for the range shifting while ((10*scaleStep>scaleStepEnd) and (NoPeak<5) and ((Flag==1) or (scaleFactor+scaleStep*1.1>=0))): # print("scale loop") scaleArray = make_array_loop(scaleFactor, scaleStep, numSample) chi2Array = np.zeros(numSample) for i in range(len(scaleArray)): # ------------------Kaplow method for scale-------------------- Q = Qorg Subt = calc_Subt(I_Q, Ibkg_Q, scaleArray[i]) alpha = calc_alpha(J_Q[Q<=QmaxIntegrate], Sinf, Q[Q<=QmaxIntegrate], Subt[Q<=QmaxIntegrate], fe_Q[Q<=QmaxIntegrate], Ztot, density) S_Q = calc_SQ(Q, Subt, alpha, fe_Q, J_Q, Ztot, Sinf, QmaxIntegrate) Ssmooth_Q = UtilityAnalysis.calc_SQsmoothing(Q, S_Q, Sinf, smoothingFactor, minQ, QmaxIntegrate, maxQ) Q, Ssmooth_Q = UtilityAnalysis.rebinning(Q, Ssmooth_Q, 0.0, maxQ, NumPoints) SsmoothDamp_Q = UtilityAnalysis.calc_SQdamp(Ssmooth_Q, Sinf, dampingFunction) chi2Array[i] = FitRemoveGofRPeaks(Q, SsmoothDamp_Q, Sinf, QmaxIntegrate, Fintra_r, iterations, rmin, density, J_Q, Ztot) # --------------------Range shifting selection -------------------- if np.amax(chi2Array) > 10**8: scaleFactor = scaleArray[np.argmin(chi2Array[0:np.argmax(chi2Array)])] - scaleStep*1.1 else: scaleFactor = scaleArray[np.argmin(chi2Array)] - scaleStep*1.1 nearIdx, nearEl = UtilityAnalysis.find_nearest(scaleArray, scaleFactor) if nearIdx == 0: print("out1") scaleFactor -= scaleStep*10 scaleStep *= 10 NoPeak += 1 if nearIdx >= numSample-2: print("out2") scaleFactor += scaleStep*10 scaleStep *= 10 NoPeak += 1 scaleStep /= 10 Flag += 1 print(Flag) # ------------------------chi2 curve fit for scale------------------------- xFit, yFit, scaleFactor, chi2Min = chi2Fit(scaleFactor, scaleArray, chi2Array) # plt.plot(xFit, yFit) # plt.grid(True) print("final scale factor", scaleFactor) # plt.show() return scaleFactor
def chi2_minimization(scaleFactor, Q, I_Q, Ibkg_Q, J_Q, fe_Q, Iincoh_Q, Sinf, Ztot, density, Fintra_r, r, minQ, QmaxIntegrate, maxQ, smoothFactor, dampFactor, iteration, rmin): """Function to calculate the whole loop for the chi2 minimization. """ scaleStep = 0.05 densityStep = 0.025 numSample = 23 numLoopIteration = 0 plt.ion() figure, ax = plt.subplots() while True: NoPeak = 0 while True: ax.cla() ax.grid(True) scaleArray = UtilityAnalysis.make_array_loop( scaleFactor, scaleStep, numSample) chi2Array = np.zeros(numSample) plt.xlabel("Scale") ax.relim() ax.autoscale_view() for i in range(len(scaleArray)): chi2Array[ i], SsmoothDamp_Q, F_r, Fopt_r = KaplowMethod.Kaplow_method( Q, I_Q, Ibkg_Q, J_Q, fe_Q, Iincoh_Q, Sinf, Ztot, scaleArray[i], density, Fintra_r, r, minQ, QmaxIntegrate, maxQ, smoothFactor, dampFactor, iteration, rmin) plt.scatter(scaleArray[i], chi2Array[i]) figure.canvas.draw() if np.amax(chi2Array) > 10**8: chi2Array = chi2Array[0:np.amax(chi2Array)] scaleFactor = scaleArray[np.argmin(chi2Array)] - scaleStep * 1.1 ax.cla() ax.grid(True) density0 = density densityArray = UtilityAnalysis.make_array_loop(density, densityStep, numSample) chi2Array = np.zeros(numSample) plt.xlabel("Density") ax.relim() ax.autoscale_view() for i in range(len(densityArray)): chi2Array[ i], SsmoothDamp_Q, F_r, Fopt_r = KaplowMethod.Kaplow_method( Q, I_Q, Ibkg_Q, J_Q, fe_Q, Iincoh_Q, Sinf, Ztot, scaleFactor, densityArray[i], Fintra_r, r, minQ, QmaxIntegrate, maxQ, smoothFactor, dampFactor, iteration, rmin) plt.scatter(densityArray[i], chi2Array[i]) figure.canvas.draw() xfit, yfit, density = chi2_fit(densityArray, chi2Array) plt.plot(xfit, yfit) figure.canvas.draw() if np.abs(density - density0) > density0 / 25: scaleStep = 0.006 densityStep = density0 / 10 elif np.abs(density - density0) > density0 / 75: scaleStep = 0.0006 densityStep = density0 / 100 else: scaleStep = 0.00006 densityStep = density0 / 1000 numLoopIteration += 1 if (np.abs(density - density0) < density0 / 2500 or numLoopIteration > 30): break plt.ioff() return (density, scaleFactor)
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 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)
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) _, Fintra_r = UtilityAnalysis.rebinning(rintra, Fintra_r, np.amin(rintra), np.amax(rintra), 8192) _, dampingFunction = UtilityAnalysis.rebinning(Q, dampingFunction, 0.0, variables.maxQ, variables.NumPoints)
def OptimizeDensityGofRCorr(Q, I_Q, Ibkg_Q, J_Q, fe_Q, maxQ, minQ, QmaxIntegrate, Ztot, density, scaleFactor, Sinf, smoothingFactor, rmin, NumPoints, dampingFunction, Fintra_r, iterations, densityStep, densityStepEnd): """Function for the density optimization. """ Flag = 0 NoPeak = 0 # densityStep = density/50 # densityStepEnd = density/250 numSample = 23 density = density-densityStep*11 Qorg = Q while ((10*densityStep>densityStepEnd) and (NoPeak<5)): # Loop for the range shifting densityArray = make_array_loop(density, densityStep, numSample) chi2Array = np.zeros(numSample) for i in range(len(densityArray)): # ------------------Kaplow method for scale-------------------- Q = Qorg Subt = calc_Subt(I_Q, Ibkg_Q, scaleFactor) alpha = calc_alpha(J_Q[Q<=QmaxIntegrate], Sinf, Q[Q<=QmaxIntegrate], Subt[Q<=QmaxIntegrate], fe_Q[Q<=QmaxIntegrate], Ztot, densityArray[i]) S_Q = calc_SQ(Q, Subt, alpha, fe_Q, J_Q, Ztot, Sinf, QmaxIntegrate) Ssmooth_Q = UtilityAnalysis.calc_SQsmoothing(Q, S_Q, Sinf, smoothingFactor, minQ, QmaxIntegrate, maxQ) Q, Ssmooth_Q = UtilityAnalysis.rebinning(Q, Ssmooth_Q, 0.0, maxQ, NumPoints) SsmoothDamp_Q = UtilityAnalysis.calc_SQdamp(Ssmooth_Q, Sinf, dampingFunction) chi2Array[i] = FitRemoveGofRPeaks(Q, SsmoothDamp_Q, Sinf, QmaxIntegrate, Fintra_r, iterations, rmin, densityArray[i], J_Q, Ztot) # --------------------Range shifting selection -------------------- density = densityArray[np.argmin(chi2Array)] - densityStep*1.1 nearIdx, nearEl = UtilityAnalysis.find_nearest(densityArray, density) if nearIdx == 0: print("out3") density -= densityStep*10 densityStep *= 10 NoPeak += 1 if nearIdx >= numSample-2: print("out4") density += densityStep*10 densityStep *= 10 NoPeak += 1 densityStep /= 10 Flag += 1 print(Flag) plt.scatter(densityArray, chi2Array) plt.grid(True) # plt.show # if ((10*densityStep<=densityStepEnd) and (NoPeak>=5)): # break # ------------------------chi2 curve fit for scale------------------------- xFit, yFit, density, chi2Min = chi2Fit(density, densityArray, chi2Array) print("final density", density) return density
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
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
elementList = Utility.molToElemList(inputVariables["molecule"]) elementParameters = Utility.read_parameters( elementList, inputVariables["elementParamsPath"]) elementPosition = Utility.read_xyz_file(inputVariables["xyzPath"]) Q, I_Q = Utility.read_file(inputVariables["dataFile"]) Qbkg, Ibkg_Q = Utility.read_file(inputVariables["bkgFile"]) # plt.plot(Q, I_Q) # plt.plot(Qbkg, Ibkg_Q) # 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(
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) Qiintradamp_Q = Q * iintradamp_Q rintra, Fintra_r = MainFunctions.calc_Fr( Q[Q <= variables.QmaxIntegrate], Qiintradamp_Q[Q <= variables.QmaxIntegrate]) # _, Fintra_r = UtilityAnalysis.rebinning(rintra, Fintra_r, np.amin(Fintra_r), # np.amax(Fintra_r), 8192)
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