Contents | |
A plug-in can however compute ancillary attributes for both groups and apparitions. For a group, these might include the average position and magnitudes of apparitions belonging to the group. For an apparition, these might include an identifier for the "best" group containing the apparition.
To illustrate each of the steps in writing a plug-in, an example will be developed alongside the explanatory text. Information specific to the example will be presented inside boxes with a light-blue borders.
Example Goals |
For each group :
|
For each apparition, given a list of groups containing the apparition, find the one with average position closest to the apparition, and :
|
The example plug-in will be used to process the 2MASS 6X2 Survey Point Source Table, sixx2@rmt_pebble:pt_src_6x2_01 .
|
% cd /my_wax_install
% mkdir my_wax_plugin
Then, the template files must be copied over :
% cd my_wax_plugin
% cp ../template/* .
The example plug-in is located in the wax_example subdirectory of the WAX installation directory : This directory already contains all necessary files, so the template files do not need to be copied over. |
The first file to edit is retrieve.tbl
, the retrieval column file. This file should be edited to list the names of all the columns which must be retrieved from the input apparition table in order to compute the desired group and apparition attributes.
The example WAX plug-in requires only the position of each apparition for its computations. Since the WAX software automatically retrieves those, the retrieve.tbl file should be left as is, empty. |
The next file to edit is output.tbl
, the output column file. This file should be edited to list the names and Informix types of all the columns corresponding to group attributes. The file essentially dictates the database schema for the group information table.
Here is the output.tbl file for the example WAX plug-in:
|
The grpapp.tbl
file is the grouped apparition column file, and must be edited to list the names and Informix types of all the columns corresponding to apparition attributes. This dictates the database schema for the grouped apparition table.
Here is the grpapp.tbl file for the example WAX plug-in:
|
The final file to edit is gen.sh
. This file is described in detail here, and is essentially a wrapper script which supplies arguments to the source generation helper application. It must be edited to specify the apparition table to use, the name of the plug-in, etc...
Here is the gen.sh shell script, with comments stripped, for the example WAX plug-in :
|
gen.sh
shell script must be run. This will generate several source/script files, documented in detail here. summary.h
) in a C file named summary[_name].c
. This is the file which must be edited to process groups and apparitions. summary[_name].c
file will always begin by including several header files, making a wide variety of library functions available to the plug-in code :
|
These header files, described below
common.h
vector.h
radec_t
(representing a position as a right ascension and declination) and vec3_t
(a vector in ) structures, as well as functions operating on them. These include functions for computing the vector cross and inner products, functions for vector normalization and magnitude, etc... Note that RaDec
is an alias for struct radec_t
, and Vec3
an alias for struct vec3_t
appgroup.h
app_t
(representing an apparition) and group_t
(representing a group) structures. App
is an alias for struct app_t
, and Group
an alias for struct group_t
. Together, these structures contain all standard attributes (both retrieved and computed) for apparitions and groups. The data corresponding to the specified retrieval columns is available via App::info
, which is a pointer to an app_info_t
(AppInfo
) structure that is declared in the generated info[_name].h
header file. The data corresponding to the specified group attributes (output columns) is available from Group::info
, a pointer to a group_info_t
(GroupInfo
) structure, also declared in the info[_name].h
header file. Finally, the data corresponding to the desired apparition attributes (grouped apparition columns) is stored in structures of type grouped_app_info_t
(GroupedAppInfo
).
info[_name].h
putil.h
summary.h
initProcess()
processGroup()
, processSingle()
, and processApparition()
.
freeProcess()
initProcess()
.
processGroup()
processSingle()
processApparition()
summary_example.c
):
/* ---------------------------------------------------------------- Copyright (C) California Institute of Technology. All rights reserved. US Government Sponsorship is acknowledged. ---------------------------------------------------------------- */ /** \file summary_wsdb.c \author This file was generated by the WAX source generation utility \date Wed Sep 8 22:43:44 2004 */
static double sgSinRad; /* Allocates resources for group/apparition processing */ void initProcess(const double rad, const double decmin, const double decmax) { /* Precompute the sine of the grouping radius. */ sgSinRad = sin( gRadPerDeg * (rad / 3600.0) ); /* Load the BSP files for the band being processed. */ loadBsp(decmin, decmax, TRUE); } /* Releases resources allocated for group/apparition processing */ void freeProcess() { /* Nothing to do here */ } /* Processes a group containing at least two apparitions */ int processGroup(Group * const grp, const size_t napp, const App * const * const list) { Vec3 avgpos; RaDec avgloc; GroupInfo * ginfo; const App * const * a; const App * const * alim; const App * app; /* Get a pointer to the GroupInfo structure to store computed attributes in */ ginfo = grp->info; /* Set the initial average position to the zero vector */ avgpos.x = 0; avgpos.y = 0; avgpos.z = 0; /* Loop over all apparitions in the group, adding the vector position of each one to avgpos */ a = list; alim = list + napp; while (a < alim) { app = *a; ++a; vadd2(&avgpos, &(app->pos)); } /* normalize the sum of all the apparition positions, obtaining an average position for the group */ vnormalize(&avgpos); /* convert the average position vector to a right ascension and declination */ vtord(&avgloc, &avgpos); /* store the average position in the GroupInfo structure */ ginfo->ra = avgloc.ra; ginfo->dec = avgloc.dec; ginfo->x = avgpos.x; ginfo->y = avgpos.y; ginfo->z = avgpos.z; /* Compute the HTM index for the groups average position */ getSpatialIndex( &avgpos, &(ginfo->spt_ind) ); /* Compute the minimum and maximum scan coverage for a circular region centered on the groups average position with a radius equal to the group radius. */ overlapRange( &avgloc, &avgpos, sgSinRad, &(ginfo->smin), &(ginfo->smax) ); /* Compute scan coverage for the groups average position */ overlapRange( &avgloc, &avgpos, 0.0, &(ginfo->spos), &(ginfo->spos) ); /* return the GROUP_OK constant to indicate that this group should be inserted into the output tables */ return GROUP_OK; } /* Processes a group containing a single apparition */ int processSingle(Group * const grp, const App * const app) { GroupInfo * ginfo; /* Get a pointer to the GroupInfo structure to store computed attributes in */ ginfo = grp->info; /* The average group position is identical to the apparition position */ ginfo->ra = (app->loc).ra; ginfo->dec = (app->loc).dec; ginfo->x = (app->pos).x; ginfo->y = (app->pos).y; ginfo->z = (app->pos).z; /* Compute the HTM index for the groups average position */ getSpatialIndex( &(app->pos), &(ginfo->spt_ind) ); /* Compute the minimum and maximum scan coverage for a circular region centered on the groups average position with a radius equal to the group radius. */ overlapRange( &(app->loc), &(app->pos), sgSinRad, &(ginfo->smin), &(ginfo->smax) ); /* Compute scan coverage for the groups average position */ overlapRange( &(app->loc), &(app->pos), 0.0, &(ginfo->spos), &(ginfo->spos) ); /* return the GROUP_OK constant to indicate that this group should be inserted into the output tables */ return GROUP_OK; } /* Processes an apparition */ void processApparition(const App * const app, GroupedAppInfo * const gainfo, const size_t ngrp, const Group * const * const list) { double dp, maxdp; const Group * const * g; const Group * const * glim; const Group * grp; const Group * best; const GroupInfo * ginfo; if (ngrp == 1) { /* there is only one choice for the "best" group */ best = *list; } else { /* Set the maximum dot product to -2 (smaller than any dot product of two unit vectors) */ maxdp = -2.0; /* Loop over all groups containing the apparition, finding the one with average position closest to the apparition */ g = list; glim = list + ngrp; while (g < glim) { grp = *g; ++g; ginfo = grp->info; /* compute the dot-product of the apparition position and the group average position */ dp = (app->pos).x * (ginfo->x) + (app->pos).y * (ginfo->y) + (app->pos).z * (ginfo->z); /* if this dot product is greater than the previous maximum dot product, then grp is closer to app than best, so set best to equal grp */ if (dp > maxdp) best = grp; } } /* Now the best group is known. Copy its attributes to gainfo */ gainfo->ngrp = ngrp; gainfo->best_gcntr = best->gcntr; gainfo->best_napp = best->napp; gainfo->best_gtype = best->gtype; gainfo->best_sdet = best->sdet; ginfo = best->info; gainfo->best_smin = ginfo->smin; gainfo->best_smax = ginfo->smax; gainfo->best_spos = ginfo->spos; /* all done */ } /* ---------------------------------------------------------------- */ /* ================================================================ */ |
% make_example.sh
This will produce a WAX executable named wax_example
. overlapRange()
function to compute scan coverage, which internally uses BSP trees. To generate these BSP trees, the bspgen helper application must be run on an ASCII scan corner file :
% cd ../bsp_example
% ../bin/bspgen scanex.4cvecs.nds . -v -p
% cd ../wax_example
This will generate example BSP files in the /my_wax_install/bsp_example
directory. ex_info
(for group attributes), ex_link
(links between groups and apparitions), and ex_gapp
(apparition attributes). To create these tables in the ipac@rmt_gravel
database, run wax_example
as follows :
% wax_example -create "ipac@rmt_gravel" ex_info ex_link -grpapp ex_gapp -v
To drop them, run
% wax_example -drop "ipac@rmt_gravel" ex_info ex_link -grpapp ex_gapp -v
bands.txt
(the band file), run wax_example
as follows:
% wax_example -pri 0-482 bands.txt 2.0 . "sixx2@rmt_pebble:pt_src_6x2_01" \
"ipac@rmt_gravel" ex_info ex_link -v -p -grpapp ex_gapp \
-bsp ../bsp_example
To do the same for the secondary bands (which must always be processed after the primary bands have completed):
% wax_example -sec 0-482 bands.txt 2.0 . "sixx2@rmt_pebble:pt_src_6x2_01" \
"ipac@rmt_gravel" ex_info ex_link -v -p -grpapp ex_gapp \
-bsp ../bsp_example
See this page for in-depth documentation on the command line arguments accepted by WAX executables.