static int m2i_change_target_seqids(GtFeatureNode *fn, const char *target, GtRegionMapping *region_mapping, GtError *err) { GtStrArray *target_ids; GtArray *target_ranges, *target_strands; GtStr *desc, *new_seqid; unsigned long i; int had_err; gt_error_check(err); gt_assert(fn && target && region_mapping); target_ids = gt_str_array_new(); target_ranges = gt_array_new(sizeof (GtRange)); target_strands = gt_array_new(sizeof (GtStrand)); desc = gt_str_new(); new_seqid = gt_str_new(); had_err = gt_gff3_parser_parse_all_target_attributes(target, false, target_ids, target_ranges, target_strands, "", 0, err); for (i = 0; !had_err && i < gt_str_array_size(target_ids); i++) { GtStr *seqid; gt_str_reset(desc); gt_str_reset(new_seqid); seqid = gt_str_array_get_str(target_ids, i); had_err = gt_region_mapping_get_description(region_mapping, desc, seqid, err); if (!had_err) gt_regular_seqid_save(new_seqid, desc); gt_str_array_set(target_ids, i, new_seqid); } if (!had_err) { GtStr *new_target = gt_str_new(); gt_gff3_parser_build_target_str(new_target, target_ids, target_ranges, target_strands); gt_feature_node_set_attribute(fn, GT_GFF_TARGET, gt_str_get(new_target)); gt_str_delete(new_target); } gt_str_delete(new_seqid); gt_str_delete(desc); gt_array_delete(target_strands); gt_array_delete(target_ranges); gt_str_array_delete(target_ids); return had_err; }
static int gt_extract_feature_sequence_generic(GtStr *sequence, GtGenomeNode *gn, const char *type, bool join, GtStr *seqid, GtStrArray *target_ids, unsigned int *out_phase_offset, GtRegionMapping *region_mapping, GtError *err) { GtFeatureNode *fn; GtRange range; unsigned int phase_offset = 0; char *outsequence; const char *target; int had_err = 0; gt_error_check(err); fn = gt_genome_node_cast(gt_feature_node_class(), gn); gt_assert(fn); if (seqid) gt_str_append_str(seqid, gt_genome_node_get_seqid(gn)); if (target_ids && (target = gt_feature_node_get_attribute(fn, GT_GFF_TARGET))) { had_err = gt_gff3_parser_parse_all_target_attributes(target, false, target_ids, NULL, NULL, "", 0, err); } if (!had_err) { if (join) { GtFeatureNodeIterator *fni; GtFeatureNode *child; bool reverse_strand = false, first_child = true, first_child_of_type_seen = false; GtPhase phase = GT_PHASE_UNDEFINED; /* in this case we have to traverse the children */ fni = gt_feature_node_iterator_new_direct(gt_feature_node_cast(gn)); while (!had_err && (child = gt_feature_node_iterator_next(fni))) { if (first_child) { if (target_ids && (target = gt_feature_node_get_attribute(child, GT_GFF_TARGET))) { gt_str_array_reset(target_ids); had_err = gt_gff3_parser_parse_all_target_attributes(target, false, target_ids, NULL, NULL, "", 0, err); } first_child = false; } if (!had_err) { if (extract_join_feature((GtGenomeNode*) child, type, region_mapping, sequence, &reverse_strand, &first_child_of_type_seen, &phase, err)) { had_err = -1; } if (phase != GT_PHASE_UNDEFINED) { phase_offset = (int) phase; } } } gt_feature_node_iterator_delete(fni); gt_assert(phase_offset <= (unsigned int) GT_PHASE_UNDEFINED); if (!had_err && gt_str_length(sequence)) { if (reverse_strand) { had_err = gt_reverse_complement(gt_str_get(sequence), gt_str_length(sequence), err); } } } else if (gt_feature_node_get_type(fn) == type) { GtPhase phase = gt_feature_node_get_phase(fn); gt_assert(!had_err); if (phase != GT_PHASE_UNDEFINED) phase_offset = (unsigned int) phase; /* otherwise we only have to look at this feature */ range = gt_genome_node_get_range(gn); gt_assert(range.start); /* 1-based coordinates */ had_err = gt_region_mapping_get_sequence(region_mapping, &outsequence, gt_genome_node_get_seqid(gn), range.start, range.end, err); if (!had_err) { gt_str_append_cstr_nt(sequence, outsequence, gt_range_length(&range)); gt_free(outsequence); if (gt_feature_node_get_strand(fn) == GT_STRAND_REVERSE) { had_err = gt_reverse_complement(gt_str_get(sequence), gt_str_length(sequence), err); } } } } if (out_phase_offset && phase_offset != GT_PHASE_UNDEFINED) { *out_phase_offset = phase_offset; } return had_err; }