Exemplo n.º 1
0
int get_PSRFITS_rawblock(float *fdata, struct spectra_info *s, int *padding)
// This routine reads a single block (i.e subint) from the input files
// which contain raw data in PSRFITS format.  If padding is
// returned as 1, then padding was added and statistics should not be
// calculated.  Return 1 on success.
{
    int numtopad = 0, numtoread, status = 0, anynull;
    float *fdataptr = fdata;
    double offs_sub;
    
    fdataptr = fdata + numbuffered * s->num_channels;
    // numtoread is always this size since we need to read
    // full PSRFITS subints...
    numtoread = s->spectra_per_subint;
    
    // If our buffer array is offset from last time, 
    // copy the previously offset part into the beginning.
    // New data comes after the old data in the buffer.
    if (numbuffered)
        memcpy(fdata, fdata + numtoread * s->num_channels, 
               numbuffered * s->num_channels * sizeof(float));
    
    // Make sure our current file number is valid
    if (cur_file >= s->num_files) return 0;
    
    // Read a subint of data from the DATA col
    if (cur_subint <= s->num_subint[cur_file]) {
        
        // Read the OFFS_SUB column value in case there were dropped blocks
        fits_read_col(s->fitsfiles[cur_file], TDOUBLE, 
                      s->offs_sub_col, cur_subint, 1L, 1L, 
                      0, &offs_sub, &anynull, &status);
        
        // Set last_offs_sub to proper value
        if (cur_subint==1 && (offs_sub < s->time_per_subint)) {
            if (cur_file==0) {
                // This is for the first time
                last_offs_sub = offs_sub - s->time_per_subint;
            } else {
                // And this is if we are combining observations
                last_offs_sub = (s->start_spec[cur_file] - 
                                 (cur_spec + numbuffered)) * s->dt - 
                    0.5 * s->time_per_subint;
            }
        }
        
        // The following determines if there were lost blocks.  We should
        // always be within 0.5 sample (and only that big if we are putting
        // two different observations together).
        if (fabs((offs_sub - last_offs_sub) - s->time_per_subint) < 0.5 * s->dt) {
            // if things look good, with no missing blocks, read the data
            get_PSRFITS_subint(fdataptr, cdatabuffer, s);
            last_offs_sub = offs_sub;
            cur_subint++;
            goto return_block;
        } else {
            if (offs_sub < last_offs_sub) { // Files out of order?  Shouldn't get here.
                fprintf(stderr, "Error!:  Current subint has earlier time than previous!\n\n"
                        "\tfilename = '%s', subint = %d\n"
                        "\tlast_offs_sub = %20.15f  offs_sub = %20.15f\n",
                        s->filenames[cur_file], cur_subint, last_offs_sub, offs_sub);
                exit(1);
            } else {  // there is some missing data, use padding
                numtopad = (int)round((offs_sub - last_offs_sub) / s->dt) - numbuffered;
                if (numtopad > s->spectra_per_subint) numtopad = s->spectra_per_subint;
                add_padding(fdataptr, s->padvals, s->num_channels, numtopad);
                // Update the time of the last subs based on this padding
                last_offs_sub += numtopad * s->dt;
                // Update pointer into the buffer
                numbuffered = (numbuffered + numtopad) % s->spectra_per_subint;
                // Set the padding flag
                *padding = 1;
                // If we haven't gotten a full block, or completed the buffered one
                // then recursively call get_PSRFITS_rawblock()
                if (numbuffered)
                    return get_PSRFITS_rawblock(fdata, s, padding);
                else
                    goto return_block;
            }
        }
        
    } else {
        // We can't read anymore...  so read OFFS_SUB for the last row
        // of the current file to see about padding
        fits_read_col(s->fitsfiles[cur_file], TDOUBLE, 
                      s->offs_sub_col, s->num_subint[cur_file], 1L, 1L, 
                      0, &offs_sub, &anynull, &status);
    }
    
    if (s->num_pad[cur_file]==0 ||
        (fabs(last_offs_sub - offs_sub) < 0.5 * s->dt)) {
        // No padding is necessary.  The second check means that the
        // lack of data we noticed upon reading the file was due to
        // dropped data in the middle of the file that we already
        // fixed.  So no padding is really necessary.
        cur_file++;
        cur_subint = 1;
        return get_PSRFITS_rawblock(fdata, s, padding);
    } else { // add padding
        // Set offs_sub to the correct offs_sub time for the first
        // row of the next file.  Since that might or might not
        // be from a different observation, use absolute times from
        // the start of the observation for both offs_sub and last_offs_sub
        offs_sub = s->start_spec[cur_file+1] * s->dt + 0.5 * s->time_per_subint;
        last_offs_sub = (cur_spec + numbuffered) * s->dt - 0.5 * s->time_per_subint;
        // Compute the amount of required padding
        numtopad = (int)round((offs_sub - last_offs_sub) / s->dt) - numbuffered;
        if (numtopad > s->spectra_per_subint) numtopad = s->spectra_per_subint;
        add_padding(fdataptr, s->padvals, s->num_channels, numtopad);
        // Update the time of the last subs based on this padding
        last_offs_sub += numtopad * s->dt;
        // Update pointer into the buffer
        numbuffered = (numbuffered + numtopad) % s->spectra_per_subint;
        // Set the padding flag
        *padding = 1;
        // If we haven't gotten a full block, or completed the buffered one
        // then recursively call get_PSRFITS_rawblock()
        if (numbuffered)
            return get_PSRFITS_rawblock(fdata, s, padding);
        else
            goto return_block;
    }
    
return_block:
    // Apply the corrections that need a full block

    // Invert the band if needed
    if (s->apply_flipband) flip_band(fdata, s);

    // Perform Zero-DMing if requested
    if (s->remove_zerodm) remove_zerodm(fdata, s);

    // Increment our static counter (to determine how much data we
    // have written on the fly).
    cur_spec += s->spectra_per_subint;

    return 1;
}
Exemplo n.º 2
0
int get_PSRFITS_rawblock(float *fdata, struct spectra_info *s, int *padding)
// This routine reads a single block (i.e subint) from the input files
// which contain raw data in PSRFITS format.  If padding is
// returned as 1, then padding was added and statistics should not be
// calculated.  Return 1 on success.
{
    int numtopad = 0, numtoread, status = 0, anynull;
    float *fdataptr = fdata;

    fdataptr = fdata + numbuffered * s->num_channels;
    // numtoread is always this size since we need to read
    // full PSRFITS subints...
    numtoread = s->spectra_per_subint;

    // If our buffer array is offset from last time,
    // copy the previously offset part into the beginning.
    // New data comes after the old data in the buffer.
    if (numbuffered)
        memcpy((char *) fdata, (char *) (fdata + numtoread * s->num_channels),
               numbuffered * s->num_channels * sizeof(float));

    // Make sure our current file number is valid
    if (cur_file >= s->num_files)
        return 0;

    // Read a subint of data from the DATA col
    if (cur_subint <= s->num_subint[cur_file]) {
        double offs_sub = 0.0;
        if (!offs_sub_are_zero) {
            // Read the OFFS_SUB column value in case there were dropped blocks
            fits_read_col(s->fitsfiles[cur_file], TDOUBLE,
                          s->offs_sub_col, cur_subint, 1L, 1L,
                          0, &offs_sub, &anynull, &status);
            // Set new_spec to proper value, accounting for possibly
            // missing initial rows of data and/or combining observations
            // Note: need to remove start_subint because that was already put
            // into start_spec.  This is important if initial rows are gone.
            new_spec = s->start_spec[cur_file] +
                roundl((offs_sub - (s->start_subint[cur_file] + 0.5)
                        * s->time_per_subint) / s->dt);
        } else {
            new_spec = s->start_spec[cur_file] +
                (cur_subint - 1) * s->spectra_per_subint;
        }

        //printf("cur/new_spec = %lld, %lld  s->start_spec[cur_file] = %lld\n",
        //       cur_spec, new_spec, s->start_spec[cur_file]);

        // The following determines if there were lost blocks, or if
        // we are putting different observations together so that
        // the blocks are not aligned
        if (new_spec == cur_spec + numbuffered) {
            // if things look good, with no missing blocks, read the data
            get_PSRFITS_subint(fdataptr, cdatabuffer, s);
            cur_subint++;
            goto return_block;
        } else {
            goto padding_block;
        }
    } else {
        // We are going to move to the next file, so update
        // new_spec to be the starting spectra from the next file
        // so we can see if any padding is necessary
        if (cur_file < s->num_files - 1)
            new_spec = s->start_spec[cur_file + 1];
        else
            new_spec = cur_spec + numbuffered;
    }

    if (new_spec == cur_spec + numbuffered) {
        // No padding is necessary, so switch files
        cur_file++;
        cur_subint = 1;
        return get_PSRFITS_rawblock(fdata, s, padding);
    } else {                    // add padding
        goto padding_block;
    }

  padding_block:
    if (new_spec < cur_spec) {
        // Files out of order?  Shouldn't get here.
        fprintf(stderr, "Error!:  Current subint has earlier time than previous!\n\n"
                "\tfilename = '%s', subint = %d\n"
                "\tcur_spec = %lld  new_spec = %lld\n",
                s->filenames[cur_file], cur_subint, cur_spec, new_spec);
        exit(1);
    }
    numtopad = new_spec - cur_spec;
    // Don't add more than 1 block and if buffered, then realign the buffer
    if (numtopad > (s->spectra_per_subint - numbuffered))
        numtopad = s->spectra_per_subint - numbuffered;
    add_padding(fdataptr, s->padvals, s->num_channels, numtopad);
    // Update pointer into the buffer
    numbuffered = (numbuffered + numtopad) % s->spectra_per_subint;
    // Set the padding flag
    *padding = 1;
    // If we haven't gotten a full block, or completed the buffered one
    // then recursively call get_PSRFITS_rawblock()
    if (numbuffered) {
        printf("Adding %d spectra of padding to buffer at subint %d\n",
               numtopad, cur_subint);
        return get_PSRFITS_rawblock(fdata, s, padding);
    } else {
        printf("Adding %d spectra of padding at subint %d\n", numtopad, cur_subint);
        goto return_block;
    }

  return_block:
    // Apply the corrections that need a full block

    // Invert the band if needed
    if (s->apply_flipband)
        flip_band(fdata, s);

    // Perform Zero-DMing if requested
    if (s->remove_zerodm)
        remove_zerodm(fdata, s);

    // Increment our static counter (to determine how much data we
    // have written on the fly).
    cur_spec += s->spectra_per_subint;

    return 1;
}