Coverage for python/lsst/analysis/tools/actions/plot/rhoStatisticsPlot.py: 25%
57 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-10 04:56 -0700
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-10 04:56 -0700
1# This file is part of analysis_tools.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <https://www.gnu.org/licenses/>.
22from __future__ import annotations
24from typing import TYPE_CHECKING, Any, Iterable, Mapping
26__all__ = ("RhoStatisticsPlot",)
28import numpy as np
29from lsst.pex.config import ConfigDictField
31from ...interfaces import PlotAction, Vector
32from .plotUtils import addPlotInfo
33from .xyPlot import XYPlot
35if TYPE_CHECKING: 35 ↛ 36line 35 didn't jump to line 36, because the condition on line 35 was never true
36 from matplotlib.figure import Figure
38 from ...interfaces import KeyedData, KeyedDataSchema
41class RhoStatisticsPlot(PlotAction):
42 """Make multiple plots of rho statistics.
44 Rho statistics capture the spatial correlation amongst various PSF size and
45 shape residual quantities. For exact definitions, see
46 :ref:`here <rho_definitions>`.
47 """
49 rhoPlots = ConfigDictField(
50 doc="A configurable dict describing the rho statistics to plot.",
51 keytype=str,
52 itemtype=XYPlot,
53 default={},
54 )
56 def setDefaults(self) -> None:
57 super().setDefaults()
58 self.rhoPlots = {rhoName: XYPlot() for rhoName in ("rho3alt", "rho1", "rho2", "rho3", "rho4", "rho5")}
60 yLabels = {
61 "rho3alt": r"$\rho'_{3}(\theta) = \langle \frac{\delta T}{T}, \frac{\delta T}{T}\rangle$",
62 "rho1": r"$\rho_{1}(\theta) = \langle \delta e, \delta e \rangle$",
63 "rho2": r"$\rho_{2}(\theta) = \langle e, \delta e \rangle$",
64 "rho3": r"$\rho_{3}(\theta) = \langle e\frac{\delta T}{T} , e\frac{\delta T}{T} \rangle$",
65 "rho4": r"$\rho_{4}(\theta) = \langle \delta e, e\frac{\delta T}{T} \rangle$",
66 "rho5": r"$\rho_{5}(\theta) = \langle e, e\frac{\delta T}{T} \rangle$",
67 }
69 for rhoId, rhoPlot in self.rhoPlots.items():
70 rhoPlot.xAxisLabel = "Separation [arcmin]"
71 rhoPlot.yAxisLabel = yLabels[rhoId]
72 rhoPlot.xScale = "log"
73 rhoPlot.yScale = "symlog"
74 rhoPlot.yLinThresh = 1e-6
75 rhoPlot.yLine = 0.0
77 self.rhoPlots["rho3alt"].yScale = "linear" # type: ignore
79 def getInputSchema(self) -> KeyedDataSchema:
80 # Docstring inherited
81 base: list[tuple[str, type[Vector]]] = []
82 base.append(("coord_ra", Vector))
83 base.append(("coord_dec", Vector))
84 base.append(("{{band}}_ixx", Vector))
85 base.append(("{{band}}_iyy", Vector))
86 base.append(("{{band}}_ixy", Vector))
87 base.append(("{{band}}_ixxPSF", Vector))
88 base.append(("{{band}}_iyyPSF", Vector))
89 base.append(("{{band}}_ixyPSF", Vector))
90 return base
92 def getOutputNames(self) -> Iterable[str]:
93 # Docstring inherited
94 return ("rho3alt", "rho1", "rho2", "rho3", "rho4", "rho5")
96 def __call__(self, data: KeyedData, **kwargs) -> Mapping[str, Figure]:
97 self._validateInput(data)
98 return self.makePlot(data, **kwargs)
100 def _validateInput(self, data: KeyedData) -> None:
101 if not set(("rho3alt", "rho1", "rho2", "rho3", "rho4", "rho5")).issubset(data.keys()):
102 raise ValueError("Input data must contain rho3alt, rho1, rho2, rho3, rho4, and rho5.")
104 def makePlot(
105 self, data: KeyedData, plotInfo: Mapping[str, str] | None = None, **kwargs: Any
106 ) -> Mapping[str, Figure]:
107 r"""Make the plot(s).
109 Parameters
110 ----------
111 data : `~pandas.core.frame.DataFrame`
112 The catalog containing various rho statistics.
113 plotInfo : `dict`, optional
114 A dictionary of information about the data being plotted with keys:
115 ``"run"``
116 The output run for the plots (`str`).
117 ``"skymap"``
118 The type of skymap used for the data (`str`).
119 ``"filter"``
120 The filter used for this data (`str`).
121 ``"tract"``
122 The tract that the data comes from (`str`).
123 **kwargs
124 Additional keyword arguments to pass to the plot
126 Returns
127 -------
128 fig_dict : `dict` [`~matplotlib.figure.Figure`]
129 The resulting figures.
130 The figure corresponding :math:`\rho_1(\theta)` can be accessed
131 with the key `rho1` and similarly for the other rho statistics.
132 :math:`\rho_3'` is accessed with the key `rho3alt`.
134 Examples
135 --------
136 An example rho statistics plot may be seen below:
138 .. image:: /_static/analysis_tools/rhoPlotExample.png
140 For further details on how to generate a plot, please refer to the
141 :ref:`getting started guide<analysis-tools-getting-started>`.
142 """
143 fig_dict: dict[str, Figure] = {}
144 for rho_name in ("rho1", "rho2", "rho3", "rho4", "rho5"):
145 rho: XYPlot = self.rhoPlots[rho_name]
147 subdata = {
148 "x": data[rho_name].meanr, # type: ignore
149 "y": data[rho_name].xip, # type: ignore
150 "yerr": np.sqrt(data[rho_name].varxip), # type: ignore
151 "xerr": None,
152 }
153 fig = rho(subdata, **kwargs)
154 if plotInfo is not None:
155 fig_dict[rho_name] = addPlotInfo(fig, plotInfo)
157 # rho3alt is handled differently because its attributes differ.
158 subdata = {
159 "x": data["rho3alt"].meanr, # type: ignore
160 "y": data["rho3alt"].xi, # type: ignore
161 "yerr": np.sqrt(data["rho3alt"].varxi), # type: ignore
162 "xerr": None,
163 }
164 fig = self.rhoPlots["rho3alt"](subdata, **kwargs) # type: ignore[misc]
165 if plotInfo is not None:
166 fig_dict["rho3alt"] = addPlotInfo(fig, plotInfo)
168 return fig_dict