lsst-pipe-base 29.2025.1900__py3-none-any.whl → 29.2025.2100__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -48,7 +48,7 @@ from lsst.daf.butler import (
48
48
  DimensionRecordSet,
49
49
  MissingDatasetTypeError,
50
50
  )
51
- from lsst.utils.logging import LsstLogAdapter
51
+ from lsst.utils.logging import LsstLogAdapter, PeriodicLogger
52
52
  from lsst.utils.timer import timeMethod
53
53
 
54
54
  from ._datasetQueryConstraints import DatasetQueryConstraintVariant
@@ -215,17 +215,26 @@ class AllDimensionsQuantumGraphBuilder(QuantumGraphBuilder):
215
215
  # Allow duplicates from common skypix overlaps to make some queries
216
216
  # run faster.
217
217
  query._allow_duplicate_overlaps = True
218
- self.log.info("Iterating over query results to associate quanta with datasets.")
219
218
  # Iterate over query results, populating data IDs for datasets,
220
219
  # quanta, and edges. We populate only the first level of the tree
221
220
  # in the first pass, so we can be done with the query results as
222
221
  # quickly as possible in case that holds a connection/cursor open.
223
222
  n_rows = 0
223
+ progress_logger: PeriodicLogger | None = None
224
224
  for common_data_id in query.data_ids(tree.all_dimensions):
225
+ if progress_logger is None:
226
+ # There can be a long wait between submitting the query and
227
+ # returning the first row, so we want to make sure we log
228
+ # when we get it; note that PeriodicLogger is not going to
229
+ # do that for us, as it waits for its interval _after_ the
230
+ # first log is seen.
231
+ self.log.info("Iterating over data ID query results.")
232
+ progress_logger = PeriodicLogger(self.log)
225
233
  for branch_dimensions, branch in tree.trunk_branches.items():
226
234
  data_id = common_data_id.subset(branch_dimensions)
227
235
  branch.data_ids.add(data_id)
228
236
  n_rows += 1
237
+ progress_logger.log("Iterating over data ID query results: %d rows processed so far.", n_rows)
229
238
  if n_rows == 0:
230
239
  # A single multiline log plays better with log aggregators like
231
240
  # Loki.
@@ -242,7 +251,7 @@ class AllDimensionsQuantumGraphBuilder(QuantumGraphBuilder):
242
251
  # If an exception was raised, write a partial.
243
252
  self.log.error("\n".join(lines))
244
253
  return
245
- self.log.verbose("Processed %s initial data ID query rows.", n_rows)
254
+ self.log.verbose("Done iterating over query results: %d rows processed in total.", n_rows)
246
255
  # We now recursively populate the data IDs of the rest of the tree.
247
256
  tree.project_data_ids(self.log)
248
257
 
@@ -61,6 +61,7 @@ def register_instrument(*args: Any, **kwargs: Any) -> None:
61
61
  @click.option(
62
62
  "--dry-run", is_flag=True, default=False, help="Run the transfer but do not update the destination butler"
63
63
  )
64
+ @dataset_type_option(help="Subset of dataset types to transfer from graph.")
64
65
  @options_file_option()
65
66
  def transfer_from_graph(**kwargs: Any) -> None:
66
67
  """Transfer datasets from a quantum graph to a destination butler.
@@ -31,6 +31,8 @@ from lsst.daf.butler import Butler, CollectionType, QuantumBackedButler, Registr
31
31
  from lsst.daf.butler.registry import MissingCollectionError
32
32
  from lsst.pipe.base import QuantumGraph
33
33
 
34
+ from .utils import filter_by_dataset_type_glob
35
+
34
36
 
35
37
  def transfer_from_graph(
36
38
  graph: str,
@@ -39,6 +41,7 @@ def transfer_from_graph(
39
41
  transfer_dimensions: bool,
40
42
  update_output_chain: bool,
41
43
  dry_run: bool,
44
+ dataset_type: tuple[str, ...],
42
45
  ) -> int:
43
46
  """Transfer output datasets from quantum graph to dest.
44
47
 
@@ -60,6 +63,9 @@ def transfer_from_graph(
60
63
  name as a the first collection in the chain.
61
64
  dry_run : `bool`
62
65
  Run the transfer without updating the destination butler.
66
+ dataset_type : `tuple` of `str`
67
+ Dataset type names. An empty tuple implies all dataset types.
68
+ Can include globs.
63
69
 
64
70
  Returns
65
71
  -------
@@ -84,11 +90,14 @@ def transfer_from_graph(
84
90
  dataset_types=dataset_types,
85
91
  )
86
92
 
93
+ # Filter the refs based on requested dataset types.
94
+ filtered_refs = filter_by_dataset_type_glob(output_refs, dataset_type)
95
+
87
96
  dest_butler = Butler.from_config(dest, writeable=True)
88
97
 
89
98
  transferred = dest_butler.transfer_from(
90
99
  qbb,
91
- output_refs,
100
+ filtered_refs,
92
101
  transfer="auto",
93
102
  register_dataset_types=register_dataset_types,
94
103
  transfer_dimensions=transfer_dimensions,
@@ -0,0 +1,74 @@
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 software is dual licensed under the GNU General Public License and also
10
+ # under a 3-clause BSD license. Recipients may choose which of these licenses
11
+ # to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12
+ # respectively. If you choose the GPL option then the following text applies
13
+ # (but note that there is still no warranty even if you opt for BSD instead):
14
+ #
15
+ # This program is free software: you can redistribute it and/or modify
16
+ # it under the terms of the GNU General Public License as published by
17
+ # the Free Software Foundation, either version 3 of the License, or
18
+ # (at your option) any later version.
19
+ #
20
+ # This program is distributed in the hope that it will be useful,
21
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
+ # GNU General Public License for more details.
24
+ #
25
+ # You should have received a copy of the GNU General Public License
26
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
27
+
28
+ from __future__ import annotations
29
+
30
+ __all__ = [
31
+ "filter_by_dataset_type_glob",
32
+ ]
33
+
34
+ import re
35
+ from collections.abc import Collection
36
+
37
+ from lsst.daf.butler import DatasetRef
38
+ from lsst.daf.butler.utils import globToRegex
39
+
40
+
41
+ def _matches_dataset_type(dataset_type_name: str, regexes: list[str | re.Pattern]) -> bool:
42
+ for regex in regexes:
43
+ if isinstance(regex, str):
44
+ if dataset_type_name == regex:
45
+ return True
46
+ elif regex.search(dataset_type_name):
47
+ return True
48
+ return False
49
+
50
+
51
+ def filter_by_dataset_type_glob(
52
+ refs: Collection[DatasetRef], dataset_types: tuple[str, ...]
53
+ ) -> Collection[DatasetRef]:
54
+ """Filter the refs based on requested dataset types.
55
+
56
+ Parameters
57
+ ----------
58
+ refs : `collections.abc.Collection` [ `lsst.daf.butler.DatasetRef` ]
59
+ Datasets to be filtered.
60
+ dataset_types : `tuple` [ `str`, ...]
61
+ Dataset type names or globs to use for filtering. Empty tuple implies
62
+ no filtering.
63
+
64
+ Returns
65
+ -------
66
+ filtered : `collections.abc.Collection` [ `lsst.daf.butler.DatasetRef` ]
67
+ Filter datasets.
68
+ """
69
+ regexes = globToRegex(dataset_types)
70
+ if regexes is ...:
71
+ # Nothing to do.
72
+ return refs
73
+
74
+ return {ref for ref in refs if _matches_dataset_type(ref.datasetType.name, regexes)}
@@ -28,13 +28,13 @@
28
28
  __all__ = ["zip_from_graph"]
29
29
 
30
30
  import logging
31
- import re
32
31
 
33
32
  from lsst.daf.butler import QuantumBackedButler
34
- from lsst.daf.butler.utils import globToRegex
35
33
  from lsst.pipe.base import QuantumGraph
36
34
  from lsst.resources import ResourcePath
37
35
 
36
+ from .utils import filter_by_dataset_type_glob
37
+
38
38
  _LOG = logging.getLogger(__name__)
39
39
 
40
40
 
@@ -83,22 +83,8 @@ def zip_from_graph(
83
83
  )
84
84
 
85
85
  # Filter the refs based on requested dataset types.
86
- regexes = globToRegex(dataset_type)
87
- if regexes is ...:
88
- filtered_refs = output_refs
89
- else:
90
-
91
- def _matches(dataset_type_name: str, regexes: list[str | re.Pattern]) -> bool:
92
- for regex in regexes:
93
- if isinstance(regex, str):
94
- if dataset_type_name == regex:
95
- return True
96
- elif regex.search(dataset_type_name):
97
- return True
98
- return False
99
-
100
- filtered_refs = {ref for ref in output_refs if _matches(ref.datasetType.name, regexes)}
86
+ filtered_refs = filter_by_dataset_type_glob(output_refs, dataset_type)
101
87
 
102
- _LOG.info("Retrieving artifacts for %d datasets and storing in Zip file.", len(output_refs))
88
+ _LOG.info("Retrieving artifacts for %d datasets and storing in Zip file.", len(filtered_refs))
103
89
  zip = qbb.retrieve_artifacts_zip(filtered_refs, dest)
104
90
  return zip
lsst/pipe/base/version.py CHANGED
@@ -1,2 +1,2 @@
1
1
  __all__ = ["__version__"]
2
- __version__ = "29.2025.1900"
2
+ __version__ = "29.2025.2100"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lsst-pipe-base
3
- Version: 29.2025.1900
3
+ Version: 29.2025.2100
4
4
  Summary: Pipeline infrastructure for the Rubin Science Pipelines.
5
5
  Author-email: Rubin Observatory Data Management <dm-admin@lists.lsst.org>
6
6
  License: BSD 3-Clause License
@@ -8,7 +8,7 @@ lsst/pipe/base/_observation_dimension_packer.py,sha256=78Jg2OVFOdXIK62TS2Y3X4095
8
8
  lsst/pipe/base/_quantumContext.py,sha256=gb60mTHbgOIEptYvJ64SaChvViXyeKJlG6kEHq4nYVw,19345
9
9
  lsst/pipe/base/_status.py,sha256=tvKm-z_haZGksOR4nQ-ePJgbLag-e3t4nQY47yLFP2M,15741
10
10
  lsst/pipe/base/_task_metadata.py,sha256=SfM4L07Pe5itBDCsNh-XjdQvlKLY5LBcG6lpdtpMxHA,24968
11
- lsst/pipe/base/all_dimensions_quantum_graph_builder.py,sha256=b_MVBsQcLERTOoitO0swJHdGK36P4-1CpeeD_ohU9Ug,45105
11
+ lsst/pipe/base/all_dimensions_quantum_graph_builder.py,sha256=YCgDh-P1HxgS2zH2fP57uYCCZGI9DxBLIcXihnc-czQ,45758
12
12
  lsst/pipe/base/automatic_connection_constants.py,sha256=H5uuh1rYRpjndgPdb0dh1L_-OyLKdT6VWOZTAb__xCU,3298
13
13
  lsst/pipe/base/caching_limited_butler.py,sha256=u1uJYzCE7OxW8MW8Xv2LDB9-Nuj-Ao8lBJcDttKrc1Y,7700
14
14
  lsst/pipe/base/config.py,sha256=yNipVEc6awwhU_O9I01g20OnvQrs28dAwkXuI1hrlYE,11982
@@ -32,11 +32,11 @@ lsst/pipe/base/task.py,sha256=XHBd-7m1a4-6LgobBYA1DgY4H7EV-_RWKfxbhZbMmD4,15145
32
32
  lsst/pipe/base/taskFactory.py,sha256=4GhN2DozPM8suBYIvoKN4E6VP0I3mYZHBjCUO5JcCGk,2901
33
33
  lsst/pipe/base/testUtils.py,sha256=lSBKMhoKflbi8JkMNYfEqqHNl-rtFI8UYT3QneDYpLo,18477
34
34
  lsst/pipe/base/utils.py,sha256=JmEt3l0xrh9uayKrSXuQEq12aXOhDr2YXmbYduaxCko,1940
35
- lsst/pipe/base/version.py,sha256=duakYcQBT5t4KBaOX14WCtq_sSvpoXvNcxi3sUb8GvI,55
35
+ lsst/pipe/base/version.py,sha256=czd5myijXlfzN1l1OFP7x6hn5ASHoE02wXhI32IqLec,55
36
36
  lsst/pipe/base/cli/__init__.py,sha256=861tXIAW7SqtqNUYkjbeEdfg8lDswXsjJQca0gVCFz4,54
37
37
  lsst/pipe/base/cli/_get_cli_subcommands.py,sha256=g_af64klRybBGKAg7fmBSZBdw2LYBAsFON_yQIMZON0,1289
38
38
  lsst/pipe/base/cli/cmd/__init__.py,sha256=BGicstnryQ48rYcNRh4fa6Vy63ZIlZ_pPAEa17jhkwY,1519
39
- lsst/pipe/base/cli/cmd/commands.py,sha256=noP1fU7mlNUwxzJGtYy5CF457iQMl3O4W2X0sYQNIYc,5535
39
+ lsst/pipe/base/cli/cmd/commands.py,sha256=t91PZoIQwgstzONNbqpFJMWpaxeHesVP6EtgkMJYrcE,5612
40
40
  lsst/pipe/base/cli/opt/__init__.py,sha256=DN17wUbMwNIgbDBfF35sdyGfaMT81f3b_CA5Pp8POdk,1347
41
41
  lsst/pipe/base/cli/opt/arguments.py,sha256=9LhDnsM98_2zOqqm-eyv_nnZmAQcBG5OpHzeJYw_eTw,1484
42
42
  lsst/pipe/base/cli/opt/options.py,sha256=d5mC2WXZJiUbkdaIo_VUsvNxShD3GmredbEN5jQD64Q,1900
@@ -74,8 +74,9 @@ lsst/pipe/base/pipeline_graph/visualization/_status_annotator.py,sha256=dp7PXl9C
74
74
  lsst/pipe/base/script/__init__.py,sha256=cLEXE7aq5UZ0juL_ScmRw0weFgp4tDgwEX_ts-NEYic,1522
75
75
  lsst/pipe/base/script/register_instrument.py,sha256=TRC2r2tSoYBNWNVQya01ELxAtGH8WVk9Ya-uNgCIL5U,2426
76
76
  lsst/pipe/base/script/retrieve_artifacts_for_quanta.py,sha256=pYI0wNl5PU8ImgzWfGEDrRz3PSKSg2szWLEIVKdm7Og,3939
77
- lsst/pipe/base/script/transfer_from_graph.py,sha256=OE_ruTiaDMDKe05RA_y7sbDawmQzdKVEtGj_cmHY2tM,5599
78
- lsst/pipe/base/script/zip_from_graph.py,sha256=E4_ziLRQCKEwQ0rWIXt9evJoi8FDghG4zDrDXg277Kg,3728
77
+ lsst/pipe/base/script/transfer_from_graph.py,sha256=YkOFszLJuaqD2vl1izhSWemZzGCxDxUSdZNDoDyFEfo,5949
78
+ lsst/pipe/base/script/utils.py,sha256=E00wb3usCuL3-3rJHZeqLJ_kwHV9V7Vaj6SdUe1VxU4,2631
79
+ lsst/pipe/base/script/zip_from_graph.py,sha256=rbH_5Jk7Yc-YFD3X4mbDE4Vzddtu5y90Z77wha94mdM,3228
79
80
  lsst/pipe/base/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
80
81
  lsst/pipe/base/tests/no_dimensions.py,sha256=58UpyRN8cLAMZtkOmjTm3dJZyRFRekotQ-7-OgEfiAI,4710
81
82
  lsst/pipe/base/tests/pipelineStepTester.py,sha256=KGxdB8gdVpSey2RUGURDIzIfPL-4qvQCsBpMrhG4Z2M,7208
@@ -85,13 +86,13 @@ lsst/pipe/base/tests/mocks/__init__.py,sha256=NrIJYDeYgR3HsOJXBEXi8EXDhhV7iw7dgw
85
86
  lsst/pipe/base/tests/mocks/_data_id_match.py,sha256=WU0-5cPsU4565UhlsvQwhZKP5RzPJPyZ8sGio1CKAPI,6813
86
87
  lsst/pipe/base/tests/mocks/_pipeline_task.py,sha256=fqaJ-tB7K3jxlfCvCSnVd_GNrz-JhX7FB914h7nHLXc,29366
87
88
  lsst/pipe/base/tests/mocks/_storage_class.py,sha256=JvUmyXQC5DwOkFoLHkJk6u0ldn1VgZVVjh9GjpXRGg0,25211
88
- lsst_pipe_base-29.2025.1900.dist-info/licenses/COPYRIGHT,sha256=kB3Z9_f6a6uFLGpEmNJT_n186CE65H6wHu4F6BNt_zA,368
89
- lsst_pipe_base-29.2025.1900.dist-info/licenses/LICENSE,sha256=pRExkS03v0MQW-neNfIcaSL6aiAnoLxYgtZoFzQ6zkM,232
90
- lsst_pipe_base-29.2025.1900.dist-info/licenses/bsd_license.txt,sha256=7MIcv8QRX9guUtqPSBDMPz2SnZ5swI-xZMqm_VDSfxY,1606
91
- lsst_pipe_base-29.2025.1900.dist-info/licenses/gpl-v3.0.txt,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
92
- lsst_pipe_base-29.2025.1900.dist-info/METADATA,sha256=gGserBL9JVxpAxDR1NTfZ_AVFs-J4JnlG5l69qDgZNg,2195
93
- lsst_pipe_base-29.2025.1900.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
94
- lsst_pipe_base-29.2025.1900.dist-info/entry_points.txt,sha256=bnmUhJBsChxMdqST9VmFBYYKxLQoToOfqW1wjW7khjk,64
95
- lsst_pipe_base-29.2025.1900.dist-info/top_level.txt,sha256=eUWiOuVVm9wwTrnAgiJT6tp6HQHXxIhj2QSZ7NYZH80,5
96
- lsst_pipe_base-29.2025.1900.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
97
- lsst_pipe_base-29.2025.1900.dist-info/RECORD,,
89
+ lsst_pipe_base-29.2025.2100.dist-info/licenses/COPYRIGHT,sha256=kB3Z9_f6a6uFLGpEmNJT_n186CE65H6wHu4F6BNt_zA,368
90
+ lsst_pipe_base-29.2025.2100.dist-info/licenses/LICENSE,sha256=pRExkS03v0MQW-neNfIcaSL6aiAnoLxYgtZoFzQ6zkM,232
91
+ lsst_pipe_base-29.2025.2100.dist-info/licenses/bsd_license.txt,sha256=7MIcv8QRX9guUtqPSBDMPz2SnZ5swI-xZMqm_VDSfxY,1606
92
+ lsst_pipe_base-29.2025.2100.dist-info/licenses/gpl-v3.0.txt,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
93
+ lsst_pipe_base-29.2025.2100.dist-info/METADATA,sha256=4CN9L65r6qXfM8HHmng1_umH1vLoq6CW_kjzbJvlLx8,2195
94
+ lsst_pipe_base-29.2025.2100.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
95
+ lsst_pipe_base-29.2025.2100.dist-info/entry_points.txt,sha256=bnmUhJBsChxMdqST9VmFBYYKxLQoToOfqW1wjW7khjk,64
96
+ lsst_pipe_base-29.2025.2100.dist-info/top_level.txt,sha256=eUWiOuVVm9wwTrnAgiJT6tp6HQHXxIhj2QSZ7NYZH80,5
97
+ lsst_pipe_base-29.2025.2100.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
98
+ lsst_pipe_base-29.2025.2100.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.3.1)
2
+ Generator: setuptools (80.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5