Пример #1
0
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;
}
Пример #2
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);
}
Пример #3
0
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");
}
Пример #4
0
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);
    }
}