utility.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. """
  2. @Author: F. Paul Spitzner
  3. @Email: paul.spitzner@ds.mpg.de
  4. @Created: 2020-01-21
  5. @Last Modified: 2020-01-21
  6. @Description:
  7. Helper functions to load and plot the preprocessed hdf5 files containing
  8. correlation coefficients.
  9. """
  10. import numpy as np
  11. import mrestimator as mre
  12. import h5py
  13. def h5_load(filename, dsetname, raise_ex=False):
  14. try:
  15. file = h5py.File(filename, "r")
  16. try:
  17. res = file[dsetname][:]
  18. # maybe it is a scalar
  19. except ValueError:
  20. res = file[dsetname][()]
  21. file.close()
  22. return res
  23. except Exception as e:
  24. print(f"failed to load {dsetname} from {filename}: {e}")
  25. if raise_ex:
  26. raise e
  27. # draw an arrow at specified side
  28. def arrowed_spines(ax, side="bottom", **ap):
  29. # ap = dict(arrowstyle="->", fc="k", ec="k", connectionstyle="arc3",
  30. # shrinkA=0, shrinkB=0, lw=1, mutation_scale=5)
  31. ap.setdefault("arrowstyle", "->")
  32. ap.setdefault("fc", "k")
  33. ap.setdefault("ec", "k")
  34. ap.setdefault("connectionstyle", "arc3")
  35. ap.setdefault("shrinkA", 0)
  36. ap.setdefault("shrinkB", 0)
  37. ap.setdefault("lw", 1)
  38. ap.setdefault("mutation_scale", 7)
  39. cs = dict(xycoords="axes fraction", textcoords="axes fraction", zorder=20)
  40. for s in side:
  41. if s == "bottom":
  42. ax.annotate("", xy=(0, 1), xytext=(0, 0), **cs, arrowprops=ap)
  43. elif s == "left":
  44. ax.annotate("", xy=(1, 0), xytext=(0, 0), **cs, arrowprops=ap)
  45. elif s == "top":
  46. ax.annotate("", xy=(1, 1), xytext=(0, 1), **cs, arrowprops=ap)
  47. elif s == "right":
  48. ax.annotate("", xy=(1, 1), xytext=(1, 0), **cs, arrowprops=ap)
  49. # other option, way more complicated, modified:
  50. # https://stackoverflow.com/questions/33737736/matplotlib-axis-arrow-tip
  51. # hl = 1./20.*(xmax-xmin) / width
  52. def plot_stdd(ax, x, y_mean, y_stdd, mode="bar", eb_ls='-', **kwargs):
  53. if mode=="fill":
  54. if "alpha" not in kwargs:
  55. kwargs = dict(kwargs, alpha=0.1)
  56. if "lw" not in kwargs:
  57. kwargs = dict(kwargs, lw=0)
  58. ax.fill_between(
  59. x,
  60. (y_mean - y_stdd),
  61. (y_mean + y_stdd),
  62. **kwargs
  63. )
  64. elif mode=="bar":
  65. eb = ax.errorbar(x, y_mean, yerr=y_stdd, fmt='o', markersize=0, capsize=2, capthick=0.5, lw=0.5, **kwargs)
  66. try:
  67. eb[-1][0].set_linestyle(eb_ls)
  68. except Exceptions as e:
  69. print(e)
  70. # find_prec(arr, "312.62", ".2f")
  71. def find_prec(arr, expr, ptrn):
  72. for idx, i in enumerate(arr):
  73. if "{i:{ptrn}}".format(i=i, ptrn=ptrn) == expr:
  74. return idx
  75. return -1
  76. # bias corrected solution by Marriott and Pope
  77. def rk_analytic_408(k_max, m, numsteps):
  78. k_range = np.arange(1, int(k_max + 1))
  79. return np.power(m, k_range) - 2 * k_range * np.power(m, k_range) / numsteps
  80. def rk_analytic_407(k_max, m, numsteps):
  81. k_range = np.arange(1, int(k_max + 1))
  82. geom = np.zeros(k_max)
  83. for idx, k in enumerate(k_range):
  84. # print(f"{idx} {k}")
  85. # print(f"\t{np.power(m, k_range[:k]-1)}")
  86. geom[idx] = np.sum(np.power(m, k_range[:k] - 1))
  87. res = np.power(m, k_range) - 1.0 / numsteps * (
  88. (1 + m) * geom - 2 * k_range * np.power(m, k_range) / numsteps
  89. )
  90. return res
  91. def tau_est_over_tau_407(tau, targetlength, k_max, fdx=0):
  92. # targetlength will be multiplied by tau
  93. m = np.exp(-1.0 / tau)
  94. k_range = np.arange(1, k_max + 1)
  95. res = np.zeros(len(targetlength))
  96. for idx, T in enumerate(targetlength):
  97. print(f"{T}/{targetlength[-1]}")
  98. rks = rk_analytic_407(k_max, m, T * tau)
  99. rks = mre.CoefficientResult(steps=k_range, coefficients=rks)
  100. res[idx] = mre.fit(rks, fitfunc=fitfuncs[fdx]).tau / tau
  101. return res
  102. def tau_est_over_tau_408(tau, targetlength, k_max, fdx=0):
  103. # targetlength will be multiplied by tau
  104. m = np.exp(-1.0 / tau)
  105. k_range = np.arange(1, k_max + 1)
  106. res = np.zeros(len(targetlength))
  107. for idx, T in enumerate(targetlength):
  108. print(f"{T}/{targetlength[-1]}")
  109. rks = rk_analytic_408(k_max, m, T * tau)
  110. rks = mre.CoefficientResult(steps=k_range, coefficients=rks)
  111. res[idx] = mre.fit(rks, fitfunc=fitfuncs[fdx]).tau / tau
  112. return res