Reworked taxonomy Cython API to be a subclass of OBIWrapper
This commit is contained in:
0
python/obitools3/dms/taxo/__init__.py
Normal file
0
python/obitools3/dms/taxo/__init__.py
Normal file
@ -4,12 +4,16 @@ from ..capi.obitaxonomy cimport ecotx_t, OBIDMS_taxonomy_p
|
||||
|
||||
from ..dms cimport DMS
|
||||
|
||||
from ..object cimport OBIWrapper
|
||||
|
||||
cdef class OBI_Taxonomy :
|
||||
cdef str _name
|
||||
cdef OBIDMS_taxonomy_p _pointer
|
||||
cdef OBIDMS _dms
|
||||
|
||||
cdef class OBI_Taxonomy(OBIWrapper) :
|
||||
cdef str _name # TODO keep as bytes?
|
||||
cdef DMS _dms
|
||||
|
||||
cdef inline OBIDMS_taxonomy_p pointer(self)
|
||||
|
||||
cpdef get_taxon_by_idx(self, int idx)
|
||||
cpdef write(self, str prefix)
|
||||
cpdef int add_taxon(self, str name, str rank_name, int parent_taxid, int min_taxid=*)
|
||||
cpdef close(self)
|
||||
|
@ -14,18 +14,38 @@ from ..capi.obitaxonomy cimport obi_read_taxonomy, \
|
||||
from cpython.pycapsule cimport PyCapsule_New, PyCapsule_GetPointer
|
||||
|
||||
|
||||
cdef class OBI_Taxonomy :
|
||||
cdef class OBI_Taxonomy(OBIWrapper) :
|
||||
# TODO function to import taxonomy?
|
||||
def __init__(self, OBIDMS dms, str name, bint taxdump=False) :
|
||||
|
||||
self._dms = dms
|
||||
self._name = name
|
||||
cdef inline OBIDMS_taxonomy_p pointer(self) :
|
||||
return <OBIDMS_taxonomy_p>(self._pointer)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def open(DMS dms, str name, bint taxdump=False) :
|
||||
|
||||
cdef void* pointer
|
||||
cdef OBI_Taxonomy taxo
|
||||
|
||||
if taxdump :
|
||||
self._pointer = obi_read_taxdump(tobytes(name))
|
||||
pointer = <void*>obi_read_taxdump(tobytes(name))
|
||||
else :
|
||||
self._pointer = obi_read_taxonomy(dms._pointer, tobytes(name), True) # TODO discuss
|
||||
pointer = <void*>obi_read_taxonomy(dms.pointer(), tobytes(name), True) # TODO discuss
|
||||
# TODO if not found in DMS, try to import?
|
||||
|
||||
if pointer == NULL :
|
||||
raise RuntimeError("Error : Cannot read taxonomy %s"
|
||||
% name)
|
||||
|
||||
taxo = OBIWrapper.new(OBI_Taxonomy, pointer)
|
||||
|
||||
dms.register(taxo)
|
||||
|
||||
taxo._dms = dms
|
||||
taxo._name = name
|
||||
|
||||
return taxo
|
||||
|
||||
|
||||
def __getitem__(self, object ref):
|
||||
|
||||
@ -33,7 +53,7 @@ cdef class OBI_Taxonomy :
|
||||
cdef object taxon_capsule
|
||||
|
||||
if type(ref) == int :
|
||||
taxon_p = obi_taxo_get_taxon_with_taxid(self._pointer, ref)
|
||||
taxon_p = obi_taxo_get_taxon_with_taxid(self.pointer(), ref)
|
||||
if taxon_p == NULL :
|
||||
raise Exception("Taxon not found")
|
||||
taxon_capsule = PyCapsule_New(taxon_p, NULL, NULL)
|
||||
@ -42,6 +62,22 @@ cdef class OBI_Taxonomy :
|
||||
raise Exception("Not implemented")
|
||||
|
||||
|
||||
cpdef get_taxon_by_idx(self, int idx):
|
||||
|
||||
cdef ecotx_t* taxa
|
||||
cdef ecotx_t* taxon_p
|
||||
cdef object taxon_capsule
|
||||
|
||||
taxa = self.pointer().taxa.taxon
|
||||
taxon_p = <ecotx_t*> (taxa+idx)
|
||||
taxon_capsule = PyCapsule_New(taxon_p, NULL, NULL)
|
||||
return OBI_Taxon(taxon_capsule, self)
|
||||
|
||||
|
||||
def __len__(self):
|
||||
return self.pointer().taxa.count
|
||||
|
||||
|
||||
def __iter__(self):
|
||||
|
||||
cdef ecotx_t* taxa
|
||||
@ -49,23 +85,23 @@ cdef class OBI_Taxonomy :
|
||||
cdef object taxon_capsule
|
||||
cdef int t
|
||||
|
||||
taxa = self._pointer.taxa.taxon
|
||||
taxa = self.pointer().taxa.taxon
|
||||
|
||||
# Yield each taxid
|
||||
for t in range(self._pointer.taxa.count):
|
||||
for t in range(self.pointer().taxa.count):
|
||||
taxon_p = <ecotx_t*> (taxa+t)
|
||||
taxon_capsule = PyCapsule_New(taxon_p, NULL, NULL)
|
||||
yield OBI_Taxon(taxon_capsule, self)
|
||||
|
||||
|
||||
cpdef write(self, str prefix) :
|
||||
if obi_write_taxonomy(self._dms._pointer, self._pointer, tobytes(prefix)) < 0 :
|
||||
if obi_write_taxonomy(self._dms.pointer(), self.pointer(), tobytes(prefix)) < 0 :
|
||||
raise Exception("Error writing the taxonomy to binary files")
|
||||
|
||||
|
||||
cpdef int add_taxon(self, str name, str rank_name, int parent_taxid, int min_taxid=10000000) :
|
||||
cdef int taxid
|
||||
taxid = obi_taxo_add_local_taxon(self._pointer, tobytes(name), tobytes(rank_name), parent_taxid, min_taxid)
|
||||
taxid = obi_taxo_add_local_taxon(self.pointer(), tobytes(name), tobytes(rank_name), parent_taxid, min_taxid)
|
||||
if taxid < 0 :
|
||||
raise Exception("Error adding a new taxon to the taxonomy")
|
||||
else :
|
||||
@ -73,8 +109,21 @@ cdef class OBI_Taxonomy :
|
||||
|
||||
|
||||
cpdef close(self) :
|
||||
if (obi_close_taxonomy(self._pointer) < 0) :
|
||||
raise Exception("Error closing the taxonomy")
|
||||
|
||||
cdef OBIDMS_taxonomy_p pointer = self.pointer()
|
||||
|
||||
if self.active() :
|
||||
self._dms.unregister(self)
|
||||
OBIWrapper.close(self)
|
||||
if (obi_close_taxonomy(self.pointer()) < 0) :
|
||||
raise Exception("Problem closing the taxonomy %s" %
|
||||
self._name)
|
||||
|
||||
|
||||
# name property getter
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
|
||||
cdef class OBI_Taxon : # TODO dict subclass?
|
||||
@ -86,6 +135,16 @@ cdef class OBI_Taxon : # TODO dict subclass?
|
||||
self._tax = tax
|
||||
|
||||
|
||||
# To test equality
|
||||
def __richcmp__(self, OBI_Taxon taxon2, int op):
|
||||
return (self.name == taxon2.name) and \
|
||||
(self.taxid == taxon2.taxid) and \
|
||||
(self.rank == taxon2.rank) and \
|
||||
(self.farest == taxon2.farest) and \
|
||||
(self.parent.taxid == taxon2.parent.taxid) and \
|
||||
(self.preferred_name == taxon2.preferred_name)
|
||||
|
||||
|
||||
# name property getter
|
||||
@property
|
||||
def name(self):
|
||||
@ -121,13 +180,14 @@ cdef class OBI_Taxon : # TODO dict subclass?
|
||||
|
||||
@preferred_name.setter
|
||||
def preferred_name(self, str new_preferred_name) : # @DuplicatedSignature
|
||||
if (obi_taxo_add_preferred_name_with_taxon(self._tax._pointer, self._pointer, tobytes(new_preferred_name)) < 0) :
|
||||
if (obi_taxo_add_preferred_name_with_taxon(self._tax.pointer(), self._pointer, tobytes(new_preferred_name)) < 0) :
|
||||
raise Exception("Error adding a new preferred name to a taxon")
|
||||
|
||||
def __repr__(self):
|
||||
d = {}
|
||||
d['taxid'] = self.taxid
|
||||
d['name'] = self.name
|
||||
d['rank'] = self.rank
|
||||
d['preferred name'] = self.preferred_name
|
||||
d['parent'] = self.parent.taxid
|
||||
d['farest'] = self.farest
|
||||
|
Reference in New Issue
Block a user