|
| 1 | +# %% |
| 2 | +from IPython import get_ipython |
| 3 | + |
| 4 | +# %% |
| 5 | +# enable autoreload for interactive sessions |
| 6 | +ipython = get_ipython() |
| 7 | +if ipython is not None: |
| 8 | + ipython.run_line_magic("load_ext", "autoreload") |
| 9 | + ipython.run_line_magic("autoreload", "2") |
| 10 | + ipython.run_line_magic("load_ext", "log_cell_time") |
| 11 | +# %% |
| 12 | +if ipython is not None: |
| 13 | + ipython.run_line_magic("matplotlib", "inline") |
| 14 | + |
| 15 | +# %% |
| 16 | +import sys |
| 17 | +import os |
| 18 | +import numpy as np |
| 19 | +from astropy.io import fits |
| 20 | +import matplotlib.pylab as plt |
| 21 | +import healpy as hp |
| 22 | +import healsparse as hsp |
| 23 | + |
| 24 | +from cs_util import plots as cs_plots |
| 25 | +from cs_util import cat as cs_cat |
| 26 | + |
| 27 | +from sp_validation import run_joint_cat as sp_joint |
| 28 | +from sp_validation import util |
| 29 | +from sp_validation.basic import metacal |
| 30 | +from sp_validation import calibration |
| 31 | +import sp_validation.cat as cat |
| 32 | + |
| 33 | +# %% |
| 34 | +# Initialize calibration class instance (for config and data) |
| 35 | +obj = sp_joint.CalibrateCat() |
| 36 | + |
| 37 | +# %% |
| 38 | +# Read configuration file and set parameters |
| 39 | +config = obj.read_config_set_params("config_mask.yaml") |
| 40 | + |
| 41 | +# %% |
| 42 | +# Get data. Set load_into_memory to False for very large files |
| 43 | +dat, dat_ext = obj.read_cat(load_into_memory=False) |
| 44 | +# %% |
| 45 | +# Additional parameters |
| 46 | +key_ra = "RA" |
| 47 | +key_dec = "Dec" |
| 48 | + |
| 49 | +nside_min = 512 |
| 50 | +nside_max = 16384 |
| 51 | + |
| 52 | +# %% |
| 53 | +# Create healsparse mask instance |
| 54 | +hsp_obj = sp_joint.ApplyHspMasks() |
| 55 | + |
| 56 | +# %% Mask directory and aux mask file(s) |
| 57 | +hsp_obj._params["mask_dir"] = f"{os.environ['HOME']}/masks" |
| 58 | +hsp_obj._params["aux_mask_files"] = f"{hsp_obj._params['mask_dir']}/mask_r_nside131072_npoint.hsp" |
| 59 | +hsp_obj._params["aux_mask_labels"] = "npoint3" |
| 60 | +hsp_obj._params["verbose"] = True |
| 61 | + |
| 62 | +# %% |
| 63 | +# Masks to use |
| 64 | + |
| 65 | +# Bits |
| 66 | +hsp_obj._params["bits"] = 1+2+4+8+64+1024 |
| 67 | + |
| 68 | +# Index of base mask (e.g., coverage mask) |
| 69 | +label_base_mask = "npoint3" |
| 70 | +#label_base_mask = "" |
| 71 | + |
| 72 | +# Names |
| 73 | +masks_to_apply = [ |
| 74 | + "npoint3", |
| 75 | + "1_Faint_star_halos", |
| 76 | + "2_Bright_star_halos", |
| 77 | + "4_Stars", |
| 78 | + "8_Manual", |
| 79 | + "64_r", |
| 80 | + "1024_Maximask", |
| 81 | +] |
| 82 | + |
| 83 | +# Load and initialise masks |
| 84 | +masks, labels = sp_joint.get_masks_from_config( |
| 85 | + config, |
| 86 | + dat, |
| 87 | + dat_ext, |
| 88 | + masks_to_apply=masks_to_apply, |
| 89 | + verbose=True |
| 90 | +) |
| 91 | + |
| 92 | +# %% |
| 93 | +# if base mask: apply to all other masks |
| 94 | +if label_base_mask != "": |
| 95 | + |
| 96 | + print(f"Applying base mask {label_base_mask} to all other masks:") |
| 97 | + |
| 98 | + # Find base mask |
| 99 | + for mask in masks: |
| 100 | + if mask._col_name == label_base_mask: |
| 101 | + base_mask = mask._mask |
| 102 | + break |
| 103 | + |
| 104 | + # Mask all others |
| 105 | + for mask in masks: |
| 106 | + if mask._col_name != label_base_mask: |
| 107 | + mask._mask = mask._mask & base_mask |
| 108 | + print(mask._col_name, "#True = ", sum(mask._mask), f"({100*sum(mask._mask)/len(mask._mask):.2f}%)") |
| 109 | +else: |
| 110 | + print("No base mask applied.") |
| 111 | + |
| 112 | +# %% |
| 113 | +# Bin data |
| 114 | + |
| 115 | +# Create array of nsides between min and max with powers of two |
| 116 | +nsides = np.array([2**i for i in range(int(np.log2(nside_min)), int(np.log2(nside_max))+1)]) |
| 117 | + |
| 118 | +# %% |
| 119 | +areas_deg2 = {} |
| 120 | +for mask in masks: |
| 121 | + |
| 122 | + print(f"Mask: {mask._col_name}") |
| 123 | + areas_deg2[mask._col_name] = {} |
| 124 | + |
| 125 | + # Apply mask to positions |
| 126 | + m = mask._mask |
| 127 | + |
| 128 | + ra = dat[key_ra][m] |
| 129 | + dec = dat[key_dec][m] |
| 130 | + |
| 131 | + for nside in nsides: |
| 132 | + |
| 133 | + area_deg2 = cs_cat.get_binned_area(ra, dec, nside=nside) |
| 134 | + print(f"binned area (nside={nside}) ≈ {area_deg2:.3f} deg^2") |
| 135 | + areas_deg2[mask._col_name][nside] = area_deg2 |
| 136 | + |
| 137 | +# %% |
| 138 | +def save_areas(areas_deg2, filename): |
| 139 | + """Save areas to a ASCII file. |
| 140 | +
|
| 141 | + Parameters |
| 142 | + ---------- |
| 143 | + areas_deg2 : dict |
| 144 | + Dictionary with mask names as keys and another dictionary as values. |
| 145 | + The inner dictionary has nsides as keys and areas in deg² as values. |
| 146 | + filename : str |
| 147 | + Output filename. |
| 148 | + """ |
| 149 | + with open(filename, 'w') as f: |
| 150 | + # Write header |
| 151 | + f.write("# Mask_name nside area_deg2\n") |
| 152 | + for mask_name, area_dict in areas_deg2.items(): |
| 153 | + for nside, area in area_dict.items(): |
| 154 | + f.write(f"{mask_name} {nside} {area:.6f}\n") |
| 155 | + |
| 156 | + print(f"Wrote areas to {filename}") |
| 157 | + |
| 158 | +# %% |
| 159 | + |
| 160 | +# %% |
| 161 | +# Get area of hsp masks |
| 162 | +area_wcov_deg2 = {} |
| 163 | +if True: |
| 164 | + if label_base_mask != "": |
| 165 | + # Coverage = read aux file mask |
| 166 | + coverage = hsp.HealSparseMap.read(hsp_obj._params["aux_mask_files"]) |
| 167 | + area_coverage = coverage.get_valid_area(degrees=True) |
| 168 | + area_wcov_deg2["npoint3"] = area_coverage |
| 169 | + |
| 170 | + # Loop over other, bit-coded masks |
| 171 | + paths = hsp_obj.get_paths_bit_masks() |
| 172 | + for bit, path in paths.items(): |
| 173 | + print(bit, path) |
| 174 | + hsp_mask = hsp.HealSparseMap.read(path) |
| 175 | + |
| 176 | + if label_base_mask != "": |
| 177 | + # Apply coverage mask |
| 178 | + hsp_mask_wcov = coverage & (~hsp_mask) |
| 179 | + else: |
| 180 | + hsp_mask_wcov = ~hsp_mask |
| 181 | + |
| 182 | + key = hsp_obj.get_mask_col_name(bit) |
| 183 | + area_wcov_deg2[key] = hsp_mask_wcov.get_valid_area(degrees=True) |
| 184 | + |
| 185 | +# %% |
| 186 | +# Plot areas |
| 187 | +markers = ['o', 's', '^', 'v', 'D', 'x', '*'] |
| 188 | +ls = ['dashed', 'dotted', 'dashdot', 'solid', (0, (3, 1, 1, 1)), (0, (5, 10)), (0, (1, 10))] |
| 189 | +fig, ax = plt.subplots(figsize=(8,8)) |
| 190 | +plt.xticks(nsides, nsides) |
| 191 | +for idx, mask in enumerate(masks): |
| 192 | + label = mask._col_name |
| 193 | + area_dict = areas_deg2[label] |
| 194 | + nsides = np.array(list(area_dict.keys())) |
| 195 | + dx = cs_plots.dx(idx, len(masks)) |
| 196 | + areas = np.array(list(area_dict.values())) |
| 197 | + ax.plot(nsides * dx, areas, marker=markers[idx], label=label, linestyle=ls[idx]) |
| 198 | + ax.hlines( |
| 199 | + area_wcov_deg2[label], |
| 200 | + nsides[0]*0.8, |
| 201 | + nsides[-1]*1.1, |
| 202 | + colors='C'+str(idx), |
| 203 | + linestyles=ls[idx], |
| 204 | + ) |
| 205 | +plt.legend() |
| 206 | +plt.xlabel("nside") |
| 207 | +plt.ylabel("binned area [deg²]") |
| 208 | +_ = plt.setp(ax.get_xticklabels(), rotation=90, ha="right", rotation_mode="anchor") |
| 209 | +# %% |
| 210 | +cs_plots.savefig("binned_hsp_areas.png") |
| 211 | +# %% |
| 212 | +# Add hsp values to dict of binned catalogue with new "hsp" key |
| 213 | +for key in areas_deg2: |
| 214 | + areas_deg2[key]["hsp"] = area_wcov_deg2[key] |
| 215 | +# %% |
| 216 | +# Write to disk |
| 217 | +save_areas(areas_deg2, "areas.txt") |
0 commit comments