New command: obi taxonomy to add local taxa (closes #64)
This commit is contained in:
@ -1092,7 +1092,7 @@ static int write_ranks_idx(OBIDMS_p dms, OBIDMS_taxonomy_p tax, const char* taxo
|
||||
free(taxonomy_path);
|
||||
|
||||
// Create file
|
||||
file_descriptor = open(file_name, O_RDWR | O_CREAT | O_EXCL, 0777);
|
||||
file_descriptor = open(file_name, O_RDWR | O_CREAT, 0777);
|
||||
if (file_descriptor < 0)
|
||||
{
|
||||
obi_set_errno(OBI_TAXONOMY_ERROR);
|
||||
@ -1196,7 +1196,7 @@ static int write_taxonomy_idx(OBIDMS_p dms, OBIDMS_taxonomy_p tax, const char* t
|
||||
free(taxonomy_path);
|
||||
|
||||
// Create file
|
||||
file_descriptor = open(file_name, O_RDWR | O_CREAT | O_EXCL, 0777);
|
||||
file_descriptor = open(file_name, O_RDWR | O_CREAT, 0777);
|
||||
if (file_descriptor < 0)
|
||||
{
|
||||
obi_set_errno(OBI_TAXONOMY_ERROR);
|
||||
@ -1472,7 +1472,7 @@ static int write_names_idx(OBIDMS_p dms, OBIDMS_taxonomy_p tax, const char* taxo
|
||||
free(taxonomy_path);
|
||||
|
||||
// Create file
|
||||
file_descriptor = open(file_name, O_RDWR | O_CREAT | O_EXCL, 0777);
|
||||
file_descriptor = open(file_name, O_RDWR | O_CREAT, 0777);
|
||||
if (file_descriptor < 0)
|
||||
{
|
||||
obi_set_errno(OBI_TAXONOMY_ERROR);
|
||||
@ -1760,7 +1760,7 @@ static int write_merged_idx(OBIDMS_p dms, OBIDMS_taxonomy_p tax, const char* tax
|
||||
free(taxonomy_path);
|
||||
|
||||
// Create file
|
||||
file_descriptor = open(file_name, O_RDWR | O_CREAT | O_EXCL, 0777);
|
||||
file_descriptor = open(file_name, O_RDWR | O_CREAT, 0777);
|
||||
if (file_descriptor < 0)
|
||||
{
|
||||
obi_set_errno(OBI_TAXONOMY_ERROR);
|
||||
@ -3250,47 +3250,48 @@ OBIDMS_taxonomy_p obi_read_taxonomy(OBIDMS_p dms, const char* taxonomy_name, boo
|
||||
}
|
||||
|
||||
|
||||
int obi_write_taxonomy(OBIDMS_p dms, OBIDMS_taxonomy_p tax, const char* tax_name)
|
||||
int obi_write_taxonomy(OBIDMS_p dms, OBIDMS_taxonomy_p tax, const char* tax_name, bool update)
|
||||
{
|
||||
char* taxonomy_path;
|
||||
|
||||
// Build the taxonomy directory path
|
||||
taxonomy_path = get_taxonomy_path(dms, tax_name);
|
||||
if (taxonomy_path == NULL)
|
||||
return -1;
|
||||
|
||||
// Try to create the directory
|
||||
if (mkdir(taxonomy_path, 00777) < 0)
|
||||
{
|
||||
if (errno == EEXIST)
|
||||
obidebug(1, "\nA taxonomy already exists with this name.");
|
||||
obidebug(1, "\nProblem creating a new taxonomy directory");
|
||||
if (!update) {
|
||||
// Build the taxonomy directory path
|
||||
taxonomy_path = get_taxonomy_path(dms, tax_name);
|
||||
if (taxonomy_path == NULL)
|
||||
return -1;
|
||||
// Try to create the directory
|
||||
if (mkdir(taxonomy_path, 00777) < 0)
|
||||
{
|
||||
if (errno == EEXIST)
|
||||
obidebug(1, "\nA taxonomy already exists with this name.");
|
||||
obidebug(1, "\nProblem creating a new taxonomy directory");
|
||||
free(taxonomy_path);
|
||||
return -1;
|
||||
}
|
||||
free(taxonomy_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(taxonomy_path);
|
||||
|
||||
if (write_ranks_idx(dms, tax, tax_name) < 0)
|
||||
return -1;
|
||||
if (write_taxonomy_idx(dms, tax, tax_name) < 0)
|
||||
return -1;
|
||||
if (write_names_idx(dms, tax, tax_name) < 0)
|
||||
return -1;
|
||||
if (write_merged_idx(dms, tax, tax_name) < 0)
|
||||
return -1;
|
||||
// Check if there are local taxa (if so last taxon is local)
|
||||
if (write_ranks_idx(dms, tax, tax_name) < 0)
|
||||
return -1;
|
||||
if (write_taxonomy_idx(dms, tax, tax_name) < 0)
|
||||
return -1;
|
||||
if (write_names_idx(dms, tax, tax_name) < 0)
|
||||
return -1;
|
||||
if (write_merged_idx(dms, tax, tax_name) < 0)
|
||||
return -1;
|
||||
// Write preferred names if there are some
|
||||
if (tax->preferred_names != NULL)
|
||||
{
|
||||
if (write_preferred_names_idx(dms, tax, tax_name) < 0)
|
||||
return -1;
|
||||
}
|
||||
// Write local taxa if there are some
|
||||
if ((tax->taxa)->local_count > 0)
|
||||
{
|
||||
if (write_local_taxonomy_idx(dms, tax, tax_name) < 0)
|
||||
return -1;
|
||||
}
|
||||
// Write preferred names if there are some
|
||||
if (tax->preferred_names != NULL)
|
||||
{
|
||||
if (write_preferred_names_idx(dms, tax, tax_name) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3302,16 +3303,17 @@ int obi_close_taxonomy(OBIDMS_taxonomy_p taxonomy)
|
||||
if (taxonomy)
|
||||
{
|
||||
// Update local informations (local taxa and preferred names) if there are any
|
||||
if ((taxonomy->taxa)->local_count > 0)
|
||||
{
|
||||
if (taxonomy->dms == NULL)
|
||||
{
|
||||
obi_set_errno(OBI_TAXONOMY_ERROR);
|
||||
obidebug(1, "\nError closing a taxonomy with local files but no DMS associated (probably read directly from taxdump)"); // TODO discuss
|
||||
}
|
||||
if (write_local_taxonomy_idx(taxonomy->dms, taxonomy, taxonomy->tax_name) < 0)
|
||||
return -1;
|
||||
}
|
||||
// Done with write_taxo, edits all needed files. Only ldx file was edited in OBI1 but it led to issues. Discussable
|
||||
// if ((taxonomy->taxa)->local_count > 0)
|
||||
// {
|
||||
// if (taxonomy->dms == NULL)
|
||||
// {
|
||||
// obi_set_errno(OBI_TAXONOMY_ERROR);
|
||||
// obidebug(1, "\nError closing a taxonomy with local files but no DMS associated (probably read directly from taxdump)"); // TODO discuss
|
||||
// }
|
||||
// if (write_local_taxonomy_idx(taxonomy->dms, taxonomy, taxonomy->tax_name) < 0)
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// Write preferred names if there are some
|
||||
if (taxonomy->preferred_names)
|
||||
@ -3377,9 +3379,10 @@ int obi_close_taxonomy(OBIDMS_taxonomy_p taxonomy)
|
||||
int obi_taxo_add_local_taxon(OBIDMS_taxonomy_p tax, const char* name, const char* rank_name, int32_t parent_taxid, int32_t min_taxid)
|
||||
{
|
||||
int32_t taxid;
|
||||
int32_t count;
|
||||
ecotx_t* taxon;
|
||||
int i;
|
||||
// econame_t* name_struct;
|
||||
econame_t* name_struct;
|
||||
|
||||
// Enlarge the structure memory for a new taxon
|
||||
tax->taxa = (ecotxidx_t*) realloc(tax->taxa, sizeof(ecotxidx_t) + sizeof(ecotx_t) * (((tax->taxa)->count) + 1));
|
||||
@ -3441,42 +3444,65 @@ int obi_taxo_add_local_taxon(OBIDMS_taxonomy_p tax, const char* name, const char
|
||||
((tax->taxa)->local_count)++;
|
||||
(tax->taxa)->buffer_size = (tax->taxa)->count;
|
||||
|
||||
// // Add new name in names structure // Commented because the new name was not added in the .ndx file in the OBITools1
|
||||
// // Allocate memory for new name
|
||||
// tax->names = (econameidx_t*) realloc(tax->names, sizeof(econameidx_t) + sizeof(econame_t) * ((tax->names)->count + 1));
|
||||
// if (tax->names == NULL)
|
||||
// {
|
||||
// obi_set_errno(OBI_MALLOC_ERROR);
|
||||
// obidebug(1, "\nError reallocating memory for a taxonomy structure to add a new taxon");
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// // Add new name
|
||||
// name_struct = (tax->names)->names + ((tax->names)->count);
|
||||
// name_struct->name = (char*) malloc((strlen(name) + 1) * sizeof(char));
|
||||
// if (name_struct->name == NULL)
|
||||
// {
|
||||
// obi_set_errno(OBI_MALLOC_ERROR);
|
||||
// obidebug(1, "\nError allocating memory for a taxon name to add a new taxon");
|
||||
// return -1;
|
||||
// }
|
||||
// strcpy(name_struct->name, name);
|
||||
// name_struct->class_name = (char*) malloc((strlen("scientific name") + 1) * sizeof(char));
|
||||
// if (name_struct->class_name == NULL)
|
||||
// {
|
||||
// obi_set_errno(OBI_MALLOC_ERROR);
|
||||
// obidebug(1, "\nError allocating memory for a taxon class name to add a new taxon");
|
||||
// return -1;
|
||||
// }
|
||||
// strcpy(name_struct->class_name, "scientific name");
|
||||
// name_struct->is_scientific_name = true;
|
||||
// name_struct->taxon = ((tax->taxa)->taxon) + ((tax->taxa)->count) - 1;
|
||||
//
|
||||
// // Sort names in alphabetical order
|
||||
// qsort((tax->names)->names, (tax->names)->count, sizeof(econame_t), cmp_names);
|
||||
//
|
||||
// // Update name count
|
||||
// ((tax->names)->count)++;
|
||||
// Add new name in names structure // On the OBI1, the new name was not added in the .ndx file but it could create issues
|
||||
// Allocate memory for new name
|
||||
tax->names = (econameidx_t*) realloc(tax->names, sizeof(econameidx_t) + sizeof(econame_t) * ((tax->names)->count + 1));
|
||||
if (tax->names == NULL)
|
||||
{
|
||||
obi_set_errno(OBI_MALLOC_ERROR);
|
||||
obidebug(1, "\nError reallocating memory for a taxonomy structure to add a new taxon");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Add new name
|
||||
name_struct = (tax->names)->names + ((tax->names)->count);
|
||||
name_struct->name = (char*) malloc((strlen(name) + 1) * sizeof(char));
|
||||
if (name_struct->name == NULL)
|
||||
{
|
||||
obi_set_errno(OBI_MALLOC_ERROR);
|
||||
obidebug(1, "\nError allocating memory for a taxon name to add a new taxon");
|
||||
return -1;
|
||||
}
|
||||
strcpy(name_struct->name, name);
|
||||
name_struct->class_name = (char*) malloc((strlen("scientific name") + 1) * sizeof(char));
|
||||
if (name_struct->class_name == NULL)
|
||||
{
|
||||
obi_set_errno(OBI_MALLOC_ERROR);
|
||||
obidebug(1, "\nError allocating memory for a taxon class name to add a new taxon");
|
||||
return -1;
|
||||
}
|
||||
strcpy(name_struct->class_name, "scientific name");
|
||||
name_struct->is_scientific_name = true;
|
||||
name_struct->taxon = ((tax->taxa)->taxon) + ((tax->taxa)->count) - 1;
|
||||
|
||||
// Update name count
|
||||
((tax->names)->count)++;
|
||||
|
||||
// Sort names in alphabetical order
|
||||
qsort((tax->names)->names, (tax->names)->count, sizeof(econame_t), cmp_names);
|
||||
|
||||
// Add to merged index
|
||||
tax->merged_idx = (ecomergedidx_t*) realloc(tax->merged_idx, sizeof(ecomergedidx_t) + sizeof(ecomerged_t) * ((tax->merged_idx)->count + 1));
|
||||
if (tax->merged_idx == NULL)
|
||||
{
|
||||
obi_set_errno(OBI_MALLOC_ERROR);
|
||||
obidebug(1, "\nError reallocating memory for a taxonomy structure");
|
||||
return -1;
|
||||
}
|
||||
|
||||
count = (tax->merged_idx)->count;
|
||||
(tax->merged_idx)->count = count + 1;
|
||||
(tax->merged_idx)->merged[count].taxid = taxid;
|
||||
(tax->merged_idx)->merged[count].idx = taxon->idx;
|
||||
|
||||
//fprintf(stderr, "\nEntered in merged taxon.idx=%d", (tax->merged_idx)->merged[(tax->merged_idx)->count -1].idx);
|
||||
//fprintf(stderr, "\nEntered in merged taxon.taxid=%d", (tax->merged_idx)->merged[(tax->merged_idx)->count -1].taxid);
|
||||
//fprintf(stderr, "\nEntered in merged at %d", (tax->merged_idx)->count -1);
|
||||
//taxon = obi_taxo_get_taxon_with_taxid(tax, taxid);
|
||||
//fprintf(stderr, "\ntaxon=%x", taxon);
|
||||
//fprintf(stderr, "\ntaxon.taxid=%d", taxon->taxid);
|
||||
//fprintf(stderr, "\ntaxon.name=%s", taxon->name);
|
||||
//fprintf(stderr, "\ntaxon.idx=%d\n\n", ((tax->merged_idx)->count));
|
||||
|
||||
return taxid;
|
||||
}
|
||||
@ -3547,11 +3573,12 @@ int obi_taxo_add_preferred_name_with_taxon(OBIDMS_taxonomy_p tax, ecotx_t* taxon
|
||||
name_struct->is_scientific_name = false;
|
||||
name_struct->taxon = taxon;
|
||||
|
||||
// Update preferred name count
|
||||
((tax->preferred_names)->count)++;
|
||||
|
||||
// Sort preferred names in alphabetical order
|
||||
qsort((tax->preferred_names)->names, (tax->preferred_names)->count, sizeof(econame_t), cmp_names);
|
||||
|
||||
// Update preferred name count
|
||||
((tax->preferred_names)->count)++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -3669,8 +3696,10 @@ ecotx_t* obi_taxo_get_taxon_with_taxid(OBIDMS_taxonomy_p taxonomy, int32_t taxid
|
||||
else if (indexed_taxon->idx == -1)
|
||||
current_taxon = NULL; // TODO discuss what to do when old deleted taxon
|
||||
else
|
||||
{
|
||||
current_taxon = (taxonomy->taxa->taxon)+(indexed_taxon->idx);
|
||||
|
||||
//fprintf(stderr, "\n>>>idx %d, taxid %d<<<\n", indexed_taxon->idx, indexed_taxon->taxid);
|
||||
}
|
||||
return current_taxon;
|
||||
}
|
||||
|
||||
|
@ -239,6 +239,7 @@ OBIDMS_taxonomy_p obi_read_taxonomy(OBIDMS_p dms, const char* taxonomy_name, boo
|
||||
* @param dms A pointer on the DMS to which the taxonomy belongs.
|
||||
* @param tax A pointer on the taxonomy structure.
|
||||
* @param tax_name The name (prefix) of the taxonomy.
|
||||
* @param update Whether files should be rewritten or if it's a new taxonomy (set to true e.g. after adding local taxa).
|
||||
*
|
||||
* @returns An integer value indicating the success of the operation.
|
||||
* @retval 0 on success.
|
||||
@ -247,7 +248,7 @@ OBIDMS_taxonomy_p obi_read_taxonomy(OBIDMS_p dms, const char* taxonomy_name, boo
|
||||
* @since 2016
|
||||
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
||||
*/
|
||||
int obi_write_taxonomy(OBIDMS_p dms, OBIDMS_taxonomy_p tax, const char* tax_name);
|
||||
int obi_write_taxonomy(OBIDMS_p dms, OBIDMS_taxonomy_p tax, const char* tax_name, bool update);
|
||||
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user