/*****************************************************************************/ /* */ /* UNIT: NTL1_Abs_Corres_1 (Level 1 library routine) */ /* */ /* Author: Nikola Stojanovic */ /* */ /* Revision: 20 JUL 94 Version 1.0 */ /* 01 NOV 95 Version 2.0 */ /* */ /* Function: */ /* */ /* Procedure determines the set of absolute alignment offsets for a */ /* position, given by some origin and offset with respect to it; structures */ /* containing data about the origins and the alignment are provided as input */ /* parameters; returns the standard error structure, NULL if there were no */ /* errors */ /* */ /* NOTE: If there is no absolute correspondent for the given origin/offset */ /* value within the alignment, the procedure still returns valid error */ /* status (NULL), however the results list is also empty (NULL). If */ /* the sequence containing the given origin is not present in the */ /* alignment at all, that is considered to be a genuine error, and */ /* reported as such */ /* */ /*****************************************************************************/ #include #include #include #include "ntl1.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 NTL1_AC1_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: NTL1_Abs_Corres_1 */ /* */ /* Central procedure for the unit; returns NULL if the absolute position */ /* has been found and set of corresponding values allocated, error */ /* diagnostics structure otherwise */ errind NTL1_Abs_Corres_1 (char *reference, long int offset, orgref_ptr origins, header_ptr file_data, align_ptr alignment, int_ptr *result) { char *owner_seq; long int reference_position; orgref_ptr or; long int abs_seq, counter, scanner; int index; bool found; line_ptr tracker; int_ptr new_corr; /* Check the legality of provided offset with respect to origin position */ if (offset == 0) return NTL1_AC1_Assemble_Error (USER_ERROR, ERR_BAD_REFERENCE, "Zero offsets not permitted", 0); /* Determine the "owner" sequence for the given origin (reference) site */ owner_seq = NULL; reference_position = 0; for (or = origins; (or != NULL) && (owner_seq == NULL); or = or -> next) { if (!strcmp (or -> site_name, reference)) { owner_seq = NTL0_strsave (or -> in_species); reference_position = or -> location; } } if (owner_seq == NULL) { sprintf (Error_Message, "Site <%s> not found in origins file", reference); return NTL1_AC1_Assemble_Error (USER_ERROR, ERR_BAD_REFERENCE, Error_Message, 1); } /* Check whether the "owner" sequence is present in the alignment at all */ found = FALSE; index = 0; while ((!found) && (index < file_data -> dimension)) { if (!strcmp (((file_data -> sequences) [index]).seq_name, owner_seq)) found = TRUE; else index++; } if (!found) { sprintf (Error_Message, "Owner sequence <%s> of the origin %s not present in the alignment", owner_seq, reference); return NTL1_AC1_Assemble_Error (USER_ERROR, ERR_BAD_REFERENCE, Error_Message, 2); } /* Calculate the absolute position of the reference in its sequence */ if ((reference_position == 1) && (offset < 0)) abs_seq = offset; else if (offset < 0) abs_seq = reference_position + offset; else abs_seq = reference_position + offset - 1; /* Compensate for lack of 0 */ *result = NULL; /* Start with an empty list of absolute correspondents */ /* Check the legality of calculated absolute position */ /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ /* if (abs_seq <= 0) */ /* return NTL1_AC1_Assemble_Error (USER_ERROR, ERR_BAD_REFERENCE, */ /* "Illegal offset out of alignment", 0); */ /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ if (abs_seq <= 0) return NULL; /* Negative - certainly not in the alignment */ /* Locate the absolute position in the alignment for the requested site */ for (index = 0; index < file_data -> dimension; index++) { /* Sequences... */ if (!strcmp (((file_data -> sequences) [index]).seq_name, owner_seq)) { if ((abs_seq >= (alignment -> begin) [index]) && (abs_seq <= (alignment -> end) [index])) { new_corr = (int_ptr) NTL0_ckalloc (sizeof (Int_Struct)); counter = 0; scanner = (alignment -> begin) [index]; found = FALSE; for (tracker = (alignment -> lines) [index]; (tracker != NULL) && (!found); tracker = tracker -> next) { if (tracker -> code == GAP_STRETCH) counter += tracker -> length; else if (tracker -> code == TEXT_STRETCH) { if (scanner + tracker -> length > abs_seq) { new_corr -> value = counter + abs_seq - scanner; found = TRUE; } else { counter += tracker -> length; scanner += tracker -> length; } } } if (!found) return NTL1_AC1_Assemble_Error (FATAL_ERROR, ERR_CODE_PROBLEM, "Absolute correspondent not found", 3); else { new_corr -> next = *result; *result = new_corr; } } } } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ /* if (*result == NULL) { There was no overlap with any corresponding seq. */ /* sprintf (Error_Message, "Referenced position <%s,%ld> out of alignment", */ /* reference, offset); */ /* return NTL1_AC1_Assemble_Error (WARNING, ERR_NO_VALUE, Error_Message, 0);*/ /* } */ /* else return NULL; At least one absolute correspondent has been located */ /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ return NULL; /* Return with or without absolute correspondent(s) */ } /*****************************************************************************/ /* */ /* Procedure: NTL1_AC1_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 NTL1_AC1_Assemble_Error (int severity, int code, char *comment, int description) { char *report; errind assembled; report = (char *) NTL0_ckalloc ( (strlen (comment) + strlen ("_Abs_Corres_1: ") + 1) * sizeof (char)); sprintf (report, "_Abs_Corres_1: %s", comment); assembled = NTL1_Error_Record (severity, code, report, description); free (report); return assembled; }