The following example programs demonstrate the use of ntuples in managing a large dataset. The first program creates a set of 100,000 simulated "events", each with 3 associated values @math{(x,y,z)}. These are generated from a gaussian distribution with unit variance, for demonstration purposes, and written to the ntuple file `test.dat'.
#include <config.h> #include <gsl/gsl_ntuple.h> #include <gsl/gsl_rng.h> #include <gsl/gsl_randist.h> struct data { double x; double y; double z; }; int main (void) { const gsl_rng_type * T; gsl_rng * r; struct data ntuple_row; int i; gsl_ntuple *ntuple = gsl_ntuple_create ("test.dat", &ntuple_row, sizeof (ntuple_row)); gsl_rng_env_setup(); T = gsl_rng_default; r = gsl_rng_alloc (T); for (i = 0; i < 10000; i++) { ntuple_row.x = gsl_ran_ugaussian (r); ntuple_row.y = gsl_ran_ugaussian (r); ntuple_row.z = gsl_ran_ugaussian (r); gsl_ntuple_write (ntuple); } gsl_ntuple_close(ntuple); return 0; }
The next program analyses the ntuple data in the file `test.dat'. The analysis procedure is to compute the squared-magnitude of each event, @math{E^2=x^2+y^2+z^2}, and select only those which exceed a lower limit of 1.5. The selected events are then histogrammed using their @math{E^2} values.
#include <config.h> #include <math.h> #include <gsl/gsl_ntuple.h> #include <gsl/gsl_histogram.h> struct data { double x; double y; double z; }; int sel_func (void *ntuple_data, void *params); double val_func (void *ntuple_data, void *params); int main (void) { struct data ntuple_row; int i; gsl_ntuple *ntuple = gsl_ntuple_open ("test.dat", &ntuple_row, sizeof (ntuple_row)); double lower = 1.5; gsl_ntuple_select_fn S; gsl_ntuple_value_fn V; gsl_histogram *h = gsl_histogram_alloc (100); gsl_histogram_set_ranges_uniform(h, 0.0, 10.0); S.function = &sel_func; S.params = &lower; V.function = &val_func; V.params = 0; gsl_ntuple_project (h, ntuple, &V, &S); gsl_histogram_fprintf (stdout, h, "%f", "%f"); gsl_histogram_free (h); gsl_ntuple_close (ntuple); return 0; } int sel_func (void *ntuple_data, void *params) { double x, y, z, E, scale; scale = *(double *) params; x = ((struct data *) ntuple_data)->x; y = ((struct data *) ntuple_data)->y; z = ((struct data *) ntuple_data)->z; E2 = x * x + y * y + z * z; return E2 > scale; } double val_func (void *ntuple_data, void *params) { double x, y, z; x = ((struct data *) ntuple_data)->x; y = ((struct data *) ntuple_data)->y; z = ((struct data *) ntuple_data)->z; return x * x + y * y + z * z; }
The following plot shows the distribution of the selected events. Note the cut-off at the lower bound.
@image{ntuple,4in}