fish2eod.geometry package

Submodules

fish2eod.geometry.fish module

Functions and classes for defining special fish geometries.

Fish is the generic fish class Apteronotus is a fish of species Apteronotus with appropriate body and parameters Eigenmannia is a fish of species Eigenmannia with appropriate body and parameters

class fish2eod.geometry.fish.Fish(skeleton_x, skeleton_y, species, skin_thickness=0.01)

Bases: object

Body of a fish defined by a skeleton.

Parameters:
  • skeleton_x (Sequence[float]) – x coordinates of the skeleton

  • skeleton_y (Sequence[float]) – y coordinates of the skeleton

  • species (str) – Either a provided name or FishSettings

  • body – Optional dataframe specifying the body geometry

  • eod – Optional dataframe specifying the EOD

draw(draw_sides=True)

Draw the fish.

Parameters:

draw_sides – Color the sides differently (left red, right green) for debug purposes

Return type:

None

Returns:

None

eod(phase)
eod_boundary_condition(eod, domain_label)
get_body_coordinates(n=100, m=500)

Get the body coordinates uniformly interpolated interpolated.

Parameters:
  • n (int) – Number of points to interpolate

  • m (int) – Resolution for computing curve length

Returns:

Body x and y coordinates uniformly interpolated

offset_skeleton(d, threshold, bounds=None, lcar=0.5)

Create a body part by offsetting the skeleton.

Parameters:
  • d (Union[float, Sequence[float]]) – Distance from curve to offset

  • bounds (Optional[Sequence[float]]) – Optional bounds to offset from. This is used for the organ which is not the whole skeleton

  • threshold (float) – Width to simplify

  • lcar – Characteristic length

Return type:

Polygon

Returns:

The offset polygon

property settings
setup_sides()

Tag and create a contour for the left and right sides of each body part.

skin_conductance(x, y)

Compute the skin conductance at a point (x,y) on the skin.

Parameters:
  • x (float) – x coordinate on skin

  • y (float) – y coordinate on skin

Return type:

float

Returns:

Returns the skin conductance

class fish2eod.geometry.fish.FishContainer

Bases: object

init_fish(fish_x_list, fish_y_list, species)

Initialize all fish.

Multiple fish are specified with multidimensional lists.

The x list [0,20] would specify a single fish spanning [0,20]cm. The x list [[0,20]] would specify a single fish spanning [0,20]cm. The x list [[0,20], [40, 60]] would specify two fish one spanning [0,20]cm and the other [40,60]cm

Any number of fish can be specified in this manner as long as there are an equal number of fish specified in the x and y coordinates.

Parameters:
  • fish_x_list (Union[Sequence[Sequence[float]], Sequence[float]]) – List of fish x-coordinates

  • fish_y_list (Union[Sequence[Sequence[float]], Sequence[float]]) – List of fish y-coordinates

  • species (str) – Name of the species

  • body – Optional custom body geometry

  • eod – Optional custom eod waveform

Return type:

None

Returns:

None

class fish2eod.geometry.fish.SideStruct(left: ndarray, right: ndarray)

Bases: NamedTuple

Convenience struct to hold a left and right side array.

left: ndarray

Alias for field number 0

right: ndarray

Alias for field number 1

fish2eod.geometry.fish.align_contour_head_tail(side, head)

Reorder a side if necessary so that it runs from head -> tail.

Parameters:
  • side (ndarray) – Coordinates of the side

  • head (ndarray) – Coordinate of the head

Return type:

ndarray

Returns:

Coordinates of the side in correct order

fish2eod.geometry.fish.assign_left_right(parts, skeleton)

Map the 2 sides onto a “left” and “right” relative to the fish axis.

Parameters:
  • parts (List[LineString]) – Tuple of sides to assign

  • skeleton (LineString) – The body skeleton

Return type:

Tuple[ndarray, ndarray]

Returns:

Tuple of coordinates for right and left (in that order)

fish2eod.geometry.fish.clean_linestring(body_half, contour)

Fix the cut body contour.

When the polygon gets cut - the outline of the cutter is embedded into it. This extracts the pure skin contour

Parameters:
  • body_half (Polygon) – The half body to get the skin from

  • contour (LineString) – Contour of the whole fish

Return type:

LineString

Returns:

Appropriate sided contour

fish2eod.geometry.fish.determine_right(side, head, tail, skeleton)

Determine if the given side is the right side.

Parameters:
  • side (ndarray) – One of the sides

  • head (ndarray) – Head coordinates

  • tail (ndarray) – Tail coordinates

  • skeleton (ndarray) – Skeleton Coordinates

Returns:

If the side is the right side of not

fish2eod.geometry.fish.fish_rotation_matrix(head, tail)

Compute the 2D rotation matrix for the fish with rotation relative to y-axis.

Parameters:
  • head (ndarray) – Coordinates of the head

  • tail (ndarray) – Coordinates of the tail

Return type:

ndarray

Returns:

Rotation matrix

fish2eod.geometry.fish.make_eod_fcn(phase, data)
fish2eod.geometry.fish.split_body(skeleton, polygon)

Split a polygon with a skeleton.

Parameters:
  • skeleton (LineString) – Body skeleton

  • polygon (Polygon) – The body part to split

Return type:

List[LineString]

Returns:

The two halves of the body part

fish2eod.geometry.operations module

Geometry operations for slicing, offsetting, and interpolating lines.

fish2eod.geometry.operations.cut_line_between_fractions(line, start_fraction, end_fraction)

Cut a line at 2 fractions and return the region between them.

Parameters:
  • line (<module 'shapely.geometry.linestring' from '/home/docs/checkouts/readthedocs.org/user_builds/fish2eod/conda/latest/lib/python3.10/site-packages/shapely/geometry/linestring.py'>) – Linestring to cut

  • start_fraction (float) – Fraction 1 (0 < f1 < f2)

  • end_fraction (float) – Fraction 2 (f1 < f2 < 1)

Return type:

LineString

Returns:

Linestring that was cut out

fish2eod.geometry.operations.extend_line(x, y, fraction=0.1)

Extend (linearly extrapolate) an arbitrary curve at both ends.

x and y are now of the form

front_extrapolate, x_original, end_extrapolate

Parameters:
  • x (Sequence[float]) – x coordinates of the curve

  • y (Sequence[float]) – y coordinates of the curve

  • fraction (float) – Fraction of the line distance to extrapolate

Return type:

Tuple[ndarray, ndarray]

Returns:

Extended line

fish2eod.geometry.operations.filter_line_length(original_line, start_fraction, end_fraction, line_slice, tol=1e-10)

Determine if a line slice is “very close” to the target line fractions.

Parameters:
  • original_line (LineString) – Original line being cut

  • start_fraction (float) – Fraction 1 (0 < f1 < f2)

  • end_fraction (float) – Fraction 2 (f1 < f2 < 1)

  • line_slice (LineString) – New line to check

  • tol (float) – Optional parameter to define how close is “close”

Return type:

bool

Returns:

If the line_slice is the desired sliced line

fish2eod.geometry.operations.measure_and_interpolate(x, y, m)

Interpolate coordinates and compute length of each section.

Parameters:
  • x (Sequence[float]) – X coordinates

  • y (Sequence[float]) – Y coordinates

  • m (int) – Minimum number of points to interpolate

Return type:

Tuple[ndarray, ndarray, ndarray]

Returns:

length of each segment and interpolated x, y

fish2eod.geometry.operations.parallel_curves(x, y, d=1.0)

TODO def this.

Return type:

Dict[str, ndarray]

fish2eod.geometry.operations.uniform_spline_interpolation(x, y, n, m=10000)

Interpolate coordinates with n evenly spaced points along a spline.

Interpolation will ensure the first and last point on the line are included in the spline

If there are turns in the spline (like a sine-wave) the number of points (n) needs to be high enough that spatial frequency of sampled points >> spatial frequency of spline or you will get cuts at the curves - interpolation is a low pass filter

Parameters:
  • x (Sequence[float]) – x coordinates

  • y (Sequence[float]) – y coordinates

  • n (int) – Number of points to interpolate

  • m (int) – Resolution for computing curve length (default of 10000 should be sufficient)

Return type:

Tuple[ndarray, ndarray]

Returns:

Interpolated x, y points for sources

fish2eod.geometry.primitives module

Geometry geometry_primitives for constructing a model.

Polygon is the base class which can be used to define abstract shapes Circle defines circles Rectangle defines rectangles

class fish2eod.geometry.primitives.Circle(center, radius, lcar=None)

Bases: Polygon

Circle geometry object.

Parameters:
  • center (Sequence[float]) – Sequence of 2 floats specifying circle center

  • radius (float) – Circle radius

  • lcar (Optional[float]) – Optional overwrite for characteristic length

inside(x, *_, buffer=5e-06)

Create the string expression for a particular circle for dolfin to check if a point is inside.

x[0] and x[1] are the dolfin expressions for coordinates x, y

checks if (x-x[0])^2 + (y-x[1])^2 <= (r+buffer)^2

Parameters:
  • x – Ignored

  • _ – Ignored

  • buffer (float) – Radius buffer to include edge points - should be small, enough to catch rounding errors

Return type:

str

Returns:

String of code to compile

class fish2eod.geometry.primitives.Polygon(x, y, lcar=None)

Bases: SubDomain

Polygon object: all geometry objects are represented as polygons.

Provides a convenient interface between shapely and dolfin SubDomains

Parameters:
  • x (Sequence[float]) – Sequence of floats specifying x coordinates

  • y (Sequence[float]) – Sequence of floats specifying y coordinates

  • lcar (Optional[float]) – Optional overwrite for characteristic length

property center: Tuple[float, float]

Get coordinates of the centroid of the object.

Should be close but not exact for circles and rectangles

Return type:

Tuple[float, float]

Returns:

Tuple of center

draw(color='k')

Plot the geometry object.

Parameters:

color – Valid matplotlib color

Return type:

None

Returns:

None

expand(distance)

Blow up a geometry to widen it.

Buffer or expand slightly a geometry object.

Note: This is exact for circles but angles will round the more the shape is offset

Parameters:

distance (float) – The distance to offset: try to keep this small

Return type:

TypeVar(T, bound= Polygon)

Returns:

The offset object

inside(x, *_, buffer=1e-06)

Is the point x inside the shape.

Parameters:
  • x – Point to check

  • _ – Ignored

  • buffer – Edge buffer to include edge points - should be small, enough to catch rounding errors

Return type:

bool

intersects(other)

Determine if geometry intersect another.

Parameters:

other (Polygon) – Another geometry object to check

Return type:

bool

Returns:

Whether or not the two geometries intersect

property mesh_representation: Iterable[Tuple[float, float, int]]

Get the coordinates for the mesh.

gmsh requires surfaces to be open and implicitly closes them so x and y return [:-1]

Return type:

Iterable[Tuple[float, float, int]]

Returns:

Iterable of (x,y,z) pairs: z=0

rotate(angle, degrees=True, center=None)

Rotate an object.

Parameters:
  • angle (float) – Angle to rotate object in

  • degrees (bool) – Is number in degrees or radians. Defaults to degrees

  • center (Optional[Sequence[float]]) – Optional center to rotate about: sequence of 2 floats

Return type:

Polygon

property shapely_representation: Polygon

Get representation of the shape as a geometry object.

Return type:

Polygon

simplify(threshold)

Simplify a geometry.

Complex geometries can have too many micro verteces which make meshing complex. Strip out edges shorter than threshold

Parameters:

threshold (float) – Threshold length to simplify

Returns:

None

translate(dx=0, dy=0)

Translate an object.

Parameters:
  • dx (float) – Shift in x

  • dy (float) – Shift in y

Return type:

Polygon

class fish2eod.geometry.primitives.PreDomain(label: int, primitive: bool, objects: Union[Polygon, List[Polygon]])

Bases: NamedTuple

Convenience structure for containing information to be converted to a domain.

label: int

Alias for field number 0

objects: Union[Polygon, List[Polygon]]

Alias for field number 2

primitive: bool

Alias for field number 1

class fish2eod.geometry.primitives.Rectangle(corner, width, height=None, lcar=None)

Bases: Polygon

Rectangle geometry object.

Parameters:
  • corner (Sequence[float]) – Bottom left corner of the rectangle: sequence of 2 floats defining the bottom left

  • width (float) – Width of the rectangle (x-axis)

  • height (Optional[float]) – Optional height of the rectangle: if not specified the rectangle becomes a square

  • lcar (Optional[float]) – Optional overwrite for characteristic length

classmethod from_center(center, width, height=None, lcar=None)

Construct rectangle when the center of the rectangle is specified (alternate constructor).

Parameters:
  • center (Sequence[float]) – Center coordinate: sequence of 2 floats defining the rectangle center

  • width (float) – Width of the rectangle (x-axis)

  • height (Optional[float]) – Optional height of the rectangle: if not specified the rectangle becomes a square

  • lcar (Optional[float]) – Optional overwrite for characteristic length

Return type:

TypeVar(T, bound= Polygon)

Returns:

A rectangle defined from the center

inside(x, *_, buffer=1e-06)

Create the string expression for a particular rectangle for dolfin to check if a point is inside.

x[0] and x[1] are the dolfin expressions for coordinates x, y

Parameters:
  • x – Ignored

  • _ – Ignored

  • buffer – Edge buffer to include edge points - should be small, enough to catch rounding errors

Return type:

str

Returns:

String of code to compile