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 = struct_tools.complement(self.axes, outer_axes) else: assert outer_axes is None outer_axes = struct_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 = struct_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 = struct_tools.complement(attrs, absent) return attrs
def for_params(method, **fixed_params): dc_fields = [f.name for f in dcs.fields(method)] params = struct_tools.intersect(param_dict, dc_fields) params = struct_tools.complement(params, fixed_params) params = {**glob_dict, **params} # glob_dict 1st def xp1(dct): xp = method(**struct_tools.intersect(dct, dc_fields), **fixed_params) for key, v in struct_tools.intersect(dct, glob_dict).items(): setattr(xp, key, v) return xp return [xp1(dct) for dct in struct_tools.prodct(params)]
def unpack1(arr, i, uq): if uq is None: return # Columns: val/prec if decimals is None: # v, c = uq.round() v, c = str(uq).split("±") else: v, c = np.round([uq.val, uq.prec], decimals) v = pad0(str(v)) c = pad0(str(c)) arr["val"][i], arr["prec"][i] = v.replace(" ", ""), c.replace(" ", "") # Columns: others for col in struct_tools.complement(cols, ["val", "prec"]): 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 = struct_tools.complement(aggregate, excluded) return aggregate