def METHOD_NAME(ctab_lines):
    """
    Parse a *MDL* connection table (Ctab) to obtain an
    :class:`AtomArray`. :footcite:`Dalby1992`
    Parameters
    ----------
    ctab_lines : lines of str
        The lines containing the *ctab*.
        Must begin with the *counts* line and end with the `M END` line
    Returns
    -------
    atoms : AtomArray
        This :class:`AtomArray` contains the optional ``charge``
        annotation and has an associated :class:`BondList`.
    References
    ----------
    .. footbibliography::
    """
    n_atoms, n_bonds = _get_counts(ctab_lines[0])
    atom_lines = ctab_lines[1 : 1 + n_atoms]
    bond_lines = ctab_lines[1 + n_atoms : 1 + n_atoms + n_bonds]
    atoms = AtomArray(n_atoms)
    atoms.add_annotation("charge", int)
    for i, line in enumerate(atom_lines):
        atoms.coord[i, 0] = float(line[0:10])
        atoms.coord[i, 1] = float(line[10:20])
        atoms.coord[i, 2] = float(line[20:30])
        atoms.element[i] = line[31:34].strip().upper()
        charge = CHARGE_MAPPING.get(int(line[36:39]))
        if charge is None:
            warnings.warn(
                f"Cannot handle MDL charge type {int(line[36 : 39])}, "
                f"0 is used instead"
            )
            charge = 0
        atoms.charge[i] = charge
    bond_array = np.zeros((n_bonds, 3), dtype=np.uint32)
    for i, line in enumerate(bond_lines):
        bond_type = BOND_TYPE_MAPPING.get(int(line[6:9]))
        if bond_type is None:
            warnings.warn(
                f"Cannot handle MDL bond type {int(line[6 : 9])}, "
                f"BondType.ANY is used instead"
            )
            bond_type = BondType.ANY
        bond_array[i, 0] = int(line[0:3]) - 1
        bond_array[i, 1] = int(line[3:6]) - 1
        bond_array[i, 2] = bond_type
    atoms.bonds = BondList(n_atoms, bond_array)
    return atoms