The main snappy class, namely Manifold, is derived from more basic class below.

class snappy.Triangulation

A Triangulation object represents a compact 3-manifold with torus boundary components, given as an ideal triangulation of the manifold’s interior. A Dehn-filling can be specified for each boundary component, allowing the description of closed 3-manifolds and some orbifolds. For non-orientable 3-manifolds, the boundary components can also be Klein bottles. Two Triangulations are equal (‘==’) if they represent combinatorially isomorphic triangulations. A Triangulation does not have any geometric structure, and usually one works with the subclass Manifold which adds this. Here’s a quick example:

>>> M = Triangulation('9_42')
>>> M.num_tetrahedra()
>>> M.is_orientable()

A Triangulation can be specified in a number of ways, e.g.

  • Triangulation(‘9_42’) : The complement of the knot 9_42 in S^3.
  • Triangulation(‘m125(1,2)(4,5)’) : The SnapPea census manifold m125 where the first cusp has Dehn filling (1,2) and the second cusp has filling (4,5).
  • Triangulation() : Opens a link editor window where can you specify a link complement.

In general, the specification can be from among the below, with information on Dehn fillings added.

  • SnapPea cusped census manifolds: e.g. ‘m123’, ‘s123’, ‘v123’.

  • Link complements:
    • Rolfsen’s table: e.g. ‘4_1’, ‘04_1’, ‘5^2_6’, ‘6_4^7’, ‘L20935’, ‘l104001’.
    • Knots and links up to 14 crossings from tabulations by Hoste and Thistlethwaite: e.g. ‘K12a456’ or ‘L13n579’.
    • Hoste-Thistlethwaite Knotscape table: e.g. ‘11a17’ or ‘12n345’
    • Dowker-Thistlethwaite code: e.g. ‘DT:[(6,8,2,4)]’, ‘DT:dadbcda’
  • Once-punctured torus bundles: e.g. ‘b++LLR’, ‘b+-llR’, ‘bo-RRL’, ‘bn+LRLR’

  • Fibered manifold associated to a braid: ‘Braid:[1,2,-3,4]’

    Here, the braid is thought of as a mapping class of the punctured disc, and this manifold is the corresponding mapping torus. If you want the braid closure, do (1,0) filling of the last cusp.

  • From mapping class group data using Twister:

    ‘Bundle(S_{1,1}, [a0, B1])’ or ‘Splitting(S_{1,0}, [b1, A0], [a0,B1])’

    See the help for the ‘twister’ module for more.

  • A SnapPea triangulation or link projection file: ‘filename’

    The file will be loaded if found in the current directory or the path given by the shell variable SNAPPEA_MANIFOLD_DIRECTORY.

  • A Regina-style isomorphism signature, such as ‘dLQbcccdxwb’.

  • A string containing the contents of a SnapPea triangulation or link projection file.


Computes the multivariable Alexander polynomial of the manifold:

sage: M = Manifold('K12n123')
sage: M.alexander_polynomial()
2*a^6 - 14*a^5 + 34*a^4 - 45*a^3 + 34*a^2 - 14*a + 2

sage: N = Triangulation('v1539(5,1)')
sage: N.alexander_polynomial()
a^2*b + a*b^2 + a*b + a + b

Any provided keyword arguments are passed to fundamental_group and so affect the group presentation used in the computation.


Returns the peripheral curve in the given cusp, if any, which is homologically trivial (with rational coefficients) in the manifold:

sage: M = Manifold('m015')
sage: M.homological_longitude()
(2, -1)

If no cusp is specified, the default is the first unfilled cusp; if all cusps are filled, the default is the first cusp:

sage: M = Manifold('L5a1(3,4)(0,0)')
sage: M.homological_longitude()
(0, 1)

The components of the next link have nontrivial linking number so there is no such curve:

sage: W = Manifold('L7a2')
sage: W.homological_longitude(cusp=1) == None

If every curve in the given cusp is trivial in the rational homology of the manifold, an exception is raised:

sage: M = Manifold('4_1(1,0)')
sage: M.homological_longitude()
Traceback (most recent call last):
ValueError: Every curve on cusp is homologically trivial
normal_boundary_slopes(subset='all', algorithm='FXrays')

For a one-cusped manifold, returns all the nonempty boundary slopes of spun normal surfaces. Provided the triangulation supports a genuine hyperbolic structure, then by Thurston and Walsh any strict boundary slope (the boundary of an essential surface which is not a fiber or semifiber) must be listed here.

>>> M = Manifold('K3_1')
>>> M.normal_boundary_slopes()
[(16, -1), (20, -1), (37, -2)]

If the subset flag is set to 'kabaya', then it only returns boundary slopes associated to vertex surfaces with a quad in every tetrahedron; by Theorem 1.1. of [DG] these are all strict boundary slopes.

>>> N = Manifold('m113')
>>> N.normal_boundary_slopes()
[(1, 1), (1, 2), (2, -1), (2, 3), (8, 11)]
>>> N.normal_boundary_slopes('kabaya')
[(8, 11)]

If the subset flag is set to 'brasile' then it returns only the boundary slopes that are associated to vertex surfaces giving isolated rays in the space of embedded normal surfaces.

>>> N.normal_boundary_slopes('brasile')
[(1, 2), (8, 11)]

All the vertex spun-normal surfaces in the current triangulation.

>>> M = Manifold('m004')
>>> M.normal_surfaces()    
[<Surface 0: [0, 0] [1, 2] (4, 1)>,
 <Surface 1: [0, 1] [1, 2] (4, -1)>,
 <Surface 2: [1, 2] [2, 1] (-4, -1)>,
 <Surface 3: [2, 2] [2, 1] (-4, 1)>]