/*****************************************************************************/ /* */ /* UNIT: NTL2_Get_Alignment_Copy (Level 2 library routine) */ /* */ /* Author: Nikola Stojanovic */ /* */ /* Revision: 07 SEP 96 Version 1.0 */ /* */ /* Function: */ /* */ /* Procedure uses other library routines to load, unpack and "trim" the */ /* specified alignment - then copies its contents into a simplified internal */ /* structure that enables more efficient analysis - the simplified structure */ /* is then returned as a parameter, while all the other intermediate ones */ /* are discarded; returns the 'standard' error structure, NULL if everything */ /* went OK (may contain a warning in the error structure, though) */ /* */ /*****************************************************************************/ #include #include #include #include "ntl2.h" /*****************************************************************************/ /* */ /* Definitions section */ /* */ /*****************************************************************************/ /*****************************************************************************/ /* Definitions of local constants of the unit */ /*****************************************************************************/ /* Limits for predefined buffer sizes */ #define ERR_MSGLIMIT 128 /*****************************************************************************/ /* Prototypes of all locally used functions of this unit */ /*****************************************************************************/ errind NTL2_GC_Source_File (char *file_name, strlist_ptr search_paths, header_ptr *file_info); errind NTL2_GC_Assemble_Error (int severity, int code, char *comment, int description); /*****************************************************************************/ /* Definitions of global (static) variables of the unit */ /*****************************************************************************/ static char Error_Message [ERR_MSGLIMIT]; /* Temporary buffer, error passing */ /*****************************************************************************/ /* */ /* Code section */ /* */ /*****************************************************************************/ /*****************************************************************************/ /* */ /* PROCEDURE: NTL2_Get_Alignment_Copy */ /* */ /* Central procedure for the unit - distribution of the actions; returns */ /* error status, NULL if everything was done without problems or warnings */ errind NTL2_Get_Alignment_Copy (char *file_name, strlist_ptr search_paths, int number, char *pivot_seq, long int from, long int to, restricted_ptr *alignment) { header_ptr file_info; align_ptr packed; unpacked_ptr expanded; line_ptr line_al, last_line; int seqs, count; errind err_stat, err_ret; /* First find and load the requested file, then deal with alignment(s) data */ if ((err_stat = NTL2_GC_Source_File (file_name, search_paths, &file_info)) != NULL) return err_stat; else { /* File correctly loaded - get the alignment */ if ((number < 1) || (number > file_info -> numalign)) { sprintf (Error_Message, "Illegal alignment number (%d) request (total %d)", number, file_info -> numalign); return NTL2_GC_Assemble_Error (USER_ERROR, ERR_BAD_VALUE, Error_Message, 0); } else { /* Particular alignment number requested */ if ((err_stat = NTL1_Load_Alignment (number, file_info, &packed)) != NULL) return err_stat; else if ((err_stat = NTL2_Unpack_Alignment (number, file_info, packed, search_paths, &expanded)) != NULL) return err_stat; else { /* Expansion of the full alignment done OK, check for restriction */ if (pivot_seq != NULL) { if ((err_stat = NTL1_Cut_Alignment (file_info, expanded, pivot_seq, from, to)) != NULL) { if (err_stat -> kind != WARNING) return err_stat; else err_ret = err_stat; } else err_ret = NULL; } else err_ret = NULL; /* Now copy the full expanded alignment into a simplified structure */ *alignment = (restricted_ptr) NTL0_ckalloc (sizeof (Restricted_Struct)); count = 0; for (seqs = 0; seqs < expanded -> dimension; seqs++) { if ((expanded -> segment_code) [seqs] == VALID_SEGMENT) count++; } (*alignment) -> dimension = count; (*alignment) -> size = expanded -> size; (*alignment) -> texts = (char **) NTL0_ckalloc (count * sizeof (char *)); (*alignment) -> begin = (long int *) NTL0_ckalloc (count * sizeof (long int *)); (*alignment) -> end = (long int *) NTL0_ckalloc (count * sizeof (long int *)); (*alignment) -> starts = (long int *) NTL0_ckalloc (count * sizeof (long int *)); (*alignment) -> stops = (long int *) NTL0_ckalloc (count * sizeof (long int *)); count = 0; for (seqs = 0; seqs < expanded -> dimension; seqs++) { if ((expanded -> segment_code) [seqs] == VALID_SEGMENT) { ((*alignment) -> texts) [count] = (expanded -> texts) [seqs]; ((*alignment) -> begin) [count] = (expanded -> begin) [seqs]; ((*alignment) -> end) [count] = (expanded -> end) [seqs]; ((*alignment) -> starts) [count] = (expanded -> starts) [seqs]; ((*alignment) -> stops) [count] = (expanded -> stops) [seqs]; count++; } } /* Destroy the "file_info" structure, since its contents are not needed */ /* ### To be defined ################################################### */ /* Destroy "partially unpacked" structure used in the expansion - done */ if (packed -> begin != NULL) free (packed -> begin); if (packed -> end != NULL) free (packed -> end); if (packed -> lines != NULL) { for (seqs = 0; seqs < expanded -> dimension; seqs++) { line_al = (packed -> lines) [seqs]; while (line_al != NULL) { last_line = line_al; line_al = line_al -> next; free (last_line); } } } free (packed); /* Destroy the expanded alignment info now when the restricted copy made */ /* ### To be defined ################################################### */ return err_ret; } } } } /*****************************************************************************/ /* */ /* Internal procedures for maintenance and execution of external requests */ /* */ /*****************************************************************************/ /*****************************************************************************/ /* */ /* PROCEDURE: NTL2_GC_Source_File */ /* */ /* Procedure loads the "header structure" with the information from the */ /* specified alignment file - if the file has not been found in the */ /* current directory, it tries to find it in all specified search paths; */ /* returns the error structure, NULL if loading done without errors */ errind NTL2_GC_Source_File (char *file_name, strlist_ptr search_paths, header_ptr *file_info) { strlist_ptr current_path; char *new_path; errind err_stat; /* Check first whether the alignment file is accessible by the given name */ *file_info = NULL; err_stat = NULL; if ((err_stat = NTL2_Load_AlignFile (file_name, file_info)) != NULL) { /* If file not found try all the paths from the provided paths list */ *file_info = NULL; current_path = search_paths; while ((*file_info == NULL) && (current_path != NULL)) { new_path = NTL0_ckalloc ((strlen (current_path -> string) + strlen (file_name) + 2) * sizeof (char)); strcpy (new_path, current_path -> string); if (file_name [0] != '/') strcat (new_path, "/"); strcat (new_path, file_name); if ((err_stat = NTL2_Load_AlignFile (new_path, file_info)) != NULL) { *file_info = NULL; current_path = current_path -> next; } free (new_path); } } /* If the alignment file could not be located at any location, report error */ if (*file_info == NULL) { if (err_stat != NULL) return err_stat; else return NTL2_GC_Assemble_Error (SYSTEM_ERROR, ERR_NO_VALUE, "File data not loaded - no report", 0); } else return NULL; } /*****************************************************************************/ /* */ /* Procedure: NTL2_GC_Assemble_Error */ /* */ /* Service procedure for assembling and returnning an error report, based on */ /* the values of the input parameters; returns the record with the report */ errind NTL2_GC_Assemble_Error (int severity, int code, char *comment, int description) { char *report; errind assembled; report = (char *) NTL0_ckalloc ( (strlen (comment) + strlen ("_Get_Alignment_Copy: ") + 1) * sizeof (char)); sprintf (report, "_Get_Alignment_Copy: %s", comment); assembled = NTL1_Error_Record (severity, code, report, description); free (report); return assembled; }