static int layout_tracks(void *key, void *value, void *data, GT_UNUSED GtError *err) { unsigned long i, max; GtTrack *track; GtLayoutTraverseInfo *lti = (GtLayoutTraverseInfo*) data; GtArray *list = (GtArray*) value; GtStr *gt_track_key; const char *type = key; GtBlock *block; bool split; double tmp; gt_assert(type && list); /* to get a deterministic layout, we sort the GtBlocks for each type */ gt_array_sort_stable(list, blocklist_block_compare); block = *(GtBlock**) gt_array_get(list, 0); gt_track_key = gt_str_new_cstr((char*) key); if (!gt_style_get_bool(lti->layout->style, "format", "split_lines", &split, NULL)) split = true; if (split) if (!gt_style_get_bool(lti->layout->style, type, "split_lines", &split, NULL)) split = true; if (gt_style_get_num(lti->layout->style, type, "max_num_lines", &tmp, NULL)) max = tmp; else max = 50; track = gt_track_new(gt_track_key, max, split, gt_line_breaker_captions_new(lti->layout, lti->layout->width, lti->layout->style)); lti->layout->nof_tracks++; for (i = 0; i < gt_array_size(list); i++) { block = *(GtBlock**) gt_array_get(list, i); gt_track_insert_block(track, block); } gt_hashmap_add(lti->layout->tracks, gt_cstr_dup(gt_str_get(gt_track_key)), track); gt_str_delete(gt_track_key); return 0; }
static int layout_tracks(void *key, void *value, void *data, GtError *err) { unsigned long i, max = 50; GtTrack *track = NULL; GtLayoutTraverseInfo *lti = (GtLayoutTraverseInfo*) data; GtArray *list = (GtArray*) value; GtStr *gt_track_key; GtBlock *block; int had_err = 0; bool split = true; double tmp = 50; gt_assert(list); /* to get a deterministic layout, we sort the GtBlocks for each type */ if (lti->layout->block_ordering_func) { gt_array_sort_stable_with_data(list, blocklist_block_compare, lti->layout); } /* XXX: get first block for track property lookups, this should be reworked to allow arbitrary track keys! */ block = *(GtBlock**) gt_array_get(list, 0); gt_track_key = gt_str_new_cstr((char*) key); /* obtain default settings*/ if (gt_style_get_bool(lti->layout->style, "format", "split_lines", &split, NULL, err) == GT_STYLE_QUERY_ERROR) { had_err = 1; } if (!had_err) { if (gt_style_get_num(lti->layout->style, "format", "max_num_lines", &tmp, NULL, err) == GT_STYLE_QUERY_ERROR) { had_err = 1; } } /* obtain track-specific settings, should be changed to query arbitrary track keys! */ if (!had_err) { if (gt_style_get_bool(lti->layout->style, gt_block_get_type(block), "split_lines", &split, NULL, err) == GT_STYLE_QUERY_ERROR) { had_err = 1; } } if (!had_err) { if (gt_style_get_num(lti->layout->style, gt_block_get_type(block), "max_num_lines", &tmp, NULL, err) == GT_STYLE_QUERY_ERROR) { had_err = 1; } } if (!had_err) { max = (unsigned long) tmp; track = gt_track_new(gt_track_key, max, split, gt_line_breaker_captions_new(lti->layout, lti->layout->width, lti->layout->style)); lti->layout->nof_tracks++; for (i = 0; !had_err && i < gt_array_size(list); i++) { block = *(GtBlock**) gt_array_get(list, i); had_err = gt_track_insert_block(track, block, err); } } if (!had_err) { gt_hashmap_add(lti->layout->tracks, gt_cstr_dup(gt_str_get(gt_track_key)), track); } else { gt_track_delete(track); } gt_str_delete(gt_track_key); return had_err; }
int gt_track_unit_test(GtError *err) { int had_err = 0; GtBlock *b[4]; GtRange r[4]; GtTrack *track; GtGenomeNode *parent[4], *gn[4]; GtStr *title; double height, tmp; GtStyle *sty; unsigned long i; GtLineBreaker *lb; double t_rest = 0, l_rest = 0; gt_error_check(err); title = gt_str_new_cstr("test"); r[0].start=100UL; r[0].end=1000UL; r[1].start=1001UL; r[1].end=1500UL; r[2].start=700UL; r[2].end=1200UL; r[3].start=10UL; r[3].end=200UL; for (i=0; i<4; i++) { parent[i] = gt_feature_node_new(title, gt_ft_gene, r[i].start, r[i].end, GT_STRAND_FORWARD); gn[i] = gt_feature_node_new(title, gt_ft_exon, r[i].start, r[i].end, GT_STRAND_FORWARD); gt_feature_node_add_child((GtFeatureNode*) parent[i], (GtFeatureNode*) gn[i]); gt_feature_node_add_attribute((GtFeatureNode*) parent[i], GT_GFF_NAME, "parent"); gt_feature_node_add_attribute((GtFeatureNode*) gn[i], GT_GFF_NAME, "child"); } for (i=0; i<4; i++) { b[i] = gt_block_new(); gt_block_set_range(b[i], r[i]); gt_block_insert_element(b[i], (GtFeatureNode*) parent[i]); gt_block_insert_element(b[i], (GtFeatureNode*) gn[i]); } lb = gt_line_breaker_bases_new(); sty = gt_style_new(err); if (gt_style_get_num(sty, "format", "track_caption_font_size", &tmp, NULL, err) == GT_STYLE_QUERY_NOT_SET) { tmp = TEXT_SIZE_DEFAULT; } t_rest += tmp; if (gt_style_get_num(sty, "format", "track_caption_space", &tmp, NULL, err) == GT_STYLE_QUERY_NOT_SET) { tmp = CAPTION_BAR_SPACE_DEFAULT; } t_rest += tmp; if (gt_style_get_num(sty, "format", "track_vspace", &tmp, NULL, err) == GT_STYLE_QUERY_NOT_SET) { tmp = TRACK_VSPACE_DEFAULT; } t_rest += tmp; if (gt_style_get_num(sty, "format", "bar_vspace", &l_rest, NULL, err) == GT_STYLE_QUERY_NOT_SET) { l_rest = BAR_VSPACE_DEFAULT; } track = gt_track_new(title, GT_UNDEF_ULONG, true, lb); gt_ensure(had_err, track); gt_ensure(had_err, gt_track_get_title(track) == title); gt_ensure(had_err, gt_track_get_number_of_lines(track) == 0); gt_ensure(had_err, gt_track_get_height(track, &height, sty, err) == 0); gt_ensure(had_err, height == t_rest); gt_ensure(had_err, !gt_error_is_set(err)); gt_ensure(had_err, gt_track_insert_block(track, b[0], err) == 0); gt_ensure(had_err, !gt_error_is_set(err)); gt_ensure(had_err, gt_track_get_number_of_lines(track) == 1); gt_ensure(had_err, gt_track_get_height(track, &height, sty, err) == 0); gt_ensure(had_err, height == t_rest + l_rest + BAR_HEIGHT_DEFAULT); gt_ensure(had_err, !gt_error_is_set(err)); gt_ensure(had_err, gt_track_insert_block(track, b[1], err) == 0); gt_ensure(had_err, !gt_error_is_set(err)); gt_ensure(had_err, gt_track_get_number_of_lines(track) == 1); gt_ensure(had_err, gt_track_get_height(track, &height, sty, err) == 0); gt_ensure(had_err, height == t_rest + l_rest + BAR_HEIGHT_DEFAULT); gt_ensure(had_err, !gt_error_is_set(err)); gt_ensure(had_err, gt_track_insert_block(track, b[2], err) == 0); gt_ensure(had_err, !gt_error_is_set(err)); gt_ensure(had_err, gt_track_get_number_of_lines(track) == 2); gt_ensure(had_err, gt_track_insert_block(track, b[3], err) == 0); gt_ensure(had_err, !gt_error_is_set(err)); gt_ensure(had_err, gt_track_get_number_of_lines(track) == 2); gt_ensure(had_err, gt_track_get_height(track, &height, sty, err) == 0); gt_ensure(had_err, height == t_rest + 2*(l_rest + BAR_HEIGHT_DEFAULT)); gt_ensure(had_err, !gt_error_is_set(err)); gt_style_set_num(sty, "exon", "bar_height", 42); gt_ensure(had_err, gt_track_get_height(track, &height, sty, err) == 0); gt_ensure(had_err, height == t_rest + 2*(l_rest+42)); gt_ensure(had_err, !gt_error_is_set(err)); gt_style_set_num(sty, "gene", "bar_height", 23); gt_ensure(had_err, gt_track_get_height(track, &height, sty, err) == 0); gt_ensure(had_err, height == t_rest + 2*(l_rest+42)); gt_ensure(had_err, !gt_error_is_set(err)); gt_style_unset(sty, "exon", "bar_height"); gt_ensure(had_err, gt_track_get_height(track, &height, sty, err) == 0); gt_ensure(had_err, height == t_rest + 2*(l_rest+23)); gt_ensure(had_err, !gt_error_is_set(err)); gt_style_unset(sty, "gene", "bar_height"); gt_style_set_num(sty, "format", "bar_height", 99); gt_ensure(had_err, gt_track_get_height(track, &height, sty, err) == 0); gt_ensure(had_err, height == t_rest + 2*(l_rest+99)); gt_ensure(had_err, !gt_error_is_set(err)); gt_ensure(had_err, gt_track_get_number_of_discarded_blocks(track) == 0); gt_track_delete(track); gt_str_delete(title); gt_style_delete(sty); for (i=0; i<4; i++) { gt_block_delete(b[i]); gt_genome_node_delete(parent[i]); } return had_err; }