LSSTApplications  17.0+10,17.0+51,17.0+88,18.0.0+10,18.0.0+15,18.0.0+34,18.0.0+4,18.0.0+6,18.0.0-2-ge43143a+6,18.1.0-1-g0001055+2,18.1.0-1-g0896a44+10,18.1.0-1-g1349e88+9,18.1.0-1-g2505f39+7,18.1.0-1-g380d4d4+9,18.1.0-1-g5e4b7ea+2,18.1.0-1-g7e8fceb,18.1.0-1-g85f8cd4+7,18.1.0-1-g9a6769a+3,18.1.0-1-ga1a4c1a+6,18.1.0-1-gc037db8+2,18.1.0-1-gd55f500+3,18.1.0-1-ge10677a+7,18.1.0-10-g73b8679e+12,18.1.0-12-gf30922b,18.1.0-13-g451e75588,18.1.0-13-gbfe7f7f,18.1.0-2-g31c43f9+7,18.1.0-2-g9c63283+9,18.1.0-2-gdf0b915+9,18.1.0-2-gf03bb23+2,18.1.0-3-g52aa583+3,18.1.0-3-g8f4a2b1+1,18.1.0-3-g9cb968e+8,18.1.0-4-g7bbbad0,18.1.0-5-g510c42a+8,18.1.0-5-ga46117f,18.1.0-5-gaeab27e+9,18.1.0-6-gdda7f3e+11,18.1.0-8-g4084bf03+1,w.2019.34
LSSTDataManagementBasePackage
config.py
Go to the documentation of this file.
1 # This file is part of pipe_base.
2 #
3 # Developed for the LSST Data Management System.
4 # This product includes software developed by the LSST Project
5 # (http://www.lsst.org).
6 # See the COPYRIGHT file at the top-level directory of this distribution
7 # for details of code ownership.
8 #
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 
22 """Module defining config classes for PipelineTask.
23 """
24 
25 __all__ = ["InputDatasetConfig", "InputDatasetField",
26  "OutputDatasetConfig", "OutputDatasetField",
27  "InitInputDatasetConfig", "InitInputDatasetField",
28  "InitOutputDatasetConfig", "InitOutputDatasetField",
29  "ResourceConfig", "QuantumConfig", "PipelineTaskConfig"]
30 
31 # -------------------------------
32 # Imports of standard modules --
33 # -------------------------------
34 from textwrap import dedent, indent
35 
36 # -----------------------------
37 # Imports for other modules --
38 # -----------------------------
39 import lsst.pex.config as pexConfig
40 
41 # ----------------------------------
42 # Local non-exported definitions --
43 # ----------------------------------
44 
45 # ------------------------
46 # Exported definitions --
47 # ------------------------
48 
49 PIPELINETASK_CONFIG_TEMPLATE_DICT = {}
50 
51 
52 def _makeDatasetField(name, dtype):
53  """ Function to make callables which produce ConfigField objects
54 
55  This is factory function which produces factory functions. The factories
56  returned by this function are used to simplify the process of creating
57  `lsst.pex.config.ConfigField` which have dtypes derived from either
58  `_DatasetTypeConfig`, or `_GlobalDatasetTypeConfig`. These functions can
59  then be used in a mannor similar to other `~lsst.pex.config.ConfigField`
60  constructors.
61 
62  Below is a flow diagram to explain the use of this function visually,
63  where arrows indicate processing flow.
64 
65  Make a ConfigField factory:
66  _makeDatasetField() -> return wrappedFunc -> assign to variable corresponding
67  to name
68 
69  Use a ConfigField factory:
70  name() -> factory() -> return pexConfig instance
71 
72  Example
73  -------
74  FooField = _makeDatasetField("FooField", FooConfig)
75  fooFieldInstance = FooField("An example Foo ConfigField",
76  "fooConfigurable",
77  ("tract", "patch"),
78  "Exposure")
79 
80  Parameters
81  ----------
82  name : `str`
83  The name to use as the final output `~lsst.pex.config.Field`
84  constructor
85  dtype : Configuration Object
86  This is the python type to set as the dtype in the ConfigField
87  construction
88 
89  Returns
90  -------
91  func : function
92  Python callable function which can be used to produce instances of
93  `~lsst.pex.config.ConfigField` of type dtype.
94 
95  Raises
96  ------
97  TypeError
98  Possibly raises a TypeError if attempting to create a factory function
99  from an incompatible type
100  """
101 
102  def factory(**kwargs):
103  """ This is the innermost function in the closure, and does the work
104  of actually producing the ConfigField
105  """
106  # kwargs contain all the variables needed to construct the ConfigField
107  # The doc and check variables are used to construct the ConfigField,
108  # while the rest are used in the construction of the dtype object,
109  # which is why doc and check are filted out before unpacking the
110  # dictionary to the dtype constructor.
111  return pexConfig.ConfigField(doc=kwargs['doc'],
112  dtype=dtype,
113  default=dtype(
114  **{k: v for k, v in kwargs.items()
115  if k not in ('doc', 'check')}),
116  check=kwargs['check'])
117 
118  # here the dtype is checked against its baseclass type. This is due to the fact
119  # the code nesseary to make ConfigField factories is shared, but the arguments
120  # the factories take differ between base class types
121  if issubclass(dtype, _GlobalDatasetTypeConfig):
122  # Handle global dataset types like InitInputDatasetConfig, these types have
123  # a function signature with no dimensions variable
124  def wrappedFunc(*, doc, storageClass, check=None, name="", nameTemplate=''):
125  return factory(**{k: v for k, v in locals().items() if k != 'factory'})
126  # This factory does not take a dimensions argument, so set the
127  # variables for the dimensions documentation to empty python strings
128  extraDoc = ""
129  extraFields = ""
130  elif issubclass(dtype, _DatasetTypeConfig):
131  # Handle dataset types like InputDatasetConfig, note these take a dimensions argument
132  def wrappedFunc(*, doc, dimensions, storageClass, name="", scalar=False, check=None, nameTemplate='',
133  manualLoad=False):
134  return factory(**{k: v for k, v in locals().items() if k != 'factory'})
135  # Set the string corresponding to the dimensions parameter documentation
136  # formatting is to support final output of the docstring variable
137  extraDoc = """
138  dimensions : iterable of `str`
139  Iterable of Dimensions for this `~lsst.daf.butler.DatasetType`
140  scalar : `bool`, optional
141  If set to True then only a single dataset is expected on input or
142  produced on output. In that case list of objects/DataIds will be
143  unpacked before calling task methods, returned data is expected
144  to contain single objects as well.
145  nameTemplate : `str`, optional
146  Template for the `name` field which is specified as a python formattable
147  string. The template is formatted during the configuration of a Config
148  class with a user defined string. Defaults to empty string, in which
149  case no formatting is done.
150  manualLoad : `bool`
151  Indicates runQuantum will not load the data from the butler, and that
152  the task intends to do the loading itself. Defaults to False
153  """
154  # Set a string to add the dimensions argument to the list of arguments in the
155  # docstring explanation section formatting is to support final output
156  # of the docstring variable
157  extraFields = ", dimensions, scalar, nameTemplate, manualLoad"
158  else:
159  # if someone tries to create a config factory for a type that is not
160  # handled raise and exception
161  raise TypeError(f"Cannot create a factory for dtype {dtype}")
162 
163  # Programatically create a docstring to use in the factory function
164  docstring = f""" Factory function to create `~lsst.pex.config.Config` class instances
165  of `{dtype.__name__}`
166 
167  This function servers as syntactic sugar for creating
168  `~lsst.pex.config.ConfigField` which are `{dtype.__name__}`. The naming of
169  this function violates the normal convention of a lowercase first letter
170  in the function name, as this function is intended to sit in the same
171  place as `~lsst.pex.config.ConfigField` classes, and consistency in
172  declaration syntax is important.
173 
174  The input arguments for this class are a combination of the arguments for
175  `~lsst.pex.config.ConfigField` and `{dtype.__name__}`. The arguments
176  doc and check come from `~lsst.pex.config.ConfigField`, while name{extraFields}
177  and storageClass come from `{dtype.__name__}`.
178 
179  Parameters
180  ----------
181  doc : `str`
182  Documentation string for the `{dtype.__name__}`
183  name : `str`
184  Name of the `~lsst.daf.butler.DatasetType` in the returned
185  `{dtype.__name__}`{indent(dedent(extraDoc), " " * 4)}
186  storageClass : `str`
187  Name of the `~lsst.daf.butler.StorageClass` in the `{dtype.__name__}`
188  check : callable
189  A callable to be called with the field value that returns
190  False if the value is invalid.
191 
192  Returns
193  -------
194  result : `~lsst.pex.config.ConfigField`
195  Instance of a `~lsst.pex.config.ConfigField` with `InputDatasetConfig` as a dtype
196  """
197  # Set the name to be used for the returned ConfigField factory function
198  wrappedFunc.__name__ = name
199  # Set the name to be used for the returned ConfigField factory function, and unindent
200  # the docstring as it was indednted to corrispond to this factory functions indention
201  wrappedFunc.__doc__ = dedent(docstring)
202  return wrappedFunc
203 
204 
205 class QuantumConfig(pexConfig.Config):
206  """Configuration class which defines PipelineTask quanta dimensions.
207 
208  In addition to a list of dataUnit names this also includes optional list of
209  SQL statements to be executed against Registry database. Exact meaning and
210  format of SQL will be determined at later point.
211  """
212  dimensions = pexConfig.ListField(dtype=str,
213  doc="list of Dimensions which define quantum")
214  sql = pexConfig.ListField(dtype=str,
215  doc="sequence of SQL statements",
216  optional=True)
217 
218 
219 class _BaseDatasetTypeConfig(pexConfig.Config):
220  """Intermediate base class for dataset type configuration in PipelineTask.
221  """
222  name = pexConfig.Field(dtype=str,
223  doc="name of the DatasetType")
224  storageClass = pexConfig.Field(dtype=str,
225  doc="name of the StorageClass")
226  nameTemplate = pexConfig.Field(dtype=str,
227  default='',
228  optional=True,
229  doc=("Templated name of string, used to set name "
230  "field according to a shared substring when "
231  "`~PipelineTaskConfig.formatTemplateNames` "
232  "is called"))
233 
234 
236  """Configuration class which defines dataset type used by PipelineTask.
237 
238  Consists of DatasetType name, list of Dimension names and StorageCass name.
239  PipelineTasks typically define one or more input and output datasets. This
240  class should not be used directly, instead one of `InputDatasetConfig` or
241  `OutputDatasetConfig` should be used in PipelineTask config.
242  """
243  dimensions = pexConfig.ListField(dtype=str,
244  doc="list of Dimensions for this DatasetType")
245  scalar = pexConfig.Field(dtype=bool,
246  default=False,
247  optional=True,
248  doc=("If set to True then only a single dataset is expected "
249  "on input or produced on output. In that case list of "
250  "objects/DataIds will be unpacked before calling task "
251  "methods, returned data is expected to contain single "
252  "objects as well."))
253  manualLoad = pexConfig.Field(dtype=bool,
254  default=False,
255  optional=True,
256  doc=("If this is set to True, the class intends to load "
257  "the data associated with this Configurable Field "
258  "manually, and runQuantum should not load it. Should "
259  "not be set by configuration override"))
260 
261 
263  pass
264 
265 
266 class OutputDatasetConfig(_DatasetTypeConfig):
267  pass
268 
269 
271  """Configuration class which defines dataset types used in PipelineTask
272  initialization.
273 
274  Consists of DatasetType name and StorageCass name, with a read-only
275  ``dimensions`` property that returns an empty tuple, enforcing the
276  constraint that datasets used in initialization are not associated with
277  any Dimensions. This class should not be used directly, instead one of
278  `InitInputDatasetConfig` or `InitOutputDatasetConfig` should be used in
279  PipelineTask config.
280  """
281  @property
282  def dimensions(self):
283  """Dimensions associated with this DatasetType (always empty)."""
284  return ()
285 
286 
288  pass
289 
290 
291 class InitOutputDatasetConfig(_GlobalDatasetTypeConfig):
292  pass
293 
294 
295 class ResourceConfig(pexConfig.Config):
296  """Configuration for resource requirements.
297 
298  This configuration class will be used by some activators to estimate
299  resource use by pipeline. Additionally some tasks could use it to adjust
300  their resource use (e.g. reduce the number of threads).
301 
302  For some resources their limit can be estimated by corresponding task,
303  in that case task could set the field value. For many fields defined in
304  this class their associated resource used by a task will depend on the
305  size of the data and is not known in advance. For these resources their
306  value will be configured through overrides based on some external
307  estimates.
308  """
309  minMemoryMB = pexConfig.Field(dtype=int, default=None, optional=True,
310  doc="Minimal memory needed by task, can be None if estimate is unknown.")
311  minNumCores = pexConfig.Field(dtype=int, default=1,
312  doc="Minimal number of cores needed by task.")
313 
314 
315 class PipelineTaskConfig(pexConfig.Config):
316  """Base class for all PipelineTask configurations.
317 
318  This class defines fields that must be defined for every
319  `~lsst.pipe.base.PipelineTask`. It will be used as a base class for all
320  `~lsst.pipe.base.PipelineTask` configurations instead of
321  `pex.config.Config`.
322  """
323  quantum = pexConfig.ConfigField(dtype=QuantumConfig,
324  doc="configuration for PipelineTask quantum")
325 
326  def formatTemplateNames(self, templateParamsDict):
327  # Look up the stored parameters for the specific instance of this config
328  # class
329  storedParamsDict = PIPELINETASK_CONFIG_TEMPLATE_DICT.setdefault(id(self), {})
330  storedParamsDict.update(templateParamsDict)
331  for key, value in self.items():
332  if isinstance(value, _BaseDatasetTypeConfig) and value.nameTemplate != '':
333  value.name = value.nameTemplate.format(**storedParamsDict)
334 
335 
336 InputDatasetField = _makeDatasetField("InputDatasetField", InputDatasetConfig)
337 OutputDatasetField = _makeDatasetField("OutputDatasetField", OutputDatasetConfig)
338 InitInputDatasetField = _makeDatasetField("InitInputDatasetField", InitInputDatasetConfig)
339 InitOutputDatasetField = _makeDatasetField("InitOutputDatasetField", InitOutputDatasetConfig)
std::vector< SchemaItem< Flag > > * items
table::Key< int > id
Definition: Detector.cc:166
def formatTemplateNames(self, templateParamsDict)
Definition: config.py:326