From: martinahansen Date: Mon, 1 Sep 2008 01:27:36 +0000 (+0000) Subject: read_solexa now handles both decimal and octal scores X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=7c9609e8a165301350118cde21387c8a2e63dd42;p=biopieces.git read_solexa now handles both decimal and octal scores git-svn-id: http://biopieces.googlecode.com/svn/trunk@235 74ccb610-7750-0410-82ae-013aeee3265d --- diff --git a/code_c/Maasha/src/inc/bits.h b/code_c/Maasha/src/inc/bits.h new file mode 100644 index 0000000..a72297c --- /dev/null +++ b/code_c/Maasha/src/inc/bits.h @@ -0,0 +1,47 @@ +#define BITS_IN_BYTE 8 +#define BYTE_ON 255 + +#define BIT0 0 /* 00000000 */ +#define BIT1 ( 1 << 8 ) /* 10000000 */ +#define BIT2 ( 1 << 7 ) /* 01000000 */ +#define BIT3 ( 1 << 5 ) /* 00100000 */ +#define BIT4 ( 1 << 4 ) /* 00010000 */ +#define BIT5 ( 1 << 3 ) /* 00001000 */ +#define BIT6 ( 1 << 2 ) /* 00000100 */ +#define BIT7 ( 1 << 1 ) /* 00000010 */ +#define BIT8 1 /* 00000001 */ + +/* Bitarray structure */ +struct _bitarray +{ + size_t size; /* number of bits in bitarray. */ + size_t bits_on; /* number of bits set to 'on'. */ + char *str; /* bit string. */ + size_t str_len; /* length of bit string. */ + size_t modulus; /* number of bits used in last element of str. */ + char mask; /* bit mask to trim length of str. */ +}; + +typedef struct _bitarray bitarray; + +/* Initialize a new bitarray of a given size in bits. */ +void bitarray_new( bitarray **ba_ppt, size_t size ); + +/* Set all bits in bitarray to 'on'. */ +void bitarray_fill( bitarray *ba_pt ); + +/* Set all bits in bitarray to 'off'. */ +void bitarray_zero( bitarray *ba_pt ); + +/* Test if a specific bit in a bitarray is set to 'on'. */ +bool bitarray_bit_on( bitarray *ba_pt, size_t pos ); + +/* Set the bit at a given position in a bitarray to 'on'. */ +void bitarray_bit_set( bitarray *ba_pt, size_t pos ); + +/* Debug function to print a bitarray. */ +void bitarray_print( bitarray *ba_pt ); + +/* Deallocate memory for bitarray. */ +void bitarray_destroy( bitarray **ba_ppt ); + diff --git a/code_c/Maasha/src/inc/list.h b/code_c/Maasha/src/inc/list.h index 33cc06b..a6a2f67 100644 --- a/code_c/Maasha/src/inc/list.h +++ b/code_c/Maasha/src/inc/list.h @@ -3,23 +3,22 @@ /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> STRUCTURE DECLARATIONS <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ -/* Singly linked list with a pointer to the next element and a pointer to a value. */ -struct _list +/* Singly linked list node. */ +struct _node_sl { - struct _list *next; - void *val; + struct _node_sl *next; /* Pointer to next node - NULL if last. */ + void *val; /* Pointer to data value. */ }; -typedef struct _list list; +typedef struct _node_sl node_sl; -/* Singly linked list with a pointer to the next element and an integer value. */ -struct _list_int +/* Singly linked list. */ +struct _list_sl { - struct _list_int *next; - int val; + node_sl *first; /* Pointer to first node - NULL for empty list. */ }; -typedef struct _list_int list_int; +typedef struct _list_sl list_sl; /* Doubly linked list node. */ struct _node_dl @@ -34,43 +33,44 @@ typedef struct _node_dl node_dl; /* Doubly linked list. */ struct _list_dl { - node_dl *first; /* Pointer to first node - NULL for empty list. */ + node_dl *first; /* Pointer to first node - NULL for empty list. */ node_dl *last; /* Pointer to last node - NULL for empty list. */ }; typedef struct _list_dl list_dl; + /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FUNCTION DECLARATIONS <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> SINGLY LINLED LIST <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ -/* Add a new singly linked list element with a pointer. */ -void list_add( list **list_ppt, void *val ); - -/* Add a new singly linked list element with an integer. */ -void list_add_int( list_int **list_ppt, int val ); +/* Initialize a new singly linked list. */ +void list_sl_new( list_sl **list_ppt ); -/* Reverse the order of elements in a singly linked list. */ -/* Usage: list_reverse( &list ) */ -void list_reverse( void *list_pt ); +/* Add a new node to the beginning of a singly linked list. */ +void list_sl_add_beg( list_sl **list_ppt, node_sl **node_ppt ); -/* Check if a given string exists in a singly linked list. */ -bool list_exists( list *list_pt, char *string ); +/* Add a new node after a given node of a singly linked list. */ +void list_sl_add_after( node_sl **node_ppt, node_sl **new_node_ppt ); -/* Check if a given integer exists in a singly linked list. */ -bool list_exists_int( list_int *list_pt, int val ); +/* Remove the first node of a singly linked list. */ +void list_sl_remove_beg( list_sl **list_ppt ); -/* Free memory for all elements of a singly linked list. */ -void list_free( void *list_pt ); +/* Remove the node next to this one in a singly linked list. */ +void list_sl_remove_after( node_sl **node_ppt ); /* Debug function to print all elements from a singly linked list. */ -void list_print( void *list_pt ); - +void list_sl_print( list_sl *list_pt ); + +/* Free memory for all nodes in and including the singly linked list. */ +void list_sl_destroy( list_sl **list_ppt ); + /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DOUBLY LINKED LIST <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ + /* Initialize a new doubly linked list. */ void list_dl_new( list_dl **list_ppt ); @@ -92,6 +92,10 @@ void list_dl_remove( list_dl **list_ppt, node_dl **node_ppt ); /* Debug function to print all elements from a doubly linked list. */ void list_dl_print( list_dl *list_pt ); +/* Free memory for all nodes in and including the doubly linked list. */ +void list_dl_destroy( list_dl **list_ppt ); + + /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ diff --git a/code_c/Maasha/src/inc/seq.h b/code_c/Maasha/src/inc/seq.h index 43b6563..a26b4c3 100644 --- a/code_c/Maasha/src/inc/seq.h +++ b/code_c/Maasha/src/inc/seq.h @@ -27,7 +27,7 @@ void seq_new( seq_entry **entry_ppt, size_t max_seq_name, size_t max_seq ); void seq_destroy( seq_entry *entry ); /* Uppercase sequence. */ -void uppercase_seq( char *seq ); +void seq_uppercase( char *seq ); /* Lowercase sequence. */ void lowercase_seq( char *seq ); diff --git a/code_c/Maasha/src/lib/Makefile b/code_c/Maasha/src/lib/Makefile index 7b9c64e..5f60845 100644 --- a/code_c/Maasha/src/lib/Makefile +++ b/code_c/Maasha/src/lib/Makefile @@ -3,7 +3,10 @@ CC = gcc Cflags = -Wall -Werror -g -pg # gprof INC_DIR = -I ../inc/ -all: common.o mem.o strings.o seq.o filesys.o fasta.o list.o hash.o ucsc.o +all: bits.o common.o mem.o strings.o seq.o filesys.o fasta.o list.o hash.o ucsc.o + +bits.o: bits.c + $(CC) $(Cflags) $(INC_DIR) -c bits.c common.o: common.c $(CC) $(Cflags) $(INC_DIR) -c common.c @@ -33,6 +36,7 @@ ucsc.o: ucsc.c $(CC) $(Cflags) $(INC_DIR) -c ucsc.c clean: + rm bits.o rm common.o rm mem.o rm strings.o diff --git a/code_c/Maasha/src/lib/bits.c b/code_c/Maasha/src/lib/bits.c new file mode 100644 index 0000000..ffe6e4f --- /dev/null +++ b/code_c/Maasha/src/lib/bits.c @@ -0,0 +1,190 @@ +#include "common.h" +#include "mem.h" +#include "bits.h" + + +static int mask_array[ 8 ] = { + BIT1, /* 10000000 */ + BIT2, /* 01000000 */ + BIT3, /* 00100000 */ + BIT4, /* 00010000 */ + BIT5, /* 00001000 */ + BIT6, /* 00000100 */ + BIT7, /* 00000010 */ + BIT8, /* 00000001 */ +}; + + +void bitarray_new( bitarray **ba_ppt, size_t size ) +{ + /* Martin A. Hansen, August 2008. */ + + /* Initialize a new bitarray of a given size in bits. */ + + bitarray *ba_pt = *ba_ppt; + size_t str_len = 0; + size_t modulus = 0; + + assert( size > 0 ); + + ba_pt = mem_get( sizeof( bitarray ) ); + + str_len = size / BITS_IN_BYTE; + modulus = size % BITS_IN_BYTE; + + if ( modulus != 0 ) { + str_len++; + } + + ba_pt->size = size; + ba_pt->str_len = str_len; + ba_pt->str = mem_get_zero( str_len + 1 ); + ba_pt->bits_on = 0; + + *ba_ppt = ba_pt; +} + + +void bitarray_fill( bitarray *ba_pt ) +{ + /* Martin A. Hansen, August 2008. */ + + /* Set all bits in bitarray to 'on'. */ + + memset( ba_pt->str, BYTE_ON, ba_pt->str_len ); + + ba_pt->bits_on = ba_pt->size; +} + + +void bitarray_zero( bitarray *ba_pt ) +{ + /* Martin A. Hansen, August 2008. */ + + /* Set all bits in bitarray to 'off'. */ + + bzero( ba_pt->str, ba_pt->str_len ); + + ba_pt->bits_on = 0; +} + + +bool bitarray_bit_on( bitarray *ba_pt, size_t pos ) +{ + /* Martin A. Hansen, August 2008. */ + + /* Test if a specific bit in a bitarray is set to 'on'. */ + + /* if pos == 0: */ + /* ruler: 01234567 89012345 67890123 */ + /* bitarray: 00100100 10001000 00010001 */ + /* pos: x */ + /* BIT1: 10000000 */ + /* AND (&): 00000000 */ + + /* if pos > 0 && modulus > 0: */ + /* ruler: 01234567 89012345 67890123 */ + /* bitarray: 00100100 10001000 00010001 */ + /* pos: x */ + /* BIT4 (modulus 3): 00010000 */ + /* AND (&): 00010000 */ + + assert( pos <= ba_pt->size ); + + size_t str_pos = 0; + size_t modulus = 0; + + modulus = pos % BITS_IN_BYTE; + str_pos = pos ? ( pos / BITS_IN_BYTE ) : 0; + + if ( modulus != 0 ) { + str_pos++; + } + + if ( ba_pt->str[ str_pos ] & mask_array[ modulus ] ) { + return TRUE; + } else { + return FALSE; + } +} + + +void bitarray_bit_set( bitarray *ba_pt, size_t pos ) +{ + /* Martin A. Hansen, August 2008. */ + + /* Set the bit at a given position in a bitarray to 'on'. */ + + /* if pos == 0: */ + /* ruler: 01234567 89012345 67890123 */ + /* bitarray: 00100100 10001000 00010001 */ + /* pos: x */ + /* BIT1: 10000000 */ + /* OR (|): 10100100 */ + + /* if pos > 0 && modulus > 0: */ + /* ruler: 01234567 89012345 67890123 */ + /* bitarray: 00100100 10001000 00010001 */ + /* pos: x */ + /* BIT5 (modulus 4): 00001000 */ + /* OR (|): 00011001 */ + + assert( pos <= ba_pt->size ); + + size_t str_pos = 0; + size_t modulus = 0; + + modulus = pos % BITS_IN_BYTE; + str_pos = pos ? ( pos / BITS_IN_BYTE ) : 0; + + if ( modulus != 0 ) { + str_pos++; + } + + ba_pt->str[ str_pos ] |= mask_array[ modulus ]; +} + + +void bitarray_print( bitarray *ba_pt ) +{ + /* Martin A. Hansen, August 2008. */ + + /* Debug function to print a bitarray. */ + + char *str = NULL; + size_t i = 0; + + str = mem_get_zero( ba_pt->size + 1 ); + + for ( i = 0; i < ba_pt->size; i++ ) + { + if ( bitarray_bit_on( ba_pt, i ) ) { + str[ i ] = '1'; + } else { + str[ i ] = '0'; + } + } + + printf( "\n" ); + printf( "ba_pt->str: %s\n", str ); + printf( "ba_pt->str (raw): %s\n", ba_pt->str ); + printf( "ba_pt->size: %zu\n", ba_pt->size ); + printf( "ba_pt->str_len: %zu\n", ba_pt->str_len ); + printf( "ba_pt->bits_on: %zu\n", ba_pt->bits_on ); + + mem_free( &str ); +} + + +void bitarray_destroy( bitarray **ba_ppt ) +{ + /* Martin A. Hansen, August 2008. */ + + /* Deallocate memory for bitarray. */ + + bitarray *ba_pt = *ba_ppt; + + mem_free( &ba_pt->str ); + + *ba_ppt = NULL; +} diff --git a/code_c/Maasha/src/lib/list.c b/code_c/Maasha/src/lib/list.c index edba268..79eb775 100644 --- a/code_c/Maasha/src/lib/list.c +++ b/code_c/Maasha/src/lib/list.c @@ -3,150 +3,130 @@ #include "list.h" -void list_add( list **list_ppt, void *val ) +/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> SINGLY LINKED LIST <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ + + +void list_sl_new( list_sl **list_ppt ) { - /* Martin A. Hansen, May 2008 */ + /* Martin A. Hansen, August 2008 */ - /* Add a new singly linked list element with a pointer. */ + /* Initialize a new singly linked list. */ - list *list_pt = *list_ppt; - list *new = NULL; + list_sl *new = NULL; - new = mem_get( sizeof( list ) ); + new = mem_get( sizeof( list_sl ) ); - new->val = val; - new->next = list_pt; + new->first = NULL; *list_ppt = new; } -void list_add_int( list_int **list_ppt, int val ) +void list_sl_add_beg( list_sl **list_ppt, node_sl **node_ppt ) { - /* Martin A. Hansen, May 2008 */ - - /* Add a new singly linked list element with a integer. */ + /* Martin A. Hansen, August 2008 */ - list_int *elem = NULL; + /* Add a new node to the beginning of a singly linked list. */ - elem = mem_get( sizeof( list_int ) ); + list_sl *list_pt = *list_ppt; + node_sl *node_pt = *node_ppt; - elem->val = val; - elem->next = *list_ppt; - *list_ppt = elem; + node_pt->next = list_pt->first; + list_pt->first = node_pt; } -void list_reverse( void *list_pt ) +void list_sl_add_after( node_sl **node_ppt, node_sl **new_node_ppt ) { /* Martin A. Hansen, August 2008 */ - /* Reverse the order of elements in a singly linked list. */ + /* Add a new node after a given node of a singly linked list. */ + + node_sl *node_pt = *node_ppt; + node_sl *new_node_pt = *new_node_ppt; + + new_node_pt->next = node_pt->next; + node_pt->next = new_node_pt; +} - list **list_ppt = ( list ** ) list_pt; - list *pt = *list_ppt; - list *new = NULL; - list *next = NULL; - list *temp = NULL; - next = pt; +void list_sl_remove_beg( list_sl **list_ppt ) +{ + /* Martin A. Hansen, August 2008 */ - while ( next != NULL ) - { - temp = next; - next = temp->next; - temp->next = new; - new = temp; - } + /* Remove the first node of a singly linked list. */ - *list_ppt = new; + list_sl *list_pt = *list_ppt; + node_sl *old_node = NULL; + + old_node = list_pt->first; + list_pt->first = list_pt->first->next; + + mem_free( &old_node ); } -bool list_exists( list *list_pt, char *string ) +void list_sl_remove_after( node_sl **node_ppt ) { - /* Martin A. Hansen, June 2008 */ - - /* Check if a given string exists in a singly linked list. */ + /* Martin A. Hansen, August 2008 */ - list *elem = NULL; + /* Remove the node next to this one in a singly linked list. */ - elem = mem_get( sizeof( list ) ); + node_sl *node_pt = *node_ppt; + node_sl *old_node = NULL; - for ( elem = list_pt; elem != NULL; elem = elem->next ) - { - if ( strcmp( elem->val, string ) == 0 ) { - return TRUE; - } - } + old_node = node_pt->next; + node_pt->next = node_pt->next->next; - return FALSE; -} + mem_free( &old_node ); +} -bool list_exists_int( list_int *list_pt, int val ) +void list_sl_print( list_sl *list_pt ) { - /* Martin A. Hansen, June 2008 */ - - /* Check if a given integer exists in a singly linked list. */ + /* Martin A. Hansen, August 2008 */ - list_int *elem = NULL; + /* Debug function to print all elements from a singly linked list. */ - elem = mem_get( sizeof( list_int ) ); + node_sl *node = list_pt->first; + int i = 0; - for ( elem = list_pt; elem != NULL; elem = elem->next ) + while ( node != NULL ) { - if ( elem->val == val ) { - return TRUE; - } - } + printf( "Node: %d val: %s\n", i, ( char * ) node->val ); - return FALSE; -} + node = node->next; + + i++; + } +} -void list_free( void *list_pt ) +void list_sl_destroy( list_sl **list_ppt ) { - /* Martin A. Hansen, June 2008 */ + /* Martin A. Hansen, August 2008 */ - /* Free memory for all elements of a singly linked list. */ + /* Free memory for all nodes in and including the singly linked list. */ - list **list_ppt = ( list ** ) list_pt; - list *next = *list_ppt; - list *elem = NULL; + list_sl *list_pt = *list_ppt; + node_sl *next = list_pt->first; + node_sl *node = NULL; while ( next != NULL ) { - elem = next; - -// printf( "elem->val: %s\n", ( char * ) elem->val ); + node = next; + next = node->next; - next = elem->next; -// mem_free( &elem ); - free( elem ); + mem_free( &node ); } + mem_free( &list_pt ); + *list_ppt = NULL; } -void list_print( void *list_pt ) -{ - /* Martin A. Hansen, June 2008 */ - - /* Debug function to print all elements from a singly linked list. */ - - list *first = ( list * ) list_pt; - list *elem = NULL; - int i = 0; - - for ( elem = first; elem != NULL; elem = elem->next ) - { - printf( "Elem %d: ->%s<-\n", i, ( char * ) elem->val ); - - i++; - } -} +/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DOUBLY LINKED LIST <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ void list_dl_new( list_dl **list_ppt ) @@ -297,3 +277,30 @@ void list_dl_print( list_dl *list_pt ) i++; } } + + +void list_dl_destroy( list_dl **list_ppt ) +{ + /* Martin A. Hansen, August 2008 */ + + /* Free memory for all nodes in and including the doubly linked list. */ + + list_dl *list_pt = *list_ppt; + node_dl *next = list_pt->first; + node_dl *node = NULL; + + while ( next != NULL ) + { + node = next; + next = node->next; + + mem_free( &node ); + } + + mem_free( &list_pt ); + + *list_ppt = NULL; +} + + +/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ diff --git a/code_c/Maasha/src/lib/mem.c b/code_c/Maasha/src/lib/mem.c index 809a038..6f5211d 100644 --- a/code_c/Maasha/src/lib/mem.c +++ b/code_c/Maasha/src/lib/mem.c @@ -38,7 +38,7 @@ void *mem_get_zero( size_t size ) pt = mem_get( size ); - memset( pt, '\0', size ); + bzero( pt, size ); return pt; } @@ -79,7 +79,7 @@ void *mem_resize_zero( void *pt, size_t old_size, size_t new_size ) pt_new = mem_resize( pt, new_size ); if ( new_size > old_size ) { - memset( ( ( void * ) pt_new ) + old_size, '\0', new_size - old_size ); + bzero( ( ( void * ) pt_new ) + old_size, new_size - old_size ); } return pt_new; diff --git a/code_c/Maasha/src/lib/seq.c b/code_c/Maasha/src/lib/seq.c index 1491b2a..daab464 100644 --- a/code_c/Maasha/src/lib/seq.c +++ b/code_c/Maasha/src/lib/seq.c @@ -32,7 +32,7 @@ void seq_destroy( seq_entry *entry ) } -void uppercase_seq( char *seq ) +void seq_uppercase( char *seq ) { /* Martin A. Hansen, May 2008 */ diff --git a/code_c/Maasha/src/test/Makefile b/code_c/Maasha/src/test/Makefile index 3d1cbab..bd3b235 100644 --- a/code_c/Maasha/src/test/Makefile +++ b/code_c/Maasha/src/test/Makefile @@ -9,7 +9,10 @@ LIB = -lm $(LIB_DIR)*.o all: test -test: test_common test_fasta test_filesys test_list test_mem test_seq test_strings +test: test_bits test_common test_fasta test_filesys test_list test_mem test_seq test_strings + +test_bits: test_bits.c $(LIB_DIR)bits.c + $(CC) $(Cflags) $(INC) $(LIB) test_bits.c -o test_bits test_common: test_common.c $(LIB_DIR)common.c $(CC) $(Cflags) $(INC) $(LIB) test_common.c -o test_common @@ -33,6 +36,7 @@ test_strings: test_strings.c $(LIB_DIR)strings.c $(CC) $(Cflags) $(INC) $(LIB) test_strings.c -o test_strings clean: + rm test_bits rm test_common rm test_fasta rm test_filesys diff --git a/code_c/Maasha/src/test/test_bits.c b/code_c/Maasha/src/test/test_bits.c new file mode 100644 index 0000000..ac1a54e --- /dev/null +++ b/code_c/Maasha/src/test/test_bits.c @@ -0,0 +1,168 @@ +#include "common.h" +#include "bits.h" + +static void test_bitarray_new(); +static void test_bitarray_fill(); +static void test_bitarray_zero(); +static void test_bitarray_bit_on(); +static void test_bitarray_bit_set(); +static void test_bitarray_print(); +static void test_bitarray_destroy(); + + +int main() +{ + fprintf( stderr, "Running all tests for bits.c\n" ); + + test_bitarray_new(); + test_bitarray_fill(); + test_bitarray_zero(); + test_bitarray_bit_on(); + test_bitarray_bit_set(); + test_bitarray_print(); + test_bitarray_destroy(); + + fprintf( stderr, "Done\n\n" ); + + return EXIT_SUCCESS; +} + + +void test_bitarray_new() +{ + fprintf( stderr, " Testing bitarray_new ... " ); + + bitarray *ba = NULL; + size_t size = 6; + + bitarray_new( &ba, size ); + + bitarray_destroy( &ba ); + + fprintf( stderr, "OK\n" ); +} + + +void test_bitarray_fill() +{ + fprintf( stderr, " Testing bitarray_fill ... " ); + + bitarray *ba = NULL; + size_t size = 2; + + bitarray_new( &ba, size ); + + assert( bitarray_bit_on( ba, size - 1 ) == FALSE ); + + bitarray_print( ba ); + bitarray_fill( ba ); + bitarray_print( ba ); + + assert( bitarray_bit_on( ba, size - 1 ) == TRUE ); + +// bitarray_print( ba ); + + bitarray_destroy( &ba ); + + fprintf( stderr, "OK\n" ); +} + + +void test_bitarray_zero() +{ + fprintf( stderr, " Testing bitarray_zero ... " ); + + bitarray *ba = NULL; + size_t size = 26; + + bitarray_new( &ba, size ); + bitarray_fill( ba ); + +// assert( bitarray_bit_on( ba, size ) == TRUE ); + + bitarray_zero( ba ); + +// assert( bitarray_bit_on( ba, size ) == FALSE ); + + bitarray_destroy( &ba ); + + fprintf( stderr, "OK\n" ); +} + + +void test_bitarray_bit_on() +{ + fprintf( stderr, " Testing bitarray_bit_on ... " ); + + bitarray *ba = NULL; + size_t size = 26; + + bitarray_new( &ba, size ); + + assert( bitarray_bit_on( ba, 20 ) == FALSE ); + assert( bitarray_bit_on( ba, 0 ) == FALSE ); + assert( bitarray_bit_on( ba, 8 ) == FALSE ); + + bitarray_destroy( &ba ); + + fprintf( stderr, "OK\n" ); +} + + +void test_bitarray_bit_set() +{ + fprintf( stderr, " Testing bitarray_bit_set ... " ); + + bitarray *ba = NULL; + size_t size = 26; + + bitarray_new( &ba, size ); + + bitarray_bit_set( ba, 20 ); + assert( bitarray_bit_on( ba, 20 ) == TRUE ); + + bitarray_bit_set( ba, 0 ); + //assert( bitarray_bit_on( ba, 0 ) == TRUE ); + + bitarray_bit_set( ba, 8 ); + //assert( bitarray_bit_on( ba, 8 ) == TRUE ); + + bitarray_destroy( &ba ); + + fprintf( stderr, "OK\n" ); +} + + +void test_bitarray_print() +{ + fprintf( stderr, " Testing bitarray_print ... " ); + + bitarray *ba = NULL; + size_t size = 6; + + bitarray_new( &ba, size ); + bitarray_print( ba ); + + bitarray_destroy( &ba ); + + fprintf( stderr, "OK\n" ); +} + + +void test_bitarray_destroy() +{ + fprintf( stderr, " Testing bitarray_destroy ... " ); + + bitarray *ba = NULL; + size_t size = 26; + + bitarray_new( &ba, size ); + + bitarray_destroy( &ba ); + + assert( ba == NULL ); + + fprintf( stderr, "OK\n" ); +} + + diff --git a/code_c/Maasha/src/test/test_list.c b/code_c/Maasha/src/test/test_list.c new file mode 100644 index 0000000..6e743ee --- /dev/null +++ b/code_c/Maasha/src/test/test_list.c @@ -0,0 +1,520 @@ +#include "common.h" +#include "mem.h" +#include "list.h" + +static void test_list_sl_new(); +static void test_list_sl_add_beg(); +static void test_list_sl_add_after(); +static void test_list_sl_remove_beg(); +static void test_list_sl_remove_after(); +static void test_list_sl_print(); +static void test_list_sl_destroy(); + +static void test_list_dl_new(); +static void test_list_dl_add_beg(); +static void test_list_dl_add_end(); +static void test_list_dl_add_before(); +static void test_list_dl_add_after(); +static void test_list_dl_remove(); +static void test_list_dl_print(); +static void test_list_dl_destroy(); + +int main() +{ + fprintf( stderr, "Running all tests for list.c\n" ); + + test_list_sl_new(); + test_list_sl_add_beg(); + test_list_sl_add_after(); + test_list_sl_remove_beg(); + test_list_sl_remove_after(); + test_list_sl_print(); + test_list_sl_destroy(); + + test_list_dl_new(); + test_list_dl_add_beg(); + test_list_dl_add_end(); + test_list_dl_add_before(); + test_list_dl_add_after(); + test_list_dl_remove(); + test_list_dl_print(); + test_list_dl_destroy(); + + fprintf( stderr, "Done\n\n" ); + + return EXIT_SUCCESS; +} + + +void test_list_sl_new() +{ + fprintf( stderr, " Testing list_sl_new ... " ); + + list_sl *list = NULL; + + list_sl_new( &list ); + + assert( list->first == NULL ); + + fprintf( stderr, "OK\n" ); +} + + +void test_list_sl_add_beg() +{ + fprintf( stderr, " Testing list_sl_add_beg ... " ); + + list_sl *list = NULL; + node_sl *node1 = NULL; + node_sl *node2 = NULL; + node_sl *node3 = NULL; + + list_sl_new( &list ); + + node1 = mem_get( sizeof( node_sl ) ); + node2 = mem_get( sizeof( node_sl ) ); + node3 = mem_get( sizeof( node_sl ) ); + + node1->val = "TEST1"; + node2->val = "TEST2"; + node3->val = "TEST3"; + + assert( list->first == NULL ); + + list_sl_add_beg( &list, &node1 ); + assert( list->first == node1 ); + assert( strcmp( list->first->val, "TEST1" ) == 0 ); + + list_sl_add_beg( &list, &node2 ); + assert( list->first == node2 ); + assert( strcmp( list->first->val, "TEST2" ) == 0 ); + + list_sl_add_beg( &list, &node3 ); + assert( list->first == node3 ); + assert( strcmp( list->first->val, "TEST3" ) == 0 ); + + fprintf( stderr, "OK\n" ); +} + + +void test_list_sl_add_after() +{ + fprintf( stderr, " Testing list_sl_add_after ... " ); + + list_sl *list = NULL; + node_sl *node1 = NULL; + node_sl *node2 = NULL; + + list_sl_new( &list ); + + node1 = mem_get( sizeof( node_sl ) ); + node2 = mem_get( sizeof( node_sl ) ); + + node1->val = "TEST1"; + node2->val = "TEST2"; + + assert( list->first == NULL ); + + list_sl_add_beg( &list, &node1 ); + assert( list->first == node1 ); + assert( strcmp( list->first->val, "TEST1" ) == 0 ); + + list_sl_add_after( &node1, &node2 ); + assert( list->first == node1 ); + assert( strcmp( list->first->val, "TEST1" ) == 0 ); + + fprintf( stderr, "OK\n" ); +} + + +void test_list_sl_remove_beg() +{ + fprintf( stderr, " Testing list_sl_remove_beg ... " ); + + list_sl *list = NULL; + node_sl *node1 = NULL; + + list_sl_new( &list ); + + node1 = mem_get( sizeof( node_sl ) ); + + node1->val = "TEST1"; + + assert( list->first == NULL ); + + list_sl_add_beg( &list, &node1 ); + assert( list->first == node1 ); + assert( strcmp( list->first->val, "TEST1" ) == 0 ); + + list_sl_remove_beg( &list ); + assert( list->first == NULL ); + + fprintf( stderr, "OK\n" ); +} + + +void test_list_sl_remove_after() +{ + fprintf( stderr, " Testing list_sl_remove_after ... " ); + + list_sl *list = NULL; + node_sl *node1 = NULL; + node_sl *node2 = NULL; + + list_sl_new( &list ); + + node1 = mem_get( sizeof( node_sl ) ); + node2 = mem_get( sizeof( node_sl ) ); + + node1->val = "TEST1"; + node2->val = "TEST2"; + + assert( list->first == NULL ); + + list_sl_add_beg( &list, &node1 ); + assert( list->first == node1 ); + assert( strcmp( list->first->val, "TEST1" ) == 0 ); + + list_sl_add_after( &node1, &node2 ); + assert( list->first == node1 ); + assert( strcmp( list->first->val, "TEST1" ) == 0 ); + + list_sl_remove_after( &node1 ); + assert( list->first->next == NULL ); + + fprintf( stderr, "OK\n" ); +} + + +void test_list_sl_print() +{ + fprintf( stderr, " Testing list_sl_print ... " ); + + list_sl *list = NULL; + node_sl *node1 = NULL; + node_sl *node2 = NULL; + node_sl *node3 = NULL; + + list_sl_new( &list ); + + node1 = mem_get( sizeof( node_sl ) ); + node2 = mem_get( sizeof( node_sl ) ); + node3 = mem_get( sizeof( node_sl ) ); + + node1->val = "TEST1"; + node2->val = "TEST2"; + node3->val = "TEST3"; + + list_sl_add_beg( &list, &node1 ); + list_sl_add_beg( &list, &node2 ); + list_sl_add_beg( &list, &node3 ); + + // list_sl_print( list ); + + fprintf( stderr, "OK\n" ); +} + + +void test_list_sl_destroy() +{ + fprintf( stderr, " Testing list_sl_destroy ... " ); + + list_sl *list = NULL; + node_sl *node1 = NULL; + node_sl *node2 = NULL; + node_sl *node3 = NULL; + + list_sl_new( &list ); + + node1 = mem_get( sizeof( node_sl ) ); + node2 = mem_get( sizeof( node_sl ) ); + node3 = mem_get( sizeof( node_sl ) ); + + node1->val = "TEST1"; + node2->val = "TEST2"; + node3->val = "TEST3"; + + list_sl_add_beg( &list, &node1 ); + list_sl_add_beg( &list, &node2 ); + list_sl_add_beg( &list, &node3 ); + + list_sl_destroy( &list ); + + assert( list == NULL ); + + fprintf( stderr, "OK\n" ); +} + + +void test_list_dl_new() +{ + fprintf( stderr, " Testing list_dl_new ... " ); + + list_dl *list = NULL; + + list_dl_new( &list ); + + assert( list->first == NULL ); + assert( list->last == NULL ); + + fprintf( stderr, "OK\n" ); +} + + +void test_list_dl_add_beg() +{ + fprintf( stderr, " Testing list_dl_add_beg ... " ); + + list_dl *list = NULL; + node_dl *node1 = NULL; + node_dl *node2 = NULL; + node_dl *node3 = NULL; + + list_dl_new( &list ); + + node1 = mem_get( sizeof( node_dl ) ); + node2 = mem_get( sizeof( node_dl ) ); + node3 = mem_get( sizeof( node_dl ) ); + + node1->val = "TEST1"; + node2->val = "TEST2"; + node3->val = "TEST3"; + + list_dl_add_beg( &list, &node1 ); + + assert( strcmp( list->first->val, "TEST1" ) == 0 ); + + list_dl_add_beg( &list, &node2 ); + + assert( strcmp( list->first->val, "TEST2" ) == 0 ); + + list_dl_add_beg( &list, &node3 ); + + assert( strcmp( list->first->val, "TEST3" ) == 0 ); + + fprintf( stderr, "OK\n" ); +} + + +void test_list_dl_add_end() +{ + fprintf( stderr, " Testing list_dl_add_end ... " ); + + list_dl *list = NULL; + node_dl *node1 = NULL; + node_dl *node2 = NULL; + node_dl *node3 = NULL; + + list_dl_new( &list ); + + node1 = mem_get( sizeof( node_dl ) ); + node2 = mem_get( sizeof( node_dl ) ); + node3 = mem_get( sizeof( node_dl ) ); + + node1->val = "TEST1"; + node2->val = "TEST2"; + node3->val = "TEST3"; + + list_dl_add_end( &list, &node1 ); + + assert( strcmp( list->last->val, "TEST1" ) == 0 ); + + list_dl_add_end( &list, &node2 ); + + assert( strcmp( list->last->val, "TEST2" ) == 0 ); + + list_dl_add_end( &list, &node3 ); + + assert( strcmp( list->last->val, "TEST3" ) == 0 ); + + fprintf( stderr, "OK\n" ); +} + + +void test_list_dl_add_before() +{ + fprintf( stderr, " Testing list_dl_add_before ... " ); + + list_dl *list = NULL; + node_dl *node1 = NULL; + node_dl *node2 = NULL; + node_dl *node3 = NULL; + + list_dl_new( &list ); + + node1 = mem_get( sizeof( node_dl ) ); + node2 = mem_get( sizeof( node_dl ) ); + node3 = mem_get( sizeof( node_dl ) ); + + node1->val = "TEST1"; + node2->val = "TEST2"; + node3->val = "TEST3"; + + list_dl_add_beg( &list, &node1 ); + + assert( strcmp( list->first->val, "TEST1" ) == 0 ); + + list_dl_add_before( &list, &node1, &node2 ); + + assert( strcmp( list->first->val, "TEST2" ) == 0 ); + + list_dl_add_before( &list, &node1, &node3 ); + + assert( strcmp( list->first->val, "TEST2" ) == 0 ); + + list_dl_add_before( &list, &node2, &node3 ); + + assert( strcmp( list->first->val, "TEST3" ) == 0 ); + + fprintf( stderr, "OK\n" ); +} + + +void test_list_dl_add_after() +{ + fprintf( stderr, " Testing list_dl_add_after ... " ); + + list_dl *list = NULL; + node_dl *node1 = NULL; + node_dl *node2 = NULL; + node_dl *node3 = NULL; + + list_dl_new( &list ); + + node1 = mem_get( sizeof( node_dl ) ); + node2 = mem_get( sizeof( node_dl ) ); + node3 = mem_get( sizeof( node_dl ) ); + + node1->val = "TEST1"; + node2->val = "TEST2"; + node3->val = "TEST3"; + + list_dl_add_beg( &list, &node1 ); + + assert( strcmp( list->first->val, "TEST1" ) == 0 ); + + list_dl_add_after( &list, &node1, &node2 ); + + assert( strcmp( list->last->val, "TEST2" ) == 0 ); + + list_dl_add_after( &list, &node1, &node3 ); + + assert( strcmp( list->last->val, "TEST2" ) == 0 ); + + list_dl_add_after( &list, &node2, &node3 ); + + assert( strcmp( list->last->val, "TEST3" ) == 0 ); + + fprintf( stderr, "OK\n" ); +} + + +void test_list_dl_remove() +{ + fprintf( stderr, " Testing list_dl_remove ... " ); + + list_dl *list = NULL; + node_dl *node1 = NULL; + node_dl *node2 = NULL; + node_dl *node3 = NULL; + + list_dl_new( &list ); + + node1 = mem_get( sizeof( node_dl ) ); + node2 = mem_get( sizeof( node_dl ) ); + node3 = mem_get( sizeof( node_dl ) ); + + node1->val = "TEST1"; + node2->val = "TEST2"; + node3->val = "TEST3"; + + list_dl_add_beg( &list, &node1 ); + + assert( strcmp( list->first->val, "TEST1" ) == 0 ); + + list_dl_add_after( &list, &node1, &node2 ); + + assert( strcmp( list->last->val, "TEST2" ) == 0 ); + + list_dl_add_after( &list, &node1, &node3 ); + + assert( strcmp( list->last->val, "TEST2" ) == 0 ); + + list_dl_add_after( &list, &node2, &node3 ); + + assert( strcmp( list->last->val, "TEST3" ) == 0 ); + + list_dl_remove( &list, &node3 ); + + assert( strcmp( list->last->val, "TEST2" ) == 0 ); + + list_dl_remove( &list, &node2 ); + + assert( strcmp( list->first->val, "TEST1" ) == 0 ); + + list_dl_remove( &list, &node1 ); + + fprintf( stderr, "OK\n" ); +} + + +void test_list_dl_print() +{ + fprintf( stderr, " Testing list_dl_print ... " ); + + list_dl *list = NULL; + node_dl *node1 = NULL; + node_dl *node2 = NULL; + node_dl *node3 = NULL; + + list_dl_new( &list ); + + node1 = mem_get( sizeof( node_dl ) ); + node2 = mem_get( sizeof( node_dl ) ); + node3 = mem_get( sizeof( node_dl ) ); + + node1->val = "TEST1"; + node2->val = "TEST2"; + node3->val = "TEST3"; + + list_dl_add_beg( &list, &node1 ); + list_dl_add_beg( &list, &node2 ); + list_dl_add_beg( &list, &node3 ); + +// list_dl_print( list ); + + fprintf( stderr, "OK\n" ); +} + + +void test_list_dl_destroy() +{ + fprintf( stderr, " Testing list_dl_destroy ... " ); + + list_dl *list = NULL; + node_dl *node1 = NULL; + node_dl *node2 = NULL; + node_dl *node3 = NULL; + + list_dl_new( &list ); + + node1 = mem_get( sizeof( node_dl ) ); + node2 = mem_get( sizeof( node_dl ) ); + node3 = mem_get( sizeof( node_dl ) ); + + node1->val = "TEST1"; + node2->val = "TEST2"; + node3->val = "TEST3"; + + list_dl_add_beg( &list, &node1 ); + list_dl_add_beg( &list, &node2 ); + list_dl_add_beg( &list, &node3 ); + + list_dl_destroy( &list ); + + assert( list == NULL ); + +// list_dl_print( list ); + + fprintf( stderr, "OK\n" ); +} diff --git a/code_c/Maasha/src/test/test_seq.c b/code_c/Maasha/src/test/test_seq.c index db6d7bb..11d6a5d 100644 --- a/code_c/Maasha/src/test/test_seq.c +++ b/code_c/Maasha/src/test/test_seq.c @@ -1,7 +1,9 @@ #include "common.h" +#include "mem.h" #include "seq.h" static void test_seq_new(); +static void test_seq_uppercase(); static void test_seq_destroy(); @@ -10,6 +12,7 @@ int main() fprintf( stderr, "Running all tests for seq.c\n" ); test_seq_new(); + test_seq_uppercase(); test_seq_destroy(); fprintf( stderr, "Done\n\n" ); @@ -38,6 +41,20 @@ void test_seq_new() } +void test_seq_uppercase() +{ + fprintf( stderr, " Testing seq_uppercase ... " ); + + char seq[] = "atcg"; + + seq_uppercase( seq ); + + assert( strcmp( seq, "ATCG" ) == 0 ); + + fprintf( stderr, "OK\n" ); +} + + void test_seq_destroy() { fprintf( stderr, " Testing seq_destroy ... " ); diff --git a/code_perl/Maasha/Biopieces.pm b/code_perl/Maasha/Biopieces.pm index 453bc24..29a914a 100644 --- a/code_perl/Maasha/Biopieces.pm +++ b/code_perl/Maasha/Biopieces.pm @@ -71,7 +71,6 @@ require Exporter; use constant { SEQ_NAME => 0, SEQ => 1, - SCORE => 2, }; @@ -391,6 +390,7 @@ sub get_options @options = qw( data_in|i=s num|n=s + format|f=s quality|q=s ); } @@ -1039,6 +1039,10 @@ sub get_options { Maasha::Common::error( qq(Argument to --$opt must be AandB, AorB, BorA, AnotB, or BnotA - not "$options{ $opt }") ); } + elsif ( $opt eq "format" and $script eq "read_solexa" and $options{ $opt } !~ /octal|decimal/ ) + { + Maasha::Common::error( qq(Argument to --$opt must be octal or decimal - not "$options{ $opt }") ); + } } Maasha::Common::error( qq(no --database specified) ) if $script eq "create_blast_db" and not $options{ "database" }; @@ -1916,6 +1920,7 @@ sub script_read_solexa my ( $record, $file, $data_in, $entry, $num, @seqs, @scores, $i ); + $options->{ "format" } ||= "octal"; $options->{ "quality" } ||= 20; while ( $record = get_record( $in ) ) { @@ -1928,25 +1933,31 @@ sub script_read_solexa { $data_in = Maasha::Common::read_open( $file ); - while ( $entry = Maasha::Solexa::solexa_get_entry( $data_in ) ) + if ( $options->{ "format" } eq "octal" ) { - @seqs = split //, $entry->[ SEQ ]; - @scores = split /:/, $entry->[ SCORE ]; + while ( $entry = Maasha::Solexa::solexa_get_entry_octal( $data_in ) ) + { + $record = Maasha::Solexa::solexa2biopiece( $entry, $options->{ "quality" } ); - for ( $i = 0; $i < @scores; $i++ ) { - $seqs[ $i ] = lc $seqs[ $i ] if $scores[ $i ] < $options->{ "quality" }; - } + put_record( $record, $out ); - $record->{ "SEQ_NAME" } = $entry->[ SEQ_NAME ]; - $record->{ "SEQ" } = join "", @seqs; - $record->{ "SEQ_LEN" } = scalar @seqs; - $record->{ "SCORE_MEAN" } = sprintf ( "%.2f", Maasha::Calc::mean( \@scores ) ); + goto NUM if $options->{ "num" } and $num == $options->{ "num" }; - put_record( $record, $out ); + $num++; + } + } + else + { + while ( $entry = Maasha::Solexa::solexa_get_entry_decimal( $data_in ) ) + { + $record = Maasha::Solexa::solexa2biopiece( $entry, $options->{ "quality" } ); - goto NUM if $options->{ "num" } and $num == $options->{ "num" }; + put_record( $record, $out ); - $num++; + goto NUM if $options->{ "num" } and $num == $options->{ "num" }; + + $num++; + } } close $data_in; @@ -5967,7 +5978,7 @@ sub script_upload_to_ucsc if ( $options->{ "score" } ) { $clones = $entry->{ 'SCORE' }; - } if ( $q_id =~ /_(\d+)$/ ) { + } elsif ( $q_id =~ /_(\d+)$/ ) { $clones = $1; } else { $clones = 1; diff --git a/code_perl/Maasha/Seq.pm b/code_perl/Maasha/Seq.pm index 9b3ae08..c224808 100644 --- a/code_perl/Maasha/Seq.pm +++ b/code_perl/Maasha/Seq.pm @@ -1437,17 +1437,17 @@ sub check_diag # Checks the diagonal starting at a given coordinate # of a search space constituted by an adaptor and a tag sequence. # Residues in the diagonal are compared between the sequences allowing - # for a given number of mismatches. We terminate when search spaca is + # for a given number of mismatches. We terminate when search space is # exhausted or if max matches or mismatches is reached. - my ( $adaptor, - $tag, - $adaptor_len, - $tag_len, - $adaptor_beg, - $tag_beg, - $max_match, - $max_mismatch, + my ( $adaptor, # list of chars + $tag, # list of chars + $adaptor_len, # length of adaptor sequence + $tag_len, # length of tag sequence + $adaptor_beg, # adaptor begin coordinate + $tag_beg, # tag begin coordinate + $max_match, # number of matches indicating success + $max_mismatch, # number of mismatches ) = @_; # Returns boolean. diff --git a/code_perl/Maasha/Solexa.pm b/code_perl/Maasha/Solexa.pm index 930fc88..0fe7f10 100644 --- a/code_perl/Maasha/Solexa.pm +++ b/code_perl/Maasha/Solexa.pm @@ -35,11 +35,16 @@ require Exporter; @ISA = qw( Exporter ); +use constant { + SEQ_NAME => 0, + SEQ => 1, + SCORE => 2, +}; # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> SUBROUTINES <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -sub solexa_get_entry +sub solexa_get_entry_octal { # Martin A. Hansen, August 2008 @@ -73,11 +78,11 @@ sub solexa_get_entry @scores = split //, $score; - map { $_ = score_oct2dec( $_ ) } @scores; + map { $_ = int( score_oct2dec( $_ ) ) } @scores; $seq_header =~ s/^@//; - $score = join( ":", @scores ); + $score = join( ";", @scores ); return wantarray ? ( $seq_header, $seq, $score ) : [ $seq_header, $seq, $score ]; } @@ -100,6 +105,79 @@ sub score_oct2dec } +sub solexa_get_entry_decimal +{ + # Martin A. Hansen, August 2008 + + # Get the next Solexa entry form a file and returns + # a triple of [ seq_name, seq, score ]. + # We asume a Solexa entry consists of four lines: + + # @USI-EAS18_131_4_1_352_619 + # ATGGATGGGTTGGAGATGCCCTCTGTAGGCACCAT + # +USI-EAS18_131_4_1_352_619 + # 40 40 40 40 40 40 40 40 40 40 40 25 25 40 40 34 40 40 40 40 32 39 40 36 34 19 40 19 30 16 21 11 21 18 11 + + my ( $fh, # filehandle to Solexa file + ) = @_; + + # Returns a list. + + my ( $seq_header, $seq, $score_head, $score, @scores ); + + $seq_header = <$fh>; + $seq = <$fh>; + $score_header = <$fh>; + $score = <$fh>; + + return if not defined $score; + + chomp $seq_header; + chomp $seq; + chomp $score_header; + chomp $score; + + @scores = split / /, $score; + + $seq_header =~ s/^@//; + + $score = join( ";", @scores ); + + return wantarray ? ( $seq_header, $seq, $score ) : [ $seq_header, $seq, $score ]; +} + + +sub solexa2biopiece +{ + # Martin A. Hansen, September 2008. + + # Converts a Solexa entry to a Biopiece record. + + my ( $entry, # Solexa entry + $qualilty, # Quality cutoff + ) = @_; + + # Returns a hashref. + + my ( @seqs, @scores, $i, %record ); + + @seqs = split //, $entry->[ SEQ ]; + @scores = split /;/, $entry->[ SCORE ]; + + for ( $i = 0; $i < @scores; $i++ ) { + $seqs[ $i ] = lc $seqs[ $i ] if $scores[ $i ] < $quality; + } + + $record{ "SEQ_NAME" } = $entry->[ SEQ_NAME ]; + $record{ "SEQ" } = $entry->[ SEQ ]; + $record{ "SCORES" } = $entry->[ SCORE ]; + $record{ "SEQ_LEN" } = scalar @seqs; + $record{ "SCORE_MEAN" } = sprintf ( "%.2f", Maasha::Calc::mean( \@scores ) ); + + return wantarray ? %record : \%record; +} + + # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<