BioPandas/biopandas

Mol2 files bonds

btyukodi opened this issue · 8 comments

PandasMol2().read_mol2() reads and parses a mol2 file, however, in the dataframe, only the @ATOM section is present. Is there any way to access the bonds?

Thanks
Botond

rasbt commented

Hi there,

in the current version of biopandas, the Mol2 BOND section is not parsed, yet. You would need to parse it from the raw text data that is attached to a PandasMol2 object pmol via pmol.mol2_text.

I think adding some parsing functionality for the BOND section would be a good thing to do!


Since the analysis of bonds is not necessarily done in each virtual screening analysis/application, I would make parsing the bonds section not the default (but optional) for computational efficiency reasons.

A general "design" question now is whether a BOND DataFrame should be stored/accessed via

a) pmol.df_bonds (where pmol.df is currently storing the atom section)

or

b) pmol.df['bonds'] (where pmol.df would then have to be renamed to pmol.df['atom'], which would make it more consistent with PandasPdb())

pmol.parse_bonds() # method to parse the bonds section
pmol.df_bonds # dataframe containing the bonds section

Feedback and comments (and PRs!) are welcome!

Hi, thanks for your answer. Just wrote a quick, dirty and probably non-optimal parser. It could serve as a temporary solution:

def bond_parser(filename):
    f = open(filename,'r')
    f_text = f.read()
    f.close()
    bond_start = f_text.find('@<TRIPOS>BOND')
    bond_end = f_text[bond_start:].replace('@<TRIPOS>BOND','').find('@')
    df_bonds = pd.DataFrame(np.array(f_text[bond_start:bond_end].replace('@<TRIPOS>BOND\n','').replace('\n',' ').split(' ')).reshape((-1,4)),
            columns=['bond_id', 'atom1', 'atom2', 'bond_type'])
    df_bonds.set_index(['bond_id'], inplace=True)
    return df_bonds

Here is a shorter version of of what @btyukodi wrote that uses regex:

dwef bond_parset(filename):
    with open(filename, 'r') as f:
        f_text = f.read()
    bonds =  np.array(re.sub(r'\s+', ' ', re.search(r'@<TRIPOS>BOND([a-z0-9\s]*)@', f_text).group(1)).split()).reshape((-1, 4))
    df_bonds = pd.DataFrame(bonds, columns=['bond_id', 'atom1', 'atom2', 'bond_type'])
    df_bonds.set_index(['bond_id'], inplace=True)
    return df_bonds
rasbt commented

Thanks a lot. I totally forgot about this / got to busy to work on this. Thanks for sharing though, I hopefully will get to it one day (or maybe someone else :))

Hey there all, was this ever implemented?

rasbt commented

No, sorry, never really found the time to do that :(

Seems like this is still an open issue?

rasbt commented

yeah, this is still an open issue