LSST Applications g0265f82a02+0e5473021a,g02d81e74bb+0dd8ce4237,g1470d8bcf6+3ea6592b6f,g2079a07aa2+86d27d4dc4,g2305ad1205+5ca4c0b359,g295015adf3+d10818ec9d,g2a9a014e59+6f9be1b9cd,g2bbee38e9b+0e5473021a,g337abbeb29+0e5473021a,g3ddfee87b4+703ba97ebf,g487adcacf7+4fa16da234,g50ff169b8f+96c6868917,g52b1c1532d+585e252eca,g591dd9f2cf+ffa42b374e,g5a732f18d5+53520f316c,g64a986408d+0dd8ce4237,g858d7b2824+0dd8ce4237,g8a8a8dda67+585e252eca,g99cad8db69+d39438377f,g9ddcbc5298+9a081db1e4,ga1e77700b3+15fc3df1f7,ga8c6da7877+f1d96605c8,gb0e22166c9+60f28cb32d,gb6a65358fc+0e5473021a,gba4ed39666+c2a2e4ac27,gbb8dafda3b+e5339d463f,gc120e1dc64+da31e9920e,gc28159a63d+0e5473021a,gcf0d15dbbd+703ba97ebf,gdaeeff99f8+f9a426f77a,ge6526c86ff+889fc9d533,ge79ae78c31+0e5473021a,gee10cc3b42+585e252eca,gf18bd8381d+7268b93478,gff1a9f87cc+0dd8ce4237,w.2024.16
LSST Data Management Base Package
Loading...
Searching...
No Matches
Public Member Functions | Public Attributes | Static Public Attributes | Protected Attributes | List of all members
lsst.pipe.tasks.functors.CompositeFunctor Class Reference
Inheritance diagram for lsst.pipe.tasks.functors.CompositeFunctor:
lsst.pipe.tasks.functors.Functor

Public Member Functions

 __init__ (self, funcs, **kwargs)
 
 filt (self)
 
 filt (self, filt)
 
 update (self, new)
 
 columns (self)
 
 multilevelColumns (self, data, **kwargs)
 
 __call__ (self, data, **kwargs)
 
 renameCol (cls, col, renameRules)
 
 from_file (cls, filename, **kwargs)
 
 from_yaml (cls, translationDefinition, **kwargs)
 

Public Attributes

 funcDict
 
 filt
 
 name
 

Static Public Attributes

 dataset = None
 
str name = "CompositeFunctor"
 

Protected Attributes

 _filt
 

Detailed Description

Perform multiple calculations at once on a catalog.

The role of a `CompositeFunctor` is to group together computations from
multiple functors.
Instead of returning `~pandas.Series` a `CompositeFunctor` returns a
`~pandas.DataFrame`, with the column names being the keys of ``funcDict``.

The `columns` attribute of a `CompositeFunctor` is the union of all columns
in all the component functors.

A `CompositeFunctor` does not use a `_func` method itself; rather, when a
`CompositeFunctor` is called, all its columns are loaded at once, and the
resulting DataFrame is passed to the `_func` method of each component
functor.
This has the advantage of only doing I/O (reading from parquet file) once,
and works because each individual `_func` method of each component functor
does not care if there are *extra* columns in the DataFrame being passed;
only that it must contain *at least* the `columns` it expects.

An important and useful class method is `from_yaml`, which takes as an
argument the path to a YAML file specifying a collection of functors.

Parameters
----------
funcs : `dict` or `list`
    Dictionary or list of functors.
    If a list, then it will be converted into a dictonary according to the
    `.shortname` attribute of each functor.

Definition at line 377 of file functors.py.

Constructor & Destructor Documentation

◆ __init__()

lsst.pipe.tasks.functors.CompositeFunctor.__init__ ( self,
funcs,
** kwargs )

Reimplemented from lsst.pipe.tasks.functors.Functor.

Definition at line 410 of file functors.py.

410 def __init__(self, funcs, **kwargs):
411
412 if type(funcs) == dict:
413 self.funcDict = funcs
414 else:
415 self.funcDict = {f.shortname: f for f in funcs}
416
417 self._filt = None
418
419 super().__init__(**kwargs)
420

Member Function Documentation

◆ __call__()

lsst.pipe.tasks.functors.CompositeFunctor.__call__ ( self,
data,
** kwargs )
Apply the functor to the data table.

Parameters
----------
data : various
    The data represented as `~lsst.daf.butler.DeferredDatasetHandle`,
    `~lsst.pipe.base.InMemoryDatasetHandle`, or `~pandas.DataFrame`.
    The table or a pointer to a table on disk from which columns can
    be accessed.

Reimplemented from lsst.pipe.tasks.functors.Functor.

Definition at line 464 of file functors.py.

464 def __call__(self, data, **kwargs):
465 """Apply the functor to the data table.
466
467 Parameters
468 ----------
469 data : various
470 The data represented as `~lsst.daf.butler.DeferredDatasetHandle`,
471 `~lsst.pipe.base.InMemoryDatasetHandle`, or `~pandas.DataFrame`.
472 The table or a pointer to a table on disk from which columns can
473 be accessed.
474 """
475 if isinstance(data, pd.DataFrame):
476 _data = InMemoryDatasetHandle(data, storageClass="DataFrame")
477 elif isinstance(data, (DeferredDatasetHandle, InMemoryDatasetHandle)):
478 _data = data
479 else:
480 raise RuntimeError(f"Unexpected type provided for data. Got {get_full_type_name(data)}.")
481
482 columnIndex = self._get_columnIndex(_data)
483
484 if isinstance(columnIndex, pd.MultiIndex):
485 columns = self.multilevelColumns(_data, columnIndex=columnIndex)
486 df = _data.get(parameters={"columns": columns})
487
488 valDict = {}
489 for k, f in self.funcDict.items():
490 try:
491 subdf = f._setLevels(
492 df[f.multilevelColumns(_data, returnTuple=True, columnIndex=columnIndex)]
493 )
494 valDict[k] = f._func(subdf)
495 except Exception as e:
496 self.log.exception(
497 "Exception in %s (funcs: %s) call: %s",
498 self.name,
499 str(list(self.funcDict.keys())),
500 type(e).__name__,
501 )
502 try:
503 valDict[k] = f.fail(subdf)
504 except NameError:
505 raise e
506
507 else:
508 df = _data.get(parameters={"columns": self.columns})
509
510 valDict = {k: f._func(df) for k, f in self.funcDict.items()}
511
512 # Check that output columns are actually columns.
513 for name, colVal in valDict.items():
514 if len(colVal.shape) != 1:
515 raise RuntimeError("Transformed column '%s' is not the shape of a column. "
516 "It is shaped %s and type %s." % (name, colVal.shape, type(colVal)))
517
518 try:
519 valDf = pd.concat(valDict, axis=1)
520 except TypeError:
521 print([(k, type(v)) for k, v in valDict.items()])
522 raise
523
524 if kwargs.get('dropna', False):
525 valDf = valDf.dropna(how='any')
526
527 return valDf
528
std::vector< SchemaItem< Flag > > * items

◆ columns()

lsst.pipe.tasks.functors.CompositeFunctor.columns ( self)
Columns required to perform calculation.

Reimplemented from lsst.pipe.tasks.functors.Functor.

Definition at line 446 of file functors.py.

446 def columns(self):
447 return list(set([x for y in [f.columns for f in self.funcDict.values()] for x in y]))
448
daf::base::PropertySet * set
Definition fits.cc:931

◆ filt() [1/2]

lsst.pipe.tasks.functors.CompositeFunctor.filt ( self)

Reimplemented from lsst.pipe.tasks.functors.Functor.

Definition at line 422 of file functors.py.

422 def filt(self):
423 return self._filt
424

◆ filt() [2/2]

lsst.pipe.tasks.functors.CompositeFunctor.filt ( self,
filt )

Reimplemented from lsst.pipe.tasks.functors.Functor.

Definition at line 426 of file functors.py.

426 def filt(self, filt):
427 if filt is not None:
428 for _, f in self.funcDict.items():
429 f.filt = filt
430 self._filt = filt
431

◆ from_file()

lsst.pipe.tasks.functors.CompositeFunctor.from_file ( cls,
filename,
** kwargs )

Definition at line 539 of file functors.py.

539 def from_file(cls, filename, **kwargs):
540 # Allow environment variables in the filename.
541 filename = os.path.expandvars(filename)
542 with open(filename) as f:
543 translationDefinition = yaml.safe_load(f)
544
545 return cls.from_yaml(translationDefinition, **kwargs)
546

◆ from_yaml()

lsst.pipe.tasks.functors.CompositeFunctor.from_yaml ( cls,
translationDefinition,
** kwargs )

Definition at line 548 of file functors.py.

548 def from_yaml(cls, translationDefinition, **kwargs):
549 funcs = {}
550 for func, val in translationDefinition['funcs'].items():
551 funcs[func] = init_fromDict(val, name=func)
552
553 if 'flag_rename_rules' in translationDefinition:
554 renameRules = translationDefinition['flag_rename_rules']
555 else:
556 renameRules = None
557
558 if 'calexpFlags' in translationDefinition:
559 for flag in translationDefinition['calexpFlags']:
560 funcs[cls.renameCol(flag, renameRules)] = Column(flag, dataset='calexp')
561
562 if 'refFlags' in translationDefinition:
563 for flag in translationDefinition['refFlags']:
564 funcs[cls.renameCol(flag, renameRules)] = Column(flag, dataset='ref')
565
566 if 'forcedFlags' in translationDefinition:
567 for flag in translationDefinition['forcedFlags']:
568 funcs[cls.renameCol(flag, renameRules)] = Column(flag, dataset='forced_src')
569
570 if 'flags' in translationDefinition:
571 for flag in translationDefinition['flags']:
572 funcs[cls.renameCol(flag, renameRules)] = Column(flag, dataset='meas')
573
574 return cls(funcs, **kwargs)
575
576

◆ multilevelColumns()

lsst.pipe.tasks.functors.CompositeFunctor.multilevelColumns ( self,
data,
** columnIndex )
Returns columns needed by functor from multilevel dataset.

To access tables with multilevel column structure, the
`~lsst.daf.butler.DeferredDatasetHandle` or
`~lsst.pipe.base.InMemoryDatasetHandle` needs to be passed
either a list of tuples or a dictionary.

Parameters
----------
data : various
    The data as either `~lsst.daf.butler.DeferredDatasetHandle`, or
    `~lsst.pipe.base.InMemoryDatasetHandle`.
columnIndex (optional): pandas `~pandas.Index` object
    Either passed or read in from
    `~lsst.daf.butler.DeferredDatasetHandle`.
`returnTuple` : `bool`
    If true, then return a list of tuples rather than the column
    dictionary specification.
    This is set to `True` by `CompositeFunctor` in order to be able to
    combine columns from the various component functors.

Reimplemented from lsst.pipe.tasks.functors.Functor.

Definition at line 449 of file functors.py.

449 def multilevelColumns(self, data, **kwargs):
450 # Get the union of columns for all component functors.
451 # Note the need to have `returnTuple=True` here.
452 return list(
453 set(
454 [
455 x
456 for y in [
457 f.multilevelColumns(data, returnTuple=True, **kwargs) for f in self.funcDict.values()
458 ]
459 for x in y
460 ]
461 )
462 )
463

◆ renameCol()

lsst.pipe.tasks.functors.CompositeFunctor.renameCol ( cls,
col,
renameRules )

Definition at line 530 of file functors.py.

530 def renameCol(cls, col, renameRules):
531 if renameRules is None:
532 return col
533 for old, new in renameRules:
534 if col.startswith(old):
535 col = col.replace(old, new)
536 return col
537

◆ update()

lsst.pipe.tasks.functors.CompositeFunctor.update ( self,
new )
Update the functor with new functors.

Definition at line 432 of file functors.py.

432 def update(self, new):
433 """Update the functor with new functors."""
434 if isinstance(new, dict):
435 self.funcDict.update(new)
436 elif isinstance(new, CompositeFunctor):
437 self.funcDict.update(new.funcDict)
438 else:
439 raise TypeError('Can only update with dictionary or CompositeFunctor.')
440
441 # Make sure new functors have the same 'filt' set.
442 if self.filt is not None:
443 self.filt = self.filt
444

Member Data Documentation

◆ _filt

lsst.pipe.tasks.functors.CompositeFunctor._filt
protected

Definition at line 417 of file functors.py.

◆ dataset

lsst.pipe.tasks.functors.CompositeFunctor.dataset = None
static

Definition at line 407 of file functors.py.

◆ filt

lsst.pipe.tasks.functors.CompositeFunctor.filt

Definition at line 443 of file functors.py.

◆ funcDict

lsst.pipe.tasks.functors.CompositeFunctor.funcDict

Definition at line 413 of file functors.py.

◆ name [1/2]

str lsst.pipe.tasks.functors.CompositeFunctor.name = "CompositeFunctor"
static

Definition at line 408 of file functors.py.

◆ name [2/2]

lsst.pipe.tasks.functors.CompositeFunctor.name

Definition at line 498 of file functors.py.


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