gde_linux/HGL_SRC/HGLfuncs.c

2850 lines
68 KiB
C
Executable File

/****************************************************************
*
* This is a set of functions defined for the genome
* project.
*
****************************************************************/
#ifndef _GLOBAL_DEFS_H
#define _GLOBAL_DEFS_H
#include <ctype.h>
#include <stdlib.h>
#include "global_defs.h"
#endif
#define MAXLINELEN 256
static char Default_DNA_Trans[16] = {'-', 'a', 'c', 'm', 'g', 'r', 's', 'v',
't', 'w', 'y', 'h', 'k', 'd', 'b', 'n'};
/***********
*
* WriteRecord() outputs one record at a time in HGL format.
* Only the fields in the fields_array will be output. All the
* fields will be output if fields_array is NULL.
*
* fp : pointer to the output file.
* tSeq: pointer to the record.
* fields_array: contains the field ids of the selected fields.
* array_size: number of selected fields.
*
* Returns: 1 if any field is printed;
* 0 if no field is printed;
* -1 if anything is wrong.
*
**********/
int WriteRecord(fp, tSeq, fields_array, array_size)
FILE *fp;
const Sequence *tSeq;
int *fields_array;
int array_size;
{
int i, save_str_size, tt;
int all_fields = FALSE;
int first_field = TRUE;
char temp_str[256];
char *save_str;
char *ptr;
save_str = (char *)Calloc(256, 1);
save_str_size = 256;
/* When all the fields are selected. */
if (fields_array == NULL) {
all_fields = TRUE;
fields_array = (int *)Calloc(NUM_OF_FIELDS, sizeof(int));
for (i = 0; i < NUM_OF_FIELDS; i++) {
fields_array[i] = i;
}
array_size = NUM_OF_FIELDS;
}
for (i = 0; i < array_size; i++) {
save_str[0] = '\0';
if (fields_array[i] == e_creation_date &&
tSeq->creation_date[0] != 0) {
sprintf(save_str, "\n%s\t%d/%d/%d ",
at[fields_array[i]], tSeq->creation_date[1],
tSeq->creation_date[2], tSeq->creation_date[0]);
if (tSeq->creation_date[3] >= 0) {
if (tSeq->creation_date[4] < 0)
tSeq->creation_date[4] = 0;
if (tSeq->creation_date[5] < 0)
tSeq->creation_date[5] = 0;
sprintf(save_str, "%s%d:%d:%d", save_str,
tSeq->creation_date[3],
tSeq->creation_date[4],
tSeq->creation_date[5]);
}
}
else if (fields_array[i] == e_probing_date &&
tSeq->probing_date[0] != 0) {
sprintf(save_str, "\n%s\t%d/%d/%d ",
at[fields_array[i]], tSeq->probing_date[1],
tSeq->probing_date[2], tSeq->probing_date[0]);
if (tSeq->probing_date[3] >= 0) {
if (tSeq->probing_date[4] < 0)
tSeq->probing_date[4] = 0;
if (tSeq->probing_date[5] < 0)
tSeq->probing_date[5] = 0;
sprintf(save_str, "%s%d:%d:%d", save_str,
tSeq->probing_date[3],
tSeq->probing_date[4],
tSeq->probing_date[5]);
}
}
else if (fields_array[i] == e_autorad_date &&
tSeq->autorad_date[0] != 0) {
sprintf(save_str, "\n%s\t%d/%d/%d ",
at[fields_array[i]], tSeq->autorad_date[1],
tSeq->autorad_date[2], tSeq->autorad_date[0]);
if (tSeq->autorad_date[3] >= 0) {
if (tSeq->autorad_date[4] < 0)
tSeq->autorad_date[4] = 0;
if (tSeq->autorad_date[5] < 0)
tSeq->autorad_date[5] = 0;
sprintf(save_str, "%s%d:%d:%d", save_str,
tSeq->autorad_date[3],
tSeq->autorad_date[4],
tSeq->autorad_date[5]);
}
}
else if (fields_array[i] == e_c_elem && tSeq->c_elem != NULL) {
ptr = tSeq->c_elem;
sprintf(save_str, "\n%s\t\"", at[fields_array[i]]);
while (ptr < tSeq->c_elem + tSeq->seqlen) {
if (ptr != tSeq->c_elem) strcat(save_str, "\n");
strncpy(
temp_str, ptr,
MIN(60, tSeq->c_elem + tSeq->seqlen - ptr));
temp_str[MIN(60, tSeq->c_elem + tSeq->seqlen -
ptr)] = '\0';
/* Gurantee strlen(temp_str) chars for the
* string, one for \n, one for ", and one for
* \0.
*/
while (save_str_size - strlen(save_str) <
strlen(temp_str) + 3) {
save_str_size *= 2;
save_str = (char *)Realloc(
save_str, save_str_size);
}
strcat(save_str, temp_str);
ptr += 60;
}
strcat(save_str, "\"");
}
else if (fields_array[i] == e_comments &&
tSeq->commentslen != 0) {
while (save_str_size < 20 + tSeq->commentslen) {
save_str_size *= 2;
save_str =
(char *)Realloc(save_str, save_str_size);
}
strcat(save_str, "\n");
strcat(save_str, at[fields_array[i]]);
strcat(save_str, "\t\"\n");
/* put a \0 at the end of comments. */
while (tSeq->commentslen + 1 > tSeq->commentsmaxlen) {
tSeq->commentsmaxlen *= 2;
tSeq->comments = (char *)Realloc(
tSeq->comments, tSeq->commentsmaxlen);
}
tSeq->comments[tSeq->commentslen] = '\0';
/* clean up the leading empty lines.*/
tt = 0;
while (tSeq->comments[tt] == '\n' ||
tSeq->comments[tt] == ' ')
tt++;
tSeq->commentslen -= tt;
strcat(save_str, tSeq->comments + tt);
strcat(save_str, "\"");
}
else if (fields_array[i] == e_laneset && tSeq->laneset != -1)
sprintf(save_str, "\n%s\t\t%d", at[fields_array[i]],
tSeq->laneset);
else if (fields_array[i] == e_strandedness &&
tSeq->strandedness != 0)
sprintf(save_str, "\n%s\t%d", at[fields_array[i]],
tSeq->strandedness);
else if (fields_array[i] == e_direction && tSeq->direction != 0)
sprintf(save_str, "\n%s\t%d", at[fields_array[i]],
tSeq->direction);
else if (fields_array[i] == e_orig_strand &&
tSeq->orig_strand != 0)
sprintf(save_str, "\n%s\t%d", at[fields_array[i]],
tSeq->orig_strand);
else if (fields_array[i] == e_orig_direction &&
tSeq->orig_direction != 0)
sprintf(save_str, "\n%s\t%d", at[fields_array[i]],
tSeq->orig_direction);
else if (fields_array[i] == e_offset)
sprintf(save_str, "\n%s\t\t%d", at[fields_array[i]],
tSeq->offset);
else if (fields_array[i] == e_group_number &&
tSeq->group_number != 0)
sprintf(save_str, "\n%s\t%d", at[fields_array[i]],
tSeq->group_number);
else if (fields_array[i] == e_group_ID)
sprintf(save_str, "\n%s\t%d", at[fields_array[i]],
tSeq->group_ID);
else if (fields_array[i] == e_type && tSeq->type[0] != '\0')
sprintf(save_str, "\n%s\t\t\"%s\"", at[fields_array[i]],
tSeq->type);
else if (fields_array[i] == e_barcode &&
tSeq->barcode[0] != '\0')
sprintf(save_str, "\n%s\t\t\"%s\"", at[fields_array[i]],
tSeq->barcode);
else if (fields_array[i] == e_name && tSeq->name[0] != '\0')
sprintf(save_str, "\n%s\t\t\"%s\"", at[fields_array[i]],
tSeq->name);
else if (fields_array[i] == e_status && tSeq->status[0] != '\0')
sprintf(save_str, "\n%s\t\t\"%s\"", at[fields_array[i]],
tSeq->status);
else if (fields_array[i] == e_walk && tSeq->walk[0] != '\0')
sprintf(save_str, "\n%s\t\t\"%s\"", at[fields_array[i]],
tSeq->walk);
else if (fields_array[i] == e_sequence_ID &&
tSeq->sequence_ID[0] != '\0')
sprintf(save_str, "\n%s\t\"%s\"", at[fields_array[i]],
tSeq->sequence_ID);
else if (fields_array[i] == e_creator &&
tSeq->creator[0] != '\0')
sprintf(save_str, "\n%s\t\t\"%s\"", at[fields_array[i]],
tSeq->creator);
else if (fields_array[i] == e_film && tSeq->film[0] != '\0')
sprintf(save_str, "\n%s\t\t\"%s\"", at[fields_array[i]],
tSeq->film);
else if (fields_array[i] == e_membrane &&
tSeq->membrane[0] != '\0')
sprintf(save_str, "\n%s\t\"%s\"", at[fields_array[i]],
tSeq->membrane);
else if (fields_array[i] == e_source_ID &&
tSeq->source_ID[0] != '\0')
sprintf(save_str, "\n%s\t\"%s\"", at[fields_array[i]],
tSeq->source_ID);
else if (fields_array[i] == e_contig && tSeq->contig[0] != '\0')
sprintf(save_str, "\n%s\t\t\"%s\"", at[fields_array[i]],
tSeq->contig);
else if (fields_array[i] == e_baggage && tSeq->baglen != 0) {
if (save_str_size < tSeq->baglen + 2) {
save_str_size = tSeq->baglen + 2;
save_str =
(char *)Realloc(save_str, save_str_size);
}
save_str[0] = '\n';
save_str[1] = '\0';
/* put a \0 at the end of baggage. */
strncat(save_str, tSeq->baggage, tSeq->baglen);
while (save_str[tSeq->baglen - 1] == '\n') {
tSeq->baglen--;
}
save_str[tSeq->baglen] = '\0';
}
if (save_str[0] != '\0') {
if (first_field == TRUE) {
first_field = FALSE;
fprintf(fp, "{");
}
fprintf(fp, "%s", save_str);
}
}
if (first_field == FALSE) {
fprintf(fp, "\n}\n");
}
if (all_fields == TRUE && fields_array != NULL) {
Cfree(fields_array);
fields_array = NULL;
}
if (save_str != NULL) {
Cfree(save_str);
save_str = NULL;
}
if (first_field == TRUE)
return 0;
else
return 1;
}
/*********
*
* ReadRecord() reads one record from fp into tSeq. fp remains at
* the finishing position so that next time when ReadRecord() is
* called, it reads the next record.
*
* The caller program should LOCATE MEMORY for the tSeq before calling.
*
* ReadRecord() returns:
* TRUE if no error;
* FALSE if anything is wrong
* -1 if end-of-file is reached
*
**********/
int ReadRecord(fp, tSeq)
FILE *fp;
Sequence *tSeq;
{
char field_name[20], line[256], orig_line[256];
int temp_str_size, start, end, l, max_len = 255;
char *fgets_ret, *temp_str, *fgets_ret1;
int start_rec = FALSE;
int need_to_read = TRUE;
char started = 'F';
void InitRecord();
void FreeRecord();
temp_str = (char *)Calloc(256, 1);
temp_str_size = 256;
InitRecord(tSeq);
if (tSeq->c_elem == NULL) {
tSeq->c_elem = (char *)Calloc(256, 1);
tSeq->seqmaxlen = 256;
}
tSeq->c_elem[0] = '\0';
/* read file line-by-line. */
while (need_to_read == TRUE &&
((fgets_ret = fgets(line, max_len, fp)) != NULL ||
start_rec == TRUE)) {
strcpy(orig_line, line);
end = strlen(line) - 1;
while (end >= 0 && (line[end] == ' ' || line[end] == '\t' ||
line[end] == ',' || line[end] == '\n'))
end--;
/* ignore empty lines. */
if (end == -1) continue;
if (line[end] == '{') started = 'T';
/* to ignore the lines between a } and a {. */
while (started == 'F' && fgets_ret != NULL) {
fgets_ret = fgets(line, max_len, fp);
strcpy(orig_line, line);
end = strlen(line) - 1;
while (end >= 0 &&
(line[end] == ' ' || line[end] == '\t' ||
line[end] == ',' || line[end] == '\n'))
end--;
/* ignore empty lines. */
if (end == -1) continue;
if (line[end] == '{') started = 'T';
}
if (fgets_ret == NULL) return -1;
if (end < 0) {
}
else if ((line[end] == '}') && (end == 0)) {
start_rec = FALSE;
need_to_read = FALSE;
}
else if (line[end] == '{' && end <= 10) {
start_rec = TRUE;
}
else {
if (line[end] == '}') {
need_to_read = FALSE;
start_rec = FALSE;
}
/* locate the tag. */
start = 0;
while (line[start] == ' ' || line[start] == '\t' ||
line[start] == '\n' || line[start] == '{')
start++;
end = start + 1;
while (line[end] != ' ' && line[end] != '\t' &&
line[end] != '\n' && line[end] != '\0')
end++;
strncpy(field_name, line + start, end - start);
field_name[end - start] = '\0';
/* process the field value. */
/*
* creation_date, probing_date, or autorad_date
*/
if (strcmp(field_name, "creation-date") == 0) {
while (!isdigit(line[end])) end++;
if (strToDate(line + end,
tSeq->creation_date) == -1) {
return FALSE;
}
}
else if (strcmp(field_name, "probing-date") == 0) {
while (line[end] != '\0' && !isdigit(line[end]))
end++;
if (line[end] != '\0' &&
strToDate(line + end, tSeq->probing_date) ==
-1) {
return FALSE;
}
}
else if (strcmp(field_name, "autorad-date") == 0) {
while (line[end] != '\0' && !isdigit(line[end]))
end++;
if (line[end] != '\0' &&
strToDate(line + end, tSeq->autorad_date) ==
-1) {
return FALSE;
}
}
/*
* sequence or comments.
*/
else if (strcmp(field_name, "sequence") == 0 ||
strcmp(field_name, "comments") == 0) {
temp_str[0] = '\0';
/* locate the first ". */
while (line[end++] != '"')
;
start = end;
end = strlen(line);
/* ---"\n\0. */
if (line[end - 2] == '"')
end -= 2;
else if (line[end - 1] == '\n' &&
strcmp(field_name, "sequence") == 0)
end--;
while (temp_str_size < end - start + 1) {
temp_str_size *= 2;
temp_str = (char *)Realloc(
temp_str, temp_str_size);
}
if (end - start > 0)
strncat(temp_str, line + start,
end - start);
/* Read the second line of the seq. or comments,
if any. end-start<0 is the case that " is the
only char this line.*/
if (line[strlen(line) - 2] != '"' ||
end - start < 0) {
while ((fgets_ret1 =
fgets(line, max_len, fp)) !=
NULL) {
/* IGNORE empty lines. 5/4/92 */
int empty_line = 0;
while (line[empty_line] == ' ')
empty_line++;
if (line[empty_line] == '\n') {
continue;
/* strncat(temp_str,
* line, end); 5/4/92 */
}
l = strlen(line) - 1;
if (line[l - 1] == '"')
end = l - 1;
else
end = l;
if (line[end] == '\n' &&
strcmp(field_name,
"comments") == 0)
end++;
/* Gurantee 'end' chars for the
* string, one for ", and one
* for \0.
*/
while (temp_str_size -
strlen(temp_str) <
end + 3) {
temp_str_size *= 2;
temp_str =
(char *)Realloc(
temp_str,
temp_str_size);
}
strncat(temp_str, line, end);
if (line[l - 1] == '"') break;
}
if (fgets_ret1 == NULL &&
need_to_read == TRUE) {
fprintf(stderr,
"ReadRecord(): "
"incomplete record.\n");
return FALSE;
}
}
l = strlen(temp_str);
if (strcmp(field_name, "comments") == 0) {
if (tSeq->commentsmaxlen == 0) {
tSeq->comments =
(char *)Calloc(l + 1, 1);
tSeq->commentsmaxlen = l + 1;
}
else {
while (tSeq->commentslen + l +
1 >
tSeq->commentsmaxlen) {
tSeq->commentsmaxlen *=
2;
tSeq->comments =
(char *)Realloc(
tSeq->comments,
tSeq->commentsmaxlen);
}
}
tSeq->comments[tSeq->commentslen] =
'\0';
strcat(tSeq->comments, temp_str);
tSeq->commentslen += l;
}
else /* it is the sequence. */
{
if (tSeq->seqmaxlen == 0) {
tSeq->c_elem =
(char *)Calloc(l + 1, 1);
}
else if (l + 1 > tSeq->seqmaxlen) {
tSeq->c_elem = (char *)Realloc(
tSeq->c_elem, l + 1);
}
tSeq->seqmaxlen = l + 1;
tSeq->seqlen = l;
strcpy(tSeq->c_elem, temp_str);
}
}
/*
* Integer or String.
*/
else {
/* locate the value: a string or an integer. */
while (line[end] == ' ' || line[end] == '\t')
end++;
if (line[end] == '"') {
/* It is a string. */
end++;
start = end;
while (line[end] != '\0' &&
line[end] != '"')
end++;
/*
* strncat will not put a \0 at the end
* of a string if the copying string is
* longer than n.
*/
line[end++] = '\0';
}
else {
/* It is an integer. */
start = end;
while (line[end] != ' ' &&
line[end] != '\t' &&
line[end] != '\n' &&
line[end] != '\0')
end++;
strncpy(temp_str, line + start,
end - start + 1); /*4/26 add 1*/
temp_str[end - start] = '\0';
}
/* assign to an integer field. */
if (strcmp(field_name, "laneset") == 0)
tSeq->laneset = atoi(temp_str);
else if (strcmp(field_name, "strandedness") ==
0)
tSeq->strandedness = atoi(temp_str);
else if (strcmp(field_name, "direction") == 0)
tSeq->direction = atoi(temp_str);
else if (strcmp(field_name, "orig_strand") == 0)
tSeq->orig_strand = atoi(temp_str);
else if (strcmp(field_name, "orig_direction") ==
0)
tSeq->orig_direction = atoi(temp_str);
else if (strcmp(field_name, "offset") == 0)
tSeq->offset = atoi(temp_str);
else if (strcmp(field_name, "group-number") ==
0)
tSeq->group_number = atoi(temp_str);
else if (strcmp(field_name, "group-ID") == 0)
tSeq->group_ID = atoi(temp_str);
/* assign to a string field. */
else if (strcmp(field_name, "type") == 0) {
if (end - start > 31) end = start + 31;
strncpy(tSeq->type, line + start,
end - start);
tSeq->type[end - start] = '\0';
}
else if (strcmp(field_name, "barcode") == 0) {
if (end - start > 31) end = start + 31;
strncpy(tSeq->barcode, line + start,
end - start);
tSeq->barcode[end - start] = '\0';
}
else if (strcmp(field_name, "name") == 0) {
if (end - start > 31) end = start + 31;
strncpy(tSeq->name, line + start,
end - start);
tSeq->name[end - start] = '\0';
}
else if (strcmp(field_name, "status") == 0) {
if (end - start > 31) end = start + 31;
strncpy(tSeq->status, line + start,
end - start);
tSeq->status[end - start] = '\0';
}
else if (strcmp(field_name, "walk") == 0) {
if (end - start > 31) end = start + 31;
strncpy(tSeq->walk, line + start,
end - start);
tSeq->walk[end - start] = '\0';
}
else if (strcmp(field_name, "sequence-ID") ==
0) {
if (end - start > 31) end = start + 31;
strncpy(tSeq->sequence_ID, line + start,
end - start);
tSeq->sequence_ID[end - start] = '\0';
}
else if (strcmp(field_name, "creator") == 0) {
if (end - start > 31) end = start + 31;
strncpy(tSeq->creator, line + start,
end - start);
tSeq->creator[end - start] = '\0';
}
else if (strcmp(field_name, "film") == 0) {
if (end - start > 31) end = start + 31;
strncpy(tSeq->film, line + start,
end - start);
tSeq->film[end - start] = '\0';
}
else if (strcmp(field_name, "membrane") == 0) {
if (end - start > 31) end = start + 31;
strncpy(tSeq->membrane, line + start,
end - start);
tSeq->membrane[end - start] = '\0';
}
else if (strcmp(field_name, "source-ID") == 0) {
if (end - start > 31) end = start + 31;
strncpy(tSeq->source_ID, line + start,
end - start);
tSeq->source_ID[end - start] = '\0';
}
else if (strcmp(field_name, "contig") == 0) {
if (end - start > 31) end = start + 31;
strncpy(tSeq->contig, line + start,
end - start);
tSeq->contig[end - start] = '\0';
}
else {
if (tSeq->bagmaxlen == 0) {
tSeq->bagmaxlen =
4 * strlen(orig_line);
tSeq->baggage = (char *)Calloc(
tSeq->bagmaxlen, 1);
}
else {
while (tSeq->bagmaxlen <
tSeq->baglen + 2 +
strlen(orig_line)) {
tSeq->bagmaxlen *= 2;
tSeq->baggage =
(char *)Realloc(
tSeq->baggage,
tSeq->bagmaxlen);
}
}
if (tSeq->baglen == 0) {
/*
tSeq->baggage[0] = '\n';
tSeq->baggage[1] = '\0';
tSeq->baglen = 1;
*/
tSeq->baggage[0] = '\0';
}
/* strcat(tSeq->baggage, "\n");*/
strcat(tSeq->baggage, orig_line);
tSeq->baglen += strlen(orig_line);
}
}
}
}
if (temp_str != NULL) {
Cfree(temp_str);
temp_str = NULL;
}
if (start_rec == FALSE && fgets_ret == NULL) {
/* end of file, did not get a record. */
return -1;
}
else
return TRUE;
}
/*********
*
* Initialize a record.
*
* Note: no memory allocation is performed.
*
**********/
void InitRecord(tSeq) Sequence *tSeq;
{
int i;
strcpy(tSeq->type, "DNA");
tSeq->barcode[0] = '\0';
tSeq->name[0] = '\0';
tSeq->status[0] = '\0';
strcpy(tSeq->walk, "FALSE");
tSeq->sequence_ID[0] = '\0';
tSeq->c_elem = NULL;
tSeq->seqlen = 0;
tSeq->seqmaxlen = 0;
for (i = 0; i < 6; i++) {
tSeq->creation_date[i] = 0;
tSeq->probing_date[i] = 0;
tSeq->autorad_date[i] = 0;
}
tSeq->creator[0] = '\0';
tSeq->film[0] = '\0';
tSeq->membrane[0] = '\0';
tSeq->source_ID[0] = '\0';
tSeq->contig[0] = '\0';
tSeq->laneset = -1;
tSeq->direction = 1; /* (1/-1/0),default: 5 to 3. */
tSeq->strandedness = 1; /* (1/2/0), default: primary.*/
tSeq->orig_direction = 0; /* (0 unknown, -1:3'->5', 1:5'->3') */
tSeq->orig_strand = 0; /* (0 unknown, 1:primary, 2:secondary) */
tSeq->offset = 0;
tSeq->comments = NULL;
tSeq->commentslen = 0;
tSeq->commentsmaxlen = 0;
tSeq->baggage = NULL;
tSeq->baglen = 0;
tSeq->bagmaxlen = 0;
tSeq->group_number = 0;
tSeq->group_ID = 0;
}
void CopyRecord(to, from) Sequence *from, *to;
{
int i;
InitRecord(to);
strcpy(to->type, from->type);
strcpy(to->barcode, from->barcode);
strcpy(to->name, from->name);
strcpy(to->status, from->status);
strcpy(to->walk, from->walk);
strcpy(to->sequence_ID, from->sequence_ID);
if (from->c_elem != NULL) {
to->seqlen = from->seqlen;
to->seqmaxlen = from->seqmaxlen;
to->c_elem = (char *)Calloc(to->seqmaxlen, 1);
strncpy(to->c_elem, from->c_elem, to->seqlen);
to->c_elem[to->seqlen] = '\0';
}
for (i = 0; i < 6; i++) {
to->creation_date[i] = from->creation_date[i];
to->probing_date[i] = from->probing_date[i];
to->autorad_date[i] = from->autorad_date[i];
}
strcpy(to->creator, from->creator);
strcpy(to->film, from->film);
strcpy(to->membrane, from->membrane);
strcpy(to->source_ID, from->source_ID);
strcpy(to->contig, from->contig);
to->laneset = from->laneset;
to->strandedness = from->strandedness;
to->orig_direction = from->orig_direction;
to->orig_strand = from->orig_strand;
to->direction = from->direction;
to->offset = from->offset;
if (from->comments != NULL) {
to->commentsmaxlen = from->commentsmaxlen;
to->commentslen = from->commentslen;
to->comments = (char *)Calloc(to->commentsmaxlen, 1);
strncpy(to->comments, from->comments, to->commentslen);
to->comments[to->commentslen] = '\0';
}
if (from->baggage != NULL) {
to->baglen = from->baglen;
to->bagmaxlen = from->bagmaxlen;
to->baggage = (char *)Calloc(to->bagmaxlen, 1);
strncpy(to->baggage, from->baggage, to->baglen);
to->baggage[to->baglen] = '\0';
}
to->group_number = from->group_number;
to->group_ID = from->group_ID;
}
/*********
*
* Clean the contents of a record without changing the memory size.
*
**********/
void CleanRecord(tSeq) Sequence *tSeq;
{
int i;
strcpy(tSeq->type, "DNA");
tSeq->name[0] = '\0';
tSeq->barcode[0] = '\0';
tSeq->status[0] = '\0';
strcpy(tSeq->walk, "FALSE");
tSeq->sequence_ID[0] = '\0';
if (tSeq->c_elem != NULL) tSeq->c_elem[0] = '\0';
tSeq->seqlen = 0;
for (i = 0; i < 6; i++) {
tSeq->creation_date[i] = 0;
tSeq->probing_date[i] = 0;
tSeq->autorad_date[i] = 0;
}
tSeq->creator[0] = '\0';
tSeq->film[0] = '\0';
tSeq->membrane[0] = '\0';
tSeq->source_ID[0] = '\0';
tSeq->contig[0] = '\0';
tSeq->laneset = -1;
tSeq->strandedness = 1; /* (1/2/0), default. primary. */
tSeq->direction = 1; /* (1/-1/0),default. 5 to 3. */
tSeq->orig_direction = 0;
tSeq->orig_strand = 0;
tSeq->offset = 0;
if (tSeq->comments != NULL) tSeq->comments[0] = '\0';
tSeq->commentslen = 0;
if (tSeq->baggage != NULL) tSeq->baggage[0] = '\0';
tSeq->baglen = 0;
tSeq->group_number = 0;
tSeq->group_ID = 0;
}
/*********
*
* Free memory for a record.
*
**********/
void FreeRecord(tSeq) Sequence **tSeq;
{
Cfree((*tSeq)->c_elem);
Cfree((*tSeq)->comments);
Cfree((*tSeq)->baggage);
Cfree((*tSeq));
(*tSeq)->c_elem = NULL;
(*tSeq)->comments = NULL;
(*tSeq)->baggage = NULL;
(*tSeq) = NULL;
}
static max_day[2][13] = {{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
/***********
*
* strToDate() locates first six integers and translates them
* into a date.
*
* String should have the format of "mm/dd/yy hh/mn/sc xm",
* with anything except digit as the delimiters.
*
* Order in the date array is (0->5): (yy mm dd hh mn sc).
*
* Returns FALSE if anything is wrong, TRUE otherwise.
*
**********/
int strToDate(str, date) const char *str;
int date[];
{
int leap;
char temp_str[2];
char longstr[256];
/* locate 6 integers. */
strcpy(longstr, str);
strcat(longstr, " -1/-1/-1 ");
sscanf(longstr, "%d%*c%d%*c%d%*c%d%*c%d%*c%d%2s", &date[1], &date[2],
&date[0], &date[3], &date[4], &date[5], temp_str);
/* verify year. */
if (date[0] >= 100) date[0] -= 1900;
/* verify month. */
if (date[1] > 12 || date[1] < 1) {
fprintf(stderr, "invalid month %s\n", str);
return FALSE;
}
/* verify day. */
if ((date[0] % 4 == 0 && date[0] % 100 != 0) || date[0] % 400 == 0)
leap = 1;
else
leap = 0;
if (date[2] > max_day[leap][date[1]] || date[2] < 1) {
fprintf(stderr, "invalid day %s\n", str);
return FALSE;
}
/* verify time. */
if (strncmp(temp_str, "pm", 2) == 0) date[3] += 12;
if (date[3] < -1 || date[3] > 23 || date[4] < -1 || date[4] > 59 ||
date[5] < -1 || date[5] > 59) {
fprintf(stderr, "invalid time %s\n", str);
return FALSE;
}
return TRUE;
}
/**********
*
* Default_IUPAC_Trans() translates an ASCII IUPAC code into
* an (char) integer.
*
**********/
char Default_IUPAC_Trans(base)
char base;
{
int i;
char c;
c = base | 32;
if (c == 'u') return (char)8;
if (c == 'p') return (char)5;
for (i = 0; i < 16; i++) {
if (c == Default_DNA_Trans[i]) {
return ((char)i);
}
}
fprintf(stderr, "Character %c is not IUPAC coded.\n", base);
return -1;
}
char *uniqueID();
/***********
*
* MakeConsensus() takes an array of aligned sequence and an
* initialized 'Sequence' consensus. It modifies the consensus.
*
* The memory that 'consensus' has located will be reused, and
* consensus->seqmaxlen will be modified if necessary.
*
* Returns TRUE if successful, FALSE otherwise.
*
**********/
int MakeConsensus(aligned, numOfAligned, consensus, group)
Sequence aligned[]; /* input. */
int numOfAligned; /* input. */
Sequence *consensus; /* input and output. */
int group; /* Group number (if zero, use all groups) */
{
char occurence;
int i, j, index;
int max_cons = INT_MIN;
int min_offset = INT_MAX;
char temp_str[2];
unsigned char case_bit;
/*
* Search for the minimun offset.
*/
for (i = 0; i < numOfAligned; i++) {
if (group == 0 || aligned[i].group_number == group) {
SeqNormal(&aligned[i]);
min_offset = MIN(min_offset, aligned[i].offset);
max_cons = MAX(max_cons,
aligned[i].offset + aligned[i].seqlen);
}
}
/*
* Decide consensus base by base.
*/
CleanRecord(consensus);
consensus->offset = min_offset;
if (aligned[0].contig[0] != '\0') {
strcpy(consensus->name, aligned[0].contig);
strcat(consensus->name, ".");
}
else if (strncmp(aligned[0].name, "cons.", 5) != 0) {
strcpy(consensus->name, "cons.");
strcat(consensus->name, aligned[0].name);
}
strcpy(consensus->sequence_ID, uniqueID());
strcpy(consensus->contig, aligned[0].contig);
for (j = min_offset; j < max_cons; j++) {
occurence = 00;
case_bit = 0;
for (i = 0; i < numOfAligned; i++) {
if (group == 0 || aligned[i].group_number == group) {
if (j >= aligned[i].offset &&
j < aligned[i].offset + aligned[i].seqlen) {
index = j - aligned[i].offset;
if (aligned[i].c_elem[index] == '-')
case_bit = 32;
else if (case_bit == 0)
case_bit |=
(aligned[i].c_elem[index] &
32);
occurence =
occurence |
Default_IUPAC_Trans(
aligned[i].c_elem[index]);
if (occurence != 1 && occurence != 2 &&
occurence != 4 && occurence != 8)
case_bit = 32;
/*
printf("%1c", aligned[i].c_elem[index]);
*/
}
/*
else
printf(" ");
*/
}
}
sprintf(temp_str, "%1c", Default_DNA_Trans[(int)occurence]);
if (case_bit == 0) temp_str[0] = toupper(temp_str[0]);
if (InsertElems(consensus, j, temp_str) == FALSE) return FALSE;
/*
printf(" cons[%d]=%1c\n", j - min_offset,
consensus->c_elem[j - min_offset]);
*/
}
return TRUE;
}
/***********
*
* MakeScore() takes an array of aligned sequence, and generates
* a consensus. Note, memory for (Sequence* consensus) should be
* located before it is passed to this function.
*
* Returns TRUE if successful, FALSE otherwise.
*
**********/
int MakeScore(aligned, numOfAligned, consensus, group)
Sequence aligned[]; /* input. */
int numOfAligned; /* input. */
Sequence *consensus; /* input and output. */
int group;
{
int i, j, index, score;
int max_cons = INT_MIN;
int min_offset = INT_MAX;
int As, Cs, Ts, Gs, Ns, tot_in_grp;
char temp_str[2], occurence, base;
int max_occ;
static char map[17] = "0123456789ABCDEF";
/*
* Search for the minimum offset.
*/
for (i = 0; i < numOfAligned; i++) {
if (group == 0 || aligned[i].group_number == group) {
SeqNormal(&aligned[i]);
min_offset = MIN(min_offset, aligned[i].offset);
max_cons = MAX(max_cons,
aligned[i].offset + aligned[i].seqlen);
}
}
/*
* Decide consensus base by base.
*/
CleanRecord(consensus);
consensus->offset = min_offset;
if (aligned[0].contig[0] != '\0') {
strcpy(consensus->name, aligned[0].contig);
strcat(consensus->name, ".");
}
else if (strncmp(aligned[0].name, "cons.", 5) != 0) {
strcpy(consensus->name, "cons.");
strcat(consensus->name, aligned[0].name);
}
strcpy(consensus->sequence_ID, uniqueID());
strcpy(consensus->contig, aligned[0].contig);
for (j = min_offset; j < max_cons; j++) {
As = Cs = Ts = Gs = Ns = 0;
tot_in_grp = 0;
occurence = 00;
for (i = 0; i < numOfAligned; i++) {
if (group == 0 || aligned[i].group_number == group) {
if (j >= aligned[i].offset &&
j < aligned[i].offset + aligned[i].seqlen) {
tot_in_grp++;
index = j - aligned[i].offset;
/*
occurence =
Default_IUPAC_Trans(aligned[i].c_elem[index]);
if((occurence & 01) == 01)
As++;
if((occurence & 02) == 02)
Cs++;
if((occurence & 04) == 04)
Gs++;
if((occurence & 010) == 010)
Ts++;
*/
base = (aligned[i].c_elem[index] | 32);
if (base == 'a')
As++;
else if (base == 'c')
Cs++;
else if (base == 'g')
Gs++;
else if (base == 't')
Ts++;
else if (base == 'n' || base == '-')
Ns++;
/*
printf("%1c",
aligned[i].c_elem[index]);
*/
}
/*
else
printf(" ");
*/
}
}
max_occ = MAX(As, MAX(Cs, MAX(Gs, Ts)));
/* socre = [0,E], F:all mismatches are either 'n' or '-' */
if (Ns != 0 && max_occ + Ns == tot_in_grp)
score = 15;
else
score = max_occ * 14 / tot_in_grp;
/*
if( score > 0xF )
{
if (InsertElems(consensus, j, "F") == FALSE)
{
return FALSE;
}
}
else
{
*/
sprintf(temp_str, "%1c", map[score]);
if (InsertElems(consensus, j, temp_str) == FALSE) {
return FALSE;
}
/*
printf(" %2d-%2d-%2d-%2d %2d cons[%d]=%1c\n",
Ts, Gs, Cs, As, score, j,
consensus->c_elem[j]);
*/
}
return TRUE;
}
/***********
*
* MakePhyloMask() takes an array of aligned sequence, and generates
* a mask that has a '0' for all columns except the columns which contain
* a, c, g, t and u only.
*
* Returns TRUE if successful, FALSE otherwise.
*
**********/
int MakePhyloMask(aligned, numOfAligned, consensus, group, acgtu)
Sequence aligned[]; /* input. */
int numOfAligned; /* input. */
Sequence *consensus; /* input and output. */
int acgtu[];
int group;
{
int i, j, cnt, max_cons = INT_MIN, min_offset = INT_MAX;
/*
* Search for the minimum offset.
*/
for (i = 0; i < numOfAligned; i++) {
if (group == 0 || aligned[i].group_number == group) {
SeqNormal(&aligned[i]);
min_offset = MIN(min_offset, aligned[i].offset);
max_cons = MAX(max_cons,
aligned[i].offset + aligned[i].seqlen);
}
}
/*
* Decide consensus base by base.
*/
CleanRecord(consensus);
consensus->offset = min_offset;
strcpy(consensus->name, "mask");
strcpy(consensus->type, "MASK");
strcpy(consensus->sequence_ID, uniqueID());
strcpy(consensus->contig, aligned[0].contig);
consensus->seqlen = max_cons - min_offset;
if (consensus->seqmaxlen == 0) {
consensus->c_elem =
(char *)Calloc(max_cons - min_offset + 5, 1);
consensus->seqmaxlen = max_cons - min_offset + 5;
}
else if (consensus->seqmaxlen < max_cons - min_offset) {
consensus->seqmaxlen = max_cons - min_offset + 5;
consensus->c_elem = (char *)Realloc(consensus->c_elem,
max_cons - min_offset + 5);
}
cnt = 0;
for (j = min_offset; j < max_cons; j++) {
consensus->c_elem[j - min_offset] = '1';
for (i = 0; i < numOfAligned; i++) {
if (group == 0 || aligned[i].group_number == group) {
if (j < aligned[i].offset ||
j >=
aligned[i].offset + aligned[i].seqlen ||
acgtu[aligned[i]
.c_elem[j - aligned[i].offset]] ==
0) {
consensus->c_elem[j - min_offset] = '0';
cnt++;
break;
}
}
}
}
fprintf(stderr, "\nNumber of 1s in mask: %d\n",
max_cons - min_offset - cnt);
fprintf(stderr, "Number of 0s in mask: %d\n\n", cnt);
return TRUE;
}
/***********
*
* MajorityCons() takes an array of aligned sequence, and generates
* a MAJORITY consensus.
* Note, memory for (Sequence* consensus) should be
* located before it is passed to this function.
*
* Returns TRUE if successful, FALSE otherwise.
*
**********/
int MajorityCons(aligned, numOfAligned, consensus, group, major_perc)
Sequence aligned[]; /* input. */
int numOfAligned; /* input. */
Sequence *consensus; /* input and output. */
int group, major_perc;
{
int i, j, index, score, ii, base, max;
int max_cons = INT_MIN;
int min_offset = INT_MAX;
char temp_str[2], occurence;
int *cnts, tot_in_grp;
unsigned char case_bit;
cnts = (int *)Calloc(16, sizeof(int));
/*
* Search for the minimum offset.
*/
for (i = 0; i < numOfAligned; i++) {
if (group == 0 || aligned[i].group_number == group) {
SeqNormal(&aligned[i]);
min_offset = MIN(min_offset, aligned[i].offset);
max_cons = MAX(max_cons,
aligned[i].offset + aligned[i].seqlen);
}
}
/*
* Decide consensus base by base.
*/
CleanRecord(consensus);
consensus->offset = min_offset;
if (aligned[0].contig[0] != '\0') {
strcpy(consensus->name, aligned[0].contig);
strcat(consensus->name, ".");
}
else if (strncmp(aligned[0].name, "cons.", 5) != 0) {
strcpy(consensus->name, "cons.");
strcat(consensus->name, aligned[0].name);
}
strcpy(consensus->sequence_ID, uniqueID());
strcpy(consensus->contig, aligned[0].contig);
for (j = min_offset; j < max_cons; j++) {
case_bit = 0;
occurence = 00;
tot_in_grp = 0;
for (ii = 0; ii < 16; ii++) cnts[ii] = 0;
for (i = 0; i < numOfAligned; i++) {
if (group == 0 || aligned[i].group_number == group) {
if (j >= aligned[i].offset &&
j < aligned[i].offset + aligned[i].seqlen) {
tot_in_grp++;
index = j - aligned[i].offset;
if (aligned[i].c_elem[index] == '-')
case_bit = 32;
else if (case_bit == 0)
case_bit |=
(aligned[i].c_elem[index] &
32);
occurence |= Default_IUPAC_Trans(
aligned[i].c_elem[index]);
cnts[(int)Default_IUPAC_Trans(
aligned[i].c_elem[index])]++;
if (case_bit == 0 && occurence != 1 &&
occurence != 2 && occurence != 4 &&
occurence != 8)
case_bit = 32;
}
}
}
max = 0;
for (ii = 0; ii < 16; ii++) {
if (cnts[ii] > max) {
max = cnts[ii];
base = ii;
}
}
if (max * 100 / tot_in_grp >= major_perc) {
/* follow the majority rule. */
sprintf(temp_str, "%1c", Default_DNA_Trans[base]);
}
else {
/* use IUPAC code. */
sprintf(temp_str, "%1c",
Default_DNA_Trans[(int)occurence]);
}
if (case_bit == 0) temp_str[0] = toupper(temp_str[0]);
if (InsertElems(consensus, j, temp_str) == FALSE) {
return FALSE;
}
}
return TRUE;
}
/***********
*
* ReadGDEtoHGL() reads a GDE formated file into an array of HGL structure.
*
* Return -1 if anything is wrong, number_of_sequence otherwise.
*
***********/
int ReadGDEtoHGL(fp, tSeq_arr)
FILE *fp;
Sequence **tSeq_arr;
{
char line[MAXLINELEN];
int ptr, num_seq, max_num_seq = 20;
int seq_len = 200;
char *newline;
(*tSeq_arr) = (Sequence *)Calloc(max_num_seq, sizeof(Sequence));
num_seq = -1;
while (fgets(line, MAXLINELEN - 2, fp) != NULL) /* spaces for \n\0 */
{
/* ptr points to the last char. */
ptr = strlen(line) - 1;
/* clear up the tail. */
while (ptr >= 0 && (line[ptr] == '\n' || line[ptr] == ' ' ||
line[ptr] == '\t'))
ptr--;
line[ptr + 1] = '\0';
if (ptr <= 0) {
/* it is an empty line. */
}
else if (line[0] == '#') {
if (++num_seq == max_num_seq) {
max_num_seq *= 2;
/* printf("max_num_seq = %d\n", max_num_seq); */
(*tSeq_arr) = (Sequence *)Realloc(
(*tSeq_arr),
max_num_seq * sizeof(Sequence));
}
InitRecord((*tSeq_arr)[num_seq]);
if (line[ptr] == '<') {
(*tSeq_arr)[num_seq].direction = 2; /* 3to5 */
line[ptr] = '\0';
}
else if (line[ptr] == '>') {
(*tSeq_arr)[num_seq].direction = 1; /* 5to3 */
line[ptr] = '\0';
}
strcpy((*tSeq_arr)[num_seq].sequence_ID, line + 1);
}
else {
ptr = 0;
if ((*tSeq_arr)[num_seq].seqlen == 0) {
/* determine the offset. */
while (line[ptr] != '\0' && line[ptr] == '-') {
ptr++;
}
(*tSeq_arr)[num_seq].offset += ptr;
}
if (line[ptr] != '\0') {
newline = line + ptr;
if ((*tSeq_arr)[num_seq].seqmaxlen == 0) {
(*tSeq_arr)[num_seq].c_elem =
(char *)Calloc(seq_len, 1);
(*tSeq_arr)[num_seq].c_elem[0] = '\0';
(*tSeq_arr)[num_seq].seqmaxlen =
seq_len;
}
else {
while ((*tSeq_arr)[num_seq].seqlen +
strlen(newline) + 1 >
(*tSeq_arr)[num_seq].seqmaxlen) {
seq_len *= 2;
(*tSeq_arr)[num_seq]
.c_elem = (char *)Realloc(
(*tSeq_arr)[num_seq].c_elem,
seq_len);
(*tSeq_arr)[num_seq].seqmaxlen =
seq_len;
}
}
strcat((*tSeq_arr)[num_seq].c_elem, newline);
(*tSeq_arr)[num_seq].seqlen =
strlen((*tSeq_arr)[num_seq].c_elem);
}
}
}
return (num_seq + 1);
}
/********
*
* InsertElems returns TRUE if successful, FALSE otherwise.
*
********/
int InsertElems(seq, pos, c)
Sequence *seq; /* Sequence */
int pos; /* Position (in respect to the master consensus)
* to insert BEFORE
* always move string to the right. */
char c[]; /*Null terminated array of elements to insert */
{
int dashes, j, len;
len = strlen(c);
if (seq->seqlen == 0) {
/* get rid of '-'s at right. */
/*
dashes = len-1;
while(dashes >= 0 && c[dashes] == '-')
dashes--;
if(dashes < 0)
{
seq->offset = pos;
return TRUE;
}
c[dashes+1] = '\0';
*/
/* clear out '-'s at left. */
dashes = 0;
/*
while(c[dashes] == '-')
dashes++;
c += dashes;
len = strlen(c);
pos += dashes;
*/
if (seq->seqmaxlen == 0) {
seq->c_elem = (char *)Calloc(len + 1, 1);
seq->seqmaxlen = len + 1;
}
else if (len + 1 >= seq->seqmaxlen) {
seq->c_elem = (char *)Realloc(seq->c_elem, len + 1);
seq->seqmaxlen = len + 1;
}
strcpy(seq->c_elem, c);
seq->seqlen = len;
seq->offset = pos;
return TRUE;
}
/* to make sure there is a space for '\0'. */
if (seq->seqlen > seq->seqmaxlen) {
fprintf(
stderr,
"InsertElems(): seqlen>seqmaxlen. Something is wrong.\n");
return FALSE;
}
else {
while (seq->seqlen + 1 >= seq->seqmaxlen) {
seq->seqmaxlen *= 2;
seq->c_elem =
(char *)Realloc(seq->c_elem, seq->seqmaxlen);
}
}
seq->c_elem[seq->seqlen] = '\0';
if (pos < seq->offset) /* insert to the left of the seq. */
{
/* ignore the dashes at the left. */
dashes = 0;
/*
while(dashes < len && c[dashes] == '-')
dashes++;
if(c[dashes] == '\0')
{
seq->offset += len;
return TRUE;
}
c += dashes;
len -= dashes;
*/
if (seq->seqlen + len + seq->offset - pos > seq->seqmaxlen) {
seq->seqmaxlen =
seq->seqlen + len + seq->offset - pos + 256;
seq->c_elem =
(char *)Realloc(seq->c_elem, seq->seqmaxlen);
}
/* copy the old string including the last '\0'. */
for (j = seq->seqlen; j >= 0; j--)
seq->c_elem[j + len + seq->offset - pos] =
seq->c_elem[j];
/* insert dashes. */
for (j = len; j < len + seq->offset - pos; j++)
seq->c_elem[j] = '-';
/* copy the inserted string. */
for (j = 0; j < len; j++) seq->c_elem[j] = c[j];
/* detector. */
if (c[j] != '\0')
fprintf(stderr, "InsertElems: Problem.....\n");
seq->seqlen = strlen(seq->c_elem);
/* seq->offset = pos; commented on 6-3-91 */
seq->offset = pos + dashes;
if (dashes > 0)
printf("\nInsertElems(): dashes is not zero.\n\n");
}
else if (pos - seq->offset >= seq->seqlen) /* insert to the right. */
{
/* ignore the dashes at the right. */
/*
dashes = len -1;
while(dashes >= 0 && c[dashes] == '-')
dashes--;
if(dashes < 0)
return TRUE;
len = dashes+1;
c[len] = '\0';
*/
if (pos - seq->offset + len > seq->seqmaxlen) {
seq->seqmaxlen = pos - seq->offset + len + 256;
seq->c_elem =
(char *)Realloc(seq->c_elem, seq->seqmaxlen);
}
/* insert dashes. */
for (j = seq->seqlen; j < pos - seq->offset; j++)
seq->c_elem[j] = '-';
/* copy the inserted string. */
for (j = 0; j < len; j++)
seq->c_elem[pos - seq->offset + j] = c[j];
seq->c_elem[pos - seq->offset + len] = '\0';
/* detector. */
if (c[j] != '\0')
fprintf(stderr, "InsertElems: Problem too .....\n");
seq->seqlen = strlen(seq->c_elem);
}
else /* insert into the seq. */
{
if (seq->seqlen + len > seq->seqmaxlen) {
seq->seqmaxlen = seq->seqlen + len + 256;
seq->c_elem =
(char *)Realloc(seq->c_elem, seq->seqmaxlen);
}
/* move the bottom part of the older string including the last
* '\0'. */
for (j = seq->seqlen; j >= pos - seq->offset; j--)
seq->c_elem[j + len] = seq->c_elem[j];
/* copy the inserted string. */
for (j = 0; j < len; j++)
seq->c_elem[pos - seq->offset + j] = c[j];
/* detector. */
if (c[j] != '\0')
fprintf(stderr,
"InsertElems: Problem too too .....\n");
seq->seqlen = strlen(seq->c_elem);
}
return TRUE;
}
/******************************************************************
*
* int GetArgs(argArray, numArgs)
* Arg *argArray;
* int numArgs;
*
* Return TRUE if successful, FALSE otherwise.
*
******************************************************************/
#define MAX_ARGS 50 /* maximum args this can process */
int GetArgs(argArray, numArgs, argc, argv)
Args *argArray;
int numArgs;
int argc;
char **argv;
{
int i, j;
Args *curarg;
int noArgOK = TRUE;
if ((argArray == NULL) || (numArgs == 0) || (numArgs > MAX_ARGS)) {
fprintf(stderr, "GetArgs: Invalid number of args.\n");
return FALSE;
}
/*
* Test if all are either 'default' or 'optional'.
*/
curarg = argArray;
for (i = 0; i < numArgs; i++, curarg++) {
if (curarg->strvalue[0] == '\0' && curarg->optional == 'F') {
noArgOK = FALSE;
break;
}
}
/*
* show usage if some arg is required but no arg is
* supllied on command line.
*/
if (noArgOK == FALSE && argc == 1) {
fprintf(stderr, "\n%s arguments:\n\n", argv[0]);
curarg = argArray;
for (i = 0; i < numArgs; i++, curarg++) {
fprintf(stderr, " -%c %s ", curarg->tag,
curarg->prompt);
if (curarg->optional == 'T')
fprintf(stderr, " [Optional]");
fprintf(stderr, "\n");
if (curarg->strvalue[0] != '\0')
fprintf(stderr, " default = %s\n",
curarg->strvalue);
}
fprintf(stderr, "\n");
return FALSE;
}
/*
* Process
*/
for (i = 1; i < argc; i++) {
if (argv[i][0] != '-') {
fprintf(stderr, "Arguments must start with -");
return FALSE;
}
/* check the tag. */
curarg = argArray;
for (j = 0; j < numArgs; j++, curarg++) {
if ((argv[i][1] | 32) == (curarg->tag | 32)) break;
}
if (j == numArgs) {
fprintf(stderr, "Invalid argument tag in %s\n",
argv[i]);
return FALSE;
}
strcpy(curarg->strvalue, argv[i] + 2);
if (curarg->strvalue[0] == '\'' &&
curarg->strvalue[strlen(curarg->strvalue) - 1] == '\'') {
char ttmm[256];
strcpy(ttmm, curarg->strvalue + 1);
ttmm[strlen(ttmm) - 1] = '\0';
strcpy(curarg->strvalue, ttmm);
}
}
return TRUE;
}
/*********
*
* GetCond interprets the -c argument, the condition.
*
* The condition will be set to NULL if no condition is specified,
* that is, if you pass '&p' as the address of a cond* structure,
* p will be set to NULL if no condition [(p == NULL) = TRUE].
*
* Return TRUE if successful, FALSE otherwise.
*
*********/
int GetCond(arg, cond)
char *arg;
str_cond **cond;
{
int start, end, i, found;
char message_buf[1000];
if (strcmp(arg, "null") == 0) {
(*cond) = NULL;
return TRUE;
}
else {
(*cond) = (str_cond *)Calloc(1, sizeof(str_cond));
start = end = 0;
/* find the field name. */
while (('a' <= arg[end] && arg[end] <= 'z') ||
('A' <= arg[end] && arg[end] <= 'Z') || arg[end] == '-')
end++;
found = FALSE;
for (i = 0; i < NUM_OF_FIELDS && found == FALSE; i++) {
if (strncmp(arg, at[i], strlen(at[i])) == 0) {
(*cond)->field =
i; /* condition on field &at[i]. */
found = TRUE;
break;
}
}
if (found == FALSE) {
strncpy(message_buf, arg, end - start);
message_buf[end - start] = '\0';
fprintf(stderr, "Field %s not found.\n", message_buf);
return FALSE;
}
start = end;
end++;
while (arg[end] == '=' || arg[end] == '!' || arg[end] == '>' ||
arg[end] == '<')
end++;
strncpy((*cond)->symbol, arg + start, end - start);
(*cond)->symbol[end - start] = '\0';
if (strlen((*cond)->symbol) > 2 ||
strlen((*cond)->symbol) < 1 ||
(strlen((*cond)->symbol) == 1 &&
*((*cond)->symbol) != '>' && *((*cond)->symbol) != '<') ||
(strlen((*cond)->symbol) == 2 &&
(strncmp((*cond)->symbol, "!=", 2) != 0) &&
(strncmp((*cond)->symbol, "==", 2) != 0) &&
(strncmp((*cond)->symbol, ">=", 2) != 0) &&
(strncmp((*cond)->symbol, "<=", 2) != 0))) {
fprintf(stderr, "Invalid condition.\n");
return FALSE;
}
if (arg[end] == '"' && arg[strlen(arg) - 1] == '"') {
end++;
arg[strlen(arg) - 1] = '\0';
}
(*cond)->value = (char *)Calloc(strlen(arg) - end + 2, 1);
strcpy((*cond)->value, arg + end);
}
return TRUE;
}
/*********
*
* GetFields interprets the -f arguments, the fields list.
*
* Returns number of selected fields, 0 if anything is wrong.
*
*********/
int GetFields(arg, selected_fields)
char *arg;
int selected_fields[];
{
int start, end, i, found, list_done, i_selected;
char message_buf[1000];
if (strcmp(arg, "all") == 0) {
selected_fields[0] = -1;
return NUM_OF_FIELDS;
}
else {
start = end = 0;
list_done = FALSE;
i_selected = 0;
while (list_done == FALSE) {
while (arg[end] != '\0' && arg[end] != ',') {
end++;
}
if (arg[end] == '\0') {
list_done = TRUE;
}
found = FALSE;
for (i = 0; i < NUM_OF_FIELDS && found == FALSE; i++) {
if (strncmp(arg + start, at[i],
strlen(at[i])) == 0) {
selected_fields[i_selected++] = i;
found = TRUE;
start = end + 1;
break;
}
}
if (found == FALSE) {
strncpy(message_buf, (arg + start),
end - start);
message_buf[end - start] = '\0';
fprintf(stderr, "Field %s not found.\n",
message_buf);
return 0;
}
end++;
}
}
return i_selected;
}
static char *pairs[] = {"aa", "ac", "ag", "at", "ca", "cc", "cg", "ct",
"ga", "gc", "gg", "gt", "ta", "tc", "tg", "tt"};
static int stemp[16] = {55, 98, 58, 57, 55, 86, 73, 58,
87, 136, 86, 98, 37, 87, 55, 55};
/*******
*
* MST() returns Mean Stacking Temperature for the given sequence,
* returns -1 if anything is wrong.
*
*******/
float MST(c_elem) const char *c_elem;
{
int i, j, l;
int tot_stemp = 0, non_amb_pairs = 0;
char *seq;
l = strlen(c_elem);
seq = (char *)Calloc(l, 1 + 1);
/* clean out dashes. */
j = 0;
for (i = 0; i < l; i++) {
if (c_elem[i] != '-') {
seq[j] = c_elem[i] | 32;
if (seq[j] == 'u') seq[j] = 't';
j++;
}
}
seq[j] = '\0';
l = j;
for (i = 0; i < l - 1; i++) {
j = 0;
while (j < 16 && strncmp(seq + i, pairs[j], 2) != 0) {
j++;
}
/* ignore the pairing of an ambiguous base. */
if (j != 16) {
tot_stemp += stemp[j];
non_amb_pairs++;
}
}
if (seq != NULL) {
Cfree(seq);
seq = NULL;
}
return ((float)tot_stemp / (float)non_amb_pairs);
}
/********
*
* SubStr() fill ss with a substring of at most 'length' chars and returns
* TRUE. If anything is wrong, it sets ss to be empty and returns FALSE.
*
********/
int SubStr(string, start, length, ss) const char *string;
int start, length;
char *ss;
{
int i;
if (strlen(string) <= start) {
fprintf(stderr,
"SubStr(): starting point is beyond the boundary.\n");
ss[0] = '\0';
return FALSE;
}
for (i = start; string[i] != '\0' && i < start + length; i++) {
ss[i - start] = string[i];
}
ss[i - start] = '\0';
return TRUE;
}
/*******
*
* FindPattern() searches string for pattern.
* Returns the number of appearences.
*
*******/
int FindPattern(string, pattern) const char *string;
const char *pattern;
{
int i, sl, pl, num_app = 0;
if (string == NULL || (sl = strlen(string)) == 0) return 0;
pl = strlen(pattern);
for (i = 0; i <= sl - pl; i++) {
if (strncmp(string + i, pattern, pl) == 0) num_app++;
}
return num_app;
}
/*******
*
* FindPattern2(), same as FindPattern(), but returns the #
* of appearences that do not overlap only.
*
*******/
int FindPattern2(string, pattern, orig_loc) const char *string;
const char *pattern;
int orig_loc;
{
int i, sl, pl, num_app = 0;
if (string == NULL || (sl = strlen(string)) == 0) return 0;
pl = strlen(pattern);
for (i = 0; i <= sl - pl; i++) {
if (abs(i - orig_loc) >= pl &&
strncmp(string + i, pattern, pl) == 0)
num_app++;
}
return num_app;
}
/*******
*
* FindPatternNC() searches string for pattern , CASE INSENSITIVE.
* Returns the number of appearences.
*
*******/
int FindPatternNC(string, pattern) const char *string;
const char *pattern;
{
int i, j, sl, pl, num_app = 0;
if (string == NULL || (sl = strlen(string)) == 0) return 0;
pl = strlen(pattern);
for (i = 0; i <= sl - pl; i++) {
j = 0;
while (j < pl && (string[i + j] | 32) == (pattern[j] | 32)) j++;
if (j == pl) num_app++;
}
return num_app;
}
/*******
*
* Complementary() CHANGES the given DNA/RNA string to its complementary,
* and returns TRUE. Returns FALSE if anything is wrong and keep the
* given string unchanged.
*
*******/
int Complementary(sequence, type)
char *sequence;
char type;
{
int i, l;
char *temp_str;
l = strlen(sequence);
temp_str = (char *)Calloc(l + 1, sizeof(char));
if (type == 'D' || type == 'd')
type = 0;
else if (type == 'R' || type == 'r')
type = 1;
else {
fprintf(stderr,
"Complementary(): type unknown. Type is D/d/R/r\n");
return (int)NULL;
}
for (i = 0; i < l; i++) {
switch (sequence[i]) {
case 'A':
temp_str[i] = (type == 0) ? 'T' : 'U';
break;
case 'a':
temp_str[i] = (type == 0) ? 't' : 'u';
break;
case 'C':
temp_str[i] = 'G';
break;
case 'c':
temp_str[i] = 'g';
break;
case 'G':
temp_str[i] = 'C';
break;
case 'g':
temp_str[i] = 'c';
break;
case 'T':
case 'U':
temp_str[i] = 'A';
break;
case 't':
case 'u':
temp_str[i] = 'a';
break;
}
}
temp_str[i] = '\0';
strcpy(sequence, temp_str);
if (temp_str != NULL) {
Cfree(temp_str);
temp_str = NULL;
}
return TRUE;
}
/********
*
* KnownSeq() returns an integer which is the index of the first
* occurence of an ambiguous base in the seq. -1 if no ambiguous
* base in the seq.
*
********/
int KnownSeq(seq)
char *seq;
{
int i;
char c;
for (i = 0; i < strlen(seq); i++) {
c = seq[i] | 32;
if (c != 'a' && c != 't' && c != 'g' && c != 'c' && c != 'u')
return i;
}
return -1;
}
/********
*
* Reverse() reverses the given string and returns TRUE.
* (NOTE: Reverse() actually changes the string).
* If anything goes wrong, leave seq unchanged.
*
*
********/
int Reverse(seq)
char *seq;
{
int i, l;
char c;
l = strlen(seq);
if (l < 2) {
return TRUE;
}
for (i = 0; i < l / 2; i++) {
c = seq[i];
seq[i] = seq[l - i - 1];
seq[l - i - 1] = c;
}
return TRUE;
}
/********
*
* GoodOligos() returns a pointer to an array of subsequences that
* do not contant secondary structure, nor self complementary structure.
* Returns NULL if anything is wrong.
*
* l_bnd and r_bnd are regards to the head of the probe.
*
* Note: this program Calloc-s memory for the returned pointer.
* The caller program is responsible of Freeing the memory when
* not needed.
*
********/
char **GoodOligos(c_elem, check_len, min_len, max_len, l_bnd, r_bnd)
char *c_elem;
int check_len, min_len, max_len, l_bnd, r_bnd;
/* l_bnd and r_bnd are relative to c_elem, so they should be in
[0,strlen(c_elem)] */
{
int i, l, seq_len, max_num_probe, seq_cnt = 0;
char **seq_set;
char *seq, *subseq, *scd_str, *PossibleOligo;
int BadOligo, PO_len, PO_index, PO_l;
/* constant(s): */
/* to check if there is a substr of length 'no_repeat_len' appears
* more than once in the PossibleOligo. */
int no_repeat_len = 15;
seq_len = strlen(c_elem);
/* A lower case copy of the c_elem. */
seq = (char *)Calloc(seq_len + 1, sizeof(char));
/* String used to check the PossibleOligo. */
PossibleOligo = (char *)Calloc(max_len + 1, sizeof(char));
subseq = (char *)Calloc(max_len + 1, sizeof(char));
scd_str = (char *)Calloc(max_len + 1, sizeof(char));
/* The output. A set of possibly good oligos. */
max_num_probe = 20;
seq_set = (char **)Calloc(max_num_probe, sizeof(char *));
for (i = 0; i < seq_len; i++) {
seq[i] = c_elem[i] | 32;
}
i = MAX(l_bnd, 0);
while (i <= MIN(r_bnd, seq_len - min_len)) {
BadOligo = FALSE;
for (l = min_len;
BadOligo == FALSE && l <= seq_len - i && l <= max_len;
l++) {
int uk;
SubStr(seq, i, l, PossibleOligo);
/* Any unknow base?
*/
if ((uk = KnownSeq(PossibleOligo)) != -1) {
fprintf(stderr, "%s has ambiguous base(s)\n",
PossibleOligo);
i += uk + 1;
BadOligo = TRUE;
}
PO_len = strlen(PossibleOligo);
/* check if there is a substr of len(no_repeat_len)
* repeat itself in the PossibleOligo.
DOESN'T MATTER! IT COULD MESS UP AT MOST SEVERAL
BASES READ INTO THE PROBE. CUT_SITE IS WHAT REALLY
MATTERS.
for(PO_index = 0;
BadOligo==FALSE && PO_index<=PO_len-no_repeat_len;
PO_index++)
{
SubStr(PossibleOligo,PO_index,no_repeat_len,subseq);
if(FindPattern(PossibleOligo, subseq) > 1)
{
fprintf(stderr,
"%s has 15 repatitive base(s) %s\n",
PossibleOligo, subseq);
i++;
BadOligo = TRUE;
}
}
*/
/*
* To ensure that the probe is not going to hybridize
* with itself:
*/
for (PO_index = 0; BadOligo == FALSE &&
PO_index <= PO_len - no_repeat_len;
PO_index++) {
SubStr(PossibleOligo, PO_index, no_repeat_len,
subseq);
strcpy(scd_str, subseq);
Complementary(scd_str, 'd');
Reverse(scd_str);
if (FindPattern(PossibleOligo, scd_str) > 0) {
fprintf(stderr,
"%s may hybridize with itself: "
"%s vs. %s.\n",
PossibleOligo, subseq, scd_str);
i++;
BadOligo = TRUE;
}
}
for (PO_index = 0; BadOligo == FALSE &&
PO_index <= PO_len - 2 * check_len;
PO_index++) {
SubStr(PossibleOligo, PO_index, check_len,
subseq);
Complementary(subseq, 'd');
strcpy(scd_str, subseq);
Reverse(scd_str);
/*
if(FindPattern2(PossibleOligo,subseq,PO_index)>0)
{
fprintf(stderr, "%s has self-compl %s\n",
PossibleOligo, subseq);
i += PO_index+1;
BadOligo = TRUE;
}
else
*/
if (FindPattern2(PossibleOligo, scd_str,
PO_index) > 0) {
fprintf(stderr,
"%s has 2nd struct %s\n",
PossibleOligo, scd_str);
i += PO_index + 1;
BadOligo = TRUE;
}
}
if (BadOligo == FALSE) {
seq_set[seq_cnt] = (char *)Calloc(
strlen(PossibleOligo) + 1, sizeof(char));
strcpy(seq_set[seq_cnt], PossibleOligo);
if (++seq_cnt == max_num_probe) {
max_num_probe *= 2;
seq_set = (char **)Realloc(
seq_set,
max_num_probe * sizeof(char *));
}
i++;
}
} /* end of l. */
} /* end of i. */
seq_set[seq_cnt] = NULL;
if (seq_cnt == 0) return NULL;
return seq_set;
}
/* ALWAYS COPY the result from uniqueID() to a char[32],
* (strlen(hostname)+1+10). Memory is lost when the function
* is finished.
*/
char vname[32];
char *uniqueID()
{
char hname[32], /* vname[32], rtm 18.III.98 */ tstr[32];
time_t *tp;
static cnt = 0;
int ll;
tp = (time_t *)Calloc(1, sizeof(time_t));
if (gethostname(hname, 32) == -1) {
fprintf(stderr, "UniqueID(): Failed to get host name.\n");
exit(1);
}
time(tp);
sprintf(tstr, ":%d:%ld", cnt, *tp);
if ((ll = strlen(tstr)) > 31) {
strncpy(vname, tstr, 31);
vname[31] = '\0';
}
else {
ll = strlen(hname) - (31 - ll);
if (ll < 0) ll = 0;
sprintf(vname, "%s%s", hname + ll, tstr);
}
cnt++;
Cfree(tp);
return (vname);
}
/* return the percentage of GCcontents. */
int GCcontent(seq)
char *seq;
{
int l, gc = 0, j;
l = strlen(seq);
for (j = 0; j < l; j++) {
if ((seq[j] | 32) == 'g' || (seq[j] | 32) == 'c') {
gc++;
}
}
return ((int)(gc * 100 / l));
}
/******
*
* HGLtoIQ() outputs a HGL format record to an ASCII file with
* the Input-Queue format, the format for the synthesizer.
*
******/
void HGLtoIQ(fname, tSeq) const char *fname;
Sequence *tSeq;
{
FILE *fp;
if ((fp = fopen(fname, "w")) == NULL) {
fprintf(stderr, "Can't open IQ file: %s\n", fname);
exit(1);
}
fprintf(fp, "%s %s\n", tSeq->comments, tSeq->c_elem);
}
Find2(string, key) char *key, *string;
/*
* Like find, but returns the index of the leftmost
* occurence, and -1 if not found.
* Note in this program, T==U, and case insensitive.
*/
{
int i, j, len1, len2, dif, flag = FALSE;
char *target;
if (string == NULL || string[0] == '\0') return -1;
len2 = strlen(string);
target = (char *)Calloc(len2 + 1, 1);
for (i = 0; i < len2; i++) {
target[i] = string[i] | 32;
if (target[i] == 'u') target[i] = 't';
}
len1 = strlen(key);
for (i = 0; i < len1; i++) {
key[i] |= 32;
if (key[i] == 'u') key[i] = 't';
}
dif = len2 - len1 + 1;
if (len1 > 0)
for (j = 0; j < dif && flag == FALSE; j++) {
flag = TRUE;
for (i = 0; i < len1 && flag; i++)
flag = (key[i] == target[i + j]) ? TRUE : FALSE;
}
Cfree(target);
return (flag ? j - 1 : -1);
}
/* return -1 if end-of-file.
FALSE if anything is wrong.
*/
int ReadGDE(fp, seq)
FILE *fp;
Sequence *seq;
{
char temp_line[1000], waste[64];
int ii, l1;
while (fgets(temp_line, 1000, fp) != NULL) {
if (strncmp(temp_line, "sequence-ID", 11) == 0) {
sscanf(temp_line, "%s%s", waste, seq->sequence_ID);
}
else if (temp_line[0] == '#') {
strncpy(seq->name, temp_line + 1, 31);
seq->name[31] = '\0';
ii = 0;
while (ii < strlen(seq->name) && seq->name[ii] != ' ' &&
seq->name[ii] != '\n')
ii++;
seq->name[ii] = '\0';
seq->seqmaxlen = 256;
seq->c_elem = (char *)Calloc(seq->seqmaxlen, 1);
seq->seqlen = 0;
while (fgets(temp_line, 1000, fp) != NULL) {
l1 = strlen(temp_line);
if (temp_line[l1 - 1] == '\n') {
l1--;
temp_line[l1] = '\0';
}
while (seq->seqmaxlen <
seq->seqlen + strlen(temp_line) + 1) {
seq->seqmaxlen *= 2;
seq->c_elem = (char *)Realloc(
seq->c_elem, seq->seqmaxlen);
}
strcat(seq->c_elem, temp_line);
seq->seqlen += strlen(temp_line);
}
if (seq->seqlen == 0) {
fprintf(stderr, "\n%s\n", "Sequence is empty.");
return FALSE;
}
}
}
return -1;
}
void heapify(seq_set, seq_size, heap_size, elem, Pkey, Skey, order) int seq_size
,
elem, heap_size, **order;
char Pkey[], Skey[];
Sequence *seq_set;
{
int l, r, temp, largest;
l = 2 * elem + 1;
r = 2 * elem + 2;
if (l <= heap_size && CompKey(seq_set[(*order)[l]],
seq_set[(*order)[elem]], Pkey, Skey) > 0)
largest = l;
else
largest = elem;
if (r <= heap_size &&
CompKey(seq_set[(*order)[r]], seq_set[(*order)[largest]], Pkey,
Skey) > 0)
largest = r;
if (largest != elem) {
temp = (*order)[elem];
(*order)[elem] = (*order)[largest];
(*order)[largest] = temp;
heapify(seq_set, seq_size, heap_size, largest, Pkey, Skey,
order);
}
}
heapsort(seq_set, seq_size, Pkey, Skey, order) int seq_size, **order;
char Pkey[], Skey[];
Sequence *seq_set;
{
int ii, temp, heap_size;
/*
* build_heap(seq_set, seq_size, &heap_size, order);
*/
heap_size = seq_size - 1;
for (ii = (seq_size - 1) / 2; ii >= 0; ii--) /* (L-1)/2-1?? */
{
heapify(seq_set, seq_size, heap_size, ii, Pkey, Skey, order);
}
for (ii = seq_size - 1; ii > 0; ii--) {
temp = (*order)[0];
(*order)[0] = (*order)[ii];
(*order)[ii] = temp;
heap_size--;
heapify(seq_set, seq_size, heap_size, 0, Pkey, Skey, order);
}
}
/*
* Return >0, ==0, <0.
*/
int CompKey(seq1, seq2, Pkey, Skey)
Sequence seq1, seq2;
char Pkey[], Skey[];
{
int ii, jj, Pret;
char b1[32], b2[32];
if (strcmp(Pkey, "type") == 0) {
Pret = strcmp(seq1.type, seq2.type);
if (Pret != 0 || Skey[0] == '\0') return Pret;
}
else if (strcmp(Pkey, "name") == 0) {
Pret = strcmp(seq1.name, seq2.name);
if (Pret != 0 || Skey[0] == '\0') return Pret;
}
else if (strcmp(Pkey, "sequence-ID") == 0) {
Pret = strcmp(seq1.sequence_ID, seq2.sequence_ID);
if (Pret != 0 || Skey[0] == '\0') return Pret;
}
else if (strcmp(Pkey, "creator") == 0) {
Pret = strcmp(seq1.creator, seq2.creator);
if (Pret != 0 || Skey[0] == '\0') return Pret;
}
else if (strcmp(Pkey, "offset") == 0) {
Pret = seq1.offset - seq2.offset;
if (Pret != 0 || Skey[0] == '\0') return Pret;
}
else if (strcmp(Pkey, "group-ID") == 0) {
Pret = seq1.group_ID - seq2.group_ID;
if (Pret != 0 || Skey[0] == '\0') return Pret;
}
else if (strcmp(Pkey, "barcode") == 0) {
if (seq1.barcode[0] == 'P')
strcpy(b1, seq1.barcode + 2);
else
strcpy(b1, seq1.barcode);
if (seq2.barcode[0] == 'P')
strcpy(b2, seq2.barcode + 2);
else
strcpy(b2, seq2.barcode);
Pret = strcmp(b1, b2);
if (Pret != 0 || Skey[0] == '\0') return Pret;
}
else if (strcmp(Pkey, "seqlen") == 0) {
Pret = seq1.seqlen - seq2.seqlen;
if (Pret != 0 || Skey[0] == '\0') return Pret;
}
else if (strcmp(Pkey, "creation-date") == 0) {
seq1.creation_date[0] %= 100;
seq2.creation_date[0] %= 100;
Pret = seq1.creation_date[0] * 10000 +
seq1.creation_date[1] * 100 + seq1.creation_date[2] -
seq2.creation_date[0] * 10000 -
seq2.creation_date[1] * 100 - seq2.creation_date[2];
if (Pret == 0) {
Pret = seq1.creation_date[3] * 10000 +
seq1.creation_date[4] * 100 +
seq1.creation_date[5] -
seq2.creation_date[3] * 10000 -
seq2.creation_date[4] * 100 -
seq2.creation_date[5];
}
if (Pret != 0 || Skey[0] == '\0') return Pret;
}
else if (strcmp(Pkey, "probing-date") == 0) {
seq1.probing_date[0] %= 100;
seq2.probing_date[0] %= 100;
Pret = seq1.probing_date[0] * 10000 +
seq1.probing_date[1] * 100 + seq1.probing_date[2] -
seq2.probing_date[0] * 10000 -
seq2.probing_date[1] * 100 - seq2.probing_date[2];
if (Pret == 0) {
Pret =
seq1.probing_date[3] * 10000 +
seq1.probing_date[4] * 100 + seq1.probing_date[5] -
seq2.probing_date[3] * 10000 -
seq2.probing_date[4] * 100 - seq2.probing_date[5];
}
if (Pret != 0 || Skey[0] == '\0') return Pret;
}
else if (strcmp(Pkey, "autorad_date") == 0) {
seq1.autorad_date[0] %= 100;
seq2.autorad_date[0] %= 100;
Pret = seq1.autorad_date[0] * 10000 +
seq1.autorad_date[1] * 100 + seq1.autorad_date[2] -
seq2.autorad_date[0] * 10000 -
seq2.autorad_date[1] * 100 - seq2.autorad_date[2];
if (Pret == 0) {
Pret =
seq1.autorad_date[3] * 10000 +
seq1.autorad_date[4] * 100 + seq1.autorad_date[5] -
seq2.autorad_date[3] * 10000 -
seq2.autorad_date[4] * 100 - seq2.autorad_date[5];
}
if (Pret != 0 || Skey[0] == '\0') return Pret;
}
else if (strcmp(Pkey, "film") == 0) {
Pret = strcmp(seq1.film, seq2.film);
if (Pret != 0 || Skey[0] == '\0') return Pret;
}
else if (strcmp(Pkey, "membrane") == 0) {
Pret = strcmp(seq1.membrane, seq2.membrane);
if (Pret != 0 || Skey[0] == '\0') return Pret;
}
else if (strcmp(Pkey, "contig") == 0) {
Pret = strcmp(seq1.contig, seq2.contig);
if (Pret != 0 || Skey[0] == '\0') return Pret;
}
else {
fprintf(stderr, "CompKey(): Invalid primary key %s.\n", Pkey);
exit(1);
}
if (strcmp(Skey, "type") == 0) {
return (strcmp(seq1.type, seq2.type));
}
else if (strcmp(Skey, "name") == 0) {
return (strcmp(seq1.name, seq2.name));
}
else if (strcmp(Skey, "sequence-ID") == 0) {
return (strcmp(seq1.sequence_ID, seq2.sequence_ID));
}
else if (strcmp(Skey, "creator") == 0) {
return (strcmp(seq1.creator, seq2.creator));
}
else if (strcmp(Skey, "offset") == 0) {
return (seq1.offset - seq2.offset);
}
else if (strcmp(Skey, "group-ID") == 0) {
return (seq1.group_ID - seq2.group_ID);
}
else if (strcmp(Skey, "barcode") == 0) {
if (seq1.barcode[0] == 'P')
strcpy(b1, seq1.barcode + 2);
else
strcpy(b1, seq1.barcode);
if (seq2.barcode[0] == 'P')
strcpy(b2, seq2.barcode + 2);
else
strcpy(b2, seq2.barcode);
return (strcmp(b1, b2));
}
else if (strcmp(Skey, "seqlen") == 0) {
return (seq1.seqlen - seq2.seqlen);
}
else if (strcmp(Skey, "creation-date") == 0) {
seq1.creation_date[0] %= 100;
seq2.creation_date[0] %= 100;
Pret = seq1.creation_date[0] * 10000 +
seq1.creation_date[1] * 100 + seq1.creation_date[2] -
seq2.creation_date[0] * 10000 -
seq2.creation_date[1] * 100 - seq2.creation_date[2];
if (Pret != 0) return Pret;
return (seq1.creation_date[3] * 10000 +
seq1.creation_date[4] * 100 + seq1.creation_date[5] -
seq2.creation_date[3] * 10000 -
seq2.creation_date[4] * 100 - seq2.creation_date[5]);
}
else if (strcmp(Skey, "probing-date") == 0) {
seq1.probing_date[0] %= 100;
seq2.probing_date[0] %= 100;
Pret = seq1.probing_date[0] * 10000 +
seq1.probing_date[1] * 100 + seq1.probing_date[2] -
seq2.probing_date[0] * 10000 -
seq2.probing_date[1] * 100 - seq2.probing_date[2];
if (Pret != 0) return Pret;
return (seq1.probing_date[3] * 10000 +
seq1.probing_date[4] * 100 + seq1.probing_date[5] -
seq2.probing_date[3] * 10000 -
seq2.probing_date[4] * 100 - seq2.probing_date[5]);
}
else if (strcmp(Skey, "autorad_date") == 0) {
seq1.autorad_date[0] %= 100;
seq2.autorad_date[0] %= 100;
Pret = seq1.autorad_date[0] * 10000 +
seq1.autorad_date[1] * 100 + seq1.autorad_date[2] -
seq2.autorad_date[0] * 10000 -
seq2.autorad_date[1] * 100 - seq2.autorad_date[2];
if (Pret != 0) return Pret;
return (seq1.autorad_date[3] * 10000 +
seq1.autorad_date[4] * 100 + seq1.autorad_date[5] -
seq2.autorad_date[3] * 10000 -
seq2.autorad_date[4] * 100 - seq2.autorad_date[5]);
}
else if (strcmp(Skey, "film") == 0) {
return (strcmp(seq1.film, seq2.film));
}
else if (strcmp(Skey, "membrane") == 0) {
return (strcmp(seq1.membrane, seq2.membrane));
}
else if (strcmp(Skey, "contig") == 0) {
return (strcmp(seq1.contig, seq2.contig));
}
else {
fprintf(stderr, "CompKey(): Invalid secondary key %s.\n", Skey);
exit(1);
}
}
int Lock(fname)
char *fname;
{
char buffer[1024];
FILE *fp;
int wait = 0;
while ((fp = fopen(fname, "r")) == NULL) {
sleep(1);
if (++wait == 30) {
fprintf(stderr,
"File %s not available, Try later.\n\n",
fname);
return FALSE;
}
}
fclose(fp);
sprintf(buffer, "mv %s %s.locked", fname, fname);
system(buffer);
return TRUE;
}
void Unlock(fname) char *fname;
{
char buffer[1024];
sprintf(buffer, "mv %s.locked %s", fname, fname);
system(buffer);
}
AppendComments(seq, str) Sequence *seq;
char *str;
{
int ii, jj, kk;
kk = strlen(str);
if (seq->commentsmaxlen == 0) {
seq->comments = (char *)Calloc(kk + 1, 1);
seq->commentsmaxlen = kk + 1;
seq->commentslen = 0;
}
else if (seq->commentslen + kk + 1 > seq->commentsmaxlen) {
seq->commentsmaxlen += 2 * (kk + 1);
seq->comments =
(char *)Realloc(seq->comments, seq->commentsmaxlen);
}
seq->comments[seq->commentslen] = '\0';
seq->comments[seq->commentslen] = '\0';
strcat(seq->comments, str);
seq->commentslen = strlen(seq->comments);
}