int sdfits_create(struct sdfits *sf) { int itmp, *status; char ctmp[40]; struct hdrinfo *hdr; hdr = &(sf->hdr); // dereference the ptr to the header struct status = &(sf->status); // dereference the ptr to the CFITSIO status // Initialize the key variables if needed if (sf->new_file == 1) { // first time writing to the file sf->status = 0; sf->tot_rows = 0; sf->N = 0L; sf->T = 0.0; sf->mode = 'w'; // Create the output directory if needed char datadir[1024]; strncpy(datadir, sf->basefilename, 1023); char *last_slash = strrchr(datadir, '/'); if (last_slash!=NULL && last_slash!=datadir) { *last_slash = '\0'; printf("Using directory '%s' for output.\n", datadir); char cmd[1024]; sprintf(cmd, "mkdir -m 1777 -p %s", datadir); system(cmd); } sf->new_file = 0; } sf->filenum++; sf->rownum = 1; sprintf(sf->filename, "%s_%04d.fits", sf->basefilename, sf->filenum); // Create basic FITS file from our template char *vegas_dir = getenv("VEGAS_DIR"); char template_file[1024]; if (vegas_dir==NULL) { fprintf(stderr, "Error: VEGAS_DIR environment variable not set, exiting.\n"); exit(1); } printf("Opening file '%s'\n", sf->filename); sprintf(template_file, "%s/%s", vegas_dir, SDFITS_TEMPLATE); fits_create_template(&(sf->fptr), sf->filename, template_file, status); // Check to see if file was successfully created if (*status) { fprintf(stderr, "Error creating sdfits file from template.\n"); fits_report_error(stderr, *status); exit(1); } // Go to the primary HDU fits_movabs_hdu(sf->fptr, 1, NULL, status); // Update the keywords that need it fits_get_system_time(ctmp, &itmp, status); // date the file was written fits_update_key(sf->fptr, TSTRING, "DATE", ctmp, NULL, status); // Go to the SINGLE DISH HDU fits_movnam_hdu(sf->fptr, BINARY_TBL, "SINGLE DISH", 0, status); // Update the keywords that need it fits_update_key(sf->fptr, TSTRING, "TELESCOP", hdr->telescope,NULL, status); fits_update_key(sf->fptr, TDOUBLE, "BANDWID", &(hdr->bandwidth), NULL, status); fits_update_key(sf->fptr, TSTRING, "DATE-OBS", hdr->date_obs, NULL, status); fits_update_key(sf->fptr, TDOUBLE, "TSYS", &(hdr->tsys), NULL, status); fits_update_key(sf->fptr, TSTRING, "PROJID", hdr->projid, NULL, status); fits_update_key(sf->fptr, TSTRING, "FRONTEND", hdr->frontend, NULL, status); fits_update_key(sf->fptr, TDOUBLE, "OBSFREQ", &(hdr->obsfreq), NULL, status); fits_update_key(sf->fptr, TDOUBLE, "SCAN", &(hdr->scan), NULL, status); fits_update_key(sf->fptr, TSTRING, "INSTRUME", hdr->instrument, NULL, status); fits_update_key(sf->fptr, TSTRING, "CAL_MODE", hdr->cal_mode, NULL, status); if (strcmp("OFF", hdr->cal_mode) != 0) { fits_update_key(sf->fptr, TDOUBLE, "CAL_FREQ", &(hdr->cal_freq), NULL, status); fits_update_key(sf->fptr, TDOUBLE, "CAL_DCYC", &(hdr->cal_dcyc), NULL, status); fits_update_key(sf->fptr, TDOUBLE, "CAL_PHS", &(hdr->cal_phs), NULL, status); } fits_update_key(sf->fptr, TINT, "NPOL", &(hdr->npol), NULL, status); fits_update_key(sf->fptr, TINT, "NCHAN", &(hdr->nchan), NULL, status); fits_update_key(sf->fptr, TDOUBLE, "CHAN_BW", &(hdr->chan_bw), NULL, status); fits_update_key(sf->fptr, TINT, "NSUBBAND", &(hdr->nsubband), NULL, status); fits_update_key(sf->fptr, TDOUBLE, "EFSAMPFR", &(hdr->efsampfr), NULL, status); fits_update_key(sf->fptr, TDOUBLE, "FPGACLK", &(hdr->fpgaclk), NULL, status); fits_update_key(sf->fptr, TDOUBLE, "HWEXPOSR", &(hdr->hwexposr), NULL, status); fits_update_key(sf->fptr, TDOUBLE, "FILTNEP", &(hdr->filtnep), NULL, status); fits_update_key(sf->fptr, TDOUBLE, "STTMJD", &(hdr->sttmjd), NULL, status); // Update the column sizes for the colums containing arrays itmp = hdr->nsubband * hdr->nchan * 4; //num elements, not bytes fits_modify_vector_len(sf->fptr, 20, itmp, status); // DATA fits_modify_vector_len(sf->fptr, 14, hdr->nsubband, status); // SUBFREQ // Update the TDIM field for the data column sprintf(ctmp, "(%d,%d,4,1,1)", hdr->nchan, hdr->nsubband); fits_update_key(sf->fptr, TSTRING, "TDIM20", ctmp, NULL, status); fits_flush_file(sf->fptr, status); return *status; }
int main(int argc, char **argv) { int i, iarg, nPix, anynul, status, mask; char help[4096]; fitsfile *iPtr; int iBitpix, iNaxis; long iNaxes[MAXDIM]; float *iRData=NULL; fitsfile *mPtr; int mBitpix, mNaxis; long mNaxes[MAXDIM]; int *mRData=NULL; char *inim=NULL, *maskim=NULL, *outim=NULL; float fillVal=D_FILLVAL; /* START */ status = 0; mask = D_MASK; fillVal = D_FILLVAL; sprintf(help, "Usage : maskim [options]\n"); sprintf(help, "%sRequired options:\n", help); sprintf(help, "%s [-inim fitsfile] : input image\n", help); sprintf(help, "%s [-maskim fitsfile]: corresponding mask image\n", help); sprintf(help, "%s [-outim fitsfile] : output masked image\n\n", help); sprintf(help, "%sOptions:\n", help); sprintf(help, "%s [-fi fillval] : Value of filled pixels (%.3f)\n", help, fillVal); sprintf(help, "%s [-mask hex] : Mask for bad pixels (0x%x)\n", help, mask); /* read in command options. j counts # of required args given */ for (iarg=1; iarg < argc; iarg++) { if (argv[iarg][0]=='-') { if (strcasecmp(argv[iarg]+1,"inim")==0) { inim = argv[++iarg]; } else if (strcasecmp(argv[iarg]+1,"maskim")==0) { maskim = argv[++iarg]; } else if (strcasecmp(argv[iarg]+1,"outim")==0) { outim = argv[++iarg]; } else if (strcasecmp(argv[iarg]+1,"fi")==0) { sscanf(argv[++iarg], "%f", &fillVal); } else if (strcasecmp(argv[iarg]+1,"mask")==0) { sscanf(argv[++iarg], "%d", &mask); } else { fprintf(stderr, "Unknown option : %s\n", argv[iarg]); exit(1); } } else { fprintf(stderr, "Unexpected string encountered on command line : %s\n", argv[iarg]); exit(1); } } /* read in command options */ if (argc < 2) { fprintf(stderr, "%s\n", help); exit(1); } /* insanity checking */ if ( !(inim) ) { fprintf(stderr, "FATAL ERROR inim is required command line option\n"); exit(1); } if ( !(maskim) ) { fprintf(stderr, "FATAL ERROR maskim is required command line option\n"); exit(1); } if ( !(outim) ) { fprintf(stderr, "FATAL ERROR outim is required command line option\n"); exit(1); } /* open up, get bitpix, # dimensions, image size */ if ( fits_open_file(&iPtr, inim, 0, &status) || fits_get_img_param(iPtr, 2, &iBitpix, &iNaxis, iNaxes, &status) ) { printError(status); } if ( fits_open_file(&mPtr, maskim, 0, &status) || fits_get_img_param(mPtr, 2, &mBitpix, &mNaxis, mNaxes, &status) ) { printError(status); } assert(iNaxes[0] == mNaxes[0]); assert(iNaxes[1] == mNaxes[1]); nPix = iNaxes[0]*iNaxes[1]; iRData = (float *)realloc(iRData, nPix*sizeof(float)); mRData = (int *)realloc(mRData, nPix*sizeof(int)); if (iRData == NULL || mRData == NULL) { fprintf(stderr, "Cannot Allocate Standard Data Arrays\n"); exit (1); } memset(iRData, 0.0, nPix*sizeof(float)); memset(mRData, 0x0, nPix*sizeof(int)); if (fits_read_img(iPtr, TFLOAT, 1, nPix, 0, iRData, &anynul, &status) || fits_read_img(mPtr, TINT, 1, nPix, 0, mRData, &anynul, &status) || fits_close_file(mPtr, &status)) printError(status); /* do the masking */ for (i = nPix; i--; ) if (mRData[i] & mask) iRData[i] = fillVal; /* reuse mptr and help */ sprintf(help, "!%s", outim); if (fits_create_template(&mPtr, help, inim, &status) || fits_write_img(mPtr, TFLOAT, 1, nPix, iRData, &status) || fits_close_file(mPtr, &status) || fits_close_file(iPtr, &status)) printError(status); free(iRData); free(mRData); return 0; }
//---------------------------------------------------------- int etfits_create(etfits_t * etf) { //---------------------------------------------------------- int * status_p = &(etf->status); *status_p = 0; struct tm tm_now; time_t time_now; char file_name_str[256]; // TODO enclose all init code in a do-as-needed block // Initialize the key variables if needed if (etf->new_run == 1) { // first time writing this run etf->new_run = 0; etf->status = 0; etf->N = 0L; etf->T = 0.0; etf->mode = 'w'; // Create the output directory if needed char datadir[1024]; strncpy(datadir, etf->basefilename, 1023); char *last_slash = strrchr(datadir, '/'); if (last_slash!=NULL && last_slash!=datadir) { *last_slash = '\0'; printf("Using directory '%s' for output.\n", datadir); char cmd[1024]; sprintf(cmd, "mkdir -m 1777 -p %s", datadir); system(cmd); } } // end first time writing this run etf->tot_rows = 0; // count rows per file // Form file name time(&time_now); localtime_r(&time_now, &tm_now); sprintf(file_name_str, "%s_%04d_%04d%02d%02d_%02d%02d%02d", etf->primary_hdr.receiver, etf->file_chan, 1900+tm_now.tm_year, 1+tm_now.tm_mon, tm_now.tm_mday, tm_now.tm_hour, tm_now.tm_min, tm_now.tm_sec); sprintf(etf->filename_working, "%s_%s_%s.working", etf->basefilename, etf->hostname, file_name_str); sprintf(etf->filename_fits, "%s_%s_%s.fits", etf->basefilename, etf->hostname, file_name_str); // Create basic FITS file from our template char template_file[1024]; //printf("Opening file '%s'\n", etf->filename); sprintf(template_file, "%s/%s", etf->s6_dir, ETFITS_TEMPLATE); if(! *status_p) fits_create_template(&(etf->fptr), etf->filename_working, template_file, status_p); // Check to see if file was successfully created if (*status_p) { hashpipe_error(__FUNCTION__, "Error creating sdfits file from template"); //fprintf(stderr, "Error creating sdfits file from template.\n"); fits_report_error(stderr, *status_p); } else { etf->file_open = 1; // successful file open } return *status_p; }
int psrfits_create(struct psrfits *pf) { int itmp, *status; long long lltmp; long double ldtmp; double dtmp; char ctmp[40]; struct hdrinfo *hdr; struct foldinfo *fld; hdr = &(pf->hdr); // dereference the ptr to the header struct status = &(pf->status); // dereference the ptr to the CFITSIO status fld = &(pf->fold); // ptr to foldinfo struct // Figure out what mode this is int mode=0; mode = psrfits_obs_mode(hdr->obs_mode); if (mode==fold) { if (hdr->onlyI) printf("Warning! In folding mode and ONLY_I is set!\n"); if (hdr->ds_time_fact > 1) printf("Warning! In folding mode and DS_TIME is > 1!\n"); if (hdr->ds_freq_fact > 1) printf("Warning! In folding mode and DS_FREQ is > 1!\n"); } // Initialize the key variables if needed if (pf->filenum == 0) { // first time writing to the file pf->status = 0; pf->tot_rows = 0; pf->N = 0L; pf->T = 0.0; hdr->offset_subint = 0; pf->mode = 'w'; // Create the output directory if needed char datadir[1024]; strncpy(datadir, pf->basefilename, 1023); char *last_slash = strrchr(datadir, '/'); if (last_slash!=NULL && last_slash!=datadir) { *last_slash = '\0'; printf("Using directory '%s' for output.\n", datadir); char cmd[1024]; sprintf(cmd, "mkdir -m 1777 -p %s", datadir); system(cmd); } } pf->filenum++; pf->rownum = 1; hdr->offset_subint = pf->tot_rows; // Update the filename - don't include filenum for fold mode // TODO : use rf/cf extensions for psr/cals? if (mode==fold && pf->multifile!=1) sprintf(pf->filename, "%s.fits", pf->basefilename); else sprintf(pf->filename, "%s_%04d.fits", pf->basefilename, pf->filenum); // Create basic FITS file from our template // Fold mode template has additional tables (polyco, ephem) char template_dir[1024]; char template_file[1024]; #ifdef PSRFITS_TEMPLATE_DIR sprintf(template_dir, "%s", PSRFITS_TEMPLATE_DIR); #else char *guppi_dir = getenv("GUPPI_DIR"); if (guppi_dir==NULL) { fprintf(stderr, "Error: GUPPI_DIR environment variable not set, exiting.\n"); exit(1); } sprintf(template_dir, "%s/src", guppi_dir); #endif printf("Opening file '%s' ", pf->filename); if (mode==search) { printf("in search mode.\n"); sprintf(template_file, "%s/%s", template_dir, PSRFITS_SEARCH_TEMPLATE); } else if (mode==fold) { printf("in fold mode.\n"); sprintf(template_file, "%s/%s", template_dir, PSRFITS_FOLD_TEMPLATE); } fits_create_template(&(pf->fptr), pf->filename, template_file, status); // Check to see if file was successfully created if (*status) { fprintf(stderr, "Error creating psrfits file from template.\n"); fits_report_error(stderr, *status); exit(1); } // Go to the primary HDU fits_movabs_hdu(pf->fptr, 1, NULL, status); // Update the keywords that need it fits_get_system_time(ctmp, &itmp, status); // Note: this is the date the file was _written_, not the obs start date fits_update_key(pf->fptr, TSTRING, "DATE", ctmp, NULL, status); fits_update_key(pf->fptr, TSTRING, "TELESCOP", hdr->telescope,NULL, status); fits_update_key(pf->fptr, TSTRING, "OBSERVER", hdr->observer, NULL, status); fits_update_key(pf->fptr, TSTRING, "PROJID", hdr->project_id, NULL, status); fits_update_key(pf->fptr, TSTRING, "FRONTEND", hdr->frontend, NULL, status); fits_update_key(pf->fptr, TSTRING, "BACKEND", hdr->backend, NULL, status); if (hdr->onlyI || hdr->summed_polns) { if (!hdr->onlyI && hdr->npol > 1) { printf("Warning!: Can't have %d polarizations _and_ be summed!\n", hdr->npol); } itmp = 2; fits_update_key(pf->fptr, TINT, "NRCVR", &itmp, NULL, status); } else { if (hdr->npol > 2) { // Can't have more than 2 real polns (i.e. NRCVR) itmp = 2; fits_update_key(pf->fptr, TINT, "NRCVR", &itmp, NULL, status); } else { fits_update_key(pf->fptr, TINT, "NRCVR", &(hdr->npol), NULL, status); } } fits_update_key(pf->fptr, TSTRING, "FD_POLN", hdr->poln_type, NULL, status); fits_update_key(pf->fptr, TINT, "FD_HAND", &(hdr->fd_hand), NULL, status); fits_update_key(pf->fptr, TDOUBLE, "FD_SANG", &(hdr->fd_sang), NULL, status); fits_update_key(pf->fptr, TDOUBLE, "FD_XYPH", &(hdr->fd_xyph), NULL, status); fits_update_key(pf->fptr, TINT, "BE_PHASE", &(hdr->be_phase), NULL, status); fits_update_key(pf->fptr, TSTRING, "DATE-OBS", hdr->date_obs, NULL, status); if (mode==fold && !strcmp("CAL",hdr->obs_mode)) fits_update_key(pf->fptr, TSTRING, "OBS_MODE", hdr->obs_mode, NULL, status); fits_update_key(pf->fptr, TDOUBLE, "OBSFREQ", &(hdr->fctr), NULL, status); fits_update_key(pf->fptr, TDOUBLE, "OBSBW", &(hdr->BW), NULL, status); fits_update_key(pf->fptr, TINT, "OBSNCHAN", &(hdr->orig_nchan), NULL, status); fits_update_key(pf->fptr, TDOUBLE, "CHAN_DM", &(hdr->chan_dm), NULL, status); fits_update_key(pf->fptr, TSTRING, "SRC_NAME", hdr->source, NULL, status); if (!strcmp("UNKNOWN", hdr->track_mode)) { printf("Warning!: Unknown telescope tracking mode!\n"); } fits_update_key(pf->fptr, TSTRING, "TRK_MODE", hdr->track_mode, NULL, status); // TODO: will need to change the following if we aren't tracking! fits_update_key(pf->fptr, TSTRING, "RA", hdr->ra_str, NULL, status); fits_update_key(pf->fptr, TSTRING, "DEC", hdr->dec_str, NULL, status); fits_update_key(pf->fptr, TSTRING, "STT_CRD1", hdr->ra_str, NULL, status); fits_update_key(pf->fptr, TSTRING, "STP_CRD1", hdr->ra_str, NULL, status); // TODO: update these at the end of the file or obs fits_update_key(pf->fptr, TSTRING, "STT_CRD2", hdr->dec_str, NULL, status); fits_update_key(pf->fptr, TSTRING, "STP_CRD2", hdr->dec_str, NULL, status); fits_update_key(pf->fptr, TDOUBLE, "BMAJ", &(hdr->beam_FWHM), NULL, status); fits_update_key(pf->fptr, TDOUBLE, "BMIN", &(hdr->beam_FWHM), NULL, status); if (strcmp("OFF", hdr->cal_mode)) { fits_update_key(pf->fptr, TDOUBLE, "CAL_FREQ", &(hdr->cal_freq), NULL, status); fits_update_key(pf->fptr, TDOUBLE, "CAL_DCYC", &(hdr->cal_dcyc), NULL, status); fits_update_key(pf->fptr, TDOUBLE, "CAL_PHS", &(hdr->cal_phs), NULL, status); } fits_update_key(pf->fptr, TDOUBLE, "SCANLEN", &(hdr->scanlen), NULL, status); itmp = (int) hdr->MJD_epoch; fits_update_key(pf->fptr, TINT, "STT_IMJD", &itmp, NULL, status); ldtmp = (hdr->MJD_epoch - (long double) itmp) * 86400.0L; // in sec itmp = (int) ldtmp; fits_update_key(pf->fptr, TINT, "STT_SMJD", &itmp, NULL, status); ldtmp -= (long double) itmp; dtmp = (double) ldtmp; fits_update_key(pf->fptr, TDOUBLE, "STT_OFFS", &dtmp, NULL, status); fits_update_key(pf->fptr, TDOUBLE, "STT_LST", &(hdr->start_lst), NULL, status); // If fold mode, copy the parfile into the PSRFITS EPHEM table if (mode==fold) { if (strcmp("CAL",hdr->obs_mode)==0) { // CAL mode has no par file, or no par file given psrfits_remove_ephem(pf); } else if (fld->parfile[0]=='\0') { // No par file given fprintf(stderr, "psrfits_create warning: " "Fold mode selected, but no parfile given - " "EPHEM table will be removed.\n" ); psrfits_remove_ephem(pf); } else { FILE *parfile = fopen(fld->parfile, "r"); if (parfile==NULL) { fprintf(stderr, "psrfits_create warning: " "Error opening parfile %s - " "EPHEM table will be removed.\n", fld->parfile ); psrfits_remove_ephem(pf); } else { psrfits_write_ephem(pf, parfile); fclose(parfile); } } } // Go to the SUBINT HDU fits_movnam_hdu(pf->fptr, BINARY_TBL, "SUBINT", 0, status); // Update the keywords that need it if (hdr->onlyI) { itmp = 1; fits_update_key(pf->fptr, TINT, "NPOL", &itmp, NULL, status); } else { fits_update_key(pf->fptr, TINT, "NPOL", &(hdr->npol), NULL, status); } if (!hdr->onlyI && !hdr->summed_polns) { // TODO: These need to be updated for the real machine. if (hdr->npol==1) strcpy(ctmp, "AA"); else if (hdr->npol==2) strcpy(ctmp, "AABB"); else if (hdr->npol==4) { if (strncmp(hdr->poln_order, "AABBCRCI", 8)==0) strcpy(ctmp, hdr->poln_order); else strcpy(ctmp, "IQUV"); } fits_update_key(pf->fptr, TSTRING, "POL_TYPE", ctmp, NULL, status); } else { fits_update_key(pf->fptr, TSTRING, "POL_TYPE", "AA+BB", NULL, status); } // TODO what does TBIN mean in fold mode? dtmp = hdr->dt * hdr->ds_time_fact; fits_update_key(pf->fptr, TDOUBLE, "TBIN", &dtmp, NULL, status); fits_update_key(pf->fptr, TINT, "NSUBOFFS", &(hdr->offset_subint), NULL, status); itmp = hdr->nchan / hdr->ds_freq_fact; fits_update_key(pf->fptr, TINT, "NCHAN", &itmp, NULL, status); dtmp = hdr->df * hdr->ds_freq_fact; fits_update_key(pf->fptr, TDOUBLE, "CHAN_BW", &dtmp, NULL, status); if (mode==search) { int out_nsblk = hdr->nsblk / hdr->ds_time_fact; itmp = 1; fits_update_key(pf->fptr, TINT, "NSBLK", &out_nsblk, NULL, status); fits_update_key(pf->fptr, TINT, "NBITS", &(hdr->nbits), NULL, status); fits_update_key(pf->fptr, TINT, "NBIN", &itmp, NULL, status); } else if (mode==fold) { itmp = 1; fits_update_key(pf->fptr, TINT, "NSBLK", &itmp, NULL, status); fits_update_key(pf->fptr, TINT, "NBITS", &itmp, NULL, status); fits_update_key(pf->fptr, TINT, "NBIN", &(hdr->nbin), NULL, status); fits_update_key(pf->fptr, TSTRING, "EPOCHS", "MIDTIME", NULL, status); } // Update the column sizes for the colums containing arrays { int out_npol = hdr->npol; int out_nchan = hdr->nchan / hdr->ds_freq_fact; if (hdr->onlyI) out_npol = 1; int out_nsblk = hdr->nsblk / hdr->ds_time_fact; fits_modify_vector_len(pf->fptr, 13, out_nchan, status); // DAT_FREQ fits_modify_vector_len(pf->fptr, 14, out_nchan, status); // DAT_WTS itmp = out_nchan * out_npol; fits_modify_vector_len(pf->fptr, 15, itmp, status); // DAT_OFFS fits_modify_vector_len(pf->fptr, 16, itmp, status); // DAT_SCL if (mode==search) { lltmp = out_nsblk; lltmp = (lltmp * hdr->nbits * out_nchan * out_npol) / 8L; } else if (mode==fold) lltmp = (hdr->nbin * out_nchan * out_npol); fits_modify_vector_len(pf->fptr, 17, lltmp, status); // DATA // Update the TDIM field for the data column if (mode==search) sprintf(ctmp, "(1,%d,%d,%d)", out_nchan, out_npol, out_nsblk); else if (mode==fold) sprintf(ctmp, "(%d,%d,%d,1)", hdr->nbin, out_nchan, out_npol); fits_update_key(pf->fptr, TSTRING, "TDIM17", ctmp, NULL, status); } fits_flush_file(pf->fptr, status); return *status; }
int main(int argc, char *argv[]) { int numfiles, ii, numrows, rownum, ichan, itsamp, datidx; int spec_per_row, status, maxrows; unsigned long int maxfilesize; float offset, scale, datum, packdatum, maxval, fulltsubint; float *datachunk; FILE **infiles; struct psrfits pfin, pfout; Cmdline *cmd; fitsfile *infits, *outfits; char outfilename[128], templatename[128], tform[8]; char *pc1, *pc2; int first = 1, dummy = 0, nclipped; short int *inrowdata; unsigned char *outrowdata; if (argc == 1) { Program = argv[0]; usage(); exit(1); } // Parse the command line using the excellent program Clig cmd = parseCmdline(argc, argv); numfiles = cmd->argc; infiles = (FILE **) malloc(numfiles * sizeof(FILE *)); //Set the max. total size (in bytes) of all rows in an output file, //leaving some room for PSRFITS header maxfilesize = (unsigned long int)(cmd->numgb * GB); maxfilesize = maxfilesize - 1000*KB; //fprintf(stderr,"cmd->numgb: %f maxfilesize: %ld\n",cmd->numgb,maxfilesize); #ifdef DEBUG showOptionValues(); #endif printf("\n PSRFITS 16-bit to 4-bit Conversion Code\n"); printf(" by J. Deneva, S. Ransom, & S. Chatterjee\n\n"); // Open the input files status = 0; //fits_close segfaults if this is not initialized printf("Reading input data from:\n"); for (ii = 0; ii < numfiles; ii++) { printf(" '%s'\n", cmd->argv[ii]); //Get the file basename and number from command-line argument //(code taken from psrfits2fil) pc2 = strrchr(cmd->argv[ii], '.'); // at .fits *pc2 = 0; // terminate string pc1 = pc2 - 1; while ((pc1 >= cmd->argv[ii]) && isdigit(*pc1)) pc1--; if (pc1 <= cmd->argv[ii]) { // need at least 1 char before filenum puts("Illegal input filename. must have chars before the filenumber"); exit(1); } pc1++; // we were sitting on "." move to first digit pfin.filenum = atoi(pc1); pfin.fnamedigits = pc2 - pc1; // how many digits in filenumbering scheme. *pc1 = 0; // null terminate the basefilename strcpy(pfin.basefilename, cmd->argv[ii]); pfin.initialized = 0; // set to 1 in psrfits_open() pfin.status = 0; //(end of code taken from psrfits2fil) //Open the existing psrfits file if (psrfits_open(&pfin, READONLY) != 0) { fprintf(stderr, "error opening file\n"); fits_report_error(stderr, pfin.status); exit(1); } // Create the subint arrays if (first) { pfin.sub.dat_freqs = (float *) malloc(sizeof(float) * pfin.hdr.nchan); pfin.sub.dat_weights = (float *) malloc(sizeof(float) * pfin.hdr.nchan); pfin.sub.dat_offsets = (float *) malloc(sizeof(float) * pfin.hdr.nchan * pfin.hdr.npol); pfin.sub.dat_scales = (float *) malloc(sizeof(float) * pfin.hdr.nchan * pfin.hdr.npol); //first is set to 0 after data buffer allocation further below } infits = pfin.fptr; spec_per_row = pfin.hdr.nsblk; fits_read_key(infits, TINT, "NAXIS2", &dummy, NULL, &status); pfin.tot_rows = dummy; numrows = dummy; //If dealing with 1st input file, create output template if (ii == 0) { sprintf(templatename, "%s.template.fits",cmd->outfile); fits_create_file(&outfits, templatename, &status); //fprintf(stderr,"pfin.basefilename: %s\n", pfin.basefilename); //fprintf(stderr,"status: %d\n", status); //Instead of copying HDUs one by one, can move to the SUBINT //HDU, and copy all the HDUs preceding it fits_movnam_hdu(infits, BINARY_TBL, "SUBINT", 0, &status); fits_copy_file(infits, outfits, 1, 0, 0, &status); //Copy the SUBINT table header fits_copy_header(infits, outfits, &status); fits_flush_buffer(outfits, 0, &status); //Set NAXIS2 in the output SUBINT table to 0 b/c we haven't //written any rows yet dummy = 0; fits_update_key(outfits, TINT, "NAXIS2", &dummy, NULL, &status); //Edit the NBITS key if (DEBUG) { dummy = 8; fits_update_key(outfits, TINT, "NBITS", &dummy, NULL, &status); } else { fits_update_key(outfits, TINT, "NBITS", &(cmd->numbits), NULL, &status); } //Edit the TFORM17 column: # of data bytes per row //fits_get_colnum(outfits,1,"DATA",&dummy,&status); if (DEBUG) sprintf(tform, "%dB", pfin.hdr.nsblk * pfin.hdr.nchan * pfin.hdr.npol); else sprintf(tform, "%dB", pfin.hdr.nsblk * pfin.hdr.nchan * pfin.hdr.npol * cmd->numbits / 8); fits_update_key(outfits, TSTRING, "TTYPE17", "DATA", NULL, &status); fits_update_key(outfits, TSTRING, "TFORM17", tform, NULL, &status); //Edit NAXIS1: row width in bytes fits_read_key(outfits, TINT, "NAXIS1", &dummy, NULL, &status); if (DEBUG) { dummy = dummy - pfin.hdr.nsblk * pfin.hdr.nchan * pfin.hdr.npol * (pfin.hdr.nbits - 8) / 8; } else { dummy = dummy - pfin.hdr.nsblk * pfin.hdr.nchan * pfin.hdr.npol * (pfin.hdr.nbits - cmd->numbits) / 8; } fits_update_key(outfits, TINT, "NAXIS1", &dummy, NULL, &status); //Set the max # of rows per file, based on the requested //output file size maxrows = maxfilesize / dummy; //fprintf(stderr,"maxrows: %d\n",maxrows); fits_close_file(outfits, &status); rownum = 0; } while (psrfits_read_subint(&pfin, first) == 0) { fprintf(stderr, "Working on row %d\n", ++rownum); //If this is the first row, store the length of a full subint if (ii == 0 && rownum == 1) fulltsubint = pfin.sub.tsubint; //If this is the last row and it's partial, drop it. //(It's pfin.rownum-1 below because the rownum member of the psrfits struct seems to be intended to indicate at the *start* of what row we are, i.e. a row that has not yet been read. In contrast, pfout.rownum indicates how many rows have been written, i.e. at the *end* of what row we are in the output.) if (pfin.rownum-1 == numrows && fabs(pfin.sub.tsubint - fulltsubint) > pfin.hdr.dt) { fprintf(stderr, "Dropping partial row of length %f s (full row is %f s)\n", pfin.sub.tsubint, fulltsubint); break; } //If we just read in the 1st row, or if we already wrote the last row in the current output file, create a new output file if ((ii == 0 && rownum == 1) || pfout.rownum == maxrows) { //Create new output file from the template pfout.fnamedigits = pfin.fnamedigits; if(ii == 0) pfout.filenum = pfin.filenum; else pfout.filenum++; sprintf(outfilename, "%s.%0*d.fits", cmd->outfile, pfout.fnamedigits, pfout.filenum); fits_create_template(&outfits, outfilename, templatename, &status); //fprintf(stderr,"After fits_create_template, status: %d\n",status); fits_close_file(outfits, &status); //Now reopen the file so that the pfout structure is initialized pfout.status = 0; pfout.initialized = 0; sprintf(pfout.basefilename, "%s.", cmd->outfile); if (psrfits_open(&pfout, READWRITE) != 0) { fprintf(stderr, "error opening file\n"); fits_report_error(stderr, pfout.status); exit(1); } outfits = pfout.fptr; maxval = pow(2, cmd->numbits) - 1; pfout.rows_per_file = maxrows; //fprintf(stderr, "maxval: %f\n", maxval); //fprintf(stderr, "pfout.rows_per_file: %d\n",pfout.rows_per_file); //These are not initialized in psrfits_open but are needed //in psrfits_write_subint (not obvious what are the corresponding //fields in any of the psrfits table headers) pfout.hdr.ds_freq_fact = 1; pfout.hdr.ds_time_fact = 1; } //Copy the subint struct from pfin to pfout, but correct //elements that are not the same pfout.sub = pfin.sub; //this copies array pointers too pfout.sub.bytes_per_subint = pfin.sub.bytes_per_subint * pfout.hdr.nbits / pfin.hdr.nbits; pfout.sub.dataBytesAlloced = pfout.sub.bytes_per_subint; pfout.sub.FITS_typecode = TBYTE; if (first) { //Allocate scaling buffer and output buffer datachunk = gen_fvect(spec_per_row); outrowdata = gen_bvect(pfout.sub.bytes_per_subint); first = 0; } pfout.sub.data = outrowdata; inrowdata = (short int *) pfin.sub.data; nclipped = 0; // Loop over all the channels: for (ichan = 0; ichan < pfout.hdr.nchan * pfout.hdr.npol; ichan++) { // Populate datachunk[] by picking out all time samples for ichan for (itsamp = 0; itsamp < spec_per_row; itsamp++) datachunk[itsamp] = (float) (inrowdata[ichan + itsamp * pfout.hdr.nchan * pfout.hdr.npol]); // Compute the statistics here, and put the offsets and scales in // pf.sub.dat_offsets[] and pf.sub.dat_scales[] if (rescale(datachunk, spec_per_row, cmd->numbits, &offset, &scale) != 0) { printf("Rescale routine failed!\n"); return (-1); } pfout.sub.dat_offsets[ichan] = offset; pfout.sub.dat_scales[ichan] = scale; // Since we have the offset and scale ready, rescale the data: for (itsamp = 0; itsamp < spec_per_row; itsamp++) { datum = (scale == 0.0) ? 0.0 : roundf((datachunk[itsamp] - offset) / scale); if (datum < 0.0) { datum = 0; nclipped++; } else if (datum > maxval) { datum = maxval; nclipped++; } inrowdata[ichan + itsamp * pfout.hdr.nchan * pfout.hdr.npol] = (short int) datum; } // Now inrowdata[ichan] contains rescaled ints. } // Then do the conversion and store the // results in pf.sub.data[] if (cmd->numbits == 8 || DEBUG) { for (itsamp = 0; itsamp < spec_per_row; itsamp++) { datidx = itsamp * pfout.hdr.nchan * pfout.hdr.npol; for (ichan = 0; ichan < pfout.hdr.nchan * pfout.hdr.npol; ichan++, datidx++) { pfout.sub.data[datidx] = (unsigned char) inrowdata[datidx]; } } } else if (cmd->numbits == 4) { for (itsamp = 0; itsamp < spec_per_row; itsamp++) { datidx = itsamp * pfout.hdr.nchan * pfout.hdr.npol; for (ichan = 0; ichan < pfout.hdr.nchan * pfout.hdr.npol; ichan += 2, datidx += 2) { packdatum = inrowdata[datidx] * 16 + inrowdata[datidx + 1]; pfout.sub.data[datidx / 2] = (unsigned char) packdatum; } } } else { fprintf(stderr, "Only 4 or 8-bit output formats supported.\n"); fprintf(stderr, "Bits per sample requested: %d\n", cmd->numbits); exit(1); } //pfout.sub.offs = (pfout.tot_rows+0.5) * pfout.sub.tsubint; fprintf(stderr, "nclipped: %d fraction clipped: %f\n", nclipped, (float) nclipped / (pfout.hdr.nchan * pfout.hdr.npol * pfout.hdr.nsblk)); // Now write the row. status = psrfits_write_subint(&pfout); if (status) { printf("\nError (%d) writing PSRFITS...\n\n", status); break; } //If current output file has reached the max # of rows, close it if (pfout.rownum == maxrows) fits_close_file(outfits, &status); } //Close the files fits_close_file(infits, &status); } fits_close_file(outfits, &status); // Free the structure arrays too... free(datachunk); free(infiles); free(pfin.sub.dat_freqs); free(pfin.sub.dat_weights); free(pfin.sub.dat_offsets); free(pfin.sub.dat_scales); free(pfin.sub.data); free(pfout.sub.data); free(pfin.sub.stat); return 0; }