vc2-static-filter-analysis
¶
This command statically analyses a VC-2 filter configuration to determine mathematical expressions for worst-case signal ranges and generate test patterns.
Example usage¶
A simple 2-level LeGall (5, 3) transform:
$ vc2-static-filter-analysis \
--wavelet-index le_gall_5_3 \
--dwt-depth 2 \
--output static_analysis.json
A more complex asymmetric transform:
$ vc2-static-filter-analysis \
--wavelet-index haar_with_shift \
--wavelet-index-ho le_gall_5_3 \
--dwt-depth 1 \
--dwt-depth-ho 2 \
--output static_analysis.json
Arguments¶
The complete set of arguments can be listed using --help
usage: vc2-static-filter-analysis [-h] --wavelet-index WAVELET_INDEX
[--wavelet-index-ho WAVELET_INDEX_HO]
[--dwt-depth DWT_DEPTH]
[--dwt-depth-ho DWT_DEPTH_HO]
[--num-batches NUM_BATCHES]
[--batch-num BATCH_NUM] [--output OUTPUT]
[--verbose]
This command statically analyses a VC-2 filter configuration to determine
mathematical expressions for worst-case signal ranges and generate test
patterns. Writes the output to a JSON file.
optional arguments:
-h, --help show this help message and exit
--wavelet-index WAVELET_INDEX, -w WAVELET_INDEX
The VC-2 wavelet index for the wavelet transform. One
of: 0 or deslauriers_dubuc_9_7, 1 or le_gall_5_3, 2 or
deslauriers_dubuc_13_7, 3 or haar_no_shift, 4 or
haar_with_shift, 5 or fidelity, 6 or daubechies_9_7.
--wavelet-index-ho WAVELET_INDEX_HO, -W WAVELET_INDEX_HO
The VC-2 wavelet index for the horizontal parts of the
wavelet transform. If not specified, assumed to be the
same as --wavelet-index/-w.
--dwt-depth DWT_DEPTH, -d DWT_DEPTH
The VC-2 transform depth. Defaults to 0 if not
specified.
--dwt-depth-ho DWT_DEPTH_HO, -D DWT_DEPTH_HO
The VC-2 horizontal-only transform depth. Defaults to
0 if not specified.
--num-batches NUM_BATCHES, -B NUM_BATCHES
If the analysis is to be performed in a series of
smaller batches, the number of batches to split it
into.
--batch-num BATCH_NUM, -b BATCH_NUM
When --num-batches is used, the specific the batch to
run.
--output OUTPUT, -o OUTPUT
The name of the file to write the computed JSON output
to. Defaults to stdout.
--verbose, -v Show more detailed status information during
execution.
JSON file format¶
The output of vc2-static-filter-analysis
is a JSON file which has the
following structure:
{
"wavelet_index": <int>,
"wavelet_index_ho": <int>,
"dwt_depth": <int>,
"dwt_depth_ho": <int>,
"analysis_signal_bounds": [<signal-bounds>, ...],
"synthesis_signal_bounds": [<signal-bounds>, ...],
"analysis_test_patterns": [<test-pattern-specification>, ...],
"synthesis_test_patterns": [<test-pattern-specification>, ...],
}
Signal bounds¶
The "analysis_signal_bounds"
and "synthesis_signal_bounds"
lists define
algebraic expressions for the upper- and lower-bounds for each analysis and
synthesis filter phase (see Terminology) as follows:
<signal-bounds> = {
"level": <int>,
"array_name": <string>,
"phase": [<int>, <int>],
"lower_bound": <algebraic-expression>,
"upper_bound": <algebraic-expression>,
}
<algebraic-expression> = [
{
"symbol": <string-or-null>,
"numer": <string>,
"denom": <string>,
},
...
]
Note
The
deserialise_signal_bounds()
Python utility function is provided for unpacking this structure.
Each <algebraic-expression>
defines an algebraic linear expression. As an
example, the following expression:
Would be represented in JSON form as:
[
{"symbol": "a", "numer": "2", "denom": "3"},
{"symbol": "b", "numer": "5", "denom": "1"},
{"symbol": null, "numer": "-2", "denom": "1"},
]
In the expressions defining the analysis filter signal levels, the following symbols are used:
signal_min
– The minimum picture signal value (e.g. -512 for 10 bit signals).
signal_max
– The minimum picture signal value (e.g. 511 for 10 bit signals).
In the expressions defining the synthesis filter signal levels, symbols with
the form coeff_<level>_<orient>_min
and coeff_<level>_<orient>_min
are
used. For example coeff_1_LL_min
would mean the minimum value a level-1
‘LL’ subband value could have.
Test patterns¶
The "analysis_test_patterns
and "synthesis_test_patterns
lists define
test patterns for each analysis and synthesis filter phase like so:
<test-pattern-specification> = {
"level": <int>,
"array_name": <string>,
"phase": [<int>, <int>],
"target": [<int>, <int>],
"target_transition_multiple": [<int>, <int>],
"pattern": <test-pattern>,
"pattern_transition_multiple": [<int>, <int>],
}
<test-pattern> = {
"dx": <int>,
"dy": <int>,
"width": <int>,
"height": <int>,
"positive": <string>,
"mask": <string>,
}
Note
The
deserialise_test_pattern_specifications()
Python utility function is provided for unpacking this structure.
Test patterns are defined in terms of a collection of pixel polarity values
which indicate which pixels should be set to their maximum level and which
should be set to their minimum. All other pixel values may be set arbitrarily.
For the encoding used by the <test-pattern>
object to encode the pixel
polarities themselves, see
serialise_test_pattern
.
Test patterns must be carefully aligned within a test picture when used. See
TestPatternSpecification
for the
meaning of the relevant fields of <test-pattern-specification>
. .
Missing values¶
Only intermediate arrays are included which contain novel values. Arrays which are just renamings, interleavings and subsamplings of other arrays are omitted.
Runtime and memory consumption¶
For typical ‘real world’ filter configurations, this command should complete within a few seconds and use a trivial amount of memory.
For larger wavelets (e.g. the fidelity filter) and deeper transforms (e.g. three or more levels), the runtime and memory requirements can grow significantly. For example, a 4-level LeGall (5, 3) transform will take on the order of an hour to analyse. As an especially extreme case, a 4-level Fidelity wavelet will require around 16 GB of RAM and several weeks to complete.
The --verbose
option provides useful progress information as the static
analysis process proceeds. As a guide, the vast majority of the runtime will be
spent on the synthesis filters due to their far greater number. RAM usage grows
rapidly during the processing of the analysis filters and then only grow very
slightly during synthesis filter analysis.
Batched/parallel execution¶
When analysing extremely large filters, it might be useful to split the analysis process into multiple batches to be executed simultaneously on several cores or computers.
To run the analysis process in batched mode, the --num-batches
argument
must be given specifying the total number of batches the execution will be
split into. Each batch must also be given a --batch-num
argument specifying
which batch is to be executed. For example, the following commands might be run
on four machines to parallelise the analysis of a 3-level Fidelity filter.
$ vc2-static-filter-analysis \
--wavelet-index fidelity \
--depth 3 \
--num-batches 4 \
--batch-num 0 \
--output static_analysis_batch_0.json
$ vc2-static-filter-analysis \
--wavelet-index fidelity \
--depth 3 \
--num-batches 4 \
--batch-num 1 \
--output static_analysis_batch_1.json
$ vc2-static-filter-analysis \
--wavelet-index fidelity \
--depth 3 \
--num-batches 4 \
--batch-num 2 \
--output static_analysis_batch_2.json
$ vc2-static-filter-analysis \
--wavelet-index fidelity \
--depth 3 \
--num-batches 4 \
--batch-num 3 \
--output static_analysis_batch_3.json
Once all four analyses have finished, the results are then combined together using the vc2-static-filter-analysis-combine utility:
$ vc2-static-filter-analysis-combine \
static_analysis_batch_0.json \
static_analysis_batch_1.json \
static_analysis_batch_2.json \
static_analysis_batch_3.json \
--output static_analysis.json
Warning
Each batch may still require the same amount of RAM as a complete analysis.
Warning
The batching process requires some duplicated processing in each batch. Consequently more total CPU time may be required than non-batched execution.
Warning
Though batches are intended to take similar amounts of time to execute, this is not guaranteed.