LSST Applications g0f08755f38+82efc23009,g12f32b3c4e+e7bdf1200e,g1653933729+a8ce1bb630,g1a0ca8cf93+50eff2b06f,g28da252d5a+52db39f6a5,g2bbee38e9b+37c5a29d61,g2bc492864f+37c5a29d61,g2cdde0e794+c05ff076ad,g3156d2b45e+41e33cbcdc,g347aa1857d+37c5a29d61,g35bb328faa+a8ce1bb630,g3a166c0a6a+37c5a29d61,g3e281a1b8c+fb992f5633,g414038480c+7f03dfc1b0,g41af890bb2+11b950c980,g5fbc88fb19+17cd334064,g6b1c1869cb+12dd639c9a,g781aacb6e4+a8ce1bb630,g80478fca09+72e9651da0,g82479be7b0+04c31367b4,g858d7b2824+82efc23009,g9125e01d80+a8ce1bb630,g9726552aa6+8047e3811d,ga5288a1d22+e532dc0a0b,gae0086650b+a8ce1bb630,gb58c049af0+d64f4d3760,gc28159a63d+37c5a29d61,gcf0d15dbbd+2acd6d4d48,gd7358e8bfb+778a810b6e,gda3e153d99+82efc23009,gda6a2b7d83+2acd6d4d48,gdaeeff99f8+1711a396fd,ge2409df99d+6b12de1076,ge79ae78c31+37c5a29d61,gf0baf85859+d0a5978c5a,gf3967379c6+4954f8c433,gfb92a5be7c+82efc23009,gfec2e1e490+2aaed99252,w.2024.46
LSST Data Management Base Package
Loading...
Searching...
No Matches
data_factory.py
Go to the documentation of this file.
1# This file is part of dax_apdb.
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/>.
21
22from __future__ import annotations
23
24import datetime
25import random
26from collections.abc import Iterator
27from typing import Any
28
29import astropy.time
30import numpy
31import pandas
32from lsst.sphgeom import LonLat, Region, UnitVector3d
33
34
35def _genPointsInRegion(region: Region, count: int) -> Iterator[LonLat]:
36 """Generate bunch of SpherePoints inside given region.
37
38 Parameters
39 ----------
40 region : `lsst.sphgeom.Region`
41 Spherical region.
42 count : `int`
43 Number of points to generate.
44
45 Notes
46 -----
47 Returned points are random but not necessarily uniformly distributed.
48 """
49 bbox = region.getBoundingBox()
50 center = bbox.getCenter()
51 center_lon = center.getLon().asRadians()
52 center_lat = center.getLat().asRadians()
53 width = bbox.getWidth().asRadians()
54 height = bbox.getHeight().asRadians()
55 while count > 0:
56 lon = random.uniform(center_lon - width / 2, center_lon + width / 2)
57 lat = random.uniform(center_lat - height / 2, center_lat + height / 2)
58 lonlat = LonLat.fromRadians(lon, lat)
59 uv3d = UnitVector3d(lonlat)
60 if region.contains(uv3d):
61 yield lonlat
62 count -= 1
63
64
66 region: Region | LonLat, count: int, visit_time: astropy.time.Time, *, start_id: int = 1, **kwargs: Any
67) -> pandas.DataFrame:
68 """Make a catalog containing a bunch of DiaObjects inside a region.
69
70 Parameters
71 ----------
72 region : `lsst.sphgeom.Region` or `lsst.sphgeom.LonLat`
73 Spherical region or spherical coordinate.
74 count : `int`
75 Number of records to generate.
76 visit_time : `astropy.time.Time`
77 Time of the visit.
78 start_id : `int`
79 Starting diaObjectId.
80 **kwargs : `Any`
81 Additional columns and their values to add to catalog.
82
83 Returns
84 -------
85 catalog : `pandas.DataFrame`
86 Catalog of DiaObjects records.
87
88 Notes
89 -----
90 Returned catalog only contains three columns - ``diaObjectId`, ``ra``, and
91 ``dec`` (in degrees).
92 """
93 if isinstance(region, Region):
94 points = list(_genPointsInRegion(region, count))
95 else:
96 points = [region] * count
97 # diaObjectId=0 may be used in some code for DiaSource foreign key to mean
98 # the same as ``None``.
99 ids = numpy.arange(start_id, len(points) + start_id, dtype=numpy.int64)
100 ras = numpy.array([lonlat.getLon().asDegrees() for lonlat in points], dtype=numpy.float64)
101 decs = numpy.array([lonlat.getLat().asDegrees() for lonlat in points], dtype=numpy.float64)
102 nDiaSources = numpy.ones(len(points), dtype=numpy.int32)
103 dt = visit_time.datetime
104 data = dict(
105 kwargs,
106 diaObjectId=ids,
107 ra=ras,
108 dec=decs,
109 nDiaSources=nDiaSources,
110 lastNonForcedSource=dt,
111 )
112 df = pandas.DataFrame(data)
113 return df
114
115
117 objects: pandas.DataFrame,
118 visit_time: astropy.time.Time,
119 start_id: int = 0,
120 visit: int = 1,
121 detector: int = 1,
122) -> pandas.DataFrame:
123 """Make a catalog containing a bunch of DiaSources associated with the
124 input DiaObjects.
125
126 Parameters
127 ----------
128 objects : `pandas.DataFrame`
129 Catalog of DiaObject records.
130 visit_time : `astropy.time.Time`
131 Time of the visit.
132 start_id : `int`
133 Starting value for ``diaObjectId``.
134 visit, detector : `int`
135 Value for ``visit`` and ``detector`` fields.
136
137 Returns
138 -------
139 catalog : `pandas.DataFrame`
140 Catalog of DiaSource records.
141
142 Notes
143 -----
144 Returned catalog only contains small number of columns needed for tests.
145 """
146 nrows = len(objects)
147 midpointMjdTai = visit_time.mjd
148 # TODO: Note that for now we use naive datetime for time_processed, to have
149 # it consistent with ap_association, will need to update once we migrate
150 # to aware times everywhere.
151 time_processed = datetime.datetime.now()
152 df = pandas.DataFrame(
153 {
154 "diaSourceId": numpy.arange(start_id, start_id + nrows, dtype=numpy.int64),
155 "diaObjectId": objects["diaObjectId"],
156 "visit": numpy.full(nrows, visit, dtype=numpy.int64),
157 "detector": numpy.full(nrows, detector, dtype=numpy.int16),
158 "parentDiaSourceId": 0,
159 "ra": objects["ra"],
160 "dec": objects["dec"],
161 "midpointMjdTai": numpy.full(nrows, midpointMjdTai, dtype=numpy.float64),
162 "flags": numpy.full(nrows, 0, dtype=numpy.int64),
163 "ssObjectId": None,
164 "time_processed": time_processed,
165 }
166 )
167 return df
168
169
171 objects: pandas.DataFrame, visit_time: astropy.time.Time, visit: int = 1, detector: int = 1
172) -> pandas.DataFrame:
173 """Make a catalog containing a bunch of DiaForcedSources associated with
174 the input DiaObjects.
175
176 Parameters
177 ----------
178 objects : `pandas.DataFrame`
179 Catalog of DiaObject records.
180 visit_time : `astropy.time.Time`
181 Time of the visit.
182 visit, detector : `int`
183 Value for ``visit`` and ``detector`` fields.
184
185 Returns
186 -------
187 catalog : `pandas.DataFrame`
188 Catalog of DiaForcedSource records.
189
190 Notes
191 -----
192 Returned catalog only contains small number of columns needed for tests.
193 """
194 nrows = len(objects)
195 midpointMjdTai = visit_time.mjd
196 # TODO: Note that for now we use naive datetime for time_processed, to have
197 # it consistent with ap_association, will need to update once we migrate
198 # to aware times everywhere.
199 time_processed = datetime.datetime.now()
200 df = pandas.DataFrame(
201 {
202 "diaObjectId": objects["diaObjectId"],
203 "visit": numpy.full(nrows, visit, dtype=numpy.int64),
204 "detector": numpy.full(nrows, detector, dtype=numpy.int16),
205 "ra": objects["ra"],
206 "dec": objects["dec"],
207 "midpointMjdTai": numpy.full(nrows, midpointMjdTai, dtype=numpy.float64),
208 "flags": numpy.full(nrows, 0, dtype=numpy.int64),
209 "time_processed": time_processed,
210 }
211 )
212 return df
213
214
215def makeSSObjectCatalog(count: int, start_id: int = 1, flags: int = 0) -> pandas.DataFrame:
216 """Make a catalog containing a bunch of SSObjects.
217
218 Parameters
219 ----------
220 count : `int`
221 Number of records to generate.
222 startID : `int`
223 Initial SSObject ID.
224 flags : `int`
225 Value for ``flags`` column.
226
227 Returns
228 -------
229 catalog : `pandas.DataFrame`
230 Catalog of SSObjects records.
231
232 Notes
233 -----
234 Returned catalog only contains three columns - ``ssObjectId`, ``arc``,
235 and ``flags``.
236 """
237 ids = numpy.arange(start_id, count + start_id, dtype=numpy.int64)
238 arc = numpy.full(count, 0.001, dtype=numpy.float32)
239 flags_array = numpy.full(count, flags, dtype=numpy.int64)
240 df = pandas.DataFrame({"ssObjectId": ids, "arc": arc, "flags": flags_array})
241 return df
UnitVector3d is a unit vector in ℝ³ with components stored in double precision.
pandas.DataFrame makeSourceCatalog(pandas.DataFrame objects, astropy.time.Time visit_time, int start_id=0, int visit=1, int detector=1)
pandas.DataFrame makeObjectCatalog(Region|LonLat region, int count, astropy.time.Time visit_time, *int start_id=1, **Any kwargs)
Iterator[LonLat] _genPointsInRegion(Region region, int count)
pandas.DataFrame makeSSObjectCatalog(int count, int start_id=1, int flags=0)
pandas.DataFrame makeForcedSourceCatalog(pandas.DataFrame objects, astropy.time.Time visit_time, int visit=1, int detector=1)