def normalize_attention_token_scalars(
    list_of_sequence_lists: list[list[list[TokenAndRawAttentionScalars]]],
) -> list[list[list[TokenAndAttentionScalars]]]:
    """The high level setup is analogous to normalize_token_scalars, but using
    TokenAndRawAttentionScalars objects, which have a list of floats associated
    to each token. There are several kinds of normalizations applied:

    1. Normalizing all scalars in all provenances, in all sequences, in all tokens,
    all scalars within a token's scalars, to the same scale so that they are in
    the range [0, 1].
    2. Summarizing the lists of scalars per token in some way to get a single scalar
    per token, and then normalizing those scalars to the same scale, as described in 1.and
    a. one way to summarize is to compute a summary statistic on the "scalars in", which are
    the list of floats associated to each token.
    b. the other way is to compute a summary statistic on the "scalars out", which are the
    ith entry in each list of of floats that contains an ith entry.
    i. one summary statistic used is the "total", or sum of all scalars in or out
    ii. another summary statistic used is the "max", or maximum of all scalars in or out

    These normalized and summarized scalars are then stored in a TokenAndAttentionScalars object,
    which is returned in a nested list structure parallel to the input structure.
    """

    indexed_by_token_sequence = flatten(list_of_sequence_lists)
    indexed_by_token = flatten(indexed_by_token_sequence)
    indexed_by_token = [
        TokenAndRawAttentionScalars(token=d.token, scalars=[max(a, 0) for a in d.scalars])
        for d in indexed_by_token
    ]
    max_scalar = max([a for d in indexed_by_token for a in d.scalars]) or 0
    total_scalar_scale = create_scale_linear(max_scalar)

    def compute_summary_of_scalar_in(
        attn_token_sequence_list: list[TokenAndRawAttentionScalars],
        operation: Callable[[Sequence[float | None]], float],
    ) -> list[float]:
        return [operation(d.scalars) for d in attn_token_sequence_list]

    def _get_entry_if_available(scalars: Sequence[float], index: int) -> float | None:
        # if index is out of bounds, return None; otherwise return the entry at that index
        return scalars[index] if index < len(scalars) else None

    def _sum_non_none(scalars: Sequence[float | None]) -> float:
        # sum all non-None entries in scalars
        return sum([a for a in scalars if a is not None])

    def _max_non_none(scalars: Sequence[float | None]) -> float:
        # return the max of all non-None entries in scalars
        return max([a for a in scalars if a is not None])

    def compute_summary_of_scalar_out(
        attn_token_sequence_list: list[TokenAndRawAttentionScalars],
        operation: Callable[[Sequence[float | None]], float],
    ) -> list[float]:
        for i in range(len(attn_token_sequence_list)):
            # the attended to sequence length at token i is at most i+1
            assert len(attn_token_sequence_list[i].scalars) <= i + 1, (
                i,
                len(attn_token_sequence_list[i].scalars),
            )
        scalar_out = [
            operation(
                [
                    _get_entry_if_available(attn_token_sequence_list[i].scalars, j)
                    for i in range(j, len(attn_token_sequence_list))
                ]
            )
            for j in range(len(attn_token_sequence_list))
        ]
        return scalar_out

    def compute_total_scalar_in(
        attn_token_sequence_list: list[TokenAndRawAttentionScalars],
    ) -> list[float]:
        return compute_summary_of_scalar_in(attn_token_sequence_list, _sum_non_none)

    def compute_max_scalar_in(
        attn_token_sequence_list: list[TokenAndRawAttentionScalars],
    ) -> list[float]:
        return compute_summary_of_scalar_in(attn_token_sequence_list, _max_non_none)

    def compute_total_scalar_out(
        attn_token_sequence_list: list[TokenAndRawAttentionScalars],
    ) -> list[float]:
        return compute_summary_of_scalar_out(attn_token_sequence_list, _sum_non_none)

    def compute_max_scalar_out(
        attn_token_sequence_list: list[TokenAndRawAttentionScalars],
    ) -> list[float]:
        return compute_summary_of_scalar_out(attn_token_sequence_list, _max_non_none)

    def compute_scalar_summary_and_scale(
        compute_scalar_summary_function: Callable[[list[TokenAndRawAttentionScalars]], list[float]],
        list_of_sequence_lists: list[list[list[TokenAndRawAttentionScalars]]],
    ) -> tuple[list[list[list[float]]], Callable[[float], float]]:
        scalar_indexed_by_token_sequence_list: list[list[list[float]]] = [
            [compute_scalar_summary_function(sequence) for sequence in sequence_list]
            for sequence_list in list_of_sequence_lists
        ]
        scalar_indexed_by_token: list[float] = flatten(
            flatten(scalar_indexed_by_token_sequence_list)
        )
        scalar_indexed_by_token = [max(a, 0) for a in scalar_indexed_by_token]
        scalar_scale: Callable[[float], float] = create_scale_linear(
            max(scalar_indexed_by_token) or 0
        )
        return scalar_indexed_by_token_sequence_list, scalar_scale

    (
        total_scalar_in_indexed_by_token_sequence_list,
        total_scalar_in_scale,
    ) = compute_scalar_summary_and_scale(compute_total_scalar_in, list_of_sequence_lists)
    (
        max_scalar_in_indexed_by_token_sequence_list,
        max_scalar_in_scale,
    ) = compute_scalar_summary_and_scale(compute_max_scalar_in, list_of_sequence_lists)
    (
        total_scalar_out_indexed_by_token_sequence_list,
        total_scalar_out_scale,
    ) = compute_scalar_summary_and_scale(compute_total_scalar_out, list_of_sequence_lists)
    (
        max_scalar_out_indexed_by_token_sequence_list,
        max_scalar_out_scale,
    ) = compute_scalar_summary_and_scale(compute_max_scalar_out, list_of_sequence_lists)

    return [
        [
            [
                TokenAndAttentionScalars(
                    token=d.token,
                    scalars=d.scalars,
                    normalized_scalars=[total_scalar_scale(a) for a in d.scalars],
                    total_scalar_in=total_scalar_in_indexed_by_token_sequence_list[seq_list_idx][
                        seq_idx
                    ][token_idx],
                    normalized_total_scalar_in=total_scalar_in_scale(
                        total_scalar_in_indexed_by_token_sequence_list[seq_list_idx][seq_idx][
                            token_idx
                        ]
                    ),
                    max_scalar_in=max_scalar_in_indexed_by_token_sequence_list[seq_list_idx][
                        seq_idx
                    ][token_idx],
                    normalized_max_scalar_in=max_scalar_in_scale(
                        max_scalar_in_indexed_by_token_sequence_list[seq_list_idx][seq_idx][
                            token_idx
                        ]
                    ),
                    total_scalar_out=total_scalar_out_indexed_by_token_sequence_list[seq_list_idx][
                        seq_idx
                    ][token_idx],
                    normalized_total_scalar_out=total_scalar_out_scale(
                        total_scalar_out_indexed_by_token_sequence_list[seq_list_idx][seq_idx][
                            token_idx
                        ]
                    ),
                    max_scalar_out=max_scalar_out_indexed_by_token_sequence_list[seq_list_idx][
                        seq_idx
                    ][token_idx],
                    normalized_max_scalar_out=max_scalar_out_scale(
                        max_scalar_out_indexed_by_token_sequence_list[seq_list_idx][seq_idx][
                            token_idx
                        ]
                    ),
                )
                for token_idx, d in enumerate(sequence)
            ]
            for seq_idx, sequence in enumerate(list_of_sequences)
        ]
        for seq_list_idx, list_of_sequences in enumerate(list_of_sequence_lists)
    ]
The high level setup is analogous to normalize_token_scalars, but using
    TokenAndRawAttentionScalars objects, which have a list of floats associated
    to each token. There are several kinds of normalizations applied:

    1. Normalizing all scalars in all provenances, in all sequences, in all tokens,
    all scalars within a token's scalars, to the same scale so that they are in
    the range [0, 1].
    2. Summarizing the lists of scalars per token in some way to get a single scalar
    per token, and then normalizing those scalars to the same scale, as described in 1.and
    a. one way to summarize is to compute a summary statistic on the "scalars in", which are
    the list of floats associated to each token.
    b. the other way is to compute a summary statistic on the "scalars out", which are the
    ith entry in each list of of floats that contains an ith entry.
    i. one summary statistic used is the "total", or sum of all scalars in or out
    ii. another summary statistic used is the "max", or maximum of all scalars in or out

    These normalized and summarized scalars are then stored in a TokenAndAttentionScalars object,
    which is returned in a nested list structure parallel to the input structure.
    
neuron_explainer/activation_server/read_routes.py