Example #1
0
def plot_time_table(t_ccd_table):
    fig = plt.figure(figsize=(6, 5))
    day_secs = DateTime(t_ccd_table['day']).secs
    nom_t_ccd = t_ccd_table['nom_t_ccd']
    best_t_ccd = t_ccd_table['best_t_ccd']
    plot_cxctime(day_secs,
                 nom_t_ccd,
                 'r')
    plot_cxctime(day_secs,
                 best_t_ccd,
                 'b')
    plot_cxctime(day_secs,
                 nom_t_ccd,
                 'r.',
                 label='nom roll t ccd')
    plot_cxctime(day_secs,
                 best_t_ccd,
                 'b.',
                 label='best roll t ccd')
    plt.grid()
    plt.ylim(ymin=COLD_T_CCD, ymax=WARM_T_CCD + 3.0)
    plt.xlim(xmin=cxctime2plotdate([day_secs[0]]),
             xmax=cxctime2plotdate([day_secs[-1]]))
    plt.legend(loc='upper left', title="", numpoints=1, handlelength=.5)
    plt.ylabel('Max ACA CCD Temp (degC)')
    plt.tight_layout()
    return fig
Example #2
0
def plot_cxctime(times, y, fmt='-b', fig=None, ax=None, yerr=None, xerr=None, tz=None,
                 state_codes=None, interactive=True, **kwargs):
    """Make a date plot where the X-axis values are in CXC time.  If no ``fig``
    value is supplied then the current figure will be used (and created
    automatically if needed).  If yerr or xerr is supplied, ``errorbar()`` will be
    called and any additional keyword arguments will be passed to it.  Otherwise
    any additional keyword arguments (e.g. ``fmt='b-'``) are passed through to
    the ``plot()`` function.  Also see ``errorbar()`` for an explanation of the possible
    forms of *yerr*/*xerr*.

    If the ``state_codes`` keyword argument is provided then the y-axis ticks and
    tick labels will be set accordingly.  The ``state_codes`` value must be a list
    of (raw_count, state_code) tuples, and is normally set to ``msid.state_codes``
    for an MSID object from fetch().

    If the ``interactive`` keyword is True (default) then the plot will be redrawn
    at the end and a GUI callback will be created which allows for on-the-fly
    update of the date tick labels when panning and zooming interactively.  Set
    this to False to improve the speed when making several plots.  This will likely
    require issuing a plt.draw() or fig.canvas.draw() command at the end.

    :param times: CXC time values for x-axis (date)
    :param y: y values
    :param fmt: plot format (default = '-b')
    :param fig: pyplot figure object (optional)
    :param yerr: error on y values, may be [ scalar | N, Nx1, or 2xN array-like ]
    :param xerr: error on x values in units of DAYS (may be [ scalar | N, Nx1, or 2xN array-like ] )
    :param tz: timezone string
    :param state_codes: list of (raw_count, state_code) tuples
    :param interactive: use plot interactively (default=True, faster if False)
    :param **kwargs: keyword args passed through to ``plot_date()`` or ``errorbar()``

    :rtype: ticklocs, fig, ax = tick locations, figure, and axes object.
    """

    if fig is None:
        fig = matplotlib.pyplot.gcf()

    if ax is None:
        ax = fig.gca()

    if yerr is not None or xerr is not None:
        ax.errorbar(cxctime2plotdate(times), y, yerr=yerr, xerr=xerr, fmt=fmt, **kwargs)
        ax.xaxis_date(tz)
    else:
        ax.plot_date(cxctime2plotdate(times), y, fmt=fmt, **kwargs)
    ticklocs = Ska.Matplotlib.set_time_ticks(ax)
    fig.autofmt_xdate()

    if state_codes is not None:
        counts, codes = zip(*state_codes)
        ax.yaxis.set_major_locator(Ska.Matplotlib.FixedLocator(counts))
        ax.yaxis.set_major_formatter(Ska.Matplotlib.FixedFormatter(codes))

    # If plotting interactively then show the figure and enable interactive resizing
    if interactive and hasattr(fig, 'show'):
        # fig.canvas.draw()
        ax.callbacks.connect('xlim_changed', Ska.Matplotlib.remake_ticks)

    return ticklocs, fig, ax
Example #3
0
def paint_perigee(perigee_passages, states, plots, msid):
    """
    This function draws vertical dahsed lines for EEF, Perigee and XEF
    events in the load.EEF and XEF lines are black; Perigee is red.

    You supply the list of perigee passage events which are:
        Radzone Start/Stop time
        Perigee Passage time

        The states you created in main

        The dictionary of plots you created

        The MSID (in this case FP_TEMP) used to access the dictionary
    """
    #
    # Now plot any perigee passages that occur between xmin and xmax
    for eachpassage in perigee_passages:
        # The index [1] item is always the Perigee Passage time. Draw that line in red
        # If this line is between tstart and tstop then it needs to be drawn 
        # on the plot. otherwise ignore
        if states['tstop'][-1] >= DateTime(eachpassage[0]).secs >= states['tstart'][0]:
            # Have to convert this time into the new x axis time scale necessitated by SKA
            xpos = cxctime2plotdate([DateTime(eachpassage[0]).secs])

            ymin, ymax = plots[msid]['ax'].get_ylim()

            # now plot the line.
            plots[msid]['ax'].vlines(xpos, ymin, ymax, linestyle=':', color='red', linewidth=2.0)

            # Plot the perigee passage time so long as it was specified in the CTI_report file
            if eachpassage[1] != "Not-within-load":
                perigee_time = cxctime2plotdate([DateTime(eachpassage[1]).secs])
                plots[msid]['ax'].vlines(perigee_time, ymin, ymax, linestyle=':',
                                         color='black', linewidth=2.0)
Example #4
0
def plot_cxctime(times, y, fmt='-b', fig=None, ax=None, yerr=None, xerr=None, tz=None,
                 state_codes=None, interactive=True, **kwargs):
    """Make a date plot where the X-axis values are in CXC time.  If no ``fig``
    value is supplied then the current figure will be used (and created
    automatically if needed).  If yerr or xerr is supplied, ``errorbar()`` will be
    called and any additional keyword arguments will be passed to it.  Otherwise
    any additional keyword arguments (e.g. ``fmt='b-'``) are passed through to
    the ``plot()`` function.  Also see ``errorbar()`` for an explanation of the possible
    forms of *yerr*/*xerr*.

    If the ``state_codes`` keyword argument is provided then the y-axis ticks and
    tick labels will be set accordingly.  The ``state_codes`` value must be a list
    of (raw_count, state_code) tuples, and is normally set to ``msid.state_codes``
    for an MSID object from fetch().

    If the ``interactive`` keyword is True (default) then the plot will be redrawn
    at the end and a GUI callback will be created which allows for on-the-fly
    update of the date tick labels when panning and zooming interactively.  Set
    this to False to improve the speed when making several plots.  This will likely
    require issuing a plt.draw() or fig.canvas.draw() command at the end.

    :param times: CXC time values for x-axis (date)
    :param y: y values
    :param fmt: plot format (default = '-b')
    :param fig: pyplot figure object (optional)
    :param yerr: error on y values, may be [ scalar | N, Nx1, or 2xN array-like ] 
    :param xerr: error on x values in units of DAYS (may be [ scalar | N, Nx1, or 2xN array-like ] )
    :param tz: timezone string
    :param state_codes: list of (raw_count, state_code) tuples
    :param interactive: use plot interactively (default=True, faster if False)
    :param **kwargs: keyword args passed through to ``plot_date()`` or ``errorbar()``

    :rtype: ticklocs, fig, ax = tick locations, figure, and axes object.
    """

    if fig is None:
        fig = matplotlib.pyplot.gcf()

    if ax is None:
        ax = fig.gca()

    if yerr is not None or xerr is not None:
        ax.errorbar(cxctime2plotdate(times), y, yerr=yerr, xerr=xerr, fmt=fmt, **kwargs)
        ax.xaxis_date(tz)
    else:
        ax.plot_date(cxctime2plotdate(times), y, fmt=fmt, **kwargs)
    ticklocs = Ska.Matplotlib.set_time_ticks(ax)
    fig.autofmt_xdate()

    if state_codes is not None:
        counts, codes = zip(*state_codes)
        ax.yaxis.set_major_locator(Ska.Matplotlib.FixedLocator(counts))
        ax.yaxis.set_major_formatter(Ska.Matplotlib.FixedFormatter(codes))

    # If plotting interactively then show the figure and enable interactive resizing
    if interactive and hasattr(fig, 'show'):
        # fig.canvas.draw()
        ax.callbacks.connect('xlim_changed', Ska.Matplotlib.remake_ticks)

    return ticklocs, fig, ax
def plot_two(
        fig_id,
        x,
        y,
        x2,
        y2,
        linestyle='-',
        linestyle2='-',
        color='blue',
        color2='magenta',
        ylim=None,
        ylim2=None,
        xlabel='',
        ylabel='',
        ylabel2='',
        title='',
        figsize=(7, 3.5),
        markersize2=None,
        marker2=None,
):
    """Plot two quantities with a date x-axis"""
    xt = cxctime2plotdate(x)
    fig = plt.figure(fig_id, figsize=figsize)
    fig.clf()
    ax = fig.add_subplot(1, 1, 1)
    ax.plot_date(xt, y, fmt='-', linestyle=linestyle, color=color)
    ax.set_xlim(min(xt), max(xt))
    if ylim:
        ax.set_ylim(*ylim)
    ax.set_xlabel(xlabel)
    ax.set_ylabel(ylabel)
    ax.set_title(title)
    ax.grid()

    ax2 = ax.twinx()

    xt2 = cxctime2plotdate(x2)
    ax2.plot_date(xt2,
                  y2,
                  fmt='-',
                  linestyle=linestyle2,
                  color=color2,
                  markersize=markersize2,
                  marker=marker2)
    ax2.set_xlim(min(xt), max(xt))
    if ylim2:
        ax2.set_ylim(*ylim2)
    ax2.set_ylabel(ylabel2, color=color2)
    ax2.xaxis.set_visible(False)

    set_time_ticks(ax)
    [label.set_rotation(30) for label in ax.xaxis.get_ticklabels()]
    [label.set_color(color2) for label in ax2.yaxis.get_ticklabels()]

    fig.subplots_adjust(bottom=0.22)

    return {'fig': fig, 'ax': ax, 'ax2': ax2}
def plot_two(
    fig_id,
    x,
    y,
    x2,
    y2,
    linestyle="-",
    linestyle2="-",
    color="blue",
    color2="magenta",
    ylim=None,
    ylim2=None,
    xlabel="",
    ylabel="",
    ylabel2="",
    title="",
    figsize=(7, 3.5),
    markersize2=None,
    marker2=None,
):
    """Plot two quantities with a date x-axis"""
    xt = cxctime2plotdate(x)
    fig = plt.figure(fig_id, figsize=figsize)
    fig.clf()
    ax = fig.add_subplot(1, 1, 1)
    ax.plot_date(xt, y, fmt="-", linestyle=linestyle, color=color)
    ax.set_xlim(min(xt), max(xt))
    if ylim:
        ax.set_ylim(*ylim)
    ax.set_xlabel(xlabel)
    ax.set_ylabel(ylabel)
    ax.set_title(title)
    ax.grid()

    ax2 = ax.twinx()

    xt2 = cxctime2plotdate(x2)
    ax2.plot_date(xt2, y2, fmt="-", linestyle=linestyle2, color=color2, markersize=markersize2, marker=marker2)
    ax2.set_xlim(min(xt), max(xt))
    if ylim2:
        ax2.set_ylim(*ylim2)
    ax2.set_ylabel(ylabel2, color=color2)
    ax2.xaxis.set_visible(False)

    set_time_ticks(ax)
    [label.set_rotation(30) for label in ax.xaxis.get_ticklabels()]
    [label.set_color(color2) for label in ax2.yaxis.get_ticklabels()]

    fig.subplots_adjust(bottom=0.22)

    return {"fig": fig, "ax": ax, "ax2": ax2}
Example #7
0
def paint_perigee(perigee_passages, states, plots):
    """
    This function draws vertical dashed lines for EEF, Perigee and XEF
    events in the load.EEF and XEF lines are black; Perigee is red.

    You supply the list of perigee passage events which are:
        Radzone Start/Stop time
        Perigee Passage time

        The states you created in main

        The dictionary of plots you created

        The MSID (in this case FP_TEMP) used to access the dictionary
    """
    #
    # Now plot any perigee passages that occur between xmin and xmax
    from cxotime import CxoTime
    for plot in plots.values():
        for eachpassage in perigee_passages:
            # The index [1] item is always the Perigee Passage time. Draw that
            # line in red If this line is between tstart and tstop then it
            # needs to be drawn on the plot. otherwise ignore
            if states['tstop'][-1] >= CxoTime(
                    eachpassage[0]).secs >= states['tstart'][0]:
                # Have to convert this time into the new x axis time scale
                # necessitated by SKA
                xpos = cxctime2plotdate([CxoTime(eachpassage[0]).secs])

                ymin, ymax = plot['ax'].get_ylim()

                # now plot the line.
                plot['ax'].vlines(xpos,
                                  ymin,
                                  ymax,
                                  linestyle=':',
                                  color='red',
                                  linewidth=2.0)

                # Plot the perigee passage time so long as it was specified in
                # the CTI_report file
                if eachpassage[1] != "Not-within-load":
                    perigee_time = cxctime2plotdate(
                        [CxoTime(eachpassage[1]).secs])
                    plot['ax'].vlines(perigee_time,
                                      ymin,
                                      ymax,
                                      linestyle=':',
                                      color='black',
                                      linewidth=2.0)
Example #8
0
File: base.py Project: nrawolk/xija
 def __init__(self, model):
     self.model = model
     self.n_mvals = 0
     self.predict = False  # Predict values for this model component
     self.pars = []
     self.data = None
     self.data_times = None
     self.model_plotdate = cxctime2plotdate(self.model.times)
Example #9
0
 def update(self, *args):
     pd0, pd1, pd_center = cxctime2plotdate(times[np.array(get_index_lims())])
     if not hasattr(self, 'patch'):
         self.patch = matplotlib.patches.Rectangle(
             (pd0, 0), width=(pd1-pd0), height=1.6e8, zorder=-100,
             facecolor='y', alpha=0.5)
         self.ax.add_patch(self.patch)
     else:
         self.patch.set_xy((pd0, 0))
         self.patch.set_width(pd1-pd0)
Example #10
0
 def update(self, *args):
     pd0, pd1, pd_center = cxctime2plotdate(times[np.array(get_index_lims())])
     if not hasattr(self, 'patch'):
         self.patch = matplotlib.patches.Rectangle(
             (pd0, 0), width=(pd1-pd0), height=1.6e8, zorder=-100,
             facecolor='y', alpha=0.5)
         self.ax.add_patch(self.patch)
     else:
         self.patch.set_xy((pd0, 0))
         self.patch.set_width(pd1-pd0)
Example #11
0
File: base.py Project: jzuhone/xija
    def __init__(self, model):
        # This class overrides __setattr__ with a method that requires
        # the `pars` and `pars_dict` attrs to be visible.  So do this
        # with the super (object) method right away.
        super(ModelComponent, self).__setattr__('pars', [])
        super(ModelComponent, self).__setattr__('pars_dict', {})

        self.model = model
        self.n_mvals = 0
        self.predict = False  # Predict values for this model component
        self.data = None
        self.data_times = None
        self.model_plotdate = cxctime2plotdate(self.model.times)
Example #12
0
 def _plot_bands(self, tbegin, tend, plot, events, color, alpha=1.0):
     tc_start = list(self.events[events[0]]["times"])
     tc_end = list(self.events[events[1]]["times"])
     if tc_end[0] < tc_start[0]:
         tc_start.insert(0, self.first_time)
     if tc_start[-1] > tc_end[-1]:
         tc_end.append(self.last_time)
     assert len(tc_start) == len(tc_end)
     tc_start = date2secs(tc_start)
     tc_end = date2secs(tc_end)
     ybot, ytop = plot.ax.get_ylim()
     t = np.linspace(tbegin, tend, 500)
     tplot = cxctime2plotdate(t)
     for tcs, tce in zip(tc_start, tc_end):
         in_evt = (t >= tcs) & (t <= tce)
         plot.ax.fill_between(tplot,
                              ybot,
                              ytop,
                              where=in_evt,
                              color=color,
                              alpha=alpha)
Example #13
0
def test_check_many_sizes():
    """Run through a multiplicative series of x-axis lengths and visually
    confirm that chosen axes are OK."""
    plt.ion()
    dt = 6
    while True:
        print dt
        t0 = np.random.uniform(3e7 * 10)
        times = np.linspace(t0, t0 + dt, 20)
        x = cxctime2plotdate(times)
        y = np.random.normal(size=len(times))

        fig = plt.figure(1)
        fig.clf()
        plt1 = fig.add_subplot(1, 1, 1)
        plt1.plot_date(x, y, fmt="b-")

        set_time_ticks(plt1)

        fig.autofmt_xdate()
        plt.savefig("test-{:09d}.png".format(dt))
        dt *= 2
        if dt > 1e9:
            break
Example #14
0
    def make_prediction_plots(self, outdir, states, times, temps, load_start):
        """
        Make plots of the thermal prediction as well as associated 
        commanded states.

        Parameters
        ----------
        outdir : string
            The path to the output directory.
        states : NumPy record array
            Commanded states
        times : NumPy array
            Times in seconds from the beginning of the mission for the
            temperature arrays
        temps : dict of NumPy arrays
            Dictionary of temperature arrays
        load_start : float
            The start time of the load in seconds from the beginning of the
            mission.
        """
        plots = {}

        # Start time of loads being reviewed expressed in units for plotdate()
        load_start = cxctime2plotdate([load_start])[0]
        # Value for left side of plots
        plot_start = max(load_start-2.0, cxctime2plotdate([times[0]])[0])

        w1 = None
        mylog.info('Making temperature prediction plots')
        plots[self.name] = plot_two(fig_id=1, x=times, y=temps[self.name],
                                    x2=pointpair(states['tstart'], states['tstop']),
                                    y2=pointpair(states['pitch']),
                                    title=self.msid.upper(), xmin=plot_start,
                                    xlabel='Date', ylabel='Temperature (C)',
                                    ylabel2='Pitch (deg)', ylim2=(40, 180),
                                    figsize=(8.0, 4.0), width=w1, load_start=load_start)
        # Add horizontal lines for the planning and caution limits
        ymin, ymax = plots[self.name]['ax'].get_ylim()
        ymax = max(self.yellow_hi+1, ymax)
        plots[self.name]['ax'].axhline(self.yellow_hi, linestyle='-', color='y',
                                       linewidth=2.0)
        plots[self.name]['ax'].axhline(self.plan_limit_hi, linestyle='--', 
                                       color='y', linewidth=2.0)
        if self.flag_cold_viols:
            ymin = min(self.yellow_lo-1, ymin)
            plots[self.name]['ax'].axhline(self.yellow_lo, linestyle='-', color='y',
                                           linewidth=2.0)
            plots[self.name]['ax'].axhline(self.plan_limit_lo, linestyle='--',
                                           color='y', linewidth=2.0)
        plots[self.name]['ax'].set_ylim(ymin, ymax)
        filename = self.msid.lower() + '.png'
        outfile = os.path.join(outdir, filename)
        mylog.info('Writing plot file %s' % outfile)
        plots[self.name]['fig'].savefig(outfile)
        plots[self.name]['filename'] = filename

        # The next line is to ensure that the width of the axes
        # of all the weekly prediction plots are the same.
        w1, _ = plots[self.name]['fig'].get_size_inches()

        self._make_state_plots(plots, 1, w1, plot_start,
                               outdir, states, load_start)

        plots['default'] = plots[self.name]

        return plots
Example #15
0
File: base.py Project: sot/xija
 def model_plotdate(self):
     if not hasattr(self, '_model_plotdate'):
         self._model_plotdate = cxctime2plotdate(self.model.times)
     return self._model_plotdate
Example #16
0
def draw_obsids(extract_and_filter, 
                obs_with_sensitivity, 
                nopref_array,
                plots,
                msid, 
                ypos, 
                endcapstart, 
                endcapstop, 
                textypos, 
                fontsize,
                plot_start):
    """
    This functiion draws visual indicators across the top of the plot showing
    which observations are ACIS; whether they are ACIS-I (red) or ACIS-S (green)
    when they start and stop, and whether or not any observation is sensitive to the
    focal plane temperature.  The list of observations sensitive to the focal plane
    is found by reading the fp_sensitive.dat file that is located in each LR
    directory and is created by the LR script.

    No CTI measurements are indicated - only science runs.

    The caller supplies:
               Options from the Command line supplied by the user at runtime
               The instance of the ObsidFindFilter() class created 
               nopref rec array
               The plot dictionary
               The MSID used to index into the plot dictinary (superfluous but required)
               The position on the Y axis you'd like these indicators to appear
               The Y position of the bottom of the end caps
               The Y position of the top of the end caps
               The starting position of the OBSID number text
               The font size
               The left time of the plot in plot_date units
    """
    # Now run through the observation list attribute of the ObsidFindFilter class
    for eachobservation in obs_with_sensitivity:
        # extract the obsid

        obsid = str(extract_and_filter.get_obsid(eachobservation))

        # Color all ACIS-S observations green; all ACIS-I 
        # observations red
        if eachobservation[extract_and_filter.in_focal_plane] == "ACIS-I":
            color = 'red'
        else:
            color = 'green'

        # Add the sensitivity text if the observation was found to be FP TEMP
        # sensitive
        #
        # If the observation is FP sensitive in the first place............
        if eachobservation[extract_and_filter.is_fp_sensitive]:
            # extract the obsid for convenience
            this_obsid = extract_and_filter.get_obsid(eachobservation)

            # But if it's also in the nopref list AND the upcased CandS_status entry is "NO PREF"
            where_words = np.where(nopref_array['obsid'] == str(this_obsid))
            if str(this_obsid) in nopref_array['obsid'] and \
               nopref_array['CandS_status'][where_words[0][0]].upper()[:7] == 'NO_PREF':
                color = 'purple'
                obsid = obsid + ' * NO PREF *'
            else:
                obsid = obsid + ' * FP SENS *'

        # Convert the start and stop times into the Ska-required format
        obs_start = cxctime2plotdate([extract_and_filter.get_tstart(eachobservation)])
        obs_stop = cxctime2plotdate([extract_and_filter.get_tstop(eachobservation)])

        if eachobservation[extract_and_filter.in_focal_plane].startswith("ACIS-"):
            # For each ACIS Obsid, draw a horizontal line to show 
            # its start and stop
            plots[msid]['ax'].hlines(ypos, 
                                     obs_start, 
                                     obs_stop, 
                                     linestyle='-', 
                                     color=color, 
                                     linewidth=2.0)

            # Plot vertical end caps for each obsid to visually show start/stop
            plots[msid]['ax'].vlines(obs_start, 
                                     endcapstart, 
                                     endcapstop, 
                                     color=color, 
                                     linewidth=2.0)
            plots[msid]['ax'].vlines(obs_stop, 
                                     endcapstart, 
                                     endcapstop, 
                                     color=color, 
                                     linewidth=2.0)

            # Now print the obsid in the middle of the time span, 
            # above the line, and rotate 90 degrees. 

            obs_time = obs_start + (obs_stop - obs_start)/2
            if obs_time > plot_start:
                # Now plot the obsid.
                plots[msid]['ax'].text(obs_time, 
                                       textypos, 
                                       obsid,  
                                       color = color, 
                                       va='bottom', 
                                       ma='left', 
                                       rotation = 90, 
                                       fontsize = fontsize)
Example #17
0
    def make_prediction_plots(self, outdir, states, times, temps, tstart):
        """
        Make output plots.

        :param outdir: the directory to which the products are written
        :param states: commanded states
        :param times: time stamps (sec) for temperature arrays
        :param temps: dict of temperatures
        :param tstart: load start time
        :rtype: dict of review information including plot file names

        This function assumes that ACIS Ops LR has been run and that the directory
        is populated with
        """

        # Gather perigee passages
        self._gather_perigee(times[0], tstart)

        # Next we need to find all the ACIS-S observations within the start/stop
        # times so that we can paint those on the plots as well. We will get
        # those from the commanded states data structure called "states" 
        # 
        # Create an instance of the ObsidFindFilter class. This class provides
        # methods to extract obsid intervals from the commanded states based 
        # upon ACIS definitions and considerations. It also provides
        # various methods to filter the interval set based upon pitch range, 
        # number of ccd's, filter out CTI observations, and a range of exposure 
        # times.
        extract_and_filter = ObsidFindFilter()

        # extract the OBSID's from the commanded states. NOTE: this contains all
        # observations including CTI runs and HRC observations
        observation_intervals = extract_and_filter.find_obsid_intervals(states, None)

        # Filter out any HRC science observations BUT keep ACIS CTI observations
        acis_and_cti_obs = extract_and_filter.hrc_science_obs_filter(observation_intervals)

        # Ok so now you have all the ACIS observations collected. Also,
        # they have been identified by ObsidFindFilter as to who is in the focal plane.
        # Some apps, like this one, care about FP_TEMP sensitivity. Some do not. 
        # Since we do, then checking that and assigning a sensitivity must be done
        # 
        # Open the sensitive observation list file, which is found in the LR 
        # directory,
        # read each line, extract the OBSID and add that to a list.
        sensefile = open(os.path.join(self.bsdir, 'fp_sensitive.txt'), 'r')

        # The list_of_sensitive_obs is the list of all FP TEMP sensitive 
        # observations extracted from the file in the load review directory
        list_of_sensitive_obs = []

        # Get the list of FP_TEMP sensitive observations
        for eachline in sensefile.readlines()[1:]:
            # Extract the OBSID from each line; the obsid is in the second
            # column of this line. Append it to the list of FP_TEMP sensitive
            # observations
            #
            # NOTE: The obsid here is a STRING
            list_of_sensitive_obs.append(eachline.split()[1])
        # Done with the file - close it
        sensefile.close()

        # Now that you have the latest list of temperature sensitive OBSID's,
        # run through each observation and append either "*FP SENS*" or
        # "NOT FP SENS" to the end of each observation.

        # Now run through the observation list attribute of the ObsidFindFilter class
        for eachobservation in acis_and_cti_obs:
            # Pull the obsid from the observation and turn it into a string

            obsid = str(extract_and_filter.get_obsid(eachobservation))
            # See if it's in the sensitive list. If so, indicate whether or
            # not this observation is FP Senstive in the new list. This will be
            # used later in make_prediction_viols to catch violations.
            if obsid in list_of_sensitive_obs:
                eachobservation.append(True)
            else:
                eachobservation.append(False)

            self.obs_with_sensitivity.append(eachobservation)

        # create an empty dictionary called plots to contain the returned
        # figures, axes 1  and axes 2 of the plot_two call
        plots = {}

        # Start time of loads being reviewed expressed in units for plotdate()
        load_start = cxctime2plotdate([tstart])[0]
        # Value for left side of plots
        plot_start = max(load_start-2.0, cxctime2plotdate([times[0]])[0])

        w1 = None
        # Make plots of FPTEMP and pitch vs time, looping over
        # three different temperature ranges
        ylim = [(-120, -90), (-120, -119), (-120.0, -111.5)]
        ypos = [-110.0, -119.35, -116]
        capwidth = [2.0, 0.1, 0.4]
        textypos = [-108.0, -119.3, -115.7]
        fontsize = [12, 9, 9]
        for i in range(3):
            name = "%s_%d" % (self.name, i+1)
            plots[name] = plot_two(fig_id=i+1, x=times, y=temps[self.name],
                                   x2=pointpair(states['tstart'], states['tstop']),
                                   y2=pointpair(states['pitch']),
                                   title=self.msid.upper() + " (ACIS-I obs. in red; ACIS-S in green)",
                                   xlabel='Date', ylabel='Temperature (C)',
                                   ylabel2='Pitch (deg)', xmin=plot_start,
                                   ylim=ylim[i], ylim2=(40, 180),
                                   figsize=(12, 6), width=w1, load_start=load_start)
            # Draw a horizontal line indicating the FP Sensitive Observation Cut off
            plots[name]['ax'].axhline(self.fp_sens_limit, linestyle='--', color='red', linewidth=2.0)
            # Draw a horizontal line showing the ACIS-I -114 deg. C cutoff
            plots[name]['ax'].axhline(self.acis_i_limit, linestyle='--', color='purple', linewidth=1.0)
            # Draw a horizontal line showing the ACIS-S -112 deg. C cutoff
            plots[name]['ax'].axhline(self.acis_s_limit, linestyle='--', color='blue', linewidth=1.0)

            # Get the width of this plot to make the widths of all the
            # prediction plots the same
            if i == 0:
                w1, _ = plots[name]['fig'].get_size_inches()

            # Now plot any perigee passages that occur between xmin and xmax
            # for eachpassage in perigee_passages:
            paint_perigee(self.perigee_passages, states, plots, name)

            # Now draw horizontal lines on the plot running from start to stop
            # and label them with the Obsid
            draw_obsids(extract_and_filter, self.obs_with_sensitivity, self.nopref_array,
                        plots, name, ypos[i], ypos[i]-0.5*capwidth[i], ypos[i]+0.5*capwidth[i],
                        textypos[i], fontsize[i], plot_start)

            # Build the file name and output the plot to a file
            filename = self.msid.lower() + 'M%dtoM%d.png' % (-ylim[i][0], -ylim[i][1])
            outfile = os.path.join(outdir, filename)
            mylog.info('Writing plot file %s' % outfile)
            plots[name]['fig'].savefig(outfile)
            plots[name]['filename'] = filename

        self._make_state_plots(plots, 3, w1, plot_start,
                               outdir, states, load_start, figsize=(12, 6))

        return plots
Example #18
0
import numpy as np
import matplotlib.pyplot as plt
from  Ska.Matplotlib import cxctime2plotdate
dac_vals = np.array([])
dac_times = np.array([])
from Chandra.Time import DateTime
for year in range(2002, 2014):
    print year
    y_dac_vals = np.load('{}_vals.npy'.format(year))
    y_dac_mask = np.load('{}_mask.npy'.format(year))
    dac_vals = np.append(dac_vals, y_dac_vals[~y_dac_mask])
    del y_dac_vals
    y_dac_times = cxctime2plotdate(np.load('{}_times.npy'.format(year)))
    dac_times = np.append(dac_times, y_dac_times[~y_dac_mask])
    del y_dac_times
    del y_dac_mask

plt.figure(figsize=(6,4))
plt.plot_date(dac_times, dac_vals, 'b.', markersize=1)
plt.ylim(230, 530)
plt.xlabel('Year')
plt.ylabel('DAC level')
plt.setp(plt.gca().xaxis.get_majorticklabels(), rotation=30)
plt.tight_layout()
plt.grid()
plt.savefig('dac_level_over_time.png')
Example #19
0
 def model_plotdate(self):
     if not hasattr(self, '_model_plotdate'):
         self._model_plotdate = cxctime2plotdate(self.model.times)
     return self._model_plotdate
Example #20
0
def draw_obsids(extract_and_filter, obs_with_sensitivity, plots, msid, ypos,
                endcapstart, endcapstop, textypos, fontsize, plot_start):
    """
    This function draws visual indicators across the top of the plot showing
    which observations are ACIS; whether they are ACIS-I (red) or ACIS-S (green)
    when they start and stop, and whether or not any observation is sensitive to the
    focal plane temperature.  The list of observations sensitive to the focal plane
    is found by reading the fp_sensitive.dat file that is located in each LR
    directory and is created by the LR script.

    No CTI measurements are indicated - only science runs.

    The caller supplies:
               Options from the Command line supplied by the user at runtime
               The instance of the ObsidFindFilter() class created 
               The plot dictionary
               The MSID used to index into the plot dictionary (superfluous but required)
               The position on the Y axis you'd like these indicators to appear
               The Y position of the bottom of the end caps
               The Y position of the top of the end caps
               The starting position of the OBSID number text
               The font size
               The left time of the plot in plot_date units
    """
    # Now run through the observation list attribute of the ObsidFindFilter class
    for eachobservation in obs_with_sensitivity:
        # extract the obsid

        obsid = str(extract_and_filter.get_obsid(eachobservation))

        # Color all ACIS-S observations green; all ACIS-I
        # observations red
        if eachobservation[extract_and_filter.in_focal_plane] == "ACIS-I":
            color = 'red'
        else:
            color = 'green'

        # Add the sensitivity text if the observation was found to be FP TEMP
        # sensitive
        #
        # If the observation is FP sensitive in the first place............
        if eachobservation[extract_and_filter.is_fp_sensitive]:
            obsid = obsid + ' * FP SENS *'

        # Convert the start and stop times into the Ska-required format
        obs_start = cxctime2plotdate(
            [extract_and_filter.get_tstart(eachobservation)])
        obs_stop = cxctime2plotdate(
            [extract_and_filter.get_tstop(eachobservation)])

        if eachobservation[extract_and_filter.in_focal_plane].startswith(
                "ACIS-"):
            # For each ACIS Obsid, draw a horizontal line to show
            # its start and stop
            plots[msid]['ax'].hlines(ypos,
                                     obs_start,
                                     obs_stop,
                                     linestyle='-',
                                     color=color,
                                     linewidth=2.0)

            # Plot vertical end caps for each obsid to visually show start/stop
            plots[msid]['ax'].vlines(obs_start,
                                     endcapstart,
                                     endcapstop,
                                     color=color,
                                     linewidth=2.0)
            plots[msid]['ax'].vlines(obs_stop,
                                     endcapstart,
                                     endcapstop,
                                     color=color,
                                     linewidth=2.0)

            # Now print the obsid in the middle of the time span,
            # above the line, and rotate 90 degrees.

            obs_time = obs_start + (obs_stop - obs_start) / 2
            if obs_time > plot_start:
                # Now plot the obsid.
                plots[msid]['ax'].text(obs_time,
                                       textypos,
                                       obsid,
                                       color=color,
                                       va='bottom',
                                       ma='left',
                                       rotation=90,
                                       fontsize=fontsize)
Example #21
0
    def make_prediction_plots(self, outdir, states, temps, tstart):
        """
        Make output plots.

        :param outdir: the directory to which the products are written
        :param states: commanded states
        :param times: time stamps (sec) for temperature arrays
        :param temps: dict of temperatures
        :param tstart: load start time
        :rtype: dict of review information including plot file names

        This function assumes that ACIS Ops LR has been run and that the directory
        is populated with
        """

        times = self.predict_model.times

        # Gather perigee passages
        self._gather_perigee(times[0], tstart)

        # Next we need to find all the ACIS-S observations within the start/stop
        # times so that we can paint those on the plots as well. We will get
        # those from the commanded states data structure called "states"
        #
        # Create an instance of the ObsidFindFilter class. This class provides
        # methods to extract obsid intervals from the commanded states based
        # upon ACIS definitions and considerations. It also provides
        # various methods to filter the interval set based upon pitch range,
        # number of ccd's, filter out CTI observations, and a range of exposure
        # times.
        extract_and_filter = ObsidFindFilter()

        # extract the OBSID's from the commanded states. NOTE: this contains all
        # observations including CTI runs and HRC observations
        observation_intervals = extract_and_filter.find_obsid_intervals(
            states, None)

        # Filter out any HRC science observations BUT keep ACIS CTI observations
        acis_and_cti_obs = extract_and_filter.hrc_science_obs_filter(
            observation_intervals)

        # Ok so now you have all the ACIS observations collected. Also,
        # they have been identified by ObsidFindFilter as to who is in the focal plane.
        # Some apps, like this one, care about FP_TEMP sensitivity. Some do not.
        # Since we do, then checking that and assigning a sensitivity must be done
        #
        # Open the sensitive observation list file, which is found in the LR
        # directory,
        # read each line, extract the OBSID and add that to a list.
        sensefile = open(os.path.join(self.bsdir, 'fp_sensitive.txt'), 'r')

        # The list_of_sensitive_obs is the list of all FP TEMP sensitive
        # observations extracted from the file in the load review directory
        list_of_sensitive_obs = []

        # Get the list of FP_TEMP sensitive observations
        for eachline in sensefile.readlines()[1:]:
            # Extract the OBSID from each line; the obsid is in the second
            # column of this line. Append it to the list of FP_TEMP sensitive
            # observations
            #
            # NOTE: The obsid here is a STRING
            list_of_sensitive_obs.append(eachline.split()[1])
        # Done with the file - close it
        sensefile.close()

        # Now that you have the latest list of temperature sensitive OBSID's,
        # run through each observation and append either "*FP SENS*" or
        # "NOT FP SENS" to the end of each observation.

        # Now run through the observation list attribute of the ObsidFindFilter class
        for eachobservation in acis_and_cti_obs:
            # Pull the obsid from the observation and turn it into a string

            obsid = str(extract_and_filter.get_obsid(eachobservation))
            # See if it's in the sensitive list. If so, indicate whether or
            # not this observation is FP Senstive in the new list. This will be
            # used later in make_prediction_viols to catch violations.
            if obsid in list_of_sensitive_obs:
                eachobservation.append(True)
            else:
                eachobservation.append(False)

            self.obs_with_sensitivity.append(eachobservation)

        # create an empty dictionary called plots to contain the returned
        # figures, axes 1  and axes 2 of the plot_two call
        plots = {}

        # Start time of loads being reviewed expressed in units for plotdate()
        load_start = cxctime2plotdate([tstart])[0]
        # Value for left side of plots
        plot_start = max(load_start - 2.0, cxctime2plotdate([times[0]])[0])

        w1 = None
        # Make plots of FPTEMP and pitch vs time, looping over
        # three different temperature ranges
        ylim = [(-120, -90), (-120, -119), (-120.0, -109.5)]
        ypos = [-110.0, -119.35, -116]
        capwidth = [2.0, 0.1, 0.4]
        textypos = [-108.0, -119.3, -115.7]
        fontsize = [12, 9, 9]
        for i in range(3):
            name = "%s_%d" % (self.name, i + 1)
            plots[name] = plot_two(fig_id=i + 1,
                                   x=times,
                                   y=temps[self.name],
                                   x2=self.predict_model.times,
                                   y2=self.predict_model.comp["pitch"].mvals,
                                   title=self.msid.upper() +
                                   " (ACIS-I obs. in red; ACIS-S in green)",
                                   xlabel='Date',
                                   ylabel='Temperature (C)',
                                   ylabel2='Pitch (deg)',
                                   xmin=plot_start,
                                   ylim=ylim[i],
                                   ylim2=(40, 180),
                                   width=w1,
                                   load_start=load_start)
            # Draw a horizontal line indicating the FP Sensitive Observation Cut off
            plots[name]['ax'].axhline(self.fp_sens_limit,
                                      linestyle='--',
                                      color='red',
                                      linewidth=2.0)
            # Draw a horizontal line showing the ACIS-I -114 deg. C cutoff
            plots[name]['ax'].axhline(self.acis_i_limit,
                                      linestyle='--',
                                      color='purple',
                                      linewidth=1.0)
            # Draw a horizontal line showing the ACIS-S -112 deg. C cutoff
            plots[name]['ax'].axhline(self.acis_s_limit,
                                      linestyle='--',
                                      color='blue',
                                      linewidth=1.0)

            # Get the width of this plot to make the widths of all the
            # prediction plots the same
            if i == 0:
                w1, _ = plots[name]['fig'].get_size_inches()

            # Now plot any perigee passages that occur between xmin and xmax
            # for eachpassage in perigee_passages:
            paint_perigee(self.perigee_passages, states, plots, name)

            # Now draw horizontal lines on the plot running from start to stop
            # and label them with the Obsid
            draw_obsids(extract_and_filter, self.obs_with_sensitivity, plots,
                        name, ypos[i], ypos[i] - 0.5 * capwidth[i],
                        ypos[i] + 0.5 * capwidth[i], textypos[i], fontsize[i],
                        plot_start)

            # Build the file name and output the plot to a file
            filename = self.msid.lower() + 'M%dtoM%d.png' % (-ylim[i][0],
                                                             -ylim[i][1])
            outfile = os.path.join(outdir, filename)
            mylog.info('Writing plot file %s' % outfile)
            plots[name]['fig'].savefig(outfile)
            plots[name]['filename'] = filename

        self._make_state_plots(plots,
                               3,
                               w1,
                               plot_start,
                               outdir,
                               states,
                               load_start,
                               figsize=(12, 6))

        return plots
Example #22
0
    def make_validation_plots(self, tlm, model_spec, outdir, run_start):
        """
        Make validation output plots by running the thermal model from a
        time in the past forward to the present and compare it to real
        telemetry

        Parameters
        ----------
        tlm : NumPy record array
            NumPy record array of telemetry
        model_spec : string
            The path to the thermal model specification.
        outdir : string
            The directory to write outputs to.
        run_start : string
            The starting date/time of the run. 
        """
        start = tlm['date'][0]
        stop = tlm['date'][-1]
        states = self.state_builder.get_validation_states(start, stop)

        mylog.info('Calculating %s thermal model for validation' % self.name.upper())

        # Run the thermal model from the beginning of obtained telemetry
        # to the end, so we can compare its outputs to the real values
        model = self.calc_model_wrapper(model_spec, states, start, stop)

        self.validate_model = model

        # Use an OrderedDict here because we want the plots on the validation
        # page to appear in this order
        pred = OrderedDict([(self.msid, model.comp[self.msid].mvals),
                            ('pitch', model.comp['pitch'].mvals),
                            ('tscpos', model.comp['sim_z'].mvals)])
        if "roll" in model.comp:
            pred["roll"] = model.comp['roll'].mvals

        # Interpolate the model and data to a consistent set of times
        idxs = Ska.Numpy.interpolate(np.arange(len(tlm)), tlm['date'], model.times,
                                     method='nearest')
        tlm = tlm[idxs]

        # Set up labels for validation plots
        labels = {self.msid: 'Degrees (C)',
                  'pitch': 'Pitch (degrees)',
                  'tscpos': 'SIM-Z (steps/1000)',
                  'roll': 'Off-Nominal Roll (degrees)'}

        scales = {'tscpos': 1000.}

        fmts = {self.msid: '%.2f',
                'pitch': '%.3f',
                'tscpos': '%d',
                'roll': '%.3f'}

        # Set up a mask of "good times" for which the validation is 
        # "valid", e.g., not during situations where we expect in 
        # advance that telemetry and model data will not match. This
        # is so we do not flag violations during these times
        good_mask = np.ones(len(tlm), dtype='bool')
        if hasattr(model, "bad_times"):
            for interval in model.bad_times:
                bad = ((tlm['date'] >= DateTime(interval[0]).secs)
                    & (tlm['date'] < DateTime(interval[1]).secs))
                good_mask[bad] = False

        # find perigee passages
        rzs = events.rad_zones.filter(start, stop)

        plots = []
        mylog.info('Making %s model validation plots and quantile table' % self.name.upper())
        quantiles = (1, 5, 16, 50, 84, 95, 99)
        # store lines of quantile table in a string and write out later
        quant_table = ''
        quant_head = ",".join(['MSID'] + ["quant%d" % x for x in quantiles])
        quant_table += quant_head + "\n"
        xmin, xmax = cxctime2plotdate(model.times)[[0, -1]]
        for fig_id, msid in enumerate(pred.keys()):
            plot = dict(msid=msid.upper())
            fig = plt.figure(10 + fig_id, figsize=(7, 3.5))
            fig.clf()
            scale = scales.get(msid, 1.0)
            ticklocs, fig, ax = plot_cxctime(model.times, tlm[msid] / scale,
                                             fig=fig, fmt='-r')
            ticklocs, fig, ax = plot_cxctime(model.times, pred[msid] / scale,
                                             fig=fig, fmt='-b')
            if np.any(~good_mask):
                ticklocs, fig, ax = plot_cxctime(model.times[~good_mask], 
                                                 tlm[msid][~good_mask] / scale,
                                                 fig=fig, fmt='.c')
            ax.set_title(msid.upper() + ' validation')
            ax.set_ylabel(labels[msid])
            ax.grid()
            # add lines for perigee passages
            for rz in rzs:
                ptimes = cxctime2plotdate([rz.tstart, rz.tstop])
                for ptime in ptimes:
                    ax.axvline(ptime, ls='--', color='g')
            # Add horizontal lines for the planning and caution limits
            # or the limits for the focal plane model. Make sure we can
            # see all of the limits.
            if self.msid == msid:
                ymin, ymax = ax.get_ylim()
                if msid == "fptemp":
                    fp_sens, acis_s, acis_i = get_acis_limits("fptemp")
                    ax.axhline(acis_i, linestyle='-.', color='purple')
                    ax.axhline(acis_s, linestyle='-.', color='blue')
                    ymax = max(acis_i+1, ymax)
                else:
                    ax.axhline(self.yellow_hi, linestyle='-', color='y')
                    ax.axhline(self.plan_limit_hi, linestyle='--', color='y')
                    ymax = max(self.yellow_hi+1, ymax)
                    if self.flag_cold_viols:
                        ax.axhline(self.yellow_lo, linestyle='-', color='y')
                        ax.axhline(self.plan_limit_lo, linestyle='--', color='y')
                        ymin = min(self.yellow_lo-1, ymin)
                ax.set_ylim(ymin, ymax)
            ax.set_xlim(xmin, xmax)
            filename = msid + '_valid.png'
            outfile = os.path.join(outdir, filename)
            mylog.info('Writing plot file %s' % outfile)
            fig.savefig(outfile)
            plot['lines'] = filename

            # Figure out histogram masks
            if msid == self.msid:
                masks = self.get_histogram_mask(tlm, self.hist_limit)
                ok = masks[0] & good_mask
                # Some models have a second histogram limit
                if len(self.hist_limit) == 2:
                    ok2 = masks[1] & good_mask
                else:
                    ok2 = np.zeros(tlm[msid].size, dtype=bool)
            else:
                ok = np.ones(tlm[msid].size, dtype=bool)
                ok2 = np.zeros(tlm[msid].size, dtype=bool)
            diff = np.sort(tlm[msid][ok] - pred[msid][ok])
            if ok2.any():
                diff2 = np.sort(tlm[msid][ok2] - pred[msid][ok2])
            quant_line = "%s" % msid
            for quant in quantiles:
                quant_val = diff[(len(diff) * quant) // 100]
                plot['quant%02d' % quant] = fmts[msid] % quant_val
                quant_line += (',' + fmts[msid] % quant_val)
            quant_table += quant_line + "\n"
            # We make two histogram plots for each validation,
            # one with linear and another with log scaling.
            for histscale in ('log', 'lin'):
                fig = plt.figure(20 + fig_id, figsize=(4, 3))
                fig.clf()
                ax = fig.gca()
                ax.hist(diff / scale, bins=50, log=(histscale == 'log'),
                        histtype='step', color='b')
                if ok2.any():
                    ax.hist(diff2 / scale, bins=50, log=(histscale == 'log'),
                            color='red', histtype='step')
                ax.set_title(msid.upper() + ' residuals: data - model')
                ax.set_xlabel(labels[msid])
                fig.subplots_adjust(bottom=0.18)
                filename = '%s_valid_hist_%s.png' % (msid, histscale)
                outfile = os.path.join(outdir, filename)
                mylog.info('Writing plot file %s' % outfile)
                fig.savefig(outfile)
                plot['hist' + histscale] = filename

            plots.append(plot)

        # Write quantile tables to a CSV file
        filename = os.path.join(outdir, 'validation_quant.csv')
        mylog.info('Writing quantile table %s' % filename)
        f = open(filename, 'w')
        f.write(quant_table)
        f.close()

        # If run_start is specified this is likely for regression testing
        # or other debugging.  In this case write out the full predicted and
        # telemetered dataset as a pickle.
        if run_start:
            filename = os.path.join(outdir, 'validation_data.pkl')
            mylog.info('Writing validation data %s' % filename)
            f = open(filename, 'wb')
            pickle.dump({'pred': pred, 'tlm': tlm}, f)
            f.close()

        return plots
Example #23
0
def plot_one(fig_id, x, y, yy=None, linestyle='-',
             ll='--', color=thermal_blue, 
             linewidth=2, xmin=None, xmax=None, 
             ylim=None, xlabel='', ylabel='', title='',
             figsize=(12, 6), load_start=None,
             width=None):
    """
    Plot one quantities with a date x-axis and a left
    y-axis.

    Parameters
    ----------
    fig_id : integer
        The ID for this particular figure.
    x : NumPy array
        Times in seconds since the beginning of the mission for
        the left y-axis quantity.
    y : NumPy array
        Quantity to plot against the times on the left x-axis.
    yy : NumPy array, optional
        A second quantity to plot against the times on the 
        left x-axis. Default: None
    linestyle : string, optional
        The style of the line for the left y-axis.
    ll : string, optional
        The style of the second line for the left y-axis.
    color : string, optional
        The color of the line for the left y-axis.
    linewidth : string, optional
        The width of the lines. Default: 2
    xmin : float, optional
        The left-most value of the x-axis.
    xmax : float, optional
        The right-most value of the x-axis.
    ylim : 2-tuple, optional
        The limits for the left y-axis.
    xlabel : string, optional
        The label of the x-axis.
    ylabel : string, optional
        The label for the left y-axis.
    title : string, optional
        The title for the plot.
    figsize : 2-tuple of floats
        Size of plot in width and height in inches.
    """
    # Convert times to dates
    xt = cxctime2plotdate(x)
    fig = plt.figure(fig_id, figsize=figsize)
    fig.clf()
    ax = fig.add_subplot(1, 1, 1)
    # Plot left y-axis
    ax.plot_date(xt, y, fmt='-', linestyle=linestyle, linewidth=linewidth, 
                 color=color)
    if yy is not None:
        ax.plot_date(xt, yy, fmt='-', linestyle=ll, linewidth=linewidth, 
                     color=color)
    if xmin is None:
        xmin = min(xt)
    if xmax is None:
        xmax = max(xt)
    ax.set_xlim(xmin, xmax)
    if ylim:
        ax.set_ylim(*ylim)
    ax.set_xlabel(xlabel)
    ax.set_ylabel(ylabel)
    ax.set_title(title)
    ax.grid()

    if load_start is not None:
        # Add a vertical line to mark the start time of the load
        ax.axvline(load_start, linestyle='-', color='g', linewidth=2.0)

    Ska.Matplotlib.set_time_ticks(ax)
    [label.set_rotation(30) for label in ax.xaxis.get_ticklabels()]

    fig.subplots_adjust(bottom=0.22, right=0.87)
    # The next several lines ensure that the width of the axes
    # of all the weekly prediction plots are the same
    if width is not None:
        w2, _ = fig.get_size_inches()
        lm = fig.subplotpars.left * width / w2
        rm = fig.subplotpars.right * width / w2
        fig.subplots_adjust(left=lm, right=rm)

    return {'fig': fig, 'ax': ax}
Example #24
0
def plot_one(fig_id, x, y, linestyle='-', 
             color='blue', xmin=None,
             xmax=None, ylim=None, 
             xlabel='', ylabel='', title='',
             figsize=(7, 3.5), load_start=None,
             width=None):
    """
    Plot one quantities with a date x-axis and a left
    y-axis.

    Parameters
    ----------
    fig_id : integer
        The ID for this particular figure.
    x : NumPy array
        Times in seconds since the beginning of the mission for
        the left y-axis quantity.
    y : NumPy array
        Quantity to plot against the times on the left x-axis.
    linestyle : string, optional
        The style of the line for the left y-axis.
    color : string, optional
        The color of the line for the left y-axis.
    xmin : float, optional
        The left-most value of the x-axis.
    xmax : float, optional
        The right-most value of the x-axis.
    ylim : 2-tuple, optional
        The limits for the left y-axis.
    xlabel : string, optional
        The label of the x-axis.
    ylabel : string, optional
        The label for the left y-axis.
    title : string, optional
        The title for the plot.
    figsize : 2-tuple of floats
        Size of plot in width and height in inches.
    """
    # Convert times to dates
    xt = cxctime2plotdate(x)
    fig = plt.figure(fig_id, figsize=figsize)
    fig.clf()
    ax = fig.add_subplot(1, 1, 1)
    # Plot left y-axis
    ax.plot_date(xt, y, fmt='-', linestyle=linestyle, color=color)
    if xmin is None:
        xmin = min(xt)
    if xmax is None:
        xmax = max(xt)
    ax.set_xlim(xmin, xmax)
    if ylim:
        ax.set_ylim(*ylim)
    ax.set_xlabel(xlabel)
    ax.set_ylabel(ylabel)
    ax.set_title(title)
    ax.grid()

    if load_start is not None:
        # Add a vertical line to mark the start time of the load
        ax.axvline(load_start, linestyle='-', color='g', linewidth=2.0)

    Ska.Matplotlib.set_time_ticks(ax)
    [label.set_rotation(30) for label in ax.xaxis.get_ticklabels()]

    fig.subplots_adjust(bottom=0.22, right=0.87)
    # The next several lines ensure that the width of the axes
    # of all the weekly prediction plots are the same
    if width is not None:
        w2, _ = fig.get_size_inches()
        lm = fig.subplotpars.left * width / w2
        rm = fig.subplotpars.right * width / w2
        fig.subplots_adjust(left=lm, right=rm)

    return {'fig': fig, 'ax': ax}
Example #25
0
    dat = dat[dat['r5_c2'] != 1759.75]
    dat = dat[dat['r6_c5'] != 791.0]
    dat = dat[dat['r2_c7'] != 584.0]
    dat = dat[dat['r7_c5'] != 470.0]
    dat = dat[dat['r2_c0'] != 410.0]
    dat = dat[dat['r0_c6'] != 235.0]
    dat = dat[dat['r0_c7'] != 217.0]
    dat = dat[dat['time'] > start.secs]
    dat['dt'] = dat['time'] - dat['time'][0]
    integ = dat['INTEG']

    ccdfig = plt.figure("ccdplot")
    ccdax = plt.gca()
    if ccdax.lines:
        ccdline = ccdax.lines[0]
        ccdline.set_data(cxctime2plotdate(dat['time']), dat['TEMPCD'])
        ccdax.relim()
        ccdax.autoscale_view()
    else:
        plot_cxctime(dat['time'], dat['TEMPCD'], 'b.', ax=ccdax)

    #for colname in colnames:
    #    dat[colname] = median_filter(dat[colname], 5)
    maxes = [np.max(median_filter(dat[colname], 5)) for colname in colnames]

    i_brightest = np.argsort(maxes)[-opt.n_brightest:]
    cols = []
    for i, colname in enumerate(colnames):
        if i in i_brightest:
            cols.append(dat[colname])
Example #26
0
def plot_two(fig_id,
             x,
             y,
             x2,
             y2,
             yy=None,
             linewidth=2,
             linestyle='-',
             linestyle2='-',
             ll='--',
             color=thermal_blue,
             color2='magenta',
             xmin=None,
             xmax=None,
             ylim=None,
             ylim2=None,
             xlabel='',
             ylabel='',
             ylabel2='',
             title='',
             figsize=(12, 6),
             load_start=None,
             width=None):
    """
    Plot two quantities with a date x-axis, one on the left
    y-axis and the other on the right y-axis.

    Parameters
    ----------
    fig_id : integer
        The ID for this particular figure.
    x : NumPy array
        Times in seconds since the beginning of the mission for
        the left y-axis quantity.
    y : NumPy array
        Quantity to plot against the times on the left x-axis.
    x2 : NumPy array
        Times in seconds since the beginning of the mission for
        the right y-axis quantity.
    y2 : NumPy array
        Quantity to plot against the times on the right y-axis.
    yy : NumPy array, optional
        A second quantity to plot against the times on the 
        left x-axis. Default: None
    linewidth : string, optional
        The width of the lines. Default: 2
    linestyle : string, optional
        The style of the line for the left y-axis.
    linestyle2 : string, optional
        The style of the line for the right y-axis.
    ll : string, optional
        The style of the second line for the left y-axis.
    color : string, optional
        The color of the line for the left y-axis.
    color2 : string, optional
        The color of the line for the right y-axis.
    xmin : float, optional
        The left-most value of the x-axis.
    xmax : float, optional
        The right-most value of the x-axis.
    ylim : 2-tuple, optional
        The limits for the left y-axis.
    ylim2 : 2-tuple, optional
        The limits for the right y-axis.
    xlabel : string, optional
        The label of the x-axis.
    ylabel : string, optional
        The label for the left y-axis.
    ylabel2 : string, optional
        The label for the right y-axis.
    title : string, optional
        The title for the plot.
    figsize : 2-tuple of floats
        Size of plot in width and height in inches.
    """
    # Convert times to dates
    xt = cxctime2plotdate(x)
    fig = plt.figure(fig_id, figsize=figsize)
    fig.clf()
    ax = fig.add_subplot(1, 1, 1)
    # Plot left y-axis
    ax.plot_date(xt,
                 y,
                 fmt='-',
                 linestyle=linestyle,
                 linewidth=linewidth,
                 color=color)
    if yy is not None:
        ax.plot_date(xt,
                     yy,
                     fmt='-',
                     linestyle=ll,
                     linewidth=linewidth,
                     color=color)
    if xmin is None:
        xmin = min(xt)
    if xmax is None:
        xmax = max(xt)
    ax.set_xlim(xmin, xmax)
    if ylim:
        ax.set_ylim(*ylim)
    ax.set_xlabel(xlabel)
    ax.set_ylabel(ylabel)
    ax.set_title(title)
    ax.grid()

    # Plot right y-axis

    ax2 = ax.twinx()
    xt2 = cxctime2plotdate(x2)
    ax2.plot_date(xt2,
                  y2,
                  fmt='-',
                  linestyle=linestyle2,
                  linewidth=linewidth,
                  color=color2)
    ax2.set_xlim(xmin, xmax)
    if ylim2:
        ax2.set_ylim(*ylim2)
    ax2.set_ylabel(ylabel2, color=color2)
    ax2.xaxis.set_visible(False)

    if load_start is not None:
        # Add a vertical line to mark the start time of the load
        ax.axvline(load_start, linestyle='-', color='g', linewidth=2.0)

    Ska.Matplotlib.set_time_ticks(ax)
    for label in ax.xaxis.get_ticklabels():
        label.set_rotation_mode("anchor")
        label.set_rotation(30)
        label.set_horizontalalignment('right')
    [label.set_color(color2) for label in ax2.yaxis.get_ticklabels()]
    ax.tick_params(which='major', axis='x', length=6)
    ax.tick_params(which='minor', axis='x', length=3)
    fig.subplots_adjust(bottom=0.22, right=0.87)
    # The next several lines ensure that the width of the axes
    # of all the weekly prediction plots are the same
    if width is not None:
        w2, _ = fig.get_size_inches()
        lm = fig.subplotpars.left * width / w2
        rm = fig.subplotpars.right * width / w2
        fig.subplots_adjust(left=lm, right=rm)

    ax.set_zorder(10)
    ax.patch.set_visible(False)

    return {'fig': fig, 'ax': ax, 'ax2': ax2}