docstr: Write record DataFrames to a PDB file or gzipped PDB file.
  
  Parameters
  ----------
  path : str
      A valid output path for the pdb file
  
  records : iterable, default: None
      A list of PDB record sections in
      {'ATOM', 'HETATM', 'ANISOU', 'OTHERS'} that are to be written.
      Writes all lines to PDB if `records=None`.
  
  gz : bool, default: False
      Writes a gzipped PDB file if True.
  
  append_newline : bool, default: True
      Appends a new line at the end of the PDB file if True
code: def to_pdb(self, path, records=None, gz=False, append_newline=True):
      """Write record DataFrames to a PDB file or gzipped PDB file.
  
      Parameters
      ----------
      path : str
          A valid output path for the pdb file
  
      records : iterable, default: None
          A list of PDB record sections in
          {'ATOM', 'HETATM', 'ANISOU', 'OTHERS'} that are to be written.
          Writes all lines to PDB if `records=None`.
  
      gz : bool, default: False
          Writes a gzipped PDB file if True.
  
      append_newline : bool, default: True
          Appends a new line at the end of the PDB file if True
  
      """
      if gz:
          openf = gzip.open
          w_mode = "wt"
      else:
          openf = open
          w_mode = "w"
      if not records:
          records = self.df.keys()
  
      dfs = {
          r: self.df[r].copy() for r in records if not self.df[r].empty
      }
  
      for r in dfs:
          for col in pdb_records[r]:
              dfs[r][col["id"]] = dfs[r][col["id"]].apply(col["strf"])
              dfs[r]["OUT"] = pd.Series("", index=dfs[r].index)
  
          for c in dfs[r].columns:
              # fix issue where coordinates with four or more digits would
              # cause issues because the columns become too wide
              if c in {"x_coord", "y_coord", "z_coord"}:
                  for idx in range(dfs[r][c].values.shape[0]):
                      if len(dfs[r][c].values[idx]) > 8:
                          dfs[r][c].values[idx] = str(
                              dfs[r][c].values[idx]
                          ).strip()
              if c in {"line_idx", "OUT"}:
                  pass
              elif r in {"ATOM", "HETATM"} and c not in pdb_df_columns:
                  warn(
                      "Column %s is not an expected column and"
                      " will be skipped." % c
                  )
              else:
                  dfs[r]["OUT"] = dfs[r]["OUT"] + dfs[r][c]
  
      if pd_version < LooseVersion("0.17.0"):
          warn(
              "You are using an old pandas version (< 0.17)"
              " that relies on the old sorting syntax."
              " Please consider updating your pandas"
              " installation to a more recent version.",
              DeprecationWarning,
          )
          dfs.sort(columns="line_idx", inplace=True)
  
      elif pd_version < LooseVersion("0.23.0"):
          df = pd.concat(dfs)
  
      else:
          df = pd.concat(dfs, sort=False)
  
      df.sort_values(by="line_idx", inplace=True)
  
      with openf(path, w_mode) as f:
          s = df["OUT"].tolist()
          for idx in range(len(s)):
              if len(s[idx]) < 80:
                  s[idx] = f"{s[idx]}{' ' * (80 - len(s[idx]))}"
          to_write = "\n".join(s)
          f.write(to_write)
          if append_newline:
              f.write("\n")
  
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 18 for calling the PandasMmtf obj's underlying member method code with example usage: obj.to_pdb(path, records, gz, append_newline) without return types