Example #1
0
def proper_fits_shapes(qname, uname, frequencyname):
    """
    Verify that the Q and U FITS cubes and the file with frequency
    data have compatible shapes. *qname* and *uname* are the filenames
    of the Q and U FITS files, respectively; *frequencyname* is the
    filename of the frequency file.

    Returns True if all is well, raises ShapeError otherwise.
    """
    frequencies = parse_frequency_file(frequencyname)
    q_h = fits.get_header(qname)
    u_h = fits.get_header(uname)
    errors = []
    for name, hdr in [(qname, q_h), (uname, u_h)]:
        if hdr['NAXIS'] != 3:
            errors.append('number of axes in %s  is  %d, not 3' %
                          (name, hdr['NAXIS']))

    for axis in ['NAXIS1', 'NAXIS2', 'NAXIS3']:
        if q_h[axis] != u_h[axis]:
            errors.append('%s in %s (%d) not equal to %s in %s (%d)' %
                          (axis, qname, q_h[axis], axis, uname, u_h[axis]))

    if q_h['NAXIS3'] != len(frequencies):
        msg = ('frames in %r and %r (%d) not the same as in %r (%d)' %
               (qname, uname, q_h['NAXIS3'], frequencyname, len(frequencies)))
        errors.append(msg)
    if len(errors) > 0:
        raise ShapeError('\n'.join(errors))
    return True
Example #2
0
def correct_and_average_cubes(p_out_name,
                              q_out_name,
                              u_out_name,
                              weights_name,
                              qu_input_names,
                              freq_hz,
                              force_overwrite=False,
                              rm_to_remove=None,
                              ignore_frames=None):
    r'''
    TBD
    '''
    logging.info('correct_and_average_cubes()')
    q_header = fits.get_header(qu_input_names[0][0])
    u_header = fits.get_header(qu_input_names[0][1])
    qu_iterators = [[fits.image_frames(name) for name in qu_name]
                    for qu_name in qu_input_names]
    flat_qu_iterators = [
        item for sub_list in qu_iterators for item in sub_list
    ]
    if rm_to_remove is None:
        rm_to_remove = zeros(len(qu_input_names), dtype=float64)
    if ignore_frames is None:
        ignore_frames = [[]] * len(qu_input_names)

    p_out_hdr, q_out_hdr, u_out_hdr = output_pqu_headers(q_header)
    logging.info('P header:\n%r', p_out_hdr)
    p_out, q_out, u_out = [
        fits.streaming_output_hdu(fits_name, header, force_overwrite)
        for fits_name, header in [(
            p_out_name, p_out_hdr), (q_out_name,
                                     q_out_hdr), (u_out_name, u_out_hdr)]
    ]

    weights = []
    for channel, freq_qu_list in enumerate(izip(freq_hz, *flat_qu_iterators)):
        freq = freq_qu_list[0]
        logging.info('Channel %r: %.3f MHz', channel, freq / 1e6)
        wl2 = wavelength_squared_m2_from_freq_hz(freq)
        q_frames = array(freq_qu_list[1::2], dtype=float32)
        u_frames = array(freq_qu_list[2::2], dtype=float32)
        mask = 1.0 - array([channel in ignore for ignore in ignore_frames])
        phasors = exp(-2.j * array(rm_to_remove) * wl2) * mask
        corr_p_frames = (q_frames + 1j * u_frames) * phasors[:, newaxis,
                                                             newaxis]
        if mask.sum() == 0.0:
            p_final = corr_p_frames.sum(axis=0) * 0.0
        else:
            p_final = corr_p_frames.sum(axis=0) / float(mask.sum())
        weights.append(mask.sum())
        p_out.write(array(abs(p_final), dtype=float32))
        q_out.write(array(p_final.real, dtype=float32))
        u_out.write(array(p_final.imag, dtype=float32))
    p_out.close()
    q_out.close()
    u_out.close()
    with open(weights_name, 'w') as w_out:
        w_out.write('\n'.join([str(w) for w in weights]))
    logging.info('Done correcting')
Example #3
0
def correct_and_average_cubes(p_out_name, q_out_name, u_out_name,
                              weights_name,
                              qu_input_names,
                              freq_hz,
                              force_overwrite=False,
                              rm_to_remove=None,
                              ignore_frames=None):
    r'''
    TBD
    '''
    logging.info('correct_and_average_cubes()')
    q_header = fits.get_header(qu_input_names[0][0])
    u_header = fits.get_header(qu_input_names[0][1])
    qu_iterators = [[fits.image_frames(name) for name in qu_name]
                    for qu_name in qu_input_names]
    flat_qu_iterators = [item for sub_list in qu_iterators
                         for item in sub_list]
    if rm_to_remove is None:
        rm_to_remove = zeros(len(qu_input_names), dtype=float64)
    if ignore_frames is None:
        ignore_frames = [[]]*len(qu_input_names)

    p_out_hdr, q_out_hdr, u_out_hdr = output_pqu_headers(q_header)
    logging.info('P header:\n%r', p_out_hdr)
    p_out, q_out, u_out = [fits.streaming_output_hdu(fits_name,
                                                     header,
                                                     force_overwrite)
                           for fits_name, header in [(p_out_name, p_out_hdr),
                                                     (q_out_name, q_out_hdr),
                                                     (u_out_name, u_out_hdr)]]

    weights = []
    for channel, freq_qu_list in enumerate(izip(freq_hz, *flat_qu_iterators)):
        freq = freq_qu_list[0]
        logging.info('Channel %r: %.3f MHz', channel, freq/1e6)
        wl2 = wavelength_squared_m2_from_freq_hz(freq)
        q_frames = array(freq_qu_list[1::2], dtype=float32)
        u_frames = array(freq_qu_list[2::2], dtype=float32)
        mask = 1.0 - array([channel in ignore for ignore in ignore_frames])
        phasors = exp(-2.j*array(rm_to_remove)*wl2)*mask
        corr_p_frames = (q_frames +1j*u_frames)*phasors[:, newaxis, newaxis]
        if mask.sum() == 0.0:
            p_final = corr_p_frames.sum(axis=0)*0.0
        else:
            p_final = corr_p_frames.sum(axis=0)/float(mask.sum())
        weights.append(mask.sum())
        p_out.write(array(abs(p_final), dtype=float32))
        q_out.write(array(p_final.real, dtype=float32))
        u_out.write(array(p_final.imag, dtype=float32))
    p_out.close()
    q_out.close()
    u_out.close()
    with open(weights_name, 'w') as w_out:
        w_out.write('\n'.join([str(w) for w in weights]))
    logging.info('Done correcting')
Example #4
0
def mean_psf(psf_name, frequencies, output_fits_name, force_overwrite,
             max_mem_gb=2.0, bad_frames=None):
    logging.info('mean_psf()')
    psf_header = fits.get_header(psf_name)
    pixels_per_frame = psf_header['NAXIS1']*psf_header['NAXIS2']
    max_mem_bytes = max_mem_gb*1024**3
    bytes_per_input_pixel = psf_header['BITPIX']/8.0
    max_input_pixels = max_mem_bytes/bytes_per_input_pixel
    block_length = int(floor(max_input_pixels/pixels_per_frame/4.0))
    num_blocks = int(floor(psf_header['NAXIS3']/block_length))
    if psf_header['NAXIS3'] % block_length > 0:
        num_blocks += 1
    output_header = psf_header

    nfreq = len(frequencies)
    psf_frames = fits.image_frames(psf_name)
    frame_id = 0
    skipped_frames = 0
    sum_psf = zeros((psf_header['NAXIS2'], psf_header['NAXIS1']), dtype=float32)
    sum_freq_hz = 0.0
    for freq_hz, psf in izip(frequencies, psf_frames):
        if bad_frames is not None and frame_id in bad_frames:
            logging.warn('skipping frame % d: in bad frame list.', frame_id)
            skipped_frames += 1
        else:
            logging.info('processing frame '+str(frame_id+1)+'/'+str(nfreq))
            sum_psf += psf
            sum_freq_hz += freq_hz
        gc.collect()
        frame_id += 1
    frames_added = nfreq - skipped_frames
    mean_psf_frame = sum_psf/frames_added
    mean_freq_hz = sum_freq_hz/frames_added
    fits.write_cube(output_fits_name, output_header, mean_psf_frame, force_overwrite)
    logging.info('Done')
Example #5
0
def rmsynthesis_dirty_lowmem_mp(qname, uname, q_factor, u_factor,
                                frequencies, phi_array):
    """
    Perform an RM synthesis on Q and U image cubes with given
    frequencies. The rmcube that is returned is complex valued and has
    a frame for every value in phi_array. It is assumed that the
    dimensions of qcube, ucube, and frequencies have been verified
    before with the help of the proper_fits_shapes() function. The
    polarization vectors are derotated to the average lambda^2.

    Uses the multiprocessing module to speed up the calculations.
    """
    num_workers = mp.cpu_count()-1

    wl2 = wavelength_squared_m2_from_freq_hz(frequencies)
    qheader = fits.get_header(qname)
    wl2_0 = wl2.mean()

    nfreq = len(frequencies)
    q_frames = fits.image_frames(qname)
    u_frames = fits.image_frames(uname)
    frame_id = 0
    wl2_norm = wl2 - wl2_0

    phi_arrays = array_split(phi_array, num_workers)
    frame_shape = (qheader['NAXIS2'], qheader['NAXIS1'])
    mp_shared_p_complex = mp.Array(ctypes.c_float,
                                   frame_shape[0]*frame_shape[1]*2)
    p_complex = frombuffer(mp_shared_p_complex.get_obj(),
                           dtype=complex64).reshape(frame_shape)

    queues = [mp.JoinableQueue() for _ in range(num_workers)]
    workers = [mp.Process(target=rmsynthesis_worker,
                          args=(queue, mp_shared_p_complex,
                                frame_shape, phi))
                   for queue, phi in zip(queues, phi_arrays)]
    for worker in workers:
        worker.daemon = True
        worker.start()

    for q_frame, u_frame in izip(q_frames, u_frames):
        logging.info('processing frame '+str(frame_id+1)+'/'+str(nfreq))
        p_complex[:, :] = q_frame*q_factor + 1.0j*u_frame*u_factor
        wl2_frame = wl2_norm[frame_id]

        for queue in queues:
            queue.put(wl2_frame)
        for queue in queues:
            queue.join()
        frame_id += 1
        gc.collect()
    for queue in queues:
        queue.put(None)
    logging.info('Collecting partial results')
    partial_rmcubes = [queue.get() for queue in queues]
    rmcube = concatenate(partial_rmcubes)/nfreq
    for worker in workers:
        worker.join()
    gc.collect()
    return rmcube
Example #6
0
def average_psf_cubes(psf_out_name,
                      weights_name,
                      psf_input_names,
                      force_overwrite=False,
                      ignore_frames=None):
    r'''
    TBD
    '''
    logging.info('correct_and_average_cubes()')
    psf_header = fits.get_header(psf_input_names[0])
    psf_iterators = [fits.image_frames(name) for name in psf_input_names]

    if ignore_frames is None:
        ignore_frames = [[]]*len(qu_input_names)

    psf_out_hdr = psf_header
    logging.info('PSF header:\n%r', psf_out_hdr)
    psf_out = fits.streaming_output_hdu(psf_out_name, psf_header, force_overwrite)

    weights = []
    for channel, frames in enumerate(izip(*psf_iterators)):
        logging.info('Channel %r', channel)
        psf_frames = array(frames, dtype=float32)
        mask = 1.0 - array([channel in ignore for ignore in ignore_frames])
        masked_psf_frames = psf_frames*mask[:, newaxis, newaxis]
        if mask.sum() == 0.0:
            psf_final = psf_frames[0,:,:]*0.0
        else:
            psf_final = psf_frames.sum(axis=0)/float(mask.sum())
        weights.append(mask.sum())
        psf_out.write(array(psf_final, dtype=float32))
    psf_out.close()
    with open(weights_name, 'w') as w_out:
        w_out.write('\n'.join([str(w) for w in weights]))
    logging.info('Done averaging')
Example #7
0
def rmsynthesis_crosscorr_dirty_lowmem_main(q_template_name, u_template_name,
                                            q_name, u_name,
                                            q_factor, u_factor,
                                            output_dir, freq_hz, phi_rad_m2,
                                            force_overwrite, max_mem_gb=2.0,
                                            bad_frames=None):
    r'''
    '''
    logging.info('rmsynthesis_crosscorr_dirty_lowmem_main()')
    q_header = fits.get_header(q_name)
    pixels_per_frame = q_header['NAXIS1']*q_header['NAXIS2']

    max_mem_bytes = max_mem_gb*1024**3
    bytes_per_output_pixel = 4
    max_output_pixels = max_mem_bytes/bytes_per_output_pixel
    # 7 = (re, im) + p_out + q_out + u_out
    block_length = int(floor(max_output_pixels/pixels_per_frame/9.0))
    num_blocks = int(floor(len(phi_rad_m2)/block_length))
    if len(phi_rad_m2) % block_length > 0:
        num_blocks += 1


    output_header = add_phi_to_fits_header(q_header.copy(), phi_rad_m2)
    p_out_name, q_out_name, u_out_name = output_pqu_fits_names(output_dir)
    p_out_hdr, q_out_hdr, u_out_hdr = output_pqu_headers(output_header)
    p_out, q_out, u_out = [fits.streaming_output_hdu(fits_name,
                                                     header,
                                                     force_overwrite)
                           for fits_name, header in [(p_out_name, p_out_hdr),
                                                     (q_out_name, q_out_hdr),
                                                     (u_out_name, u_out_hdr)]]
    try:
        logging.info('Computing cross correlation with templates\n  - Q:%s\n  - U:%s',
                     q_template_name, u_template_name)
        for block in range(num_blocks):
            phi = phi_rad_m2[block*block_length:(block+1)*block_length]
            logging.info('Processing block %d / %d', block + 1, num_blocks)
            logging.info('Phi in  [%.1f, %.1f]', phi[0], phi[-1])
            rmcube = rmsynthesis_crosscorr_dirty_lowmem(
                q_template_name, u_template_name,
                q_name, u_name,
                q_factor, u_factor,
                freq_hz, phi,
                bad_frames=bad_frames)
            logging.info('Saving data')

            p_out.write(absolute(rmcube))
            q_out.write(rmcube.real)
            u_out.write(rmcube.imag)
    finally:
        p_out.close()
        q_out.close()
        u_out.close()
        logging.info('Done')
Example #8
0
def rmsynthesis_crosscorr_dirty_lowmem(q_template_name, u_template_name,
                                       qname, uname, q_factor, u_factor,
                                       frequencies, phi_array,
                                       bad_frames=None):
    """Perform a cross correlation in Faraday space by multiplying QU
    frames with template QU frames, and performing an RM synthesis on
    the resulting Q and U image cubes with given frequencies. The
    rmcube that is returned is complex valued and has a frame for
    every value in phi_array. It is assumed that the dimensions of
    qcube, ucube, and frequencies have been verified before with the
    help of the proper_fits_shapes() function. The polarization
    vectors are derotated to the average lambda^2.
    """
    wl2 = wavelength_squared_m2_from_freq_hz(frequencies)
    qheader = fits.get_header(qname)
    rmcube = zeros((len(phi_array), qheader['NAXIS2'], qheader['NAXIS1']),
                   dtype=complex64)
    wl2_0 = wl2.mean()

    nfreq = len(frequencies)
    q_template_frames = fits.image_frames(q_template_name)
    u_template_frames = fits.image_frames(u_template_name)
    q_frames = fits.image_frames(qname)
    u_frames = fits.image_frames(uname)
    frame_id = 0
    skipped_frames = 0
    wl2_norm = wl2 - wl2_0
    for q_temp, u_temp, q_frame, u_frame in izip(q_template_frames, u_template_frames, q_frames, u_frames):
        if bad_frames is not None and frame_id in bad_frames:
            logging.warn('skipping frame % d: in bad frame list.', frame_id)
            skipped_frames += 1
        else:
            logging.info('processing frame '+str(frame_id+1)+'/'+str(nfreq))
            template_complex = q_temp*q_factor +1.0j*u_temp*u_factor
            p_complex = (q_frame*q_factor + 1.0j*u_frame*u_factor)*template_complex.conj()
            wl2_frame = wl2_norm[frame_id]
            phases = phases_lambda2_to_phi(wl2_frame, phi_array)
            for frame, phase in enumerate(phases):
                rmcube[frame, :, :] += p_complex*phase
        gc.collect()
        frame_id += 1
    frames_added = nfreq - skipped_frames
    return rmcube/float(frames_added)
Example #9
0
def average_psf_cubes(psf_out_name,
                      weights_name,
                      psf_input_names,
                      force_overwrite=False,
                      ignore_frames=None):
    r'''
    TBD
    '''
    logging.info('correct_and_average_cubes()')
    psf_header = fits.get_header(psf_input_names[0])
    psf_iterators = [fits.image_frames(name) for name in psf_input_names]

    if ignore_frames is None:
        ignore_frames = [[]] * len(qu_input_names)

    psf_out_hdr = psf_header
    logging.info('PSF header:\n%r', psf_out_hdr)
    psf_out = fits.streaming_output_hdu(psf_out_name, psf_header,
                                        force_overwrite)

    weights = []
    for channel, frames in enumerate(izip(*psf_iterators)):
        logging.info('Channel %r', channel)
        psf_frames = array(frames, dtype=float32)
        mask = 1.0 - array([channel in ignore for ignore in ignore_frames])
        masked_psf_frames = psf_frames * mask[:, newaxis, newaxis]
        if mask.sum() == 0.0:
            psf_final = psf_frames[0, :, :] * 0.0
        else:
            psf_final = psf_frames.sum(axis=0) / float(mask.sum())
        weights.append(mask.sum())
        psf_out.write(array(psf_final, dtype=float32))
    psf_out.close()
    with open(weights_name, 'w') as w_out:
        w_out.write('\n'.join([str(w) for w in weights]))
    logging.info('Done averaging')