void save_data_in_fits_file(const char* file_name, double* data,
                            size_t num_of_elements)
{
    fitsfile* file;
    int status = 0;
    char* ttype[] = { "SAMPLE" };
    char* tform[] = { "1D" };
    char* tunit[] = { "" };

    if (fits_create_file(&file, file_name, &status) != 0)
        goto error;

    if (fits_create_tbl(file, BINARY_TBL, 0, 1, ttype, tform, tunit,
                        "DECOMPR", &status) != 0)
        goto error;

    if (fits_write_col(file, TDOUBLE, 1, 1, 1, num_of_elements, data,
                       &status) != 0)
        goto error;

    fits_close_file(file, &status);
    return;

error:
    fits_report_error(stderr, status);
    if (file != NULL)
        fits_close_file(file, &status);
    exit(1);
}
Beispiel #2
0
void he_write_healpix_map(float **tmap,int nfields,long nside,char *fname)
{
  fitsfile *fptr;
  int ii,status=0;
  char *ttype[]={"T","Q","U"};
  char *tform[]={"1E","1E","1E"};
  char *tunit[]={"mK","mK","mK"};

  if((nfields!=1)&&(nfields!=3)) {
    fprintf(stderr,"CRIME: nfields must be 1 or 3\n");
    exit(1);
  }

  fits_create_file(&fptr,fname,&status);
  fits_create_tbl(fptr,BINARY_TBL,0,nfields,ttype,tform,
		  tunit,"BINTABLE",&status);
  fits_write_key(fptr,TSTRING,"PIXTYPE","HEALPIX","HEALPIX Pixelisation",
		 &status);

  fits_write_key(fptr,TSTRING,"ORDERING","RING",
		 "Pixel ordering scheme, either RING or NESTED",&status);
  fits_write_key(fptr,TLONG,"NSIDE",&nside,
		 "Resolution parameter for HEALPIX",&status);
  fits_write_key(fptr,TSTRING,"COORDSYS","G",
		 "Pixelisation coordinate system",&status);
  fits_write_comment(fptr,
		     "G = Galactic, E = ecliptic, C = celestial = equatorial",
		     &status);
  for(ii=0;ii<nfields;ii++) {
    fits_write_col(fptr,TFLOAT,ii+1,1,1,nside2npix(nside),tmap[ii],&status);
  }
  fits_close_file(fptr, &status);
}
Beispiel #3
0
int write_map(const char *filename, double *intensity, double *q, double *u, long nrows)
{
    
    fitsfile *fptr;
    int status = 0;
    int hdutype;
    int tfields=3;
    char extname[] = "BINTABLE";   /* extension name */
    char *ttype[] = { "I","Q","U" };
    char *tform[] = { "1E","1E","1E" };
    char *tunit[] = { " "," ", " " };
    if (fits_create_file(&fptr, filename, &status)) 
    fprintf(stderr, "%s (%d): Could not create new fits file.\n", 
        __FILE__, __LINE__);

    /* move to 1st HDU  */
    fits_movabs_hdu(fptr, 1, &hdutype, &status);
    //long nrows = 12L*nside*nside*2;
    //long nside = sqrtl(nrows/12L);
    long nside = 1024; //FIXME compute it

    /* append a new empty binary table onto the FITS file */
    fits_create_tbl( fptr, BINARY_TBL, nrows, tfields, ttype, tform,
            tunit, extname, &status);

    fits_write_key(fptr, TSTRING, "ORDERING", "NESTED", 
             "Pixel ordering scheme, either RING or NESTED", &status);

    fits_write_key(fptr, TLONG, "NSIDE", &nside, "Resolution parameter for HEALPIX", &status);
    long firstrow  = 1;  /* first row in table to write   */
    long firstelem = 1;  /* first element in row  (ignored in ASCII tables)  */

    if (fits_write_col(fptr, TDOUBLE, 1, firstrow, firstelem, nrows, intensity,
             &status))
    fprintf(stderr, "%s (%d): Could not write signal.\n", __FILE__, __LINE__);
    if (fits_write_col(fptr, TDOUBLE, 2, firstrow, firstelem, nrows, q,
             &status))
    fprintf(stderr, "%s (%d): Could not write signal.\n", __FILE__, __LINE__);
    if (fits_write_col(fptr, TDOUBLE, 3, firstrow, firstelem, nrows, u,
             &status))
    fprintf(stderr, "%s (%d): Could not write signal.\n", __FILE__, __LINE__);

    fits_close_file(fptr, &status);

    return true;
}
void FitsFile::WriteTableCell(int row, int col, const bool *data, size_t size)
{
	std::vector<char> dataChar(size);
	int status = 0;
	for(size_t i = 0;i<size;++i)
	{
		dataChar[i] = data[i] ? 1 : 0;
	}
	fits_write_col(_fptr, TBIT, col, row, 1, size, dataChar.data(), &status);
}
Beispiel #5
0
void FitsFile::WriteTableCell(int row, int col, const bool *data, size_t size)
{
	char *dataChar = new char[size];
	int status = 0;
	for(size_t i = 0;i<size;++i)
	{
		dataChar[i] = data[i] ? 1 : 0;
	}
	fits_write_col(_fptr, TBIT, col, row, 1, size, dataChar, &status);
	delete[] dataChar;
}
Beispiel #6
0
void OutputFileFITS::_write(int ncol, std::vector<T>& buff, int type, long frow, long lrow) {
	int status = 0;
	if(!isOpened())
		throwException("Error in OutputFileFITS::_write() ", status);

	long nelem = lrow - frow + 1;

	std::vector<T> buffptr = buff;
	fits_write_col(infptr, type, ncol+1, frow+1, 1, nelem, &buffptr[0], &status);

	if(status)
		throwException("Error in OutputFileFITS::_write() ", status);
}
Beispiel #7
0
void OutputFileFITS::_writev(int ncol, std::vector< std::vector<T> >& buff, int type, long frow, long lrow) {
	int status = 0;
	if(!isOpened())
		throwException("Error in OutputFileFITS::_writev() ", status);

	long nelem = lrow - frow + 1;
	unsigned int size = buff[0].size();
	T* buffptr = new T[nelem*size];
	for(unsigned int row=frow; row<lrow+1; row++)
	{
		for(unsigned int i=0; i<size; i++)
		{
			buffptr[row*size + i] = buff[row][i];
		}
	}

	fits_write_col(infptr, type, ncol+1, frow+1, 1, nelem*size, buffptr, &status);

	delete[] buffptr;

	if(status)
		throwException("Error in OutputFileFITS::_writev() ", status);
}
Beispiel #8
0
void OutputFileFITS::writeString(int ncol, std::vector< std::vector<char> >& buff, long frow, long lrow)
{
	int status = 0;
	if(!isOpened())
		throwException("Error in OutputFileFITS::writeString() ", status);

	long nelem = lrow - frow + 1;
	unsigned int size = buff[0].size();
	char** buffptrs = new char*[nelem];
	for(unsigned int row=frow; row<lrow+1; row++)
	{
		buffptrs[row] = new char[buff[0].size()];
		memcpy(buffptrs[row], &buff[row][0], buff[0].size());
	}

	fits_write_col(infptr, TSTRING, ncol+1, frow+1, 1, nelem, buffptrs, &status);

	for(unsigned int row=frow; row<lrow+1; row++)
		delete buffptrs[row];
	delete[] buffptrs;

	if(status)
		throwException("Error in OutputFileFITS::writeString() ", status);
}
int psrfits_write_ephem(struct psrfits *pf, FILE *parfile) {
    // Read a pulsar ephemeris (par file) and put it into
    // the psrfits PSREPHEM table.  Only minimal checking
    // is done.
   
    // Get status
    int *status = &(pf->status);

    // Save current HDU, move to psrephem table
    int hdu;
    fits_get_hdu_num(pf->fptr, &hdu);
    fits_movnam_hdu(pf->fptr, BINARY_TBL, "PSREPHEM", 0, status);

    // Loop over lines in par file
    int row=1, col, dtype;
    double dval;
    int ival;
    long double ldval;
    char line[256], *ptr, *saveptr, *key, *val;
    while (fgets(line, 256, parfile)!=NULL) {

        // Convert tabs to spaces
        while ((ptr=strchr(line,'\t'))!=NULL) { *ptr=' '; }

        // strip leading whitespace
        ptr = line;
        while (*ptr==' ') { ptr++; }

        // Identify comments or blank lines
        if (line[0]=='\n' || line[0]=='#' || 
                (line[0]=='C' && line[1]==' '))
            continue;

        // Split into key/val (ignore fit flag and error)
        key = strtok_r(line,  " ", &saveptr);
        val = strtok_r(NULL, " ", &saveptr);
        if (key==NULL || val==NULL) continue; // TODO : complain?

        // Deal with any special cases here
        if (strncmp(key, "PSR", 3)==0)  {

            // PSR(J) -> PSR_NAME
            fits_get_colnum(pf->fptr,CASEINSEN,"PSR_NAME",&col,status);
            fits_write_col(pf->fptr,TSTRING,col,row,1,1,&val,status);

        } else if (strncmp(key, "RA", 2)==0) {

            // RA -> RAJ
            fits_get_colnum(pf->fptr,CASEINSEN,"RAJ",&col,status);
            fits_write_col(pf->fptr,TSTRING,col,row,1,1,&val,status);

        } else if (strncmp(key, "DEC", 3)==0) {

            // DEC -> DECJ
            fits_get_colnum(pf->fptr,CASEINSEN,"DECJ",&col,status);
            fits_write_col(pf->fptr,TSTRING,col,row,1,1,&val,status);

        } else if (key[0]=='E' && key[1]=='\0') {

            // E -> ECC
            dval = atof(val);
            fits_get_colnum(pf->fptr,CASEINSEN,"ECC",&col,status);
            fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&dval,status);

        } else if (strncmp(key, "F0", 2)==0) {

            // F is converted to mHz and split into int/frac
            ldval = strtold(val,NULL) * 1000.0; // Hz->mHz
            ival = (int)ldval;
            dval = ldval - (long double)ival;
            fits_get_colnum(pf->fptr,CASEINSEN,"IF0",&col,status);
            fits_write_col(pf->fptr,TINT,col,row,1,1,&ival,status);
            fits_get_colnum(pf->fptr,CASEINSEN,"FF0",&col,status);
            fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&dval,status);

        } else if (strncmp(key, "TZRMJD", 6)==0) {

            // TZRMJD is split into int/frac
            ldval = strtold(val,NULL);
            ival = (int)ldval;
            dval = ldval - (long double)ival;
            fits_get_colnum(pf->fptr,CASEINSEN,"TZRIMJD",&col,status);
            fits_write_col(pf->fptr,TINT,col,row,1,1,&ival,status);
            fits_get_colnum(pf->fptr,CASEINSEN,"TZRFMJD",&col,status);
            fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&dval,status);

        } else {

            // Find column, skip/warn if this one isn't present
            fits_get_colnum(pf->fptr,CASEINSEN,key,&col,status);
            if (*status==COL_NOT_FOUND) {
#if (DEBUGOUT)
                fprintf(stderr, 
                        "psrfits_write_epherm warning: Couldn't find keyword %s "
                        "in ephemeris table.\n",
                        key);
#endif
                *status=0;
                continue;
            }

            // Need to convert string to appropriate column data type
            // and then write it to the column.  These should all be
            // either double int or string.
            fits_get_coltype(pf->fptr,col,&dtype,NULL,NULL,status);
            if (dtype==TDOUBLE || dtype==TFLOAT) { 
                dval = atof(val);
                fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&dval,status);
            } else if (dtype==TINT || dtype==TLONG || dtype==TSHORT) {
                ival = atoi(val);
                fits_write_col(pf->fptr,TINT,col,row,1,1,&ival,status);
            } else if (dtype==TSTRING) {
                fits_write_col(pf->fptr,TSTRING,col,row,1,1,&val,status);
            } else {
                fprintf(stderr, "psrfits_write_ephem warning: "
                        "Unhandled column datatype (key=%s)\n", key);
                continue;
            }
        }

        // sucess/failure
        if (*status) {
            fprintf(stderr, "psrfits_write_ephem failed: key=%s val=%s\n",
                    key, val);
            fits_report_error(stderr, *status);
            *status=0;
        } 
#if 0  // DEBUG
        else {
            fprintf(stderr, "psrfits_write_ephem success: key=%s val=%s\n",
                    key, val);
        }
#endif

    }

    // Go back to orig HDU
    fits_movabs_hdu(pf->fptr, hdu, NULL, status);

    return *status;
}
int psrfits_write_polycos(struct psrfits *pf, struct polyco *pc, int npc) {

    // Usual setup
    int *status = &(pf->status);

    // If mode!=fold, exit?

    // Save current HDU, move to polyco table
    int hdu;
    fits_get_hdu_num(pf->fptr, &hdu);
    fits_movnam_hdu(pf->fptr, BINARY_TBL, "POLYCO", 0, status);

    int itmp;
    double dtmp;
    char datestr[32], ctmp[32];
    char *cptr;
    fits_get_system_time(datestr, &itmp, status);
    int i, col, n_written=0; 
    long row;
    fits_get_num_rows(pf->fptr, &row, status); // Start at end of table
    for (i=0; i<npc; i++) {

        // Only write polycos that were used
        if (!pc[i].used) continue; 

        // Go to next row (1-based index)
        row++;

        cptr = datestr;
        fits_get_colnum(pf->fptr,CASEINSEN,"DATE_PRO",&col,status);
        fits_write_col(pf->fptr,TSTRING,col,row,1,1,&cptr,status);

        sprintf(ctmp, "11.005"); // Tempo version?
        cptr = ctmp;
        fits_get_colnum(pf->fptr,CASEINSEN,"POLYVER",&col,status);
        fits_write_col(pf->fptr,TSTRING,col,row,1,1,&cptr,status);

        fits_get_colnum(pf->fptr,CASEINSEN,"NSPAN",&col,status);
        fits_write_col(pf->fptr,TINT,col,row,1,1,&(pc[i].nmin),status);

        fits_get_colnum(pf->fptr,CASEINSEN,"NCOEF",&col,status);
        fits_write_col(pf->fptr,TINT,col,row,1,1,&(pc[i].nc),status);

        sprintf(ctmp,"%d", pc[i].nsite); // XXX convert to letter?
        cptr = ctmp;
        fits_get_colnum(pf->fptr,CASEINSEN,"NSITE",&col,status);
        fits_write_col(pf->fptr,TSTRING,col,row,1,1,&cptr,status);

        fits_get_colnum(pf->fptr,CASEINSEN,"REF_FREQ",&col,status);
        fits_write_col(pf->fptr,TFLOAT,col,row,1,1,&(pc[i].rf),status);

        // XXX needs to be accurate??
        dtmp=0.0;
        fits_get_colnum(pf->fptr,CASEINSEN,"PRED_PHS",&col,status);
        fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&dtmp,status);

        dtmp = (double)pc[i].mjd + pc[i].fmjd;
        fits_get_colnum(pf->fptr,CASEINSEN,"REF_MJD",&col,status);
        fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&dtmp,status);

        fits_get_colnum(pf->fptr,CASEINSEN,"REF_PHS",&col,status);
        fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&(pc[i].rphase),status);

        fits_get_colnum(pf->fptr,CASEINSEN,"REF_F0",&col,status);
        fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&(pc[i].f0),status);

        // XXX don't parse this yet
        dtmp=-6.0;
        fits_get_colnum(pf->fptr,CASEINSEN,"LGFITERR",&col,status);
        fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&dtmp,status);

        fits_get_colnum(pf->fptr,CASEINSEN,"COEFF",&col,status);
        fits_write_col(pf->fptr,TDOUBLE,col,row,1,pc[i].nc,pc[i].c,status);

        n_written++;
    }

    // Update polyco block count, only if new info was added
    if (n_written) {
        itmp = row;
        fits_get_colnum(pf->fptr,CASEINSEN,"NPBLK",&col,status);
        for (i=1; i<=row; i++) 
            fits_write_col(pf->fptr,TINT,col,i,1,1,&itmp,status);
    }

    // Flush buffers (so files are valid as they are created)
    fits_flush_file(pf->fptr, status);

    // Go back to orig HDU
    fits_movabs_hdu(pf->fptr, hdu, NULL, status);

    return *status;
}
int psrfits_write_subint(struct psrfits *pf) {
    int row, *status, nchan, nivals, mode, out_nbytes;
    float ftmp;
    struct hdrinfo *hdr;
    struct subint *sub;

    hdr = &(pf->hdr);        // dereference the ptr to the header struct
    sub = &(pf->sub);        // dereference the ptr to the subint struct
    status = &(pf->status);  // dereference the ptr to the CFITSIO status
    nchan = hdr->nchan / hdr->ds_freq_fact;
    if (hdr->onlyI)
        nivals = nchan;
    else
        nivals = nchan * hdr->npol;
    mode = psrfits_obs_mode(hdr->obs_mode);
    if (mode==fold)
        out_nbytes = sub->bytes_per_subint / hdr->ds_freq_fact;
    else {
        out_nbytes = sub->bytes_per_subint / (hdr->ds_freq_fact * hdr->ds_time_fact);
        if (hdr->onlyI)
            out_nbytes /= hdr->npol;
    }

    // Create the initial file or change to a new one if needed.
    // Stay with a single file for fold mode.
    if (pf->filenum==0 || 
            ( (mode==search || pf->multifile==1) 
              && pf->rownum > pf->rows_per_file)) {
        if (pf->filenum) {
            printf("Closing file '%s'\n", pf->filename);
            fits_close_file(pf->fptr, status);
        }
        psrfits_create(pf);
    }

    row = pf->rownum;
    fits_write_col(pf->fptr, TDOUBLE, 1, row, 1, 1, &(sub->tsubint), status);
    fits_write_col(pf->fptr, TDOUBLE, 2, row, 1, 1, &(sub->offs), status);
    fits_write_col(pf->fptr, TDOUBLE, 3, row, 1, 1, &(sub->lst), status);
    fits_write_col(pf->fptr, TDOUBLE, 4, row, 1, 1, &(sub->ra), status);
    fits_write_col(pf->fptr, TDOUBLE, 5, row, 1, 1, &(sub->dec), status);
    fits_write_col(pf->fptr, TDOUBLE, 6, row, 1, 1, &(sub->glon), status);
    fits_write_col(pf->fptr, TDOUBLE, 7, row, 1, 1, &(sub->glat), status);
    ftmp = (float) sub->feed_ang;
    fits_write_col(pf->fptr, TFLOAT, 8, row, 1, 1, &ftmp, status);
    ftmp = (float) sub->pos_ang;
    fits_write_col(pf->fptr, TFLOAT, 9, row, 1, 1, &ftmp, status);
    ftmp = (float) sub->par_ang;
    fits_write_col(pf->fptr, TFLOAT, 10, row, 1, 1, &ftmp, status);
    ftmp = (float) sub->tel_az;
    fits_write_col(pf->fptr, TFLOAT, 11, row, 1, 1, &ftmp, status);
    ftmp = (float) sub->tel_zen;
    fits_write_col(pf->fptr, TFLOAT, 12, row, 1, 1, &ftmp, status);
    fits_write_col(pf->fptr, TDOUBLE, 13, row, 1, nchan, sub->dat_freqs, status);
    fits_write_col(pf->fptr, TFLOAT, 14, row, 1, nchan, sub->dat_weights, status);
    fits_write_col(pf->fptr, TFLOAT, 15, row, 1, nivals, sub->dat_offsets, status);
    fits_write_col(pf->fptr, TFLOAT, 16, row, 1, nivals, sub->dat_scales, status);
    if (mode==search) {
        if (hdr->nbits==4) pf_8bit_to_4bit(pf);
        fits_write_col(pf->fptr, TBYTE, 17, row, 1, out_nbytes, 
                       sub->rawdata, status);
    } else if (mode==fold) { 
        // Fold mode writes floats for now..
        fits_write_col(pf->fptr, TFLOAT, 17, row, 1, out_nbytes/sizeof(float), 
                       sub->data, status);
    }

    // Flush the buffers if not finished with the file
    // Note:  this use is not entirely in keeping with the CFITSIO
    //        documentation recommendations.  However, manually 
    //        correcting NAXIS2 and using fits_flush_buffer()
    //        caused occasional hangs (and extrememly large
    //        files due to some infinite loop).
    fits_flush_file(pf->fptr, status);

    // Print status if bad
    if (*status) {
        fprintf(stderr, "Error writing subint %d:\n", pf->rownum);
        fits_report_error(stderr, *status);
        fflush(stderr);
    }

    // Now update some key values if no CFITSIO errors
    if (!(*status)) {
        pf->rownum++;
        pf->tot_rows++;
        pf->N += hdr->nsblk / hdr->ds_time_fact;
        pf->T += sub->tsubint;

        // For fold mode, print info each subint written
        if (mode==fold && pf->quiet!=1) {
            printf("Wrote subint %d (total time %.1fs)\n", pf->rownum-1, pf->T);
            fflush(stdout);
        }

    }

    return *status;
}
Beispiel #12
0
int hpic_fits_vecindx_write(char *filename, char *creator, char *extname,
                            char *comment, hpic_vec_int * indx,
                            hpic_vec_fltarr * vecs, char **vecnames,
                            char **vecunits, hpic_keys * keys)
{

  size_t i, j, k, m;
  fitsfile *fp;
  int ret = 0;
  int bitpix = SHORT_IMG;
  int nax = 0;
  long axes[] = { 0, 0 };
  int total;
  int type;
  long rows;
  long frow = 1;
  long fsamp = 1;
  size_t veclen;
  char **vectypes;
  char **names;
  char **units;
  size_t nvecs = hpic_vec_fltarr_n_get(vecs);
  hpic_vec_float *tempvec;

  if (nvecs == 0) {
    HPIC_ERROR(HPIC_ERR_FITS, "must specify more than zero vectors!");
  }
  if (!indx) {
    HPIC_ERROR(HPIC_ERR_ACCESS, "index vector is not allocated");
  }
  for (i = 0; i < nvecs; i++) {
    tempvec = hpic_vec_fltarr_get(vecs, i);
    if (!tempvec) {
      HPIC_ERROR(HPIC_ERR_ACCESS, "input vector is not allocated");
    }
  }
  vectypes = hpic_strarr_alloc(nvecs + 1);
  names = hpic_strarr_alloc(nvecs + 1);
  units = hpic_strarr_alloc(nvecs + 1);

  veclen = hpic_vec_int_n_get(indx);
  for (i = 0; i < nvecs; i++) {
    tempvec = hpic_vec_fltarr_get(vecs, i);
    if (veclen != hpic_vec_float_n_get(tempvec)) {
      HPIC_ERROR(HPIC_ERR_FITS, "all vectors must have the same length");
    }
  }

  /* setup column parameters */

  strncpy(vectypes[0], "1J", HPIC_STRNL);
  strncpy(names[0], "INDEX", HPIC_STRNL);
  strncpy(units[0], "", HPIC_STRNL);
  for (i = 1; i < nvecs + 1; i++) {
    strncpy(vectypes[i], "1E", HPIC_STRNL);
    strncpy(names[i], vecnames[i - 1], HPIC_STRNL);
    strncpy(units[i], vecunits[i - 1], HPIC_STRNL);
  }

  /* create file */
  if (fits_create_file(&fp, filename, &ret)) {
    fitserr(ret, "hpic_fits_vecindx_write:  creating file");
  }

  /* create empty primary image */
  if (fits_create_img(fp, bitpix, nax, axes, &ret)) {
    fitserr(ret, "hpic_fits_vecindx_write:  creating primary image");
  }

  /* write header */
  if (fits_write_comment(fp, "    ", &ret)) {
    fitserr(ret, "hpic_fits_vecindx_write:  writing header comment 1");
  }
  if (fits_write_comment(fp, comment, &ret)) {
    fitserr(ret, "hpic_fits_vecindx_write:  writing header comment 2");
  }
  if (fits_write_comment(fp, "    ", &ret)) {
    fitserr(ret, "hpic_fits_vecindx_write:  writing header comment 3");
  }
  if (fits_write_date(fp, &ret)) {
    fitserr(ret, "hpic_fits_vecindx_write:  writing date");
  }
  if (fits_write_key
      (fp, TSTRING, "CREATOR", creator, "Software creating the map", &ret)) {
    fitserr(ret, "hpic_fits_vecindx_write:  writing creator");
  }

  /* write extension */
  if (fits_create_tbl
      (fp, BINARY_TBL, (long)veclen, (int)(nvecs + 1), names, vectypes, units,
       extname, &ret)) {
    fitserr(ret, "hpic_fits_vecindx_write:  creating binary table");
  }
  if (fits_movabs_hdu(fp, 2, &type, &ret)) {
    fitserr(ret, "hpic_fits_vecindx_write:  moving to extension");
  }

  /* write mandatory keywords */
  if (fits_write_comment(fp, "     ", &ret)) {
    fitserr(ret, "hpic_fits_vecindx_write:  writing ext comment 1");
  }
  if (fits_write_comment
      (fp, "-----------------------------------------------", &ret)) {
    fitserr(ret, "hpic_fits_vecindx_write:  writing ext comment 2");
  }
  if (fits_write_comment(fp, "            Data Specific Keywords    ", &ret)) {
    fitserr(ret, "hpic_fits_vecindx_write:  writing ext comment 3");
  }
  if (fits_write_comment
      (fp, "-----------------------------------------------", &ret)) {
    fitserr(ret, "hpic_fits_vecindx_write:  writing ext comment 4");
  }
  if (fits_write_comment(fp, "      ", &ret)) {
    fitserr(ret, "hpic_fits_vecindx_write:  writing comment 5");
  }

  /* write optional keywords */

  hpic_keys_write(keys, fp, &ret);

  /* write the data and clean up */
  if (fits_write_col
      (fp, TINT, 1, frow, fsamp, (long)veclen, indx->data, &ret)) {
    fitserr(ret, "hpic_fits_vecindx_write:  writing index column");
  }
  for (i = 0; i < nvecs; i++) {
    tempvec = hpic_vec_fltarr_get(vecs, i);
    if (fits_write_col
        (fp, TFLOAT, (int)(i + 2), frow, fsamp, (long)veclen, tempvec->data,
         &ret)) {
      fitserr(ret, "hpic_fits_vecindx_write:  writing data column");
    }
  }
  
  hpic_strarr_free(vectypes, nvecs + 1);
  hpic_strarr_free(names, nvecs + 1);
  hpic_strarr_free(units, nvecs + 1);

  if (fits_close_file(fp, &ret)) {
    fitserr(ret, "hpic_fits_vecindx_write:  closing file");
  }

  return ret;
}
Beispiel #13
0
int CDfits_write_subint( int num_cycles, int num_bins, int num_chans, int num_pols )
{
  int status;
  int j, k;
  int nscl, ndata;
  float x;
  double dx, dy, dz, ds, dc;
    
  int nrows, ncols, col;
  char *ttype[19], *tform[19], *tunit[19];
  long naxes[3];
  
  char Cstr16[16], Estr16[16], Istr16[16];

#define ASTR_LEN 32
  char astr[ ASTR_LEN ];

  
  /* BEGIN */

  nscl =  num_chans * num_pols;
  ndata = num_bins * nscl;

  status = 0;
  
  /* Increment SUBINT counter and if first SUBINT, write header */
  if( ++subint_cnt == 1 ) {

    /* Add START TIME to primary HDU */
    /* Move to primary HDU */
    fits_movabs_hdu( cfitsptr, 1, NULL, &status );

    if( bat_to_ut_str( astr, ASTR_LEN, newcycle.WBpsr_timer_start_bat ) < 0 ) {
      return( -9999 );
    }
    
    astr[10] = '\0';
    fits_update_key( cfitsptr, TSTRING, "STT_DATE", astr,
		     "Start UT date (YYYY-MM-DD)", &status);
    fits_update_key( cfitsptr, TSTRING, "STT_TIME", &astr[11],
		     "Start UT (hh:mm:ss)", &status);

    bat_to_mjd( &dx, newcycle.WBpsr_timer_start_bat );

    dz = modf( dx, &dy );   /* dz = fractional day,  dy = days */    

    j = (int) floor( ( dy + 0.1 ) );  /* Add 0.1d to make sure we get the correct one */
    fits_update_key( cfitsptr, TINT, "STT_IMJD", &j,
		     "Start MJD (UTC days) (J)", &status);
    
    dy = dz * 86400.0;   /* This should be an exact second - timer starts on 1pps */
    k = (int) floor( ( dy + 0.1 ) );   /* Add 0.1s to make sure we get the correct one */
    fits_update_key( cfitsptr, TINT, "STT_SMJD", &k,
		     "[s] Start time (sec past UTC 00h) (J)", &status);

    /* Add in offset = 1 - start phase - one bin !!!!!!!!!!! */
    /* 9 Jun 2004 - remove one bin offset - wrong !! */
    /* Was:
       dz = 1.0 - modf( newcycle.WBpsr_start_psr_phase, &dx ) - 1.0 / (double) num_bins; 
       dz *= (*c_c).pulsar_period;
       Now: the offset time is available directly */
    dz = newcycle.WBpsr_timer_start_offset_secs;
    
    /* Quantise to 128MHz clock cycles */
    dz *= 128.0E06;
    dx = floor( dz );
    dx /= 128.0E06;
    
    fits_update_key( cfitsptr, TDOUBLE, "STT_OFFS", &dx,
		     "[s] Start time offset (D)", &status);

    /* LST provided corresponds to integ. start time, i.e. oldcycle.bat */
    bat_to_ut_secs( &dy, oldcycle.bat );
    dy += dx;
    dx = scan_start_time_secs - dy;
    if( dx < -43200.0 ) dx += 86400.0;
    if( dx >  43200.0 ) dx -= 86400.0;
    dy = ( ( oldcycle.lst * 86400.0 ) / TwoPi ) + ( dx * 1.002737909350795 );
    if( dy < 0.0 ) dy += 86400.0;
    if( dy > 86400.0 ) dy -= 86400.0;
    fits_update_key( cfitsptr, TDOUBLE, "STT_LST ", &dy,
		     "[s] Start LST (D)", &status);

    /* Finished with primary HDU */

    /* Move to last created HDU in scan header */
    fits_movabs_hdu( cfitsptr, last_scanhdr_hdu, NULL, &status );
    

    /* Create SUBINT BINTABLE */

    nrows = 0; /* naxis2 - Let CFITSIO sort this out */
    ncols = 19; /* tfields */

    ttype[0] = "ISUBINT ";    /* Subint number. If NAXIS=-1, 0 indicates EOD. */
    tform[0] = "1J      ";
    tunit[0] = "";
    ttype[1] = "INDEXVAL";    /* Optionally used if INT_TYPE != TIME */
    tform[1] = "1D      ";
    tunit[1] = "";
    ttype[2] = "TSUBINT ";    /* [s] Length of subintegration */
    tform[2] = "1D      ";
    tunit[2] = "";
    ttype[3] = "OFFS_SUB";    /* [s] Offset from Start UTC of subint centre */
    tform[3] = "1D      ";
    tunit[3] = "";
    ttype[4] = "LST_SUB ";    /* [s] LST at subint centre */
    tform[4] = "1D      ";
    tunit[4] = "";
    ttype[5] = "RA_SUB  ";    /* [turns] RA (J2000) at subint centre */
    tform[5] = "1D      ";
    tunit[5] = "";
    ttype[6] = "DEC_SUB ";    /* [turns] Dec (J2000) at subint centre */
    tform[6] = "1D      ";
    tunit[6] = "";
    ttype[7] = "GLON_SUB";    /* [deg] Gal longitude at subint centre */
    tform[7] = "1D      ";
    tunit[7] = "";
    ttype[8] = "GLAT_SUB";    /* [deg] Gal latitude at subint centre */
    tform[8] = "1D      ";
    tunit[8] = "";
    ttype[9] = "FD_ANG  ";    /* [deg] Feed angle at subint centre */
    tform[9] = "1E      ";
    tunit[9] = "";
    ttype[10] = "POS_ANG ";    /* [deg] Position angle of feed at subint centre */
    tform[10] = "1E      ";
    tunit[10] = "";
    ttype[11] = "PAR_ANG ";    /* [deg] Parallactic angle at subint centre */
    tform[11] = "1E      ";
    tunit[11] = "";
    ttype[12] = "TEL_AZ  ";    /* [deg] Telescope azimuth at subint centre */
    tform[12] = "1E      ";
    tunit[12] = "";
    ttype[13] = "TEL_ZEN ";    /* [deg] Telescope zenith angle at subint centre */
    tform[13] = "1E      ";
    tunit[13] = "";

    sprintf( Cstr16, "%dE", num_chans );
    ttype[14] = "DAT_FREQ";
    tform[14] = Cstr16;
    tunit[14] = "";
    ttype[15] = "DAT_WTS ";
    tform[15] = Cstr16;
    tunit[15] = "";

    sprintf( Estr16, "%dE", nscl );
    ttype[16] = "DAT_OFFS";
    tform[16] = Estr16;
    tunit[16] = "";
    ttype[17] = "DAT_SCL ";
    tform[17] = Estr16;
    tunit[17] = "";

    sprintf( Istr16, "%dI", ndata );
    ttype[18] = "DATA    ";
    tform[18] = Istr16;
    tunit[18] = "Jy      ";


    fits_create_tbl( cfitsptr, BINARY_TBL, nrows, ncols, 
		     ttype, tform, tunit, "SUBINT  ", &status);

    /* Add dimensions of column 'ncols' = SUBINT Data */
    naxes[0] = num_bins;
    naxes[1] = num_chans;
    naxes[2] = num_pols;
  
    fits_write_tdim( cfitsptr, ncols, 3, naxes, &status );

    /* Add keywords */
    fits_update_key( cfitsptr, TSTRING, "INT_TYPE", "TIME",
		     "Time axis (TIME, BINPHSPERI, BINLNGASC, etc)", &status);

    fits_update_key( cfitsptr, TSTRING, "INT_UNIT", "SEC",
		     "Unit of time axis (SEC, PHS (0-1), DEG)", &status);

    fits_update_key( cfitsptr, TINT, "NCH_FILE", &num_chans,
		     "Number of channels/sub-bands in this file (I)", &status);
    j = 0;
    fits_update_key( cfitsptr, TINT, "NCH_STRT", &j,
		     "Start channel/sub-band number (0 to NCHAN-1) (I)", &status);
    
    /* Store subint hdu number */
    fits_get_hdu_num( cfitsptr, &subint_hdu );

  }
  
  /* Write SUBINT BINTABLE columns */

  /* Fill in columns of table */
  col = 1;
  
  /* Subint number. If NAXIS=-1, 0 indicates EOD. */
  fits_write_col( cfitsptr, TINT, col, subint_cnt, 1, 1, &subint_cnt, &status );
  col++;
  
  /* INDEXVAL - Optionally used if INT_TYPE != TIME */
  dx = 0.0;
  fits_write_col( cfitsptr, TDOUBLE, col, subint_cnt, 1, 1, &dx, &status );
  col++;

  /* [s] Length of subint */
  fits_write_col( cfitsptr, TDOUBLE, col, subint_cnt, 1, 1, &sum_subint_len_secs, &status );
  col++;

  /* [s] Offset from Start UTC of subint centre */
  dx = sum_subint_mid_pt / sum_subint_len_secs;
  fits_write_col( cfitsptr, TDOUBLE, col, subint_cnt, 1, 1, &dx, &status );
  col++;

  /* [s] LST at subint centre */
  ds = sum_subint_lst_sin / sum_subint_len_secs;
  dc = sum_subint_lst_cos / sum_subint_len_secs;
  if( ( dx = ( atan2( ds, dc ) / TwoPi ) ) < 0.0 ) dx += 1.0;
  dx *= 86400.0;
  fits_write_col( cfitsptr, TDOUBLE, col, subint_cnt, 1, 1, &dx, &status );
  col++;

  /* [turns] RA (J2000) at subint centre */
  ds = sum_subint_ra_sin / sum_subint_len_secs;
  dc = sum_subint_ra_cos / sum_subint_len_secs;
  if( ( dx = ( atan2( ds, dc ) / TwoPi ) ) < 0.0 ) dx += 1.0;
  fits_write_col( cfitsptr, TDOUBLE, col, subint_cnt, 1, 1, &dx, &status );
  col++;

  /* [turns] Dec (J2000) at subint centre */
  ds = sum_subint_dec_sin / sum_subint_len_secs;
  dc = sum_subint_dec_cos / sum_subint_len_secs;
  dx = atan2( ds, dc ) / TwoPi;
  fits_write_col( cfitsptr, TDOUBLE, col, subint_cnt, 1, 1, &dx, &status );
  col++;

  /* [deg] Gal longitude at subint centre */
  ds = sum_subint_Glon_sin / sum_subint_len_secs;
  dc = sum_subint_Glon_cos / sum_subint_len_secs;
  if( ( dx = ( atan2( ds, dc ) / TwoPi ) ) < 0.0 ) dx += 1.0;
  dx *= 360.0;
  fits_write_col( cfitsptr, TDOUBLE, col, subint_cnt, 1, 1, &dx, &status );
  col++;

  /* [deg] Gal latitude at subint centre */
  ds = sum_subint_Glat_sin / sum_subint_len_secs;
  dc = sum_subint_Glat_cos / sum_subint_len_secs;
  dx = atan2( ds, dc ) * 360.0 / TwoPi;
  fits_write_col( cfitsptr, TDOUBLE, col, subint_cnt, 1, 1, &dx, &status );
  col++;

  /* [deg] Feed angle at subint centre */
  ds = sum_subint_fa_sin / sum_subint_len_secs;
  dc = sum_subint_fa_cos / sum_subint_len_secs;
  dx = atan2( ds, dc ) * 360.0 / TwoPi;
  x = (float) dx;
  fits_write_col( cfitsptr, TFLOAT, col, subint_cnt, 1, 1, &x, &status );
  col++;

  /* [deg] Parallactic angle at subint centre */
  ds = sum_subint_pa_sin / sum_subint_len_secs;
  dc = sum_subint_pa_cos / sum_subint_len_secs;
  dy = atan2( ds, dc ) * 360.0 / TwoPi;

  /* [deg] Position angle of feed at subint centre */
  dx = dx + dy;
  if( dx > 180.0 ) dx -= 360.0;
  if( dx < 180.0 ) dx += 360.0;
  x = (float) dx;
  fits_write_col( cfitsptr, TFLOAT, col, subint_cnt, 1, 1, &x, &status );
  col++;

  /* [deg] Parallactic angle at subint centre */
  x = (float) dy;
  fits_write_col( cfitsptr, TFLOAT, col, subint_cnt, 1, 1, &x, &status );
  col++;

  /* [deg] Telescope azimuth at subint centre */
  ds = sum_subint_az_sin / sum_subint_len_secs;
  dc = sum_subint_az_cos / sum_subint_len_secs;
  if( ( dx = ( atan2( ds, dc ) / TwoPi ) ) < 0.0 ) dx += 1.0;
  dx *= 360.0;
  x = (float) dx;
  fits_write_col( cfitsptr, TFLOAT, col, subint_cnt, 1, 1, &x, &status );
  col++;

  /* [deg] Telescope zenith angle at subint centre */
  ds = sum_subint_el_sin / sum_subint_len_secs;
  dc = sum_subint_el_cos / sum_subint_len_secs;
  dx = 90.0 - ( atan2( ds, dc ) * 360.0 / TwoPi );
  x = (float) dx;
  fits_write_col( cfitsptr, TFLOAT, col, subint_cnt, 1, 1, &x, &status );
  col++;


  /* Centre freq. for each channel - NCHAN floats */
  fits_write_col( cfitsptr, TFLOAT, col, subint_cnt, 1, num_chans, binned_freq, &status );
  col++;

  /* Weights for each channel -  NCHAN floats */
  fits_write_col( cfitsptr, TFLOAT, col, subint_cnt, 1, num_chans, binned_weight, &status );
  col++;

  /* Data offset for each channel - NCHAN*NPOL floats */
  fits_write_col( cfitsptr, TFLOAT, col, subint_cnt, 1, nscl, binned_offset, &status );
  col++;

  /* Data scale factor for each channel - NCHAN*NPOL floats */
  fits_write_col( cfitsptr, TFLOAT, col, subint_cnt, 1, nscl, binned_scale, &status );
  col++;

  /* Subint data table - Dimensions of data table = (NBIN,NCHAN,NPOL) */
  fits_write_col( cfitsptr, TSHORT, col, subint_cnt, 1, ndata, binned_data, &status );
  col++;
  
  /* Finished SUBINT */

#define STEP_BACK
#ifdef STEP_BACK

  /* Move to digitiser statistics  */
  fits_movabs_hdu( cfitsptr, dig_stats_hdu, NULL, &status );

  if( subint_cnt == 1 ) {
    
    /* Now we know whether samplers are in fixed or auto mode - Add DIGLEV key */
    if( (*c_c).wb_ifsam.freq[0].ant[0].pol[0].sam_status & WBSAM_FIXED )
      strcpy( astr, "FIX" );
    else 
      strcpy( astr, "AUTO" );
    fits_update_key( cfitsptr, TSTRING, "DIGLEV", astr,
		     "Digitiser level-setting mode (AUTO, FIX)", &status);
  }
  
  /* Add data for this subint */
  fits_write_col( cfitsptr, TFLOAT, 1, subint_cnt, 1, num_wbsam_stats, wbsam_stats, &status );


  /* Move to bandpass  */
  fits_movabs_hdu( cfitsptr, bpass_hdu, NULL, &status );
  /* Overwrite row 1 with latest data  */

  /* Data offset for each receiver channel - NRCVR floats */
  fits_write_col( cfitsptr, TFLOAT, 1, 1, 1, nrcvr, bpass_offset, &status );

  /* Data scale factor for each receiver channel - NRCVR floats */
  fits_write_col( cfitsptr, TFLOAT, 2, 1, 1, nrcvr, bpass_scale, &status );

  /* Bandpass data table - Dimensions of data table = (NCHAN_orig,NRCVR) */
  ndata = nchan_orig * nrcvr;
  fits_write_col( cfitsptr, TSHORT, 3, 1, 1, ndata, bpass_data, &status );


  /* Move back to subint HDU for next subint */
  fits_movabs_hdu( cfitsptr, subint_hdu, NULL, &status );

#endif /* STEP_BACK */

  /* Now FLUSH any internal buffers to the file */
  fits_flush_file( cfitsptr, &status );


  return( status );
  
}
Beispiel #14
0
void FitsFile::WriteTableCell(int row, int col, double *data, size_t size)
{
	int status = 0;
	fits_write_col(_fptr, TDOUBLE, col, row, 1, size, data, &status);
	CheckStatus(status);
}
Beispiel #15
0
int main(void)
{
    fitsfile *fptr;
    int status = 0;
    char* file_name = "!mybintab.fits";

    //create a fits file
    CheckErrors( fits_create_file(&fptr,file_name, &status) );

    // specify what is in each column, see the link for more details
    //http://heasarc.gsfc.nasa.gov/docs/software/fitsio/quick/node10.html
    const long nrows=1025;
    const int tfields=2;
    char *ttype[tfields], *tform[tfields], *tunit[tfields];

    for (int ii = 0; ii < tfields; ii++)
    {
        ttype[ii] = (char *) malloc(20);
        tform[ii] = (char *) malloc(20);
        tunit[ii] = (char *) malloc(20);
    }

    // name for the column
    strcpy(ttype[0], "l");
    strcpy(ttype[1], "C_l");

    // data format
    strcpy(tform[0], "I11");
    strcpy(tform[1], "E13.5");

    // units
    strcpy(tunit[0], "");
    strcpy(tunit[1], "mK^2");

    // name of the HDU extension
    char *extname ="POWER SPECTRUM";

    //insert an empy table first
    CheckErrors(fits_create_tbl(fptr, BINARY_TBL, nrows, tfields, ttype,tform, tunit,extname,&status) );

    //note that everything here starts with 1 rather than 0 (unlike the C arryas)
    long firstrow =1;
    long firstelem = 1;
    long nelements = nrows;
    int* ell = malloc(nrows*sizeof(int));
    double* c_ell=malloc(nrows*sizeof(double));

    // create data
    for(long i=0;i<nrows;++i)
    {
        ell[i] = (int) i;
        c_ell[i] = (double) i*100;
    }

    //first column datatype TINT
    int colnum = 1;
    CheckErrors( fits_write_col(fptr, TINT, colnum, firstrow, firstelem, nelements, ell,&status) );

    //second column datatype is TDOUBLE
    colnum = 2 ;
    CheckErrors( fits_write_col(fptr, TDOUBLE, colnum, firstrow, firstelem, nelements, c_ell,&status) );

    //free memory
    for (int ii = 0; ii < tfields; ii++)
    {
        free(ttype[ii]);
        free(tform[ii]);
        free(tunit[ii]);
    }
    free(ell);
    free(c_ell);

    //close fits file
    CheckErrors( fits_close_file(fptr, &status) );
    return 0;
}
int psrfits_write_subint(struct psrfits *pf)
{
    int row, *status, nchan, nivals, mode, out_nbytes, nstat, dummy;
    float ftmp;
    struct hdrinfo *hdr;
    struct subint *sub;

    hdr = &(pf->hdr);           // dereference the ptr to the header struct
    sub = &(pf->sub);           // dereference the ptr to the subint struct
    status = &(pf->status);     // dereference the ptr to the CFITSIO status
    nchan = hdr->nchan / hdr->ds_freq_fact;
    nstat = sub->statbytes_per_subint / 2;      //stat array is shorts
    if (hdr->onlyI)
        nivals = nchan;
    else
        nivals = nchan * hdr->npol;
    mode = psrfits_obs_mode(hdr->obs_mode);
    if (mode == fold)
        out_nbytes = sub->bytes_per_subint / hdr->ds_freq_fact;
    else {
        out_nbytes = sub->bytes_per_subint / (hdr->ds_freq_fact * hdr->ds_time_fact);
        if (hdr->onlyI)
            out_nbytes /= hdr->npol;
    }

    // Create the initial file or change to a new one if needed.
    // Stay with a single file for fold mode.

    //fprintf(stderr,"In psrfits write, pf->filenum: %d pf->multifile: %d\n",pf->filenum,pf->multifile);
    //fprintf(stderr,"In psrfits write, pf->rownum %d pf->rows_per_file: %d\n",pf->rownum,pf->rows_per_file);

    /*
       if (pf->filenum==0 ||
       ( (mode==search || pf->multifile==1)
       && pf->rownum > pf->rows_per_file)) {
       if (pf->filenum) {
       printf("Closing file '%s'\n", pf->filename);
       fits_close_file(pf->fptr, status);
       return *status;
       }
       psrfits_create(pf);
       }
     */

    row = pf->rownum;
    //fprintf(stderr,"In psrfits write, row: %d\n",row);

    //fits_read_key(pf->fptr, TINT, "NAXIS2", &dummy, NULL, status);
    //fprintf(stderr,"In psrfits write, before col writing, NAXIS2: %d status; %d\n",dummy,*status);

    fprintf(stderr, "tsubint: %f  offs_sub: %f\n", sub->tsubint, sub->offs);

    fits_write_col(pf->fptr, TDOUBLE, 1, row, 1, 1, &(sub->tsubint), status);
    fits_write_col(pf->fptr, TDOUBLE, 2, row, 1, 1, &(sub->offs), status);
    fits_write_col(pf->fptr, TDOUBLE, 3, row, 1, 1, &(sub->lst), status);
    fits_write_col(pf->fptr, TDOUBLE, 4, row, 1, 1, &(sub->ra), status);
    fits_write_col(pf->fptr, TDOUBLE, 5, row, 1, 1, &(sub->dec), status);
    fits_write_col(pf->fptr, TDOUBLE, 6, row, 1, 1, &(sub->glon), status);
    fits_write_col(pf->fptr, TDOUBLE, 7, row, 1, 1, &(sub->glat), status);
    ftmp = (float) sub->feed_ang;
    fits_write_col(pf->fptr, TFLOAT, 8, row, 1, 1, &ftmp, status);
    ftmp = (float) sub->pos_ang;
    fits_write_col(pf->fptr, TFLOAT, 9, row, 1, 1, &ftmp, status);
    ftmp = (float) sub->par_ang;
    fits_write_col(pf->fptr, TFLOAT, 10, row, 1, 1, &ftmp, status);
    ftmp = (float) sub->tel_az;
    fits_write_col(pf->fptr, TFLOAT, 11, row, 1, 1, &ftmp, status);
    ftmp = (float) sub->tel_zen;
    fits_write_col(pf->fptr, TFLOAT, 12, row, 1, 1, &ftmp, status);
    fits_write_col(pf->fptr, TFLOAT, 13, row, 1, nchan, sub->dat_freqs, status);
    fits_write_col(pf->fptr, TFLOAT, 14, row, 1, nchan, sub->dat_weights, status);
    fits_write_col(pf->fptr, TFLOAT, 15, row, 1, nivals, sub->dat_offsets, status);
    fits_write_col(pf->fptr, TFLOAT, 16, row, 1, nivals, sub->dat_scales, status);

    if (mode == search) {
        // Need to change this for other data types...
        //fprintf(stderr,"In psrfits write, out_nbytes (data bytes per subint): %d\n",out_nbytes);
        fits_write_col(pf->fptr, TBYTE, 17, row, 1, out_nbytes, sub->data, status);
    } else if (mode == fold) {
        // Fold mode writes floats for now..
        fits_write_col(pf->fptr, TFLOAT, 17, row, 1, out_nbytes / sizeof(float),
                       sub->data, status);
    }

    /*
       fprintf(stderr,"In psrfits write, out_nbytes: %d, nchan: %d nivals: %d nstat: %d status: %d\n",out_nbytes,nchan,nivals,nstat,*status);
       fits_flush_file(pf->fptr, status);
       fits_read_key(pf->fptr, TINT, "NAXIS2", &dummy, NULL, status);
       fprintf(stderr,"In psrfits write after 17 column, NAXIS2: %d status; %d\n",dummy,*status);
     */

    fits_write_col(pf->fptr, TSHORT, 18, row, 1, nstat, sub->stat, status);

    // Flush the buffers if not finished with the file
    // Note:  this use is not entirely in keeping with the CFITSIO
    //        documentation recommendations.  However, manually
    //        correcting NAXIS2 and using fits_flush_buffer()
    //        caused occasional hangs (and extrememly large
    //        files due to some infinite loop).
    fits_flush_file(pf->fptr, status);

    //NOTE: using flush_file resulted in an extra row for some reason

    //fits_flush_buffer(pf->fptr,0,status);

    //fits_read_key(pf->fptr, TINT, "NAXIS2", &dummy, NULL, status);
    //fprintf(stderr,"In psrfits write, after fits flush, NAXIS2: %d status; %d\n",dummy,*status);

    // Print status if bad
    if (*status) {
        fprintf(stderr, "Error writing subint %d:\n", pf->rownum);
        fits_report_error(stderr, *status);
        fflush(stderr);
    }
    // Now update some key values if no CFITSIO errors
    if (!(*status)) {
        pf->rownum++;
        pf->tot_rows++;
        pf->N += hdr->nsblk / hdr->ds_time_fact;
        pf->T += sub->tsubint;

        // For fold mode, print info each subint written
        if (mode == fold && pf->quiet != 1) {
            printf("Wrote subint %d (total time %.1fs)\n", pf->rownum - 1, pf->T);
            fflush(stdout);
        }

    }
    //fits_update_key(pf->fptr,TINT,"NAXIS2",&(pf->tot_rows),NULL,status);

    return *status;
}
Beispiel #17
0
//----------------------------------------------------------
int write_hits(s6_output_databuf_t *db, int block_idx, etfits_t *etf) {      
//----------------------------------------------------------

    long firstrow, firstelem, colnum;
    size_t nrows, hit_i, nhits_this_input;  
    int cur_beam, cur_input, cur_beampol;  

    size_t nhits = 0;

    int * status_p = &(etf->status);
    *status_p = 0;

    etf->beampol_cnt = 0;

//fprintf(stderr, "writing hits\n");
    //std::vector<hits_t> hits;

    float  det_pow[MAXHITS];
    float  mean_pow[MAXHITS];
    int    coarse_chan[MAXHITS];
    int    fine_chan[MAXHITS];

    firstrow  = 1;
    firstelem = 1;

    for(int beam=0; beam < N_BEAMS; beam++) {
        // TODO - this goes through the output block for each beam twice. We could cut
        // this in half if we have a set of arrays for each pol (consuming twice the
        // memory).
        for(int input=0; input < N_POLS_PER_BEAM; input++) {        
            int beampol = beam * N_POLS_PER_BEAM + input;
            int hit_j=0;
            nhits_this_input=0;
            for(int hit_i=0; hit_i < (size_t)db->block[block_idx].header.nhits[beam]; hit_i++) {
                if(db->block[block_idx].pol[beam][hit_i] == input) {
                    nhits_this_input++;
                    det_pow[hit_j]     = db->block[block_idx].power[beam][hit_i];
                    mean_pow[hit_j]    = db->block[block_idx].baseline[beam][hit_i];
                    coarse_chan[hit_j] = db->block[block_idx].coarse_chan[beam][hit_i];
                    fine_chan[hit_j]   = db->block[block_idx].fine_chan[beam][hit_i];
                    hit_j++;
                }
            }

            write_hits_header(etf, 
                              beampol, 
                              nhits_this_input, 
                              (size_t)db->block[block_idx].header.missed_pkts[beam]);
            nhits += nhits_this_input;

            // write the hits for this input
            colnum      = 1;
            if(! *status_p) fits_write_col(etf->fptr, TFLOAT, colnum, firstrow, firstelem, nhits_this_input, det_pow, status_p);
            colnum      = 2;
            if(! *status_p) fits_write_col(etf->fptr, TFLOAT, colnum, firstrow, firstelem, nhits_this_input, mean_pow, status_p);
            colnum      = 3;
            if(! *status_p) fits_write_col(etf->fptr, TINT, colnum, firstrow, firstelem, nhits_this_input, coarse_chan, status_p);
            colnum      = 4;
            if(! *status_p) fits_write_col(etf->fptr, TINT, colnum, firstrow, firstelem, nhits_this_input, fine_chan, status_p);

            etf->beampol_cnt++;
        } 
    }

    if (*status_p) {
        hashpipe_error(__FUNCTION__, "Error writing hits");
        //fprintf(stderr, "Error writing hits.\n");
        fits_report_error(stderr, *status_p);
    }

    // non-standard return
    if(*status_p) {
        return -1;
    } else {
        return nhits;
    }
}
Beispiel #18
0
/* does the actual write of the file */
static void file_write_rays2fits(long fileNum, long firstTask, long lastTask, MPI_Comm fileComm)
{
  const char *ttype[] = 
    { "nest", "ra", "dec", "A00", "A01", "A10", "A11"
#ifdef OUTPUTRAYDEFLECTIONS
      , "alpha0", "alpha1"
#endif
#ifdef OUTPUTPHI
      , "phi"
#endif
    };
  
  const char *tform[] = 
    { "K", "D", "D", "D", "D", "D", "D"
#ifdef OUTPUTRAYDEFLECTIONS
      , "D", "D"
#endif
#ifdef OUTPUTPHI
      , "D"
#endif
    };
  
  char name[MAX_FILENAME];
  char bangname[MAX_FILENAME];
  long NumRaysInFile,i,j;
  long *NumRaysInPeanoCell,*StartRaysInPeanoCell,peano;
  
  fitsfile *fptr;
  int status = 0;
  int naxis = 1;
  long naxes[1],fpixel[1];
  LONGLONG nrows;
  int tfields,colnum;
  long k,chunkInd,firstInd,lastInd,NumRaysInChunkBase,NumRaysInChunk,NumChunks;
  LONGLONG firstrow,firstelem,nelements;
  double *darr;
  long *larr;
  char *buff;
  double ra,dec;
  
  long nwc=0,NtotToRecv,nw=0,nwg=0,rpeano,rowloc;
  MPI_Status mpistatus;
  double t0 = 0.0;
  
  sprintf(name,"%s/%s%04ld.%04ld",rayTraceData.OutputPath,rayTraceData.RayOutputName,rayTraceData.CurrentPlaneNum,fileNum);
  sprintf(bangname,"!%s",name);
  
  /* build fits table layout*/
  tfields = 7;
#ifdef OUTPUTRAYDEFLECTIONS
  tfields += 2;
#endif
#ifdef OUTPUTPHI
  tfields += 1;
#endif
  
  /* build file layout*/
  NumRaysInPeanoCell = (long*)malloc(sizeof(long)*NbundleCells);
  assert(NumRaysInPeanoCell != NULL);
  StartRaysInPeanoCell = (long*)malloc(sizeof(long)*NbundleCells);
  assert(StartRaysInPeanoCell != NULL);
  for(i=0;i<NbundleCells;++i)
    StartRaysInPeanoCell[i] = 0;
  for(i=0;i<NbundleCells;++i)
    {
      if(ISSETBITFLAG(bundleCells[i].active,PRIMARY_BUNDLECELL))
	{
	  peano = nest2peano(bundleCells[i].nest,rayTraceData.bundleOrder);
	  StartRaysInPeanoCell[peano] = bundleCells[i].Nrays;
	  nwc += bundleCells[i].Nrays;
	}
    }
  MPI_Allreduce(StartRaysInPeanoCell,NumRaysInPeanoCell,(int) NbundleCells,MPI_LONG,MPI_SUM,fileComm);
  j = 0;
  for(i=0;i<NbundleCells;++i)
    {
      StartRaysInPeanoCell[i] = j;
      j += NumRaysInPeanoCell[i];
    }
  NumRaysInFile = j;
  
  /* make the file and write header info */
  if(ThisTask == firstTask)
    {
      t0 = -MPI_Wtime();
      
      remove(name);
      
      fits_create_file(&fptr,bangname,&status);
      if(status)
        fits_report_error(stderr,status);
      
      naxes[0] = 2l*NbundleCells;
      fits_create_img(fptr,LONGLONG_IMG,naxis,naxes,&status);
      if(status)
        fits_report_error(stderr,status);
      
      fpixel[0] = 0+1;
      fits_write_pix(fptr,TLONG,fpixel,(LONGLONG) (NbundleCells),NumRaysInPeanoCell,&status);
      if(status)
        fits_report_error(stderr,status);
      
      fpixel[0] = NbundleCells+1;
      fits_write_pix(fptr,TLONG,fpixel,(LONGLONG) (NbundleCells),StartRaysInPeanoCell,&status);
      if(status)
        fits_report_error(stderr,status);
      
      fits_write_key(fptr,TLONG,"NumFiles",&(rayTraceData.NumRayOutputFiles),"number of files that rays are split into",&status);
      if(status)
        fits_report_error(stderr,status);
      
      fits_write_key(fptr,TLONG,"PeanoCellHEALPixOrder",&(rayTraceData.bundleOrder),"HEALPix order of peano indexed cells rays are organized into",&status);
      if(status)
        fits_report_error(stderr,status);
      
      fits_write_key(fptr,TLONG,"RayHEALPixOrder",&(rayTraceData.rayOrder),"HEALPix order of ray grid",&status);
      if(status)
        fits_report_error(stderr,status);
      
      nrows = (LONGLONG) (NumRaysInFile);
      fits_create_tbl(fptr,BINARY_TBL,nrows,tfields,ttype,tform,NULL,"Rays",&status);
      if(status)
        fits_report_error(stderr,status);
      
      fits_get_rowsize(fptr,&NumRaysInChunkBase,&status);
      if(status)
	fits_report_error(stderr,status);
    }
  
  MPI_Bcast(&NumRaysInChunkBase,1,MPI_LONG,0,fileComm);
  if(sizeof(long) > sizeof(double))
    buff = (char*)malloc(sizeof(long)*NumRaysInChunkBase);
  else
    buff = (char*)malloc(sizeof(double)*NumRaysInChunkBase);
  assert(buff != NULL);
  darr = (double*) buff;
  larr = (long*) buff;
  
  for(i=firstTask;i<=lastTask;++i)
    {
      if(ThisTask == i)
	{
#ifdef DEBUG
#if DEBUG_LEVEL > 0
	  fprintf(stderr,"%d: fileNum = %ld, first,last = %ld|%ld\n",ThisTask,fileNum,firstTask,lastTask);
#endif
#endif
	  if(ThisTask != firstTask)
	    MPI_Send(&nwc,1,MPI_LONG,(int) firstTask,TAG_RAYIO_TOTNUM,MPI_COMM_WORLD);
	  
	  for(rpeano=0;rpeano<NrestrictedPeanoInd;++rpeano)
            {
              j = bundleCellsRestrictedPeanoInd2Nest[rpeano];
              
	      if(ISSETBITFLAG(bundleCells[j].active,PRIMARY_BUNDLECELL))
		{
		  peano = nest2peano(bundleCells[j].nest,rayTraceData.bundleOrder);
		  
		  assert(NumRaysInPeanoCell[peano] == ((1l) << (2*(rayTraceData.rayOrder-rayTraceData.bundleOrder))));
		  assert((StartRaysInPeanoCell[peano] - 
			  ((StartRaysInPeanoCell[peano])/(((1l) << (2*(rayTraceData.rayOrder-rayTraceData.bundleOrder)))))
			  *(((1l) << (2*(rayTraceData.rayOrder-rayTraceData.bundleOrder))))) == 0);
		  
		  NumChunks = NumRaysInPeanoCell[peano]/NumRaysInChunkBase;
		  if(NumChunks*NumRaysInChunkBase < NumRaysInPeanoCell[peano])
		    NumChunks += 1;
		  
		  firstrow = (LONGLONG) (StartRaysInPeanoCell[peano]) + (LONGLONG) 1;
		  firstelem = 1;
		  for(chunkInd=0;chunkInd<NumChunks;++chunkInd)
		    {
		      firstInd = chunkInd*NumRaysInChunkBase;
		      lastInd = (chunkInd+1)*NumRaysInChunkBase-1;
		      if(lastInd >= NumRaysInPeanoCell[peano]-1)
			lastInd = NumRaysInPeanoCell[peano]-1;
		      NumRaysInChunk = lastInd - firstInd + 1;
		      
		      nelements = (LONGLONG) NumRaysInChunk;
		      nw += NumRaysInChunk;
		      
		      if(ThisTask != firstTask)
			{
			  rowloc = firstrow;
			  MPI_Send(&rowloc,1,MPI_LONG,(int) firstTask,TAG_RAYIO_CHUNKDATA,MPI_COMM_WORLD);
			  MPI_Send(&NumRaysInChunk,1,MPI_LONG,(int) firstTask,TAG_RAYIO_NUMCHUNK,MPI_COMM_WORLD);
			  colnum = TAG_RAYIO_CHUNKDATA+1;
			  
			  for(k=firstInd;k<=lastInd;++k)
			    larr[k-firstInd] = bundleCells[j].rays[k].nest;
			  MPI_Ssend(larr,(int) NumRaysInChunk,MPI_LONG,(int) firstTask,colnum,MPI_COMM_WORLD);
			  ++colnum;
			  
			  for(k=firstInd;k<=lastInd;++k)
			    {
			      vec2radec(bundleCells[j].rays[k].n,&ra,&dec);
			      darr[k-firstInd] = ra;
			    }
			  MPI_Ssend(darr,(int) NumRaysInChunk,MPI_DOUBLE,(int) firstTask,colnum,MPI_COMM_WORLD);
			  ++colnum;
			  
			  for(k=firstInd;k<=lastInd;++k)
			    {
			      vec2radec(bundleCells[j].rays[k].n,&ra,&dec);
			      darr[k-firstInd] = dec;
			    }
			  MPI_Ssend(darr,(int) NumRaysInChunk,MPI_DOUBLE,(int) firstTask,colnum,MPI_COMM_WORLD);
			  ++colnum;
			  
			  for(k=firstInd;k<=lastInd;++k)
			    darr[k-firstInd] = bundleCells[j].rays[k].A[2*0+0];
			  MPI_Ssend(darr,(int) NumRaysInChunk,MPI_DOUBLE,(int) firstTask,colnum,MPI_COMM_WORLD);
                          ++colnum;
			  			  
			  for(k=firstInd;k<=lastInd;++k)
			    darr[k-firstInd] = bundleCells[j].rays[k].A[2*0+1];
			  MPI_Ssend(darr,(int) NumRaysInChunk,MPI_DOUBLE,(int) firstTask,colnum,MPI_COMM_WORLD);
			  ++colnum;
			  
			  for(k=firstInd;k<=lastInd;++k)
			    darr[k-firstInd] = bundleCells[j].rays[k].A[2*1+0];
			  MPI_Ssend(darr,(int) NumRaysInChunk,MPI_DOUBLE,(int) firstTask,colnum,MPI_COMM_WORLD);
			  ++colnum;
			  
			  for(k=firstInd;k<=lastInd;++k)
			    darr[k-firstInd] = bundleCells[j].rays[k].A[2*1+1];
			  MPI_Ssend(darr,(int) NumRaysInChunk,MPI_DOUBLE,(int) firstTask,colnum,MPI_COMM_WORLD);
			  ++colnum;
			  
#ifdef OUTPUTRAYDEFLECTIONS
			  for(k=firstInd;k<=lastInd;++k)
			    darr[k-firstInd] = bundleCells[j].rays[k].alpha[0];
			  MPI_Ssend(darr,(int) NumRaysInChunk,MPI_DOUBLE,(int) firstTask,colnum,MPI_COMM_WORLD);
			  ++colnum;
			  
			  for(k=firstInd;k<=lastInd;++k)
			    darr[k-firstInd] = bundleCells[j].rays[k].alpha[1];
			  MPI_Ssend(darr,(int) NumRaysInChunk,MPI_DOUBLE,(int) firstTask,colnum,MPI_COMM_WORLD);
			  ++colnum;
#endif
#ifdef OUTPUTPHI
			  for(k=firstInd;k<=lastInd;++k)
			    darr[k-firstInd] = bundleCells[j].rays[k].phi;
			  MPI_Ssend(darr,(int) NumRaysInChunk,MPI_DOUBLE,(int) firstTask,colnum,MPI_COMM_WORLD);
			  ++colnum;
#endif
			  firstrow += nelements;
			}
		      else
			{
			  colnum = 1;
			  for(k=firstInd;k<=lastInd;++k)
			    larr[k-firstInd] = bundleCells[j].rays[k].nest;
			  fits_write_col(fptr,TLONG,colnum,firstrow,firstelem,nelements,larr,&status);
			  if(status)
			    fits_report_error(stderr,status);
			  ++colnum;
			  
			  for(k=firstInd;k<=lastInd;++k)
			    {
			      vec2radec(bundleCells[j].rays[k].n,&ra,&dec);
			      darr[k-firstInd] = ra;
			    }
			  fits_write_col(fptr,TDOUBLE,colnum,firstrow,firstelem,nelements,darr,&status);
			  if(status)
			    fits_report_error(stderr,status);
			  ++colnum;
			  
			  for(k=firstInd;k<=lastInd;++k)
			    {
			      vec2radec(bundleCells[j].rays[k].n,&ra,&dec);
			      darr[k-firstInd] = dec;
			    }
			  fits_write_col(fptr,TDOUBLE,colnum,firstrow,firstelem,nelements,darr,&status);
			  if(status)
			    fits_report_error(stderr,status);
			  ++colnum;
			  
			  for(k=firstInd;k<=lastInd;++k)
			    darr[k-firstInd] = bundleCells[j].rays[k].A[2*0+0];
			  fits_write_col(fptr,TDOUBLE,colnum,firstrow,firstelem,nelements,darr,&status);
			  if(status)
			    fits_report_error(stderr,status);
			  ++colnum;
			  
			  for(k=firstInd;k<=lastInd;++k)
			    darr[k-firstInd] = bundleCells[j].rays[k].A[2*0+1];
			  fits_write_col(fptr,TDOUBLE,colnum,firstrow,firstelem,nelements,darr,&status);
			  if(status)
			    fits_report_error(stderr,status);
			  ++colnum;
			  
			  for(k=firstInd;k<=lastInd;++k)
			    darr[k-firstInd] = bundleCells[j].rays[k].A[2*1+0];
			  fits_write_col(fptr,TDOUBLE,colnum,firstrow,firstelem,nelements,darr,&status);
			  if(status)
			    fits_report_error(stderr,status);
			  ++colnum;
			  
			  for(k=firstInd;k<=lastInd;++k)
			    darr[k-firstInd] = bundleCells[j].rays[k].A[2*1+1];
			  fits_write_col(fptr,TDOUBLE,colnum,firstrow,firstelem,nelements,darr,&status);
			  if(status)
			    fits_report_error(stderr,status);
			  ++colnum;
			  
#ifdef OUTPUTRAYDEFLECTIONS
			  for(k=firstInd;k<=lastInd;++k)
			    darr[k-firstInd] = bundleCells[j].rays[k].alpha[0];
			  fits_write_col(fptr,TDOUBLE,colnum,firstrow,firstelem,nelements,darr,&status);
			  if(status)
			    fits_report_error(stderr,status);
			  ++colnum;
			  
			  for(k=firstInd;k<=lastInd;++k)
			    darr[k-firstInd] = bundleCells[j].rays[k].alpha[1];
			  fits_write_col(fptr,TDOUBLE,colnum,firstrow,firstelem,nelements,darr,&status);
			  if(status)
			    fits_report_error(stderr,status);
			  ++colnum;
#endif
#ifdef OUTPUTPHI
			  for(k=firstInd;k<=lastInd;++k)
			    darr[k-firstInd] = bundleCells[j].rays[k].phi;
			  fits_write_col(fptr,TDOUBLE,colnum,firstrow,firstelem,nelements,darr,&status);
			  if(status)
			    fits_report_error(stderr,status);
			  ++colnum;
#endif
			  firstrow += nelements;
			}
		    }// for(chunkInd=0;chunkInd<NumChunks;++chunkInd)
		} //if(ISSETBITFLAG(bundleCells[j].active,PRIMARY_BUNDLECELL)).
	    } //for(j=0;j<NbundleCells;++j)
	} //if(ThisTask == i)
      
      if(i != firstTask && ThisTask == firstTask)
	{
	  MPI_Recv(&NtotToRecv,1,MPI_LONG,(int) i,TAG_RAYIO_TOTNUM,MPI_COMM_WORLD,&mpistatus);
	  
	  firstelem = 1;
	  while(NtotToRecv > 0)
	    {
	      MPI_Recv(&rowloc,1,MPI_LONG,(int) i,TAG_RAYIO_CHUNKDATA,MPI_COMM_WORLD,&mpistatus);
	      MPI_Recv(&NumRaysInChunk,1,MPI_LONG,(int) i,TAG_RAYIO_NUMCHUNK,MPI_COMM_WORLD,&mpistatus);
	      firstrow = (LONGLONG) (rowloc);
	      nelements = (LONGLONG) NumRaysInChunk;
	      colnum = 1;
	      
	      MPI_Recv(larr,(int) NumRaysInChunk,MPI_LONG,(int) i,colnum+TAG_RAYIO_CHUNKDATA,MPI_COMM_WORLD,&mpistatus);
	      fits_write_col(fptr,TLONG,colnum,firstrow,firstelem,nelements,larr,&status);
	      if(status)
		fits_report_error(stderr,status);
	      ++colnum;
	      
	      MPI_Recv(darr,(int) NumRaysInChunk,MPI_DOUBLE,(int) i,colnum+TAG_RAYIO_CHUNKDATA,MPI_COMM_WORLD,&mpistatus);
	      fits_write_col(fptr,TDOUBLE,colnum,firstrow,firstelem,nelements,darr,&status);
	      if(status)
		fits_report_error(stderr,status);
	      ++colnum;
	      
	      MPI_Recv(darr,(int) NumRaysInChunk,MPI_DOUBLE,(int) i,colnum+TAG_RAYIO_CHUNKDATA,MPI_COMM_WORLD,&mpistatus);
	      fits_write_col(fptr,TDOUBLE,colnum,firstrow,firstelem,nelements,darr,&status);
	      if(status)
		fits_report_error(stderr,status);
	      ++colnum;
	      
	      MPI_Recv(darr,(int) NumRaysInChunk,MPI_DOUBLE,(int) i,colnum+TAG_RAYIO_CHUNKDATA,MPI_COMM_WORLD,&mpistatus);
	      fits_write_col(fptr,TDOUBLE,colnum,firstrow,firstelem,nelements,darr,&status);
	      if(status)
		fits_report_error(stderr,status);
	      ++colnum;
	      
	      MPI_Recv(darr,(int) NumRaysInChunk,MPI_DOUBLE,(int) i,colnum+TAG_RAYIO_CHUNKDATA,MPI_COMM_WORLD,&mpistatus);
	      fits_write_col(fptr,TDOUBLE,colnum,firstrow,firstelem,nelements,darr,&status);
	      if(status)
		fits_report_error(stderr,status);
	      ++colnum;
	      
	      MPI_Recv(darr,(int) NumRaysInChunk,MPI_DOUBLE,(int) i,colnum+TAG_RAYIO_CHUNKDATA,MPI_COMM_WORLD,&mpistatus);
	      fits_write_col(fptr,TDOUBLE,colnum,firstrow,firstelem,nelements,darr,&status);
	      if(status)
		fits_report_error(stderr,status);
	      ++colnum;
	      
	      MPI_Recv(darr,(int) NumRaysInChunk,MPI_DOUBLE,(int) i,colnum+TAG_RAYIO_CHUNKDATA,MPI_COMM_WORLD,&mpistatus);
	      fits_write_col(fptr,TDOUBLE,colnum,firstrow,firstelem,nelements,darr,&status);
	      if(status)
		fits_report_error(stderr,status);
	      ++colnum;
	      
#ifdef OUTPUTRAYDEFLECTIONS
	      MPI_Recv(darr,(int) NumRaysInChunk,MPI_DOUBLE,(int) i,colnum+TAG_RAYIO_CHUNKDATA,MPI_COMM_WORLD,&mpistatus);
	      fits_write_col(fptr,TDOUBLE,colnum,firstrow,firstelem,nelements,darr,&status);
	      if(status)
		fits_report_error(stderr,status);
	      ++colnum;
	      
	      MPI_Recv(darr,(int) NumRaysInChunk,MPI_DOUBLE,(int) i,colnum+TAG_RAYIO_CHUNKDATA,MPI_COMM_WORLD,&mpistatus);
	      fits_write_col(fptr,TDOUBLE,colnum,firstrow,firstelem,nelements,darr,&status);
	      if(status)
		fits_report_error(stderr,status);
	      ++colnum;
#endif
#ifdef OUTPUTPHI
	      MPI_Recv(darr,(int) NumRaysInChunk,MPI_DOUBLE,(int) i,colnum+TAG_RAYIO_CHUNKDATA,MPI_COMM_WORLD,&mpistatus);
	      fits_write_col(fptr,TDOUBLE,colnum,firstrow,firstelem,nelements,darr,&status);
	      if(status)
		fits_report_error(stderr,status);
	      ++colnum;
#endif
	      	      
	      nwg += NumRaysInChunk;
              NtotToRecv -= NumRaysInChunk;
	    }
	}
      
      //////////////////////////////
      MPI_Barrier(fileComm);
      //////////////////////////////
    }
  
  if(ThisTask == firstTask)
    {
      fits_close_file(fptr,&status);
      if(status)
	fits_report_error(stderr,status);
      
      t0 += MPI_Wtime();

#ifdef DEBUG      
      fprintf(stderr,"writing %ld rays to file '%s' took %g seconds.\n",NumRaysInFile,name,t0);
#endif
      
      assert(nwg == NumRaysInFile-nw); //error check # of rays recvd
    }
  
  //error check # of rays written
  MPI_Allreduce(&nw,&nwg,1,MPI_LONG,MPI_SUM,fileComm);
  assert(nw == nwc);
  assert(nwg == NumRaysInFile);
  
  //clean up and close files for this task
  free(buff);
  free(StartRaysInPeanoCell);
  free(NumRaysInPeanoCell);
}
/*******************************************************************************
 * gaussian_test
 * This function creates a fits table, then populates it with the mean, sigma,
 * and error on the mean from experiments sampling from a gaussian num_samples
 * number of times.
 * Input:
 *      fptr:           Fits file to write the table to
 *      num_iter:       Number of experiments to run
 *      num_samples:    Number of samples for each experiment
 *      mean:           Mean for the distibution in the experiments
 *      sigma:          Sigma for the distribution in the experiments
 * Output:
 *      status:         Fits error status
 ******************************************************************************/
void gaussian_test(fitsfile *fptr, long num_iter, long num_samples, double mean,
        double sigma, int *status){
    long nrows, i, num_sigma;
    double *stats, ratio_sigma, ave_mean, mean_sd, *all_means;
    /* Fits file columns */
    char *ttype[] = {"mean", "sigma", "error"};
    char *tform[] = {"D", "D", "D"};
    char *tunit[] = {NULL, NULL, NULL};
    char *key[] = {"NSAMPLES", "MEAN", "SIGMA", "MEANAVE", "MEANSD"};
    char *comment[] = {"Number of samples per iteration",
        "True mean of the gaussian",
        "True standard deviation of the gaussian",
        "Average mean",
        "Standard deviation of all means"};

    /* Create the fits table */
    fits_create_tbl(fptr, BINARY_TBL, 0, 3, ttype, tform, tunit, NULL, status);
    if (*status){
        printf("Error creating fits table in guassian_test.\n");
        exit(*status);
    }

    /* Get mean, sigma, and error, then save to a fits file */
    all_means = (double *) malloc(num_iter * sizeof(double));
    ave_mean = 0;
    for (nrows = 0; nrows < num_iter; nrows++){
        stats = sample_gauss(num_samples, mean, sigma);
        ave_mean += stats[0];
        all_means[nrows] = stats[0];
        /* Write to file */
        for (i=0; i < 3; i++){
            fits_write_col(fptr, TDOUBLE, i+1, nrows+1, 1L,1L, stats+i, status);
            if (*status){
                printf("Error writing to fits table in gaussian_test.\n");
                exit(1);
            }
        }
        free(stats); /* free memory for next iteration */
    }
    ave_mean /= num_iter;

    /* Get standard deviation of all means */
    mean_sd = 0;
    for (i=0; i<num_iter; i++)
        mean_sd += pow(ave_mean - all_means[i], 2);
    mean_sd /= num_iter - 1;
    mean_sd = sqrt(mean_sd);

    /* Get percentage of experiments within 2 sigma */
    num_sigma = 0;
    for (i=0; i<num_iter; i++){
        if (fabs(all_means[i] - ave_mean) < 2 * mean_sd)
            num_sigma++;
    }
    ratio_sigma = (double) num_sigma / num_iter;
    free(all_means);

    /* print some results */
    printf("Average mean: %g\n", ave_mean);
    printf("Sigma of all means: %g\n", mean_sd);
    printf("Percentage of experiments within 2 sigma: ");
    printf("%g%c\n", 100 * ratio_sigma, (char) 37);

    /* Write the number of samples to the fits table */
    fits_write_key(fptr, TLONG, key[0], &num_samples, comment[0], status);
    fits_write_key(fptr, TDOUBLE, key[1], &mean, comment[1], status);
    fits_write_key(fptr, TDOUBLE, key[2], &num_sigma, comment[2], status);
    fits_write_key(fptr, TDOUBLE, key[3], &ave_mean, comment[3], status);
    fits_write_key(fptr, TDOUBLE, key[4], &mean_sd, comment[4], status);
    if (*status){
        printf("Error writing to fits header.\n");
        exit(*status);
    }
}
Beispiel #20
0
int sdfits_write_subint(struct sdfits *sf) {
    int row, *status;
    int nchan, nivals, nsubband;
    struct hdrinfo *hdr;
    struct sdfits_data_columns *dcols;
    char* temp_str;
    double temp_dbl;

    hdr = &(sf->hdr);               // dereference the ptr to the header struct
    dcols = &(sf->data_columns);    // dereference the ptr to the subint struct
    status = &(sf->status);         // dereference the ptr to the CFITSIO status
    nchan = hdr->nchan; 
    nsubband = hdr->nsubband;
    nivals = nchan * nsubband * 4;  // 4 stokes parameters

    // Create the initial file or change to a new one if needed.
    if (sf->new_file || (sf->multifile==1 && sf->rownum > sf->rows_per_file))
    {
        if (!sf->new_file) {
            printf("Closing file '%s'\n", sf->filename);
            fits_close_file(sf->fptr, status);
        }
        sdfits_create(sf);
    }
    row = sf->rownum;
    temp_str = dcols->object;
    temp_dbl = 0.0;
    dcols->centre_freq_idx++;

    fits_write_col(sf->fptr, TDOUBLE, 1,  row, 1, 1, &(dcols->time), status);
    fits_write_col(sf->fptr, TINT,    2,  row, 1, 1, &(dcols->time_counter), status);
    fits_write_col(sf->fptr, TINT,    3,  row, 1, 1, &(dcols->integ_num), status);
    fits_write_col(sf->fptr, TFLOAT,  4,  row, 1, 1, &(dcols->exposure), status);
    fits_write_col(sf->fptr, TSTRING, 5,  row, 1, 1, &temp_str, status);
    fits_write_col(sf->fptr, TFLOAT,  6,  row, 1, 1, &(dcols->azimuth), status);
    fits_write_col(sf->fptr, TFLOAT,  7,  row, 1, 1, &(dcols->elevation), status);
    fits_write_col(sf->fptr, TFLOAT,  8,  row, 1, 1, &(dcols->bmaj), status);
    fits_write_col(sf->fptr, TFLOAT,  9,  row, 1, 1, &(dcols->bmin), status);
    fits_write_col(sf->fptr, TFLOAT,  10,  row, 1, 1, &(dcols->bpa), status);
    fits_write_col(sf->fptr, TINT,    11,  row, 1, 1, &(dcols->accumid), status);
    fits_write_col(sf->fptr, TINT,    12, row, 1, 1, &(dcols->sttspec), status);
    fits_write_col(sf->fptr, TINT,    13, row, 1, 1, &(dcols->stpspec), status);
    fits_write_col(sf->fptr, TDOUBLE, 14, row, 1, nsubband, dcols->centre_freq, status);

    fits_write_col(sf->fptr, TFLOAT,  15, row, 1, 1, &(dcols->centre_freq_idx), status);
    fits_write_col(sf->fptr, TDOUBLE, 16, row, 1, 1, &temp_dbl, status);
    fits_write_col(sf->fptr, TDOUBLE, 17, row, 1, 1, &(sf->hdr.chan_bw), status);
    fits_write_col(sf->fptr, TDOUBLE, 18, row, 1, 1, &(dcols->ra), status);
    fits_write_col(sf->fptr, TDOUBLE, 19, row, 1, 1, &(dcols->dec), status);
    fits_write_col(sf->fptr, TFLOAT,  20, row, 1, nivals, dcols->data, status);

    // Flush the buffers if not finished with the file
    // Note:  this use is not entirely in keeping with the CFITSIO
    //        documentation recommendations.  However, manually 
    //        correcting NAXIS2 and using fits_flush_buffer()
    //        caused occasional hangs (and extrememly large
    //        files due to some infinite loop).
    fits_flush_file(sf->fptr, status);
    // Print status if bad
    if (*status) {
        fprintf(stderr, "Error writing subint %d:\n", sf->rownum);
        fits_report_error(stderr, *status);
        fflush(stderr);
    }

    // Now update some key values if no CFITSIO errors
    if (!(*status)) {
        sf->rownum++;
        sf->tot_rows++;
        sf->N += 1;
        sf->T += dcols->exposure;
    }

    return *status;
}
Beispiel #21
0
int CDfits_write_scanhdr( void )
{
  int status;
  int i, j, k, m, n;
  short int sj;
  
  double dx, dy, dz;
  
  long lk;
    
  int nrows, ncols;
  long naxes[3];

  char *ttype[4], *tform[4], *tunit[4];

  char str[16], Istr[16], *qch, *rch, *sch, *tch;

  int chan_inc, first_normal_group, npols, pol;
      
  float x;

#undef POINT_PAR
#ifdef POINT_PAR

  float xa[12];

#endif
  
  FILE *fp;
  char filename[80];
  
#define GSTR_LEN 88
  char gstr[GSTR_LEN];
  char astr[80];
  
  void *pv;

  char date_time[24];

#define MAX_BLKS 20
  char *pch[MAX_BLKS];
  char site[MAX_BLKS][2];
  short int nspan[MAX_BLKS];
  short int ncoeff[MAX_BLKS];
  double rfreq[MAX_BLKS];
  double rmjd[MAX_BLKS];
  double rphase[MAX_BLKS];
  double lgfiterr[MAX_BLKS];
  double f0[MAX_BLKS];
#define MAX_COEFF 15
  double coeff[MAX_BLKS][MAX_COEFF];


  /* For Pulsar History BINTABLE */
 
  static char *PHtype[18] = {
    "DATE_PRO","PROC_CMD","POL_TYPE","NPOL    ","NBIN    ","NBIN_PRD","TBIN    ","CTR_FREQ",
    "NCHAN   ","CHAN_BW ","PAR_CORR","RM_CORR ","DEDISP  ","DDS_MTHD","SC_MTHD ","CAL_MTHD",
    "CAL_FILE","RFI_MTHD"
  };
  
  static char *PHform[18] = {
    "24A     ","80A     ","8A      ","1I      ","1I      ","1I      ","1D      ","1D      ",
    "1I      ","1D      ","1I      ","1I      ","1I      ","32A     ","32A     ","32A     ",
    "32A     ","32A     "
  };
  
  static char *PHunit[18] = {
    "        ","        ","        ","        ","        ","        ","s       ","MHz     ",
    "        ","MHz     ","        ","        ","        ","        ","        ","        ",
    "        ","        "
  };


  /* For Pulsar Epmemeris BINTABLE */

  static char *PEtype[56] = {
    "DATE_PRO", "PROC_CMD", "EPHVER", "PSR_NAME", "RAJ", "DECJ", "PMRA", "PMDEC", 
    "PX", "POSEPOCH", "IF0", "FF0", "F1", "F2", "F3", "PEPOCH",
    "DM", "DM1", "RM", "BINARY", "T0", "PB", "A1", "OM", 
    "OMDOT", "ECC", "PBDOT", "GAMMA", "SINI", "M2", "T0_2", "PB_2",
    "A1_2", "OM_2", "ECC_2", "DTHETA", "XDOT", "EDOT", "TASC", "EPS1",
    "EPS2", "START", "FINISH", "TRES", "NTOA", "CLK", "EPHEM", "TZRIMJD",
    "TZRFMJD", "TZRFRQ", "TZRSITE", "GLEP_1", "GLPH_1", "GLF0_1", "GLF1_1", "GLF0D_1"
  };
  
  static char *PEform[56] = {
    "24A     ", "80A     ", "16A     ", "16A     ", "24A     ", "24A     ", "1D      ", "1D      ",
    "1D      ", "1D      ", "1J      ", "1D      ", "1D      ", "1D      ", "1D      ", "1D      ",
    "1D      ", "1D      ", "1D      ", "8A      ", "1D      ", "1D      ", "1D      ", "1D      ",
    "1D      ", "1D      ", "1D      ", "1D      ", "1D      ", "1D      ", "1D      ", "1D      ",
    "1D      ", "1D      ", "1D      ", "1D      ", "1D      ", "1D      ", "1D      ", "1D      ",
    "1D      ", "1D      ", "1D      ", "1D      ", "1I      ", "12A     ", "12A     ", "1J      ",
    "1D      ", "1D      ", "1A      ", "1D      ", "1D      ", "1D      ", "1D      ", "1D      "
  };
  
  /* For Pulsar Polyco BINTABLE */

  static char *PPtype[13] = {
    "DATE_PRO", "POLYVER ", "NSPAN   ", "NCOEF   ", "NPBLK   ", "NSITE   ", "REF_FREQ", "PRED_PHS",
    "REF_MJD ", "REF_PHS ", "REF_F0  ", "LGFITERR", "COEFF   "
  };
    
  static char *PPform[13] = {
    "24A     ", "16A     ", "1I      ", "1I      ", "1I      ", "1A      ", "1D      ", "1D      ",
    "1D      ", "1D      ", "1D      ", "1D      ", "15D     ",
  };

  /* BEGIN */

  status = 0;

  /* Get DateTime string - required in various BINTABLEs */
  fits_get_system_time( date_time, &n, &status );
  
  if( new_file ) {

    /* Add required keywords to primary header */

    /* fits_update_key( cfitsptr, TSTRING, "ORIGIN", "RNM", 
       "Output class", &status); */

    fits_update_key( cfitsptr, TSTRING, "OBSERVER", header.observer, 
		     "Observer name(s)", &status);
    fits_update_key( cfitsptr, TSTRING, "PROJID", supplhdr.project, 
		     "Project name", &status);
    fits_update_key( cfitsptr, TSTRING, "TELESCOP", supplhdr.site_name,
		     "Telescope name", &status);
    fits_update_key( cfitsptr, TDOUBLE, "ANT_X", &header.antenna[0].x,
		     "[m] Antenna ITRF X-coordinate (D)", &status);
    fits_update_key( cfitsptr, TDOUBLE, "ANT_Y", &header.antenna[0].y,
		     "[m] Antenna ITRF Y-coordinate (D)", &status);
    fits_update_key( cfitsptr, TDOUBLE, "ANT_Z", &header.antenna[0].z,
		     "[m] Antenna ITRF Z-coordinate (D)", &status);
    fits_update_key( cfitsptr, TSTRING, "FRONTEND", supplhdr.frontend, 
		     "Rx and feed ID", &status);

    fits_update_key( cfitsptr, TSTRING, "FD_POLN", supplhdr.polzn,
		     "LIN or CIRC", &status);
    x = 0.0;
    fits_update_key( cfitsptr, TFLOAT, "XPOL_ANG", &x,
		     "[deg] Angle of X-probe wrt platform zero (E)", &status);

    fits_update_key( cfitsptr, TSTRING, "BACKEND", supplhdr.backend, 
		     "Backend ID", &status);
    fits_update_key( cfitsptr, TSTRING, "BECONFIG", (*c_c).config_menu_name,
		     "Backend configuration file name", &status);

    /* Basic cycle time for integration */
    dx = (*c_c).integ_time / 1.0E06;
    fits_update_key( cfitsptr, TDOUBLE, "TCYCLE", &dx,
		     "[s] Correlator cycle time (D)", &status);

    /* Find the first normal group in band */
    first_normal_group = -1;
    i = (*c_c).band[0].first_group;
    k = i + (*c_c).band[0].num_group - 1;
    while( ( i <= k ) && ( first_normal_group < 0 ) ) {
      if( (*c_c).product[ (*c_c).prod_group[i].first_prod ].type < POL_CAL_OFF ) {
	first_normal_group = i;
      }
      i++;
    }
    if( first_normal_group < 0 ) first_normal_group = 0;

    npols = (*c_c).prod_group[first_normal_group].num_prod;

    /* Receiver channels - best guess */
    if( npols == 1 ) nrcvr = 1;
    else nrcvr = 2;
    
    fits_update_key( cfitsptr, TINT, "NRCVR", &nrcvr,
		     "Number of receiver channels (I)", &status);
    fits_update_key( cfitsptr, TSTRING, "OBS_MODE", supplhdr.obsmode,
		     "(PSR, CAL, SEARCH)", &status);
    /* fits_update_key( cfitsptr, TSTRING, "DATATYPE", "FOLD",
                     "FOLD or DUMP", &status);  */
    fits_update_key( cfitsptr, TSTRING, "SRC_NAME", header.source,
		     "Source or scan ID", &status);
    fits_update_key( cfitsptr, TSTRING, "COORD_MD", header.epoch,
		     "Coordinate mode (J2000, Gal, Ecliptic, etc.)", &status);

    /* J2000 or B1950 */
    if( header.epoch[0] == 'J' || header.epoch[0] == 'B') j = 0;
    /* All others */
    else j = 2;

    rads_to_str( gstr, 16, supplhdr.start_long, j );

    /*
    gstr[17] = '\0';
    printf("\n rads_to_str(mode0) on %f = '%s'", supplhdr.start_long, gstr );
    */

    fits_update_key( cfitsptr, TSTRING, "STT_CRD1", gstr,
		     "Start coord 1 (hh:mm:ss.sss or ddd.ddd)", &status);

    rads_to_str( gstr, 16, supplhdr.start_lat, j+1 );
    fits_update_key( cfitsptr, TSTRING, "STT_CRD2", gstr,
		     "Start coord 2 (-dd:mm:ss.sss or -dd.ddd)", &status);
   
    fits_update_key( cfitsptr, TSTRING, "TRK_MODE", supplhdr.trackmode,
		     "Track mode (TRACK, SCANGC, SCANLAT)", &status);

    rads_to_str( gstr, 16, supplhdr.stop_long, j );
    fits_update_key( cfitsptr, TSTRING, "STP_CRD1", gstr,
		     "Stop coord 1 (hh:mm:ss.sss or ddd.ddd)", &status);

    rads_to_str( gstr, 16, supplhdr.stop_lat, j+1 );
    fits_update_key( cfitsptr, TSTRING, "STP_CRD2", gstr,
		     "Stop coord 2 (-dd:mm:ss.sss or -dd.ddd)", &status);
   
    x = supplhdr.scan_cycles * ( (*c_c).integ_time / 1.0E06 );
    fits_update_key( cfitsptr, TFLOAT, "SCANLEN ", &x,
		     "[s] Requested scan length (E)", &status);
    
    fits_update_key( cfitsptr, TSTRING, "FD_MODE", supplhdr.fdmode,
		     "Feed track mode - Const FA, CPA, GPA", &status);

    fits_update_key( cfitsptr, TFLOAT, "FA_REQ", &supplhdr.xpolang,
		     "[deg] Feed/Posn angle requested (E)", &status);

    fits_update_key( cfitsptr, TFLOAT, "ATTEN_A", &supplhdr.atten_a,
		     "[db] Attenuator, Poln A (E)", &status);

    fits_update_key( cfitsptr, TFLOAT, "ATTEN_B", &supplhdr.atten_b,
		     "[db] Attenuator, Poln B (E)", &status);

    fits_update_key( cfitsptr, TSTRING, "CAL_MODE", supplhdr.calmode,
		     "Cal mode (OFF, SYNC, EXT1, EXT2)", &status);

    x = (float) (*c_c).pulsar_ncal_sig_frequency;
    fits_update_key( cfitsptr, TFLOAT, "CAL_FREQ", &x,
		     "[Hz] Cal modulation frequency (E)", &status);

    x = (float) (*c_c).pulsar_ncal_sig_duty_cycle;
    fits_update_key( cfitsptr, TFLOAT, "CAL_DCYC", &x,
		     "Cal duty cycle (E)", &status);

    x = (float) (*c_c).pulsar_ncal_sig_start_phase;
    fits_update_key( cfitsptr, TFLOAT, "CAL_PHS ", &x,
		     "Cal phase (wrt start time) (E)", &status);
    

    new_file = 0;

  }

#ifdef POINT_PAR

  /* Add Pointing Parameters BINTABLE */

  nrows = 0;  /* naxis2 - Let CFITSIO sort this out */
  ncols = 1; /* tfields */
  ttype[0] = "PPAR    ";
  tform[0] = "12E     ";

  fits_create_tbl( cfitsptr, BINARY_TBL, nrows, ncols, 
		   ttype, tform, NULL, "POINTPAR", &status);

  /* Pointing parameters */
  for( n=0; n<11; n++ ) xa[n] = (float) supplhdr.pointing_parameter[n];
  xa[11] = 0.0;
  fits_write_col( cfitsptr, TFLOAT, 1, 1, 1, 12, xa, &status );

#endif

  /* Add Processing History BINTABLE */

  nrows = 0;  /* naxis2 - Let CFITSIO sort this out */
  ncols = 18; /* tfields */
   
  fits_create_tbl( cfitsptr, BINARY_TBL, nrows, ncols, 
		   PHtype, PHform, PHunit, "HISTORY", &status);

  /* Processing date and time (YYYY-MM-DDThh:mm:ss UTC) */
  pch[0] = date_time;
  fits_write_col( cfitsptr, TSTRING, 1, 1, 1, 1, pch, &status );
  /* Processing program and command */
  pch[0] = "WBCOR";
  fits_write_col( cfitsptr, TSTRING, 2, 1, 1, 1, pch, &status );
  /* Polarisation identifier */
  if( npols < 4 ) {
    str[0] = '\0';
    k = (*c_c).prod_group[first_normal_group].first_prod;
    m = 0;
    for( j=0; j<npols; j++ ) {
      pol = (*c_c).product[k].polarisation;
      if( pol == 1 ) strcat( str, "XX" );
      else if( pol == 2 ) {
	/* An XY product will be written out as two pols, real and imag */
	strcat( str, "CRCI" );
	m++;
      }
      else if( pol == 3 ) {
	/* A YX product will be written out as two pols, real and imag */
	strcat( str, "CRCI" );
	m++;
      }
      else if( pol == 4 ) strcat( str, "YY" );
      else strcat( str, "??" );
      k++;
    }
  }
  else {
    strcpy( str, "XXYYXYYX" );
  }
  pch[0] = str;
  fits_write_col( cfitsptr, TSTRING, 3, 1, 1, 1, pch, &status );

  /* Nr of pols  - i.e. actually written out */
  sj = npols + m;
  fits_write_col( cfitsptr, TSHORT, 4, 1, 1, 1, &sj, &status );

  /* Nr of bins per product (0 for SEARCH mode) */
  sj = (*c_c).band[0].num_bins;
  fits_write_col( cfitsptr, TSHORT, 5, 1, 1, 1, &sj, &status );

  /* Nr of bins per period */
  fits_write_col( cfitsptr, TSHORT, 6, 1, 1, 1, &sj, &status );

  /* Bin time */
  dx =  (*c_c).pulsar_period / sj;
  fits_write_col( cfitsptr, TDOUBLE, 7, 1, 1, 1, &dx, &status );

  /* Centre freq. */
  dx = header.band[0].frequency;  
  fits_write_col( cfitsptr, TDOUBLE, 8, 1, 1, 1, &dx, &status );

  /* Number of channels */
  chan_inc = header.band[0].channel_increment;
  if( chan_inc <= 0 ) chan_inc = 1;
  n = ( ( header.band[0].last_channel - 
		   header.band[0].first_channel ) 
		 / chan_inc ) + 1;

  /* Don't include DC channel */  
  if( header.band[0].first_channel == 1 ) n--;
  
  sj = n;
  fits_write_col( cfitsptr, TSHORT, 9, 1, 1, 1, &sj, &status );

  /* Channel bandwidth */
  dy = header.band[0].bandwidth / (double) ( (*c_c).band[0].nfft / 2 );
  if( header.band[0].spectrum_inverted < 0 ) dy = -dy;

  /* Channel incr. width - signed */
  dx = (double) chan_inc * dy;
  fits_write_col( cfitsptr, TDOUBLE, 10, 1, 1, 1, &dx, &status );

  /* Create frequency array for later */
  /* Get freq. of first channel */
  if( ( k = header.band[0].first_channel ) == 1 ) k = 2;
  
  j = ( (*c_c).band[0].nfft / 4 ) + 1 - k;
  dz = header.band[0].frequency - ( j * dy );

  for(i=0; i<n; i++ ) {
    binned_freq[i] = (float) dz;
    dz += dx;
  }    


  sj = 0;
  /* Parallactic angle correction applied */
  fits_write_col( cfitsptr, TSHORT, 11, 1, 1, 1, &sj, &status );
  /* RM correction applied */
  fits_write_col( cfitsptr, TSHORT, 12, 1, 1, 1, &sj, &status );
  /* Data dedispersed */
  fits_write_col( cfitsptr, TSHORT, 13, 1, 1, 1, &sj, &status );
  /* Dedispersion method */
  pch[0] = "NONE";
  fits_write_col( cfitsptr, TSTRING, 14, 1, 1, 1, pch, &status );
  /* Scattered power correction method */
  pch[0] = supplhdr.scpwr;
  fits_write_col( cfitsptr, TSTRING, 15, 1, 1, 1, pch, &status );
  /* Calibration method */
  pch[0] = "NONE";
  fits_write_col( cfitsptr, TSTRING, 16, 1, 1, 1, pch, &status );
  /* Name of calibration file */
  pch[0] = "NONE";
  fits_write_col( cfitsptr, TSTRING, 17, 1, 1, 1, pch, &status );
  /* RFI excision method */
  pch[0] = supplhdr.rfiex;
  fits_write_col( cfitsptr, TSTRING, 18, 1, 1, 1, pch, &status );


  /* Add Original BANDPASS BINTABLE */

  nrows = 0;  /* naxis2 - Let CFITSIO sort this out */
  ncols = 3;  /* tfields */

  nchan_orig = ( (*c_c).band[0].nfft / 2 ) + 1;

  naxes[0] = nchan_orig;
  naxes[1] = nrcvr;

  sprintf( str, "%ldE", naxes[1] );

  ttype[0] = "DAT_OFFS";
  tform[0] = str;
  tunit[0] = "";

  ttype[1] = "DAT_SCL ";
  tform[1] = str;
  tunit[1] = "";

  sprintf( Istr, "%ldI", ( naxes[0] * naxes[1] ) );
  ttype[2] = "DATA    ";
  tform[2] = Istr;
  tunit[2] = "Jy      ";

  fits_create_tbl( cfitsptr, BINARY_TBL, nrows, ncols, 
		   ttype, tform, tunit, "BANDPASS", &status);

  /* Add dimensions of column 3 = BANDPASS Data */  
  fits_write_tdim( cfitsptr, 3, 2, naxes, &status );

  /* Add keywords */
  fits_update_key( cfitsptr, TINT, "NCH_ORIG", &nchan_orig,
		     "Number of channels in original bandpass (I)", &status);
  fits_update_key( cfitsptr, TINT, "BP_NPOL ", &nrcvr,
		     "Number of polarizations in bandpass (I)", &status);

  /* Store hdu number */
  fits_get_hdu_num( cfitsptr, &bpass_hdu );


  /* Add Pulsar Ephemeris BINTABLE */

  nrows = 0;  /* naxis2 - Let CFITSIO sort this out */
  ncols = 56; /* tfields */

  fits_create_tbl( cfitsptr, BINARY_TBL, nrows, ncols, 
		   PEtype, PEform, NULL, "PSREPHEM", &status);

  /* Processing date and time (YYYY-MM-DDThh:mm:ss UTC) */
  pch[0] = date_time;
  fits_write_col( cfitsptr, TSTRING, 1, 1, 1, 1, pch, &status );
  /* Processing program and command */
  pch[0] = "WBCOR";
  fits_write_col( cfitsptr, TSTRING, 2, 1, 1, 1, pch, &status );
  /* Ephemeris version */
  pch[0] = "PSRINFO:1.4";
  fits_write_col( cfitsptr, TSTRING, 3, 1, 1, 1, pch, &status );

  /* Open ephemeris file */
  /* Construct filename  */
  if( ( qch = getenv( "cor_pulsar" ) ) == NULL ) return(-11);

  strcpy( filename, qch );
  if( filename[ strlen(filename) - 1 ] != '/' )
    strcat( filename, "/" );
  strcat( filename, "online.eph" );
 
  if( ( fp = fopen( filename, "r" ) ) == NULL ) return(-12);

  while( fgets( gstr, GSTR_LEN, fp ) != NULL ) {

    if( ( qch = strtok( gstr, " " ) ) != NULL ) {

      /* Following gets a name change - From PSRJ to PSR_NAME */
      if( strcmp( qch, "PSRJ" ) == 0 ) i = 3;
      /* Following two get split into integer and fractional parts */
      else if( strcmp( qch, "F" ) == 0 ) i = 10;
      else if( strcmp( qch, "F0" ) == 0 ) i = 10; /* Possible alternative to just F */
      else if( strcmp( qch, "TZRMJD" ) == 0 ) i = 47;
      else {
	for( i=0; i<ncols; i++ ) {
	  if( strcmp( qch, PEtype[i] ) == 0 ) break;
	}
      }

      if( i < ncols ) {
	/* Get next parameter */
	if( ( rch = strtok( NULL, " " ) ) == NULL ) return(-13);

	if( i == 10 || i == 47 || ( qch = strchr( PEform[i], 'D' ) ) != NULL ) {
	  /* Change any D exponent to E */
	  if( ( sch = strrchr( rch, 'D' ) ) != NULL ) *sch = 'E';
	  tch = sch;
	
	  if( i == 10 || i == 47 ) {
	    /* Convert to integer + fractional part AND
	       if i == 10 convert from Hz to mHz i.e. multiply by 1000 */
	    /* Get exponent */
	    if( sch != NULL ) {
	      if( sscanf( ++sch, "%d", &j ) != 1 )  return(-91);
	    }
	    else j = 0;
	  
	    /* get position of decimal point */
	    if( ( sch = strrchr( rch, '.' ) ) == NULL ) {
	      /* Integer part only */
	      if( sscanf( rch, "%ld", &lk ) != 1 ) return(-92);
	      dx = 0.0;
	    }
	    else {
	      /* Decimal point present */
	      if( i == 10 ) j += 3;  /* multiply by 1000 - sec. to ms. */

	      if( j >= 0 ) {
		k = (int) ( sch - rch );
		if( k > 0 ) {
		  strncpy( astr, rch, k );
		  astr[k] = '\0';
		}
		else strcpy( astr, "0" );
	      
		if( j > 0 ) { /* multiply by 10**j, i.e. move decimal point */
		  strncat( astr, (sch+1), j );
		  *(sch += j) = '.';
		  *--sch = '0';
		}
		/* Now astr contains integer part, sch points to fractional part */
		if( sscanf( astr, "%ld", &lk ) != 1 ) return(-93);
		/* Don't want exponent - reduced to fraction */
		if( tch != NULL ) *tch = '\0';
		if( sscanf( sch, "%lf", &dx ) != 1 ) return(-94);
	      }
	      else {
		/* Fractional part only */
		lk = 0;
		if( sscanf( sch, "%lf", &dx ) != 1 ) return(-94);
		if( i == 10 ) dx *= 1000.0;
	      }
	    	    
	    }
	  
	    pv = &lk;
	    j = TLONG;

	  }
	  else {

	    if( sscanf( rch, "%lf", &dx ) != 1 ) return(-14);

	    j = TDOUBLE;
	    pv = &dx;

	  }	
	}
	else if( ( qch = strchr( PEform[i], 'A' ) ) != NULL ) {
	  j = TSTRING;
	  /* Strip off any trailing newline */
	  if( ( sch = strrchr( rch, '\n' ) ) != NULL ) *sch = '\0';
	  pch[0] = rch;
	  pv = pch;
	}
	else if( ( qch = strchr( PEform[i], 'I' ) ) != NULL ) {
	  j = TSHORT;
	  if( sscanf( rch, "%d", &k ) != 1 ) return(-15);
	  sj = k;
	  pv = &sj;
	}
	else if( ( qch = strchr( PEform[i], 'J' ) ) != NULL ) {
	  j = TINT;
	  if( sscanf( rch, "%d", &k ) != 1 ) return(-16);
	  pv = &k;
	}
	else return(-17);
            
	fits_write_col( cfitsptr, j, i+1, 1, 1, 1, pv, &status );

	/* Write fractional part */
	if( i == 10 || i == 47 ) {
	  j = TDOUBLE;
	  pv = &dx;
	  fits_write_col( cfitsptr, j, i+2, 1, 1, 1, pv, &status );
	  
	  printf( "\n In Ephemeris BINTABLE: %s = %ld %e", PEtype[i], lk, dx );
	}
      }
    }
  }
  fclose( fp );
  
  /* Add Digitiser Statistics BINTABLE */

  nrows = 0;  /* naxis2 - Let CFITSIO sort this out */
  ncols = 1; /* tfields */

  wbsam_levs = 2;
  num_wbsams = nrcvr;

  naxes[0] = wbsam_levs;
  naxes[1] = num_wbsams;
  if( ( n = header.cycles_to_avg ) <= 0 ) n = 1;
  naxes[2] = n;

  sprintf( str, "%ldE", ( naxes[0] * naxes[1] * naxes[2] ) );
  ttype[0] = "DATA    ";
  tform[0] = str;

  fits_create_tbl( cfitsptr, BINARY_TBL, nrows, ncols, 
		   ttype, tform, NULL, "DIG_STAT", &status);

  /* Add dimensions of column 1 = Data */  
  fits_write_tdim( cfitsptr, 1, 3, naxes, &status );

  /* Add keywords */
  fits_update_key( cfitsptr, TSTRING, "DIG_MODE", "2-bit,3-level",
		     "Digitiser mode", &status);
  fits_update_key( cfitsptr, TINT, "NDIGR", &num_wbsams,
		     "Number of digitised channels (I)", &status);
  fits_update_key( cfitsptr, TINT, "NLEV", &wbsam_levs,
		     "Number of digitiser levels (I)", &status);
  fits_update_key( cfitsptr, TINT, "NCYCSUB", &n,
		     "Number of correlator cycles per subint (I)", &status);

  /* Store current hdu number */
  fits_get_hdu_num( cfitsptr, &dig_stats_hdu );


  
  /* Add Polyco History BINTABLE */

  /* Read in polyco file */
  /* Construct filename from .eph name  */

  qch = strstr( filename, ".eph" );
  *qch = '\0';
  strcat( filename, ".polyco" );
  if( ( fp = fopen( filename, "r" ) ) == NULL ) return(-18);

  k = 0;
  while( ( k < MAX_BLKS ) && 
	 ( ( n = fscanf( fp, "%s %s%lf%lf%lf%lf%lf%lf%lf %s%hd%hd%lf%16c", 
			 gstr, gstr, &dx, &rmjd[k], &dx, &dx, &lgfiterr[k], &rphase[k], &f0[k],
			 site[k], &nspan[k], &ncoeff[k], &rfreq[k], gstr ) ) != EOF ) ) {
    if( n != 14 ) return(-20);
    if( ncoeff[k] > MAX_COEFF ) return(-21);
    
    for( i=0; i<ncoeff[k]; i++ ) {
      if( fscanf( fp, "%s", gstr  ) != 1 ) return(-22);
      /* Translate exponent D to E */
      if( ( qch = strchr( gstr, (int) 'D' ) ) != NULL ) *qch = 'E';
      if( sscanf( gstr, "%lE", &coeff[k][i] ) != 1 ) return(-23);
    }
    for( i=ncoeff[k]; i<MAX_COEFF; i++ ) coeff[k][i] = 0.0;
    k++;
  }
  if( k >= MAX_BLKS ) return(-24);
  
  fclose( fp );

  printf("\nCFITS_SUBS:  Polyco - Site[0,1](hex) = %x %x", site[0][0], site[0][1] );
  

  nrows = 0;  /* naxis2 - Let CFITSIO sort this out */
  ncols = 13; /* tfields */
  

  fits_create_tbl( cfitsptr, BINARY_TBL, nrows, ncols, 
		   PPtype, PPform, NULL, "POLYCO  ", &status);

  /* Processing date and time (YYYY-MM-DDThh:mm:ss UTC) */
  for( i=0; i<k; i++ ) pch[i] = date_time;
  fits_write_col( cfitsptr, TSTRING, 1, 1, 1, k, pch, &status );
  /* Polyco version */
  for( i=0; i<k; i++ ) pch[i] = "TEMPO:11.0";
  fits_write_col( cfitsptr, TSTRING, 2, 1, 1, k, pch, &status );
  /* Span of polyco in min */
  fits_write_col( cfitsptr, TSHORT, 3, 1, 1, k, nspan, &status );
  /* Nr of coefficients - per block */
  fits_write_col( cfitsptr, TSHORT, 4, 1, 1, k, ncoeff, &status );
  /* Nr of polyco blocks (of NCOEF coefficients) -reuse nspan array */
  for( i=0; i<k; i++ ) nspan[i] = k;
  fits_write_col( cfitsptr, TSHORT, 5, 1, 1, k, nspan, &status );
  /* TEMPO site code - 1 character */
  for( i=0; i<k; i++ ) pch[i] = &site[i][0];
  fits_write_col( cfitsptr, TSTRING, 6, 1, 1, k, pch, &status );
  /* Reference frequency for phase */
  fits_write_col( cfitsptr, TDOUBLE, 7, 1, 1, k, rfreq, &status );

  /* Predicted pulse phase at obs start - reuse rfreq  */
  for( i=0; i<k; i++ ) rfreq[i] = newcycle.WBpsr_timer_start_phase;
  fits_write_col( cfitsptr, TDOUBLE, 8, 1, 1, k, rfreq, &status );

  /* Reference MJD - NPBLK doubles */
  fits_write_col( cfitsptr, TDOUBLE, 9, 1, 1, k, rmjd, &status );
  /* Reference phase - NPBLK doubles */
  fits_write_col( cfitsptr, TDOUBLE, 10, 1, 1, k, rphase, &status );
  /* Reference F0 - NPBLK doubles */
  fits_write_col( cfitsptr, TDOUBLE, 11, 1, 1, k, f0, &status );
  /* Fit error - NPBLK doubles */
  fits_write_col( cfitsptr, TDOUBLE, 12, 1, 1, k, lgfiterr, &status );
  /* Polyco coefficients - NPBLK*NCOEF doubles */
  j = k * MAX_COEFF;
  fits_write_col( cfitsptr, TDOUBLE, 13, 1, 1, j, &coeff[0][0], &status );


  /* Store last header hdu number */
  fits_get_hdu_num( cfitsptr, &last_scanhdr_hdu );
  
  /* Restart SUBINT counter */
  subint_cnt = 0;
  
  return( status );

}
Beispiel #22
0
str FITSexportTable(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	str msg = MAL_SUCCEED;
	str tname = *(str*) getArgReference(stk, pci, 1);
	mvc *m = NULL;
	sql_trans *tr;
	sql_schema *sch;
	sql_table *tbl, *column, *tables = NULL;
	sql_column *col;
	oid rid = oid_nil;
	str type, name, *colname, *tform;
	fitsfile *fptr;
	char filename[BUFSIZ];
	long nrows = 0, optimal;
	rids * rs;

	int tm0, texportboolean=0, texportchar=0, texportstring=0, texportshort=0, texportint=0, texportlong=0, texportfloat=0, texportdouble=0;
	int numberrow = 0, cc = 0, status = 0, j = 0, columns, fid, dimension = 0, block = 0;
	int boolcols = 0, charcols = 0, strcols = 0, shortcols = 0, intcols = 0, longcols = 0, floatcols = 0, doublecols = 0;
	int hdutype;

	char charvalue, *readcharrows;
	str strvalue; char **readstrrows;
	short shortvalue, *readshortrows;
	int intvalue, *readintrows;
	long longvalue, *readlongrows;
	float realvalue, *readfloatrows;
	double doublevalue, *readdoublerows;
	_Bool boolvalue, *readboolrows;
	struct list * set;

	msg = getSQLContext(cntxt, mb, &m, NULL);
	if (msg)
		return msg;

	tr = m->session->tr;
	sch = mvc_bind_schema(m, "sys");

	/* First step: look if the table exists in the database. If the table is not in the database, the export function cannot continue */
 
	tbl = mvc_bind_table(m, sch, tname);
	if (tbl == NULL) {
		msg = createException (MAL, "fits.exporttable", "Table %s is missing.\n", tname);
		return msg;
	}

	set = (*tbl).columns.set;

	columns = list_length(set);
	colname = (str *) GDKmalloc(columns * sizeof(str));
	tform = (str *) GDKmalloc(columns * sizeof(str));

	/*	mnstr_printf(GDKout,"Number of columns: %d\n", columns);*/

	tables = mvc_bind_table(m, sch, "_tables");
	col = mvc_bind_column(m, tables, "name");
	rid = table_funcs.column_find_row(m->session->tr, col, tname, NULL);

	col = mvc_bind_column(m, tables, "id");
	fid = *(int*) table_funcs.column_find_value(m->session->tr, col, rid);

	column =  mvc_bind_table(m, sch, "_columns");
	col = mvc_bind_column(m, column, "table_id");

	rs = table_funcs.rids_select(m->session->tr, col, (void *) &fid, (void *) &fid, NULL);

	while ((rid = table_funcs.rids_next(rs)) != oid_nil)
	{
		col = mvc_bind_column(m, column, "name");
		name = (char *) table_funcs.column_find_value(m->session->tr, col, rid);
		colname[j] = toLower(name);

		col = mvc_bind_column(m, column, "type");
		type = (char *) table_funcs.column_find_value(m->session->tr, col, rid);

		if (strcmp(type,"boolean")==0) tform[j] = "1L";

 		if (strcmp(type,"char")==0) tform[j] = "1S";

		if (strcmp(type,"varchar")==0) tform[j] = "8A";

		if (strcmp(type,"smallint")==0) tform[j] = "1I";

		if (strcmp(type,"int")==0) tform[j] = "1J";

		if (strcmp(type,"bigint")==0) tform[j] = "1K";

		if (strcmp(type,"real")==0) tform[j] = "1E";

		if (strcmp(type,"double")==0) tform[j] = "1D";

		j++;
	}

	col = mvc_bind_column(m, tbl, colname[0]);

	nrows = store_funcs.count_col(tr, col, 1);

	snprintf(filename,BUFSIZ,"\n%s.fit",tname);
	mnstr_printf(GDKout, "Filename: %s\n", filename);

	remove(filename);

	status=0;

	fits_create_file(&fptr, filename, &status);
	fits_create_img(fptr,  USHORT_IMG, 0, NULL, &status);
	fits_close_file(fptr, &status);
	fits_open_file(&fptr, filename, READWRITE, &status);

	fits_movabs_hdu(fptr, 1, &hdutype, &status);
	fits_create_tbl( fptr, BINARY_TBL, 0, columns, colname, tform, NULL, tname, &status);

	for (cc = 0; cc < columns; cc++)
	{
		char * columntype;
		col = mvc_bind_column(m, tbl, colname[cc]);
		columntype = col -> type.type->sqlname;

		if (strcmp(columntype,"boolean")==0)
		{
			boolcols++; dimension = 0; block = 0;
			fits_get_rowsize(fptr,&optimal,&status);
			readboolrows = (_Bool *) GDKmalloc (sizeof(_Bool) * optimal);

			for (numberrow = 0; numberrow < nrows ; numberrow++)
			{
				boolvalue = *(_Bool*) table_funcs.column_find_value(m->session->tr, col, numberrow);
				readboolrows[dimension] = boolvalue;
				dimension++;

				if (dimension == optimal)
				{
					dimension = 0;
					tm0 = GDKms();
					fits_write_col(fptr, TLOGICAL, cc+1, (optimal*block)+1, 1, optimal, readboolrows, &status);
					texportboolean += GDKms() - tm0;
					GDKfree(readboolrows);
					readboolrows = (_Bool *) GDKmalloc (sizeof(_Bool) * optimal);
					block++;
				}
			}
			tm0 = GDKms();
			fits_write_col(fptr, TLOGICAL, cc+1, (optimal*block)+1, 1, dimension, readboolrows, &status);
			texportboolean += GDKms() - tm0;
			GDKfree(readboolrows);		
		}

		if (strcmp(columntype,"char")==0)
		{
			charcols++; dimension = 0; block = 0;
			fits_get_rowsize(fptr,&optimal,&status);
			readcharrows = (char *) GDKmalloc (sizeof(char) * optimal);

			for (numberrow = 0; numberrow < nrows ; numberrow++)
			{
				charvalue = *(char*) table_funcs.column_find_value(m->session->tr, col, numberrow);
				readcharrows[dimension] = charvalue;
				dimension++;

				if (dimension == optimal)
				{
					dimension = 0;
					tm0 = GDKms();
					fits_write_col(fptr, TBYTE, cc+1, (optimal*block)+1, 1, optimal, readcharrows, &status);
					texportchar += GDKms() - tm0;
					GDKfree(readcharrows);
					readcharrows = (char *) GDKmalloc (sizeof(char) * optimal);
					block++;
				}
			}
			tm0 = GDKms();
			fits_write_col(fptr, TBYTE, cc+1, (optimal*block)+1, 1, dimension, readcharrows, &status);
			texportchar += GDKms() - tm0;
			GDKfree(readcharrows);
		}

		if (strcmp(columntype,"varchar")==0)
		{
			strcols++; dimension=0; block=0;
			fits_get_rowsize(fptr,&optimal,&status);
			readstrrows = (char **) GDKmalloc (sizeof(char *) * optimal);

			for (numberrow = 0; numberrow < nrows ; numberrow++)
			{
				strvalue = (char *) table_funcs.column_find_value(m->session->tr, col, numberrow);
				readstrrows[dimension] = strvalue;
				dimension++;

				if (dimension == optimal)
				{
					dimension = 0;
					tm0 = GDKms();
					fits_write_col_str(fptr, cc+1, (optimal*block)+1, 1, optimal, readstrrows, &status);
					texportstring += GDKms() - tm0;
					GDKfree(readstrrows);
					readstrrows = (char **) GDKmalloc(sizeof(char *) * optimal);
					block++;
				}
			}
			tm0 = GDKms();
			fits_write_col_str(fptr, cc+1, (optimal*block)+1, 1, dimension, readstrrows, &status);
			texportstring += GDKms() - tm0;
			GDKfree(readstrrows);
		}

		if (strcmp(columntype,"smallint")==0)
		{
			shortcols++; dimension = 0; block = 0;
			fits_get_rowsize(fptr,&optimal,&status);
			readshortrows = (short *) GDKmalloc (sizeof(short) * optimal);

			for (numberrow = 0; numberrow < nrows ; numberrow++)
			{
				shortvalue = *(short*) table_funcs.column_find_value(m->session->tr, col, numberrow);
				readshortrows[dimension] = shortvalue;
				dimension++;

				if (dimension == optimal)
				{
					dimension = 0;
					tm0 = GDKms();
					fits_write_col(fptr, TSHORT, cc+1, (optimal*block)+1, 1, optimal, readshortrows, &status);
					texportshort += GDKms() - tm0;
					GDKfree(readshortrows);
					readshortrows = (short *) GDKmalloc (sizeof(short) * optimal);
					block++;
				}
			} 
			tm0 = GDKms();
			fits_write_col(fptr, TSHORT, cc+1, (optimal*block)+1, 1, dimension, readshortrows, &status);
			texportshort += GDKms() - tm0;
			GDKfree(readshortrows);
		}

		if (strcmp(columntype,"int")==0)
		{
			intcols++; dimension = 0; block = 0;
			fits_get_rowsize(fptr,&optimal,&status);
			readintrows = (int *) GDKmalloc (sizeof(int) * optimal);

			for (numberrow = 0; numberrow < nrows ; numberrow++)
			{
				intvalue = *(int*) table_funcs.column_find_value(m->session->tr, col, numberrow);
				readintrows[dimension] = intvalue;
				dimension++;

				if (dimension == optimal)
				{
					dimension = 0;
					tm0 = GDKms();
					fits_write_col(fptr, TINT, cc+1, (optimal*block)+1, 1, optimal, readintrows, &status);
					texportint += GDKms() - tm0;
					GDKfree(readintrows);
					readintrows = (int *) GDKmalloc (sizeof(int) * optimal);
					block++;
				}
			} 
			tm0 = GDKms();
			fits_write_col(fptr, TINT, cc+1, (optimal*block)+1, 1, dimension, readintrows, &status);
			texportint += GDKms() - tm0;
			GDKfree(readintrows);	
		}

		if (strcmp(columntype,"bigint")==0)
		{
			longcols++; dimension = 0; block = 0;
			fits_get_rowsize(fptr,&optimal,&status);
			readlongrows = (long *) GDKmalloc (sizeof(long) * optimal);

			for (numberrow = 0; numberrow < nrows ; numberrow++)
			{
				longvalue = *(long*) table_funcs.column_find_value(m->session->tr, col, numberrow);
				readlongrows[dimension] = longvalue;
				dimension++;

				if (dimension == optimal)
				{
					dimension = 0;
					tm0 = GDKms();
					fits_write_col(fptr, TLONG, cc+1, (optimal*block)+1, 1, optimal, readlongrows, &status);
					texportlong += GDKms() - tm0;
					GDKfree(readlongrows);
					readlongrows = (long *) GDKmalloc (sizeof(long) * optimal);
					block++;
				}
			} 
			tm0 = GDKms();
			fits_write_col(fptr, TLONG, cc+1, (optimal*block)+1, 1, dimension, readlongrows, &status);
			texportlong += GDKms() - tm0;
			GDKfree(readlongrows);
		}

		if (strcmp(columntype,"real")==0)
		{
			floatcols++; dimension = 0; block = 0;
			fits_get_rowsize(fptr,&optimal,&status);
			readfloatrows = (float *) GDKmalloc (sizeof(float) * optimal);

			for (numberrow = 0; numberrow < nrows ; numberrow++)
			{
				realvalue = *(float*) table_funcs.column_find_value(m->session->tr, col, numberrow);
				readfloatrows[dimension] = realvalue;
				dimension++;

				if (dimension == optimal)
				{
					dimension = 0;
					tm0 = GDKms();
					fits_write_col(fptr, TFLOAT, cc+1, (optimal*block)+1, 1, optimal, readfloatrows, &status);
					texportfloat += GDKms() - tm0;
					GDKfree(readfloatrows);
					readfloatrows = (float *) GDKmalloc (sizeof(float) * optimal);
					block++;
				}
			} 
			tm0 = GDKms();
			fits_write_col(fptr, TFLOAT, cc+1, (optimal*block)+1, 1, dimension, readfloatrows, &status);
			texportfloat += GDKms() - tm0;
			GDKfree(readfloatrows);
		}

		if (strcmp(columntype,"double")==0)
		{
			doublecols++; dimension = 0; block = 0;
			fits_get_rowsize(fptr,&optimal,&status);
			readdoublerows = (double *) GDKmalloc (sizeof(double) * optimal);

			for (numberrow = 0; numberrow < nrows ; numberrow++)
			{
				doublevalue = *(double*) table_funcs.column_find_value(m->session->tr, col, numberrow);
				readdoublerows[dimension] = doublevalue;
				dimension++;

				if (dimension == optimal)
				{
					dimension = 0;
					tm0 = GDKms();
					fits_write_col(fptr, TDOUBLE, cc+1, (optimal*block)+1, 1, optimal, readdoublerows, &status);
					texportdouble += GDKms() - tm0;
					GDKfree(readdoublerows);
					readdoublerows = (double *) GDKmalloc (sizeof(double) * optimal);
					block++;
				}
			}
			tm0 = GDKms();
			fits_write_col(fptr, TDOUBLE, cc+1, (optimal*block)+1, 1, optimal, readdoublerows, &status);
			texportdouble += GDKms() - tm0;
			GDKfree(readdoublerows); 
		}
	}

	/* print all the times that were needed to export each one of the columns
		
	mnstr_printf(GDKout, "\n\n");
	if (texportboolean > 0)		mnstr_printf(GDKout, "%d Boolean\tcolumn(s) exported in %d ms\n", boolcols,   texportboolean);
	if (texportchar > 0)		mnstr_printf(GDKout, "%d Char\t\tcolumn(s) exported in %d ms\n",    charcols,   texportchar);
	if (texportstring > 0)		mnstr_printf(GDKout, "%d String\tcolumn(s) exported in %d ms\n",  strcols,    texportstring);
	if (texportshort > 0)		mnstr_printf(GDKout, "%d Short\t\tcolumn(s) exported in %d ms\n",   shortcols,  texportshort);
	if (texportint > 0)		mnstr_printf(GDKout, "%d Integer\tcolumn(s) exported in %d ms\n", intcols,    texportint);
	if (texportlong > 0)		mnstr_printf(GDKout, "%d Long\t\tcolumn(s) exported in %d ms\n",    longcols,   texportlong);
	if (texportfloat > 0)		mnstr_printf(GDKout, "%d Float\t\tcolumn(s) exported in %d ms\n",   floatcols,  texportfloat);
	if (texportdouble > 0) 		mnstr_printf(GDKout, "%d Double\tcolumn(s) exported in %d ms\n",  doublecols, texportdouble);
	*/

	fits_close_file(fptr, &status);
	return msg;
}
Beispiel #23
0
int
vot_writeFITSData (fitsfile *fp, char **data, char *fmt[], int nrows, int ncols)
{
    int     i, j, n, type, width, status = 0;
    char    **ccol, *tform, cell[1024], *tok, *sep = " ", *brkt = NULL;
    float  *fcol;
    double *dcol;
    long   *icol;
    long    frow = 1, felem = 1;
    

    for (j = 0; j < ncols; j++) {

	tform = fmt[j];
	width = atoi (tform);
	type = strlen (tform) - 1;

	switch (tform[type]) {
	case 'A':						/* CHAR	    */
    	    ccol = (char **) calloc (1, (nrows * (width+1) * sizeof (char *)));

    	    for (i = 0; i < nrows; i++)
        	ccol[i] = (char *) data[i * ncols + j];

	    fits_write_col (fp, TSTRING, j+1, frow,felem, nrows, ccol, &status);
	    free ((void *) ccol);
	    break;

	case 'D':						/* DOUBLE   */
    	    dcol = (double *) calloc (1, (nrows * (width+1) * sizeof (double)));

	    if (width == 0) {
    	        for (i = 0; i < nrows; i++)
        	    ((double *) dcol)[i] = (double) atof (data[i * ncols + j]);
	        fits_write_col (fp, TDOUBLE, j+1, frow,felem, nrows, dcol, 
			&status);
	    } else {
		double *dp = dcol, *dpr = dp;

    	        for (i = 0; i < nrows; i++) {
		    brkt = NULL;
		    memset (cell, 0, 1024);
		    strcpy (cell, data[i * ncols + j]);

		    dpr = dp;
		    for (n=1, tok=strtok_r (cell, sep, &brkt); tok;
		         tok=strtok_r (NULL, sep, &brkt), n++)
			    *dp++ = (double) atof (tok);
		    for ( ; n < width; n++)		/* missing values  */
			*dp++ = (double) 0.0;

	            fits_write_col (fp, TDOUBLE, j+1, i+1,felem, width, dpr, 
			&status);
		}
	    }

	    free ((void *) dcol);
	    break;

	case 'E':						/* FLOAT    */
    	    fcol = (float *) calloc (1, (nrows * (width+1) * sizeof (float)));

	    if (width == 0) {
    	        for (i = 0; i < nrows; i++)
        	    ((float *) fcol)[i] = (float) atof (data[i * ncols + j]);
	        fits_write_col (fp, TFLOAT, j+1, frow,felem, nrows, fcol, 
			&status);
	    } else {
		float *rp = fcol, *rpr = rp;

    	        for (i = 0; i < nrows; i++) {
		    brkt = NULL;
		    memset (cell, 0, 1024);
		    strcpy (cell, data[i * ncols + j]);

		    rpr = rp;
		    for (n=1, tok=strtok_r (cell, sep, &brkt); tok;
		         tok=strtok_r (NULL, sep, &brkt), n++)
			    *rp++ = (float) atof (tok);
		    for ( ; n < width; n++)		/* missing values  */
			*rp++ = (float) 0.0;

	            fits_write_col (fp, TFLOAT, j+1, i+1,felem, width, rpr, 
			&status);
		}
	    }

	    free ((void *) fcol);
	    break;

	case 'J':						/* INT      */
    	    icol = (long *) calloc (1, (nrows * (width+1) * sizeof (long)));

	    if (width == 0) {
    	        for (i = 0; i < nrows; i++)
        	    ((long *) icol)[i] = (long) atoi (data[i * ncols + j]);
	        fits_write_col (fp, TLONG, j+1, frow,felem, nrows, icol, 
			&status);
	    } else {
		long *ip = icol, *ipr = ip;

    	        for (i = 0; i < nrows; i++) {
		    brkt = NULL;
		    memset (cell, 0, 1024);
		    strcpy (cell, data[i * ncols + j]);

		    ipr = ip;
		    for (n=1, tok=strtok_r (cell, sep, &brkt); tok;
		         tok=strtok_r (NULL, sep, &brkt), n++)
			    *ip++ = (long) atoi (tok);
		    for ( ; n < width; n++)		/* missing values  */
			*ip++ = (long) 0;

	            fits_write_col (fp, TLONG, j+1, i+1,felem, width, ipr, 
			&status);
		}
	    }

	    free ((void *) icol);
	    break;

	default:
	    fprintf (stderr, "Invalid column type '%c'\n", tform[type]);
	    continue;
	}
    }

    return (0);
}
Beispiel #24
0
int main(int argc, char *argv[]) {
    fitsfile *infile;
    int ii, jj, kk, status = 0;
    int nchan, nchan2, npol, wgts_col, offs_col;
    long nrows;
    float *weights, *offsets;
    char comment[120];

    // Read the weights and offsets
    read_wgts_and_offs(argv[1], &nchan, &weights, &offsets);
    printf("Read in %d channels of weights and offsets from\n\t'%s'\n", 
           nchan, argv[1]);

    // Step through the FITS files
    for (ii = 0 ; ii < argc-2 ; ii++) {
        printf("Updating '%s'\n", argv[ii+2]);
        
        // Is the file a PSRFITS file?
        if (!is_PSRFITS(argv[ii+2])) {
            fprintf(stderr,
                    "  Error!  '%s' does not appear to be PSRFITS!\n",
                    argv[ii+2]);
            exit(1);
        }
        
        // Open the PSRFITS file
        fits_open_file(&infile, argv[ii+2], READWRITE, &status);
        if (status) {
            printf("  Error!  Cannot open '%s'!\n", argv[ii+2]);
            exit(1);
        }

        // Move to the SUBINT HDU
        fits_movnam_hdu(infile, BINARY_TBL, "SUBINT", 0, &status);
        if (status) {
            printf("  Warning!  Cannot find NPOL in '%s'!  Assuming NPOL=1\n", 
                   argv[ii+2]);
            status = 0;
        }

        // Read the number of channels and polarizations
        fits_read_key(infile, TINT, "NCHAN", &nchan2, comment, &status); \
        if (status) {
            printf("  Warning!  Cannot find NCHAN in '%s'!\n", argv[ii+2]);
            status = 0;
        } else if (nchan != nchan2) {
            printf("  Error!  The number of channels in '%s'\n", argv[1]);
            printf("          and in '%s' do not match!\n", argv[ii+2]);
            exit(1);
        }
        fits_read_key(infile, TINT, "NPOL", &npol, comment, &status); \
        if (status) {
            printf("  Warning!  Cannot find NPOL in '%s'!  Assuming NPOL=1\n", 
                   argv[ii+2]);
            npol = 1;
            status = 0;
        }
        
        // How many rows are there?
        fits_get_num_rows(infile, &nrows, &status);
        if (status) {
            printf("  Error!  Cannot read the number of rows in '%s'!\n", 
                   argv[ii+2]);
            exit(1);
        }

        // Get the column numbers for the weights
        fits_get_colnum(infile, 0, "DAT_WTS", &wgts_col, &status);
        if (status==COL_NOT_FOUND) {
            printf("  Warning!:  Can't find the channel weights!\n");
            status = 0;
        } else {
            // update the weights, row by row
            for (jj = 1 ; jj < nrows+1 ; jj++)
                fits_write_col(infile, TFLOAT, wgts_col, jj, 
                               1L, nchan, weights, &status);
        }
        
        // Get the column numbers for the offsets
        if (0) {
            fits_get_colnum(infile, 0, "DAT_OFFS", &offs_col, &status);
            if (status==COL_NOT_FOUND) {
                printf("  Warning!:  Can't find the channel offsets!\n");
                status = 0;
            } else {
                // update the offsets, row by row
                for (jj = 1 ; jj < nrows+1 ; jj++)
                    for (kk = 0 ; kk < npol ; kk++)
                        fits_write_col(infile, TFLOAT, offs_col, jj, 
                                       kk*nchan+1L, nchan, offsets, &status);
            }
        }
        
        // Close the file
        fits_close_file(infile, &status);
        if (status) {
            printf("  Warning!:  Cannot properly close '%s' (status=%d)!\n", 
                   argv[ii+2], status);
            status = 0;
        }
    }
    free(weights);
    free(offsets);
    printf("Finished.\n");
    exit(0);
}
Beispiel #25
0
void write_profiles(float *prof,int nbins, int nchan, int nifs, FILE *out)/*includefile*/
{
  int i,j,c,b,k,m,year,month,day;
  float *profile,scale,offset,rms,epoch;
  double usec,tbin,tres,psec;
  static int first=1;
  struct EPN epn;

  int sta=0;
  short int sj;
  float x,binned_freq[16384],binned_weight[16384],
    binned_offset[16384],binned_scale[16384],binned_data[16384];
  int bitpix=8, naxis=0, nrcvr, nrows, ncols, col;
  static int subint_cnt;
  char datestr[10],timestr[8];
  char Cstr16[16], Estr16[16], Istr16[16];
  char *ttype[20], *tform[20], *tunit[20];
  long naxes[4];
  int junk,rah,ram,ded,dem,subint_hdu,hh,mm;
  float ss;
  int last_scanhdr_hdu;
  double ras,des,dx;
  char rastr[80], destr[80], sra[80], sde[80];
  char date_time[24];
  char *pch[MAX_BLKS];
  char site[MAX_BLKS][2];
  short int nspan[MAX_BLKS];
  short int ncoeff[MAX_BLKS];
  double rfreq[MAX_BLKS];
  double rmjd[MAX_BLKS];
  double rphase[MAX_BLKS];
  double lgfiterr[MAX_BLKS];
  double f0[MAX_BLKS];
  double coeff[MAX_BLKS][MAX_COEFF];
  static double srcl, srcb;
  /* For Pulsar History BINTABLE */
 
  static char *PHtype[18] = {
    "DATE_PRO","PROC_CMD","POL_TYPE","NPOL    ","NBIN    ","NBIN_PRD","TBIN    ","CTR_FREQ",
    "NCHAN   ","CHAN_BW ","PAR_CORR","RM_CORR ","DEDISP  ","DDS_MTHD","SC_MTHD ","CAL_MTHD",
    "CAL_FILE","RFI_MTHD"
  };
  
  static char *PHform[18] = {
    "24A     ","80A     ","8A      ","1I      ","1I      ","1I      ","1D      ","1D      ",
    "1I      ","1D      ","1I      ","1I      ","1I      ","32A     ","32A     ","32A     ",
    "32A     ","32A     "
  };
  
  static char *PHunit[18] = {
    "        ","        ","        ","        ","        ","        ","s       ","MHz     ",
    "        ","MHz     ","        ","        ","        ","        ","        ","        ",
    "        ","        "
  };

  /* subtract baseline from outgoing profiles if requested */
  if (userbase != 0.0) for (i=0;i<multiple*nbins*nifs*nchans;i++) 
    prof[i]-=userbase;

  /* multiply outgoing profiles by Jansky calibration factor if supplied */
  if (jyfactor != 0.0) for (i=0;i<multiple*nbins*nifs*nchans;i++) 
    prof[i]*=jyfactor;

  /* sum first two polarizations together if requested */
  if (totalpower && (nifs > 1)) {
    for (i=0;i<multiple*nbins*nchans;i++) 
      prof[i]+=prof[i+multiple*nbins*nchans];
    nifs=1;
  }

  if (binary) {
    /* write out profiles in binary format */
    folding_period=pfld0*1000.0;
    tadd=tstart;
    tstart=tstart+tsta/86400.0;
    npuls=pulsecount;
    fold_header();
    tstart=tadd;
    for (i=0; i<nifs; i++) {
      for (c=0; c<nchan; c++) {
	for (b=0; b<nbins; b++) 
	  fwrite(&prof[i*nchan*nbins+c*nbins+b],sizeof(float),1,out);
      }
    }
  } else if (stream) {
    /* write out profiles as ASCII streams with START/STOP boundaries */
    k=0;
    for (i=0;i<nifs;i++) {
      for (c=0;c<nchan;c++) {
	fprintf(out,"#START %d %f %f\n",nbins,tsta,fch1+foff*(float)c);
	for (m=0;m<multiple;m++) {
	  for (b=0;b<nbins;b++) {
	    fprintf(out,"%d %f\n",b+m*nbins,prof[i*nchan*nbins+c*nbins+b]);
	  }
	}
	fprintf(out,"#STOP\n");
      }
    }
  } else if (asciipol) {
    /* write profiles in format for Jim's polarization code */
    for (b=0;b<nbins;b++) 
      for (i=0;i<nifs;i++)
	for (c=0;c<nchan;c++) 
	  fprintf(out,"%d %d %d %f\n",b,i,c,prof[i*nchan*nbins+c*nbins+b]);
  } else if (ascii) {
    fprintf(output,"# %.1f %.7f %.10f %ld %.3f %.3f %d %c %d %s\n",
     floor(tstart),(tstart-floor(tstart))*86400.0+tsta,pfld0,pulsecount,fch1,refdm,nbins,tempo_site(telescope_id),1,source_name);
    for (b=0;b<nbins;b++) {
      fprintf(out,"%d",b+1);
      for (i=0;i<nifs;i++) {
	for (c=0;c<nchan;c++) fprintf(out," %f",prof[i*nchan*nbins+c*nbins+b]);
      }
      fprintf(out,"\n");
    }
#ifdef PSRFITS
  } else if (psrfits) {
    if (first) {
      first=0;
      /* write profile in PSRFITS format */
      fits_create_file(&fits, "stdout", &sta);
      fits_create_img(fits,bitpix,naxis,naxes,&sta);
      fits_write_date(fits,&sta);
      /* Get DateTime string - required in various BINTABLEs */
      fits_get_system_time(date_time,&junk,&sta);
      fits_update_key(fits,TSTRING,"HDRVER","1.19","Header version",&sta);
      fits_update_key(fits,TSTRING,"OBSERVER",culprits,
		      "Observer name(s)",&sta);
      fits_update_key(fits,TSTRING,"PROJID",project,"Project name",&sta);
      fits_update_key(fits,TSTRING,"TELESCOP",telescope_name(telescope_id),
		      "Telescope name", &sta);
      fits_update_key(fits,TSTRING,"BACKEND",backend_name(machine_id),
		      "Backend ID",&sta);
      if (nifs>1) 
	nrcvr=2;
      else
	nrcvr=1;
      fits_update_key(fits,TINT,"NRCVR",&nrcvr,
		      "Number of receiver channels (I)",&sta);
      fits_update_key(fits,TSTRING,"OBS_MODE", "PSR",
		      "(PSR, CAL, SEARCH)", &sta);
      fits_update_key(fits,TSTRING,"SRC_NAME", source_name,
		      "Source or scan ID", &sta);
      fits_update_key(fits,TSTRING,"COORD_MD", "J2000",
		      "Coordinate mode (J2000, Gal, Ecliptic, etc.)", &sta);
      
      angle_split(src_raj,&rah,&ram,&ras);
      if (ras<10.0) 
	sprintf(sra,"0%.3f",ras);
      else
	sprintf(sra,"%.3f",ras);
      sprintf(rastr,"%02d:%02d:%s",rah,ram,sra);
      angle_split(src_dej,&ded,&dem,&des);
      if (des<10.0) 
	sprintf(sde,"0%.3f",des);
      else
	sprintf(sde,"%.3f",des);
      sprintf(destr,"%02d:%02d:%s",ded,dem,sde);
      cel2gal(rah,ram,ras,ded,dem,des,&srcl,&srcb);

      fits_update_key(fits, TSTRING, "STT_CRD1", rastr,
		      "Start coord 1 (hh:mm:ss.sss or ddd.ddd)", &sta);
      fits_update_key(fits, TSTRING, "STT_CRD2", destr,
		      "Start coord 2 (-dd:mm:ss.sss or -dd.ddd)", &sta);
      fits_update_key(fits, TSTRING, "TRK_MODE", "TRACK",
		      "Track mode (TRACK, SCANGC, SCANLAT)", &sta);
      fits_update_key(fits, TSTRING, "STP_CRD1", rastr,
		      "Stop coord 1 (hh:mm:ss.sss or ddd.ddd)", &sta);
      fits_update_key(fits, TSTRING, "STP_CRD2", destr,
		      "Stop coord 2 (-dd:mm:ss.sss or -dd.ddd)", &sta);
      fits_update_key(fits, TSTRING, "CAL_MODE", "OFF",
		      "Cal mode (OFF, SYNC, EXT1, EXT2)", &sta);
      fits_create_tbl(fits,BINARY_TBL,0,18,PHtype,
		      PHform,PHunit,"HISTORY",&sta);
      pch[0] = date_time;
      fits_write_col(fits,  TSTRING, 1, 1, 1, 1, pch, &sta);
      pch[0] = "SIGPROC";
      fits_write_col(fits,  TSTRING, 2, 1, 1, 1, pch, &sta);
      pch[0] = "??";
      fits_write_col(fits,  TSTRING, 3, 1, 1, 1, pch, &sta);
      /* Nr of pols  - i.e. actually written out */
      sj = nifs;
      fits_write_col(fits, TSHORT, 4, 1, 1, 1, &sj, &sta );
      
      /* Nr of bins per product (0 for SEARCH mode) */
      sj = nbins;
      fits_write_col( fits, TSHORT, 5, 1, 1, 1, &sj, &sta );
      
      /* Nr of bins per period */
      fits_write_col( fits, TSHORT, 6, 1, 1, 1, &sj, &sta );
      
      /* Bin time */
      dx =  folding_period/sj;
      fits_write_col( fits, TDOUBLE, 7, 1, 1, 1, &dx, &sta );
      
      /* Centre freq. */
      dx = ((double)(nchans/2)-1.0)*foff+fch1;
      fits_write_col( fits, TDOUBLE, 8, 1, 1, 1, &dx, &sta );
      
      /* Number of channels */
      sj = nchans;
      fits_write_col( fits, TSHORT, 9, 1, 1, 1, &sj, &sta );
      
      /* Channel bandwidth */
      dx = foff;
      fits_write_col( fits, TDOUBLE, 10, 1, 1, 1, &dx, &sta );
      
      /* Create frequency array for later */
      /* Get freq. of first channel */
      if ((fch1==0.0) && (foff==0.0)) {
	for (i=0; i<nchans; i++) binned_freq[i]=(float) frequency_table[i];
      } else {
	for (i=0; i<nchans; i++) 
	  binned_freq[i]=fch1+i*foff;
      }
      
      for (i=0; i<16384; i++) {
	binned_scale[i]=1.0;
	binned_offset[i]=0.0;
	binned_weight[i]=1.0;
      }
      
      sj = 0;
      /* Parallactic angle correction applied */
      fits_write_col( fits, TSHORT, 11, 1, 1, 1, &sj, &sta );
      /* RM correction applied */
      fits_write_col( fits, TSHORT, 12, 1, 1, 1, &sj, &sta );
      /* Data dedispersed */
      fits_write_col( fits, TSHORT, 13, 1, 1, 1, &sj, &sta );
      /* Dedispersion method */
      pch[0] = "NONE";
      fits_write_col( fits, TSTRING, 14, 1, 1, 1, pch, &sta );
      /* Scattered power correction method */
      pch[0] = "NONE";
      fits_write_col( fits, TSTRING, 15, 1, 1, 1, pch, &sta );
      /* Calibration method */
      pch[0] = "NONE";
      fits_write_col( fits, TSTRING, 16, 1, 1, 1, pch, &sta );
      /* Name of calibration file */
      pch[0] = "NONE";
      fits_write_col( fits, TSTRING, 17, 1, 1, 1, pch, &sta );
      /* RFI excision method */
      pch[0] = "NONE";
      fits_write_col( fits, TSTRING, 18, 1, 1, 1, pch, &sta );
      /* Store last header hdu number */
      fits_get_hdu_num( fits, &last_scanhdr_hdu );

      subint_cnt=1;
      /* Add START TIME to primary HDU */
      /* Move to primary HDU */
      fits_movabs_hdu( fits, 1, NULL, &sta );
      cal(tstart,&epn.year,&epn.month,&epn.day);
      sprintf(datestr,"%4d-%02d-%02d",epn.year,epn.month,epn.day);
      fits_update_key( fits, TSTRING, "STT_DATE", datestr,
		       "Start UT date (YYYY-MM-DD)", &sta);
      uttime(tstart,&hh,&mm,&ss);
      sprintf(timestr,"%02d:%02d:%02d",hh,mm,ss);
      fits_update_key( fits, TSTRING, "STT_TIME", timestr,
		       "Start UT (hh:mm:ss)", &sta);
      dx=86400*(tstart-floor(tstart));
      fits_update_key( fits, TINT, "STT_SMJD", &dx,
		     "[s] Start time (sec past UTC 00h) (J)", &sta);
      /* Move to last created HDU in scan header */
      fits_movabs_hdu( fits, last_scanhdr_hdu, NULL, &sta );

      /* Create SUBINT BINTABLE */
      ttype[0] = "ISUBINT ";/* Subint number. If NAXIS=-1, 0 indicates EOD. */
      tform[0] = "1J      ";
      tunit[0] = "";
      ttype[1] = "INDEXVAL";    /* Optionally used if INT_TYPE != TIME */
      tform[1] = "1D      ";
      tunit[1] = "";
      ttype[2] = "TSUBINT ";    /* [s] Length of subintegration */
      tform[2] = "1D      ";
      tunit[2] = "";
      ttype[3] = "OFFS_SUB"; /* [s] Offset from Start UTC of subint centre */
      tform[3] = "1D      ";
      tunit[3] = "";
      ttype[4] = "LST_SUB ";    /* [s] LST at subint centre */
      tform[4] = "1D      ";
      tunit[4] = "";
      ttype[5] = "RA_SUB  ";    /* [turns] RA (J2000) at subint centre */
      tform[5] = "1D      ";
      tunit[5] = "";
      ttype[6] = "DEC_SUB ";    /* [turns] Dec (J2000) at subint centre */
      tform[6] = "1D      ";
      tunit[6] = "";
      ttype[7] = "GLON_SUB";    /* [deg] Gal longitude at subint centre */
      tform[7] = "1D      ";
      tunit[7] = "";
      ttype[8] = "GLAT_SUB";    /* [deg] Gal latitude at subint centre */
      tform[8] = "1D      ";
      tunit[8] = "";
      ttype[9] = "FD_ANG  ";    /* [deg] Feed angle at subint centre */
      tform[9] = "1E      ";
      tunit[9] = "";
      ttype[10] = "POS_ANG ";/*[deg] Position angle of feed at subint centre */
      tform[10] = "1E      ";
      tunit[10] = "";
      ttype[11] = "PAR_ANG ";    /* [deg] Parallactic angle at subint centre */
      tform[11] = "1E      ";
      tunit[11] = "";
      ttype[12] = "TEL_AZ  ";    /* [deg] Telescope azimuth at subint centre */
      tform[12] = "1E      ";
      tunit[12] = "";
      ttype[13] = "TEL_ZEN ";/*[deg] Telescope zenith angle at subint centre */
      tform[13] = "1E      ";
      tunit[13] = "";

      sprintf( Cstr16, "%dE", nchans );
      ttype[14] = "DAT_FREQ";
      tform[14] = Cstr16;
      tunit[14] = "";
      ttype[15] = "DAT_WTS ";
      tform[15] = Cstr16;
      tunit[15] = "";
      
      sprintf( Estr16, "%dE", nifs*nchans );
      ttype[16] = "DAT_OFFS";
      tform[16] = Estr16;
      tunit[16] = "";
      ttype[17] = "DAT_SCL ";
      tform[17] = Estr16;
      tunit[17] = "";
      
      sprintf( Istr16, "%dE", nifs*nchans*nbins );
      ttype[18] = "DATA    ";
      tform[18] = Istr16;
      tunit[18] = "Jy      ";
      
      nrows = 0; /* naxis2 - Let CFITSIO sort this out */
      ncols = 19; /* tfields */
      fits_create_tbl( fits, BINARY_TBL, nrows, ncols, 
		       ttype, tform, tunit, "SUBINT  ", &sta);
      
      /* Add dimensions of column 'ncols' = SUBINT Data */
      naxes[0] = nbins;
      naxes[1] = nchans;
      naxes[2] = nifs;
    
      fits_write_tdim( fits, ncols, 3, naxes, &sta );
      
      /* Add keywords */
      fits_update_key( fits, TSTRING, "INT_TYPE", "TIME",
		       "Time axis (TIME, BINPHSPERI, BINLNGASC, etc)", &sta);
      
      fits_update_key( fits, TSTRING, "INT_UNIT", "SEC",
		       "Unit of time axis (SEC, PHS (0-1), DEG)", &sta);
      
      fits_update_key( fits, TINT, "NCH_FILE", &nchans,
		       "Number of channels/sub-bands in this file (I)", &sta);
      j = 0;
      fits_update_key( fits, TINT, "NCH_STRT", &j,
		     "Start channel/sub-band number (0 to NCHAN-1) (I)", &sta);
    
      /* Store subint hdu number */
      fits_get_hdu_num( fits, &subint_hdu );
    }
    
    /* Write SUBINT BINTABLE columns */
    
    /* Fill in columns of table */
    col = 1;
    
    /* Subint number. If NAXIS=-1, 0 indicates EOD. */
    j=subint_cnt;
    fits_write_col( fits, TINT, col, subint_cnt, 1, 1, &j, &sta );
    col++;
    
    /* INDEXVAL - Optionally used if INT_TYPE != TIME */
    dx = 0.0;
    fits_write_col( fits, TDOUBLE, col, subint_cnt, 1, 1, &dx, &sta );
    col++;
    
    /* [s] Length of subint */
    fits_write_col( fits, TDOUBLE, col, subint_cnt, 1, 1, &dump_time, &sta );
    col++;
    
    /* [s] Offset from Start UTC of subint centre */
    dx = 0.0;
    fits_write_col( fits, TDOUBLE, col, subint_cnt, 1, 1, &dx, &sta );
    col++;
    
    /* [s] LST at subint centre */
    dx=0.0;
    fits_write_col( fits, TDOUBLE, col, subint_cnt, 1, 1, &dx, &sta );
    col++;
    
    /* [turns] RA (J2000) at subint centre */
    dx=src_raj/360.0;
    fits_write_col( fits, TDOUBLE, col, subint_cnt, 1, 1, &dx, &sta );
    col++;
    
    /* [turns] Dec (J2000) at subint centre */
    dx=src_dej/360.0;
    fits_write_col( fits, TDOUBLE, col, subint_cnt, 1, 1, &dx, &sta );
    col++;
    
    /* [deg] Gal longitude at subint centre */
    dx=srcl;
    fits_write_col( fits, TDOUBLE, col, subint_cnt, 1, 1, &dx, &sta );
    col++;

    /* [deg] Gal latitude at subint centre */
    dx=srcb;
    fits_write_col( fits, TDOUBLE, col, subint_cnt, 1, 1, &dx, &sta );
    col++;

    /* [deg] Feed angle at subint centre */
    x=0.0;
    fits_write_col( fits, TFLOAT, col, subint_cnt, 1, 1, &x, &sta );
    col++;

    /* [deg] Parallactic angle at subint centre */

    /* [deg] Position angle of feed at subint centre */
    fits_write_col( fits, TFLOAT, col, subint_cnt, 1, 1, &x, &sta );
    col++;

    /* [deg] Parallactic angle at subint centre */
    fits_write_col( fits, TFLOAT, col, subint_cnt, 1, 1, &x, &sta );
    col++;

    /* [deg] Telescope azimuth at subint centre */
    x=(float) az_start;
    fits_write_col( fits, TFLOAT, col, subint_cnt, 1, 1, &x, &sta );
    col++;

    /* [deg] Telescope zenith angle at subint centre */
    x=(float) za_start;
    fits_write_col( fits, TFLOAT, col, subint_cnt, 1, 1, &x, &sta );
    col++;

    /* Centre freq. for each channel - NCHAN floats */
    fits_write_col( fits, TFLOAT, col, subint_cnt, 1,nchans,binned_freq,&sta );
    col++;

    /* Weights for each channel -  NCHAN floats */
    fits_write_col( fits, TFLOAT, col, subint_cnt, 1, nchans,
		    binned_weight, &sta );
    col++;

    /* Data offset for each channel - NCHAN*NPOL floats */
    fits_write_col( fits, TFLOAT, col, subint_cnt, 1, nchans*nifs,
		    binned_offset, &sta );
    col++;

    /* Data scale factor for each channel - NCHAN*NPOL floats */
    fits_write_col( fits, TFLOAT, col, subint_cnt, 1, nchans*nifs, 
		    binned_scale, &sta );
    col++;

    /* Subint data table - Dimensions of data table = (NBIN,NCHAN,NPOL) */
    for (i=0;i<nchans*nifs*nbins;i++) binned_data[i]=prof[i];

    fits_write_col(fits,TFLOAT,col, subint_cnt, 1, nbins*nchans*nifs, 
		   binned_data, &sta );

    subint_cnt++;
    if (sta) fits_report_error(stderr,sta);
#endif
  } else {
    /* EPN format requested - set up some general EPN variables */
    sprintf(epn.history,"%s %s fast-sampled data reduced using fold",
	    telescope_name(telescope_id),backend_name(machine_id));
    while (strlen(epn.history)<65) strcat(epn.history," ");
    strcpy(epn.jname,"");
    strcpy(epn.cname,"");
    epn.pbar=pfld0;
    epn.dm=refdm;
    epn.rm=0.0;
    strcpy(epn.catref,"none");
    strcpy(epn.bibref,"none");
    epn.raj=0.0;
    epn.dec=0.0;
    strcpy(epn.telname,telescope_name(telescope_id));
    epn.epoch=(float) floor(tstart);
    epn.opos=0.0;
    epn.paflag=' ';
    epn.timflag='U';
    epn.xtel=0.0;
    epn.ytel=0.0;
    epn.ztel=0.0;
    cal((double)epn.epoch,&epn.year,&epn.month,&epn.day);
    epn.scanno=0;
    epn.subscan=0;
    epn.npol=nifs;
    epn.nfreq=nchan;
    epn.nbins=nbins;
    epn.tbin=1.0e6*pfld0/(double)nbins;
    epn.nint=0;
    epn.ncal=0;
    epn.lcal=0;
    epn.tres=epn.tbin;
    epn.fluxflag='U';
    epn.navg=1;
    strcpy(epn.uf,"MHz ");
    epn.df=1000.0*fabs(foff);
    strcpy(epn.ud,"kHz ");
    if (epn.df>=10000.0) {
      epn.df/=1000.0;
      strcpy(epn.ud,"MHz ");
    }
    epn.tstart=(tstart-floor(tstart))*86400.0+tsta;
    epn.tstart*=1.0e6;
    epn.iprofile=(unsigned long *) malloc(epn.nbins*sizeof(long));
    profile = (float *) malloc(sizeof(float)*nbins);
    for (i=0;i<nifs;i++) {
      strcpy(epn.idfield,"I");
      for (c=0;c<nchan;c++) {
	for (b=0;b<nbins;b++) {
	  profile[b]=prof[i*nchan*nbins+c*nbins+b];
	}
	scale_prof(profile,nbins,epn.iprofile,&epn.scale,&epn.offset);
	epn.f0=fch1+foff*c;
	epn.nband=c+1;
	epn.papp=pfld0;
	epn.rms=0.0;
	epn.tres=tbin=1.0e6*pfld0*window/(double)nbins;
	if (c==0) write_epn_header(out,epn);
	write_epn_subheader(out,epn);
      }
    }
    fflush(out);
    free(profile);
    free(epn.iprofile);
  }
}