---
title: metric
---

<div class="python-reference">
<a id="fastvideo.eval.metrics.physics_iq.metric-classes"></a>
<a id="fastvideo.eval.metrics.physics_iq.metric-functions"></a>
<a id="fastvideo.eval.metrics.physics_iq.metric"></a>

<h2 id="fastvideo.eval.metrics.physics_iq.metric.BaseMetric"><code>fastvideo.eval.metrics.physics_iq.metric.BaseMetric</code></h2>
<pre class="doc-signature"><code>BaseMetric()</code></pre>
<p>Abstract base class for all eval metrics.</p>
<p>Two execution shapes:</p>
<ul>
<li>
<p><strong>Per-sample</strong> (<code>is_set_metric=False</code>, default) — implement
  :meth:<code>compute</code>. The Evaluator calls it once per input sample and
  returns one :class:<code>MetricResult</code> per sample.</p>
</li>
<li>
<p><strong>Set-vs-set</strong> (<code>is_set_metric=True</code>) — implement
  :meth:<code>accumulate</code> (called once per sample to buffer features)
  and :meth:<code>finalize</code> (called once after all samples to compute
  the corpus-level result). Use :meth:<code>reset</code> to clear buffers and
  :meth:<code>merge_from</code> to fold multi-GPU per-worker state together.</p>
</li>
</ul>
<p>Optionally override :meth:<code>setup</code> to eagerly load models. Metrics
that chunk along the time dim for memory hardcode their own chunk
size in <code>__init__</code> (see <code>optical_flow</code> for the canonical
example). Eval always processes one video per
:meth:<code>Evaluator.evaluate</code> call; <code>compute</code> / <code>accumulate</code>
receive a single sample, not a batch.</p>

<h3 id="fastvideo.eval.metrics.physics_iq.metric.BaseMetric.to"><code>fastvideo.eval.metrics.physics_iq.metric.BaseMetric.to</code></h3>
<pre class="doc-signature"><code>to(device: str | torch.device) -&gt; BaseMetric</code></pre>
<p>Move metric (and its internal models) to <em>device</em>.</p>
<h3 id="fastvideo.eval.metrics.physics_iq.metric.BaseMetric.setup"><code>fastvideo.eval.metrics.physics_iq.metric.BaseMetric.setup</code></h3>
<pre class="doc-signature"><code>setup() -&gt; None</code></pre>
<p>Eagerly load models. Called once by :class:<code>EvalWorker</code>.</p>
<p>Default is a no-op; metrics with no eager state (pixel math,
closed-form ops) inherit this. Override only if your metric
needs to load weights.</p>
<h3 id="fastvideo.eval.metrics.physics_iq.metric.BaseMetric.compute"><code>fastvideo.eval.metrics.physics_iq.metric.BaseMetric.compute</code></h3>
<pre class="doc-signature"><code>compute(sample: dict) -&gt; MetricResult</code></pre>
<p>Per-sample metrics: compute the score for one sample.</p>
<p><code>sample["video"]</code> is <code>(T, C, H, W)</code> float in <code>[0, 1]</code>.
<code>sample["reference"]</code> (if used) has the same shape. Return
<code>self._skip(sample, reason)</code> for missing inputs.</p>
<h3 id="fastvideo.eval.metrics.physics_iq.metric.BaseMetric.reset"><code>fastvideo.eval.metrics.physics_iq.metric.BaseMetric.reset</code></h3>
<pre class="doc-signature"><code>reset() -&gt; None</code></pre>
<p>Clear accumulator state at the start of each evaluate() call.</p>
<h3 id="fastvideo.eval.metrics.physics_iq.metric.BaseMetric.accumulate"><code>fastvideo.eval.metrics.physics_iq.metric.BaseMetric.accumulate</code></h3>
<pre class="doc-signature"><code>accumulate(sample: dict) -&gt; None</code></pre>
<p>Buffer per-sample features for a corpus-level metric.</p>
<h3 id="fastvideo.eval.metrics.physics_iq.metric.BaseMetric.finalize"><code>fastvideo.eval.metrics.physics_iq.metric.BaseMetric.finalize</code></h3>
<pre class="doc-signature"><code>finalize() -&gt; MetricResult</code></pre>
<p>Compute the corpus-level result from buffered state.</p>
<h3 id="fastvideo.eval.metrics.physics_iq.metric.BaseMetric.merge_from"><code>fastvideo.eval.metrics.physics_iq.metric.BaseMetric.merge_from</code></h3>
<pre class="doc-signature"><code>merge_from(other: BaseMetric) -&gt; None</code></pre>
<p>Multi-GPU: fold another worker's accumulator state into this one.</p>
<h2 id="fastvideo.eval.metrics.physics_iq.metric.PhysicsIQMSEMetric"><code>fastvideo.eval.metrics.physics_iq.metric.PhysicsIQMSEMetric</code></h2>
<pre class="doc-signature"><code>PhysicsIQMSEMetric(**kwargs: Any)</code></pre>


<h3 id="fastvideo.eval.metrics.physics_iq.metric.PhysicsIQMSEMetric.compute"><code>fastvideo.eval.metrics.physics_iq.metric.PhysicsIQMSEMetric.compute</code></h3>
<pre class="doc-signature"><code>compute(sample: dict) -&gt; MetricResult</code></pre>

<h2 id="fastvideo.eval.metrics.physics_iq.metric.SpatialIoUMetric"><code>fastvideo.eval.metrics.physics_iq.metric.SpatialIoUMetric</code></h2>
<pre class="doc-signature"><code>SpatialIoUMetric(**kwargs: Any)</code></pre>


<h3 id="fastvideo.eval.metrics.physics_iq.metric.SpatialIoUMetric.compute"><code>fastvideo.eval.metrics.physics_iq.metric.SpatialIoUMetric.compute</code></h3>
<pre class="doc-signature"><code>compute(sample: dict) -&gt; MetricResult</code></pre>

<h2 id="fastvideo.eval.metrics.physics_iq.metric.SpatiotemporalIoUMetric"><code>fastvideo.eval.metrics.physics_iq.metric.SpatiotemporalIoUMetric</code></h2>
<pre class="doc-signature"><code>SpatiotemporalIoUMetric(**kwargs: Any)</code></pre>


<h3 id="fastvideo.eval.metrics.physics_iq.metric.SpatiotemporalIoUMetric.compute"><code>fastvideo.eval.metrics.physics_iq.metric.SpatiotemporalIoUMetric.compute</code></h3>
<pre class="doc-signature"><code>compute(sample: dict) -&gt; MetricResult</code></pre>

<h2 id="fastvideo.eval.metrics.physics_iq.metric.WeightedSpatialIoUMetric"><code>fastvideo.eval.metrics.physics_iq.metric.WeightedSpatialIoUMetric</code></h2>
<pre class="doc-signature"><code>WeightedSpatialIoUMetric(**kwargs: Any)</code></pre>


<h3 id="fastvideo.eval.metrics.physics_iq.metric.WeightedSpatialIoUMetric.compute"><code>fastvideo.eval.metrics.physics_iq.metric.WeightedSpatialIoUMetric.compute</code></h3>
<pre class="doc-signature"><code>compute(sample: dict) -&gt; MetricResult</code></pre>

<h2 id="fastvideo.eval.metrics.physics_iq.metric.mean"><code>fastvideo.eval.metrics.physics_iq.metric.mean</code></h2>
<pre class="doc-signature"><code>mean(values: list&#91;float&#93; | tuple&#91;float, ...&#93;) -&gt; float</code></pre>

<h2 id="fastvideo.eval.metrics.physics_iq.metric.prepare_pair_inputs"><code>fastvideo.eval.metrics.physics_iq.metric.prepare_pair_inputs</code></h2>
<pre class="doc-signature"><code>prepare_pair_inputs(generated: Any, reference: Any, *, generated_mask: Any | None = None, reference_mask: Any | None = None, target_fps: int = DEFAULT_TARGET_FPS, duration_seconds: int = DEFAULT_DURATION_SECONDS, video_time_selection: str = &#x27;first&#x27;, threshold: int = 10, alpha: float = 0.3, roundtrip_generated_masks: bool = True) -&gt; PreparedPhysicsIQPair</code></pre>

<h2 id="fastvideo.eval.metrics.physics_iq.metric.prepare_triplet_inputs"><code>fastvideo.eval.metrics.physics_iq.metric.prepare_triplet_inputs</code></h2>
<pre class="doc-signature"><code>prepare_triplet_inputs(generated: Any, reference: Any, reference_take2: Any, *, generated_mask: Any | None = None, reference_mask: Any | None = None, reference_take2_mask: Any | None = None, target_fps: int = DEFAULT_TARGET_FPS, duration_seconds: int = DEFAULT_DURATION_SECONDS, video_time_selection: str = &#x27;first&#x27;, threshold: int = 10, alpha: float = 0.3, roundtrip_generated_masks: bool = True) -&gt; PreparedPhysicsIQTriplet</code></pre>

<h2 id="fastvideo.eval.metrics.physics_iq.metric.register"><code>fastvideo.eval.metrics.physics_iq.metric.register</code></h2>
<pre class="doc-signature"><code>register(name: str)</code></pre>
<p>Decorator to register a metric class.</p>
<p>Usage::</p>
<pre><code>@register("ssim")
class SSIMMetric(BaseMetric):
    ...
</code></pre>
<h2 id="fastvideo.eval.metrics.physics_iq.metric.MetricResult"><code>fastvideo.eval.metrics.physics_iq.metric.MetricResult</code></h2>
<pre class="doc-signature"><code>MetricResult(name: str, score: float | None, details: dict&#91;str, Any&#93; = dict())</code></pre>
<p>Standard result container returned by all metrics.</p>
<p><code>score</code> is <code>None</code> when the metric was skipped (e.g. missing
required input).  Check <code>details["skipped"]</code> for the reason.</p>

<h2 id="fastvideo.eval.metrics.physics_iq.metric.PhysicsIQMetric"><code>fastvideo.eval.metrics.physics_iq.metric.PhysicsIQMetric</code></h2>
<pre class="doc-signature"><code>PhysicsIQMetric(*, target_fps: int = DEFAULT_TARGET_FPS, duration_seconds: int = DEFAULT_DURATION_SECONDS, video_time_selection: str = &#x27;first&#x27;, threshold: int = 10, alpha: float = 0.3, roundtrip_generated_masks: bool = True)</code></pre>


<details><summary>Source</summary><pre><code>@register(&quot;physics_iq&quot;)
class PhysicsIQMetric(BaseMetric):
    name = &quot;physics_iq&quot;
    requires_reference = True
    higher_is_better = True

    def __init__(
        self,
        *,
        target_fps: int = DEFAULT_TARGET_FPS,
        duration_seconds: int = DEFAULT_DURATION_SECONDS,
        video_time_selection: str = &quot;first&quot;,
        threshold: int = 10,
        alpha: float = 0.3,
        roundtrip_generated_masks: bool = True,
    ) -&gt; None:
        super().__init__()
        self._prep_kwargs = &#123;
            &quot;target_fps&quot;: target_fps,
            &quot;duration_seconds&quot;: duration_seconds,
            &quot;video_time_selection&quot;: video_time_selection,
            &quot;threshold&quot;: threshold,
            &quot;alpha&quot;: alpha,
            &quot;roundtrip_generated_masks&quot;: roundtrip_generated_masks,
        &#125;
        self._mse = PhysicsIQMSEMetric(**self._prep_kwargs)
        self._spatiotemporal_iou = SpatiotemporalIoUMetric(**self._prep_kwargs)
        self._spatial_iou = SpatialIoUMetric(**self._prep_kwargs)
        self._weighted_spatial_iou = WeightedSpatialIoUMetric(**self._prep_kwargs)

    @staticmethod
    def _extract_payload(result: MetricResult | Mapping&#91;str, Any&#93;) -&gt; Mapping&#91;str, Any&#93;:
        if isinstance(result, MetricResult):
            return result.details
        return result

    def _compute_pair_metrics(self, prepared_pair) -&gt; dict&#91;str, Any&#93;:
        sample = &#123;&quot;_physics_iq_pair&quot;: prepared_pair&#125;
        mse = self._mse.compute(sample)
        st = self._spatiotemporal_iou.compute(sample)
        spatial = self._spatial_iou.compute(sample)
        weighted = self._weighted_spatial_iou.compute(sample)
        return &#123;
            &quot;mse_per_frame&quot;: mse.details&#91;&quot;per_frame&quot;&#93;,
            &quot;spatiotemporal_iou_per_frame&quot;: st.details&#91;&quot;per_frame&quot;&#93;,
            &quot;spatial_iou&quot;: float(spatial.score),
            &quot;weighted_spatial_iou&quot;: float(weighted.score),
            &quot;mse_mean&quot;: float(mse.score),
            &quot;spatiotemporal_iou_mean&quot;: float(st.score),
        &#125;

    def compute_single(
        self,
        generated: Any,
        reference: Any,
        reference_take2: Any,
        *,
        generated_mask: Any | None = None,
        reference_mask: Any | None = None,
        reference_take2_mask: Any | None = None,
        scenario: str | None = None,
        view: str | None = None,
    ) -&gt; dict&#91;str, Any&#93;:
        prepared = prepare_triplet_inputs(
            generated,
            reference,
            reference_take2,
            generated_mask=generated_mask,
            reference_mask=reference_mask,
            reference_take2_mask=reference_take2_mask,
            **self._prep_kwargs,
        )
        pair_metrics = self._compute_pair_metrics(prepared)
        variance_pair = prepare_pair_inputs(
            reference,
            reference_take2,
            generated_mask=reference_mask,
            reference_mask=reference_take2_mask,
            **self._prep_kwargs,
        )
        variance_metrics = self._compute_pair_metrics(variance_pair)
        details = &#123;
            **pair_metrics,
            &quot;pv_mse_per_frame&quot;: variance_metrics&#91;&quot;mse_per_frame&quot;&#93;,
            &quot;pv_spatiotemporal_iou_per_frame&quot;: variance_metrics&#91;&quot;spatiotemporal_iou_per_frame&quot;&#93;,
            &quot;pv_spatial_iou&quot;: variance_metrics&#91;&quot;spatial_iou&quot;&#93;,
            &quot;pv_weighted_spatial_iou&quot;: variance_metrics&#91;&quot;weighted_spatial_iou&quot;&#93;,
            &quot;pv_mse_mean&quot;: variance_metrics&#91;&quot;mse_mean&quot;&#93;,
            &quot;pv_spatiotemporal_iou_mean&quot;: variance_metrics&#91;&quot;spatiotemporal_iou_mean&quot;&#93;,
        &#125;
        if scenario is not None:
            details&#91;&quot;scenario&quot;&#93; = scenario
        if view is not None:
            details&#91;&quot;view&quot;&#93; = view
        return details

    @classmethod
    def aggregate(cls, results_list: Iterable&#91;MetricResult | Mapping&#91;str, Any&#93;&#93;) -&gt; float:
        payloads = &#91;cls._extract_payload(result) for result in results_list&#93;
        if not payloads:
            raise ValueError(&quot;PhysicsIQMetric.aggregate requires at least one result.&quot;)

        a_mse = mean(&#91;value for payload in payloads for value in payload&#91;&quot;mse_per_frame&quot;&#93;&#93;)
        a_st = mean(&#91;value for payload in payloads for value in payload&#91;&quot;spatiotemporal_iou_per_frame&quot;&#93;&#93;)
        a_s = mean(&#91;float(payload&#91;&quot;spatial_iou&quot;&#93;) for payload in payloads&#93;)
        a_ws = mean(&#91;float(payload&#91;&quot;weighted_spatial_iou&quot;&#93;) for payload in payloads&#93;)

        v_mse = mean(&#91;value for payload in payloads for value in payload&#91;&quot;pv_mse_per_frame&quot;&#93;&#93;)
        v_st = mean(&#91;value for payload in payloads for value in payload&#91;&quot;pv_spatiotemporal_iou_per_frame&quot;&#93;&#93;)
        v_s = mean(&#91;float(payload&#91;&quot;pv_spatial_iou&quot;&#93;) for payload in payloads&#93;)
        v_ws = mean(&#91;float(payload&#91;&quot;pv_weighted_spatial_iou&quot;&#93;) for payload in payloads&#93;)

        score = 100.0 * ((((a_st / v_st) + (a_s / v_s) + (a_ws / v_ws)) / 3.0) - (a_mse - v_mse))
        return round(float(np.clip(score, 0.0, 100.0)), 2)

    @classmethod
    def aggregate_components(cls, results_list: Iterable&#91;MetricResult | Mapping&#91;str, Any&#93;&#93;) -&gt; dict&#91;str, float&#93;:
        payloads = &#91;cls._extract_payload(result) for result in results_list&#93;
        return &#123;
            &quot;physics_iq&quot;: cls.aggregate(payloads),
            &quot;a_mse&quot;: mean(&#91;value for payload in payloads for value in payload&#91;&quot;mse_per_frame&quot;&#93;&#93;),
            &quot;a_st&quot;: mean(&#91;value for payload in payloads for value in payload&#91;&quot;spatiotemporal_iou_per_frame&quot;&#93;&#93;),
            &quot;a_s&quot;: mean(&#91;float(payload&#91;&quot;spatial_iou&quot;&#93;) for payload in payloads&#93;),
            &quot;a_ws&quot;: mean(&#91;float(payload&#91;&quot;weighted_spatial_iou&quot;&#93;) for payload in payloads&#93;),
            &quot;v_mse&quot;: mean(&#91;value for payload in payloads for value in payload&#91;&quot;pv_mse_per_frame&quot;&#93;&#93;),
            &quot;v_st&quot;: mean(&#91;value for payload in payloads for value in payload&#91;&quot;pv_spatiotemporal_iou_per_frame&quot;&#93;&#93;),
            &quot;v_s&quot;: mean(&#91;float(payload&#91;&quot;pv_spatial_iou&quot;&#93;) for payload in payloads&#93;),
            &quot;v_ws&quot;: mean(&#91;float(payload&#91;&quot;pv_weighted_spatial_iou&quot;&#93;) for payload in payloads&#93;),
        &#125;

    def _per_video_score(self, details: Mapping&#91;str, Any&#93;) -&gt; float:
        score = 100.0 * (
            ((mean(details&#91;&quot;spatiotemporal_iou_per_frame&quot;&#93;) / mean(details&#91;&quot;pv_spatiotemporal_iou_per_frame&quot;&#93;)) +
             (float(details&#91;&quot;spatial_iou&quot;&#93;) / float(details&#91;&quot;pv_spatial_iou&quot;&#93;)) +
             (float(details&#91;&quot;weighted_spatial_iou&quot;&#93;) / float(details&#91;&quot;pv_weighted_spatial_iou&quot;&#93;))) / 3.0 -
            (mean(details&#91;&quot;mse_per_frame&quot;&#93;) - mean(details&#91;&quot;pv_mse_per_frame&quot;&#93;)))
        return round(float(np.clip(score, 0.0, 100.0)), 2)

    def compute(self, sample: dict) -&gt; MetricResult:
        if &quot;reference&quot; not in sample:
            raise KeyError(&quot;PhysicsIQMetric requires sample&#91;&#x27;reference&#x27;&#93;.&quot;)

        take2_key = None
        for candidate in (&quot;reference_take2&quot;, &quot;real_take2&quot;, &quot;take2&quot;):
            if candidate in sample:
                take2_key = candidate
                break
        if take2_key is None:
            raise KeyError(&quot;PhysicsIQMetric requires sample&#91;&#x27;reference_take2&#x27;&#93; or an alias.&quot;)

        video = sample&#91;&quot;video&quot;&#93;
        reference = sample&#91;&quot;reference&quot;&#93;
        reference_take2 = sample&#91;take2_key&#93;
        generated_mask = sample.get(&quot;video_mask&quot;)
        reference_mask = sample.get(&quot;reference_mask&quot;)
        reference_take2_mask = sample.get(&quot;reference_take2_mask&quot;)

        scenario = sample.get(&quot;scenario&quot;)
        view = sample.get(&quot;view&quot;)

        details = self.compute_single(
            video,
            reference,
            reference_take2,
            generated_mask=generated_mask,
            reference_mask=reference_mask,
            reference_take2_mask=reference_take2_mask,
            scenario=scenario,
            view=view,
        )
        return MetricResult(name=self.name, score=self._per_video_score(details), details=details)</code></pre></details>
<h3 id="fastvideo.eval.metrics.physics_iq.metric.PhysicsIQMetric.compute_single"><code>fastvideo.eval.metrics.physics_iq.metric.PhysicsIQMetric.compute_single</code></h3>
<pre class="doc-signature"><code>compute_single(generated: Any, reference: Any, reference_take2: Any, *, generated_mask: Any | None = None, reference_mask: Any | None = None, reference_take2_mask: Any | None = None, scenario: str | None = None, view: str | None = None) -&gt; dict&#91;str, Any&#93;</code></pre>

<details><summary>Source</summary><pre><code>def compute_single(
    self,
    generated: Any,
    reference: Any,
    reference_take2: Any,
    *,
    generated_mask: Any | None = None,
    reference_mask: Any | None = None,
    reference_take2_mask: Any | None = None,
    scenario: str | None = None,
    view: str | None = None,
) -&gt; dict&#91;str, Any&#93;:
    prepared = prepare_triplet_inputs(
        generated,
        reference,
        reference_take2,
        generated_mask=generated_mask,
        reference_mask=reference_mask,
        reference_take2_mask=reference_take2_mask,
        **self._prep_kwargs,
    )
    pair_metrics = self._compute_pair_metrics(prepared)
    variance_pair = prepare_pair_inputs(
        reference,
        reference_take2,
        generated_mask=reference_mask,
        reference_mask=reference_take2_mask,
        **self._prep_kwargs,
    )
    variance_metrics = self._compute_pair_metrics(variance_pair)
    details = &#123;
        **pair_metrics,
        &quot;pv_mse_per_frame&quot;: variance_metrics&#91;&quot;mse_per_frame&quot;&#93;,
        &quot;pv_spatiotemporal_iou_per_frame&quot;: variance_metrics&#91;&quot;spatiotemporal_iou_per_frame&quot;&#93;,
        &quot;pv_spatial_iou&quot;: variance_metrics&#91;&quot;spatial_iou&quot;&#93;,
        &quot;pv_weighted_spatial_iou&quot;: variance_metrics&#91;&quot;weighted_spatial_iou&quot;&#93;,
        &quot;pv_mse_mean&quot;: variance_metrics&#91;&quot;mse_mean&quot;&#93;,
        &quot;pv_spatiotemporal_iou_mean&quot;: variance_metrics&#91;&quot;spatiotemporal_iou_mean&quot;&#93;,
    &#125;
    if scenario is not None:
        details&#91;&quot;scenario&quot;&#93; = scenario
    if view is not None:
        details&#91;&quot;view&quot;&#93; = view
    return details</code></pre></details>
<h3 id="fastvideo.eval.metrics.physics_iq.metric.PhysicsIQMetric.aggregate"><code>fastvideo.eval.metrics.physics_iq.metric.PhysicsIQMetric.aggregate</code></h3>
<pre class="doc-signature"><code>aggregate(results_list: Iterable&#91;MetricResult | Mapping&#91;str, Any&#93;&#93;) -&gt; float</code></pre>

<details><summary>Source</summary><pre><code>@classmethod
def aggregate(cls, results_list: Iterable&#91;MetricResult | Mapping&#91;str, Any&#93;&#93;) -&gt; float:
    payloads = &#91;cls._extract_payload(result) for result in results_list&#93;
    if not payloads:
        raise ValueError(&quot;PhysicsIQMetric.aggregate requires at least one result.&quot;)

    a_mse = mean(&#91;value for payload in payloads for value in payload&#91;&quot;mse_per_frame&quot;&#93;&#93;)
    a_st = mean(&#91;value for payload in payloads for value in payload&#91;&quot;spatiotemporal_iou_per_frame&quot;&#93;&#93;)
    a_s = mean(&#91;float(payload&#91;&quot;spatial_iou&quot;&#93;) for payload in payloads&#93;)
    a_ws = mean(&#91;float(payload&#91;&quot;weighted_spatial_iou&quot;&#93;) for payload in payloads&#93;)

    v_mse = mean(&#91;value for payload in payloads for value in payload&#91;&quot;pv_mse_per_frame&quot;&#93;&#93;)
    v_st = mean(&#91;value for payload in payloads for value in payload&#91;&quot;pv_spatiotemporal_iou_per_frame&quot;&#93;&#93;)
    v_s = mean(&#91;float(payload&#91;&quot;pv_spatial_iou&quot;&#93;) for payload in payloads&#93;)
    v_ws = mean(&#91;float(payload&#91;&quot;pv_weighted_spatial_iou&quot;&#93;) for payload in payloads&#93;)

    score = 100.0 * ((((a_st / v_st) + (a_s / v_s) + (a_ws / v_ws)) / 3.0) - (a_mse - v_mse))
    return round(float(np.clip(score, 0.0, 100.0)), 2)</code></pre></details>
<h3 id="fastvideo.eval.metrics.physics_iq.metric.PhysicsIQMetric.aggregate_components"><code>fastvideo.eval.metrics.physics_iq.metric.PhysicsIQMetric.aggregate_components</code></h3>
<pre class="doc-signature"><code>aggregate_components(results_list: Iterable&#91;MetricResult | Mapping&#91;str, Any&#93;&#93;) -&gt; dict&#91;str, float&#93;</code></pre>

<details><summary>Source</summary><pre><code>@classmethod
def aggregate_components(cls, results_list: Iterable&#91;MetricResult | Mapping&#91;str, Any&#93;&#93;) -&gt; dict&#91;str, float&#93;:
    payloads = &#91;cls._extract_payload(result) for result in results_list&#93;
    return &#123;
        &quot;physics_iq&quot;: cls.aggregate(payloads),
        &quot;a_mse&quot;: mean(&#91;value for payload in payloads for value in payload&#91;&quot;mse_per_frame&quot;&#93;&#93;),
        &quot;a_st&quot;: mean(&#91;value for payload in payloads for value in payload&#91;&quot;spatiotemporal_iou_per_frame&quot;&#93;&#93;),
        &quot;a_s&quot;: mean(&#91;float(payload&#91;&quot;spatial_iou&quot;&#93;) for payload in payloads&#93;),
        &quot;a_ws&quot;: mean(&#91;float(payload&#91;&quot;weighted_spatial_iou&quot;&#93;) for payload in payloads&#93;),
        &quot;v_mse&quot;: mean(&#91;value for payload in payloads for value in payload&#91;&quot;pv_mse_per_frame&quot;&#93;&#93;),
        &quot;v_st&quot;: mean(&#91;value for payload in payloads for value in payload&#91;&quot;pv_spatiotemporal_iou_per_frame&quot;&#93;&#93;),
        &quot;v_s&quot;: mean(&#91;float(payload&#91;&quot;pv_spatial_iou&quot;&#93;) for payload in payloads&#93;),
        &quot;v_ws&quot;: mean(&#91;float(payload&#91;&quot;pv_weighted_spatial_iou&quot;&#93;) for payload in payloads&#93;),
    &#125;</code></pre></details>
<h3 id="fastvideo.eval.metrics.physics_iq.metric.PhysicsIQMetric.compute"><code>fastvideo.eval.metrics.physics_iq.metric.PhysicsIQMetric.compute</code></h3>
<pre class="doc-signature"><code>compute(sample: dict) -&gt; MetricResult</code></pre>

<details><summary>Source</summary><pre><code>def compute(self, sample: dict) -&gt; MetricResult:
    if &quot;reference&quot; not in sample:
        raise KeyError(&quot;PhysicsIQMetric requires sample&#91;&#x27;reference&#x27;&#93;.&quot;)

    take2_key = None
    for candidate in (&quot;reference_take2&quot;, &quot;real_take2&quot;, &quot;take2&quot;):
        if candidate in sample:
            take2_key = candidate
            break
    if take2_key is None:
        raise KeyError(&quot;PhysicsIQMetric requires sample&#91;&#x27;reference_take2&#x27;&#93; or an alias.&quot;)

    video = sample&#91;&quot;video&quot;&#93;
    reference = sample&#91;&quot;reference&quot;&#93;
    reference_take2 = sample&#91;take2_key&#93;
    generated_mask = sample.get(&quot;video_mask&quot;)
    reference_mask = sample.get(&quot;reference_mask&quot;)
    reference_take2_mask = sample.get(&quot;reference_take2_mask&quot;)

    scenario = sample.get(&quot;scenario&quot;)
    view = sample.get(&quot;view&quot;)

    details = self.compute_single(
        video,
        reference,
        reference_take2,
        generated_mask=generated_mask,
        reference_mask=reference_mask,
        reference_take2_mask=reference_take2_mask,
        scenario=scenario,
        view=view,
    )
    return MetricResult(name=self.name, score=self._per_video_score(details), details=details)</code></pre></details>
</div>
