Mercurial > repos > bgruening > molecule_datatypes
changeset 4:1a070566e9c6
Uploaded
author | bgruening |
---|---|
date | Sat, 11 May 2013 17:09:49 -0400 |
parents | ad5ecf08508a |
children | 1b63345907ec |
files | cml_to_inchi_converter.xml cml_to_mol2_converter.xml cml_to_sdf_converter.xml cml_to_smi_converter.xml datatypes_conf.xml inchi_to_cml_converter.xml mol2_to_cml_converter.xml mol_to_cml_converter.xml molecules.py sdf_to_cml_converter.xml sdf_to_inchi_converter.xml sdf_to_mol2_converter.xml sdf_to_smi_converter.xml smi_to_cml_converter.xml |
diffstat | 14 files changed, 359 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cml_to_inchi_converter.xml Sat May 11 17:09:49 2013 -0400 @@ -0,0 +1,16 @@ +<tool id="CONVERTER_cml_to_inchi" name="CML to InChI" version="1.0.0"> + <description></description> + <parallelism method="multi" split_inputs="input" split_mode="to_size" split_size="10000" shared_inputs="" merge_outputs="output"></parallelism> + <requirements> + <requirement type="package" version="2.3.2">openbabel</requirement> + </requirements> + <command >obabel -icml "${input}" -oinchi -O "${output}" -e 2>&1</command> + <inputs> + <param name="input" type="data" format="cml" label="Molecules in CML-format"/> + </inputs> + <outputs> + <data name="output" format="inchi"/> + </outputs> + <help> + </help> +</tool>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cml_to_mol2_converter.xml Sat May 11 17:09:49 2013 -0400 @@ -0,0 +1,16 @@ +<tool id="CONVERTER_cml_to_mol2" name="CML to mol2" version="1.0.0"> + <description></description> + <parallelism method="multi" split_inputs="input" split_mode="to_size" split_size="10000" shared_inputs="" merge_outputs="output"></parallelism> + <requirements> + <requirement type="package" version="2.3.2">openbabel</requirement> + </requirements> + <command >obabel -icml "${input}" -omol2 -O "${output}" -e 2>&1</command> + <inputs> + <param name="input" type="data" format="cml" label="Molecules in CML-format"/> + </inputs> + <outputs> + <data name="output" format="mol2"/> + </outputs> + <help> + </help> +</tool>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cml_to_sdf_converter.xml Sat May 11 17:09:49 2013 -0400 @@ -0,0 +1,16 @@ +<tool id="CONVERTER_cml_to_sdf" name="CML to SDF" version="1.0.0"> + <description></description> + <parallelism method="multi" split_inputs="input" split_mode="to_size" split_size="10000" shared_inputs="" merge_outputs="output"></parallelism> + <requirements> + <requirement type="package" version="2.3.2">openbabel</requirement> + </requirements> + <command >obabel -icml "${input}" -osdf "${output}" -e 2>&1</command> + <inputs> + <param name="input" type="data" format="cml" label="Molecules in CML-format"/> + </inputs> + <outputs> + <data name="output" format="sdf"/> + </outputs> + <help> + </help> +</tool>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cml_to_smi_converter.xml Sat May 11 17:09:49 2013 -0400 @@ -0,0 +1,42 @@ +<tool id="CONVERTER_cml_to_smiles" name="CML to SMILES" version="1.0.0"> + <description></description> + <parallelism method="multi" split_inputs="input" split_mode="to_size" split_size="10000" shared_inputs="" merge_outputs="output"></parallelism> + <requirements> + <requirement type="package" version="2.3.2">openbabel</requirement> + </requirements> + <command > + obabel -icml "${input}" + #if $can: + -ocan + #else: + -osmi + #end if + -O "${output}" -e + $remove_h + #if $iso_chi or $can or $exp_h: + -x$iso_chi$exp_h$can + #end if + #if $dative_bonds: + -b + #end if + #if int($ph) >= 0: + -p $ph + #end if + + 2>&1 + </command> + <inputs> + <param name="input" type="data" format="cml" label="Molecules in CML-format"/> + <param name="iso_chi" type="boolean" label="Do not include isotopic or chiral markings (-xi)" truevalue="i" falsevalue="" checked="false" /> + <param name="can" type="boolean" label="Output in canonical form (-xc)" truevalue="c" falsevalue="" checked="false" /> + <param name="exp_h" type="boolean" label="Output explicit hydrogens as such (-xh)" truevalue="h" falsevalue="" checked="false" /> + <param name="remove_h" type="boolean" label="Delete hydrogen atoms (-d)" truevalue="-d" falsevalue="" /> + <param name="ph" size="3" type="float" value="-1" label="Add hydrogens appropriate for pH (-p)" help="-1 means deactivated"/> + <param name="dative_bonds" type="boolean" label="Convert dative bonds (e.g. [N+]([O-])=O to N(=O)=O) (-b)" truevalue="-b" falsevalue="" /> + </inputs> + <outputs> + <data name="output" format="smi"/> + </outputs> + <help> + </help> +</tool>
--- a/datatypes_conf.xml Mon Apr 29 11:59:42 2013 -0400 +++ b/datatypes_conf.xml Sat May 11 17:09:49 2013 -0400 @@ -9,18 +9,21 @@ <converter file="mol_to_inchi_converter.xml" target_datatype="inchi"/> <converter file="mol_to_mol2_converter.xml" target_datatype="mol2"/> <converter file="mol_to_smi_converter.xml" target_datatype="smi"/> + <converter file="mol_to_cml_converter.xml" target_datatype="cml"/> </datatype> <datatype extension="mol2" type="galaxy.datatypes.molecules:MOL2" display_in_upload="False"> <converter file="mol2_to_inchi_converter.xml" target_datatype="inchi"/> <converter file="mol2_to_mol_converter.xml" target_datatype="mol"/> <converter file="mol2_to_smi_converter.xml" target_datatype="smi"/> <converter file="mol2_to_sdf_converter.xml" target_datatype="sdf"/> + <converter file="mol2_to_cml_converter.xml" target_datatype="cml"/> </datatype> <datatype extension="inchi" type="galaxy.datatypes.molecules:InChI" display_in_upload="True"> <converter file="inchi_to_mol_converter.xml" target_datatype="mol"/> <converter file="inchi_to_mol2_converter.xml" target_datatype="mol2"/> <converter file="inchi_to_smi_converter.xml" target_datatype="smi"/> <converter file="inchi_to_sdf_converter.xml" target_datatype="sdf"/> + <converter file="inchi_to_cml_converter.xml" target_datatype="cml"/> </datatype> <datatype extension="smi" type="galaxy.datatypes.molecules:SMILES" display_in_upload="True"> <converter file="smi_to_mol_converter.xml" target_datatype="mol"/> @@ -28,11 +31,19 @@ <converter file="smi_to_inchi_converter.xml" target_datatype="inchi"/> <converter file="smi_to_sdf_converter.xml" target_datatype="sdf"/> <converter file="smi_to_smi_converter.xml" target_datatype="smi"/> + <converter file="smi_to_cml_converter.xml" target_datatype="cml"/> </datatype> <datatype extension="sdf" type="galaxy.datatypes.molecules:SDF" display_in_upload="True"> <converter file="sdf_to_inchi_converter.xml" target_datatype="inchi"/> <converter file="sdf_to_smi_converter.xml" target_datatype="smi"/> <converter file="sdf_to_mol2_converter.xml" target_datatype="mol2"/> + <converter file="sdf_to_cml_converter.xml" target_datatype="cml"/> + </datatype> + <datatype extension="cml" type="galaxy.datatypes.molecules:CML" display_in_upload="True"> + <converter file="cml_to_inchi_converter.xml" target_datatype="inchi"/> + <converter file="cml_to_smi_converter.xml" target_datatype="smi"/> + <converter file="cml_to_mol2_converter.xml" target_datatype="mol2"/> + <converter file="cml_to_sdf_converter.xml" target_datatype="sdf"/> </datatype> <datatype extension="fps" type="galaxy.datatypes.molecules:FPS" mimetype="text/html" display_in_upload="True" /> <datatype extension="obfs" type="galaxy.datatypes.molecules:OBFS" mimetype="text/html" display_in_upload="False" /> @@ -45,6 +56,7 @@ <sniffer type="galaxy.datatypes.molecules:MOL2"/> <sniffer type="galaxy.datatypes.molecules:InChI"/> <sniffer type="galaxy.datatypes.molecules:FPS"/> + <sniffer type="galaxy.datatypes.molecules:CML"/> <!-- TODO: see molecules.py <sniffer type="galaxy.datatypes.molecules:SMILES"/>--> </sniffers> </datatypes>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inchi_to_cml_converter.xml Sat May 11 17:09:49 2013 -0400 @@ -0,0 +1,16 @@ +<tool id="CONVERTER_inchi_to_cml" name="InChI to CML" version="1.0.0"> + <description></description> + <parallelism method="multi" split_inputs="input" split_mode="to_size" split_size="10000" shared_inputs="" merge_outputs="output"></parallelism> + <requirements> + <requirement type="package" version="2.3.2">openbabel</requirement> + </requirements> + <command >obabel -iinchi "${input}" -ocml -O "${output}" -e 2>&1</command> + <inputs> + <param name="input" type="data" format="inchi" label="Molecules in InChI format"/> + </inputs> + <outputs> + <data name="output" format="cml"/> + </outputs> + <help> + </help> +</tool>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mol2_to_cml_converter.xml Sat May 11 17:09:49 2013 -0400 @@ -0,0 +1,16 @@ +<tool id="CONVERTER_mol2_to_cml" name="MOL2 to CML" version="1.0.0"> + <description></description> + <parallelism method="multi" split_inputs="input" split_mode="to_size" split_size="10000" shared_inputs="" merge_outputs="output"></parallelism> + <requirements> + <requirement type="package" version="2.3.2">openbabel</requirement> + </requirements> + <command >obabel -imol2 "${input}" -ocml -O "${output}" -e 2>&1</command> + <inputs> + <param name="input" type="data" format="mol2" label="Molecules in MOL2-format"/> + </inputs> + <outputs> + <data name="output" format="cml"/> + </outputs> + <help> + </help> +</tool>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mol_to_cml_converter.xml Sat May 11 17:09:49 2013 -0400 @@ -0,0 +1,15 @@ +<tool id="CONVERTER_mol_to_cml" name="MOL to CML" version="1.0.0"> + <description></description> + <requirements> + <requirement type="package" version="2.3.2">openbabel</requirement> + </requirements> + <command >obabel -imol "${input}" -ocml -O "${output}" -e 2>&1</command> + <inputs> + <param name="input" type="data" format="mol" label="Molecules in MOL-format"/> + </inputs> + <outputs> + <data name="output" format="cml"/> + </outputs> + <help> + </help> +</tool>
--- a/molecules.py Mon Apr 29 11:59:42 2013 -0400 +++ b/molecules.py Sat May 11 17:09:49 2013 -0400 @@ -6,6 +6,7 @@ from galaxy.datatypes.data import get_file_peek from galaxy.datatypes.tabular import Tabular from galaxy.datatypes.binary import Binary +from galaxy.datatypes.xml import GenericXml import subprocess import os #import pybel @@ -183,7 +184,7 @@ else: raise Exception('Unsupported split mode %s' % split_params['split_mode']) - def _read_sdf_records( filename ): + def _read_mol2_records( filename ): lines = [] start = True with open(filename) as handle: @@ -204,15 +205,15 @@ part_file.close() try: - sdf_records = _read_sdf_records( input_files[0] ) - sdf_lines_accumulated = [] - for counter, sdf_record in enumerate( sdf_records, start = 1): - sdf_lines_accumulated.extend( sdf_record ) + mol2_records = _read_mol2_records( input_files[0] ) + mol2_lines_accumulated = [] + for counter, mol2_record in enumerate( mol2_records, start = 1): + mol2_lines_accumulated.extend( mol2_record ) if counter % chunk_size == 0: - _write_part_mol2_file( sdf_lines_accumulated ) - sdf_lines_accumulated = [] - if sdf_lines_accumulated: - _write_part_mol2_file( sdf_lines_accumulated ) + _write_part_mol2_file( mol2_lines_accumulated ) + mol2_lines_accumulated = [] + if mol2_lines_accumulated: + _write_part_mol2_file( mol2_lines_accumulated ) except Exception, e: log.error('Unable to split files: %s' % str(e)) raise @@ -222,7 +223,7 @@ class FPS( GenericMolFile ): """ - chemfp fingerprint file: http://code.google.com/p/chem-fingerprints/wiki/FPS + chemfp fingerprint file: http://code.google.com/p/chem-fingerprints/wiki/FPS """ file_ext = "fps" def sniff( self, filename ): @@ -236,7 +237,7 @@ """ Set the number of lines of data in dataset. """ - dataset.metadata.number_of_molecules = count_special_lines('^#', dataset.file_name, invert = True)#self.count_data_lines(dataset) + dataset.metadata.number_of_molecules = count_special_lines('^#', dataset.file_name, invert = True) def split( cls, input_datasets, subdir_generator_function, split_params): @@ -392,10 +393,13 @@ """ Set the number of lines of data in dataset. """ - dataset.metadata.number_of_molecules = count_special_lines('\"ligand id\"', dataset.file_name, invert = True)#self.count_data_lines(dataset) + dataset.metadata.number_of_molecules = count_special_lines('\"ligand id\"', dataset.file_name, invert = True) class PHAR( GenericMolFile ): + """ + Pharmacophore database format from silicos-it. + """ file_ext = "phar" def set_peek( self, dataset, is_multi_byte=False ): if not dataset.dataset.purged: @@ -407,6 +411,10 @@ class PDB( GenericMolFile ): + """ + Protein Databank format. + http://www.wwpdb.org/documentation/format33/v3.3.html + """ file_ext = "pdb" def sniff( self, filename ): headers = get_headers( filename, sep=' ', count=300 ) @@ -560,21 +568,174 @@ ''' + +class CML( GenericXml ): + """ + Chemical Markup Language + http://cml.sourceforge.net/ + """ + file_ext = "cml" + MetadataElement( name="number_of_molecules", default=0, desc="Number of molecules", readonly=True, visible=True, optional=True, no_value=0 ) + + + def set_meta( self, dataset, **kwd ): + """ + Set the number of lines of data in dataset. + """ + dataset.metadata.number_of_molecules = count_special_lines( '^\s*<molecule', dataset.file_name ) + + def set_peek( self, dataset, is_multi_byte=False ): + if not dataset.dataset.purged: + dataset.peek = get_file_peek( dataset.file_name, is_multi_byte=is_multi_byte ) + if (dataset.metadata.number_of_molecules == 1): + dataset.blurb = "1 molecule" + else: + dataset.blurb = "%s molecules" % dataset.metadata.number_of_molecules + dataset.peek = data.get_file_peek( dataset.file_name, is_multi_byte=is_multi_byte ) + else: + dataset.peek = 'file does not exist' + dataset.blurb = 'file purged from disk' + + def sniff( self, filename ): + """ + Try to guess if the file is a CML file. + TODO: add true positive test, need to submit a CML example + + >>> fname = get_test_fname( 'interval.interval' ) + >>> CML().sniff( fname ) + False + """ + handle = open(filename) + line = handle.readline() + if line.strip() != '<?xml version="1.0"?>': + handle.close() + return False + line = handle.readline() + if line.strip().find('http://www.xml-cml.org/schema') == -1: + handle.close() + return False + handle.close() + return True + + + def split( cls, input_datasets, subdir_generator_function, split_params): + """ + Split the input files by molecule records. + """ + if split_params is None: + return None + + if len(input_datasets) > 1: + raise Exception("CML-file splitting does not support multiple files") + input_files = [ds.file_name for ds in input_datasets] + + chunk_size = None + if split_params['split_mode'] == 'number_of_parts': + raise Exception('Split mode "%s" is currently not implemented for CML-files.' % split_params['split_mode']) + elif split_params['split_mode'] == 'to_size': + chunk_size = int(split_params['split_size']) + else: + raise Exception('Unsupported split mode %s' % split_params['split_mode']) + + def _read_cml_records( filename ): + lines = [] + with open(filename) as handle: + for line in handle: + if line.lstrip().startswith('<?xml version="1.0"?>') or \ + line.lstrip().startswith('<cml xmlns="http://www.xml-cml.org/schema') or \ + line.lstrip().startswith('</cml>'): + continue + lines.append( line ) + if line.lstrip().startswith('</molecule>'): + yield lines + lines = [] + + header_lines = ['<?xml version="1.0"?>\n', '<cml xmlns="http://www.xml-cml.org/schema">\n'] + footer_line = ['</cml>\n'] + def _write_part_cml_file( accumulated_lines ): + part_dir = subdir_generator_function() + part_path = os.path.join(part_dir, os.path.basename(input_files[0])) + part_file = open(part_path, 'w') + part_file.writelines( header_lines ) + part_file.writelines( accumulated_lines ) + part_file.writelines( footer_line ) + part_file.close() + + try: + cml_records = _read_cml_records( input_files[0] ) + cml_lines_accumulated = [] + for counter, cml_record in enumerate( cml_records, start = 1): + cml_lines_accumulated.extend( cml_record ) + if counter % chunk_size == 0: + _write_part_cml_file( cml_lines_accumulated ) + cml_lines_accumulated = [] + if cml_lines_accumulated: + _write_part_cml_file( cml_lines_accumulated ) + except Exception, e: + log.error('Unable to split files: %s' % str(e)) + raise + split = classmethod(split) + + + def merge(split_files, output_file): + """ + Merging CML files. + """ + if len(split_files) == 1: + #For one file only, use base class method (move/copy) + return Text.merge(split_files, output_file) + if not split_files: + raise ValueError("Given no CML files, %r, to merge into %s" \ + % (split_files, output_file)) + with open(output_file, "w") as out: + for filename in split_files: + with open( filename ) as handle: + header = handle.readline() + if not header: + raise ValueError("CML file %s was empty" % f) + if not header.lstrip().startswith('<?xml version="1.0"?>'): + out.write(header) + raise ValueError("%s is not a valid XML file!" % f) + line = handle.readline() + header += line + if not line.lstrip().startswith('<cml xmlns="http://www.xml-cml.org/schema'): + out.write(header) + raise ValueError("%s is not a CML file!" % f) + molecule_found = False + for line in handle.readlines(): + # we found two required header lines, the next line should start with <molecule > + if line.lstrip().startswith('</cml>'): + continue + if line.lstrip().startswith('<molecule'): + molecule_found = True + if molecule_found: + out.write( line ) + out.write("</cml>\n") + merge = staticmethod(merge) + + if __name__ == '__main__': """ - TODO: We need to figure out, how to put example files under /lib/galaxy/datatypes/test/ from a toolshed, so that doctest can work properly. + TODO: We need to figure out, how to put example files under /lib/galaxy/datatypes/test/ from a toolshed, so that doctest can work properly. """ inchi = get_test_fname('drugbank_drugs.inchi') smiles = get_test_fname('drugbank_drugs.smi') sdf = get_test_fname('drugbank_drugs.sdf') fps = get_test_fname('50_chemfp_fingerprints_FPS1.fps') pdb = get_test_fname('2zbz.pdb') + cml = get_test_fname('/home/bag/Downloads/approved.cml') + print 'CML test' + print CML().sniff(cml), 'cml' + print CML().sniff(inchi) + print CML().sniff(pdb) + CML().split() + """ print 'SMILES test' print SMILES().sniff(smiles), 'smi' print SMILES().sniff(inchi) print SMILES().sniff(pdb) - + """ print 'InChI test' print InChI().sniff(smiles) print InChI().sniff(sdf)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdf_to_cml_converter.xml Sat May 11 17:09:49 2013 -0400 @@ -0,0 +1,16 @@ +<tool id="CONVERTER_sdf_to_cml" name="SDF to CML" version="1.0.0"> + <description></description> + <parallelism method="multi" split_inputs="input" split_mode="to_size" split_size="10000" shared_inputs="" merge_outputs="output"></parallelism> + <requirements> + <requirement type="package" version="2.3.2">openbabel</requirement> + </requirements> + <command >obabel -isdf "${input}" -ocml -O "${output}" -e 2>&1</command> + <inputs> + <param name="input" type="data" format="sdf" label="Molecules in SDF-format"/> + </inputs> + <outputs> + <data name="output" format="cml"/> + </outputs> + <help> + </help> +</tool>
--- a/sdf_to_inchi_converter.xml Mon Apr 29 11:59:42 2013 -0400 +++ b/sdf_to_inchi_converter.xml Sat May 11 17:09:49 2013 -0400 @@ -6,7 +6,7 @@ </requirements> <command >obabel -isdf "${input}" -oinchi -O "${output}" -e 2>&1</command> <inputs> - <param name="input" type="data" format="sdf" label="Molecules in SD-format"/> + <param name="input" type="data" format="sdf" label="Molecules in SDF-format"/> </inputs> <outputs> <data name="output" format="inchi"/>
--- a/sdf_to_mol2_converter.xml Mon Apr 29 11:59:42 2013 -0400 +++ b/sdf_to_mol2_converter.xml Sat May 11 17:09:49 2013 -0400 @@ -6,7 +6,7 @@ </requirements> <command >obabel -isdf "${input}" -omol2 -O "${output}" -e 2>&1</command> <inputs> - <param name="input" type="data" format="sdf" label="Molecules in SD-format"/> + <param name="input" type="data" format="sdf" label="Molecules in SDF-format"/> </inputs> <outputs> <data name="output" format="mol2"/>
--- a/sdf_to_smi_converter.xml Mon Apr 29 11:59:42 2013 -0400 +++ b/sdf_to_smi_converter.xml Sat May 11 17:09:49 2013 -0400 @@ -26,7 +26,7 @@ 2>&1 </command> <inputs> - <param name="input" type="data" format="sdf" label="Molecules in SD-format"/> + <param name="input" type="data" format="sdf" label="Molecules in SDF-format"/> <param name="iso_chi" type="boolean" label="Do not include isotopic or chiral markings (-xi)" truevalue="i" falsevalue="" checked="false" /> <param name="can" type="boolean" label="Output in canonical form (-xc)" truevalue="c" falsevalue="" checked="false" /> <param name="exp_h" type="boolean" label="Output explicit hydrogens as such (-xh)" truevalue="h" falsevalue="" checked="false" />
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/smi_to_cml_converter.xml Sat May 11 17:09:49 2013 -0400 @@ -0,0 +1,16 @@ +<tool id="CONVERTER_SMILES_to_cml" name="SMILES to CML" version="1.0.0"> + <description></description> + <parallelism method="multi" split_inputs="input" split_mode="to_size" split_size="10000" shared_inputs="" merge_outputs="output"></parallelism> + <requirements> + <requirement type="package" version="2.3.2">openbabel</requirement> + </requirements> + <command >obabel -ismi "${input}" -ocml -O "${output}" -e 2>&1</command> + <inputs> + <param name="input" type="data" format="smi" label="Molecules in SMILES format"/> + </inputs> + <outputs> + <data name="output" format="cml"/> + </outputs> + <help> + </help> +</tool>