示例#1
0
def find_fold_times(pulsar, obsid, beg, end, min_z_power=(0.3, 0.1)):
    """
    Finds the fractional time the pulsar is in the beam at some zenith normalized power

    Parameters:
    -----------
    pulsar: string
        Pulsar J name
    obsid: int
        The observation ID
    beg: int
        The beginning of the observation time in gps time
    end: int
        The end of the observation time in gps time
    min_z_power: tuple/list
        OPTIONAL - evaluated the pulsar as 'in the beam' at this normalized zenith power. If None will use [0.3, 0.1] Default: None

    Returns:
    [enter, leave, power]: list
        enter: float
            The time the pulsar enters the beam as a normalized fraction of beg and end. None if pulsar not in beam
        leave: float
            The time the pulsar leaves the beam as a normalized fraction of beg and end. None if pulsar not in beam
        power: float
            The power for which enter and leave are calculated
    """
    if min_z_power is None:
        min_z_power = [0.3, 0.1]
    if not isinstance(min_z_power, list):
        min_z_power = list(min_z_power)

    min_z_power = sorted(min_z_power, reverse=True)
    names_ra_dec = fpio.grab_source_alog(pulsar_list=[pulsar])
    pow_dict, _ = check_known_pulsars.find_pulsars_power(
        obsid, powers=min_z_power, names_ra_dec=names_ra_dec)
    for power in pow_dict.keys():
        psr_list = pow_dict[power][obsid]
        enter = None
        leave = None
        if psr_list:  #if pulsar is in beam for this power coverage
            this_enter, this_leave = snfe.pulsar_beam_coverage(
                obsid, pulsar, beg=beg, end=end, min_z_power=power)
            if this_enter is not None and this_leave is not None:
                enter = this_enter
                leave = this_leave
                break

    return [enter, leave, power]
示例#2
0
def pulsar_beam_coverage(obsid, pulsar, beg=None, end=None):
    #returns the beginning and end time as a fraction that a pulsar is in the primary beam for the obsid files
    #beg and end should only be supplied if the files are not present on the system

    #find the enter and exit times of pulsar normalized with the observing time
    names_ra_dec = fpio.grab_source_alog(pulsar_list=[pulsar])
    beam_source_data, _ = fpio.find_sources_in_obs([obsid], names_ra_dec)

    enter_obs_norm = beam_source_data[obsid][0][1]
    exit_obs_norm = beam_source_data[obsid][0][2]

    if beg is None and end is None:
        #find the beginning and end time of the observation FILES you have on disk
        files_beg, files_end = checks.find_beg_end(obsid)
        files_duration = files_end - files_beg + 1
    else:
        #uses manually input beginning and end times to find beam coverage
        files_beg = beg
        files_end = end
        files_duration = files_end - files_beg + 1

    #find how long the total observation is (because that's what enter and exit uses)
    obs_beg, obs_end, obs_dur = file_maxmin.print_minmax(obsid)
    obs_dur = obs_end - obs_beg

    #times the source enters and exits beam
    time_enter = obs_beg + obs_dur * enter_obs_norm
    time_exit = obs_beg + obs_dur * exit_obs_norm

    #normalised time the source enters/exits the beam in the files
    enter_files = (time_enter - files_beg) / files_duration
    exit_files = (time_exit - files_beg) / files_duration

    if enter_files < 0.:
        enter_files = 0.
    if exit_files > 1.:
        exit_files = 1.
    if enter_files > 1.:
        logger.warn(
            "source {0} is not in the beam for the files on disk".format(
                pulsar))
    if exit_files < 0.:
        logger.warn(
            "source {0} is not in the beam for the files on the disk".format(
                pulsar))

    return enter_files, exit_files
def test_get_source_alog():
    """Test get_source_alog"""

    #source_type, pulsar_list, include_dm, answer
    tests = [[
        'Pulsar', 'J2313+4253', False,
        [['J2313+4253', '23:13:08.6209', '+42:53:13.043']]
    ],
             [
                 'Pulsar', 'J2313+4253', True,
                 [['J2313+4253', '23:13:08.6209', '+42:53:13.043', 17.27693]]
             ],
             ['FRB', 'FRB171019', False, [['FRB171019', '22:17.5', '-08:40']]],
             [
                 'FRB', 'FRB171019', True,
                 [['FRB171019', '22:17.5', '-08:40', '460.8']]
             ],
             [
                 'rFRB', 'FRB171019', False,
                 [['FRB171019', '22:17:30', '-08:40']]
             ],
             [
                 'rFRB', 'FRB171019', True,
                 [['FRB171019', '22:17:30', '-08:40', '460.8']]
             ],
             [
                 'RRATs', 'J1913+1330', False,
                 [['J1913+1330', '19:13:17', '13:30:32.8']]
             ],
             [
                 'RRATs', 'J1913+1330', True,
                 [['J1913+1330', '19:13:17', '13:30:32.8', '175.64']]
             ]]
    # Removing because can't test them on travis without making the candidates public
    #['Fermi' ,'J2219.7-6837' , False, [['J2219.7-6837', '22:19:47.256', '-68:37:02.28']]],
    #['Fermi' ,'J2219.7-6837' , True,  [['J2219.7-6837', '22:19:47.256', '-68:37:02.28', 2.43]]]]

    for test in tests:
        stype, name, dm, expected_ans = test
        ans = fpio.grab_source_alog(source_type=stype,
                                    pulsar_list=[name],
                                    include_dm=dm)
        if ans != expected_ans:
            raise AssertionError()
def get_sources_in_fov(obsid, source_type, fwhm):
    """
    Find all sources of the input type in the observations field-of-view

    Parameters:
    -----------
    obsid: str
        observation ID to search in
    source_type: str
        the source type input to fpio.grab_source_alog
    fwhm: float
        FWHM of the tied-array beam in degrees.
        Can be calculated in the calc_ta_fwhm function

    Returns:
    --------
    list:
        name_list: list
            A list of pulsars in the FOV
        pointing_list: list
            A list of pointings corresponding to the pulsars in name_list
    """
    names_ra_dec = fpio.grab_source_alog(source_type=source_type)
    obs_data, meta_data = fpio.find_sources_in_obs([obsid],
                                                   names_ra_dec,
                                                   dt_input=100)

    name_list = []
    pointing_list = []
    for pulsar_line in obs_data[obsid]:
        jname = pulsar_line[0]
        for line in names_ra_dec:
            if jname == line[0]:
                jname, raj, decj = line
        jname_temp_list = [jname]

        # grid the pointings to fill the position uncertaint (given in arcminutes)
        pointing_list_list = get_pointings_required(raj, decj, fwhm, 1. / 60.)

        # sort the pointings into the right groups
        for prd in pointing_list_list:
            name_list.append(jname_temp_list)
            pointing_list.append("{0}_{1}".format(prd[0], prd[1]))
    return [name_list, pointing_list]
def find_pulsars_power(obsid, powers=None, names_ra_dec=None):
    """
    Finds the beam power information for pulsars in a specific obsid

    Parameters:
    -----------
    obsid: int
        The observation ID
    powers: list/tuple
        OPTIONAL - A list of minimum beam powers to evaluate the pulsar coverage at. If none, will use [0.3, 0.1]. Default: None
    names_ra_dec: list
        OPTIONAL - A list of puslars and their RA and Dec values to evaluate (generated from fpio.get_source_alog).
                   If none, will look for all pulsars. Default: None

    Returns:
    --------
    pulsar_power_dict: dictionary
        Contains keys - power
            Contains key - obsid
                Contains one list for each pulsar found in that power
                    Each list is constructed as [jname, enter, exit, max_power]
    meta_data: list
        A list of the output of get_common_obs_metadata for the input obsid
    """
    if not powers:
        powers = [0.3, 0.1]
    elif not (isinstance(powers, list) or isinstance(powers, tuple)):
        #try this if powers isn't iterable
        powers = list(powers)

    if names_ra_dec is None:
        names_ra_dec = np.array(fpio.grab_source_alog(max_dm=250))

    pulsar_power_dict = {}
    for pwr in powers:
        obs_data, meta_data = fpio.find_sources_in_obs([obsid],
                                                       names_ra_dec,
                                                       dt_input=100,
                                                       min_power=pwr)
        pulsar_power_dict[pwr] = obs_data

    return pulsar_power_dict, meta_data
示例#6
0
def find_pulsars_in_fov(obsid, psrbeg, psrend):
    """
    Find all pulsars in the field of view and return all the pointings sorted into vdif and normal lists:
    -----------
    obsid: int
        The observation ID
    psrbeg: int
        The begining of the observation you are processing in GPS time
    psrend: int
        The end of the observation you are processing in GPS time

    Returns:
    --------
    list of lists:
           [pulsar_name_list,
            pulsar_pointing_list,
            vdif_name_list,
            vdif_pointing_list,
            sp_name_list,
            sp_pointing_list]
    """

    #Find all pulsars in beam at at least 0.3 of zenith normlaized power
    names_ra_dec = np.array(fpio.grab_source_alog(max_dm=250))
    pow_dict, meta_data = find_pulsars_power(obsid,
                                             powers=[0.3, 0.1],
                                             names_ra_dec=names_ra_dec)
    channels = meta_data[-1][-1]
    obs_psrs = pow_dict[0.3][obsid]
    psrs_list_03 = [x[0] for x in obs_psrs]
    #Include all bright pulsars in beam at at least 0.1 of zenith normalized power
    psrs_01 = [x[0] for x in pow_dict[0.1][obsid]]
    sn_dict_01 = snfe.multi_psr_snfe(psrs_01,
                                     obsid,
                                     beg=psrbeg,
                                     end=psrend,
                                     min_z_power=0.1)
    for psr in pow_dict[0.1][obsid]:
        if psr[0] not in psrs_list_03:
            sn, sn_err = sn_dict_01[psr[0]]
            if sn is not None and sn_err is not None:
                if sn - sn_err >= 10.:
                    obs_psrs.append(psr)

    #get all the pulsars periods
    pulsar_list = []
    for o in obs_psrs:
        pulsar_list.append(o[0])
    periods = psrqpy.QueryATNF(params=["P0"],
                               psrs=pulsar_list,
                               loadfromdb=ATNF_LOC).pandas["P0"]

    oap = get_obs_array_phase(obsid)
    centrefreq = 1.28 * float(min(channels) + max(channels)) / 2.
    fwhm = calc_ta_fwhm(centrefreq, array_phase=oap)

    # Sort all the sources into 3 categories, pulsars which is for slow pulsars, vdif
    # for fast pulsars that require vdif and sp for singple pulse searches (FRBs,
    # RRATs and pulsars without ATNF periods)
    pulsar_pointing_list = []
    pulsar_name_list = []
    vdif_pointing_list = []
    vdif_name_list = []
    pulsar_search_pointing_list = []
    pulsar_search_name_list = []
    sp_pointing_list = []
    sp_name_list = []

    for pi, pulsar_line in enumerate(obs_psrs):
        vdif_check = False
        sp_check = False

        PSRJ = pulsar_line[0]
        #See if pulsar is in beam for times
        #enter, exit = snfe.pulsar_beam_coverage(obsid, PSRJ, beg=psrbeg, end=psrend)
        #if enter is None or exit is None:
        #    print("{0} is not in beam for time range. Not beamforming".format(PSRJ))
        #    continue
        #TODO: uncomment this section when sn_flux_est is pulled to vcstools master

        if not (len(PSRJ) < 11 or PSRJ[-1] == 'A' or PSRJ[-2:] == 'aa'):
            continue

        for line in names_ra_dec:
            if PSRJ == line[0]:
                temp = [line]

        #temp = fpio.get_psrcat_ra_dec(pulsar_list=[PSRJ])
        temp = fpio.format_ra_dec(temp, ra_col=1, dec_col=2)
        jname, raj, decj = temp[0]
        #get pulsar period
        period = periods[pi]
        if math.isnan(period):
            print(
                "WARNING: Period not found in ephermeris for {0} so assuming "
                "it's an RRAT".format(jname))
            sp_check = True
            period = 0.
        elif float(period) < .05:
            vdif_check = True
        period = float(period) * 1000.
        print(
            "{0:12} RA: {1} Dec: {2} Period: {3:8.2f} (ms) Begin {4} End {5}".
            format(PSRJ, raj, decj, period, psrbeg, psrend))

        jname_temp_list = []
        if PSRJ[-1] == 'A' or PSRJ[-2:] == 'aa':
            #Got to find all the pulsar J names with other letters
            vdif_check = True
            for pulsar_l in obs_psrs:
                pulsar_name = pulsar_l[0]
                if pulsar_name.startswith(PSRJ[:-2]):
                    jname_temp_list.append(pulsar_name)
        else:
            jname_temp_list.append(jname)

        # grid the pointings to fill 2 arcminute raduis to account for ionosphere shift
        pointing_list_list = get_pointings_required(raj, decj, fwhm, 2. / 60.)

        # sort the pointings into the right groups
        for prd in pointing_list_list:
            if vdif_check:
                vdif_name_list.append(jname_temp_list)
                vdif_pointing_list.append("{0}_{1}".format(prd[0], prd[1]))
            elif sp_check:
                sp_name_list.append(jname_temp_list)
                sp_pointing_list.append("{0}_{1}".format(prd[0], prd[1]))
            else:
                pulsar_name_list.append(jname_temp_list)
                pulsar_pointing_list.append("{0}_{1}".format(prd[0], prd[1]))

    #Get the rest of the singple pulse search canidates
    #-----------------------------------------------------------------------------------------------------------
    temp = get_sources_in_fov(obsid, 'RRATs', fwhm)
    sp_name_list = sp_name_list + temp[0]
    sp_pointing_list = sp_pointing_list + temp[1]

    # Find all of the FRB candidates
    #-----------------------------------------------------------------------------------------------------------
    temp = get_sources_in_fov(obsid, 'FRB', fwhm)
    sp_name_list = sp_name_list + temp[0]
    sp_pointing_list = sp_pointing_list + temp[1]

    # Find all of the Fermi candidates
    #-----------------------------------------------------------------------------------------------------------
    fermi_list = get_sources_in_fov(obsid, 'Fermi', fwhm)
    pulsar_search_name_list = pulsar_search_name_list + fermi_list[0]
    pulsar_search_pointing_list = pulsar_search_pointing_list + fermi_list[1]

    # Find all of the points of interest candidates
    #-----------------------------------------------------------------------------------------------
    poi_list = get_sources_in_fov(obsid, 'POI', fwhm)
    pulsar_search_name_list = pulsar_search_name_list + poi_list[0]
    pulsar_search_pointing_list = pulsar_search_pointing_list + poi_list[1]

    # Sometimes we get redundant RRATs that are found in RRAT and ANTF catalogues so they need to be removed
    sp_name_list = list(dict.fromkeys([";".join(s) for s in sp_name_list]))
    sp_pointing_list = list(dict.fromkeys(sp_pointing_list))

    # Changing the format of the names list to make it easier to format
    return [[";".join(s) for s in pulsar_name_list], pulsar_pointing_list,
            [";".join(s) for s in vdif_name_list], vdif_pointing_list,
            [";".join(s) for s in pulsar_search_name_list],
            pulsar_search_pointing_list, sp_name_list, sp_pointing_list]
示例#7
0
def pulsar_beam_coverage(obsid, pulsar, beg=None, end=None, ondisk=False):
    """
    Finds the normalised time that a pulsar is in the beam for a given obsid
    If pulsar is not in beam, returns None, None

    Parameters:
    -----------
    obsid: int
        The observation ID
    pulsar: string
        The pulsar's J name
    beg: int
        OPTIONAL - The beginning of the observing time in gps time
    end: int
        OPTIONAL - The end of the observing time in gps time
    ondisk: boolean
        Whether to use files that are on-disk for beginning and end times. Default=False

    Returns:
    --------
    enter_files: float
        A float between 0 and 1 that describes the normalised time that the pulsar enters the beam
    exit_files: float
         a float between 0 and 1 that describes the normalised time that the pulsar exits the beam
    """
    #Find the beginning and end of obs
    obs_beg, obs_end = files_beg, files_end = mwa_metadb_utils.obs_max_min(
        obsid)
    obs_dur = obs_end - obs_beg + 1

    #Logic loop:
    if ondisk == True:
        #find the beginning and end time of the observation FILES you have on disk
        files_beg, files_end = process_vcs.find_combined_beg_end(obsid)
        files_duration = files_end - files_beg + 1
    elif beg is None and end is None:
        logger.warning(
            "ondisk==False so beg and end can not be None. Returning Nones")
        return None, None
    else:
        #uses manually input beginning and end times to find beam coverage
        files_beg = beg
        files_end = end
        files_duration = files_end - files_beg + 1

    #find the enter and exit times of pulsar normalized with the observing time
    names_ra_dec = fpio.grab_source_alog(pulsar_list=[pulsar])
    beam_source_data, _ = fpio.find_sources_in_obs([obsid], names_ra_dec)
    enter_obs_norm = beam_source_data[obsid][0][1]
    exit_obs_norm = beam_source_data[obsid][0][2]

    #times the source enters and exits beam
    time_enter = obs_beg + obs_dur * enter_obs_norm
    time_exit = obs_beg + obs_dur * exit_obs_norm

    #normalised time the source enters/exits the beam in the files
    enter_files = (time_enter - files_beg) / files_duration
    exit_files = (time_exit - files_beg) / files_duration

    if enter_files < 0.:
        enter_files = 0.
    if exit_files > 1.:
        exit_files = 1.
    if enter_files > 1. or exit_files < 0.:
        logger.warning(
            "source {0} is not in the beam for the files on disk".format(
                pulsar))
        enter_files = None
        exit_files = None

    return enter_files, exit_files
def beamform_and_fold(obsid,
                      DI_dir,
                      cal_obs,
                      args,
                      psrbeg,
                      psrend,
                      product_dir='/group/mwaops/vcs',
                      mwa_search_version='master'):

    #obsbeg, obsend, obsdur = file_maxmin.print_minmax(obsid)

    #wrapping for find_pulsar_in_obs.py
    names_ra_dec = np.array(fpio.grab_source_alog(max_dm=250))
    obs_data, meta_data = fpio.find_sources_in_obs([obsid],
                                                   names_ra_dec,
                                                   dt_input=100)
    channels = meta_data[-1][-1]

    oap = get_obs_array_phase(obsid)
    centrefreq = 1.28 * float(min(channels) + max(channels)) / 2.
    fwhm = calc_ta_fwhm(centrefreq, array_phase=oap)

    # Sort all the sources into 3 categories, pulsars which is for slow pulsars, vdif
    # for fast pulsars that require vdif and sp for singple pulse searches (FRBs,
    # RRATs and pulsars without ATNF periods)
    pulsar_pointing_list = []
    pulsar_name_list = []
    vdif_pointing_list = []
    vdif_name_list = []
    sp_pointing_list = []
    sp_name_list = []
    for pulsar_line in obs_data[obsid]:
        vdif_check = False
        sp_check = False

        PSRJ = pulsar_line[0]
        if not (len(PSRJ) < 11 or PSRJ[-1] == 'A' or PSRJ[-2:] == 'aa'):
            continue

        for line in names_ra_dec:
            if PSRJ == line[0]:
                temp = [line]

        #temp = fpio.get_psrcat_ra_dec(pulsar_list=[PSRJ])
        temp = fpio.format_ra_dec(temp, ra_col=1, dec_col=2)
        jname, raj, decj = temp[0]
        #get pulsar period
        period = psrqpy.QueryATNF(params=["P0"],
                                  psrs=[jname],
                                  loadfromdb=ATNF_LOC).pandas["P0"][0]

        if math.isnan(period):
            print(
                "WARNING: Period not found in ephermeris for {0} so assuming "
                "it's an RRAT".format(jname))
            sp_check = True
            period = 0.
        elif float(period) < .05:
            vdif_check = True
        period = float(period) * 1000.
        print(
            "{0:12} RA: {1} Dec: {2} Period: {3:8.2f} (ms) Begin {4} End {5}".
            format(PSRJ, raj, decj, period, psrbeg, psrend))

        jname_temp_list = []
        if PSRJ[-1] == 'A' or PSRJ[-2:] == 'aa':
            #Got to find all the pulsar J names with other letters
            vdif_check = True
            for pulsar_l in pulsar_lines:
                if pulsar_l.startswith(PSRJ[:-2]):
                    jname_temp_list.append(pulsar_l.split()[0])
        else:
            jname_temp_list.append(jname)

        #convert to radians
        coord = SkyCoord(raj, decj, unit=(u.hourangle, u.deg))
        rar = coord.ra.radian  #in radians
        decr = coord.dec.radian

        #make a grid around each pulsar
        grid_sep = np.radians(fwhm * 0.6)
        rads, decds = get_grid(rar, decr, grid_sep, 1)

        #convert back to sexidecimals
        coord = SkyCoord(rads, decds, unit=(u.deg, u.deg))
        rajs = coord.ra.to_string(unit=u.hour, sep=':')
        decjs = coord.dec.to_string(unit=u.degree, sep=':')
        temp = []
        for raj, decj in zip(rajs, decjs):
            temp.append([raj, decj])
        pointing_list_list = fpio.format_ra_dec(temp, ra_col=0, dec_col=1)

        # sort the pointings into the right groups
        for prd in pointing_list_list:
            if vdif_check:
                vdif_name_list.append(jname_temp_list)
                vdif_pointing_list.append("{0} {1}".format(prd[0], prd[1]))
            elif sp_check:
                sp_name_list.append(jname_temp_list)
                sp_pointing_list.append("{0} {1}".format(prd[0], prd[1]))
            else:
                pulsar_name_list.append(jname_temp_list)
                pulsar_pointing_list.append("{0} {1}".format(prd[0], prd[1]))

    print('SENDING OFF PULSAR SEARCHS')
    # Send off pulsar search
    relaunch_script = 'mwa_search_pipeline.py -o {0} -O {1} --DI_dir {2} -b {3} -e {4} --channels'.format(
        obsid, cal_obs, DI_dir, psrbeg, psrend)
    for ch in channels:
        relaunch_script = "{0} {1}".format(relaunch_script, ch)
    search_opts = search_pipe.search_options_class(
        obsid,
        cal_id=cal_obs,
        begin=psrbeg,
        end=psrend,
        channels=channels,
        args=args,
        DI_dir=DI_dir,
        relaunch_script=relaunch_script,
        search_ver=mwa_search_version)
    search_pipe.beamform(search_opts,
                         pulsar_pointing_list,
                         pulsar_list_list=pulsar_name_list)

    print('SENDING OFF VDIF PULSAR SEARCHS')
    #Send off vdif pulsar search
    relaunch_script = "{0} --vdif".format(relaunch_script)
    search_opts = search_pipe.search_options_class(
        obsid,
        cal_id=cal_obs,
        begin=psrbeg,
        end=psrend,
        channels=channels,
        args=args,
        DI_dir=DI_dir,
        relaunch_script=relaunch_script,
        search_ver=mwa_search_version,
        vdif=True)
    search_pipe.beamform(search_opts,
                         vdif_pointing_list,
                         pulsar_list_list=vdif_name_list)

    #Get the rest of the singple pulse search canidates
    orig_names_ra_dec = fpio.grab_source_alog(source_type='RRATs',
                                              max_dm=250,
                                              include_dm=True)
    # remove any RRATs without at least arc minute accuracy
    names_ra_dec = np.array(
        [s for s in orig_names_ra_dec if (len(s[1]) > 4 and len(s[2]) > 4)])
    obs_data, meta_data = fpio.find_sources_in_obs([obsid],
                                                   names_ra_dec,
                                                   dt_input=100)

    for pulsar_line in obs_data[obsid]:
        jname = pulsar_line[0]
        for line in names_ra_dec:
            if jname == line[0]:
                jname, raj, decj, dm = line
        jname_temp_list = [jname]

        #convert to radians
        coord = SkyCoord(raj, decj, unit=(u.hourangle, u.deg))
        rar = coord.ra.radian  #in radians
        decr = coord.dec.radian

        #make a grid around each pulsar
        grid_sep = np.radians(fwhm * 0.6)
        rads, decds = get_grid(rar, decr, grid_sep, 1)

        #convert back to sexidecimals
        coord = SkyCoord(rads, decds, unit=(u.deg, u.deg))
        rajs = coord.ra.to_string(unit=u.hour, sep=':')
        decjs = coord.dec.to_string(unit=u.degree, sep=':')
        temp = []
        for raj, decj in zip(rajs, decjs):
            temp.append([raj, decj])
        pointing_list_list = fpio.format_ra_dec(temp, ra_col=0, dec_col=1)

        # sort the pointings into the right groups
        for prd in pointing_list_list:
            sp_name_list.append(jname_temp_list)
            sp_pointing_list.append("{0} {1}".format(prd[0], prd[1]))

    print('SENDING OFF SINGLE PULSE SEARCHS')
    # Send off pulsar search
    relaunch_script = 'mwa_search_pipeline.py -o {0} -O {1} --DI_dir {2} -b {3} -e {4} --single_pulse --channels'.format(
        obsid, cal_obs, DI_dir, psrbeg, psrend)
    for ch in channels:
        relaunch_script = "{0} {1}".format(relaunch_script, ch)
    search_opts = search_pipe.search_options_class(
        obsid,
        cal_id=cal_obs,
        begin=psrbeg,
        end=psrend,
        channels=channels,
        args=args,
        DI_dir=DI_dir,
        relaunch_script=relaunch_script,
        search_ver=mwa_search_version,
        single_pulse=True)
    search_pipe.beamform(search_opts,
                         sp_pointing_list,
                         pulsar_list_list=sp_name_list,
                         code_comment="Single pulse search")

    return
def submit_folds(obsid,
                 DI_dir,
                 cal_obs,
                 args,
                 psrbeg,
                 psrend,
                 product_dir='/group/mwaops/vcs',
                 mwa_search_version='master',
                 vcstools_version='master',
                 relaunch=False):
    """
    Beamforms on all pulsar locations in the obsid field between some time range. Launches search pipeline when done

    Parameters:
    -----------
    obsid: int
        The observation ID
    DI_dir: str
        The directory containing the Jones matrices solutions
    cal_obs:
        The calibration observation ID
    args: object
        The args object generated from argparse. Used for documentation purposes
    psrbeg: int
        The beginning of the observing time
    psrend: int
        The end of the observing time
    product_dir: string
        OPTIONAL - The base directory to store data products. Default = '/group/mwaops/vcs'
    mwa_search_version: string
        OPTIONAL - The version of mwas_search to use. Default = 'master'
    vcstools_version: string
        OPTIONAL - The version of vcstools to use. Default = 'master'
    """
    base_dir = os.path.join(product_dir, obsid, "pointings")
    nfiles = (psrend - psrbeg + 1) // 200
    if ((psrend - psrbeg + 1) % 200 != 0):
        nfiles += 1

    #Find all pulsars in beam at at least 0.3 of zenith normlaized power
    names_ra_dec = np.array(fpio.grab_source_alog(max_dm=250))
    pow_dict, meta_data = find_pulsars_power(obsid,
                                             powers=[0.3, 0.1],
                                             names_ra_dec=names_ra_dec)
    channels = meta_data[-1][-1]
    obs_psrs = pow_dict[0.3][obsid]
    psrs_list_03 = [x[0] for x in obs_psrs]
    #Include all bright pulsars in beam at at least 0.1 of zenith normalized power
    psrs_01 = [x[0] for x in pow_dict[0.1][obsid]]
    sn_dict_01 = snfe.multi_psr_snfe(psrs_01,
                                     obsid,
                                     beg=psrbeg,
                                     end=psrend,
                                     min_z_power=0.1)
    for psr in pow_dict[0.1][obsid]:
        if psr[0] not in psrs_list_03:
            sn, sn_err = sn_dict_01[psr[0]]
            if sn is not None and sn_err is not None:
                if sn - sn_err >= 10.:
                    obs_psrs.append(psr)

    #get all the pulsars periods
    pulsar_list = []
    for o in obs_psrs:
        pulsar_list.append(o[0])
    periods = psrqpy.QueryATNF(params=["P0"],
                               psrs=pulsar_list,
                               loadfromdb=ATNF_LOC).pandas["P0"]

    oap = get_obs_array_phase(obsid)
    centrefreq = 1.28 * float(min(channels) + max(channels)) / 2.
    fwhm = calc_ta_fwhm(centrefreq, array_phase=oap)

    # Sort all the sources into 3 categories, pulsars which is for slow pulsars, vdif
    # for fast pulsars that require vdif and sp for singple pulse searches (FRBs,
    # RRATs and pulsars without ATNF periods)
    pulsar_pointing_list = []
    pulsar_name_list = []
    vdif_pointing_list = []
    vdif_name_list = []
    sp_pointing_list = []
    sp_name_list = []
    for pi, pulsar_line in enumerate(obs_psrs):
        vdif_check = False
        sp_check = False

        PSRJ = pulsar_line[0]
        #See if pulsar is in beam for times
        enter, leave = snfe.pulsar_beam_coverage(obsid,
                                                 PSRJ,
                                                 beg=psrbeg,
                                                 end=psrend)
        if enter is None or leave is None:
            print(
                "{0} is not in beam for time range. Not folding".format(PSRJ))
            continue

        if not (len(PSRJ) < 11 or PSRJ[-1] == 'A' or PSRJ[-2:] == 'aa'):
            continue

        for line in names_ra_dec:
            if PSRJ == line[0]:
                temp = [line]

        #temp = fpio.get_psrcat_ra_dec(pulsar_list=[PSRJ])
        temp = fpio.format_ra_dec(temp, ra_col=1, dec_col=2)
        jname, raj, decj = temp[0]
        #get pulsar period
        period = periods[pi]
        if math.isnan(period):
            print(
                "WARNING: Period not found in ephermeris for {0} so assuming "
                "it's an RRAT".format(jname))
            sp_check = True
            period = 0.
        elif float(period) < .05:
            vdif_check = True
        period = float(period) * 1000.
        print(
            "{0:12} RA: {1} Dec: {2} Period: {3:8.2f} (ms) Begin {4} End {5}".
            format(PSRJ, raj, decj, period, psrbeg, psrend))

        jname_temp_list = []
        if PSRJ[-1] == 'A' or PSRJ[-2:] == 'aa':
            #Got to find all the pulsar J names with other letters
            vdif_check = True
            for pulsar_l in obs_psrs:
                pulsar_name = pulsar_l[0]
                if pulsar_name.startswith(PSRJ[:-2]):
                    jname_temp_list.append(pulsar_name)
        else:
            jname_temp_list.append(jname)

        # grid the pointings to fill 2 arcminute raduis to account for ionosphere shift
        pointing_list_list = get_pointings_required(raj, decj, fwhm, 2. / 60.)

        # sort the pointings into the right groups
        for prd in pointing_list_list:
            if vdif_check:
                vdif_name_list.append(jname_temp_list)
                vdif_pointing_list.append("{0}_{1}".format(prd[0], prd[1]))
            elif sp_check:
                sp_name_list.append(jname_temp_list)
                sp_pointing_list.append("{0}_{1}".format(prd[0], prd[1]))
            else:
                pulsar_name_list.append(jname_temp_list)
                pulsar_pointing_list.append("{0}_{1}".format(prd[0], prd[1]))

    print('\nSENDING OFF PULSAR PROCESSING')
    print(
        '----------------------------------------------------------------------------------------'
    )
    # Send off pulsar search
    relaunch_script = 'mwa_search_pipeline.py -o {0} -O {1} --DI_dir {2} -b {3} -e {4} --cand_type Pulsar --vcstools_version {5} --mwa_search_version {6} --channels'.format(
        obsid, cal_obs, DI_dir, psrbeg, psrend, vcstools_version,
        mwa_search_version)
    for ch in channels:
        relaunch_script = "{0} {1}".format(relaunch_script, ch)
    search_opts = search_pipe.search_options_class(
        obsid,
        cal_id=cal_obs,
        begin=psrbeg,
        end=psrend,
        channels=channels,
        args=args,
        DI_dir=DI_dir,
        relaunch_script=relaunch_script,
        search_ver=mwa_search_version,
        vcstools_ver=vcstools_version,
        data_process=True)
    pulsar_pointing_dirs = [
        os.path.join(base_dir, s) for s in pulsar_pointing_list
    ]
    for pdir in pulsar_pointing_dirs:
        # Check if fits files are there
        if len(glob.glob("{0}/{1}_*fits".format(pdir, obsid))) < nfiles:
            logger.error(
                "Can not find the {0} expected files in {1}. Exiting".format(
                    nfiles, pdir))
            sys.exit(1)
    for ppd, pnl in zip(pulsar_pointing_dirs, pulsar_name_list):
        for pulsar_name in pnl:
            # Not sure if this works with extended array obs with gridded pointings
            search_pipe.multibeam_binfind(search_opts, [ppd], None,
                                          pulsar_name)

    print('\nSENDING OFF VDIF PULSAR PROCESSING')
    print(
        '----------------------------------------------------------------------------------------'
    )
    #Send off vdif pulsar search
    relaunch_script = "{0} --vdif".format(relaunch_script)
    search_opts = search_pipe.search_options_class(
        obsid,
        cal_id=cal_obs,
        begin=psrbeg,
        end=psrend,
        channels=channels,
        args=args,
        DI_dir=DI_dir,
        relaunch_script=relaunch_script,
        search_ver=mwa_search_version,
        vcstools_ver=vcstools_version,
        vdif=True,
        data_process=True)
    vdif_pointing_dirs = [
        os.path.join(base_dir, s) for s in vdif_pointing_list
    ]
    for pdir in vdif_pointing_dirs:
        # Check if fits files are there
        if len(glob.glob("{0}/{1}_*fits".format(pdir, obsid))) < nfiles:
            print("Can not find the {0} expected files in {1}. Exiting".format(
                nfiles, pdir))
            sys.exit(1)
    for vpd, vnl in zip(vdif_pointing_dirs, vdif_name_list):
        for vdif_name in vnl:
            # Not sure if this works with extended array obs with gridded pointings
            search_pipe.multibeam_binfind(search_opts, [vpd], None, vdif_name)

    return