/utils/radialprofile.py

http://github.com/kiyo-masui/analysis_IM · Python · 153 lines · 56 code · 36 blank · 61 comment · 2 complexity · 50f1d61fe5b694b84d25ee8226ed656c MD5 · raw file

  1. """Calculate the radial average of a 2-d image. Code stolen from:
  2. http://www.astrobetter.com/wiki/tiki-index.php?page=python_radial_profiles
  3. and modified to crudely have a controllable bin width.
  4. """
  5. import numpy as np
  6. def azimuthalAverage(image, center=None, bw = 3):
  7. """
  8. Calculate the azimuthally averaged radial profile.
  9. Parameters
  10. ----------
  11. image : np.ndarray
  12. The 2D image.
  13. center : array_like, optional
  14. The [x,y] pixel coordinates used as the center. The default is
  15. None, which then uses the center of the image (including
  16. fractional pixels).
  17. Returns
  18. -------
  19. bl : np.ndarray
  20. The lower limit of the bin radius.
  21. radial_prof : np.ndarray
  22. The radial averaged profile.
  23. """
  24. # Calculate the indices from the image
  25. y, x = np.indices(image.shape)
  26. if not center:
  27. center = np.array([(x.max()-x.min())/2.0, (y.max()-y.min())/2.0])
  28. r = np.hypot(x - center[0], y - center[1])
  29. # Get sorted radii
  30. maxr = np.array([image.shape[0] - center[0], image.shape[1] - center[1]]).min()
  31. ind = np.argsort(r.flat)
  32. r_sorted = r.flat[ind]
  33. i_sorted = image.flat[ind]
  34. maxind = np.searchsorted(r_sorted, maxr+0.00001)
  35. r_sorted = r_sorted[:maxind]
  36. i_sorted = i_sorted[:maxind]
  37. numbins = int(maxr / bw)
  38. maxr = numbins * bw
  39. bn = np.linspace(0.0, maxr, numbins+1)
  40. bc = 0.5*(bn[1:] + bn[:-1])
  41. bl = bn[:-1]
  42. # Get the integer part of the radii (bin size = 1)
  43. #r_int = r_sorted.astype(int)
  44. r_int = np.digitize(r_sorted, bn)
  45. # Find all pixels that fall within each radial bin.
  46. deltar = r_int[1:] - r_int[:-1] # Assumes all radii represented
  47. #pdb.set_trace()
  48. rind = np.where(deltar)[0] # location of changed radius
  49. rind = np.insert(rind, 0, -1)
  50. nr = rind[1:] - rind[:-1] # number of radius bin
  51. # Cumulative sum to figure out sums for each radius bin
  52. csim = np.cumsum(i_sorted, dtype=image.dtype)
  53. csim = np.insert(csim, 0, 0.0)
  54. tbin = csim[rind[1:]+1] - csim[rind[:-1]+1]
  55. radial_prof = tbin / nr
  56. return bl, radial_prof
  57. def azimuthalAverage_nd(image, center=None, bw = 3):
  58. """
  59. Calculate the azimuthally averaged radial profile.
  60. Parameters
  61. ----------
  62. image : np.ndarray
  63. The 2D image.
  64. center : array_like, optional
  65. The [x,y] pixel coordinates used as the center. The default is
  66. None, which then uses the center of the image (including
  67. fractional pixels).
  68. Returns
  69. -------
  70. bl : np.ndarray
  71. The lower limit of the bin radius.
  72. radial_prof : np.ndarray
  73. The radial averaged profile.
  74. """
  75. # Calculate the indices from the image
  76. ia = np.indices(image.shape)
  77. ia = np.rollaxis(ia, 0, ia.ndim)
  78. if not center:
  79. center = (np.array(image.shape) - 1.0) / 2.0
  80. r = np.sum((ia - center)**2, axis=-1)**0.5
  81. # Get sorted radii
  82. #maxr = np.array([image.shape[0] - center[0], image.shape[1] - center[1]]).min()
  83. maxr = (np.array(image.shape) - center).min()
  84. ind = np.argsort(r.flat)
  85. r_sorted = r.flat[ind]
  86. i_sorted = image.flat[ind]
  87. maxind = np.searchsorted(r_sorted, maxr+0.00001)
  88. r_sorted = r_sorted[:maxind]
  89. i_sorted = i_sorted[:maxind]
  90. numbins = int(maxr / bw)
  91. maxr = numbins * bw
  92. bn = np.linspace(0.0, maxr, numbins+1)
  93. bc = 0.5*(bn[1:] + bn[:-1])
  94. bl = bn[:-1]
  95. # Get the integer part of the radii (bin size = 1)
  96. #r_int = r_sorted.astype(int)
  97. r_int = np.digitize(r_sorted, bn)
  98. # Find all pixels that fall within each radial bin.
  99. deltar = r_int[1:] - r_int[:-1] # Assumes all radii represented
  100. #pdb.set_trace()
  101. rind = np.where(deltar)[0] # location of changed radius
  102. rind = np.insert(rind, 0, -1)
  103. nr = rind[1:] - rind[:-1] # number of radius bin
  104. # Cumulative sum to figure out sums for each radius bin
  105. csim = np.cumsum(i_sorted, dtype=image.dtype)
  106. csim = np.insert(csim, 0, 0.0)
  107. tbin = csim[rind[1:]+1] - csim[rind[:-1]+1]
  108. radial_prof = tbin / nr
  109. return bl, radial_prof