From 9cd57deca9dfa78be021d898ace279fa7a87911a Mon Sep 17 00:00:00 2001 From: Celine Mercier Date: Fri, 30 Sep 2016 17:48:53 +0200 Subject: [PATCH] Added OBIView_line_selection class to make new line selections associated with the view to clone, and improved and renamed method closing a view --- python/obi.py | 4 +- python/obitools3/commands/align.pyx | 9 ++--- python/obitools3/commands/export.pyx | 2 +- python/obitools3/commands/grep.pyx | 6 +-- python/obitools3/commands/import.pyx | 8 ++-- python/obitools3/commands/test.pyx | 11 +++--- python/obitools3/format/fasta.pyx | 2 - python/obitools3/obidms/_obidms.pxd | 10 ++++- python/obitools3/obidms/_obidms.pyx | 55 +++++++++++++++++++++++----- src/obiview.c | 16 ++++++++ 10 files changed, 90 insertions(+), 33 deletions(-) diff --git a/python/obi.py b/python/obi.py index f4ca596..7f92fec 100644 --- a/python/obi.py +++ b/python/obi.py @@ -21,7 +21,9 @@ default_config = { 'software' : "The OBITools", 'log' : False, 'loglevel' : 'INFO', 'progress' : True, - 'defaultdms' : None + 'defaultdms' : None, + 'inputview' : None, + 'outputview' : None } root_config_name='obi' diff --git a/python/obitools3/commands/align.pyx b/python/obitools3/commands/align.pyx index 4adb507..8e4e1d1 100644 --- a/python/obitools3/commands/align.pyx +++ b/python/obitools3/commands/align.pyx @@ -108,18 +108,15 @@ def run(config): # Call cython alignment function iview.align(oview) - print(oview.__repr__()) + repr(oview) - iview.save_and_close() - oview.save_and_close() + iview.close() + oview.close() d.close() print("Done.") - - - \ No newline at end of file diff --git a/python/obitools3/commands/export.pyx b/python/obitools3/commands/export.pyx index d64450c..79348e4 100644 --- a/python/obitools3/commands/export.pyx +++ b/python/obitools3/commands/export.pyx @@ -85,7 +85,7 @@ def run(config): print(toprint) i+=1 - iview.save_and_close() + iview.close() d.close() print("Done.") diff --git a/python/obitools3/commands/grep.pyx b/python/obitools3/commands/grep.pyx index f64fe13..e056dd1 100644 --- a/python/obitools3/commands/grep.pyx +++ b/python/obitools3/commands/grep.pyx @@ -75,10 +75,10 @@ def run(config): # Create output view with the line selection oview = d.new_view(config['obi']['outputview'], view_to_clone=iview, line_selection=selection, comments="obi grep: "+config['grep']['predicate']+"\n") - print(oview.__repr__()) + repr(oview) - iview.save_and_close() - oview.save_and_close() + iview.close() + oview.close() d.close() print("Done.") diff --git a/python/obitools3/commands/import.pyx b/python/obitools3/commands/import.pyx index 7cc753c..fb0c7cd 100644 --- a/python/obitools3/commands/import.pyx +++ b/python/obitools3/commands/import.pyx @@ -4,9 +4,9 @@ from obitools3.parsers.fasta import fastaIterator from obitools3.parsers.fastq import fastqIterator from obitools3.obidms._obidms import OBIDMS - import time + __title__="Counts sequences in a sequence set" @@ -90,7 +90,7 @@ def addOptions(parser): # TODO: Handling of NA values def run(config): - #pb = ProgressBar(35000000, config, seconde=5) + pb = ProgressBar(35000000, config, seconde=5) inputs = uopen(config['import']['filename']) @@ -113,7 +113,7 @@ def run(config): i = 0 for seq in iseq: - #pb(i) + pb(i) view[i].set_id(seq['id']) view[i].set_definition(seq['definition']) view[i].set_sequence(seq['sequence']) @@ -125,7 +125,7 @@ def run(config): print(view.__repr__()) - view.save_and_close() + view.close() d.close() print("Done.") diff --git a/python/obitools3/commands/test.pyx b/python/obitools3/commands/test.pyx index 8e81e5f..3a45289 100644 --- a/python/obitools3/commands/test.pyx +++ b/python/obitools3/commands/test.pyx @@ -1,5 +1,6 @@ from obitools3.apps.progress cimport ProgressBar # TODO I absolutely don't understand why it doesn't work without that line from obitools3.obidms._obidms import OBIDMS # TODO cimport doesn't work +from obitools3.obidms._obidms import OBIView_line_selection from obitools3.utils cimport str2bytes import shutil @@ -120,7 +121,7 @@ def test_add_col(config, infos): # else : # alias = '' # infos['view'].add_column(random_column_refs['name'], version_number=random_column_refs['version'], alias=alias, create=False) - # random_view.save_and_close() + # random_view.close() #else : create_random_column(config, infos) print_test(config, ">>> Add column test OK") @@ -215,7 +216,7 @@ def random_new_view(config, infos, first=False): quality_col = False # TODO if not first: infos['view_names'].append(infos['view'].name) - infos['view'].save_and_close() + infos['view'].close() v_to_clone = infos['dms'].open_view(random.choice(infos["view_names"])) v_type = None print_test(config, "View to clone: ") @@ -223,7 +224,7 @@ def random_new_view(config, infos, first=False): create_line_selection = random_bool(config) if create_line_selection and v_to_clone.line_count > 0: print_test(config, "New view with new line selection.") - line_selection = [] + line_selection = OBIView_line_selection(v_to_clone) for i in range(random.randint(1, v_to_clone.line_count)) : line_selection.append(random.randint(0, v_to_clone.line_count-1)) #print_test(config, "New line selection: "+str(line_selection)) @@ -241,7 +242,7 @@ def random_new_view(config, infos, first=False): assert v_to_clone.line_count == infos['view'].line_count, "New view and cloned view don't have the same line count" else : assert len(line_selection) == infos['view'].line_count, "New view with new line selection does not have the right line count" - v_to_clone.save_and_close() + v_to_clone.close() if first : fill_view(config, infos) @@ -370,7 +371,7 @@ def run(config): #print(infos) - infos['view'].save_and_close() + infos['view'].close() infos['dms'].close() shutil.rmtree(config['obi']['defaultdms']+'.obidms', ignore_errors=True) diff --git a/python/obitools3/format/fasta.pyx b/python/obitools3/format/fasta.pyx index 259e368..67005f7 100644 --- a/python/obitools3/format/fasta.pyx +++ b/python/obitools3/format/fasta.pyx @@ -1,6 +1,4 @@ cimport cython -from libc.stdlib cimport malloc, free, realloc -from libc.string cimport strncpy cdef class FastaFormat: diff --git a/python/obitools3/obidms/_obidms.pxd b/python/obitools3/obidms/_obidms.pxd index 76738cb..339d4fb 100644 --- a/python/obitools3/obidms/_obidms.pxd +++ b/python/obitools3/obidms/_obidms.pxd @@ -52,7 +52,7 @@ cdef class OBIView: ) cpdef change_column_alias(self, str current_alias, str new_alias) cpdef update_column_pointers(self) - cpdef save_and_close(self) + cpdef close(self) cdef class OBIView_NUC_SEQS(OBIView): @@ -73,6 +73,12 @@ cdef class OBIView_line : cdef OBIView _view +cdef class OBIView_line_selection(list): + + cdef OBIView _view + cdef str _view_name + + cdef class OBIDMS: cdef OBIDMS_p _pointer @@ -80,7 +86,7 @@ cdef class OBIDMS: cpdef close(self) cpdef OBI_Taxonomy open_taxonomy(self, str taxo_name) cpdef OBIView open_view(self, str view_name) - cpdef OBIView new_view(self, str view_name, object view_to_clone=*, list line_selection=*, str view_type=*, str comments=*, bint quality_column=*) + cpdef OBIView new_view(self, str view_name, object view_to_clone=*, OBIView_line_selection line_selection=*, str view_type=*, str comments=*, bint quality_column=*) cpdef dict read_view_infos(self, str view_name) # cpdef dict read_views(self) TODO diff --git a/python/obitools3/obidms/_obidms.pyx b/python/obitools3/obidms/_obidms.pyx index cabed87..d81c421 100644 --- a/python/obitools3/obidms/_obidms.pyx +++ b/python/obitools3/obidms/_obidms.pyx @@ -273,7 +273,7 @@ cdef class OBIDMS_column_line : cdef class OBIView : - def __init__(self, OBIDMS dms, str view_name, bint new=False, object view_to_clone=None, list line_selection=None, str comments="", bint quality_column=False): + def __init__(self, OBIDMS dms, str view_name, bint new=False, object view_to_clone=None, OBIView_line_selection line_selection=None, str comments="", bint quality_column=False): # TODO quality_column is only here because it's needed for OBIView_NUC_SEQS views, not clean? cdef Obiview_p view = NULL @@ -420,9 +420,11 @@ cdef class OBIView : column._pointer = obi_view_get_pointer_on_column_in_view(self._pointer, str2bytes(column_n)) - cpdef save_and_close(self) : + cpdef close(self) : if (obi_save_and_close_view(self._pointer) < 0) : raise Exception("Problem closing a view") + self._pointer = NULL + self._columns = {} def __iter__(self): @@ -483,11 +485,13 @@ cdef class OBIView : return bytes2str(self._pointer.infos.comments) # TODO setter that concatenates new comments? -############################################# + +###################################################################################################### + cdef class OBIView_NUC_SEQS(OBIView): - def __init__(self, OBIDMS dms, str view_name, bint new=False, object view_to_clone=None, list line_selection=None, str comments="", bint quality_column=False): + def __init__(self, OBIDMS dms, str view_name, bint new=False, object view_to_clone=None, OBIView_line_selection line_selection=None, str comments="", bint quality_column=False): cdef Obiview_p view = NULL cdef index_t* line_selection_p @@ -497,10 +501,20 @@ cdef class OBIView_NUC_SEQS(OBIView): cdef object subclass if line_selection is not None : - line_selection_p = malloc((len(line_selection) + 1) * sizeof(index_t)) + # Check that the line selection is associated with the view to clone + if view_to_clone is None : + raise Exception("Error creating a view: there is a new line selection but no associated view to clone") + if type(view_to_clone) == str : + if line_selection._view_name != view_to_clone : + raise Exception("Error creating a view: the new line selection isn't associated with the view to clone") + elif line_selection._view != view_to_clone : + raise Exception("Error creating a view: the new line selection isn't associated with the view to clone") + + # Build the C array corresponding to the line selection + line_selection_p = malloc((len(line_selection) + 1) * sizeof(index_t)) # +1 for the -1 flagging the end of the array for i in range(len(line_selection)) : line_selection_p[i] = line_selection[i] - line_selection_p[len(line_selection)] = -1 + line_selection_p[len(line_selection)] = -1 # flagging the end of the array else : line_selection_p = NULL @@ -602,7 +616,8 @@ cdef class OBIView_NUC_SEQS(OBIView): raise Exception("Error aligning sequences") -############################################# +###################################################################################################### + cdef class OBIView_line : @@ -656,7 +671,29 @@ cdef class OBIView_line : line[column_name] = self[column_name] return str(line) -########################################## + +###################################################################################################### + + +cdef class OBIView_line_selection(list): + + def __init__(self, OBIView view) : + if view._pointer == NULL: + raise Exception("Error: trying to create a line selection with an invalidated view") + self._view = view + self._view_name = view.name + + def append(self, index_t idx) : + if idx >= self._view.line_count : + raise Exception("Error: trying to select a line beyond the line count of a view") + # if idx in self : # TODO discuss. Discuss order too + # pass + # else : + super(OBIView_line_selection, self).append(idx) + + +###################################################################################################### + cdef class OBIDMS : @@ -704,7 +741,7 @@ cdef class OBIDMS : return view_class(self, view_name) - cpdef OBIView new_view(self, str view_name, object view_to_clone=None, list line_selection=None, str view_type=None, str comments="", bint quality_column=False) : + cpdef OBIView new_view(self, str view_name, object view_to_clone=None, OBIView_line_selection line_selection=None, str view_type=None, str comments="", bint quality_column=False) : cdef object view_class diff --git a/src/obiview.c b/src/obiview.c index bd6712d..3e3b12c 100644 --- a/src/obiview.c +++ b/src/obiview.c @@ -1132,6 +1132,22 @@ Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_cl int i; index_t line_nb; + // Check that the DMS is a valid pointer + if (dms == NULL) + { + obi_set_errno(OBIVIEW_ERROR); + obidebug(1, "\nError creating a view: DMS pointer is NULL"); + return NULL; + } + + // Check that the view name pointer is valid + if (view_name == NULL) + { + obi_set_errno(OBIVIEW_ERROR); + obidebug(1, "\nError creating a view: view name is NULL"); + return NULL; + } + // Check uniqueness of name if (view_exists(dms, view_name)) {