def rmmd(input, mask, sig): """ removes the dipole and mask of input file if mask = "auto" uses 30 deg sky cut """ import healpy as hp try: m = hp.read_map( input, field=(0, 1, 2), verbose=False, dtype=None, ) except: m = hp.read_map( input, field=(0, ), verbose=False, dtype=None, ) nside = hp.get_nside(m) npix = hp.nside2npix(nside) print(f"Nside: {nside}, npix: {npix}") # Mask map for dipole estimation m_masked = hp.ma(m) if mask: m_masked.mask = np.logical_not( hp.read_map( mask, verbose=False, dtype=None, )) # Fit dipole to masked map for i in sig: if not mask: mono, dip = hp.fit_dipole(m_masked[i], gal_cut=30) else: mono, dip = hp.fit_dipole(m_masked[i]) # Subtract dipole map from data click.echo(click.style("Removing dipole:", fg="yellow")) click.echo(click.style("Dipole vector:", fg="green") + f" {dip}") click.echo( click.style("Dipole amplitude:", fg="green") + f" {np.sqrt(np.sum(dip ** 2))}") click.echo(click.style("Monopole:", fg="green") + f" {mono}") # Create dipole template ray = range(npix) vecs = hp.pix2vec(nside, ray) dipole = np.dot(dip, vecs) m[i] = m[i] - dipole - mono hp.write_map(input.replace(".fits", "_no-md.fits"), m, dtype=None, overwrite=True)
def get_dipole_dir(sky): ''' Return the direction of the reconstructed dipole in (RA, dec) coordinated ''' mono, dipole = hp.fit_dipole(sky) d = hp.vec2ang(dipole, lonlat=True) return (d[0][0], d[1][0])
def remove_md(m, remove_dipole, remove_monopole, nside): if remove_monopole: dip_mask_name = remove_monopole if remove_dipole: dip_mask_name = remove_dipole # Mask map for dipole estimation if dip_mask_name == 'auto': mono, dip = hp.fit_dipole(m, gal_cut=30) else: m_masked = hp.ma(m) m_masked.mask = np.logical_not( hp.read_map( dip_mask_name, verbose=False, dtype=None, )) # Fit dipole to masked map mono, dip = hp.fit_dipole(m_masked) # Subtract dipole map from data if remove_dipole: click.echo(click.style("Removing dipole:", fg="yellow")) click.echo(click.style("Dipole vector:", fg="green") + f" {dip}") click.echo( click.style("Dipole amplitude:", fg="green") + f" {np.sqrt(np.sum(dip ** 2))}") # Create dipole template nside = int(nside) ray = range(hp.nside2npix(nside)) vecs = hp.pix2vec(nside, ray) dipole = np.dot(dip, vecs) m = m - dipole if remove_monopole: click.echo(click.style("Removing monopole:", fg="yellow")) click.echo(click.style("Mono:", fg="green") + f" {mono}") m = m - mono return m
def get_dipole_ampl(sky, subtract_noise=False, iso_map=None): ''' Returns the reconstructed dipole amplitude If subtract_noise is True, use the procedure, described in Fermi paper (1903.02905) for the noise subtraction. Exposure map should be provided in this case ''' if not subtract_noise: mono, dipole = hp.fit_dipole(sky) return np.sqrt((dipole * dipole).sum()) else: if iso_map is None: raise ValueError("Please, specify the isotropy map") C_ell = hp.anafast(sky)[1] obs_map = get_obs_map(iso_map, sky) C_N = 4. * np.pi / len(iso_map)**2 * (obs_map / iso_map**2).sum() # C_N /= 1.35**2 return 3 * np.sqrt((C_ell - C_N) / 4 / np.pi)
def test_solar_dipole_fit(tmpdir): tmpdir = Path(tmpdir) test = unittest.TestCase() # The purpose of this test is to simulate the motion of the spacecraft # for one year (see `time_span_s`) and produce *two* timelines: the first # is associated with variables `*_s_o` and refers to the case of a nonzero # velocity of the Solar System, and the second is associated with variables # `*_o` and assumes that the reference frame of the Solar System is the # same as the CMB's (so that there is no dipole). start_time = Time("2022-01-01") time_span_s = 365 * 24 * 3600 nside = 256 sampling_hz = 1 sim = lbs.Simulation(start_time=start_time, duration_s=time_span_s) scanning = lbs.SpinningScanningStrategy( spin_sun_angle_rad=0.785_398_163_397_448_3, precession_rate_hz=8.664_850_513_998_931e-05, spin_rate_hz=0.000_833_333_333_333_333_4, start_time=start_time, ) spin2ecliptic_quats = scanning.generate_spin2ecl_quaternions( start_time, time_span_s, delta_time_s=7200 ) instr = lbs.InstrumentInfo( boresight_rotangle_rad=0.0, spin_boresight_angle_rad=0.872_664_625_997_164_8, spin_rotangle_rad=3.141_592_653_589_793, ) det = lbs.DetectorInfo( name="Boresight_detector", sampling_rate_hz=sampling_hz, bandcenter_ghz=100.0, quat=[0.0, 0.0, 0.0, 1.0], ) (obs_s_o,) = sim.create_observations(detectors=[det]) (obs_o,) = sim.create_observations(detectors=[det]) pointings = lbs.scanning.get_pointings( obs_s_o, spin2ecliptic_quats=spin2ecliptic_quats, detector_quats=[det.quat], bore2spin_quat=instr.bore2spin_quat, ) orbit_s_o = lbs.SpacecraftOrbit(obs_s_o.start_time) orbit_o = lbs.SpacecraftOrbit(obs_o.start_time, solar_velocity_km_s=0.0) assert orbit_s_o.solar_velocity_km_s == 369.8160 assert orbit_o.solar_velocity_km_s == 0.0 pos_vel_s_o = lbs.spacecraft_pos_and_vel(orbit_s_o, obs_s_o, delta_time_s=86400.0) pos_vel_o = lbs.spacecraft_pos_and_vel(orbit_o, obs_o, delta_time_s=86400.0) assert pos_vel_s_o.velocities_km_s.shape == (366, 3) assert pos_vel_o.velocities_km_s.shape == (366, 3) lbs.add_dipole_to_observations( obs_s_o, pointings, pos_vel_s_o, dipole_type=lbs.DipoleType.LINEAR ) lbs.add_dipole_to_observations( obs_o, pointings, pos_vel_o, dipole_type=lbs.DipoleType.LINEAR ) npix = hp.nside2npix(nside) pix_indexes = hp.ang2pix(nside, pointings[0, :, 0], pointings[0, :, 1]) h = np.zeros(npix) m = np.zeros(npix) map_s_o = np.zeros(npix) map_o = np.zeros(npix) bin_map( tod=obs_s_o.tod, pixel_indexes=pix_indexes, binned_map=map_s_o, accum_map=m, hit_map=h, ) import healpy healpy.write_map(tmpdir / "map_s_o.fits.gz", map_s_o, overwrite=True) bin_map( tod=obs_o.tod, pixel_indexes=pix_indexes, binned_map=map_o, accum_map=m, hit_map=h, ) healpy.write_map(tmpdir / "map_o.fits.gz", map_o, overwrite=True) dip_map = map_s_o - map_o assert np.abs(np.nanmean(map_s_o) * 1e6) < 1 assert np.abs(np.nanmean(map_o) * 1e6) < 1 assert np.abs(np.nanmean(dip_map) * 1e6) < 1 dip_map[np.isnan(dip_map)] = healpy.UNSEEN mono, dip = hp.fit_dipole(dip_map) r = hp.Rotator(coord=["E", "G"]) l, b = hp.vec2ang(r(dip), lonlat=True) # Amplitude, longitude and latitude test.assertAlmostEqual(np.sqrt(np.sum(dip ** 2)) * 1e6, 3362.08, 1) test.assertAlmostEqual(l[0], 264.021, 1) test.assertAlmostEqual(b[0], 48.253, 1)
def Plotter( input, dataset, nside, auto, min, max, mid, rng, colorbar, lmax, fwhm, mask, mfill, sig, remove_dipole, logscale, size, white_background, darkmode, png, cmap, title, ltitle, unit, scale, outdir, verbose, data, ): rcParams["backend"] = "agg" if png else "pdf" rcParams["legend.fancybox"] = True rcParams["lines.linewidth"] = 2 rcParams["savefig.dpi"] = 300 rcParams["axes.linewidth"] = 1 masked = False if darkmode: rcParams["text.color"] = "white" # axes background color rcParams["axes.facecolor"] = "white" # axes background color rcParams["axes.edgecolor"] = "white" # axes edge color rcParams["axes.labelcolor"] = "white" rcParams["xtick.color"] = "white" # color of the tick labels rcParams["ytick.color"] = "white" # color of the tick labels rcParams["grid.color"] = "white" # grid color rcParams[ "legend.facecolor"] = "inherit" # legend background color (when 'inherit' uses axes.facecolor) rcParams[ "legend.edgecolor"] = "white" # legend edge color (when 'inherit' uses axes.edgecolor) rc( "text.latex", preamble=r"\usepackage{sfmath}", ) # Which signal to plot print("") print("") print("{:#^48}".format("")) #if len(input)==1: input = input[0] print("Plotting", input) ####################### #### READ MAP ##### ####################### # Get maps array if .h5 file if input.endswith(".h5"): from src.commands import h5map2fits from src.tools import alm2fits_tool # Get maps from alm data in .h5 if dataset.endswith("alm"): print("Converting alms to map") ( maps, nsid, lmax, fwhm, outfile, ) = alm2fits_tool( input, dataset, nside, lmax, fwhm, save=False, ) # Get maps from map data in .h5 elif dataset.endswith("map"): print("Reading map from h5") ( maps, nsid, lmax, outfile, ) = h5map2fits(input, dataset, save=False) # Found no data specified kind in .h5 else: print("Dataset not found. Breaking.") print(f"Does {input}/{dataset} exist?") sys.exit() # Plot all signals specified print(f"Plotting the following signals: {sig}") print("{:#^48}".format("")) for polt in sig: signal_label = get_signallabel(polt) if data is not None: m = data.copy() m = hp.ma(m) nsid = hp.get_nside(m) outfile = input.replace(".fits", "") else: try: if input.endswith(".fits"): map, header = hp.read_map( input, field=polt, verbose=False, h=True, dtype=None, ) header = dict(header) try: signal_label = header[f"TTYPE{polt+1}"] if signal_label in ["TEMPERATURE", "TEMP"]: signal_label = "T" if signal_label in [ "Q-POLARISATION", "Q_POLARISATION" ]: signal_label = "Q" if signal_label in [ "U-POLARISATION", "U_POLARISATION" ]: signal_label = "U" except: pass m = hp.ma(map) # Dont use header for this nsid = hp.get_nside(m) outfile = input.replace(".fits", "") elif input.endswith(".h5"): m = maps[polt] except: print(f"{polt} not found") sys.exit() ############ # SMOOTH # ############ if fwhm > 0 and input.endswith(".fits"): print("") print(f"Smoothing fits map to {fwhm} arcmin fwhm") print("") m = hp.smoothing( m, fwhm=arcmin2rad(fwhm), lmax=lmax, ) ############ # UD_GRADE # ############ if nside is not None and input.endswith(".fits"): if nsid != nside: print(f"UDgrading map from {nsid} to {nside}") m = hp.ud_grade( m, nside, ) else: nside = nsid ######################## #### remove dipole ##### ######################## if remove_dipole: starttime = time.time() print("Removing dipole:") dip_mask_name = remove_dipole # Mask map for dipole estimation m_masked = hp.ma(m) m_masked.mask = np.logical_not( hp.read_map( dip_mask_name, verbose=False, dtype=None, )) # Fit dipole to masked map mono, dip = hp.fit_dipole(m_masked) print(f"Dipole vector: {dip}") print(f"Dipole amplitude: {np.sqrt(np.sum(dip ** 2))}") # Create dipole template nside = int(nside) ray = range(hp.nside2npix(nside)) vecs = hp.pix2vec(nside, ray) dipole = np.dot(dip, vecs) # Subtract dipole map from data m = m - dipole print(f"Dipole removal : {(time.time() - starttime)}" ) if verbose else None ####################### #### Auto-param ##### ####################### # Reset these every signal tempmin = min tempmax = max temptitle = title templtitle = ltitle tempunit = unit templogscale = logscale tempcmap = cmap # ttl, unt and cmb are temporary variables for title, unit and colormap if auto: ( _title, ticks, cmp, lgscale, scale, ) = get_params( m, outfile, polt, signal_label, ) # Title if _title["stddev"]: ttl = _title["param"] + r"$_{\mathrm{" + _title[ "comp"] + "}}^{\sigma}$" elif _title["mean"]: ttl = r"$\langle$" + _title[ "param"] + r"$\rangle$" + r"$_{\mathrm{" + _title[ "comp"] + "}}^{ }$" elif _title["diff"]: ttl = r"$\Delta$ " + _title["param"] + r"$_{\mathrm{" + _title[ "comp"] + "}}^{" + _title["diff_label"] + "}$" else: ttl = _title["param"] + r"$_{\mathrm{" + _title[ "comp"] + "}}^{ }$" # Left signal label lttl = r"$" + _title["sig"] + "$" if lttl == "$I$": lttl = "$T$" elif lttl == "$QU$": lttl = "$P$" #elif lttl == "$P$": # ticks *= 2 # Tick bug fix mn = ticks[0] mx = ticks[-1] if len(ticks) > 2: mid = ticks[1:-1] # Unit unt = _title["unit"] else: ttl = "" lttl = "" unt = "" ticks = [False, False] cmp = "planck" lgscale = False # Scale map m *= scale # If range has been specified, set. """ if rng: if rng == "auto": if minmax: mn = np.min(m) mx = np.max(m) else: mn, mx = get_ticks(m, 97.5) if min is False: min = mn if max is False: max = mx else: rng = float(rng) min = -rng max = rng ticks = [min, 0.0, max] print("hihi",rng) else: print("pre", ticks, min, max) # If min and max have been specified, set. if min is not False: ticks[0] = float(min) if max is not False: ticks[-1] = float(max) """ # If min and max have been specified, set. if rng == "auto" and not auto: print("Setting range from 97.5th percentile of data") mn, mx = get_ticks(m, 97.5) elif rng == "minmax": print("Setting range from min to max of data") mn = np.min(m) mx = np.max(m) else: try: if float(rng) > 0.0: mn = -float(rng) mx = float(rng) ticks = [False, 0.0, False] except: pass if min is False: min = mn else: min = float(min) if max is False: max = mx else: max = float(max) ticks[0] = min ticks[-1] = max if mid: ticks = [min, *mid, max] ########################## #### Plotting Params ##### ########################## # Upper right title if not title: title = ttl # Upper left title if not ltitle: ltitle = lttl # Unit under colorbar if not unit: unit = unt # Image size - ratio is always 1/2 xsize = 2000 ysize = int(xsize / 2.0) ticklabels = ticks ####################### #### logscale ##### ####################### # Some maps turns on logscale automatically # -logscale command overwrites this if logscale == None: logscale = lgscale if logscale: print("Applying logscale") starttime = time.time() m = np.log10(0.5 * (m + np.sqrt(4.0 + m * m))) ticks = [] for i in ticklabels: if i > 0: ticks.append(np.log10(i)) elif i < 0: ticks.append(-np.log10(abs(i))) else: ticks.append(i) m = np.maximum(np.minimum(m, ticks[-1]), ticks[0]) print( "Logscale", (time.time() - starttime), ) if verbose else None ###################### #### COLOR SETUP ##### ###################### # Chose colormap manually if cmap == None: # If not defined autoset or goto planck cmap = cmp if cmap == "planck": from pathlib import Path cmap = Path(__file__).parent / "parchment1.dat" cmap = col.ListedColormap(np.loadtxt(cmap) / 255.0, "planck") else: try: import cmasher cmap = eval(f"cmasher.{cmap}") except: cmap = plt.get_cmap(cmap) print(f"Colormap: {cmap.name}") ####################### #### Projection? ##### ####################### theta = np.linspace(np.pi, 0, ysize) phi = np.linspace(-np.pi, np.pi, xsize) longitude = np.radians(np.linspace(-180, 180, xsize)) latitude = np.radians(np.linspace(-90, 90, ysize)) # project the map to a rectangular matrix xsize x ysize PHI, THETA = np.meshgrid(phi, theta) grid_pix = hp.ang2pix(nside, THETA, PHI) ###################### ######## Mask ######## ###################### if mask: print(f"Masking using {mask}") masked = True # Apply mask hp.ma(m) m.mask = np.logical_not(hp.read_map(mask, field=polt)) # Don't know what this does, from paperplots by Zonca. grid_mask = m.mask[grid_pix] grid_map = np.ma.MaskedArray(m[grid_pix], grid_mask) if mfill: cmap.set_bad(mfill) # color of missing pixels # cmap.set_under("white") # color of background, necessary if you want to use # using directly matplotlib instead of mollview has higher quality output else: grid_map = m[grid_pix] ###################### #### Formatting ###### ###################### from matplotlib.projections.geo import GeoAxes class ThetaFormatterShiftPi(GeoAxes.ThetaFormatter): """Shifts labelling by pi Shifts labelling from -180,180 to 0-360""" def __call__(self, x, pos=None): if x != 0: x *= -1 if x < 0: x += 2 * np.pi return GeoAxes.ThetaFormatter.__call__(self, x, pos) sizes = get_sizes(size) for width in sizes: print("Size: " + str(width)) height = width / 2.0 # Make sure text doesnt change with colorbar height *= 1.275 if colorbar else 1 ################ ##### font ##### ################ if width > 12.0: fontsize = 8 elif width == 12.0: fontsize = 7 else: fontsize = 6 fig = plt.figure(figsize=( cm2inch(width), cm2inch(height), ), ) ax = fig.add_subplot(111, projection="mollweide") # rasterized makes the map bitmap while the labels remain vectorial # flip longitude to the astro convention image = plt.pcolormesh( longitude[::-1], latitude, grid_map, vmin=ticks[0], vmax=ticks[-1], rasterized=True, cmap=cmap, shading='auto', ) # graticule ax.set_longitude_grid(60) ax.xaxis.set_major_formatter(ThetaFormatterShiftPi(60)) if width < 10: ax.set_latitude_grid(45) ax.set_longitude_grid_ends(90) ################ ### COLORBAR ### ################ if colorbar: # colorbar from matplotlib.ticker import FuncFormatter cb = fig.colorbar( image, orientation="horizontal", shrink=0.3, pad=0.08, ticks=ticks, format=FuncFormatter(fmt), ) # Format tick labels print("Ticks: ", ticklabels) ticklabels = [fmt(i, 1) for i in ticklabels] cb.ax.set_xticklabels(ticklabels) cb.ax.xaxis.set_label_text(unit) cb.ax.xaxis.label.set_size(fontsize) # cb.ax.minorticks_on() cb.ax.tick_params( which="both", axis="x", direction="in", labelsize=fontsize, ) cb.ax.xaxis.labelpad = 4 # -11 # workaround for issue with viewers, see colorbar docstring cb.solids.set_edgecolor("face") # remove longitude tick labels ax.xaxis.set_ticklabels([]) # remove horizontal grid ax.xaxis.set_ticks([]) ax.yaxis.set_ticklabels([]) ax.yaxis.set_ticks([]) plt.grid(True) ################### ## RIGHT TITLE #### ################### plt.text( 6.0, 1.3, r"%s" % title, ha="center", va="center", fontsize=fontsize, ) ################## ## LEFT TITLE #### ################## plt.text( -6.0, 1.3, r"%s" % ltitle, ha="center", va="center", fontsize=fontsize, ) ############## #### SAVE #### ############## plt.tight_layout() filetype = "png" if png else "pdf" # Turn on transparency unless told otherwise tp = False if white_background else True ############## ## filename ## ############## print(f"Signal label: {signal_label}") outfile = outfile.replace("_IQU_", "_") outfile = outfile.replace("_I_", "_") filename = [] filename.append(f"{str(int(fwhm))}arcmin") if fwhm > 0 else None filename.append("cb") if colorbar else None filename.append("masked") if masked else None filename.append("nodip") if remove_dipole else None filename.append("dark") if darkmode else None filename.append(f"c-{cmap.name}") nside_tag = "_n" + str(int(nside)) if nside_tag in outfile: outfile = outfile.replace(nside_tag, "") fn = outfile + f"_{signal_label}_w{str(int(width))}" + nside_tag for i in filename: fn += f"_{i}" fn += f".{filetype}" starttime = time.time() if outdir: fn = outdir + "/" + os.path.split(fn)[-1] print(f"Output: {fn}") plt.savefig( fn, bbox_inches="tight", pad_inches=0.02, transparent=tp, format=filetype, ) print( "Savefig", (time.time() - starttime), ) if verbose else None plt.close() print( "Totaltime:", (time.time() - totaltime), ) if verbose else None min = tempmin max = tempmax title = temptitle ltitle = temptitle unit = tempunit logscale = templogscale cmap = tempcmap
def release(ctx, chain, burnin, procver, resamp, copy_, freqmaps, ame, ff, cmb, synch, dust, br, diff, diffcmb, goodness, chisq, res, all_, plot): """ Creates a release file-set on the BeyondPlanck format. https://gitlab.com/BeyondPlanck/repo/-/wikis/BeyondPlanck-Release-Candidate-2 ex. c3pp release chains_v1_c{1,2}/chain_c000{1,2}.h5 30 BP_r1 Will output formatted files using all chains specified, with a burnin of 30 to a directory called BP_r1 This function outputs the following files to the {procver} directory: BP_chain01_full_{procver}.h5 BP_resamp_chain01_full_Cl_{procver}.h5 BP_resamp_chain01_full_noCl_{procver}.h5 BP_param_full_v1.txt BP_param_resamp_Cl_v1.txt BP_param_resamp_noCl_v1.txt BP_030_IQU_full_n0512_{procver}.fits BP_044_IQU_full_n0512_{procver}.fits BP_070_IQU_full_n1024_{procver}.fits BP_cmb_IQU_full_n1024_{procver}.fits BP_synch_IQU_full_n1024_{procver}.fits BP_freefree_I_full_n1024_{procver}.fits BP_ame_I_full_n1024_{procver}.fits BP_cmb_GBRlike_{procver}.fits """ # TODO # Use proper masks for output of CMB component # Use inpainted data as well in CMB component from src.fitsformatter import format_fits, get_data, get_header from pathlib import Path import shutil if all_: # sets all other flags to true copy_ = not copy_ freqmaps = not freqmaps ame = not ame ff = not ff cmb = not cmb synch = not synch dust = not dust br = not br diff = not diff diffcmb = not diffcmb goodness = not goodness res = not res chisq = not chisq if goodness: chisq = res = True elif chisq or res: goodness = True # Make procver directory if not exists click.echo("{:#^80}".format("")) click.echo(f"Creating directory {procver}") Path(procver).mkdir(parents=True, exist_ok=True) chains = chain maxchain = len(chains) """ Copying chains files """ if copy_: # Commander3 parameter file for main chain for i, chainfile in enumerate(chains, 1): path = os.path.split(chainfile)[0] for file in os.listdir(path): if file.startswith("param") and i == 1: # Copy only first click.echo( f"Copying {path}/{file} to {procver}/BP_param_full_c" + str(i).zfill(4) + ".txt") if resamp: shutil.copyfile( f"{path}/{file}", f"{procver}/BP_param_resamp_Cl_c" + str(i).zfill(4) + ".txt", ) else: shutil.copyfile( f"{path}/{file}", f"{procver}/BP_param_full_c" + str(i).zfill(4) + ".txt", ) if resamp: # Resampled CMB-only full-mission Gibbs chain file with Cls (for BR estimator) click.echo(f"Copying {chainfile} to {procver}/BP_resamp_c" + str(i).zfill(4) + f"_full_Cl_{procver}.h5") shutil.copyfile( chainfile, f"{procver}/BP_resamp_c" + str(i).zfill(4) + f"_full_Cl_{procver}.h5", ) else: # Full-mission Gibbs chain file click.echo(f"Copying {chainfile} to {procver}/BP_c" + str(i).zfill(4) + f"_full_{procver}.h5") shutil.copyfile( chainfile, f"{procver}/BP_c" + str(i).zfill(4) + f"_full_{procver}.h5", ) #if halfring: # # Copy halfring files # for i, chainfile in enumerate([halfring], 1): # # Copy halfring files # click.echo(f"Copying {resamp} to {procver}/BP_halfring_c" + str(i).zfill(4) + f"_full_Cl_{procver}.h5") # shutil.copyfile(halfring, f"{procver}/BP_halfring_c" + str(i).zfill(4) + f"_full_Cl_{procver}.h5",) """ IQU mean, IQU stdev, (Masks for cmb) Run mean and stddev from min to max sample (Choose min manually or start at 1?) """ if resamp: chain = f"{procver}/BP_resamp_c0001_full_Cl_{procver}.h5" else: chain = f"{procver}/BP_c0001_full_{procver}.h5" if freqmaps: try: # Full-mission 30 GHz IQU frequency map # BP_030_IQU_full_n0512_{procver}.fits format_fits( chain=chain, extname="FREQMAP", types=[ "I_MEAN", "Q_MEAN", "U_MEAN", "I_RMS", "Q_RMS", "U_RMS", "I_STDDEV", "Q_STDDEV", "U_STDDEV", ], units=[ "uK", "uK", "uK", "uK", "uK", "uK", "uK", "uK", "uK", ], nside=512, burnin=burnin, maxchain=maxchain, polar=True, component="030", fwhm=0.0, nu_ref_t="30.0 GHz", nu_ref_p="30.0 GHz", procver=procver, filename=f"BP_030_IQU_full_n0512_{procver}.fits", bndctr=30, restfreq=28.456, bndwid=9.899, ) # Full-mission 44 GHz IQU frequency map format_fits( chain=chain, extname="FREQMAP", types=[ "I_MEAN", "Q_MEAN", "U_MEAN", "I_RMS", "Q_RMS", "U_RMS", "I_STDDEV", "Q_STDDEV", "U_STDDEV", ], units=[ "uK", "uK", "uK", "uK", "uK", "uK", "uK", "uK", "uK", ], nside=512, burnin=burnin, maxchain=maxchain, polar=True, component="044", fwhm=0.0, nu_ref_t="44.0 GHz", nu_ref_p="44.0 GHz", procver=procver, filename=f"BP_044_IQU_full_n0512_{procver}.fits", bndctr=44, restfreq=44.121, bndwid=10.719, ) # Full-mission 70 GHz IQU frequency map format_fits( chain=chain, extname="FREQMAP", types=[ "I_MEAN", "Q_MEAN", "U_MEAN", "I_RMS", "Q_RMS", "U_RMS", "I_STDDEV", "Q_STDDEV", "U_STDDEV", ], units=[ "uK", "uK", "uK", "uK", "uK", "uK", "uK", "uK", "uK", ], nside=1024, burnin=burnin, maxchain=maxchain, polar=True, component="070", fwhm=0.0, nu_ref_t="70.0 GHz", nu_ref_p="70.0 GHz", procver=procver, filename=f"BP_070_IQU_full_n1024_{procver}.fits", bndctr=70, restfreq=70.467, bndwid=14.909, ) except Exception as e: print(e) click.secho("Continuing...", fg="yellow") """ FOREGROUND MAPS """ # Full-mission CMB IQU map if cmb: if resamp: try: format_fits( chain, extname="COMP-MAP-CMB-RESAMP", types=[ "I_MEAN", "I_STDDEV", ], units=[ "uK_cmb", "uK_cmb", ], nside=1024, burnin=burnin, maxchain=maxchain, polar=True, component="CMB", fwhm=14.0, nu_ref_t="NONE", nu_ref_p="NONE", procver=procver, filename=f"BP_cmb_resamp_IQU_full_n1024_{procver}.fits", bndctr=None, restfreq=None, bndwid=None, ) except Exception as e: print(e) click.secho("Continuing...", fg="yellow") else: try: format_fits( chain, extname="COMP-MAP-CMB", types=[ "I_MEAN", "Q_MEAN", "U_MEAN", "I_STDDEV", "Q_STDDEV", "U_STDDEV", "mask1", "mask2", ], units=[ "uK_cmb", "uK_cmb", "uK", "uK", "NONE", "NONE", ], nside=1024, burnin=burnin, maxchain=maxchain, polar=True, component="CMB", fwhm=14.0, nu_ref_t="NONE", nu_ref_p="NONE", procver=procver, filename=f"BP_cmb_IQU_full_n1024_{procver}.fits", bndctr=None, restfreq=None, bndwid=None, ) except Exception as e: print(e) click.secho("Continuing...", fg="yellow") if ff: try: # Full-mission free-free I map format_fits( chain, extname="COMP-MAP-FREE-FREE", types=[ "I_MEAN", "I_TE_MEAN", "I_STDDEV", "I_TE_STDDEV", ], units=[ "uK_RJ", "K", "uK_RJ", "K", ], nside=1024, burnin=burnin, maxchain=maxchain, polar=False, component="FREE-FREE", fwhm=30.0, nu_ref_t="40.0 GHz", nu_ref_p="40.0 GHz", procver=procver, filename=f"BP_freefree_I_full_n1024_{procver}.fits", bndctr=None, restfreq=None, bndwid=None, ) except Exception as e: print(e) click.secho("Continuing...", fg="yellow") if ame: try: # Full-mission AME I map format_fits( chain, extname="COMP-MAP-AME", types=[ "I_MEAN", "I_NU_P_MEAN", "I_STDDEV", "I_NU_P_STDDEV", ], units=[ "uK_RJ", "GHz", "uK_RJ", "GHz", ], nside=1024, burnin=burnin, maxchain=maxchain, polar=False, component="AME", fwhm=120.0, nu_ref_t="22.0 GHz", nu_ref_p="22.0 GHz", procver=procver, filename=f"BP_ame_I_full_n1024_{procver}.fits", bndctr=None, restfreq=None, bndwid=None, ) except Exception as e: print(e) click.secho("Continuing...", fg="yellow") if synch: try: # Full-mission synchrotron IQU map format_fits( chain, extname="COMP-MAP-SYNCHROTRON", types=[ "I_MEAN", "Q_MEAN", "U_MEAN", "P_MEAN", "I_BETA_MEAN", "QU_BETA_MEAN", "I_STDDEV", "Q_STDDEV", "U_STDDEV", "P_STDDEV", "I_BETA_STDDEV", "QU_BETA_STDDEV", ], units=[ "uK_RJ", "uK_RJ", "uK_RJ", "uK_RJ", "NONE", "NONE", "uK_RJ", "uK_RJ", "uK_RJ", "uK_RJ", "NONE", "NONE", ], nside=1024, burnin=burnin, maxchain=maxchain, polar=True, component="SYNCHROTRON", fwhm=60.0, # 60.0, nu_ref_t="30.0 GHz", nu_ref_p="30.0 GHz", procver=procver, filename=f"BP_synch_IQU_full_n1024_{procver}.fits", bndctr=None, restfreq=None, bndwid=None, ) except Exception as e: print(e) click.secho("Continuing...", fg="yellow") if dust: try: # Full-mission thermal dust IQU map format_fits( chain, extname="COMP-MAP-DUST", types=[ "I_MEAN", "Q_MEAN", "U_MEAN", "P_MEAN", "I_BETA_MEAN", "QU_BETA_MEAN", "I_T_MEAN", "QU_T_MEAN", "I_STDDEV", "Q_STDDEV", "U_STDDEV", "P_STDDEV", "I_BETA_STDDEV", "QU_BETA_STDDEV", "I_T_STDDEV", "QU_T_STDDEV", ], units=[ "uK_RJ", "uK_RJ", "uK_RJ", "uK_RJ", "NONE", "NONE", "K", "K", "uK_RJ", "uK_RJ", "uK_RJ", "uK_RJ", "NONE", "NONE", "K", "K", ], nside=1024, burnin=burnin, maxchain=maxchain, polar=True, component="DUST", fwhm=10.0, # 60.0, nu_ref_t="545 GHz", nu_ref_p="353 GHz", procver=procver, filename=f"BP_dust_IQU_full_n1024_{procver}.fits", bndctr=None, restfreq=None, bndwid=None, ) except Exception as e: print(e) click.secho("Continuing...", fg="yellow") if diff: import healpy as hp try: click.echo("Creating frequency difference maps") path_dx12 = "/mn/stornext/u3/trygvels/compsep/cdata/like/BP_releases/dx12" path_npipe = "/mn/stornext/u3/trygvels/compsep/cdata/like/BP_releases/npipe" maps_dx12 = [ "30ghz_2018_n1024_beamscaled_dip.fits", "44ghz_2018_n1024_beamscaled_dip.fits", "70ghz_2018_n1024_beamscaled_dip.fits" ] maps_npipe = [ "npipe6v20_030_map_uK.fits", "npipe6v20_044_map_uK.fits", "npipe6v20_070_map_uK.fits", ] maps_BP = [ f"BP_030_IQU_full_n0512_{procver}.fits", f"BP_044_IQU_full_n0512_{procver}.fits", f"BP_070_IQU_full_n1024_{procver}.fits", ] beamscaling = [9.8961854E-01, 9.9757886E-01, 9.9113965E-01] for i, freq in enumerate([ "030", "044", "070", ]): map_BP = hp.read_map(f"{procver}/{maps_BP[i]}", field=(0, 1, 2), verbose=False, dtype=None) map_npipe = hp.read_map(f"{path_npipe}/{maps_npipe[i]}", field=(0, 1, 2), verbose=False, dtype=None) map_dx12 = hp.read_map(f"{path_dx12}/{maps_dx12[i]}", field=(0, 1, 2), verbose=False, dtype=None) #dx12 dipole values: # 3362.08 pm 0.99, 264.021 pm 0.011, 48.253 ± 0.005 # 233.18308357 2226.43833645 -2508.42179665 #dipole_dx12 = -3362.08*hp.dir2vec(264.021, 48.253, lonlat=True) #map_dx12 = map_dx12/beamscaling[i] # Smooth to 60 arcmin map_BP = hp.smoothing(map_BP, fwhm=arcmin2rad(60.0), verbose=False) map_npipe = hp.smoothing(map_npipe, fwhm=arcmin2rad(60.0), verbose=False) map_dx12 = hp.smoothing(map_dx12, fwhm=arcmin2rad(60.0), verbose=False) #ud_grade 30 and 44ghz if i < 2: map_npipe = hp.ud_grade( map_npipe, nside_out=512, ) map_dx12 = hp.ud_grade( map_dx12, nside_out=512, ) # Remove monopoles map_BP -= np.mean(map_BP, axis=1).reshape(-1, 1) map_npipe -= np.mean(map_npipe, axis=1).reshape(-1, 1) map_dx12 -= np.mean(map_dx12, axis=1).reshape(-1, 1) hp.write_map(f"{procver}/BP_{freq}_diff_npipe_{procver}.fits", np.array(map_BP - map_npipe), overwrite=True, column_names=["I_DIFF", "Q_DIFF", "U_DIFF"], dtype=None) hp.write_map(f"{procver}/BP_{freq}_diff_dx12_{procver}.fits", np.array(map_BP - map_dx12), overwrite=True, column_names=["I_DIFF", "Q_DIFF", "U_DIFF"], dtype=None) except Exception as e: print(e) click.secho("Continuing...", fg="yellow") if diffcmb: import healpy as hp try: click.echo("Creating cmb difference maps") path_cmblegacy = "/mn/stornext/u3/trygvels/compsep/cdata/like/BP_releases/cmb-legacy" mask_ = hp.read_map( "/mn/stornext/u3/trygvels/compsep/cdata/like/BP_releases/masks/dx12_v3_common_mask_int_005a_1024_TQU.fits", verbose=False, dtype=np.bool, ) map_BP = hp.read_map( f"{procver}/BP_cmb_IQU_full_n1024_{procver}.fits", field=(0, 1, 2), verbose=False, dtype=None, ) map_BP_masked = hp.ma(map_BP[0]) map_BP_masked.mask = np.logical_not(mask_) mono, dip = hp.fit_dipole(map_BP_masked) nside = 1024 ray = range(hp.nside2npix(nside)) vecs = hp.pix2vec(nside, ray) dipole = np.dot(dip, vecs) map_BP[0] = map_BP[0] - dipole - mono map_BP = hp.smoothing(map_BP, fwhm=arcmin2rad(np.sqrt(60.0**2 - 14**2)), verbose=False) #map_BP -= np.mean(map_BP,axis=1).reshape(-1,1) for i, method in enumerate([ "commander", "sevem", "nilc", "smica", ]): data = f"COM_CMB_IQU-{method}_2048_R3.00_full.fits" click.echo(f"making difference map with {data}") map_cmblegacy = hp.read_map(f"{path_cmblegacy}/{data}", field=(0, 1, 2), verbose=False, dtype=None) map_cmblegacy = hp.smoothing(map_cmblegacy, fwhm=arcmin2rad(60.0), verbose=False) map_cmblegacy = hp.ud_grade( map_cmblegacy, nside_out=1024, ) map_cmblegacy = map_cmblegacy * 1e6 # Remove monopoles map_cmblegacy_masked = hp.ma(map_cmblegacy[0]) map_cmblegacy_masked.mask = np.logical_not(mask_) mono = hp.fit_monopole(map_cmblegacy_masked) click.echo(f"{method} subtracting monopole {mono}") map_cmblegacy[0] = map_cmblegacy[ 0] - mono #np.mean(map_cmblegacy,axis=1).reshape(-1,1) hp.write_map(f"{procver}/BP_cmb_diff_{method}_{procver}.fits", np.array(map_BP - map_cmblegacy), overwrite=True, column_names=["I_DIFF", "Q_DIFF", "U_DIFF"], dtype=None) except Exception as e: print(e) click.secho("Continuing...", fg="yellow") if goodness: import healpy as hp path_goodness = procver + "/goodness" Path(path_goodness).mkdir(parents=True, exist_ok=True) print("PATH", path_goodness) cmin = int(os.path.split(chains[0])[0].rsplit("_c")[-1]) cmax = int(os.path.split(chains[-1])[0].rsplit("_c")[-1]) chdir = os.path.split(chains[0])[0].rsplit("_", 1)[0] if chisq: try: format_fits( chains, extname="CHISQ", types=[ "I_MEAN", "P_MEAN", ], units=[ "NONE", "NONE", ], nside=16, burnin=burnin, maxchain=maxchain, polar=True, component="CHISQ", fwhm=0.0, nu_ref_t="NONE", nu_ref_p="NONE", procver=procver, filename=f'goodness/BP_chisq_n16_{procver}.fits', bndctr=None, restfreq=None, bndwid=None, cmin=cmin, cmax=cmax, chdir=chdir, ) except Exception as e: print(e) click.secho("Continuing...", fg="yellow") if res: click.echo("Save and format chisq map and residual maps") bands = { "030": { "nside": 512, "fwhm": 120, "sig": "IQU", "fields": (0, 1, 2), "unit": "uK", "scale": 1., }, "044": { "nside": 512, "fwhm": 120, "sig": "IQU", "fields": (0, 1, 2), "unit": "uK", "scale": 1., }, "070": { "nside": 1024, "fwhm": 120, "sig": "IQU", "fields": (0, 1, 2), "unit": "uK", "scale": 1., }, "030-WMAP_Ka": { "nside": 512, "fwhm": 120, "sig": "I", "fields": (0, ), "unit": "uK", "scale": 1e3, }, "040-WMAP_Q1": { "nside": 512, "fwhm": 120, "sig": "I", "fields": (0, ), "unit": "uK", "scale": 1., }, "040-WMAP_Q2": { "nside": 512, "fwhm": 120, "sig": "I", "fields": (0, ), "unit": "uK", "scale": 1., }, "060-WMAP_V1": { "nside": 512, "fwhm": 120, "sig": "I", "fields": (0, ), "unit": "uK", "scale": 1., }, "060-WMAP_V2": { "nside": 512, "fwhm": 120, "sig": "I", "fields": (0, ), "unit": "uK", "scale": 1., }, "0.4-Haslam": { "nside": 512, "fwhm": 120, "sig": "I", "fields": (0, ), "unit": "uK", "scale": 1., }, "857": { "nside": 1024, "fwhm": 120, "sig": "I", "fields": (0, ), "unit": "uK", "scale": 1., }, "033-WMAP_Ka_P": { "nside": 16, "fwhm": 0, "sig": "QU", "fields": (1, 2), "unit": "uK", "scale": 1e3, }, "041-WMAP_Q_P": { "nside": 16, "fwhm": 0, "sig": "QU", "fields": (1, 2), "unit": "uK", "scale": 1e3, }, "061-WMAP_V_P": { "nside": 16, "fwhm": 0, "sig": "QU", "fields": (1, 2), "unit": "uK", "scale": 1e3, }, "353": { "nside": 1024, "fwhm": 120, "sig": "QU", "fields": (1, 2), "unit": "uK", "scale": 1., }, } for label, b in bands.items(): types = [] units = [] for l in b["sig"]: types.append(f'{l}_MEAN') units.append(b["unit"]) for l in b["sig"]: types.append(f'{l}_STDDEV') units.append(b["unit"]) try: format_fits( chains, extname="FREQBAND_RES", types=types, units=units, nside=b["nside"], burnin=burnin, maxchain=maxchain, polar=True, component=label, fwhm=b["fwhm"], nu_ref_t="NONE", nu_ref_p="NONE", procver=procver, filename= f'goodness/BP_res_{label}_{b["sig"]}_full_n{b["nside"]}_{b["fwhm"]}arcmin_{b["unit"]}_{procver}.fits', bndctr=None, restfreq=None, bndwid=None, cmin=cmin, cmax=cmax, chdir=chdir, fields=b["fields"], scale=b["scale"], ) except Exception as e: print(e) click.secho("Continuing...", fg="yellow") """ As implemented by Simone """ if br and resamp: # Gaussianized TT Blackwell-Rao input file click.echo("{:-^50}".format("CMB GBR")) ctx.invoke( sigma_l2fits, filename=resamp, nchains=1, burnin=burnin, path="cmb/sigma_l", outname=f"{procver}/BP_cmb_GBRlike_{procver}.fits", save=True, ) """ TODO Generalize this so that they can be generated by Elina and Anna-Stiina """ # Full-mission 30 GHz IQU beam symmetrized frequency map # BP_030_IQUdeconv_full_n0512_{procver}.fits # Full-mission 44 GHz IQU beam symmetrized frequency map # BP_044_IQUdeconv_full_n0512_{procver}.fits # Full-mission 70 GHz IQU beam symmetrized frequency map # BP_070_IQUdeconv_full_n1024_{procver}.fits """ Both sigma_l's and Dl's re in the h5. (Which one do we use?) """ # CMB TT, TE, EE power spectrum # BP_cmb_Cl_{procver}.txt """ Just get this from somewhere """ # Best-fit LCDM CMB TT, TE, EE power spectrum # BP_cmb_bfLCDM_{procver}.txt if plot: os.chdir(procver) ctx.invoke(plotrelease, procver=procver, all_=True)
#! http://lambda.gsfc.nasa.gov/data/map/dr4/skymaps/7yr/raw/wmap_band_imap_r9_7yr_W_v4.fits filename = 'wmap_band_imap_r9_7yr_W_v4.fits' #filename = '/global/scratch/sd/planck/user/zonca/healpytut/wmap_band_imap_r9_7yr_W_v4.fits' m = healpy.read_map(filename) #by default converts to RING!! healpy.mollview(m, title='Histogram equalized', nest=False, norm='hist') show() m = healpy.read_map(filename, nest=True) #keeps nested healpy.mollview(m, coord=['G','E'], title='Linear scale', unit='mK', nest=True, min=-1,max=1, xsize=2000) #xsize increases resolution healpy.graticule() show() healpy.gnomview(m, rot=[0,0.3], title='Linear scale', unit='mK', format='%.2g', nest=True) show() print(healpy.fit_dipole(m, gal_cut=20)) # degrees #!Smoothing #!~~~~~~~~~ m_smoothed = healpy.smoothing(m, fwhm=60, arcmin=True) healpy.mollview(m_smoothed, min=-1, max=1, title='Map smoothed 1 deg') #!Rotator #!~~~~~~~ rot = healpy.Rotator(coord=['G','E']) theta_gal, phi_gal = np.pi/2., 0. theta_ecl, phi_ecl = rot(theta_gal, phi_gal) print(theta_ecl, phi_ecl)
def Plotter(input, dataset, nside, auto, min, max, mid, rng, colorbar, lmax, fwhm, mask, mfill, sig, remove_dipole, remove_monopole, logscale, size, white_background, darkmode, png, cmap, title, ltitle, unit, scale, outdir, verbose, data, labelsize): dpi = 150 rcParams["backend"] = "agg" if png else "pdf" rcParams["legend.fancybox"] = True rcParams["lines.linewidth"] = 2 rcParams["savefig.dpi"] = dpi #300 rcParams["axes.linewidth"] = 1 masked = False if darkmode: rcParams["text.color"] = "white" # axes background color rcParams["axes.facecolor"] = "white" # axes background color rcParams["axes.edgecolor"] = "white" # axes edge color rcParams["axes.labelcolor"] = "white" rcParams["xtick.color"] = "white" # color of the tick labels rcParams["ytick.color"] = "white" # color of the tick labels rcParams["grid.color"] = "white" # grid color rcParams["legend.facecolor"] = "inherit" # legend background color (when 'inherit' uses axes.facecolor) rcParams["legend.edgecolor"] = "white" # legend edge color (when 'inherit' uses axes.edgecolor) rc("text.latex", preamble=r"\usepackage{sfmath}",) # Which signal to plot click.echo("") click.echo(click.style("{:#^48}".format(""), fg="green")) click.echo(click.style("Plotting",fg="green") + f" {input}") ####################### #### READ MAP ##### ####################### # Get maps array if .h5 file if input.endswith(".h5"): from src.commands_hdf import h5map2fits from src.tools import alm2fits_tool # Get maps from alm data in .h5 if dataset.endswith("alm"): click.echo(click.style("Converting alms to map",fg="green")) (maps, nsid, lmax, fwhm, outfile,) = alm2fits_tool(input, dataset, nside, lmax, fwhm, save=False,) # Get maps from map data in .h5 elif dataset.endswith("map"): click.echo(click.style("Reading map from hdf",fg="green")) (maps, nsid, lmax, outfile,) = h5map2fits(input, dataset, save=False) # Found no data specified kind in .h5 else: click.echo(click.style("Dataset not found. Breaking.",fg="red")) click.echo(click.style(f"Does {input}/{dataset} exist?",fg="red")) sys.exit() # Plot all signals specified click.echo(click.style("Using signals ",fg="green") + f"{sig}") click.echo(click.style("{:#^48}".format(""), fg="green")) for polt in sig: signal_label = get_signallabel(polt) if data is not None: m = data.copy() m = hp.ma(m) nsid = hp.get_nside(m) outfile = input.replace(".fits", "") else: try: if input.endswith(".fits"): map, header = hp.read_map(input, field=polt, verbose=False, h=True, dtype=None,) header = dict(header) try: signal_label = header[f"TTYPE{polt+1}"] if signal_label in ["TEMPERATURE", "TEMP"]: signal_label = "T" if signal_label in ["Q-POLARISATION", "Q_POLARISATION"]: signal_label = "Q" if signal_label in ["U-POLARISATION", "U_POLARISATION"]: signal_label = "U" except: pass m = hp.ma(map) # Dont use header for this nsid = hp.get_nside(m) outfile = input.replace(".fits", "") elif input.endswith(".h5"): m = maps[polt] except: click.echo(click.style(f"{polt} not found",fg="red")) sys.exit() ############ # SMOOTH # ############ if float(fwhm) > 0 and input.endswith(".fits"): click.echo(click.style(f"Smoothing fits map to {fwhm} arcmin fwhm",fg="yellow")) m = hp.smoothing(m, fwhm=arcmin2rad(fwhm), lmax=lmax,) ############ # UD_GRADE # ############ if nside is not None and input.endswith(".fits"): if nsid != nside: click.echo(click.style(f"UDgrading map from {nsid} to {nside}", fg="yellow")) m = hp.ud_grade(m, nside,) else: nside = nsid ######################## #### remove dipole ##### ######################## if remove_dipole or remove_monopole: starttime = time.time() if remove_monopole: dip_mask_name = remove_monopole if remove_dipole: dip_mask_name = remove_dipole # Mask map for dipole estimation if dip_mask_name == 'auto': mono, dip = hp.fit_dipole(m, gal_cut=30) else: m_masked = hp.ma(m) m_masked.mask = np.logical_not(hp.read_map(dip_mask_name,verbose=False,dtype=None,)) # Fit dipole to masked map mono, dip = hp.fit_dipole(m_masked) # Subtract dipole map from data if remove_dipole: click.echo(click.style("Removing dipole:", fg="yellow")) click.echo(click.style("Dipole vector:",fg="green") + f" {dip}") click.echo(click.style("Dipole amplitude:",fg="green") + f" {np.sqrt(np.sum(dip ** 2))}") # Create dipole template nside = int(nside) ray = range(hp.nside2npix(nside)) vecs = hp.pix2vec(nside, ray) dipole = np.dot(dip, vecs) m = m - dipole if remove_monopole: click.echo(click.style("Removing monopole:", fg="yellow")) click.echo(click.style("Mono:",fg="green") + f" {mono}") m = m - mono click.echo(f"Dipole removal : {(time.time() - starttime)}") if verbose else None ####################### #### Auto-param ##### ####################### # Reset these every signal tempmin = min tempmax = max tempmid = mid temptitle = title templtitle = ltitle tempunit = unit templogscale = logscale tempcmap = cmap # Scale map if scale: if "chisq" in outfile: click.echo(click.style(f"Scaling chisq data with dof={scale}",fg="yellow")) m = (m-scale)/np.sqrt(2*scale) else: click.echo(click.style(f"Scaling data by {scale}",fg="yellow")) m *= scale if auto: (_title, ticks, cmp, lgscale,) = get_params(m, outfile, polt, signal_label,) # Title if _title["stddev"]: if _title["special"]: ttl = r"$\sigma_{\mathrm{" + _title["param"].replace("$","") + "}}$" else: #_title["param"] + r"$_{\mathrm{" + _title["comp"] + "}}^{\sigma}$" ttl = r"$\sigma_{\mathrm{" + _title["comp"] + "}}$" elif _title["rms"]: ttl = _title["param"] + r"$_{\mathrm{" + _title["comp"] + "}}^{\mathrm{RMS}}$" elif _title["mean"]: #r"$\langle$" + _title["param"] + r"$\rangle$" + r"$_{\mathrm{" + _title["comp"] + "}}^{ }$" ttl = r"$\langle$" + _title["param"] + r"$_{\mathrm{" + _title["comp"] + "}}^{ }$" + r"$\rangle$" elif _title["diff"]: ttl = r"$\Delta$ " + _title["param"] + r"$_{\mathrm{" + _title["comp"] + "}}^{" + _title["diff_label"] + "}$" else: ttl = _title["param"] + r"$_{\mathrm{" + _title["comp"] + "}}^{ }$" try: ttl = _title["custom"] except: pass # Left signal label lttl = r"$" + _title["sig"] +"$" if lttl == "$I$": lttl = "$T$" elif lttl == "$QU$": lttl= "$P$" # Tick bug fix mn = ticks[0] mx = ticks[-1] md = None if not mid and len(ticks)>2: if ticks[0]<ticks[1] and ticks[-2]<ticks[-1]: md = ticks[1:-1] else: ticks.pop(1) # Unit unt = _title["unit"] else: ttl = "" lttl = "" unt = "" md = None ticks = [False, False] cmp = "planck" lgscale = False # If min and max have been specified, set. if rng == "auto" and not auto: click.echo(click.style("Setting range from 97.5th percentile of data",fg="yellow")) mn, mx = get_ticks(m, 97.5) elif rng == "minmax": click.echo(click.style("Setting range from min to max of data",fg="yellow")) mn = np.min(m) mx = np.max(m) else: try: if float(rng)>0.0: mn = -float(rng) mx = float(rng) ticks = [False, 0.0, False] except: pass if min is False: min = mn else: min = float(min) if max is False: max = mx else: max = float(max) ticks[0] = min ticks[-1] = max if mid: ticks = [min, *mid, max] elif md: ticks = [min, *md, max] ticks = [float(i) for i in ticks] ########################## #### Plotting Params ##### ########################## # Upper right title if not title: title = ttl # Upper left title if not ltitle: ltitle = lttl # Unit under colorbar if not unit: unit = unt # Image size - ratio is always 1/2 xsize = 2000 ysize = int(xsize / 2.0) ticklabels = ticks ####################### #### logscale ##### ####################### # Some maps turns on logscale automatically # -logscale command overwrites this if logscale == None: logscale = lgscale if logscale: click.echo(click.style("Applying semi-logscale", fg="yellow", blink=True, bold=True)) starttime = time.time() linthresh=1 m = symlog(m,linthresh) ticks = [] for i in ticklabels: ticks.append(symlog(i,linthresh)) m = np.maximum(np.minimum(m, ticks[-1]), ticks[0]) click.echo("Logscale", (time.time() - starttime),) if verbose else None ###################### #### COLOR SETUP ##### ###################### # Chose colormap manually if cmap == None: # If not defined autoset or goto planck cmap = cmp if cmap == "planck": from pathlib import Path if False: #logscale: cmap = Path(__file__).parent / "planck_cmap_logscale.dat" else: cmap = Path(__file__).parent / "planck_cmap.dat" cmap = col.ListedColormap(np.loadtxt(cmap) / 255.0, "planck") elif cmap.startswith("q-"): import plotly.colors as pcol _, clab, *numvals = cmap.split("-") colors = getattr(pcol.qualitative, clab) if clab=="Plotly": #colors.insert(3,colors.pop(-1)) colors.insert(0,colors.pop(-1)) colors.insert(3,colors.pop(2)) try: cmap = col.ListedColormap(colors[:int(numvals[0])], f'{clab}-{numvals[0]}') click.echo(click.style("Using qualitative colormap:", fg="yellow") + f" {clab} up to {numvals[0]}") except: cmap = col.ListedColormap(colors,clab) click.echo(click.style("Using qualitative colormap:", fg="yellow") + f" {clab}") elif cmap.startswith("black2"): cmap = col.LinearSegmentedColormap.from_list(cmap,cmap.split("2")) else: try: import cmasher cmap = eval(f"cmasher.{cmap}") except: cmap = plt.get_cmap(cmap) click.echo(click.style("Colormap:", fg="green") + f" {cmap.name}") ####################### #### Projection? ##### ####################### theta = np.linspace(np.pi, 0, ysize) phi = np.linspace(-np.pi, np.pi, xsize) longitude = np.radians(np.linspace(-180, 180, xsize)) latitude = np.radians(np.linspace(-90, 90, ysize)) # project the map to a rectangular matrix xsize x ysize PHI, THETA = np.meshgrid(phi, theta) grid_pix = hp.ang2pix(nside, THETA, PHI) ###################### ######## Mask ######## ###################### if mask: click.echo(click.style(f"Masking using {mask}", fg="yellow")) masked = True # Apply mask hp.ma(m) mask_field = polt-3 if polt>2 else polt m.mask = np.logical_not(hp.read_map(mask, field=mask_field, verbose=False, dtype=None)) # Don't know what this does, from paperplots by Zonca. grid_mask = m.mask[grid_pix] grid_map = np.ma.MaskedArray(m[grid_pix], grid_mask) if mfill: cmap.set_bad(mfill) # color of missing pixels # cmap.set_under("white") # color of background, necessary if you want to use # using directly matplotlib instead of mollview has higher quality output else: grid_map = m[grid_pix] ###################### #### Formatting ###### ###################### from matplotlib.projections.geo import GeoAxes class ThetaFormatterShiftPi(GeoAxes.ThetaFormatter): """Shifts labelling by pi Shifts labelling from -180,180 to 0-360""" def __call__(self, x, pos=None): if x != 0: x *= -1 if x < 0: x += 2 * np.pi return GeoAxes.ThetaFormatter.__call__(self, x, pos) # Format tick labels click.echo(click.style("Ticks: ", fg="green") + f"{ticklabels}") ticklabels = [fmt(i, 1) for i in ticklabels] click.echo(click.style("Unit: ", fg="green") + f"{unit}") click.echo(click.style("Title: ", fg="green") + f"{title}") sizes = get_sizes(size) for width in sizes: # Size of plot click.echo(click.style("Size: ", fg="green") + str(width)) height = width / 2.0 height *= 1.275 if colorbar else 1 # Make sure text doesnt change with colorbar ################ ##### font ##### ################ fontsize = 10 fig = plt.figure(figsize=(cm2inch(width), cm2inch(height),),) ax = fig.add_subplot(111, projection="mollweide") # rasterized makes the map bitmap while the labels remain vectorial # flip longitude to the astro convention image = plt.pcolormesh(longitude[::-1], latitude, grid_map, vmin=ticks[0], vmax=ticks[-1], rasterized=True, cmap=cmap, shading='auto',) # graticule ax.set_longitude_grid(60) ax.xaxis.set_major_formatter(ThetaFormatterShiftPi(60)) if width < 10: ax.set_latitude_grid(45) ax.set_longitude_grid_ends(90) ################ ### COLORBAR ### ################ if colorbar: # colorbar from matplotlib.ticker import FuncFormatter, LogLocator cb = fig.colorbar(image, orientation="horizontal", shrink=0.4, pad=0.08, ticks=ticks, format=FuncFormatter(fmt),) cb.ax.set_xticklabels(ticklabels) cb.ax.xaxis.set_label_text(unit) cb.ax.xaxis.label.set_size(fontsize) if logscale: #if f == 0: # linticks = np.array([]) #else: linticks = np.linspace(-1, 1, 3)*linthresh logmin = np.round(ticks[0]) logmax = np.round(ticks[-1]) logticks_min = -10**np.arange(0, abs(logmin)+1) logticks_max = 10**np.arange(0, logmax+1) ticks_ = np.unique(np.concatenate((logticks_min, linticks, logticks_max))) #cb.set_ticks(np.concatenate((ticks,symlog(ticks_))), []) # Set major ticks logticks = symlog(ticks_, linthresh) logticks = [x for x in logticks if x not in ticks] cb.set_ticks(np.concatenate((ticks,logticks ))) # Set major ticks cb.ax.set_xticklabels(ticklabels + ['']*len(logticks)) minorticks = np.linspace(-linthresh, linthresh, 5) minorticks2 = np.arange(2,10)*linthresh for i in range(len(logticks_min)): minorticks = np.concatenate((-10**i*minorticks2,minorticks)) for i in range(len(logticks_max)): minorticks = np.concatenate((minorticks, 10**i*minorticks2)) minorticks = symlog(minorticks, linthresh) minorticks = minorticks[ (minorticks >= ticks[0]) & ( minorticks<= ticks[-1]) ] cb.ax.xaxis.set_ticks(minorticks, minor=True) cb.ax.tick_params(which="both", axis="x", direction="in", labelsize=fontsize,) cb.ax.xaxis.labelpad = 4 # -11 # workaround for issue with viewers, see colorbar docstring cb.solids.set_edgecolor("face") # remove longitude tick labels ax.xaxis.set_ticklabels([]) # remove horizontal grid ax.xaxis.set_ticks([]) ax.yaxis.set_ticklabels([]) ax.yaxis.set_ticks([]) plt.grid(True) ################### ## RIGHT TITLE #### ################### plt.text(4.5, 1.1, r"%s" % title, ha="center", va="center", fontsize=labelsize,) ################## ## LEFT TITLE #### ################## plt.text(-4.5, 1.1, r"%s" % ltitle, ha="center", va="center", fontsize=labelsize,) ############## #### SAVE #### ############## plt.tight_layout() filetype = "png" if png else "pdf" # Turn on transparency unless told otherwise tp = False if white_background else True ############## ## filename ## ############## outfile = outfile.replace("_IQU_", "_") outfile = outfile.replace("_I_", "_") filename = [] filename.append(f"{str(int(fwhm))}arcmin") if float(fwhm) > 0 else None filename.append("cb") if colorbar else None filename.append("masked") if masked else None filename.append("nodip") if remove_dipole else None filename.append("dark") if darkmode else None filename.append(f"c-{cmap.name}") nside_tag = "_n" + str(int(nside)) if nside_tag in outfile: outfile = outfile.replace(nside_tag, "") fn = outfile + f"_{signal_label}_w{str(int(width))}" + nside_tag for i in filename: fn += f"_{i}" fn += f".{filetype}" starttime = time.time() if outdir: fn = outdir + "/" + os.path.split(fn)[-1] click.echo(click.style("Output:", fg="green") + f" {fn}") plt.savefig(fn, bbox_inches="tight", pad_inches=0.02, transparent=tp, format=filetype,dpi=dpi) click.echo("Savefig", (time.time() - starttime),) if verbose else None plt.close() click.echo("Totaltime:", (time.time() - totaltime),) if verbose else None min = tempmin max = tempmax mid = tempmid mn = mx = md = None title = temptitle ltitle = temptitle unit = tempunit logscale = templogscale cmap = tempcmap
#!/usr/bin/env python import healpy as hp import numpy as np nside = 16 xyz = hp.pix2vec(nside, np.arange(0, 12*nside**2)) c, [dx, dy, dz] = hp.fit_dipole(np.ones(12*nside**2)) print 'c' + (' dipole map c, [dx, dy, dz] = %+2.2e, [%+2.2e, %+2.2e, %+2.2e]' % (c, dx, dy, dz)) for i, f in zip( (0, 1, 2), ('x', 'y', 'z') ): c, [dx, dy, dz] = hp.fit_dipole(xyz[i]) print f + (' dipole map c, [dx, dy, dz] = %+2.2e, [%+2.2e, %+2.2e, %+2.2e]' % (c, dx, dy, dz)) alm = np.zeros(3, dtype=np.complex) alm[0] = np.random.standard_normal(1)[0] alm[1] = np.random.standard_normal(1)[0] alm[2] = np.random.standard_normal(1)[0] + np.random.standard_normal(1)[0]*1.j tmap = hp.alm2map(alm, nside) c, [dx, dy, dz] = hp.fit_dipole(tmap) alm_c = +alm[0].real / np.sqrt(4.*np.pi) alm_dz = +alm[1].real / np.sqrt(4.*np.pi/3.) alm_dx = -alm[2].real / np.sqrt(2.*np.pi/3.) alm_dy = +alm[2].imag / np.sqrt(2.*np.pi/3.) print ' c = ', c, ' dx = ', dx, ' dy = ', dy, ' dz = ', dz print 'alm_c = ', alm_c, ' alm_dx = ', alm_dx, ' alm_dy = ', alm_dy, ' alm_dz = ', alm_dz
def smooth_combine(maps_and_weights, variance_maps_and_weights=None, fwhm=np.radians(2.0), degraded_nside=32, spectra=False, smooth_mask=False, spectra_mask=False, base_filename="out", root_folder=".", metadata={}, chi2=False): """Combine, smooth, take-spectra, write metadata The maps (I or IQU) are first combined with their own weights, then smoothed and degraded. This function writes a combined smoothed and degraded map, a spectra 1 or 6 components (not degraded) and a json file with metadata Parameters ---------- maps_and_weights : list of tuples [(map1_array, map1_weight), (map2_array, map2_weight), ...] each tuple contains a I or IQU map to be combined with its own weight to give the final map variance_maps_and_weights : list of tuples same as maps_and_weights but containing variances fwhm : double smoothing gaussian beam width in radians degraded_nside : integer nside of the output map spectra : bool whether to compute and write angular power spectra of the combined map smooth_mask, spectra_mask : bool array masks for smoothing and spectra, same nside of input maps, masks shoud be true *inside* the masked region. spectra are masked with both masks. Typically smooth_mask should be a point source mask, while spectra_mask a galaxy plane mask. base_filename : string base filename of the output files root_folder : string root path of the output files metadata : dict initial state of the metadata to be written to the json files Returns ------- None : all outputs are written to fits files """ log.debug("smooth_combine") # check if I or IQU is_IQU = len(maps_and_weights[0][0]) == 3 if not is_IQU: assert hp.isnpixok(len(maps_and_weights[0][0])), "Input maps must have either 1 or 3 components" combined_map = combine_maps(maps_and_weights) for m in combined_map: m.mask |= smooth_mask if not variance_maps_and_weights is None: combined_variance_map = combine_maps(variance_maps_and_weights) for m in combined_variance_map: m.mask |= smooth_mask monopole_I, dipole_I = hp.fit_dipole(combined_map[0], gal_cut=30) # remove monopole, only I combined_map[0] -= monopole_I if spectra: # save original masks orig_mask = [m.mask.copy() for m in combined_map] # spectra log.debug("Anafast") for m in combined_map: m.mask |= spectra_mask # dividing by two in order to recover the same noise as the average map (M1 - M2)/2 cl = hp.anafast([m/2. for m in combined_map]) # sky fraction sky_frac = (~combined_map[0].mask).sum()/float(len(combined_map[0])) if is_IQU: for cl_comp in cl: cl_comp /= sky_frac else: cl /= sky_frac # write spectra log.debug("Write cl: " + base_filename + "_cl.fits") try: hp.write_cl(os.path.join(root_folder, base_filename + "_cl.fits"), cl) except exceptions.NotImplementedError: log.error("Write IQU Cls to fits requires more recent version of healpy") del cl if not variance_maps_and_weights is None: # expected cl from white noise # /4. to have same normalization of cl metadata["whitenoise_cl"] = utils.get_whitenoise_cl(combined_variance_map[0]/4., mask=combined_map[0].mask) / sky_frac if is_IQU: # /2. is the mean, /4. is the half difference in power metadata["whitenoise_cl_P"] = utils.get_whitenoise_cl((combined_variance_map[1] + combined_variance_map[2])/2./4., mask=combined_map[1].mask | combined_map[2].mask) / sky_frac # restore masks for m, mask in zip(combined_map, orig_mask): m.mask = mask # smooth log.debug("Smooth") smoothed_map = hp.smoothing(combined_map, fwhm=fwhm) if not variance_maps_and_weights is None: log.debug("Smooth Variance") if is_IQU: smoothed_variance_map = [utils.smooth_variance_map(var, fwhm=fwhm) for var in combined_variance_map] for comp,m,var in zip("IQU", smoothed_map, smoothed_variance_map): metadata["map_chi2_%s" % comp] = np.mean(m**2 / var) for comp,m,var in zip("IQU", combined_map, combined_variance_map): metadata["map_unsm_chi2_%s" % comp] = np.mean(m**2 / var) else: smoothed_variance_map = utils.smooth_variance_map(combined_variance_map[0], fwhm=fwhm) metadata["map_chi2"] = np.mean(smoothed_map**2 / smoothed_variance_map) metadata["map_unsm_chi2"] = np.mean(combined_map[0]**2 / combined_variance_map[0]) del smoothed_variance_map # removed downgrade of variance # smoothed_variance_map = hp.ud_grade(smoothed_variance_map, degraded_nside, power=2) # fits log.info("Write fits map: " + base_filename + "_map.fits") smoothed_map = hp.ud_grade(smoothed_map, degraded_nside) hp.write_map(os.path.join(root_folder, base_filename + "_map.fits"), smoothed_map) # metadata metadata["base_file_name"] = base_filename metadata["file_name"] = base_filename + "_cl.fits" metadata["file_type"] += "_cl" metadata["removed_monopole_I"] = monopole_I metadata["dipole_I"] = tuple(dipole_I) if spectra: metadata["sky_fraction"] = sky_frac with open(os.path.join(root_folder, base_filename + "_cl.json"), 'w') as f: json.dump(metadata, f, indent=4) metadata["file_name"] = base_filename + "_map.fits" metadata["file_type"] = metadata["file_type"].replace("_cl","_map") metadata["smooth_fwhm_deg"] = "%.2f" % np.degrees(fwhm) metadata["out_nside"] = degraded_nside if is_IQU: for comp,m in zip("IQU", smoothed_map): metadata["map_p2p_%s" % comp] = m.ptp() metadata["map_std_%s" % comp] = m.std() else: metadata["map_p2p_I"] = smoothed_map.ptp() metadata["map_std_I"] = smoothed_map.std() with open(os.path.join(root_folder, base_filename + "_map.json"), 'w') as f: json.dump(metadata, f, indent=4)