Calibration Smoothing¶

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:

• Figure 1: Full-Day Gain Amplitudes Before and After smooth_cal¶

• Figure 2: Full-Day Gain Phases Before and After smooth_cal¶

• Figure 3: Full-Day $\chi^2$ / DoF Waterfall from Redundant-Baseline Calibration¶

• Figure 4: Average $\chi^2$ per Antenna vs. Time and Frequency¶

In [1]:
import time
tstart = time.time()
In [2]:
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

Parse inputs¶

In [3]:
# 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 = /lustre/aoc/projects/hera/h6c-analysis/IDR2/2459873/zen.2459873.25254.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 = /lustre/aoc/projects/hera/h6c-analysis/IDR2/2459873/2459873_aposteriori_flags.yaml

Load files¶

In [4]:
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 1862 *.sum.omni.calfits files starting with /lustre/aoc/projects/hera/h6c-analysis/IDR2/2459873/zen.2459873.25254.sum.omni.calfits.
In [5]:
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 1862 *.sum.flag_waterfall.h5 files starting with /lustre/aoc/projects/hera/h6c-analysis/IDR2/2459873/zen.2459873.25254.sum.flag_waterfall.h5.
In [6]:
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 1862 *.sum.antenna_flags.h5 files starting with /lustre/aoc/projects/hera/h6c-analysis/IDR2/2459873/zen.2459873.25254.sum.antenna_flags.h5.
In [7]:
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 123 selected for Jnn.
Reference antenna 123 selected for Jee.
In [8]:
# 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']}

Perform smoothing¶

In [9]:
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)
No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)

Plot results¶

In [10]:
lst_grid = utils.JD2LST(cs.time_grid) * 12 / np.pi
lst_grid[lst_grid > lst_grid[-1]] -= 24
In [11]:
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()    
In [12]:
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()

Figure 1: Full-Day Gain Amplitudes Before and After 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.

In [13]:
for ant_to_plot in ants_to_plot:
    amplitude_plot(ant_to_plot)

Antenna 15 Amplitude Waterfalls

Antenna 221 Amplitude Waterfalls

Figure 2: Full-Day Gain Phases Before and After 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.

In [14]:
for ant_to_plot in ants_to_plot:
    phase_plot(ant_to_plot)

Antenna 15 Phase Waterfalls

Antenna 221 Phase Waterfalls

Examine $\chi^2$¶

In [15]:
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)

Figure 3: Full-Day $\chi^2$ / DoF Waterfall from Redundant-Baseline Calibration¶

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.

In [16]:
chisq_plot()
FixedFormatter should only be used together with FixedLocator
In [17]:
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
In [18]:
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()
In [19]:
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()

Figure 4: Average $\chi^2$ per Antenna vs. Time and Frequency¶

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.

In [20]:
cspa_vs_time_plot()
cspa_vs_freq_plot()
Mean of empty slice
FixedFormatter should only be used together with FixedLocator

Save Results¶

In [21]:
add_to_history = 'Produced by calibration_smoothing notebook with the following environment:\n' + '=' * 65 + '\n' + os.popen('conda env export').read() + '=' * 65
In [22]:
cs.write_smoothed_cal(output_replace=(CAL_SUFFIX, SMOOTH_CAL_SUFFIX), add_to_history=add_to_history, clobber=True)
Mean of empty slice
In [23]:
# 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 /lustre/aoc/projects/hera/h6c-analysis/IDR2/2459873/2459873_aposteriori_flags.yaml
-----------------------------------------------------------------------------------------------------------
JD_flags: [[2459873.260257126, 2459873.260480822], [2459873.260480822, 2459873.2607045183], [2459873.2639481137, 2459873.264395506], [2459873.2674154053, 2459873.2676391015], [2459873.2676391015, 2459873.268086494], [2459873.269316823, 2459873.2695405195], [2459873.273007811, 2459873.2732315073], [2459873.2859821925, 2459873.2862058887], [2459873.288442851, 2459873.2886665473], [2459873.2886665473, 2459873.2888902435], [2459873.2916864464, 2459873.2920219908], [2459873.293140472, 2459873.293364168], [2459873.296272219, 2459873.2964959154], [2459873.2966077635, 2459873.2968314597], [2459873.3051082203, 2459873.3054437647], [2459873.3054437647, 2459873.305667461], [2459873.305667461, 2459873.305891157], [2459873.310700626, 2459873.3109243223], [2459873.3141679177, 2459873.314503462], [2459873.340452225, 2459873.3408996174], [2459873.341682554, 2459873.3419062505], [2459873.3429128835, 2459873.343248428], [2459873.3641640255, 2459873.3643877218], [2459873.3649469623, 2459873.3651706586], [2459873.3651706586, 2459873.365394355], [2459873.366400988, 2459873.366624684], [2459873.3788161287, 2459873.379039825], [2459873.3884350667, 2459873.388658763], [2459873.388770611, 2459873.3889943073], [2459873.4162852475, 2459873.416508944], [2459873.416508944, 2459873.41673264], [2459873.421430261, 2459873.421653957], [2459873.442010314, 2459873.4424577067], [2459873.4452539096, 2459873.445477606], [2459873.448721201, 2459873.4489448974], [2459873.4508463154, 2459873.4510700116], [2459873.4538662145, 2459873.4540899107], [2459873.454537303, 2459873.4547609994], [2459873.4550965438, 2459873.45532024], [2459873.458116443, 2459873.458340139], [2459873.459123076, 2459873.459346772], [2459873.4616955826, 2459873.461919279], [2459873.4633733043, 2459873.4635970006], [2459873.465162874, 2459873.4653865704], [2459873.4684064696, 2459873.468742014], [2459873.4693012545, 2459873.4695249507], [2459873.4695249507, 2459873.469748647], [2459873.4719856093, 2459873.4722093055], [2459873.473551483, 2459873.473775179], [2459873.474781812, 2459873.4750055084], [2459873.4767950783, 2459873.4770187745], [2459873.480486066, 2459873.4807097623], [2459873.489993156, 2459873.490216852], [2459873.496704043, 2459873.496927739], [2459873.4971514354, 2459873.497822524], [2459873.514264197, 2459873.5144878933], [2459873.5148234377, 2459873.515047134], [2459873.515158982, 2459873.5153826782], [2459873.5168367038, 2459873.517284096], [2459873.517284096, 2459873.5175077925], [2459873.5203039953, 2459873.5205276916], [2459873.5243305275, 2459873.5245542238], [2459873.5264556417, 2459873.526679338], [2459873.5338376174, 2459873.5340613136], [2459873.5340613136, 2459873.53428501], [2459873.53428501, 2459873.534508706], [2459873.568398685, 2459873.5686223814], [2459873.5800308893, 2459873.5802545855], [2459873.5820441553, 2459873.5822678516], [2459873.5842811177, 2459873.584504814], [2459873.585623295, 2459873.5858469913], [2459873.5955777774, 2459873.5958014736], [2459873.599045069, 2459873.599268765], [2459873.5993806133, 2459873.5996043095], [2459873.603966386, 2459873.6041900823], [2459873.6055322597, 2459873.605755956], [2459873.6070981333, 2459873.6074336777], [2459873.608552159, 2459873.608775855], [2459873.609558792, 2459873.609782488], [2459873.6101180324, 2459873.6103417287], [2459873.6121312985, 2459873.6123549948], [2459873.613361628, 2459873.613585324], [2459873.6139208684, 2459873.6141445646], [2459873.615374894, 2459873.61559859], [2459873.6160459826, 2459873.616269679], [2459873.6177237043, 2459873.6179474005], [2459873.6186184892, 2459873.6188421855], [2459873.619289578, 2459873.619513274], [2459873.6198488185, 2459873.6200725148], [2459873.621079148, 2459873.621302844], [2459873.622421325, 2459873.6227568695], [2459873.62331611, 2459873.6235398063], [2459873.6248819837, 2459873.62510568], [2459873.6254412243, 2459873.6256649205], [2459873.627007098, 2459873.627230794], [2459873.628237427, 2459873.6284611234], [2459873.6296914527, 2459873.629915149], [2459873.6323758075, 2459873.6325995037], [2459873.635954947, 2459873.6361786434], [2459873.644567252, 2459873.6447909484], [2459873.646356822, 2459873.646580518], [2459873.66190371, 2459873.6690619895]]

freq_flags: [[49911499.0234375, 50033569.3359375], [62240600.5859375, 62728881.8359375], [63217163.0859375, 63339233.3984375], [69931030.2734375, 70053100.5859375], [74081420.8984375, 74325561.5234375], [77865600.5859375, 77987670.8984375], [87509155.2734375, 108016967.7734375], [112167358.3984375, 112289428.7109375], [112655639.6484375, 112777709.9609375], [113265991.2109375, 113388061.5234375], [113632202.1484375, 113754272.4609375], [114486694.3359375, 114608764.6484375], [116439819.3359375, 116561889.6484375], [116683959.9609375, 116806030.2734375], [117050170.8984375, 117172241.2109375], [124740600.5859375, 125228881.8359375], [127548217.7734375, 127670288.0859375], [136215209.9609375, 136459350.5859375], [136947631.8359375, 137313842.7734375], [137435913.0859375, 137924194.3359375], [141464233.3984375, 141830444.3359375], [142074584.9609375, 142318725.5859375], [143783569.3359375, 144027709.9609375], [145492553.7109375, 145980834.9609375], [147323608.3984375, 147567749.0234375], [148178100.5859375, 148544311.5234375], [149154663.0859375, 149276733.3984375], [154159545.8984375, 154403686.5234375], [155258178.7109375, 155380249.0234375], [155868530.2734375, 156112670.8984375], [159164428.7109375, 159286499.0234375], [170883178.7109375, 171005249.0234375], [175155639.6484375, 175277709.9609375], [181137084.9609375, 181259155.2734375], [183212280.2734375, 183334350.5859375], [186386108.3984375, 186508178.7109375], [187362670.8984375, 187606811.5234375], [189193725.5859375, 189315795.8984375], [189682006.8359375, 189804077.1484375], [191146850.5859375, 191513061.5234375], [193222045.8984375, 193344116.2109375], [196395874.0234375, 196517944.3359375], [196884155.2734375, 197006225.5859375], [197128295.8984375, 197372436.5234375], [198104858.3984375, 198348999.0234375], [199203491.2109375, 199325561.5234375], [200057983.3984375, 200180053.7109375], [201766967.7734375, 201889038.0859375], [204940795.8984375, 205062866.2109375], [208480834.9609375, 208724975.5859375], [212142944.3359375, 212265014.6484375], [220565795.8984375, 220809936.5234375], [222640991.2109375, 223861694.3359375], [225692749.0234375, 225814819.3359375], [227401733.3984375, 227767944.3359375], [229110717.7734375, 229476928.7109375], [231063842.7734375, 231430053.7109375], [231552124.0234375, 234237670.8984375]]

ex_ants: [[4, Jee], [10, Jee], [18, Jee], [18, Jnn], [22, Jee], [22, Jnn], [27, Jee], [27, Jnn], [28, Jee], [28, Jnn], [32, Jee], [32, Jnn], [33, Jnn], [34, Jee], [43, Jee], [44, Jee], [44, Jnn], [46, Jnn], [47, Jee], [50, Jnn], [51, Jee], [51, Jnn], [54, Jee], [54, Jnn], [55, Jnn], [57, Jee], [58, Jee], [58, Jnn], [59, Jee], [60, Jee], [60, Jnn], [63, Jee], [63, Jnn], [64, Jee], [64, Jnn], [68, Jnn], [73, Jee], [73, Jnn], [74, Jee], [74, Jnn], [75, Jee], [75, Jnn], [77, Jee], [77, Jnn], [78, Jee], [78, Jnn], [84, Jnn], [92, Jee], [92, Jnn], [98, Jnn], [99, Jnn], [102, Jnn], [103, Jee], [103, Jnn], [104, Jnn], [108, Jee], [109, Jnn], [110, Jnn], [111, Jnn], [116, Jnn], [117, Jee], [117, Jnn], [120, Jnn], [121, Jee], [135, Jnn], [139, Jee], [140, Jee], [140, Jnn], [141, Jnn], [142, Jnn], [143, Jee], [146, Jee], [146, Jnn], [147, Jee], [147, Jnn], [150, Jee], [150, Jnn], [151, Jee], [153, Jee], [155, Jee], [156, Jee], [158, Jnn], [159, Jnn], [161, Jnn], [165, Jee], [166, Jee], [166, Jnn], [169, Jnn], [170, Jee], [173, Jee], [173, Jnn], [179, Jee], [179, Jnn], [180, Jee], [180, Jnn], [182, Jee], [183, Jee], [184, Jee], [184, Jnn], [185, Jee], [185, Jnn], [186, Jee], [186, Jnn], [187, Jee], [187, Jnn], [189, Jee], [189, Jnn], [190, Jee], [190, Jnn], [191, Jee], [191, Jnn], [192, Jnn], [193, Jee], [200, Jee], [200, Jnn], [201, Jee], [201, Jnn], [203, Jee], [203, Jnn], [219, Jee], [237, Jee], [237, Jnn], [238, Jee], [238, Jnn], [239, Jee], [239, Jnn], [320, Jee], [320, Jnn], [321, Jee], [321, Jnn], [322, Jee], [322, Jnn], [323, Jee], [323, Jnn], [324, Jee], [324, Jnn], [325, Jee], [325, Jnn], [329, Jee], [329, Jnn], [333, Jee], [333, Jnn]]

Metadata¶

In [24]:
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.2.3
hera_qm: 2.1.1
hera_filters: 0.1.4.dev2+ga4ff591
hera_notebook_templates: 0.1.dev531+gfe314a8
pyuvdata: 2.3.3.dev39+g16031096
In [25]:
print(f'Finished execution in {(time.time() - tstart) / 60:.2f} minutes.')
Finished execution in 39.57 minutes.