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

}
Пример #4
0
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;
}
Пример #5
0
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", &amp2, status );
            parGet0d( "PHASE2", &phase2, status );
            parGet0d( "AMP4", &amp4, status );
            parGet0d( "PHASE4", &phase4, status );
            parGet0d( "AMP16", &amp16, 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);
   }
}
Пример #6
0
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 {
Пример #7
0
// 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;
};
Пример #8
0
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;

};