def bundle_get_static_filter_analysis( file_or_filename, wavelet_index, wavelet_index_ho, dwt_depth, dwt_depth_ho, ): """ Read a static filter analysis for a particular filter configuration from a bundle. Raises :py:exc:`KeyError` if no matching analysis is present in the bundle. Parameters ========== file_or_filename : file-like or str The bundle to read. wavelet_index : int wavelet_index_ho : int dwt_depth : int dwt_depth_ho : int Returns ======= analysis_signal_bounds : {(level, array_name, x, y): (lower_bound_exp, upper_bound_exp), ...} synthesis_signal_bounds : {(level, array_name, x, y): (lower_bound_exp, upper_bound_exp), ...} analysis_test_patterns: {(level, array_name, x, y): :py:class:`~vc2_bit_widths.patterns.TestPatternSpecification`, ...} synthesis_test_patterns: {(level, array_name, x, y): :py:class:`~vc2_bit_widths.patterns.TestPatternSpecification`, ...} See :py:func:`vc2_bit_widths.helpers.static_filter_analysis`. """ analysis = bundle_get_serialised_static_filter_analysis( file_or_filename, wavelet_index, wavelet_index_ho, dwt_depth, dwt_depth_ho, ) return ( deserialise_signal_bounds(analysis["analysis_signal_bounds"]), deserialise_signal_bounds(analysis["synthesis_signal_bounds"]), deserialise_test_pattern_specifications( TestPatternSpecification, analysis["analysis_test_patterns"]), deserialise_test_pattern_specifications( TestPatternSpecification, analysis["synthesis_test_patterns"]), )
def deserialise_static_analysis(data): """ Deserialise contents in place. """ data["analysis_signal_bounds"] = deserialise_signal_bounds( data["analysis_signal_bounds"], ) data["synthesis_signal_bounds"] = deserialise_signal_bounds( data["synthesis_signal_bounds"], ) data["analysis_test_patterns"] = deserialise_test_pattern_specifications( TPS, data["analysis_test_patterns"], ) data["synthesis_test_patterns"] = deserialise_test_pattern_specifications( TPS, data["synthesis_test_patterns"], ) return data
def main(args=None): args = parse_args(args) # Load precomputed signal bounds static_filter_analysis = json.load(args.static_filter_analysis) quantisation_matrix = parse_quantisation_matrix_argument( args.custom_quantisation_matrix, static_filter_analysis["wavelet_index"], static_filter_analysis["wavelet_index_ho"], static_filter_analysis["dwt_depth"], static_filter_analysis["dwt_depth_ho"], ) analysis_signal_bounds = deserialise_signal_bounds( static_filter_analysis["analysis_signal_bounds"] ) synthesis_signal_bounds = deserialise_signal_bounds( static_filter_analysis["synthesis_signal_bounds"] ) ( concrete_analysis_signal_bounds, concrete_synthesis_signal_bounds, ) = evaluate_filter_bounds( static_filter_analysis["wavelet_index"], static_filter_analysis["wavelet_index_ho"], static_filter_analysis["dwt_depth"], static_filter_analysis["dwt_depth_ho"], analysis_signal_bounds, synthesis_signal_bounds, args.picture_bit_width, ) print(quantisation_index_bound( concrete_analysis_signal_bounds, quantisation_matrix, )) return 0
def test_serialise_signal_bounds(): before = OrderedDict([ ((1, "LH", 2, 3), ( LinExp("foo")/2, LinExp("bar")/4, )), ((2, "HL", 3, 2), ( LinExp("qux")/8, LinExp("quo")/16, )), ]) after = serialise_signal_bounds(before) after = json_roundtrip(after) assert after == [ { "level": 1, "array_name": "LH", "phase": [2, 3], "lower_bound": [ {"symbol": "foo", "numer": "1", "denom": "2"}, ], "upper_bound": [ {"symbol": "bar", "numer": "1", "denom": "4"}, ], }, { "level": 2, "array_name": "HL", "phase": [3, 2], "lower_bound": [ {"symbol": "qux", "numer": "1", "denom": "8"}, ], "upper_bound": [ {"symbol": "quo", "numer": "1", "denom": "16"}, ], }, ] assert deserialise_signal_bounds(after) == before
else: if args.picture_bit_width is None: parser.error("A --picture-bit-width/-b argument or a set of " "optimised synthesis test signals are required.") return args args = parse_args() if args.verbose: logging.basicConfig(level=logging.INFO) # Load precomputed signal bounds static_filter_analysis = json.load(args.static_filter_analysis) analysis_signal_bounds = deserialise_signal_bounds( static_filter_analysis["analysis_signal_bounds"]) synthesis_signal_bounds = deserialise_signal_bounds( static_filter_analysis["synthesis_signal_bounds"]) # Load precomputed test signals analysis_test_signals = deserialise_test_signals( TestSignalSpecification, static_filter_analysis["analysis_test_signals"]) synthesis_test_signals = deserialise_test_signals( TestSignalSpecification, static_filter_analysis["synthesis_test_signals"]) # Load optimised synthesis signal if args.optimised_synthesis_test_signals is not None: optimised_json = json.load(args.optimised_synthesis_test_signals) assert static_filter_analysis["wavelet_index"] == optimised_json[ "wavelet_index"]
def load_filter_analysis( static_filter_analysis_file, optimised_synthesis_patterns_file, quantisation_matrix_argument, picture_bit_width, ): """ Load a static filter analysis and optionally a set of optimised synthesis test patterns, returning all of the loaded data. Parameters ========== static_filter_analysis_file : :py:class:`file` An open file ready to read the static filter analysis data from a JSON file. optimised_synthesis_patterns_file : :py:class:`file` or None An open file ready to read a set of optimised synthesis test patterns for a JSON file. If None, synthesis test patterns will be read from the ``static_filter_analysis_file`` instead. quantisation_matrix_argument : [str, ...] or None The --custom-quantisation-matrix argument which will be parsed (if optimised_synthesis_patterns_file is not provided) picture_bit_width : int or None The --picture-bit-width argument which will be used if no optimised_synthesis_test_patterns file is provided. Returns ======= wavelet_index : int wavelet_index_ho : int dwt_depth : int dwt_depth_ho : int quantisation_matrix : {level: {orient: value, ...}, ...} picture_bit_width : int max_quantisation_index : int concrete_analysis_bounds : {(level, array_name, x, y): (lo, hi), ...} concrete_synthesis_bounds : {(level, array_name, x, y): (lo, hi), ...} analysis_test_patterns : {(level, array_name, x, y): :py:class:`~vc2_bit_widths.patterns.TestPatternSpecification`, ...} synthesis_test_patterns : {(level, array_name, x, y): :py:class:`~vc2_bit_widths.patterns.TestPatternSpecification`, ...} """ # Load precomputed signal bounds static_filter_analysis = json.load(static_filter_analysis_file) analysis_signal_bounds = deserialise_signal_bounds( static_filter_analysis["analysis_signal_bounds"] ) synthesis_signal_bounds = deserialise_signal_bounds( static_filter_analysis["synthesis_signal_bounds"] ) # Load precomputed test patterns analysis_test_patterns = deserialise_test_pattern_specifications( TestPatternSpecification, static_filter_analysis["analysis_test_patterns"] ) synthesis_test_patterns = deserialise_test_pattern_specifications( TestPatternSpecification, static_filter_analysis["synthesis_test_patterns"] ) # Load optimised synthesis signal if optimised_synthesis_patterns_file is not None: optimised_json = json.load(optimised_synthesis_patterns_file) assert static_filter_analysis["wavelet_index"] == optimised_json["wavelet_index"] assert static_filter_analysis["wavelet_index_ho"] == optimised_json["wavelet_index_ho"] assert static_filter_analysis["dwt_depth"] == optimised_json["dwt_depth"] assert static_filter_analysis["dwt_depth_ho"] == optimised_json["dwt_depth_ho"] picture_bit_width = optimised_json["picture_bit_width"] quantisation_matrix = deserialise_quantisation_matrix( optimised_json["quantisation_matrix"] ) synthesis_test_patterns = deserialise_test_pattern_specifications( OptimisedTestPatternSpecification, optimised_json["optimised_synthesis_test_patterns"] ) else: quantisation_matrix = parse_quantisation_matrix_argument( quantisation_matrix_argument, static_filter_analysis["wavelet_index"], static_filter_analysis["wavelet_index_ho"], static_filter_analysis["dwt_depth"], static_filter_analysis["dwt_depth_ho"], ) # Compute signal bounds for all specified bit widths # # analysis_bounds_dicts = [{(level, array_name, x, y): (lower_bound, upper_bound), ...}, ...] # synthesis_bounds_dicts = same as above concrete_analysis_bounds, concrete_synthesis_bounds = evaluate_filter_bounds( static_filter_analysis["wavelet_index"], static_filter_analysis["wavelet_index_ho"], static_filter_analysis["dwt_depth"], static_filter_analysis["dwt_depth_ho"], analysis_signal_bounds, synthesis_signal_bounds, picture_bit_width, ) # Find the maximum quantisation index for each bit width max_quantisation_index = quantisation_index_bound( concrete_analysis_bounds, quantisation_matrix, ) return ( static_filter_analysis["wavelet_index"], static_filter_analysis["wavelet_index_ho"], static_filter_analysis["dwt_depth"], static_filter_analysis["dwt_depth_ho"], quantisation_matrix, picture_bit_width, max_quantisation_index, concrete_analysis_bounds, concrete_synthesis_bounds, analysis_test_patterns, synthesis_test_patterns, )
def main(args=None): args = parse_args(args) if args.verbose: logging.basicConfig(level=logging.INFO) static_filter_analysis = json.load(args.static_filter_analysis) quantisation_matrix = parse_quantisation_matrix_argument( args.custom_quantisation_matrix, static_filter_analysis["wavelet_index"], static_filter_analysis["wavelet_index_ho"], static_filter_analysis["dwt_depth"], static_filter_analysis["dwt_depth_ho"], ) analysis_signal_bounds = deserialise_signal_bounds( static_filter_analysis["analysis_signal_bounds"]) synthesis_signal_bounds = deserialise_signal_bounds( static_filter_analysis["synthesis_signal_bounds"]) synthesis_test_patterns = deserialise_test_pattern_specifications( TestPatternSpecification, static_filter_analysis["synthesis_test_patterns"]) ( concrete_analysis_signal_bounds, concrete_synthesis_signal_bounds, ) = evaluate_filter_bounds( static_filter_analysis["wavelet_index"], static_filter_analysis["wavelet_index_ho"], static_filter_analysis["dwt_depth"], static_filter_analysis["dwt_depth_ho"], analysis_signal_bounds, synthesis_signal_bounds, args.picture_bit_width, ) max_quantisation_index = quantisation_index_bound( concrete_analysis_signal_bounds, quantisation_matrix, ) random_state = np.random.RandomState(args.seed) optimised_synthesis_test_patterns = optimise_synthesis_test_patterns( wavelet_index=static_filter_analysis["wavelet_index"], wavelet_index_ho=static_filter_analysis["wavelet_index_ho"], dwt_depth=static_filter_analysis["dwt_depth"], dwt_depth_ho=static_filter_analysis["dwt_depth_ho"], quantisation_matrix=quantisation_matrix, picture_bit_width=args.picture_bit_width, synthesis_test_patterns=synthesis_test_patterns, max_quantisation_index=max_quantisation_index, random_state=random_state, number_of_searches=args.number_of_searches, terminate_early=args.terminate_early, added_corruption_rate=args.added_corruption_rate, removed_corruption_rate=args.removed_corruption_rate, base_iterations=args.base_iterations, added_iterations_per_improvement=args.added_iterations_per_improvement, ) out = { "wavelet_index": static_filter_analysis["wavelet_index"], "wavelet_index_ho": static_filter_analysis["wavelet_index_ho"], "dwt_depth": static_filter_analysis["dwt_depth"], "dwt_depth_ho": static_filter_analysis["dwt_depth_ho"], "picture_bit_width": args.picture_bit_width, "quantisation_matrix": serialise_quantisation_matrix(quantisation_matrix, ), "optimised_synthesis_test_patterns": serialise_test_pattern_specifications( OptimisedTestPatternSpecification, optimised_synthesis_test_patterns, ) } json.dump(out, args.output) args.output.write("\n") return 0