static PyObject* pyndf_dim(NDF *self) { int i; PyArrayObject* dim = NULL; int ndim; int idim[NDF__MXDIM]; int status = SAI__OK; errBegin(&status); ndfDim(self->_ndfid, NDF__MXDIM, idim, &ndim, &status ); if (raiseNDFException(&status)) return NULL; npy_intp odim[1]; odim[0] = ndim; dim = (PyArrayObject*) PyArray_SimpleNew(1, odim, PyArray_INT); if(dim == NULL) goto fail; for(i=0; i<ndim; i++) ((int *)dim->data)[i] = idim[ndim-i-1]; return Py_BuildValue("N", PyArray_Return(dim)); fail: Py_XDECREF(dim); return NULL; };
static int tr_iaxis(int indf, int iaxis, int *status) { if(iaxis == -1) return 0; // Get dimensions int ndim, idim[NDF__MXDIM]; ndfDim(indf, NDF__MXDIM, idim, &ndim, status); if(*status != SAI__OK) return -1; if(iaxis < -1 || iaxis > ndim-1){ PyErr_SetString(PyExc_IOError, "tr_axis: axis number too out of range"); *status = SAI__ERROR; return -1; } return ndim-iaxis; }
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 ); }
int *smf_find_bad_dets( Grp *igrp, int size, int *nbaddet, int *status ){ /* Local Variables */ float *p = NULL; int *result; int dims[ 3 ]; int el; int i; int ifile; int indf; int j; int k; int ndim; int outlen; /* Initialise returned values. */ *nbaddet = 0; result = NULL; outlen = 0; /* Check inherited status */ if( *status != SAI__OK ) return result; /* Loop round all the input NDFs. */ for( ifile = 1; ifile <= size && *status == SAI__OK; ifile++ ) { /* Get an NDF identifier for the input NDF. */ ndgNdfas( igrp, ifile, "READ", &indf, status ); /* Get the dimensions of the NDF. */ ndfDim( indf, 3, dims, &ndim, status ); /* If the returned array is shorter than the number of detectors in this NDF, extend the returned array and initialise the new elements to zero. */ if( outlen < dims[ 1 ] ) { result = astGrow( result, dims[ 1 ], sizeof( int ) ); if( astOK ) { for( i = outlen; i < dims[ 1 ]; i++ ) result[ i ] = 0; outlen = dims[ 1 ]; } } /* Map the data array of the NDF. */ ndfMap( indf, "Data", "_REAL", "READ", (void *) &p, &el, status ); /* Loop round all elements of the NDF. */ for( k = 0; k < dims[ 2 ]; k++ ) { for( j = 0; j < dims[ 1 ]; j++ ) { for( i = 0; i < dims[ 0 ]; i++ ) { /* If this data value is good, indicate that the detector has some good values, and break out of the "i" loop to move on to the next spectrum. */ if( *p != VAL__BADR ) { result[ j ] = 1; p += dims[ 0 ] - i; break; } else { p++; } } } } /* Annul the input NDF identifier. */ ndfAnnul( &indf, status ); } /* Count the number of bad detectors. */ for( i = 0; i < outlen; i++ ) { if( result[ i ] == 0 ) (*nbaddet)++; } /* Return the result. */ return result; }
void smurf_unmakemap( int *status ) { /* Local Variables */ AstFrameSet *wcsin = NULL; /* WCS Frameset for input cube */ AstMapping *skymap; /* GRID->SkyFrame Mapping from input WCS */ AstSkyFrame *abskyfrm; /* Input SkyFrame (always absolute) */ AstSkyFrame *skyfrm = NULL;/* SkyFrame from the input WCS Frameset */ Grp *igrp1 = NULL; /* Group of input sky files */ Grp *igrp2 = NULL; /* Group of input template files */ Grp *igrpc = NULL; /* Group of input COM files */ Grp *igrpg = NULL; /* Group of input GAI files */ Grp *igrpq = NULL; /* Group of input Q sky files */ Grp *igrpu = NULL; /* Group of input U sky files */ Grp *ogrp = NULL; /* Group containing output file */ HDSLoc *cloc = NULL; /* HDS locator for component ipdata structure */ HDSLoc *iploc = NULL; /* HDS locator for top level ipdata structure */ ThrWorkForce *wf = NULL; /* Pointer to a pool of worker threads */ char ipdata[ 200 ]; /* Text buffer for IPDATA value */ char pabuf[ 10 ]; /* Text buffer for parameter value */ char subarray[ 5 ]; /* Name of SCUBA-2 subarray (s8a,s8b,etc) */ dim_t iel; /* Index of next element */ dim_t ndata; /* Number of elements in array */ dim_t ntslice; /* Number of time slices in array */ double *ang_data = NULL; /* Pointer to the FP orientation angles */ double *angc_data = NULL; /* Pointer to the instrumental ANGC data */ double *c0_data = NULL; /* Pointer to the instrumental C0 data */ double *gai_data = NULL; /* Pointer to the input GAI map */ double *in_data = NULL; /* Pointer to the input I sky map */ double *inc_data = NULL; /* Pointer to the input COM data */ double *inq_data = NULL; /* Pointer to the input Q sky map */ double *inu_data = NULL; /* Pointer to the input U sky map */ double *outq_data = NULL; /* Pointer to the Q time series data */ double *outu_data = NULL; /* Pointer to the U time series data */ double *p0_data = NULL; /* Pointer to the instrumental P0 data */ double *p1_data = NULL; /* Pointer to the instrumental P1 data */ double *pd; /* Pointer to next element */ double *pq = NULL; /* Pointer to next Q time series value */ double *pu = NULL; /* Pointer to next U time series value */ double *qinst_data = NULL; /* Pointer to the instrumental Q data */ double *uinst_data = NULL; /* Pointer to the instrumental U data */ double amp16; /* Amplitude of 16 Hz signal */ double amp2; /* Amplitude of 2 Hz signal */ double amp4; /* Amplitude of 4 Hz signal */ double angrot; /* Angle from focal plane X axis to fixed analyser */ double paoff; /* WPLATE value corresponding to POL_ANG=0.0 */ double params[ 4 ]; /* astResample parameters */ double phase16; /* Phase of 16 Hz signal */ double phase2; /* Phase of 2 Hz signal */ double phase4; /* Phase of 4 Hz signal */ double sigma; /* Standard deviation of noise to add to output */ int alignsys; /* Align data in the map's system? */ int cdims[ 3 ]; /* Common-mode NDF dimensions */ int dims[ NDF__MXDIM ]; /* NDF dimensions */ int flag; /* Was the group expression flagged? */ int gdims[ 3 ]; /* GAI model NDF dimensions */ int harmonic; /* The requested harmonic */ int ifile; /* Input file index */ int indf; /* Input sky map NDF identifier */ int indfangc; /* IP ANGC values NDF identifier */ int indfc0; /* IP C0 values NDF identifier */ int indfc; /* Input COM NDF identifier */ int indfcs; /* NDF identifier for matching section of COM */ int indfg; /* Input GAI NDF identifier */ int indfin; /* Input template cube NDF identifier */ int indfiq; /* Input instrumental Q NDF */ int indfiu; /* Input instrumental U NDF */ int indfout; /* Output cube NDF identifier */ int indfp0; /* IP P0 values NDF identifier */ int indfp1; /* IP P1 values NDF identifier */ int indfq; /* Input Q map NDF identifier */ int indfu; /* Input U map NDF identifier */ int interp = 0; /* Pixel interpolation method */ int lbndc[ 3 ]; /* Array of lower bounds of COM NDF */ int moving; /* Is the telescope base position changing? */ int ndim; /* Number of pixel axes in NDF */ int ndimc; /* Number of pixel axes in common-mode NDF */ int ndimg; /* Number of pixel axes in GAI NDF */ int nel; /* Number of elements in array */ int nelc; /* Number of elements in COM array */ int nelg; /* Number of elements in GAI array */ int nelqu; /* Number of elements in Q or U array */ int ngood; /* No. of good values in putput cube */ int nparam = 0; /* No. of parameters required for interpolation scheme */ int pasign; /* Indicates sense of POL_ANG value */ int sdim[ 2 ]; /* Array of significant pixel axes */ int slbnd[ 2 ]; /* Array of lower bounds of input map */ int subnd[ 2 ]; /* Array of upper bounds of input map */ int ubndc[ 3 ]; /* Array of upper bounds of COM NDF */ size_t ncom; /* Number of com files */ size_t ngai; /* Number of gai files */ size_t nskymap; /* Number of supplied sky cubes */ size_t outsize; /* Number of files in output group */ size_t size; /* Number of files in input group */ smfData *odata = NULL; /* Pointer to output data struct */ /* Check inherited status */ if( *status != SAI__OK ) return; /* Begin an AST context */ astBegin; /* Begin an NDF context. */ ndfBegin(); /* Find the number of cores/processors available and create a pool of threads of the same size. */ wf = thrGetWorkforce( thrGetNThread( SMF__THREADS, status ), status ); /* Get an identifier for the input NDF. We use NDG (via kpg1Rgndf) instead of calling ndfAssoc directly since NDF/HDS has problems with file names containing spaces, which NDG does not have. */ kpg1Rgndf( "IN", 1, 1, "", &igrp1, &nskymap, status ); ndgNdfas( igrp1, 1, "READ", &indf, status ); /* Map the data array in the input sky map. */ ndfMap( indf, "DATA", "_DOUBLE", "READ", (void **) &in_data, &nel, status ); /* Get the WCS FrameSet from the sky map, together with its pixel index bounds. */ kpg1Asget( indf, 2, 0, 1, 1, sdim, slbnd, subnd, &wcsin, status ); /* Check the current Frame is a SKY frame. */ skyfrm = astGetFrame( wcsin, AST__CURRENT ); if( !astIsASkyFrame( skyfrm ) && *status == SAI__OK ) { ndfMsg( "N", indf ); *status = SAI__ERROR; errRep( " ", " Current Frame in ^N is not a SKY Frame.", status ); } /* Get a copy of the current frame that represents absolute coords rather than offsets. We assume the target is moving if the map represents offsets. */ moving = ( *status == SAI__OK && !strcmp( astGetC( skyfrm, "SkyRefIs" ), "Origin" ) ) ? 1 : 0; abskyfrm = astCopy( skyfrm ); astClear( abskyfrm, "SkyRefIs" ); /* If the ALIGNSYS parameter is TRUE then we align the raw data with the map in the current system of the map, rather than the default ICRS. */ parGet0l( "ALIGNSYS", &alignsys, status ); if( alignsys ) astSetC( abskyfrm, "AlignSystem", astGetC( abskyfrm, "System" ) ); /* Get the Mapping from the Sky Frame to grid axis in the iput map. */ skymap = astGetMapping( wcsin, AST__CURRENT, AST__BASE ); /* Get the pixel interpolation scheme to use. */ parChoic( "INTERP", "NEAREST", "NEAREST,LINEAR,SINC," "SINCSINC,SINCCOS,SINCGAUSS,SOMB,SOMBCOS", 1, pabuf, 10, status ); if( !strcmp( pabuf, "NEAREST" ) ) { interp = AST__NEAREST; nparam = 0; } else if( !strcmp( pabuf, "LINEAR" ) ) { interp = AST__LINEAR; nparam = 0; } else if( !strcmp( pabuf, "SINC" ) ) { interp = AST__SINC; nparam = 1; } else if( !strcmp( pabuf, "SINCSINC" ) ) { interp = AST__SINCSINC; nparam = 2; } else if( !strcmp( pabuf, "SINCCOS" ) ) { interp = AST__SINCCOS; nparam = 2; } else if( !strcmp( pabuf, "SINCGAUSS" ) ) { interp = AST__SINCGAUSS; nparam = 2; } else if( !strcmp( pabuf, "SOMB" ) ) { interp = AST__SOMB; nparam = 1; } else if( !strcmp( pabuf, "SOMBCOS" ) ) { interp = AST__SOMBCOS; nparam = 2; } else if( *status == SAI__OK ) { nparam = 0; *status = SAI__ERROR; msgSetc( "V", pabuf ); errRep( "", "Support not available for INTERP = ^V (programming " "error)", status ); } /* Get an additional parameter vector if required. */ if( nparam > 0 ) parExacd( "PARAMS", nparam, params, status ); /* Get a group of reference time series files to use as templates for the output time series files.*/ ndgAssoc( "REF", 1, &igrp2, &size, &flag, status ); /* Get output file(s) */ kpg1Wgndf( "OUT", igrp2, size, size, "More output files required...", &ogrp, &outsize, status ); /* Get he noise level to add to the output data. */ parGet0d( "SIGMA", &sigma, status ); /* Get any Q and U input maps. */ if( *status == SAI__OK ) { kpg1Rgndf( "QIN", 1, 1, "", &igrpq, &nskymap, status ); ndgNdfas( igrpq, 1, "READ", &indfq, status ); ndfMap( indfq, "DATA", "_DOUBLE", "READ", (void **) &inq_data, &nelqu, status ); if( nelqu != nel && *status == SAI__OK ) { ndfMsg( "Q", indfq ); *status = SAI__ERROR; errRep( "", "Q image '^Q' is not the same size as the I image.", status ); } kpg1Rgndf( "UIN", 1, 1, "", &igrpu, &nskymap, status ); ndgNdfas( igrpu, 1, "READ", &indfu, status ); ndfMap( indfu, "DATA", "_DOUBLE", "READ", (void **) &inu_data, &nelqu, status ); if( nelqu != nel && *status == SAI__OK ) { ndfMsg( "U", indfu ); *status = SAI__ERROR; errRep( "", "U image '^U' is not the same size as the I image.", status ); } if( *status == PAR__NULL ) { ndfAnnul( &indfq, status ); ndfAnnul( &indfu, status ); inq_data = NULL; inu_data = NULL; errAnnul( status ); } else { parGet0d( "ANGROT", &angrot, status ); parGet0d( "PAOFF", &paoff, status ); parGet0l( "PASIGN", &pasign, status ); } } /* Get any common-mode files. */ if( *status == SAI__OK ) { kpg1Rgndf( "COM", size, size, "", &igrpc, &ncom, status ); if( *status == PAR__NULL ) { errAnnul( status ); ncom = 0; } } /* Get any GAI files. */ if( *status == SAI__OK ) { kpg1Rgndf( "GAI", size, size, "", &igrpg, &ngai, status ); if( *status == PAR__NULL ) { errAnnul( status ); ngai = 0; } } /* Get any instrumental polarisation files. */ if( *status == SAI__OK ) { /* First see if the user wants to use the "INSTQ/INSTU" scheme for specifying instrumental polarisation. */ ndfAssoc( "INSTQ", "Read", &indfiq, status ); ndfAssoc( "INSTU", "Read", &indfiu, status ); if( *status == PAR__NULL ) { ndfAnnul( &indfiq, status ); ndfAnnul( &indfiu, status ); errAnnul( status ); } else { msgOut( " ", "Using user-defined IP model", status ); ndfDim( indfiq, 2, dims, &ndim, status ); if( dims[ 0 ] != 32 || dims[ 1 ] != 40 ) { *status = SAI__ERROR; ndfMsg( "N", indfiq ); errRep( " ", "Instrumental polarisation file ^N has bad " "dimensions - should be 32x40.", status ); } else { ndfMap( indfiq, "DATA", "_DOUBLE", "READ", (void **) &qinst_data, &nel, status ); } ndfDim( indfiu, 2, dims, &ndim, status ); if( dims[ 0 ] != 32 || dims[ 1 ] != 40 ) { *status = SAI__ERROR; ndfMsg( "N", indfiu ); errRep( " ", "Instrumental polarisation file ^N has bad " "dimensions - should be 32x40.", status ); } else { ndfMap( indfiu, "DATA", "_DOUBLE", "READ", (void **) &uinst_data, &nel, status ); } } /* If not, see if the user wants to use the Johnstone/Kennedy instrumental polarisation model. The IPDATA parameter gives the path to an HDS container file contining NDFs holding the required IP data for all subarrays. */ if( !qinst_data ) { parGet0c( "IPDATA", ipdata, sizeof(ipdata), status ); if( *status == PAR__NULL ) { errAnnul( status ); } else { msgOutf( " ", "Using Johnstone/Kennedy IP model in %s", status, ipdata ); hdsOpen( ipdata, "READ", &iploc, status ); } } } /* Loop round all the template time series files. */ for( ifile = 1; ifile <= (int) size && *status == SAI__OK; ifile++ ) { /* Start a new NDF context. */ ndfBegin(); /* Create the output NDF by propagating everything from the input, except for quality and variance. */ ndgNdfas( igrp2, ifile, "READ", &indfin, status ); ndfMsg( "FILE", indfin ); msgSeti( "THISFILE", ifile ); msgSeti( "NUMFILES", size ); msgOutif( MSG__NORM, " ", "Simulating ^THISFILE/^NUMFILES ^FILE", status ); ndgNdfpr( indfin, "DATA,HISTORY,LABEL,TITLE,WCS,UNITS,EXTENSION(*)", ogrp, ifile, &indfout, status ); ndfAnnul( &indfin, status ); ndfAnnul( &indfout, status ); /* We now re-open the output NDF and then modify its data values. */ smf_open_file( wf, ogrp, ifile, "UPDATE", 0, &odata, status ); /* Issue a suitable message and abort if anything went wrong. */ if( *status != SAI__OK ) { errRep( FUNC_NAME, "Could not open input template file.", status ); break; } else { if( odata->file == NULL ) { *status = SAI__ERROR; errRep( FUNC_NAME, "No smfFile associated with smfData.", status ); break; } else if( odata->hdr == NULL ) { *status = SAI__ERROR; errRep( FUNC_NAME, "No smfHead associated with smfData.", status ); break; } } /* Check the reference time series contains double precision values. */ smf_dtype_check_fatal( odata, NULL, SMF__DOUBLE, status ); /* Get the total number of data elements, and the number of time slices. */ smf_get_dims( odata, NULL, NULL, NULL, &ntslice, &ndata, NULL, NULL, status ); /* Get the subarray name */ smf_fits_getS( odata->hdr, "SUBARRAY", subarray, sizeof(subarray), status ); /* If we are using the Johnstone/Kennedy IP model, open and map the relevant parameter NDFs within the IPDATA container file. */ if( iploc ) { datFind( iploc, subarray, &cloc, status ); ndfFind( cloc, "C0", &indfc0, status ); ndfDim( indfc0, 2, dims, &ndim, status ); if( dims[ 0 ] != 32 || dims[ 1 ] != 40 ) { *status = SAI__ERROR; ndfMsg( "N", indfc0 ); errRep( " ", "Instrumental polarisation file ^N has bad " "dimensions - should be 32x40.", status ); } else { ndfMap( indfc0, "DATA", "_DOUBLE", "READ", (void **) &c0_data, &nel, status ); } ndfFind( cloc, "P0", &indfp0, status ); ndfDim( indfp0, 2, dims, &ndim, status ); if( dims[ 0 ] != 32 || dims[ 1 ] != 40 ) { *status = SAI__ERROR; ndfMsg( "N", indfp0 ); errRep( " ", "Instrumental polarisation file ^N has bad " "dimensions - should be 32x40.", status ); } else { ndfMap( indfp0, "DATA", "_DOUBLE", "READ", (void **) &p0_data, &nel, status ); } ndfFind( cloc, "P1", &indfp1, status ); ndfDim( indfp1, 2, dims, &ndim, status ); if( dims[ 0 ] != 32 || dims[ 1 ] != 40 ) { *status = SAI__ERROR; ndfMsg( "N", indfp1 ); errRep( " ", "Instrumental polarisation file ^N has bad " "dimensions - should be 32x40.", status ); } else { ndfMap( indfp1, "DATA", "_DOUBLE", "READ", (void **) &p1_data, &nel, status ); } ndfFind( cloc, "ANGC", &indfangc, status ); ndfDim( indfangc, 2, dims, &ndim, status ); if( dims[ 0 ] != 32 || dims[ 1 ] != 40 ) { *status = SAI__ERROR; ndfMsg( "N", indfangc ); errRep( " ", "Instrumental polarisation file ^N has bad " "dimensions - should be 32x40.", status ); } else { ndfMap( indfangc, "DATA", "_DOUBLE", "READ", (void **) &angc_data, &nel, status ); } } /* Open any COM file. */ if( ncom ) { ndgNdfas( igrpc, ifile, "READ", &indfc, status ); ndfDim( indfc, 3, cdims, &ndimc, status ); /* Check its dimensions. */ if( *status == SAI__OK ) { if( ndimc == 1 ) { if( cdims[ 0 ] < (int) ntslice ) { *status = SAI__ERROR; ndfMsg( "C", indfc ); ndfMsg( "R", indfin ); msgSeti( "N", cdims[ 0 ] ); msgSeti( "M", ntslice ); errRep( " ", "Supplied COM file (^C) has ^N time-slices, but " "the reference NDF (^R) has ^M time-slices.", status ); } else { ndfBound( indfc, 3, lbndc, ubndc, &ndimc, status ); ubndc[ 0 ] = lbndc[ 0 ] + ntslice - 1; ndfSect( indfc, 1, lbndc, ubndc, &indfcs, status ); } } else if( ndimc == 3 ) { if( cdims[ 0 ] != 1 || cdims[ 1 ] != 1 ) { *status = SAI__ERROR; ndfMsg( "C", indfc ); errRep( " ", "Supplied 3D COM file (^C) has bad " "dimensions for axis 1 and/or 2 (should " "both be 1 pixel long).", status ); } else if( cdims[ 2 ] < (int) ntslice ) { *status = SAI__ERROR; ndfMsg( "C", indfc ); ndfMsg( "R", indfin ); msgSeti( "N", cdims[ 2 ] ); msgSeti( "M", ntslice ); errRep( " ", "Supplied COM file (^C) has ^N time-slices, but " "the reference NDF (^R) has ^M time-slices.", status ); } else { ndfBound( indfc, 3, lbndc, ubndc, &ndimc, status ); ubndc[ 2 ] = lbndc[ 2 ] + ntslice - 1; ndfSect( indfc, 3, lbndc, ubndc, &indfcs, status ); } } else { *status = SAI__ERROR; ndfMsg( "C", indfc ); msgSeti( "N", ndimc ); errRep( " ", "Supplied COM file (^C) has ^N dimensions - " "must be 3.", status ); } } ndfMap( indfcs, "DATA", "_DOUBLE", "READ", (void **) &inc_data, &nelc, status ); } else { indfcs = NDF__NOID; inc_data = NULL; } /* Open any GAI files. */ if( ngai ) { ndgNdfas( igrpg, ifile, "READ", &indfg, status ); ndfDim( indfg, 3, gdims, &ndimg, status ); /* Check its dimensions, and map it if OK. */ if( *status == SAI__OK ) { if( ndimg != 2 ) { *status = SAI__ERROR; ndfMsg( "C", indfg ); msgSeti( "N", ndimg ); errRep( " ", "Supplied GAI file (^C) has ^N dimensions - " "must be 2.", status ); } else if( gdims[ 0 ] != 32 || gdims[ 1 ] != 40 ) { *status = SAI__ERROR; ndfMsg( "C", indfg ); errRep( " ", "Supplied GAI file (^C) has has bad " "dimensions - should be 32x40.", status ); } } ndfMap( indfg, "DATA", "_DOUBLE", "READ", (void **) &gai_data, &nelg, status ); } else { indfg = NDF__NOID; gai_data = NULL; } /* Fill the output with bad values. */ if( *status == SAI__OK ) { pd = odata->pntr[ 0 ]; for( iel = 0; iel < ndata; iel++ ) *(pd++) = VAL__BADD; } /* Resample the sky map data into the output time series. */ smf_resampmap( wf, odata, abskyfrm, skymap, moving, slbnd, subnd, interp, params, sigma, in_data, odata->pntr[ 0 ], NULL, &ngood, status ); /* Add on any COM data. */ smf_addcom( wf, odata, inc_data, status ); /* Issue a wrning if there is no good data in the output cube. */ if( ngood == 0 ) msgOutif( MSG__NORM, " ", " Output contains no " "good data values.", status ); /* If Q and U maps have been given, allocate room to hold resampled Q and U values, and fill them with bad values. */ if( inq_data && inu_data ) { pq = outq_data = astMalloc( ndata*sizeof( *outq_data ) ); pu = outu_data = astMalloc( ndata*sizeof( *outu_data ) ); if( *status == SAI__OK ) { for( iel = 0; iel < ndata; iel++ ) { *(pu++) = VAL__BADD; *(pq++) = VAL__BADD; } } /* Determine the harmonic to use. */ parGet0i( "HARMONIC", &harmonic, status ); /* If producing the normal 8 Hz harmonic, get the amplitude and phase of a other signals to add onto the 8 Hz signal. */ if( harmonic == 4 ) { parGet0d( "AMP2", &2, status ); parGet0d( "PHASE2", &phase2, status ); parGet0d( "AMP4", &4, status ); parGet0d( "PHASE4", &phase4, status ); parGet0d( "AMP16", &16, status ); parGet0d( "PHASE16", &phase16, status ); } else { amp2 = 0.0; phase2 = 0.0; amp4 = 0.0; phase4 = 0.0; amp16 = 0.0; phase16 = 0.0; } /* Allocate room for an array to hold the angle from the Y pixel axis in the sky map to the focal plane Y axis, in radians, at each time slice. Positive rotation is in the same sense as rotation from focal plane X to focal plane Y. */ ang_data = astMalloc( ntslice*sizeof( *ang_data ) ); /* Resample them both into 3D time series. These Q/U values arw with respect to the sky image Y axis. */ smf_resampmap( wf, odata, abskyfrm, skymap, moving, slbnd, subnd, interp, params, sigma, inq_data, outq_data, ang_data, &ngood, status ); smf_resampmap( wf, odata, abskyfrm, skymap, moving, slbnd, subnd, interp, params, sigma, inu_data, outu_data, NULL, &ngood, status ); /* Combine these time series with the main output time series so that the main output is analysed intensity. */ smf_uncalc_iqu( wf, odata, odata->pntr[ 0 ], outq_data, outu_data, ang_data, pasign, AST__DD2R*paoff, AST__DD2R*angrot, amp2, AST__DD2R*phase2, amp4, AST__DD2R*phase4, amp16, AST__DD2R*phase16, qinst_data, uinst_data, c0_data, p0_data, p1_data, angc_data, harmonic, status ); /* Release work space. */ outq_data = astFree( outq_data ); outu_data = astFree( outu_data ); ang_data = astFree( ang_data ); } /* Factor in any GAI data. */ smf_addgai( wf, odata, gai_data, status ); /* Close the output time series file. */ smf_close_file( wf, &odata, status ); /* Close the IP data container for the current subarray, if it is open. */ if( cloc ) datAnnul( &cloc, status ); /* End the NDF context. */ ndfEnd( status ); } /* Close any input data file that is still open due to an early exit from the above loop. */ if( odata != NULL ) { smf_close_file( wf, &odata, status ); odata = NULL; } /* Free remaining resources. */ if( igrp1 != NULL) grpDelet( &igrp1, status); if( igrp2 != NULL) grpDelet( &igrp2, status); if( igrpq != NULL) grpDelet( &igrpq, status); if( igrpu != NULL) grpDelet( &igrpu, status); if( igrpc != NULL) grpDelet( &igrpc, status); if( igrpg != NULL) grpDelet( &igrpg, status); if( ogrp != NULL) grpDelet( &ogrp, status); if( iploc ) datAnnul( &iploc, status ); /* End the NDF context. */ ndfEnd( status ); /* End the tile's AST context. */ astEnd; /* Issue a status indication.*/ if( *status == SAI__OK ) { msgOutif(MSG__VERB," ",TASK_NAME " succeeded, time series written.", status); } else { msgOutif(MSG__VERB," ",TASK_NAME " failed.", 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 {
// Reads an NDF into a numpy array static PyObject* pyndf_read(NDF *self, PyObject *args) { int i; const char *comp; if(!PyArg_ParseTuple(args, "s:pyndf_read", &comp)) return NULL; // series of declarations in an attempt to avoid problem with // goto fail const int MXLEN=32; char type[MXLEN+1]; size_t nbyte; int npix, nelem; // Return None if component does not exist int state, status = SAI__OK; errBegin(&status); ndfState(self->_ndfid, comp, &state, &status); if (raiseNDFException(&status)) return NULL; if(!state) Py_RETURN_NONE; PyArrayObject* arr = NULL; // Get dimensions, reverse order to account for C vs Fortran int idim[NDF__MXDIM]; npy_intp rdim[NDF__MXDIM]; int ndim; errBegin(&status); ndfDim(self->_ndfid, NDF__MXDIM, idim, &ndim, &status); if (raiseNDFException(&status)) return NULL; // Reverse order to account for C vs Fortran for(i=0; i<ndim; i++) rdim[i] = idim[ndim-i-1]; // Determine the data type errBegin(&status); ndfType(self->_ndfid, comp, type, MXLEN+1, &status); if (raiseNDFException(&status)) return NULL; // Create array of correct dimensions and type to save data to int npytype = ndftype2numpy( type, &nbyte ); if (npytype == 0) return NULL; arr = (PyArrayObject*) PyArray_SimpleNew(ndim, rdim, npytype); if(arr == NULL) goto fail; // get number of elements, allocate space, map, store errBegin(&status); ndfSize(self->_ndfid, &npix, &status); if (raiseNDFException(&status)) goto fail; void *pntr[1]; errBegin(&status); ndfMap(self->_ndfid, comp, type, "READ", pntr, &nelem, &status); if (raiseNDFException(&status)) goto fail; if(nelem != npix){ PyErr_SetString(PyExc_IOError, "ndf_read error: number of elements different from number expected"); goto fail; } memcpy(arr->data, pntr[0], npix*nbyte); errBegin(&status); ndfUnmap(self->_ndfid, comp, &status); if (raiseNDFException(&status)) goto fail; return Py_BuildValue("N", PyArray_Return(arr)); fail: Py_XDECREF(arr); return NULL; };
static PyObject* pyndf_aread(NDF *self, PyObject *args) { int iaxis; const char *MMOD = "READ"; const char *comp; if(!PyArg_ParseTuple(args, "si:pyndf_aread", &comp, &iaxis)) return NULL; int status = SAI__OK; errBegin(&status); int naxis = tr_iaxis(self->_ndfid, iaxis, &status); // Return None if component does not exist int state; ndfAstat(self->_ndfid, comp, naxis, &state, &status); if (raiseNDFException(&status)) return NULL; if(!state) Py_RETURN_NONE; // Get dimensions int idim[NDF__MXDIM], ndim; errBegin(&status); ndfDim(self->_ndfid, NDF__MXDIM, idim, &ndim, &status); if (raiseNDFException(&status)) return NULL; // get number for particular axis in question. int nelem = idim[naxis-1]; // Determine the data type const int MXLEN=33; char type[MXLEN]; errBegin(&status); ndfAtype(self->_ndfid, comp, naxis, type, MXLEN, &status); if (raiseNDFException(&status)) return NULL; // Create array of correct dimensions and type to save data to size_t nbyte; ndim = 1; npy_intp dim[1] = {nelem}; PyArrayObject* arr = NULL; int npytype = ndftype2numpy( type, &nbyte ); if (npytype ==0) return NULL; arr = (PyArrayObject*) PyArray_SimpleNew(ndim, dim, npytype); if(arr == NULL) goto fail; // map, store, unmap int nread; void *pntr[1]; errBegin(&status); ndfAmap(self->_ndfid, comp, naxis, type, MMOD, pntr, &nread, &status); if (raiseNDFException(&status)) goto fail; if(nelem != nread){ printf("nread = %d, nelem = %d, iaxis = %d, %d\n",nread,nelem,iaxis,naxis); PyErr_SetString(PyExc_IOError, "ndf_aread error: number of elements different from number expected"); goto fail; } memcpy(arr->data, pntr[0], nelem*nbyte); errBegin(&status); ndfAunmp(self->_ndfid, comp, naxis, &status); if (raiseNDFException(&status)) goto fail; return Py_BuildValue("N", PyArray_Return(arr)); fail: Py_XDECREF(arr); return NULL; };