Most people using IMP at some point get tripped up by the fact that ScoreState dependent state is not updated until Model::update() is caller or a Restraint that requires it is evaluated. For example, if you move a bunch of particles, the non-bonded no longer contains the correct pairs until Model::update is called. And similar problems can arrise with rigid bodies. The reason for this is that updating the state can be expensive (imagine moving each of 100 or 1000 particles one at a time and updating the non bonded list after each move when all you care about is the result at the end) and updating things when they are accessed requires putting relatively expensive logic into each access or modifier function, or providing two separate versions of much of the IMP API (one of which checks and one of which is designed to be used in circumstances when you known things are up to date).
This sort of issue is not an uncommon one, and the typical solution is to introduce the concept of an editing session and to only update things when the session is finished. One could then start an editing session, modify a bunch of things cheaply, and the have Model::update() called when the session ends (or, perhaps, something somewhat more clever). This would make the idea of things being temporarily invalid more explicit and so could avoid various trip ups, and would be easy to implement. The big questions are
- what to do when things are changed without an editing session being in progress? The most proper solution is to throw an exception and force people to use editing sessions. But I think the horse is out of the barn on this one as doing this would break lots and lots of existing code. More practical solutions are to allow people to turn on the error checking or to spit out a warning at the end of a session if sessions are not used.
- how valuable people would find this? Is this just something that trips up everyone once and then you get it right from then on? Or an ongoing issue?
Anyway, I'd propose implementing sessions through one or more RAII objects (perhaps more than one to provide more flexibility about handling nested sessions).