22__all__ = [
"init_fromDict",
"Functor",
"CompositeFunctor",
"mag_aware_eval",
23 "CustomFunctor",
"Column",
"Index",
"CoordColumn",
"RAColumn",
24 "DecColumn",
"SinglePrecisionFloatColumn",
"HtmIndex20",
"fluxName",
"fluxErrName",
"Mag",
25 "MagErr",
"MagDiff",
"Color",
"DeconvolvedMoments",
"SdssTraceSize",
26 "PsfSdssTraceSizeDiff",
"HsmTraceSize",
"PsfHsmTraceSizeDiff",
27 "HsmFwhm",
"E1",
"E2",
"RadiusFromQuadrupole",
"LocalWcs",
28 "ComputePixelScale",
"ConvertPixelToArcseconds",
29 "ConvertPixelSqToArcsecondsSq",
30 "ConvertDetectorAngleToPositionAngle",
31 "ConvertDetectorAngleErrToPositionAngleErr",
32 "ReferenceBand",
"Photometry",
33 "NanoJansky",
"NanoJanskyErr",
"LocalPhotometry",
"LocalNanojansky",
34 "LocalNanojanskyErr",
"LocalDipoleMeanFlux",
35 "LocalDipoleMeanFluxErr",
"LocalDipoleDiffFlux",
36 "LocalDipoleDiffFluxErr",
"Ebv",
37 "MomentsIuuSky",
"MomentsIvvSky",
"MomentsIuvSky",
38 "CorrelationIuuSky",
"CorrelationIvvSky",
"CorrelationIuvSky",
39 "PositionAngleFromMoments",
"PositionAngleFromCorrelation",
40 "SemimajorAxisFromMoments",
"SemimajorAxisFromCorrelation",
41 "SemiminorAxisFromMoments",
"SemiminorAxisFromCorrelation",
49from contextlib
import redirect_stdout
50from itertools
import product
52import astropy.units
as u
58from astropy.coordinates
import SkyCoord
59from lsst.daf.butler
import DeferredDatasetHandle
60from lsst.pipe.base
import InMemoryDatasetHandle
61from lsst.utils
import doImport
62from lsst.utils.introspection
import get_full_type_name
66 typeKey='functor', name=None):
67 """Initialize an object defined in a dictionary.
69 The object needs to be importable as f'{basePath}.{initDict[typeKey]}'.
70 The positional and keyword arguments (if any) are contained in "args" and
71 "kwargs" entries in the dictionary, respectively.
72 This is used in `~lsst.pipe.tasks.functors.CompositeFunctor.from_yaml` to
73 initialize a composite functor from a specification in a YAML file.
78 Dictionary describing object's initialization.
79 Must contain an entry keyed by ``typeKey`` that is the name of the
80 object, relative to ``basePath``.
82 Path relative to module in which ``initDict[typeKey]`` is defined.
84 Key of ``initDict`` that is the name of the object (relative to
87 initDict = initDict.copy()
89 pythonType = doImport(f
'{basePath}.{initDict.pop(typeKey)}')
91 if 'args' in initDict:
92 args = initDict.pop(
'args')
93 if isinstance(args, str):
96 element = pythonType(*args, **initDict)
97 except Exception
as e:
98 message = f
'Error in constructing functor "{name}" of type {pythonType.__name__} with args: {args}'
99 raise type(e)(message, e.args)
104 """Define and execute a calculation on a DataFrame or Handle holding a
107 The `__call__` method accepts either a `~pandas.DataFrame` object or a
108 `~lsst.daf.butler.DeferredDatasetHandle` or
109 `~lsst.pipe.base.InMemoryDatasetHandle`, and returns the
110 result of the calculation as a single column.
111 Each functor defines what columns are needed for the calculation, and only
112 these columns are read from the dataset handle.
114 The action of `__call__` consists of two steps: first, loading the
115 necessary columns from disk into memory as a `~pandas.DataFrame` object;
116 and second, performing the computation on this DataFrame and returning the
119 To define a new `Functor`, a subclass must define a `_func` method,
120 that takes a `~pandas.DataFrame` and returns result in a `~pandas.Series`.
121 In addition, it must define the following attributes:
123 * `_columns`: The columns necessary to perform the calculation
124 * `name`: A name appropriate for a figure axis label
125 * `shortname`: A name appropriate for use as a dictionary key
127 On initialization, a `Functor` should declare what band (``filt`` kwarg)
128 and dataset (e.g. ``'ref'``, ``'meas'``, ``'forced_src'``) it is intended
130 This enables the `_get_data` method to extract the proper columns from the
132 If not specified, the dataset will fall back on the `_defaultDataset`
134 If band is not specified and ``dataset`` is anything other than ``'ref'``,
135 then an error will be raised when trying to perform the calculation.
137 Originally, `Functor` was set up to expect datasets formatted like the
138 ``deepCoadd_obj`` dataset; that is, a DataFrame with a multi-level column
139 index, with the levels of the column index being ``band``, ``dataset``, and
141 It has since been generalized to apply to DataFrames without multi-level
142 indices and multi-level indices with just ``dataset`` and ``column``
144 In addition, the `_get_data` method that reads the columns from the
145 underlying data will return a DataFrame with column index levels defined by
146 the `_dfLevels` attribute; by default, this is ``column``.
148 The `_dfLevels` attributes should generally not need to be changed, unless
149 `_func` needs columns from multiple filters or datasets to do the
151 An example of this is the `~lsst.pipe.tasks.functors.Color` functor, for
152 which `_dfLevels = ('band', 'column')`, and `_func` expects the DataFrame
153 it gets to have those levels in the column index.
158 Band upon which to do the calculation.
161 Dataset upon which to do the calculation (e.g., 'ref', 'meas',
165 _defaultDataset =
'ref'
166 _dfLevels = (
'column',)
167 _defaultNoDup =
False
169 def __init__(self, filt=None, dataset=None, noDup=None):
173 self.
log = logging.getLogger(type(self).__name__)
177 """Do not explode by band if used on object table."""
178 if self.
_noDup is not None:
185 """Columns required to perform calculation."""
186 if not hasattr(self,
'_columns'):
187 raise NotImplementedError(
'Must define columns property or _columns attribute')
191 """Gets the names of the column index levels.
193 This should only be called in the context of a multilevel table.
198 The data to be read, can be a
199 `~lsst.daf.butler.DeferredDatasetHandle` or
200 `~lsst.pipe.base.InMemoryDatasetHandle`.
201 columnIndex (optional): pandas `~pandas.Index` object
202 If not passed, then it is read from the
203 `~lsst.daf.butler.DeferredDatasetHandle`
204 for `~lsst.pipe.base.InMemoryDatasetHandle`.
206 if columnIndex
is None:
207 columnIndex = data.get(component=
"columns")
208 return columnIndex.names
211 """Gets the content of each of the column levels for a multilevel
214 if columnIndex
is None:
215 columnIndex = data.get(component=
"columns")
217 columnLevels = columnIndex.names
219 level: list(np.unique(np.array([c
for c
in columnIndex])[:, i]))
220 for i, level
in enumerate(columnLevels)
222 return columnLevelNames
225 """Converts dictionary column specficiation to a list of columns."""
229 for i, lev
in enumerate(columnLevels):
231 if isinstance(colDict[lev], str):
232 new_colDict[lev] = [colDict[lev]]
234 new_colDict[lev] = colDict[lev]
236 new_colDict[lev] = columnIndex.levels[i]
238 levelCols = [new_colDict[lev]
for lev
in columnLevels]
239 cols = list(product(*levelCols))
240 colsAvailable = [col
for col
in cols
if col
in columnIndex]
244 """Returns columns needed by functor from multilevel dataset.
246 To access tables with multilevel column structure, the
247 `~lsst.daf.butler.DeferredDatasetHandle` or
248 `~lsst.pipe.base.InMemoryDatasetHandle` needs to be passed
249 either a list of tuples or a dictionary.
254 The data as either `~lsst.daf.butler.DeferredDatasetHandle`, or
255 `~lsst.pipe.base.InMemoryDatasetHandle`.
256 columnIndex (optional): pandas `~pandas.Index` object
257 Either passed or read in from
258 `~lsst.daf.butler.DeferredDatasetHandle`.
259 `returnTuple` : `bool`
260 If true, then return a list of tuples rather than the column
261 dictionary specification.
262 This is set to `True` by `CompositeFunctor` in order to be able to
263 combine columns from the various component functors.
266 if not isinstance(data, (DeferredDatasetHandle, InMemoryDatasetHandle)):
267 raise RuntimeError(f
"Unexpected data type. Got {get_full_type_name(data)}.")
269 if columnIndex
is None:
270 columnIndex = data.get(component=
"columns")
276 columnDict = {
'column': self.
columns,
278 if self.
filt is None:
280 if "band" in columnLevels:
282 columnDict[
"band"] = columnLevelNames[
"band"][0]
284 raise ValueError(f
"'filt' not set for functor {self.name}"
285 f
"(dataset {self.dataset}) "
287 "contains multiple filters in column index. "
288 "Set 'filt' or set 'dataset' to 'ref'.")
290 columnDict[
'band'] = self.
filt
293 return self.
_colsFromDict(columnDict, columnIndex=columnIndex)
298 raise NotImplementedError(
'Must define calculation on DataFrame')
301 """Return columnIndex."""
303 if isinstance(data, (DeferredDatasetHandle, InMemoryDatasetHandle)):
304 return data.get(component=
"columns")
309 """Retrieve DataFrame necessary for calculation.
311 The data argument can be a `~pandas.DataFrame`, a
312 `~lsst.daf.butler.DeferredDatasetHandle`, or
313 an `~lsst.pipe.base.InMemoryDatasetHandle`.
315 Returns a DataFrame upon which `self._func` can act.
319 if isinstance(data, pd.DataFrame):
320 _data = InMemoryDatasetHandle(data, storageClass=
"DataFrame")
321 elif isinstance(data, (DeferredDatasetHandle, InMemoryDatasetHandle)):
324 raise RuntimeError(f
"Unexpected type provided for data. Got {get_full_type_name(data)}.")
329 is_multiLevel = isinstance(columnIndex, pd.MultiIndex)
338 df = _data.get(parameters={
"columns": columns})
347 levelsToDrop = [n
for n
in df.columns.names
if n
not in self.
_dfLevels]
348 df.columns = df.columns.droplevel(levelsToDrop)
357 vals = self.
_func(df)
358 except Exception
as e:
359 self.
log.error(
"Exception in %s call: %s: %s", self.
name, type(e).__name__, e)
367 """Computes difference between functor called on two different
368 DataFrame/Handle objects.
370 return self(data1, **kwargs) -
self(data2, **kwargs)
373 return pd.Series(np.full(len(df), np.nan), index=df.index)
377 """Full name of functor (suitable for figure labels)."""
378 return NotImplementedError
382 """Short name of functor (suitable for column name/dict key)."""
387 """Perform multiple calculations at once on a catalog.
389 The role of a `CompositeFunctor` is to group together computations from
391 Instead of returning `~pandas.Series` a `CompositeFunctor` returns a
392 `~pandas.DataFrame`, with the column names being the keys of ``funcDict``.
394 The `columns` attribute of a `CompositeFunctor` is the union of all columns
395 in all the component functors.
397 A `CompositeFunctor` does not use a `_func` method itself; rather, when a
398 `CompositeFunctor` is called, all its columns are loaded at once, and the
399 resulting DataFrame is passed to the `_func` method of each component
401 This has the advantage of only doing I/O (reading from parquet file) once,
402 and works because each individual `_func` method of each component functor
403 does not care if there are *extra* columns in the DataFrame being passed;
404 only that it must contain *at least* the `columns` it expects.
406 An important and useful class method is `from_yaml`, which takes as an
407 argument the path to a YAML file specifying a collection of functors.
411 funcs : `dict` or `list`
412 Dictionary or list of functors.
413 If a list, then it will be converted into a dictonary according to the
414 `.shortname` attribute of each functor.
417 name =
"CompositeFunctor"
421 if type(funcs)
is dict:
424 self.
funcDict = {f.shortname: f
for f
in funcs}
442 """Update the functor with new functors."""
443 if isinstance(new, dict):
445 elif isinstance(new, CompositeFunctor):
448 raise TypeError(
'Can only update with dictionary or CompositeFunctor.')
451 if self.
filt is not None:
456 return list(set([x
for y
in [f.columns
for f
in self.
funcDict.values()]
for x
in y]))
466 f.multilevelColumns(data, returnTuple=
True, **kwargs)
for f
in self.
funcDict.values()
474 """Apply the functor to the data table.
479 The data represented as `~lsst.daf.butler.DeferredDatasetHandle`,
480 `~lsst.pipe.base.InMemoryDatasetHandle`, or `~pandas.DataFrame`.
481 The table or a pointer to a table on disk from which columns can
484 if isinstance(data, pd.DataFrame):
485 _data = InMemoryDatasetHandle(data, storageClass=
"DataFrame")
486 elif isinstance(data, (DeferredDatasetHandle, InMemoryDatasetHandle)):
489 raise RuntimeError(f
"Unexpected type provided for data. Got {get_full_type_name(data)}.")
493 if isinstance(columnIndex, pd.MultiIndex):
495 df = _data.get(parameters={
"columns": columns})
500 subdf = f._setLevels(
501 df[f.multilevelColumns(_data, returnTuple=
True, columnIndex=columnIndex)]
503 valDict[k] = f._func(subdf)
504 except Exception
as e:
506 "Exception in %s (funcs: %s) call: %s",
512 valDict[k] = f.fail(subdf)
517 df = _data.get(parameters={
"columns": self.
columns})
519 valDict = {k: f._func(df)
for k, f
in self.
funcDict.items()}
522 for name, colVal
in valDict.items():
523 if len(colVal.shape) != 1:
524 raise RuntimeError(
"Transformed column '%s' is not the shape of a column. "
525 "It is shaped %s and type %s." % (name, colVal.shape, type(colVal)))
528 valDf = pd.concat(valDict, axis=1)
530 print([(k, type(v))
for k, v
in valDict.items()])
533 if kwargs.get(
'dropna',
False):
534 valDf = valDf.dropna(how=
'any')
540 if renameRules
is None:
542 for old, new
in renameRules:
543 if col.startswith(old):
544 col = col.replace(old, new)
550 filename = os.path.expandvars(filename)
551 with open(filename)
as f:
552 translationDefinition = yaml.safe_load(f)
554 return cls.
from_yaml(translationDefinition, **kwargs)
559 for func, val
in translationDefinition[
'funcs'].items():
562 if 'flag_rename_rules' in translationDefinition:
563 renameRules = translationDefinition[
'flag_rename_rules']
567 if 'calexpFlags' in translationDefinition:
568 for flag
in translationDefinition[
'calexpFlags']:
569 funcs[cls.
renameCol(flag, renameRules)] =
Column(flag, dataset=
'calexp')
571 if 'refFlags' in translationDefinition:
572 for flag
in translationDefinition[
'refFlags']:
575 if 'forcedFlags' in translationDefinition:
576 for flag
in translationDefinition[
'forcedFlags']:
577 funcs[cls.
renameCol(flag, renameRules)] =
Column(flag, dataset=
'forced_src')
579 if 'flags' in translationDefinition:
580 for flag
in translationDefinition[
'flags']:
583 return cls(funcs, **kwargs)
587 """Evaluate an expression on a DataFrame, knowing what the 'mag' function
590 Builds on `pandas.DataFrame.eval`, which parses and executes math on
595 df : ~pandas.DataFrame
596 DataFrame on which to evaluate expression.
602 expr_new = re.sub(
r'mag\((\w+)\)',
r'-2.5*log(\g<1>)/log(10)', expr)
603 val = df.eval(expr_new)
604 except Exception
as e:
605 log.error(
"Exception in mag_aware_eval: %s: %s", type(e).__name__, e)
606 expr_new = re.sub(
r'mag\((\w+)\)',
r'-2.5*log(\g<1>_instFlux)/log(10)', expr)
607 val = df.eval(expr_new)
612 """Arbitrary computation on a catalog.
614 Column names (and thus the columns to be loaded from catalog) are found by
615 finding all words and trying to ignore all "math-y" words.
620 Expression to evaluate, to be parsed and executed by
621 `~lsst.pipe.tasks.functors.mag_aware_eval`.
623 _ignore_words = (
'mag',
'sin',
'cos',
'exp',
'log',
'sqrt')
635 flux_cols = re.findall(
r'mag\(\s*(\w+)\s*\)', self.
expr)
637 cols = [c
for c
in re.findall(
r'[a-zA-Z_]+', self.
expr)
if c
not in self.
_ignore_words]
640 if not re.search(
'_instFlux$', c):
641 cols.append(f
'{c}_instFlux')
646 return list(set([c
for c
in cols
if c
not in not_a_col]))
653 """Get column with a specified name."""
672 """Return the value of the index for each object."""
674 columns = [
'coord_ra']
675 _defaultDataset =
'ref'
679 return pd.Series(df.index, index=df.index)
683 """Base class for coordinate column, in degrees."""
692 output = df[self.
col] * 180 / np.pi
if self.
_radians else df[self.
col]
697 """Right Ascension, in degrees."""
702 super().
__init__(
'coord_ra', **kwargs)
705 return super().
__call__(catalog, **kwargs)
709 """Declination, in degrees."""
714 super().
__init__(
'coord_dec', **kwargs)
717 return super().
__call__(catalog, **kwargs)
721 """Angular uncertainty in Right Ascension, in degrees.
723 Note that ``coord_raErr`` is the uncertainty on RA·cos(Dec),
724 i.e. an arc-length on the sky in the RA direction.
730 super().
__init__(
'coord_raErr', **kwargs)
734 """Uncertainty in declination, in degrees."""
739 super().
__init__(
'coord_decErr', **kwargs)
743 """Tangent-plane angular covariance, in degrees^2.
745 As with the RA error, this is the covariance between RA·cos(Dec) and Dec,
746 Cov(xi, eta) = Cov(RA*cos(Dec), Dec).
753 super().
__init__(
'coord_ra_dec_Cov', **kwargs)
758 output = df[self.
col]*(180/np.pi)**2
if self.
_radians else df[self.
col]
763 """A column with a band in a multiband table."""
774 """A float32 MultibandColumn"""
776 return super().
_func(df).astype(np.float32)
780 """Return a column cast to a single-precision float."""
783 return df[self.
col].astype(np.float32)
787 """Compute the level 20 HtmIndex for the catalog.
791 This functor was implemented to satisfy requirements of old APDB interface
792 which required the ``pixelId`` column in DiaObject with HTM20 index.
793 The APDB interface had migrated to not need that information, but we keep
794 this class in case it may be useful for something else.
809 def computePixel(row):
818 return self.
pixelator.index(sphPoint.getVector())
820 return df.apply(computePixel, axis=1, result_type=
'reduce').astype(
'int64')
824 """Append _instFlux to the column name if it doesn't have it already."""
825 if not col.endswith(
'_instFlux'):
831 """Append _instFluxErr to the column name if it doesn't have it already."""
832 if not col.endswith(
'_instFluxErr'):
833 col +=
'_instFluxErr'
838 """Compute calibrated magnitude.
840 Returns the flux at mag=0.
841 The default ``fluxMag0`` is 63095734448.0194, which is default for HSC.
842 TO DO: This default should be made configurable in DM-21955.
844 This calculation hides warnings about invalid values and dividing by zero.
846 As with all functors, a ``dataset`` and ``filt`` kwarg should be provided
848 Unlike the default `Functor`, however, the default dataset for a `Mag` is
849 ``'meas'``, rather than ``'ref'``.
854 Name of flux column from which to compute magnitude.
855 Can be parseable by the `~lsst.pipe.tasks.functors.fluxName` function;
856 that is, you can pass ``'modelfit_CModel'`` instead of
857 ``'modelfit_CModel_instFlux'``, and it will understand.
859 _defaultDataset =
'meas'
873 with warnings.catch_warnings():
874 warnings.filterwarnings(
'ignore',
r'invalid value encountered')
875 warnings.filterwarnings(
'ignore',
r'divide by zero')
880 return f
'mag_{self.col}'
884 """Compute calibrated magnitude uncertainty.
889 Name of the flux column.
902 with warnings.catch_warnings():
903 warnings.filterwarnings(
'ignore',
r'invalid value encountered')
904 warnings.filterwarnings(
'ignore',
r'divide by zero')
905 fluxCol, fluxErrCol = self.
columns
906 x = df[fluxErrCol] / df[fluxCol]
908 magErr = (2.5 / np.log(10.)) * np.sqrt(x*x + y*y)
913 return super().name +
'_err'
917 """Functor to calculate magnitude difference."""
918 _defaultDataset =
'meas'
930 with warnings.catch_warnings():
931 warnings.filterwarnings(
'ignore',
r'invalid value encountered')
932 warnings.filterwarnings(
'ignore',
r'divide by zero')
933 return -2.5*np.log10(df[self.
col1]/df[self.
col2])
937 return f
'(mag_{self.col1} - mag_{self.col2})'
941 return f
'magDiff_{self.col1}_{self.col2}'
945 """Compute the color between two filters.
947 Computes color by initializing two different `Mag` functors based on the
948 ``col`` and filters provided, and then returning the difference.
950 This is enabled by the `_func` method expecting a DataFrame with a
951 multilevel column index, with both ``'band'`` and ``'column'``, instead of
952 just ``'column'``, which is the `Functor` default.
953 This is controlled by the `_dfLevels` attribute.
955 Also of note, the default dataset for `Color` is ``forced_src'``, whereas
956 for `Mag` it is ``'meas'``.
961 Name of the flux column from which to compute; same as would be passed
962 to `~lsst.pipe.tasks.functors.Mag`.
965 Filters from which to compute magnitude difference.
966 Color computed is ``Mag(filt2) - Mag(filt1)``.
968 _defaultDataset =
'forced_src'
969 _dfLevels = (
'band',
'column')
975 raise RuntimeError(
"Cannot compute Color for %s: %s - %s " % (col, filt2, filt1))
993 mag2 = self.mag2.
_func(df[self.filt2])
994 mag1 = self.mag1.
_func(df[self.filt1])
999 return [self.
mag1.col, self.
mag2.col]
1006 return f
'{self.filt2} - {self.filt1} ({self.col})'
1010 return f
"{self.col}_{self.filt2.replace('-', '')}m{self.filt1.replace('-', '')}"
1014 """This functor subtracts the trace of the PSF second moments from the
1015 trace of the second moments of the source.
1017 If the HsmShapeAlgorithm measurement is valid, then these will be used for
1019 Otherwise, the SdssShapeAlgorithm measurements will be used.
1021 name =
'Deconvolved Moments'
1022 shortname =
'deconvolvedMoments'
1023 _columns = (
"ext_shapeHSM_HsmSourceMoments_xx",
1024 "ext_shapeHSM_HsmSourceMoments_yy",
1025 "base_SdssShape_xx",
"base_SdssShape_yy",
1026 "ext_shapeHSM_HsmPsfMoments_xx",
1027 "ext_shapeHSM_HsmPsfMoments_yy")
1030 """Calculate deconvolved moments."""
1031 if "ext_shapeHSM_HsmSourceMoments_xx" in df.columns:
1032 hsm = df[
"ext_shapeHSM_HsmSourceMoments_xx"] + df[
"ext_shapeHSM_HsmSourceMoments_yy"]
1034 hsm = np.ones(len(df))*np.nan
1035 sdss = df[
"base_SdssShape_xx"] + df[
"base_SdssShape_yy"]
1036 if "ext_shapeHSM_HsmPsfMoments_xx" in df.columns:
1037 psf = df[
"ext_shapeHSM_HsmPsfMoments_xx"] + df[
"ext_shapeHSM_HsmPsfMoments_yy"]
1042 raise RuntimeError(
'No psf shape parameter found in catalog')
1044 return hsm.where(np.isfinite(hsm), sdss) - psf
1048 """Functor to calculate the SDSS trace radius size for sources.
1050 The SDSS trace radius size is a measure of size equal to the square root of
1051 half of the trace of the second moments tensor measured with the
1052 SdssShapeAlgorithm plugin.
1053 This has units of pixels.
1055 name =
"SDSS Trace Size"
1056 shortname =
'sdssTrace'
1057 _columns = (
"base_SdssShape_xx",
"base_SdssShape_yy")
1060 srcSize = np.sqrt(0.5*(df[
"base_SdssShape_xx"] + df[
"base_SdssShape_yy"]))
1065 """Functor to calculate the SDSS trace radius size difference (%) between
1066 the object and the PSF model.
1072 name =
"PSF - SDSS Trace Size"
1073 shortname =
'psf_sdssTrace'
1074 _columns = (
"base_SdssShape_xx",
"base_SdssShape_yy",
1075 "base_SdssShape_psf_xx",
"base_SdssShape_psf_yy")
1078 srcSize = np.sqrt(0.5*(df[
"base_SdssShape_xx"] + df[
"base_SdssShape_yy"]))
1079 psfSize = np.sqrt(0.5*(df[
"base_SdssShape_psf_xx"] + df[
"base_SdssShape_psf_yy"]))
1080 sizeDiff = 100*(srcSize - psfSize)/(0.5*(srcSize + psfSize))
1085 """Functor to calculate the HSM trace radius size for sources.
1087 The HSM trace radius size is a measure of size equal to the square root of
1088 half of the trace of the second moments tensor measured with the
1089 HsmShapeAlgorithm plugin.
1090 This has units of pixels.
1092 name =
'HSM Trace Size'
1093 shortname =
'hsmTrace'
1094 _columns = (
"ext_shapeHSM_HsmSourceMoments_xx",
1095 "ext_shapeHSM_HsmSourceMoments_yy")
1098 srcSize = np.sqrt(0.5*(df[
"ext_shapeHSM_HsmSourceMoments_xx"]
1099 + df[
"ext_shapeHSM_HsmSourceMoments_yy"]))
1104 """Functor to calculate the HSM trace radius size difference (%) between
1105 the object and the PSF model.
1111 name =
'PSF - HSM Trace Size'
1112 shortname =
'psf_HsmTrace'
1113 _columns = (
"ext_shapeHSM_HsmSourceMoments_xx",
1114 "ext_shapeHSM_HsmSourceMoments_yy",
1115 "ext_shapeHSM_HsmPsfMoments_xx",
1116 "ext_shapeHSM_HsmPsfMoments_yy")
1119 srcSize = np.sqrt(0.5*(df[
"ext_shapeHSM_HsmSourceMoments_xx"]
1120 + df[
"ext_shapeHSM_HsmSourceMoments_yy"]))
1121 psfSize = np.sqrt(0.5*(df[
"ext_shapeHSM_HsmPsfMoments_xx"]
1122 + df[
"ext_shapeHSM_HsmPsfMoments_yy"]))
1123 sizeDiff = 100*(srcSize - psfSize)/(0.5*(srcSize + psfSize))
1128 """Functor to calculate the PSF FWHM with second moments measured from the
1129 HsmShapeAlgorithm plugin.
1131 This is in units of arcseconds, and assumes the hsc_rings_v1 skymap pixel
1132 scale of 0.168 arcseconds/pixel.
1136 This conversion assumes the PSF is Gaussian, which is not always the case.
1138 name =
'HSM Psf FWHM'
1139 _columns = (
'ext_shapeHSM_HsmPsfMoments_xx',
'ext_shapeHSM_HsmPsfMoments_yy')
1142 SIGMA2FWHM = 2*np.sqrt(2*np.log(2))
1146 0.5*(df[
'ext_shapeHSM_HsmPsfMoments_xx']
1147 + df[
'ext_shapeHSM_HsmPsfMoments_yy']))).astype(np.float32)
1151 r"""Calculate :math:`e_1` ellipticity component for sources, defined as:
1154 e_1 &= (I_{xx}-I_{yy})/(I_{xx}+I_{yy})
1160 name =
"Distortion Ellipticity (e1)"
1161 shortname =
"Distortion"
1175 return ((df[self.
colXX] - df[self.
colYY]) / (
1176 df[self.
colXX] + df[self.
colYY])).astype(np.float32)
1180 r"""Calculate :math:`e_2` ellipticity component for sources, defined as:
1183 e_2 &= 2I_{xy}/(I_{xx}+I_{yy})
1189 name =
"Ellipticity e2"
1202 return (2*df[self.
colXY] / (df[self.
colXX] + df[self.
colYY])).astype(np.float32)
1206 """Calculate the radius from the quadrupole moments.
1208 This returns the fourth root of the determinant of the second moments
1209 tensor, which has units of pixels.
1228 return ((df[self.
colXX]*df[self.
colYY] - df[self.
colXY]**2)**0.25).astype(np.float32)
1232 """Computations using the stored localWcs."""
1233 name =
"LocalWcsOperations"
1248 """Compute the dRA, dDec from dx, dy.
1252 x : `~pandas.Series`
1254 y : `~pandas.Series`
1256 cd11 : `~pandas.Series`
1257 [1, 1] element of the local Wcs affine transform.
1258 cd12 : `~pandas.Series`
1259 [1, 2] element of the local Wcs affine transform.
1260 cd21 : `~pandas.Series`
1261 [2, 1] element of the local Wcs affine transform.
1262 cd22 : `~pandas.Series`
1263 [2, 2] element of the local Wcs affine transform.
1268 RA and Dec conversion of x and y given the local Wcs.
1269 Returned units are in radians.
1273 If x and y are with respect to the CRVAL1, CRVAL2
1274 then this will return the RA, Dec for that WCS.
1276 return (x * cd11 + y * cd12, x * cd21 + y * cd22)
1279 """Compute the local pixel scale conversion.
1283 ra1 : `~pandas.Series`
1284 Ra of the first coordinate in radians.
1285 dec1 : `~pandas.Series`
1286 Dec of the first coordinate in radians.
1287 ra2 : `~pandas.Series`
1288 Ra of the second coordinate in radians.
1289 dec2 : `~pandas.Series`
1290 Dec of the second coordinate in radians.
1294 dist : `~pandas.Series`
1295 Distance on the sphere in radians.
1297 deltaDec = dec2 - dec1
1299 return 2 * np.arcsin(
1301 np.sin(deltaDec / 2) ** 2
1302 + np.cos(dec2) * np.cos(dec1) * np.sin(deltaRa / 2) ** 2))
1305 """Compute the distance on the sphere from x2, y1 to x1, y1.
1309 x1 : `~pandas.Series`
1311 y1 : `~pandas.Series`
1313 x2 : `~pandas.Series`
1315 y2 : `~pandas.Series`
1317 cd11 : `~pandas.Series`
1318 [1, 1] element of the local Wcs affine transform.
1319 cd12 : `~pandas.Series`
1320 [1, 2] element of the local Wcs affine transform.
1321 cd21 : `~pandas.Series`
1322 [2, 1] element of the local Wcs affine transform.
1323 cd22 : `~pandas.Series`
1324 [2, 2] element of the local Wcs affine transform.
1328 Distance : `~pandas.Series`
1329 Arcseconds per pixel at the location of the local WC.
1337 """Compute position angle (E of N) from (ra1, dec1) to (ra2, dec2).
1341 ra1 : iterable [`float`]
1342 RA of the first coordinate [radian].
1343 dec1 : iterable [`float`]
1344 Dec of the first coordinate [radian].
1345 ra2 : iterable [`float`]
1346 RA of the second coordinate [radian].
1347 dec2 : iterable [`float`]
1348 Dec of the second coordinate [radian].
1352 Position Angle: `~pandas.Series`
1357 (ra1, dec1) -> (ra2, dec2) is interpreted as the shorter way around the sphere
1359 For a separation of 0.0001 rad, the position angle is good to 0.0009 rad
1360 all over the sphere.
1364 position_angle = np.zeros(len(ra1))
1365 for i, (r1, d1, r2, d2)
in enumerate(zip(ra1, dec1, ra2, dec2)):
1368 bearing = point1.bearingTo(point2)
1369 pa_ref_angle =
geom.Angle(np.pi/2, geom.radians)
1370 pa = pa_ref_angle - bearing
1373 position_angle[i] = pa.asRadians()
1375 return pd.Series(position_angle)
1378 """Compute position angle (E of N) from detector angle (+y of +x).
1383 detector angle [radian]
1385 [1, 1] element of the local Wcs affine transform.
1387 [1, 2] element of the local Wcs affine transform.
1389 [2, 1] element of the local Wcs affine transform.
1391 [2, 2] element of the local Wcs affine transform.
1395 Position Angle: `~pandas.Series`
1408 """Compute the local pixel scale from the stored CDMatrix.
1420 """Compute the local pixel to scale conversion in arcseconds.
1424 cd11 : `~pandas.Series`
1425 [1, 1] element of the local Wcs affine transform in radians.
1426 cd11 : `~pandas.Series`
1427 [1, 1] element of the local Wcs affine transform in radians.
1428 cd12 : `~pandas.Series`
1429 [1, 2] element of the local Wcs affine transform in radians.
1430 cd21 : `~pandas.Series`
1431 [2, 1] element of the local Wcs affine transform in radians.
1432 cd22 : `~pandas.Series`
1433 [2, 2] element of the local Wcs affine transform in radians.
1437 pixScale : `~pandas.Series`
1438 Arcseconds per pixel at the location of the local WC.
1440 return 3600 * np.degrees(np.sqrt(np.fabs(cd11 * cd22 - cd12 * cd21)))
1450 """Convert a value in units of pixels to units of arcseconds."""
1468 return f
"{self.col}_asArcseconds"
1486 """Convert a value in units of pixels squared to units of arcseconds
1506 return f
"{self.col}_asArcsecondsSq"
1521 return df[self.
col] * pixScale * pixScale
1525 """Compute a position angle from a detector angle and the stored CDMatrix.
1529 position angle : degrees
1532 name =
"PositionAngle"
1544 super().
__init__(colCD_1_1, colCD_1_2, colCD_2_1, colCD_2_2, **kwargs)
1567 """Convert a detector angle error to a position angle error.
1571 position angle error : degrees
1574 name =
"PositionAngleErr"
1589 """Return the band used to seed multiband forced photometry.
1591 This functor is to be used on Object tables.
1592 It converts the boolean merge_measurements_{band} columns into a single
1593 string representing the first band for which merge_measurements_{band}
1596 Assumes the default priority order of i, r, z, y, g, u.
1598 name =
'Reference Band'
1599 shortname =
'refBand'
1601 band_order = (
"i",
"r",
"z",
"y",
"g",
"u")
1609 return [f
"merge_measurement_{band}" for band
in bands]
1611 def _func(self, df: pd.DataFrame) -> pd.Series:
1612 def getFilterAliasName(row):
1614 colName = row.idxmax()
1615 return colName.replace(
'merge_measurement_',
'')
1619 columns = [col
for col
in self.
columns if col
in df.columns]
1621 return df[columns].apply(getFilterAliasName, axis=1,
1622 result_type=
'reduce').astype(
'object')
1624 def __init__(self, bands: tuple[str] | list[str] |
None =
None, **kwargs):
1630 """Base class for Object table calibrated fluxes and magnitudes."""
1632 AB_FLUX_SCALE = (0 * u.ABmag).to_value(u.nJy)
1633 LOG_AB_FLUX_SCALE = 12.56
1634 FIVE_OVER_2LOG10 = 1.085736204758129569
1638 def __init__(self, colFlux, colFluxErr=None, **kwargs):
1654 return f
'mag_{self.col}'
1658 """Compute sqrt(a^2 + b^2) without under/overflow."""
1659 if np.abs(a) < np.abs(b):
1664 return np.abs(a) * np.sqrt(1. + q*q)
1667 """Convert instrumental flux to nanojanskys."""
1668 return (self.
AB_FLUX_SCALE * dn / fluxMag0).astype(np.float32)
1671 """Convert instrumental flux to AB magnitude."""
1672 with warnings.catch_warnings():
1673 warnings.filterwarnings(
'ignore',
r'invalid value encountered')
1674 warnings.filterwarnings(
'ignore',
r'divide by zero')
1675 return (-2.5 * np.log10(dn/fluxMag0)).astype(np.float32)
1678 """Convert instrumental flux error to nanojanskys."""
1679 retVal = self.
vhypot(dn * fluxMag0Err, dnErr * fluxMag0)
1681 return retVal.astype(np.float32)
1684 """Convert instrumental flux error to AB magnitude error."""
1685 retVal = self.
dn2fluxErr(dn, dnErr, fluxMag0, fluxMag0Err) / self.
dn2flux(dn, fluxMag0)
1690 """Convert instrumental flux to nanojanskys."""
1696 """Convert instrumental flux error to nanojanskys."""
1703 return pd.Series(retArr, index=df.index)
1707 """Base class for calibrating the specified instrument flux column using
1708 the local photometric calibration.
1713 Name of the instrument flux column.
1714 instFluxErrCol : `str`
1715 Name of the assocated error columns for ``instFluxCol``.
1716 photoCalibCol : `str`
1717 Name of local calibration column.
1718 photoCalibErrCol : `str`, optional
1719 Error associated with ``photoCalibCol``. Ignored and deprecated; will
1720 be removed after v29.
1727 logNJanskyToAB = (1 * u.nJy).to_value(u.ABmag)
1733 photoCalibErrCol=None,
1739 if photoCalibErrCol
is not None:
1740 warnings.warn(
"The photoCalibErrCol argument is deprecated and will be removed after v29.",
1741 category=FutureWarning)
1745 """Convert instrument flux to nanojanskys.
1749 instFlux : `~numpy.ndarray` or `~pandas.Series`
1750 Array of instrument flux measurements.
1751 localCalib : `~numpy.ndarray` or `~pandas.Series`
1752 Array of local photometric calibration estimates.
1756 calibFlux : `~numpy.ndarray` or `~pandas.Series`
1757 Array of calibrated flux measurements.
1759 return instFlux * localCalib
1762 """Convert instrument flux to nanojanskys.
1766 instFlux : `~numpy.ndarray` or `~pandas.Series`
1767 Array of instrument flux measurements. Ignored (accepted for
1768 backwards compatibility and consistency with magnitude-error
1769 calculation methods).
1770 instFluxErr : `~numpy.ndarray` or `~pandas.Series`
1771 Errors on associated ``instFlux`` values.
1772 localCalib : `~numpy.ndarray` or `~pandas.Series`
1773 Array of local photometric calibration estimates.
1774 localCalibErr : `~numpy.ndarray` or `~pandas.Series`, optional
1775 Errors on associated ``localCalib`` values. Ignored and deprecated;
1776 will be removed after v29.
1780 calibFluxErr : `~numpy.ndarray` or `~pandas.Series`
1781 Errors on calibrated flux measurements.
1784 if localCalibErr
is not None:
1785 warnings.warn(
"The localCalibErr argument is deprecated and will be removed after v29.",
1786 category=FutureWarning)
1787 return instFluxErr * localCalib
1790 """Convert instrument flux to nanojanskys.
1794 instFlux : `~numpy.ndarray` or `~pandas.Series`
1795 Array of instrument flux measurements.
1796 localCalib : `~numpy.ndarray` or `~pandas.Series`
1797 Array of local photometric calibration estimates.
1801 calibMag : `~numpy.ndarray` or `~pandas.Series`
1802 Array of calibrated AB magnitudes.
1807 """Convert instrument flux err to nanojanskys.
1811 instFlux : `~numpy.ndarray` or `~pandas.Series`
1812 Array of instrument flux measurements.
1813 instFluxErr : `~numpy.ndarray` or `~pandas.Series`
1814 Errors on associated ``instFlux`` values.
1815 localCalib : `~numpy.ndarray` or `~pandas.Series`
1816 Array of local photometric calibration estimates.
1817 localCalibErr : `~numpy.ndarray` or `~pandas.Series`, optional
1818 Errors on associated ``localCalib`` values. Ignored and deprecated;
1819 will be removed after v29.
1823 calibMagErr: `~numpy.ndarray` or `~pandas.Series`
1824 Error on calibrated AB magnitudes.
1827 if localCalibErr
is not None:
1828 warnings.warn(
"The localCalibErr argument is deprecated and will be removed after v29.",
1829 category=FutureWarning)
1835 """Compute calibrated fluxes using the local calibration value.
1837 This returns units of nanojanskys.
1846 return f
'flux_{self.instFluxCol}'
1854 """Compute calibrated flux errors using the local calibration value.
1856 This returns units of nanojanskys.
1865 return f
'fluxErr_{self.instFluxCol}'
1873 """Compute absolute mean of dipole fluxes.
1879 LocalDipoleMeanFluxErr
1881 LocalDipoleDiffFluxErr
1890 photoCalibErrCol=None,
1911 return f
'dipMeanFlux_{self.instFluxPosCol}_{self.instFluxNegCol}'
1919 """Compute the error on the absolute mean of dipole fluxes.
1927 LocalDipoleDiffFluxErr
1940 return f
'dipMeanFluxErr_{self.instFluxPosCol}_{self.instFluxNegCol}'
1947 """Compute the absolute difference of dipole fluxes.
1949 Calculated value is (abs(pos) - abs(neg)).
1956 LocalDipoleMeanFluxErr
1957 LocalDipoleDiffFluxErr
1968 return f
'dipDiffFlux_{self.instFluxPosCol}_{self.instFluxNegCol}'
1976 """Compute the error on the absolute difference of dipole fluxes.
1983 LocalDipoleMeanFluxErr
1997 return f
'dipDiffFluxErr_{self.instFluxPosCol}_{self.instFluxNegCol}'
2004 """Compute E(B-V) from dustmaps.sfd."""
2005 _defaultDataset =
'ref'
2012 with open(os.devnull,
"w")
as devnull:
2013 with redirect_stdout(devnull):
2014 from dustmaps.sfd
import SFDQuery
2020 coords = SkyCoord(df[
'coord_ra'].values * u.rad, df[
'coord_dec'].values * u.rad)
2021 ebv = self.
sfd(coords)
2022 return pd.Series(ebv, index=df.index).astype(
'float32')
2026 """Base class for functors that use shape moments and localWCS
2030 is_covariance : bool
2031 Whether the shape columns are terms of a covariance matrix. If False,
2032 they will be assumed to be terms of a correlation matrix instead.
2035 is_covariance: bool =
True
2065 """Return columns that are needed from the ref table."""
2073 r"""Return terms commonly used for ellipse parameterization conversions.
2080 Whether to compute the terms in sky coordinates.
2081 If False, XX, YY and XY moments are used instead of
2087 The sum of the diagonal terms of the covariance.
2089 The difference of the diagonal terms of the covariance.
2091 A term similar to the discriminant of the quadratic formula.
2096 t2 = xx_m_yy**2 + 4.0*(self.
sky_uv(df)
if sky
else self.
get_xy(df))**2
2100 return xx + yy, xx_m_yy, t2
2117 """Return the component of the moments tensor aligned with the RA axis, in radians."""
2123 return (CD_1_1*(i_xx*CD_1_1 + i_xy*CD_1_2)
2124 + CD_1_2*(i_xy*CD_1_1 + i_yy*CD_1_2))
2127 """Return the component of the moments tensor aligned with the dec axis, in radians."""
2133 return (CD_2_1*(i_xx*CD_2_1 + i_xy*CD_2_2)
2134 + CD_2_2*(i_xy*CD_2_1 + i_yy*CD_2_2))
2137 """Return the covariance of the moments tensor in ra, dec coordinates, in radians."""
2145 return ((CD_1_1 * i_xx + CD_1_2 * i_xy) * CD_2_1
2146 + (CD_1_1 * i_xy + CD_1_2 * i_yy) * CD_2_2)
2150 Calculate shear-type ellipticity parameter G1.
2156 denom = sky_uu + sky_vv + 2 * np.sqrt(sky_uu*sky_vv - sky_uv**2)
2157 return ((sky_uu - sky_vv) / denom).astype(np.float32)
2161 Calculate shear-type ellipticity parameter G2.
2163 This has the opposite sign as sky_uv in order to maintain consistency with the HSM moments
2170 denom = sky_uu + sky_vv + 2 * np.sqrt(sky_uu*sky_vv - sky_uv**2)
2171 return (-2*sky_uv / denom).astype(np.float32)
2176 return np.sqrt(0.5*(sky_uu + sky_vv)).astype(np.float32)
2180 """Rotate pixel moments Ixx,Iyy,Ixy into RA/dec frame and G1/G2 reduced
2181 shear parameterization"""
2182 _defaultDataset =
'meas'
2184 shortname =
"moments_g1"
2189 return pd.Series(sky_g1.astype(np.float32), index=df.index)
2193 """Rotate pixel moments Ixx,Iyy,Ixy into RA/dec frame and G1/G2 reduced
2194 shear parameterization"""
2195 _defaultDataset =
'meas'
2197 shortname =
"moments_g2"
2202 return pd.Series(sky_g2.astype(np.float32), index=df.index)
2206 """Trace radius size in arcseconds from pixel moments Ixx,Iyy,Ixy
2208 The trace radius size is a measure of size equal to the square root of
2209 half of the trace of the second moments tensor.
2211 _defaultDataset =
'meas'
2212 name =
"moments_trace"
2213 shortname =
"moments_trace"
2218 return pd.Series((sky_trace_radians*(180/np.pi)*3600).astype(np.float32), index=df.index)
2222 """Rotate pixel moments Ixx,Iyy,Ixy into ra,dec frame and arcseconds"""
2223 _defaultDataset =
'meas'
2225 shortname =
"moments_uu"
2228 sky_uu_radians = self.
sky_uu(df)
2230 return pd.Series((sky_uu_radians*((180/np.pi)*3600)**2).astype(np.float32), index=df.index)
2234 """MomentsIuuSky but from sigma_x, sigma_y, rho correlation terms."""
2235 is_covariance =
False
2239 """Rotate pixel moments Ixx,Iyy,Ixy into ra,dec frame and arcseconds"""
2240 _defaultDataset =
'meas'
2242 shortname =
"moments_vv"
2245 sky_vv_radians = self.
sky_vv(df)
2247 return pd.Series((sky_vv_radians*((180/np.pi)*3600)**2).astype(np.float32), index=df.index)
2251 """MomentsIvvSky but from sigma_x, sigma_y, rho correlation terms."""
2252 is_covariance =
False
2256 """Rotate pixel moments Ixx,Iyy,Ixy into ra,dec frame and arcseconds"""
2257 _defaultDataset =
'meas'
2259 shortname =
"moments_uv"
2262 sky_uv_radians = self.
sky_uv(df)
2264 return pd.Series((sky_uv_radians*((180/np.pi)*3600)**2).astype(np.float32), index=df.index)
2268 """MomentsIuvSky but from sigma_x, sigma_y, rho correlation terms."""
2269 is_covariance =
False
2273 """Compute position angle relative to ra,dec frame, in degrees, from Ixx,Iyy,Ixy pixel moments."""
2274 _defaultDataset =
'meas'
2275 name =
"moments_theta"
2276 shortname =
"moments_theta"
2282 theta = 0.5*np.arctan2(2*sky_uv, sky_uu - sky_vv)
2284 return pd.Series((np.degrees(np.array(theta))).astype(np.float32), index=df.index)
2288 """PositionAngleFromMoments but from sigma_x, sigma_y, rho correlation terms."""
2289 is_covariance =
False
2293 """Compute the semimajor axis length in arcseconds, from Ixx,Iyy,Ixy pixel moments."""
2294 _defaultDataset =
'meas'
2296 shortname =
"moments_a"
2301 a_radians = np.sqrt(0.5 * (xx_p_yy + np.sqrt(t2)))
2303 return pd.Series((np.degrees(a_radians)*3600).astype(np.float32), index=df.index)
2307 """SemimajorAxisFromMoments but from sigma_x, sigma_y, rho correlation terms."""
2308 is_covariance =
False
2312 """Compute the semiminor axis length in arcseconds, from Ixx,Iyy,Ixy pixel moments."""
2313 _defaultDataset =
'meas'
2315 shortname =
"moments_b"
2320 b_radians = np.sqrt(0.5 * (xx_p_yy - np.sqrt(t2)))
2322 return pd.Series((np.degrees(b_radians)*3600).astype(np.float32), index=df.index)
2326 """SemiminorAxisFromMoments but from sigma_x, sigma_y, rho correlation terms."""
2327 is_covariance =
False
__init__(self, col, filt2, filt1, **kwargs)
multilevelColumns(self, parq, **kwargs)
__init__(self, col, **kwargs)
multilevelColumns(self, data, **kwargs)
__call__(self, data, **kwargs)
from_file(cls, filename, **kwargs)
renameCol(cls, col, renameRules)
from_yaml(cls, translationDefinition, **kwargs)
__init__(self, funcs, **kwargs)
pixelScaleArcseconds(self, cd11, cd12, cd21, cd22)
__init__(self, theta_err_col, **kwargs)
__init__(self, theta_col, colCD_1_1, colCD_1_2, colCD_2_1, colCD_2_2, **kwargs)
__init__(self, col, colCD_1_1, colCD_1_2, colCD_2_1, colCD_2_2, **kwargs)
__init__(self, col, colCD_1_1, colCD_1_2, colCD_2_1, colCD_2_2, **kwargs)
__init__(self, col, **kwargs)
__init__(self, expr, **kwargs)
__call__(self, catalog, **kwargs)
__init__(self, colXX, colXY, colYY, **kwargs)
__init__(self, colXX, colXY, colYY, **kwargs)
_func(self, df, dropna=True)
_get_columnIndex(self, data)
multilevelColumns(self, data, columnIndex=None, returnTuple=False)
__call__(self, data, dropna=False)
_get_data_columnLevels(self, data, columnIndex=None)
_colsFromDict(self, colDict, columnIndex=None)
difference(self, data1, data2, **kwargs)
_get_data_columnLevelNames(self, data, columnIndex=None)
__init__(self, filt=None, dataset=None, noDup=None)
__init__(self, ra, dec, **kwargs)
__init__(self, instFluxPosCol, instFluxNegCol, instFluxPosErrCol, instFluxNegErrCol, photoCalibCol, photoCalibErrCol=None, **kwargs)
instFluxToNanojansky(self, instFlux, localCalib)
instFluxErrToMagnitudeErr(self, instFlux, instFluxErr, localCalib, localCalibErr=None)
instFluxToMagnitude(self, instFlux, localCalib)
__init__(self, instFluxCol, instFluxErrCol, photoCalibCol, photoCalibErrCol=None, **kwargs)
instFluxErrToNanojanskyErr(self, instFlux, instFluxErr, localCalib, localCalibErr=None)
computeSkySeparation(self, ra1, dec1, ra2, dec2)
__init__(self, colCD_1_1, colCD_1_2, colCD_2_1, colCD_2_2, **kwargs)
computeDeltaRaDec(self, x, y, cd11, cd12, cd21, cd22)
getSkySeparationFromPixel(self, x1, y1, x2, y2, cd11, cd12, cd21, cd22)
computePositionAngle(self, ra1, dec1, ra2, dec2)
getPositionAngleFromDetectorAngle(self, theta, cd11, cd12, cd21, cd22)
__init__(self, col1, col2, **kwargs)
__init__(self, *args, **kwargs)
__init__(self, col, **kwargs)
__init__(self, shape_1_1, shape_2_2, shape_1_2, colCD_1_1, colCD_1_2, colCD_2_1, colCD_2_2, **kwargs)
compute_ellipse_terms(self, df, bool sky=True)
__init__(self, col, band_to_check, **kwargs)
dn2flux(self, dn, fluxMag0)
__init__(self, colFlux, colFluxErr=None, **kwargs)
dn2mag(self, dn, fluxMag0)
dn2MagErr(self, dn, dnErr, fluxMag0, fluxMag0Err)
dn2fluxErr(self, dn, dnErr, fluxMag0, fluxMag0Err)
__call__(self, catalog, **kwargs)
__init__(self, colXX, colXY, colYY, **kwargs)
pd.Series _func(self, pd.DataFrame df)
__init__(self, tuple[str]|list[str]|None bands=None, **kwargs)
init_fromDict(initDict, basePath='lsst.pipe.tasks.functors', typeKey='functor', name=None)
mag_aware_eval(df, expr, log)