Skip to content

Commit eae0ec5

Browse files
committed
new nulls parsing
1 parent 4a8cb1d commit eae0ec5

1 file changed

Lines changed: 109 additions & 39 deletions

File tree

‎pspipe_utils/pspipe_list.py‎

Lines changed: 109 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import os
77
import re
88
import numpy as np
9+
import yaml
910

1011
def get_windownames_list(dict):
1112
"""Get the unique window names from the paramdict."""
@@ -44,50 +45,119 @@ def get_arrays_list(dict):
4445
n_arrays += 1
4546
return n_arrays, sv_list, ar_list
4647

47-
def get_spectra_list(dict):
48+
# to get around delimiters...
49+
def get_sv_and_m_from_sv_m(sv_m, sv_m_list, sv_list, m_list):
50+
idx = sv_m_list.index(sv_m)
51+
return sv_list[idx], m_list[idx]
52+
53+
# given a dictionary of rules, test if a pair of two dicts of tags passes
54+
def eval_mpair_rules(t1, t2, rules):
55+
if not rules:
56+
return True
57+
58+
# 1. Require specific tags (strict list pools expected)
59+
for tag_key, (pool1, pool2) in rules.get('require_tags', {}).items():
60+
v1 = t1.get(tag_key)
61+
v2 = t2.get(tag_key)
62+
63+
# Check standard and flipped orientations using the pools
64+
match_standard = (v1 in pool1) and (v2 in pool2)
65+
match_flipped = (v1 in pool2) and (v2 in pool1)
66+
67+
if not (match_standard or match_flipped):
68+
return False
69+
70+
# 2. Dynamic matching (must have the same value for these tags)
71+
if 'match_any_tag' in rules:
72+
if not any(t1.get(key) == t2.get(key) for key in rules['match_any_tag']):
73+
return False
74+
75+
if 'match_all_tags' in rules:
76+
if not all(t1.get(key) == t2.get(key) for key in rules['match_all_tags']):
77+
return False
78+
79+
return True
80+
81+
def get_spec2nullgroup2nullflag_mpairs(d, return_spectra_list=False):
82+
with open(d['spec2nullgroup2nullflag_mpairs_yaml'], 'r') as file:
83+
inp = yaml.safe_load(file)
84+
85+
_, _sv_list, _m_list = get_arrays_list(d)
86+
_sv_m_list = ['_'.join(_sv_m) for _sv_m in zip(_sv_list, _m_list)] # assume delimiter = '_' to match against tags dict
87+
_full_mpairs_list = list(cwr(_sv_m_list, r=2))
88+
_full_mpairs_list_with_reversed = list(product(_sv_m_list, repeat=2))
89+
90+
spec2nullgroup2nullflag_mpairs = {}
91+
_spec_name_list = [], []
92+
for spec, nullgroup2nullflag_mpairrules in inp.items():
93+
if spec[0] == spec[1]:
94+
mpairs_iter = _full_mpairs_list
95+
else:
96+
mpairs_iter = _full_mpairs_list_with_reversed
97+
98+
spec2nullgroup2nullflag_mpairs[spec] = {}
99+
for nullgroup, nullflag_mpairrules in nullgroup2nullflag_mpairrules.items():
100+
spec2nullgroup2nullflag_mpairs[spec][nullgroup] = [nullflag_mpairrules['nullflag']]
101+
102+
mpairrules = nullflag_mpairrules.get('mpair_rules', {})
103+
mpairs = [f'{m1}x{m2}' for m1, m2 in mpairs_iter if eval_mpair_rules(d[f'tags_{m1}'], d[f'tags_{m2}'], mpairrules)]
104+
105+
assert len(mpairs) == len(np.unique(mpairs)), \
106+
f'mpairs from spec2nullgroup2nullflag_mpairs_yaml, {spec} not unique'
107+
108+
spec2nullgroup2nullflag_mpairs[spec][nullgroup].append(mpairs)
109+
110+
for mpair in mpairs:
111+
for _mpair in (mpair, 'x'.join(mpair.split('x')[::-1])):
112+
if _mpair in _full_mpairs_list and _mpair not in _spec_name_list:
113+
_spec_name_list.append(_mpair)
114+
115+
# from _spec_name_list to spectra list.
116+
# do this because "spectra_list" is more fundamental even though spec_name_list is used as
117+
# an intermediary above because it's easier to test membership in
118+
n_spec = 0
119+
sv1_list, ar1_list, sv2_list, ar2_list = [], [], [], []
120+
for _spec_name in _spec_name_list:
121+
n1, n2 = _spec_name.split('x')
122+
sv1, ar1 = get_sv_and_m_from_sv_m(n1, _sv_m_list, _sv_list, _m_list)
123+
sv2, ar2 = get_sv_and_m_from_sv_m(n2, _sv_m_list, _sv_list, _m_list)
124+
sv1_list += [sv1]
125+
ar1_list += [ar1]
126+
sv2_list += [sv2]
127+
ar2_list += [ar2]
128+
n_spec += 1
129+
130+
if return_spectra_list:
131+
return spec2nullgroup2nullflag_mpairs, (n_spec, sv1_list, ar1_list, sv2_list, ar2_list)
132+
else:
133+
return spec2nullgroup2nullflag_mpairs
134+
135+
def get_spectra_list(dict, from_spec_nullgroups=False):
48136
"""This function creates the lists over which mpi is done
49-
when we parallelized over each spectra
50-
If combinations_infos appears in the paramfile, precompute the list of skipped computations
51-
It look at keys (sv1, sv2) in d["comibations_infos"] that should be a list of :
52-
"skip": skips all combinations of sv1 with sv2
53-
"tube": skips all combinations except with same tube (using tags_sv*_ar*)
54-
"freq": skips all combinations except with same freq (using tags_sv*_ar*)
55-
"smthg": skips all combinations except with same "smthg" (using tags_sv*_ar*)
56-
"tube" and "freq" are used by convention but you can put anything,
57-
as long as it appears in tags_sv*_ar*.
58-
If the list is empty, then it will skip everything (like "skip").
59-
To not skip anything, d["comibations_infos"][sv1, sv2] must be None
60-
or [sv1, sv2] must not appear in d["comibations_infos"].
137+
when we parallelized over each spectra.
61138
62139
Parameters
63140
----------
64141
dict : dict
65142
the global dictionnary file used in pspipe
66143
67144
"""
68-
surveys = dict["surveys"]
69-
70-
def check_combination(sv1, ar1, sv2, ar2, comb_list):
71-
if comb_list is None: return True
72-
elif 'skip' in comb_list: return False # If skip, doesnot even need tags_...
73-
74-
tags_ar1 = dict[f'tags_{sv1}_{ar1}']
75-
tags_ar2 = dict[f'tags_{sv2}_{ar2}']
76-
77-
return any(tags_ar1[kw] == tags_ar2[kw] for kw in comb_list)
145+
if from_spec_nullgroups:
146+
_, (n_spec, sv1_list, ar1_list, sv2_list, ar2_list) = get_spec2nullgroup2nullflag_mpairs(dict, return_spec_name_list=True)
78147

79-
sv1_list, ar1_list, sv2_list, ar2_list = [], [], [], []
80-
n_spec = 0
81-
for id_sv1, sv1 in enumerate(surveys):
82-
arrays_1 = dict[f"arrays_{sv1}"]
83-
for id_ar1, ar1 in enumerate(arrays_1):
84-
for id_sv2, sv2 in enumerate(surveys):
85-
arrays_2 = dict[f"arrays_{sv2}"]
86-
for id_ar2, ar2 in enumerate(arrays_2):
87-
if (id_sv1 > id_sv2) : continue
88-
if (id_sv1 == id_sv2) & (id_ar1 > id_ar2) : continue
89-
if ('combination_args' not in dict) or (check_combination(sv1, ar1, sv2, ar2, dict['combination_args'][(sv1, sv2)])):
90-
# This ensures that we do not repeat redundant computations
148+
else:
149+
surveys = dict["surveys"]
150+
151+
sv1_list, ar1_list, sv2_list, ar2_list = [], [], [], []
152+
n_spec = 0
153+
for id_sv1, sv1 in enumerate(surveys):
154+
arrays_1 = dict[f"arrays_{sv1}"]
155+
for id_ar1, ar1 in enumerate(arrays_1):
156+
for id_sv2, sv2 in enumerate(surveys):
157+
arrays_2 = dict[f"arrays_{sv2}"]
158+
for id_ar2, ar2 in enumerate(arrays_2):
159+
if (id_sv1 > id_sv2) : continue
160+
if (id_sv1 == id_sv2) & (id_ar1 > id_ar2) : continue
91161
sv1_list += [sv1]
92162
ar1_list += [ar1]
93163
sv2_list += [sv2]
@@ -96,7 +166,7 @@ def check_combination(sv1, ar1, sv2, ar2, comb_list):
96166

97167
return n_spec, sv1_list, ar1_list, sv2_list, ar2_list
98168

99-
def get_covariances_list(dict, delimiter="&"):
169+
def get_covariances_list(dict, delimiter="&", from_spec_nullgroups=False):
100170
"""This function creates the lists over which mpi is done
101171
when we parallelized over each covariance element
102172
@@ -107,7 +177,7 @@ def get_covariances_list(dict, delimiter="&"):
107177
108178
"""
109179

110-
spec_name = get_spec_name_list(dict, delimiter)
180+
spec_name = get_spec_name_list(dict, delimiter=delimiter, from_spec_nullgroups=from_spec_nullgroups)
111181
na_list, nb_list, nc_list, nd_list = [], [], [], []
112182
ncovs = 0
113183

@@ -124,7 +194,7 @@ def get_covariances_list(dict, delimiter="&"):
124194

125195
return ncovs, na_list, nb_list, nc_list, nd_list
126196

127-
def get_spec_name_list(dict, delimiter="&"):
197+
def get_spec_name_list(dict, delimiter="&", from_spec_nullgroups=False):
128198
"""This function creates a list with the name of all spectra we consider
129199
130200
Parameters
@@ -136,7 +206,7 @@ def get_spec_name_list(dict, delimiter="&"):
136206
"""
137207

138208
spec_name_list = []
139-
n_spec, sv1_list, ar1_list, sv2_list, ar2_list = get_spectra_list(dict)
209+
n_spec, sv1_list, ar1_list, sv2_list, ar2_list = get_spectra_list(dict, from_spec_nullgroups=from_spec_nullgroups)
140210
for sv1, ar1, sv2, ar2 in zip(sv1_list, ar1_list, sv2_list, ar2_list):
141211
spec_name_list += [f"{sv1}{delimiter}{ar1}x{sv2}{delimiter}{ar2}"]
142212

0 commit comments

Comments
 (0)