// open an existing or new NDF file static PyObject* pyndf_open(NDF *self, PyObject *args) { const char *name; const char *mode = "READ"; const char *stat = "OLD"; if(!PyArg_ParseTuple(args, "s|ss:pyndf_open", &name, &mode, &stat)) return NULL; // check for allowed values of mode and stat if(strcmp(mode,"READ") != 0 && strcmp(mode,"WRITE") != 0 && strcmp(mode,"UPDATE") != 0) { PyErr_SetString( PyExc_ValueError, "Incorrect mode for ndf_open"); return NULL; } if(strcmp(stat,"OLD") != 0 && strcmp(stat,"NEW") != 0 && strcmp(stat,"UNKNOWN") != 0) { PyErr_SetString( PyExc_ValueError, "Unknown status string for ndf_open" ); return NULL; } int indf, place; int status = SAI__OK; errBegin(&status); indf = NDF__NOID; place = NDF__NOPL; ndfOpen( NULL, name, mode, stat, &indf, &place, &status); if (raiseNDFException(&status)) return NULL; return NDF_create_object( indf, place ); };
void smf_open_ndfname( const HDSLoc *loc, const char accmode[], const char extname[], const char state[], const char dattype[], const int ndims, const int lbnd[], const int ubnd[], const char datalabel[], const char dataunits[], const AstFrameSet* wcs, smfData **ndfdata, int *status) { /* Local variables */ void *datarr[] = { NULL, NULL }; /* Pointers for data */ int dims[NDF__MXDIM]; /* Extent of each dimension */ smf_dtype dtype; /* Data type */ int flags = 0; /* Flags for creating smfDA, smfFile and smfHead components in the output smfData */ int i; int ndat; /* Number of elements mapped in the requested NDF */ char ndfaccmode[NDF__SZMMD+1];/* Access mode to use to open the file */ int ndimsmapped; /* Number of dimensions in mapped NDF */ int ndfid; /* NDF identifier */ AstFrameSet *ndfwcs = NULL; /* Copy of input FrameSet to write to NDF */ smfFile *newfile = NULL; /* New smfFile with details of requested NDF */ int place; /* Placeholder for NDF */ int updating = 0; /* True if the extension is being updated */ /* Initialize the output smfData to NULL pointer */ *ndfdata = NULL; if ( *status != SAI__OK ) return; /* Check to see if the HDS Locator is null and retrieve the NDF id */ if ( loc == NULL ) { errRep( FUNC_NAME, "Given HDS locator is NULL", status ); return; } /* Start be assuming the requested access mode can be used for mapping and file opening */ one_strlcpy( ndfaccmode, accmode, sizeof(ndfaccmode), status ); /* Note: write access clears the contents of the NDF */ if ( strncmp( accmode, "WRITE", 5 ) == 0 ) { msgOutif(MSG__DEBUG," ", "Opening NDF with WRITE access: this will clear the current contents if the NDF exists.", status); updating = 1; /* We can have WRITE/ZERO or WRITE/BAD so we need to force WRITE into the NDF open access mode */ one_strlcpy( ndfaccmode, "WRITE", sizeof(ndfaccmode), status ); } else if ( strncmp( accmode, "UPDATE", 6) == 0) { updating = 1; } ndfOpen( loc, extname, ndfaccmode, state, &ndfid, &place, status ); if ( *status != SAI__OK ) { errRep( FUNC_NAME, "Call to ndfOpen failed: unable to obtain an NDF identifier", status ); return; } /* No placeholder => NDF exists */ if ( place != NDF__NOPL ) { /* Define properties of NDF */ ndfNew( dattype, ndims, lbnd, ubnd, &place, &ndfid, status ); if ( *status != SAI__OK ) { errRep( FUNC_NAME, "Unable to create a new NDF", status ); return; } } /* Convert the data type string to SMURF dtype */ dtype = smf_dtype_fromstring( dattype, status ); /* First step is to create an empty smfData with no extra components */ flags |= SMF__NOCREATE_DA; flags |= SMF__NOCREATE_FTS; flags |= SMF__NOCREATE_HEAD; flags |= SMF__NOCREATE_FILE; *ndfdata = smf_create_smfData( flags, status); /* Set the requested data type */ (*ndfdata)->dtype = dtype; /* OK, now map the data array */ ndfMap( ndfid, "DATA", dattype, accmode, &datarr[0], &ndat, status ); if ( *status != SAI__OK ) { errRep( FUNC_NAME, "Unable to map data array: invalid NDF identifier?", status ); } /* Retrieve dimensions of mapped array */ ndfDim( ndfid, NDF__MXDIM, dims, &ndimsmapped, status ); if ( *status != SAI__OK ) { errRep( FUNC_NAME, "Problem identifying dimensions of requested NDF", status ); } /* Consistency check */ if ( ndimsmapped != ndims ) { if ( *status == SAI__OK ) { *status = SAI__ERROR; errRep( FUNC_NAME, "Number of dimensions in new NDF not equal to number of dimensions specified", status ); } } if (*status == SAI__OK) { for (i=0; i<ndims; i++) { ((*ndfdata)->dims)[i] = dims[i]; ((*ndfdata)->lbnd)[i] = lbnd[i]; } } /* Allow for label, units and WCS to be written */ if (updating) { if (datalabel) ndfCput( datalabel, ndfid, "Label", status ); if (dataunits) ndfCput( dataunits, ndfid, "Unit", status ); if (wcs) { /* Take a copy of the input WCS and modify if necessary that before writing to the NDF */ ndfwcs = astCopy( wcs ); smf_set_moving( (AstFrame *) ndfwcs, NULL, status ); ndfPtwcs( ndfwcs, ndfid, status ); if (ndfwcs) ndfwcs = astAnnul( ndfwcs ); } } /* Create the smfFile */ newfile = smf_construct_smfFile( newfile, ndfid, 0, 0, NULL, status ); if ( *status != SAI__OK ) { errRep( FUNC_NAME, "Unable to construct new smfFile", status ); } /* And populate the new smfData */ *ndfdata = smf_construct_smfData( *ndfdata, newfile, NULL, NULL, NULL, dtype, datarr, NULL, SMF__QFAM_NULL, NULL, 0, 1, (*ndfdata)->dims, (*ndfdata)->lbnd, ndims, 0, 0, NULL, NULL, status ); }
void smf_flat_write( smf_flatmeth flatmeth, const char * flatname, double refres, const smfData * bolval, const smfData * powref, const smfData * bolref, const smfData * polyfit, const Grp * prvgrp, int * status ) { size_t colsize; /* number of columns */ double *dbuf = NULL; /* input double buffer for mean data */ double *dvar = NULL; /* input double buffer for variance of data */ char fitsrec[SC2STORE__MAXFITS*SZFITSCARD+1]; /* Store for FITS records */ int *ibuf = NULL; /* int buffer for mean data */ int indf = NDF__NOID; /* NDF identifier for output file */ size_t ncards; /* number of fits cards */ size_t numbols; /* number of bolometers */ double *outvar = NULL; /* buffer for variance of data */ int place = NDF__NOPL; /* Dummy placeholder for NDF */ size_t rowsize; /* number of rows */ JCMTState *state = NULL; /* State for this flatfield */ sc2ast_subarray_t subnum; /* subarray number */ AstFrameSet *result, *spacefset; AstLutMap *heatmap; AstFrame *heatfrm; int *dksquid; /* pointer to dummy dark SQUID data */ size_t j; /* loop counter */ int jig_vert[1][2]; /* dummy jiggle vertices */ double jig_path[1][2]; /* dummy jiggle path */ size_t nframes = 0; /* Number of frames in bolval */ int npath = 0; /* size of jiggle path */ int nvert = 0; /* number of jiggle vertices */ char *xmlfile = NULL; /* dummy xmlfile name */ if (*status != SAI__OK) return; if (!bolval->da) { *status = SAI__ERROR; errRep( "", "No flatfield solution provided for writing", status ); return; } if (!bolval->da->heatval) { *status = SAI__ERROR; errRep( "", "Must provide heater values in DA struct to smf_flat_write" " (possible programming error)", status ); return; } /* note that colsize is the number of rows and rowsize is the number of columns */ colsize = (bolval->dims)[SC2STORE__ROW_INDEX]; rowsize = (bolval->dims)[SC2STORE__COL_INDEX]; numbols = colsize * rowsize; nframes = (bolval->dims)[2]; /* Make sure we have a FLAT header that reflects this file as the flatfield solution */ smf_fits_updateS( bolval->hdr, "FLAT", flatname, "Name of flat-field file", status ); /* Create a FITS header for DA */ smf_fits_export2DA( bolval->hdr->fitshdr, &ncards, fitsrec, status ); /* Copy the data as integers so it can be written to data file. To prevent overflow in the variance we store that as doubles */ ibuf = astMalloc( (numbols * nframes)*sizeof(*ibuf) ); outvar = astMalloc( (numbols * nframes)*sizeof(*outvar) ); dbuf = (bolval->pntr)[0]; dvar = (bolval->pntr)[1]; if (*status == SAI__OK) { for (j = 0; j < (nframes * numbols); j++) { /* These started off as integers so the mean value must fit in an integer */ if ( dbuf[j] == VAL__BADD) { ibuf[j] = VAL__BADI; } else { ibuf[j] = (int)dbuf[j]; } /* Same data type so no need to convert bad values */ if (dvar) { outvar[j] = dvar[j]; } else { outvar[j] = VAL__BADD; } } } /* get subarray number */ smf_find_subarray( bolval->hdr, NULL, 0, &subnum, status ); /* Create dummy components for output file */ dksquid = astCalloc ( rowsize* nframes, sizeof(*dksquid) ); jig_vert[0][0] = 0; jig_vert[0][1] = 0; jig_path[0][0] = 0.0; jig_path[0][1] = 0.0; sc2store_setcompflag ( SC2STORE__NONE, status ); sc2store_wrtstream ( flatname, subnum, ncards, fitsrec, colsize, rowsize, nframes, (bolref->dims)[2], refres, 0, smf_flat_methstring( flatmeth, status ), bolval->hdr->allState, NULL, ibuf, dksquid, (bolref->pntr)[0], (powref->pntr)[0], "FLATCAL", NULL, NULL, jig_vert, nvert, jig_path, npath, xmlfile, status ); sc2store_free ( status ); /* To copy in the variance and modify fix up the WCS we need to reopen the file */ ndfOpen( NULL, flatname, "UPDATE", "OLD", &indf, &place, status ); /* make sure that history is not written twice */ ndfHsmod( "SKIP", indf, status ); if (outvar) { void *pntr[3]; int el; ndfStype( "_DOUBLE", indf, "VARIANCE", status ); ndfMap( indf, "VARIANCE", "_DOUBLE", "WRITE", pntr, &el, status ); if (*status == SAI__OK) { memcpy( pntr[0], outvar, sizeof(*outvar)*el ); } } /* For the WCS a time frame is less relevant than heater settings */ astBegin; /* Create frame for focal plane coordinates */ sc2ast_createwcs( subnum, NULL, NULL, NULL, NO_FTS, &spacefset, status ); /* Copy it to make sure we do not mess with the cache */ result = astCopy( spacefset ); /* and switch to BOLO frame which is best for bolometer analysis */ { int frnum = AST__NOFRAME; kpg1Asffr( result, "BOLO", &frnum, status ); if (frnum != AST__NOFRAME) astSetI( result, "CURRENT", frnum ); } /* Create a simple frame for heater settings */ heatfrm = astFrame( 1, "Domain=HEATER,Label(1)=Heater Setting" ); heatmap = astLutMap( nframes, bolval->da->heatval, 1.0, 1.0, " " ); /* Append the heater axis to the spatial frameset */ atlAddWcsAxis( result, (AstMapping *)heatmap, (AstFrame *) heatfrm, NULL, NULL, status ); /* write it to the NDF */ ndfPtwcs( result, indf, status ); /* Write provenance information */ if (prvgrp) { size_t size = grpGrpsz( prvgrp, status ); char prvname[ 2 * PAR__SZNAM + 1]; smf_get_taskname( NULL, prvname, status ); for (j=1; j<=size; j++) { smf_accumulate_prov( NULL, prvgrp, j, indf, prvname, NULL, status ); } } /* Write the polynomial expansion into an extension */ if (polyfit) { char fitfile[GRP__SZNAM+1]; int fndf = NDF__NOID; place = NDF__NOPL; one_strlcpy( fitfile, flatname, sizeof(fitfile), status ); one_strlcat( fitfile, ".MORE.SMURF.FLATFIT", sizeof(fitfile), status ); /* create the file */ smf_write_smfData( polyfit, NULL, fitfile, NULL, 0, NDF__NOID, MSG__VERB, 0, status ); /* Same WCS as the main file */ ndfOpen( NULL, fitfile, "UPDATE", "OLD", &fndf, &place, status ); ndfPtwcs( result, fndf, status ); ndfAnnul( &fndf, status ); } astEnd; ndfAnnul( &indf, status); if (ibuf) ibuf = astFree( ibuf ); if (outvar) outvar = astFree( outvar ); if (dksquid) dksquid = astFree( dksquid ); if (state) state = astFree( state ); }
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 {
int write_ndf( int argc, void *argv[]) { /* ** Declare variables */ void *arr; /* Pointer to the data array */ int n_dims; /* The number of dimensions */ int *arr_bnds; /* The dimensions */ IDL_STRING *ndf_name; /* The name of the NDF to be created */ IDL_STRING *comp; /* The component name */ IDL_STRING *type; /* The HDS type of the NDF to be created */ int badset; /* Whether bad value is set */ void *bad_value; /* Pointer to the bad value */ int status; /* Starlink status */ int lbnd[5]={1L,1L,1L,1L,1L}; /* Lower bounds array */ int ndf; /* NDF identifier */ int place; /* NDF placeholder */ int npix; /* Number of pixels */ void *ptr[3]; /* Pointer to mapped NDF data Fortran style */ size_t nbytes; /* Number of bytes in NDF */ int bpix=1; /* Number of bits/pixel */ int idltype=1; /* Pixel type code */ int fstat; /* Final status (before errLoad) */ int errn=0; /* Error sequence number */ char param[ERR__SZPAR]; /* Error message parameter name */ int parlen; /* Length of error message parameter name */ char opstr[ERR__SZMSG]; /* Error message */ int oplen; /* Length of error message */ /* ** Start Error context */ status = SAI__OK; errMark(); /* ** Check that the correct number of arguments were passed in */ if(argc != 8) { /* ** Print an error message and return */ status = SAI__ERROR; errRep( " ", "write_ndf: Incorrect number of arguments", &status ); } else { /* ** Extract the arguments to comprehensible names */ arr = argv[0]; n_dims = *(int *)argv[1]; arr_bnds = (int *)argv[2]; ndf_name = (IDL_STRING *)argv[3]; comp = (IDL_STRING *)argv[4]; type = (IDL_STRING *)argv[5]; badset = *(int *)argv[6]; bad_value = (void *)argv[7]; /* ** Enable NDF calls */ ndfBegin(); if ( !strcmp( comp->s, "DATA" ) ) { /* ** Create the NDF */ ndfOpen( NULL, ndf_name->s, "WRITE", "NEW", &ndf, &place, &status ); ndfNew( type->s, n_dims, lbnd, arr_bnds, &place, &ndf, &status ); } else { if ( !strcmp( comp->s, "QUALITY") && strcmp(type->s, "_UBYTE")) { status = SAI__ERROR; errRep( " ", "write_ndf: Incorrect type for QUALITY", &status ); } /* ** Open existing NDF */ ndfOpen( NULL, ndf_name->s, "UPDATE", "OLD", &ndf, &place, &status ); } /* ** Check the number of pixels is same in given array and NDF for QUALITY ** and VARIANCE. */ if ( strcmp( comp->s, "DATA" ) ) { ndfSize( ndf, &npix, &status ); if ( ( status == SAI__OK ) && ( npix != arr_bnds[n_dims+1] ) ) { /* ** Array size and NDF size do not agree */ status = SAI__ERROR; errRep( " ", "write_ndf: Incorrect number elements supplied", &status ); } } /* ** Obtain mapped access to the array component of the NDF */ ndfMap( ndf, comp->s, type->s, "WRITE", ptr, &npix, &status ); /* ** Now copy the values from ARR into the mapped NDF */ if ( status == SAI__OK ) { /* ** First check the returned pointer is good */ if ( ptr[0] == NULL ) { /* ** Fortran to C pointer conversion failed */ status = SAI__ERROR; errRep( " ", "write_ndf: Fortran to C pointer conversion failed", &status ); } else { /* ** then get the IDL type code and number of bytes per pixel */ if (!strcmp(type->s, "_REAL")) { idltype = 4; bpix = 4; } else if (!strcmp(type->s, "_INTEGER")) { idltype = 3; bpix = 4; } else if (!strcmp(type->s, "_WORD")) { idltype = 2; bpix = 2; } else if (!strcmp(type->s, "_DOUBLE")) { idltype = 5; bpix = 8; } else if (!strcmp(type->s, "_UBYTE")) { idltype = 1; bpix = 1; } else { status = SAI__ERROR; msgSetc( "TYPE", type->s ); errRep( " ", "Illegal type ^TYPE", &status ); } /* ** Now copy the data from the array to the NDF. ** If we need to check for bad values in the array, use copybadout. ** If any bad values are found copybadout will replace them with the ** appropriate PRIMDAT bad value. The NDF bad pixel flag is then set ** depending on whether copybadout detected any bad values. ** If we need not check for bad pixels just copy the whole lot; */ if ( status == SAI__OK ) { if ( badset ) { if ( !copybadout( ptr[0], arr, npix, idltype, bad_value ) ) ndfSbad( 0, ndf, comp->s, &status); } else { nbytes = bpix * npix; memcpy( ptr[0], arr, nbytes ); } } } } /* ** Close NDF */ ndfEnd( &status ); } /* ** Report any error messages ** Adding Starlink-style !! and ! prefix */ fstat = status; while ( status != SAI__OK ) { errLoad( param, ERR__SZPAR, &parlen, opstr, ERR__SZMSG, &oplen, &status ); if ( status != SAI__OK ) printf( "%s %s\r\n", errn++?"! ":"!!", opstr ); } errRlse(); /* ** That's it, return to the calling routine */ return( fstat == SAI__OK ); }
int read_ndf( int argc, void *argv[] ) { /* ** Declare variables */ IDL_STRING *ndf_name; /* The name of the NDF to be read */ IDL_STRING *comp; /* The component name */ IDL_STRING *type; /* The HDS type of the component to be read */ void *arr; /* Pointer to the data array */ int badset; /* Whether bad value is set */ void *bad_value; /* Pointer to the bad value */ int status; /* Starlink status */ int ndf; /* NDF identifier */ int place; /* NDF placeholder */ int npix; /* Number of pixels */ void *ptr[3]; /* Pointer to mapped NDF data Fortran style */ size_t nbytes; /* Number of bytes in NDF */ int bpix=1; /* Number of bits/pixel */ int idltype=1; /* Pixel type code */ int bad; /* If bad pixels need handling */ int fstat; /* Final status (before errLoad) */ int errn=0; /* Error sequence number */ char param[ERR__SZPAR]; /* Error message parameter name */ int parlen; /* Length of error message parameter name */ char opstr[ERR__SZMSG]; /* Error message */ int oplen; /* Length of error message */ /* ** Start Error context */ status = SAI__OK; errMark(); /* ** Check that the correct number of arguments were passed in */ if(argc != 6) { /* ** Print an error message and return */ status = SAI__ERROR; errRep( " ", "read_ndf: Incorrect number of arguments", &status ); } else { /* ** Extract the arguments to comprehensible names */ ndf_name = (IDL_STRING *)argv[0]; comp = (IDL_STRING *)argv[1]; type = (IDL_STRING *)argv[2]; arr = argv[3]; badset = *(int *)argv[4]; bad_value = (void *)argv[5]; /* ** Enable NDF calls */ ndfBegin(); /* ptr[2]=malloc(256);*/ /* ** Open the NDF */ ndfOpen( NULL, ndf_name->s, "READ", "OLD", &ndf, &place, &status ); /* ** Obtain mapped access to the array component of the first NDF */ ndfMap( ndf, comp->s, type->s, "READ", ptr, &npix, &status ); /* ** Now copy the values from the mapped NDF into ARR */ if ( status == SAI__OK ) { /* ** First check the returned pointer is good */ if ( ptr[0] == NULL ) { /* ** Fortran to C pointer conversion failed */ status = SAI__ERROR; errRep( " ", "read_ndf: Fortran to C pointer conversion failed", &status ); } else { /* ** then get the IDL type and number of bytes per pixel */ if (!strcmp(type->s, "_REAL")) { idltype = 4; bpix = 4; } else if (!strcmp(type->s, "_INTEGER")) { idltype = 3; bpix = 4; } else if (!strcmp(type->s, "_WORD")) { idltype = 2; bpix = 2; } else if (!strcmp(type->s, "_DOUBLE")) { idltype = 5; bpix = 8; } else if (!strcmp(type->s, "_UBYTE")) { idltype = 1; bpix = 1; } else { status = SAI__ERROR; msgSetc( "TYPE", type->s ); errRep( " ", "Illegal type ^TYPE", &status ); } /* ** If badset is false, we can just copy everything; otherwise see if ** bad pixels may be set and act accordingly. Set bad if we need to check ** for bad pixels. */ bad = 0; if ( badset ) ndfBad( ndf, "DATA", 0, &bad, &status ); /* ** Now copy the data from the NDF to the array. ** If we need not check for bad pixels just copy the whole lot */ if ( status == SAI__OK ) { if ( bad ) { copybadin( arr, ptr[0], npix, idltype, bad_value ); } else { nbytes = bpix * npix; memcpy( arr, ptr[0], nbytes ); } } } } /* ** Close NDF */ ndfEnd( &status ); } /* ** Report any error messages ** Adding Starlink-style !! and ! prefix */ fstat = status; while ( status != SAI__OK ) { errLoad( param, ERR__SZPAR, &parlen, opstr, ERR__SZMSG, &oplen, &status ); if ( status != SAI__OK ) printf( "%s %s\r\n", errn++?"! ":"!!", opstr ); } errRlse(); /* ** That's it, return to the calling routine */ return( fstat == SAI__OK ); }