static PyObject* pyndf_xloc(NDF *self, PyObject *args) { const char *xname, *mode; if(!PyArg_ParseTuple(args, "ss:pyndf_xloc", &xname, &mode)) return NULL; HDSLoc* loc = NULL; int status = SAI__OK; errBegin(&status); ndfXloc(self->_ndfid, xname, mode, &loc, &status); if (raiseNDFException(&status)) return NULL; // PyCObject to pass pointer along to other wrappers PyObject *pobj = NpyCapsule_FromVoidPtr(loc, PyDelLoc); return Py_BuildValue("O", pobj); };
void smf_ext2km( int indf, const char *xname, AstKeyMap *keymap, int mode, int *status ){ /* Local Variables */ HDSLoc *cloc = NULL; HDSLoc *sloc = NULL; HDSLoc *xloc = NULL; const char *key = NULL; hdsdim diml[NDF__MXDIM]; hdsdim dimu[NDF__MXDIM]; int dim[ NDF__MXDIM ]; int i; int idim; int lbnd[ NDF__MXDIM ]; int ncomp; int ndim; int nentry; int ntime = 0; int prim; int there; int ubnd[ NDF__MXDIM ]; /* Check the inherited status */ if( *status != SAI__OK ) return; /* Get the shape of the NDF. */ ndfBound( indf, 3, lbnd, ubnd, &ndim, status ); /* Get a locator to the named extension. */ ndfXloc( indf, xname, "READ", &xloc, status ); /* Select the name of the prototype component that determines the length of the arrays to be copied. */ if( !strcmp( xname, "JCMTSTATE" ) ) { key = "RTS_NUM"; } else if( !strcmp( xname, "ACSIS" ) ) { key = "TSYS"; } else { cloc = NULL; msgSetc( "X", xname ); errRep( "", "smf_ext2km: Unknown extension specified - '^X'. " "Must be 'JCMTSTATE' or 'ACSIS'.", status ); } /* Check the prorotype component is present in the extension. Report an error if not. */ datThere( xloc, key, &there, status ); if( !there && *status == SAI__OK ) { msgSetc( "C", key ); msgSetc( "X", xname ); errRep( "", "smf_ext2km: Component '^C' not found in extension " "^X", status ); /* If it is present, get the length of its last pixel axis. This is the length of the arrays to be copied. */ } else { datFind( xloc, key, &cloc, status ); datShape( cloc, NDF__MXDIM, dim, &ndim, status ); ntime = dim[ ndim - 1 ]; datAnnul( &cloc, status ); } /* First deal with mode 1... */ /* ========================= */ if( mode == 1 ) { /* Loop round every component in the extension. */ datNcomp( xloc, &ncomp, status ); for( i = 1; i <= ncomp; i++ ) { datIndex( xloc, i, &cloc, status ); /* Check the component has primitive values. */ datPrim( cloc, &prim, status ); if( prim ) { /* Get the shape of the component. */ datShape( cloc, NDF__MXDIM, dim, &ndim, status ); /* Skip over this component if the length of its final axis is not equal to the expected number of time slices. */ if( ndim > 0 && dim[ ndim - 1 ] == ntime ) { /* Also skip if we are dealing with the ACSIS extension and the array has only 1 (or zero) axes. */ if( ndim > 1 || strcmp( xname, "ACSIS" ) ) { /* Cut a section from the HDS array so that it matches the pixel bounds of the NDF . */ for( idim = 0; idim < ndim - 1; idim++ ) { diml[ idim ] = 1; dimu[ idim ] = dim[ idim ]; } diml[ idim ] = lbnd[ 2 ]; dimu[ idim ] = ubnd[ 2 ]; datSlice( cloc, ndim, diml, dimu, &sloc, status ); /* Store the values as a new entry in "keymap". */ kpg1Hdsky( sloc, keymap, 2, 1, status ); /* Annul the locator for the slice. */ datAnnul( &sloc, status ); } } } datAnnul( &cloc, status ); } /* Now deal with mode 2... */ /* ========================= */ } else if( mode == 2 ) { /* Loop round every entry in the KeyMap. */ nentry = astMapSize( keymap ); for( i = 0; i < nentry; i++ ) { key = astMapKey( keymap, i ); /* See if the supplied extension has a component with the same name. */ datThere( xloc, key, &there, status ); /* If it did, check the component is primitive. */ if( there && *status == SAI__OK ) { datFind( xloc, key, &cloc, status ); datPrim( cloc, &prim, status ); if( prim ) { /* Check the final axis of the primitive array has a length equal to the expected number of time slices. */ datShape( cloc, NDF__MXDIM, dim, &ndim, status ); if( ndim > 0 && dim[ ndim - 1 ] == ntime ) { /* Also skip if we are dealing with the ACSIS extension and the array has only 1 (or zero) axes. */ if( ndim > 1 || strcmp( xname, "ACSIS" ) ) { /* Cut a section from the HDS array so that it matches the pixel bounds of the NDF . */ for( idim = 0; idim < ndim - 1; idim++ ) { diml[ idim ] = 1; dimu[ idim ] = dim[ idim ]; } diml[ idim ] = lbnd[ 2 ]; dimu[ idim ] = ubnd[ 2 ]; datSlice( cloc, ndim, diml, dimu, &sloc, status ); /* Append the values to the end of the existing KeyMap entry. */ kpg1Hdsky( sloc, keymap, 1, 3, status ); /* Annul the locator for the slice. */ datAnnul( &sloc, status ); } } else if( *status == SAI__OK ) { *status = SAI__ERROR; msgSetc( "X", xname ); msgSetc( "K", key ); ndfMsg( "F", indf ); errRep( "", "The ^X.^K array has an unexpected shape in " "\"^F\".", status ); } } else if( *status == SAI__OK ) { *status = SAI__ERROR; msgSetc( "X", xname ); msgSetc( "K", key ); ndfMsg( "F", indf ); errRep( "", "The ^X.^K array has an unexpected data type in " "\"^F\".", status ); } datAnnul( &cloc, status ); } else if( *status == SAI__OK ) { *status = SAI__ERROR; msgSetc( "X", xname ); msgSetc( "K", key ); ndfMsg( "F", indf ); errRep( "", "The ^X.^K array is missing in \"^F\".", status ); } } /* Now tidy up. */ /* ============ */ /* Report an error if the "mode" value was illegal. */ } else if( *status == SAI__OK ) { *status = SAI__ERROR; msgSeti( "MODE", mode ); errRep( "", "smf_ext2km: Illegal value (^MODE) supplied for " "argument MODE (programming error).", status ); } /* Free resources. */ datAnnul( &xloc, status ); }
void smurf_fts2_transcorr(int* status) { if( *status != SAI__OK ) { return; } char filename[GRP__SZNAM+1]; /* Filename */ char *pname = NULL; /* Pointer to filename */ int bolCount = 0; /* Number of bolometers */ int bolIndex = 0; /* Bolometer index */ int count; int dims[NDF__MXDIM]; int debug = 0; /* If not debug, include dry component */ int ftsExists = 0; int index = 0; int indf; /* NDF identifier for TAU file */ int KERNELLENGTH = 101; int nbolX = 0; /* Width of the source subarray */ int nbolY = 0; /* Height of the source subarray */ int ndfTau; int ndim; int nPWV = 0; int nWN = 0; int N = 0; /* Sample count */ int i = 0; /* Index */ int j = 0; /* Index */ int k = 0; /* Index */ int place; double AM = 0.0; /* Airmass at ZPD */ double DELTAPWV = 0.0; double PWV0 = 0.0; double PWV = 0.0; /* PWV at ZPD */ double wnFact = 0.0; /* Wave number factor */ double* inPntr = NULL; /* Pointer to the input data */ double* outPntr = NULL; /* Pointer to the output data */ double* wnScan = NULL; double* wnTau = NULL; double* TAtm = NULL; double* TAtmNew = NULL; double* GAUSSIANKERNEL = NULL; double* PWVARR = NULL; double* PWVNEW = NULL; double* TAUNEW = NULL; double* TAUWET = NULL; double* TMPARR = NULL; Grp* inGrp = NULL; /* Input group */ Grp* outGrp = NULL; /* Output group */ Grp* tauGrp = NULL; /* TAU WET group */ HDSLoc* loc = NULL; /* HDS location */ size_t fIndex = 0; /* File loop counter */ size_t inSize = 0; /* Size of the input group */ size_t outSize = 0; /* Size of the output group */ size_t tauSize = 0; /* Size of the tau group */ smfData* inData = NULL; /* Pointer to input data */ smfData* outData = NULL; /* Pointer to output data */ smfData* tauData = NULL; /* Pointer to tau dry data */ void* TAU[] = {NULL, NULL}; /* {dry, wet} */ const double SQRT2PI = 2.50662827463100050242; const double SQRT2LN2 = 1.17741002251547469101; // GET INPUT GROUP kpg1Rgndf("IN", 0, 1, "", &inGrp, &inSize, status); // GET OUTPUT GROUP kpg1Wgndf("OUT", outGrp, inSize, inSize, "Equal number of input and output files expected!", &outGrp, &outSize, status); // GET TAU GROUP kpg1Gtgrp("TAU", &tauGrp, &tauSize, status); parGet0l("DEBUG", &debug, status); ndfBegin(); // =========================================================================== // GET TAU INFORMATION // =========================================================================== int dryOK = 0; int wetOK = 0; pname = filename; grpGet(tauGrp, 1, 1, &pname, sizeof(filename), status); ndgNdfas(tauGrp, 1, "READ", &indf, status ); if (indf == NDF__NOID) { *status = SAI__ERROR; msgSetc("FILE", filename); errRep("", FUNC_NAME ": Could not locate file ^FILE", status); return; } ndfXstat(indf, "FTS2", &ftsExists, status); if(*status == SAI__OK && ftsExists) { ndfXloc(indf, "FTS2", "READ", &loc, status); if(*status == SAI__OK && loc != NULL) { // DRY COMPONENT ndfOpen(loc, "DRY", "READ", "UNKNOWN", &ndfTau, &place, status); if(*status == SAI__OK && ndfTau != NDF__NOID) { ndfDim(ndfTau, NDF__MXDIM, dims, &ndim, status); if(*status == SAI__OK && ndim == 1) { ndfMap(ndfTau, "DATA", "_DOUBLE", "READ", &TAU[0], &count, status); dryOK = 1; } } // WET COMPONENT ndfOpen(loc, "WET", "READ", "UNKNOWN", &ndfTau, &place, status); if(*status == SAI__OK && ndfTau != NDF__NOID) { ndfDim(ndfTau, NDF__MXDIM, dims, &ndim, status); if(*status == SAI__OK && ndim == 2) { ndfMap(ndfTau, "DATA", "_DOUBLE", "READ", &TAU[1], &count, status); wetOK = 1; } } } } if(loc) { datAnnul(&loc, status); } if(!(dryOK && wetOK)) { *status = SAI__ERROR; errRep("", FUNC_NAME ": Unable to obtain TAU values!", status); return; } smf_open_file(NULL, tauGrp, 1, "READ", 0, &tauData, status); smf_fits_getD(tauData->hdr, "PWV0", &PWV0, status); smf_fits_getD(tauData->hdr, "DELTAPWV", &DELTAPWV, status); if(*status != SAI__OK) { *status = SAI__ERROR; errRep("", FUNC_NAME ": Unable to obtain PWV value(s)!", status); return; } nWN = dims[0]; nPWV = dims[1]; PWVARR = astMalloc(nPWV * sizeof(*PWVARR)); for(i = 0; i < nPWV; i++) { PWVARR[i] = PWV0 + i * DELTAPWV; } PWVNEW = astMalloc(1 * sizeof(*PWVNEW)); TAUNEW = astMalloc(1 * sizeof(*TAUNEW)); // =========================================================================== // LOOP THROUGH EACH NDF FILE IN THE INPUT GROUP // =========================================================================== for(fIndex = 1; fIndex <= inSize; fIndex++) { // OPEN INPUT FILE smf_open_file(NULL, inGrp, fIndex, "READ", 0, &inData, status); if(*status != SAI__OK) { *status = SAI__ERROR; errRep(FUNC_NAME, "Unable to open source file!", status); break; } outData = smf_deepcopy_smfData(NULL, inData, 0, SMF__NOCREATE_DATA, 0, 0, status); if(*status == SAI__OK) { inPntr = inData->pntr[0]; nbolX = inData->dims[0]; nbolY = inData->dims[1]; N = inData->dims[2]; bolCount = nbolX * nbolY; outData->dtype = SMF__DOUBLE; outData->ndims = 3; outData->dims[0] = inData->dims[0]; outData->dims[1] = inData->dims[1]; outData->dims[2] = inData->dims[2]; outData->lbnd[0] = outData->lbnd[0]; outData->lbnd[1] = outData->lbnd[1]; outData->lbnd[2] = outData->lbnd[2]; outData->pntr[0] = (double*) astMalloc( (N * bolCount)*sizeof(double) ); outPntr = outData->pntr[0]; // DETERMINE WAVENUMBER FACTOR FROM FITS smf_fits_getD(inData->hdr, "WNFACT", &wnFact, status); if(*status != SAI__OK) { errRep(FUNC_NAME, "Unable to find wave number factor!", status); smf_close_file( NULL,&inData, status); break; } // TODO // DETERMINE AIRMASS AT ZPD // TODO // DETERMINE PWV AT ZPD PWVNEW[0] = PWV; // GET TAU WET FOR CORRESPONDING PWV TAUWET = astMalloc(nWN * sizeof(*TAUWET)); TMPARR = astMalloc(nWN * sizeof(*TMPARR)); for(k = 0; k < nWN; k++) { for(j = 0; j < nPWV; j++) { TMPARR[j] = *((double*) TAU[1] + j); } fts2_naturalcubicsplineinterpolator(PWVARR, TMPARR, nPWV, PWVNEW, TAUNEW, 1); TAUWET[k] = TAUNEW[0]; } astFree(TMPARR); // COMPUTE ATMOSPHERIC TRANSMISSION // TATM = EXP(-AIRMASS * (PWV * TAUWET + TAUDRY)) TAtm = astMalloc(nWN * sizeof(*TAtm)); if(!debug) { for(i = 0; i < nWN; i++) { TAtm[i] = exp(-AM * (PWV * TAUWET[i] + (*((double*) TAU[0] + i)))); } } else { for(i = 0; i < nWN; i++) { TAtm[i] = exp(-AM * PWV * TAUWET[i]); } } // SMOOTH ATMOSPHERIC TRANSMISSION VIA GAUSSIAN CONVOLUTION // NEED TO TRIM FROM BOTH ENDS BY HALF OF (KERNELLENGTH - 1) double OPDMAX = 1.0; double FWHM = 1.0 / (2.0 * OPDMAX); // FWHM = 1 / (2 x OPDMAX) double SDEV = 0.5 * FWHM / SQRT2LN2; // FWHM = 2 x SQRT(2ln2) x SDEV double VAR = SDEV * SDEV; double VAR2 = 2.0 * VAR; double NORM = 1.0 / (SDEV * SQRT2PI); double XMIN = -6 * SDEV; double XMAX = 6 * SDEV; double DX = (XMAX - XMIN) / (KERNELLENGTH - 1); double X = XMIN; for(i = 0; i < KERNELLENGTH; i++) { X = XMIN + i * DX; GAUSSIANKERNEL[i] = NORM * exp(-(X * X) / VAR2); } int M = nWN + KERNELLENGTH - 1; TMPARR = astMalloc(M * sizeof(*TMPARR)); for(i = 0; i < nWN; i++) { for(j = 0; j < KERNELLENGTH; j++) { TMPARR[i + j] += (TAtm[i] * GAUSSIANKERNEL[j]); } } int OFFSET = (KERNELLENGTH - 1) >> 1; for(i = 0; i < nWN; i++) { TAtm[i] = TMPARR[i + OFFSET]; } astFree(TMPARR); // INTERPOLATE ATMOSPHERIC TRANSMISSION ONTO SCAN RESOLUTION wnTau = astMalloc(nWN * sizeof(*wnTau)); wnScan = astMalloc(N * sizeof(*wnScan)); TAtmNew = astMalloc(N * sizeof(*TAtmNew)); for(i = 0; i < N; i++) { wnScan[i] = i * wnFact; } for(i = 0; i < nWN; i++) { wnTau[i] = i; } fts2_naturalcubicsplineinterpolator(wnTau, TAtm, nWN, wnScan, TAtmNew, N); // TSOURCE = TOBS / TATM for(i = 0; i < nbolY; i++) { for(j = 0; j < nbolX; j++) { bolIndex = i + j * nbolY; for(k = 0; k < N; k++) { index = bolIndex + bolCount * k; outPntr[index] = inPntr[index] / TAtmNew[k]; } } } astFree(wnTau); astFree(wnScan); astFree(TAtm); astFree(TAtmNew); smf_write_smfData(NULL, outData, NULL, NULL, outGrp, fIndex, 0, MSG__VERB, 0, status); smf_close_file( NULL,&outData, status); smf_close_file( NULL,&inData, status); } else {
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 ); } }