Using Parallel Tempering to fold a protein
Note
This problem is hard! It is only meant for those who wish to learn about cutting edge attempts to fold proteins on a computer. If you're not interested in such things, that's fine! There are lot of people studying this problem already!
Parallel Tempering Links to an external site. is a clever method for efficiently finding low lying minima in high dimensional functions with rough landscapes. An example of such a problem is protein folding. There are many metastable low energy states, and it is hard to find the ground state. The idea of Parallel Tempering, is to simulate a large number (say 32) copies of the same protein for a large range of temperatures. They all merrily perform Monte Carlo moves in their own separate universes, but occasionally, the Parallel Temperer takes a look at two systems at neighboring temperatures, say at 300 and 320 degrees, and decides if the these systems can be exchanged! That means that the configuration at the cooler temperature suddenly finds itself at the warmer temperature and vice-versa. By exchanging systems like this many times, eventually a system that started off really hot, gets exchanged down to one that is really cold. And one that is really cold can eventually find itself really hot.
The effect of all of this is similar to simulated annealing described in the last problem, except you don't have to worry about getting the temperature schedule just right. The directory hw7/partemp has an implementation of parallel tempering in python along with similar to code to the last problem for doing Monte Carlo on the protein.
If you're interested in this problem, I recommend that you look at ParTemp.py and the above wikipedia page. If this is hard for you to understand, I recommend against you pursuing this any further, because it's not important for a general understanding of biophysics but only those who want to seriously attempt to solve protein folding on a computer.
If you think that this is cool, you can try playing around with the array of (inverse) temperature Beta. This is the hardest part to get right with this method. If you choose the wrong set of temperatures, some neighboring systems won't be able to exchange, making the method fairly useless. If you have too many copies of the system, then the whole things slows down considerably.
At the bottom of ParLattProt.py, you can also change the number steps per move, StepsPerMove, which tells you how often you want to attempt to exchange with neighboring systems. Too long, and you miss opportunities to exchange two systems, two short, and the simulation becomes inefficient.
Lastly, you'll see that actually the energies outputted rarely hit the ground state. So you could try to improve the code by tracking the minimum energy seen during a simulation. This is accessible through "Rmin" just as it is in lattice_protein.py of the previous problem. So you could look at that code and integrate output minimum energies seen to see if this improves the performance of this method.