by Josh Dillon, last updated March 29, 2023
This notebook runs calibration smoothing to the gains coming out of file_calibration notebook. It removes any flags founds on by that notebook and replaces them with flags generated from full_day_rfi and full_day_antenna_flagging. It also plots the results for a couple of antennas.
Here's a set of links to skip to particular figures and tables:
smooth_cal
¶smooth_cal
¶import time
tstart = time.time()
import os
os.environ['HDF5_USE_FILE_LOCKING'] = 'FALSE'
import h5py
import hdf5plugin # REQUIRED to have the compression plugins available
import numpy as np
import glob
import copy
import warnings
import matplotlib
import matplotlib.pyplot as plt
from hera_cal import io, utils, smooth_cal
from hera_qm.time_series_metrics import true_stretches
%matplotlib inline
from IPython.display import display, HTML
# get files
SUM_FILE = os.environ.get("SUM_FILE", None)
# SUM_FILE = '/users/jsdillon/lustre/H6C/abscal/2459853/zen.2459853.25518.sum.uvh5'
SUM_SUFFIX = os.environ.get("SUM_SUFFIX", 'sum.uvh5')
CAL_SUFFIX = os.environ.get("CAL_SUFFIX", 'sum.omni.calfits')
SMOOTH_CAL_SUFFIX = os.environ.get("SMOOTH_CAL_SUFFIX", 'sum.smooth.calfits')
ANT_FLAG_SUFFIX = os.environ.get("ANT_FLAG_SUFFIX", 'sum.antenna_flags.h5')
RFI_FLAG_SUFFIX = os.environ.get("RFI_FLAG_SUFFIX", 'sum.flag_waterfall.h5')
FREQ_SMOOTHING_SCALE = float(os.environ.get("FREQ_SMOOTHING_SCALE", 10.0)) # MHz
TIME_SMOOTHING_SCALE = float(os.environ.get("TIME_SMOOTHING_SCALE", 6e5)) # seconds
EIGENVAL_CUTOFF = float(os.environ.get("EIGENVAL_CUTOFF", 1e-12))
OUT_YAML_SUFFIX = os.environ.get("OUT_YAML_SUFFIX", '_aposteriori_flags.yaml')
OUT_YAML_DIR = os.environ.get("OUT_YAML_DIR", None)
if OUT_YAML_DIR is None:
OUT_YAML_DIR = os.path.dirname(SUM_FILE)
out_yaml_file = os.path.join(OUT_YAML_DIR, SUM_FILE.split('.')[-4] + OUT_YAML_SUFFIX)
for setting in ['SUM_FILE', 'SUM_SUFFIX', 'CAL_SUFFIX', 'SMOOTH_CAL_SUFFIX', 'ANT_FLAG_SUFFIX', 'RFI_FLAG_SUFFIX',
'FREQ_SMOOTHING_SCALE', 'TIME_SMOOTHING_SCALE', 'EIGENVAL_CUTOFF', 'out_yaml_file']:
print(f'{setting} = {eval(setting)}')
SUM_FILE = /mnt/sn1/2460144/zen.2460144.42108.sum.uvh5 SUM_SUFFIX = sum.uvh5 CAL_SUFFIX = sum.omni.calfits SMOOTH_CAL_SUFFIX = sum.smooth.calfits ANT_FLAG_SUFFIX = sum.antenna_flags.h5 RFI_FLAG_SUFFIX = sum.flag_waterfall.h5 FREQ_SMOOTHING_SCALE = 10.0 TIME_SMOOTHING_SCALE = 600000.0 EIGENVAL_CUTOFF = 1e-12 out_yaml_file = /mnt/sn1/2460144/2460144_aposteriori_flags.yaml
sum_glob = '.'.join(SUM_FILE.split('.')[:-3]) + '.*.' + SUM_SUFFIX
cal_files_glob = sum_glob.replace(SUM_SUFFIX, CAL_SUFFIX)
cal_files = sorted(glob.glob(cal_files_glob))
print(f'Found {len(cal_files)} *.{CAL_SUFFIX} files starting with {cal_files[0]}.')
Found 360 *.sum.omni.calfits files starting with /mnt/sn1/2460144/zen.2460144.42108.sum.omni.calfits.
rfi_flag_files_glob = sum_glob.replace(SUM_SUFFIX, RFI_FLAG_SUFFIX)
rfi_flag_files = sorted(glob.glob(rfi_flag_files_glob))
print(f'Found {len(rfi_flag_files)} *.{RFI_FLAG_SUFFIX} files starting with {rfi_flag_files[0]}.')
Found 360 *.sum.flag_waterfall.h5 files starting with /mnt/sn1/2460144/zen.2460144.42108.sum.flag_waterfall.h5.
ant_flag_files_glob = sum_glob.replace(SUM_SUFFIX, ANT_FLAG_SUFFIX)
ant_flag_files = sorted(glob.glob(ant_flag_files_glob))
print(f'Found {len(ant_flag_files)} *.{ANT_FLAG_SUFFIX} files starting with {ant_flag_files[0]}.')
Found 360 *.sum.antenna_flags.h5 files starting with /mnt/sn1/2460144/zen.2460144.42108.sum.antenna_flags.h5.
cs = smooth_cal.CalibrationSmoother(cal_files, flag_file_list=(ant_flag_files + rfi_flag_files), ignore_calflags=True,
pick_refant=True, propagate_refant_flags=True, load_chisq=True, load_cspa=True)
for pol in cs.refant:
print(f'Reference antenna {cs.refant[pol][0]} selected for {pol}.')
Mean of empty slice
Reference antenna 86 selected for Jnn. Reference antenna 56 selected for Jee.
# duplicate a small number of abscal gains for plotting
antnums = set([ant[0] for ant in cs.ants])
flags_per_antnum = [np.sum(cs.flag_grids[ant, 'Jnn']) + np.sum(cs.flag_grids[ant, 'Jee']) for ant in antnums]
refant_nums = [ant[0] for ant in cs.refant.values()]
candidate_ants = [ant for ant, nflags in zip(antnums, flags_per_antnum) if (ant not in refant_nums) and (nflags <= np.percentile(flags_per_antnum, 25))
and not np.all(cs.flag_grids[ant, 'Jee']) and not np.all(cs.flag_grids[ant, 'Jnn'])]
ants_to_plot = [func(candidate_ants) for func in (np.min, np.max)]
abscal_gains = {(ant, pol): np.array(cs.gain_grids[(ant, pol)]) for ant in ants_to_plot for pol in ['Jee', 'Jnn']}
cs.time_freq_2D_filter(freq_scale=FREQ_SMOOTHING_SCALE, time_scale=TIME_SMOOTHING_SCALE, eigenval_cutoff=EIGENVAL_CUTOFF,
method='DPSS', fit_method='lu_solve', fix_phase_flips=True, flag_phase_flip_ints=True)
WARNING:jax._src.lib.xla_bridge:No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)
50 phase-flipped integrations detected on antenna (93, 'Jee') between 2460144.4902036227 and 2460144.5015002824.
lst_grid = utils.JD2LST(cs.time_grid) * 12 / np.pi
lst_grid[lst_grid > lst_grid[-1]] -= 24
def amplitude_plot(ant_to_plot):
with warnings.catch_warnings():
warnings.simplefilter("ignore")
# Pick vmax to not saturate 90% of the abscal gains
vmax = np.max([np.percentile(np.abs(cs.gain_grids[ant_to_plot, pol][~cs.flag_grids[ant_to_plot, pol]]), 99) for pol in ['Jee', 'Jnn']])
display(HTML(f'<h2>Antenna {ant_to_plot} Amplitude Waterfalls</h2>'))
# Plot abscal gain amplitude waterfalls for a single antenna
fig, axes = plt.subplots(4, 2, figsize=(14,14), gridspec_kw={'height_ratios': [1, 1, .4, .4]})
for ax, pol in zip(axes[0], ['Jee', 'Jnn']):
ant = (ant_to_plot, pol)
extent=[cs.freqs[0]/1e6, cs.freqs[-1]/1e6, lst_grid[-1], lst_grid[0]]
im = ax.imshow(np.where(cs.flag_grids[ant], np.nan, np.abs(cs.gain_grids[ant])), aspect='auto', cmap='inferno',
interpolation='nearest', vmin=0, vmax=vmax, extent=extent)
ax.set_title(f'Smoothcal Gain Amplitude of Antenna {ant[0]}: {pol[-1]}-polarized' )
ax.set_xlabel('Frequency (MHz)')
ax.set_ylabel('LST (Hours)')
ax.set_xlim([cs.freqs[0]/1e6, cs.freqs[-1]/1e6])
ax.set_yticklabels(ax.get_yticks() % 24)
plt.colorbar(im, ax=ax, orientation='horizontal', pad=.15)
# Now flagged plot abscal waterfall
for ax, pol in zip(axes[1], ['Jee', 'Jnn']):
ant = (ant_to_plot, pol)
extent=[cs.freqs[0]/1e6, cs.freqs[-1]/1e6, lst_grid[-1], lst_grid[0]]
im = ax.imshow(np.where(cs.flag_grids[ant], np.nan, np.abs(abscal_gains[ant])), aspect='auto', cmap='inferno',
interpolation='nearest', vmin=0, vmax=vmax, extent=extent)
ax.set_title(f'Abscal Gain Amplitude of Antenna {ant[0]}: {pol[-1]}-polarized' )
ax.set_xlabel('Frequency (MHz)')
ax.set_ylabel('LST (Hours)')
ax.set_xlim([cs.freqs[0]/1e6, cs.freqs[-1]/1e6])
ax.set_yticklabels(ax.get_yticks() % 24)
plt.colorbar(im, ax=ax, orientation='horizontal', pad=.15)
# Now plot mean gain spectra
for ax, pol in zip(axes[2], ['Jee', 'Jnn']):
ant = (ant_to_plot, pol)
nflags_spectrum = np.sum(cs.flag_grids[ant], axis=0)
to_plot = nflags_spectrum <= np.percentile(nflags_spectrum, 75)
ax.plot(cs.freqs[to_plot] / 1e6, np.nanmean(np.where(cs.flag_grids[ant], np.nan, np.abs(abscal_gains[ant])), axis=0)[to_plot], 'r.', label='Abscal')
ax.plot(cs.freqs[to_plot] / 1e6, np.nanmean(np.where(cs.flag_grids[ant], np.nan, np.abs(cs.gain_grids[ant])), axis=0)[to_plot], 'k.', ms=2, label='Smoothed')
ax.set_ylim([0, vmax])
ax.set_xlim([cs.freqs[0]/1e6, cs.freqs[-1]/1e6])
ax.set_xlabel('Frequency (MHz)')
ax.set_ylabel('|g| (unitless)')
ax.set_title(f'Mean Infrequently-Flagged Gain Amplitude of Antenna {ant[0]}: {pol[-1]}-polarized')
ax.legend(loc='upper left')
# Now plot mean gain time series
for ax, pol in zip(axes[3], ['Jee', 'Jnn']):
ant = (ant_to_plot, pol)
nflags_series = np.sum(cs.flag_grids[ant], axis=1)
to_plot = nflags_series <= np.percentile(nflags_series, 75)
ax.plot(lst_grid[to_plot], np.nanmean(np.where(cs.flag_grids[ant], np.nan, np.abs(abscal_gains[ant])), axis=1)[to_plot], 'r.', label='Abscal')
ax.plot(lst_grid[to_plot], np.nanmean(np.where(cs.flag_grids[ant], np.nan, np.abs(cs.gain_grids[ant])), axis=1)[to_plot], 'k.', ms=2, label='Smoothed')
ax.set_ylim([0, vmax])
ax.set_xlabel('LST (hours)')
ax.set_ylabel('|g| (unitless)')
ax.set_title(f'Mean Infrequently-Flagged Gain Amplitude of Antenna {ant[0]}: {pol[-1]}-polarized')
ax.set_xticklabels(ax.get_xticks() % 24)
ax.legend(loc='upper left')
plt.tight_layout()
plt.show()
def phase_plot(ant_to_plot):
with warnings.catch_warnings():
warnings.simplefilter("ignore")
display(HTML(f'<h2>Antenna {ant_to_plot} Phase Waterfalls</h2>'))
fig, axes = plt.subplots(4, 2, figsize=(14,14), gridspec_kw={'height_ratios': [1, 1, .4, .4]})
# Plot phase waterfalls for a single antenna
for ax, pol in zip(axes[0], ['Jee', 'Jnn']):
ant = (ant_to_plot, pol)
extent=[cs.freqs[0]/1e6, cs.freqs[-1]/1e6, lst_grid[-1], lst_grid[0]]
im = ax.imshow(np.where(cs.flag_grids[ant], np.nan, np.angle(cs.gain_grids[ant])), aspect='auto', cmap='inferno',
interpolation='nearest', vmin=-np.pi, vmax=np.pi, extent=extent)
ax.set_title(f'Smoothcal Gain Phase of Ant {ant[0]} / Ant {cs.refant[pol][0]}: {pol[-1]}-polarized')
ax.set_xlabel('Frequency (MHz)')
ax.set_ylabel('LST (Hours)')
ax.set_xlim([cs.freqs[0]/1e6, cs.freqs[-1]/1e6])
ax.set_yticklabels(ax.get_yticks() % 24)
plt.colorbar(im, ax=ax, orientation='horizontal', pad=.15)
# Now plot abscal phase waterfall
for ax, pol in zip(axes[1], ['Jee', 'Jnn']):
ant = (ant_to_plot, pol)
extent=[cs.freqs[0]/1e6, cs.freqs[-1]/1e6, lst_grid[-1], lst_grid[0]]
im = ax.imshow(np.where(cs.flag_grids[ant], np.nan, np.angle(abscal_gains[ant])), aspect='auto', cmap='inferno',
interpolation='nearest', vmin=-np.pi, vmax=np.pi, extent=extent)
ax.set_title(f'Abscal Gain Phase of Ant {ant[0]} / Ant {cs.refant[pol][0]}: {pol[-1]}-polarized')
ax.set_xlabel('Frequency (MHz)')
ax.set_ylabel('LST (Hours)')
ax.set_xlim([cs.freqs[0]/1e6, cs.freqs[-1]/1e6])
ax.set_yticklabels(ax.get_yticks() % 24)
plt.colorbar(im, ax=ax, orientation='horizontal', pad=.15)
# Now plot median gain spectra
for ax, pol in zip(axes[2], ['Jee', 'Jnn']):
ant = (ant_to_plot, pol)
nflags_spectrum = np.sum(cs.flag_grids[ant], axis=0)
to_plot = nflags_spectrum <= np.percentile(nflags_spectrum, 75)
ax.plot(cs.freqs[to_plot] / 1e6, np.nanmedian(np.where(cs.flag_grids[ant], np.nan, np.angle(abscal_gains[ant])), axis=0)[to_plot], 'r.', label='Abscal')
ax.plot(cs.freqs[to_plot] / 1e6, np.nanmedian(np.where(cs.flag_grids[ant], np.nan, np.angle(cs.gain_grids[ant])), axis=0)[to_plot], 'k.', ms=2, label='Smoothed')
ax.set_ylim([-np.pi, np.pi])
ax.set_xlim([cs.freqs[0]/1e6, cs.freqs[-1]/1e6])
ax.set_xlabel('Frequency (MHz)')
ax.set_ylabel(f'Phase of g$_{{{ant[0]}}}$ / g$_{{{cs.refant[pol][0]}}}$')
ax.set_title(f'Median Infrequently-Flagged Gain Phase of Ant {ant[0]} / Ant {cs.refant[pol][0]}: {pol[-1]}-polarized')
ax.legend(loc='upper left')
# # Now plot median gain time series
for ax, pol in zip(axes[3], ['Jee', 'Jnn']):
ant = (ant_to_plot, pol)
nflags_series = np.sum(cs.flag_grids[ant], axis=1)
to_plot = nflags_series <= np.percentile(nflags_series, 75)
ax.plot(lst_grid[to_plot], np.nanmean(np.where(cs.flag_grids[ant], np.nan, np.angle(abscal_gains[ant])), axis=1)[to_plot], 'r.', label='Abscal')
ax.plot(lst_grid[to_plot], np.nanmean(np.where(cs.flag_grids[ant], np.nan, np.angle(cs.gain_grids[ant])), axis=1)[to_plot], 'k.', ms=2, label='Smoothed')
ax.set_ylim([-np.pi, np.pi])
ax.set_xlabel('LST (hours)')
ax.set_ylabel(f'Phase of g$_{{{ant[0]}}}$ / g$_{{{cs.refant[pol][0]}}}$')
ax.set_title(f'Mean Infrequently-Flagged Gain Phase of Ant {ant[0]} / Ant {cs.refant[pol][0]}: {pol[-1]}-polarized')
ax.set_xticklabels(ax.get_xticks() % 24)
ax.legend(loc='upper left')
plt.tight_layout()
plt.show()
smooth_cal
¶Here we plot abscal
and smooth_cal
gain amplitudes for both of the sample antennas. We also show means across time/frequency, excluding frequencies/times that are frequently flagged.
for ant_to_plot in ants_to_plot:
amplitude_plot(ant_to_plot)
smooth_cal
¶Here we plot abscal
and smooth_cal
phases relative to each polarization's reference antenna for both of the sample antennas. We also show medians across time/frequency, excluding frequencies/times that are frequently flagged.
for ant_to_plot in ants_to_plot:
phase_plot(ant_to_plot)
def chisq_plot():
fig, axes = plt.subplots(1, 2, figsize=(14, 10), sharex=True, sharey=True)
extent = [cs.freqs[0]/1e6, cs.freqs[-1]/1e6, lst_grid[-1], lst_grid[0]]
for ax, pol in zip(axes, ['Jee', 'Jnn']):
im = ax.imshow(np.where(cs.flag_grids[cs.refant[pol]], np.nan, cs.chisq_grids[pol]), vmin=1, vmax=5,
aspect='auto', cmap='turbo', interpolation='none', extent=extent)
ax.set_yticklabels(ax.get_yticks() % 24)
ax.set_title(f'{pol[1:]}-Polarized $\\chi^2$ / DoF')
ax.set_xlabel('Frequency (MHz)')
axes[0].set_ylabel('LST (hours)')
plt.tight_layout()
fig.colorbar(im, ax=axes, pad=.07, label='$\\chi^2$ / DoF', orientation='horizontal', extend='both', aspect=50)
Here we plot $\chi^2$ per degree of freedom from redundant-baseline calibration for both polarizations separately. While this plot is a little out of place, as it was not produced by this notebook, it is a convenient place where all the necessary components are readily available. If the array were perfectly redundant and any non-redundancies in the calibrated visibilities were explicable by thermal noise alone, this waterfall should be all 1.
chisq_plot()
FixedFormatter should only be used together with FixedLocator
avg_cspa_vs_time = {ant: np.nanmean(np.where(cs.flag_grids[ant], np.nan, cs.cspa_grids[ant]), axis=1) for ant in cs.ants}
avg_cspa_vs_freq = {ant: np.nanmean(np.where(cs.flag_grids[ant], np.nan, cs.cspa_grids[ant]), axis=0) for ant in cs.ants}
Mean of empty slice Mean of empty slice
def cspa_vs_time_plot():
fig, axes = plt.subplots(2, 1, figsize=(14, 8), sharex=True, sharey=True, gridspec_kw={'hspace': 0})
for ax, pol in zip(axes, ['Jee', 'Jnn']):
detail_cutoff = np.percentile([np.nanmean(m) for ant, m in avg_cspa_vs_time.items()
if ant[1] == pol and np.isfinite(np.nanmean(m))], 95)
for ant in avg_cspa_vs_time:
if ant[1] == pol and not np.all(cs.flag_grids[ant]):
if np.nanmean(avg_cspa_vs_time[ant]) > detail_cutoff:
ax.plot(lst_grid, avg_cspa_vs_time[ant], label=ant, zorder=100)
else:
ax.plot(lst_grid, avg_cspa_vs_time[ant], c='grey', alpha=.2, lw=.5)
ax.legend(title=f'{pol[1:]}-Polarized', ncol=2)
ax.set_ylabel('Mean Unflagged $\\chi^2$ per Antenna')
ax.set_xlabel('LST (hours)')
ax.set_xticklabels(ax.get_xticks() % 24)
plt.ylim([1, 5.4])
plt.tight_layout()
def cspa_vs_freq_plot():
fig, axes = plt.subplots(2, 1, figsize=(14, 6), sharex=True, sharey=True, gridspec_kw={'hspace': 0})
for ax, pol in zip(axes, ['Jee', 'Jnn']):
detail_cutoff = np.percentile([np.nanmean(m) for ant, m in avg_cspa_vs_freq.items()
if ant[1] == pol and np.isfinite(np.nanmean(m))], 95)
for ant in avg_cspa_vs_freq:
if ant[1] == pol and not np.all(cs.flag_grids[ant]):
if np.nanmean(avg_cspa_vs_freq[ant]) > detail_cutoff:
ax.plot(cs.freqs / 1e6, avg_cspa_vs_freq[ant], label=ant, zorder=100)
else:
ax.plot(cs.freqs / 1e6, avg_cspa_vs_freq[ant], c='grey', alpha=.2, lw=.5)
ax.legend(title=f'{pol[1:]}-Polarized', ncol=2)
ax.set_ylabel('Mean Unflagged $\\chi^2$ per Antenna')
ax.set_xlabel('Frequency (MHz)')
plt.ylim([1, 5.4])
plt.tight_layout()
Here we plot $\chi^2$ per antenna from redundant-baseline calibration, separating polarizations and averaging the unflagged pixels in the waterfalls over frequency or time. The worst 5% of antennas are shown in color and highlighted in the legends, the rest are shown in grey.
cspa_vs_time_plot()
cspa_vs_freq_plot()
Mean of empty slice FixedFormatter should only be used together with FixedLocator
add_to_history = 'Produced by calibration_smoothing notebook with the following environment:\n' + '=' * 65 + '\n' + os.popen('conda env export').read() + '=' * 65
cs.write_smoothed_cal(output_replace=(CAL_SUFFIX, SMOOTH_CAL_SUFFIX), add_to_history=add_to_history, clobber=True)
Mean of empty slice
# write summary of entirely flagged times/freqs/ants to yaml
all_flagged_times = np.all([np.all(cs.flag_grids[ant], axis=1) for ant in cs.flag_grids], axis=0)
all_flagged_freqs = np.all([np.all(cs.flag_grids[ant], axis=0) for ant in cs.flag_grids], axis=0)
all_flagged_ants = sorted([ant for ant in cs.flag_grids if np.all(cs.flag_grids[ant])])
out_yml_str = 'JD_flags: ' + str([[cs.time_grid[flag_stretch][0] - cs.dt, cs.time_grid[flag_stretch][-1] + cs.dt]
for flag_stretch in true_stretches(all_flagged_times)])
chan_res = np.median(np.diff(cs.freqs))
out_yml_str += '\n\nfreq_flags: ' + str([[cs.freqs[flag_stretch][0] - chan_res / 2, cs.freqs[flag_stretch][-1] + chan_res / 2]
for flag_stretch in true_stretches(all_flagged_freqs)])
out_yml_str += '\n\nex_ants: ' + str(all_flagged_ants).replace("'", "").replace('(', '[').replace(')', ']')
print(f'Writing the following to {out_yaml_file}\n' + '-' * (25 + len(out_yaml_file)))
print(out_yml_str)
with open(out_yaml_file, 'w') as outfile:
outfile.writelines(out_yml_str)
Writing the following to /mnt/sn1/2460144/2460144_aposteriori_flags.yaml ------------------------------------------------------------------------ JD_flags: [[2460144.421081487, 2460144.4213051833], [2460144.4216407277, 2460144.421864424], [2460144.4224236645, 2460144.422871057], [2460144.423765842, 2460144.4243250825], [2460144.4253317155, 2460144.4255554117], [2460144.4264501967, 2460144.426673893], [2460144.4270094372, 2460144.4272331335], [2460144.427680526, 2460144.427904222], [2460144.4284634627, 2460144.428687159], [2460144.4290227033, 2460144.4292463996], [2460144.4302530326, 2460144.430476729], [2460144.4313715138, 2460144.431818906], [2460144.432489995, 2460144.432713691], [2460144.4328255393, 2460144.4330492355], [2460144.433496628, 2460144.433720324], [2460144.4348388053, 2460144.4351743497], [2460144.4357335903, 2460144.4359572865], [2460144.436516527, 2460144.4367402233], [2460144.4368520714, 2460144.4370757677], [2460144.43752316, 2460144.4377468564], [2460144.4379705526, 2460144.438306097], [2460144.43931273, 2460144.439536426], [2460144.4399838187, 2460144.440319363], [2460144.4408786036, 2460144.4411023], [2460144.4415496923, 2460144.4417733885], [2460144.442108933, 2460144.442332629], [2460144.443003718, 2460144.443227414], [2460144.443227414, 2460144.4434511103], [2460144.4444577433, 2460144.4446814395], [2460144.445016984, 2460144.44524068], [2460144.446023617, 2460144.446247313], [2460144.4463591613, 2460144.4465828575], [2460144.447253946, 2460144.4474776424], [2460144.447925035, 2460144.448148731], [2460144.4484842755, 2460144.448931668], [2460144.4497146048, 2460144.449938301], [2460144.450833086, 2460144.451056782], [2460144.4512804784, 2460144.4515041746], [2460144.451727871, 2460144.451951567], [2460144.452846352, 2460144.4530700482], [2460144.453964833, 2460144.4541885294], [2460144.4545240737, 2460144.454859618], [2460144.4550833143, 2460144.4553070106], [2460144.4559780993, 2460144.4563136436], [2460144.4574321248, 2460144.457655821], [2460144.457879517, 2460144.4581032135], [2460144.458438758, 2460144.458662454], [2460144.458774302, 2460144.4589979984], [2460144.459445391, 2460144.459669087], [2460144.461458657, 2460144.461682353], [2460144.4622415937, 2460144.462577138], [2460144.462688986, 2460144.4630245306], [2460144.4631363787, 2460144.463471923], [2460144.4638074674, 2460144.4641430117], [2460144.4650377966, 2460144.465261493], [2460144.466156278, 2460144.466379974], [2460144.4670510627, 2460144.467274759], [2460144.4678339995, 2460144.468169544], [2460144.4689524807, 2460144.469176177], [2460144.4695117213, 2460144.4698472656], [2460144.4707420506, 2460144.471077595], [2460144.4714131393, 2460144.4717486836], [2460144.472196076, 2460144.4724197723], [2460144.473202709, 2460144.4734264053], [2460144.4737619497, 2460144.473985646], [2460144.473985646, 2460144.474209342], [2460144.4747685827, 2460144.474992279], [2460144.475104127, 2460144.4754396714], [2460144.47611076, 2460144.4763344564], [2460144.4765581526, 2460144.476781849], [2460144.477117393, 2460144.4774529375], [2460144.4783477224, 2460144.4785714187], [2460144.4791306593, 2460144.4794662036], [2460144.4795780517, 2460144.479801748], [2460144.4803609885, 2460144.4805846848], [2460144.481032077, 2460144.4812557735], [2460144.4823742546, 2460144.482709799], [2460144.483716432, 2460144.4839401282], [2460144.4843875207, 2460144.484611217], [2460144.4849467613, 2460144.4851704575], [2460144.486400787, 2460144.486624483], [2460144.4868481793, 2460144.4870718755], [2460144.4872955717, 2460144.487519268], [2460144.4888614453, 2460144.4890851416], [2460144.489644382, 2460144.4899799265], [2460144.4908747114, 2460144.4910984077], [2460144.4910984077, 2460144.491322104], [2460144.491433952, 2460144.4916576482], [2460144.4918813445, 2460144.492216889], [2460144.492552433, 2460144.4927761294], [2460144.4931116737, 2460144.49333537], [2460144.49333537, 2460144.493559066], [2460144.494453851, 2460144.4946775474], [2460144.4950130917, 2460144.495236788], [2460144.495236788, 2460144.495460484], [2460144.4965789653, 2460144.4968026616], [2460144.497026358, 2460144.497250054], [2460144.498032991, 2460144.498256687], [2460144.4985922314, 2460144.4988159277], [2460144.499151472, 2460144.4993751682], [2460144.4995988645, 2460144.4998225607], [2460144.501276586, 2460144.5015002824]] freq_flags: [[46859741.2109375, 53207397.4609375], [53329467.7734375, 57479858.3984375], [57723999.0234375, 57846069.3359375], [57968139.6484375, 58212280.2734375], [58334350.5859375, 61019897.4609375], [61264038.0859375, 61386108.3984375], [62118530.2734375, 64193725.5859375], [64315795.8984375, 64559936.5234375], [65902709.9609375, 67733764.6484375], [69198608.3984375, 69442749.0234375], [69686889.6484375, 71395874.0234375], [72128295.8984375, 72372436.5234375], [74447631.8359375, 75668334.9609375], [81283569.3359375, 81527709.9609375], [84945678.7109375, 85067749.0234375], [85433959.9609375, 85922241.2109375], [87387084.9609375, 108261108.3984375], [109970092.7734375, 110092163.0859375], [112655639.6484375, 112777709.9609375], [113632202.1484375, 113754272.4609375], [116195678.7109375, 116317749.0234375], [116439819.3359375, 116561889.6484375], [116683959.9609375, 116806030.2734375], [124618530.2734375, 125228881.8359375], [136215209.9609375, 136459350.5859375], [136825561.5234375, 138168334.9609375], [138290405.2734375, 138412475.5859375], [141464233.3984375, 141586303.7109375], [141708374.0234375, 141830444.3359375], [142074584.9609375, 142318725.5859375], [143539428.7109375, 143661499.0234375], [143783569.3359375, 144027709.9609375], [144638061.5234375, 144760131.8359375], [145492553.7109375, 145736694.3359375], [147445678.7109375, 147567749.0234375], [148178100.5859375, 148422241.2109375], [149154663.0859375, 149276733.3984375], [154159545.8984375, 154403686.5234375], [155014038.0859375, 155258178.7109375], [155868530.2734375, 156112670.8984375], [158187866.2109375, 158432006.8359375], [159164428.7109375, 159286499.0234375], [161239624.0234375, 161483764.6484375], [175155639.6484375, 175277709.9609375], [178695678.7109375, 178817749.0234375], [179306030.2734375, 179428100.5859375], [180282592.7734375, 180404663.0859375], [182479858.3984375, 182601928.7109375], [183334350.5859375, 183578491.2109375], [185653686.5234375, 185775756.8359375], [186386108.3984375, 186630249.0234375], [187362670.8984375, 187728881.8359375], [188583374.0234375, 188949584.9609375], [190170288.0859375, 192611694.3359375], [193222045.8984375, 193466186.5234375], [195297241.2109375, 196273803.7109375], [196395874.0234375, 196640014.6484375], [196884155.2734375, 197006225.5859375], [197128295.8984375, 197372436.5234375], [198104858.3984375, 198348999.0234375], [199203491.2109375, 199325561.5234375], [199935913.0859375, 200180053.7109375], [200912475.5859375, 201034545.8984375], [201766967.7734375, 201889038.0859375], [203231811.5234375, 203353881.8359375], [204940795.8984375, 205062866.2109375], [206893920.8984375, 207015991.2109375], [207748413.0859375, 207870483.3984375], [208480834.9609375, 208724975.5859375], [209945678.7109375, 210067749.0234375], [210433959.9609375, 210556030.2734375], [212142944.3359375, 212265014.6484375], [213485717.7734375, 213607788.0859375], [215194702.1484375, 215316772.4609375], [215682983.3984375, 215805053.7109375], [216659545.8984375, 216781616.2109375], [219833374.0234375, 219955444.3359375], [220687866.2109375, 220809936.5234375], [221176147.4609375, 221298217.7734375], [223129272.4609375, 223373413.0859375], [225692749.0234375, 225814819.3359375], [226669311.5234375, 226791381.8359375], [227401733.3984375, 227645874.0234375], [229110717.7734375, 229476928.7109375], [230209350.5859375, 230331420.8984375], [231063842.7734375, 231185913.0859375], [232284545.8984375, 232406616.2109375], [232528686.5234375, 232650756.8359375], [233749389.6484375, 233871459.9609375], [233993530.2734375, 234237670.8984375]] ex_ants: [[4, Jee], [4, Jnn], [8, Jee], [8, Jnn], [10, Jee], [15, Jee], [18, Jee], [18, Jnn], [27, Jee], [27, Jnn], [28, Jnn], [29, Jee], [29, Jnn], [30, Jee], [32, Jee], [32, Jnn], [34, Jee], [40, Jnn], [43, Jee], [43, Jnn], [44, Jee], [44, Jnn], [45, Jee], [45, Jnn], [46, Jee], [46, Jnn], [47, Jee], [47, Jnn], [51, Jee], [54, Jee], [54, Jnn], [55, Jee], [58, Jee], [58, Jnn], [59, Jee], [59, Jnn], [60, Jee], [60, Jnn], [61, Jee], [61, Jnn], [63, Jnn], [73, Jee], [73, Jnn], [74, Jee], [74, Jnn], [77, Jee], [77, Jnn], [78, Jee], [80, Jnn], [84, Jee], [84, Jnn], [86, Jee], [87, Jee], [87, Jnn], [88, Jee], [88, Jnn], [89, Jee], [89, Jnn], [90, Jee], [90, Jnn], [91, Jee], [91, Jnn], [92, Jee], [92, Jnn], [93, Jnn], [96, Jnn], [97, Jnn], [104, Jnn], [105, Jee], [105, Jnn], [106, Jee], [106, Jnn], [107, Jee], [107, Jnn], [108, Jee], [108, Jnn], [109, Jee], [109, Jnn], [110, Jee], [111, Jee], [113, Jee], [113, Jnn], [114, Jee], [115, Jee], [115, Jnn], [121, Jee], [123, Jee], [124, Jee], [124, Jnn], [125, Jee], [125, Jnn], [126, Jee], [126, Jnn], [131, Jee], [131, Jnn], [133, Jee], [133, Jnn], [134, Jnn], [136, Jnn], [141, Jee], [143, Jee], [143, Jnn], [144, Jee], [144, Jnn], [145, Jee], [145, Jnn], [146, Jee], [146, Jnn], [151, Jee], [153, Jee], [155, Jee], [155, Jnn], [160, Jee], [161, Jnn], [163, Jee], [163, Jnn], [164, Jee], [164, Jnn], [165, Jee], [165, Jnn], [166, Jee], [166, Jnn], [173, Jee], [173, Jnn], [174, Jee], [174, Jnn], [175, Jnn], [180, Jnn], [182, Jnn], [183, Jnn], [184, Jee], [184, Jnn], [185, Jee], [185, Jnn], [186, Jee], [186, Jnn], [187, Jee], [187, Jnn], [189, Jee], [189, Jnn], [192, Jee], [192, Jnn], [193, Jee], [193, Jnn], [194, Jee], [195, Jee], [200, Jee], [200, Jnn], [201, Jee], [201, Jnn], [202, Jee], [202, Jnn], [204, Jee], [204, Jnn], [205, Jee], [205, Jnn], [206, Jee], [206, Jnn], [207, Jee], [207, Jnn], [208, Jnn], [209, Jee], [209, Jnn], [211, Jnn], [213, Jee], [213, Jnn], [214, Jee], [220, Jee], [220, Jnn], [221, Jee], [221, Jnn], [222, Jee], [222, Jnn], [223, Jee], [223, Jnn], [224, Jee], [224, Jnn], [225, Jee], [225, Jnn], [226, Jee], [226, Jnn], [237, Jee], [237, Jnn], [238, Jee], [238, Jnn], [239, Jee], [239, Jnn], [240, Jee], [240, Jnn], [241, Jee], [241, Jnn], [242, Jee], [242, Jnn], [243, Jee], [243, Jnn], [246, Jnn], [320, Jee], [320, Jnn], [324, Jee], [324, Jnn], [325, Jee], [325, Jnn], [329, Jee], [329, Jnn], [332, Jee], [332, Jnn], [333, Jee], [333, Jnn], [336, Jee], [336, Jnn], [340, Jee], [340, Jnn]]
for repo in ['hera_cal', 'hera_qm', 'hera_filters', 'hera_notebook_templates', 'pyuvdata']:
exec(f'from {repo} import __version__')
print(f'{repo}: {__version__}')
hera_cal: 3.3.0 hera_qm: 2.1.1 hera_filters: 0.1.0 hera_notebook_templates: 0.1.dev486+gfb8560a pyuvdata: 2.4.0
print(f'Finished execution in {(time.time() - tstart) / 60:.2f} minutes.')
Finished execution in 4.53 minutes.