|
- #!/usr/bin/python
-
- import os
- import nilmtools.filter
- import nilmtools.decimate
- import nilmdb.client
- import argparse
- import fnmatch
-
- def main(argv = None):
- parser = argparse.ArgumentParser(
- formatter_class = argparse.RawDescriptionHelpFormatter,
- description = """\
- Automatically create multiple decimations from a single source
- stream, continuing until the last decimated level contains fewer
- than 500 points total.
-
- Wildcards and multiple paths are accepted. Decimated paths are
- ignored when matching wildcards.
- """)
- def_url = os.environ.get("NILMDB_URL", "http://localhost/nilmdb/")
- parser.add_argument("-u", "--url", action="store", default=def_url,
- help="NilmDB server URL (default: %(default)s)")
- parser.add_argument("-f", "--factor", action="store", default=4, type=int,
- help='Decimation factor (default: %(default)s)')
- parser.add_argument("-m", "--max", action="store", default=500, type=int,
- help='Maximum number of points in last level ' +
- '(default: %(default)s)')
- parser.add_argument("-F", "--force-metadata", action="store_true",
- default=False,
- help="Force metadata changes if the dest "
- "doesn't match")
- parser.add_argument("-v", "--version", action="version",
- version=nilmtools.__version__)
- parser.add_argument("path", action="store", nargs='+',
- help='Path of base stream')
- args = parser.parse_args(argv)
-
- if args.max < 0:
- print("error: bad max, must be nonnegative")
- raise SystemExit(1)
-
- # Pull out info about the base stream
- client = nilmdb.client.Client(args.url)
-
- # Find list of paths to process
- streams = [ str(s[0]) for s in client.stream_list() ]
- streams = [ s for s in streams if "~decim-" not in s ]
- paths = []
- for path in args.path:
- new = fnmatch.filter(streams, str(path))
- if not new:
- print("error: no stream matched path:", path)
- raise SystemExit(1)
- paths.extend(new)
-
- for path in paths:
- do_decimation(client, args, path)
-
- def do_decimation(client, args, path):
- print("Decimating", path)
- info = nilmtools.filter.get_stream_info(client, path)
- if not info: # pragma: no cover (only good paths passed above)
- raise Exception("path " + path + " not found")
-
- meta = client.stream_get_metadata(path)
- if "decimate_source" in meta:
- print("Stream", path, "was decimated from", meta["decimate_source"])
- print("You need to pass the base stream instead")
- raise SystemExit(1)
-
- # Figure out the type we should use for decimated streams
- if ('int32' in info.layout_type or
- 'int64' in info.layout_type or
- 'float64' in info.layout_type):
- decimated_type = 'float64_' + str(info.layout_count * 3)
- else:
- decimated_type = 'float32_' + str(info.layout_count * 3)
-
- # Now do the decimations until we have few enough points
- factor = 1
- while True:
- print("Level", factor, "decimation has", info.rows, "rows")
- if info.rows <= args.max:
- break
- factor *= args.factor
- new_path = "%s~decim-%d" % (path, factor)
-
- # Create the stream if needed
- new_info = nilmtools.filter.get_stream_info(client, new_path)
- if not new_info:
- print("Creating stream", new_path)
- client.stream_create(new_path, decimated_type)
-
- # Run the decimation as if it were run from the commandline
- new_argv = [ "-u", args.url,
- "-f", str(args.factor) ]
- if args.force_metadata:
- new_argv.extend([ "--force-metadata" ])
- new_argv.extend([info.path, new_path])
- nilmtools.decimate.main(new_argv)
-
- # Update info using the newly decimated stream
- info = nilmtools.filter.get_stream_info(client, new_path)
-
- return
-
- if __name__ == "__main__":
- main()
|