24 """This module provides the FsScanner class."""
33 """Class to scan a filesystem location for paths matching a template.
35 Decomposes the resulting paths into fields and passes them to a callback
40 """Constructor. Takes the path template, which should be in the form
41 of a Python string with named format substitution specifications.
42 Such a template would be suitable for generating a path given a set of
43 fields in a dictionary. Does not handle hex (%x or %X).
46 %(field)s/%(visit)d/%(exposure)d/raw-%(visit)d-e%(exposure)03d-c%(ccd)03d-a%(amp)03d.fits
48 Note that fields may appear multiple times; the second and subsequent
49 appearances of such fields will have "_{number}" appended to them to
50 disambiguate, although it is typically assumed that they will all be
53 Trailing brackets (and their contents) can be used to indicate which HDU from a file should
54 be used. They will not be included in the filename search.
58 if pathTemplate.endswith(
']'):
59 pathTemplate = pathTemplate[0:pathTemplate.rfind(
'[')]
62 fmt = re.compile(
r'%\((\w+)\).*?([dioueEfFgGcrs])')
72 for m
in fmt.finditer(pathTemplate):
73 fieldName = m.group(1)
74 if fieldName
in self.
fields:
75 fieldName +=
"_%d" % (n,)
78 prefix = pathTemplate[last:m.start(0)]
82 if m.group(2)
in 'crs':
84 self.
reString +=
r'(?P<' + fieldName +
'>.+)'
85 elif m.group(2)
in 'eEfFgG':
87 self.
reString +=
r'(?P<' + fieldName +
r'>[\d.eE+-]+)'
90 self.
reString +=
r'(?P<' + fieldName +
r'>[\d+-]+)'
92 self.
fields[fieldName] = dict(pos=pos, fieldType=fieldType)
98 """Return the list of fields that will be returned from matched
101 fieldList = [
"" for i
in range(len(self.
fields))]
103 fieldList[self.
fields[f][
'pos']] = f
107 """Return true if the given field contains a number."""
109 return self.
fields[name][
'fieldType']
in (float, int)
112 """Return true if the given field contains an integer."""
114 return self.
fields[name][
'fieldType'] == int
117 """Return true if the given field contains an float."""
119 return self.
fields[name][
'fieldType'] == float
123 Scan a given path location. Return info about paths that conform to the path template:
125 :return: Path info: {path: {key:value ...}, ...} e.g.:
126 {'0239622/instcal0239622.fits.fz': {'visit_0': 239622, 'visit': 239622}}
132 for path
in pathList:
135 dataId = m.groupdict()
138 dataId[f] = int(dataId[f])
140 dataId[f] = float(dataId[f])
143 print(
"Warning: unmatched path: %s" % (path,), file=sys.stderr)