suppFig5_fitted.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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[:, 1]
  92. # plt.figure('index2')
  93. # plt.plot(x, np.real(m), label='orig')
  94. # plt.plot(x, np.imag(m), label='orig')
  95. # plt.plot(x, np.real(m), label='mod')
  96. # plt.plot(x, np.imag(m), label='mod')
  97. # plt.legend()
  98. # plt.show()
  99. # sys.exit()
  100. Qext = getMesoQext(R, x, m, d_perp)
  101. def getQfit(x_fit):
  102. d_fit = multi_lorentzian(omega_ratio, x_fit)
  103. return getMesoQext(R, x, m, d_fit)
  104. def rms_base(Q_rms, Q_fit):
  105. diff_re = np.real(Q_rms - Q_fit)
  106. diff_im = np.imag(Q_rms - Q_fit)
  107. rms = (np.sum(np.abs(diff_re)**2))
  108. rms += (np.sum(np.abs(diff_im)**2))
  109. return rms
  110. def rms(x0):
  111. Q_fit = getQfit(x0)
  112. return rms_base(Q_rms, Q_fit)
  113. def rms_x12(x0):
  114. x0[:pc] = x0[:pc]+x1
  115. Q_fit = getQfit(x0)
  116. return rms_base(Q_rms, Q_fit)
  117. def rms_x1(x0):
  118. Q_fit = getQfit(np.hstack((x1, x0)))
  119. return rms_base(Q_rms, Q_fit)
  120. x_fit_from_d_perp = np.array([0.09391149, 0.81234806, -0.30526326, -0.01044856,
  121. 0.3121473, 0.55333457, -0.01684191, 0.04727765,
  122. 0.11249052, 0.88368699, -0.04680872, -0.10982548])
  123. x0 = np.random.random(pc)
  124. Q_rms = Qext
  125. xfit, es = cma.fmin2(rms, x0, sigma0=2)
  126. # xfit = np.array([0.32740616895990493, -0.844352181880013, -
  127. # 0.5682552466755, 0.015925488550861087])
  128. x1 = np.copy(xfit)
  129. Qext_fit = getQfit(xfit)
  130. # print(x1)
  131. # x0 = np.random.random(pc)
  132. # # x0 = np.copy(x1)
  133. # x0 = np.hstack((x1, x0))
  134. # xfit, es = cma.fmin2(rms, x0, sigma0=0.2)
  135. # # xfit = np.array([-9.03308419e-01, -1.77584180e+00, -2.36259518e+01, 3.41837008e+00,
  136. # 5.75724471e-06, , 2.64230613e+00, , 4.72267415e+01, -1.61624064e+00])
  137. # # xfit = np.array([0.32740616895990493, -0.844352181880013, -
  138. # # 0.5682552466755, 0.015925488550861087])
  139. # x2 = np.copy(xfit)
  140. # Qext_fit = getQfit(np.hstack((x1, x2)))
  141. print(xfit)
  142. om_rat_plot = omega_ratio
  143. if isPlot:
  144. Qext_fit = getQfit(xfit)
  145. Qext_no_d = getMesoQext(R, x, m, np.zeros(len(x)))
  146. d_fit = multi_lorentzian(omega_ratio, xfit)
  147. plt.figure(fig)
  148. plt.plot(om_rat_plot, Qext_fit,
  149. label='fitted', color='gray', lw=4)
  150. plt.plot(om_rat_plot, Qext_no_d,
  151. label='d=0', color='gray', lw=4)
  152. plt.plot(om_rat_plot, Qext, label='direct', color='red', lw=1)
  153. plt.legend()
  154. # plt.yscale('log')
  155. # plt.xlim((0.4, 0.404))
  156. # plt.ylim((y_min[fig]*1.9, y_min[fig]*2.3))
  157. plt.xlim((0.4, 0.75))
  158. # plt.xlim((0.5, 0.6))
  159. # plt.ylim((y_min[fig], y_max[fig]))
  160. plt.title("Qext for R="+str(R))
  161. plt.figure("d_param "+str(fig))
  162. plt.plot(om_rat_plot, np.real(d_fit), label='re fit', lw=4)
  163. plt.plot(om_rat_plot, np.real(d_perp), label='re d_perp')
  164. plt.plot(om_rat_plot, np.imag(d_fit), label='im fit', lw=4)
  165. plt.plot(om_rat_plot, np.imag(d_perp), label='im d_perp')
  166. plt.legend()
  167. if isPlot:
  168. plt.show()
  169. # @timeit
  170. def getMesoQext(R, x, m, d_perp):
  171. Qext = np.zeros((len(x)))
  172. for i in range(len(x)):
  173. mesomie.calc_ab(R*10, # calc_ab needs R in angstrem
  174. x[i], # xd
  175. x[i] * m[i], # xm
  176. 1, # eps_d
  177. m[i] * m[i], # eps_m
  178. 0, # d_parallel
  179. d_perp[i]) # d_perp
  180. mesomie.calc_Q()
  181. Qext[i] = mesomie.GetQext()
  182. return Qext
  183. run()