code: def write_mmtf(df: pd.DataFrame, file_path: str):
      """Writes a biopandas dataframe to an MMTF file.
  
      Parameters
      ----------
      df : pd.DataFrame
          Dataframe to write
      file_path : str, default: '?'
          Path to output file.
      """
      count_models, count_chains, count_groups, count_atoms = 0, 0, 0, 0
      # Check if the input is a valid BioPandas DataFrame
      if not isinstance(df, pd.DataFrame):
          raise TypeError("The input must be a BioPandas DataFrame.")
  
      # Initialize MMTF encoder
      encoder = MMTFEncoder()
      encoder.init_structure(
          total_num_bonds=0,
          total_num_atoms=0,
          total_num_groups=0,
          total_num_chains=0,
          total_num_models=0,
          structure_id="",
      )
      encoder.set_xtal_info(space_group="", unit_cell=None)
  
      encoder.set_header_info(
          r_free=None,
          r_work=None,
          resolution=None,
          title=None,
          deposition_date=None,
          release_date=None,
          experimental_methods=None,
      )
  
      node_ids = (
          df.model_id.astype(str)
          + ":"
          + df.chain_id
          + ":"
          + df.residue_name
          + ":"
          + df.residue_number.astype(str)
          + ":"
          + df.insertion.astype(str)
      )
      df["residue_id"] = node_ids
      # Tracks values to replace them at the end
      chains_per_model = []
      groups_per_chain = []
  
      # Iterate over each model
      for model_idx, model in enumerate(df.model_id.unique()):
          # Subset the DataFrame to the current model
          # Ang get the chains
          model_df = df.loc[df.model_id == model]
          chains = model_df.chain_id.unique()
  
          count_models += 1
          # Set the model info
          encoder.set_model_info(
              # model_id=model_idx, # According to mmtf-python this is meaningless
              model_id=model_idx,  # According to mmtf-python this is meaningless
              chain_count=0,  # Set to 0 here and changed later
          )
          # Iterate over chains in model
          for chain_id in chains:
              seqs = []
              seq = ""
              prev_res_type = ""
              prev_resname = ""
              first_chain = True
  
              # Subset the dataframe to the current chain
              chain_df = model_df[model_df.chain_id == chain_id]
  
              # Iterate over residues in chain
              residues = chain_df.residue_id.unique()
              for residue_id in residues:
                  count_groups += 1
                  # Subset the dataframe to the current residue
                  residue_df = chain_df.loc[
                      chain_df.residue_id == residue_id
                  ]
                  # Get residue and entity types
                  if all(residue_df.record_name == "ATOM"):
                      residue_type = "ATOM"
                      entity_type = "polymer"
                  elif all(residue_df.residue_name == "HOH"):
                      residue_type = "HETATM"
                      entity_type = "water"
                  else:
                      residue_type = "HETATM"
                      entity_type = "non-polymer"
                  # Get the 3-letter residue name
                  resname = residue_df.residue_name.iloc[0]
  
                  # Check if the molecule changes within the chain
                  # This will always increment for the first residue in a
                  #  chain due to the starting values above
                  # Checking for similar entities is non-trivial from the
                  #  structure object so we treat each molecule as a separate
                  #  entity
                  if residue_type != prev_res_type or (
                      residue_type == "HETATM"
                      and resname != prev_resname
                  ):
                      encoder.set_entity_info(
                          chain_indices=[count_chains],
                          sequence="",  # Set to empty here and changed later
                          description="",
                          entity_type=entity_type,
                      )
                      encoder.set_chain_info(
                          chain_id=chain_id,
                          chain_name="\x00"
                          if len(chain_id.strip()) == 0
                          else chain_id,
                          num_groups=0,  # Set to 0 here and changed later
                      )
                      if count_chains > 0:
                          groups_per_chain.append(
                              count_groups - sum(groups_per_chain) - 1
                          )
                      if not first_chain:
                          seqs.append(seq)
                      first_chain = False
                      count_chains += 1
                      seq = ""
  
                  if entity_type == "polymer":
                      seq += _seq1(
                          residue_df.residue_name.unique()[0],
                          charmap=protein_letters_3to1_extended,
                      )
  
                  prev_res_type = residue_type
                  prev_resname = resname
  
                  group_type = (
                      "NON-POLYMER"
                      if residue_type == "HETATM"
                      else "L-PEPTIDE LINKING"
                  )
                  encoder.set_group_info(
                      group_name=residue_df.residue_name.unique()[0],
                      group_number=int(
                          residue_df.residue_number.unique()[0]
                      ),
                      insertion_code="\x00"
                      if residue_df.insertion.unique()[0] == ""
                      else residue_df.insertion.unique()[0],
                      group_type=group_type,  # Hack to ensure we can re-parse.
                      atom_count=len(residue_df),
                      bond_count=0,
                      single_letter_code=_seq1(
                          df.residue_name.unique()[0],
                          charmap=protein_letters_3to1_extended,
                      ),
                      sequence_index=len(seq) - 1
                      if entity_type == "polymer"
                      else -1,
                      secondary_structure_type=-1,
                  )
                  for row in residue_df.itertuples():
                      count_atoms += 1
                      encoder.set_atom_info(
                          atom_name=row.atom_name,
                          serial_number=row.atom_number,
                          alternative_location_id="\x00"
                          if row.alt_loc == ""
                          else row.alt_loc,
                          x=row.x_coord,
                          y=row.y_coord,
                          z=row.z_coord,
                          occupancy=row.occupancy,
                          temperature_factor=row.b_factor,
                          element=row.element_symbol,
                          charge=0
                          if row.charge == ""
                          else int(row.charge),
                      )
              seqs.append(seq)
              start_ind = len(encoder.entity_list) - len(seqs)
              for i, seq in enumerate(seqs):
                  encoder.entity_list[start_ind + i]["sequence"] = seq
  
          chains_per_model.append(count_chains - sum(chains_per_model))
      groups_per_chain.append(count_groups - sum(groups_per_chain))
  
      encoder.chains_per_model = chains_per_model
      encoder.groups_per_chain = groups_per_chain
      encoder.num_atoms = count_atoms
      encoder.num_groups = count_groups
      encoder.num_chains = count_chains
      encoder.num_models = count_models
      encoder.finalize_structure()
      encoder.write_file(file_path)
  
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 5 for calling a global function with example usage: write_mmtf(df, file_path) without return types