mod_suppFig5_fitted.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. #!/usr/bin/env python3
  2. # -*- coding: UTF-8 -*-
  3. from glob import glob
  4. from operator import truediv
  5. from matplotlib import pyplot as plt
  6. import cmath
  7. from scattnlay import mesomie, mie
  8. import numpy as np
  9. import scipy.io
  10. from functools import wraps
  11. import time
  12. from eval_spectra import multi_lorentzian, params_count as pc
  13. import cma
  14. import sys
  15. from optical_constants import read_refractive_index_from_yaml as read_nk
  16. isPlot = True
  17. # isPlot = False
  18. def timeit(func):
  19. @wraps(func)
  20. def timeit_wrapper(*args, **kwargs):
  21. start_time = time.perf_counter()
  22. result = func(*args, **kwargs)
  23. end_time = time.perf_counter()
  24. total_time = end_time - start_time
  25. print(
  26. f'Function {func.__name__}{args} {kwargs} Took {total_time:.4f} seconds')
  27. return result
  28. return timeit_wrapper
  29. min_lim = 0.4
  30. max_lim = 0.75
  31. # mat = scipy.io.loadmat('d-parameters/rs=4.mat')
  32. # omega_ratio = mat['omegav'][0]
  33. # d_perp = mat['dperp'][0]*10
  34. from_disk = np.loadtxt('rs4-d_perp_interpolated.txt')
  35. from_disk = from_disk[:,
  36. from_disk[0, :] > min_lim
  37. ]
  38. from_disk = from_disk[:,
  39. from_disk[0, :] < max_lim
  40. ]
  41. omega_ratio = from_disk[0, :]
  42. d_perp = from_disk[1, :] + 1j*from_disk[2, :]
  43. c = 299792458 # m/s
  44. h_reduced = 6.5821e-16 # eV s
  45. omega_p = 5.9 # eV
  46. gamma = 0.1 # eV
  47. eps_d = 1
  48. # omega_p_star = 3.81 # eV #orig
  49. omega_p_star = 5.81 # eV
  50. omega = omega_ratio*omega_p_star
  51. # WL_mkm = 2*np.pi/((omega/c)/h_reduced)*1e6
  52. WL = 2*np.pi/((omega_ratio * omega_p_star/c)/h_reduced)*1e6 # mkm
  53. # min_WL_available = 0.1879
  54. # max_WL_available = 1.9370
  55. # WL[WL < min_WL_available] = min_WL_available
  56. # WL[WL > max_WL_available] = max_WL_available
  57. index_Ag = read_nk('Ag-Johnson-1972.yml', WL, kind=1)
  58. eps_Ag = index_Ag**2
  59. # print(index_Ag)
  60. # plt.figure('index')
  61. # plt.plot(index_Ag[:, 0], np.real(index_Ag[:, 1]))
  62. # plt.plot(index_Ag[:, 0], np.imag(index_Ag[:, 1]))
  63. # plt.show()
  64. # sys.exit()
  65. def eps_m(omega):
  66. return 1 - omega_p * omega_p / (omega*omega + 1j*omega*gamma)
  67. n = 1 if isPlot else 1
  68. Rs = [2.5]*n # nm
  69. y_min = [1e-2]*n
  70. y_max = [1e1]*n
  71. # Rs = [2.5, 5, 10, 25] # nm
  72. # y_min = [1e-2, 1e-2, 1e-1, 1e-1]
  73. # y_max = [1e1, 1e1, 5e1, 5e1]
  74. # for om_rat in omega_ratio:
  75. R = 0
  76. @ timeit
  77. def run():
  78. for fig in range(len(Rs)):
  79. global R
  80. R = Rs[fig]
  81. Qext = []
  82. Qext_fit = []
  83. om_rat_plot = []
  84. x_fit_from_d_perp = np.array([0.09391149, 0.81234806, -0.30526326, -0.01044856,
  85. 0.3121473, 0.55333457, -0.01684191, 0.04727765,
  86. 0.11249052, 0.88368699, -0.04680872, -0.10982548])
  87. omega = omega_ratio*omega_p
  88. x = (omega/c) * R * 1e-9/h_reduced
  89. m_orig = np.sqrt(eps_m(omega))
  90. # m = np.sqrt(eps_m(omega))
  91. # m = index_Ag
  92. m = index_Ag[:, 1]
  93. # plt.figure('index2')
  94. # plt.plot(x, np.real(m), label='orig')
  95. # plt.plot(x, np.imag(m), label='orig')
  96. # plt.plot(x, np.real(m), label='mod')
  97. # plt.plot(x, np.imag(m), label='mod')
  98. # plt.legend()
  99. # plt.show()
  100. # sys.exit()
  101. Qext = getMesoQext(R, x, m_orig, d_perp)
  102. def getQfit(x_fit):
  103. d_fit = multi_lorentzian(omega_ratio, x_fit)
  104. return getMesoQext(R, x, m, d_fit)
  105. def rms_base(Q_rms, Q_fit):
  106. diff_re = np.real(Q_rms - Q_fit)
  107. diff_im = np.imag(Q_rms - Q_fit)
  108. rms = (np.sum(np.abs(diff_re)**2))
  109. rms += (np.sum(np.abs(diff_im)**2))
  110. return rms
  111. def rms(x0):
  112. Q_fit = getQfit(x0)
  113. return rms_base(Q_rms, Q_fit)
  114. def rms_x12(x0):
  115. x0[:pc] = x0[:pc]+x1
  116. Q_fit = getQfit(x0)
  117. return rms_base(Q_rms, Q_fit)
  118. def rms_x1(x0):
  119. Q_fit = getQfit(np.hstack((x1, x0)))
  120. return rms_base(Q_rms, Q_fit)
  121. x_fit_from_d_perp = np.array([0.09391149, 0.81234806, -0.30526326, -0.01044856,
  122. 0.3121473, 0.55333457, -0.01684191, 0.04727765,
  123. 0.11249052, 0.88368699, -0.04680872, -0.10982548])
  124. x0 = np.random.random(pc)
  125. Q_rms = Qext
  126. xfit, es = cma.fmin2(rms, x0, sigma0=2)
  127. # xfit = np.array([0.32740616895990493, -0.844352181880013, -
  128. # 0.5682552466755, 0.015925488550861087])
  129. x1 = np.copy(xfit)
  130. Qext_fit = getQfit(xfit)
  131. # print(x1)
  132. # x0 = np.random.random(pc)
  133. # # x0 = np.copy(x1)
  134. # x0 = np.hstack((x1, x0))
  135. # xfit, es = cma.fmin2(rms, x0, sigma0=0.2)
  136. # # xfit = np.array([-9.03308419e-01, -1.77584180e+00, -2.36259518e+01, 3.41837008e+00,
  137. # 5.75724471e-06, , 2.64230613e+00, , 4.72267415e+01, -1.61624064e+00])
  138. # # xfit = np.array([0.32740616895990493, -0.844352181880013, -
  139. # # 0.5682552466755, 0.015925488550861087])
  140. # x2 = np.copy(xfit)
  141. # Qext_fit = getQfit(np.hstack((x1, x2)))
  142. print(xfit)
  143. om_rat_plot = omega_ratio
  144. if isPlot:
  145. Qext_fit = getQfit(xfit)
  146. Qext_no_d = getMesoQext(R, x, m_orig, np.zeros(len(x)))
  147. Qext_no_d_mod = getMesoQext(R, x, m, np.zeros(len(x)))
  148. d_fit = multi_lorentzian(omega_ratio, xfit)
  149. plt.figure(fig)
  150. plt.plot(om_rat_plot, Qext_fit,
  151. label='fitted orig using mod', color='gray', lw=4)
  152. plt.plot(om_rat_plot, Qext_no_d,
  153. label='d=0 orig', color='gray', lw=4)
  154. plt.plot(om_rat_plot, Qext_no_d_mod,
  155. label='d=0 mod', color='gray', lw=4)
  156. plt.plot(om_rat_plot, Qext, label='direct orig', color='red', lw=1)
  157. plt.legend()
  158. # plt.yscale('log')
  159. # plt.xlim((0.4, 0.404))
  160. # plt.ylim((y_min[fig]*1.9, y_min[fig]*2.3))
  161. plt.xlim((0.4, 0.75))
  162. # plt.xlim((0.5, 0.6))
  163. # plt.ylim((y_min[fig], y_max[fig]))
  164. plt.title("Qext for R="+str(R))
  165. plt.figure("d_param "+str(fig))
  166. plt.plot(om_rat_plot, np.real(d_fit), label='re fit', lw=4)
  167. plt.plot(om_rat_plot, np.real(d_perp), label='re d_perp')
  168. plt.plot(om_rat_plot, np.imag(d_fit), label='im fit', lw=4)
  169. plt.plot(om_rat_plot, np.imag(d_perp), label='im d_perp')
  170. plt.legend()
  171. if isPlot:
  172. plt.show()
  173. # @timeit
  174. def getMesoQext(R, x, m, d_perp):
  175. Qext = np.zeros((len(x)))
  176. for i in range(len(x)):
  177. mesomie.calc_ab(R*10, # calc_ab needs R in angstrem
  178. x[i], # xd
  179. x[i] * m[i], # xm
  180. 1, # eps_d
  181. m[i] * m[i], # eps_m
  182. 0, # d_parallel
  183. d_perp[i]) # d_perp
  184. mesomie.calc_Q()
  185. Qext[i] = mesomie.GetQext()
  186. return Qext
  187. run()