"""`dupin.data.base.DataMap` subclasses to transform distributional data.Mapping in dupin is the idea of taking one distribution and transforming itinto another. This is distinct from the mathematical view of functions as mapsand is more general than Python's map builtin. A distribution/array can bemapped to a new array of any size. A common example in molecular simulations isspatial averaging which reduces local fluctuations of features. This particularmap can be found in `dupin.data.spatial.NeighborAveraging`."""fromtypingimportUnionimportnumpyasnpimportnumpy.typingasnptfrom.importbase
[docs]classIdentity(base.DataMap):"""A identity mapping for use in a data pipeline. This class maps a distribution to itself. This is useful when using with `Tee`. Example:: generator.pipe( du.data.map.Tee([ du.data.map.Identity() du.data.map.CustomMap(lambda x: {"new_dist": x + 2}) ]) ) """
[docs]defcompute(self,data:npt.ArrayLike)->npt.ArrayLike:"""Return the same distribution. Parameters ---------- distribution : :math:`(N,)` numpy.ndarray of float The array representing a distribution to map. Return ------- signals : dict[str, float] Returns a dictionary with the key ``None`` and the passed in data as a value. """return{None:data}
[docs]classTee(base.DataMap):"""Combine mutliple maps into one acting on the same generator object. Example:: generator.pipe( du.data.map.Tee([ du.data.map.Identity(), du.data.map.CustomMap(lambda x: {"new_dist": x + 2}) ]) ) Parameters ---------- reducers: `list` [`dupin.data.base.DataReducer`] A sequence of data modifiers. """
[docs]def__init__(self,maps:list[base.DataMap],):iflen(maps)==0:msg="Cannot have empty maps sequence."raiseValueError(msg)self._maps=mapssuper().__init__()
[docs]defcompute(self,distribution:npt.ArrayLike)->dict[str,Union[float,np.ndarray]]:"""Run all composed map computes."""processed_data={}formap_inself._maps:processed_data.update(map_.compute(distribution))returnprocessed_data
[docs]defupdate(self,args,kwargs):"""Iterate over composed mappings and call update."""formap_inself._maps:args,kwargs=map_.update(args,kwargs)returnargs,kwargs
[docs]defattach_logger(self,logger):"""Add a logger to this step in the data pipeline. Parameters ---------- logger: dupin.data.logging.Logger A logger object to store data from the data pipeline for individual elements of the composed maps. """self._logger=loggerformap_inself._maps:try:map_.attach_logger(logger)# Do nothing if generator does not have attach_logger logger# function (e.g. custom map function).exceptAttributeError:pass
[docs]defremove_logger(self):"""Remove a logger from this step in the pipeline if it exists."""self._logger=Noneformap_inself._maps:try:map_.remove_logger()# Do nothing if generator does not have remove_logger logger# function (e.g. custom map function).exceptAttributeError:pass
[docs]defmap_(func):"""Decorate an additional map step to the current pipeline. Note: This is for the decorator syntax for creating pipelines. Note: This uses `CustomMap`. Parameters ---------- func : ``callable`` The function to use for mapping. """returnCustomMap(func)