def map2minfo(m): """Given an enmap with constant-latitude rows and constant longitude intervals, return a corresponding sharp map_info.""" theta = np.pi/2 - m[...,:,:1].posmap()[0,:,0] # Slice to make calculation faster. Could have just queried m.wcs cirectly here # instead. Offset by 1 away from bottom to avoid any pole-related problems. phi0 = m[...,1:2,0:1].posmap()[1,0,0] nphi = m.shape[-1] return sharp.map_info(theta, nphi, phi0)
def match_predefined_minfo(m, rtol=None, atol=None): """Given an enmapwith constant-latitude rows and constant longitude intervals, return the libsharp predefined minfo with ringweights that's the closest match to our pixelization.""" if rtol is None: rtol = 1e-3*utils.arcmin if atol is None: atol = 1.0*utils.arcmin # Make sure the colatitude ascends flipy = m.wcs.wcs.cdelt[1] > 0 if flipy: m = m[...,::-1,:] theta = np.pi/2 - m[...,:,:1].posmap()[0,:,0] phi0 = m[...,1:2,0:1].posmap()[1,0,0] ntheta, nphi = m.shape[-2:] # First find out how many lat rings there are in the whole sky. # Find the first and last pixel center inside bounds y1 = int(np.round(m.sky2pix([np.pi/2,0])[0])) y2 = int(np.round(m.sky2pix([-np.pi/2,0])[0])) phi0 = m.pix2sky([0,0])[1] ny = utils.nint(y2-y1+1) nx = utils.nint(np.abs(360./m.wcs.wcs.cdelt[0])) # Define our candidate pixelizations minfos = [] for i in range(-1,2): #minfos.append(sharp.map_info_gauss_legendre(ny+i, nx, phi0)) minfos.append(sharp.map_info_clenshaw_curtis(ny+i, nx, phi0)) minfos.append(sharp.map_info_fejer1(ny+i, nx, phi0)) minfos.append(sharp.map_info_fejer2(ny+i, nx, phi0)) minfos.append(sharp.map_info_mw(ny+i, nx, phi0)) # For each pixelization find the first ring in the map aroffs, scores, minfos2 = [], [], [] for minfo in minfos: # Find theta closest to our first theta i1 = np.argmin(np.abs(theta[0]-minfo.theta)) # If we're already on the full sky, the the +1 # pixel alternative will not work. if i1+len(theta) > minfo.theta.size: continue # Find the largest theta offset for all y in our input map offs = theta-minfo.theta[i1:i1+len(theta)] aoff = np.max(np.abs(offs)) # Find the largest offset after applying a small pointing offset roff = np.max(np.abs(offs-np.mean(offs))) aroffs.append([aoff,roff,i1]) scores.append(aoff/atol + roff/rtol) minfos2.append(minfo) # Choose the one with the lowest score (lowest mismatch) best = np.argmin(scores) aoff, roff, i1 = aroffs[best] i2 = i1+ntheta if not aoff < atol: raise ShapeError("Could not find a map_info with predefined weights matching input map (abs offset %e >= %e)" % (aoff, atol)) if not roff < rtol: raise ShapeError("Could not find a map_info with predefined weights matching input map (%rel offset e >= %e)" % (aoff, atol)) minfo = minfos2[best] # Modify the minfo to restrict it to only the rows contained in m minfo_cut = sharp.map_info( minfo.theta[i1:i2], minfo.nphi[i1:i2], minfo.phi0[i1:i2], minfo.offsets[i1:i2]-minfo.offsets[i1], minfo.stride[i1:i2], minfo.weight[i1:i2]) if flipy: # Actual map is flipped in y relative to the one we computed the map info minfo_cut = sharp.map_info( minfo_cut.theta[::-1], minfo_cut.nphi[::-1], minfo_cut.phi0[::-1], minfo_cut.offsets[:], minfo_cut.stride[:], minfo_cut.weight[::-1]) # Phew! Return the result return minfo_cut