Guest User

Untitled

a guest
Nov 21st, 2017
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.11 KB | None | 0 0
  1. from mpi4py import MPI
  2.  
  3. import numpy as np
  4.  
  5. import healpy as hp
  6.  
  7. import libsharp
  8.  
  9. mpi = True
  10. rank = MPI.COMM_WORLD.Get_rank()
  11.  
  12. nside = 256
  13. npix = hp.nside2npix(nside)
  14.  
  15. np.random.seed(100)
  16. input_map = np.random.normal(size=(3, npix))
  17. fwhm_deg = 10
  18. lmax = 512
  19.  
  20. nrings = 4 * nside - 1 # four missing pixels
  21.  
  22. if rank == 0:
  23. print("total rings", nrings)
  24.  
  25. n_mpi_processes = MPI.COMM_WORLD.Get_size()
  26. rings_per_process = nrings // n_mpi_processes + 1
  27. # ring indices are 1-based
  28.  
  29. ring_indices_emisphere = np.arange(2*nside, dtype=np.int32) + 1
  30. local_ring_indices = ring_indices_emisphere[rank::n_mpi_processes]
  31.  
  32. # to improve performance, simmetric rings north/south need to be in the same rank
  33. # therefore we use symmetry to create the full ring indexing
  34.  
  35. if local_ring_indices[-1] == 2 * nside:
  36. # has equator ring
  37. local_ring_indices = np.concatenate(
  38. [local_ring_indices[:-1],
  39. nrings - local_ring_indices[::-1] + 1]
  40. )
  41. else:
  42. # does not have equator ring
  43. local_ring_indices = np.concatenate(
  44. [local_ring_indices,
  45. nrings - local_ring_indices[::-1] + 1]
  46. )
  47.  
  48. print("rank", rank, "n_rings", len(local_ring_indices))
  49.  
  50. if not mpi:
  51. local_ring_indices = None
  52. grid = libsharp.healpix_grid(nside, rings=local_ring_indices)
  53.  
  54. # returns start index of the ring and number of pixels
  55. startpix, ringpix, _, _, _ = hp.ringinfo(nside, local_ring_indices.astype(np.int64))
  56.  
  57. local_npix = grid.local_size()
  58.  
  59. def expand_pix(startpix, ringpix, local_npix):
  60. """Turn first pixel index and number of pixel in full array of pixels
  61.  
  62. to be optimized with cython or numba
  63. """
  64. local_pix = np.empty(local_npix, dtype=np.int64)
  65. i = 0
  66. for start, num in zip(startpix, ringpix):
  67. local_pix[i:i+num] = np.arange(start, start+num)
  68. i += num
  69. return local_pix
  70.  
  71. local_pix = expand_pix(startpix, ringpix, local_npix)
  72.  
  73. local_map = input_map[:, local_pix]
  74.  
  75. local_hitmap = np.zeros(npix)
  76. local_hitmap[local_pix] = 1
  77. hp.write_map("hitmap_{}.fits".format(rank), local_hitmap, overwrite=True)
  78.  
  79. print("rank", rank, "npix", npix, "local_npix", local_npix, "local_map len", len(local_map), "unique pix", len(np.unique(local_pix)))
  80.  
  81. local_m_indices = np.arange(rank, lmax + 1, MPI.COMM_WORLD.Get_size(), dtype=np.int32)
  82. if not mpi:
  83. local_m_indices = None
  84.  
  85. order = libsharp.packed_real_order(lmax, ms=local_m_indices)
  86. local_nl = order.local_size()
  87. print("rank", rank, "local_nl", local_nl, "mval", order.mval())
  88.  
  89. mpi_comm = MPI.COMM_WORLD if mpi else None
  90.  
  91. # map2alm
  92. # maps in libsharp are 3D, 2nd dimension is IQU, 3rd is pixel
  93.  
  94. alm_sharp_I = libsharp.analysis(grid, order,
  95. np.ascontiguousarray(local_map[0].reshape((1, 1, -1))),
  96. spin=0, comm=mpi_comm)
  97. alm_sharp_P = libsharp.analysis(grid, order,
  98. np.ascontiguousarray(local_map[1:].reshape((1, 2, -1))),
  99. spin=2, comm=mpi_comm)
  100.  
  101. beam = hp.gauss_beam(fwhm=np.radians(fwhm_deg), lmax=lmax, pol=True)
  102.  
  103. print("Smooth")
  104. # smooth in place (zonca implemented this function)
  105. order.almxfl(alm_sharp_I, np.ascontiguousarray(beam[:, 0:1]), rank)
  106. order.almxfl(alm_sharp_P, np.ascontiguousarray(beam[:, (1, 2)]), rank)
  107.  
  108. # alm2map
  109.  
  110. new_local_map_I = libsharp.synthesis(grid, order, alm_sharp_I, spin=0, comm=mpi_comm)
  111. new_local_map_P = libsharp.synthesis(grid, order, alm_sharp_P, spin=2, comm=mpi_comm)
  112.  
  113. # Transfer map to first process for writing
  114.  
  115. local_full_map = np.zeros(input_map.shape, dtype=np.float64)
  116. local_full_map[0, local_pix] = new_local_map_I
  117. local_full_map[1:, local_pix] = new_local_map_P
  118.  
  119. output_map = np.zeros(input_map.shape, dtype=np.float64) if rank == 0 else None
  120. mpi_comm.Reduce(local_full_map, output_map, root=0, op=MPI.SUM)
  121.  
  122. if rank == 0:
  123. hp.write_map("sharp_smoothed_map.fits", output_map, overwrite=True)
  124. #hp_smoothed = hp.alm2map(hp.map2alm(input_map, lmax=lmax), nside=nside) # transform only
  125. hp_smoothed = hp.smoothing(input_map, fwhm=np.radians(fwhm_deg), lmax=lmax)
  126. print("Std of difference between libsharp and healpy", (hp_smoothed-output_map).std())
  127. hp.write_map(
  128. "healpy_smoothed_map.fits",
  129. hp_smoothed,
  130. overwrite=True
  131. )
Add Comment
Please, Sign In to add comment