LSSTApplications  18.0.0+112,18.0.0+52,19.0.0,19.0.0+1,19.0.0+14,19.0.0+15,19.0.0+17,19.0.0+22,19.0.0+3,19.0.0-1-g20d9b18+8,19.0.0-1-g425ff20,19.0.0-1-g5549ca4,19.0.0-1-g580fafe+8,19.0.0-1-g6fe20d0+2,19.0.0-1-g7011481+13,19.0.0-1-g8c57eb9+8,19.0.0-1-gdc0e4a7+13,19.0.0-1-ge272bc4+8,19.0.0-1-ge3aa853+1,19.0.0-12-g296864c0+2,19.0.0-15-g85ac9ad,19.0.0-2-g0d9f9cd+15,19.0.0-2-g5037de4+1,19.0.0-2-g9b11441+2,19.0.0-2-gb96a1c4+9,19.0.0-2-gd955cfd+21,19.0.0-3-g97e0e8e9+1,19.0.0-4-g41ffa1d+1,19.0.0-4-g725f80e+17,19.0.0-4-ga8eba22,19.0.0-4-gad373c5+8,19.0.0-5-gb9a06e236+1,19.0.0-5-gfe96e6c+6,19.0.0-7-gea0a0fe+4,w.2020.02
LSSTDataManagementBasePackage
filePathParser.py
Go to the documentation of this file.
1 # This file is part of obs_base.
2 #
3 # Developed for the LSST Data Management System.
4 # This product includes software developed by the LSST Project
5 # (https://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 from __future__ import annotations
22 
23 __all__ = ["FilePathParser"]
24 
25 import re
26 from typing import Dict
27 
28 from ..mapping import Mapping
29 
30 
32  """A callable object that extracts Gen2 data IDs from filenames
33  corresponding to a particular Gen2 DatasetType.
34 
35  External code should use the `fromMapping` method to construct instances.
36 
37  Parameters
38  ----------
39  keys : `dict`
40  Dictionary mapping Gen2 data ID key to the type of its associated
41  value.
42  regex : regular expression object
43  Regular expression pattern with named groups for all data ID keys.
44  """
45  def __init__(self, keys: Dict[str, type], regex: re.Pattern):
46  self.keys = keys
47  self.regex = regex
48 
49  # Regular expression that matches a single substitution in
50  # Gen2 CameraMapper template, such as "%(tract)04d".
51  TEMPLATE_RE = re.compile(r"\%\((?P<name>\w+)\)[^\%]*?(?P<type>[idrs])")
52 
53  @classmethod
54  def fromMapping(cls, mapping: Mapping) -> FilePathParser:
55  """Construct a FilePathParser instance from a Gen2
56  `lsst.obs.base.Mapping` instance.
57 
58  Parameters
59  ----------
60  mapping : `lsst.obs.base.Mapping`
61  Mapping instance from a Gen2 `CameraMapper`.
62 
63  Returns
64  -------
65  parser : `FilePathParser`
66  A new `FilePathParser` instance that can extract Gen2 data IDs
67  from filenames with the given mapping's template.
68 
69  Raises
70  ------
71  RuntimeError
72  Raised if the mapping has no template.
73  """
74  template = mapping.template
75  keys = {}
76  # The template string is something like
77  # "deepCoadd/%(tract)04d-%(patch)s/%(filter)s"; each step of this
78  # iterator corresponds to a %-tagged substitution string.
79  # Our goal in all of this parsing is to turn the template into a regex
80  # we can use to extract the associated values when matching strings
81  # generated with the template.
82  last = 0
83  terms = []
84  allKeys = mapping.keys()
85  for match in cls.TEMPLATE_RE.finditer(template):
86  # Copy the (escaped) regular string between the last substitution
87  # and this one to the terms that will form the regex.
88  terms.append(re.escape(template[last:match.start()]))
89  # Pull out the data ID key from the name used in the
90  # substitution string. Use that and the substition
91  # type to come up with the pattern to use in the regex.
92  name = match.group("name")
93  if name == "patch":
94  pattern = r"\d+,\d+"
95  elif match.group("type") in "id": # integers
96  pattern = r"0*\d+"
97  else:
98  pattern = ".+"
99  # only use named groups for the first occurence of a key
100  if name not in keys:
101  terms.append(r"(?P<%s>%s)" % (name, pattern))
102  keys[name] = allKeys[name]
103  else:
104  terms.append(r"(%s)" % pattern)
105  # Remember the end of this match
106  last = match.end()
107  # Append anything remaining after the last substitution string
108  # to the regex.
109  terms.append(re.escape(template[last:]))
110  return cls(keys, regex=re.compile("".join(terms)))
111 
112  def __call__(self, filePath: str) -> dict:
113  """Extract a Gen2 data ID dictionary from the given path.
114 
115  Parameters
116  ----------
117  filePath : `str`
118  Path and filename relative to the repository root.
119 
120  Returns
121  -------
122  dataId : `dict`
123  Dictionary used to identify the dataset in the Gen2 butler, or
124  None if the file was not recognized.
125  """
126  m = self.regex.fullmatch(filePath)
127  if m is None:
128  return None
129  return {k: v(m.group(k)) for k, v in self.keys.items()}
std::vector< SchemaItem< Flag > > * items