diff --git a/python/obitools3/commands/test.pyx b/python/obitools3/commands/test.pyx index 6a3eda0..7875694 100644 --- a/python/obitools3/commands/test.pyx +++ b/python/obitools3/commands/test.pyx @@ -65,7 +65,7 @@ def random_str_with_max_len(max_len): def random_column(infos): - return random.choice(list(infos['view'].get_columns())) + return random.choice(list(infos['view'].columns)) def random_unique_name(infos): @@ -117,7 +117,7 @@ def test_add_col(config, infos): #existing_col = random_bool(config) # TODO doesn't work because of line count problem. See obiview.c line 1737 #if existing_col and infos["view_names"] != [] : # random_view = infos['dms'].open_view(random.choice(infos["view_names"])) - # random_column = random_view[random.choice(list(random_view.get_columns()))] + # random_column = random_view[random.choice(list(random_view.columns)] # random_column_refs = random_column.refs # if random_column_refs['name'] in infos['view'] : # alias = random_unique_name(infos) @@ -132,7 +132,7 @@ def test_add_col(config, infos): def test_delete_col(config, infos): print_test(config, ">>> Delete column test") - if len(list(infos['view'].get_columns())) <= 1 : + if len(list(infos['view'].columns)) <= 1 : print_test(config, "-") return col_name = random_column(infos) @@ -218,18 +218,18 @@ def random_new_view(config, infos, first=False): clone = False quality_col = False # TODO if not first: - infos['view_names'].append(infos['view'].get_name()) + infos['view_names'].append(infos['view'].name) infos['view'].save_and_close() v_to_clone = infos['dms'].open_view(random.choice(infos["view_names"])) v_type = None print_test(config, "View to clone: ") print_test(config, repr(v_to_clone)) create_line_selection = random_bool(config) - if create_line_selection and v_to_clone.get_line_count() > 0: + if create_line_selection and v_to_clone.line_count > 0: print_test(config, "New view with new line selection.") line_selection = [] - for i in range(random.randint(1, v_to_clone.get_line_count())) : - line_selection.append(random.randint(0, v_to_clone.get_line_count()-1)) + 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)) else : v_type = random_view_type() @@ -242,9 +242,9 @@ def random_new_view(config, infos, first=False): print_test(config, repr(infos['view'])) if v_to_clone is not None : if line_selection is None: - assert v_to_clone.get_line_count() == infos['view'].get_line_count(), "New view and cloned view don't have the same line count" + 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'].get_line_count(), "New view with new line selection does not have the right line count" + 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() if first : fill_view(config, infos) diff --git a/python/obitools3/obidms/_obidms.pxd b/python/obitools3/obidms/_obidms.pxd index 37723bc..8ed7a98 100644 --- a/python/obitools3/obidms/_obidms.pxd +++ b/python/obitools3/obidms/_obidms.pxd @@ -28,16 +28,14 @@ cdef class OBIDMS_column_multi_elts(OBIDMS_column): cdef class OBIDMS_column_line: cdef OBIDMS_column column - cdef index_t index + cdef index_t index cdef class OBIView: cdef Obiview_p pointer - cdef str name - cdef str comments - cdef dict columns cdef OBIDMS dms + cdef dict columns cpdef delete_column(self, str column_name) cpdef add_column(self, @@ -57,14 +55,10 @@ 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 str get_name(self) - cpdef dict get_columns(self) - cpdef int get_line_count(self) cdef class OBIView_NUC_SEQS(OBIView): - cpdef delete_column(self, str column_name) cpdef align(self, OBIView oview, OBIView iview2=*, diff --git a/python/obitools3/obidms/_obidms.pyx b/python/obitools3/obidms/_obidms.pyx index 5c7d1a3..7105092 100644 --- a/python/obitools3/obidms/_obidms.pyx +++ b/python/obitools3/obidms/_obidms.pyx @@ -83,7 +83,7 @@ from cpython.pycapsule cimport PyCapsule_New, PyCapsule_GetPointer cdef class OBIDMS_column : - # Should only be initialized through a subclass + # Note: should only be initialized through a subclass def __init__(self, OBIView view, str column_alias): cdef OBIDMS_column_p column_p @@ -94,9 +94,9 @@ cdef class OBIDMS_column : # Fill structure self.column_alias = column_alias - self.pointer = column_pp - self.dms = view.dms - self.view = view + self.pointer = column_pp + self.dms = view.dms + self.view = view def __setitem__(self, index_t line_nb, object value): self.set_line(line_nb, value) @@ -105,20 +105,16 @@ cdef class OBIDMS_column : return self.get_line(line_nb) def __len__(self): - return (self.pointer)[0].header.lines_used + return self.lines_used def __sizeof__(self): return ((self.pointer)[0].header.header_size + (self.pointer)[0].header.data_size) def __iter__(self): - # Declarations - cdef index_t lines_used - cdef index_t line_nb - + cdef index_t line_nb # Yield each line - lines_used = (self.pointer)[0].header.lines_used - for line_nb in range(lines_used): + for line_nb in range(self.lines_used): yield self.get_line(line_nb) def __str__(self) : @@ -129,7 +125,7 @@ cdef class OBIDMS_column : return to_print def __repr__(self) : - return (self.column_alias + ", original name: " + self.original_name + ", version " + str((self.pointer)[0].header.version) + ", data type: " + self.data_type) + return (self.column_alias + ", original name: " + self.original_name + ", version " + str(self.version) + ", data type: " + self.data_type) cpdef close(self): if obi_close_column((self.pointer)[0]) < 0 : @@ -177,7 +173,6 @@ cdef class OBIDMS_column : @property def comments(self): return bytes2str((self.pointer)[0].header.comments) - # TODO setter that concatenates? # creation_date property getter @property @@ -187,11 +182,11 @@ cdef class OBIDMS_column : @staticmethod cdef object get_subclass_type(OBIDMS_column_p column_p) : - cdef object subclass + cdef object subclass cdef OBIDMS_column_header_p header - cdef OBIType_t col_type - cdef bint col_writable - cdef bint col_one_element_per_line + cdef OBIType_t col_type + cdef bint col_writable + cdef bint col_one_element_per_line header = column_p.header col_type = header.returned_data_type @@ -241,6 +236,7 @@ cdef class OBIDMS_column : ###################################################################################################### + cdef class OBIDMS_column_multi_elts(OBIDMS_column) : def __getitem__(self, index_t line_nb): @@ -250,8 +246,10 @@ cdef class OBIDMS_column_multi_elts(OBIDMS_column) : for element_name in values : self.set_item(line_nb, element_name, values[element_name]) + ###################################################################################################### + cdef class OBIDMS_column_line : def __init__(self, OBIDMS_column column, index_t line_nb) : @@ -270,22 +268,21 @@ cdef class OBIDMS_column_line : def __repr__(self) : return str(self.column.get_line(self.index)) -########################################## + +###################################################################################################### 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): - # TODO quality_column is only here because it's needed for OBIView_NUC_SEQS views, not clean + # TODO quality_column is only here because it's needed for OBIView_NUC_SEQS views, not clean? - cdef Obiview_p view = NULL - cdef int i - cdef list col_list - cdef str col_name - cdef OBIDMS_column column - cdef OBIDMS_column_p column_p - cdef OBIDMS_column_header_p header - cdef index_t* line_selection_p + 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 self.dms = dms @@ -305,46 +302,38 @@ cdef class OBIView : 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)) - elif view_to_clone is None : + else : view = obi_new_view(dms.pointer, str2bytes(view_name), NULL, line_selection_p, str2bytes(comments)) # Else, open the existing view - 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) # TODO discuss - + else : + view = obi_open_view(dms.pointer, str2bytes(view_name)) + if view == NULL : raise Exception("Error creating/opening a view") self.pointer = view - self.name = bytes2str(view.infos.name) - # Go through columns to build dictionaries of corresponding python instances + # Go through columns to build dictionaries of corresponding python instances # TODO make function? self.columns = {} for i in range(view.infos.column_count) : - column_p = (view.columns)[i] - header = (column_p).header - col_name = bytes2str(view.infos.column_references[i].alias) - subclass = OBIDMS_column.get_subclass_type(column_p) - self.columns[col_name] = subclass(self, col_name) + 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 __repr__(self) : cdef str s - s = str(self.name) + "\n" + str(self.comments) + "\n" + str(self.pointer.infos.line_count) + " lines\n" + s = str(self.name) + "\n" + str(self.comments) + "\n" + str(self.line_count) + " lines\n" for column_name in self.columns : - s = s + self.columns[column_name].__repr__() + '\n' + s = s + repr(self.columns[column_name]) + '\n' return s cpdef delete_column(self, str column_name) : - cdef str column_n - if obi_view_delete_column(self.pointer, str2bytes(column_name)) < 0 : raise Exception("Problem deleting a column from a view") - # Update the dictionary of column objects: (self.columns).pop(column_name) self.update_column_pointers() @@ -382,7 +371,7 @@ cdef class OBIView : elif nb_elements_per_line == 1 : elements_names_b = column_name_b - if type : + if type : # TODO make C function that does that if type == 'OBI_INT' : data_type = OBI_INT elif type == 'OBI_FLOAT' : @@ -400,7 +389,7 @@ cdef class OBIView : else : raise Exception("Invalid provided data type") - if (obi_view_add_column(self.pointer, column_name_b, version_number, alias_b, # TODO should return pointer on column? + if (obi_view_add_column(self.pointer, column_name_b, version_number, alias_b, data_type, nb_lines, nb_elements_per_line, elements_names_b, str2bytes(indexer_name), str2bytes(associated_column_name), associated_column_version, @@ -413,8 +402,8 @@ cdef class OBIView : # Open and store the subclass subclass = OBIDMS_column.get_subclass_type(column_p) (self.columns)[alias] = subclass(self, alias) - - + + cpdef change_column_alias(self, str current_alias, str new_alias): cdef OBIDMS_column column if (obi_view_create_column_alias(self.pointer, str2bytes(current_alias), str2bytes(new_alias)) < 0) : @@ -440,17 +429,14 @@ cdef class OBIView : def __iter__(self): - # iter on each line of all columns + # Iteration on each line of all columns # Declarations - cdef index_t lines_used cdef index_t line_nb - cdef OBIView_line line # TODO Check that this works for NUC SEQ views + cdef OBIView_line line - # Yield each line - lines_used = self.pointer.infos.line_count - - for line_nb in range(lines_used) : + # Yield each line + for line_nb in range(self.line_count) : line = self[line_nb] yield line @@ -467,29 +453,38 @@ cdef class OBIView : def __len__(self): - return(self.pointer.infos.line_count) + return(self.line_count) def __str__(self) : cdef OBIView_line line cdef str to_print to_print = "" - for line in self.__iter__() : + for line in self : to_print = to_print + str(line) + "\n" return to_print - cpdef str get_name(self): - return self.name - - - cpdef dict get_columns(self): - return self.columns - - - cpdef int get_line_count(self) : + # line_count property getter + @property + def line_count(self): return self.pointer.infos.line_count + # name property getter + @property + def name(self): + return bytes2str(self.pointer.infos.name) + + # columns property getter + @property + def columns(self): + return self.columns + + # comments property getter + @property + def comments(self): + return bytes2str(self.pointer.infos.comments) + # TODO setter that concatenates new comments? ############################################# @@ -497,14 +492,12 @@ 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): - cdef Obiview_p view = NULL - cdef int i - cdef list col_list - cdef str col_name - cdef OBIDMS_column column - cdef OBIDMS_column_p column_p - cdef OBIDMS_column_header_p header - cdef index_t* line_selection_p + 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 self.dms = dms @@ -534,17 +527,14 @@ cdef class OBIView_NUC_SEQS(OBIView): raise Exception("Error creating/opening view") self.pointer = view - self.name = bytes2str(view.infos.name) - self.comments = bytes2str(view.infos.comments) - # Go through columns to build list of corresponding python instances + # Go through columns to build dictionaries of corresponding python instances # TODO make function? self.columns = {} for i in range(view.infos.column_count) : - column_p = (view.columns)[i] - header = (column_p).header - col_name = bytes2str(view.infos.column_references[i].alias) - subclass = OBIDMS_column.get_subclass_type(column_p) - self.columns[col_name] = subclass(self, col_name) + 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 : @@ -557,7 +547,7 @@ cdef class OBIView_NUC_SEQS(OBIView): self[line_idx][key] = sequence_obj[key] - # TODO + # TODO discuss cpdef align(self, OBIView oview, OBIView iview2=None, double threshold=0.0, bint normalize=True, int reference=0, bint similarity_mode=True) :