Coverage for tests/test_finalizeCharacterization.py: 18%
88 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-16 08:24 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-16 08:24 +0000
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.pipe.base as pipeBase
31from lsst.pipe.tasks.finalizeCharacterization import (FinalizeCharacterizationConfig,
32 FinalizeCharacterizationTask)
35class TestFinalizeCharacterizationTask(FinalizeCharacterizationTask):
36 """A derived class which skips the initialization routines.
37 """
38 __test__ = False # Stop Pytest from trying to parse as a TestCase
40 def __init__(self, **kwargs):
41 pipeBase.PipelineTask.__init__(self, **kwargs)
43 self.makeSubtask('reserve_selection')
46class FinalizeCharacterizationTestCase(lsst.utils.tests.TestCase):
47 """Tests of some functionality of FinalizeCharacterizationTask.
49 Full testing comes from integration tests such as ci_hsc and ci_imsim.
51 These tests bypass the middleware used for accessing data and
52 managing Task execution.
53 """
54 def setUp(self):
55 config = FinalizeCharacterizationConfig()
57 self.finalizeCharacterizationTask = TestFinalizeCharacterizationTask(
58 config=config,
59 )
61 self.isolated_star_cat_dict, self.isolated_star_source_dict = self._make_isocats()
63 def _make_isocats(self):
64 """Make test isolated star catalogs.
66 Returns
67 -------
68 isolated_star_cat_dict : `dict`
69 Per-"tract" dict of isolated star catalogs.
70 isolate_star_source_dict : `dict`
71 Per-"tract" dict of isolated source catalogs.
72 """
73 dtype_cat = [('isolated_star_id', 'i8'),
74 ('ra', 'f8'),
75 ('dec', 'f8'),
76 ('primary_band', 'U2'),
77 ('source_cat_index', 'i4'),
78 ('nsource', 'i4'),
79 ('source_cat_index_i', 'i4'),
80 ('nsource_i', 'i4'),
81 ('source_cat_index_r', 'i4'),
82 ('nsource_r', 'i4'),
83 ('source_cat_index_z', 'i4'),
84 ('nsource_z', 'i4')]
86 dtype_source = [('sourceId', 'i8'),
87 ('obj_index', 'i4')]
89 isolated_star_cat_dict = {}
90 isolated_star_source_dict = {}
92 np.random.seed(12345)
94 # There are 90 stars in both r, i. 10 individually in each.
95 nstar = 110
96 nsource_per_band_per_star = 2
97 self.nstar_total = nstar
98 self.nstar_per_band = nstar - 10
100 # This is a brute-force assembly of a star catalog and matched sources.
101 for tract in [0, 1, 2]:
102 ra = np.random.uniform(low=tract, high=tract + 1.0, size=nstar)
103 dec = np.random.uniform(low=0.0, high=1.0, size=nstar)
105 cat = np.zeros(nstar, dtype=dtype_cat)
106 cat['isolated_star_id'] = tract*nstar + np.arange(nstar)
107 cat['ra'] = ra
108 cat['dec'] = dec
109 if tract < 2:
110 cat['primary_band'][0: 100] = 'i'
111 cat['primary_band'][100:] = 'r'
112 else:
113 # Tract 2 only has z band.
114 cat['primary_band'][:] = 'z'
116 source_cats = []
117 counter = 0
118 for i in range(cat.size):
119 cat['source_cat_index'][i] = counter
120 if tract < 2:
121 if i < 90:
122 cat['nsource'][i] = 2*nsource_per_band_per_star
123 bands = ['r', 'i']
124 else:
125 cat['nsource'][i] = nsource_per_band_per_star
126 if i < 100:
127 bands = ['i']
128 else:
129 bands = ['r']
130 else:
131 cat['nsource'][i] = nsource_per_band_per_star
132 bands = ['z']
134 for band in bands:
135 cat[f'source_cat_index_{band}'][i] = counter
136 cat[f'nsource_{band}'][i] = nsource_per_band_per_star
137 source_cat = np.zeros(nsource_per_band_per_star, dtype=dtype_source)
138 source_cat['sourceId'] = np.arange(
139 tract*nstar + counter,
140 tract*nstar + counter + nsource_per_band_per_star
141 )
142 source_cat['obj_index'] = i
144 source_cats.append(source_cat)
146 counter += nsource_per_band_per_star
148 source_cat = np.concatenate(source_cats)
150 isolated_star_cat_dict[tract] = pipeBase.InMemoryDatasetHandle(pd.DataFrame(cat),
151 storageClass="DataFrame")
152 isolated_star_source_dict[tract] = pipeBase.InMemoryDatasetHandle(pd.DataFrame(source_cat),
153 storageClass="DataFrame")
155 return isolated_star_cat_dict, isolated_star_source_dict
157 def test_concat_isolated_star_cats(self):
158 """Test concatenation and reservation of the isolated star catalogs.
159 """
161 for band in ['r', 'i']:
162 iso, iso_src = self.finalizeCharacterizationTask.concat_isolated_star_cats(
163 band,
164 self.isolated_star_cat_dict,
165 self.isolated_star_source_dict
166 )
168 # There are two tracts, so double everything.
169 self.assertEqual(len(iso), 2*self.nstar_per_band)
171 reserve_fraction = self.finalizeCharacterizationTask.config.reserve_selection.reserve_fraction
172 self.assertEqual(np.sum(iso['reserved']),
173 int(reserve_fraction*len(iso)))
175 # 2 tracts, 4 observations per tract per star, minus 2*10 not in the given band.
176 self.assertEqual(len(iso_src), 2*(4*len(iso)//2 - 20))
178 # Check that every star is properly matched to the sources.
179 for i in range(len(iso)):
180 np.testing.assert_array_equal(
181 iso_src['obj_index'][iso[f'source_cat_index_{band}'][i]:
182 iso[f'source_cat_index_{band}'][i] + iso[f'nsource_{band}'][i]],
183 i
184 )
186 # Check that every reserved star is marked as a reserved source.
187 res_star, = np.where(iso['reserved'])
188 for i in res_star:
189 np.testing.assert_array_equal(
190 iso_src['reserved'][iso[f'source_cat_index_{band}'][i]:
191 iso[f'source_cat_index_{band}'][i] + iso[f'nsource_{band}'][i]],
192 True
193 )
195 # Check that every reserved source is marked as a reserved star.
196 res_src, = np.where(iso_src['reserved'])
197 np.testing.assert_array_equal(
198 iso['reserved'][iso_src['obj_index'][res_src]],
199 True
200 )
202 def test_concat_isolate_star_cats_no_sources(self):
203 """Test concatenation when there are no sources in a tract."""
204 iso, iso_src = self.finalizeCharacterizationTask.concat_isolated_star_cats(
205 'z',
206 self.isolated_star_cat_dict,
207 self.isolated_star_source_dict
208 )
210 self.assertGreater(len(iso), 0)
213class MyMemoryTestCase(lsst.utils.tests.MemoryTestCase):
214 pass
217def setup_module(module):
218 lsst.utils.tests.init()
221if __name__ == "__main__": 221 ↛ 222line 221 didn't jump to line 222, because the condition on line 221 was never true
222 lsst.utils.tests.init()
223 unittest.main()