Compare commits

...

73 Commits

Author SHA1 Message Date
ce2833c04b switch to version v3.0.1b15 2022-02-25 17:48:44 +13:00
f64b3da30b split command 2022-02-25 17:44:18 +13:00
388b3e0410 removed a trace 2021-11-11 15:53:27 +13:00
c9db990b83 switch to version 3.0.1b14 2021-11-11 15:28:00 +13:00
3f253feb5e Cython: View: fixed keys method to get list of view keys 2021-11-11 15:27:32 +13:00
85d2bab607 small fix 2021-11-11 15:26:48 +13:00
53b3d81137 small fixes and improvements 2021-11-11 15:26:09 +13:00
f6353fbf28 obi export: added options to export to metabaR compatible format 2021-11-11 15:24:12 +13:00
5a8b9dca5d goes with previous commit 2021-11-11 15:12:04 +13:00
8bd6d6c8e9 Python: URI decoding: now properly checking that paths can be encoded in
ASCII (issue #89)
2021-11-02 11:17:59 +13:00
405e6ef420 Python: URI decoding: added metabaR output 2021-11-02 11:16:29 +13:00
fedacfafe7 switch to version 3.0.1b13 2021-09-13 11:46:17 +12:00
2d66e0e965 python: genbank parser: better handling of white spaces 2021-09-13 11:44:38 +12:00
f43856b712 switch to version 3.0.1b12 2021-09-08 10:56:55 +12:00
9e0c319806 Cython: fixed rewriting of column when rewriting a 1 element dict column 2021-09-08 10:54:23 +12:00
58b42cd977 C: views: now correctly parses view names containing '.' when cleaning
unfinished views. Closes #115
2021-09-08 10:52:42 +12:00
34de90bce6 ngsfilter: checks better if there is an associated sequencing quality 2021-09-08 10:30:11 +12:00
4be9f36f99 stats: fixed the computation of variance when it is equal to 0 2021-08-05 11:32:16 +12:00
f10e78ba3c C: fixed the printing of view informations from a DMS (fixes #114) 2021-08-05 11:31:24 +12:00
88c8463ed7 Cython: taxonomy: improved logging 2021-08-05 11:29:20 +12:00
89168271ef ecopcr: now accepting taxonomy from a different DMS than the reference
sequences
2021-08-05 11:28:57 +12:00
82d2642000 Switch to version 3.0.1b11 2021-07-22 09:25:39 +12:00
99c1cd60d6 export: now exports header for tabular files by default and added option
to only export specific columns
2021-07-22 09:23:18 +12:00
ce7ae4ac55 export: fixed 'only' option printing one too many if printing header 2021-07-21 15:23:04 +12:00
0b4283bb58 cat: improved error handling 2021-07-21 15:22:08 +12:00
747f3efbb2 Improved taxonomy reading information display 2021-07-21 15:20:44 +12:00
6c1a3aff47 Fixed the handling of sample names that are numbers (forcing conversion) 2021-07-21 15:19:24 +12:00
e2932b05f2 Implements #108 export integer missing values as 0 for tables by default 2021-07-21 14:41:54 +12:00
32345b9ec4 Addresses #111 2021-07-19 15:55:25 +12:00
9334cf6cc6 import: improved genbank parser and switch to version 3.0.1.b10 2021-06-17 08:42:01 +12:00
8ec13a294c Switch to version 3.0.1b9 2021-06-01 09:21:43 +12:00
3e45c34491 import: now imports and adds taxids for SILVA and RDP files, added
import of lists, fixed skipping of errors (was not overwriting), and
fixed --no-progress-bar option
2021-06-01 09:21:07 +12:00
c2f3d90dc1 build_ref_db: set default threshold to 0.99 2021-06-01 09:11:17 +12:00
6b732d11d3 align: fixed column URI parsing 2021-06-01 09:10:21 +12:00
9eb833a0af typo fix 2021-06-01 09:09:16 +12:00
6b7b0e3bd1 cat: fixed the handling of dictionary columns 2021-06-01 09:06:13 +12:00
47691a8f58 count: added option to specify the count column 2021-06-01 09:05:14 +12:00
b908b581c8 clean: hid not implemented option 2021-06-01 09:04:22 +12:00
03c174fd7a grep: added taxonomy check 2021-05-31 17:03:39 +12:00
2156588ff6 added TODO comment 2021-05-31 17:01:57 +12:00
6ff29c6a6a Increased maximum line count to 10E12 2021-05-31 17:00:55 +12:00
51a3c68fb5 C: build_reference_db: fixed gcc warning/error 2021-05-31 16:59:17 +12:00
da91ffc2c7 URI decoding: fixed reading a taxonomy before any view 2021-05-31 16:57:20 +12:00
c884615522 obi stats: various fixes and improvements 2021-05-31 16:51:06 +12:00
cb53381863 ecotag: BEST_MATCH_TAXIDS now dereplicated (no repeated taxids in the
list) and switch to version 3.0.1b8
2021-05-10 16:02:06 +12:00
72b3e5d872 switch to version 3.0.1b7 2021-04-07 10:31:54 +12:00
238e9f70f3 alignpairedend: fixed bug that would cut out sequence ends when it
should not have
2021-04-07 10:31:12 +12:00
e099a16624 small fixes 2021-04-07 10:28:02 +12:00
847c9c816d import: fixed count estimation for tabular files with header 2021-03-30 09:07:14 +13:00
6026129ca8 Fixes 101 2021-03-30 09:06:08 +13:00
169b6514b4 small doc fixes 2021-03-29 13:07:48 +13:00
89b0c48141 switch to version 3.0.1b6 2021-03-29 11:18:44 +13:00
7c02782e3c import/export: workaround for issue where flake8(?) reads '\t' as
'\'+'t' when parsing an option value
2021-03-29 11:18:19 +13:00
ecc4c2c78b stats: improved the tabular display 2021-03-29 09:03:32 +13:00
f5413381fd C: taxonomy: fixed a bug where some taxa would not be stored in the
merged index
2021-03-29 09:02:18 +13:00
3e93cfff7b import: Columns are now rewritten in OBI_FLOAT if a value is > INT32_MAX 2021-03-29 09:00:52 +13:00
6d445fe3ad switch to version 3.0.1b5 2021-03-22 09:41:01 +13:00
824deb7e21 new command: obi rm: deletes any view (for now the user deleting a view
accepts that there will be missing information when running obi history
if other views came from the deleted view)
2021-03-18 09:17:06 +13:00
d579bb2749 switch to version 3.0.1b4 2021-03-16 17:40:58 +13:00
10e5ebdbc0 ngsfilter: fixed critical bug where barcodes shorter than the forward
primer would be missed
2021-03-16 15:09:28 +13:00
8833110490 import: fixed the import of tabular files with no header 2021-03-16 09:15:48 +13:00
bd38449f2d switch to version 3.0.1b3 2021-03-15 16:50:17 +13:00
904823c827 uniq: now OK to use -m option even if only one unique key in information
to merge (e.g. one sample)
2021-03-15 16:48:22 +13:00
af68a1024c Switch to version 3.0.1b2 2021-03-15 16:26:43 +13:00
425fe25bd2 Made the OBITools3 more 'empty file friendly' 2021-03-15 16:25:41 +13:00
d48aed38d4 switch to version 3.0.1b1 2021-03-11 17:11:23 +13:00
5e32f8523e Merge branch 'wsl_version' 2021-03-11 16:47:59 +13:00
8f1d94fd24 obi test: fixed bug introduced in ad1fd3c3 2021-03-11 16:31:31 +13:00
38f42cb0fb C: Made maximum file path length 2048 instead of 1024 2021-03-11 15:23:22 +13:00
7f0f63cf26 C: now completely unmapping files before truncating them to a smaller
size (#68)
2021-03-11 15:12:40 +13:00
cba78111c9 obi test: fixed bug introduced in previous version 2021-03-11 11:36:52 +13:00
41fbae7b6c Switch to version 3.0.0b43 2021-03-10 16:52:03 +13:00
ad1fd3c341 Now handling dictionaries with one key 2021-03-10 16:50:30 +13:00
67 changed files with 1278 additions and 435 deletions

View File

@ -1,3 +1,9 @@
import codecs
def unescaped_str(arg_str):
return arg_str.encode('latin-1', 'backslashreplace').decode('unicode-escape')
def __addInputOption(optionManager): def __addInputOption(optionManager):
optionManager.add_argument( optionManager.add_argument(
@ -43,7 +49,13 @@ def __addImportInputOption(optionManager):
action="store_const", dest="obi:inputformat", action="store_const", dest="obi:inputformat",
default=None, default=None,
const=b'silva', const=b'silva',
help="Input file is in SILVA fasta format") help="Input file is in SILVA fasta format. If NCBI taxonomy provided with --taxonomy, taxid and scientific name will be added for each sequence.")
group.add_argument('--rdp-input',
action="store_const", dest="obi:inputformat",
default=None,
const=b'rdp',
help="Input file is in RDP training set fasta format. If NCBI taxonomy provided with --taxonomy, taxid and scientific name will be added for each sequence.")
group.add_argument('--embl-input', group.add_argument('--embl-input',
action="store_const", dest="obi:inputformat", action="store_const", dest="obi:inputformat",
@ -125,15 +137,15 @@ def __addImportInputOption(optionManager):
def __addTabularOption(optionManager): def __addTabularOption(optionManager):
group = optionManager.add_argument_group("Input and output format options for tabular files") group = optionManager.add_argument_group("Input and output format options for tabular files")
group.add_argument('--header', group.add_argument('--no-header',
action="store_true", dest="obi:header", action="store_false", dest="obi:header",
default=False, default=True,
help="First line of tabular file contains column names") help="Don't print the header (first line with column names")
group.add_argument('--sep', group.add_argument('--sep',
action="store", dest="obi:sep", action="store", dest="obi:sep",
default="\t", default="\t",
type=str, type=unescaped_str,
help="Column separator") help="Column separator")
@ -165,6 +177,16 @@ def __addTabularInputOption(optionManager):
help="Lines starting by this char are considered as comment") help="Lines starting by this char are considered as comment")
def __addTabularOutputOption(optionManager):
group = optionManager.add_argument_group("Output format options for tabular files")
__addTabularOption(optionManager)
group.add_argument('--na-int-stay-na',
action="store_false", dest="obi:na_int_to_0",
help="NA (Non available) integer values should be exported as NA in tabular output (default: they are converted to 0 for tabular output).") # TODO
def __addTaxdumpInputOption(optionManager): # TODO maybe not the best way to do it def __addTaxdumpInputOption(optionManager): # TODO maybe not the best way to do it
group = optionManager.add_argument_group("Input format options for taxdump") group = optionManager.add_argument_group("Input format options for taxdump")
@ -198,6 +220,10 @@ def addTabularInputOption(optionManager):
__addTabularInputOption(optionManager) __addTabularInputOption(optionManager)
def addTabularOutputOption(optionManager):
__addTabularOutputOption(optionManager)
def addTaxonomyOption(optionManager): def addTaxonomyOption(optionManager):
__addTaxonomyOption(optionManager) __addTaxonomyOption(optionManager)
@ -210,6 +236,7 @@ def addAllInputOption(optionManager):
__addInputOption(optionManager) __addInputOption(optionManager)
__addImportInputOption(optionManager) __addImportInputOption(optionManager)
__addTabularInputOption(optionManager) __addTabularInputOption(optionManager)
__addTabularOutputOption(optionManager)
__addTaxonomyOption(optionManager) __addTaxonomyOption(optionManager)
__addTaxdumpInputOption(optionManager) __addTaxdumpInputOption(optionManager)
@ -270,6 +297,35 @@ def __addExportOutputOption(optionManager):
const=b'tabular', const=b'tabular',
help="Output file is in tabular format") help="Output file is in tabular format")
group.add_argument('--metabaR-output',
action="store_const", dest="obi:outputformat",
default=None,
const=b'metabaR',
help="Export the files needed by the obifiles_to_metabarlist function of the metabaR package")
group.add_argument('--metabaR-prefix',
action="store", dest="obi:metabarprefix",
type=str,
help="Prefix for the files when using --metabaR-output option")
group.add_argument('--metabaR-ngsfilter',
action="store", dest="obi:metabarngsfilter",
type=str,
default=None,
help="URI to the ngsfilter view when using --metabaR-output option (if not provided, it is not exported)")
group.add_argument('--metabaR-samples',
action="store", dest="obi:metabarsamples",
type=str,
default=None,
help="URI to the sample metadata view when using --metabaR-output option (if not provided, it is built as just a list of the sample names)")
group.add_argument('--only-keys',
action="append", dest="obi:only_keys",
type=str,
default=[],
help="Only export the given keys (columns).")
group.add_argument('--print-na', group.add_argument('--print-na',
action="store_true", dest="obi:printna", action="store_true", dest="obi:printna",
default=False, default=False,
@ -302,14 +358,14 @@ def addTabularOutputOption(optionManager):
def addExportOutputOption(optionManager): def addExportOutputOption(optionManager):
__addExportOutputOption(optionManager) __addExportOutputOption(optionManager)
__addTabularOption(optionManager) __addTabularOutputOption(optionManager)
def addAllOutputOption(optionManager): def addAllOutputOption(optionManager):
__addOutputOption(optionManager) __addOutputOption(optionManager)
__addDMSOutputOption(optionManager) __addDMSOutputOption(optionManager)
__addExportOutputOption(optionManager) __addExportOutputOption(optionManager)
__addTabularOption(optionManager) __addTabularOutputOption(optionManager)
def addNoProgressBarOption(optionManager): def addNoProgressBarOption(optionManager):

View File

@ -26,7 +26,7 @@ import sys
from cpython.exc cimport PyErr_CheckSignals from cpython.exc cimport PyErr_CheckSignals
__title__="Annotate sequences with their corresponding NCBI taxid found from the taxon scientific name." __title__="Annotate sequences with their corresponding NCBI taxid found from the taxon scientific name"
@ -45,7 +45,7 @@ def addOptions(parser):
metavar="<TAXID_TAG>", metavar="<TAXID_TAG>",
default=b"TAXID", default=b"TAXID",
help="Name of the tag to store the found taxid " help="Name of the tag to store the found taxid "
"(default: 'TAXID'.") "(default: 'TAXID').")
group.add_argument('-n', '--taxon-name-tag', group.add_argument('-n', '--taxon-name-tag',
action="store", action="store",
@ -53,7 +53,7 @@ def addOptions(parser):
metavar="<SCIENTIFIC_NAME_TAG>", metavar="<SCIENTIFIC_NAME_TAG>",
default=b"SCIENTIFIC_NAME", default=b"SCIENTIFIC_NAME",
help="Name of the tag giving the scientific name of the taxon " help="Name of the tag giving the scientific name of the taxon "
"(default: 'SCIENTIFIC_NAME'.") "(default: 'SCIENTIFIC_NAME').")
group.add_argument('-g', '--try-genus-match', group.add_argument('-g', '--try-genus-match',
action="store_true", dest="addtaxids:try_genus_match", action="store_true", dest="addtaxids:try_genus_match",
@ -174,6 +174,7 @@ def run(config):
taxid_column[i] = taxon.taxid taxid_column[i] = taxon.taxid
found_count+=1 found_count+=1
elif try_genus: # try finding genus or other parent taxon from the first word elif try_genus: # try finding genus or other parent taxon from the first word
#print(i, o_view[i].id)
taxon_name_sp = taxon_name.split(b" ") taxon_name_sp = taxon_name.split(b" ")
taxon = taxo.get_taxon_by_name(taxon_name_sp[0], res_anc) taxon = taxo.get_taxon_by_name(taxon_name_sp[0], res_anc)
if taxon is not None: if taxon is not None:

View File

@ -19,7 +19,7 @@ import time
import sys import sys
__title__="Aligns one sequence column with itself or two sequence columns" __title__="Align one sequence column with itself or two sequence columns"
def addOptions(parser): def addOptions(parser):
@ -158,7 +158,7 @@ def run(config):
i_view_name = i_uri.split(b"/")[0] i_view_name = i_uri.split(b"/")[0]
i_column_name = b"" i_column_name = b""
i_element_name = b"" i_element_name = b""
if len(i_uri.split(b"/")) == 2: if len(i_uri.split(b"/")) >= 2:
i_column_name = i_uri.split(b"/")[1] i_column_name = i_uri.split(b"/")[1]
if len(i_uri.split(b"/")) == 3: if len(i_uri.split(b"/")) == 3:
i_element_name = i_uri.split(b"/")[2] i_element_name = i_uri.split(b"/")[2]
@ -181,7 +181,7 @@ def run(config):
i_dms_name_2 = i_dms_2.name i_dms_name_2 = i_dms_2.name
i_uri_2 = input_2[1] i_uri_2 = input_2[1]
original_i_view_name_2 = i_uri_2.split(b"/")[0] original_i_view_name_2 = i_uri_2.split(b"/")[0]
if len(i_uri_2.split(b"/")) == 2: if len(i_uri_2.split(b"/")) >= 2:
i_column_name_2 = i_uri_2.split(b"/")[1] i_column_name_2 = i_uri_2.split(b"/")[1]
if len(i_uri_2.split(b"/")) == 3: if len(i_uri_2.split(b"/")) == 3:
i_element_name_2 = i_uri_2.split(b"/")[2] i_element_name_2 = i_uri_2.split(b"/")[2]

View File

@ -23,7 +23,7 @@ import os
from cpython.exc cimport PyErr_CheckSignals from cpython.exc cimport PyErr_CheckSignals
__title__="Aligns paired-ended reads" __title__="Align paired-ended reads"
@ -205,19 +205,25 @@ def run(config):
if type(entries) == list: if type(entries) == list:
forward = entries[0] forward = entries[0]
reverse = entries[1] reverse = entries[1]
aligner = Kmer_similarity(forward, \ if len(forward) == 0 or len(reverse) == 0:
view2=reverse, \ aligner = None
kmer_size=config['alignpairedend']['kmersize'], \ else:
reversed_column=None) aligner = Kmer_similarity(forward, \
view2=reverse, \
kmer_size=config['alignpairedend']['kmersize'], \
reversed_column=None)
else: else:
aligner = Kmer_similarity(entries, \ if len(entries) == 0:
column2=entries[REVERSE_SEQUENCE_COLUMN], \ aligner = None
qual_column2=entries[REVERSE_QUALITY_COLUMN], \ else:
kmer_size=config['alignpairedend']['kmersize'], \ aligner = Kmer_similarity(entries, \
reversed_column=entries[b'reversed']) # column created by the ngsfilter tool column2=entries[REVERSE_SEQUENCE_COLUMN], \
qual_column2=entries[REVERSE_QUALITY_COLUMN], \
kmer_size=config['alignpairedend']['kmersize'], \
reversed_column=entries[b'reversed']) # column created by the ngsfilter tool
ba = alignmentIterator(entries, aligner) ba = alignmentIterator(entries, aligner)
i = 0 i = 0
for ali in ba: for ali in ba:
@ -251,7 +257,7 @@ def run(config):
pb(i, force=True) pb(i, force=True)
print("", file=sys.stderr) print("", file=sys.stderr)
if kmer_ali : if kmer_ali and aligner is not None:
aligner.free() aligner.free()
# Save command config in View and DMS comments # Save command config in View and DMS comments

View File

@ -16,7 +16,7 @@ import sys
from cpython.exc cimport PyErr_CheckSignals from cpython.exc cimport PyErr_CheckSignals
__title__="Tag a set of sequences for PCR and sequencing errors identification" __title__="Build a reference database for ecotag"
def addOptions(parser): def addOptions(parser):
@ -31,10 +31,9 @@ def addOptions(parser):
group.add_argument('--threshold','-t', group.add_argument('--threshold','-t',
action="store", dest="build_ref_db:threshold", action="store", dest="build_ref_db:threshold",
metavar='<THRESHOLD>', metavar='<THRESHOLD>',
default=0.0, default=0.99,
type=float, type=float,
help="Score threshold as a normalized identity, e.g. 0.95 for an identity of 95%%. Default: 0.00" help="Score threshold as a normalized identity, e.g. 0.95 for an identity of 95%%. Default: 0.99.")
" (no threshold).")
def run(config): def run(config):

View File

@ -22,7 +22,7 @@ import sys
from cpython.exc cimport PyErr_CheckSignals from cpython.exc cimport PyErr_CheckSignals
__title__="Concatenate views." __title__="Concatenate views"
def addOptions(parser): def addOptions(parser):
@ -97,7 +97,7 @@ def run(config):
Column.new_column(o_view, REVERSE_QUALITY_COLUMN, OBI_QUAL, associated_column_name=REVERSE_SEQUENCE_COLUMN, associated_column_version=o_view[REVERSE_SEQUENCE_COLUMN].version) Column.new_column(o_view, REVERSE_QUALITY_COLUMN, OBI_QUAL, associated_column_name=REVERSE_SEQUENCE_COLUMN, associated_column_version=o_view[REVERSE_SEQUENCE_COLUMN].version)
# Initialize multiple elements columns # Initialize multiple elements columns
if type(output_0)==BufferedWriter: if type(output_0)!=BufferedWriter:
dict_cols = {} dict_cols = {}
for v_uri in config["cat"]["views_to_cat"]: for v_uri in config["cat"]["views_to_cat"]:
v = open_uri(v_uri)[1] v = open_uri(v_uri)[1]
@ -115,7 +115,7 @@ def run(config):
v.close() 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']), dict_column=True)
# Initialize the progress bar # Initialize the progress bar
if not config['obi']['noprogressbar']: if not config['obi']['noprogressbar']:
@ -134,7 +134,11 @@ def run(config):
rep = repr(entry) rep = repr(entry)
output_0.write(str2bytes(rep)+b"\n") output_0.write(str2bytes(rep)+b"\n")
else: else:
o_view[i] = entry try:
o_view[i] = entry
except:
print("\nError with entry:", repr(entry))
print(repr(o_view))
i+=1 i+=1
v.close() v.close()

View File

@ -54,11 +54,11 @@ def addOptions(parser):
default=False, default=False,
help="Only sequences labeled as heads are kept in the output. Default: False") help="Only sequences labeled as heads are kept in the output. Default: False")
group.add_argument('--cluster-tags', '-C', # group.add_argument('--cluster-tags', '-C',
action="store_true", # action="store_true",
dest="clean:cluster-tags", # dest="clean:cluster-tags",
default=False, # default=False,
help="Adds tags for each sequence giving its cluster's head and weight for each sample.") # help="Adds tags for each sequence giving its cluster's head and weight for each sample.")
group.add_argument('--thread-count','-p', # TODO should probably be in a specific option group group.add_argument('--thread-count','-p', # TODO should probably be in a specific option group
action="store", dest="clean:thread-count", action="store", dest="clean:thread-count",
@ -142,4 +142,5 @@ def run(config):
i_dms.close(force=True) i_dms.close(force=True)
logger("info", "Done.") logger("info", "Done.")

View File

@ -10,7 +10,7 @@ from obitools3.dms.capi.obiview cimport COUNT_COLUMN
from cpython.exc cimport PyErr_CheckSignals from cpython.exc cimport PyErr_CheckSignals
__title__="Counts sequence records" __title__="Count sequence records"
def addOptions(parser): def addOptions(parser):
@ -29,6 +29,12 @@ def addOptions(parser):
default=False, default=False,
help="Prints only the total count of sequence records (if a sequence has no `count` attribute, its default count is 1) (default: False).") help="Prints only the total count of sequence records (if a sequence has no `count` attribute, its default count is 1) (default: False).")
group.add_argument('-c','--count-tag',
action="store", dest="count:countcol",
default='COUNT',
type=str,
help="Name of the tag/column associated with the count information (default: COUNT).")
def run(config): def run(config):
@ -41,18 +47,20 @@ def run(config):
if input is None: if input is None:
raise Exception("Could not read input") raise Exception("Could not read input")
entries = input[1] entries = input[1]
countcol = config['count']['countcol']
count1 = len(entries) count1 = len(entries)
count2 = 0 count2 = 0
if COUNT_COLUMN in entries and ((config['count']['sequence'] == config['count']['all']) or (config['count']['all'])) : if countcol in entries and ((config['count']['sequence'] == config['count']['all']) or (config['count']['all'])) :
for e in entries: for e in entries:
PyErr_CheckSignals() PyErr_CheckSignals()
count2+=e[COUNT_COLUMN] count2+=e[countcol]
if COUNT_COLUMN in entries and (config['count']['sequence'] == config['count']['all']): if countcol in entries and (config['count']['sequence'] == config['count']['all']):
print(count1,count2) print(count1,count2)
elif COUNT_COLUMN in entries and config['count']['all']: elif countcol in entries and config['count']['all']:
print(count2) print(count2)
else: else:
print(count1) print(count1)

View File

@ -175,6 +175,14 @@ def run(config):
o_dms_name = output[0].name o_dms_name = output[0].name
o_view_name = output[1] o_view_name = output[1]
# Open the taxonomy DMS
taxdms = open_uri(config['obi']['taxoURI'],
dms_only=True)
if taxdms is None:
raise Exception("Could not open taxonomy DMS")
tax_dms = taxdms[0]
tax_dms_name = taxdms[0].name
# Read taxonomy name # Read taxonomy name
taxonomy_name = config['obi']['taxoURI'].split("/")[-1] # Robust in theory taxonomy_name = config['obi']['taxoURI'].split("/")[-1] # Robust in theory
@ -197,7 +205,8 @@ def run(config):
# TODO: primers in comments? # TODO: primers in comments?
if obi_ecopcr(i_dms.name_with_full_path, tobytes(i_view_name), tobytes(taxonomy_name), \ if obi_ecopcr(i_dms.name_with_full_path, tobytes(i_view_name),
tax_dms.name_with_full_path, tobytes(taxonomy_name), \
o_dms.name_with_full_path, tobytes(o_view_name), comments, \ o_dms.name_with_full_path, tobytes(o_view_name), comments, \
tobytes(config['ecopcr']['primer1']), tobytes(config['ecopcr']['primer2']), \ tobytes(config['ecopcr']['primer1']), tobytes(config['ecopcr']['primer2']), \
config['ecopcr']['error'], \ config['ecopcr']['error'], \

View File

@ -6,6 +6,9 @@ from obitools3.apps.config import logger
from obitools3.dms import DMS from obitools3.dms import DMS
from obitools3.dms.obiseq import Nuc_Seq from obitools3.dms.obiseq import Nuc_Seq
from obitools3.dms.capi.obiview cimport QUALITY_COLUMN from obitools3.dms.capi.obiview cimport QUALITY_COLUMN
from obitools3.writers.tab import TabWriter
from obitools3.format.tab import TabFormat
from obitools3.utils cimport tobytes, tostr
from obitools3.apps.optiongroups import addMinimalInputOption, \ from obitools3.apps.optiongroups import addMinimalInputOption, \
addExportOutputOption, \ addExportOutputOption, \
@ -76,6 +79,13 @@ def run(config):
else: else:
pb = ProgressBar(withoutskip - skip, config) pb = ProgressBar(withoutskip - skip, config)
if config['obi']['outputformat'] == b'metabaR':
# Check prefix
if "metabarprefix" not in config["obi"]:
raise Exception("Prefix needed when exporting for metabaR (--metabaR-prefix option)")
else:
metabaRprefix = config["obi"]["metabarprefix"]
i=0 i=0
for seq in iview : for seq in iview :
PyErr_CheckSignals() PyErr_CheckSignals()
@ -91,6 +101,81 @@ def run(config):
pb(i, force=True) pb(i, force=True)
print("", file=sys.stderr) print("", file=sys.stderr)
if config['obi']['outputformat'] == b'metabaR':
# Export ngsfilter file if view provided
if 'metabarngsfilter' in config['obi']:
ngsfilter_input = open_uri(config['obi']['metabarngsfilter'])
if ngsfilter_input is None:
raise Exception("Could not read ngsfilter view for metabaR output")
ngsfilter_view = ngsfilter_input[1]
ngsfilter_output = open(config['obi']['metabarprefix']+'.ngsfilter', 'w')
for line in ngsfilter_view:
line_to_print = b""
line_to_print += line[b'experiment']
line_to_print += b"\t"
line_to_print += line[b'sample']
line_to_print += b"\t"
line_to_print += line[b'forward_tag']
line_to_print += b":"
line_to_print += line[b'reverse_tag']
line_to_print += b"\t"
line_to_print += line[b'forward_primer']
line_to_print += b"\t"
line_to_print += line[b'reverse_primer']
line_to_print += b"\t"
line_to_print += line[b'additional_info']
print(tostr(line_to_print), file=ngsfilter_output)
if ngsfilter_input[0] != input[0]:
ngsfilter_input[0].close()
ngsfilter_output.close()
# Export sample metadata
samples_output = open(config['obi']['metabarprefix']+'_samples.csv', 'w')
# Export sample metadata file if view provided
if 'metabarsamples' in config['obi']:
samples_input = open_uri(config['obi']['metabarsamples'])
if samples_input is None:
raise Exception("Could not read sample view for metabaR output")
samples_view = samples_input[1]
# Export with tab formatter
TabWriter(TabFormat(header=True, sep='\t',),
samples_output,
header=True)
if samples_input[0] != input[0]:
samples_input[0].close()
# Else export just sample names from main view
else:
sample_list = []
if 'MERGED_sample' in iview:
sample_list = iview['MERGED_sample'].keys()
elif 'sample' not in iview:
for seq in iview:
sample = seq['sample']
if sample not in sample_list:
sample_list.append(sample)
else:
logger("warning", "Can not read sample list from main view for metabaR sample list export")
print("sample_id", file=samples_output)
for sample in sample_list:
line_to_print = b""
line_to_print += sample
line_to_print += b"\t"
print(tostr(line_to_print), file=samples_output)
samples_output.close()
# TODO save command in input dms? # TODO save command in input dms?
if not BrokenPipeError and not IOError: if not BrokenPipeError and not IOError:

View File

@ -91,7 +91,7 @@ def addOptions(parser):
metavar="<ATTRIBUTE_NAME>", metavar="<ATTRIBUTE_NAME>",
help="Select records with the attribute <ATTRIBUTE_NAME> " help="Select records with the attribute <ATTRIBUTE_NAME> "
"defined (not set to NA value). " "defined (not set to NA value). "
"Several -a options can be used on the same " "Several -A options can be used on the same "
"command line.") "command line.")
group.add_argument("-L", "--lmax", group.add_argument("-L", "--lmax",
@ -258,6 +258,13 @@ def Filter_generator(options, tax_filter, i_view):
def Taxonomy_filter_generator(taxo, options): def Taxonomy_filter_generator(taxo, options):
if (("required_ranks" in options and options["required_ranks"]) or \
("required_taxids" in options and options["required_taxids"]) or \
("ignored_taxids" in options and options["ignored_taxids"])) and \
(taxo is None):
raise RollbackException("obi grep error: can't use taxonomy options without providing a taxonomy. Rollbacking view")
if taxo is not None: if taxo is not None:
def tax_filter(seq): def tax_filter(seq):
good = True good = True

View File

@ -16,7 +16,7 @@ from io import BufferedWriter
from cpython.exc cimport PyErr_CheckSignals from cpython.exc cimport PyErr_CheckSignals
__title__="Keep the N first lines of a view." __title__="Keep the N first lines of a view"
def addOptions(parser): def addOptions(parser):

View File

@ -34,14 +34,17 @@ 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 OBI_STR, \
OBI_INT
from obitools3.dms.capi.obierrno cimport obi_errno from obitools3.dms.capi.obierrno cimport obi_errno
from obitools3.apps.optiongroups import addImportInputOption, \ from obitools3.apps.optiongroups import addImportInputOption, \
addTabularInputOption, \ addTabularInputOption, \
addTaxdumpInputOption, \ addTaxdumpInputOption, \
addMinimalOutputOption addMinimalOutputOption, \
addNoProgressBarOption, \
addTaxonomyOption
from obitools3.uri.decode import open_uri from obitools3.uri.decode import open_uri
@ -50,9 +53,10 @@ from obitools3.apps.config import logger
from cpython.exc cimport PyErr_CheckSignals from cpython.exc cimport PyErr_CheckSignals
from io import BufferedWriter from io import BufferedWriter
import ast
__title__="Imports sequences from different formats into a DMS" __title__="Import sequences from different formats into a DMS"
default_config = { 'destview' : None, default_config = { 'destview' : None,
@ -69,7 +73,9 @@ def addOptions(parser):
addImportInputOption(parser) addImportInputOption(parser)
addTabularInputOption(parser) addTabularInputOption(parser)
addTaxdumpInputOption(parser) addTaxdumpInputOption(parser)
addTaxonomyOption(parser)
addMinimalOutputOption(parser) addMinimalOutputOption(parser)
addNoProgressBarOption(parser)
group = parser.add_argument_group('obi import specific options') group = parser.add_argument_group('obi import specific options')
@ -85,6 +91,10 @@ def addOptions(parser):
help="If importing a view into another DMS, do it by importing each line, saving disk space if the original view " help="If importing a view into another DMS, do it by importing each line, saving disk space if the original view "
"has a line selection associated.") "has a line selection associated.")
# group.add_argument('--only-id',
# action="store", dest="import:onlyid",
# help="only id")
def run(config): def run(config):
cdef tuple input cdef tuple input
@ -97,6 +107,7 @@ def run(config):
cdef bint get_quality cdef bint get_quality
cdef bint NUC_SEQS_view cdef bint NUC_SEQS_view
cdef bint silva cdef bint silva
cdef bint rdp
cdef int nb_elts cdef int nb_elts
cdef object d cdef object d
cdef View view cdef View view
@ -180,6 +191,16 @@ def run(config):
logger("info", "Done.") logger("info", "Done.")
return return
# Open taxonomy if there is one
if 'taxoURI' in config['obi'] and config['obi']['taxoURI'] is not None:
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]
else :
taxo = None
# If importing a view between two DMS and not wanting to save space if line selection in original view, use C API # If importing a view between two DMS and not wanting to save space if line selection in original view, use C API
if isinstance(input[1], View) and not config['import']['space_priority']: if isinstance(input[1], View) and not config['import']['space_priority']:
if obi_import_view(input[0].name_with_full_path, o_dms.name_with_full_path, input[1].name, tobytes((config['obi']['outputURI'].split('/'))[-1])) < 0 : if obi_import_view(input[0].name_with_full_path, o_dms.name_with_full_path, input[1].name, tobytes((config['obi']['outputURI'].split('/'))[-1])) < 0 :
@ -192,8 +213,11 @@ def run(config):
logger("info", "Done.") logger("info", "Done.")
return return
if entry_count >= 0: # Reinitialize the progress bar
if entry_count >= 0 and config['obi']['noprogressbar'] == False:
pb = ProgressBar(entry_count, config) pb = ProgressBar(entry_count, config)
else:
pb = None
NUC_SEQS_view = False NUC_SEQS_view = False
if isinstance(output[1], View) : if isinstance(output[1], View) :
@ -202,20 +226,25 @@ def run(config):
NUC_SEQS_view = True NUC_SEQS_view = True
else: else:
raise NotImplementedError() raise NotImplementedError()
# Save basic columns in variables for optimization # Save basic columns in variables for optimization
if NUC_SEQS_view : if NUC_SEQS_view :
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 # Prepare taxon scientific name and taxid refs if RDP or SILVA file
if 'inputformat' in config['obi'] and config['obi']['inputformat'] == b"silva": silva = False
rdp = False
if 'inputformat' in config['obi'] and (config['obi']['inputformat'] == b"silva" or config['obi']['inputformat'] == b"rdp"):
#if taxo is None:
# raise Exception("A taxonomy (as built by 'obi import --taxdump') must be provided for SILVA and RDP files")
silva = True silva = True
sci_name_col = Column.new_column(view, SCIENTIFIC_NAME_COLUMN, OBI_STR) rdp = True
else: if taxo is not None:
silva = False sci_name_col = Column.new_column(view, SCIENTIFIC_NAME_COLUMN, OBI_STR)
taxid_col = Column.new_column(view, TAXID_COLUMN, OBI_INT)
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
@ -257,15 +286,21 @@ def run(config):
for tag in dict_dict: for tag in dict_dict:
dcols[tag] = (Column.new_column(view, tag, dict_dict[tag][1], \ dcols[tag] = (Column.new_column(view, tag, dict_dict[tag][1], \
nb_elements_per_line=len(dict_dict[tag][0]), \ nb_elements_per_line=len(dict_dict[tag][0]), \
elements_names=list(dict_dict[tag][0])), \ elements_names=list(dict_dict[tag][0]), \
dict_column=True), \
dict_dict[tag][1]) dict_dict[tag][1])
# Reinitialize the input # Reinitialize the input
if isinstance(input[0], CompressedFile): if isinstance(input[0], CompressedFile):
input_is_file = True input_is_file = True
if entry_count >= 0:
# Reinitialize the progress bar
if entry_count >= 0 and config['obi']['noprogressbar'] == False:
pb = ProgressBar(entry_count, config) pb = ProgressBar(entry_count, config)
else:
pb = None
try: try:
input[0].close() input[0].close()
except AttributeError: except AttributeError:
@ -274,6 +309,11 @@ def run(config):
if input is None: if input is None:
raise Exception("Could not open input URI") raise Exception("Could not open input URI")
# if 'onlyid' in config['import']:
# onlyid = tobytes(config['import']['onlyid'])
# else:
# onlyid = None
entries = input[1] entries = input[1]
i = 0 i = 0
for entry in entries : for entry in entries :
@ -291,6 +331,9 @@ def run(config):
elif not i%50000: elif not i%50000:
logger("info", "Imported %d entries", i) logger("info", "Imported %d entries", i)
# if onlyid is not None and entry.id != onlyid:
# continue
try: try:
if NUC_SEQS_view: if NUC_SEQS_view:
@ -306,11 +349,18 @@ def run(config):
if get_quality: if get_quality:
qual_col[i] = entry.quality qual_col[i] = entry.quality
# Parse taxon scientific name if SILVA file # Parse taxon scientific name if RDP file
if silva: if (rdp or silva) and taxo is not None:
sci_name = entry.definition.split(b";")[-1] sci_names = entry.definition.split(b";")
sci_name_col[i] = sci_name for sci_name in reversed(sci_names):
if sci_name.split()[0] != b'unidentified' and sci_name.split()[0] != b'uncultured' and sci_name.split()[0] != b'metagenome' :
taxon = taxo.get_taxon_by_name(sci_name)
if taxon is not None:
sci_name_col[i] = taxon.name
taxid_col[i] = taxon.taxid
#print(taxid_col[i], sci_name_col[i])
break
for tag in entry : for tag in entry :
if tag != ID_COLUMN and tag != DEFINITION_COLUMN and tag != NUC_SEQUENCE_COLUMN and tag != QUALITY_COLUMN : # TODO dirty if tag != ID_COLUMN and tag != DEFINITION_COLUMN and tag != NUC_SEQUENCE_COLUMN and tag != QUALITY_COLUMN : # TODO dirty
@ -322,28 +372,41 @@ def run(config):
tag = COUNT_COLUMN tag = COUNT_COLUMN
if tag[:7] == b"merged_": if tag[:7] == b"merged_":
tag = MERGED_PREFIX+tag[7:] tag = MERGED_PREFIX+tag[7:]
if type(value) == bytes and value[:1]==b"[" :
try:
if type(eval(value)) == list:
value = eval(value)
#print(value)
except:
pass
if tag not in dcols : if tag not in dcols :
value_type = type(value) value_type = type(value)
nb_elts = 1 nb_elts = 1
value_obitype = OBI_VOID value_obitype = OBI_VOID
dict_col = False
if value_type == dict or value_type == list :
if value_type == dict :
nb_elts = len(value) nb_elts = len(value)
elt_names = list(value) elt_names = list(value)
dict_col = True
else : else :
nb_elts = 1 nb_elts = 1
elt_names = None elt_names = None
if value_type == list :
tuples = True
else:
tuples = False
value_obitype = get_obitype(value) value_obitype = get_obitype(value)
if value_obitype != OBI_VOID : if value_obitype != OBI_VOID :
dcols[tag] = (Column.new_column(view, tag, value_obitype, nb_elements_per_line=nb_elts, elements_names=elt_names), value_obitype) dcols[tag] = (Column.new_column(view, tag, value_obitype, nb_elements_per_line=nb_elts, elements_names=elt_names, dict_column=dict_col, tuples=tuples), value_obitype)
# Fill value # Fill value
if value_type == dict and nb_elts == 1: # special case that makes the OBI3 create a 1 elt/line column which won't read a dict value
value = value[list(value.keys())[0]] # The solution is to transform the value in a simple atomic one acceptable by the column
dcols[tag][0][i] = value dcols[tag][0][i] = value
# TODO else log error? # TODO else log error?
@ -369,8 +432,8 @@ def run(config):
# Fill value # Fill value
dcols[tag][0][i] = value dcols[tag][0][i] = value
except IndexError : except (IndexError, OverflowError):
value_type = type(value) value_type = type(value)
old_column = dcols[tag][0] old_column = dcols[tag][0]
old_nb_elements_per_line = old_column.nb_elements_per_line old_nb_elements_per_line = old_column.nb_elements_per_line
@ -417,18 +480,19 @@ def run(config):
dcols[tag][0][i] = value dcols[tag][0][i] = value
except Exception as e: except Exception as e:
print("\nCould not import sequence id:", entry.id, "(error raised:", e, ")") print("\nCould not import sequence:", repr(entry), "(error raised:", e, ")")
if 'skiperror' in config['obi'] and not config['obi']['skiperror']: if 'skiperror' in config['obi'] and not config['obi']['skiperror']:
raise e raise e
else: else:
pass pass
i-=1 # overwrite problematic entry
i+=1 i+=1
if pb is not None: if pb is not None:
pb(i, force=True) pb(i, force=True)
print("", file=sys.stderr) print("", file=sys.stderr)
logger("info", "Imported %d entries", i) logger("info", "Imported %d entries", len(view))
# Save command config in View and DMS comments # Save command config in View and DMS comments
command_line = " ".join(sys.argv[1:]) command_line = " ".join(sys.argv[1:])

15
python/obitools3/commands/ngsfilter.pyx Normal file → Executable file
View File

@ -24,7 +24,7 @@ from cpython.exc cimport PyErr_CheckSignals
from io import BufferedWriter from io import BufferedWriter
__title__="Assigns sequence records to the corresponding experiment/sample based on DNA tags and primers" __title__="Assign sequence records to the corresponding experiment/sample based on DNA tags and primers"
def addOptions(parser): def addOptions(parser):
@ -271,7 +271,7 @@ cdef tuple annotate(sequences, infos, no_tags, verbose=False):
sequences[0][REVERSE_QUALITY_COLUMN] = sequences[1].quality # used by alignpairedend tool sequences[0][REVERSE_QUALITY_COLUMN] = sequences[1].quality # used by alignpairedend tool
for seq in sequences: for seq in sequences:
if hasattr(seq, "quality_array"): if hasattr(seq, "quality_array") and seq.quality_array is not None:
q = -reduce(lambda x,y:x+y,(math.log10(z) for z in seq.quality_array),0)/len(seq.quality_array)*10 q = -reduce(lambda x,y:x+y,(math.log10(z) for z in seq.quality_array),0)/len(seq.quality_array)*10
seq[b'avg_quality']=q seq[b'avg_quality']=q
q = -reduce(lambda x,y:x+y,(math.log10(z) for z in seq.quality_array[0:10]),0) q = -reduce(lambda x,y:x+y,(math.log10(z) for z in seq.quality_array[0:10]),0)
@ -322,7 +322,7 @@ cdef tuple annotate(sequences, infos, no_tags, verbose=False):
sequences[0] = sequences[0][directmatch[1][2]:] sequences[0] = sequences[0][directmatch[1][2]:]
else: else:
sequences[1] = sequences[1][directmatch[1][2]:] sequences[1] = sequences[1][directmatch[1][2]:]
sequences[0][REVERSE_SEQUENCE_COLUMN] = sequences[1].seq # used by alignpairedend tool sequences[0][REVERSE_SEQUENCE_COLUMN] = sequences[1].seq # used by alignpairedend tool
sequences[0][REVERSE_QUALITY_COLUMN] = sequences[1].quality # used by alignpairedend tool sequences[0][REVERSE_QUALITY_COLUMN] = sequences[1].quality # used by alignpairedend tool
if directmatch[0].forward: if directmatch[0].forward:
@ -369,7 +369,7 @@ cdef tuple annotate(sequences, infos, no_tags, verbose=False):
sequences[0] = sequences[0][:r[1]] sequences[0] = sequences[0][:r[1]]
else: else:
sequences[1] = sequences[1][:r[1]] sequences[1] = sequences[1][:r[1]]
sequences[0][REVERSE_SEQUENCE_COLUMN] = sequences[1].seq # used by alignpairedend tool sequences[0][REVERSE_SEQUENCE_COLUMN] = sequences[1].seq # used by alignpairedend tool
sequences[0][REVERSE_QUALITY_COLUMN] = sequences[1].quality # used by alignpairedend tool sequences[0][REVERSE_QUALITY_COLUMN] = sequences[1].quality # used by alignpairedend tool
# do the same on the other seq # do the same on the other seq
if first_match_first_seq: if first_match_first_seq:
@ -394,7 +394,7 @@ cdef tuple annotate(sequences, infos, no_tags, verbose=False):
seq_to_match = sequences[0] seq_to_match = sequences[0]
reversematch = [] reversematch = []
# Compute begin # Compute begin
begin=directmatch[1][2]+1 # end of match + 1 on the same sequence #begin=directmatch[1][2]+1 # end of match + 1 on the same sequence -- No, already cut out forward primer
# Try reverse matching on the other sequence: # Try reverse matching on the other sequence:
new_seq = True new_seq = True
pattern = 0 pattern = 0
@ -408,7 +408,7 @@ cdef tuple annotate(sequences, infos, no_tags, verbose=False):
primer=p primer=p
# Saving original primer as 4th member of the tuple to serve as correct key in infos dict even if it might have been reversed complemented # Saving original primer as 4th member of the tuple to serve as correct key in infos dict even if it might have been reversed complemented
# (3rd member already used by directmatch) # (3rd member already used by directmatch)
reversematch.append((primer, primer(seq_to_match, same_sequence=not new_seq, pattern=pattern, begin=begin), None, p)) reversematch.append((primer, primer(seq_to_match, same_sequence=not new_seq, pattern=pattern, begin=0), None, p))
new_seq = False new_seq = False
pattern+=1 pattern+=1
# Choose match closer to the end of the sequence # Choose match closer to the end of the sequence
@ -450,7 +450,7 @@ cdef tuple annotate(sequences, infos, no_tags, verbose=False):
sequences[1] = sequences[1][reversematch[1][2]:] sequences[1] = sequences[1][reversematch[1][2]:]
if not directmatch[0].forward: if not directmatch[0].forward:
sequences[1] = sequences[1].reverse_complement sequences[1] = sequences[1].reverse_complement
sequences[0][REVERSE_SEQUENCE_COLUMN] = sequences[1].seq # used by alignpairedend tool sequences[0][REVERSE_SEQUENCE_COLUMN] = sequences[1].seq # used by alignpairedend tool
sequences[0][REVERSE_QUALITY_COLUMN] = sequences[1].quality # used by alignpairedend tool sequences[0][REVERSE_QUALITY_COLUMN] = sequences[1].quality # used by alignpairedend tool
else: else:
sequences[0] = sequences[0][reversematch[1][2]:] sequences[0] = sequences[0][reversematch[1][2]:]
@ -645,6 +645,7 @@ def run(config):
g = 0 g = 0
u = 0 u = 0
i = 0
no_tags = config['ngsfilter']['notags'] no_tags = config['ngsfilter']['notags']
try: try:
for i in range(entries_len): for i in range(entries_len):

View File

@ -0,0 +1,44 @@
#cython: language_level=3
from obitools3.uri.decode import open_uri
from obitools3.apps.config import logger
from obitools3.dms import DMS
from obitools3.apps.optiongroups import addMinimalInputOption
from obitools3.dms.view.view cimport View
import os
__title__="Delete a view"
def addOptions(parser):
addMinimalInputOption(parser)
def run(config):
DMS.obi_atexit()
logger("info", "obi rm")
# Open the input
input = open_uri(config['obi']['inputURI'])
if input is None:
raise Exception("Could not read input")
# Check that it's a view
if isinstance(input[1], View) :
view = input[1]
else:
raise NotImplementedError()
# Get the path to the view file to remove
path = input[0].full_path # dms path
path+=b"/VIEWS/"
path+=view.name
path+=b".obiview"
# Close the view and the DMS
view.close()
input[0].close(force=True)
# Rm
os.remove(path)

View File

@ -36,7 +36,7 @@ NULL_VALUE = {OBI_BOOL: OBIBool_NA,
OBI_STR: b""} OBI_STR: b""}
__title__="Sort view lines according to the value of a given attribute." __title__="Sort view lines according to the value of a given attribute"
def addOptions(parser): def addOptions(parser):

View File

@ -0,0 +1,105 @@
#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.apps.config import logger
from obitools3.utils cimport tobytes
import sys
from cpython.exc cimport PyErr_CheckSignals
__title__="Split"
def addOptions(parser):
addMinimalInputOption(parser)
addNoProgressBarOption(parser)
group=parser.add_argument_group("obi split specific options")
group.add_argument('-p','--prefix',
action="store", dest="split:prefix",
metavar="<PREFIX>",
help="Prefix added to each subview name (included undefined)")
group.add_argument('-t','--tag-name',
action="store", dest="split:tagname",
metavar="<TAG_NAME>",
help="Attribute/tag used to split the input")
group.add_argument('-u','--undefined',
action="store", dest="split:undefined",
default=b'UNDEFINED',
metavar="<VIEW_NAME>",
help="Name of the view where undefined sequenced are stored (will be PREFIX_VIEW_NAME)")
def run(config):
DMS.obi_atexit()
logger("info", "obi split")
# 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]
# Initialize the progress bar
if config['obi']['noprogressbar'] == False:
pb = ProgressBar(len(i_view), config)
else:
pb = None
tag_to_split = config["split"]["tagname"]
undefined = tobytes(config["split"]["undefined"])
selections = {}
# Go through input view and split
for i in range(len(i_view)):
PyErr_CheckSignals()
if pb is not None:
pb(i)
line = i_view[i]
if tag_to_split not in line or line[tag_to_split] is None or len(line[tag_to_split])==0:
value = undefined
else:
value = line[tag_to_split]
if value not in selections:
selections[value] = Line_selection(i_view)
selections[value].append(i)
if pb is not None:
pb(len(i_view), force=True)
print("", file=sys.stderr)
# Create output views with the line selection
try:
for cat in selections:
o_view_name = config["split"]["prefix"].encode()+cat
o_view = selections[cat].materialize(o_view_name)
# Save command config in View and DMS comments
command_line = " ".join(sys.argv[1:])
input_dms_name=[input[0].name]
input_view_name=[input[1].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, "split", command_line, input_dms_name=input_dms_name, input_view_name=input_view_name)
o_view.close()
except Exception, e:
raise RollbackException("obi split error, rollbacking view: "+str(e), o_view)
i_dms.record_command_line(command_line)
i_dms.close(force=True)
logger("info", "Done.")

View File

@ -16,7 +16,7 @@ import sys
from cpython.exc cimport PyErr_CheckSignals from cpython.exc cimport PyErr_CheckSignals
__title__="Compute basic statistics for attribute values." __title__="Compute basic statistics for attribute values"
''' '''
`obi stats` computes basic statistics for attribute values of sequence records. `obi stats` computes basic statistics for attribute values of sequence records.
@ -119,9 +119,12 @@ def mean(values, options):
def variance(v): def variance(v):
if len(v)==1: if len(v)==1:
return 0 return 0
s = reduce(lambda x,y:(x[0]+y,x[1]+y**2),v,(0.,0.)) s = reduce(lambda x,y:(x[0]+y,x[1]+y**2),v,(0.,0.))
return s[1]/(len(v)-1) - s[0]**2/len(v)/(len(v)-1) var = round(s[1]/(len(v)-1) - s[0]**2/len(v)/(len(v)-1), 5) # round to go around shady python rounding stuff when var is actually 0
if var == -0.0: # then fix -0 to +0 if was rounded to -0
var = 0.0
return var
def varpop(values, options): def varpop(values, options):
@ -154,7 +157,7 @@ def run(config):
else : else :
taxo = None taxo = None
statistics = set(config['stats']['minimum']) | set(config['stats']['maximum']) | set(config['stats']['mean']) statistics = set(config['stats']['minimum']) | set(config['stats']['maximum']) | set(config['stats']['mean']) | set(config['stats']['var']) | set(config['stats']['sd'])
total = 0 total = 0
catcount={} catcount={}
totcount={} totcount={}
@ -195,7 +198,7 @@ def run(config):
except KeyError: except KeyError:
totcount[category]=totcount.get(category,0)+1 totcount[category]=totcount.get(category,0)+1
for var in statistics: for var in statistics:
if var in line: if var in line and line[var] is not None:
v = line[var] v = line[var]
if var not in values: if var not in values:
values[var]={} values[var]={}
@ -238,14 +241,34 @@ def run(config):
else: else:
sdvar= "%s" sdvar= "%s"
hcat = "\t".join([pcat % x for x in config['stats']['categories']]) + "\t" +\ hcat = ""
"\t".join([minvar % x for x in config['stats']['minimum']]) + "\t" +\
"\t".join([maxvar % x for x in config['stats']['maximum']]) + "\t" +\ for x in config['stats']['categories']:
"\t".join([meanvar % x for x in config['stats']['mean']]) + "\t" +\ hcat += pcat % x
"\t".join([varvar % x for x in config['stats']['var']]) + "\t" +\ hcat += "\t"
"\t".join([sdvar % x for x in config['stats']['sd']]) + \
"\t count" + \ for x in config['stats']['minimum']:
"\t total" hcat += minvar % x
hcat += "\t"
for x in config['stats']['maximum']:
hcat += maxvar % x
hcat += "\t"
for x in config['stats']['mean']:
hcat += meanvar % x
hcat += "\t"
for x in config['stats']['var']:
hcat += varvar % x
hcat += "\t"
for x in config['stats']['sd']:
hcat += sdvar % x
hcat += "\t"
hcat += "count\ttotal"
print(hcat) print(hcat)
sorted_stats = sorted(catcount.items(), key = lambda kv:(totcount[kv[0]]), reverse=True) sorted_stats = sorted(catcount.items(), key = lambda kv:(totcount[kv[0]]), reverse=True)
for i in range(len(sorted_stats)): for i in range(len(sorted_stats)):
@ -265,8 +288,8 @@ def run(config):
print((("%%%df" % lvarp[m]) % varp[m][c])+"\t", end="") print((("%%%df" % lvarp[m]) % varp[m][c])+"\t", end="")
for m in config['stats']['sd']: for m in config['stats']['sd']:
print((("%%%df" % lsigma[m]) % sigma[m][c])+"\t", end="") print((("%%%df" % lsigma[m]) % sigma[m][c])+"\t", end="")
print("%7d" %catcount[c], end="") print("%d" %catcount[c]+"\t", end="")
print("%9d" %totcount[c]) print("%d" %totcount[c]+"\t")
input[0].close(force=True) input[0].close(force=True)

View File

@ -15,7 +15,7 @@ from cpython.exc cimport PyErr_CheckSignals
from io import BufferedWriter from io import BufferedWriter
__title__="Keep the N last lines of a view." __title__="Keep the N last lines of a view"
def addOptions(parser): def addOptions(parser):

View File

@ -39,7 +39,7 @@ COL_COMMENTS_MAX_LEN = 2048
MAX_INT = 2147483647 # used to generate random float values MAX_INT = 2147483647 # used to generate random float values
__title__="Tests if the obitools are working properly" __title__="Test if the obitools are working properly"
default_config = { default_config = {
@ -301,8 +301,11 @@ def fill_column(config, infos, col) :
def create_random_column(config, infos) : def create_random_column(config, infos) :
alias = random.choice([b'', random_unique_name(infos)]) alias = random.choice([b'', random_unique_name(infos)])
tuples = random.choice([True, False]) tuples = random.choice([True, False])
dict_column = False
if not tuples : if not tuples :
nb_elements_per_line=random.randint(1, config['test']['maxelts']) nb_elements_per_line=random.randint(1, config['test']['maxelts'])
if nb_elements_per_line > 1:
dict_column = True
elements_names = [] elements_names = []
for i in range(nb_elements_per_line) : for i in range(nb_elements_per_line) :
elements_names.append(random_unique_element_name(config, infos)) elements_names.append(random_unique_element_name(config, infos))
@ -318,6 +321,7 @@ def create_random_column(config, infos) :
data_type, data_type,
nb_elements_per_line=nb_elements_per_line, nb_elements_per_line=nb_elements_per_line,
elements_names=elements_names, elements_names=elements_names,
dict_column=dict_column,
tuples=tuples, tuples=tuples,
comments=random_comments(config), comments=random_comments(config),
alias=alias alias=alias

View File

@ -354,8 +354,8 @@ cdef uniq_sequences(View_NUC_SEQS view, View_NUC_SEQS o_view, ProgressBar pb, di
key = mergedKeys[k] key = mergedKeys[k]
merged_col_name = mergedKeys_m[k] merged_col_name = mergedKeys_m[k]
if merged_infos[merged_col_name]['nb_elts'] == 1: # if merged_infos[merged_col_name]['nb_elts'] == 1:
raise Exception("Can't merge information from a tag with only one element (e.g. one sample ; don't use -m option)") # raise Exception("Can't merge information from a tag with only one element (e.g. one sample ; don't use -m option)")
if merged_col_name in view: if merged_col_name in view:
i_col = view[merged_col_name] i_col = view[merged_col_name]
@ -378,6 +378,7 @@ cdef uniq_sequences(View_NUC_SEQS view, View_NUC_SEQS o_view, ProgressBar pb, di
OBI_INT, OBI_INT,
nb_elements_per_line=merged_infos[merged_col_name]['nb_elts'], nb_elements_per_line=merged_infos[merged_col_name]['nb_elts'],
elements_names=list(merged_infos[merged_col_name]['elt_names']), elements_names=list(merged_infos[merged_col_name]['elt_names']),
dict_column=True,
comments=i_col.comments, comments=i_col.comments,
alias=merged_col_name alias=merged_col_name
) )
@ -400,6 +401,7 @@ cdef uniq_sequences(View_NUC_SEQS view, View_NUC_SEQS o_view, ProgressBar pb, di
OBI_INT, OBI_INT,
nb_elements_per_line=len(view), nb_elements_per_line=len(view),
elements_names=[id for id in i_id_col], elements_names=[id for id in i_id_col],
dict_column=True,
alias=TAXID_DIST_COLUMN alias=TAXID_DIST_COLUMN
) )

View File

@ -31,6 +31,7 @@ cdef extern from "obidmscolumn.h" nogil:
const_char_p elements_names const_char_p elements_names
OBIType_t returned_data_type OBIType_t returned_data_type
OBIType_t stored_data_type OBIType_t stored_data_type
bint dict_column
bint tuples bint tuples
bint to_eval bint to_eval
time_t creation_date time_t creation_date

View File

@ -8,6 +8,7 @@ cdef extern from "obi_ecopcr.h" nogil:
int obi_ecopcr(const char* input_dms_name, int obi_ecopcr(const char* input_dms_name,
const char* i_view_name, const char* i_view_name,
const char* tax_dms_name,
const char* taxonomy_name, const char* taxonomy_name,
const char* output_dms_name, const char* output_dms_name,
const char* o_view_name, const char* o_view_name,

View File

@ -53,6 +53,8 @@ cdef extern from "obitypes.h" nogil:
extern const_char_p OBIQual_char_NA extern const_char_p OBIQual_char_NA
extern uint8_t* OBIQual_int_NA extern uint8_t* OBIQual_int_NA
extern void* OBITuple_NA extern void* OBITuple_NA
extern obiint_t OBI_INT_MAX
const_char_p name_data_type(int data_type) const_char_p name_data_type(int data_type)

View File

@ -95,6 +95,7 @@ cdef extern from "obiview.h" nogil:
index_t nb_elements_per_line, index_t nb_elements_per_line,
char* elements_names, char* elements_names,
bint elt_names_formatted, bint elt_names_formatted,
bint dict_column,
bint tuples, bint tuples,
bint to_eval, bint to_eval,
const_char_p indexer_name, const_char_p indexer_name,

View File

@ -7,7 +7,8 @@ __OBIDMS_COLUMN_CLASS__ = {}
from ..capi.obitypes cimport name_data_type, \ from ..capi.obitypes cimport name_data_type, \
obitype_t, \ obitype_t, \
obiversion_t, \ obiversion_t, \
OBI_QUAL OBI_QUAL, \
OBI_STR
from ..capi.obidms cimport obi_import_column from ..capi.obidms cimport obi_import_column
@ -90,6 +91,7 @@ cdef class Column(OBIWrapper) :
obitype_t data_type, obitype_t data_type,
index_t nb_elements_per_line=1, index_t nb_elements_per_line=1,
list elements_names=None, list elements_names=None,
bint dict_column=False,
bint tuples=False, bint tuples=False,
bint to_eval=False, bint to_eval=False,
object associated_column_name=b"", object associated_column_name=b"",
@ -127,6 +129,10 @@ cdef class Column(OBIWrapper) :
else: else:
elements_names_p = NULL elements_names_p = NULL
if column_name_b == b"SAMPLE" or column_name_b == b"sample":
# force str type
data_type = OBI_STR
if data_type == OBI_QUAL: if data_type == OBI_QUAL:
if associated_column_name_b == b"": if associated_column_name_b == b"":
if column_name == QUALITY_COLUMN: if column_name == QUALITY_COLUMN:
@ -152,6 +158,7 @@ cdef class Column(OBIWrapper) :
nb_elements_per_line = nb_elements_per_line, nb_elements_per_line = nb_elements_per_line,
elements_names = elements_names_p, elements_names = elements_names_p,
elt_names_formatted = False, elt_names_formatted = False,
dict_column = dict_column,
tuples = tuples, tuples = tuples,
to_eval = to_eval, to_eval = to_eval,
indexer_name = NULL, indexer_name = NULL,
@ -200,7 +207,7 @@ cdef class Column(OBIWrapper) :
column_p = column_pp[0] column_p = column_pp[0]
column_type = column_p.header.returned_data_type column_type = column_p.header.returned_data_type
column_class = Column.get_column_class(column_type, (column_p.header.nb_elements_per_line > 1), column_p.header.tuples) column_class = Column.get_column_class(column_type, (column_p.header.nb_elements_per_line > 1 or column_p.header.dict_column == True), column_p.header.tuples)
column = OBIWrapper.new_wrapper(column_class, column_pp) column = OBIWrapper.new_wrapper(column_class, column_pp)
column._view = view column._view = view
@ -236,6 +243,7 @@ cdef class Column(OBIWrapper) :
nb_elements_per_line = -1, nb_elements_per_line = -1,
elements_names = NULL, elements_names = NULL,
elt_names_formatted = False, elt_names_formatted = False,
dict_column = False,
tuples = False, tuples = False,
to_eval = False, to_eval = False,
indexer_name = NULL, indexer_name = NULL,
@ -374,6 +382,13 @@ cdef class Column(OBIWrapper) :
raise OBIDeactivatedInstanceError() raise OBIDeactivatedInstanceError()
return self.pointer().header.nb_elements_per_line return self.pointer().header.nb_elements_per_line
# dict_column property getter
@property
def dict_column(self):
if not self.active() :
raise OBIDeactivatedInstanceError()
return self.pointer().header.dict_column
# data_type property getter # data_type property getter
@property @property
def data_type(self): def data_type(self):

View File

@ -38,11 +38,13 @@ cdef class Column_bool(Column):
object column_name, object column_name,
index_t nb_elements_per_line=1, index_t nb_elements_per_line=1,
object elements_names=None, object elements_names=None,
bint dict_column=False,
bint tuples=False, bint tuples=False,
object comments={}): object comments={}):
return Column.new_column(view, column_name, OBI_BOOL, return Column.new_column(view, column_name, OBI_BOOL,
nb_elements_per_line=nb_elements_per_line, nb_elements_per_line=nb_elements_per_line,
elements_names=elements_names, elements_names=elements_names,
dict_column=dict_column,
tuples=tuples, tuples=tuples,
comments=comments) comments=comments)

View File

@ -36,12 +36,14 @@ cdef class Column_char(Column):
object column_name, object column_name,
index_t nb_elements_per_line=1, index_t nb_elements_per_line=1,
object elements_names=None, object elements_names=None,
bint dict_column=False,
bint tuples=False, bint tuples=False,
object comments={}): object comments={}):
return Column.new_column(view, column_name, OBI_CHAR, return Column.new_column(view, column_name, OBI_CHAR,
nb_elements_per_line=nb_elements_per_line, nb_elements_per_line=nb_elements_per_line,
elements_names=elements_names, elements_names=elements_names,
dict_column=dict_column,
tuples=tuples, tuples=tuples,
comments=comments) comments=comments)

View File

@ -36,12 +36,14 @@ cdef class Column_float(Column):
object column_name, object column_name,
index_t nb_elements_per_line=1, index_t nb_elements_per_line=1,
object elements_names=None, object elements_names=None,
bint dict_column=False,
bint tuples=False, bint tuples=False,
object comments={}): object comments={}):
return Column.new_column(view, column_name, OBI_FLOAT, return Column.new_column(view, column_name, OBI_FLOAT,
nb_elements_per_line=nb_elements_per_line, nb_elements_per_line=nb_elements_per_line,
elements_names=elements_names, elements_names=elements_names,
dict_column=dict_column,
tuples=tuples, tuples=tuples,
comments=comments) comments=comments)

View File

@ -38,12 +38,14 @@ cdef class Column_int(Column):
object column_name, object column_name,
index_t nb_elements_per_line=1, index_t nb_elements_per_line=1,
object elements_names=None, object elements_names=None,
bint dict_column=False,
bint tuples=False, bint tuples=False,
object comments={}): object comments={}):
return Column.new_column(view, column_name, OBI_INT, return Column.new_column(view, column_name, OBI_INT,
nb_elements_per_line=nb_elements_per_line, nb_elements_per_line=nb_elements_per_line,
elements_names=elements_names, elements_names=elements_names,
dict_column=dict_column,
tuples=tuples, tuples=tuples,
comments=comments) comments=comments)

View File

@ -38,6 +38,7 @@ cdef class Column_qual(Column_idx):
object column_name, object column_name,
index_t nb_elements_per_line=1, index_t nb_elements_per_line=1,
object elements_names=None, object elements_names=None,
bint dict_column=False,
object associated_column_name=b"", object associated_column_name=b"",
int associated_column_version=-1, int associated_column_version=-1,
object comments={}): object comments={}):
@ -45,6 +46,7 @@ cdef class Column_qual(Column_idx):
return Column.new_column(view, column_name, OBI_QUAL, return Column.new_column(view, column_name, OBI_QUAL,
nb_elements_per_line=nb_elements_per_line, nb_elements_per_line=nb_elements_per_line,
elements_names=elements_names, elements_names=elements_names,
dict_column=dict_column,
tuples=False, tuples=False,
associated_column_name=associated_column_name, associated_column_name=associated_column_name,
associated_column_version=associated_column_name, associated_column_version=associated_column_name,

View File

@ -39,12 +39,14 @@ cdef class Column_seq(Column_idx):
object column_name, object column_name,
index_t nb_elements_per_line=1, index_t nb_elements_per_line=1,
object elements_names=None, object elements_names=None,
bint dict_column=False,
bint tuples=False, bint tuples=False,
object comments={}): object comments={}):
return Column.new_column(view, column_name, OBI_SEQ, return Column.new_column(view, column_name, OBI_SEQ,
nb_elements_per_line=nb_elements_per_line, nb_elements_per_line=nb_elements_per_line,
elements_names=elements_names, elements_names=elements_names,
dict_column=dict_column,
tuples=tuples, tuples=tuples,
comments=comments) comments=comments)

View File

@ -38,12 +38,14 @@ cdef class Column_str(Column_idx):
object column_name, object column_name,
index_t nb_elements_per_line=1, index_t nb_elements_per_line=1,
object elements_names=None, object elements_names=None,
bint dict_column=False,
bint tuples=False, bint tuples=False,
object comments={}): object comments={}):
return Column.new_column(view, column_name, OBI_STR, return Column.new_column(view, column_name, OBI_STR,
nb_elements_per_line=nb_elements_per_line, nb_elements_per_line=nb_elements_per_line,
elements_names=elements_names, elements_names=elements_names,
dict_column=dict_column,
tuples=tuples, tuples=tuples,
comments=comments) comments=comments)
@ -72,6 +74,9 @@ cdef class Column_str(Column_idx):
if value is None : if value is None :
value_b = <char*>OBIStr_NA value_b = <char*>OBIStr_NA
else : else :
if self.name == b'sample' or self.name == b'SAMPLE':
if type(value) == int:
value = str(value) # force sample ids to be str
value_bytes = tobytes(value) value_bytes = tobytes(value)
value_b = <char*>value_bytes value_b = <char*>value_bytes
@ -135,6 +140,9 @@ cdef class Column_multi_elts_str(Column_multi_elts_idx):
if value is None : if value is None :
value_b = <char*>OBIStr_NA value_b = <char*>OBIStr_NA
else : else :
if self.name == b'sample' or self.name == b'SAMPLE':
if type(value) == int:
value = str(value) # force sample ids to be str
value_bytes = tobytes(value) value_bytes = tobytes(value)
value_b = <char*>value_bytes value_b = <char*>value_bytes
@ -204,6 +212,9 @@ cdef class Column_tuples_str(Column_idx):
i = 0 i = 0
for elt in value : for elt in value :
if elt is not None and elt != '': if elt is not None and elt != '':
if self.name == b'sample' or self.name == b'SAMPLE':
if type(elt) == int:
elt = str(elt) # force sample ids to be str
elt_b = tobytes(elt) elt_b = tobytes(elt)
strcpy(array+i, <char*>elt_b) strcpy(array+i, <char*>elt_b)
i = i + len(elt_b) + 1 i = i + len(elt_b) + 1

View File

@ -1,5 +1,7 @@
#cython: language_level=3 #cython: language_level=3
import sys
from obitools3.utils cimport str2bytes, bytes2str, tobytes, tostr from obitools3.utils cimport str2bytes, bytes2str, tobytes, tostr
from ..capi.obidms cimport OBIDMS_p, obi_dms_get_full_path from ..capi.obidms cimport OBIDMS_p, obi_dms_get_full_path
@ -34,7 +36,7 @@ cdef class Taxonomy(OBIWrapper) :
return <OBIDMS_taxonomy_p>(self._pointer) return <OBIDMS_taxonomy_p>(self._pointer)
cdef fill_name_dict(self): cdef fill_name_dict(self):
print("Indexing taxon names...") print("Indexing taxon names...", file=sys.stderr)
cdef OBIDMS_taxonomy_p pointer = self.pointer() cdef OBIDMS_taxonomy_p pointer = self.pointer()
cdef ecotx_t* taxon_p cdef ecotx_t* taxon_p
@ -91,6 +93,8 @@ cdef class Taxonomy(OBIWrapper) :
raise RuntimeError("Error : Cannot read taxonomy %s" raise RuntimeError("Error : Cannot read taxonomy %s"
% tostr(name)) % tostr(name))
print("Taxonomy read", file=sys.stderr)
taxo = OBIWrapper.new_wrapper(Taxonomy, pointer) taxo = OBIWrapper.new_wrapper(Taxonomy, pointer)
dms.register(taxo) dms.register(taxo)
@ -146,7 +150,9 @@ cdef class Taxonomy(OBIWrapper) :
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))
print('Read %d taxa' % len(taxo), file=sys.stderr)
return taxo return taxo
@ -304,6 +310,11 @@ cdef class Taxonomy(OBIWrapper) :
def name(self): def name(self):
return self._name return self._name
# ranks property getter
@property
def ranks(self):
return self._ranks
def parental_tree_iterator(self, int taxid): def parental_tree_iterator(self, int taxid):
""" """

View File

@ -77,7 +77,7 @@ cdef class View(OBIWrapper) :
@staticmethod @staticmethod
def import_view(object dms_1, object dms_2, object view_name_1, object view_name_2): def import_view(object dms_1, object dms_2, object view_name_1, object view_name_2): # TODO argument to import line by line to avoid huge AVL copy
if obi_import_view(tobytes(dms_1), tobytes(dms_2), tobytes(view_name_1), tobytes(view_name_2)) < 0 : if obi_import_view(tobytes(dms_1), tobytes(dms_2), tobytes(view_name_1), tobytes(view_name_2)) < 0 :
raise Exception("Error importing a view") raise Exception("Error importing a view")
@ -343,9 +343,9 @@ cdef class View(OBIWrapper) :
new_column = Column.new_column(self, old_column.pointer().header.name, new_data_type, new_column = Column.new_column(self, old_column.pointer().header.name, new_data_type,
nb_elements_per_line=new_nb_elements_per_line, elements_names=new_elements_names, nb_elements_per_line=new_nb_elements_per_line, elements_names=new_elements_names,
comments=old_column.comments, alias=column_name_b+tobytes('___new___')) dict_column=(new_nb_elements_per_line>1), comments=old_column.comments, alias=column_name_b+tobytes('___new___'))
switch_to_dict = old_column.nb_elements_per_line == 1 and new_nb_elements_per_line > 1 switch_to_dict = not old_column.dict_column and new_nb_elements_per_line > 1
ori_key = old_column._elements_names[0] ori_key = old_column._elements_names[0]
for i in range(length) : for i in range(length) :
@ -404,6 +404,7 @@ cdef class View(OBIWrapper) :
col.data_type_int, col.data_type_int,
nb_elements_per_line = col.nb_elements_per_line, nb_elements_per_line = col.nb_elements_per_line,
elements_names = col._elements_names, elements_names = col._elements_names,
dict_column = col.dict_column,
tuples = col.tuples, tuples = col.tuples,
to_eval = col.to_eval, to_eval = col.to_eval,
comments = col.comments, comments = col.comments,
@ -599,7 +600,8 @@ cdef class View(OBIWrapper) :
if element is not None: if element is not None:
if element.comments[b"input_dms_name"] is not None : if element.comments[b"input_dms_name"] is not None :
for i in range(len(element.comments[b"input_dms_name"])) : for i in range(len(element.comments[b"input_dms_name"])) :
if element.comments[b"input_dms_name"][i] == element.dms.name and b"/" not in element.comments[b"input_view_name"][i]: # Same DMS and not a special element like a taxonomy if b"/" not in element.comments[b"input_view_name"][i] and element.comments[b"input_view_name"][i] in element.dms \
and element.comments[b"input_dms_name"][i] == element.dms.name : # Same DMS and not a special element like a taxonomy and view was not deleted
top_level.append(element.dms[element.comments[b"input_view_name"][i]]) top_level.append(element.dms[element.comments[b"input_view_name"][i]])
else: else:
top_level.append(None) top_level.append(None)
@ -797,7 +799,8 @@ cdef class Line :
def keys(self): def keys(self):
return self._view.keys() cdef bytes key
return [key for key in self._view.keys()]
def __contains__(self, object column_name): def __contains__(self, object column_name):

View File

@ -7,11 +7,12 @@ from obitools3.utils cimport bytes2str
cdef class FastaFormat: cdef class FastaFormat:
def __init__(self, list tags=[], bint printNAKeys=False, bytes NAString=b"NA"): def __init__(self, list tags=[], bint printNAKeys=False, bytes NAString=b"NA", bint NAIntTo0=False):
self.headerFormatter = HeaderFormat("fasta", self.headerFormatter = HeaderFormat("fasta",
tags=tags, tags=tags,
printNAKeys=printNAKeys, printNAKeys=printNAKeys,
NAString=NAString) NAString=NAString,
NAIntTo0=NAIntTo0)
@cython.boundscheck(False) @cython.boundscheck(False)
def __call__(self, object data): def __call__(self, object data):

View File

@ -8,11 +8,12 @@ from obitools3.utils cimport bytes2str, str2bytes, tobytes
# TODO quality offset option? # TODO quality offset option?
cdef class FastqFormat: cdef class FastqFormat:
def __init__(self, list tags=[], bint printNAKeys=False, bytes NAString=b"NA"): def __init__(self, list tags=[], bint printNAKeys=False, bytes NAString=b"NA", bint NAIntTo0=False):
self.headerFormatter = HeaderFormat("fastq", self.headerFormatter = HeaderFormat("fastq",
tags=tags, tags=tags,
printNAKeys=printNAKeys, printNAKeys=printNAKeys,
NAString=NAString) NAString=NAString,
NAIntTo0=NAIntTo0)
@cython.boundscheck(False) @cython.boundscheck(False)
def __call__(self, object data): def __call__(self, object data):

View File

@ -4,5 +4,6 @@ cdef class HeaderFormat:
cdef set tags cdef set tags
cdef bint printNAKeys cdef bint printNAKeys
cdef bytes NAString cdef bytes NAString
cdef bint NAIntTo0
cdef size_t headerBufferLength cdef size_t headerBufferLength

View File

@ -8,13 +8,14 @@ from obitools3.dms.capi.obiview cimport NUC_SEQUENCE_COLUMN, \
from obitools3.utils cimport str2bytes, bytes2str_object from obitools3.utils cimport str2bytes, bytes2str_object
from obitools3.dms.column.column cimport Column_line from obitools3.dms.column.column cimport Column_line
from obitools3.dms.column.typed_column.int cimport Column_int, Column_multi_elts_int
cdef class HeaderFormat: cdef class HeaderFormat:
SPECIAL_KEYS = [NUC_SEQUENCE_COLUMN, ID_COLUMN, DEFINITION_COLUMN, QUALITY_COLUMN] SPECIAL_KEYS = [NUC_SEQUENCE_COLUMN, ID_COLUMN, DEFINITION_COLUMN, QUALITY_COLUMN]
def __init__(self, str format="fasta", list tags=[], bint printNAKeys=False, bytes NAString=b"NA"): def __init__(self, str format="fasta", list tags=[], bint printNAKeys=False, bytes NAString=b"NA", bint NAIntTo0=False):
''' '''
@param format: @param format:
@type format: `str` @type format: `str`
@ -32,6 +33,7 @@ cdef class HeaderFormat:
self.tags = set(tags) self.tags = set(tags)
self.printNAKeys = printNAKeys self.printNAKeys = printNAKeys
self.NAString = NAString self.NAString = NAString
self.NAIntTo0 = NAIntTo0
if format=="fasta": if format=="fasta":
self.start=b">" self.start=b">"
@ -57,17 +59,25 @@ cdef class HeaderFormat:
if k in tags: if k in tags:
value = data[k] value = data[k]
if value is None or (isinstance(value, Column_line) and value.is_NA()): if value is None or (isinstance(value, Column_line) and value.is_NA()):
if self.printNAKeys: if isinstance(data.view[k], Column_int) and self.NAIntTo0: # people want missing int values to be 0
value = b'0'
elif self.printNAKeys:
value = self.NAString value = self.NAString
else: else:
value = None value = None
else: else:
if type(value) == Column_line: if type(value) == Column_line:
value = value.bytes() if isinstance(data.view[k], Column_multi_elts_int) and self.NAIntTo0:
value = dict(value)
for key in data.view[k].keys():
if key not in value or value[key]:
value[key] = 0
else:
value = value.bytes()
else: else:
if type(value) == tuple: if type(value) == tuple:
value=list(value) value=list(value)
value = str2bytes(str(bytes2str_object(value))) # genius programming value = str2bytes(str(bytes2str_object(value))) # genius programming
if value is not None: if value is not None:
lines.append(k + b"=" + value + b";") lines.append(k + b"=" + value + b";")

View File

@ -4,5 +4,8 @@ cdef class TabFormat:
cdef bint header cdef bint header
cdef bint first_line cdef bint first_line
cdef bytes NAString cdef bytes NAString
cdef list tags cdef set tags
cdef bytes sep cdef bytes sep
cdef bint NAIntTo0
cdef bint metabaR
cdef bint ngsfilter

View File

@ -4,57 +4,80 @@ cimport cython
from obitools3.dms.view.view cimport Line from obitools3.dms.view.view cimport Line
from obitools3.utils cimport bytes2str_object, str2bytes, tobytes from obitools3.utils cimport bytes2str_object, str2bytes, tobytes
from obitools3.dms.column.column cimport Column_line, Column_multi_elts from obitools3.dms.column.column cimport Column_line, Column_multi_elts
from obitools3.dms.column.typed_column.int cimport Column_int, Column_multi_elts_int
import sys import sys
cdef class TabFormat: cdef class TabFormat:
def __init__(self, header=True, bytes NAString=b"NA", bytes sep=b"\t"): def __init__(self, list tags=[], header=True, bytes NAString=b"NA", bytes sep=b"\t", bint NAIntTo0=True, metabaR=False, ngsfilter=False):
self.tags = set(tags)
self.header = header self.header = header
self.first_line = True self.first_line = True
self.NAString = NAString self.NAString = NAString
self.sep = sep self.sep = sep
self.NAIntTo0 = NAIntTo0
self.metabaR = metabaR
self.ngsfilter = ngsfilter
@cython.boundscheck(False) @cython.boundscheck(False)
def __call__(self, object data): def __call__(self, object data):
cdef set ktags
cdef list tags = [key for key in data]
line = [] line = []
if self.first_line: if self.tags is not None and self.tags:
self.tags = [k for k in data.keys()] ktags = self.tags
else:
ktags = set(tags)
if self.header and self.first_line: if self.header and self.first_line:
for k in self.tags: for k in ktags:
if isinstance(data.view[k], Column_multi_elts): if k in tags:
keys = data.view[k].keys() if self.metabaR:
keys.sort() if k == b'NUC_SEQ':
for k2 in keys: ktoprint = b'sequence'
line.append(tobytes(k)+b':'+tobytes(k2)) else:
else: ktoprint = k.lower()
line.append(tobytes(k)) ktoprint = ktoprint.replace(b'merged_', b'')
else:
ktoprint = k
if isinstance(data.view[k], Column_multi_elts):
keys = data.view[k].keys()
keys.sort()
for k2 in keys:
line.append(tobytes(ktoprint)+b':'+tobytes(k2))
else:
line.append(tobytes(ktoprint))
r = self.sep.join(value for value in line) r = self.sep.join(value for value in line)
r += b'\n' r += b'\n'
line = [] line = []
for k in self.tags: for k in ktags:
value = data[k] if k in tags:
if isinstance(data.view[k], Column_multi_elts): value = data[k]
keys = data.view[k].keys() if isinstance(data.view[k], Column_multi_elts):
keys.sort() keys = data.view[k].keys()
if value is None: # all keys at None keys.sort()
for k2 in keys: # TODO could be much more efficient if value is None: # all keys at None
line.append(self.NAString) for k2 in keys: # TODO could be much more efficient
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) line.append(self.NAString)
else: else:
if value is not None: for k2 in keys: # TODO could be much more efficient
line.append(str2bytes(str(bytes2str_object(value)))) if value[k2] is not None:
line.append(str2bytes(str(bytes2str_object(value[k2])))) # genius programming
else:
if self.NAIntTo0 and isinstance(data.view[k], Column_multi_elts_int):
line.append(b"0")
else:
line.append(self.NAString)
else: else:
line.append(self.NAString) if value is not None or (self.NAIntTo0 and isinstance(data.view[k], Column_int)):
line.append(str2bytes(str(bytes2str_object(value))))
else:
line.append(self.NAString)
if self.header and self.first_line: if self.header and self.first_line:
r += self.sep.join(value for value in line) r += self.sep.join(value for value in line)

View File

@ -22,11 +22,11 @@ from libc.stdlib cimport free, malloc, realloc
from libc.string cimport strcpy, strlen from libc.string cimport strcpy, strlen
_featureMatcher = re.compile(b'^FEATURES.+\n(?=ORIGIN )',re.DOTALL + re.M) _featureMatcher = re.compile(b'^FEATURES.+\n(?=ORIGIN(\s*))',re.DOTALL + re.M)
_headerMatcher = re.compile(b'^LOCUS.+(?=\nFEATURES)', re.DOTALL + re.M) _headerMatcher = re.compile(b'^LOCUS.+(?=\nFEATURES)', re.DOTALL + re.M)
_seqMatcher = re.compile(b'ORIGIN .+(?=//\n)', re.DOTALL + re.M) _seqMatcher = re.compile(b'^ORIGIN.+(?=//\n)', re.DOTALL + re.M)
_cleanSeq1 = re.compile(b'ORIGIN.+\n') _cleanSeq1 = re.compile(b'ORIGIN(\s*)\n')
_cleanSeq2 = re.compile(b'[ \n0-9]+') _cleanSeq2 = re.compile(b'[ \n0-9]+')
_acMatcher = re.compile(b'(?<=^ACCESSION ).+',re.M) _acMatcher = re.compile(b'(?<=^ACCESSION ).+',re.M)
_deMatcher = re.compile(b'(?<=^DEFINITION ).+\n( .+\n)*',re.M) _deMatcher = re.compile(b'(?<=^DEFINITION ).+\n( .+\n)*',re.M)
@ -155,10 +155,10 @@ def genbankIterator_file(lineiterator,
yield seq yield seq
read+=1 read+=1
# Last sequence # Last sequence if not empty lines
seq = genbankParser(entry) if entry.strip():
seq = genbankParser(entry)
yield seq yield seq
free(entry) free(entry)

View File

@ -48,13 +48,13 @@ def ngsfilterIterator(lineiterator,
all_lines.insert(0, firstline) all_lines.insert(0, firstline)
# Insert header for column names # Insert header for column names
column_names = [b"experiment", b"sample", b"forward_tag", b"reverse_tag", b"forward_primer", b"reverse_primer"] column_names = [b"experiment", b"sample", b"forward_tag", b"reverse_tag", b"forward_primer", b"reverse_primer",b"additional_info"]
header = out_sep.join(column_names) header = out_sep.join(column_names)
new_lines.append(header) new_lines.append(header)
for line in all_lines: for line in all_lines:
split_line = line.split() split_line = line.split(maxsplit=5)
tags = split_line.pop(2) tags = split_line.pop(2)
tags = tags.split(b":") tags = tags.split(b":")
for t_idx in range(len(tags)): for t_idx in range(len(tags)):
@ -64,7 +64,7 @@ def ngsfilterIterator(lineiterator,
tags.append(tags[0]) tags.append(tags[0])
split_line.insert(2, tags[0]) split_line.insert(2, tags[0])
split_line.insert(3, tags[1]) split_line.insert(3, tags[1])
new_lines.append(out_sep.join(split_line[0:6])) new_lines.append(out_sep.join(split_line[0:7]))
return tabIterator(iter(new_lines), return tabIterator(iter(new_lines),
header = True, header = True,

View File

@ -8,7 +8,7 @@ Created on feb 20th 2018
import types import types
from obitools3.utils cimport __etag__ from obitools3.utils cimport __etag__
from obitools3.utils cimport str2bytes
def tabIterator(lineiterator, def tabIterator(lineiterator,
bint header = False, bint header = False,
@ -75,7 +75,7 @@ def tabIterator(lineiterator,
continue continue
else: else:
# TODO ??? default column names? like R? # TODO ??? default column names? like R?
keys = [i for i in range(len(line.split(sep)))] keys = [str2bytes(str(i)) for i in range(len(line.split(sep)))]
while skipped < skip : while skipped < skip :
line = next(iterator) line = next(iterator)

View File

@ -53,7 +53,11 @@ def entryIteratorFactory(lineiterator,
i = iterator i = iterator
first=next(i) try:
first=next(i)
except StopIteration:
first=""
pass
format=b"tabular" format=b"tabular"

View File

@ -173,7 +173,10 @@ def open_uri(uri,
type newviewtype=View, type newviewtype=View,
dms_only=False, dms_only=False,
force_file=False): force_file=False):
if type(uri) == str and not uri.isascii():
raise Exception("Paths must be ASCII characters only")
cdef bytes urib = tobytes(uri) cdef bytes urib = tobytes(uri)
cdef bytes scheme cdef bytes scheme
cdef tuple dms cdef tuple dms
@ -192,7 +195,7 @@ def open_uri(uri,
config = getConfiguration() config = getConfiguration()
urip = urlparse(urib) urip = urlparse(urib)
if 'obi' not in config: if 'obi' not in config:
config['obi']={} config['obi']={}
@ -209,13 +212,14 @@ def open_uri(uri,
scheme = urip.scheme scheme = urip.scheme
error = None error = None
if urib != b"-" and \ if b'/taxonomy/' in urib or \
(urib != b"-" and \
(scheme==b"dms" or \ (scheme==b"dms" or \
(scheme==b"" and \ (scheme==b"" and \
(((not input) and "outputformat" not in config["obi"]) or \ (((not input) and "outputformat" not in config["obi"]) or \
(input and "inputformat" not in config["obi"])))): # TODO maybe not best way (input and "inputformat" not in config["obi"]))))): # TODO maybe not best way
if default_dms is not None and b"/" not in urip.path: # assuming view to open in default DMS (TODO discuss) if default_dms is not None and b"/" not in urip.path: # assuming view to open in default DMS (TODO discuss)
dms=(default_dms, urip.path) dms=(default_dms, urip.path)
else: else:
@ -223,7 +227,7 @@ def open_uri(uri,
if dms is None and default_dms is not None: if dms is None and default_dms is not None:
dms=(default_dms, urip.path) dms=(default_dms, urip.path)
if dms is not None: if dms is not None:
if dms_only: if dms_only:
return (dms[0], return (dms[0],
@ -248,7 +252,7 @@ def open_uri(uri,
if default_dms is None: if default_dms is None:
config["obi"]["defaultdms"]=resource[0] config["obi"]["defaultdms"]=resource[0]
return (resource[0], return (resource[0],
resource[1], resource[1],
type(resource[1]), type(resource[1]),
@ -276,7 +280,12 @@ def open_uri(uri,
iseq = urib iseq = urib
objclass = bytes objclass = bytes
else: # TODO update uopen to be able to write? else: # TODO update uopen to be able to write?
if not urip.path or urip.path == b'-': if config['obi']['outputformat'] == b'metabaR':
if 'metabarprefix' not in config['obi']:
raise Exception("Prefix needed when exporting for metabaR (--metabaR-prefix option)")
else:
file = open(config['obi']['metabarprefix']+'.tab', 'wb')
elif not urip.path or urip.path == b'-':
file = sys.stdout.buffer file = sys.stdout.buffer
else: else:
file = open(urip.path, 'wb') file = open(urip.path, 'wb')
@ -298,11 +307,11 @@ def open_uri(uri,
format=config["obi"][formatkey] format=config["obi"][formatkey]
except KeyError: except KeyError:
format=None format=None
if b'seqtype' in qualifiers: if b'seqtype' in qualifiers:
seqtype=qualifiers[b'seqtype'][0] seqtype=qualifiers[b'seqtype'][0]
else: else:
if format == b"ngsfilter" or format == b"tabular": # TODO discuss if format == b"ngsfilter" or format == b"tabular" or format == b"metabaR": # TODO discuss
seqtype=None seqtype=None
else: else:
try: try:
@ -386,10 +395,10 @@ def open_uri(uri,
raise MalformedURIException('Malformed header argument in URI') raise MalformedURIException('Malformed header argument in URI')
if b"sep" in qualifiers: if b"sep" in qualifiers:
sep=tobytes(qualifiers[b"sep"][0][0]) sep = tobytes(qualifiers[b"sep"][0][0])
else: else:
try: try:
sep=tobytes(config["obi"]["sep"]) sep = tobytes(config["obi"]["sep"])
except KeyError: except KeyError:
sep=None sep=None
@ -426,7 +435,21 @@ def open_uri(uri,
nastring=tobytes(config["obi"][nakey]) nastring=tobytes(config["obi"][nakey])
except KeyError: except KeyError:
nastring=b'NA' nastring=b'NA'
if b"na_int_to_0" in qualifiers:
try:
na_int_to_0=eval(qualifiers[b"na_int_to_0"][0])
except Exception as e:
raise MalformedURIException("Malformed 'NA_int_to_0' argument in URI")
else:
try:
na_int_to_0=config["obi"]["na_int_to_0"]
except KeyError:
if format==b"tabular" or format==b"metabaR":
na_int_to_0=True
else:
na_int_to_0=False
if b"stripwhite" in qualifiers: if b"stripwhite" in qualifiers:
try: try:
stripwhite=eval(qualifiers[b"stripwhite"][0]) stripwhite=eval(qualifiers[b"stripwhite"][0])
@ -461,17 +484,36 @@ def open_uri(uri,
except KeyError: except KeyError:
commentchar=b'#' commentchar=b'#'
if b"only_keys" in qualifiers:
only_keys=qualifiers[b"only_keys"][0] # not sure that works but no one ever uses qualifiers
else:
try:
only_keys_str=config["obi"]["only_keys"]
only_keys=[]
for key in only_keys_str:
only_keys.append(tobytes(key))
except KeyError:
only_keys=[]
if b"metabaR_prefix" in qualifiers:
metabaR_prefix = tobytes(qualifiers[b"metabaR_prefix"][0][0])
else:
try:
metabaR_prefix = tobytes(config["obi"]["metabarprefix"])
except KeyError:
metabaR_prefix=None
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" or format==b"silva": if format==b"fasta" or format==b"silva" or format==b"rdp":
if input: if input:
iseq = fastaNucIterator(file, iseq = fastaNucIterator(file,
skip=skip, skip=skip,
only=only, only=only,
nastring=nastring) nastring=nastring)
else: else:
iseq = FastaNucWriter(FastaFormat(printNAKeys=printna, NAString=nastring), iseq = FastaNucWriter(FastaFormat(tags=only_keys, printNAKeys=printna, NAString=nastring),
file, file,
skip=skip, skip=skip,
only=only) only=only)
@ -484,7 +526,7 @@ def open_uri(uri,
noquality=noquality, noquality=noquality,
nastring=nastring) nastring=nastring)
else: else:
iseq = FastqWriter(FastqFormat(printNAKeys=printna, NAString=nastring), iseq = FastqWriter(FastqFormat(tags=only_keys, printNAKeys=printna, NAString=nastring),
file, file,
skip=skip, skip=skip,
only=only) only=only)
@ -520,7 +562,17 @@ def open_uri(uri,
skip = skip, skip = skip,
only = only) only = only)
else: else:
iseq = TabWriter(TabFormat(header=header, NAString=nastring, sep=sep), iseq = TabWriter(TabFormat(tags=only_keys, header=header, NAString=nastring, sep=sep, NAIntTo0=na_int_to_0),
file,
skip=skip,
only=only,
header=header)
elif format==b"metabaR":
objclass = dict
if input:
raise NotImplementedError('Input data file format not implemented')
else:
iseq = TabWriter(TabFormat(tags=only_keys, header=header, NAString=nastring, sep=sep, NAIntTo0=na_int_to_0, metabaR=True),
file, file,
skip=skip, skip=skip,
only=only, only=only,
@ -538,7 +590,7 @@ def open_uri(uri,
skip = skip, skip = skip,
only = only) only = only)
else: else:
raise NotImplementedError('Output sequence file format not implemented') raise NotImplementedError('Output data file format not implemented')
else: else:
if input: if input:
iseq, objclass, format = entryIteratorFactory(file, iseq, objclass, format = entryIteratorFactory(file,
@ -556,7 +608,7 @@ def open_uri(uri,
commentchar) commentchar)
else: # default export is in fasta? or tab? TODO else: # default export is in fasta? or tab? TODO
objclass = Nuc_Seq # Nuc_Seq_Stored? TODO objclass = Nuc_Seq # Nuc_Seq_Stored? TODO
iseq = FastaNucWriter(FastaFormat(printNAKeys=printna, NAString=nastring), iseq = FastaNucWriter(FastaFormat(tags=only_keys, printNAKeys=printna, NAString=nastring),
file, file,
skip=skip, skip=skip,
only=only) only=only)
@ -565,6 +617,6 @@ def open_uri(uri,
entry_count = -1 entry_count = -1
if input: if input:
entry_count = count_entries(file, format) entry_count = count_entries(file, format, header)
return (file, iseq, objclass, urib, entry_count) return (file, iseq, objclass, urib, entry_count)

View File

@ -3,7 +3,7 @@
from obitools3.dms.capi.obitypes cimport obitype_t, index_t from obitools3.dms.capi.obitypes cimport obitype_t, index_t
cpdef bytes format_uniq_pattern(bytes format) cpdef bytes format_uniq_pattern(bytes format)
cpdef int count_entries(file, bytes format) cpdef int count_entries(file, bytes format, bint header)
cdef obi_errno_to_exception(index_t line_nb=*, object elt_id=*, str error_message=*) cdef obi_errno_to_exception(index_t line_nb=*, object elt_id=*, str error_message=*)
@ -18,7 +18,7 @@ cdef object clean_empty_values_from_object(object value, exclude=*)
cdef obitype_t get_obitype_single_value(object value) cdef obitype_t get_obitype_single_value(object value)
cdef obitype_t update_obitype(obitype_t obitype, object new_value) cdef obitype_t update_obitype(obitype_t obitype, object new_value)
cdef obitype_t get_obitype_iterable_value(object value) cdef obitype_t get_obitype_iterable_value(object value, type t)
cdef obitype_t get_obitype(object value) cdef obitype_t get_obitype(object value)
cdef object __etag__(bytes x, bytes nastring=*) cdef object __etag__(bytes x, bytes nastring=*)

View File

@ -9,7 +9,8 @@ from obitools3.dms.capi.obitypes cimport is_a_DNA_seq, \
OBI_QUAL, \ OBI_QUAL, \
OBI_SEQ, \ OBI_SEQ, \
OBI_STR, \ OBI_STR, \
index_t index_t, \
OBI_INT_MAX
from obitools3.dms.capi.obierrno cimport OBI_LINE_IDX_ERROR, \ from obitools3.dms.capi.obierrno cimport OBI_LINE_IDX_ERROR, \
OBI_ELT_IDX_ERROR, \ OBI_ELT_IDX_ERROR, \
@ -39,7 +40,7 @@ cpdef bytes format_uniq_pattern(bytes format):
return None return None
cpdef int count_entries(file, bytes format): cpdef int count_entries(file, bytes format, bint header):
try: try:
sep = format_uniq_pattern(format) sep = format_uniq_pattern(format)
@ -74,6 +75,8 @@ cpdef int count_entries(file, bytes format):
total_count += len(re.findall(sep, mmapped_file)) total_count += len(re.findall(sep, mmapped_file))
if format != b"ngsfilter" and format != b"tabular" and format != b"embl" and format != b"genbank" and format != b"fastq": if format != b"ngsfilter" and format != b"tabular" and format != b"embl" and format != b"genbank" and format != b"fastq":
total_count += 1 # adding +1 for 1st entry because separators include \n (ngsfilter and tabular already count one more because of last \n) total_count += 1 # adding +1 for 1st entry because separators include \n (ngsfilter and tabular already count one more because of last \n)
if format == b"tabular" and header: # not counting header as an entry
total_count -= 1
except: except:
if len(files) > 1: if len(files) > 1:
@ -257,38 +260,51 @@ cdef obitype_t update_obitype(obitype_t obitype, object new_value) :
new_type = type(new_value) new_type = type(new_value)
if obitype == OBI_INT : #if new_type == NoneType: # doesn't work because Cython sucks
if new_type == float : if new_value == None or new_type==list or new_type==dict or new_type==tuple:
return OBI_FLOAT return obitype
# TODO BOOL vers INT/FLOAT
elif new_type == str or new_type == bytes : # TODO BOOL to INT/FLOAT
if new_type == str or new_type == bytes :
if obitype == OBI_SEQ and is_a_DNA_seq(tobytes(new_value)) : if obitype == OBI_SEQ and is_a_DNA_seq(tobytes(new_value)) :
pass pass
else : else :
return OBI_STR return OBI_STR
elif obitype == OBI_INT :
if new_type == float or new_value > OBI_INT_MAX :
return OBI_FLOAT
return obitype return obitype
cdef obitype_t get_obitype_iterable_value(object value) : cdef obitype_t get_obitype_iterable_value(object value, type t) :
cdef obitype_t value_obitype cdef obitype_t value_obitype
value_obitype = OBI_VOID value_obitype = OBI_VOID
for k in value : if t == dict:
if value_obitype == OBI_VOID : for k in value :
value_obitype = get_obitype_single_value(value[k]) if value_obitype == OBI_VOID :
else : value_obitype = get_obitype_single_value(value[k])
value_obitype = update_obitype(value_obitype, value[k]) else :
value_obitype = update_obitype(value_obitype, value[k])
elif t == list or t == tuple:
for v in value :
if value_obitype == OBI_VOID :
value_obitype = get_obitype_single_value(v)
else :
value_obitype = update_obitype(value_obitype, v)
return value_obitype return value_obitype
cdef obitype_t get_obitype(object value) : cdef obitype_t get_obitype(object value) :
if type(value) == dict or type(value) == list or type(value) == tuple : t = type(value)
return get_obitype_iterable_value(value) if t == dict or t == list or t == tuple :
return get_obitype_iterable_value(value, t)
else : else :
return get_obitype_single_value(value) return get_obitype_single_value(value)

View File

@ -1,5 +1,5 @@
major = 3 major = 3
minor = 0 minor = 0
serial= '0b42' serial= '1b15'
version ="%d.%d.%s" % (major,minor,serial) version ="%d.%d.%s" % (major,minor,serial)

View File

@ -20,8 +20,6 @@ cdef class TabWriter:
self.only = -1 self.only = -1
else: else:
self.only = int(only) self.only = int(only)
if header:
self.only += 1
self.formatter = formatter self.formatter = formatter
self.output = output_object self.output = output_object

View File

@ -77,6 +77,7 @@ static inline ecotx_t* get_lca_from_merged_taxids(Obiview_p view, OBIDMS_column_
{ {
ecotx_t* taxon = NULL; ecotx_t* taxon = NULL;
ecotx_t* lca = NULL; ecotx_t* lca = NULL;
ecotx_t* lca1 = NULL;
int32_t taxid; int32_t taxid;
index_t taxid_idx; index_t taxid_idx;
int64_t taxid_str_idx; int64_t taxid_str_idx;
@ -108,10 +109,11 @@ static inline ecotx_t* get_lca_from_merged_taxids(Obiview_p view, OBIDMS_column_
else else
{ {
// Compute LCA // Compute LCA
lca1 = lca;
lca = obi_taxo_get_lca(taxon, lca); lca = obi_taxo_get_lca(taxon, lca);
if (lca == NULL) if (lca == NULL)
{ {
obidebug(1, "\nError getting the last common ancestor of two taxa when building a reference database"); obidebug(1, "\nError getting the last common ancestor of two taxa when building a reference database, %d %d", taxid, lca1->taxid);
return NULL; return NULL;
} }
} }
@ -185,7 +187,7 @@ int build_reference_db(const char* dms_name,
matrix_view_name = strcpy(matrix_view_name, o_view_name); matrix_view_name = strcpy(matrix_view_name, o_view_name);
strcat(matrix_view_name, "_matrix"); strcat(matrix_view_name, "_matrix");
fprintf(stderr, "Aligning queries with reference database...\n"); fprintf(stderr, "Aligning sequences...\n");
if (obi_lcs_align_one_column(dms_name, if (obi_lcs_align_one_column(dms_name,
refs_view_name, refs_view_name,
"", "",
@ -243,6 +245,7 @@ int build_reference_db(const char* dms_name,
false, false,
false, false,
false, false,
false,
"", "",
"", "",
-1, -1,
@ -392,6 +395,7 @@ int build_reference_db(const char* dms_name,
1, 1,
"", "",
false, false,
false,
true, true,
false, false,
"", "",
@ -415,6 +419,7 @@ int build_reference_db(const char* dms_name,
1, 1,
"", "",
false, false,
false,
true, true,
false, false,
"", "",
@ -860,7 +865,8 @@ int build_reference_db(const char* dms_name,
fprintf(stderr,"\rDone : 100 %% \n"); fprintf(stderr,"\rDone : 100 %% \n");
// Add information about the threshold used to build the DB // Add information about the threshold used to build the DB
snprintf(threshold_str, 5, "%f", threshold); #define snprintf_nowarn(...) (snprintf(__VA_ARGS__) < 0 ? abort() : (void)0)
snprintf_nowarn(threshold_str, 5, "%f", threshold);
new_comments = obi_add_comment((o_view->infos)->comments, DB_THRESHOLD_KEY_IN_COMMENTS, threshold_str); new_comments = obi_add_comment((o_view->infos)->comments, DB_THRESHOLD_KEY_IN_COMMENTS, threshold_str);
if (new_comments == NULL) if (new_comments == NULL)

View File

@ -77,7 +77,6 @@ Obi_ali_p kmer_similarity(Obiview_p view1, OBIDMS_column_p column1, index_t idx1
int32_t* shift_count_array; int32_t* shift_count_array;
Obi_ali_p ali = NULL; Obi_ali_p ali = NULL;
int i, j; int i, j;
bool switched_seqs;
bool reversed; bool reversed;
int score = 0; int score = 0;
Obi_blob_p blob1 = NULL; Obi_blob_p blob1 = NULL;
@ -124,6 +123,8 @@ Obi_ali_p kmer_similarity(Obiview_p view1, OBIDMS_column_p column1, index_t idx1
bool keep_seq2_start; bool keep_seq2_start;
bool keep_seq1_end; bool keep_seq1_end;
bool keep_seq2_end; bool keep_seq2_end;
bool left_ali;
bool rev_quals = false;
// Check kmer size // Check kmer size
if ((kmer_size < 1) || (kmer_size > 4)) if ((kmer_size < 1) || (kmer_size > 4))
@ -148,19 +149,8 @@ Obi_ali_p kmer_similarity(Obiview_p view1, OBIDMS_column_p column1, index_t idx1
} }
// Choose the shortest sequence to save kmer positions in array // Choose the shortest sequence to save kmer positions in array
switched_seqs = false;
len1 = blob1->length_decoded_value; len1 = blob1->length_decoded_value;
len2 = blob2->length_decoded_value; len2 = blob2->length_decoded_value;
if (len2 < len1)
{
switched_seqs = true;
temp_len = len1;
len1 = len2;
len2 = temp_len;
temp_blob = blob1;
blob1 = blob2;
blob2 = temp_blob;
}
// Force encoding on 2 bits by replacing ambiguous nucleotides by 'a's // Force encoding on 2 bits by replacing ambiguous nucleotides by 'a's
if (blob1->element_size == 4) if (blob1->element_size == 4)
@ -196,7 +186,47 @@ Obi_ali_p kmer_similarity(Obiview_p view1, OBIDMS_column_p column1, index_t idx1
else else
reversed = false; reversed = false;
if (reversed) if (reversed)
switched_seqs = !switched_seqs; // unreverse to make cases simpler. Costly but rare (direct match is reverse primer match)
{
if (seq2 == NULL)
seq2 = obi_blob_to_seq(blob2);
seq2 = reverse_complement_sequence(seq2);
blob2 = obi_seq_to_blob(seq2);
if (seq1 == NULL)
seq1 = obi_blob_to_seq(blob1);
seq1 = reverse_complement_sequence(seq1);
blob1 = obi_seq_to_blob(seq1);
free_blob1 = true;
// Get the quality arrays
qual1 = obi_get_qual_int_with_elt_idx_and_col_p_in_view(view1, qual_col1, idx1, 0, &qual1_len);
if (qual1 == NULL)
{
obidebug(1, "\nError getting the quality of the 1st sequence when computing the kmer similarity between two sequences");
return NULL;
}
qual2 = obi_get_qual_int_with_elt_idx_and_col_p_in_view(view2, qual_col2, idx2, 0, &qual2_len);
if (qual2 == NULL)
{
obidebug(1, "\nError getting the quality of the 2nd sequence when computing the kmer similarity between two sequences");
return NULL;
}
uint8_t* newqual1 = malloc(qual1_len*sizeof(uint8_t));
uint8_t* newqual2 = malloc(qual2_len*sizeof(uint8_t));
for (i=0;i<qual1_len;i++)
newqual1[i] = qual1[qual1_len-1-i];
for (i=0;i<qual2_len;i++)
newqual2[i] = qual2[qual2_len-1-i];
qual1 = newqual1;
qual2 = newqual2;
rev_quals = true;
}
// Save total length for the shift counts array // Save total length for the shift counts array
total_len = len1 + len2 + 1; // +1 for shift 0 total_len = len1 + len2 + 1; // +1 for shift 0
@ -237,7 +267,7 @@ Obi_ali_p kmer_similarity(Obiview_p view1, OBIDMS_column_p column1, index_t idx1
return NULL; return NULL;
} }
} }
else if (len1 >= shift_array_height) else if (total_len >= shift_array_height)
{ {
shift_array_height = total_len; shift_array_height = total_len;
*shift_array_p = (int32_t*) realloc(*shift_array_p, ARRAY_LENGTH * shift_array_height * sizeof(int32_t)); *shift_array_p = (int32_t*) realloc(*shift_array_p, ARRAY_LENGTH * shift_array_height * sizeof(int32_t));
@ -291,7 +321,7 @@ Obi_ali_p kmer_similarity(Obiview_p view1, OBIDMS_column_p column1, index_t idx1
*shift_array_height_p = shift_array_height; *shift_array_height_p = shift_array_height;
*shift_count_array_length_p = shift_count_array_length; *shift_count_array_length_p = shift_count_array_length;
// Fill array with positions of kmers in the shortest sequence // Fill array with positions of kmers in the first sequence
encoding = blob1->element_size; encoding = blob1->element_size;
kmer_count = len1 - kmer_size + 1; kmer_count = len1 - kmer_size + 1;
for (kmer_idx=0; kmer_idx < kmer_count; kmer_idx++) for (kmer_idx=0; kmer_idx < kmer_count; kmer_idx++)
@ -310,7 +340,7 @@ Obi_ali_p kmer_similarity(Obiview_p view1, OBIDMS_column_p column1, index_t idx1
kmer_pos_array[(kmer*kmer_pos_array_height)+i] = kmer_idx; kmer_pos_array[(kmer*kmer_pos_array_height)+i] = kmer_idx;
} }
// Compare positions of kmers between both sequences and store shifts // Compare positions of kmers between both sequences and store shifts (a shift corresponds to pos2 - pos1)
kmer_count = blob2->length_decoded_value - kmer_size + 1; kmer_count = blob2->length_decoded_value - kmer_size + 1;
for (kmer_idx=0; kmer_idx < kmer_count; kmer_idx++) for (kmer_idx=0; kmer_idx < kmer_count; kmer_idx++)
{ {
@ -374,35 +404,42 @@ Obi_ali_p kmer_similarity(Obiview_p view1, OBIDMS_column_p column1, index_t idx1
// The 873863 cases of hell // The 873863 cases of hell
if (best_shift > 0) if (best_shift > 0)
{ {
left_ali = false;
overlap_len = len2 - best_shift; overlap_len = len2 - best_shift;
if (len1 <= overlap_len) if (len1 <= overlap_len)
{ {
overlap_len = len1; overlap_len = len1;
if (! switched_seqs) keep_seq2_end = true;
keep_seq2_end = true;
else
keep_seq2_start = true;
}
else if (switched_seqs)
{
keep_seq2_start = true;
keep_seq1_end = true;
} }
} }
else if (best_shift < 0) else if (best_shift < 0)
{ {
left_ali = true;
overlap_len = len1 + best_shift; overlap_len = len1 + best_shift;
if (!switched_seqs) if (len2 <= overlap_len)
{ {
keep_seq1_start = true; overlap_len = len2;
keep_seq2_end = true; keep_seq1_start = true;
} }
} else
else {
{ keep_seq1_start = true;
overlap_len = len1;
if ((!switched_seqs) && (len2 > len1))
keep_seq2_end = true; keep_seq2_end = true;
}
}
else // if (best_shift == 0)
{
if (len2 >= len1)
{
overlap_len = len1;
keep_seq2_end = true;
left_ali = true;
}
else
{
overlap_len = len2;
left_ali = false; // discussable
}
} }
ali = (Obi_ali_p) malloc(sizeof(Obi_ali_t)); ali = (Obi_ali_p) malloc(sizeof(Obi_ali_t));
@ -433,7 +470,7 @@ Obi_ali_p kmer_similarity(Obiview_p view1, OBIDMS_column_p column1, index_t idx1
ali->direction[0] = '\0'; ali->direction[0] = '\0';
else else
{ {
if (((best_shift <= 0) && (!switched_seqs)) || ((best_shift > 0) && switched_seqs)) if (left_ali)
strcpy(ali->direction, "left"); strcpy(ali->direction, "left");
else else
strcpy(ali->direction, "right"); strcpy(ali->direction, "right");
@ -442,28 +479,28 @@ Obi_ali_p kmer_similarity(Obiview_p view1, OBIDMS_column_p column1, index_t idx1
// Build the consensus sequence if asked // Build the consensus sequence if asked
if (build_consensus) if (build_consensus)
{ {
// Get the quality arrays if (! rev_quals)
qual1 = obi_get_qual_int_with_elt_idx_and_col_p_in_view(view1, qual_col1, idx1, 0, &qual1_len);
if (qual1 == NULL)
{ {
obidebug(1, "\nError getting the quality of the 1st sequence when computing the kmer similarity between two sequences"); // Get the quality arrays
return NULL; qual1 = obi_get_qual_int_with_elt_idx_and_col_p_in_view(view1, qual_col1, idx1, 0, &qual1_len);
} if (qual1 == NULL)
qual2 = obi_get_qual_int_with_elt_idx_and_col_p_in_view(view2, qual_col2, idx2, 0, &qual2_len); {
if (qual2 == NULL) obidebug(1, "\nError getting the quality of the 1st sequence when computing the kmer similarity between two sequences");
{ return NULL;
obidebug(1, "\nError getting the quality of the 2nd sequence when computing the kmer similarity between two sequences"); }
return NULL; qual2 = obi_get_qual_int_with_elt_idx_and_col_p_in_view(view2, qual_col2, idx2, 0, &qual2_len);
if (qual2 == NULL)
{
obidebug(1, "\nError getting the quality of the 2nd sequence when computing the kmer similarity between two sequences");
return NULL;
}
} }
// Decode the first sequence if not already done // Decode the first sequence if not already done
if (seq1 == NULL) if (seq1 == NULL)
seq1 = obi_blob_to_seq(blob1); seq1 = obi_blob_to_seq(blob1);
if (! switched_seqs) consensus_len = len2 - best_shift;
consensus_len = len2 - best_shift;
else
consensus_len = len1 + best_shift;
// Allocate memory for consensus sequence // Allocate memory for consensus sequence
consensus_seq = (char*) malloc(consensus_len + 1 * sizeof(char)); // TODO keep malloced too maybe consensus_seq = (char*) malloc(consensus_len + 1 * sizeof(char)); // TODO keep malloced too maybe
@ -557,6 +594,12 @@ Obi_ali_p kmer_similarity(Obiview_p view1, OBIDMS_column_p column1, index_t idx1
free(seq2); free(seq2);
free(blob2); free(blob2);
if (rev_quals)
{
free(qual1);
free(qual2);
}
return ali; return ali;
} }

View File

@ -88,42 +88,42 @@ static int create_output_columns(Obiview_p o_view,
int sample_count) int sample_count)
{ {
// Status column // Status column
if (obi_view_add_column(o_view, CLEAN_STATUS_COLUMN_NAME, -1, NULL, OBI_CHAR, 0, sample_count, (sample_column->header)->elements_names, true, false, false, NULL, NULL, -1, CLEAN_STATUS_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, CLEAN_STATUS_COLUMN_NAME, -1, NULL, OBI_CHAR, 0, sample_count, (sample_column->header)->elements_names, true, true, false, false, NULL, NULL, -1, CLEAN_STATUS_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", CLEAN_STATUS_COLUMN_NAME); obidebug(1, "\nError creating the %s column", CLEAN_STATUS_COLUMN_NAME);
return -1; return -1;
} }
// Head column // Head column
if (obi_view_add_column(o_view, CLEAN_HEAD_COLUMN_NAME, -1, NULL, OBI_BOOL, 0, 1, NULL, false, false, false, NULL, NULL, -1, CLEAN_HEAD_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, CLEAN_HEAD_COLUMN_NAME, -1, NULL, OBI_BOOL, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, CLEAN_HEAD_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", CLEAN_HEAD_COLUMN_NAME); obidebug(1, "\nError creating the %s column", CLEAN_HEAD_COLUMN_NAME);
return -1; return -1;
} }
// Sample count column // Sample count column
if (obi_view_add_column(o_view, CLEAN_SAMPLECOUNT_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, CLEAN_SAMPLECOUNT_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, CLEAN_SAMPLECOUNT_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, CLEAN_SAMPLECOUNT_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", CLEAN_SAMPLECOUNT_COLUMN_NAME); obidebug(1, "\nError creating the %s column", CLEAN_SAMPLECOUNT_COLUMN_NAME);
return -1; return -1;
} }
// Head count column // Head count column
if (obi_view_add_column(o_view, CLEAN_HEADCOUNT_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, CLEAN_HEADCOUNT_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, CLEAN_HEADCOUNT_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, CLEAN_HEADCOUNT_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", CLEAN_HEADCOUNT_COLUMN_NAME); obidebug(1, "\nError creating the %s column", CLEAN_HEADCOUNT_COLUMN_NAME);
return -1; return -1;
} }
// Internal count column // Internal count column
if (obi_view_add_column(o_view, CLEAN_INTERNALCOUNT_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, CLEAN_INTERNALCOUNT_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, CLEAN_INTERNALCOUNT_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, CLEAN_INTERNALCOUNT_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", CLEAN_INTERNALCOUNT_COLUMN_NAME); obidebug(1, "\nError creating the %s column", CLEAN_INTERNALCOUNT_COLUMN_NAME);
return -1; return -1;
} }
// Singleton count column // Singleton count column
if (obi_view_add_column(o_view, CLEAN_SINGLETONCOUNT_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, CLEAN_SINGLETONCOUNT_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, CLEAN_SINGLETONCOUNT_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, CLEAN_SINGLETONCOUNT_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", CLEAN_SINGLETONCOUNT_COLUMN_NAME); obidebug(1, "\nError creating the %s column", CLEAN_SINGLETONCOUNT_COLUMN_NAME);
return -1; return -1;
@ -229,6 +229,8 @@ int obi_clean(const char* dms_name,
return -1; return -1;
} }
seq_count = (i_view->infos)->line_count;
// Open the sequence column // Open the sequence column
if (strcmp((i_view->infos)->view_type, VIEW_TYPE_NUC_SEQS) == 0) if (strcmp((i_view->infos)->view_type, VIEW_TYPE_NUC_SEQS) == 0)
iseq_column = obi_view_get_column(i_view, NUC_SEQUENCE_COLUMN); iseq_column = obi_view_get_column(i_view, NUC_SEQUENCE_COLUMN);
@ -245,7 +247,7 @@ int obi_clean(const char* dms_name,
} }
// Open the sample column if there is one // Open the sample column if there is one
if ((strcmp(sample_column_name, "") == 0) || (sample_column_name == NULL)) if ((strcmp(sample_column_name, "") == 0) || (sample_column_name == NULL) || (seq_count == 0))
{ {
fprintf(stderr, "Info: No sample information provided, assuming one sample.\n"); fprintf(stderr, "Info: No sample information provided, assuming one sample.\n");
sample_column = obi_view_get_column(i_view, COUNT_COLUMN); sample_column = obi_view_get_column(i_view, COUNT_COLUMN);
@ -340,66 +342,67 @@ int obi_clean(const char* dms_name,
return -1; return -1;
} }
// Build kmer tables if (seq_count > 0)
ktable = hash_seq_column(i_view, iseq_column, 0);
if (ktable == NULL)
{ {
obi_set_errno(OBI_CLEAN_ERROR); // Build kmer tables
obidebug(1, "\nError building kmer tables before aligning"); ktable = hash_seq_column(i_view, iseq_column, 0);
return -1; if (ktable == NULL)
} {
obi_set_errno(OBI_CLEAN_ERROR);
obidebug(1, "\nError building kmer tables before aligning");
return -1;
}
seq_count = (i_view->infos)->line_count; // Allocate arrays for sample counts otherwise reading in mapped files takes longer
complete_sample_count_array = (int*) malloc(seq_count * sample_count * sizeof(int));
// Allocate arrays for sample counts otherwise reading in mapped files takes longer if (complete_sample_count_array == NULL)
complete_sample_count_array = (int*) malloc(seq_count * sample_count * sizeof(int)); {
if (complete_sample_count_array == NULL) obi_set_errno(OBI_MALLOC_ERROR);
{ obidebug(1, "\nError allocating memory for the array of sample counts, size: %lld", seq_count * sample_count * sizeof(int));
obi_set_errno(OBI_MALLOC_ERROR); return -1;
obidebug(1, "\nError allocating memory for the array of sample counts, size: %lld", seq_count * sample_count * sizeof(int)); }
return -1;
}
for (samp=0; samp < sample_count; samp++)
{
for (k=0; k<seq_count; k++)
complete_sample_count_array[k+(samp*seq_count)] = obi_get_int_with_elt_idx_and_col_p_in_view(i_view, sample_column, k, samp);
}
// Allocate arrays for blobs otherwise reading in mapped files takes longer
blob_array = (Obi_blob_p*) malloc(seq_count * sizeof(Obi_blob_p));
if (blob_array == NULL)
{
obi_set_errno(OBI_MALLOC_ERROR);
obidebug(1, "\nError allocating memory for the array of blobs");
return -1;
}
for (k=0; k<seq_count; k++)
{
blob_array[k] = obi_get_blob_with_elt_idx_and_col_p_in_view(i_view, iseq_column, k, 0);
}
// Allocate alignment result array (byte at 0 if not aligned yet,
// 1 if sequence at index has a similarity above the threshold with the current sequence,
// 2 if sequence at index has a similarity below the threshold with the current sequence)
alignment_result_array = (byte_t*) calloc(seq_count, sizeof(byte_t));
if (alignment_result_array == NULL)
{
obi_set_errno(OBI_MALLOC_ERROR);
obidebug(1, "\nError allocating memory for alignment result array");
return -1;
}
// Initialize all sequences to singletons or NA if no sequences in that sample
for (k=0; k<seq_count; k++)
{
for (samp=0; samp < sample_count; samp++) for (samp=0; samp < sample_count; samp++)
{ {
if (obi_get_int_with_elt_idx_and_col_p_in_view(i_view, sample_column, k, samp) != OBIInt_NA) // Only initialize samples where there are some sequences for (k=0; k<seq_count; k++)
complete_sample_count_array[k+(samp*seq_count)] = obi_get_int_with_elt_idx_and_col_p_in_view(i_view, sample_column, k, samp);
}
// Allocate arrays for blobs otherwise reading in mapped files takes longer
blob_array = (Obi_blob_p*) malloc(seq_count * sizeof(Obi_blob_p));
if (blob_array == NULL)
{
obi_set_errno(OBI_MALLOC_ERROR);
obidebug(1, "\nError allocating memory for the array of blobs");
return -1;
}
for (k=0; k<seq_count; k++)
{
blob_array[k] = obi_get_blob_with_elt_idx_and_col_p_in_view(i_view, iseq_column, k, 0);
}
// Allocate alignment result array (byte at 0 if not aligned yet,
// 1 if sequence at index has a similarity above the threshold with the current sequence,
// 2 if sequence at index has a similarity below the threshold with the current sequence)
alignment_result_array = (byte_t*) calloc(seq_count, sizeof(byte_t));
if (alignment_result_array == NULL)
{
obi_set_errno(OBI_MALLOC_ERROR);
obidebug(1, "\nError allocating memory for alignment result array");
return -1;
}
// Initialize all sequences to singletons or NA if no sequences in that sample
for (k=0; k<seq_count; k++)
{
for (samp=0; samp < sample_count; samp++)
{ {
if (obi_set_char_with_elt_idx_and_col_p_in_view(o_view, status_column, k, samp, 's') < 0) if (obi_get_int_with_elt_idx_and_col_p_in_view(i_view, sample_column, k, samp) != OBIInt_NA) // Only initialize samples where there are some sequences
{ {
obidebug(1, "\nError initializing all sequences to singletons"); if (obi_set_char_with_elt_idx_and_col_p_in_view(o_view, status_column, k, samp, 's') < 0)
return -1; {
obidebug(1, "\nError initializing all sequences to singletons");
return -1;
}
} }
} }
} }
@ -551,17 +554,20 @@ int obi_clean(const char* dms_name,
} }
} }
free_kmer_tables(ktable, seq_count); if (seq_count > 0)
free(complete_sample_count_array); {
free(blob_array); free_kmer_tables(ktable, seq_count);
free(alignment_result_array); free(complete_sample_count_array);
free(blob_array);
free(alignment_result_array);
}
fprintf(stderr, "\n"); fprintf(stderr, "\n");
if (stop) if (stop)
return -1; return -1;
if (heads_only) if (heads_only && (seq_count > 0))
{ {
line_selection = malloc((((o_view->infos)->line_count) + 1) * sizeof(index_t)); line_selection = malloc((((o_view->infos)->line_count) + 1) * sizeof(index_t));
if (line_selection == NULL) if (line_selection == NULL)
@ -635,7 +641,7 @@ int obi_clean(const char* dms_name,
} }
// Flag the end of the line selection // Flag the end of the line selection
if (heads_only) if (heads_only && (seq_count > 0))
line_selection[l] = -1; line_selection[l] = -1;
// Create new view with line selection if heads only // Create new view with line selection if heads only

View File

@ -150,49 +150,49 @@ static int print_seq(Obiview_p i_view, Obiview_p o_view,
static int create_output_columns(Obiview_p o_view, bool kingdom_mode) static int create_output_columns(Obiview_p o_view, bool kingdom_mode)
{ {
// Original length column // Original length column
if (obi_view_add_column(o_view, ECOPCR_SEQLEN_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_SEQLEN_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_SEQLEN_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_SEQLEN_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_SEQLEN_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_SEQLEN_COLUMN_NAME);
return -1; return -1;
} }
// Amplicon length column // Amplicon length column
if (obi_view_add_column(o_view, ECOPCR_AMPLICONLEN_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_AMPLICONLEN_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_AMPLICONLEN_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_AMPLICONLEN_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_AMPLICONLEN_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_AMPLICONLEN_COLUMN_NAME);
return -1; return -1;
} }
// Taxid column // Taxid column
if (obi_view_add_column(o_view, TAXID_COLUMN, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, TAXID_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, TAXID_COLUMN, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, TAXID_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", TAXID_COLUMN); obidebug(1, "\nError creating the %s column", TAXID_COLUMN);
return -1; return -1;
} }
// Taxonomic rank column // Taxonomic rank column
if (obi_view_add_column(o_view, ECOPCR_RANK_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_RANK_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_RANK_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_RANK_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_RANK_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_RANK_COLUMN_NAME);
return -1; return -1;
} }
// Species taxid column // Species taxid column
if (obi_view_add_column(o_view, ECOPCR_SPECIES_TAXID_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_SPECIES_TAXID_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_SPECIES_TAXID_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_SPECIES_TAXID_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_SPECIES_TAXID_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_SPECIES_TAXID_COLUMN_NAME);
return -1; return -1;
} }
// Genus taxid column // Genus taxid column
if (obi_view_add_column(o_view, ECOPCR_GENUS_TAXID_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_GENUS_TAXID_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_GENUS_TAXID_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_GENUS_TAXID_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_GENUS_TAXID_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_GENUS_TAXID_COLUMN_NAME);
return -1; return -1;
} }
// Family taxid column // Family taxid column
if (obi_view_add_column(o_view, ECOPCR_FAMILY_TAXID_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_FAMILY_TAXID_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_FAMILY_TAXID_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_FAMILY_TAXID_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_FAMILY_TAXID_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_FAMILY_TAXID_COLUMN_NAME);
return -1; return -1;
@ -201,7 +201,7 @@ static int create_output_columns(Obiview_p o_view, bool kingdom_mode)
if (kingdom_mode) if (kingdom_mode)
{ {
// Kingdom taxid column // Kingdom taxid column
if (obi_view_add_column(o_view, ECOPCR_KINGDOM_TAXID_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_KINGDOM_TAXID_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_KINGDOM_TAXID_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_KINGDOM_TAXID_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_KINGDOM_TAXID_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_KINGDOM_TAXID_COLUMN_NAME);
return -1; return -1;
@ -210,7 +210,7 @@ static int create_output_columns(Obiview_p o_view, bool kingdom_mode)
else else
{ {
// Superkingdom taxid column // Superkingdom taxid column
if (obi_view_add_column(o_view, ECOPCR_SUPERKINGDOM_TAXID_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_SUPERKINGDOM_TAXID_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_SUPERKINGDOM_TAXID_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_SUPERKINGDOM_TAXID_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_SUPERKINGDOM_TAXID_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_SUPERKINGDOM_TAXID_COLUMN_NAME);
return -1; return -1;
@ -218,28 +218,28 @@ static int create_output_columns(Obiview_p o_view, bool kingdom_mode)
} }
// Scientific name column // Scientific name column
if (obi_view_add_column(o_view, ECOPCR_SCIENTIFIC_NAME_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_SCIENTIFIC_NAME_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_SCIENTIFIC_NAME_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_SCIENTIFIC_NAME_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_SCIENTIFIC_NAME_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_SCIENTIFIC_NAME_COLUMN_NAME);
return -1; return -1;
} }
// Species name column // Species name column
if (obi_view_add_column(o_view, ECOPCR_SPECIES_NAME_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_SPECIES_NAME_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_SPECIES_NAME_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_SPECIES_NAME_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_SPECIES_NAME_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_SPECIES_NAME_COLUMN_NAME);
return -1; return -1;
} }
// Genus name column // Genus name column
if (obi_view_add_column(o_view, ECOPCR_GENUS_NAME_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_GENUS_NAME_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_GENUS_NAME_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_GENUS_NAME_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_GENUS_NAME_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_GENUS_NAME_COLUMN_NAME);
return -1; return -1;
} }
// Family name column // Family name column
if (obi_view_add_column(o_view, ECOPCR_FAMILY_NAME_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_FAMILY_NAME_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_FAMILY_NAME_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_FAMILY_NAME_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_FAMILY_NAME_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_FAMILY_NAME_COLUMN_NAME);
return -1; return -1;
@ -248,7 +248,7 @@ static int create_output_columns(Obiview_p o_view, bool kingdom_mode)
if (kingdom_mode) if (kingdom_mode)
{ {
// Kingdom name column // Kingdom name column
if (obi_view_add_column(o_view, ECOPCR_KINGDOM_NAME_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_KINGDOM_NAME_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_KINGDOM_NAME_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_KINGDOM_NAME_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_KINGDOM_NAME_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_KINGDOM_NAME_COLUMN_NAME);
return -1; return -1;
@ -257,7 +257,7 @@ static int create_output_columns(Obiview_p o_view, bool kingdom_mode)
else else
{ {
// Superkingdom name column // Superkingdom name column
if (obi_view_add_column(o_view, ECOPCR_SUPERKINGDOM_NAME_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_SUPERKINGDOM_NAME_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_SUPERKINGDOM_NAME_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_SUPERKINGDOM_NAME_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_SUPERKINGDOM_NAME_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_SUPERKINGDOM_NAME_COLUMN_NAME);
return -1; return -1;
@ -265,49 +265,49 @@ static int create_output_columns(Obiview_p o_view, bool kingdom_mode)
} }
// Strand column // Strand column
if (obi_view_add_column(o_view, ECOPCR_STRAND_COLUMN_NAME, -1, NULL, OBI_CHAR, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_STRAND_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_STRAND_COLUMN_NAME, -1, NULL, OBI_CHAR, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_STRAND_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_STRAND_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_STRAND_COLUMN_NAME);
return -1; return -1;
} }
// Primer 1 column // Primer 1 column
if (obi_view_add_column(o_view, ECOPCR_PRIMER1_COLUMN_NAME, -1, NULL, OBI_SEQ, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_PRIMER1_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_PRIMER1_COLUMN_NAME, -1, NULL, OBI_SEQ, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_PRIMER1_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_PRIMER1_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_PRIMER1_COLUMN_NAME);
return -1; return -1;
} }
// Primer 2 column // Primer 2 column
if (obi_view_add_column(o_view, ECOPCR_PRIMER2_COLUMN_NAME, -1, NULL, OBI_SEQ, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_PRIMER2_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_PRIMER2_COLUMN_NAME, -1, NULL, OBI_SEQ, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_PRIMER2_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_PRIMER2_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_PRIMER2_COLUMN_NAME);
return -1; return -1;
} }
// Error 1 column // Error 1 column
if (obi_view_add_column(o_view, ECOPCR_ERROR1_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_ERROR1_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_ERROR1_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_ERROR1_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_ERROR1_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_ERROR1_COLUMN_NAME);
return -1; return -1;
} }
// Error 2 column // Error 2 column
if (obi_view_add_column(o_view, ECOPCR_ERROR2_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_ERROR2_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_ERROR2_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_ERROR2_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_ERROR2_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_ERROR2_COLUMN_NAME);
return -1; return -1;
} }
// Temperature 1 column // Temperature 1 column
if (obi_view_add_column(o_view, ECOPCR_TEMP1_COLUMN_NAME, -1, NULL, OBI_FLOAT, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_TEMP1_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_TEMP1_COLUMN_NAME, -1, NULL, OBI_FLOAT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_TEMP1_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_TEMP1_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_TEMP1_COLUMN_NAME);
return -1; return -1;
} }
// Temperature 2 column // Temperature 2 column
if (obi_view_add_column(o_view, ECOPCR_TEMP2_COLUMN_NAME, -1, NULL, OBI_FLOAT, 0, 1, NULL, false, false, false, NULL, NULL, -1, ECOPCR_TEMP2_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(o_view, ECOPCR_TEMP2_COLUMN_NAME, -1, NULL, OBI_FLOAT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ECOPCR_TEMP2_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the %s column", ECOPCR_TEMP2_COLUMN_NAME); obidebug(1, "\nError creating the %s column", ECOPCR_TEMP2_COLUMN_NAME);
return -1; return -1;
@ -645,7 +645,8 @@ static int print_seq(Obiview_p i_view, Obiview_p o_view,
int obi_ecopcr(const char* i_dms_name, int obi_ecopcr(const char* i_dms_name,
const char* i_view_name, const char* i_view_name,
const char* taxonomy_name, // TODO discuss that input dms assumed const char* tax_dms_name,
const char* taxonomy_name,
const char* o_dms_name, const char* o_dms_name,
const char* o_view_name, const char* o_view_name,
const char* o_view_comments, const char* o_view_comments,
@ -678,6 +679,7 @@ int obi_ecopcr(const char* i_dms_name,
OBIDMS_p i_dms = NULL; OBIDMS_p i_dms = NULL;
OBIDMS_p o_dms = NULL; OBIDMS_p o_dms = NULL;
OBIDMS_p tax_dms = NULL;
OBIDMS_taxonomy_p taxonomy = NULL; OBIDMS_taxonomy_p taxonomy = NULL;
Obiview_p i_view = NULL; Obiview_p i_view = NULL;
Obiview_p o_view = NULL; Obiview_p o_view = NULL;
@ -965,8 +967,16 @@ int obi_ecopcr(const char* i_dms_name,
return -1; return -1;
} }
// Open taxonomy DMS
tax_dms = obi_open_dms(tax_dms_name, false);
if (tax_dms == NULL)
{
obidebug(1, "\nError opening the taxonomy DMS");
return -1;
}
// Open the taxonomy // Open the taxonomy
taxonomy = obi_read_taxonomy(i_dms, taxonomy_name, false); taxonomy = obi_read_taxonomy(tax_dms, taxonomy_name, false);
if (taxonomy == NULL) if (taxonomy == NULL)
{ {
obidebug(1, "\nError opening the taxonomy"); obidebug(1, "\nError opening the taxonomy");

View File

@ -77,7 +77,8 @@
* *
* @param i_dms_name The path to the input DMS. * @param i_dms_name The path to the input DMS.
* @param i_view_name The name of the input view. * @param i_view_name The name of the input view.
* @param taxonomy_name The name of the taxonomy in the input DMS. * @param tax_dms_name The path to the DMS containing the taxonomy.
* @param taxonomy_name The name of the taxonomy.
* @param o_dms_name The path to the output DMS. * @param o_dms_name The path to the output DMS.
* @param o_view_name The name of the output view. * @param o_view_name The name of the output view.
* @param o_view_comments The comments to associate with the output view. * @param o_view_comments The comments to associate with the output view.
@ -106,6 +107,7 @@
*/ */
int obi_ecopcr(const char* i_dms_name, int obi_ecopcr(const char* i_dms_name,
const char* i_view_name, const char* i_view_name,
const char* tax_dms_name,
const char* taxonomy_name, const char* taxonomy_name,
const char* o_dms_name, const char* o_dms_name,
const char* o_view_name, const char* o_view_name,

View File

@ -104,42 +104,42 @@ int print_assignment_result(Obiview_p output_view, index_t line,
static int create_output_columns(Obiview_p o_view) static int create_output_columns(Obiview_p o_view)
{ {
// Score column // Score column
if (obi_view_add_column(o_view, ECOTAG_SCORE_COLUMN_NAME, -1, NULL, OBI_FLOAT, 0, 1, NULL, false, false, false, NULL, NULL, -1, "{}", true) < 0) if (obi_view_add_column(o_view, ECOTAG_SCORE_COLUMN_NAME, -1, NULL, OBI_FLOAT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, "{}", true) < 0)
{ {
obidebug(1, "\nError creating the column for the score in ecotag"); obidebug(1, "\nError creating the column for the score in ecotag");
return -1; return -1;
} }
// Assigned taxid column // Assigned taxid column
if (obi_view_add_column(o_view, ECOTAG_TAXID_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, "{}", true) < 0) if (obi_view_add_column(o_view, ECOTAG_TAXID_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, "{}", true) < 0)
{ {
obidebug(1, "\nError creating the column for the assigned taxid in ecotag"); obidebug(1, "\nError creating the column for the assigned taxid in ecotag");
return -1; return -1;
} }
// Assigned scientific name column // Assigned scientific name column
if (obi_view_add_column(o_view, ECOTAG_NAME_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, NULL, NULL, -1, "{}", true) < 0) if (obi_view_add_column(o_view, ECOTAG_NAME_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, "{}", true) < 0)
{ {
obidebug(1, "\nError creating the column for the assigned scientific name in ecotag"); obidebug(1, "\nError creating the column for the assigned scientific name in ecotag");
return -1; return -1;
} }
// Assignement status column // Assignement status column
if (obi_view_add_column(o_view, ECOTAG_STATUS_COLUMN_NAME, -1, NULL, OBI_BOOL, 0, 1, NULL, false, false, false, NULL, NULL, -1, "{}", true) < 0) if (obi_view_add_column(o_view, ECOTAG_STATUS_COLUMN_NAME, -1, NULL, OBI_BOOL, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, "{}", true) < 0)
{ {
obidebug(1, "\nError creating the column for the assignment status in ecotag"); obidebug(1, "\nError creating the column for the assignment status in ecotag");
return -1; return -1;
} }
// Column for array of best match ids // Column for array of best match ids
if (obi_view_add_column(o_view, ECOTAG_BEST_MATCH_IDS_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, true, false, NULL, NULL, -1, "{}", true) < 0) if (obi_view_add_column(o_view, ECOTAG_BEST_MATCH_IDS_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, true, false, NULL, NULL, -1, "{}", true) < 0)
{ {
obidebug(1, "\nError creating the column for the array of ids of best matches in ecotag"); obidebug(1, "\nError creating the column for the array of ids of best matches in ecotag");
return -1; return -1;
} }
// Column for array of best match taxids // Column for array of best match taxids
if (obi_view_add_column(o_view, ECOTAG_BEST_MATCH_TAXIDS_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, true, false, NULL, NULL, -1, "{}", true) < 0) if (obi_view_add_column(o_view, ECOTAG_BEST_MATCH_TAXIDS_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, true, false, NULL, NULL, -1, "{}", true) < 0)
{ {
obidebug(1, "\nError creating the column for the array of taxids of best matches in ecotag"); obidebug(1, "\nError creating the column for the array of taxids of best matches in ecotag");
return -1; return -1;
@ -233,7 +233,7 @@ int obi_ecotag(const char* dms_name,
// Write result (max score, threshold, LCA assigned, list of the ids of the best matches) // Write result (max score, threshold, LCA assigned, list of the ids of the best matches)
index_t i, j, k; index_t i, j, k, t;
ecotx_t* lca; ecotx_t* lca;
ecotx_t* lca_in_array; ecotx_t* lca_in_array;
ecotx_t* best_match; ecotx_t* best_match;
@ -259,16 +259,20 @@ int obi_ecotag(const char* dms_name,
int32_t* best_match_taxids; int32_t* best_match_taxids;
int32_t* best_match_taxids_to_store; int32_t* best_match_taxids_to_store;
int best_match_count; int best_match_count;
int best_match_taxid_count;
int buffer_size; int buffer_size;
int best_match_ids_buffer_size; int best_match_ids_buffer_size;
index_t best_match_idx; index_t best_match_idx;
int32_t lca_array_length; int32_t lca_array_length;
int32_t lca_taxid; int32_t lca_taxid;
int32_t taxid_best_match; int32_t taxid_best_match;
int32_t taxid;
int32_t taxid_to_store;
bool assigned; bool assigned;
const char* lca_name; const char* lca_name;
const char* id; const char* id;
int id_len; int id_len;
bool already_in;
OBIDMS_p dms = NULL; OBIDMS_p dms = NULL;
OBIDMS_p ref_dms = NULL; OBIDMS_p ref_dms = NULL;
@ -488,10 +492,11 @@ int obi_ecotag(const char* dms_name,
for (i=0; i < query_count; i++) for (i=0; i < query_count; i++)
{ {
if (i%1000 == 0) if (i%10 == 0)
fprintf(stderr,"\rDone : %f %% ", (i / (float) query_count)*100); fprintf(stderr,"\rDone : %f %% ", (i / (float) query_count)*100);
best_match_count = 0; best_match_count = 0;
best_match_taxid_count = 0;
best_match_ids_length = 0; best_match_ids_length = 0;
threshold = ecotag_threshold; threshold = ecotag_threshold;
best_score = 0.0; best_score = 0.0;
@ -543,6 +548,7 @@ int obi_ecotag(const char* dms_name,
// Reset the array with that match // Reset the array with that match
best_match_ids_length = 0; best_match_ids_length = 0;
best_match_count = 0; best_match_count = 0;
best_match_taxid_count = 0;
} }
// Store in best match array // Store in best match array
@ -585,8 +591,27 @@ int obi_ecotag(const char* dms_name,
// Save match // Save match
best_match_array[best_match_count] = j; best_match_array[best_match_count] = j;
best_match_taxids[best_match_count] = obi_get_int_with_elt_idx_and_col_p_in_view(ref_view, ref_taxid_column, j, 0);
best_match_count++; best_match_count++;
// Save best match taxid only if not already in array
taxid_to_store = obi_get_int_with_elt_idx_and_col_p_in_view(ref_view, ref_taxid_column, j, 0);
already_in = false;
for (t=0; t<best_match_taxid_count; t++)
{
taxid = best_match_taxids[t];
//fprintf(stderr, "\ntaxid %d, taxid_to_store %d\n", taxid, taxid_to_store);
if (taxid == taxid_to_store)
{
already_in = true;
break;
}
}
if (! already_in)
{
best_match_taxids[best_match_taxid_count] = taxid_to_store;
best_match_taxid_count++;
}
strcpy(best_match_ids+best_match_ids_length, id); strcpy(best_match_ids+best_match_ids_length, id);
best_match_ids_length = best_match_ids_length + id_len + 1; best_match_ids_length = best_match_ids_length + id_len + 1;
} }
@ -693,7 +718,7 @@ int obi_ecotag(const char* dms_name,
assigned_name_column, lca_name, assigned_name_column, lca_name,
assigned_status_column, assigned, assigned_status_column, assigned,
best_match_ids_column, best_match_ids_to_store, best_match_ids_length, best_match_ids_column, best_match_ids_to_store, best_match_ids_length,
best_match_taxids_column, best_match_taxids_to_store, best_match_count, best_match_taxids_column, best_match_taxids_to_store, best_match_taxid_count,
score_column, best_score score_column, best_score
) < 0) ) < 0)
return -1; return -1;

View File

@ -155,35 +155,35 @@ static int create_alignment_output_columns(Obiview_p output_view,
bool normalize, int reference, bool similarity_mode) bool normalize, int reference, bool similarity_mode)
{ {
// Create the column for the ids of the 1st sequence aligned // Create the column for the ids of the 1st sequence aligned
if (obi_view_add_column(output_view, ID1_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, id1_indexer_name, NULL, -1, ID1_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(output_view, ID1_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, false, id1_indexer_name, NULL, -1, ID1_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the first column for the sequence ids when aligning"); obidebug(1, "\nError creating the first column for the sequence ids when aligning");
return -1; return -1;
} }
// Create the column for the ids of the 2nd sequence aligned // Create the column for the ids of the 2nd sequence aligned
if (obi_view_add_column(output_view, ID2_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, id2_indexer_name, NULL, -1, ID2_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(output_view, ID2_COLUMN_NAME, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, false, id2_indexer_name, NULL, -1, ID2_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the second column for the sequence ids when aligning"); obidebug(1, "\nError creating the second column for the sequence ids when aligning");
return -1; return -1;
} }
// Create the column for the index (in the input view) of the first sequences aligned // Create the column for the index (in the input view) of the first sequences aligned
if (obi_view_add_column(output_view, IDX1_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, IDX1_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(output_view, IDX1_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, IDX1_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the first column for the sequence indices when aligning"); obidebug(1, "\nError creating the first column for the sequence indices when aligning");
return -1; return -1;
} }
// Create the column for the index (in the input view) of the second sequences aligned // Create the column for the index (in the input view) of the second sequences aligned
if (obi_view_add_column(output_view, IDX2_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, IDX2_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(output_view, IDX2_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, IDX2_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the second column for the sequence indices when aligning"); obidebug(1, "\nError creating the second column for the sequence indices when aligning");
return -1; return -1;
} }
// Create the column for the LCS length // Create the column for the LCS length
if (obi_view_add_column(output_view, LCS_LENGTH_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, LCS_LENGTH_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(output_view, LCS_LENGTH_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, LCS_LENGTH_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the column for the LCS length when aligning"); obidebug(1, "\nError creating the column for the LCS length when aligning");
return -1; return -1;
@ -192,7 +192,7 @@ static int create_alignment_output_columns(Obiview_p output_view,
// Create the column for the alignment length if it is computed // Create the column for the alignment length if it is computed
if ((reference == ALILEN) && (normalize || !similarity_mode)) if ((reference == ALILEN) && (normalize || !similarity_mode))
{ {
if (obi_view_add_column(output_view, ALI_LENGTH_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, ALI_LENGTH_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(output_view, ALI_LENGTH_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, ALI_LENGTH_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the column for the alignment length when aligning"); obidebug(1, "\nError creating the column for the alignment length when aligning");
return -1; return -1;
@ -201,7 +201,7 @@ static int create_alignment_output_columns(Obiview_p output_view,
// Create the column for the alignment score // Create the column for the alignment score
if (normalize) if (normalize)
{ {
if (obi_view_add_column(output_view, SCORE_COLUMN_NAME, -1, NULL, OBI_FLOAT, 0, 1, NULL, false, false, false, NULL, NULL, -1, SCORE_COLUMN_NAME, true) < 0) if (obi_view_add_column(output_view, SCORE_COLUMN_NAME, -1, NULL, OBI_FLOAT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, SCORE_COLUMN_NAME, true) < 0)
{ {
obidebug(1, "\nError creating the column for the score when aligning"); obidebug(1, "\nError creating the column for the score when aligning");
return -1; return -1;
@ -209,7 +209,7 @@ static int create_alignment_output_columns(Obiview_p output_view,
} }
else else
{ {
if (obi_view_add_column(output_view, SCORE_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, SCORE_COLUMN_NAME, true) < 0) if (obi_view_add_column(output_view, SCORE_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, SCORE_COLUMN_NAME, true) < 0)
{ {
obidebug(1, "\nError creating the column for the score when aligning"); obidebug(1, "\nError creating the column for the score when aligning");
return -1; return -1;
@ -219,14 +219,14 @@ static int create_alignment_output_columns(Obiview_p output_view,
if (print_seq) if (print_seq)
{ {
// Create the column for the first sequences aligned // Create the column for the first sequences aligned
if (obi_view_add_column(output_view, SEQ1_COLUMN_NAME, -1, NULL, OBI_SEQ, 0, 1, NULL, false, false, false, seq1_indexer_name, NULL, -1, SEQ1_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(output_view, SEQ1_COLUMN_NAME, -1, NULL, OBI_SEQ, 0, 1, NULL, false, false, false, false, seq1_indexer_name, NULL, -1, SEQ1_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the first column for the sequences when aligning"); obidebug(1, "\nError creating the first column for the sequences when aligning");
return -1; return -1;
} }
// Create the column for the second sequences aligned // Create the column for the second sequences aligned
if (obi_view_add_column(output_view, SEQ2_COLUMN_NAME, -1, NULL, OBI_SEQ, 0, 1, NULL, false, false, false, seq2_indexer_name, NULL, -1, SEQ2_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(output_view, SEQ2_COLUMN_NAME, -1, NULL, OBI_SEQ, 0, 1, NULL, false, false, false, false, seq2_indexer_name, NULL, -1, SEQ2_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the second column for the sequences when aligning"); obidebug(1, "\nError creating the second column for the sequences when aligning");
return -1; return -1;
@ -235,14 +235,14 @@ static int create_alignment_output_columns(Obiview_p output_view,
if (print_count) if (print_count)
{ {
// Create the column for the count of the first sequences aligned // Create the column for the count of the first sequences aligned
if (obi_view_add_column(output_view, COUNT1_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, COUNT1_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(output_view, COUNT1_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, COUNT1_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the first column for the sequence counts when aligning"); obidebug(1, "\nError creating the first column for the sequence counts when aligning");
return -1; return -1;
} }
// Create the column for the count of the second sequences aligned // Create the column for the count of the second sequences aligned
if (obi_view_add_column(output_view, COUNT2_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, COUNT2_COLUMN_COMMENTS, true) < 0) if (obi_view_add_column(output_view, COUNT2_COLUMN_NAME, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, COUNT2_COLUMN_COMMENTS, true) < 0)
{ {
obidebug(1, "\nError creating the second column for the sequence counts when aligning"); obidebug(1, "\nError creating the second column for the sequence counts when aligning");
return -1; return -1;

View File

@ -582,6 +582,7 @@ int truncate_avl_to_size_used(OBIDMS_avl_p avl) // TODO is it necessary to unmap
{ {
size_t file_size; size_t file_size;
size_t new_data_size; size_t new_data_size;
size_t header_size;
double multiple; double multiple;
int file_descriptor; int file_descriptor;
@ -589,6 +590,8 @@ int truncate_avl_to_size_used(OBIDMS_avl_p avl) // TODO is it necessary to unmap
multiple = ceil((double) (ONE_IF_ZERO((avl->header)->nb_items * sizeof(AVL_node_t))) / (double) getpagesize()); multiple = ceil((double) (ONE_IF_ZERO((avl->header)->nb_items * sizeof(AVL_node_t))) / (double) getpagesize());
new_data_size = ((size_t) multiple) * getpagesize(); new_data_size = ((size_t) multiple) * getpagesize();
header_size = (avl->header)->header_size;
// Check that it is actually greater than the current size of the file, otherwise no need to truncate // Check that it is actually greater than the current size of the file, otherwise no need to truncate
if ((avl->header)->avl_size == new_data_size) if ((avl->header)->avl_size == new_data_size)
return 0; return 0;
@ -596,16 +599,22 @@ int truncate_avl_to_size_used(OBIDMS_avl_p avl) // TODO is it necessary to unmap
// Get the file descriptor // Get the file descriptor
file_descriptor = avl->avl_fd; file_descriptor = avl->avl_fd;
// Unmap the tree before truncating the file // Unmap the entire file before truncating it (WSL requirement)
if (munmap(avl->tree, (avl->header)->avl_size) < 0) if (munmap(avl->tree, (avl->header)->avl_size) < 0)
{ {
obi_set_errno(OBI_AVL_ERROR); obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError munmapping the tree of an AVL before truncating"); obidebug(1, "\nError munmapping the tree of an AVL before truncating");
return -1; return -1;
} }
if (munmap(avl->header, header_size) < 0)
{
obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError munmapping the tree of an AVL before truncating");
return -1;
}
// Truncate the file // Truncate the file
file_size = (avl->header)->header_size + new_data_size; file_size = header_size + new_data_size;
if (ftruncate(file_descriptor, file_size) < 0) if (ftruncate(file_descriptor, file_size) < 0)
{ {
obi_set_errno(OBI_AVL_ERROR); obi_set_errno(OBI_AVL_ERROR);
@ -613,7 +622,22 @@ int truncate_avl_to_size_used(OBIDMS_avl_p avl) // TODO is it necessary to unmap
return -1; return -1;
} }
// Remap the data // Remap the header and the data
avl->header = mmap(NULL,
header_size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
file_descriptor,
0
);
if (avl->header == MAP_FAILED)
{
obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError re-mmapping the header of an AVL after truncating");
return -1;
}
avl->tree = mmap(NULL, avl->tree = mmap(NULL,
new_data_size, new_data_size,
PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
@ -640,6 +664,7 @@ int truncate_avl_data_to_size_used(OBIDMS_avl_data_p avl_data) // TODO is it nec
{ {
size_t file_size; size_t file_size;
index_t new_data_size; index_t new_data_size;
size_t header_size;
double multiple; double multiple;
int file_descriptor; int file_descriptor;
@ -647,6 +672,8 @@ int truncate_avl_data_to_size_used(OBIDMS_avl_data_p avl_data) // TODO is it nec
multiple = ceil((double) (ONE_IF_ZERO((avl_data->header)->data_size_used)) / (double) getpagesize()); multiple = ceil((double) (ONE_IF_ZERO((avl_data->header)->data_size_used)) / (double) getpagesize());
new_data_size = ((index_t) multiple) * getpagesize(); new_data_size = ((index_t) multiple) * getpagesize();
header_size = (avl_data->header)->header_size;
// Check that it is actually greater than the current size of the file, otherwise no need to truncate // Check that it is actually greater than the current size of the file, otherwise no need to truncate
if ((avl_data->header)->data_size_max >= new_data_size) if ((avl_data->header)->data_size_max >= new_data_size)
return 0; return 0;
@ -654,7 +681,8 @@ int truncate_avl_data_to_size_used(OBIDMS_avl_data_p avl_data) // TODO is it nec
// Get the file descriptor // Get the file descriptor
file_descriptor = avl_data->data_fd; file_descriptor = avl_data->data_fd;
// Unmap the data before truncating the file // Unmap the entire file before truncating it (WSL requirement)
if (munmap(avl_data->data, (avl_data->header)->data_size_max) < 0) if (munmap(avl_data->data, (avl_data->header)->data_size_max) < 0)
{ {
obi_set_errno(OBI_AVL_ERROR); obi_set_errno(OBI_AVL_ERROR);
@ -662,8 +690,15 @@ int truncate_avl_data_to_size_used(OBIDMS_avl_data_p avl_data) // TODO is it nec
return -1; return -1;
} }
if (munmap(avl_data->header, header_size) < 0)
{
obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError munmapping the header of an AVL before truncating");
return -1;
}
// Truncate the file // Truncate the file
file_size = (avl_data->header)->header_size + new_data_size; file_size = header_size + new_data_size;
if (ftruncate(file_descriptor, file_size) < 0) if (ftruncate(file_descriptor, file_size) < 0)
{ {
obi_set_errno(OBI_AVL_ERROR); obi_set_errno(OBI_AVL_ERROR);
@ -672,6 +707,22 @@ int truncate_avl_data_to_size_used(OBIDMS_avl_data_p avl_data) // TODO is it nec
} }
// Remap the data // Remap the data
avl_data->header = mmap(NULL,
header_size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
file_descriptor,
0
);
if (avl_data->header == MAP_FAILED)
{
obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError re-mmapping the header of an AVL after truncating");
return -1;
}
avl_data->data = mmap(NULL, avl_data->data = mmap(NULL,
new_data_size, new_data_size,
PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
@ -710,6 +761,20 @@ int grow_avl(OBIDMS_avl_p avl) // TODO Lock when needed
header_size = (avl->header)->header_size; header_size = (avl->header)->header_size;
file_size = header_size + new_data_size; file_size = header_size + new_data_size;
// Unmap the entire file before truncating it (WSL requirement)
if (munmap(avl->tree, old_data_size) < 0)
{
obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError munmapping the tree of an AVL tree file before enlarging");
return -1;
}
if (munmap(avl->header, header_size) < 0)
{
obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError munmapping the header of an AVL tree file before enlarging");
return -1;
}
// Enlarge the file // Enlarge the file
if (ftruncate(avl_file_descriptor, file_size) < 0) if (ftruncate(avl_file_descriptor, file_size) < 0)
{ {
@ -718,12 +783,20 @@ int grow_avl(OBIDMS_avl_p avl) // TODO Lock when needed
return -1; return -1;
} }
// Unmap and re-map the data // Re-map
if (munmap(avl->tree, old_data_size) < 0) avl->header = mmap(NULL,
header_size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
avl_file_descriptor,
0
);
if (avl->header == MAP_FAILED)
{ {
obi_set_errno(OBI_AVL_ERROR); obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError munmapping the tree of an AVL tree file before enlarging"); obidebug(1, "\nError re-mmapping the header of an AVL tree file after enlarging the file");
return -1; return -1;
} }
@ -768,6 +841,20 @@ int grow_avl_data(OBIDMS_avl_data_p avl_data) // TODO Lock when needed
header_size = (avl_data->header)->header_size; header_size = (avl_data->header)->header_size;
file_size = header_size + new_data_size; file_size = header_size + new_data_size;
// Unmap the entire file before truncating it (WSL requirement)
if (munmap(avl_data->data, old_data_size) < 0)
{
obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError munmapping the data of an AVL tree data file before enlarging");
return -1;
}
if (munmap(avl_data->header, header_size) < 0)
{
obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError munmapping the header of an AVL tree data file before enlarging");
return -1;
}
// Enlarge the file // Enlarge the file
if (ftruncate(avl_data_file_descriptor, file_size) < 0) if (ftruncate(avl_data_file_descriptor, file_size) < 0)
{ {
@ -776,12 +863,19 @@ int grow_avl_data(OBIDMS_avl_data_p avl_data) // TODO Lock when needed
return -1; return -1;
} }
// Unmap and re-map the data // Re-map
if (munmap(avl_data->data, old_data_size) < 0) avl_data->header = mmap(NULL,
header_size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
avl_data_file_descriptor,
0
);
if (avl_data->header == MAP_FAILED)
{ {
obi_set_errno(OBI_AVL_ERROR); obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError munmapping the data of an AVL tree data file before enlarging"); obidebug(1, "\nError re-mmapping the header of an AVL tree data file after enlarging the file");
return -1; return -1;
} }
@ -792,7 +886,6 @@ int grow_avl_data(OBIDMS_avl_data_p avl_data) // TODO Lock when needed
avl_data_file_descriptor, avl_data_file_descriptor,
header_size header_size
); );
if (avl_data->data == MAP_FAILED) if (avl_data->data == MAP_FAILED)
{ {
obi_set_errno(OBI_AVL_ERROR); obi_set_errno(OBI_AVL_ERROR);

View File

@ -316,6 +316,15 @@ static int enlarge_infos_file(OBIDMS_p dms, size_t new_size)
multiple = ceil((double) new_size / (double) getpagesize()); multiple = ceil((double) new_size / (double) getpagesize());
rounded_new_size = multiple * getpagesize(); rounded_new_size = multiple * getpagesize();
// Unmap the entire file before truncating it (WSL requirement)
if (munmap(dms->infos, (dms->infos)->file_size) < 0)
{
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
obidebug(1, "\nError munmapping a DMS information file when enlarging");
close(infos_file_descriptor);
return -1;
}
// Enlarge the file // Enlarge the file
if (ftruncate(infos_file_descriptor, rounded_new_size) < 0) if (ftruncate(infos_file_descriptor, rounded_new_size) < 0)
{ {
@ -325,15 +334,7 @@ static int enlarge_infos_file(OBIDMS_p dms, size_t new_size)
return -1; return -1;
} }
// Unmap and remap the file // Remap the file
if (munmap(dms->infos, (dms->infos)->file_size) < 0)
{
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
obidebug(1, "\nError munmapping a DMS information file when enlarging");
close(infos_file_descriptor);
return -1;
}
dms->infos = mmap(NULL, dms->infos = mmap(NULL,
rounded_new_size, rounded_new_size,
PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
@ -1416,7 +1417,7 @@ char* obi_dms_formatted_infos(OBIDMS_p dms, bool detailed)
char* view_name = NULL; char* view_name = NULL;
char* tax_name = NULL; char* tax_name = NULL;
char* all_tax_dir_path = NULL; char* all_tax_dir_path = NULL;
int i; int i, last_dot_pos;
struct dirent* dp; struct dirent* dp;
Obiview_p view; Obiview_p view;
@ -1438,17 +1439,21 @@ char* obi_dms_formatted_infos(OBIDMS_p dms, bool detailed)
if ((dp->d_name)[0] == '.') if ((dp->d_name)[0] == '.')
continue; continue;
i=0; i=0;
while ((dp->d_name)[i] != '.') while (i < strlen(dp->d_name))
{
if ((dp->d_name)[i] == '.')
last_dot_pos = i;
i++; i++;
view_name = (char*) malloc((i+1) * sizeof(char)); }
view_name = (char*) malloc((last_dot_pos+1) * sizeof(char));
if (view_name == NULL) if (view_name == NULL)
{ {
obi_set_errno(OBI_MALLOC_ERROR); 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); obidebug(1, "\nError allocating memory for a view name when getting formatted DMS infos: file %s", dp->d_name);
return NULL; return NULL;
} }
strncpy(view_name, dp->d_name, i); strncpy(view_name, dp->d_name, last_dot_pos);
view_name[i] = '\0'; view_name[last_dot_pos] = '\0';
view = obi_open_view(dms, view_name); view = obi_open_view(dms, view_name);
if (view == NULL) if (view == NULL)
{ {
@ -1575,8 +1580,8 @@ obiversion_t obi_import_column(const char* dms_path_1, const char* dms_path_2, c
// Create new column // Create new column
column_2 = obi_create_column(dms_2, column_name, header_1->returned_data_type, header_1->line_count, column_2 = obi_create_column(dms_2, column_name, header_1->returned_data_type, header_1->line_count,
header_1->nb_elements_per_line, header_1->elements_names, true, header_1->tuples, header_1->nb_elements_per_line, header_1->elements_names, true, header_1->dict_column,
header_1->to_eval, new_avl_name, (header_1->associated_column).column_name, header_1->tuples, header_1->to_eval, new_avl_name, (header_1->associated_column).column_name,
(header_1->associated_column).version, header_1->comments); (header_1->associated_column).version, header_1->comments);
if (column_2 == NULL) if (column_2 == NULL)
@ -1813,6 +1818,7 @@ int obi_import_view(const char* dms_path_1, const char* dms_path_2, const char*
false, false,
false, false,
false, false,
false,
NULL, NULL,
NULL, NULL,
-1, -1,

View File

@ -40,7 +40,7 @@
*/ */
#define MAX_NB_OPENED_INDEXERS (1000) /**< The maximum number of indexers open at the same time. #define MAX_NB_OPENED_INDEXERS (1000) /**< The maximum number of indexers open at the same time.
*/ */
#define MAX_PATH_LEN (1024) /**< Maximum length for the character string defining a #define MAX_PATH_LEN (2048) /**< Maximum length for the character string defining a
* file or directory path. * file or directory path.
*/ */

View File

@ -873,7 +873,7 @@ static ecotxidx_t* read_taxonomy_idx(const char* taxa_file_name, const char* loc
taxa_index->buffer_size = taxa_index->count; taxa_index->buffer_size = taxa_index->count;
taxa_index->max_taxid = 0; taxa_index->max_taxid = 0;
printf("Reading %d taxa...\n", count_taxa); fprintf(stderr, "Reading %d taxa...\n", count_taxa);
for (i=0; i<count_taxa; i++) for (i=0; i<count_taxa; i++)
{ {
readnext_ecotaxon(f_taxa, &(taxa_index->taxon[i])); readnext_ecotaxon(f_taxa, &(taxa_index->taxon[i]));
@ -886,9 +886,9 @@ static ecotxidx_t* read_taxonomy_idx(const char* taxa_file_name, const char* loc
} }
if (count_local_taxa > 0) if (count_local_taxa > 0)
printf("Reading %d local taxa...\n", count_local_taxa); fprintf(stderr, "Reading %d local taxa...\n", count_local_taxa);
else else
printf("No local taxa\n"); fprintf(stderr, "No local taxa\n");
count_taxa = taxa_index->count; count_taxa = taxa_index->count;
@ -2463,6 +2463,32 @@ int read_merged_dmp(const char* taxdump, OBIDMS_taxonomy_p tax, int32_t* delnode
return -1; return -1;
} }
// Write the rest of the taxa from the current taxa list
while (nT < (tax->taxa)->count)
{
// Add element from taxa list
// Enlarge structure if needed
if (n == buffer_size)
{
buffer_size = buffer_size * 2;
tax->merged_idx = (ecomergedidx_t*) realloc(tax->merged_idx, sizeof(ecomergedidx_t) + sizeof(ecomerged_t) * buffer_size);
if (tax->merged_idx == NULL)
{
obi_set_errno(OBI_MALLOC_ERROR);
obidebug(1, "\nError reallocating memory for a taxonomy structure");
closedir(tax_dir);
fclose(file);
return -1;
}
}
(tax->merged_idx)->merged[n].taxid = (tax->taxa)->taxon[nT].taxid;
(tax->merged_idx)->merged[n].idx = nT;
nT++;
n++;
}
// Store count // Store count
(tax->merged_idx)->count = n; (tax->merged_idx)->count = n;

View File

@ -75,7 +75,7 @@ typedef struct {
*/ */
int32_t max_taxid; /**< Maximum taxid existing in the taxon index. int32_t max_taxid; /**< Maximum taxid existing in the taxon index.
*/ */
int32_t buffer_size; /**< Number of taxa. // TODO kept this but not sure of its use int32_t buffer_size; /**< . // TODO kept this but not sure of its use
*/ */
ecotx_t taxon[]; /**< Taxon array. ecotx_t taxon[]; /**< Taxon array.
*/ */

View File

@ -1024,6 +1024,7 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms,
index_t nb_elements_per_line, index_t nb_elements_per_line,
char* elements_names, char* elements_names,
bool elt_names_formatted, bool elt_names_formatted,
bool dict_column,
bool tuples, bool tuples,
bool to_eval, bool to_eval,
const char* indexer_name, const char* indexer_name,
@ -1282,6 +1283,7 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms,
header->nb_elements_per_line = nb_elements_per_line; header->nb_elements_per_line = nb_elements_per_line;
header->stored_data_type = stored_data_type; header->stored_data_type = stored_data_type;
header->returned_data_type = returned_data_type; header->returned_data_type = returned_data_type;
header->dict_column = dict_column;
header->tuples = tuples; header->tuples = tuples;
header->to_eval = to_eval; header->to_eval = to_eval;
header->creation_date = time(NULL); header->creation_date = time(NULL);
@ -1611,6 +1613,7 @@ OBIDMS_column_p obi_clone_column(OBIDMS_p dms,
nb_elements_per_line, nb_elements_per_line,
(column_to_clone->header)->elements_names, (column_to_clone->header)->elements_names,
true, true,
(column_to_clone->header)->dict_column,
(column_to_clone->header)->tuples, (column_to_clone->header)->tuples,
(column_to_clone->header)->to_eval, (column_to_clone->header)->to_eval,
(column_to_clone->header)->indexer_name, (column_to_clone->header)->indexer_name,
@ -1766,6 +1769,7 @@ int obi_truncate_column(OBIDMS_column_p column) // TODO is it necessary to unmap
{ {
size_t file_size; size_t file_size;
size_t data_size; size_t data_size;
size_t header_size;
index_t new_line_count; index_t new_line_count;
double multiple; double multiple;
int column_file_descriptor; int column_file_descriptor;
@ -1788,6 +1792,8 @@ int obi_truncate_column(OBIDMS_column_p column) // TODO is it necessary to unmap
data_size = obi_array_sizeof((column->header)->stored_data_type, new_line_count, (column->header)->nb_elements_per_line); data_size = obi_array_sizeof((column->header)->stored_data_type, new_line_count, (column->header)->nb_elements_per_line);
header_size = (column->header)->header_size;
// Check that it is actually greater than the current data size, otherwise no need to truncate // Check that it is actually greater than the current data size, otherwise no need to truncate
if ((column->header)->data_size == data_size) if ((column->header)->data_size == data_size)
return 0; return 0;
@ -1852,7 +1858,7 @@ int obi_truncate_column(OBIDMS_column_p column) // TODO is it necessary to unmap
return -1; return -1;
} }
// Unmap the data before truncating the file // Unmap the entire file before truncating it (WSL requirement)
if (munmap(column->data, (column->header)->data_size) < 0) if (munmap(column->data, (column->header)->data_size) < 0)
{ {
obi_set_errno(OBICOL_UNKNOWN_ERROR); obi_set_errno(OBICOL_UNKNOWN_ERROR);
@ -1860,9 +1866,16 @@ int obi_truncate_column(OBIDMS_column_p column) // TODO is it necessary to unmap
close(column_file_descriptor); close(column_file_descriptor);
return -1; return -1;
} }
if (munmap(column->header, header_size) < 0)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError munmapping the header of a column before truncating");
close(column_file_descriptor);
return -1;
}
// Truncate the column file // Truncate the column file
file_size = (column->header)->header_size + data_size; file_size = header_size + data_size;
if (ftruncate(column_file_descriptor, file_size) < 0) if (ftruncate(column_file_descriptor, file_size) < 0)
{ {
obi_set_errno(OBICOL_UNKNOWN_ERROR); obi_set_errno(OBICOL_UNKNOWN_ERROR);
@ -1871,13 +1884,30 @@ int obi_truncate_column(OBIDMS_column_p column) // TODO is it necessary to unmap
return -1; return -1;
} }
// Remap the data // Remap the header and the data
column->header = mmap(NULL,
header_size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
column_file_descriptor,
0
);
if (column->header == MAP_FAILED)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError re-mmapping the header of a column after truncating");
close(column_file_descriptor);
return -1;
}
column->data = mmap(NULL, column->data = mmap(NULL,
data_size, data_size,
PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
MAP_SHARED, MAP_SHARED,
column_file_descriptor, column_file_descriptor,
(column->header)->header_size header_size
); );
if (column->data == MAP_FAILED) if (column->data == MAP_FAILED)

View File

@ -36,7 +36,7 @@
*/ */
#define COLUMN_GROWTH_FACTOR (2) /**< The growth factor when a column is enlarged. #define COLUMN_GROWTH_FACTOR (2) /**< The growth factor when a column is enlarged.
*/ */
#define MAXIMUM_LINE_COUNT (1000000000) /**< The maximum line count for the data of a column (1E9). //TODO #define MAXIMUM_LINE_COUNT (1000000000000) /**< The maximum line count for the data of a column (1E12). //TODO
*/ */
#define COMMENTS_MAX_LENGTH (4096) /**< The maximum length for comments. #define COMMENTS_MAX_LENGTH (4096) /**< The maximum length for comments.
*/ */
@ -77,6 +77,8 @@ typedef struct OBIDMS_column_header {
OBIType_t stored_data_type; /**< Type of the data that is actually stored in the data OBIType_t stored_data_type; /**< Type of the data that is actually stored in the data
* part of the column. * part of the column.
*/ */
bool dict_column; /**< Whether the column contains dictionary-like values.
*/
bool tuples; /**< A boolean indicating whether the column contains indices referring to indexed tuples. bool tuples; /**< A boolean indicating whether the column contains indices referring to indexed tuples.
*/ */
bool to_eval; /**< A boolean indicating whether the column contains expressions that should be evaluated bool to_eval; /**< A boolean indicating whether the column contains expressions that should be evaluated
@ -249,6 +251,7 @@ size_t obi_calculate_header_size(index_t nb_elements_per_line, int64_t elts_name
* @param elements_names The names of the elements with ';' as separator (no terminal ';'), * @param elements_names The names of the elements with ';' as separator (no terminal ';'),
* NULL or "" if the default names are to be used ("0\01\02\0...\0n"). * NULL or "" if the default names are to be used ("0\01\02\0...\0n").
* @param elt_names_formatted Whether the separator for the elements names is ';' (false), or '\0' (true, as formatted by format_elements_names()). * @param elt_names_formatted Whether the separator for the elements names is ';' (false), or '\0' (true, as formatted by format_elements_names()).
* @param dict_column A boolean indicating whether the column should contain dictionary-like values.
* @param tuples A boolean indicating whether the column should contain indices referring to indexed tuples. * @param tuples A boolean indicating whether the column should contain indices referring to indexed tuples.
* @param to_eval A boolean indicating whether the column contains expressions that should be evaluated * @param to_eval A boolean indicating whether the column contains expressions that should be evaluated
* (typically OBI_STR columns containing character strings to be evaluated by Python). * (typically OBI_STR columns containing character strings to be evaluated by Python).
@ -271,6 +274,7 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms,
index_t nb_elements_per_line, index_t nb_elements_per_line,
char* elements_names, char* elements_names,
bool elt_names_formatted, bool elt_names_formatted,
bool dict_column,
bool tuples, bool tuples,
bool to_eval, bool to_eval,
const char* indexer_name, const char* indexer_name,

View File

@ -29,6 +29,8 @@
#define OBIQual_int_NA (NULL) /**< NA value for the type OBI_QUAL if the quality is in integer format */ #define OBIQual_int_NA (NULL) /**< NA value for the type OBI_QUAL if the quality is in integer format */
#define OBITuple_NA (NULL) /**< NA value for tuples of any type */ #define OBITuple_NA (NULL) /**< NA value for tuples of any type */
#define OBI_INT_MAX (INT32_MAX) /**< Maximum value for the type OBI_INT */
/** /**
* @brief enum for the boolean OBIType. * @brief enum for the boolean OBIType.

View File

@ -638,6 +638,15 @@ static int enlarge_view_file(Obiview_p view, size_t new_size)
multiple = ceil((double) new_size / (double) getpagesize()); multiple = ceil((double) new_size / (double) getpagesize());
rounded_new_size = multiple * getpagesize(); rounded_new_size = multiple * getpagesize();
// Unmap the entire file before truncating it (WSL requirement)
if (munmap(view->infos, (view->infos)->file_size) < 0)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError munmapping a view file when enlarging");
close(obiview_file_descriptor);
return -1;
}
// Enlarge the file // Enlarge the file
if (ftruncate(obiview_file_descriptor, rounded_new_size) < 0) if (ftruncate(obiview_file_descriptor, rounded_new_size) < 0)
{ {
@ -647,15 +656,7 @@ static int enlarge_view_file(Obiview_p view, size_t new_size)
return -1; return -1;
} }
// Unmap and remap the file // Remap the file
if (munmap(view->infos, (view->infos)->file_size) < 0)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError munmapping a view file when enlarging");
close(obiview_file_descriptor);
return -1;
}
view->infos = mmap(NULL, view->infos = mmap(NULL,
rounded_new_size, rounded_new_size,
PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
@ -1712,7 +1713,7 @@ Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_cl
// If there is a new line selection, build it by combining it with the one from the view to clone if there is one // If there is a new line selection, build it by combining it with the one from the view to clone if there is one
else if (line_selection != NULL) else if (line_selection != NULL)
{ {
view->line_selection = obi_create_column(view->dms, LINES_COLUMN_NAME, OBI_IDX, 0, 1, NULL, false, false, false, NULL, NULL, -1, NULL); view->line_selection = obi_create_column(view->dms, LINES_COLUMN_NAME, OBI_IDX, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, NULL);
if ((view->line_selection) == NULL) if ((view->line_selection) == NULL)
{ {
obidebug(1, "\nError creating a column corresponding to a line selection"); obidebug(1, "\nError creating a column corresponding to a line selection");
@ -1862,6 +1863,7 @@ Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_cl
false, false,
false, false,
false, false,
false,
NULL, NULL,
NULL, NULL,
-1, -1,
@ -1930,19 +1932,19 @@ Obiview_p obi_new_view_nuc_seqs(OBIDMS_p dms, const char* view_name, Obiview_p v
if ((view_to_clone == NULL) && create_default_columns) if ((view_to_clone == NULL) && create_default_columns)
{ {
// Adding sequence column // Adding sequence column
if (obi_view_add_column(view, NUC_SEQUENCE_COLUMN, -1, NULL, OBI_SEQ, 0, 1, NULL, false, false, false, NULL, NULL, -1, "{}", true) < 0) // discuss using same indexer "NUC_SEQ_INDEXER" if (obi_view_add_column(view, NUC_SEQUENCE_COLUMN, -1, NULL, OBI_SEQ, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, "{}", true) < 0) // discuss using same indexer "NUC_SEQ_INDEXER"
{ {
obidebug(1, "Error adding an obligatory column in a nucleotide sequences view"); obidebug(1, "Error adding an obligatory column in a nucleotide sequences view");
return NULL; return NULL;
} }
// Adding id column // Adding id column
if (obi_view_add_column(view, ID_COLUMN, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, NULL, NULL, -1, "{}", true) < 0) if (obi_view_add_column(view, ID_COLUMN, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, "{}", true) < 0)
{ {
obidebug(1, "Error adding an obligatory column in a nucleotide sequences view"); obidebug(1, "Error adding an obligatory column in a nucleotide sequences view");
return NULL; return NULL;
} }
// Adding definition column // Adding definition column
if (obi_view_add_column(view, DEFINITION_COLUMN, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, NULL, NULL, -1, "{}", true) < 0) if (obi_view_add_column(view, DEFINITION_COLUMN, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, "{}", true) < 0)
{ {
obidebug(1, "Error adding an obligatory column in a nucleotide sequences view"); obidebug(1, "Error adding an obligatory column in a nucleotide sequences view");
return NULL; return NULL;
@ -1951,7 +1953,7 @@ Obiview_p obi_new_view_nuc_seqs(OBIDMS_p dms, const char* view_name, Obiview_p v
if (quality_column) if (quality_column)
{ {
associated_nuc_column = obi_view_get_column(view, NUC_SEQUENCE_COLUMN); associated_nuc_column = obi_view_get_column(view, NUC_SEQUENCE_COLUMN);
if (obi_view_add_column(view, QUALITY_COLUMN, -1, NULL, OBI_QUAL, 0, 1, NULL, false, false, false, NULL, (associated_nuc_column->header)->name, (associated_nuc_column->header)->version, "{}", true) < 0) // TODO discuss automatic association if (obi_view_add_column(view, QUALITY_COLUMN, -1, NULL, OBI_QUAL, 0, 1, NULL, false, false, false, false, NULL, (associated_nuc_column->header)->name, (associated_nuc_column->header)->version, "{}", true) < 0) // TODO discuss automatic association
{ {
obidebug(1, "Error adding an obligatory column in a nucleotide sequences view"); obidebug(1, "Error adding an obligatory column in a nucleotide sequences view");
return NULL; return NULL;
@ -2284,6 +2286,7 @@ int obi_view_add_column(Obiview_p view,
index_t nb_elements_per_line, index_t nb_elements_per_line,
char* elements_names, char* elements_names,
bool elt_names_formatted, bool elt_names_formatted,
bool dict_column,
bool tuples, bool tuples,
bool to_eval, bool to_eval,
const char* indexer_name, const char* indexer_name,
@ -2366,7 +2369,7 @@ int obi_view_add_column(Obiview_p view,
// Open or create the column // Open or create the column
if (create) if (create)
{ // Create column { // Create column
column = obi_create_column(view->dms, column_name, data_type, nb_lines, nb_elements_per_line, elements_names, elt_names_formatted, tuples, to_eval, indexer_name, associated_column_name, associated_column_version, comments); column = obi_create_column(view->dms, column_name, data_type, nb_lines, nb_elements_per_line, elements_names, elt_names_formatted, dict_column, tuples, to_eval, indexer_name, associated_column_name, associated_column_version, comments);
if (column == NULL) if (column == NULL)
{ {
obidebug(1, "\nError creating a column to add to a view"); obidebug(1, "\nError creating a column to add to a view");
@ -2907,7 +2910,7 @@ int obi_clean_unfinished_views(OBIDMS_p dms)
if ((dp->d_name)[0] == '.') if ((dp->d_name)[0] == '.')
continue; continue;
i=0; i=0;
while ((dp->d_name)[i] != '.') while (strncmp((dp->d_name)+i, ".obiview", 8))
i++; i++;
relative_path = (char*) malloc(strlen(VIEW_DIR_NAME) + strlen(dp->d_name) + 2); relative_path = (char*) malloc(strlen(VIEW_DIR_NAME) + strlen(dp->d_name) + 2);
strcpy(relative_path, VIEW_DIR_NAME); strcpy(relative_path, VIEW_DIR_NAME);
@ -3230,7 +3233,7 @@ int obi_create_auto_count_column(Obiview_p view)
return -1; return -1;
} }
if (obi_view_add_column(view, COUNT_COLUMN, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, NULL, NULL, -1, "{}", true) < 0) if (obi_view_add_column(view, COUNT_COLUMN, -1, NULL, OBI_INT, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, "{}", true) < 0)
{ {
obidebug(1, "Error adding an automatic count column in a view"); obidebug(1, "Error adding an automatic count column in a view");
return -1; return -1;
@ -3282,7 +3285,7 @@ int obi_create_auto_id_column(Obiview_p view, const char* prefix)
} }
// Create the new ID column // Create the new ID column
if (obi_view_add_column(view, ID_COLUMN, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, NULL, NULL, -1, "{}", true) < 0) if (obi_view_add_column(view, ID_COLUMN, -1, NULL, OBI_STR, 0, 1, NULL, false, false, false, false, NULL, NULL, -1, "{}", true) < 0)
{ {
obidebug(1, "Error adding an automatic ID column in a view"); obidebug(1, "Error adding an automatic ID column in a view");
return -1; return -1;

View File

@ -400,6 +400,7 @@ Obiview_p obi_open_view(OBIDMS_p dms, const char* view_name);
* @param elements_names The names of the elements with ';' as separator (no terminal ';'), * @param elements_names The names of the elements with ';' as separator (no terminal ';'),
* if the column is created; NULL or "" if the default names are to be used ("0\01\02\0...\0n"). * if the column is created; NULL or "" if the default names are to be used ("0\01\02\0...\0n").
* @param elt_names_formatted Whether the separator for the elements names is ';' (false), or '\0' (true, as formatted by format_elements_names()). * @param elt_names_formatted Whether the separator for the elements names is ';' (false), or '\0' (true, as formatted by format_elements_names()).
* @param dict_column Whether the column contains dictionary-like values.
* @param tuples A boolean indicating whether the column should contain indices referring to indexed tuples. * @param tuples A boolean indicating whether the column should contain indices referring to indexed tuples.
* @param to_eval A boolean indicating whether the column contains expressions that should be evaluated * @param to_eval A boolean indicating whether the column contains expressions that should be evaluated
* (typically OBI_STR columns containing character strings to be evaluated by Python). * (typically OBI_STR columns containing character strings to be evaluated by Python).
@ -426,6 +427,7 @@ int obi_view_add_column(Obiview_p view,
index_t nb_elements_per_line, index_t nb_elements_per_line,
char* elements_names, char* elements_names,
bool elt_names_formatted, bool elt_names_formatted,
bool dict_column,
bool tuples, bool tuples,
bool to_eval, bool to_eval,
const char* indexer_name, const char* indexer_name,