Tutorial: 3D Flex Mesh Preparation

It can often be important to the success of 3D Flexible Refinement that a mesh with the proper topology is created prior to training. The mesh defines what types of motion are “allowable”. In this article, we first highlight the theoretical grounding for 3D Flex meshes and why custom meshes may be necessary in many cases. We then walk through the process of creating an example mesh. More detail is available in the original 3D Flexible Refinement publication (Punjani and Fleet, 2023).

The material covered in this page is also available in video form:


3D Flex Meshes are used to regularize the 3D Flex deformation model during training. Custom meshes are most useful when discontinuous motion, such as separation or sliding, are expected. When generating a custom mesh, special care must be taken when deciding on a fusion strategy to allow the model to capture the full range of target motion.

3D Flex Mesh Overview

Why model deformation with a mesh?

At its core, CryoSPARC’s 3D Flex is attempting to determine the conformation of a given single particle using just one image. The algorithm treats conformational change as movement of electron potential from one voxel to another.

An algorithm to directly solve this problem by checking various mixtures of density in various voxels would be both slow and sensitive to overfitting. We have therefore implemented 3D Flex to instead model movement of the vertices of a mesh. This reduces the number of degrees of freedom in the model and imposes smoothness on the resulting flexibility because nearby regions of the map must move together. The reduced number of degrees of freedom also result in increased speed during training.

To explain how the use of a deformation mesh achieves these goals, consider a theoretical 1D particle. This particle can stretch or squish to various degrees along its length. Rather than directly try to model the movement of intensity from one pixel to another, we instead create a mesh along the particle, like so.

Then, rather than applying a deformation to each pixel individually, we instead move just the points of the mesh. Everything between the mesh points is squished or stretched linearly as the points on either side move closer or further apart:

The same principle can be applied in higher dimensions — the important point is that the algorithm is only modeling deformation of the mesh. The deformation of the underlying volume is, in turn, a function of the deformation of the mesh.

Meshes are created with the 3D Flex Mesh Prep job. This job requires a consensus volume and a solvent mask. When you run this job, a number of tetrahedral cells (hereafter just “tetras”) will be created to span the entirety of the box. The resulting tetra mesh can then be used by a 3D Flex Training job to model the movement of the particles. It is during the training job that the tetra cell vertices are moved to model deformation — 3D Flex Mesh Prep jobs produces the vertices in their evenly-spaced “starting” positions.

This is an important point — both vertices and tetras are important in 3D Flex. When a vertex moves, the tetra deforms. This deformation will move any voxels inside the tetra in a linear fashion. For a simpler example, consider again the two-dimensional case. We start with a consensus reconstruction, a solvent mask, and a set of “tetras” (triangles in 2D). When we move individual vertices along the right-hand side of our mesh, the rectangular particle is deformed linearly within each tetra.

Using this technique we can model most forms of continuous motion as movement of the vertices which make up the mesh (or, equivalently, the expansion and contraction of tetras). Note, however, that moving a vertex deforms all adjacent tetras in the same way. All of these tetras share their vertices, so they cannot move independently from each other.

We thus cannot model discontinuous motion (i.e., domains which slide past each other or move apart from one another) using a single tetra mesh. We therefore must segment the mesh into separate parts which can move independently.

Discontinuous Motion

Consider the case in which we have two domains which “slip” past each other:

To model the movement of the purple arrow downward we could move the vertices enclosing it downward. Similarly, to move the orange arrow upward we could move the vertices surrounding the orange arrow upward.

However, this creates a problem at the interface between the two arrows — the vertices there want to move downward and upward at the same time.

This is not possible with a single mesh — the vertex must move either up or down. Therefore, the sliding movement of these two arrows cannot be modeled with this mesh topology.

To resolve this conflict, we instead create two overlapping meshes and assign each arrow to its respective mesh. These meshes start with vertices and tetras in the same position, but there are now multiple vertices and tetras where the meshes overlap.

In this image, we have segmented our starting mesh into two distinct meshes, one for each arrow. As before, each mesh is defined by a set of vertices, indicated with blue circles. The vertices are annotated with a symbol corresponding to the mesh to which they belong.

At the border between the two arrows, where the two meshes meet, there are two vertices which start in the same position. These vertices are thus annotated with both an up- and down-arrow symbol. This vertex duplication allows each mesh to deform the same region of space in its own direction, since it models that region with vertices and tetras which are independent of the other mesh.

Note that the formerly-overlapping vertices are no longer in the same position. The orange mesh moved its vertices up and to the right, while the purple mesh moved its vertices down and to the left. We have successfully modeled sliding movement of the arrows, even though they are positioned in a region of space which fits inside a single tetra.

When is a custom mesh required?

As demonstrated above, domains which are expected to slide past each other or move apart from each other require custom meshes. Other types of flexibility, or specific targets, may benefit from a custom mesh even in the absence of sliding or separating movements. For instance, proteins with a micelle may benefit from a custom mesh in which the micelle is segmented into a separate mesh which is then marked as rigid, so as not to waste latent space modeling uninteresting deformation of the micelle.

In the remainder of this page, we walk through the process of segmenting and creating a mesh.

How does CryoSPARC assign voxels to one or the other overlapping mesh?

When you create a segmented 3D Flex mesh, two objects are actually created. The first is the mesh (or set of meshes), which itself comprises a list of vertices and the connections between those vertices. The connections are listed in out in sets of four, with each set therefore defining a tetrahedral cell. Each of these tetra cells are then assigned to a mesh.

The second object is a tetra mask, which is a 3D volume the same size as the input volume used for segmentation and training. Each voxel of the tetra mask stores an integer value corresponding to the mesh to which that voxel “belongs”.

During training and reconstruction, the density in a particular voxel is flowed along the vector described by the mesh indicated by its coordinate in latent space and the tetra to which it is mapped.

In this way, tetra meshes can overlap while still only moving map density from “their own” voxels, and voxel-level segmentation is retained while the tetras themselves are significantly larger than a single voxel.

Creating a custom mesh

Creating a custom mesh from prepared data comprises three main steps:

  1. Create the segmentation

  2. Decide on a mesh fusion strategy

  3. Run the 3D Flex Mesh Prep job

This tutorial will walk through the details of each of these steps, working through the process of creating a custom 3D Flex Mesh for NaV 1.7 (EMPIAR 10261). The data used in this tutorial were originally collected and processed by Xu and colleagues (2019).

Creating a segmentation

3D Flex Mesh Prep jobs need a way to assign each voxel in the consensus map to a particular tetrahedron. In the default case, there is only one tetra segment which covers the entire map. Assignment is thus trivial — voxels belong to the lone tetra that encloses that voxel.

However, in the case of the custom mesh, voxels which are on the border between two segments may be enclosed by two or more tetra cells, so their assignment is uncertain. The segmentation we create in this step explicitly assigns every voxel inside the mask to one and only one tetra.

Segmenting the mesh using another tool We recommend creating a segmentation using the Segger tool in ChimeraX, and we cover that technique in this tutorial. If you prefer another tool, 3D Flex Mesh Prep jobs also accept an .mrc file with an integer value in each voxel corresponding to that voxel’s segment.

The segmentation .mrc file should have the same dimensions as the map from 3D Flex Data Prep. In each voxel, store an integer value to indicate the segment ID for that voxel. All voxels of a given segment should contain the same segment ID value. The segment IDs you use should start from zero and be contiguous (i.e., for S segments, use the IDs 0, 1, 2,..., S-1) . Indicate solvent voxels (i.e., "No segment") with -1. When identifying segments for fusion, use the integers in the .mrc file instead of using ChimeraX segment ID numbers.

First, download the consensus volume from the 3D Flex Data Prep job. This volume has already been cropped and downsampled to match the training box size. For Nav 1.7, the consensus volume looks like this:

From the lower contour (transparent in this image) it is clear that the C-terminus of the channel (bottom of the image) is poorly aligned, perhaps due to flexibility. However, it should never slide along or separate from the well-aligned transmembrane domain (TMD), so the TMD and C-terminus should be one segment. Two fabs are bound to the channel at the top of the image. A 3D Variability Analysis job shows that these Fabs flex toward and away from each other, so they should be separated into individual mesh segments.

Finally, the micelle is visible in the low contour. There is not a clear best method of treating the micelle in 3D Flex Meshes. We generally recommend starting by segmenting the micelle into its own mesh and marking it as rigid, but there are several alternate treatments of the micelle which may produce better results with some targets. See the Micelles, fusion, and rigidity section of this page for more discussion of this topic.

The custom mesh for this target will therefore have four mesh segments:

  1. The “root” segment of the TMD and C-terminus

  2. The micelle, which should be treated as if it is rigid

  3. The “left” Fab

  4. the “right” Fab

Following the guidance in the Mask Creation tutorial, the Segger segmentation for such a mesh looks like this:

At this point you should make note of the segment numbers for your segmentation. You can find the segment number by hovering over a region of the segmentation and reading the number out of the tooltip. In this example, the “left” Fab is segment 570, the “right” fab is segment 569, the micelle is segment 572, and the TMD/C-terminus segment is number 571.

The hover tooltip displays both the segment number and ChimeraX’s model ID. The segment number is the one you will enter into CryoSPARC and usually appears first. It does not have a prefix and is typically a larger integer, e.g., 570. The ChimeraX model ID, which is not what you want, is instead prefixed with a # and is typically two small integers separated by a ., e.g., #2.2.

Save the segmentation as a .seg file using File > Save segmentation in the Segger pane and upload the resulting file to the CryoSPARC system.

Decide on a fusion strategy

Why fuse segments?

Recall that the ultimate goal of this job is to create separate mesh segments with overlapping tetra cells to allow for discontinuous movement of domains which are not physically attached to each other. When you import your segmentation, the creation of these independent meshes is automatic, since they are fully defined by the base tetra grid and the segmentation file. However, there is no way to know from this information alone which vertices should be physically coupled and which should be allowed to move freely.

For instance, using the above segmentation, the mesh creation job will create four tetra mesh segments.

In these images, tetras are colored by which mesh segment they belong to. They have also been slightly scaled inward for visibility — the true tetra cells share edges with no gap between them.

Each of these mesh segments comprise individual tetras which use the same vertex grid. Additionally, each segment contains some tetra cells which enclose the same physical space as other grids. For instance, the green and yellow grids both contain tetra cells which enclose the interface between the two fabs.

We can show this in another way by marking the vertices with symbols based on which grids use that vertex, as we did for the 2D example above:

In this image, the base tetra mesh vertices are marked with transparent spheres. If a tetra mesh contains any tetra cells which use a vertex, that vertex is marked with a symbol corresponding to that mesh. Vertices between the two fabs are used by both the green and yellow meshes, so they are marked with a green cube and a yellow cone. As with the 2D example, the green and yellow meshes each have their own “copy” of these vertices that they can move independently during training and reconstruction — they only overlap now because both meshes start in their consensus, undeformed state.

Additionally, each Fab also has overlapping tetra cells with the TMD/C-terminal segment:

The Fabs are bound tightly to the TMD, and so the 3D Flex model should not be allowed to move voxels which belong to the fab away from voxels which belong to the TMD. However, if each Fab is in its own mesh, there is no reason for the model to keep them attached to the TMD. We must impose this mesh fusion on the model.

Consider the 2D cartoon above. If each mesh is allowed to move independently (top), the arrows can separate from each other instead of sliding. If, however, the overlapping tetras are removed and the border vertices are forced to occupy the same position, the orange arrow can no longer move away from the purple arrow.

The process of:

  1. Deleting one copy of tetras shared by two meshes, then

  2. Fixing the position of the border vertices to be the same in both meshes

is called a mesh fusion. Tuning these fusions is an important component of generating a custom mesh. Typically, several fusion strategies should be tried to find the optimal parent/child order and final mesh topology.

In this example, we will fuse each fab and the micelle to the TMD and no other fusions.

Mesh Fusion and Rigidity

It is important to be careful when choosing a mesh fusion strategy when some segments will be marked rigid.

In this cartoon example, the blue segment is fused to yellow, yellow to orange, etc. The pink segment is the only rigid segment. It may be obvious that the vertices that purple and red share with pink will be rigid, since those mesh segments are fused. However, the central vertex of all of the mesh segments will be rigid, since blue cannot move its central vertex without moving that of yellow, etc., until we consider that red’s central vertex cannot move without moving the rigid vertex of pink. Although this fact may be readily apparent in this simple example, results of segment fusion can be less obvious when considering a three-dimensional mesh.

Running the Job

Launch the 3D Flex Mesh Prep job and input the prepared solvent mask and consensus volume and enter the path to the .seg file. In the example segmentation, the TMD/C-terminus segment is 571, the two Fabs are 569 and 570, and the micelle is 572. The Segment connections field (which controls segment fusions) should therefore read 571>569,571>570,571>572 to produce our desired topology of TMD > Fab1, TMD > Fab2, TMD > micelle.

Finally, we set the micelle segment fully rigid by entering 572 in Rigid segments. This allows the 3D Flex Train job to correctly model the micelle without trying to move density in or out of this region.


The three components of the 3D Flex Train results are displayed above. The constant regions (at the top of the image) of the fabs are able to move closer together and further apart with the custom mesh than the default mesh, because they are not fused together. Note, however, that the TMD is held relatively steady because of the rigidity of the micelle segment.

Directly investigating the mesh can be overwhelming, but provides insight into how tetra cells are allowed to deform when one or more of their vertices are fused with other tetra segments.

Micelles, fusion, and rigidity

Consider the motions detected by 3D Variability again, paying close attention to the transmembrane domain:

3DVA modeled a significant flexing motion of the TMD, but the 3D Flex results captured only a slight deformation of this region. While it is possible that 3D Flex more accurately modeled the data and the channel truly is rigid, it is also possible that this rigidity is an artifact of marking the micelle segment rigid.

As discussed above, if a vertex belongs to two fused meshes, it must occupy the same position in both meshes. This means that the edges of the TMD are treated as rigid, since they must be in the same position as the rigid micelle. Additionally, because the mesh is extended to fill the mask, the C-terminus moves in our custom mesh example than the default mesh, because it is also fused to the rigid micelle.

It is undesirable for the micelle to hold parts of the target in a single rigid conformation. However, there is not yet an obvious best treatment of micelles in 3D Flex. Below we present a non-exhaustive collection of alternate fusion strategies, each of which have their own advantages and drawbacks. Aside from the fusion parameter, these training jobs all used the same parameters. Optimization of the other training parameters for each fusion strategy may further improve results.

Which of these strategies (or a strategy of your own creation) works best depends on the sample. The best results typically require trying a few different fusion strategies, especially for new targets with as-yet unknown motion.

Note that it is not currently possible to make a one-to-one comparison between different 3D Flex training jobs, as the latent spaces are almost certainly different. For these examples we display a trajectory along each coordinate (the default behavior of 3D Flex Generate).

Alternate strategy 1: Do not mark the micelle as rigid

Another approach would be to simply allow the micelle to move as much as any other segment. This approach allows the Flex model to “see” micelle density and so prevents it from filling the micelle with density from other regions, and allows nearby regions like the TMD to move freely. However, in some cases, the model will dedicate an undesirable amount of focus to modeling micelle noise rather than biologically-relevant flexibility.

Here is the result of using the same mask and mesh as above, but without setting the micelle as rigid.

The flexibility of the fabs remains clear, but the movements of the TMD and C-terminus have also been captured, unlike the rigid micelle example. Clearly, fusing a rigid micelle to the TMD had a detrimental effect on the ability of 3D Flex to model those domains.

Alternate strategy 2: Mask out the micelle entirely

One obvious approach is to mask the micelle out entirely, as one would for 3DVA or Local Refinement. In some cases, this does produce good results. In others, the model moves density which belongs to the helices to fill the empty space where the micelle should be. This happens because no matter how we mask the volume, the micelle is still present in the images, and the model has no way of knowing which parts of the image we may want it to ignore.

Here is the result of using a mask during the mesh prep job that does not include the micelle, then creating a custom mesh with three segments: one for each fab and one for the channel.

This mesh produced a model in which the C-terminus and TMD are both highly flexible — more than either the the rigid or non-rigid micelle models. However, the movement of the fabs toward and away from each other is no longer clear.

Unlike all other forms of refinement currently available in CryoSPARC, 3D Flexible Refinement performs volume reconstruction in real space rather than Fourier space. This can introduce surprising and significant artifacts when the mask cuts through significant map density. If large streaks of map density are observed, we recommend increasing the size of the mask.

Alternate strategy 3: Fuse the rigid micelle to a less flexible region

Recall that when we fuse regions, we do not necessarily need to follow the physical linkages of the sample. In the case of the NaV 1.7 channel, the micelle truly is fused (in some sense) to the TMD — but for the purposes of 3D Flex, we could fuse it to one of the Fabs instead. This would allow the TMD to move independently of the micelle, and could allow rigid body movement of the entire channel/fab complex relative to the micelle. Below is an example of this fusion strategy.

Treating the micelle in this way also failed to capture the flexibility of the TMD, and also may have held the Fabs more rigid. However, the model is able to move the C-terminus of the channel significantly more in this topology than when the micelle was fused to the ion channel.

Recalling that each mesh segment is expanded to fill the mask this result is not too surprising, since the rigid micelle and C-terminus share a border. The movement of the C-terminus in this example may therefore also be captured if a fifth mesh segment was added surrounding the C-terminus and fused to the TMD.


  1. Ali Punjani and David J. Fleet, “3DFlex: Determining Structure and Motion of Flexible Proteins from Cryo-EM,” Nature Methods 20, no. 6 (June 1, 2023): 860–70, https://doi.org/10.1038/s41592-023-01853-8.

  2. Hui Xu et al., “Structural Basis of Nav1.7 Inhibition by a Gating-Modifier Spider Toxin,” Cell 176, no. 4 (February 7, 2019): 702-715.e14, https://doi.org/10.1016/j.cell.2018.12.018.

Last updated