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 """Uncertainty in Right Ascension, in degrees."""
726 super().
__init__(
'coord_raErr', **kwargs)
730 """Uncertainty in declination, in degrees."""
735 super().
__init__(
'coord_decErr', **kwargs)
739 """Coordinate covariance column, in degrees."""
745 super().
__init__(
'coord_ra_dec_Cov', **kwargs)
750 output = df[self.
col]*(180/np.pi)**2
if self.
_radians else df[self.
col]
755 """A column with a band in a multiband table."""
766 """A float32 MultibandColumn"""
768 return super().
_func(df).astype(np.float32)
772 """Return a column cast to a single-precision float."""
775 return df[self.
col].astype(np.float32)
779 """Compute the level 20 HtmIndex for the catalog.
783 This functor was implemented to satisfy requirements of old APDB interface
784 which required the ``pixelId`` column in DiaObject with HTM20 index.
785 The APDB interface had migrated to not need that information, but we keep
786 this class in case it may be useful for something else.
801 def computePixel(row):
810 return self.
pixelator.index(sphPoint.getVector())
812 return df.apply(computePixel, axis=1, result_type=
'reduce').astype(
'int64')
816 """Append _instFlux to the column name if it doesn't have it already."""
817 if not col.endswith(
'_instFlux'):
823 """Append _instFluxErr to the column name if it doesn't have it already."""
824 if not col.endswith(
'_instFluxErr'):
825 col +=
'_instFluxErr'
830 """Compute calibrated magnitude.
832 Returns the flux at mag=0.
833 The default ``fluxMag0`` is 63095734448.0194, which is default for HSC.
834 TO DO: This default should be made configurable in DM-21955.
836 This calculation hides warnings about invalid values and dividing by zero.
838 As with all functors, a ``dataset`` and ``filt`` kwarg should be provided
840 Unlike the default `Functor`, however, the default dataset for a `Mag` is
841 ``'meas'``, rather than ``'ref'``.
846 Name of flux column from which to compute magnitude.
847 Can be parseable by the `~lsst.pipe.tasks.functors.fluxName` function;
848 that is, you can pass ``'modelfit_CModel'`` instead of
849 ``'modelfit_CModel_instFlux'``, and it will understand.
851 _defaultDataset =
'meas'
865 with warnings.catch_warnings():
866 warnings.filterwarnings(
'ignore',
r'invalid value encountered')
867 warnings.filterwarnings(
'ignore',
r'divide by zero')
872 return f
'mag_{self.col}'
876 """Compute calibrated magnitude uncertainty.
881 Name of the flux column.
894 with warnings.catch_warnings():
895 warnings.filterwarnings(
'ignore',
r'invalid value encountered')
896 warnings.filterwarnings(
'ignore',
r'divide by zero')
897 fluxCol, fluxErrCol = self.
columns
898 x = df[fluxErrCol] / df[fluxCol]
900 magErr = (2.5 / np.log(10.)) * np.sqrt(x*x + y*y)
905 return super().name +
'_err'
909 """Functor to calculate magnitude difference."""
910 _defaultDataset =
'meas'
922 with warnings.catch_warnings():
923 warnings.filterwarnings(
'ignore',
r'invalid value encountered')
924 warnings.filterwarnings(
'ignore',
r'divide by zero')
925 return -2.5*np.log10(df[self.
col1]/df[self.
col2])
929 return f
'(mag_{self.col1} - mag_{self.col2})'
933 return f
'magDiff_{self.col1}_{self.col2}'
937 """Compute the color between two filters.
939 Computes color by initializing two different `Mag` functors based on the
940 ``col`` and filters provided, and then returning the difference.
942 This is enabled by the `_func` method expecting a DataFrame with a
943 multilevel column index, with both ``'band'`` and ``'column'``, instead of
944 just ``'column'``, which is the `Functor` default.
945 This is controlled by the `_dfLevels` attribute.
947 Also of note, the default dataset for `Color` is ``forced_src'``, whereas
948 for `Mag` it is ``'meas'``.
953 Name of the flux column from which to compute; same as would be passed
954 to `~lsst.pipe.tasks.functors.Mag`.
957 Filters from which to compute magnitude difference.
958 Color computed is ``Mag(filt2) - Mag(filt1)``.
960 _defaultDataset =
'forced_src'
961 _dfLevels = (
'band',
'column')
967 raise RuntimeError(
"Cannot compute Color for %s: %s - %s " % (col, filt2, filt1))
985 mag2 = self.mag2.
_func(df[self.filt2])
986 mag1 = self.mag1.
_func(df[self.filt1])
991 return [self.
mag1.col, self.
mag2.col]
998 return f
'{self.filt2} - {self.filt1} ({self.col})'
1002 return f
"{self.col}_{self.filt2.replace('-', '')}m{self.filt1.replace('-', '')}"
1006 """This functor subtracts the trace of the PSF second moments from the
1007 trace of the second moments of the source.
1009 If the HsmShapeAlgorithm measurement is valid, then these will be used for
1011 Otherwise, the SdssShapeAlgorithm measurements will be used.
1013 name =
'Deconvolved Moments'
1014 shortname =
'deconvolvedMoments'
1015 _columns = (
"ext_shapeHSM_HsmSourceMoments_xx",
1016 "ext_shapeHSM_HsmSourceMoments_yy",
1017 "base_SdssShape_xx",
"base_SdssShape_yy",
1018 "ext_shapeHSM_HsmPsfMoments_xx",
1019 "ext_shapeHSM_HsmPsfMoments_yy")
1022 """Calculate deconvolved moments."""
1023 if "ext_shapeHSM_HsmSourceMoments_xx" in df.columns:
1024 hsm = df[
"ext_shapeHSM_HsmSourceMoments_xx"] + df[
"ext_shapeHSM_HsmSourceMoments_yy"]
1026 hsm = np.ones(len(df))*np.nan
1027 sdss = df[
"base_SdssShape_xx"] + df[
"base_SdssShape_yy"]
1028 if "ext_shapeHSM_HsmPsfMoments_xx" in df.columns:
1029 psf = df[
"ext_shapeHSM_HsmPsfMoments_xx"] + df[
"ext_shapeHSM_HsmPsfMoments_yy"]
1034 raise RuntimeError(
'No psf shape parameter found in catalog')
1036 return hsm.where(np.isfinite(hsm), sdss) - psf
1040 """Functor to calculate the SDSS trace radius size for sources.
1042 The SDSS trace radius size is a measure of size equal to the square root of
1043 half of the trace of the second moments tensor measured with the
1044 SdssShapeAlgorithm plugin.
1045 This has units of pixels.
1047 name =
"SDSS Trace Size"
1048 shortname =
'sdssTrace'
1049 _columns = (
"base_SdssShape_xx",
"base_SdssShape_yy")
1052 srcSize = np.sqrt(0.5*(df[
"base_SdssShape_xx"] + df[
"base_SdssShape_yy"]))
1057 """Functor to calculate the SDSS trace radius size difference (%) between
1058 the object and the PSF model.
1064 name =
"PSF - SDSS Trace Size"
1065 shortname =
'psf_sdssTrace'
1066 _columns = (
"base_SdssShape_xx",
"base_SdssShape_yy",
1067 "base_SdssShape_psf_xx",
"base_SdssShape_psf_yy")
1070 srcSize = np.sqrt(0.5*(df[
"base_SdssShape_xx"] + df[
"base_SdssShape_yy"]))
1071 psfSize = np.sqrt(0.5*(df[
"base_SdssShape_psf_xx"] + df[
"base_SdssShape_psf_yy"]))
1072 sizeDiff = 100*(srcSize - psfSize)/(0.5*(srcSize + psfSize))
1077 """Functor to calculate the HSM trace radius size for sources.
1079 The HSM trace radius size is a measure of size equal to the square root of
1080 half of the trace of the second moments tensor measured with the
1081 HsmShapeAlgorithm plugin.
1082 This has units of pixels.
1084 name =
'HSM Trace Size'
1085 shortname =
'hsmTrace'
1086 _columns = (
"ext_shapeHSM_HsmSourceMoments_xx",
1087 "ext_shapeHSM_HsmSourceMoments_yy")
1090 srcSize = np.sqrt(0.5*(df[
"ext_shapeHSM_HsmSourceMoments_xx"]
1091 + df[
"ext_shapeHSM_HsmSourceMoments_yy"]))
1096 """Functor to calculate the HSM trace radius size difference (%) between
1097 the object and the PSF model.
1103 name =
'PSF - HSM Trace Size'
1104 shortname =
'psf_HsmTrace'
1105 _columns = (
"ext_shapeHSM_HsmSourceMoments_xx",
1106 "ext_shapeHSM_HsmSourceMoments_yy",
1107 "ext_shapeHSM_HsmPsfMoments_xx",
1108 "ext_shapeHSM_HsmPsfMoments_yy")
1111 srcSize = np.sqrt(0.5*(df[
"ext_shapeHSM_HsmSourceMoments_xx"]
1112 + df[
"ext_shapeHSM_HsmSourceMoments_yy"]))
1113 psfSize = np.sqrt(0.5*(df[
"ext_shapeHSM_HsmPsfMoments_xx"]
1114 + df[
"ext_shapeHSM_HsmPsfMoments_yy"]))
1115 sizeDiff = 100*(srcSize - psfSize)/(0.5*(srcSize + psfSize))
1120 """Functor to calculate the PSF FWHM with second moments measured from the
1121 HsmShapeAlgorithm plugin.
1123 This is in units of arcseconds, and assumes the hsc_rings_v1 skymap pixel
1124 scale of 0.168 arcseconds/pixel.
1128 This conversion assumes the PSF is Gaussian, which is not always the case.
1130 name =
'HSM Psf FWHM'
1131 _columns = (
'ext_shapeHSM_HsmPsfMoments_xx',
'ext_shapeHSM_HsmPsfMoments_yy')
1134 SIGMA2FWHM = 2*np.sqrt(2*np.log(2))
1138 0.5*(df[
'ext_shapeHSM_HsmPsfMoments_xx']
1139 + df[
'ext_shapeHSM_HsmPsfMoments_yy']))).astype(np.float32)
1143 r"""Calculate :math:`e_1` ellipticity component for sources, defined as:
1146 e_1 &= (I_{xx}-I_{yy})/(I_{xx}+I_{yy})
1152 name =
"Distortion Ellipticity (e1)"
1153 shortname =
"Distortion"
1167 return ((df[self.
colXX] - df[self.
colYY]) / (
1168 df[self.
colXX] + df[self.
colYY])).astype(np.float32)
1172 r"""Calculate :math:`e_2` ellipticity component for sources, defined as:
1175 e_2 &= 2I_{xy}/(I_{xx}+I_{yy})
1181 name =
"Ellipticity e2"
1194 return (2*df[self.
colXY] / (df[self.
colXX] + df[self.
colYY])).astype(np.float32)
1198 """Calculate the radius from the quadrupole moments.
1200 This returns the fourth root of the determinant of the second moments
1201 tensor, which has units of pixels.
1220 return ((df[self.
colXX]*df[self.
colYY] - df[self.
colXY]**2)**0.25).astype(np.float32)
1224 """Computations using the stored localWcs."""
1225 name =
"LocalWcsOperations"
1240 """Compute the dRA, dDec from dx, dy.
1244 x : `~pandas.Series`
1246 y : `~pandas.Series`
1248 cd11 : `~pandas.Series`
1249 [1, 1] element of the local Wcs affine transform.
1250 cd12 : `~pandas.Series`
1251 [1, 2] element of the local Wcs affine transform.
1252 cd21 : `~pandas.Series`
1253 [2, 1] element of the local Wcs affine transform.
1254 cd22 : `~pandas.Series`
1255 [2, 2] element of the local Wcs affine transform.
1260 RA and Dec conversion of x and y given the local Wcs.
1261 Returned units are in radians.
1265 If x and y are with respect to the CRVAL1, CRVAL2
1266 then this will return the RA, Dec for that WCS.
1268 return (x * cd11 + y * cd12, x * cd21 + y * cd22)
1271 """Compute the local pixel scale conversion.
1275 ra1 : `~pandas.Series`
1276 Ra of the first coordinate in radians.
1277 dec1 : `~pandas.Series`
1278 Dec of the first coordinate in radians.
1279 ra2 : `~pandas.Series`
1280 Ra of the second coordinate in radians.
1281 dec2 : `~pandas.Series`
1282 Dec of the second coordinate in radians.
1286 dist : `~pandas.Series`
1287 Distance on the sphere in radians.
1289 deltaDec = dec2 - dec1
1291 return 2 * np.arcsin(
1293 np.sin(deltaDec / 2) ** 2
1294 + np.cos(dec2) * np.cos(dec1) * np.sin(deltaRa / 2) ** 2))
1297 """Compute the distance on the sphere from x2, y1 to x1, y1.
1301 x1 : `~pandas.Series`
1303 y1 : `~pandas.Series`
1305 x2 : `~pandas.Series`
1307 y2 : `~pandas.Series`
1309 cd11 : `~pandas.Series`
1310 [1, 1] element of the local Wcs affine transform.
1311 cd12 : `~pandas.Series`
1312 [1, 2] element of the local Wcs affine transform.
1313 cd21 : `~pandas.Series`
1314 [2, 1] element of the local Wcs affine transform.
1315 cd22 : `~pandas.Series`
1316 [2, 2] element of the local Wcs affine transform.
1320 Distance : `~pandas.Series`
1321 Arcseconds per pixel at the location of the local WC.
1329 """Compute position angle (E of N) from (ra1, dec1) to (ra2, dec2).
1333 ra1 : iterable [`float`]
1334 RA of the first coordinate [radian].
1335 dec1 : iterable [`float`]
1336 Dec of the first coordinate [radian].
1337 ra2 : iterable [`float`]
1338 RA of the second coordinate [radian].
1339 dec2 : iterable [`float`]
1340 Dec of the second coordinate [radian].
1344 Position Angle: `~pandas.Series`
1349 (ra1, dec1) -> (ra2, dec2) is interpreted as the shorter way around the sphere
1351 For a separation of 0.0001 rad, the position angle is good to 0.0009 rad
1352 all over the sphere.
1356 position_angle = np.zeros(len(ra1))
1357 for i, (r1, d1, r2, d2)
in enumerate(zip(ra1, dec1, ra2, dec2)):
1360 bearing = point1.bearingTo(point2)
1361 pa_ref_angle =
geom.Angle(np.pi/2, geom.radians)
1362 pa = pa_ref_angle - bearing
1365 position_angle[i] = pa.asRadians()
1367 return pd.Series(position_angle)
1370 """Compute position angle (E of N) from detector angle (+y of +x).
1375 detector angle [radian]
1377 [1, 1] element of the local Wcs affine transform.
1379 [1, 2] element of the local Wcs affine transform.
1381 [2, 1] element of the local Wcs affine transform.
1383 [2, 2] element of the local Wcs affine transform.
1387 Position Angle: `~pandas.Series`
1400 """Compute the local pixel scale from the stored CDMatrix.
1412 """Compute the local pixel to scale conversion in arcseconds.
1416 cd11 : `~pandas.Series`
1417 [1, 1] element of the local Wcs affine transform in radians.
1418 cd11 : `~pandas.Series`
1419 [1, 1] element of the local Wcs affine transform in radians.
1420 cd12 : `~pandas.Series`
1421 [1, 2] element of the local Wcs affine transform in radians.
1422 cd21 : `~pandas.Series`
1423 [2, 1] element of the local Wcs affine transform in radians.
1424 cd22 : `~pandas.Series`
1425 [2, 2] element of the local Wcs affine transform in radians.
1429 pixScale : `~pandas.Series`
1430 Arcseconds per pixel at the location of the local WC.
1432 return 3600 * np.degrees(np.sqrt(np.fabs(cd11 * cd22 - cd12 * cd21)))
1442 """Convert a value in units of pixels to units of arcseconds."""
1460 return f
"{self.col}_asArcseconds"
1478 """Convert a value in units of pixels squared to units of arcseconds
1498 return f
"{self.col}_asArcsecondsSq"
1513 return df[self.
col] * pixScale * pixScale
1517 """Compute a position angle from a detector angle and the stored CDMatrix.
1521 position angle : degrees
1524 name =
"PositionAngle"
1536 super().
__init__(colCD_1_1, colCD_1_2, colCD_2_1, colCD_2_2, **kwargs)
1559 """Convert a detector angle error to a position angle error.
1563 position angle error : degrees
1566 name =
"PositionAngleErr"
1581 """Return the band used to seed multiband forced photometry.
1583 This functor is to be used on Object tables.
1584 It converts the boolean merge_measurements_{band} columns into a single
1585 string representing the first band for which merge_measurements_{band}
1588 Assumes the default priority order of i, r, z, y, g, u.
1590 name =
'Reference Band'
1591 shortname =
'refBand'
1593 band_order = (
"i",
"r",
"z",
"y",
"g",
"u")
1601 return [f
"merge_measurement_{band}" for band
in bands]
1603 def _func(self, df: pd.DataFrame) -> pd.Series:
1604 def getFilterAliasName(row):
1606 colName = row.idxmax()
1607 return colName.replace(
'merge_measurement_',
'')
1611 columns = [col
for col
in self.
columns if col
in df.columns]
1613 return df[columns].apply(getFilterAliasName, axis=1,
1614 result_type=
'reduce').astype(
'object')
1616 def __init__(self, bands: tuple[str] | list[str] |
None =
None, **kwargs):
1622 """Base class for Object table calibrated fluxes and magnitudes."""
1624 AB_FLUX_SCALE = (0 * u.ABmag).to_value(u.nJy)
1625 LOG_AB_FLUX_SCALE = 12.56
1626 FIVE_OVER_2LOG10 = 1.085736204758129569
1630 def __init__(self, colFlux, colFluxErr=None, **kwargs):
1646 return f
'mag_{self.col}'
1650 """Compute sqrt(a^2 + b^2) without under/overflow."""
1651 if np.abs(a) < np.abs(b):
1656 return np.abs(a) * np.sqrt(1. + q*q)
1659 """Convert instrumental flux to nanojanskys."""
1660 return (self.
AB_FLUX_SCALE * dn / fluxMag0).astype(np.float32)
1663 """Convert instrumental flux to AB magnitude."""
1664 with warnings.catch_warnings():
1665 warnings.filterwarnings(
'ignore',
r'invalid value encountered')
1666 warnings.filterwarnings(
'ignore',
r'divide by zero')
1667 return (-2.5 * np.log10(dn/fluxMag0)).astype(np.float32)
1670 """Convert instrumental flux error to nanojanskys."""
1671 retVal = self.
vhypot(dn * fluxMag0Err, dnErr * fluxMag0)
1673 return retVal.astype(np.float32)
1676 """Convert instrumental flux error to AB magnitude error."""
1677 retVal = self.
dn2fluxErr(dn, dnErr, fluxMag0, fluxMag0Err) / self.
dn2flux(dn, fluxMag0)
1682 """Convert instrumental flux to nanojanskys."""
1688 """Convert instrumental flux error to nanojanskys."""
1695 return pd.Series(retArr, index=df.index)
1699 """Base class for calibrating the specified instrument flux column using
1700 the local photometric calibration.
1705 Name of the instrument flux column.
1706 instFluxErrCol : `str`
1707 Name of the assocated error columns for ``instFluxCol``.
1708 photoCalibCol : `str`
1709 Name of local calibration column.
1710 photoCalibErrCol : `str`, optional
1711 Error associated with ``photoCalibCol``. Ignored and deprecated; will
1712 be removed after v29.
1719 logNJanskyToAB = (1 * u.nJy).to_value(u.ABmag)
1725 photoCalibErrCol=None,
1731 if photoCalibErrCol
is not None:
1732 warnings.warn(
"The photoCalibErrCol argument is deprecated and will be removed after v29.",
1733 category=FutureWarning)
1737 """Convert instrument flux to nanojanskys.
1741 instFlux : `~numpy.ndarray` or `~pandas.Series`
1742 Array of instrument flux measurements.
1743 localCalib : `~numpy.ndarray` or `~pandas.Series`
1744 Array of local photometric calibration estimates.
1748 calibFlux : `~numpy.ndarray` or `~pandas.Series`
1749 Array of calibrated flux measurements.
1751 return instFlux * localCalib
1754 """Convert instrument flux to nanojanskys.
1758 instFlux : `~numpy.ndarray` or `~pandas.Series`
1759 Array of instrument flux measurements. Ignored (accepted for
1760 backwards compatibility and consistency with magnitude-error
1761 calculation methods).
1762 instFluxErr : `~numpy.ndarray` or `~pandas.Series`
1763 Errors on associated ``instFlux`` values.
1764 localCalib : `~numpy.ndarray` or `~pandas.Series`
1765 Array of local photometric calibration estimates.
1766 localCalibErr : `~numpy.ndarray` or `~pandas.Series`, optional
1767 Errors on associated ``localCalib`` values. Ignored and deprecated;
1768 will be removed after v29.
1772 calibFluxErr : `~numpy.ndarray` or `~pandas.Series`
1773 Errors on calibrated flux measurements.
1776 if localCalibErr
is not None:
1777 warnings.warn(
"The localCalibErr argument is deprecated and will be removed after v29.",
1778 category=FutureWarning)
1779 return instFluxErr * localCalib
1782 """Convert instrument flux to nanojanskys.
1786 instFlux : `~numpy.ndarray` or `~pandas.Series`
1787 Array of instrument flux measurements.
1788 localCalib : `~numpy.ndarray` or `~pandas.Series`
1789 Array of local photometric calibration estimates.
1793 calibMag : `~numpy.ndarray` or `~pandas.Series`
1794 Array of calibrated AB magnitudes.
1799 """Convert instrument flux err to nanojanskys.
1803 instFlux : `~numpy.ndarray` or `~pandas.Series`
1804 Array of instrument flux measurements.
1805 instFluxErr : `~numpy.ndarray` or `~pandas.Series`
1806 Errors on associated ``instFlux`` values.
1807 localCalib : `~numpy.ndarray` or `~pandas.Series`
1808 Array of local photometric calibration estimates.
1809 localCalibErr : `~numpy.ndarray` or `~pandas.Series`, optional
1810 Errors on associated ``localCalib`` values. Ignored and deprecated;
1811 will be removed after v29.
1815 calibMagErr: `~numpy.ndarray` or `~pandas.Series`
1816 Error on calibrated AB magnitudes.
1819 if localCalibErr
is not None:
1820 warnings.warn(
"The localCalibErr argument is deprecated and will be removed after v29.",
1821 category=FutureWarning)
1827 """Compute calibrated fluxes using the local calibration value.
1829 This returns units of nanojanskys.
1838 return f
'flux_{self.instFluxCol}'
1846 """Compute calibrated flux errors using the local calibration value.
1848 This returns units of nanojanskys.
1857 return f
'fluxErr_{self.instFluxCol}'
1865 """Compute absolute mean of dipole fluxes.
1871 LocalDipoleMeanFluxErr
1873 LocalDipoleDiffFluxErr
1882 photoCalibErrCol=None,
1903 return f
'dipMeanFlux_{self.instFluxPosCol}_{self.instFluxNegCol}'
1911 """Compute the error on the absolute mean of dipole fluxes.
1919 LocalDipoleDiffFluxErr
1932 return f
'dipMeanFluxErr_{self.instFluxPosCol}_{self.instFluxNegCol}'
1939 """Compute the absolute difference of dipole fluxes.
1941 Calculated value is (abs(pos) - abs(neg)).
1948 LocalDipoleMeanFluxErr
1949 LocalDipoleDiffFluxErr
1960 return f
'dipDiffFlux_{self.instFluxPosCol}_{self.instFluxNegCol}'
1968 """Compute the error on the absolute difference of dipole fluxes.
1975 LocalDipoleMeanFluxErr
1989 return f
'dipDiffFluxErr_{self.instFluxPosCol}_{self.instFluxNegCol}'
1996 """Compute E(B-V) from dustmaps.sfd."""
1997 _defaultDataset =
'ref'
2004 with open(os.devnull,
"w")
as devnull:
2005 with redirect_stdout(devnull):
2006 from dustmaps.sfd
import SFDQuery
2012 coords = SkyCoord(df[
'coord_ra'].values * u.rad, df[
'coord_dec'].values * u.rad)
2013 ebv = self.
sfd(coords)
2014 return pd.Series(ebv, index=df.index).astype(
'float32')
2018 """Base class for functors that use shape moments and localWCS
2022 is_covariance : bool
2023 Whether the shape columns are terms of a covariance matrix. If False,
2024 they will be assumed to be terms of a correlation matrix instead.
2027 is_covariance: bool =
True
2057 """Return columns that are needed from the ref table."""
2065 r"""Return terms commonly used for ellipse parameterization conversions.
2072 Whether to compute the terms in sky coordinates.
2073 If False, XX, YY and XY moments are used instead of
2079 The sum of the diagonal terms of the covariance.
2081 The difference of the diagonal terms of the covariance.
2083 A term similar to the discriminant of the quadratic formula.
2088 t2 = xx_m_yy**2 + 4.0*(self.
sky_uv(df)
if sky
else self.
get_xy(df))**2
2092 return xx + yy, xx_m_yy, t2
2109 """Return the component of the moments tensor aligned with the RA axis, in radians."""
2115 return (CD_1_1*(i_xx*CD_1_1 + i_xy*CD_1_2)
2116 + CD_1_2*(i_xy*CD_1_1 + i_yy*CD_1_2))
2119 """Return the component of the moments tensor aligned with the dec axis, in radians."""
2125 return (CD_2_1*(i_xx*CD_2_1 + i_xy*CD_2_2)
2126 + CD_2_2*(i_xy*CD_2_1 + i_yy*CD_2_2))
2129 """Return the covariance of the moments tensor in ra, dec coordinates, in radians."""
2137 return ((CD_1_1 * i_xx + CD_1_2 * i_xy) * CD_2_1
2138 + (CD_1_1 * i_xy + CD_1_2 * i_yy) * CD_2_2)
2142 Calculate shear-type ellipticity parameter G1.
2148 denom = sky_uu + sky_vv + 2 * np.sqrt(sky_uu*sky_vv - sky_uv**2)
2149 return ((sky_uu - sky_vv) / denom).astype(np.float32)
2153 Calculate shear-type ellipticity parameter G2.
2155 This has the opposite sign as sky_uv in order to maintain consistency with the HSM moments
2162 denom = sky_uu + sky_vv + 2 * np.sqrt(sky_uu*sky_vv - sky_uv**2)
2163 return (-2*sky_uv / denom).astype(np.float32)
2168 return np.sqrt(0.5*(sky_uu + sky_vv)).astype(np.float32)
2172 """Rotate pixel moments Ixx,Iyy,Ixy into RA/dec frame and G1/G2 reduced
2173 shear parameterization"""
2174 _defaultDataset =
'meas'
2176 shortname =
"moments_g1"
2181 return pd.Series(sky_g1.astype(np.float32), index=df.index)
2185 """Rotate pixel moments Ixx,Iyy,Ixy into RA/dec frame and G1/G2 reduced
2186 shear parameterization"""
2187 _defaultDataset =
'meas'
2189 shortname =
"moments_g2"
2194 return pd.Series(sky_g2.astype(np.float32), index=df.index)
2198 """Trace radius size in arcseconds from pixel moments Ixx,Iyy,Ixy
2200 The trace radius size is a measure of size equal to the square root of
2201 half of the trace of the second moments tensor.
2203 _defaultDataset =
'meas'
2204 name =
"moments_trace"
2205 shortname =
"moments_trace"
2210 return pd.Series((sky_trace_radians*(180/np.pi)*3600).astype(np.float32), index=df.index)
2214 """Rotate pixel moments Ixx,Iyy,Ixy into ra,dec frame and arcseconds"""
2215 _defaultDataset =
'meas'
2217 shortname =
"moments_uu"
2220 sky_uu_radians = self.
sky_uu(df)
2222 return pd.Series((sky_uu_radians*((180/np.pi)*3600)**2).astype(np.float32), index=df.index)
2226 """MomentsIuuSky but from sigma_x, sigma_y, rho correlation terms."""
2227 is_covariance =
False
2231 """Rotate pixel moments Ixx,Iyy,Ixy into ra,dec frame and arcseconds"""
2232 _defaultDataset =
'meas'
2234 shortname =
"moments_vv"
2237 sky_vv_radians = self.
sky_vv(df)
2239 return pd.Series((sky_vv_radians*((180/np.pi)*3600)**2).astype(np.float32), index=df.index)
2243 """MomentsIvvSky but from sigma_x, sigma_y, rho correlation terms."""
2244 is_covariance =
False
2248 """Rotate pixel moments Ixx,Iyy,Ixy into ra,dec frame and arcseconds"""
2249 _defaultDataset =
'meas'
2251 shortname =
"moments_uv"
2254 sky_uv_radians = self.
sky_uv(df)
2256 return pd.Series((sky_uv_radians*((180/np.pi)*3600)**2).astype(np.float32), index=df.index)
2260 """MomentsIuvSky but from sigma_x, sigma_y, rho correlation terms."""
2261 is_covariance =
False
2265 """Compute position angle relative to ra,dec frame, in degrees, from Ixx,Iyy,Ixy pixel moments."""
2266 _defaultDataset =
'meas'
2267 name =
"moments_theta"
2268 shortname =
"moments_theta"
2274 theta = 0.5*np.arctan2(2*sky_uv, sky_uu - sky_vv)
2276 return pd.Series((np.degrees(np.array(theta))).astype(np.float32), index=df.index)
2280 """PositionAngleFromMoments but from sigma_x, sigma_y, rho correlation terms."""
2281 is_covariance =
False
2285 """Compute the semimajor axis length in arcseconds, from Ixx,Iyy,Ixy pixel moments."""
2286 _defaultDataset =
'meas'
2288 shortname =
"moments_a"
2293 a_radians = np.sqrt(0.5 * (xx_p_yy + np.sqrt(t2)))
2295 return pd.Series((np.degrees(a_radians)*3600).astype(np.float32), index=df.index)
2299 """SemimajorAxisFromMoments but from sigma_x, sigma_y, rho correlation terms."""
2300 is_covariance =
False
2304 """Compute the semiminor axis length in arcseconds, from Ixx,Iyy,Ixy pixel moments."""
2305 _defaultDataset =
'meas'
2307 shortname =
"moments_b"
2312 b_radians = np.sqrt(0.5 * (xx_p_yy - np.sqrt(t2)))
2314 return pd.Series((np.degrees(b_radians)*3600).astype(np.float32), index=df.index)
2318 """SemiminorAxisFromMoments but from sigma_x, sigma_y, rho correlation terms."""
2319 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)