# Advanced Uses of OPS Ensembles¶

One of the novelties of OpenPathSampling is the new set-theoretic treatment of path ensembles. The second paper on OPS contains more details. This section will illustrate a few uses of that approach.

## Visit all states¶

We want a path which contains at least one frame in each state. The question is, what ensemble can we use to create such a trajectory?

The first obvious thought would be:

goal_ensemble = PartInXEnsemble(A) & PartInXEnsemble(B)


(which can, of course, be further generalized to more states). However, while that is the ensemble we want to eventually satisfy, we can’t use its can_append to create it, because its can_append always returns True: the trajectory will go on forever!

But we can use a trick: since what we want is the first trajectory that satisfies goal_ensemble, we know that every shorter trajectory will not satisfy it. This means that the shorter trajectories must satisfy the complement of goal_ensemble, and the trajectory we want will be the first trajectory that does not satisfy the complement!

So the trick we’ll use is to build the trajectory by using the fact that the shorter trajectories are in the complement of goal_ensemble, which is given by:

complement = AllOutXEnsemble(A) | AllOutXEnsemble(B)


The generate function will stop when that is no longer true, giving us the trajectory we want. This can be directly generalized to more states.

Here we’re not even using the can_append function. That happens to be the same as the ensemble itself for this particular ensemble, but conceptually, we’re actually using the test of whether a trajectory is in the ensemble at all.

init_traj_ensemble = paths.AllOutXEnsemble(A) | paths.AllOutXEnsemble(B)
trajectory = engine.generate(engine.current_snapshot, [init_traj_ensemble])


Those two lines are the entirety of what you need to do to generate a trajectory that visits both states.

Note that this functionality has been implemented in OPS as the VisitAllStatesEnsemble. When using that, you should use the can_append method. That ensemble adds progress reporting functionality to show how many frames have been run and what states have been found so far, so it is more pleasant to use. However, this idea is what underlies its implementation.