Exemple #1
0
def convert_scan_list_to_times(aips_data, scan_list):
    """convert a list of scan ID numbers into times by the start of the scan

INPUTS:
aips_data    I  The AIPSUVData object to investigate
scan_list    I  A list of scan ID numbers to fid the start times for

OUTPUTS: time_list
time_list    I  A list of times as doubles in days since the reference date of
                the start of each scan.  This array is sorted in increasing time
                order.
    """
    assert(jma_aips.check_table_version_exists(aips_data, 'AIPS NX', 0))
    nx_table = aips_data.table('AIPS NX', 0)
    time_list = []
    for scan in scan_list:
        row = nx_table[scan-1]
        start_time = row.time - 0.5 * row.time_interval
        time_list.append(start_time)
    time_list.sort()
    return time_list
Exemple #2
0
def get_subarray_scan_times(aips_data, subarray):
    """get a list of [scan_id, start_time, end_time] for all subarray scans

INPUTS:
aips_data    I  The AIPSUVData object to investigate
subarray     I  subarray number to check

OUTPUTS: scan_times
scan_times   O  A list of [scan_id, start_time, end_time] lists for all
                scans for the subarray.  The times are in AIPS days since the
                reference date

    """    
    assert(jma_aips.check_table_version_exists(aips_data, 'AIPS NX', 0))
    nx_table = aips_data.table('AIPS NX', 0)
    scan_times = []
    count = -1
    for row in nx_table:
        count = count+1
        if(row.subarray == subarray):
            start_time = row.time - 0.5 * row.time_interval
            end_time = row.time + 0.5 * row.time_interval
            scan_times.append([copy.copy(count), start_time, end_time])
    return scan_times
Exemple #3
0
def correct_180_phase_jumps(aips_data,
                            antenna,
                            refant,
                            CL_use,
                            CL_in,
                            CL_out,
                            SN_out,
                            solint=120,
                            source_list = None,
                            subarray=1,
                            overwrite=0
                            ):
    """Fix a dataset for 180 degree phase jumps introduced at random scan starts

Some telescopes (Onsala) sometimes introduce 180 degree phase jumps in the
instrument (LO) phase at the beginning of scans.  This process appears to be
approximately random as to which scans this appears in.  This function will
try to figure out wheresuch phase jumps are located and correct for them.

This is intended to help with phase referencing, but it should also help
to a small extent with bright objects too.  However, for phase referencing,
if the target object is weak, there is no way to tell whether a phase jump
has happened at the start of the target scan.  :(

The idea is that you should have the data reasonably calibrated and flagged.
For VLBI data, hopefully you have corrected for the major delay and rate terms
using bright FRINGE finder scans (but at this point you should NOT have
applied any phase corrections from your FRING runs).  Ionospheric calibration
should also have been applied.  Hopefully, your sources are bright and reasonably
compact, or at least have structure which does not change rapidly with time.
This routine will run a simple point-source model for all supplied sources
with CALIB to determine instrumental phases.  This is done using a solint of
solint.  Because this is expected only for L Band Onsala data at the moment, a
default of 120 seconds solint has been chosen.  The resulting SN table is
examined to search for phase jumps in the supplied antenna.

INPUTS:
aips_data    I  The AIPSUVData object to investigate
antenna      I  antenna in the subarray to correct.  This may either be the
                antenna number or the name of the antenna
refant       I  A reference antenna to use for CALIB.  This must not be the
                same as antenna!  You may give the name or the number
CL_use       I  CL table to use for gain calibration in order to search for
                phase jumps.  May be different from CL_in.
                If 0, use the highest.
CL_in        I  Number of CL table to use to start to make the next CL table
                with the calibrated jumps.  If 0, use the highest.
CL_out       I  Number of CL table to write out to (must not exist if overwrite
                is false!)  If 0, use the highest +1
SN_out       I  Number of SN table to create to search for phase jumps
solint       I  Solution interval to use for CALIB run, in seconds
source_list  I  Source list to use for CALIB run.  Defaults to None, which
                means to use all sources.  If you select a subset of sources,
                then only those sources will be checked and corrected.  This
                could be potentially useful if a target source you wish to
                fix has lots of structure
subarray     I  subarray number to correct
overwrite    I  May the CL_out table be overwritten?

OUTPUTS: None
    """
    # Check antennas
    antenna_number = antenna
    if(type(antenna) != type(5)):
        antenna_number = jma_aips.get_antenna_number_subarray(aips_data, antenna,
                                                              subarray)
    if(type(refant) != type(5)):
        refant = jma_aips.get_antenna_number_subarray(aips_data, refant,subarray)
    if(refant == antenna_number):
        warnings.warn("Hey, don't use same antenna for antenna and refant here.\nTold to use %d"%refant)
        if(refant <= 1):
            refant = 2
        else:
            refant -= 1
    # Check CL tables
    if(CL_out == 0):
        CL_out = aips_data.table_highver('AIPS CL') + 1
    if(CL_in == 0):
        CL_in = aips_data.table_highver('AIPS CL')
    if(CL_use == 0):
        CL_use = aips_data.table_highver('AIPS CL')
    assert(jma_aips.check_table_version_exists(aips_data, 'AIPS CL', CL_in))
    assert(jma_aips.check_table_version_exists(aips_data, 'AIPS CL', CL_use))
    # Make sure the SN table spot is free
    if(SN_out == 0):
        SN_out = aips_data.table_highver('AIPS SN') + 1
    jma_aips.verify_table_version_free(aips_data, 'AIPS SN', SN_out, overwrite)
    # Now, run CALIB
    jma_aips.run_calib(aips_data, refant, solint, 0,
                       sources_use = source_list,
                       gainuse=CL_use,
                       aparm=[None,3,0,0,0,0,0,2.5],
                       soltype='L1',
                       solmode='P!A',
                       snver=SN_out)
    
    # Now get the list of times
    time_list = locate_180_phase_jumps_in_SN(aips_data, SN_out,
                                             subarray, antenna_number)
    # Now fix the problem
    if(time_list):
        fix_scan_180_degree_phase_jumps(aips_data,
                                        CL_in,
                                        CL_out,
                                        subarray,
                                        antenna_number,
                                        time_list,
                                        overwrite=0
                                        )
    elif(CL_in != CL_out):
        # There is nothing to fix.  But to keep things sane, just copy
        # over the CL table
        jma_aips.run_tacop(aips_data, 'CL', CL_in, 1, aips_data, CL_out)
    return
Exemple #4
0
def locate_180_phase_jumps_in_SN(aips_data,
                                 SN,
                                 subarray,
                                 antenna_number
                                 ):
    """Search for 180 degree phase jumps in data from an SN table

INPUTS:
aips_data    I  The AIPSUVData object to investigate
SN           I  The SN table version to investigate
subarray     I  subarray number to correct
antenna_number I  antenna number in the subarray to correct

OUTPUTS:
time_list    O  A list of times as doubles in days since the reference date of
                the start of each scan.  This array must be sorted in increasing
                time order.  This list gives the times at which the new phase
                starts.
    """
    assert(jma_aips.check_table_version_exists(aips_data, 'AIPS SN', SN))
    w = Wizardry.AIPSData.AIPSUVData(aips_data)
    SN_table = w.table('AIPS SN',SN)
    NUM_IF = SN_table.keywords['NO_IF']
    NUM_POL = SN_table.keywords['NO_POL']
    scan_times = get_subarray_scan_times(aips_data, subarray)
    if(len(scan_times) < 2):
        # 1 or fewer scans means there cannot be a phase jump
        return None
    time_list = []
    early_scan = 0
    found_flag = 0
    while(early_scan < len(scan_times) -1):
        start_time = scan_times[early_scan][1]
        end_time = scan_times[early_scan][2]
        found_flag, early_phase = \
                    find_SN_phase_data(SN_table, NUM_IF, NUM_POL,
                                       subarray, antenna_number,
                                       start_time, end_time, 1)
        if(found_flag):
            break
        early_scan = early_scan + 1
    if(found_flag == 0):
        raise RuntimeError("No data in SN table to match")
    late_scan = early_scan
    while(late_scan < len(scan_times) -1):
        # check the next scan
        late_scan = late_scan+1
        start_time = scan_times[late_scan][1]
        end_time = scan_times[late_scan][2]
        found_flag, late_phase = \
                    find_SN_phase_data(SN_table, NUM_IF, NUM_POL,
                                       subarray, antenna_number,
                                       start_time, end_time, 0)
        if(found_flag):
            # Hey, found the next set of data
            print "Scan %3d"%late_scan
            mean_phase = compare_SN_phase_data(NUM_IF, NUM_POL,
                                               early_phase, late_phase)
            if(mean_phase is not None):
                if(math.fabs(mean_phase) > math.pi*0.5):
                    print "found phase difference at scan ", late_scan
                    time_list.append(start_time)
                # now reget the early phase SN values for this scan
                found_flag, early_phase = \
                            find_SN_phase_data(SN_table, NUM_IF, NUM_POL,
                                               subarray, antenna_number,
                                               start_time, end_time, 1)
            else:
                # cannot compare this scan with the previous scan.
                # Oh well.  Skip it and hope for the best
                pass
    if(len(time_list) == 0):
        return None
    return time_list
Exemple #5
0
def fix_scan_180_degree_phase_jumps(aips_data,
                                    CL_in,
                                    CL_out,
                                    subarray,
                                    antenna_number,
                                    time_list,
                                    overwrite=0
                                    ):
    """Fix a CL table for 180 degree phase jumps introduced at random scan starts

Some telescopes (Onsala) sometimes introduce 180 degree phase jumps in the
instrument (LO) phase at the beginning of scans.  This process appears to be
approximately random as to which scans this appears in.  This function takes in
a list of times of the beginnings of scans where there was a 180 degree phase
jump, and it corrects a CL table for those phase jumps.

This is intended to help with phase referencing, but it should also help
to a small extent with bright objects too.  However, for phase referencing,
if the target object is weak, there is no way to tell whether a phase jump
has happened at the start of the target scan.  :(

INPUTS:
aips_data    I  The AIPSUVData object to investigate
CL_in        I  Number of CL table to use for input.  If 0, use the highest.
CL_out       I  Number of CL table to write out to (must not exist if overwrite
                is false!)  If 0, use the highest +1
subarray     I  subarray number to correct
antenna_number I  antenna number in the subarray to correct
time_list    I  A list of times as doubles in days since the reference date of
                the start of each scan.  This array must be sorted in increasing
                time order.  This list gives the times at which the new phase
                starts.
overwrite    I  May the CL_out table be overwritten?

OUTPUTS: None
    """
    if(CL_out == 0):
        CL_out = aips_data.table_highver('AIPS CL') + 1
    if(CL_in == 0):
        CL_in = aips_data.table_highver('AIPS CL')
    assert(jma_aips.check_table_version_exists(aips_data, 'AIPS CL', CL_in))
    delete_CL_in_flag = 0
    if(CL_in == CL_out):
        delete_CL_in_flag = 1
        CL_in = aips_data.table_highver('AIPS CL') +1
        jma_aips.run_tacop(aips_data, 'CL', CL_out, 1, aips_data, CL_in)
        aips_data.zap_table('AIPS CL', CL_out)
    # Next, make sure the new CL table is free
    jma_aips.verify_table_version_free(aips_data, 'AIPS CL', CL_out, overwrite)
    # Ok, create the new CL table using a Wizardry dataset
    W_dataset = Wizardry.AIPSData.AIPSUVData(aips_data)
    # Get the old table and the new one
    CL_table_in = W_dataset.table('CL', CL_in)
    CL_table_out = W_dataset.attach_table(
        'CL', CL_out, no_term=CL_table_in.keywords['NO_TERM'])
    # How big is the CL table?
    Num_Total_CL_Rows = len(CL_table_in)
    #no_if=CL_table_in.keywords['NO_IF']  This is automatically copied
    #no_pol=CL_table_in.keywords['NO_POL']  This is automatically copied
    CL_table_out.keywords['REVISION'] = CL_table_in.keywords['REVISION']
    CL_table_out.keywords['NO_ANT'] = CL_table_in.keywords['NO_ANT']
    CL_table_out.keywords['MGMOD'] = CL_table_in.keywords['MGMOD']
    # how many polarizations are there? If 2, then set a flag
    two_pol = 0
    if(CL_table_in.keywords['NO_POL'] > 1): two_pol = 1
    NUM_IF = CL_table_in.keywords['NO_IF']
    # ready the time checks
    time_list = copy.copy(time_list)
    # &*@#! Python has no way of accessing standard IEEE 754 +Inf
    time_list.append(1E3000)    
    num_time_slots = len(time_list)
    phase_array = [0]*num_time_slots
    for i in xrange(num_time_slots):
        if(i&0x1 == 1):
            phase_array[i] = math.pi
    # Now loop over all of the rows in the old table to update and
    # place into the new one.  Keep track of how far along I am, so that
    # I can print out some progress messages
    start_time = systime.clock()
    count = -1
    for row in CL_table_in:
        count = count + 1
        if( (count&0x3FF) == 0 ):
            print "%5.1f%% completed in %10.1f s"%\
                  ((float(count)*100.0/Num_Total_CL_Rows),
                   systime.clock()-start_time)
        if((row.subarray == subarray) and (row.antenna_no == antenna_number)):
            # Ok, check the time.  Use 0.499 instead of 0.5 to avoid roundoff
            # errors, as AIPS only has 32-bit floats
            index = find_time_slot(row.time+0.499*row.time_interval, time_list)
            # Ok, do we rotate the phase?
            if(phase_array[index]):
                # assume phase 180 degrees
                for i in xrange(NUM_IF):
                    row.real1[i] = -row.real1[i]
                    row.imag1[i] = -row.imag1[i]
                if(two_pol):
                    for i in xrange(NUM_IF):
                        row.real2[i] = -row.real2[i]
                        row.imag2[i] = -row.imag2[i]
        CL_table_out.append(row)
    # Close the file to make sure the rows get written.
    CL_table_out.close()
    # Do we need to zap a temp CL file?
    if(delete_CL_in_flag):
        aips_data.zap_table('AIPS CL', CL_in)
    return