66 def run(self, diaSources, tractPatchId=None, skymapBits=None, idGenerator=None):
67 """Associate DiaSources into a collection of DiaObjects using a
68 brute force matching algorithm.
70 Reproducible is for the same input data is assured by ordering the
71 DiaSource data by ccdVisit ordering.
75 diaSources : `pandas.DataFrame`
76 DiaSources grouped by CcdVisitId to spatially associate into
78 tractPatchId : `int`, optional
79 Unique identifier for the tract patch. Deprecated in favor of
80 ``idGenerator`` along with `lsst.obs.base.ExposureIdInfo`.
82 Maximum number of bits used the ``tractPatchId`` integer
83 identifier. Deprecated in favor of ``idGenerator`` along with
84 `lsst.obs.base.ExposureIdInfo`.
85 idGenerator : `lsst.meas.base.IdGenerator`, optional
86 Object that generates Object IDs and random number generator seeds.
90 results : `lsst.pipe.base.Struct`
91 Results struct with attributes:
94 Table of DiaSources with updated values for the DiaObjects
95 they are spatially associated to (`pandas.DataFrame`).
97 Table of DiaObjects from matching DiaSources
104 doDropIndex = diaSources.index.names[0]
is None
105 diaSources.reset_index(inplace=
True, drop=doDropIndex)
109 diaSources.set_index([
"ccdVisitId",
"diaSourceId"], inplace=
True)
117 if idGenerator
is None:
118 if tractPatchId
is not None and skymapBits
is not None:
119 exposureIdInfo = ExposureIdInfo(tractPatchId, skymapBits)
120 idGenerator = IdGenerator._from_exposure_id_info(exposureIdInfo)
122 idGenerator = IdGenerator()
123 idCat = idGenerator.make_source_catalog(afwTable.SourceTable.makeMinimalSchema())
125 for ccdVisit
in diaSources.index.levels[0]:
128 ccdVisitSources = diaSources.loc[ccdVisit]
129 if len(diaObjectCat) == 0:
130 for diaSourceId, diaSrc
in ccdVisitSources.iterrows():
141 usedMatchIndicies = []
143 for diaSourceId, diaSrc
in ccdVisitSources.iterrows():
147 2*self.config.tolerance,
150 dists = matchResult.dists
151 matches = matchResult.matches
164 if np.min(dists) < np.deg2rad(self.config.tolerance/3600):
165 matchDistArg = np.argmin(dists)
166 matchIndex = matches[matchDistArg]
168 if np.isin([matchIndex], usedMatchIndicies).sum() < 1:
177 usedMatchIndicies.append(matchIndex)
202 diaSources.reset_index(inplace=
True)
203 diaSources.set_index(
"diaSourceId", inplace=
True, verify_integrity=
True)
205 objs = diaObjectCat
if diaObjectCat
else np.array([], dtype=[(
'diaObjectId',
'int64'),
208 (
'nDiaSources',
'int64')])
209 diaObjects = pd.DataFrame(data=objs)
211 if "diaObjectId" in diaObjects.columns:
212 diaObjects.set_index(
"diaObjectId", inplace=
True, verify_integrity=
True)
214 return pipeBase.Struct(
215 assocDiaSources=diaSources,
216 diaObjects=diaObjects)
227 """Create a new DiaObject and append its data.
231 diaSrc : `pandas.Series`
232 Full unassociated DiaSource to create a DiaObject from.
233 diaSources : `pandas.DataFrame`
234 DiaSource catalog to update information in. The catalog is
237 Unique identifier of the ccdVisit where ``diaSrc`` was observed.
239 Unique identifier of the DiaSource.
240 diaObjectCat : `list` of `dict`s
241 Catalog of diaObjects to append the new object o.
242 idCat : `lsst.afw.table.SourceCatalog`
243 Catalog with the IdFactory used to generate unique DiaObject
245 diaObjectCoords : `list` of `list`s of `lsst.geom.SpherePoint`s
246 Set of coordinates of DiaSource locations that make up the
247 DiaObject average coordinate.
248 healPixIndices : `list` of `int`s
249 HealPix indices representing the locations of each currently
252 hpIndex = toIndex(self.config.nside,
255 healPixIndices.append(hpIndex)
260 diaObjCoords.append([sphPoint])
262 diaObjId = idCat.addNew().get(
"id")
266 diaSources.loc[(ccdVisit, diaSourceId),
"diaObjectId"] = diaObjId
277 """Update DiaObject and DiaSource values after an association.
282 Array index location of the DiaObject that ``diaSrc`` was
284 diaSrc : `pandas.Series`
285 Full unassociated DiaSource to create a DiaObject from.
286 diaSources : `pandas.DataFrame`
287 DiaSource catalog to update information in. The catalog is
290 Unique identifier of the ccdVisit where ``diaSrc`` was observed.
292 Unique identifier of the DiaSource.
293 diaObjectCat : `list` of `dict`s
294 Catalog of diaObjects to append the new object o.
295 diaObjectCoords : `list` of `list`s of `lsst.geom.SpherePoint`s
296 Set of coordinates of DiaSource locations that make up the
297 DiaObject average coordinate.
298 healPixIndices : `list` of `int`s
299 HealPix indices representing the locations of each currently
306 diaObjCoords[matchIndex].append(sphPoint)
307 aveCoord = geom.averageSpherePoint(diaObjCoords[matchIndex])
308 diaObjCat[matchIndex][
"ra"] = aveCoord.getRa().asDegrees()
309 diaObjCat[matchIndex][
"dec"] = aveCoord.getDec().asDegrees()
310 nSources = diaObjCat[matchIndex][
"nDiaSources"]
311 diaObjCat[matchIndex][
"nDiaSources"] = nSources + 1
312 healPixIndices[matchIndex] = toIndex(self.config.nside,
313 diaObjCat[matchIndex][
"ra"],
314 diaObjCat[matchIndex][
"dec"])
316 diaSources.loc[(ccdVisit, diaSourceId),
"diaObjectId"] = \
317 diaObjCat[matchIndex][
"diaObjectId"]
320 """Search healPixels around DiaSource locations for DiaObjects.
325 DiaSource RA location.
327 DiaSource Dec location.
329 Size of annulus to convert to covering healPixels and search for
331 hpIndices : `list` of `int`s
332 List of heal pix indices containing the DiaObjects in ``diaObjs``.
333 diaObjs : `list` of `dict`s
334 Catalog diaObjects to with full location information for comparing
339 results : `lsst.pipe.base.Struct`
340 Results struct containing
343 Array of distances between the current DiaSource diaObjects.
344 (`numpy.ndarray` or `None`)
346 Array of array indices of diaObjects this DiaSource matches to.
347 (`numpy.ndarray` or `None`)
349 match_indices = query_disc(self.config.nside,
352 np.deg2rad(tol/3600.))
353 matchIndices = np.argwhere(np.isin(hpIndices, match_indices)).flatten()
355 if len(matchIndices) < 1:
356 return pipeBase.Struct(dists=
None, matches=
None)
359 [np.sqrt(np.sum((eq2xyz(src_ra, src_dec)
360 - eq2xyz(diaObjs[match][
"ra"],
361 diaObjs[match][
"dec"]))**2))
362 for match
in matchIndices])
363 return pipeBase.Struct(
365 matches=matchIndices)