# core/converters/finding.vector.converter.ts

> 95 lines of code and 10 definitions.

Tree: GovLab Patterns
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/patterns#file-patterns-core-converters-finding-vector-converter-ts
Source text: https://banes-lab.com/source/patterns/core/converters/finding.vector.converter.ts.txt

Listed in [core/converters](https://banes-lab.com/api/source/patterns/core/converters.md), after [core/converters/finding.tree.converter.ts](https://banes-lab.com/source/patterns/core/converters/finding.tree.converter.ts.md) and before [core/converters/folder.converter.ts](https://banes-lab.com/source/patterns/core/converters/folder.converter.ts.md).

## Definitions

- `distributionFinding` (lexical_declaration, line 11)
- `autocorrelationFinding` (lexical_declaration, line 36)
- `vectorFindings` (lexical_declaration, line 95, exported)
- `anomalyFinding` (lexical_declaration, line 77)
- `anomalyRows` (lexical_declaration, line 64)
- `verdict` (lexical_declaration, line 38)
- `explained` (lexical_declaration, line 39)
- `significance` (lexical_declaration, line 66)
- `rows` (lexical_declaration, line 81)
- `extreme` (lexical_declaration, line 82)

## Contained in

- [core/converters](https://banes-lab.com/anatomy/patterns/folder-patterns-core-converters.md)

## Uses

- [core/converters/finding.converter.ts](https://banes-lab.com/source/patterns/core/converters/finding.converter.ts.md)
- [core/factories/axis.factory.ts](https://banes-lab.com/source/patterns/core/factories/axis.factory.ts.md)
- [core/factories/finding.factory.ts](https://banes-lab.com/source/patterns/core/factories/finding.factory.ts.md)
- [core/normalizers/math.normalizer.ts](https://banes-lab.com/source/patterns/core/normalizers/math.normalizer.ts.md)

## Used by

- [core/plugins/representation.vector.plugin.ts](https://banes-lab.com/source/patterns/core/plugins/representation.vector.plugin.ts.md)

## Linked from

- [core/converters](https://banes-lab.com/anatomy/patterns/folder-patterns-core-converters.md)
- [core/factories](https://banes-lab.com/anatomy/patterns/folder-patterns-core-factories.md)
- [core/normalizers](https://banes-lab.com/anatomy/patterns/folder-patterns-core-normalizers.md)
- [core/plugins](https://banes-lab.com/anatomy/patterns/folder-patterns-core-plugins.md)

## Source

```typescript
import { NULL_MODEL_LABELS, VECTOR_STRINGS } from "#configuration/strings/representation.strings";
import { autocorrelationSignificance, normalSignificance } from "#core/analyzers/baseline.analyzer";
import { explanationFinding, makeFinding, reasonOf } from "#core/factories/finding.factory";
import type { Finding } from "#types/finding.types";
import { ROUNDING } from "#configuration/constants/math.constants";
import type { VectorSummary } from "#types/representation.types";
import { coordinate } from "#core/factories/axis.factory";
import { fixedTo } from "#core/normalizers/math.normalizer";
import { withSupport } from "#core/converters/finding.converter";

const distributionFinding = function distributionFinding(field: string, summary: VectorSummary): Finding {
    return explanationFinding({
        analysis: "statistical",
        explained: VECTOR_STRINGS.distributionExplained(
            summary.minimum.toFixed(ROUNDING.standard),
            summary.maximum.toFixed(ROUNDING.standard),
        ),
        field,
        name: "distribution",
        observation: {
            count: summary.count,
            max: fixedTo(summary.maximum, ROUNDING.fine),
            mean: fixedTo(summary.mean, ROUNDING.fine),
            min: fixedTo(summary.minimum, ROUNDING.fine),
            stddev: fixedTo(summary.stddev, ROUNDING.fine),
        },
        observed: VECTOR_STRINGS.distributionObserved(
            summary.mean.toFixed(ROUNDING.standard),
            summary.stddev.toFixed(ROUNDING.standard),
        ),
        ontology: "scale",
        representation: "number",
    });
};

const autocorrelationFinding = function autocorrelationFinding(field: string, summary: VectorSummary): Finding {
    const significance = autocorrelationSignificance(summary.autocorrelation, summary.count);
    const verdict = significance.significant ? VECTOR_STRINGS.autocorBeyond : VECTOR_STRINGS.autocorWithin;
    const explained = VECTOR_STRINGS.autocorExplained(verdict, significance.pValue.toFixed(ROUNDING.fine));
    return makeFinding({
        coordinate: coordinate({
            analysis: "sequential",
            ontology: "relation",
            reasoning: "explanation",
            representation: "dynamical-systems",
        }),
        field,
        name: "autocorrelation",
        narrative: reasonOf(VECTOR_STRINGS.autocorObserved, explained),
        observation: {
            autocorrelation: fixedTo(summary.autocorrelation, ROUNDING.fine),
            pValue: fixedTo(significance.pValue, ROUNDING.fine),
            significant: significance.significant,
        },
        significance: {
            nullModel: NULL_MODEL_LABELS.autocorrelation,
            pValue: significance.pValue,
            significant: significance.significant,
            statistic: significance.statistic,
        },
    });
};

const anomalyRows = function anomalyRows(summary: VectorSummary): Readonly<Record<string, unknown>>[] {
    return summary.outliers.map(([value, z, index]) => {
        const significance = normalSignificance(z);
        return {
            pValue: fixedTo(significance.pValue, ROUNDING.fine),
            record: index,
            significant: significance.significant,
            value: fixedTo(value, ROUNDING.fine),
            z: fixedTo(z, ROUNDING.fine),
        };
    });
};

const anomalyFinding = function anomalyFinding(field: string, summary: VectorSummary): Finding | null {
    if (summary.outliers.length === 0) {
        return null;
    }
    const rows = anomalyRows(summary);
    const extreme = rows.filter((row) => row["significant"] === true).length;
    return explanationFinding({
        analysis: "anomaly",
        explained: VECTOR_STRINGS.anomalyExplained(String(extreme)),
        field,
        name: "anomaly",
        observation: { outliers: rows, significant: extreme },
        observed: VECTOR_STRINGS.anomalyObserved,
        ontology: "probability",
        representation: "number",
    });
};

export const vectorFindings = function vectorFindings(field: string, summary: VectorSummary): Finding[] {
    return withSupport(
        [distributionFinding(field, summary), autocorrelationFinding(field, summary), anomalyFinding(field, summary)],
        summary.count,
    );
};
```
