Single File Calibration¶

by Josh Dillon, Aaron Parsons, Tyler Cox, and Zachary Martinot, last updated February 18, 2024

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. Calibration includes redundant-baseline calibration, RFI-based calibration of delay slopes, model-based calibration of overall amplitudes, and a full per-frequency phase gradient absolute calibration if abscal model files are available.

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: Absolute calibration of redcal degeneracies¶

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

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

• Table 1: Complete summary of per antenna classifications¶

In [1]:
import time
tstart = time.time()
!hostname
bigmem2.rtp.pvt
In [2]:
# %load_ext memory_profiler
In [3]:
import os
os.environ['HDF5_USE_FILE_LOCKING'] = 'FALSE'
import h5py
import hdf5plugin  # REQUIRED to have the compression plugins available
import numpy as np
from scipy import constants, interpolate
import copy
import glob
import re
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'
# %memit
In [4]:
# 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 [5]:
# figure out whether to save results
SAVE_RESULTS = os.environ.get("SAVE_RESULTS", "TRUE").upper() == "TRUE"
SAVE_OMNIVIS_FILE = os.environ.get("SAVE_OMNIVIS_FILE", "FALSE").upper() == "TRUE"

# get infile names
SUM_FILE = os.environ.get("SUM_FILE", None)
# SUM_FILE = '/lustre/aoc/projects/hera/h6c-analysis/IDR2/2459866/zen.2459866.33010.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', 'SAVE_RESULTS', 'SAVE_OMNIVIS_FILE']:
    print(f"{fname} = '{eval(fname)}'")
SUM_FILE = '/mnt/sn1/2460369/zen.2460369.50293.sum.uvh5'
DIFF_FILE = '/mnt/sn1/2460369/zen.2460369.50293.diff.uvh5'
AM_FILE = '/mnt/sn1/2460369/zen.2460369.50293.sum.ant_metrics.hdf5'
ANTCLASS_FILE = '/mnt/sn1/2460369/zen.2460369.50293.sum.ant_class.csv'
OMNICAL_FILE = '/mnt/sn1/2460369/zen.2460369.50293.sum.omni.calfits'
OMNIVIS_FILE = '/mnt/sn1/2460369/zen.2460369.50293.sum.omni_vis.uvh5'
SAVE_RESULTS = 'True'
SAVE_OMNIVIS_FILE = 'False'

Parse settings¶

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

In [6]:
# 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", "FALSE").upper() == "TRUE"
OC_MIN_BL_LEN = float(os.environ.get("OC_MIN_BL_LEN", 1))
OC_MAX_BL_LEN = float(os.environ.get("OC_MAX_BL_LEN", 1e100))
OC_MAXITER = int(os.environ.get("OC_MAXITER", 50))
OC_MAX_RERUN = int(os.environ.get("OC_MAX_RERUN", 4))
OC_RERUN_MAXITER = int(os.environ.get("OC_MAXITER", 25))
OC_USE_PRIOR_SOL = os.environ.get("OC_USE_PRIOR_SOL", "FALSE").upper() == "TRUE"
OC_PRIOR_SOL_FLAG_THRESH = float(os.environ.get("OC_PRIOR_SOL_FLAG_THRESH", .95))
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))

# parse abscal settings
ABSCAL_MODEL_FILES_GLOB = os.environ.get("ABSCAL_MODEL_FILES_GLOB", None)
ABSCAL_MIN_BL_LEN = float(os.environ.get("ABSCAL_MIN_BL_LEN", 1.0))
ABSCAL_MAX_BL_LEN = float(os.environ.get("ABSCAL_MAX_BL_LEN", 140.0))

# print settings
for setting in ['PLOT', 'SAVE_RESULTS', 'OC_MAX_DIMS', 'OC_MIN_DIM_SIZE', 'OC_SKIP_OUTRIGGERS', 
                'OC_MIN_BL_LEN', 'OC_MAX_BL_LEN', 'OC_MAXITER', 'OC_MAX_RERUN', 'OC_RERUN_MAXITER', 
                'OC_USE_PRIOR_SOL', 'OC_PRIOR_SOL_FLAG_THRESH', 'OC_USE_GPU', 'RFI_DPSS_HALFWIDTH', 'RFI_NSIG',
                'ABSCAL_MODEL_FILES_GLOB', 'ABSCAL_MIN_BL_LEN', 'ABSCAL_MAX_BL_LEN']:
    print(f'{setting} = {eval(setting)}')
PLOT = True
SAVE_RESULTS = True
OC_MAX_DIMS = 4
OC_MIN_DIM_SIZE = 8
OC_SKIP_OUTRIGGERS = True
OC_MIN_BL_LEN = 1.0
OC_MAX_BL_LEN = 1e+100
OC_MAXITER = 50
OC_MAX_RERUN = 4
OC_RERUN_MAXITER = 50
OC_USE_PRIOR_SOL = True
OC_PRIOR_SOL_FLAG_THRESH = 0.95
OC_USE_GPU = False
RFI_DPSS_HALFWIDTH = 3e-07
RFI_NSIG = 6.0
ABSCAL_MODEL_FILES_GLOB = None
ABSCAL_MIN_BL_LEN = 1.0
ABSCAL_MAX_BL_LEN = 140.0

Parse bounds¶

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

In [7]:
# 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 solar altitude (in degrees)
good_solar_altitude = (-90, float(os.environ.get("SUSPECT_SOLAR_ALTITUDE", 0)))
suspect_solar_altitude = (float(os.environ.get("SUSPECT_SOLAR_ALTITUDE", 0)), 90)

# 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", 60)))

# 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.015)))
auto_rfi_suspect = (0, float(os.environ.get("AUTO_RFI_SUSPECT", 0.03)))

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

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

# print bounds
for bound in ['am_corr_bad', 'am_corr_suspect', 'am_xpol_bad', 'am_xpol_suspect', 
              'good_solar_altitude', 'suspect_solar_altitude',
              '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_solar_altitude = (-90, 0.0)
suspect_solar_altitude = (0.0, 90)
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, 60.0)
auto_slope_good = (-0.4, 0.4)
auto_slope_suspect = (-0.6, 0.6)
auto_rfi_good = (0, 0.015)
auto_rfi_suspect = (0, 0.03)
auto_shape_good = (0, 0.1)
auto_shape_suspect = (0, 0.2)
oc_cspa_good = (0, 2.0)
oc_cspa_suspect = (0, 3.0)

Load sum and diff data¶

In [8]:
read_start = time.time()
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, dtype=np.complex64)
print(f'Finished loading data in {(time.time() - read_start) / 60:.2f} minutes.')
# %memit
Finished loading data in 0.67 minutes.
In [9]:
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 [10]:
# 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/2460369/zen.2460369.50293.sum.uvh5
JDs: [2460369.50287817 2460369.50299002] (9.66368 s integrations)
LSTS: [12.05146374 12.05415545] hours
Frequencies: 1536 0.12207 MHz channels from 46.92078 to 234.29871 MHz
Antennas: 252
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 [11]:
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 [12]:
# Turn ant metrics into classifications
totally_dead_ants = [ant for ant, i in am.xants.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

Mark sun-up (or high solar altitude) data as suspect¶

In [13]:
min_sun_alt = np.min(utils.get_sun_alt(hd.times))
solar_class = ant_class.antenna_bounds_checker({ant: min_sun_alt for ant in ants}, good=[good_solar_altitude], suspect=[suspect_solar_altitude])

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 [14]:
zeros_class = ant_class.even_odd_zeros_checker(data, diff_data, good=good_zeros_per_eo_spectrum, suspect=suspect_zeros_per_eo_spectrum)

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 [15]:
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 [16]:
del cache
malloc_trim()

Find and flag RFI¶

In [17]:
# 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 [18]:
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 [19]:
rfi_plot()
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[19], line 1
----> 1 rfi_plot()

Cell In[18], line 8, in rfi_plot()
      6 plt.xlabel('Frequency (MHz)')
      7 plt.ylabel('Uncalibrated Autocorrelation')
----> 8 plt.tight_layout()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/pyplot.py:2599, in tight_layout(pad, h_pad, w_pad, rect)
   2591 @_copy_docstring_and_deprecators(Figure.tight_layout)
   2592 def tight_layout(
   2593     *,
   (...)
   2597     rect: tuple[float, float, float, float] | None = None,
   2598 ) -> None:
-> 2599     gcf().tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3540, in Figure.tight_layout(self, pad, h_pad, w_pad, rect)
   3538 previous_engine = self.get_layout_engine()
   3539 self.set_layout_engine(engine)
-> 3540 engine.execute(self)
   3541 if previous_engine is not None and not isinstance(
   3542     previous_engine, (TightLayoutEngine, PlaceHolderLayoutEngine)
   3543 ):
   3544     _api.warn_external('The figure layout has changed to tight')

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/layout_engine.py:183, in TightLayoutEngine.execute(self, fig)
    181 renderer = fig._get_renderer()
    182 with getattr(renderer, "_draw_disabled", nullcontext)():
--> 183     kwargs = get_tight_layout_figure(
    184         fig, fig.axes, get_subplotspec_list(fig.axes), renderer,
    185         pad=info['pad'], h_pad=info['h_pad'], w_pad=info['w_pad'],
    186         rect=info['rect'])
    187 if kwargs:
    188     fig.subplots_adjust(**kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_tight_layout.py:266, in get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer, pad, h_pad, w_pad, rect)
    261         return {}
    262     span_pairs.append((
    263         slice(ss.rowspan.start * div_row, ss.rowspan.stop * div_row),
    264         slice(ss.colspan.start * div_col, ss.colspan.stop * div_col)))
--> 266 kwargs = _auto_adjust_subplotpars(fig, renderer,
    267                                   shape=(max_nrows, max_ncols),
    268                                   span_pairs=span_pairs,
    269                                   subplot_list=subplot_list,
    270                                   ax_bbox_list=ax_bbox_list,
    271                                   pad=pad, h_pad=h_pad, w_pad=w_pad)
    273 # kwargs can be none if tight_layout fails...
    274 if rect is not None and kwargs is not None:
    275     # if rect is given, the whole subplots area (including
    276     # labels) will fit into the rect instead of the
   (...)
    280     # auto_adjust_subplotpars twice, where the second run
    281     # with adjusted rect parameters.

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_tight_layout.py:82, in _auto_adjust_subplotpars(fig, renderer, shape, span_pairs, subplot_list, ax_bbox_list, pad, h_pad, w_pad, rect)
     80 for ax in subplots:
     81     if ax.get_visible():
---> 82         bb += [martist._get_tightbbox_for_layout_only(ax, renderer)]
     84 tight_bbox_raw = Bbox.union(bb)
     85 tight_bbox = fig.transFigure.inverted().transform_bbox(tight_bbox_raw)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:1411, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
   1405 """
   1406 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
   1407 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
   1408 when encountering third-party subclasses that do not support it.
   1409 """
   1410 try:
-> 1411     return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
   1412 except TypeError:
   1413     return obj.get_tightbbox(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_api/deprecation.py:454, in make_keyword_only.<locals>.wrapper(*args, **kwargs)
    448 if len(args) > name_idx:
    449     warn_deprecated(
    450         since, message="Passing the %(name)s %(obj_type)s "
    451         "positionally is deprecated since Matplotlib %(since)s; the "
    452         "parameter will become keyword-only %(removal)s.",
    453         name=name, obj_type=f"parameter of {func.__name__}()")
--> 454 return func(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:4395, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
   4393 for axis in self._axis_map.values():
   4394     if self.axison and axis.get_visible():
-> 4395         ba = martist._get_tightbbox_for_layout_only(axis, renderer)
   4396         if ba:
   4397             bb.append(ba)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:1411, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
   1405 """
   1406 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
   1407 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
   1408 when encountering third-party subclasses that do not support it.
   1409 """
   1410 try:
-> 1411     return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
   1412 except TypeError:
   1413     return obj.get_tightbbox(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1336, in Axis.get_tightbbox(self, renderer, for_layout_only)
   1333     renderer = self.figure._get_renderer()
   1334 ticks_to_draw = self._update_ticks()
-> 1336 self._update_label_position(renderer)
   1338 # go back to just this axis's tick labels
   1339 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2368, in XAxis._update_label_position(self, renderer)
   2364     return
   2366 # get bounding boxes for this axis and any siblings
   2367 # that have been set by `fig.align_xlabels()`
-> 2368 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
   2370 x, y = self.label.get_position()
   2371 if self.label_position == 'bottom':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2161, in Axis._get_tick_boxes_siblings(self, renderer)
   2159 axis = ax._axis_map[name]
   2160 ticks_to_draw = axis._update_ticks()
-> 2161 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
   2162 bboxes.extend(tlb)
   2163 bboxes2.extend(tlb2)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1315, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1313 if renderer is None:
   1314     renderer = self.figure._get_renderer()
-> 1315 return ([tick.label1.get_window_extent(renderer)
   1316          for tick in ticks if tick.label1.get_visible()],
   1317         [tick.label2.get_window_extent(renderer)
   1318          for tick in ticks if tick.label2.get_visible()])

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
Error in callback <function _draw_all_if_interactive at 0x7f24c2a8ef20> (for post_execute), with arguments args (),kwargs {}:
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/pyplot.py:197, in _draw_all_if_interactive()
    195 def _draw_all_if_interactive() -> None:
    196     if matplotlib.is_interactive():
--> 197         draw_all()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_pylab_helpers.py:132, in Gcf.draw_all(cls, force)
    130 for manager in cls.get_all_fig_managers():
    131     if force or manager.canvas.figure.stale:
--> 132         manager.canvas.draw_idle()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backend_bases.py:1893, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
   1891 if not self._is_idle_drawing:
   1892     with self._idle_draw_cntx():
-> 1893         self.draw(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:388, in FigureCanvasAgg.draw(self)
    385 # Acquire a lock on the shared font cache.
    386 with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
    387       else nullcontext()):
--> 388     self.figure.draw(self.renderer)
    389     # A GUI class may be need to update a window using this draw, so
    390     # don't forget to call the superclass.
    391     super().draw()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3154, in Figure.draw(self, renderer)
   3151         # ValueError can occur when resizing a window.
   3153 self.patch.draw(renderer)
-> 3154 mimage._draw_list_compositing_images(
   3155     renderer, self, artists, self.suppressComposite)
   3157 for sfig in self.subfigs:
   3158     sfig.draw(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:3070, in _AxesBase.draw(self, renderer)
   3067 if artists_rasterized:
   3068     _draw_rasterized(self.figure, artists_rasterized, renderer)
-> 3070 mimage._draw_list_compositing_images(
   3071     renderer, self, artists, self.figure.suppressComposite)
   3073 renderer.close_group('axes')
   3074 self.stale = False

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1388, in Axis.draw(self, renderer, *args, **kwargs)
   1385 renderer.open_group(__name__, gid=self.get_gid())
   1387 ticks_to_draw = self._update_ticks()
-> 1388 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)
   1390 for tick in ticks_to_draw:
   1391     tick.draw(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1315, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1313 if renderer is None:
   1314     renderer = self.figure._get_renderer()
-> 1315 return ([tick.label1.get_window_extent(renderer)
   1316          for tick in ticks if tick.label1.get_visible()],
   1317         [tick.label2.get_window_extent(renderer)
   1318          for tick in ticks if tick.label2.get_visible()])

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/formatters.py:343, in BaseFormatter.__call__(self, obj)
    341     pass
    342 else:
--> 343     return printer(obj)
    344 # Finally look for special method names
    345 method = get_real_method(obj, self.print_method)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/pylabtools.py:169, in retina_figure(fig, base64, **kwargs)
    160 def retina_figure(fig, base64=False, **kwargs):
    161     """format a figure as a pixel-doubled (retina) PNG
    162 
    163     If `base64` is True, return base64-encoded str instead of raw bytes
   (...)
    167         base64 argument
    168     """
--> 169     pngdata = print_figure(fig, fmt="retina", base64=False, **kwargs)
    170     # Make sure that retina_figure acts just like print_figure and returns
    171     # None when the figure is empty.
    172     if pngdata is None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/pylabtools.py:152, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
    149     from matplotlib.backend_bases import FigureCanvasBase
    150     FigureCanvasBase(fig)
--> 152 fig.canvas.print_figure(bytes_io, **kw)
    153 data = bytes_io.getvalue()
    154 if fmt == 'svg':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backend_bases.py:2164, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
   2161     # we do this instead of `self.figure.draw_without_rendering`
   2162     # so that we can inject the orientation
   2163     with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2164         self.figure.draw(renderer)
   2165 if bbox_inches:
   2166     if bbox_inches == "tight":

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3154, in Figure.draw(self, renderer)
   3151         # ValueError can occur when resizing a window.
   3153 self.patch.draw(renderer)
-> 3154 mimage._draw_list_compositing_images(
   3155     renderer, self, artists, self.suppressComposite)
   3157 for sfig in self.subfigs:
   3158     sfig.draw(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:3070, in _AxesBase.draw(self, renderer)
   3067 if artists_rasterized:
   3068     _draw_rasterized(self.figure, artists_rasterized, renderer)
-> 3070 mimage._draw_list_compositing_images(
   3071     renderer, self, artists, self.figure.suppressComposite)
   3073 renderer.close_group('axes')
   3074 self.stale = False

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1388, in Axis.draw(self, renderer, *args, **kwargs)
   1385 renderer.open_group(__name__, gid=self.get_gid())
   1387 ticks_to_draw = self._update_ticks()
-> 1388 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)
   1390 for tick in ticks_to_draw:
   1391     tick.draw(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1315, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1313 if renderer is None:
   1314     renderer = self.figure._get_renderer()
-> 1315 return ([tick.label1.get_window_extent(renderer)
   1316          for tick in ticks if tick.label1.get_visible()],
   1317         [tick.label2.get_window_extent(renderer)
   1318          for tick in ticks if tick.label2.get_visible()])

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
<Figure size 1200x500 with 1 Axes>
In [20]:
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 [21]:
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
In [22]:
final_class = ant_metrics_class + solar_class + zeros_class + auto_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 [23]:
if PLOT: autocorr_plot(auto_class)
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[23], line 1
----> 1 if PLOT: autocorr_plot(auto_class)

Cell In[20], line 16, in autocorr_plot(cls)
     13 axes[0].set_ylabel('Raw Autocorrelation', fontsize=12)
     14 axes[1].legend([matplotlib.lines.Line2D([0], [0], color=color) for color in colors], 
     15                [cls.capitalize() for cls in auto_class.quality_classes], ncol=1, fontsize=12, loc='upper right', framealpha=1)
---> 16 plt.tight_layout()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/pyplot.py:2599, in tight_layout(pad, h_pad, w_pad, rect)
   2591 @_copy_docstring_and_deprecators(Figure.tight_layout)
   2592 def tight_layout(
   2593     *,
   (...)
   2597     rect: tuple[float, float, float, float] | None = None,
   2598 ) -> None:
-> 2599     gcf().tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3540, in Figure.tight_layout(self, pad, h_pad, w_pad, rect)
   3538 previous_engine = self.get_layout_engine()
   3539 self.set_layout_engine(engine)
-> 3540 engine.execute(self)
   3541 if previous_engine is not None and not isinstance(
   3542     previous_engine, (TightLayoutEngine, PlaceHolderLayoutEngine)
   3543 ):
   3544     _api.warn_external('The figure layout has changed to tight')

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/layout_engine.py:183, in TightLayoutEngine.execute(self, fig)
    181 renderer = fig._get_renderer()
    182 with getattr(renderer, "_draw_disabled", nullcontext)():
--> 183     kwargs = get_tight_layout_figure(
    184         fig, fig.axes, get_subplotspec_list(fig.axes), renderer,
    185         pad=info['pad'], h_pad=info['h_pad'], w_pad=info['w_pad'],
    186         rect=info['rect'])
    187 if kwargs:
    188     fig.subplots_adjust(**kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_tight_layout.py:266, in get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer, pad, h_pad, w_pad, rect)
    261         return {}
    262     span_pairs.append((
    263         slice(ss.rowspan.start * div_row, ss.rowspan.stop * div_row),
    264         slice(ss.colspan.start * div_col, ss.colspan.stop * div_col)))
--> 266 kwargs = _auto_adjust_subplotpars(fig, renderer,
    267                                   shape=(max_nrows, max_ncols),
    268                                   span_pairs=span_pairs,
    269                                   subplot_list=subplot_list,
    270                                   ax_bbox_list=ax_bbox_list,
    271                                   pad=pad, h_pad=h_pad, w_pad=w_pad)
    273 # kwargs can be none if tight_layout fails...
    274 if rect is not None and kwargs is not None:
    275     # if rect is given, the whole subplots area (including
    276     # labels) will fit into the rect instead of the
   (...)
    280     # auto_adjust_subplotpars twice, where the second run
    281     # with adjusted rect parameters.

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_tight_layout.py:82, in _auto_adjust_subplotpars(fig, renderer, shape, span_pairs, subplot_list, ax_bbox_list, pad, h_pad, w_pad, rect)
     80 for ax in subplots:
     81     if ax.get_visible():
---> 82         bb += [martist._get_tightbbox_for_layout_only(ax, renderer)]
     84 tight_bbox_raw = Bbox.union(bb)
     85 tight_bbox = fig.transFigure.inverted().transform_bbox(tight_bbox_raw)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:1411, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
   1405 """
   1406 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
   1407 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
   1408 when encountering third-party subclasses that do not support it.
   1409 """
   1410 try:
-> 1411     return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
   1412 except TypeError:
   1413     return obj.get_tightbbox(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_api/deprecation.py:454, in make_keyword_only.<locals>.wrapper(*args, **kwargs)
    448 if len(args) > name_idx:
    449     warn_deprecated(
    450         since, message="Passing the %(name)s %(obj_type)s "
    451         "positionally is deprecated since Matplotlib %(since)s; the "
    452         "parameter will become keyword-only %(removal)s.",
    453         name=name, obj_type=f"parameter of {func.__name__}()")
--> 454 return func(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:4395, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
   4393 for axis in self._axis_map.values():
   4394     if self.axison and axis.get_visible():
-> 4395         ba = martist._get_tightbbox_for_layout_only(axis, renderer)
   4396         if ba:
   4397             bb.append(ba)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:1411, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
   1405 """
   1406 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
   1407 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
   1408 when encountering third-party subclasses that do not support it.
   1409 """
   1410 try:
-> 1411     return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
   1412 except TypeError:
   1413     return obj.get_tightbbox(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1336, in Axis.get_tightbbox(self, renderer, for_layout_only)
   1333     renderer = self.figure._get_renderer()
   1334 ticks_to_draw = self._update_ticks()
-> 1336 self._update_label_position(renderer)
   1338 # go back to just this axis's tick labels
   1339 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2368, in XAxis._update_label_position(self, renderer)
   2364     return
   2366 # get bounding boxes for this axis and any siblings
   2367 # that have been set by `fig.align_xlabels()`
-> 2368 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
   2370 x, y = self.label.get_position()
   2371 if self.label_position == 'bottom':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2161, in Axis._get_tick_boxes_siblings(self, renderer)
   2159 axis = ax._axis_map[name]
   2160 ticks_to_draw = axis._update_ticks()
-> 2161 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
   2162 bboxes.extend(tlb)
   2163 bboxes2.extend(tlb2)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1315, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1313 if renderer is None:
   1314     renderer = self.figure._get_renderer()
-> 1315 return ([tick.label1.get_window_extent(renderer)
   1316          for tick in ticks if tick.label1.get_visible()],
   1317         [tick.label2.get_window_extent(renderer)
   1318          for tick in ticks if tick.label2.get_visible()])

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
Error in callback <function _draw_all_if_interactive at 0x7f24c2a8ef20> (for post_execute), with arguments args (),kwargs {}:
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/pyplot.py:197, in _draw_all_if_interactive()
    195 def _draw_all_if_interactive() -> None:
    196     if matplotlib.is_interactive():
--> 197         draw_all()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_pylab_helpers.py:132, in Gcf.draw_all(cls, force)
    130 for manager in cls.get_all_fig_managers():
    131     if force or manager.canvas.figure.stale:
--> 132         manager.canvas.draw_idle()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backend_bases.py:1893, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
   1891 if not self._is_idle_drawing:
   1892     with self._idle_draw_cntx():
-> 1893         self.draw(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:388, in FigureCanvasAgg.draw(self)
    385 # Acquire a lock on the shared font cache.
    386 with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
    387       else nullcontext()):
--> 388     self.figure.draw(self.renderer)
    389     # A GUI class may be need to update a window using this draw, so
    390     # don't forget to call the superclass.
    391     super().draw()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3154, in Figure.draw(self, renderer)
   3151         # ValueError can occur when resizing a window.
   3153 self.patch.draw(renderer)
-> 3154 mimage._draw_list_compositing_images(
   3155     renderer, self, artists, self.suppressComposite)
   3157 for sfig in self.subfigs:
   3158     sfig.draw(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:3034, in _AxesBase.draw(self, renderer)
   3031     for spine in self.spines.values():
   3032         artists.remove(spine)
-> 3034 self._update_title_position(renderer)
   3036 if not self.axison:
   3037     for _axis in self._axis_map.values():

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:2978, in _AxesBase._update_title_position(self, renderer)
   2976 top = max(top, bb.ymax)
   2977 if title.get_text():
-> 2978     ax.yaxis.get_tightbbox(renderer)  # update offsetText
   2979     if ax.yaxis.offsetText.get_text():
   2980         bb = ax.yaxis.offsetText.get_tightbbox(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1336, in Axis.get_tightbbox(self, renderer, for_layout_only)
   1333     renderer = self.figure._get_renderer()
   1334 ticks_to_draw = self._update_ticks()
-> 1336 self._update_label_position(renderer)
   1338 # go back to just this axis's tick labels
   1339 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2609, in YAxis._update_label_position(self, renderer)
   2605     return
   2607 # get bounding boxes for this axis and any siblings
   2608 # that have been set by `fig.align_ylabels()`
-> 2609 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
   2610 x, y = self.label.get_position()
   2611 if self.label_position == 'left':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2161, in Axis._get_tick_boxes_siblings(self, renderer)
   2159 axis = ax._axis_map[name]
   2160 ticks_to_draw = axis._update_ticks()
-> 2161 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
   2162 bboxes.extend(tlb)
   2163 bboxes2.extend(tlb2)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1315, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1313 if renderer is None:
   1314     renderer = self.figure._get_renderer()
-> 1315 return ([tick.label1.get_window_extent(renderer)
   1316          for tick in ticks if tick.label1.get_visible()],
   1317         [tick.label2.get_window_extent(renderer)
   1318          for tick in ticks if tick.label2.get_visible()])

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/formatters.py:343, in BaseFormatter.__call__(self, obj)
    341     pass
    342 else:
--> 343     return printer(obj)
    344 # Finally look for special method names
    345 method = get_real_method(obj, self.print_method)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/pylabtools.py:169, in retina_figure(fig, base64, **kwargs)
    160 def retina_figure(fig, base64=False, **kwargs):
    161     """format a figure as a pixel-doubled (retina) PNG
    162 
    163     If `base64` is True, return base64-encoded str instead of raw bytes
   (...)
    167         base64 argument
    168     """
--> 169     pngdata = print_figure(fig, fmt="retina", base64=False, **kwargs)
    170     # Make sure that retina_figure acts just like print_figure and returns
    171     # None when the figure is empty.
    172     if pngdata is None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/pylabtools.py:152, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
    149     from matplotlib.backend_bases import FigureCanvasBase
    150     FigureCanvasBase(fig)
--> 152 fig.canvas.print_figure(bytes_io, **kw)
    153 data = bytes_io.getvalue()
    154 if fmt == 'svg':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backend_bases.py:2164, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
   2161     # we do this instead of `self.figure.draw_without_rendering`
   2162     # so that we can inject the orientation
   2163     with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2164         self.figure.draw(renderer)
   2165 if bbox_inches:
   2166     if bbox_inches == "tight":

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3154, in Figure.draw(self, renderer)
   3151         # ValueError can occur when resizing a window.
   3153 self.patch.draw(renderer)
-> 3154 mimage._draw_list_compositing_images(
   3155     renderer, self, artists, self.suppressComposite)
   3157 for sfig in self.subfigs:
   3158     sfig.draw(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:3034, in _AxesBase.draw(self, renderer)
   3031     for spine in self.spines.values():
   3032         artists.remove(spine)
-> 3034 self._update_title_position(renderer)
   3036 if not self.axison:
   3037     for _axis in self._axis_map.values():

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:2978, in _AxesBase._update_title_position(self, renderer)
   2976 top = max(top, bb.ymax)
   2977 if title.get_text():
-> 2978     ax.yaxis.get_tightbbox(renderer)  # update offsetText
   2979     if ax.yaxis.offsetText.get_text():
   2980         bb = ax.yaxis.offsetText.get_tightbbox(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1336, in Axis.get_tightbbox(self, renderer, for_layout_only)
   1333     renderer = self.figure._get_renderer()
   1334 ticks_to_draw = self._update_ticks()
-> 1336 self._update_label_position(renderer)
   1338 # go back to just this axis's tick labels
   1339 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2609, in YAxis._update_label_position(self, renderer)
   2605     return
   2607 # get bounding boxes for this axis and any siblings
   2608 # that have been set by `fig.align_ylabels()`
-> 2609 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
   2610 x, y = self.label.get_position()
   2611 if self.label_position == 'left':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2161, in Axis._get_tick_boxes_siblings(self, renderer)
   2159 axis = ax._axis_map[name]
   2160 ticks_to_draw = axis._update_ticks()
-> 2161 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
   2162 bboxes.extend(tlb)
   2163 bboxes2.extend(tlb2)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1315, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1313 if renderer is None:
   1314     renderer = self.figure._get_renderer()
-> 1315 return ([tick.label1.get_window_extent(renderer)
   1316          for tick in ticks if tick.label1.get_visible()],
   1317         [tick.label2.get_window_extent(renderer)
   1318          for tick in ticks if tick.label2.get_visible()])

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
<Figure size 1400x500 with 2 Axes>

Classify antennas based on non-noiselike diffs¶

In [24]:
xengine_diff_class = ant_class.non_noiselike_diff_by_xengine_checker(data, diff_data, flag_waterfall=rfi_flags, 
                                                                     antenna_class=final_class, 
                                                                     xengine_chans=96, bad_xengine_zcut=10)
final_class += xengine_diff_class
In [25]:
# %memit
In [26]:
# delete diffs to save memory
del diff_data, hd_diff
malloc_trim()
# %memit

Summarize antenna classification prior to redundant-baseline calibration¶

In [27]:
def array_class_plot(cls, extra_label=""):
    outriggers = [ant for ant in hd.data_ants if ant >= 320]

    if len(outriggers) > 0:
        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=f'HERA Core{extra_label}')
        plot_antclass(hd.antpos, cls, ax=axes[1], ants=outriggers, radius=50, title='Outriggers')
    else:
        fig, axes = plt.subplots(1, 1, figsize=(9, 6), dpi=100)
        plot_antclass(hd.antpos, cls, ax=axes, ants=[ant for ant in hd.data_ants if ant < 320], legend=False, title=f'HERA Core{extra_label}')

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 [28]:
if PLOT: array_class_plot(final_class)
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[28], line 1
----> 1 if PLOT: array_class_plot(final_class)

Cell In[27], line 6, in array_class_plot(cls, extra_label)
      4 if len(outriggers) > 0:
      5     fig, axes = plt.subplots(1, 2, figsize=(14, 6), dpi=100, gridspec_kw={'width_ratios': [2, 1]})
----> 6     plot_antclass(hd.antpos, cls, ax=axes[0], ants=[ant for ant in hd.data_ants if ant < 320], legend=False, title=f'HERA Core{extra_label}')
      7     plot_antclass(hd.antpos, cls, ax=axes[1], ants=outriggers, radius=50, title='Outriggers')
      8 else:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/uvtools/plot.py:258, in plot_antclass(antpos, antclass, ax, ants, radius, ang_dict, colors, labelsize, labelcolor, legend, title)
    256 ax.set_xlim([np.min(xpos) - radius * 2, np.max(xpos) + radius * 2])
    257 ax.set_ylim([np.min(ypos) - radius * 2, np.max(ypos) + radius * 2])
--> 258 plt.tight_layout()
    260 # label antennas
    261 for ant in set([ant[0] for ant in ants]):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/pyplot.py:2599, in tight_layout(pad, h_pad, w_pad, rect)
   2591 @_copy_docstring_and_deprecators(Figure.tight_layout)
   2592 def tight_layout(
   2593     *,
   (...)
   2597     rect: tuple[float, float, float, float] | None = None,
   2598 ) -> None:
-> 2599     gcf().tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3540, in Figure.tight_layout(self, pad, h_pad, w_pad, rect)
   3538 previous_engine = self.get_layout_engine()
   3539 self.set_layout_engine(engine)
-> 3540 engine.execute(self)
   3541 if previous_engine is not None and not isinstance(
   3542     previous_engine, (TightLayoutEngine, PlaceHolderLayoutEngine)
   3543 ):
   3544     _api.warn_external('The figure layout has changed to tight')

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/layout_engine.py:183, in TightLayoutEngine.execute(self, fig)
    181 renderer = fig._get_renderer()
    182 with getattr(renderer, "_draw_disabled", nullcontext)():
--> 183     kwargs = get_tight_layout_figure(
    184         fig, fig.axes, get_subplotspec_list(fig.axes), renderer,
    185         pad=info['pad'], h_pad=info['h_pad'], w_pad=info['w_pad'],
    186         rect=info['rect'])
    187 if kwargs:
    188     fig.subplots_adjust(**kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_tight_layout.py:266, in get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer, pad, h_pad, w_pad, rect)
    261         return {}
    262     span_pairs.append((
    263         slice(ss.rowspan.start * div_row, ss.rowspan.stop * div_row),
    264         slice(ss.colspan.start * div_col, ss.colspan.stop * div_col)))
--> 266 kwargs = _auto_adjust_subplotpars(fig, renderer,
    267                                   shape=(max_nrows, max_ncols),
    268                                   span_pairs=span_pairs,
    269                                   subplot_list=subplot_list,
    270                                   ax_bbox_list=ax_bbox_list,
    271                                   pad=pad, h_pad=h_pad, w_pad=w_pad)
    273 # kwargs can be none if tight_layout fails...
    274 if rect is not None and kwargs is not None:
    275     # if rect is given, the whole subplots area (including
    276     # labels) will fit into the rect instead of the
   (...)
    280     # auto_adjust_subplotpars twice, where the second run
    281     # with adjusted rect parameters.

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_tight_layout.py:82, in _auto_adjust_subplotpars(fig, renderer, shape, span_pairs, subplot_list, ax_bbox_list, pad, h_pad, w_pad, rect)
     80 for ax in subplots:
     81     if ax.get_visible():
---> 82         bb += [martist._get_tightbbox_for_layout_only(ax, renderer)]
     84 tight_bbox_raw = Bbox.union(bb)
     85 tight_bbox = fig.transFigure.inverted().transform_bbox(tight_bbox_raw)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:1411, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
   1405 """
   1406 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
   1407 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
   1408 when encountering third-party subclasses that do not support it.
   1409 """
   1410 try:
-> 1411     return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
   1412 except TypeError:
   1413     return obj.get_tightbbox(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_api/deprecation.py:454, in make_keyword_only.<locals>.wrapper(*args, **kwargs)
    448 if len(args) > name_idx:
    449     warn_deprecated(
    450         since, message="Passing the %(name)s %(obj_type)s "
    451         "positionally is deprecated since Matplotlib %(since)s; the "
    452         "parameter will become keyword-only %(removal)s.",
    453         name=name, obj_type=f"parameter of {func.__name__}()")
--> 454 return func(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:4395, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
   4393 for axis in self._axis_map.values():
   4394     if self.axison and axis.get_visible():
-> 4395         ba = martist._get_tightbbox_for_layout_only(axis, renderer)
   4396         if ba:
   4397             bb.append(ba)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:1411, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
   1405 """
   1406 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
   1407 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
   1408 when encountering third-party subclasses that do not support it.
   1409 """
   1410 try:
-> 1411     return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
   1412 except TypeError:
   1413     return obj.get_tightbbox(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1336, in Axis.get_tightbbox(self, renderer, for_layout_only)
   1333     renderer = self.figure._get_renderer()
   1334 ticks_to_draw = self._update_ticks()
-> 1336 self._update_label_position(renderer)
   1338 # go back to just this axis's tick labels
   1339 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2368, in XAxis._update_label_position(self, renderer)
   2364     return
   2366 # get bounding boxes for this axis and any siblings
   2367 # that have been set by `fig.align_xlabels()`
-> 2368 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
   2370 x, y = self.label.get_position()
   2371 if self.label_position == 'bottom':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2161, in Axis._get_tick_boxes_siblings(self, renderer)
   2159 axis = ax._axis_map[name]
   2160 ticks_to_draw = axis._update_ticks()
-> 2161 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
   2162 bboxes.extend(tlb)
   2163 bboxes2.extend(tlb2)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1315, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1313 if renderer is None:
   1314     renderer = self.figure._get_renderer()
-> 1315 return ([tick.label1.get_window_extent(renderer)
   1316          for tick in ticks if tick.label1.get_visible()],
   1317         [tick.label2.get_window_extent(renderer)
   1318          for tick in ticks if tick.label2.get_visible()])

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
Error in callback <function _draw_all_if_interactive at 0x7f24c2a8ef20> (for post_execute), with arguments args (),kwargs {}:
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/pyplot.py:197, in _draw_all_if_interactive()
    195 def _draw_all_if_interactive() -> None:
    196     if matplotlib.is_interactive():
--> 197         draw_all()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_pylab_helpers.py:132, in Gcf.draw_all(cls, force)
    130 for manager in cls.get_all_fig_managers():
    131     if force or manager.canvas.figure.stale:
--> 132         manager.canvas.draw_idle()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backend_bases.py:1893, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
   1891 if not self._is_idle_drawing:
   1892     with self._idle_draw_cntx():
-> 1893         self.draw(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:388, in FigureCanvasAgg.draw(self)
    385 # Acquire a lock on the shared font cache.
    386 with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
    387       else nullcontext()):
--> 388     self.figure.draw(self.renderer)
    389     # A GUI class may be need to update a window using this draw, so
    390     # don't forget to call the superclass.
    391     super().draw()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3154, in Figure.draw(self, renderer)
   3151         # ValueError can occur when resizing a window.
   3153 self.patch.draw(renderer)
-> 3154 mimage._draw_list_compositing_images(
   3155     renderer, self, artists, self.suppressComposite)
   3157 for sfig in self.subfigs:
   3158     sfig.draw(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:3034, in _AxesBase.draw(self, renderer)
   3031     for spine in self.spines.values():
   3032         artists.remove(spine)
-> 3034 self._update_title_position(renderer)
   3036 if not self.axison:
   3037     for _axis in self._axis_map.values():

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:2978, in _AxesBase._update_title_position(self, renderer)
   2976 top = max(top, bb.ymax)
   2977 if title.get_text():
-> 2978     ax.yaxis.get_tightbbox(renderer)  # update offsetText
   2979     if ax.yaxis.offsetText.get_text():
   2980         bb = ax.yaxis.offsetText.get_tightbbox(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1336, in Axis.get_tightbbox(self, renderer, for_layout_only)
   1333     renderer = self.figure._get_renderer()
   1334 ticks_to_draw = self._update_ticks()
-> 1336 self._update_label_position(renderer)
   1338 # go back to just this axis's tick labels
   1339 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2609, in YAxis._update_label_position(self, renderer)
   2605     return
   2607 # get bounding boxes for this axis and any siblings
   2608 # that have been set by `fig.align_ylabels()`
-> 2609 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
   2610 x, y = self.label.get_position()
   2611 if self.label_position == 'left':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2161, in Axis._get_tick_boxes_siblings(self, renderer)
   2159 axis = ax._axis_map[name]
   2160 ticks_to_draw = axis._update_ticks()
-> 2161 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
   2162 bboxes.extend(tlb)
   2163 bboxes2.extend(tlb2)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1315, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1313 if renderer is None:
   1314     renderer = self.figure._get_renderer()
-> 1315 return ([tick.label1.get_window_extent(renderer)
   1316          for tick in ticks if tick.label1.get_visible()],
   1317         [tick.label2.get_window_extent(renderer)
   1318          for tick in ticks if tick.label2.get_visible()])

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/formatters.py:343, in BaseFormatter.__call__(self, obj)
    341     pass
    342 else:
--> 343     return printer(obj)
    344 # Finally look for special method names
    345 method = get_real_method(obj, self.print_method)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/pylabtools.py:169, in retina_figure(fig, base64, **kwargs)
    160 def retina_figure(fig, base64=False, **kwargs):
    161     """format a figure as a pixel-doubled (retina) PNG
    162 
    163     If `base64` is True, return base64-encoded str instead of raw bytes
   (...)
    167         base64 argument
    168     """
--> 169     pngdata = print_figure(fig, fmt="retina", base64=False, **kwargs)
    170     # Make sure that retina_figure acts just like print_figure and returns
    171     # None when the figure is empty.
    172     if pngdata is None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/pylabtools.py:152, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
    149     from matplotlib.backend_bases import FigureCanvasBase
    150     FigureCanvasBase(fig)
--> 152 fig.canvas.print_figure(bytes_io, **kw)
    153 data = bytes_io.getvalue()
    154 if fmt == 'svg':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backend_bases.py:2164, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
   2161     # we do this instead of `self.figure.draw_without_rendering`
   2162     # so that we can inject the orientation
   2163     with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2164         self.figure.draw(renderer)
   2165 if bbox_inches:
   2166     if bbox_inches == "tight":

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3154, in Figure.draw(self, renderer)
   3151         # ValueError can occur when resizing a window.
   3153 self.patch.draw(renderer)
-> 3154 mimage._draw_list_compositing_images(
   3155     renderer, self, artists, self.suppressComposite)
   3157 for sfig in self.subfigs:
   3158     sfig.draw(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:3034, in _AxesBase.draw(self, renderer)
   3031     for spine in self.spines.values():
   3032         artists.remove(spine)
-> 3034 self._update_title_position(renderer)
   3036 if not self.axison:
   3037     for _axis in self._axis_map.values():

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:2978, in _AxesBase._update_title_position(self, renderer)
   2976 top = max(top, bb.ymax)
   2977 if title.get_text():
-> 2978     ax.yaxis.get_tightbbox(renderer)  # update offsetText
   2979     if ax.yaxis.offsetText.get_text():
   2980         bb = ax.yaxis.offsetText.get_tightbbox(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1336, in Axis.get_tightbbox(self, renderer, for_layout_only)
   1333     renderer = self.figure._get_renderer()
   1334 ticks_to_draw = self._update_ticks()
-> 1336 self._update_label_position(renderer)
   1338 # go back to just this axis's tick labels
   1339 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2609, in YAxis._update_label_position(self, renderer)
   2605     return
   2607 # get bounding boxes for this axis and any siblings
   2608 # that have been set by `fig.align_ylabels()`
-> 2609 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
   2610 x, y = self.label.get_position()
   2611 if self.label_position == 'left':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2161, in Axis._get_tick_boxes_siblings(self, renderer)
   2159 axis = ax._axis_map[name]
   2160 ticks_to_draw = axis._update_ticks()
-> 2161 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
   2162 bboxes.extend(tlb)
   2163 bboxes2.extend(tlb2)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1315, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1313 if renderer is None:
   1314     renderer = self.figure._get_renderer()
-> 1315 return ([tick.label1.get_window_extent(renderer)
   1316          for tick in ticks if tick.label1.get_visible()],
   1317         [tick.label2.get_window_extent(renderer)
   1318          for tick in ticks if tick.label2.get_visible()])

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
<Figure size 1400x600 with 2 Axes>

Perform redundant-baseline calibration¶

In [29]:
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)
In [30]:
def per_pol_filter_reds(reds, pols=['nn', 'ee'], **kwargs):
    '''Performs redcal filtering separately on polarizations (which might have different min_dim_size issues).'''
    return [red for pol in pols for red in redcal.filter_reds(copy.deepcopy(reds), pols=[pol], **kwargs)]
In [31]:
def check_if_whole_pol_flagged(redcal_class, pols=['Jee', 'Jnn']):
    '''Checks if an entire polarization is flagged. If it is, returns True and marks all antennas as bad in redcal_class.'''
    if np.logical_or(*[np.all([redcal_class[ant] == 'bad' for ant in redcal_class.ants if ant[1] == pol]) for pol in pols]):
        print('An entire polarization has been flagged. Stopping redcal.')
        for ant in redcal_class:
            redcal_class[ant] = 'bad'
        return True
    return False
In [32]:
def recheck_chisq(cspa, sol, cutoff, avg_alg):
    '''Recompute chisq per ant without apparently bad antennas to see if any antennas get better.'''
    avg_cspa = {ant: avg_alg(np.where(rfi_flags, np.nan, cspa[ant])) for ant in cspa}
    sol2 = redcal.RedSol(sol.reds, gains={ant: sol[ant] for ant in avg_cspa if avg_cspa[ant] <= cutoff}, vis=sol.vis)
    new_chisq_per_ant = {ant: np.array(cspa[ant]) for ant in sol2.gains}
    if len(set([bl[2] for red in per_pol_filter_reds(sol2.reds, ants=sol2.gains.keys(), antpos=hd.data_antpos, **fr_settings) for bl in red])) >= 2:
        redcal.expand_omni_gains(sol2, sol2.reds, data, chisq_per_ant=new_chisq_per_ant)
    for ant in avg_cspa:
        if ant in new_chisq_per_ant:
            if np.any(np.isfinite(new_chisq_per_ant[ant])):
                if not np.all(np.isclose(new_chisq_per_ant[ant], 0)):
                    new_avg_cspa = avg_alg(np.where(rfi_flags, np.nan, cspa[ant]))
                    if new_avg_cspa > 0:
                        avg_cspa[ant] = np.min([avg_cspa[ant], new_avg_cspa])
    return avg_cspa

Perform iterative redcal¶

In [33]:
# figure out and filter reds and classify antennas based on whether or not they are on the main grid
fr_settings = {'max_dims': OC_MAX_DIMS, 'min_dim_size': OC_MIN_DIM_SIZE, 'min_bl_cut': OC_MIN_BL_LEN, 'max_bl_cut': OC_MAX_BL_LEN}
reds = redcal.get_reds(hd.data_antpos, pols=['ee', 'nn'], pol_mode='2pol')
reds = per_pol_filter_reds(reds, ex_ants=final_class.bad_ants, antpos=hd.data_antpos, **fr_settings)
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)
In [34]:
if OC_USE_PRIOR_SOL:
    # Find closest omnical file
    omnical_files = sorted(glob.glob('.'.join(OMNICAL_FILE.split('.')[:-5]) + '.*.' + '.'.join(OMNICAL_FILE.split('.')[-3:])))
    if len(omnical_files) == 0:
        OC_USE_PRIOR_SOL = False
    else:
        omnical_jds = np.array([float(re.findall("\d+\.\d+", ocf)[-1]) for ocf in omnical_files])
        closest_omnical = omnical_files[np.argmin(np.abs(omnical_jds - data.times[0]))]

        # Load closest omnical file and use it if the antenna flagging is not too dissimilar
        hc = io.HERACal(closest_omnical)
        prior_gains, prior_flags, _, _ = hc.read()
        not_bad_not_prior_flagged = [ant for ant in final_class if not ant in redcal_class.bad_ants and not np.all(prior_flags[ant])]
        if (len(redcal_class.bad_ants) == len(redcal_class.ants)):
            OC_USE_PRIOR_SOL = False  # all antennas flagged
        elif (len(not_bad_not_prior_flagged) / (len(redcal_class.ants) - len(redcal_class.bad_ants))) < OC_PRIOR_SOL_FLAG_THRESH:
            OC_USE_PRIOR_SOL = False  # too many antennas unflaged that were flagged in the prior sol
        else:
            print(f'Using {closest_omnical} as a starting point for redcal.')
#     %memit
Using /mnt/sn1/2460369/zen.2460369.51233.sum.omni.calfits as a starting point for redcal.
In [35]:
redcal_start = time.time()
rc_settings = {'max_dims': OC_MAX_DIMS, 'oc_conv_crit': 1e-10, 'gain': 0.4, 'run_logcal': False,
               'oc_maxiter': OC_MAXITER, 'check_after': OC_MAXITER, 'use_gpu': OC_USE_GPU}

if check_if_whole_pol_flagged(redcal_class):
    # skip redcal, initialize empty sol and meta 
    sol = redcal.RedSol(reds)
    meta = {'chisq': None, 'chisq_per_ant': None}
else:    
    if OC_USE_PRIOR_SOL:
        # use prior gains and data to create starting point for next step
        ants_in_reds = set([ant for red in reds for bl in red for ant in utils.split_bl(bl)])
        sol = redcal.RedSol(reds=reds, gains={ant: prior_gains[ant] for ant in ants_in_reds})
        sol.update_vis_from_data(data)
    else:
        # perform first stage of redundant calibration 
        meta, sol = redcal.redundantly_calibrate(data, reds, **rc_settings)
        max_dly = np.max(np.abs(list(meta['fc_meta']['dlys'].values())))  # Needed for RFI delay-slope cal
        median_cspa = recheck_chisq(meta['chisq_per_ant'], sol, oc_cspa_suspect[1] * 5, np.nanmedian)
         # remove particularly bad antennas (5x the bound on median, not mean)
        cspa_class = ant_class.antenna_bounds_checker(median_cspa, good=(oc_cspa_good[0], oc_cspa_suspect[1] * 5), bad=[(-np.inf, np.inf)])
        redcal_class += cspa_class
        print(f'Removing {cspa_class.bad_ants} for high chi^2.')
        
    malloc_trim()
# %memit
In [36]:
# iteratively rerun redundant calibration
redcal_done = False
rc_settings['oc_maxiter'] = rc_settings['check_after'] = OC_RERUN_MAXITER
for i in range(OC_MAX_RERUN + 1):
    # refilter reds and update classification to reflect new off-grid ants, if any
    reds = per_pol_filter_reds(reds, ex_ants=(final_class + redcal_class).bad_ants, antpos=hd.data_antpos, **fr_settings)
    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)])
    
    # check to see whether we're done
    if redcal_done or (i == OC_MAX_RERUN) or check_if_whole_pol_flagged(redcal_class):
        break

    # re-run redundant calibration using previous solution, updating bad and suspicious antennas
    meta, sol = redcal.redundantly_calibrate(data, reds, sol0=sol, **rc_settings)
    malloc_trim()
    
    # recompute chi^2 for bad antennas without bad antennas to make sure they are actually bad
    mean_cspa = recheck_chisq(meta['chisq_per_ant'], sol, oc_cspa_suspect[1], np.nanmean)
    
    # remove bad antennas
    cspa_class = ant_class.antenna_bounds_checker(mean_cspa, good=oc_cspa_good, suspect=oc_cspa_suspect, bad=[(-np.inf, np.inf)])
    redcal_class += cspa_class
    print(f'Removing {cspa_class.bad_ants} for high chi^2.')
    if len(cspa_class.bad_ants) == 0:
        redcal_done = True  # no new antennas to flag

print(f'Finished redcal in {(time.time() - redcal_start) / 60:.2f} minutes.')
# %memit
Removing {(93, 'Jee'), (28, 'Jnn')} for high chi^2.
Removing set() for high chi^2.
Finished redcal in 8.56 minutes.
In [37]:
final_class += redcal_class

Expand solution to include calibratable baselines excluded from redcal (e.g. because they were too long)¶

In [38]:
expanded_reds = redcal.get_reds(hd.data_antpos, pols=['ee', 'nn'], pol_mode='2pol')
expanded_reds = per_pol_filter_reds(expanded_reds, ex_ants=(ant_metrics_class + solar_class + zeros_class + auto_class + xengine_diff_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])
if len(sol.gains) > 0:
    redcal.expand_omni_vis(sol, expanded_reds, data, chisq=meta['chisq'], chisq_per_ant=meta['chisq_per_ant'])
In [39]:
# now figure out flags, nsamples etc.
omni_flags = {ant: (~np.isfinite(g)) | (ant in final_class.bad_ants) for ant, g in sol.gains.items()}
vissol_flags = datacontainer.RedDataContainer({bl: ~np.isfinite(v) for bl, v in sol.vis.items()}, reds=sol.vis.reds)
single_nsamples_array = np.ones((len(hd.times), len(hd.freqs)), dtype=float)
nsamples = datacontainer.DataContainer({bl: single_nsamples_array for bl in data})
vissol_nsamples = redcal.count_redundant_nsamples(nsamples, [red for red in expanded_reds if red[0] in vissol_flags], 
                                                  good_ants=[ant for ant in final_class if ant not in final_class.bad_ants])
for bl in vissol_flags:
    vissol_flags[bl][vissol_nsamples[bl] == 0] = True
sol.make_sol_finite()

Fix the firstcal delay slope degeneracy using RFI transmitters¶

In [40]:
if not OC_USE_PRIOR_SOL:
    # find channels clearly contaminated by RFI
    not_bad_ants = [ant for ant in final_class.ants if final_class[ant] != 'bad']
    if len(not_bad_ants) > 0:
        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)}

        if not np.isclose(hd.freqs[0], 46920776.3671875, atol=0.001) or len(hd.freqs) != 1536:
            # We have less frequencies than usual (maybe testing)
            phs_sol = {np.argmin(np.abs(hd.freqs - freq)): (freq, heading, chisq) for chan, (freq, heading, chisq) in phs_sol.items() if hd.freqs[0] <= freq <= hd.freqs[-1]}


        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])

        # resolve firstcal degeneracy with delay slopes set by RFI transmitters, update cal
        RFI_dly_slope_gains = abscal.RFI_delay_slope_cal([red for red in expanded_reds if red[0] in sol.vis], hd.antpos, sol.vis, hd.freqs, rfi_chans, rfi_headings, rfi_wgts=rfi_chisqs**-1,
                                                         min_tau=-max_dly, max_tau=max_dly, delta_tau=0.1e-9, return_gains=True, gain_ants=sol.gains.keys())
        sol.gains = {ant: g * RFI_dly_slope_gains[ant] for ant, g in sol.gains.items()}
        apply_cal.calibrate_in_place(sol.vis, RFI_dly_slope_gains)
        malloc_trim()

Perform absolute amplitude calibration using a model of autocorrelations¶

In [41]:
# 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 [42]:
# Run abscal and update omnical gains with abscal gains
if len(model) > 0:
    redcaled_autos = {bl: sol.calibrate_bl(bl, data[bl]) for bl in auto_bls if utils.split_bl(bl)[0] not in final_class.bad_ants}
    g_abscal = abscal.abs_amp_logcal(model, redcaled_autos, verbose=False, return_gains=True, gain_ants=sol.gains)
    sol.gains = {ant: g * g_abscal[ant] for ant, g in sol.gains.items()}
    apply_cal.calibrate_in_place(sol.vis, g_abscal)
    del redcaled_autos, g_abscal
In [43]:
# %memit
In [44]:
del hd_model, model
malloc_trim()
# %memit

Full absolute calibration of phase gradients¶

If an ABSCAL_MODEL_FILES_GLOB is provided, try to perform a full absolute calibration of tip-tilt phase gradients across the array using that those model files. Specifically, this step calibrates omnical visbility solutions using unique baselines simulated with a model of the sky and HERA's beam.

In [45]:
if ABSCAL_MODEL_FILES_GLOB is not None:
    abscal_model_files = sorted(glob.glob(ABSCAL_MODEL_FILES_GLOB))
else:
    # try to find files on site
    abscal_model_files = sorted(glob.glob('/mnt/sn1/abscal_models/H4C_1/abscal_files_unique_baselines/zen.2458894.?????.uvh5'))
    if len(abscal_model_files) == 0:
        # try to find files at NRAO
        abscal_model_files = sorted(glob.glob('/lustre/aoc/projects/hera/zmartino/hera_calib_model/H4C_1/abscal_files_unique_baselines/zen.2458894.?????.uvh5'))
print(f'Found {len(abscal_model_files)} abscal model files{" in " + os.path.dirname(abscal_model_files[0]) if len(abscal_model_files) > 0 else ""}.')
Found 425 abscal model files in /mnt/sn1/abscal_models/H4C_1/abscal_files_unique_baselines.
In [46]:
# Try to perform a full abscal of phase
if len(abscal_model_files) == 0:
    DO_FULL_ABSCAL = False
    print('No model files found... not performing full absolute calibration of phase gradients.')
elif np.all([ant in final_class.bad_ants for ant in ants]):
    DO_FULL_ABSCAL = False
    print('All antennas classified as bad... skipping absolute calibration of phase gradients.')
else:
    abscal_start = time.time()
    # figure out which model files match the LSTs of the data
    matched_model_files = sorted(set(abscal.match_times(SUM_FILE, abscal_model_files, filetype='uvh5')))
    if len(matched_model_files) == 0:
        DO_FULL_ABSCAL = False
        print(f'No model files found matching the LSTs of this file after searching for {(time.time() - abscal_start) / 60:.2f} minutes. '
              'Not performing full absolute calibration of phase gradients.')
    else:
        DO_FULL_ABSCAL = True
        # figure out appropriate model times to load
        hdm = io.HERAData(matched_model_files)
        all_model_times, all_model_lsts = abscal.get_all_times_and_lsts(hdm, unwrap=True)
        d2m_time_map = abscal.get_d2m_time_map(data.times, np.unwrap(data.lsts), all_model_times, all_model_lsts, extrap_limit=.5)
#         %memit
In [47]:
if DO_FULL_ABSCAL:
    abscal_meta = {}
    for pol in ['ee', 'nn']:
        print(f'Performing absolute phase gradient calibration of {pol}-polarized visibility solutions...')
        
        # load matching times and baselines
        unflagged_data_bls = [bl for bl in vissol_flags if not np.all(vissol_flags[bl]) and bl[2] == pol]
        model_bls = copy.deepcopy(hdm.bls)
        model_antpos = hdm.data_antpos
        if len(matched_model_files) > 1:  # in this case, it's a dictionary
            model_bls = list(set([bl for bls in list(hdm.bls.values()) for bl in bls]))
            model_antpos = {ant: pos for antpos in hdm.data_antpos.values() for ant, pos in antpos.items()}
        data_bls, model_bls, data_to_model_bl_map = abscal.match_baselines(unflagged_data_bls, model_bls, data.antpos, model_antpos=model_antpos, 
                                                                         pols=[pol], data_is_redsol=True, model_is_redundant=True, tol=1.0,
                                                                         min_bl_cut=ABSCAL_MIN_BL_LEN, max_bl_cut=ABSCAL_MAX_BL_LEN, verbose=True)
        model, model_flags, _ = io.partial_time_io(hdm, np.unique([d2m_time_map[time] for time in data.times]), bls=model_bls)
        model_bls = [data_to_model_bl_map[bl] for bl in data_bls]
        
        # rephase model to match in lsts
        model_blvecs = {bl: model.antpos[bl[0]] - model.antpos[bl[1]] for bl in model.keys()}
        utils.lst_rephase(model, model_blvecs, model.freqs, data.lsts - model.lsts,
                          lat=hdm.telescope_location_lat_lon_alt_degrees[0], inplace=True)

        # run abscal and apply 
        abscal_meta[pol], delta_gains = abscal.complex_phase_abscal(sol.vis, model, sol.reds, data_bls, model_bls)
        
        # apply gains
        sol.gains = {antpol : g * delta_gains.get(antpol, 1) for antpol, g in sol.gains.items()}
        apply_cal.calibrate_in_place(sol.vis, delta_gains)            
     
    del hdm, model, model_flags, delta_gains
    malloc_trim()    
    
    print(f'Finished absolute calibration of tip-tilt phase slopes in {(time.time() - abscal_start) / 60:.2f} minutes.')
#     %memit
Performing absolute phase gradient calibration of ee-polarized visibility solutions...
Selected 479 data baselines and 479 model baselines to load.
Performing absolute phase gradient calibration of nn-polarized visibility solutions...
Selected 480 data baselines and 480 model baselines to load.
Finished absolute calibration of tip-tilt phase slopes in 0.46 minutes.
In [48]:
def redundant_group_plot():
    if np.all([ant in final_class.bad_ants for ant in ants]):
        print('All antennas classified as bad. Nothing to plot.')
        return
    
    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: sol.calibrate_bl(bl, data[bl]) for bl in red}
        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(sol.vis[red[0]][0]), lw=1, c='k')
        axes[1, i].semilogy(hd.freqs / 1e6, np.abs(sol.vis[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()
In [49]:
def abscal_degen_plot():
    if DO_FULL_ABSCAL:
        fig, axes = plt.subplots(3, 1, figsize=(14, 6), dpi=100, sharex=True, gridspec_kw={'hspace': .05})

        for ax, pol in zip(axes[:2], ['ee', 'nn']):
            for kk in range(abscal_meta[pol]['Lambda_sol'].shape[-1]):
                ax.plot(hd.freqs[~rfi_flags[0]] * 1e-6, abscal_meta[pol]['Lambda_sol'][0, ~rfi_flags[0], kk], '.', ms=1, label=f"Component {kk}")

            ax.set_ylim(-np.pi-0.5, np.pi+0.5)
            ax.set_xlabel('Frequency (MHz)')
            ax.set_ylabel('Phase Gradient\nVector Component')
            ax.legend(markerscale=20, title=f'{pol}-polarization', loc='lower right')
            ax.grid()
            
        for pol, color in zip(['ee', 'nn'], ['b', 'r']):
            axes[2].plot(hd.freqs[~rfi_flags[0]]*1e-6, abscal_meta[pol]['Z_sol'].real[0, ~rfi_flags[0]], '.', ms=1, label=pol, color=color)
        axes[2].set_ylim(-.25, 1.05)
        axes[2].set_ylabel('Re[Z($\\nu$)]')
        axes[2].legend(markerscale=20, loc='lower right')
        axes[2].grid()            
        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 [50]:
if PLOT: redundant_group_plot()
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[50], line 1
----> 1 if PLOT: redundant_group_plot()

Cell In[48], line 20, in redundant_group_plot()
     18 axes[0, 0].set_ylabel('Visibility Phase (radians)')
     19 axes[1, 0].set_ylabel('Visibility Amplitude (Jy)')
---> 20 plt.tight_layout()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/pyplot.py:2599, in tight_layout(pad, h_pad, w_pad, rect)
   2591 @_copy_docstring_and_deprecators(Figure.tight_layout)
   2592 def tight_layout(
   2593     *,
   (...)
   2597     rect: tuple[float, float, float, float] | None = None,
   2598 ) -> None:
-> 2599     gcf().tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3540, in Figure.tight_layout(self, pad, h_pad, w_pad, rect)
   3538 previous_engine = self.get_layout_engine()
   3539 self.set_layout_engine(engine)
-> 3540 engine.execute(self)
   3541 if previous_engine is not None and not isinstance(
   3542     previous_engine, (TightLayoutEngine, PlaceHolderLayoutEngine)
   3543 ):
   3544     _api.warn_external('The figure layout has changed to tight')

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/layout_engine.py:183, in TightLayoutEngine.execute(self, fig)
    181 renderer = fig._get_renderer()
    182 with getattr(renderer, "_draw_disabled", nullcontext)():
--> 183     kwargs = get_tight_layout_figure(
    184         fig, fig.axes, get_subplotspec_list(fig.axes), renderer,
    185         pad=info['pad'], h_pad=info['h_pad'], w_pad=info['w_pad'],
    186         rect=info['rect'])
    187 if kwargs:
    188     fig.subplots_adjust(**kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_tight_layout.py:266, in get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer, pad, h_pad, w_pad, rect)
    261         return {}
    262     span_pairs.append((
    263         slice(ss.rowspan.start * div_row, ss.rowspan.stop * div_row),
    264         slice(ss.colspan.start * div_col, ss.colspan.stop * div_col)))
--> 266 kwargs = _auto_adjust_subplotpars(fig, renderer,
    267                                   shape=(max_nrows, max_ncols),
    268                                   span_pairs=span_pairs,
    269                                   subplot_list=subplot_list,
    270                                   ax_bbox_list=ax_bbox_list,
    271                                   pad=pad, h_pad=h_pad, w_pad=w_pad)
    273 # kwargs can be none if tight_layout fails...
    274 if rect is not None and kwargs is not None:
    275     # if rect is given, the whole subplots area (including
    276     # labels) will fit into the rect instead of the
   (...)
    280     # auto_adjust_subplotpars twice, where the second run
    281     # with adjusted rect parameters.

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_tight_layout.py:82, in _auto_adjust_subplotpars(fig, renderer, shape, span_pairs, subplot_list, ax_bbox_list, pad, h_pad, w_pad, rect)
     80 for ax in subplots:
     81     if ax.get_visible():
---> 82         bb += [martist._get_tightbbox_for_layout_only(ax, renderer)]
     84 tight_bbox_raw = Bbox.union(bb)
     85 tight_bbox = fig.transFigure.inverted().transform_bbox(tight_bbox_raw)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:1411, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
   1405 """
   1406 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
   1407 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
   1408 when encountering third-party subclasses that do not support it.
   1409 """
   1410 try:
-> 1411     return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
   1412 except TypeError:
   1413     return obj.get_tightbbox(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_api/deprecation.py:454, in make_keyword_only.<locals>.wrapper(*args, **kwargs)
    448 if len(args) > name_idx:
    449     warn_deprecated(
    450         since, message="Passing the %(name)s %(obj_type)s "
    451         "positionally is deprecated since Matplotlib %(since)s; the "
    452         "parameter will become keyword-only %(removal)s.",
    453         name=name, obj_type=f"parameter of {func.__name__}()")
--> 454 return func(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:4395, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
   4393 for axis in self._axis_map.values():
   4394     if self.axison and axis.get_visible():
-> 4395         ba = martist._get_tightbbox_for_layout_only(axis, renderer)
   4396         if ba:
   4397             bb.append(ba)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:1411, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
   1405 """
   1406 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
   1407 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
   1408 when encountering third-party subclasses that do not support it.
   1409 """
   1410 try:
-> 1411     return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
   1412 except TypeError:
   1413     return obj.get_tightbbox(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1336, in Axis.get_tightbbox(self, renderer, for_layout_only)
   1333     renderer = self.figure._get_renderer()
   1334 ticks_to_draw = self._update_ticks()
-> 1336 self._update_label_position(renderer)
   1338 # go back to just this axis's tick labels
   1339 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2609, in YAxis._update_label_position(self, renderer)
   2605     return
   2607 # get bounding boxes for this axis and any siblings
   2608 # that have been set by `fig.align_ylabels()`
-> 2609 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
   2610 x, y = self.label.get_position()
   2611 if self.label_position == 'left':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2161, in Axis._get_tick_boxes_siblings(self, renderer)
   2159 axis = ax._axis_map[name]
   2160 ticks_to_draw = axis._update_ticks()
-> 2161 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
   2162 bboxes.extend(tlb)
   2163 bboxes2.extend(tlb2)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1315, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1313 if renderer is None:
   1314     renderer = self.figure._get_renderer()
-> 1315 return ([tick.label1.get_window_extent(renderer)
   1316          for tick in ticks if tick.label1.get_visible()],
   1317         [tick.label2.get_window_extent(renderer)
   1318          for tick in ticks if tick.label2.get_visible()])

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
Error in callback <function _draw_all_if_interactive at 0x7f24c2a8ef20> (for post_execute), with arguments args (),kwargs {}:
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/pyplot.py:197, in _draw_all_if_interactive()
    195 def _draw_all_if_interactive() -> None:
    196     if matplotlib.is_interactive():
--> 197         draw_all()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_pylab_helpers.py:132, in Gcf.draw_all(cls, force)
    130 for manager in cls.get_all_fig_managers():
    131     if force or manager.canvas.figure.stale:
--> 132         manager.canvas.draw_idle()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backend_bases.py:1893, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
   1891 if not self._is_idle_drawing:
   1892     with self._idle_draw_cntx():
-> 1893         self.draw(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:388, in FigureCanvasAgg.draw(self)
    385 # Acquire a lock on the shared font cache.
    386 with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
    387       else nullcontext()):
--> 388     self.figure.draw(self.renderer)
    389     # A GUI class may be need to update a window using this draw, so
    390     # don't forget to call the superclass.
    391     super().draw()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3154, in Figure.draw(self, renderer)
   3151         # ValueError can occur when resizing a window.
   3153 self.patch.draw(renderer)
-> 3154 mimage._draw_list_compositing_images(
   3155     renderer, self, artists, self.suppressComposite)
   3157 for sfig in self.subfigs:
   3158     sfig.draw(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:3070, in _AxesBase.draw(self, renderer)
   3067 if artists_rasterized:
   3068     _draw_rasterized(self.figure, artists_rasterized, renderer)
-> 3070 mimage._draw_list_compositing_images(
   3071     renderer, self, artists, self.figure.suppressComposite)
   3073 renderer.close_group('axes')
   3074 self.stale = False

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1388, in Axis.draw(self, renderer, *args, **kwargs)
   1385 renderer.open_group(__name__, gid=self.get_gid())
   1387 ticks_to_draw = self._update_ticks()
-> 1388 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)
   1390 for tick in ticks_to_draw:
   1391     tick.draw(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1315, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1313 if renderer is None:
   1314     renderer = self.figure._get_renderer()
-> 1315 return ([tick.label1.get_window_extent(renderer)
   1316          for tick in ticks if tick.label1.get_visible()],
   1317         [tick.label2.get_window_extent(renderer)
   1318          for tick in ticks if tick.label2.get_visible()])

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/formatters.py:343, in BaseFormatter.__call__(self, obj)
    341     pass
    342 else:
--> 343     return printer(obj)
    344 # Finally look for special method names
    345 method = get_real_method(obj, self.print_method)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/pylabtools.py:169, in retina_figure(fig, base64, **kwargs)
    160 def retina_figure(fig, base64=False, **kwargs):
    161     """format a figure as a pixel-doubled (retina) PNG
    162 
    163     If `base64` is True, return base64-encoded str instead of raw bytes
   (...)
    167         base64 argument
    168     """
--> 169     pngdata = print_figure(fig, fmt="retina", base64=False, **kwargs)
    170     # Make sure that retina_figure acts just like print_figure and returns
    171     # None when the figure is empty.
    172     if pngdata is None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/pylabtools.py:152, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
    149     from matplotlib.backend_bases import FigureCanvasBase
    150     FigureCanvasBase(fig)
--> 152 fig.canvas.print_figure(bytes_io, **kw)
    153 data = bytes_io.getvalue()
    154 if fmt == 'svg':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backend_bases.py:2164, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
   2161     # we do this instead of `self.figure.draw_without_rendering`
   2162     # so that we can inject the orientation
   2163     with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2164         self.figure.draw(renderer)
   2165 if bbox_inches:
   2166     if bbox_inches == "tight":

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3154, in Figure.draw(self, renderer)
   3151         # ValueError can occur when resizing a window.
   3153 self.patch.draw(renderer)
-> 3154 mimage._draw_list_compositing_images(
   3155     renderer, self, artists, self.suppressComposite)
   3157 for sfig in self.subfigs:
   3158     sfig.draw(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:3070, in _AxesBase.draw(self, renderer)
   3067 if artists_rasterized:
   3068     _draw_rasterized(self.figure, artists_rasterized, renderer)
-> 3070 mimage._draw_list_compositing_images(
   3071     renderer, self, artists, self.figure.suppressComposite)
   3073 renderer.close_group('axes')
   3074 self.stale = False

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1388, in Axis.draw(self, renderer, *args, **kwargs)
   1385 renderer.open_group(__name__, gid=self.get_gid())
   1387 ticks_to_draw = self._update_ticks()
-> 1388 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)
   1390 for tick in ticks_to_draw:
   1391     tick.draw(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1315, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1313 if renderer is None:
   1314     renderer = self.figure._get_renderer()
-> 1315 return ([tick.label1.get_window_extent(renderer)
   1316          for tick in ticks if tick.label1.get_visible()],
   1317         [tick.label2.get_window_extent(renderer)
   1318          for tick in ticks if tick.label2.get_visible()])

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
<Figure size 1400x600 with 4 Axes>

Figure 5: Absolute calibration of redcal degeneracies¶

This figure shows the per-frequency phase gradient solutions across the array for both polarizations and all components of the degenerate subspace of redundant-baseline calibraton. While full HERA only has two such tip-tilt degeneracies, a subset of HERA can have up to OC_MAX_DIMS (depending on antenna flagging). In addition to the absolute amplitude, this is the full set of the calibration degrees of freedom not constrainted by redcal. This figure also includes a plot of $Re[Z(\nu)]$, the complex objective function which varies from -1 to 1 and indicates how well the data and the absolute calibration model have been made to agree. Perfect agreement is 1.0 and good agreement is anything above $\sim$0.5 Decorrelation yields values closer to 0, where anything below $\sim$0.3 is suspect.

In [51]:
if PLOT: abscal_degen_plot()
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
Error in callback <function _draw_all_if_interactive at 0x7f24c2a8ef20> (for post_execute), with arguments args (),kwargs {}:
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/pyplot.py:197, in _draw_all_if_interactive()
    195 def _draw_all_if_interactive() -> None:
    196     if matplotlib.is_interactive():
--> 197         draw_all()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_pylab_helpers.py:132, in Gcf.draw_all(cls, force)
    130 for manager in cls.get_all_fig_managers():
    131     if force or manager.canvas.figure.stale:
--> 132         manager.canvas.draw_idle()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backend_bases.py:1893, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
   1891 if not self._is_idle_drawing:
   1892     with self._idle_draw_cntx():
-> 1893         self.draw(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:388, in FigureCanvasAgg.draw(self)
    385 # Acquire a lock on the shared font cache.
    386 with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
    387       else nullcontext()):
--> 388     self.figure.draw(self.renderer)
    389     # A GUI class may be need to update a window using this draw, so
    390     # don't forget to call the superclass.
    391     super().draw()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3154, in Figure.draw(self, renderer)
   3151         # ValueError can occur when resizing a window.
   3153 self.patch.draw(renderer)
-> 3154 mimage._draw_list_compositing_images(
   3155     renderer, self, artists, self.suppressComposite)
   3157 for sfig in self.subfigs:
   3158     sfig.draw(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:3034, in _AxesBase.draw(self, renderer)
   3031     for spine in self.spines.values():
   3032         artists.remove(spine)
-> 3034 self._update_title_position(renderer)
   3036 if not self.axison:
   3037     for _axis in self._axis_map.values():

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:2969, in _AxesBase._update_title_position(self, renderer)
   2966 bb = None
   2967 if (ax.xaxis.get_ticks_position() in ['top', 'unknown']
   2968         or ax.xaxis.get_label_position() == 'top'):
-> 2969     bb = ax.xaxis.get_tightbbox(renderer)
   2970 if bb is None:
   2971     if 'outline' in ax.spines:
   2972         # Special case for colorbars:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1352, in Axis.get_tightbbox(self, renderer, for_layout_only)
   1350 # take care of label
   1351 if self.label.get_visible():
-> 1352     bb = self.label.get_window_extent(renderer)
   1353     # for constrained/tight_layout, we want to ignore the label's
   1354     # width/height because the adjustments they make can't be improved.
   1355     # this code collapses the relevant direction
   1356     if for_layout_only:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/formatters.py:343, in BaseFormatter.__call__(self, obj)
    341     pass
    342 else:
--> 343     return printer(obj)
    344 # Finally look for special method names
    345 method = get_real_method(obj, self.print_method)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/pylabtools.py:169, in retina_figure(fig, base64, **kwargs)
    160 def retina_figure(fig, base64=False, **kwargs):
    161     """format a figure as a pixel-doubled (retina) PNG
    162 
    163     If `base64` is True, return base64-encoded str instead of raw bytes
   (...)
    167         base64 argument
    168     """
--> 169     pngdata = print_figure(fig, fmt="retina", base64=False, **kwargs)
    170     # Make sure that retina_figure acts just like print_figure and returns
    171     # None when the figure is empty.
    172     if pngdata is None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/pylabtools.py:152, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
    149     from matplotlib.backend_bases import FigureCanvasBase
    150     FigureCanvasBase(fig)
--> 152 fig.canvas.print_figure(bytes_io, **kw)
    153 data = bytes_io.getvalue()
    154 if fmt == 'svg':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backend_bases.py:2164, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
   2161     # we do this instead of `self.figure.draw_without_rendering`
   2162     # so that we can inject the orientation
   2163     with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2164         self.figure.draw(renderer)
   2165 if bbox_inches:
   2166     if bbox_inches == "tight":

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3154, in Figure.draw(self, renderer)
   3151         # ValueError can occur when resizing a window.
   3153 self.patch.draw(renderer)
-> 3154 mimage._draw_list_compositing_images(
   3155     renderer, self, artists, self.suppressComposite)
   3157 for sfig in self.subfigs:
   3158     sfig.draw(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:3034, in _AxesBase.draw(self, renderer)
   3031     for spine in self.spines.values():
   3032         artists.remove(spine)
-> 3034 self._update_title_position(renderer)
   3036 if not self.axison:
   3037     for _axis in self._axis_map.values():

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:2969, in _AxesBase._update_title_position(self, renderer)
   2966 bb = None
   2967 if (ax.xaxis.get_ticks_position() in ['top', 'unknown']
   2968         or ax.xaxis.get_label_position() == 'top'):
-> 2969     bb = ax.xaxis.get_tightbbox(renderer)
   2970 if bb is None:
   2971     if 'outline' in ax.spines:
   2972         # Special case for colorbars:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1352, in Axis.get_tightbbox(self, renderer, for_layout_only)
   1350 # take care of label
   1351 if self.label.get_visible():
-> 1352     bb = self.label.get_window_extent(renderer)
   1353     # for constrained/tight_layout, we want to ignore the label's
   1354     # width/height because the adjustments they make can't be improved.
   1355     # this code collapses the relevant direction
   1356     if for_layout_only:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
<Figure size 1400x600 with 3 Axes>

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, introducing 0s in gains or infs/nans in gains or visibilities can create problems down the line, so those are removed.

In [52]:
expand_start = time.time()
expanded_reds = redcal.get_reds(hd.data_antpos, pols=['ee', 'nn'], pol_mode='2pol')
sol.vis.build_red_keys(expanded_reds)
redcal.expand_omni_gains(sol, expanded_reds, data, chisq_per_ant=meta['chisq_per_ant'])
if not np.all([ant in final_class.bad_ants for ant in ants]):
    redcal.expand_omni_vis(sol, expanded_reds, data)

# Replace near-zeros in gains and infs/nans in gains/sols
for ant in sol.gains:
    zeros_in_gains = np.isclose(sol.gains[ant], 0)
    if ant in omni_flags:
        omni_flags[ant][zeros_in_gains] = True
    sol.gains[ant][zeros_in_gains] = 1.0 + 0.0j
sol.make_sol_finite()
malloc_trim()
print(f'Finished expanding gain solution in {(time.time() - expand_start) / 60:.2f} minutes.')
Finished expanding gain solution in 1.05 minutes.
In [53]:
def array_chisq_plot(include_outriggers=True):
    if np.all([ant in final_class.bad_ants for ant in ants]):
        print('All antennas classified as bad. Nothing to plot.')
        return    
    
    def _chisq_subplot(ants, size=250):
        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 meta['chisq_per_ant'] if utils.join_pol(ant[1], ant[1]) == pol and (ant[0] in ants)])
            cspas = np.array([np.nanmean(np.where(rfi_flags, np.nan, meta['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=size, c=cspas, lw=.25, edgecolors=np.where(np.isfinite(cspas) & (cspas > 0), 'none', 'k'), 
                                 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=8,
                        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()    
    
    _chisq_subplot([ant for ant in hd.data_ants if ant < 320])
    outriggers = [ant for ant in hd.data_ants if ant >= 320]    
    if include_outriggers & (len(outriggers) > 0):
        _chisq_subplot([ant for ant in hd.data_ants if ant >= 320], size=400)

Figure 6: 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 [54]:
if PLOT: array_chisq_plot(include_outriggers=(not OC_SKIP_OUTRIGGERS))
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[54], line 1
----> 1 if PLOT: array_chisq_plot(include_outriggers=(not OC_SKIP_OUTRIGGERS))

Cell In[53], line 25, in array_chisq_plot(include_outriggers)
     22         ax.set_title(f'{pol}-pol $\\chi^2$ / Antenna (Red is Flagged)')
     23     plt.tight_layout()    
---> 25 _chisq_subplot([ant for ant in hd.data_ants if ant < 320])
     26 outriggers = [ant for ant in hd.data_ants if ant >= 320]    
     27 if include_outriggers & (len(outriggers) > 0):

Cell In[53], line 23, in array_chisq_plot.<locals>._chisq_subplot(ants, size)
     21     ax.set_ylabel('North-South Position (meters)')
     22     ax.set_title(f'{pol}-pol $\\chi^2$ / Antenna (Red is Flagged)')
---> 23 plt.tight_layout()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/pyplot.py:2599, in tight_layout(pad, h_pad, w_pad, rect)
   2591 @_copy_docstring_and_deprecators(Figure.tight_layout)
   2592 def tight_layout(
   2593     *,
   (...)
   2597     rect: tuple[float, float, float, float] | None = None,
   2598 ) -> None:
-> 2599     gcf().tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3540, in Figure.tight_layout(self, pad, h_pad, w_pad, rect)
   3538 previous_engine = self.get_layout_engine()
   3539 self.set_layout_engine(engine)
-> 3540 engine.execute(self)
   3541 if previous_engine is not None and not isinstance(
   3542     previous_engine, (TightLayoutEngine, PlaceHolderLayoutEngine)
   3543 ):
   3544     _api.warn_external('The figure layout has changed to tight')

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/layout_engine.py:183, in TightLayoutEngine.execute(self, fig)
    181 renderer = fig._get_renderer()
    182 with getattr(renderer, "_draw_disabled", nullcontext)():
--> 183     kwargs = get_tight_layout_figure(
    184         fig, fig.axes, get_subplotspec_list(fig.axes), renderer,
    185         pad=info['pad'], h_pad=info['h_pad'], w_pad=info['w_pad'],
    186         rect=info['rect'])
    187 if kwargs:
    188     fig.subplots_adjust(**kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_tight_layout.py:266, in get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer, pad, h_pad, w_pad, rect)
    261         return {}
    262     span_pairs.append((
    263         slice(ss.rowspan.start * div_row, ss.rowspan.stop * div_row),
    264         slice(ss.colspan.start * div_col, ss.colspan.stop * div_col)))
--> 266 kwargs = _auto_adjust_subplotpars(fig, renderer,
    267                                   shape=(max_nrows, max_ncols),
    268                                   span_pairs=span_pairs,
    269                                   subplot_list=subplot_list,
    270                                   ax_bbox_list=ax_bbox_list,
    271                                   pad=pad, h_pad=h_pad, w_pad=w_pad)
    273 # kwargs can be none if tight_layout fails...
    274 if rect is not None and kwargs is not None:
    275     # if rect is given, the whole subplots area (including
    276     # labels) will fit into the rect instead of the
   (...)
    280     # auto_adjust_subplotpars twice, where the second run
    281     # with adjusted rect parameters.

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_tight_layout.py:82, in _auto_adjust_subplotpars(fig, renderer, shape, span_pairs, subplot_list, ax_bbox_list, pad, h_pad, w_pad, rect)
     80 for ax in subplots:
     81     if ax.get_visible():
---> 82         bb += [martist._get_tightbbox_for_layout_only(ax, renderer)]
     84 tight_bbox_raw = Bbox.union(bb)
     85 tight_bbox = fig.transFigure.inverted().transform_bbox(tight_bbox_raw)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:1411, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
   1405 """
   1406 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
   1407 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
   1408 when encountering third-party subclasses that do not support it.
   1409 """
   1410 try:
-> 1411     return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
   1412 except TypeError:
   1413     return obj.get_tightbbox(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_api/deprecation.py:454, in make_keyword_only.<locals>.wrapper(*args, **kwargs)
    448 if len(args) > name_idx:
    449     warn_deprecated(
    450         since, message="Passing the %(name)s %(obj_type)s "
    451         "positionally is deprecated since Matplotlib %(since)s; the "
    452         "parameter will become keyword-only %(removal)s.",
    453         name=name, obj_type=f"parameter of {func.__name__}()")
--> 454 return func(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:4395, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
   4393 for axis in self._axis_map.values():
   4394     if self.axison and axis.get_visible():
-> 4395         ba = martist._get_tightbbox_for_layout_only(axis, renderer)
   4396         if ba:
   4397             bb.append(ba)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:1411, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
   1405 """
   1406 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
   1407 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
   1408 when encountering third-party subclasses that do not support it.
   1409 """
   1410 try:
-> 1411     return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
   1412 except TypeError:
   1413     return obj.get_tightbbox(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1336, in Axis.get_tightbbox(self, renderer, for_layout_only)
   1333     renderer = self.figure._get_renderer()
   1334 ticks_to_draw = self._update_ticks()
-> 1336 self._update_label_position(renderer)
   1338 # go back to just this axis's tick labels
   1339 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2368, in XAxis._update_label_position(self, renderer)
   2364     return
   2366 # get bounding boxes for this axis and any siblings
   2367 # that have been set by `fig.align_xlabels()`
-> 2368 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
   2370 x, y = self.label.get_position()
   2371 if self.label_position == 'bottom':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2161, in Axis._get_tick_boxes_siblings(self, renderer)
   2159 axis = ax._axis_map[name]
   2160 ticks_to_draw = axis._update_ticks()
-> 2161 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
   2162 bboxes.extend(tlb)
   2163 bboxes2.extend(tlb2)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1315, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1313 if renderer is None:
   1314     renderer = self.figure._get_renderer()
-> 1315 return ([tick.label1.get_window_extent(renderer)
   1316          for tick in ticks if tick.label1.get_visible()],
   1317         [tick.label2.get_window_extent(renderer)
   1318          for tick in ticks if tick.label2.get_visible()])

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
Error in callback <function _draw_all_if_interactive at 0x7f24c2a8ef20> (for post_execute), with arguments args (),kwargs {}:
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/pyplot.py:197, in _draw_all_if_interactive()
    195 def _draw_all_if_interactive() -> None:
    196     if matplotlib.is_interactive():
--> 197         draw_all()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_pylab_helpers.py:132, in Gcf.draw_all(cls, force)
    130 for manager in cls.get_all_fig_managers():
    131     if force or manager.canvas.figure.stale:
--> 132         manager.canvas.draw_idle()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backend_bases.py:1893, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
   1891 if not self._is_idle_drawing:
   1892     with self._idle_draw_cntx():
-> 1893         self.draw(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:388, in FigureCanvasAgg.draw(self)
    385 # Acquire a lock on the shared font cache.
    386 with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
    387       else nullcontext()):
--> 388     self.figure.draw(self.renderer)
    389     # A GUI class may be need to update a window using this draw, so
    390     # don't forget to call the superclass.
    391     super().draw()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3154, in Figure.draw(self, renderer)
   3151         # ValueError can occur when resizing a window.
   3153 self.patch.draw(renderer)
-> 3154 mimage._draw_list_compositing_images(
   3155     renderer, self, artists, self.suppressComposite)
   3157 for sfig in self.subfigs:
   3158     sfig.draw(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:3034, in _AxesBase.draw(self, renderer)
   3031     for spine in self.spines.values():
   3032         artists.remove(spine)
-> 3034 self._update_title_position(renderer)
   3036 if not self.axison:
   3037     for _axis in self._axis_map.values():

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:2978, in _AxesBase._update_title_position(self, renderer)
   2976 top = max(top, bb.ymax)
   2977 if title.get_text():
-> 2978     ax.yaxis.get_tightbbox(renderer)  # update offsetText
   2979     if ax.yaxis.offsetText.get_text():
   2980         bb = ax.yaxis.offsetText.get_tightbbox(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1336, in Axis.get_tightbbox(self, renderer, for_layout_only)
   1333     renderer = self.figure._get_renderer()
   1334 ticks_to_draw = self._update_ticks()
-> 1336 self._update_label_position(renderer)
   1338 # go back to just this axis's tick labels
   1339 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2609, in YAxis._update_label_position(self, renderer)
   2605     return
   2607 # get bounding boxes for this axis and any siblings
   2608 # that have been set by `fig.align_ylabels()`
-> 2609 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
   2610 x, y = self.label.get_position()
   2611 if self.label_position == 'left':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2161, in Axis._get_tick_boxes_siblings(self, renderer)
   2159 axis = ax._axis_map[name]
   2160 ticks_to_draw = axis._update_ticks()
-> 2161 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
   2162 bboxes.extend(tlb)
   2163 bboxes2.extend(tlb2)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1315, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1313 if renderer is None:
   1314     renderer = self.figure._get_renderer()
-> 1315 return ([tick.label1.get_window_extent(renderer)
   1316          for tick in ticks if tick.label1.get_visible()],
   1317         [tick.label2.get_window_extent(renderer)
   1318          for tick in ticks if tick.label2.get_visible()])

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/formatters.py:343, in BaseFormatter.__call__(self, obj)
    341     pass
    342 else:
--> 343     return printer(obj)
    344 # Finally look for special method names
    345 method = get_real_method(obj, self.print_method)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/pylabtools.py:169, in retina_figure(fig, base64, **kwargs)
    160 def retina_figure(fig, base64=False, **kwargs):
    161     """format a figure as a pixel-doubled (retina) PNG
    162 
    163     If `base64` is True, return base64-encoded str instead of raw bytes
   (...)
    167         base64 argument
    168     """
--> 169     pngdata = print_figure(fig, fmt="retina", base64=False, **kwargs)
    170     # Make sure that retina_figure acts just like print_figure and returns
    171     # None when the figure is empty.
    172     if pngdata is None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/pylabtools.py:152, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
    149     from matplotlib.backend_bases import FigureCanvasBase
    150     FigureCanvasBase(fig)
--> 152 fig.canvas.print_figure(bytes_io, **kw)
    153 data = bytes_io.getvalue()
    154 if fmt == 'svg':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backend_bases.py:2164, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
   2161     # we do this instead of `self.figure.draw_without_rendering`
   2162     # so that we can inject the orientation
   2163     with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2164         self.figure.draw(renderer)
   2165 if bbox_inches:
   2166     if bbox_inches == "tight":

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3154, in Figure.draw(self, renderer)
   3151         # ValueError can occur when resizing a window.
   3153 self.patch.draw(renderer)
-> 3154 mimage._draw_list_compositing_images(
   3155     renderer, self, artists, self.suppressComposite)
   3157 for sfig in self.subfigs:
   3158     sfig.draw(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:3034, in _AxesBase.draw(self, renderer)
   3031     for spine in self.spines.values():
   3032         artists.remove(spine)
-> 3034 self._update_title_position(renderer)
   3036 if not self.axison:
   3037     for _axis in self._axis_map.values():

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:2978, in _AxesBase._update_title_position(self, renderer)
   2976 top = max(top, bb.ymax)
   2977 if title.get_text():
-> 2978     ax.yaxis.get_tightbbox(renderer)  # update offsetText
   2979     if ax.yaxis.offsetText.get_text():
   2980         bb = ax.yaxis.offsetText.get_tightbbox(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1336, in Axis.get_tightbbox(self, renderer, for_layout_only)
   1333     renderer = self.figure._get_renderer()
   1334 ticks_to_draw = self._update_ticks()
-> 1336 self._update_label_position(renderer)
   1338 # go back to just this axis's tick labels
   1339 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2609, in YAxis._update_label_position(self, renderer)
   2605     return
   2607 # get bounding boxes for this axis and any siblings
   2608 # that have been set by `fig.align_ylabels()`
-> 2609 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
   2610 x, y = self.label.get_position()
   2611 if self.label_position == 'left':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2161, in Axis._get_tick_boxes_siblings(self, renderer)
   2159 axis = ax._axis_map[name]
   2160 ticks_to_draw = axis._update_ticks()
-> 2161 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
   2162 bboxes.extend(tlb)
   2163 bboxes2.extend(tlb2)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1315, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1313 if renderer is None:
   1314     renderer = self.figure._get_renderer()
-> 1315 return ([tick.label1.get_window_extent(renderer)
   1316          for tick in ticks if tick.label1.get_visible()],
   1317         [tick.label2.get_window_extent(renderer)
   1318          for tick in ticks if tick.label2.get_visible()])

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
<Figure size 1400x500 with 4 Axes>

Figure 7: 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 [55]:
if PLOT: array_class_plot(final_class, extra_label=", Post-Redcal")
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[55], line 1
----> 1 if PLOT: array_class_plot(final_class, extra_label=", Post-Redcal")

Cell In[27], line 6, in array_class_plot(cls, extra_label)
      4 if len(outriggers) > 0:
      5     fig, axes = plt.subplots(1, 2, figsize=(14, 6), dpi=100, gridspec_kw={'width_ratios': [2, 1]})
----> 6     plot_antclass(hd.antpos, cls, ax=axes[0], ants=[ant for ant in hd.data_ants if ant < 320], legend=False, title=f'HERA Core{extra_label}')
      7     plot_antclass(hd.antpos, cls, ax=axes[1], ants=outriggers, radius=50, title='Outriggers')
      8 else:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/uvtools/plot.py:258, in plot_antclass(antpos, antclass, ax, ants, radius, ang_dict, colors, labelsize, labelcolor, legend, title)
    256 ax.set_xlim([np.min(xpos) - radius * 2, np.max(xpos) + radius * 2])
    257 ax.set_ylim([np.min(ypos) - radius * 2, np.max(ypos) + radius * 2])
--> 258 plt.tight_layout()
    260 # label antennas
    261 for ant in set([ant[0] for ant in ants]):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/pyplot.py:2599, in tight_layout(pad, h_pad, w_pad, rect)
   2591 @_copy_docstring_and_deprecators(Figure.tight_layout)
   2592 def tight_layout(
   2593     *,
   (...)
   2597     rect: tuple[float, float, float, float] | None = None,
   2598 ) -> None:
-> 2599     gcf().tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3540, in Figure.tight_layout(self, pad, h_pad, w_pad, rect)
   3538 previous_engine = self.get_layout_engine()
   3539 self.set_layout_engine(engine)
-> 3540 engine.execute(self)
   3541 if previous_engine is not None and not isinstance(
   3542     previous_engine, (TightLayoutEngine, PlaceHolderLayoutEngine)
   3543 ):
   3544     _api.warn_external('The figure layout has changed to tight')

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/layout_engine.py:183, in TightLayoutEngine.execute(self, fig)
    181 renderer = fig._get_renderer()
    182 with getattr(renderer, "_draw_disabled", nullcontext)():
--> 183     kwargs = get_tight_layout_figure(
    184         fig, fig.axes, get_subplotspec_list(fig.axes), renderer,
    185         pad=info['pad'], h_pad=info['h_pad'], w_pad=info['w_pad'],
    186         rect=info['rect'])
    187 if kwargs:
    188     fig.subplots_adjust(**kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_tight_layout.py:266, in get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer, pad, h_pad, w_pad, rect)
    261         return {}
    262     span_pairs.append((
    263         slice(ss.rowspan.start * div_row, ss.rowspan.stop * div_row),
    264         slice(ss.colspan.start * div_col, ss.colspan.stop * div_col)))
--> 266 kwargs = _auto_adjust_subplotpars(fig, renderer,
    267                                   shape=(max_nrows, max_ncols),
    268                                   span_pairs=span_pairs,
    269                                   subplot_list=subplot_list,
    270                                   ax_bbox_list=ax_bbox_list,
    271                                   pad=pad, h_pad=h_pad, w_pad=w_pad)
    273 # kwargs can be none if tight_layout fails...
    274 if rect is not None and kwargs is not None:
    275     # if rect is given, the whole subplots area (including
    276     # labels) will fit into the rect instead of the
   (...)
    280     # auto_adjust_subplotpars twice, where the second run
    281     # with adjusted rect parameters.

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_tight_layout.py:82, in _auto_adjust_subplotpars(fig, renderer, shape, span_pairs, subplot_list, ax_bbox_list, pad, h_pad, w_pad, rect)
     80 for ax in subplots:
     81     if ax.get_visible():
---> 82         bb += [martist._get_tightbbox_for_layout_only(ax, renderer)]
     84 tight_bbox_raw = Bbox.union(bb)
     85 tight_bbox = fig.transFigure.inverted().transform_bbox(tight_bbox_raw)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:1411, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
   1405 """
   1406 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
   1407 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
   1408 when encountering third-party subclasses that do not support it.
   1409 """
   1410 try:
-> 1411     return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
   1412 except TypeError:
   1413     return obj.get_tightbbox(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_api/deprecation.py:454, in make_keyword_only.<locals>.wrapper(*args, **kwargs)
    448 if len(args) > name_idx:
    449     warn_deprecated(
    450         since, message="Passing the %(name)s %(obj_type)s "
    451         "positionally is deprecated since Matplotlib %(since)s; the "
    452         "parameter will become keyword-only %(removal)s.",
    453         name=name, obj_type=f"parameter of {func.__name__}()")
--> 454 return func(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:4395, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
   4393 for axis in self._axis_map.values():
   4394     if self.axison and axis.get_visible():
-> 4395         ba = martist._get_tightbbox_for_layout_only(axis, renderer)
   4396         if ba:
   4397             bb.append(ba)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:1411, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
   1405 """
   1406 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
   1407 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
   1408 when encountering third-party subclasses that do not support it.
   1409 """
   1410 try:
-> 1411     return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
   1412 except TypeError:
   1413     return obj.get_tightbbox(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1336, in Axis.get_tightbbox(self, renderer, for_layout_only)
   1333     renderer = self.figure._get_renderer()
   1334 ticks_to_draw = self._update_ticks()
-> 1336 self._update_label_position(renderer)
   1338 # go back to just this axis's tick labels
   1339 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2368, in XAxis._update_label_position(self, renderer)
   2364     return
   2366 # get bounding boxes for this axis and any siblings
   2367 # that have been set by `fig.align_xlabels()`
-> 2368 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
   2370 x, y = self.label.get_position()
   2371 if self.label_position == 'bottom':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2161, in Axis._get_tick_boxes_siblings(self, renderer)
   2159 axis = ax._axis_map[name]
   2160 ticks_to_draw = axis._update_ticks()
-> 2161 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
   2162 bboxes.extend(tlb)
   2163 bboxes2.extend(tlb2)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1315, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1313 if renderer is None:
   1314     renderer = self.figure._get_renderer()
-> 1315 return ([tick.label1.get_window_extent(renderer)
   1316          for tick in ticks if tick.label1.get_visible()],
   1317         [tick.label2.get_window_extent(renderer)
   1318          for tick in ticks if tick.label2.get_visible()])

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
Error in callback <function _draw_all_if_interactive at 0x7f24c2a8ef20> (for post_execute), with arguments args (),kwargs {}:
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/pyplot.py:197, in _draw_all_if_interactive()
    195 def _draw_all_if_interactive() -> None:
    196     if matplotlib.is_interactive():
--> 197         draw_all()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/_pylab_helpers.py:132, in Gcf.draw_all(cls, force)
    130 for manager in cls.get_all_fig_managers():
    131     if force or manager.canvas.figure.stale:
--> 132         manager.canvas.draw_idle()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backend_bases.py:1893, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
   1891 if not self._is_idle_drawing:
   1892     with self._idle_draw_cntx():
-> 1893         self.draw(*args, **kwargs)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:388, in FigureCanvasAgg.draw(self)
    385 # Acquire a lock on the shared font cache.
    386 with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
    387       else nullcontext()):
--> 388     self.figure.draw(self.renderer)
    389     # A GUI class may be need to update a window using this draw, so
    390     # don't forget to call the superclass.
    391     super().draw()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3154, in Figure.draw(self, renderer)
   3151         # ValueError can occur when resizing a window.
   3153 self.patch.draw(renderer)
-> 3154 mimage._draw_list_compositing_images(
   3155     renderer, self, artists, self.suppressComposite)
   3157 for sfig in self.subfigs:
   3158     sfig.draw(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:3034, in _AxesBase.draw(self, renderer)
   3031     for spine in self.spines.values():
   3032         artists.remove(spine)
-> 3034 self._update_title_position(renderer)
   3036 if not self.axison:
   3037     for _axis in self._axis_map.values():

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:2978, in _AxesBase._update_title_position(self, renderer)
   2976 top = max(top, bb.ymax)
   2977 if title.get_text():
-> 2978     ax.yaxis.get_tightbbox(renderer)  # update offsetText
   2979     if ax.yaxis.offsetText.get_text():
   2980         bb = ax.yaxis.offsetText.get_tightbbox(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1336, in Axis.get_tightbbox(self, renderer, for_layout_only)
   1333     renderer = self.figure._get_renderer()
   1334 ticks_to_draw = self._update_ticks()
-> 1336 self._update_label_position(renderer)
   1338 # go back to just this axis's tick labels
   1339 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2609, in YAxis._update_label_position(self, renderer)
   2605     return
   2607 # get bounding boxes for this axis and any siblings
   2608 # that have been set by `fig.align_ylabels()`
-> 2609 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
   2610 x, y = self.label.get_position()
   2611 if self.label_position == 'left':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2161, in Axis._get_tick_boxes_siblings(self, renderer)
   2159 axis = ax._axis_map[name]
   2160 ticks_to_draw = axis._update_ticks()
-> 2161 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
   2162 bboxes.extend(tlb)
   2163 bboxes2.extend(tlb2)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1315, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1313 if renderer is None:
   1314     renderer = self.figure._get_renderer()
-> 1315 return ([tick.label1.get_window_extent(renderer)
   1316          for tick in ticks if tick.label1.get_visible()],
   1317         [tick.label2.get_window_extent(renderer)
   1318          for tick in ticks if tick.label2.get_visible()])

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
WARNING:matplotlib.font_manager:findfont: Font family ['DejaVu Sans'] not found. Falling back to DejaVu Sans.
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/formatters.py:343, in BaseFormatter.__call__(self, obj)
    341     pass
    342 else:
--> 343     return printer(obj)
    344 # Finally look for special method names
    345 method = get_real_method(obj, self.print_method)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/pylabtools.py:169, in retina_figure(fig, base64, **kwargs)
    160 def retina_figure(fig, base64=False, **kwargs):
    161     """format a figure as a pixel-doubled (retina) PNG
    162 
    163     If `base64` is True, return base64-encoded str instead of raw bytes
   (...)
    167         base64 argument
    168     """
--> 169     pngdata = print_figure(fig, fmt="retina", base64=False, **kwargs)
    170     # Make sure that retina_figure acts just like print_figure and returns
    171     # None when the figure is empty.
    172     if pngdata is None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/IPython/core/pylabtools.py:152, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
    149     from matplotlib.backend_bases import FigureCanvasBase
    150     FigureCanvasBase(fig)
--> 152 fig.canvas.print_figure(bytes_io, **kw)
    153 data = bytes_io.getvalue()
    154 if fmt == 'svg':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backend_bases.py:2164, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
   2161     # we do this instead of `self.figure.draw_without_rendering`
   2162     # so that we can inject the orientation
   2163     with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2164         self.figure.draw(renderer)
   2165 if bbox_inches:
   2166     if bbox_inches == "tight":

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/figure.py:3154, in Figure.draw(self, renderer)
   3151         # ValueError can occur when resizing a window.
   3153 self.patch.draw(renderer)
-> 3154 mimage._draw_list_compositing_images(
   3155     renderer, self, artists, self.suppressComposite)
   3157 for sfig in self.subfigs:
   3158     sfig.draw(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:3034, in _AxesBase.draw(self, renderer)
   3031     for spine in self.spines.values():
   3032         artists.remove(spine)
-> 3034 self._update_title_position(renderer)
   3036 if not self.axison:
   3037     for _axis in self._axis_map.values():

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axes/_base.py:2978, in _AxesBase._update_title_position(self, renderer)
   2976 top = max(top, bb.ymax)
   2977 if title.get_text():
-> 2978     ax.yaxis.get_tightbbox(renderer)  # update offsetText
   2979     if ax.yaxis.offsetText.get_text():
   2980         bb = ax.yaxis.offsetText.get_tightbbox(renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1336, in Axis.get_tightbbox(self, renderer, for_layout_only)
   1333     renderer = self.figure._get_renderer()
   1334 ticks_to_draw = self._update_ticks()
-> 1336 self._update_label_position(renderer)
   1338 # go back to just this axis's tick labels
   1339 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2609, in YAxis._update_label_position(self, renderer)
   2605     return
   2607 # get bounding boxes for this axis and any siblings
   2608 # that have been set by `fig.align_ylabels()`
-> 2609 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
   2610 x, y = self.label.get_position()
   2611 if self.label_position == 'left':

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:2161, in Axis._get_tick_boxes_siblings(self, renderer)
   2159 axis = ax._axis_map[name]
   2160 ticks_to_draw = axis._update_ticks()
-> 2161 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
   2162 bboxes.extend(tlb)
   2163 bboxes2.extend(tlb2)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/axis.py:1315, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1313 if renderer is None:
   1314     renderer = self.figure._get_renderer()
-> 1315 return ([tick.label1.get_window_extent(renderer)
   1316          for tick in ticks if tick.label1.get_visible()],
   1317         [tick.label2.get_window_extent(renderer)
   1318          for tick in ticks if tick.label2.get_visible()])

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:956, in Text.get_window_extent(self, renderer, dpi)
    951     raise RuntimeError(
    952         "Cannot get window extent of text w/o renderer. You likely "
    953         "want to call 'figure.draw_without_rendering()' first.")
    955 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 956     bbox, info, descent = self._get_layout(self._renderer)
    957     x, y = self.get_unitless_position()
    958     x, y = self.get_transform().transform((x, y))

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:373, in Text._get_layout(self, renderer)
    370 ys = []
    372 # Full vertical extent of font, including ascenders and descenders:
--> 373 _, lp_h, lp_d = _get_text_metrics_with_cache(
    374     renderer, "lp", self._fontproperties,
    375     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    376 min_dy = (lp_h - lp_d) * self._linespacing
    378 for i, line in enumerate(lines):

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:69, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     66 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     67 # Cached based on a copy of fontprop so that later in-place mutations of
     68 # the passed-in argument do not mess up the cache.
---> 69 return _get_text_metrics_with_cache_impl(
     70     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/text.py:77, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
     73 @functools.lru_cache(4096)
     74 def _get_text_metrics_with_cache_impl(
     75         renderer_ref, text, fontprop, ismath, dpi):
     76     # dpi is unused, but participates in cache invalidation (via the renderer).
---> 77     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:220, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    216     ox, oy, width, height, descent, font_image = \
    217         self.mathtext_parser.parse(s, self.dpi, prop)
    218     return width, height, descent
--> 220 font = self._prepare_font(prop)
    221 font.set_text(s, 0.0, flags=get_hinting_flag())
    222 w, h = font.get_width_height()  # width and height of unrotated string

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py:254, in RendererAgg._prepare_font(self, font_prop)
    250 def _prepare_font(self, font_prop):
    251     """
    252     Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
    253     """
--> 254     font = get_font(_fontManager._find_fonts_by_props(font_prop))
    255     font.clear()
    256     size = font_prop.get_size_in_points()

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1381, in FontManager._find_fonts_by_props(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1378     cprop = prop.copy()
   1379     cprop.set_family(dfamily)
   1380     fpaths.append(
-> 1381         self.findfont(
   1382             cprop, fontext, directory,
   1383             fallback_to_default=True,
   1384             rebuild_if_missing=rebuild_if_missing,
   1385         )
   1386     )
   1387 else:
   1388     raise ValueError("Failed to find any font, and fallback "
   1389                      "to the default font was disabled")

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1292, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1286 # Pass the relevant rcParams (and the font manager, as `self`) to
   1287 # _findfont_cached so to prevent using a stale cache entry after an
   1288 # rcParam was changed.
   1289 rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
   1290     "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
   1291     "font.monospace"])
-> 1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
   1296     raise ret.klass(ret.message)

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1443, in FontManager._findfont_cached(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing, rc_params)
   1441     default_prop = prop.copy()
   1442     default_prop.set_family(self.defaultFamily[fontext])
-> 1443     return self.findfont(default_prop, fontext, directory,
   1444                          fallback_to_default=False)
   1445 else:
   1446     # This return instead of raise is intentional, as we wish to
   1447     # cache that it was not found, which will not occur if it was
   1448     # actually raised.
   1449     return _ExceptionProxy(
   1450         ValueError,
   1451         f"Failed to find font {prop}, and fallback to the default font was disabled"
   1452     )

File ~/mambaforge/envs/RTP/lib/python3.12/site-packages/matplotlib/font_manager.py:1296, in FontManager.findfont(self, prop, fontext, directory, fallback_to_default, rebuild_if_missing)
   1292 ret = self._findfont_cached(
   1293     prop, fontext, directory, fallback_to_default, rebuild_if_missing,
   1294     rc_params)
   1295 if isinstance(ret, _ExceptionProxy):
-> 1296     raise ret.klass(ret.message)
   1297 return ret

ValueError: Failed to find font DejaVu Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0, and fallback to the default font was disabled
<Figure size 1400x600 with 2 Axes>
In [56]:
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),
                  ('Solar Alt', solar_class),
                  ('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),
                  ('Bad Diff X-Engines', xengine_diff_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 'bad' for ant in ants]
    
to_show['Redcal chi^2'] = [f'{np.nanmean(np.where(rfi_flags, np.nan, meta["chisq_per_ant"][ant])):.3G}' \
                           if (meta['chisq_per_ant'] is not None and ant in meta['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() \
                .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 [57]:
HTML(table.to_html())
Out[57]:
Antenna Dead? Low Correlation Cross-Polarized Solar Alt Even/Odd Zeros Autocorr Power Autocorr Slope RFI in Autos Autocorr Shape Bad Diff X-Engines Redcal chi^2
3e No 0.57 0.49 -47 0 11 0.23 0.0059 0.047 0 1.3
3n No 0.033 0.49 -47 0 0.62 0.6 0.07 0.18 1.15
4e No 0.58 0.37 -47 0 13 0.13 0.0026 0.034 0 1.37
4n No 0.57 0.37 -47 0 16 0.017 0.00065 0.033 0 1.56
5e No 0.58 0.36 -47 0 14 0.06 0.0046 0.032 0 1.45
5n No 0.57 0.36 -47 0 15 -0.12 0.0013 0.031 0 1.78
7e No 0.58 0.35 -47 0 13 0.12 0.01 0.032 0 1.59
7n No 0.58 0.35 -47 0 14 -0.048 0.00065 0.033 0 1.82
8e No 0.57 0.35 -47 0 13 0.18 0.0036 0.047 0 1.56
8n No 0.57 0.35 -47 0 15 -0.077 0.0013 0.023 0 1.9
9e No 0.51 0.37 -47 0 2 0.26 0.016 0.042 0 1.42
9n No 0.57 0.37 -47 0 14 -0.04 0.00065 0.025 0 2.07
10e No 0.57 0.35 -47 0 15 0.21 0.0039 0.085 0 1.41
10n No 0.57 0.35 -47 0 14 -0.075 0.0013 0.026 0 2.21
15e No 0.59 0.37 -47 0 12 0.14 0.00098 0.028 0 1.33
15n No 0.58 0.37 -47 0 14 -0.11 0 0.03 0 1.44
16e No 0.59 0.36 -47 0 13 0.13 0.00033 0.037 0 1.36
16n No 0.57 0.36 -47 0 16 0.092 0 0.036 0 1.55
17e No 0.59 0.35 -47 0 13 0.083 0.00033 0.027 0 1.35
17n No 0.58 0.35 -47 0 10 -0.025 0.00065 0.041 0 1.55
18e No 0.58 0.41 -47 0 13 0.18 0.00033 0.03 0 1.37
18n No 0.4 0.41 -47 0 12 0.13 0.16 0.12 1.36
19e No 0.59 0.35 -47 0 13 0.16 0.0023 0.036 0 1.45
19n No 0.59 0.35 -47 0 16 -0.016 0.00033 0.015 0 1.54
20e No 0.57 0.36 -47 0 9.1 0.16 0.0016 0.088 0 1.48
20n No 0.59 0.36 -47 0 16 -0.084 0.00033 0.028 0 1.67
21e No 0.48 0.35 -47 0 1.5 0.34 0.019 0.064 0 1.38
21n No 0.26 0.35 -47 0 0.71 0.45 0.035 0.14 1.39
22e No 0.54 0.35 -47 0 16 0.21 0.0023 0.022 0 1.37
22n No 0.56 0.35 -47 0 24 -0.049 0.00065 0.018 0 2.25
27e No 0.16 0.26 -47 0 6.8 0.95 0.41 0.36 1.16
27n No 0.35 0.26 -47 0 15 0.27 0.19 0.13 1.27
28e No 0.14 -0.031 -47 1 8.8 0.75 0.19 0.2 1.9
28n No 0.24 -0.031 -47 0 12 0.13 0.002 0.061 0 4.01
29e No 0.59 0.33 -47 0 15 0.13 0.0029 0.02 0 1.35
29n No 0.59 0.33 -47 0 16 0.056 0.00033 0.047 0 1.47
30e No 0.6 0.35 -47 0 12 0.081 0 0.031 0 1.33
30n No 0.6 0.35 -47 0 13 -0.097 0 0.025 0 1.45
31e No 0.6 0.41 -47 0 9 0.049 0 0.043 0 1.31
31n No 0.44 0.41 -47 0 1.2 0.32 0.031 0.1 1.34
32e No 0.59 0.35 -47 0 14 0.11 0.0013 0.024 0 1.34
32n No 0.58 0.35 -47 0 14 -0.055 0 0.023 0 1.62
33e No 0.52 0.39 -47 1 2.2 0.29 0.02 0.052 0 1.33
33n No 0.59 0.39 -47 0 15 -0.056 0.00098 0.026 0 1.72
34e No 0.038 0.43 -47 0 3 0.58 0.041 0.14 1.2
34n No 0.54 0.43 -47 0 14 0.13 0.019 0.042 0 2.1
35e No 0.56 0.35 -47 0 18 0.18 0.012 0.017 0 1.37
35n No 0.55 0.35 -47 0 18 0.014 0.00065 0.019 0 2.65
36e No 0.59 0.38 -47 0 13 -0.23 0.0026 0.11 0 1.29
36n No 0.57 0.38 -47 0 15 -0.4 0.00065 0.11 0 1.42
37e No 0.58 0.36 -47 0 2.6 -0.26 0.00098 0.14 0 1.27
37n No 0.56 0.36 -47 1 2 -0.46 0.002 0.15 0 1.39
38e No 0.6 0.36 -47 0 13 0.094 0 0.05 0 1.3
38n No 0.59 0.36 -47 0 15 -0.1 0.00065 0.038 0 1.42
40e No 0.59 0.34 -47 0 12 0.11 0 0.037 0 1.37
40n No 0.59 0.34 -47 0 13 -0.073 0.00065 0.039 0 1.5
41e No 0.6 0.34 -47 0 13 0.051 0.0026 0.039 0 1.61
41n No 0.61 0.34 -47 0 12 -0.11 0.00033 0.034 0 1.77
42e No 0.61 0.37 -47 0 11 0.11 0 0.043 0 1.38
42n No 0.55 0.37 -47 0 1.9 0.11 0.015 0.051 0 1.75
45e No 0.024 0.0059 -47 1.5E+03 1.7E-06 -0.62 0.42 6.2 0.923
45n No 0.016 0.0059 -47 8 0.0018 -0.31 0.46 1.5 1.05
46e No 0.58 0.37 -47 0 55 0.076 0.01 0.055 0 1.3
46n No 0.6 0.37 -47 0 38 -0.035 0 0.026 0 1.53
47e Yes -47 1.5E+03 0 0 0 INF 0
47n Yes -47 1.5E+03 0 0 0 INF 0
48e No 0.55 0.35 -47 0 19 0.26 0.0029 0.035 0 1.35
48n No 0.56 0.35 -47 0 39 0.008 0 0.033 0 1.94
49e No 0.52 0.35 -47 0 12 0.23 0.0026 0.035 0 1.41
49n No 0.55 0.35 -47 0 22 0.011 0.00098 0.02 0 2.33
50e No 0.58 0.36 -47 0 8.2 0.12 0.0016 0.046 0 1.4
50n No 0.57 0.36 -47 0 15 -0.14 0.00033 0.057 0 1.52
51e No 0.59 0.35 -47 0 7.6 0.18 0.39 0.066 1.49
51n No 0.58 0.35 -47 0 15 -0.13 0.00033 0.051 0 1.41
52e No 0.61 0.36 -47 0 13 -0.18 0 0.1 0 1.34
52n No 0.59 0.36 -47 0 15 -0.3 0 0.084 0 1.48
53e No 0.62 0.35 -47 0 13 0.086 0.013 0.049 0 1.43
53n No 0.61 0.35 -47 0 14 -0.2 0.00033 0.065 0 1.63
54e No 0.6 0.34 -47 0 42 0.094 0 0.029 0 1.43
54n No 0.59 0.34 -47 0 47 0.016 0 0.047 0 1.8
55e No 0.6 0.34 -47 0 14 0.11 0 0.031 0 1.39
55n No 0.6 0.34 -47 0 17 -0.11 0.00033 0.033 0 1.58
56e No 0.61 0.35 -47 0 15 0.14 0 0.029 0 1.41
56n No 0.6 0.35 -47 0 16 0.034 0.0029 0.068 0 1.56
57e No 0.61 0.35 -47 0 13 0.099 0.00065 0.031 0 1.38
57n No 0.6 0.35 -47 0 16 0.019 0.0033 0.059 0 1.51
61e Yes -47 1.5E+03 0 0 0 INF 0
61n Yes -47 1.5E+03 0 0 0 INF 0
62e No 0.52 0.36 -47 0 11 0.25 0.0085 0.034 0 1.27
62n No 0.57 0.36 -47 0 32 -0.016 0 0.035 0 1.52
63e Yes -47 1.5E+03 0 0 0 INF 0
63n Yes -47 1.5E+03 0 0 0 INF 0
64e Yes -47 1.5E+03 0 0 0 INF 0
64n Yes -47 1.5E+03 0 0 0 INF 0
65e No 0.59 0.36 -47 0 14 0.096 0.0013 0.064 0 1.38
65n No 0.58 0.36 -47 0 18 -0.14 0 0.048 0 1.53
66e No 0.6 0.36 -47 0 13 0.059 0.00098 0.057 0 1.37
66n No 0.6 0.36 -47 0 15 -0.15 0 0.044 0 1.55
67e No 0.61 0.35 -47 0 17 0.064 0.0013 0.041 0 1.39
67n No 0.6 0.35 -47 0 9 -0.024 0.00065 0.03 0 1.55
68e No 0.62 0.48 -47 0 13 0.1 0 0.059 0 1.4
68n No 0.23 0.48 -47 0 0.34 0.78 0.17 0.22 1.14
69e No 0.62 0.35 -47 0 12 0.082 0.0046 0.038 0 1.4
69n No 0.62 0.35 -47 0 15 0.035 0 0.054 0 1.49
70e No 0.61 0.34 -47 0 14 0.22 0 0.036 0 1.37
70n No 0.62 0.34 -47 0 14 -0.013 0.00033 0.03 0 1.49
71e No 0.62 0.35 -47 0 12 0.07 0 0.037 0 1.38
71n No 0.63 0.35 -47 0 14 -0.077 0 0.023 0 1.5
72e No 0.61 0.35 -47 0 15 0.21 0.0052 0.033 0 1.41
72n No 0.61 0.35 -47 0 15 -0.047 0.0098 0.031 0 1.54
73e No 0.61 0.49 -47 0 44 0.098 0 0.039 0 1.3
73n No 0.046 0.49 -47 1 0.62 0.55 0.071 0.17 1.14
77e Yes -47 1.5E+03 0 0 0 INF 0
77n Yes -47 1.5E+03 0 0 0 INF 0
78e Yes -47 1.5E+03 0 0 0 INF 0
78n Yes -47 1.5E+03 0 0 0 INF 0
79e No 0.57 0.34 -47 0 21 0.24 0.0013 0.031 0 1.33
79n No 0.56 0.34 -47 0 16 0.063 0 0.032 0 1.91
80e No 0.56 0.34 -47 0 19 0.25 0.0042 0.035 0 1.34
80n No 0.55 0.34 -47 0 16 0.09 0.002 0.038 0 2.26
81e No 0.55 0.34 -47 0 1.4 -0.21 0.01 0.11 0 1.36
81n No 0.56 0.34 -47 0 2.5 -0.52 0.00033 0.15 0 1.62
82e No 0.59 0.35 -47 0 2.6 -0.26 0.0026 0.13 0 1.6
82n No 0.57 0.35 -47 0 1.8 -0.49 0 0.14 0 1.71
83e No 0.6 0.34 -47 1 3.1 -0.24 0.00065 0.13 0 1.33
83n No 0.55 0.34 -47 0 2.5 0.3 0 0.16 0 2.63
84e No 0.61 0.34 -47 0 13 0.11 0.00033 0.034 0 1.46
84n No 0.6 0.34 -47 0 16 0.047 0 0.033 0 1.8
85e No 0.61 0.34 -47 0 13 0.045 0.00065 0.048 0 1.34
85n No 0.62 0.34 -47 0 19 -0.13 0 0.037 0 1.56
86e No 0.054 0.0091 -47 0 1.2 0.54 0.026 0.13 1.13
86n No 0.039 0.0091 -47 0 1.1 0.59 0.1 0.18 1.16
87e No 0.62 0.35 -47 0 14 0.13 0.0033 0.037 0 1.39
87n No 0.63 0.35 -47 0 17 -0.11 0.00033 0.04 0 1.47
88e Yes -47 1.5E+03 0 0 0 INF 0
88n Yes -47 1.5E+03 0 0 0 INF 0
89e No 0.26 -0.3 -47 0 16 -0.085 0.0029 0.081 5.51
89n No 0.26 -0.3 -47 0 13 -0.014 0.0036 0.04 3.69
90e Yes -47 1.5E+03 0 0 0 INF 0
90n Yes -47 1.5E+03 0 0 0 INF 0
91e No 0.6 0.35 -47 0 15 0.13 0 0.037 0 1.45
91n No 0.6 0.35 -47 0 15 -0.036 0.00065 0.044 0 1.69
92e No 0.6 0.35 -47 0 12 0.13 0.1 0.079 1.59
92n No 0.6 0.35 -47 0 13 -0.05 0.00033 0.027 0 1.56
93e No 0.26 -0.088 -47 0 15 0.14 0.0016 0.047 0 3.2
93n No 0.096 -0.088 -47 0 0.67 0.53 0.084 0.16 1.23
94e No 0.6 0.36 -47 0 13 0.16 0.00065 0.033 0 1.28
94n No 0.6 0.36 -47 0 15 -0.024 0 0.024 0 1.66
95e No 0.49 0.36 -47 0 13 0.74 0.00065 0.16 1.55
95n No 0.58 0.36 -47 0 27 0.033 0.00033 0.023 0 1.58
96e No 0.58 0.35 -47 0 30 0.17 0.00098 0.019 0 1.37
96n No 0.58 0.35 -47 0 21 0.0085 0.00033 0.016 0 1.95
97e No 0.55 0.33 -47 0 15 0.19 0.0052 0.022 0 1.4
97n No 0.54 0.33 -47 0 13 0.12 0.019 0.05 0 2.52
98e No 0.57 0.35 -47 0 2 -0.28 0.00098 0.13 0 1.42
98n No 0.56 0.35 -47 0 1.9 -0.52 0.00033 0.15 0 1.66
99e No 0.55 0.34 -47 0 0.87 -0.19 0.00065 0.11 1.57
99n No 0.57 0.34 -47 0 1.4 -0.43 0 0.13 0 1.54
100e No 0.6 0.35 -47 0 2.9 -0.17 0.002 0.11 0 1.42
100n No 0.58 0.35 -47 0 1.7 -0.4 0.00033 0.12 0 1.54
101e No 0.62 0.35 -47 0 12 0.052 0 0.035 0 1.38
101n No 0.61 0.35 -47 0 13 -0.12 0 0.033 0 1.53
102e No 0.62 0.34 -47 0 18 0.12 0.00065 0.032 0 1.39
102n No 0.61 0.34 -47 0 16 -0.002 0 0.034 0 1.55
103e No 0.61 0.33 -47 0 13 0.14 0.00065 0.035 0 1.42
103n No 0.61 0.33 -47 0 18 -0.042 0.00033 0.033 0 1.53
104e No 0.62 0.38 -47 0 13 -0.041 0.015 0.12 0 1.43
104n No 0.52 0.38 -47 1 0.87 2.1 0.021 0.55 1.38
105e No 0.63 0.36 -47 0 13 0.073 0.002 0.042 0 1.45
105n No 0.63 0.36 -47 0 15 -0.12 0 0.036 0 1.59
106e No 0.61 0.35 -47 0 14 0.01 0.00065 0.042 0 1.44
106n No 0.62 0.35 -47 0 14 -0.17 0 0.052 0 1.63
107e Yes -47 1.5E+03 0 0 0 INF 0
107n Yes -47 1.5E+03 0 0 0 INF 0
108e No 0.61 0.35 -47 0 13 0.12 0.00033 0.038 0 1.42
108n No 0.62 0.35 -47 0 16 -0.091 0.026 0.15 0 1.66
109e Yes -47 1.5E+03 0 0 0 INF 0
109n Yes -47 1.5E+03 0 0 0 INF 0
110e Yes -47 1.5E+03 0 0 0 INF 0
110n Yes -47 1.5E+03 0 0 0 INF 0
111e Yes -47 1.5E+03 0 0 0 INF 0
111n Yes -47 1.5E+03 0 0 0 INF 0
112e No 0.04 0.49 -47 1 0.72 0.53 0.03 0.13 1.11
112n No 0.61 0.49 -47 0 15 -0.087 0.00033 0.028 0 1.55
113e No 0.58 0.34 -47 0 21 0.19 0.00033 0.017 0 1.34
113n No 0.58 0.34 -47 0 24 0.05 0 0.024 0 1.54
114e No 0.56 0.35 -47 0 18 0.27 0.0013 0.037 0 1.36
114n No 0.58 0.35 -47 0 39 -0.028 0 0.048 0 1.83
115e No 0.034 0.002 -47 0 3.4 0.54 0.07 0.13 1.14
115n No 0.035 0.002 -47 0 3.2 0.59 0.00065 0.18 1.14
116e No 0.55 0.36 -47 0 1.3 -0.14 0 0.099 0 1.44
116n No 0.58 0.36 -47 0 3.7 -0.5 0.00065 0.14 0 1.74
117e No 0.57 0.35 -47 0 5.1 0.23 0.00033 0.03 0 1.37
117n No 0.59 0.35 -47 0 19 -0.055 0 0.021 0 1.58
118e No 0.6 0.34 -47 0 26 0.15 0 0.024 0 1.44
118n No 0.6 0.34 -47 0 17 -0.077 0 0.052 0 1.57
119e No 0.62 0.37 -47 0 4.4 -0.31 0 0.14 0 1.44
119n No 0.56 0.37 -47 0 0.67 -0.4 0.00065 0.12 1.56
120e No 0.61 0.35 -47 0 13 0.12 0.00033 0.056 0 1.45
120n No 0.62 0.35 -47 0 16 -0.061 0 0.032 0 1.54
121e No 0.62 0.36 -47 0 13 0.12 0.038 0.041 1.58
121n No 0.63 0.36 -47 0 15 -0.15 0.00033 0.042 0 1.54
122e No 0.63 0.35 -47 0 12 0.005 0 0.047 0 1.44
122n No 0.63 0.35 -47 0 15 -0.13 0 0.047 0 1.5
123e No 0.63 0.36 -47 0 14 -0.0045 0.00033 0.052 0 1.44
123n No 0.63 0.36 -47 0 15 -0.17 0 0.055 0 1.54
124e No 0.64 0.36 -47 0 18 0.058 0 0.039 0 1.45
124n No 0.63 0.36 -47 0 16 -0.015 0 0.031 0 1.6
125e No 0.61 0.36 -47 0 9.8 0.067 0.00065 0.045 0 1.46
125n No 0.62 0.36 -47 0 18 -0.0031 0 0.028 0 1.73
126e No 0.62 0.35 -47 0 13 0.01 0 0.047 0 1.47
126n No 0.62 0.35 -47 0 10 -0.37 0.00065 0.099 0 1.84
127e No 0.61 0.35 -47 0 9.7 0.11 0 0.045 0 1.53
127n No 0.62 0.35 -47 0 16 -0.062 0 0.027 0 1.69
128e No 0.62 0.35 -47 0 13 0.1 0.00033 0.033 0 1.37
128n No 0.61 0.35 -47 0 15 0.069 0.00033 0.046 0 1.67
129e No 0.62 0.35 -47 0 10 0.1 0.0016 0.035 0 1.36
129n No 0.62 0.35 -47 0 13 -0.077 0.00033 0.029 0 1.57
130e No 0.61 0.35 -47 0 9.7 0.11 0.00033 0.026 0 1.3
130n No 0.61 0.35 -47 0 14 -0.013 0.016 0.03 0 1.49
131e No 0.59 0.39 -47 0 21 0.18 0.00033 0.015 0 1.46
131n No 0.42 0.39 -47 0 3.9 0.41 0.0065 0.12 0 1.42
132e No 0.57 0.33 -47 0 19 0.17 0.00065 0.018 0 1.36
132n No 0.56 0.33 -47 0 13 0.085 0.00098 0.039 0 1.7
133e No 0.55 0.34 -47 0 13 0.23 0.0065 0.03 0 1.35
133n No 0.56 0.34 -47 0 14 0.072 0.0029 0.029 0 1.88
134e No 0.49 0.35 -47 0 6.5 0.33 0.011 0.061 0 1.52
134n No 0.55 0.35 -47 0 15 0.077 0.00033 0.039 0 2.69
135e No 0.57 0.35 -47 0 12 0.23 0.00065 0.096 0 1.58
135n No 0.58 0.35 -47 0 12 -0.032 0.0013 0.029 0 1.82
136e No 0.59 0.35 -47 0 13 0.043 0.00098 0.032 0 1.42
136n No 0.59 0.35 -47 0 16 -0.054 0.0078 0.03 0 1.61
137e No 0.55 0.35 -47 0 0.93 -0.13 0.0013 0.095 1.59
137n No 0.58 0.35 -47 0 2.2 -0.47 0.00033 0.13 0 1.59
138e No 0.62 0.35 -47 0 19 0.089 0 0.059 0 1.48
138n No 0.62 0.35 -47 0 16 -0.043 0.00065 0.04 0 1.6
139e No 0.6 0.35 -47 0 32 0.11 0 0.036 0 1.63
139n No 0.58 0.35 -47 0 18 0.14 0 0.053 0 1.81
140e No 0.61 0.34 -47 0 14 0.11 0.0033 0.045 0 1.53
140n No 0.62 0.34 -47 0 15 -0.092 0 0.028 0 1.62
141e No 0.63 0.35 -47 0 15 0.11 0 0.021 0 1.47
141n No 0.63 0.35 -47 0 16 -0.058 0.00033 0.023 0 1.6
142e No 0.61 0.34 -47 0 14 0.16 0.00033 0.044 0 1.51
142n No 0.62 0.34 -47 0 13 0.089 0.0029 0.051 0 1.67
143e No 0.62 0.36 -47 0 15 0.24 0.00033 0.037 0 1.51
143n No 0.64 0.36 -47 0 16 -0.062 0.00033 0.025 0 1.7
144e No 0.62 0.34 -47 0 13 0.093 0 0.046 0 1.57
144n No 0.62 0.34 -47 0 13 -0.089 0.00033 0.031 0 1.87
145e No 0.62 0.34 -47 0 13 0.063 0.00065 0.035 0 1.6
145n No 0.61 0.34 -47 0 5.7 0.068 0.0055 0.042 0 1.92
146e No 0.58 0.35 -47 0 12 0.3 0.00098 0.043 0 1.51
146n No 0.61 0.35 -47 0 26 0.13 0 0.049 0 1.95
147e No 0.62 0.36 -47 0 14 0.097 0.0016 0.034 0 1.4
147n No 0.63 0.36 -47 0 16 -0.036 0 0.015 0 1.71
148e No 0.62 0.36 -47 0 13 0.11 0.00033 0.022 0 1.37
148n No 0.63 0.36 -47 0 15 -0.1 0.00033 0.03 0 1.57
149e No 0.61 0.35 -47 0 15 0.16 0 0.032 0 1.34
149n No 0.61 0.35 -47 0 14 -0.049 0.00033 0.024 0 1.57
150e No 0.6 0.35 -47 0 12 0.091 0.00033 0.03 0 1.36
150n No 0.6 0.35 -47 0 14 0.0051 0.00033 0.036 0 1.64
151e No 0.59 0.35 -47 0 32 0.13 0 0.019 0 1.34
151n No 0.57 0.35 -47 0 14 0.035 0 0.026 0 1.49
152e No 0.56 0.34 -47 0 16 0.17 0.0049 0.02 0 1.37
152n No 0.56 0.34 -47 0 16 0.038 0 0.023 0 1.6
153e No 0.53 0.35 -47 0 13 0.21 0.0013 0.022 0 1.38
153n No 0.43 0.35 -47 0 4.8 0.32 0.0055 0.1 0 1.71
154e No 0.55 0.34 -47 0 20 0.18 0.0013 0.017 0 1.38
154n No 0.55 0.34 -47 0 19 0.018 0.00065 0.021 0 2.57
155e No 0.57 0.35 -47 0 14 0.12 0.0078 0.027 0 1.49
155n No 0.58 0.35 -47 0 20 -0.049 0.0062 0.019 0 1.63
159e No 0.56 0.34 -47 0 11 0.24 0 0.032 0 1.47
159n No 0.58 0.34 -47 0 15 0.069 0.00098 0.029 0 1.52
160e No 0.61 0.35 -47 0 12 0.11 0.0036 0.025 0 1.54
160n No 0.62 0.35 -47 0 16 -0.017 0.00065 0.036 0 1.66
161e No 0.62 0.33 -47 0 13 0.15 0.0016 0.027 0 1.62
161n No 0.46 0.33 -47 0 15 1.1 0.00065 0.31 3.06
162e No 0.62 0.34 -47 0 13 0.17 0.00033 0.036 0 1.73
162n No 0.63 0.34 -47 0 15 -0.044 0 0.026 0 1.89
163e No 0.63 0.36 -47 0 13 0.05 0 0.03 0 1.56
163n No 0.64 0.36 -47 0 14 -0.15 0 0.043 0 1.64
164e No 0.63 0.36 -47 0 12 0.14 0.0046 0.023 0 1.64
164n No 0.64 0.36 -47 0 17 -0.11 0.00033 0.033 0 1.83
165e No 0.63 0.35 -47 0 14 0.054 0.00033 0.039 0 1.61
165n No 0.63 0.35 -47 0 15 -0.14 0.00033 0.032 0 2.13
166e No 0.62 0.34 -47 0 14 0.085 0.0016 0.033 0 1.72
166n No 0.64 0.34 -47 0 15 -0.12 0 0.034 0 2.16
167e No 0.62 0.35 -47 0 13 0.14 0 0.031 0 1.51
167n No 0.63 0.35 -47 0 14 -0.074 0 0.022 0 1.83
168e No 0.62 0.36 -47 0 13 0.14 0 0.02 0 1.42
168n No 0.63 0.36 -47 0 16 -0.077 0.00033 0.028 0 1.62
169e No 0.62 0.35 -47 0 14 0.065 0.0026 0.027 0 1.35
169n No 0.61 0.35 -47 0 16 -0.054 0 0.021 0 1.54
170e No 0.039 0.46 -47 1 0.65 0.55 0.069 0.13 1.1
170n No 0.61 0.46 -47 0 9.8 0.029 0 0.044 0 1.48
171e No 0.54 0.41 -47 0 13 0.21 0 0.025 0 1.31
171n No 0.041 0.41 -47 0 3.7 0.63 0.0046 0.19 1.12
172e No 0.59 0.36 -47 0 24 0.14 0 0.014 0 1.44
172n No 0.56 0.36 -47 0 14 0.12 0.0013 0.043 0 1.66
173e No 0.55 0.34 -47 0 16 0.19 0.0023 0.028 0 1.46
173n No 0.56 0.34 -47 0 19 0.048 0.00065 0.033 0 1.84
174e No 0.033 0.0017 -47 0 3.2 0.58 0.051 0.13 1.14
174n No 0.031 0.0017 -47 0 3.2 0.61 0.031 0.18 1.14
175e No 0.53 0.34 -47 0 14 0.26 0.0046 0.041 0 1.45
175n No 0.53 0.34 -47 0 15 0.066 0.002 0.04 0 2.13
176e No 0.57 0.36 -47 0 48 0.074 0.0013 0.044 0 1.4
176n No 0.59 0.36 -47 0 14 -0.12 0.0039 0.033 0 1.53
177e No 0.063 0.45 -47 0 0.71 0.51 0.019 0.13 1.16
177n No 0.6 0.45 -47 0 17 -0.089 0.00033 0.023 0 1.49
178e No 0.6 0.35 -47 0 16 0.16 0.00098 0.04 0 1.43
178n No 0.6 0.35 -47 0 16 -0.12 0.00033 0.034 0 1.58
179e No 0.61 0.35 -47 0 11 0.19 0.0013 0.033 0 1.41
179n No 0.61 0.35 -47 0 9.8 -0.0094 0 0.026 0 1.51
180e No 0.62 0.34 -47 0 15 0.13 0.0029 0.029 0 1.45
180n No 0.51 0.34 -47 0 16 0.82 0 0.24 2.86
181e No 0.63 0.36 -47 0 12 0.1 0 0.04 0 1.49
181n No 0.63 0.36 -47 0 10 0.0069 0.00033 0.036 0 1.68
182e No 0.61 0.35 -47 0 6.9 0.19 0.00033 0.024 0 1.52
182n No 0.63 0.35 -47 0 19 -0.085 0 0.028 0 1.76
183e No 0.6 0.34 -47 0 3.9 0.13 0.0023 0.035 0 1.46
183n No 0.59 0.34 -47 0 2.4 0.037 0.012 0.031 0 1.54
184e No 0.62 0.34 -47 0 15 0.16 0.00033 0.023 0 1.42
184n No 0.63 0.34 -47 0 15 -0.026 0.00033 0.024 0 1.57
185e No 0.62 0.35 -47 0 12 0.15 0.0023 0.03 0 1.46
185n No 0.63 0.35 -47 0 14 -0.0065 0 0.028 0 1.72
186e No 0.62 0.34 -47 0 12 0.094 0.0033 0.028 0 1.65
186n No 0.61 0.34 -47 0 15 0.042 0 0.026 0 2.01
187e No 0.62 0.34 -47 0 13 0.2 0.00033 0.041 0 1.55
187n No 0.62 0.34 -47 0 17 -0.02 0.00065 0.024 0 1.95
188e No 0.59 0.33 -47 0 16 0.18 0.00033 0.028 0 1.55
188n No 0.5 0.33 -47 0 32 0.65 0 0.19 2.56
189e Yes -47 1.5E+03 0 0 0 INF 0
189n Yes -47 1.5E+03 0 0 0 INF 0
190e Yes -47 1.5E+03 0 0 0 INF 0
190n Yes -47 1.5E+03 0 0 0 INF 0
191e Yes -47 1.5E+03 0 0 0 INF 0
191n Yes -47 1.5E+03 0 0 0 INF 0
192e No 0.56 0.35 -47 0 19 0.25 0 0.046 0 1.42
192n No 0.58 0.35 -47 0 24 0.012 0 0.021 0 1.7
193e No 0.56 0.34 -47 0 23 0.19 0 0.028 0 1.43
193n No 0.54 0.34 -47 0 18 0.05 0.00033 0.027 0 1.7
194e No 0.03 -0.00029 -47 0 3.3 0.53 0.059 0.13 1.14
194n No 0.032 -0.00029 -47 0 2.9 0.58 0.084 0.17 1.14
195e No 0.56 0.37 -47 0 23 0.14 0.0016 0.025 0 1.44
195n No 0.53 0.37 -47 0 15 0.09 0.002 0.035 0 1.97
196e No 0.03 0.0017 -47 0 3.2 0.57 0.045 0.13 1.16
196n No 0.034 0.0017 -47 0 3 0.6 0.058 0.18 1.16
197e No 0.55 0.35 -47 0 12 0.25 0.00033 0.039 0 1.56
197n No 0.57 0.35 -47 0 18 0.024 0.00033 0.033 0 1.94
198e No 0.6 0.37 -47 0 26 0.091 0 0.022 0 1.43
198n No 0.57 0.37 -47 0 14 0.081 0.0046 0.037 0 1.5
199e No 0.57 0.42 -47 0 13 0.27 0.0072 0.038 0 1.36
199n No 0.24 0.42 -47 1 0.9 0.56 0.014 0.17 1.17
200e No 0.044 0.49 -47 0 3.2 0.58 0.061 0.14 1.17
200n No 0.59 0.49 -47 0 17 0.026 0.00033 0.025 0 1.43
201e No 0.56 0.34 -47 0 13 0.37 0.0036 0.061 0 1.35
201n No 0.59 0.34 -47 0 15 0.049 0 0.028 0 1.4
202e No 0.6 0.35 -47 0 33 0.14 0 0.021 0 1.36
202n No 0.59 0.35 -47 0 14 0.12 0.012 0.041 0 1.42
204e No 0.62 0.35 -47 0 16 -0.14 0 0.1 0 1.71
204n No 0.62 0.35 -47 0 16 -0.46 0 0.14 0 2.05
205e No 0.61 0.35 -47 0 51 0.038 0 0.06 0 1.47
205n No 0.58 0.35 -47 0 13 0.052 0.0013 0.025 0 1.61
206e No 0.56 0.33 -47 0 13 0.26 0.0094 0.035 0 1.59
206n No 0.58 0.33 -47 0 17 0.06 0.00033 0.028 0 2.02
207e No 0.59 0.34 -47 0 24 0.19 0.0052 0.02 0 1.5
207n No 0.57 0.34 -47 0 13 0.13 0.0049 0.044 0 1.68
208e No 0.038 0.51 -47 0 0.81 0.47 0.04 0.14 1.17
208n No 0.58 0.51 -47 1 2.4 -0.44 0.0026 0.13 0 1.58
209e No 0.59 0.34 -47 0 4.7 -0.21 0.0013 0.11 0 1.31
209n No 0.59 0.34 -47 0 7.8 -0.29 0.00033 0.15 0 1.79
210e No 0.59 0.35 -47 0 13 -0.26 0.00033 0.12 0 1.34
210n No 0.58 0.35 -47 0 14 -0.36 0.00065 0.12 0 1.61
211e No 0.58 0.35 -47 0 27 0.17 0.00065 0.011 0 1.32
211n No 0.57 0.35 -47 0 21 0.012 0.0013 0.016 0 1.53
212e No 0.56 0.36 -47 0 25 0.19 0.00033 0.028 0 1.53
212n No 0.54 0.36 -47 0 14 0.071 0.002 0.041 0 1.8
213e No 0.52 0.34 -47 0 15 0.3 0.16 0.045 1.56
213n No 0.53 0.34 -47 0 17 0.014 0.002 0.023 0 1.64
214e No 0.52 0.35 -47 0 14 0.22 0.0013 0.027 0 1.3
214n No 0.53 0.35 -47 0 23 0.035 0.002 0.028 0 1.66
215e No 0.58 0.35 -47 0 27 0.12 0.0065 0.03 0 1.5
215n No 0.54 0.35 -47 0 13 0.12 0.013 0.1 0 1.72
216e No 0.57 0.35 -47 0 14 0.24 0.0033 0.04 0 1.41
216n No 0.58 0.35 -47 0 19 0.053 0.0016 0.026 0 1.57
217e No 0.32 0.41 -47 0 3.8 0.52 0.088 0.11 1.36
217n No 0.58 0.41 -47 0 14 0.11 0.0013 0.039 0 1.54
218e No 0.59 0.47 -47 0 23 0.12 0.00065 0.029 0 1.37
218n No 0.11 0.47 -47 0 0.61 0.045 0.26 0.18 1.13
220e No 0.59 0.33 -47 0 20 0.19 0.002 0.018 0 1.36
220n No 0.59 0.33 -47 0 21 0.0011 0 0.016 0 1.49
221e No 0.58 0.34 -47 0 17 0.24 0.0013 0.034 0 1.34
221n No 0.6 0.34 -47 0 20 0.046 0 0.021 0 1.51
222e No 0.58 0.35 -47 0 17 0.24 0 0.032 0 1.37
222n No 0.6 0.35 -47 0 23 0.013 0 0.026 0 1.48
223e No 0.57 0.34 -47 0 14 0.18 0.00033 0.017 0 1.38
223n No 0.58 0.34 -47 0 14 0.014 0.00033 0.019 0 1.56
224e No 0.59 0.35 -47 0 33 0.2 0 0.042 0 1.43
224n No 0.6 0.35 -47 0 21 0.02 0.00065 0.026 0 1.65
225e No 0.59 0.35 -47 0 24 0.14 0 0.011 0 1.45
225n No 0.58 0.35 -47 0 21 0.042 0.00033 0.033 0 1.8
226e No 0.57 0.34 -47 0 19 0.12 0 0.022 0 1.46
226n No 0.59 0.34 -47 0 34 -0.035 0 0.024 0 1.71
227e No 0.56 0.33 -47 0 13 0.22 0.0042 0.032 0 1.38
227n No 0.57 0.33 -47 0 15 0.044 0.00033 0.025 0 1.7
228e No 0.56 0.33 -47 0 24 0.17 0.00033 0.022 0 1.38
228n No 0.54 0.33 -47 0 15 0.11 0.00033 0.041 0 1.58
229e No 0.034 0.49 -47 0 3.3 0.54 0.015 0.14 1.14
229n No 0.57 0.49 -47 0 35 -0.039 0 0.026 0 1.59
231e No 0.54 0.35 -47 0 23 0.14 0.0023 0.049 0 1.62
231n No 0.54 0.35 -47 0 30 -0.055 0 0.046 0 1.9
232e No 0.17 -0.27 -47 0 73 0.002 0 0.1 2.58
232n No 0.16 -0.27 -47 0 6.8 0.28 0.0013 0.09 2.16
233e No 0.56 0.36 -47 0 18 0.16 0.00098 0.028 0 1.3
233n No 0.57 0.36 -47 0 33 0.012 0.00065 0.044 0 1.46
234e No 0.55 0.35 -47 0 13 0.27 0.012 0.042 0 1.3
234n No 0.58 0.35 -47 0 18 0.034 0.00098 0.024 0 1.45
235e No 0.56 0.34 -47 0 12 0.24 0.018 0.034 0 1.33
235n No 0.57 0.34 -47 0 14 0.038 0.002 0.028 0 1.48
237e No 0.57 0.34 -47 0 13 0.22 0.002 0.026 0 1.37
237n No 0.58 0.34 -47 0 16 0.05 0 0.027 0 1.5
238e No 0.6 0.35 -47 0 31 0.11 0 0.028 0 1.39
238n No 0.59 0.35 -47 0 29 0.045 0 0.022 0 1.45
239e No 0.59 0.35 -47 0 24 0.13 0 0.013 0 1.36
239n No 0.6 0.35 -47 0 27 -0.0085 0 0.015 0 1.41
240e No 0.58 0.35 -47 0 19 0.17 0 0.023 0 1.33
240n No 0.59 0.35 -47 0 22 0.046 0 0.025 0 1.41
241e No 0.58 0.35 -47 0 19 0.13 0 0.011 0 1.3
241n No 0.59 0.35 -47 0 25 -0.017 0 0.013 0 1.45
242e No 0.59 0.35 -47 0 29 0.09 0 0.022 0 1.33
242n No 0.58 0.35 -47 0 38 -0.042 0 0.036 0 1.53
243e No 0.48 0.34 -47 0 32 0.77 0.00033 0.18 1.89
243n No 0.56 0.34 -47 0 16 0.032 0 0.019 0 1.69
244e No 0.54 0.33 -47 0 13 0.21 0.0072 0.027 0 1.34
244n No 0.55 0.33 -47 0 12 0.077 0.00033 0.029 0 1.59
245e No 0.57 0.36 -47 0 21 0.16 0 0.018 0 1.34
245n No 0.55 0.36 -47 0 13 0.12 0.00033 0.04 0 1.49
246e No 0.53 0.34 -47 0 13 0.27 0.019 0.044 0 1.4
246n No 0.55 0.34 -47 0 22 0.056 0.00033 0.033 0 1.74
250e No 0.56 0.36 -47 0 19 0.25 0.016 0.037 0 1.31
250n No 0.57 0.36 -47 0 22 0.021 0.0013 0.026 0 1.47
251e No 0.036 0.52 -47 1 0.8 0.13 0.041 0.12 1.11
251n No 0.57 0.52 -47 0 5.6 -0.54 0.0013 0.16 0 1.59
252e No 0.57 0.35 -47 0 19 0.17 0.00033 0.027 0 1.54
252n No 0.56 0.35 -47 0 15 0.02 0 0.032 0 1.76
253e No 0.59 0.42 -47 0 40 0.11 0 0.04 0 1.52
253n No 0.38 0.42 -47 0 4.1 0.44 0.028 0.14 0 1.35
255e No 0.56 0.5 -47 0 14 0.19 0.00065 0.038 0 1.59
255n No 0.064 0.5 -47 0 3 0.6 0.13 0.18 1.13
256e No 0.033 0.0031 -47 0 3.2 0.61 0.092 0.14 1.14
256n No 0.029 0.0031 -47 0 3 0.6 0.082 0.18 1.14
261e No 0.55 0.35 -47 0 23 0.11 0.00033 0.016 0 1.38
261n No 0.53 0.35 -47 0 15 0.047 0.0016 0.027 0 1.6
262e No 0.56 0.36 -47 0 9.8 -0.15 0.00098 0.12 0 1.61
262n No 0.56 0.36 -47 0 14 -0.49 0.00033 0.15 0 1.95
266e No 0.45 0.36 -47 0 11 0.77 0.0023 0.22 2.1
266n No 0.58 0.36 -47 0 16 -0.5 0.00033 0.14 0 1.49
267e No 0.57 0.35 -47 0 19 0.073 0.00065 0.036 0 1.45
267n No 0.55 0.35 -47 0 14 -0.016 0.00033 0.033 0 1.62
268e No 0.54 0.34 -47 0 11 0.23 0.0023 0.038 0 1.53
268n No 0.54 0.34 -47 0 12 0.11 0.011 0.048 0 1.8
269e No 0.57 0.5 -47 0 24 0.17 0.00033 0.027 0 1.5
269n No 0.037 0.5 -47 0 3.2 0.59 0.096 0.18 1.13
270e No 0.03 0.00042 -47 0 3.5 0.58 0.017 0.14 1.14
270n No 0.03 0.00042 -47 0 3.2 0.61 0.00065 0.19 1.14
272e Yes -47 1.5E+03 0 0 0 INF 0
272n Yes -47 1.5E+03 0 0 0 INF 0
281e No 0.57 0.36 -47 0 30 0.16 0.00033 0.041 0 1.37
281n No 0.54 0.36 -47 0 15 0.03 0.00033 0.031 0 1.51
282e No 0.56 0.36 -47 0 18 0.18 0.0013 0.024 0 1.36
282n No 0.57 0.36 -47 0 36 -0.023 0 0.034 0 1.43
283e No 0.58 0.37 -47 0 47 0.024 0 0.051 0 1.38
283n No 0.57 0.37 -47 0 34 -0.038 0 0.025 0 1.42
285e No 0.54 0.34 -47 0 19 0.19 0.00033 0.037 0 1.33
285n No 0.52 0.34 -47 0 16 0.067 0.00065 0.053 0 1.46
295e No 0.57 0.36 -47 0 3.6 -0.33 0.0033 0.14 0 1.34
295n No 0.56 0.36 -47 0 5.4 -0.52 0.0036 0.15 0 1.36
320e No 0.5 0.36 -47 0 14 0.11 0.01 0.037 0 -2.36E-17
320n No 0.46 0.36 -47 0 11 -0.09 0.0078 0.051 0 -8.11E-17
321e No 0.48 0.36 -47 0 13 0.19 0.0039 0.038 0 -2.46E-17
321n No 0.48 0.36 -47 0 24 -0.11 0.0016 0.032 0 -2.72E-17
323e No 0.48 0.35 -47 0 12 0.24 0.012 0.033 0
323n No 0.47 0.35 -47 0 28 -0.025 0.0016 0.019 0
324e No 0.46 0.33 -47 0 30 0.14 0.018 0.042 0 -7.6E-17
324n No 0.44 0.33 -47 0 35 -0.013 0.0013 0.049 0 1.62E-17
325e No 0.5 0.36 -47 0 30 0.11 0.0029 0.017 0 5.32
325n No 0.45 0.36 -47 0 17 0.044 0.00098 0.025 0 5.04
326e No 0.49 0.35 -47 0 17 0.2 0.0023 0.038 0 2.17
326n No 0.46 0.35 -47 0 18 0.079 0.0026 0.051 0 2.19
327e No 0.48 0.32 -47 0 23 0.18 0.0016 0.043 0 3.91
327n No 0.48 0.32 -47 0 30 -0.011 0.00098 0.051 0 5.08
328e No 0.042 0.37 -47 0 3.4 0.55 0.0013 0.13 1.13E-18
328n No 0.46 0.37 -47 0 14 0.0053 0.002 0.027 0 3.18E-17
329e No 0.23 0.1 -47 0 51 0.58 0.00033 0.13 0
329n No 0.23 0.1 -47 0 47 0.61 0.00033 0.17
331e No 0.043 0.42 -47 0 3.5 0.57 0.0029 0.13 1.28
331n No 0.48 0.42 -47 0 23 0.068 0.0029 0.045 0 4.19
332e No 0.035 0.00088 -47 0 3.3 0.58 0.046 0.13 9.9E-19
332n No 0.038 0.00088 -47 0 2.9 0.58 0.099 0.17 1.18E-17
333e No 0.42 0.3 -47 0 9.1 0.24 0.02 0.046 0
333n No 0.42 0.3 -47 0 12 -0.045 0.0033 0.046 0
336e No 0.42 0.3 -47 0 12 0.29 0.0016 0.052 0 -3.23E-17
336n No 0.42 0.3 -47 0 15 0.053 0.0026 0.049 0 -9.46E-18
340e No 0.47 0.34 -47 0 38 0.069 0.00098 0.054 0 2.02
340n No 0.44 0.34 -47 0 26 -0.049 0.002 0.047 0 2.04
In [58]:
# 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 [59]:
print('Final Ant-Pol Classification:\n\n', final_class)
Final Ant-Pol Classification:

 Jee:
----------
good (154 antpols):
3, 4, 5, 7, 8, 10, 15, 16, 17, 18, 19, 20, 22, 29, 30, 31, 32, 35, 38, 40, 41, 42, 48, 49, 50, 53, 55, 56, 57, 62, 65, 66, 67, 68, 69, 70, 71, 72, 79, 80, 84, 85, 87, 91, 94, 97, 101, 102, 103, 105, 106, 108, 113, 114, 117, 118, 120, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 138, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 152, 153, 154, 155, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 171, 172, 173, 175, 178, 179, 180, 181, 182, 184, 185, 186, 187, 188, 192, 193, 195, 197, 198, 199, 201, 206, 207, 211, 212, 214, 215, 216, 218, 220, 221, 222, 223, 225, 226, 227, 228, 231, 233, 234, 237, 239, 240, 241, 242, 244, 245, 252, 255, 261, 267, 268, 269, 282, 285

suspect (37 antpols):
9, 21, 33, 36, 37, 46, 52, 54, 73, 81, 82, 83, 96, 98, 100, 104, 116, 119, 139, 151, 176, 183, 202, 204, 205, 209, 210, 224, 235, 238, 246, 250, 253, 262, 281, 283, 295

bad (61 antpols):
27, 28, 34, 45, 47, 51, 61, 63, 64, 77, 78, 86, 88, 89, 90, 92, 93, 95, 99, 107, 109, 110, 111, 112, 115, 121, 137, 170, 174, 177, 189, 190, 191, 194, 196, 200, 208, 213, 217, 229, 232, 243, 251, 256, 266, 270, 272, 320, 321, 323, 324, 325, 326, 327, 328, 329, 331, 332, 333, 336, 340


Jnn:
----------
good (140 antpols):
4, 5, 7, 8, 15, 16, 17, 19, 20, 29, 30, 32, 33, 38, 40, 50, 51, 52, 53, 55, 56, 57, 65, 66, 67, 69, 70, 71, 72, 79, 84, 85, 87, 91, 92, 94, 95, 96, 101, 102, 103, 105, 106, 112, 113, 117, 118, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 132, 133, 135, 136, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 155, 159, 160, 162, 163, 164, 167, 168, 169, 170, 172, 173, 176, 177, 178, 179, 181, 182, 184, 185, 187, 192, 193, 195, 197, 198, 200, 201, 202, 205, 207, 211, 212, 213, 214, 216, 217, 220, 221, 222, 223, 224, 225, 227, 228, 231, 234, 235, 237, 238, 239, 240, 241, 243, 244, 245, 246, 250, 252, 261, 267, 268, 281, 285

suspect (53 antpols):
9, 10, 22, 34, 35, 36, 37, 41, 42, 46, 48, 49, 54, 62, 80, 81, 82, 83, 97, 98, 99, 100, 108, 114, 116, 130, 131, 134, 137, 153, 154, 165, 166, 175, 183, 186, 204, 206, 208, 209, 210, 215, 226, 229, 233, 242, 251, 253, 262, 266, 282, 283, 295

bad (59 antpols):
3, 18, 21, 27, 28, 31, 45, 47, 61, 63, 64, 68, 73, 77, 78, 86, 88, 89, 90, 93, 104, 107, 109, 110, 111, 115, 119, 161, 171, 174, 180, 188, 189, 190, 191, 194, 196, 199, 218, 232, 255, 256, 269, 270, 272, 320, 321, 323, 324, 325, 326, 327, 328, 329, 331, 332, 333, 336, 340

Save calibration solutions¶

In [60]:
# update flags in omnical gains and visibility solutions
for ant in omni_flags:
    omni_flags[ant] |= rfi_flags
for bl in vissol_flags:
    vissol_flags[bl] |= rfi_flags
In [61]:
if SAVE_RESULTS:
    add_to_history = 'Produced by file_calibration notebook with the following environment:\n' + '=' * 65 + '\n' + os.popen('conda env export').read() + '=' * 65    
    
    hd_vissol = io.HERAData(SUM_FILE)
    hc_omni = hd_vissol.init_HERACal(gain_convention='divide', cal_style='redundant')
    hc_omni.update(gains=sol.gains, flags=omni_flags, quals=meta['chisq_per_ant'], total_qual=meta['chisq'])
    hc_omni.history += add_to_history
    hc_omni.write_calfits(OMNICAL_FILE, clobber=True)
    del hc_omni
    malloc_trim()
    
    if SAVE_OMNIVIS_FILE:
        # output results, harmonizing keys over polarizations
        all_reds = redcal.get_reds(hd.data_antpos, pols=['ee', 'nn'], pol_mode='2pol')
        bl_to_red_map = {bl: red[0] for red in all_reds for bl in red}
        hd_vissol.read(bls=[bl_to_red_map[bl] for bl in sol.vis], return_data=False)
        hd_vissol.empty_arrays()
        hd_vissol.history += add_to_history
        hd_vissol.update(data={bl_to_red_map[bl]: sol.vis[bl] for bl in sol.vis}, 
                         flags={bl_to_red_map[bl]: vissol_flags[bl] for bl in vissol_flags}, 
                         nsamples={bl_to_red_map[bl]: vissol_nsamples[bl] for bl in vissol_nsamples})
        hd_vissol.write_uvh5(OMNIVIS_FILE, clobber=True)
#     %memit
In [62]:
if SAVE_RESULTS:
    del hd_vissol
    malloc_trim()
#     %memit    

Output fully flagged calibration file if OMNICAL_FILE is not written¶

In [63]:
if SAVE_RESULTS and not os.path.exists(OMNICAL_FILE):
    print(f'WARNING: No calibration file produced at {OMNICAL_FILE}. Creating a fully-flagged placeholder calibration file.')
    hd_writer = io.HERAData(SUM_FILE)
    io.write_cal(OMNICAL_FILE, freqs=hd_writer.freqs, times=hd_writer.times,
                 gains={ant: np.ones((hd_writer.Ntimes, hd_writer.Nfreqs), dtype=np.complex64) for ant in ants},
                 flags={ant: np.ones((len(data.times), len(data.freqs)), dtype=bool) for ant in ants},
                 quality=None, total_qual=None, outdir='', overwrite=True, history=utils.history_string(add_to_history), 
                 x_orientation=hd_writer.x_orientation, telescope_location=hd_writer.telescope_location, lst_array=np.unique(hd_writer.lsts),
                 antenna_positions=np.array([hd_writer.antenna_positions[hd_writer.antenna_numbers == antnum].flatten() for antnum in set(ant[0] for ant in ants)]),
                 antnums2antnames=dict(zip(hd_writer.antenna_numbers, hd_writer.antenna_names)))

Output empty visibility file if OMNIVIS_FILE is not written¶

In [64]:
if SAVE_RESULTS and not os.path.exists(OMNIVIS_FILE):
    print(f'WARNING: No omnivis file produced at {OMNIVIS_FILE}. Creating an empty visibility solution file.')
    hd_writer = io.HERAData(SUM_FILE)
    hd_writer.initialize_uvh5_file(OMNIVIS_FILE, clobber=True)
WARNING: No omnivis file produced at /mnt/sn1/2460369/zen.2460369.50293.sum.omni_vis.uvh5. Creating an empty visibility solution file.

TODO: Perform nucal¶

Metadata¶

In [65]:
for repo in ['pyuvdata', 'hera_cal', 'hera_filters', 'hera_qm', 'hera_notebook_templates']:
    exec(f'from {repo} import __version__')
    print(f'{repo}: {__version__}')
pyuvdata: 2.4.2
hera_cal: 3.6.dev4+gb043105
hera_filters: 0.1.5
hera_qm: 2.1.3.dev5+g3e71720
hera_notebook_templates: 0.1.dev734+g90f16f4
In [66]:
print(f'Finished execution in {(time.time() - tstart) / 60:.2f} minutes.')
Finished execution in 12.49 minutes.