def nest(self, inner_axes=None, outer_axes=None): """Return a new xpSpace with axes ``outer_axes``, obtained by projecting along the ``inner_axes``. The entries of this ``xpSpace`` are themselves ``xpSpace``s, with axes ``inner_axes``, each one regrouping the entries with the same (projected) coordinate. Note: is also called by ``__getitem__(key)`` if ``key`` is dict.""" # Default: a singleton outer space, # with everything contained in the inner (projection) space. if inner_axes is None and outer_axes is None: outer_axes = () # Validate axes if inner_axes is None: assert outer_axes is not None inner_axes = dict_tools.complement(self.axes, outer_axes) else: assert outer_axes is None outer_axes = dict_tools.complement(self.axes, inner_axes) # Fill spaces outer_space = self.__class__(outer_axes) for coord, entry in self.items(): outer_coord = outer_space.__getkey__(coord) try: inner_space = outer_space[outer_coord] except KeyError: inner_space = self.__class__(inner_axes) outer_space[outer_coord] = inner_space inner_space[inner_space.__getkey__(coord)] = entry return outer_space
def intersect_axes(self, attrs): """Rm those a in attrs that are not in self.axes. This allows errors in the axes allotment, for ease-of-use.""" absent = dict_tools.complement(attrs, self.axes) if absent: print(color_text("Warning:", colorama.Fore.RED), "The requested attributes", color_text(str(absent), colorama.Fore.RED), ("were not found among the" " xpSpace axes (attrs. used as coordinates" " for the set of experiments)." " This may be no problem if the attr. is redundant" " for the coord-sys." " However, if it is caused by confusion or mis-spelling," " then it is likely to cause mis-interpretation" " of the shown results.")) attrs = dict_tools.complement(attrs, absent) return attrs
def for_params(method, **fixed_params): dc_fields = [f.name for f in dcs.fields(method)] params = dict_tools.intersect(param_dict, dc_fields) params = dict_tools.complement(params, fixed_params) params = {**glob_dict, **params} # glob_dict 1st def xp1(dct): xp = method(**dict_tools.intersect(dct, dc_fields), **fixed_params) for key, v in dict_tools.intersect(dct, glob_dict).items(): setattr(xp, key, v) return xp return [xp1(dct) for dct in dict_tools.prodct(params)]
def unpack1(arr, i, uq): if uq is None: return # val/conf if decimals is None: v, c = uq.round(mult=0.1) else: v, c = np.round([uq.val, uq.conf], decimals) arr["val"][i], arr["conf"][i] = v, c # Others for col in dict_tools.complement(cols, ["val", "conf"]): try: arr[col][i] = getattr(uq, col) except AttributeError: pass
def _aggregate_keys(): "Aggregate keys from all `xp`" if len(self) == 0: return [] # Start with da_method aggregate = ['da_method'] # Aggregate all other keys for xp in self: # Get dataclass fields try: dc_fields = dcs.fields(xp.__class__) dc_names = [F.name for F in dc_fields] keys = xp.__dict__.keys() except TypeError: # Assume namedtuple dc_names = [] keys = xp._fields # For all potential keys: for k in keys: # If not already present: if k not in aggregate: # If dataclass, check repr: if k in dc_names: if dc_fields[dc_names.index(k)].repr: aggregate.append(k) # Else, just append else: aggregate.append(k) # Remove unwanted excluded = [re.compile('^_'), 'avrgs', 'stats', 'HMM', 'duration'] aggregate = dict_tools.complement(aggregate, excluded) return aggregate