8. path

This module is used to maniuplate and calculate geometry quantities on 3D paths.

Note: This module uses pyopencl (via simple_cl) to compute any quantities whose complexity is \(N^2\). If your GPU has good float support, you may see a dramatic improvement in speed by adding the following at the beginning of your code:

from ilpm import path
path.set_opencl_params(device='gpu')

8.1. Overview

Path(path[, closed, info, derivative_points]) Object which describes a 3D path, optionally with attached attributes.
Tangle(paths[, ignore_empty_paths, info]) Object which describes multiple 3D paths.
load_path(fn[, ignore_empty_paths]) Load a path or tangle from a file.
load_tangle(fn[, ignore_empty_paths]) Similiar load_path(), but always returns a tangle object.
as_path(x) Convert object to a path, if possible.
set_opencl_params([use_doubles, device, context]) Set the parameters of the OpenCL Session used for computations.
torus_knot(p, q[, r, a, NP]) Generate a (generalized) torus knot.

8.2. Classes and Functions

ilpm.path.set_opencl_params(use_doubles=None, device=None, context=None)[source]

Set the parameters of the OpenCL Session used for computations.

See simple_cl documentation for details.

Note: this function must be called before any functions that use it, or an error will be raised.

Parameters:

use_doubles : bool, optional (default: False)

device : string or list, optional (default: ‘cpu’)

context : pyopencl Context or CLSession object, optional

If specified, causes CLSession to share a context.

ilpm.path.set_default_core_model(model)[source]

Set the default core model used for energy and velocity calculations.

All models adapted from Donnelly, R. J.,
Vortex rings in classical and quantum systems, Fluid Dynamics Research, 41(5), 051401 1-31 (2009).
Valid options:
  • "solid": (default) solid rotating core, constant volume
  • "hollow_cv": hollow core, constant volume
  • "hollow_cp": hollow core, constant pressure
  • "hollow_st": hollow core with surface tension
  • "nlse": Nonlinear schrodinger equation, i.e. Gross-Pitaevskii equation
  • "viscous": Viscous relaxed core (i.e. Gaussian)

The default is “solid”.

class ilpm.path.Path(path, closed=True, info={}, derivative_points=5, **kwargs)[source]

Bases: object

Object which describes a 3D path, optionally with attached attributes.

Automatically handles the calculation of geometric parameters like tangents, etc. as special attributes:

  • tangent: the tangent vector, calculated as the normalized path derivative
  • seg_length: the segment length
  • L: the total length, calculated as sum(seg_length)
  • s: path length coordinate, defined from the first point in the path
  • fs_normal, fs_binormal: the Frenet-Serret (bi-)normal
  • torsion, curvature: the torsion and curvature, from the Frenet-Serret basis
  • s_polygon, L_polygon: like s and L, but for a polygonal path

These parameters will appear as attached as attributes once they are created. If the path is modified in place these derived attributes should be deleted with clear_derived(). (This happens automatically unless the path array is modified in place.)

Also allows the attachment of arbitrary parameters to the path as arrays with shape (N, -any-), where N is the number of points in the path. These can either be defined at creation, or attached as attributes later.

Methods

apply_basis(B) Apply an orthonormal basis transformation.
biot_savart_on_path(a[, gamma, core_model, ...]) Compute the biot-savart flow field on the path.
center() Return the center of the path.
clear_derived() Clear all derived attributes.
color_by_proximity(p[, c, w, rgb_only, ...]) Color a path by proximity to another path, tangle, or set of colored points.
colorize(c[, cmap, clim]) Color a Path using matplotlib specifications.
copy() Return a copy of the path in which all attached arrays are copied.
cubic_bezier_resample(s[, attached_interp]) Resample the path using a cubic bezier.
decimate(ratio) Decimate the path points, preserving end points if not closed.
eliminate_close_points(min_dist) Eliminate points which are too close.
gen_normal(normal) Fix a normal vector to be unit length and perpendicular to the tangent.
keep(indices) Keep only the specified point indices in the path.
mean(a) Compute the mean of some variable over the path, accounting for non-uniform segment length.
mesh_tube([width, outline]) Create a Mesh object by tracing the Path, create a tube.
midpoint() Return the segment midpoints.
moment() Calculates the path magnetic moment: \(\vec{m} = \frac{1}{2} \oint \vec{r} \times d\vec{r}\).
orient(X[, Y]) Orient tangle so specified vector is in the x-direction.
parallel_transport_framing([N0, twist_to_close]) Generate a parallel transport framing, starting from the first point.
partial_s(a) Take a partial derivative with respect to path length of any quantity on the tangle.
reduce_by_curvature([points_per_circle]) Reduce a path by eliminating points in nearly-straight sections.
resample_with_spacing(dl[, attached_interp]) Resample path evenly, spacing points by specified distance.
rms_radius() Return the root mean squared radius of the path.
rot(rv) Rotate the path in place.
save(fn) Save the path as a file.
scale(scale) Scale the path in place.
seg_length_per_point() Compute the segment length associated with each point.
to_dict([omit]) Convert all parameters to a dictionary, usually for saving.
translate(offset) Translate the path in place.
twist([normal, per_point, normalize]) Measure the twist of a normal vector about a path.
clear_derived()[source]

Clear all derived attributes.

Should be used if the path is modified in place by external commands.

midpoint()[source]

Return the segment midpoints.

If closed==False, will return one less than the number of points.

copy()[source]

Return a copy of the path in which all attached arrays are copied.

rot(rv)[source]

Rotate the path in place.

Parameters:

rv : vector ([3] array)

Rotation vector, will rotate counter-clockwise around axis by an amount given be the length of the vector (in radians).

scale(scale)[source]

Scale the path in place.

translate(offset)[source]

Translate the path in place.

partial_s(a)[source]

Take a partial derivative with respect to path length of any quantity on the tangle.

Parameters:

a : string or [N, M] array

If a is a string, an attribute of the path is used. Otherwise the first dimension of a should match the number of points.

Returns:

partial_s : [N, M] array

The partial derivative with respect to path length. A 3 or 5 point stencil is used (depending on self.deriviative_points). Fully accounts for non-equal segment lengths and end points for open paths.

mean(a)[source]

Compute the mean of some variable over the path, accounting for non-uniform segment length.

Parameters:

a : string or [N, M] array

If a is a string, an attribute of the path is used. Otherwise the first dimension of a should match the number of points.

Returns:

mean : [M] array

seg_length_per_point()[source]

Compute the segment length associated with each point.

Returns:

seg_L_per_point : [N] array

For closed paths, half of the length of each adjacent segment is assigned to each point. For open paths, the end points only get a single segment piece.

to_dict(omit=('derivative_points', 'refine_s'))[source]

Convert all parameters to a dictionary, usually for saving.

Parameters:

omit : list or tuple

Parameters not to include in dictionary.

Returns:

d : dict

save(fn)[source]

Save the path as a file. The filename is not enforced, but .path is recommended.

The resulting file is a JSON version of self.to_dict.

keep(indices)[source]

Keep only the specified point indices in the path.

Parameters:indices : int array
decimate(ratio)[source]

Decimate the path points, preserving end points if not closed.

Also decimates all the attached arrays.

Parameters:ratio : int
eliminate_close_points(min_dist)[source]

Eliminate points which are too close.

Parameters:

min_dist : float

Distance between points below which to clip.

reduce_by_curvature(points_per_circle=100)[source]

Reduce a path by eliminating points in nearly-straight sections.

Works by computing the angle of each corner, and only keeps points when the total accumulated angle exceeds a threshold given by the specified number of points per circle.

Parameters:points_per_circle : int, optional (default: 100)
moment()[source]

Calculates the path magnetic moment: \(\vec{m} = \frac{1}{2} \oint \vec{r} \times d\vec{r}\).

Uses a discrete approximation: \(\vec{m} \approx \frac{1}{2} \sum \left(\vec{r}_{i+1} - \vec{r}_i\right) \times \frac{1}{2}\left(\vec{r}_{i+1} + \vec{r}_i\right)\)

orient(X, Y=None)[source]

Orient tangle so specified vector is in the x-direction.

Parameters:

X : vector

Y : vector, optional

These vectors will appear as the new x and y axis, respectively. If only one is specified, the y axis is chosen semi-arbitrarily. Note: if x and y are not orthogonal, y will be adjusted so that a right-handed orthonormal basis is formed (in other words the result is always a pure rotation, with no mirroring, etc.).

apply_basis(B)[source]

Apply an orthonormal basis transformation.

Parameters:

B : basis array (3, 3)

Assumed to be orthonormal, but not checked.

center()[source]

Return the center of the path.

Computed as: \(\left<\vec{r}\right> = \frac{\sum \frac{L_i}{2}\left(\vec{r}_{i+1} + \vec{r}_i\right)}{\sum L_i}\)

rms_radius()[source]

Return the root mean squared radius of the path.

Computed as: \(\bar{r} = \sqrt{\frac{\sum L_i \left|\frac{\vec{r}_{i+1} + \vec{r}_i}{2} - \left<\vec{r}\right>\right|^2}{\sum L_i}}\)

gen_normal(normal)[source]

Fix a normal vector to be unit length and perpendicular to the tangent.

twist(normal=None, per_point=False, normalize=True)[source]

Measure the twist of a normal vector about a path.

Computed as \(Tw = \frac{1}{2\pi}\oint d\vec{r} \cdot \left(\vec{n} \times \partial_s\vec{n}\right)\)

If the normal is the Frenet-Serret normal, the twist becomes the (integrated) torsion; the sign convention is such that right handed helices have positive twist.

Parameters:

normal : vector array, optional (default: self.normal)

per_point : bool, optional (default: False)

If True, returns the twist rate per point instead of the total.

normalize : bool, optional (default: True)

If True, the normal is passed through path.gen_normal() first.

Returns:

twist : float or array

The total or per point twist density.

biot_savart_on_path(a, gamma=1.0, core_model=None, alpha=None)[source]

Compute the biot-savart flow field on the path.

Uses an exact expression for a polygonal path; neighboring segments are not included in the expression, and are replaced with a computation for a circular arc going through three points.

Parameters:

a : float

The “core size” used in the cutoff calculation.

gamma : float, optional (default: 1)

The core circulation; multiplies the overall flow.

core_model : str, optional

The core model to use; affects the way the short range cutoff is handlded. The default is specified by a global variable; see set_default_core_model() for more information.

alpha : float, optional

The cutoff correction parameter. Usually determined from the core_model, but if specified directly overrides this setting.

colorize(c, cmap='jet', clim=None)[source]

Color a Path using matplotlib specifications.

Parameters:

c : string or array

  • If type is string, it is interpreted like a normal matplotlib color (e.g., "r" for red, or "0.5" for 50% gray, or "#FF8888" for pink).
  • If type is array, it should have the same length as the number of points, and it will be converted to a colormap.

cmap : string or matplotlib colormap (default: ‘jet’)

The color map to use. Only relevant if c is an array.

clim : tuple (default: None)

The color limits. If None, the max/min of c are used.

color_by_proximity(p, c=None, w=None, rgb_only=True, power=-6, period=None)[source]

Color a path by proximity to another path, tangle, or set of colored points.

Parameters:

p : Path, Tangle or [N, 3] array

c : [N, 3 or 4] array

The color of each point; required if p is an array, and ignored if it is a Path or Tangle (in this case the color attribute is used).

w : [N] array, optional

Weight array.

rgb_only : bool, optional (default: True)

If True, the alpha component is dropped

power : int, optional (default: -6)

The power of the radial weighting function. Recommended values are <= -4.

period : None, float or (3,) array_like (optional)

If not None, the period to use for wrapping the proximity calculation (data assumed to be go from 0-period on each axis). If one number is specified, the period is assumed to be the same on all three axes.

cubic_bezier_resample(s, attached_interp='linear')[source]

Resample the path using a cubic bezier.

The resulting path will go through all the original points with a tangent given by the tangent attribute.

Any properties on the path will be resample as well.

Parameters:

s : array

The target s-coordinates (pathlength) of the new points.

attached_interp : str or int, optional (default: "linear")

The interpolation order for attached attributes. Passed directly to scipy.interpolate.interp1d. (Options: "linear", "nearest", "zero", "slinear", "quadratic", "cubic", or an integer specifying the spline order)

Returns:

path : Path

The interpolated path, with all attached attributes resampled.

resample_with_spacing(dl, attached_interp='linear')[source]

Resample path evenly, spacing points by specified distance.

Parameters:

dl : float

New point spacing target. Actual spacing will slightly different, as the points will be equally spaced.

attached_interp : int or string (default: "linear")

Type of interpolation for attached attributes. See cubic_bezier_resample() for details.

Returns:

path : Path

The interpolated path, with all attached attributes resampled.

parallel_transport_framing(N0=(1, 0, 0), twist_to_close=False)[source]

Generate a parallel transport framing, starting from the first point.

Parameters:

N0 : [3] array, optional (default: (1, 0, 0))

The normal vector to begin the framing.

twist_to_close : bool, optional (default: False)

If True, the framing is uniformly twisted to close on itself. Ignored if the path is not closed.

Returns:

normal : [N, 3] array

Unit normal vectors

mesh_tube(width=None, outline=10)[source]

Create a Mesh object by tracing the Path, create a tube.

If the Path has a color attribute, the mesh will be colored accordingly.

Uses ilpm.mesh.extrude_shape().

Parameters:

width : [N] array, float or None, optional (default: 1)

The thickness of the tube/ribbon. If not specified, will be given by the thickness attribute, or defaults to 1.

outline : int, optional (default: 10)

The number of points for the circumference of the circle/ribbon tracing the outline.

ilpm.path.as_path(x)[source]

Convert object to a path, if possible.

class ilpm.path.Tangle(paths, ignore_empty_paths=True, info={})[source]

Bases: object

Object which describes multiple 3D paths.

Most methods are the same as for Path.

Any attribute which is valid for all of the child paths is also a valid attribute of the Tangle. (It will return a list of values from the child Paths.)

Parameters:

paths : list of Paths, or objects convertable to Paths

ignore_empty_paths : bool, optional (default: True)

If True, empty paths in a Tangle are ignored.

info : dict

Arbitrary info, saved in file

Methods

apply_basis(B) Apply basis to the tangle.
center() Return center of tangle.
closest_opposed([cutoff, per_point]) Find the closet point in the Tangle where paths are facing in opposite directions.
color_by_proximity(p[, c, w, rgb_only, ...]) Color a path by proximity to another path, tangle, or set of colored points.
colorize(c[, cmap, clim]) Color a Tangle.
compacted_segment_attribute(attr) Return a compcated form of a attached attribute of the paths.
compacted_segments() Create a compacted path array and a number of points array.
copy() Return a copt of the Tangle
crossing_matrix() Compute the crossing number matrix for all paths in the Tangle.
decimate(ratio) Decimate all the paths in the tangle.
drop(attr) Drop the specified attribute from the child paths.
drop_shorter_than([N, L_polygon, L]) Remove short paths from the tangle, specified either in number of points and/or length.
eliminate_close_points(min_dist) Eliminate points which are too close.
inductance_matrix([a, core_model, period]) Compute the path inductance of a Tangle.
mean(a) Compute the mean of some variable over the tangle.
mesh_tube([width, outline]) Create a Mesh object by tracing the Tangle, create a tube.
moment() Return the first moment of the path.
orient(vec) Orient tangle so specified vector is in the x-direction.
reduce_by_curvature([points_per_circle]) Reduce a tangle by eliminating points in nearly-straight sections.
reduce_topology() Remove as many points from the tangle as possible without changing the crossings.
resample_with_spacing(dl[, attached_interp]) Resample path evenly, spacing points by specified distance.
rms_radius() Return the root mean squared radius of the tangle.
rot(rv) Rotate the tangle.
save(fn) Save the path as a file.
scale(scale) Scale the tangle.
to_dict([path_omit]) Returns a copy of the Tangle as a dict.
total_length() Compute the total length of all the paths in the Tangle.
total_points() Return the total points in all paths
translate(offset) Translate the tangle.
twist() Calculate the normal twist for each element in a tangle.
twist_rate() Calculate the normal twist rate for each element in a tangle.
copy()[source]

Return a copt of the Tangle

to_dict(path_omit=('derivative_points', 'refine_s'))[source]

Returns a copy of the Tangle as a dict.

Parameters:

path_omit : tuple of strings

Keywords to omit from the path sub-dictionaries.

save(fn)[source]

Save the path as a file. The filename is not enforced, but .tangle is recommended.

The resulting file is a JSON version of self.to_dict.

compacted_segments()[source]

Create a compacted path array and a number of points array.

Used primarily for OpenCL calculations.

Returns:

points : [total_segments + num_paths, 3] array

A vstack of all the paths in the tangle. If the path is closed, the beginning point is added the end of the appropriate chunk and num_points = len(path) + 1

num_segs : int array, shape [num_paths]

The number of segments (points) in each path.

path_i0, path_i1 : int array, shape [num_paths]

The beginning and end index of each path. There will be a gap of 1 between i1 for path j and i0 of path j+1 because i1 references the start point of the last segment. (Exception to the rule: if a path is open and include_ends==True, then the last point will be included.)

compacted_segment_attribute(attr)[source]

Return a compcated form of a attached attribute of the paths.

Designed to work in coordinate with compacted_segments().

Parameters:

attr : string

A valid attribute on all the paths (e.g. "tangent").

Returns:

a : array

A concatenated array of the attributes whose indices match those returned by the paths from compacted_segments().

rot(rv)[source]

Rotate the tangle. (see Path.rot())

apply_basis(B)[source]

Apply basis to the tangle. (see Path.apply_basis())

translate(offset)[source]

Translate the tangle. (see Path.translate())

scale(scale)[source]

Scale the tangle. (see Path.scale())

decimate(ratio)[source]

Decimate all the paths in the tangle. (see Path.decimate())

total_points()[source]

Return the total points in all paths

moment()[source]

Return the first moment of the path. (see Path.moment())

orient(vec)[source]

Orient tangle so specified vector is in the x-direction. (see Path.orient())

center()[source]

Return center of tangle. (see Path.center())

rms_radius()[source]

Return the root mean squared radius of the tangle. (see Path.rms_radius())

eliminate_close_points(min_dist)[source]

Eliminate points which are too close. (see Path.eliminate_close_points())

reduce_by_curvature(points_per_circle=100)[source]

Reduce a tangle by eliminating points in nearly-straight sections. (see :meth:`Path.reduce_by_curvature’)

twist()[source]

Calculate the normal twist for each element in a tangle. (see Path.twist())

If you need to specify a normal vector other than the predefined normal, call Path.twist() on the elements of the Tangle.

twist_rate()[source]

Calculate the normal twist rate for each element in a tangle. (see Path.twist())

If you need to specify a normal vector other than the predefined normal, call Path.twist() on the elements of the Tangle.

total_length()[source]

Compute the total length of all the paths in the Tangle.

crossing_matrix()[source]

Compute the crossing number matrix for all paths in the Tangle.

Returns:

signed_crossings : [N, N] array

The total signed crossings for each pair of paths. Self-crossing term is the Writhe, the off-diagonal terms are linking numbers (integer-ness is enforced).

unsigned crossings : [N, N] array

The average number of unsigned crossings for each pair of paths, averaged over all orientations.

inductance_matrix(a=1.0, core_model=None, period=None)[source]

Compute the path inductance of a Tangle.

The path inductance is defined as:
\(\mathcal{E}_{ij} \approx \frac{1}{4 \pi} \oint \oint_{\left|\vec r_i - \vec r_j\right| > \frac{a}{2}} \frac{d\vec r_i \cdot d\vec r_j}{\left|\vec r - \vec r_j\right|}+ \delta_{ij} \frac{2-\alpha}{2\pi} L_i\)
Parameters:

a : float, optional [default: 1.0]

The core size.

core_model : float or string, optional

The core model used to determine \(\alpha\); see set_default_core_model() for options. If a float value is specified, this will be used to directly set alpha(). If not specified, it is determined by the default set by set_default_core_model() [defaulut: "solid"].

period : [3] array or float, optional

If specified, a 3x3x3 periodic copy of the original tangle is used to calculate inductances.

Returns:

inductance : (N, N) matrix

closest_opposed(cutoff=0, per_point=False)[source]

Find the closet point in the Tangle where paths are facing in opposite directions.

Tests the tangent vectors of all pairs of points in the Tangle, finding the closest pair for which :math:T_i \cdot T_j \leq cutoff.

If no pairs meet this criterium, NaN is returned instead.

Parameters:

cutoff : float, optional (default: 0)

per_point : bool, optional (default: False)

If True, returns a list of arrays corresponding to the closest distance from each individual point.

Returns:

r : float or array

The cloesest radius meeting the condition. (Optionally for each individual point)

colorize(c, cmap='jet', clim=None)[source]

Color a Tangle. (see Path.colorize())

The color may be specified either as a single item, or a list/tuple of values. (e.g. a list of arrays that correspond to color values)

drop(attr)[source]

Drop the specified attribute from the child paths.

mean(a)[source]

Compute the mean of some variable over the tangle. See Path.mean()

color_by_proximity(p, c=None, w=None, rgb_only=True, power=-6, period=None)[source]

Color a path by proximity to another path, tangle, or set of colored points. See Path.color_by_proximity()

resample_with_spacing(dl, attached_interp='linear')[source]

Resample path evenly, spacing points by specified distance. See :meth:`Path.resample_with_spacing’

drop_shorter_than(N=None, L_polygon=None, L=None)[source]

Remove short paths from the tangle, specified either in number of points and/or length.

Parameters:

N : int, optional

Clip by this number of points

L_polygon :

Clip by this length (from the L_polygon parameter of the path). This avoids complete computation of the interpolations parameters, which is much faster.

L : float, optional

Clip by this length (from the L parameter of the path)

mesh_tube(width=None, outline=10)[source]

Create a Mesh object by tracing the Tangle, create a tube.

See Path.mesh_tube() for details.

reduce_topology()[source]

Remove as many points from the tangle as possible without changing the crossings.

The remaining tangle will have the same topology, but with a small number of points. Topologically trivial loops will be removed; if the entire tangle is topologically trivial it should create an empty tangle.

The algorithm works by choosing a random point and testing if it can be removed without changing any crossings. (It tests for this by looking for intersections between segments and the triangle formed by the three-point neighborhood of the point.)

Note: It is possible that the reduction may get stuck if the tangled is very tangled. Typically, however, it is able to reduce the tangle succesfully.

Note 2: This algorithm can be slow; it is highly recommended to run reduce_by_curvature() on the tangle first.

ilpm.path.load_path(fn, ignore_empty_paths=True)[source]

Load a path or tangle from a file.

Supports either the new style path/tangle format as well as the older ”.json” tangle format.

Parameters:

fn : string

A filename corresponding to a valid path.

ignore_empty_paths : bool, optional (default: True)

If True, empty paths in a Tangle are ignored.

Returns:

path : Path or Tangle

ilpm.path.load_tangle(fn, ignore_empty_paths=True)[source]

Similiar load_path(), but always returns a tangle object.

Parameters:

fn : string

A filename corresponding to a valid path or tangle.

ignore_empty_paths : bool, optional (default: True)

If True, empty paths in a Tangle are ignored.

Returns:

tangle : Tangle

If the filename corresponds to a Path, it is converted to a Tangle with a single path.

ilpm.path.torus_knot(p, q, r=1, a=0.3333333333333333, NP=128)[source]

Generate a (generalized) torus knot.

Constructed so that p is the number of filaments in a bundle cross-section and p/q is the twist number per revolution.

Parameters:

p, q: integer

Winding numbers

r, a: float, optional

Major and minor radius (default: r=1, a=1/3)

NP: int, optional

The number of points per revolution (default: 128)

Returns:

tangle : Tangle

A tangle of the torus knot.