Skip to content

Commit

Permalink
Codec-Compare version 0.2.0 (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
y-guyon authored Mar 7, 2024
1 parent 2cf3e27 commit 2b02778
Show file tree
Hide file tree
Showing 21 changed files with 1,056 additions and 112 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## v0.2.0

- Show a simple sentence by default. Keep the advanced interface in another tab.
- Add the source asset gallery in a tab.

## v0.1.10

- Fix swapped data point display toggle setting when off by default.
Expand Down
6 changes: 5 additions & 1 deletion assets/demo_batch_some_codec_exp.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@
{ "codec": "Name of the codec used to generate this data" },
{ "version": "Version of the codec used to generate this data" },
{ "time": "Timestamp of when this data was generated" },
{ "source data set": "The origin of the images used as input" },
{ "original_path": "The path to the original image" },
{ "preview": "The path to the original image preview" },
{ "encoded_path": "The path to the encoded image" },
{ "encoding_cmd": "The command used to encode the original image" },
{ "decoding_cmd": "The command used to decode the encoded image" }
],
"constant_values": [
"Some codec experiment",
"some_codec",
"some_codec_exp",
"experiment",
"2023-05-22T13:02:15.137053618Z",
"https://testimages.org/sampling/",
"/rainbow.png",
"assets/rainbow_q0.webp",
"/rainbow_q50.webp",
"encode ${original_name} ${encoded_name}",
"decode ${encoded_name} ${encoded_name}.png"
Expand Down
1 change: 0 additions & 1 deletion assets/demo_batches.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
[
["demo_batch_some_codec_exp.json"],
["demo_batch_some_codec_effort0.json"],
["demo_batch_some_codec_effort1.json"],
["demo_batch_some_codec_effort2.json"],
["demo_batch_other_codec_settingA.json"],
Expand Down
1 change: 0 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
}
codec-compare {
min-width: 600px;
overflow: auto;
flex: 0;
}
#plotly_div {
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codec_compare",
"version": "0.1.10",
"version": "0.2.0",
"description": "Codec performance comparison tool",
"publisher": "Google LLC",
"author": "Yannis Guyon",
Expand Down Expand Up @@ -34,6 +34,8 @@
"@material/mwc-menu": "^0.27.0",
"@material/mwc-slider": "^0.27.0",
"@material/mwc-switch": "^0.27.0",
"@material/mwc-tab": "^0.27.0",
"@material/mwc-tab-bar": "^0.27.0",
"@material/mwc-textfield": "^0.27.0",
"lit": "^3.1.0",
"plotly.js-dist": "^2.27.1"
Expand Down
Binary file modified readme_preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
183 changes: 183 additions & 0 deletions src/batch_merger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import {BatchSelection} from './batch_selection';
import {hexStringToRgb, rgbToHexString} from './color_setter';
import {Batch} from './entry';
import {GeometricMean} from './geometric_mean';
import {FieldMetricStats, SourceCount} from './metric';

function mergeBatchesWithSameCodec(batches: BatchSelection[]): BatchSelection|
undefined {
const mergedBatch =
new Batch(batches[0].batch.url, batches[0].batch.folderPath);
mergedBatch.index = batches[0].batch.index; // Used to access fields through
// FieldMetric.fieldIndices.
mergedBatch.codec = batches[0].batch.codec;
mergedBatch.name = mergedBatch.codec;
mergedBatch.version = batches[0].batch.version;
for (const batch of batches) {
if (batch.batch.version !== batches[0].batch.version) return undefined;
}

// Use the time field as a way of signaling the aggregation.
mergedBatch.time = undefined;
mergedBatch.timeStringShort = 'aggregate of';
for (const batch of batches) {
mergedBatch.timeStringShort += ' ' + batch.batch.name;
}
mergedBatch.timeStringLong = mergedBatch.timeStringShort;

// Shallow copy the fields and check their consistency accross the batches of
// the same codec.
mergedBatch.fields = batches[0].batch.fields;
for (const batch of batches) {
if (batch.batch.fields.length !== mergedBatch.fields.length) {
console.log(batch.batch.name);
return undefined;
}
for (let i = 0; i < mergedBatch.fields.length; i++) {
if (batch.batch.fields[i].id !== mergedBatch.fields[i].id) {
return undefined;
}
}
}

// Average the colors.
let [rSum, gSum, bSum] = [0, 0, 0];
for (const batch of batches) {
const [r, g, b] = hexStringToRgb(batch.batch.color);
rSum += r;
gSum += g;
bSum += b;
}
mergedBatch.color = rgbToHexString(
rSum / batches.length, gSum / batches.length, bSum / batches.length);

// Ignore all BatchSelection fields but the stats.
const mergedBatchSelection = new BatchSelection(mergedBatch);
for (const batch of batches) {
if (batch.stats.length !== batches[0].stats.length) return undefined;
}
for (let stat = 0; stat < batches[0].stats.length; stat++) {
const mergedStats = new FieldMetricStats();
mergedStats.minRatio = batches[0].stats[stat].minRatio;
mergedStats.maxRatio = batches[0].stats[stat].maxRatio;
mergedStats.arithmeticMean = 0;

const geometricMean = new GeometricMean();
let weightSum = 0;
for (const batch of batches) {
// Weigh each batch by its match count.
const weight = batch.matchedDataPoints.rows.length;
// TODO: Check the validity of the aggregation methods.
for (let p = 0; p < batch.matchedDataPoints.rows.length; ++p) {
geometricMean.add(batch.stats[stat].geometricMean);
}
mergedStats.minRatio =
Math.min(mergedStats.minRatio, batch.stats[stat].minRatio);
mergedStats.maxRatio =
Math.max(mergedStats.maxRatio, batch.stats[stat].maxRatio);
mergedStats.arithmeticMean += batch.stats[stat].arithmeticMean * weight;
weightSum += weight;
}

if (weightSum === 0) return undefined;
mergedStats.geometricMean = geometricMean.get();
mergedStats.arithmeticMean /= weightSum;

mergedBatchSelection.stats.push(mergedStats);
}

// No UI need for mergeHistograms() here. Skip it.

return mergedBatchSelection;
}

/* Combine Batch stats based on same codec.
* Returns partial data with shallow copies of members.
* Returns an empty array in case of error or if there is nothing to merge. */
export function mergeBatches(
batches: BatchSelection[], skipIndex: number): BatchSelection[] {
const map = new Map<string, BatchSelection[]>();
for (const batch of batches) {
const batchesWithSameCodec = map.get(batch.batch.codec);
if (batchesWithSameCodec === undefined) {
map.set(batch.batch.codec, [batch]);
} else {
batchesWithSameCodec.push(batch);
}
}

const skipCodec = (skipIndex >= 0 && skipIndex < batches.length) ?
batches[skipIndex].batch.codec :
undefined;
let atLeastOneMerge = false;
const mergedBatches: BatchSelection[] = [];
for (const [codec, batches] of map) {
if (codec === skipCodec) continue;

if (batches.length === 1) {
mergedBatches.push(batches[0]);
} else {
const mergedBatch = mergeBatchesWithSameCodec(batches);
if (mergedBatch === undefined) {
return [];
}
mergedBatches.push(mergedBatch);
atLeastOneMerge = true;
}
}
return atLeastOneMerge ? mergedBatches : [];
}

/** Aggregates histograms by sourceName. */
export function mergeHistograms(histograms: SourceCount[][]): SourceCount[] {
const aggHisto = new Map<string, SourceCount>();
for (const histogram of histograms) {
for (const sourceCount of histogram) {
let aggSourceCount = aggHisto.get(sourceCount.sourceName);
if (aggSourceCount === undefined) {
aggSourceCount = new SourceCount();
aggSourceCount.sourceName = sourceCount.sourceName;
aggSourceCount.sourcePath = sourceCount.sourcePath;
aggSourceCount.previewPath = sourceCount.previewPath;
aggSourceCount.count = sourceCount.count;
aggHisto.set(aggSourceCount.sourceName, aggSourceCount);
} else {
// Keep the first set field/constant values and make sure they are
// consistent across batches.
if (aggSourceCount.sourcePath === undefined) {
aggSourceCount.sourcePath = sourceCount.sourcePath;
} else if (
sourceCount.sourcePath !== undefined &&
aggSourceCount.sourcePath !== sourceCount.sourcePath) {
return []; // Should not happen.
}
if (aggSourceCount.previewPath === undefined) {
aggSourceCount.previewPath = sourceCount.previewPath;
} else if (
sourceCount.previewPath !== undefined &&
aggSourceCount.previewPath !== sourceCount.previewPath) {
return []; // Should not happen.
}

aggSourceCount.count += sourceCount.count;
}
}
}

// Sort by decreasing occurrences.
return Array.from(aggHisto.values()).sort((a, b) => b.count - a.count);
}
3 changes: 2 additions & 1 deletion src/batch_selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {Batch} from './entry';
import {dispatch, EventType, listen} from './events';
import {enableDefaultFilters, FieldFilter, getFilteredRowIndices} from './filter';
import {MatchedDataPoints} from './matcher';
import {FieldMetricStats} from './metric';
import {FieldMetricStats, SourceCount} from './metric';

/** One Batch (~ codec experiment results) to compare with another. */
export class BatchSelection {
Expand All @@ -37,6 +37,7 @@ export class BatchSelection {

/** The statistics to display. */
stats: FieldMetricStats[] = []; // As many as State.metrics.
histogram: SourceCount[] = []; // As many as distinct source media inputs.

constructor(selectedBatch: Batch) {
this.batch = selectedBatch;
Expand Down
Loading

0 comments on commit 2b02778

Please sign in to comment.