Skip to content

Commit

Permalink
Cleaned up definition of emulsions, allowing to define empty emulsions
Browse files Browse the repository at this point in the history
* Removed `grid` attribute from `Emulsion` and similar classes
* Instead, grid instances can now be specified when distances are
important, which separates concerns better
* Added explicit `dtype` attribute to emulsions to clearly specify type
of droplets in empty emulsions. This can often be ignored, though.
  • Loading branch information
david-zwicker committed Aug 29, 2023
1 parent be8a8f8 commit 2625997
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 172 deletions.
13 changes: 9 additions & 4 deletions droplets/droplet_tracks.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ def time_overlaps(self, other: "DropletTrack") -> bool:
return s0 <= o1 and o0 <= s1

@classmethod
def _from_hdf_dataset(cls, dataset) -> "DropletTrack":
def _from_hdf_dataset(cls, dataset) -> DropletTrack:
"""construct a droplet track by reading data from an hdf5 dataset
Args:
Expand Down Expand Up @@ -455,7 +455,9 @@ def __getitem__(self, key: Union[int, slice]): # type: ignore
def from_emulsion_time_course(
cls,
time_course: EmulsionTimeCourse,
*,
method: str = "overlap",
grid: Optional[GridBase] = None,
progress: bool = False,
**kwargs,
) -> DropletTrackList:
Expand All @@ -469,6 +471,9 @@ def from_emulsion_time_course(
"overlap" (adding droplets that overlap with those in previous frames)
and "distance" (matching droplets to minimize center-to-center
distances).
grid (:class:`~pde.grids.base.GridBase`):
The grid on which the droplets are defined, which is necessary if
periodic boundary conditions should be respected for measuring distances
progress (bool):
Whether to show the progress of the process.
**kwargs:
Expand Down Expand Up @@ -496,7 +501,7 @@ def match_tracks(
# determine which old tracks could be extended
overlaps: List[DropletTrack] = []
for track in tracks_alive:
if track.last.overlaps(droplet, time_course.grid):
if track.last.overlaps(droplet, grid=grid):
overlaps.append(track)

if len(overlaps) == 1:
Expand All @@ -522,10 +527,10 @@ def match_tracks(

# calculate the distance between droplets
if tracks_alive:
if time_course.grid is None:
if grid is None:
metric: Union[str, Callable] = "euclidean"
else:
metric = time_course.grid.distance_real
metric = grid.distance_real
points_prev = [track.last.position for track in tracks_alive]
points_now = [droplet.position for droplet in emulsion]
dists = distance.cdist(points_prev, points_now, metric=metric)
Expand Down
14 changes: 9 additions & 5 deletions droplets/droplets.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
"""
Classes representing (perturbed) droplets in various dimensions
The classes differ in what features of a droplet they track. In the simplest case, only
the position and radius of a spherical droplet are stored. Other classes additionally
keep track of the interfacial width or shape perturbations (of various degrees).
.. autosummary::
:nosignatures:
Expand Down Expand Up @@ -240,7 +243,7 @@ def data_bounds(self) -> Tuple[np.ndarray, np.ndarray]:
return np.full(num, -np.inf), np.full(num, np.inf)


class SphericalDroplet(DropletBase): # lgtm [py/missing-equals]
class SphericalDroplet(DropletBase):
"""Represents a single, spherical droplet"""

__slots__ = ["data"]
Expand Down Expand Up @@ -1181,13 +1184,14 @@ def _get_mpl_patch(self, dim=None, *, color=None, **kwargs):
raise NotImplementedError("Plotting PerturbedDroplet3D is not implemented")


def droplet_from_data(droplet_class: str, data) -> DropletBase:
def droplet_from_data(droplet_class: str, data: np.ndarray) -> DropletBase:
"""create a droplet instance of the given class using some data
Args:
droplet_class (str): The name of the class that is used to create the
droplet instance
data (numpy.ndarray): A numpy array that defines the droplet properties
droplet_class (str):
The name of the class that is used to create the droplet instance
data (:class:`~numpy.ndarray`):
A numpy array that defines the droplet properties
"""
cls = DropletBase._subclasses[droplet_class]
return cls(**{key: data[key] for key in data.dtype.names}) # type: ignore
Expand Down
Loading

0 comments on commit 2625997

Please sign in to comment.