> ## Documentation Index
> Fetch the complete documentation index at: https://bagel.softnanolab.com/llms.txt
> Use this file to discover all available pages before exploring further.

# FlexEvoBindEnergy

> Energy that minimizes the 'average minimum distance' between two groups of residues. In practice, for each residue in the first group, it finds the closest residue in the second group and calculates the minimum distance between them. The minimum is over all possible pairs of atoms that make up the two residues. The average is over all the residues in the first group. Symmetrise this operation by doing the same but looking at residues from group 2 and what is their minimum distance when looking at residues to group one.

This energy is a symmetrised version of the minimum separation component of the loss used to design peptide binders in:
'Li, Q., Vlachos, E.N. & Bryant, P. Design of linear and cyclic peptide binders from protein sequence information. Commun Chem 8, 211 (2025)'
DOI [https://doi.org/10.1038/s42004-025-01601-3](https://doi.org/10.1038/s42004-025-01601-3)

Note in this reference the explanation of Eq.1 is misleading. Here, the average of the minimum distance
is over all the the residues in the first group.

## Definition

The FlexEvoBind energy computes the average minimum inter-atomic distance between two residue groups, adapted from the binding loss in Li et al. 2025. For each residue in group 1, the minimum distance to any atom in group 2 is found, and these minimum distances are averaged. When `symmetrized=True` (the default), the same calculation is performed from group 2 to group 1, and a weighted average of both directions is taken. When `plddt_weighted=True`, each direction is divided by its group's average pLDDT, producing a formulation closer to the EvoBind loss.

## Parameters

<ResponseField name="oracle" type="FoldingOracle" required>
  The oracle to use for the energy term.
</ResponseField>

<ResponseField name="residues" type="tuple[list[Residue], list[Residue]]" required>
  A tuple containing two lists of residues, those to include in the first \[0] and second \[1] group.
</ResponseField>

<ResponseField name="plddt_weighted" type="bool" default="False">
  A bool indicating whether the result need to be weighted by the plddt of the residues considered. If True, this definition is closer to the EvoBind energy in the reference below
</ResponseField>

<ResponseField name="symmetrized" type="bool" default="True">
  A bool indicating whether or not the calculation of the minimum distances need to be symmetrized between residues in residued\[0] and those in residues\[1]. Otherwise the minimum distances are those between any atom in residues from residues\[0] and those in residues in residues\[1], but not vice versa.
</ResponseField>

<ResponseField name="inheritable" type="bool" default="True">
  If a new residue is added next to a residue included in this energy term, this dictates whether that new residue could then be added to this energy term.
</ResponseField>

<ResponseField name="weight" type="float" default="1.0">
  The weight of the energy term.
</ResponseField>

<ResponseField name="name" type="str | None" default="None">
  Optional name to append to the energy term name.
</ResponseField>

## Methods

### compute

**Parameters**

<ResponseField name="oracles_result" type="OraclesResultDict" required />

## Example

```python theme={null}
import bagel as bg

# Create the folding oracle
esmfold = bg.oracles.ESMFold()

# Define two groups of residues (e.g. hotspot and binder)
hotspot_residues = [residues_target[i] for i in range(10, 20)]
binder_residues = residues_binder

# Minimize average minimum distance between two residue groups
flex_evo_bind = bg.energies.FlexEvoBindEnergy(
    oracle=esmfold,
    residues=[hotspot_residues, binder_residues],
    symmetrized=True,
    weight=1.0,
)

# Add to a state
state = bg.State(
    chains=[binder_chain, target_chain],
    energy_terms=[flex_evo_bind],
    name="my_state",
)
```
