Morfeus Molecular Feature Calculations

repository·main·Indexed 42 days ago

https://github.com/digital-chemistry-laboratory/morfeus

A Python package for calculating molecular features and descriptors in chemistry, including steric and electronic properties. It provides tools for computing exact cone angles, bite angles, buried volume (with quadrant and octant decomposition), and distal volume. Morfeus includes a comprehensive CLI for quick calculations and supports conformer generation via RDKit and OpenBabel.

Tokens
14.7K
Snippets
58
Records
69
Agent score
51%

What's inside Morfeus

  1. Overview of Morfeus features

    main

    Morfeus is designed to calculate molecular features from 3D structures, with a primary focus on steric descriptors. Supported features include:

    • Bite angle
    • Buried volume
    • Conformer tools
    • Dispersion descriptor
    • Exact ligand cone angle
    • Ligand solid angle
    • Local force constant
    • Pyramidalization
    • Solvent accessible surface area
    • Sterimol parameters
    • XTB electronic descriptors
  2. Understanding ligand solid angle, cone angle, and G parameter

    main

    Morfeus implements a numerical method to quantify ligand shielding:

    • Ligand Solid Angle (Ω): The solid angle of the complete shadow cast by a ligand when hypothetically illuminated from the metal center.
    • Solid Cone Angle (Θ): A value calculated from Ω that is analogous to Tolman's cone angle. It is expressed in degrees.
    • G Parameter: A measure of how much of the metal coordination sphere is shielded by the ligands, expressed in percent.

    Morfeus uses a numerical method similar to the Solid-G program but with different radii. Results are benchmarked against the exact solid angle program by Allen et al. and agree within numerical accuracy.

  3. Understand one-based atom indexing in Morfeus

    main

    The Morfeus API uses one-based indexing for atom indices (the first atom is index 1). This is designed to match visual indices in molecular viewers.

    To accommodate Python's standard zero-based indexing, atom properties are returned as dictionaries where the keys are the one-based indices. If you need to use these properties with standard Python list operations or zero-based loops, you can convert the dictionary values to a list.

    from morfeus import SASA, read_geometry
    
    # Properties are returned as dictionaries with 1-based keys
    elements, coordinates = read_geometry("Et.gjf")
    sasa = SASA(elements, coordinates)
    print(sasa.atom_areas) 
    # Output: {1: 22.489..., 2: 19.180..., ...}
    
    # Convert to a zero-indexed list if needed
    area_list = list(sasa.atom_areas.values())
    print(area_list)
    # Output: [22.489..., 19.180..., ...]
  4. Handle transition states in local force calculations

    main

    Local force constants and frequencies are based on the harmonic approximation and are valid at stationary points (minima and transition states).

    Important Constraints for Transition States:

    • Only the local modes method can be used for transition states.
    • The imaginary mode corresponding to the reaction is projected out by the local modes approach.
    • Local force constants and frequencies involving the atoms corresponding to this imaginary mode are meaningless and should not be used.
    • The local modes method is generally more robust to small imaginary frequencies than the compliance matrix method.
  5. Understanding Pyramidalization measures (P and P_angle)

    main

    Morfeus implements two distinct mathematical models for pyramidalization of tetracoordinate atoms:

    Agranat and Radhakrishnan (P)

    Calculated using angles $\alpha$ and $\theta$: $$P = \sin{\theta} \cdot \cos{\alpha}$$

    • $\theta$ is the angle between vectors a and b (from the central atom to substituents A and B).
    • $\alpha$ is the angle between vector c (to substituent C) and the normal vector u to the plane defined by a and b.
    • Note on extreme cases: Following Tobias Gensch, if the angle between vector c and the sum of vectors a and b is acute, $\alpha$ is treated as negative. In such cases, the final value is calculated as $2 - P$, allowing values to exceed unity.

    Gavrish (P_angle)

    An alternative measure based on the sum of the three bond angles $\theta$: $$P = \sqrt{360° - \sum{\theta}}$$ where the sum is over the three possible bond angles around the central atom.

  6. Concept: Solvent Accessible Surface Area (SASA) in Morfeus

    main

    Solvent Accessible Surface Area (SASA) measures how much of a molecule's area is available to a solvent. Atomic SASA serves as a measure of the steric availability of a specific atom.

    Implementation Details:

    • Algorithm: Morfeus uses a modified version of the Shrake and Rupley method, employing a constant surface density of points rather than a fixed number of points per atom.
    • Volume Calculation: Atomic SASA and volumes are computed following the method described by Eisenhaber et al.
    • Limitations: Morfeus is not optimized for very large molecules (such as proteins); specialized software is recommended for those use cases.
  7. Handle inverted bite angles (> 180°)

    main

    A bite angle is considered 'inverted' if it exceeds 180°. Because this cannot be detected automatically from coordinates alone, you must provide a reference to determine the correct orientation.

    You can supply ref_atoms (a list of atom indices). The class will automatically construct a ref_vector pointing from the metal atom to the geometric mean of these reference atoms. This vector defines the 'direction' of the ligand.

    Use the .inverted property to check if the angle was detected as inverted.

    from morfeus import BiteAngle, read_xyz
    
    elements, coordinates = read_xyz("bpy_inverted.xyz")
    
    # Use ref_atoms to resolve the orientation for angles > 180°
    ba = BiteAngle(coordinates, 1, 2, 3, ref_atoms=[4, 17])
    
    print(ba.angle)     # Returns the angle (e.g., 198.39...)
    print(ba.inverted)  # Returns True if the angle is inverted
  8. Concept: Exact cone angles vs. Tolman cone angles

    main

    While the original Tolman cone angle was designed for assessing ligand steric size, it has limitations with asymmetric ligands.

    morfeus implements exact cone angles based on the method by Allen et al. (Bilbrey et al., 2013). This implementation is suitable for both monodentate and multidentate ligands and has been benchmarked to agree with the original article within numerical accuracy.

  9. Understand local force constant methods in Morfeus

    main

    Morfeus supports two primary methods for calculating local force constants: the local modes method (Cremer) and the compliance matrix method (Grunenberg). These methods are numerically equivalent in most cases.

    Handling Imaginary or Low-Frequency Modes

    In cases where modes have imaginary or very small frequencies, the local modes approach is more robust. Morfeus handles these problematic cases by default using the following logic:

    1. Projection: It projects out imaginary modes.
    2. Cutoff: It raises the force constants of low-frequency modes to a cutoff value of 0.001 mDyne/Å.

    Recommendation: Use the local modes method with default settings for the most robust results in problematic cases. Expert users can manually disable projection or alter the cutoff value.

    Limitation: Interactions involving imaginary modes (e.g., bond breaking/forming in transition states) cannot be assessed by local force constants.

  10. Decompose buried volume into quadrants and octants

    main

    You can decompose the buried volume into contributions from quadrants and octants using the .octant_analysis() method. To ensure reproducible results, you must orient the system using the following keyword arguments in the BuriedVolume constructor:

    • z_axis_atoms (list of int): Atom indices used to define the z-axis. The axis is oriented from the geometric center of these atoms toward the metal atom.
    • xz_plane_atoms (list of int): Atom indices used to define the xz-plane. The coordinate system is rotated so the geometric mean of these atoms lies in the xz-plane.

    Results: After calling .octant_analysis(), results are stored in:

    • bv.octants: A dictionary containing percent_buried_volume, buried_volume (ų), and free_volume (ų) for each octant (numbered 0–7).
    • bv.quadrants: A dictionary containing percent_buried_volume, buried_volume (ų), and free_volume (ų) for each quadrant (numbered 1–4).
    bv = BuriedVolume(elements, coordinates, 1, 
                      excluded_atoms=[2, 3, 4, 5, 6, 7], 
                      z_axis_atoms=[14], 
                      xz_plane_atoms=[11])
    bv.octant_analysis()
    
    # Access results
    print(bv.octants)
    print(bv.quadrants)
  11. How CLI subcommands and partial initialization work

    main

    Each subcommand in the CLI corresponds to a Python class in the morfeus module system.

    When you run a command like morfeus sterimol tBu.xyz -, the CLI performs partial initialization. It reads the geometry file (tBu.xyz) to extract elements and coordinates, then returns a partially instantiated Sterimol object.

    To fully instantiate the object and access its methods or attributes, you must provide the remaining required arguments (like dummy_index and attached_index) and use a hyphen - to signal that the object should be evaluated.

    To inspect the available arguments and flags for a partially instantiated object, use the -- --help syntax.

    # Partially instantiate Sterimol with a geometry file
    $ morfeus sterimol tBu.xyz -
    
    # Inspect available flags/arguments for the partially instantiated object
    $ morfeus sterimol tBu.xyz - -- --help
    
    # Fully instantiate and call a method
    $ morfeus sterimol tBu.xyz - 1 2 --radii_type=bondi - print_report
  12. Use Interactive Mode in the CLI

    main

    You can pass the result of a CLI command to an interactive Python REPL (IPython) by using the -- --interactive flag. This allows you to manually manipulate the resulting object, such as calling 3D drawing methods or accessing attributes directly.

    $ morfeus sterimol tBu.xyz - 1 2 - -- --interactive
    
    # Inside the REPL:
    In [1]: result.bond_length
    Out[1]: 1.1
    In [2]: result.draw_3D()