Exemplo n.º 1
0
static int check_cds_phases_if_necessary(GtFeatureNode *fn,
                                         GtCDSCheckVisitor *v,
                                         bool second_pass, GtError *err)
{
  GtFeatureNodeIterator *fni;
  GtFeatureNode *node;
  GtArray *cds_features = NULL;
  GtHashmap *multi_features = NULL;
  int had_err = 0;
  gt_error_check(err);
  gt_assert(fn);
  fni = gt_feature_node_iterator_new_direct(fn);
  while ((node = gt_feature_node_iterator_next(fni))) {
    if (gt_feature_node_has_type(node, gt_ft_CDS)) {
      if (gt_feature_node_is_multi(node)) {
        GtArray *features;
        if (!multi_features)
          multi_features = gt_hashmap_new(GT_HASH_DIRECT, NULL,
                                          (GtFree) gt_array_delete);
        if ((features =
                gt_hashmap_get(multi_features,
                             gt_feature_node_get_multi_representative(node)))) {
          gt_array_add(features, node);
        }
        else {
          GtFeatureNode *representative;
          features = gt_array_new(sizeof (GtFeatureNode*));
          representative = gt_feature_node_get_multi_representative(node);
          gt_array_add(features, representative);
          gt_hashmap_add(multi_features, representative, features);
        }
      }
      else {
        if (!cds_features)
          cds_features = gt_array_new(sizeof (GtFeatureNode*));
        gt_array_add(cds_features, node);
      }
    }
  }
  if (cds_features)
    had_err = check_cds_phases(cds_features, v, false, second_pass, err);
  if (!had_err && multi_features)
    had_err = gt_hashmap_foreach(multi_features, check_cds_phases_hm, v, err);
  gt_array_delete(cds_features);
  gt_hashmap_delete(multi_features);
  gt_feature_node_iterator_delete(fni);
  return had_err;
}
Exemplo n.º 2
0
static int compute_statistics(GtFeatureNode *fn, void *data, GtError *err)
{
    GtStatVisitor *sv;
    GT_UNUSED int rval;
    gt_error_check(err);
    gt_assert(data);
    sv = (GtStatVisitor*) data;
    if (gt_feature_node_is_multi(fn) &&
            gt_feature_node_get_multi_representative(fn) == fn) {
        sv->number_of_multi_features++;
    }
    if (sv->used_sources)
        compute_source_statistics(fn, sv->used_sources);
    compute_type_statistics(fn, sv);
    if (sv->exon_number_distribution || sv->cds_length_distribution) {
        sv->exon_number_for_distri = 0;
        sv->cds_length_for_distri = 0;
        rval = gt_feature_node_traverse_direct_children(fn, sv,
                add_exon_or_cds_number,
                err);
        gt_assert(!rval); /* add_exon_or_cds_number() is sane */
        if (sv->exon_number_distribution && sv->exon_number_for_distri) {
            gt_disc_distri_add(sv->exon_number_distribution,
                               sv->exon_number_for_distri);
        }
        if (sv->cds_length_distribution && sv->cds_length_for_distri) {
            gt_disc_distri_add(sv->cds_length_distribution,
                               sv->cds_length_for_distri);
        }
    }
    return 0;
}
Exemplo n.º 3
0
static int store_ids(GtFeatureNode *fn, void *data, GtError *err)
{
  GtGFF3Visitor *gff3_visitor = (GtGFF3Visitor*) data;
  AddIDInfo add_id_info;
  int had_err = 0;
  GtStr *id;

  gt_error_check(err);
  gt_assert(fn && gff3_visitor);

  if (gt_feature_node_has_children(fn) || gt_feature_node_is_multi(fn) ||
      (gff3_visitor->retain_ids && gt_feature_node_get_attribute(fn, "ID"))) {
    if (gt_feature_node_is_multi(fn)) {
      id = gt_hashmap_get(gff3_visitor->feature_node_to_unique_id_str,
                          gt_feature_node_get_multi_representative(fn));
      if (!id) {
        /* the representative does not have its own id yet -> create it */
        if (gff3_visitor->retain_ids) {
          id = make_id_unique(gff3_visitor,
                              gt_feature_node_get_multi_representative(fn));
        }
        else {
          id = create_unique_id(gff3_visitor,
                                gt_feature_node_get_multi_representative(fn));
        }
      }
      /* store id for feature, if the feature was not the representative */
      if (gt_feature_node_get_multi_representative(fn) != fn) {
        gt_hashmap_add(gff3_visitor->feature_node_to_unique_id_str, fn,
                       gt_str_ref(id));
      }
    }
    else {
      if (gff3_visitor->retain_ids)
        id = make_id_unique(gff3_visitor, fn);
      else
        id = create_unique_id(gff3_visitor, fn);
    }
    /* for each child -> store the parent feature in the hash map */
    add_id_info.gt_feature_node_to_id_array =
      gff3_visitor->feature_node_to_id_array,
    add_id_info.id = gt_str_get(id);
    had_err = gt_feature_node_traverse_direct_children(fn, &add_id_info, add_id,
                                                       err);
  }
  return had_err;
}
Exemplo n.º 4
0
static void add_recursive(GtDiagram *d, GtFeatureNode *node,
                          GtFeatureNode* parent,
                          GtFeatureNode *original_node)
{
  NodeInfoElement *ni;
  GtFeatureNode *rep = GT_UNDEF_REPR;
  gt_assert(d && node && original_node);
  if (!parent) return;
  ni = nodeinfo_get(d, node);
  if (gt_feature_node_is_multi(original_node)) {
    rep = gt_feature_node_get_multi_representative(original_node);
  }
    /* end of recursion, insert into target block */
  if (parent == node) {
    GtBlock *block ;
    block = nodeinfo_find_block(ni,
                                gt_feature_node_get_type(node),
                                rep);
    if (!block) {
      block = gt_block_new_from_node(node);
      nodeinfo_add_block(ni,
                         gt_feature_node_get_type(node),
                         rep,
                         block);
    }
    gt_block_insert_element(block, original_node);
    gt_log_log("add %s to target %s", gt_feature_node_get_type(original_node),
                                      gt_block_get_type(block));
  }
  else
  {
    /* not at target type block yet, set up reverse entry and follow */
    NodeInfoElement *parent_ni;
    /* set up reverse entry */
    ni->parent = parent;
    parent_ni = gt_hashmap_get(d->nodeinfo, parent);
    if (parent_ni) {
      gt_log_log("recursion: %s -> %s", gt_feature_node_get_type(node),
                                        gt_feature_node_get_type(parent));
      add_recursive(d, parent, parent_ni->parent, original_node);
    }
  }
}
Exemplo n.º 5
0
static int add_to_rep(GtDiagram *d, GtFeatureNode *node, GtFeatureNode* parent,
                      GtError *err)
{
  GtBlock *block = NULL;
  GtFeatureNode *rep = GT_UNDEF_REPR;
  NodeInfoElement *ni;
  gt_assert(d && node && gt_feature_node_is_multi(node));

  rep = gt_feature_node_get_multi_representative(node);
  gt_log_log("adding %s to representative %p", gt_feature_node_get_type(node),
                                               rep);
  ni = nodeinfo_get(d, rep);

  block = nodeinfo_find_block(ni,
                              gt_feature_node_get_type(node),
                              rep);
  if (!block) {
    block = gt_block_new_from_node(parent);
    gt_block_set_type(block, gt_feature_node_get_type(node));
    /* if parent is a pseudonode, then we have a multiline feature without
       a parent. we must not access the parent in this case! */
    if (gt_feature_node_is_pseudo(parent)) {
      if (assign_block_caption(d, node, NULL, block, err) < 0) {
        gt_block_delete(block);
        return -1;
      }
    } else {
      if (assign_block_caption(d, node, parent, block, err) < 0) {
        gt_block_delete(block);
        return -1;
      }
    }
    nodeinfo_add_block(ni, gt_feature_node_get_type(node),
                       rep, block);
  }
  gt_assert(block);
  gt_block_insert_element(block, node);
  return 0;
}
Exemplo n.º 6
0
static int process_node(GtDiagram *d, GtFeatureNode *node,
                        GtFeatureNode *parent, GtError *err)
{
  GtRange elem_range;
  bool *collapse;
  GtShouldGroupByParent *group;
  const char *feature_type = NULL,
             *parent_gft = NULL;
  double tmp;
  GtStyleQueryStatus rval;
  GtUword max_show_width = GT_UNDEF_UWORD,
                par_max_show_width = GT_UNDEF_UWORD;

  gt_assert(d && node);

  gt_log_log(">> getting '%s'", gt_feature_node_get_type(node));

  /* skip pseudonodes */
  if (gt_feature_node_is_pseudo(node))
    return 0;

  feature_type = gt_feature_node_get_type(node);
  gt_assert(feature_type);

  /* discard elements that do not overlap with visible range */
  elem_range = gt_genome_node_get_range((GtGenomeNode*) node);
  if (!gt_range_overlap(&d->range, &elem_range))
    return 0;

  /* get maximal view widths in nucleotides to show this type */
  rval = gt_style_get_num(d->style, feature_type, "max_show_width", &tmp, NULL,
                          err);
  switch (rval) {
    case GT_STYLE_QUERY_OK:
      max_show_width = tmp;
      break;
    case GT_STYLE_QUERY_ERROR:
      return -1;
      break; /* should never be reached */
    default:
      /* do not change default value */
      break;
  }

  /* for non-root nodes, get maximal view with to show parent */
  if (parent)
  {
    if (!gt_feature_node_is_pseudo(parent))
    {
      parent_gft = gt_feature_node_get_type(parent);
      rval = gt_style_get_num(d->style,
                              parent_gft, "max_show_width",
                              &tmp, NULL, err);
      switch (rval) {
        case GT_STYLE_QUERY_OK:
          par_max_show_width = tmp;
          break;
        case GT_STYLE_QUERY_ERROR:
          return -1;
          break; /* should never be reached */
        default:
          /* do not change default value */
          break;
      }
    } else
      par_max_show_width = GT_UNDEF_UWORD;
  }

  /* check if this type is to be displayed at all */
  if (max_show_width != GT_UNDEF_UWORD &&
      gt_range_length(&d->range) > max_show_width)
  {
    return 0;
  }

  /* disregard parent node if it is configured not to be shown */
  if (parent
        && par_max_show_width != GT_UNDEF_UWORD
        && gt_range_length(&d->range) > par_max_show_width)
  {
    parent = NULL;
  }

  /* check if this is a collapsing type, cache result */
  if ((collapse = (bool*) gt_hashmap_get(d->collapsingtypes,
                                         feature_type)) == NULL)
  {
    collapse = gt_malloc(sizeof (bool));
    *collapse = false;
    if (gt_style_get_bool(d->style, feature_type, "collapse_to_parent",
                           collapse, NULL, err) == GT_STYLE_QUERY_ERROR) {
      gt_free(collapse);
      return -1;
    }
    gt_hashmap_add(d->collapsingtypes, (void*) feature_type, collapse);
  }

  /* check if type should be grouped by parent, cache result */
  if ((group = (GtShouldGroupByParent*) gt_hashmap_get(d->groupedtypes,
                                                       feature_type)) == NULL)
  {
    bool tmp;
    group = gt_malloc(sizeof (GtShouldGroupByParent));
    rval = gt_style_get_bool(d->style, feature_type, "group_by_parent",
                             &tmp, NULL, err);
    switch (rval) {
      case GT_STYLE_QUERY_OK:
        if (tmp)
          *group = GT_GROUP_BY_PARENT;
        else
          *group = GT_DO_NOT_GROUP_BY_PARENT;
        break;
      case GT_STYLE_QUERY_NOT_SET:
        *group = GT_UNDEFINED_GROUPING;
        break;
      case GT_STYLE_QUERY_ERROR:
        gt_free(group);
        return -1;
        break; /* should never be reached */
    }
    gt_hashmap_add(d->groupedtypes, (void*) feature_type, group);
  }

  /* decide where to place this feature: */
  if (*collapse)
  {
    /* user has specified collapsing to parent for this type */
    if (parent && !gt_feature_node_is_pseudo(parent)) {
      /* collapsing child nodes are added to upwards blocks,
         but never collapse into pseudo nodes */
      add_recursive(d, node, parent, node);
    } else {
      /* if no parent or only pseudo-parent, do not collapse */
      if (add_to_current(d, node, parent, err) < 0) {
        return -1;
      }
    }
  }
  else  /* (!*collapse) */
  {
    if (parent) {
      bool do_not_overlap = false;
      do_not_overlap = gt_feature_node_direct_children_do_not_overlap_st(parent,
                                                                         node);
      if (*group == GT_GROUP_BY_PARENT
          || (do_not_overlap && *group == GT_UNDEFINED_GROUPING))
      {
        if (gt_feature_node_is_pseudo(parent)
              && gt_feature_node_is_multi(node))
        {
          if (add_to_rep(d, node, parent, err) < 0) {
            return -1;
          }
        } else if
            (gt_feature_node_number_of_children(parent) > 1)
        {
          if (add_to_parent(d, node, parent, err) < 0) {
            return -1;
          }
        } else {
          if (add_to_current(d, node, parent, err) < 0) {
            return -1;
          }
        }
      } else {
        if (gt_feature_node_is_pseudo(parent)
              && gt_feature_node_is_multi(node))
        {
          if (add_to_rep(d, node, parent, err) < 0) {
            return -1;
          }
        } else {
          if (add_to_current(d, node, parent, err) < 0) {
            return -1;
          }
        }
      }
    } else {
      /* root nodes always get their own block */
      if (add_to_current(d, node, parent, err) < 0) {
        return -1;
      }
    }
  }

  /* we can now assume that this node (or its representative)
     has been processed into the reverse lookup structure */
#ifndef NDEBUG
  if (gt_feature_node_is_multi(node))
  {
    GtFeatureNode *rep;
    rep = gt_feature_node_get_multi_representative((GtFeatureNode*) node);
    gt_assert(gt_hashmap_get(d->nodeinfo, rep));
  }
  else
    gt_assert(gt_hashmap_get(d->nodeinfo, node));
#endif

  return 0;
}