Coverage for tests/test_transformObject.py: 20%
81 statements
« prev ^ index » next coverage.py v7.3.1, created at 2023-09-11 10:41 +0000
« prev ^ index » next coverage.py v7.3.1, created at 2023-09-11 10:41 +0000
1# This file is part of pipe_tasks.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://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 <http://www.gnu.org/licenses/>.
22import os
23import unittest
24import pandas as pd
25import numpy as np
27import lsst.utils.tests
29from lsst.pipe.base import InMemoryDatasetHandle
30from lsst.pipe.tasks.functors import HsmFwhm, Column
31from lsst.pipe.tasks.postprocess import TransformObjectCatalogTask, TransformObjectCatalogConfig
33ROOT = os.path.abspath(os.path.dirname(__file__))
36def setup_module(module):
37 lsst.utils.tests.init()
40class TransformObjectCatalogTestCase(unittest.TestCase):
41 def setUp(self):
42 # Note that this test input includes HSC-G, HSC-R, and HSC-I data
43 df = pd.read_csv(os.path.join(ROOT, 'data', 'test_multilevel_parq.csv.gz'),
44 header=[0, 1, 2], index_col=0)
46 self.dataId = {"tract": 9615, "patch": "4,4"}
47 self.handle = InMemoryDatasetHandle(df, storageClass="DataFrame", dataId=self.dataId)
49 def testNullFilter(self):
50 """Test that columns for all filters are created despite they may not
51 exist in the input data.
52 """
53 config = TransformObjectCatalogConfig()
54 config.camelCase = True
55 # Want y band columns despite the input data do not have them
56 # Exclude g band columns despite the input data have them
57 config.outputBands = ["r", "i", "y"]
58 # Arbitrarily choose a boolean flag column to be "good"
59 config.goodFlags = ['GoodFlagColumn']
60 task = TransformObjectCatalogTask(config=config)
61 # Add in a float column, an integer column, a good flag, and
62 # a bad flag. It does not matter which columns we choose, just
63 # that they have the appropriate type.
64 funcs = {'FloatColumn': HsmFwhm(dataset='meas'),
65 'IntColumn': Column('base_InputCount_value', dataset='meas'),
66 'GoodFlagColumn': Column('slot_GaussianFlux_flag', dataset='meas'),
67 'BadFlagColumn': Column('slot_Centroid_flag', dataset='meas')}
68 df = task.run(self.handle, funcs=funcs, dataId=self.dataId)
69 self.assertIsInstance(df, pd.DataFrame)
71 for filt in config.outputBands:
72 self.assertIn(filt + 'FloatColumn', df.columns)
73 self.assertIn(filt + 'IntColumn', df.columns)
74 self.assertIn(filt + 'BadFlagColumn', df.columns)
75 self.assertIn(filt + 'GoodFlagColumn', df.columns)
77 # Check that the default filling has worked.
78 self.assertNotIn('gFloatColumn', df.columns)
79 self.assertTrue(df['yFloatColumn'].isnull().all())
80 self.assertTrue(df['iFloatColumn'].notnull().all())
81 self.assertTrue(np.all(df['iIntColumn'].values >= 0))
82 self.assertTrue(np.all(df['yIntColumn'].values < 0))
83 self.assertTrue(np.all(~df['yGoodFlagColumn'].values))
84 self.assertTrue(np.all(df['yBadFlagColumn'].values))
86 # Check that the datatypes are preserved.
87 self.assertEqual(df['iFloatColumn'].dtype, np.dtype(np.float64))
88 self.assertEqual(df['yFloatColumn'].dtype, np.dtype(np.float64))
89 self.assertEqual(df['iIntColumn'].dtype, np.dtype(np.int64))
90 self.assertEqual(df['yIntColumn'].dtype, np.dtype(np.int64))
91 self.assertEqual(df['iGoodFlagColumn'].dtype, np.dtype(np.bool_))
92 self.assertEqual(df['yGoodFlagColumn'].dtype, np.dtype(np.bool_))
93 self.assertEqual(df['iBadFlagColumn'].dtype, np.dtype(np.bool_))
94 self.assertEqual(df['yBadFlagColumn'].dtype, np.dtype(np.bool_))
96 def testUnderscoreColumnFormat(self):
97 """Test the per-filter column format with an underscore"""
98 config = TransformObjectCatalogConfig()
99 config.outputBands = ["g", "r", "i"]
100 config.camelCase = False
101 task = TransformObjectCatalogTask(config=config)
102 funcs = {'Fwhm': HsmFwhm(dataset='meas')}
103 df = task.run(self.handle, funcs=funcs, dataId=self.dataId)
104 self.assertIsInstance(df, pd.DataFrame)
105 for filt in config.outputBands:
106 self.assertIn(filt + '_Fwhm', df.columns)
108 def testMultilevelOutput(self):
109 """Test the non-flattened result dataframe with a multilevel column index"""
110 config = TransformObjectCatalogConfig()
111 config.outputBands = ["r", "i"]
112 config.multilevelOutput = True
113 task = TransformObjectCatalogTask(config=config)
114 funcs = {'Fwhm': HsmFwhm(dataset='meas')}
115 df = task.run(self.handle, funcs=funcs, dataId=self.dataId)
116 self.assertIsInstance(df, pd.DataFrame)
117 self.assertNotIn('g', df)
118 for filt in config.outputBands:
119 self.assertIsInstance(df[filt], pd.DataFrame)
120 self.assertIn('Fwhm', df[filt].columns)
122 def testNoOutputBands(self):
123 """All the input bands should go into the output, and nothing else.
124 """
125 config = TransformObjectCatalogConfig()
126 config.multilevelOutput = True
127 task = TransformObjectCatalogTask(config=config)
128 funcs = {'Fwhm': HsmFwhm(dataset='meas')}
129 df = task.run(self.handle, funcs=funcs, dataId=self.dataId)
130 self.assertIsInstance(df, pd.DataFrame)
131 self.assertNotIn('HSC-G', df)
132 for filt in ['g', 'r', 'i']:
133 self.assertIsInstance(df[filt], pd.DataFrame)
134 self.assertIn('Fwhm', df[filt].columns)
137if __name__ == "__main__": 137 ↛ 138line 137 didn't jump to line 138, because the condition on line 137 was never true
138 lsst.utils.tests.init()
139 unittest.main()