Single File Calibration¶

by Josh Dillon, Aaron Parsons, and Tyler Cox, last updated October 3, 2022

This notebook is designed to infer as much information about the array from a single file, including pushing the calibration and RFI mitigation as far as possible

Here's a set of links to skip to particular figures and tables:

• Figure 1: RFI Flagging¶

• Figure 2: Plot of autocorrelations with classifications¶

• Figure 3: Summary of antenna classifications prior to calibration¶

• Figure 4: Redundant calibration of a single baseline group¶

• Figure 5: chi^2 per antenna across the array¶

• Figure 6: Summary of antenna classifications after redundant calibration¶

• Table 1: Complete summary of per antenna classifications¶

In [1]:
import time
tstart = time.time()
In [2]:
import os
os.environ['HDF5_USE_FILE_LOCKING'] = 'FALSE'
import numpy as np
from scipy import constants, interpolate
import copy
import matplotlib
import matplotlib.pyplot as plt
import pandas as pd
pd.set_option('display.max_rows', 1000)
from uvtools.plot import plot_antpos, plot_antclass
from hera_qm import ant_metrics, ant_class, xrfi
from hera_cal import io, utils, redcal, apply_cal, datacontainer, abscal
from hera_notebook_templates.data import DATA_PATH as HNBT_DATA
from IPython.display import display, HTML
import linsolve
display(HTML("<style>.container { width:100% !important; }</style>"))
_ = np.seterr(all='ignore')  # get rid of red warnings
%config InlineBackend.figure_format = 'retina'
In [3]:
# this enables better memory management on linux
import ctypes
def malloc_trim():
    try:
        ctypes.CDLL('libc.so.6').malloc_trim(0) 
    except OSError:
        pass

Parse inputs and outputs¶

To use this notebook interactively, you will have to provide a sum filename path if none exists as an environment variable. All other parameters have reasonable default values.

In [4]:
# figure out whether to save results
SAVE_RESULTS = os.environ.get("SAVE_RESULTS", "TRUE").upper() == "TRUE"

# get infile names
SUM_FILE = os.environ.get("SUM_FILE", None)
# SUM_FILE = '/mnt/sn1/zen.2459797.30001.sum.uvh5'  # If sum_file is not defined in the environment variables, define it here.
DIFF_FILE = SUM_FILE.replace('sum', 'diff')

# get outfilenames
AM_FILE = (SUM_FILE.replace('.uvh5', '.ant_metrics.hdf5') if SAVE_RESULTS else None)
ANTCLASS_FILE = (SUM_FILE.replace('.uvh5', '.ant_class.csv') if SAVE_RESULTS else None)
OMNICAL_FILE = (SUM_FILE.replace('.uvh5', '.omni.calfits') if SAVE_RESULTS else None)
OMNIVIS_FILE = (SUM_FILE.replace('.uvh5', '.omni_vis.uvh5') if SAVE_RESULTS else None)

for fname in ['SUM_FILE', 'DIFF_FILE', 'AM_FILE', 'ANTCLASS_FILE', 'OMNICAL_FILE', 'OMNIVIS_FILE']:
    print(f"{fname} = '{eval(fname)}'")
SUM_FILE = '/mnt/sn1/2459886/zen.2459886.25252.sum.uvh5'
DIFF_FILE = '/mnt/sn1/2459886/zen.2459886.25252.diff.uvh5'
AM_FILE = '/mnt/sn1/2459886/zen.2459886.25252.sum.ant_metrics.hdf5'
ANTCLASS_FILE = '/mnt/sn1/2459886/zen.2459886.25252.sum.ant_class.csv'
OMNICAL_FILE = '/mnt/sn1/2459886/zen.2459886.25252.sum.omni.calfits'
OMNIVIS_FILE = '/mnt/sn1/2459886/zen.2459886.25252.sum.omni_vis.uvh5'

Parse settings¶

Load settings relating to the operation of the notebook, then print what was loaded (or default).

In [5]:
# parse plotting settings
PLOT = os.environ.get("PLOT", "TRUE").upper() == "TRUE"
if PLOT:
    %matplotlib inline

# parse omnical settings
OC_MAX_DIMS = int(os.environ.get("OC_MAX_DIMS", 4))
OC_MIN_DIM_SIZE = int(os.environ.get("OC_MIN_DIM_SIZE", 8))
OC_SKIP_OUTRIGGERS = os.environ.get("OC_SKIP_OUTRIGGERS", "TRUE").upper() == "TRUE"
OC_MAXITER = int(os.environ.get("OC_MAXITER", 50))
OC_MAX_RERUN = int(os.environ.get("OC_MAX_RERUN", 4))
OC_USE_GPU = os.environ.get("SAVE_RESULTS", "FALSE").upper() == "TRUE"

# parse RFI settings
RFI_DPSS_HALFWIDTH = float(os.environ.get("RFI_DPSS_HALFWIDTH", 300e-9))
RFI_NSIG = float(os.environ.get("RFI_NSIG", 6))

# print settings
for setting in ['PLOT', 'SAVE_RESULTS', 'OC_MAX_DIMS', 'OC_MIN_DIM_SIZE', 'OC_SKIP_OUTRIGGERS', 'OC_MAXITER', 'OC_MAX_RERUN',
                'OC_USE_GPU', 'RFI_DPSS_HALFWIDTH', 'RFI_NSIG']:
    print(f'{setting} = {eval(setting)}')
PLOT = True
SAVE_RESULTS = True
OC_MAX_DIMS = 4
OC_MIN_DIM_SIZE = 8
OC_SKIP_OUTRIGGERS = True
OC_MAXITER = 50
OC_MAX_RERUN = 4
OC_USE_GPU = False
RFI_DPSS_HALFWIDTH = 3e-07
RFI_NSIG = 6.0

Parse bounds¶

Load settings related to classifying antennas as good, suspect, or bad, then print what was loaded (or default).

In [6]:
# ant_metrics bounds for low correlation / dead antennas
am_corr_bad = (0, float(os.environ.get("AM_CORR_BAD", 0.3)))
am_corr_suspect = (float(os.environ.get("AM_CORR_BAD", 0.3)), float(os.environ.get("AM_CORR_SUSPECT", 0.5)))

# ant_metrics bounds for cross-polarized antennas
am_xpol_bad = (-1, float(os.environ.get("AM_XPOL_BAD", -0.1)))
am_xpol_suspect = (float(os.environ.get("AM_XPOL_BAD", -0.1)), float(os.environ.get("AM_XPOL_SUSPECT", 0)))

# bounds on zeros in spectra
good_zeros_per_eo_spectrum = (0, int(os.environ.get("MAX_ZEROS_PER_EO_SPEC_GOOD", 2)))
suspect_zeros_per_eo_spectrum = (0, int(os.environ.get("MAX_ZEROS_PER_EO_SPEC_SUSPECT", 8)))

# bounds on autocorrelation power
auto_power_good = (float(os.environ.get("AUTO_POWER_GOOD_LOW", 5)), float(os.environ.get("AUTO_POWER_GOOD_HIGH", 30)))
auto_power_suspect = (float(os.environ.get("AUTO_POWER_SUSPECT_LOW", 1)), float(os.environ.get("AUTO_POWER_SUSPECT_HIGH", 50)))

# bounds on autocorrelation slope
auto_slope_good = (float(os.environ.get("AUTO_SLOPE_GOOD_LOW", -0.4)), float(os.environ.get("AUTO_SLOPE_GOOD_HIGH", 0.4)))
auto_slope_suspect = (float(os.environ.get("AUTO_SLOPE_SUSPECT_LOW", -0.6)), float(os.environ.get("AUTO_SLOPE_SUSPECT_HIGH", 0.6)))

# bounds on autocorrelation RFI
auto_rfi_good = (0, float(os.environ.get("AUTO_RFI_GOOD", 0.01)))
auto_rfi_suspect = (0, float(os.environ.get("AUTO_RFI_SUSPECT", 0.02)))

# bounds on autocorrelation shape
auto_shape_good = (0, float(os.environ.get("AUTO_SHAPE_GOOD", 0.0625)))
auto_shape_suspect = (0, float(os.environ.get("AUTO_SHAPE_SUSPECT", 0.125)))

# bounds on chi^2 per antenna in omnical
oc_cspa_good = (0, float(os.environ.get("OC_CSPA_GOOD", 3)))
oc_cspa_suspect = (float(os.environ.get("OC_CSPA_GOOD", 3)), float(os.environ.get("OC_CSPA_SUSPECT", 6)))

# print bounds
for bound in ['am_corr_bad', 'am_corr_suspect', 'am_xpol_bad', 'am_xpol_suspect', 
              'good_zeros_per_eo_spectrum', 'suspect_zeros_per_eo_spectrum',
              'auto_power_good', 'auto_power_suspect', 'auto_slope_good', 'auto_slope_suspect',
              'auto_rfi_good', 'auto_rfi_suspect', 'auto_shape_good', 'auto_shape_suspect',
              'oc_cspa_good', 'oc_cspa_suspect']:
    print(f'{bound} = {eval(bound)}')
am_corr_bad = (0, 0.2)
am_corr_suspect = (0.2, 0.4)
am_xpol_bad = (-1, -0.1)
am_xpol_suspect = (-0.1, 0.0)
good_zeros_per_eo_spectrum = (0, 2)
suspect_zeros_per_eo_spectrum = (0, 8)
auto_power_good = (5.0, 30.0)
auto_power_suspect = (1.0, 50.0)
auto_slope_good = (-0.4, 0.4)
auto_slope_suspect = (-0.6, 0.6)
auto_rfi_good = (0, 0.01)
auto_rfi_suspect = (0, 0.02)
auto_shape_good = (0, 0.0625)
auto_shape_suspect = (0, 0.125)
oc_cspa_good = (0, 3.0)
oc_cspa_suspect = (3.0, 6.0)

Load sum and diff data¶

In [7]:
hd = io.HERADataFastReader(SUM_FILE)
data, _, _ = hd.read(read_flags=False, read_nsamples=False)
hd_diff = io.HERADataFastReader(DIFF_FILE)
diff_data, _, _ = hd_diff.read(read_flags=False, read_nsamples=False)
In [8]:
ants = sorted(set([ant for bl in hd.bls for ant in utils.split_bl(bl)]))
auto_bls = [bl for bl in data if (bl[0] == bl[1]) and (utils.split_pol(bl[2])[0] == utils.split_pol(bl[2])[1])]
antpols = sorted(set([ant[1] for ant in ants]))
In [9]:
# print basic information about the file
print(f'File: {SUM_FILE}')
print(f'JDs: {hd.times} ({np.median(np.diff(hd.times)) * 24 * 3600:.5f} s integrations)')
print(f'LSTS: {hd.lsts * 12 / np.pi } hours')
print(f'Frequencies: {len(hd.freqs)} {np.median(np.diff(hd.freqs)) / 1e6:.5f} MHz channels from {hd.freqs[0] / 1e6:.5f} to {hd.freqs[-1] / 1e6:.5f} MHz')
print(f'Antennas: {len(hd.data_ants)}')
print(f'Polarizations: {hd.pols}')
File: /mnt/sn1/2459886/zen.2459886.25252.sum.uvh5
JDs: [2459886.25246065 2459886.2525725 ] (9.66368 s integrations)
LSTS: [22.28699901 22.28969072] hours
Frequencies: 1536 0.12207 MHz channels from 46.92078 to 234.29871 MHz
Antennas: 201
Polarizations: ['nn', 'ee', 'ne', 'en']

Classify good, suspect, and bad antpols¶

Run ant_metrics¶

This classifies antennas as cross-polarized, low-correlation, or dead. Such antennas are excluded from any calibration.

In [10]:
am = ant_metrics.AntennaMetrics(SUM_FILE, DIFF_FILE, sum_data=data, diff_data=diff_data)
am.iterative_antenna_metrics_and_flagging(crossCut=am_xpol_bad[1], deadCut=am_corr_bad[1])
am.all_metrics = {}  # this saves time and disk by getting rid of per-iteration information we never use
if SAVE_RESULTS:
    am.save_antenna_metrics(AM_FILE, overwrite=True)
In [11]:
# Turn ant metrics into classifications
totally_dead_ants = [ant for ant, i in am.removal_iteration.items() if i == -1]
am_totally_dead = ant_class.AntennaClassification(good=[ant for ant in ants if ant not in totally_dead_ants], bad=totally_dead_ants)
am_corr = ant_class.antenna_bounds_checker(am.final_metrics['corr'], bad=[am_corr_bad], suspect=[am_corr_suspect], good=[(0, 1)])
am_xpol = ant_class.antenna_bounds_checker(am.final_metrics['corrXPol'], bad=[am_xpol_bad], suspect=[am_xpol_suspect], good=[(-1, 1)])
ant_metrics_class = am_totally_dead + am_corr + am_xpol

Classify antennas responsible for 0s in visibilities as bad:¶

This classifier looks for X-engine failure or packet loss specific to an antenna which causes either the even visibilities (or the odd ones, or both) to be 0s.

In [12]:
zeros_class = ant_class.even_odd_zeros_checker(data, diff_data, good=good_zeros_per_eo_spectrum, suspect=suspect_zeros_per_eo_spectrum)
In [13]:
# delete diffs to save memory
del diff_data, hd_diff
malloc_trim()

Examine and classify autocorrelation power, slope, and RFI occpancy¶

These classifiers look for antennas with too high or low power, to steep a slope, or too much excess RFI.

In [14]:
auto_power_class = ant_class.auto_power_checker(data, good=auto_power_good, suspect=auto_power_suspect)
auto_slope_class = ant_class.auto_slope_checker(data, good=auto_slope_good, suspect=auto_slope_suspect, edge_cut=100, filt_size=17)
cache = {}
auto_rfi_class = ant_class.auto_rfi_checker(data, good=auto_rfi_good, suspect=auto_rfi_suspect, 
                                            filter_half_widths=[RFI_DPSS_HALFWIDTH], nsig=RFI_NSIG, cache=cache)
auto_class = auto_power_class + auto_slope_class + auto_rfi_class
In [15]:
del cache
malloc_trim()

Find and flag RFI¶

In [16]:
# Compute int_count for all unflagged autocorrelations averaged together
int_time = 24 * 3600 * np.median(np.diff(data.times_by_bl[auto_bls[0][0:2]]))
chan_res = np.median(np.diff(data.freqs))
final_class = ant_metrics_class + zeros_class + auto_class
int_count = int(int_time * chan_res) * (len(final_class.good_ants) + len(final_class.suspect_ants))
avg_auto = {(-1, -1, 'ee'): np.mean([data[bl] for bl in auto_bls if final_class[utils.split_bl(bl)[0]] != 'bad'], axis=0)}
# Flag RFI first with channel differences and then with DPSS
antenna_flags, _ = xrfi.flag_autos(avg_auto, int_count=int_count, nsig=(RFI_NSIG * 5))
_, rfi_flags = xrfi.flag_autos(avg_auto, int_count=int_count, flag_method='dpss_flagger',
                               flags=antenna_flags, freqs=data.freqs, filter_centers=[0],
                               filter_half_widths=[RFI_DPSS_HALFWIDTH], eigenval_cutoff=[1e-9], nsig=RFI_NSIG)
malloc_trim()
In [17]:
def rfi_plot():
    plt.figure(figsize=(12, 5), dpi=100)
    plt.semilogy(hd.freqs / 1e6, np.where(rfi_flags, np.nan, avg_auto[(-1, -1, 'ee')])[1], label = 'Average Good or Suspect Autocorrelation', zorder=100)
    plt.semilogy(hd.freqs / 1e6, np.where(False, np.nan, avg_auto[(-1, -1, 'ee')])[1], 'r', lw=.5, label=f'{np.sum(rfi_flags[0])} Channels Flagged for RFI')
    plt.legend()
    plt.xlabel('Frequency (MHz)')
    plt.ylabel('Uncalibrated Autocorrelation')
    plt.tight_layout()

Figure 1: RFI Flagging¶

This figure shows RFI identified using the average of all autocorrelations---excluding bad antennas---for the first integration in the file.

In [18]:
rfi_plot()
In [19]:
def autocorr_plot(cls):    
    fig, axes = plt.subplots(1, 2, figsize=(14, 5), dpi=100, sharey=True, gridspec_kw={'wspace': 0})
    labels = []
    colors = ['darkgreen', 'goldenrod', 'maroon']
    for ax, pol in zip(axes, antpols):
        for ant in cls.ants:
            if ant[1] == pol:
                color = colors[cls.quality_classes.index(cls[ant])]
                ax.semilogy(np.mean(data[utils.join_bl(ant, ant)], axis=0), color=color, lw=.5)
        ax.set_xlabel('Channel', fontsize=12)
        ax.set_title(f'{utils.join_pol(pol, pol)}-Polarized Autos')

    axes[0].set_ylabel('Raw Autocorrelation', fontsize=12)
    axes[1].legend([matplotlib.lines.Line2D([0], [0], color=color) for color in colors], 
                   [cls.capitalize() for cls in auto_class.quality_classes], ncol=1, fontsize=12, loc='upper right', framealpha=1)
    plt.tight_layout()

Classify antennas based on shapes, excluding RFI-contamined channels¶

In [20]:
auto_shape_class = ant_class.auto_shape_checker(data, good=auto_shape_good, suspect=auto_shape_suspect,
                                                flag_spectrum=np.sum(rfi_flags, axis=0).astype(bool), antenna_class=final_class)
auto_class += auto_shape_class

Figure 2: Plot of autocorrelations with classifications¶

This figure shows a plot of all autocorrelations in the array, split by polarization. Antennas are classified based on their autocorrelations into good, suspect, and bad, by examining power, slope, and RFI-occupancy.

In [21]:
if PLOT: autocorr_plot(auto_class)

Summarize antenna classification prior to redundant-baseline calibration¶

In [22]:
final_class = ant_metrics_class + zeros_class + auto_class
In [23]:
def array_class_plot(cls):
    fig, axes = plt.subplots(1, 2, figsize=(14, 6), dpi=100, gridspec_kw={'width_ratios': [2, 1]})
    plot_antclass(hd.antpos, cls, ax=axes[0], ants=[ant for ant in hd.data_ants if ant < 320], legend=False, title='HERA Core')
    plot_antclass(hd.antpos, cls, ax=axes[1], ants=[ant for ant in hd.data_ants if ant >= 320], radius=50, title='Outriggers')

Figure 3: Summary of antenna classifications prior to calibration¶

This figure shows the location and classification of all antennas prior to calibration. Antennas are split along the diagonal, with ee-polarized antpols represented by the southeast half of each antenna and nn-polarized antpols represented by the northwest half. Outriggers are split from the core and shown at exaggerated size in the right-hand panel. This classification includes ant_metrics, a count of the zeros in the even or odd visibilities, and autocorrelation power, slope, and RFI occupancy. An antenna classified as bad in any classification will be considered bad. An antenna marked as suspect any in any classification will be considered suspect unless it is also classified as bad elsewhere.

In [24]:
if PLOT: array_class_plot(final_class)

Perform redundant-baseline calibration¶

In [25]:
def classify_off_grid(reds, all_ants):
    '''Returns AntennaClassification of all_ants where good ants are in reds while bad ants are not.'''
    ants_in_reds = set([ant for red in reds for bl in red for ant in utils.split_bl(bl)])
    on_grid = [ant for ant in all_ants if ant in ants_in_reds]
    off_grid = [ant for ant in all_ants if ant not in ants_in_reds]
    return ant_class.AntennaClassification(good=on_grid, bad=off_grid)

Perform iterative redcal¶

In [26]:
redcal_start = time.time()
rc_settings = {'max_dims': OC_MAX_DIMS, 'oc_conv_crit': 1e-10, 'gain': 0.4, 
               'oc_maxiter': OC_MAXITER, 'check_after': OC_MAXITER, 'use_gpu': OC_USE_GPU}

# figure out and filter reds and classify antennas based on whether or not they are on the main grid
reds = redcal.get_reds(hd.data_antpos, pols=['ee', 'nn'], pol_mode='2pol')
reds = redcal.filter_reds(reds, ex_ants=final_class.bad_ants, max_dims=OC_MAX_DIMS, min_dim_size=OC_MIN_DIM_SIZE)
if OC_SKIP_OUTRIGGERS:
    reds = redcal.filter_reds(reds, ex_ants=[ant for ant in ants if ant[0] >= 320])
redcal_class = classify_off_grid(reds, ants)

# perform first stage of redundant calibration, 
cal = redcal.redundantly_calibrate(data, reds, **rc_settings)
malloc_trim()
max_dly = np.max(np.abs(list(cal['fc_meta']['dlys'].values())))
med_cspa = {ant: np.median(cal['chisq_per_ant'][ant]) for ant in cal['chisq_per_ant']}
cspa_class = ant_class.antenna_bounds_checker(med_cspa, good=np.array(oc_cspa_good)*5, suspect=np.array(oc_cspa_suspect)*5, bad=(0, np.inf))
redcal_class += cspa_class
print(f'Removing {cspa_class.bad_ants} for high chi^2.')

# iteratively rerun redundant calibration
for i in range(OC_MAX_RERUN):
    # build RedDataContainer of old visibility solution
    prior_vis = datacontainer.RedDataContainer(cal['v_omnical'], reds)
    
    # refilter reds and update classification to reflect new off-grid ants, if any
    reds = redcal.filter_reds(reds, ex_ants=(final_class + redcal_class).bad_ants, max_dims=OC_MAX_DIMS, min_dim_size=OC_MIN_DIM_SIZE)
    reds = sorted(reds, key=len, reverse=True)
    redcal_class += classify_off_grid(reds, ants)
    ants_in_reds = set([ant for red in reds for bl in red for ant in utils.split_bl(bl)])    
   
    # re-run redundant calibration using previous solution, updating bad and suspicious antennas
    prior_sol = redcal.RedSol(reds, gains={ant: cal['g_omnical'][ant] for ant in ants_in_reds}, 
                              vis={red[0]: prior_vis[red[0]] for red in reds})    
    cal = redcal.redundantly_calibrate(data, reds, prior_firstcal=prior_sol.gains, prior_sol=prior_sol, **rc_settings)
    malloc_trim()
    med_cspa = {ant: np.median(cal['chisq_per_ant'][ant]) for ant in cal['chisq_per_ant']}
    cspa_class = ant_class.antenna_bounds_checker(med_cspa, good=oc_cspa_good, suspect=oc_cspa_suspect, bad=(0, np.inf))
    redcal_class += cspa_class
    print(f'Removing {cspa_class.bad_ants} for high chi^2.')
    if len(cspa_class.bad_ants) == 0:
        break  # no new antennas to flag
final_class += redcal_class
print(f'Finished redcal in {(time.time() - redcal_start) / 60:.2f} minutes.')
Removing {(55, 'Jee'), (44, 'Jnn'), (110, 'Jee'), (189, 'Jnn'), (72, 'Jnn'), (42, 'Jee'), (163, 'Jee'), (68, 'Jee'), (46, 'Jee'), (125, 'Jnn'), (191, 'Jnn'), (189, 'Jee'), (84, 'Jee'), (74, 'Jnn'), (61, 'Jnn'), (85, 'Jnn'), (129, 'Jnn'), (206, 'Jnn'), (72, 'Jee'), (10, 'Jnn'), (4, 'Jee'), (59, 'Jee'), (70, 'Jee'), (125, 'Jee'), (191, 'Jee'), (19, 'Jee'), (30, 'Jee'), (85, 'Jee'), (129, 'Jee'), (140, 'Jee'), (91, 'Jnn'), (102, 'Jnn'), (157, 'Jnn'), (168, 'Jnn'), (223, 'Jnn'), (51, 'Jnn'), (21, 'Jee'), (142, 'Jee'), (221, 'Jee'), (91, 'Jee'), (102, 'Jee'), (157, 'Jee'), (168, 'Jee'), (181, 'Jee'), (40, 'Jnn'), (119, 'Jnn'), (185, 'Jnn'), (38, 'Jee'), (49, 'Jee'), (159, 'Jee'), (53, 'Jee'), (42, 'Jnn'), (121, 'Jnn'), (108, 'Jnn'), (187, 'Jnn'), (242, 'Jnn'), (81, 'Jnn'), (136, 'Jnn'), (202, 'Jnn'), (66, 'Jee'), (222, 'Jee'), (187, 'Jee'), (15, 'Jee'), (59, 'Jnn'), (70, 'Jnn'), (160, 'Jnn'), (138, 'Jnn'), (136, 'Jee'), (147, 'Jee'), (30, 'Jnn'), (164, 'Jnn'), (17, 'Jee'), (138, 'Jee'), (160, 'Jee'), (239, 'Jee'), (32, 'Jee'), (21, 'Jnn'), (155, 'Jnn'), (164, 'Jee'), (243, 'Jnn'), (47, 'Jnn'), (126, 'Jnn'), (181, 'Jnn'), (241, 'Jee'), (45, 'Jee'), (56, 'Jee'), (128, 'Jnn'), (139, 'Jnn'), (183, 'Jnn'), (7, 'Jee'), (128, 'Jee'), (139, 'Jee'), (207, 'Jee'), (66, 'Jnn'), (156, 'Jnn'), (222, 'Jnn'), (15, 'Jnn'), (9, 'Jee'), (130, 'Jee'), (158, 'Jnn'), (145, 'Jee'), (118, 'Jnn'), (83, 'Jnn'), (162, 'Jnn'), (37, 'Jee'), (158, 'Jee'), (41, 'Jee'), (52, 'Jee'), (118, 'Jee'), (241, 'Jnn'), (69, 'Jnn'), (34, 'Jnn'), (109, 'Jee'), (69, 'Jee'), (137, 'Jnn'), (135, 'Jee'), (7, 'Jnn'), (86, 'Jnn'), (73, 'Jnn'), (141, 'Jnn'), (207, 'Jnn'), (22, 'Jnn'), (16, 'Jee'), (137, 'Jee'), (205, 'Jnn'), (20, 'Jee'), (31, 'Jee'), (99, 'Jnn'), (86, 'Jee'), (165, 'Jnn'), (163, 'Jnn'), (35, 'Jnn'), (169, 'Jnn'), (205, 'Jee'), (44, 'Jee'), (165, 'Jee'), (105, 'Jnn'), (116, 'Jnn'), (127, 'Jnn'), (114, 'Jee'), (169, 'Jee'), (65, 'Jnn'), (50, 'Jee'), (61, 'Jee'), (105, 'Jee'), (127, 'Jee'), (206, 'Jee'), (10, 'Jee'), (65, 'Jee'), (144, 'Jnn'), (67, 'Jee'), (146, 'Jnn'), (144, 'Jee'), (223, 'Jee'), (106, 'Jnn'), (71, 'Jnn'), (93, 'Jee'), (148, 'Jee'), (146, 'Jee'), (40, 'Jee'), (106, 'Jee'), (185, 'Jee'), (161, 'Jee')} for high chi^2.
Removing {(9, 'Jnn'), (132, 'Jnn'), (112, 'Jnn'), (57, 'Jnn'), (114, 'Jnn'), (147, 'Jnn'), (48, 'Jnn'), (35, 'Jee'), (112, 'Jee'), (4, 'Jnn'), (37, 'Jnn'), (94, 'Jnn'), (48, 'Jee'), (81, 'Jee'), (17, 'Jnn'), (19, 'Jnn'), (41, 'Jnn'), (52, 'Jnn'), (83, 'Jee'), (116, 'Jee'), (100, 'Jnn'), (98, 'Jee'), (45, 'Jnn'), (67, 'Jnn'), (3, 'Jnn'), (36, 'Jnn'), (93, 'Jnn'), (148, 'Jnn'), (5, 'Jnn'), (100, 'Jee'), (111, 'Jee'), (36, 'Jee'), (170, 'Jnn'), (16, 'Jnn'), (38, 'Jnn'), (49, 'Jnn'), (82, 'Jnn'), (62, 'Jnn'), (20, 'Jnn'), (31, 'Jnn'), (53, 'Jnn'), (82, 'Jee'), (62, 'Jee'), (130, 'Jnn')} for high chi^2.
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In [26], line 35
     32 # re-run redundant calibration using previous solution, updating bad and suspicious antennas
     33 prior_sol = redcal.RedSol(reds, gains={ant: cal['g_omnical'][ant] for ant in ants_in_reds}, 
     34                           vis={red[0]: prior_vis[red[0]] for red in reds})    
---> 35 cal = redcal.redundantly_calibrate(data, reds, prior_firstcal=prior_sol.gains, prior_sol=prior_sol, **rc_settings)
     36 malloc_trim()
     37 med_cspa = {ant: np.median(cal['chisq_per_ant'][ant]) for ant in cal['chisq_per_ant']}

File ~/mambaforge/envs/RTP/lib/python3.10/site-packages/hera_cal/redcal.py:1682, in redundantly_calibrate(data, reds, freqs, times_by_bl, oc_conv_crit, oc_maxiter, check_every, check_after, gain, max_dims, prior_firstcal, prior_sol, use_gpu)
   1680 dts_by_bl = DataContainer({bl: infer_dt(times_by_bl, bl, default_dt=SEC_PER_DAY**-1) * SEC_PER_DAY for bl in red_bls})
   1681 data_wgts = DataContainer({bl: predict_noise_variance_from_autos(bl, data, dt=dts_by_bl[bl])**-1 for bl in red_bls})
-> 1682 rv['omni_meta'], omni_sol = rc.omnical(data, prior_sol, wgts=data_wgts, conv_crit=oc_conv_crit, maxiter=oc_maxiter,
   1683                                        check_every=check_every, check_after=check_after, gain=gain)
   1685 # update omnical flags and then remove degeneracies
   1686 rv['g_omnical'], rv['v_omnical'] = get_gains_and_vis_from_sol(omni_sol)

File ~/mambaforge/envs/RTP/lib/python3.10/site-packages/hera_cal/redcal.py:1184, in RedundantCalibrator.omnical(self, data, sol0, wgts, gain, conv_crit, maxiter, check_every, check_after, wgt_func)
   1182 sol0 = {self.pack_sol_key(k): sol0[k] for k in sol0}
   1183 ls = self._solver(OmnicalSolver, data, sol0=sol0, wgts=wgts, gain=gain)
-> 1184 meta, sol = ls.solve_iteratively(conv_crit=conv_crit, maxiter=maxiter, check_every=check_every, check_after=check_after, wgt_func=wgt_func)
   1185 sol = RedSol(self.reds, sol_dict={self.unpack_sol_key(k): sol[k] for k in sol.keys()})
   1186 return meta, sol

File ~/mambaforge/envs/RTP/lib/python3.10/site-packages/hera_cal/redcal.py:764, in OmnicalSolver.solve_iteratively(self, conv_crit, maxiter, check_every, check_after, wgt_func, verbose)
    762 clamp_wgts_u = {k: v * wgt_func(abs2_u[k]) for k, v in wgts_u.items()}
    763 sol_u = {k: v[update].flatten() for k, v in sol.items()}
--> 764 iters = np.zeros(chisq.shape, dtype=int)
    765 conv = np.ones_like(chisq)
    766 for i in range(1, maxiter + 1):

AttributeError: 'int' object has no attribute 'shape'

Fix the firstcal delay slope degeneracy using RFI transmitters¶

In [27]:
# find channels clearly contaminated by RFI
not_bad_ants = [ant for ant in final_class.ants if final_class[ant] != 'bad']
chan_flags = np.mean([xrfi.detrend_medfilt(data[utils.join_bl(ant, ant)], Kf=8, Kt=2) for ant in not_bad_ants], axis=(0, 1)) > 5

# hardcoded RFI transmitters and their headings
# channel: frequency (Hz), heading (rad), chi^2
phs_sol = {359: ( 90744018.5546875, 0.7853981, 23.3),
           360: ( 90866088.8671875, 0.7853981, 10.8),
           385: ( 93917846.6796875, 0.7853981, 27.3),
           386: ( 94039916.9921875, 0.7853981, 18.1),
           400: ( 95748901.3671875, 6.0632738, 24.0),
           441: (100753784.1796875, 0.7853981, 21.7),
           442: (100875854.4921875, 0.7853981, 19.4),
           455: (102462768.5546875, 6.0632738, 18.8),
           456: (102584838.8671875, 6.0632738,  8.8),
           471: (104415893.5546875, 0.7853981, 13.3),
           484: (106002807.6171875, 6.0632738, 21.2),
           485: (106124877.9296875, 6.0632738,  4.0),
          1181: (191085815.4296875, 0.7853981, 26.3),
          1182: (191207885.7421875, 0.7853981, 27.0),
          1183: (191329956.0546875, 0.7853981, 25.6),
          1448: (223678588.8671875, 2.6075219, 25.7),
          1449: (223800659.1796875, 2.6075219, 22.6),
          1450: (223922729.4921875, 2.6075219, 11.6),
          1451: (224044799.8046875, 2.6075219,  5.9),
          1452: (224166870.1171875, 2.6075219, 22.6),
          1510: (231246948.2421875, 0.1068141, 23.9)}
rfi_chans = [chan for chan in phs_sol if chan_flags[chan]]
print('Channels used for delay-slope calibration with RFI:', rfi_chans)
rfi_angles = np.array([phs_sol[chan][1] for chan in rfi_chans])
rfi_headings = np.array([np.cos(rfi_angles), np.sin(rfi_angles), np.zeros_like(rfi_angles)])
rfi_chisqs = np.array([phs_sol[chan][2] for chan in rfi_chans])
Channels used for delay-slope calibration with RFI: [359, 360, 385, 386, 400, 441, 455, 456, 471, 485]
In [28]:
# resolve firstcal degeneracy with delay slopes set by RFI transmitters, update cal
RFI_dly_slope_gains = abscal.RFI_delay_slope_cal(reds, hd.antpos, cal['v_omnical'], hd.freqs, rfi_chans, rfi_headings, rfi_wgts=rfi_chisqs**-.5,
                                                 min_tau=-max_dly, max_tau=max_dly, delta_tau=0.1e-9, return_gains=True, gain_ants=cal['g_omnical'].keys())
cal['g_omnical'] = {ant: g * RFI_dly_slope_gains[ant] for ant, g in cal['g_omnical'].items()}
apply_cal.calibrate_in_place(cal['v_omnical'], RFI_dly_slope_gains)
malloc_trim()
---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
Cell In [28], line 2
      1 # resolve firstcal degeneracy with delay slopes set by RFI transmitters, update cal
----> 2 RFI_dly_slope_gains = abscal.RFI_delay_slope_cal(reds, hd.antpos, cal['v_omnical'], hd.freqs, rfi_chans, rfi_headings, rfi_wgts=rfi_chisqs**-.5,
      3                                                  min_tau=-max_dly, max_tau=max_dly, delta_tau=0.1e-9, return_gains=True, gain_ants=cal['g_omnical'].keys())
      4 cal['g_omnical'] = {ant: g * RFI_dly_slope_gains[ant] for ant, g in cal['g_omnical'].items()}
      5 apply_cal.calibrate_in_place(cal['v_omnical'], RFI_dly_slope_gains)

File ~/mambaforge/envs/RTP/lib/python3.10/site-packages/hera_cal/abscal.py:933, in RFI_delay_slope_cal(reds, antpos, red_data, freqs, rfi_chans, rfi_headings, rfi_wgts, min_tau, max_tau, delta_tau, return_gains, gain_ants)
    931 # check that reds are 1pol or 2pol
    932 if redcal.parse_pol_mode(reds) not in ['1pol', '2pol']:
--> 933     raise NotImplementedError('RFI_delay_slope_cal cannot currently handle 4pol calibration.')
    935 # compute unique baseline vectors and idealized baseline vectors if desired
    936 unique_blvecs = {red[0]: np.mean([antpos[bl[1]] - antpos[bl[0]] for bl in red], axis=0) for red in reds}

NotImplementedError: RFI_delay_slope_cal cannot currently handle 4pol calibration.

Perform approximate absolute amplitude calibration using a model of autocorrelations¶

In [29]:
# Load simulated and then downsampled model of autocorrelations that includes receiver noise, then interpolate to upsample
hd_model = io.HERADataFastReader(f'{HNBT_DATA}/SSM_autocorrelations_downsampled.uvh5')
model, _, _ = hd_model.read(read_flags=False, read_nsamples=False)
per_pol_interpolated_model = {}
for bl in model:
    sorted_lsts, lst_indices = np.unique(model.lsts, return_index=True)
    periodic_model = np.vstack([model[bl][lst_indices, :], model[bl][lst_indices[0], :]])
    periodic_lsts = np.append(sorted_lsts, sorted_lsts[0] + 2 * np.pi)
    lst_interpolated = interpolate.CubicSpline(periodic_lsts, periodic_model, axis=0, bc_type='periodic')(data.lsts)
    per_pol_interpolated_model[bl[2]] = interpolate.CubicSpline(model.freqs, lst_interpolated, axis=1)(data.freqs)
model = {bl: per_pol_interpolated_model[bl[2]] for bl in auto_bls if utils.split_bl(bl)[0] not in final_class.bad_ants}    
In [30]:
# Run abscal and update omnical gains with abscal gains
redcaled_autos = datacontainer.DataContainer({bl: np.array(data[bl]) for bl in auto_bls if utils.split_bl(bl)[0] not in final_class.bad_ants})
apply_cal.calibrate_in_place(redcaled_autos, cal['g_omnical'])
g_abscal = abscal.abs_amp_lincal(model, redcaled_autos, verbose=False, return_gains=True, gain_ants=cal['g_omnical'])
cal['g_omnical'] = {ant: g * g_abscal[ant] for ant, g in cal['g_omnical'].items()}
apply_cal.calibrate_in_place(cal['v_omnical'], g_abscal)
In [31]:
del hd_model, model, redcaled_autos
malloc_trim()
In [32]:
def redundant_group_plot():
    fig, axes = plt.subplots(2, 2, figsize=(14, 6), dpi=100, sharex='col', sharey='row', gridspec_kw={'hspace': 0, 'wspace': 0})
    for i, pol in enumerate(['ee', 'nn']):
        reds_here = redcal.get_reds(hd.data_antpos, pols=[pol], pol_mode='1pol')
        red = sorted(redcal.filter_reds(reds_here, ex_ants=final_class.bad_ants), key=len, reverse=True)[0]
        rc_data = {bl: np.array(data[bl]) for bl in red}
        apply_cal.calibrate_in_place(rc_data, cal['g_omnical'])
        for bl in red:
            axes[0, i].plot(hd.freqs/1e6, np.angle(rc_data[bl][0]), alpha=.5, lw=.5)
            axes[1, i].semilogy(hd.freqs/1e6, np.abs(rc_data[bl][0]), alpha=.5, lw=.5)
        axes[0, i].plot(hd.freqs / 1e6, np.angle(cal['v_omnical'][red[0]][0]), lw=1, c='k')
        axes[1, i].semilogy(hd.freqs / 1e6, np.abs(cal['v_omnical'][red[0]][0]), lw=1, c='k', label=f'Baseline Group:\n{red[0]}')
        axes[1, i].set_xlabel('Frequency (MHz)')
        axes[1, i].legend(loc='upper right')
    axes[0, 0].set_ylabel('Visibility Phase (radians)')
    axes[1, 0].set_ylabel('Visibility Amplitude (Jy)')
    plt.tight_layout()

Figure 4: Redundant calibration of a single baseline group¶

The results of a redundant-baseline calibration of a single integration and a single group, the one with the highest redundancy in each polarization after antenna classification and excision based on the above, plus the removal of antennas with high chi^2 per antenna. The black line is the redundant visibility solution. Each thin colored line is a different baseline group. Phases are shown in the top row, amplitudes in the bottom, ee-polarized visibilities in the left column, and nn-polarized visibilities in the right.

In [33]:
if PLOT: redundant_group_plot()
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
File ~/mambaforge/envs/RTP/lib/python3.10/site-packages/hera_cal/datacontainer.py:112, in DataContainer.__getitem__(self, key)
    111 try:  # just see if the key works first
--> 112     return self._data[key]
    113 except(KeyError):

KeyError: (9, 10, 'ee')

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
File ~/mambaforge/envs/RTP/lib/python3.10/site-packages/hera_cal/datacontainer.py:121, in DataContainer.__getitem__(self, key)
    120 try:
--> 121     return self._data[bl]
    122 except(KeyError):

KeyError: (9, 10, 'ee')

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
File ~/mambaforge/envs/RTP/lib/python3.10/site-packages/hera_cal/datacontainer.py:124, in DataContainer.__getitem__(self, key)
    123 try:
--> 124     if np.iscomplexobj(self._data[reverse_bl(bl)]):
    125         return np.conj(self._data[reverse_bl(bl)])

KeyError: (10, 9, 'ee')

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
Cell In [33], line 1
----> 1 if PLOT: redundant_group_plot()

Cell In [32], line 11, in redundant_group_plot()
      9     axes[0, i].plot(hd.freqs/1e6, np.angle(rc_data[bl][0]), alpha=.5, lw=.5)
     10     axes[1, i].semilogy(hd.freqs/1e6, np.abs(rc_data[bl][0]), alpha=.5, lw=.5)
---> 11 axes[0, i].plot(hd.freqs / 1e6, np.angle(cal['v_omnical'][red[0]][0]), lw=1, c='k')
     12 axes[1, i].semilogy(hd.freqs / 1e6, np.abs(cal['v_omnical'][red[0]][0]), lw=1, c='k', label=f'Baseline Group:\n{red[0]}')
     13 axes[1, i].set_xlabel('Frequency (MHz)')

File ~/mambaforge/envs/RTP/lib/python3.10/site-packages/hera_cal/datacontainer.py:129, in DataContainer.__getitem__(self, key)
    127         return self._data[reverse_bl(bl)]
    128 except(KeyError):
--> 129     raise KeyError('Cannot find either {} or {} in this DataContainer.'.format(key, reverse_bl(key)))

KeyError: "Cannot find either (9, 10, 'ee') or (10, 9, 'ee') in this DataContainer."

Attempt to calibrate some flagged antennas¶

This attempts to calibrate bad antennas using information from good or suspect antennas without allowing bad antennas to affect their calibration. However antennas flagged for ant_metrics or lots of zeros in the even or odd visibilities are considered beyond saving. Likewise, some antennas would add extra degeneracies (controlled by OC_MAX_DIMS, OC_MIN_DIM_SIZE, and OC_SKIP_OUTRIGGERS) are excluded.

In [34]:
expand_start = time.time()
expanded_reds = redcal.get_reds(hd.data_antpos, pols=['ee', 'nn'], pol_mode='2pol')
expanded_reds = redcal.filter_reds(expanded_reds, ex_ants=(ant_metrics_class + zeros_class).bad_ants, max_dims=OC_MAX_DIMS, min_dim_size=OC_MIN_DIM_SIZE)
if OC_SKIP_OUTRIGGERS:
    expanded_reds = redcal.filter_reds(expanded_reds, ex_ants=[ant for ant in ants if ant[0] >= 320])
nsamples = datacontainer.DataContainer({bl: np.ones_like(data[bl], dtype=float) for bl in data})
redcal.expand_omni_sol(cal, expanded_reds, data, nsamples)
malloc_trim()
print(f'Finished expanding omni_sol in {(time.time() - expand_start) / 60:.2f} minutes.')
Finished expanding omni_sol in 3.54 minutes.
In [35]:
def array_chisq_plot():
    fig, axes = plt.subplots(1, 2, figsize=(14, 5), dpi=100)
    for ax, pol in zip(axes, ['ee', 'nn']):
        ants_to_plot = set([ant for ant in cal['chisq_per_ant'] if utils.join_pol(ant[1], ant[1]) == pol])
        cspas = [np.median(cal['chisq_per_ant'][ant]) for ant in ants_to_plot]
        xpos = [hd.antpos[ant[0]][0] for ant in ants_to_plot]
        ypos = [hd.antpos[ant[0]][1] for ant in ants_to_plot]
        scatter = ax.scatter(xpos, ypos, s=300, c=cspas, norm=matplotlib.colors.LogNorm(vmin=1, vmax=oc_cspa_suspect[1]))
        for ant in ants_to_plot:
            ax.text(hd.antpos[ant[0]][0], hd.antpos[ant[0]][1], ant[0], va='center', ha='center', fontsize=9,
                    c=('r' if ant in final_class.bad_ants else 'w'))
        plt.colorbar(scatter, ax=ax, extend='both')
        ax.axis('equal')
        ax.set_xlabel('East-West Position (meters)')
        ax.set_ylabel('North-South Position (meters)')
        ax.set_title(f'{pol}-pol $\\chi^2$ / Antenna (Red is Flagged)')
    plt.tight_layout()

Figure 5: chi^2 per antenna across the array¶

This plot shows median (taken over time and frequency) of the normalized chi^2 per antenna. The expectation value for this quantity when the array is perfectly redundant is 1.0. Antennas that are classified as bad for any reason have their numbers shown in red. Some of those antennas were classified as bad during redundant calibration for high chi^2. Some of those antennas were originally excluded from redundant calibration because they were classified as bad earlier for some reason. See here for more details. Note that the color scale saturates at below 1 and above 10.

In [36]:
if PLOT: array_chisq_plot()
In [37]:
def array_class_after_redcal_plot():
    fig, axes = plt.subplots(1, 2, figsize=(14, 6), dpi=100, gridspec_kw={'width_ratios': [2, 1]})
    plot_antclass(hd.antpos, final_class, ax=axes[0], ants=[ant for ant in hd.data_ants if ant < 320], legend=False, title='HERA Core, Post-Redcal')
    plot_antclass(hd.antpos, final_class, ax=axes[1], ants=[ant for ant in hd.data_ants if ant >= 320], radius=50, title='Outriggers')

Figure 6: Summary of antenna classifications after redundant calibration¶

This figure is the same as Figure 2, except that it now includes additional suspect or bad antennas based on redundant calibration. This can include antennas with high chi^2, but it can also include antennas classified as "bad" because they would add extra degeneracies to calibration.

In [38]:
if PLOT: array_class_after_redcal_plot()
In [39]:
to_show = {'Antenna': [f'{ant[0]}{ant[1][-1]}' for ant in ants]}
classes = {'Antenna': [final_class[ant] if ant in final_class else '-' for ant in ants]}
to_show['Dead?'] = [{'good': 'No', 'bad': 'Yes'}[am_totally_dead[ant]] if (ant in am_totally_dead) else '' for ant in ants]
classes['Dead?'] = [am_totally_dead[ant] if (ant in am_totally_dead) else '' for ant in ants]
for title, ac in [('Low Correlation', am_corr),
                  ('Cross-Polarized', am_xpol),
                  ('Even/Odd Zeros', zeros_class),
                  ('Autocorr Power', auto_power_class),
                  ('Autocorr Slope', auto_slope_class),
                  ('RFI in Autos', auto_rfi_class),
                  ('Autocorr Shape', auto_shape_class)]:
    to_show[title] = [f'{ac._data[ant]:.2G}' if (ant in ac._data) else '' for ant in ants]
    classes[title] = [ac[ant] if ant in ac else '' for ant in ants]
    
to_show['Redcal chi^2'] = [f'{np.median(cal["chisq_per_ant"][ant]):.3G}' if (ant in cal['chisq_per_ant']) else '-' for ant in ants]
classes['Redcal chi^2'] = [redcal_class[ant] if ant in redcal_class else '' for ant in ants]

df = pd.DataFrame(to_show)
df_classes = pd.DataFrame(classes)
colors = {'good': 'darkgreen', 'suspect': 'goldenrod', 'bad': 'maroon'}
df_colors = df_classes.applymap(lambda x: f'background-color: {colors.get(x, None)}')

table = df.style.hide_index() \
                .apply(lambda x: pd.DataFrame(df_colors.values, columns=x.columns), axis=None) \
                .set_properties(subset=['Antenna'], **{'font-weight': 'bold', 'border-right': "3pt solid black"}) \
                .set_properties(subset=df.columns[1:], **{'border-left': "1pt solid black"}) \
                .set_properties(**{'text-align': 'center', 'color': 'white'})

Table 1: Complete summary of per-antenna classifications¶

This table summarizes the results of the various classifications schemes detailed above. As before, green is good, yellow is suspect, and red is bad. The color for each antenna (first column) is the final summary of all other classifications. Antennas missing from redcal $\chi^2$ were excluded redundant-baseline calibration, either because they were flagged by ant_metrics or the even/odd zeros check, or because they would add unwanted extra degeneracies.

In [40]:
HTML(table.render())
Out[40]:
Antenna Dead? Low Correlation Cross-Polarized Even/Odd Zeros Autocorr Power Autocorr Slope RFI in Autos Autocorr Shape Redcal chi^2
3e No 0.043 0.77 0 2.3 0.54 0.029 0.19 -
3n No 0.93 0.77 0 39 -0.15 0 0.028 19.1
4e No 0.95 0.093 0 20 -0.2 0.00098 0.025 -2.83E-14
4n No 0.93 0.093 0 27 -0.15 0 0.024 17.7
5e No 0.94 0.094 1 39 -0.14 0.028 0.03 278
5n No 0.92 0.094 0 43 -0.2 0 0.023 22.9
7e No 0.93 0.094 0 15 -0.26 0.0026 0.039 192
7n No 0.92 0.094 0 18 -0.33 0.00098 0.039 53.3
8e No 0.91 0.11 0 58 -0.05 0.029 0.052 319
8n No 0.88 0.11 0 64 -0.066 0 0.061 22.3
9e No 0.92 0.092 0 15 -0.26 0.002 0.049 363
9n No 0.91 0.092 0 15 -0.33 0.00033 0.049 23.9
10e No 0.91 0.095 0 27 -0.17 0.0033 0.021 324
10n No 0.9 0.095 0 23 -0.29 0.00065 0.032 67
15e No 0.95 0.075 0 8.1 -0.36 0.00098 0.077 125
15n No 0.94 0.075 0 14 -0.47 0.00033 0.087 53
16e No 0.95 0.076 0 18 -0.25 0.00065 0.037 2.75E-14
16n No 0.93 0.076 0 16 -0.33 0 0.038 20.3
17e No 0.94 0.083 0 15 -0.34 0.00033 0.056 368
17n No 0.93 0.083 0 16 -0.39 0.00065 0.066 21.7
18e No 0.94 0.19 0 16 -0.34 0.21 0.098 336
18n No 0.86 0.19 0 14 -0.37 0.31 0.16 18.1
19e No 0.93 0.088 0 21 -0.22 0.0013 0.029 98.3
19n No 0.92 0.088 0 30 -0.23 0.00033 0.014 20.3
20e No 0.93 0.089 0 17 -0.25 0.0016 0.035 579
20n No 0.92 0.089 0 30 -0.24 0.00033 0.016 21.1
21e No 0.92 0.084 0 18 -0.22 0.0023 0.035 397
21n No 0.91 0.084 0 18 -0.35 0.00065 0.052 112
22e No 0.87 0.084 0 15 0.48 0.0036 0.21 141
22n No 0.9 0.084 0 29 -0.22 0.00033 0.029 84.7
27e No 0.036 0.0063 1 0.68 0.51 0.08 0.18 -
27n No 0.042 0.0063 1 0.65 0.55 0.053 0.21 -
28e No 0.86 0.35 0 9.5 0.38 0.00065 0.14 31.8
28n No 0.63 0.35 1 11 0.56 0.25 0.32 10.8
29e No 0.95 0.82 0 12 -1.6 0.0013 0.42 750
29n No 0.044 0.82 0 0.71 0.56 0.015 0.21 -
30e No 0.94 0.07 0 20 -0.23 0 0.036 440
30n No 0.93 0.07 0 16 -0.39 0.00033 0.059 54.1
31e No 0.94 0.073 0 11 -0.42 0.00098 0.079 370
31n No 0.93 0.073 0 15 -0.35 0.00065 0.047 23.7
32e No 0.93 0.051 0 12 0.12 0.00065 0.098 -1.61E-15
32n No 0.92 0.051 0 17 0.4 0.00033 0.21 129
34e No 0.056 0.53 0 2.9 0.58 0.035 0.2 -
34n No 0.91 0.53 0 28 -0.17 0.00033 0.034 80.3
35e No 0.91 0.094 0 38 -0.1 0.00033 0.023 17.8
35n No 0.91 0.094 0 23 -0.24 0.00033 0.026 97.3
36e No 0.95 0.069 0 38 -0.33 0 0.067 17.6
36n No 0.95 0.069 0 40 -0.3 0.00033 0.045 23.1
37e No 0.95 0.058 0 19 -0.29 0.00065 0.052 58.5
37n No 0.95 0.058 0 13 -0.4 0 0.073 20.6
38e No 0.96 0.057 0 16 -0.29 0.00033 0.055 67.2
38n No 0.95 0.057 0 16 -0.36 0.00065 0.053 20.2
40e No 0.95 0.063 0 15 -0.32 0.0016 0.056 137
40n No 0.95 0.063 0 15 -0.36 0.00033 0.052 49.2
41e No 0.95 0.07 0 43 -0.14 0.00098 0.027 70.1
41n No 0.94 0.07 0 42 -0.13 0 0.028 20
42e No 0.95 0.063 0 16 -0.29 0.0013 0.05 38.2
42n No 0.95 0.063 0 14 -0.35 0.00065 0.048 70.7
43e No 0.053 0.48 0 0.7 0.48 0.049 0.18 -
43n No 0.82 0.48 0 9.5 1 0 0.32 66.6
44e No 0.94 0.065 0 14 -0.25 0.00033 0.046 392
44n No 0.94 0.065 0 16 -0.32 0 0.047 67.5
45e No 0.94 0.068 0 15 -0.35 0.00098 0.059 180
45n No 0.93 0.068 0 16 -0.34 0.00098 0.048 26.6
46e No 0.94 0.59 0 16 -0.3 0.002 0.046 583
46n No 0.076 0.59 0 0.65 0.58 0.1 0.21 -
47e No 0.044 0.52 0 3.1 0.55 0.031 0.19 -
47n No 0.92 0.52 0 25 -0.15 0.00033 0.035 82.5
48e No 0.91 0.085 0 37 -0.053 0.0013 0.033 14.1
48n No 0.91 0.085 0 43 -0.13 0.00065 0.034 28.9
49e No 0.91 0.1 0 21 -0.12 0.0026 0.027 134
49n No 0.91 0.1 0 39 -0.14 0.00033 0.029 27.3
50e No 0.95 0.056 0 38 -0.12 0 0.036 61.3
50n No 0.93 0.056 0 33 0.29 0.0016 0.18 92.5
51e No 0.1 0.65 0 1.2 0.66 0.15 0.21 -
51n No 0.95 0.65 0 22 -0.28 0.0091 0.039 36.4
52e No 0.95 0.062 0 39 -0.3 0 0.058 46.2
52n No 0.95 0.062 0 39 -0.3 0 0.044 19.2
53e No 0.95 0.065 0 41 -0.14 0 0.027 29.9
53n No 0.95 0.065 0 46 -0.21 0 0.034 23
54e No 0.071 -0.0015 0 0.68 0.51 0.056 0.18 -
54n No 0.072 -0.0015 0 0.62 0.58 0.017 0.22 -
55e No 0.95 0.66 0 16 -0.24 0 0.033 162
55n No 0.051 0.66 1 0.63 0.61 0.076 0.22 -
56e No 0.96 0.66 0 14 -0.3 0.00065 0.051 109
56n No 0.047 0.66 0 0.6 0.61 0.017 0.22 -
57e No 0.92 0.059 0 20 0.48 0.0046 0.21 7.98E-16
57n No 0.95 0.059 0 39 -0.13 0 0.035 19.8
58e No 0.92 0.063 0 49 0.29 0 0.15 250
58n No 0.93 0.063 0 57 -0.06 0.00033 0.055 30.6
59e No 0.94 0.061 0 16 -0.11 0.00033 0.03 312
59n No 0.94 0.061 0 12 -0.26 0.002 0.037 91.5
60e No 0.029 0.0019 1 0.69 0.53 0.059 0.19 -
60n No 0.028 0.0019 0 0.63 0.56 0.071 0.21 -
61e No 0.93 0.076 0 17 -0.1 0.00098 0.031 70
61n No 0.93 0.076 0 15 -0.21 0.00065 0.031 71.9
62e No 0.92 0.086 0 31 -0.081 0.0016 0.028 18.2
62n No 0.92 0.086 0 42 -0.15 0.00033 0.031 24.8
63e Yes 1.5E+03 0 0 0 INF -
63n Yes 1.5E+03 0 0 0 INF -
64e Yes 1.5E+03 0 0 0 INF -
64n Yes 1.5E+03 0 0 0 INF -
65e No 0.94 0.072 0 14 -0.33 0.00098 0.07 72.4
65n No 0.95 0.072 0 14 -0.42 0.00033 0.066 39.5
66e No 0.95 0.066 0 10 -0.51 0 0.11 107
66n No 0.95 0.066 0 11 -0.48 0 0.086 43.3
67e No 0.95 0.064 0 12 -0.37 0.00033 0.075 63.9
67n No 0.95 0.064 0 14 -0.4 0 0.063 19
68e No 0.95 0.7 0 15 -0.3 0.00033 0.056 60.5
68n No 0.075 0.7 1 0.27 1.1 0.19 0.33 -
69e No 0.95 0.057 0 15 -0.25 0.00065 0.046 24.9
69n No 0.95 0.057 0 15 -0.38 0 0.053 55.4
70e No 0.95 0.055 0 17 -0.25 0.00033 0.046 224
70n No 0.95 0.055 0 17 -0.32 0 0.056 52.4
71e No 0.96 0.054 0 14 -0.58 0.00065 0.13 184
71n No 0.95 0.054 0 14 -0.38 0.00065 0.055 64.2
72e No 0.96 0.052 0 14 -0.15 0.00033 0.041 97.5
72n No 0.95 0.052 0 14 -0.37 0.00065 0.049 61.7
73e No 0.95 0.064 0 55 -0.067 0.027 0.046 227
73n No 0.95 0.064 0 3.9 -0.56 0.013 0.11 100
74e No 0.94 0.069 0 61 -0.065 0.064 0.055 163
74n No 0.94 0.069 0 45 -0.13 0 0.037 38.8
77e No 0.89 0.046 0 32 0.41 0.0052 0.17 128
77n No 0.9 0.046 0 28 0.38 0.0068 0.18 154
78e Yes 1.5E+03 0 0 0 INF -
78n Yes 1.5E+03 0 0 0 INF -
79e No 0.91 0.1 0 55 -0.019 0 0.055 58.6
79n No 0.92 0.1 0 55 -0.058 0 0.058 34.7
80e No 0.82 0.54 0 50 0.37 0.0052 0.14 71.3
80n No 0.044 0.54 0 2.9 0.61 0.039 0.22 -
81e No 0.94 0.076 0 40 -0.12 0.00033 0.029 17.3
81n No 0.93 0.076 0 7.2 -0.13 0.018 0.039 43
82e No 0.94 0.076 0 38 -0.13 0 0.023 21.2
82n No 0.95 0.076 0 25 -0.24 0.00033 0.022 16.5
83e No 0.94 0.07 0 39 -0.13 0 0.026 14.2
83n No 0.95 0.07 0 40 -0.13 0 0.037 23
84e No 0.95 0.45 0 6 -0.55 0.014 0.12 113
84n No 0.075 0.45 0 0.27 0.95 0.12 0.32 -
85e No 0.95 0.061 0 16 -0.32 0.0013 0.054 60.6
85n No 0.95 0.061 0 15 -0.37 0.00065 0.05 51.1
86e No 0.95 0.056 0 9.5 -0.39 0.0026 0.072 38.6
86n No 0.95 0.056 0 12 -0.43 0.00065 0.068 59.9
87e No 0.92 0.066 0 56 0.28 0.0013 0.12 247
87n No 0.94 0.066 0 65 -0.13 0 0.059 25.3
88e Yes 1.5E+03 0 0 0 INF -
88n Yes 1.5E+03 0 0 0 INF -
89e Yes 1.5E+03 0 0 0 INF -
89n Yes 1.5E+03 0 0 0 INF -
90e Yes 1.5E+03 0 0 0 INF -
90n Yes 1.5E+03 0 0 0 INF -
91e No 0.95 0.057 0 15 -0.33 0.00098 0.056 383
91n No 0.95 0.057 0 16 -0.41 0.0016 0.061 107
92e No 0.84 0.078 0 11 1.2 0.0049 0.33 123
92n No 0.79 0.078 0 15 1.4 0.0046 0.44 63.6
93e No 0.94 0.069 0 10 -0.27 0.0033 0.058 110
93n No 0.94 0.069 0 17 -0.29 0.00098 0.04 23.1
94e No 0.041 0.46 0 0.66 0.56 0.019 0.19 -
94n No 0.94 0.46 0 14 -0.33 0.00065 0.042 22.1
95e No 0.92 0.098 0 53 -0.025 0 0.053 50.8
95n No 0.92 0.098 0 65 -0.05 0 0.069 22.8
96e No 0.033 0.0043 0 3.1 0.56 0.042 0.19 -
96n No 0.04 0.0043 0 2.8 0.6 0.027 0.22 -
97e No 0.91 0.11 0 60 -0.031 0 0.061 22.8
97n No 0.92 0.11 0 78 -0.023 0 0.087 30
98e No 0.93 0.096 0 44 -0.13 0.00033 0.029 12.9
98n No 0.94 0.096 0 53 -0.12 0 0.043 17
99e No 0.92 0.088 0 61 -0.069 0 0.055 41.9
99n No 0.94 0.088 0 36 -0.2 0 0.017 19
100e No 0.93 0.082 0 42 -0.085 0 0.031 17.8
100n No 0.94 0.082 0 39 -0.12 0 0.035 14.5
101e No 0.93 0.083 0 66 -0.13 0 0.066 44.9
101n No 0.93 0.083 0 62 -0.15 0 0.059 27.1
102e No 0.95 0.063 0 32 -0.15 0 0.017 60
102n No 0.95 0.063 0 14 -0.34 0.00033 0.043 41.1
103e Yes 1.5E+03 0 0 0 INF -
103n Yes 1.5E+03 0 0 0 INF -
104e Yes 1.5E+03 0 0 0 INF -
104n Yes 1.5E+03 0 0 0 INF -
105e No 0.96 0.056 0 21 -0.25 0 0.036 176
105n No 0.95 0.056 0 14 -0.41 0.002 0.063 68.1
106e No 0.96 0.055 0 12 -0.37 0.00033 0.065 84.9
106n No 0.96 0.055 0 13 -0.41 0.0026 0.061 53.8
107e Yes 1.5E+03 0 0 0 INF -
107n Yes 1.5E+03 0 0 0 INF -
108e No 0.79 0.19 0 0.74 0.42 0.045 0.16 27.4
108n No 0.95 0.19 0 19 -0.38 0.0013 0.06 127
109e No 0.95 0.49 0 14 -0.34 0.00065 0.058 76
109n No 0.065 0.49 0 0.67 0.57 0.055 0.21 -
110e No 0.95 0.47 0 17 -0.3 0.00033 0.064 77.2
110n No 0.046 0.47 1 0.29 1 0.055 0.32 -
111e No 0.94 0.49 0 15 -0.34 0.00098 0.064 14
111n No 0.063 0.49 0 0.65 0.56 0.049 0.21 -
112e No 0.93 0.081 0 16 -0.26 0.00098 0.035 10.9
112n No 0.94 0.081 0 18 -0.24 0.00033 0.024 23.2
113e No 0.04 0.0055 0 12 0.59 0.033 0.2 -
113n No 0.03 0.0055 0 11 0.62 0.029 0.22 -
114e No 0.91 0.1 0 11 -0.11 0.0075 0.037 76.3
114n No 0.94 0.1 0 32 -0.18 0 0.024 21.2
115e No 0.9 0.12 0 72 -0.03 0 0.075 14.5
115n No 0.93 0.12 0 73 -0.041 0 0.077 37.7
116e No 0.92 0.1 0 41 -0.11 0.0026 0.029 14.2
116n No 0.93 0.1 0 38 -0.13 0.0026 0.039 19
117e No 0.028 0.004 0 0.68 0.55 0.027 0.19 -
117n No 0.034 0.004 0 0.58 0.63 0.092 0.23 -
118e No 0.93 0.084 0 15 -0.27 0 0.045 103
118n No 0.94 0.084 0 14 -0.33 0.00033 0.051 32.3
119e No 0.92 0.086 0 19 0.06 0.0013 0.065 -1.47E+14
119n No 0.94 0.086 0 20 -0.18 0.0013 0.033 34
120e Yes 1.5E+03 0 0 0 INF -
120n Yes 1.5E+03 0 0 0 INF -
121e No 0.95 0.062 0 17 -0.72 0.0029 0.18 75.5
121n No 0.95 0.062 0 11 -0.59 0.00098 0.11 65.5
122e No 0.94 0.07 0 67 -0.13 0 0.067 -1.2E-14
122n No 0.94 0.07 0 63 -0.15 0 0.058 25.7
123e No 0.96 0.056 0 15 -0.6 0.00065 0.13 167
123n No 0.95 0.056 0 13 -0.8 0.0016 0.17 48.4
124e Yes 1.5E+03 0 0 0 INF -
124n Yes 1.5E+03 0 0 0 INF -
125e No 0.96 0.053 0 19 -0.28 0.00033 0.042 8.09E-16
125n No 0.96 0.053 0 14 -0.36 0.0023 0.048 88.1
126e No 0.94 0.057 0 14 0.26 0.00065 0.14 454
126n No 0.95 0.057 0 14 -0.45 0.0023 0.071 88.7
127e No 0.95 0.058 0 16 -0.35 0.0016 0.068 28.3
127n No 0.95 0.058 0 16 -0.35 0.00033 0.046 51.9
128e No 0.95 0.063 0 10 -0.36 0.0029 0.071 76.7
128n No 0.95 0.063 0 15 -0.32 0.00065 0.033 50.9
129e No 0.95 0.069 0 14 -0.33 0.00098 0.06 115
129n No 0.95 0.069 0 14 -0.38 0.00033 0.052 66.2
130e No 0.94 0.074 0 16 -0.26 0.00033 0.04 124
130n No 0.95 0.074 0 17 -0.29 0 0.032 18.8
131e No 0.037 0.0014 0 12 0.56 0.04 0.19 -
131n No 0.042 0.0014 0 10 0.63 0 0.23 -
132e No 0.92 0.1 0 57 -0.031 0 0.057 36
132n No 0.94 0.1 0 46 -0.088 0 0.048 21.8
133e No 0.048 0.44 0 12 0.58 0.042 0.2 -
133n No 0.76 0.44 0 18 0.65 0.026 0.22 41.9
135e No 0.91 0.55 0 16 -0.35 0.014 0.068 135
135n No 0.057 0.55 0 0.62 0.57 0.03 0.21 -
136e No 0.91 0.092 0 32 -0.13 0.0013 0.016 79.3
136n No 0.93 0.092 0 11 -0.43 0.00098 0.076 45.8
137e No 0.92 0.088 0 15 -0.32 0.0036 0.066 97.1
137n No 0.93 0.088 0 15 -0.36 0.00033 0.046 47.9
138e No 0.92 0.088 0 47 -0.11 0 0.036 72.8
138n No 0.93 0.088 0 36 -0.16 0 0.031 33.4
139e No 0.93 0.08 0 42 -0.083 0 0.027 63.5
139n No 0.94 0.08 0 28 -0.2 0 0.016 51
140e No 0.94 0.57 0 31 -0.16 0.00033 0.014 54.8
140n No 0.11 0.57 0 0.64 0.59 0.063 0.22 -
141e No 0.94 0.065 0 14 -1.3 0.00033 0.34 8.79E-15
141n No 0.94 0.065 0 40 -0.16 0.00033 0.028 37.6
142e No 0.95 0.6 0 18 -0.22 0.00065 0.068 352
142n No 0.1 0.6 1 0.63 0.56 0.047 0.21 -
143e No 0.055 0.64 0 0.66 0.52 0 0.18 -
143n No 0.95 0.64 0 14 -0.65 0.00065 0.15 64.7
144e No 0.96 0.055 0 16 -0.29 0.0013 0.056 116
144n No 0.95 0.055 0 24 -0.33 0 0.045 58.7
145e No 0.96 0.065 0 13 -0.34 0.0023 0.058 702
145n No 0.94 0.065 0 2.4 -0.43 0.031 0.091 98.9
146e No 0.95 0.057 0 20 -0.18 0.00033 0.031 18.1
146n No 0.95 0.057 0 41 -0.19 0.00033 0.032 35.3
147e No 0.95 0.062 0 30 -0.091 0.00033 0.021 41.6
147n No 0.95 0.062 0 30 -0.19 0.00033 0.016 15.3
148e No 0.95 0.068 0 23 -0.2 0 0.017 67.4
148n No 0.95 0.068 0 33 -0.2 0 0.02 15.6
149e No 0.93 0.09 0 55 -0.069 0 0.044 43.8
149n No 0.93 0.09 0 71 -0.064 0 0.07 18.5
150e Yes 1.5E+03 0 0 0 INF -
150n Yes 1.5E+03 0 0 0 INF -
155e No 0.9 0.11 0 17 -0.34 0.027 0.066 -7.54E-16
155n No 0.92 0.11 0 11 -0.36 0.013 0.054 66.9
156e No 0.7 0.29 0 0.76 0.33 0.037 0.14 -6.39E-16
156n No 0.92 0.29 0 11 -0.55 0.00033 0.099 4.12E-16
157e No 0.92 0.089 0 15 -0.3 0.00098 0.06 -9.35E-16
157n No 0.92 0.089 0 15 -0.37 0.00065 0.057 33.7
158e No 0.93 0.084 0 19 -0.25 0.0023 0.044 -1.77E-15
158n No 0.93 0.084 0 22 -0.26 0.00033 0.024 41.9
159e No 0.93 0.079 0 22 -0.14 0 0.025 210
159n No 0.91 0.079 0 20 0.32 0.00065 0.18 3.66E-16
160e No 0.94 0.072 0 17 -0.33 0.00098 0.055 175
160n No 0.94 0.072 0 20 -0.28 0.00065 0.027 784
161e No 0.94 0.065 0 42 -0.13 0 0.027 1.96E-15
161n No 0.9 0.065 0 45 0.35 0 0.16 211
162e No 0.94 0.067 0 50 -0.025 0 0.042 132
162n No 0.94 0.067 0 42 -0.11 0 0.038 217
163e No 0.95 0.055 0 17 -0.34 0.00065 0.058 162
163n No 0.95 0.055 0 16 -0.45 0.00033 0.07 317
164e No 0.95 0.055 0 14 -0.29 0.00033 0.049 -1.51E-15
164n No 0.95 0.055 0 19 -0.3 0.00033 0.028 290
165e No 0.91 0.076 0 1.9 0.05 0.0059 0.1 200
165n No 0.96 0.076 0 18 -0.37 0.00065 0.043 302
166e No 0.92 0.35 0 3.8 -0.96 0.0036 0.26 307
166n No 0.67 0.35 0 0.71 0.47 0.014 0.19 11.1
167e Yes 1.5E+03 0 0 0 INF -
167n Yes 1.5E+03 0 0 0 INF -
168e No 0.95 0.063 0 16 -0.27 0.00098 0.054 19.7
168n No 0.95 0.063 0 19 -0.42 0 0.062 29.8
169e No 0.95 0.073 0 19 -0.41 0.00033 0.093 52.7
169n No 0.94 0.073 0 22 -0.26 0 0.093 25.9
170e No 0.084 0.69 0 0.66 0.54 0.018 0.19 -
170n No 0.95 0.69 0 33 -0.15 0 0.026 14.9
179e No 0.35 0.32 0 0.66 0.55 0.021 0.19 3.73
179n No 0.65 0.32 0 0.59 0.53 0.022 0.2 35.7
180e No 0.073 -0.002 0 0.67 0.52 0.019 0.19 -
180n No 0.09 -0.002 0 0.61 0.59 0.056 0.22 -
181e No 0.94 0.07 0 17 -0.28 0.00065 0.044 8.78E-16
181n No 0.93 0.07 0 15 -0.37 0.00098 0.052 640
182e No 0.93 0.094 0 52 -0.085 0.0039 0.038 220
182n No 0.91 0.094 0 79 -0.055 0 0.082 113
183e No 0.049 0.58 0 0.7 0.53 0.012 0.19 -
183n No 0.94 0.58 0 15 -0.33 0 0.037 402
184e No 0.54 0.25 0 0.67 0.49 0.019 0.18 2.85
184n No 0.43 0.25 0 0.62 0.57 0.021 0.21 3.87
185e No 0.91 0.1 0 1.1 -0.079 0.017 0.059 841
185n No 0.93 0.1 0 3 -0.6 0.0049 0.12 1.31E+03
186e No 0.17 0.54 1 0.67 0.51 0.064 0.18 -
186n No 0.94 0.54 0 53 -0.091 0 0.049 7.36E-16
187e No 0.95 0.062 0 4.2 -0.44 0.017 0.1 403
187n No 0.95 0.062 0 36 -0.34 0 0.059 26.3
189e No 0.95 0.062 0 11 -0.35 0.0016 0.084 72.6
189n No 0.95 0.062 0 19 -0.34 0.00065 0.054 42.8
190e No 0.93 0.71 0 19 0.59 0.00098 0.24 100
190n No 0.073 0.71 0 0.62 0.59 0.085 0.22 -
191e No 0.94 0.076 0 7.1 -0.4 0.0081 0.082 22.8
191n No 0.95 0.076 0 17 -0.3 0.00033 0.034 46.7
200e No 0.051 0.53 0 3.1 0.58 0.062 0.2 -
200n No 0.71 0.53 0 33 1 0.00065 0.37 87.1
201e No 0.9 0.092 0 80 -0.015 0 0.086 176
201n No 0.89 0.092 0 78 -0.035 0 0.084 147
202e No 0.93 0.072 0 38 -0.09 0 0.031 261
202n No 0.92 0.072 0 17 -0.19 0.0026 0.025 384
203e No 0.035 0.0037 0 2.3 0.58 0.068 0.2 -
203n No 0.05 0.0037 0 2.2 0.62 0.099 0.22 -
205e No 0.95 0.073 0 35 -0.13 0.00065 0.039 149
205n No 0.93 0.073 0 13 -0.25 0.016 0.049 -1.27E-14
206e No 0.95 0.07 0 25 -0.16 0.00065 0.025 102
206n No 0.94 0.07 0 33 -0.25 0.00033 0.028 5.4E-15
207e No 0.95 0.064 0 31 -0.16 0.00065 0.1 23.5
207n No 0.95 0.064 0 25 -0.31 0.00033 0.11 29.4
208e Yes 1.5E+03 0 0 0 INF -
208n Yes 1.5E+03 0 0 0 INF -
209e Yes 1.5E+03 0 0 0 INF -
209n Yes 1.5E+03 0 0 0 INF -
210e Yes 1.5E+03 0 0 0 INF -
210n Yes 1.5E+03 0 0 0 INF -
211e Yes 1.5E+03 0 0 0 INF -
211n Yes 1.5E+03 0 0 0 INF -
219e No 0.9 0.12 0 82 -0.023 0.0023 0.087 174
219n No 0.9 0.12 0 59 -0.1 0 0.052 125
220e No 0.93 0.083 0 30 -0.12 0.00098 0.012 256
220n No 0.92 0.083 0 32 -0.17 0.00033 0.017 281
221e No 0.94 0.08 0 17 -0.15 0.00098 0.029 -6.6E-15
221n No 0.92 0.08 0 29 -0.17 0.00033 0.025 365
222e No 0.94 0.078 0 26 -0.095 0.00033 0.028 231
222n No 0.93 0.078 0 32 -0.14 0.00033 0.029 326
223e No 0.95 0.079 0 17 -0.23 0.00065 0.044 299
223n No 0.93 0.079 0 34 -0.23 0 0.036 2.73E-15
224e No 0.92 0.1 0 84 -0.023 0.0075 0.09 6.95
224n No 0.91 0.1 0 81 -0.03 0 0.087 -4.47E-15
225e Yes 1.5E+03 0 0 0 INF -
225n Yes 1.5E+03 0 0 0 INF -
226e Yes 1.5E+03 0 0 0 INF -
226n Yes 1.5E+03 0 0 0 INF -
227e Yes 1.5E+03 0 0 0 INF -
227n Yes 1.5E+03 0 0 0 INF -
228e Yes 1.5E+03 0 0 0 INF -
228n Yes 1.5E+03 0 0 0 INF -
229e Yes 1.5E+03 0 0 0 INF -
229n Yes 1.5E+03 0 0 0 INF -
237e No 0.92 0.091 0 16 -0.18 0.00065 0.046 351
237n No 0.9 0.091 0 26 -0.2 0.00033 0.034 191
238e No 0.93 0.096 0 39 -0.12 0.00033 0.029 250
238n No 0.91 0.096 0 39 -0.12 0 0.034 1.14E-14
239e No 0.94 0.093 0 30 -0.17 0.00033 0.022 277
239n No 0.91 0.093 0 42 -0.17 0 0.024 1.08E-13
240e Yes 1.5E+03 0 0 0 INF -
240n Yes 1.5E+03 0 0 0 INF -
241e No 0.95 0.093 0 27 -0.19 0.0013 0.041 -5.28E-15
241n No 0.92 0.093 0 14 -0.33 0 0.064 -1.63E-14
242e No 0.93 0.066 0 31 0.4 0.00098 0.19 609
242n No 0.93 0.066 0 44 -0.14 0 0.037 1.53E-14
243e No 0.89 0.12 0 32 1.7 0.00098 0.46 200
243n No 0.93 0.12 0 25 -0.21 0.00033 0.038 36.3
244e Yes 1.5E+03 0 0 0 INF -
244n Yes 1.5E+03 0 0 0 INF -
245e Yes 1.5E+03 0 0 0 INF -
245n Yes 1.5E+03 0 0 0 INF -
246e Yes 1.5E+03 0 0 0 INF -
246n Yes 1.5E+03 0 0 0 INF -
261e Yes 1.5E+03 0 0 0 INF -
261n Yes 1.5E+03 0 0 0 INF -
262e Yes 1.5E+03 0 0 0 INF -
262n Yes 1.5E+03 0 0 0 INF -
320e No 0.95 0.7 0 13 -0.27 0 0.054 -
320n No 0.082 0.7 0 1.2 0.56 0.1 0.21 -
324e No 0.88 0.14 0 34 -0.11 0.0026 0.032 -
324n No 0.86 0.14 0 39 -0.2 0.00033 0.033 -
325e Yes 1.5E+03 0 0 0 INF -
325n Yes 1.5E+03 0 0 0 INF -
329e No 0.86 0.13 0 19 -0.17 0.027 0.044 -
329n No 0.89 0.13 0 31 -0.2 0.0026 0.024 -
333e No 0.81 0.26 0 21 -0.1 0.0026 0.039 -
333n No 0.9 0.26 0 32 -0.09 0.0013 0.042 -
In [41]:
# Save antenna classification table as a csv
if SAVE_RESULTS:
    for ind, col in zip(np.arange(len(df.columns), 0, -1), df_classes.columns[::-1]):
        df.insert(int(ind), col + ' Class', df_classes[col])
    df.to_csv(ANTCLASS_FILE)    
In [42]:
print('Final Ant-Pol Classification:\n\n', final_class)
Final Ant-Pol Classification:

 Jee:
----------
good (58 antpols):
4, 7, 9, 10, 16, 17, 19, 20, 21, 30, 37, 38, 40, 42, 44, 45, 46, 49, 55, 56, 59, 61, 68, 69, 70, 72, 85, 91, 93, 105, 109, 112, 114, 118, 125, 129, 130, 144, 145, 146, 148, 157, 158, 159, 160, 163, 164, 168, 181, 206, 221, 222, 223, 237, 239, 241, 320, 333

suspect (50 antpols):
15, 31, 32, 35, 36, 41, 48, 50, 52, 53, 62, 65, 66, 67, 81, 82, 83, 84, 86, 98, 100, 102, 106, 110, 111, 116, 119, 127, 128, 135, 136, 137, 138, 139, 140, 142, 147, 161, 165, 169, 185, 187, 189, 191, 202, 205, 207, 220, 238, 324

bad (93 antpols):
3, 5, 8, 18, 22, 27, 28, 29, 34, 43, 47, 51, 54, 57, 58, 60, 63, 64, 71, 73, 74, 77, 78, 79, 80, 87, 88, 89, 90, 92, 94, 95, 96, 97, 99, 101, 103, 104, 107, 108, 113, 115, 117, 120, 121, 122, 123, 124, 126, 131, 132, 133, 141, 143, 149, 150, 155, 156, 162, 166, 167, 170, 179, 180, 182, 183, 184, 186, 190, 200, 201, 203, 208, 209, 210, 211, 219, 224, 225, 226, 227, 228, 229, 240, 242, 243, 244, 245, 246, 261, 262, 325, 329


Jnn:
----------
good (56 antpols):
4, 7, 9, 10, 16, 20, 21, 22, 30, 31, 34, 35, 38, 40, 42, 44, 45, 47, 51, 59, 61, 69, 70, 71, 72, 82, 85, 93, 94, 102, 108, 112, 118, 119, 125, 127, 128, 129, 130, 137, 139, 144, 147, 157, 158, 160, 164, 165, 181, 183, 189, 191, 202, 221, 237, 243

suspect (59 antpols):
3, 5, 15, 17, 19, 36, 37, 41, 48, 49, 52, 53, 57, 62, 65, 66, 67, 73, 74, 81, 83, 86, 91, 99, 100, 105, 106, 114, 116, 121, 126, 132, 136, 138, 141, 146, 148, 155, 156, 162, 163, 168, 169, 170, 185, 187, 205, 206, 207, 220, 222, 223, 238, 239, 241, 242, 324, 329, 333

bad (86 antpols):
8, 18, 27, 28, 29, 32, 43, 46, 50, 54, 55, 56, 58, 60, 63, 64, 68, 77, 78, 79, 80, 84, 87, 88, 89, 90, 92, 95, 96, 97, 98, 101, 103, 104, 107, 109, 110, 111, 113, 115, 117, 120, 122, 123, 124, 131, 133, 135, 140, 142, 143, 145, 149, 150, 159, 161, 166, 167, 179, 180, 182, 184, 186, 190, 200, 201, 203, 208, 209, 210, 211, 219, 224, 225, 226, 227, 228, 229, 240, 244, 245, 246, 261, 262, 320, 325

Save calibration solutions¶

In [43]:
# update flags in omnical gains and visibility solutions
for ant in cal['gf_omnical']:
    cal['gf_omnical'][ant] |= rfi_flags
for bl in cal['vf_omnical']:
    cal['vf_omnical'][bl] |= rfi_flags
In [44]:
if SAVE_RESULTS:
    hd_writer = io.HERAData(SUM_FILE)
    redcal._redcal_run_write_results(cal, hd_writer, None, OMNICAL_FILE, OMNIVIS_FILE, None, '', vispols=['ee', 'nn'],
                                     clobber=True, verbose=True, add_to_history='Producted by file_inspect notebook.')
    del hd_writer
    malloc_trim()
Now saving omnical gains to /mnt/sn1/2459886/zen.2459886.25252.sum.omni.calfits
Now saving omnical visibilities to /mnt/sn1/2459886/zen.2459886.25252.sum.omni_vis.uvh5

TODO: Perform nucal¶

Metadata¶

In [45]:
from hera_cal import __version__
print('hera_cal:', __version__)
from hera_qm import __version__
print('hera_qm:', __version__)
hera_cal: 3.1.5.dev171+gc8e6162
hera_qm: 2.0.4.dev44+g3962204
In [46]:
print(f'Finished execution in {(time.time() - tstart) / 60:.2f} minutes.')
Finished execution in 7.21 minutes.