Coverage for tests/test_finalizeCharacterization.py: 26%
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# This file is part of pipe_tasks.
2#
3# LSST Data Management System
4# This product includes software developed by the
5# LSST Project (http://www.lsst.org/).
6# See COPYRIGHT file at the top of the source tree.
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the LSST License Statement and
19# the GNU General Public License along with this program. If not,
20# see <https://www.lsstcorp.org/LegalNotices/>.
21#
22"""Test FinalizeCharacterizationTask.
23"""
24import unittest
25import numpy as np
26import pandas as pd
28import lsst.utils.tests
29import lsst.daf.butler
30import lsst.pipe.base as pipeBase
32from lsst.pipe.tasks.finalizeCharacterization import (FinalizeCharacterizationConfig,
33 FinalizeCharacterizationTask)
36class MockDataFrameReference(lsst.daf.butler.DeferredDatasetHandle):
37 """Very simple object that looks like a Gen3 data reference to
38 a dataframe.
39 """
40 def __init__(self, df):
41 self.df = df
43 def get(self, parameters={}, **kwargs):
44 """Retrieve the specified dataset using the API of the Gen3 Butler.
46 Parameters
47 ----------
48 parameters : `dict`, optional
49 Parameter dictionary. Supported key is ``columns``.
51 Returns
52 -------
53 dataframe : `pandas.DataFrame`
54 dataframe, cut to the specified columns.
55 """
56 if 'columns' in parameters:
57 _columns = parameters['columns']
59 return self.df[_columns]
60 else:
61 return self.df.copy()
64class TestFinalizeCharacterizationTask(FinalizeCharacterizationTask):
65 """A derived class which skips the initialization routines.
66 """
67 __test__ = False # Stop Pytest from trying to parse as a TestCase
69 def __init__(self, **kwargs):
70 pipeBase.PipelineTask.__init__(self, **kwargs)
72 self.makeSubtask('reserve_selection')
75class FinalizeCharacterizationTestCase(lsst.utils.tests.TestCase):
76 """Tests of some functionality of FinalizeCharacterizationTask.
78 Full testing comes from integration tests such as ci_hsc and ci_imsim.
80 These tests bypass the middleware used for accessing data and
81 managing Task execution.
82 """
83 def setUp(self):
84 config = FinalizeCharacterizationConfig()
86 self.finalizeCharacterizationTask = TestFinalizeCharacterizationTask(
87 config=config,
88 )
90 self.isolated_star_cat_dict, self.isolated_star_source_dict = self._make_isocats()
92 def _make_isocats(self):
93 """Make test isolated star catalogs.
95 Returns
96 -------
97 isolated_star_cat_dict : `dict`
98 Per-"tract" dict of isolated star catalogs.
99 isolate_star_source_dict : `dict`
100 Per-"tract" dict of isolated source catalogs.
101 """
102 dtype_cat = [('isolated_star_id', 'i8'),
103 ('ra', 'f8'),
104 ('decl', 'f8'),
105 ('primary_band', 'U2'),
106 ('source_cat_index', 'i4'),
107 ('nsource', 'i4'),
108 ('source_cat_index_i', 'i4'),
109 ('nsource_i', 'i4'),
110 ('source_cat_index_r', 'i4'),
111 ('nsource_r', 'i4')]
113 dtype_source = [('sourceId', 'i8'),
114 ('obj_index', 'i4')]
116 isolated_star_cat_dict = {}
117 isolated_star_source_dict = {}
119 np.random.seed(12345)
121 # There are 90 stars in both r, i. 10 individually in each.
122 nstar = 110
123 nsource_per_band_per_star = 2
124 self.nstar_total = nstar
125 self.nstar_per_band = nstar - 10
127 # This is a brute-force assembly of a star catalog and matched sources.
128 for tract in [0, 1]:
129 ra = np.random.uniform(low=tract, high=tract + 1.0, size=nstar)
130 dec = np.random.uniform(low=0.0, high=1.0, size=nstar)
132 cat = np.zeros(nstar, dtype=dtype_cat)
133 cat['isolated_star_id'] = tract*nstar + np.arange(nstar)
134 cat['ra'] = ra
135 cat['decl'] = dec
136 cat['primary_band'][0: 100] = 'i'
137 cat['primary_band'][100:] = 'r'
139 source_cats = []
140 counter = 0
141 for i in range(cat.size):
142 cat['source_cat_index'][i] = counter
143 if i < 90:
144 cat['nsource'][i] = 2*nsource_per_band_per_star
145 bands = ['r', 'i']
146 else:
147 cat['nsource'][i] = nsource_per_band_per_star
148 if i < 100:
149 bands = ['i']
150 else:
151 bands = ['r']
153 for band in bands:
154 cat[f'source_cat_index_{band}'][i] = counter
155 cat[f'nsource_{band}'][i] = nsource_per_band_per_star
156 source_cat = np.zeros(nsource_per_band_per_star, dtype=dtype_source)
157 source_cat['sourceId'] = np.arange(
158 tract*nstar + counter,
159 tract*nstar + counter + nsource_per_band_per_star
160 )
161 source_cat['obj_index'] = i
163 source_cats.append(source_cat)
165 counter += nsource_per_band_per_star
167 source_cat = np.concatenate(source_cats)
169 isolated_star_cat_dict[tract] = MockDataFrameReference(pd.DataFrame(cat))
170 isolated_star_source_dict[tract] = MockDataFrameReference(pd.DataFrame(source_cat))
172 return isolated_star_cat_dict, isolated_star_source_dict
174 def test_concat_isolated_star_cats(self):
175 """Test concatenation and reservation of the isolated star catalogs.
176 """
178 for band in ['r', 'i']:
179 iso, iso_src = self.finalizeCharacterizationTask.concat_isolated_star_cats(
180 band,
181 self.isolated_star_cat_dict,
182 self.isolated_star_source_dict
183 )
185 # There are two tracts, so double everything.
186 self.assertEqual(len(iso), 2*self.nstar_per_band)
188 reserve_fraction = self.finalizeCharacterizationTask.config.reserve_selection.reserve_fraction
189 self.assertEqual(np.sum(iso['reserved']),
190 int(reserve_fraction*len(iso)))
192 # 2 tracts, 4 observations per tract per star, minus 2*10 not in the given band.
193 self.assertEqual(len(iso_src), 2*(4*len(iso)//2 - 20))
195 # Check that every star is properly matched to the sources.
196 for i in range(len(iso)):
197 np.testing.assert_array_equal(
198 iso_src['obj_index'][iso[f'source_cat_index_{band}'][i]:
199 iso[f'source_cat_index_{band}'][i] + iso[f'nsource_{band}'][i]],
200 i
201 )
203 # Check that every reserved star is marked as a reserved source.
204 res_star, = np.where(iso['reserved'])
205 for i in res_star:
206 np.testing.assert_array_equal(
207 iso_src['reserved'][iso[f'source_cat_index_{band}'][i]:
208 iso[f'source_cat_index_{band}'][i] + iso[f'nsource_{band}'][i]],
209 True
210 )
212 # Check that every reserved source is marked as a reserved star.
213 res_src, = np.where(iso_src['reserved'])
214 np.testing.assert_array_equal(
215 iso['reserved'][iso_src['obj_index'][res_src]],
216 True
217 )
220class MyMemoryTestCase(lsst.utils.tests.MemoryTestCase):
221 pass
224def setup_module(module):
225 lsst.utils.tests.init()
228if __name__ == "__main__": 228 ↛ 229line 228 didn't jump to line 229, because the condition on line 228 was never true
229 lsst.utils.tests.init()
230 unittest.main()