You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

104 lines
3.8 KiB

  1. #!/usr/bin/python
  2. import os
  3. import nilmtools.filter
  4. import nilmtools.decimate
  5. import nilmdb.client
  6. import argparse
  7. import fnmatch
  8. def main(argv = None):
  9. parser = argparse.ArgumentParser(
  10. formatter_class = argparse.RawDescriptionHelpFormatter,
  11. description = """\
  12. Automatically create multiple decimations from a single source
  13. stream, continuing until the last decimated level contains fewer
  14. than 500 points total.
  15. Wildcards and multiple paths are accepted. Decimated paths are
  16. ignored when matching wildcards.
  17. """)
  18. def_url = os.environ.get("NILMDB_URL", "http://localhost/nilmdb/")
  19. parser.add_argument("-u", "--url", action="store", default=def_url,
  20. help="NilmDB server URL (default: %(default)s)")
  21. parser.add_argument("-f", "--factor", action="store", default=4, type=int,
  22. help='Decimation factor (default: %(default)s)')
  23. parser.add_argument("-m", "--max", action="store", default=500, type=int,
  24. help='Maximum number of points in last level ' +
  25. '(default: %(default)s)')
  26. parser.add_argument("-F", "--force-metadata", action="store_true",
  27. default = False,
  28. help="Force metadata changes if the dest "
  29. "doesn't match")
  30. parser.add_argument("-v", "--version", action="version",
  31. version=nilmtools.__version__)
  32. parser.add_argument("path", action="store", nargs='+',
  33. help='Path of base stream')
  34. args = parser.parse_args(argv)
  35. # Pull out info about the base stream
  36. client = nilmdb.client.Client(args.url)
  37. # Find list of paths to process
  38. streams = [ str(s[0]) for s in client.stream_list() ]
  39. streams = [ s for s in streams if "~decim-" not in s ]
  40. paths = []
  41. for path in args.path:
  42. new = fnmatch.filter(streams, str(path))
  43. if not new:
  44. print("error: no stream matched path:", path)
  45. raise SystemExit(1)
  46. paths.extend(new)
  47. for path in paths:
  48. do_decimation(client, args, path)
  49. def do_decimation(client, args, path):
  50. print("Decimating", path)
  51. info = nilmtools.filter.get_stream_info(client, path)
  52. if not info:
  53. raise Exception("path " + path + " not found")
  54. meta = client.stream_get_metadata(path)
  55. if "decimate_source" in meta:
  56. print("Stream", path, "was decimated from", meta["decimate_source"])
  57. print("You need to pass the base stream instead")
  58. raise SystemExit(1)
  59. # Figure out the type we should use for decimated streams
  60. if 'int32' in info.layout_type or 'float64' in info.layout_type:
  61. decimated_type = 'float64_' + str(info.layout_count * 3)
  62. else:
  63. decimated_type = 'float32_' + str(info.layout_count * 3)
  64. # Now do the decimations until we have few enough points
  65. factor = 1
  66. while True:
  67. print("Level", factor, "decimation has", info.rows, "rows")
  68. if info.rows <= args.max:
  69. break
  70. factor *= args.factor
  71. new_path = "%s~decim-%d" % (path, factor)
  72. # Create the stream if needed
  73. new_info = nilmtools.filter.get_stream_info(client, new_path)
  74. if not new_info:
  75. print("Creating stream", new_path)
  76. client.stream_create(new_path, decimated_type)
  77. # Run the decimation as if it were run from the commandline
  78. new_argv = [ "-u", args.url,
  79. "-f", str(args.factor) ]
  80. if args.force_metadata:
  81. new_argv.extend([ "--force-metadata" ])
  82. new_argv.extend([info.path, new_path])
  83. nilmtools.decimate.main(new_argv)
  84. # Update info using the newly decimated stream
  85. info = nilmtools.filter.get_stream_info(client, new_path)
  86. return
  87. if __name__ == "__main__":
  88. main()