moleditpy_cif_viewer

MoleditPy CIF Viewer

A crystal structure viewer plugin for MoleditPy.

This plugin allows researchers and developers to load CIF files, generate supercells, customize rendering styles, view along crystallographic axes, and display anisotropic displacement parameters (Thermal Ellipsoids) with extensive styling options.

Table of Contents

  1. Key Features
  2. Detailed Tab Guide & Settings
  3. Advanced Rendering & Optimization
  4. Crystallographic Camera Math
  5. Code Architecture & Integration
  6. Installation
  7. Verification & Testing
  8. Dependencies

Key Features


Detailed Tab Guide & Settings

The CIF Viewer control panel docks as a widget on the right side of the main window (View > CIF Viewer Panel). Its interface is organized into four sections:

1. Structure Tab

2. Supercell Tab

3. Ellipsoids Tab

4. Cell / Axes Tab


Advanced Rendering & Optimization

Drawing thousands of spheres and lines individually can bottleneck the CPU/GPU interface. The plugin uses several advanced strategies to maximize performance:

  1. Single Mesh Merging: Instead of adding a PyVista actor for each ellipsoid, the plugin pre-processes the point-cloud of the atoms. For each atom, it creates a base sphere, applies the anisotropic displacement scale matrix, rotates it according to the thermal eigenvectors, translates it to the fractional position, and colors it. All individual meshes are then concatenated into a single master pyvista.PolyData mesh and added to the plotter in one call.
  2. PolyData Lines Pre-Assembly: Rings representing the outer boundaries of the ellipsoids are constructed by calculating circular segments around the principal planes of the thermal ellipsoids. The points for all circles are pre-calculated, indexed, and loaded into a single polydata line mesh structure to be drawn in a single operation.
  3. Debouncing: Adjusting sliders or color pickers can trigger multiple redraw signals in milliseconds. The widget routes all redraw events through a 50ms single-shot QTimer (self.render_timer). Rapid adjustments reset the timer, ensuring a single render occurs only after the user stops interacting with the UI.

Crystallographic Camera Math

Viewing along crystallographic axes requires setting the camera’s position, focal point, and up vector relative to the lattice vectors.

Let the unit cell lattice be represented by a $3 \times 3$ matrix: \(\mathbf{L} = \begin{bmatrix} \mathbf{a} \\ \mathbf{b} \\ \mathbf{c} \end{bmatrix}\)

When a user clicks one of the directional buttons, the camera properties are calculated as follows:

Button View Direction ($\mathbf{d}$) View Up Vector ($\mathbf{u}$)
a $\mathbf{a}$ $\mathbf{c}$
-a $-\mathbf{a}$ $\mathbf{c}$
b $\mathbf{b}$ $\mathbf{c}$
-b $-\mathbf{b}$ $\mathbf{c}$
c $\mathbf{c}$ $\mathbf{b}$
-c $-\mathbf{c}$ $\mathbf{b}$
  1. Focal Point: The center of the current supercell, calculated using the lattice vectors scaled by their repetition bounds: \(\mathbf{f} = \frac{1}{2} (n_a \mathbf{a} + n_b \mathbf{b} + n_c \mathbf{c})\)
  2. Distance: Scaled to twice the maximum dimension of the supercell bounding box to guarantee all atoms fit in the viewport: \(\text{distance} = 2 \times \max(\|\mathbf{a}\| n_a, \|\mathbf{b}\| n_b, \|\mathbf{c}\| n_c)\)
  3. Camera Position: Positioned along the unit direction vector $\mathbf{\hat{d}}$ at the computed distance from the focal point: \(\mathbf{p} = \mathbf{f} + \mathbf{\hat{d}} \times \text{distance}\)
  4. View Up: Normalized view up vector $\mathbf{\hat{u}}$ ensuring stable crystallographic orientation.

Code Architecture & Integration

The plugin uses the MoleditPy Plugin API, structured as follows:

Failsafe Safeguard

The custom drawing callback in __init__.py checks the active molecule for the _from_cif_viewer property. If a user loads a normal molecule (e.g. from an XYZ or MOL file) while the style is set to “Thermal Ellipsoids”, the plugin automatically switches the view back to “Ball and Stick” style, preventing rendering artifacts or crash loops.


Installation

Standard Installation

Download from Plugin Explorer. Place the cif_viewer folder into your local MoleditPy plugins directory (typically under ~/.moleditpy/plugins/).


Verification & Testing

The plugin comes with a comprehensive unit and integration test suite that runs headlessly by mocking the main application context and Qt GUI loop.

# Run the full test suite
python test_all.py

# Run only unit/parser tests (skipping PyQt6 GUI/integration tests)
python test_all.py --unit-only

Dependencies