示例#1
0
def get_polgains_scan_cal2(i, n, scan, reference, sites, method, pad_amp,
                           caltable, show_solution, msgtype):

    if n > 1:
        global counter
        counter.increment()
        obsh.prog_msg(counter.value(), counter.maxval, msgtype,
                      counter.value() - 1)

    return polgains_cal_scan(scan,
                             reference,
                             sites,
                             method=method,
                             caltable=caltable,
                             show_solution=show_solution,
                             pad_amp=pad_amp,
                             msgtype=msgtype)
def get_selfcal_scan_cal2(i, n, scan, im, V_scan, sites, polrep, pol, method,
                          minimizer_method, show_solution, pad_amp, gain_tol,
                          caltable, debias, msgtype):
    if n > 1:
        global counter
        counter.increment()
        obsh.prog_msg(counter.value(), counter.maxval, msgtype,
                      counter.value() - 1)

    return self_cal_scan(scan,
                         im,
                         V_scan=V_scan,
                         sites=sites,
                         polrep=polrep,
                         pol=pol,
                         method=method,
                         minimizer_method=minimizer_method,
                         show_solution=show_solution,
                         pad_amp=pad_amp,
                         gain_tol=gain_tol,
                         caltable=caltable,
                         debias=debias)
示例#3
0
def get_network_scan_cal2(i, n, scan, zbl, sites, cluster_data, polrep, pol,
                          method, pad_amp, gain_tol, caltable, show_solution,
                          debias, msgtype):
    if n > 1:
        global counter
        counter.increment()
        obsh.prog_msg(counter.value(), counter.maxval, msgtype,
                      counter.value() - 1)

    return network_cal_scan(scan,
                            zbl,
                            sites,
                            cluster_data,
                            polrep=polrep,
                            pol=pol,
                            zbl_uvidst_max=ZBLCUTOFF,
                            method=method,
                            caltable=caltable,
                            show_solution=show_solution,
                            pad_amp=pad_amp,
                            gain_tol=gain_tol,
                            debias=debias)
示例#4
0
def polgains_cal(obs,
                 reference='AA',
                 sites=[],
                 method='phase',
                 minimizer_method='BFGS',
                 pad_amp=0.,
                 solution_interval=0.0,
                 scan_solutions=False,
                 caltable=False,
                 processes=-1,
                 show_solution=False,
                 msgtype='bar'):

    # TODO: function to globalize the polarimetric solution in time
    # given provided absolute calibration of the reference station
    # so that we have a meaningful EVPA
    """Polarimeteric-phase-gains-calibrate a dataset.
        Numerically solves for polarimetric gains to align RCP and LCP feeds.
        Uses all baselines to find the solution. Effectively assumes phase of Stokes V to be zero.
        Because fits are local, it's not providing absolute phase calibration.

       Args:
        obs (Obsdata): The observation to be calibrated
        reference (str): station used as reference to break the degeneracy
                         (LCP on baselines to the reference station remains unchanged)
        sites (list): list of sites to include in the polarimetric calibration.
                      Empty list calibrates all sites
        method (str): chooses what to calibrate, 'phase' or 'both'
                      'phase' is default, most useful (instrumental offsets),
                      'both' will align RCP/LCP amplitudes as well
        minimizer_method (str): Method for scipy.optimize.minimize (e.g., 'CG', 'BFGS')
        pad_amp (float): adds fractional uncertainty to amplitude sigmas in quadrature
        solution_interval (float): solution interval in seconds; one gain is derived per interval.
                                   If 0.0, a solution is determined for each unique time.
        scan_solutions (bool): If True, determine one gain per site per scan
                               Supersedes solution_interval.
        caltable (bool): if True, returns a Caltable instead of an Obsdata
        processes (int): number of cores to use in multiprocessing
        show_solution (bool): if True, display the solution as it is calculated
        msgtype (str): type of progress message to be printed, default is 'bar'

       Returns:
           (Obsdata): the calibrated observation, if caltable==False
           (Caltable): the derived calibration table, if caltable==True
    """
    # circular representation is needed
    if obs.polrep != 'circ':
        obs = obs.switch_polrep('circ')

    if len(sites) == 0:
        print("No stations specified in polgain cal!")
        print(
            'Defaulting to calibrating all stations with reference station as: '
            + reference)
        sites = np.array([x for x in obs.tarr['site'] if x != reference],
                         dtype='<U32')

    # get scans
    scans = obs.tlist(t_gather=solution_interval, scan_gather=scan_solutions)
    scans_cal = copy.copy(scans)

    # Make the pool for parallel processing
    if processes > 0:
        counter = parloop.Counter(initval=0, maxval=len(scans))
        if processes > len(scans):
            processes = len(scans)
        print("Using Multiprocessing with %d Processes" % processes)
        pool = Pool(processes=processes,
                    initializer=init,
                    initargs=(counter, ))
    elif processes == 0:
        counter = parloop.Counter(initval=0, maxval=len(scans))
        processes = int(cpu_count())
        if processes > len(scans):
            processes = len(scans)
        print("Using Multiprocessing with %d Processes" % processes)
        pool = Pool(processes=processes,
                    initializer=init,
                    initargs=(counter, ))
    else:
        print("Not Using Multiprocessing")

    # loop over scans and calibrate
    tstart = time.time()
    if processes > 0:  # with multiprocessing
        scans_cal = pool.map(get_polgains_scan_cal, [[
            i,
            len(scans), scans[i], reference, sites, method, pad_amp, caltable,
            show_solution, msgtype
        ] for i in range(len(scans))])

    else:  # without multiprocessing
        for i in range(len(scans)):
            obsh.prog_msg(i, len(scans), msgtype=msgtype, nscan_last=i - 1)
            scans_cal[i] = polgains_cal_scan(scans[i],
                                             reference,
                                             sites,
                                             method=method,
                                             minimizer_method=minimizer_method,
                                             show_solution=show_solution,
                                             caltable=caltable,
                                             pad_amp=pad_amp)

    tstop = time.time()
    print("\npolgain_cal time: %f s" % (tstop - tstart))

    if caltable:  # create and return  a caltable
        allsites = obs.tarr['site']
        caldict = {k: v.reshape(1) for k, v in scans_cal[0].items()}
        for i in range(1, len(scans_cal)):
            row = scans_cal[i]
            if len(row) == 0:
                continue

            for site in allsites:
                try:
                    dat = row[site]
                except KeyError:
                    continue

                try:
                    caldict[site] = np.append(caldict[site], row[site])
                except KeyError:
                    caldict[site] = [dat]

        caltable = ehtim.caltable.Caltable(obs.ra,
                                           obs.dec,
                                           obs.rf,
                                           obs.bw,
                                           caldict,
                                           obs.tarr,
                                           source=obs.source,
                                           mjd=obs.mjd,
                                           timetype=obs.timetype)
        out = caltable

    else:  # return the calibrated observation
        arglist, argdict = obs.obsdata_args()
        arglist[4] = np.concatenate(scans_cal)
        out = ehtim.obsdata.Obsdata(*arglist, **argdict)

    # close multiprocessing jobs
    if processes != -1:
        pool.close()

    return out
def self_cal(obs,
             im,
             sites=[],
             method="both",
             pol='I',
             minimizer_method='BFGS',
             pad_amp=0.,
             gain_tol=.2,
             solution_interval=0.0,
             scan_solutions=False,
             ttype='direct',
             fft_pad_factor=2,
             caltable=False,
             debias=True,
             copy_closure_tables=True,
             processes=-1,
             show_solution=False,
             msgtype='bar'):
    """Self-calibrate a dataset to an image.

       Args:
           obs (Obsdata): The observation to be calibrated
           im (Image): the image to be calibrated  to
           sites (list): list of sites to include in the self calibration.
                         empty list calibrates all sites
           method (str): chooses what to calibrate, 'amp', 'phase', or 'both'
           minimizer_method (str): Method for scipy.optimize.minimize (e.g., 'CG', 'BFGS')
           pol (str): which image polarization to self-calibrate visibilities to

           pad_amp (float): adds fractional uncertainty to amplitude sigmas in quadrature
           gain_tol (float or list): gains that exceed this value will be disfavored by the prior
                                     for asymmetric gain_tol for corrections below/above unity,
                                     pass a 2-element list
           solution_interval (float): solution interval in seconds;
                                      If 0., determine solution for each unique time
           scan_solutions (bool): If True, determine one gain per site per scan
                                  (supersedes solution_interval)

           caltable (bool): if True, returns a Caltable instead of an Obsdata
           processes (int): number of cores to use in multiprocessing

           ttype (str): if "fast" or "nfft" use FFT to produce visibilities. Else "direct" for DTFT
           fft_pad_factor (float): zero pad the image to fft_pad_factor * image size in FFT

           debias (bool): If True, debias the amplitudes
           show_solution (bool): if True, display the solution as it is calculated
           msgtype (str): type of progress message to be printed, default is 'bar'

       Returns:
           (Obsdata): the calibrated observation, if caltable==False
           (Caltable): the derived calibration table, if caltable==True
    """

    if pol not in ['I', 'Q', 'U', 'V', 'RR', 'LL']:
        raise Exception(
            "Can only self-calibrate to I, Q, U, V, RR, or LL images!")
    if pol in ['I', 'Q', 'U', 'V']:
        if obs.polrep != 'stokes':
            raise Exception(
                "selfcal pol is a stokes parameter, but obs.polrep!='stokes'")
        im = im.switch_polrep('stokes', pol)
    elif pol in ['RR', 'LL', 'RRLL']:
        if obs.polrep != 'circ':
            raise Exception("selfcal pol is RR or LL, but obs.polrep!='circ'")
        im = im.switch_polrep('circ', pol)

    # V = model visibility, V' = measured visibility, G_i = site gain
    # G_i * conj(G_j) * V_ij = V'_ij
    if len(sites) == 0:
        print(
            "No stations specified in self cal: defaulting to calibrating all stations!"
        )
        sites = obs.tarr['site']

    # First, sample the model visibilities of the specified polarization
    print("Computing the Model Visibilities with " + ttype +
          " Fourier Transform...")
    obs_clean = im.observe_same_nonoise(obs,
                                        ttype=ttype,
                                        fft_pad_factor=fft_pad_factor)

    # Partition the list of observed visibilities into scans
    scans = obs.tlist(t_gather=solution_interval, scan_gather=scan_solutions)
    scans_cal = copy.copy(scans)

    # Partition the list of model visibilities into scans
    V_scans = [
        o[ehc.vis_poldict[pol]]
        for o in obs_clean.tlist(t_gather=solution_interval,
                                 scan_gather=scan_solutions)
    ]

    # Make the pool for parallel processing
    if processes > 0:
        counter = parloop.Counter(initval=0, maxval=len(scans))
        print("Using Multiprocessing with %d Processes" % processes)
        pool = Pool(processes=processes,
                    initializer=init,
                    initargs=(counter, ))
    elif processes == 0:
        counter = parloop.Counter(initval=0, maxval=len(scans))
        processes = int(cpu_count())
        print("Using Multiprocessing with %d Processes" % processes)
        pool = Pool(processes=processes,
                    initializer=init,
                    initargs=(counter, ))
    else:
        print("Not Using Multiprocessing")

    # loop over scans and calibrate
    tstart = time.time()
    if processes > 0:  # run on multiple cores with multiprocessing
        scans_cal = np.array(
            pool.map(get_selfcal_scan_cal, [[
                i,
                len(scans), scans[i], im, V_scans[i], sites, obs.polrep, pol,
                method, minimizer_method, show_solution, pad_amp, gain_tol,
                caltable, debias, msgtype
            ] for i in range(len(scans))]))

    else:  # run on a single core
        for i in range(len(scans)):
            obsh.prog_msg(i, len(scans), msgtype=msgtype, nscan_last=i - 1)
            scans_cal[i] = self_cal_scan(scans[i],
                                         im,
                                         V_scan=V_scans[i],
                                         sites=sites,
                                         polrep=obs.polrep,
                                         pol=pol,
                                         method=method,
                                         minimizer_method=minimizer_method,
                                         show_solution=show_solution,
                                         debias=debias,
                                         pad_amp=pad_amp,
                                         gain_tol=gain_tol,
                                         caltable=caltable)

    tstop = time.time()
    print("\nself_cal time: %f s" % (tstop - tstart))

    if caltable:  # assemble the caltable to return
        allsites = obs.tarr['site']
        caldict = scans_cal[0]
        for i in range(1, len(scans_cal)):
            row = scans_cal[i]
            for site in allsites:
                try:
                    dat = row[site]
                except KeyError:
                    continue

                try:
                    caldict[site] = np.append(caldict[site], row[site])
                except KeyError:
                    caldict[site] = dat

        caltable = ehtim.caltable.Caltable(obs.ra,
                                           obs.dec,
                                           obs.rf,
                                           obs.bw,
                                           caldict,
                                           obs.tarr,
                                           source=obs.source,
                                           mjd=obs.mjd,
                                           timetype=obs.timetype)
        out = caltable

    else:  # return a calibrated observation
        arglist, argdict = obs.obsdata_args()
        arglist[4] = np.concatenate(scans_cal)
        out = ehtim.obsdata.Obsdata(*arglist, **argdict)
        if copy_closure_tables:
            out.camp = obs.camp
            out.logcamp = obs.logcamp
            out.cphase = obs.cphase

    # close multiprocessing jobs
    if processes >= 0:
        pool.close()

    return out
示例#6
0
def network_cal(obs,
                zbl,
                sites=[],
                zbl_uvdist_max=ZBLCUTOFF,
                method="amp",
                minimizer_method='BFGS',
                pol='I',
                pad_amp=0.,
                gain_tol=.2,
                solution_interval=0.0,
                scan_solutions=False,
                caltable=False,
                processes=-1,
                show_solution=False,
                debias=True,
                msgtype='bar'):
    """Network-calibrate a dataset with zero baseline constraints.

       Args:
           obs (Obsdata): The observation to be calibrated
           zbl (float or function): constant zero baseline flux in Jy, or a function of UT hour.
           sites (list): list of sites to include in the network calibration.
                         empty list calibrates all sites
           zbl_uvdist_max (float): maximum uv-distance considered a zero baseline
           method (str): chooses what to calibrate, 'amp', 'phase', or 'both'.
           minimizer_method (str): Method for scipy.optimize.minimize (e.g., 'CG', 'BFGS')
           pol (str): which visibility to compute gains for

           pad_amp (float): adds fractional uncertainty to amplitude sigmas in quadrature
           gain_tol (float): gains that exceed this value will be disfavored by the prior
           solution_interval (float): solution interval in seconds;
                                      one gain is derived for each interval.
                                      If 0.0, a solution is determined for each unique time
           scan_solutions (bool): If True, determine one gain per site per scan.
                                  Supersedes solution_interval

           debias (bool): If True, debias the amplitudes
           caltable (bool): if True, returns a Caltable instead of an Obsdata
           processes (int): number of cores to use in multiprocessing
           show_solution (bool): if True, display the solution as it is calculated
           msgtype (str): type of progress message to be printed, default is 'bar'

       Returns:
           (Obsdata): the calibrated observation, if caltable==False
           (Caltable): the derived calibration table, if caltable==True
    """

    # Here, RRLL means to use both RR and LL (both as proxies for Stokes I)
    # to derive a network calibration solution
    if pol not in ['I', 'Q', 'U', 'V', 'RR', 'LL', 'RRLL']:
        raise Exception(
            "Can only network-calibrate to I, Q, U, V, RR, LL, or RRLL!")
    if pol in ['I', 'Q', 'U', 'V']:
        if obs.polrep != 'stokes':
            raise Exception(
                "netcal pol is a stokes parameter, but obs.polrep!='stokes'")
        # obs = obs.switch_polrep('stokes',pol)
    elif pol in ['RR', 'LL', 'RRLL']:
        if obs.polrep != 'circ':
            raise Exception(
                "netcal pol is RR or LL or RRLL, but obs.polrep!='circ'")
        # obs = obs.switch_polrep('circ',pol)

    # V = model visibility, V' = measured visibility, G_i = site gain
    # G_i * conj(G_j) * V_ij = V'_ij
    if len(sites) == 0:
        print(
            "No stations specified in network cal: defaulting to calibrating all stations!"
        )
        sites = obs.tarr['site']

    # find colocated sites and put into list allclusters
    cluster_data = calh.make_cluster_data(obs, zbl_uvdist_max)

    # get scans
    scans = obs.tlist(t_gather=solution_interval, scan_gather=scan_solutions)
    scans_cal = copy.copy(scans)

    # Make the pool for parallel processing
    if processes > 0:
        counter = parloop.Counter(initval=0, maxval=len(scans))
        if processes > len(scans):
            processes = len(scans)
        print("Using Multiprocessing with %d Processes" % processes)
        pool = Pool(processes=processes,
                    initializer=init,
                    initargs=(counter, ))
    elif processes == 0:
        counter = parloop.Counter(initval=0, maxval=len(scans))
        processes = int(cpu_count())
        if processes > len(scans):
            processes = len(scans)
        print("Using Multiprocessing with %d Processes" % processes)
        pool = Pool(processes=processes,
                    initializer=init,
                    initargs=(counter, ))
    else:
        print("Not Using Multiprocessing")

    # loop over scans and calibrate
    tstart = time.time()
    if processes > 0:  # with multiprocessing
        scans_cal = pool.map(get_network_scan_cal, [[
            i,
            len(scans), scans[i], zbl, sites, cluster_data, obs.polrep, pol,
            method, pad_amp, gain_tol, caltable, show_solution, debias, msgtype
        ] for i in range(len(scans))])
    else:  # without multiprocessing
        for i in range(len(scans)):
            obsh.prog_msg(i, len(scans), msgtype=msgtype, nscan_last=i - 1)
            scans_cal[i] = network_cal_scan(scans[i],
                                            zbl,
                                            sites,
                                            cluster_data,
                                            polrep=obs.polrep,
                                            pol=pol,
                                            method=method,
                                            minimizer_method=minimizer_method,
                                            show_solution=show_solution,
                                            caltable=caltable,
                                            pad_amp=pad_amp,
                                            gain_tol=gain_tol,
                                            debias=debias)

    tstop = time.time()
    print("\nnetwork_cal time: %f s" % (tstop - tstart))

    if caltable:  # create and return  a caltable
        allsites = obs.tarr['site']
        caldict = {k: v.reshape(1) for k, v in scans_cal[0].items()}
        for i in range(1, len(scans_cal)):
            row = scans_cal[i]
            if len(row) == 0:
                continue

            for site in allsites:
                try:
                    dat = row[site]
                except KeyError:
                    continue

                try:
                    caldict[site] = np.append(caldict[site], row[site])
                except KeyError:
                    caldict[site] = [dat]

        caltable = ehtim.caltable.Caltable(obs.ra,
                                           obs.dec,
                                           obs.rf,
                                           obs.bw,
                                           caldict,
                                           obs.tarr,
                                           source=obs.source,
                                           mjd=obs.mjd,
                                           timetype=obs.timetype)
        out = caltable

    else:  # return the calibrated observation
        arglist, argdict = obs.obsdata_args()
        arglist[4] = np.concatenate(scans_cal)
        out = ehtim.obsdata.Obsdata(*arglist, **argdict)

    # close multiprocessing jobs
    if processes != -1:
        pool.close()

    return out