<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Mission trend for upper limit on aspect solution RMS error
Using the method described in the sim_asol_centroids notebook, this plots the mission trend of the upper limit on 1-axis aspect solution RMS error.  This shows that nearly all observations are comfortably below the SE31 image reconstruction budget.  However there
is a detectable trend upward that correlates with increase ACA CCD temperature, and
some outliers are approaching or have exceeded the limit.
Obsid 14462 was noted independently because of large yaw gyro biases.  Obsid 14557
was highlighted in V&V for extremely large centroid residuals.  The root cause
was not fully understood, but perhaps this was the
result of a very unlucky configuration of CCD hot pixels.
<img src="asol_rms_err_upper_limit.png">
Step1:  Figure 1 - Using the method described in the sim_asol_centroids notebook, this plot shows the mission trend of the upper limit on 1-axis aspect solution RMS error.
<ASSISTANT_TASK:>
Python Code:
from mica.vv import get_rms_data
from astropy.table import Table
import matplotlib.pyplot as plt
from Ska.Matplotlib import plot_cxctime
from astropy.time import Time
%matplotlib inline
# Get the mica table of V&V data
dat = Table(get_rms_data())
# Filter table to select only useful and final data
datm = dat['obsid isdefault tstart  used slot type dy_rms dz_rms'.split()]
ok = (dat['type'] == 'GUIDE') & (dat['used'] == 1) & (dat['isdefault'] == 1)
datm = datm[ok]
datm.sort('obsid')
datm
# Group by obsid
datmg = datm['obsid tstart dy_rms dz_rms'.split()].group_by('obsid')
datmg.groups[1]
# Select the minimum within each obsid
datmg_min = datmg.groups.aggregate(np.min)
# Make the plot
dyz_rms = np.maximum(datmg_min['dy_rms'], datmg_min['dz_rms'])
for sym, alpha in (('.b', 0.8), (',r', 0.5), (',y', 0.15)):
    plot_cxctime(datmg_min['tstart'], dyz_rms, sym, alpha=alpha)
plt.grid()
x0, x1 = plt.xlim()
plt.hlines(0.177, x0, x1, linestyles='--', colors='r')
plt.text(x0, 0.177, '  SE31 image reconstruction budget', va='bottom', ha='left')
plt.text(Time('2013:240').plot_date, 0.21, 'Obsid 14557', ha='right')
plt.text(Time('2012:180').plot_date, 0.255, 'Obsid 14462', ha='right')
plt.ylabel('Error upper limit (arcsec)');
plt.title('Aspect solution 1-axis RMS error upper limit vs. time');
plt.savefig('asol_rms_err_upper_limit.png');
Explanation: Mission trend for upper limit on aspect solution RMS error
Using the method described in the sim_asol_centroids notebook, this plots the mission trend of the upper limit on 1-axis aspect solution RMS error.  This shows that nearly all observations are comfortably below the SE31 image reconstruction budget.  However there
is a detectable trend upward that correlates with increase ACA CCD temperature, and
some outliers are approaching or have exceeded the limit.
Obsid 14462 was noted independently because of large yaw gyro biases.  Obsid 14557
was highlighted in V&V for extremely large centroid residuals.  The root cause
was not fully understood, but perhaps this was the
result of a very unlucky configuration of CCD hot pixels.
<img src="asol_rms_err_upper_limit.png">
End of explanation
# Show outliers
ok = dyz_rms > 0.2
datmg_min[ok]
Explanation: Figure 1 - Using the method described in the sim_asol_centroids notebook, this plot shows the mission trend of the upper limit on 1-axis aspect solution RMS error.
End of explanation
<END_TASK>