docs: def to_pdb(structure, filename, contigs=None, annotations=None,
             indices=None, special_bins=None):
      """From a structure (or matrix) generate the corresponding pdb file
      representing each chain as a contig/chromosome and filling the occupancy
      field with a custom annotation. If the matrix has been trimmed somewhat,
      remaining indices may be specified.
      """
  
      n = len(structure)
      letters = (string.ascii_uppercase + string.ascii_lowercase +
                 string.digits + string.punctuation) * int(n / 94 + 1)
      if contigs is None:
          contigs = np.ones(n + 1)
      if annotations is None:
          annotations = np.zeros(n + 1)
      if indices is None:
          indices = range(n + 1)
      if special_bins is None:
          special_bins = np.zeros(n + 1)
  
      structure_shapes_match = structure.shape[0] == structure.shape[1]
      if isinstance(structure, np.ndarray) and structure_shapes_match:
          structure = (to_structure(structure))
  
      X, Y, Z = (structure[:, i] for i in range(3))
      Xmax, Ymax, Zmax = (np.max(np.abs(Xi)) for Xi in (X, Y, Z))
      X *= 100.0 / Xmax
      Y *= 100.0 / Ymax
      Z *= 100.0 / Zmax
  
      X = np.around(X, 3)
      Y = np.around(Y, 3)
      Z = np.around(Z, 3)
  
      reference = ["OW", "OW", "CE", "TE", "tR"]
  
      with open(filename, 'w') as f:
          for i in range(1, n):
              line = "ATOM"  # 1-4 "ATOM"
              line += "  "  # 5-6 unused
              line += str(i).rjust(5)  # 7-11 atom serial number
              line += " "  # 12 unused
              line += reference[special_bins[i]].rjust(4)  # 13-16 atom name
              line += " "  # 17 alternate location indicator
              line += "SOL"  # 18-20 residue name
              line += " "  # 21 unused
              line += letters[int(contigs[indices[i]] - 1)
                              ]  # 22 chain identifier
              line += str(i).rjust(4)  # 23-26 residue sequence number
              line += " "  # 27 code for insertion of residues
              line += "   "  # 28-30 unused
              line += str(X[i]).rjust(8)  # 31-38 X orthogonal Å coordinate
              line += str(Y[i]).rjust(8)  # 39-46 Y orthogonal Å coordinate
              line += str(Z[i]).rjust(8)  # 47-54 Z orthogonal Å coordinate
              line += "1.00".rjust(6)  # 55-60 Occupancy
              # 61-66 Temperature factor
              line += str(annotations[i - 1]).rjust(6)
              line += "      "  # 67-72 unused
              line += "    "  # 73-76 segment identifier
              line += "O".rjust(2)  # 77-78 element symbol
              line += "\n"
              f.write(line)