From 69c50ff92254468a59aa1c56d7887d12b13a2a68 Mon Sep 17 00:00:00 2001 From: Celine Mercier Date: Thu, 27 Jul 2017 19:29:10 +0200 Subject: [PATCH] Cython API: added a Column subclass to allow direct access to indexes for columns that store indexes referring to other data --- python/obitools3/dms/column/column_idx.pxd | 21 ++++ python/obitools3/dms/column/column_idx.pyx | 114 ++++++++++++++++++ .../obitools3/dms/column/typed_column/seq.pxd | 8 +- .../obitools3/dms/column/typed_column/seq.pyx | 6 +- .../obitools3/dms/column/typed_column/str.pxd | 8 +- .../obitools3/dms/column/typed_column/str.pyx | 6 +- 6 files changed, 151 insertions(+), 12 deletions(-) create mode 100644 python/obitools3/dms/column/column_idx.pxd create mode 100644 python/obitools3/dms/column/column_idx.pyx diff --git a/python/obitools3/dms/column/column_idx.pxd b/python/obitools3/dms/column/column_idx.pxd new file mode 100644 index 0000000..c07c9b7 --- /dev/null +++ b/python/obitools3/dms/column/column_idx.pxd @@ -0,0 +1,21 @@ +# #cython: language_level=3 + + +from ..capi.obitypes cimport index_t + +from .column cimport Column, \ + Column_multi_elts + + +cdef class Column_idx(Column) : + + cpdef object get_line_idx(self, index_t line_nb) + cpdef set_line_idx(self, index_t line_nb, object value) + + +cdef class Column_multi_elts_idx(Column_multi_elts) : + + cpdef object get_item_idx(self, index_t line_nb, object elt_id) + cpdef object get_line_idx(self, index_t line_nb) + cpdef set_item_idx(self, index_t line_nb, object elt_id, object value) + cpdef set_line_idx(self, index_t line_nb, object values) diff --git a/python/obitools3/dms/column/column_idx.pyx b/python/obitools3/dms/column/column_idx.pyx new file mode 100644 index 0000000..b59cac9 --- /dev/null +++ b/python/obitools3/dms/column/column_idx.pyx @@ -0,0 +1,114 @@ +#cython: language_level=3 + +from obitools3.dms.capi.obierrno cimport obi_errno + +from ..view.view cimport View + +from obitools3.utils cimport tobytes, \ + obi_errno_to_exception + +from ..capi.obiview cimport obi_get_index_with_elt_name_and_col_p_in_view, \ + obi_get_index_with_elt_idx_and_col_p_in_view, \ + obi_set_index_with_elt_name_and_col_p_in_view, \ + obi_set_index_with_elt_idx_and_col_p_in_view, \ + Obiview_p + +from ..capi.obidmscolumn cimport OBIDMS_column_p + +from ..capi.obitypes cimport OBI_IDX, OBIIdx_NA, index_t + +from cpython.long cimport PyLong_FromLongLong + + +# TODO overwrite other functions from Column and Column_multi_elts + + +cdef class Column_idx(Column): + + cpdef object get_line_idx(self, index_t line_nb): + global obi_errno + cdef index_t value + cdef object result + value = obi_get_index_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0) + obi_errno_to_exception(obi_errno, line_nb=line_nb, elt_id=None, error_message="Problem getting a value from a column") + if value == OBIIdx_NA : + result = None + else : + result = PyLong_FromLongLong(value) + return result + + cpdef set_line_idx(self, index_t line_nb, object value): + global obi_errno + if value is None : + value = OBIIdx_NA + if obi_set_index_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0, value) < 0: + obi_errno_to_exception(obi_errno, line_nb=line_nb, elt_id=None, error_message="Problem setting a value in a column") + + +cdef class Column_multi_elts_idx(Column_multi_elts): + + cpdef object get_item_idx(self, index_t line_nb, object elt_id) : + global obi_errno + cdef int value + cdef object result + cdef bytes elt_name + if type(elt_id) == int : + value = obi_get_index_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_id) + else : + elt_name = tobytes(elt_id) + value = obi_get_index_with_elt_name_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_name) + obi_errno_to_exception(obi_errno, line_nb=line_nb, elt_id=elt_id, error_message="Problem getting a value from a column") + if value == OBIIdx_NA : + result = None + else : + result = PyLong_FromLongLong(value) + return result + + cpdef object get_line_idx(self, index_t line_nb) : + global obi_errno + cdef index_t value + cdef int value_in_result + cdef dict result + cdef index_t i + cdef bint all_NA + cdef list elements_names + cdef Obiview_p view_p + cdef OBIDMS_column_p column_p + result = {} + all_NA = True + view_p = self._view.pointer() + column_p = self.pointer() + elements_names = self.elements_names + for i in range(self.nb_elements_per_line) : + value = obi_get_index_with_elt_idx_and_col_p_in_view(view_p, column_p, line_nb, i) + obi_errno_to_exception(obi_errno, line_nb=line_nb, elt_id=i, error_message="Problem getting a value from a column") + if value != OBIIdx_NA : + value_in_result = PyLong_FromLongLong(value) + result[elements_names[i]] = value_in_result + if all_NA : + all_NA = False + if all_NA : + result = None + return result + + cpdef set_item_idx(self, index_t line_nb, object elt_id, object value) : + global obi_errno + cdef bytes elt_name + if value is None : + value = OBIIdx_NA + if type(elt_id) == int : + if obi_set_index_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_id, value) < 0 : + obi_errno_to_exception(obi_errno, line_nb=line_nb, elt_id=elt_id, error_message="Problem setting a value in a column") + else : + elt_name = tobytes(elt_id) + if obi_set_index_with_elt_name_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_name, value) < 0 : + obi_errno_to_exception(obi_errno, line_nb=line_nb, elt_id=elt_id, error_message="Problem setting a value in a column") + + cpdef set_line_idx(self, index_t line_nb, object values): + if values is None : + for element_name in self.elements_names : + self.set_item_idx(line_nb, element_name, None) + else : + for element_name in values : + self.set_item_idx(line_nb, element_name, values[element_name]) + diff --git a/python/obitools3/dms/column/typed_column/seq.pxd b/python/obitools3/dms/column/typed_column/seq.pxd index 5a195bb..854fd1b 100644 --- a/python/obitools3/dms/column/typed_column/seq.pxd +++ b/python/obitools3/dms/column/typed_column/seq.pxd @@ -3,17 +3,17 @@ from ...capi.obitypes cimport index_t -from ..column cimport Column, \ - Column_multi_elts +from ..column_idx cimport Column_idx, \ + Column_multi_elts_idx -cdef class Column_seq(Column) : +cdef class Column_seq(Column_idx) : cpdef object get_line(self, index_t line_nb) cpdef set_line(self, index_t line_nb, object value) -cdef class Column_multi_elts_seq(Column_multi_elts) : +cdef class Column_multi_elts_seq(Column_multi_elts_idx) : cpdef object get_item(self, index_t line_nb, object elt_id) cpdef object get_line(self, index_t line_nb) diff --git a/python/obitools3/dms/column/typed_column/seq.pyx b/python/obitools3/dms/column/typed_column/seq.pyx index eb5dceb..1929469 100644 --- a/python/obitools3/dms/column/typed_column/seq.pyx +++ b/python/obitools3/dms/column/typed_column/seq.pyx @@ -6,6 +6,8 @@ from ..column cimport register_column_class from ...view.view cimport View +from ..column cimport Column + from obitools3.utils cimport tobytes, \ obi_errno_to_exception @@ -22,7 +24,7 @@ from ...capi.obitypes cimport OBI_SEQ, OBISeq_NA from libc.stdlib cimport free -cdef class Column_seq(Column): +cdef class Column_seq(Column_idx): @staticmethod def new(View view, @@ -68,7 +70,7 @@ cdef class Column_seq(Column): obi_errno_to_exception(obi_errno, line_nb=line_nb, elt_id=None, error_message="Problem setting a value in a column") -cdef class Column_multi_elts_seq(Column_multi_elts): +cdef class Column_multi_elts_seq(Column_multi_elts_idx): cpdef object get_item(self, index_t line_nb, object elt_id) : global obi_errno diff --git a/python/obitools3/dms/column/typed_column/str.pxd b/python/obitools3/dms/column/typed_column/str.pxd index 5bb8ddc..d35ebda 100644 --- a/python/obitools3/dms/column/typed_column/str.pxd +++ b/python/obitools3/dms/column/typed_column/str.pxd @@ -3,17 +3,17 @@ from ...capi.obitypes cimport index_t -from ..column cimport Column, \ - Column_multi_elts +from ..column_idx cimport Column_idx, \ + Column_multi_elts_idx -cdef class Column_str(Column) : +cdef class Column_str(Column_idx) : cpdef object get_line(self, index_t line_nb) cpdef set_line(self, index_t line_nb, object value) -cdef class Column_multi_elts_str(Column_multi_elts) : +cdef class Column_multi_elts_str(Column_multi_elts_idx) : cpdef object get_item(self, index_t line_nb, object elt_id) cpdef object get_line(self, index_t line_nb) diff --git a/python/obitools3/dms/column/typed_column/str.pyx b/python/obitools3/dms/column/typed_column/str.pyx index 5b0262f..f0c78f8 100644 --- a/python/obitools3/dms/column/typed_column/str.pyx +++ b/python/obitools3/dms/column/typed_column/str.pyx @@ -6,6 +6,8 @@ from ..column cimport register_column_class from ...view.view cimport View +from ..column cimport Column + from obitools3.utils cimport tobytes, \ obi_errno_to_exception @@ -20,7 +22,7 @@ from ...capi.obidmscolumn cimport OBIDMS_column_p from ...capi.obitypes cimport OBI_STR, OBIStr_NA, const_char_p -cdef class Column_str(Column): +cdef class Column_str(Column_idx): @staticmethod def new(View view, @@ -63,7 +65,7 @@ cdef class Column_str(Column): obi_errno_to_exception(obi_errno, line_nb=line_nb, elt_id=None, error_message="Problem setting a value in a column") -cdef class Column_multi_elts_str(Column_multi_elts): +cdef class Column_multi_elts_str(Column_multi_elts_idx): cpdef object get_item(self, index_t line_nb, object elt_id) : global obi_errno