33import numbers
44from collections import defaultdict
55from dataclasses import dataclass
6- from typing import Union , List , Any , Optional
6+ from typing import Union , List , Any , Optional , Dict
77
88import astropy .time
99import 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
0 commit comments