-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpca_systematics.py
135 lines (100 loc) · 4.08 KB
/
pca_systematics.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#####################################################################################################
# -
#####################################################################################################
import config
import healpy as hp
import healsparse as hsp
import numpy as np
from map_utils import *
from output_utils import colour_string
import os
import glob
### SETTINGS ###
cf = config.pcaSystematics
if cf.plot_eigen:
import plot_utils as pu
from matplotlib import pyplot as plt
plt.style.use(pu.styledict)
###################
#### FUNCTIONS ####
###################
def load_systmap_hsp(map_path, mask):
'''
Loads a HealSparse map, and uses the mask to retrieve only the valid pixels,
and also compute and subtract the mean.
Parameters
----------
map_path: str
Path to the HealSparse map being loaded.
mask: MaskData
MaskData object containing all information about the mask.
Returns
-------
systmap: np.array
Systematics map data in all valid pixels,
'''
#load the systematics map
systmap = hsp.HealSparseMap.read(map_path)
#get the valid pixels from the mask (NEST ordering)
vpix = mask.vpix_nest
#keep only these pixels and convert any hp.UNSEEN or NaNs to zero
systmap = systmap[vpix].astype(np.float64)
systmap[systmap == hp.UNSEEN] = 0.
systmap[np.isnan(systmap)] = 0.
#calculate the weighted mean
mu = np.sum(systmap * mask.mask[mask.vpix]) / mask.sum
#subtract this from the data
systmap -= mu
return systmap
#######################################################
############### START OF SCRIPT #################
#######################################################
for fd in cf.get_global_fields():
print(colour_string(fd.upper(), 'orange'))
#relevant directories
PATH_MAPS = cf.PATH_OUT + f'{fd}/'
PATH_SYST = PATH_MAPS + 'systmaps/'
PATH_PCA = PATH_SYST + 'pca/'
#load the mask data
MD = MaskData(PATH_MAPS + f'survey_mask_{cf.nside_hi}.hsp', mask_thresh=cf.weight_thresh)
mask = MD.mask[MD.vpix]
#get the number of (valid) pixels
Npix = len(MD.vpix_nest)
#get the filenames of all systematics maps at the correct NSIDE
systs = [os.path.basename(m) for m in (glob.glob(f'{PATH_SYST}*_{cf.nside_hi}.hsp') + glob.glob(f'{PATH_SYST}*_{cf.nside_hi}_*.hsp'))]
Nsyst = len(systs)
#set up an array for the data
data_orig = np.array(np.zeros((Npix, Nsyst)))
#load each systematic and store in the array
for i, s in enumerate(systs):
sm = load_systmap_hsp(PATH_SYST + s, mask=MD)
data_orig[:,i] = sm
#standardise the data
data_orig /= data_orig.std(axis=0)
#compute the weighted covariance matrix
cov = (1 / MD.sum) * data_orig.T * mask[None, :]
cov = np.matmul(cov, data_orig)
#compute the eigenvectors and eigenvalues
eigvals, eigvecs = np.linalg.eig(cov)
#sort the eigenvalues and eigenvectors by order of decreasing eigenvalue
idx_sort = np.argsort(eigvals)[::-1]
eigvals = eigvals[idx_sort]
eigvecs = eigvecs[:,idx_sort]
if cf.plot_eigen:
f, ax = plt.subplots()
ax.set_xlabel('Principal component')
ax.set_ylabel('Fraction of total variance')
#along the x axis just plot integer label for each principal component
X = np.arange(Nsyst).astype(int) + 1
#plot the fraction of the total variance contained within each PC
Y = eigvals.real / eigvals.real.sum()
ax.plot(X, Y)
#determine the number of PCs required to contain the desired fraction of the total variance
PC_max = np.argwhere(np.cumsum(Y) > cf.var_thresh).min()
#plot the cutoff as a vertical line
ax.axvline(PC_max + 0.5, c=pu.red, linestyle='--')
ax.text(PC_max+1.7, Y.max()*0.95, f'{int(100*cf.var_thresh)}\% variance', rotation=0, va='center', ha='left', color=pu.red)
#set y-axis limits
#ax.set_ylim(0., Y.max()*1.02)
f.tight_layout()
f.savefig(cf.PATH_PLOTS + f'systematics_pca_variance_{fd}.png', dpi=300)