static PyObject* pydat_cell(HDSObject *self, PyObject *args) { PyObject *pobj1, *osub; if(!PyArg_ParseTuple(args, "O:pydat_cell", &osub)) return NULL; // Recover C-pointer passed via Python HDSLoc* loc1 = HDS_retrieve_locator(self); // Attempt to convert the input to something useable PyArrayObject *sub = (PyArrayObject *) PyArray_ContiguousFromAny(osub, NPY_INT, 1, 1); if(!sub) return NULL; // Convert Python-like --> Fortran-like int ndim = PyArray_SIZE(sub); int i, rdim[ndim]; int *sdata = (int*)PyArray_DATA(sub); for(i=0; i<ndim; i++) rdim[i] = sdata[ndim-i-1]+1; HDSLoc* loc2 = NULL; int status = SAI__OK; errBegin(&status); // Finally run the routine datCell(loc1, ndim, rdim, &loc2, &status); if(status != SAI__OK) goto fail; // PyCObject to pass pointer along to other wrappers Py_DECREF(sub); return HDS_create_object(loc2); fail: raiseHDSException(&status); Py_XDECREF(sub); return NULL; };
void atlKy2hd( AstKeyMap *keymap, HDSLoc *loc, int *status ) { /* * Name: * atlKy2hd * Purpose: * Copies values from an AST KeyMap to a primitive HDS object. * Language: * C. * Invocation: * void atlKy2hd( AstKeyMap *keymap, HDSLoc *loc, int *status ) * Description: * This routine copies the contents of an AST KeyMap into a supplied * HDS structure. * Arguments: * keymap * An AST pointer to the KeyMap. * loc * A locator for the HDS object into which the KeyMap contents * are to be copied. A new component is added to the HDS object for * each entry in the KeyMap. * status * The inherited status. * Copyright: * Copyright (C) 2008, 2010, 2012 Science & Technology Facilities Council. * All Rights Reserved. * Licence: * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be * useful,but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street,Fifth Floor, Boston, MA * 02110-1301, USA * Authors: * DSB: David S. Berry * TIMJ: Tim Jenness (JAC, Hawaii) * {enter_new_authors_here} * History: * 29-APR-2008 (DSB): * Original version. * 2010-09-23 (TIMJ): * Fix arrays of strings. * 2010-09-30 (TIMJ): * Make sure that we are using the correct status pointer in AST. * 2010-10-01 (TIMJ): * Sort the keys when writing to HDS structured. * 2010-10-04 (TIMJ): * Support Short ints in keymap * 14-SEP-2012 (DSB): * Moved from kaplibs to atl. * 17-SEP-2012 (DSB): * Add support for undefined values. * {enter_further_changes_here} * Bugs: * {note_any_bugs_here} */ /* Local Varianles: */ AstObject **objArray = NULL; AstObject *obj = NULL; HDSLoc *cloc = NULL; HDSLoc *dloc = NULL; const char *cval = NULL; const char *key; double dval; float fval; int i; int ival; int j; int lenc; int nval; char *oldsortby; int *oldstat = NULL; int size; int type; int veclen; size_t el; void *pntr = NULL; /* Check inherited status */ if( *status != SAI__OK ) return; /* Make sure that we are checking AST status */ oldstat = astWatch( status ); /* If set, save the old SortBy value and then ensure alphabetical sorting. We need to take a copy of the original string since the buffer in which the string is stored may be re-used by subsequent incocations of astGetC. */ if( astTest( keymap, "SortBy" ) ) { int nc = 0; oldsortby = astAppendString( NULL, &nc, astGetC( keymap, "SortBy" ) ); } else { oldsortby = NULL; } astSet( keymap, "SortBy=KeyUp" ); /* Loop round each entry in the KeyMap. */ size = astMapSize( keymap ); for( i = 0; i < size; i++ ) { if (*status != SAI__OK) break; /* Get the key. the data type and the vector length for the current KeyMap entry. */ key = astMapKey( keymap, i ); type = astMapType( keymap, key ); veclen = astMapLength( keymap, key ); /* If the current entry holds one or more nested KeyMaps, then we call this function recursively to add them into a new HDS component. */ if( type == AST__OBJECTTYPE ) { /* First deal with scalar entries holding a single KeyMap. */ if( veclen == 1 ) { datNew( loc, key, "KEYMAP_ENTRY", 0, NULL, status ); datFind( loc, key, &cloc, status ); (void) astMapGet0A( keymap, key, &obj ); if( astIsAKeyMap( obj ) ) { atlKy2hd( (AstKeyMap *) obj, cloc, status ); } else if( *status == SAI__OK ) { *status = SAI__ERROR; errRep( "", "atlKy2hd: Supplied KeyMap contains unusable AST " "objects (programming error).", status ); } datAnnul( &cloc, status ); /* Now deal with vector entries holding multiple KeyMaps. */ } else { datNew( loc, key, "KEYMAP_ENTRY", 1, &veclen, status ); datFind( loc, key, &cloc, status ); objArray = astMalloc( sizeof( AstObject *) * (size_t)veclen ); if( objArray ) { (void) astMapGet1A( keymap, key, veclen, &nval, objArray ); for( j = 1; j <= veclen; j++ ) { datCell( cloc, 1, &j, &dloc, status ); if( astIsAKeyMap( objArray[ j - 1 ] ) ) { atlKy2hd( (AstKeyMap *) objArray[ j - 1 ], dloc, status ); } else if( *status == SAI__OK ) { *status = SAI__ERROR; errRep( "", "atlKy2hd: Supplied KeyMap contains unusable AST " "objects (programming error).", status ); } datAnnul( &dloc, status ); } objArray = astFree( objArray ); } datAnnul( &cloc, status ); } /* For primitive types... */ } else if( type == AST__INTTYPE ) { if( veclen == 1 ) { datNew0I( loc, key, status ); datFind( loc, key, &cloc, status ); (void) astMapGet0I( keymap, key, &ival ); datPut0I( cloc, ival, status ); datAnnul( &cloc, status ); } else { datNew1I( loc, key, veclen, status ); datFind( loc, key, &cloc, status ); datMapV( cloc, "_INTEGER", "WRITE", &pntr, &el, status ); (void) astMapGet1I( keymap, key, veclen, &nval, (int *) pntr ); datUnmap( cloc, status ); datAnnul( &cloc, status ); } } else if( type == AST__SINTTYPE ) { short sval = 0; if( veclen == 1 ) { datNew0W( loc, key, status ); datFind( loc, key, &cloc, status ); (void) astMapGet0S( keymap, key, &sval ); datPut0W( cloc, sval, status ); datAnnul( &cloc, status ); } else { datNew1W( loc, key, veclen, status ); datFind( loc, key, &cloc, status ); datMapV( cloc, "_WORD", "WRITE", &pntr, &el, status ); (void) astMapGet1S( keymap, key, veclen, &nval, (short *) pntr ); datUnmap( cloc, status ); datAnnul( &cloc, status ); } } else if( type == AST__DOUBLETYPE ) { if( veclen == 1 ) { datNew0D( loc, key, status ); datFind( loc, key, &cloc, status ); (void) astMapGet0D( keymap, key, &dval ); datPut0D( cloc, dval, status ); datAnnul( &cloc, status ); } else { datNew1D( loc, key, veclen, status ); datFind( loc, key, &cloc, status ); datMapV( cloc, "_DOUBLE", "WRITE", &pntr, &el, status ); (void) astMapGet1D( keymap, key, veclen, &nval, (double *) pntr ); datUnmap( cloc, status ); datAnnul( &cloc, status ); } } else if( type == AST__FLOATTYPE ) { if( veclen == 1 ) { datNew0R( loc, key, status ); datFind( loc, key, &cloc, status ); (void) astMapGet0F( keymap, key, &fval ); datPut0R( cloc, fval, status ); datAnnul( &cloc, status ); } else { datNew1R( loc, key, veclen, status ); datFind( loc, key, &cloc, status ); datMapV( cloc, "_REAL", "WRITE", &pntr, &el, status ); (void) astMapGet1F( keymap, key, veclen, &nval, (float *) pntr ); datUnmap( cloc, status ); datAnnul( &cloc, status ); } } else if( type == AST__STRINGTYPE ) { lenc = astMapLenC( keymap, key ); if( veclen == 1 ) { datNew0C( loc, key, lenc, status ); datFind( loc, key, &cloc, status ); (void) astMapGet0C( keymap, key, &cval ); datPut0C( cloc, cval, status ); datAnnul( &cloc, status ); } else { datNew1C( loc, key, lenc, veclen, status ); datFind( loc, key, &cloc, status ); datMapV( cloc, "_CHAR", "WRITE", &pntr, &el, status ); (void) atlMapGet1C( keymap, key, veclen*lenc, lenc, &nval, (char *) pntr, status ); datUnmap( cloc, status ); datAnnul( &cloc, status ); } /* KeyMap "UNDEF" values are always scalar and have no corresponding HDS data type. So arbitrarily use an "_INTEGER" primitive with no defined value to represent a KeyMap UNDEF value. */ } else if( type == AST__UNDEFTYPE ) { datNew0L( loc, key, status ); /* Unknown or unsupported data types. */ } else if( *status == SAI__OK ) { *status = SAI__ERROR; msgSeti( "T", type ); errRep( "", "atlKy2hd: Supplied KeyMap contains entries with " "unusable data type (^T) (programming error).", status ); } } /* If it was originally set, re-instate the old SortBy value in the KeyMap, then free the memory. Otherwise, clear the SortBy attribute. */ if( oldsortby ) { astSetC( keymap, "SortBy", oldsortby ); oldsortby = astFree( oldsortby ); } else { astClear( keymap, "SortBy" ); } /* Reset AST status */ astWatch( oldstat ); }
void cupidGCNdfClump( HDSLoc **obj, double sum, double *par, double rms, int ndim, int *lbox, int *ubox, int list_size, double *mlist, int *plist, int *lbnd, int iclump, int *dax, AstKeyMap *extra, int bad, int *status ){ /* *+ * Name: * cupidGCNdfClump * Purpose: * Create an NDF containing a description of a single clump. * Language: * Starlink C * Synopsis: * void cupidGCNdfClump( HDSLoc **obj, double sum, double *par, double rms, * int ndim, int *lbox, int *ubox, int list_size, * double *mlist, int *plist, int *lbnd, int iclump, * int *dax, AstKeyMap *extra, int bad, * int *status ) * Description: * This function creates a temporary NDF and stores the integrated * intensity of the clump in its Data component. The bounds of the NDF * will be the smallest possible which still encompass the clump. In * addition, if required it will create a Cupid extension in the NDF * containing * * - The parameters of a Gaussian approximation to the clump (if supplied). * - Any supplied extra information. * Parameters: * obj * A pointer to a locator for an HDS array of NDF objects. The array * will be extended to accomodate the new NDF. If NULL is supplied a * new temporary HDS object is created, and the locator stored at the * given address. * sum * The integrated intensity in the clump. Note, unlike par[0] and * par[1], this value should not be normalised to the RMS noise. * par * Pointer to an array holding the parameters of a Gaussian * approximation to the clump, or NULL. How many of these are used * depends on the value of "ndim": if "ndim" is 1 only elements 0 to * 3 are used, if "ndim" is 2 only elements 0 to 6 are used, if "ndim" * is 3 all elements are used. All axis values are represented in GRID * pixels: * * par[0]: Peak intensity of clump (in units of the RMS noise level). * par[1]: Constant intensity offset (in units of the RMS noise level). * par[2]: Model centre on internal axis 0 (in pixels) * par[3]: Intrinsic FWHM on axis 0 (in pixels) * par[4]: Model centre on internal axis 1 (in pixels) * par[5]: Intrinsic FWHM on axis 1 (in pixels) * par[6]: Spatial orientation angle (in radians, positive from * +ve GRID1 axis to +ve GRID2 axis). * par[7]: Model centre on internal axis 3 (velocity) (in pixels) * par[8]: Intrinsic FWHM on velocity axis (in pixels) * par[9]: Axis 0 of internal velocity gradient vector (in velocity * pixels per spatial pixel). * par[10]: Axis 1 of internal velocity gradient vector (in * velocity pixels per spatial pixel). * rms * The RMS noise level. * ndim * The number of pixel axes in the array. * lbox * The lower grid index bounds of the area containing the clump * (using internal axis numbering). * ubox * The upper grid index bounds of the area containing the clump * (using internal axis numbering). * list_size * The number of values supplied in mlist and plist. * mlist * An array of "list_size" elements containing the clump values at * each pixel. * plist * An array of "ndim*list_size" elements in which each group of * "ndim" adjacent values forms the grid indices of the corresponding * value in "mlist". This uses external axis ordering. * lbnd * Pointer to array holding the pixel indices of the first pixel in * the user-supplied NDF (using external axis numbering). * iclump * The index of the current clump. * dax * Array holding external axis number indexed by internal axis number. * extra * An AstKeyMap holding extra diagnositic information to add to the * clump structure. * bad * Set the Unit component of the NDF to "BAD". This is used as a * flag to indicate that the clump touches too many areas of bad * pixels. * status * Pointer to the inherited status value. * Copyright: * Copyright (C) 2009 Science and Technology Facilities Council. * Copyright (C) 2005,2007 Particle Physics & Astronomy Research Council. * All Rights Reserved. * Licence: * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street,Fifth Floor, Boston, MA * 02110-1301, USA * Authors: * DSB: David S. Berry * TIMJ: Tim Jenness (JAC, Hawaii) * {enter_new_authors_here} * History: * 10-NOV-2005 (DSB): * Original version. * 5-MAR-2007 (DSB): * Initiaslise "exloc" locator to NULL before calling datFind. * 13-JAN-2009 (TIMJ): * DO NOT CAST int* to size_t* since that is not going to work for long. * 26-JAN-2011 (DSB): * Ensure the "m" pointer is incremented even if the currrent model pixel * is off the edge of the NDF. Previously, this bug caused a stripey * "aliasing" type effect if the supplied model data extends outside the * bounds of the NDF. * 25-MAY-2017 (DSB): * Switch off group history and provenance recording during this * function. This is because it can inflate the time taken to run * findclumps enormously if there are many thousands of clumps. * {enter_further_changes_here} * Bugs: * {note_any_bugs_here} *- */ /* Local Variables: */ const char *cen[] = { "CENTRE1", "CENTRE2", "CENTRE3" }; const char *fwhm[] = { "FWHM1", "FWHM2", "FWHM3" }; const char *vgrad[] = { "VGRAD1", "VGRAD2", "VGRAD3" }; HDSLoc *cloc; /* Cell locator */ HDSLoc *dloc; /* Component locator */ HDSLoc *xloc; /* Extension locator */ HDSLoc *exloc; /* Locator for structure holding extra info */ const char *key; /* KeyMap key name */ double *ipd; /* Pointer to Data array */ double *m; /* Pointer to next data value */ double dval; /* Double value to store */ int *p; /* Pointer to next grid axis value */ int el; /* Number of elements mapped */ int elb[ 3 ]; /* The lower NDF limit on each external axis */ int elbox[ 3 ]; /* The lower box limit on each external axis */ int estep[ 3 ]; /* The step size on each external axis */ int eub[ 3 ]; /* The upper NDF limit on each external axis */ int eubox[ 3 ]; /* The upper box limit on each external axis */ int i; /* Point index */ int indf; /* NDF identifier */ int iv; /* 1D vector index for current data value */ int j; /* Axis index */ int lb[ 3 ]; /* Lower pixel index bounds of NDF */ int nex; /* No. of extra items of information */ int ok; /* Pixel within clump NDF? */ int old_ghstate; /* Non-zero if group history recording is switched on */ int old_pvstate; /* Non-zero if provenance recording is switched on */ int place; /* NDF place holder */ int pv; /* Pixel offset */ size_t oldsize; /* Size of original NDF */ hdsdim size[1]; /* No of elements in NDF array */ int step[ 3 ]; /* The step size on each internal axis */ int ub[ 3 ]; /* Upper pixel index bounds of NDF */ /* Abort if an error has already occurred. */ if( *status != SAI__OK ) return; /* If no array was supplied create one of length 1. */ if( !(*obj) ) { size[0] = 1; datTemp( "NDF", 1, size, obj, status ); /* Otherwise, get the number of NDFs already in the supplied array of NDFs, and increase it by 1. */ } else { datSize( *obj, &oldsize, status ); size[0] = oldsize + 1; datAlter( *obj, 1, size, status ); } /* Get a locator for the new cell. */ cloc = NULL; datCell( *obj, 1, size, &cloc, status ); /* Begin an NDF context */ ndfBegin(); /* Temporaily switch off group history and provenance recording since there can be thousands of clump NDFs. */ ndgHltgh( 0, &old_ghstate, status ); ndgHltpv( 0, &old_pvstate, status ); /* Find the pixel index bounds of the NDF and the step between adjacent pixels on each axis. */ lb[ 0 ] = lbox[ 0 ] - 1 + lbnd[ dax[ 0 ] ]; ub[ 0 ] = ubox[ 0 ] - 1 + lbnd[ dax[ 0 ] ]; step[ 0 ] = 1; for( i = 1; i < ndim; i++ ) { lb[ i ] = lbox[ i ] - 1 + lbnd[ dax[ i ] ]; ub[ i ] = ubox[ i ] - 1 + lbnd[ dax[ i ] ]; step[ i ] = ( ub[ i - 1 ] - lb[ i - 1 ] + 1 )*step[ i - 1 ]; } /* Convert lbox, lb, ub and step from internal axis numbering to external axis numbering. */ for( i = 0; i < ndim; i++ ) { elbox[ dax[ i ] ] = lbox[ i ]; eubox[ dax[ i ] ] = ubox[ i ]; elb[ dax[ i ] ] = lb[ i ]; eub[ dax[ i ] ] = ub[ i ]; estep[ dax[ i ] ] = step[ i ]; } /* Create a place holder for the new NDF within the new cell. The NDF will be copied to its final resting place before the program exits. */ ndfPlace( cloc, " ", &place, status ); /* Create the NDF to receive the clump values. The size of this NDF is the minimum needed to contain the clump. */ ndfNew( "_DOUBLE", ndim, elb, eub, &place, &indf, status ); /* Map the NDFs Data array, filling it with bad values. */ ndfMap( indf, "DATA", "_DOUBLE", "WRITE/BAD", (void *) &ipd, &el, status ); if( ipd ) { /* Store every supplied model value in the NDF data array. */ m = mlist; p = plist; for( i = 0; i < list_size; i++,m++ ) { /* Find the 1D vector index into the NDF data array corresponding to the grid indices (within the user supplied NDF) of the current point.*/ pv = *(p++); iv = pv - elbox[ 0 ]; ok = ( pv >= elbox[ 0 ] && pv <= eubox[ 0 ] ); for( j = 1; j < ndim; j++ ) { pv = *(p++); iv += ( pv - elbox[ j ] )*estep[ j ]; if( pv < elbox[ j ] || pv > eubox[ j ] ) ok = 0; } /* Store the value. */ if( ok ) ipd[ iv ] = *m; } /* Unmap the NDFs Data array. */ ndfUnmap( indf, "DATA", status ); } /* If required, create a Cupid extension in the NDF. */ if( par || extra ) { xloc = NULL; ndfXnew( indf, "CUPID", "CUPID_EXT", 0, NULL, &xloc, status ); /* First do Gaussian parameters. */ if( par ) { /* Store the integrated intensity in the clump. */ dloc = NULL; datNew( xloc, "SUM", "_DOUBLE", 0, NULL, status ); datFind( xloc, "SUM", &dloc, status ); datPutD( dloc, 0, NULL, &sum, status ); datAnnul( &dloc, status ); /* Store the parameters of the Gaussian approximation, taking out the normalisation by the RMS noise level.*/ datNew( xloc, "PEAK", "_DOUBLE", 0, NULL, status ); datFind( xloc, "PEAK", &dloc, status ); dval = rms*par[ 0 ]; datPutD( dloc, 0, NULL, &dval, status ); datAnnul( &dloc, status ); datNew( xloc, "OFFSET", "_DOUBLE", 0, NULL, status ); datFind( xloc, "OFFSET", &dloc, status ); dval = rms*par[ 1 ]; datPutD( dloc, 0, NULL, &dval, status ); datAnnul( &dloc, status ); datNew( xloc, cen[ dax[ 0 ] ], "_DOUBLE", 0, NULL, status ); datFind( xloc, cen[ dax[ 0 ] ], &dloc, status ); dval = par[ 2 ] + lbnd[ dax[ 0 ] ] - 1.5; datPutD( dloc, 0, NULL, &dval, status ); datAnnul( &dloc, status ); datNew( xloc, fwhm[ dax[ 0 ] ], "_DOUBLE", 0, NULL, status ); datFind( xloc, fwhm[ dax[ 0 ] ], &dloc, status ); datPutD( dloc, 0, NULL, par + 3, status ); datAnnul( &dloc, status ); if( ndim > 1 ) { datNew( xloc, cen[ dax[ 1 ] ], "_DOUBLE", 0, NULL, status ); datFind( xloc, cen[ dax[ 1 ] ], &dloc, status ); dval = par[ 4 ] + lbnd[ dax[ 1 ] ] - 1.5; datPutD( dloc, 0, NULL, &dval, status ); datAnnul( &dloc, status ); datNew( xloc, fwhm[ dax[ 1 ] ], "_DOUBLE", 0, NULL, status ); datFind( xloc, fwhm[ dax[ 1 ] ], &dloc, status ); datPutD( dloc, 0, NULL, par + 5, status ); datAnnul( &dloc, status ); datNew( xloc, "ANGLE", "_DOUBLE", 0, NULL, status ); datFind( xloc, "ANGLE", &dloc, status ); dval = par[ 6 ]*AST__DR2D; datPutD( dloc, 0, NULL, &dval, status ); datAnnul( &dloc, status ); if( ndim > 2 ) { datNew( xloc, cen[ dax[ 2 ] ], "_DOUBLE", 0, NULL, status ); datFind( xloc, cen[ dax[ 2 ] ], &dloc, status ); dval = par[ 7 ] + lbnd[ dax[ 2 ] ] - 1.5; datPutD( dloc, 0, NULL, &dval, status ); datAnnul( &dloc, status ); datNew( xloc, fwhm[ dax[ 2 ] ], "_DOUBLE", 0, NULL, status ); datFind( xloc, fwhm[ dax[ 2 ] ], &dloc, status ); datPutD( dloc, 0, NULL, par + 8, status ); datAnnul( &dloc, status ); datNew( xloc, vgrad[ dax[ 0 ] ], "_DOUBLE", 0, NULL, status ); datFind( xloc, vgrad[ dax[ 0 ] ], &dloc, status ); datPutD( dloc, 0, NULL, par + 9, status ); datAnnul( &dloc, status ); datNew( xloc, vgrad[ dax[ 1 ] ], "_DOUBLE", 0, NULL, status ); datFind( xloc, vgrad[ dax[ 1 ] ], &dloc, status ); datPutD( dloc, 0, NULL, par + 10, status ); datAnnul( &dloc, status ); } } } /* Now store any extra diagnostic information. */ if( extra ) { datNew( xloc, "EXTRA", "EXTRA", 0, NULL, status ); exloc = NULL; datFind( xloc, "EXTRA", &exloc, status ); nex = astMapSize( extra ); for( i = 0; i < nex; i++ ) { key = astMapKey( extra, i ); if( astMapGet0D( extra, key, &dval ) ) { datNew( exloc, key, "_DOUBLE", 0, NULL, status ); datFind( exloc, key, &dloc, status ); datPutD( dloc, 0, NULL, &dval, status ); datAnnul( &dloc, status ); } } datAnnul( &exloc, status ); } /* Release the extension locator. */ datAnnul( &xloc, status ); } /* If required set the Unit component to "BAD". */ if( bad ) ndfCput( "BAD", indf, "Unit", status ); /* Switch group history and provenance recording back to their original states. */ ndgHltgh( old_ghstate, NULL, status ); ndgHltpv( old_pvstate, NULL, status ); /* End the NDF context */ ndfEnd( status ); /* Release the cell locator. */ datAnnul( &cloc, status ); }
void cupidStoreConfig( HDSLoc *loc, AstKeyMap *config, int *status ){ /* *+ * Name: * cupidStoreConfig * Purpose: * Store the configuraton used by CLUMPS in the given CUPID extension. * Language: * Starlink C * Synopsis: * void cupidStoreConfig( HDSLoc *loc, AstKeyMap *config, int *status ) * Description: * This function extracts each keyword/value pair from the given * configuration keymap, and stores them in the CUPID extension. * Parameters: * loc * HDS locator for the CUPID extension. * config * An AST KeyMap holding the configuration parameters. * status * Pointer to the inherited status value. * Copyright: * Copyright (C) 2005 Particle Physics & Astronomy Research Council. * All Rights Reserved. * Licence: * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street,Fifth Floor, Boston, MA * 02110-1301, USA * Authors: * DSB: David S. Berry * TIMJ: Tim Jenness (JAC, Hawaii) * {enter_new_authors_here} * History: * 9-NOV-2005 (DSB): * Original version. * 15-JUL-2008 (TIMJ): * Tweak to GRP C API. * {enter_further_changes_here} * Bugs: * {note_any_bugs_here} *- */ /* Local Variables: */ Grp *grp; /* Pointer to group */ HDSLoc *aloc; /* HDS locator for entire CONFIG array */ HDSLoc *cloc; /* HDS locator for single cell of ONFIG array */ char name[ GRP__SZNAM + 1 ];/* Value extracted from GRP group */ char *pname; /* Pointer to pass to grpGet */ int el; /* Index of element to store */ int i; /* Index of next entry in group */ int n; /* Number of entries in group */ int nc; /* Number of characters in group entry */ int ncmax; /* Max number of characters in any group entry */ int subs[ 1 ]; /* Array containing required cell index */ int there; /* Does component exist?*/ /* Abort if an error has already occurred. */ if( *status != SAI__OK ) return; /* Initialise all HDS locator pointers to NULL since HDS now objects if it receives an uninitialised pointer. */ aloc = NULL; cloc = NULL; /* Create a GRP group containing the required text. */ grp = NULL; kpg1Kygrp( config, &grp, status ); /* Get the number of values in the group. Pass on if it is zero. */ n = grpGrpsz( grp, status ); if( n ) { /* We need to pass a pointer to the "name" variable to grpGet */ pname = name; /* Scan the group to find the length of the longest value. */ ncmax = 0; for( i = 1; i <= n; i++ ) { grpGet( grp, i, 1, &pname, GRP__SZNAM + 1, status ); nc = astChrLen( name ); if( nc > ncmax ) ncmax = nc; } /* Create a suitable array of character strings in the CUPID extension, and get a locator for the whole array. */ datThere( loc, "CONFIG", &there, status ); if( there ) datErase( loc, "CONFIG", status ); datNewC( loc, "CONFIG", ncmax + 1, 1, &n, status ); datFind( loc, "CONFIG", &aloc, status ); /* Store each list item in the new array. */ el = 1; for( i = 0; i < n; i++ ) { subs[ 0 ]= i + 1; cloc = NULL; datCell( aloc, 1, subs, &cloc, status ); grpGet( grp, subs[ 0 ], 1, &pname, GRP__SZNAM + 1, status ); nc = astChrLen( pname ); datPutC( cloc, 0, &el, pname, astChrLen( name ), status ); datAnnul( &cloc, status ); } /* Free resources. */ datAnnul( &aloc, status ); } /* Delete the group */ grpDelet( &grp, status ); }
void clumpinfo( int *status ) { /* *+ * Name: * CLUMPINFO * Purpose: * Obtain information about one or more previously identified clumps. * Language: * C * Type of Module: * ADAM A-task * Description: * This application returns various items of information about a * single clump, or a collection of clumps, previously identified * using FINDCLUMPS or EXTRACTCLUMPS. * Usage: * clumpinfo ndf clumps quiet * ADAM Parameters: * CLUMPS = LITERAL (Read) * Specifies the indices of the clumps to be included in the * returned information. It can take any of the following values: * * - "ALL" or "*" -- All clumps. * * - "xx,yy,zz" -- A list of clump indices. * * - "xx:yy" -- Clump indices between xx and yy inclusively. When * xx is omitted the range begins from one; when yy is omitted the * range ends with the final clump index. * * - Any reasonable combination of above values separated by * commas. * FLBND( ) = _DOUBLE (Write) * The lower bounds of the bounding box enclosing the selected * clumps in the current WCS Frame of the input NDF. Celestial axis * values are always in units of radians, but spectral axis units * will be in the spectral units used by the current WCS Frame. * FUBND( ) = _DOUBLE (Write) * The upper bounds of the bounding box enclosing the selected * clumps. See parameter FLBND for more details. * LBOUND( ) = _INTEGER (Write) * The lower pixel bounds of bounding box enclosing the selected * clumps. * NCLUMPS = _INTEGER (Write) * The total number of clumps descrriptions stored within the supplied * NDF. * NDF = NDF (Read) * The NDF defining the previously identified clumps. This * should contain a CUPID extension describing all the identified * clumps, in the format produced by FINDCLUMPS or EXTRACTCLUMPS. * QUIET = _LOGICAL (Read) * If TRUE, then no information is written out to the screen, * although the output parameters are still assigned values. [FALSE] * UBOUND( ) = _INTEGER (Write) * The upper pixel bounds of bounding box enclosing the selected * clumps. * Notes: * - It is hoped to extend the range of information reported by this * application as new requirements arise. * Synopsis: * void clumpinfo( int *status ); * Copyright: * Copyright (C) 2007 Particle Physics & Astronomy Research Council. * All Rights Reserved. * Licence: * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street,Fifth Floor, Boston, MA * 02110-1301, USA * Authors: * DSB: David S. Berry * {enter_new_authors_here} * History: * 22-MAR-2007 (DSB): * Original version. * {enter_further_changes_here} * Bugs: * {note_any_bugs_here} *- */ /* Local Variables: */ AstFrame *cfrm; /* Pointer to current WCS Frame */ AstMapping *cmap; /* Pointer to PIXEL->current Frame Mapping */ CupidClumpInfo info; /* Structure holding returned information */ Grp *grp = NULL; /* GRP group holding input NDF name */ HDSLoc *aloc = NULL; /* Locator for CLUMPS array in CUPID extension */ HDSLoc *cloc = NULL; /* Locator for a single CLUMP structure */ HDSLoc *xloc = NULL; /* Locator for CUPID extension */ char *p; /* Pointer into tmpstr string */ char tmpstr[ 100 ]; /* Buffer for temporary strings */ const char *dom; /* Pointer to axis Domain name */ double flbnd[ NDF__MXDIM ]; /* Lower bounds of WCS bounding box */ double fubnd[ NDF__MXDIM ]; /* Upper bounds of WCS bounding box */ double plbnd[ NDF__MXDIM ]; /* Lower bounds of PIXEL bounding box */ double pubnd[ NDF__MXDIM ]; /* Upper bounds of PIXEL bounding box */ int *clump_flags = NULL; /* Flags indicating if each clump is to be used */ int *clump_indices = NULL;/* List of indices of clumps to be used */ int i; /* Loop count */ int iclump; /* One-based clump index */ int indf; /* NDF identifier for input NDF */ int ipix; /* Index of PIXEL Frame */ size_t nclumps; /* No. of clump descriptions within the supplied NDF */ int nuse; /* Number of clumps to be used */ int primary; /* Value for locator primary flag */ int quiet; /* Supress screen output? */ size_t size; /* Number of values in group "*grp" */ int there; /* Does the enquired object exist? */ /* Abort if an error has already occurred. */ if( *status != SAI__OK ) return; /* Begin an AST context */ astBegin; /* Start an NDF context */ ndfBegin(); /* Obtain the input NDF and get a locator for the array of clump descriptions within it. ----------------------------------------------------------------- */ /* Get an identifier for the input NDF. We use NDG (via kpg1_Rgndf) instead of calling ndfAssoc directly since NDF/HDS has problems with file names containing spaces, which NDG does not have. */ kpg1Rgndf( "NDF", 1, 1, "", &grp, &size, status ); ndgNdfas( grp, 1, "READ", &indf, status ); grpDelet( &grp, status ); /* Check the NDF has a suitable CUPID extension containing an array of clump cut-outs. Get an HDS locator for the array. */ ndfXstat( indf, "CUPID", &there, status ); if( !there ) { if( *status == SAI__OK ) { *status = SAI__ERROR; ndfMsg( "NDF", indf ); errRep( "", "The NDF \"^NDF\" does not contain a CUPID extension " "such as created by FINDCLUMPS or EXTRACTCLUMPS.", status ); } } else { ndfXloc( indf, "CUPID", "READ", &xloc, status ); datThere( xloc, "CLUMPS", &there, status ); if( !there ) { if( *status == SAI__OK ) { *status = SAI__ERROR; ndfMsg( "NDF", indf ); errRep( "", "The CUPID extension within NDF \"^NDF\" does not " "contain an array of clumps such as created by " "FINDCLUMPS or EXTRACTCLUMPS.", status ); } } else { datFind( xloc, "CLUMPS", &aloc, status ); primary = 1; datPrmry( 1, &aloc, &primary, status ); } datAnnul( &xloc, status ); } /* Abort if we have no clumps array locator, or if an error occurred. */ if( !aloc || *status != SAI__OK ) goto L999; /* Calculate the required clump information, and store it in the "info" structure. ----------------------------------------------------------------- */ /* Indicate that the structure holding the returned information has not yet been initialised. */ info.init = 0; /* Get the WCS FrameSet from the input NDF, and store a pointer to it in the "info" structure. */ kpg1Gtwcs( indf, &(info.iwcs), status ); /* Get the number of clumps defined within the input NDF. */ datSize( aloc, &nclumps, status ); /* Get the list of clump indices to iclude in the returned information. */ clump_flags = astMalloc( sizeof( int )*nclumps ); clump_indices = astMalloc( sizeof( int )*nclumps ); kpg1Gilst( 1, (int) nclumps, (int) nclumps, "CLUMPS", clump_flags, clump_indices, &nuse, status ); /* Loop round all clumps that are to be used. */ for( i = 0; i < nuse && *status == SAI__OK; i++ ) { iclump = clump_indices[ i ]; /* Get a locator for this clump. */ datCell( aloc, 1, &iclump, &cloc, status ); /* Update the returned information to include this clump. */ cupidClumpInfo1( cloc, &info, status ); /* Annul the clump structure locator. */ datAnnul( &cloc, status ); } /* Write out the information to the screen and to appropriate output parameters. ----------------------------------------------------------------- */ /* See if screen output is required. */ parGet0l( "QUIET", &quiet, status ); if( !quiet ) msgBlank( status ); /* The number of clumps defined within the input NDF... */ parPut0i( "NCLUMPS", (int) nclumps, status ); if( ! quiet ) { msgSeti( "NCLUMPS", (int) nclumps ); msgOut( "", " Total no. of clumps: ^NCLUMPS", status ); } /* Pixel index bounding box... */ parPut1i( "LBOUND", info.npix, info.lbnd, status ); parPut1i( "UBOUND", info.npix, info.ubnd, status ); if( !quiet ) { p = tmpstr + sprintf( tmpstr, "( " ); for( i = 0; i < info.npix; i++) { p += sprintf( p, "%d:%d", info.lbnd[ i ], info.ubnd[ i ] ); if( i < info.npix - 1 ) p += sprintf( p, ", " ); } p += sprintf( p, " )" ); msgSetc( "SECTION", tmpstr ); msgOut( "", " Pixel index bounding box: ^SECTION", status ); } /* WCS bounding box (first convert the pixel index bounding box into WCS coords)... */ cfrm = astGetFrame( info.iwcs, AST__CURRENT ); kpg1Asffr( info.iwcs, "PIXEL", &ipix, status ); cmap = astGetMapping( info.iwcs, ipix, AST__CURRENT ); for( i = 0; i < info.npix; i++ ) { plbnd[ i ] = info.lbnd[ i ] - 1.0; pubnd[ i ] = info.ubnd[ i ]; } for( i = 0; i < info.nwcs; i++ ) { astMapBox( cmap, plbnd, pubnd, 1, i + 1, flbnd + i, fubnd + i, NULL, NULL); } astNorm( cfrm, flbnd ); astNorm( cfrm, fubnd ); parPut1d( "FLBND", info.nwcs, flbnd, status ); parPut1d( "FUBND", info.nwcs, fubnd, status ); if( !quiet ) { msgOut( "", " WCS bounding box:", status ); for( i = 0; i < info.nwcs; i++) { msgSetc( "L", astFormat( cfrm, i + 1, flbnd[ i ] ) ); msgSetc( "U", astFormat( cfrm, i + 1, fubnd[ i ] ) ); sprintf( tmpstr, "Domain(%d)", i + 1 ); dom = astGetC( cfrm, tmpstr ); if( dom && strcmp( dom, "SKY" ) ) { sprintf( tmpstr, "Unit(%d)", i + 1 ); msgSetc( "UNT", astGetC( cfrm, tmpstr ) ); } else { msgSetc( "UNT", "" ); } sprintf( tmpstr, "Label(%d)", i + 1 ); msgSetc( "LAB", astGetC( cfrm, tmpstr ) ); msgOut( "", " ^LAB: ^L -> ^U ^UNT", status ); } } if( !quiet ) msgBlank( status ); /* Tidy up. -------- */ L999: ; /* Free resources. */ clump_flags = astFree( clump_flags ); clump_indices = astFree( clump_indices ); if( aloc ) datAnnul( &aloc, status ); /* End the NDF context */ ndfEnd( status ); /* End the AST context */ astEnd; /* If an error has occurred, issue another error report identifying the program which has failed (i.e. this one). */ if( *status != SAI__OK ) { errRep( "CLUMPINFO_ERR", "CLUMPINFO: Failed to obtain information " "about one or more previously identified clumps.", status ); } }