Exemplo n.º 1
0
/* 
 * Recursive compaction routine. Pulls attribute up to the highest node such that
 * all children share the attribute value.
 */
static GhtErr
ght_node_compact_attribute_with_delta(GhtNode *node, 
		const GhtDimension *dim,
		double delta,
		GhtAttribute *compacted_attribute)
{
	int i;

	/* This is an internal node, see if all the children share a value in this dimension */
	if ( node->children && node->children->num_nodes > 0 )
	{
		double minval = DBL_MAX;
		double maxval = -1 * DBL_MAX;
		double totval = 0.0;
		int node_count = 0;

		/* Figure out the range of values for this dimension in child nodes */
		for ( i = 0; i < node->children->num_nodes; i++ )
		{
			GhtAttribute attr;
			GhtErr err;
			err = ght_node_compact_attribute_with_delta(node->children->nodes[i], dim, delta, &attr);
			if ( err == GHT_OK )
			{
				double d;
				GHT_TRY(ght_attribute_get_value(&attr, &d));
				(d < minval) ? (minval = d) : 0;
				(d > maxval) ? (maxval = d) : 0;
				totval += d;
				node_count++;
			}
			else
			{
				continue;
			}
		}

		/* If the range is narrow, and we got values from all our children, compact them */
		if ( (maxval-minval) < delta && node_count == node->children->num_nodes )
		{
			double val = (minval+maxval)/2.0;
			GhtAttribute *myattr;
			for ( i = 0; i < node->children->num_nodes; i++ )
			{
				ght_node_delete_attribute(node->children->nodes[i], dim);
			}
			ght_attribute_new_from_double(dim, val, &myattr);
			memcpy(compacted_attribute, myattr, sizeof(GhtAttribute));
			ght_node_add_attribute(node, myattr);
			return GHT_OK;
		}
		return GHT_ERROR;
	}
	/* This is a leaf node, send the attribute value up to the caller */
	else
	{
		if ( ! node->attributes ) return GHT_ERROR;
		return ght_attribute_get_by_dimension(node->attributes, dim, compacted_attribute);
	}
}
Exemplo n.º 2
0
//return ght_node_calculate_z(tree->root);
GhtErr
ght_node_calculate_z(const GhtNode *node, GhtAttribute *attr, GhtSchema *schema)
{
	static int hash_array_len = GHT_MAX_HASH_LENGTH + 1;
	GhtHash h[hash_array_len];
	GhtAttribute *a;

	// TODO Vérifier l'access au hash de chaque noeud

	/* Make a copy of all the incoming attributes */
	GHT_TRY(ght_attribute_union(node->attributes, attr, &a));

	/* Recurse down to leaf nodes, copying attributes and passing them down */
	if ( node->children && node->children->num_nodes > 0 )
	{
		int i;
		for ( i = 0; i < node->children->num_nodes; i++ )
		{
			GHT_TRY(ght_node_calculate_z(node->children->nodes[i], a, schema ));
		}
		double acc = 0; int k;
		for ( k = 0; k < node->children->num_nodes; k++ )
		{
			acc = node->children->nodes[k]->z_avg + acc;
		}

		GHT_TRY(ght_node_set_z_avg( node, acc / node->children->num_nodes ));

		ght_attribute_free(a);
	}
	/* This is a leaf node, create a new node and add to list */
	else
	{
	    // printf (">> Dans une feuille \n");
	    double valeur;

		// *** DEBUT ***
		// TODO On a besoin d'une fonction plus géneral
		// Pour l'instant on va le tester avec la dimension "elevation" = Z

		GhtDimension *dim;
		GhtAttribute found;

		/*
	    int num_dims;
	    GHT_TRY( ght_schema_get_num_dimensions( schema, &num_dims) );
	    printf ("> num dimension %i \n ", num_dims);
		*/

		//GhtErr ght_schema_get_dimension_by_name(const GhtSchema *schema, const char *name, GhtDimension **dim)
		GHT_TRY( ght_schema_get_dimension_by_name(schema, "Z", &dim) );

		/*
		const char *name_dim ;
		ght_dimension_get_name(dim,&name_dim);
		printf("> Name of dimension: ");
		puts(name_dim);
		*/
		//GhtErr ght_attribute_get_by_dimension(const GhtAttribute *attr, const GhtDimension *dim, GhtAttribute *found)
		GHT_TRY( ght_attribute_get_by_dimension(a, dim, &found) );

		//GhtErr ght_attribute_get_value(const GhtAttribute *attr, double *val)
		GHT_TRY( ght_attribute_get_value(&found, &valeur) );

		//printf ("> VALEUR %g \n ", valeur);

		GHT_TRY( ght_node_set_z_avg(node, valeur) );
		// *** FIN ***

		/*   GhtNode *n;
        GHT_TRY(ght_node_new_from_hash(h, &n));
        GHT_TRY(ght_node_add_attribute(n, a));
        GHT_TRY(ght_nodelist_add_node(nodelist, n));
		 */
		/*
        double d;
        GHT_TRY(ght_attribute_get_value(attr, &d));
        ght_attribute_get_value
		 */
	}
	return GHT_OK;
}
Exemplo n.º 3
0
GhtErr 
ght_node_filter_by_attribute(const GhtNode *node, const GhtFilter *filter, GhtNode **filtered_node)
{
	int i;
	double val;
	int keep = 1;
	GhtAttribute *attr;
	GhtNode *node_copy = NULL;

	/* Our default position is nothing is getting returned */
	*filtered_node = NULL;

	/* No-op on an empty input */
	if ( ! node )
		return GHT_OK;

	attr = node->attributes;
	while ( attr )
	{
		/* Only filter on the attribute of interest */
		if ( attr->dim != filter->dim )
		{
			attr = attr->next;
		}
		else
		{
			GHT_TRY(ght_attribute_get_value(attr, &val));
			switch ( filter->mode )
			{
			case GHT_GREATER_THAN:
				keep = (val > filter->range.min);
				break;
			case GHT_LESS_THAN:
				keep = (val < filter->range.max);
				break;
			case GHT_BETWEEN:
				keep = ((val <= filter->range.max) && (val >= filter->range.min));
				break;
			case GHT_EQUAL:
				keep = (val == filter->range.min);
				break;
			default:
				ght_error("%s: invalid GhtFilterMode (%d)", __func__, filter->mode);
			}
			break;
		}
	}

	/* We found a relevant attribute, and it failed the filter test. */
	/* So, this node (and all it's children) can be excluded! */
	if ( ! keep )
	{
		return GHT_OK;
	}

	/* Also take copies of any children that pass the filter */
	if ( node->children )
	{
		for ( i = 0; i < node->children->num_nodes; i++ )
		{
			GhtNode *child_copy;
			GHT_TRY(ght_node_filter_by_attribute(node->children->nodes[i], filter, &child_copy));
			/* Child survived the filtering */
			if ( child_copy )
			{
				if ( ! node_copy )
				{
					GHT_TRY(ght_node_new(&node_copy));
					GHT_TRY(ght_hash_clone(node->hash, &(node_copy->hash)));
					GHT_TRY(ght_attribute_clone(node->attributes, &(node_copy->attributes)));
				}
				GHT_TRY(ght_node_add_child(node_copy, child_copy));
			}
		}
	}
	else
	{
		GHT_TRY(ght_node_new(&node_copy));
		GHT_TRY(ght_hash_clone(node->hash, &(node_copy->hash)));
		GHT_TRY(ght_attribute_clone(node->attributes, &(node_copy->attributes)));
	}

	/* Done, return the structure */
	*filtered_node = node_copy;
	return GHT_OK;
}
Exemplo n.º 4
0
static void
test_ght_build_tree_with_attributes(void)
{
    int i;
    static const char *simpledata = "test/data/simple-data.tsv";   
    GhtNodeList *nodelist;
    GhtNode *root, *node;
    GhtErr err;
    GhtAttribute attr;
    stringbuffer_t *sb;
    double d;
    
    /* Read a nodelist from a TSV file */
    nodelist = tsv_file_to_node_list(simpledata, simpleschema);
    CU_ASSERT_EQUAL(nodelist->num_nodes, 8);
    
    /* Build node list into a tree */
    root = nodelist->nodes[0];
    for ( i = 1; i < nodelist->num_nodes; i++ )
    {
        err = ght_node_insert_node(root, nodelist->nodes[i], GHT_DUPES_YES);
    }

    /* Write the tree to string:
        c0n0e
          q
            m
              m7
                dvy8yz9  Z=123.4:Intensity=5
                ky667sj  Z=123.4:Intensity=5
              qw00rg068  Z=123.4:Intensity=5
            hekkhnhj3b  Z=123.4:Intensity=5
            6myj870p99  Z=123.3:Intensity=5
            46jybv17y1  Z=123.4:Intensity=5
          r
            980jtyf1dh  Z=123.4:Intensity=5
            2khvpfu13f  Z=123.4:Intensity=5
    */
    sb = stringbuffer_create();
    ght_node_to_string(root, sb, 0);
    // printf("\n%s\n", stringbuffer_getstring(sb));
    stringbuffer_destroy(sb);

    /* Compact the tree on both attributes:
        c0n0e  Intensity=5
          q
            m  Z=123.4
              m7
                dvy8yz9
                ky667sj
              qw00rg068
            hekkhnhj3b  Z=123.4
            6myj870p99  Z=123.3
            46jybv17y1  Z=123.4
          r  Z=123.4
            980jtyf1dh
            2khvpfu13f  
    */
    sb = stringbuffer_create();
    ght_node_compact_attribute(root, simpleschema->dims[2], &attr);
    ght_node_compact_attribute(root, simpleschema->dims[3], &attr);
    ght_node_to_string(root, sb, 0);
    // printf("\n%s\n", stringbuffer_getstring(sb));
    stringbuffer_destroy(sb);
    
    /* Check that Intensity=5 has migrated all the way to the top of the tree */
    CU_ASSERT_STRING_EQUAL(root->attributes->dim->name, "Intensity");
    ght_attribute_get_value(root->attributes, &d);
    CU_ASSERT_DOUBLE_EQUAL(d, 5, 0.00000001);
    
    ght_node_free(root);
    ght_nodelist_free_shallow(nodelist);
}
Exemplo n.º 5
0
PCPATCH_UNCOMPRESSED *
pc_patch_uncompressed_from_ght(const PCPATCH_GHT *paght)
{
#ifndef HAVE_LIBGHT
	pcerror("%s: libght support is not enabled", __func__);
	return NULL;
#else
	int i, npoints;
	PCPATCH_UNCOMPRESSED *patch;
	PCPOINT point;
	const PCSCHEMA *schema;
	GhtNodeListPtr nodelist;
	GhtCoordinate coord;
	GhtNodePtr node;
	GhtTreePtr tree;
	GhtAttributePtr attr;

	/* Build a structured tree from the tree serialization */
	if ( ! paght || ! paght->ght ) return NULL;
	tree = ght_tree_from_pc_patch(paght);
	if ( ! tree ) return NULL;

	/* Convert tree to nodelist */
	ght_nodelist_new(paght->npoints, &nodelist);
	ght_tree_to_nodelist(tree, nodelist);

	/* Allocate uncompressed patch */
	ght_nodelist_get_num_nodes(nodelist, &npoints);
	schema = paght->schema;
	patch = pcalloc(sizeof(PCPATCH_UNCOMPRESSED));
	patch->type = PC_NONE;
	patch->readonly = PC_FALSE;
	patch->schema = schema;
	patch->npoints = npoints;
	patch->bounds = paght->bounds;
	patch->stats = pc_stats_clone(paght->stats);
	patch->maxpoints = npoints;
	patch->datasize = schema->size * npoints;
	patch->data = pcalloc(patch->datasize);

	/* Set up utility point */
	point.schema = schema;
	point.readonly = PC_FALSE;
	point.data = patch->data;

	/* Process each point... */
	for ( i = 0; i < npoints; i++ )
	{
		double val;

		/* Read and set X and Y */
		ght_nodelist_get_node(nodelist, i, &node);
		ght_node_get_coordinate(node, &coord);
		pc_point_set_x(&point, coord.x);
		pc_point_set_y(&point, coord.y);

		/* Read and set all the attributes */
		ght_node_get_attributes(node, &attr);
		while ( attr )
		{
			GhtDimensionPtr dim;
			const char *name;
			ght_attribute_get_value(attr, &val);
			ght_attribute_get_dimension(attr, &dim);
			ght_dimension_get_name(dim, &name);
			pc_point_set_double_by_name(&point, name, val);
			ght_attribute_get_next(attr, &attr);
		}
		point.data += schema->size;
	}

	/* Done w/ nodelist and tree */
	ght_nodelist_free_deep(nodelist);
	// ght_tree_free(tree);

	/* Done */
	return patch;
#endif
}