def get_context_potential_energy(context, positions, box_vectors=None,
                                 by_force_group=True):
    """Compute the potential energy of a System in a Context object.

    This is simply a shortcut that takes care of setting
    box vectors and positions before computing the energy.

    Parameters
    ----------
    context : simtk.openmm.Context
        The Context object containing the system.
    positions : simtk.unit.Quantity
        A n_atoms x 3 arrays of coordinates with units of length.
    box_vectors : simtk.unit.Quantity, optional
        If specified, this should be a 3 x 3 array. Each row should
        be a box vector.
    by_force_group : bool, optional
        If True, it returns a dictionary mapping force groups to
        their potential energies. Default is True.

    Returns
    -------
    potential_energy : simtk.unit.Quantity or Dict[type, Quantity]
        The potential energy of the system at the given coordinates.
        If ``by_force_group`` is True, then this is a dictionary
        mapping force groups to their potential energy.

    """
    # Box vectors must be updated before positions are set.
    if box_vectors is not None:
        context.setPeriodicBoxVectors(*box_vectors)
    context.setPositions(positions)

    # If we don't have energies by force group,
    # just return the energy of the full System.
    if not by_force_group:
        return context.getState(getEnergy=True).getPotentialEnergy()

    # Determine how many force groups we need to compute.
    force_groups = {f.getForceGroup() for f in context.getSystem().getForces()}

    # Compute potential energies of all groups.
    potential_energies = {}
    for force_group in force_groups:
        state = context.getState(getEnergy=True, groups={force_group})
        potential_energies[force_group] = state.getPotentialEnergy()
    return potential_energies