diff --git a/python/obitools3/obidms/_obidms.pxd b/python/obitools3/obidms/_obidms.pxd index 339d4fb..0fe036f 100644 --- a/python/obitools3/obidms/_obidms.pxd +++ b/python/obitools3/obidms/_obidms.pxd @@ -35,6 +35,16 @@ cdef class OBIView: cdef Obiview_p _pointer cdef dict _columns + cdef Obiview_p _open_or_create_view(self, + OBIDMS dms, + str view_name, + bint new=*, + object view_to_clone=*, + index_t* line_selection_p=*, + str comments=*, + bint quality_column=*, + str view_type=*) + cpdef delete_column(self, str column_name) cpdef add_column(self, str column_name, diff --git a/python/obitools3/obidms/_obidms.pyx b/python/obitools3/obidms/_obidms.pyx index d81c421..7b3cee3 100644 --- a/python/obitools3/obidms/_obidms.pyx +++ b/python/obitools3/obidms/_obidms.pyx @@ -273,50 +273,65 @@ cdef class OBIDMS_column_line : cdef class OBIView : - 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? + 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, str view_type=None): - cdef Obiview_p view = NULL - cdef index_t* line_selection_p + cdef index_t* line_selection_p = NULL cdef int i cdef str col_alias cdef OBIDMS_column_p column_p cdef object subclass - - # Create the C array for the line selection if needed + if line_selection is not None : - line_selection_p = malloc((len(line_selection) + 1) * sizeof(index_t)) + # Get the name of the associated view to clone + view_to_clone = line_selection._view_name # TODO discuss. This makes it possible for the view to clone to be closed. If a view to clone was given it is not checked. + # 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 - else : - line_selection_p = NULL + line_selection_p[len(line_selection)] = -1 # flagging the end of the array - # Create the view if needed + self._pointer = self._open_or_create_view(dms, view_name, new=new, view_to_clone=view_to_clone, line_selection_p=line_selection_p, comments=comments, quality_column=quality_column, view_type=None) + + # Go through columns to build dictionaries of corresponding python instances # TODO make function? + self._columns = {} + for i in range(self._pointer.infos.column_count) : + col_alias = bytes2str(self._pointer.infos.column_references[i].alias) + column_p = (self._pointer.columns)[i] + subclass = OBIDMS_column.get_subclass_type(column_p) + self._columns[col_alias] = subclass(self, col_alias) + + + cdef Obiview_p _open_or_create_view(self, OBIDMS dms, str view_name, bint new=False, object view_to_clone=None, index_t* line_selection_p=NULL, str comments="", bint quality_column=False, str view_type=None): + + cdef Obiview_p view = NULL + + # Create the view if needed, with the right type if new : - if view_to_clone is not None : - if type(view_to_clone) == str : - view = obi_new_view_cloned_from_name(dms._pointer, str2bytes(view_name), str2bytes(view_to_clone), line_selection_p, str2bytes(comments)) + if view_type is None : + if view_to_clone is not None : + if type(view_to_clone) == str : + view = obi_new_view_cloned_from_name(dms._pointer, str2bytes(view_name), str2bytes(view_to_clone), line_selection_p, str2bytes(comments)) + else : + view = obi_new_view(dms._pointer, str2bytes(view_name), ( view_to_clone)._pointer, line_selection_p, str2bytes(comments)) else : - view = obi_new_view(dms._pointer, str2bytes(view_name), ( view_to_clone)._pointer, line_selection_p, str2bytes(comments)) - else : - view = obi_new_view(dms._pointer, str2bytes(view_name), NULL, line_selection_p, str2bytes(comments)) + view = obi_new_view(dms._pointer, str2bytes(view_name), NULL, line_selection_p, str2bytes(comments)) + elif view_type == VIEW_TYPE_NUC_SEQS : + if view_to_clone is not None : + if type(view_to_clone) == str : + view = obi_new_view_nuc_seqs_cloned_from_name(dms._pointer, str2bytes(view_name), str2bytes(view_to_clone), line_selection_p, str2bytes(comments), quality_column) + else : + view = obi_new_view_nuc_seqs(dms._pointer, str2bytes(view_name), ( view_to_clone)._pointer, line_selection_p, str2bytes(comments), quality_column) + else : + view = obi_new_view_nuc_seqs(dms._pointer, str2bytes(view_name), NULL, line_selection_p, str2bytes(comments), quality_column) + # Else, open the existing view else : view = obi_open_view(dms._pointer, str2bytes(view_name)) if view == NULL : raise Exception("Error creating/opening a view") - - self._pointer = view - # Go through columns to build dictionaries of corresponding python instances # TODO make function? - self._columns = {} - for i in range(view.infos.column_count) : - col_alias = bytes2str(view.infos.column_references[i].alias) - column_p = (view.columns)[i] - subclass = OBIDMS_column.get_subclass_type(column_p) - self._columns[col_alias] = subclass(self, col_alias) + return view def __repr__(self) : @@ -491,66 +506,14 @@ cdef class OBIView : cdef class OBIView_NUC_SEQS(OBIView): - 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 - cdef int i - cdef str col_alias - cdef OBIDMS_column_p column_p - cdef object subclass - - if line_selection is not None : - # 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 # flagging the end of the array - else : - line_selection_p = NULL - - if new : - if view_to_clone is not None : - if type(view_to_clone) == str : - view = obi_new_view_nuc_seqs_cloned_from_name(dms._pointer, str2bytes(view_name), str2bytes(view_to_clone), line_selection_p, str2bytes(comments), quality_column) - else : - view = obi_new_view_nuc_seqs(dms._pointer, str2bytes(view_name), ( view_to_clone)._pointer, line_selection_p, str2bytes(comments), quality_column) - elif view_to_clone is None : - view = obi_new_view_nuc_seqs(dms._pointer, str2bytes(view_name), NULL, line_selection_p, str2bytes(comments), quality_column) - elif not new : - if view_name is not None : - view = obi_open_view(dms._pointer, str2bytes(view_name)) - elif view_name is None : - view = obi_open_view(dms._pointer, NULL) - - if view == NULL : - raise Exception("Error creating/opening view") - - self._pointer = view - - # Go through columns to build dictionaries of corresponding python instances # TODO make function? - self._columns = {} - for i in range(view.infos.column_count) : - col_alias = bytes2str(view.infos.column_references[i].alias) - column_p = (view.columns)[i] - subclass = OBIDMS_column.get_subclass_type(column_p) - self._columns[col_alias] = subclass(self, col_alias) - + def __getitem__(self, object item) : if type(item) == str : return (self._columns)[item] elif type(item) == int : return OBI_Nuc_Seq_Stored(self, item) + def __setitem__(self, index_t line_idx, OBI_Nuc_Seq sequence_obj) : for key in sequence_obj : self[line_idx][key] = sequence_obj[key] @@ -753,11 +716,12 @@ cdef class OBIDMS : view_class = OBIView # Check the type of the view to clone if there is one # TODO make generic for future other view types if view_to_clone is not None and \ - ((type(view_to_clone) == str and self.read_view_infos(view_to_clone)["view_type"] == VIEW_TYPE_NUC_SEQS) or \ + ((type(view_to_clone) == str and self.read_view_infos(view_to_clone)["view_type"] == bytes2str(VIEW_TYPE_NUC_SEQS)) or \ isinstance(view_to_clone, OBIView_NUC_SEQS)) : + view_type = bytes2str(VIEW_TYPE_NUC_SEQS) view_class = OBIView_NUC_SEQS - return view_class(self, view_name, new=True, view_to_clone=view_to_clone, line_selection=line_selection, comments=comments, quality_column=quality_column) + return view_class(self, view_name, new=True, view_to_clone=view_to_clone, line_selection=line_selection, comments=comments, quality_column=quality_column, view_type=view_type) cpdef dict read_view_infos(self, str view_name) :