1 /* Martin Asser Hansen (mail@maasha.dk) Copyright (C) 2008 - All right reserved */
12 bed_entry *bed_entry_new( const int cols )
14 /* Martin A. Hansen, September 2008 */
16 /* Returns a new BED entry with memory allocated for */
17 /* a given number of columns. */
19 bed_entry *entry = mem_get( sizeof( bed_entry ) );
22 entry->chr = mem_get( BED_CHR_MAX );
30 entry->q_id = mem_get( BED_QID_MAX );
50 entry->itemrgb = mem_get( BED_ITEMRGB_MAX );
51 entry->blockcount = 0;
52 entry->blocksizes = mem_get( BED_BLOCKSIZES_MAX );
53 entry->q_begs = mem_get( BED_QBEGS_MAX );
59 void bed_entry_destroy( bed_entry *entry )
61 /* Martin A. Hansen, September 2008 */
63 /* Free memory for a BED entry. */
65 int cols = entry->cols;
69 free( entry->itemrgb );
70 free( entry->blocksizes );
71 free( entry->q_begs );
89 bed_entry *bed_entry_get( FILE *fp, int cols )
91 /* Martin A. Hansen, September 2008 */
93 /* Get next BED entry of a given number of columns from a file pointer. */
95 bed_entry *entry = bed_entry_new( cols );
96 char buffer[ BED_BUFFER ];
98 assert( cols == 0 || cols == 3 || cols == 4 || cols == 5 || cols == 6 || cols == 12 );
100 if ( fgets( buffer, sizeof( buffer ), fp ) != NULL )
104 cols = 1 + strchr_total( buffer, '\t' );
139 "%s\t%u\t%u\t%s\t%i",
154 "%s\t%u\t%u\t%s\t%i\t%c",
170 "%s\t%u\t%u\t%s\t%i\t%c\t%u\t%u\t%s\t%u\t%s\t%s",
193 list_sl *bed_entries_get( char *path, const int cols )
195 /* Martin A. Hansen, September 2008 */
197 /* Get a singly linked list with all BED entries (of a given number of coluns */
198 /* from a specified file. */
200 list_sl *list = list_sl_new();
201 node_sl *node = node_sl_new();
202 node_sl *old_node = NULL;
203 bed_entry *entry = NULL;
206 fp = read_open( path );
208 if ( ( entry = bed_entry_get( fp, cols ) ) != NULL )
212 list_sl_add_beg( &list, &node );
217 while ( ( entry = bed_entry_get( fp, cols ) ) != NULL )
219 node = node_sl_new();
223 list_sl_add_after( &old_node, &node );
234 void bed_entry_put( bed_entry *entry, int cols )
236 /* Martin A. Hansen, September 2008 */
238 /* Output a given number of columns from a BED entry to stdout. */
253 else if ( cols == 4 )
263 else if ( cols == 5 )
266 "%s\t%u\t%u\t%s\t%i\n",
274 else if ( cols == 6 )
277 "%s\t%u\t%u\t%s\t%i\t%c\n",
286 else if ( cols == 12 )
289 "%s\t%u\t%u\t%s\t%i\t%c\t%u\t%u\t%s\t%u\t%s\t%s\n",
306 fprintf( stderr, "ERROR: Wrong number of columns in bed_entry_put: %d\n", cols );
313 void bed_entries_put( list_sl *entries, int cols )
315 /* Martin A. Hansen, September 2008 */
317 /* Output a given number of columns from all BED entries */
318 /* in a singly linked list. */
320 node_sl *node = NULL;
322 for ( node = entries->first; node != NULL; node = node->next ) {
323 bed_entry_put( ( bed_entry * ) node->val, cols );
328 void bed_entries_destroy( list_sl **entries_ppt )
330 /* Martin A. Hansen, September 2008 */
332 /* Free memory for all BED entries and list nodes. */
334 list_sl *entries = *entries_ppt;
335 node_sl *node = NULL;
336 node_sl *next = NULL;
338 next = entries->first;
340 while ( next != NULL )
344 bed_entry_destroy( ( bed_entry * ) node->val );
351 mem_free( &entries );
357 void bed_file_sort_beg( char *path, int cols )
359 /* Martin A. Hansen, September 2008 */
361 /* Given a path to a BED file, read the given number of cols */
362 /* according to the begin position. The result is written to stdout. */
364 list_sl *entries = NULL;
366 entries = bed_entries_get( path, cols );
368 list_sl_sort( &entries, cmp_bed_sort_beg );
370 bed_entries_put( entries, cols );
372 bed_entries_destroy( &entries );
376 void bed_file_sort_strand_beg( char *path, int cols )
378 /* Martin A. Hansen, September 2008 */
380 /* Given a path to a BED file, read the given number of cols */
381 /* according to the strand AND begin position. The result is written to stdout. */
385 list_sl *entries = NULL;
387 entries = bed_entries_get( path, cols );
389 list_sl_sort( &entries, cmp_bed_sort_strand_beg );
391 bed_entries_put( entries, cols );
393 bed_entries_destroy( &entries );
397 void bed_file_sort_chr_beg( char *path, int cols )
399 /* Martin A. Hansen, September 2008 */
401 /* Given a path to a BED file, read the given number of cols */
402 /* according to the chromosome AND begin position. The result is written to stdout. */
404 list_sl *entries = NULL;
406 entries = bed_entries_get( path, cols );
408 list_sl_sort( &entries, cmp_bed_sort_chr_beg );
410 bed_entries_put( entries, cols );
412 bed_entries_destroy( &entries );
416 void bed_file_sort_chr_strand_beg( char *path, int cols )
418 /* Martin A. Hansen, September 2008 */
420 /* Given a path to a BED file, read the given number of cols */
421 /* according to the chromosome AND strand AND begin position. The result is written to stdout. */
425 list_sl *entries = NULL;
427 entries = bed_entries_get( path, cols );
429 list_sl_sort( &entries, cmp_bed_sort_chr_strand_beg );
431 bed_entries_put( entries, cols );
433 bed_entries_destroy( &entries );
437 int cmp_bed_sort_beg( const void *a, const void *b )
439 /* Martin A. Hansen, September 2008 */
441 /* Compare function for sorting a singly linked list of BED entries */
442 /* according to begin position. */
444 node_sl *a_node = *( ( node_sl ** ) a );
445 node_sl *b_node = *( ( node_sl ** ) b );
447 bed_entry *a_entry = ( bed_entry * ) a_node->val;
448 bed_entry *b_entry = ( bed_entry * ) b_node->val;
450 if ( a_entry->chr_beg < b_entry->chr_beg ) {
452 } else if ( a_entry->chr_beg > b_entry->chr_beg ) {
460 int cmp_bed_sort_strand_beg( const void *a, const void *b )
462 /* Martin A. Hansen, September 2008 */
464 /* Compare function for sorting a singly linked list of BED entries */
465 /* according to strand AND begin position. */
467 node_sl *a_node = *( ( node_sl ** ) a );
468 node_sl *b_node = *( ( node_sl ** ) b );
470 bed_entry *a_entry = ( bed_entry * ) a_node->val;
471 bed_entry *b_entry = ( bed_entry * ) b_node->val;
473 if ( a_entry->strand < b_entry->strand ) {
475 } else if ( a_entry->strand > b_entry->strand ) {
477 } else if ( a_entry->chr_beg < b_entry->chr_beg ) {
479 } else if ( a_entry->chr_beg > b_entry->chr_beg ) {
487 int cmp_bed_sort_chr_beg( const void *a, const void *b )
489 /* Martin A. Hansen, September 2008 */
491 /* Compare function for sorting a singly linked list of BED entries */
492 /* according to chromosome name AND begin position. */
494 node_sl *a_node = *( ( node_sl ** ) a );
495 node_sl *b_node = *( ( node_sl ** ) b );
497 bed_entry *a_entry = ( bed_entry * ) a_node->val;
498 bed_entry *b_entry = ( bed_entry * ) b_node->val;
502 diff = strcmp( a_entry->chr, b_entry->chr );
506 } else if ( diff > 0 ) {
508 } else if ( a_entry->chr_beg < b_entry->chr_beg ) {
510 } else if ( a_entry->chr_beg > b_entry->chr_beg ) {
518 int cmp_bed_sort_chr_strand_beg( const void *a, const void *b )
520 /* Martin A. Hansen, September 2008 */
522 /* Compare function for sorting a singly linked list of BED entries */
523 /* according to chromosome name AND strand AND begin position. */
525 node_sl *a_node = *( ( node_sl ** ) a );
526 node_sl *b_node = *( ( node_sl ** ) b );
528 bed_entry *a_entry = ( bed_entry * ) a_node->val;
529 bed_entry *b_entry = ( bed_entry * ) b_node->val;
533 diff = strcmp( a_entry->chr, b_entry->chr );
537 } else if ( diff > 0 ) {
539 } else if ( a_entry->strand < b_entry->strand ) {
541 } else if ( a_entry->strand > b_entry->strand ) {
543 } else if ( a_entry->chr_beg < b_entry->chr_beg ) {
545 } else if ( a_entry->chr_beg > b_entry->chr_beg ) {