Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
8ba7acdfe1 | |||
38051b1e4f | |||
52a2e21b38 | |||
d27a5b9115 | |||
20bd3350b4 | |||
2e191372d7 | |||
112e12cab0 | |||
b9b4cec5b5 | |||
199f3772e8 | |||
422a6450fa | |||
137c109f86 | |||
b6648ae81e | |||
f6dffbecfe | |||
c4696ac865 | |||
11a0945a9b | |||
f23c40c905 |
@ -39,6 +39,12 @@ def __addImportInputOption(optionManager):
|
|||||||
const=b'fastq',
|
const=b'fastq',
|
||||||
help="Input file is in fastq format")
|
help="Input file is in fastq format")
|
||||||
|
|
||||||
|
group.add_argument('--silva-input',
|
||||||
|
action="store_const", dest="obi:inputformat",
|
||||||
|
default=None,
|
||||||
|
const=b'silva',
|
||||||
|
help="Input file is in SILVA fasta format")
|
||||||
|
|
||||||
group.add_argument('--embl-input',
|
group.add_argument('--embl-input',
|
||||||
action="store_const", dest="obi:inputformat",
|
action="store_const", dest="obi:inputformat",
|
||||||
default=None,
|
default=None,
|
||||||
|
230
python/obitools3/commands/addtaxids.pyx
Executable file
230
python/obitools3/commands/addtaxids.pyx
Executable file
@ -0,0 +1,230 @@
|
|||||||
|
#cython: language_level=3
|
||||||
|
|
||||||
|
from obitools3.apps.progress cimport ProgressBar # @UnresolvedImport
|
||||||
|
from obitools3.dms import DMS
|
||||||
|
from obitools3.dms.view.view cimport View, Line_selection
|
||||||
|
from obitools3.uri.decode import open_uri
|
||||||
|
from obitools3.apps.optiongroups import addMinimalInputOption, addTaxonomyOption, addMinimalOutputOption, addNoProgressBarOption
|
||||||
|
from obitools3.dms.view import RollbackException
|
||||||
|
from obitools3.dms.column.column cimport Column
|
||||||
|
from functools import reduce
|
||||||
|
from obitools3.apps.config import logger
|
||||||
|
from obitools3.utils cimport tobytes, str2bytes, tostr
|
||||||
|
from io import BufferedWriter
|
||||||
|
from obitools3.dms.capi.obiview cimport NUC_SEQUENCE_COLUMN, \
|
||||||
|
ID_COLUMN, \
|
||||||
|
DEFINITION_COLUMN, \
|
||||||
|
QUALITY_COLUMN, \
|
||||||
|
COUNT_COLUMN, \
|
||||||
|
TAXID_COLUMN
|
||||||
|
from obitools3.dms.capi.obitypes cimport OBI_INT
|
||||||
|
from obitools3.dms.capi.obitaxonomy cimport MIN_LOCAL_TAXID
|
||||||
|
import time
|
||||||
|
import math
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from cpython.exc cimport PyErr_CheckSignals
|
||||||
|
|
||||||
|
|
||||||
|
__title__="Annotate sequences with their corresponding NCBI taxid found from the taxon scientific name."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def addOptions(parser):
|
||||||
|
|
||||||
|
addMinimalInputOption(parser)
|
||||||
|
addTaxonomyOption(parser)
|
||||||
|
addMinimalOutputOption(parser)
|
||||||
|
addNoProgressBarOption(parser)
|
||||||
|
|
||||||
|
group=parser.add_argument_group('obi addtaxids specific options')
|
||||||
|
|
||||||
|
group.add_argument('-t', '--taxid-tag',
|
||||||
|
action="store",
|
||||||
|
dest="addtaxids:taxid_tag",
|
||||||
|
metavar="<TAXID_TAG>",
|
||||||
|
default=b"TAXID",
|
||||||
|
help="Name of the tag to store the found taxid "
|
||||||
|
"(default: 'TAXID'.")
|
||||||
|
|
||||||
|
group.add_argument('-n', '--taxon-name-tag',
|
||||||
|
action="store",
|
||||||
|
dest="addtaxids:taxon_name_tag",
|
||||||
|
metavar="<SCIENTIFIC_NAME_TAG>",
|
||||||
|
default=b"SCIENTIFIC_NAME",
|
||||||
|
help="Name of the tag giving the scientific name of the taxon "
|
||||||
|
"(default: 'SCIENTIFIC_NAME'.")
|
||||||
|
|
||||||
|
group.add_argument('-g', '--try-genus-match',
|
||||||
|
action="store_true", dest="addtaxids:try_genus_match",
|
||||||
|
default=False,
|
||||||
|
help="Try matching the first word of <SCIENTIFIC_NAME_TAG> when can't find corresponding taxid for a taxon. "
|
||||||
|
"If there is a match it is added in the 'parent_taxid' tag. (Can be used by 'obi taxonomy' to add the taxon under that taxid).")
|
||||||
|
|
||||||
|
group.add_argument('-a', '--restricting-ancestor',
|
||||||
|
action="store",
|
||||||
|
dest="addtaxids:restricting_ancestor",
|
||||||
|
metavar="<RESTRICTING_ANCESTOR>",
|
||||||
|
default=None,
|
||||||
|
help="Enables to restrict the search of taxids under an ancestor specified by its taxid.")
|
||||||
|
|
||||||
|
group.add_argument('-l', '--log-file',
|
||||||
|
action="store",
|
||||||
|
dest="addtaxids:log_file",
|
||||||
|
metavar="<LOG_FILE>",
|
||||||
|
default='',
|
||||||
|
help="Path to a log file to write informations about not found taxids.")
|
||||||
|
|
||||||
|
|
||||||
|
def run(config):
|
||||||
|
|
||||||
|
DMS.obi_atexit()
|
||||||
|
|
||||||
|
logger("info", "obi addtaxids")
|
||||||
|
|
||||||
|
# Open the input
|
||||||
|
input = open_uri(config['obi']['inputURI'])
|
||||||
|
if input is None:
|
||||||
|
raise Exception("Could not read input view")
|
||||||
|
i_dms = input[0]
|
||||||
|
i_view = input[1]
|
||||||
|
i_view_name = input[1].name
|
||||||
|
|
||||||
|
# Open the output: only the DMS, as the output view is going to be created by cloning the input view
|
||||||
|
# (could eventually be done via an open_uri() argument)
|
||||||
|
output = open_uri(config['obi']['outputURI'],
|
||||||
|
input=False,
|
||||||
|
dms_only=True)
|
||||||
|
if output is None:
|
||||||
|
raise Exception("Could not create output view")
|
||||||
|
o_dms = output[0]
|
||||||
|
output_0 = output[0]
|
||||||
|
o_view_name = output[1]
|
||||||
|
|
||||||
|
# stdout output: create temporary view
|
||||||
|
if type(output_0)==BufferedWriter:
|
||||||
|
o_dms = i_dms
|
||||||
|
i=0
|
||||||
|
o_view_name = b"temp"
|
||||||
|
while o_view_name in i_dms: # Making sure view name is unique in output DMS
|
||||||
|
o_view_name = o_view_name+b"_"+str2bytes(str(i))
|
||||||
|
i+=1
|
||||||
|
imported_view_name = o_view_name
|
||||||
|
|
||||||
|
# If the input and output DMS are not the same, import the input view in the output DMS before cloning it to modify it
|
||||||
|
# (could be the other way around: clone and modify in the input DMS then import the new view in the output DMS)
|
||||||
|
if i_dms != o_dms:
|
||||||
|
imported_view_name = i_view_name
|
||||||
|
i=0
|
||||||
|
while imported_view_name in o_dms: # Making sure view name is unique in output DMS
|
||||||
|
imported_view_name = i_view_name+b"_"+str2bytes(str(i))
|
||||||
|
i+=1
|
||||||
|
View.import_view(i_dms.full_path[:-7], o_dms.full_path[:-7], i_view_name, imported_view_name)
|
||||||
|
i_view = o_dms[imported_view_name]
|
||||||
|
|
||||||
|
# Clone output view from input view
|
||||||
|
o_view = i_view.clone(o_view_name)
|
||||||
|
if o_view is None:
|
||||||
|
raise Exception("Couldn't create output view")
|
||||||
|
i_view.close()
|
||||||
|
|
||||||
|
# Open taxonomy
|
||||||
|
taxo_uri = open_uri(config['obi']['taxoURI'])
|
||||||
|
if taxo_uri is None or taxo_uri[2] == bytes:
|
||||||
|
raise Exception("Couldn't open taxonomy")
|
||||||
|
taxo = taxo_uri[1]
|
||||||
|
|
||||||
|
# Initialize the progress bar
|
||||||
|
if config['obi']['noprogressbar'] == False:
|
||||||
|
pb = ProgressBar(len(o_view), config)
|
||||||
|
else:
|
||||||
|
pb = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
if config['addtaxids']['log_file']:
|
||||||
|
logfile = open(config['addtaxids']['log_file'], 'w')
|
||||||
|
else:
|
||||||
|
logfile = None
|
||||||
|
if config['addtaxids']['try_genus_match']:
|
||||||
|
try_genus = True
|
||||||
|
else:
|
||||||
|
try_genus = False
|
||||||
|
if 'restricting_ancestor' in config['addtaxids']:
|
||||||
|
res_anc = int(config['addtaxids']['restricting_ancestor'])
|
||||||
|
else:
|
||||||
|
res_anc = None
|
||||||
|
taxid_column_name = config['addtaxids']['taxid_tag']
|
||||||
|
parent_taxid_column_name = "PARENT_TAXID" # TODO macro
|
||||||
|
taxon_name_column_name = config['addtaxids']['taxon_name_tag']
|
||||||
|
taxid_column = Column.new_column(o_view, taxid_column_name, OBI_INT)
|
||||||
|
parent_taxid_column = Column.new_column(o_view, parent_taxid_column_name, OBI_INT)
|
||||||
|
taxon_name_column = o_view[taxon_name_column_name]
|
||||||
|
|
||||||
|
found_count = 0
|
||||||
|
not_found_count = 0
|
||||||
|
parent_found_count = 0
|
||||||
|
|
||||||
|
for i in range(len(o_view)):
|
||||||
|
PyErr_CheckSignals()
|
||||||
|
if pb is not None:
|
||||||
|
pb(i)
|
||||||
|
taxon_name = taxon_name_column[i]
|
||||||
|
taxon = taxo.get_taxon_by_name(taxon_name, res_anc)
|
||||||
|
if taxon is not None:
|
||||||
|
taxid_column[i] = taxon.taxid
|
||||||
|
found_count+=1
|
||||||
|
elif try_genus: # try finding genus or other parent taxon from the first word
|
||||||
|
taxon_name_sp = taxon_name.split(b" ")
|
||||||
|
taxon = taxo.get_taxon_by_name(taxon_name_sp[0], res_anc)
|
||||||
|
if taxon is not None:
|
||||||
|
parent_taxid_column[i] = taxon.taxid
|
||||||
|
parent_found_count+=1
|
||||||
|
if logfile:
|
||||||
|
print("Found parent taxon for", tostr(taxon_name), file=logfile)
|
||||||
|
else:
|
||||||
|
not_found_count+=1
|
||||||
|
if logfile:
|
||||||
|
print("No taxid found for", tostr(taxon_name), file=logfile)
|
||||||
|
else:
|
||||||
|
not_found_count+=1
|
||||||
|
if logfile:
|
||||||
|
print("No taxid found for", tostr(taxon_name), file=logfile)
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
raise RollbackException("obi addtaxids error, rollbacking view: "+str(e), o_view)
|
||||||
|
|
||||||
|
if pb is not None:
|
||||||
|
pb(i, force=True)
|
||||||
|
print("", file=sys.stderr)
|
||||||
|
|
||||||
|
logger("info", "\nTaxids found: "+str(found_count)+"/"+str(len(o_view))+" ("+str(round(found_count*100.0/len(o_view), 2))+"%)")
|
||||||
|
if config['addtaxids']['try_genus_match']:
|
||||||
|
logger("info", "\nParent taxids found: "+str(parent_found_count)+"/"+str(len(o_view))+" ("+str(round(parent_found_count*100.0/len(o_view), 2))+"%)")
|
||||||
|
logger("info", "\nTaxids not found: "+str(not_found_count)+"/"+str(len(o_view))+" ("+str(round(not_found_count*100.0/len(o_view), 2))+"%)")
|
||||||
|
|
||||||
|
# Save command config in View and DMS comments
|
||||||
|
command_line = " ".join(sys.argv[1:])
|
||||||
|
input_dms_name=[input[0].name]
|
||||||
|
input_view_name=[i_view_name]
|
||||||
|
if 'taxoURI' in config['obi'] and config['obi']['taxoURI'] is not None:
|
||||||
|
input_dms_name.append(config['obi']['taxoURI'].split("/")[-3])
|
||||||
|
input_view_name.append("taxonomy/"+config['obi']['taxoURI'].split("/")[-1])
|
||||||
|
o_view.write_config(config, "addtaxids", command_line, input_dms_name=input_dms_name, input_view_name=input_view_name)
|
||||||
|
o_dms.record_command_line(command_line)
|
||||||
|
|
||||||
|
#print("\n\nOutput view:\n````````````", file=sys.stderr)
|
||||||
|
#print(repr(o_view), file=sys.stderr)
|
||||||
|
|
||||||
|
# stdout output: write to buffer
|
||||||
|
if type(output_0)==BufferedWriter:
|
||||||
|
logger("info", "Printing to output...")
|
||||||
|
o_view.print_to_output(output_0, noprogressbar=config['obi']['noprogressbar'])
|
||||||
|
o_view.close()
|
||||||
|
|
||||||
|
# If the input and the output DMS are different or if stdout output, delete the temporary imported view used to create the final view
|
||||||
|
if i_dms != o_dms or type(output_0)==BufferedWriter:
|
||||||
|
View.delete_view(o_dms, imported_view_name)
|
||||||
|
o_dms.close(force=True)
|
||||||
|
i_dms.close(force=True)
|
||||||
|
|
||||||
|
logger("info", "Done.")
|
@ -4,7 +4,7 @@ from obitools3.apps.progress cimport ProgressBar # @UnresolvedImport
|
|||||||
from obitools3.dms import DMS
|
from obitools3.dms import DMS
|
||||||
from obitools3.dms.view.view cimport View
|
from obitools3.dms.view.view cimport View
|
||||||
from obitools3.uri.decode import open_uri
|
from obitools3.uri.decode import open_uri
|
||||||
from obitools3.apps.optiongroups import addMinimalOutputOption
|
from obitools3.apps.optiongroups import addMinimalOutputOption, addNoProgressBarOption
|
||||||
from obitools3.dms.view import RollbackException
|
from obitools3.dms.view import RollbackException
|
||||||
from obitools3.apps.config import logger
|
from obitools3.apps.config import logger
|
||||||
from obitools3.utils cimport str2bytes
|
from obitools3.utils cimport str2bytes
|
||||||
@ -28,6 +28,7 @@ __title__="Concatenate views."
|
|||||||
def addOptions(parser):
|
def addOptions(parser):
|
||||||
|
|
||||||
addMinimalOutputOption(parser)
|
addMinimalOutputOption(parser)
|
||||||
|
addNoProgressBarOption(parser)
|
||||||
|
|
||||||
group=parser.add_argument_group('obi cat specific options')
|
group=parser.add_argument_group('obi cat specific options')
|
||||||
|
|
||||||
@ -47,9 +48,9 @@ def run(config):
|
|||||||
|
|
||||||
logger("info", "obi cat")
|
logger("info", "obi cat")
|
||||||
|
|
||||||
# Open the views to concatenate
|
# Check the views to concatenate
|
||||||
iview_list = []
|
|
||||||
idms_list = []
|
idms_list = []
|
||||||
|
iview_list = []
|
||||||
total_len = 0
|
total_len = 0
|
||||||
remove_qual = False
|
remove_qual = False
|
||||||
remove_rev_qual = False
|
remove_rev_qual = False
|
||||||
@ -67,8 +68,9 @@ def run(config):
|
|||||||
if REVERSE_QUALITY_COLUMN not in i_view: # same as above for reverse quality
|
if REVERSE_QUALITY_COLUMN not in i_view: # same as above for reverse quality
|
||||||
remove_rev_qual = True
|
remove_rev_qual = True
|
||||||
total_len += len(i_view)
|
total_len += len(i_view)
|
||||||
iview_list.append(i_view)
|
|
||||||
idms_list.append(i_dms)
|
idms_list.append(i_dms)
|
||||||
|
iview_list.append(i_view.name)
|
||||||
|
i_view.close()
|
||||||
|
|
||||||
# Open the output: only the DMS
|
# Open the output: only the DMS
|
||||||
output = open_uri(config['obi']['outputURI'],
|
output = open_uri(config['obi']['outputURI'],
|
||||||
@ -97,8 +99,10 @@ def run(config):
|
|||||||
# Initialize multiple elements columns
|
# Initialize multiple elements columns
|
||||||
if type(output_0)==BufferedWriter:
|
if type(output_0)==BufferedWriter:
|
||||||
dict_cols = {}
|
dict_cols = {}
|
||||||
for v in iview_list:
|
for v_uri in config["cat"]["views_to_cat"]:
|
||||||
|
v = open_uri(v_uri)[1]
|
||||||
for coln in v.keys():
|
for coln in v.keys():
|
||||||
|
col = v[coln]
|
||||||
if v[coln].nb_elements_per_line > 1:
|
if v[coln].nb_elements_per_line > 1:
|
||||||
if coln not in dict_cols:
|
if coln not in dict_cols:
|
||||||
dict_cols[coln] = {}
|
dict_cols[coln] = {}
|
||||||
@ -108,6 +112,7 @@ def run(config):
|
|||||||
else:
|
else:
|
||||||
dict_cols[coln]['eltnames'] = set(v[coln].elements_names + list(dict_cols[coln]['eltnames']))
|
dict_cols[coln]['eltnames'] = set(v[coln].elements_names + list(dict_cols[coln]['eltnames']))
|
||||||
dict_cols[coln]['nbelts'] = len(dict_cols[coln]['eltnames'])
|
dict_cols[coln]['nbelts'] = len(dict_cols[coln]['eltnames'])
|
||||||
|
v.close()
|
||||||
for coln in dict_cols:
|
for coln in dict_cols:
|
||||||
Column.new_column(o_view, coln, dict_cols[coln]['obitype'],
|
Column.new_column(o_view, coln, dict_cols[coln]['obitype'],
|
||||||
nb_elements_per_line=dict_cols[coln]['nbelts'], elements_names=list(dict_cols[coln]['eltnames']))
|
nb_elements_per_line=dict_cols[coln]['nbelts'], elements_names=list(dict_cols[coln]['eltnames']))
|
||||||
@ -119,7 +124,8 @@ def run(config):
|
|||||||
pb = None
|
pb = None
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
for v in iview_list:
|
for v_uri in config["cat"]["views_to_cat"]:
|
||||||
|
v = open_uri(v_uri)[1]
|
||||||
for entry in v:
|
for entry in v:
|
||||||
PyErr_CheckSignals()
|
PyErr_CheckSignals()
|
||||||
if pb is not None:
|
if pb is not None:
|
||||||
@ -130,6 +136,7 @@ def run(config):
|
|||||||
else:
|
else:
|
||||||
o_view[i] = entry
|
o_view[i] = entry
|
||||||
i+=1
|
i+=1
|
||||||
|
v.close()
|
||||||
|
|
||||||
# Deletes quality columns if needed
|
# Deletes quality columns if needed
|
||||||
if type(output_0)!=BufferedWriter:
|
if type(output_0)!=BufferedWriter:
|
||||||
@ -144,7 +151,7 @@ def run(config):
|
|||||||
|
|
||||||
# Save command config in DMS comments
|
# Save command config in DMS comments
|
||||||
command_line = " ".join(sys.argv[1:])
|
command_line = " ".join(sys.argv[1:])
|
||||||
o_view.write_config(config, "cat", command_line, input_dms_name=[d.name for d in idms_list], input_view_name=[v.name for v in iview_list])
|
o_view.write_config(config, "cat", command_line, input_dms_name=[d.name for d in idms_list], input_view_name=[vname for vname in iview_list])
|
||||||
o_dms.record_command_line(command_line)
|
o_dms.record_command_line(command_line)
|
||||||
|
|
||||||
#print("\n\nOutput view:\n````````````", file=sys.stderr)
|
#print("\n\nOutput view:\n````````````", file=sys.stderr)
|
||||||
|
@ -41,6 +41,17 @@ def addOptions(parser):
|
|||||||
help="Minimum identity to consider for assignment, as a normalized identity, e.g. 0.95 for an identity of 95%%. "
|
help="Minimum identity to consider for assignment, as a normalized identity, e.g. 0.95 for an identity of 95%%. "
|
||||||
"Default: 0.00 (no threshold).")
|
"Default: 0.00 (no threshold).")
|
||||||
|
|
||||||
|
group.add_argument('--minimum-circle','-c',
|
||||||
|
action="store", dest="ecotag:bubble_threshold",
|
||||||
|
metavar='<CIRCLE_THRESHOLD>',
|
||||||
|
default=0.99,
|
||||||
|
type=float,
|
||||||
|
help="Minimum identity considered for the assignment circle "
|
||||||
|
"(sequence is assigned to the LCA of all sequences within a similarity circle of the best matches; "
|
||||||
|
"the threshold for this circle is the highest value between <CIRCLE_THRESHOLD> and the best assignment score found for the query sequence). "
|
||||||
|
"Give value as a normalized identity, e.g. 0.95 for an identity of 95%%. "
|
||||||
|
"Default: 0.99.")
|
||||||
|
|
||||||
def run(config):
|
def run(config):
|
||||||
|
|
||||||
DMS.obi_atexit()
|
DMS.obi_atexit()
|
||||||
@ -66,9 +77,8 @@ def run(config):
|
|||||||
ref_view_name = ref[1]
|
ref_view_name = ref[1]
|
||||||
|
|
||||||
# Check that the threshold demanded is greater than or equal to the threshold used to build the reference database
|
# Check that the threshold demanded is greater than or equal to the threshold used to build the reference database
|
||||||
if config['ecotag']['threshold'] < eval(ref_dms[ref_view_name].comments["ref_db_threshold"]) :
|
if config['ecotag']['bubble_threshold'] < eval(ref_dms[ref_view_name].comments["ref_db_threshold"]) :
|
||||||
print("Error: The threshold demanded (%f) is lower than the threshold used to build the reference database (%f).",
|
raise Exception(f"Error: The threshold demanded ({config['ecotag']['bubble_threshold']}) is lower than the threshold used to build the reference database ({float(ref_dms[ref_view_name].comments['ref_db_threshold'])}).")
|
||||||
config['ecotag']['threshold'], ref_dms[ref_view_name].comments["ref_db_threshold"])
|
|
||||||
|
|
||||||
# Open the output: only the DMS
|
# Open the output: only the DMS
|
||||||
output = open_uri(config['obi']['outputURI'],
|
output = open_uri(config['obi']['outputURI'],
|
||||||
@ -113,8 +123,9 @@ def run(config):
|
|||||||
if obi_ecotag(i_dms.name_with_full_path, tobytes(i_view_name), \
|
if obi_ecotag(i_dms.name_with_full_path, tobytes(i_view_name), \
|
||||||
ref_dms.name_with_full_path, tobytes(ref_view_name), \
|
ref_dms.name_with_full_path, tobytes(ref_view_name), \
|
||||||
taxo_dms.name_with_full_path, tobytes(taxonomy_name), \
|
taxo_dms.name_with_full_path, tobytes(taxonomy_name), \
|
||||||
tobytes(o_view_name), comments,
|
tobytes(o_view_name), comments, \
|
||||||
config['ecotag']['threshold']) < 0:
|
config['ecotag']['threshold'], \
|
||||||
|
config['ecotag']['bubble_threshold']) < 0:
|
||||||
raise Exception("Error running ecotag")
|
raise Exception("Error running ecotag")
|
||||||
|
|
||||||
# If the input and output DMS are not the same, export result view to output DMS
|
# If the input and output DMS are not the same, export result view to output DMS
|
||||||
|
@ -184,7 +184,7 @@ def Filter_generator(options, tax_filter, i_view):
|
|||||||
invert_selection = options["invert_selection"]
|
invert_selection = options["invert_selection"]
|
||||||
id_set = None
|
id_set = None
|
||||||
if "id_list" in options:
|
if "id_list" in options:
|
||||||
id_set = set(x.strip() for x in open(options["id_list"]))
|
id_set = set(x.strip() for x in open(options["id_list"], 'rb'))
|
||||||
|
|
||||||
# Initialize the regular expression patterns
|
# Initialize the regular expression patterns
|
||||||
seq_pattern = None
|
seq_pattern = None
|
||||||
|
@ -26,13 +26,15 @@ from obitools3.dms.capi.obiview cimport VIEW_TYPE_NUC_SEQS, \
|
|||||||
QUALITY_COLUMN, \
|
QUALITY_COLUMN, \
|
||||||
COUNT_COLUMN, \
|
COUNT_COLUMN, \
|
||||||
TAXID_COLUMN, \
|
TAXID_COLUMN, \
|
||||||
MERGED_PREFIX
|
MERGED_PREFIX, \
|
||||||
|
SCIENTIFIC_NAME_COLUMN
|
||||||
|
|
||||||
from obitools3.dms.capi.obidms cimport obi_import_view
|
from obitools3.dms.capi.obidms cimport obi_import_view
|
||||||
|
|
||||||
from obitools3.dms.capi.obitypes cimport obitype_t, \
|
from obitools3.dms.capi.obitypes cimport obitype_t, \
|
||||||
OBI_VOID, \
|
OBI_VOID, \
|
||||||
OBI_QUAL
|
OBI_QUAL, \
|
||||||
|
OBI_STR
|
||||||
|
|
||||||
from obitools3.dms.capi.obierrno cimport obi_errno
|
from obitools3.dms.capi.obierrno cimport obi_errno
|
||||||
|
|
||||||
@ -94,6 +96,7 @@ def run(config):
|
|||||||
cdef obitype_t new_type
|
cdef obitype_t new_type
|
||||||
cdef bint get_quality
|
cdef bint get_quality
|
||||||
cdef bint NUC_SEQS_view
|
cdef bint NUC_SEQS_view
|
||||||
|
cdef bint silva
|
||||||
cdef int nb_elts
|
cdef int nb_elts
|
||||||
cdef object d
|
cdef object d
|
||||||
cdef View view
|
cdef View view
|
||||||
@ -104,6 +107,8 @@ def run(config):
|
|||||||
cdef Column seq_col
|
cdef Column seq_col
|
||||||
cdef Column qual_col
|
cdef Column qual_col
|
||||||
cdef Column old_column
|
cdef Column old_column
|
||||||
|
cdef Column sci_name_col
|
||||||
|
cdef bytes sci_name
|
||||||
cdef bint rewrite
|
cdef bint rewrite
|
||||||
cdef dict dcols
|
cdef dict dcols
|
||||||
cdef int skipping
|
cdef int skipping
|
||||||
@ -203,9 +208,16 @@ def run(config):
|
|||||||
id_col = view[ID_COLUMN]
|
id_col = view[ID_COLUMN]
|
||||||
def_col = view[DEFINITION_COLUMN]
|
def_col = view[DEFINITION_COLUMN]
|
||||||
seq_col = view[NUC_SEQUENCE_COLUMN]
|
seq_col = view[NUC_SEQUENCE_COLUMN]
|
||||||
|
|
||||||
|
# Prepare taxon scientific name if SILVA file
|
||||||
|
if 'inputformat' in config['obi'] and config['obi']['inputformat'] == b"silva":
|
||||||
|
silva = True
|
||||||
|
sci_name_col = Column.new_column(view, SCIENTIFIC_NAME_COLUMN, OBI_STR)
|
||||||
|
else:
|
||||||
|
silva = False
|
||||||
|
|
||||||
dcols = {}
|
dcols = {}
|
||||||
|
|
||||||
# First read through the entries to prepare columns with dictionaries as they are very time-expensive to rewrite
|
# First read through the entries to prepare columns with dictionaries as they are very time-expensive to rewrite
|
||||||
if config['import']['preread']:
|
if config['import']['preread']:
|
||||||
logger("info", "First readthrough...")
|
logger("info", "First readthrough...")
|
||||||
@ -282,7 +294,7 @@ def run(config):
|
|||||||
try:
|
try:
|
||||||
|
|
||||||
if NUC_SEQS_view:
|
if NUC_SEQS_view:
|
||||||
id_col[i] = entry.id
|
id_col[i] = entry.id
|
||||||
def_col[i] = entry.definition
|
def_col[i] = entry.definition
|
||||||
seq_col[i] = entry.seq
|
seq_col[i] = entry.seq
|
||||||
# Check if there is a sequencing quality associated by checking the first entry # TODO haven't found a more robust solution yet
|
# Check if there is a sequencing quality associated by checking the first entry # TODO haven't found a more robust solution yet
|
||||||
@ -293,6 +305,11 @@ def run(config):
|
|||||||
qual_col = view[QUALITY_COLUMN]
|
qual_col = view[QUALITY_COLUMN]
|
||||||
if get_quality:
|
if get_quality:
|
||||||
qual_col[i] = entry.quality
|
qual_col[i] = entry.quality
|
||||||
|
|
||||||
|
# Parse taxon scientific name if SILVA file
|
||||||
|
if silva:
|
||||||
|
sci_name = entry.definition.split(b";")[-1]
|
||||||
|
sci_name_col[i] = sci_name
|
||||||
|
|
||||||
for tag in entry :
|
for tag in entry :
|
||||||
|
|
||||||
|
@ -31,27 +31,11 @@ def run(config):
|
|||||||
input = open_uri(config['obi']['inputURI'])
|
input = open_uri(config['obi']['inputURI'])
|
||||||
if input is None:
|
if input is None:
|
||||||
raise Exception("Could not read input")
|
raise Exception("Could not read input")
|
||||||
if input[2] == DMS and not config['ls']['longformat']:
|
|
||||||
dms = input[0]
|
# Print representation
|
||||||
l = []
|
if config['ls']['longformat']:
|
||||||
for viewname in input[0]:
|
print(input[1].repr_longformat())
|
||||||
view = dms[viewname]
|
|
||||||
l.append(tostr(viewname) + "\t(Date created: " + str(bytes2str_object(view.comments["Date created"]))+")")
|
|
||||||
view.close()
|
|
||||||
l.sort()
|
|
||||||
for v in l:
|
|
||||||
print(v)
|
|
||||||
else:
|
else:
|
||||||
print(repr(input[1]))
|
print(repr(input[1]))
|
||||||
if input[2] == DMS:
|
|
||||||
taxolist = ["\n### Taxonomies:"]
|
|
||||||
for t in Taxonomy.list_taxos(input[0]):
|
|
||||||
taxolist.append("\t"+tostr(t))
|
|
||||||
if len(taxolist) > 1:
|
|
||||||
for t in taxolist:
|
|
||||||
print(t)
|
|
||||||
if config['ls']['longformat'] and len(input[1].comments) > 0:
|
|
||||||
print("\n### Comments:")
|
|
||||||
print(str(input[1].comments))
|
|
||||||
|
|
||||||
input[0].close(force=True)
|
input[0].close(force=True)
|
||||||
|
@ -24,10 +24,6 @@ from cpython.exc cimport PyErr_CheckSignals
|
|||||||
from io import BufferedWriter
|
from io import BufferedWriter
|
||||||
|
|
||||||
|
|
||||||
#REVERSE_SEQ_COLUMN_NAME = b"REVERSE_SEQUENCE" # used by alignpairedend tool
|
|
||||||
#REVERSE_QUALITY_COLUMN_NAME = b"REVERSE_QUALITY" # used by alignpairedend tool
|
|
||||||
|
|
||||||
|
|
||||||
__title__="Assigns sequence records to the corresponding experiment/sample based on DNA tags and primers"
|
__title__="Assigns sequence records to the corresponding experiment/sample based on DNA tags and primers"
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ cdef extern from "obidms.h" nogil:
|
|||||||
int obi_close_dms(OBIDMS_p dms, bint force)
|
int obi_close_dms(OBIDMS_p dms, bint force)
|
||||||
char* obi_dms_get_dms_path(OBIDMS_p dms)
|
char* obi_dms_get_dms_path(OBIDMS_p dms)
|
||||||
char* obi_dms_get_full_path(OBIDMS_p dms, const_char_p path_name)
|
char* obi_dms_get_full_path(OBIDMS_p dms, const_char_p path_name)
|
||||||
|
char* obi_dms_formatted_infos(OBIDMS_p dms, bint detailed)
|
||||||
void obi_close_atexit()
|
void obi_close_atexit()
|
||||||
|
|
||||||
obiversion_t obi_import_column(const char* dms_path_1, const char* dms_path_2, const char* column_name, obiversion_t version_number)
|
obiversion_t obi_import_column(const char* dms_path_1, const char* dms_path_2, const char* column_name, obiversion_t version_number)
|
||||||
|
@ -63,10 +63,11 @@ cdef extern from "obidmscolumn.h" nogil:
|
|||||||
|
|
||||||
char* obi_get_elements_names(OBIDMS_column_p column)
|
char* obi_get_elements_names(OBIDMS_column_p column)
|
||||||
|
|
||||||
char* obi_column_formatted_infos(OBIDMS_column_p column)
|
|
||||||
|
|
||||||
index_t obi_column_get_element_index_from_name(OBIDMS_column_p column, const char* element_name)
|
index_t obi_column_get_element_index_from_name(OBIDMS_column_p column, const char* element_name)
|
||||||
|
|
||||||
int obi_column_write_comments(OBIDMS_column_p column, const char* comments)
|
int obi_column_write_comments(OBIDMS_column_p column, const char* comments)
|
||||||
|
|
||||||
int obi_column_add_comment(OBIDMS_column_p column, const char* key, const char* value)
|
int obi_column_add_comment(OBIDMS_column_p column, const char* key, const char* value)
|
||||||
|
|
||||||
|
char* obi_column_formatted_infos(OBIDMS_column_p column, bint detailed)
|
||||||
|
|
@ -11,4 +11,5 @@ cdef extern from "obi_ecotag.h" nogil:
|
|||||||
const char* taxonomy_name,
|
const char* taxonomy_name,
|
||||||
const char* output_view_name,
|
const char* output_view_name,
|
||||||
const char* output_view_comments,
|
const char* output_view_comments,
|
||||||
double ecotag_threshold)
|
double ecotag_threshold,
|
||||||
|
double bubble_threshold)
|
||||||
|
@ -7,6 +7,8 @@ from libc.stdint cimport int32_t
|
|||||||
|
|
||||||
cdef extern from "obidms_taxonomy.h" nogil:
|
cdef extern from "obidms_taxonomy.h" nogil:
|
||||||
|
|
||||||
|
extern int MIN_LOCAL_TAXID
|
||||||
|
|
||||||
struct ecotxnode :
|
struct ecotxnode :
|
||||||
int32_t taxid
|
int32_t taxid
|
||||||
int32_t rank
|
int32_t rank
|
||||||
@ -18,6 +20,13 @@ cdef extern from "obidms_taxonomy.h" nogil:
|
|||||||
ctypedef ecotxnode ecotx_t
|
ctypedef ecotxnode ecotx_t
|
||||||
|
|
||||||
|
|
||||||
|
struct econame_t : # can't get this struct to be accepted by Cython ('unknown size')
|
||||||
|
char* name
|
||||||
|
char* class_name
|
||||||
|
int32_t is_scientific_name
|
||||||
|
ecotxnode* taxon
|
||||||
|
|
||||||
|
|
||||||
struct ecotxidx_t :
|
struct ecotxidx_t :
|
||||||
int32_t count
|
int32_t count
|
||||||
int32_t max_taxid
|
int32_t max_taxid
|
||||||
@ -30,9 +39,14 @@ cdef extern from "obidms_taxonomy.h" nogil:
|
|||||||
char** label
|
char** label
|
||||||
|
|
||||||
|
|
||||||
|
struct econameidx_t :
|
||||||
|
int32_t count
|
||||||
|
econame_t* names
|
||||||
|
|
||||||
|
|
||||||
struct OBIDMS_taxonomy_t :
|
struct OBIDMS_taxonomy_t :
|
||||||
ecorankidx_t* ranks
|
ecorankidx_t* ranks
|
||||||
# econameidx_t* names
|
econameidx_t* names
|
||||||
ecotxidx_t* taxa
|
ecotxidx_t* taxa
|
||||||
|
|
||||||
ctypedef OBIDMS_taxonomy_t* OBIDMS_taxonomy_p
|
ctypedef OBIDMS_taxonomy_t* OBIDMS_taxonomy_p
|
||||||
@ -51,7 +65,11 @@ cdef extern from "obidms_taxonomy.h" nogil:
|
|||||||
ecotx_t* obi_taxo_get_parent_at_rank(ecotx_t* taxon, int32_t rankidx)
|
ecotx_t* obi_taxo_get_parent_at_rank(ecotx_t* taxon, int32_t rankidx)
|
||||||
|
|
||||||
ecotx_t* obi_taxo_get_taxon_with_taxid(OBIDMS_taxonomy_p taxonomy, int32_t taxid)
|
ecotx_t* obi_taxo_get_taxon_with_taxid(OBIDMS_taxonomy_p taxonomy, int32_t taxid)
|
||||||
|
|
||||||
|
char* obi_taxo_get_name_from_name_idx(OBIDMS_taxonomy_p taxonomy, int32_t idx)
|
||||||
|
|
||||||
|
ecotx_t* obi_taxo_get_taxon_from_name_idx(OBIDMS_taxonomy_p taxonomy, int32_t idx)
|
||||||
|
|
||||||
bint obi_taxo_is_taxon_under_taxid(ecotx_t* taxon, int32_t other_taxid)
|
bint obi_taxo_is_taxon_under_taxid(ecotx_t* taxon, int32_t other_taxid)
|
||||||
|
|
||||||
ecotx_t* obi_taxo_get_species(ecotx_t* taxon, OBIDMS_taxonomy_p taxonomy)
|
ecotx_t* obi_taxo_get_species(ecotx_t* taxon, OBIDMS_taxonomy_p taxonomy)
|
||||||
@ -71,4 +89,4 @@ cdef extern from "obidms_taxonomy.h" nogil:
|
|||||||
int obi_taxo_add_preferred_name_with_taxon(OBIDMS_taxonomy_p tax, ecotx_t* taxon, const char* preferred_name)
|
int obi_taxo_add_preferred_name_with_taxon(OBIDMS_taxonomy_p tax, ecotx_t* taxon, const char* preferred_name)
|
||||||
|
|
||||||
const char* obi_taxo_rank_index_to_label(int32_t rank_idx, ecorankidx_t* ranks)
|
const char* obi_taxo_rank_index_to_label(int32_t rank_idx, ecorankidx_t* ranks)
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ cdef extern from "obiview.h" nogil:
|
|||||||
extern const_char_p REVERSE_QUALITY_COLUMN
|
extern const_char_p REVERSE_QUALITY_COLUMN
|
||||||
extern const_char_p REVERSE_SEQUENCE_COLUMN
|
extern const_char_p REVERSE_SEQUENCE_COLUMN
|
||||||
extern const_char_p COUNT_COLUMN
|
extern const_char_p COUNT_COLUMN
|
||||||
|
extern const_char_p SCIENTIFIC_NAME_COLUMN
|
||||||
extern const_char_p TAXID_COLUMN
|
extern const_char_p TAXID_COLUMN
|
||||||
extern const_char_p MERGED_TAXID_COLUMN
|
extern const_char_p MERGED_TAXID_COLUMN
|
||||||
extern const_char_p MERGED_PREFIX
|
extern const_char_p MERGED_PREFIX
|
||||||
@ -103,13 +104,17 @@ cdef extern from "obiview.h" nogil:
|
|||||||
bint create)
|
bint create)
|
||||||
|
|
||||||
int obi_view_delete_column(Obiview_p view, const_char_p column_name, bint delete_file)
|
int obi_view_delete_column(Obiview_p view, const_char_p column_name, bint delete_file)
|
||||||
|
|
||||||
OBIDMS_column_p obi_view_get_column(Obiview_p view, const_char_p column_name)
|
OBIDMS_column_p obi_view_get_column(Obiview_p view, const_char_p column_name)
|
||||||
|
|
||||||
OBIDMS_column_p* obi_view_get_pointer_on_column_in_view(Obiview_p view, const_char_p column_name)
|
OBIDMS_column_p* obi_view_get_pointer_on_column_in_view(Obiview_p view, const_char_p column_name)
|
||||||
|
|
||||||
int obi_view_create_column_alias(Obiview_p view, const_char_p current_name, const_char_p alias)
|
int obi_view_create_column_alias(Obiview_p view, const_char_p current_name, const_char_p alias)
|
||||||
|
|
||||||
|
char* obi_view_formatted_infos(Obiview_p view, bint detailed)
|
||||||
|
|
||||||
|
char* obi_view_formatted_infos_one_line(Obiview_p view)
|
||||||
|
|
||||||
int obi_view_write_comments(Obiview_p view, const_char_p comments)
|
int obi_view_write_comments(Obiview_p view, const_char_p comments)
|
||||||
|
|
||||||
int obi_view_add_comment(Obiview_p view, const_char_p key, const_char_p value)
|
int obi_view_add_comment(Obiview_p view, const_char_p key, const_char_p value)
|
||||||
|
@ -302,15 +302,24 @@ cdef class Column(OBIWrapper) :
|
|||||||
|
|
||||||
@OBIWrapper.checkIsActive
|
@OBIWrapper.checkIsActive
|
||||||
def __repr__(self) :
|
def __repr__(self) :
|
||||||
cdef bytes s
|
cdef str s
|
||||||
#cdef char* s_b
|
cdef char* sc
|
||||||
#cdef str s_str
|
cdef OBIDMS_column_p pointer = self.pointer()
|
||||||
#s_b = obi_column_formatted_infos(self.pointer())
|
sc = obi_column_formatted_infos(pointer, False)
|
||||||
#s_str = bytes2str(s_b)
|
s = bytes2str(sc)
|
||||||
#free(s_b)
|
free(sc)
|
||||||
s = self._alias + b", data type: " + self.data_type
|
return s
|
||||||
#return s_str
|
|
||||||
return bytes2str(s)
|
|
||||||
|
@OBIWrapper.checkIsActive
|
||||||
|
def repr_longformat(self) :
|
||||||
|
cdef str s
|
||||||
|
cdef char* sc
|
||||||
|
cdef OBIDMS_column_p pointer = self.pointer()
|
||||||
|
sc = obi_column_formatted_infos(pointer, True)
|
||||||
|
s = bytes2str(sc)
|
||||||
|
free(sc)
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
def close(self): # TODO discuss, can't be called bc then bug when closing view that tries to close it in C
|
def close(self): # TODO discuss, can't be called bc then bug when closing view that tries to close it in C
|
||||||
|
@ -10,7 +10,8 @@ from .capi.obidms cimport obi_open_dms, \
|
|||||||
obi_dms_exists, \
|
obi_dms_exists, \
|
||||||
obi_dms_get_full_path, \
|
obi_dms_get_full_path, \
|
||||||
obi_close_atexit, \
|
obi_close_atexit, \
|
||||||
obi_dms_write_comments
|
obi_dms_write_comments, \
|
||||||
|
obi_dms_formatted_infos
|
||||||
|
|
||||||
from .capi.obitypes cimport const_char_p
|
from .capi.obitypes cimport const_char_p
|
||||||
|
|
||||||
@ -32,6 +33,8 @@ from .object import OBIWrapper
|
|||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
from libc.stdlib cimport free
|
||||||
|
|
||||||
|
|
||||||
cdef class DMS(OBIWrapper):
|
cdef class DMS(OBIWrapper):
|
||||||
|
|
||||||
@ -223,13 +226,24 @@ cdef class DMS(OBIWrapper):
|
|||||||
|
|
||||||
|
|
||||||
@OBIWrapper.checkIsActive
|
@OBIWrapper.checkIsActive
|
||||||
def __repr__(self):
|
def __repr__(self) :
|
||||||
cdef str s
|
cdef str s
|
||||||
s=""
|
cdef char* sc
|
||||||
for view_name in self.keys():
|
cdef OBIDMS_p pointer = self.pointer()
|
||||||
view = self.get_view(view_name)
|
sc = obi_dms_formatted_infos(pointer, False)
|
||||||
s = s + repr(view) + "\n"
|
s = bytes2str(sc)
|
||||||
view.close()
|
free(sc)
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
@OBIWrapper.checkIsActive
|
||||||
|
def repr_longformat(self) :
|
||||||
|
cdef str s
|
||||||
|
cdef char* sc
|
||||||
|
cdef OBIDMS_p pointer = self.pointer()
|
||||||
|
sc = obi_dms_formatted_infos(pointer, True)
|
||||||
|
s = bytes2str(sc)
|
||||||
|
free(sc)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,11 +11,14 @@ cdef class Taxonomy(OBIWrapper) :
|
|||||||
cdef bytes _name
|
cdef bytes _name
|
||||||
cdef DMS _dms
|
cdef DMS _dms
|
||||||
cdef list _ranks
|
cdef list _ranks
|
||||||
|
cdef dict _name_dict
|
||||||
|
|
||||||
cdef inline OBIDMS_taxonomy_p pointer(self)
|
cdef inline OBIDMS_taxonomy_p pointer(self)
|
||||||
|
cdef fill_name_dict(self)
|
||||||
|
|
||||||
cpdef Taxon get_taxon_by_idx(self, int idx)
|
cpdef Taxon get_taxon_by_idx(self, int idx)
|
||||||
cpdef Taxon get_taxon_by_taxid(self, int taxid)
|
cpdef Taxon get_taxon_by_taxid(self, int taxid)
|
||||||
|
cpdef Taxon get_taxon_by_name(self, object taxon_name, object restricting_taxid=*)
|
||||||
cpdef write(self, object prefix)
|
cpdef write(self, object prefix)
|
||||||
cpdef int add_taxon(self, str name, str rank_name, int parent_taxid, int min_taxid=*)
|
cpdef int add_taxon(self, str name, str rank_name, int parent_taxid, int min_taxid=*)
|
||||||
cpdef object get_species(self, int taxid)
|
cpdef object get_species(self, int taxid)
|
||||||
|
@ -15,7 +15,11 @@ from ..capi.obitaxonomy cimport obi_taxonomy_exists, \
|
|||||||
obi_taxo_get_species, \
|
obi_taxo_get_species, \
|
||||||
obi_taxo_get_genus, \
|
obi_taxo_get_genus, \
|
||||||
obi_taxo_get_family, \
|
obi_taxo_get_family, \
|
||||||
ecotx_t
|
ecotx_t, \
|
||||||
|
econame_t, \
|
||||||
|
obi_taxo_get_name_from_name_idx, \
|
||||||
|
obi_taxo_get_taxon_from_name_idx
|
||||||
|
|
||||||
|
|
||||||
from cpython.pycapsule cimport PyCapsule_New, PyCapsule_GetPointer
|
from cpython.pycapsule cimport PyCapsule_New, PyCapsule_GetPointer
|
||||||
import tarfile
|
import tarfile
|
||||||
@ -24,11 +28,29 @@ from libc.stdlib cimport free
|
|||||||
|
|
||||||
|
|
||||||
cdef class Taxonomy(OBIWrapper) :
|
cdef class Taxonomy(OBIWrapper) :
|
||||||
# TODO function to import taxonomy?
|
# TODO function to import taxonomy?
|
||||||
|
|
||||||
cdef inline OBIDMS_taxonomy_p pointer(self) :
|
cdef inline OBIDMS_taxonomy_p pointer(self) :
|
||||||
return <OBIDMS_taxonomy_p>(self._pointer)
|
return <OBIDMS_taxonomy_p>(self._pointer)
|
||||||
|
|
||||||
|
cdef fill_name_dict(self):
|
||||||
|
print("Indexing taxon names...")
|
||||||
|
|
||||||
|
cdef OBIDMS_taxonomy_p pointer = self.pointer()
|
||||||
|
cdef ecotx_t* taxon_p
|
||||||
|
cdef object taxon_capsule
|
||||||
|
cdef bytes name
|
||||||
|
cdef int count
|
||||||
|
cdef int n
|
||||||
|
|
||||||
|
count = (<OBIDMS_taxonomy_p>pointer).names.count
|
||||||
|
|
||||||
|
for n in range(count) :
|
||||||
|
name = obi_taxo_get_name_from_name_idx(pointer, n)
|
||||||
|
taxon_p = obi_taxo_get_taxon_from_name_idx(pointer, n)
|
||||||
|
taxon_capsule = PyCapsule_New(taxon_p, NULL, NULL)
|
||||||
|
self._name_dict[name] = Taxon(taxon_capsule, self)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def exists(DMS dms, object name) :
|
def exists(DMS dms, object name) :
|
||||||
@ -75,7 +97,8 @@ cdef class Taxonomy(OBIWrapper) :
|
|||||||
|
|
||||||
taxo._dms = dms
|
taxo._dms = dms
|
||||||
taxo._name = tobytes(name)
|
taxo._name = tobytes(name)
|
||||||
|
taxo._name_dict = {}
|
||||||
|
taxo.fill_name_dict()
|
||||||
taxo._ranks = []
|
taxo._ranks = []
|
||||||
for r in range((<OBIDMS_taxonomy_p>pointer).ranks.count) :
|
for r in range((<OBIDMS_taxonomy_p>pointer).ranks.count) :
|
||||||
taxo._ranks.append(obi_taxo_rank_index_to_label(r, (<OBIDMS_taxonomy_p>pointer).ranks))
|
taxo._ranks.append(obi_taxo_rank_index_to_label(r, (<OBIDMS_taxonomy_p>pointer).ranks))
|
||||||
@ -118,7 +141,8 @@ cdef class Taxonomy(OBIWrapper) :
|
|||||||
|
|
||||||
taxo._dms = dms
|
taxo._dms = dms
|
||||||
taxo._name = folder_path
|
taxo._name = folder_path
|
||||||
|
taxo._name_dict = {}
|
||||||
|
taxo.fill_name_dict()
|
||||||
taxo._ranks = []
|
taxo._ranks = []
|
||||||
for r in range((<OBIDMS_taxonomy_p>pointer).ranks.count) :
|
for r in range((<OBIDMS_taxonomy_p>pointer).ranks.count) :
|
||||||
taxo._ranks.append(obi_taxo_rank_index_to_label(r, (<OBIDMS_taxonomy_p>pointer).ranks))
|
taxo._ranks.append(obi_taxo_rank_index_to_label(r, (<OBIDMS_taxonomy_p>pointer).ranks))
|
||||||
@ -129,8 +153,8 @@ cdef class Taxonomy(OBIWrapper) :
|
|||||||
def __getitem__(self, object ref):
|
def __getitem__(self, object ref):
|
||||||
if type(ref) == int :
|
if type(ref) == int :
|
||||||
return self.get_taxon_by_taxid(ref)
|
return self.get_taxon_by_taxid(ref)
|
||||||
else :
|
elif type(ref) == str or type(ref) == bytes :
|
||||||
raise NotImplementedError()
|
return self.get_taxon_by_name(ref)
|
||||||
|
|
||||||
|
|
||||||
cpdef Taxon get_taxon_by_taxid(self, int taxid):
|
cpdef Taxon get_taxon_by_taxid(self, int taxid):
|
||||||
@ -143,6 +167,19 @@ cdef class Taxonomy(OBIWrapper) :
|
|||||||
return Taxon(taxon_capsule, self)
|
return Taxon(taxon_capsule, self)
|
||||||
|
|
||||||
|
|
||||||
|
cpdef Taxon get_taxon_by_name(self, object taxon_name, object restricting_taxid=None):
|
||||||
|
taxon = self._name_dict.get(tobytes(taxon_name), None)
|
||||||
|
if not taxon:
|
||||||
|
return None
|
||||||
|
elif restricting_taxid:
|
||||||
|
if self.is_ancestor(restricting_taxid, taxon.taxid):
|
||||||
|
return taxon
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return taxon
|
||||||
|
|
||||||
|
|
||||||
cpdef Taxon get_taxon_by_idx(self, int idx):
|
cpdef Taxon get_taxon_by_idx(self, int idx):
|
||||||
cdef ecotx_t* taxa
|
cdef ecotx_t* taxa
|
||||||
cdef ecotx_t* taxon_p
|
cdef ecotx_t* taxon_p
|
||||||
@ -232,7 +269,7 @@ cdef class Taxonomy(OBIWrapper) :
|
|||||||
|
|
||||||
taxa = self.pointer().taxa.taxon
|
taxa = self.pointer().taxa.taxon
|
||||||
|
|
||||||
# Yield each taxid
|
# Yield each taxon
|
||||||
for t in range(self.pointer().taxa.count):
|
for t in range(self.pointer().taxa.count):
|
||||||
taxon_p = <ecotx_t*> (taxa+t)
|
taxon_p = <ecotx_t*> (taxa+t)
|
||||||
taxon_capsule = PyCapsule_New(taxon_p, NULL, NULL)
|
taxon_capsule = PyCapsule_New(taxon_p, NULL, NULL)
|
||||||
|
@ -19,7 +19,9 @@ from ..capi.obiview cimport Alias_column_pair_p, \
|
|||||||
obi_view_delete_column, \
|
obi_view_delete_column, \
|
||||||
obi_view_create_column_alias, \
|
obi_view_create_column_alias, \
|
||||||
obi_view_write_comments, \
|
obi_view_write_comments, \
|
||||||
obi_delete_view
|
obi_delete_view, \
|
||||||
|
obi_view_formatted_infos, \
|
||||||
|
obi_view_formatted_infos_one_line
|
||||||
|
|
||||||
from ..capi.obidmscolumn cimport OBIDMS_column_p
|
from ..capi.obidmscolumn cimport OBIDMS_column_p
|
||||||
from ..capi.obidms cimport OBIDMS_p
|
from ..capi.obidms cimport OBIDMS_p
|
||||||
@ -59,6 +61,8 @@ import pkgutil
|
|||||||
import json
|
import json
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from libc.stdlib cimport free
|
||||||
|
|
||||||
|
|
||||||
cdef class View(OBIWrapper) :
|
cdef class View(OBIWrapper) :
|
||||||
|
|
||||||
@ -186,15 +190,22 @@ cdef class View(OBIWrapper) :
|
|||||||
@OBIWrapper.checkIsActive
|
@OBIWrapper.checkIsActive
|
||||||
def __repr__(self) :
|
def __repr__(self) :
|
||||||
cdef str s
|
cdef str s
|
||||||
if self.read_only: # can read date
|
cdef char* sc
|
||||||
s = "#View name:\n{name:s}\n#Date created:\n{date:s}\n#Line count:\n{line_count:d}\n#Columns:\n".format(name = bytes2str(self.name),
|
cdef Obiview_p pointer = self.pointer()
|
||||||
line_count = self.line_count,
|
sc = obi_view_formatted_infos(pointer, False)
|
||||||
date = str(bytes2str_object(self.comments["Date created"])))
|
s = bytes2str(sc)
|
||||||
else:
|
free(sc)
|
||||||
s = "#View name:\n{name:s}\n#Line count:\n{line_count:d}\n#Columns:\n".format(name = bytes2str(self.name),
|
return s
|
||||||
line_count = self.line_count)
|
|
||||||
for column_name in self.keys() :
|
|
||||||
s = s + repr(self[column_name]) + '\n'
|
@OBIWrapper.checkIsActive
|
||||||
|
def repr_longformat(self) :
|
||||||
|
cdef str s
|
||||||
|
cdef char* sc
|
||||||
|
cdef Obiview_p pointer = self.pointer()
|
||||||
|
sc = obi_view_formatted_infos(pointer, True)
|
||||||
|
s = bytes2str(sc)
|
||||||
|
free(sc)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,9 +23,8 @@ cdef class TabFormat:
|
|||||||
if self.first_line:
|
if self.first_line:
|
||||||
self.tags = [k for k in data.keys()]
|
self.tags = [k for k in data.keys()]
|
||||||
|
|
||||||
for k in self.tags:
|
if self.header and self.first_line:
|
||||||
|
for k in self.tags:
|
||||||
if self.header and self.first_line:
|
|
||||||
if isinstance(data.view[k], Column_multi_elts):
|
if isinstance(data.view[k], Column_multi_elts):
|
||||||
keys = data.view[k].keys()
|
keys = data.view[k].keys()
|
||||||
keys.sort()
|
keys.sort()
|
||||||
@ -33,27 +32,36 @@ cdef class TabFormat:
|
|||||||
line.append(tobytes(k)+b':'+tobytes(k2))
|
line.append(tobytes(k)+b':'+tobytes(k2))
|
||||||
else:
|
else:
|
||||||
line.append(tobytes(k))
|
line.append(tobytes(k))
|
||||||
else:
|
r = self.sep.join(value for value in line)
|
||||||
value = data[k]
|
r += b'\n'
|
||||||
if isinstance(data.view[k], Column_multi_elts):
|
line = []
|
||||||
keys = data.view[k].keys()
|
|
||||||
keys.sort()
|
for k in self.tags:
|
||||||
if value is None: # all keys at None
|
value = data[k]
|
||||||
for k2 in keys: # TODO could be much more efficient
|
if isinstance(data.view[k], Column_multi_elts):
|
||||||
line.append(self.NAString)
|
keys = data.view[k].keys()
|
||||||
else:
|
keys.sort()
|
||||||
for k2 in keys: # TODO could be much more efficient
|
if value is None: # all keys at None
|
||||||
if value[k2] is not None:
|
for k2 in keys: # TODO could be much more efficient
|
||||||
line.append(str2bytes(str(bytes2str_object(value[k2])))) # genius programming
|
|
||||||
else:
|
|
||||||
line.append(self.NAString)
|
|
||||||
else:
|
|
||||||
if value is not None:
|
|
||||||
line.append(str2bytes(str(bytes2str_object(value))))
|
|
||||||
else:
|
|
||||||
line.append(self.NAString)
|
line.append(self.NAString)
|
||||||
|
else:
|
||||||
|
for k2 in keys: # TODO could be much more efficient
|
||||||
|
if value[k2] is not None:
|
||||||
|
line.append(str2bytes(str(bytes2str_object(value[k2])))) # genius programming
|
||||||
|
else:
|
||||||
|
line.append(self.NAString)
|
||||||
|
else:
|
||||||
|
if value is not None:
|
||||||
|
line.append(str2bytes(str(bytes2str_object(value))))
|
||||||
|
else:
|
||||||
|
line.append(self.NAString)
|
||||||
|
|
||||||
|
if self.header and self.first_line:
|
||||||
|
r += self.sep.join(value for value in line)
|
||||||
|
else:
|
||||||
|
r = self.sep.join(value for value in line)
|
||||||
|
|
||||||
if self.first_line:
|
if self.first_line:
|
||||||
self.first_line = False
|
self.first_line = False
|
||||||
|
|
||||||
return self.sep.join(value for value in line)
|
return r
|
||||||
|
@ -464,7 +464,7 @@ def open_uri(uri,
|
|||||||
if format is not None:
|
if format is not None:
|
||||||
if seqtype==b"nuc":
|
if seqtype==b"nuc":
|
||||||
objclass = Nuc_Seq # Nuc_Seq_Stored? TODO
|
objclass = Nuc_Seq # Nuc_Seq_Stored? TODO
|
||||||
if format==b"fasta":
|
if format==b"fasta" or format==b"silva":
|
||||||
if input:
|
if input:
|
||||||
iseq = fastaNucIterator(file,
|
iseq = fastaNucIterator(file,
|
||||||
skip=skip,
|
skip=skip,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
major = 3
|
major = 3
|
||||||
minor = 0
|
minor = 0
|
||||||
serial= '0b32'
|
serial= '0b39'
|
||||||
|
|
||||||
version ="%d.%d.%s" % (major,minor,serial)
|
version ="%d.%d.%s" % (major,minor,serial)
|
||||||
|
@ -36,10 +36,12 @@ bool only_ATGC(const char* seq)
|
|||||||
{
|
{
|
||||||
if (!((*c == 'A') || \
|
if (!((*c == 'A') || \
|
||||||
(*c == 'T') || \
|
(*c == 'T') || \
|
||||||
|
(*c == 'U') || \
|
||||||
(*c == 'G') || \
|
(*c == 'G') || \
|
||||||
(*c == 'C') || \
|
(*c == 'C') || \
|
||||||
(*c == 'a') || \
|
(*c == 'a') || \
|
||||||
(*c == 't') || \
|
(*c == 't') || \
|
||||||
|
(*c == 'u') || \
|
||||||
(*c == 'g') || \
|
(*c == 'g') || \
|
||||||
(*c == 'c')))
|
(*c == 'c')))
|
||||||
{
|
{
|
||||||
@ -182,6 +184,8 @@ byte_t* encode_seq_on_2_bits(const char* seq, int32_t length)
|
|||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
case 'T':
|
case 'T':
|
||||||
|
case 'u':
|
||||||
|
case 'U':
|
||||||
seq_b[i/4] |= NUC_T_2b;
|
seq_b[i/4] |= NUC_T_2b;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -288,6 +292,8 @@ byte_t* encode_seq_on_4_bits(const char* seq, int32_t length)
|
|||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
case 'T':
|
case 'T':
|
||||||
|
case 'u': // discussable
|
||||||
|
case 'U':
|
||||||
seq_b[i/2] |= NUC_T_4b;
|
seq_b[i/2] |= NUC_T_4b;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
|
44
src/encode.h
44
src/encode.h
@ -64,7 +64,7 @@ enum
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks if there are only 'atgcATGC' characters in a
|
* @brief Checks if there are only 'atgcuATGCU' characters in a
|
||||||
* character string.
|
* character string.
|
||||||
*
|
*
|
||||||
* @param seq The sequence to check.
|
* @param seq The sequence to check.
|
||||||
@ -129,12 +129,13 @@ byte_t get_nucleotide_from_encoded_seq(byte_t* seq, int32_t idx, uint8_t encodin
|
|||||||
/**
|
/**
|
||||||
* @brief Encodes a DNA sequence with each nucleotide coded on 2 bits.
|
* @brief Encodes a DNA sequence with each nucleotide coded on 2 bits.
|
||||||
*
|
*
|
||||||
* A or a : 00
|
* A or a : 00
|
||||||
* C or c : 01
|
* C or c : 01
|
||||||
* T or t : 10
|
* T or t or U or u : 10
|
||||||
* G or g : 11
|
* G or g : 11
|
||||||
*
|
*
|
||||||
* @warning The DNA sequence must contain only 'atgcATGC' characters.
|
* @warning The DNA sequence must contain only 'atgcuATGCU' characters.
|
||||||
|
* @warning Uracil ('U') bases are encoded as Thymine ('T') bases.
|
||||||
*
|
*
|
||||||
* @param seq The sequence to encode.
|
* @param seq The sequence to encode.
|
||||||
* @param length The length of the sequence to encode.
|
* @param length The length of the sequence to encode.
|
||||||
@ -169,23 +170,24 @@ char* decode_seq_on_2_bits(byte_t* seq_b, int32_t length_seq);
|
|||||||
/**
|
/**
|
||||||
* @brief Encodes a DNA sequence with each nucleotide coded on 4 bits.
|
* @brief Encodes a DNA sequence with each nucleotide coded on 4 bits.
|
||||||
*
|
*
|
||||||
* A or a : 0001
|
* A or a : 0001
|
||||||
* C or c : 0010
|
* C or c : 0010
|
||||||
* G or g : 0011
|
* G or g : 0011
|
||||||
* T or t : 0100
|
* T or t or U or u : 0100
|
||||||
* R or r : 0101
|
* R or r : 0101
|
||||||
* Y or y : 0110
|
* Y or y : 0110
|
||||||
* S or s : 0111
|
* S or s : 0111
|
||||||
* W or w : 1000
|
* W or w : 1000
|
||||||
* K or k : 1001
|
* K or k : 1001
|
||||||
* M or m : 1010
|
* M or m : 1010
|
||||||
* B or b : 1011
|
* B or b : 1011
|
||||||
* D or d : 1100
|
* D or d : 1100
|
||||||
* H or h : 1101
|
* H or h : 1101
|
||||||
* V or v : 1110
|
* V or v : 1110
|
||||||
* N or n : 1111
|
* N or n : 1111
|
||||||
*
|
*
|
||||||
* @warning The DNA sequence must contain only IUPAC characters.
|
* @warning The DNA sequence must contain only IUPAC characters.
|
||||||
|
* @warning Uracil ('U') bases are encoded as Thymine ('T') bases.
|
||||||
*
|
*
|
||||||
* @param seq The sequence to encode.
|
* @param seq The sequence to encode.
|
||||||
* @param length The length of the sequence to encode.
|
* @param length The length of the sequence to encode.
|
||||||
|
@ -218,7 +218,8 @@ int obi_ecotag(const char* dms_name,
|
|||||||
const char* taxonomy_name,
|
const char* taxonomy_name,
|
||||||
const char* output_view_name,
|
const char* output_view_name,
|
||||||
const char* output_view_comments,
|
const char* output_view_comments,
|
||||||
double ecotag_threshold) // TODO different threshold for the similarity sphere around ref seqs
|
double ecotag_threshold,
|
||||||
|
double bubble_threshold)
|
||||||
{
|
{
|
||||||
|
|
||||||
// For each sequence
|
// For each sequence
|
||||||
@ -239,6 +240,7 @@ int obi_ecotag(const char* dms_name,
|
|||||||
index_t query_seq_idx, ref_seq_idx;
|
index_t query_seq_idx, ref_seq_idx;
|
||||||
double score, best_score;
|
double score, best_score;
|
||||||
double threshold;
|
double threshold;
|
||||||
|
double lca_threshold;
|
||||||
int lcs_length;
|
int lcs_length;
|
||||||
int ali_length;
|
int ali_length;
|
||||||
Kmer_table_p ktable;
|
Kmer_table_p ktable;
|
||||||
@ -389,10 +391,10 @@ int obi_ecotag(const char* dms_name,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
free(db_threshold_str);
|
free(db_threshold_str);
|
||||||
if (ecotag_threshold < db_threshold)
|
if (bubble_threshold < db_threshold)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "\nError: The threshold demanded (%f) is lower than the threshold used to build the reference database (%f).\n\n",
|
fprintf(stderr, "\nError: The threshold demanded (%f) is lower than the threshold used to build the reference database (%f).\n\n",
|
||||||
ecotag_threshold, db_threshold);
|
bubble_threshold, db_threshold);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -597,11 +599,16 @@ int obi_ecotag(const char* dms_name,
|
|||||||
{
|
{
|
||||||
best_match_idx = best_match_array[j];
|
best_match_idx = best_match_array[j];
|
||||||
|
|
||||||
// Find the LCA for the chosen threshold
|
// Find the LCA for the highest threshold between best_score and the chosen bubble threshold
|
||||||
score_array = obi_get_array_with_col_p_in_view(ref_view, score_a_column, best_match_idx, &lca_array_length);
|
score_array = obi_get_array_with_col_p_in_view(ref_view, score_a_column, best_match_idx, &lca_array_length);
|
||||||
|
|
||||||
|
if (bubble_threshold < best_score)
|
||||||
|
lca_threshold = best_score;
|
||||||
|
else
|
||||||
|
lca_threshold = bubble_threshold;
|
||||||
|
|
||||||
k = 0;
|
k = 0;
|
||||||
while ((k < lca_array_length) && (score_array[k] >= best_score))
|
while ((k < lca_array_length) && (score_array[k] >= lca_threshold))
|
||||||
k++;
|
k++;
|
||||||
|
|
||||||
if (k>0)
|
if (k>0)
|
||||||
|
@ -42,12 +42,14 @@
|
|||||||
* @param output_view_name The name to give to the output view.
|
* @param output_view_name The name to give to the output view.
|
||||||
* @param output_view_comments The comments to associate to the output view.
|
* @param output_view_comments The comments to associate to the output view.
|
||||||
* @param ecotag_threshold The threshold at which to assign.
|
* @param ecotag_threshold The threshold at which to assign.
|
||||||
|
* @param bubble_threshold The threshold at which to look for an LCA (i.e. minimum identity considered for the assignment circle);
|
||||||
|
* the threshold actually used will be the highest between this value and the best assignment score found.
|
||||||
*
|
*
|
||||||
* The algorithm works like this:
|
* The algorithm works like this:
|
||||||
* For each query sequence:
|
* For each query sequence:
|
||||||
* Align with reference database
|
* Align with reference database
|
||||||
* Keep the indices of all the best matches
|
* Keep the indices of all the best matches
|
||||||
* For each kept index, get the LCA at that threshold as stored in the reference database, then the LCA of those LCAs
|
* For each kept index, get the LCA at the highest threshold between bubble_threshold and the best assignment score found (as stored in the reference database), then the LCA of those LCAs
|
||||||
* Write result (max score, threshold, taxid and scientific name of the LCA assigned, list of the ids of the best matches)
|
* Write result (max score, threshold, taxid and scientific name of the LCA assigned, list of the ids of the best matches)
|
||||||
*
|
*
|
||||||
* @returns A value indicating the success of the operation.
|
* @returns A value indicating the success of the operation.
|
||||||
@ -65,7 +67,8 @@ int obi_ecotag(const char* dms_name,
|
|||||||
const char* taxonomy_name,
|
const char* taxonomy_name,
|
||||||
const char* output_view_name,
|
const char* output_view_name,
|
||||||
const char* output_view_comments,
|
const char* output_view_comments,
|
||||||
double ecotag_threshold);
|
double ecotag_threshold,
|
||||||
|
double bubble_threshold);
|
||||||
|
|
||||||
|
|
||||||
#endif /* OBI_ECOTAG_H_ */
|
#endif /* OBI_ECOTAG_H_ */
|
||||||
|
101
src/obidms.c
101
src/obidms.c
@ -1409,6 +1409,107 @@ DIR* opendir_in_dms(OBIDMS_p dms, const char* path_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* obi_dms_formatted_infos(OBIDMS_p dms, bool detailed)
|
||||||
|
{
|
||||||
|
char* dms_infos = NULL;
|
||||||
|
char* view_infos = NULL;
|
||||||
|
char* view_name = NULL;
|
||||||
|
char* tax_name = NULL;
|
||||||
|
char* all_tax_dir_path = NULL;
|
||||||
|
int i;
|
||||||
|
struct dirent* dp;
|
||||||
|
Obiview_p view;
|
||||||
|
|
||||||
|
// DMS name
|
||||||
|
dms_infos = (char*) malloc((strlen("# DMS name: ")+strlen(dms->dms_name)+strlen("\n# Views:\n")+1) * sizeof(char));
|
||||||
|
if (dms_infos == NULL)
|
||||||
|
{
|
||||||
|
obidebug(1, "\nError allocating memory for DMS formatted infos");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
strcpy(dms_infos, "# DMS name: ");
|
||||||
|
strcat(dms_infos, dms->dms_name);
|
||||||
|
strcat(dms_infos, "\n# Views:\n");
|
||||||
|
|
||||||
|
// Go through views and get their infos
|
||||||
|
rewinddir(dms->view_directory);
|
||||||
|
while ((dp = readdir(dms->view_directory)) != NULL)
|
||||||
|
{
|
||||||
|
if ((dp->d_name)[0] == '.')
|
||||||
|
continue;
|
||||||
|
i=0;
|
||||||
|
while ((dp->d_name)[i] != '.')
|
||||||
|
i++;
|
||||||
|
view_name = (char*) malloc((i+1) * sizeof(char));
|
||||||
|
if (view_name == NULL)
|
||||||
|
{
|
||||||
|
obi_set_errno(OBI_MALLOC_ERROR);
|
||||||
|
obidebug(1, "\nError allocating memory for a view name when getting formatted DMS infos: file %s", dp->d_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
strncpy(view_name, dp->d_name, i);
|
||||||
|
view_name[i] = '\0';
|
||||||
|
view = obi_open_view(dms, view_name);
|
||||||
|
if (view == NULL)
|
||||||
|
{
|
||||||
|
obidebug(1, "\nError opening a view to get DMS formatted infos");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (detailed)
|
||||||
|
view_infos = obi_view_formatted_infos(view, detailed);
|
||||||
|
else
|
||||||
|
view_infos = obi_view_formatted_infos_one_line(view);
|
||||||
|
if (view_infos == NULL)
|
||||||
|
{
|
||||||
|
obidebug(1, "\nError getting a view infos to get DMS formatted infos");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
dms_infos = realloc(dms_infos, (strlen(dms_infos)+strlen(view_infos)+1) * sizeof(char));
|
||||||
|
if (dms_infos == NULL)
|
||||||
|
{
|
||||||
|
obidebug(1, "\nError reallocating memory for DMS formatted infos");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
strcat(dms_infos, view_infos);
|
||||||
|
if (obi_save_and_close_view(view) < 0)
|
||||||
|
{
|
||||||
|
obidebug(1, "\nError closing view while getting DMS formatted infos");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (detailed)
|
||||||
|
{
|
||||||
|
dms_infos = realloc(dms_infos, (strlen(dms_infos)+2) * sizeof(char));
|
||||||
|
strcat(dms_infos, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add taxonomies
|
||||||
|
dms_infos = realloc(dms_infos, (strlen(dms_infos)+strlen("\n# Taxonomies:\n")+1) * sizeof(char));
|
||||||
|
if (dms_infos == NULL)
|
||||||
|
{
|
||||||
|
obidebug(1, "\nError reallocating memory for DMS formatted infos");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
strcat(dms_infos, "# Taxonomies:\n");
|
||||||
|
rewinddir(dms->tax_directory);
|
||||||
|
while ((dp = readdir(dms->tax_directory)) != NULL)
|
||||||
|
{
|
||||||
|
if ((dp->d_name)[0] == '.')
|
||||||
|
continue;
|
||||||
|
tax_name = dp->d_name;
|
||||||
|
dms_infos = realloc(dms_infos, (strlen(dms_infos)+strlen(" # ")+strlen(view_infos)+1) * sizeof(char));
|
||||||
|
if (dms_infos == NULL)
|
||||||
|
{
|
||||||
|
obidebug(1, "\nError reallocating memory for DMS formatted infos");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
strcat(dms_infos, " # ");
|
||||||
|
strcat(dms_infos, tax_name);
|
||||||
|
}
|
||||||
|
return dms_infos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO move somewhere else maybe
|
// TODO move somewhere else maybe
|
||||||
// TODO discuss arguments
|
// TODO discuss arguments
|
||||||
obiversion_t obi_import_column(const char* dms_path_1, const char* dms_path_2, const char* column_name, obiversion_t version_number)
|
obiversion_t obi_import_column(const char* dms_path_1, const char* dms_path_2, const char* column_name, obiversion_t version_number)
|
||||||
|
17
src/obidms.h
17
src/obidms.h
@ -459,6 +459,23 @@ char* obi_dms_get_full_path(OBIDMS_p dms, const char* path_name);
|
|||||||
DIR* opendir_in_dms(OBIDMS_p dms, const char* path_name);
|
DIR* opendir_in_dms(OBIDMS_p dms, const char* path_name);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the informations of a DMS with a human readable format (dms name, taxonomies and view infos).
|
||||||
|
*
|
||||||
|
* @warning The returned pointer has to be freed by the caller.
|
||||||
|
*
|
||||||
|
* @param column A pointer on a DMS.
|
||||||
|
* @param detailed Whether the informations should contain detailed view infos.
|
||||||
|
*
|
||||||
|
* @returns A pointer on a character array where the formatted DMS informations are stored.
|
||||||
|
* @retval NULL if an error occurred.
|
||||||
|
*
|
||||||
|
* @since September 2020
|
||||||
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
||||||
|
*/
|
||||||
|
char* obi_dms_formatted_infos(OBIDMS_p dms, bool detailed);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Imports a column, copying it from a DMS to another DMS, and returns the version of the column in the destination DMS.
|
* @brief Imports a column, copying it from a DMS to another DMS, and returns the version of the column in the destination DMS.
|
||||||
*
|
*
|
||||||
|
@ -3649,6 +3649,18 @@ ecotx_t* obi_taxo_get_taxon_with_taxid(OBIDMS_taxonomy_p taxonomy, int32_t taxid
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* obi_taxo_get_name_from_name_idx(OBIDMS_taxonomy_p taxonomy, int32_t idx)
|
||||||
|
{
|
||||||
|
return (((taxonomy->names)->names)[idx]).name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ecotx_t* obi_taxo_get_taxon_from_name_idx(OBIDMS_taxonomy_p taxonomy, int32_t idx)
|
||||||
|
{
|
||||||
|
return (((taxonomy->names)->names)[idx]).taxon;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int obi_taxo_is_taxon_under_taxid(ecotx_t* taxon, int32_t other_taxid) // TODO discuss that this doesn't work with deprecated taxids
|
int obi_taxo_is_taxon_under_taxid(ecotx_t* taxon, int32_t other_taxid) // TODO discuss that this doesn't work with deprecated taxids
|
||||||
{
|
{
|
||||||
ecotx_t* next_parent;
|
ecotx_t* next_parent;
|
||||||
|
@ -447,8 +447,51 @@ ecotx_t* obi_taxo_get_superkingdom(ecotx_t* taxon, OBIDMS_taxonomy_p taxonomy);
|
|||||||
const char* obi_taxo_rank_index_to_label(int32_t rank_idx, ecorankidx_t* ranks);
|
const char* obi_taxo_rank_index_to_label(int32_t rank_idx, ecorankidx_t* ranks);
|
||||||
|
|
||||||
|
|
||||||
// TODO
|
/**
|
||||||
|
* @brief Function checking whether a taxid is included in a subset of the taxonomy.
|
||||||
|
*
|
||||||
|
* @param taxonomy A pointer on the taxonomy structure.
|
||||||
|
* @param restrict_to_taxids An array of taxids. The researched taxid must be under at least one of those array taxids.
|
||||||
|
* @param count Number of taxids in restrict_to_taxids.
|
||||||
|
* @param taxid The taxid to check.
|
||||||
|
*
|
||||||
|
* @returns A value indicating whether the taxid is included in the chosen subset of the taxonomy.
|
||||||
|
* @retval 0 if the taxid is not included in the subset of the taxonomy.
|
||||||
|
* @retval 1 if the taxid is included in the subset of the taxonomy.
|
||||||
|
*
|
||||||
|
* @since October 2020
|
||||||
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
||||||
|
*/
|
||||||
int obi_taxo_is_taxid_included(OBIDMS_taxonomy_p taxonomy,
|
int obi_taxo_is_taxid_included(OBIDMS_taxonomy_p taxonomy,
|
||||||
int32_t* restrict_to_taxids,
|
int32_t* restrict_to_taxids,
|
||||||
int32_t count,
|
int32_t count,
|
||||||
int32_t taxid);
|
int32_t taxid);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function returning the name of a taxon from its index in the taxonomy name index (econameidx_t).
|
||||||
|
*
|
||||||
|
* @param taxonomy A pointer on the taxonomy structure.
|
||||||
|
* @param idx The index at which the name is in the taxonomy name index (econameidx_t).
|
||||||
|
*
|
||||||
|
* @returns The taxon name.
|
||||||
|
*
|
||||||
|
* @since October 2020
|
||||||
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
||||||
|
*/
|
||||||
|
char* obi_taxo_get_name_from_name_idx(OBIDMS_taxonomy_p taxonomy, int32_t idx);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function returning a taxon structure from its index in the taxonomy name index (econameidx_t).
|
||||||
|
*
|
||||||
|
* @param taxonomy A pointer on the taxonomy structure.
|
||||||
|
* @param idx The index at which the taxon is in the taxonomy name index (econameidx_t).
|
||||||
|
*
|
||||||
|
* @returns The taxon structure.
|
||||||
|
*
|
||||||
|
* @since October 2020
|
||||||
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
||||||
|
*/
|
||||||
|
ecotx_t* obi_taxo_get_taxon_from_name_idx(OBIDMS_taxonomy_p taxonomy, int32_t idx);
|
||||||
|
|
||||||
|
@ -2435,17 +2435,77 @@ char* obi_column_formatted_infos(OBIDMS_column_p column, bool detailed)
|
|||||||
{
|
{
|
||||||
char* column_infos = NULL;
|
char* column_infos = NULL;
|
||||||
char* elt_names = NULL;
|
char* elt_names = NULL;
|
||||||
char* column_name = NULL;
|
char* data_type_str = NULL;
|
||||||
// should be in view.c because alias exists in the context of view
|
char* comments = NULL;
|
||||||
column_infos = malloc(2048 * sizeof(char)); // TODO
|
|
||||||
|
|
||||||
|
// Get element names informations
|
||||||
elt_names = obi_get_formatted_elements_names(column);
|
elt_names = obi_get_formatted_elements_names(column);
|
||||||
|
if (elt_names == NULL)
|
||||||
|
{
|
||||||
|
obidebug(1, "\nError getting formatted elements names for formatted columns infos");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get data type informations
|
||||||
|
data_type_str = name_data_type((column->header)->returned_data_type);
|
||||||
|
if (data_type_str == NULL)
|
||||||
|
{
|
||||||
|
obidebug(1, "\nError getting formatted data type for formatted columns infos");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// "column_name, data type: OBI_TYPE, element names: [formatted element names](, all comments)"
|
// Get commments if detailed informations required
|
||||||
|
if (detailed)
|
||||||
|
comments = (column->header)->comments;
|
||||||
|
|
||||||
|
// Build the string of formatted infos, allocating memory as needed
|
||||||
|
|
||||||
|
// Data type
|
||||||
|
column_infos = (char*) malloc((strlen("data type: ")+strlen(data_type_str)+1) * sizeof(char));
|
||||||
|
if (column_infos == NULL)
|
||||||
|
{
|
||||||
|
obi_set_errno(OBI_MALLOC_ERROR);
|
||||||
|
obidebug(1, "\nError allocating memory for formatted column infos");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(column_infos, "data type: ");
|
||||||
|
strcat(column_infos, data_type_str);
|
||||||
|
|
||||||
|
// Element names if more than 1
|
||||||
|
if ((column->header)->nb_elements_per_line > 1)
|
||||||
|
{
|
||||||
|
column_infos = realloc(column_infos, (strlen(column_infos)+strlen(", elements: ")+strlen(elt_names)+1) * sizeof(char));
|
||||||
|
if (column_infos == NULL)
|
||||||
|
{
|
||||||
|
obi_set_errno(OBI_MALLOC_ERROR);
|
||||||
|
obidebug(1, "\nError allocating memory for formatted column infos");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcat(column_infos, ", elements: ");
|
||||||
|
strcat(column_infos, elt_names);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (detailed && (strlen(comments)>2)) // Add all comments if required and not empty
|
||||||
|
{
|
||||||
|
column_infos = realloc(column_infos, (strlen(column_infos)+strlen("\nComments:\n")+strlen(comments)+1) * sizeof(char));
|
||||||
|
if (column_infos == NULL)
|
||||||
|
{
|
||||||
|
obi_set_errno(OBI_MALLOC_ERROR);
|
||||||
|
obidebug(1, "\nError allocating memory for formatted column infos");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcat(column_infos, "\nComments:\n");
|
||||||
|
strcat(column_infos, comments);
|
||||||
|
}
|
||||||
|
|
||||||
|
// "data type: OBI_TYPE, element names: [formatted element names](, all comments)"
|
||||||
|
|
||||||
free(elt_names);
|
free(elt_names);
|
||||||
|
free(data_type_str);
|
||||||
|
|
||||||
return column_infos;
|
return column_infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2492,7 +2552,6 @@ int obi_column_prepare_to_set_value(OBIDMS_column_p column, index_t line_nb, ind
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int obi_column_prepare_to_get_value(OBIDMS_column_p column, index_t line_nb)
|
int obi_column_prepare_to_get_value(OBIDMS_column_p column, index_t line_nb)
|
||||||
{
|
{
|
||||||
if ((line_nb+1) > ((column->header)->line_count))
|
if ((line_nb+1) > ((column->header)->line_count))
|
||||||
|
@ -505,12 +505,37 @@ index_t obi_column_get_element_index_from_name(OBIDMS_column_p column, const cha
|
|||||||
char* obi_get_elements_names(OBIDMS_column_p column);
|
char* obi_get_elements_names(OBIDMS_column_p column);
|
||||||
|
|
||||||
|
|
||||||
// TODO
|
/**
|
||||||
//char* obi_get_formatted_elements_names(OBIDMS_column_p column);
|
* @brief Recovers the elements names of the lines of a column with a human readable format ("0; 1; 2; ...; n\0").
|
||||||
|
*
|
||||||
|
* @warning The returned pointer has to be freed by the caller.
|
||||||
|
*
|
||||||
|
* @param column A pointer on an OBIDMS column.
|
||||||
|
*
|
||||||
|
* @returns A pointer on a character array where the elements names are stored.
|
||||||
|
* @retval NULL if an error occurred.
|
||||||
|
*
|
||||||
|
* @since September 2020
|
||||||
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
||||||
|
*/
|
||||||
|
char* obi_get_formatted_elements_names(OBIDMS_column_p column);
|
||||||
|
|
||||||
|
|
||||||
// TODO
|
/**
|
||||||
//char* obi_column_formatted_infos(OBIDMS_column_p column);
|
* @brief Returns the informations of a column with a human readable format (data type, element names, comments).
|
||||||
|
*
|
||||||
|
* @warning The returned pointer has to be freed by the caller.
|
||||||
|
*
|
||||||
|
* @param column A pointer on an OBIDMS column.
|
||||||
|
* @param detailed Whether the informations should contain column comments or just data type and element names.
|
||||||
|
*
|
||||||
|
* @returns A pointer on a character array where the formatted column informations are stored.
|
||||||
|
* @retval NULL if an error occurred.
|
||||||
|
*
|
||||||
|
* @since September 2020
|
||||||
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
||||||
|
*/
|
||||||
|
char* obi_column_formatted_infos(OBIDMS_column_p column, bool detailed);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
140
src/obiview.c
140
src/obiview.c
@ -17,6 +17,7 @@
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <time.h>
|
||||||
//#include <ctype.h>
|
//#include <ctype.h>
|
||||||
|
|
||||||
#include "obiview.h"
|
#include "obiview.h"
|
||||||
@ -1185,6 +1186,7 @@ static int close_view(Obiview_p view)
|
|||||||
obidebug(1, "\nError getting a column to close from the linked list of column pointers of a view");
|
obidebug(1, "\nError getting a column to close from the linked list of column pointers of a view");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obi_close_column(column) < 0)
|
if (obi_close_column(column) < 0)
|
||||||
{
|
{
|
||||||
obidebug(1, "\nError closing a column while closing a view");
|
obidebug(1, "\nError closing a column while closing a view");
|
||||||
@ -2603,6 +2605,144 @@ int obi_view_create_column_alias(Obiview_p view, const char* current_name, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* obi_view_formatted_infos(Obiview_p view, bool detailed)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char* view_infos = NULL;
|
||||||
|
char* view_name = NULL;
|
||||||
|
time_t creation_date;
|
||||||
|
char* creation_date_str = NULL;
|
||||||
|
index_t line_count;
|
||||||
|
char line_count_str[256];
|
||||||
|
OBIDMS_column_p column;
|
||||||
|
char* column_alias = NULL;
|
||||||
|
char* column_infos = NULL;
|
||||||
|
char* comments = NULL;
|
||||||
|
|
||||||
|
// View name
|
||||||
|
view_name = (view->infos)->name;
|
||||||
|
view_infos = (char*) malloc((strlen("# View name:\n")+strlen(view_name)+1) * sizeof(char));
|
||||||
|
strcpy(view_infos, "# View name:\n");
|
||||||
|
strcat(view_infos, view_name);
|
||||||
|
|
||||||
|
// Date created
|
||||||
|
if (view->read_only) // Date not saved until view is finished writing
|
||||||
|
{
|
||||||
|
creation_date = (view->infos)->creation_date;
|
||||||
|
creation_date_str = ctime(&creation_date);
|
||||||
|
view_infos = realloc(view_infos, (strlen(view_infos)+strlen("\n# Date created:\n")+strlen(creation_date_str)+1) * sizeof(char));
|
||||||
|
strcat(view_infos, "\n# Date created:\n");
|
||||||
|
strcat(view_infos, creation_date_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Line count
|
||||||
|
line_count = (view->infos)->line_count;
|
||||||
|
snprintf(line_count_str, sizeof line_count_str, "%lld", line_count);
|
||||||
|
view_infos = realloc(view_infos, (strlen(view_infos)+strlen("\n# Line count:\n")+strlen(line_count_str)+1) * sizeof(char));
|
||||||
|
strcat(view_infos, "# Line count:\n");
|
||||||
|
strcat(view_infos, line_count_str);
|
||||||
|
|
||||||
|
// Columns: go through each, print their alias then their infos
|
||||||
|
view_infos = realloc(view_infos, (strlen(view_infos)+strlen("\n# Columns:")+1) * sizeof(char));
|
||||||
|
strcat(view_infos, "\n# Columns:");
|
||||||
|
for (i=0; i<((view->infos)->column_count); i++)
|
||||||
|
{
|
||||||
|
column = *((OBIDMS_column_p*)ll_get(view->columns, i));
|
||||||
|
if (column == NULL)
|
||||||
|
{
|
||||||
|
obidebug(1, "\nError getting a column from the linked list of column pointers of a view to format view infos");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Column alias
|
||||||
|
column_alias = (((view->infos)->column_references)[i]).alias;
|
||||||
|
view_infos = realloc(view_infos, (strlen(view_infos)+strlen("\n")+strlen(column_alias)+strlen(", ")+1) * sizeof(char));
|
||||||
|
strcat(view_infos, "\n");
|
||||||
|
strcat(view_infos, column_alias);
|
||||||
|
strcat(view_infos, ", ");
|
||||||
|
|
||||||
|
// Column infos
|
||||||
|
column_infos = obi_column_formatted_infos(column, detailed);
|
||||||
|
if (column_infos == NULL)
|
||||||
|
{
|
||||||
|
obidebug(1, "\nError getting column infos to format view infos");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
view_infos = realloc(view_infos, (strlen(view_infos)+strlen(column_infos)+1) * sizeof(char));
|
||||||
|
strcat(view_infos, column_infos);
|
||||||
|
free(column_infos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get commments if detailed informations required
|
||||||
|
if (detailed)
|
||||||
|
{
|
||||||
|
comments = (view->infos)->comments;
|
||||||
|
if (strlen(comments)>2) // Add all comments if not empty
|
||||||
|
{
|
||||||
|
view_infos = realloc(view_infos, (strlen(view_infos)+strlen("\n# Comments:\n")+strlen(comments)+1) * sizeof(char));
|
||||||
|
if (view_infos == NULL)
|
||||||
|
{
|
||||||
|
obi_set_errno(OBI_MALLOC_ERROR);
|
||||||
|
obidebug(1, "\nError allocating memory for formatted view infos");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcat(view_infos, "\n# Comments:\n");
|
||||||
|
strcat(view_infos, comments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
view_infos = realloc(view_infos, (strlen(view_infos)+2) * sizeof(char));
|
||||||
|
strcat(view_infos, "\n");
|
||||||
|
|
||||||
|
return view_infos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* obi_view_formatted_infos_one_line(Obiview_p view)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char* view_infos = NULL;
|
||||||
|
char* view_name = NULL;
|
||||||
|
time_t creation_date;
|
||||||
|
char* creation_date_str = NULL;
|
||||||
|
index_t line_count;
|
||||||
|
char line_count_str[256];
|
||||||
|
|
||||||
|
// View name
|
||||||
|
view_name = (view->infos)->name;
|
||||||
|
view_infos = (char*) malloc((strlen(" # ")+strlen(view_name)+2) * sizeof(char));
|
||||||
|
strcpy(view_infos, " # ");
|
||||||
|
strcat(view_infos, view_name);
|
||||||
|
strcat(view_infos, ":");
|
||||||
|
|
||||||
|
// Date created
|
||||||
|
if (view->read_only) // Date not saved until view is finished writing
|
||||||
|
{
|
||||||
|
creation_date = (view->infos)->creation_date;
|
||||||
|
creation_date_str = ctime(&creation_date);
|
||||||
|
// Delete \n added by ctime
|
||||||
|
creation_date_str[strlen(creation_date_str)-1] = '\0';
|
||||||
|
view_infos = realloc(view_infos, (strlen(view_infos)+strlen(" Date created: ")+strlen(creation_date_str)+1) * sizeof(char));
|
||||||
|
strcat(view_infos, " Date created: ");
|
||||||
|
strcat(view_infos, creation_date_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Line count
|
||||||
|
line_count = (view->infos)->line_count;
|
||||||
|
snprintf(line_count_str, sizeof line_count_str, "%lld", line_count);
|
||||||
|
view_infos = realloc(view_infos, (strlen(view_infos)+strlen(" ; Line count: ")+strlen(line_count_str)+1) * sizeof(char));
|
||||||
|
strcat(view_infos, " ; Line count: ");
|
||||||
|
strcat(view_infos, line_count_str);
|
||||||
|
|
||||||
|
view_infos = realloc(view_infos, (strlen(view_infos)+2) * sizeof(char));
|
||||||
|
strcat(view_infos, "\n");
|
||||||
|
|
||||||
|
return view_infos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int obi_view_write_comments(Obiview_p view, const char* comments)
|
int obi_view_write_comments(Obiview_p view, const char* comments)
|
||||||
{
|
{
|
||||||
size_t new_size;
|
size_t new_size;
|
||||||
|
129
src/obiview.h
129
src/obiview.h
@ -30,54 +30,56 @@
|
|||||||
#include "obiblob.h"
|
#include "obiblob.h"
|
||||||
|
|
||||||
|
|
||||||
#define OBIVIEW_NAME_MAX_LENGTH (249) /**< The maximum length of an OBIDMS view name, without the extension.
|
#define OBIVIEW_NAME_MAX_LENGTH (249) /**< The maximum length of an OBIDMS view name, without the extension.
|
||||||
*/
|
*/
|
||||||
#define VIEW_TYPE_MAX_LENGTH (1024) /**< The maximum length of the type name of a view.
|
#define VIEW_TYPE_MAX_LENGTH (1024) /**< The maximum length of the type name of a view.
|
||||||
*/
|
*/
|
||||||
#define LINES_COLUMN_NAME "LINES" /**< The name of the column containing the line selections
|
#define LINES_COLUMN_NAME "LINES" /**< The name of the column containing the line selections
|
||||||
* in all views.
|
* in all views.
|
||||||
*/
|
*/
|
||||||
#define VIEW_TYPE_NUC_SEQS "NUC_SEQS_VIEW" /**< The type name of views based on nucleotide sequences
|
#define VIEW_TYPE_NUC_SEQS "NUC_SEQS_VIEW" /**< The type name of views based on nucleotide sequences
|
||||||
* and their metadata.
|
* and their metadata.
|
||||||
*/
|
*/
|
||||||
#define NUC_SEQUENCE_COLUMN "NUC_SEQ" /**< The name of the column containing the nucleotide sequences
|
#define NUC_SEQUENCE_COLUMN "NUC_SEQ" /**< The name of the column containing the nucleotide sequences
|
||||||
* in NUC_SEQS_VIEW views.
|
* in NUC_SEQS_VIEW views.
|
||||||
*/
|
*/
|
||||||
#define ID_COLUMN "ID" /**< The name of the column containing the sequence identifiers
|
#define ID_COLUMN "ID" /**< The name of the column containing the sequence identifiers
|
||||||
* in NUC_SEQS_VIEW views.
|
* in NUC_SEQS_VIEW views.
|
||||||
*/
|
*/
|
||||||
#define DEFINITION_COLUMN "DEFINITION" /**< The name of the column containing the sequence definitions
|
#define DEFINITION_COLUMN "DEFINITION" /**< The name of the column containing the sequence definitions
|
||||||
* in NUC_SEQS_VIEW views.
|
* in NUC_SEQS_VIEW views.
|
||||||
*/
|
*/
|
||||||
#define QUALITY_COLUMN "QUALITY" /**< The name of the column containing the sequence qualities
|
#define QUALITY_COLUMN "QUALITY" /**< The name of the column containing the sequence qualities
|
||||||
* in NUC_SEQS_VIEW views.
|
* in NUC_SEQS_VIEW views.
|
||||||
*/
|
*/
|
||||||
#define REVERSE_QUALITY_COLUMN "REVERSE_QUALITY" /**< The name of the column containing the sequence qualities
|
#define REVERSE_QUALITY_COLUMN "REVERSE_QUALITY" /**< The name of the column containing the sequence qualities
|
||||||
* of the reverse read (generated by ngsfilter, used by alignpairedend).
|
* of the reverse read (generated by ngsfilter, used by alignpairedend).
|
||||||
*/
|
*/
|
||||||
#define REVERSE_SEQUENCE_COLUMN "REVERSE_SEQUENCE" /**< The name of the column containing the sequence
|
#define REVERSE_SEQUENCE_COLUMN "REVERSE_SEQUENCE" /**< The name of the column containing the sequence
|
||||||
* of the reverse read (generated by ngsfilter, used by alignpairedend).
|
* of the reverse read (generated by ngsfilter, used by alignpairedend).
|
||||||
*/
|
*/
|
||||||
#define QUALITY_COLUMN "QUALITY" /**< The name of the column containing the sequence qualities
|
#define QUALITY_COLUMN "QUALITY" /**< The name of the column containing the sequence qualities
|
||||||
* in NUC_SEQS_VIEW views.
|
* in NUC_SEQS_VIEW views.
|
||||||
*/
|
*/
|
||||||
#define COUNT_COLUMN "COUNT" /**< The name of the column containing the sequence counts
|
#define COUNT_COLUMN "COUNT" /**< The name of the column containing the sequence counts
|
||||||
* in NUC_SEQS_VIEW views.
|
* in NUC_SEQS_VIEW views.
|
||||||
*/
|
*/
|
||||||
#define TAXID_COLUMN "TAXID" /**< The name of the column containing the taxids. TODO subtype of INT column?
|
#define SCIENTIFIC_NAME_COLUMN "SCIENTIFIC_NAME" /**< The name of the column containing the taxon scientific name.
|
||||||
*/
|
*/
|
||||||
#define MERGED_TAXID_COLUMN "MERGED_TAXID" /**< The name of the column containing the merged taxids information.
|
#define TAXID_COLUMN "TAXID" /**< The name of the column containing the taxids. TODO subtype of INT column?
|
||||||
*/
|
*/
|
||||||
#define MERGED_PREFIX "MERGED_" /**< The prefix to prepend to column names when merging informations during obi uniq.
|
#define MERGED_TAXID_COLUMN "MERGED_TAXID" /**< The name of the column containing the merged taxids information.
|
||||||
*/
|
*/
|
||||||
#define TAXID_DIST_COLUMN "TAXID_DIST" /**< The name of the column containing a dictionary of taxid:[list of ids] when merging informations during obi uniq.
|
#define MERGED_PREFIX "MERGED_" /**< The prefix to prepend to column names when merging informations during obi uniq.
|
||||||
*/
|
*/
|
||||||
#define MERGED_COLUMN "MERGED" /**< The name of the column containing a list of ids when merging informations during obi uniq.
|
#define TAXID_DIST_COLUMN "TAXID_DIST" /**< The name of the column containing a dictionary of taxid:[list of ids] when merging informations during obi uniq.
|
||||||
*/
|
*/
|
||||||
#define ID_PREFIX "seq" /**< The default prefix of sequence identifiers in automatic ID columns.
|
#define MERGED_COLUMN "MERGED" /**< The name of the column containing a list of ids when merging informations during obi uniq.
|
||||||
*/
|
*/
|
||||||
#define PREDICATE_KEY "predicates" /**< The key used in the json-formatted view comments to store predicates.
|
#define ID_PREFIX "seq" /**< The default prefix of sequence identifiers in automatic ID columns.
|
||||||
*/
|
*/
|
||||||
|
#define PREDICATE_KEY "predicates" /**< The key used in the json-formatted view comments to store predicates.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -519,6 +521,39 @@ OBIDMS_column_p* obi_view_get_pointer_on_column_in_view(Obiview_p view, const ch
|
|||||||
int obi_view_create_column_alias(Obiview_p view, const char* current_name, const char* alias);
|
int obi_view_create_column_alias(Obiview_p view, const char* current_name, const char* alias);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the informations of a view with a human readable format (view name, date created, line count, column informations, comments).
|
||||||
|
*
|
||||||
|
* @warning The returned pointer has to be freed by the caller.
|
||||||
|
*
|
||||||
|
* @param column A pointer on a view.
|
||||||
|
* @param detailed Whether the informations should contain view comments.
|
||||||
|
*
|
||||||
|
* @returns A pointer on a character array where the formatted view informations are stored.
|
||||||
|
* @retval NULL if an error occurred.
|
||||||
|
*
|
||||||
|
* @since September 2020
|
||||||
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
||||||
|
*/
|
||||||
|
char* obi_view_formatted_infos(Obiview_p view, bool detailed);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the informations of a view with a human readable format on one line (view name, date created, line count).
|
||||||
|
*
|
||||||
|
* @warning The returned pointer has to be freed by the caller.
|
||||||
|
*
|
||||||
|
* @param column A pointer on a view.
|
||||||
|
*
|
||||||
|
* @returns A pointer on a character array where the formatted view informations are stored.
|
||||||
|
* @retval NULL if an error occurred.
|
||||||
|
*
|
||||||
|
* @since September 2020
|
||||||
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
||||||
|
*/
|
||||||
|
char* obi_view_formatted_infos_one_line(Obiview_p view);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Internal function writing new comments in a view file.
|
* @brief Internal function writing new comments in a view file.
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user