# core/converters/metric.converter.ts

> 40 lines of code and 6 definitions.

Tree: Bane's Lab Build Scripts
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/build-scripts#file-build-scripts-core-converters-metric-converter-ts
Source text: https://banes-lab.com/source/build-scripts/core/converters/metric.converter.ts.txt

Listed in [core/converters](https://banes-lab.com/api/source/build-scripts/core/converters.md), after [core/converters/markup.converter.ts](https://banes-lab.com/source/build-scripts/core/converters/markup.converter.ts.md) and before [core/converters/ontology.converter.ts](https://banes-lab.com/source/build-scripts/core/converters/ontology.converter.ts.md).

## Definitions

- `total` (lexical_declaration, line 8)
- `summed` (lexical_declaration, line 7)
- `anatomyMeasures` (lexical_declaration, line 27, exported)
- `edges` (lexical_declaration, line 11)
- `unresolvedCalls` (lexical_declaration, line 12)
- `measured` (lexical_declaration, line 31, exported)

## Contained in

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

## Uses

- [core/converters/structure.converter.ts](https://banes-lab.com/source/build-scripts/core/converters/structure.converter.ts.md)

## Linked from

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

## Source

```typescript
import type { AnatomyMeasures, TreeMeasure } from "@banes-lab/web/types/metric.types.js";
import { sumStats, tallyOf } from "#core/converters/structure.converter";
import type { AnatomyMetrics } from "@banes-lab/web/types/anatomy.types.js";
import type { DerivedTree } from "#types/anatomy.types";
import { resolutionRate } from "@govlab/patterns";

const summed = function summed(parts: readonly AnatomyMetrics[]): AnatomyMetrics {
    const total = function total(pick: (part: AnatomyMetrics) => number): number {
        return parts.reduce((sum, part) => sum + pick(part), 0);
    };
    const edges = total((part) => part.edges);
    const unresolvedCalls = total((part) => part.unresolvedCalls);
    return {
        callable: total((part) => part.callable),
        definitions: total((part) => part.definitions),
        edges,
        exported: total((part) => part.exported),
        findings: tallyOf(parts.map((part) => part.findings)),
        flows: tallyOf(parts.map((part) => part.flows)),
        maxInDegree: Math.max(0, ...parts.map((part) => part.maxInDegree)),
        maxOutDegree: Math.max(0, ...parts.map((part) => part.maxOutDegree)),
        resolutionRate: resolutionRate(edges, unresolvedCalls),
        unresolvedCalls,
    };
};

export const anatomyMeasures = function anatomyMeasures(
    trees: readonly DerivedTree[],
    labelOf: (tab: string) => string,
): AnatomyMeasures {
    const measured: readonly TreeMeasure[] = trees.map((tree) => ({
        label: labelOf(tree.tab),
        metrics: tree.snapshot.metrics,
        stats: tree.snapshot.tree.stats,
        tab: tree.tab,
    }));
    return {
        metrics: summed(measured.map((tree) => tree.metrics)),
        stats: sumStats(measured.map((tree) => tree.stats)),
        trees: measured,
    };
};
```
