LSST Applications g00d0e8bbd7+edbf708997,g199a45376c+5137f08352,g1fd858c14a+48cd4dd530,g228ff663f5+2051e4e242,g262e1987ae+9c6f24d2e3,g29ae962dfc+03663621e0,g2cef7863aa+73c82f25e4,g35bb328faa+edbf708997,g3fd5ace14f+8c4d25a1ce,g47891489e3+27ba970c8a,g53246c7159+edbf708997,g5b326b94bb+db962c32ee,g64539dfbff+d237af7fd9,g67b6fd64d1+27ba970c8a,g74acd417e5+8234f56c0c,g786e29fd12+af89c03590,g87389fa792+a4172ec7da,g88cb488625+6878ed1c5e,g89139ef638+27ba970c8a,g8d7436a09f+f76ea57dde,g8ea07a8fe4+79658f16ab,g90f42f885a+6577634e1f,g97be763408+494f77a6c4,g98df359435+1750ea0126,g9b50b81019+d8f85438e7,ga2180abaac+edbf708997,ga9e74d7ce9+128cc68277,gad4c79568f+321c5e11c3,gbf99507273+edbf708997,gc2a301910b+d237af7fd9,gca7fc764a6+27ba970c8a,gcedae5159b+afaec0eb3d,gd7ef33dd92+27ba970c8a,gdab6d2f7ff+8234f56c0c,gdbb4c4dda9+d237af7fd9,ge410e46f29+27ba970c8a,ge41e95a9f2+d237af7fd9,geaed405ab2+062dfc8cdc,w.2025.45
LSST Data Management Base Package
Loading...
Searching...
No Matches
lsst.pipe.tasks.diff_matched_tract_catalog.DiffMatchedTractCatalogTask Class Reference
Inheritance diagram for lsst.pipe.tasks.diff_matched_tract_catalog.DiffMatchedTractCatalogTask:

Public Member Functions

 runQuantum (self, butlerQC, inputRefs, outputRefs)
 
pipeBase.Struct run (self, astropy.table.Table catalog_ref, astropy.table.Table catalog_target, astropy.table.Table catalog_match_ref, astropy.table.Table catalog_match_target, afwGeom.SkyWcs wcs=None)
 

Static Public Attributes

 ConfigClass = DiffMatchedTractCatalogConfig
 

Static Protected Attributes

str _DefaultName = "DiffMatchedTractCatalog"
 

Detailed Description

Load subsets of matched catalogs and output a merged catalog of matched sources.

Definition at line 312 of file diff_matched_tract_catalog.py.

Member Function Documentation

◆ run()

pipeBase.Struct lsst.pipe.tasks.diff_matched_tract_catalog.DiffMatchedTractCatalogTask.run ( self,
astropy.table.Table catalog_ref,
astropy.table.Table catalog_target,
astropy.table.Table catalog_match_ref,
astropy.table.Table catalog_match_target,
afwGeom.SkyWcs wcs = None )
Load matched reference and target (measured) catalogs, measure summary statistics, and output
a combined matched catalog with columns from both inputs.

Parameters
----------
catalog_ref : `astropy.table.Table`
    A reference catalog to diff objects/sources from.
catalog_target : `astropy.table.Table`
    A target catalog to diff reference objects/sources to.
catalog_match_ref : `astropy.table.Table`
    A catalog with match indices of target sources and selection flags
    for each reference source.
catalog_match_target : `astropy.table.Table`
    A catalog with selection flags for each target source.
wcs : `lsst.afw.image.SkyWcs`
    A coordinate system to convert catalog positions to sky coordinates,
    if necessary.

Returns
-------
retStruct : `lsst.pipe.base.Struct`
    A struct with output_ref and output_target attribute containing the
    output matched catalogs.

Definition at line 341 of file diff_matched_tract_catalog.py.

348 ) -> pipeBase.Struct:
349 """Load matched reference and target (measured) catalogs, measure summary statistics, and output
350 a combined matched catalog with columns from both inputs.
351
352 Parameters
353 ----------
354 catalog_ref : `astropy.table.Table`
355 A reference catalog to diff objects/sources from.
356 catalog_target : `astropy.table.Table`
357 A target catalog to diff reference objects/sources to.
358 catalog_match_ref : `astropy.table.Table`
359 A catalog with match indices of target sources and selection flags
360 for each reference source.
361 catalog_match_target : `astropy.table.Table`
362 A catalog with selection flags for each target source.
363 wcs : `lsst.afw.image.SkyWcs`
364 A coordinate system to convert catalog positions to sky coordinates,
365 if necessary.
366
367 Returns
368 -------
369 retStruct : `lsst.pipe.base.Struct`
370 A struct with output_ref and output_target attribute containing the
371 output matched catalogs.
372 """
373 # Would be nice if this could refer directly to ConfigClass
374 config: DiffMatchedTractCatalogConfig = self.config
375
376 # Strip any provenance from tables before merging to prevent
377 # warnings from conflicts being issued by astropy.utils.merge during
378 # vstack or hstack calls.
379 DatasetProvenance.strip_provenance_from_flat_dict(catalog_ref.meta)
380 DatasetProvenance.strip_provenance_from_flat_dict(catalog_target.meta)
381 DatasetProvenance.strip_provenance_from_flat_dict(catalog_match_ref.meta)
382 DatasetProvenance.strip_provenance_from_flat_dict(catalog_match_target.meta)
383
384 # It would be nice to make this a Selector but those are
385 # only available in analysis_tools for now
386 select_ref, select_target = (
387 (catalog[column] if column else np.ones(len(catalog), dtype=bool))
388 for catalog, column in (
389 (catalog_match_ref, self.config.column_match_candidate_ref),
390 (catalog_match_target, self.config.column_match_candidate_target),
391 )
392 )
393 # Add additional selection criteria for target sources beyond those for matching
394 # (not recommended, but can be done anyway)
395 for column in config.columns_target_select_true:
396 select_target &= catalog_target[column]
397 for column in config.columns_target_select_false:
398 select_target &= ~catalog_target[column]
399
400 ref, target = config.coord_format.format_catalogs(
401 catalog_ref=catalog_ref, catalog_target=catalog_target,
402 select_ref=None, select_target=select_target, wcs=wcs, radec_to_xy_func=radec_to_xy,
403 )
404 cat_ref = ref.catalog
405 cat_target = target.catalog
406 n_target = len(cat_target)
407
408 if not config.filter_on_match_candidate:
409 for cat_add, cat_match, column in (
410 (cat_ref, catalog_match_ref, config.column_match_candidate_ref),
411 (cat_target, catalog_match_target, config.column_match_candidate_target),
412 ):
413 if column is not None:
414 cat_add[column] = cat_match[column]
415
416 match_row = catalog_match_ref['match_row']
417 matched_ref = match_row >= 0
418 matched_row = match_row[matched_ref]
419 matched_target = np.zeros(n_target, dtype=bool)
420 matched_target[matched_row] = True
421
422 # Add/compute distance columns
423 coord1_target_err, coord2_target_err = config.columns_target_coord_err
424 column_dist, column_dist_err = 'match_distance', 'match_distanceErr'
425 dist = np.full(n_target, np.nan)
426
427 target_match_c1, target_match_c2 = (coord[matched_row] for coord in (target.coord1, target.coord2))
428 target_ref_c1, target_ref_c2 = (coord[matched_ref] for coord in (ref.coord1, ref.coord2))
429
430 dist_err = np.full(n_target, np.nan)
431 dist[matched_row] = sphdist(
432 target_match_c1, target_match_c2, target_ref_c1, target_ref_c2
433 ) if config.coord_format.coords_spherical else np.hypot(
434 target_match_c1 - target_ref_c1, target_match_c2 - target_ref_c2,
435 )
436 cat_target_matched = cat_target[matched_row]
437 # This will convert a masked array to an array filled with nans
438 # wherever there are bad values (otherwise sphdist can raise)
439 c1_err, c2_err = (
440 np.ma.getdata(cat_target_matched[c_err]) for c_err in (coord1_target_err, coord2_target_err)
441 )
442 # Should probably explicitly add cosine terms if ref has errors too
443 dist_err[matched_row] = sphdist(
444 target_match_c1, target_match_c2, target_match_c1 + c1_err, target_match_c2 + c2_err
445 ) if config.coord_format.coords_spherical else np.hypot(c1_err, c2_err)
446 cat_target[column_dist], cat_target[column_dist_err] = dist, dist_err
447
448 # Create a matched table, preserving the target catalog's named index (if it has one)
449 cat_left = cat_target[matched_row]
450 cat_right = cat_ref[matched_ref]
451 if config.column_matched_prefix_target:
452 cat_left.rename_columns(
453 list(cat_left.columns),
454 new_names=[f'{config.column_matched_prefix_target}{col}' for col in cat_left.columns],
455 )
456 if config.column_matched_prefix_ref:
457 cat_right.rename_columns(
458 list(cat_right.columns),
459 new_names=[f'{config.column_matched_prefix_ref}{col}' for col in cat_right.columns],
460 )
461 cat_matched = astropy.table.hstack((cat_left, cat_right))
462
463 if config.include_unmatched:
464 # Create an unmatched table with the same schema as the matched one
465 # ... but only for objects with no matches (for completeness/purity)
466 # and that were selected for matching (or inclusion via config)
467 cat_right = astropy.table.Table(
468 cat_ref[~matched_ref & select_ref]
469 )
470 cat_right.rename_columns(
471 cat_right.colnames,
472 [f"{config.column_matched_prefix_ref}{col}" for col in cat_right.colnames],
473 )
474 match_row_target = catalog_match_target['match_row']
475 cat_left = cat_target[~(match_row_target >= 0) & select_target]
476 cat_left.rename_columns(
477 cat_left.colnames,
478 [f"{config.column_matched_prefix_target}{col}" for col in cat_left.colnames],
479 )
480 # This may be slower than pandas but will, for example, create
481 # masked columns for booleans, which pandas does not support.
482 # See https://github.com/pandas-dev/pandas/issues/46662
483 cat_unmatched = astropy.table.vstack([cat_left, cat_right])
484
485 for columns_convert_base, prefix in (
486 (config.columns_ref_mag_to_nJy, config.column_matched_prefix_ref),
487 (config.columns_target_mag_to_nJy, ""),
488 ):
489 if columns_convert_base:
490 columns_convert = {
491 f"{prefix}{k}": f"{prefix}{v}" for k, v in columns_convert_base.items()
492 } if prefix else columns_convert_base
493 to_convert = [cat_matched]
494 if config.include_unmatched:
495 to_convert.append(cat_unmatched)
496 for cat_convert in to_convert:
497 cat_convert.rename_columns(
498 tuple(columns_convert.keys()),
499 tuple(columns_convert.values()),
500 )
501 for column_flux in columns_convert.values():
502 cat_convert[column_flux] = u.ABmag.to(u.nJy, cat_convert[column_flux])
503
504 if config.include_unmatched:
505 # This is probably less efficient than just doing an outer join originally; worth checking
506 cat_matched = astropy.table.vstack([cat_matched, cat_unmatched])
507 if (prefix_coord := config.prefix_best_coord) is not None:
508 columns_coord_best = (
509 f"{prefix_coord}{col_coord}" for col_coord in (
510 ("ra", "dec") if config.coord_format.coords_spherical else ("coord1", "coord2")
511 )
512 )
513 for column_coord_best, column_coord_ref, column_coord_target in zip(
514 columns_coord_best,
515 (config.coord_format.column_ref_coord1, config.coord_format.column_ref_coord2),
516 (config.coord_format.column_target_coord1, config.coord_format.column_target_coord2),
517 ):
518 column_full_ref = f'{config.column_matched_prefix_ref}{column_coord_ref}'
519 column_full_target = f'{config.column_matched_prefix_target}{column_coord_target}'
520 values = cat_matched[column_full_ref]
521 unit = values.unit
522 values_bad = np.ma.masked_invalid(values).mask
523 # Cast to an unmasked array - there will be no bad values
524 values = np.array(values)
525 values[values_bad] = cat_matched[column_full_target][values_bad]
526 cat_matched[column_coord_best] = values
527 cat_matched[column_coord_best].unit = unit
528 cat_matched[column_coord_best].description = (
529 f"Best {columns_coord_best} value from {column_full_ref} if available"
530 f" else {column_full_target}"
531 )
532
533 retStruct = pipeBase.Struct(cat_matched=cat_matched)
534 return retStruct

◆ runQuantum()

lsst.pipe.tasks.diff_matched_tract_catalog.DiffMatchedTractCatalogTask.runQuantum ( self,
butlerQC,
inputRefs,
outputRefs )

Definition at line 318 of file diff_matched_tract_catalog.py.

318 def runQuantum(self, butlerQC, inputRefs, outputRefs):
319 inputs = butlerQC.get(inputRefs)
320 skymap = inputs.pop("skymap")
321
322 columns_match_ref = ['match_row']
323 if (column := self.config.column_match_candidate_ref) is not None:
324 columns_match_ref.append(column)
325
326 columns_match_target = ['match_row']
327 if (column := self.config.column_match_candidate_target) is not None and (
328 column in inputs['columns_match_target']
329 ):
330 columns_match_target.append(column)
331
332 outputs = self.run(
333 catalog_ref=inputs['cat_ref'].get(parameters={'columns': self.config.columns_in_ref}),
334 catalog_target=inputs['cat_target'].get(parameters={'columns': self.config.columns_in_target}),
335 catalog_match_ref=inputs['cat_match_ref'].get(parameters={'columns': columns_match_ref}),
336 catalog_match_target=inputs['cat_match_target'].get(parameters={'columns': columns_match_target}),
337 wcs=skymap[butlerQC.quantum.dataId["tract"]].wcs,
338 )
339 butlerQC.put(outputs, outputRefs)
340

Member Data Documentation

◆ _DefaultName

str lsst.pipe.tasks.diff_matched_tract_catalog.DiffMatchedTractCatalogTask._DefaultName = "DiffMatchedTractCatalog"
staticprotected

Definition at line 316 of file diff_matched_tract_catalog.py.

◆ ConfigClass

lsst.pipe.tasks.diff_matched_tract_catalog.DiffMatchedTractCatalogTask.ConfigClass = DiffMatchedTractCatalogConfig
static

Definition at line 315 of file diff_matched_tract_catalog.py.


The documentation for this class was generated from the following file: