void read_PSRFITS_files(struct spectra_info *s) // Read and convert PSRFITS information from a group of files // and place the resulting info into a spectra_info structure. { int IMJD, SMJD, itmp, ii, status = 0; double OFFS, dtmp; long double MJDf; char ctmp[80], comment[120]; s->datatype = PSRFITS; s->fitsfiles = (fitsfile **)malloc(sizeof(fitsfile *) * s->num_files); s->start_subint = gen_ivect(s->num_files); s->num_subint = gen_ivect(s->num_files); s->start_spec = (long long *)malloc(sizeof(long long) * s->num_files); s->num_spec = (long long *)malloc(sizeof(long long) * s->num_files); s->num_pad = (long long *)malloc(sizeof(long long) * s->num_files); s->start_MJD = (long double *)malloc(sizeof(long double) * s->num_files); s->N = 0; s->num_beams = 1; s->get_rawblock = &get_PSRFITS_rawblock; s->offset_to_spectra = &offset_to_PSRFITS_spectra; // By default, don't flip the band. But don't change // the input value if it is aleady set to flip the band always if (s->apply_flipband==-1) s->apply_flipband = 0; // Step through the other files for (ii = 0 ; ii < s->num_files ; ii++) { // Is the file a PSRFITS file? if (!is_PSRFITS(s->filenames[ii])) { fprintf(stderr, "\nError! File '%s' does not appear to be PSRFITS!\n", s->filenames[ii]); exit(1); } // Open the PSRFITS file fits_open_file(&(s->fitsfiles[ii]), s->filenames[ii], READONLY, &status); // Is the data in search mode? fits_read_key(s->fitsfiles[ii], TSTRING, "OBS_MODE", ctmp, comment, &status); // Quick fix for Parkes DFB data (SRCH? why????)... if (strcmp("SRCH", ctmp)==0) { strncpy(ctmp, "SEARCH", 40); } if (strcmp(ctmp, "SEARCH")) { fprintf(stderr, "\nError! File '%s' does not contain SEARCH-mode data!\n", s->filenames[ii]); exit(1); } // Now get the stuff we need from the primary HDU header fits_read_key(s->fitsfiles[ii], TSTRING, "TELESCOP", ctmp, comment, &status); \ // Quick fix for MockSpec data... if (strcmp("ARECIBO 305m", ctmp)==0) { strncpy(ctmp, "Arecibo", 40); } // Quick fix for Parkes DFB data... { char newctmp[80]; // Copy ctmp first since strlower() is in-place strcpy(newctmp, ctmp); if (strcmp("parkes", strlower(remove_whitespace(newctmp)))==0) { strncpy(ctmp, "Parkes", 40); } } if (status) { printf("Error %d reading key %s\n", status, "TELESCOP"); if (ii==0) s->telescope[0]='\0'; if (status==KEY_NO_EXIST) status=0; } else { if (ii==0) strncpy(s->telescope, ctmp, 40); else if (strcmp(s->telescope, ctmp)!=0) printf("Warning!: %s values don't match for files 0 and %d!\n", "TELESCOP", ii); } get_hdr_string("OBSERVER", s->observer); get_hdr_string("SRC_NAME", s->source); get_hdr_string("FRONTEND", s->frontend); get_hdr_string("BACKEND", s->backend); get_hdr_string("PROJID", s->project_id); get_hdr_string("DATE-OBS", s->date_obs); get_hdr_string("FD_POLN", s->poln_type); get_hdr_string("RA", s->ra_str); get_hdr_string("DEC", s->dec_str); get_hdr_double("OBSFREQ", s->fctr); get_hdr_int("OBSNCHAN", s->orig_num_chan); get_hdr_double("OBSBW", s->orig_df); //get_hdr_double("CHAN_DM", s->chan_dm); get_hdr_double("BMIN", s->beam_FWHM); /* This is likely not in earlier versions of PSRFITS so */ /* treat it a bit differently */ fits_read_key(s->fitsfiles[ii], TDOUBLE, "CHAN_DM", &(s->chan_dm), comment, &status); if (status==KEY_NO_EXIST) { status = 0; s->chan_dm = 0.0; } // Don't use the macros unless you are using the struct! fits_read_key(s->fitsfiles[ii], TINT, "STT_IMJD", &IMJD, comment, &status); s->start_MJD[ii] = (long double) IMJD; fits_read_key(s->fitsfiles[ii], TINT, "STT_SMJD", &SMJD, comment, &status); fits_read_key(s->fitsfiles[ii], TDOUBLE, "STT_OFFS", &OFFS, comment, &status); s->start_MJD[ii] += ((long double) SMJD + (long double) OFFS) / SECPERDAY; // Are we tracking? fits_read_key(s->fitsfiles[ii], TSTRING, "TRK_MODE", ctmp, comment, &status); itmp = (strcmp("TRACK", ctmp)==0) ? 1 : 0; if (ii==0) s->tracking = itmp; else if (s->tracking != itmp) printf("Warning!: TRK_MODE values don't match for files 0 and %d!\n", ii); // Now switch to the SUBINT HDU header fits_movnam_hdu(s->fitsfiles[ii], BINARY_TBL, "SUBINT", 0, &status); get_hdr_double("TBIN", s->dt); get_hdr_int("NCHAN", s->num_channels); get_hdr_int("NPOL", s->num_polns); get_hdr_string("POL_TYPE", s->poln_order); fits_read_key(s->fitsfiles[ii], TINT, "NCHNOFFS", &itmp, comment, &status); if (itmp > 0) printf("Warning!: First freq channel is not 0 in file %d!\n", ii); get_hdr_int("NSBLK", s->spectra_per_subint); get_hdr_int("NBITS", s->bits_per_sample); fits_read_key(s->fitsfiles[ii], TINT, "NAXIS2", &(s->num_subint[ii]), comment, &status); fits_read_key(s->fitsfiles[ii], TINT, "NSUBOFFS", &(s->start_subint[ii]), comment, &status); s->time_per_subint = s->dt * s->spectra_per_subint; /* This is likely not in earlier versions of PSRFITS so */ /* treat it a bit differently */ fits_read_key(s->fitsfiles[ii], TFLOAT, "ZERO_OFF", &(s->zero_offset), comment, &status); if (status==KEY_NO_EXIST) { status = 0; s->zero_offset = 0.0; } s->zero_offset = fabs(s->zero_offset); // Get the time offset column info and the offset for the 1st row { double offs_sub; int colnum, anynull, numrows; // Identify the OFFS_SUB column number fits_get_colnum(s->fitsfiles[ii], 0, "OFFS_SUB", &colnum, &status); if (status==COL_NOT_FOUND) { printf("Warning!: Can't find the OFFS_SUB column!\n"); status = 0; // Reset status } else { if (ii==0) { s->offs_sub_col = colnum; } else if (colnum != s->offs_sub_col) { printf("Warning!: OFFS_SUB column changes between files!\n"); } } // Read the OFFS_SUB column value for the 1st row fits_read_col(s->fitsfiles[ii], TDOUBLE, s->offs_sub_col, 1L, 1L, 1L, 0, &offs_sub, &anynull, &status); numrows = (int)((offs_sub - 0.5 * s->time_per_subint) / s->time_per_subint + 1e-7); // Check to see if any rows have been deleted or are missing if (numrows > s->start_subint[ii]) { printf("Warning: NSUBOFFS reports %d previous rows\n" " but OFFS_SUB implies %d. Using OFFS_SUB.\n" " Will likely be able to correct for this.\n", s->start_subint[ii], numrows); } s->start_subint[ii] = numrows; } // This is the MJD offset based on the starting subint number MJDf = (s->time_per_subint * s->start_subint[ii]) / SECPERDAY; // The start_MJD values should always be correct s->start_MJD[ii] += MJDf; // Compute the starting spectra from the times MJDf = s->start_MJD[ii] - s->start_MJD[0]; if (MJDf < 0.0) { fprintf(stderr, "Error!: File %d seems to be from before file 0!\n", ii); exit(1); } s->start_spec[ii] = (long long)(MJDf * SECPERDAY / s->dt + 0.5); // Now pull stuff from the other columns { float ftmp; long repeat, width; int colnum, anynull; // Identify the data column and the data type fits_get_colnum(s->fitsfiles[ii], 0, "DATA", &colnum, &status); if (status==COL_NOT_FOUND) { printf("Warning!: Can't find the DATA column!\n"); status = 0; // Reset status } else { if (ii==0) { s->data_col = colnum; fits_get_coltype(s->fitsfiles[ii], colnum, &(s->FITS_typecode), &repeat, &width, &status); } else if (colnum != s->data_col) { printf("Warning!: DATA column changes between files!\n"); } } // Telescope azimuth fits_get_colnum(s->fitsfiles[ii], 0, "TEL_AZ", &colnum, &status); if (status==COL_NOT_FOUND) { s->azimuth = 0.0; status = 0; // Reset status } else { fits_read_col(s->fitsfiles[ii], TFLOAT, colnum, 1L, 1L, 1L, 0, &ftmp, &anynull, &status); if (ii==0) s->azimuth = (double) ftmp; } // Telescope zenith angle fits_get_colnum(s->fitsfiles[ii], 0, "TEL_ZEN", &colnum, &status); if (status==COL_NOT_FOUND) { s->zenith_ang = 0.0; status = 0; // Reset status } else { fits_read_col(s->fitsfiles[ii], TFLOAT, colnum, 1L, 1L, 1L, 0, &ftmp, &anynull, &status); if (ii==0) s->zenith_ang = (double) ftmp; } // Observing frequencies fits_get_colnum(s->fitsfiles[ii], 0, "DAT_FREQ", &colnum, &status); if (status==COL_NOT_FOUND) { printf("Warning!: Can't find the channel freq column!\n"); status = 0; // Reset status } else { int jj; float *freqs = (float *)malloc(sizeof(float) * s->num_channels); fits_read_col(s->fitsfiles[ii], TFLOAT, colnum, 1L, 1L, s->num_channels, 0, freqs, &anynull, &status); if (ii==0) { s->df = freqs[1]-freqs[0]; s->lo_freq = freqs[0]; s->hi_freq = freqs[s->num_channels-1]; // Now check that the channel spacing is the same throughout for (jj = 0 ; jj < s->num_channels - 1 ; jj++) { ftmp = freqs[jj+1] - freqs[jj]; if (fabs(ftmp - s->df) > 1e-7) printf("Warning!: Channel spacing changes in file %d!\n", ii); } } else { ftmp = fabs(s->df-(freqs[1]-freqs[0])); if (ftmp > 1e-7) printf("Warning!: Channel spacing changes between files!\n"); ftmp = fabs(s->lo_freq-freqs[0]); if (ftmp > 1e-7) printf("Warning!: Low channel changes between files!\n"); ftmp = fabs(s->hi_freq-freqs[s->num_channels-1]); if (ftmp > 1e-7) printf("Warning!: High channel changes between files!\n"); } free(freqs); } // Data weights fits_get_colnum(s->fitsfiles[ii], 0, "DAT_WTS", &colnum, &status); if (status==COL_NOT_FOUND) { printf("Warning!: Can't find the channel weights!\n"); status = 0; // Reset status } else { if (s->apply_weight < 0) { // Use the data to decide int jj; if (ii==0) { s->dat_wts_col = colnum; } else if (colnum != s->dat_wts_col) { printf("Warning!: DAT_WTS column changes between files!\n"); } float *fvec = (float *)malloc(sizeof(float) * s->num_channels); fits_read_col(s->fitsfiles[ii], TFLOAT, s->dat_wts_col, 1L, 1L, s->num_channels, 0, fvec, &anynull, &status); for (jj = 0 ; jj < s->num_channels ; jj++) { // If the weights are not 1, apply them if (fvec[jj] != 1.0) { s->apply_weight = 1; break; } } free(fvec); } if (s->apply_weight < 0) s->apply_weight = 0; // not needed } // Data offsets fits_get_colnum(s->fitsfiles[ii], 0, "DAT_OFFS", &colnum, &status); if (status==COL_NOT_FOUND) { printf("Warning!: Can't find the channel offsets!\n"); status = 0; // Reset status } else { if (s->apply_offset < 0) { // Use the data to decide int jj; if (ii==0) { s->dat_offs_col = colnum; } else if (colnum != s->dat_offs_col) { printf("Warning!: DAT_OFFS column changes between files!\n"); } float *fvec = (float *)malloc(sizeof(float) * s->num_channels * s->num_polns); fits_read_col(s->fitsfiles[ii], TFLOAT, s->dat_offs_col, 1L, 1L, s->num_channels * s->num_polns, 0, fvec, &anynull, &status); for (jj = 0 ; jj < s->num_channels * s->num_polns ; jj++) { // If the offsets are not 0, apply them if (fvec[jj] != 0.0) { s->apply_offset = 1; break; } } free(fvec); } if (s->apply_offset < 0) s->apply_offset = 0; // not needed } // Data scalings fits_get_colnum(s->fitsfiles[ii], 0, "DAT_SCL", &colnum, &status); if (status==COL_NOT_FOUND) { printf("Warning!: Can't find the channel scalings!\n"); status = 0; // Reset status } else { if (s->apply_scale < 0) { // Use the data to decide int jj; if (ii==0) { s->dat_scl_col = colnum; } else if (colnum != s->dat_scl_col) { printf("Warning!: DAT_SCL column changes between files!\n"); } float *fvec = (float *)malloc(sizeof(float) * s->num_channels * s->num_polns); fits_read_col(s->fitsfiles[ii], TFLOAT, colnum, 1L, 1L, s->num_channels * s->num_polns, 0, fvec, &anynull, &status); for (jj = 0 ; jj < s->num_channels * s->num_polns ; jj++) { // If the scales are not 1, apply them if (fvec[jj] != 1.0) { s->apply_scale = 1; break; } } free(fvec); } if (s->apply_scale < 0) s->apply_scale = 0; // not needed } } // Compute the samples per file and the amount of padding // that the _previous_ file has s->num_pad[ii] = 0; s->num_spec[ii] = s->spectra_per_subint * s->num_subint[ii]; if (ii > 0) { if (s->start_spec[ii] > s->N) { // Need padding s->num_pad[ii-1] = s->start_spec[ii] - s->N; s->N += s->num_pad[ii-1]; } } s->N += s->num_spec[ii]; } // Convert the position strings into degrees { int d, h, m; double sec; ra_dec_from_string(s->ra_str, &h, &m, &sec); s->ra2000 = hms2rad(h, m, sec) * RADTODEG; ra_dec_from_string(s->dec_str, &d, &m, &sec); s->dec2000 = dms2rad(d, m, sec) * RADTODEG; } // Are the polarizations summed? if ((strncmp("AA+BB", s->poln_order, 5)==0) || (strncmp("INTEN", s->poln_order, 5)==0)) s->summed_polns = 1; else s->summed_polns = 0; // Calculate some others s->T = s->N * s->dt; s->orig_df /= (double) s->orig_num_chan; s->samples_per_spectra = s->num_polns * s->num_channels; // Note: the following is the number of bytes that will be in // the returned array from CFITSIO. // CFITSIO turns bits into bytes when FITS_typecode=1 // and we turn 2-bits or 4-bits into bytes if bits_per_sample < 8 if (s->bits_per_sample < 8) s->bytes_per_spectra = s->samples_per_spectra; else s->bytes_per_spectra = (s->bits_per_sample * s->samples_per_spectra) / 8; s->samples_per_subint = s->samples_per_spectra * s->spectra_per_subint; s->bytes_per_subint = s->bytes_per_spectra * s->spectra_per_subint; // Flip the band? if (s->hi_freq < s->lo_freq) { float ftmp = s->hi_freq; s->hi_freq = s->lo_freq; s->lo_freq = ftmp; s->df *= -1.0; s->apply_flipband = 1; } // Compute the bandwidth s->BW = s->num_channels * s->df; // Flip the bytes for Parkes FB_1BIT data if (s->bits_per_sample==1 && strcmp(s->telescope, "Parkes")==0 && strcmp(s->backend, "FB_1BIT")==0) { printf("Flipping bit ordering since Parkes FB_1BIT data.\n"); s->flip_bytes = 1; } else { s->flip_bytes = 0; } // Allocate the buffers cdatabuffer = gen_bvect(s->bytes_per_subint); // Following is twice as big because we use it as a ringbuffer too fdatabuffer = gen_fvect(2 * s->spectra_per_subint * s->num_channels); s->padvals = gen_fvect(s->num_channels); for (ii = 0 ; ii < s->num_channels ; ii++) s->padvals[ii] = 0.0; offsets = gen_fvect(s->num_channels * s->num_polns); scales = gen_fvect(s->num_channels * s->num_polns); weights = gen_fvect(s->num_channels); // Initialize these if we won't be reading them from the file if (s->apply_offset==0) for (ii = 0 ; ii < s->num_channels * s->num_polns ; ii++) offsets[ii] = 0.0; if (s->apply_scale==0) for (ii = 0 ; ii < s->num_channels * s->num_polns ; ii++) scales[ii] = 1.0; if (s->apply_weight==0) for (ii = 0 ; ii < s->num_channels ; ii++) weights[ii] = 1.0; }
void fill_psrfits_struct(int numwapps, int numbits, struct HEADERP *h, struct wappinfo *w, struct psrfits *pf) { int slen, ii; char *cptr; pf->filenum = 0; // Crucial for initialization pf->hdr.nsblk = (int) (1.0 / w->dt); // _might_ be a problem... // Now set values for our hdrinfo structure strcpy(pf->hdr.telescope, "Arecibo"); cptr = get_hdr_string(h, "obs_type", &slen); if (strncmp("PULSAR_SEARCH", cptr, slen) == 0) { strcpy(pf->hdr.obs_mode, "SEARCH"); } else { printf("Error: Wapp data is not in search format!\n\n"); exit(1); } strcpy(pf->hdr.backend, "WAPP"); cptr = get_hdr_string(h, "frontend", &slen); if(cptr != NULL) strncpy(pf->hdr.frontend, cptr, slen); else strncpy(pf->hdr.frontend, "alfa", 4); cptr = get_hdr_string(h, "observers", &slen); strncpy(pf->hdr.observer, cptr, slen); cptr = get_hdr_string(h, "project_id", &slen); strncpy(pf->hdr.project_id, cptr, slen); cptr = get_hdr_string(h, "src_name", &slen); strncpy(pf->hdr.source, cptr, slen); strcpy(pf->hdr.date_obs, w->date_obs); pf->hdr.scanlen = get_hdr_double(h, "obs_time"); strcpy(pf->hdr.poln_type, "LIN"); // set based on known receivers if (get_hdr_int(h, "sum")) { strcpy(pf->hdr.poln_order, "AA+BB"); pf->hdr.summed_polns = 1; } else if (w->numifs == 1) { strcpy(pf->hdr.poln_order, "AA"); pf->hdr.summed_polns = 0; } strcpy(pf->hdr.track_mode, "TRACK"); // Potentially not-true? strcpy(pf->hdr.cal_mode, "OFF"); // Potentially not-true? strcpy(pf->hdr.feed_mode, "FA"); // check this... pf->hdr.beamnum = 0; if (get_hdr_int(h, "isalfa")) pf->hdr.beamnum = w->beamnum; pf->hdr.dt = w->dt; pf->hdr.fctr = w->fctr + 0.5 * (numwapps - 1.0) * w->BW; pf->hdr.BW = w->BW * numwapps; pf->hdr.beam_FWHM = beam_FWHM(pf->hdr.fctr, 300.0); pf->hdr.nchan = w->numchans * numwapps; pf->hdr.orig_nchan = w->numchans * numwapps; pf->hdr.orig_df = pf->hdr.df = pf->hdr.BW / pf->hdr.nchan; pf->hdr.nbits = numbits; pf->hdr.npol = w->numifs; pf->hdr.MJD_epoch = w->MJD_epoch; pf->hdr.start_day = (int) (w->MJD_epoch); pf->hdr.start_sec = (w->MJD_epoch - pf->hdr.start_day) * 86400.0; pf->hdr.scan_number = get_hdr_int(h, "scan_number"); pf->hdr.ra2000 = w->ra; dec2hms(pf->hdr.ra_str, pf->hdr.ra2000 / 15.0, 0); pf->hdr.dec2000 = w->dec; dec2hms(pf->hdr.dec_str, pf->hdr.dec2000, 1); pf->hdr.azimuth = get_hdr_double(h, "start_az"); pf->hdr.zenith_ang = get_hdr_double(h, "start_za"); pf->hdr.rcvr_polns = 2; pf->hdr.offset_subint = 0; pf->hdr.onlyI = 0; pf->hdr.ds_time_fact = 1; pf->hdr.ds_freq_fact = 1; pf->hdr.chan_dm = 0.0; pf->hdr.fd_hand = pf->hdr.be_phase = 0; // This is almost certainly not correct pf->hdr.fd_sang = pf->hdr.fd_xyph = 0.0; // This is almost certainly not correct pf->hdr.feed_angle = 0.0; // This is almost certainly not correct pf->hdr.cal_freq = pf->hdr.cal_dcyc = pf->hdr.cal_phs = 0.0; // ditto // Now set values for our subint structure pf->sub.tel_az = get_hdr_double(h, "start_az"); pf->sub.tel_zen = get_hdr_double(h, "start_za"); pf->sub.lst = get_hdr_double(h, "start_lst"); pf->hdr.start_lst = pf->sub.lst; pf->sub.tsubint = pf->hdr.nsblk * pf->hdr.dt; pf->sub.ra = pf->hdr.ra2000; pf->sub.dec = pf->hdr.dec2000; pf->sub.offs = 0.5 * pf->sub.tsubint; slaEqgal(pf->hdr.ra2000 * DEGTORAD, pf->hdr.dec2000 * DEGTORAD, &pf->sub.glon, &pf->sub.glat); pf->sub.glon *= RADTODEG; pf->sub.glat *= RADTODEG; // The following three are unknown or hard to get, I think (SMR) pf->sub.feed_ang = 0.0; pf->sub.pos_ang = 0.0; pf->sub.par_ang = 0.0; pf->sub.bytes_per_subint = (pf->hdr.nbits * pf->hdr.nchan * pf->hdr.npol * pf->hdr.nsblk) / 8; pf->sub.FITS_typecode = TBYTE; // 11 = byte // Create and initialize the subint arrays pf->sub.dat_freqs = gen_fvect(pf->hdr.nchan); pf->sub.dat_weights = gen_fvect(pf->hdr.nchan); for (ii = 0; ii < pf->hdr.nchan; ii++) { pf->sub.dat_freqs[ii] = w->lofreq + ii * pf->hdr.df; pf->sub.dat_weights[ii] = 1.0; } // The following are re-set to try to preserve the band shape later pf->sub.dat_offsets = gen_fvect(pf->hdr.nchan * pf->hdr.npol); pf->sub.dat_scales = gen_fvect(pf->hdr.nchan * pf->hdr.npol); for (ii = 0; ii < pf->hdr.nchan * pf->hdr.npol; ii++) { pf->sub.dat_offsets[ii] = 0.0; pf->sub.dat_scales[ii] = 1.0; } // This is the raw data block that will be updated // for each row of the PSRFITS file pf->sub.data = gen_bvect(pf->sub.bytes_per_subint); }
void print_WAPP_hdr(struct HEADERP *hdr) /* Output a WAPP header in human readable form */ { int len, vers, inverted = 0; char datetime[100]; vers = get_hdr_int(hdr, "header_version"); printf("\n Header version = %d\n", vers); printf(" Header size (bytes) = %d\n", hdr->headlen + hdr->offset); printf(" Source Name = %s\n", get_hdr_string(hdr, "src_name", &len)); printf(" Observation Type = %s\n", get_hdr_string(hdr, "obs_type", &len)); printf(" Observation Date (YYYMMDD) = %s\n", get_hdr_string(hdr, "obs_date", &len)); printf(" Obs Start UT (HH:MM:SS) = %s\n", get_hdr_string(hdr, "start_time", &len)); printf(" MJD start time = %.12Lf\n", UT_strings_to_MJD(get_hdr_string(hdr, "obs_date", &len), get_hdr_string(hdr, "start_time", &len), datetime)); printf(" Project ID = %s\n", get_hdr_string(hdr, "project_id", &len)); printf(" Observers = %s\n", get_hdr_string(hdr, "observers", &len)); printf(" Scan Number = %d\n", get_hdr_int(hdr, "scan_number")); printf(" RA (J2000, HHMMSS.SSSS) = %.4f\n", get_hdr_double(hdr, "src_ra")); printf(" DEC (J2000, DDMMSS.SSSS) = %.4f\n", get_hdr_double(hdr, "src_dec")); printf(" Start Azimuth (deg) = %-17.15g\n", get_hdr_double(hdr, "start_az")); printf(" Start Zenith Ang (deg) = %-17.15g\n", get_hdr_double(hdr, "start_za")); printf(" Start AST (sec) = %-17.15g\n", get_hdr_double(hdr, "start_ast")); printf(" Start LST (sec) = %-17.15g\n", get_hdr_double(hdr, "start_lst")); printf(" Obs Length (sec) = %-17.15g\n", get_hdr_double(hdr, "obs_time")); printf(" Requested T_samp (us) = %-17.15g\n", get_hdr_double(hdr, "samp_time")); printf(" Actual T_samp (us) = %-17.15g\n", get_hdr_double(hdr, "wapp_time")); printf(" Central freq (MHz) = %-17.15g\n", get_hdr_double(hdr, "cent_freq")); printf(" Total Bandwidth (MHz) = %-17.15g\n", get_hdr_double(hdr, "bandwidth")); printf(" Number of lags = %d\n", get_hdr_int(hdr, "num_lags")); printf(" Number of IFs = %d\n", get_hdr_int(hdr, "nifs")); printf(" Samples since obs start = %lld\n", get_hdr_longlong(hdr, "timeoff")); printf(" Other information:\n"); if (get_hdr_int(hdr, "sum") == 1) printf(" IFs are summed.\n"); if (get_hdr_int(hdr, "freqinversion")) { inverted = (inverted == 1) ? 0 : 1; } if (vers >= 7) { if (get_hdr_int(hdr, "iflo_flip")) { inverted = (inverted == 1) ? 0 : 1; } } if (inverted) printf(" Frequency band is inverted.\n"); if (get_hdr_int(hdr, "lagformat") == 0) printf(" Lags are 16 bit integers.\n"); else printf(" Lags are 32 bit integers.\n"); }
static void set_wappinfo(struct HEADERP *h, struct wappinfo *w) { int ival; // Header version w->header_version = get_hdr_int(h, "header_version"); // Header Length w->header_size = h->headlen + h->offset; // Number of channels (i.e. lags) w->numchans = get_hdr_int(h, "num_lags"); // Number of IFs (i.e. polns) in the data w->numifs = get_hdr_int(h, "nifs"); if (w->numifs > 1) { printf("\nERROR: wapp2psrfits cannot (yet?) handle more than 1 IF!\n\n"); exit(1); } // 16- or 32-bit lags ival = get_hdr_int(h, "lagformat"); if (ival == 0) w->bits_per_lag = 16; else if (ival == 1) w->bits_per_lag = 32; else { printf("\nERROR: Unrecognized bits per sample (%d, 'lagformat')!\n\n", w->bits_per_lag); exit(1); } // How many bytes are there in a sample in time (i.e. all the lags) w->bytes_per_sample = (w->bits_per_lag / 8) * w->numifs * w->numchans; // 3- or 9-level correlations ival = get_hdr_int(h, "level"); if (ival == 1) w->corr_level = 3; else if (ival == 2) w->corr_level = 9; else { printf("\nERROR: Unrecognized 'level' setting! (%d)\n\n", w->corr_level); exit(1); } // Is the band inverted? (i.e. lower sideband) w->invertband = 0; if (get_hdr_int(h, "freqinversion")) { w->invertband = (w->invertband == 1) ? 0 : 1; } // These two parameters are cumulative... if (w->header_version >= 7) { if (get_hdr_int(h, "iflo_flip")) { w->invertband = (w->invertband == 1) ? 0 : 1; } } // Sampling time in sec w->dt = get_hdr_double(h, "wapp_time") / 1.0e6; // Bandwidth in MHz w->BW = get_hdr_double(h, "bandwidth"); // Center freq of the band w->fctr = get_hdr_double(h, "cent_freq"); // Channel BW in MHz w->df = fabs(w->BW / w->numchans); // Center freq of the lowest freq channel // See: http://www.cv.nrao.edu/~pdemores/wapp/ // Note: If band is inverted, since we reorder the channels // explicitly, we don't need to use the negative "B" // factor from Paul's webpage above. And the following // is correct for USB or LSB data. w->lofreq = w->fctr - 0.5 * w->BW + 0.5 * w->df; // Correlator scaling { double dtus, corr_rate; dtus = w->dt * 1.0e6; corr_rate = 1.0 / (dtus - WAPP_DEADTIME); w->corr_scale = corr_rate / w->BW; // Correction for narrow band use if (w->BW < 50.0) w->corr_scale = corr_rate / 50.0; if (w->corr_level == 9) // 9-level sampling w->corr_scale /= 16.0; if (get_hdr_int(h, "sum")) // summed IFs (search mode) w->corr_scale /= 2.0; w->corr_scale *= pow(2.0, (double) get_hdr_int(h, "lagtrunc")); } // RA (J2000) in decimal degrees { double hr, m, s, dval; dval = get_hdr_double(h, "src_ra"); hr = (int) floor(dval / 10000.0); m = (int) floor((dval - hr * 10000) / 100.0); s = dval - hr * 10000 - m * 100; w->ra = (hr + (m + s / 60.0) / 60.0) * 15.0; } // DEC (J2000) in decimal degrees { double d, m, s, dval; dval = get_hdr_double(h, "src_dec"); d = (int) floor(fabs(dval) / 10000.0); m = (int) floor((fabs(dval) - d * 10000) / 100.0); s = fabs(dval) - d * 10000 - m * 100; w->dec = (d + (m + s / 60.0) / 60.0); if (dval < 0.0) w->dec = -w->dec; } // Epoch (MJD) of the first sample { int len; char *cptr1, *cptr2; cptr1 = get_hdr_string(h, "obs_date", &len); cptr2 = get_hdr_string(h, "start_time", &len); w->MJD_epoch = UT_strings_to_MJD(cptr1, cptr2, w->date_obs); } }