def apply_apod(div): if apod_params is None: return div weight = div.preflat[0] moo = enmap.downgrade(weight, 50) maxval = np.max(enmap.downgrade(weight, 50)) apod = np.minimum(1, weight / maxval / apod_params[0])**apod_params[1] return div * apod
def build_foreground_var(maps, bsize1=8, bsize2=4, scale=0.5): """Given maps[ncomp,ny,nx] that may contain point sources etc., return an estimate of the foreground variance. This can be used to downweight high-foreground regions.""" vbox = np.array([[-32, -88], [-31, -90]]) * utils.degree # Can't use op=np.var here because downgrade does the operation in two steps v1 = enmap.downgrade(maps**2, bsize1, op=np.mean, inclusive=True) v1 -= enmap.downgrade(maps, bsize1, op=np.mean, inclusive=True)**2 v2 = enmap.downgrade(v1, bsize2, op=np.median, inclusive=True) for v in v2: v[v == 0] = np.median(v[v != 0]) res = np.exp(enmap.project(np.log(v2), maps.shape, maps.wcs, order=1)) res *= scale return res
def load_survey_mask(qid, dg=2): # load survey mask mask = load_survey_mask_core(qid) mask_dg = enmap.downgrade(mask, dg) return mask_dg
def high_res_plot_img(array, filename=None, down=None, verbose=True, overwrite=True, crange=None, cmap="planck"): if not (overwrite): if os.path.isfile(filename): return try: from pixell import enmap, enplot except: traceback.print_exc() cprint( "Could not produce plot " + filename + ". High resolution plotting requires enlib, which couldn't be imported. Continuing without plotting.", color='fail') return if (down is not None) and (down != 1): downmap = enmap.downgrade(enmap.enmap(array)[None], down) else: downmap = enmap.enmap(array)[None] img = enplot.draw_map_field(downmap, enplot.parse_args("-c " + cmap + " -vvvg moo"), crange=crange) #img = enplot.draw_map_field(downmap,enplot.parse_args("--grid 1"),crange=crange) if filename is None: img.show() else: img.save(filename) if verbose: print(bcolors.OKGREEN + "Saved high-res plot to", filename + bcolors.ENDC)
def smooth_downup(map, n): n = np.minimum(n, map.shape[-2:]) o = (np.array(map.shape[-2:]) % n) // 2 return enmap.upgrade(enmap.downgrade(map, n, off=o, inclusive=True), n, off=o, oshape=map.shape, inclusive=True)
def plot(fname,imap,dg=4,grid=False,**kwargs): from orphics import io img = enplot.plot(enmap.downgrade(imap,dg),grid=grid,**kwargs) if fname is None: enplot.show(img) else: enplot.write(fname,img) print(io.bcolors.OKGREEN+"Saved high-res plot to", fname+io.bcolors.ENDC)
def load_map(version): box = np.asarray([[-10, -10], [10, 10]]) * u.degree imaps = [] ivars = [] for i in range(2): if version == 'v18': fname = f"/scratch/r/rbond/msyriac/data/planck/data/hybrid/planck_hybrid_545_2way_{i}_map.fits" ifname = fname = f"/scratch/r/rbond/msyriac/data/planck/data/hybrid/planck_hybrid_545_2way_{i}_ivar.fits" elif version == 'v20': fname = f"/home/r/rbond/sigurdkn/project/actpol/planck/npipe/car_equ/planck_npipe_545_split{i+1}_map.fits" ifname = f"/home/r/rbond/sigurdkn/project/actpol/planck/npipe/car_equ/planck_npipe_545_split{i+1}_ivar.fits" p18 = enmap.downgrade( enmap.read_map(fname, box=box, sel=np.s_[0, ...]), 4) ip18 = enmap.downgrade(enmap.read_map(ifname, box=box, sel=np.s_[0, ...]), 4, op=np.sum) print(p18.shape, ip18.shape) return p18
def save_maps(hmap, root_name, telescope): for res in resolutions[telescope]: shape, wcs = get_geometry(res, bounds_deg=bounds[telescope]) imap = ivar_hp_to_cyl(hmap, shape, wcs) if comm.rank == 0: oname = cr_remote_data.get_local_output( f"{root_name}_CAR_{res:.2f}_arcmin.fits") enmap.write_map(oname, imap) os.system(f"gzip -f {oname}") plots = enplot.get_plots(enmap.downgrade(imap, 8)) savename = cr_remote_data.get_local_output( f"rmap_{root_name}_{res:.2f}") enplot.write(savename, plots) print(f"Plot saved to {savename}")
def smooth(m): ''' Local smoothing of input map. Parameters ---------- m : enmap Input map Returns ------- m_smoothed : enmap Output map with same shape as input. ''' m_smoothed = enmap.downgrade(m, 2) m_smoothed = enmap.project(m_smoothed, m.shape, m.wcs, order=1) return m_smoothed
def get_ivar(qid, mask, dg=2): # First, read survey parameters from qid model, season, array, patch, freq = local.qid_info(qid[0]) # Day time data if model == 'dr5': dm = interfaces.models['dr5'](region=mask) ivars = enmap.enmap([dm.get_ivars(q, calibrated=True) for q in qid]) # Night time data if model == 'act_mr3': dm = interfaces.models['act_mr3'](region=mask, calibrated=True) ivars = dm.get_splits_ivar(season=season, patch=patch, arrays=dm.array_freqs[array]) # downgrade ivars = enmap.downgrade(ivars, dg) return ivars
def coadd_real_data(qid, mask, dg=2): # Compute coadded map by simply summing up each split with the inverse variance weight assert mask.ndim == 2 # First, read survey parameters from qid model, season, array, patch, freq = local.qid_info(qid[0]) # Day time data if model == 'dr5': dm = interfaces.models['dr5'](region=mask) datas = enmap.enmap([dm.get_splits(q, calibrated=True) for q in qid]) ivars = enmap.enmap([dm.get_ivars(q, calibrated=True) for q in qid]) # Night time data if model == 'act_mr3': dm = interfaces.models['act_mr3'](region=mask, calibrated=True) datas = dm.get_splits(season=season, patch=patch, arrays=dm.array_freqs[array], srcfree=True) ivars = dm.get_splits_ivar(season=season, patch=patch, arrays=dm.array_freqs[array]) # coadded map civars = np.average(ivars, axis=1) civars[civars == 0] = np.inf map_c = mask[None, None, :, :] * np.average(datas * ivars, axis=1) / civars / local.Tcmb # downgrade map_c = enmap.downgrade(map_c, dg) # check assert map_c.ndim == 4 return map_c
def bounded_pix(imap, threadhold=None, threshold_factor=1., sigma=None, downsample=None, verbose=False): shape, wcs = imap.shape, imap.wcs template = imap.copy() if sigma: # smooth the input if necessary template = scipy.ndimage.gaussian_filter(template, sigma=sigma) template = enmap.enmap(template, wcs=wcs) if downsample: # downsample maps to speed up the search process if verbose: print("downsampling by a factor of %d" % downsample) template = enmap.downgrade(template, factor=downsample) loc = np.where(template != 0.) if not threadhold: threadhold = template.mean() loc = np.where(template > threadhold * threshold_factor) binary_map = template * 0. binary_map[loc] = 1. del template # get pix for the bounded region _, pix = misc.max_size(binary_map, value=1., verbose=verbose) # if the input map was downsampled, we need to map pixels at low resolutions to those at higher resolution if downsample: ll_pix = imap.sky2pix(binary_map.pix2sky([pix[0], pix[2]])) ur_pix = imap.sky2pix(binary_map.pix2sky([pix[1], pix[3]])) pix = np.array([ll_pix[0], ur_pix[0], ll_pix[1], ur_pix[1]]).astype(int) return pix
""" Given the mask saved from mapcat.py, generate and save a random catalog. """ paths = cutils.paths #cat_type = "wise_panstarrs" #cat_type = "madcows_photz" cat_type = args.sys[1] Nx = int(args.sys[2]) ras,decs,_,_,_ = cutils.catalog_interface(cat_type,is_meanfield=False) N = Nx * len(ras) mask = enmap.read_map(f'{paths.scratch}{cat_type}_mask.fits') shape,wcs = mask.shape,mask.wcs Npix = mask[mask>0].size inds = np.random.choice(Npix,size=N,replace=False) pixs = enmap.pixmap(shape,wcs) print(pixs.shape) coords = mask.pix2sky(pixs[:,mask>0][:,inds]) / utils.degree io.save_cols(paths.data+f"{cat_type}_randoms.txt",(coords[1],coords[0])) print(coords.shape) cmapper = catalogs.CatMapper(coords[1],coords[0],shape=shape,wcs=wcs) io.hplot(enmap.downgrade(cmapper.counts,16),'randcounts',mask=0)
os.path.split(mapdir)[1])) hitmap = enmap.read_map(opj(mapdir, 'hits.fits')) cutmap = enmap.read_map(opj(mapdir, 'cuts.fits')) ratio = cutmap.copy() ratio[hitmap == 0] *= 0 ratio[hitmap != 0] /= hitmap[hitmap != 0] if args.signal_map is not None: freq = [x for x in mapdir.split('_') if x.startswith('f')][0] signal_map = args.signal_map if len(signal_map) == 1: signal_map = signal_map[0] signal = read_signal_map(signal_map, freq, ratio.shape, ratio.wcs) signal = enmap.downgrade(signal, args.downgrade) hitmap = enmap.downgrade(hitmap, args.downgrade) cutmap = enmap.downgrade(cutmap, args.downgrade) ratio = enmap.downgrade(ratio, args.downgrade) ratio[hitmap == 0] = np.nan plot = enplot.plot(hitmap, **plot_opts) enplot.write(opj(mapdir, 'hits'), plot) plot = enplot.plot(cutmap, **plot_opts) enplot.write(opj(mapdir, 'cuts'), plot) plot = enplot.plot(ratio, min=0, max=args.range, **plot_opts) enplot.write(opj(mapdir, 'ratio'), plot)
def combine_tiles(ipathfmt, opathfmt, combine=2, downsample=2, itile1=(None, None), itile2=(None, None), tyflip=False, txflip=False, pad_to=None, comm=None, verbose=False): """Given a set of tiles on disk at locaiton ipathfmt % {"y":...,"x"...}, combine them into larger tiles, downsample and write the result to opathfmt % {"y":...,"x":...}. x and y must be contiguous and start at 0. reftile[2] indicates the tile coordinates of the first valid input tile. This needs to be specified if not all tiles of the logical tiling are physically present. tyflip and txflip indicate if the tiles coordinate system is reversed relative to the pixel coordinates or not." """ # Expand combine and downsample to 2d combine = np.zeros(2, int) + combine downsample = np.zeros(2, int) + downsample if pad_to is not None: pad_to = np.zeros(2, int) + pad_to # Handle optional mpi rank, size = (comm.rank, comm.size) if comm is not None else (0, 1) # Find the range of input tiles itile1, itile2 = find_tile_range(ipathfmt, itile1, itile2) # Read the first tile to get its size information ibase = enmap.read_map(ipathfmt % {"y": itile1[0], "x": itile1[1]}) * 0 # Find the set of output tiles we need to consider otile1 = itile1 // combine otile2 = (itile2 - 1) // combine + 1 # And loop over them oyx = [(oy, ox) for oy in range(otile1[0], otile2[0]) for ox in range(otile1[1], otile2[1])] for i in range(rank, len(oyx), size): oy, ox = oyx[i] # Read in all associated tiles into a list of lists rows = [] for dy in range(combine[0]): iy = oy * combine[0] + dy if iy >= itile2[0]: continue cols = [] for dx in range(combine[1]): ix = ox * combine[1] + dx if ix >= itile2[1]: continue if iy < itile1[0] or ix < itile1[1]: # The first tiles are missing on disk, but are # logically a part of the tiling. Use ibase, # which has been zeroed out. cols.append(ibase) else: itname = ipathfmt % {"y": iy, "x": ix} cols.append(enmap.read_map(itname)) if txflip: cols = cols[::-1] rows.append(cols) # Stack them next to each other into a big tile if tyflip: rows = rows[::-1] omap = enmap.tile_maps(rows) # Downgrade if necessary if np.any(downsample > 1): omap = enmap.downgrade(omap, downsample) if pad_to is not None: # Padding happens towards the end of the tiling, # which depends on the flip status padding = np.array( [[0, 0], [pad_to[0] - omap.shape[-2], pad_to[1] - omap.shape[-1]]]) if tyflip: padding[:, 0] = padding[::-1, 0] if txflip: padding[:, 1] = padding[::-1, 1] omap = enmap.pad(omap, padding) # And output otname = opathfmt % {"y": oy, "x": ox} utils.mkdir(os.path.dirname(otname)) enmap.write_map(otname, omap) if verbose: print(otname)
imap = enmap.rand_map(shape, wcs, np.ones((1, 1, shape[0], shape[1]))) ta = tiling.TiledAnalysis(shape, wcs, comm) ta.initialize_output("out") for ext, ins in ta.tiles(): emap = ext(imap) emap = filter_map(emap) ta.update_output("out", emap, ins) outmap = ta.get_final_output("out") # print(comm.rank) # io.plot_img(outmap,"rank_%d" % comm.rank) if comm.rank == 0: fcmap = filter_map(imap) io.hplot(enmap.downgrade(imap, 8)) io.hplot(enmap.downgrade(outmap, 8)) io.hplot(enmap.downgrade(fcmap, 8)) io.plot_img(enmap.downgrade(outmap - fcmap, 8), lim=1) # brmap = enmap.zeros(observed.shape[-2:],observed.wcs) # bwrmap = enmap.zeros(observed.shape[-2:],observed.wcs) # shape,wcs = observed.shape,observed.wcs # epboxes = get_pixboxes(shape,wcs,width_deg,pad_deg) # pboxes = get_pixboxes(shape,wcs,width_deg,pad_deg-2.*rtap_deg) # for i in range(pboxes.shape[0]): # for j in range(pboxes.shape[1]): # omap = observed.copy() # #print(npix(pboxes[i,j])) # emap = enmap.extract_pixbox(omap,epboxes[i,j],wrap=shape[-2:]) # print("Min ell: ", maps.minimum_ell(emap.shape,emap.wcs))
random = True cversion = 'joint' region = 'deep56' fname = os.environ['WORK'] + "/data/boss/eboss_dr14/data_DR14_QSO_S.fits" cols = catalogs.load_fits(fname, ['RA', 'DEC']) ras = cols['RA'] decs = cols['DEC'] sns = np.array(ras) * 0 + 6 tdir = '/scratch/r/rbond/msyriac/data/depot/tilec/v1.0.0_rc_20190919' mask = sints.get_act_mr3_crosslinked_mask(region) bmask = mask.copy() bmask[bmask < 0.99] = 0 io.hplot(enmap.downgrade(bmask, 4), "fig_qso_bmask") solution = 'tsz' bfile = tutils.get_generic_fname(tdir, region, 'cmb', None, 'act', beam=True) yfile = tutils.get_generic_fname(tdir, region, 'cmb', None, 'act') bfile2 = tutils.get_generic_fname(tdir, region, 'cmb', None, 'planck', beam=True) yfile2 = tutils.get_generic_fname(tdir, region, 'cmb', None, 'planck') cmap = enmap.read_map(yfile2)
outdir = opj(args.odir, subdir) utils.mkdir(outdir) freq = get_freq(subdir) print('[rank {:03d}]: reading maps'.format(rank)) mask = enmap.read_map(opj(args.sdir, subdir, 'hits.fits')) ratio = enmap.read_map(opj(args.sdir, subdir, 'cuts.fits')) signal_map = args.signal_map if len(signal_map) == 1: signal_map = signal_map[0] signal = read_signal_map(signal_map, freq, ratio.shape, ratio.wcs) print('[rank {:03d}]: processing maps'.format(rank)) if args.downgrade != 1: signal = enmap.downgrade(signal, args.downgrade) mask = enmap.downgrade(mask, args.downgrade) ratio = enmap.downgrade(ratio, args.downgrade) ratio[mask == 0] *= 0 ratio[mask != 0] /= mask[mask != 0] mask[mask != 0] = 1. ratio = smooth(ratio) mask = maptools.apod_C2(mask, 0.2) namap_cut = nw.namap_car(maps=(ratio, None, None), masks=mask) namap_sig = nw.namap_car(maps=(signal, None, None), masks=mask) bins = nw.create_binning(lmax=args.lmax, lmin=2, widths=50)
def generate_map(qids, overwrite=False, verbose=True, dg=2, **kwargs): # Here we compute the real coadd map and simulated maps from the noise covariance and pre-computed fullsky signal # This function uses actsims "simgen" code for qid in qids: if qid in ['boss_d04', 's16_d03', 'boss_04']: # Here, the simulation is performed for each array, not frequency, to take into account their correlation # For pa3, there are two frequency bands if verbose: print('skip ' + qid + ': the map is generated by running f090 case.') continue if '_d0' in qid: version = 'v6.3.0_calibrated_mask_version_masks_20200723' else: version = 'v6.3.0_calibrated_mask_version_padded_v1' # define qid_array to take into account multi-frequency case if qid == 'boss_d03': qid_array = ['boss_d03', 'boss_d04'] elif qid == 's16_d02': qid_array = ['s16_d02', 's16_d03'] elif qid == 'boss_03': qid_array = ['boss_03', 'boss_04'] else: # single frequency case qid_array = [qid] # define filename aobj = { q: local.init_analysis_params(qid=q, **kwargs) for q in qid_array } # load survey mask mask = load_survey_mask(qid, dg=1) # Define an object for sim generation model, season, array, patch, freq = local.qid_info(qid) if model == 'dr5': simobj = simgen.SimGen(version=version, qid=qid_array, model=model) if model == 'act_mr3': simobj = simgen.SimGen(version=version, model=model) # save 1/var map if not misctools.check_path(aobj[qid_array[0]].fivar, overwrite=overwrite, verbose=verbose): ivars = get_ivar(qid_array, mask) civars = np.average(ivars, axis=1) # coadd ivar for qi, q in enumerate(qid_array): enmap.write_map(aobj[q].fivar, civars[qi, :, :, :]) # loop over realizations for i in tqdm.tqdm(aobj[qid].rlz): if misctools.check_path(aobj[qid].fmap['s'][i], overwrite=overwrite, verbose=verbose): continue # maps will have signal ('s') and noise ('n') and each has [Nfreq, NTPol, Coord1, Coord2] maps = {} # real data if i == 0: # take coadd data maps['s'] = coadd_real_data(qid_array, mask) # SZ map subtraction shape, wcs = maps['s'][0, 0, :, :].shape, maps['s'].wcs if q in [ 'boss_d03', 's16_d02', 'boss_03' ]: # need both freqs for combined data array of two freqs sz_map_090 = enmap.project( enmap.read_map( 'data_local/input/S18d_202006_confirmed_model_f090.fits' ), shape, wcs) / local.Tcmb sz_map_150 = enmap.project( enmap.read_map( 'data_local/input/S18d_202006_confirmed_model_f150.fits' ), shape, wcs) / local.Tcmb maps['s'][0, 0, :, :] -= sz_map_090 maps['s'][1, 0, :, :] -= sz_map_150 else: sz_map = enmap.project( enmap.read_map( 'data_local/input/S18d_202006_confirmed_model_f150.fits' ), shape, wcs) / local.Tcmb maps['s'][0, 0, :, :] -= sz_map # simulation else: maps['s'], maps['n'], ivars = simobj.get_sim(season, patch, array, sim_num=i, set_idx=0) # coadd with civars weight implicitly multiplied civars = np.average(ivars, axis=1) civars[civars == 0] = np.inf maps['s'] = mask[None, None, :, :] * np.average( maps['s'] * ivars, axis=1) / civars / local.Tcmb maps['n'] = mask[None, None, :, :] * np.average( maps['n'] * ivars, axis=1) / civars / local.Tcmb # downgrade maps['s'] = enmap.downgrade(maps['s'], dg) maps['n'] = enmap.downgrade(maps['n'], dg) # save signal and noise to files for s in ['s', 'n']: if s == 'n' and i == 0: continue # real data is saved to a signal file for qi, q in enumerate(qid_array): enmap.write_map(aobj[q].fmap[s][i], maps[s][qi, :, :, :])
import numpy as np from pixell import enmap, utils, enplot m1 = enmap.read_map("/scratch/r/rbond/msyriac/data/for_sigurd/planck_353.fits") m2 = enmap.read_map( "/scratch/r/rbond/msyriac/data/for_sigurd/mask_boss.fits", geometry=m1.geometry) + enmap.read_map( "/scratch/r/rbond/msyriac/data/for_sigurd/mask_deep56.fits", geometry=m1.geometry) print(m1.wcs) print(m2.wcs) off = [0, 1000] m1s = enmap.shift(enmap.downgrade(m1, 10), off) m2s = enmap.shift(enmap.downgrade(m2, 10), off) p1 = enplot.plot(m1s, min=500, max=1e4, color="cooltowarm", ticks="10", layers=True, font_size=50, contour_color='ffffff') p2 = enplot.plot(m2s, min=0, max=1, ticks="10", layers=True,
def pshow(cov,fname=None): io.hplot(np.log10(enmap.downgrade(enmap.enmap(np.fft.fftshift(cov),cov.wcs),2)),fname) """
args = parser.parse_args() geoms = load_geometries(qids) pshape, pwcs = load_geometries([parent_qid])[parent_qid] # mask = sints.get_act_mr3_crosslinked_mask("deep56") # pshape,pwcs = mask.shape,mask.wcs ta = tiling.TiledAnalysis(pshape, pwcs, comm=comm, width_deg=4., pix_arcmin=0.5) for solution in solutions: ta.initialize_output(name=solution) down = lambda x, n=2: enmap.downgrade(x, n) if args.dtiles is not None: dtiles = [int(x) for x in args.dtiles.split(',')] else: dtiles = [] for i, extracter, inserter, eshape, ewcs in ta.tiles( from_file=True): # this is an MPI loop # What is the shape and wcs of the tile? is this needed? aids = [] kdiffs = [] ksplits = [] kcoadds = [] masks = [] lmins = []
import os, sys from pixell import enmap from orphics import io tdir = '/scratch/r/rbond/msyriac/data/depot/tilec/v1.0.0_rc_20190919' def get_tsz_map(): pass for region in ['deep56', 'boss']: for dcomb in ['joint', 'act', 'planck']: for solution in ['cmb', 'tsz']: for deproj in [None, 'cib'] + [{ 'cmb': 'tsz', 'tsz': 'cmb' }[solution]]: fname = tutils.get_generic_fname(tdir, region, solution, deproj, dcomb) imap = enmap.downgrade(enmap.read_map(fname), 4) bname = 'plot_' + os.path.basename(fname).replace('.fits', '') io.hplot(imap, bname, grid=True, color={ 'cmb': 'planck', 'tsz': 'gray' }[solution]) #print(os.path.basename(fname))
seed = (0,0,task+sindex) # If debugging, get unfiltered maps and plot Cls if task==0 and debug_cmb: t_alm,e_alm,b_alm = solint.get_kmap(channel,seed,lmin,lmax,filtered=False) tcl = hp.alm2cl(t_alm) ls = np.arange(tcl.size) pl = io.Plotter('Cell') pl.add(ls,tcl/w2) ls2,nells,nells_P = solint.get_noise_power(channel,beam_deconv=True) theory = cosmology.default_theory() pl.add(ls,theory.lCl('TT',ls) + maps.interp(ls2,nells)(ls),color='k') pl._ax.set_xlim(1,6000) pl._ax.set_ylim(1e-6,1e3) pl.done(f'{solenspipe.opath}/tcl.png') imap = enmap.downgrade(solint.alm2map(np.asarray([t_alm,e_alm,b_alm]),ncomp=3) * maps.binary_mask(mask),2) for i in range(3): io.hplot(imap[i],f'{solenspipe.opath}/imap_{i}',mask=0) with bench.show("sim"): # Get simulated, prepared filtered T, E, B maps, i.e. (1/(C+N) * teb_alm) t_alm,e_alm,b_alm = solint.get_kmap(channel,seed,lmin,lmax,filtered=True) # Get the reconstructed kappa map alms and filter it with the normalization recon_alms = qe.filter_alms(solint.get_mv_kappa(polcomb,t_alm,e_alm,b_alm),maps.interp(Als['L'],Als[polcomb])) # Subtract a meanfield if necessary recon_alms = recon_alms - mf_alm if task==0 and debug_cmb: rmap = solint.alm2map(recon_alms,ncomp=1)[0] * maps.binary_mask(mask) io.hplot(rmap,f'{solenspipe.opath}/rmap',mask=0,color='gray')
mask = sints.get_act_mr3_crosslinked_mask( mpatch, version=in_versions[survey], kind='binary_apod', season="s16" if survey == 'advact' else None, array=None, pad=pad) print(survey, patch) # FFT friendliness Ny, Nx = mask.shape[-2:] dNy = fft.fft_len(Ny, "above") dNx = fft.fft_len(Nx, "above") pny = dNy - Ny pnx = dNx - Nx pady1 = pny // 2 pady2 = pny - pady1 padx1 = pnx // 2 padx2 = pnx - padx1 mask = enmap.pad(mask, ((pady1, padx1), (pady2, padx2))) assert mask.shape[-2] == dNy assert mask.shape[-1] == dNx enmap.write_map(out_path + "%s.fits" % patch, mask) io.hplot(enmap.downgrade(mask, 8), out_path + "%s" % patch) sN = get_smooth_N(patch) smoothed = mask_smoothing(mask, sN) enmap.write_map(out_path + "%s_smoothed.fits" % patch, smoothed) io.hplot(enmap.downgrade(smoothed, 8), out_path + "%s_smoothed" % patch)