docstr: Compute the Root Mean Square Deviation between molecules.
  
  Parameters
  ----------
  df1 : pandas.DataFrame
      DataFrame with HETATM, ATOM, and/or ANISOU entries.
  
  df2 : pandas.DataFrame
      Second DataFrame for RMSD computation against df1. Must have the
      same number of entries as df1.
  
  s : {'main chain', 'hydrogen', 'c-alpha', 'heavy', 'carbon'} or None,
      default: None
      String to specify which entries to consider. If None, considers
      all atoms for comparison.
  
  invert : bool, default: False
      Inverts the string query if true. For example, the setting
      `s='hydrogen', invert=True` computes the RMSD based on all
      but hydrogen atoms.
  
  Returns
  ---------
  rmsd : float
      Root Mean Square Deviation between df1 and df2
code: def rmsd(df1, df2, s=None, invert=False):
      """Compute the Root Mean Square Deviation between molecules.
  
      Parameters
      ----------
      df1 : pandas.DataFrame
          DataFrame with HETATM, ATOM, and/or ANISOU entries.
  
      df2 : pandas.DataFrame
          Second DataFrame for RMSD computation against df1. Must have the
          same number of entries as df1.
  
      s : {'main chain', 'hydrogen', 'c-alpha', 'heavy', 'carbon'} or None,
          default: None
          String to specify which entries to consider. If None, considers
          all atoms for comparison.
  
      invert : bool, default: False
          Inverts the string query if true. For example, the setting
          `s='hydrogen', invert=True` computes the RMSD based on all
          but hydrogen atoms.
  
      Returns
      ---------
      rmsd : float
          Root Mean Square Deviation between df1 and df2
  
      """
      if df1.shape[0] != df2.shape[0]:
          raise AttributeError("DataFrames have unequal lengths")
      get_dict = PandasMmtf._init_get_dict()
      if s:
          if s not in get_dict.keys():
              raise AttributeError(
                  f"s must be in {get_dict.keys()} or None"
              )
          df1 = get_dict[s](df1, invert=invert)
          df2 = get_dict[s](df2, invert=invert)
  
      total = (
          (df1["x_coord"].values - df2["x_coord"].values) ** 2
          + (df1["y_coord"].values - df2["y_coord"].values) ** 2
          + (df1["z_coord"].values - df2["z_coord"].values) ** 2
      )
      return round((total.sum() / df1.shape[0]) ** 0.5, 4)
  
imports: from __future__ import annotations
  import os
  import copy
  import gzip
  import warnings
  from string import ascii_uppercase
  from typing import Any, Dict, List, Union
  from warnings import warn
  import numpy
  import pandas
  from looseversion import LooseVersion
  from mmtf import MMTFDecoder, MMTFEncoder, fetch, parse, parse_gzip
  from biopandas.constants import protein_letters_3to1_extended
  from ..pdb.engines import amino3to1dict, pdb_df_columns, pdb_records
label_desc: Use image node_id 8 for calling the PandasMmtf obj's underlying member method code with example usage: obj.rmsd(df1, df2, s, invert) and returns: round