Exemplo n.º 1
0
//----------------------------------------------------------
int write_hits_header(etfits_t * etf, int beampol, size_t nhits, size_t missed_pkts) {
//----------------------------------------------------------

#define TFIELDS 4
    int * status_p = &(etf->status);
    *status_p = 0;

    int tbltype                = BINARY_TBL;
    long long naxis2           = 0;
    //const int tfields          = 3;
    // TODO check chan types!
    const char *ttype[TFIELDS] = {"DETPOW  ", "MEANPOW ",  "COARCHAN", "FINECHAN"};
    const char *tform[TFIELDS] = {"1E",       "1E",        "1U",        "1V"};     // cfitsio format codes 
                             //     32-bit floats       16-bit unint   32-bit uint

    if(etf->integration_cnt == 0 && etf->beampol_cnt == 0) {
        // at start of file go to the template created HDU for this set of beampols
        if(! *status_p) fits_movnam_hdu(etf->fptr, BINARY_TBL, (char *)"ETHITS", 0, status_p);
    } else {
        // otherwise create new HDU for this set of beampols
        if(! *status_p) fits_create_tbl(etf->fptr, BINARY_TBL, 0, TFIELDS, (char **)&ttype, (char **)&tform, NULL, (char *)"ETHITS", status_p);
    }

    if(! *status_p) fits_update_key(etf->fptr, TINT,    "TIME",    &(etf->hits_hdr[beampol].time),    NULL, status_p);    
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "RA",      &(etf->hits_hdr[beampol].ra),      NULL, status_p);   
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "DEC",     &(etf->hits_hdr[beampol].dec),     NULL, status_p);   
    if(! *status_p) fits_update_key(etf->fptr, TINT,    "BEAMPOL", &(etf->hits_hdr[beampol].beampol), NULL, status_p);   
    if(! *status_p) fits_update_key(etf->fptr, TINT,    "NHITS",   &nhits,                            NULL, status_p);   
    if(! *status_p) fits_update_key(etf->fptr, TINT,    "MISSEDPK",&missed_pkts,                      NULL, status_p);   

    if (*status_p) {
        hashpipe_error(__FUNCTION__, "Error writing hits header");
        fits_report_error(stderr, *status_p);
    }
}
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);
}
Exemplo n.º 3
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);
}
Exemplo n.º 4
0
void OutputFileFITS::createTable(const std::string& name, const std::vector<field>& fields) {
	int status = 0;

	if(!isOpened())
		throwException("Error in OutputFileFITS::createTable() ", status);

	unsigned int nfields = fields.size();

	char** ttypes = new char*[nfields*sizeof(char*)];
	char** tform = new char*[nfields*sizeof(char*)];
	char** tunit = new char*[nfields*sizeof(char*)];

	for(unsigned int i=0; i<nfields; i++)
	{
		ttypes[i] = new char[10];
		std::string type = fields[i].name.c_str();
		std::memcpy(ttypes[i], type.c_str(), 10);

		tform[i] = new char[10];
		std::string form(_getFieldTypeString(fields[i].type, fields[i].vsize));
		std::memcpy(tform[i], form.c_str(), 10);

		tunit[i] = new char[10];
		std::string unit = fields[i].unit.c_str();
		std::memcpy(tunit[i], unit.c_str(), 10);
	}

	fits_create_tbl(infptr, BINARY_TBL, 0, nfields, ttypes, tform, tunit, name.c_str(), &status);

	for(unsigned int i=0; i<nfields; i++)
	{
		delete ttypes[i];
		delete tform[i];
		delete tunit[i];
	}

	delete ttypes;
	delete tform;
	delete tunit;

	if (status)
		throwException("Error in OutputFileFITS::createTable() ", status);

	for(unsigned int i=0; i<nfields; i++)
	{
		if(fields[i].type == STRING)
		{
			long tdim[] = {fields[i].vsize, 1};
			fits_write_tdim(infptr, i+1, 2, tdim, &status);
		}
	}
	if (status)
		throwException("Error in OutputFileFITS::createTable() ", status);
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
int create_input()

{
  const double TWOPI = 2.0 * 3.14159265358979323846;

  /* These must match wcstab.keyrec. */
  const char infile[] = "test/wcstab.keyrec";
  const long NAXIS1 = 256;
  const long NAXIS2 = 128;
  const long NAXIS3 =   4;
  const char *ttype1[3] = {"CelCoords", "RAIndex", "DecIndex"};
  const char *tform1[3] = {"5600E", "70E", "40E"};
  const char *tunit1[3] = {"deg", "", ""};
  const char *ttype2[4] = {"WaveIndex", "WaveCoord",
                           "TimeIndex", "TimeCoord"};
  const char *tform2[4] = {"8E", "8D", "8E", "8D"};
  const char *tunit2[4] = {"", "m", "", "a"};

  /* The remaining parameters may be chosen at will. */
  float  refval[] = {150.0f, -30.0f};
  float  span[]   = {5.0f, (5.0f*K2)/K1};
  float  sigma[]  = {0.10f, 0.05f};
  double wcoord[] = {0.21106114, 0.21076437, 2.0e-6, 2.2e-6,
                     500.0e-9, 650.0e-9, 1.24e-9, 2.48e-9};
  double windex[] = {0.5, 1.5, 1.5, 2.5, 2.5, 3.5, 3.5, 4.5};
  double tcoord[] = {1997.84512, 1997.84631, 1993.28451, 1993.28456,
                     2001.59234, 2001.59239, 2002.18265, 2002.18301};
  double tindex[] = {0.0, 1.0, 1.0, 2.0, 2.0, 3.0, 3.0, 4.0};

  char   keyrec[84];
  int    i, status;
  long   dummy, firstelem, k1, k2, p1, p2, p3;
  float  array[2*K1*K2], *fp, image[256];
  double s, t, x1, x2, z, z1, z2;
  FILE   *stream;
  fitsfile *fptr;

  /* Look for the input header keyrecords. */
  if ((stream = fopen(infile+5, "r")) == 0x0) {
    if ((stream = fopen(infile, "r")) == 0x0) {
      printf("ERROR opening %s\n", infile);
      return 1;
    }
  }

  /* Create the FITS output file, deleting any pre-existing file. */
  status = 0;
  fits_create_file(&fptr, "!wcstab.fits", &status);

  /* Convert header keyrecords to FITS. */
  while (fgets(keyrec, 82, stream) != NULL) {
    /* Ignore meta-comments (copyright information, etc.). */
    if (keyrec[0] == '#') continue;

    /* Strip off the newline. */
    i = strlen(keyrec) - 1;
    if (keyrec[i] == '\n') keyrec[i] = '\0';

    fits_write_record(fptr, keyrec, &status);
  }
  fclose(stream);

  /* Create and write some phoney image data. */
  firstelem = 1;
  for (p3 = 0; p3 < NAXIS3; p3++) {
    for (p2 = 0; p2 < NAXIS2; p2++) {
      fp = image;
      s = (p3 + 1) * cos(0.2 * p2);
      t = cos(0.8*p2);
      for (p1 = 0; p1 < NAXIS1; p1++) {
        /* Do not adjust your set! */
        *(fp++) = sin(0.1*(p1+p2) + s) * cos(0.4*p1) * t;
      }

      fits_write_img_flt(fptr, 0L, firstelem, NAXIS1, image, &status);
      firstelem += NAXIS1;
    }
  }


  /* Add the first binary table extension. */
  fits_create_tbl(fptr, BINARY_TBL, 1L, 3L, (char **)ttype1, (char **)tform1,
     (char **)tunit1, NULL, &status);

  /* Write EXTNAME and EXTVER near the top, after TFIELDS. */
  fits_read_key_lng(fptr, "TFIELDS", &dummy, NULL, &status);
  fits_insert_key_str(fptr, "EXTNAME", "WCS-TABLE",
    "WCS Coordinate lookup table", &status);
  fits_insert_key_lng(fptr, "EXTVER", 1L, "Table number 1", &status);

  /* Write the TDIM1 keyrecord after TFORM1. */
  fits_read_key_str(fptr, "TFORM1", keyrec, NULL, &status);
  sprintf(keyrec, "(2,%ld,%ld)", K1, K2);
  fits_insert_key_str(fptr, "TDIM1", keyrec, "Dimensions of 3-D array",
    &status);

  /* Plate carrée projection with a bit of noise for the sake of realism. */
  fp = array;
  for (k2 = 0; k2 < K2; k2++) {
    for (k1 = 0; k1 < K1; k1++) {
      /* Box-Muller transformation: uniform -> normal distribution. */
      x1 = lcprng();
      x2 = lcprng();
      if (x1 == 0.0) x1 = 1.0;
      z  = sqrt(-2.0 * log(x1));
      x2 *= TWOPI;
      z1 = z * cos(x2);
      z2 = z * sin(x2);

      *(fp++) = refval[0] + span[0] * (k1/(K1-1.0) - 0.5) + z1 * sigma[0];
      *(fp++) = refval[1] + span[1] * (k2/(K2-1.0) - 0.5) + z2 * sigma[1];
    }
  }
  fits_write_col_flt(fptr, 1, 1L, 1L, 2*K1*K2, array, &status);

  fp = array;
  for (k1 = 0; k1 < K1; k1++) {
    *(fp++) = 4.0f * k1;
  }
  fits_write_col_flt(fptr, 2, 1L, 1L, K1, array, &status);

  fp = array;
  for (k2 = 0; k2 < K2; k2++) {
    *(fp++) = 4.0f * k2;
  }
  fits_write_col_flt(fptr, 3, 1L, 1L, K2, array, &status);


  /* Add the second binary table extension. */
  if (fits_create_tbl(fptr, BINARY_TBL, 1L, 4L, (char **)ttype2,
     (char **)tform2, (char **)tunit2, NULL, &status)) {
    fits_report_error(stderr, status);
    return 1;
  }

  /* Write EXTNAME and EXTVER near the top, after TFIELDS. */
  fits_read_key_lng(fptr, "TFIELDS", &dummy, NULL, &status);
  fits_insert_key_str(fptr, "EXTNAME", "WCS-TABLE",
    "WCS Coordinate lookup table", &status);
  fits_insert_key_lng(fptr, "EXTVER", 2L, "Table number 2", &status);

  /* Write the TDIM2 keyrecord after TFORM2. */
  fits_read_key_str(fptr, "TFORM2", keyrec, NULL, &status);
  fits_insert_key_str(fptr, "TDIM2", "(1,8)", "Dimensions of 2-D array",
    &status);

  /* Write the TDIM4 keyrecord after TFORM4. */
  fits_read_key_str(fptr, "TFORM4", keyrec, NULL, &status);
  fits_insert_key_str(fptr, "TDIM4", "(1,8)", "Dimensions of 2-D array",
    &status);


  fits_write_col_dbl(fptr, 1, 1L, 1L, 8L, windex, &status);
  fits_write_col_dbl(fptr, 2, 1L, 1L, 8L, wcoord, &status);
  fits_write_col_dbl(fptr, 3, 1L, 1L, 8L, tindex, &status);
  fits_write_col_dbl(fptr, 4, 1L, 1L, 8L, tcoord, &status);

  fits_close_file(fptr, &status);

  if (status) {
    fits_report_error(stderr, status);
    return 1;
  }

  return 0;
}
Exemplo n.º 7
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 );
  
}
Exemplo n.º 8
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 );

}
Exemplo n.º 9
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;
}
Exemplo n.º 10
0
int	ngp_read_xtension(fitsfile *ff, int parent_hn, int simple_mode)
 { int		r, exflg, l, my_hn, tmp0, incrementor_index, i, j;
   int		ngph_dim, ngph_bitpix, ngph_node_type, my_version;
   char		incrementor_name[NGP_MAX_STRING], ngph_ctmp;
   char 	*ngph_extname = 0;
   long		ngph_size[NGP_MAX_ARRAY_DIM];
   NGP_HDU	ngph;
   long		lv;

   incrementor_name[0] = 0;			/* signal no keyword+'#' found yet */
   incrementor_index = 0;

   if (NGP_OK != (r = ngp_hdu_init(&ngph))) return(r);

   if (NGP_OK != (r = ngp_read_line(0))) return(r);	/* EOF always means error here */
   switch (NGP_XTENSION_SIMPLE & simple_mode)
     {
       case 0:  if (NGP_TOKEN_XTENSION != ngp_keyidx) return(NGP_TOKEN_NOT_EXPECT);
		break;
       default:	if (NGP_TOKEN_SIMPLE != ngp_keyidx) return(NGP_TOKEN_NOT_EXPECT);
		break;
     }
       	
   if (NGP_OK != (r = ngp_hdu_insert_token(&ngph, &ngp_linkey))) return(r);

   for (;;)
    { if (NGP_OK != (r = ngp_read_line(0))) return(r);	/* EOF always means error here */
      exflg = 0;
      switch (ngp_keyidx)
       { 
	 case NGP_TOKEN_SIMPLE:
	 		r = NGP_TOKEN_NOT_EXPECT;
			break;
	 		                        
	 case NGP_TOKEN_END:
         case NGP_TOKEN_XTENSION:
         case NGP_TOKEN_GROUP:
         		r = ngp_unread_line();	/* WARNING - not break here .... */
         case NGP_TOKEN_EOF:
			exflg = 1;
 			break;

         default:	l = strlen(ngp_linkey.name);
			if ((l >= 2) && (l <= 6))
			  { if ('#' == ngp_linkey.name[l - 1])
			      { if (0 == incrementor_name[0])
			          { memcpy(incrementor_name, ngp_linkey.name, l - 1);
			            incrementor_name[l - 1] = 0;
			          }
			        if (((l - 1) == (int)strlen(incrementor_name)) && (0 == memcmp(incrementor_name, ngp_linkey.name, l - 1)))
			          { incrementor_index++;
			          }
			        sprintf(ngp_linkey.name + l - 1, "%d", incrementor_index);
			      }
			  }
			r = ngp_hdu_insert_token(&ngph, &ngp_linkey);
 			break;
       }
      if ((NGP_OK != r) || exflg) break;
    }

   if (NGP_OK == r)
     { 				/* we should scan keywords, and calculate HDU's */
				/* structure ourselves .... */

       ngph_node_type = NGP_NODE_INVALID;	/* init variables */
       ngph_bitpix = 0;
       ngph_extname = NULL;
       for (i=0; i<NGP_MAX_ARRAY_DIM; i++) ngph_size[i] = 0;
       ngph_dim = 0;

       for (i=0; i<ngph.tokcnt; i++)
        { if (!strcmp("XTENSION", ngph.tok[i].name))
            { if (NGP_TTYPE_STRING == ngph.tok[i].type)
                { if (!ngp_strcasencmp("BINTABLE", ngph.tok[i].value.s,8)) ngph_node_type = NGP_NODE_BTABLE;
                  if (!ngp_strcasencmp("TABLE", ngph.tok[i].value.s,5)) ngph_node_type = NGP_NODE_ATABLE;
                  if (!ngp_strcasencmp("IMAGE", ngph.tok[i].value.s,5)) ngph_node_type = NGP_NODE_IMAGE;
                }
            }
          else if (!strcmp("SIMPLE", ngph.tok[i].name))
            { if (NGP_TTYPE_BOOL == ngph.tok[i].type)
                { if (ngph.tok[i].value.b) ngph_node_type = NGP_NODE_IMAGE;
                }
            }
          else if (!strcmp("BITPIX", ngph.tok[i].name))
            { if (NGP_TTYPE_INT == ngph.tok[i].type)  ngph_bitpix = ngph.tok[i].value.i;
            }
          else if (!strcmp("NAXIS", ngph.tok[i].name))
            { if (NGP_TTYPE_INT == ngph.tok[i].type)  ngph_dim = ngph.tok[i].value.i;
            }
          else if (!strcmp("EXTNAME", ngph.tok[i].name))	/* assign EXTNAME, I hope struct does not move */
            { if (NGP_TTYPE_STRING == ngph.tok[i].type)  ngph_extname = ngph.tok[i].value.s;
            }
          else if (1 == sscanf(ngph.tok[i].name, "NAXIS%d%c", &j, &ngph_ctmp))
            { if (NGP_TTYPE_INT == ngph.tok[i].type)
		if ((j>=1) && (j <= NGP_MAX_ARRAY_DIM))
		  { ngph_size[j - 1] = ngph.tok[i].value.i;
		  }
            }
        }

       switch (ngph_node_type)
        { case NGP_NODE_IMAGE:
			if (NGP_XTENSION_FIRST == ((NGP_XTENSION_FIRST | NGP_XTENSION_SIMPLE) & simple_mode))
			  { 		/* if caller signals that this is 1st HDU in file */
					/* and it is IMAGE defined with XTENSION, then we */
					/* need create dummy Primary HDU */			  
			    fits_create_img(ff, 16, 0, NULL, &r);
			  }
					/* create image */
			fits_create_img(ff, ngph_bitpix, ngph_dim, ngph_size, &r);

					/* update keywords */
			if (NGP_OK == r)  r = ngp_keyword_all_write(&ngph, ff, NGP_NON_SYSTEM_ONLY);
			break;

          case NGP_NODE_ATABLE:
          case NGP_NODE_BTABLE:
					/* create table, 0 rows and 0 columns for the moment */
			fits_create_tbl(ff, ((NGP_NODE_ATABLE == ngph_node_type)
					     ? ASCII_TBL : BINARY_TBL),
					0, 0, NULL, NULL, NULL, NULL, &r);
			if (NGP_OK != r) break;

					/* add columns ... */
			r = ngp_append_columns(ff, &ngph, 0);
			if (NGP_OK != r) break;

					/* add remaining keywords */
			r = ngp_keyword_all_write(&ngph, ff, NGP_NON_SYSTEM_ONLY);
			if (NGP_OK != r) break;

					/* if requested add rows */
			if (ngph_size[1] > 0) fits_insert_rows(ff, 0, ngph_size[1], &r);
			break;

	  default:	r = NGP_BAD_ARG;
	  		break;
	}

     }

   if ((NGP_OK == r) && (NULL != ngph_extname))
     { r = ngp_get_extver(ngph_extname, &my_version);	/* write correct ext version number */
       lv = my_version;		/* bugfix - 22-Jan-99, BO - nonalignment of OSF/Alpha */
       fits_write_key(ff, TLONG, "EXTVER", &lv, "auto assigned by template parser", &r); 
     }

   if (NGP_OK == r)
     { if (parent_hn > 0)
         { fits_get_hdu_num(ff, &my_hn);
           fits_movabs_hdu(ff, parent_hn, &tmp0, &r);	/* link us to parent */
           fits_add_group_member(ff, NULL, my_hn, &r);
           fits_movabs_hdu(ff, my_hn, &tmp0, &r);
           if (NGP_OK != r) return(r);
         }
     }

   if (NGP_OK != r)					/* in case of error - delete hdu */
     { tmp0 = 0;
       fits_delete_hdu(ff, NULL, &tmp0);
     }

   ngp_hdu_clear(&ngph);
   return(r);
 }
/*******************************************************************************
 * 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);
    }
}
Exemplo n.º 12
0
//----------------------------------------------------------
int write_integration_header(etfits_t * etf, scram_t *scram) {
//----------------------------------------------------------
    
    int * status_p = &(etf->status);
    *status_p = 0;

//fprintf(stderr, "writing integration header\n");
    if(etf->integration_cnt == 0) {
        // go to the template created HDU
        if(! *status_p) fits_movnam_hdu(etf->fptr, BINARY_TBL, (char *)"AOSCRAM", 0, status_p);
    } else {
        // create new HDU
        if(! *status_p) fits_create_tbl(etf->fptr, BINARY_TBL, 0, 0, NULL, NULL, NULL, (char *)"AOSCRAM", status_p);
    }

    if(! *status_p) fits_update_key(etf->fptr, TSTRING,  "EXTNAME",  (char *)"AOSCRAM",  NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TINT,     "COARCHID", &scram->coarse_chan_id,   NULL, status_p); 

    // observatory (scram) data 
    if(! *status_p) fits_update_key(etf->fptr, TINT,    "PNTSTIME",  &(scram->PNTSTIME), NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "PNTRA",     &(scram->PNTRA),    NULL, status_p);      
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "PNTDEC",    &(scram->PNTDEC),   NULL, status_p);      
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "PNTMJD",    &(scram->PNTMJD),   NULL, status_p);      
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "PNTAZCOR",  &(scram->PNTAZCOR), NULL, status_p);      
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "PNTZACOR",  &(scram->PNTZACOR), NULL, status_p);      

    if(! *status_p) fits_update_key(etf->fptr, TINT,    "AGCSTIME", &(scram->AGCSTIME),  NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "AGCAZ",    &(scram->AGCAZ),     NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "AGCZA",    &(scram->AGCZA),     NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TINT,    "AGCTIME",  &(scram->AGCTIME),   NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "AGCLST",   &(scram->AGCLST),    NULL, status_p);     // TODO

    if(! *status_p) fits_update_key(etf->fptr, TINT,    "ALFSTIME", &(scram->ALFSTIME),  NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TINT,    "ALFBIAS1", &(scram->ALFBIAS1),  NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TINT,    "ALFBIAS2", &(scram->ALFBIAS2),  NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "ALFMOPOS", &(scram->ALFMOPOS),  NULL, status_p);

    if(! *status_p) fits_update_key(etf->fptr, TINT,    "IF1STIME", &(scram->IF1STIME),  NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "IF1SYNHZ", &(scram->IF1SYNHZ),  NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TINT,    "IF1SYNDB", &(scram->IF1SYNDB),  NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "IF1RFFRQ", &(scram->IF1RFFRQ),  NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "IF1IFFRQ", &(scram->IF1IFFRQ),  NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TINT,    "IF1ALFFB", &(scram->IF1ALFFB),  NULL, status_p);

    if(! *status_p) fits_update_key(etf->fptr, TINT,    "IF2STIME", &(scram->IF2STIME),  NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TINT,    "IF2ALFON", &(scram->IF2ALFON),  NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "IF2SYNHZ", &(scram->IF2SYNHZ),  NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TINT,    "IF2SIGSR", &(scram->IF2SIGSR),  NULL, status_p); 

    if(! *status_p) fits_update_key(etf->fptr, TINT,    "TTSTIME",  &(scram->TTSTIME),   NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TINT,    "TTTURENC", &(scram->TTTURENC),  NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "TTTURDEG", &(scram->TTTURDEG),  NULL, status_p);

    if(! *status_p) fits_update_key(etf->fptr, TINT,    "CLOCKTIM",  &(scram->CLOCKTIM), NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "CLOCKFRQ",  &(scram->CLOCKFRQ), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "CLOCKDBM",  &(scram->CLOCKDBM), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TINT,    "CLOCKLOC",  &(scram->CLOCKLOC), NULL, status_p); 

    if(! *status_p) fits_update_key(etf->fptr, TINT,    "BIRDITIM",  &(scram->BIRDITIM), NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "BIRDIFRQ",  &(scram->BIRDIFRQ), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "BIRDIDBM",  &(scram->BIRDIDBM), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TINT,    "BIRDILOC",  &(scram->BIRDILOC), NULL, status_p); 

    if(! *status_p) fits_update_key(etf->fptr, TINT,    "ADCRMSTM",  &(scram->ADCRMSTM),   NULL, status_p); 
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "ADCRMS01",  &(scram->ADC1RMS[0]), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "ADCRMS02",  &(scram->ADC1RMS[1]), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "ADCRMS03",  &(scram->ADC1RMS[2]), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "ADCRMS04",  &(scram->ADC1RMS[3]), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "ADCRMS05",  &(scram->ADC1RMS[4]), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "ADCRMS06",  &(scram->ADC1RMS[5]), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "ADCRMS07",  &(scram->ADC1RMS[6]), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "ADCRMS08",  &(scram->ADC1RMS[7]), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "ADCRMS09",  &(scram->ADC2RMS[0]), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "ADCRMS10",  &(scram->ADC2RMS[1]), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "ADCRMS11",  &(scram->ADC2RMS[2]), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "ADCRMS12",  &(scram->ADC2RMS[3]), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "ADCRMS13",  &(scram->ADC2RMS[4]), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "ADCRMS14",  &(scram->ADC2RMS[5]), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "ADCRMS15",  &(scram->ADC2RMS[6]), NULL, status_p);
    if(! *status_p) fits_update_key(etf->fptr, TDOUBLE, "ADCRMS16",  &(scram->ADC2RMS[7]), NULL, status_p);
#if 0
    fits_update_key(etf->fptr, TINT,    "MISSEDPK", &(scram.MISSEDPK),    NULL, status_p);    // missed packets per input per second 
#endif

    //if(! *status_p) fits_flush_file(etf->fptr, status_p);

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

    return *status_p;
}
Exemplo n.º 13
0
void
zvot_writeFITS (handle_t vot, char *oname)
{
    char  *name, *unit, *dtype, *width, **cells, *cell, *asize;
    char  *ttype[MAX_FIELDS], *tform[MAX_FIELDS], *tunit[MAX_FIELDS], *ch;
    int    res, tab, data, tdata, field, handle, hdutype, *widths, *spaces;
    int    i, j, len, ncols, nrows, status = 0, resnum = 1, bitpix = 8;
    long   naxis = 0,  naxes[2] = { 0, 0 };
    fitsfile  *fp;		/* CFITSIO descriptor		*/



    if (fits_create_file (&fp, oname, &status)) /* create new FITS file */
        printerror (status);

    if ( fits_create_img (fp,  bitpix, naxis, naxes, &status) )
        printerror (status);


    /*  Loop over all <RESOURCE> elements in the file, creating an new
     *  extension for each one.
     */
    for (res=vot_getRESOURCE (vot); res; res=vot_getNext(res) ) {

	/*  Get handles for the current resource.
	 */
      	tab   = vot_getTABLE (res);
      	data  = vot_getDATA (tab);
      	tdata = vot_getTABLEDATA (data);
      	nrows = vot_getNRows (tdata);
      	ncols = vot_getNCols (tdata);

	/*  Allocate space for the data cells.  Read in the cells so we can
 	 *  convert it for output.  Also collect the widths so we can
 	 *  properly size the table.
	 */
	cells  = (char **) calloc (1, (nrows * ncols) * sizeof (char *));
	widths = (int *) calloc (1, ncols * sizeof (int));
	spaces = (int *) calloc (1, ncols * sizeof (int));
        for (i = 0; i < nrows; i++) {
            for (j = 0; j < ncols; j++) {
                cell = cells[i*ncols+j] = vot_getTableCell(tdata, i, j);

		if ((len = strlen (cell)) > widths[j])
		    widths[j] = len;

		if (cell[0] && strchr (cell, (int)' ') && len > 1 && i < 1) {
		    for (ch=cell; *ch; ch++) {
			if (*ch == ' ')
		    	    spaces[j]++;
		    }
		}
            }
        }


        memset (&ttype[0], 0, MAX_FIELDS);	/* initialize		*/
	memset (&tform[0], 0, MAX_FIELDS);
	memset (&tunit[0], 0, MAX_FIELDS);

	/*  Move to proper extension HDU.
	 */
        if (fits_movabs_hdu (fp, resnum++, &hdutype, &status)) 
            printerror (status);

        /*  Get the column attributes and set them in the header.
         */
	i = 0;
        for (field=vot_getFIELD(tab); field; field=vot_getNext (field)) {
	    dtype = vot_getAttr (field, "datatype");
	    width = vot_getAttr (field, "width");
	    asize = vot_getAttr (field, "arraysize");

	    if ((name = vot_getAttr (field, "name")))
	    	ttype[i] =  (name ? name : strdup ("X"));
	    if ((unit = vot_getAttr (field, "unit")))
	    	tunit[i] =  (unit ? unit : strdup ("Y"));

	    tform[i] = calloc (1, 16);
	    if (strncasecmp (dtype, "char", 4) == 0) {
		if (asize[0]) {
		    sprintf (tform[i], "%dA", 
			(asize[0] == '*' ? widths[i] : atoi (asize)));
		} else
		    strcpy (tform[i], "A");

	    } else if (strncasecmp (dtype, "float", 4) == 0) {
		if (spaces[i])
		    sprintf (tform[i], "%dE", spaces[i]+1);
		else
		    strcpy (tform[i], "E");

	    } else if (strncasecmp (dtype, "double", 4) == 0) {
		if (spaces[i])
		    sprintf (tform[i], "%dD", spaces[i]+1);
		else
		    strcpy (tform[i], "D");

	    } else if (strncasecmp (dtype, "int", 3) == 0) {
		if (spaces[i])
		    sprintf (tform[i], "%dJ", spaces[i]+1);
		else
		    strcpy (tform[i], "J");
	    }

	    if (dtype)	free ( (void *) dtype);
	    if (width)	free ( (void *) width);
	    if (asize)	free ( (void *) asize);
	    i++;
        }

        /*  Append a new empty binary table onto the FITS file
	 */
        if (fits_create_tbl (fp, BINARY_TBL, nrows, ncols, ttype, tform,
            tunit, "extname", &status))
        	printerror (status);

	/*  Add UCD and UTYPE keywords for the FIELDs if defined.
	 */
        for (i=1,field=vot_getFIELD(tab); field; field=vot_getNext (field))
	    vot_addFieldMeta (field, fp, i++);

	/* Add keywords for all the <INFO> and <PARAM> elements.
	 */
      	handle = vot_getINFO (res);
	for (i=1, len=vot_getLength (handle); i < len; i++) {
	    vot_addFITSMeta (handle, fp, "INFO", i);
	    handle = vot_getNext (handle);
	}

      	handle = vot_getPARAM (res);
	for (i=1, len=vot_getLength (handle); i < len; i++) {
	    vot_addFITSMeta (handle, fp, "PARAM", i);
	    handle = vot_getNext (handle);
	}


	/*  Write the data to the file.
	 */
	vot_writeFITSData (fp, cells, tform, nrows, ncols);

	/*  Free the allocated pointers.
	 */
	for (i=0; i < ncols; i++) {
	    if (ttype[i])  free ((void *) ttype[i]);
	    if (tunit[i])  free ((void *) tunit[i]);
	    if (tform[i])  free ((void *) tform[i]);
	}
	if (cells)	free ((void *) cells);
	if (widths)	free ((void *) widths);
	if (spaces)	free ((void *) spaces);
    }


    vot_closeVOTABLE (vot);			/* close the VOTable  	*/
    if (fits_close_file (fp, &status))       	/* close the FITS file 	*/
         printerror (status);
}
Exemplo n.º 14
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;
}
Exemplo n.º 15
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);
}
Exemplo n.º 16
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;
}
Exemplo n.º 17
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);
  }
}