void guppi_psrfits_thread(void *_args) { /* Get args */ struct guppi_thread_args *args = (struct guppi_thread_args *)_args; pthread_cleanup_push((void *)guppi_thread_set_finished, args); /* Set cpu affinity */ cpu_set_t cpuset, cpuset_orig; sched_getaffinity(0, sizeof(cpu_set_t), &cpuset_orig); CPU_ZERO(&cpuset); CPU_SET(1, &cpuset); int rv = sched_setaffinity(0, sizeof(cpu_set_t), &cpuset); if (rv<0) { guppi_error("guppi_psrfits_thread", "Error setting cpu affinity."); perror("sched_setaffinity"); } /* Set priority */ rv = setpriority(PRIO_PROCESS, 0, args->priority); if (rv<0) { guppi_error("guppi_psrfits_thread", "Error setting priority level."); perror("set_priority"); } /* Attach to status shared mem area */ struct guppi_status st; rv = guppi_status_attach(&st); if (rv!=GUPPI_OK) { guppi_error("guppi_psrfits_thread", "Error attaching to status shared memory."); pthread_exit(NULL); } pthread_cleanup_push((void *)guppi_status_detach, &st); pthread_cleanup_push((void *)set_exit_status, &st); /* Init status */ guppi_status_lock_safe(&st); hputs(st.buf, STATUS_KEY, "init"); guppi_status_unlock_safe(&st); /* Initialize some key parameters */ struct guppi_params gp; struct psrfits pf; pf.sub.data = NULL; pf.sub.dat_freqs = pf.sub.dat_weights = NULL; pf.sub.dat_offsets = pf.sub.dat_scales = NULL; pf.hdr.chan_dm = 0.0; pf.filenum = 0; // This is crucial pthread_cleanup_push((void *)guppi_free_psrfits, &pf); pthread_cleanup_push((void *)psrfits_close, &pf); //pf.multifile = 0; // Use a single file for fold mode pf.multifile = 1; // Use a multiple files for fold mode pf.quiet = 0; // Print a message per each subint written /* Attach to databuf shared mem */ struct guppi_databuf *db; db = guppi_databuf_attach(args->input_buffer); if (db==NULL) { guppi_error("guppi_psrfits_thread", "Error attaching to databuf shared memory."); pthread_exit(NULL); } pthread_cleanup_push((void *)guppi_databuf_detach, db); /* Loop */ int curblock=0, total_status=0, firsttime=1, run=1, got_packet_0=0; int mode=SEARCH_MODE; char *ptr; char tmpstr[256]; struct foldbuf fb; struct polyco pc[64]; memset(pc, 0, sizeof(pc)); int n_polyco_written=0; float *fold_output_array = NULL; int scan_finished=0; signal(SIGINT, cc); do { /* Note waiting status */ guppi_status_lock_safe(&st); if (got_packet_0) sprintf(tmpstr, "waiting(%d)", curblock); else sprintf(tmpstr, "ready"); hputs(st.buf, STATUS_KEY, tmpstr); guppi_status_unlock_safe(&st); /* Wait for buf to have data */ rv = guppi_databuf_wait_filled(db, curblock); if (rv!=0) { // This is a big ol' kludge to avoid this process hanging // due to thread synchronization problems. sleep(1); continue; } /* Note current block */ guppi_status_lock_safe(&st); hputi4(st.buf, "CURBLOCK", curblock); guppi_status_unlock_safe(&st); /* See how full databuf is */ total_status = guppi_databuf_total_status(db); /* Read param structs for this block */ ptr = guppi_databuf_header(db, curblock); if (firsttime) { guppi_read_obs_params(ptr, &gp, &pf); firsttime = 0; } else { guppi_read_subint_params(ptr, &gp, &pf); } /* Find out what mode this data is in */ mode = psrfits_obs_mode(pf.hdr.obs_mode); /* Check if we got both packet 0 and a valid observation * start time. If so, flag writing to start. */ if (got_packet_0==0 && gp.packetindex==0 && gp.stt_valid==1) { got_packet_0 = 1; guppi_read_obs_params(ptr, &gp, &pf); guppi_update_ds_params(&pf); memset(pc, 0, sizeof(pc)); n_polyco_written=0; } /* If actual observation has started, write the data */ if (got_packet_0) { /* Note waiting status */ guppi_status_lock_safe(&st); hputs(st.buf, STATUS_KEY, "writing"); guppi_status_unlock_safe(&st); /* Get the pointer to the current data */ if (mode==FOLD_MODE) { fb.nchan = pf.hdr.nchan; fb.npol = pf.hdr.npol; fb.nbin = pf.hdr.nbin; fb.data = (float *)guppi_databuf_data(db, curblock); fb.count = (unsigned *)(guppi_databuf_data(db, curblock) + foldbuf_data_size(&fb)); fold_output_array = (float *)realloc(fold_output_array, sizeof(float) * pf.hdr.nbin * pf.hdr.nchan * pf.hdr.npol); pf.sub.data = (unsigned char *)fold_output_array; pf.fold.pc = (struct polyco *)(guppi_databuf_data(db,curblock) + foldbuf_data_size(&fb) + foldbuf_count_size(&fb)); } else pf.sub.data = (unsigned char *)guppi_databuf_data(db, curblock); /* Set the DC and Nyquist channels explicitly to zero */ /* because of the "FFT Problem" that splits DC power */ /* into those two bins. */ zero_end_chans(&pf); /* Output only Stokes I (in place) */ if (pf.hdr.onlyI && pf.hdr.npol==4) get_stokes_I(&pf); /* Downsample in frequency (in place) */ if (pf.hdr.ds_freq_fact > 1) downsample_freq(&pf); /* Downsample in time (in place) */ if (pf.hdr.ds_time_fact > 1) downsample_time(&pf); /* Folded data needs a transpose */ if (mode==FOLD_MODE) normalize_transpose_folds(fold_output_array, &fb); /* Write the data */ int last_filenum = pf.filenum; psrfits_write_subint(&pf); /* Any actions that need to be taken when a new file * is created. */ if (pf.filenum!=last_filenum) { /* No polycos yet written to the new file */ n_polyco_written=0; } /* Write the polycos if needed */ int write_pc=0, i, j; for (i=0; i<pf.fold.n_polyco_sets; i++) { if (pf.fold.pc[i].used==0) continue; int new_pc=1; for (j=0; j<n_polyco_written; j++) { if (polycos_differ(&pf.fold.pc[i], &pc[j])==0) { new_pc=0; break; } } if (new_pc || n_polyco_written==0) { pc[n_polyco_written] = pf.fold.pc[i]; n_polyco_written++; write_pc=1; } else { pf.fold.pc[i].used = 0; // Already have this one } } if (write_pc) psrfits_write_polycos(&pf, pf.fold.pc, pf.fold.n_polyco_sets); /* Is the scan complete? */ if ((pf.hdr.scanlen > 0.0) && (pf.T > pf.hdr.scanlen)) scan_finished = 1; /* For debugging... */ if (gp.drop_frac > 0.0) { printf("Block %d dropped %.3g%% of the packets\n", pf.tot_rows, gp.drop_frac*100.0); } } /* Mark as free */ guppi_databuf_set_free(db, curblock); /* Go to next block */ curblock = (curblock + 1) % db->n_block; /* Check for cancel */ pthread_testcancel(); } while (run && !scan_finished); /* Cleanup */ if (fold_output_array!=NULL) free(fold_output_array); pthread_exit(NULL); pthread_cleanup_pop(0); /* Closes psrfits_close */ pthread_cleanup_pop(0); /* Closes guppi_free_psrfits */ pthread_cleanup_pop(0); /* Closes set_exit_status */ pthread_cleanup_pop(0); /* Closes set_finished */ pthread_cleanup_pop(0); /* Closes guppi_status_detach */ pthread_cleanup_pop(0); /* Closes guppi_databuf_detach */ }
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 psrfits_write_subint(struct psrfits *pf) { int row, *status, nchan, nivals, mode, out_nbytes; float ftmp; struct hdrinfo *hdr; struct subint *sub; hdr = &(pf->hdr); // dereference the ptr to the header struct sub = &(pf->sub); // dereference the ptr to the subint struct status = &(pf->status); // dereference the ptr to the CFITSIO status nchan = hdr->nchan / hdr->ds_freq_fact; if (hdr->onlyI) nivals = nchan; else nivals = nchan * hdr->npol; mode = psrfits_obs_mode(hdr->obs_mode); if (mode==fold) out_nbytes = sub->bytes_per_subint / hdr->ds_freq_fact; else { out_nbytes = sub->bytes_per_subint / (hdr->ds_freq_fact * hdr->ds_time_fact); if (hdr->onlyI) out_nbytes /= hdr->npol; } // Create the initial file or change to a new one if needed. // Stay with a single file for fold mode. if (pf->filenum==0 || ( (mode==search || pf->multifile==1) && pf->rownum > pf->rows_per_file)) { if (pf->filenum) { printf("Closing file '%s'\n", pf->filename); fits_close_file(pf->fptr, status); } psrfits_create(pf); } row = pf->rownum; fits_write_col(pf->fptr, TDOUBLE, 1, row, 1, 1, &(sub->tsubint), status); fits_write_col(pf->fptr, TDOUBLE, 2, row, 1, 1, &(sub->offs), status); fits_write_col(pf->fptr, TDOUBLE, 3, row, 1, 1, &(sub->lst), status); fits_write_col(pf->fptr, TDOUBLE, 4, row, 1, 1, &(sub->ra), status); fits_write_col(pf->fptr, TDOUBLE, 5, row, 1, 1, &(sub->dec), status); fits_write_col(pf->fptr, TDOUBLE, 6, row, 1, 1, &(sub->glon), status); fits_write_col(pf->fptr, TDOUBLE, 7, row, 1, 1, &(sub->glat), status); ftmp = (float) sub->feed_ang; fits_write_col(pf->fptr, TFLOAT, 8, row, 1, 1, &ftmp, status); ftmp = (float) sub->pos_ang; fits_write_col(pf->fptr, TFLOAT, 9, row, 1, 1, &ftmp, status); ftmp = (float) sub->par_ang; fits_write_col(pf->fptr, TFLOAT, 10, row, 1, 1, &ftmp, status); ftmp = (float) sub->tel_az; fits_write_col(pf->fptr, TFLOAT, 11, row, 1, 1, &ftmp, status); ftmp = (float) sub->tel_zen; fits_write_col(pf->fptr, TFLOAT, 12, row, 1, 1, &ftmp, status); fits_write_col(pf->fptr, TDOUBLE, 13, row, 1, nchan, sub->dat_freqs, status); fits_write_col(pf->fptr, TFLOAT, 14, row, 1, nchan, sub->dat_weights, status); fits_write_col(pf->fptr, TFLOAT, 15, row, 1, nivals, sub->dat_offsets, status); fits_write_col(pf->fptr, TFLOAT, 16, row, 1, nivals, sub->dat_scales, status); if (mode==search) { if (hdr->nbits==4) pf_8bit_to_4bit(pf); fits_write_col(pf->fptr, TBYTE, 17, row, 1, out_nbytes, sub->rawdata, status); } else if (mode==fold) { // Fold mode writes floats for now.. fits_write_col(pf->fptr, TFLOAT, 17, row, 1, out_nbytes/sizeof(float), sub->data, status); } // Flush the buffers if not finished with the file // Note: this use is not entirely in keeping with the CFITSIO // documentation recommendations. However, manually // correcting NAXIS2 and using fits_flush_buffer() // caused occasional hangs (and extrememly large // files due to some infinite loop). fits_flush_file(pf->fptr, status); // Print status if bad if (*status) { fprintf(stderr, "Error writing subint %d:\n", pf->rownum); fits_report_error(stderr, *status); fflush(stderr); } // Now update some key values if no CFITSIO errors if (!(*status)) { pf->rownum++; pf->tot_rows++; pf->N += hdr->nsblk / hdr->ds_time_fact; pf->T += sub->tsubint; // For fold mode, print info each subint written if (mode==fold && pf->quiet!=1) { printf("Wrote subint %d (total time %.1fs)\n", pf->rownum-1, pf->T); fflush(stdout); } } return *status; }
/* This function is similar to psrfits_create, except it * deals with reading existing files. It is assumed that * basename and filenum are filled in correctly to point to * the first file in the set OR that filename already contains * the correct file name. */ int psrfits_open(struct psrfits *pf) { int itmp; double dtmp; char ctmp[256]; struct hdrinfo *hdr = &(pf->hdr); struct subint *sub = &(pf->sub); struct foldinfo *fold = &(pf->fold); int *status = &(pf->status); if (pf->numfiles==0) { // Dynamically generated file names sprintf(pf->filename, "%s_%04d.fits", pf->basefilename, pf->filenum); } else { // Using explicit filenames if (pf->filenum < pf->numfiles) { strncpy(pf->filename, pf->filenames[pf->filenum], 200); } else { *status = FILE_NOT_OPENED; return *status; } } fits_open_file(&(pf->fptr), pf->filename, READONLY, status); pf->mode = 'r'; // If file no exist, exit now if (*status) { return *status; } else { printf("Opened file '%s'\n", pf->filename); } // Move to main HDU fits_movabs_hdu(pf->fptr, 1, NULL, status); // Figure out obs mode fits_read_key(pf->fptr, TSTRING, "OBS_MODE", hdr->obs_mode, NULL, status); int mode = psrfits_obs_mode(hdr->obs_mode); // Set the downsampling stuff to default values hdr->onlyI = 0; hdr->ds_time_fact = 1; hdr->ds_freq_fact = 1; // Blank parfile name, folding params fold->parfile[0] = '\0'; fold->n_polyco_sets = 0; fold->pc = NULL; // Read some stuff fits_read_key(pf->fptr, TSTRING, "TELESCOP", hdr->telescope, NULL, status); fits_read_key(pf->fptr, TSTRING, "OBSERVER", hdr->observer, NULL, status); fits_read_key(pf->fptr, TSTRING, "PROJID", hdr->project_id, NULL, status); fits_read_key(pf->fptr, TSTRING, "FRONTEND", hdr->frontend, NULL, status); fits_read_key(pf->fptr, TSTRING, "BACKEND", hdr->backend, NULL, status); fits_read_key(pf->fptr, TSTRING, "FD_POLN", hdr->poln_type, NULL, status); fits_read_key(pf->fptr, TSTRING, "DATE-OBS", hdr->date_obs, NULL, status); fits_read_key(pf->fptr, TDOUBLE, "OBSFREQ", &(hdr->fctr), NULL, status); fits_read_key(pf->fptr, TDOUBLE, "OBSBW", &(hdr->BW), NULL, status); fits_read_key(pf->fptr, TINT, "OBSNCHAN", &(hdr->orig_nchan), NULL, status); hdr->orig_df = hdr->BW / hdr->orig_nchan; fits_read_key(pf->fptr, TDOUBLE, "CHAN_DM", &(hdr->chan_dm), NULL, status); if (*status==KEY_NO_EXIST) { hdr->chan_dm=0.0; *status=0; } fits_read_key(pf->fptr, TSTRING, "SRC_NAME", hdr->source, NULL, status); fits_read_key(pf->fptr, TSTRING, "TRK_MODE", hdr->track_mode, NULL, status); // TODO warn if not TRACK? fits_read_key(pf->fptr, TSTRING, "RA", hdr->ra_str, NULL, status); fits_read_key(pf->fptr, TSTRING, "DEC", hdr->dec_str, NULL, status); fits_read_key(pf->fptr, TDOUBLE, "BMAJ", &(hdr->beam_FWHM), NULL, status); fits_read_key(pf->fptr, TSTRING, "CAL_MODE", hdr->cal_mode, NULL, status); fits_read_key(pf->fptr, TDOUBLE, "CAL_FREQ", &(hdr->cal_freq), NULL, status); fits_read_key(pf->fptr, TDOUBLE, "CAL_DCYC", &(hdr->cal_dcyc), NULL, status); fits_read_key(pf->fptr, TDOUBLE, "CAL_PHS", &(hdr->cal_phs), NULL, status); fits_read_key(pf->fptr, TSTRING, "FD_MODE", hdr->feed_mode, NULL, status); fits_read_key(pf->fptr, TDOUBLE, "FA_REQ", &(hdr->feed_angle), NULL, status); fits_read_key(pf->fptr, TDOUBLE, "SCANLEN", &(hdr->scanlen), NULL, status); fits_read_key(pf->fptr, TDOUBLE, "FD_SANG", &(hdr->fd_sang), NULL, status); fits_read_key(pf->fptr, TDOUBLE, "FD_XYPH", &(hdr->fd_xyph), NULL, status); fits_read_key(pf->fptr, TINT, "FD_HAND", &(hdr->fd_hand), NULL, status); fits_read_key(pf->fptr, TINT, "BE_PHASE", &(hdr->be_phase), NULL, status); fits_read_key(pf->fptr, TINT, "STT_IMJD", &itmp, NULL, status); hdr->MJD_epoch = (long double)itmp; hdr->start_day = itmp; fits_read_key(pf->fptr, TDOUBLE, "STT_SMJD", &dtmp, NULL, status); hdr->MJD_epoch += dtmp/86400.0L; hdr->start_sec = dtmp; fits_read_key(pf->fptr, TDOUBLE, "STT_OFFS", &dtmp, NULL, status); hdr->MJD_epoch += dtmp/86400.0L; hdr->start_sec += dtmp; fits_read_key(pf->fptr, TDOUBLE, "STT_LST", &(hdr->start_lst), NULL, status); // Move to first subint fits_movnam_hdu(pf->fptr, BINARY_TBL, "SUBINT", 0, status); // Read some more stuff fits_read_key(pf->fptr, TINT, "NPOL", &(hdr->npol), NULL, status); fits_read_key(pf->fptr, TSTRING, "POL_TYPE", &(hdr->poln_order), NULL, status); if (strncmp(hdr->poln_order, "AA+BB", 6)==0) hdr->summed_polns=1; else hdr->summed_polns=0; fits_read_key(pf->fptr, TDOUBLE, "TBIN", &(hdr->dt), NULL, status); fits_read_key(pf->fptr, TINT, "NBIN", &(hdr->nbin), NULL, status); fits_read_key(pf->fptr, TINT, "NSUBOFFS", &(hdr->offset_subint), NULL, status); fits_read_key(pf->fptr, TINT, "NCHAN", &(hdr->nchan), NULL, status); fits_read_key(pf->fptr, TDOUBLE, "CHAN_BW", &(hdr->df), NULL, status); fits_read_key(pf->fptr, TINT, "NSBLK", &(hdr->nsblk), NULL, status); fits_read_key(pf->fptr, TINT, "NBITS", &(hdr->nbits), NULL, status); if (mode==SEARCH_MODE) { long long lltmp = hdr->nsblk; // Prevents a possible overflow in numerator below lltmp = (lltmp * hdr->nbits * hdr->nchan * hdr->npol) / 8L; sub->bytes_per_subint = (int) lltmp; } else if (mode==FOLD_MODE) { sub->bytes_per_subint = (hdr->nbin * hdr->nchan * hdr->npol); // XXX data type?? } // Init counters pf->rownum = 1; fits_read_key(pf->fptr, TINT, "NAXIS2", &(pf->rows_per_file), NULL, status); return *status; }
/* Read next subint from the set of files described * by the psrfits struct. It is assumed that all files * form a consistent set. Read automatically goes to the * next file when one ends. Arrays should be allocated * outside this routine. */ int psrfits_read_subint(struct psrfits *pf) { struct hdrinfo *hdr = &(pf->hdr); struct subint *sub = &(pf->sub); int colnum = 0, *status = &(pf->status); // See if we need to move to next file if (pf->rownum > pf->rows_per_file) { printf("Closing file '%s'\n", pf->filename); fits_close_file(pf->fptr, status); pf->filenum++; psrfits_open(pf); if (*status==FILE_NOT_OPENED) { printf("Finished with all input files.\n"); pf->filenum--; *status = 1; return *status; } } int mode = psrfits_obs_mode(hdr->obs_mode); int nchan = hdr->nchan; int nivals = hdr->nchan * hdr->npol; int row = pf->rownum; // TODO: bad! really need to base this on column names fits_get_colnum(pf->fptr, 0, "TSUBINT", &colnum, status); fits_read_col(pf->fptr, TDOUBLE, colnum, row, 1, 1, NULL, &(sub->tsubint), NULL, status); double last_offs = sub->offs; fits_get_colnum(pf->fptr, 0, "OFFS_SUB", &colnum, status); fits_read_col(pf->fptr, TDOUBLE, colnum, row, 1, 1, NULL, &(sub->offs), NULL, status); // Hack to fix wrapping in coherent data if (pf->tot_rows > 0) { double delta_offs = sub->offs - last_offs; double wrap_offs = 4294967296L * hdr->dt; if (delta_offs < -0.5*wrap_offs) { sub->offs += wrap_offs; fprintf(stderr, "Warning: detected likely counter wrap, attempting to fix it.\n"); } } fits_get_colnum(pf->fptr, 0, "LST_SUB", &colnum, status); fits_read_col(pf->fptr, TDOUBLE, colnum, row, 1, 1, NULL, &(sub->lst), NULL, status); fits_get_colnum(pf->fptr, 0, "RA_SUB", &colnum, status); fits_read_col(pf->fptr, TDOUBLE, colnum, row, 1, 1, NULL, &(sub->ra), NULL, status); fits_get_colnum(pf->fptr, 0, "DEC_SUB", &colnum, status); fits_read_col(pf->fptr, TDOUBLE, colnum, row, 1, 1, NULL, &(sub->dec), NULL, status); fits_get_colnum(pf->fptr, 0, "GLON_SUB", &colnum, status); fits_read_col(pf->fptr, TDOUBLE, colnum, row, 1, 1, NULL, &(sub->glon), NULL, status); fits_get_colnum(pf->fptr, 0, "GLAT_SUB", &colnum, status); fits_read_col(pf->fptr, TDOUBLE, colnum, row, 1, 1, NULL, &(sub->glat), NULL, status); fits_get_colnum(pf->fptr, 0, "FD_ANG", &colnum, status); fits_read_col(pf->fptr, TDOUBLE, colnum, row, 1, 1, NULL, &(sub->feed_ang), NULL, status); fits_get_colnum(pf->fptr, 0, "POS_ANG", &colnum, status); fits_read_col(pf->fptr, TDOUBLE, colnum, row, 1, 1, NULL, &(sub->pos_ang), NULL, status); fits_get_colnum(pf->fptr, 0, "PAR_ANG", &colnum, status); fits_read_col(pf->fptr, TDOUBLE, colnum, row, 1, 1, NULL, &(sub->par_ang), NULL, status); fits_get_colnum(pf->fptr, 0, "TEL_AZ", &colnum, status); fits_read_col(pf->fptr, TDOUBLE, colnum, row, 1, 1, NULL, &(sub->tel_az), NULL, status); fits_get_colnum(pf->fptr, 0, "TEL_ZEN", &colnum, status); fits_read_col(pf->fptr, TDOUBLE, colnum, row, 1, 1, NULL, &(sub->tel_zen), NULL, status); fits_get_colnum(pf->fptr, 0, "DAT_FREQ", &colnum, status); fits_read_col(pf->fptr, TFLOAT, colnum, row, 1, nchan, NULL, sub->dat_freqs, NULL, status); fits_get_colnum(pf->fptr, 0, "DAT_WTS", &colnum, status); fits_read_col(pf->fptr, TFLOAT, colnum, row, 1, nchan, NULL, sub->dat_weights, NULL, status); fits_get_colnum(pf->fptr, 0, "DAT_OFFS", &colnum, status); fits_read_col(pf->fptr, TFLOAT, colnum, row, 1, nivals, NULL, sub->dat_offsets, NULL, status); fits_get_colnum(pf->fptr, 0, "DAT_SCL", &colnum, status); fits_read_col(pf->fptr, TFLOAT, colnum, row, 1, nivals, NULL, sub->dat_scales, NULL, status); fits_get_colnum(pf->fptr, 0, "DATA", &colnum, status); if (mode==SEARCH_MODE) { if (hdr->nbits==32) fits_read_col(pf->fptr, TFLOAT, colnum, row, 1, sub->bytes_per_subint/4, NULL, sub->rawdata, NULL, status); else fits_read_col(pf->fptr, TBYTE, colnum, row, 1, sub->bytes_per_subint, NULL, sub->rawdata, NULL, status); if (hdr->nbits==4) pf_4bit_to_8bit(pf); } else if (mode==FOLD_MODE) { fits_read_col(pf->fptr, TFLOAT, colnum, row, 1, sub->bytes_per_subint, NULL, sub->data, NULL, status); } // Complain on error fits_report_error(stderr, *status); // Update counters if (!(*status)) { pf->rownum++; pf->tot_rows++; pf->N += hdr->nsblk; pf->T = pf->N * hdr->dt; } return *status; }
int psrfits_write_subint(struct psrfits *pf) { int row, *status, nchan, nivals, mode, out_nbytes, nstat, dummy; float ftmp; struct hdrinfo *hdr; struct subint *sub; hdr = &(pf->hdr); // dereference the ptr to the header struct sub = &(pf->sub); // dereference the ptr to the subint struct status = &(pf->status); // dereference the ptr to the CFITSIO status nchan = hdr->nchan / hdr->ds_freq_fact; nstat = sub->statbytes_per_subint / 2; //stat array is shorts if (hdr->onlyI) nivals = nchan; else nivals = nchan * hdr->npol; mode = psrfits_obs_mode(hdr->obs_mode); if (mode == fold) out_nbytes = sub->bytes_per_subint / hdr->ds_freq_fact; else { out_nbytes = sub->bytes_per_subint / (hdr->ds_freq_fact * hdr->ds_time_fact); if (hdr->onlyI) out_nbytes /= hdr->npol; } // Create the initial file or change to a new one if needed. // Stay with a single file for fold mode. //fprintf(stderr,"In psrfits write, pf->filenum: %d pf->multifile: %d\n",pf->filenum,pf->multifile); //fprintf(stderr,"In psrfits write, pf->rownum %d pf->rows_per_file: %d\n",pf->rownum,pf->rows_per_file); /* if (pf->filenum==0 || ( (mode==search || pf->multifile==1) && pf->rownum > pf->rows_per_file)) { if (pf->filenum) { printf("Closing file '%s'\n", pf->filename); fits_close_file(pf->fptr, status); return *status; } psrfits_create(pf); } */ row = pf->rownum; //fprintf(stderr,"In psrfits write, row: %d\n",row); //fits_read_key(pf->fptr, TINT, "NAXIS2", &dummy, NULL, status); //fprintf(stderr,"In psrfits write, before col writing, NAXIS2: %d status; %d\n",dummy,*status); fprintf(stderr, "tsubint: %f offs_sub: %f\n", sub->tsubint, sub->offs); fits_write_col(pf->fptr, TDOUBLE, 1, row, 1, 1, &(sub->tsubint), status); fits_write_col(pf->fptr, TDOUBLE, 2, row, 1, 1, &(sub->offs), status); fits_write_col(pf->fptr, TDOUBLE, 3, row, 1, 1, &(sub->lst), status); fits_write_col(pf->fptr, TDOUBLE, 4, row, 1, 1, &(sub->ra), status); fits_write_col(pf->fptr, TDOUBLE, 5, row, 1, 1, &(sub->dec), status); fits_write_col(pf->fptr, TDOUBLE, 6, row, 1, 1, &(sub->glon), status); fits_write_col(pf->fptr, TDOUBLE, 7, row, 1, 1, &(sub->glat), status); ftmp = (float) sub->feed_ang; fits_write_col(pf->fptr, TFLOAT, 8, row, 1, 1, &ftmp, status); ftmp = (float) sub->pos_ang; fits_write_col(pf->fptr, TFLOAT, 9, row, 1, 1, &ftmp, status); ftmp = (float) sub->par_ang; fits_write_col(pf->fptr, TFLOAT, 10, row, 1, 1, &ftmp, status); ftmp = (float) sub->tel_az; fits_write_col(pf->fptr, TFLOAT, 11, row, 1, 1, &ftmp, status); ftmp = (float) sub->tel_zen; fits_write_col(pf->fptr, TFLOAT, 12, row, 1, 1, &ftmp, status); fits_write_col(pf->fptr, TFLOAT, 13, row, 1, nchan, sub->dat_freqs, status); fits_write_col(pf->fptr, TFLOAT, 14, row, 1, nchan, sub->dat_weights, status); fits_write_col(pf->fptr, TFLOAT, 15, row, 1, nivals, sub->dat_offsets, status); fits_write_col(pf->fptr, TFLOAT, 16, row, 1, nivals, sub->dat_scales, status); if (mode == search) { // Need to change this for other data types... //fprintf(stderr,"In psrfits write, out_nbytes (data bytes per subint): %d\n",out_nbytes); fits_write_col(pf->fptr, TBYTE, 17, row, 1, out_nbytes, sub->data, status); } else if (mode == fold) { // Fold mode writes floats for now.. fits_write_col(pf->fptr, TFLOAT, 17, row, 1, out_nbytes / sizeof(float), sub->data, status); } /* fprintf(stderr,"In psrfits write, out_nbytes: %d, nchan: %d nivals: %d nstat: %d status: %d\n",out_nbytes,nchan,nivals,nstat,*status); fits_flush_file(pf->fptr, status); fits_read_key(pf->fptr, TINT, "NAXIS2", &dummy, NULL, status); fprintf(stderr,"In psrfits write after 17 column, NAXIS2: %d status; %d\n",dummy,*status); */ fits_write_col(pf->fptr, TSHORT, 18, row, 1, nstat, sub->stat, status); // Flush the buffers if not finished with the file // Note: this use is not entirely in keeping with the CFITSIO // documentation recommendations. However, manually // correcting NAXIS2 and using fits_flush_buffer() // caused occasional hangs (and extrememly large // files due to some infinite loop). fits_flush_file(pf->fptr, status); //NOTE: using flush_file resulted in an extra row for some reason //fits_flush_buffer(pf->fptr,0,status); //fits_read_key(pf->fptr, TINT, "NAXIS2", &dummy, NULL, status); //fprintf(stderr,"In psrfits write, after fits flush, NAXIS2: %d status; %d\n",dummy,*status); // Print status if bad if (*status) { fprintf(stderr, "Error writing subint %d:\n", pf->rownum); fits_report_error(stderr, *status); fflush(stderr); } // Now update some key values if no CFITSIO errors if (!(*status)) { pf->rownum++; pf->tot_rows++; pf->N += hdr->nsblk / hdr->ds_time_fact; pf->T += sub->tsubint; // For fold mode, print info each subint written if (mode == fold && pf->quiet != 1) { printf("Wrote subint %d (total time %.1fs)\n", pf->rownum - 1, pf->T); fflush(stdout); } } //fits_update_key(pf->fptr,TINT,"NAXIS2",&(pf->tot_rows),NULL,status); return *status; }
/*********************************************************************************** * psrfits_subint(struct *psrfits *pf,int first) * first: if true then first call, we need to read all the keys in the subint row. * after the first we just read the data and the status. * * Read next subint from the set of files described * by the psrfits struct. It is assumed that all files * form a consistent set. Read automatically goes to the * next file when one ends. Arrays should be allocated * outside this routine. */ int psrfits_read_subint(struct psrfits *pf, int first) { struct hdrinfo *hdr = &(pf->hdr); struct subint *sub = &(pf->sub); int *status = &(pf->status); // See if we need to move to next file /* if (pf->rownum > pf->rows_per_file) { fits_close_file(pf->fptr, status); fprintf(stderr,"Closed file '%s'\n", pf->filename); pf->filenum++; if (psrfits_open(pf) != 0) { return *status; } } */ if (pf->rownum > pf->rows_per_file) return 1; int mode = psrfits_obs_mode(hdr->obs_mode); // match the args for the cfitsio params LONGLONG nchan = hdr->nchan; LONGLONG nivals = hdr->nchan * hdr->npol; LONGLONG row = pf->rownum; LONGLONG firstE = 1; // first element of row LONGLONG oneE = 1; // one element in row SUBINT_COLS *pcol; pcol = &pf->subcols; //Need to read all columns at every subint in order to copy the fields to //converted psrfits data output // if (first) { // modified to use column names. pjp 10jan09 fits_read_col(pf->fptr, TDOUBLE, pcol->tsubint, row, firstE, oneE, NULL, &(sub->tsubint), NULL, status); fits_read_col(pf->fptr, TDOUBLE, pcol->offs_sub, row, firstE, oneE, NULL, &(sub->offs), NULL, status); fits_read_col(pf->fptr, TDOUBLE, pcol->lst_sub, row, firstE, oneE, NULL, &(sub->lst), NULL, status); fits_read_col(pf->fptr, TDOUBLE, pcol->ra_sub, row, firstE, oneE, NULL, &(sub->ra), NULL, status); fits_read_col(pf->fptr, TDOUBLE, pcol->dec_sub, row, firstE, oneE, NULL, &(sub->dec), NULL, status); fits_read_col(pf->fptr, TDOUBLE, pcol->glon_sub, row, firstE, oneE, NULL, &(sub->glon), NULL, status); fits_read_col(pf->fptr, TDOUBLE, pcol->glat_sub, row, firstE, oneE, NULL, &(sub->glat), NULL, status); fits_read_col(pf->fptr, TDOUBLE, pcol->fd_ang, row, firstE, oneE, NULL, &(sub->feed_ang), NULL, status); fits_read_col(pf->fptr, TDOUBLE, pcol->pos_ang, row, firstE, oneE, NULL, &(sub->pos_ang), NULL, status); fits_read_col(pf->fptr, TDOUBLE, pcol->par_ang, row, firstE, oneE, NULL, &(sub->par_ang), NULL, status); fits_read_col(pf->fptr, TDOUBLE, pcol->tel_az, row, firstE, oneE, NULL, &(sub->tel_az), NULL, status); fits_read_col(pf->fptr, TDOUBLE, pcol->tel_zen, row, firstE, oneE, NULL, &(sub->tel_zen), NULL, status); fits_read_col(pf->fptr, TFLOAT, pcol->dat_freq, row, firstE, nchan, NULL, sub->dat_freqs, NULL, status); fits_read_col(pf->fptr, TFLOAT, pcol->dat_wts, row, firstE, nchan, NULL, sub->dat_weights, NULL, status); fits_read_col(pf->fptr, TFLOAT, pcol->dat_offs, row, firstE, nivals, NULL, sub->dat_offsets, NULL, status); fits_read_col(pf->fptr, TFLOAT, pcol->dat_scl, row, firstE, nivals, NULL, sub->dat_scales, NULL, status); // } if (mode == SEARCH_MODE) { switch (sub->typecode) { case TBYTE: fits_read_col(pf->fptr, sub->typecode, pcol->data, row, firstE, (LONGLONG) (sub->bytes_per_subint) / sub->bytesPerDatum, NULL, sub->data, NULL, status); break; case TSHORT: fits_read_col(pf->fptr, sub->typecode, pcol->data, row, firstE, (LONGLONG) (sub->bytes_per_subint) / sub->bytesPerDatum, NULL, (short *) sub->data, NULL, status); break; case TINT: fits_read_col(pf->fptr, sub->typecode, pcol->data, row, firstE, (LONGLONG) (sub->bytes_per_subint) / sub->bytesPerDatum, NULL, (int *) sub->data, NULL, status); break; case TFLOAT: fits_read_col(pf->fptr, sub->typecode, pcol->data, row, firstE, (LONGLONG) (sub->bytes_per_subint) / sub->bytesPerDatum, NULL, (float *) sub->data, NULL, status); break; case TDOUBLE: fits_read_col(pf->fptr, sub->typecode, pcol->data, row, firstE, (LONGLONG) (sub->bytes_per_subint) / sub->bytesPerDatum, NULL, (double *) sub->data, NULL, status); break; default: fprintf(stderr, "psrfits_read_subint:unsupported datatype code:%d\n", sub->typecode); fprintf(stderr, "Currently supported:TBYTE=11,TSHORT=21,TINT=31,TFLOAT=32,TDOUBLE=82\n"); fprintf(stderr, "..see fitsio.h include file for the definitions\n"); exit(-1); break; } fits_read_col(pf->fptr, TSHORT, pcol->stat, row, firstE, (LONGLONG) (sub->statbytes_per_subint) / sizeof(short), NULL, sub->stat, NULL, status); } else if (mode == FOLD_MODE) { fits_read_col(pf->fptr, sub->typecode, pcol->data, row, firstE, (LONGLONG) (sub->bytes_per_subint) / sub->bytesPerDatum, NULL, sub->data, NULL, status); } // Complain on error fits_report_error(stderr, *status); // Update counters if (!(*status)) { pf->rownum++; pf->tot_rows++; pf->N += hdr->nsblk; pf->T = pf->N * hdr->dt; } return *status; }
/* This function is similar to psrfits_create, except it * deals with reading existing files. It is assumed that * basename and filenum are filled in correctly to point to * the first file in the set. */ int psrfits_open(struct psrfits *pf, int iomode) { int itmp; double dtmp; char ctmp[256]; struct hdrinfo *hdr = &(pf->hdr); struct subint *sub = &(pf->sub); int *status = &(pf->status); sprintf(pf->filename, "%s%0*d.fits", pf->basefilename, pf->fnamedigits, pf->filenum); //fprintf(stderr,"%s\n",pf->filename); fits_open_file(&(pf->fptr), pf->filename, iomode, status); // If file does not exist, exit now if (*status) { return *status; } fprintf(stderr, "Opened file '%s'\n", pf->filename); // Move to main HDU fits_movabs_hdu(pf->fptr, 1, NULL, status); // Figure out obs mode fits_read_key(pf->fptr, TSTRING, "OBS_MODE", hdr->obs_mode, NULL, status); int mode = psrfits_obs_mode(hdr->obs_mode); // Read some stuff fits_read_key(pf->fptr, TSTRING, "TELESCOP", hdr->telescope, NULL, status); fits_read_key(pf->fptr, TSTRING, "OBSERVER", hdr->observer, NULL, status); fits_read_key(pf->fptr, TSTRING, "PROJID", hdr->project_id, NULL, status); fits_read_key(pf->fptr, TSTRING, "FRONTEND", hdr->frontend, NULL, status); fits_read_key(pf->fptr, TSTRING, "BACKEND", hdr->backend, NULL, status); fits_read_key(pf->fptr, TSTRING, "FD_POLN", hdr->poln_type, NULL, status); fits_read_key(pf->fptr, TSTRING, "DATE-OBS", hdr->date_obs, NULL, status); fits_read_key(pf->fptr, TDOUBLE, "OBSFREQ", &(hdr->fctr), NULL, status); fits_read_key(pf->fptr, TDOUBLE, "OBSBW", &(hdr->BW), NULL, status); fits_read_key(pf->fptr, TINT, "OBSNCHAN", &(hdr->orig_nchan), NULL, status); fits_read_key(pf->fptr, TSTRING, "SRC_NAME", hdr->source, NULL, status); fits_read_key(pf->fptr, TSTRING, "TRK_MODE", hdr->track_mode, NULL, status); // TODO warn if not TRACK? fits_read_key(pf->fptr, TSTRING, "RA", hdr->ra_str, NULL, status); fits_read_key(pf->fptr, TSTRING, "DEC", hdr->dec_str, NULL, status); fits_read_key(pf->fptr, TDOUBLE, "BMAJ", &(hdr->beam_FWHM), NULL, status); fits_read_key(pf->fptr, TSTRING, "CAL_MODE", hdr->cal_mode, NULL, status); fits_read_key(pf->fptr, TDOUBLE, "CAL_FREQ", &(hdr->cal_freq), NULL, status); fits_read_key(pf->fptr, TDOUBLE, "CAL_DCYC", &(hdr->cal_dcyc), NULL, status); fits_read_key(pf->fptr, TDOUBLE, "CAL_PHS", &(hdr->cal_phs), NULL, status); fits_read_key(pf->fptr, TSTRING, "FD_MODE", hdr->feed_mode, NULL, status); fits_read_key(pf->fptr, TDOUBLE, "FA_REQ", &(hdr->feed_angle), NULL, status); fits_read_key(pf->fptr, TDOUBLE, "SCANLEN", &(hdr->scanlen), NULL, status); fits_read_key(pf->fptr, TINT, "STT_IMJD", &itmp, NULL, status); hdr->MJD_epoch = (long double) itmp; fits_read_key(pf->fptr, TDOUBLE, "STT_SMJD", &dtmp, NULL, status); hdr->MJD_epoch += dtmp / 86400.0L; fits_read_key(pf->fptr, TDOUBLE, "STT_OFFS", &dtmp, NULL, status); hdr->MJD_epoch += dtmp / 86400.0L; fits_read_key(pf->fptr, TDOUBLE, "STT_LST", &(hdr->start_lst), NULL, status); // Move to pdev bintab to see if blanking enabled // int blankSel, adcThr; fits_movnam_hdu(pf->fptr, BINARY_TBL, "PDEV", 0, status); fits_read_key(pf->fptr, TINT, "PHBLKSEL", &(blankSel), NULL, status); fits_read_key(pf->fptr, TINT, "PHADCTHR", &(adcThr), NULL, status); fits_read_key(pf->fptr, TINT, "PHFFTACC", &(hdr->fftAccum), NULL, status); hdr->blankingOn = (blankSel != 15) || (adcThr != 65535); // Move to first subint fits_movnam_hdu(pf->fptr, BINARY_TBL, "SUBINT", 0, status); // Read some more stuff fits_read_key(pf->fptr, TINT, "NPOL", &(hdr->npol), NULL, status); fits_read_key(pf->fptr, TSTRING, "POL_TYPE", ctmp, NULL, status); if (strncmp(ctmp, "AA+BB", 6) == 0) hdr->summed_polns = 1; else hdr->summed_polns = 0; fits_read_key(pf->fptr, TDOUBLE, "TBIN", &(hdr->dt), NULL, status); fits_read_key(pf->fptr, TINT, "NBIN", &(hdr->nbin), NULL, status); fits_read_key(pf->fptr, TINT, "NSUBOFFS", &(hdr->offset_subint), NULL, status); fits_read_key(pf->fptr, TINT, "NCHAN", &(hdr->nchan), NULL, status); fits_read_key(pf->fptr, TDOUBLE, "CHAN_BW", &(hdr->df), NULL, status); fits_read_key(pf->fptr, TINT, "NSBLK", &(hdr->nsblk), NULL, status); fits_read_key(pf->fptr, TINT, "NBITS", &(hdr->nbits), NULL, status); if (mode == SEARCH_MODE) { sub->bytes_per_subint = (hdr->nbits * hdr->nchan * hdr->npol * hdr->nsblk) / 8; sub->statbytes_per_subint = hdr->nsblk * AO_NUM_SH_STAT_1DMP * sizeof(short); } else if (mode == FOLD_MODE) { sub->bytes_per_subint = (hdr->nbin * hdr->nchan * hdr->npol) * hdr->nbits / 8; //XXX data type?? } // to tell us the end of the good data in file. pf->hdr.numBlksTot = (pf->hdr.scanlen / pf->hdr.dt + .5); // Init counters pf->rownum = 1; fits_read_key(pf->fptr, TINT, "NAXIS2", &(pf->rows_per_file), NULL, status); if (!pf->initialized) { fits_get_colnum(pf->fptr, 1, "TSUBINT", &pf->subcols.tsubint, status); fits_get_colnum(pf->fptr, 1, "OFFS_SUB", &pf->subcols.offs_sub, status); fits_get_colnum(pf->fptr, 1, "LST_SUB", &pf->subcols.lst_sub, status); fits_get_colnum(pf->fptr, 1, "RA_SUB", &pf->subcols.ra_sub, status); fits_get_colnum(pf->fptr, 1, "DEC_SUB", &pf->subcols.dec_sub, status); fits_get_colnum(pf->fptr, 1, "GLON_SUB", &pf->subcols.glon_sub, status); fits_get_colnum(pf->fptr, 1, "GLAT_SUB", &pf->subcols.glat_sub, status); fits_get_colnum(pf->fptr, 1, "FD_ANG", &pf->subcols.fd_ang, status); fits_get_colnum(pf->fptr, 1, "POS_ANG", &pf->subcols.pos_ang, status); fits_get_colnum(pf->fptr, 1, "PAR_ANG", &pf->subcols.par_ang, status); fits_get_colnum(pf->fptr, 1, "TEL_AZ", &pf->subcols.tel_az, status); fits_get_colnum(pf->fptr, 1, "TEL_ZEN", &pf->subcols.tel_zen, status); fits_get_colnum(pf->fptr, 1, "DAT_FREQ", &pf->subcols.dat_freq, status); fits_get_colnum(pf->fptr, 1, "DAT_WTS", &pf->subcols.dat_wts, status); fits_get_colnum(pf->fptr, 1, "DAT_OFFS", &pf->subcols.dat_offs, status); fits_get_colnum(pf->fptr, 1, "DAT_SCL", &pf->subcols.dat_scl, status); fits_get_colnum(pf->fptr, 1, "DATA", &pf->subcols.data, status); fits_get_colnum(pf->fptr, 1, "STAT", &pf->subcols.stat, status); long repeat; long width; fits_get_coltype(pf->fptr, pf->subcols.data, &sub->typecode, &repeat, &width, status); sub->bytesPerDatum = width; if (sub->typecode == TINT32BIT) sub->typecode = TINT; sub->data = malloc(sizeof(char) * sub->bytes_per_subint); sub->dataBytesAlloced = sub->bytes_per_subint; sub->stat = (unsigned short *) malloc(sub->statbytes_per_subint); pf->initialized = 1; } return *status; }