Skip to content

Commit 0a252de

Browse files
committed
add selective incremental changes from #372
1 parent deaa35c commit 0a252de

3 files changed

Lines changed: 37 additions & 21 deletions

File tree

litebird_sim/io.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ def write_list_of_observations(
470470
observations = [observations]
471471
except IndexError:
472472
# Empty list
473-
# We do not want to return here, as we still need to participate to
473+
# We do not want to return here, as we still need to participate in
474474
# the call to _compute_global_start_index below
475475
observations = [] # type: List[Observation]
476476

litebird_sim/observations.py

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import numbers
44
from collections import defaultdict
55
from dataclasses import dataclass
6-
from typing import Union, List, Any, Optional
6+
from typing import Union, List, Any, Optional, Dict
77

88
import astropy.time
99
import numpy as np
@@ -243,40 +243,52 @@ def _get_local_start_time_start_and_n_samples(self):
243243

244244
return self.start_time_global + start * delta, start, num
245245

246-
def _set_attributes_from_list_of_dict(self, list_of_dict, root):
246+
def _set_attributes_from_list_of_dict(
247+
self,
248+
list_of_dict: List[Dict[str, str]],
249+
root: int,
250+
) -> None:
251+
"""
252+
Take a list of dictionaries describing each detector and propagate them
253+
"""
247254
np.testing.assert_equal(len(list_of_dict), self.n_detectors_global)
248255

249256
# Turn list of dict into dict of arrays
250257
if not self.comm or self.comm.rank == root:
251258
# Build a list of all the keys in the dictionaries contained within
252-
# `list_of_dict` (which is a *list* of dictionaries)
259+
# `list_of_dict` (which is a *list* of dictionaries). `keys` is a list of
260+
# strings like `name`, `net_ukrts`, `fknee_mhz`, etc.
253261
keys = list(set().union(*list_of_dict) - set(dir(self)))
254262

255263
# This will be the dictionary associating each key with the
256-
# *array* of value for that dictionary
257-
dict_of_array = {k: [] for k in keys}
264+
# *array* of values for that dictionary
265+
dict_of_array = {cur_key: [] for cur_key in keys}
258266

259267
# This array associates either np.nan or None to each type;
260268
# the former indicates that the value is a NumPy array, while
261269
# None is used for everything else
262270
nan_or_none = {}
263-
for k in keys:
264-
for d in list_of_dict:
265-
if k in d:
271+
for cur_key in keys:
272+
for cur_det_dict in list_of_dict:
273+
if cur_key in cur_det_dict:
266274
try:
267-
nan_or_none[k] = np.nan * d[k]
275+
nan_or_none[cur_key] = np.nan * cur_det_dict[cur_key]
268276
except TypeError:
269-
nan_or_none[k] = None
277+
nan_or_none[cur_key] = None
270278
break
271279

272280
# Finally, build `dict_of_array`
273-
for d in list_of_dict:
274-
for k in keys:
275-
dict_of_array[k].append(d.get(k, nan_or_none[k]))
281+
for cur_det_dict in list_of_dict:
282+
for cur_key in keys:
283+
dict_of_array[cur_key].append(
284+
cur_det_dict.get(cur_key, nan_or_none[cur_key])
285+
)
276286

277-
# Why should this code iterate over `keys`?!?
278-
for k in keys:
279-
dict_of_array = {k: np.array(dict_of_array[k]) for k in keys}
287+
# So far, dict_of_array entries are plain lists. This converts them into
288+
# NumPy arrays
289+
dict_of_array = {
290+
cur_key: np.array(dict_of_array[cur_key]) for cur_key in keys
291+
}
280292
else:
281293
keys = None
282294
dict_of_array = {}
@@ -285,8 +297,8 @@ def _set_attributes_from_list_of_dict(self, list_of_dict, root):
285297
if self.comm and self.comm.size > 1:
286298
keys = self.comm.bcast(keys)
287299

288-
for k in keys:
289-
self.setattr_det_global(k, dict_of_array.get(k), root)
300+
for cur_key in keys:
301+
self.setattr_det_global(cur_key, dict_of_array.get(cur_key), root)
290302

291303
@property
292304
def n_samples_global(self):
@@ -814,7 +826,7 @@ def prepare_pointings(
814826

815827
# If the hwp object is passed and is not initialised in the observations, it gets applied to all detectors
816828
if hwp is None:
817-
assert all(m is None for m in self.mueller_hwp), (
829+
assert self.no_mueller_hwp(), (
818830
"Some detectors have been initialized with a mueller_hwp,"
819831
"but no HWP object has been passed to prepare_pointings."
820832
)
@@ -1019,6 +1031,10 @@ def precompute_pointings(
10191031
self.pointing_matrix = pointing_matrix
10201032
self.hwp_angle = hwp_angle
10211033

1034+
def no_mueller_hwp(self) -> bool:
1035+
"Return True if no detectors have defined a Mueller matrix for the HWP"
1036+
return (self.mueller_hwp is None) or all(m is None for m in self.mueller_hwp)
1037+
10221038
def _set_mpi_subcommunicators(self):
10231039
"""
10241040
This function splits the global MPI communicator into three kinds of

litebird_sim/pointings_in_obs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def _get_hwp_angle(
119119
hwp_angle = obs.get_hwp_angle(pointings_dtype=pointing_dtype)
120120
else:
121121
if hasattr(obs, "mueller_hwp"):
122-
assert all(m is None for m in obs.mueller_hwp), (
122+
assert obs.no_mueller_hwp(), (
123123
"Detectors have been initialized with a mueller_hwp,"
124124
"but no HWP is either passed or initilized in the pointing"
125125
)

0 commit comments

Comments
 (0)