biopandas icon indicating copy to clipboard operation
biopandas copied to clipboard

Mol2 files bonds

Open btyukodi opened this issue 5 years ago • 8 comments

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

Thanks Botond

btyukodi avatar Jul 06 '18 16:07 btyukodi

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!

rasbt avatar Jul 06 '18 19:07 rasbt

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

btyukodi avatar Jul 06 '18 21:07 btyukodi

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

wlgfour avatar Sep 10 '20 18:09 wlgfour

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 :))

rasbt avatar Sep 10 '20 22:09 rasbt

Hey there all, was this ever implemented?

mercicle avatar Dec 03 '20 00:12 mercicle

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

rasbt avatar Dec 03 '20 01:12 rasbt

Seems like this is still an open issue?

Kroppeb avatar May 14 '22 15:05 Kroppeb

yeah, this is still an open issue

rasbt avatar May 14 '22 15:05 rasbt