Пример #1
0
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;
};
Пример #2
0
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 );

}
Пример #3
0
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 );

}
Пример #5
0
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 );
    }

}